@endora-commerce/mod-delivery-methods 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/api/delivery-methods-client.d.ts +41 -0
  4. package/dist/admin/api/delivery-methods-client.d.ts.map +1 -0
  5. package/dist/admin/api/delivery-methods-client.js +20 -0
  6. package/dist/admin/api/delivery-methods-client.js.map +1 -0
  7. package/dist/admin/index.d.ts +34 -0
  8. package/dist/admin/index.d.ts.map +1 -0
  9. package/dist/admin/index.js +44 -0
  10. package/dist/admin/index.js.map +1 -0
  11. package/dist/admin/pages/DeliveryMethodsPage.d.ts +4 -0
  12. package/dist/admin/pages/DeliveryMethodsPage.d.ts.map +1 -0
  13. package/dist/admin/pages/DeliveryMethodsPage.js +167 -0
  14. package/dist/admin/pages/DeliveryMethodsPage.js.map +1 -0
  15. package/dist/admin/renderers/registry.d.ts +15 -0
  16. package/dist/admin/renderers/registry.d.ts.map +1 -0
  17. package/dist/admin/renderers/registry.js +18 -0
  18. package/dist/admin/renderers/registry.js.map +1 -0
  19. package/dist/backend/adapters/built-in-adapters.d.ts +46 -0
  20. package/dist/backend/adapters/built-in-adapters.d.ts.map +1 -0
  21. package/dist/backend/adapters/built-in-adapters.js +62 -0
  22. package/dist/backend/adapters/built-in-adapters.js.map +1 -0
  23. package/dist/backend/commands/delivery-method.commands.d.ts +61 -0
  24. package/dist/backend/commands/delivery-method.commands.d.ts.map +1 -0
  25. package/dist/backend/commands/delivery-method.commands.js +107 -0
  26. package/dist/backend/commands/delivery-method.commands.js.map +1 -0
  27. package/dist/backend/demo/reset.d.ts +12 -0
  28. package/dist/backend/demo/reset.d.ts.map +1 -0
  29. package/dist/backend/demo/reset.js +13 -0
  30. package/dist/backend/demo/reset.js.map +1 -0
  31. package/dist/backend/demo/rows.d.ts +24 -0
  32. package/dist/backend/demo/rows.d.ts.map +1 -0
  33. package/dist/backend/demo/rows.js +22 -0
  34. package/dist/backend/demo/rows.js.map +1 -0
  35. package/dist/backend/demo/seed.d.ts +14 -0
  36. package/dist/backend/demo/seed.d.ts.map +1 -0
  37. package/dist/backend/demo/seed.js +28 -0
  38. package/dist/backend/demo/seed.js.map +1 -0
  39. package/dist/backend/entities/delivery-method.entity.d.ts +30 -0
  40. package/dist/backend/entities/delivery-method.entity.d.ts.map +1 -0
  41. package/dist/backend/entities/delivery-method.entity.js +91 -0
  42. package/dist/backend/entities/delivery-method.entity.js.map +1 -0
  43. package/dist/backend/index.d.ts +88 -0
  44. package/dist/backend/index.d.ts.map +1 -0
  45. package/dist/backend/index.js +144 -0
  46. package/dist/backend/index.js.map +1 -0
  47. package/dist/backend/routes.d.ts +51 -0
  48. package/dist/backend/routes.d.ts.map +1 -0
  49. package/dist/backend/routes.js +152 -0
  50. package/dist/backend/routes.js.map +1 -0
  51. package/dist/backend/services/delivery-method-read-port.d.ts +25 -0
  52. package/dist/backend/services/delivery-method-read-port.d.ts.map +1 -0
  53. package/dist/backend/services/delivery-method-read-port.js +56 -0
  54. package/dist/backend/services/delivery-method-read-port.js.map +1 -0
  55. package/dist/backend/services/delivery-method-reconciler.d.ts +97 -0
  56. package/dist/backend/services/delivery-method-reconciler.d.ts.map +1 -0
  57. package/dist/backend/services/delivery-method-reconciler.js +157 -0
  58. package/dist/backend/services/delivery-method-reconciler.js.map +1 -0
  59. package/dist/backend/services/order-status-registry.port.d.ts +50 -0
  60. package/dist/backend/services/order-status-registry.port.d.ts.map +1 -0
  61. package/dist/backend/services/order-status-registry.port.js +45 -0
  62. package/dist/backend/services/order-status-registry.port.js.map +1 -0
  63. package/dist/backend/services/registry-singleton.d.ts +20 -0
  64. package/dist/backend/services/registry-singleton.d.ts.map +1 -0
  65. package/dist/backend/services/registry-singleton.js +21 -0
  66. package/dist/backend/services/registry-singleton.js.map +1 -0
  67. package/dist/backend/services/shipment-usage-guard.d.ts +31 -0
  68. package/dist/backend/services/shipment-usage-guard.d.ts.map +1 -0
  69. package/dist/backend/services/shipment-usage-guard.js +33 -0
  70. package/dist/backend/services/shipment-usage-guard.js.map +1 -0
  71. package/dist/backend/services/shipping-adapter-registry.d.ts +98 -0
  72. package/dist/backend/services/shipping-adapter-registry.d.ts.map +1 -0
  73. package/dist/backend/services/shipping-adapter-registry.js +92 -0
  74. package/dist/backend/services/shipping-adapter-registry.js.map +1 -0
  75. package/dist/backend/services/shipping-method-eligibility.d.ts +24 -0
  76. package/dist/backend/services/shipping-method-eligibility.d.ts.map +1 -0
  77. package/dist/backend/services/shipping-method-eligibility.js +46 -0
  78. package/dist/backend/services/shipping-method-eligibility.js.map +1 -0
  79. package/dist/install/index.d.ts +59 -0
  80. package/dist/install/index.d.ts.map +1 -0
  81. package/dist/install/index.js +59 -0
  82. package/dist/install/index.js.map +1 -0
  83. package/dist/manifest.d.ts +193 -0
  84. package/dist/manifest.d.ts.map +1 -0
  85. package/dist/manifest.js +185 -0
  86. package/dist/manifest.js.map +1 -0
  87. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts +30 -0
  88. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts.map +1 -0
  89. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.js +72 -0
  90. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.js.map +1 -0
  91. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.d.ts +24 -0
  92. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.d.ts.map +1 -0
  93. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.js +28 -0
  94. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.js.map +1 -0
  95. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.d.ts +27 -0
  96. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.d.ts.map +1 -0
  97. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.js +44 -0
  98. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.js.map +1 -0
  99. package/dist/migrations/index.d.ts +29 -0
  100. package/dist/migrations/index.d.ts.map +1 -0
  101. package/dist/migrations/index.js +33 -0
  102. package/dist/migrations/index.js.map +1 -0
  103. package/dist/ports/index.d.ts +129 -0
  104. package/dist/ports/index.d.ts.map +1 -0
  105. package/dist/ports/index.js +2 -0
  106. package/dist/ports/index.js.map +1 -0
  107. package/docs/delivery_methods.md +197 -0
  108. package/i18n/en.json +5 -0
  109. package/i18n/pl.json +5 -0
  110. package/package.json +100 -0
  111. package/tailwind.css +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ <!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
2
+
3
+ # @endora-commerce/mod-delivery-methods
4
+
5
+ Shipping/delivery method definitions and per-channel availability.
6
+
7
+ ## What this is
8
+
9
+ An **Endora Commerce module package**. Its module id is `delivery_methods` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
10
+
11
+ A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
12
+
13
+ ## Entry points
14
+
15
+ | Import | Contents |
16
+ | --- | --- |
17
+ | `@endora-commerce/mod-delivery-methods` | the module manifest — its id, version, dependencies, settings and activation |
18
+ | `@endora-commerce/mod-delivery-methods/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
19
+ | `@endora-commerce/mod-delivery-methods/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
20
+ | `@endora-commerce/mod-delivery-methods/install` | the install surface: factories another module’s `installHook` constructs over its own `EntityManager` |
21
+ | `@endora-commerce/mod-delivery-methods/migrations` | the module’s own schema migrations, in the order the platform runs them |
22
+ | `@endora-commerce/mod-delivery-methods/ports` | type-only — the port interfaces other modules resolve this one through |
23
+ | `@endora-commerce/mod-delivery-methods/tailwind.css` | the Tailwind source declaration for the admin code above |
24
+
25
+ ## Depends on
26
+
27
+ Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
28
+
29
+ **Endora packages**
30
+
31
+ - `@endora-commerce/admin-kit` — *optional*
32
+ - `@endora-commerce/contracts`
33
+ - `@endora-commerce/platform`
34
+
35
+ **Third-party**
36
+
37
+ - `@mikro-orm/core` ^6
38
+ - `@mikro-orm/migrations` ^6
39
+ - `@mikro-orm/postgresql` ^6
40
+ - `fastify` ^5
41
+ - `lucide-react` ^1 — *optional*
42
+ - `react` ^19 — *optional*
43
+
44
+ ## What the tarball carries
45
+
46
+ - `dist/` — the compiled JavaScript and its type declarations
47
+ - `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
48
+ - `docs/` — the package’s own pages in the Endora Commerce documentation site
49
+ - `tailwind.css` — the Tailwind source declaration
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pnpm add @endora-commerce/mod-delivery-methods
55
+ ```
56
+
57
+ ## Licence
58
+
59
+ MIT — the text is in `LICENSE`, beside this file.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Typed admin client for delivery (shipping) methods (feature 035). Wraps the
3
+ * shared apiClient with the adapter-aware endpoints.
4
+ */
5
+ export interface AdminDeliveryMethod {
6
+ id: string;
7
+ code: string;
8
+ adapter: string;
9
+ name: Record<string, string>;
10
+ cost: {
11
+ amount: number;
12
+ currency: string;
13
+ };
14
+ status: 'active' | 'inactive';
15
+ statusOnSuccess: string;
16
+ statusOnFailure: string;
17
+ salesChannelIds: string[];
18
+ rendererKey: string | null;
19
+ }
20
+ export interface OrderStatusOption {
21
+ code: string;
22
+ label: string;
23
+ }
24
+ export interface DeliveryMethodUpsertBody {
25
+ code: string;
26
+ name: Record<string, string>;
27
+ cost: number;
28
+ currency: string;
29
+ status?: 'active' | 'inactive';
30
+ statusOnSuccess?: string;
31
+ statusOnFailure?: string;
32
+ salesChannelIds?: string[];
33
+ }
34
+ export declare const deliveryMethodsClient: {
35
+ list(): Promise<AdminDeliveryMethod[]>;
36
+ /** Shared endpoint owned by the payment-methods admin routes (same registry). */
37
+ orderStatuses(): Promise<OrderStatusOption[]>;
38
+ upsert(code: string, body: DeliveryMethodUpsertBody): Promise<AdminDeliveryMethod>;
39
+ remove(id: string): Promise<void>;
40
+ };
41
+ //# sourceMappingURL=delivery-methods-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-methods-client.d.ts","sourceRoot":"","sources":["../../../src/admin/api/delivery-methods-client.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,eAAO,MAAM,qBAAqB;YAClB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAO5C,iFAAiF;qBAC1D,OAAO,CAAC,iBAAiB,EAAE,CAAC;iBAKhC,MAAM,QAAQ,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC;eAQvE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { apiClient } from '@endora-commerce/admin-kit/lib';
2
+ export const deliveryMethodsClient = {
3
+ async list() {
4
+ const res = await apiClient.get('/api/v1/admin/delivery-methods');
5
+ return res.data;
6
+ },
7
+ /** Shared endpoint owned by the payment-methods admin routes (same registry). */
8
+ async orderStatuses() {
9
+ const res = await apiClient.get('/api/v1/admin/order-statuses');
10
+ return res.data;
11
+ },
12
+ async upsert(code, body) {
13
+ const res = await apiClient.put(`/api/v1/admin/delivery-methods/${encodeURIComponent(code)}`, body);
14
+ return res.data;
15
+ },
16
+ async remove(id) {
17
+ await apiClient.delete(`/api/v1/admin/delivery-methods/${id}`);
18
+ },
19
+ };
20
+ //# sourceMappingURL=delivery-methods-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-methods-client.js","sourceRoot":"","sources":["../../../src/admin/api/delivery-methods-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAkC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAC7B,gCAAgC,CACjC,CAAC;QACF,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,aAAa;QACjB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAgC,8BAA8B,CAAC,CAAC;QAC/F,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,IAA8B;QACvD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAC7B,kCAAkC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAC5D,IAAI,CACL,CAAC;QACF,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,SAAS,CAAC,MAAM,CAAO,kCAAkC,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;CACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * `delivery_methods`' admin surface — one route, one sidebar entry, one
3
+ * command-palette action (through the manifest) and **one zone it renders**
4
+ * (feature 091, Phase 4, batch 8;
5
+ * `specs/091-module-owned-admin-surfaces/contracts/admin-contribution.md`).
6
+ *
7
+ * **Its one boundary drain was `dictionaries`' currency picker**, which the
8
+ * screen renders to choose the currency a flat shipping rate is priced in.
9
+ * `backend/scripts/ledgers/cross-module-imports/delivery_methods.ts` recorded
10
+ * it; the picker is generic, so it moved into `@endora-commerce/admin-kit` and
11
+ * the shard is deleted rather than edited.
12
+ *
13
+ * **Its other drain is the one this module is in this batch for**, and it is a
14
+ * zone rather than an import. The list screen carried a hard-coded
15
+ * `dhl_parcel` block and a hard-coded `inpost` block — each with the other
16
+ * module's title, description, route and permission code — which
17
+ * `backend/scripts/ledgers/foreign-module-ids.ts` recorded as two
18
+ * `visibility-gate` couplings with this conversion as their retiring
19
+ * condition. `delivery_method.list.integrations` is the enum member the host
20
+ * renders; both carriers were already packaged, so the host and both
21
+ * contributions land together, which is why `plan.md` put all three here.
22
+ *
23
+ * **The baseline counted `nav: 2` and only one of them is a sidebar row** — the
24
+ * other was a `PALETTE_ITEMS` literal, which `adminNavEntries` reads because it
25
+ * carries `to` and `module`. It arrives as a manifest action
26
+ * (`open-delivery-methods`) instead, which is the surface the server's
27
+ * effective enabled-set filters rather than a copy nobody asked it about.
28
+ *
29
+ * **This entry exports data and nothing else** (R2); the component is a
30
+ * dynamic-import factory (R6).
31
+ */
32
+ import type { AdminContributions } from '@endora-commerce/admin-kit/contributions';
33
+ export declare const contributions: AdminContributions;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAKnF,eAAO,MAAM,aAAa,EAAE,kBAwC3B,CAAC"}
@@ -0,0 +1,44 @@
1
+ /** The module's only route: the shipping-method list and its editor form. */
2
+ const ROUTE_PATH = '/delivery-methods';
3
+ export const contributions = {
4
+ routes: [
5
+ {
6
+ path: ROUTE_PATH,
7
+ component: () => import('./pages/DeliveryMethodsPage.js'),
8
+ // `requireAdmin('delivery_methods:read')` on
9
+ // `GET /api/v1/admin/delivery-methods`, which the screen calls on mount,
10
+ // and the code its own `useSurfaceVisibility` gate has asked for since
11
+ // 2026-08-28 — the module stopped borrowing `catalog:read` then.
12
+ requiredPermission: 'delivery_methods:read',
13
+ index: true,
14
+ },
15
+ ],
16
+ nav: [
17
+ {
18
+ to: ROUTE_PATH,
19
+ // Module-relative (R8), out of
20
+ // `packages/modules/delivery_methods/i18n/`. `appShell.nav.deliveryMethods`
21
+ // **stayed** in `_i18n` through batch 8 rather than moving with this row:
22
+ // it was also the parent crumb of the two carrier trails that batch left
23
+ // standing (`/delivery-methods/dhl-parcel` and `/settings/inpost`, whose
24
+ // modules contribute no nav entry for `registryCrumbs` to derive from),
25
+ // so deleting it then would have rendered a raw key on two screens that
26
+ // batch did not touch. That was batch 7's `appShell.nav.paymentMethods`
27
+ // asymmetry, met a second time and for the same reason, and it retired
28
+ // when those two trails did — feature 134's wave 1 (FR-023), which took
29
+ // both `CRUMB_DICT` rules out because `dhl_parcel` and `inpost` leave
30
+ // this repository. `appShell.nav.paymentMethods` is still standing and
31
+ // retires with wave 2's five.
32
+ labelKey: 'nav.deliveryMethods.label',
33
+ icon: 'Truck',
34
+ section: 'pricing',
35
+ // Third of three in the hand-written *Pricing* table, after `/taxes`.
36
+ // Both surviving rows there are the host's, so a registry entry appends
37
+ // after them whatever it declares; the weight is what keeps this below
38
+ // `taxes`' 200 once the section converts.
39
+ weight: 300,
40
+ requiredPermission: 'delivery_methods:read',
41
+ },
42
+ ],
43
+ };
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAiCA,6EAA6E;AAC7E,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,MAAM,EAAE;QACN;YACE,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,gCAAgC,CAAC;YACzD,6CAA6C;YAC7C,yEAAyE;YACzE,uEAAuE;YACvE,iEAAiE;YACjE,kBAAkB,EAAE,uBAAuB;YAC3C,KAAK,EAAE,IAAI;SACZ;KACF;IACD,GAAG,EAAE;QACH;YACE,EAAE,EAAE,UAAU;YACd,+BAA+B;YAC/B,4EAA4E;YAC5E,0EAA0E;YAC1E,yEAAyE;YACzE,yEAAyE;YACzE,wEAAwE;YACxE,wEAAwE;YACxE,wEAAwE;YACxE,uEAAuE;YACvE,wEAAwE;YACxE,sEAAsE;YACtE,uEAAuE;YACvE,8BAA8B;YAC9B,QAAQ,EAAE,2BAA2B;YACrC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,SAAS;YAClB,sEAAsE;YACtE,wEAAwE;YACxE,uEAAuE;YACvE,0CAA0C;YAC1C,MAAM,EAAE,GAAG;YACX,kBAAkB,EAAE,uBAAuB;SAC5C;KACF;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function DeliveryMethodsPage(): ReactNode;
3
+ export default DeliveryMethodsPage;
4
+ //# sourceMappingURL=DeliveryMethodsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeliveryMethodsPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/DeliveryMethodsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAezF,wBAAgB,mBAAmB,IAAI,SAAS,CA4Q/C;AA6ID,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Pencil, Trash2 } from 'lucide-react';
4
+ import { ApiError, formatMoney, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
5
+ import { Alert, AlertDescription, Badge, Button, Card, CardContent, CardHeader, CardTitle, Input, Label, PageHeader, Select, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@endora-commerce/admin-kit/ui';
6
+ import { CurrencyPicker } from '@endora-commerce/admin-kit/components';
7
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
8
+ import { useAdminZone, AdminZone } from '@endora-commerce/admin-kit/zones';
9
+ import { deliveryMethodsClient, } from '../api/delivery-methods-client.js';
10
+ import { resolveAdminDeliveryMethodRenderer } from '../renderers/registry.js';
11
+ export function DeliveryMethodsPage() {
12
+ const t = useTranslation('core');
13
+ /**
14
+ * `useSurfaceVisibility` is the predicate the sidebar, the palette and the
15
+ * dashboard already share, and it answers both axes at once: the operator's
16
+ * permission and the owning module's effective presence. The DHL card below
17
+ * was already asking both questions by hand; this is the same question in one
18
+ * expression, which is what stops the two from drifting.
19
+ */
20
+ const isVisible = useSurfaceVisibility();
21
+ /**
22
+ * The screen's own gate (2026-08-28), on the code its routes now enforce.
23
+ *
24
+ * `delivery_methods` used to borrow `catalog:read`, so this page had no
25
+ * permission of its own to check and the sidebar entry beside it carried the
26
+ * catalogue's. Both moved together; hiding the screen rather than letting it
27
+ * 403 is the treatment the sidebar, the palette and the dashboard already
28
+ * apply to a denied destination, and `AppShell.tsx`'s `PALETTE_ITEMS` comment
29
+ * argues it at length. The module half is asked too, because the admin router
30
+ * carries no guard of its own: a switched-off module must contribute no
31
+ * surface at all (Constitution XVII item 5), and a permission gate alone
32
+ * leaves this screen rendering and answering 503.
33
+ *
34
+ * The fetch is skipped as well as the render — a page that renders nothing has
35
+ * no reason to ask the API two questions it will be refused.
36
+ */
37
+ const canRead = isVisible({
38
+ module: 'delivery_methods',
39
+ requiredPermission: 'delivery_methods:read',
40
+ });
41
+ /**
42
+ * The integrations card is a **zone** since feature 091's batch 8 (FR-007).
43
+ *
44
+ * It used to hold a hard-coded `dhl_parcel` block and a hard-coded `inpost`
45
+ * block, each carrying that module's title, description, route and permission
46
+ * code — two `visibility-gate` couplings in
47
+ * `backend/scripts/ledgers/foreign-module-ids.ts`, and the shape FR-007 cites
48
+ * by name: a module reaching into another module's screen because the screen
49
+ * offers nowhere to contribute to. Each carrier declares its own card now.
50
+ *
51
+ * The hook rather than `<AdminZone>` alone, because the **card** is this
52
+ * screen's and must not render empty: `useAdminZone` has already applied both
53
+ * axes and every contribution's own permission, so its length is the honest
54
+ * answer to "does this operator have any integration to see", and the old
55
+ * `showDhlParcel || showInpost` is that same question over a closed set of
56
+ * two.
57
+ */
58
+ const integrations = useAdminZone('delivery_method.list.integrations', {});
59
+ const [rows, setRows] = useState([]);
60
+ const [orderStatuses, setOrderStatuses] = useState([]);
61
+ const [loading, setLoading] = useState(true);
62
+ const [error, setError] = useState(null);
63
+ const [info, setInfo] = useState(null);
64
+ const [editing, setEditing] = useState(null);
65
+ const refresh = useCallback(async () => {
66
+ if (!canRead) {
67
+ setLoading(false);
68
+ return;
69
+ }
70
+ setLoading(true);
71
+ setError(null);
72
+ try {
73
+ const [methods, statuses] = await Promise.all([
74
+ deliveryMethodsClient.list(),
75
+ // Shared endpoint owned by the payment-methods admin routes (feature 035);
76
+ // gated `requireAdminAny(['payment_methods:read', 'delivery_methods:read'])`
77
+ // since this module took its own codes, so the read code that opened this
78
+ // screen also opens the status list.
79
+ deliveryMethodsClient.orderStatuses().catch(() => []),
80
+ ]);
81
+ setRows(methods);
82
+ setOrderStatuses(statuses);
83
+ }
84
+ catch (err) {
85
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Failed to load.');
86
+ }
87
+ finally {
88
+ setLoading(false);
89
+ }
90
+ }, [canRead]);
91
+ useEffect(() => {
92
+ void refresh();
93
+ }, [refresh]);
94
+ const handleUpsert = useCallback(async (input) => {
95
+ const name = {};
96
+ if (input.nameEn)
97
+ name['en-US'] = input.nameEn;
98
+ if (input.namePl)
99
+ name['pl-PL'] = input.namePl;
100
+ try {
101
+ await deliveryMethodsClient.upsert(input.code, {
102
+ code: input.code,
103
+ name,
104
+ cost: input.cost,
105
+ currency: input.currency,
106
+ status: input.status,
107
+ ...(input.statusOnSuccess ? { statusOnSuccess: input.statusOnSuccess } : {}),
108
+ ...(input.statusOnFailure ? { statusOnFailure: input.statusOnFailure } : {}),
109
+ });
110
+ setInfo(t('legacyMethods.messages.saved', { code: input.code }));
111
+ setEditing(null);
112
+ await refresh();
113
+ }
114
+ catch (err) {
115
+ setError(err instanceof ApiError ? err.envelope.error.message : t('legacyMethods.errors.save'));
116
+ }
117
+ }, [refresh]);
118
+ const handleEdit = useCallback((row) => {
119
+ setEditing(row);
120
+ setInfo(null);
121
+ setError(null);
122
+ window.scrollTo({ top: 0, behavior: 'smooth' });
123
+ }, []);
124
+ const handleDelete = useCallback(async (id) => {
125
+ if (!confirm(t('legacyMethods.delivery.deleteConfirm')))
126
+ return;
127
+ try {
128
+ await deliveryMethodsClient.remove(id);
129
+ await refresh();
130
+ }
131
+ catch (err) {
132
+ setError(err instanceof ApiError ? err.envelope.error.message : t('legacyMethods.errors.delete'));
133
+ }
134
+ }, [refresh]);
135
+ if (!canRead) {
136
+ return (_jsx(Alert, { children: _jsx(AlertDescription, { children: t('legacyMethods.delivery.noPermission') }) }));
137
+ }
138
+ return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: t('legacyMethods.delivery.title'), description: t('legacyMethods.delivery.description') }), error ? (_jsx(Alert, { variant: "destructive", className: "mb-4", children: _jsx(AlertDescription, { children: error }) })) : null, info ? (_jsx(Alert, { variant: "success", className: "mb-4", children: _jsx(AlertDescription, { children: info }) })) : null, integrations.length > 0 ? (_jsxs(Card, { className: "mb-4", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: t('legacyMethods.integrations.title') }) }), _jsxs(CardContent, { className: "space-y-3", children: [_jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: t('legacyMethods.integrations.shippingDescription') }), _jsx(AdminZone, { name: "delivery_method.list.integrations", props: {} })] })] })) : null, _jsxs(Card, { className: "mb-4", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: editing
139
+ ? t('legacyMethods.delivery.editTitle', { code: editing.code })
140
+ : t('legacyMethods.formTitle') }) }), _jsx(CardContent, { children: _jsx(UpsertForm, { editing: editing, onSubmit: handleUpsert, onCancel: () => setEditing(null), orderStatuses: orderStatuses }, editing?.id ?? 'new') })] }), _jsx(Card, { children: _jsx(CardContent, { className: "pt-6", children: loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('common.state.loading') })) : rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('legacyMethods.delivery.empty') })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t('legacyMethods.columns.code') }), _jsx(TableHead, { children: t('legacyMethods.columns.name') }), _jsx(TableHead, { children: "Adapter" }), _jsx(TableHead, { children: t('legacyMethods.columns.cost') }), _jsx(TableHead, { children: "On success / failure" }), _jsx(TableHead, { children: t('legacyMethods.columns.status') }), _jsx(TableHead, {})] }) }), _jsx(TableBody, { children: rows.map((r) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx("code", { className: "font-mono text-xs", children: r.code }) }), _jsx(TableCell, { children: resolveAdminDeliveryMethodRenderer(r.rendererKey)(r) }), _jsx(TableCell, { children: _jsx("code", { className: "font-mono text-xs", children: r.adapter }) }), _jsx(TableCell, { className: "tabular-nums", children: formatMoney(r.cost.amount, r.cost.currency) }), _jsxs(TableCell, { className: "text-xs text-muted-foreground", children: [r.statusOnSuccess, " / ", r.statusOnFailure] }), _jsx(TableCell, { children: _jsx(Badge, { variant: r.status === 'active' ? 'success' : 'secondary', children: t(`legacyMethods.status.${r.status}`) }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex justify-end gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", type: "button", onClick: () => handleEdit(r), children: [_jsx(Pencil, {}), t('common.action.edit')] }), _jsxs(Button, { variant: "destructive", size: "sm", type: "button", onClick: () => void handleDelete(r.id), children: [_jsx(Trash2, {}), t('common.action.delete')] })] }) })] }, r.id))) })] })) }) })] }));
141
+ }
142
+ function UpsertForm({ editing, onSubmit, onCancel, orderStatuses, }) {
143
+ const t = useTranslation('core');
144
+ const [code, setCode] = useState(editing?.code ?? '');
145
+ const [nameEn, setNameEn] = useState(editing?.name['en-US'] ?? '');
146
+ const [namePl, setNamePl] = useState(editing?.name['pl-PL'] ?? '');
147
+ const [cost, setCost] = useState(editing ? String(editing.cost.amount) : '0');
148
+ const [currency, setCurrency] = useState(editing?.cost.currency ?? 'PLN');
149
+ const [status, setStatus] = useState(editing?.status ?? 'active');
150
+ const [statusOnSuccess, setStatusOnSuccess] = useState(editing?.statusOnSuccess ?? '');
151
+ const [statusOnFailure, setStatusOnFailure] = useState(editing?.statusOnFailure ?? '');
152
+ return (_jsxs("form", { className: "space-y-4", onSubmit: (e) => {
153
+ e.preventDefault();
154
+ void onSubmit({
155
+ code,
156
+ nameEn,
157
+ namePl,
158
+ cost: Number(cost),
159
+ currency,
160
+ status,
161
+ statusOnSuccess,
162
+ statusOnFailure,
163
+ });
164
+ }, children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dcode", children: t('legacyMethods.fields.code') }), _jsx(Input, { id: "dcode", value: code, onChange: (e) => setCode(e.target.value), required: true, disabled: editing !== null, readOnly: editing !== null })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dnameen", children: t('legacyMethods.fields.nameEn') }), _jsx(Input, { id: "dnameen", value: nameEn, onChange: (e) => setNameEn(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dnamepl", children: t('legacyMethods.fields.namePl') }), _jsx(Input, { id: "dnamepl", value: namePl, onChange: (e) => setNamePl(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dcost", children: t('legacyMethods.fields.cost') }), _jsx(Input, { id: "dcost", type: "number", step: "0.01", min: "0", value: cost, onChange: (e) => setCost(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dcur", children: t('legacyMethods.fields.currency') }), _jsx(CurrencyPicker, { id: "dcur", value: currency, onChange: (e) => setCurrency(e.target.value), required: true })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dstatus", children: t('legacyMethods.fields.status') }), _jsxs(Select, { id: "dstatus", value: status, onChange: (e) => setStatus(e.target.value), children: [_jsx("option", { value: "active", children: t('legacyMethods.status.active') }), _jsx("option", { value: "inactive", children: t('legacyMethods.status.inactive') })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dsuccess", children: "Order status on shipment success" }), _jsxs(Select, { id: "dsuccess", value: statusOnSuccess, onChange: (e) => setStatusOnSuccess(e.target.value), children: [_jsx("option", { value: "", children: "(default: shipped)" }), orderStatuses.map((s) => (_jsx("option", { value: s.code, children: s.label }, s.code)))] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dfailure", children: "Order status on shipment failure" }), _jsxs(Select, { id: "dfailure", value: statusOnFailure, onChange: (e) => setStatusOnFailure(e.target.value), children: [_jsx("option", { value: "", children: "(default: in_fulfilment)" }), orderStatuses.map((s) => (_jsx("option", { value: s.code, children: s.label }, s.code)))] })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { type: "submit", children: t('common.action.save') }), editing ? (_jsx(Button, { type: "button", variant: "outline", onClick: onCancel, children: t('common.action.cancel') })) : null] })] }));
165
+ }
166
+ export default DeliveryMethodsPage;
167
+ //# sourceMappingURL=DeliveryMethodsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeliveryMethodsPage.js","sourceRoot":"","sources":["../../../src/admin/pages/DeliveryMethodsPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { AdminDeliveryMethod } from '../api/delivery-methods-client.js';
3
+ /**
4
+ * Admin shipping-method renderer registry (feature 035, FR-016/FR-017).
5
+ *
6
+ * An adapter may register a custom renderer for how its method appears in the
7
+ * admin list (keyed by the adapter's `renderers.admin`). When none is
8
+ * registered, the platform default renderer is used — so every method always
9
+ * renders in the admin surface.
10
+ */
11
+ export type AdminDeliveryMethodRenderer = (method: AdminDeliveryMethod) => ReactNode;
12
+ export declare const DefaultAdminDeliveryMethodRenderer: AdminDeliveryMethodRenderer;
13
+ export declare function registerAdminDeliveryMethodRenderer(key: string, renderer: AdminDeliveryMethodRenderer): void;
14
+ export declare function resolveAdminDeliveryMethodRenderer(rendererKey: string | null): AdminDeliveryMethodRenderer;
15
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/admin/renderers/registry.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,SAAS,CAAC;AAMrF,eAAO,MAAM,kCAAkC,EAAE,2BAIhD,CAAC;AAIF,wBAAgB,mCAAmC,CACjD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,2BAA2B,GACpC,IAAI,CAEN;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,2BAA2B,CAM7B"}
@@ -0,0 +1,18 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ function pickName(name) {
3
+ return name['en-US'] ?? name.default ?? Object.values(name)[0] ?? '';
4
+ }
5
+ export const DefaultAdminDeliveryMethodRenderer = (method) => (_jsxs("span", { children: [pickName(method.name), " ", _jsxs("code", { className: "font-mono text-xs", children: ["(", method.adapter, ")"] })] }));
6
+ const registry = new Map();
7
+ export function registerAdminDeliveryMethodRenderer(key, renderer) {
8
+ registry.set(key, renderer);
9
+ }
10
+ export function resolveAdminDeliveryMethodRenderer(rendererKey) {
11
+ if (rendererKey) {
12
+ const found = registry.get(rendererKey);
13
+ if (found)
14
+ return found;
15
+ }
16
+ return DefaultAdminDeliveryMethodRenderer;
17
+ }
18
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/admin/renderers/registry.tsx"],"names":[],"mappings":";AAaA,SAAS,QAAQ,CAAC,IAA4B;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,kCAAkC,GAAgC,CAAC,MAAM,EAAE,EAAE,CAAC,CACzF,2BACG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAE,gBAAM,SAAS,EAAC,mBAAmB,kBAAG,MAAM,CAAC,OAAO,SAAS,IAChF,CACR,CAAC;AAEF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuC,CAAC;AAEhE,MAAM,UAAU,mCAAmC,CACjD,GAAW,EACX,QAAqC;IAErC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,WAA0B;IAE1B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,kCAAkC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { ShippingAdapter, ShippingEligibilityContext, OrderCreatedContext, ShipmentCreatedContext, StartShipmentResult, ReceiveShipmentContext, ShipmentOutcome } from '@endora-commerce/contracts';
2
+ /**
3
+ * Built-in shipping adapters (feature 035). Two bundled offline reference
4
+ * adapters — neither needs an external carrier, so the full
5
+ * order_created → shipment_created → receive_shipment lifecycle is testable
6
+ * end-to-end out of the box (FR-004, SC-003).
7
+ *
8
+ * Validators default to `() => true` (FR-010). `onOrderCreated` is a no-op
9
+ * (the spec allows skipping it). `onReceiveShipment` echoes the outcome the
10
+ * ingress already validated — the offline adapters are settled by an admin /
11
+ * out-of-band.
12
+ */
13
+ declare abstract class BaseShippingAdapter implements ShippingAdapter {
14
+ abstract readonly adapterKey: string;
15
+ validateUseOnStorefront(_ctx: ShippingEligibilityContext): Promise<boolean>;
16
+ validateUseOnAdmin(_ctx: ShippingEligibilityContext): Promise<boolean>;
17
+ validateUseInApi(_ctx: ShippingEligibilityContext): Promise<boolean>;
18
+ /** No creation-time work for the offline adapters. */
19
+ onOrderCreated(_ctx: OrderCreatedContext): Promise<void>;
20
+ abstract onShipmentCreated(ctx: ShipmentCreatedContext): Promise<StartShipmentResult>;
21
+ /**
22
+ * Default: the ingress is the source of truth for the outcome. Provider
23
+ * details and the external reference flow straight onto the Shipment row.
24
+ */
25
+ onReceiveShipment(ctx: ReceiveShipmentContext): Promise<ShipmentOutcome>;
26
+ }
27
+ /**
28
+ * Manual courier (`Wysyłka własna`) — an operator generates the parcel
29
+ * out-of-band and reports the outcome via `receive_shipment`.
30
+ */
31
+ export declare class ManualCourierAdapter extends BaseShippingAdapter {
32
+ readonly adapterKey = "manual_courier";
33
+ onShipmentCreated(): Promise<StartShipmentResult>;
34
+ }
35
+ /**
36
+ * Personal pickup (`Odbiór osobisty`) — no carrier; generation succeeds as soon
37
+ * as a shipment is opened (still confirmed via `receive_shipment`).
38
+ */
39
+ export declare class PersonalPickupAdapter extends BaseShippingAdapter {
40
+ readonly adapterKey = "personal_pickup";
41
+ onShipmentCreated(): Promise<StartShipmentResult>;
42
+ }
43
+ /** The adapters registered for the platform's built-in shipping methods. */
44
+ export declare function builtInShippingAdapters(): ShippingAdapter[];
45
+ export {};
46
+ //# sourceMappingURL=built-in-adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"built-in-adapters.d.ts","sourceRoot":"","sources":["../../../src/backend/adapters/built-in-adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC1B,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,uBAAe,mBAAoB,YAAW,eAAe;IAC3D,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE/B,uBAAuB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC;IAG3E,kBAAkB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC;IAGtE,gBAAgB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E,sDAAsD;IAChD,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,QAAQ,CAAC,iBAAiB,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAErF;;;OAGG;IACG,iBAAiB,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC;CAO/E;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,mBAAmB;IAC3D,QAAQ,CAAC,UAAU,oBAAoB;IAEjC,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAGxD;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,UAAU,qBAAqB;IAElC,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAGxD;AAED,4EAA4E;AAC5E,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Built-in shipping adapters (feature 035). Two bundled offline reference
3
+ * adapters — neither needs an external carrier, so the full
4
+ * order_created → shipment_created → receive_shipment lifecycle is testable
5
+ * end-to-end out of the box (FR-004, SC-003).
6
+ *
7
+ * Validators default to `() => true` (FR-010). `onOrderCreated` is a no-op
8
+ * (the spec allows skipping it). `onReceiveShipment` echoes the outcome the
9
+ * ingress already validated — the offline adapters are settled by an admin /
10
+ * out-of-band.
11
+ */
12
+ class BaseShippingAdapter {
13
+ async validateUseOnStorefront(_ctx) {
14
+ return true;
15
+ }
16
+ async validateUseOnAdmin(_ctx) {
17
+ return true;
18
+ }
19
+ async validateUseInApi(_ctx) {
20
+ return true;
21
+ }
22
+ /** No creation-time work for the offline adapters. */
23
+ async onOrderCreated(_ctx) {
24
+ return;
25
+ }
26
+ /**
27
+ * Default: the ingress is the source of truth for the outcome. Provider
28
+ * details and the external reference flow straight onto the Shipment row.
29
+ */
30
+ async onReceiveShipment(ctx) {
31
+ return {
32
+ result: 'success',
33
+ externalReference: ctx.externalReference ?? null,
34
+ ...(ctx.providerDetails ? { providerDetails: ctx.providerDetails } : {}),
35
+ };
36
+ }
37
+ }
38
+ /**
39
+ * Manual courier (`Wysyłka własna`) — an operator generates the parcel
40
+ * out-of-band and reports the outcome via `receive_shipment`.
41
+ */
42
+ export class ManualCourierAdapter extends BaseShippingAdapter {
43
+ adapterKey = 'manual_courier';
44
+ async onShipmentCreated() {
45
+ return { kind: 'pending' };
46
+ }
47
+ }
48
+ /**
49
+ * Personal pickup (`Odbiór osobisty`) — no carrier; generation succeeds as soon
50
+ * as a shipment is opened (still confirmed via `receive_shipment`).
51
+ */
52
+ export class PersonalPickupAdapter extends BaseShippingAdapter {
53
+ adapterKey = 'personal_pickup';
54
+ async onShipmentCreated() {
55
+ return { kind: 'generated' };
56
+ }
57
+ }
58
+ /** The adapters registered for the platform's built-in shipping methods. */
59
+ export function builtInShippingAdapters() {
60
+ return [new ManualCourierAdapter(), new PersonalPickupAdapter()];
61
+ }
62
+ //# sourceMappingURL=built-in-adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"built-in-adapters.js","sourceRoot":"","sources":["../../../src/backend/adapters/built-in-adapters.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;GAUG;AACH,MAAe,mBAAmB;IAGhC,KAAK,CAAC,uBAAuB,CAAC,IAAgC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,CAAC,kBAAkB,CAAC,IAAgC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,CAAC,gBAAgB,CAAC,IAAgC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sDAAsD;IACtD,KAAK,CAAC,cAAc,CAAC,IAAyB;QAC5C,OAAO;IACT,CAAC;IAID;;;OAGG;IACH,KAAK,CAAC,iBAAiB,CAAC,GAA2B;QACjD,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,IAAI;YAChD,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACJ,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,mBAAmB;IAClD,UAAU,GAAG,gBAAgB,CAAC;IAEvC,KAAK,CAAC,iBAAiB;QACrB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IACnD,UAAU,GAAG,iBAAiB,CAAC;IAExC,KAAK,CAAC,iBAAiB;QACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,UAAU,uBAAuB;IACrC,OAAO,CAAC,IAAI,oBAAoB,EAAE,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;AACnE,CAAC"}