includio-cms 0.28.0 → 0.34.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 +39 -13
- package/CHANGELOG.md +19 -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 +2209 -2209
- 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 +71 -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 +4 -4
- package/dist/admin/remote/index.d.ts +1 -0
- package/dist/admin/remote/index.js +1 -0
- package/dist/admin/remote/invite.d.ts +2 -2
- package/dist/admin/remote/shop.remote.d.ts +75 -48
- package/dist/admin/remote/shop.remote.js +41 -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/button-group/button-group-separator.svelte.d.ts +1 -1
- package/dist/components/ui/command/command.svelte.d.ts +1 -1
- package/dist/components/ui/field/field-label.svelte.d.ts +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/item/item-separator.svelte.d.ts +1 -1
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-separator.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 +1 -4
- package/dist/core/index.js +4 -4
- package/dist/core/server/index.d.ts +4 -1
- package/dist/core/server/index.js +4 -1
- package/dist/db-postgres/schema/shop/order.d.ts +34 -0
- package/dist/db-postgres/schema/shop/order.js +4 -0
- package/dist/paraglide/messages/_index.d.ts +3 -36
- package/dist/paraglide/messages/_index.js +3 -71
- package/dist/paraglide/messages/hello_world.d.ts +5 -0
- package/dist/paraglide/messages/hello_world.js +33 -0
- package/dist/paraglide/messages/login_hello.d.ts +16 -0
- package/dist/paraglide/messages/login_hello.js +34 -0
- package/dist/paraglide/messages/login_please_login.d.ts +16 -0
- package/dist/paraglide/messages/login_please_login.js +34 -0
- package/dist/shop/adapters/fakturownia/client.d.ts +5 -0
- package/dist/shop/adapters/fakturownia/client.js +20 -0
- package/dist/shop/adapters/fakturownia/index.js +11 -0
- package/dist/shop/adapters/payu/index.js +11 -0
- package/dist/shop/index.d.ts +1 -1
- 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/orders.d.ts +60 -1
- package/dist/shop/server/orders.js +145 -16
- 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 +63 -0
- package/dist/sveltekit/index.d.ts +0 -1
- package/dist/sveltekit/index.js +0 -1
- package/dist/sveltekit/server/index.d.ts +2 -0
- package/dist/sveltekit/server/index.js +4 -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.34.0/index.d.ts +2 -0
- package/dist/updates/0.34.0/index.js +17 -0
- package/dist/updates/index.js +3 -1
- package/package.json +7 -2
- package/dist/paraglide/messages/en.d.ts +0 -5
- package/dist/paraglide/messages/en.js +0 -14
- package/dist/paraglide/messages/pl.d.ts +0 -5
- package/dist/paraglide/messages/pl.js +0 -14
|
@@ -93,24 +93,18 @@ 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?: "only" | "include" | "exclude" | 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;
|
|
@@ -132,10 +126,19 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
|
|
|
132
126
|
shipmentCreatedAt: Date | null;
|
|
133
127
|
paymentMethod: string | null;
|
|
134
128
|
paymentProviderRef: string | null;
|
|
129
|
+
consents: {
|
|
130
|
+
id: string;
|
|
131
|
+
accepted: boolean;
|
|
132
|
+
label: string;
|
|
133
|
+
}[] | null;
|
|
135
134
|
notes: string | null;
|
|
135
|
+
language: string | null;
|
|
136
136
|
accessToken: string;
|
|
137
137
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
138
138
|
balanceOwed: boolean;
|
|
139
|
+
deletedAt: Date | null;
|
|
140
|
+
deletedBy: string | null;
|
|
141
|
+
updatedAt: Date;
|
|
139
142
|
}[];
|
|
140
143
|
total: number;
|
|
141
144
|
limit: number;
|
|
@@ -144,18 +147,11 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
|
|
|
144
147
|
export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
145
148
|
order: {
|
|
146
149
|
number: string;
|
|
147
|
-
currency: string;
|
|
148
|
-
consents: {
|
|
149
|
-
id: string;
|
|
150
|
-
accepted: boolean;
|
|
151
|
-
label: string;
|
|
152
|
-
}[] | null;
|
|
153
150
|
id: string;
|
|
154
|
-
status: import("../../shop/types.js").OrderStatus;
|
|
155
|
-
createdAt: Date;
|
|
156
|
-
updatedAt: Date;
|
|
157
|
-
language: string | null;
|
|
158
151
|
carrierType: string | null;
|
|
152
|
+
createdAt: Date;
|
|
153
|
+
status: import("../../shop/types.js").OrderStatus;
|
|
154
|
+
currency: string;
|
|
159
155
|
customerEmail: string;
|
|
160
156
|
customerName: string | null;
|
|
161
157
|
customerPhone: string | null;
|
|
@@ -177,10 +173,19 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
|
|
|
177
173
|
shipmentCreatedAt: Date | null;
|
|
178
174
|
paymentMethod: string | null;
|
|
179
175
|
paymentProviderRef: string | null;
|
|
176
|
+
consents: {
|
|
177
|
+
id: string;
|
|
178
|
+
accepted: boolean;
|
|
179
|
+
label: string;
|
|
180
|
+
}[] | null;
|
|
180
181
|
notes: string | null;
|
|
182
|
+
language: string | null;
|
|
181
183
|
accessToken: string;
|
|
182
184
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
183
185
|
balanceOwed: boolean;
|
|
186
|
+
deletedAt: Date | null;
|
|
187
|
+
deletedBy: string | null;
|
|
188
|
+
updatedAt: Date;
|
|
184
189
|
};
|
|
185
190
|
items: {
|
|
186
191
|
id: string;
|
|
@@ -196,12 +201,16 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
|
|
|
196
201
|
}[];
|
|
197
202
|
history: {
|
|
198
203
|
id: string;
|
|
199
|
-
note: string | null;
|
|
200
204
|
status: import("../../shop/types.js").OrderStatus;
|
|
205
|
+
note: string | null;
|
|
201
206
|
orderId: string;
|
|
202
207
|
changedBy: string | null;
|
|
203
208
|
changedAt: Date;
|
|
204
209
|
}[];
|
|
210
|
+
coupon: {
|
|
211
|
+
code: string;
|
|
212
|
+
discountAmount: number;
|
|
213
|
+
} | null;
|
|
205
214
|
} | null>;
|
|
206
215
|
export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
207
216
|
orderId: string;
|
|
@@ -209,18 +218,11 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
|
|
|
209
218
|
note?: string | undefined;
|
|
210
219
|
}, Promise<{
|
|
211
220
|
number: string;
|
|
212
|
-
currency: string;
|
|
213
|
-
consents: {
|
|
214
|
-
id: string;
|
|
215
|
-
accepted: boolean;
|
|
216
|
-
label: string;
|
|
217
|
-
}[] | null;
|
|
218
221
|
id: string;
|
|
219
|
-
status: import("../../shop/types.js").OrderStatus;
|
|
220
|
-
createdAt: Date;
|
|
221
|
-
updatedAt: Date;
|
|
222
|
-
language: string | null;
|
|
223
222
|
carrierType: string | null;
|
|
223
|
+
createdAt: Date;
|
|
224
|
+
status: import("../../shop/types.js").OrderStatus;
|
|
225
|
+
currency: string;
|
|
224
226
|
customerEmail: string;
|
|
225
227
|
customerName: string | null;
|
|
226
228
|
customerPhone: string | null;
|
|
@@ -242,10 +244,35 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
|
|
|
242
244
|
shipmentCreatedAt: Date | null;
|
|
243
245
|
paymentMethod: string | null;
|
|
244
246
|
paymentProviderRef: string | null;
|
|
247
|
+
consents: {
|
|
248
|
+
id: string;
|
|
249
|
+
accepted: boolean;
|
|
250
|
+
label: string;
|
|
251
|
+
}[] | null;
|
|
245
252
|
notes: string | null;
|
|
253
|
+
language: string | null;
|
|
246
254
|
accessToken: string;
|
|
247
255
|
partialPayment: import("../../shop/types.js").PartialPayment | null;
|
|
248
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;
|
|
249
276
|
}>>;
|
|
250
277
|
export declare const resendOrderEmailCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
251
278
|
orderId: string;
|
|
@@ -286,18 +313,18 @@ export declare const listShopableCollections: import("@sveltejs/kit").RemoteQuer
|
|
|
286
313
|
}[]>;
|
|
287
314
|
export declare const getOrderRefundsAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
288
315
|
refunds: {
|
|
289
|
-
amount: number;
|
|
290
|
-
currency: string;
|
|
291
316
|
id: string;
|
|
292
|
-
status: import("../../db-postgres/schema/shop/index.js").ShopRefundStatus;
|
|
293
317
|
createdAt: Date;
|
|
318
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopRefundStatus;
|
|
319
|
+
currency: string;
|
|
294
320
|
updatedAt: Date;
|
|
295
|
-
|
|
321
|
+
amount: number;
|
|
296
322
|
provider: string;
|
|
323
|
+
createdBy: string | null;
|
|
324
|
+
orderId: string;
|
|
297
325
|
providerRef: string | null;
|
|
298
326
|
paymentId: string | null;
|
|
299
327
|
reason: string | null;
|
|
300
|
-
createdBy: string | null;
|
|
301
328
|
}[];
|
|
302
329
|
refundedAmount: number;
|
|
303
330
|
remainingRefundable: number;
|
|
@@ -327,13 +354,13 @@ export declare const refundOrderCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
327
354
|
export declare const getOrderInvoiceAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
|
|
328
355
|
invoice: {
|
|
329
356
|
number: string | null;
|
|
330
|
-
raw: unknown;
|
|
331
357
|
id: string;
|
|
332
|
-
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
333
358
|
createdAt: Date;
|
|
359
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
334
360
|
updatedAt: Date;
|
|
335
|
-
|
|
361
|
+
raw: unknown;
|
|
336
362
|
provider: string;
|
|
363
|
+
orderId: string;
|
|
337
364
|
kind: string;
|
|
338
365
|
externalId: string | null;
|
|
339
366
|
pdfUrl: string | null;
|
|
@@ -350,13 +377,13 @@ export declare const issueInvoiceCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
350
377
|
success: true;
|
|
351
378
|
invoice: {
|
|
352
379
|
number: string | null;
|
|
353
|
-
raw: unknown;
|
|
354
380
|
id: string;
|
|
355
|
-
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
356
381
|
createdAt: Date;
|
|
382
|
+
status: import("../../db-postgres/schema/shop/index.js").ShopInvoiceStatus;
|
|
357
383
|
updatedAt: Date;
|
|
358
|
-
|
|
384
|
+
raw: unknown;
|
|
359
385
|
provider: string;
|
|
386
|
+
orderId: string;
|
|
360
387
|
kind: string;
|
|
361
388
|
externalId: string | null;
|
|
362
389
|
pdfUrl: string | null;
|
|
@@ -409,7 +436,7 @@ export declare const getCouponAdmin: import("@sveltejs/kit").RemoteQueryFunction
|
|
|
409
436
|
}>;
|
|
410
437
|
export declare const createCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
411
438
|
code: string;
|
|
412
|
-
type: "
|
|
439
|
+
type: "fixed" | "percent";
|
|
413
440
|
value: number;
|
|
414
441
|
minOrderAmount?: number | null | undefined;
|
|
415
442
|
maxUses?: number | null | undefined;
|
|
@@ -418,12 +445,12 @@ export declare const createCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
418
445
|
}, Promise<{
|
|
419
446
|
code: string;
|
|
420
447
|
id: string;
|
|
421
|
-
|
|
448
|
+
isActive: boolean;
|
|
422
449
|
createdAt: Date;
|
|
423
450
|
updatedAt: Date;
|
|
424
|
-
isActive: boolean;
|
|
425
451
|
expiresAt: Date | null;
|
|
426
452
|
value: string;
|
|
453
|
+
type: import("../../db-postgres/schema/shop/index.js").ShopCouponType;
|
|
427
454
|
minOrderAmount: number | null;
|
|
428
455
|
maxUses: number | null;
|
|
429
456
|
usedCount: number;
|
|
@@ -432,7 +459,7 @@ export declare const updateCouponCmd: import("@sveltejs/kit").RemoteCommand<{
|
|
|
432
459
|
id: string;
|
|
433
460
|
input: {
|
|
434
461
|
code?: string | undefined;
|
|
435
|
-
type?: "
|
|
462
|
+
type?: "fixed" | "percent" | undefined;
|
|
436
463
|
value?: number | undefined;
|
|
437
464
|
minOrderAmount?: number | null | undefined;
|
|
438
465
|
maxUses?: number | null | undefined;
|
|
@@ -457,7 +484,7 @@ export declare const deleteCouponCmd: import("@sveltejs/kit").RemoteCommand<stri
|
|
|
457
484
|
}>>;
|
|
458
485
|
export declare const exportOrdersCsv: import("@sveltejs/kit").RemoteQueryFunction<{
|
|
459
486
|
status?: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected" | "refunded" | undefined;
|
|
460
|
-
|
|
487
|
+
search?: string | undefined;
|
|
461
488
|
} | undefined, {
|
|
462
489
|
csv: string;
|
|
463
490
|
count: number;
|
|
@@ -3,15 +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';
|
|
9
10
|
import { getInvoiceByOrderId, issueInvoiceForOrder } from '../../shop/server/invoices.js';
|
|
10
11
|
import { getRefundedAmount, listRefunds, refundOrder, RefundError } from '../../shop/server/refund.js';
|
|
11
12
|
import { getShopDb } from '../../shop/server/db.js';
|
|
12
13
|
import { shopCouponsTable } from '../../db-postgres/schema/shop/index.js';
|
|
13
14
|
import { eq } from 'drizzle-orm';
|
|
14
|
-
import { requireAuth } from './middleware/auth.js';
|
|
15
|
+
import { requireAuth, requireRole } from './middleware/auth.js';
|
|
15
16
|
export const getShopEnabled = query(async () => {
|
|
16
17
|
return getCMS().shopConfig !== null;
|
|
17
18
|
});
|
|
@@ -138,18 +139,25 @@ const orderStatusSchema = z.enum([
|
|
|
138
139
|
export const listOrdersAdmin = query(z
|
|
139
140
|
.object({
|
|
140
141
|
status: orderStatusSchema.optional(),
|
|
141
|
-
|
|
142
|
+
search: z.string().trim().min(1).optional(),
|
|
142
143
|
limit: z.number().int().optional(),
|
|
143
|
-
offset: z.number().int().optional()
|
|
144
|
+
offset: z.number().int().optional(),
|
|
145
|
+
deleted: z.enum(['exclude', 'only', 'include']).optional()
|
|
144
146
|
})
|
|
145
147
|
.optional(), async (opts) => {
|
|
146
|
-
requireAuth();
|
|
147
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');
|
|
148
156
|
const limit = params.limit ?? 50;
|
|
149
157
|
const offset = params.offset ?? 0;
|
|
150
158
|
const [items, total] = await Promise.all([
|
|
151
|
-
listOrders({ ...params, limit, offset }),
|
|
152
|
-
countOrders({ status: params.status,
|
|
159
|
+
listOrders({ ...params, deleted, limit, offset }),
|
|
160
|
+
countOrders({ status: params.status, search: params.search, deleted })
|
|
153
161
|
]);
|
|
154
162
|
return { items, total, limit, offset };
|
|
155
163
|
});
|
|
@@ -158,8 +166,12 @@ export const getOrderForAdmin = query(z.string(), async (id) => {
|
|
|
158
166
|
const order = await getOrderById(id);
|
|
159
167
|
if (!order)
|
|
160
168
|
return null;
|
|
161
|
-
const [items, history] = await Promise.all([
|
|
162
|
-
|
|
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 };
|
|
163
175
|
});
|
|
164
176
|
export const updateOrderStatusCmd = command(z.object({
|
|
165
177
|
orderId: z.string(),
|
|
@@ -170,6 +182,25 @@ export const updateOrderStatusCmd = command(z.object({
|
|
|
170
182
|
const updated = await updateOrderStatus(orderId, status, { note, changedBy: 'admin' });
|
|
171
183
|
return updated;
|
|
172
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
|
+
});
|
|
173
204
|
export const resendOrderEmailCmd = command(z.object({ orderId: z.string(), status: orderStatusSchema }), async ({ orderId, status }) => {
|
|
174
205
|
requireAuth();
|
|
175
206
|
await sendOrderStatusEmail(orderId, status);
|
|
@@ -393,7 +424,7 @@ function csvEscape(value) {
|
|
|
393
424
|
const exportFiltersSchema = z
|
|
394
425
|
.object({
|
|
395
426
|
status: orderStatusSchema.optional(),
|
|
396
|
-
|
|
427
|
+
search: z.string().trim().min(1).optional()
|
|
397
428
|
})
|
|
398
429
|
.optional();
|
|
399
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;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const ButtonGroupSeparator: import("svelte").Component<Omit<{
|
|
2
2
|
orientation?: import("bits-ui").Orientation;
|
|
3
3
|
decorative?: boolean;
|
|
4
|
-
}, "
|
|
4
|
+
}, "child" | "children"> & {
|
|
5
5
|
child?: import("svelte").Snippet<[{
|
|
6
6
|
props: Record<string, unknown>;
|
|
7
7
|
}]> | undefined;
|
|
@@ -3,6 +3,6 @@ export type CommandRootApi = CommandPrimitive.Root;
|
|
|
3
3
|
type $$ComponentProps = CommandPrimitive.RootProps & {
|
|
4
4
|
api?: CommandRootApi | null;
|
|
5
5
|
};
|
|
6
|
-
declare const Command: import("svelte").Component<$$ComponentProps, {}, "ref" | "
|
|
6
|
+
declare const Command: import("svelte").Component<$$ComponentProps, {}, "ref" | "api" | "value">;
|
|
7
7
|
type Command = ReturnType<typeof Command>;
|
|
8
8
|
export default Command;
|
|
@@ -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" | "value" | "files">;
|
|
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" | "hidden" | "email" | "password" | (string & {}) | "reset" | "color" | "button" | "checkbox" | "tel" | "time" | "month" | "submit" | "datetime-local" | "range" | "week";
|
|
6
6
|
files?: undefined;
|
|
7
7
|
})) & {
|
|
8
8
|
ref?: HTMLElement | null | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const ItemSeparator: import("svelte").Component<Omit<{
|
|
2
2
|
orientation?: import("bits-ui").Orientation;
|
|
3
3
|
decorative?: boolean;
|
|
4
|
-
}, "
|
|
4
|
+
}, "child" | "children"> & {
|
|
5
5
|
child?: import("svelte").Snippet<[{
|
|
6
6
|
props: Record<string, unknown>;
|
|
7
7
|
}]> | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const SelectGroupHeading: import("svelte").Component<Omit<{}, "
|
|
1
|
+
declare const SelectGroupHeading: import("svelte").Component<Omit<{}, "child" | "children"> & {
|
|
2
2
|
child?: import("svelte").Snippet<[{
|
|
3
3
|
props: Record<string, unknown>;
|
|
4
4
|
}]> | 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" | "hidden" | "email" | "password" | (string & {}) | "reset" | "color" | "button" | "checkbox" | "tel" | "time" | "month" | "submit" | "datetime-local" | "range" | "week";
|
|
6
6
|
files?: undefined;
|
|
7
7
|
})) & {
|
|
8
8
|
ref?: HTMLElement | null | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const SidebarSeparator: import("svelte").Component<Omit<{
|
|
2
2
|
orientation?: import("bits-ui").Orientation;
|
|
3
3
|
decorative?: boolean;
|
|
4
|
-
}, "
|
|
4
|
+
}, "child" | "children"> & {
|
|
5
5
|
child?: import("svelte").Snippet<[{
|
|
6
6
|
props: Record<string, unknown>;
|
|
7
7
|
}]> | 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>;
|