@fayz-ai/shop 0.9.0 → 0.11.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/README.md +18 -1
- package/dist/admin.d.ts +2 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/catalog.d.ts +1 -3
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +2 -2
- package/dist/{chunk-IYQHKMLB.js → chunk-2WACO2TG.js} +4 -4
- package/dist/chunk-2WACO2TG.js.map +1 -0
- package/dist/chunk-3GERSY5F.js +526 -0
- package/dist/chunk-3GERSY5F.js.map +1 -0
- package/dist/chunk-6BO2TMZ5.js +93 -0
- package/dist/chunk-6BO2TMZ5.js.map +1 -0
- package/dist/chunk-FQPGE3YN.js +3 -0
- package/dist/{chunk-JR25TISO.js.map → chunk-FQPGE3YN.js.map} +1 -1
- package/dist/{chunk-CTKZ6O2J.js → chunk-IKNGCRUM.js} +41 -15
- package/dist/chunk-IKNGCRUM.js.map +1 -0
- package/dist/chunk-KLDS7IPU.js +17 -0
- package/dist/chunk-KLDS7IPU.js.map +1 -0
- package/dist/chunk-NWW3WJ7Y.js +136 -0
- package/dist/chunk-NWW3WJ7Y.js.map +1 -0
- package/dist/chunk-STRNMFC4.js +1438 -0
- package/dist/chunk-STRNMFC4.js.map +1 -0
- package/dist/chunk-U6HV3LVP.js +1170 -0
- package/dist/chunk-U6HV3LVP.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/data/customer-search.d.ts +3 -0
- package/dist/data/customer-search.d.ts.map +1 -0
- package/dist/data/functions.d.ts +9 -0
- package/dist/data/functions.d.ts.map +1 -0
- package/dist/data/media.d.ts +37 -0
- package/dist/data/media.d.ts.map +1 -0
- package/dist/{mock-catalog.d.ts → data/mock-catalog.d.ts} +21 -1
- package/dist/data/mock-catalog.d.ts.map +1 -0
- package/dist/data/mock-provider.d.ts +165 -0
- package/dist/data/mock-provider.d.ts.map +1 -0
- package/dist/data/mock.d.ts +3 -0
- package/dist/data/mock.d.ts.map +1 -0
- package/dist/data/provider.d.ts +335 -0
- package/dist/data/provider.d.ts.map +1 -0
- package/dist/data/supabase-provider.d.ts +208 -0
- package/dist/data/supabase-provider.d.ts.map +1 -0
- package/dist/data/tables.d.ts +38 -0
- package/dist/data/tables.d.ts.map +1 -0
- package/dist/data/tenant.d.ts.map +1 -0
- package/dist/entities/entity-reconcile.d.ts +32 -0
- package/dist/entities/entity-reconcile.d.ts.map +1 -0
- package/dist/entities/entity-sql.d.ts +50 -0
- package/dist/entities/entity-sql.d.ts.map +1 -0
- package/dist/entities/entity-store.d.ts +58 -0
- package/dist/entities/entity-store.d.ts.map +1 -0
- package/dist/entities/index.d.ts +10 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/mock-entity-store.d.ts +17 -0
- package/dist/entities/mock-entity-store.d.ts.map +1 -0
- package/dist/entities/supabase-entity-store.d.ts +8 -0
- package/dist/entities/supabase-entity-store.d.ts.map +1 -0
- package/dist/entities.js +159 -0
- package/dist/entities.js.map +1 -0
- package/dist/index.d.ts +28 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1558 -40
- package/dist/index.js.map +1 -1
- package/dist/inventory/allocation.d.ts +98 -0
- package/dist/inventory/allocation.d.ts.map +1 -0
- package/dist/inventory/index.d.ts +13 -0
- package/dist/inventory/index.d.ts.map +1 -0
- package/dist/inventory/mock-stock-store.d.ts +89 -0
- package/dist/inventory/mock-stock-store.d.ts.map +1 -0
- package/dist/inventory/postgrest-double.d.ts +65 -0
- package/dist/inventory/postgrest-double.d.ts.map +1 -0
- package/dist/inventory/shopify-mapping.d.ts +67 -0
- package/dist/inventory/shopify-mapping.d.ts.map +1 -0
- package/dist/inventory/stock-contract.d.ts +46 -0
- package/dist/inventory/stock-contract.d.ts.map +1 -0
- package/dist/inventory/stock-store.d.ts +96 -0
- package/dist/inventory/stock-store.d.ts.map +1 -0
- package/dist/inventory/stock-types.d.ts +351 -0
- package/dist/inventory/stock-types.d.ts.map +1 -0
- package/dist/inventory/supabase-stock-store.d.ts +60 -0
- package/dist/inventory/supabase-stock-store.d.ts.map +1 -0
- package/dist/inventory/vocabulary.d.ts +86 -0
- package/dist/inventory/vocabulary.d.ts.map +1 -0
- package/dist/inventory.js +4 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lib/catalog.d.ts +4 -0
- package/dist/lib/catalog.d.ts.map +1 -0
- package/dist/{commerce.d.ts → lib/commerce.d.ts} +2 -2
- package/dist/lib/commerce.d.ts.map +1 -0
- package/dist/lib/document.d.ts +13 -0
- package/dist/lib/document.d.ts.map +1 -0
- package/dist/lib/emails.d.ts +50 -0
- package/dist/lib/emails.d.ts.map +1 -0
- package/dist/lib/message-events.d.ts +4 -0
- package/dist/lib/message-events.d.ts.map +1 -0
- package/dist/lib/runtime.d.ts +5 -0
- package/dist/lib/runtime.d.ts.map +1 -0
- package/dist/lib/variant-matrix.d.ts +120 -0
- package/dist/lib/variant-matrix.d.ts.map +1 -0
- package/dist/mock.d.ts +1 -2
- package/dist/mock.d.ts.map +1 -1
- package/dist/mock.js +4 -2
- package/dist/provider.d.ts +1 -88
- package/dist/provider.d.ts.map +1 -1
- package/dist/providers/checkout.d.ts +129 -0
- package/dist/providers/checkout.d.ts.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/shipping.d.ts +43 -0
- package/dist/providers/shipping.d.ts.map +1 -0
- package/dist/providers.js +70 -0
- package/dist/providers.js.map +1 -0
- package/dist/rules/adapter.d.ts +36 -0
- package/dist/rules/adapter.d.ts.map +1 -0
- package/dist/rules/attributes.d.ts +64 -0
- package/dist/rules/attributes.d.ts.map +1 -0
- package/dist/rules/context.d.ts +43 -0
- package/dist/rules/context.d.ts.map +1 -0
- package/dist/rules/evaluator.d.ts +37 -0
- package/dist/rules/evaluator.d.ts.map +1 -0
- package/dist/rules/index.d.ts +13 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/prices.d.ts +25 -0
- package/dist/rules/prices.d.ts.map +1 -0
- package/dist/rules/rule-types.d.ts +160 -0
- package/dist/rules/rule-types.d.ts.map +1 -0
- package/dist/rules.js +22 -0
- package/dist/rules.js.map +1 -0
- package/dist/runtime.d.ts +1 -4
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +5 -3
- package/dist/shipping/label-provider.d.ts +43 -0
- package/dist/shipping/label-provider.d.ts.map +1 -0
- package/dist/types.d.ts +688 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +30 -20
- package/dist/chunk-CTKZ6O2J.js.map +0 -1
- package/dist/chunk-IYQHKMLB.js.map +0 -1
- package/dist/chunk-JR25TISO.js +0 -3
- package/dist/chunk-SVTCJ6HP.js +0 -440
- package/dist/chunk-SVTCJ6HP.js.map +0 -1
- package/dist/commerce.d.ts.map +0 -1
- package/dist/mock-catalog.d.ts.map +0 -1
- package/dist/mock-provider.d.ts +0 -60
- package/dist/mock-provider.d.ts.map +0 -1
- package/dist/supabase-provider.d.ts +0 -56
- package/dist/supabase-provider.d.ts.map +0 -1
- package/dist/tables.d.ts +0 -12
- package/dist/tables.d.ts.map +0 -1
- package/dist/tenant.d.ts.map +0 -1
- package/src/catalog.ts +0 -3
- package/src/commerce.ts +0 -120
- package/src/index.ts +0 -40
- package/src/mock-catalog.ts +0 -266
- package/src/mock-provider.ts +0 -480
- package/src/mock.ts +0 -2
- package/src/provider.ts +0 -117
- package/src/runtime.ts +0 -20
- package/src/supabase-provider.ts +0 -754
- package/src/tables.ts +0 -17
- package/src/tenant.ts +0 -21
- package/src/types.ts +0 -623
- /package/dist/{tenant.d.ts → data/tenant.d.ts} +0 -0
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
export type ProductStatus = 'draft' | 'active' | 'archived';
|
|
2
|
+
/**
|
|
3
|
+
* A handling requirement declared on a product (0048).
|
|
4
|
+
*
|
|
5
|
+
* This is a DECLARATION, not a guarantee: it is what travels to whoever carries
|
|
6
|
+
* the parcel — a carrier's refrigerated service, a motoboy, or the merchant's
|
|
7
|
+
* own car. What RESTRICTS who may carry it is the product's shipping profile
|
|
8
|
+
* (0049), not this list — this one only travels.
|
|
9
|
+
*/
|
|
10
|
+
export type HandlingRequirement = 'refrigerated' | 'frozen' | 'fragile';
|
|
2
11
|
export interface Product {
|
|
3
12
|
id: string;
|
|
4
13
|
tenantId: string;
|
|
@@ -16,11 +25,133 @@ export interface Product {
|
|
|
16
25
|
images: ProductImage[];
|
|
17
26
|
categoryId: string | null;
|
|
18
27
|
categoryName: string | null;
|
|
28
|
+
/** False keeps the product out of the freight calculation entirely (0001,
|
|
29
|
+
* finally read in FAY-1407). */
|
|
19
30
|
isPhysical: boolean;
|
|
20
31
|
weight: number | null;
|
|
32
|
+
/** The unit `weight` is in. Honoured by the packing code — it is not
|
|
33
|
+
* decoration, and a catalogue in grams quoted as kg is a thousandfold error. */
|
|
21
34
|
weightUnit: string;
|
|
35
|
+
/** Centimetres (0044b/0046). Null is "not measured", which degrades the cart
|
|
36
|
+
* to the store's default package rather than inventing a size. */
|
|
37
|
+
heightCm?: number | null;
|
|
38
|
+
widthCm?: number | null;
|
|
39
|
+
lengthCm?: number | null;
|
|
40
|
+
/**
|
|
41
|
+
* Em que embalagem da loja este produto vai (0047). NULL = a padrão da
|
|
42
|
+
* loja, que é o estado de todo produto no dia da aplicação. Aponta para
|
|
43
|
+
* plg_shop_packages; a medida está lá, não aqui.
|
|
44
|
+
*/
|
|
45
|
+
packageId?: string | null;
|
|
46
|
+
/**
|
|
47
|
+
* What the box needs from whoever carries it (0048). Empty is "nothing
|
|
48
|
+
* declared", which is how every catalogue starts.
|
|
49
|
+
*
|
|
50
|
+
* On the PRODUCT and not the variant on purpose: needing cold is a property of
|
|
51
|
+
* what is inside, and a chocolate melts in all three sizes. Weight and
|
|
52
|
+
* dimensions live on the variant because those genuinely differ.
|
|
53
|
+
*
|
|
54
|
+
* Optional and not `HandlingRequirement[]`: eleven apps build Product literals
|
|
55
|
+
* from source, and a required field on a shared interface makes a declaration
|
|
56
|
+
* nobody asked for into a build break in every one of them. The live provider
|
|
57
|
+
* always returns an array, so a reader may treat `undefined` as empty.
|
|
58
|
+
*/
|
|
59
|
+
handling?: HandlingRequirement[];
|
|
60
|
+
/** Which delivery profile ships this product (0049). Undefined = the general
|
|
61
|
+
* one, which is every product nobody has moved. */
|
|
62
|
+
shippingProfileId?: string | null;
|
|
22
63
|
createdAt: string;
|
|
23
64
|
updatedAt: string;
|
|
65
|
+
/**
|
|
66
|
+
* Option axes from the variant tables (0028), position-ordered — present
|
|
67
|
+
* when the read path fetched them (products.bySlug attaches them via
|
|
68
|
+
* ShopProvider.getProductVariants). Undefined means "not fetched", NOT
|
|
69
|
+
* "no options": list reads skip variants on purpose.
|
|
70
|
+
*/
|
|
71
|
+
options?: ProductOption[];
|
|
72
|
+
/** Sellable variants (0028), present under the same conditions as `options`. */
|
|
73
|
+
variants?: ProductVariant[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* One option axis of a product ('Tamanho' → ['P','M','G']). Mirrors
|
|
77
|
+
* plg_shop_product_options: the axis `name` is also the key used inside each
|
|
78
|
+
* variant's `options` object — that is what ties the two together.
|
|
79
|
+
*/
|
|
80
|
+
export interface ProductOption {
|
|
81
|
+
id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
/** Ordered values for the picker (P before M before G is not alphabetical). */
|
|
84
|
+
values: string[];
|
|
85
|
+
position: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The sellable unit once a product has option axes. Mirrors
|
|
89
|
+
* plg_shop_product_variants: `price` null inherits the product price;
|
|
90
|
+
* inventory is per-variant (two sizes never share a counter again).
|
|
91
|
+
*/
|
|
92
|
+
export interface ProductVariant {
|
|
93
|
+
id: string;
|
|
94
|
+
productId: string;
|
|
95
|
+
/** The combination this variant IS, e.g. {"Tamanho":"P","Cor":"Azul"}. */
|
|
96
|
+
options: Record<string, string>;
|
|
97
|
+
sku: string | null;
|
|
98
|
+
/** Null inherits the product's price. */
|
|
99
|
+
price: number | null;
|
|
100
|
+
compareAtPrice: number | null;
|
|
101
|
+
inventoryCount: number;
|
|
102
|
+
position: number;
|
|
103
|
+
status: 'active' | 'archived';
|
|
104
|
+
/** Variant-specific photo; null falls back to the product's primary image. */
|
|
105
|
+
imageId: string | null;
|
|
106
|
+
/**
|
|
107
|
+
* 0037's placeholder sellable unit for a product that declares no axes. MUST
|
|
108
|
+
* BE INVISIBLE to the merchant — no row in the variant grid, no options label.
|
|
109
|
+
*/
|
|
110
|
+
isDefaultVariant?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Shipping measurements (0046). Null inherits the product's, exactly like
|
|
113
|
+
* `price` — a camiseta P and a GG do not occupy the same box, and a
|
|
114
|
+
* catalogue where every size weighs the same is measured once, on the
|
|
115
|
+
* product, and never again.
|
|
116
|
+
*/
|
|
117
|
+
weight?: number | null;
|
|
118
|
+
weightUnit?: string | null;
|
|
119
|
+
heightCm?: number | null;
|
|
120
|
+
widthCm?: number | null;
|
|
121
|
+
lengthCm?: number | null;
|
|
122
|
+
}
|
|
123
|
+
/** What ShopProvider.getProductVariants answers for one product. */
|
|
124
|
+
export interface ProductVariantSet {
|
|
125
|
+
options: ProductOption[];
|
|
126
|
+
variants: ProductVariant[];
|
|
127
|
+
}
|
|
128
|
+
/** One axis as the admin submits it. Order of `values` is the picker's order. */
|
|
129
|
+
export interface ProductOptionInput {
|
|
130
|
+
name: string;
|
|
131
|
+
values: string[];
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The variant fields the admin owns. `inventoryCount` is deliberately ABSENT:
|
|
135
|
+
* since 0034 stock is a ledger and since 0036 `inventory_count` is its mirror,
|
|
136
|
+
* so a write here would be a second truth. Stock moves through
|
|
137
|
+
* ShopProvider.setVariantStock, which appends a movement.
|
|
138
|
+
*/
|
|
139
|
+
export interface UpdateProductVariantInput {
|
|
140
|
+
sku?: string | null;
|
|
141
|
+
price?: number | null;
|
|
142
|
+
compareAtPrice?: number | null;
|
|
143
|
+
position?: number;
|
|
144
|
+
status?: 'active' | 'archived';
|
|
145
|
+
imageId?: string | null;
|
|
146
|
+
weight?: number | null;
|
|
147
|
+
weightUnit?: string | null;
|
|
148
|
+
heightCm?: number | null;
|
|
149
|
+
widthCm?: number | null;
|
|
150
|
+
lengthCm?: number | null;
|
|
151
|
+
}
|
|
152
|
+
export interface CreateProductVariantInput extends UpdateProductVariantInput {
|
|
153
|
+
/** The combination this variant IS. Empty is refused — that shape is 0037's. */
|
|
154
|
+
options: Record<string, string>;
|
|
24
155
|
}
|
|
25
156
|
export interface ProductImage {
|
|
26
157
|
id: string;
|
|
@@ -47,6 +178,12 @@ export interface CreateProductInput {
|
|
|
47
178
|
isPhysical?: boolean;
|
|
48
179
|
weight?: number;
|
|
49
180
|
weightUnit?: string;
|
|
181
|
+
heightCm?: number | null;
|
|
182
|
+
widthCm?: number | null;
|
|
183
|
+
lengthCm?: number | null;
|
|
184
|
+
packageId?: string | null;
|
|
185
|
+
handling?: HandlingRequirement[];
|
|
186
|
+
shippingProfileId?: string | null;
|
|
50
187
|
}
|
|
51
188
|
export interface UpdateProductInput {
|
|
52
189
|
name?: string;
|
|
@@ -64,6 +201,12 @@ export interface UpdateProductInput {
|
|
|
64
201
|
isPhysical?: boolean;
|
|
65
202
|
weight?: number | null;
|
|
66
203
|
weightUnit?: string;
|
|
204
|
+
heightCm?: number | null;
|
|
205
|
+
widthCm?: number | null;
|
|
206
|
+
lengthCm?: number | null;
|
|
207
|
+
packageId?: string | null;
|
|
208
|
+
handling?: HandlingRequirement[];
|
|
209
|
+
shippingProfileId?: string | null;
|
|
67
210
|
}
|
|
68
211
|
export interface ListProductsOptions {
|
|
69
212
|
status?: ProductStatus;
|
|
@@ -167,9 +310,25 @@ export interface Order {
|
|
|
167
310
|
paymentMethodKind: PaymentMethodKind | null;
|
|
168
311
|
paidAt: string | null;
|
|
169
312
|
items: OrderItem[];
|
|
313
|
+
/**
|
|
314
|
+
* What the buyer needs to follow the box (0052). Only `getOrder` fills it —
|
|
315
|
+
* on a list, `[]` means "not asked for" as much as "nothing shipped".
|
|
316
|
+
*/
|
|
317
|
+
shipments?: OrderShipment[];
|
|
170
318
|
createdAt: string;
|
|
171
319
|
updatedAt: string;
|
|
172
320
|
}
|
|
321
|
+
/** One non-cancelled shipment, as the buyer's own window returns it. */
|
|
322
|
+
export interface OrderShipment {
|
|
323
|
+
id: string;
|
|
324
|
+
status: string;
|
|
325
|
+
carrier: string | null;
|
|
326
|
+
trackingCode: string | null;
|
|
327
|
+
trackingUrl: string | null;
|
|
328
|
+
shippedAt: string | null;
|
|
329
|
+
estimatedDeliveryAt: string | null;
|
|
330
|
+
deliveredAt: string | null;
|
|
331
|
+
}
|
|
173
332
|
export interface OrderItem {
|
|
174
333
|
id: string;
|
|
175
334
|
orderId: string;
|
|
@@ -223,6 +382,13 @@ export interface ListOrdersOptions {
|
|
|
223
382
|
export interface PlaceOrderLine {
|
|
224
383
|
productId: string;
|
|
225
384
|
quantity: number;
|
|
385
|
+
/**
|
|
386
|
+
* Variant to sell (0028/0029). When present the server prices the line from
|
|
387
|
+
* the variant, checks and decrements the VARIANT's stock, and derives the
|
|
388
|
+
* options label from the variant's combination. Absent = the product-level
|
|
389
|
+
* path, unchanged.
|
|
390
|
+
*/
|
|
391
|
+
variantId?: string;
|
|
226
392
|
/** Variant/options label appended to the stored item name (display only). */
|
|
227
393
|
optionsLabel?: string;
|
|
228
394
|
}
|
|
@@ -245,8 +411,125 @@ export interface ShippingAddressInput {
|
|
|
245
411
|
recipient?: string;
|
|
246
412
|
phone?: string;
|
|
247
413
|
label?: string;
|
|
414
|
+
/**
|
|
415
|
+
* CPF/CNPJ of whoever is buying — digits only. It is NOT part of the address:
|
|
416
|
+
* it travels here because shop_place_order cannot grow a parameter without a
|
|
417
|
+
* DROP, and 0050's BEFORE INSERT trigger lifts it into
|
|
418
|
+
* plg_shop_orders.customer_document and removes it from the stored jsonb.
|
|
419
|
+
* Read the column, never this field.
|
|
420
|
+
*/
|
|
421
|
+
document?: string;
|
|
248
422
|
}
|
|
249
423
|
export type PaymentMethodKind = 'pix' | 'credit_card' | 'debit_card' | 'boleto' | 'cash' | 'other';
|
|
424
|
+
export interface CreateFulfillmentInput {
|
|
425
|
+
orderId: string;
|
|
426
|
+
/** Free text: the merchant's own courier is as valid as a named carrier. */
|
|
427
|
+
carrier?: string;
|
|
428
|
+
/** With one, the shipment is already in transit; without, it is picking. */
|
|
429
|
+
trackingCode?: string;
|
|
430
|
+
locationId?: string;
|
|
431
|
+
notes?: string;
|
|
432
|
+
/** Partial shipment. Omitted means everything still outstanding. */
|
|
433
|
+
items?: Array<{
|
|
434
|
+
orderItemId: string;
|
|
435
|
+
quantity: number;
|
|
436
|
+
}>;
|
|
437
|
+
}
|
|
438
|
+
export interface ShipFulfillmentInput {
|
|
439
|
+
trackingCode?: string;
|
|
440
|
+
trackingUrl?: string;
|
|
441
|
+
carrier?: string;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* O carrinho congelado enquanto o comprador paga.
|
|
445
|
+
*
|
|
446
|
+
* Existe porque o pedido passou a nascer DEPOIS do pagamento. Entre "escolhi
|
|
447
|
+
* pagar" e "paguei" não há pedido nenhum — há esta sessão, com os preços que o
|
|
448
|
+
* SERVIDOR recalculou, e é dela que o pedido é criado quando o dinheiro entra.
|
|
449
|
+
*/
|
|
450
|
+
export interface CheckoutSessionInput {
|
|
451
|
+
items: Array<{
|
|
452
|
+
productId: string;
|
|
453
|
+
variantId?: string | null;
|
|
454
|
+
quantity: number;
|
|
455
|
+
optionsLabel?: string | null;
|
|
456
|
+
}>;
|
|
457
|
+
customer: {
|
|
458
|
+
name?: string | null;
|
|
459
|
+
email: string;
|
|
460
|
+
};
|
|
461
|
+
shippingAddress?: ShippingAddressInput;
|
|
462
|
+
discountCode?: string | null;
|
|
463
|
+
paymentMethod?: PaymentMethodKind;
|
|
464
|
+
}
|
|
465
|
+
export interface CheckoutSession {
|
|
466
|
+
sessionId: string;
|
|
467
|
+
/** Recalculado no servidor. O navegador exibe; nunca decide. */
|
|
468
|
+
total: number;
|
|
469
|
+
charge: PaymentCharge | null;
|
|
470
|
+
state: 'open' | 'paid' | 'failed' | 'expired';
|
|
471
|
+
}
|
|
472
|
+
/** `orderId` só aparece quando o pagamento entrou — é ele que prova a compra. */
|
|
473
|
+
export interface CheckoutSettlement {
|
|
474
|
+
/** `pending` is what the acquirer answers while the buyer still has the QR
|
|
475
|
+
* code open — the ordinary case, and the one a caller must never read as a
|
|
476
|
+
* refusal. Only `failed`, `expired` and `cancelled` end the wait. */
|
|
477
|
+
state: 'open' | 'pending' | 'paid' | 'failed' | 'expired' | 'cancelled' | 'unknown';
|
|
478
|
+
orderId?: string | null;
|
|
479
|
+
reason?: string | null;
|
|
480
|
+
}
|
|
481
|
+
/** A carrier label, from quote to tracking. `labelUrl` is a PDF the merchant prints. */
|
|
482
|
+
export interface ShippingLabelOption {
|
|
483
|
+
serviceId: number;
|
|
484
|
+
name: string;
|
|
485
|
+
carrier: string;
|
|
486
|
+
price: number;
|
|
487
|
+
etaMinDays?: number | null;
|
|
488
|
+
etaMaxDays?: number | null;
|
|
489
|
+
}
|
|
490
|
+
/** A carrier drop-off point, as a settings screen lists it. */
|
|
491
|
+
export interface ShippingAgency {
|
|
492
|
+
id: string;
|
|
493
|
+
name: string;
|
|
494
|
+
city: string;
|
|
495
|
+
state: string;
|
|
496
|
+
address: string;
|
|
497
|
+
/** Carrier service ids this one accepts — a choice that hides them is a
|
|
498
|
+
* choice the merchant discovers is wrong at the first dispatch. */
|
|
499
|
+
services: string[];
|
|
500
|
+
}
|
|
501
|
+
export interface ShippingLabel {
|
|
502
|
+
labelId: string;
|
|
503
|
+
labelUrl?: string | null;
|
|
504
|
+
status?: string | null;
|
|
505
|
+
tracking?: {
|
|
506
|
+
code: string | null;
|
|
507
|
+
status: string | null;
|
|
508
|
+
url: string | null;
|
|
509
|
+
} | null;
|
|
510
|
+
}
|
|
511
|
+
/** What a connected acquirer can be asked to open. Card waits for hosted fields. */
|
|
512
|
+
export type PaymentChargeMethod = 'pix';
|
|
513
|
+
/**
|
|
514
|
+
* A charge the buyer can act on. `qrcodeBase64` is a bare base64 PNG — no
|
|
515
|
+
* `data:` prefix — because that is how the provider returns it.
|
|
516
|
+
*/
|
|
517
|
+
export interface PaymentCharge {
|
|
518
|
+
emv: string;
|
|
519
|
+
qrcodeBase64: string | null;
|
|
520
|
+
expiresAt: string;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* `unopened` is not an error: the page may ask for the state before the charge
|
|
524
|
+
* call has returned. `failed` is the provider's final no.
|
|
525
|
+
*/
|
|
526
|
+
export interface PaymentChargeResult {
|
|
527
|
+
state: 'pending' | 'paid' | 'refunded' | 'failed' | 'unopened';
|
|
528
|
+
orderId: string;
|
|
529
|
+
reference?: string | null;
|
|
530
|
+
charge?: PaymentCharge | null;
|
|
531
|
+
providerStatus?: string | null;
|
|
532
|
+
}
|
|
250
533
|
/**
|
|
251
534
|
* A range of postal codes the store delivers to, with its own price and ETA.
|
|
252
535
|
*
|
|
@@ -268,9 +551,208 @@ export interface ShippingZone {
|
|
|
268
551
|
etaMaxDays?: number | null;
|
|
269
552
|
active: boolean;
|
|
270
553
|
sortOrder: number;
|
|
554
|
+
/**
|
|
555
|
+
* A zone the store REFUSES (0048) — "não entrego aqui", by any means.
|
|
556
|
+
*
|
|
557
|
+
* It beats every other zone covering the same postcode and it beats a carrier
|
|
558
|
+
* quote, because the refusal is about the store and not about who carries the
|
|
559
|
+
* parcel. Enforced server-side on the order, so a direct POST cannot get
|
|
560
|
+
* around it. `rate` and the ETA are ignored on an excluded zone.
|
|
561
|
+
*
|
|
562
|
+
* Not-cadastrar is a different thing: a broad zone covering a whole region
|
|
563
|
+
* already accepts the street the merchant wants to avoid, and there was no way
|
|
564
|
+
* to carve an exception out of it.
|
|
565
|
+
*/
|
|
566
|
+
excluded: boolean;
|
|
567
|
+
/** Which profile owns this range (0049). Undefined = the general profile. */
|
|
568
|
+
profileId?: string | null;
|
|
271
569
|
}
|
|
272
570
|
export type CreateShippingZoneInput = Omit<ShippingZone, 'id' | 'tenantId'>;
|
|
273
571
|
export type UpdateShippingZoneInput = Partial<CreateShippingZoneInput>;
|
|
572
|
+
export type ShippingPackageKind = 'box' | 'envelope' | 'soft';
|
|
573
|
+
/**
|
|
574
|
+
* A box the store actually owns (plg_shop_packages, 0046).
|
|
575
|
+
*
|
|
576
|
+
* The freight engine picks the SMALLEST of these the cart fits in and adds
|
|
577
|
+
* `emptyWeightGrams` to what the carrier weighs. Before this cadastro existed
|
|
578
|
+
* the box was a constant in the edge function — 4×16×20cm for every store —
|
|
579
|
+
* and the difference between the quote and the label came out of the
|
|
580
|
+
* merchant's margin.
|
|
581
|
+
*
|
|
582
|
+
* `isDefault` is the box a cart falls back to when some item has no
|
|
583
|
+
* measurements. That fallback used to be the constant; it is data now.
|
|
584
|
+
*/
|
|
585
|
+
export interface ShippingPackage {
|
|
586
|
+
id: string;
|
|
587
|
+
tenantId: string;
|
|
588
|
+
name: string;
|
|
589
|
+
kind: ShippingPackageKind;
|
|
590
|
+
heightCm: number;
|
|
591
|
+
widthCm: number;
|
|
592
|
+
lengthCm: number;
|
|
593
|
+
/** Grams, because that is how a merchant reads a carton's own weight. */
|
|
594
|
+
emptyWeightGrams: number;
|
|
595
|
+
isDefault: boolean;
|
|
596
|
+
active: boolean;
|
|
597
|
+
}
|
|
598
|
+
export type CreateShippingPackageInput = Omit<ShippingPackage, 'id' | 'tenantId'>;
|
|
599
|
+
export type UpdateShippingPackageInput = Partial<CreateShippingPackageInput>;
|
|
600
|
+
/**
|
|
601
|
+
* A named group of products with its own delivery zones (0049).
|
|
602
|
+
*
|
|
603
|
+
* The general mechanism behind "estes produtos vão de outro jeito", copied from
|
|
604
|
+
* Shopify's shipping profiles: refrigerated, fragile, oversized and made-to-order
|
|
605
|
+
* are all the same shape — a set of products the store ships differently — and
|
|
606
|
+
* modelling them one column at a time is how a settings screen ends up with four
|
|
607
|
+
* radios that each answer one merchant's question.
|
|
608
|
+
*
|
|
609
|
+
* INHERITANCE is by NULL on both ends: a product with no profile uses the
|
|
610
|
+
* general one, and a zone with no profile belongs to the general one. That is
|
|
611
|
+
* what lets this ship without migrating a single existing product or zone.
|
|
612
|
+
*/
|
|
613
|
+
export interface ShippingProfile {
|
|
614
|
+
id: string;
|
|
615
|
+
tenantId: string;
|
|
616
|
+
name: string;
|
|
617
|
+
/**
|
|
618
|
+
* Whether a freight gateway may quote for the products in this profile.
|
|
619
|
+
*
|
|
620
|
+
* Undefined inherits `StoreSettings.carrierQuotes`. `false` is what replaces
|
|
621
|
+
* the old cold-chain policy: these products leave only through the zones the
|
|
622
|
+
* store declared itself. In a cart that mixes profiles the most restrictive one
|
|
623
|
+
* wins — otherwise "these do not go by truck" would be undone by adding a mug.
|
|
624
|
+
*/
|
|
625
|
+
carrierQuotes?: boolean;
|
|
626
|
+
/** The general profile, so the screen has somewhere to hang unprofiled zones. */
|
|
627
|
+
isDefault: boolean;
|
|
628
|
+
}
|
|
629
|
+
export type CreateShippingProfileInput = Omit<ShippingProfile, 'id' | 'tenantId'>;
|
|
630
|
+
export type UpdateShippingProfileInput = Partial<CreateShippingProfileInput>;
|
|
631
|
+
/**
|
|
632
|
+
* The store-wide delivery fallback (public.shipping_settings, 0015).
|
|
633
|
+
*
|
|
634
|
+
* A zone always wins over this. It is what a store charges for an address no
|
|
635
|
+
* zone covers — and for a store that has declared no zone at all, which is how
|
|
636
|
+
* most start. A tenant with no row at all charges nothing, which is the safe
|
|
637
|
+
* default: inventing a freight nobody configured is worse than free delivery.
|
|
638
|
+
*/
|
|
639
|
+
export interface ShippingSettings {
|
|
640
|
+
flatRate: number;
|
|
641
|
+
/** Subtotal (after discount) at or above which delivery is free. */
|
|
642
|
+
freeAbove?: number | null;
|
|
643
|
+
currency: string;
|
|
644
|
+
}
|
|
645
|
+
export type UpdateShippingSettingsInput = Partial<ShippingSettings>;
|
|
646
|
+
/**
|
|
647
|
+
* Per-field checkout policy. Keyed by the form field the storefront renders.
|
|
648
|
+
*
|
|
649
|
+
* A record rather than columns because the SET OF FIELDS is the variable part:
|
|
650
|
+
* a store selling downloads has no use for a district, and the next storefront
|
|
651
|
+
* will want one nobody has thought of. `visible: false` implies not required —
|
|
652
|
+
* a field nobody can see cannot be filled in.
|
|
653
|
+
*/
|
|
654
|
+
export type CheckoutFieldKey = 'name' | 'email' | 'phone' | 'document' | 'street' | 'number' | 'complement' | 'district' | 'city' | 'state' | 'postalCode';
|
|
655
|
+
export interface CheckoutFieldPolicy {
|
|
656
|
+
visible?: boolean;
|
|
657
|
+
required?: boolean;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* The store's commercial policy — what plg_shop_settings holds (0044b).
|
|
661
|
+
*
|
|
662
|
+
* Every field is OPTIONAL and `undefined` means NOT DECIDED, which is a
|
|
663
|
+
* different thing from a false or an empty list: not-decided keeps whatever the
|
|
664
|
+
* app declared in its StorefrontConfig, while `paymentMethods: []` would be a
|
|
665
|
+
* merchant who accepts nothing. That distinction is what lets this ship to eight
|
|
666
|
+
* live storefronts without changing any of them on deploy day.
|
|
667
|
+
*
|
|
668
|
+
* Two of these are enforced SERVER-SIDE by a trigger (`paymentMethods`,
|
|
669
|
+
* `guestCheckout`); the rest are read by the storefront. The docs on each say
|
|
670
|
+
* which, because "the checkbox is off" and "the server refuses" are promises of
|
|
671
|
+
* very different strength.
|
|
672
|
+
*/
|
|
673
|
+
export interface StoreSettings {
|
|
674
|
+
/** Vitrine display. Undefined = the app's own currency/locale. */
|
|
675
|
+
currency?: string;
|
|
676
|
+
locale?: string;
|
|
677
|
+
showOutOfStock?: boolean;
|
|
678
|
+
/** Admin-side: makes SKU mandatory on the product form. Not a storefront rule. */
|
|
679
|
+
requireSku?: boolean;
|
|
680
|
+
/** ERP ownership of stock (0029). 'external' means a connector owns the numbers. */
|
|
681
|
+
stockOwnership?: 'internal' | 'external';
|
|
682
|
+
/** What the checkout may offer. ENFORCED: an order naming a method outside
|
|
683
|
+
* this list is refused by the server, not merely hidden by the form. */
|
|
684
|
+
paymentMethods?: PaymentMethodKind[];
|
|
685
|
+
/** Which connected gateway charges, when more than one is connected. The id of
|
|
686
|
+
* a ConnectorDefinition ('appmax'), never a credential. */
|
|
687
|
+
paymentProvider?: string;
|
|
688
|
+
/** ENFORCED: a storefront order with no account-linked customer is refused
|
|
689
|
+
* when this is explicitly false. */
|
|
690
|
+
guestCheckout?: boolean;
|
|
691
|
+
/** Storefront-side only — confirming an e-mail is a fact about the auth
|
|
692
|
+
* provider, not about the order, so the server does not police it. */
|
|
693
|
+
requireConfirmedEmail?: boolean;
|
|
694
|
+
marketingOptIn?: boolean;
|
|
695
|
+
discountsEnabled?: boolean;
|
|
696
|
+
checkoutFields?: Partial<Record<CheckoutFieldKey, CheckoutFieldPolicy>>;
|
|
697
|
+
/** 'never' — every shipment is created by hand. 'on_payment' — one is created
|
|
698
|
+
* when the payment is confirmed. 'always' — when the order is placed. */
|
|
699
|
+
autoFulfill?: 'never' | 'on_payment' | 'always';
|
|
700
|
+
notifyNewOrder?: boolean;
|
|
701
|
+
notifyLowStock?: boolean;
|
|
702
|
+
/**
|
|
703
|
+
* A declaração que viaja com o pedido — para você, para o motoboy, e na
|
|
704
|
+
* observação da etiqueta. Nunca mostrada ao comprador.
|
|
705
|
+
*
|
|
706
|
+
* Onde ficou a política de frio: num PERFIL DE ENTREGA (0049). "Refrigerado só
|
|
707
|
+
* sai no meu carro" é uma frase sobre logística, e uma coluna de três valores
|
|
708
|
+
* só respondia por temperatura — a loja seguinte pede o mesmo para frágil, para
|
|
709
|
+
* volumoso, para sob encomenda. Um perfil atende os quatro sem código novo.
|
|
710
|
+
*/
|
|
711
|
+
/**
|
|
712
|
+
* Whether a freight GATEWAY may quote for this store (0048).
|
|
713
|
+
*
|
|
714
|
+
* Melhor Envio is not a carrier — it is a gateway that brings Correios,
|
|
715
|
+
* Jadlog, Loggi and others behind one connection. So the store's question is
|
|
716
|
+
* not "which carrier" but WHO CALCULATES: the merchant, from her zones, or a
|
|
717
|
+
* gateway, from the shopper's postcode.
|
|
718
|
+
*
|
|
719
|
+
* `false` = the merchant calculates, and no gateway is asked even if one is
|
|
720
|
+
* connected. Undefined = not decided, which behaves as today (ask if
|
|
721
|
+
* connected). It has to be storable rather than inferred from "no connection":
|
|
722
|
+
* the day someone connects a gateway in this app, a store that dispatches by
|
|
723
|
+
* hand would start receiving carrier prices it never chose — and 0044b makes a
|
|
724
|
+
* gateway quote WIN over the zones when it answers.
|
|
725
|
+
*/
|
|
726
|
+
carrierQuotes?: boolean;
|
|
727
|
+
/**
|
|
728
|
+
* The note that travels with the parcel ("caixa térmica com gelo, entregar em
|
|
729
|
+
* até 24h"). Admin-side and carrier-side only — never shown to the shopper,
|
|
730
|
+
* which is why `shop_store_settings()` does not return it.
|
|
731
|
+
*/
|
|
732
|
+
handlingNote?: string;
|
|
733
|
+
}
|
|
734
|
+
export type UpdateStoreSettingsInput = Partial<StoreSettings>;
|
|
735
|
+
/**
|
|
736
|
+
* The answer to "does this store deliver to this postcode?" (0048,
|
|
737
|
+
* `shop_delivery_check`), asked with the address and BEFORE the card.
|
|
738
|
+
*
|
|
739
|
+
* Two separate facts, because they are not the same question:
|
|
740
|
+
* · `refused` — an exclusion zone covers it. A no from the store, true even
|
|
741
|
+
* where a carrier would happily deliver.
|
|
742
|
+
* · `ownZone` — a zone of the store's own covers it. What tells "our car"
|
|
743
|
+
* from "a gateway", and what a shipping profile with the gateway off (0049)
|
|
744
|
+
* narrows a product to.
|
|
745
|
+
*
|
|
746
|
+
* Deliberately NOT "is there freight": that is `quoteShipping`, which also
|
|
747
|
+
* consults a carrier. Answering both here would tell every carrier-only store
|
|
748
|
+
* that it does not deliver anywhere.
|
|
749
|
+
*/
|
|
750
|
+
export interface DeliveryCheck {
|
|
751
|
+
refused: boolean;
|
|
752
|
+
/** The exclusion zone's name, so the shopper reads a reason and not an error. */
|
|
753
|
+
refusedZone?: string | null;
|
|
754
|
+
ownZone: boolean;
|
|
755
|
+
}
|
|
274
756
|
/**
|
|
275
757
|
* One delivery option for a postal code, as quoted by shop_quote_shipping.
|
|
276
758
|
*
|
|
@@ -345,6 +827,12 @@ export interface PlaceOrderInput {
|
|
|
345
827
|
shippingAddress?: ShippingAddressInput;
|
|
346
828
|
/** How the buyer is paying. Opens the ledger row in public.transactions. */
|
|
347
829
|
paymentMethod?: PaymentMethodKind;
|
|
830
|
+
/**
|
|
831
|
+
* Machine-readable metadata stamped on the order, namespaced by contributor
|
|
832
|
+
* (spine M7's order.metadata extension point). Persisted by providers that
|
|
833
|
+
* support it (0029's plg_shop_orders.metadata); others may ignore it.
|
|
834
|
+
*/
|
|
835
|
+
metadata?: Record<string, unknown>;
|
|
348
836
|
items: PlaceOrderLine[];
|
|
349
837
|
}
|
|
350
838
|
export interface ShopCustomer {
|
|
@@ -354,6 +842,10 @@ export interface ShopCustomer {
|
|
|
354
842
|
lastName: string;
|
|
355
843
|
email: string | null;
|
|
356
844
|
phone: string | null;
|
|
845
|
+
/** CPF/CNPJ, digits only. The person's, not the order's — an invoice issued
|
|
846
|
+
* months later needs the document that was valid on the day it is issued,
|
|
847
|
+
* and the order keeps its own frozen copy for that. */
|
|
848
|
+
document?: string | null;
|
|
357
849
|
notes: string | null;
|
|
358
850
|
ordersCount: number;
|
|
359
851
|
totalSpent: number;
|
|
@@ -365,6 +857,7 @@ export interface CreateCustomerInput {
|
|
|
365
857
|
lastName?: string;
|
|
366
858
|
email?: string;
|
|
367
859
|
phone?: string;
|
|
860
|
+
document?: string;
|
|
368
861
|
notes?: string;
|
|
369
862
|
}
|
|
370
863
|
export interface UpdateCustomerInput {
|
|
@@ -372,6 +865,7 @@ export interface UpdateCustomerInput {
|
|
|
372
865
|
lastName?: string;
|
|
373
866
|
email?: string | null;
|
|
374
867
|
phone?: string | null;
|
|
868
|
+
document?: string | null;
|
|
375
869
|
notes?: string | null;
|
|
376
870
|
}
|
|
377
871
|
export interface ListCustomersOptions {
|
|
@@ -530,4 +1024,198 @@ export interface CartTotals {
|
|
|
530
1024
|
shippingTotal: number;
|
|
531
1025
|
total: number;
|
|
532
1026
|
}
|
|
1027
|
+
export type EmailEventKey = 'order_confirmation' | 'order_paid' | 'order_shipped' | 'order_delivered' | 'order_cancelled' | 'refund_confirmation' | 'customer_welcome' | 'abandoned_cart';
|
|
1028
|
+
/** Transacional responde a um ato do cliente; marketing é iniciativa da loja —
|
|
1029
|
+
* e é a distinção que decide se o envio precisa de consentimento. */
|
|
1030
|
+
export type EmailTemplateKind = 'transactional' | 'marketing';
|
|
1031
|
+
export interface EmailTemplate {
|
|
1032
|
+
id: string;
|
|
1033
|
+
tenantId: string;
|
|
1034
|
+
event: EmailEventKey;
|
|
1035
|
+
/** Ligado. Null = usar o `defaultEnabled` do catálogo — a mesma regra de
|
|
1036
|
+
* subject/body. Sem isso, salvar só o TEXTO de um modelo nunca tocado
|
|
1037
|
+
* gravava `false` e desligava o e-mail sem ninguém pedir. */
|
|
1038
|
+
enabled: boolean | null;
|
|
1039
|
+
/** Assunto. Null = usar o padrão que o SDK define para este evento. */
|
|
1040
|
+
subject: string | null;
|
|
1041
|
+
/** Corpo. Null = usar o padrão. */
|
|
1042
|
+
body: string | null;
|
|
1043
|
+
updatedAt: string;
|
|
1044
|
+
}
|
|
1045
|
+
export interface UpsertEmailTemplateInput {
|
|
1046
|
+
event: EmailEventKey;
|
|
1047
|
+
/** Omitir = não mexer no estado atual. Null = voltar ao padrão do catálogo. */
|
|
1048
|
+
enabled?: boolean | null;
|
|
1049
|
+
subject?: string | null;
|
|
1050
|
+
body?: string | null;
|
|
1051
|
+
}
|
|
1052
|
+
export interface CustomerGroup {
|
|
1053
|
+
id: string;
|
|
1054
|
+
tenantId: string;
|
|
1055
|
+
name: string;
|
|
1056
|
+
description: string | null;
|
|
1057
|
+
/** Chip colour in the admin. Null = default neutral. */
|
|
1058
|
+
color: string | null;
|
|
1059
|
+
/** Members, cheapest shape — counts and chips without a customer join. */
|
|
1060
|
+
customerIds: string[];
|
|
1061
|
+
createdAt: string;
|
|
1062
|
+
updatedAt: string;
|
|
1063
|
+
}
|
|
1064
|
+
export interface CreateCustomerGroupInput {
|
|
1065
|
+
name: string;
|
|
1066
|
+
description?: string | null;
|
|
1067
|
+
color?: string | null;
|
|
1068
|
+
customerIds?: string[];
|
|
1069
|
+
}
|
|
1070
|
+
export type UpdateCustomerGroupInput = Partial<CreateCustomerGroupInput>;
|
|
1071
|
+
/**
|
|
1072
|
+
* A segment's rule, as explicit columns rather than opaque JSON: every
|
|
1073
|
+
* criterion here is one the customer list can actually evaluate, so a saved
|
|
1074
|
+
* segment always has a real, checkable membership. A free-form rule blob would
|
|
1075
|
+
* let the admin store conditions nothing knows how to answer.
|
|
1076
|
+
*
|
|
1077
|
+
* All criteria are AND-ed. Every field null = matches everyone.
|
|
1078
|
+
*/
|
|
1079
|
+
export interface CustomerSegment {
|
|
1080
|
+
id: string;
|
|
1081
|
+
tenantId: string;
|
|
1082
|
+
name: string;
|
|
1083
|
+
description: string | null;
|
|
1084
|
+
minOrders: number | null;
|
|
1085
|
+
maxOrders: number | null;
|
|
1086
|
+
minSpent: number | null;
|
|
1087
|
+
maxSpent: number | null;
|
|
1088
|
+
/** ISO date — customer joined on or after this day. */
|
|
1089
|
+
joinedAfter: string | null;
|
|
1090
|
+
joinedBefore: string | null;
|
|
1091
|
+
createdAt: string;
|
|
1092
|
+
updatedAt: string;
|
|
1093
|
+
}
|
|
1094
|
+
export interface CreateCustomerSegmentInput {
|
|
1095
|
+
name: string;
|
|
1096
|
+
description?: string | null;
|
|
1097
|
+
minOrders?: number | null;
|
|
1098
|
+
maxOrders?: number | null;
|
|
1099
|
+
minSpent?: number | null;
|
|
1100
|
+
maxSpent?: number | null;
|
|
1101
|
+
joinedAfter?: string | null;
|
|
1102
|
+
joinedBefore?: string | null;
|
|
1103
|
+
}
|
|
1104
|
+
export type UpdateCustomerSegmentInput = Partial<CreateCustomerSegmentInput>;
|
|
1105
|
+
export interface Collection {
|
|
1106
|
+
id: string;
|
|
1107
|
+
tenantId: string;
|
|
1108
|
+
title: string;
|
|
1109
|
+
/** URL segment on the storefront. Derived from the title when omitted. */
|
|
1110
|
+
handle: string;
|
|
1111
|
+
description: string | null;
|
|
1112
|
+
imageUrl: string | null;
|
|
1113
|
+
/** Storefront <title>; falls back to `title` when empty. */
|
|
1114
|
+
seoTitle: string | null;
|
|
1115
|
+
seoDescription: string | null;
|
|
1116
|
+
published: boolean;
|
|
1117
|
+
sortOrder: number;
|
|
1118
|
+
/** Members, cheapest possible shape — counts and chips without a product join. */
|
|
1119
|
+
productIds: string[];
|
|
1120
|
+
createdAt: string;
|
|
1121
|
+
updatedAt: string;
|
|
1122
|
+
}
|
|
1123
|
+
export interface CreateCollectionInput {
|
|
1124
|
+
title: string;
|
|
1125
|
+
handle?: string;
|
|
1126
|
+
description?: string | null;
|
|
1127
|
+
imageUrl?: string | null;
|
|
1128
|
+
seoTitle?: string | null;
|
|
1129
|
+
seoDescription?: string | null;
|
|
1130
|
+
published?: boolean;
|
|
1131
|
+
sortOrder?: number;
|
|
1132
|
+
productIds?: string[];
|
|
1133
|
+
}
|
|
1134
|
+
export interface UpdateCollectionInput {
|
|
1135
|
+
title?: string;
|
|
1136
|
+
handle?: string;
|
|
1137
|
+
description?: string | null;
|
|
1138
|
+
imageUrl?: string | null;
|
|
1139
|
+
seoTitle?: string | null;
|
|
1140
|
+
seoDescription?: string | null;
|
|
1141
|
+
published?: boolean;
|
|
1142
|
+
sortOrder?: number;
|
|
1143
|
+
productIds?: string[];
|
|
1144
|
+
}
|
|
1145
|
+
export type GiftCardStatus = 'active' | 'redeemed' | 'expired' | 'disabled';
|
|
1146
|
+
export interface GiftCard {
|
|
1147
|
+
id: string;
|
|
1148
|
+
tenantId: string;
|
|
1149
|
+
/** What the buyer types at checkout. Unique per tenant, stored upper-case. */
|
|
1150
|
+
code: string;
|
|
1151
|
+
/** Face value at issue, in the store currency. Never changes. */
|
|
1152
|
+
initialBalance: number;
|
|
1153
|
+
/** What is left to spend. The only field redemption moves. */
|
|
1154
|
+
balance: number;
|
|
1155
|
+
currency: string;
|
|
1156
|
+
status: GiftCardStatus;
|
|
1157
|
+
/** Null = never expires. */
|
|
1158
|
+
expiresAt: string | null;
|
|
1159
|
+
/** Recipient, when the card was issued to a known customer. */
|
|
1160
|
+
customerId: string | null;
|
|
1161
|
+
customerEmail: string | null;
|
|
1162
|
+
note: string | null;
|
|
1163
|
+
createdAt: string;
|
|
1164
|
+
updatedAt: string;
|
|
1165
|
+
}
|
|
1166
|
+
export interface CreateGiftCardInput {
|
|
1167
|
+
code?: string;
|
|
1168
|
+
initialBalance: number;
|
|
1169
|
+
currency?: string;
|
|
1170
|
+
status?: GiftCardStatus;
|
|
1171
|
+
expiresAt?: string | null;
|
|
1172
|
+
customerId?: string | null;
|
|
1173
|
+
customerEmail?: string | null;
|
|
1174
|
+
note?: string | null;
|
|
1175
|
+
}
|
|
1176
|
+
export interface UpdateGiftCardInput {
|
|
1177
|
+
code?: string;
|
|
1178
|
+
/** Adjusting the remaining balance (a goodwill top-up, a correction). */
|
|
1179
|
+
balance?: number;
|
|
1180
|
+
status?: GiftCardStatus;
|
|
1181
|
+
expiresAt?: string | null;
|
|
1182
|
+
customerId?: string | null;
|
|
1183
|
+
customerEmail?: string | null;
|
|
1184
|
+
note?: string | null;
|
|
1185
|
+
}
|
|
1186
|
+
export type MediaFileKind = 'image' | 'video' | 'document';
|
|
1187
|
+
/**
|
|
1188
|
+
* The record a file hangs off.
|
|
1189
|
+
*
|
|
1190
|
+
* Without this a media library is a wall of anonymous thumbnails: a merchant can
|
|
1191
|
+
* see that a photo is bad and has nowhere to go to replace it. Only products own
|
|
1192
|
+
* files today; the shape is a discriminated union so a collection or a category
|
|
1193
|
+
* can join without changing the screens that read it.
|
|
1194
|
+
*/
|
|
1195
|
+
export interface MediaFileReference {
|
|
1196
|
+
type: 'product';
|
|
1197
|
+
/** The record's id — what the admin route is built from. */
|
|
1198
|
+
id: string;
|
|
1199
|
+
/** The record's name, for the card's link. */
|
|
1200
|
+
label: string;
|
|
1201
|
+
/** The attachment row (plg_shop_product_images.id). Deleting a file from the
|
|
1202
|
+
* library targets this: detaching it IS the deletion. */
|
|
1203
|
+
attachmentId: string;
|
|
1204
|
+
/** True for the photo the storefront leads with. */
|
|
1205
|
+
isCover?: boolean;
|
|
1206
|
+
}
|
|
1207
|
+
export interface MediaFile {
|
|
1208
|
+
/** Storage path relative to the bucket — the stable identity. */
|
|
1209
|
+
id: string;
|
|
1210
|
+
name: string;
|
|
1211
|
+
url: string;
|
|
1212
|
+
kind: MediaFileKind;
|
|
1213
|
+
/** Bytes. 0 when the backend does not report a size. */
|
|
1214
|
+
size: number;
|
|
1215
|
+
/** Upper-cased extension, for the card's type caption (WEBP, MP4…). */
|
|
1216
|
+
extension: string;
|
|
1217
|
+
createdAt: string;
|
|
1218
|
+
/** Absent for files uploaded straight to the library, which belong to nothing. */
|
|
1219
|
+
reference?: MediaFileReference;
|
|
1220
|
+
}
|
|
533
1221
|
//# sourceMappingURL=types.d.ts.map
|