pattern-dump 0.1.0-alpha.2 → 0.1.0-alpha.4
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 +55 -0
- package/README.md +1 -1
- package/dist/chunks/{chunk-3WZHFYHZ.js → chunk-NXGPZL5L.js} +3 -3
- package/dist/index.js +1 -1
- package/dist/pd.js +481 -310
- package/dist/types/config/index.d.ts +12 -4
- package/dist/types/contracts/dev-protocol.d.ts +4 -3
- package/package.json +2 -1
package/dist/pd.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ConfigError,
|
|
4
4
|
validateConfig
|
|
5
|
-
} from "./chunks/chunk-
|
|
5
|
+
} from "./chunks/chunk-NXGPZL5L.js";
|
|
6
6
|
|
|
7
7
|
// packages/discovery/src/index.ts
|
|
8
8
|
import { readdir } from "node:fs/promises";
|
|
@@ -30,10 +30,12 @@ function collapseComponentId(relNoExt) {
|
|
|
30
30
|
const parent = dirname(relNoExt);
|
|
31
31
|
return stem === basename(parent) ? parent : relNoExt;
|
|
32
32
|
}
|
|
33
|
+
function stripOrderPrefixes(path) {
|
|
34
|
+
return path.split("/").map((seg) => seg.replace(/^\d+[-_]/, "")).join("/");
|
|
35
|
+
}
|
|
33
36
|
function deriveHandle(id) {
|
|
34
|
-
const parts = id.split("/");
|
|
35
|
-
|
|
36
|
-
return `${unnumbered(parts[0])}-${unnumbered(parts[parts.length - 1])}`;
|
|
37
|
+
const parts = stripOrderPrefixes(id).split("/");
|
|
38
|
+
return `${parts[0]}-${parts[parts.length - 1]}`;
|
|
37
39
|
}
|
|
38
40
|
async function buildDiscoveryMap(roots) {
|
|
39
41
|
const rootList = typeof roots === "string" ? [{ dir: roots }] : roots;
|
|
@@ -418,6 +420,7 @@ function _plainPre(code) {
|
|
|
418
420
|
import { HtmlValidate } from "html-validate";
|
|
419
421
|
import Handlebars from "handlebars";
|
|
420
422
|
import { readFile } from "node:fs/promises";
|
|
423
|
+
import { basename as basename2 } from "node:path";
|
|
421
424
|
var htmlValidator = new HtmlValidate({
|
|
422
425
|
rules: {
|
|
423
426
|
"element-permitted-content": "error",
|
|
@@ -439,6 +442,36 @@ function deepMerge(target, ...sources) {
|
|
|
439
442
|
return target;
|
|
440
443
|
}
|
|
441
444
|
var safePart = (n) => n.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
445
|
+
function jsonErrorPosition(reason, text) {
|
|
446
|
+
const lineColumn = /line (\d+) column (\d+)/.exec(reason);
|
|
447
|
+
if (lineColumn) return { line: Number(lineColumn[1]), column: Number(lineColumn[2]) };
|
|
448
|
+
const position = /position (\d+)/.exec(reason);
|
|
449
|
+
if (!position) return {};
|
|
450
|
+
const lines = text.slice(0, Number(position[1])).split("\n");
|
|
451
|
+
return { line: lines.length, column: lines[lines.length - 1].length + 1 };
|
|
452
|
+
}
|
|
453
|
+
async function readDataFile(path) {
|
|
454
|
+
let text;
|
|
455
|
+
try {
|
|
456
|
+
text = await readFile(path, "utf-8");
|
|
457
|
+
} catch {
|
|
458
|
+
return {};
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
return { data: JSON.parse(text) };
|
|
462
|
+
} catch (e) {
|
|
463
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
464
|
+
return {
|
|
465
|
+
diagnostic: {
|
|
466
|
+
kind: "DATA_INVALID",
|
|
467
|
+
source: "render",
|
|
468
|
+
severity: "error",
|
|
469
|
+
message: `${basename2(path)} is not valid JSON (${reason}); its data was not used`,
|
|
470
|
+
location: { file: path, ...jsonErrorPosition(reason, text) }
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
}
|
|
442
475
|
function registerHelpers(env, mintId, getLastId, projectHelpers, helperRegistrars) {
|
|
443
476
|
env.registerHelper("id", (name) => mintId(name));
|
|
444
477
|
env.registerHelper("getId", (name) => mintId(name));
|
|
@@ -519,30 +552,34 @@ var createRenderer = (options) => {
|
|
|
519
552
|
discoveryMap ??= maps.discoveryMap;
|
|
520
553
|
handleMap ??= maps.handleMap;
|
|
521
554
|
}
|
|
522
|
-
|
|
523
|
-
|
|
555
|
+
let componentId = input.component;
|
|
556
|
+
let variant = input.variant;
|
|
557
|
+
const tilde = componentId.indexOf("~");
|
|
558
|
+
if (tilde > 0 && !variant && discoveryMap.has(componentId.slice(0, tilde))) {
|
|
559
|
+
variant = componentId.slice(tilde + 1);
|
|
560
|
+
componentId = componentId.slice(0, tilde);
|
|
561
|
+
}
|
|
562
|
+
const entry = discoveryMap.get(componentId);
|
|
563
|
+
if (!entry) throw new Error(`[renderer] Component not found: "${componentId}"`);
|
|
524
564
|
let templateHbsPath = entry.hbsPath;
|
|
525
565
|
let variantJsonPath;
|
|
526
|
-
if (
|
|
527
|
-
const variantEntry = discoveryMap.get(`${
|
|
528
|
-
if (!variantEntry) throw new Error(`[renderer] Variant not found: "${
|
|
566
|
+
if (variant) {
|
|
567
|
+
const variantEntry = discoveryMap.get(`${componentId}~${variant}`);
|
|
568
|
+
if (!variantEntry) throw new Error(`[renderer] Variant not found: "${componentId}~${variant}"`);
|
|
529
569
|
if (variantEntry.ownMarkup && variantEntry.hbsPath) {
|
|
530
570
|
templateHbsPath = variantEntry.hbsPath;
|
|
531
571
|
}
|
|
532
572
|
variantJsonPath = variantEntry.jsonPath;
|
|
533
573
|
}
|
|
534
574
|
const templateSrc = templateHbsPath ? await readFile(templateHbsPath, "utf-8") : "";
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
if (variantJsonPath) {
|
|
544
|
-
variantData = JSON.parse(await readFile(variantJsonPath, "utf-8"));
|
|
545
|
-
}
|
|
575
|
+
const dataDiagnostics = /* @__PURE__ */ new Map();
|
|
576
|
+
const readData = async (path) => {
|
|
577
|
+
const { data: data2, diagnostic } = await readDataFile(path);
|
|
578
|
+
if (diagnostic) dataDiagnostics.set(path, diagnostic);
|
|
579
|
+
return data2;
|
|
580
|
+
};
|
|
581
|
+
const defaultData = (entry.jsonPath ? await readData(entry.jsonPath) : void 0) ?? {};
|
|
582
|
+
const variantData = variantJsonPath ? await readData(variantJsonPath) : void 0;
|
|
546
583
|
const data = deepMerge(
|
|
547
584
|
structuredClone(options.globalData ?? {}),
|
|
548
585
|
defaultData,
|
|
@@ -550,7 +587,7 @@ var createRenderer = (options) => {
|
|
|
550
587
|
input.data
|
|
551
588
|
);
|
|
552
589
|
const env = Handlebars.create();
|
|
553
|
-
const componentSlug = safePart(
|
|
590
|
+
const componentSlug = safePart(componentId.replace(/[\\/]/g, "-"));
|
|
554
591
|
let currentBase = `pd-${componentSlug}`;
|
|
555
592
|
const idCache = /* @__PURE__ */ new Map();
|
|
556
593
|
let lastMintedId = "";
|
|
@@ -570,13 +607,12 @@ var createRenderer = (options) => {
|
|
|
570
607
|
if (!compEntry?.hbsPath) continue;
|
|
571
608
|
try {
|
|
572
609
|
const partialSrc = await readFile(compEntry.hbsPath, "utf-8");
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
610
|
+
const childData = compEntry.jsonPath ? await readDataFile(compEntry.jsonPath) : {};
|
|
611
|
+
const childDataPath = compEntry.jsonPath;
|
|
612
|
+
const variantTilde = compId.indexOf("~");
|
|
613
|
+
const baseJsonPath = variantTilde > 0 ? discoveryMap.get(compId.slice(0, variantTilde))?.jsonPath : void 0;
|
|
614
|
+
const baseData = baseJsonPath ? await readDataFile(baseJsonPath) : {};
|
|
615
|
+
const childDefaults = deepMerge(structuredClone(baseData.data ?? {}), childData.data);
|
|
580
616
|
const childTemplate = env.compile(partialSrc);
|
|
581
617
|
const capturedDefaults = childDefaults;
|
|
582
618
|
const partialSlug = safePart(compId.replace(/[\\/]/g, "-"));
|
|
@@ -593,13 +629,16 @@ var createRenderer = (options) => {
|
|
|
593
629
|
invocationCounters.set(counterKey, n + 1);
|
|
594
630
|
thisBase = n === 0 ? currentBase : `pd-${partialSlug}-${n}`;
|
|
595
631
|
}
|
|
632
|
+
if (childData.diagnostic && childDataPath) dataDiagnostics.set(childDataPath, childData.diagnostic);
|
|
633
|
+
if (baseData.diagnostic && baseJsonPath) dataDiagnostics.set(baseJsonPath, baseData.diagnostic);
|
|
596
634
|
const savedBase = currentBase;
|
|
597
635
|
currentBase = thisBase;
|
|
598
636
|
const merged = deepMerge(
|
|
599
637
|
structuredClone(capturedDefaults),
|
|
600
638
|
context != null && typeof context === "object" && !Array.isArray(context) ? context : {}
|
|
601
639
|
);
|
|
602
|
-
const
|
|
640
|
+
const data2 = { ...opts?.data, ...opts?.fn ? { "partial-block": opts.fn } : {} };
|
|
641
|
+
const runtime = opts?.fn ? { data: data2, partials: { ...env.partials, "@partial-block": opts.fn } } : { data: data2 };
|
|
603
642
|
const result = childTemplate(merged, runtime);
|
|
604
643
|
currentBase = savedBase;
|
|
605
644
|
return result;
|
|
@@ -611,7 +650,7 @@ var createRenderer = (options) => {
|
|
|
611
650
|
const html = env.compile(templateSrc)(data, {
|
|
612
651
|
partials: { ...env.partials, "@partial-block": () => "" }
|
|
613
652
|
});
|
|
614
|
-
const diagnostics = [];
|
|
653
|
+
const diagnostics = [...dataDiagnostics.values()];
|
|
615
654
|
const htmlReport = htmlValidator.validateStringSync(html);
|
|
616
655
|
for (const result of htmlReport.results) {
|
|
617
656
|
for (const msg of result.messages) {
|
|
@@ -660,7 +699,7 @@ var createRenderer = (options) => {
|
|
|
660
699
|
}
|
|
661
700
|
} catch {
|
|
662
701
|
}
|
|
663
|
-
const meta = diagnostics.length > 0 ? { componentId
|
|
702
|
+
const meta = diagnostics.length > 0 ? { componentId, variant, diagnostics } : void 0;
|
|
664
703
|
return { html, document: buildDocument(html, options), ...meta ? { meta } : {} };
|
|
665
704
|
};
|
|
666
705
|
};
|
|
@@ -683,9 +722,26 @@ import * as sass from "sass";
|
|
|
683
722
|
import postcss from "postcss";
|
|
684
723
|
import autoprefixer from "autoprefixer";
|
|
685
724
|
import { build as esbuildBuild } from "esbuild";
|
|
725
|
+
import { existsSync } from "node:fs";
|
|
686
726
|
import { readdir as readdir2 } from "node:fs/promises";
|
|
687
|
-
import { join as join2, extname, resolve } from "node:path";
|
|
727
|
+
import { dirname as dirname2, join as join2, extname, resolve } from "node:path";
|
|
688
728
|
import { fileURLToPath } from "node:url";
|
|
729
|
+
var packageOptionsCache = /* @__PURE__ */ new Map();
|
|
730
|
+
function sassPackageOptions(entryFile) {
|
|
731
|
+
const start = dirname2(resolve(entryFile));
|
|
732
|
+
let options = packageOptionsCache.get(start);
|
|
733
|
+
if (!options) {
|
|
734
|
+
const loadPaths = [];
|
|
735
|
+
for (let dir = start; ; dir = dirname2(dir)) {
|
|
736
|
+
const modules = join2(dir, "node_modules");
|
|
737
|
+
if (existsSync(modules)) loadPaths.push(modules);
|
|
738
|
+
if (dirname2(dir) === dir) break;
|
|
739
|
+
}
|
|
740
|
+
options = { loadPaths, importers: [new sass.NodePackageImporter(start)] };
|
|
741
|
+
packageOptionsCache.set(start, options);
|
|
742
|
+
}
|
|
743
|
+
return options;
|
|
744
|
+
}
|
|
689
745
|
async function collectScssFiles(dir) {
|
|
690
746
|
const files = [];
|
|
691
747
|
async function walk(current) {
|
|
@@ -708,7 +764,7 @@ async function collectScssFiles(dir) {
|
|
|
708
764
|
return files;
|
|
709
765
|
}
|
|
710
766
|
async function compileSassFileWithDeps(filePath) {
|
|
711
|
-
const result = sass.compile(filePath);
|
|
767
|
+
const result = sass.compile(filePath, sassPackageOptions(filePath));
|
|
712
768
|
const processed = await postcss([autoprefixer]).process(result.css, { from: void 0 });
|
|
713
769
|
const deps = result.loadedUrls.filter((u) => u.protocol === "file:").map((u) => fileURLToPath(u)).filter((p) => resolve(p) !== resolve(filePath));
|
|
714
770
|
return { css: processed.css, deps };
|
|
@@ -1180,7 +1236,7 @@ async function loadGlobalData(dataDirs) {
|
|
|
1180
1236
|
|
|
1181
1237
|
// packages/dev-server/src/surfacing.ts
|
|
1182
1238
|
import { mkdir, readFile as readFile5, writeFile } from "node:fs/promises";
|
|
1183
|
-
import { join as
|
|
1239
|
+
import { join as join8, relative as relative3 } from "node:path";
|
|
1184
1240
|
|
|
1185
1241
|
// packages/dev-server/src/flattening.ts
|
|
1186
1242
|
import { parse as parseHtml } from "node-html-parser";
|
|
@@ -1426,11 +1482,108 @@ function pdScratchDir(root) {
|
|
|
1426
1482
|
return join5(tmpdir(), "pattern-dump", key);
|
|
1427
1483
|
}
|
|
1428
1484
|
|
|
1485
|
+
// packages/dev-server/src/server-config.ts
|
|
1486
|
+
import { basename as basename3, join as join6, resolve as resolve4 } from "node:path";
|
|
1487
|
+
function shadowedAssetRoots(assetRoots) {
|
|
1488
|
+
const first = /* @__PURE__ */ new Map();
|
|
1489
|
+
const shadowed = [];
|
|
1490
|
+
for (const root of assetRoots) {
|
|
1491
|
+
const by = first.get(basename3(root));
|
|
1492
|
+
if (by === void 0) first.set(basename3(root), root);
|
|
1493
|
+
else if (by !== root) shadowed.push({ root, by });
|
|
1494
|
+
}
|
|
1495
|
+
return shadowed;
|
|
1496
|
+
}
|
|
1497
|
+
var DEFAULT_SWATCH_SLOTS = ["--bodyBackground", "--themePrimary", "--accent"];
|
|
1498
|
+
function resolveServerConfig(config, cwd, opts = {}, packages = []) {
|
|
1499
|
+
const port2 = opts.port ?? Number(process.env["PD_PORT"] ?? 4e3);
|
|
1500
|
+
const wsPort = opts.wsPort ?? Number(process.env["PD_WS_PORT"] ?? port2 + 1);
|
|
1501
|
+
const patternsDir = resolve4(cwd, config.patternsDir);
|
|
1502
|
+
const stylesDir = resolve4(cwd, config.styles.dir);
|
|
1503
|
+
const stylesEntries = config.styles.entry ? (Array.isArray(config.styles.entry) ? config.styles.entry : [config.styles.entry]).map((e) => resolve4(stylesDir, e)) : void 0;
|
|
1504
|
+
const inPackage = (p, rel) => join6(p.dir, rel);
|
|
1505
|
+
const asList = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
|
|
1506
|
+
const patternRoots = [
|
|
1507
|
+
{ dir: patternsDir, ...config.exclude?.length ? { exclude: config.exclude } : {} },
|
|
1508
|
+
...packages.filter((p) => p.manifest.patterns).map((p) => ({
|
|
1509
|
+
dir: inPackage(p, p.manifest.patterns),
|
|
1510
|
+
source: p.name,
|
|
1511
|
+
...p.exclude.length ? { exclude: p.exclude } : {}
|
|
1512
|
+
}))
|
|
1513
|
+
];
|
|
1514
|
+
const styleRoots = [
|
|
1515
|
+
{ dir: stylesDir, entries: stylesEntries, base: config.documentBase },
|
|
1516
|
+
...packages.filter((p) => p.manifest.styles && p.styles).map((p) => {
|
|
1517
|
+
const dir = inPackage(p, p.manifest.styles.dir);
|
|
1518
|
+
const entries = asList(p.manifest.styles.entry).map((e) => resolve4(dir, e));
|
|
1519
|
+
return { dir, entries: entries.length ? entries : void 0, source: p.name, base: p.manifest.styles.documentBase };
|
|
1520
|
+
})
|
|
1521
|
+
];
|
|
1522
|
+
const themePackages = packages.filter((p) => p.manifest.themes);
|
|
1523
|
+
const themeDirs = [
|
|
1524
|
+
...config.themes?.dir ? [resolve4(cwd, config.themes.dir)] : [],
|
|
1525
|
+
...themePackages.map((p) => inPackage(p, p.manifest.themes.dir))
|
|
1526
|
+
];
|
|
1527
|
+
const switches = [config.themes?.switch, ...themePackages.map((p) => p.manifest.themes.switch)];
|
|
1528
|
+
const themeSwitch = switches.includes("stylesheet") ? "stylesheet" : "attribute";
|
|
1529
|
+
const assetRoots = [
|
|
1530
|
+
...asList(config.assets?.dir).map((d) => resolve4(cwd, d)),
|
|
1531
|
+
...packages.flatMap((p) => (p.manifest.assets ?? []).map((a) => inPackage(p, a)))
|
|
1532
|
+
];
|
|
1533
|
+
const globalScripts = [.../* @__PURE__ */ new Set([
|
|
1534
|
+
...packages.flatMap((p) => p.manifest.globalScripts ?? []),
|
|
1535
|
+
...config.globalScripts ?? []
|
|
1536
|
+
])];
|
|
1537
|
+
const scriptsDirs = [
|
|
1538
|
+
...config.scriptsDir ? [resolve4(cwd, config.scriptsDir)] : [],
|
|
1539
|
+
...packages.filter((p) => p.manifest.scripts).map((p) => inPackage(p, p.manifest.scripts))
|
|
1540
|
+
];
|
|
1541
|
+
const documentBaseEnabled = Array.isArray(config.documentBase) && config.documentBase.length > 0 || packages.some((p) => p.styles && (p.manifest.styles?.documentBase?.length ?? 0) > 0);
|
|
1542
|
+
return {
|
|
1543
|
+
port: port2,
|
|
1544
|
+
wsPort,
|
|
1545
|
+
cwd,
|
|
1546
|
+
config,
|
|
1547
|
+
packages,
|
|
1548
|
+
patternRoots,
|
|
1549
|
+
patternDirs: patternRoots.map((r) => r.dir),
|
|
1550
|
+
styleRoots,
|
|
1551
|
+
dataDirs: [
|
|
1552
|
+
...packages.filter((p) => p.manifest.data).map((p) => inPackage(p, p.manifest.data)),
|
|
1553
|
+
...config.dataDir ? [resolve4(cwd, config.dataDir)] : []
|
|
1554
|
+
],
|
|
1555
|
+
helperPaths: [
|
|
1556
|
+
...packages.filter((p) => p.manifest.helpers).map((p) => inPackage(p, p.manifest.helpers)),
|
|
1557
|
+
...config.helpers ? [resolve4(cwd, config.helpers)] : []
|
|
1558
|
+
],
|
|
1559
|
+
scriptsDirs,
|
|
1560
|
+
patternsDir,
|
|
1561
|
+
stylesDir,
|
|
1562
|
+
stylesEntries,
|
|
1563
|
+
themeDirs,
|
|
1564
|
+
themesDir: themeDirs[0] ?? null,
|
|
1565
|
+
defaultTheme: config.themes?.default ?? themePackages[0]?.manifest.themes?.default,
|
|
1566
|
+
assetRoots,
|
|
1567
|
+
assetRootNames: assetRoots.map((r) => basename3(r)),
|
|
1568
|
+
assetsDir: assetRoots[0] ?? null,
|
|
1569
|
+
assetsCss: config.assets?.css ?? [],
|
|
1570
|
+
scriptsDir: scriptsDirs[0] ?? null,
|
|
1571
|
+
globalScripts,
|
|
1572
|
+
withGlobalScripts: (own) => [.../* @__PURE__ */ new Set([...globalScripts, ...own ?? []])],
|
|
1573
|
+
overviewsEnabled: config.overviews !== false,
|
|
1574
|
+
documentBaseEnabled,
|
|
1575
|
+
themeSwitch,
|
|
1576
|
+
swatchSlots: config.themes?.swatch?.slots ?? DEFAULT_SWATCH_SLOTS,
|
|
1577
|
+
packageSwatchSlots: DEFAULT_SWATCH_SLOTS
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1429
1581
|
// packages/dev-server/src/style-index.ts
|
|
1430
|
-
import { dirname as
|
|
1431
|
-
import { existsSync } from "node:fs";
|
|
1582
|
+
import { dirname as dirname3, join as join7, relative as relative2, resolve as resolve5 } from "node:path";
|
|
1583
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
1432
1584
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1433
1585
|
import postcss3 from "postcss";
|
|
1586
|
+
import selectorParser from "postcss-selector-parser";
|
|
1434
1587
|
import { SourceMapConsumer } from "source-map";
|
|
1435
1588
|
import * as sass2 from "sass";
|
|
1436
1589
|
|
|
@@ -1442,6 +1595,10 @@ function cssNodeText(node) {
|
|
|
1442
1595
|
const text = node.toString();
|
|
1443
1596
|
return node.type === "atrule" && !node.nodes ? `${text};` : text;
|
|
1444
1597
|
}
|
|
1598
|
+
function addLastOccurrence(bucket, chunk) {
|
|
1599
|
+
bucket.delete(chunk);
|
|
1600
|
+
bucket.add(chunk);
|
|
1601
|
+
}
|
|
1445
1602
|
function joinCssChunks(chunks) {
|
|
1446
1603
|
const charset = [];
|
|
1447
1604
|
const imports = [];
|
|
@@ -1453,7 +1610,33 @@ function joinCssChunks(chunks) {
|
|
|
1453
1610
|
}
|
|
1454
1611
|
return [...charset.slice(0, 1), ...imports, ...rest].join("\n");
|
|
1455
1612
|
}
|
|
1456
|
-
var
|
|
1613
|
+
var selectorClassCache = /* @__PURE__ */ new Map();
|
|
1614
|
+
function selectorClasses(selector) {
|
|
1615
|
+
const cached = selectorClassCache.get(selector);
|
|
1616
|
+
if (cached) return cached;
|
|
1617
|
+
const defines = /* @__PURE__ */ new Set();
|
|
1618
|
+
const mentions = /* @__PURE__ */ new Set();
|
|
1619
|
+
try {
|
|
1620
|
+
selectorParser((list) => {
|
|
1621
|
+
list.each((complex) => {
|
|
1622
|
+
const contextFree = !complex.some((node) => node.type === "combinator");
|
|
1623
|
+
complex.walkClasses((cls) => {
|
|
1624
|
+
(contextFree && cls.parent === complex ? defines : mentions).add(cls.value);
|
|
1625
|
+
});
|
|
1626
|
+
});
|
|
1627
|
+
}).processSync(selector);
|
|
1628
|
+
} catch {
|
|
1629
|
+
for (const m of selector.matchAll(/\.([\w-]+)/g)) defines.add(m[1]);
|
|
1630
|
+
}
|
|
1631
|
+
for (const name of defines) mentions.delete(name);
|
|
1632
|
+
const result = { defines: [...defines], mentions: [...mentions] };
|
|
1633
|
+
selectorClassCache.set(selector, result);
|
|
1634
|
+
return result;
|
|
1635
|
+
}
|
|
1636
|
+
function claimRank(owner, defines) {
|
|
1637
|
+
return (defines ? 2 : 0) + (owner === "__base__" ? 0 : 1);
|
|
1638
|
+
}
|
|
1639
|
+
var indexRanks = /* @__PURE__ */ new WeakMap();
|
|
1457
1640
|
var strippedIdCache = /* @__PURE__ */ new WeakMap();
|
|
1458
1641
|
function strippedIds(componentIds) {
|
|
1459
1642
|
let map = strippedIdCache.get(componentIds);
|
|
@@ -1506,55 +1689,72 @@ function missingDocumentBase(stylesDir, base2) {
|
|
|
1506
1689
|
return (base2 ?? []).filter((entry) => {
|
|
1507
1690
|
const e = normalizeBaseEntry(entry);
|
|
1508
1691
|
if (e === "") return false;
|
|
1509
|
-
const dir =
|
|
1692
|
+
const dir = dirname3(join7(stylesDir, e));
|
|
1510
1693
|
const name = e.split("/").pop();
|
|
1511
|
-
return ![
|
|
1694
|
+
return ![join7(stylesDir, e), join7(dir, `${name}.scss`), join7(dir, `_${name}.scss`)].some(existsSync2);
|
|
1512
1695
|
});
|
|
1513
1696
|
}
|
|
1514
1697
|
function extractClassesFromCompiled(consumer, root, entryFile, stylesDir, componentIds) {
|
|
1515
1698
|
const classMap = /* @__PURE__ */ new Map();
|
|
1516
1699
|
const baseModules = /* @__PURE__ */ new Map();
|
|
1700
|
+
const ranks = /* @__PURE__ */ new Map();
|
|
1517
1701
|
root.walkRules((rule) => {
|
|
1518
|
-
const
|
|
1519
|
-
if (
|
|
1702
|
+
const { defines, mentions } = selectorClasses(rule.selector);
|
|
1703
|
+
if (defines.length === 0 && mentions.length === 0) return;
|
|
1520
1704
|
const pos = rule.source?.start;
|
|
1521
1705
|
if (!pos) return;
|
|
1522
1706
|
const original = consumer.originalPositionFor({ line: pos.line, column: pos.column - 1 });
|
|
1523
1707
|
if (!original.source) return;
|
|
1524
|
-
const originPath = original.source.startsWith("file://") ? fileURLToPath2(original.source) :
|
|
1708
|
+
const originPath = original.source.startsWith("file://") ? fileURLToPath2(original.source) : resolve5(dirname3(entryFile), original.source);
|
|
1525
1709
|
const resolved = resolveScssToComponent(originPath, stylesDir, componentIds);
|
|
1526
1710
|
const owner = resolved ?? "__base__";
|
|
1527
1711
|
const modulePath = resolved === null ? resolveSharedModulePath(originPath, stylesDir, true) : null;
|
|
1528
|
-
|
|
1529
|
-
const
|
|
1530
|
-
if (
|
|
1531
|
-
|
|
1712
|
+
const claim = (name, rank) => {
|
|
1713
|
+
const prev = ranks.get(name);
|
|
1714
|
+
if (prev === void 0 || rank > prev) {
|
|
1715
|
+
classMap.set(name, owner);
|
|
1716
|
+
ranks.set(name, rank);
|
|
1717
|
+
if (modulePath && owner === "__base__") baseModules.set(name, modulePath);
|
|
1718
|
+
else baseModules.delete(name);
|
|
1719
|
+
} else if (modulePath && owner === "__base__" && classMap.get(name) === "__base__" && !baseModules.has(name)) {
|
|
1532
1720
|
baseModules.set(name, modulePath);
|
|
1533
1721
|
}
|
|
1534
|
-
}
|
|
1722
|
+
};
|
|
1723
|
+
for (const name of defines) claim(name, claimRank(owner, true));
|
|
1724
|
+
for (const name of mentions) claim(name, claimRank(owner, false));
|
|
1535
1725
|
});
|
|
1536
|
-
return { classMap, baseModules };
|
|
1726
|
+
return { classMap, baseModules, ranks };
|
|
1537
1727
|
}
|
|
1538
1728
|
async function attributeClassesFromFile(entryFile, stylesDir, componentIds) {
|
|
1539
1729
|
try {
|
|
1540
|
-
const compiled = sass2.compile(entryFile, { sourceMap: true });
|
|
1730
|
+
const compiled = sass2.compile(entryFile, { sourceMap: true, ...sassPackageOptions(entryFile) });
|
|
1541
1731
|
if (!compiled.sourceMap) return null;
|
|
1542
1732
|
const consumer = new SourceMapConsumer(compiled.sourceMap);
|
|
1543
1733
|
const root = postcss3.parse(compiled.css);
|
|
1544
|
-
const { classMap } = extractClassesFromCompiled(consumer, root, entryFile, stylesDir, componentIds);
|
|
1545
|
-
return classMap;
|
|
1734
|
+
const { classMap, ranks } = extractClassesFromCompiled(consumer, root, entryFile, stylesDir, componentIds);
|
|
1735
|
+
return { classMap, ranks };
|
|
1546
1736
|
} catch {
|
|
1547
1737
|
return null;
|
|
1548
1738
|
}
|
|
1549
1739
|
}
|
|
1550
1740
|
async function patchClassOwnerIndex(entryFile, changedCompId, stylesDir, componentIds, index) {
|
|
1741
|
+
const ranks = indexRanks.get(index);
|
|
1551
1742
|
for (const [cls, owner] of index) {
|
|
1552
|
-
if (owner === changedCompId)
|
|
1743
|
+
if (owner === changedCompId) {
|
|
1744
|
+
index.delete(cls);
|
|
1745
|
+
ranks?.delete(cls);
|
|
1746
|
+
}
|
|
1553
1747
|
}
|
|
1554
1748
|
const fresh = await attributeClassesFromFile(entryFile, stylesDir, componentIds);
|
|
1555
1749
|
if (!fresh) return false;
|
|
1556
|
-
for (const [name, owner] of fresh) {
|
|
1557
|
-
if (owner
|
|
1750
|
+
for (const [name, owner] of fresh.classMap) {
|
|
1751
|
+
if (owner !== changedCompId) continue;
|
|
1752
|
+
const rank = fresh.ranks.get(name) ?? 0;
|
|
1753
|
+
const prev = ranks?.get(name);
|
|
1754
|
+
if (!index.has(name) || prev !== void 0 && rank > prev) {
|
|
1755
|
+
index.set(name, owner);
|
|
1756
|
+
ranks?.set(name, rank);
|
|
1757
|
+
}
|
|
1558
1758
|
}
|
|
1559
1759
|
return true;
|
|
1560
1760
|
}
|
|
@@ -1562,6 +1762,8 @@ async function buildAllStyleData(roots, componentIds, entryOverride) {
|
|
|
1562
1762
|
if (verboseTiming) console.time("[dev-server:timing] full classOwnerIndex build");
|
|
1563
1763
|
const styleUsesModules = /* @__PURE__ */ new Map();
|
|
1564
1764
|
const classIndex = /* @__PURE__ */ new Map();
|
|
1765
|
+
const classRanks = /* @__PURE__ */ new Map();
|
|
1766
|
+
indexRanks.set(classIndex, classRanks);
|
|
1565
1767
|
const baseProvenance = /* @__PURE__ */ new Map();
|
|
1566
1768
|
const componentCssBuckets = /* @__PURE__ */ new Map();
|
|
1567
1769
|
const baseCssByRoot = [];
|
|
@@ -1579,12 +1781,11 @@ async function buildAllStyleData(roots, componentIds, entryOverride) {
|
|
|
1579
1781
|
entryFiles = [...styleRoot.entries];
|
|
1580
1782
|
} else {
|
|
1581
1783
|
try {
|
|
1582
|
-
entryFiles = await collectScssFiles(stylesDir);
|
|
1784
|
+
entryFiles = (await collectScssFiles(stylesDir)).sort();
|
|
1583
1785
|
} catch {
|
|
1584
1786
|
entryFiles = [];
|
|
1585
1787
|
}
|
|
1586
1788
|
}
|
|
1587
|
-
entryFiles.sort();
|
|
1588
1789
|
for (const entryFile of entryFiles) {
|
|
1589
1790
|
let originPathFor2 = function(node) {
|
|
1590
1791
|
const pos = node.source?.start;
|
|
@@ -1594,18 +1795,18 @@ async function buildAllStyleData(roots, componentIds, entryOverride) {
|
|
|
1594
1795
|
column: pos.column - 1
|
|
1595
1796
|
});
|
|
1596
1797
|
if (!original.source) return null;
|
|
1597
|
-
return original.source.startsWith("file://") ? fileURLToPath2(original.source) :
|
|
1798
|
+
return original.source.startsWith("file://") ? fileURLToPath2(original.source) : resolve5(dirname3(entryFile), original.source);
|
|
1598
1799
|
};
|
|
1599
1800
|
var originPathFor = originPathFor2;
|
|
1600
1801
|
const compOwner = resolveScssToComponent(entryFile, stylesDir, componentIds);
|
|
1601
1802
|
let compiled;
|
|
1602
1803
|
try {
|
|
1603
|
-
compiled = sass2.compile(entryFile, { sourceMap: true });
|
|
1804
|
+
compiled = sass2.compile(entryFile, { sourceMap: true, ...sassPackageOptions(entryFile) });
|
|
1604
1805
|
} catch {
|
|
1605
1806
|
continue;
|
|
1606
1807
|
}
|
|
1607
1808
|
if (compOwner) {
|
|
1608
|
-
const deps = compiled.loadedUrls.filter((u) => u.protocol === "file:").map((u) => fileURLToPath2(u)).filter((p) =>
|
|
1809
|
+
const deps = compiled.loadedUrls.filter((u) => u.protocol === "file:").map((u) => fileURLToPath2(u)).filter((p) => resolve5(p) !== resolve5(entryFile));
|
|
1609
1810
|
for (const dep of deps) {
|
|
1610
1811
|
const depComp = resolveScssToComponent(dep, stylesDir, componentIds);
|
|
1611
1812
|
if (depComp !== null && depComp !== compOwner) {
|
|
@@ -1640,7 +1841,7 @@ async function buildAllStyleData(roots, componentIds, entryOverride) {
|
|
|
1640
1841
|
const nodeText = cssNodeText(node);
|
|
1641
1842
|
const owner = inBase(originPath) ? "__base__" : resolveScssToComponent(originPath, stylesDir, componentIds) ?? "__base__";
|
|
1642
1843
|
if (owner === "__base__") {
|
|
1643
|
-
baseCssBucket
|
|
1844
|
+
addLastOccurrence(baseCssBucket, nodeText);
|
|
1644
1845
|
if (reportOutside && !inBase(originPath)) {
|
|
1645
1846
|
const seen = outsideRules.get(originPath) ?? /* @__PURE__ */ new Set();
|
|
1646
1847
|
seen.add(nodeText);
|
|
@@ -1648,16 +1849,23 @@ async function buildAllStyleData(roots, componentIds, entryOverride) {
|
|
|
1648
1849
|
}
|
|
1649
1850
|
} else {
|
|
1650
1851
|
const bucket = componentCssBuckets.get(owner) ?? /* @__PURE__ */ new Set();
|
|
1651
|
-
bucket
|
|
1852
|
+
addLastOccurrence(bucket, nodeText);
|
|
1652
1853
|
componentCssBuckets.set(owner, bucket);
|
|
1653
1854
|
}
|
|
1654
1855
|
});
|
|
1655
|
-
const { classMap: perFileClasses, baseModules: perFileBaseModules } = extractClassesFromCompiled(consumer, root, entryFile, stylesDir, componentIds);
|
|
1856
|
+
const { classMap: perFileClasses, baseModules: perFileBaseModules, ranks: perFileRanks } = extractClassesFromCompiled(consumer, root, entryFile, stylesDir, componentIds);
|
|
1656
1857
|
for (const [name, owner] of perFileClasses) {
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
if (
|
|
1858
|
+
const rank = perFileRanks.get(name) ?? 0;
|
|
1859
|
+
const prev = classRanks.get(name);
|
|
1860
|
+
const mod = perFileBaseModules.get(name);
|
|
1861
|
+
if (prev === void 0 || rank > prev) {
|
|
1862
|
+
classIndex.set(name, owner);
|
|
1863
|
+
classRanks.set(name, rank);
|
|
1864
|
+
if (mod) baseProvenance.set(name, mod);
|
|
1865
|
+
else baseProvenance.delete(name);
|
|
1866
|
+
} else if (mod && classIndex.get(name) === "__base__" && !baseProvenance.has(name)) {
|
|
1867
|
+
baseProvenance.set(name, mod);
|
|
1868
|
+
}
|
|
1661
1869
|
}
|
|
1662
1870
|
}
|
|
1663
1871
|
baseCssByRoot[baseCssByRoot.length - 1] = [...baseCssBucket];
|
|
@@ -1687,7 +1895,7 @@ async function surfaceCollisions(collisions, cwd, hotreloader) {
|
|
|
1687
1895
|
hotreloader.push(messages[i]);
|
|
1688
1896
|
console.warn(`[dev-server] HANDLE_COLLISION: "${col.handle}" \u2014 incumbent: ${col.incumbentPath} \u2014 quarantined: ${col.quarantinedPath}`);
|
|
1689
1897
|
}
|
|
1690
|
-
if (collisions.length > 0) console.warn(`[dev-server] collisions listed in ${
|
|
1898
|
+
if (collisions.length > 0) console.warn(`[dev-server] collisions listed in ${join8(pdScratchDir(cwd), "CONFLICTS.generated.md")}`);
|
|
1691
1899
|
const md = collisions.length === 0 ? "# Conflicts\n\nNo handle collisions detected.\n" : [
|
|
1692
1900
|
"# Conflicts",
|
|
1693
1901
|
"",
|
|
@@ -1703,7 +1911,7 @@ async function surfaceCollisions(collisions, cwd, hotreloader) {
|
|
|
1703
1911
|
try {
|
|
1704
1912
|
const dir = pdScratchDir(cwd);
|
|
1705
1913
|
await mkdir(dir, { recursive: true });
|
|
1706
|
-
await writeFile(
|
|
1914
|
+
await writeFile(join8(dir, "CONFLICTS.generated.md"), md, "utf-8");
|
|
1707
1915
|
} catch (e) {
|
|
1708
1916
|
console.warn("[dev-server] Could not write CONFLICTS.generated.md to scratch dir:", e);
|
|
1709
1917
|
}
|
|
@@ -1724,12 +1932,12 @@ async function surfaceFlattening(discoveryMap, registry, cwd) {
|
|
|
1724
1932
|
const md = renderFlatteningReport(clusters);
|
|
1725
1933
|
if (clusters.length) {
|
|
1726
1934
|
const members = clusters.reduce((n, c3) => n + c3.members.length, 0);
|
|
1727
|
-
console.warn(`[dev-server] FLATTENED: ${clusters.length} cluster(s) across ${members} components \u2014 see ${
|
|
1935
|
+
console.warn(`[dev-server] FLATTENED: ${clusters.length} cluster(s) across ${members} components \u2014 see ${join8(pdScratchDir(cwd), "FLATTENED.generated.md")}`);
|
|
1728
1936
|
}
|
|
1729
1937
|
try {
|
|
1730
1938
|
const dir = pdScratchDir(cwd);
|
|
1731
1939
|
await mkdir(dir, { recursive: true });
|
|
1732
|
-
await writeFile(
|
|
1940
|
+
await writeFile(join8(dir, "FLATTENED.generated.md"), md, "utf-8");
|
|
1733
1941
|
} catch (e) {
|
|
1734
1942
|
console.warn("[dev-server] Could not write FLATTENED.generated.md to scratch dir:", e);
|
|
1735
1943
|
}
|
|
@@ -1746,11 +1954,21 @@ function surfaceDocumentBase(roots, outsideList, cwd) {
|
|
|
1746
1954
|
const examples = files.slice(0, 3).map(([path]) => relative3(cwd, path)).join(", ");
|
|
1747
1955
|
console.log(`[dev-server] base layer: ${rules} rule(s) from ${files.length} file(s) that no component owns and documentBase does not list, e.g. ${examples}`);
|
|
1748
1956
|
}
|
|
1957
|
+
function surfaceAssetRoots(assetRoots, cwd) {
|
|
1958
|
+
for (const { root, by } of shadowedAssetRoots(assetRoots)) {
|
|
1959
|
+
console.warn(`[dev-server] assets: ${relative3(cwd, root)} is hidden by ${relative3(cwd, by) || "."}, which has the same folder name; its files are not served`);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
function surfaceDefaultTheme(defaultTheme, themeNames) {
|
|
1963
|
+
if (!defaultTheme || themeNames.includes(defaultTheme)) return;
|
|
1964
|
+
const available = themeNames.length ? `available: ${[...themeNames].sort().join(", ")}` : "no theme folder is configured or provided by a package";
|
|
1965
|
+
console.warn(`[dev-server] themes.default "${defaultTheme}" matches no theme; ${available}`);
|
|
1966
|
+
}
|
|
1749
1967
|
|
|
1750
1968
|
// packages/dev-server/src/diagnostics.ts
|
|
1751
1969
|
import { createHash as createHash2 } from "node:crypto";
|
|
1752
1970
|
import { readFile as readFile6, writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
|
|
1753
|
-
import { join as
|
|
1971
|
+
import { join as join9 } from "node:path";
|
|
1754
1972
|
|
|
1755
1973
|
// packages/a11y/src/producer.ts
|
|
1756
1974
|
import { createRequire } from "node:module";
|
|
@@ -1904,7 +2122,7 @@ function assembleGraph(audits) {
|
|
|
1904
2122
|
}
|
|
1905
2123
|
var GRAPH_ARTIFACT_VERSION = 1;
|
|
1906
2124
|
function graphArtifactPath(root) {
|
|
1907
|
-
return
|
|
2125
|
+
return join9(pdScratchDir(root), "diagnostics-graph.json");
|
|
1908
2126
|
}
|
|
1909
2127
|
async function readDiagnosticsArtifact(root) {
|
|
1910
2128
|
try {
|
|
@@ -1959,101 +2177,15 @@ async function persistSlices(root, slices, discoveryMap, globalData) {
|
|
|
1959
2177
|
await writeDiagnosticsArtifact(root, { version: GRAPH_ARTIFACT_VERSION, hashes, graph: assembleGraph([...slices.values()]) });
|
|
1960
2178
|
}
|
|
1961
2179
|
|
|
1962
|
-
// packages/dev-server/src/server-config.ts
|
|
1963
|
-
import { basename as basename2, join as join9, resolve as resolve5 } from "node:path";
|
|
1964
|
-
var DEFAULT_SWATCH_SLOTS = ["--bodyBackground", "--themePrimary", "--accent"];
|
|
1965
|
-
function resolveServerConfig(config, cwd, opts = {}, packages = []) {
|
|
1966
|
-
const port2 = opts.port ?? Number(process.env["PD_PORT"] ?? 4e3);
|
|
1967
|
-
const wsPort = opts.wsPort ?? Number(process.env["PD_WS_PORT"] ?? port2 + 1);
|
|
1968
|
-
const patternsDir = resolve5(cwd, config.patternsDir);
|
|
1969
|
-
const stylesDir = resolve5(cwd, config.styles.dir);
|
|
1970
|
-
const stylesEntries = config.styles.entry ? (Array.isArray(config.styles.entry) ? config.styles.entry : [config.styles.entry]).map((e) => resolve5(stylesDir, e)) : void 0;
|
|
1971
|
-
const inPackage = (p, rel) => join9(p.dir, rel);
|
|
1972
|
-
const asList = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
|
|
1973
|
-
const patternRoots = [
|
|
1974
|
-
{ dir: patternsDir, ...config.exclude?.length ? { exclude: config.exclude } : {} },
|
|
1975
|
-
...packages.filter((p) => p.manifest.patterns).map((p) => ({
|
|
1976
|
-
dir: inPackage(p, p.manifest.patterns),
|
|
1977
|
-
source: p.name,
|
|
1978
|
-
...p.exclude.length ? { exclude: p.exclude } : {}
|
|
1979
|
-
}))
|
|
1980
|
-
];
|
|
1981
|
-
const styleRoots = [
|
|
1982
|
-
{ dir: stylesDir, entries: stylesEntries, base: config.documentBase },
|
|
1983
|
-
...packages.filter((p) => p.manifest.styles).map((p) => {
|
|
1984
|
-
const dir = inPackage(p, p.manifest.styles.dir);
|
|
1985
|
-
const entries = asList(p.manifest.styles.entry).map((e) => resolve5(dir, e));
|
|
1986
|
-
return { dir, entries: entries.length ? entries : void 0, source: p.name, base: p.manifest.styles.documentBase };
|
|
1987
|
-
})
|
|
1988
|
-
];
|
|
1989
|
-
const themePackages = packages.filter((p) => p.manifest.themes);
|
|
1990
|
-
const themeDirs = [
|
|
1991
|
-
...config.themes ? [resolve5(cwd, config.themes.dir)] : [],
|
|
1992
|
-
...themePackages.map((p) => inPackage(p, p.manifest.themes.dir))
|
|
1993
|
-
];
|
|
1994
|
-
const switches = [config.themes?.switch, ...themePackages.map((p) => p.manifest.themes.switch)];
|
|
1995
|
-
const themeSwitch = switches.includes("stylesheet") ? "stylesheet" : "attribute";
|
|
1996
|
-
const assetRoots = [
|
|
1997
|
-
...asList(config.assets?.dir).map((d) => resolve5(cwd, d)),
|
|
1998
|
-
...packages.flatMap((p) => (p.manifest.assets ?? []).map((a) => inPackage(p, a)))
|
|
1999
|
-
];
|
|
2000
|
-
const globalScripts = [.../* @__PURE__ */ new Set([
|
|
2001
|
-
...packages.flatMap((p) => p.manifest.globalScripts ?? []),
|
|
2002
|
-
...config.globalScripts ?? []
|
|
2003
|
-
])];
|
|
2004
|
-
const scriptsDirs = [
|
|
2005
|
-
...config.scriptsDir ? [resolve5(cwd, config.scriptsDir)] : [],
|
|
2006
|
-
...packages.filter((p) => p.manifest.scripts).map((p) => inPackage(p, p.manifest.scripts))
|
|
2007
|
-
];
|
|
2008
|
-
const documentBaseEnabled = Array.isArray(config.documentBase) && config.documentBase.length > 0 || packages.some((p) => (p.manifest.styles?.documentBase?.length ?? 0) > 0);
|
|
2009
|
-
return {
|
|
2010
|
-
port: port2,
|
|
2011
|
-
wsPort,
|
|
2012
|
-
cwd,
|
|
2013
|
-
config,
|
|
2014
|
-
packages,
|
|
2015
|
-
patternRoots,
|
|
2016
|
-
patternDirs: patternRoots.map((r) => r.dir),
|
|
2017
|
-
styleRoots,
|
|
2018
|
-
dataDirs: [
|
|
2019
|
-
...packages.filter((p) => p.manifest.data).map((p) => inPackage(p, p.manifest.data)),
|
|
2020
|
-
...config.dataDir ? [resolve5(cwd, config.dataDir)] : []
|
|
2021
|
-
],
|
|
2022
|
-
helperPaths: [
|
|
2023
|
-
...packages.filter((p) => p.manifest.helpers).map((p) => inPackage(p, p.manifest.helpers)),
|
|
2024
|
-
...config.helpers ? [resolve5(cwd, config.helpers)] : []
|
|
2025
|
-
],
|
|
2026
|
-
scriptsDirs,
|
|
2027
|
-
patternsDir,
|
|
2028
|
-
stylesDir,
|
|
2029
|
-
stylesEntries,
|
|
2030
|
-
themeDirs,
|
|
2031
|
-
themesDir: themeDirs[0] ?? null,
|
|
2032
|
-
defaultTheme: config.themes?.default ?? themePackages[0]?.manifest.themes?.default,
|
|
2033
|
-
assetRoots,
|
|
2034
|
-
assetRootNames: assetRoots.map((r) => basename2(r)),
|
|
2035
|
-
assetsDir: assetRoots[0] ?? null,
|
|
2036
|
-
assetsCss: config.assets?.css ?? [],
|
|
2037
|
-
scriptsDir: scriptsDirs[0] ?? null,
|
|
2038
|
-
globalScripts,
|
|
2039
|
-
withGlobalScripts: (own) => [.../* @__PURE__ */ new Set([...globalScripts, ...own ?? []])],
|
|
2040
|
-
overviewsEnabled: config.overviews !== false,
|
|
2041
|
-
documentBaseEnabled,
|
|
2042
|
-
themeSwitch,
|
|
2043
|
-
swatchSlots: config.themes?.swatch?.slots ?? DEFAULT_SWATCH_SLOTS,
|
|
2044
|
-
packageSwatchSlots: DEFAULT_SWATCH_SLOTS
|
|
2045
|
-
};
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
2180
|
// packages/dev-server/src/packages.ts
|
|
2049
|
-
import { existsSync as
|
|
2050
|
-
import { dirname as
|
|
2181
|
+
import { existsSync as existsSync3, readFileSync } from "node:fs";
|
|
2182
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
2051
2183
|
function findPackageDir(name, root) {
|
|
2052
2184
|
let dir = root;
|
|
2053
2185
|
for (; ; ) {
|
|
2054
2186
|
const candidate = join10(dir, "node_modules", name);
|
|
2055
|
-
if (
|
|
2056
|
-
const parent =
|
|
2187
|
+
if (existsSync3(join10(candidate, "package.json"))) return candidate;
|
|
2188
|
+
const parent = dirname4(dir);
|
|
2057
2189
|
if (parent === dir) return null;
|
|
2058
2190
|
dir = parent;
|
|
2059
2191
|
}
|
|
@@ -2061,7 +2193,7 @@ function findPackageDir(name, root) {
|
|
|
2061
2193
|
function loadPatternPackages(references, root) {
|
|
2062
2194
|
const out = [];
|
|
2063
2195
|
const seen = /* @__PURE__ */ new Set();
|
|
2064
|
-
const visit = (name,
|
|
2196
|
+
const visit = (name, direct, from) => {
|
|
2065
2197
|
if (seen.has(name)) return;
|
|
2066
2198
|
const dir = findPackageDir(name, from);
|
|
2067
2199
|
if (!dir) {
|
|
@@ -2081,14 +2213,16 @@ function loadPatternPackages(references, root) {
|
|
|
2081
2213
|
version: pkg.version ?? "0.0.0",
|
|
2082
2214
|
dir,
|
|
2083
2215
|
manifest: pkg.patternDump,
|
|
2084
|
-
exclude: [...pkg.patternDump.exclude ?? [], ...
|
|
2085
|
-
direct
|
|
2216
|
+
exclude: [...pkg.patternDump.exclude ?? [], ...options.get(name)?.exclude ?? []],
|
|
2217
|
+
direct,
|
|
2218
|
+
styles: options.get(name)?.styles ?? true
|
|
2086
2219
|
});
|
|
2087
|
-
for (const peer of Object.keys(pkg.peerDependencies ?? {})) visit(peer,
|
|
2220
|
+
for (const peer of Object.keys(pkg.peerDependencies ?? {})) visit(peer, false, dir);
|
|
2088
2221
|
};
|
|
2222
|
+
const options = /* @__PURE__ */ new Map();
|
|
2223
|
+
for (const ref of references ?? []) if (typeof ref !== "string") options.set(ref.name, ref);
|
|
2089
2224
|
for (const ref of references ?? []) {
|
|
2090
|
-
|
|
2091
|
-
visit(name, exclude, true, root);
|
|
2225
|
+
visit(typeof ref === "string" ? ref : ref.name, true, root);
|
|
2092
2226
|
}
|
|
2093
2227
|
return out;
|
|
2094
2228
|
}
|
|
@@ -2124,7 +2258,7 @@ async function runDiagnosticsAudit(config, cwd) {
|
|
|
2124
2258
|
|
|
2125
2259
|
// packages/dev-server/src/static-build.ts
|
|
2126
2260
|
import { cp, mkdir as mkdir3, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
2127
|
-
import { dirname as
|
|
2261
|
+
import { dirname as dirname5, join as join11, relative as relative4, resolve as resolve6, sep } from "node:path";
|
|
2128
2262
|
|
|
2129
2263
|
// packages/dev-server/src/http-utils.ts
|
|
2130
2264
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
@@ -2245,7 +2379,7 @@ async function buildStaticSite(config, root, opts) {
|
|
|
2245
2379
|
}
|
|
2246
2380
|
const type = res.headers.get("content-type") ?? "";
|
|
2247
2381
|
const target = diskPath(outDir, file);
|
|
2248
|
-
await mkdir3(
|
|
2382
|
+
await mkdir3(dirname5(target), { recursive: true });
|
|
2249
2383
|
if (isText(type)) {
|
|
2250
2384
|
const body = await res.text();
|
|
2251
2385
|
const out = withBasePath(body, basePath);
|
|
@@ -2265,7 +2399,7 @@ async function buildStaticSite(config, root, opts) {
|
|
|
2265
2399
|
if (done.has(file)) return;
|
|
2266
2400
|
done.add(file);
|
|
2267
2401
|
const target = diskPath(outDir, file);
|
|
2268
|
-
await mkdir3(
|
|
2402
|
+
await mkdir3(dirname5(target), { recursive: true });
|
|
2269
2403
|
const out = withBasePath(body, basePath);
|
|
2270
2404
|
await writeFile3(target, out);
|
|
2271
2405
|
report.bytes += Buffer.byteLength(out);
|
|
@@ -2328,7 +2462,13 @@ async function buildStaticSite(config, root, opts) {
|
|
|
2328
2462
|
} else {
|
|
2329
2463
|
log("\u2026 corpus audit left out (build.audit: false / --no-audit)");
|
|
2330
2464
|
}
|
|
2465
|
+
const shadowed = new Map(shadowedAssetRoots(cfg.assetRoots).map((s) => [s.root, s.by]));
|
|
2331
2466
|
for (const [i, rootDir] of cfg.assetRoots.entries()) {
|
|
2467
|
+
const by = shadowed.get(rootDir);
|
|
2468
|
+
if (by !== void 0) {
|
|
2469
|
+
report.warnings.push(`assets: ${relative4(root, rootDir)} is hidden by ${relative4(root, by) || "."}, which has the same folder name; left out`);
|
|
2470
|
+
continue;
|
|
2471
|
+
}
|
|
2332
2472
|
const exists = await stat2(rootDir).then((s) => s.isDirectory(), () => false);
|
|
2333
2473
|
if (!exists) continue;
|
|
2334
2474
|
await cp(rootDir, join11(outDir, "assets", cfg.assetRootNames[i]), { recursive: true });
|
|
@@ -2344,7 +2484,7 @@ async function buildStaticSite(config, root, opts) {
|
|
|
2344
2484
|
const shell = withBasePath(buildShellHtml(runtime), basePath);
|
|
2345
2485
|
for (const route of routes) {
|
|
2346
2486
|
const target = diskPath(outDir, staticPathFor(route));
|
|
2347
|
-
await mkdir3(
|
|
2487
|
+
await mkdir3(dirname5(target), { recursive: true });
|
|
2348
2488
|
await writeFile3(target, shell);
|
|
2349
2489
|
report.files++;
|
|
2350
2490
|
report.bytes += Buffer.byteLength(shell);
|
|
@@ -2358,6 +2498,99 @@ async function buildStaticSite(config, root, opts) {
|
|
|
2358
2498
|
return report;
|
|
2359
2499
|
}
|
|
2360
2500
|
|
|
2501
|
+
// packages/dev-server/src/requires.ts
|
|
2502
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
2503
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
2504
|
+
import { basename as basename4, join as join12, relative as relative5 } from "node:path";
|
|
2505
|
+
function normalizeScriptId(raw) {
|
|
2506
|
+
let s = raw.trim().replace(/^\[(.+)\]$/, "$1").trim();
|
|
2507
|
+
s = basename4(s);
|
|
2508
|
+
s = s.replace(/\.(ts|js)$/, "");
|
|
2509
|
+
return s;
|
|
2510
|
+
}
|
|
2511
|
+
function parseFrontmatterList(md, key) {
|
|
2512
|
+
const values = [];
|
|
2513
|
+
const re = new RegExp(`^${key}:\\s*(.+)$`, "mg");
|
|
2514
|
+
for (const [, val] of md.matchAll(re)) {
|
|
2515
|
+
values.push(val.trim());
|
|
2516
|
+
}
|
|
2517
|
+
return values;
|
|
2518
|
+
}
|
|
2519
|
+
async function aggregateRequires(componentId, patternsDir, flatNameToPath, discoveryMap, visited = /* @__PURE__ */ new Set()) {
|
|
2520
|
+
if (visited.has(componentId)) return { scripts: [], assets: [] };
|
|
2521
|
+
visited.add(componentId);
|
|
2522
|
+
const entry = discoveryMap.get(componentId);
|
|
2523
|
+
let ownScripts = [];
|
|
2524
|
+
let ownAssets = [];
|
|
2525
|
+
if (entry?.mdPath) {
|
|
2526
|
+
try {
|
|
2527
|
+
const md = await readFile8(entry.mdPath, "utf-8");
|
|
2528
|
+
ownScripts = parseFrontmatterList(md, "requireScript").map(normalizeScriptId);
|
|
2529
|
+
ownAssets = parseFrontmatterList(md, "requireAssets").map((v) => v.trim().replace(/^\[(.+)\]$/, "$1").trim());
|
|
2530
|
+
} catch {
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
const allScripts = [...ownScripts];
|
|
2534
|
+
const allAssets = [...ownAssets];
|
|
2535
|
+
const hbsPath = entry?.hbsPath ?? "";
|
|
2536
|
+
let hbs = "";
|
|
2537
|
+
try {
|
|
2538
|
+
hbs = hbsPath ? await readFile8(hbsPath, "utf-8") : "";
|
|
2539
|
+
} catch {
|
|
2540
|
+
}
|
|
2541
|
+
for (const flatName of parsePartialsFromHbs(hbs)) {
|
|
2542
|
+
const childPath = flatNameToPath.get(flatName);
|
|
2543
|
+
if (childPath) {
|
|
2544
|
+
const child = await aggregateRequires(childPath, patternsDir, flatNameToPath, discoveryMap, visited);
|
|
2545
|
+
allScripts.push(...child.scripts);
|
|
2546
|
+
allAssets.push(...child.assets);
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
return {
|
|
2550
|
+
scripts: [...new Set(allScripts)],
|
|
2551
|
+
assets: [...new Set(allAssets)]
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
async function loadSvgAssets(ids, assetsDir) {
|
|
2555
|
+
const contents = [];
|
|
2556
|
+
for (const id of ids) {
|
|
2557
|
+
for (const candidate of [`${id}.svg`, `images/${id}.svg`]) {
|
|
2558
|
+
try {
|
|
2559
|
+
const raw = await readFile8(join12(assetsDir, candidate), "utf-8");
|
|
2560
|
+
contents.push(hideSvg(raw));
|
|
2561
|
+
break;
|
|
2562
|
+
} catch {
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
return contents;
|
|
2567
|
+
}
|
|
2568
|
+
function hideSvg(svg) {
|
|
2569
|
+
return svg.replace(/<svg(\s|>)/, '<svg$1style="display:none;position:absolute" aria-hidden="true" ');
|
|
2570
|
+
}
|
|
2571
|
+
async function reportUnresolvableScripts(discoveryMap, scriptsDirs, globalScripts, cwd) {
|
|
2572
|
+
const resolves = (id) => scriptsDirs.some((d) => existsSync4(join12(d, `${id}.ts`)));
|
|
2573
|
+
const where = scriptsDirs.length ? scriptsDirs.map((d) => relative5(cwd, d) || d).join(" or ") : "no scriptsDir configured";
|
|
2574
|
+
for (const id of globalScripts) {
|
|
2575
|
+
if (id.includes("://") || resolves(normalizeScriptId(id))) continue;
|
|
2576
|
+
console.warn(`[dev-server] globalScripts "${id}": no ${normalizeScriptId(id)}.ts in ${where}`);
|
|
2577
|
+
}
|
|
2578
|
+
for (const [componentId, entry] of discoveryMap) {
|
|
2579
|
+
if (!entry.mdPath) continue;
|
|
2580
|
+
let md;
|
|
2581
|
+
try {
|
|
2582
|
+
md = await readFile8(entry.mdPath, "utf-8");
|
|
2583
|
+
} catch {
|
|
2584
|
+
continue;
|
|
2585
|
+
}
|
|
2586
|
+
for (const raw of parseFrontmatterList(md, "requireScript")) {
|
|
2587
|
+
const id = normalizeScriptId(raw);
|
|
2588
|
+
if (resolves(id)) continue;
|
|
2589
|
+
console.warn(`[dev-server] requireScript "${raw}" on ${componentId}: no ${id}.ts in ${where}`);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2361
2594
|
// packages/dev-server/src/server-state.ts
|
|
2362
2595
|
function createServerState() {
|
|
2363
2596
|
return {
|
|
@@ -2399,25 +2632,25 @@ function applyStyleData(state, data) {
|
|
|
2399
2632
|
}
|
|
2400
2633
|
|
|
2401
2634
|
// packages/dev-server/src/routes.ts
|
|
2402
|
-
import { basename as
|
|
2635
|
+
import { basename as basename5, extname as extname2, join as join18, relative as relative6 } from "node:path";
|
|
2403
2636
|
import { readFile as readFile15, stat as stat4 } from "node:fs/promises";
|
|
2404
|
-
import { existsSync as
|
|
2637
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
2405
2638
|
|
|
2406
2639
|
// packages/dev-server/src/component-tree.ts
|
|
2640
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
2641
|
+
import { join as join15 } from "node:path";
|
|
2642
|
+
|
|
2643
|
+
// packages/dev-server/src/layout-mode.ts
|
|
2407
2644
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
2408
2645
|
import { join as join14 } from "node:path";
|
|
2409
2646
|
|
|
2410
|
-
// packages/dev-server/src/
|
|
2647
|
+
// packages/dev-server/src/pattern-dirs.ts
|
|
2411
2648
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
2412
2649
|
import { join as join13 } from "node:path";
|
|
2413
|
-
|
|
2414
|
-
// packages/dev-server/src/pattern-dirs.ts
|
|
2415
|
-
import { readFile as readFile8 } from "node:fs/promises";
|
|
2416
|
-
import { join as join12 } from "node:path";
|
|
2417
2650
|
async function readFolderFile(dirs, rel) {
|
|
2418
2651
|
for (const dir of typeof dirs === "string" ? [dirs] : dirs) {
|
|
2419
2652
|
try {
|
|
2420
|
-
return await
|
|
2653
|
+
return await readFile9(join13(dir, rel), "utf-8");
|
|
2421
2654
|
} catch {
|
|
2422
2655
|
}
|
|
2423
2656
|
}
|
|
@@ -2429,8 +2662,8 @@ var FULL_CATEGORIES = /* @__PURE__ */ new Set(["pages", "templates"]);
|
|
|
2429
2662
|
async function resolveLayoutMode(componentId, patternsDir, discoveryMap) {
|
|
2430
2663
|
const parts = componentId.split("/");
|
|
2431
2664
|
const category = parts[0];
|
|
2432
|
-
let layout = FULL_CATEGORIES.has(category) ? "full" : "centered";
|
|
2433
|
-
const categoryIndex = await readFolderFile(patternsDir,
|
|
2665
|
+
let layout = FULL_CATEGORIES.has(stripOrderPrefixes(category)) ? "full" : "centered";
|
|
2666
|
+
const categoryIndex = await readFolderFile(patternsDir, join14(category, "index.md"));
|
|
2434
2667
|
if (categoryIndex !== null) {
|
|
2435
2668
|
const m = categoryIndex.match(/^preview:\s*(centered|full)$/m);
|
|
2436
2669
|
if (m) layout = m[1];
|
|
@@ -2438,7 +2671,7 @@ async function resolveLayoutMode(componentId, patternsDir, discoveryMap) {
|
|
|
2438
2671
|
const mdPath = discoveryMap?.get(componentId)?.mdPath;
|
|
2439
2672
|
if (mdPath) {
|
|
2440
2673
|
try {
|
|
2441
|
-
const md = await
|
|
2674
|
+
const md = await readFile10(mdPath, "utf-8");
|
|
2442
2675
|
const m = md.match(/^preview:\s*(centered|full)$/m);
|
|
2443
2676
|
if (m) layout = m[1];
|
|
2444
2677
|
} catch {
|
|
@@ -2531,7 +2764,7 @@ function folderTitle(segment) {
|
|
|
2531
2764
|
const text = words.join(" ");
|
|
2532
2765
|
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
2533
2766
|
}
|
|
2534
|
-
var readText = (path) =>
|
|
2767
|
+
var readText = (path) => readFile11(path, "utf-8").catch(() => null);
|
|
2535
2768
|
function orderOf(md) {
|
|
2536
2769
|
return md === null ? void 0 : parseOrder(readFrontmatter(md)["order"]);
|
|
2537
2770
|
}
|
|
@@ -2582,7 +2815,7 @@ async function buildTreeNodeFromMap(nodePath, idsUnderPath, patternsDir, overvie
|
|
|
2582
2815
|
if (o && "weight" in o) weight = o.weight;
|
|
2583
2816
|
}
|
|
2584
2817
|
}
|
|
2585
|
-
const indexMd = await readFolderFile(patternsDir,
|
|
2818
|
+
const indexMd = await readFolderFile(patternsDir, join15(nodePath, "index.md"));
|
|
2586
2819
|
const folderOrder = orderOf(indexMd);
|
|
2587
2820
|
const built = [];
|
|
2588
2821
|
for (const childPath of directChildPaths(nodePath, idsUnderPath)) {
|
|
@@ -2630,7 +2863,7 @@ async function buildTreeNodeFromMap(nodePath, idsUnderPath, patternsDir, overvie
|
|
|
2630
2863
|
import { readFile as readFile14 } from "node:fs/promises";
|
|
2631
2864
|
|
|
2632
2865
|
// packages/dev-server/src/markdown.ts
|
|
2633
|
-
import { readFile as
|
|
2866
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
2634
2867
|
import MarkdownIt from "markdown-it";
|
|
2635
2868
|
var _md = new MarkdownIt({ html: false, linkify: false });
|
|
2636
2869
|
_md.validateLink = (url) => {
|
|
@@ -2719,7 +2952,7 @@ async function _resolveFence(info, content, idx, renderComponent, out, discovery
|
|
|
2719
2952
|
return;
|
|
2720
2953
|
}
|
|
2721
2954
|
try {
|
|
2722
|
-
const src = await
|
|
2955
|
+
const src = await readFile12(entry.hbsPath, "utf-8");
|
|
2723
2956
|
out.set(idx, wrapWithCopyButton(highlight(src, "handlebars"), src));
|
|
2724
2957
|
} catch (e) {
|
|
2725
2958
|
console.warn(`[dev-server] src-template read error [${spec}]:`, e);
|
|
@@ -2744,8 +2977,8 @@ async function _resolveFence(info, content, idx, renderComponent, out, discovery
|
|
|
2744
2977
|
}
|
|
2745
2978
|
const baseJsonPath = discoveryMap.get(compId)?.jsonPath;
|
|
2746
2979
|
const variantJsonPath = variantEntry.jsonPath;
|
|
2747
|
-
const baseData = baseJsonPath ? JSON.parse(await
|
|
2748
|
-
const variantData = variantJsonPath ? JSON.parse(await
|
|
2980
|
+
const baseData = baseJsonPath ? JSON.parse(await readFile12(baseJsonPath, "utf-8")) : {};
|
|
2981
|
+
const variantData = variantJsonPath ? JSON.parse(await readFile12(variantJsonPath, "utf-8")) : {};
|
|
2749
2982
|
const merged = deepMerge(structuredClone(baseData), variantData);
|
|
2750
2983
|
const src = JSON.stringify(merged, null, 2);
|
|
2751
2984
|
out.set(idx, wrapWithCopyButton(highlight(src, "json"), src));
|
|
@@ -2755,7 +2988,7 @@ async function _resolveFence(info, content, idx, renderComponent, out, discovery
|
|
|
2755
2988
|
out.set(idx, `<p class="doc-error">[src-data: ${escapeHtml(spec)} \u2014 no data file]</p>`);
|
|
2756
2989
|
return;
|
|
2757
2990
|
}
|
|
2758
|
-
const src = await
|
|
2991
|
+
const src = await readFile12(jsonPath, "utf-8");
|
|
2759
2992
|
out.set(idx, wrapWithCopyButton(highlight(src, "json"), src));
|
|
2760
2993
|
}
|
|
2761
2994
|
} catch (e) {
|
|
@@ -2785,8 +3018,8 @@ async function _resolveFence(info, content, idx, renderComponent, out, discovery
|
|
|
2785
3018
|
}
|
|
2786
3019
|
|
|
2787
3020
|
// packages/dev-server/src/css-closure.ts
|
|
2788
|
-
import { readFile as
|
|
2789
|
-
import { dirname as
|
|
3021
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
3022
|
+
import { dirname as dirname6, resolve as resolve7 } from "node:path";
|
|
2790
3023
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
2791
3024
|
import postcss4 from "postcss";
|
|
2792
3025
|
import * as sass3 from "sass";
|
|
@@ -2794,7 +3027,7 @@ import { SourceMapConsumer as SourceMapConsumer2 } from "source-map";
|
|
|
2794
3027
|
import { parse as parseHtml2 } from "node-html-parser";
|
|
2795
3028
|
async function recomputeComponentCss(entryFile, compId, stylesDir, componentIds, inBase = () => false) {
|
|
2796
3029
|
try {
|
|
2797
|
-
const compiled = sass3.compile(entryFile, { sourceMap: true });
|
|
3030
|
+
const compiled = sass3.compile(entryFile, { sourceMap: true, ...sassPackageOptions(entryFile) });
|
|
2798
3031
|
const rawMap = compiled.sourceMap;
|
|
2799
3032
|
if (!rawMap) return null;
|
|
2800
3033
|
const consumer = new SourceMapConsumer2(rawMap);
|
|
@@ -2805,10 +3038,10 @@ async function recomputeComponentCss(entryFile, compId, stylesDir, componentIds,
|
|
|
2805
3038
|
if (!pos) return;
|
|
2806
3039
|
const original = consumer.originalPositionFor({ line: pos.line, column: pos.column - 1 });
|
|
2807
3040
|
if (!original.source) return;
|
|
2808
|
-
const originPath = original.source.startsWith("file://") ? fileURLToPath3(original.source) : resolve7(
|
|
3041
|
+
const originPath = original.source.startsWith("file://") ? fileURLToPath3(original.source) : resolve7(dirname6(entryFile), original.source);
|
|
2809
3042
|
if (inBase(originPath)) return;
|
|
2810
3043
|
const originComp = resolveScssToComponent(originPath, stylesDir, componentIds);
|
|
2811
|
-
if (originComp === compId) bucket
|
|
3044
|
+
if (originComp === compId) addLastOccurrence(bucket, cssNodeText(node));
|
|
2812
3045
|
});
|
|
2813
3046
|
return joinCssChunks(bucket);
|
|
2814
3047
|
} catch {
|
|
@@ -2825,7 +3058,7 @@ async function computeCssClosure(componentId, compReg, patternsDir, classOwnerIn
|
|
|
2825
3058
|
const hbsPath = discoveryMap.get(id)?.hbsPath ?? "";
|
|
2826
3059
|
let hbs = "";
|
|
2827
3060
|
try {
|
|
2828
|
-
hbs = hbsPath ? await
|
|
3061
|
+
hbs = hbsPath ? await readFile13(hbsPath, "utf-8") : "";
|
|
2829
3062
|
} catch {
|
|
2830
3063
|
}
|
|
2831
3064
|
const { styleUses } = deriveClassBorrowingFields(hbs, id, classOwnerIndex);
|
|
@@ -2881,76 +3114,6 @@ function linkableClosure(closureIds, perComponentCss) {
|
|
|
2881
3114
|
return closureIds.filter((id) => !!perComponentCss.get(id));
|
|
2882
3115
|
}
|
|
2883
3116
|
|
|
2884
|
-
// packages/dev-server/src/requires.ts
|
|
2885
|
-
import { readFile as readFile13 } from "node:fs/promises";
|
|
2886
|
-
import { join as join15, basename as basename3 } from "node:path";
|
|
2887
|
-
function normalizeScriptId(raw) {
|
|
2888
|
-
let s = raw.trim().replace(/^\[(.+)\]$/, "$1").trim();
|
|
2889
|
-
s = basename3(s);
|
|
2890
|
-
s = s.replace(/\.(ts|js)$/, "");
|
|
2891
|
-
return s;
|
|
2892
|
-
}
|
|
2893
|
-
function parseFrontmatterList(md, key) {
|
|
2894
|
-
const values = [];
|
|
2895
|
-
const re = new RegExp(`^${key}:\\s*(.+)$`, "mg");
|
|
2896
|
-
for (const [, val] of md.matchAll(re)) {
|
|
2897
|
-
values.push(val.trim());
|
|
2898
|
-
}
|
|
2899
|
-
return values;
|
|
2900
|
-
}
|
|
2901
|
-
async function aggregateRequires(componentId, patternsDir, flatNameToPath, discoveryMap, visited = /* @__PURE__ */ new Set()) {
|
|
2902
|
-
if (visited.has(componentId)) return { scripts: [], assets: [] };
|
|
2903
|
-
visited.add(componentId);
|
|
2904
|
-
const entry = discoveryMap.get(componentId);
|
|
2905
|
-
let ownScripts = [];
|
|
2906
|
-
let ownAssets = [];
|
|
2907
|
-
if (entry?.mdPath) {
|
|
2908
|
-
try {
|
|
2909
|
-
const md = await readFile13(entry.mdPath, "utf-8");
|
|
2910
|
-
ownScripts = parseFrontmatterList(md, "requireScript").map(normalizeScriptId);
|
|
2911
|
-
ownAssets = parseFrontmatterList(md, "requireAssets").map((v) => v.trim().replace(/^\[(.+)\]$/, "$1").trim());
|
|
2912
|
-
} catch {
|
|
2913
|
-
}
|
|
2914
|
-
}
|
|
2915
|
-
const allScripts = [...ownScripts];
|
|
2916
|
-
const allAssets = [...ownAssets];
|
|
2917
|
-
const hbsPath = entry?.hbsPath ?? "";
|
|
2918
|
-
let hbs = "";
|
|
2919
|
-
try {
|
|
2920
|
-
hbs = hbsPath ? await readFile13(hbsPath, "utf-8") : "";
|
|
2921
|
-
} catch {
|
|
2922
|
-
}
|
|
2923
|
-
for (const flatName of parsePartialsFromHbs(hbs)) {
|
|
2924
|
-
const childPath = flatNameToPath.get(flatName);
|
|
2925
|
-
if (childPath) {
|
|
2926
|
-
const child = await aggregateRequires(childPath, patternsDir, flatNameToPath, discoveryMap, visited);
|
|
2927
|
-
allScripts.push(...child.scripts);
|
|
2928
|
-
allAssets.push(...child.assets);
|
|
2929
|
-
}
|
|
2930
|
-
}
|
|
2931
|
-
return {
|
|
2932
|
-
scripts: [...new Set(allScripts)],
|
|
2933
|
-
assets: [...new Set(allAssets)]
|
|
2934
|
-
};
|
|
2935
|
-
}
|
|
2936
|
-
async function loadSvgAssets(ids, assetsDir) {
|
|
2937
|
-
const contents = [];
|
|
2938
|
-
for (const id of ids) {
|
|
2939
|
-
for (const candidate of [`${id}.svg`, `images/${id}.svg`]) {
|
|
2940
|
-
try {
|
|
2941
|
-
const raw = await readFile13(join15(assetsDir, candidate), "utf-8");
|
|
2942
|
-
contents.push(hideSvg(raw));
|
|
2943
|
-
break;
|
|
2944
|
-
} catch {
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
|
-
return contents;
|
|
2949
|
-
}
|
|
2950
|
-
function hideSvg(svg) {
|
|
2951
|
-
return svg.replace(/<svg(\s|>)/, '<svg$1style="display:none;position:absolute" aria-hidden="true" ');
|
|
2952
|
-
}
|
|
2953
|
-
|
|
2954
3117
|
// packages/dev-server/src/detail.ts
|
|
2955
3118
|
async function buildComponentDetail(componentId, patternsDir, renderFn, tracker, defaultTheme, flatNameToPath, compositionReg, scssGraph, classOwnerIndex, discoveryMap, baseProvenance) {
|
|
2956
3119
|
const parts = componentId.split("/");
|
|
@@ -3075,7 +3238,7 @@ async function buildComponentDetail(componentId, patternsDir, renderFn, tracker,
|
|
|
3075
3238
|
import { join as join16 } from "node:path";
|
|
3076
3239
|
async function buildFolderOverview(folderPath, patternsDir, renderFn, discoveryMap) {
|
|
3077
3240
|
const category = folderPath.split("/")[0];
|
|
3078
|
-
let folderLayout = FULL_CATEGORIES.has(category) ? "full" : "centered";
|
|
3241
|
+
let folderLayout = FULL_CATEGORIES.has(stripOrderPrefixes(category)) ? "full" : "centered";
|
|
3079
3242
|
let doc;
|
|
3080
3243
|
try {
|
|
3081
3244
|
const rawIndex = await readFolderFile(patternsDir, join16(folderPath, "index.md"));
|
|
@@ -3214,10 +3377,10 @@ function normalizeAssetRefs(text, rootNames) {
|
|
|
3214
3377
|
}
|
|
3215
3378
|
|
|
3216
3379
|
// packages/dev-server/src/assets.ts
|
|
3217
|
-
import { existsSync as
|
|
3380
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
3218
3381
|
import { createRequire as createRequire2 } from "node:module";
|
|
3219
3382
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
3220
|
-
function resolveDevUiDist(moduleUrl, exists =
|
|
3383
|
+
function resolveDevUiDist(moduleUrl, exists = existsSync5) {
|
|
3221
3384
|
const packaged = fileURLToPath4(new URL("./dev-ui/", moduleUrl));
|
|
3222
3385
|
if (exists(`${packaged}main.js`)) return packaged;
|
|
3223
3386
|
return fileURLToPath4(new URL("../../../apps/dev-ui/dist/", moduleUrl));
|
|
@@ -3290,7 +3453,7 @@ async function handleRequest(req, res, ctx) {
|
|
|
3290
3453
|
return;
|
|
3291
3454
|
}
|
|
3292
3455
|
const themeName = decodeURIComponent(
|
|
3293
|
-
|
|
3456
|
+
basename5(pathname, ".css")
|
|
3294
3457
|
);
|
|
3295
3458
|
if (state.themeCss.has(themeName)) {
|
|
3296
3459
|
res.writeHead(200, { "Content-Type": "text/css" });
|
|
@@ -3307,10 +3470,15 @@ async function handleRequest(req, res, ctx) {
|
|
|
3307
3470
|
res.end("No scriptsDir configured");
|
|
3308
3471
|
return;
|
|
3309
3472
|
}
|
|
3310
|
-
const scriptId = normalizeScriptId(decodeURIComponent(
|
|
3473
|
+
const scriptId = normalizeScriptId(decodeURIComponent(basename5(pathname, ".js")));
|
|
3311
3474
|
try {
|
|
3312
3475
|
if (!state.scriptCache.has(scriptId)) {
|
|
3313
|
-
const entryPoint = scriptsDirs.map((d) => join18(d, `${scriptId}.ts`)).find((f) =>
|
|
3476
|
+
const entryPoint = scriptsDirs.map((d) => join18(d, `${scriptId}.ts`)).find((f) => existsSync6(f));
|
|
3477
|
+
if (entryPoint === void 0) {
|
|
3478
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
3479
|
+
res.end(`No script "${scriptId}": scripts are TypeScript, so ${scriptId}.ts is expected in ` + scriptsDirs.map((d) => relative6(cwd, d) || d).join(" or "));
|
|
3480
|
+
return;
|
|
3481
|
+
}
|
|
3314
3482
|
const js = await compileScriptFile(entryPoint);
|
|
3315
3483
|
state.scriptCache.set(scriptId, js);
|
|
3316
3484
|
}
|
|
@@ -3594,12 +3762,12 @@ function describeBindError(e, port2, role, ports) {
|
|
|
3594
3762
|
}
|
|
3595
3763
|
|
|
3596
3764
|
// packages/dev-server/src/watch.ts
|
|
3597
|
-
import { basename as
|
|
3765
|
+
import { basename as basename6, extname as extname3, relative as relative7, resolve as resolve8 } from "node:path";
|
|
3598
3766
|
import chokidar from "chokidar";
|
|
3599
3767
|
function startWatching(ctx) {
|
|
3600
3768
|
const { cfg, state, render, tracker, hotreloader } = ctx;
|
|
3601
3769
|
const { patternsDir, stylesDir, styleRoots, patternRoots, patternDirs, swatchSlots, cwd } = cfg;
|
|
3602
|
-
const themesDir = cfg.config.themes ? cfg.themesDir : null;
|
|
3770
|
+
const themesDir = cfg.config.themes?.dir ? cfg.themesDir : null;
|
|
3603
3771
|
const scriptsDir = cfg.config.scriptsDir ? cfg.scriptsDirs[0] ?? null : null;
|
|
3604
3772
|
const inProjectBase = documentBaseMatcher(stylesDir, cfg.config.documentBase);
|
|
3605
3773
|
const watchDirs = [patternsDir, stylesDir, ...themesDir ? [themesDir] : [], ...scriptsDir ? [scriptsDir] : []];
|
|
@@ -3618,7 +3786,7 @@ function startWatching(ctx) {
|
|
|
3618
3786
|
hotreloader.push({
|
|
3619
3787
|
type: "error",
|
|
3620
3788
|
scope: "build",
|
|
3621
|
-
message: `SCSS ${
|
|
3789
|
+
message: `SCSS ${basename6(file)} \u2014 ${message.split("\n")[0]}`
|
|
3622
3790
|
});
|
|
3623
3791
|
}
|
|
3624
3792
|
state.scssGraphDirty = true;
|
|
@@ -3663,10 +3831,10 @@ function startWatching(ctx) {
|
|
|
3663
3831
|
}
|
|
3664
3832
|
const orderedHrefs = await closureHrefs(timestamp);
|
|
3665
3833
|
for (const m of pending) hotreloader.push({ ...m, orderedHrefs });
|
|
3666
|
-
console.log(`[dev-server] CSS updated (recompiled: ${effectiveFiles.map((f) =>
|
|
3834
|
+
console.log(`[dev-server] CSS updated (recompiled: ${effectiveFiles.map((f) => basename6(f)).join(", ")})`);
|
|
3667
3835
|
}
|
|
3668
3836
|
async function restyleAll(allIds, timestamp, files, hadCompileErrors) {
|
|
3669
|
-
const names = files.map((f) =>
|
|
3837
|
+
const names = files.map((f) => basename6(f)).join(", ");
|
|
3670
3838
|
if (hadCompileErrors) {
|
|
3671
3839
|
console.warn(`[dev-server] CSS not updated \u2014 compile errors (recompiled: ${names})`);
|
|
3672
3840
|
return;
|
|
@@ -3706,7 +3874,7 @@ function startWatching(ctx) {
|
|
|
3706
3874
|
}
|
|
3707
3875
|
return void 0;
|
|
3708
3876
|
};
|
|
3709
|
-
const rel =
|
|
3877
|
+
const rel = relative7(patternsDir, filePath);
|
|
3710
3878
|
if (event === "change") state.discoveryResult ??= await buildDiscoveryMap(patternRoots);
|
|
3711
3879
|
let owner = ownerIn(state.discoveryResult);
|
|
3712
3880
|
if (event === "change") {
|
|
@@ -3728,7 +3896,7 @@ function startWatching(ctx) {
|
|
|
3728
3896
|
}
|
|
3729
3897
|
if (ext === ".scss") {
|
|
3730
3898
|
if (themesDir && filePath.startsWith(themesDir)) {
|
|
3731
|
-
const themeName =
|
|
3899
|
+
const themeName = basename6(filePath, ".theme.scss");
|
|
3732
3900
|
try {
|
|
3733
3901
|
const css = await compileSassFile(filePath);
|
|
3734
3902
|
state.themeCss.set(themeName, css);
|
|
@@ -3764,7 +3932,7 @@ function startWatching(ctx) {
|
|
|
3764
3932
|
if (verboseTiming) console.log(`[dev-server:timing] diagnostics: live re-audit ${componentId} (1 component; total ${state.liveReauditCount})`);
|
|
3765
3933
|
}
|
|
3766
3934
|
} else if (ext === ".ts" && scriptsDir && filePath.startsWith(scriptsDir)) {
|
|
3767
|
-
const scriptId =
|
|
3935
|
+
const scriptId = basename6(filePath, ".ts");
|
|
3768
3936
|
state.scriptCache.delete(scriptId);
|
|
3769
3937
|
if (state.lastComponentId) {
|
|
3770
3938
|
hotreloader.push({ type: "content-swap", componentId: state.lastComponentId });
|
|
@@ -3788,21 +3956,21 @@ function startWatching(ctx) {
|
|
|
3788
3956
|
if (ext === ".scss" && !(themesDir && filePath.startsWith(themesDir))) {
|
|
3789
3957
|
await handleComponentScss(filePath);
|
|
3790
3958
|
} else if (ext === ".hbs" && filePath.startsWith(patternsDir)) {
|
|
3791
|
-
await rebuildAndSignalTree(`Pattern added: ${
|
|
3959
|
+
await rebuildAndSignalTree(`Pattern added: ${relative7(patternsDir, filePath)}`);
|
|
3792
3960
|
} else if (ext === ".md" && filePath.startsWith(patternsDir)) {
|
|
3793
3961
|
await handleMarkdown(filePath, "add");
|
|
3794
3962
|
}
|
|
3795
3963
|
});
|
|
3796
3964
|
watcher.on("unlink", async (filePath) => {
|
|
3797
3965
|
if (extname3(filePath) === ".hbs" && filePath.startsWith(patternsDir)) {
|
|
3798
|
-
await rebuildAndSignalTree(`Pattern removed: ${
|
|
3966
|
+
await rebuildAndSignalTree(`Pattern removed: ${relative7(patternsDir, filePath)}`);
|
|
3799
3967
|
} else if (extname3(filePath) === ".md" && filePath.startsWith(patternsDir)) {
|
|
3800
3968
|
await handleMarkdown(filePath, "unlink");
|
|
3801
3969
|
}
|
|
3802
3970
|
});
|
|
3803
3971
|
watcher.on("unlinkDir", async (dirPath) => {
|
|
3804
3972
|
if (dirPath.startsWith(patternsDir) && dirPath !== patternsDir) {
|
|
3805
|
-
await rebuildAndSignalTree(`Pattern dir removed: ${
|
|
3973
|
+
await rebuildAndSignalTree(`Pattern dir removed: ${relative7(patternsDir, dirPath)}`);
|
|
3806
3974
|
}
|
|
3807
3975
|
});
|
|
3808
3976
|
return watcher;
|
|
@@ -3810,7 +3978,7 @@ function startWatching(ctx) {
|
|
|
3810
3978
|
|
|
3811
3979
|
// packages/dev-server/src/export-io.ts
|
|
3812
3980
|
import { readFile as readFile16, writeFile as writeFile4, mkdir as mkdir4 } from "node:fs/promises";
|
|
3813
|
-
import { dirname as
|
|
3981
|
+
import { dirname as dirname7, join as join19, relative as relative8, resolve as resolve9 } from "node:path";
|
|
3814
3982
|
|
|
3815
3983
|
// packages/dev-server/src/export.ts
|
|
3816
3984
|
var escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -3960,7 +4128,7 @@ async function planExport(config, cwd) {
|
|
|
3960
4128
|
const hbs = await readFile16(entry.hbsPath, "utf-8");
|
|
3961
4129
|
inputs.push({ id, hbs });
|
|
3962
4130
|
hbsById.set(id, hbs);
|
|
3963
|
-
relPathById.set(id,
|
|
4131
|
+
relPathById.set(id, relative8(patternsDir, entry.hbsPath).replace(/\.hbs$/, ""));
|
|
3964
4132
|
if (entry.jsonPath) {
|
|
3965
4133
|
try {
|
|
3966
4134
|
dataJsonById.set(id, await readFile16(entry.jsonPath, "utf-8"));
|
|
@@ -4004,7 +4172,7 @@ async function writeExport(families, sink) {
|
|
|
4004
4172
|
for (const family of families) {
|
|
4005
4173
|
const baseRel = `${family.baseId}.hbs`;
|
|
4006
4174
|
const basePath = join19(sink, baseRel);
|
|
4007
|
-
await mkdir4(
|
|
4175
|
+
await mkdir4(dirname7(basePath), { recursive: true });
|
|
4008
4176
|
await writeFile4(basePath, family.baseHbs, "utf-8");
|
|
4009
4177
|
files.push(baseRel);
|
|
4010
4178
|
if (family.baseData) {
|
|
@@ -4047,9 +4215,9 @@ async function writeThreadedIncluders(threaded, patternsDir, sink) {
|
|
|
4047
4215
|
const res = rewriteIncludes(src, map);
|
|
4048
4216
|
if (res.rewrites === 0) continue;
|
|
4049
4217
|
rewrites += res.rewrites;
|
|
4050
|
-
const rel =
|
|
4218
|
+
const rel = relative8(patternsDir, hbsPath);
|
|
4051
4219
|
const outPath = join19(sink, rel);
|
|
4052
|
-
await mkdir4(
|
|
4220
|
+
await mkdir4(dirname7(outPath), { recursive: true });
|
|
4053
4221
|
await writeFile4(outPath, res.hbs, "utf-8");
|
|
4054
4222
|
files.push(rel);
|
|
4055
4223
|
}
|
|
@@ -4209,7 +4377,7 @@ async function startDevServer(config, cwd, opts = {}) {
|
|
|
4209
4377
|
try {
|
|
4210
4378
|
const css = await compileSassFile(join20(dir, `${name}.theme.scss`));
|
|
4211
4379
|
state.themeCss.set(name, css);
|
|
4212
|
-
const slots = config.themes && dir === cfg.themeDirs[0] ? swatchSlots : cfg.packageSwatchSlots;
|
|
4380
|
+
const slots = config.themes?.dir && dir === cfg.themeDirs[0] ? swatchSlots : cfg.packageSwatchSlots;
|
|
4213
4381
|
state.themeTokens.set(name, await extractThemeTokens(name, css, slots, dir));
|
|
4214
4382
|
} catch (e) {
|
|
4215
4383
|
console.warn(`[dev-server] Theme compile error (${name}):`, e);
|
|
@@ -4218,6 +4386,7 @@ async function startDevServer(config, cwd, opts = {}) {
|
|
|
4218
4386
|
}
|
|
4219
4387
|
}
|
|
4220
4388
|
}
|
|
4389
|
+
surfaceDefaultTheme(cfg.defaultTheme, [...state.themeCss.keys()]);
|
|
4221
4390
|
{
|
|
4222
4391
|
const dr = await buildDiscoveryMap(patternRoots);
|
|
4223
4392
|
state.discoveryResult = dr;
|
|
@@ -4231,6 +4400,8 @@ async function startDevServer(config, cwd, opts = {}) {
|
|
|
4231
4400
|
const styleData = await buildAllStyleData(styleRoots, allComponentIds);
|
|
4232
4401
|
applyStyleData(state, styleData);
|
|
4233
4402
|
surfaceDocumentBase(styleRoots, styleData.baseOutsideList, cwd);
|
|
4403
|
+
surfaceAssetRoots(cfg.assetRoots, cwd);
|
|
4404
|
+
await reportUnresolvableScripts(dr.discoveryMap, cfg.scriptsDirs, cfg.globalScripts, cwd);
|
|
4234
4405
|
}
|
|
4235
4406
|
const boot = {
|
|
4236
4407
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4271,9 +4442,9 @@ async function startDevServer(config, cwd, opts = {}) {
|
|
|
4271
4442
|
|
|
4272
4443
|
// packages/core/src/index.ts
|
|
4273
4444
|
import { build as esbuild } from "esbuild";
|
|
4274
|
-
import { existsSync as
|
|
4445
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
4275
4446
|
import { readFile as readFile17, writeFile as writeFile5, unlink, mkdir as mkdir5 } from "node:fs/promises";
|
|
4276
|
-
import { join as join21, dirname as
|
|
4447
|
+
import { join as join21, dirname as dirname8, resolve as resolve10, relative as relative9, isAbsolute } from "node:path";
|
|
4277
4448
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
4278
4449
|
import { createHash as createHash3 } from "node:crypto";
|
|
4279
4450
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
@@ -4301,7 +4472,7 @@ async function runAudit(root, configPath, format = "md") {
|
|
|
4301
4472
|
const { graph, reaudited, reused, artifactPath } = await runDiagnosticsAudit(config, root);
|
|
4302
4473
|
const report = formatAudit(graph, format);
|
|
4303
4474
|
const ext = format === "json" ? "json" : format === "text" ? "txt" : "md";
|
|
4304
|
-
const reportPath = join21(
|
|
4475
|
+
const reportPath = join21(dirname8(artifactPath), `diagnostics-report.${ext}`);
|
|
4305
4476
|
await writeFile5(reportPath, report, "utf-8");
|
|
4306
4477
|
console.log(report);
|
|
4307
4478
|
const affected = new Set(graph.occurrences.map((o) => o.component)).size;
|
|
@@ -4316,7 +4487,7 @@ function defaultExportDir(root) {
|
|
|
4316
4487
|
return join21(tmpdir2(), "pattern-dump", key, "export");
|
|
4317
4488
|
}
|
|
4318
4489
|
function assertOutsideRoot(outDir, root) {
|
|
4319
|
-
const rel =
|
|
4490
|
+
const rel = relative9(resolve10(root), resolve10(outDir));
|
|
4320
4491
|
const inside = rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
4321
4492
|
if (inside) {
|
|
4322
4493
|
throw new Error(
|
|
@@ -4387,14 +4558,14 @@ async function runExport(root, configPath, outDir) {
|
|
|
4387
4558
|
}
|
|
4388
4559
|
async function loadConfig(root, configPath) {
|
|
4389
4560
|
if (configPath) {
|
|
4390
|
-
if (!
|
|
4561
|
+
if (!existsSync7(configPath)) {
|
|
4391
4562
|
throw new ConfigError(`--config file not found: ${configPath}`);
|
|
4392
4563
|
}
|
|
4393
4564
|
return validateConfig(await readConfigFile(configPath), configPath);
|
|
4394
4565
|
}
|
|
4395
4566
|
for (const name of ["pattern-dump.config.ts", "pattern-dump.config.json"]) {
|
|
4396
4567
|
const path = join21(root, name);
|
|
4397
|
-
if (
|
|
4568
|
+
if (existsSync7(path)) return validateConfig(await readConfigFile(path), name);
|
|
4398
4569
|
}
|
|
4399
4570
|
throw new ConfigError(
|
|
4400
4571
|
`No pattern-dump.config.ts or pattern-dump.config.json found in ${root} (and no --config given)`
|
|
@@ -4609,14 +4780,14 @@ var USAGE = `Usage: pd <command> [options]
|
|
|
4609
4780
|
help [command] Show this help`;
|
|
4610
4781
|
|
|
4611
4782
|
// packages/cli/src/init/run.ts
|
|
4612
|
-
import { existsSync as
|
|
4783
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
4613
4784
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
4614
|
-
import { basename as
|
|
4785
|
+
import { basename as basename7, dirname as dirname10, join as join23, relative as relative11, resolve as resolve12 } from "node:path";
|
|
4615
4786
|
|
|
4616
4787
|
// packages/cli/package.json
|
|
4617
4788
|
var package_default = {
|
|
4618
4789
|
name: "@pattern-dump/cli",
|
|
4619
|
-
version: "0.1.0-alpha.
|
|
4790
|
+
version: "0.1.0-alpha.4",
|
|
4620
4791
|
private: true,
|
|
4621
4792
|
description: "The pd command and the published pattern-dump package.",
|
|
4622
4793
|
type: "module",
|
|
@@ -4652,14 +4823,14 @@ var PD_VERSION = package_default.version;
|
|
|
4652
4823
|
|
|
4653
4824
|
// packages/cli/src/init/files.ts
|
|
4654
4825
|
import { mkdir as mkdir6, readdir as readdir5, readFile as readFile18, writeFile as writeFile6 } from "node:fs/promises";
|
|
4655
|
-
import { dirname as
|
|
4826
|
+
import { dirname as dirname9, join as join22, relative as relative10, sep as sep2 } from "node:path";
|
|
4656
4827
|
async function readTemplateDir(dir) {
|
|
4657
4828
|
const out = [];
|
|
4658
4829
|
async function walk(current) {
|
|
4659
4830
|
for (const entry of await readdir5(current, { withFileTypes: true })) {
|
|
4660
4831
|
const full = join22(current, entry.name);
|
|
4661
4832
|
if (entry.isDirectory()) await walk(full);
|
|
4662
|
-
else out.push({ path:
|
|
4833
|
+
else out.push({ path: relative10(dir, full).split(sep2).join("/"), content: await readFile18(full, "utf8") });
|
|
4663
4834
|
}
|
|
4664
4835
|
}
|
|
4665
4836
|
await walk(dir);
|
|
@@ -4676,7 +4847,7 @@ async function applyPlan(target, plan) {
|
|
|
4676
4847
|
await mkdir6(target, { recursive: true });
|
|
4677
4848
|
for (const file of plan.writes) {
|
|
4678
4849
|
const abs = join22(target, file.path);
|
|
4679
|
-
await mkdir6(
|
|
4850
|
+
await mkdir6(dirname9(abs), { recursive: true });
|
|
4680
4851
|
await writeFile6(abs, file.content, { flag: "wx" });
|
|
4681
4852
|
}
|
|
4682
4853
|
await writeFile6(join22(target, "package.json"), plan.packageJson.content);
|
|
@@ -4759,12 +4930,12 @@ function mergePackageJson(current, answers, packageName) {
|
|
|
4759
4930
|
function dependencySpec(pdSource, cwd) {
|
|
4760
4931
|
if (pdSource === void 0) return `^${PD_VERSION}`;
|
|
4761
4932
|
const asPath = resolve12(cwd, pdSource);
|
|
4762
|
-
if (
|
|
4933
|
+
if (existsSync8(asPath)) return `file:${asPath}`;
|
|
4763
4934
|
return pdSource.startsWith(`${PD_PACKAGE_NAME}@`) ? pdSource.slice(PD_PACKAGE_NAME.length + 1) : pdSource;
|
|
4764
4935
|
}
|
|
4765
4936
|
async function insideGitRepo(target, io) {
|
|
4766
4937
|
let dir = target;
|
|
4767
|
-
while (!
|
|
4938
|
+
while (!existsSync8(dir) && dirname10(dir) !== dir) dir = dirname10(dir);
|
|
4768
4939
|
return await io.run("git", ["rev-parse", "--is-inside-work-tree"], dir) === 0;
|
|
4769
4940
|
}
|
|
4770
4941
|
async function runInit(cmd, io) {
|
|
@@ -4789,7 +4960,7 @@ async function runInit(cmd, io) {
|
|
|
4789
4960
|
}
|
|
4790
4961
|
const pkgPath = join23(target, "package.json");
|
|
4791
4962
|
let packageJson = null;
|
|
4792
|
-
if (
|
|
4963
|
+
if (existsSync8(pkgPath)) {
|
|
4793
4964
|
try {
|
|
4794
4965
|
packageJson = JSON.parse(await readFile19(pkgPath, "utf8"));
|
|
4795
4966
|
} catch (e) {
|
|
@@ -4799,7 +4970,7 @@ async function runInit(cmd, io) {
|
|
|
4799
4970
|
}
|
|
4800
4971
|
const prompt = io.interactive && !cmd.yes;
|
|
4801
4972
|
const existingName = typeof packageJson?.name === "string" ? packageJson.name : void 0;
|
|
4802
|
-
const name = cmd.name ?? (prompt ? await io.ask("Project name", existingName ?? toPackageName(
|
|
4973
|
+
const name = cmd.name ?? (prompt ? await io.ask("Project name", existingName ?? toPackageName(basename7(target))) : existingName ?? toPackageName(basename7(target)));
|
|
4803
4974
|
const brand = cmd.brand ?? (prompt ? await io.ask("Title in the Nav Rail", name) : name);
|
|
4804
4975
|
const examples = cmd.examples ?? (prompt ? await io.confirm("Include starter components", true) : true);
|
|
4805
4976
|
const gitDefault = !await insideGitRepo(target, io);
|
|
@@ -4807,14 +4978,14 @@ async function runInit(cmd, io) {
|
|
|
4807
4978
|
const install = cmd.install ?? (prompt ? await io.confirm("Run npm install", true) : true);
|
|
4808
4979
|
const answers = { name, brand, examples, dependency };
|
|
4809
4980
|
const templates = await readTemplates(io.templatesDir);
|
|
4810
|
-
const result = planInit(templates, answers, { packageJson, exists: (p) =>
|
|
4981
|
+
const result = planInit(templates, answers, { packageJson, exists: (p) => existsSync8(join23(target, p)) }, PD_PACKAGE_NAME);
|
|
4811
4982
|
if (!result.ok) {
|
|
4812
4983
|
io.log(`\u2717 ${result.reason}`);
|
|
4813
4984
|
return 1;
|
|
4814
4985
|
}
|
|
4815
4986
|
const { plan } = result;
|
|
4816
4987
|
await applyPlan(target, plan);
|
|
4817
|
-
const where =
|
|
4988
|
+
const where = relative11(io.cwd, target) || ".";
|
|
4818
4989
|
io.log(`\u2713 ${plan.writes.length} files written to ${where}`);
|
|
4819
4990
|
io.log(`\u2713 package.json ${plan.packageJson.created ? "created" : "updated"} \u2014 ${PD_PACKAGE_NAME} ${answers.dependency}`);
|
|
4820
4991
|
for (const note of plan.packageJson.notes) io.log(` \xB7 ${note}`);
|
|
@@ -4847,7 +5018,7 @@ async function runInit(cmd, io) {
|
|
|
4847
5018
|
}
|
|
4848
5019
|
|
|
4849
5020
|
// packages/cli/src/init/local-build.ts
|
|
4850
|
-
import { existsSync as
|
|
5021
|
+
import { existsSync as existsSync9, statSync } from "node:fs";
|
|
4851
5022
|
import { join as join24 } from "node:path";
|
|
4852
5023
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
4853
5024
|
var BUILT = [
|
|
@@ -4866,9 +5037,9 @@ var mtime = (path) => {
|
|
|
4866
5037
|
};
|
|
4867
5038
|
function detectLocalBuild(moduleUrl, packageName, version) {
|
|
4868
5039
|
const repo = fileURLToPath6(new URL("../../../", moduleUrl)).replace(/[\\/]$/, "");
|
|
4869
|
-
if (!
|
|
5040
|
+
if (!existsSync9(join24(repo, "packages/cli/src/distribution.ts"))) return null;
|
|
4870
5041
|
const tarball = join24(repo, ".pd-pack", `${packageName}-${version}.tgz`);
|
|
4871
|
-
if (!
|
|
5042
|
+
if (!existsSync9(tarball)) return { repo, tarball: null, stale: false };
|
|
4872
5043
|
const newestBuild = Math.max(...BUILT.map((p) => mtime(join24(repo, p))));
|
|
4873
5044
|
return { repo, tarball, stale: newestBuild > mtime(tarball) };
|
|
4874
5045
|
}
|