@porulle/core 0.8.0 → 0.10.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/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +26 -7
- package/dist/auth/setup.d.ts.map +1 -1
- package/dist/auth/setup.js +7 -5
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +3 -1
- package/dist/config/types.d.ts +13 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/generated/plugin-manifest.d.ts +3 -0
- package/dist/generated/plugin-manifest.d.ts.map +1 -1
- package/dist/generated/plugin-manifest.js +1 -0
- package/dist/hooks/checkout-completion.d.ts.map +1 -1
- package/dist/hooks/checkout-completion.js +2 -2
- package/dist/hooks/checkout.d.ts.map +1 -1
- package/dist/hooks/checkout.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/interfaces/rest/router.d.ts.map +1 -1
- package/dist/interfaces/rest/router.js +2 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/admin/staff.js +37 -3
- package/dist/interfaces/rest/routes/checkout.d.ts +9 -0
- package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/checkout.js +82 -22
- package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/inventory.js +13 -0
- package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/orders.js +13 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts +391 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/orders.js +2 -2
- package/dist/interfaces/rest/schemas/responses.d.ts +85 -0
- package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/search.d.ts +17 -0
- package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
- package/dist/kernel/database/scoped-db.d.ts +2 -1
- package/dist/kernel/database/scoped-db.d.ts.map +1 -1
- package/dist/kernel/database/scoped-db.js +74 -15
- package/dist/kernel/errors.d.ts +12 -0
- package/dist/kernel/errors.d.ts.map +1 -1
- package/dist/kernel/errors.js +16 -0
- package/dist/kernel/jobs/adapter.d.ts +27 -8
- package/dist/kernel/jobs/adapter.d.ts.map +1 -1
- package/dist/kernel/jobs/adapter.js +1 -2
- package/dist/kernel/jobs/drizzle-adapter.d.ts +13 -3
- package/dist/kernel/jobs/drizzle-adapter.d.ts.map +1 -1
- package/dist/kernel/jobs/drizzle-adapter.js +46 -5
- package/dist/kernel/jobs/runner.d.ts +2 -1
- package/dist/kernel/jobs/runner.d.ts.map +1 -1
- package/dist/kernel/jobs/runner.js +100 -15
- package/dist/kernel/jobs/types.d.ts +13 -0
- package/dist/kernel/jobs/types.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.d.ts +5 -0
- package/dist/kernel/plugin/manifest.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.js +9 -0
- package/dist/modules/analytics/drizzle-adapter.d.ts.map +1 -1
- package/dist/modules/analytics/drizzle-adapter.js +16 -3
- package/dist/modules/cart/service.d.ts.map +1 -1
- package/dist/modules/cart/service.js +3 -2
- package/dist/modules/catalog/entity-service.d.ts +1 -0
- package/dist/modules/catalog/entity-service.d.ts.map +1 -1
- package/dist/modules/catalog/entity-service.js +49 -3
- package/dist/modules/catalog/repository/index.d.ts +2 -2
- package/dist/modules/catalog/repository/index.d.ts.map +1 -1
- package/dist/modules/catalog/repository/index.js +9 -1
- package/dist/modules/catalog/schema.d.ts +51 -0
- package/dist/modules/catalog/schema.d.ts.map +1 -1
- package/dist/modules/catalog/schema.js +12 -1
- package/dist/modules/catalog/schemas.d.ts +3 -1
- package/dist/modules/catalog/schemas.d.ts.map +1 -1
- package/dist/modules/channels/adapter.d.ts +117 -0
- package/dist/modules/channels/adapter.d.ts.map +1 -0
- package/dist/modules/channels/adapter.js +3 -0
- package/dist/modules/customers/service.d.ts.map +1 -1
- package/dist/modules/customers/service.js +6 -0
- package/dist/modules/inventory/repository/index.js +4 -4
- package/dist/modules/inventory/service.d.ts.map +1 -1
- package/dist/modules/inventory/service.js +7 -3
- 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 +4 -0
- package/dist/modules/orders/service.d.ts +16 -2
- package/dist/modules/orders/service.d.ts.map +1 -1
- package/dist/modules/orders/service.js +226 -26
- package/dist/modules/orders/stale-order-cleanup.d.ts.map +1 -1
- package/dist/modules/orders/stale-order-cleanup.js +37 -16
- package/dist/modules/pricing/service.d.ts.map +1 -1
- package/dist/modules/pricing/service.js +5 -5
- package/dist/modules/promotions/repository/index.d.ts +1 -1
- package/dist/modules/promotions/repository/index.d.ts.map +1 -1
- package/dist/modules/promotions/repository/index.js +6 -3
- package/dist/modules/promotions/service.d.ts +1 -0
- package/dist/modules/promotions/service.d.ts.map +1 -1
- package/dist/modules/promotions/service.js +1 -1
- package/dist/modules/webhooks/repository/index.d.ts +1 -1
- package/dist/modules/webhooks/repository/index.d.ts.map +1 -1
- package/dist/modules/webhooks/repository/index.js +16 -10
- package/dist/runtime/kernel.d.ts.map +1 -1
- package/dist/runtime/kernel.js +14 -2
- package/dist/runtime/server.d.ts +1 -4
- package/dist/runtime/server.d.ts.map +1 -1
- package/dist/runtime/server.js +16 -34
- package/dist/test-utils/create-test-config.d.ts.map +1 -1
- package/dist/test-utils/create-test-config.js +2 -0
- package/dist/test-utils/order-test-helpers.d.ts +12 -0
- package/dist/test-utils/order-test-helpers.d.ts.map +1 -0
- package/dist/test-utils/order-test-helpers.js +18 -0
- package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
- package/dist/test-utils/rest-api-test-utils.js +1 -0
- package/dist/test-utils/test-actors.js +1 -1
- package/dist/testing.d.ts +1 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1 -0
- package/package.json +1 -1
- package/src/auth/middleware.ts +26 -7
- package/src/auth/setup.ts +10 -4
- package/src/config/defaults.ts +3 -1
- package/src/config/types.ts +16 -3
- package/src/generated/plugin-capabilities.d.ts +1 -0
- package/src/generated/plugin-manifest.ts +1 -0
- package/src/generated/plugin-repositories.d.ts +1 -0
- package/src/hooks/checkout-completion.ts +22 -16
- package/src/hooks/checkout.ts +11 -8
- package/src/index.ts +31 -1
- package/src/interfaces/rest/router.ts +2 -0
- package/src/interfaces/rest/routes/admin/staff.ts +45 -3
- package/src/interfaces/rest/routes/checkout.ts +94 -28
- package/src/interfaces/rest/routes/inventory.ts +14 -0
- package/src/interfaces/rest/routes/orders.ts +11 -0
- package/src/interfaces/rest/schemas/orders.ts +2 -2
- package/src/kernel/database/scoped-db.ts +83 -15
- package/src/kernel/errors.ts +20 -0
- package/src/kernel/jobs/adapter.ts +39 -8
- package/src/kernel/jobs/drizzle-adapter.ts +72 -9
- package/src/kernel/jobs/runner.ts +194 -72
- package/src/kernel/jobs/types.ts +25 -0
- package/src/kernel/plugin/manifest.ts +15 -0
- package/src/modules/analytics/drizzle-adapter.ts +19 -3
- package/src/modules/cart/service.ts +3 -2
- package/src/modules/catalog/entity-service.ts +37 -2
- package/src/modules/catalog/repository/index.ts +13 -3
- package/src/modules/catalog/schema.ts +33 -18
- package/src/modules/catalog/schemas.ts +3 -1
- package/src/modules/channels/adapter.ts +139 -0
- package/src/modules/customers/service.ts +6 -0
- package/src/modules/inventory/repository/index.ts +4 -4
- package/src/modules/inventory/service.ts +12 -2
- package/src/modules/orders/schema.ts +4 -0
- package/src/modules/orders/service.ts +404 -64
- package/src/modules/orders/stale-order-cleanup.ts +52 -27
- package/src/modules/pricing/service.ts +5 -6
- package/src/modules/promotions/repository/index.ts +6 -2
- package/src/modules/promotions/service.ts +2 -0
- package/src/modules/webhooks/repository/index.ts +16 -14
- package/src/runtime/kernel.ts +16 -2
- package/src/runtime/server.ts +22 -42
- package/src/test-utils/create-test-config.ts +2 -0
- package/src/test-utils/order-test-helpers.ts +26 -0
- package/src/test-utils/rest-api-test-utils.ts +1 -0
- package/src/test-utils/test-actors.ts +1 -1
- package/src/testing.ts +1 -0
|
@@ -507,6 +507,23 @@ export declare const OrderLineItemSchema: import("drizzle-zod").BuildSchema<"sel
|
|
|
507
507
|
identity: undefined;
|
|
508
508
|
generated: undefined;
|
|
509
509
|
}, {}, {}>;
|
|
510
|
+
isCustomPrice: import("drizzle-orm/pg-core").PgColumn<{
|
|
511
|
+
name: "is_custom_price";
|
|
512
|
+
tableName: "order_line_items";
|
|
513
|
+
dataType: "boolean";
|
|
514
|
+
columnType: "PgBoolean";
|
|
515
|
+
data: boolean;
|
|
516
|
+
driverParam: boolean;
|
|
517
|
+
notNull: true;
|
|
518
|
+
hasDefault: true;
|
|
519
|
+
isPrimaryKey: false;
|
|
520
|
+
isAutoincrement: false;
|
|
521
|
+
hasRuntimeDefault: false;
|
|
522
|
+
enumValues: undefined;
|
|
523
|
+
baseColumn: never;
|
|
524
|
+
identity: undefined;
|
|
525
|
+
generated: undefined;
|
|
526
|
+
}, {}, {}>;
|
|
510
527
|
taxAmount: import("drizzle-orm/pg-core").PgColumn<{
|
|
511
528
|
name: "tax_amount";
|
|
512
529
|
tableName: "order_line_items";
|
|
@@ -769,6 +786,23 @@ export declare const OrderWithItemsSchema: z.ZodObject<{
|
|
|
769
786
|
identity: undefined;
|
|
770
787
|
generated: undefined;
|
|
771
788
|
}, {}, {}>;
|
|
789
|
+
isCustomPrice: import("drizzle-orm/pg-core").PgColumn<{
|
|
790
|
+
name: "is_custom_price";
|
|
791
|
+
tableName: "order_line_items";
|
|
792
|
+
dataType: "boolean";
|
|
793
|
+
columnType: "PgBoolean";
|
|
794
|
+
data: boolean;
|
|
795
|
+
driverParam: boolean;
|
|
796
|
+
notNull: true;
|
|
797
|
+
hasDefault: true;
|
|
798
|
+
isPrimaryKey: false;
|
|
799
|
+
isAutoincrement: false;
|
|
800
|
+
hasRuntimeDefault: false;
|
|
801
|
+
enumValues: undefined;
|
|
802
|
+
baseColumn: never;
|
|
803
|
+
identity: undefined;
|
|
804
|
+
generated: undefined;
|
|
805
|
+
}, {}, {}>;
|
|
772
806
|
taxAmount: import("drizzle-orm/pg-core").PgColumn<{
|
|
773
807
|
name: "tax_amount";
|
|
774
808
|
tableName: "order_line_items";
|
|
@@ -1892,6 +1926,23 @@ export declare const CatalogEntitySchema: import("drizzle-zod").BuildSchema<"sel
|
|
|
1892
1926
|
identity: undefined;
|
|
1893
1927
|
generated: undefined;
|
|
1894
1928
|
}, {}, {}>;
|
|
1929
|
+
sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1930
|
+
name: "source_store_id";
|
|
1931
|
+
tableName: "sellable_entities";
|
|
1932
|
+
dataType: "string";
|
|
1933
|
+
columnType: "PgText";
|
|
1934
|
+
data: string;
|
|
1935
|
+
driverParam: string;
|
|
1936
|
+
notNull: false;
|
|
1937
|
+
hasDefault: false;
|
|
1938
|
+
isPrimaryKey: false;
|
|
1939
|
+
isAutoincrement: false;
|
|
1940
|
+
hasRuntimeDefault: false;
|
|
1941
|
+
enumValues: [string, ...string[]];
|
|
1942
|
+
baseColumn: never;
|
|
1943
|
+
identity: undefined;
|
|
1944
|
+
generated: undefined;
|
|
1945
|
+
}, {}, {}>;
|
|
1895
1946
|
type: import("drizzle-orm/pg-core").PgColumn<{
|
|
1896
1947
|
name: "type";
|
|
1897
1948
|
tableName: "sellable_entities";
|
|
@@ -3656,6 +3707,23 @@ export declare const CatalogEntityResponse: z.ZodObject<{
|
|
|
3656
3707
|
identity: undefined;
|
|
3657
3708
|
generated: undefined;
|
|
3658
3709
|
}, {}, {}>;
|
|
3710
|
+
sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
|
|
3711
|
+
name: "source_store_id";
|
|
3712
|
+
tableName: "sellable_entities";
|
|
3713
|
+
dataType: "string";
|
|
3714
|
+
columnType: "PgText";
|
|
3715
|
+
data: string;
|
|
3716
|
+
driverParam: string;
|
|
3717
|
+
notNull: false;
|
|
3718
|
+
hasDefault: false;
|
|
3719
|
+
isPrimaryKey: false;
|
|
3720
|
+
isAutoincrement: false;
|
|
3721
|
+
hasRuntimeDefault: false;
|
|
3722
|
+
enumValues: [string, ...string[]];
|
|
3723
|
+
baseColumn: never;
|
|
3724
|
+
identity: undefined;
|
|
3725
|
+
generated: undefined;
|
|
3726
|
+
}, {}, {}>;
|
|
3659
3727
|
type: import("drizzle-orm/pg-core").PgColumn<{
|
|
3660
3728
|
name: "type";
|
|
3661
3729
|
tableName: "sellable_entities";
|
|
@@ -3851,6 +3919,23 @@ export declare const CatalogEntityListResponse: z.ZodObject<{
|
|
|
3851
3919
|
identity: undefined;
|
|
3852
3920
|
generated: undefined;
|
|
3853
3921
|
}, {}, {}>;
|
|
3922
|
+
sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
|
|
3923
|
+
name: "source_store_id";
|
|
3924
|
+
tableName: "sellable_entities";
|
|
3925
|
+
dataType: "string";
|
|
3926
|
+
columnType: "PgText";
|
|
3927
|
+
data: string;
|
|
3928
|
+
driverParam: string;
|
|
3929
|
+
notNull: false;
|
|
3930
|
+
hasDefault: false;
|
|
3931
|
+
isPrimaryKey: false;
|
|
3932
|
+
isAutoincrement: false;
|
|
3933
|
+
hasRuntimeDefault: false;
|
|
3934
|
+
enumValues: [string, ...string[]];
|
|
3935
|
+
baseColumn: never;
|
|
3936
|
+
identity: undefined;
|
|
3937
|
+
generated: undefined;
|
|
3938
|
+
}, {}, {}>;
|
|
3854
3939
|
type: import("drizzle-orm/pg-core").PgColumn<{
|
|
3855
3940
|
name: "type";
|
|
3856
3941
|
tableName: "sellable_entities";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/responses.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAStC,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAEpB,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/responses.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAStC,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAEpB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAE5B,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGL,CAAC;AAI7B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAEnB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEL,CAAC;AAE3B,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGL,CAAC;AAI5B,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAoD,CAAC;AAEhF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAmE,CAAC;AAItG,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAGL,CAAC;AAI5B,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAkD,CAAC;AAKzE,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;kBAExE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;kBAE7E;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM;;;;;;;kBAS7E;AAID,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA6C,CAAC;AACxE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsD,CAAC;AACrF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAoD,CAAC;AAC9E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAmD,CAAC;AACjF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA0E,CAAC;AACnH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA6D,CAAC;AAChG,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsE,CAAC;AAC7G,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAkD,CAAC"}
|
|
@@ -56,6 +56,23 @@ export declare const searchRoute: {
|
|
|
56
56
|
identity: undefined;
|
|
57
57
|
generated: undefined;
|
|
58
58
|
}, {}, {}>;
|
|
59
|
+
sourceStoreId: import("drizzle-orm/pg-core").PgColumn<{
|
|
60
|
+
name: "source_store_id";
|
|
61
|
+
tableName: "sellable_entities";
|
|
62
|
+
dataType: "string";
|
|
63
|
+
columnType: "PgText";
|
|
64
|
+
data: string;
|
|
65
|
+
driverParam: string;
|
|
66
|
+
notNull: false;
|
|
67
|
+
hasDefault: false;
|
|
68
|
+
isPrimaryKey: false;
|
|
69
|
+
isAutoincrement: false;
|
|
70
|
+
hasRuntimeDefault: false;
|
|
71
|
+
enumValues: [string, ...string[]];
|
|
72
|
+
baseColumn: never;
|
|
73
|
+
identity: undefined;
|
|
74
|
+
generated: undefined;
|
|
75
|
+
}, {}, {}>;
|
|
59
76
|
type: import("drizzle-orm/pg-core").PgColumn<{
|
|
60
77
|
name: "type";
|
|
61
78
|
tableName: "sellable_entities";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAKnD,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/schemas/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAKnD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBvB,CAAC"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wraps a Drizzle PgDatabase instance so that INSERT operations on
|
|
5
5
|
* org-scoped tables automatically include the actor's organizationId,
|
|
6
|
-
* and SELECT
|
|
6
|
+
* and SELECT / UPDATE / DELETE against org-scoped tables constrain rows to
|
|
7
|
+
* that organization — including when the caller supplies no WHERE clause.
|
|
7
8
|
*
|
|
8
9
|
* Plugin route handlers receive this scoped db via PluginContext.database.db
|
|
9
10
|
* (organization resolved per operation from AsyncLocalStorage when used from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/kernel/database/scoped-db.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/kernel/database/scoped-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;AAuD3D,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,oBAAoB,GAAG,GAAG,CA2GpF"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wraps a Drizzle PgDatabase instance so that INSERT operations on
|
|
5
5
|
* org-scoped tables automatically include the actor's organizationId,
|
|
6
|
-
* and SELECT
|
|
6
|
+
* and SELECT / UPDATE / DELETE against org-scoped tables constrain rows to
|
|
7
|
+
* that organization — including when the caller supplies no WHERE clause.
|
|
7
8
|
*
|
|
8
9
|
* Plugin route handlers receive this scoped db via PluginContext.database.db
|
|
9
10
|
* (organization resolved per operation from AsyncLocalStorage when used from
|
|
@@ -24,6 +25,40 @@ function tableHasOrganizationId(table) {
|
|
|
24
25
|
return false;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Wrap a WHERE-able Drizzle builder so every `.where()` call AND-s `orgEq` in
|
|
30
|
+
* AND re-wraps its result. Re-wrapping is what makes a chained
|
|
31
|
+
* `.where(a).where(b)` safe: Drizzle's second `.where()` REPLACES the first, so
|
|
32
|
+
* without re-wrapping the chained call would reach the raw builder and execute
|
|
33
|
+
* with only the caller's condition — dropping the org predicate and leaking
|
|
34
|
+
* across tenants. Every link in the chain re-injects `orgEq`.
|
|
35
|
+
*/
|
|
36
|
+
function wrapWhereable(builder, orgEq) {
|
|
37
|
+
return new Proxy(builder, {
|
|
38
|
+
get(st, sp, sr) {
|
|
39
|
+
const sv = Reflect.get(st, sp, sr);
|
|
40
|
+
if (sp === "where" && typeof sv === "function") {
|
|
41
|
+
return (condition, ...wRest) => {
|
|
42
|
+
const c = condition;
|
|
43
|
+
const merged = c ? and(orgEq, c) : orgEq;
|
|
44
|
+
const next = sv.call(st, merged, ...wRest);
|
|
45
|
+
return wrapWhereable(next, orgEq);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return typeof sv === "function" ? sv.bind(st) : sv;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Pre-apply the org predicate to a WHERE-able builder (UPDATE/DELETE) and wrap
|
|
54
|
+
* its `.where()` so a caller-supplied condition is AND-ed with the org filter
|
|
55
|
+
* rather than replacing it. Pre-applying `orgEq` immediately means a builder
|
|
56
|
+
* executed with NO caller `.where()` (e.g. `update(t).set(...)`) is still
|
|
57
|
+
* constrained to the org — it can never touch another tenant's rows.
|
|
58
|
+
*/
|
|
59
|
+
function scopeWhereBuilder(builder, orgEq) {
|
|
60
|
+
return wrapWhereable(builder.where(orgEq), orgEq);
|
|
61
|
+
}
|
|
27
62
|
export function createScopedDb(rawDb, orgSource) {
|
|
28
63
|
if (!rawDb || typeof rawDb !== "object")
|
|
29
64
|
return rawDb;
|
|
@@ -76,20 +111,7 @@ export function createScopedDb(rawDb, orgSource) {
|
|
|
76
111
|
return chain;
|
|
77
112
|
const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
|
|
78
113
|
const inner = chain;
|
|
79
|
-
|
|
80
|
-
return new Proxy(scoped, {
|
|
81
|
-
get(st, sp, sr) {
|
|
82
|
-
const sv = Reflect.get(st, sp, sr);
|
|
83
|
-
if (sp === "where" && typeof sv === "function") {
|
|
84
|
-
return (condition, ...wRest) => {
|
|
85
|
-
const c = condition;
|
|
86
|
-
const merged = c ? and(orgEq, c) : orgEq;
|
|
87
|
-
return sv.call(st, merged, ...wRest);
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
return typeof sv === "function" ? sv.bind(st) : sv;
|
|
91
|
-
},
|
|
92
|
-
});
|
|
114
|
+
return wrapWhereable(inner.where(orgEq), orgEq);
|
|
93
115
|
};
|
|
94
116
|
}
|
|
95
117
|
return typeof sbVal === "function" ? sbVal.bind(sbTarget) : sbVal;
|
|
@@ -97,6 +119,43 @@ export function createScopedDb(rawDb, orgSource) {
|
|
|
97
119
|
});
|
|
98
120
|
};
|
|
99
121
|
}
|
|
122
|
+
if (prop === "update" && typeof value === "function") {
|
|
123
|
+
return (table) => {
|
|
124
|
+
const builder = value.call(target, table);
|
|
125
|
+
if (!tableHasOrganizationId(table))
|
|
126
|
+
return builder;
|
|
127
|
+
const orgCol = getTableColumns(table).organizationId;
|
|
128
|
+
if (!orgCol)
|
|
129
|
+
return builder;
|
|
130
|
+
const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
|
|
131
|
+
// The org filter lives after `.set()`, so wrap `.set()` and scope the
|
|
132
|
+
// resulting WHERE-able builder.
|
|
133
|
+
return new Proxy(builder, {
|
|
134
|
+
get(t, p, r) {
|
|
135
|
+
const v = Reflect.get(t, p, r);
|
|
136
|
+
if (p === "set" && typeof v === "function") {
|
|
137
|
+
return (data) => {
|
|
138
|
+
const setBuilder = v.call(t, data);
|
|
139
|
+
return scopeWhereBuilder(setBuilder, orgEq);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return typeof v === "function" ? v.bind(t) : v;
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (prop === "delete" && typeof value === "function") {
|
|
148
|
+
return (table) => {
|
|
149
|
+
const builder = value.call(target, table);
|
|
150
|
+
if (!tableHasOrganizationId(table))
|
|
151
|
+
return builder;
|
|
152
|
+
const orgCol = getTableColumns(table).organizationId;
|
|
153
|
+
if (!orgCol)
|
|
154
|
+
return builder;
|
|
155
|
+
const orgEq = eq(orgCol, resolveOrganizationId(orgSource));
|
|
156
|
+
return scopeWhereBuilder(builder, orgEq);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
100
159
|
return typeof value === "function" ? value.bind(target) : value;
|
|
101
160
|
},
|
|
102
161
|
});
|
package/dist/kernel/errors.d.ts
CHANGED
|
@@ -18,6 +18,18 @@ export declare class CommerceValidationError extends Error implements CommerceEr
|
|
|
18
18
|
code: "VALIDATION_FAILED";
|
|
19
19
|
constructor(message: string, fieldErrors?: FieldError[] | undefined, details?: unknown | undefined);
|
|
20
20
|
}
|
|
21
|
+
/** Canonical message for a missing inventory record — the single source used by
|
|
22
|
+
* the inventory repository and mapped to the typed error below. */
|
|
23
|
+
export declare const INVENTORY_RECORD_NOT_FOUND_MESSAGE = "No inventory record found for this entity.";
|
|
24
|
+
/** Raised when an inventory reserve/release targets an entity with no inventory
|
|
25
|
+
* record. Consumers (e.g. order status transitions that tolerate a missing
|
|
26
|
+
* record) discriminate on `code === "INVENTORY_RECORD_NOT_FOUND"`, never the
|
|
27
|
+
* message string. */
|
|
28
|
+
export declare class CommerceInventoryRecordNotFoundError extends Error implements CommerceError {
|
|
29
|
+
details?: unknown | undefined;
|
|
30
|
+
code: "INVENTORY_RECORD_NOT_FOUND";
|
|
31
|
+
constructor(message?: string, details?: unknown | undefined);
|
|
32
|
+
}
|
|
21
33
|
export declare class CommerceForbiddenError extends Error implements CommerceError {
|
|
22
34
|
details?: unknown | undefined;
|
|
23
35
|
code: "FORBIDDEN";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;mEACmE;AACnE,eAAO,MAAM,kCAAkC,+CACD,CAAC;AAE/C;;;qBAGqB;AACrB,qBAAa,oCAAqC,SAAQ,KAAM,YAAW,aAAa;IAI7E,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,4BAA4B,CAAU;gBAE3C,OAAO,GAAE,MAA2C,EAC7C,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
|
package/dist/kernel/errors.js
CHANGED
|
@@ -18,6 +18,22 @@ export class CommerceValidationError extends Error {
|
|
|
18
18
|
this.name = "CommerceValidationError";
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/** Canonical message for a missing inventory record — the single source used by
|
|
22
|
+
* the inventory repository and mapped to the typed error below. */
|
|
23
|
+
export const INVENTORY_RECORD_NOT_FOUND_MESSAGE = "No inventory record found for this entity.";
|
|
24
|
+
/** Raised when an inventory reserve/release targets an entity with no inventory
|
|
25
|
+
* record. Consumers (e.g. order status transitions that tolerate a missing
|
|
26
|
+
* record) discriminate on `code === "INVENTORY_RECORD_NOT_FOUND"`, never the
|
|
27
|
+
* message string. */
|
|
28
|
+
export class CommerceInventoryRecordNotFoundError extends Error {
|
|
29
|
+
details;
|
|
30
|
+
code = "INVENTORY_RECORD_NOT_FOUND";
|
|
31
|
+
constructor(message = INVENTORY_RECORD_NOT_FOUND_MESSAGE, details) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.details = details;
|
|
34
|
+
this.name = "CommerceInventoryRecordNotFoundError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
21
37
|
export class CommerceForbiddenError extends Error {
|
|
22
38
|
details;
|
|
23
39
|
code = "FORBIDDEN";
|
|
@@ -1,12 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* The full DrizzleJobsAdapter implements this; hooks receive
|
|
4
|
-
* it on HookContext.jobs so they can defer work without caring
|
|
5
|
-
* about the underlying storage.
|
|
6
|
-
*/
|
|
1
|
+
import type { JobProcessingOrder, TaskContext, TaskDefinition } from "./types.js";
|
|
2
|
+
/** Enqueue-only surface exposed to hooks and services. */
|
|
7
3
|
export interface JobsAdapter {
|
|
8
4
|
enqueue(taskSlug: string, input: Record<string, unknown>, options: EnqueueOptions): Promise<string>;
|
|
9
5
|
}
|
|
6
|
+
export interface RunJobsOptions {
|
|
7
|
+
queue?: string;
|
|
8
|
+
limit?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface RunJobsResult {
|
|
11
|
+
processed: number;
|
|
12
|
+
failed: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ExecutionEngineSetup {
|
|
15
|
+
tasks: ReadonlyMap<string, TaskDefinition>;
|
|
16
|
+
context: TaskContext;
|
|
17
|
+
processingOrder?: JobProcessingOrder;
|
|
18
|
+
}
|
|
19
|
+
export type ExecutionDriver = {
|
|
20
|
+
mode: "pull";
|
|
21
|
+
run(options?: RunJobsOptions): Promise<RunJobsResult>;
|
|
22
|
+
} | {
|
|
23
|
+
mode: "push";
|
|
24
|
+
};
|
|
25
|
+
/** Full job-engine contract selected through `config.jobs.adapter`. */
|
|
26
|
+
export interface ExecutionEngine extends JobsAdapter {
|
|
27
|
+
readonly execution: ExecutionDriver;
|
|
28
|
+
register(setup: ExecutionEngineSetup): void;
|
|
29
|
+
}
|
|
10
30
|
export interface EnqueueOptions {
|
|
11
31
|
organizationId: string;
|
|
12
32
|
queue?: string;
|
|
@@ -16,8 +36,7 @@ export interface EnqueueOptions {
|
|
|
16
36
|
supersedes?: boolean;
|
|
17
37
|
}
|
|
18
38
|
/**
|
|
19
|
-
* No-op
|
|
20
|
-
* All enqueue calls silently succeed and return a placeholder ID.
|
|
39
|
+
* No-op enqueue surface used by isolated hook contexts.
|
|
21
40
|
*/
|
|
22
41
|
export declare class NullJobsAdapter implements JobsAdapter {
|
|
23
42
|
enqueue(_taskSlug: string, _input: Record<string, unknown>, _options: EnqueueOptions): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,OAAO,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACvD,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,uEAAuE;AACvE,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAC3C,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC;CAGnB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* No-op
|
|
3
|
-
* All enqueue calls silently succeed and return a placeholder ID.
|
|
2
|
+
* No-op enqueue surface used by isolated hook contexts.
|
|
4
3
|
*/
|
|
5
4
|
export class NullJobsAdapter {
|
|
6
5
|
async enqueue(_taskSlug, _input, _options) {
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import type { DrizzleDatabase } from "../database/drizzle-db.js";
|
|
2
2
|
import type { TaskDefinition } from "./types.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { EnqueueOptions, ExecutionEngine, ExecutionEngineSetup, RunJobsOptions } from "./adapter.js";
|
|
4
4
|
/**
|
|
5
5
|
* PostgreSQL-backed job queue adapter using the application's own database.
|
|
6
6
|
* Stores jobs in the `commerce_jobs` table. Supports concurrency keys
|
|
7
7
|
* and supersede semantics for deduplication.
|
|
8
8
|
*/
|
|
9
|
-
export declare class DrizzleJobsAdapter implements
|
|
9
|
+
export declare class DrizzleJobsAdapter implements ExecutionEngine {
|
|
10
10
|
private db;
|
|
11
11
|
private tasks;
|
|
12
|
-
|
|
12
|
+
private setup;
|
|
13
|
+
private lastStaleJobReaperAt;
|
|
14
|
+
readonly execution: {
|
|
15
|
+
mode: "pull";
|
|
16
|
+
run: (options?: RunJobsOptions) => Promise<{
|
|
17
|
+
processed: number;
|
|
18
|
+
failed: number;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
constructor(db: DrizzleDatabase, tasks?: Map<string, TaskDefinition>);
|
|
22
|
+
register(setup: ExecutionEngineSetup): void;
|
|
13
23
|
enqueue(taskSlug: string, input: Record<string, unknown>, options: EnqueueOptions): Promise<string>;
|
|
14
24
|
}
|
|
15
25
|
//# sourceMappingURL=drizzle-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle-adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/drizzle-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"drizzle-adapter.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/drizzle-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,cAAc,EACf,MAAM,cAAc,CAAC;AAUtB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IA4CtD,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IA5Cf,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,oBAAoB,CAAK;IAEjC,QAAQ,CAAC,SAAS;;wBAEK,cAAc;;;;MAmCnC;gBAGQ,EAAE,EAAE,eAAe,EACnB,KAAK,GAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAa;IAGxD,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI;IAKrC,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC;CA+CnB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { eq, and } from "drizzle-orm";
|
|
2
2
|
import { OrgResolutionError } from "../errors.js";
|
|
3
3
|
import { commerceJobs } from "./schema.js";
|
|
4
|
+
import { runPendingJobs } from "./runner.js";
|
|
5
|
+
import { getJobReapThresholdMs, getJobsReaperIntervalMs, runStaleJobReaper, } from "./reaper.js";
|
|
4
6
|
/**
|
|
5
7
|
* PostgreSQL-backed job queue adapter using the application's own database.
|
|
6
8
|
* Stores jobs in the `commerce_jobs` table. Supports concurrency keys
|
|
@@ -9,23 +11,62 @@ import { commerceJobs } from "./schema.js";
|
|
|
9
11
|
export class DrizzleJobsAdapter {
|
|
10
12
|
db;
|
|
11
13
|
tasks;
|
|
12
|
-
|
|
14
|
+
setup;
|
|
15
|
+
lastStaleJobReaperAt = 0;
|
|
16
|
+
execution = {
|
|
17
|
+
mode: "pull",
|
|
18
|
+
run: async (options = {}) => {
|
|
19
|
+
if (!this.setup) {
|
|
20
|
+
throw new Error("DrizzleJobsAdapter must be registered before running jobs.");
|
|
21
|
+
}
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
if (now - this.lastStaleJobReaperAt >= getJobsReaperIntervalMs()) {
|
|
24
|
+
this.lastStaleJobReaperAt = now;
|
|
25
|
+
try {
|
|
26
|
+
await runStaleJobReaper(this.db, getJobReapThresholdMs(), this.setup.context.logger);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
this.setup.context.logger.error("Stale job reaper failed", {
|
|
30
|
+
error: error instanceof Error ? error.message : String(error),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return runPendingJobs({
|
|
35
|
+
db: this.db,
|
|
36
|
+
tasks: new Map(this.setup.tasks),
|
|
37
|
+
logger: this.setup.context.logger,
|
|
38
|
+
services: this.setup.context.services,
|
|
39
|
+
...(options.queue !== undefined ? { queue: options.queue } : {}),
|
|
40
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
41
|
+
...(this.setup.processingOrder !== undefined
|
|
42
|
+
? { processingOrder: this.setup.processingOrder }
|
|
43
|
+
: {}),
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
constructor(db, tasks = new Map()) {
|
|
13
48
|
this.db = db;
|
|
14
49
|
this.tasks = tasks;
|
|
15
50
|
}
|
|
51
|
+
register(setup) {
|
|
52
|
+
this.setup = setup;
|
|
53
|
+
this.tasks = new Map(setup.tasks);
|
|
54
|
+
}
|
|
16
55
|
async enqueue(taskSlug, input, options) {
|
|
17
56
|
const organizationId = options.organizationId.trim();
|
|
18
57
|
if (!organizationId) {
|
|
19
58
|
throw new OrgResolutionError("Jobs enqueue requires a non-empty organizationId.");
|
|
20
59
|
}
|
|
60
|
+
const task = this.tasks.get(taskSlug);
|
|
61
|
+
const concurrencyKey = options.concurrencyKey ?? task?.concurrency?.key(input);
|
|
62
|
+
const supersedes = options.supersedes ?? task?.concurrency?.supersedes;
|
|
21
63
|
// If supersedes is set, delete existing pending jobs with the same concurrency key
|
|
22
|
-
if (
|
|
64
|
+
if (concurrencyKey && supersedes) {
|
|
23
65
|
await this.db
|
|
24
66
|
.delete(commerceJobs)
|
|
25
|
-
.where(and(eq(commerceJobs.
|
|
67
|
+
.where(and(eq(commerceJobs.organizationId, organizationId), eq(commerceJobs.taskSlug, taskSlug), eq(commerceJobs.concurrencyKey, concurrencyKey), eq(commerceJobs.status, "pending")));
|
|
26
68
|
}
|
|
27
69
|
// Look up task definition for default retry config
|
|
28
|
-
const task = this.tasks.get(taskSlug);
|
|
29
70
|
const maxAttempts = options.maxAttempts ?? task?.retries?.attempts ?? 1;
|
|
30
71
|
const rows = await this.db
|
|
31
72
|
.insert(commerceJobs)
|
|
@@ -38,7 +79,7 @@ export class DrizzleJobsAdapter {
|
|
|
38
79
|
waitUntil: options.delayMs
|
|
39
80
|
? new Date(Date.now() + options.delayMs)
|
|
40
81
|
: null,
|
|
41
|
-
concurrencyKey:
|
|
82
|
+
concurrencyKey: concurrencyKey ?? null,
|
|
42
83
|
})
|
|
43
84
|
.returning({ id: commerceJobs.id });
|
|
44
85
|
return rows[0].id;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { DrizzleDatabase } from "../database/drizzle-db.js";
|
|
2
2
|
import type { Logger, ServiceContainer } from "../hooks/types.js";
|
|
3
|
-
import type { TaskDefinition } from "./types.js";
|
|
3
|
+
import type { JobProcessingOrder, TaskDefinition } from "./types.js";
|
|
4
4
|
export interface RunPendingJobsArgs {
|
|
5
5
|
db: DrizzleDatabase;
|
|
6
6
|
tasks: Map<string, TaskDefinition>;
|
|
7
7
|
queue?: string;
|
|
8
8
|
limit?: number;
|
|
9
|
+
processingOrder?: JobProcessingOrder;
|
|
9
10
|
logger: Logger;
|
|
10
11
|
services: ServiceContainer;
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/kernel/jobs/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGrE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,eAAe,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AA4CD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkNhD"}
|