@porulle/core 0.10.8 → 0.13.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.
- package/dist/auth/auth-schema-guard.d.ts +2444 -0
- package/dist/auth/auth-schema-guard.d.ts.map +1 -0
- package/dist/auth/auth-schema-guard.js +113 -0
- package/dist/auth/auth-schema.d.ts +228 -0
- package/dist/auth/auth-schema.d.ts.map +1 -1
- package/dist/auth/auth-schema.js +24 -2
- package/dist/auth/middleware.d.ts +1 -0
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +13 -5
- package/dist/auth/org.d.ts +8 -2
- package/dist/auth/org.d.ts.map +1 -1
- package/dist/auth/org.js +12 -4
- package/dist/auth/organization-guard.d.ts +5 -0
- package/dist/auth/organization-guard.d.ts.map +1 -0
- package/dist/auth/organization-guard.js +124 -0
- package/dist/auth/permissions.d.ts +10 -0
- package/dist/auth/permissions.d.ts.map +1 -1
- package/dist/auth/permissions.js +31 -7
- package/dist/auth/role-authority.d.ts +44 -0
- package/dist/auth/role-authority.d.ts.map +1 -0
- package/dist/auth/role-authority.js +85 -0
- package/dist/auth/setup.d.ts.map +1 -1
- package/dist/auth/setup.js +17 -0
- package/dist/auth/strict-org-resolution.d.ts.map +1 -1
- package/dist/auth/strict-org-resolution.js +9 -1
- package/dist/auth/types.d.ts +1 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +2 -0
- package/dist/config/types.d.ts +33 -4
- package/dist/config/types.d.ts.map +1 -1
- package/dist/hooks/checkout.d.ts.map +1 -1
- package/dist/hooks/checkout.js +10 -9
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/interfaces/rest/audit-middleware.d.ts.map +1 -1
- package/dist/interfaces/rest/audit-middleware.js +2 -0
- package/dist/interfaces/rest/customer-portal.d.ts.map +1 -1
- package/dist/interfaces/rest/customer-portal.js +9 -8
- package/dist/interfaces/rest/index.d.ts.map +1 -1
- package/dist/interfaces/rest/index.js +4 -0
- package/dist/interfaces/rest/route-coverage.d.ts +14 -0
- package/dist/interfaces/rest/route-coverage.d.ts.map +1 -0
- package/dist/interfaces/rest/route-coverage.js +81 -0
- package/dist/interfaces/rest/router.d.ts +7 -2
- package/dist/interfaces/rest/router.d.ts.map +1 -1
- package/dist/interfaces/rest/router.js +8 -4
- package/dist/interfaces/rest/routes/admin/compensation-failures.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/admin/compensation-failures.js +7 -5
- package/dist/interfaces/rest/routes/admin/custom-field-proposals.d.ts +5 -0
- package/dist/interfaces/rest/routes/admin/custom-field-proposals.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/admin/custom-field-proposals.js +22 -0
- package/dist/interfaces/rest/routes/admin/entity-field-definitions.d.ts +5 -0
- package/dist/interfaces/rest/routes/admin/entity-field-definitions.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/admin/entity-field-definitions.js +39 -0
- package/dist/interfaces/rest/routes/admin/permissions.d.ts +1 -1
- package/dist/interfaces/rest/routes/admin/permissions.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/admin/permissions.js +2 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/admin/staff.js +126 -66
- package/dist/interfaces/rest/routes/admin-jobs.js +3 -3
- package/dist/interfaces/rest/routes/audit.js +3 -3
- package/dist/interfaces/rest/routes/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/carts.js +13 -10
- package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/catalog.js +47 -4
- package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/checkout.js +30 -35
- package/dist/interfaces/rest/routes/documents.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/documents.js +10 -5
- package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/inventory.js +2 -0
- package/dist/interfaces/rest/routes/media.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/media.js +7 -3
- package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/orders.js +26 -8
- package/dist/interfaces/rest/routes/pricing.js +2 -2
- package/dist/interfaces/rest/routes/promotions.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/promotions.js +13 -10
- package/dist/interfaces/rest/routes/search.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/search.js +14 -1
- package/dist/interfaces/rest/schemas/admin-custom-field-proposals.d.ts +134 -0
- package/dist/interfaces/rest/schemas/admin-custom-field-proposals.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/admin-custom-field-proposals.js +26 -0
- package/dist/interfaces/rest/schemas/admin-entity-field-definitions.d.ts +592 -0
- package/dist/interfaces/rest/schemas/admin-entity-field-definitions.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/admin-entity-field-definitions.js +109 -0
- package/dist/interfaces/rest/schemas/carts.d.ts +7 -0
- package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/catalog.d.ts +1364 -401
- package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/catalog.js +86 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts +35 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/orders.d.ts +204 -0
- package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/pricing.d.ts +1 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/responses.d.ts +71 -0
- package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/search.d.ts +1 -0
- package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/search.js +1 -0
- package/dist/interfaces/rest/utils.d.ts +15 -0
- package/dist/interfaces/rest/utils.d.ts.map +1 -1
- package/dist/interfaces/rest/utils.js +45 -2
- package/dist/kernel/compensation/executor.js +2 -2
- package/dist/kernel/database/tx-context.d.ts +8 -0
- package/dist/kernel/database/tx-context.d.ts.map +1 -1
- package/dist/kernel/database/tx-context.js +13 -0
- package/dist/kernel/hooks/create-context.d.ts +2 -0
- package/dist/kernel/hooks/create-context.d.ts.map +1 -1
- package/dist/kernel/hooks/create-context.js +1 -0
- package/dist/kernel/hooks/types.d.ts +2 -0
- package/dist/kernel/hooks/types.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.js +9 -5
- package/dist/modules/analytics/service.js +2 -2
- package/dist/modules/audit/service.js +3 -3
- package/dist/modules/cart/repository/index.d.ts +13 -7
- package/dist/modules/cart/repository/index.d.ts.map +1 -1
- package/dist/modules/cart/repository/index.js +16 -10
- package/dist/modules/cart/schema.d.ts +17 -0
- package/dist/modules/cart/schema.d.ts.map +1 -1
- package/dist/modules/cart/schema.js +4 -0
- package/dist/modules/cart/service.d.ts +22 -9
- package/dist/modules/cart/service.d.ts.map +1 -1
- package/dist/modules/cart/service.js +57 -33
- package/dist/modules/catalog/brand-service.js +7 -7
- package/dist/modules/catalog/category-service.js +7 -7
- package/dist/modules/catalog/entity-service.d.ts +19 -10
- package/dist/modules/catalog/entity-service.d.ts.map +1 -1
- package/dist/modules/catalog/entity-service.js +180 -51
- package/dist/modules/catalog/module.d.ts +6 -1
- package/dist/modules/catalog/module.d.ts.map +1 -1
- package/dist/modules/catalog/module.js +6 -1
- package/dist/modules/catalog/ownership.d.ts +5 -0
- package/dist/modules/catalog/ownership.d.ts.map +1 -0
- package/dist/modules/catalog/ownership.js +11 -0
- package/dist/modules/catalog/read-policy.d.ts +9 -0
- package/dist/modules/catalog/read-policy.d.ts.map +1 -0
- package/dist/modules/catalog/read-policy.js +8 -0
- package/dist/modules/catalog/repository/index.d.ts +55 -3
- package/dist/modules/catalog/repository/index.d.ts.map +1 -1
- package/dist/modules/catalog/repository/index.js +335 -6
- package/dist/modules/catalog/revision.d.ts +4 -0
- package/dist/modules/catalog/revision.d.ts.map +1 -0
- package/dist/modules/catalog/revision.js +33 -0
- package/dist/modules/catalog/schema.d.ts +979 -110
- package/dist/modules/catalog/schema.d.ts.map +1 -1
- package/dist/modules/catalog/schema.js +112 -2
- package/dist/modules/catalog/schemas.d.ts +2 -0
- package/dist/modules/catalog/schemas.d.ts.map +1 -1
- package/dist/modules/catalog/schemas.js +2 -0
- package/dist/modules/catalog/service.d.ts +80 -15
- package/dist/modules/catalog/service.d.ts.map +1 -1
- package/dist/modules/catalog/service.js +522 -14
- package/dist/modules/channels/adapter.d.ts +85 -0
- package/dist/modules/channels/adapter.d.ts.map +1 -1
- package/dist/modules/channels/adapter.js +9 -1
- package/dist/modules/customers/module.d.ts.map +1 -1
- package/dist/modules/customers/module.js +1 -0
- package/dist/modules/customers/service.d.ts +2 -0
- package/dist/modules/customers/service.d.ts.map +1 -1
- package/dist/modules/customers/service.js +21 -20
- package/dist/modules/documents/module.d.ts.map +1 -1
- package/dist/modules/documents/module.js +1 -0
- package/dist/modules/documents/service.d.ts +18 -4
- package/dist/modules/documents/service.d.ts.map +1 -1
- package/dist/modules/documents/service.js +54 -16
- package/dist/modules/fulfillment/module.d.ts.map +1 -1
- package/dist/modules/fulfillment/module.js +1 -0
- package/dist/modules/fulfillment/service.d.ts +2 -0
- package/dist/modules/fulfillment/service.d.ts.map +1 -1
- package/dist/modules/fulfillment/service.js +15 -6
- package/dist/modules/inventory/service.d.ts.map +1 -1
- package/dist/modules/inventory/service.js +15 -14
- package/dist/modules/media/module.d.ts +68 -0
- package/dist/modules/media/module.d.ts.map +1 -1
- package/dist/modules/media/module.js +2 -0
- package/dist/modules/media/schema.d.ts +70 -0
- package/dist/modules/media/schema.d.ts.map +1 -1
- package/dist/modules/media/schema.js +20 -2
- package/dist/modules/media/service.d.ts +8 -1
- package/dist/modules/media/service.d.ts.map +1 -1
- package/dist/modules/media/service.js +71 -23
- package/dist/modules/orders/guest-access.d.ts +27 -0
- package/dist/modules/orders/guest-access.d.ts.map +1 -0
- package/dist/modules/orders/guest-access.js +46 -0
- package/dist/modules/orders/module.d.ts.map +1 -1
- package/dist/modules/orders/module.js +1 -0
- package/dist/modules/orders/quote.d.ts.map +1 -1
- package/dist/modules/orders/quote.js +1 -0
- package/dist/modules/orders/repository/index.d.ts +1 -1
- package/dist/modules/orders/repository/index.d.ts.map +1 -1
- package/dist/modules/orders/repository/index.js +2 -2
- package/dist/modules/orders/schema.d.ts +17 -0
- package/dist/modules/orders/schema.d.ts.map +1 -1
- package/dist/modules/orders/schema.js +5 -3
- package/dist/modules/orders/service.d.ts +16 -7
- package/dist/modules/orders/service.d.ts.map +1 -1
- package/dist/modules/orders/service.js +184 -55
- package/dist/modules/pricing/module.d.ts.map +1 -1
- package/dist/modules/pricing/module.js +1 -0
- package/dist/modules/pricing/schema.d.ts +17 -0
- package/dist/modules/pricing/schema.d.ts.map +1 -1
- package/dist/modules/pricing/schema.js +1 -0
- package/dist/modules/pricing/schemas.d.ts +1 -0
- package/dist/modules/pricing/schemas.d.ts.map +1 -1
- package/dist/modules/pricing/schemas.js +1 -0
- package/dist/modules/pricing/service.d.ts +2 -0
- package/dist/modules/pricing/service.d.ts.map +1 -1
- package/dist/modules/pricing/service.js +18 -12
- package/dist/modules/promotions/module.d.ts.map +1 -1
- package/dist/modules/promotions/module.js +1 -0
- package/dist/modules/promotions/service.d.ts +3 -0
- package/dist/modules/promotions/service.d.ts.map +1 -1
- package/dist/modules/promotions/service.js +19 -11
- package/dist/modules/search/adapter.d.ts +8 -0
- package/dist/modules/search/adapter.d.ts.map +1 -1
- package/dist/modules/search/module.d.ts.map +1 -1
- package/dist/modules/search/module.js +3 -0
- package/dist/modules/search/service.d.ts +5 -0
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +131 -11
- package/dist/modules/settings/module.d.ts.map +1 -1
- package/dist/modules/settings/module.js +1 -0
- package/dist/modules/settings/service.d.ts +3 -0
- package/dist/modules/settings/service.d.ts.map +1 -1
- package/dist/modules/settings/service.js +6 -4
- package/dist/modules/shipping/service.js +9 -9
- package/dist/modules/tax/module.d.ts.map +1 -1
- package/dist/modules/tax/module.js +1 -0
- package/dist/modules/tax/service.d.ts +3 -0
- package/dist/modules/tax/service.d.ts.map +1 -1
- package/dist/modules/tax/service.js +11 -9
- package/dist/modules/webhooks/hook.js +2 -2
- package/dist/modules/webhooks/module.d.ts.map +1 -1
- package/dist/modules/webhooks/module.js +1 -0
- package/dist/modules/webhooks/service.d.ts +2 -0
- package/dist/modules/webhooks/service.d.ts.map +1 -1
- package/dist/modules/webhooks/service.js +4 -4
- package/dist/runtime/kernel-modules.d.ts +73 -0
- package/dist/runtime/kernel-modules.d.ts.map +1 -1
- package/dist/runtime/server.d.ts.map +1 -1
- package/dist/runtime/server.js +10 -2
- package/dist/test-utils/create-pglite-adapter.d.ts.map +1 -1
- package/dist/test-utils/create-pglite-adapter.js +35 -13
- package/dist/test-utils/create-test-config.d.ts.map +1 -1
- package/dist/test-utils/create-test-config.js +4 -0
- package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
- package/dist/test-utils/rest-api-test-utils.js +2 -0
- package/dist/test-utils/test-actors.js +2 -2
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +11 -0
- package/package.json +6 -5
- package/src/auth/auth-schema-guard.ts +143 -0
- package/src/auth/auth-schema.ts +50 -19
- package/src/auth/middleware.ts +17 -5
- package/src/auth/org.ts +15 -3
- package/src/auth/organization-guard.ts +158 -0
- package/src/auth/permissions.ts +31 -8
- package/src/auth/role-authority.ts +107 -0
- package/src/auth/setup.ts +17 -0
- package/src/auth/strict-org-resolution.ts +7 -1
- package/src/auth/types.ts +1 -1
- package/src/config/defaults.ts +2 -0
- package/src/config/types.ts +32 -4
- package/src/hooks/checkout.ts +19 -12
- package/src/index.ts +30 -6
- package/src/interfaces/rest/audit-middleware.ts +2 -0
- package/src/interfaces/rest/customer-portal.ts +31 -24
- package/src/interfaces/rest/index.ts +4 -0
- package/src/interfaces/rest/route-coverage.ts +103 -0
- package/src/interfaces/rest/router.ts +16 -10
- package/src/interfaces/rest/routes/admin/compensation-failures.ts +8 -5
- package/src/interfaces/rest/routes/admin/custom-field-proposals.ts +37 -0
- package/src/interfaces/rest/routes/admin/entity-field-definitions.ts +89 -0
- package/src/interfaces/rest/routes/admin/permissions.ts +3 -1
- package/src/interfaces/rest/routes/admin/staff.ts +161 -72
- package/src/interfaces/rest/routes/admin-jobs.ts +3 -3
- package/src/interfaces/rest/routes/audit.ts +3 -3
- package/src/interfaces/rest/routes/carts.ts +17 -7
- package/src/interfaces/rest/routes/catalog.ts +96 -0
- package/src/interfaces/rest/routes/checkout.ts +41 -38
- package/src/interfaces/rest/routes/documents.ts +15 -1
- package/src/interfaces/rest/routes/inventory.ts +2 -0
- package/src/interfaces/rest/routes/media.ts +8 -3
- package/src/interfaces/rest/routes/orders.ts +27 -8
- package/src/interfaces/rest/routes/pricing.ts +2 -2
- package/src/interfaces/rest/routes/promotions.ts +12 -9
- package/src/interfaces/rest/routes/search.ts +19 -1
- package/src/interfaces/rest/schemas/admin-custom-field-proposals.ts +29 -0
- package/src/interfaces/rest/schemas/admin-entity-field-definitions.ts +120 -0
- package/src/interfaces/rest/schemas/catalog.ts +92 -0
- package/src/interfaces/rest/schemas/search.ts +2 -0
- package/src/interfaces/rest/utils.ts +61 -2
- package/src/kernel/compensation/executor.ts +2 -2
- package/src/kernel/database/tx-context.ts +25 -0
- package/src/kernel/hooks/create-context.ts +3 -0
- package/src/kernel/hooks/types.ts +2 -0
- package/src/kernel/plugin/manifest.ts +9 -5
- package/src/modules/analytics/service.ts +2 -2
- package/src/modules/audit/service.ts +3 -3
- package/src/modules/cart/repository/index.ts +22 -8
- package/src/modules/cart/schema.ts +4 -0
- package/src/modules/cart/service.ts +62 -27
- package/src/modules/catalog/brand-service.ts +7 -7
- package/src/modules/catalog/category-service.ts +7 -7
- package/src/modules/catalog/entity-service.ts +188 -53
- package/src/modules/catalog/module.ts +15 -0
- package/src/modules/catalog/ownership.ts +17 -0
- package/src/modules/catalog/read-policy.ts +16 -0
- package/src/modules/catalog/repository/index.ts +566 -4
- package/src/modules/catalog/revision.ts +35 -0
- package/src/modules/catalog/schema.ts +169 -1
- package/src/modules/catalog/schemas.ts +2 -0
- package/src/modules/catalog/service.ts +766 -26
- package/src/modules/channels/adapter.ts +107 -1
- package/src/modules/customers/module.ts +2 -0
- package/src/modules/customers/service.ts +23 -22
- package/src/modules/documents/module.ts +2 -0
- package/src/modules/documents/service.ts +74 -11
- package/src/modules/fulfillment/module.ts +2 -0
- package/src/modules/fulfillment/service.ts +17 -6
- package/src/modules/inventory/service.ts +15 -24
- package/src/modules/media/module.ts +2 -0
- package/src/modules/media/schema.ts +23 -2
- package/src/modules/media/service.ts +89 -28
- package/src/modules/orders/guest-access.ts +55 -0
- package/src/modules/orders/module.ts +1 -0
- package/src/modules/orders/quote.ts +1 -0
- package/src/modules/orders/repository/index.ts +2 -0
- package/src/modules/orders/schema.ts +5 -3
- package/src/modules/orders/service.ts +302 -52
- package/src/modules/pricing/module.ts +2 -0
- package/src/modules/pricing/schema.ts +1 -0
- package/src/modules/pricing/schemas.ts +1 -0
- package/src/modules/pricing/service.ts +21 -18
- package/src/modules/promotions/module.ts +2 -0
- package/src/modules/promotions/service.ts +25 -16
- package/src/modules/search/adapter.ts +8 -0
- package/src/modules/search/module.ts +3 -0
- package/src/modules/search/service.ts +142 -12
- package/src/modules/settings/module.ts +2 -0
- package/src/modules/settings/service.ts +8 -4
- package/src/modules/shipping/service.ts +9 -9
- package/src/modules/tax/module.ts +1 -0
- package/src/modules/tax/service.ts +13 -9
- package/src/modules/webhooks/hook.ts +2 -2
- package/src/modules/webhooks/module.ts +2 -0
- package/src/modules/webhooks/service.ts +6 -4
- package/src/runtime/server.ts +16 -2
- package/src/test-utils/create-pglite-adapter.ts +34 -12
- package/src/test-utils/create-test-config.ts +10 -6
- package/src/test-utils/rest-api-test-utils.ts +2 -0
- package/src/test-utils/test-actors.ts +2 -2
- package/src/utils/id.ts +20 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOrgIdForCommerce } from "../../auth/org.js";
|
|
2
2
|
import { assertOwnership, assertPermission } from "../../auth/permissions.js";
|
|
3
3
|
import type { Actor } from "../../auth/types.js";
|
|
4
4
|
import type { CommerceConfig } from "../../config/types.js";
|
|
@@ -60,6 +60,7 @@ function makeContext(
|
|
|
60
60
|
actor: Actor | null,
|
|
61
61
|
services: Record<string, unknown>,
|
|
62
62
|
database: DatabaseAdapter,
|
|
63
|
+
config: CommerceConfig,
|
|
63
64
|
tx: unknown = null,
|
|
64
65
|
): HookContext {
|
|
65
66
|
return createHookContext({
|
|
@@ -69,6 +70,7 @@ function makeContext(
|
|
|
69
70
|
services,
|
|
70
71
|
context: { moduleName: "cart" },
|
|
71
72
|
database: { db: database.db as PluginDb },
|
|
73
|
+
commerceConfig: config,
|
|
72
74
|
});
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -98,7 +100,7 @@ export class CartService {
|
|
|
98
100
|
|
|
99
101
|
const ttlMinutes = this.deps.config.cart?.ttlMinutes ?? 60 * 24 * 7;
|
|
100
102
|
const now = new Date();
|
|
101
|
-
const orgId =
|
|
103
|
+
const orgId = resolveOrgIdForCommerce(actor ?? null, this.deps.config);
|
|
102
104
|
|
|
103
105
|
// SECURITY: cart.customerId is service-managed.
|
|
104
106
|
//
|
|
@@ -145,6 +147,7 @@ export class CartService {
|
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
const guestSecret = resolvedCustomerId === null ? crypto.randomUUID() : undefined;
|
|
148
151
|
const cart = await this.repo.create(
|
|
149
152
|
{
|
|
150
153
|
organizationId: orgId,
|
|
@@ -153,6 +156,7 @@ export class CartService {
|
|
|
153
156
|
metadata: input.metadata ?? {},
|
|
154
157
|
expiresAt: new Date(now.getTime() + ttlMinutes * 60 * 1000),
|
|
155
158
|
...(resolvedCustomerId !== null ? { customerId: resolvedCustomerId } : {}),
|
|
159
|
+
...(guestSecret !== undefined ? { secret: guestSecret } : {}),
|
|
156
160
|
...(input.email !== undefined ? { email: input.email } : {}),
|
|
157
161
|
},
|
|
158
162
|
ctx,
|
|
@@ -173,7 +177,7 @@ export class CartService {
|
|
|
173
177
|
// read any cart's contents, prices, line items, and metadata. This now
|
|
174
178
|
// requires either an authenticated owner/staff actor OR the cart's
|
|
175
179
|
// secret token (returned only at createGuest()).
|
|
176
|
-
const orgId =
|
|
180
|
+
const orgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
177
181
|
const cart = await this.repo.findById(orgId, id, ctx);
|
|
178
182
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
179
183
|
|
|
@@ -195,10 +199,31 @@ export class CartService {
|
|
|
195
199
|
});
|
|
196
200
|
}
|
|
197
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Reads a cart for a trusted server pipeline after the request boundary has
|
|
204
|
+
* already authenticated the caller. Organization scope is explicit; caller
|
|
205
|
+
* identity and guest secrets are intentionally not consulted here.
|
|
206
|
+
*/
|
|
207
|
+
async getByIdForInternalUse(
|
|
208
|
+
id: string,
|
|
209
|
+
organizationId: string,
|
|
210
|
+
ctx?: TxContext,
|
|
211
|
+
): Promise<Result<Cart & { lineItems: CartLineItem[] }>> {
|
|
212
|
+
const cart = await this.repo.findById(organizationId, id, ctx);
|
|
213
|
+
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
214
|
+
|
|
215
|
+
const lineItems = await this.repo.findLineItemsByCartId(id, ctx);
|
|
216
|
+
return Ok({
|
|
217
|
+
...cart,
|
|
218
|
+
lineItems,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
198
222
|
async addItem(
|
|
199
223
|
input: AddCartItemInput,
|
|
200
224
|
actor?: Actor | null,
|
|
201
225
|
ctx?: TxContext,
|
|
226
|
+
presentedSecret?: string,
|
|
202
227
|
): Promise<Result<CartLineItem>> {
|
|
203
228
|
try {
|
|
204
229
|
assertPermission(actor ?? null, "cart:update");
|
|
@@ -206,12 +231,12 @@ export class CartService {
|
|
|
206
231
|
return Err(toCommerceError(error));
|
|
207
232
|
}
|
|
208
233
|
|
|
209
|
-
const orgId =
|
|
234
|
+
const orgId = resolveOrgIdForCommerce(actor ?? null, this.deps.config);
|
|
210
235
|
const cart = await this.repo.findById(orgId, input.cartId, ctx);
|
|
211
236
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
212
237
|
|
|
213
238
|
try {
|
|
214
|
-
await this.assertCartOwnership(actor ?? null, cart, ctx);
|
|
239
|
+
await this.assertCartOwnership(actor ?? null, cart, ctx, presentedSecret);
|
|
215
240
|
} catch (error) {
|
|
216
241
|
return Err(toCommerceError(error));
|
|
217
242
|
}
|
|
@@ -253,7 +278,7 @@ export class CartService {
|
|
|
253
278
|
);
|
|
254
279
|
}
|
|
255
280
|
|
|
256
|
-
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, ctx?.tx);
|
|
281
|
+
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, this.deps.config, ctx?.tx);
|
|
257
282
|
const beforeHooks = this.deps.hooks.resolve(
|
|
258
283
|
"cart.beforeAddItem",
|
|
259
284
|
) as CartAddBeforeHook[];
|
|
@@ -319,6 +344,7 @@ export class CartService {
|
|
|
319
344
|
itemId: string,
|
|
320
345
|
actor?: Actor | null,
|
|
321
346
|
ctx?: TxContext,
|
|
347
|
+
presentedSecret?: string,
|
|
322
348
|
): Promise<Result<void>> {
|
|
323
349
|
try {
|
|
324
350
|
assertPermission(actor ?? null, "cart:update");
|
|
@@ -326,12 +352,12 @@ export class CartService {
|
|
|
326
352
|
return Err(toCommerceError(error));
|
|
327
353
|
}
|
|
328
354
|
|
|
329
|
-
const orgId =
|
|
355
|
+
const orgId = resolveOrgIdForCommerce(actor ?? null, this.deps.config);
|
|
330
356
|
const cart = await this.repo.findById(orgId, cartId, ctx);
|
|
331
357
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
332
358
|
|
|
333
359
|
try {
|
|
334
|
-
await this.assertCartOwnership(actor ?? null, cart, ctx);
|
|
360
|
+
await this.assertCartOwnership(actor ?? null, cart, ctx, presentedSecret);
|
|
335
361
|
} catch (error) {
|
|
336
362
|
return Err(toCommerceError(error));
|
|
337
363
|
}
|
|
@@ -341,7 +367,7 @@ export class CartService {
|
|
|
341
367
|
return Err(new CommerceNotFoundError("Cart item not found."));
|
|
342
368
|
}
|
|
343
369
|
|
|
344
|
-
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, ctx?.tx);
|
|
370
|
+
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, this.deps.config, ctx?.tx);
|
|
345
371
|
const beforeHooks = this.deps.hooks.resolve(
|
|
346
372
|
"cart.beforeRemoveItem",
|
|
347
373
|
) as CartRemoveBeforeHook[];
|
|
@@ -360,6 +386,7 @@ export class CartService {
|
|
|
360
386
|
input: UpdateCartItemInput,
|
|
361
387
|
actor?: Actor | null,
|
|
362
388
|
ctx?: TxContext,
|
|
389
|
+
presentedSecret?: string,
|
|
363
390
|
): Promise<Result<CartLineItem>> {
|
|
364
391
|
try {
|
|
365
392
|
assertPermission(actor ?? null, "cart:update");
|
|
@@ -367,12 +394,12 @@ export class CartService {
|
|
|
367
394
|
return Err(toCommerceError(error));
|
|
368
395
|
}
|
|
369
396
|
|
|
370
|
-
const orgId =
|
|
397
|
+
const orgId = resolveOrgIdForCommerce(actor ?? null, this.deps.config);
|
|
371
398
|
const cart = await this.repo.findById(orgId, input.cartId, ctx);
|
|
372
399
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
373
400
|
|
|
374
401
|
try {
|
|
375
|
-
await this.assertCartOwnership(actor ?? null, cart, ctx);
|
|
402
|
+
await this.assertCartOwnership(actor ?? null, cart, ctx, presentedSecret);
|
|
376
403
|
} catch (error) {
|
|
377
404
|
return Err(toCommerceError(error));
|
|
378
405
|
}
|
|
@@ -388,7 +415,7 @@ export class CartService {
|
|
|
388
415
|
);
|
|
389
416
|
}
|
|
390
417
|
|
|
391
|
-
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, ctx?.tx);
|
|
418
|
+
const context = makeContext(actor ?? null, this.deps.services, this.deps.database, this.deps.config, ctx?.tx);
|
|
392
419
|
const beforeHooks = this.deps.hooks.resolve(
|
|
393
420
|
"cart.beforeUpdateQuantity",
|
|
394
421
|
) as CartUpdateBeforeHook[];
|
|
@@ -424,7 +451,7 @@ export class CartService {
|
|
|
424
451
|
return Err(toCommerceError(error));
|
|
425
452
|
}
|
|
426
453
|
|
|
427
|
-
const orgId =
|
|
454
|
+
const orgId = resolveOrgIdForCommerce(actor ?? null, this.deps.config);
|
|
428
455
|
const source = await this.repo.findById(orgId, sourceCartId, ctx);
|
|
429
456
|
const target = await this.repo.findById(orgId, targetCartId, ctx);
|
|
430
457
|
if (!source || !target)
|
|
@@ -479,7 +506,7 @@ export class CartService {
|
|
|
479
506
|
} catch (error) {
|
|
480
507
|
return Err(toCommerceError(error));
|
|
481
508
|
}
|
|
482
|
-
const orgId =
|
|
509
|
+
const orgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
483
510
|
const rows = await this.repo.list(
|
|
484
511
|
orgId,
|
|
485
512
|
{
|
|
@@ -518,7 +545,7 @@ export class CartService {
|
|
|
518
545
|
} catch (error) {
|
|
519
546
|
return Err(toCommerceError(error));
|
|
520
547
|
}
|
|
521
|
-
const orgId =
|
|
548
|
+
const orgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
522
549
|
const cart = await this.repo.findById(orgId, cartId, ctx);
|
|
523
550
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
524
551
|
if (cart.status === "checked_out" || cart.status === "merged" || cart.status === "checking_out") {
|
|
@@ -544,7 +571,7 @@ export class CartService {
|
|
|
544
571
|
null,
|
|
545
572
|
updated ?? cart,
|
|
546
573
|
"recover",
|
|
547
|
-
makeContext(actor ?? null, this.deps.services, this.deps.database, ctx?.tx ?? null),
|
|
574
|
+
makeContext(actor ?? null, this.deps.services, this.deps.database, this.deps.config, ctx?.tx ?? null),
|
|
548
575
|
);
|
|
549
576
|
|
|
550
577
|
return Ok({
|
|
@@ -558,7 +585,7 @@ export class CartService {
|
|
|
558
585
|
}
|
|
559
586
|
|
|
560
587
|
async abandon(cartId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>> {
|
|
561
|
-
const orgId =
|
|
588
|
+
const orgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
562
589
|
const cart = await this.repo.findById(orgId, cartId, ctx);
|
|
563
590
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
564
591
|
|
|
@@ -571,24 +598,27 @@ export class CartService {
|
|
|
571
598
|
actor?: Actor | null,
|
|
572
599
|
ctx?: TxContext,
|
|
573
600
|
): Promise<Result<void>> {
|
|
574
|
-
const orgId =
|
|
601
|
+
const orgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
575
602
|
const cart = await this.repo.findById(orgId, cartId, ctx);
|
|
576
603
|
if (!cart) return Err(new CommerceNotFoundError("Cart not found."));
|
|
577
604
|
|
|
578
|
-
await this.repo.
|
|
605
|
+
await this.repo.update(cartId, { status: "checked_out", checkoutClaimToken: null }, ctx);
|
|
579
606
|
return Ok(undefined);
|
|
580
607
|
}
|
|
581
608
|
|
|
582
609
|
/**
|
|
583
|
-
* Atomically transitions a cart from "active" to "checking_out"
|
|
584
|
-
* Returns Err if the cart was already claimed by
|
|
585
|
-
* This prevents TOCTOU race conditions on
|
|
610
|
+
* Atomically transitions a cart from "active" to "checking_out", recording
|
|
611
|
+
* `claimToken` as the holder. Returns Err if the cart was already claimed by
|
|
612
|
+
* a concurrent checkout. This prevents TOCTOU race conditions on
|
|
613
|
+
* double-checkout, and the token is what lets {@link releaseCheckoutClaim}
|
|
614
|
+
* tell the winner's release from a loser's.
|
|
586
615
|
*/
|
|
587
616
|
async claimForCheckout(
|
|
588
617
|
cartId: string,
|
|
618
|
+
claimToken: string,
|
|
589
619
|
ctx?: TxContext,
|
|
590
620
|
): Promise<Result<Cart>> {
|
|
591
|
-
const claimed = await this.repo.transitionToCheckingOut(cartId, ctx);
|
|
621
|
+
const claimed = await this.repo.transitionToCheckingOut(cartId, claimToken, ctx);
|
|
592
622
|
if (!claimed) {
|
|
593
623
|
return Err(
|
|
594
624
|
new CommerceValidationError(
|
|
@@ -601,13 +631,17 @@ export class CartService {
|
|
|
601
631
|
|
|
602
632
|
/**
|
|
603
633
|
* Atomically returns a failed checkout claim to `active`. A checked-out,
|
|
604
|
-
* merged, abandoned, or already-active cart is left untouched
|
|
634
|
+
* merged, abandoned, or already-active cart is left untouched — and so is a
|
|
635
|
+
* claim held by a different checkout attempt, so a losing attempt's failure
|
|
636
|
+
* path cannot reopen the cart the winner is still checking out. Returns null
|
|
637
|
+
* when nothing was released.
|
|
605
638
|
*/
|
|
606
639
|
async releaseCheckoutClaim(
|
|
607
640
|
cartId: string,
|
|
641
|
+
claimToken: string,
|
|
608
642
|
ctx?: TxContext,
|
|
609
643
|
): Promise<Result<Cart | null>> {
|
|
610
|
-
return Ok((await this.repo.releaseCheckoutClaim(cartId, ctx)) ?? null);
|
|
644
|
+
return Ok((await this.repo.releaseCheckoutClaim(cartId, claimToken, ctx)) ?? null);
|
|
611
645
|
}
|
|
612
646
|
|
|
613
647
|
/**
|
|
@@ -625,7 +659,8 @@ export class CartService {
|
|
|
625
659
|
|
|
626
660
|
const cart = await this.repo.create(
|
|
627
661
|
{
|
|
628
|
-
|
|
662
|
+
// Actor-less by design; resolves to the deployment's declared organization.
|
|
663
|
+
organizationId: resolveOrgIdForCommerce(null, this.deps.config),
|
|
629
664
|
customerId: undefined,
|
|
630
665
|
status: "active",
|
|
631
666
|
currency,
|
|
@@ -651,7 +686,7 @@ export class CartService {
|
|
|
651
686
|
actor: Actor,
|
|
652
687
|
ctx?: TxContext,
|
|
653
688
|
): Promise<Result<Cart>> {
|
|
654
|
-
const orgId =
|
|
689
|
+
const orgId = resolveOrgIdForCommerce(actor, this.deps.config);
|
|
655
690
|
const sourceCart = await this.repo.findById(orgId, sourceCartId, ctx);
|
|
656
691
|
if (!sourceCart || sourceCart.secret !== sourceSecret) {
|
|
657
692
|
return Err(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOrgIdForCommerce } from "../../auth/org.js";
|
|
2
2
|
import { assertPermission } from "../../auth/permissions.js";
|
|
3
3
|
import type { Actor } from "../../auth/types.js";
|
|
4
4
|
import {
|
|
@@ -23,14 +23,14 @@ export class BrandService {
|
|
|
23
23
|
|
|
24
24
|
private assertSameOrg(resource: { organizationId?: string | null } | undefined, actor: Actor | null): void {
|
|
25
25
|
if (!resource) return;
|
|
26
|
-
const orgId =
|
|
26
|
+
const orgId = resolveOrgIdForCommerce(actor, this.deps.config);
|
|
27
27
|
if (resource.organizationId && resource.organizationId !== orgId) {
|
|
28
28
|
throw new CommerceNotFoundError("Entity not found.");
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async listBrands(ctx?: TxContext): Promise<Result<Brand[]>> {
|
|
33
|
-
const allBrands = await this.repo.findAllBrands(
|
|
33
|
+
const allBrands = await this.repo.findAllBrands(resolveOrgIdForCommerce(ctx?.actor ?? null, this.deps.config), ctx);
|
|
34
34
|
return Ok(allBrands.sort((a, b) => a.displayName.localeCompare(b.displayName)));
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -40,7 +40,7 @@ export class BrandService {
|
|
|
40
40
|
const existingById = await this.repo.findBrandById(input.id, ctx);
|
|
41
41
|
if (existingById) return Err(new CommerceConflictError(`Brand with id ${input.id} already exists.`));
|
|
42
42
|
}
|
|
43
|
-
const orgId =
|
|
43
|
+
const orgId = resolveOrgIdForCommerce(actor, this.deps.config);
|
|
44
44
|
const existingBySlug = await this.repo.findBrandBySlug(orgId, input.slug, ctx);
|
|
45
45
|
if (existingBySlug) return Err(new CommerceConflictError(`Brand with slug ${input.slug} already exists.`));
|
|
46
46
|
return Ok(await this.repo.createBrand({ organizationId: orgId, ...(input.id ? { id: input.id } : {}), slug: input.slug, displayName: input.displayName, metadata: input.metadata ?? {} }, ctx));
|
|
@@ -52,7 +52,7 @@ export class BrandService {
|
|
|
52
52
|
if (!existing) return Err(new CommerceNotFoundError("Brand not found."));
|
|
53
53
|
try { this.assertSameOrg(existing, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
54
54
|
if (input.slug) {
|
|
55
|
-
const existingBySlug = await this.repo.findBrandBySlug(
|
|
55
|
+
const existingBySlug = await this.repo.findBrandBySlug(resolveOrgIdForCommerce(actor, this.deps.config), input.slug, ctx);
|
|
56
56
|
if (existingBySlug && existingBySlug.id !== id) return Err(new CommerceConflictError(`Brand with slug ${input.slug} already exists.`));
|
|
57
57
|
}
|
|
58
58
|
const updated = await this.repo.updateBrand(id, { ...(input.slug !== undefined ? { slug: input.slug } : {}), ...(input.displayName !== undefined ? { displayName: input.displayName } : {}), ...(input.metadata !== undefined ? { metadata: input.metadata } : {}) }, ctx);
|
|
@@ -75,7 +75,7 @@ export class BrandService {
|
|
|
75
75
|
const entity = await this.deps.repository.findEntityById(entityId, ctx);
|
|
76
76
|
if (!entity) return Err(new CommerceNotFoundError("Entity not found."));
|
|
77
77
|
try { this.assertSameOrg(entity, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
78
|
-
const addBrandOrgId =
|
|
78
|
+
const addBrandOrgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
79
79
|
const isBrandUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(brandId);
|
|
80
80
|
let brand = isBrandUuid ? await this.repo.findBrandById(brandId, ctx) : null;
|
|
81
81
|
if (!brand) brand = await this.repo.findBrandBySlug(addBrandOrgId, brandId, ctx);
|
|
@@ -93,7 +93,7 @@ export class BrandService {
|
|
|
93
93
|
try { this.assertSameOrg(entity, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
94
94
|
const isBrUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(brandId);
|
|
95
95
|
let brand = isBrUuid ? await this.repo.findBrandById(brandId, ctx) : null;
|
|
96
|
-
if (!brand) brand = await this.repo.findBrandBySlug(
|
|
96
|
+
if (!brand) brand = await this.repo.findBrandBySlug(resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config), brandId, ctx);
|
|
97
97
|
const removed = await this.repo.removeEntityFromBrand(entityId, brand?.id ?? brandId, ctx);
|
|
98
98
|
if (!removed) return Err(new CommerceNotFoundError("Brand assignment not found."));
|
|
99
99
|
return Ok(undefined);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOrgIdForCommerce } from "../../auth/org.js";
|
|
2
2
|
import { assertPermission } from "../../auth/permissions.js";
|
|
3
3
|
import type { Actor } from "../../auth/types.js";
|
|
4
4
|
import {
|
|
@@ -23,14 +23,14 @@ export class CategoryService {
|
|
|
23
23
|
|
|
24
24
|
private assertSameOrg(resource: { organizationId?: string | null } | undefined, actor: Actor | null): void {
|
|
25
25
|
if (!resource) return;
|
|
26
|
-
const orgId =
|
|
26
|
+
const orgId = resolveOrgIdForCommerce(actor, this.deps.config);
|
|
27
27
|
if (resource.organizationId && resource.organizationId !== orgId) {
|
|
28
28
|
throw new CommerceNotFoundError("Entity not found.");
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async listCategories(ctx?: TxContext, opts?: { includeArchived?: boolean }): Promise<Result<CategorySummary[]>> {
|
|
33
|
-
const allCategories = await this.repo.findAllCategories(
|
|
33
|
+
const allCategories = await this.repo.findAllCategories(resolveOrgIdForCommerce(ctx?.actor ?? null, this.deps.config), ctx);
|
|
34
34
|
const visible = opts?.includeArchived
|
|
35
35
|
? allCategories
|
|
36
36
|
: allCategories.filter((c) => (c.status ?? "active") === "active");
|
|
@@ -62,7 +62,7 @@ export class CategoryService {
|
|
|
62
62
|
const existingById = await this.repo.findCategoryById(input.id, ctx);
|
|
63
63
|
if (existingById) return Err(new CommerceConflictError(`Category with id ${input.id} already exists.`));
|
|
64
64
|
}
|
|
65
|
-
const orgId =
|
|
65
|
+
const orgId = resolveOrgIdForCommerce(actor, this.deps.config);
|
|
66
66
|
const existingBySlug = await this.repo.findCategoryBySlug(orgId, input.slug, ctx);
|
|
67
67
|
if (existingBySlug) return Err(new CommerceConflictError(`Category with slug ${input.slug} already exists.`));
|
|
68
68
|
const category = await this.repo.createCategory({ organizationId: orgId, ...(input.id ? { id: input.id } : {}), slug: input.slug, sortOrder: input.sortOrder ?? 0, metadata: input.metadata ?? {}, ...(input.parentId !== undefined ? { parentId: input.parentId } : {}) }, ctx);
|
|
@@ -75,7 +75,7 @@ export class CategoryService {
|
|
|
75
75
|
if (!existing) return Err(new CommerceNotFoundError("Category not found."));
|
|
76
76
|
try { this.assertSameOrg(existing, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
77
77
|
if (input.slug) {
|
|
78
|
-
const existingBySlug = await this.repo.findCategoryBySlug(
|
|
78
|
+
const existingBySlug = await this.repo.findCategoryBySlug(resolveOrgIdForCommerce(actor, this.deps.config), input.slug, ctx);
|
|
79
79
|
if (existingBySlug && existingBySlug.id !== id) return Err(new CommerceConflictError(`Category with slug ${input.slug} already exists.`));
|
|
80
80
|
}
|
|
81
81
|
const updated = await this.repo.updateCategory(id, { ...(input.slug !== undefined ? { slug: input.slug } : {}), ...(input.sortOrder !== undefined ? { sortOrder: input.sortOrder } : {}), ...(input.metadata !== undefined ? { metadata: input.metadata } : {}), ...(input.parentId !== undefined ? { parentId: input.parentId } : {}) }, ctx);
|
|
@@ -98,7 +98,7 @@ export class CategoryService {
|
|
|
98
98
|
const entity = await this.deps.repository.findEntityById(entityId, ctx);
|
|
99
99
|
if (!entity) return Err(new CommerceNotFoundError("Entity not found."));
|
|
100
100
|
try { this.assertSameOrg(entity, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
101
|
-
const addCatOrgId =
|
|
101
|
+
const addCatOrgId = resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config);
|
|
102
102
|
const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(categoryId);
|
|
103
103
|
let category = isUuid ? await this.repo.findCategoryById(categoryId, ctx) : null;
|
|
104
104
|
if (!category) category = await this.repo.findCategoryBySlug(addCatOrgId, categoryId, ctx);
|
|
@@ -116,7 +116,7 @@ export class CategoryService {
|
|
|
116
116
|
try { this.assertSameOrg(entity, actor); } catch (error) { return Err(toCommerceError(error)); }
|
|
117
117
|
const isCatUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(categoryId);
|
|
118
118
|
let category = isCatUuid ? await this.repo.findCategoryById(categoryId, ctx) : null;
|
|
119
|
-
if (!category) category = await this.repo.findCategoryBySlug(
|
|
119
|
+
if (!category) category = await this.repo.findCategoryBySlug(resolveOrgIdForCommerce(actor ?? ctx?.actor ?? null, this.deps.config), categoryId, ctx);
|
|
120
120
|
const removed = await this.repo.removeEntityFromCategory(entityId, category?.id ?? categoryId, ctx);
|
|
121
121
|
if (!removed) return Err(new CommerceNotFoundError("Category assignment not found."));
|
|
122
122
|
return Ok(undefined);
|