@parity-app/cli 0.6.1 → 0.6.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/dist/bin.mjs +9 -14
- package/dist/{client-CoW-KcnT.mjs → client-C4An81o9.mjs} +1 -1
- package/dist/index.mjs +1 -1
- package/dist/schema-CiVy9tZT.mjs +227 -0
- package/dist/src-AKjejfTT.mjs +4 -0
- package/dist/src-B40wy5fK.mjs +1 -0
- package/dist/{src-Zm_PYFFH.mjs → src-C5-HaJcA.mjs} +437 -122
- package/dist/src-DzU4U2rh.mjs +129 -0
- package/dist/{src-C4faIpux.mjs → src-YQY8r4mh.mjs} +64 -8
- package/package.json +1 -1
- package/dist/schema-BpGSCLEu.mjs +0 -113
- package/dist/src-5CrSA_RX.mjs +0 -53
- package/dist/src-Cr8pfFJE.mjs +0 -1
- package/dist/src-p0vFxRBz.mjs +0 -3
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./src-
|
|
1
|
+
import { a as plainObject, i as parseData, n as jsonText, t as finiteNumber } from "./schema-CiVy9tZT.mjs";
|
|
2
|
+
import { D as collectCustomProperties, M as packageManifest, a as applyLibraryEdits, c as isSampleElement, f as parseLibraryEdits, j as lengthToPixels, l as isSampleRender, m as renderSlotOf, p as parseLibraryManifest, s as isMadeValue, u as libraryManifestExtension } from "./src-YQY8r4mh.mjs";
|
|
3
|
+
import { r as readLibraryEdits, s as parseJsonc } from "./src-DzU4U2rh.mjs";
|
|
3
4
|
import { a as publishedVersions, n as packageFile, o as repositoryFiles, r as publishedSource } from "./published-CdXoUgfD.mjs";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import { mkdir, readFile, readdir, realpath, rm, stat, writeFile } from "node:fs/promises";
|
|
6
7
|
import { basename, dirname, extname, join, posix, relative, resolve, sep } from "node:path";
|
|
7
8
|
import { promisify } from "node:util";
|
|
8
9
|
import { createHash } from "node:crypto";
|
|
9
|
-
import { existsSync, realpathSync } from "node:fs";
|
|
10
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
10
11
|
import { homedir } from "node:os";
|
|
12
|
+
import { z } from "zod";
|
|
11
13
|
import { pathToFileURL } from "node:url";
|
|
12
14
|
import ts from "typescript";
|
|
13
15
|
import "semver";
|
|
@@ -526,28 +528,182 @@ function slashes(path) {
|
|
|
526
528
|
return path.replaceAll("\\", "/");
|
|
527
529
|
}
|
|
528
530
|
ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive | ts.TypeFlags.TypeParameter;
|
|
529
|
-
// ../
|
|
530
|
-
/**
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
531
|
+
// ../tokens/src/dtcg-values.ts
|
|
532
|
+
/** A value written as CSS. */
|
|
533
|
+
const css = z.string();
|
|
534
|
+
const colorSpace = z.enum([
|
|
535
|
+
"srgb",
|
|
536
|
+
"srgb-linear",
|
|
537
|
+
"hsl",
|
|
538
|
+
"hwb",
|
|
539
|
+
"lab",
|
|
540
|
+
"lch",
|
|
541
|
+
"oklab",
|
|
542
|
+
"oklch",
|
|
543
|
+
"display-p3",
|
|
544
|
+
"a98-rgb",
|
|
545
|
+
"prophoto-rgb",
|
|
546
|
+
"rec2020",
|
|
547
|
+
"xyz-d65",
|
|
548
|
+
"xyz-d50"
|
|
549
|
+
]);
|
|
550
|
+
const colorObject = z.object({
|
|
551
|
+
colorSpace,
|
|
552
|
+
components: z.array(z.union([finiteNumber, z.literal("none")])).length(3, "expected 3 components"),
|
|
553
|
+
alpha: finiteNumber.min(0).max(1).optional(),
|
|
554
|
+
hex: z.string().regex(/^#[\da-f]{6}$/i, "expected a 6-digit hex color such as #0a0a0a").optional()
|
|
555
|
+
});
|
|
556
|
+
const color = z.union([css, colorObject]);
|
|
557
|
+
const dimensionObject = z.object({
|
|
558
|
+
value: finiteNumber,
|
|
559
|
+
unit: z.string().regex(/^([a-z]+|%)$/i, "expected a unit such as px or rem")
|
|
560
|
+
});
|
|
561
|
+
const dimension = z.union([css, dimensionObject]);
|
|
562
|
+
const duration = z.union([css, z.object({
|
|
563
|
+
value: finiteNumber,
|
|
564
|
+
unit: z.enum(["ms", "s"])
|
|
565
|
+
})]);
|
|
566
|
+
/** A cubic Bézier's x coordinates, which CSS keeps between 0 and 1. */
|
|
567
|
+
const unitInterval = finiteNumber.min(0).max(1);
|
|
568
|
+
const cubicBezier = z.union([css, z.tuple([
|
|
569
|
+
unitInterval,
|
|
570
|
+
finiteNumber,
|
|
571
|
+
unitInterval,
|
|
572
|
+
finiteNumber
|
|
573
|
+
])]);
|
|
574
|
+
const fontFamily = z.union([css, z.array(z.string()).min(1)]);
|
|
575
|
+
const fontWeight = z.union([css, finiteNumber.min(1).max(1e3)]);
|
|
576
|
+
const number = z.union([css, finiteNumber]);
|
|
577
|
+
const strokeStyle = z.union([css, z.object({
|
|
578
|
+
dashArray: z.array(dimension).min(1),
|
|
579
|
+
lineCap: z.enum([
|
|
580
|
+
"round",
|
|
581
|
+
"butt",
|
|
582
|
+
"square"
|
|
583
|
+
])
|
|
584
|
+
})]);
|
|
585
|
+
const border = z.union([css, z.object({
|
|
586
|
+
color,
|
|
587
|
+
width: dimension,
|
|
588
|
+
style: strokeStyle
|
|
589
|
+
})]);
|
|
590
|
+
const transition = z.union([css, z.object({
|
|
591
|
+
duration,
|
|
592
|
+
delay: duration,
|
|
593
|
+
timingFunction: cubicBezier
|
|
594
|
+
})]);
|
|
595
|
+
const shadowLayer = z.object({
|
|
596
|
+
color,
|
|
597
|
+
offsetX: dimension.default("0"),
|
|
598
|
+
offsetY: dimension.default("0"),
|
|
599
|
+
blur: dimension.default("0"),
|
|
600
|
+
spread: dimension.default("0"),
|
|
601
|
+
inset: z.boolean().default(false)
|
|
602
|
+
});
|
|
603
|
+
const shadow = z.union([
|
|
604
|
+
css,
|
|
605
|
+
shadowLayer,
|
|
606
|
+
z.array(z.union([css, shadowLayer])).min(1)
|
|
607
|
+
]);
|
|
608
|
+
const gradient = z.union([css, z.array(z.object({
|
|
609
|
+
color,
|
|
610
|
+
position: finiteNumber
|
|
611
|
+
})).min(1)]);
|
|
612
|
+
const typography = z.union([css, z.object({
|
|
613
|
+
fontFamily,
|
|
614
|
+
fontSize: dimension,
|
|
615
|
+
fontWeight: fontWeight.default("normal"),
|
|
616
|
+
letterSpacing: dimension.optional(),
|
|
617
|
+
lineHeight: z.union([number, dimensionObject]).optional()
|
|
618
|
+
})]);
|
|
619
|
+
border.transform(borderCss), color.transform(colorCss), cubicBezier.transform(cubicBezierCss), dimension.transform(dimensionCss), duration.transform(dimensionCss), fontFamily.transform(fontFamilyCss), fontWeight.transform(String), gradient.transform(gradientCss), number.transform(String), shadow.transform(shadowCss), strokeStyle.transform(strokeStyleCss), transition.transform(transitionCss), typography.transform(typographyCss);
|
|
620
|
+
const colorFunctions = /* @__PURE__ */ new Set([
|
|
621
|
+
"hsl",
|
|
622
|
+
"hwb",
|
|
623
|
+
"lab",
|
|
624
|
+
"lch",
|
|
625
|
+
"oklab",
|
|
626
|
+
"oklch"
|
|
627
|
+
]);
|
|
628
|
+
function colorCss(value) {
|
|
629
|
+
if (typeof value === "string") return value;
|
|
630
|
+
const alpha = value.alpha !== void 0 && value.alpha < 1 ? value.alpha : void 0;
|
|
631
|
+
if (value.hex && alpha === void 0) return value.hex;
|
|
632
|
+
const slash = alpha === void 0 ? "" : ` / ${alpha}`;
|
|
633
|
+
if (value.colorSpace === "srgb") {
|
|
634
|
+
const [r, g, b] = value.components.map((part) => part === "none" ? part : Math.round(part * 255));
|
|
635
|
+
return `rgb(${r} ${g} ${b}${slash})`;
|
|
636
|
+
}
|
|
637
|
+
const components = value.components.join(" ");
|
|
638
|
+
if (colorFunctions.has(value.colorSpace)) return `${value.colorSpace}(${components}${slash})`;
|
|
639
|
+
return `color(${value.colorSpace} ${components}${slash})`;
|
|
640
|
+
}
|
|
641
|
+
function dimensionCss(value) {
|
|
642
|
+
return typeof value === "string" ? value : `${value.value}${value.unit}`;
|
|
643
|
+
}
|
|
644
|
+
function cubicBezierCss(value) {
|
|
645
|
+
return typeof value === "string" ? value : `cubic-bezier(${value.join(", ")})`;
|
|
646
|
+
}
|
|
647
|
+
function fontFamilyCss(value) {
|
|
648
|
+
return typeof value === "string" ? value : value.map(fontName).join(", ");
|
|
649
|
+
}
|
|
650
|
+
function fontName(name) {
|
|
651
|
+
return /^[\w-]+$/.test(name) ? name : `"${name}"`;
|
|
652
|
+
}
|
|
653
|
+
/** A stroke style as CSS: a border can't draw a dash pattern, so one is written as dashed. */
|
|
654
|
+
function strokeStyleCss(value) {
|
|
655
|
+
return typeof value === "string" ? value : "dashed";
|
|
656
|
+
}
|
|
657
|
+
function borderCss(value) {
|
|
658
|
+
if (typeof value === "string") return value;
|
|
659
|
+
return `${dimensionCss(value.width)} ${strokeStyleCss(value.style)} ${colorCss(value.color)}`;
|
|
660
|
+
}
|
|
661
|
+
function transitionCss(value) {
|
|
662
|
+
if (typeof value === "string") return value;
|
|
663
|
+
return `${dimensionCss(value.duration)} ${cubicBezierCss(value.timingFunction)} ${dimensionCss(value.delay)}`;
|
|
664
|
+
}
|
|
665
|
+
function shadowCss(value) {
|
|
666
|
+
if (typeof value === "string") return value;
|
|
667
|
+
return (Array.isArray(value) ? value : [value]).map((layer) => typeof layer === "string" ? layer : shadowLayerCss(layer)).join(", ");
|
|
668
|
+
}
|
|
669
|
+
function shadowLayerCss(layer) {
|
|
670
|
+
const lengths = [
|
|
671
|
+
layer.offsetX,
|
|
672
|
+
layer.offsetY,
|
|
673
|
+
layer.blur,
|
|
674
|
+
layer.spread
|
|
675
|
+
].map(dimensionCss).join(" ");
|
|
676
|
+
return `${layer.inset ? "inset " : ""}${lengths} ${colorCss(layer.color)}`;
|
|
677
|
+
}
|
|
678
|
+
function gradientCss(value) {
|
|
679
|
+
if (typeof value === "string") return value;
|
|
680
|
+
return `linear-gradient(${value.map((stop) => `${colorCss(stop.color)} ${Math.round(stop.position * 1e3) / 10}%`).join(", ")})`;
|
|
681
|
+
}
|
|
682
|
+
function typographyCss(value) {
|
|
683
|
+
if (typeof value === "string") return value;
|
|
684
|
+
const { lineHeight } = value;
|
|
685
|
+
const line = lineHeight === void 0 ? "" : `/${typeof lineHeight === "object" ? dimensionCss(lineHeight) : lineHeight}`;
|
|
686
|
+
return `${value.fontWeight} ${dimensionCss(value.fontSize)}${line} ${fontFamilyCss(value.fontFamily)}`;
|
|
687
|
+
}
|
|
688
|
+
// ../tokens/src/dtcg.ts
|
|
689
|
+
/** Token groups, or `$ref`s to them in this file or another. */
|
|
690
|
+
const tokenSources = z.array(plainObject);
|
|
691
|
+
z.object({ sources: tokenSources });
|
|
692
|
+
const resolverModifier = z.object({
|
|
693
|
+
contexts: z.record(z.string(), tokenSources).transform((contexts) => new Map(Object.entries(contexts))),
|
|
694
|
+
default: z.string().optional()
|
|
695
|
+
});
|
|
696
|
+
z.object({ $ref: z.string() });
|
|
697
|
+
resolverModifier.extend({ name: z.string().optional() });
|
|
698
|
+
z.object({
|
|
699
|
+
$type: z.string().optional(),
|
|
700
|
+
$description: z.string().optional(),
|
|
701
|
+
$extensions: z.object({ parity: z.object({
|
|
702
|
+
var: z.string().optional(),
|
|
703
|
+
category: z.string().optional(),
|
|
704
|
+
lineHeight: z.string().optional()
|
|
705
|
+
}).optional() }).optional()
|
|
706
|
+
});
|
|
551
707
|
// ../tokens/src/policy.ts
|
|
552
708
|
/**
|
|
553
709
|
* At-rules that don't pick a theme: a cascade layer only orders rules, and a feature check holds whatever the theme.
|
|
@@ -757,6 +913,247 @@ new Intl.Collator("en", {
|
|
|
757
913
|
numeric: true,
|
|
758
914
|
sensitivity: "base"
|
|
759
915
|
});
|
|
916
|
+
// ../project/src/packages.ts
|
|
917
|
+
/**
|
|
918
|
+
* The package a folder's code gets for `name`, found the way Node finds packages: in `node_modules` here or in a folder
|
|
919
|
+
* above, with links followed. It reads the package's own package.json, which its `exports` may leave out of reach of
|
|
920
|
+
* `require.resolve`, and never falls back to NODE_PATH, which pnpm's bin shims point at Parity's own dependencies.
|
|
921
|
+
* Throws when the manifest isn't a package's.
|
|
922
|
+
*/
|
|
923
|
+
async function findPackage(from, name) {
|
|
924
|
+
for (let folder = resolve(from);; folder = dirname(folder)) {
|
|
925
|
+
const installedAt = join(folder, "node_modules", name);
|
|
926
|
+
const text = await readFile(join(installedAt, "package.json"), "utf8").catch(() => void 0);
|
|
927
|
+
if (text !== void 0) {
|
|
928
|
+
const manifest = readManifest(text, join(installedAt, "package.json"));
|
|
929
|
+
return {
|
|
930
|
+
dir: await realpath(installedAt),
|
|
931
|
+
installedAt,
|
|
932
|
+
manifest
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
if (dirname(folder) === folder) return void 0;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
/** The package in a folder, or nothing when it has no package.json. Throws when the manifest isn't a package's. */
|
|
939
|
+
async function readPackage(dir) {
|
|
940
|
+
const file = join(dir, "package.json");
|
|
941
|
+
const text = await readFile(file, "utf8").catch(() => void 0);
|
|
942
|
+
return text === void 0 ? void 0 : {
|
|
943
|
+
dir,
|
|
944
|
+
manifest: readManifest(text, file)
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
function readManifest(text, file) {
|
|
948
|
+
try {
|
|
949
|
+
return parseData(jsonText(packageManifest), text);
|
|
950
|
+
} catch (error) {
|
|
951
|
+
throw new TypeError(`${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
/** A bare specifier's package and the entry point in it: `@acme/ui/button` is `@acme/ui` and `./button`. */
|
|
955
|
+
function splitSpecifier(specifier) {
|
|
956
|
+
const parts = specifier.split("/");
|
|
957
|
+
const length = specifier.startsWith("@") ? 2 : 1;
|
|
958
|
+
const rest = parts.slice(length).join("/");
|
|
959
|
+
return {
|
|
960
|
+
name: parts.slice(0, length).join("/"),
|
|
961
|
+
subpath: rest ? `./${rest}` : "."
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
const conditions = {
|
|
965
|
+
types: [
|
|
966
|
+
"types",
|
|
967
|
+
"import",
|
|
968
|
+
"default",
|
|
969
|
+
"require"
|
|
970
|
+
],
|
|
971
|
+
runtime: [
|
|
972
|
+
"node",
|
|
973
|
+
"import",
|
|
974
|
+
"default"
|
|
975
|
+
],
|
|
976
|
+
source: [
|
|
977
|
+
"source",
|
|
978
|
+
"types",
|
|
979
|
+
"import",
|
|
980
|
+
"default"
|
|
981
|
+
],
|
|
982
|
+
style: [
|
|
983
|
+
"style",
|
|
984
|
+
"import",
|
|
985
|
+
"default"
|
|
986
|
+
]
|
|
987
|
+
};
|
|
988
|
+
/** Which files a target may lead to for each use: declarations for types, anything but them otherwise. */
|
|
989
|
+
const accepts = {
|
|
990
|
+
types: (file) => isDeclaration(file),
|
|
991
|
+
runtime: (file) => !isDeclaration(file),
|
|
992
|
+
source: () => true,
|
|
993
|
+
style: (file) => !isDeclaration(file)
|
|
994
|
+
};
|
|
995
|
+
/**
|
|
996
|
+
* The file one of a package's entry points leads to for a use, or nothing when no file is there. `subpath` is the
|
|
997
|
+
* entry point as `exports` names it: `.` for the package itself, or one such as `./tailwind.css`, which can be written
|
|
998
|
+
* `tailwind.css`. A package that doesn't list an entry point in `exports` is read as older packages are: `types` or
|
|
999
|
+
* `typings` for declarations, `module` or `main` for its module, and `style` for its stylesheet.
|
|
1000
|
+
*/
|
|
1001
|
+
function packageEntry(pkg, use, subpath = ".") {
|
|
1002
|
+
const entry = subpath === "." || subpath.startsWith("./") ? subpath : `./${subpath}`;
|
|
1003
|
+
for (const candidate of entryCandidates(pkg.manifest, use, entry)) {
|
|
1004
|
+
const file = candidate && join(pkg.dir, candidate);
|
|
1005
|
+
if (file && isFile(file)) return file;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function entryCandidates(manifest, use, entry) {
|
|
1009
|
+
const root = entry === ".";
|
|
1010
|
+
const path = entry.slice(2);
|
|
1011
|
+
const exported = exportTarget(manifest.exports, entry, conditions[use], accepts[use]);
|
|
1012
|
+
switch (use) {
|
|
1013
|
+
case "types": return [
|
|
1014
|
+
exported,
|
|
1015
|
+
...root ? [manifest.types, manifest.typings] : [],
|
|
1016
|
+
...entryCandidates(manifest, "runtime", entry).map((file) => file && declarationOf(file)),
|
|
1017
|
+
root ? "index.d.ts" : `${path}/index.d.ts`,
|
|
1018
|
+
root ? void 0 : `${path}.d.ts`
|
|
1019
|
+
];
|
|
1020
|
+
case "runtime": return [
|
|
1021
|
+
exported,
|
|
1022
|
+
...root ? [manifest.module, ...moduleFiles(manifest.main)] : [],
|
|
1023
|
+
...root || manifest.exports !== void 0 ? [] : moduleFiles(path)
|
|
1024
|
+
];
|
|
1025
|
+
case "source": {
|
|
1026
|
+
const named = [exported, ...root ? [
|
|
1027
|
+
manifest.types,
|
|
1028
|
+
manifest.typings,
|
|
1029
|
+
manifest.module,
|
|
1030
|
+
manifest.main
|
|
1031
|
+
] : []].find((file) => file !== void 0);
|
|
1032
|
+
return [...named && isBuilt(named) ? sourcesOf(named) : [named], ...root ? [
|
|
1033
|
+
"src/index.tsx",
|
|
1034
|
+
"src/index.ts",
|
|
1035
|
+
"src/index.jsx",
|
|
1036
|
+
"src/index.js",
|
|
1037
|
+
"index.tsx",
|
|
1038
|
+
"index.ts"
|
|
1039
|
+
] : []];
|
|
1040
|
+
}
|
|
1041
|
+
case "style": return root ? [manifest.style, exported] : [exported, path];
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
/** A `main` as Node reads it: the file, the file with `.js`, or a folder's `index.js`; `index.js` without one. */
|
|
1045
|
+
function moduleFiles(main) {
|
|
1046
|
+
return main ? [
|
|
1047
|
+
main,
|
|
1048
|
+
`${main}.js`,
|
|
1049
|
+
`${main}/index.js`
|
|
1050
|
+
] : ["index.js"];
|
|
1051
|
+
}
|
|
1052
|
+
const stylesheetNames = [
|
|
1053
|
+
"tailwind.css",
|
|
1054
|
+
"styles.css",
|
|
1055
|
+
"style.css",
|
|
1056
|
+
"index.css",
|
|
1057
|
+
"theme.css"
|
|
1058
|
+
];
|
|
1059
|
+
/**
|
|
1060
|
+
* The stylesheet a project imports to use a package, as a path from the package: its `style` field, else the CSS its
|
|
1061
|
+
* `exports` lists, the usual names first. Only one that leads to a file counts.
|
|
1062
|
+
*/
|
|
1063
|
+
function packageStylesheet(pkg) {
|
|
1064
|
+
const { style, exports } = pkg.manifest;
|
|
1065
|
+
if (style && isFile(join(pkg.dir, style))) return style;
|
|
1066
|
+
const css = Object.keys(exports === void 0 ? {} : subpaths(exports)).filter((key) => key.endsWith(".css") && !key.includes("*")).map((key) => key.slice(2));
|
|
1067
|
+
const pick = stylesheetNames.find((name) => css.includes(name)) ?? css[0];
|
|
1068
|
+
return pick && packageEntry(pkg, "style", pick) ? pick : void 0;
|
|
1069
|
+
}
|
|
1070
|
+
/** `exports` by subpath: a map as written, or the package's one entry point, which is `.`. */
|
|
1071
|
+
function subpaths(exports) {
|
|
1072
|
+
if (typeof exports !== "object" || exports === null || Array.isArray(exports)) return { ".": exports };
|
|
1073
|
+
return Object.keys(exports).some((key) => key.startsWith(".")) ? exports : { ".": exports };
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Where `exports` leads for an entry point under these conditions: the entry point as written, else the longest
|
|
1077
|
+
* pattern that matches it (`./icons/*`), with what `*` stood for put in.
|
|
1078
|
+
*/
|
|
1079
|
+
function exportTarget(exports, entry, wanted, accept) {
|
|
1080
|
+
if (exports === void 0) return void 0;
|
|
1081
|
+
const map = subpaths(exports);
|
|
1082
|
+
if (Object.hasOwn(map, entry)) return resolveTarget(map[entry], wanted, accept);
|
|
1083
|
+
let best;
|
|
1084
|
+
for (const key of Object.keys(map)) {
|
|
1085
|
+
const star = key.indexOf("*");
|
|
1086
|
+
if (star === -1) continue;
|
|
1087
|
+
const [prefix, suffix] = [key.slice(0, star), key.slice(star + 1)];
|
|
1088
|
+
if (entry.length < key.length || !entry.startsWith(prefix) || !entry.endsWith(suffix)) continue;
|
|
1089
|
+
if (!best || prefix.length > best.prefix.length) best = {
|
|
1090
|
+
key,
|
|
1091
|
+
prefix,
|
|
1092
|
+
match: entry.slice(prefix.length, entry.length - suffix.length)
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
if (!best) return void 0;
|
|
1096
|
+
const { key, match } = best;
|
|
1097
|
+
return resolveTarget(map[key], wanted, (file) => accept(file.replaceAll("*", match)))?.replaceAll("*", match);
|
|
1098
|
+
}
|
|
1099
|
+
/** The first file a target leads to under the wanted conditions, taken in the order they're wanted. */
|
|
1100
|
+
function resolveTarget(target, wanted, accept) {
|
|
1101
|
+
if (typeof target === "string") return accept(target) ? target : void 0;
|
|
1102
|
+
if (target === null) return void 0;
|
|
1103
|
+
if (Array.isArray(target)) {
|
|
1104
|
+
for (const each of target) {
|
|
1105
|
+
const found = resolveTarget(each, wanted, accept);
|
|
1106
|
+
if (found) return found;
|
|
1107
|
+
}
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
for (const condition of wanted) {
|
|
1111
|
+
const found = Object.hasOwn(target, condition) ? resolveTarget(target[condition], wanted, accept) : void 0;
|
|
1112
|
+
if (found) return found;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function isDeclaration(file) {
|
|
1116
|
+
return /\.d\.[cm]?ts$/.test(file);
|
|
1117
|
+
}
|
|
1118
|
+
/** The declarations TypeScript looks for beside a module: `index.d.ts` for `index.js`, `index.d.mts` for `index.mjs`. */
|
|
1119
|
+
function declarationOf(file) {
|
|
1120
|
+
const match = /\.([cm]?)jsx?$/.exec(file);
|
|
1121
|
+
return match ? `${file.slice(0, match.index)}.d.${match[1]}ts` : void 0;
|
|
1122
|
+
}
|
|
1123
|
+
/** Folders a package's build writes to, which its source isn't in. */
|
|
1124
|
+
const builtFolders = /* @__PURE__ */ new Set([
|
|
1125
|
+
"dist",
|
|
1126
|
+
"build",
|
|
1127
|
+
"lib",
|
|
1128
|
+
"out",
|
|
1129
|
+
"esm",
|
|
1130
|
+
"cjs"
|
|
1131
|
+
]);
|
|
1132
|
+
/** A file a build wrote: declarations, or anything in a build folder at the package's root. */
|
|
1133
|
+
function isBuilt(file) {
|
|
1134
|
+
return isDeclaration(file) || builtFolders.has(file.replace(/^\.\//, "").split("/")[0]);
|
|
1135
|
+
}
|
|
1136
|
+
const sourceExtensions = [
|
|
1137
|
+
".tsx",
|
|
1138
|
+
".ts",
|
|
1139
|
+
".jsx",
|
|
1140
|
+
".js"
|
|
1141
|
+
];
|
|
1142
|
+
/**
|
|
1143
|
+
* Where a built file's source may be, in the order to look: `dist/index.js` and `dist/index.d.ts` were built from
|
|
1144
|
+
* `src/index.tsx`, `src/index.ts`, `src/index.jsx` or `src/index.js`, and `dist/esm/button.js` from `src/button.tsx`.
|
|
1145
|
+
*/
|
|
1146
|
+
function sourcesOf(file) {
|
|
1147
|
+
const parts = file.replace(/^\.\//, "").split("/");
|
|
1148
|
+
let start = 0;
|
|
1149
|
+
while (start < parts.length - 1 && builtFolders.has(parts[start])) start++;
|
|
1150
|
+
const rest = parts.slice(start).join("/").replace(/\.d\.[cm]?ts$|\.[cm]?jsx?$/, "");
|
|
1151
|
+
const stem = start > 0 ? `src/${rest}` : rest;
|
|
1152
|
+
return sourceExtensions.map((extension) => stem + extension);
|
|
1153
|
+
}
|
|
1154
|
+
function isFile(path) {
|
|
1155
|
+
return statSync(path, { throwIfNoEntry: false })?.isFile() ?? false;
|
|
1156
|
+
}
|
|
760
1157
|
// ../project/src/styles.ts
|
|
761
1158
|
/**
|
|
762
1159
|
* Where an app keeps its global styles when neither `components.json` nor the entry says: Vite's and Create React App's
|
|
@@ -869,21 +1266,6 @@ async function readText(path) {
|
|
|
869
1266
|
function toPosix(path) {
|
|
870
1267
|
return path.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
871
1268
|
}
|
|
872
|
-
// ../project/src/libraries.ts
|
|
873
|
-
/**
|
|
874
|
-
* Where a dependency is installed, found the way Node finds packages: in `node_modules` here or in a folder above. It
|
|
875
|
-
* doesn't resolve `<name>/package.json`, because a package whose `exports` leaves that out can't be resolved that way.
|
|
876
|
-
*/
|
|
877
|
-
async function installedPackage(root, importName) {
|
|
878
|
-
for (let folder = resolve(root);; folder = dirname(folder)) {
|
|
879
|
-
const candidate = join(folder, "node_modules", importName);
|
|
880
|
-
if (await isFile(join(candidate, "package.json"))) return realpath(candidate);
|
|
881
|
-
if (dirname(folder) === folder) return void 0;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
async function isFile(path) {
|
|
885
|
-
return stat(path).then((stats) => stats.isFile(), () => false);
|
|
886
|
-
}
|
|
887
1269
|
/** A sentence that ends this far in is kept whole, rather than its words cut down to the length. */
|
|
888
1270
|
const shortestSentence = 20;
|
|
889
1271
|
/**
|
|
@@ -3746,7 +4128,6 @@ const presets = {
|
|
|
3746
4128
|
id: style,
|
|
3747
4129
|
name: `Shadcn ${style.charAt(0).toUpperCase()}${style.slice(1)}`,
|
|
3748
4130
|
description: `Every shadcn component on Base UI, in the ${style} style, kept in step with upstream.`,
|
|
3749
|
-
styles: "tailwind.css",
|
|
3750
4131
|
examples: {
|
|
3751
4132
|
paths: ["apps/v4/examples/base/"],
|
|
3752
4133
|
anatomy: ["apps/v4/content/docs/components/base/"]
|
|
@@ -4449,16 +4830,16 @@ async function generateLibrary(options) {
|
|
|
4449
4830
|
}
|
|
4450
4831
|
async function describePackage(options, importName) {
|
|
4451
4832
|
const root = resolve(options.root);
|
|
4452
|
-
const
|
|
4453
|
-
if (!
|
|
4454
|
-
const
|
|
4833
|
+
const installed = await findPackage(root, importName);
|
|
4834
|
+
if (!installed) throw new Error(`${importName} isn't installed in ${root}. Install it with the project's package manager first.`);
|
|
4835
|
+
const { dir, manifest: pkg } = installed;
|
|
4455
4836
|
const name = pkg.name ?? importName;
|
|
4456
4837
|
const version = pkg.version ?? "0.0.0";
|
|
4457
4838
|
const preset = presets[name];
|
|
4458
4839
|
const notes = [...preset?.notes ?? []];
|
|
4459
4840
|
const iconImport = preset?.icons?.import;
|
|
4460
4841
|
const componentImport = iconImport ?? preset?.components;
|
|
4461
|
-
const entry =
|
|
4842
|
+
const entry = packageEntry(installed, "types", componentImport ? splitSpecifier(componentImport).subpath : ".")?.replaceAll("\\", "/");
|
|
4462
4843
|
if (!entry) notes.push("No type declarations were found, so no components could be read.");
|
|
4463
4844
|
const scan = entry ? findComponents({
|
|
4464
4845
|
entries: [entry],
|
|
@@ -4473,8 +4854,9 @@ async function describePackage(options, importName) {
|
|
|
4473
4854
|
const dataIcons = preset?.icons?.render !== void 0 && preset.icons.render !== "export";
|
|
4474
4855
|
const isIcons = preset?.icons !== void 0 || looksLikeIcons(scan);
|
|
4475
4856
|
const tokens = /* @__PURE__ */ new Map();
|
|
4476
|
-
const styles = preset?.styles ??
|
|
4477
|
-
|
|
4857
|
+
const styles = preset?.styles ?? packageStylesheet(installed);
|
|
4858
|
+
const stylesheet = styles && packageEntry(installed, "style", styles);
|
|
4859
|
+
if (stylesheet) for (const token of cssTokens(await readStylesheet(stylesheet))) tokens.set(token.var, token);
|
|
4478
4860
|
let breakpoints;
|
|
4479
4861
|
if (preset?.theme) try {
|
|
4480
4862
|
const theme = await preset.theme(loader(root, dir));
|
|
@@ -4522,7 +4904,7 @@ async function describePackage(options, importName) {
|
|
|
4522
4904
|
if (preset?.icons?.variants) icons.variants = preset.icons.variants;
|
|
4523
4905
|
if (!dataIcons) {
|
|
4524
4906
|
const load = loader(root, dir);
|
|
4525
|
-
const modules = await styleModules(name, typeof pkg.exports === "object" && pkg.exports !== null ? Object.keys(pkg.exports) : [], iconImport ?? name, load, await iconDrawer(load));
|
|
4907
|
+
const modules = await styleModules(name, typeof pkg.exports === "object" && pkg.exports !== null && !Array.isArray(pkg.exports) ? Object.keys(pkg.exports) : [], iconImport ?? name, load, await iconDrawer(load));
|
|
4526
4908
|
if (modules) {
|
|
4527
4909
|
const main = Object.keys(modules).find((style) => modules[style] === (iconImport ?? name));
|
|
4528
4910
|
icons.variants = {
|
|
@@ -4663,7 +5045,7 @@ async function reviseLibrary(generated, options) {
|
|
|
4663
5045
|
const edits = options.edits ?? kept;
|
|
4664
5046
|
if (edits !== void 0) {
|
|
4665
5047
|
manifest.edits = edits;
|
|
4666
|
-
const resolved =
|
|
5048
|
+
const resolved = await readLibraryEdits(edits, resolve(options.editsBase ?? options.root));
|
|
4667
5049
|
const { orphans } = applyLibraryEdits(parseLibraryManifest(manifest), resolved);
|
|
4668
5050
|
if (orphans.length > 0) report.orphanEdits = orphans;
|
|
4669
5051
|
}
|
|
@@ -4753,7 +5135,7 @@ function summarizeParts(relations) {
|
|
|
4753
5135
|
const appExtensions = [".tsx", ".jsx"];
|
|
4754
5136
|
async function describeApp(options) {
|
|
4755
5137
|
const root = resolve(options.root);
|
|
4756
|
-
const pkg =
|
|
5138
|
+
const pkg = (await readPackage(root))?.manifest ?? {};
|
|
4757
5139
|
const notes = [];
|
|
4758
5140
|
const tsconfig = readTsconfig(root);
|
|
4759
5141
|
const { files } = await appFiles(root, { componentExtensions: appExtensions }, tsconfig);
|
|
@@ -4810,8 +5192,8 @@ async function describeApp(options) {
|
|
|
4810
5192
|
async function appManifestPath(root) {
|
|
4811
5193
|
const existing = (await readdir(root)).find((file) => file.endsWith(libraryManifestExtension));
|
|
4812
5194
|
if (existing) return join(root, existing);
|
|
4813
|
-
const
|
|
4814
|
-
return join(root, `${
|
|
5195
|
+
const name = (await readPackage(root))?.manifest.name ?? basename(root);
|
|
5196
|
+
return join(root, `${name.replace(/^@[^/]+\//, "")}${libraryManifestExtension}`);
|
|
4815
5197
|
}
|
|
4816
5198
|
/**
|
|
4817
5199
|
* A generated manifest laid over the file already there: what generating finds replaces what it found before, and
|
|
@@ -4872,56 +5254,6 @@ function defaultRange(version) {
|
|
|
4872
5254
|
const [major = "0", minor = "0"] = version.split(/[.-]/);
|
|
4873
5255
|
return major === "0" ? `^0.${minor}.0` : `^${major}.0.0`;
|
|
4874
5256
|
}
|
|
4875
|
-
function subpath(specifier, packageName) {
|
|
4876
|
-
return specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
|
|
4877
|
-
}
|
|
4878
|
-
/** The type declarations for one of a package's entry points, from `exports`, else `types`, else `index.d.ts`. */
|
|
4879
|
-
function typesEntry(dir, pkg, entry) {
|
|
4880
|
-
const exported = typeof pkg.exports === "object" && pkg.exports !== null ? pkg.exports : {};
|
|
4881
|
-
const condition = (value) => {
|
|
4882
|
-
if (typeof value === "string") return /\.d\.[cm]?ts$/.test(value) ? value : void 0;
|
|
4883
|
-
if (typeof value !== "object" || value === null) return void 0;
|
|
4884
|
-
const record = value;
|
|
4885
|
-
for (const key of [
|
|
4886
|
-
"types",
|
|
4887
|
-
"import",
|
|
4888
|
-
"default",
|
|
4889
|
-
"require"
|
|
4890
|
-
]) {
|
|
4891
|
-
const found = condition(record[key]);
|
|
4892
|
-
if (found) return found;
|
|
4893
|
-
}
|
|
4894
|
-
};
|
|
4895
|
-
const candidates = [
|
|
4896
|
-
condition(exported[entry]),
|
|
4897
|
-
entry === "." ? pkg.types ?? pkg.typings : void 0,
|
|
4898
|
-
entry === "." ? "index.d.ts" : `${entry.slice(2)}/index.d.ts`,
|
|
4899
|
-
entry === "." ? void 0 : `${entry.slice(2)}.d.ts`
|
|
4900
|
-
];
|
|
4901
|
-
for (const candidate of candidates) if (candidate && existsSync(join(dir, candidate))) return join(dir, candidate).replaceAll("\\", "/");
|
|
4902
|
-
}
|
|
4903
|
-
/** The stylesheet a project imports to use a package: its `style` field, else the CSS its `exports` list first. */
|
|
4904
|
-
function stylesheetOf(dir, pkg) {
|
|
4905
|
-
if (pkg.style && existsSync(join(dir, pkg.style))) return pkg.style;
|
|
4906
|
-
const css = (typeof pkg.exports === "object" && pkg.exports !== null ? Object.keys(pkg.exports) : []).filter((key) => key.endsWith(".css")).map((key) => key.slice(2));
|
|
4907
|
-
const pick = [
|
|
4908
|
-
"tailwind.css",
|
|
4909
|
-
"styles.css",
|
|
4910
|
-
"style.css",
|
|
4911
|
-
"index.css",
|
|
4912
|
-
"theme.css"
|
|
4913
|
-
].find((name) => css.includes(name)) ?? css[0];
|
|
4914
|
-
if (!pick) return void 0;
|
|
4915
|
-
const target = pkg.exports[`./${pick}`];
|
|
4916
|
-
const file = typeof target === "string" ? target : target?.default;
|
|
4917
|
-
return typeof file === "string" && existsSync(join(dir, file)) ? pick : void 0;
|
|
4918
|
-
}
|
|
4919
|
-
/** The file an export such as `tailwind.css` points at: `dist/tailwind.css` for Buildkit's styles. */
|
|
4920
|
-
function exportedFile(dir, pkg, specifier) {
|
|
4921
|
-
const target = (typeof pkg.exports === "object" && pkg.exports !== null ? pkg.exports : {})[`./${specifier}`];
|
|
4922
|
-
const file = typeof target === "string" ? target : target?.default;
|
|
4923
|
-
return join(dir, typeof file === "string" ? file : specifier);
|
|
4924
|
-
}
|
|
4925
5257
|
/** A DTCG token file the package ships, if it has one in the format; Buildkit's `tokens.json` isn't yet. */
|
|
4926
5258
|
async function dtcgIn(dir) {
|
|
4927
5259
|
for (const candidate of [
|
|
@@ -5052,25 +5384,8 @@ function resolveRequire(from, specifier) {
|
|
|
5052
5384
|
}
|
|
5053
5385
|
/** An ESM-only package's entry, from the `import` condition of its `exports`, which `require` can't see. */
|
|
5054
5386
|
async function resolveImport(from, specifier) {
|
|
5055
|
-
const name
|
|
5056
|
-
const
|
|
5057
|
-
|
|
5058
|
-
const pkg = JSON.parse(await readFile(join(dir, "package.json"), "utf8"));
|
|
5059
|
-
const exported = typeof pkg.exports === "object" && pkg.exports !== null ? pkg.exports : {};
|
|
5060
|
-
const pick = (value) => {
|
|
5061
|
-
if (typeof value === "string") return /\.d\.[cm]?ts$/.test(value) ? void 0 : value;
|
|
5062
|
-
if (typeof value !== "object" || value === null) return void 0;
|
|
5063
|
-
const record = value;
|
|
5064
|
-
for (const key of [
|
|
5065
|
-
"node",
|
|
5066
|
-
"import",
|
|
5067
|
-
"default"
|
|
5068
|
-
]) {
|
|
5069
|
-
const found = pick(record[key]);
|
|
5070
|
-
if (found) return found;
|
|
5071
|
-
}
|
|
5072
|
-
};
|
|
5073
|
-
const file = pick(exported[subpath(specifier, name)]) ?? (specifier === name ? pkg.module : void 0);
|
|
5074
|
-
return file ? join(dir, file) : void 0;
|
|
5387
|
+
const { name, subpath } = splitSpecifier(specifier);
|
|
5388
|
+
const installed = await findPackage(from, name);
|
|
5389
|
+
return installed && packageEntry(installed, "runtime", subpath);
|
|
5075
5390
|
}
|
|
5076
5391
|
export { appManifestPath, generateLibrary, manifestText, mergeManifest, parseLibraryEdits, reviseLibrary, iconVariants as t };
|