@porulle/core 0.7.0 → 0.9.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 +8 -5
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +7 -0
- package/dist/config/types.d.ts +26 -1
- 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 +17 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/interfaces/rest/index.d.ts.map +1 -1
- package/dist/interfaces/rest/index.js +12 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts +12 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/admin/staff.js +206 -0
- package/dist/interfaces/rest/routes/analytics.d.ts +5 -0
- package/dist/interfaces/rest/routes/analytics.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/analytics.js +24 -0
- package/dist/interfaces/rest/routes/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/carts.js +39 -2
- package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/catalog.js +17 -1
- 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 +97 -21
- package/dist/interfaces/rest/routes/documents.d.ts +10 -0
- package/dist/interfaces/rest/routes/documents.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/documents.js +40 -0
- 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 +111 -1
- package/dist/interfaces/rest/routes/pricing.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/pricing.js +36 -1
- package/dist/interfaces/rest/routes/settings.d.ts +5 -0
- package/dist/interfaces/rest/routes/settings.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/settings.js +50 -0
- package/dist/interfaces/rest/routes/shipping.d.ts +5 -0
- package/dist/interfaces/rest/routes/shipping.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/shipping.js +68 -0
- package/dist/interfaces/rest/routes/tax.d.ts +5 -0
- package/dist/interfaces/rest/routes/tax.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/tax.js +68 -0
- package/dist/interfaces/rest/schemas/admin-staff.d.ts +899 -0
- package/dist/interfaces/rest/schemas/admin-staff.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/admin-staff.js +98 -0
- package/dist/interfaces/rest/schemas/analytics.d.ts +252 -0
- package/dist/interfaces/rest/schemas/analytics.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/analytics.js +33 -0
- package/dist/interfaces/rest/schemas/carts.d.ts +656 -0
- package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/carts.js +38 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts +1218 -1
- package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/catalog.js +48 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts +2 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/checkout.js +4 -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/documents.d.ts +509 -0
- package/dist/interfaces/rest/schemas/documents.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/documents.js +65 -0
- package/dist/interfaces/rest/schemas/orders.d.ts +3110 -43
- package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/orders.js +234 -1
- package/dist/interfaces/rest/schemas/pricing.d.ts +405 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/pricing.js +70 -0
- package/dist/interfaces/rest/schemas/responses.d.ts +190 -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/interfaces/rest/schemas/settings.d.ts +397 -0
- package/dist/interfaces/rest/schemas/settings.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/settings.js +79 -0
- package/dist/interfaces/rest/schemas/shipping.d.ts +1093 -0
- package/dist/interfaces/rest/schemas/shipping.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/shipping.js +146 -0
- package/dist/interfaces/rest/schemas/tax.d.ts +1074 -0
- package/dist/interfaces/rest/schemas/tax.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/tax.js +132 -0
- package/dist/kernel/database/schema.d.ts +4 -0
- package/dist/kernel/database/schema.d.ts.map +1 -1
- package/dist/kernel/database/schema.js +8 -0
- 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 +62 -1
- package/dist/kernel/hooks/types.d.ts +1 -1
- package/dist/kernel/hooks/types.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.d.ts +26 -0
- package/dist/kernel/plugin/manifest.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.js +17 -2
- package/dist/modules/analytics/drizzle-adapter.d.ts.map +1 -1
- package/dist/modules/analytics/drizzle-adapter.js +16 -3
- package/dist/modules/analytics/module.d.ts.map +1 -1
- package/dist/modules/analytics/module.js +6 -0
- package/dist/modules/analytics/reports.d.ts +58 -0
- package/dist/modules/analytics/reports.d.ts.map +1 -0
- package/dist/modules/analytics/reports.js +249 -0
- package/dist/modules/analytics/service.d.ts +10 -0
- package/dist/modules/analytics/service.d.ts.map +1 -1
- package/dist/modules/analytics/service.js +14 -0
- package/dist/modules/cart/repository/index.d.ts +7 -0
- package/dist/modules/cart/repository/index.d.ts.map +1 -1
- package/dist/modules/cart/repository/index.js +25 -1
- 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 +2 -0
- package/dist/modules/cart/schemas.d.ts +1 -0
- package/dist/modules/cart/schemas.d.ts.map +1 -1
- package/dist/modules/cart/schemas.js +1 -0
- package/dist/modules/cart/service.d.ts +32 -0
- package/dist/modules/cart/service.d.ts.map +1 -1
- package/dist/modules/cart/service.js +61 -2
- package/dist/modules/catalog/entity-service.d.ts +21 -0
- package/dist/modules/catalog/entity-service.d.ts.map +1 -1
- package/dist/modules/catalog/entity-service.js +166 -5
- package/dist/modules/catalog/schema.d.ts +34 -0
- package/dist/modules/catalog/schema.d.ts.map +1 -1
- package/dist/modules/catalog/schema.js +5 -0
- package/dist/modules/catalog/schemas.d.ts +3 -0
- package/dist/modules/catalog/schemas.d.ts.map +1 -1
- package/dist/modules/catalog/schemas.js +3 -0
- package/dist/modules/catalog/service.d.ts +36 -0
- package/dist/modules/catalog/service.d.ts.map +1 -1
- package/dist/modules/catalog/service.js +6 -0
- package/dist/modules/customers/service.d.ts.map +1 -1
- package/dist/modules/customers/service.js +6 -0
- package/dist/modules/documents/module.d.ts +7 -0
- package/dist/modules/documents/module.d.ts.map +1 -0
- package/dist/modules/documents/module.js +12 -0
- package/dist/modules/documents/pdf.d.ts +25 -0
- package/dist/modules/documents/pdf.d.ts.map +1 -0
- package/dist/modules/documents/pdf.js +80 -0
- package/dist/modules/documents/render.d.ts +32 -0
- package/dist/modules/documents/render.d.ts.map +1 -0
- package/dist/modules/documents/render.js +190 -0
- package/dist/modules/documents/repository/index.d.ts +25 -0
- package/dist/modules/documents/repository/index.d.ts.map +1 -0
- package/dist/modules/documents/repository/index.js +47 -0
- package/dist/modules/documents/schema.d.ts +214 -0
- package/dist/modules/documents/schema.d.ts.map +1 -0
- package/dist/modules/documents/schema.js +42 -0
- package/dist/modules/documents/service.d.ts +51 -0
- package/dist/modules/documents/service.d.ts.map +1 -0
- package/dist/modules/documents/service.js +119 -0
- package/dist/modules/fulfillment/service.d.ts +18 -0
- package/dist/modules/fulfillment/service.d.ts.map +1 -1
- package/dist/modules/fulfillment/service.js +85 -1
- package/dist/modules/orders/repository/index.d.ts +18 -1
- package/dist/modules/orders/repository/index.d.ts.map +1 -1
- package/dist/modules/orders/repository/index.js +86 -1
- package/dist/modules/orders/schema.d.ts +391 -0
- package/dist/modules/orders/schema.d.ts.map +1 -1
- package/dist/modules/orders/schema.js +56 -1
- package/dist/modules/orders/service.d.ts +102 -3
- package/dist/modules/orders/service.d.ts.map +1 -1
- package/dist/modules/orders/service.js +653 -29
- package/dist/modules/orders/stale-order-cleanup.d.ts.map +1 -1
- package/dist/modules/orders/stale-order-cleanup.js +13 -1
- package/dist/modules/pricing/repository/index.d.ts +5 -0
- package/dist/modules/pricing/repository/index.d.ts.map +1 -1
- package/dist/modules/pricing/repository/index.js +19 -0
- package/dist/modules/pricing/service.d.ts +18 -0
- package/dist/modules/pricing/service.d.ts.map +1 -1
- package/dist/modules/pricing/service.js +43 -5
- package/dist/modules/settings/module.d.ts +6 -0
- package/dist/modules/settings/module.d.ts.map +1 -0
- package/dist/modules/settings/module.js +11 -0
- package/dist/modules/settings/repository/index.d.ts +16 -0
- package/dist/modules/settings/repository/index.d.ts.map +1 -0
- package/dist/modules/settings/repository/index.js +41 -0
- package/dist/modules/settings/schema.d.ts +121 -0
- package/dist/modules/settings/schema.d.ts.map +1 -0
- package/dist/modules/settings/schema.js +24 -0
- package/dist/modules/settings/service.d.ts +26 -0
- package/dist/modules/settings/service.d.ts.map +1 -0
- package/dist/modules/settings/service.js +51 -0
- package/dist/modules/shipping/calculator.d.ts +5 -0
- package/dist/modules/shipping/calculator.d.ts.map +1 -1
- package/dist/modules/shipping/calculator.js +10 -0
- package/dist/modules/shipping/module.d.ts +5 -1
- package/dist/modules/shipping/module.d.ts.map +1 -1
- package/dist/modules/shipping/module.js +4 -1
- package/dist/modules/shipping/repository/index.d.ts +27 -2
- package/dist/modules/shipping/repository/index.d.ts.map +1 -1
- package/dist/modules/shipping/repository/index.js +105 -1
- package/dist/modules/shipping/schema.d.ts +419 -0
- package/dist/modules/shipping/schema.d.ts.map +1 -0
- package/dist/modules/shipping/schema.js +56 -0
- package/dist/modules/shipping/service.d.ts +54 -0
- package/dist/modules/shipping/service.d.ts.map +1 -1
- package/dist/modules/shipping/service.js +161 -2
- package/dist/modules/tax/adapter.d.ts +13 -0
- package/dist/modules/tax/adapter.d.ts.map +1 -1
- package/dist/modules/tax/module.d.ts +5 -1
- package/dist/modules/tax/module.d.ts.map +1 -1
- package/dist/modules/tax/module.js +4 -1
- package/dist/modules/tax/repository/index.d.ts +38 -2
- package/dist/modules/tax/repository/index.d.ts.map +1 -1
- package/dist/modules/tax/repository/index.js +138 -1
- package/dist/modules/tax/schema.d.ts +355 -0
- package/dist/modules/tax/schema.d.ts.map +1 -0
- package/dist/modules/tax/schema.js +55 -0
- package/dist/modules/tax/service.d.ts +60 -1
- package/dist/modules/tax/service.d.ts.map +1 -1
- package/dist/modules/tax/service.js +227 -2
- package/dist/runtime/kernel-modules.d.ts +15 -2
- package/dist/runtime/kernel-modules.d.ts.map +1 -1
- package/dist/runtime/kernel-modules.js +4 -0
- package/dist/runtime/kernel-types.d.ts +5 -1
- package/dist/runtime/kernel-types.d.ts.map +1 -1
- package/dist/runtime/kernel-types.js +2 -0
- package/dist/runtime/server.js +1 -1
- package/dist/test-utils/create-plugin-test-app.d.ts +3 -0
- package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
- package/dist/test-utils/create-plugin-test-app.js +15 -3
- 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 +7 -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 +3 -3
- package/src/auth/middleware.ts +26 -7
- package/src/auth/setup.ts +11 -4
- package/src/config/defaults.ts +7 -0
- package/src/config/types.ts +26 -1
- 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 +36 -11
- package/src/index.ts +1 -0
- package/src/interfaces/rest/index.ts +12 -0
- package/src/interfaces/rest/routes/admin/staff.ts +260 -0
- package/src/interfaces/rest/routes/analytics.ts +33 -0
- package/src/interfaces/rest/routes/carts.ts +52 -2
- package/src/interfaces/rest/routes/catalog.ts +34 -0
- package/src/interfaces/rest/routes/checkout.ts +114 -27
- package/src/interfaces/rest/routes/documents.ts +61 -0
- package/src/interfaces/rest/routes/inventory.ts +14 -0
- package/src/interfaces/rest/routes/orders.ts +148 -1
- package/src/interfaces/rest/routes/pricing.ts +44 -1
- package/src/interfaces/rest/routes/settings.ts +61 -0
- package/src/interfaces/rest/routes/shipping.ts +92 -0
- package/src/interfaces/rest/routes/tax.ts +90 -0
- package/src/interfaces/rest/schemas/admin-staff.ts +110 -0
- package/src/interfaces/rest/schemas/analytics.ts +39 -0
- package/src/interfaces/rest/schemas/carts.ts +40 -0
- package/src/interfaces/rest/schemas/catalog.ts +53 -0
- package/src/interfaces/rest/schemas/checkout.ts +4 -0
- package/src/interfaces/rest/schemas/documents.ts +72 -0
- package/src/interfaces/rest/schemas/orders.ts +258 -1
- package/src/interfaces/rest/schemas/pricing.ts +75 -0
- package/src/interfaces/rest/schemas/settings.ts +93 -0
- package/src/interfaces/rest/schemas/shipping.ts +164 -0
- package/src/interfaces/rest/schemas/tax.ts +148 -0
- package/src/kernel/database/schema.ts +12 -0
- package/src/kernel/database/scoped-db.ts +70 -1
- package/src/kernel/hooks/types.ts +1 -0
- package/src/kernel/plugin/manifest.ts +41 -2
- package/src/modules/analytics/drizzle-adapter.ts +19 -3
- package/src/modules/analytics/module.ts +10 -0
- package/src/modules/analytics/reports.ts +311 -0
- package/src/modules/analytics/service.ts +23 -0
- package/src/modules/cart/repository/index.ts +30 -1
- package/src/modules/cart/schema.ts +2 -0
- package/src/modules/cart/schemas.ts +1 -0
- package/src/modules/cart/service.ts +104 -2
- package/src/modules/catalog/entity-service.ts +196 -4
- package/src/modules/catalog/schema.ts +5 -0
- package/src/modules/catalog/schemas.ts +3 -0
- package/src/modules/catalog/service.ts +30 -0
- package/src/modules/customers/service.ts +6 -0
- package/src/modules/documents/module.ts +19 -0
- package/src/modules/documents/pdf.ts +101 -0
- package/src/modules/documents/render.ts +231 -0
- package/src/modules/documents/repository/index.ts +68 -0
- package/src/modules/documents/schema.ts +44 -0
- package/src/modules/documents/service.ts +176 -0
- package/src/modules/fulfillment/service.ts +139 -1
- package/src/modules/orders/repository/index.ts +127 -1
- package/src/modules/orders/schema.ts +58 -1
- package/src/modules/orders/service.ts +1041 -65
- package/src/modules/orders/stale-order-cleanup.ts +18 -4
- package/src/modules/pricing/repository/index.ts +34 -0
- package/src/modules/pricing/service.ts +76 -6
- package/src/modules/settings/module.ts +18 -0
- package/src/modules/settings/repository/index.ts +59 -0
- package/src/modules/settings/schema.ts +25 -0
- package/src/modules/settings/service.ts +82 -0
- package/src/modules/shipping/calculator.ts +27 -0
- package/src/modules/shipping/module.ts +6 -2
- package/src/modules/shipping/repository/index.ts +136 -2
- package/src/modules/shipping/schema.ts +58 -0
- package/src/modules/shipping/service.ts +260 -1
- package/src/modules/tax/adapter.ts +9 -0
- package/src/modules/tax/module.ts +6 -2
- package/src/modules/tax/repository/index.ts +169 -2
- package/src/modules/tax/schema.ts +57 -0
- package/src/modules/tax/service.ts +313 -2
- package/src/runtime/kernel-modules.ts +4 -0
- package/src/runtime/kernel-types.ts +6 -0
- package/src/runtime/server.ts +1 -1
- package/src/test-utils/create-plugin-test-app.ts +17 -4
- 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 +7 -0
- package/src/test-utils/test-actors.ts +1 -1
- package/src/testing.ts +1 -0
|
@@ -1,11 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOrgId } from "../../auth/org.js";
|
|
2
|
+
import { CommerceNotFoundError, CommerceValidationError } from "../../kernel/errors.js";
|
|
2
3
|
import { Err, Ok } from "../../kernel/result.js";
|
|
3
4
|
export class TaxService {
|
|
4
5
|
adapter;
|
|
6
|
+
repository;
|
|
5
7
|
constructor(deps) {
|
|
6
8
|
this.adapter = deps.adapter;
|
|
9
|
+
this.repository = deps.repository;
|
|
7
10
|
}
|
|
8
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Calculates tax. Resolution order:
|
|
13
|
+
* 1. Product tax classes (issue #57) — when the org defines active classes,
|
|
14
|
+
* each line taxes by its class (variant taxClass beats entity taxClass;
|
|
15
|
+
* unclassed lines use the default class or 0), with `orderDiscount`
|
|
16
|
+
* pro-rated across lines first. Returns per-line results in `lines`.
|
|
17
|
+
* 2. Runtime tax rates for the org matching `toAddress` (issue #45) —
|
|
18
|
+
* state-specific matches beat country-level; matches at the winning
|
|
19
|
+
* specificity are summed (e.g. GST + PST).
|
|
20
|
+
* 3. The configured tax adapter.
|
|
21
|
+
* 4. Zero tax.
|
|
22
|
+
*/
|
|
23
|
+
async calculate(params, orgId, ctx) {
|
|
24
|
+
if (this.repository && orgId && params.lineItems.length > 0) {
|
|
25
|
+
const classes = await this.repository.findActiveClasses(orgId, ctx);
|
|
26
|
+
if (classes.length > 0) {
|
|
27
|
+
return Ok(await this.calculateByClasses(params, classes, ctx));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (this.repository && orgId && params.toAddress) {
|
|
31
|
+
const matched = await this.matchRuntimeRates(orgId, params.toAddress, ctx);
|
|
32
|
+
if (matched.length > 0) {
|
|
33
|
+
const taxableAmount = params.lineItems.reduce((sum, lineItem) => sum + lineItem.unitPrice * lineItem.quantity - (lineItem.discount ?? 0), 0);
|
|
34
|
+
let amountToCollect = 0;
|
|
35
|
+
const breakdown = {};
|
|
36
|
+
for (const rate of matched) {
|
|
37
|
+
const base = taxableAmount + (rate.appliesToShipping ? params.shippingAmount : 0);
|
|
38
|
+
const amount = Math.max(0, Math.round((base * rate.rateBps) / 10_000));
|
|
39
|
+
amountToCollect += amount;
|
|
40
|
+
breakdown[rate.name] = { rateBps: rate.rateBps, amount };
|
|
41
|
+
}
|
|
42
|
+
const totalBps = matched.reduce((sum, r) => sum + r.rateBps, 0);
|
|
43
|
+
return Ok({
|
|
44
|
+
amountToCollect,
|
|
45
|
+
taxableAmount,
|
|
46
|
+
rate: totalBps / 10_000,
|
|
47
|
+
breakdown,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
9
51
|
if (!this.adapter) {
|
|
10
52
|
return Ok({
|
|
11
53
|
amountToCollect: 0,
|
|
@@ -15,6 +57,123 @@ export class TaxService {
|
|
|
15
57
|
}
|
|
16
58
|
return this.adapter.calculateTax(params);
|
|
17
59
|
}
|
|
60
|
+
/** Per-line class-based tax with cart-discount pro-ration (issue #57). */
|
|
61
|
+
async calculateByClasses(params, classes, ctx) {
|
|
62
|
+
const byName = new Map(classes.map((c) => [c.name, c]));
|
|
63
|
+
const defaultClass = classes.find((c) => c.isDefault) ?? null;
|
|
64
|
+
const { byEntity, byVariant } = await this.repository.resolveCatalogTaxClasses(params.lineItems.map((li) => ({ entityId: li.entityId, variantId: li.variantId })), ctx);
|
|
65
|
+
// Pro-rate the cart-level discount across lines by value share; the last
|
|
66
|
+
// line absorbs the rounding remainder so the sum stays exact.
|
|
67
|
+
const lineValues = params.lineItems.map((li) => Math.max(0, li.unitPrice * li.quantity - (li.discount ?? 0)));
|
|
68
|
+
const totalValue = lineValues.reduce((sum, v) => sum + v, 0);
|
|
69
|
+
const orderDiscount = Math.min(params.orderDiscount ?? 0, totalValue);
|
|
70
|
+
const prorated = lineValues.map((value) => totalValue > 0 ? Math.round((orderDiscount * value) / totalValue) : 0);
|
|
71
|
+
if (lineValues.length > 0) {
|
|
72
|
+
const drift = orderDiscount - prorated.reduce((sum, v) => sum + v, 0);
|
|
73
|
+
prorated[prorated.length - 1] += drift;
|
|
74
|
+
}
|
|
75
|
+
let amountToCollect = 0;
|
|
76
|
+
let taxableAmount = 0;
|
|
77
|
+
const breakdown = {};
|
|
78
|
+
const lines = [];
|
|
79
|
+
for (const [i, lineItem] of params.lineItems.entries()) {
|
|
80
|
+
const className = (lineItem.variantId ? byVariant.get(lineItem.variantId) : null) ??
|
|
81
|
+
byEntity.get(lineItem.entityId) ??
|
|
82
|
+
defaultClass?.name ??
|
|
83
|
+
null;
|
|
84
|
+
const taxClass = className ? (byName.get(className) ?? defaultClass) : defaultClass;
|
|
85
|
+
const base = Math.max(0, lineValues[i] - prorated[i]);
|
|
86
|
+
const taxAmount = taxClass
|
|
87
|
+
? Math.max(0, Math.round((base * taxClass.rateBps) / 10_000))
|
|
88
|
+
: 0;
|
|
89
|
+
amountToCollect += taxAmount;
|
|
90
|
+
taxableAmount += base;
|
|
91
|
+
lines.push({ id: lineItem.id, taxClass: taxClass?.name ?? null, taxAmount });
|
|
92
|
+
if (taxClass) {
|
|
93
|
+
const entry = breakdown[taxClass.name] ?? {
|
|
94
|
+
rateBps: taxClass.rateBps,
|
|
95
|
+
amount: 0,
|
|
96
|
+
};
|
|
97
|
+
entry.amount += taxAmount;
|
|
98
|
+
breakdown[taxClass.name] = entry;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
amountToCollect,
|
|
103
|
+
taxableAmount,
|
|
104
|
+
rate: taxableAmount > 0 ? amountToCollect / taxableAmount : 0,
|
|
105
|
+
breakdown,
|
|
106
|
+
lines,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ── Tax class management (issue #57) ─────────────────────────────────────
|
|
110
|
+
async createTaxClass(input, actor, ctx) {
|
|
111
|
+
const repo = this.requireRepository();
|
|
112
|
+
if (!repo.ok)
|
|
113
|
+
return repo;
|
|
114
|
+
if (input.rateBps < 0) {
|
|
115
|
+
return Err(new CommerceValidationError("rateBps must be non-negative."));
|
|
116
|
+
}
|
|
117
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
118
|
+
if (input.isDefault)
|
|
119
|
+
await repo.value.clearDefaultClass(orgId, ctx);
|
|
120
|
+
const created = await repo.value.createClass({
|
|
121
|
+
organizationId: orgId,
|
|
122
|
+
name: input.name,
|
|
123
|
+
rateBps: input.rateBps,
|
|
124
|
+
isDefault: input.isDefault ?? false,
|
|
125
|
+
isActive: input.isActive ?? true,
|
|
126
|
+
}, ctx);
|
|
127
|
+
return Ok(created);
|
|
128
|
+
}
|
|
129
|
+
async listTaxClasses(actor, ctx) {
|
|
130
|
+
const repo = this.requireRepository();
|
|
131
|
+
if (!repo.ok)
|
|
132
|
+
return repo;
|
|
133
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
134
|
+
return Ok(await repo.value.findAllClasses(orgId, ctx));
|
|
135
|
+
}
|
|
136
|
+
async updateTaxClass(id, patch, actor, ctx) {
|
|
137
|
+
const repo = this.requireRepository();
|
|
138
|
+
if (!repo.ok)
|
|
139
|
+
return repo;
|
|
140
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
141
|
+
const existing = await repo.value.findClassById(orgId, id, ctx);
|
|
142
|
+
if (!existing)
|
|
143
|
+
return Err(new CommerceNotFoundError("Tax class not found."));
|
|
144
|
+
if (patch.isDefault)
|
|
145
|
+
await repo.value.clearDefaultClass(orgId, ctx);
|
|
146
|
+
const updated = await repo.value.updateClass(id, {
|
|
147
|
+
...(patch.name !== undefined ? { name: patch.name } : {}),
|
|
148
|
+
...(patch.rateBps !== undefined ? { rateBps: patch.rateBps } : {}),
|
|
149
|
+
...(patch.isDefault !== undefined ? { isDefault: patch.isDefault } : {}),
|
|
150
|
+
...(patch.isActive !== undefined ? { isActive: patch.isActive } : {}),
|
|
151
|
+
}, ctx);
|
|
152
|
+
return Ok(updated);
|
|
153
|
+
}
|
|
154
|
+
async deleteTaxClass(id, actor, ctx) {
|
|
155
|
+
const repo = this.requireRepository();
|
|
156
|
+
if (!repo.ok)
|
|
157
|
+
return repo;
|
|
158
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
159
|
+
const existing = await repo.value.findClassById(orgId, id, ctx);
|
|
160
|
+
if (!existing)
|
|
161
|
+
return Err(new CommerceNotFoundError("Tax class not found."));
|
|
162
|
+
await repo.value.deleteClass(id, ctx);
|
|
163
|
+
return Ok({ deleted: true });
|
|
164
|
+
}
|
|
165
|
+
async matchRuntimeRates(orgId, toAddress, ctx) {
|
|
166
|
+
const rates = await this.repository.findActive(orgId, ctx);
|
|
167
|
+
if (rates.length === 0)
|
|
168
|
+
return [];
|
|
169
|
+
const country = toAddress.country?.toUpperCase();
|
|
170
|
+
const state = toAddress.state?.toUpperCase();
|
|
171
|
+
const countryMatches = rates.filter((r) => r.country === "*" || r.country.toUpperCase() === country);
|
|
172
|
+
const stateMatches = countryMatches.filter((r) => r.state != null && state != null && r.state.toUpperCase() === state);
|
|
173
|
+
if (stateMatches.length > 0)
|
|
174
|
+
return stateMatches;
|
|
175
|
+
return countryMatches.filter((r) => r.state == null);
|
|
176
|
+
}
|
|
18
177
|
async reportTransaction(params) {
|
|
19
178
|
if (!this.adapter)
|
|
20
179
|
return Ok({ transactionId: params.transactionId });
|
|
@@ -31,4 +190,70 @@ export class TaxService {
|
|
|
31
190
|
}
|
|
32
191
|
return Ok(this.adapter);
|
|
33
192
|
}
|
|
193
|
+
// ── Runtime tax-rate management (issue #45) ────────────────────────────
|
|
194
|
+
requireRepository() {
|
|
195
|
+
if (!this.repository) {
|
|
196
|
+
return Err(new CommerceValidationError("Tax rate persistence is not available."));
|
|
197
|
+
}
|
|
198
|
+
return Ok(this.repository);
|
|
199
|
+
}
|
|
200
|
+
async createTaxRate(input, actor, ctx) {
|
|
201
|
+
const repo = this.requireRepository();
|
|
202
|
+
if (!repo.ok)
|
|
203
|
+
return repo;
|
|
204
|
+
if (input.rateBps < 0) {
|
|
205
|
+
return Err(new CommerceValidationError("rateBps must be non-negative."));
|
|
206
|
+
}
|
|
207
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
208
|
+
const rate = await repo.value.create({
|
|
209
|
+
organizationId: orgId,
|
|
210
|
+
name: input.name,
|
|
211
|
+
country: input.country.toUpperCase(),
|
|
212
|
+
state: input.state?.toUpperCase() ?? null,
|
|
213
|
+
rateBps: input.rateBps,
|
|
214
|
+
appliesToShipping: input.appliesToShipping ?? true,
|
|
215
|
+
priority: input.priority ?? 100,
|
|
216
|
+
isActive: input.isActive ?? true,
|
|
217
|
+
}, ctx);
|
|
218
|
+
return Ok(rate);
|
|
219
|
+
}
|
|
220
|
+
async listTaxRates(actor, ctx) {
|
|
221
|
+
const repo = this.requireRepository();
|
|
222
|
+
if (!repo.ok)
|
|
223
|
+
return repo;
|
|
224
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
225
|
+
return Ok(await repo.value.findAll(orgId, ctx));
|
|
226
|
+
}
|
|
227
|
+
async updateTaxRate(id, patch, actor, ctx) {
|
|
228
|
+
const repo = this.requireRepository();
|
|
229
|
+
if (!repo.ok)
|
|
230
|
+
return repo;
|
|
231
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
232
|
+
const existing = await repo.value.findById(orgId, id, ctx);
|
|
233
|
+
if (!existing)
|
|
234
|
+
return Err(new CommerceNotFoundError("Tax rate not found."));
|
|
235
|
+
const updated = await repo.value.update(id, {
|
|
236
|
+
...(patch.name !== undefined ? { name: patch.name } : {}),
|
|
237
|
+
...(patch.country !== undefined ? { country: patch.country.toUpperCase() } : {}),
|
|
238
|
+
...(patch.state !== undefined ? { state: patch.state?.toUpperCase() ?? null } : {}),
|
|
239
|
+
...(patch.rateBps !== undefined ? { rateBps: patch.rateBps } : {}),
|
|
240
|
+
...(patch.appliesToShipping !== undefined
|
|
241
|
+
? { appliesToShipping: patch.appliesToShipping }
|
|
242
|
+
: {}),
|
|
243
|
+
...(patch.priority !== undefined ? { priority: patch.priority } : {}),
|
|
244
|
+
...(patch.isActive !== undefined ? { isActive: patch.isActive } : {}),
|
|
245
|
+
}, ctx);
|
|
246
|
+
return Ok(updated);
|
|
247
|
+
}
|
|
248
|
+
async deleteTaxRate(id, actor, ctx) {
|
|
249
|
+
const repo = this.requireRepository();
|
|
250
|
+
if (!repo.ok)
|
|
251
|
+
return repo;
|
|
252
|
+
const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);
|
|
253
|
+
const existing = await repo.value.findById(orgId, id, ctx);
|
|
254
|
+
if (!existing)
|
|
255
|
+
return Err(new CommerceNotFoundError("Tax rate not found."));
|
|
256
|
+
await repo.value.delete(id, ctx);
|
|
257
|
+
return Ok({ deleted: true });
|
|
258
|
+
}
|
|
34
259
|
}
|
|
@@ -179,6 +179,13 @@ export declare const KERNEL_ALL_MODULES: {
|
|
|
179
179
|
dialect: "pg";
|
|
180
180
|
}>;
|
|
181
181
|
}, import("../index.js").AuditService, Record<string, unknown>>;
|
|
182
|
+
readonly settings: AppModule<{
|
|
183
|
+
storeSettings: typeof import("../modules/settings/schema.js").storeSettings;
|
|
184
|
+
}, import("../modules/settings/service.js").SettingsService, Record<string, never>>;
|
|
185
|
+
readonly documents: AppModule<{
|
|
186
|
+
invoiceSequences: typeof import("../modules/documents/schema.js").invoiceSequences;
|
|
187
|
+
orderDocuments: typeof import("../modules/documents/schema.js").orderDocuments;
|
|
188
|
+
}, import("../modules/documents/service.js").DocumentsService, Record<string, never>>;
|
|
182
189
|
readonly webhooks: AppModule<{
|
|
183
190
|
webhookEndpoints: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
184
191
|
name: "webhook_endpoints";
|
|
@@ -1701,10 +1708,16 @@ export declare const KERNEL_ALL_MODULES: {
|
|
|
1701
1708
|
readonly search: AppModule<Record<string, never>, import("../modules/search/service.js").SearchService, {
|
|
1702
1709
|
catalog: import("../modules/catalog/service.js").CatalogServiceImpl;
|
|
1703
1710
|
}>;
|
|
1704
|
-
readonly shipping: AppModule<
|
|
1711
|
+
readonly shipping: AppModule<{
|
|
1712
|
+
shippingZones: typeof import("../modules/shipping/schema.js").shippingZones;
|
|
1713
|
+
shippingRates: typeof import("../modules/shipping/schema.js").shippingRates;
|
|
1714
|
+
}, import("../modules/shipping/service.js").ShippingService, {
|
|
1705
1715
|
catalog: import("../modules/catalog/service.js").CatalogServiceImpl;
|
|
1706
1716
|
}>;
|
|
1707
|
-
readonly tax: AppModule<
|
|
1717
|
+
readonly tax: AppModule<{
|
|
1718
|
+
taxRates: typeof import("../modules/tax/schema.js").taxRates;
|
|
1719
|
+
taxClasses: typeof import("../modules/tax/schema.js").taxClasses;
|
|
1720
|
+
}, import("../modules/tax/service.js").TaxService, Record<string, never>>;
|
|
1708
1721
|
readonly payments: AppModule<Record<string, never>, import("../modules/payments/service.js").PaymentsService, Record<string, never>>;
|
|
1709
1722
|
readonly analytics: AppModule<Record<string, never>, import("../modules/analytics/service.js").AnalyticsService, Record<string, never>>;
|
|
1710
1723
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kernel-modules.d.ts","sourceRoot":"","sources":["../../src/runtime/kernel-modules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"kernel-modules.d.ts","sourceRoot":"","sources":["../../src/runtime/kernel-modules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsB3D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoBrB,CAAC;AAEX,2FAA2F;AAC3F,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAoBpE;AAED,wBAAgB,8BAA8B,IAAI,SAAS,MAAM,EAAE,CAElE"}
|
|
@@ -4,6 +4,7 @@ import { analyticsModule } from "../modules/analytics/module.js";
|
|
|
4
4
|
import { cartModule } from "../modules/cart/module.js";
|
|
5
5
|
import { catalogModule } from "../modules/catalog/module.js";
|
|
6
6
|
import { customersModule } from "../modules/customers/index.js";
|
|
7
|
+
import { documentsModule } from "../modules/documents/module.js";
|
|
7
8
|
import { fulfillmentModule } from "../modules/fulfillment/module.js";
|
|
8
9
|
import { inventoryModule } from "../modules/inventory/module.js";
|
|
9
10
|
import { mediaModule } from "../modules/media/index.js";
|
|
@@ -13,11 +14,14 @@ import { paymentsModule } from "../modules/payments/module.js";
|
|
|
13
14
|
import { pricingModule } from "../modules/pricing/index.js";
|
|
14
15
|
import { promotionsModule } from "../modules/promotions/module.js";
|
|
15
16
|
import { searchModule } from "../modules/search/module.js";
|
|
17
|
+
import { settingsModule } from "../modules/settings/module.js";
|
|
16
18
|
import { shippingModule } from "../modules/shipping/module.js";
|
|
17
19
|
import { taxModule } from "../modules/tax/module.js";
|
|
18
20
|
import { webhooksModule } from "../modules/webhooks/index.js";
|
|
19
21
|
export const KERNEL_ALL_MODULES = {
|
|
20
22
|
audit: auditModule,
|
|
23
|
+
settings: settingsModule,
|
|
24
|
+
documents: documentsModule,
|
|
21
25
|
webhooks: webhooksModule,
|
|
22
26
|
media: mediaModule,
|
|
23
27
|
organization: organizationModule,
|
|
@@ -16,6 +16,8 @@ import { PromotionService } from "../modules/promotions/service.js";
|
|
|
16
16
|
import { TaxService } from "../modules/tax/service.js";
|
|
17
17
|
import { ShippingService } from "../modules/shipping/service.js";
|
|
18
18
|
import { SearchService } from "../modules/search/service.js";
|
|
19
|
+
import { SettingsService } from "../modules/settings/service.js";
|
|
20
|
+
import { DocumentsService } from "../modules/documents/service.js";
|
|
19
21
|
import type { AuditService } from "../modules/audit/service.js";
|
|
20
22
|
import { OrganizationService } from "../modules/organization/service.js";
|
|
21
23
|
import { createLogger } from "../utils/logger.js";
|
|
@@ -51,6 +53,8 @@ export interface Kernel {
|
|
|
51
53
|
tax: TaxService;
|
|
52
54
|
shipping: ShippingService;
|
|
53
55
|
search: SearchService;
|
|
56
|
+
settings: SettingsService;
|
|
57
|
+
documents: DocumentsService;
|
|
54
58
|
audit: AuditService;
|
|
55
59
|
compensationFailures: CompensationFailuresRepository;
|
|
56
60
|
email: CommerceConfig["email"];
|
|
@@ -59,7 +63,7 @@ export interface Kernel {
|
|
|
59
63
|
pluginPermissions: PluginPermission[];
|
|
60
64
|
logger: ReturnType<typeof createLogger>;
|
|
61
65
|
}
|
|
62
|
-
export declare const KERNEL_REQUIRED_SERVICE_KEYS: ["catalog", "inventory", "media", "cart", "orders", "payments", "fulfillment", "customers", "webhooks", "analytics", "pricing", "promotions", "tax", "shipping", "search", "audit", "compensationFailures"];
|
|
66
|
+
export declare const KERNEL_REQUIRED_SERVICE_KEYS: ["catalog", "inventory", "media", "cart", "orders", "payments", "fulfillment", "customers", "webhooks", "analytics", "pricing", "promotions", "tax", "shipping", "search", "settings", "documents", "audit", "compensationFailures"];
|
|
63
67
|
export declare function assertKernelServicesReady(services: Partial<Kernel["services"]>): asserts services is Kernel["services"];
|
|
64
68
|
export declare function assertSortedBefore(topo: readonly string[], a: string, b: string): void;
|
|
65
69
|
//# sourceMappingURL=kernel-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kernel-types.d.ts","sourceRoot":"","sources":["../../src/runtime/kernel-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"kernel-types.d.ts","sourceRoot":"","sources":["../../src/runtime/kernel-types.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/server.js
CHANGED
|
@@ -281,7 +281,7 @@ export async function createServer(config) {
|
|
|
281
281
|
// body-limit stack apply (all are scoped to /api/*).
|
|
282
282
|
app.route("/api/me", createCustomerPortalRoutes(kernel));
|
|
283
283
|
if (config.routes) {
|
|
284
|
-
config.routes(app, kernel);
|
|
284
|
+
config.routes(app, kernel, auth);
|
|
285
285
|
}
|
|
286
286
|
// OpenAPI spec — disabled in production unless explicitly enabled
|
|
287
287
|
const exposeSpec = config.exposeOpenApiSpec ?? !isProd;
|
|
@@ -21,6 +21,7 @@ import type { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
|
|
|
21
21
|
import type { CommerceConfig, CommercePlugin } from "../config/types.js";
|
|
22
22
|
import type { Actor } from "../auth/types.js";
|
|
23
23
|
import type { Kernel } from "../runtime/kernel.js";
|
|
24
|
+
import { type AuthInstance } from "../auth/setup.js";
|
|
24
25
|
/**
|
|
25
26
|
* Hono environment type for the test app. Declares the `actor` context
|
|
26
27
|
* variable so c.set("actor", ...) / c.get("actor") are properly typed
|
|
@@ -38,6 +39,8 @@ export interface PluginTestApp {
|
|
|
38
39
|
kernel: Kernel;
|
|
39
40
|
/** Drizzle database instance for direct queries in test assertions. */
|
|
40
41
|
db: PgDatabase<PgQueryResultHKT, Record<string, unknown>>;
|
|
42
|
+
/** The Better Auth instance passed to plugin routes (mint/verify API keys in tests). */
|
|
43
|
+
auth: AuthInstance;
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Creates a fully-wired test application for plugin E2E testing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-plugin-test-app.d.ts","sourceRoot":"","sources":["../../src/test-utils/create-plugin-test-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-plugin-test-app.d.ts","sourceRoot":"","sources":["../../src/test-utils/create-plugin-test-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnD,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAajE;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE;QACT,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;KACrB,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAC7B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,EAAE,EAAE,UAAU,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,wFAAwF;IACxF,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,eAAe,GAAE,OAAO,CAAC,cAAc,CAAM,GAC5C,OAAO,CAAC,aAAa,CAAC,CAyFxB"}
|
|
@@ -24,6 +24,8 @@ import { buildSchema } from "../kernel/database/migrate.js";
|
|
|
24
24
|
import { unwrapDb } from "../kernel/database/adapter.js";
|
|
25
25
|
import { ensureDefaultOrg } from "../auth/org.js";
|
|
26
26
|
import { mapErrorToStatus } from "../kernel/error-mapper.js";
|
|
27
|
+
import { createAuth } from "../auth/setup.js";
|
|
28
|
+
import { authMiddleware } from "../auth/middleware.js";
|
|
27
29
|
// drizzle-kit/api uses CJS internally; createRequire provides ESM compat.
|
|
28
30
|
const require = createRequire(import.meta.url);
|
|
29
31
|
/**
|
|
@@ -56,7 +58,10 @@ export async function createPluginTestApp(plugin, configOverrides = {}) {
|
|
|
56
58
|
// 5. Create OpenAPIHono --- matching production server.ts
|
|
57
59
|
// Plugin routes register via manifest.ts which calls app.openapi().
|
|
58
60
|
const app = new OpenAPIHono();
|
|
59
|
-
|
|
61
|
+
const auth = createAuth(kernel.database, config);
|
|
62
|
+
// 6. Test actor middleware: parse x-test-actor header -> set on context.
|
|
63
|
+
// Requests without the header fall through to the real auth middleware,
|
|
64
|
+
// so API keys minted by plugins (issue #51) authenticate like production.
|
|
60
65
|
app.use("*", async (c, next) => {
|
|
61
66
|
const header = c.req.header("x-test-actor");
|
|
62
67
|
if (header) {
|
|
@@ -67,9 +72,15 @@ export async function createPluginTestApp(plugin, configOverrides = {}) {
|
|
|
67
72
|
}
|
|
68
73
|
await next();
|
|
69
74
|
});
|
|
70
|
-
|
|
75
|
+
app.use("*", async (c, next) => {
|
|
76
|
+
if (c.get("actor"))
|
|
77
|
+
return next();
|
|
78
|
+
return authMiddleware(auth, config)(c, next);
|
|
79
|
+
});
|
|
80
|
+
// 7. Register plugin routes (deferred via config.routes) — with the auth
|
|
81
|
+
// instance, matching server.ts's config.routes(app, kernel, auth).
|
|
71
82
|
const routes = config.routes;
|
|
72
|
-
routes?.(app, kernel);
|
|
83
|
+
routes?.(app, kernel, auth);
|
|
73
84
|
// 8. Error handler matching production server.ts — maps CommerceError
|
|
74
85
|
// subclasses (CommerceForbiddenError, CommerceNotFoundError, etc.)
|
|
75
86
|
// to their proper HTTP status codes (403, 404, 409, 422, 503).
|
|
@@ -89,5 +100,6 @@ export async function createPluginTestApp(plugin, configOverrides = {}) {
|
|
|
89
100
|
app,
|
|
90
101
|
kernel,
|
|
91
102
|
db: kernel.database.db,
|
|
103
|
+
auth,
|
|
92
104
|
};
|
|
93
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-test-config.d.ts","sourceRoot":"","sources":["../../src/test-utils/create-test-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAgDzD,wBAAsB,gBAAgB,CACpC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"create-test-config.d.ts","sourceRoot":"","sources":["../../src/test-utils/create-test-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAgDzD,wBAAsB,gBAAgB,CACpC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,OAAO,CAAC,cAAc,CAAC,CAiHzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAUnE"}
|
|
@@ -53,6 +53,7 @@ export async function createTestConfig(overrides = {}) {
|
|
|
53
53
|
provider: "postgresql",
|
|
54
54
|
},
|
|
55
55
|
auth: {
|
|
56
|
+
allowTestActor: true,
|
|
56
57
|
defaultOrganizationId: "org_default",
|
|
57
58
|
requireEmailVerification: false,
|
|
58
59
|
apiKeys: { enabled: true, defaultPermissions: ["catalog:read"] },
|
|
@@ -70,6 +71,7 @@ export async function createTestConfig(overrides = {}) {
|
|
|
70
71
|
"orders:create",
|
|
71
72
|
"orders:read",
|
|
72
73
|
"orders:update",
|
|
74
|
+
"orders:manage",
|
|
73
75
|
"cart:create",
|
|
74
76
|
"cart:update",
|
|
75
77
|
"customers:update:self",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Kernel } from "../runtime/kernel.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mark an order as paid (captured) for tests.
|
|
4
|
+
*
|
|
5
|
+
* Refund and return flows require a paid order — a refund moves collected money,
|
|
6
|
+
* and the order primitive rejects refunds on unpaid/pending orders. There is no
|
|
7
|
+
* public "set captured amount" service (capture() needs a live payment intent),
|
|
8
|
+
* so tests set the column here through a single typed helper rather than
|
|
9
|
+
* scattering raw SQL / `as any` casts across test files.
|
|
10
|
+
*/
|
|
11
|
+
export declare function markOrderPaidForTest(kernel: Kernel, orderId: string, amountCaptured: number, paymentIntentId?: string): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=order-test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-test-helpers.d.ts","sourceRoot":"","sources":["../../src/test-utils/order-test-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { eq } from "drizzle-orm";
|
|
2
|
+
import { orders } from "../modules/orders/schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* Mark an order as paid (captured) for tests.
|
|
5
|
+
*
|
|
6
|
+
* Refund and return flows require a paid order — a refund moves collected money,
|
|
7
|
+
* and the order primitive rejects refunds on unpaid/pending orders. There is no
|
|
8
|
+
* public "set captured amount" service (capture() needs a live payment intent),
|
|
9
|
+
* so tests set the column here through a single typed helper rather than
|
|
10
|
+
* scattering raw SQL / `as any` casts across test files.
|
|
11
|
+
*/
|
|
12
|
+
export async function markOrderPaidForTest(kernel, orderId, amountCaptured, paymentIntentId) {
|
|
13
|
+
const db = kernel.database.db;
|
|
14
|
+
await db
|
|
15
|
+
.update(orders)
|
|
16
|
+
.set({ amountCaptured, ...(paymentIntentId ? { paymentIntentId } : {}) })
|
|
17
|
+
.where(eq(orders.id, orderId));
|
|
18
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-api-test-utils.d.ts","sourceRoot":"","sources":["../../src/test-utils/rest-api-test-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAOpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,KAAK,SAAS,GAAG;IACf,SAAS,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;KACrB,CAAC;CACH,CAAC;AAiDF;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,OAAO,CAAC;IACT,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACxC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC,CAqDD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAEnF;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"rest-api-test-utils.d.ts","sourceRoot":"","sources":["../../src/test-utils/rest-api-test-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAOpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,KAAK,SAAS,GAAG;IACf,SAAS,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;KACrB,CAAC;CACH,CAAC;AAiDF;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,OAAO,CAAC;IACT,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACxC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC,CAqDD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAEnF;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAoCvB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KASzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,WAwBA;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EACvB,OAAO,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,qBAYF"}
|
|
@@ -130,12 +130,19 @@ export const testActor = {
|
|
|
130
130
|
"orders:create",
|
|
131
131
|
"orders:read",
|
|
132
132
|
"orders:update",
|
|
133
|
+
"orders:manage",
|
|
133
134
|
"cart:create",
|
|
134
135
|
"cart:update",
|
|
135
136
|
"cart:read",
|
|
137
|
+
"cart:manage",
|
|
136
138
|
"customers:update:self",
|
|
137
139
|
"webhooks:manage",
|
|
138
140
|
"pricing:manage",
|
|
141
|
+
"shipping:manage",
|
|
142
|
+
"tax:manage",
|
|
143
|
+
"settings:manage",
|
|
144
|
+
"analytics:read",
|
|
145
|
+
"staff:manage",
|
|
139
146
|
"promotions:manage",
|
|
140
147
|
"promotions:read",
|
|
141
148
|
"audit:read",
|
|
@@ -28,7 +28,7 @@ export const testStaffActor = {
|
|
|
28
28
|
role: "staff",
|
|
29
29
|
permissions: [
|
|
30
30
|
"catalog:read", "catalog:create", "catalog:update",
|
|
31
|
-
"inventory:adjust", "orders:read", "orders:create", "orders:update",
|
|
31
|
+
"inventory:adjust", "orders:read", "orders:create", "orders:update", "orders:manage",
|
|
32
32
|
],
|
|
33
33
|
};
|
|
34
34
|
/** Customer with minimal read/write-own permissions. */
|
package/dist/testing.d.ts
CHANGED
|
@@ -11,5 +11,6 @@ export { createRepositoryTestHarness } from "./test-utils/create-repository-test
|
|
|
11
11
|
export { createPluginTestApp, type PluginTestApp, type TestAppEnv } from "./test-utils/create-plugin-test-app.js";
|
|
12
12
|
export { TEST_ORG_ID, testAdminActor, testStaffActor, testCustomerActor, testNoPermActor, jsonHeaders, } from "./test-utils/test-actors.js";
|
|
13
13
|
export { beforeHook, afterHook } from "./test-utils/typed-hooks.js";
|
|
14
|
+
export { markOrderPaidForTest } from "./test-utils/order-test-helpers.js";
|
|
14
15
|
export type { Actor } from "./auth/types.js";
|
|
15
16
|
//# sourceMappingURL=testing.d.ts.map
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAClH,OAAO,EACL,WAAW,EACX,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAClE,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAClH,OAAO,EACL,WAAW,EACX,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAClE,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/testing.js
CHANGED
|
@@ -11,3 +11,4 @@ export { createRepositoryTestHarness } from "./test-utils/create-repository-test
|
|
|
11
11
|
export { createPluginTestApp } from "./test-utils/create-plugin-test-app.js";
|
|
12
12
|
export { TEST_ORG_ID, testAdminActor, testStaffActor, testCustomerActor, testNoPermActor, jsonHeaders, } from "./test-utils/test-actors.js";
|
|
13
13
|
export { beforeHook, afterHook } from "./test-utils/typed-hooks.js";
|
|
14
|
+
export { markOrderPaidForTest } from "./test-utils/order-test-helpers.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@porulle/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"eslint": "^9.39.1",
|
|
57
57
|
"typescript": "5.9.2",
|
|
58
58
|
"vitest": "^3.2.4",
|
|
59
|
-
"@porulle/
|
|
60
|
-
"@porulle/
|
|
59
|
+
"@porulle/typescript-config": "0.1.0",
|
|
60
|
+
"@porulle/eslint-config": "0.1.0"
|
|
61
61
|
},
|
|
62
62
|
"publishConfig": {
|
|
63
63
|
"access": "public"
|