@porulle/core 0.7.0 → 0.8.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/setup.d.ts.map +1 -1
- package/dist/auth/setup.js +1 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -0
- package/dist/config/types.d.ts +17 -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.d.ts.map +1 -1
- package/dist/hooks/checkout.js +16 -1
- 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 +172 -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.map +1 -1
- package/dist/interfaces/rest/routes/checkout.js +17 -0
- 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/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/orders.js +98 -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 +233 -0
- 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 +156 -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/hooks/types.d.ts +1 -1
- package/dist/kernel/hooks/types.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.d.ts +23 -0
- package/dist/kernel/plugin/manifest.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.js +17 -2
- 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 +58 -0
- 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 +132 -3
- 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/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 +374 -0
- package/dist/modules/orders/schema.d.ts.map +1 -1
- package/dist/modules/orders/schema.js +52 -1
- package/dist/modules/orders/service.d.ts +86 -1
- package/dist/modules/orders/service.d.ts.map +1 -1
- package/dist/modules/orders/service.js +447 -20
- 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 +38 -0
- 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/rest-api-test-utils.d.ts.map +1 -1
- package/dist/test-utils/rest-api-test-utils.js +6 -0
- package/package.json +3 -3
- package/src/auth/setup.ts +1 -0
- package/src/config/defaults.ts +5 -0
- package/src/config/types.ts +17 -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.ts +25 -3
- package/src/index.ts +1 -0
- package/src/interfaces/rest/index.ts +12 -0
- package/src/interfaces/rest/routes/admin/staff.ts +218 -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 +22 -0
- package/src/interfaces/rest/routes/documents.ts +61 -0
- package/src/interfaces/rest/routes/orders.ts +137 -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 +257 -0
- 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/hooks/types.ts +1 -0
- package/src/kernel/plugin/manifest.ts +38 -2
- 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 +101 -0
- package/src/modules/catalog/entity-service.ts +168 -3
- 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/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 +54 -1
- package/src/modules/orders/service.ts +654 -22
- package/src/modules/pricing/repository/index.ts +34 -0
- package/src/modules/pricing/service.ts +71 -0
- 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/rest-api-test-utils.ts +6 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { z, createRoute } from "@hono/zod-openapi";
|
|
2
|
+
import { errorResponses } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
// ─── Request Schemas ────────────────────────────────────────────────────────
|
|
5
|
+
|
|
6
|
+
export const CreateShippingZoneBodySchema = z.object({
|
|
7
|
+
name: z.string().min(1).openapi({ example: "United States" }),
|
|
8
|
+
countries: z.array(z.string().min(1)).min(1).openapi({ example: ["US"] }),
|
|
9
|
+
states: z.array(z.string().min(1)).optional().openapi({ example: ["NY", "NJ"] }),
|
|
10
|
+
priority: z.number().int().optional(),
|
|
11
|
+
isActive: z.boolean().optional(),
|
|
12
|
+
}).openapi("CreateShippingZoneRequest");
|
|
13
|
+
|
|
14
|
+
export const UpdateShippingZoneBodySchema = z.object({
|
|
15
|
+
name: z.string().min(1).optional(),
|
|
16
|
+
countries: z.array(z.string().min(1)).min(1).optional(),
|
|
17
|
+
states: z.array(z.string().min(1)).optional(),
|
|
18
|
+
priority: z.number().int().optional(),
|
|
19
|
+
isActive: z.boolean().optional(),
|
|
20
|
+
}).openapi("UpdateShippingZoneRequest");
|
|
21
|
+
|
|
22
|
+
export const CreateShippingRateBodySchema = z.object({
|
|
23
|
+
zoneId: z.uuid(),
|
|
24
|
+
name: z.string().min(1).openapi({ example: "Standard" }),
|
|
25
|
+
amount: z.number().int().nonnegative().openapi({ example: 1500, description: "Flat cost in minor units" }),
|
|
26
|
+
currency: z.string().length(3).optional().openapi({ example: "USD" }),
|
|
27
|
+
minSubtotal: z.number().int().nonnegative().optional(),
|
|
28
|
+
maxSubtotal: z.number().int().nonnegative().optional(),
|
|
29
|
+
minWeightGrams: z.number().int().nonnegative().optional(),
|
|
30
|
+
maxWeightGrams: z.number().int().nonnegative().optional(),
|
|
31
|
+
freeShippingThreshold: z.number().int().nonnegative().optional().openapi({ example: 10000, description: "Subtotal at or above which shipping is free" }),
|
|
32
|
+
isActive: z.boolean().optional(),
|
|
33
|
+
}).openapi("CreateShippingRateRequest");
|
|
34
|
+
|
|
35
|
+
export const UpdateShippingRateBodySchema = z.object({
|
|
36
|
+
name: z.string().min(1).optional(),
|
|
37
|
+
amount: z.number().int().nonnegative().optional(),
|
|
38
|
+
currency: z.string().length(3).optional(),
|
|
39
|
+
minSubtotal: z.number().int().nonnegative().nullable().optional(),
|
|
40
|
+
maxSubtotal: z.number().int().nonnegative().nullable().optional(),
|
|
41
|
+
minWeightGrams: z.number().int().nonnegative().nullable().optional(),
|
|
42
|
+
maxWeightGrams: z.number().int().nonnegative().nullable().optional(),
|
|
43
|
+
freeShippingThreshold: z.number().int().nonnegative().nullable().optional(),
|
|
44
|
+
isActive: z.boolean().optional(),
|
|
45
|
+
}).openapi("UpdateShippingRateRequest");
|
|
46
|
+
|
|
47
|
+
// ─── Shared ─────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
const IdParam = z.object({
|
|
50
|
+
id: z.uuid().openapi({ example: "550e8400-e29b-41d4-a716-446655440000" }),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const DataResponse = z.object({ data: z.any() }).openapi("ShippingConfigResponse");
|
|
54
|
+
|
|
55
|
+
// ─── Zone Routes ────────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
export const createShippingZoneRoute = createRoute({
|
|
58
|
+
method: "post",
|
|
59
|
+
path: "/zones",
|
|
60
|
+
tags: ["Shipping"],
|
|
61
|
+
summary: "Create a shipping zone",
|
|
62
|
+
request: {
|
|
63
|
+
body: { content: { "application/json": { schema: CreateShippingZoneBodySchema } }, required: true },
|
|
64
|
+
},
|
|
65
|
+
responses: {
|
|
66
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Zone created." },
|
|
67
|
+
...errorResponses,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const listShippingZonesRoute = createRoute({
|
|
72
|
+
method: "get",
|
|
73
|
+
path: "/zones",
|
|
74
|
+
tags: ["Shipping"],
|
|
75
|
+
summary: "List shipping zones",
|
|
76
|
+
responses: {
|
|
77
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Zones" },
|
|
78
|
+
...errorResponses,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const updateShippingZoneRoute = createRoute({
|
|
83
|
+
method: "patch",
|
|
84
|
+
path: "/zones/{id}",
|
|
85
|
+
tags: ["Shipping"],
|
|
86
|
+
summary: "Update a shipping zone",
|
|
87
|
+
request: {
|
|
88
|
+
params: IdParam,
|
|
89
|
+
body: { content: { "application/json": { schema: UpdateShippingZoneBodySchema } }, required: true },
|
|
90
|
+
},
|
|
91
|
+
responses: {
|
|
92
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Zone updated." },
|
|
93
|
+
...errorResponses,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export const deleteShippingZoneRoute = createRoute({
|
|
98
|
+
method: "delete",
|
|
99
|
+
path: "/zones/{id}",
|
|
100
|
+
tags: ["Shipping"],
|
|
101
|
+
summary: "Delete a shipping zone (and its rates)",
|
|
102
|
+
request: { params: IdParam },
|
|
103
|
+
responses: {
|
|
104
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Zone deleted." },
|
|
105
|
+
...errorResponses,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// ─── Rate Routes ────────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
export const createShippingRateRoute = createRoute({
|
|
112
|
+
method: "post",
|
|
113
|
+
path: "/rates",
|
|
114
|
+
tags: ["Shipping"],
|
|
115
|
+
summary: "Create a shipping rate in a zone",
|
|
116
|
+
request: {
|
|
117
|
+
body: { content: { "application/json": { schema: CreateShippingRateBodySchema } }, required: true },
|
|
118
|
+
},
|
|
119
|
+
responses: {
|
|
120
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Rate created." },
|
|
121
|
+
...errorResponses,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
export const listShippingRatesRoute = createRoute({
|
|
126
|
+
method: "get",
|
|
127
|
+
path: "/rates",
|
|
128
|
+
tags: ["Shipping"],
|
|
129
|
+
summary: "List shipping rates",
|
|
130
|
+
request: {
|
|
131
|
+
query: z.object({ zoneId: z.string().optional() }),
|
|
132
|
+
},
|
|
133
|
+
responses: {
|
|
134
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Rates" },
|
|
135
|
+
...errorResponses,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
export const updateShippingRateRoute = createRoute({
|
|
140
|
+
method: "patch",
|
|
141
|
+
path: "/rates/{id}",
|
|
142
|
+
tags: ["Shipping"],
|
|
143
|
+
summary: "Update a shipping rate",
|
|
144
|
+
request: {
|
|
145
|
+
params: IdParam,
|
|
146
|
+
body: { content: { "application/json": { schema: UpdateShippingRateBodySchema } }, required: true },
|
|
147
|
+
},
|
|
148
|
+
responses: {
|
|
149
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Rate updated." },
|
|
150
|
+
...errorResponses,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
export const deleteShippingRateRoute = createRoute({
|
|
155
|
+
method: "delete",
|
|
156
|
+
path: "/rates/{id}",
|
|
157
|
+
tags: ["Shipping"],
|
|
158
|
+
summary: "Delete a shipping rate",
|
|
159
|
+
request: { params: IdParam },
|
|
160
|
+
responses: {
|
|
161
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Rate deleted." },
|
|
162
|
+
...errorResponses,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { z, createRoute } from "@hono/zod-openapi";
|
|
2
|
+
import { errorResponses } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
export const CreateTaxRateBodySchema = z.object({
|
|
5
|
+
name: z.string().min(1).openapi({ example: "NY sales tax" }),
|
|
6
|
+
country: z.string().min(1).openapi({ example: "US", description: "ISO 3166-1 alpha-2; \"*\" matches any country" }),
|
|
7
|
+
state: z.string().min(1).optional().openapi({ example: "NY" }),
|
|
8
|
+
rateBps: z.number().int().nonnegative().openapi({ example: 500, description: "Basis points: 500 = 5%" }),
|
|
9
|
+
appliesToShipping: z.boolean().optional(),
|
|
10
|
+
priority: z.number().int().optional(),
|
|
11
|
+
isActive: z.boolean().optional(),
|
|
12
|
+
}).openapi("CreateTaxRateRequest");
|
|
13
|
+
|
|
14
|
+
export const UpdateTaxRateBodySchema = z.object({
|
|
15
|
+
name: z.string().min(1).optional(),
|
|
16
|
+
country: z.string().min(1).optional(),
|
|
17
|
+
state: z.string().min(1).nullable().optional(),
|
|
18
|
+
rateBps: z.number().int().nonnegative().optional(),
|
|
19
|
+
appliesToShipping: z.boolean().optional(),
|
|
20
|
+
priority: z.number().int().optional(),
|
|
21
|
+
isActive: z.boolean().optional(),
|
|
22
|
+
}).openapi("UpdateTaxRateRequest");
|
|
23
|
+
|
|
24
|
+
const IdParam = z.object({
|
|
25
|
+
id: z.uuid().openapi({ example: "550e8400-e29b-41d4-a716-446655440000" }),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const DataResponse = z.object({ data: z.any() }).openapi("TaxConfigResponse");
|
|
29
|
+
|
|
30
|
+
export const createTaxRateRoute = createRoute({
|
|
31
|
+
method: "post",
|
|
32
|
+
path: "/rates",
|
|
33
|
+
tags: ["Tax"],
|
|
34
|
+
summary: "Create a tax rate",
|
|
35
|
+
request: {
|
|
36
|
+
body: { content: { "application/json": { schema: CreateTaxRateBodySchema } }, required: true },
|
|
37
|
+
},
|
|
38
|
+
responses: {
|
|
39
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate created." },
|
|
40
|
+
...errorResponses,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const listTaxRatesRoute = createRoute({
|
|
45
|
+
method: "get",
|
|
46
|
+
path: "/rates",
|
|
47
|
+
tags: ["Tax"],
|
|
48
|
+
summary: "List tax rates",
|
|
49
|
+
responses: {
|
|
50
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rates" },
|
|
51
|
+
...errorResponses,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const updateTaxRateRoute = createRoute({
|
|
56
|
+
method: "patch",
|
|
57
|
+
path: "/rates/{id}",
|
|
58
|
+
tags: ["Tax"],
|
|
59
|
+
summary: "Update a tax rate",
|
|
60
|
+
request: {
|
|
61
|
+
params: IdParam,
|
|
62
|
+
body: { content: { "application/json": { schema: UpdateTaxRateBodySchema } }, required: true },
|
|
63
|
+
},
|
|
64
|
+
responses: {
|
|
65
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate updated." },
|
|
66
|
+
...errorResponses,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const deleteTaxRateRoute = createRoute({
|
|
71
|
+
method: "delete",
|
|
72
|
+
path: "/rates/{id}",
|
|
73
|
+
tags: ["Tax"],
|
|
74
|
+
summary: "Delete a tax rate",
|
|
75
|
+
request: { params: IdParam },
|
|
76
|
+
responses: {
|
|
77
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate deleted." },
|
|
78
|
+
...errorResponses,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// ── Product tax classes (issue #57) ─────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
export const CreateTaxClassBodySchema = z.object({
|
|
85
|
+
name: z.string().min(1).regex(/^[a-z][a-z0-9_-]*$/, "lowercase slug (e.g. standard, zero)"),
|
|
86
|
+
rateBps: z.number().int().nonnegative().openapi({ example: 1800, description: "Basis points: 1800 = 18%" }),
|
|
87
|
+
isDefault: z.boolean().optional().openapi({ description: "Lines with no taxClass use the default class." }),
|
|
88
|
+
isActive: z.boolean().optional(),
|
|
89
|
+
}).openapi("CreateTaxClassRequest");
|
|
90
|
+
|
|
91
|
+
export const UpdateTaxClassBodySchema = z.object({
|
|
92
|
+
name: z.string().min(1).regex(/^[a-z][a-z0-9_-]*$/).optional(),
|
|
93
|
+
rateBps: z.number().int().nonnegative().optional(),
|
|
94
|
+
isDefault: z.boolean().optional(),
|
|
95
|
+
isActive: z.boolean().optional(),
|
|
96
|
+
}).openapi("UpdateTaxClassRequest");
|
|
97
|
+
|
|
98
|
+
const ClassIdParam = z.object({ id: z.uuid() });
|
|
99
|
+
|
|
100
|
+
export const createTaxClassRoute = createRoute({
|
|
101
|
+
method: "post",
|
|
102
|
+
path: "/classes",
|
|
103
|
+
tags: ["Tax"],
|
|
104
|
+
summary: "Create a product tax class",
|
|
105
|
+
request: { body: { content: { "application/json": { schema: CreateTaxClassBodySchema } }, required: true } },
|
|
106
|
+
responses: {
|
|
107
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Tax class created." },
|
|
108
|
+
...errorResponses,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const listTaxClassesRoute = createRoute({
|
|
113
|
+
method: "get",
|
|
114
|
+
path: "/classes",
|
|
115
|
+
tags: ["Tax"],
|
|
116
|
+
summary: "List product tax classes",
|
|
117
|
+
responses: {
|
|
118
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax classes." },
|
|
119
|
+
...errorResponses,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
export const updateTaxClassRoute = createRoute({
|
|
124
|
+
method: "patch",
|
|
125
|
+
path: "/classes/{id}",
|
|
126
|
+
tags: ["Tax"],
|
|
127
|
+
summary: "Update a product tax class",
|
|
128
|
+
request: {
|
|
129
|
+
params: ClassIdParam,
|
|
130
|
+
body: { content: { "application/json": { schema: UpdateTaxClassBodySchema } }, required: true },
|
|
131
|
+
},
|
|
132
|
+
responses: {
|
|
133
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax class updated." },
|
|
134
|
+
...errorResponses,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export const deleteTaxClassRoute = createRoute({
|
|
139
|
+
method: "delete",
|
|
140
|
+
path: "/classes/{id}",
|
|
141
|
+
tags: ["Tax"],
|
|
142
|
+
summary: "Delete a product tax class",
|
|
143
|
+
request: { params: ClassIdParam },
|
|
144
|
+
responses: {
|
|
145
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Tax class deleted." },
|
|
146
|
+
...errorResponses,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
@@ -43,6 +43,18 @@ export * from "../../modules/webhooks/schema.js";
|
|
|
43
43
|
// Fulfillment module
|
|
44
44
|
export * from "../../modules/fulfillment/schema.js";
|
|
45
45
|
|
|
46
|
+
// Shipping module (runtime zones & rates)
|
|
47
|
+
export * from "../../modules/shipping/schema.js";
|
|
48
|
+
|
|
49
|
+
// Tax module (runtime tax rates)
|
|
50
|
+
export * from "../../modules/tax/schema.js";
|
|
51
|
+
|
|
52
|
+
// Settings module (org-scoped runtime settings)
|
|
53
|
+
export * from "../../modules/settings/schema.js";
|
|
54
|
+
|
|
55
|
+
// Documents module (fiscal sequences + issued documents)
|
|
56
|
+
export * from "../../modules/documents/schema.js";
|
|
57
|
+
|
|
46
58
|
// Jobs (kernel)
|
|
47
59
|
export * from "../jobs/schema.js";
|
|
48
60
|
|
|
@@ -59,6 +59,14 @@ export interface PluginContext {
|
|
|
59
59
|
transaction<T>(fn: (tx: PluginDb) => Promise<T>): Promise<T>;
|
|
60
60
|
};
|
|
61
61
|
logger: PluginLogger;
|
|
62
|
+
/**
|
|
63
|
+
* The Better Auth instance (issue #51) — lets plugins mint/revoke
|
|
64
|
+
* credentials (e.g. per-shift API keys from a POS PIN login). Present when
|
|
65
|
+
* routes are mounted by createServer; may be absent in bare-kernel setups,
|
|
66
|
+
* so plugins must degrade gracefully. Typed loosely to avoid coupling every
|
|
67
|
+
* plugin to Better Auth's generics — cast to the narrow surface you use.
|
|
68
|
+
*/
|
|
69
|
+
auth?: unknown;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
const UNSCOPED_WARN_COOLDOWN_MS = 60_000;
|
|
@@ -139,6 +147,18 @@ export interface CommercePluginManifest {
|
|
|
139
147
|
hooks?: () => PluginHookRegistration[];
|
|
140
148
|
routes?: (ctx: PluginContext) => PluginRouteRegistration[];
|
|
141
149
|
analyticsModels?: () => unknown[];
|
|
150
|
+
/**
|
|
151
|
+
* Named API-key scopes this plugin mints credentials under (issue #51),
|
|
152
|
+
* merged into `config.auth.apiKeyScopes`. User-defined scopes with the
|
|
153
|
+
* same name win.
|
|
154
|
+
*/
|
|
155
|
+
apiKeyScopes?: () => Record<string, {
|
|
156
|
+
prefix?: string;
|
|
157
|
+
description?: string;
|
|
158
|
+
permissions?: Record<string, string[]>;
|
|
159
|
+
/** Expiry bounds in DAYS (fractions allowed — 1/24 = one hour). */
|
|
160
|
+
keyExpiration?: { minExpiresIn?: number; maxExpiresIn?: number };
|
|
161
|
+
}>;
|
|
142
162
|
}
|
|
143
163
|
|
|
144
164
|
// ─── Plugin Dependency Tracking ──────────────────────────────────────
|
|
@@ -193,6 +213,21 @@ export function defineCommercePlugin(
|
|
|
193
213
|
};
|
|
194
214
|
}
|
|
195
215
|
|
|
216
|
+
// 0. API-key scopes — merge into auth.apiKeyScopes (user config wins)
|
|
217
|
+
if (manifest.apiKeyScopes) {
|
|
218
|
+
const scopes = manifest.apiKeyScopes();
|
|
219
|
+
result = {
|
|
220
|
+
...result,
|
|
221
|
+
auth: {
|
|
222
|
+
...(result.auth ?? {}),
|
|
223
|
+
apiKeyScopes: {
|
|
224
|
+
...scopes,
|
|
225
|
+
...(result.auth?.apiKeyScopes ?? {}),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
} as CommerceConfig;
|
|
229
|
+
}
|
|
230
|
+
|
|
196
231
|
// 1. Schema — push into customSchemas for kernel to register
|
|
197
232
|
if (manifest.schema) {
|
|
198
233
|
const schemas = manifest.schema();
|
|
@@ -220,8 +255,8 @@ export function defineCommercePlugin(
|
|
|
220
255
|
const pluginRoutes = manifest.routes;
|
|
221
256
|
result = {
|
|
222
257
|
...result,
|
|
223
|
-
routes: (app: Hono, kernel: Kernel) => {
|
|
224
|
-
existingRoutes?.(app, kernel);
|
|
258
|
+
routes: (app: Hono, kernel: Kernel, auth?: unknown) => {
|
|
259
|
+
existingRoutes?.(app, kernel, auth as never);
|
|
225
260
|
const k = kernel as {
|
|
226
261
|
config: CommerceConfig;
|
|
227
262
|
services: Record<string, unknown>;
|
|
@@ -240,6 +275,7 @@ export function defineCommercePlugin(
|
|
|
240
275
|
k.logger,
|
|
241
276
|
),
|
|
242
277
|
logger: k.logger,
|
|
278
|
+
...(auth !== undefined ? { auth } : {}),
|
|
243
279
|
});
|
|
244
280
|
for (const route of regs) {
|
|
245
281
|
// ── Error boundary: wrap handler with plugin context ──
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { CommerceConfig } from "../../config/types.js";
|
|
2
2
|
import type { DrizzleDatabase } from "../../kernel/database/drizzle-db.js";
|
|
3
3
|
import { defineModule } from "../../kernel/module/index.js";
|
|
4
|
+
import type { SettingsService } from "../settings/service.js";
|
|
4
5
|
import { DrizzleAnalyticsAdapter } from "./drizzle-adapter.js";
|
|
5
6
|
import { BUILTIN_ANALYTICS_MODELS } from "./models.js";
|
|
7
|
+
import { RetailReportsEngine } from "./reports.js";
|
|
6
8
|
import { AnalyticsService } from "./service.js";
|
|
7
9
|
|
|
8
10
|
export const analyticsModule = defineModule<
|
|
@@ -17,9 +19,17 @@ export const analyticsModule = defineModule<
|
|
|
17
19
|
for (const model of BUILTIN_ANALYTICS_MODELS) {
|
|
18
20
|
adapter.registerModel(model);
|
|
19
21
|
}
|
|
22
|
+
// Settings is resolved lazily from the shared service container — the
|
|
23
|
+
// settings module may instantiate after analytics.
|
|
24
|
+
const services = deps.services as Record<string, unknown>;
|
|
25
|
+
const reports = new RetailReportsEngine(
|
|
26
|
+
deps.db.db as DrizzleDatabase,
|
|
27
|
+
(orgId, group) => (services.settings as SettingsService).read(orgId, group),
|
|
28
|
+
);
|
|
20
29
|
return new AnalyticsService({
|
|
21
30
|
adapter,
|
|
22
31
|
config: deps.config as CommerceConfig,
|
|
32
|
+
reports,
|
|
23
33
|
});
|
|
24
34
|
},
|
|
25
35
|
});
|