includio-cms 0.27.0 → 0.33.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/API.md +58 -14
- package/CHANGELOG.md +59 -0
- package/DOCS.md +1 -1
- package/ROADMAP.md +1 -0
- package/dist/admin/api/handler.js +4 -0
- package/dist/admin/api/integrations.d.ts +13 -0
- package/dist/admin/api/integrations.js +61 -0
- package/dist/admin/api/test-email.d.ts +9 -0
- package/dist/admin/api/test-email.js +39 -0
- package/dist/admin/auth-client.d.ts +543 -543
- package/dist/admin/client/index.d.ts +10 -0
- package/dist/admin/client/index.js +12 -0
- package/dist/admin/client/maintenance/maintenance-page.svelte +210 -0
- package/dist/admin/client/shop/coupon-schema.d.ts +1 -1
- package/dist/admin/client/shop/restore-order-cell.svelte +29 -0
- package/dist/admin/client/shop/restore-order-cell.svelte.d.ts +8 -0
- package/dist/admin/client/shop/shop-order-detail-page.svelte +156 -1
- package/dist/admin/client/shop/shop-orders-list-page.svelte +113 -53
- package/dist/admin/components/layout/app-sidebar.svelte +2 -0
- package/dist/admin/components/layout/nav-custom.svelte +26 -0
- package/dist/admin/components/layout/nav-custom.svelte.d.ts +3 -0
- package/dist/admin/components/layout/page-header.svelte +13 -3
- package/dist/admin/components/layout/page-header.svelte.d.ts +13 -3
- package/dist/admin/remote/admin.remote.d.ts +7 -0
- package/dist/admin/remote/admin.remote.js +10 -0
- package/dist/admin/remote/entry.remote.d.ts +2 -2
- package/dist/admin/remote/index.d.ts +1 -0
- package/dist/admin/remote/index.js +1 -0
- package/dist/admin/remote/invite.d.ts +1 -1
- package/dist/admin/remote/shop.remote.d.ts +125 -40
- package/dist/admin/remote/shop.remote.js +59 -10
- package/dist/admin/types.d.ts +15 -0
- package/dist/admin/utils/csv-export.d.ts +45 -0
- package/dist/admin/utils/csv-export.js +61 -0
- package/dist/cli/scaffold/admin.js +1 -1
- package/dist/components/ui/input/input.svelte.d.ts +1 -1
- package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/core/cms.d.ts +44 -2
- package/dist/core/cms.js +64 -0
- package/dist/core/index.d.ts +2 -4
- package/dist/core/index.js +1 -4
- package/dist/core/server/index.d.ts +4 -1
- package/dist/core/server/index.js +4 -1
- package/dist/db-postgres/schema/shop/index.d.ts +1 -0
- package/dist/db-postgres/schema/shop/index.js +1 -0
- package/dist/db-postgres/schema/shop/invoice.d.ts +254 -0
- package/dist/db-postgres/schema/shop/invoice.js +27 -0
- package/dist/db-postgres/schema/shop/order.d.ts +104 -0
- package/dist/db-postgres/schema/shop/order.js +8 -0
- package/dist/shop/adapters/fakturownia/client.d.ts +33 -0
- package/dist/shop/adapters/fakturownia/client.js +87 -0
- package/dist/shop/adapters/fakturownia/index.d.ts +27 -0
- package/dist/shop/adapters/fakturownia/index.js +47 -0
- package/dist/shop/adapters/fakturownia/payload.d.ts +35 -0
- package/dist/shop/adapters/fakturownia/payload.js +45 -0
- package/dist/shop/adapters/payu/index.js +11 -0
- package/dist/shop/client/index.d.ts +7 -0
- package/dist/shop/http/checkout-handler.js +11 -0
- package/dist/shop/index.d.ts +4 -1
- package/dist/shop/index.js +3 -0
- package/dist/shop/nip.d.ts +12 -0
- package/dist/shop/nip.js +23 -0
- package/dist/shop/server/coupons.d.ts +10 -0
- package/dist/shop/server/coupons.js +19 -0
- package/dist/shop/server/email.d.ts +7 -3
- package/dist/shop/server/email.js +86 -112
- package/dist/shop/server/emailTemplateRegistry.d.ts +47 -0
- package/dist/shop/server/emailTemplateRegistry.js +288 -0
- package/dist/shop/server/invoices.d.ts +64 -0
- package/dist/shop/server/invoices.js +237 -0
- package/dist/shop/server/orders.d.ts +64 -1
- package/dist/shop/server/orders.js +155 -15
- package/dist/shop/templates/_partials/footer.en.html +4 -0
- package/dist/shop/templates/_partials/footer.pl.html +4 -0
- package/dist/shop/templates/_partials/header.en.html +4 -0
- package/dist/shop/templates/_partials/header.pl.html +4 -0
- package/dist/shop/templates/_partials/items.en.html +14 -0
- package/dist/shop/templates/_partials/items.pl.html +14 -0
- package/dist/shop/templates/_partials/tracking.en.html +7 -0
- package/dist/shop/templates/_partials/tracking.pl.html +7 -0
- package/dist/shop/templates/awaiting-payment.en.html +6 -0
- package/dist/shop/templates/awaiting-payment.pl.html +6 -0
- package/dist/shop/templates/cancelled.en.html +6 -0
- package/dist/shop/templates/cancelled.pl.html +6 -0
- package/dist/shop/templates/low-stock.en.html +14 -0
- package/dist/shop/templates/low-stock.pl.html +14 -0
- package/dist/shop/templates/order-completed.en.html +6 -0
- package/dist/shop/templates/order-completed.pl.html +6 -0
- package/dist/shop/templates/order-received.en.html +7 -0
- package/dist/shop/templates/order-received.pl.html +7 -0
- package/dist/shop/templates/payment-received.en.html +7 -0
- package/dist/shop/templates/payment-received.pl.html +7 -0
- package/dist/shop/templates/payment-rejected.en.html +6 -0
- package/dist/shop/templates/payment-rejected.pl.html +6 -0
- package/dist/shop/templates/preparing.en.html +7 -0
- package/dist/shop/templates/preparing.pl.html +7 -0
- package/dist/shop/templates/refunded.en.html +6 -0
- package/dist/shop/templates/refunded.pl.html +6 -0
- package/dist/shop/templates/shipped.en.html +7 -0
- package/dist/shop/templates/shipped.pl.html +7 -0
- package/dist/shop/types.d.ts +130 -1
- package/dist/sveltekit/index.d.ts +0 -1
- package/dist/sveltekit/index.js +0 -1
- package/dist/sveltekit/server/index.d.ts +1 -0
- package/dist/sveltekit/server/index.js +1 -0
- package/dist/types/adapters/email.d.ts +13 -0
- package/dist/types/cms.d.ts +30 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/updates/0.28.0/index.d.ts +2 -0
- package/dist/updates/0.28.0/index.js +38 -0
- package/dist/updates/0.34.0/index.d.ts +2 -0
- package/dist/updates/0.34.0/index.js +17 -0
- package/dist/updates/index.js +5 -1
- package/package.json +7 -2
|
@@ -93,28 +93,26 @@ export declare const reorderShippingMethodsCmd: import("@sveltejs/kit").RemoteCo
|
|
|
93
93
|
}>>;
|
|
94
94
|
export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunction<{
|
|
95
95
|
status?: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected" | "refunded" | undefined;
|
|
96
|
-
|
|
96
|
+
search?: string | undefined;
|
|
97
97
|
limit?: number | undefined;
|
|
98
98
|
offset?: number | undefined;
|
|
99
|
+
deleted?: "exclude" | "only" | "include" | undefined;
|
|
99
100
|
} | undefined, {
|
|
100
101
|
items: {
|
|
101
102
|
number: string;
|
|
102
|
-
currency: string;
|
|
103
|
-
consents: {
|
|
104
|
-
id: string;
|
|
105
|
-
accepted: boolean;
|
|
106
|
-
label: string;
|
|
107
|
-
}[] | null;
|
|
108
103
|
id: string;
|
|
109
|
-
status: import("../../shop/types.js").OrderStatus;
|
|
110
|
-
createdAt: Date;
|
|
111
|
-
updatedAt: Date;
|
|
112
|
-
language: string | null;
|
|
113
104
|
carrierType: string | null;
|
|
105
|
+
createdAt: Date;
|
|
106
|
+
status: import("../../shop/types.js").OrderStatus;
|
|
107
|
+
currency: string;
|
|
114
108
|
customerEmail: string;
|
|
115
109
|
customerName: string | null;
|
|
116
110
|
customerPhone: string | null;
|
|
111
|
+
customerNip: string | null;
|
|
112
|
+
customerCompanyName: string | null;
|
|
117
113
|
shippingAddress: Record<string, string> | null;
|
|
114
|
+
billingAddress: Record<string, string> | null;
|
|
115
|
+
invoiceRequested: boolean;
|
|
118
116
|
totalNet: number;
|
|
119
117
|
totalGross: number;
|
|
120
118
|
vatAmount: number;
|
|
@@ -128,10 +126,19 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
|
|
|
128
126
|
shipmentCreatedAt: Date | null;
|
|
129
127
|
paymentMethod: string | null;
|
|
130
128
|
paymentProviderRef: string | null;
|
|
129
|
+
consents: {
|
|
130
|
+
id: string;
|
|
131
|
+
accepted: boolean;
|
|
132
|
+
label: string;
|
|
133
|
+
}[] | null;
|
|
131
134
|
notes: string | null;
|
|
135
|
+
language: string | null;
|
|
132
136
|
accessToken: string;
|
|
133
137
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
134
138
|
balanceOwed: boolean;
|
|
139
|
+
deletedAt: Date | null;
|
|
140
|
+
deletedBy: string | null;
|
|
141
|
+
updatedAt: Date;
|
|
135
142
|
}[];
|
|
136
143
|
total: number;
|
|
137
144
|
limit: number;
|
|
@@ -140,22 +147,19 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
|
|
|
140
147
|
export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
141
148
|
order: {
|
|
142
149
|
number: string;
|
|
143
|
-
currency: string;
|
|
144
|
-
consents: {
|
|
145
|
-
id: string;
|
|
146
|
-
accepted: boolean;
|
|
147
|
-
label: string;
|
|
148
|
-
}[] | null;
|
|
149
150
|
id: string;
|
|
150
|
-
status: import("../../shop/types.js").OrderStatus;
|
|
151
|
-
createdAt: Date;
|
|
152
|
-
updatedAt: Date;
|
|
153
|
-
language: string | null;
|
|
154
151
|
carrierType: string | null;
|
|
152
|
+
createdAt: Date;
|
|
153
|
+
status: import("../../shop/types.js").OrderStatus;
|
|
154
|
+
currency: string;
|
|
155
155
|
customerEmail: string;
|
|
156
156
|
customerName: string | null;
|
|
157
157
|
customerPhone: string | null;
|
|
158
|
+
customerNip: string | null;
|
|
159
|
+
customerCompanyName: string | null;
|
|
158
160
|
shippingAddress: Record<string, string> | null;
|
|
161
|
+
billingAddress: Record<string, string> | null;
|
|
162
|
+
invoiceRequested: boolean;
|
|
159
163
|
totalNet: number;
|
|
160
164
|
totalGross: number;
|
|
161
165
|
vatAmount: number;
|
|
@@ -169,10 +173,19 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
|
|
|
169
173
|
shipmentCreatedAt: Date | null;
|
|
170
174
|
paymentMethod: string | null;
|
|
171
175
|
paymentProviderRef: string | null;
|
|
176
|
+
consents: {
|
|
177
|
+
id: string;
|
|
178
|
+
accepted: boolean;
|
|
179
|
+
label: string;
|
|
180
|
+
}[] | null;
|
|
172
181
|
notes: string | null;
|
|
182
|
+
language: string | null;
|
|
173
183
|
accessToken: string;
|
|
174
184
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
175
185
|
balanceOwed: boolean;
|
|
186
|
+
deletedAt: Date | null;
|
|
187
|
+
deletedBy: string | null;
|
|
188
|
+
updatedAt: Date;
|
|
176
189
|
};
|
|
177
190
|
items: {
|
|
178
191
|
id: string;
|
|
@@ -188,12 +201,16 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
|
|
|
188
201
|
}[];
|
|
189
202
|
history: {
|
|
190
203
|
id: string;
|
|
191
|
-
note: string | null;
|
|
192
204
|
status: import("../../shop/types.js").OrderStatus;
|
|
205
|
+
note: string | null;
|
|
193
206
|
orderId: string;
|
|
194
207
|
changedBy: string | null;
|
|
195
208
|
changedAt: Date;
|
|
196
209
|
}[];
|
|
210
|
+
coupon: {
|
|
211
|
+
code: string;
|
|
212
|
+
discountAmount: number;
|
|
213
|
+
} | null;
|
|
197
214
|
} | null>;
|
|
198
215
|
export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
199
216
|
orderId: string;
|
|
@@ -201,22 +218,19 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
|
|
|
201
218
|
note?: string | undefined;
|
|
202
219
|
}, Promise<{
|
|
203
220
|
number: string;
|
|
204
|
-
currency: string;
|
|
205
|
-
consents: {
|
|
206
|
-
id: string;
|
|
207
|
-
accepted: boolean;
|
|
208
|
-
label: string;
|
|
209
|
-
}[] | null;
|
|
210
221
|
id: string;
|
|
211
|
-
status: import("../../shop/types.js").OrderStatus;
|
|
212
|
-
createdAt: Date;
|
|
213
|
-
updatedAt: Date;
|
|
214
|
-
language: string | null;
|
|
215
222
|
carrierType: string | null;
|
|
223
|
+
createdAt: Date;
|
|
224
|
+
status: import("../../shop/types.js").OrderStatus;
|
|
225
|
+
currency: string;
|
|
216
226
|
customerEmail: string;
|
|
217
227
|
customerName: string | null;
|
|
218
228
|
customerPhone: string | null;
|
|
229
|
+
customerNip: string | null;
|
|
230
|
+
customerCompanyName: string | null;
|
|
219
231
|
shippingAddress: Record<string, string> | null;
|
|
232
|
+
billingAddress: Record<string, string> | null;
|
|
233
|
+
invoiceRequested: boolean;
|
|
220
234
|
totalNet: number;
|
|
221
235
|
totalGross: number;
|
|
222
236
|
vatAmount: number;
|
|
@@ -230,10 +244,35 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
|
|
|
230
244
|
shipmentCreatedAt: Date | null;
|
|
231
245
|
paymentMethod: string | null;
|
|
232
246
|
paymentProviderRef: string | null;
|
|
247
|
+
consents: {
|
|
248
|
+
id: string;
|
|
249
|
+
accepted: boolean;
|
|
250
|
+
label: string;
|
|
251
|
+
}[] | null;
|
|
233
252
|
notes: string | null;
|
|
253
|
+
language: string | null;
|
|
234
254
|
accessToken: string;
|
|
235
255
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
236
256
|
balanceOwed: boolean;
|
|
257
|
+
deletedAt: Date | null;
|
|
258
|
+
deletedBy: string | null;
|
|
259
|
+
updatedAt: Date;
|
|
260
|
+
}>>;
|
|
261
|
+
export declare const deleteOrderCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
262
|
+
orderId: string;
|
|
263
|
+
}, Promise<{
|
|
264
|
+
success: true;
|
|
265
|
+
reason?: undefined;
|
|
266
|
+
error?: undefined;
|
|
267
|
+
} | {
|
|
268
|
+
success: false;
|
|
269
|
+
reason: "status" | "invoice";
|
|
270
|
+
error: string;
|
|
271
|
+
}>>;
|
|
272
|
+
export declare const restoreOrderCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
273
|
+
orderId: string;
|
|
274
|
+
}, Promise<{
|
|
275
|
+
success: true;
|
|
237
276
|
}>>;
|
|
238
277
|
export declare const resendOrderEmailCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
239
278
|
orderId: string;
|
|
@@ -274,12 +313,12 @@ export declare const listShopableCollections: import("@sveltejs/kit").RemoteQuer
|
|
|
274
313
|
}[]>;
|
|
275
314
|
export declare const getOrderRefundsAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
276
315
|
refunds: {
|
|
277
|
-
amount: number;
|
|
278
|
-
currency: string;
|
|
279
316
|
id: string;
|
|
280
|
-
status: import("../../db-postgres/schema/shop/index.js").ShopRefundStatus;
|
|
281
317
|
createdAt: Date;
|
|
318
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopRefundStatus;
|
|
319
|
+
currency: string;
|
|
282
320
|
updatedAt: Date;
|
|
321
|
+
amount: number;
|
|
283
322
|
orderId: string;
|
|
284
323
|
provider: string;
|
|
285
324
|
providerRef: string | null;
|
|
@@ -312,6 +351,52 @@ export declare const refundOrderCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
312
351
|
code: "order_not_found" | "order_not_paid" | "no_provider_ref" | "unknown_provider" | "refund_unsupported" | "invalid_amount" | "amount_exceeds_remaining" | "provider_error" | "no_payment_kind";
|
|
313
352
|
error: string;
|
|
314
353
|
}>>;
|
|
354
|
+
export declare const getOrderInvoiceAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
355
|
+
invoice: {
|
|
356
|
+
number: string | null;
|
|
357
|
+
id: string;
|
|
358
|
+
createdAt: Date;
|
|
359
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
360
|
+
updatedAt: Date;
|
|
361
|
+
raw: unknown;
|
|
362
|
+
orderId: string;
|
|
363
|
+
provider: string;
|
|
364
|
+
kind: string;
|
|
365
|
+
externalId: string | null;
|
|
366
|
+
pdfUrl: string | null;
|
|
367
|
+
attempts: number;
|
|
368
|
+
nextRetryAt: Date | null;
|
|
369
|
+
lastError: string | null;
|
|
370
|
+
} | null;
|
|
371
|
+
invoicingEnabled: boolean;
|
|
372
|
+
}>;
|
|
373
|
+
export declare const issueInvoiceCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
374
|
+
orderId: string;
|
|
375
|
+
force?: boolean | undefined;
|
|
376
|
+
}, Promise<{
|
|
377
|
+
success: true;
|
|
378
|
+
invoice: {
|
|
379
|
+
number: string | null;
|
|
380
|
+
id: string;
|
|
381
|
+
createdAt: Date;
|
|
382
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
383
|
+
updatedAt: Date;
|
|
384
|
+
raw: unknown;
|
|
385
|
+
orderId: string;
|
|
386
|
+
provider: string;
|
|
387
|
+
kind: string;
|
|
388
|
+
externalId: string | null;
|
|
389
|
+
pdfUrl: string | null;
|
|
390
|
+
attempts: number;
|
|
391
|
+
nextRetryAt: Date | null;
|
|
392
|
+
lastError: string | null;
|
|
393
|
+
} | null;
|
|
394
|
+
error?: undefined;
|
|
395
|
+
} | {
|
|
396
|
+
success: false;
|
|
397
|
+
error: string;
|
|
398
|
+
invoice?: undefined;
|
|
399
|
+
}>>;
|
|
315
400
|
export declare const generateBalanceLinkForOrder: import("@sveltejs/kit").RemoteCommand<string, Promise<{
|
|
316
401
|
success: false;
|
|
317
402
|
error: string;
|
|
@@ -351,7 +436,7 @@ export declare const getCouponAdmin: import("@sveltejs/kit").RemoteQueryFunction
|
|
|
351
436
|
}>;
|
|
352
437
|
export declare const createCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
353
438
|
code: string;
|
|
354
|
-
type: "
|
|
439
|
+
type: "fixed" | "percent";
|
|
355
440
|
value: number;
|
|
356
441
|
minOrderAmount?: number | null | undefined;
|
|
357
442
|
maxUses?: number | null | undefined;
|
|
@@ -360,10 +445,10 @@ export declare const createCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
360
445
|
}, Promise<{
|
|
361
446
|
code: string;
|
|
362
447
|
id: string;
|
|
363
|
-
|
|
448
|
+
isActive: boolean;
|
|
364
449
|
createdAt: Date;
|
|
365
450
|
updatedAt: Date;
|
|
366
|
-
|
|
451
|
+
type: import("../../db-postgres/schema/shop/index.js").ShopCouponType;
|
|
367
452
|
expiresAt: Date | null;
|
|
368
453
|
value: string;
|
|
369
454
|
minOrderAmount: number | null;
|
|
@@ -374,7 +459,7 @@ export declare const updateCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
374
459
|
id: string;
|
|
375
460
|
input: {
|
|
376
461
|
code?: string | undefined;
|
|
377
|
-
type?: "
|
|
462
|
+
type?: "fixed" | "percent" | undefined;
|
|
378
463
|
value?: number | undefined;
|
|
379
464
|
minOrderAmount?: number | null | undefined;
|
|
380
465
|
maxUses?: number | null | undefined;
|
|
@@ -399,7 +484,7 @@ export declare const deleteCouponCmd: import("@sveltejs/kit").RemoteCommand<stri
|
|
|
399
484
|
}>>;
|
|
400
485
|
export declare const exportOrdersCsv: import("@sveltejs/kit").RemoteQueryFunction<{
|
|
401
486
|
status?: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected" | "refunded" | undefined;
|
|
402
|
-
|
|
487
|
+
search?: string | undefined;
|
|
403
488
|
} | undefined, {
|
|
404
489
|
csv: string;
|
|
405
490
|
count: number;
|
|
@@ -3,14 +3,16 @@ import z from 'zod';
|
|
|
3
3
|
import { getCMS } from '../../core/cms.js';
|
|
4
4
|
import { deleteShopData, getShopDataByEntry, listShopEntries, upsertShopData } from '../../shop/server/shop-data.js';
|
|
5
5
|
import { createShippingMethod, deleteShippingMethod, getShippingMethod, listShippingMethods, reorderShippingMethods, updateShippingMethod } from '../../shop/server/shipping.js';
|
|
6
|
-
import { countOrders, getOrderById, getOrderItems, getOrderStatusHistory, listOrders, updateOrderStatus } from '../../shop/server/orders.js';
|
|
6
|
+
import { countOrders, getOrderById, getOrderItems, getOrderStatusHistory, listOrders, OrderNotDeletableError, restoreOrder, softDeleteOrder, updateOrderStatus } from '../../shop/server/orders.js';
|
|
7
7
|
import { cancelShipmentForOrder, createShipmentForOrder } from '../../shop/server/shipments.js';
|
|
8
8
|
import { sendOrderStatusEmail } from '../../shop/server/email.js';
|
|
9
|
+
import { getOrderCoupon } from '../../shop/server/coupons.js';
|
|
10
|
+
import { getInvoiceByOrderId, issueInvoiceForOrder } from '../../shop/server/invoices.js';
|
|
9
11
|
import { getRefundedAmount, listRefunds, refundOrder, RefundError } from '../../shop/server/refund.js';
|
|
10
12
|
import { getShopDb } from '../../shop/server/db.js';
|
|
11
13
|
import { shopCouponsTable } from '../../db-postgres/schema/shop/index.js';
|
|
12
14
|
import { eq } from 'drizzle-orm';
|
|
13
|
-
import { requireAuth } from './middleware/auth.js';
|
|
15
|
+
import { requireAuth, requireRole } from './middleware/auth.js';
|
|
14
16
|
export const getShopEnabled = query(async () => {
|
|
15
17
|
return getCMS().shopConfig !== null;
|
|
16
18
|
});
|
|
@@ -137,18 +139,25 @@ const orderStatusSchema = z.enum([
|
|
|
137
139
|
export const listOrdersAdmin = query(z
|
|
138
140
|
.object({
|
|
139
141
|
status: orderStatusSchema.optional(),
|
|
140
|
-
|
|
142
|
+
search: z.string().trim().min(1).optional(),
|
|
141
143
|
limit: z.number().int().optional(),
|
|
142
|
-
offset: z.number().int().optional()
|
|
144
|
+
offset: z.number().int().optional(),
|
|
145
|
+
deleted: z.enum(['exclude', 'only', 'include']).optional()
|
|
143
146
|
})
|
|
144
147
|
.optional(), async (opts) => {
|
|
145
|
-
requireAuth();
|
|
146
148
|
const params = opts ?? {};
|
|
149
|
+
const deleted = params.deleted ?? 'exclude';
|
|
150
|
+
// The trash (soft-deleted orders) is admin-only; the normal list is for
|
|
151
|
+
// any authenticated admin-panel user.
|
|
152
|
+
if (deleted === 'exclude')
|
|
153
|
+
requireAuth();
|
|
154
|
+
else
|
|
155
|
+
requireRole('admin');
|
|
147
156
|
const limit = params.limit ?? 50;
|
|
148
157
|
const offset = params.offset ?? 0;
|
|
149
158
|
const [items, total] = await Promise.all([
|
|
150
|
-
listOrders({ ...params, limit, offset }),
|
|
151
|
-
countOrders({ status: params.status,
|
|
159
|
+
listOrders({ ...params, deleted, limit, offset }),
|
|
160
|
+
countOrders({ status: params.status, search: params.search, deleted })
|
|
152
161
|
]);
|
|
153
162
|
return { items, total, limit, offset };
|
|
154
163
|
});
|
|
@@ -157,8 +166,12 @@ export const getOrderForAdmin = query(z.string(), async (id) => {
|
|
|
157
166
|
const order = await getOrderById(id);
|
|
158
167
|
if (!order)
|
|
159
168
|
return null;
|
|
160
|
-
const [items, history] = await Promise.all([
|
|
161
|
-
|
|
169
|
+
const [items, history, coupon] = await Promise.all([
|
|
170
|
+
getOrderItems(id),
|
|
171
|
+
getOrderStatusHistory(id),
|
|
172
|
+
getOrderCoupon(id).catch(() => null)
|
|
173
|
+
]);
|
|
174
|
+
return { order, items, history, coupon };
|
|
162
175
|
});
|
|
163
176
|
export const updateOrderStatusCmd = command(z.object({
|
|
164
177
|
orderId: z.string(),
|
|
@@ -169,6 +182,25 @@ export const updateOrderStatusCmd = command(z.object({
|
|
|
169
182
|
const updated = await updateOrderStatus(orderId, status, { note, changedBy: 'admin' });
|
|
170
183
|
return updated;
|
|
171
184
|
});
|
|
185
|
+
export const deleteOrderCmd = command(z.object({ orderId: z.string() }), async ({ orderId }) => {
|
|
186
|
+
const { user } = requireRole('admin');
|
|
187
|
+
try {
|
|
188
|
+
await softDeleteOrder(orderId, user.id);
|
|
189
|
+
return { success: true };
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
if (err instanceof OrderNotDeletableError) {
|
|
193
|
+
return { success: false, reason: err.reason, error: err.message };
|
|
194
|
+
}
|
|
195
|
+
const message = err instanceof Error ? err.message : 'Nie udało się usunąć zamówienia';
|
|
196
|
+
return { success: false, reason: 'status', error: message };
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
export const restoreOrderCmd = command(z.object({ orderId: z.string() }), async ({ orderId }) => {
|
|
200
|
+
requireRole('admin');
|
|
201
|
+
await restoreOrder(orderId);
|
|
202
|
+
return { success: true };
|
|
203
|
+
});
|
|
172
204
|
export const resendOrderEmailCmd = command(z.object({ orderId: z.string(), status: orderStatusSchema }), async ({ orderId, status }) => {
|
|
173
205
|
requireAuth();
|
|
174
206
|
await sendOrderStatusEmail(orderId, status);
|
|
@@ -261,6 +293,23 @@ export const refundOrderCmd = command(z.object({
|
|
|
261
293
|
return { success: false, code: 'provider_error', error: message };
|
|
262
294
|
}
|
|
263
295
|
});
|
|
296
|
+
export const getOrderInvoiceAdmin = query(z.string(), async (orderId) => {
|
|
297
|
+
requireAuth();
|
|
298
|
+
const invoice = await getInvoiceByOrderId(orderId);
|
|
299
|
+
const invoicingEnabled = !!getCMS().shopConfig?.invoicing;
|
|
300
|
+
return { invoice, invoicingEnabled };
|
|
301
|
+
});
|
|
302
|
+
export const issueInvoiceCmd = command(z.object({ orderId: z.string(), force: z.boolean().optional() }), async ({ orderId, force }) => {
|
|
303
|
+
requireAuth();
|
|
304
|
+
try {
|
|
305
|
+
const invoice = await issueInvoiceForOrder(orderId, { force });
|
|
306
|
+
return { success: true, invoice };
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
const message = err instanceof Error ? err.message : 'Invoice issuance failed';
|
|
310
|
+
return { success: false, error: message };
|
|
311
|
+
}
|
|
312
|
+
});
|
|
264
313
|
export const generateBalanceLinkForOrder = command(z.string(), async (orderId) => {
|
|
265
314
|
requireAuth();
|
|
266
315
|
const { generateBalanceToken, requireBalanceTokenSecret } = await import('../../shop/server/balance-payment.js');
|
|
@@ -375,7 +424,7 @@ function csvEscape(value) {
|
|
|
375
424
|
const exportFiltersSchema = z
|
|
376
425
|
.object({
|
|
377
426
|
status: orderStatusSchema.optional(),
|
|
378
|
-
|
|
427
|
+
search: z.string().trim().min(1).optional()
|
|
379
428
|
})
|
|
380
429
|
.optional();
|
|
381
430
|
export const exportOrdersCsv = query(exportFiltersSchema, async (opts) => {
|
package/dist/admin/types.d.ts
CHANGED
|
@@ -8,3 +8,18 @@ export interface Breadcrumb {
|
|
|
8
8
|
label: string;
|
|
9
9
|
href?: string;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* One additional sidebar entry rendered below built-in nav sections
|
|
13
|
+
* (Dashboard, Collections, Singles, Forms, Shop). Configure via
|
|
14
|
+
* `defineConfig({ admin: { extraNavItems: [...] } })` — see CMSConfig.
|
|
15
|
+
*
|
|
16
|
+
* Icons are intentionally omitted from the public surface to keep userland
|
|
17
|
+
* free of `@tabler/icons-svelte` (or any specific icon library) as a
|
|
18
|
+
* dependency. The sidebar renders the title alone when no icon is provided.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export interface AdminNavItem {
|
|
23
|
+
title: string;
|
|
24
|
+
url: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a CSV string from `headers` and `rows`. Values are escaped per
|
|
3
|
+
* RFC 4180: any cell containing `"`, `,`, `;`, `\n`, or `\r` is wrapped in
|
|
4
|
+
* double quotes and embedded `"` are doubled. `null` / `undefined` become
|
|
5
|
+
* empty cells. Lines are joined with CRLF.
|
|
6
|
+
*
|
|
7
|
+
* Pure (no DOM access) — safe on the server. Use together with
|
|
8
|
+
* `downloadCsv()` on the client, or return as a `Response` from a server
|
|
9
|
+
* action.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildCsv(opts: {
|
|
14
|
+
headers: string[];
|
|
15
|
+
rows: (string | number | null | undefined)[][];
|
|
16
|
+
}): string;
|
|
17
|
+
/**
|
|
18
|
+
* Trigger a client-side CSV download. Wraps the given `csv` string in a
|
|
19
|
+
* `Blob` with `text/csv;charset=utf-8` and clicks a synthetic
|
|
20
|
+
* `<a download>`. Prepends a UTF-8 BOM (``) unless one is already
|
|
21
|
+
* present, so Excel honors UTF-8 (PL diacritics).
|
|
22
|
+
*
|
|
23
|
+
* Must be called from a browser context — relies on `document`, `Blob`,
|
|
24
|
+
* and `URL.createObjectURL`. Throws when called server-side.
|
|
25
|
+
*
|
|
26
|
+
* Typical wiring: server returns a precomposed CSV (e.g. via a
|
|
27
|
+
* `query()` remote like `exportOrdersCsv`) → client calls
|
|
28
|
+
* `downloadCsv({ filename, csv: result.csv })`.
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { buildCsv, downloadCsv } from 'includio-cms/admin/client';
|
|
34
|
+
*
|
|
35
|
+
* const csv = buildCsv({
|
|
36
|
+
* headers: ['email', 'name', 'consentedAt'],
|
|
37
|
+
* rows: items.map((i) => [i.email, i.name, i.consentedAt])
|
|
38
|
+
* });
|
|
39
|
+
* downloadCsv({ filename: 'newsletter-2026-06-02.csv', csv });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function downloadCsv(opts: {
|
|
43
|
+
filename: string;
|
|
44
|
+
csv: string;
|
|
45
|
+
}): void;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a CSV string from `headers` and `rows`. Values are escaped per
|
|
3
|
+
* RFC 4180: any cell containing `"`, `,`, `;`, `\n`, or `\r` is wrapped in
|
|
4
|
+
* double quotes and embedded `"` are doubled. `null` / `undefined` become
|
|
5
|
+
* empty cells. Lines are joined with CRLF.
|
|
6
|
+
*
|
|
7
|
+
* Pure (no DOM access) — safe on the server. Use together with
|
|
8
|
+
* `downloadCsv()` on the client, or return as a `Response` from a server
|
|
9
|
+
* action.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export function buildCsv(opts) {
|
|
14
|
+
const escape = (v) => {
|
|
15
|
+
const s = v == null ? '' : String(v);
|
|
16
|
+
return /["\n\r,;]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
17
|
+
};
|
|
18
|
+
const lines = [opts.headers, ...opts.rows].map((row) => row.map(escape).join(','));
|
|
19
|
+
return lines.join('\r\n');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Trigger a client-side CSV download. Wraps the given `csv` string in a
|
|
23
|
+
* `Blob` with `text/csv;charset=utf-8` and clicks a synthetic
|
|
24
|
+
* `<a download>`. Prepends a UTF-8 BOM (``) unless one is already
|
|
25
|
+
* present, so Excel honors UTF-8 (PL diacritics).
|
|
26
|
+
*
|
|
27
|
+
* Must be called from a browser context — relies on `document`, `Blob`,
|
|
28
|
+
* and `URL.createObjectURL`. Throws when called server-side.
|
|
29
|
+
*
|
|
30
|
+
* Typical wiring: server returns a precomposed CSV (e.g. via a
|
|
31
|
+
* `query()` remote like `exportOrdersCsv`) → client calls
|
|
32
|
+
* `downloadCsv({ filename, csv: result.csv })`.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { buildCsv, downloadCsv } from 'includio-cms/admin/client';
|
|
38
|
+
*
|
|
39
|
+
* const csv = buildCsv({
|
|
40
|
+
* headers: ['email', 'name', 'consentedAt'],
|
|
41
|
+
* rows: items.map((i) => [i.email, i.name, i.consentedAt])
|
|
42
|
+
* });
|
|
43
|
+
* downloadCsv({ filename: 'newsletter-2026-06-02.csv', csv });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function downloadCsv(opts) {
|
|
47
|
+
if (typeof document === 'undefined') {
|
|
48
|
+
throw new Error('[includio-cms] downloadCsv() must be called from a browser context.');
|
|
49
|
+
}
|
|
50
|
+
const csv = opts.csv.startsWith('') ? opts.csv : '' + opts.csv;
|
|
51
|
+
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
|
|
52
|
+
const url = URL.createObjectURL(blob);
|
|
53
|
+
const a = document.createElement('a');
|
|
54
|
+
a.href = url;
|
|
55
|
+
a.download = opts.filename;
|
|
56
|
+
a.style.display = 'none';
|
|
57
|
+
document.body.appendChild(a);
|
|
58
|
+
a.click();
|
|
59
|
+
document.body.removeChild(a);
|
|
60
|
+
URL.revokeObjectURL(url);
|
|
61
|
+
}
|
|
@@ -348,7 +348,7 @@ export const { GET, POST, PUT, DELETE } = createRestApiHandler();
|
|
|
348
348
|
import { json } from '@sveltejs/kit';
|
|
349
349
|
import type { RequestHandler } from './$types';
|
|
350
350
|
import { createFormSubmission, parseFormDataForSubmission } from 'includio-cms/sveltekit/server';
|
|
351
|
-
import { getCMS } from 'includio-cms/core';
|
|
351
|
+
import { getCMS } from 'includio-cms/core/server';
|
|
352
352
|
|
|
353
353
|
const counts = new Map<string, { count: number; resetAt: number }>();
|
|
354
354
|
const LIMIT = 5;
|
|
@@ -8,6 +8,6 @@ type Props = WithElementRef<Omit<HTMLInputAttributes, "type"> & ({
|
|
|
8
8
|
type?: InputType;
|
|
9
9
|
files?: undefined;
|
|
10
10
|
})>;
|
|
11
|
-
declare const Input: import("svelte").Component<Props, {}, "
|
|
11
|
+
declare const Input: import("svelte").Component<Props, {}, "ref" | "files" | "value">;
|
|
12
12
|
type Input = ReturnType<typeof Input>;
|
|
13
13
|
export default Input;
|
|
@@ -2,7 +2,7 @@ declare const InputGroupInput: import("svelte").Component<(Omit<import("svelte/e
|
|
|
2
2
|
type: "file";
|
|
3
3
|
files?: FileList;
|
|
4
4
|
} | {
|
|
5
|
-
type?: "number" | "image" | "url" | "text" | "date" | "
|
|
5
|
+
type?: "number" | "image" | "url" | "text" | "date" | "search" | "radio" | "color" | "button" | "checkbox" | (string & {}) | "email" | "tel" | "password" | "time" | "month" | "hidden" | "reset" | "submit" | "datetime-local" | "range" | "week";
|
|
6
6
|
files?: undefined;
|
|
7
7
|
})) & {
|
|
8
8
|
ref?: HTMLElement | null | undefined;
|
|
@@ -2,7 +2,7 @@ declare const SidebarInput: import("svelte").Component<(Omit<import("svelte/elem
|
|
|
2
2
|
type: "file";
|
|
3
3
|
files?: FileList;
|
|
4
4
|
} | {
|
|
5
|
-
type?: "number" | "image" | "url" | "text" | "date" | "
|
|
5
|
+
type?: "number" | "image" | "url" | "text" | "date" | "search" | "radio" | "color" | "button" | "checkbox" | (string & {}) | "email" | "tel" | "password" | "time" | "month" | "hidden" | "reset" | "submit" | "datetime-local" | "range" | "week";
|
|
6
6
|
files?: undefined;
|
|
7
7
|
})) & {
|
|
8
8
|
ref?: HTMLElement | null | undefined;
|
package/dist/core/cms.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../types/adapters/db.js';
|
|
2
2
|
import type { FilesAdapter } from '../types/adapters/files.js';
|
|
3
|
-
import type { ApiKeyConfig, AuthConfig, CMSConfig, ICMS, MediaConfig, TypographyConfig } from '../types/cms.js';
|
|
3
|
+
import type { AdminConfig, ApiKeyConfig, AuthConfig, CMSConfig, ICMS, MediaConfig, TypographyConfig } from '../types/cms.js';
|
|
4
4
|
import type { CollectionConfigWithType } from '../types/collections.js';
|
|
5
5
|
import type { Language } from '../types/languages.js';
|
|
6
6
|
import type { SingleConfigWithType } from '../types/singles.js';
|
|
7
7
|
import type { CustomFieldDefinition, IconSetPlugin, Plugin } from '../types/plugins.js';
|
|
8
8
|
import type { FormConfig } from '../types/forms.js';
|
|
9
9
|
import type { AIAdapter } from '../types/adapters/ai.js';
|
|
10
|
-
import type { EmailAdapter } from '../types/adapters/email.js';
|
|
10
|
+
import type { EmailAdapter, SendMailOptions } from '../types/adapters/email.js';
|
|
11
11
|
import { betterAuth } from 'better-auth';
|
|
12
12
|
import type { ResolvedShopConfig } from '../shop/types.js';
|
|
13
13
|
import type { ResolvedCmpConfig } from '../cmp/types.js';
|
|
@@ -28,6 +28,7 @@ export declare class CMS implements ICMS {
|
|
|
28
28
|
sidebarHelp: boolean;
|
|
29
29
|
shopConfig: ResolvedShopConfig | null;
|
|
30
30
|
cmpConfig: ResolvedCmpConfig | null;
|
|
31
|
+
adminConfig: AdminConfig | null;
|
|
31
32
|
/**
|
|
32
33
|
* Resolves once the shop's variant-attribute GIN indexes have been applied
|
|
33
34
|
* by `initCMS()`. `null` when the CMS is configured without a shop. Tests
|
|
@@ -64,3 +65,44 @@ export declare function initCMS(config: CMSConfig): CMS;
|
|
|
64
65
|
* ```
|
|
65
66
|
*/
|
|
66
67
|
export declare function getCMS(): CMS;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the configured email adapter from the active CMS singleton, or
|
|
70
|
+
* `null` when no `email` was passed to `defineConfig`. Use this in userland
|
|
71
|
+
* hooks (e.g. `ShopConfig.onOrderPaid`) to reuse the same SMTP transport the
|
|
72
|
+
* CMS already opened — no second nodemailer instance, no duplicated ENV.
|
|
73
|
+
*
|
|
74
|
+
* @returns The current `EmailAdapter` or `null`.
|
|
75
|
+
* @throws {Error} when called before `initCMS()` has run.
|
|
76
|
+
* @public
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { getMailer } from 'includio-cms/core';
|
|
80
|
+
*
|
|
81
|
+
* const mailer = getMailer();
|
|
82
|
+
* if (mailer) await mailer.sendMail({ to: 'admin@…', subject: '…', html: '…' });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function getMailer(): EmailAdapter | null;
|
|
86
|
+
/**
|
|
87
|
+
* Send an email through the configured CMS email adapter. Thin convenience
|
|
88
|
+
* wrapper around `getCMS().emailAdapter.sendMail` — same options shape, same
|
|
89
|
+
* From address, same SMTP transport as the built-in flows (reset password,
|
|
90
|
+
* shop order status, form notifications).
|
|
91
|
+
*
|
|
92
|
+
* @throws {Error} when no email adapter is configured (matches
|
|
93
|
+
* `defineConfig({ email: ... })` not being set) or when the CMS has not
|
|
94
|
+
* been initialized yet.
|
|
95
|
+
* @public
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { sendMail } from 'includio-cms/core';
|
|
99
|
+
*
|
|
100
|
+
* await sendMail({
|
|
101
|
+
* to: process.env.ADMIN_EMAIL!,
|
|
102
|
+
* subject: '[shop] New consent',
|
|
103
|
+
* text: 'Plain fallback for clients that prefer text.',
|
|
104
|
+
* html: '<p>Body…</p>'
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function sendMail(options: SendMailOptions): Promise<void>;
|