@vitrine-kit/contracts 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,388 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BACKENDS: () => BACKENDS,
24
+ BLUEPRINT_COLLECTIONS: () => BLUEPRINT_COLLECTIONS,
25
+ BLUEPRINT_FIELD_TYPES: () => BLUEPRINT_FIELD_TYPES,
26
+ COLOR_TOKENS: () => COLOR_TOKENS,
27
+ CONTRACTS_VERSION: () => CONTRACTS_VERSION,
28
+ FONT_TOKENS: () => FONT_TOKENS,
29
+ FONT_WEIGHT_TOKENS: () => FONT_WEIGHT_TOKENS,
30
+ LEADING_TOKENS: () => LEADING_TOKENS,
31
+ MOTION_TOKENS: () => MOTION_TOKENS,
32
+ RADIUS_TOKENS: () => RADIUS_TOKENS,
33
+ SHADOW_TOKENS: () => SHADOW_TOKENS,
34
+ SINGLETON_TOKENS: () => SINGLETON_TOKENS,
35
+ SLOT_IDS: () => SLOT_IDS,
36
+ SPACE_TOKENS: () => SPACE_TOKENS,
37
+ TIERS: () => TIERS,
38
+ TOKEN_CSS_VARS: () => TOKEN_CSS_VARS,
39
+ TRACKING_TOKENS: () => TRACKING_TOKENS,
40
+ backendSchema: () => backendSchema,
41
+ blueprintCollectionSchema: () => blueprintCollectionSchema,
42
+ blueprintFieldDefSchema: () => blueprintFieldDefSchema,
43
+ blueprintManifestSchema: () => blueprintManifestSchema,
44
+ cssVar: () => cssVar,
45
+ featureEnvSchema: () => featureEnvSchema,
46
+ featureFileMapSchema: () => featureFileMapSchema,
47
+ featureManifestSchema: () => featureManifestSchema,
48
+ i18nSchema: () => i18nSchema,
49
+ integrationsSchema: () => integrationsSchema,
50
+ layoutSectionSchema: () => layoutSectionSchema,
51
+ registryIndexSchema: () => registryIndexSchema,
52
+ siteConfigSchema: () => siteConfigSchema,
53
+ slotIdSchema: () => slotIdSchema,
54
+ slotRegistrationSchema: () => slotRegistrationSchema,
55
+ themeSchema: () => themeSchema,
56
+ tierSchema: () => tierSchema,
57
+ vitrineLockSchema: () => vitrineLockSchema,
58
+ vitrinePreset: () => vitrinePreset
59
+ });
60
+ module.exports = __toCommonJS(index_exports);
61
+
62
+ // src/common.ts
63
+ var import_zod = require("zod");
64
+ var TIERS = ["catalog", "simple-store", "full-store"];
65
+ var tierSchema = import_zod.z.enum(TIERS);
66
+ var BACKENDS = ["payload", "vendure"];
67
+ var backendSchema = import_zod.z.enum(BACKENDS);
68
+
69
+ // src/tokens.ts
70
+ var COLOR_TOKENS = [
71
+ "bg",
72
+ "fg",
73
+ "muted",
74
+ "muted-fg",
75
+ "surface",
76
+ "surface-fg",
77
+ "border",
78
+ "input",
79
+ "ring",
80
+ "primary",
81
+ "primary-fg",
82
+ "secondary",
83
+ "secondary-fg",
84
+ "accent",
85
+ "accent-fg",
86
+ "success",
87
+ "warning",
88
+ "danger",
89
+ "danger-fg",
90
+ "price",
91
+ "sale"
92
+ ];
93
+ var FONT_TOKENS = ["sans", "heading", "mono"];
94
+ var FONT_WEIGHT_TOKENS = ["normal", "medium", "bold", "heading"];
95
+ var LEADING_TOKENS = ["tight", "normal", "relaxed"];
96
+ var TRACKING_TOKENS = ["tight", "normal", "wide"];
97
+ var RADIUS_TOKENS = ["base", "sm", "md", "lg", "full"];
98
+ var SHADOW_TOKENS = ["sm", "md", "lg", "color"];
99
+ var SPACE_TOKENS = ["unit", "container-max", "container-padding", "section-gap"];
100
+ var MOTION_TOKENS = ["duration-fast", "duration-normal", "ease-default"];
101
+ var SINGLETON_TOKENS = ["density", "border-width"];
102
+ function cssVar(group, name) {
103
+ return name ? `--vt-${group}-${name}` : `--vt-${group}`;
104
+ }
105
+ var TOKEN_CSS_VARS = [
106
+ ...COLOR_TOKENS.map((t) => cssVar("color", t)),
107
+ ...FONT_TOKENS.map((t) => cssVar("font", t)),
108
+ ...FONT_WEIGHT_TOKENS.map((t) => cssVar("weight", t)),
109
+ ...LEADING_TOKENS.map((t) => cssVar("leading", t)),
110
+ ...TRACKING_TOKENS.map((t) => cssVar("tracking", t)),
111
+ ...RADIUS_TOKENS.map((t) => cssVar("radius", t)),
112
+ ...SHADOW_TOKENS.map((t) => cssVar("shadow", t)),
113
+ ...SPACE_TOKENS.map((t) => cssVar("space", t)),
114
+ ...MOTION_TOKENS.map((t) => cssVar("motion", t)),
115
+ ...SINGLETON_TOKENS.map((t) => cssVar(t))
116
+ ];
117
+ var ref = (group, name) => `var(${cssVar(group, name)})`;
118
+ var vitrinePreset = {
119
+ theme: {
120
+ extend: {
121
+ colors: Object.fromEntries(
122
+ COLOR_TOKENS.map((t) => [t, ref("color", t)])
123
+ ),
124
+ fontFamily: {
125
+ sans: ref("font", "sans"),
126
+ heading: ref("font", "heading"),
127
+ mono: ref("font", "mono")
128
+ },
129
+ fontWeight: Object.fromEntries(
130
+ FONT_WEIGHT_TOKENS.map((t) => [t, ref("weight", t)])
131
+ ),
132
+ lineHeight: Object.fromEntries(
133
+ LEADING_TOKENS.map((t) => [t, ref("leading", t)])
134
+ ),
135
+ letterSpacing: Object.fromEntries(
136
+ TRACKING_TOKENS.map((t) => [t, ref("tracking", t)])
137
+ ),
138
+ borderRadius: Object.fromEntries(
139
+ RADIUS_TOKENS.map((t) => [t, ref("radius", t)])
140
+ ),
141
+ boxShadow: {
142
+ sm: ref("shadow", "sm"),
143
+ md: ref("shadow", "md"),
144
+ lg: ref("shadow", "lg")
145
+ },
146
+ borderWidth: { DEFAULT: ref("border-width") },
147
+ maxWidth: { container: ref("space", "container-max") },
148
+ spacing: {
149
+ unit: ref("space", "unit"),
150
+ gutter: ref("space", "container-padding"),
151
+ section: ref("space", "section-gap")
152
+ },
153
+ transitionDuration: {
154
+ fast: ref("motion", "duration-fast"),
155
+ normal: ref("motion", "duration-normal")
156
+ },
157
+ transitionTimingFunction: { DEFAULT: ref("motion", "ease-default") }
158
+ }
159
+ }
160
+ };
161
+
162
+ // src/slots.ts
163
+ var import_zod2 = require("zod");
164
+ var SLOT_IDS = [
165
+ // global — on every page
166
+ "global.banner-top",
167
+ "global.header-start",
168
+ "global.header-nav",
169
+ "global.header-actions",
170
+ "global.footer",
171
+ "global.body-end",
172
+ // home
173
+ "home.hero",
174
+ "home.below-hero",
175
+ "home.sections",
176
+ "home.bottom",
177
+ // catalog — listing/grid
178
+ "catalog.toolbar",
179
+ "catalog.sidebar",
180
+ "catalog.grid-top",
181
+ "catalog.grid-bottom",
182
+ // category
183
+ "category.header",
184
+ "category.below-products",
185
+ // product
186
+ "product.gallery",
187
+ "product.below-title",
188
+ "product.below-price",
189
+ "product.purchase",
190
+ "product.below-description",
191
+ "product.tabs",
192
+ "product.related",
193
+ // cart
194
+ "cart.items-bottom",
195
+ "cart.summary",
196
+ "cart.below",
197
+ // checkout
198
+ "checkout.top",
199
+ "checkout.below",
200
+ // order
201
+ "order.top",
202
+ "order.below",
203
+ // search
204
+ "search.results-top",
205
+ "search.empty"
206
+ ];
207
+ var slotIdSchema = import_zod2.z.enum(SLOT_IDS);
208
+ var slotRegistrationSchema = import_zod2.z.object({
209
+ slot: slotIdSchema,
210
+ component: import_zod2.z.string().min(1),
211
+ order: import_zod2.z.number().int().optional()
212
+ });
213
+
214
+ // src/config.ts
215
+ var import_zod3 = require("zod");
216
+ var layoutSectionSchema = import_zod3.z.object({
217
+ slot: slotIdSchema,
218
+ enabled: import_zod3.z.boolean().default(true),
219
+ /** Path to the override component in the client repo (unique — as an override, §13). */
220
+ override: import_zod3.z.string().optional()
221
+ });
222
+ var integrationsSchema = import_zod3.z.object({
223
+ payments: import_zod3.z.enum(["stripe", "paddle", "yookassa"]).optional(),
224
+ email: import_zod3.z.string().optional(),
225
+ analytics: import_zod3.z.string().optional(),
226
+ media: import_zod3.z.string().optional(),
227
+ shipping: import_zod3.z.string().optional()
228
+ }).default({});
229
+ var i18nSchema = import_zod3.z.object({
230
+ defaultLocale: import_zod3.z.string().default("en"),
231
+ locales: import_zod3.z.array(import_zod3.z.string()).default(["en"]),
232
+ currency: import_zod3.z.string().default("USD"),
233
+ priceFormat: import_zod3.z.string().optional()
234
+ }).default({ defaultLocale: "en", locales: ["en"], currency: "USD" });
235
+ var themeSchema = import_zod3.z.object({
236
+ name: import_zod3.z.string().default("default"),
237
+ /** File with token values (filled by the design step). */
238
+ cssFile: import_zod3.z.string().default("theme/client.css")
239
+ }).default({ name: "default", cssFile: "theme/client.css" });
240
+ var siteConfigSchema = import_zod3.z.object({
241
+ backend: backendSchema,
242
+ tier: tierSchema,
243
+ /**
244
+ * Storefront display name (header, metadata, footer). Set by `vitrine init`
245
+ * from the project name; optional for older clients.
246
+ */
247
+ name: import_zod3.z.string().min(1).optional(),
248
+ /** Feature flags: { 'reviews': true }. Set by the install primitive. */
249
+ features: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.boolean()).default({}),
250
+ layout: import_zod3.z.object({ sections: import_zod3.z.array(layoutSectionSchema).default([]) }).default({ sections: [] }),
251
+ theme: themeSchema,
252
+ integrations: integrationsSchema,
253
+ i18n: i18nSchema
254
+ });
255
+
256
+ // src/blueprint.ts
257
+ var import_zod4 = require("zod");
258
+ var BLUEPRINT_COLLECTIONS = [
259
+ "product",
260
+ "variant",
261
+ "category",
262
+ "media",
263
+ "order",
264
+ "user"
265
+ ];
266
+ var blueprintCollectionSchema = import_zod4.z.enum(BLUEPRINT_COLLECTIONS);
267
+ var BLUEPRINT_FIELD_TYPES = [
268
+ "text",
269
+ "textarea",
270
+ "richText",
271
+ "number",
272
+ "checkbox",
273
+ "select",
274
+ "relationship",
275
+ "date",
276
+ "json",
277
+ "array",
278
+ "group"
279
+ ];
280
+ var blueprintFieldDefSchema = import_zod4.z.object({
281
+ name: import_zod4.z.string().min(1),
282
+ type: import_zod4.z.enum(BLUEPRINT_FIELD_TYPES),
283
+ required: import_zod4.z.boolean().optional(),
284
+ label: import_zod4.z.string().optional()
285
+ }).passthrough();
286
+ var blueprintManifestSchema = import_zod4.z.object({
287
+ extend: blueprintCollectionSchema,
288
+ addFields: import_zod4.z.array(import_zod4.z.string().min(1))
289
+ });
290
+
291
+ // src/manifest.ts
292
+ var import_zod5 = require("zod");
293
+ var featureFileMapSchema = import_zod5.z.object({
294
+ from: import_zod5.z.string().min(1),
295
+ to: import_zod5.z.string().min(1)
296
+ });
297
+ var featureEnvSchema = import_zod5.z.object({
298
+ key: import_zod5.z.string().min(1),
299
+ required: import_zod5.z.boolean().default(false)
300
+ });
301
+ var featureManifestSchema = import_zod5.z.object({
302
+ name: import_zod5.z.string().min(1),
303
+ title: import_zod5.z.string().min(1),
304
+ kitVersion: import_zod5.z.string().min(1),
305
+ /** semver range of required contracts, e.g. ">=1.0.0 <2.0.0". */
306
+ requiresContracts: import_zod5.z.string().min(1),
307
+ tier: import_zod5.z.array(tierSchema).nonempty(),
308
+ registryDependencies: import_zod5.z.array(import_zod5.z.string()).default([]),
309
+ /** Versioned packages: { "@vitrine-kit/core": ">=1.0.0" }. */
310
+ corePackages: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.string()).default({}),
311
+ npm: import_zod5.z.array(import_zod5.z.string()).default([]),
312
+ files: import_zod5.z.array(featureFileMapSchema).default([]),
313
+ config: import_zod5.z.object({ set: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.boolean()) }).optional(),
314
+ /**
315
+ * The payment provider of a checkout-<provider> feature. From it the CLI: (1) generates
316
+ * the provider registration in lib/payments.ts, (2) sets integrations.payments
317
+ * in site.config. register<Pascal>Provider() is exported from lib/<name>/register.ts.
318
+ */
319
+ payment: import_zod5.z.object({ provider: import_zod5.z.enum(["stripe", "paddle", "yookassa"]) }).optional(),
320
+ slots: import_zod5.z.array(slotRegistrationSchema).default([]),
321
+ blueprint: blueprintManifestSchema.optional(),
322
+ env: import_zod5.z.array(featureEnvSchema).default([]),
323
+ /** Doc appended to the client's CLAUDE.md. */
324
+ claudeDoc: import_zod5.z.string().optional(),
325
+ conflicts: import_zod5.z.array(import_zod5.z.string()).default([]),
326
+ removable: import_zod5.z.boolean().default(true)
327
+ });
328
+ var vitrineLockSchema = import_zod5.z.object({
329
+ kitVersion: import_zod5.z.string().min(1),
330
+ contracts: import_zod5.z.string().min(1),
331
+ backend: backendSchema,
332
+ tier: tierSchema,
333
+ features: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.object({ version: import_zod5.z.string().min(1) })).default({})
334
+ });
335
+ var registryIndexSchema = import_zod5.z.object({
336
+ kitVersion: import_zod5.z.string().min(1),
337
+ contracts: import_zod5.z.string().min(1),
338
+ features: import_zod5.z.record(
339
+ import_zod5.z.string(),
340
+ import_zod5.z.object({
341
+ title: import_zod5.z.string(),
342
+ kitVersion: import_zod5.z.string(),
343
+ tier: import_zod5.z.array(tierSchema)
344
+ })
345
+ ).default({})
346
+ });
347
+
348
+ // src/index.ts
349
+ var CONTRACTS_VERSION = "1.0.0";
350
+ // Annotate the CommonJS export names for ESM import in node:
351
+ 0 && (module.exports = {
352
+ BACKENDS,
353
+ BLUEPRINT_COLLECTIONS,
354
+ BLUEPRINT_FIELD_TYPES,
355
+ COLOR_TOKENS,
356
+ CONTRACTS_VERSION,
357
+ FONT_TOKENS,
358
+ FONT_WEIGHT_TOKENS,
359
+ LEADING_TOKENS,
360
+ MOTION_TOKENS,
361
+ RADIUS_TOKENS,
362
+ SHADOW_TOKENS,
363
+ SINGLETON_TOKENS,
364
+ SLOT_IDS,
365
+ SPACE_TOKENS,
366
+ TIERS,
367
+ TOKEN_CSS_VARS,
368
+ TRACKING_TOKENS,
369
+ backendSchema,
370
+ blueprintCollectionSchema,
371
+ blueprintFieldDefSchema,
372
+ blueprintManifestSchema,
373
+ cssVar,
374
+ featureEnvSchema,
375
+ featureFileMapSchema,
376
+ featureManifestSchema,
377
+ i18nSchema,
378
+ integrationsSchema,
379
+ layoutSectionSchema,
380
+ registryIndexSchema,
381
+ siteConfigSchema,
382
+ slotIdSchema,
383
+ slotRegistrationSchema,
384
+ themeSchema,
385
+ tierSchema,
386
+ vitrineLockSchema,
387
+ vitrinePreset
388
+ });
@@ -0,0 +1,728 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const TIERS: readonly ["catalog", "simple-store", "full-store"];
4
+ type Tier = (typeof TIERS)[number];
5
+ declare const tierSchema: z.ZodEnum<["catalog", "simple-store", "full-store"]>;
6
+ declare const BACKENDS: readonly ["payload", "vendure"];
7
+ type Backend = (typeof BACKENDS)[number];
8
+ declare const backendSchema: z.ZodEnum<["payload", "vendure"]>;
9
+
10
+ declare const COLOR_TOKENS: readonly ["bg", "fg", "muted", "muted-fg", "surface", "surface-fg", "border", "input", "ring", "primary", "primary-fg", "secondary", "secondary-fg", "accent", "accent-fg", "success", "warning", "danger", "danger-fg", "price", "sale"];
11
+ type ColorToken = (typeof COLOR_TOKENS)[number];
12
+ declare const FONT_TOKENS: readonly ["sans", "heading", "mono"];
13
+ type FontToken = (typeof FONT_TOKENS)[number];
14
+ declare const FONT_WEIGHT_TOKENS: readonly ["normal", "medium", "bold", "heading"];
15
+ type FontWeightToken = (typeof FONT_WEIGHT_TOKENS)[number];
16
+ declare const LEADING_TOKENS: readonly ["tight", "normal", "relaxed"];
17
+ type LeadingToken = (typeof LEADING_TOKENS)[number];
18
+ declare const TRACKING_TOKENS: readonly ["tight", "normal", "wide"];
19
+ type TrackingToken = (typeof TRACKING_TOKENS)[number];
20
+ declare const RADIUS_TOKENS: readonly ["base", "sm", "md", "lg", "full"];
21
+ type RadiusToken = (typeof RADIUS_TOKENS)[number];
22
+ declare const SHADOW_TOKENS: readonly ["sm", "md", "lg", "color"];
23
+ type ShadowToken = (typeof SHADOW_TOKENS)[number];
24
+ declare const SPACE_TOKENS: readonly ["unit", "container-max", "container-padding", "section-gap"];
25
+ type SpaceToken = (typeof SPACE_TOKENS)[number];
26
+ declare const MOTION_TOKENS: readonly ["duration-fast", "duration-normal", "ease-default"];
27
+ type MotionToken = (typeof MOTION_TOKENS)[number];
28
+ /** Single "knobs" without a group. */
29
+ declare const SINGLETON_TOKENS: readonly ["density", "border-width"];
30
+ type SingletonToken = (typeof SINGLETON_TOKENS)[number];
31
+ /** CSS variable name for a token: cssVar('color','primary') → '--vt-color-primary'. */
32
+ declare function cssVar(group: string, name?: string): `--vt-${string}`;
33
+ /** Full list of the contract's CSS variable names — for theme scaffolding and docs. */
34
+ declare const TOKEN_CSS_VARS: string[];
35
+ /**
36
+ * The Vitrine Tailwind preset: maps Tailwind keys to the contract's CSS variables.
37
+ * Used in the client's tailwind.config: `presets: [vitrinePreset]`.
38
+ * Loosely typed so contracts don't take a dependency on tailwindcss.
39
+ */
40
+ declare const vitrinePreset: {
41
+ theme: {
42
+ extend: Record<string, unknown>;
43
+ };
44
+ };
45
+
46
+ /**
47
+ * Money — an integer in the currency's minor units (cents).
48
+ * 2490 = 24.90. Decision is fixed (see the demo seed, spec §18.2).
49
+ */
50
+ type Money = number;
51
+ /** ISO 4217, e.g. 'USD', 'EUR', 'GBP'. */
52
+ type CurrencyCode = string;
53
+ interface Category {
54
+ id: string;
55
+ slug: string;
56
+ title: string;
57
+ parentId?: string | null;
58
+ description?: string;
59
+ }
60
+ interface ProductImage {
61
+ url: string;
62
+ alt?: string;
63
+ width?: number;
64
+ height?: number;
65
+ }
66
+ interface Variant {
67
+ id: string;
68
+ sku: string;
69
+ title?: string;
70
+ price: Money;
71
+ currency: CurrencyCode;
72
+ /** null/undefined = stock not tracked. */
73
+ stock?: number | null;
74
+ /** Variant options, e.g. { size: 'M', color: 'red' }. */
75
+ options?: Record<string, string>;
76
+ }
77
+ interface Seo {
78
+ title?: string;
79
+ description?: string;
80
+ image?: string;
81
+ }
82
+ interface Product {
83
+ id: string;
84
+ slug: string;
85
+ title: string;
86
+ description?: string;
87
+ categoryIds: string[];
88
+ images: ProductImage[];
89
+ variants: Variant[];
90
+ priceRange?: {
91
+ min: Money;
92
+ max: Money;
93
+ currency: CurrencyCode;
94
+ };
95
+ seo?: Seo;
96
+ /**
97
+ * Fields added by features via blueprint extend() (contract 5),
98
+ * mapped here by the adapter. The contract stays stable — features read their own keys.
99
+ */
100
+ extensions?: Record<string, unknown>;
101
+ }
102
+ type ProductSort = 'newest' | 'price-asc' | 'price-desc' | 'relevance';
103
+ interface ProductQuery {
104
+ /** Category slug. */
105
+ category?: string;
106
+ search?: string;
107
+ sort?: ProductSort;
108
+ page?: number;
109
+ perPage?: number;
110
+ /** Filter facets: { color: ['red','blue'], size: ['M'] }. */
111
+ filters?: Record<string, string[]>;
112
+ /** Inclusive lower bound on variant/list price (minor units, e.g. cents). */
113
+ priceMin?: number;
114
+ /** Inclusive upper bound on variant/list price (minor units, e.g. cents). */
115
+ priceMax?: number;
116
+ /**
117
+ * CMS / storefront locale (path cookie or explicit). Adapters that support
118
+ * localized fields pass this through to the backend; others ignore it.
119
+ */
120
+ locale?: string;
121
+ }
122
+ interface CartLine {
123
+ id: string;
124
+ variantId: string;
125
+ productId: string;
126
+ title: string;
127
+ quantity: number;
128
+ unitPrice: Money;
129
+ lineTotal: Money;
130
+ image?: string;
131
+ }
132
+ interface Cart {
133
+ id: string;
134
+ lines: CartLine[];
135
+ currency: CurrencyCode;
136
+ subtotal: Money;
137
+ discountTotal?: Money;
138
+ total: Money;
139
+ }
140
+ type OrderStatus = 'pending' | 'paid' | 'fulfilled' | 'cancelled' | 'refunded';
141
+ interface OrderLine {
142
+ variantId: string;
143
+ productId: string;
144
+ title: string;
145
+ quantity: number;
146
+ unitPrice: Money;
147
+ lineTotal: Money;
148
+ }
149
+ interface Order {
150
+ id: string;
151
+ number?: string;
152
+ status: OrderStatus;
153
+ lines: OrderLine[];
154
+ currency: CurrencyCode;
155
+ subtotal: Money;
156
+ discountTotal?: Money;
157
+ total: Money;
158
+ email?: string;
159
+ /** ISO-8601. */
160
+ createdAt: string;
161
+ }
162
+ /**
163
+ * Catalog source. Implemented by the PayloadCatalog* / VendureCatalog* adapters.
164
+ * Needed at every tier (catalog and above).
165
+ */
166
+ interface CatalogSource {
167
+ listProducts(query: ProductQuery): Promise<Product[]>;
168
+ /** Optional locale selects localized CMS fields when the backend supports them. */
169
+ getProduct(slug: string, locale?: string): Promise<Product | null>;
170
+ listCategories(locale?: string): Promise<Category[]>;
171
+ search(term: string, locale?: string): Promise<Product[]>;
172
+ }
173
+ /**
174
+ * Commerce backend. Only simple-store / full-store.
175
+ * Implemented by PayloadCommerce* / VendureCommerce*.
176
+ * The full cart surface is fixed in v1 (adding methods to the interface
177
+ * later = a breaking change for implementations).
178
+ */
179
+ interface CommerceBackend {
180
+ createCart(): Promise<Cart>;
181
+ getCart(cartId: string): Promise<Cart | null>;
182
+ addItem(cartId: string, variantId: string, qty: number): Promise<Cart>;
183
+ updateItem(cartId: string, lineId: string, qty: number): Promise<Cart>;
184
+ removeItem(cartId: string, lineId: string): Promise<Cart>;
185
+ /** Hosted checkout of the active payment provider → redirectUrl. */
186
+ startCheckout(cartId: string): Promise<{
187
+ redirectUrl: string;
188
+ }>;
189
+ getOrder(id: string): Promise<Order | null>;
190
+ }
191
+
192
+ /** 32 v1 slots. Order and grouping match the approved proposal. */
193
+ declare const SLOT_IDS: readonly ["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"];
194
+ type SlotId = (typeof SLOT_IDS)[number];
195
+ /** Zod enum of slots (for validating feature.json / site.config). */
196
+ declare const slotIdSchema: z.ZodEnum<["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"]>;
197
+ /**
198
+ * Declarative slot registration in the feature manifest (feature.json, spec §8):
199
+ * component is the component NAME, resolved in the client repository.
200
+ */
201
+ declare const slotRegistrationSchema: z.ZodObject<{
202
+ slot: z.ZodEnum<["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"]>;
203
+ component: z.ZodString;
204
+ order: z.ZodOptional<z.ZodNumber>;
205
+ }, "strip", z.ZodTypeAny, {
206
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
207
+ component: string;
208
+ order?: number | undefined;
209
+ }, {
210
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
211
+ component: string;
212
+ order?: number | undefined;
213
+ }>;
214
+ type SlotRegistration = z.infer<typeof slotRegistrationSchema>;
215
+ /**
216
+ * Runtime binding of a name to an actual component (used by @vitrine-kit/core
217
+ * in the client's lib/slots.ts). Generic over the component type so the contract
218
+ * doesn't depend on React.
219
+ */
220
+ interface SlotMount<TComponent = unknown> {
221
+ slot: SlotId;
222
+ component: TComponent;
223
+ order?: number;
224
+ }
225
+
226
+ /** Override/ordering of a page section (composition over the wireframe). */
227
+ declare const layoutSectionSchema: z.ZodObject<{
228
+ slot: z.ZodEnum<["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"]>;
229
+ enabled: z.ZodDefault<z.ZodBoolean>;
230
+ /** Path to the override component in the client repo (unique — as an override, §13). */
231
+ override: z.ZodOptional<z.ZodString>;
232
+ }, "strip", z.ZodTypeAny, {
233
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
234
+ enabled: boolean;
235
+ override?: string | undefined;
236
+ }, {
237
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
238
+ enabled?: boolean | undefined;
239
+ override?: string | undefined;
240
+ }>;
241
+ type LayoutSection = z.infer<typeof layoutSectionSchema>;
242
+ declare const integrationsSchema: z.ZodDefault<z.ZodObject<{
243
+ payments: z.ZodOptional<z.ZodEnum<["stripe", "paddle", "yookassa"]>>;
244
+ email: z.ZodOptional<z.ZodString>;
245
+ analytics: z.ZodOptional<z.ZodString>;
246
+ media: z.ZodOptional<z.ZodString>;
247
+ shipping: z.ZodOptional<z.ZodString>;
248
+ }, "strip", z.ZodTypeAny, {
249
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
250
+ email?: string | undefined;
251
+ analytics?: string | undefined;
252
+ media?: string | undefined;
253
+ shipping?: string | undefined;
254
+ }, {
255
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
256
+ email?: string | undefined;
257
+ analytics?: string | undefined;
258
+ media?: string | undefined;
259
+ shipping?: string | undefined;
260
+ }>>;
261
+ declare const i18nSchema: z.ZodDefault<z.ZodObject<{
262
+ defaultLocale: z.ZodDefault<z.ZodString>;
263
+ locales: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
264
+ currency: z.ZodDefault<z.ZodString>;
265
+ priceFormat: z.ZodOptional<z.ZodString>;
266
+ }, "strip", z.ZodTypeAny, {
267
+ defaultLocale: string;
268
+ locales: string[];
269
+ currency: string;
270
+ priceFormat?: string | undefined;
271
+ }, {
272
+ defaultLocale?: string | undefined;
273
+ locales?: string[] | undefined;
274
+ currency?: string | undefined;
275
+ priceFormat?: string | undefined;
276
+ }>>;
277
+ declare const themeSchema: z.ZodDefault<z.ZodObject<{
278
+ name: z.ZodDefault<z.ZodString>;
279
+ /** File with token values (filled by the design step). */
280
+ cssFile: z.ZodDefault<z.ZodString>;
281
+ }, "strip", z.ZodTypeAny, {
282
+ name: string;
283
+ cssFile: string;
284
+ }, {
285
+ name?: string | undefined;
286
+ cssFile?: string | undefined;
287
+ }>>;
288
+ declare const siteConfigSchema: z.ZodObject<{
289
+ backend: z.ZodEnum<["payload", "vendure"]>;
290
+ tier: z.ZodEnum<["catalog", "simple-store", "full-store"]>;
291
+ /**
292
+ * Storefront display name (header, metadata, footer). Set by `vitrine init`
293
+ * from the project name; optional for older clients.
294
+ */
295
+ name: z.ZodOptional<z.ZodString>;
296
+ /** Feature flags: { 'reviews': true }. Set by the install primitive. */
297
+ features: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
298
+ layout: z.ZodDefault<z.ZodObject<{
299
+ sections: z.ZodDefault<z.ZodArray<z.ZodObject<{
300
+ slot: z.ZodEnum<["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"]>;
301
+ enabled: z.ZodDefault<z.ZodBoolean>;
302
+ /** Path to the override component in the client repo (unique — as an override, §13). */
303
+ override: z.ZodOptional<z.ZodString>;
304
+ }, "strip", z.ZodTypeAny, {
305
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
306
+ enabled: boolean;
307
+ override?: string | undefined;
308
+ }, {
309
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
310
+ enabled?: boolean | undefined;
311
+ override?: string | undefined;
312
+ }>, "many">>;
313
+ }, "strip", z.ZodTypeAny, {
314
+ sections: {
315
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
316
+ enabled: boolean;
317
+ override?: string | undefined;
318
+ }[];
319
+ }, {
320
+ sections?: {
321
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
322
+ enabled?: boolean | undefined;
323
+ override?: string | undefined;
324
+ }[] | undefined;
325
+ }>>;
326
+ theme: z.ZodDefault<z.ZodObject<{
327
+ name: z.ZodDefault<z.ZodString>;
328
+ /** File with token values (filled by the design step). */
329
+ cssFile: z.ZodDefault<z.ZodString>;
330
+ }, "strip", z.ZodTypeAny, {
331
+ name: string;
332
+ cssFile: string;
333
+ }, {
334
+ name?: string | undefined;
335
+ cssFile?: string | undefined;
336
+ }>>;
337
+ integrations: z.ZodDefault<z.ZodObject<{
338
+ payments: z.ZodOptional<z.ZodEnum<["stripe", "paddle", "yookassa"]>>;
339
+ email: z.ZodOptional<z.ZodString>;
340
+ analytics: z.ZodOptional<z.ZodString>;
341
+ media: z.ZodOptional<z.ZodString>;
342
+ shipping: z.ZodOptional<z.ZodString>;
343
+ }, "strip", z.ZodTypeAny, {
344
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
345
+ email?: string | undefined;
346
+ analytics?: string | undefined;
347
+ media?: string | undefined;
348
+ shipping?: string | undefined;
349
+ }, {
350
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
351
+ email?: string | undefined;
352
+ analytics?: string | undefined;
353
+ media?: string | undefined;
354
+ shipping?: string | undefined;
355
+ }>>;
356
+ i18n: z.ZodDefault<z.ZodObject<{
357
+ defaultLocale: z.ZodDefault<z.ZodString>;
358
+ locales: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
359
+ currency: z.ZodDefault<z.ZodString>;
360
+ priceFormat: z.ZodOptional<z.ZodString>;
361
+ }, "strip", z.ZodTypeAny, {
362
+ defaultLocale: string;
363
+ locales: string[];
364
+ currency: string;
365
+ priceFormat?: string | undefined;
366
+ }, {
367
+ defaultLocale?: string | undefined;
368
+ locales?: string[] | undefined;
369
+ currency?: string | undefined;
370
+ priceFormat?: string | undefined;
371
+ }>>;
372
+ }, "strip", z.ZodTypeAny, {
373
+ backend: "payload" | "vendure";
374
+ tier: "catalog" | "simple-store" | "full-store";
375
+ features: Record<string, boolean>;
376
+ layout: {
377
+ sections: {
378
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
379
+ enabled: boolean;
380
+ override?: string | undefined;
381
+ }[];
382
+ };
383
+ theme: {
384
+ name: string;
385
+ cssFile: string;
386
+ };
387
+ integrations: {
388
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
389
+ email?: string | undefined;
390
+ analytics?: string | undefined;
391
+ media?: string | undefined;
392
+ shipping?: string | undefined;
393
+ };
394
+ i18n: {
395
+ defaultLocale: string;
396
+ locales: string[];
397
+ currency: string;
398
+ priceFormat?: string | undefined;
399
+ };
400
+ name?: string | undefined;
401
+ }, {
402
+ backend: "payload" | "vendure";
403
+ tier: "catalog" | "simple-store" | "full-store";
404
+ name?: string | undefined;
405
+ features?: Record<string, boolean> | undefined;
406
+ layout?: {
407
+ sections?: {
408
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
409
+ enabled?: boolean | undefined;
410
+ override?: string | undefined;
411
+ }[] | undefined;
412
+ } | undefined;
413
+ theme?: {
414
+ name?: string | undefined;
415
+ cssFile?: string | undefined;
416
+ } | undefined;
417
+ integrations?: {
418
+ payments?: "stripe" | "paddle" | "yookassa" | undefined;
419
+ email?: string | undefined;
420
+ analytics?: string | undefined;
421
+ media?: string | undefined;
422
+ shipping?: string | undefined;
423
+ } | undefined;
424
+ i18n?: {
425
+ defaultLocale?: string | undefined;
426
+ locales?: string[] | undefined;
427
+ currency?: string | undefined;
428
+ priceFormat?: string | undefined;
429
+ } | undefined;
430
+ }>;
431
+ type SiteConfig = z.infer<typeof siteConfigSchema>;
432
+
433
+ /** Base blueprint collections a feature can extend. */
434
+ declare const BLUEPRINT_COLLECTIONS: readonly ["product", "variant", "category", "media", "order", "user"];
435
+ type BlueprintCollection = (typeof BLUEPRINT_COLLECTIONS)[number];
436
+ declare const blueprintCollectionSchema: z.ZodEnum<["product", "variant", "category", "media", "order", "user"]>;
437
+ /** Supported types for added fields (minimal v1 set). */
438
+ declare const BLUEPRINT_FIELD_TYPES: readonly ["text", "textarea", "richText", "number", "checkbox", "select", "relationship", "date", "json", "array", "group"];
439
+ type BlueprintFieldType = (typeof BLUEPRINT_FIELD_TYPES)[number];
440
+ /**
441
+ * Definition of an added field (runtime form for @vitrine-kit/payload-blueprint).
442
+ * Allows extra Payload field keys (options, relationTo, …) via passthrough.
443
+ */
444
+ declare const blueprintFieldDefSchema: z.ZodObject<{
445
+ name: z.ZodString;
446
+ type: z.ZodEnum<["text", "textarea", "richText", "number", "checkbox", "select", "relationship", "date", "json", "array", "group"]>;
447
+ required: z.ZodOptional<z.ZodBoolean>;
448
+ label: z.ZodOptional<z.ZodString>;
449
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
450
+ name: z.ZodString;
451
+ type: z.ZodEnum<["text", "textarea", "richText", "number", "checkbox", "select", "relationship", "date", "json", "array", "group"]>;
452
+ required: z.ZodOptional<z.ZodBoolean>;
453
+ label: z.ZodOptional<z.ZodString>;
454
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
455
+ name: z.ZodString;
456
+ type: z.ZodEnum<["text", "textarea", "richText", "number", "checkbox", "select", "relationship", "date", "json", "array", "group"]>;
457
+ required: z.ZodOptional<z.ZodBoolean>;
458
+ label: z.ZodOptional<z.ZodString>;
459
+ }, z.ZodTypeAny, "passthrough">>;
460
+ type BlueprintFieldDef = z.infer<typeof blueprintFieldDefSchema>;
461
+ /** Runtime extension applied by extend(). */
462
+ interface BlueprintExtension {
463
+ extend: BlueprintCollection;
464
+ addFields: BlueprintFieldDef[];
465
+ }
466
+ /**
467
+ * The extend() signature, implemented in @vitrine-kit/payload-blueprint.
468
+ * Additive by contract: it adds fields to a collection.
469
+ */
470
+ type Extend = (collection: BlueprintCollection, patch: {
471
+ addFields: BlueprintFieldDef[];
472
+ }) => void;
473
+ /**
474
+ * The blueprint shape in the feature manifest (feature.json, §8): addFields are field NAMES
475
+ * (strings); the actual definitions live in the feature code / payload-blueprint.
476
+ */
477
+ declare const blueprintManifestSchema: z.ZodObject<{
478
+ extend: z.ZodEnum<["product", "variant", "category", "media", "order", "user"]>;
479
+ addFields: z.ZodArray<z.ZodString, "many">;
480
+ }, "strip", z.ZodTypeAny, {
481
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
482
+ addFields: string[];
483
+ }, {
484
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
485
+ addFields: string[];
486
+ }>;
487
+ type BlueprintManifest = z.infer<typeof blueprintManifestSchema>;
488
+
489
+ declare const featureFileMapSchema: z.ZodObject<{
490
+ from: z.ZodString;
491
+ to: z.ZodString;
492
+ }, "strip", z.ZodTypeAny, {
493
+ from: string;
494
+ to: string;
495
+ }, {
496
+ from: string;
497
+ to: string;
498
+ }>;
499
+ declare const featureEnvSchema: z.ZodObject<{
500
+ key: z.ZodString;
501
+ required: z.ZodDefault<z.ZodBoolean>;
502
+ }, "strip", z.ZodTypeAny, {
503
+ required: boolean;
504
+ key: string;
505
+ }, {
506
+ key: string;
507
+ required?: boolean | undefined;
508
+ }>;
509
+ /** registry/<feature>/feature.json — the declarative feature manifest (§8). */
510
+ declare const featureManifestSchema: z.ZodObject<{
511
+ name: z.ZodString;
512
+ title: z.ZodString;
513
+ kitVersion: z.ZodString;
514
+ /** semver range of required contracts, e.g. ">=1.0.0 <2.0.0". */
515
+ requiresContracts: z.ZodString;
516
+ tier: z.ZodArray<z.ZodEnum<["catalog", "simple-store", "full-store"]>, "atleastone">;
517
+ registryDependencies: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
518
+ /** Versioned packages: { "@vitrine-kit/core": ">=1.0.0" }. */
519
+ corePackages: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
520
+ npm: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
521
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
522
+ from: z.ZodString;
523
+ to: z.ZodString;
524
+ }, "strip", z.ZodTypeAny, {
525
+ from: string;
526
+ to: string;
527
+ }, {
528
+ from: string;
529
+ to: string;
530
+ }>, "many">>;
531
+ config: z.ZodOptional<z.ZodObject<{
532
+ set: z.ZodRecord<z.ZodString, z.ZodBoolean>;
533
+ }, "strip", z.ZodTypeAny, {
534
+ set: Record<string, boolean>;
535
+ }, {
536
+ set: Record<string, boolean>;
537
+ }>>;
538
+ /**
539
+ * The payment provider of a checkout-<provider> feature. From it the CLI: (1) generates
540
+ * the provider registration in lib/payments.ts, (2) sets integrations.payments
541
+ * in site.config. register<Pascal>Provider() is exported from lib/<name>/register.ts.
542
+ */
543
+ payment: z.ZodOptional<z.ZodObject<{
544
+ provider: z.ZodEnum<["stripe", "paddle", "yookassa"]>;
545
+ }, "strip", z.ZodTypeAny, {
546
+ provider: "stripe" | "paddle" | "yookassa";
547
+ }, {
548
+ provider: "stripe" | "paddle" | "yookassa";
549
+ }>>;
550
+ slots: z.ZodDefault<z.ZodArray<z.ZodObject<{
551
+ slot: z.ZodEnum<["global.banner-top", "global.header-start", "global.header-nav", "global.header-actions", "global.footer", "global.body-end", "home.hero", "home.below-hero", "home.sections", "home.bottom", "catalog.toolbar", "catalog.sidebar", "catalog.grid-top", "catalog.grid-bottom", "category.header", "category.below-products", "product.gallery", "product.below-title", "product.below-price", "product.purchase", "product.below-description", "product.tabs", "product.related", "cart.items-bottom", "cart.summary", "cart.below", "checkout.top", "checkout.below", "order.top", "order.below", "search.results-top", "search.empty"]>;
552
+ component: z.ZodString;
553
+ order: z.ZodOptional<z.ZodNumber>;
554
+ }, "strip", z.ZodTypeAny, {
555
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
556
+ component: string;
557
+ order?: number | undefined;
558
+ }, {
559
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
560
+ component: string;
561
+ order?: number | undefined;
562
+ }>, "many">>;
563
+ blueprint: z.ZodOptional<z.ZodObject<{
564
+ extend: z.ZodEnum<["product", "variant", "category", "media", "order", "user"]>;
565
+ addFields: z.ZodArray<z.ZodString, "many">;
566
+ }, "strip", z.ZodTypeAny, {
567
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
568
+ addFields: string[];
569
+ }, {
570
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
571
+ addFields: string[];
572
+ }>>;
573
+ env: z.ZodDefault<z.ZodArray<z.ZodObject<{
574
+ key: z.ZodString;
575
+ required: z.ZodDefault<z.ZodBoolean>;
576
+ }, "strip", z.ZodTypeAny, {
577
+ required: boolean;
578
+ key: string;
579
+ }, {
580
+ key: string;
581
+ required?: boolean | undefined;
582
+ }>, "many">>;
583
+ /** Doc appended to the client's CLAUDE.md. */
584
+ claudeDoc: z.ZodOptional<z.ZodString>;
585
+ conflicts: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
586
+ removable: z.ZodDefault<z.ZodBoolean>;
587
+ }, "strip", z.ZodTypeAny, {
588
+ name: string;
589
+ tier: ["catalog" | "simple-store" | "full-store", ...("catalog" | "simple-store" | "full-store")[]];
590
+ title: string;
591
+ kitVersion: string;
592
+ requiresContracts: string;
593
+ registryDependencies: string[];
594
+ corePackages: Record<string, string>;
595
+ npm: string[];
596
+ files: {
597
+ from: string;
598
+ to: string;
599
+ }[];
600
+ slots: {
601
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
602
+ component: string;
603
+ order?: number | undefined;
604
+ }[];
605
+ env: {
606
+ required: boolean;
607
+ key: string;
608
+ }[];
609
+ conflicts: string[];
610
+ removable: boolean;
611
+ config?: {
612
+ set: Record<string, boolean>;
613
+ } | undefined;
614
+ payment?: {
615
+ provider: "stripe" | "paddle" | "yookassa";
616
+ } | undefined;
617
+ blueprint?: {
618
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
619
+ addFields: string[];
620
+ } | undefined;
621
+ claudeDoc?: string | undefined;
622
+ }, {
623
+ name: string;
624
+ tier: ["catalog" | "simple-store" | "full-store", ...("catalog" | "simple-store" | "full-store")[]];
625
+ title: string;
626
+ kitVersion: string;
627
+ requiresContracts: string;
628
+ registryDependencies?: string[] | undefined;
629
+ corePackages?: Record<string, string> | undefined;
630
+ npm?: string[] | undefined;
631
+ files?: {
632
+ from: string;
633
+ to: string;
634
+ }[] | undefined;
635
+ config?: {
636
+ set: Record<string, boolean>;
637
+ } | undefined;
638
+ payment?: {
639
+ provider: "stripe" | "paddle" | "yookassa";
640
+ } | undefined;
641
+ slots?: {
642
+ slot: "global.banner-top" | "global.header-start" | "global.header-nav" | "global.header-actions" | "global.footer" | "global.body-end" | "home.hero" | "home.below-hero" | "home.sections" | "home.bottom" | "catalog.toolbar" | "catalog.sidebar" | "catalog.grid-top" | "catalog.grid-bottom" | "category.header" | "category.below-products" | "product.gallery" | "product.below-title" | "product.below-price" | "product.purchase" | "product.below-description" | "product.tabs" | "product.related" | "cart.items-bottom" | "cart.summary" | "cart.below" | "checkout.top" | "checkout.below" | "order.top" | "order.below" | "search.results-top" | "search.empty";
643
+ component: string;
644
+ order?: number | undefined;
645
+ }[] | undefined;
646
+ blueprint?: {
647
+ extend: "order" | "media" | "product" | "variant" | "category" | "user";
648
+ addFields: string[];
649
+ } | undefined;
650
+ env?: {
651
+ key: string;
652
+ required?: boolean | undefined;
653
+ }[] | undefined;
654
+ claudeDoc?: string | undefined;
655
+ conflicts?: string[] | undefined;
656
+ removable?: boolean | undefined;
657
+ }>;
658
+ type FeatureManifest = z.infer<typeof featureManifestSchema>;
659
+ /** vitrine.json — the client repo's lock file (§6). */
660
+ declare const vitrineLockSchema: z.ZodObject<{
661
+ kitVersion: z.ZodString;
662
+ contracts: z.ZodString;
663
+ backend: z.ZodEnum<["payload", "vendure"]>;
664
+ tier: z.ZodEnum<["catalog", "simple-store", "full-store"]>;
665
+ features: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
666
+ version: z.ZodString;
667
+ }, "strip", z.ZodTypeAny, {
668
+ version: string;
669
+ }, {
670
+ version: string;
671
+ }>>>;
672
+ }, "strip", z.ZodTypeAny, {
673
+ backend: "payload" | "vendure";
674
+ tier: "catalog" | "simple-store" | "full-store";
675
+ features: Record<string, {
676
+ version: string;
677
+ }>;
678
+ kitVersion: string;
679
+ contracts: string;
680
+ }, {
681
+ backend: "payload" | "vendure";
682
+ tier: "catalog" | "simple-store" | "full-store";
683
+ kitVersion: string;
684
+ contracts: string;
685
+ features?: Record<string, {
686
+ version: string;
687
+ }> | undefined;
688
+ }>;
689
+ type VitrineLock = z.infer<typeof vitrineLockSchema>;
690
+ /** registry/_index.json — the registry manifest: all features + the kit version. */
691
+ declare const registryIndexSchema: z.ZodObject<{
692
+ kitVersion: z.ZodString;
693
+ contracts: z.ZodString;
694
+ features: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
695
+ title: z.ZodString;
696
+ kitVersion: z.ZodString;
697
+ tier: z.ZodArray<z.ZodEnum<["catalog", "simple-store", "full-store"]>, "many">;
698
+ }, "strip", z.ZodTypeAny, {
699
+ tier: ("catalog" | "simple-store" | "full-store")[];
700
+ title: string;
701
+ kitVersion: string;
702
+ }, {
703
+ tier: ("catalog" | "simple-store" | "full-store")[];
704
+ title: string;
705
+ kitVersion: string;
706
+ }>>>;
707
+ }, "strip", z.ZodTypeAny, {
708
+ features: Record<string, {
709
+ tier: ("catalog" | "simple-store" | "full-store")[];
710
+ title: string;
711
+ kitVersion: string;
712
+ }>;
713
+ kitVersion: string;
714
+ contracts: string;
715
+ }, {
716
+ kitVersion: string;
717
+ contracts: string;
718
+ features?: Record<string, {
719
+ tier: ("catalog" | "simple-store" | "full-store")[];
720
+ title: string;
721
+ kitVersion: string;
722
+ }> | undefined;
723
+ }>;
724
+ type RegistryIndex = z.infer<typeof registryIndexSchema>;
725
+
726
+ declare const CONTRACTS_VERSION: "1.0.0";
727
+
728
+ export { BACKENDS, BLUEPRINT_COLLECTIONS, BLUEPRINT_FIELD_TYPES, type Backend, type BlueprintCollection, type BlueprintExtension, type BlueprintFieldDef, type BlueprintFieldType, type BlueprintManifest, COLOR_TOKENS, CONTRACTS_VERSION, type Cart, type CartLine, type CatalogSource, type Category, type ColorToken, type CommerceBackend, type CurrencyCode, type Extend, FONT_TOKENS, FONT_WEIGHT_TOKENS, type FeatureManifest, type FontToken, type FontWeightToken, LEADING_TOKENS, type LayoutSection, type LeadingToken, MOTION_TOKENS, type Money, type MotionToken, type Order, type OrderLine, type OrderStatus, type Product, type ProductImage, type ProductQuery, type ProductSort, RADIUS_TOKENS, type RadiusToken, type RegistryIndex, SHADOW_TOKENS, SINGLETON_TOKENS, SLOT_IDS, SPACE_TOKENS, type Seo, type ShadowToken, type SingletonToken, type SiteConfig, type SlotId, type SlotMount, type SlotRegistration, type SpaceToken, TIERS, TOKEN_CSS_VARS, TRACKING_TOKENS, type Tier, type TrackingToken, type Variant, type VitrineLock, backendSchema, blueprintCollectionSchema, blueprintFieldDefSchema, blueprintManifestSchema, cssVar, featureEnvSchema, featureFileMapSchema, featureManifestSchema, i18nSchema, integrationsSchema, layoutSectionSchema, registryIndexSchema, siteConfigSchema, slotIdSchema, slotRegistrationSchema, themeSchema, tierSchema, vitrineLockSchema, vitrinePreset };
package/dist/index.d.ts CHANGED
@@ -45,7 +45,7 @@ declare const vitrinePreset: {
45
45
 
46
46
  /**
47
47
  * Money — an integer in the currency's minor units (cents).
48
- * 199000 = 1990.00. Decision is fixed (see the demo seed, spec §18.2).
48
+ * 2490 = 24.90. Decision is fixed (see the demo seed, spec §18.2).
49
49
  */
50
50
  type Money = number;
51
51
  /** ISO 4217, e.g. 'USD', 'EUR', 'GBP'. */
@@ -109,6 +109,15 @@ interface ProductQuery {
109
109
  perPage?: number;
110
110
  /** Filter facets: { color: ['red','blue'], size: ['M'] }. */
111
111
  filters?: Record<string, string[]>;
112
+ /** Inclusive lower bound on variant/list price (minor units, e.g. cents). */
113
+ priceMin?: number;
114
+ /** Inclusive upper bound on variant/list price (minor units, e.g. cents). */
115
+ priceMax?: number;
116
+ /**
117
+ * CMS / storefront locale (path cookie or explicit). Adapters that support
118
+ * localized fields pass this through to the backend; others ignore it.
119
+ */
120
+ locale?: string;
112
121
  }
113
122
  interface CartLine {
114
123
  id: string;
@@ -156,9 +165,10 @@ interface Order {
156
165
  */
157
166
  interface CatalogSource {
158
167
  listProducts(query: ProductQuery): Promise<Product[]>;
159
- getProduct(slug: string): Promise<Product | null>;
160
- listCategories(): Promise<Category[]>;
161
- search(term: string): Promise<Product[]>;
168
+ /** Optional locale selects localized CMS fields when the backend supports them. */
169
+ getProduct(slug: string, locale?: string): Promise<Product | null>;
170
+ listCategories(locale?: string): Promise<Category[]>;
171
+ search(term: string, locale?: string): Promise<Product[]>;
162
172
  }
163
173
  /**
164
174
  * Commerce backend. Only simple-store / full-store.
@@ -278,6 +288,11 @@ declare const themeSchema: z.ZodDefault<z.ZodObject<{
278
288
  declare const siteConfigSchema: z.ZodObject<{
279
289
  backend: z.ZodEnum<["payload", "vendure"]>;
280
290
  tier: z.ZodEnum<["catalog", "simple-store", "full-store"]>;
291
+ /**
292
+ * Storefront display name (header, metadata, footer). Set by `vitrine init`
293
+ * from the project name; optional for older clients.
294
+ */
295
+ name: z.ZodOptional<z.ZodString>;
281
296
  /** Feature flags: { 'reviews': true }. Set by the install primitive. */
282
297
  features: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
283
298
  layout: z.ZodDefault<z.ZodObject<{
@@ -382,9 +397,11 @@ declare const siteConfigSchema: z.ZodObject<{
382
397
  currency: string;
383
398
  priceFormat?: string | undefined;
384
399
  };
400
+ name?: string | undefined;
385
401
  }, {
386
402
  backend: "payload" | "vendure";
387
403
  tier: "catalog" | "simple-store" | "full-store";
404
+ name?: string | undefined;
388
405
  features?: Record<string, boolean> | undefined;
389
406
  layout?: {
390
407
  sections?: {
package/dist/index.js CHANGED
@@ -179,6 +179,11 @@ var themeSchema = z3.object({
179
179
  var siteConfigSchema = z3.object({
180
180
  backend: backendSchema,
181
181
  tier: tierSchema,
182
+ /**
183
+ * Storefront display name (header, metadata, footer). Set by `vitrine init`
184
+ * from the project name; optional for older clients.
185
+ */
186
+ name: z3.string().min(1).optional(),
182
187
  /** Feature flags: { 'reviews': true }. Set by the install primitive. */
183
188
  features: z3.record(z3.string(), z3.boolean()).default({}),
184
189
  layout: z3.object({ sections: z3.array(layoutSectionSchema).default([]) }).default({ sections: [] }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitrine-kit/contracts",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Vitrine — the five stable contracts: Tokens, Data, Slots, Config, Blueprint.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,12 +9,14 @@
9
9
  "node": ">=20"
10
10
  },
11
11
  "types": "./dist/index.d.ts",
12
- "main": "./dist/index.js",
12
+ "main": "./dist/index.cjs",
13
13
  "module": "./dist/index.js",
14
14
  "exports": {
15
15
  ".": {
16
16
  "types": "./dist/index.d.ts",
17
- "import": "./dist/index.js"
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.cjs",
19
+ "default": "./dist/index.js"
18
20
  }
19
21
  },
20
22
  "files": [
@@ -36,7 +38,7 @@
36
38
  "zod-to-json-schema": "^3.24.1"
37
39
  },
38
40
  "scripts": {
39
- "build": "tsup src/index.ts --format esm --dts --clean",
41
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean",
40
42
  "typecheck": "tsc --noEmit",
41
43
  "test": "vitest run --passWithNoTests",
42
44
  "schemas": "tsx scripts/generate-schemas.ts"