{"_id":"@1ecomm/app-bridge","_rev":"2-806928bc977f0b7e13e7d5c5547e7616","name":"@1ecomm/app-bridge","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@1ecomm/app-bridge","version":"0.1.0","keywords":["1ecomm","app-bridge","ecommerce","embedded-app","sdk"],"license":"MIT","_id":"@1ecomm/app-bridge@0.1.0","maintainers":[{"name":"chengwang-cc","email":"cwang@digitrend.ca"}],"homepage":"https://developer.1ecomm.com/docs","bugs":{"url":"https://github.com/phessage/ecommerce-app-studio/issues"},"dist":{"shasum":"f0f68189aaec7790a9b4215f77fd40ffc5e25050","tarball":"https://registry.npmjs.org/@1ecomm/app-bridge/-/app-bridge-0.1.0.tgz","fileCount":7,"integrity":"sha512-/zk33JOB5w54byBucyVE7jDcYfy1yA6hs2Qct6tE/J9HqpvT8jyu6TuQbex0mwdOFki00zVoHll4IFqvAsGxdA==","signatures":[{"sig":"MEUCIQDefUIC65PSEA+DmrEMDPLxg6NKAGT8yKNudhzWcnkXwgIgH0cKy1Xrl4HtN2aRB70uo5rZy+BZvaENN68gTn0VK6g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17985},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"212fe2875aca3ddbaef97eaee87426ba6c7c8f2c","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepublishOnly":"tsc -p tsconfig.build.json"},"_npmUser":{"name":"chengwang-cc","email":"cwang@digitrend.ca"},"repository":{"url":"git+https://github.com/phessage/ecommerce-app-studio.git","type":"git","directory":"libs/app-bridge"},"_npmVersion":"10.9.8","description":"Framework-agnostic client SDK a 1ecomm app imports to talk to the platform host (App Bridge protocol): signed context, session tokens, scope-enforced API access, resize/toast/modal/navigate.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/app-bridge_0.1.0_1784388042376_0.4963154766054745","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@1ecomm/app-bridge","version":"0.2.0","description":"Framework-agnostic client SDK a 1ecomm app imports to talk to the platform host (App Bridge protocol): signed context, session tokens, scope-enforced API access, resize/toast/modal/navigate.","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"tsc -p tsconfig.build.json","test":"jest","prepublishOnly":"tsc -p tsconfig.build.json"},"repository":{"type":"git","url":"git+https://github.com/phessage/ecommerce-app-studio.git","directory":"libs/app-bridge"},"homepage":"https://developer.1ecomm.com/docs","keywords":["1ecomm","app-bridge","ecommerce","embedded-app","sdk"],"license":"MIT","publishConfig":{"access":"public"},"_id":"@1ecomm/app-bridge@0.2.0","gitHead":"3588dc0bfc72c474d6b446ea71b493fe0f447322","bugs":{"url":"https://github.com/phessage/ecommerce-app-studio/issues"},"_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-a5SZ9+ojVYn1N+XlJRQ+bDgSxyFQH0ir+tGVG9XeIfVJtmwyLvsIP4i13hCjOIpXIHaitlPaPEOVKVpKZI9EVA==","shasum":"eefa2fb3f79ae110da3b02478426916d20ae28e9","tarball":"https://registry.npmjs.org/@1ecomm/app-bridge/-/app-bridge-0.2.0.tgz","fileCount":7,"unpackedSize":20204,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCSpeM5kPHm7ZreHvUAS3NZ7QRjls3IUhkm7Z5CRDx6xgIgcum7GZtJBWqFSpqMzFAgm0CGoszcSdmEFLL1HuDLjF0="}]},"_npmUser":{"name":"chengwang-cc","email":"cwang@digitrend.ca"},"directories":{},"maintainers":[{"name":"chengwang-cc","email":"cwang@digitrend.ca"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/app-bridge_0.2.0_1784416700658_0.8829986250691395"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-18T15:20:42.207Z","modified":"2026-07-18T23:18:20.949Z","0.1.0":"2026-07-18T15:20:42.514Z","0.2.0":"2026-07-18T23:18:20.789Z"},"bugs":{"url":"https://github.com/phessage/ecommerce-app-studio/issues"},"license":"MIT","homepage":"https://developer.1ecomm.com/docs","keywords":["1ecomm","app-bridge","ecommerce","embedded-app","sdk"],"repository":{"type":"git","url":"git+https://github.com/phessage/ecommerce-app-studio.git","directory":"libs/app-bridge"},"description":"Framework-agnostic client SDK a 1ecomm app imports to talk to the platform host (App Bridge protocol): signed context, session tokens, scope-enforced API access, resize/toast/modal/navigate.","maintainers":[{"name":"chengwang-cc","email":"cwang@digitrend.ca"}],"readme":"# @1ecomm/app-bridge\n\nThe client SDK for building embedded apps on the [1ecomm](https://developer.1ecomm.com) commerce platform. It runs inside your app's sandboxed iframe and speaks a versioned, origin-validated `postMessage` protocol to the platform host, which holds your signed installation context and proxies scope-enforced API calls.\n\nZero dependencies, framework-agnostic, ~2 kB. Works with any stack that renders a page — React, Angular, Vue, or plain HTML.\n\n## Install\n\n```sh\nnpm install @1ecomm/app-bridge\n```\n\n## Quickstart\n\n```ts\nimport { createAppBridge } from '@1ecomm/app-bridge';\n\nconst bridge = createAppBridge({ hostOrigin: 'https://developer.1ecomm.com' });\n\n// Signed context: who installed you, where you're mounted, what you're granted.\nconst ctx = await bridge.getContext(); // { installationId, appId, siteId, accountId, userId, surfaceKey, grantedScopes, locale? }\n\n// Scope-enforced platform data — the host attaches your session token.\nconst products = await bridge.apiFetch('/products', { query: { limit: '20' } });\n\n// Writes take a JSON body.\nawait bridge.apiFetch(`/products/${id}/metafields/myapp/rating`, {\n  method: 'PUT',\n  body: { value: 5 },\n});\n\n// Host UI affordances.\nbridge.resize(document.body.scrollHeight); // keep the iframe fitted\nbridge.toast('Saved');\nawait bridge.modal({ title: 'Delete?', message: 'This cannot be undone.', variant: 'danger' });\nbridge.navigate('/studio/apps'); // in-app host paths only\n```\n\n## How it works\n\n- **Handshake.** The SDK announces `ready`; the host answers with your signed `AppBridgeContext`. `getContext()` resolves then (or immediately once received).\n- **Origin validation.** Every inbound message is checked against `hostOrigin` and the protocol channel/version; anything else is dropped.\n- **Nonce-matched requests.** Every call is a promise matched to a host response by request id, with a timeout (`timeoutMs`, default 10 s).\n- **Scopes are server-enforced.** `apiFetch` is proxied with your installation's session token; calls outside your granted scopes return a 403 naming the missing scope. Never store platform cookies or tokens yourself — the bridge is the only credential path you need.\n- **Cleanup.** Call `destroy()` when your surface unmounts to detach the listener and reject in-flight requests.\n\n## API\n\n| Member | Purpose |\n| --- | --- |\n| `createAppBridge(options)` | Create a bridge. `hostOrigin` is required; `window`/`host`/`generateId` are injectable for tests. |\n| `bridge.getContext()` | Resolves with the signed `AppBridgeContext` after the host handshake. |\n| `bridge.getSessionToken()` | Exchange the context for a scoped session token (for calling the platform API directly). |\n| `bridge.apiFetch(path, init?)` | Proxied, scope-enforced API call. `init`: `{ method?, query?, body? }`. |\n| `bridge.resize(height)` | Fit the host iframe to your content. |\n| `bridge.navigate(path)` | Ask the host to navigate (in-app paths only). |\n| `bridge.toast(text)` / `bridge.modal(options)` | Host-rendered notifications and dialogs. |\n| `bridge.destroy()` | Detach listeners, reject pending requests. |\n\n## Docs\n\nFull platform documentation — manifest reference, scopes and events catalogs, review rules, and the Studio IDE — lives at **[developer.1ecomm.com/docs](https://developer.1ecomm.com/docs)**.\n\n## License\n\nMIT © Digitrend\n","readmeFilename":"README.md"}