{"_id":"@aftership/ads-core","_rev":"8-2d0bd212dff45d203333ee158dcc5687","name":"@aftership/ads-core","dist-tags":{"latest":"0.4.1"},"versions":{"0.1.0":{"name":"@aftership/ads-core","version":"0.1.0","_id":"@aftership/ads-core@0.1.0","maintainers":[{"name":"aftership","email":"sdk@aftership.com"}],"dist":{"shasum":"b8c80a0c8631b685dea752aaf11ef600735a5f48","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.1.0.tgz","fileCount":21,"integrity":"sha512-2lXSQh8EUYUsYBwz7QEKACo+0dBFXyIDj0xtg1u6w7s9nhrbnJDdVKFm1twzTpSwBe+fYij60c3XuIySfc8qWw==","signatures":[{"sig":"MEQCIEz64f84/SSw7iovBfkyQYOe/5akXufLS3Q3xkNxflX+AiA/nLbO2ldD/EaW5zW+/7JhM0O4dSOFEYJuebqq1kSsLw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35691},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"fa99ea94483c52b9cebae9e7283414f8c97db756","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.1.0_1784526255330_0.9027192285683807","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aftership/ads-core","version":"0.2.0","_id":"@aftership/ads-core@0.2.0","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"dist":{"shasum":"1f17f08a882f7db200efeeebb27b99af1aaab31c","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.2.0.tgz","fileCount":21,"integrity":"sha512-fXqDwo4TUNF305LGxJIS7B5IdPhNZwTzqSATsJK9eadkweJdFEqgOX8KYln2tIQXVQWUjXkVl4PeXCYTl5fy+g==","signatures":[{"sig":"MEYCIQDA/cOyDlXcT68vc6fLU5f705cEiOcehbeTrJymZAEmwAIhAL6CuhQvyRJ8GSAGS6loWESKoEINMBGervozGKKvabc0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38010},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"c3f5bbb23522eaee2f9d28779acc790274f00d41","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.2.0_1784790431245_0.2648017908029432","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aftership/ads-core","version":"0.3.0","_id":"@aftership/ads-core@0.3.0","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"dist":{"shasum":"46e22cf238c971ffa68f07ae69e10fb2f570fe5b","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.3.0.tgz","fileCount":22,"integrity":"sha512-J9IWwJ2G70a5ilxOUYfByv5W61GlkQTuXuaW6nWqQpmWj0eJzkHAaun5vOGnIv+ehTmTXAkEUXvzSkbE15vuFQ==","signatures":[{"sig":"MEYCIQDiXRdIAsTvioMRgAO3izIo9SXe9kgPYc/bZWeGVbxlPgIhALogzKKdDxKPK9t2hHjvyu5OWD7nr6ogbvlUyyI8TnBG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41888},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"6f1d8a9f75e926eaa69be86fa3f8311a42835399","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.3.0_1785220731497_0.16252710572784457","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aftership/ads-core","version":"0.3.1","_id":"@aftership/ads-core@0.3.1","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"dist":{"shasum":"cbca314ac44effede6b093697244038046f82931","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.3.1.tgz","fileCount":22,"integrity":"sha512-EWFHkdzRPZ0ByeSBNHdsYYTFIWx3mvwQUNOPiGPY2GNeNTqz887RmgSmYnACno37EjtXB6Lp/zlBo6fptB0Q4Q==","signatures":[{"sig":"MEUCIQCI4NShZYWIJj37nCt+bcNfFuys7rUCcPG827CmC7MREQIgSCvE9sxd4Man1PsrDKDLHYPIxzNFpyz1FHHhxi1V7aE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42740},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"85347be2f0de2d599836878626208fca47d91ebe","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.3.1_1785305492614_0.7096793231150944","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aftership/ads-core","version":"0.3.2","_id":"@aftership/ads-core@0.3.2","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"dist":{"shasum":"f39912e95eee70a50f4e3ff5e1942b50a817f420","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.3.2.tgz","fileCount":22,"integrity":"sha512-ZGpQH3ettbDbt7OQgFWbatmYMKVmomVkYKZwICY5GrKsaOoEaxvOUAvzuaGFHqX1iTAnRvq7kbhZNE+yPL2ZvQ==","signatures":[{"sig":"MEUCIQCQZxSab2K54RqVtqaIA3VEaMyNY12Ihq1BwFAcQ0JAggIgXCYg7wM9ao4i5Ly1We739ca+u74vsV90m1cPs+Ns31M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42913},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"757c11bca2671e30525397642958849dc64baffa","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.3.2_1785764945301_0.0891893822532317","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aftership/ads-core","version":"0.4.0","_id":"@aftership/ads-core@0.4.0","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"dist":{"shasum":"40741c80393dbe1bc76ba5f5ccf61130f2f0ea33","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.4.0.tgz","fileCount":22,"integrity":"sha512-bTTrxqybBb2r7e2SQIDHS3iTrdHd+/oy0kmJ1yi9NL9wRol/348CwX81jzhTsuaV/YKyg8+tdIty4e+Je9K7mg==","signatures":[{"sig":"MEYCIQC5VjR+J9JOTEFpNGnDEeDXDKEam8Y2o0984je7RWGGXQIhALpdMiTgI/2G8S1wDM0E3rfPLJ4RSZwUwpvd7y50lpRv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43406},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"492596e97330f7003fd9da6380ba1c7b2ef8506e","scripts":{"dev":"tsc -p tsconfig.build.json --watch","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"_npmVersion":"10.9.4","description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ads-core_0.4.0_1788140090589_0.08287140711701046","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@aftership/ads-core","version":"0.4.1","publishConfig":{"access":"public"},"description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","type":"module","main":"./dist/index.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":"tsc -p tsconfig.build.json","dev":"tsc -p tsconfig.build.json --watch","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run"},"devDependencies":{"typescript":"^5.7.2","vitest":"^2.1.8"},"_id":"@aftership/ads-core@0.4.1","gitHead":"9be66381b9547e39be641d9b141baf368f4a544b","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-ERloPpgKRBvFuGhuJem4+1ieszTWPwrr+amBQw0OFijQDK4e331Syc1Vl6xfD7f1CMEpqoJJFZ0yPmC3Xtn21g==","shasum":"32e39f79e3c4de889fbe178194c92847c8f276a9","tarball":"https://registry.npmjs.org/@aftership/ads-core/-/ads-core-0.4.1.tgz","fileCount":22,"unpackedSize":44491,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGgmpt3wPHOsiOKbDfP2y272VZVvaJIor6nbi4DWdKKRAiEA0M6A8b4eqHnHt3/szbDhr5NTNjEWddTKC/+VbikG4BM="}]},"_npmUser":{"name":"aftership","email":"sdk@aftership.com"},"directories":{},"maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ads-core_0.4.1_1788142209090_0.5195065248505486"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-20T05:44:15.142Z","modified":"2026-08-31T02:10:09.414Z","0.1.0":"2026-07-20T05:44:15.477Z","0.2.0":"2026-07-23T07:07:11.412Z","0.3.0":"2026-07-28T06:38:51.677Z","0.3.1":"2026-07-29T06:11:32.773Z","0.3.2":"2026-08-03T13:49:05.472Z","0.4.0":"2026-08-31T01:34:50.716Z","0.4.1":"2026-08-31T02:10:09.225Z"},"description":"Headless isomorphic core for AfterShip Ads self-render channel: frozen decision contract types, fail-safe client with injectable fetcher, mock decision source, and event hooks. Zero dependencies, zero DOM.","maintainers":[{"name":"aftership","email":"sdk@aftership.com"},{"name":"aftership-dev","email":"sre+aftership-dev@aftership.com"}],"readme":"# @aftership/ads-core\n\n自渲染 Ads 界面的 headless TypeScript 基础包。没有 runtime dependency，也不访问 DOM。\n\n## 职责\n\n- 导出标准化 decision、offer、theme、token context 和 host event 类型；\n- 接受注入的 decision fetcher，不自行选择 endpoint 或认证方式；\n- 把不可信 decision 响应清理为稳定的 nullable/array 结构；\n- 丢弃缺少必填 `id` 或 `target_url` 的 offer；\n- 把 timeout、transport failure 和畸形响应降级为空 decision；\n- 为测试和 renderer demo 提供确定性 mock 场景。\n\n它不直接调用 Ads backend、不渲染 UI、不存储 decision，也不向 `POST /v1/events` 转发 event。\n\n## 公开 API\n\n```ts\nimport {\n  createAdsClient,\n  createMockFetcher,\n  mockDecision,\n  type Decision,\n  type DecisionFetcher,\n} from \"@aftership/ads-core\";\n```\n\nHost 必须提供 `DecisionFetcher`。Browser host 应调用有授权的 BFF 或使用服务端注入数据；不得把内部 Ads decision endpoint 直接暴露给 browser。\n\n`createAdsClient` 默认使用 2.5 秒 host timeout，并始终 resolve。失败时返回：\n\n```ts\n{ decision_id: \"\", offers: [], attribution: null }\n```\n\n## 契约来源\n\n- HTTP schema：[OpenAPI](../../docs/contracts/openapi.yaml)\n- Decision 行为：[Decision 架构](../../docs/architecture/decisioning.md)\n- Event 行为：[Event 架构](../../docs/architecture/event-reporting.md)\n\n## 公开类型与事件模型\n\n`Placement` 为 `tracking_page`、`order_confirmation_page`、`tracking_update_email`，与 backend decision contract 一致。`Decision`（widget 级）与 `Offer`（offer 级）暴露 backend 签发的 `report_token`。\n\n`AdsEvent` 是 host callback（`AdsEventSink`）结构，不是 `POST /v1/events` 请求体。事件类型为 `widget_load`、`widget_display`、`offer_display`、`offer_click` 与 host-local 的 `no_fill`，并携带对应 `report_token`。host 负责把有 token 的事件经自身 BFF 转发到 `POST /v1/events`；`no_fill` 与无 `report_token` 的事件不转发。以 [OpenAPI](../../docs/contracts/openapi.yaml) 为契约事实来源。\n\n## 开发\n\n```bash\npnpm --filter @aftership/ads-core build\npnpm --filter @aftership/ads-core typecheck\npnpm --filter @aftership/ads-core test\n```\n\n- `src/types.ts`：公开类型；\n- `src/client.ts`：fail-safe 注入 client；\n- `src/sanitize.ts`：runtime 响应清理；\n- `src/mock.ts`：mock decision。\n","readmeFilename":"README.md"}