@zappie/check 0.1.2 → 0.1.3
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/CHANGELOG.md +9 -0
- package/README.md +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +140 -54
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/schema/check-result.v1.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @zappie/check
|
|
2
2
|
|
|
3
|
+
## 0.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 45295a2: Make product cards ready to tap with route discovery, prefetch lint rules and measured storefront checks.
|
|
8
|
+
- Updated dependencies [45295a2]
|
|
9
|
+
- @zappie/sdk@0.1.6
|
|
10
|
+
- eslint-plugin-zappie@0.1.2
|
|
11
|
+
|
|
3
12
|
## 0.1.2
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ npx zappie check
|
|
|
20
20
|
| `test` | Your project's tests |
|
|
21
21
|
| `build` | A production build |
|
|
22
22
|
| `secrets` | No secret keys or tokens in your source or build |
|
|
23
|
+
| `readiness` | Initial route discovery is enabled, or the config records why the site opts out |
|
|
23
24
|
| `budgets` | Built JavaScript and CSS sizes, against Zappie's default budgets or the ones in your config |
|
|
24
25
|
|
|
25
26
|
Add `--json` for a machine-readable result. Its shape is the JSON Schema at `@zappie/check/schema/check-result.v1.json`.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ type CheckProblem = {
|
|
|
6
6
|
message: string;
|
|
7
7
|
fix: string | null;
|
|
8
8
|
};
|
|
9
|
-
type CheckStepName = "config" | "allowlist" | "lint" | "types" | "test" | "build" | "secrets" | "budgets";
|
|
9
|
+
type CheckStepName = "config" | "allowlist" | "lint" | "types" | "test" | "build" | "secrets" | "readiness" | "budgets";
|
|
10
10
|
type CheckStep = {
|
|
11
11
|
name: CheckStepName;
|
|
12
12
|
result: CheckResultValue;
|
|
@@ -46,6 +46,8 @@ declare function checkConfig({ cwd, signal, }: StepOptions): Promise<CheckStep>;
|
|
|
46
46
|
|
|
47
47
|
declare function checkLint({ cwd, signal, }: StepOptions): Promise<CheckStep>;
|
|
48
48
|
|
|
49
|
+
declare function checkReadiness({ cwd, signal, }: StepOptions): Promise<CheckStep>;
|
|
50
|
+
|
|
49
51
|
declare function runCheck(options: CheckOptions): Promise<CheckResult>;
|
|
50
52
|
|
|
51
53
|
declare const SECRET_FILE_SIZE_CAP: number;
|
|
@@ -59,4 +61,4 @@ declare function checkTests({ cwd, packageManager, signal, }: StepOptions): Prom
|
|
|
59
61
|
|
|
60
62
|
declare function checkTypes(options: StepOptions): Promise<CheckStep>;
|
|
61
63
|
|
|
62
|
-
export { type AllowlistSource, BUILTIN_ALLOWLIST_SOURCE, type CheckOptions, type CheckProblem, type CheckResult, type CheckResultValue, type CheckStep, type CheckStepName, type PackageManager, SECRET_FILE_SIZE_CAP, type SecretFinding, type StepOptions, checkAllowlist, checkBudgets, checkBuild, checkConfig, checkLint, checkSecrets, checkTests, checkTypes, loadConfig, runCheck, scanSecrets, supportsTypeScriptImport };
|
|
64
|
+
export { type AllowlistSource, BUILTIN_ALLOWLIST_SOURCE, type CheckOptions, type CheckProblem, type CheckResult, type CheckResultValue, type CheckStep, type CheckStepName, type PackageManager, SECRET_FILE_SIZE_CAP, type SecretFinding, type StepOptions, checkAllowlist, checkBudgets, checkBuild, checkConfig, checkLint, checkReadiness, checkSecrets, checkTests, checkTypes, loadConfig, runCheck, scanSecrets, supportsTypeScriptImport };
|
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ function distance(left, right) {
|
|
|
42
42
|
}
|
|
43
43
|
return row[right.length] ?? Infinity;
|
|
44
44
|
}
|
|
45
|
-
function unknownKeys(value, allowed,
|
|
45
|
+
function unknownKeys(value, allowed, path13, issue) {
|
|
46
46
|
for (const key of Object.keys(value)) {
|
|
47
47
|
if (allowed.includes(key)) {
|
|
48
48
|
continue;
|
|
@@ -50,7 +50,7 @@ function unknownKeys(value, allowed, path12, issue) {
|
|
|
50
50
|
const closest = allowed.map((candidate) => ({ candidate, score: distance(key, candidate) })).sort((left, right) => left.score - right.score)[0];
|
|
51
51
|
const hint = closest && closest.score <= 2 ? closest.candidate : void 0;
|
|
52
52
|
issue({
|
|
53
|
-
path:
|
|
53
|
+
path: path13 ? `${path13}.${key}` : key,
|
|
54
54
|
code: "unknown_key",
|
|
55
55
|
message: hint ? `Unknown field "${key}". Rename it to "${hint}".` : `Unknown field "${key}". Remove it from the configuration.`,
|
|
56
56
|
severity: "error"
|
|
@@ -76,20 +76,20 @@ function hostname(value) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// ../sdk/src/site-config/sections.ts
|
|
79
|
-
function nested(value,
|
|
79
|
+
function nested(value, path13, keys, issue, validate) {
|
|
80
80
|
if (value === void 0) {
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
if (!record(value)) {
|
|
84
84
|
issue({
|
|
85
|
-
path:
|
|
85
|
+
path: path13,
|
|
86
86
|
code: "invalid_type",
|
|
87
|
-
message: `Expected an object. Set ${
|
|
87
|
+
message: `Expected an object. Set ${path13} to an object or remove it.`,
|
|
88
88
|
severity: "error"
|
|
89
89
|
});
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
-
unknownKeys(value, keys,
|
|
92
|
+
unknownKeys(value, keys, path13, issue);
|
|
93
93
|
validate(value);
|
|
94
94
|
}
|
|
95
95
|
function budgets(value, issue, error) {
|
|
@@ -126,18 +126,18 @@ function budgets(value, issue, error) {
|
|
|
126
126
|
`Expected a positive finite number. Set budgets.${key} to a number greater than zero.`
|
|
127
127
|
);
|
|
128
128
|
} else if (amount > DEFAULT_BUDGETS[key]) {
|
|
129
|
-
const
|
|
129
|
+
const message5 = `The ${key} budget exceeds the ${DEFAULT_BUDGETS[key]} default.`;
|
|
130
130
|
if (budget.override === void 0) {
|
|
131
131
|
error(
|
|
132
132
|
`budgets.${key}`,
|
|
133
133
|
"budget_override",
|
|
134
|
-
`${
|
|
134
|
+
`${message5} Add budgets.override.reason to explain the increase.`
|
|
135
135
|
);
|
|
136
136
|
} else {
|
|
137
137
|
issue({
|
|
138
138
|
path: `budgets.${key}`,
|
|
139
139
|
code: "budget_override",
|
|
140
|
-
message: `${
|
|
140
|
+
message: `${message5} Lower it to the default when the exception is no longer needed.`,
|
|
141
141
|
severity: "warning"
|
|
142
142
|
});
|
|
143
143
|
}
|
|
@@ -183,12 +183,13 @@ var rootKeys = [
|
|
|
183
183
|
"packages",
|
|
184
184
|
"outbound",
|
|
185
185
|
"budgets",
|
|
186
|
+
"readiness",
|
|
186
187
|
"analytics"
|
|
187
188
|
];
|
|
188
189
|
function validateConfig(input) {
|
|
189
190
|
const issues = [];
|
|
190
191
|
const issue = (value) => issues.push(value);
|
|
191
|
-
const error = (
|
|
192
|
+
const error = (path13, code, message5) => issue({ path: path13, code, message: message5, severity: "error" });
|
|
192
193
|
if (!record(input)) {
|
|
193
194
|
return {
|
|
194
195
|
valid: false,
|
|
@@ -246,18 +247,49 @@ function validateConfig(input) {
|
|
|
246
247
|
});
|
|
247
248
|
});
|
|
248
249
|
budgets(input.budgets, issue, error);
|
|
250
|
+
nested(
|
|
251
|
+
input.readiness,
|
|
252
|
+
"readiness",
|
|
253
|
+
["routeDiscovery"],
|
|
254
|
+
issue,
|
|
255
|
+
(readiness) => {
|
|
256
|
+
nested(
|
|
257
|
+
readiness.routeDiscovery,
|
|
258
|
+
"readiness.routeDiscovery",
|
|
259
|
+
["optOut"],
|
|
260
|
+
issue,
|
|
261
|
+
(routeDiscovery) => {
|
|
262
|
+
nested(
|
|
263
|
+
routeDiscovery.optOut,
|
|
264
|
+
"readiness.routeDiscovery.optOut",
|
|
265
|
+
["reason"],
|
|
266
|
+
issue,
|
|
267
|
+
(optOut) => {
|
|
268
|
+
if (typeof optOut.reason !== "string" || !optOut.reason.trim()) {
|
|
269
|
+
error(
|
|
270
|
+
"readiness.routeDiscovery.optOut.reason",
|
|
271
|
+
"invalid_format",
|
|
272
|
+
"Expected a non-blank reason. Explain why the site disables initial route discovery."
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
);
|
|
249
281
|
analytics(input.analytics, issue, error);
|
|
250
282
|
return {
|
|
251
283
|
valid: !issues.some((entry) => entry.severity === "error"),
|
|
252
284
|
issues
|
|
253
285
|
};
|
|
254
286
|
}
|
|
255
|
-
function requiredSlug(value,
|
|
287
|
+
function requiredSlug(value, path13, error) {
|
|
256
288
|
if (!nonblank(value)) {
|
|
257
289
|
error(
|
|
258
|
-
|
|
290
|
+
path13,
|
|
259
291
|
value === void 0 ? "missing_required" : "invalid_type",
|
|
260
|
-
`Expected a non-empty storefront slug. Set ${
|
|
292
|
+
`Expected a non-empty storefront slug. Set ${path13} to the slug used by createZappie().`
|
|
261
293
|
);
|
|
262
294
|
}
|
|
263
295
|
}
|
|
@@ -276,29 +308,29 @@ function theme(value, error) {
|
|
|
276
308
|
);
|
|
277
309
|
}
|
|
278
310
|
}
|
|
279
|
-
function stringList(value,
|
|
311
|
+
function stringList(value, path13, error, options = {}) {
|
|
280
312
|
if (value === void 0) {
|
|
281
313
|
return void 0;
|
|
282
314
|
}
|
|
283
315
|
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
284
316
|
error(
|
|
285
|
-
|
|
317
|
+
path13,
|
|
286
318
|
"invalid_type",
|
|
287
|
-
`Expected an array of strings. Set ${
|
|
319
|
+
`Expected an array of strings. Set ${path13} to string values.`
|
|
288
320
|
);
|
|
289
321
|
return void 0;
|
|
290
322
|
}
|
|
291
323
|
if (options.nonempty && value.length === 0) {
|
|
292
324
|
error(
|
|
293
|
-
|
|
325
|
+
path13,
|
|
294
326
|
"invalid_format",
|
|
295
|
-
`Expected at least one value. Add a value to ${
|
|
327
|
+
`Expected at least one value. Add a value to ${path13} or remove the field.`
|
|
296
328
|
);
|
|
297
329
|
}
|
|
298
330
|
value.forEach((entry, index) => {
|
|
299
331
|
if (options.slug && !nonblank(entry)) {
|
|
300
332
|
error(
|
|
301
|
-
`${
|
|
333
|
+
`${path13}[${index}]`,
|
|
302
334
|
"invalid_format",
|
|
303
335
|
"Expected a non-empty branch slug. Remove the empty value or use a branch slug."
|
|
304
336
|
);
|
|
@@ -306,17 +338,17 @@ function stringList(value, path12, error, options = {}) {
|
|
|
306
338
|
});
|
|
307
339
|
if (options.unique && new Set(value).size !== value.length) {
|
|
308
340
|
error(
|
|
309
|
-
|
|
341
|
+
path13,
|
|
310
342
|
"duplicate",
|
|
311
|
-
`Expected unique values. Remove duplicates from ${
|
|
343
|
+
`Expected unique values. Remove duplicates from ${path13}.`
|
|
312
344
|
);
|
|
313
345
|
}
|
|
314
346
|
return value;
|
|
315
347
|
}
|
|
316
348
|
function paths(value, error) {
|
|
317
349
|
const values = stringList(value, "prerender", error, { unique: true });
|
|
318
|
-
values?.forEach((
|
|
319
|
-
if (!
|
|
350
|
+
values?.forEach((path13, index) => {
|
|
351
|
+
if (!path13.startsWith("/")) {
|
|
320
352
|
error(
|
|
321
353
|
`prerender[${index}]`,
|
|
322
354
|
"invalid_format",
|
|
@@ -819,11 +851,11 @@ var record2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
|
819
851
|
var includes = (values, key) => values.includes(key);
|
|
820
852
|
function validateTheme(input) {
|
|
821
853
|
const issues = [];
|
|
822
|
-
const issue = (
|
|
823
|
-
const keys = (obj, allowed,
|
|
854
|
+
const issue = (path13, code, message5, severity = "error") => issues.push({ path: path13, code, message: message5, severity });
|
|
855
|
+
const keys = (obj, allowed, path13) => {
|
|
824
856
|
for (const key of Object.keys(obj)) {
|
|
825
857
|
if (!allowed.includes(key)) {
|
|
826
|
-
issue(
|
|
858
|
+
issue(path13 ? `${path13}.${key}` : key, "invalid_theme", "Unknown field");
|
|
827
859
|
}
|
|
828
860
|
}
|
|
829
861
|
};
|
|
@@ -884,9 +916,9 @@ function validateTheme(input) {
|
|
|
884
916
|
}
|
|
885
917
|
}
|
|
886
918
|
for (const [key, value] of Object.entries(values)) {
|
|
887
|
-
const
|
|
919
|
+
const path13 = `${group}.${key}`;
|
|
888
920
|
if (!includes(TOKEN_NAMES, key)) {
|
|
889
|
-
issue(
|
|
921
|
+
issue(path13, "unknown_token", "Unknown semantic token");
|
|
890
922
|
continue;
|
|
891
923
|
}
|
|
892
924
|
let code, valid = false;
|
|
@@ -904,7 +936,7 @@ function validateTheme(input) {
|
|
|
904
936
|
valid = typeof value === "string" && safeValue(value) && (includes(DURATION_TOKENS, key) ? isDuration(value) : isEasing(value));
|
|
905
937
|
}
|
|
906
938
|
if (!valid) {
|
|
907
|
-
issue(
|
|
939
|
+
issue(path13, code, "Invalid or unsafe token value");
|
|
908
940
|
}
|
|
909
941
|
}
|
|
910
942
|
}
|
|
@@ -914,30 +946,30 @@ function validateTheme(input) {
|
|
|
914
946
|
} else {
|
|
915
947
|
const roles = /* @__PURE__ */ new Set();
|
|
916
948
|
input.fonts.forEach((font, i) => {
|
|
917
|
-
const
|
|
949
|
+
const path13 = `fonts[${i}]`;
|
|
918
950
|
if (!record2(font)) {
|
|
919
|
-
issue(
|
|
951
|
+
issue(path13, "invalid_font", "Expected a font object");
|
|
920
952
|
return;
|
|
921
953
|
}
|
|
922
|
-
keys(font, ["family", "source", "url", "weights", "role"],
|
|
954
|
+
keys(font, ["family", "source", "url", "weights", "role"], path13);
|
|
923
955
|
if (typeof font.family !== "string" || !isFontFamily(font.family) || font.family.includes(",")) {
|
|
924
956
|
issue(
|
|
925
|
-
`${
|
|
957
|
+
`${path13}.family`,
|
|
926
958
|
"invalid_font",
|
|
927
959
|
"Expected one unquoted font family"
|
|
928
960
|
);
|
|
929
961
|
}
|
|
930
962
|
if (typeof font.source !== "string" || !["google", "self", "system"].includes(font.source)) {
|
|
931
|
-
issue(`${
|
|
963
|
+
issue(`${path13}.source`, "invalid_font", "Unknown font source");
|
|
932
964
|
}
|
|
933
965
|
if (typeof font.role !== "string" || !["display", "body", "mono"].includes(font.role) || roles.has(font.role)) {
|
|
934
|
-
issue(`${
|
|
966
|
+
issue(`${path13}.role`, "invalid_font", "Expected a unique font role");
|
|
935
967
|
}
|
|
936
968
|
roles.add(String(font.role));
|
|
937
969
|
if (font.source === "self" || font.url !== void 0) {
|
|
938
970
|
if (typeof font.url !== "string" || !isAssetUrl(font.url, false) || !new URL(font.url).pathname.endsWith(".woff2")) {
|
|
939
971
|
issue(
|
|
940
|
-
`${
|
|
972
|
+
`${path13}.url`,
|
|
941
973
|
"invalid_font",
|
|
942
974
|
"Expected an HTTPS .woff2 URL"
|
|
943
975
|
);
|
|
@@ -947,7 +979,7 @@ function validateTheme(input) {
|
|
|
947
979
|
(w) => typeof w !== "number" || !Number.isInteger(w) || w < 1 || w > 1e3
|
|
948
980
|
))) {
|
|
949
981
|
issue(
|
|
950
|
-
`${
|
|
982
|
+
`${path13}.weights`,
|
|
951
983
|
"invalid_font",
|
|
952
984
|
"Expected 1\u20139 integer weights between 1 and 1000"
|
|
953
985
|
);
|
|
@@ -1057,13 +1089,13 @@ function escape(value) {
|
|
|
1057
1089
|
}
|
|
1058
1090
|
|
|
1059
1091
|
// src/result.ts
|
|
1060
|
-
function problem(
|
|
1061
|
-
return { ...details, message:
|
|
1092
|
+
function problem(message5, fix, details = {}) {
|
|
1093
|
+
return { ...details, message: message5, fix };
|
|
1062
1094
|
}
|
|
1063
1095
|
function step(name, result, problems = []) {
|
|
1064
1096
|
return { name, result, problems };
|
|
1065
1097
|
}
|
|
1066
|
-
var skipped = (name,
|
|
1098
|
+
var skipped = (name, message5) => step(name, "skipped", [problem(message5, null)]);
|
|
1067
1099
|
|
|
1068
1100
|
// src/config.ts
|
|
1069
1101
|
function supportsTypeScriptImport(version = process.versions.node) {
|
|
@@ -1638,9 +1670,61 @@ function message2(error) {
|
|
|
1638
1670
|
return error instanceof Error ? error.message : String(error);
|
|
1639
1671
|
}
|
|
1640
1672
|
|
|
1641
|
-
// src/
|
|
1642
|
-
import {
|
|
1673
|
+
// src/readiness.ts
|
|
1674
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
1643
1675
|
import path9 from "path";
|
|
1676
|
+
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
1677
|
+
async function checkReadiness({
|
|
1678
|
+
cwd,
|
|
1679
|
+
signal
|
|
1680
|
+
}) {
|
|
1681
|
+
signal?.throwIfAborted();
|
|
1682
|
+
const site = (await loadConfig(cwd)).value;
|
|
1683
|
+
const optOut = site.readiness?.routeDiscovery?.optOut;
|
|
1684
|
+
if (optOut) {
|
|
1685
|
+
return step("readiness", "passed", [
|
|
1686
|
+
problem(
|
|
1687
|
+
"Initial route discovery is disabled by an explained exception",
|
|
1688
|
+
`Remove readiness.routeDiscovery.optOut after you enable initial route discovery. Reason: ${optOut.reason}`,
|
|
1689
|
+
{ rule: "readiness/route-discovery-opt-out", file: "zappie.config.ts" }
|
|
1690
|
+
)
|
|
1691
|
+
]);
|
|
1692
|
+
}
|
|
1693
|
+
const file = path9.join(cwd, "react-router.config.ts");
|
|
1694
|
+
try {
|
|
1695
|
+
await readFile8(file, "utf8");
|
|
1696
|
+
const version = Date.now();
|
|
1697
|
+
const config = await import(`${pathToFileURL3(file).href}?readiness=${version}`);
|
|
1698
|
+
if (config.default?.routeDiscovery?.mode === "initial") {
|
|
1699
|
+
return step("readiness", "passed");
|
|
1700
|
+
}
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
return step("readiness", "failed", [
|
|
1703
|
+
problem(
|
|
1704
|
+
message3(error),
|
|
1705
|
+
'Create react-router.config.ts and set routeDiscovery: { mode: "initial" }.',
|
|
1706
|
+
{
|
|
1707
|
+
rule: "readiness/route-discovery",
|
|
1708
|
+
file: "react-router.config.ts"
|
|
1709
|
+
}
|
|
1710
|
+
)
|
|
1711
|
+
]);
|
|
1712
|
+
}
|
|
1713
|
+
return step("readiness", "failed", [
|
|
1714
|
+
problem(
|
|
1715
|
+
"Initial route discovery is not enabled",
|
|
1716
|
+
'Set routeDiscovery: { mode: "initial" } in react-router.config.ts so item routes are ready before a shopper taps.',
|
|
1717
|
+
{ rule: "readiness/route-discovery", file: "react-router.config.ts" }
|
|
1718
|
+
)
|
|
1719
|
+
]);
|
|
1720
|
+
}
|
|
1721
|
+
function message3(error) {
|
|
1722
|
+
return error instanceof Error ? error.message : String(error);
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
// src/secrets.ts
|
|
1726
|
+
import { lstat, readFile as readFile9, readdir as readdir2 } from "fs/promises";
|
|
1727
|
+
import path10 from "path";
|
|
1644
1728
|
|
|
1645
1729
|
// src/secret-patterns.ts
|
|
1646
1730
|
var FIX = "Move the value to a server environment variable and rotate it.";
|
|
@@ -1725,14 +1809,14 @@ async function scanSecrets(dir) {
|
|
|
1725
1809
|
if (!info.isFile() || info.size > SECRET_FILE_SIZE_CAP) {
|
|
1726
1810
|
continue;
|
|
1727
1811
|
}
|
|
1728
|
-
const contents = await
|
|
1812
|
+
const contents = await readFile9(file);
|
|
1729
1813
|
if (contents.includes(0)) {
|
|
1730
1814
|
continue;
|
|
1731
1815
|
}
|
|
1732
1816
|
const source = contents.toString("utf8");
|
|
1733
1817
|
for (const match of secretMatches(
|
|
1734
1818
|
source,
|
|
1735
|
-
|
|
1819
|
+
path10.basename(file).startsWith(".env")
|
|
1736
1820
|
)) {
|
|
1737
1821
|
findings.push({
|
|
1738
1822
|
rule: match.rule,
|
|
@@ -1763,17 +1847,17 @@ async function checkSecrets({
|
|
|
1763
1847
|
async function filesToScan(cwd) {
|
|
1764
1848
|
const files = [];
|
|
1765
1849
|
for (const directory of ["app", "public"]) {
|
|
1766
|
-
await collect2(
|
|
1850
|
+
await collect2(path10.join(cwd, directory), files);
|
|
1767
1851
|
}
|
|
1768
1852
|
await collect2(
|
|
1769
|
-
|
|
1853
|
+
path10.join(cwd, "build/client"),
|
|
1770
1854
|
files,
|
|
1771
1855
|
(file) => file.endsWith(".js")
|
|
1772
1856
|
);
|
|
1773
1857
|
try {
|
|
1774
1858
|
for (const entry of await readdir2(cwd, { withFileTypes: true })) {
|
|
1775
1859
|
if (entry.isFile() && rootConfig(entry.name)) {
|
|
1776
|
-
files.push(
|
|
1860
|
+
files.push(path10.join(cwd, entry.name));
|
|
1777
1861
|
}
|
|
1778
1862
|
}
|
|
1779
1863
|
} catch {
|
|
@@ -1787,7 +1871,7 @@ async function collect2(directory, files, accept = () => true) {
|
|
|
1787
1871
|
if (entry.isSymbolicLink()) {
|
|
1788
1872
|
continue;
|
|
1789
1873
|
}
|
|
1790
|
-
const file =
|
|
1874
|
+
const file = path10.join(directory, entry.name);
|
|
1791
1875
|
if (entry.isDirectory()) {
|
|
1792
1876
|
await collect2(file, files, accept);
|
|
1793
1877
|
} else if (entry.isFile() && accept(file)) {
|
|
@@ -1808,13 +1892,13 @@ function lineAt(source, index) {
|
|
|
1808
1892
|
}
|
|
1809
1893
|
|
|
1810
1894
|
// src/test-step.ts
|
|
1811
|
-
import
|
|
1895
|
+
import path11 from "path";
|
|
1812
1896
|
async function checkTests({
|
|
1813
1897
|
cwd,
|
|
1814
1898
|
packageManager,
|
|
1815
1899
|
signal
|
|
1816
1900
|
}) {
|
|
1817
|
-
const manifest = await json(
|
|
1901
|
+
const manifest = await json(path11.join(cwd, "package.json"));
|
|
1818
1902
|
if (!manifest.scripts?.test) {
|
|
1819
1903
|
return skipped("test", "No test script is defined in package.json.");
|
|
1820
1904
|
}
|
|
@@ -1837,11 +1921,11 @@ async function checkTests({
|
|
|
1837
1921
|
}
|
|
1838
1922
|
|
|
1839
1923
|
// src/types-step.ts
|
|
1840
|
-
import
|
|
1924
|
+
import path12 from "path";
|
|
1841
1925
|
async function checkTypes(options) {
|
|
1842
1926
|
const { cwd, packageManager, signal } = options;
|
|
1843
1927
|
signal?.throwIfAborted();
|
|
1844
|
-
const manifest = await json(
|
|
1928
|
+
const manifest = await json(path12.join(cwd, "package.json"));
|
|
1845
1929
|
if (manifest.dependencies?.["react-router"]) {
|
|
1846
1930
|
const generated = execArgs(packageManager, "react-router", ["typegen"]);
|
|
1847
1931
|
const result2 = await command(
|
|
@@ -1900,6 +1984,7 @@ var runners = [
|
|
|
1900
1984
|
{ name: "test", run: checkTests },
|
|
1901
1985
|
{ name: "build", run: checkBuild },
|
|
1902
1986
|
{ name: "secrets", run: checkSecrets },
|
|
1987
|
+
{ name: "readiness", run: checkReadiness },
|
|
1903
1988
|
{ name: "budgets", run: checkBudgets }
|
|
1904
1989
|
];
|
|
1905
1990
|
async function runCheck(options) {
|
|
@@ -1913,7 +1998,7 @@ async function runCheck(options) {
|
|
|
1913
1998
|
options.signal?.throwIfAborted();
|
|
1914
1999
|
checked = step(runner.name, "failed", [
|
|
1915
2000
|
problem(
|
|
1916
|
-
|
|
2001
|
+
message4(error),
|
|
1917
2002
|
"Fix the step setup and run zappie check again."
|
|
1918
2003
|
)
|
|
1919
2004
|
]);
|
|
@@ -1928,7 +2013,7 @@ async function runCheck(options) {
|
|
|
1928
2013
|
steps
|
|
1929
2014
|
};
|
|
1930
2015
|
}
|
|
1931
|
-
function
|
|
2016
|
+
function message4(error) {
|
|
1932
2017
|
return error instanceof Error ? error.message : String(error);
|
|
1933
2018
|
}
|
|
1934
2019
|
export {
|
|
@@ -1939,6 +2024,7 @@ export {
|
|
|
1939
2024
|
checkBuild,
|
|
1940
2025
|
checkConfig,
|
|
1941
2026
|
checkLint,
|
|
2027
|
+
checkReadiness,
|
|
1942
2028
|
checkSecrets,
|
|
1943
2029
|
checkTests,
|
|
1944
2030
|
checkTypes,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../sdk/src/site-config/types.ts","../../sdk/src/site-config/helpers.ts","../../sdk/src/site-config/sections.ts","../../sdk/src/site-config/validate.ts","../src/allowlist.ts","../../tokens/src/names.ts","../../tokens/src/defaults.ts","../../tokens/src/named-colors.ts","../../tokens/src/parse.ts","../../tokens/src/contrast.ts","../../tokens/src/validate.ts","../src/config.ts","../src/files.ts","../src/result.ts","../src/budgets.ts","../src/budget-files.ts","../src/budget-manifest.ts","../src/build.ts","../src/command.ts","../src/lint.ts","../src/secrets.ts","../src/secret-patterns.ts","../src/test-step.ts","../src/types-step.ts","../src/run.ts"],"sourcesContent":["/**\n * Default site budgets: 200 KB gzipped JavaScript, 50 KB gzipped CSS and 2500 ms LCP.\n */\nexport const DEFAULT_BUDGETS = {\n jsKbGz: 200,\n cssKbGz: 50,\n lcpMs: 2500,\n} as const;\n\n/**\n * Package names and patterns allowed globally without a site-specific allowlist entry.\n */\nexport const GLOBAL_PACKAGE_ALLOWLIST = [\n \"react\",\n \"react-dom\",\n \"react-router\",\n \"@react-router/*\",\n \"@zappie/*\",\n \"tailwindcss\",\n \"@tailwindcss/*\",\n \"clsx\",\n \"tailwind-merge\",\n \"class-variance-authority\",\n \"lucide-react\",\n \"date-fns\",\n \"embla-carousel-react\",\n \"framer-motion/motion\",\n \"zod\",\n \"@radix-ui/*\",\n \"sonner\",\n \"vaul\",\n] as const;\n\n/**\n * The store, theme and optional build policies you export from zappie.config.ts.\n */\nexport type ZappieSiteConfig = {\n store: string;\n branches?: string[];\n theme: string;\n prerender?: string[];\n menu?: { hiddenCategories?: string[] };\n packages?: { allow?: string[] };\n outbound?: { allow?: string[] };\n /** Each budget left out uses DEFAULT_BUDGETS. */\n budgets?: {\n jsKbGz?: number;\n cssKbGz?: number;\n lcpMs?: number;\n override?: { reason: string };\n };\n analytics?: { forward?: { ga4?: string; metaPixel?: string } };\n};\n\n/**\n * A configuration diagnostic with its field path, stable code, message and severity.\n */\nexport type ConfigIssue = {\n path: string;\n code:\n | \"invalid_type\"\n | \"missing_required\"\n | \"unknown_key\"\n | \"invalid_format\"\n | \"duplicate\"\n | \"redundant_allowlist\"\n | \"budget_override\";\n message: string;\n severity: \"error\" | \"warning\";\n};\n\n/**\n * Configuration validation results. Warnings alone do not make valid false.\n */\nexport type ConfigValidation = { valid: boolean; issues: ConfigIssue[] };\n","import { GLOBAL_PACKAGE_ALLOWLIST, type ConfigIssue } from \"./types\";\n\nexport const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nfunction distance(left: string, right: string) {\n let row = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {\n const next = [leftIndex];\n for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {\n next[rightIndex] = Math.min(\n (next[rightIndex - 1] ?? 0) + 1,\n (row[rightIndex] ?? 0) + 1,\n (row[rightIndex - 1] ?? 0) +\n (left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1),\n );\n }\n row = next;\n }\n return row[right.length] ?? Infinity;\n}\n\nexport function unknownKeys(\n value: Record<string, unknown>,\n allowed: readonly string[],\n path: string,\n issue: (value: ConfigIssue) => void,\n) {\n for (const key of Object.keys(value)) {\n if (allowed.includes(key)) {\n continue;\n }\n const closest = allowed\n .map((candidate) => ({ candidate, score: distance(key, candidate) }))\n .sort((left, right) => left.score - right.score)[0];\n const hint = closest && closest.score <= 2 ? closest.candidate : undefined;\n issue({\n path: path ? `${path}.${key}` : key,\n code: \"unknown_key\",\n message: hint\n ? `Unknown field \"${key}\". Rename it to \"${hint}\".`\n : `Unknown field \"${key}\". Remove it from the configuration.`,\n severity: \"error\",\n });\n }\n}\n\nexport const nonblank = (value: unknown): value is string =>\n typeof value === \"string\" && value.trim().length > 0;\n\nexport const packageName = (value: string) =>\n value.length <= 214 &&\n /^(?:@[a-z0-9][a-z0-9._~-]*\\/[a-z0-9][a-z0-9._~-]*|[a-z0-9][a-z0-9._~-]*)$/.test(\n value,\n );\n\nexport const globallyAllowed = (value: string) =>\n GLOBAL_PACKAGE_ALLOWLIST.some((allowed) =>\n allowed.endsWith(\"/*\")\n ? value.startsWith(allowed.slice(0, -1))\n : value === allowed,\n );\n\nexport function hostname(value: string) {\n const wildcard = value.startsWith(\"*.\");\n const host = wildcard ? value.slice(2) : value;\n if (\n !host.includes(\".\") ||\n /^\\d+(?:\\.\\d+){3}$/.test(host) ||\n host.length > 253 ||\n host.includes(\"..\")\n ) {\n return false;\n }\n return host\n .split(\".\")\n .every(\n (label) =>\n label.length > 0 &&\n label.length <= 63 &&\n /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label),\n );\n}\n","import { record, unknownKeys } from \"./helpers\";\nimport { DEFAULT_BUDGETS, type ConfigIssue } from \"./types\";\n\ntype AddIssue = (value: ConfigIssue) => void;\ntype AddError = (\n path: string,\n code: ConfigIssue[\"code\"],\n message: string,\n) => void;\n\nexport function nested(\n value: unknown,\n path: string,\n keys: readonly string[],\n issue: AddIssue,\n validate: (value: Record<string, unknown>) => void,\n) {\n if (value === undefined) {\n return;\n }\n if (!record(value)) {\n issue({\n path,\n code: \"invalid_type\",\n message: `Expected an object. Set ${path} to an object or remove it.`,\n severity: \"error\",\n });\n return;\n }\n unknownKeys(value, keys, path, issue);\n validate(value);\n}\n\nexport function budgets(value: unknown, issue: AddIssue, error: AddError) {\n nested(\n value,\n \"budgets\",\n [\"jsKbGz\", \"cssKbGz\", \"lcpMs\", \"override\"],\n issue,\n (budget) => {\n nested(\n budget.override,\n \"budgets.override\",\n [\"reason\"],\n issue,\n (override) => {\n if (typeof override.reason !== \"string\" || !override.reason.trim()) {\n error(\n \"budgets.override.reason\",\n \"invalid_format\",\n \"Expected a non-blank reason. Explain why the default budget must be raised.\",\n );\n }\n },\n );\n for (const key of [\"jsKbGz\", \"cssKbGz\", \"lcpMs\"] as const) {\n const amount = budget[key];\n if (amount === undefined) {\n continue;\n }\n if (\n typeof amount !== \"number\" ||\n !Number.isFinite(amount) ||\n amount <= 0\n ) {\n error(\n `budgets.${key}`,\n \"invalid_type\",\n `Expected a positive finite number. Set budgets.${key} to a number greater than zero.`,\n );\n } else if (amount > DEFAULT_BUDGETS[key]) {\n const message = `The ${key} budget exceeds the ${DEFAULT_BUDGETS[key]} default.`;\n if (budget.override === undefined) {\n error(\n `budgets.${key}`,\n \"budget_override\",\n `${message} Add budgets.override.reason to explain the increase.`,\n );\n } else {\n issue({\n path: `budgets.${key}`,\n code: \"budget_override\",\n message: `${message} Lower it to the default when the exception is no longer needed.`,\n severity: \"warning\",\n });\n }\n }\n }\n },\n );\n}\n\nexport function analytics(value: unknown, issue: AddIssue, error: AddError) {\n nested(value, \"analytics\", [\"forward\"], issue, (analyticsValue) => {\n nested(\n analyticsValue.forward,\n \"analytics.forward\",\n [\"ga4\", \"metaPixel\"],\n issue,\n (forward) => {\n if (\n forward.ga4 !== undefined &&\n (typeof forward.ga4 !== \"string\" ||\n !/^G-[A-Z0-9]+$/.test(forward.ga4))\n ) {\n error(\n \"analytics.forward.ga4\",\n \"invalid_format\",\n \"Expected a GA4 measurement id beginning with G-. Use a value such as G-XXXXXXXXXX.\",\n );\n }\n if (\n forward.metaPixel !== undefined &&\n (typeof forward.metaPixel !== \"string\" ||\n !/^\\d+$/.test(forward.metaPixel))\n ) {\n error(\n \"analytics.forward.metaPixel\",\n \"invalid_format\",\n \"Expected a numeric Meta Pixel id. Use digits only.\",\n );\n }\n },\n );\n });\n}\n","import {\n globallyAllowed,\n hostname,\n nonblank,\n packageName,\n record,\n unknownKeys,\n} from \"./helpers\";\nimport { analytics, budgets, nested } from \"./sections\";\nimport type { ConfigIssue, ConfigValidation } from \"./types\";\n\nconst rootKeys = [\n \"store\",\n \"branches\",\n \"theme\",\n \"prerender\",\n \"menu\",\n \"packages\",\n \"outbound\",\n \"budgets\",\n \"analytics\",\n] as const;\n\n/**\n * Validate a site configuration and collect errors and warnings without changing it.\n * Checks required fields, unknown keys, allowlists, budgets and analytics settings.\n *\n * @param input - The configuration value to inspect.\n * @returns Diagnostics and a valid flag that is true when there are no errors.\n */\nexport function validateConfig(input: unknown): ConfigValidation {\n const issues: ConfigIssue[] = [];\n const issue = (value: ConfigIssue) => issues.push(value);\n const error = (path: string, code: ConfigIssue[\"code\"], message: string) =>\n issue({ path, code, message, severity: \"error\" });\n if (!record(input)) {\n return {\n valid: false,\n issues: [\n {\n path: \"$\",\n code: \"invalid_type\",\n message:\n \"Expected a configuration object. Export an object from zappie.config.ts.\",\n severity: \"error\",\n },\n ],\n };\n }\n unknownKeys(input, rootKeys, \"\", issue);\n requiredSlug(input.store, \"store\", error);\n theme(input.theme, error);\n stringList(input.branches, \"branches\", error, {\n nonempty: true,\n unique: true,\n slug: true,\n });\n paths(input.prerender, error);\n nested(input.menu, \"menu\", [\"hiddenCategories\"], issue, (value) => {\n stringList(value.hiddenCategories, \"menu.hiddenCategories\", error);\n });\n nested(input.packages, \"packages\", [\"allow\"], issue, (value) => {\n const allow = stringList(value.allow, \"packages.allow\", error);\n allow?.forEach((name, index) => {\n if (globallyAllowed(name)) {\n issue({\n path: `packages.allow[${index}]`,\n code: \"redundant_allowlist\",\n message: `${name} is already globally allowed. Remove it from packages.allow.`,\n severity: \"warning\",\n });\n } else if (!packageName(name)) {\n error(\n `packages.allow[${index}]`,\n \"invalid_format\",\n \"Expected a lowercase npm package name. Use a package name such as lucide-react or @scope/name.\",\n );\n }\n });\n });\n nested(input.outbound, \"outbound\", [\"allow\"], issue, (value) => {\n const allow = stringList(value.allow, \"outbound.allow\", error);\n allow?.forEach((host, index) => {\n if (!hostname(host)) {\n error(\n `outbound.allow[${index}]`,\n \"invalid_format\",\n \"Expected a hostname or leading *. subdomain pattern without a scheme, path, port or IP. Use a value such as api.example.com.\",\n );\n }\n });\n });\n budgets(input.budgets, issue, error);\n analytics(input.analytics, issue, error);\n return {\n valid: !issues.some((entry) => entry.severity === \"error\"),\n issues,\n };\n}\n\ntype AddError = (\n path: string,\n code: ConfigIssue[\"code\"],\n message: string,\n) => void;\n\nfunction requiredSlug(value: unknown, path: string, error: AddError) {\n if (!nonblank(value)) {\n error(\n path,\n value === undefined ? \"missing_required\" : \"invalid_type\",\n `Expected a non-empty storefront slug. Set ${path} to the slug used by createZappie().`,\n );\n }\n}\n\nfunction theme(value: unknown, error: AddError) {\n if (typeof value !== \"string\") {\n error(\n \"theme\",\n value === undefined ? \"missing_required\" : \"invalid_type\",\n \"Expected a relative .json path. Set theme to a value such as ./theme.json.\",\n );\n } else if (\n !/\\.json$/.test(value) ||\n /^(?:[a-z][a-z\\d+.-]*:|\\/|\\\\)/i.test(value) ||\n value.includes(\"\\\\\")\n ) {\n error(\n \"theme\",\n \"invalid_format\",\n \"Expected a relative .json path. Use a value such as ./theme.json.\",\n );\n }\n}\n\nfunction stringList(\n value: unknown,\n path: string,\n error: AddError,\n options: { nonempty?: boolean; unique?: boolean; slug?: boolean } = {},\n) {\n if (value === undefined) {\n return undefined;\n }\n if (\n !Array.isArray(value) ||\n value.some((entry) => typeof entry !== \"string\")\n ) {\n error(\n path,\n \"invalid_type\",\n `Expected an array of strings. Set ${path} to string values.`,\n );\n return undefined;\n }\n if (options.nonempty && value.length === 0) {\n error(\n path,\n \"invalid_format\",\n `Expected at least one value. Add a value to ${path} or remove the field.`,\n );\n }\n value.forEach((entry, index) => {\n if (options.slug && !nonblank(entry)) {\n error(\n `${path}[${index}]`,\n \"invalid_format\",\n \"Expected a non-empty branch slug. Remove the empty value or use a branch slug.\",\n );\n }\n });\n if (options.unique && new Set(value).size !== value.length) {\n error(\n path,\n \"duplicate\",\n `Expected unique values. Remove duplicates from ${path}.`,\n );\n }\n return value;\n}\n\nfunction paths(value: unknown, error: AddError) {\n const values = stringList(value, \"prerender\", error, { unique: true });\n values?.forEach((path, index) => {\n if (!path.startsWith(\"/\")) {\n error(\n `prerender[${index}]`,\n \"invalid_format\",\n \"Expected a route starting with /. Prefix the route with /.\",\n );\n }\n });\n}\n","import { GLOBAL_PACKAGE_ALLOWLIST } from \"@zappie/sdk/config\";\nimport { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { loadConfig } from \"./config\";\nimport { json } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport type AllowlistSource = {\n load(signal?: AbortSignal): Promise<readonly string[]>;\n};\n\nexport const BUILTIN_ALLOWLIST_SOURCE: AllowlistSource = {\n load: async () => GLOBAL_PACKAGE_ALLOWLIST,\n};\n\ntype Manifest = {\n dependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n};\n\nexport async function checkAllowlist(\n { cwd, signal }: StepOptions,\n source: AllowlistSource = BUILTIN_ALLOWLIST_SOURCE,\n): Promise<CheckStep> {\n signal?.throwIfAborted();\n const problems: CheckProblem[] = [];\n let manifest: Manifest;\n try {\n manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n } catch (error) {\n return step(\"allowlist\", \"failed\", [\n problem(String(error), \"Add a valid package.json to the project root.\", {\n file: \"package.json\",\n }),\n ]);\n }\n if (!(await hasLockfile(cwd))) {\n problems.push(\n problem(\n \"No supported lockfile was found.\",\n \"Install dependencies and commit the generated lockfile.\",\n ),\n );\n }\n const global = await source.load(signal);\n const local = await localAllowlist(cwd);\n for (const name of Object.keys(manifest.dependencies ?? {})) {\n if (![...global, ...local].some((entry) => matches(entry, name))) {\n problems.push(\n problem(\n `${name} is not in the package allowlist.`,\n `Add ${name} to packages.allow in zappie.config.ts after reviewing it.`,\n { rule: \"allowlist/package\", file: \"package.json\" },\n ),\n );\n }\n await checkInstallScripts(cwd, name, problems);\n }\n signal?.throwIfAborted();\n return step(\"allowlist\", problems.length ? \"failed\" : \"passed\", problems);\n}\n\nasync function localAllowlist(cwd: string) {\n try {\n const loaded = await loadConfig(cwd);\n const value = loaded.value as { packages?: { allow?: unknown } };\n return Array.isArray(value?.packages?.allow)\n ? value.packages.allow.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n : [];\n } catch {\n return [];\n }\n}\n\nasync function hasLockfile(cwd: string) {\n for (let directory = cwd; ; directory = path.dirname(directory)) {\n for (const name of [\n \"pnpm-lock.yaml\",\n \"package-lock.json\",\n \"yarn.lock\",\n \"bun.lock\",\n \"bun.lockb\",\n ]) {\n try {\n await access(path.join(directory, name));\n return true;\n } catch {\n continue;\n }\n }\n if (path.dirname(directory) === directory) {\n return false;\n }\n }\n}\n\nasync function checkInstallScripts(\n cwd: string,\n name: string,\n problems: CheckProblem[],\n) {\n try {\n const dependency = await installedManifest(cwd, name);\n for (const script of [\"preinstall\", \"install\", \"postinstall\"]) {\n if (dependency.scripts?.[script]) {\n problems.push(\n problem(\n `${name} declares a ${script} script.`,\n `Remove ${name} or use a dependency without install scripts.`,\n { rule: \"allowlist/install-script\", file: \"package.json\" },\n ),\n );\n }\n }\n } catch {\n problems.push(\n problem(\n `${name} is not installed.`,\n \"Install dependencies from the committed lockfile.\",\n {\n rule: \"allowlist/not-installed\",\n file: \"package.json\",\n },\n ),\n );\n }\n}\n\nfunction matches(pattern: string, value: string) {\n return pattern.endsWith(\"/*\")\n ? value.startsWith(pattern.slice(0, -1))\n : pattern === value;\n}\n\n// Walk up like Node resolution, so dependencies hoisted to a workspace root are found.\nasync function installedManifest(cwd: string, name: string): Promise<Manifest> {\n for (let directory = cwd; ; directory = path.dirname(directory)) {\n const file = path.join(\n directory,\n \"node_modules\",\n ...name.split(\"/\"),\n \"package.json\",\n );\n try {\n return JSON.parse(await readFile(file, \"utf8\")) as Manifest;\n } catch (error) {\n if (path.dirname(directory) === directory) {\n throw error;\n }\n }\n }\n}\n","/** Closed semantic token vocabulary. Theme-private CSS variables stay outside this contract. */\nexport const COLOR_TOKENS = [\n \"--z-bg\",\n \"--z-surface\",\n \"--z-surface-raised\",\n \"--z-overlay\",\n \"--z-text\",\n \"--z-text-muted\",\n \"--z-text-inverse\",\n \"--z-accent\",\n \"--z-accent-contrast\",\n \"--z-brand-1\",\n \"--z-brand-2\",\n \"--z-brand-3\",\n \"--z-success\",\n \"--z-warning\",\n \"--z-danger\",\n \"--z-border\",\n \"--z-focus-ring\",\n] as const;\nexport const LENGTH_TOKENS = [\n \"--z-radius-sm\",\n \"--z-radius-md\",\n \"--z-radius-lg\",\n \"--z-radius-pill\",\n \"--z-space-1\",\n \"--z-space-2\",\n \"--z-space-3\",\n \"--z-space-4\",\n \"--z-space-5\",\n \"--z-space-6\",\n \"--z-space-7\",\n \"--z-space-8\",\n \"--z-text-xs\",\n \"--z-text-sm\",\n \"--z-text-md\",\n \"--z-text-lg\",\n \"--z-text-xl\",\n \"--z-text-2xl\",\n \"--z-text-3xl\",\n \"--z-drawer-width\",\n \"--z-dialog-width\",\n \"--z-dialog-height\",\n \"--z-media-sm\",\n] as const;\nexport const FONT_TOKENS = [\n \"--z-font-display\",\n \"--z-font-body\",\n \"--z-font-mono\",\n] as const;\nexport const DURATION_TOKENS = [\n \"--z-duration-fast\",\n \"--z-duration-base\",\n \"--z-duration-slow\",\n] as const;\nexport const EASING_TOKENS = [\"--z-ease-out\", \"--z-ease-in-out\"] as const;\nexport const MOTION_TOKENS = [...DURATION_TOKENS, ...EASING_TOKENS] as const;\nexport const TOKEN_NAMES = [\n ...COLOR_TOKENS,\n ...LENGTH_TOKENS,\n ...FONT_TOKENS,\n ...MOTION_TOKENS,\n] as const;\nexport const REQUIRED_TOKENS = [\n \"--z-bg\",\n \"--z-text\",\n \"--z-accent\",\n \"--z-accent-contrast\",\n] as const;\nexport type TokenName = (typeof TOKEN_NAMES)[number];\nexport type ColorToken = (typeof COLOR_TOKENS)[number];\nexport type TokenValues = Partial<Record<TokenName, string>>;\n","import type { TokenName } from \"./names\";\nimport type { ThemeJson } from \"./types\";\n\n/** Host palette from styles/colors.ts; public fonts use a licence-free system stack. */\nexport const DEFAULT_TOKENS: Readonly<Record<TokenName, string>> =\n Object.freeze({\n \"--z-bg\": \"#F9FAFB\",\n \"--z-surface\": \"#FFFFFF\",\n \"--z-surface-raised\": \"#FFFFFF\",\n \"--z-overlay\": \"#00000080\",\n \"--z-text\": \"#101828\",\n \"--z-text-muted\": \"#344054\",\n \"--z-text-inverse\": \"#FFFFFF\",\n \"--z-accent\": \"#9FE870\",\n \"--z-accent-contrast\": \"#163300\",\n \"--z-brand-1\": \"#9FE870\",\n \"--z-brand-2\": \"#163300\",\n \"--z-brand-3\": \"#EDC843\",\n \"--z-success\": \"#027A48\",\n \"--z-warning\": \"#ED7A37\",\n \"--z-danger\": \"#F04438\",\n \"--z-border\": \"#EAECF0\",\n \"--z-focus-ring\": \"#163300\",\n \"--z-radius-sm\": \"6px\",\n \"--z-radius-md\": \"12px\",\n \"--z-radius-lg\": \"20px\",\n \"--z-radius-pill\": \"9999px\",\n \"--z-space-1\": \"4px\",\n \"--z-space-2\": \"8px\",\n \"--z-space-3\": \"12px\",\n \"--z-space-4\": \"16px\",\n \"--z-space-5\": \"24px\",\n \"--z-space-6\": \"32px\",\n \"--z-space-7\": \"48px\",\n \"--z-space-8\": \"64px\",\n \"--z-font-display\": \"system-ui, sans-serif\",\n \"--z-font-body\": \"system-ui, sans-serif\",\n \"--z-font-mono\": \"ui-monospace, monospace\",\n \"--z-text-xs\": \"12px\",\n \"--z-text-sm\": \"14px\",\n \"--z-text-md\": \"16px\",\n \"--z-text-lg\": \"18px\",\n \"--z-text-xl\": \"20px\",\n \"--z-text-2xl\": \"24px\",\n \"--z-text-3xl\": \"32px\",\n \"--z-duration-fast\": \"120ms\",\n \"--z-duration-base\": \"200ms\",\n \"--z-duration-slow\": \"320ms\",\n \"--z-ease-out\": \"cubic-bezier(0, 0, 0.2, 1)\",\n \"--z-ease-in-out\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"--z-drawer-width\": \"420px\",\n \"--z-dialog-width\": \"min(1000px, calc(100vw - 32px))\",\n \"--z-dialog-height\": \"min(780px, 90dvh)\",\n \"--z-media-sm\": \"64px\",\n });\nexport const DEFAULT_THEME: ThemeJson = Object.freeze({\n version: 1,\n name: \"Zappie\",\n tokens: DEFAULT_TOKENS,\n darkMode: \"light\",\n dark: Object.freeze({\n \"--z-bg\": \"#000000\",\n \"--z-surface\": \"#242424\",\n \"--z-surface-raised\": \"#333333\",\n \"--z-text\": \"#FFFFFF\",\n \"--z-text-muted\": \"#BFBFBF\",\n \"--z-text-inverse\": \"#101828\",\n \"--z-border\": \"#474747\",\n \"--z-focus-ring\": \"#9FE870\",\n }),\n});\n","// CSS named colors from color-name 1.1.4 (MIT); see ../LICENSE.color-name.\nexport const NAMED_COLORS: Record<string, string> = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"00ffff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000000\",\n blanchedalmond: \"ffebcd\",\n blue: \"0000ff\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"00ffff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"ff00ff\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"778899\",\n lightslategrey: \"778899\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"00ff00\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"ff00ff\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"ff0000\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"ffffff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ffff00\",\n yellowgreen: \"9acd32\",\n};\n","import { NAMED_COLORS } from \"./named-colors\";\n\nexport type Rgba = [number, number, number, number];\nconst numberPattern = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?$/i;\nexport const safeValue = (value: string): boolean =>\n value.length <= 512 &&\n !/[;{}<>\\\\\\x00-\\x1f]|\\/\\*|url\\s*\\(|expression\\s*\\(/i.test(value);\nconst clamp = (n: number): number => Math.max(0, Math.min(1, n));\nfunction numeric(value: string, scale = 1): number {\n const percent = value.endsWith(\"%\");\n const raw = percent ? value.slice(0, -1) : value;\n const parsed = numberPattern.test(raw)\n ? Number(raw) / (percent ? 100 : scale)\n : NaN;\n return Number.isFinite(parsed) ? parsed : NaN;\n}\nfunction hue(value: string): number {\n const match = /^(.*?)(deg|rad|grad|turn)?$/.exec(value);\n if (!match || !numberPattern.test(match[1]!)) {\n return NaN;\n }\n const factors: Record<string, number> = {\n deg: 1,\n rad: 180 / Math.PI,\n grad: 0.9,\n turn: 360,\n };\n return Number(match[1]) * (factors[match[2] ?? \"deg\"] ?? 1);\n}\n/** Parse absolute CSS colors to normalized sRGB. Context-dependent colors are rejected. */\nexport function parseColor(input: string): Rgba | null {\n if (!safeValue(input)) {\n return null;\n }\n let value = input.trim().toLowerCase();\n if (value === \"transparent\") {\n return [0, 0, 0, 0];\n }\n if (Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)) {\n value = \"#\" + NAMED_COLORS[value];\n }\n if (/^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/.test(value)) {\n let hex = value.slice(1);\n if (hex.length < 5) {\n hex = [...hex].map((c) => c + c).join(\"\");\n }\n if (hex.length === 6) {\n hex += \"ff\";\n }\n return [0, 2, 4, 6].map(\n (i) => parseInt(hex.slice(i, i + 2), 16) / 255,\n ) as Rgba;\n }\n const match = /^(rgba?|hsla?|oklch)\\(([^()]*)\\)$/.exec(value);\n if (!match) {\n return null;\n }\n const kind = match[1]!;\n const body = match[2]!.trim();\n const comma = body.includes(\",\");\n if (comma && (body.includes(\"/\") || kind === \"oklch\")) {\n return null;\n }\n const parts = comma\n ? body.split(\",\").map((s) => s.trim())\n : body.split(/\\s*\\/\\s*/);\n let channels: string[], alpha: string | undefined;\n if (comma) {\n if (parts.length !== 3 && parts.length !== 4) {\n return null;\n }\n channels = parts.slice(0, 3);\n alpha = parts[3];\n } else {\n if (parts.length > 2) {\n return null;\n }\n channels = parts[0]!.split(/\\s+/);\n alpha = parts[1];\n }\n if (channels.length !== 3) {\n return null;\n }\n const opacity = alpha === undefined ? 1 : numeric(alpha);\n let rgb: number[];\n if (kind.startsWith(\"rgb\")) {\n if (\n comma &&\n channels.some((c) => c.endsWith(\"%\")) &&\n !channels.every((c) => c.endsWith(\"%\"))\n ) {\n return null;\n }\n rgb = channels.map((c) => numeric(c, 255));\n } else if (kind.startsWith(\"hsl\")) {\n if (!channels[1]!.endsWith(\"%\") || !channels[2]!.endsWith(\"%\")) {\n return null;\n }\n const h = ((hue(channels[0]!) % 360) + 360) % 360;\n const s = clamp(numeric(channels[1]!)),\n l = clamp(numeric(channels[2]!));\n const a = s * Math.min(l, 1 - l);\n rgb = [0, 8, 4].map((n) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n });\n } else {\n const l = clamp(numeric(channels[0]!));\n const c = Math.max(\n 0,\n numeric(channels[1]!) * (channels[1]!.endsWith(\"%\") ? 0.4 : 1),\n );\n const h = (hue(channels[2]!) * Math.PI) / 180;\n const a = c * Math.cos(h),\n b = c * Math.sin(h);\n const x = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const y = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const z = (l - 0.0894841775 * a - 1.291485548 * b) ** 3;\n rgb = [\n 4.0767416621 * x - 3.3077115913 * y + 0.2309699292 * z,\n -1.2684380046 * x + 2.6097574011 * y - 0.3413193965 * z,\n -0.0041960863 * x - 0.7034186147 * y + 1.707614701 * z,\n ].map((v) => (v <= 0.0031308 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055));\n }\n return [...rgb, opacity].every(Number.isFinite)\n ? ([...rgb.map(clamp), clamp(opacity)] as Rgba)\n : null;\n}\n/** Restricted, recursively parsed CSS lengths; arithmetic is allowed only inside calc(). */\nexport function isLength(value: string, depth = 0): boolean {\n if (!safeValue(value) || depth > 8) {\n return false;\n }\n const text = value.trim();\n if (/^(?:0|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:px|rem|em|%|dvh|vh|vw))$/.test(text)) {\n return true;\n }\n const fn = /^(min|max|clamp|calc)\\((.*)\\)$/.exec(text);\n if (!fn) {\n return false;\n }\n let level = 0,\n start = 0;\n const args: string[] = [];\n for (let i = 0; i < fn[2]!.length; i++) {\n const c = fn[2]![i];\n if (c === \"(\") {\n level++;\n }\n if (c === \")\" && --level < 0) {\n return false;\n }\n const separator =\n fn[1] === \"calc\"\n ? (c === \"+\" || c === \"-\") &&\n /\\s/.test(fn[2]![i - 1] ?? \"\") &&\n /\\s/.test(fn[2]![i + 1] ?? \"\")\n : c === \",\";\n if (level === 0 && separator) {\n args.push(fn[2]!.slice(start, i));\n start = i + 1;\n }\n }\n args.push(fn[2]!.slice(start));\n return (\n level === 0 &&\n (fn[1] !== \"clamp\" || args.length === 3) &&\n args.every((arg) => isLength(arg, depth + 1))\n );\n}\n/** CSS-wide keywords are not family names and invalidate a font-family list. */\nconst cssWideKeyword = /^(?:inherit|initial|unset|revert|revert-layer|default)$/i;\nexport function isFontFamily(value: string): boolean {\n return (\n safeValue(value) &&\n value.split(\",\").every((part) => {\n const family = part.trim();\n return (\n /^[a-zA-Z][a-zA-Z0-9 -]*$/.test(family) && !cssWideKeyword.test(family)\n );\n })\n );\n}\nexport function isDuration(value: string): boolean {\n return /^(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:ms|s)$/.test(value);\n}\nexport function isEasing(value: string): boolean {\n if (\n /^(linear|ease|ease-in|ease-out|ease-in-out|step-start|step-end)$/.test(\n value,\n )\n ) {\n return true;\n }\n const m = /^cubic-bezier\\((.*)\\)$/.exec(value);\n if (!m) {\n return false;\n }\n const ns = m[1]!\n .split(\",\")\n .map((s) => (numberPattern.test(s.trim()) ? numeric(s.trim()) : NaN));\n return (\n ns.length === 4 &&\n ns.every(Number.isFinite) &&\n ns[0]! >= 0 &&\n ns[0]! <= 1 &&\n ns[2]! >= 0 &&\n ns[2]! <= 1\n );\n}\nexport function isAssetUrl(value: string, relative = true): boolean {\n if (!value || !safeValue(value) || /[\\s\"'()]/.test(value)) {\n return false;\n }\n if (relative && !/^[a-z][\\w+.-]*:/i.test(value) && !value.startsWith(\"//\")) {\n return true;\n }\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" && !url.username && !url.password;\n } catch {\n return false;\n }\n}\n","import { parseColor } from \"./parse\";\n\n/** WCAG contrast for absolute colors. A translucent background needs an explicit backdrop. */\nexport function contrastRatio(fg: string, bg: string): number {\n const foreground = parseColor(fg),\n background = parseColor(bg);\n if (!foreground || !background || background[3] !== 1) {\n return NaN;\n }\n const luminance = (channels: number[]) =>\n channels\n .map((c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4))\n .reduce((sum, c, i) => sum + c * [0.2126, 0.7152, 0.0722][i]!, 0);\n const a = luminance(\n foreground\n .slice(0, 3)\n .map((c, i) => c * foreground[3] + background[i]! * (1 - foreground[3])),\n );\n const b = luminance(background.slice(0, 3));\n return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);\n}\n","import {\n COLOR_TOKENS,\n LENGTH_TOKENS,\n FONT_TOKENS,\n DURATION_TOKENS,\n TOKEN_NAMES,\n REQUIRED_TOKENS,\n} from \"./names\";\nimport type { TokenName, TokenValues } from \"./names\";\nimport { DEFAULT_TOKENS } from \"./defaults\";\nimport { contrastRatio } from \"./contrast\";\nimport {\n parseColor,\n isLength,\n isFontFamily,\n isDuration,\n isEasing,\n isAssetUrl,\n safeValue,\n} from \"./parse\";\nimport type { ThemeIssue, ThemeJson, ThemeValidation } from \"./types\";\n\nconst record = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst includes = (values: readonly string[], key: string) =>\n values.includes(key);\n/** Validate untrusted theme JSON, including syntax, CSS injection and effective light/dark contrast. */\nexport function validateTheme(input: unknown): ThemeValidation {\n const issues: ThemeIssue[] = [];\n const issue = (\n path: string,\n code: ThemeIssue[\"code\"],\n message: string,\n severity: ThemeIssue[\"severity\"] = \"error\",\n ) => issues.push({ path, code, message, severity });\n const keys = (\n obj: Record<string, unknown>,\n allowed: string[],\n path: string,\n ) => {\n for (const key of Object.keys(obj)) {\n if (!allowed.includes(key)) {\n issue(path ? `${path}.${key}` : key, \"invalid_theme\", \"Unknown field\");\n }\n }\n };\n if (!record(input)) {\n return {\n ok: false,\n issues: [\n {\n path: \"\",\n code: \"invalid_theme\",\n message: \"Expected a theme object\",\n severity: \"error\",\n },\n ],\n };\n }\n keys(\n input,\n [\n \"$schema\",\n \"version\",\n \"name\",\n \"tokens\",\n \"dark\",\n \"darkMode\",\n \"fonts\",\n \"logo\",\n \"motion\",\n ],\n \"\",\n );\n if (input.version !== 1) {\n issue(\"version\", \"invalid_theme\", \"Expected version 1\");\n }\n if (\n typeof input.name !== \"string\" ||\n !input.name.trim() ||\n input.name.length > 100\n ) {\n issue(\"name\", \"missing_required\", \"Expected a name of 1–100 characters\");\n }\n if (\n input.$schema !== undefined &&\n (typeof input.$schema !== \"string\" || !isAssetUrl(input.$schema, false))\n ) {\n issue(\"$schema\", \"invalid_theme\", \"Expected an HTTPS schema URL\");\n }\n if (\n input.darkMode !== undefined &&\n (typeof input.darkMode !== \"string\" ||\n ![\"auto\", \"light\", \"dark\"].includes(input.darkMode))\n ) {\n issue(\"darkMode\", \"invalid_theme\", \"Expected auto, light or dark\");\n }\n for (const group of [\"tokens\", \"dark\"] as const) {\n const values = input[group];\n if (group === \"dark\" && values === undefined) {\n continue;\n }\n if (!record(values)) {\n issue(group, \"missing_required\", \"Expected a token object\");\n continue;\n }\n if (group === \"tokens\") {\n for (const key of REQUIRED_TOKENS) {\n if (!Object.prototype.hasOwnProperty.call(values, key)) {\n issue(`${group}.${key}`, \"missing_required\", \"Required token\");\n }\n }\n }\n for (const [key, value] of Object.entries(values)) {\n const path = `${group}.${key}`;\n if (!includes(TOKEN_NAMES, key)) {\n issue(path, \"unknown_token\", \"Unknown semantic token\");\n continue;\n }\n let code: ThemeIssue[\"code\"],\n valid = false;\n if (includes(COLOR_TOKENS, key)) {\n code = \"invalid_color\";\n valid = typeof value === \"string\" && parseColor(value) !== null;\n } else if (includes(LENGTH_TOKENS, key)) {\n code = \"invalid_length\";\n valid = typeof value === \"string\" && isLength(value);\n } else if (includes(FONT_TOKENS, key)) {\n code = \"invalid_font\";\n valid = typeof value === \"string\" && isFontFamily(value);\n } else {\n code = \"invalid_motion\";\n valid =\n typeof value === \"string\" &&\n safeValue(value) &&\n (includes(DURATION_TOKENS, key)\n ? isDuration(value)\n : isEasing(value));\n }\n if (!valid) {\n issue(path, code, \"Invalid or unsafe token value\");\n }\n }\n }\n if (input.fonts !== undefined) {\n if (!Array.isArray(input.fonts) || input.fonts.length > 3) {\n issue(\"fonts\", \"invalid_font\", \"Expected at most three fonts\");\n } else {\n const roles = new Set<string>();\n input.fonts.forEach((font: unknown, i: number) => {\n const path = `fonts[${i}]`;\n if (!record(font)) {\n issue(path, \"invalid_font\", \"Expected a font object\");\n return;\n }\n keys(font, [\"family\", \"source\", \"url\", \"weights\", \"role\"], path);\n if (\n typeof font.family !== \"string\" ||\n !isFontFamily(font.family) ||\n font.family.includes(\",\")\n ) {\n issue(\n `${path}.family`,\n \"invalid_font\",\n \"Expected one unquoted font family\",\n );\n }\n if (\n typeof font.source !== \"string\" ||\n ![\"google\", \"self\", \"system\"].includes(font.source)\n ) {\n issue(`${path}.source`, \"invalid_font\", \"Unknown font source\");\n }\n if (\n typeof font.role !== \"string\" ||\n ![\"display\", \"body\", \"mono\"].includes(font.role) ||\n roles.has(font.role)\n ) {\n issue(`${path}.role`, \"invalid_font\", \"Expected a unique font role\");\n }\n roles.add(String(font.role));\n if (font.source === \"self\" || font.url !== undefined) {\n if (\n typeof font.url !== \"string\" ||\n !isAssetUrl(font.url, false) ||\n !new URL(font.url).pathname.endsWith(\".woff2\")\n ) {\n issue(\n `${path}.url`,\n \"invalid_font\",\n \"Expected an HTTPS .woff2 URL\",\n );\n }\n }\n if (\n font.weights !== undefined &&\n (!Array.isArray(font.weights) ||\n !font.weights.length ||\n font.weights.length > 9 ||\n font.weights.some(\n (w) =>\n typeof w !== \"number\" ||\n !Number.isInteger(w) ||\n w < 1 ||\n w > 1000,\n ))\n ) {\n issue(\n `${path}.weights`,\n \"invalid_font\",\n \"Expected 1–9 integer weights between 1 and 1000\",\n );\n }\n });\n }\n }\n if (input.logo !== undefined) {\n if (!record(input.logo)) {\n issue(\"logo\", \"invalid_logo\", \"Expected a logo object\");\n } else {\n keys(input.logo, [\"light\", \"dark\", \"mark\", \"alt\"], \"logo\");\n if (typeof input.logo.alt !== \"string\" || !input.logo.alt.trim()) {\n issue(\"logo.alt\", \"invalid_logo\", \"Logo alternative text is required\");\n }\n for (const key of [\"light\", \"dark\", \"mark\"]) {\n const value = input.logo[key];\n if (key === \"light\" || value !== undefined) {\n if (typeof value !== \"string\" || !isAssetUrl(value)) {\n issue(\n `logo.${key}`,\n \"invalid_logo\",\n \"Expected HTTPS or a relative asset path\",\n );\n }\n }\n }\n }\n }\n if (input.motion !== undefined) {\n if (!record(input.motion)) {\n issue(\"motion\", \"invalid_motion\", \"Expected a motion object\");\n } else {\n keys(input.motion, [\"reduce\"], \"motion\");\n if (\n input.motion.reduce !== undefined &&\n typeof input.motion.reduce !== \"boolean\"\n ) {\n issue(\"motion.reduce\", \"invalid_motion\", \"Expected a boolean\");\n }\n }\n }\n const tokenGroup = (value: unknown): TokenValues =>\n record(value) ? (value as TokenValues) : {};\n for (const group of record(input.dark) ? [\"tokens\", \"dark\"] : [\"tokens\"]) {\n const values: Record<string, unknown> = {\n ...DEFAULT_TOKENS,\n ...tokenGroup(input.tokens),\n ...(group === \"dark\" ? tokenGroup(input.dark) : {}),\n };\n const pairs: [TokenName, TokenName, number, ThemeIssue[\"severity\"]][] = [\n [\"--z-text\", \"--z-bg\", 4.5, \"error\"],\n [\"--z-text\", \"--z-surface\", 4.5, \"error\"],\n [\"--z-accent-contrast\", \"--z-accent\", 4.5, \"error\"],\n [\"--z-text-muted\", \"--z-bg\", 3, \"warning\"],\n ];\n for (const [fg, bg, minimum, severity] of pairs) {\n const foreground = values[fg],\n background = values[bg];\n // An unparseable colour has already been reported as invalid_color.\n if (\n typeof foreground !== \"string\" ||\n typeof background !== \"string\" ||\n !parseColor(foreground) ||\n !parseColor(background)\n ) {\n continue;\n }\n const ratio = contrastRatio(foreground, background);\n if (!Number.isFinite(ratio)) {\n issue(\n `${group}.${bg}`,\n \"unverified_contrast\",\n \"A contrast background must be opaque\",\n \"error\",\n );\n } else if (ratio < minimum) {\n issue(\n `${group}.${fg}`,\n \"low_contrast\",\n `Contrast against ${bg} must be at least ${minimum}:1`,\n severity,\n );\n }\n }\n }\n return issues.some((i) => i.severity === \"error\")\n ? { ok: false, issues }\n : { ok: true, theme: input as ThemeJson, warnings: issues };\n}\n","import { validateConfig, type ConfigIssue } from \"@zappie/sdk/config\";\nimport { validateTheme, type ThemeIssue } from \"@zappie/tokens/validate\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { lineFor } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport type LoadedConfig = {\n value: unknown;\n source: string;\n file: string;\n};\n\nexport function supportsTypeScriptImport(version = process.versions.node) {\n const [major = 0, minor = 0] = version.split(\".\").map(Number);\n return major > 22 || (major === 22 && minor >= 18);\n}\n\nexport async function loadConfig(cwd: string): Promise<LoadedConfig> {\n const file = path.join(cwd, \"zappie.config.ts\");\n if (!supportsTypeScriptImport()) {\n throw new Error(\n \"zappie check needs Node 22.18 or later to read zappie.config.ts\",\n );\n }\n const source = await readFile(file, \"utf8\");\n const version = (await stat(file)).mtimeMs;\n const loaded = (await import(\n `${pathToFileURL(file).href}?check=${version}`\n )) as {\n default?: unknown;\n };\n return { value: loaded.default, source, file };\n}\n\nexport async function checkConfig({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n let loaded: LoadedConfig;\n try {\n loaded = await loadConfig(cwd);\n } catch (error) {\n return step(\"config\", \"failed\", [\n problem(\n message(error),\n \"Create a readable zappie.config.ts in the project root.\",\n {\n file: \"zappie.config.ts\",\n },\n ),\n ]);\n }\n const validation = validateConfig(loaded.value);\n const problems = validation.issues.map((issue) =>\n configProblem(issue, loaded.source),\n );\n let themeFailed = false;\n const theme = configTheme(loaded.value);\n if (theme) {\n const checkedTheme = await themeProblems(cwd, theme);\n problems.push(...checkedTheme.problems);\n themeFailed = checkedTheme.failed;\n }\n signal?.throwIfAborted();\n return step(\n \"config\",\n validation.issues.some((issue) => issue.severity === \"error\") || themeFailed\n ? \"failed\"\n : \"passed\",\n problems,\n );\n}\n\nfunction configProblem(issue: ConfigIssue, source: string): CheckProblem {\n const line = lineFor(source, issue.path);\n return problem(`${issue.path}: ${issue.message}`, issue.message, {\n rule: `config/${issue.code}`,\n file: \"zappie.config.ts\",\n ...(line ? { line } : {}),\n });\n}\n\nasync function themeProblems(cwd: string, theme: string) {\n const file = path.resolve(cwd, theme);\n try {\n const source = await readFile(file, \"utf8\");\n const result = validateTheme(JSON.parse(source) as unknown);\n const issues = result.ok ? result.warnings : result.issues;\n return {\n failed: issues.some((issue) => issue.severity === \"error\"),\n problems: issues.map((issue) => themeProblem(issue, source, theme)),\n };\n } catch (error) {\n return {\n failed: true,\n problems: [\n problem(message(error), `Make ${theme} a readable JSON theme file.`, {\n rule: \"theme/unreadable\",\n file: theme,\n }),\n ],\n };\n }\n}\n\nfunction themeProblem(issue: ThemeIssue, source: string, file: string) {\n const line = lineFor(source, issue.path);\n return problem(`${issue.path}: ${issue.message}`, issue.message, {\n rule: `theme/${issue.code}`,\n file,\n ...(line ? { line } : {}),\n });\n}\n\nfunction configTheme(value: unknown) {\n return value &&\n typeof value === \"object\" &&\n \"theme\" in value &&\n typeof value.theme === \"string\"\n ? value.theme\n : undefined;\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport async function json<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport function relative(cwd: string, file: string) {\n return path.relative(cwd, file).split(path.sep).join(\"/\");\n}\n\nexport function lineFor(source: string, issuePath: string) {\n const key = issuePath\n .split(\".\")\n .at(-1)\n ?.replace(/\\[\\d+\\]$/, \"\");\n if (!key || key === \"$\") {\n return undefined;\n }\n const quoted = JSON.stringify(key);\n const lines = source.split(/\\r?\\n/);\n const index = lines.findIndex(\n (line) =>\n line.includes(quoted) || new RegExp(`\\\\b${escape(key)}\\\\b`).test(line),\n );\n return index < 0 ? undefined : index + 1;\n}\n\nfunction escape(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import type {\n CheckProblem,\n CheckResultValue,\n CheckStep,\n CheckStepName,\n} from \"./types\";\n\nexport function problem(\n message: string,\n fix: string | null,\n details: Partial<Omit<CheckProblem, \"message\" | \"fix\">> = {},\n): CheckProblem {\n return { ...details, message, fix };\n}\n\nexport function step(\n name: CheckStepName,\n result: CheckResultValue,\n problems: CheckProblem[] = [],\n): CheckStep {\n return { name, result, problems };\n}\n\nexport const skipped = (name: CheckStepName, message: string) =>\n step(name, \"skipped\", [problem(message, null)]);\n","import { DEFAULT_BUDGETS, type ZappieSiteConfig } from \"@zappie/sdk/config\";\nimport { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { cssSizes } from \"./budget-files\";\nimport {\n clientKeys,\n graphSizes,\n routeKeys,\n type AssetSize,\n type ManifestEntry,\n} from \"./budget-manifest\";\nimport { loadConfig } from \"./config\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nconst KIB = 1024;\n\nexport async function checkBudgets({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const manifestFile = path.join(cwd, \"build/client/.vite/manifest.json\");\n try {\n await access(manifestFile);\n } catch {\n return skipped(\n \"budgets\",\n \"No build/client/.vite/manifest.json is available.\",\n );\n }\n const manifest = JSON.parse(await readFile(manifestFile, \"utf8\")) as Record<\n string,\n ManifestEntry\n >;\n const config = (await loadConfig(cwd)).value as ZappieSiteConfig;\n const limits = { ...DEFAULT_BUDGETS, ...config.budgets };\n const routes = routeKeys(manifest);\n const clients = clientKeys(manifest);\n if (routes.length === 0 || clients.length === 0) {\n throw new Error(\n \"The Vite manifest needs a client entry and app/routes entries.\",\n );\n }\n const problems: CheckProblem[] = [];\n let failed = false;\n for (const route of routes) {\n const sizes = await graphSizes(cwd, manifest, [...clients, route]);\n const over = total(sizes) > limits.jsKbGz * KIB;\n failed ||= over;\n problems.push(routeProblem(route, sizes, limits.jsKbGz, over));\n }\n const styles = await cssSizes(cwd);\n const cssOver = total(styles) > limits.cssKbGz * KIB;\n failed ||= cssOver;\n problems.push(cssProblem(styles, limits.cssKbGz, cssOver));\n problems.push(\n problem(\n `LCP is not measured by zappie check; zappie verify enforces the ${limits.lcpMs} ms budget.`,\n null,\n { rule: \"budgets/lcp\" },\n ),\n );\n signal?.throwIfAborted();\n return step(\"budgets\", failed ? \"failed\" : \"passed\", problems);\n}\n\nfunction routeProblem(\n route: string,\n sizes: AssetSize[],\n limitKb: number,\n over: boolean,\n) {\n const bytes = total(sizes);\n const largest = [...sizes]\n .sort((left, right) => right.bytes - left.bytes)\n .slice(0, 3)\n .map(({ file, bytes: size }) => `${file} (${size} B)`)\n .join(\", \");\n return problem(\n `${route}: ${bytes} B gzip (limit ${limitKb * KIB} B).${over ? ` Largest chunks: ${largest}.` : \"\"}`,\n over\n ? \"Reduce the route's client JavaScript or raise the reviewed budget override.\"\n : null,\n {\n rule: over ? \"budgets/js-over\" : \"budgets/js-route\",\n file: \"build/client/.vite/manifest.json\",\n },\n );\n}\n\nfunction cssProblem(sizes: AssetSize[], limitKb: number, over: boolean) {\n const bytes = total(sizes);\n return problem(\n `Client CSS: ${bytes} B gzip (limit ${limitKb * KIB} B).`,\n over ? \"Reduce client CSS or raise the reviewed budget override.\" : null,\n { rule: over ? \"budgets/css-over\" : \"budgets/css\" },\n );\n}\n\nconst total = (sizes: AssetSize[]) =>\n sizes.reduce((sum, asset) => sum + asset.bytes, 0);\n","import { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport type { AssetSize } from \"./budget-manifest\";\n\nexport async function cssSizes(cwd: string) {\n const root = path.join(cwd, \"build/client\");\n const files: string[] = [];\n await collect(root, files);\n return Promise.all(\n files\n .filter((file) => file.endsWith(\".css\"))\n .map(async (file): Promise<AssetSize> => ({\n file: path.relative(root, file).split(path.sep).join(\"/\"),\n bytes: gzipSync(await readFile(file, \"utf8\")).byteLength,\n })),\n );\n}\n\nasync function collect(directory: string, files: string[]) {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n if (entry.isSymbolicLink()) {\n continue;\n }\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n await collect(file, files);\n } else if (entry.isFile()) {\n files.push(file);\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\n\nexport type ManifestEntry = {\n file: string;\n src?: string;\n isEntry?: boolean;\n imports?: string[];\n};\n\nexport type AssetSize = { file: string; bytes: number };\n\nexport function routeKeys(manifest: Record<string, ManifestEntry>) {\n return Object.entries(manifest)\n .filter(([key, entry]) => routeSource(entry.src ?? key))\n .map(([key]) => key)\n .sort();\n}\n\nexport function clientKeys(manifest: Record<string, ManifestEntry>) {\n return Object.entries(manifest)\n .filter(([key, entry]) => entry.isEntry && !routeSource(entry.src ?? key))\n .map(([key]) => key)\n .sort();\n}\n\nexport async function graphSizes(\n cwd: string,\n manifest: Record<string, ManifestEntry>,\n roots: string[],\n) {\n const keys = closure(manifest, roots);\n return Promise.all(\n [...keys]\n .map((key) => manifest[key])\n .filter((entry): entry is ManifestEntry => Boolean(entry))\n .filter(({ file }) => file.endsWith(\".js\"))\n .map(async ({ file }) => ({\n file,\n bytes: gzipSync(\n await readFile(path.join(cwd, \"build/client\", file), \"utf8\"),\n ).byteLength,\n })),\n );\n}\n\nfunction closure(manifest: Record<string, ManifestEntry>, roots: string[]) {\n const visited = new Set<string>();\n const visit = (key: string) => {\n if (visited.has(key)) {\n return;\n }\n const entry = manifest[key];\n if (!entry) {\n throw new Error(`Manifest import ${key} has no entry.`);\n }\n visited.add(key);\n for (const dependency of entry.imports ?? []) {\n visit(dependency);\n }\n };\n roots.forEach(visit);\n return visited;\n}\n\nfunction routeSource(value: string) {\n return value.replace(/^\\/?/, \"\").startsWith(\"app/routes/\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { command, execArgs, scriptArgs } from \"./command\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n};\n\nexport async function checkBuild({\n cwd,\n packageManager,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const manifest = JSON.parse(\n await readFile(path.join(cwd, \"package.json\"), \"utf8\"),\n ) as Manifest;\n const invocation = manifest.dependencies?.[\"react-router\"]\n ? execArgs(packageManager, \"react-router\", [\"build\"])\n : manifest.scripts?.build\n ? scriptArgs(packageManager, \"build\")\n : undefined;\n if (!invocation) {\n return skipped(\n \"build\",\n \"No react-router dependency or build script is defined in package.json.\",\n );\n }\n const result = await command(\n invocation.executable,\n invocation.args,\n cwd,\n signal,\n );\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"build\", \"passed\");\n }\n return step(\"build\", \"failed\", [\n problem(\n `The project build failed.\\n${usefulTail(result.stdout, result.stderr)}`,\n \"Fix the reported build errors and run zappie check again.\",\n { rule: \"build/failed\" },\n ),\n ]);\n}\n\nfunction usefulTail(stdout: string, stderr: string) {\n const lines = `${stdout}\\n${stderr}`\n .split(/\\r?\\n/)\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .slice(-12);\n return lines.length > 0\n ? lines.join(\"\\n\")\n : \"The build exited without output.\";\n}\n","import { spawn } from \"node:child_process\";\nimport type { PackageManager } from \"./types\";\n\nexport type CommandResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport function command(\n executable: string,\n args: string[],\n cwd: string,\n signal?: AbortSignal,\n): Promise<CommandResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(executable, args, {\n cwd,\n env: { ...process.env, NO_COLOR: \"1\", FORCE_COLOR: \"0\" },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...(signal ? { signal } : {}),\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (value) => {\n stdout += String(value);\n });\n child.stderr.on(\"data\", (value) => {\n stderr += String(value);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport function execArgs(\n manager: PackageManager,\n binary: string,\n args: string[],\n) {\n // Never download a missing binary: the check runs the project's own tools.\n if (manager === \"npm\") {\n return { executable: \"npm\", args: [\"exec\", \"--no\", \"--\", binary, ...args] };\n }\n if (manager === \"yarn\") {\n return { executable: \"yarn\", args: [\"exec\", binary, ...args] };\n }\n if (manager === \"bun\") {\n return { executable: \"bun\", args: [\"x\", \"--no-install\", binary, ...args] };\n }\n return { executable: \"pnpm\", args: [\"exec\", binary, ...args] };\n}\n\nexport function scriptArgs(manager: PackageManager, name: string) {\n if (manager === \"bun\") {\n return { executable: \"bun\", args: [\"run\", name] };\n }\n if (manager === \"npm\") {\n return { executable: \"npm\", args: [\"run\", name] };\n }\n return { executable: manager, args: [name] };\n}\n","import zappie from \"eslint-plugin-zappie\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { relative } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype LintMessage = {\n ruleId: string | null;\n line?: number;\n message: string;\n severity: number;\n fatal?: boolean;\n};\ntype LintResult = { filePath: string; messages: LintMessage[] };\ntype EslintInstance = {\n calculateConfigForFile(\n file: string,\n ): Promise<{ rules?: Record<string, unknown> } | undefined>;\n lintFiles(patterns: string[]): Promise<LintResult[]>;\n};\ntype EslintConstructor = new (options: { cwd: string }) => EslintInstance;\n\nexport async function checkLint({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n let ESLint: EslintConstructor;\n try {\n const require = createRequire(path.join(cwd, \"package.json\"));\n const loadedEslint = (await import(\n pathToFileURL(require.resolve(\"eslint\")).href\n )) as {\n ESLint: EslintConstructor;\n };\n ESLint = loadedEslint.ESLint;\n } catch (error) {\n return step(\"lint\", \"failed\", [\n problem(message(error), \"Install ESLint in the project.\", {\n rule: \"lint/unavailable\",\n }),\n ]);\n }\n try {\n const eslint = new ESLint({ cwd });\n const source = await sourceFile(cwd);\n const config = await eslint.calculateConfigForFile(source);\n const problems = recommendedProblems(config?.rules ?? {});\n if (problems.length > 0) {\n return step(\"lint\", \"failed\", problems);\n }\n const results = await eslint.lintFiles([\".\"]);\n signal?.throwIfAborted();\n const lintProblems = results.flatMap((result) =>\n result.messages.map((entry) =>\n problem(entry.message, null, {\n ...(entry.ruleId ? { rule: entry.ruleId } : {}),\n file: relative(cwd, result.filePath),\n ...(entry.line ? { line: entry.line } : {}),\n }),\n ),\n );\n const failed = results.some((result) =>\n result.messages.some((entry) => entry.fatal || entry.severity === 2),\n );\n return step(\"lint\", failed ? \"failed\" : \"passed\", lintProblems);\n } catch (error) {\n return step(\"lint\", \"failed\", [\n problem(\n message(error),\n \"Fix the project ESLint configuration and run lint again.\",\n {\n rule: \"lint/config\",\n },\n ),\n ]);\n }\n}\n\nfunction recommendedProblems(applied: Record<string, unknown>) {\n const expected = recommendedRules();\n return Object.entries(expected).flatMap(([rule, severity]) => {\n if (level(applied[rule]) >= level(severity)) {\n return [];\n }\n return [\n problem(\n `${rule} is not enabled at the recommended severity.`,\n \"Apply every entry from zappie.configs.recommended in eslint.config.mjs.\",\n { rule, file: \"eslint.config.mjs\" },\n ),\n ];\n });\n}\n\nfunction recommendedRules() {\n const result: Record<string, unknown> = {};\n for (const config of zappie.configs.recommended ?? []) {\n Object.assign(result, config.rules ?? {});\n }\n return Object.fromEntries(\n Object.entries(result).filter(([name]) => name.startsWith(\"zappie/\")),\n );\n}\n\nfunction level(value: unknown): number {\n const selected = Array.isArray(value) ? value[0] : value;\n if (selected === \"error\" || selected === 2) {\n return 2;\n }\n if (selected === \"warn\" || selected === 1) {\n return 1;\n }\n return 0;\n}\n\nasync function sourceFile(cwd: string) {\n const candidates = [\n \"app/index.ts\",\n \"app/root.tsx\",\n \"src/index.ts\",\n \"index.ts\",\n ];\n for (const candidate of candidates) {\n try {\n await import(\"node:fs/promises\").then(({ access }) =>\n access(path.join(cwd, candidate)),\n );\n return candidate;\n } catch {\n continue;\n }\n }\n return \"eslint.config.mjs\";\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n","import { lstat, readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { relative } from \"./files\";\nimport { step } from \"./result\";\nimport { secretMatches } from \"./secret-patterns\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport const SECRET_FILE_SIZE_CAP = 1024 * 1024;\nexport type SecretFinding = CheckProblem & {\n severity: \"error\" | \"warning\";\n};\n\nexport async function scanSecrets(dir: string): Promise<SecretFinding[]> {\n const findings: SecretFinding[] = [];\n for (const file of await filesToScan(dir)) {\n const info = await lstat(file);\n if (!info.isFile() || info.size > SECRET_FILE_SIZE_CAP) {\n continue;\n }\n const contents = await readFile(file);\n if (contents.includes(0)) {\n continue;\n }\n const source = contents.toString(\"utf8\");\n for (const match of secretMatches(\n source,\n path.basename(file).startsWith(\".env\"),\n )) {\n findings.push({\n rule: match.rule,\n file: relative(dir, file),\n line: lineAt(source, match.index),\n message: match.message,\n fix: match.fix,\n severity: match.severity,\n });\n }\n }\n return findings;\n}\n\nexport async function checkSecrets({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const findings = await scanSecrets(cwd);\n signal?.throwIfAborted();\n const failed = findings.some(({ severity }) => severity === \"error\");\n return step(\n \"secrets\",\n failed ? \"failed\" : \"passed\",\n findings.map(({ severity: _severity, ...finding }) => finding),\n );\n}\n\nasync function filesToScan(cwd: string) {\n const files: string[] = [];\n for (const directory of [\"app\", \"public\"]) {\n await collect(path.join(cwd, directory), files);\n }\n await collect(path.join(cwd, \"build/client\"), files, (file) =>\n file.endsWith(\".js\"),\n );\n try {\n for (const entry of await readdir(cwd, { withFileTypes: true })) {\n if (entry.isFile() && rootConfig(entry.name)) {\n files.push(path.join(cwd, entry.name));\n }\n }\n } catch {\n return files.sort();\n }\n return [...new Set(files)].sort();\n}\n\nasync function collect(\n directory: string,\n files: string[],\n accept: (file: string) => boolean = () => true,\n) {\n try {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n if (entry.isSymbolicLink()) {\n continue;\n }\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n await collect(file, files, accept);\n } else if (entry.isFile() && accept(file)) {\n files.push(file);\n }\n }\n } catch (error) {\n if (!(\n error instanceof Error &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n )) {\n throw error;\n }\n }\n}\n\nfunction rootConfig(name: string) {\n return (\n name === \"package.json\" ||\n name === \"wrangler.json\" ||\n name === \"wrangler.jsonc\" ||\n /(?:^|\\.)config\\.(?:[cm]?[jt]s|json)$/.test(name)\n );\n}\n\nfunction lineAt(source: string, index: number) {\n return source.slice(0, index).split(/\\r?\\n/).length;\n}\n","export type SecretMatch = {\n index: number;\n rule: string;\n message: string;\n fix: string;\n severity: \"error\" | \"warning\";\n};\n\nconst FIX = \"Move the value to a server environment variable and rotate it.\";\n\nexport function secretMatches(source: string, envFile: boolean) {\n const matches: SecretMatch[] = [];\n add(matches, source, /sk_(test|live)_[A-Za-z0-9]{16,}/g, (value) => {\n const live = value.startsWith(\"sk_live_\");\n return {\n rule: live ? \"secrets/sk-live\" : \"secrets/sk-test\",\n message: `Detected ${live ? \"sk_live_\" : \"sk_test_\"}… secret.`,\n fix: FIX,\n severity: \"error\",\n };\n });\n if (!envFile) {\n add(matches, source, /pk_live_[A-Za-z0-9]{16,}/g, () => ({\n rule: \"secrets/pk-live\",\n message: \"Warning: detected pk_live_… outside an .env file.\",\n fix: \"Move the publishable key to a server-provided environment variable.\",\n severity: \"warning\",\n }));\n }\n add(matches, source, /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----/g, () => ({\n rule: \"secrets/private-key\",\n message: \"Detected a PEM private key header.\",\n fix: FIX,\n severity: \"error\",\n }));\n add(matches, source, /AKIA[0-9A-Z]{16}/g, () => ({\n rule: \"secrets/aws-access-key\",\n message: \"Detected an AKIA… access key.\",\n fix: FIX,\n severity: \"error\",\n }));\n add(matches, source, /FLWSECK-[A-Za-z0-9_-]{8,}/g, () => ({\n rule: \"secrets/flutterwave-live\",\n message: \"Detected an FLWSECK-… secret.\",\n fix: FIX,\n severity: \"error\",\n }));\n const occupied = matches.map(({ index }) => index);\n const assignment =\n /\\b([A-Za-z_$][\\w$]*(?:secret|token|password|api[_-]?key)[\\w$]*)\\s*[:=]\\s*([\"'])([^\"'\\r\\n]{24,})\\2/gi;\n for (const found of source.matchAll(assignment)) {\n const value = found[3] ?? \"\";\n const valueIndex = (found.index ?? 0) + found[0].indexOf(value);\n if (\n entropy(value) > 4 &&\n !occupied.some(\n (index) => index >= valueIndex && index < valueIndex + value.length,\n )\n ) {\n matches.push({\n index: valueIndex,\n rule: \"secrets/high-entropy\",\n message: `Detected a high-entropy value assigned to ${found[1] ?? \"a secret-shaped name\"}.`,\n fix: FIX,\n severity: \"error\",\n });\n }\n }\n return matches.sort((left, right) => left.index - right.index);\n}\n\nfunction add(\n output: SecretMatch[],\n source: string,\n pattern: RegExp,\n details: (value: string) => Omit<SecretMatch, \"index\">,\n) {\n for (const match of source.matchAll(pattern)) {\n output.push({ index: match.index ?? 0, ...details(match[0]) });\n }\n}\n\nfunction entropy(value: string) {\n const counts = new Map<string, number>();\n for (const character of value) {\n counts.set(character, (counts.get(character) ?? 0) + 1);\n }\n return [...counts.values()].reduce((total, count) => {\n const probability = count / value.length;\n return total - probability * Math.log2(probability);\n }, 0);\n}\n","import path from \"node:path\";\nimport { command, scriptArgs } from \"./command\";\nimport { json } from \"./files\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = { scripts?: Record<string, string> };\n\nexport async function checkTests({\n cwd,\n packageManager,\n signal,\n}: StepOptions): Promise<CheckStep> {\n const manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n if (!manifest.scripts?.test) {\n return skipped(\"test\", \"No test script is defined in package.json.\");\n }\n const invocation = scriptArgs(packageManager, \"test\");\n const result = await command(\n invocation.executable,\n invocation.args,\n cwd,\n signal,\n );\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"test\", \"passed\");\n }\n return step(\"test\", \"failed\", [\n problem(result.stdout + result.stderr, \"Fix the failing project tests.\", {\n rule: \"test/failed\",\n }),\n ]);\n}\n","import path from \"node:path\";\nimport { command, execArgs } from \"./command\";\nimport { json } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = { dependencies?: Record<string, string> };\n\nexport async function checkTypes(options: StepOptions): Promise<CheckStep> {\n const { cwd, packageManager, signal } = options;\n signal?.throwIfAborted();\n const manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n if (manifest.dependencies?.[\"react-router\"]) {\n const generated = execArgs(packageManager, \"react-router\", [\"typegen\"]);\n const result = await command(\n generated.executable,\n generated.args,\n cwd,\n signal,\n );\n if (result.code !== 0) {\n return step(\n \"types\",\n \"failed\",\n outputProblems(result.stdout + result.stderr),\n );\n }\n }\n const typed = execArgs(packageManager, \"tsc\", [\"--noEmit\"]);\n const result = await command(typed.executable, typed.args, cwd, signal);\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"types\", \"passed\");\n }\n return step(\"types\", \"failed\", outputProblems(result.stdout + result.stderr));\n}\n\nfunction outputProblems(output: string): CheckProblem[] {\n const parsed = output.split(/\\r?\\n/).flatMap((line) => {\n const match = /^(.*)\\((\\d+),(\\d+)\\): error (TS\\d+): (.*)$/.exec(line);\n if (!match) {\n return [];\n }\n return [\n problem(match[5] ?? line, \"Fix the TypeScript error.\", {\n ...(match[4] ? { rule: match[4] } : {}),\n ...(match[1] ? { file: match[1] } : {}),\n line: Number(match[2]),\n }),\n ];\n });\n if (parsed.length > 0) {\n return parsed;\n }\n return [\n problem(\n output.trim() || \"TypeScript failed.\",\n \"Fix the TypeScript errors.\",\n ),\n ];\n}\n","import { checkAllowlist } from \"./allowlist\";\nimport { checkBudgets } from \"./budgets\";\nimport { checkBuild } from \"./build\";\nimport { checkConfig } from \"./config\";\nimport { checkLint } from \"./lint\";\nimport { problem, step } from \"./result\";\nimport { checkSecrets } from \"./secrets\";\nimport { checkTests } from \"./test-step\";\nimport type {\n CheckOptions,\n CheckResult,\n CheckStep,\n CheckStepName,\n StepOptions,\n} from \"./types\";\nimport { checkTypes } from \"./types-step\";\n\ntype Runner = (options: StepOptions) => Promise<CheckStep>;\n\nconst runners: { name: CheckStepName; run: Runner }[] = [\n { name: \"config\", run: checkConfig },\n { name: \"allowlist\", run: checkAllowlist },\n { name: \"lint\", run: checkLint },\n { name: \"types\", run: checkTypes },\n { name: \"test\", run: checkTests },\n { name: \"build\", run: checkBuild },\n { name: \"secrets\", run: checkSecrets },\n { name: \"budgets\", run: checkBudgets },\n];\n\nexport async function runCheck(options: CheckOptions): Promise<CheckResult> {\n const steps: CheckStep[] = [];\n for (const runner of runners) {\n options.signal?.throwIfAborted();\n let checked: CheckStep;\n try {\n checked = await runner.run(options);\n } catch (error) {\n options.signal?.throwIfAborted();\n checked = step(runner.name, \"failed\", [\n problem(\n message(error),\n \"Fix the step setup and run zappie check again.\",\n ),\n ]);\n }\n steps.push(checked);\n if (checked.result === \"failed\" && !options.all) {\n break;\n }\n }\n return {\n result: steps.some((entry) => entry.result === \"failed\")\n ? \"failed\"\n : \"passed\",\n steps,\n };\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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","names":["path","path","message","path","message","readFile","path","level","relative","record","path","message","readFile","path","message","path","readFile","theme","path","readFile","access","readFile","path","readFile","path","readFile","path","gzipSync","path","access","readFile","readFile","path","readFile","path","path","pathToFileURL","require","path","pathToFileURL","message","access","readFile","readdir","path","matches","total","readFile","path","collect","readdir","path","path","path","path","result","message"]}
|
|
1
|
+
{"version":3,"sources":["../../sdk/src/site-config/types.ts","../../sdk/src/site-config/helpers.ts","../../sdk/src/site-config/sections.ts","../../sdk/src/site-config/validate.ts","../src/allowlist.ts","../../tokens/src/names.ts","../../tokens/src/defaults.ts","../../tokens/src/named-colors.ts","../../tokens/src/parse.ts","../../tokens/src/contrast.ts","../../tokens/src/validate.ts","../src/config.ts","../src/files.ts","../src/result.ts","../src/budgets.ts","../src/budget-files.ts","../src/budget-manifest.ts","../src/build.ts","../src/command.ts","../src/lint.ts","../src/readiness.ts","../src/secrets.ts","../src/secret-patterns.ts","../src/test-step.ts","../src/types-step.ts","../src/run.ts"],"sourcesContent":["/**\n * Default site budgets: 200 KB gzipped JavaScript, 50 KB gzipped CSS and 2500 ms LCP.\n */\nexport const DEFAULT_BUDGETS = {\n jsKbGz: 200,\n cssKbGz: 50,\n lcpMs: 2500,\n} as const;\n\n/**\n * Package names and patterns allowed globally without a site-specific allowlist entry.\n */\nexport const GLOBAL_PACKAGE_ALLOWLIST = [\n \"react\",\n \"react-dom\",\n \"react-router\",\n \"@react-router/*\",\n \"@zappie/*\",\n \"tailwindcss\",\n \"@tailwindcss/*\",\n \"clsx\",\n \"tailwind-merge\",\n \"class-variance-authority\",\n \"lucide-react\",\n \"date-fns\",\n \"embla-carousel-react\",\n \"framer-motion/motion\",\n \"zod\",\n \"@radix-ui/*\",\n \"sonner\",\n \"vaul\",\n] as const;\n\n/**\n * The store, theme and optional build policies you export from zappie.config.ts.\n */\nexport type ZappieSiteConfig = {\n store: string;\n branches?: string[];\n theme: string;\n prerender?: string[];\n menu?: { hiddenCategories?: string[] };\n packages?: { allow?: string[] };\n outbound?: { allow?: string[] };\n /** Each budget left out uses DEFAULT_BUDGETS. */\n budgets?: {\n jsKbGz?: number;\n cssKbGz?: number;\n lcpMs?: number;\n override?: { reason: string };\n };\n /** Records explained exceptions to storefront readiness checks. */\n readiness?: {\n /** Lets this site skip the initial route discovery requirement. */\n routeDiscovery?: {\n /** Explains why this site does not use initial route discovery. */\n optOut: {\n /** States the constraint that prevents initial route discovery. */\n reason: string;\n };\n };\n };\n analytics?: { forward?: { ga4?: string; metaPixel?: string } };\n};\n\n/**\n * A configuration diagnostic with its field path, stable code, message and severity.\n */\nexport type ConfigIssue = {\n path: string;\n code:\n | \"invalid_type\"\n | \"missing_required\"\n | \"unknown_key\"\n | \"invalid_format\"\n | \"duplicate\"\n | \"redundant_allowlist\"\n | \"budget_override\";\n message: string;\n severity: \"error\" | \"warning\";\n};\n\n/**\n * Configuration validation results. Warnings alone do not make valid false.\n */\nexport type ConfigValidation = { valid: boolean; issues: ConfigIssue[] };\n","import { GLOBAL_PACKAGE_ALLOWLIST, type ConfigIssue } from \"./types\";\n\nexport const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nfunction distance(left: string, right: string) {\n let row = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {\n const next = [leftIndex];\n for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {\n next[rightIndex] = Math.min(\n (next[rightIndex - 1] ?? 0) + 1,\n (row[rightIndex] ?? 0) + 1,\n (row[rightIndex - 1] ?? 0) +\n (left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1),\n );\n }\n row = next;\n }\n return row[right.length] ?? Infinity;\n}\n\nexport function unknownKeys(\n value: Record<string, unknown>,\n allowed: readonly string[],\n path: string,\n issue: (value: ConfigIssue) => void,\n) {\n for (const key of Object.keys(value)) {\n if (allowed.includes(key)) {\n continue;\n }\n const closest = allowed\n .map((candidate) => ({ candidate, score: distance(key, candidate) }))\n .sort((left, right) => left.score - right.score)[0];\n const hint = closest && closest.score <= 2 ? closest.candidate : undefined;\n issue({\n path: path ? `${path}.${key}` : key,\n code: \"unknown_key\",\n message: hint\n ? `Unknown field \"${key}\". Rename it to \"${hint}\".`\n : `Unknown field \"${key}\". Remove it from the configuration.`,\n severity: \"error\",\n });\n }\n}\n\nexport const nonblank = (value: unknown): value is string =>\n typeof value === \"string\" && value.trim().length > 0;\n\nexport const packageName = (value: string) =>\n value.length <= 214 &&\n /^(?:@[a-z0-9][a-z0-9._~-]*\\/[a-z0-9][a-z0-9._~-]*|[a-z0-9][a-z0-9._~-]*)$/.test(\n value,\n );\n\nexport const globallyAllowed = (value: string) =>\n GLOBAL_PACKAGE_ALLOWLIST.some((allowed) =>\n allowed.endsWith(\"/*\")\n ? value.startsWith(allowed.slice(0, -1))\n : value === allowed,\n );\n\nexport function hostname(value: string) {\n const wildcard = value.startsWith(\"*.\");\n const host = wildcard ? value.slice(2) : value;\n if (\n !host.includes(\".\") ||\n /^\\d+(?:\\.\\d+){3}$/.test(host) ||\n host.length > 253 ||\n host.includes(\"..\")\n ) {\n return false;\n }\n return host\n .split(\".\")\n .every(\n (label) =>\n label.length > 0 &&\n label.length <= 63 &&\n /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label),\n );\n}\n","import { record, unknownKeys } from \"./helpers\";\nimport { DEFAULT_BUDGETS, type ConfigIssue } from \"./types\";\n\ntype AddIssue = (value: ConfigIssue) => void;\ntype AddError = (\n path: string,\n code: ConfigIssue[\"code\"],\n message: string,\n) => void;\n\nexport function nested(\n value: unknown,\n path: string,\n keys: readonly string[],\n issue: AddIssue,\n validate: (value: Record<string, unknown>) => void,\n) {\n if (value === undefined) {\n return;\n }\n if (!record(value)) {\n issue({\n path,\n code: \"invalid_type\",\n message: `Expected an object. Set ${path} to an object or remove it.`,\n severity: \"error\",\n });\n return;\n }\n unknownKeys(value, keys, path, issue);\n validate(value);\n}\n\nexport function budgets(value: unknown, issue: AddIssue, error: AddError) {\n nested(\n value,\n \"budgets\",\n [\"jsKbGz\", \"cssKbGz\", \"lcpMs\", \"override\"],\n issue,\n (budget) => {\n nested(\n budget.override,\n \"budgets.override\",\n [\"reason\"],\n issue,\n (override) => {\n if (typeof override.reason !== \"string\" || !override.reason.trim()) {\n error(\n \"budgets.override.reason\",\n \"invalid_format\",\n \"Expected a non-blank reason. Explain why the default budget must be raised.\",\n );\n }\n },\n );\n for (const key of [\"jsKbGz\", \"cssKbGz\", \"lcpMs\"] as const) {\n const amount = budget[key];\n if (amount === undefined) {\n continue;\n }\n if (\n typeof amount !== \"number\" ||\n !Number.isFinite(amount) ||\n amount <= 0\n ) {\n error(\n `budgets.${key}`,\n \"invalid_type\",\n `Expected a positive finite number. Set budgets.${key} to a number greater than zero.`,\n );\n } else if (amount > DEFAULT_BUDGETS[key]) {\n const message = `The ${key} budget exceeds the ${DEFAULT_BUDGETS[key]} default.`;\n if (budget.override === undefined) {\n error(\n `budgets.${key}`,\n \"budget_override\",\n `${message} Add budgets.override.reason to explain the increase.`,\n );\n } else {\n issue({\n path: `budgets.${key}`,\n code: \"budget_override\",\n message: `${message} Lower it to the default when the exception is no longer needed.`,\n severity: \"warning\",\n });\n }\n }\n }\n },\n );\n}\n\nexport function analytics(value: unknown, issue: AddIssue, error: AddError) {\n nested(value, \"analytics\", [\"forward\"], issue, (analyticsValue) => {\n nested(\n analyticsValue.forward,\n \"analytics.forward\",\n [\"ga4\", \"metaPixel\"],\n issue,\n (forward) => {\n if (\n forward.ga4 !== undefined &&\n (typeof forward.ga4 !== \"string\" ||\n !/^G-[A-Z0-9]+$/.test(forward.ga4))\n ) {\n error(\n \"analytics.forward.ga4\",\n \"invalid_format\",\n \"Expected a GA4 measurement id beginning with G-. Use a value such as G-XXXXXXXXXX.\",\n );\n }\n if (\n forward.metaPixel !== undefined &&\n (typeof forward.metaPixel !== \"string\" ||\n !/^\\d+$/.test(forward.metaPixel))\n ) {\n error(\n \"analytics.forward.metaPixel\",\n \"invalid_format\",\n \"Expected a numeric Meta Pixel id. Use digits only.\",\n );\n }\n },\n );\n });\n}\n","import {\n globallyAllowed,\n hostname,\n nonblank,\n packageName,\n record,\n unknownKeys,\n} from \"./helpers\";\nimport { analytics, budgets, nested } from \"./sections\";\nimport type { ConfigIssue, ConfigValidation } from \"./types\";\n\nconst rootKeys = [\n \"store\",\n \"branches\",\n \"theme\",\n \"prerender\",\n \"menu\",\n \"packages\",\n \"outbound\",\n \"budgets\",\n \"readiness\",\n \"analytics\",\n] as const;\n\n/**\n * Validate a site configuration and collect errors and warnings without changing it.\n * Checks required fields, unknown keys, allowlists, budgets and analytics settings.\n *\n * @param input - The configuration value to inspect.\n * @returns Diagnostics and a valid flag that is true when there are no errors.\n */\nexport function validateConfig(input: unknown): ConfigValidation {\n const issues: ConfigIssue[] = [];\n const issue = (value: ConfigIssue) => issues.push(value);\n const error = (path: string, code: ConfigIssue[\"code\"], message: string) =>\n issue({ path, code, message, severity: \"error\" });\n if (!record(input)) {\n return {\n valid: false,\n issues: [\n {\n path: \"$\",\n code: \"invalid_type\",\n message:\n \"Expected a configuration object. Export an object from zappie.config.ts.\",\n severity: \"error\",\n },\n ],\n };\n }\n unknownKeys(input, rootKeys, \"\", issue);\n requiredSlug(input.store, \"store\", error);\n theme(input.theme, error);\n stringList(input.branches, \"branches\", error, {\n nonempty: true,\n unique: true,\n slug: true,\n });\n paths(input.prerender, error);\n nested(input.menu, \"menu\", [\"hiddenCategories\"], issue, (value) => {\n stringList(value.hiddenCategories, \"menu.hiddenCategories\", error);\n });\n nested(input.packages, \"packages\", [\"allow\"], issue, (value) => {\n const allow = stringList(value.allow, \"packages.allow\", error);\n allow?.forEach((name, index) => {\n if (globallyAllowed(name)) {\n issue({\n path: `packages.allow[${index}]`,\n code: \"redundant_allowlist\",\n message: `${name} is already globally allowed. Remove it from packages.allow.`,\n severity: \"warning\",\n });\n } else if (!packageName(name)) {\n error(\n `packages.allow[${index}]`,\n \"invalid_format\",\n \"Expected a lowercase npm package name. Use a package name such as lucide-react or @scope/name.\",\n );\n }\n });\n });\n nested(input.outbound, \"outbound\", [\"allow\"], issue, (value) => {\n const allow = stringList(value.allow, \"outbound.allow\", error);\n allow?.forEach((host, index) => {\n if (!hostname(host)) {\n error(\n `outbound.allow[${index}]`,\n \"invalid_format\",\n \"Expected a hostname or leading *. subdomain pattern without a scheme, path, port or IP. Use a value such as api.example.com.\",\n );\n }\n });\n });\n budgets(input.budgets, issue, error);\n nested(\n input.readiness,\n \"readiness\",\n [\"routeDiscovery\"],\n issue,\n (readiness) => {\n nested(\n readiness.routeDiscovery,\n \"readiness.routeDiscovery\",\n [\"optOut\"],\n issue,\n (routeDiscovery) => {\n nested(\n routeDiscovery.optOut,\n \"readiness.routeDiscovery.optOut\",\n [\"reason\"],\n issue,\n (optOut) => {\n if (typeof optOut.reason !== \"string\" || !optOut.reason.trim()) {\n error(\n \"readiness.routeDiscovery.optOut.reason\",\n \"invalid_format\",\n \"Expected a non-blank reason. Explain why the site disables initial route discovery.\",\n );\n }\n },\n );\n },\n );\n },\n );\n analytics(input.analytics, issue, error);\n return {\n valid: !issues.some((entry) => entry.severity === \"error\"),\n issues,\n };\n}\n\ntype AddError = (\n path: string,\n code: ConfigIssue[\"code\"],\n message: string,\n) => void;\n\nfunction requiredSlug(value: unknown, path: string, error: AddError) {\n if (!nonblank(value)) {\n error(\n path,\n value === undefined ? \"missing_required\" : \"invalid_type\",\n `Expected a non-empty storefront slug. Set ${path} to the slug used by createZappie().`,\n );\n }\n}\n\nfunction theme(value: unknown, error: AddError) {\n if (typeof value !== \"string\") {\n error(\n \"theme\",\n value === undefined ? \"missing_required\" : \"invalid_type\",\n \"Expected a relative .json path. Set theme to a value such as ./theme.json.\",\n );\n } else if (\n !/\\.json$/.test(value) ||\n /^(?:[a-z][a-z\\d+.-]*:|\\/|\\\\)/i.test(value) ||\n value.includes(\"\\\\\")\n ) {\n error(\n \"theme\",\n \"invalid_format\",\n \"Expected a relative .json path. Use a value such as ./theme.json.\",\n );\n }\n}\n\nfunction stringList(\n value: unknown,\n path: string,\n error: AddError,\n options: { nonempty?: boolean; unique?: boolean; slug?: boolean } = {},\n) {\n if (value === undefined) {\n return undefined;\n }\n if (\n !Array.isArray(value) ||\n value.some((entry) => typeof entry !== \"string\")\n ) {\n error(\n path,\n \"invalid_type\",\n `Expected an array of strings. Set ${path} to string values.`,\n );\n return undefined;\n }\n if (options.nonempty && value.length === 0) {\n error(\n path,\n \"invalid_format\",\n `Expected at least one value. Add a value to ${path} or remove the field.`,\n );\n }\n value.forEach((entry, index) => {\n if (options.slug && !nonblank(entry)) {\n error(\n `${path}[${index}]`,\n \"invalid_format\",\n \"Expected a non-empty branch slug. Remove the empty value or use a branch slug.\",\n );\n }\n });\n if (options.unique && new Set(value).size !== value.length) {\n error(\n path,\n \"duplicate\",\n `Expected unique values. Remove duplicates from ${path}.`,\n );\n }\n return value;\n}\n\nfunction paths(value: unknown, error: AddError) {\n const values = stringList(value, \"prerender\", error, { unique: true });\n values?.forEach((path, index) => {\n if (!path.startsWith(\"/\")) {\n error(\n `prerender[${index}]`,\n \"invalid_format\",\n \"Expected a route starting with /. Prefix the route with /.\",\n );\n }\n });\n}\n","import { GLOBAL_PACKAGE_ALLOWLIST } from \"@zappie/sdk/config\";\nimport { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { loadConfig } from \"./config\";\nimport { json } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport type AllowlistSource = {\n load(signal?: AbortSignal): Promise<readonly string[]>;\n};\n\nexport const BUILTIN_ALLOWLIST_SOURCE: AllowlistSource = {\n load: async () => GLOBAL_PACKAGE_ALLOWLIST,\n};\n\ntype Manifest = {\n dependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n};\n\nexport async function checkAllowlist(\n { cwd, signal }: StepOptions,\n source: AllowlistSource = BUILTIN_ALLOWLIST_SOURCE,\n): Promise<CheckStep> {\n signal?.throwIfAborted();\n const problems: CheckProblem[] = [];\n let manifest: Manifest;\n try {\n manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n } catch (error) {\n return step(\"allowlist\", \"failed\", [\n problem(String(error), \"Add a valid package.json to the project root.\", {\n file: \"package.json\",\n }),\n ]);\n }\n if (!(await hasLockfile(cwd))) {\n problems.push(\n problem(\n \"No supported lockfile was found.\",\n \"Install dependencies and commit the generated lockfile.\",\n ),\n );\n }\n const global = await source.load(signal);\n const local = await localAllowlist(cwd);\n for (const name of Object.keys(manifest.dependencies ?? {})) {\n if (![...global, ...local].some((entry) => matches(entry, name))) {\n problems.push(\n problem(\n `${name} is not in the package allowlist.`,\n `Add ${name} to packages.allow in zappie.config.ts after reviewing it.`,\n { rule: \"allowlist/package\", file: \"package.json\" },\n ),\n );\n }\n await checkInstallScripts(cwd, name, problems);\n }\n signal?.throwIfAborted();\n return step(\"allowlist\", problems.length ? \"failed\" : \"passed\", problems);\n}\n\nasync function localAllowlist(cwd: string) {\n try {\n const loaded = await loadConfig(cwd);\n const value = loaded.value as { packages?: { allow?: unknown } };\n return Array.isArray(value?.packages?.allow)\n ? value.packages.allow.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n : [];\n } catch {\n return [];\n }\n}\n\nasync function hasLockfile(cwd: string) {\n for (let directory = cwd; ; directory = path.dirname(directory)) {\n for (const name of [\n \"pnpm-lock.yaml\",\n \"package-lock.json\",\n \"yarn.lock\",\n \"bun.lock\",\n \"bun.lockb\",\n ]) {\n try {\n await access(path.join(directory, name));\n return true;\n } catch {\n continue;\n }\n }\n if (path.dirname(directory) === directory) {\n return false;\n }\n }\n}\n\nasync function checkInstallScripts(\n cwd: string,\n name: string,\n problems: CheckProblem[],\n) {\n try {\n const dependency = await installedManifest(cwd, name);\n for (const script of [\"preinstall\", \"install\", \"postinstall\"]) {\n if (dependency.scripts?.[script]) {\n problems.push(\n problem(\n `${name} declares a ${script} script.`,\n `Remove ${name} or use a dependency without install scripts.`,\n { rule: \"allowlist/install-script\", file: \"package.json\" },\n ),\n );\n }\n }\n } catch {\n problems.push(\n problem(\n `${name} is not installed.`,\n \"Install dependencies from the committed lockfile.\",\n {\n rule: \"allowlist/not-installed\",\n file: \"package.json\",\n },\n ),\n );\n }\n}\n\nfunction matches(pattern: string, value: string) {\n return pattern.endsWith(\"/*\")\n ? value.startsWith(pattern.slice(0, -1))\n : pattern === value;\n}\n\n// Walk up like Node resolution, so dependencies hoisted to a workspace root are found.\nasync function installedManifest(cwd: string, name: string): Promise<Manifest> {\n for (let directory = cwd; ; directory = path.dirname(directory)) {\n const file = path.join(\n directory,\n \"node_modules\",\n ...name.split(\"/\"),\n \"package.json\",\n );\n try {\n return JSON.parse(await readFile(file, \"utf8\")) as Manifest;\n } catch (error) {\n if (path.dirname(directory) === directory) {\n throw error;\n }\n }\n }\n}\n","/** Closed semantic token vocabulary. Theme-private CSS variables stay outside this contract. */\nexport const COLOR_TOKENS = [\n \"--z-bg\",\n \"--z-surface\",\n \"--z-surface-raised\",\n \"--z-overlay\",\n \"--z-text\",\n \"--z-text-muted\",\n \"--z-text-inverse\",\n \"--z-accent\",\n \"--z-accent-contrast\",\n \"--z-brand-1\",\n \"--z-brand-2\",\n \"--z-brand-3\",\n \"--z-success\",\n \"--z-warning\",\n \"--z-danger\",\n \"--z-border\",\n \"--z-focus-ring\",\n] as const;\nexport const LENGTH_TOKENS = [\n \"--z-radius-sm\",\n \"--z-radius-md\",\n \"--z-radius-lg\",\n \"--z-radius-pill\",\n \"--z-space-1\",\n \"--z-space-2\",\n \"--z-space-3\",\n \"--z-space-4\",\n \"--z-space-5\",\n \"--z-space-6\",\n \"--z-space-7\",\n \"--z-space-8\",\n \"--z-text-xs\",\n \"--z-text-sm\",\n \"--z-text-md\",\n \"--z-text-lg\",\n \"--z-text-xl\",\n \"--z-text-2xl\",\n \"--z-text-3xl\",\n \"--z-drawer-width\",\n \"--z-dialog-width\",\n \"--z-dialog-height\",\n \"--z-media-sm\",\n] as const;\nexport const FONT_TOKENS = [\n \"--z-font-display\",\n \"--z-font-body\",\n \"--z-font-mono\",\n] as const;\nexport const DURATION_TOKENS = [\n \"--z-duration-fast\",\n \"--z-duration-base\",\n \"--z-duration-slow\",\n] as const;\nexport const EASING_TOKENS = [\"--z-ease-out\", \"--z-ease-in-out\"] as const;\nexport const MOTION_TOKENS = [...DURATION_TOKENS, ...EASING_TOKENS] as const;\nexport const TOKEN_NAMES = [\n ...COLOR_TOKENS,\n ...LENGTH_TOKENS,\n ...FONT_TOKENS,\n ...MOTION_TOKENS,\n] as const;\nexport const REQUIRED_TOKENS = [\n \"--z-bg\",\n \"--z-text\",\n \"--z-accent\",\n \"--z-accent-contrast\",\n] as const;\nexport type TokenName = (typeof TOKEN_NAMES)[number];\nexport type ColorToken = (typeof COLOR_TOKENS)[number];\nexport type TokenValues = Partial<Record<TokenName, string>>;\n","import type { TokenName } from \"./names\";\nimport type { ThemeJson } from \"./types\";\n\n/** Host palette from styles/colors.ts; public fonts use a licence-free system stack. */\nexport const DEFAULT_TOKENS: Readonly<Record<TokenName, string>> =\n Object.freeze({\n \"--z-bg\": \"#F9FAFB\",\n \"--z-surface\": \"#FFFFFF\",\n \"--z-surface-raised\": \"#FFFFFF\",\n \"--z-overlay\": \"#00000080\",\n \"--z-text\": \"#101828\",\n \"--z-text-muted\": \"#344054\",\n \"--z-text-inverse\": \"#FFFFFF\",\n \"--z-accent\": \"#9FE870\",\n \"--z-accent-contrast\": \"#163300\",\n \"--z-brand-1\": \"#9FE870\",\n \"--z-brand-2\": \"#163300\",\n \"--z-brand-3\": \"#EDC843\",\n \"--z-success\": \"#027A48\",\n \"--z-warning\": \"#ED7A37\",\n \"--z-danger\": \"#F04438\",\n \"--z-border\": \"#EAECF0\",\n \"--z-focus-ring\": \"#163300\",\n \"--z-radius-sm\": \"6px\",\n \"--z-radius-md\": \"12px\",\n \"--z-radius-lg\": \"20px\",\n \"--z-radius-pill\": \"9999px\",\n \"--z-space-1\": \"4px\",\n \"--z-space-2\": \"8px\",\n \"--z-space-3\": \"12px\",\n \"--z-space-4\": \"16px\",\n \"--z-space-5\": \"24px\",\n \"--z-space-6\": \"32px\",\n \"--z-space-7\": \"48px\",\n \"--z-space-8\": \"64px\",\n \"--z-font-display\": \"system-ui, sans-serif\",\n \"--z-font-body\": \"system-ui, sans-serif\",\n \"--z-font-mono\": \"ui-monospace, monospace\",\n \"--z-text-xs\": \"12px\",\n \"--z-text-sm\": \"14px\",\n \"--z-text-md\": \"16px\",\n \"--z-text-lg\": \"18px\",\n \"--z-text-xl\": \"20px\",\n \"--z-text-2xl\": \"24px\",\n \"--z-text-3xl\": \"32px\",\n \"--z-duration-fast\": \"120ms\",\n \"--z-duration-base\": \"200ms\",\n \"--z-duration-slow\": \"320ms\",\n \"--z-ease-out\": \"cubic-bezier(0, 0, 0.2, 1)\",\n \"--z-ease-in-out\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"--z-drawer-width\": \"420px\",\n \"--z-dialog-width\": \"min(1000px, calc(100vw - 32px))\",\n \"--z-dialog-height\": \"min(780px, 90dvh)\",\n \"--z-media-sm\": \"64px\",\n });\nexport const DEFAULT_THEME: ThemeJson = Object.freeze({\n version: 1,\n name: \"Zappie\",\n tokens: DEFAULT_TOKENS,\n darkMode: \"light\",\n dark: Object.freeze({\n \"--z-bg\": \"#000000\",\n \"--z-surface\": \"#242424\",\n \"--z-surface-raised\": \"#333333\",\n \"--z-text\": \"#FFFFFF\",\n \"--z-text-muted\": \"#BFBFBF\",\n \"--z-text-inverse\": \"#101828\",\n \"--z-border\": \"#474747\",\n \"--z-focus-ring\": \"#9FE870\",\n }),\n});\n","// CSS named colors from color-name 1.1.4 (MIT); see ../LICENSE.color-name.\nexport const NAMED_COLORS: Record<string, string> = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"00ffff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000000\",\n blanchedalmond: \"ffebcd\",\n blue: \"0000ff\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"00ffff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"ff00ff\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"778899\",\n lightslategrey: \"778899\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"00ff00\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"ff00ff\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"ff0000\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"ffffff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ffff00\",\n yellowgreen: \"9acd32\",\n};\n","import { NAMED_COLORS } from \"./named-colors\";\n\nexport type Rgba = [number, number, number, number];\nconst numberPattern = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?$/i;\nexport const safeValue = (value: string): boolean =>\n value.length <= 512 &&\n !/[;{}<>\\\\\\x00-\\x1f]|\\/\\*|url\\s*\\(|expression\\s*\\(/i.test(value);\nconst clamp = (n: number): number => Math.max(0, Math.min(1, n));\nfunction numeric(value: string, scale = 1): number {\n const percent = value.endsWith(\"%\");\n const raw = percent ? value.slice(0, -1) : value;\n const parsed = numberPattern.test(raw)\n ? Number(raw) / (percent ? 100 : scale)\n : NaN;\n return Number.isFinite(parsed) ? parsed : NaN;\n}\nfunction hue(value: string): number {\n const match = /^(.*?)(deg|rad|grad|turn)?$/.exec(value);\n if (!match || !numberPattern.test(match[1]!)) {\n return NaN;\n }\n const factors: Record<string, number> = {\n deg: 1,\n rad: 180 / Math.PI,\n grad: 0.9,\n turn: 360,\n };\n return Number(match[1]) * (factors[match[2] ?? \"deg\"] ?? 1);\n}\n/** Parse absolute CSS colors to normalized sRGB. Context-dependent colors are rejected. */\nexport function parseColor(input: string): Rgba | null {\n if (!safeValue(input)) {\n return null;\n }\n let value = input.trim().toLowerCase();\n if (value === \"transparent\") {\n return [0, 0, 0, 0];\n }\n if (Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)) {\n value = \"#\" + NAMED_COLORS[value];\n }\n if (/^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/.test(value)) {\n let hex = value.slice(1);\n if (hex.length < 5) {\n hex = [...hex].map((c) => c + c).join(\"\");\n }\n if (hex.length === 6) {\n hex += \"ff\";\n }\n return [0, 2, 4, 6].map(\n (i) => parseInt(hex.slice(i, i + 2), 16) / 255,\n ) as Rgba;\n }\n const match = /^(rgba?|hsla?|oklch)\\(([^()]*)\\)$/.exec(value);\n if (!match) {\n return null;\n }\n const kind = match[1]!;\n const body = match[2]!.trim();\n const comma = body.includes(\",\");\n if (comma && (body.includes(\"/\") || kind === \"oklch\")) {\n return null;\n }\n const parts = comma\n ? body.split(\",\").map((s) => s.trim())\n : body.split(/\\s*\\/\\s*/);\n let channels: string[], alpha: string | undefined;\n if (comma) {\n if (parts.length !== 3 && parts.length !== 4) {\n return null;\n }\n channels = parts.slice(0, 3);\n alpha = parts[3];\n } else {\n if (parts.length > 2) {\n return null;\n }\n channels = parts[0]!.split(/\\s+/);\n alpha = parts[1];\n }\n if (channels.length !== 3) {\n return null;\n }\n const opacity = alpha === undefined ? 1 : numeric(alpha);\n let rgb: number[];\n if (kind.startsWith(\"rgb\")) {\n if (\n comma &&\n channels.some((c) => c.endsWith(\"%\")) &&\n !channels.every((c) => c.endsWith(\"%\"))\n ) {\n return null;\n }\n rgb = channels.map((c) => numeric(c, 255));\n } else if (kind.startsWith(\"hsl\")) {\n if (!channels[1]!.endsWith(\"%\") || !channels[2]!.endsWith(\"%\")) {\n return null;\n }\n const h = ((hue(channels[0]!) % 360) + 360) % 360;\n const s = clamp(numeric(channels[1]!)),\n l = clamp(numeric(channels[2]!));\n const a = s * Math.min(l, 1 - l);\n rgb = [0, 8, 4].map((n) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n });\n } else {\n const l = clamp(numeric(channels[0]!));\n const c = Math.max(\n 0,\n numeric(channels[1]!) * (channels[1]!.endsWith(\"%\") ? 0.4 : 1),\n );\n const h = (hue(channels[2]!) * Math.PI) / 180;\n const a = c * Math.cos(h),\n b = c * Math.sin(h);\n const x = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const y = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const z = (l - 0.0894841775 * a - 1.291485548 * b) ** 3;\n rgb = [\n 4.0767416621 * x - 3.3077115913 * y + 0.2309699292 * z,\n -1.2684380046 * x + 2.6097574011 * y - 0.3413193965 * z,\n -0.0041960863 * x - 0.7034186147 * y + 1.707614701 * z,\n ].map((v) => (v <= 0.0031308 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055));\n }\n return [...rgb, opacity].every(Number.isFinite)\n ? ([...rgb.map(clamp), clamp(opacity)] as Rgba)\n : null;\n}\n/** Restricted, recursively parsed CSS lengths; arithmetic is allowed only inside calc(). */\nexport function isLength(value: string, depth = 0): boolean {\n if (!safeValue(value) || depth > 8) {\n return false;\n }\n const text = value.trim();\n if (/^(?:0|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:px|rem|em|%|dvh|vh|vw))$/.test(text)) {\n return true;\n }\n const fn = /^(min|max|clamp|calc)\\((.*)\\)$/.exec(text);\n if (!fn) {\n return false;\n }\n let level = 0,\n start = 0;\n const args: string[] = [];\n for (let i = 0; i < fn[2]!.length; i++) {\n const c = fn[2]![i];\n if (c === \"(\") {\n level++;\n }\n if (c === \")\" && --level < 0) {\n return false;\n }\n const separator =\n fn[1] === \"calc\"\n ? (c === \"+\" || c === \"-\") &&\n /\\s/.test(fn[2]![i - 1] ?? \"\") &&\n /\\s/.test(fn[2]![i + 1] ?? \"\")\n : c === \",\";\n if (level === 0 && separator) {\n args.push(fn[2]!.slice(start, i));\n start = i + 1;\n }\n }\n args.push(fn[2]!.slice(start));\n return (\n level === 0 &&\n (fn[1] !== \"clamp\" || args.length === 3) &&\n args.every((arg) => isLength(arg, depth + 1))\n );\n}\n/** CSS-wide keywords are not family names and invalidate a font-family list. */\nconst cssWideKeyword = /^(?:inherit|initial|unset|revert|revert-layer|default)$/i;\nexport function isFontFamily(value: string): boolean {\n return (\n safeValue(value) &&\n value.split(\",\").every((part) => {\n const family = part.trim();\n return (\n /^[a-zA-Z][a-zA-Z0-9 -]*$/.test(family) && !cssWideKeyword.test(family)\n );\n })\n );\n}\nexport function isDuration(value: string): boolean {\n return /^(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:ms|s)$/.test(value);\n}\nexport function isEasing(value: string): boolean {\n if (\n /^(linear|ease|ease-in|ease-out|ease-in-out|step-start|step-end)$/.test(\n value,\n )\n ) {\n return true;\n }\n const m = /^cubic-bezier\\((.*)\\)$/.exec(value);\n if (!m) {\n return false;\n }\n const ns = m[1]!\n .split(\",\")\n .map((s) => (numberPattern.test(s.trim()) ? numeric(s.trim()) : NaN));\n return (\n ns.length === 4 &&\n ns.every(Number.isFinite) &&\n ns[0]! >= 0 &&\n ns[0]! <= 1 &&\n ns[2]! >= 0 &&\n ns[2]! <= 1\n );\n}\nexport function isAssetUrl(value: string, relative = true): boolean {\n if (!value || !safeValue(value) || /[\\s\"'()]/.test(value)) {\n return false;\n }\n if (relative && !/^[a-z][\\w+.-]*:/i.test(value) && !value.startsWith(\"//\")) {\n return true;\n }\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" && !url.username && !url.password;\n } catch {\n return false;\n }\n}\n","import { parseColor } from \"./parse\";\n\n/** WCAG contrast for absolute colors. A translucent background needs an explicit backdrop. */\nexport function contrastRatio(fg: string, bg: string): number {\n const foreground = parseColor(fg),\n background = parseColor(bg);\n if (!foreground || !background || background[3] !== 1) {\n return NaN;\n }\n const luminance = (channels: number[]) =>\n channels\n .map((c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4))\n .reduce((sum, c, i) => sum + c * [0.2126, 0.7152, 0.0722][i]!, 0);\n const a = luminance(\n foreground\n .slice(0, 3)\n .map((c, i) => c * foreground[3] + background[i]! * (1 - foreground[3])),\n );\n const b = luminance(background.slice(0, 3));\n return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);\n}\n","import {\n COLOR_TOKENS,\n LENGTH_TOKENS,\n FONT_TOKENS,\n DURATION_TOKENS,\n TOKEN_NAMES,\n REQUIRED_TOKENS,\n} from \"./names\";\nimport type { TokenName, TokenValues } from \"./names\";\nimport { DEFAULT_TOKENS } from \"./defaults\";\nimport { contrastRatio } from \"./contrast\";\nimport {\n parseColor,\n isLength,\n isFontFamily,\n isDuration,\n isEasing,\n isAssetUrl,\n safeValue,\n} from \"./parse\";\nimport type { ThemeIssue, ThemeJson, ThemeValidation } from \"./types\";\n\nconst record = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst includes = (values: readonly string[], key: string) =>\n values.includes(key);\n/** Validate untrusted theme JSON, including syntax, CSS injection and effective light/dark contrast. */\nexport function validateTheme(input: unknown): ThemeValidation {\n const issues: ThemeIssue[] = [];\n const issue = (\n path: string,\n code: ThemeIssue[\"code\"],\n message: string,\n severity: ThemeIssue[\"severity\"] = \"error\",\n ) => issues.push({ path, code, message, severity });\n const keys = (\n obj: Record<string, unknown>,\n allowed: string[],\n path: string,\n ) => {\n for (const key of Object.keys(obj)) {\n if (!allowed.includes(key)) {\n issue(path ? `${path}.${key}` : key, \"invalid_theme\", \"Unknown field\");\n }\n }\n };\n if (!record(input)) {\n return {\n ok: false,\n issues: [\n {\n path: \"\",\n code: \"invalid_theme\",\n message: \"Expected a theme object\",\n severity: \"error\",\n },\n ],\n };\n }\n keys(\n input,\n [\n \"$schema\",\n \"version\",\n \"name\",\n \"tokens\",\n \"dark\",\n \"darkMode\",\n \"fonts\",\n \"logo\",\n \"motion\",\n ],\n \"\",\n );\n if (input.version !== 1) {\n issue(\"version\", \"invalid_theme\", \"Expected version 1\");\n }\n if (\n typeof input.name !== \"string\" ||\n !input.name.trim() ||\n input.name.length > 100\n ) {\n issue(\"name\", \"missing_required\", \"Expected a name of 1–100 characters\");\n }\n if (\n input.$schema !== undefined &&\n (typeof input.$schema !== \"string\" || !isAssetUrl(input.$schema, false))\n ) {\n issue(\"$schema\", \"invalid_theme\", \"Expected an HTTPS schema URL\");\n }\n if (\n input.darkMode !== undefined &&\n (typeof input.darkMode !== \"string\" ||\n ![\"auto\", \"light\", \"dark\"].includes(input.darkMode))\n ) {\n issue(\"darkMode\", \"invalid_theme\", \"Expected auto, light or dark\");\n }\n for (const group of [\"tokens\", \"dark\"] as const) {\n const values = input[group];\n if (group === \"dark\" && values === undefined) {\n continue;\n }\n if (!record(values)) {\n issue(group, \"missing_required\", \"Expected a token object\");\n continue;\n }\n if (group === \"tokens\") {\n for (const key of REQUIRED_TOKENS) {\n if (!Object.prototype.hasOwnProperty.call(values, key)) {\n issue(`${group}.${key}`, \"missing_required\", \"Required token\");\n }\n }\n }\n for (const [key, value] of Object.entries(values)) {\n const path = `${group}.${key}`;\n if (!includes(TOKEN_NAMES, key)) {\n issue(path, \"unknown_token\", \"Unknown semantic token\");\n continue;\n }\n let code: ThemeIssue[\"code\"],\n valid = false;\n if (includes(COLOR_TOKENS, key)) {\n code = \"invalid_color\";\n valid = typeof value === \"string\" && parseColor(value) !== null;\n } else if (includes(LENGTH_TOKENS, key)) {\n code = \"invalid_length\";\n valid = typeof value === \"string\" && isLength(value);\n } else if (includes(FONT_TOKENS, key)) {\n code = \"invalid_font\";\n valid = typeof value === \"string\" && isFontFamily(value);\n } else {\n code = \"invalid_motion\";\n valid =\n typeof value === \"string\" &&\n safeValue(value) &&\n (includes(DURATION_TOKENS, key)\n ? isDuration(value)\n : isEasing(value));\n }\n if (!valid) {\n issue(path, code, \"Invalid or unsafe token value\");\n }\n }\n }\n if (input.fonts !== undefined) {\n if (!Array.isArray(input.fonts) || input.fonts.length > 3) {\n issue(\"fonts\", \"invalid_font\", \"Expected at most three fonts\");\n } else {\n const roles = new Set<string>();\n input.fonts.forEach((font: unknown, i: number) => {\n const path = `fonts[${i}]`;\n if (!record(font)) {\n issue(path, \"invalid_font\", \"Expected a font object\");\n return;\n }\n keys(font, [\"family\", \"source\", \"url\", \"weights\", \"role\"], path);\n if (\n typeof font.family !== \"string\" ||\n !isFontFamily(font.family) ||\n font.family.includes(\",\")\n ) {\n issue(\n `${path}.family`,\n \"invalid_font\",\n \"Expected one unquoted font family\",\n );\n }\n if (\n typeof font.source !== \"string\" ||\n ![\"google\", \"self\", \"system\"].includes(font.source)\n ) {\n issue(`${path}.source`, \"invalid_font\", \"Unknown font source\");\n }\n if (\n typeof font.role !== \"string\" ||\n ![\"display\", \"body\", \"mono\"].includes(font.role) ||\n roles.has(font.role)\n ) {\n issue(`${path}.role`, \"invalid_font\", \"Expected a unique font role\");\n }\n roles.add(String(font.role));\n if (font.source === \"self\" || font.url !== undefined) {\n if (\n typeof font.url !== \"string\" ||\n !isAssetUrl(font.url, false) ||\n !new URL(font.url).pathname.endsWith(\".woff2\")\n ) {\n issue(\n `${path}.url`,\n \"invalid_font\",\n \"Expected an HTTPS .woff2 URL\",\n );\n }\n }\n if (\n font.weights !== undefined &&\n (!Array.isArray(font.weights) ||\n !font.weights.length ||\n font.weights.length > 9 ||\n font.weights.some(\n (w) =>\n typeof w !== \"number\" ||\n !Number.isInteger(w) ||\n w < 1 ||\n w > 1000,\n ))\n ) {\n issue(\n `${path}.weights`,\n \"invalid_font\",\n \"Expected 1–9 integer weights between 1 and 1000\",\n );\n }\n });\n }\n }\n if (input.logo !== undefined) {\n if (!record(input.logo)) {\n issue(\"logo\", \"invalid_logo\", \"Expected a logo object\");\n } else {\n keys(input.logo, [\"light\", \"dark\", \"mark\", \"alt\"], \"logo\");\n if (typeof input.logo.alt !== \"string\" || !input.logo.alt.trim()) {\n issue(\"logo.alt\", \"invalid_logo\", \"Logo alternative text is required\");\n }\n for (const key of [\"light\", \"dark\", \"mark\"]) {\n const value = input.logo[key];\n if (key === \"light\" || value !== undefined) {\n if (typeof value !== \"string\" || !isAssetUrl(value)) {\n issue(\n `logo.${key}`,\n \"invalid_logo\",\n \"Expected HTTPS or a relative asset path\",\n );\n }\n }\n }\n }\n }\n if (input.motion !== undefined) {\n if (!record(input.motion)) {\n issue(\"motion\", \"invalid_motion\", \"Expected a motion object\");\n } else {\n keys(input.motion, [\"reduce\"], \"motion\");\n if (\n input.motion.reduce !== undefined &&\n typeof input.motion.reduce !== \"boolean\"\n ) {\n issue(\"motion.reduce\", \"invalid_motion\", \"Expected a boolean\");\n }\n }\n }\n const tokenGroup = (value: unknown): TokenValues =>\n record(value) ? (value as TokenValues) : {};\n for (const group of record(input.dark) ? [\"tokens\", \"dark\"] : [\"tokens\"]) {\n const values: Record<string, unknown> = {\n ...DEFAULT_TOKENS,\n ...tokenGroup(input.tokens),\n ...(group === \"dark\" ? tokenGroup(input.dark) : {}),\n };\n const pairs: [TokenName, TokenName, number, ThemeIssue[\"severity\"]][] = [\n [\"--z-text\", \"--z-bg\", 4.5, \"error\"],\n [\"--z-text\", \"--z-surface\", 4.5, \"error\"],\n [\"--z-accent-contrast\", \"--z-accent\", 4.5, \"error\"],\n [\"--z-text-muted\", \"--z-bg\", 3, \"warning\"],\n ];\n for (const [fg, bg, minimum, severity] of pairs) {\n const foreground = values[fg],\n background = values[bg];\n // An unparseable colour has already been reported as invalid_color.\n if (\n typeof foreground !== \"string\" ||\n typeof background !== \"string\" ||\n !parseColor(foreground) ||\n !parseColor(background)\n ) {\n continue;\n }\n const ratio = contrastRatio(foreground, background);\n if (!Number.isFinite(ratio)) {\n issue(\n `${group}.${bg}`,\n \"unverified_contrast\",\n \"A contrast background must be opaque\",\n \"error\",\n );\n } else if (ratio < minimum) {\n issue(\n `${group}.${fg}`,\n \"low_contrast\",\n `Contrast against ${bg} must be at least ${minimum}:1`,\n severity,\n );\n }\n }\n }\n return issues.some((i) => i.severity === \"error\")\n ? { ok: false, issues }\n : { ok: true, theme: input as ThemeJson, warnings: issues };\n}\n","import { validateConfig, type ConfigIssue } from \"@zappie/sdk/config\";\nimport { validateTheme, type ThemeIssue } from \"@zappie/tokens/validate\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { lineFor } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport type LoadedConfig = {\n value: unknown;\n source: string;\n file: string;\n};\n\nexport function supportsTypeScriptImport(version = process.versions.node) {\n const [major = 0, minor = 0] = version.split(\".\").map(Number);\n return major > 22 || (major === 22 && minor >= 18);\n}\n\nexport async function loadConfig(cwd: string): Promise<LoadedConfig> {\n const file = path.join(cwd, \"zappie.config.ts\");\n if (!supportsTypeScriptImport()) {\n throw new Error(\n \"zappie check needs Node 22.18 or later to read zappie.config.ts\",\n );\n }\n const source = await readFile(file, \"utf8\");\n const version = (await stat(file)).mtimeMs;\n const loaded = (await import(\n `${pathToFileURL(file).href}?check=${version}`\n )) as {\n default?: unknown;\n };\n return { value: loaded.default, source, file };\n}\n\nexport async function checkConfig({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n let loaded: LoadedConfig;\n try {\n loaded = await loadConfig(cwd);\n } catch (error) {\n return step(\"config\", \"failed\", [\n problem(\n message(error),\n \"Create a readable zappie.config.ts in the project root.\",\n {\n file: \"zappie.config.ts\",\n },\n ),\n ]);\n }\n const validation = validateConfig(loaded.value);\n const problems = validation.issues.map((issue) =>\n configProblem(issue, loaded.source),\n );\n let themeFailed = false;\n const theme = configTheme(loaded.value);\n if (theme) {\n const checkedTheme = await themeProblems(cwd, theme);\n problems.push(...checkedTheme.problems);\n themeFailed = checkedTheme.failed;\n }\n signal?.throwIfAborted();\n return step(\n \"config\",\n validation.issues.some((issue) => issue.severity === \"error\") || themeFailed\n ? \"failed\"\n : \"passed\",\n problems,\n );\n}\n\nfunction configProblem(issue: ConfigIssue, source: string): CheckProblem {\n const line = lineFor(source, issue.path);\n return problem(`${issue.path}: ${issue.message}`, issue.message, {\n rule: `config/${issue.code}`,\n file: \"zappie.config.ts\",\n ...(line ? { line } : {}),\n });\n}\n\nasync function themeProblems(cwd: string, theme: string) {\n const file = path.resolve(cwd, theme);\n try {\n const source = await readFile(file, \"utf8\");\n const result = validateTheme(JSON.parse(source) as unknown);\n const issues = result.ok ? result.warnings : result.issues;\n return {\n failed: issues.some((issue) => issue.severity === \"error\"),\n problems: issues.map((issue) => themeProblem(issue, source, theme)),\n };\n } catch (error) {\n return {\n failed: true,\n problems: [\n problem(message(error), `Make ${theme} a readable JSON theme file.`, {\n rule: \"theme/unreadable\",\n file: theme,\n }),\n ],\n };\n }\n}\n\nfunction themeProblem(issue: ThemeIssue, source: string, file: string) {\n const line = lineFor(source, issue.path);\n return problem(`${issue.path}: ${issue.message}`, issue.message, {\n rule: `theme/${issue.code}`,\n file,\n ...(line ? { line } : {}),\n });\n}\n\nfunction configTheme(value: unknown) {\n return value &&\n typeof value === \"object\" &&\n \"theme\" in value &&\n typeof value.theme === \"string\"\n ? value.theme\n : undefined;\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport async function json<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport function relative(cwd: string, file: string) {\n return path.relative(cwd, file).split(path.sep).join(\"/\");\n}\n\nexport function lineFor(source: string, issuePath: string) {\n const key = issuePath\n .split(\".\")\n .at(-1)\n ?.replace(/\\[\\d+\\]$/, \"\");\n if (!key || key === \"$\") {\n return undefined;\n }\n const quoted = JSON.stringify(key);\n const lines = source.split(/\\r?\\n/);\n const index = lines.findIndex(\n (line) =>\n line.includes(quoted) || new RegExp(`\\\\b${escape(key)}\\\\b`).test(line),\n );\n return index < 0 ? undefined : index + 1;\n}\n\nfunction escape(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import type {\n CheckProblem,\n CheckResultValue,\n CheckStep,\n CheckStepName,\n} from \"./types\";\n\nexport function problem(\n message: string,\n fix: string | null,\n details: Partial<Omit<CheckProblem, \"message\" | \"fix\">> = {},\n): CheckProblem {\n return { ...details, message, fix };\n}\n\nexport function step(\n name: CheckStepName,\n result: CheckResultValue,\n problems: CheckProblem[] = [],\n): CheckStep {\n return { name, result, problems };\n}\n\nexport const skipped = (name: CheckStepName, message: string) =>\n step(name, \"skipped\", [problem(message, null)]);\n","import { DEFAULT_BUDGETS, type ZappieSiteConfig } from \"@zappie/sdk/config\";\nimport { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { cssSizes } from \"./budget-files\";\nimport {\n clientKeys,\n graphSizes,\n routeKeys,\n type AssetSize,\n type ManifestEntry,\n} from \"./budget-manifest\";\nimport { loadConfig } from \"./config\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nconst KIB = 1024;\n\nexport async function checkBudgets({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const manifestFile = path.join(cwd, \"build/client/.vite/manifest.json\");\n try {\n await access(manifestFile);\n } catch {\n return skipped(\n \"budgets\",\n \"No build/client/.vite/manifest.json is available.\",\n );\n }\n const manifest = JSON.parse(await readFile(manifestFile, \"utf8\")) as Record<\n string,\n ManifestEntry\n >;\n const config = (await loadConfig(cwd)).value as ZappieSiteConfig;\n const limits = { ...DEFAULT_BUDGETS, ...config.budgets };\n const routes = routeKeys(manifest);\n const clients = clientKeys(manifest);\n if (routes.length === 0 || clients.length === 0) {\n throw new Error(\n \"The Vite manifest needs a client entry and app/routes entries.\",\n );\n }\n const problems: CheckProblem[] = [];\n let failed = false;\n for (const route of routes) {\n const sizes = await graphSizes(cwd, manifest, [...clients, route]);\n const over = total(sizes) > limits.jsKbGz * KIB;\n failed ||= over;\n problems.push(routeProblem(route, sizes, limits.jsKbGz, over));\n }\n const styles = await cssSizes(cwd);\n const cssOver = total(styles) > limits.cssKbGz * KIB;\n failed ||= cssOver;\n problems.push(cssProblem(styles, limits.cssKbGz, cssOver));\n problems.push(\n problem(\n `LCP is not measured by zappie check; zappie verify enforces the ${limits.lcpMs} ms budget.`,\n null,\n { rule: \"budgets/lcp\" },\n ),\n );\n signal?.throwIfAborted();\n return step(\"budgets\", failed ? \"failed\" : \"passed\", problems);\n}\n\nfunction routeProblem(\n route: string,\n sizes: AssetSize[],\n limitKb: number,\n over: boolean,\n) {\n const bytes = total(sizes);\n const largest = [...sizes]\n .sort((left, right) => right.bytes - left.bytes)\n .slice(0, 3)\n .map(({ file, bytes: size }) => `${file} (${size} B)`)\n .join(\", \");\n return problem(\n `${route}: ${bytes} B gzip (limit ${limitKb * KIB} B).${over ? ` Largest chunks: ${largest}.` : \"\"}`,\n over\n ? \"Reduce the route's client JavaScript or raise the reviewed budget override.\"\n : null,\n {\n rule: over ? \"budgets/js-over\" : \"budgets/js-route\",\n file: \"build/client/.vite/manifest.json\",\n },\n );\n}\n\nfunction cssProblem(sizes: AssetSize[], limitKb: number, over: boolean) {\n const bytes = total(sizes);\n return problem(\n `Client CSS: ${bytes} B gzip (limit ${limitKb * KIB} B).`,\n over ? \"Reduce client CSS or raise the reviewed budget override.\" : null,\n { rule: over ? \"budgets/css-over\" : \"budgets/css\" },\n );\n}\n\nconst total = (sizes: AssetSize[]) =>\n sizes.reduce((sum, asset) => sum + asset.bytes, 0);\n","import { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport type { AssetSize } from \"./budget-manifest\";\n\nexport async function cssSizes(cwd: string) {\n const root = path.join(cwd, \"build/client\");\n const files: string[] = [];\n await collect(root, files);\n return Promise.all(\n files\n .filter((file) => file.endsWith(\".css\"))\n .map(async (file): Promise<AssetSize> => ({\n file: path.relative(root, file).split(path.sep).join(\"/\"),\n bytes: gzipSync(await readFile(file, \"utf8\")).byteLength,\n })),\n );\n}\n\nasync function collect(directory: string, files: string[]) {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n if (entry.isSymbolicLink()) {\n continue;\n }\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n await collect(file, files);\n } else if (entry.isFile()) {\n files.push(file);\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\n\nexport type ManifestEntry = {\n file: string;\n src?: string;\n isEntry?: boolean;\n imports?: string[];\n};\n\nexport type AssetSize = { file: string; bytes: number };\n\nexport function routeKeys(manifest: Record<string, ManifestEntry>) {\n return Object.entries(manifest)\n .filter(([key, entry]) => routeSource(entry.src ?? key))\n .map(([key]) => key)\n .sort();\n}\n\nexport function clientKeys(manifest: Record<string, ManifestEntry>) {\n return Object.entries(manifest)\n .filter(([key, entry]) => entry.isEntry && !routeSource(entry.src ?? key))\n .map(([key]) => key)\n .sort();\n}\n\nexport async function graphSizes(\n cwd: string,\n manifest: Record<string, ManifestEntry>,\n roots: string[],\n) {\n const keys = closure(manifest, roots);\n return Promise.all(\n [...keys]\n .map((key) => manifest[key])\n .filter((entry): entry is ManifestEntry => Boolean(entry))\n .filter(({ file }) => file.endsWith(\".js\"))\n .map(async ({ file }) => ({\n file,\n bytes: gzipSync(\n await readFile(path.join(cwd, \"build/client\", file), \"utf8\"),\n ).byteLength,\n })),\n );\n}\n\nfunction closure(manifest: Record<string, ManifestEntry>, roots: string[]) {\n const visited = new Set<string>();\n const visit = (key: string) => {\n if (visited.has(key)) {\n return;\n }\n const entry = manifest[key];\n if (!entry) {\n throw new Error(`Manifest import ${key} has no entry.`);\n }\n visited.add(key);\n for (const dependency of entry.imports ?? []) {\n visit(dependency);\n }\n };\n roots.forEach(visit);\n return visited;\n}\n\nfunction routeSource(value: string) {\n return value.replace(/^\\/?/, \"\").startsWith(\"app/routes/\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { command, execArgs, scriptArgs } from \"./command\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n};\n\nexport async function checkBuild({\n cwd,\n packageManager,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const manifest = JSON.parse(\n await readFile(path.join(cwd, \"package.json\"), \"utf8\"),\n ) as Manifest;\n const invocation = manifest.dependencies?.[\"react-router\"]\n ? execArgs(packageManager, \"react-router\", [\"build\"])\n : manifest.scripts?.build\n ? scriptArgs(packageManager, \"build\")\n : undefined;\n if (!invocation) {\n return skipped(\n \"build\",\n \"No react-router dependency or build script is defined in package.json.\",\n );\n }\n const result = await command(\n invocation.executable,\n invocation.args,\n cwd,\n signal,\n );\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"build\", \"passed\");\n }\n return step(\"build\", \"failed\", [\n problem(\n `The project build failed.\\n${usefulTail(result.stdout, result.stderr)}`,\n \"Fix the reported build errors and run zappie check again.\",\n { rule: \"build/failed\" },\n ),\n ]);\n}\n\nfunction usefulTail(stdout: string, stderr: string) {\n const lines = `${stdout}\\n${stderr}`\n .split(/\\r?\\n/)\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .slice(-12);\n return lines.length > 0\n ? lines.join(\"\\n\")\n : \"The build exited without output.\";\n}\n","import { spawn } from \"node:child_process\";\nimport type { PackageManager } from \"./types\";\n\nexport type CommandResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport function command(\n executable: string,\n args: string[],\n cwd: string,\n signal?: AbortSignal,\n): Promise<CommandResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(executable, args, {\n cwd,\n env: { ...process.env, NO_COLOR: \"1\", FORCE_COLOR: \"0\" },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n ...(signal ? { signal } : {}),\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (value) => {\n stdout += String(value);\n });\n child.stderr.on(\"data\", (value) => {\n stderr += String(value);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport function execArgs(\n manager: PackageManager,\n binary: string,\n args: string[],\n) {\n // Never download a missing binary: the check runs the project's own tools.\n if (manager === \"npm\") {\n return { executable: \"npm\", args: [\"exec\", \"--no\", \"--\", binary, ...args] };\n }\n if (manager === \"yarn\") {\n return { executable: \"yarn\", args: [\"exec\", binary, ...args] };\n }\n if (manager === \"bun\") {\n return { executable: \"bun\", args: [\"x\", \"--no-install\", binary, ...args] };\n }\n return { executable: \"pnpm\", args: [\"exec\", binary, ...args] };\n}\n\nexport function scriptArgs(manager: PackageManager, name: string) {\n if (manager === \"bun\") {\n return { executable: \"bun\", args: [\"run\", name] };\n }\n if (manager === \"npm\") {\n return { executable: \"npm\", args: [\"run\", name] };\n }\n return { executable: manager, args: [name] };\n}\n","import zappie from \"eslint-plugin-zappie\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { relative } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype LintMessage = {\n ruleId: string | null;\n line?: number;\n message: string;\n severity: number;\n fatal?: boolean;\n};\ntype LintResult = { filePath: string; messages: LintMessage[] };\ntype EslintInstance = {\n calculateConfigForFile(\n file: string,\n ): Promise<{ rules?: Record<string, unknown> } | undefined>;\n lintFiles(patterns: string[]): Promise<LintResult[]>;\n};\ntype EslintConstructor = new (options: { cwd: string }) => EslintInstance;\n\nexport async function checkLint({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n let ESLint: EslintConstructor;\n try {\n const require = createRequire(path.join(cwd, \"package.json\"));\n const loadedEslint = (await import(\n pathToFileURL(require.resolve(\"eslint\")).href\n )) as {\n ESLint: EslintConstructor;\n };\n ESLint = loadedEslint.ESLint;\n } catch (error) {\n return step(\"lint\", \"failed\", [\n problem(message(error), \"Install ESLint in the project.\", {\n rule: \"lint/unavailable\",\n }),\n ]);\n }\n try {\n const eslint = new ESLint({ cwd });\n const source = await sourceFile(cwd);\n const config = await eslint.calculateConfigForFile(source);\n const problems = recommendedProblems(config?.rules ?? {});\n if (problems.length > 0) {\n return step(\"lint\", \"failed\", problems);\n }\n const results = await eslint.lintFiles([\".\"]);\n signal?.throwIfAborted();\n const lintProblems = results.flatMap((result) =>\n result.messages.map((entry) =>\n problem(entry.message, null, {\n ...(entry.ruleId ? { rule: entry.ruleId } : {}),\n file: relative(cwd, result.filePath),\n ...(entry.line ? { line: entry.line } : {}),\n }),\n ),\n );\n const failed = results.some((result) =>\n result.messages.some((entry) => entry.fatal || entry.severity === 2),\n );\n return step(\"lint\", failed ? \"failed\" : \"passed\", lintProblems);\n } catch (error) {\n return step(\"lint\", \"failed\", [\n problem(\n message(error),\n \"Fix the project ESLint configuration and run lint again.\",\n {\n rule: \"lint/config\",\n },\n ),\n ]);\n }\n}\n\nfunction recommendedProblems(applied: Record<string, unknown>) {\n const expected = recommendedRules();\n return Object.entries(expected).flatMap(([rule, severity]) => {\n if (level(applied[rule]) >= level(severity)) {\n return [];\n }\n return [\n problem(\n `${rule} is not enabled at the recommended severity.`,\n \"Apply every entry from zappie.configs.recommended in eslint.config.mjs.\",\n { rule, file: \"eslint.config.mjs\" },\n ),\n ];\n });\n}\n\nfunction recommendedRules() {\n const result: Record<string, unknown> = {};\n for (const config of zappie.configs.recommended ?? []) {\n Object.assign(result, config.rules ?? {});\n }\n return Object.fromEntries(\n Object.entries(result).filter(([name]) => name.startsWith(\"zappie/\")),\n );\n}\n\nfunction level(value: unknown): number {\n const selected = Array.isArray(value) ? value[0] : value;\n if (selected === \"error\" || selected === 2) {\n return 2;\n }\n if (selected === \"warn\" || selected === 1) {\n return 1;\n }\n return 0;\n}\n\nasync function sourceFile(cwd: string) {\n const candidates = [\n \"app/index.ts\",\n \"app/root.tsx\",\n \"src/index.ts\",\n \"index.ts\",\n ];\n for (const candidate of candidates) {\n try {\n await import(\"node:fs/promises\").then(({ access }) =>\n access(path.join(cwd, candidate)),\n );\n return candidate;\n } catch {\n continue;\n }\n }\n return \"eslint.config.mjs\";\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { ZappieSiteConfig } from \"@zappie/sdk/config\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { loadConfig } from \"./config\";\nimport { problem, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype RouteConfig = {\n routeDiscovery?: { mode?: unknown };\n};\n\nexport async function checkReadiness({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const site = (await loadConfig(cwd)).value as ZappieSiteConfig;\n const optOut = site.readiness?.routeDiscovery?.optOut;\n if (optOut) {\n return step(\"readiness\", \"passed\", [\n problem(\n \"Initial route discovery is disabled by an explained exception\",\n `Remove readiness.routeDiscovery.optOut after you enable initial route discovery. Reason: ${optOut.reason}`,\n { rule: \"readiness/route-discovery-opt-out\", file: \"zappie.config.ts\" },\n ),\n ]);\n }\n\n const file = path.join(cwd, \"react-router.config.ts\");\n try {\n await readFile(file, \"utf8\");\n const version = Date.now();\n const config = (await import(\n `${pathToFileURL(file).href}?readiness=${version}`\n )) as { default?: RouteConfig };\n if (config.default?.routeDiscovery?.mode === \"initial\") {\n return step(\"readiness\", \"passed\");\n }\n } catch (error) {\n return step(\"readiness\", \"failed\", [\n problem(\n message(error),\n 'Create react-router.config.ts and set routeDiscovery: { mode: \"initial\" }.',\n {\n rule: \"readiness/route-discovery\",\n file: \"react-router.config.ts\",\n },\n ),\n ]);\n }\n return step(\"readiness\", \"failed\", [\n problem(\n \"Initial route discovery is not enabled\",\n 'Set routeDiscovery: { mode: \"initial\" } in react-router.config.ts so item routes are ready before a shopper taps.',\n { rule: \"readiness/route-discovery\", file: \"react-router.config.ts\" },\n ),\n ]);\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n","import { lstat, readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { relative } from \"./files\";\nimport { step } from \"./result\";\nimport { secretMatches } from \"./secret-patterns\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\nexport const SECRET_FILE_SIZE_CAP = 1024 * 1024;\nexport type SecretFinding = CheckProblem & {\n severity: \"error\" | \"warning\";\n};\n\nexport async function scanSecrets(dir: string): Promise<SecretFinding[]> {\n const findings: SecretFinding[] = [];\n for (const file of await filesToScan(dir)) {\n const info = await lstat(file);\n if (!info.isFile() || info.size > SECRET_FILE_SIZE_CAP) {\n continue;\n }\n const contents = await readFile(file);\n if (contents.includes(0)) {\n continue;\n }\n const source = contents.toString(\"utf8\");\n for (const match of secretMatches(\n source,\n path.basename(file).startsWith(\".env\"),\n )) {\n findings.push({\n rule: match.rule,\n file: relative(dir, file),\n line: lineAt(source, match.index),\n message: match.message,\n fix: match.fix,\n severity: match.severity,\n });\n }\n }\n return findings;\n}\n\nexport async function checkSecrets({\n cwd,\n signal,\n}: StepOptions): Promise<CheckStep> {\n signal?.throwIfAborted();\n const findings = await scanSecrets(cwd);\n signal?.throwIfAborted();\n const failed = findings.some(({ severity }) => severity === \"error\");\n return step(\n \"secrets\",\n failed ? \"failed\" : \"passed\",\n findings.map(({ severity: _severity, ...finding }) => finding),\n );\n}\n\nasync function filesToScan(cwd: string) {\n const files: string[] = [];\n for (const directory of [\"app\", \"public\"]) {\n await collect(path.join(cwd, directory), files);\n }\n await collect(path.join(cwd, \"build/client\"), files, (file) =>\n file.endsWith(\".js\"),\n );\n try {\n for (const entry of await readdir(cwd, { withFileTypes: true })) {\n if (entry.isFile() && rootConfig(entry.name)) {\n files.push(path.join(cwd, entry.name));\n }\n }\n } catch {\n return files.sort();\n }\n return [...new Set(files)].sort();\n}\n\nasync function collect(\n directory: string,\n files: string[],\n accept: (file: string) => boolean = () => true,\n) {\n try {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n if (entry.isSymbolicLink()) {\n continue;\n }\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n await collect(file, files, accept);\n } else if (entry.isFile() && accept(file)) {\n files.push(file);\n }\n }\n } catch (error) {\n if (!(\n error instanceof Error &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n )) {\n throw error;\n }\n }\n}\n\nfunction rootConfig(name: string) {\n return (\n name === \"package.json\" ||\n name === \"wrangler.json\" ||\n name === \"wrangler.jsonc\" ||\n /(?:^|\\.)config\\.(?:[cm]?[jt]s|json)$/.test(name)\n );\n}\n\nfunction lineAt(source: string, index: number) {\n return source.slice(0, index).split(/\\r?\\n/).length;\n}\n","export type SecretMatch = {\n index: number;\n rule: string;\n message: string;\n fix: string;\n severity: \"error\" | \"warning\";\n};\n\nconst FIX = \"Move the value to a server environment variable and rotate it.\";\n\nexport function secretMatches(source: string, envFile: boolean) {\n const matches: SecretMatch[] = [];\n add(matches, source, /sk_(test|live)_[A-Za-z0-9]{16,}/g, (value) => {\n const live = value.startsWith(\"sk_live_\");\n return {\n rule: live ? \"secrets/sk-live\" : \"secrets/sk-test\",\n message: `Detected ${live ? \"sk_live_\" : \"sk_test_\"}… secret.`,\n fix: FIX,\n severity: \"error\",\n };\n });\n if (!envFile) {\n add(matches, source, /pk_live_[A-Za-z0-9]{16,}/g, () => ({\n rule: \"secrets/pk-live\",\n message: \"Warning: detected pk_live_… outside an .env file.\",\n fix: \"Move the publishable key to a server-provided environment variable.\",\n severity: \"warning\",\n }));\n }\n add(matches, source, /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----/g, () => ({\n rule: \"secrets/private-key\",\n message: \"Detected a PEM private key header.\",\n fix: FIX,\n severity: \"error\",\n }));\n add(matches, source, /AKIA[0-9A-Z]{16}/g, () => ({\n rule: \"secrets/aws-access-key\",\n message: \"Detected an AKIA… access key.\",\n fix: FIX,\n severity: \"error\",\n }));\n add(matches, source, /FLWSECK-[A-Za-z0-9_-]{8,}/g, () => ({\n rule: \"secrets/flutterwave-live\",\n message: \"Detected an FLWSECK-… secret.\",\n fix: FIX,\n severity: \"error\",\n }));\n const occupied = matches.map(({ index }) => index);\n const assignment =\n /\\b([A-Za-z_$][\\w$]*(?:secret|token|password|api[_-]?key)[\\w$]*)\\s*[:=]\\s*([\"'])([^\"'\\r\\n]{24,})\\2/gi;\n for (const found of source.matchAll(assignment)) {\n const value = found[3] ?? \"\";\n const valueIndex = (found.index ?? 0) + found[0].indexOf(value);\n if (\n entropy(value) > 4 &&\n !occupied.some(\n (index) => index >= valueIndex && index < valueIndex + value.length,\n )\n ) {\n matches.push({\n index: valueIndex,\n rule: \"secrets/high-entropy\",\n message: `Detected a high-entropy value assigned to ${found[1] ?? \"a secret-shaped name\"}.`,\n fix: FIX,\n severity: \"error\",\n });\n }\n }\n return matches.sort((left, right) => left.index - right.index);\n}\n\nfunction add(\n output: SecretMatch[],\n source: string,\n pattern: RegExp,\n details: (value: string) => Omit<SecretMatch, \"index\">,\n) {\n for (const match of source.matchAll(pattern)) {\n output.push({ index: match.index ?? 0, ...details(match[0]) });\n }\n}\n\nfunction entropy(value: string) {\n const counts = new Map<string, number>();\n for (const character of value) {\n counts.set(character, (counts.get(character) ?? 0) + 1);\n }\n return [...counts.values()].reduce((total, count) => {\n const probability = count / value.length;\n return total - probability * Math.log2(probability);\n }, 0);\n}\n","import path from \"node:path\";\nimport { command, scriptArgs } from \"./command\";\nimport { json } from \"./files\";\nimport { problem, skipped, step } from \"./result\";\nimport type { CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = { scripts?: Record<string, string> };\n\nexport async function checkTests({\n cwd,\n packageManager,\n signal,\n}: StepOptions): Promise<CheckStep> {\n const manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n if (!manifest.scripts?.test) {\n return skipped(\"test\", \"No test script is defined in package.json.\");\n }\n const invocation = scriptArgs(packageManager, \"test\");\n const result = await command(\n invocation.executable,\n invocation.args,\n cwd,\n signal,\n );\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"test\", \"passed\");\n }\n return step(\"test\", \"failed\", [\n problem(result.stdout + result.stderr, \"Fix the failing project tests.\", {\n rule: \"test/failed\",\n }),\n ]);\n}\n","import path from \"node:path\";\nimport { command, execArgs } from \"./command\";\nimport { json } from \"./files\";\nimport { problem, step } from \"./result\";\nimport type { CheckProblem, CheckStep, StepOptions } from \"./types\";\n\ntype Manifest = { dependencies?: Record<string, string> };\n\nexport async function checkTypes(options: StepOptions): Promise<CheckStep> {\n const { cwd, packageManager, signal } = options;\n signal?.throwIfAborted();\n const manifest = await json<Manifest>(path.join(cwd, \"package.json\"));\n if (manifest.dependencies?.[\"react-router\"]) {\n const generated = execArgs(packageManager, \"react-router\", [\"typegen\"]);\n const result = await command(\n generated.executable,\n generated.args,\n cwd,\n signal,\n );\n if (result.code !== 0) {\n return step(\n \"types\",\n \"failed\",\n outputProblems(result.stdout + result.stderr),\n );\n }\n }\n const typed = execArgs(packageManager, \"tsc\", [\"--noEmit\"]);\n const result = await command(typed.executable, typed.args, cwd, signal);\n signal?.throwIfAborted();\n if (result.code === 0) {\n return step(\"types\", \"passed\");\n }\n return step(\"types\", \"failed\", outputProblems(result.stdout + result.stderr));\n}\n\nfunction outputProblems(output: string): CheckProblem[] {\n const parsed = output.split(/\\r?\\n/).flatMap((line) => {\n const match = /^(.*)\\((\\d+),(\\d+)\\): error (TS\\d+): (.*)$/.exec(line);\n if (!match) {\n return [];\n }\n return [\n problem(match[5] ?? line, \"Fix the TypeScript error.\", {\n ...(match[4] ? { rule: match[4] } : {}),\n ...(match[1] ? { file: match[1] } : {}),\n line: Number(match[2]),\n }),\n ];\n });\n if (parsed.length > 0) {\n return parsed;\n }\n return [\n problem(\n output.trim() || \"TypeScript failed.\",\n \"Fix the TypeScript errors.\",\n ),\n ];\n}\n","import { checkAllowlist } from \"./allowlist\";\nimport { checkBudgets } from \"./budgets\";\nimport { checkBuild } from \"./build\";\nimport { checkConfig } from \"./config\";\nimport { checkLint } from \"./lint\";\nimport { checkReadiness } from \"./readiness\";\nimport { problem, step } from \"./result\";\nimport { checkSecrets } from \"./secrets\";\nimport { checkTests } from \"./test-step\";\nimport type {\n CheckOptions,\n CheckResult,\n CheckStep,\n CheckStepName,\n StepOptions,\n} from \"./types\";\nimport { checkTypes } from \"./types-step\";\n\ntype Runner = (options: StepOptions) => Promise<CheckStep>;\n\nconst runners: { name: CheckStepName; run: Runner }[] = [\n { name: \"config\", run: checkConfig },\n { name: \"allowlist\", run: checkAllowlist },\n { name: \"lint\", run: checkLint },\n { name: \"types\", run: checkTypes },\n { name: \"test\", run: checkTests },\n { name: \"build\", run: checkBuild },\n { name: \"secrets\", run: checkSecrets },\n { name: \"readiness\", run: checkReadiness },\n { name: \"budgets\", run: checkBudgets },\n];\n\nexport async function runCheck(options: CheckOptions): Promise<CheckResult> {\n const steps: CheckStep[] = [];\n for (const runner of runners) {\n options.signal?.throwIfAborted();\n let checked: CheckStep;\n try {\n checked = await runner.run(options);\n } catch (error) {\n options.signal?.throwIfAborted();\n checked = step(runner.name, \"failed\", [\n problem(\n message(error),\n \"Fix the step setup and run zappie check again.\",\n ),\n ]);\n }\n steps.push(checked);\n if (checked.result === \"failed\" && !options.all) {\n break;\n }\n }\n return {\n result: steps.some((entry) => entry.result === \"failed\")\n ? \"failed\"\n : \"passed\",\n steps,\n };\n}\n\nfunction message(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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","names":["path","path","message","path","message","readFile","path","level","relative","record","path","message","readFile","path","message","path","readFile","theme","path","readFile","access","readFile","path","readFile","path","readFile","path","gzipSync","path","access","readFile","readFile","path","readFile","path","path","pathToFileURL","require","path","pathToFileURL","message","access","readFile","path","pathToFileURL","path","readFile","pathToFileURL","message","readFile","readdir","path","matches","total","readFile","path","collect","readdir","path","path","path","path","result","message"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zappie/check",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Project checks for Zappie storefronts.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"./schema/check-result.v1.json": "./schema/check-result.v1.json"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@zappie/sdk": "^0.1.
|
|
27
|
+
"@zappie/sdk": "^0.1.6",
|
|
28
28
|
"@zappie/tokens": "^0.1.1",
|
|
29
|
-
"eslint-plugin-zappie": "^0.1.
|
|
29
|
+
"eslint-plugin-zappie": "^0.1.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"ajv": "^8.18.0"
|