@fragments-sdk/cli 0.7.1 → 0.7.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/LICENSE +77 -14
- package/dist/bin.js +22 -18
- package/dist/bin.js.map +1 -1
- package/dist/chunk-D34Q6A7S.js +266 -0
- package/dist/chunk-D34Q6A7S.js.map +1 -0
- package/dist/chunk-EKLMXTWU.js +80 -0
- package/dist/chunk-EKLMXTWU.js.map +1 -0
- package/dist/{chunk-GHYYFAQN.js → chunk-P33AKQJW.js} +1 -76
- package/dist/chunk-P33AKQJW.js.map +1 -0
- package/dist/{chunk-U6VTHBNI.js → chunk-QPY4DUFB.js} +177 -46
- package/dist/chunk-QPY4DUFB.js.map +1 -0
- package/dist/{chunk-32VIEOQY.js → chunk-R2YH7NLN.js} +9 -7
- package/dist/{chunk-32VIEOQY.js.map → chunk-R2YH7NLN.js.map} +1 -1
- package/dist/{chunk-5ITIP3ES.js → chunk-R6IZZSE7.js} +44 -278
- package/dist/chunk-R6IZZSE7.js.map +1 -0
- package/dist/{chunk-DQHWLAUV.js → chunk-TOIE7VXF.js} +2 -2
- package/dist/{chunk-GCZMFLDI.js → chunk-UXLGIGSX.js} +60 -3
- package/dist/chunk-UXLGIGSX.js.map +1 -0
- package/dist/{chunk-GKX2HPZ6.js → chunk-YMPGYEWK.js} +9 -3
- package/dist/chunk-YMPGYEWK.js.map +1 -0
- package/dist/chunk-Z7EY4VHE.js +50 -0
- package/dist/{core-SFHPYR5H.js → core-3NMNCLFW.js} +8 -5
- package/dist/discovery-AKGA6CJD.js +28 -0
- package/dist/{generate-54GJAWUY.js → generate-JAUEHKK7.js} +7 -4
- package/dist/{generate-54GJAWUY.js.map → generate-JAUEHKK7.js.map} +1 -1
- package/dist/index.js +15 -11
- package/dist/index.js.map +1 -1
- package/dist/{init-EIM5WNMP.js → init-DZQOT54X.js} +6 -4
- package/dist/{init-EIM5WNMP.js.map → init-DZQOT54X.js.map} +1 -1
- package/dist/mcp-bin.js +5 -3
- package/dist/mcp-bin.js.map +1 -1
- package/dist/sass.node-4XJK6YBF.js +130708 -0
- package/dist/sass.node-4XJK6YBF.js.map +1 -0
- package/dist/scan-OJRCVKK2.js +15 -0
- package/dist/{service-ED2LNCTU.js → service-CFFBHW4X.js} +6 -4
- package/dist/service-CFFBHW4X.js.map +1 -0
- package/dist/{static-viewer-Q4F4QP5M.js → static-viewer-VA2JXSCX.js} +6 -4
- package/dist/static-viewer-VA2JXSCX.js.map +1 -0
- package/dist/{test-6VN2DA3S.js → test-O7DZNKDC.js} +8 -4
- package/dist/{test-6VN2DA3S.js.map → test-O7DZNKDC.js.map} +1 -1
- package/dist/{tokens-P2B7ZAM3.js → tokens-N7THFD6J.js} +10 -7
- package/dist/{tokens-P2B7ZAM3.js.map → tokens-N7THFD6J.js.map} +1 -1
- package/dist/{viewer-GM7IQPPB.js → viewer-QTR7QJMM.js} +390 -25
- package/dist/viewer-QTR7QJMM.js.map +1 -0
- package/package.json +13 -2
- package/src/build.ts +60 -6
- package/src/commands/graph.ts +2 -2
- package/src/core/__tests__/token-resolver.test.ts +82 -0
- package/src/core/loader.ts +0 -3
- package/src/core/parser.ts +41 -1
- package/src/core/token-parser.ts +111 -1
- package/src/core/token-resolver.ts +155 -0
- package/src/service/__tests__/patch-generator.test.ts +2 -2
- package/src/service/patch-generator.ts +8 -1
- package/src/viewer/render-utils.ts +141 -0
- package/src/viewer/vite-plugin.ts +381 -23
- package/dist/chunk-5ITIP3ES.js.map +0 -1
- package/dist/chunk-GCZMFLDI.js.map +0 -1
- package/dist/chunk-GHYYFAQN.js.map +0 -1
- package/dist/chunk-GKX2HPZ6.js.map +0 -1
- package/dist/chunk-U6VTHBNI.js.map +0 -1
- package/dist/scan-KQBKUS64.js +0 -12
- package/dist/viewer-GM7IQPPB.js.map +0 -1
- /package/dist/{chunk-DQHWLAUV.js.map → chunk-TOIE7VXF.js.map} +0 -0
- /package/dist/{core-SFHPYR5H.js.map → chunk-Z7EY4VHE.js.map} +0 -0
- /package/dist/{scan-KQBKUS64.js.map → core-3NMNCLFW.js.map} +0 -0
- /package/dist/{service-ED2LNCTU.js.map → discovery-AKGA6CJD.js.map} +0 -0
- /package/dist/{static-viewer-Q4F4QP5M.js.map → scan-OJRCVKK2.js.map} +0 -0
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
generateContextMd,
|
|
4
|
+
generateRegistry,
|
|
5
|
+
loadFragmentFile,
|
|
6
|
+
parseFragmentFile
|
|
7
|
+
} from "./chunk-R6IZZSE7.js";
|
|
8
|
+
import {
|
|
9
|
+
discoverBlockFiles,
|
|
10
|
+
discoverComponentFiles,
|
|
11
|
+
discoverFragmentFiles,
|
|
12
|
+
discoverTokenFiles,
|
|
13
|
+
extractComponentName
|
|
14
|
+
} from "./chunk-D34Q6A7S.js";
|
|
2
15
|
import {
|
|
3
16
|
BrowserPool,
|
|
4
17
|
CaptureEngine,
|
|
@@ -8,27 +21,18 @@ import {
|
|
|
8
21
|
formatMs,
|
|
9
22
|
generateHtmlReport,
|
|
10
23
|
getGrade
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import {
|
|
13
|
-
discoverBlockFiles,
|
|
14
|
-
discoverComponentFiles,
|
|
15
|
-
discoverFragmentFiles,
|
|
16
|
-
discoverTokenFiles,
|
|
17
|
-
extractComponentName,
|
|
18
|
-
generateContextMd,
|
|
19
|
-
generateRegistry,
|
|
20
|
-
loadFragmentFile,
|
|
21
|
-
parseFragmentFile
|
|
22
|
-
} from "./chunk-5ITIP3ES.js";
|
|
24
|
+
} from "./chunk-YMPGYEWK.js";
|
|
23
25
|
import {
|
|
24
26
|
compileBlock,
|
|
25
27
|
parseTokenFile
|
|
26
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-UXLGIGSX.js";
|
|
27
29
|
import {
|
|
28
|
-
BRAND,
|
|
29
|
-
DEFAULTS,
|
|
30
30
|
fragmentDefinitionSchema
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-P33AKQJW.js";
|
|
32
|
+
import {
|
|
33
|
+
BRAND,
|
|
34
|
+
DEFAULTS
|
|
35
|
+
} from "./chunk-EKLMXTWU.js";
|
|
32
36
|
|
|
33
37
|
// src/validators.ts
|
|
34
38
|
async function validateSchema(config, configDir) {
|
|
@@ -120,18 +124,110 @@ async function validateAll(config, configDir) {
|
|
|
120
124
|
|
|
121
125
|
// src/build.ts
|
|
122
126
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
123
|
-
import { resolve as
|
|
124
|
-
import { existsSync as
|
|
127
|
+
import { resolve as resolve4, join as join3 } from "path";
|
|
128
|
+
import { existsSync as existsSync4 } from "fs";
|
|
129
|
+
|
|
130
|
+
// src/core/token-resolver.ts
|
|
131
|
+
import { resolve, dirname, basename } from "path";
|
|
132
|
+
import { existsSync, readdirSync } from "fs";
|
|
133
|
+
function roundRgbValues(value) {
|
|
134
|
+
return value.replace(
|
|
135
|
+
/rgb\(([^)]+)\)/g,
|
|
136
|
+
(_full, inner) => {
|
|
137
|
+
const parts = inner.split(",").map((p) => p.trim());
|
|
138
|
+
const rounded = parts.map((p) => {
|
|
139
|
+
const num = parseFloat(p);
|
|
140
|
+
return isNaN(num) ? p : String(Math.round(num));
|
|
141
|
+
});
|
|
142
|
+
return `rgb(${rounded.join(", ")})`;
|
|
143
|
+
}
|
|
144
|
+
).replace(
|
|
145
|
+
/rgba\(([^)]+)\)/g,
|
|
146
|
+
(_full, inner) => {
|
|
147
|
+
const parts = inner.split(",").map((p) => p.trim());
|
|
148
|
+
const rounded = parts.map((p, i) => {
|
|
149
|
+
if (i >= 3) return p;
|
|
150
|
+
const num = parseFloat(p);
|
|
151
|
+
return isNaN(num) ? p : String(Math.round(num));
|
|
152
|
+
});
|
|
153
|
+
return `rgba(${rounded.join(", ")})`;
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
async function resolveTokensWithSass(unresolvedTokens, tokensDir) {
|
|
158
|
+
const resolvedMap = /* @__PURE__ */ new Map();
|
|
159
|
+
const needsResolution = unresolvedTokens.filter(
|
|
160
|
+
(t) => t.value.includes("#{") || t.value.includes("$")
|
|
161
|
+
);
|
|
162
|
+
if (needsResolution.length === 0) {
|
|
163
|
+
return resolvedMap;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const sass = await import("./sass.node-4XJK6YBF.js");
|
|
167
|
+
const variablesPath = findVariablesFile(tokensDir);
|
|
168
|
+
if (!variablesPath) {
|
|
169
|
+
return resolvedMap;
|
|
170
|
+
}
|
|
171
|
+
const fileName = basename(variablesPath);
|
|
172
|
+
const moduleName = fileName.replace(/^_/, "").replace(/\.scss$/, "");
|
|
173
|
+
const scssSource = `
|
|
174
|
+
@use '${moduleName}' as vars;
|
|
175
|
+
:root { @include vars.fui-css-variables; }
|
|
176
|
+
`;
|
|
177
|
+
const compiled = sass.compileString(scssSource, {
|
|
178
|
+
loadPaths: [tokensDir, dirname(tokensDir)],
|
|
179
|
+
style: "expanded",
|
|
180
|
+
// Suppress sass deprecation warnings during build
|
|
181
|
+
logger: { warn() {
|
|
182
|
+
}, debug() {
|
|
183
|
+
} }
|
|
184
|
+
});
|
|
185
|
+
const cssVarRegex = /(--[\w-]+)\s*:\s*([^;]+)/g;
|
|
186
|
+
let match;
|
|
187
|
+
const allResolved = /* @__PURE__ */ new Map();
|
|
188
|
+
while ((match = cssVarRegex.exec(compiled.css)) !== null) {
|
|
189
|
+
allResolved.set(match[1], roundRgbValues(match[2].trim()));
|
|
190
|
+
}
|
|
191
|
+
for (const token of needsResolution) {
|
|
192
|
+
const value = allResolved.get(token.name);
|
|
193
|
+
if (value !== void 0) {
|
|
194
|
+
resolvedMap.set(token.name, value);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
return resolvedMap;
|
|
200
|
+
}
|
|
201
|
+
function findVariablesFile(tokensDir) {
|
|
202
|
+
const candidates = ["_variables.scss", "variables.scss"];
|
|
203
|
+
for (const name of candidates) {
|
|
204
|
+
const path = resolve(tokensDir, name);
|
|
205
|
+
if (existsSync(path)) {
|
|
206
|
+
return path;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const files = readdirSync(tokensDir).filter((f) => f.endsWith(".scss"));
|
|
211
|
+
for (const file of files) {
|
|
212
|
+
const path = resolve(tokensDir, file);
|
|
213
|
+
if (file.includes("variables") || file.includes("tokens")) {
|
|
214
|
+
return path;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
125
221
|
|
|
126
222
|
// src/core/auto-props.ts
|
|
127
|
-
import { existsSync, statSync } from "fs";
|
|
128
|
-
import { dirname, extname, join, resolve } from "path";
|
|
223
|
+
import { existsSync as existsSync2, statSync } from "fs";
|
|
224
|
+
import { dirname as dirname2, extname, join, resolve as resolve2 } from "path";
|
|
129
225
|
import ts from "typescript";
|
|
130
226
|
function toPosixPath(filePath) {
|
|
131
227
|
return filePath.replace(/\\/g, "/");
|
|
132
228
|
}
|
|
133
229
|
function isFile(filePath) {
|
|
134
|
-
if (!
|
|
230
|
+
if (!existsSync2(filePath)) return false;
|
|
135
231
|
try {
|
|
136
232
|
return statSync(filePath).isFile();
|
|
137
233
|
} catch {
|
|
@@ -157,7 +253,7 @@ function resolveModulePath(basePath) {
|
|
|
157
253
|
}
|
|
158
254
|
for (const candidate of candidates) {
|
|
159
255
|
if (isFile(candidate)) {
|
|
160
|
-
return
|
|
256
|
+
return resolve2(candidate);
|
|
161
257
|
}
|
|
162
258
|
}
|
|
163
259
|
return null;
|
|
@@ -165,8 +261,8 @@ function resolveModulePath(basePath) {
|
|
|
165
261
|
function resolveComponentSourcePath(fragmentFileAbsolutePath, componentImportPath) {
|
|
166
262
|
if (!componentImportPath) return null;
|
|
167
263
|
if (!componentImportPath.startsWith(".")) return null;
|
|
168
|
-
const fragmentDir =
|
|
169
|
-
const basePath =
|
|
264
|
+
const fragmentDir = dirname2(fragmentFileAbsolutePath);
|
|
265
|
+
const basePath = resolve2(fragmentDir, componentImportPath);
|
|
170
266
|
return resolveModulePath(basePath);
|
|
171
267
|
}
|
|
172
268
|
function collectTopLevelDeclarations(sourceFile) {
|
|
@@ -354,8 +450,8 @@ function resolveComponentSignature(exportName, declarations, sourceFile) {
|
|
|
354
450
|
}
|
|
355
451
|
function extractCustomPropsFromComponentFile(componentFilePath, exportName) {
|
|
356
452
|
const warnings = [];
|
|
357
|
-
const resolvedPath =
|
|
358
|
-
if (!
|
|
453
|
+
const resolvedPath = resolve2(componentFilePath);
|
|
454
|
+
if (!existsSync2(resolvedPath)) {
|
|
359
455
|
return {
|
|
360
456
|
props: {},
|
|
361
457
|
warnings: [`Component file not found: ${resolvedPath}`],
|
|
@@ -431,9 +527,9 @@ function extractCustomPropsFromComponentFile(componentFilePath, exportName) {
|
|
|
431
527
|
|
|
432
528
|
// src/core/graph-extractor.ts
|
|
433
529
|
import ts2 from "typescript";
|
|
434
|
-
import { readFileSync, existsSync as
|
|
530
|
+
import { readFileSync, existsSync as existsSync3 } from "fs";
|
|
435
531
|
import { join as join2 } from "path";
|
|
436
|
-
import { readdirSync } from "fs";
|
|
532
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
437
533
|
import { EDGE_TYPE_WEIGHTS, computeHealthFromData } from "@fragments-sdk/context/graph";
|
|
438
534
|
async function buildComponentGraph(fragments, blocks, componentDir, options) {
|
|
439
535
|
const knownComponents = new Set(Object.keys(fragments));
|
|
@@ -790,12 +886,12 @@ function findComponentIndex(componentDir, componentName) {
|
|
|
790
886
|
join2(componentDir, componentName, `${componentName}.ts`)
|
|
791
887
|
];
|
|
792
888
|
for (const candidate of candidates) {
|
|
793
|
-
if (
|
|
889
|
+
if (existsSync3(candidate)) {
|
|
794
890
|
return candidate;
|
|
795
891
|
}
|
|
796
892
|
}
|
|
797
893
|
try {
|
|
798
|
-
const entries =
|
|
894
|
+
const entries = readdirSync2(componentDir, { withFileTypes: true });
|
|
799
895
|
for (const entry of entries) {
|
|
800
896
|
if (entry.isDirectory() && entry.name === componentName) {
|
|
801
897
|
const subCandidates = [
|
|
@@ -803,7 +899,7 @@ function findComponentIndex(componentDir, componentName) {
|
|
|
803
899
|
join2(componentDir, entry.name, "index.ts")
|
|
804
900
|
];
|
|
805
901
|
for (const sc of subCandidates) {
|
|
806
|
-
if (
|
|
902
|
+
if (existsSync3(sc)) return sc;
|
|
807
903
|
}
|
|
808
904
|
}
|
|
809
905
|
}
|
|
@@ -945,7 +1041,9 @@ async function buildFragments(config, configDir) {
|
|
|
945
1041
|
...v.args && { args: v.args }
|
|
946
1042
|
})),
|
|
947
1043
|
// Include AI metadata if present
|
|
948
|
-
...parsed.ai && { ai: parsed.ai }
|
|
1044
|
+
...parsed.ai && { ai: parsed.ai },
|
|
1045
|
+
// Include contract metadata if present
|
|
1046
|
+
...parsed.contract && { contract: parsed.contract }
|
|
949
1047
|
};
|
|
950
1048
|
fragments[parsed.meta.name] = compiled;
|
|
951
1049
|
} catch (error) {
|
|
@@ -986,38 +1084,71 @@ async function buildFragments(config, configDir) {
|
|
|
986
1084
|
const mergedCategories = {};
|
|
987
1085
|
let prefix = "--";
|
|
988
1086
|
let total = 0;
|
|
1087
|
+
const fileContents = [];
|
|
989
1088
|
for (const file of tokenFiles) {
|
|
990
1089
|
const content = await readFile(file.absolutePath, "utf-8");
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1090
|
+
fileContents.push({ content, path: file.relativePath });
|
|
1091
|
+
}
|
|
1092
|
+
const allContent = fileContents.map((f) => f.content).join("\n");
|
|
1093
|
+
for (const { content, path } of fileContents) {
|
|
1094
|
+
const parsed = parseTokenFile(allContent, path);
|
|
1095
|
+
const fileParsed = parseTokenFile(content, path);
|
|
1096
|
+
prefix = fileParsed.prefix;
|
|
1097
|
+
total += fileParsed.total;
|
|
1098
|
+
for (const [cat, catTokens] of Object.entries(fileParsed.categories)) {
|
|
995
1099
|
if (!mergedCategories[cat]) {
|
|
996
1100
|
mergedCategories[cat] = [];
|
|
997
1101
|
}
|
|
998
1102
|
for (const t of catTokens) {
|
|
999
1103
|
if (!mergedCategories[cat].some((e) => e.name === t.name)) {
|
|
1000
|
-
|
|
1104
|
+
const combinedToken = Object.values(parsed.categories).flat().find((ct) => ct.name === t.name);
|
|
1105
|
+
const resolvedValue = combinedToken?.resolvedValue ?? t.resolvedValue;
|
|
1106
|
+
mergedCategories[cat].push({
|
|
1107
|
+
name: t.name,
|
|
1108
|
+
...resolvedValue ? { value: resolvedValue } : t.value ? { value: t.value } : {},
|
|
1109
|
+
description: t.description
|
|
1110
|
+
});
|
|
1001
1111
|
}
|
|
1002
1112
|
}
|
|
1003
1113
|
}
|
|
1004
1114
|
}
|
|
1005
1115
|
if (total > 0) {
|
|
1116
|
+
const allTokens = Object.values(mergedCategories).flat();
|
|
1117
|
+
const unresolved = allTokens.filter(
|
|
1118
|
+
(t) => t.value && (t.value.includes("#{") || t.value.includes("$"))
|
|
1119
|
+
);
|
|
1120
|
+
if (unresolved.length > 0 && tokenFiles.length > 0) {
|
|
1121
|
+
const tokensDir = resolve4(configDir, tokenFiles[0].relativePath, "..");
|
|
1122
|
+
const sassResolved = await resolveTokensWithSass(
|
|
1123
|
+
unresolved,
|
|
1124
|
+
tokensDir
|
|
1125
|
+
);
|
|
1126
|
+
if (sassResolved.size > 0) {
|
|
1127
|
+
for (const catTokens of Object.values(mergedCategories)) {
|
|
1128
|
+
for (const token of catTokens) {
|
|
1129
|
+
const resolved = sassResolved.get(token.name);
|
|
1130
|
+
if (resolved && token.value && (token.value.includes("#{") || token.value.includes("$"))) {
|
|
1131
|
+
token.value = resolved;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1006
1137
|
tokens = { prefix, total, categories: mergedCategories };
|
|
1007
1138
|
}
|
|
1008
1139
|
}
|
|
1009
1140
|
} catch {
|
|
1010
1141
|
}
|
|
1011
1142
|
let packageName;
|
|
1012
|
-
const pkgJsonPath =
|
|
1013
|
-
if (
|
|
1143
|
+
const pkgJsonPath = resolve4(configDir, "package.json");
|
|
1144
|
+
if (existsSync4(pkgJsonPath)) {
|
|
1014
1145
|
try {
|
|
1015
1146
|
const pkg = JSON.parse(await readFile(pkgJsonPath, "utf-8"));
|
|
1016
1147
|
if (pkg.name) packageName = pkg.name;
|
|
1017
1148
|
} catch {
|
|
1018
1149
|
}
|
|
1019
1150
|
}
|
|
1020
|
-
const componentDir =
|
|
1151
|
+
const componentDir = resolve4(configDir, "src", "components");
|
|
1021
1152
|
let graphData;
|
|
1022
1153
|
try {
|
|
1023
1154
|
const graphResult = await buildComponentGraph(fragments, blocks, componentDir);
|
|
@@ -1057,7 +1188,7 @@ async function buildFragments(config, configDir) {
|
|
|
1057
1188
|
...tokens && { tokens },
|
|
1058
1189
|
...graphData && { graph: graphData }
|
|
1059
1190
|
};
|
|
1060
|
-
const outputPath =
|
|
1191
|
+
const outputPath = resolve4(configDir, config.outFile ?? BRAND.outFile);
|
|
1061
1192
|
await writeFile(outputPath, JSON.stringify(output));
|
|
1062
1193
|
return {
|
|
1063
1194
|
success: errors.length === 0,
|
|
@@ -1448,9 +1579,9 @@ ${BRAND.name} Diff
|
|
|
1448
1579
|
}
|
|
1449
1580
|
|
|
1450
1581
|
// src/analyze.ts
|
|
1451
|
-
import { existsSync as
|
|
1582
|
+
import { existsSync as existsSync5 } from "fs";
|
|
1452
1583
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
1453
|
-
import { join as join4, dirname as
|
|
1584
|
+
import { join as join4, dirname as dirname3 } from "path";
|
|
1454
1585
|
import pc3 from "picocolors";
|
|
1455
1586
|
async function runAnalyzeCommand(config, configDir, options = {}) {
|
|
1456
1587
|
const format = options.format ?? "html";
|
|
@@ -1459,7 +1590,7 @@ async function runAnalyzeCommand(config, configDir, options = {}) {
|
|
|
1459
1590
|
${BRAND.name} Analyzer
|
|
1460
1591
|
`));
|
|
1461
1592
|
const fragmentsPath = join4(configDir, config.outFile ?? "fragments.json");
|
|
1462
|
-
if (!
|
|
1593
|
+
if (!existsSync5(fragmentsPath)) {
|
|
1463
1594
|
console.log(pc3.red(`\u2717 No fragments.json found. Run \`${BRAND.cliCommand} build\` first.
|
|
1464
1595
|
`));
|
|
1465
1596
|
return {
|
|
@@ -1475,7 +1606,7 @@ ${BRAND.name} Analyzer
|
|
|
1475
1606
|
let outputPath;
|
|
1476
1607
|
if (format === "html" || format === "json") {
|
|
1477
1608
|
outputPath = options.output ?? getDefaultOutputPath(format, configDir);
|
|
1478
|
-
await mkdir2(
|
|
1609
|
+
await mkdir2(dirname3(outputPath), { recursive: true });
|
|
1479
1610
|
if (format === "html") {
|
|
1480
1611
|
const html = generateHtmlReport(analytics);
|
|
1481
1612
|
await writeFile2(outputPath, html);
|
|
@@ -1622,4 +1753,4 @@ export {
|
|
|
1622
1753
|
runDiffCommand,
|
|
1623
1754
|
runAnalyzeCommand
|
|
1624
1755
|
};
|
|
1625
|
-
//# sourceMappingURL=chunk-
|
|
1756
|
+
//# sourceMappingURL=chunk-QPY4DUFB.js.map
|