{"_id":"@aftership/carrier-account-sdk","name":"@aftership/carrier-account-sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@aftership/carrier-account-sdk","version":"0.1.0","type":"module","main":"./dist/index.umd.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"scripts":{"build":"bun run --bun vite build && tsc -p tsconfig.json","type-check":"tsc -p tsconfig.json --noEmit"},"_id":"@aftership/carrier-account-sdk@0.1.0","description":"This SDK enables your application to open an AfterShip-hosted popup window for carrier account creation or editing.","_integrity":"sha512-7ylNc3xNMww8v3r5SYXyJwYVullzKl3X0YInMOHSJ2uVwwa3FknFL6HXeyOU5pQz59kJ9pF5YqSQwSp+gCDY0A==","_resolved":"/private/var/folders/4b/jdgnhp5901q54hcy0ybpwv1r0000gn/T/0625968995963a4117364b4387138586/aftership-carrier-account-sdk-0.1.0.tgz","_from":"file:aftership-carrier-account-sdk-0.1.0.tgz","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-7ylNc3xNMww8v3r5SYXyJwYVullzKl3X0YInMOHSJ2uVwwa3FknFL6HXeyOU5pQz59kJ9pF5YqSQwSp+gCDY0A==","shasum":"73970f518db781c39c4f5bca7b751bca811245e2","tarball":"https://registry.npmjs.org/@aftership/carrier-account-sdk/-/carrier-account-sdk-0.1.0.tgz","fileCount":12,"unpackedSize":19215,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGUgvpMGDxz3HaLa+N5ks7H4mVd/SObcx/Ms+nxFyBqMAiBN3YsH1SgiXv8S6IiLnCR4F1yUwslQDsBBTEVHHdJHaA=="}]},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"directories":{},"maintainers":[{"name":"aftership","email":"sdk@aftership.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/carrier-account-sdk_0.1.0_1775112219527_0.15373119755146214"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-02T06:43:39.527Z","0.1.0":"2026-04-02T06:43:39.680Z","modified":"2026-04-02T06:43:39.930Z"},"maintainers":[{"name":"aftership","email":"sdk@aftership.com"}],"description":"This SDK enables your application to open an AfterShip-hosted popup window for carrier account creation or editing.","readme":"# @aftership/carrier-account-sdk\n\nThis SDK enables your application to open an AfterShip-hosted popup window for carrier account creation or editing.\n\nIt is intended for customer integration. This document focuses on the integration contract, implementation responsibilities, and SDK usage, while keeping internal implementation details to a minimum.\n\n## 1. Overview\n\nThis integration allows your application to start an AfterShip-hosted carrier account flow without redirecting the user away from your page.\n\nThe typical flow is:\n\n1. Your backend prepares a Signed URL for the requested action.\n2. Your frontend passes that Signed URL into `sdk.open(...)`.\n3. The SDK opens the popup window and manages the browser-side flow.\n4. Your frontend receives the final result through callbacks such as `onSuccess`, `onError`, or `onClose`.\n\nThis SDK is designed to keep the frontend integration simple. Your application does not need to implement popup lifecycle management or cross-window message handling by itself.\n\n## 2. Glossary\n\n| Term | Description |\n| --- | --- |\n| Signed URL | A temporary absolute URL used to open the AfterShip-hosted popup flow. |\n| `request_id` | A request identifier used to correlate a specific create flow. |\n| `shipper_account_id` | The final carrier account identifier returned after a successful flow. |\n| Popup Window | A separate browser window opened by the SDK to host the AfterShip UI. |\n| Host Application | Your frontend application that integrates this SDK. |\n| AfterShip Hosted UI | The popup page hosted by AfterShip where the user completes the flow. |\n\n## 3. Integration Flow Design\n\n### 3.1 Flowchart and Interaction Description\n\nThe integration flow is shown below:\n\n```mermaid\nflowchart TD\n    A[\"User initiates Create or Edit\"] --> B[\"Host frontend requests Signed URL from backend\"]\n    B --> C[\"Backend returns Signed URL\"]\n    C --> D[\"Frontend calls sdk.open({ url: signedUrl, ... })\"]\n    D --> E[\"SDK opens AfterShip Hosted UI in a popup window\"]\n    E --> F[\"User completes the carrier account flow\"]\n    F --> G{\"Final popup result\"}\n    G -->|Success| H[\"onSuccess({ request_id?, shipper_account_id, action })\"]\n    G -->|Runtime error| I[\"onError({ request_id?, code, message })\"]\n    G -->|Closed| J[\"onClose({ request_id?, reason })\"]\n```\n\nTypical user interaction:\n\n1. The user clicks a button or toggles a control in your application.\n2. Your frontend asks your backend for a Signed URL.\n3. Your frontend calls the SDK with that Signed URL.\n4. The SDK opens the popup window and waits for the hosted flow to finish.\n5. Your page updates its state according to the returned callback result.\n\n### 3.2 How the Signed URL and Popup Flow Work\n\nThis SDK assumes that your frontend receives a Signed URL from your backend or another trusted integration layer.\n\nWhy this design:\n\n- The popup is opened with a request-specific URL instead of static credentials.\n- The frontend only needs to pass the URL into the SDK.\n- The SDK isolates popup lifecycle handling from your application code.\n\nWhat the SDK handles on your behalf:\n\n1. Validating the Signed URL format and protocol.\n2. Opening and closing the popup window.\n3. Listening for messages returned from the popup window.\n4. Matching messages by `request_id` when available.\n5. Normalizing the final browser-side result into `onSuccess`, `onError`, or `onClose`.\n\nWhat remains outside the SDK scope:\n\n- generating the Signed URL\n- deciding when to start Create or Edit\n- updating your own business state after the callback returns\n- persisting any mapping between your entities and `shipper_account_id`\n\n## 4. What the Client Needs to Implement\n\nThe integration normally involves both frontend and backend work. The sections below outline the responsibilities for each side.\n\n### 4.1 Backend Responsibilities\n\nYour backend should:\n\n1. Prepare a Signed URL for the requested action.\n2. Return that Signed URL to the frontend.\n3. Provide the frontend with the correct business context for Create or Edit.\n\nCommon patterns:\n\n- Create flow: prepare a Signed URL associated with a new connection attempt, often including a new `request_id`.\n- Edit flow: prepare a Signed URL associated with an existing `shipper_account_id`.\n\n### 4.2 Frontend Responsibilities\n\nYour frontend should:\n\n1. Initialize the SDK on the page where the user starts the carrier account flow.\n2. Request a Signed URL before calling `sdk.open(...)`.\n3. Call the SDK from a user-triggered action whenever possible.\n4. Update the page state according to the callback result.\n5. Call `sdk.destroy()` when the page or integration surface is unloaded.\n\n### 4.3 Suggested Create and Edit Sequences\n\nCreate flow:\n\n```mermaid\nsequenceDiagram\n    participant Frontend as Host Frontend\n    participant Backend as Host Backend\n    participant SDK as AfterShip SDK\n    participant AfterShip as AfterShip Hosted UI\n\n    Frontend->>Backend: Request Signed URL for create\n    Backend-->>Frontend: Return Signed URL\n    Frontend->>SDK: sdk.open({ url: signedUrl, ... })\n    SDK->>AfterShip: Open popup with Signed URL\n    AfterShip-->>SDK: Return success / error / close result\n    SDK-->>Frontend: Trigger callback\n    Frontend->>Frontend: Update UI state\n```\n\nEdit flow:\n\n```mermaid\nsequenceDiagram\n    participant Frontend as Host Frontend\n    participant Backend as Host Backend\n    participant SDK as AfterShip SDK\n    participant AfterShip as AfterShip Hosted UI\n\n    Frontend->>Backend: Request Signed URL for edit\n    Backend-->>Frontend: Return Signed URL\n    Frontend->>SDK: sdk.open({ url: signedUrl, ... })\n    SDK->>AfterShip: Open popup with Signed URL\n    AfterShip-->>SDK: Return success / error / close result\n    SDK-->>Frontend: Trigger callback\n    Frontend->>Frontend: Update UI state\n```\n\n## 5. SDK Reference\n\n### 5.1 Installation\n\n```bash\npnpm add @aftership/carrier-account-sdk\n```\n\n### 5.2 Initialization\n\n```ts\nimport { init } from \"@aftership/carrier-account-sdk\";\n\nconst sdk = init();\n```\n\n### 5.3 `sdk.open(...)`\n\n```ts\nsdk.open({\n  url,\n  onSuccess(payload) {},\n  onError(payload) {},\n  onClose(payload) {},\n});\n```\n\nParameter reference:\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `url` | `string` | A Signed URL. It must be a valid absolute URL. |\n| `onSuccess` | `(payload) => void` | Called when the user completes the flow successfully. |\n| `onError` | `(payload) => void` | Called when the flow cannot continue because of invalid URLs or runtime errors. |\n| `onClose` | `(payload) => void` | Called when a popup that was opened is later closed. |\n\n### 5.4 Minimal Integration Example\n\n```ts\nimport { init } from \"@aftership/carrier-account-sdk\";\n\nconst sdk = init();\n\nasync function connectCarrier() {\n  const signedUrl = await getSignedUrlFromBackend();\n\n  sdk.open({\n    url: signedUrl,\n    onSuccess(payload) {\n      console.log(\"connect success\", payload);\n    },\n    onError(payload) {\n      console.error(\"connect error\", payload);\n    },\n    onClose(payload) {\n      console.log(\"popup closed\", payload);\n    },\n  });\n}\n\nwindow.addEventListener(\"beforeunload\", () => {\n  sdk.destroy();\n});\n```\n\n### 5.5 Callback Payloads\n\n#### `onSuccess`\n\nCalled when the user completes the flow successfully.\n\n```ts\n{\n  request_id?: string;\n  shipper_account_id: string;\n  action: \"create\" | \"edit\";\n}\n```\n\nField reference:\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `request_id` | `string \\| undefined` | The request identifier when available. |\n| `shipper_account_id` | `string` | The resulting carrier account identifier. |\n| `action` | `\"create\" \\| \"edit\"` | The final completed action. |\n\n#### `onError`\n\nCalled when the flow cannot continue before completion.\n\n```ts\n{\n  request_id?: string;\n  code: string;\n  message: string;\n}\n```\n\nField reference:\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `request_id` | `string \\| undefined` | The request identifier when available. |\n| `code` | `string` | A normalized error code. |\n| `message` | `string` | A normalized human-readable error message. |\n\nCommon error codes:\n\n- `INVALID_URL`: the Signed URL is not a valid absolute URL\n- `INVALID_PROTOCOL`: the Signed URL does not use an allowed protocol\n#### `onClose`\n\nCalled when the popup window is closed.\n\n```ts\n{\n  request_id?: string;\n  reason: \"user_closed\" | \"unknown\";\n}\n```\n\nField reference:\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `request_id` | `string \\| undefined` | The request identifier when available. |\n| `reason` | `\"user_closed\" \\| \"unknown\"` | The normalized close reason. |\n\nClose reasons:\n\n- `user_closed`: the user closed the popup manually\n- `unknown`: the popup closed without a more specific reason\n\n### 5.6 URL Requirements\n\nThe SDK requires the `url` passed to `sdk.open(...)` to be a valid Signed URL.\n\nAllowed protocols:\n\n```text\nProduction:\n  https://\n\nLocal development:\n  http://localhost\n  http://127.0.0.1\n  http://[::1]\n  http://::1\n```\n\nIf the URL is invalid, the SDK will trigger `onError` immediately.\n\nValidation behavior:\n\n- invalid absolute URL -> `INVALID_URL`\n- unsupported protocol -> `INVALID_PROTOCOL`\n\n## 6. Troubleshooting and FAQ\n\n### 6.1 Why did I not receive `onSuccess`?\n\nCheck in this order:\n\n1. Confirm the Signed URL is valid.\n2. Confirm the popup flow actually reached a successful end state.\n3. Confirm the `request_id` still matches the current request when applicable.\n4. Confirm your page did not destroy the SDK instance too early.\n\n### 6.2 What should I do if the popup does not open?\n\nRecommended practice:\n\n- call `sdk.open(...)` directly from a user click or similar user-triggered action\n- use `request_id` from the payload when it is available\n\n### 6.3 What should I do when the page is unloaded?\n\nCall:\n\n```ts\nsdk.destroy();\n```\n\nThis closes the popup if it is still open and removes related listeners.\n\n### 6.4 What is the simplest mental model for this SDK?\n\n```mermaid\nflowchart LR\n    A[\"Prepare Signed URL\"] --> B[\"Call sdk.open(...)\"]\n    B --> C[\"Handle callback result\"]\n```\n\nIn most integrations, you only need to do these three things:\n\n1. Prepare the Signed URL.\n2. Call `sdk.open(...)`.\n3. Update your business state according to the callback result.\n\n## 7. Debugging Tips\n\nIf you want to verify the flow quickly, you can refer to the example in the repository:\n\n```text\napps/example\n```\n\nPlease note:\n\n- the example is mainly used to verify popup behavior and callback handling\n- you should not treat the example integration as your production implementation directly\n","readmeFilename":"README.md","_rev":"1-8c2d48536df4ef4cb5a8ca627ee34ae8"}