@salixcommerce/config 0.1.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 ADDED
@@ -0,0 +1,13 @@
1
+ # @salixcommerce/config
2
+
3
+ Strict typed configuration boundary for one standalone Salix Commerce application.
4
+
5
+ ## Public configuration
6
+
7
+ Import from `@salixcommerce/config/public` or the package root. The application schema validates business identity, commerce behavior, fulfillment, supported feature flags, content/navigation metadata, and theme tokens. Unknown keys fail. `serializePublicConfiguration` constructs the browser-safe allowlist and omits the server-side shipping strategy.
8
+
9
+ ## Server environment
10
+
11
+ Import `parseServerEnvironment` from `@salixcommerce/config/server` only inside a generated server-only wrapper. It ignores unrelated host variables, rejects unknown `SALIX_*` variables, converts blank optional values to absence, and requires Supabase, Stripe, and email credential pairs to be complete when configured.
12
+
13
+ SC09 supports an explicit `disabled|fake|stripe` payment-provider selector and an optional Supabase publishable key for authenticated administrator cookie sessions. Fake payments require Supabase persistence and a 32+ character signing secret, reject production mode, and fail validation when a dormant secret is present. Stripe selection requires the Supabase pair, Stripe secret/webhook pair, and an approved checkout origin. Production origins must use HTTPS; test and development may use local HTTP. `.env.example` contains names only.
@@ -0,0 +1,252 @@
1
+ import { z } from "zod";
2
+ export declare const businessConfigurationSchema: z.ZodObject<{
3
+ currency: z.ZodDefault<z.ZodString>;
4
+ displayName: z.ZodString;
5
+ legalName: z.ZodOptional<z.ZodString>;
6
+ locale: z.ZodDefault<z.ZodString>;
7
+ publicUrl: z.ZodOptional<z.ZodString>;
8
+ supportEmail: z.ZodOptional<z.ZodString>;
9
+ supportPhone: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strict>;
11
+ export declare const commerceConfigurationSchema: z.ZodObject<{
12
+ allowBackorders: z.ZodDefault<z.ZodBoolean>;
13
+ customerAccounts: z.ZodDefault<z.ZodLiteral<false>>;
14
+ guestCheckout: z.ZodDefault<z.ZodBoolean>;
15
+ inventoryEnforcement: z.ZodDefault<z.ZodEnum<{
16
+ none: "none";
17
+ tracked: "tracked";
18
+ }>>;
19
+ }, z.core.$strict>;
20
+ export declare const fulfillmentConfigurationSchema: z.ZodObject<{
21
+ localPickup: z.ZodPrefault<z.ZodObject<{
22
+ enabled: z.ZodDefault<z.ZodBoolean>;
23
+ instructions: z.ZodOptional<z.ZodString>;
24
+ locationName: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strict>>;
26
+ shipping: z.ZodPrefault<z.ZodObject<{
27
+ enabled: z.ZodDefault<z.ZodBoolean>;
28
+ strategy: z.ZodOptional<z.ZodString>;
29
+ supportedCountries: z.ZodDefault<z.ZodArray<z.ZodString>>;
30
+ }, z.core.$strict>>;
31
+ }, z.core.$strict>;
32
+ export declare const featureConfigurationSchema: z.ZodObject<{
33
+ discounts: z.ZodDefault<z.ZodLiteral<false>>;
34
+ productReviews: z.ZodDefault<z.ZodLiteral<false>>;
35
+ recipes: z.ZodDefault<z.ZodBoolean>;
36
+ }, z.core.$strict>;
37
+ export declare const contentConfigurationSchema: z.ZodObject<{
38
+ metadata: z.ZodDefault<z.ZodObject<{
39
+ defaultDescription: z.ZodOptional<z.ZodString>;
40
+ defaultTitle: z.ZodOptional<z.ZodString>;
41
+ socialImagePath: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strict>>;
43
+ navigation: z.ZodDefault<z.ZodArray<z.ZodObject<{
44
+ external: z.ZodDefault<z.ZodBoolean>;
45
+ href: z.ZodString;
46
+ label: z.ZodString;
47
+ }, z.core.$strict>>>;
48
+ policyPaths: z.ZodDefault<z.ZodObject<{
49
+ privacy: z.ZodOptional<z.ZodString>;
50
+ refunds: z.ZodOptional<z.ZodString>;
51
+ shipping: z.ZodOptional<z.ZodString>;
52
+ terms: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strict>>;
54
+ socialLinks: z.ZodDefault<z.ZodArray<z.ZodObject<{
55
+ label: z.ZodString;
56
+ url: z.ZodString;
57
+ }, z.core.$strict>>>;
58
+ }, z.core.$strict>;
59
+ export declare const themeConfigurationSchema: z.ZodObject<{
60
+ assets: z.ZodDefault<z.ZodObject<{
61
+ iconPath: z.ZodOptional<z.ZodString>;
62
+ logoPath: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strict>>;
64
+ colors: z.ZodDefault<z.ZodObject<{
65
+ accent: z.ZodOptional<z.ZodString>;
66
+ background: z.ZodOptional<z.ZodString>;
67
+ foreground: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strict>>;
69
+ }, z.core.$strict>;
70
+ export declare const applicationConfigurationSchema: z.ZodObject<{
71
+ business: z.ZodObject<{
72
+ currency: z.ZodDefault<z.ZodString>;
73
+ displayName: z.ZodString;
74
+ legalName: z.ZodOptional<z.ZodString>;
75
+ locale: z.ZodDefault<z.ZodString>;
76
+ publicUrl: z.ZodOptional<z.ZodString>;
77
+ supportEmail: z.ZodOptional<z.ZodString>;
78
+ supportPhone: z.ZodOptional<z.ZodString>;
79
+ }, z.core.$strict>;
80
+ commerce: z.ZodPrefault<z.ZodObject<{
81
+ allowBackorders: z.ZodDefault<z.ZodBoolean>;
82
+ customerAccounts: z.ZodDefault<z.ZodLiteral<false>>;
83
+ guestCheckout: z.ZodDefault<z.ZodBoolean>;
84
+ inventoryEnforcement: z.ZodDefault<z.ZodEnum<{
85
+ none: "none";
86
+ tracked: "tracked";
87
+ }>>;
88
+ }, z.core.$strict>>;
89
+ content: z.ZodPrefault<z.ZodObject<{
90
+ metadata: z.ZodDefault<z.ZodObject<{
91
+ defaultDescription: z.ZodOptional<z.ZodString>;
92
+ defaultTitle: z.ZodOptional<z.ZodString>;
93
+ socialImagePath: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strict>>;
95
+ navigation: z.ZodDefault<z.ZodArray<z.ZodObject<{
96
+ external: z.ZodDefault<z.ZodBoolean>;
97
+ href: z.ZodString;
98
+ label: z.ZodString;
99
+ }, z.core.$strict>>>;
100
+ policyPaths: z.ZodDefault<z.ZodObject<{
101
+ privacy: z.ZodOptional<z.ZodString>;
102
+ refunds: z.ZodOptional<z.ZodString>;
103
+ shipping: z.ZodOptional<z.ZodString>;
104
+ terms: z.ZodOptional<z.ZodString>;
105
+ }, z.core.$strict>>;
106
+ socialLinks: z.ZodDefault<z.ZodArray<z.ZodObject<{
107
+ label: z.ZodString;
108
+ url: z.ZodString;
109
+ }, z.core.$strict>>>;
110
+ }, z.core.$strict>>;
111
+ features: z.ZodPrefault<z.ZodObject<{
112
+ discounts: z.ZodDefault<z.ZodLiteral<false>>;
113
+ productReviews: z.ZodDefault<z.ZodLiteral<false>>;
114
+ recipes: z.ZodDefault<z.ZodBoolean>;
115
+ }, z.core.$strict>>;
116
+ fulfillment: z.ZodPrefault<z.ZodObject<{
117
+ localPickup: z.ZodPrefault<z.ZodObject<{
118
+ enabled: z.ZodDefault<z.ZodBoolean>;
119
+ instructions: z.ZodOptional<z.ZodString>;
120
+ locationName: z.ZodOptional<z.ZodString>;
121
+ }, z.core.$strict>>;
122
+ shipping: z.ZodPrefault<z.ZodObject<{
123
+ enabled: z.ZodDefault<z.ZodBoolean>;
124
+ strategy: z.ZodOptional<z.ZodString>;
125
+ supportedCountries: z.ZodDefault<z.ZodArray<z.ZodString>>;
126
+ }, z.core.$strict>>;
127
+ }, z.core.$strict>>;
128
+ theme: z.ZodPrefault<z.ZodObject<{
129
+ assets: z.ZodDefault<z.ZodObject<{
130
+ iconPath: z.ZodOptional<z.ZodString>;
131
+ logoPath: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strict>>;
133
+ colors: z.ZodDefault<z.ZodObject<{
134
+ accent: z.ZodOptional<z.ZodString>;
135
+ background: z.ZodOptional<z.ZodString>;
136
+ foreground: z.ZodOptional<z.ZodString>;
137
+ }, z.core.$strict>>;
138
+ }, z.core.$strict>>;
139
+ }, z.core.$strict>;
140
+ export declare const publicApplicationConfigurationSchema: z.ZodObject<{
141
+ business: z.ZodObject<{
142
+ currency: z.ZodDefault<z.ZodString>;
143
+ displayName: z.ZodString;
144
+ legalName: z.ZodOptional<z.ZodString>;
145
+ locale: z.ZodDefault<z.ZodString>;
146
+ publicUrl: z.ZodOptional<z.ZodString>;
147
+ supportEmail: z.ZodOptional<z.ZodString>;
148
+ supportPhone: z.ZodOptional<z.ZodString>;
149
+ }, z.core.$strict>;
150
+ commerce: z.ZodObject<{
151
+ allowBackorders: z.ZodDefault<z.ZodBoolean>;
152
+ customerAccounts: z.ZodDefault<z.ZodLiteral<false>>;
153
+ guestCheckout: z.ZodDefault<z.ZodBoolean>;
154
+ inventoryEnforcement: z.ZodDefault<z.ZodEnum<{
155
+ none: "none";
156
+ tracked: "tracked";
157
+ }>>;
158
+ }, z.core.$strict>;
159
+ content: z.ZodObject<{
160
+ metadata: z.ZodDefault<z.ZodObject<{
161
+ defaultDescription: z.ZodOptional<z.ZodString>;
162
+ defaultTitle: z.ZodOptional<z.ZodString>;
163
+ socialImagePath: z.ZodOptional<z.ZodString>;
164
+ }, z.core.$strict>>;
165
+ navigation: z.ZodDefault<z.ZodArray<z.ZodObject<{
166
+ external: z.ZodDefault<z.ZodBoolean>;
167
+ href: z.ZodString;
168
+ label: z.ZodString;
169
+ }, z.core.$strict>>>;
170
+ policyPaths: z.ZodDefault<z.ZodObject<{
171
+ privacy: z.ZodOptional<z.ZodString>;
172
+ refunds: z.ZodOptional<z.ZodString>;
173
+ shipping: z.ZodOptional<z.ZodString>;
174
+ terms: z.ZodOptional<z.ZodString>;
175
+ }, z.core.$strict>>;
176
+ socialLinks: z.ZodDefault<z.ZodArray<z.ZodObject<{
177
+ label: z.ZodString;
178
+ url: z.ZodString;
179
+ }, z.core.$strict>>>;
180
+ }, z.core.$strict>;
181
+ features: z.ZodObject<{
182
+ discounts: z.ZodDefault<z.ZodLiteral<false>>;
183
+ productReviews: z.ZodDefault<z.ZodLiteral<false>>;
184
+ recipes: z.ZodDefault<z.ZodBoolean>;
185
+ }, z.core.$strict>;
186
+ fulfillment: z.ZodObject<{
187
+ localPickup: z.ZodObject<{
188
+ enabled: z.ZodDefault<z.ZodBoolean>;
189
+ instructions: z.ZodOptional<z.ZodString>;
190
+ locationName: z.ZodOptional<z.ZodString>;
191
+ }, z.core.$strict>;
192
+ shipping: z.ZodObject<{
193
+ enabled: z.ZodBoolean;
194
+ supportedCountries: z.ZodArray<z.ZodString>;
195
+ }, z.core.$strict>;
196
+ }, z.core.$strict>;
197
+ theme: z.ZodObject<{
198
+ assets: z.ZodDefault<z.ZodObject<{
199
+ iconPath: z.ZodOptional<z.ZodString>;
200
+ logoPath: z.ZodOptional<z.ZodString>;
201
+ }, z.core.$strict>>;
202
+ colors: z.ZodDefault<z.ZodObject<{
203
+ accent: z.ZodOptional<z.ZodString>;
204
+ background: z.ZodOptional<z.ZodString>;
205
+ foreground: z.ZodOptional<z.ZodString>;
206
+ }, z.core.$strict>>;
207
+ }, z.core.$strict>;
208
+ }, z.core.$strict>;
209
+ export type ApplicationConfigurationInput = z.input<typeof applicationConfigurationSchema>;
210
+ export type ApplicationConfiguration = z.output<typeof applicationConfigurationSchema>;
211
+ export type PublicApplicationConfiguration = z.output<typeof publicApplicationConfigurationSchema>;
212
+ export type FeatureName = keyof ApplicationConfiguration["features"];
213
+ export declare const APPLICATION_CONFIGURATION_DEFAULTS: {
214
+ readonly commerce: {
215
+ readonly allowBackorders: false;
216
+ readonly customerAccounts: false;
217
+ readonly guestCheckout: true;
218
+ readonly inventoryEnforcement: "none";
219
+ };
220
+ readonly content: {
221
+ readonly metadata: {};
222
+ readonly navigation: readonly [];
223
+ readonly policyPaths: {};
224
+ readonly socialLinks: readonly [];
225
+ };
226
+ readonly features: {
227
+ readonly discounts: false;
228
+ readonly productReviews: false;
229
+ readonly recipes: false;
230
+ };
231
+ readonly fulfillment: {
232
+ readonly localPickup: {
233
+ readonly enabled: false;
234
+ };
235
+ readonly shipping: {
236
+ readonly enabled: false;
237
+ readonly supportedCountries: readonly [];
238
+ };
239
+ };
240
+ readonly theme: {
241
+ readonly assets: {};
242
+ readonly colors: {};
243
+ };
244
+ };
245
+ export declare class DisabledFeatureError extends Error {
246
+ readonly feature: FeatureName;
247
+ constructor(feature: FeatureName);
248
+ }
249
+ export declare function parseApplicationConfiguration(input: unknown): ApplicationConfiguration;
250
+ export declare function serializePublicConfiguration(configuration: ApplicationConfiguration): PublicApplicationConfiguration;
251
+ export declare function assertFeatureEnabled(configuration: ApplicationConfiguration, feature: FeatureName): void;
252
+ //# sourceMappingURL=application.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoCxB,eAAO,MAAM,2BAA2B;;;;;;;;kBAQtC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;kBAepC,CAAC;AA2DL,eAAO,MAAM,8BAA8B;;;;;;;;;;;kBAGzC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;kBAIrC,CAAC;AAyCH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;kBAKrC,CAAC;AAaH,eAAO,MAAM,wBAAwB;;;;;;;;;;kBAGnC,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAOzC,CAAC;AAOH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAU/C,CAAC;AAEH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAC3F,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,8BAA8B,CAAC,CAAC;AACvF,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oCAAoC,CAAC,CAAC;AACnG,MAAM,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,UAAU,CAAC,CAAC;AAErE,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAcrC,CAAC;AAEX,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAgB,OAAO,EAAE,WAAW,CAAC;gBAElB,OAAO,EAAE,WAAW;CAKxC;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAEtF;AAED,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,wBAAwB,GACtC,8BAA8B,CAehC;AAED,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,wBAAwB,EACvC,OAAO,EAAE,WAAW,GACnB,IAAI,CAEN"}
@@ -0,0 +1,266 @@
1
+ import { z } from "zod";
2
+ const localeSchema = z
3
+ .string()
4
+ .trim()
5
+ .min(2)
6
+ .max(35)
7
+ .refine(isLocale, "Locale must be a valid Unicode locale identifier.");
8
+ const currencySchema = z
9
+ .string()
10
+ .trim()
11
+ .regex(/^[A-Z]{3}$/u, "Currency must be an uppercase ISO 4217 code.")
12
+ .refine(isCurrency, "Currency must be supported by the JavaScript runtime.");
13
+ const countrySchema = z
14
+ .string()
15
+ .trim()
16
+ .regex(/^[A-Z]{2}$/u, "Country must be an uppercase ISO 3166-1 alpha-2 code.");
17
+ const internalPathSchema = z
18
+ .string()
19
+ .trim()
20
+ .min(1)
21
+ .max(300)
22
+ .refine((value) => value.startsWith("/") && !value.startsWith("//"), "Path must be root-relative and may not start with //.");
23
+ const httpsUrlSchema = z
24
+ .string()
25
+ .trim()
26
+ .url()
27
+ .refine((value) => value.startsWith("https://"), "URL must use HTTPS.");
28
+ const hexColorSchema = z
29
+ .string()
30
+ .trim()
31
+ .regex(/^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/iu, "Color must use six- or eight-digit hex.");
32
+ export const businessConfigurationSchema = z.strictObject({
33
+ currency: currencySchema.default("USD"),
34
+ displayName: z.string().trim().min(1).max(100),
35
+ legalName: z.string().trim().min(1).max(160).optional(),
36
+ locale: localeSchema.default("en-US"),
37
+ publicUrl: httpsUrlSchema.optional(),
38
+ supportEmail: z.string().trim().email().optional(),
39
+ supportPhone: z.string().trim().min(3).max(40).optional(),
40
+ });
41
+ export const commerceConfigurationSchema = z
42
+ .strictObject({
43
+ allowBackorders: z.boolean().default(false),
44
+ customerAccounts: z.literal(false).default(false),
45
+ guestCheckout: z.boolean().default(true),
46
+ inventoryEnforcement: z.enum(["none", "tracked"]).default("none"),
47
+ })
48
+ .superRefine((value, context) => {
49
+ if (value.allowBackorders && value.inventoryEnforcement !== "tracked") {
50
+ context.addIssue({
51
+ code: "custom",
52
+ message: "Backorders require tracked inventory.",
53
+ path: ["allowBackorders"],
54
+ });
55
+ }
56
+ });
57
+ const shippingConfigurationSchema = z
58
+ .strictObject({
59
+ enabled: z.boolean().default(false),
60
+ strategy: z
61
+ .string()
62
+ .trim()
63
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u, "Shipping strategy must be a slug.")
64
+ .optional(),
65
+ supportedCountries: z.array(countrySchema).max(249).default([]),
66
+ })
67
+ .superRefine((value, context) => {
68
+ if (value.enabled && value.strategy === undefined) {
69
+ context.addIssue({
70
+ code: "custom",
71
+ message: "Enabled shipping requires a server-side strategy identifier.",
72
+ path: ["strategy"],
73
+ });
74
+ }
75
+ if (value.enabled && value.supportedCountries.length === 0) {
76
+ context.addIssue({
77
+ code: "custom",
78
+ message: "Enabled shipping requires at least one supported country.",
79
+ path: ["supportedCountries"],
80
+ });
81
+ }
82
+ if (!value.enabled && (value.strategy !== undefined || value.supportedCountries.length > 0)) {
83
+ context.addIssue({
84
+ code: "custom",
85
+ message: "Disabled shipping may not retain a strategy or supported countries.",
86
+ path: ["enabled"],
87
+ });
88
+ }
89
+ });
90
+ const localPickupConfigurationSchema = z
91
+ .strictObject({
92
+ enabled: z.boolean().default(false),
93
+ instructions: z.string().trim().min(1).max(500).optional(),
94
+ locationName: z.string().trim().min(1).max(120).optional(),
95
+ })
96
+ .superRefine((value, context) => {
97
+ if (value.enabled && value.locationName === undefined) {
98
+ context.addIssue({
99
+ code: "custom",
100
+ message: "Enabled local pickup requires a public location name.",
101
+ path: ["locationName"],
102
+ });
103
+ }
104
+ if (!value.enabled && (value.locationName !== undefined || value.instructions !== undefined)) {
105
+ context.addIssue({
106
+ code: "custom",
107
+ message: "Disabled local pickup may not retain location details.",
108
+ path: ["enabled"],
109
+ });
110
+ }
111
+ });
112
+ export const fulfillmentConfigurationSchema = z.strictObject({
113
+ localPickup: localPickupConfigurationSchema.prefault({}),
114
+ shipping: shippingConfigurationSchema.prefault({}),
115
+ });
116
+ export const featureConfigurationSchema = z.strictObject({
117
+ discounts: z.literal(false).default(false),
118
+ productReviews: z.literal(false).default(false),
119
+ recipes: z.boolean().default(false),
120
+ });
121
+ const navigationItemSchema = z
122
+ .strictObject({
123
+ external: z.boolean().default(false),
124
+ href: z.string().trim().min(1).max(300),
125
+ label: z.string().trim().min(1).max(80),
126
+ })
127
+ .superRefine((value, context) => {
128
+ const result = value.external
129
+ ? httpsUrlSchema.safeParse(value.href)
130
+ : internalPathSchema.safeParse(value.href);
131
+ if (!result.success) {
132
+ context.addIssue({
133
+ code: "custom",
134
+ message: value.external
135
+ ? "External navigation must use an HTTPS URL."
136
+ : "Internal navigation must use a root-relative path.",
137
+ path: ["href"],
138
+ });
139
+ }
140
+ });
141
+ const policyPathSchema = z.strictObject({
142
+ privacy: internalPathSchema.optional(),
143
+ refunds: internalPathSchema.optional(),
144
+ shipping: internalPathSchema.optional(),
145
+ terms: internalPathSchema.optional(),
146
+ });
147
+ const metadataConfigurationSchema = z.strictObject({
148
+ defaultDescription: z.string().trim().min(1).max(320).optional(),
149
+ defaultTitle: z.string().trim().min(1).max(120).optional(),
150
+ socialImagePath: internalPathSchema.optional(),
151
+ });
152
+ const socialLinkSchema = z.strictObject({
153
+ label: z.string().trim().min(1).max(80),
154
+ url: httpsUrlSchema,
155
+ });
156
+ export const contentConfigurationSchema = z.strictObject({
157
+ metadata: metadataConfigurationSchema.default({}),
158
+ navigation: z.array(navigationItemSchema).max(30).default([]),
159
+ policyPaths: policyPathSchema.default({}),
160
+ socialLinks: z.array(socialLinkSchema).max(20).default([]),
161
+ });
162
+ const themeAssetSchema = z.strictObject({
163
+ iconPath: internalPathSchema.optional(),
164
+ logoPath: internalPathSchema.optional(),
165
+ });
166
+ const themeColorSchema = z.strictObject({
167
+ accent: hexColorSchema.optional(),
168
+ background: hexColorSchema.optional(),
169
+ foreground: hexColorSchema.optional(),
170
+ });
171
+ export const themeConfigurationSchema = z.strictObject({
172
+ assets: themeAssetSchema.default({}),
173
+ colors: themeColorSchema.default({}),
174
+ });
175
+ export const applicationConfigurationSchema = z.strictObject({
176
+ business: businessConfigurationSchema,
177
+ commerce: commerceConfigurationSchema.prefault({}),
178
+ content: contentConfigurationSchema.prefault({}),
179
+ features: featureConfigurationSchema.prefault({}),
180
+ fulfillment: fulfillmentConfigurationSchema.prefault({}),
181
+ theme: themeConfigurationSchema.prefault({}),
182
+ });
183
+ const publicShippingConfigurationSchema = z.strictObject({
184
+ enabled: z.boolean(),
185
+ supportedCountries: z.array(countrySchema),
186
+ });
187
+ export const publicApplicationConfigurationSchema = z.strictObject({
188
+ business: businessConfigurationSchema,
189
+ commerce: commerceConfigurationSchema,
190
+ content: contentConfigurationSchema,
191
+ features: featureConfigurationSchema,
192
+ fulfillment: z.strictObject({
193
+ localPickup: localPickupConfigurationSchema,
194
+ shipping: publicShippingConfigurationSchema,
195
+ }),
196
+ theme: themeConfigurationSchema,
197
+ });
198
+ export const APPLICATION_CONFIGURATION_DEFAULTS = {
199
+ commerce: {
200
+ allowBackorders: false,
201
+ customerAccounts: false,
202
+ guestCheckout: true,
203
+ inventoryEnforcement: "none",
204
+ },
205
+ content: { metadata: {}, navigation: [], policyPaths: {}, socialLinks: [] },
206
+ features: { discounts: false, productReviews: false, recipes: false },
207
+ fulfillment: {
208
+ localPickup: { enabled: false },
209
+ shipping: { enabled: false, supportedCountries: [] },
210
+ },
211
+ theme: { assets: {}, colors: {} },
212
+ };
213
+ export class DisabledFeatureError extends Error {
214
+ feature;
215
+ constructor(feature) {
216
+ super(`Feature '${feature}' is disabled by application configuration.`);
217
+ this.name = "DisabledFeatureError";
218
+ this.feature = feature;
219
+ }
220
+ }
221
+ export function parseApplicationConfiguration(input) {
222
+ return applicationConfigurationSchema.parse(input);
223
+ }
224
+ export function serializePublicConfiguration(configuration) {
225
+ return publicApplicationConfigurationSchema.parse({
226
+ business: configuration.business,
227
+ commerce: configuration.commerce,
228
+ content: configuration.content,
229
+ features: configuration.features,
230
+ fulfillment: {
231
+ localPickup: configuration.fulfillment.localPickup,
232
+ shipping: {
233
+ enabled: configuration.fulfillment.shipping.enabled,
234
+ supportedCountries: configuration.fulfillment.shipping.supportedCountries,
235
+ },
236
+ },
237
+ theme: configuration.theme,
238
+ });
239
+ }
240
+ export function assertFeatureEnabled(configuration, feature) {
241
+ if (configuration.features[feature] !== true)
242
+ throw new DisabledFeatureError(feature);
243
+ }
244
+ function isLocale(value) {
245
+ try {
246
+ new Intl.Locale(value);
247
+ return true;
248
+ }
249
+ catch {
250
+ return false;
251
+ }
252
+ }
253
+ function isCurrency(value) {
254
+ const supportedValuesOf = Intl.supportedValuesOf;
255
+ if (supportedValuesOf) {
256
+ return supportedValuesOf("currency").includes(value);
257
+ }
258
+ try {
259
+ new Intl.NumberFormat("en", { currency: value, style: "currency" }).format(0);
260
+ return true;
261
+ }
262
+ catch {
263
+ return false;
264
+ }
265
+ }
266
+ //# sourceMappingURL=application.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,EAAE,CAAC;KACP,MAAM,CAAC,QAAQ,EAAE,mDAAmD,CAAC,CAAC;AACzE,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,KAAK,CAAC,aAAa,EAAE,8CAA8C,CAAC;KACpE,MAAM,CAAC,UAAU,EAAE,uDAAuD,CAAC,CAAC;AAC/E,MAAM,aAAa,GAAG,CAAC;KACpB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,KAAK,CAAC,aAAa,EAAE,uDAAuD,CAAC,CAAC;AACjF,MAAM,kBAAkB,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,GAAG,CAAC;KACR,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAC3D,uDAAuD,CACxD,CAAC;AACJ,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,EAAE;KACL,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC,CAAC;AAC1E,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,KAAK,CAAC,kCAAkC,EAAE,yCAAyC,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,YAAY,CAAC;IACxD,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC;IACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACvD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC;IACrC,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE;IACpC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAClD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,YAAY,CAAC;IACZ,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3C,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACjD,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACxC,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CAClE,CAAC;KACD,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9B,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACtE,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,uCAAuC;YAChD,IAAI,EAAE,CAAC,iBAAiB,CAAC;SAC1B,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,2BAA2B,GAAG,CAAC;KAClC,YAAY,CAAC;IACZ,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,IAAI,EAAE;SACN,KAAK,CAAC,6BAA6B,EAAE,mCAAmC,CAAC;SACzE,QAAQ,EAAE;IACb,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChE,CAAC;KACD,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9B,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClD,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,8DAA8D;YACvE,IAAI,EAAE,CAAC,UAAU,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2DAA2D;YACpE,IAAI,EAAE,CAAC,oBAAoB,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5F,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,qEAAqE;YAC9E,IAAI,EAAE,CAAC,SAAS,CAAC;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,8BAA8B,GAAG,CAAC;KACrC,YAAY,CAAC;IACZ,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC1D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CAC3D,CAAC;KACD,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9B,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACtD,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,uDAAuD;YAChE,IAAI,EAAE,CAAC,cAAc,CAAC;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,EAAE,CAAC;QAC7F,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,wDAAwD;YACjE,IAAI,EAAE,CAAC,SAAS,CAAC;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,YAAY,CAAC;IAC3D,WAAW,EAAE,8BAA8B,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxD,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,EAAE,CAAC;CACnD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC1C,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACpC,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC;KAC3B,YAAY,CAAC;IACZ,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;CACxC,CAAC;KACD,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ;QAC3B,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;QACtC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,QAAQ,CAAC;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,KAAK,CAAC,QAAQ;gBACrB,CAAC,CAAC,4CAA4C;gBAC9C,CAAC,CAAC,oDAAoD;YACxD,IAAI,EAAE,CAAC,MAAM,CAAC;SACf,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,gBAAgB,GAAG,CAAC,CAAC,YAAY,CAAC;IACtC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACtC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACvC,KAAK,EAAE,kBAAkB,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,CAAC,CAAC,YAAY,CAAC;IACjD,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAChE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC1D,eAAe,EAAE,kBAAkB,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,YAAY,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,GAAG,EAAE,cAAc;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,QAAQ,EAAE,2BAA2B,CAAC,OAAO,CAAC,EAAE,CAAC;IACjD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7D,WAAW,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3D,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,YAAY,CAAC;IACtC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACvC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,YAAY,CAAC;IACtC,MAAM,EAAE,cAAc,CAAC,QAAQ,EAAE;IACjC,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE;IACrC,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,YAAY,CAAC;IACrD,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,YAAY,CAAC;IAC3D,QAAQ,EAAE,2BAA2B;IACrC,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,EAAE,CAAC;IAClD,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAAE,CAAC;IAChD,QAAQ,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjD,WAAW,EAAE,8BAA8B,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxD,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,iCAAiC,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC,YAAY,CAAC;IACjE,QAAQ,EAAE,2BAA2B;IACrC,QAAQ,EAAE,2BAA2B;IACrC,OAAO,EAAE,0BAA0B;IACnC,QAAQ,EAAE,0BAA0B;IACpC,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC;QAC1B,WAAW,EAAE,8BAA8B;QAC3C,QAAQ,EAAE,iCAAiC;KAC5C,CAAC;IACF,KAAK,EAAE,wBAAwB;CAChC,CAAC,CAAC;AAOH,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,QAAQ,EAAE;QACR,eAAe,EAAE,KAAK;QACtB,gBAAgB,EAAE,KAAK;QACvB,aAAa,EAAE,IAAI;QACnB,oBAAoB,EAAE,MAAM;KAC7B;IACD,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;IAC3E,QAAQ,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;IACrE,WAAW,EAAE;QACX,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;QAC/B,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE;KACrD;IACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;CACzB,CAAC;AAEX,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7B,OAAO,CAAc;IAErC,YAAmB,OAAoB;QACrC,KAAK,CAAC,YAAY,OAAO,6CAA6C,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAc;IAC1D,OAAO,8BAA8B,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,aAAuC;IAEvC,OAAO,oCAAoC,CAAC,KAAK,CAAC;QAChD,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,OAAO,EAAE,aAAa,CAAC,OAAO;QAC9B,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,WAAW,EAAE;YACX,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC,WAAW;YAClD,QAAQ,EAAE;gBACR,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO;gBACnD,kBAAkB,EAAE,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB;aAC1E;SACF;QACD,KAAK,EAAE,aAAa,CAAC,KAAK;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,aAAuC,EACvC,OAAoB;IAEpB,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,iBAAiB,GACrB,IACD,CAAC,iBAAiB,CAAC;IAEpB,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Stable package identity for SC01 workspace-link verification. */
2
+ export declare const CONFIG_PACKAGE_NAME: "@salixcommerce/config";
3
+ export { ConfigurationInputError, humanizeProjectName, parseBusinessName, parsePackageManager, parseProjectName, type SupportedPackageManager, } from "./project-input.js";
4
+ export * from "./public.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,EAAG,uBAAgC,CAAC;AAEpE,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,cAAc,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ /** Stable package identity for SC01 workspace-link verification. */
2
+ export const CONFIG_PACKAGE_NAME = "@salixcommerce/config";
3
+ export { ConfigurationInputError, humanizeProjectName, parseBusinessName, parsePackageManager, parseProjectName, } from "./project-input.js";
4
+ export * from "./public.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAgC,CAAC;AAEpE,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC;AAE5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type SupportedPackageManager = "npm" | "pnpm" | "yarn";
2
+ export declare class ConfigurationInputError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function parseProjectName(input: unknown): string;
6
+ export declare function humanizeProjectName(projectName: string): string;
7
+ export declare function parseBusinessName(input: unknown): string;
8
+ export declare function parsePackageManager(input: unknown): SupportedPackageManager;
9
+ //# sourceMappingURL=project-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-input.d.ts","sourceRoot":"","sources":["../src/project-input.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAM9D,qBAAa,uBAAwB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAInC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAmBvD;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM/D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAmBxD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAG3E"}
@@ -0,0 +1,54 @@
1
+ const projectNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
2
+ const windowsReservedNamePattern = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
3
+ const reservedProjectNames = new Set(["node_modules"]);
4
+ export class ConfigurationInputError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "ConfigurationInputError";
8
+ }
9
+ }
10
+ export function parseProjectName(input) {
11
+ if (typeof input !== "string") {
12
+ throw new ConfigurationInputError("Project name must be a string.");
13
+ }
14
+ const projectName = input.trim();
15
+ if (projectName.length < 1 || projectName.length > 64) {
16
+ throw new ConfigurationInputError("Project name must contain between 1 and 64 characters.");
17
+ }
18
+ if (!projectNamePattern.test(projectName)) {
19
+ throw new ConfigurationInputError("Project name must use lowercase letters, numbers, and single hyphens only.");
20
+ }
21
+ if (reservedProjectNames.has(projectName) || windowsReservedNamePattern.test(projectName)) {
22
+ throw new ConfigurationInputError(`Project name '${projectName}' is reserved.`);
23
+ }
24
+ return projectName;
25
+ }
26
+ export function humanizeProjectName(projectName) {
27
+ const parsedProjectName = parseProjectName(projectName);
28
+ return parsedProjectName
29
+ .split("-")
30
+ .map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`)
31
+ .join(" ");
32
+ }
33
+ export function parseBusinessName(input) {
34
+ if (typeof input !== "string") {
35
+ throw new ConfigurationInputError("Business name must be a string.");
36
+ }
37
+ const businessName = input.trim();
38
+ if (businessName.length < 1 || businessName.length > 100) {
39
+ throw new ConfigurationInputError("Business name must contain between 1 and 100 characters.");
40
+ }
41
+ if ([...businessName].some((character) => {
42
+ const code = character.codePointAt(0) ?? 0;
43
+ return code <= 31 || code === 127;
44
+ })) {
45
+ throw new ConfigurationInputError("Business name may not contain control characters.");
46
+ }
47
+ return businessName;
48
+ }
49
+ export function parsePackageManager(input) {
50
+ if (input === "npm" || input === "pnpm" || input === "yarn")
51
+ return input;
52
+ throw new ConfigurationInputError("Package manager must be one of: npm, pnpm, yarn.");
53
+ }
54
+ //# sourceMappingURL=project-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-input.js","sourceRoot":"","sources":["../src/project-input.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AACxD,MAAM,0BAA0B,GAAG,0CAA0C,CAAC;AAC9E,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AAEvD,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD,YAAmB,OAAe;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,uBAAuB,CAAC,gCAAgC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACtD,MAAM,IAAI,uBAAuB,CAAC,wDAAwD,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,uBAAuB,CAC/B,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IACD,IAAI,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1F,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,WAAW,gBAAgB,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACxD,OAAO,iBAAiB;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,uBAAuB,CAAC,iCAAiC,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACzD,MAAM,IAAI,uBAAuB,CAAC,0DAA0D,CAAC,CAAC;IAChG,CAAC;IACD,IACE,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,GAAG,CAAC;IACpC,CAAC,CAAC,EACF,CAAC;QACD,MAAM,IAAI,uBAAuB,CAAC,mDAAmD,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1E,MAAM,IAAI,uBAAuB,CAAC,kDAAkD,CAAC,CAAC;AACxF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { APPLICATION_CONFIGURATION_DEFAULTS, DisabledFeatureError, applicationConfigurationSchema, assertFeatureEnabled, businessConfigurationSchema, commerceConfigurationSchema, contentConfigurationSchema, featureConfigurationSchema, fulfillmentConfigurationSchema, parseApplicationConfiguration, publicApplicationConfigurationSchema, serializePublicConfiguration, themeConfigurationSchema, type ApplicationConfiguration, type ApplicationConfigurationInput, type FeatureName, type PublicApplicationConfiguration, } from "./application.js";
2
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,oBAAoB,EACpB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,6BAA6B,EAC7B,oCAAoC,EACpC,4BAA4B,EAC5B,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,WAAW,EAChB,KAAK,8BAA8B,GACpC,MAAM,kBAAkB,CAAC"}
package/dist/public.js ADDED
@@ -0,0 +1,2 @@
1
+ export { APPLICATION_CONFIGURATION_DEFAULTS, DisabledFeatureError, applicationConfigurationSchema, assertFeatureEnabled, businessConfigurationSchema, commerceConfigurationSchema, contentConfigurationSchema, featureConfigurationSchema, fulfillmentConfigurationSchema, parseApplicationConfiguration, publicApplicationConfigurationSchema, serializePublicConfiguration, themeConfigurationSchema, } from "./application.js";
2
+ //# sourceMappingURL=public.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,oBAAoB,EACpB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,6BAA6B,EAC7B,oCAAoC,EACpC,4BAA4B,EAC5B,wBAAwB,GAKzB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ export declare const serverEnvironmentSchema: z.ZodObject<{
3
+ NODE_ENV: z.ZodDefault<z.ZodEnum<{
4
+ test: "test";
5
+ development: "development";
6
+ production: "production";
7
+ }>>;
8
+ SALIX_CHECKOUT_BASE_URL: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
9
+ SALIX_FAKE_PAYMENT_SECRET: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
10
+ SALIX_INTERNAL_ORDER_EMAIL: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
11
+ SALIX_OBSERVABILITY_DSN: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
12
+ SALIX_PAYMENT_PROVIDER: z.ZodPreprocess<z.ZodDefault<z.ZodEnum<{
13
+ disabled: "disabled";
14
+ fake: "fake";
15
+ stripe: "stripe";
16
+ }>>>;
17
+ SALIX_RESEND_API_KEY: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
18
+ SALIX_STRIPE_SECRET_KEY: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
19
+ SALIX_STRIPE_WEBHOOK_SECRET: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
20
+ SALIX_SUPABASE_PUBLISHABLE_KEY: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
21
+ SALIX_SUPABASE_SERVICE_ROLE_KEY: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
22
+ SALIX_SUPABASE_URL: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
23
+ }, z.core.$strict>;
24
+ export type ServerEnvironment = z.output<typeof serverEnvironmentSchema>;
25
+ export declare const SERVER_ENVIRONMENT_VARIABLES: readonly ["NODE_ENV", "SALIX_CHECKOUT_BASE_URL", "SALIX_FAKE_PAYMENT_SECRET", "SALIX_INTERNAL_ORDER_EMAIL", "SALIX_OBSERVABILITY_DSN", "SALIX_PAYMENT_PROVIDER", "SALIX_RESEND_API_KEY", "SALIX_STRIPE_SECRET_KEY", "SALIX_STRIPE_WEBHOOK_SECRET", "SALIX_SUPABASE_PUBLISHABLE_KEY", "SALIX_SUPABASE_SERVICE_ROLE_KEY", "SALIX_SUPABASE_URL"];
26
+ export declare function parseServerEnvironment(source: Readonly<Record<string, string | undefined>>): ServerEnvironment;
27
+ //# sourceMappingURL=server-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-environment.d.ts","sourceRoot":"","sources":["../src/server-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;kBAoGhC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAEzE,eAAO,MAAM,4BAA4B,+UAa/B,CAAC;AAEX,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GACnD,iBAAiB,CASnB"}
@@ -0,0 +1,138 @@
1
+ import { z } from "zod";
2
+ const optionalSecret = z.preprocess(emptyStringToUndefined, z.string().trim().min(1).optional());
3
+ const optionalUrl = z.preprocess(emptyStringToUndefined, z.string().trim().url().optional());
4
+ const optionalEmail = z.preprocess(emptyStringToUndefined, z.string().trim().email().optional());
5
+ const optionalFakePaymentSecret = z.preprocess(emptyStringToUndefined, z.string().trim().min(32).optional());
6
+ const paymentProvider = z.preprocess(emptyStringToUndefined, z.enum(["disabled", "fake", "stripe"]).default("disabled"));
7
+ export const serverEnvironmentSchema = z
8
+ .strictObject({
9
+ NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
10
+ SALIX_CHECKOUT_BASE_URL: optionalUrl,
11
+ SALIX_FAKE_PAYMENT_SECRET: optionalFakePaymentSecret,
12
+ SALIX_INTERNAL_ORDER_EMAIL: optionalEmail,
13
+ SALIX_OBSERVABILITY_DSN: optionalUrl,
14
+ SALIX_PAYMENT_PROVIDER: paymentProvider,
15
+ SALIX_RESEND_API_KEY: optionalSecret,
16
+ SALIX_STRIPE_SECRET_KEY: optionalSecret,
17
+ SALIX_STRIPE_WEBHOOK_SECRET: optionalSecret,
18
+ SALIX_SUPABASE_PUBLISHABLE_KEY: optionalSecret,
19
+ SALIX_SUPABASE_SERVICE_ROLE_KEY: optionalSecret,
20
+ SALIX_SUPABASE_URL: optionalUrl,
21
+ })
22
+ .superRefine((value, context) => {
23
+ requirePair(value, context, "SALIX_SUPABASE_URL", "SALIX_SUPABASE_SERVICE_ROLE_KEY", "Supabase URL and service-role key must be configured together.");
24
+ requirePair(value, context, "SALIX_STRIPE_SECRET_KEY", "SALIX_STRIPE_WEBHOOK_SECRET", "Stripe secret and webhook secret must be configured together.");
25
+ requirePair(value, context, "SALIX_RESEND_API_KEY", "SALIX_INTERNAL_ORDER_EMAIL", "Email API key and internal order recipient must be configured together.");
26
+ if (value.SALIX_PAYMENT_PROVIDER === "fake") {
27
+ if (value.NODE_ENV === "production") {
28
+ context.addIssue({
29
+ code: "custom",
30
+ message: "The fake payment provider cannot run in production.",
31
+ path: ["SALIX_PAYMENT_PROVIDER"],
32
+ });
33
+ }
34
+ if (value.SALIX_FAKE_PAYMENT_SECRET === undefined) {
35
+ context.addIssue({
36
+ code: "custom",
37
+ message: "The fake payment provider requires a signing secret.",
38
+ path: ["SALIX_FAKE_PAYMENT_SECRET"],
39
+ });
40
+ }
41
+ if (value.SALIX_SUPABASE_URL === undefined ||
42
+ value.SALIX_SUPABASE_SERVICE_ROLE_KEY === undefined) {
43
+ context.addIssue({
44
+ code: "custom",
45
+ message: "The fake payment provider requires the Supabase persistence pair.",
46
+ path: ["SALIX_PAYMENT_PROVIDER"],
47
+ });
48
+ }
49
+ }
50
+ else if (value.SALIX_FAKE_PAYMENT_SECRET !== undefined) {
51
+ context.addIssue({
52
+ code: "custom",
53
+ message: "A fake payment secret requires the fake payment provider.",
54
+ path: ["SALIX_FAKE_PAYMENT_SECRET"],
55
+ });
56
+ }
57
+ if (value.SALIX_PAYMENT_PROVIDER === "stripe") {
58
+ if (value.SALIX_STRIPE_SECRET_KEY === undefined ||
59
+ value.SALIX_STRIPE_WEBHOOK_SECRET === undefined) {
60
+ context.addIssue({
61
+ code: "custom",
62
+ message: "The Stripe payment provider requires its secret and webhook secret.",
63
+ path: ["SALIX_PAYMENT_PROVIDER"],
64
+ });
65
+ }
66
+ if (value.SALIX_SUPABASE_URL === undefined ||
67
+ value.SALIX_SUPABASE_SERVICE_ROLE_KEY === undefined) {
68
+ context.addIssue({
69
+ code: "custom",
70
+ message: "The Stripe payment provider requires the Supabase persistence pair.",
71
+ path: ["SALIX_PAYMENT_PROVIDER"],
72
+ });
73
+ }
74
+ if (value.SALIX_CHECKOUT_BASE_URL === undefined) {
75
+ context.addIssue({
76
+ code: "custom",
77
+ message: "The Stripe payment provider requires a checkout base URL.",
78
+ path: ["SALIX_CHECKOUT_BASE_URL"],
79
+ });
80
+ }
81
+ else {
82
+ validateCheckoutBaseUrl(value, context);
83
+ }
84
+ }
85
+ });
86
+ export const SERVER_ENVIRONMENT_VARIABLES = [
87
+ "NODE_ENV",
88
+ "SALIX_CHECKOUT_BASE_URL",
89
+ "SALIX_FAKE_PAYMENT_SECRET",
90
+ "SALIX_INTERNAL_ORDER_EMAIL",
91
+ "SALIX_OBSERVABILITY_DSN",
92
+ "SALIX_PAYMENT_PROVIDER",
93
+ "SALIX_RESEND_API_KEY",
94
+ "SALIX_STRIPE_SECRET_KEY",
95
+ "SALIX_STRIPE_WEBHOOK_SECRET",
96
+ "SALIX_SUPABASE_PUBLISHABLE_KEY",
97
+ "SALIX_SUPABASE_SERVICE_ROLE_KEY",
98
+ "SALIX_SUPABASE_URL",
99
+ ];
100
+ export function parseServerEnvironment(source) {
101
+ const selected = {};
102
+ if (source.NODE_ENV !== undefined)
103
+ selected.NODE_ENV = source.NODE_ENV;
104
+ for (const [name, value] of Object.entries(source)) {
105
+ if (name.startsWith("SALIX_"))
106
+ selected[name] = value;
107
+ }
108
+ return serverEnvironmentSchema.parse(selected);
109
+ }
110
+ function emptyStringToUndefined(value) {
111
+ return typeof value === "string" && value.trim() === "" ? undefined : value;
112
+ }
113
+ function requirePair(value, context, first, second, message) {
114
+ const hasFirst = value[first] !== undefined;
115
+ const hasSecond = value[second] !== undefined;
116
+ if (hasFirst === hasSecond)
117
+ return;
118
+ context.addIssue({
119
+ code: "custom",
120
+ message,
121
+ path: [hasFirst ? second : first],
122
+ });
123
+ }
124
+ function validateCheckoutBaseUrl(value, context) {
125
+ if (value.SALIX_CHECKOUT_BASE_URL === undefined)
126
+ return;
127
+ const secureOrigin = /^https:\/\/[^/?#@]+\/?$/u.test(value.SALIX_CHECKOUT_BASE_URL);
128
+ const localOrigin = value.NODE_ENV !== "production" &&
129
+ /^http:\/\/(?:localhost|127\.0\.0\.1)(?::[0-9]{1,5})?\/?$/u.test(value.SALIX_CHECKOUT_BASE_URL);
130
+ if (!secureOrigin && !localOrigin) {
131
+ context.addIssue({
132
+ code: "custom",
133
+ message: "Checkout base URL must be HTTPS, except local HTTP in development and test.",
134
+ path: ["SALIX_CHECKOUT_BASE_URL"],
135
+ });
136
+ }
137
+ }
138
+ //# sourceMappingURL=server-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-environment.js","sourceRoot":"","sources":["../src/server-environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { SERVER_ENVIRONMENT_VARIABLES, parseServerEnvironment, serverEnvironmentSchema, type ServerEnvironment, } from "./server-environment.js";
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,2 @@
1
+ export { SERVER_ENVIRONMENT_VARIABLES, parseServerEnvironment, serverEnvironmentSchema, } from "./server-environment.js";
2
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,yBAAyB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@salixcommerce/config",
3
+ "version": "0.1.0",
4
+ "description": "Typed public and server configuration contracts for Salix Commerce.",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./public": {
21
+ "types": "./dist/public.d.ts",
22
+ "import": "./dist/public.js",
23
+ "default": "./dist/public.js"
24
+ },
25
+ "./server": {
26
+ "types": "./dist/server.d.ts",
27
+ "import": "./dist/server.js",
28
+ "default": "./dist/server.js"
29
+ }
30
+ },
31
+ "engines": {
32
+ "node": ">=24.11.0 <25"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "dependencies": {
38
+ "zod": "4.4.3"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.build.json",
42
+ "typecheck": "tsc -p tsconfig.json --noEmit"
43
+ }
44
+ }