includio-cms 0.36.9 → 0.37.1
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/API.md +178 -3
- package/CHANGELOG.md +77 -0
- package/DOCS.md +28 -3
- package/ROADMAP.md +32 -0
- package/dist/admin/client/booking/booking-dashboard.svelte +40 -0
- package/dist/admin/client/booking/booking-dashboard.svelte.d.ts +3 -0
- package/dist/admin/client/booking/customer-panel.svelte +102 -0
- package/dist/admin/client/booking/customer-panel.svelte.d.ts +11 -0
- package/dist/admin/client/booking/customer-view.d.ts +52 -0
- package/dist/admin/client/booking/customer-view.js +134 -0
- package/dist/admin/client/booking/participant-data-panel.svelte +330 -0
- package/dist/admin/client/booking/participant-data-panel.svelte.d.ts +22 -0
- package/dist/admin/client/booking/reservation-detail-page.svelte +637 -0
- package/dist/admin/client/booking/reservation-detail-page.svelte.d.ts +3 -0
- package/dist/admin/client/booking/reservations-page.svelte +221 -0
- package/dist/admin/client/booking/reservations-page.svelte.d.ts +3 -0
- package/dist/admin/client/collection/collection-entries.svelte +1 -1
- package/dist/admin/client/collection/entry-link.svelte +6 -4
- package/dist/admin/client/collection/entry-link.svelte.d.ts +3 -1
- package/dist/admin/client/collection/status-badge.svelte +39 -3
- package/dist/admin/client/collection/status-badge.svelte.d.ts +5 -3
- package/dist/admin/client/entry/entry.svelte +26 -9
- package/dist/admin/client/entry/hybrid/hybrid-preview.svelte +73 -10
- package/dist/admin/client/entry/hybrid/hybrid-preview.svelte.d.ts +6 -5
- package/dist/admin/client/entry/preview-views-context.svelte.d.ts +22 -0
- package/dist/admin/client/entry/preview-views-context.svelte.js +58 -0
- package/dist/admin/client/entry/preview-views.d.ts +27 -0
- package/dist/admin/client/entry/preview-views.js +33 -0
- package/dist/admin/client/index.d.ts +3 -0
- package/dist/admin/client/index.js +3 -0
- package/dist/admin/client/modules/dashboard-registry.d.ts +7 -0
- package/dist/admin/client/modules/dashboard-registry.js +11 -0
- package/dist/admin/client/modules/module-dashboard-page.svelte +26 -0
- package/dist/admin/client/modules/module-dashboard-page.svelte.d.ts +6 -0
- package/dist/admin/client/modules/stat-card.svelte +22 -0
- package/dist/admin/client/modules/stat-card.svelte.d.ts +10 -0
- package/dist/admin/client/shop/shop-dashboard.svelte +29 -0
- package/dist/admin/client/shop/shop-dashboard.svelte.d.ts +3 -0
- package/dist/admin/components/fields/relation-field.svelte +11 -2
- package/dist/admin/components/icons/icon-map.js +8 -0
- package/dist/admin/components/layout/app-sidebar.svelte +45 -14
- package/dist/admin/components/layout/context-switcher.svelte +90 -0
- package/dist/admin/components/layout/context-switcher.svelte.d.ts +3 -0
- package/dist/admin/components/layout/lang.d.ts +4 -0
- package/dist/admin/components/layout/lang.js +8 -0
- package/dist/admin/components/layout/layout-renderer.svelte +2 -1
- package/dist/admin/components/layout/layout-tabs.svelte +14 -0
- package/dist/admin/components/layout/layout-tabs.svelte.d.ts +2 -0
- package/dist/admin/components/layout/nav-collections.svelte +16 -9
- package/dist/admin/components/layout/nav-collections.svelte.d.ts +5 -1
- package/dist/admin/components/layout/nav-global.svelte +45 -0
- package/dist/admin/components/layout/nav-global.svelte.d.ts +3 -0
- package/dist/admin/components/layout/nav-main.svelte +8 -32
- package/dist/admin/components/layout/nav-main.svelte.d.ts +6 -1
- package/dist/admin/components/layout/nav-module.svelte +57 -0
- package/dist/admin/components/layout/nav-module.svelte.d.ts +7 -0
- package/dist/admin/components/layout/nav-section.svelte +1 -1
- package/dist/admin/components/layout/nav-section.svelte.d.ts +1 -1
- package/dist/admin/components/layout/nav-singletons.svelte +14 -7
- package/dist/admin/components/layout/nav-singletons.svelte.d.ts +5 -1
- package/dist/admin/remote/booking.remote.d.ts +247 -0
- package/dist/admin/remote/booking.remote.js +286 -0
- package/dist/admin/remote/index.d.ts +2 -0
- package/dist/admin/remote/index.js +2 -0
- package/dist/admin/remote/modules.remote.d.ts +10 -0
- package/dist/admin/remote/modules.remote.js +14 -0
- package/dist/admin/state/active-context-resolve.d.ts +37 -0
- package/dist/admin/state/active-context-resolve.js +66 -0
- package/dist/admin/state/active-context.svelte.d.ts +8 -0
- package/dist/admin/state/active-context.svelte.js +27 -0
- package/dist/booking/adjustments.d.ts +33 -0
- package/dist/booking/adjustments.js +26 -0
- package/dist/booking/capacity.d.ts +12 -0
- package/dist/booking/capacity.js +10 -0
- package/dist/booking/client/index.d.ts +42 -0
- package/dist/booking/client/index.js +48 -0
- package/dist/booking/client/use-booking.svelte.d.ts +24 -0
- package/dist/booking/client/use-booking.svelte.js +56 -0
- package/dist/booking/config.d.ts +176 -0
- package/dist/booking/config.js +37 -0
- package/dist/booking/draft.d.ts +96 -0
- package/dist/booking/draft.js +67 -0
- package/dist/booking/expiry-logic.d.ts +30 -0
- package/dist/booking/expiry-logic.js +33 -0
- package/dist/booking/index.d.ts +18 -0
- package/dist/booking/index.js +52 -0
- package/dist/booking/ledger.d.ts +46 -0
- package/dist/booking/ledger.js +60 -0
- package/dist/booking/number.d.ts +2 -0
- package/dist/booking/number.js +11 -0
- package/dist/booking/participant-fields/access.d.ts +10 -0
- package/dist/booking/participant-fields/access.js +14 -0
- package/dist/booking/participant-fields/age.d.ts +12 -0
- package/dist/booking/participant-fields/age.js +28 -0
- package/dist/booking/participant-fields/completeness.d.ts +8 -0
- package/dist/booking/participant-fields/completeness.js +13 -0
- package/dist/booking/participant-fields/group.d.ts +6 -0
- package/dist/booking/participant-fields/group.js +15 -0
- package/dist/booking/participant-fields/index.d.ts +6 -0
- package/dist/booking/participant-fields/index.js +6 -0
- package/dist/booking/participant-fields/types.d.ts +50 -0
- package/dist/booking/participant-fields/types.js +5 -0
- package/dist/booking/participant-fields/validate.d.ts +7 -0
- package/dist/booking/participant-fields/validate.js +44 -0
- package/dist/booking/participant-pricing.d.ts +93 -0
- package/dist/booking/participant-pricing.js +91 -0
- package/dist/booking/participants-view.d.ts +32 -0
- package/dist/booking/participants-view.js +22 -0
- package/dist/booking/payment-context.d.ts +19 -0
- package/dist/booking/payment-context.js +29 -0
- package/dist/booking/pricing-inputs.d.ts +28 -0
- package/dist/booking/pricing-inputs.js +35 -0
- package/dist/booking/pricing.d.ts +86 -0
- package/dist/booking/pricing.js +125 -0
- package/dist/booking/recompute.d.ts +22 -0
- package/dist/booking/recompute.js +31 -0
- package/dist/booking/reminders-schedule.d.ts +11 -0
- package/dist/booking/reminders-schedule.js +28 -0
- package/dist/booking/server/adjustments.d.ts +27 -0
- package/dist/booking/server/adjustments.js +139 -0
- package/dist/booking/server/bookings.d.ts +51 -0
- package/dist/booking/server/bookings.js +336 -0
- package/dist/booking/server/catalog.d.ts +9 -0
- package/dist/booking/server/catalog.js +20 -0
- package/dist/booking/server/db.d.ts +7 -0
- package/dist/booking/server/db.js +18 -0
- package/dist/booking/server/email.d.ts +23 -0
- package/dist/booking/server/email.js +59 -0
- package/dist/booking/server/emailTemplateRegistry.d.ts +29 -0
- package/dist/booking/server/emailTemplateRegistry.js +125 -0
- package/dist/booking/server/http/create-handler.d.ts +5 -0
- package/dist/booking/server/http/create-handler.js +70 -0
- package/dist/booking/server/http/index.d.ts +4 -0
- package/dist/booking/server/http/index.js +4 -0
- package/dist/booking/server/http/maintenance-handler.d.ts +9 -0
- package/dist/booking/server/http/maintenance-handler.js +36 -0
- package/dist/booking/server/http/portal-handler.d.ts +13 -0
- package/dist/booking/server/http/portal-handler.js +103 -0
- package/dist/booking/server/http/webhook-handler.d.ts +9 -0
- package/dist/booking/server/http/webhook-handler.js +39 -0
- package/dist/booking/server/index.d.ts +12 -0
- package/dist/booking/server/index.js +14 -0
- package/dist/booking/server/maintenance.d.ts +28 -0
- package/dist/booking/server/maintenance.js +134 -0
- package/dist/booking/server/participants.d.ts +26 -0
- package/dist/booking/server/participants.js +92 -0
- package/dist/booking/server/payments.d.ts +34 -0
- package/dist/booking/server/payments.js +207 -0
- package/dist/booking/server/portal-session.d.ts +16 -0
- package/dist/booking/server/portal-session.js +42 -0
- package/dist/booking/server/portal.d.ts +206 -0
- package/dist/booking/server/portal.js +236 -0
- package/dist/booking/server/price-source.d.ts +73 -0
- package/dist/booking/server/price-source.js +94 -0
- package/dist/booking/server/refunds.d.ts +7 -0
- package/dist/booking/server/refunds.js +58 -0
- package/dist/booking/server/reminders.d.ts +9 -0
- package/dist/booking/server/reminders.js +24 -0
- package/dist/booking/server/validation.d.ts +17 -0
- package/dist/booking/server/validation.js +55 -0
- package/dist/booking/state-machine.d.ts +41 -0
- package/dist/booking/state-machine.js +73 -0
- package/dist/booking/templates/_partials/footer.en.html +4 -0
- package/dist/booking/templates/_partials/footer.pl.html +4 -0
- package/dist/booking/templates/_partials/header.en.html +4 -0
- package/dist/booking/templates/_partials/header.pl.html +4 -0
- package/dist/booking/templates/balance-due.en.html +10 -0
- package/dist/booking/templates/balance-due.pl.html +10 -0
- package/dist/booking/templates/balance-overdue-cancelled.en.html +5 -0
- package/dist/booking/templates/balance-overdue-cancelled.pl.html +5 -0
- package/dist/booking/templates/booking-received.en.html +9 -0
- package/dist/booking/templates/booking-received.pl.html +9 -0
- package/dist/booking/templates/deposit-paid.en.html +6 -0
- package/dist/booking/templates/deposit-paid.pl.html +6 -0
- package/dist/booking/templates/payment-link.en.html +5 -0
- package/dist/booking/templates/payment-link.pl.html +5 -0
- package/dist/booking/templates/payment-received.en.html +10 -0
- package/dist/booking/templates/payment-received.pl.html +10 -0
- package/dist/booking/totals.d.ts +38 -0
- package/dist/booking/totals.js +61 -0
- package/dist/booking/webhook-logic.d.ts +28 -0
- package/dist/booking/webhook-logic.js +50 -0
- package/dist/cli/create-user.d.ts +7 -1
- package/dist/cli/create-user.js +23 -15
- package/dist/cli/index.js +55 -7
- package/dist/cli/scaffold/admin.d.ts +6 -0
- package/dist/cli/scaffold/admin.js +5 -3
- package/dist/cli/scaffold/booking.d.ts +12 -0
- package/dist/cli/scaffold/booking.js +103 -0
- package/dist/core/cms.d.ts +24 -9
- package/dist/core/cms.js +72 -34
- package/dist/core/config/validatePreviews.d.ts +12 -0
- package/dist/core/config/validatePreviews.js +90 -0
- package/dist/core/fields/slugPath.d.ts +9 -1
- package/dist/core/fields/slugPath.js +16 -2
- package/dist/core/server/fields/resolveRelationFields.d.ts +11 -2
- package/dist/core/server/fields/resolveRelationFields.js +12 -3
- package/dist/core/server/generator/generator.js +7 -2
- package/dist/db-postgres/schema/booking/bookingAdjustments.d.ts +186 -0
- package/dist/db-postgres/schema/booking/bookingAdjustments.js +22 -0
- package/dist/db-postgres/schema/booking/bookingItemPersons.d.ts +117 -0
- package/dist/db-postgres/schema/booking/bookingItemPersons.js +22 -0
- package/dist/db-postgres/schema/booking/bookingItems.d.ts +181 -0
- package/dist/db-postgres/schema/booking/bookingItems.js +22 -0
- package/dist/db-postgres/schema/booking/bookingPayments.d.ts +204 -0
- package/dist/db-postgres/schema/booking/bookingPayments.js +25 -0
- package/dist/db-postgres/schema/booking/bookingPersons.d.ts +99 -0
- package/dist/db-postgres/schema/booking/bookingPersons.js +17 -0
- package/dist/db-postgres/schema/booking/bookingReminders.d.ts +131 -0
- package/dist/db-postgres/schema/booking/bookingReminders.js +18 -0
- package/dist/db-postgres/schema/booking/bookings.d.ts +324 -0
- package/dist/db-postgres/schema/booking/bookings.js +52 -0
- package/dist/db-postgres/schema/booking/index.d.ts +7 -0
- package/dist/db-postgres/schema/booking/index.js +7 -0
- package/dist/db-postgres/schema/index.d.ts +1 -0
- package/dist/db-postgres/schema/index.js +1 -0
- package/dist/db-postgres/schema-booking.d.ts +1 -0
- package/dist/db-postgres/schema-booking.js +1 -0
- package/dist/server/security/rate-limit-handler.d.ts +19 -0
- package/dist/server/security/rate-limit-handler.js +34 -0
- package/dist/shop/adapters/payu/client.js +3 -1
- package/dist/shop/adapters/payu/index.js +37 -17
- package/dist/shop/adapters/payu/payload.d.ts +6 -0
- package/dist/shop/adapters/payu/payload.js +1 -1
- package/dist/shop/adapters/stripe/index.js +36 -21
- package/dist/shop/index.d.ts +11 -2
- package/dist/shop/index.js +43 -1
- package/dist/shop/rate-limit.d.ts +1 -9
- package/dist/shop/rate-limit.js +3 -28
- package/dist/shop/types.d.ts +19 -0
- package/dist/sveltekit/config.d.ts +4 -0
- package/dist/sveltekit/config.js +6 -0
- package/dist/types/cms.d.ts +15 -1
- package/dist/types/cms.schema.d.ts +96 -2
- package/dist/types/cms.schema.js +84 -1
- package/dist/types/config.d.ts +33 -0
- package/dist/types/layout.d.ts +6 -0
- package/dist/types/modules.d.ts +133 -0
- package/dist/types/modules.js +27 -0
- package/dist/updates/0.37.0/index.d.ts +2 -0
- package/dist/updates/0.37.0/index.js +52 -0
- package/dist/updates/0.37.1/index.d.ts +2 -0
- package/dist/updates/0.37.1/index.js +24 -0
- package/dist/updates/index.js +5 -1
- package/package.json +19 -1
- package/dist/admin/components/layout/nav-shop.svelte +0 -33
- package/dist/admin/components/layout/nav-shop.svelte.d.ts +0 -3
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import type { BookingStatus } from '../../../booking/state-machine.js';
|
|
2
|
+
import type { AppliedRule, Perk } from '../../../booking/pricing.js';
|
|
3
|
+
/** Computed money snapshot kept on the booking for fast list/detail reads. */
|
|
4
|
+
export interface BookingTotals {
|
|
5
|
+
gross: number;
|
|
6
|
+
discount: number;
|
|
7
|
+
/** Σ active manual surcharges (minor units). */
|
|
8
|
+
surcharge: number;
|
|
9
|
+
/** Σ active manual discounts, magnitude (minor units). */
|
|
10
|
+
manualDiscount: number;
|
|
11
|
+
paid: number;
|
|
12
|
+
balance: number;
|
|
13
|
+
/** Granted non-monetary perks (staff notes; manual fulfilment). */
|
|
14
|
+
perks: Perk[];
|
|
15
|
+
/** Per-rule discount breakdown for display. */
|
|
16
|
+
appliedRules: AppliedRule[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A long-lived, mutable reservation with a payment ledger. Unlike a shop order
|
|
20
|
+
* ("buy → ship → done"), a booking is edited after payment and its price is
|
|
21
|
+
* recomputed. Amounts are in minor units.
|
|
22
|
+
*/
|
|
23
|
+
export declare const bookingsTable: import("drizzle-orm/pg-core/table", { with: { "resolution-mode": "require" } }).PgTableWithColumns<{
|
|
24
|
+
name: "bookings";
|
|
25
|
+
schema: undefined;
|
|
26
|
+
columns: {
|
|
27
|
+
id: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
28
|
+
name: "id";
|
|
29
|
+
tableName: "bookings";
|
|
30
|
+
dataType: "string";
|
|
31
|
+
columnType: "PgUUID";
|
|
32
|
+
data: string;
|
|
33
|
+
driverParam: string;
|
|
34
|
+
notNull: true;
|
|
35
|
+
hasDefault: true;
|
|
36
|
+
isPrimaryKey: true;
|
|
37
|
+
isAutoincrement: false;
|
|
38
|
+
hasRuntimeDefault: false;
|
|
39
|
+
enumValues: undefined;
|
|
40
|
+
baseColumn: never;
|
|
41
|
+
identity: undefined;
|
|
42
|
+
generated: undefined;
|
|
43
|
+
}, {}, {}>;
|
|
44
|
+
number: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
45
|
+
name: "number";
|
|
46
|
+
tableName: "bookings";
|
|
47
|
+
dataType: "string";
|
|
48
|
+
columnType: "PgText";
|
|
49
|
+
data: string;
|
|
50
|
+
driverParam: string;
|
|
51
|
+
notNull: true;
|
|
52
|
+
hasDefault: false;
|
|
53
|
+
isPrimaryKey: false;
|
|
54
|
+
isAutoincrement: false;
|
|
55
|
+
hasRuntimeDefault: false;
|
|
56
|
+
enumValues: [string, ...string[]];
|
|
57
|
+
baseColumn: never;
|
|
58
|
+
identity: undefined;
|
|
59
|
+
generated: undefined;
|
|
60
|
+
}, {}, {}>;
|
|
61
|
+
status: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
62
|
+
name: "status";
|
|
63
|
+
tableName: "bookings";
|
|
64
|
+
dataType: "string";
|
|
65
|
+
columnType: "PgText";
|
|
66
|
+
data: BookingStatus;
|
|
67
|
+
driverParam: string;
|
|
68
|
+
notNull: true;
|
|
69
|
+
hasDefault: true;
|
|
70
|
+
isPrimaryKey: false;
|
|
71
|
+
isAutoincrement: false;
|
|
72
|
+
hasRuntimeDefault: false;
|
|
73
|
+
enumValues: [string, ...string[]];
|
|
74
|
+
baseColumn: never;
|
|
75
|
+
identity: undefined;
|
|
76
|
+
generated: undefined;
|
|
77
|
+
}, {}, {
|
|
78
|
+
$type: BookingStatus;
|
|
79
|
+
}>;
|
|
80
|
+
currency: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
81
|
+
name: "currency";
|
|
82
|
+
tableName: "bookings";
|
|
83
|
+
dataType: "string";
|
|
84
|
+
columnType: "PgText";
|
|
85
|
+
data: string;
|
|
86
|
+
driverParam: string;
|
|
87
|
+
notNull: true;
|
|
88
|
+
hasDefault: false;
|
|
89
|
+
isPrimaryKey: false;
|
|
90
|
+
isAutoincrement: false;
|
|
91
|
+
hasRuntimeDefault: false;
|
|
92
|
+
enumValues: [string, ...string[]];
|
|
93
|
+
baseColumn: never;
|
|
94
|
+
identity: undefined;
|
|
95
|
+
generated: undefined;
|
|
96
|
+
}, {}, {}>;
|
|
97
|
+
customer: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
98
|
+
name: "customer";
|
|
99
|
+
tableName: "bookings";
|
|
100
|
+
dataType: "json";
|
|
101
|
+
columnType: "PgJsonb";
|
|
102
|
+
data: Record<string, unknown>;
|
|
103
|
+
driverParam: unknown;
|
|
104
|
+
notNull: true;
|
|
105
|
+
hasDefault: true;
|
|
106
|
+
isPrimaryKey: false;
|
|
107
|
+
isAutoincrement: false;
|
|
108
|
+
hasRuntimeDefault: false;
|
|
109
|
+
enumValues: undefined;
|
|
110
|
+
baseColumn: never;
|
|
111
|
+
identity: undefined;
|
|
112
|
+
generated: undefined;
|
|
113
|
+
}, {}, {
|
|
114
|
+
$type: Record<string, unknown>;
|
|
115
|
+
}>;
|
|
116
|
+
totals: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
117
|
+
name: "totals";
|
|
118
|
+
tableName: "bookings";
|
|
119
|
+
dataType: "json";
|
|
120
|
+
columnType: "PgJsonb";
|
|
121
|
+
data: BookingTotals;
|
|
122
|
+
driverParam: unknown;
|
|
123
|
+
notNull: true;
|
|
124
|
+
hasDefault: true;
|
|
125
|
+
isPrimaryKey: false;
|
|
126
|
+
isAutoincrement: false;
|
|
127
|
+
hasRuntimeDefault: false;
|
|
128
|
+
enumValues: undefined;
|
|
129
|
+
baseColumn: never;
|
|
130
|
+
identity: undefined;
|
|
131
|
+
generated: undefined;
|
|
132
|
+
}, {}, {
|
|
133
|
+
$type: BookingTotals;
|
|
134
|
+
}>;
|
|
135
|
+
pricedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
136
|
+
name: "priced_at";
|
|
137
|
+
tableName: "bookings";
|
|
138
|
+
dataType: "date";
|
|
139
|
+
columnType: "PgTimestamp";
|
|
140
|
+
data: Date;
|
|
141
|
+
driverParam: string;
|
|
142
|
+
notNull: false;
|
|
143
|
+
hasDefault: false;
|
|
144
|
+
isPrimaryKey: false;
|
|
145
|
+
isAutoincrement: false;
|
|
146
|
+
hasRuntimeDefault: false;
|
|
147
|
+
enumValues: undefined;
|
|
148
|
+
baseColumn: never;
|
|
149
|
+
identity: undefined;
|
|
150
|
+
generated: undefined;
|
|
151
|
+
}, {}, {}>;
|
|
152
|
+
accessToken: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
153
|
+
name: "access_token";
|
|
154
|
+
tableName: "bookings";
|
|
155
|
+
dataType: "string";
|
|
156
|
+
columnType: "PgUUID";
|
|
157
|
+
data: string;
|
|
158
|
+
driverParam: string;
|
|
159
|
+
notNull: true;
|
|
160
|
+
hasDefault: true;
|
|
161
|
+
isPrimaryKey: false;
|
|
162
|
+
isAutoincrement: false;
|
|
163
|
+
hasRuntimeDefault: false;
|
|
164
|
+
enumValues: undefined;
|
|
165
|
+
baseColumn: never;
|
|
166
|
+
identity: undefined;
|
|
167
|
+
generated: undefined;
|
|
168
|
+
}, {}, {}>;
|
|
169
|
+
staffNotes: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
170
|
+
name: "staff_notes";
|
|
171
|
+
tableName: "bookings";
|
|
172
|
+
dataType: "string";
|
|
173
|
+
columnType: "PgText";
|
|
174
|
+
data: string;
|
|
175
|
+
driverParam: string;
|
|
176
|
+
notNull: false;
|
|
177
|
+
hasDefault: false;
|
|
178
|
+
isPrimaryKey: false;
|
|
179
|
+
isAutoincrement: false;
|
|
180
|
+
hasRuntimeDefault: false;
|
|
181
|
+
enumValues: [string, ...string[]];
|
|
182
|
+
baseColumn: never;
|
|
183
|
+
identity: undefined;
|
|
184
|
+
generated: undefined;
|
|
185
|
+
}, {}, {}>;
|
|
186
|
+
language: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
187
|
+
name: "language";
|
|
188
|
+
tableName: "bookings";
|
|
189
|
+
dataType: "string";
|
|
190
|
+
columnType: "PgText";
|
|
191
|
+
data: string;
|
|
192
|
+
driverParam: string;
|
|
193
|
+
notNull: false;
|
|
194
|
+
hasDefault: false;
|
|
195
|
+
isPrimaryKey: false;
|
|
196
|
+
isAutoincrement: false;
|
|
197
|
+
hasRuntimeDefault: false;
|
|
198
|
+
enumValues: [string, ...string[]];
|
|
199
|
+
baseColumn: never;
|
|
200
|
+
identity: undefined;
|
|
201
|
+
generated: undefined;
|
|
202
|
+
}, {}, {}>;
|
|
203
|
+
balanceDueAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
204
|
+
name: "balance_due_at";
|
|
205
|
+
tableName: "bookings";
|
|
206
|
+
dataType: "date";
|
|
207
|
+
columnType: "PgTimestamp";
|
|
208
|
+
data: Date;
|
|
209
|
+
driverParam: string;
|
|
210
|
+
notNull: false;
|
|
211
|
+
hasDefault: false;
|
|
212
|
+
isPrimaryKey: false;
|
|
213
|
+
isAutoincrement: false;
|
|
214
|
+
hasRuntimeDefault: false;
|
|
215
|
+
enumValues: undefined;
|
|
216
|
+
baseColumn: never;
|
|
217
|
+
identity: undefined;
|
|
218
|
+
generated: undefined;
|
|
219
|
+
}, {}, {}>;
|
|
220
|
+
holdExpiresAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
221
|
+
name: "hold_expires_at";
|
|
222
|
+
tableName: "bookings";
|
|
223
|
+
dataType: "date";
|
|
224
|
+
columnType: "PgTimestamp";
|
|
225
|
+
data: Date;
|
|
226
|
+
driverParam: string;
|
|
227
|
+
notNull: false;
|
|
228
|
+
hasDefault: false;
|
|
229
|
+
isPrimaryKey: false;
|
|
230
|
+
isAutoincrement: false;
|
|
231
|
+
hasRuntimeDefault: false;
|
|
232
|
+
enumValues: undefined;
|
|
233
|
+
baseColumn: never;
|
|
234
|
+
identity: undefined;
|
|
235
|
+
generated: undefined;
|
|
236
|
+
}, {}, {}>;
|
|
237
|
+
cancelReason: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
238
|
+
name: "cancel_reason";
|
|
239
|
+
tableName: "bookings";
|
|
240
|
+
dataType: "string";
|
|
241
|
+
columnType: "PgText";
|
|
242
|
+
data: string;
|
|
243
|
+
driverParam: string;
|
|
244
|
+
notNull: false;
|
|
245
|
+
hasDefault: false;
|
|
246
|
+
isPrimaryKey: false;
|
|
247
|
+
isAutoincrement: false;
|
|
248
|
+
hasRuntimeDefault: false;
|
|
249
|
+
enumValues: [string, ...string[]];
|
|
250
|
+
baseColumn: never;
|
|
251
|
+
identity: undefined;
|
|
252
|
+
generated: undefined;
|
|
253
|
+
}, {}, {}>;
|
|
254
|
+
deletedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
255
|
+
name: "deleted_at";
|
|
256
|
+
tableName: "bookings";
|
|
257
|
+
dataType: "date";
|
|
258
|
+
columnType: "PgTimestamp";
|
|
259
|
+
data: Date;
|
|
260
|
+
driverParam: string;
|
|
261
|
+
notNull: false;
|
|
262
|
+
hasDefault: false;
|
|
263
|
+
isPrimaryKey: false;
|
|
264
|
+
isAutoincrement: false;
|
|
265
|
+
hasRuntimeDefault: false;
|
|
266
|
+
enumValues: undefined;
|
|
267
|
+
baseColumn: never;
|
|
268
|
+
identity: undefined;
|
|
269
|
+
generated: undefined;
|
|
270
|
+
}, {}, {}>;
|
|
271
|
+
deletedBy: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
272
|
+
name: "deleted_by";
|
|
273
|
+
tableName: "bookings";
|
|
274
|
+
dataType: "string";
|
|
275
|
+
columnType: "PgText";
|
|
276
|
+
data: string;
|
|
277
|
+
driverParam: string;
|
|
278
|
+
notNull: false;
|
|
279
|
+
hasDefault: false;
|
|
280
|
+
isPrimaryKey: false;
|
|
281
|
+
isAutoincrement: false;
|
|
282
|
+
hasRuntimeDefault: false;
|
|
283
|
+
enumValues: [string, ...string[]];
|
|
284
|
+
baseColumn: never;
|
|
285
|
+
identity: undefined;
|
|
286
|
+
generated: undefined;
|
|
287
|
+
}, {}, {}>;
|
|
288
|
+
createdAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
289
|
+
name: "created_at";
|
|
290
|
+
tableName: "bookings";
|
|
291
|
+
dataType: "date";
|
|
292
|
+
columnType: "PgTimestamp";
|
|
293
|
+
data: Date;
|
|
294
|
+
driverParam: string;
|
|
295
|
+
notNull: true;
|
|
296
|
+
hasDefault: true;
|
|
297
|
+
isPrimaryKey: false;
|
|
298
|
+
isAutoincrement: false;
|
|
299
|
+
hasRuntimeDefault: false;
|
|
300
|
+
enumValues: undefined;
|
|
301
|
+
baseColumn: never;
|
|
302
|
+
identity: undefined;
|
|
303
|
+
generated: undefined;
|
|
304
|
+
}, {}, {}>;
|
|
305
|
+
updatedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
306
|
+
name: "updated_at";
|
|
307
|
+
tableName: "bookings";
|
|
308
|
+
dataType: "date";
|
|
309
|
+
columnType: "PgTimestamp";
|
|
310
|
+
data: Date;
|
|
311
|
+
driverParam: string;
|
|
312
|
+
notNull: true;
|
|
313
|
+
hasDefault: true;
|
|
314
|
+
isPrimaryKey: false;
|
|
315
|
+
isAutoincrement: false;
|
|
316
|
+
hasRuntimeDefault: false;
|
|
317
|
+
enumValues: undefined;
|
|
318
|
+
baseColumn: never;
|
|
319
|
+
identity: undefined;
|
|
320
|
+
generated: undefined;
|
|
321
|
+
}, {}, {}>;
|
|
322
|
+
};
|
|
323
|
+
dialect: "pg";
|
|
324
|
+
}>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsonb, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core';
|
|
2
|
+
/**
|
|
3
|
+
* A long-lived, mutable reservation with a payment ledger. Unlike a shop order
|
|
4
|
+
* ("buy → ship → done"), a booking is edited after payment and its price is
|
|
5
|
+
* recomputed. Amounts are in minor units.
|
|
6
|
+
*/
|
|
7
|
+
export const bookingsTable = pgTable('bookings', {
|
|
8
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
9
|
+
number: text('number').notNull().unique(),
|
|
10
|
+
status: text('status').$type().notNull().default('draft'),
|
|
11
|
+
currency: text('currency').notNull(),
|
|
12
|
+
/** Booker details (name, email, phone, "how did you hear about us", …). */
|
|
13
|
+
customer: jsonb('customer').$type().notNull().default({}),
|
|
14
|
+
/** Computed totals (gross/discount/paid/balance), refreshed on every edit. */
|
|
15
|
+
totals: jsonb('totals').$type().notNull().default({
|
|
16
|
+
gross: 0,
|
|
17
|
+
discount: 0,
|
|
18
|
+
surcharge: 0,
|
|
19
|
+
manualDiscount: 0,
|
|
20
|
+
paid: 0,
|
|
21
|
+
balance: 0,
|
|
22
|
+
perks: [],
|
|
23
|
+
appliedRules: []
|
|
24
|
+
}),
|
|
25
|
+
/**
|
|
26
|
+
* **Moment wyceny — zamrożony.** Każde przeliczenie istniejącej rezerwacji (edycja,
|
|
27
|
+
* korekta) liczy reguły zależne od czasu (early-bird) na tę datę, **nigdy na `new Date()`**.
|
|
28
|
+
*
|
|
29
|
+
* Bez tego cena bazowa była zamrożona, ale data — nie: obsługa księgowała dopłatę
|
|
30
|
+
* tydzień przed wylotem, `daysUntil(anchor, now)` spadało poniżej progu, early-bird
|
|
31
|
+
* cicho znikał i klient robił się winien pieniądze.
|
|
32
|
+
*
|
|
33
|
+
* NULL dla rezerwacji sprzed 0.37.1 ⇒ czytamy `createdAt`, czyli dokładnie to, czym
|
|
34
|
+
* było `now` w chwili ich wyceny (zero zmiany zachowania, brak migracji danych).
|
|
35
|
+
*/
|
|
36
|
+
pricedAt: timestamp('priced_at', { withTimezone: true }),
|
|
37
|
+
/** Unguessable token for the self-service portal (`/rezerwacja/[token]`). */
|
|
38
|
+
accessToken: uuid('access_token').defaultRandom().notNull(),
|
|
39
|
+
staffNotes: text('staff_notes'),
|
|
40
|
+
language: text('language'),
|
|
41
|
+
/** Deadline to pay the balance; past it with balance>0 ⇒ auto-cancel + deposit forfeited. */
|
|
42
|
+
balanceDueAt: timestamp('balance_due_at', { withTimezone: true }),
|
|
43
|
+
/** TTL for an abandoned draft (deposit never paid) ⇒ auto-cancel. Cleared on deposit payment. */
|
|
44
|
+
holdExpiresAt: timestamp('hold_expires_at', { withTimezone: true }),
|
|
45
|
+
/** Why a booking was cancelled: 'abandoned' | 'balance_overdue' | 'manual'. */
|
|
46
|
+
cancelReason: text('cancel_reason'),
|
|
47
|
+
// Soft-delete (accounting/audit safety) — NULL = visible.
|
|
48
|
+
deletedAt: timestamp('deleted_at', { withTimezone: true }),
|
|
49
|
+
deletedBy: text('deleted_by'),
|
|
50
|
+
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
51
|
+
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
|
52
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './bookings.js';
|
|
2
|
+
export * from './bookingItems.js';
|
|
3
|
+
export * from './bookingPersons.js';
|
|
4
|
+
export * from './bookingItemPersons.js';
|
|
5
|
+
export * from './bookingPayments.js';
|
|
6
|
+
export * from './bookingReminders.js';
|
|
7
|
+
export * from './bookingAdjustments.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './bookings.js';
|
|
2
|
+
export * from './bookingItems.js';
|
|
3
|
+
export * from './bookingPersons.js';
|
|
4
|
+
export * from './bookingItemPersons.js';
|
|
5
|
+
export * from './bookingPayments.js';
|
|
6
|
+
export * from './bookingReminders.js';
|
|
7
|
+
export * from './bookingAdjustments.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './schema/booking/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './schema/booking/index.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-handler in-memory rate limiter (fixed window). Generic infra shared by the
|
|
3
|
+
* shop and booking HTTP handlers — not shop-specific. For a single instance this
|
|
4
|
+
* needs no external store; multi-instance deployments would swap the bucket map
|
|
5
|
+
* for a shared store.
|
|
6
|
+
*/
|
|
7
|
+
/** A fixed-window rule: at most `limit` hits per `windowSec` seconds. */
|
|
8
|
+
export interface RateLimitRule {
|
|
9
|
+
limit: number;
|
|
10
|
+
windowSec: number;
|
|
11
|
+
}
|
|
12
|
+
export interface RateLimitResult {
|
|
13
|
+
allowed: boolean;
|
|
14
|
+
remaining: number;
|
|
15
|
+
resetAt: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function checkRateLimit(key: string, rule: RateLimitRule): RateLimitResult;
|
|
18
|
+
export declare function resetRateLimit(key?: string): void;
|
|
19
|
+
export declare function clientKey(req: Request, prefix: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-handler in-memory rate limiter (fixed window). Generic infra shared by the
|
|
3
|
+
* shop and booking HTTP handlers — not shop-specific. For a single instance this
|
|
4
|
+
* needs no external store; multi-instance deployments would swap the bucket map
|
|
5
|
+
* for a shared store.
|
|
6
|
+
*/
|
|
7
|
+
const buckets = new Map();
|
|
8
|
+
export function checkRateLimit(key, rule) {
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
const windowMs = rule.windowSec * 1000;
|
|
11
|
+
const bucket = buckets.get(key);
|
|
12
|
+
if (!bucket || bucket.resetAt <= now) {
|
|
13
|
+
const fresh = { count: 1, resetAt: now + windowMs };
|
|
14
|
+
buckets.set(key, fresh);
|
|
15
|
+
return { allowed: true, remaining: rule.limit - 1, resetAt: fresh.resetAt };
|
|
16
|
+
}
|
|
17
|
+
if (bucket.count >= rule.limit) {
|
|
18
|
+
return { allowed: false, remaining: 0, resetAt: bucket.resetAt };
|
|
19
|
+
}
|
|
20
|
+
bucket.count += 1;
|
|
21
|
+
return { allowed: true, remaining: rule.limit - bucket.count, resetAt: bucket.resetAt };
|
|
22
|
+
}
|
|
23
|
+
export function resetRateLimit(key) {
|
|
24
|
+
if (key)
|
|
25
|
+
buckets.delete(key);
|
|
26
|
+
else
|
|
27
|
+
buckets.clear();
|
|
28
|
+
}
|
|
29
|
+
export function clientKey(req, prefix) {
|
|
30
|
+
const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||
|
|
31
|
+
req.headers.get('x-real-ip') ||
|
|
32
|
+
'unknown';
|
|
33
|
+
return `${prefix}:${ip}`;
|
|
34
|
+
}
|
|
@@ -52,7 +52,9 @@ export class PayuClient {
|
|
|
52
52
|
});
|
|
53
53
|
// PayU returns 302 by default with a JSON body (manual redirect is used to read it).
|
|
54
54
|
if (res.status !== 302 && !res.ok) {
|
|
55
|
-
|
|
55
|
+
// Surface PayU's error body (e.g. ERROR_ORDER_NOT_UNIQUE) — don't swallow it.
|
|
56
|
+
const detail = await res.text().catch(() => '');
|
|
57
|
+
throw new Error(`PayU createOrder failed: ${res.status}${detail ? ` — ${detail}` : ''}`);
|
|
56
58
|
}
|
|
57
59
|
const data = (await res.json());
|
|
58
60
|
if (data.status && data.status.statusCode && data.status.statusCode !== 'SUCCESS') {
|
|
@@ -19,31 +19,51 @@ export function payuAdapter(opts) {
|
|
|
19
19
|
id,
|
|
20
20
|
label: opts.label ?? DEFAULT_LABEL,
|
|
21
21
|
async createPayment(order, ctx) {
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
25
|
-
|
|
22
|
+
let continueUrl;
|
|
23
|
+
const buyer = {};
|
|
24
|
+
if (ctx?.continueUrl) {
|
|
25
|
+
// Non-shop caller (e.g. booking) supplied everything — skip shop hydration.
|
|
26
|
+
if (!/^https?:\/\//i.test(ctx.continueUrl)) {
|
|
27
|
+
throw new Error('payuAdapter: ctx.continueUrl must be an absolute URL.');
|
|
28
|
+
}
|
|
29
|
+
continueUrl = ctx.continueUrl;
|
|
30
|
+
buyer.firstName = ctx.buyer?.firstName;
|
|
31
|
+
buyer.lastName = ctx.buyer?.lastName;
|
|
32
|
+
buyer.phone = ctx.buyer?.phone;
|
|
33
|
+
buyer.language = ctx.language ?? undefined;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Shop path: hydrate buyer + continueUrl from the stored shop order.
|
|
37
|
+
const shop = requireShopConfig();
|
|
38
|
+
const continueTemplate = opts.continueUrl ?? shop.orderViewUrl;
|
|
39
|
+
if (!/^https?:\/\//i.test(continueTemplate)) {
|
|
40
|
+
throw new Error('payuAdapter: continueUrl (or shop.orderViewUrl) must be an absolute URL.');
|
|
41
|
+
}
|
|
42
|
+
const full = await getOrderById(order.id);
|
|
43
|
+
const names = splitFullName(full?.customerName);
|
|
44
|
+
continueUrl = buildOrderViewUrl(continueTemplate, {
|
|
45
|
+
orderNumber: order.number,
|
|
46
|
+
orderId: order.id,
|
|
47
|
+
accessToken: full?.accessToken ?? '',
|
|
48
|
+
language: ctx?.language ?? full?.language ?? null
|
|
49
|
+
});
|
|
50
|
+
buyer.firstName = names.firstName;
|
|
51
|
+
buyer.lastName = names.lastName;
|
|
52
|
+
buyer.phone = full?.customerPhone ?? undefined;
|
|
53
|
+
buyer.language = ctx?.language ?? full?.language ?? undefined;
|
|
26
54
|
}
|
|
27
|
-
// Hydrate buyer details from stored order (customerName/phone not on OrderRef)
|
|
28
|
-
const full = await getOrderById(order.id);
|
|
29
|
-
const names = splitFullName(full?.customerName);
|
|
30
|
-
const continueUrl = buildOrderViewUrl(continueTemplate, {
|
|
31
|
-
orderNumber: order.number,
|
|
32
|
-
orderId: order.id,
|
|
33
|
-
accessToken: full?.accessToken ?? '',
|
|
34
|
-
language: ctx?.language ?? full?.language ?? null
|
|
35
|
-
});
|
|
36
55
|
const payload = buildPayuOrderPayload({
|
|
37
56
|
order,
|
|
38
57
|
posId: opts.posId,
|
|
39
58
|
notifyUrl: opts.notifyUrl,
|
|
40
59
|
continueUrl,
|
|
41
60
|
customerIp: ctx?.customerIp ?? '127.0.0.1',
|
|
61
|
+
externalId: ctx?.externalId,
|
|
42
62
|
buyer: {
|
|
43
|
-
firstName:
|
|
44
|
-
lastName:
|
|
45
|
-
phone:
|
|
46
|
-
language:
|
|
63
|
+
firstName: buyer.firstName,
|
|
64
|
+
lastName: buyer.lastName,
|
|
65
|
+
phone: buyer.phone,
|
|
66
|
+
language: buyer.language
|
|
47
67
|
}
|
|
48
68
|
});
|
|
49
69
|
const { redirectUri, orderId } = await client.createOrder(payload);
|
|
@@ -32,6 +32,12 @@ export interface BuildPayuPayloadInput {
|
|
|
32
32
|
buyer?: Omit<PayuBuyer, 'email'> & {
|
|
33
33
|
email?: string;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Unique `extOrderId` for this attempt. PayU requires it unique per POS, so a
|
|
37
|
+
* single order/booking paying twice (deposit + balance) must vary it. Falls
|
|
38
|
+
* back to `order.number` when omitted.
|
|
39
|
+
*/
|
|
40
|
+
externalId?: string;
|
|
35
41
|
}
|
|
36
42
|
/**
|
|
37
43
|
* Split a single "Imię Nazwisko" string into first/last name heuristically.
|
|
@@ -35,7 +35,7 @@ export function buildPayuOrderPayload(input) {
|
|
|
35
35
|
description: input.description ?? `Order ${order.number}`,
|
|
36
36
|
currencyCode: order.currency,
|
|
37
37
|
totalAmount: String(order.totalGross),
|
|
38
|
-
extOrderId: order.number,
|
|
38
|
+
extOrderId: input.externalId ?? order.number,
|
|
39
39
|
buyer,
|
|
40
40
|
products: [
|
|
41
41
|
{
|
|
@@ -63,29 +63,44 @@ export function stripeAdapter(opts) {
|
|
|
63
63
|
id,
|
|
64
64
|
label: opts.label ?? DEFAULT_LABEL,
|
|
65
65
|
async createPayment(order, ctx) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
66
|
+
let successUrl;
|
|
67
|
+
let cancelUrl;
|
|
68
|
+
let language;
|
|
69
|
+
if (ctx?.continueUrl) {
|
|
70
|
+
// Non-shop caller (e.g. booking) supplied a fully-resolved return URL —
|
|
71
|
+
// use it verbatim and skip any shop-order hydration (mirrors payuAdapter).
|
|
72
|
+
if (!/^https?:\/\//i.test(ctx.continueUrl)) {
|
|
73
|
+
throw new Error('stripeAdapter: ctx.continueUrl must be an absolute URL.');
|
|
74
|
+
}
|
|
75
|
+
successUrl = ctx.continueUrl;
|
|
76
|
+
cancelUrl = ctx.continueUrl;
|
|
77
|
+
language = ctx.language ?? null;
|
|
71
78
|
}
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
else {
|
|
80
|
+
const shop = requireShopConfig();
|
|
81
|
+
const successTemplate = opts.successUrl ?? shop.orderViewUrl;
|
|
82
|
+
const cancelTemplate = opts.cancelUrl ?? successTemplate;
|
|
83
|
+
if (!/^https?:\/\//i.test(successTemplate)) {
|
|
84
|
+
throw new Error('stripeAdapter: successUrl (or shop.orderViewUrl) must be an absolute URL.');
|
|
85
|
+
}
|
|
86
|
+
if (!/^https?:\/\//i.test(cancelTemplate)) {
|
|
87
|
+
throw new Error('stripeAdapter: cancelUrl must be an absolute URL.');
|
|
88
|
+
}
|
|
89
|
+
const full = await getOrderById(order.id);
|
|
90
|
+
language = ctx?.language ?? full?.language ?? null;
|
|
91
|
+
successUrl = buildOrderViewUrl(successTemplate, {
|
|
92
|
+
orderNumber: order.number,
|
|
93
|
+
orderId: order.id,
|
|
94
|
+
accessToken: full?.accessToken ?? '',
|
|
95
|
+
language
|
|
96
|
+
});
|
|
97
|
+
cancelUrl = buildOrderViewUrl(cancelTemplate, {
|
|
98
|
+
orderNumber: order.number,
|
|
99
|
+
orderId: order.id,
|
|
100
|
+
accessToken: full?.accessToken ?? '',
|
|
101
|
+
language
|
|
102
|
+
});
|
|
74
103
|
}
|
|
75
|
-
const full = await getOrderById(order.id);
|
|
76
|
-
const language = ctx?.language ?? full?.language ?? null;
|
|
77
|
-
const successUrl = buildOrderViewUrl(successTemplate, {
|
|
78
|
-
orderNumber: order.number,
|
|
79
|
-
orderId: order.id,
|
|
80
|
-
accessToken: full?.accessToken ?? '',
|
|
81
|
-
language
|
|
82
|
-
});
|
|
83
|
-
const cancelUrl = buildOrderViewUrl(cancelTemplate, {
|
|
84
|
-
orderNumber: order.number,
|
|
85
|
-
orderId: order.id,
|
|
86
|
-
accessToken: full?.accessToken ?? '',
|
|
87
|
-
language
|
|
88
|
-
});
|
|
89
104
|
const productNameTpl = pickI18n(opts.productName ?? DEFAULT_PRODUCT_NAME, language);
|
|
90
105
|
const productName = productNameTpl.replace('{number}', order.number);
|
|
91
106
|
const payload = buildStripeCheckoutPayload({
|
package/dist/shop/index.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import type { ShopConfig
|
|
2
|
-
|
|
1
|
+
import type { ShopConfig } from './types.js';
|
|
2
|
+
import type { CMSModule } from '../types/modules.js';
|
|
3
|
+
/**
|
|
4
|
+
* Defines the shop module. Returns a {@link CMSModule} for
|
|
5
|
+
* `defineConfig({ modules: [defineShop({...})] })`. The resolved shop config
|
|
6
|
+
* is carried on `module.config` and reachable via `getCMS().getModuleConfig('shop')`
|
|
7
|
+
* (or the back-compat `getCMS().shopConfig`).
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare function defineShop(config: ShopConfig): CMSModule;
|
|
3
12
|
export { InvalidVariantAttributesError } from './variant-attributes.js';
|
|
4
13
|
export { isVariantExpired, filterUpcoming, VariantExpiredError } from './expiry.js';
|
|
5
14
|
export { manualAdapter } from './adapters/manual/index.js';
|