@bridge-ds/visual 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +43 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -75,6 +75,47 @@ function visualImpactProblems(raw) {
|
|
|
75
75
|
return out;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// ../core/src/products.ts
|
|
79
|
+
var DEFAULT_PRODUCTS = [
|
|
80
|
+
{ key: "admin", name: "Admin demo", path: "apps/admin", framework: "react" },
|
|
81
|
+
{ key: "library", name: "Library", default: true }
|
|
82
|
+
];
|
|
83
|
+
var KEY = /^[a-z0-9][a-z0-9-]*$/;
|
|
84
|
+
var REPO = /^[\w.-]+\/[\w.-]+$/;
|
|
85
|
+
var FIELDS = ["key", "name", "repo", "path", "preview", "framework", "default"];
|
|
86
|
+
function productProblems(raw) {
|
|
87
|
+
if (raw === void 0) return [];
|
|
88
|
+
if (!Array.isArray(raw)) return ['"products" must be a list of { "key", "name" } objects'];
|
|
89
|
+
if (!raw.length) return ['"products" must list at least one product, or be left out to use the defaults'];
|
|
90
|
+
const problems = [];
|
|
91
|
+
const seen = /* @__PURE__ */ new Set();
|
|
92
|
+
let defaults = 0;
|
|
93
|
+
raw.forEach((p, i) => {
|
|
94
|
+
const at = `"products[${i}]`;
|
|
95
|
+
if (!p || typeof p !== "object" || Array.isArray(p)) {
|
|
96
|
+
problems.push(`${at}" must be an object with a "key" and a "name"`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const o = p;
|
|
100
|
+
for (const k of Object.keys(o)) if (!FIELDS.includes(k)) problems.push(`${at}.${k}" is not a known field (${FIELDS.join(", ")})`);
|
|
101
|
+
if (typeof o.key !== "string" || !KEY.test(o.key)) problems.push(`${at}.key" must be lowercase letters, digits and dashes, such as "admin"`);
|
|
102
|
+
else if (seen.has(o.key)) problems.push(`${at}.key" ("${o.key}") is used twice: give each product its own key`);
|
|
103
|
+
else seen.add(o.key);
|
|
104
|
+
if (typeof o.name !== "string" || !o.name.trim()) problems.push(`${at}.name" must be the name people read, such as "Admin demo"`);
|
|
105
|
+
if (o.repo !== void 0 && (typeof o.repo !== "string" || !REPO.test(o.repo))) problems.push(`${at}.repo" must be "owner/name"`);
|
|
106
|
+
if (o.path !== void 0) {
|
|
107
|
+
const bad = typeof o.path !== "string" || !o.path.trim() || o.path.startsWith("/") || o.path.split("/").includes("..");
|
|
108
|
+
if (bad) problems.push(`${at}.path" must be a folder relative to the repository root, without a leading "/" or "..", such as "apps/admin"`);
|
|
109
|
+
}
|
|
110
|
+
if (o.preview !== void 0 && (typeof o.preview !== "string" || !/^https?:\/\//.test(o.preview))) problems.push(`${at}.preview" must be an http(s) URL template, such as "https://app-git-{branch}.vercel.app"`);
|
|
111
|
+
if (o.framework !== void 0 && (typeof o.framework !== "string" || !o.framework.trim())) problems.push(`${at}.framework" must be a name such as "react", "vue" or "other"`);
|
|
112
|
+
if (o.default !== void 0 && typeof o.default !== "boolean") problems.push(`${at}.default" must be true or false`);
|
|
113
|
+
if (o.default === true) defaults++;
|
|
114
|
+
});
|
|
115
|
+
if (defaults > 1) problems.push('"products" marks more than one product as default: keep "default": true on the library only');
|
|
116
|
+
return problems;
|
|
117
|
+
}
|
|
118
|
+
|
|
78
119
|
// ../core/src/config.ts
|
|
79
120
|
var CONFIG_FILE = "bridge.config.json";
|
|
80
121
|
var DEFAULT_OVERRIDE = { allowed: [], requireReason: true, minReasonLength: 20 };
|
|
@@ -215,6 +256,7 @@ function defineConfig(input) {
|
|
|
215
256
|
} : {},
|
|
216
257
|
...g.rights ? { rights: normalizeRights(g.rights) } : {}
|
|
217
258
|
},
|
|
259
|
+
products: input.products?.length ? input.products.map((p) => ({ ...p })) : DEFAULT_PRODUCTS.map((p) => ({ ...p })),
|
|
218
260
|
...input.audit ? { audit: { ...input.audit } } : {},
|
|
219
261
|
...input.visualImpact ? { visualImpact: { mode: input.visualImpact.mode === "on-demand" ? "on-demand" : "auto" } } : {},
|
|
220
262
|
...input.integrations ? { integrations: { ...input.integrations } } : {},
|
|
@@ -337,6 +379,7 @@ function loadConfig(source) {
|
|
|
337
379
|
}
|
|
338
380
|
}
|
|
339
381
|
problems.push(...visualImpactProblems(d.visualImpact));
|
|
382
|
+
problems.push(...productProblems(d.products));
|
|
340
383
|
const audit = d.audit;
|
|
341
384
|
if (audit !== void 0) {
|
|
342
385
|
if (!isObj(audit)) problems.push('"audit" must be an object');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bridge-ds/visual",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bridge visual impact analysis: screenshots the stories and app screens a design system change touches, at the base and head refs, and pixel-diffs them into before/after/diff images and a JSON manifest.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"build:package": "node ../../scripts/build-packages.mjs visual"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@bridge-ds/core": "^0.
|
|
50
|
+
"@bridge-ds/core": "^0.7.0",
|
|
51
51
|
"pixelmatch": "7.1.0",
|
|
52
52
|
"playwright-core": "1.63.0",
|
|
53
53
|
"pngjs": "7.0.0"
|