@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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { a as applyLibraryEdits, f as parseLibraryEdits, p as parseLibraryManifest, u as libraryManifestExtension } from "./src-YQY8r4mh.mjs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import semver from "semver";
|
|
7
|
+
// ../core/src/jsonc.ts
|
|
8
|
+
/** Parses JSON with comments and trailing commas, as tsconfig files allow. Comment markers inside strings are kept. */
|
|
9
|
+
function parseJsonc(text) {
|
|
10
|
+
let output = "";
|
|
11
|
+
let index = 0;
|
|
12
|
+
while (index < text.length) {
|
|
13
|
+
const char = text[index];
|
|
14
|
+
if (char === "\"") {
|
|
15
|
+
const start = index++;
|
|
16
|
+
while (index < text.length && text[index] !== "\"") index += text[index] === "\\" ? 2 : 1;
|
|
17
|
+
output += text.slice(start, ++index);
|
|
18
|
+
} else if (char === "/" && text[index + 1] === "/") while (index < text.length && text[index] !== "\n") index++;
|
|
19
|
+
else if (char === "/" && text[index + 1] === "*") {
|
|
20
|
+
const end = text.indexOf("*/", index + 2);
|
|
21
|
+
index = end === -1 ? text.length : end + 2;
|
|
22
|
+
} else {
|
|
23
|
+
output += char;
|
|
24
|
+
index++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return JSON.parse(output.replace(/,(\s*[}\]])/g, "$1"));
|
|
28
|
+
}
|
|
29
|
+
// ../registry/src/index.ts
|
|
30
|
+
const require = createRequire(import.meta.url);
|
|
31
|
+
/**
|
|
32
|
+
* The folder the registry's files are in. The published CLI bundles this module and ships the files beside it, where
|
|
33
|
+
* the package can't be resolved. Otherwise they're found through the package's own `package.json`, so it's the same
|
|
34
|
+
* whether this module runs from source or bundled into the app.
|
|
35
|
+
*/
|
|
36
|
+
function registryDir() {
|
|
37
|
+
const bundled = join(import.meta.dirname, "libraries");
|
|
38
|
+
if (existsSync(bundled)) return bundled;
|
|
39
|
+
return join(dirname(require.resolve("@parity-app/registry/package.json")), "libraries");
|
|
40
|
+
}
|
|
41
|
+
let cache;
|
|
42
|
+
/** Every file in the registry, read once. One that doesn't parse is skipped with a warning. */
|
|
43
|
+
function registryEntries(dir = registryDir()) {
|
|
44
|
+
if (dir !== registryDir()) return readEntries(dir);
|
|
45
|
+
cache ??= readEntries(dir);
|
|
46
|
+
return cache;
|
|
47
|
+
}
|
|
48
|
+
async function readEntries(dir) {
|
|
49
|
+
const files = (await readdir(dir).catch(() => [])).filter((file) => file.endsWith(libraryManifestExtension)).sort();
|
|
50
|
+
const entries = [];
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
const path = join(dir, file);
|
|
53
|
+
try {
|
|
54
|
+
const manifest = parseLibraryManifest(JSON.parse(await readFile(path, "utf8")));
|
|
55
|
+
if (!manifest.package) throw new TypeError("/package: a registry file names the package it describes");
|
|
56
|
+
entries.push({
|
|
57
|
+
file,
|
|
58
|
+
path,
|
|
59
|
+
manifest
|
|
60
|
+
});
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn(`Skipping registry file ${file}: ${errorText(error)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return entries;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The newest file for each package the registry describes, by the version it was made from, with its hand edits
|
|
69
|
+
* applied. A file whose edits can't be read is used as it is, with a warning.
|
|
70
|
+
*/
|
|
71
|
+
async function newestEntries(dir) {
|
|
72
|
+
const newest = /* @__PURE__ */ new Map();
|
|
73
|
+
for (const entry of await registryEntries(dir)) {
|
|
74
|
+
const name = entry.manifest.package.name;
|
|
75
|
+
const current = newest.get(name);
|
|
76
|
+
if (!current || compareGenerated(entry.manifest, current.manifest) > 0) newest.set(name, entry);
|
|
77
|
+
}
|
|
78
|
+
return Promise.all([...newest.values()].map(async (entry) => {
|
|
79
|
+
try {
|
|
80
|
+
return {
|
|
81
|
+
...entry,
|
|
82
|
+
manifest: (await withEdits(entry.path, entry.manifest)).manifest
|
|
83
|
+
};
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.warn(`Using registry file ${entry.file} without its edits: ${errorText(error)}`);
|
|
86
|
+
return entry;
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A library file at `path` with its hand edits applied: its own `edits`, or the shared file it names beside it. Edits
|
|
92
|
+
* for exports it doesn't have are its `orphans`, reported rather than dropped silently. Throws when the edits can't be
|
|
93
|
+
* read.
|
|
94
|
+
*/
|
|
95
|
+
async function withEdits(path, manifest) {
|
|
96
|
+
if (manifest.edits === void 0) return {
|
|
97
|
+
manifest,
|
|
98
|
+
orphans: []
|
|
99
|
+
};
|
|
100
|
+
return applyLibraryEdits(manifest, await readLibraryEdits(manifest.edits, dirname(path)));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Hand edits as a library file writes them: inline, or the path of a shared file, which is read from `from` and may
|
|
104
|
+
* have comments.
|
|
105
|
+
*/
|
|
106
|
+
async function readLibraryEdits(edits, from) {
|
|
107
|
+
return parseLibraryEdits(typeof edits === "string" ? parseJsonc(await readFile(resolve(from, edits), "utf8")) : edits);
|
|
108
|
+
}
|
|
109
|
+
function errorText(error) {
|
|
110
|
+
return error instanceof Error ? error.message : String(error);
|
|
111
|
+
}
|
|
112
|
+
/** Whether a manifest describes this version of its package. A manifest without a range covers every version. */
|
|
113
|
+
function covers(manifest, version) {
|
|
114
|
+
const range = manifest.package?.range;
|
|
115
|
+
if (!range) return true;
|
|
116
|
+
if (!version) return false;
|
|
117
|
+
const parsed = semver.coerce(version, { includePrerelease: true });
|
|
118
|
+
return parsed !== null && semver.satisfies(parsed, range, { includePrerelease: true });
|
|
119
|
+
}
|
|
120
|
+
function compareGenerated(a, b) {
|
|
121
|
+
const left = semver.coerce(a.package?.version);
|
|
122
|
+
const right = semver.coerce(b.package?.version);
|
|
123
|
+
if (!left || !right) {
|
|
124
|
+
if (left) return 1;
|
|
125
|
+
return right ? -1 : 0;
|
|
126
|
+
}
|
|
127
|
+
return semver.compare(left, right);
|
|
128
|
+
}
|
|
129
|
+
export { registryEntries as a, registryDir as i, newestEntries as n, withEdits as o, readLibraryEdits as r, parseJsonc as s, covers as t };
|
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
import "./schema-
|
|
1
|
+
import "./schema-CiVy9tZT.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
// ../core/src/adapters.ts
|
|
4
4
|
const packageVersions = z.record(z.string(), z.string());
|
|
5
|
-
z.
|
|
5
|
+
const exportsTarget = z.lazy(() => z.union([
|
|
6
|
+
z.string(),
|
|
7
|
+
z.null(),
|
|
8
|
+
z.array(exportsTarget),
|
|
9
|
+
z.record(z.string(), exportsTarget)
|
|
10
|
+
]));
|
|
11
|
+
/**
|
|
12
|
+
* The parts of a package.json Parity reads: the dependencies adapters detect a stack by, and where an installed
|
|
13
|
+
* package's entry points and a workspace's packages are (PAR-573). It's someone else's file, so the fields Parity
|
|
14
|
+
* doesn't read pass through unchecked.
|
|
15
|
+
*/
|
|
16
|
+
const packageManifest = z.looseObject({
|
|
6
17
|
name: z.string().optional(),
|
|
18
|
+
version: z.string().optional(),
|
|
7
19
|
dependencies: packageVersions.optional(),
|
|
8
20
|
devDependencies: packageVersions.optional(),
|
|
9
|
-
scripts: z.record(z.string(), z.string()).optional()
|
|
21
|
+
scripts: z.record(z.string(), z.string()).optional(),
|
|
22
|
+
/** Entry points by subpath (`.`, `./tailwind.css`), or where the package's one entry point leads. */
|
|
23
|
+
exports: exportsTarget.optional(),
|
|
24
|
+
types: z.string().optional(),
|
|
25
|
+
typings: z.string().optional(),
|
|
26
|
+
module: z.string().optional(),
|
|
27
|
+
main: z.string().optional(),
|
|
28
|
+
/** The stylesheet a project imports to use the package, as some packages name it. */
|
|
29
|
+
style: z.string().optional(),
|
|
30
|
+
/** A workspace root's package folders, as npm, Yarn and Bun write them. */
|
|
31
|
+
workspaces: z.union([z.array(z.string()), z.looseObject({ packages: z.array(z.string()).optional() })]).optional()
|
|
10
32
|
});
|
|
11
33
|
// ../core/src/devices.ts
|
|
12
34
|
const deviceKinds = [
|
|
@@ -1341,7 +1363,8 @@ function expectStringRecord(value, path) {
|
|
|
1341
1363
|
const named = /* @__PURE__ */ new WeakSet();
|
|
1342
1364
|
/**
|
|
1343
1365
|
* A new node for a component, ready to show something: required props get their default or first option, and a
|
|
1344
|
-
* component that takes children gets its own name as text, so it isn't an empty box, unless `given` has its own
|
|
1366
|
+
* component that takes children gets its own name as text, so it isn't an empty box, unless `given` has its own or the
|
|
1367
|
+
* component sets its own size (`fixedSize`), where the name would be cut off ("Avata").
|
|
1345
1368
|
*/
|
|
1346
1369
|
function componentNode(component, info, taken, given = {}) {
|
|
1347
1370
|
const props = { ...given };
|
|
@@ -1353,7 +1376,7 @@ function componentNode(component, info, taken, given = {}) {
|
|
|
1353
1376
|
else if (prop.kind === "number") props[prop.name] = 0;
|
|
1354
1377
|
else if (prop.kind === "string") props[prop.name] = prop.name;
|
|
1355
1378
|
}
|
|
1356
|
-
const labelled = !("children" in given) && info?.props.some((prop) => prop.name === "children" && prop.kind === "node");
|
|
1379
|
+
const labelled = !("children" in given) && !info?.fixedSize && info?.props.some((prop) => prop.name === "children" && prop.kind === "node");
|
|
1357
1380
|
if (labelled) props.children = component.split("/").at(-1) ?? component;
|
|
1358
1381
|
const node = {
|
|
1359
1382
|
type: "component",
|
|
@@ -1434,10 +1457,10 @@ function withLibraryContext(node, sources, around, taken) {
|
|
|
1434
1457
|
};
|
|
1435
1458
|
};
|
|
1436
1459
|
let placed = node;
|
|
1437
|
-
const sample = source.sample;
|
|
1460
|
+
const sample = source.sample ?? (named.has(node) ? usedIn(node.component, sources) : void 0);
|
|
1438
1461
|
if (sample) {
|
|
1439
1462
|
const given = { ...node.props };
|
|
1440
|
-
if (
|
|
1463
|
+
if (named.has(node)) delete given.children;
|
|
1441
1464
|
const { props, slots } = held({
|
|
1442
1465
|
...sample.props,
|
|
1443
1466
|
...given
|
|
@@ -1514,6 +1537,39 @@ function withLibraryContext(node, sources, around, taken) {
|
|
|
1514
1537
|
}
|
|
1515
1538
|
}
|
|
1516
1539
|
/**
|
|
1540
|
+
* How a part with no sample of its own is used in its library's other samples: with the children the first use gives it,
|
|
1541
|
+
* or none when it's used without any (`<MarkerIcon />`) or with elements the sample can't show (an icon, `[]`).
|
|
1542
|
+
* Undefined when no sample uses it.
|
|
1543
|
+
*/
|
|
1544
|
+
function usedIn(component, sources) {
|
|
1545
|
+
const find = (children) => {
|
|
1546
|
+
for (const child of children ?? []) {
|
|
1547
|
+
if (typeof child === "string") continue;
|
|
1548
|
+
if (isSampleRender(child)) {
|
|
1549
|
+
const found = find(child.$render);
|
|
1550
|
+
if (found) return found;
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
if (child.component === component) return child;
|
|
1554
|
+
const found = find(child.children) ?? find(elementProps(child.props));
|
|
1555
|
+
if (found) return found;
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
const library = sources[component]?.library;
|
|
1559
|
+
for (const source of Object.values(sources)) {
|
|
1560
|
+
if (source.library !== library || !source.sample) continue;
|
|
1561
|
+
const found = find(source.sample.children) ?? find(elementProps(source.sample.props));
|
|
1562
|
+
if (found) return { children: found.children ?? [] };
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
/** The elements and render functions a sample gives as props' values, as children are. */
|
|
1566
|
+
function elementProps(props) {
|
|
1567
|
+
return Object.values(props ?? {}).flatMap((value) => {
|
|
1568
|
+
if (isSampleRender(value)) return [value];
|
|
1569
|
+
return isSampleElement(value) ? value.$element : [];
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1517
1573
|
* A library file's component as the canvas inserts it, with its parents and sample named by component id.
|
|
1518
1574
|
* Discovery has already rewritten module imports for the name the project installed the package under.
|
|
1519
1575
|
*/
|
|
@@ -1564,4 +1620,4 @@ function sampleIds(sample, library) {
|
|
|
1564
1620
|
...sample.children ? { children: sample.children.map(child) } : {}
|
|
1565
1621
|
};
|
|
1566
1622
|
}
|
|
1567
|
-
export { deviceKinds as A, parseCanvasDocument as C, collectCustomProperties as D, parseModeSettings as E, viewportHeightProperty as O, paramTypes as S, generateId as T, imageFits as _, applyLibraryEdits as a, linkEndKinds as b, isSampleElement as c, parentSignals as d, parseLibraryEdits as f, containerKinds as g, canvasObjectKinds as h, withLibraryContext as i, lengthToPixels as j, viewportWidthProperty as k, isSampleRender as l, renderSlotOf as m, librarySource as n, componentEvidence as o, parseLibraryManifest as p, sampleIds as r, isMadeValue as s, componentNode as t, libraryManifestExtension as u, lenses as v, styleKeys as w, linkTypes as x, linkAllowed as y };
|
|
1623
|
+
export { deviceKinds as A, parseCanvasDocument as C, collectCustomProperties as D, parseModeSettings as E, packageManifest as M, viewportHeightProperty as O, paramTypes as S, generateId as T, imageFits as _, applyLibraryEdits as a, linkEndKinds as b, isSampleElement as c, parentSignals as d, parseLibraryEdits as f, containerKinds as g, canvasObjectKinds as h, withLibraryContext as i, lengthToPixels as j, viewportWidthProperty as k, isSampleRender as l, renderSlotOf as m, librarySource as n, componentEvidence as o, parseLibraryManifest as p, sampleIds as r, isMadeValue as s, componentNode as t, libraryManifestExtension as u, lenses as v, styleKeys as w, linkTypes as x, linkAllowed as y };
|
package/package.json
CHANGED
package/dist/schema-BpGSCLEu.mjs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
// ../core/src/errors.ts
|
|
3
|
-
/**
|
|
4
|
-
* Why an agent's call failed, as a stable code it can act on without reading the message. The CLI and MCP publish
|
|
5
|
-
* these; the app throws them where it knows the cause.
|
|
6
|
-
*/
|
|
7
|
-
const errorCodes = [
|
|
8
|
-
"invalid_input",
|
|
9
|
-
"not_running",
|
|
10
|
-
"not_answering",
|
|
11
|
-
"unknown_tab",
|
|
12
|
-
"tab_not_ready",
|
|
13
|
-
"unknown_design",
|
|
14
|
-
"unknown_node",
|
|
15
|
-
"ambiguous_reference",
|
|
16
|
-
"unknown_state",
|
|
17
|
-
"unknown_mode",
|
|
18
|
-
"unknown_viewport",
|
|
19
|
-
"unknown_component",
|
|
20
|
-
"unknown_icon_set",
|
|
21
|
-
"unknown_edit_id",
|
|
22
|
-
"conflict",
|
|
23
|
-
"execution_failed",
|
|
24
|
-
"app_error"
|
|
25
|
-
];
|
|
26
|
-
/** Details as another process sends them. Each field that's malformed falls back on its own; only the code must hold. */
|
|
27
|
-
const errorDetailsSchema = z.object({
|
|
28
|
-
code: z.enum(errorCodes),
|
|
29
|
-
/** Whether sending the same request again, unchanged, can succeed. */
|
|
30
|
-
retryable: z.boolean().catch(false),
|
|
31
|
-
/** The request field at fault, as a path: `design`, `state`, `edits/0/find`. */
|
|
32
|
-
field: z.string().min(1).optional().catch(void 0),
|
|
33
|
-
/** Valid references to use instead of an unknown or ambiguous one, at most `alternativeLimit` of them. */
|
|
34
|
-
alternatives: z.array(z.unknown()).transform((items) => items.filter((item) => typeof item === "string").slice(0, 20)).optional().catch(void 0)
|
|
35
|
-
});
|
|
36
|
-
/** An error with a stable code, the field it's about and what to use instead. */
|
|
37
|
-
var CodedError = class extends Error {
|
|
38
|
-
details;
|
|
39
|
-
constructor(message, details) {
|
|
40
|
-
super(message);
|
|
41
|
-
this.name = "CodedError";
|
|
42
|
-
this.details = {
|
|
43
|
-
...details,
|
|
44
|
-
retryable: details.retryable ?? false
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
/** An unknown reference, naming the valid ones closest to what was asked for, up to `alternativeLimit`. */
|
|
49
|
-
function unknownReference(code, message, reference, candidates, field) {
|
|
50
|
-
return new CodedError(message, {
|
|
51
|
-
code,
|
|
52
|
-
...field === void 0 ? {} : { field },
|
|
53
|
-
alternatives: closest(reference, candidates)
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Candidates sharing text with the reference first, ignoring case, then the rest by how few single-character edits
|
|
58
|
-
* away they are, so a typo's intended id makes the cut; ties keep their own order. All of them when they fit.
|
|
59
|
-
*/
|
|
60
|
-
function closest(reference, candidates, limit = 20) {
|
|
61
|
-
const unique = [...new Set(candidates)];
|
|
62
|
-
if (unique.length <= limit) return unique;
|
|
63
|
-
const wanted = reference.toLowerCase();
|
|
64
|
-
const ranked = unique.map((candidate, index) => {
|
|
65
|
-
const lower = candidate.toLowerCase();
|
|
66
|
-
const near = wanted.length > 0 && (lower.includes(wanted) || wanted.includes(lower));
|
|
67
|
-
return {
|
|
68
|
-
candidate,
|
|
69
|
-
index,
|
|
70
|
-
near: near ? 0 : 1,
|
|
71
|
-
distance: near ? 0 : editDistance(wanted, lower)
|
|
72
|
-
};
|
|
73
|
-
});
|
|
74
|
-
ranked.sort((a, b) => a.near - b.near || a.distance - b.distance || a.index - b.index);
|
|
75
|
-
return ranked.slice(0, limit).map(({ candidate }) => candidate);
|
|
76
|
-
}
|
|
77
|
-
/** How many single-character insertions, deletions or substitutions turn one string into the other. */
|
|
78
|
-
function editDistance(a, b) {
|
|
79
|
-
let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
80
|
-
for (let i = 1; i <= a.length; i++) {
|
|
81
|
-
const row = [i];
|
|
82
|
-
for (let j = 1; j <= b.length; j++) row[j] = Math.min(previous[j] + 1, row[j - 1] + 1, previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
83
|
-
previous = row;
|
|
84
|
-
}
|
|
85
|
-
return previous[b.length];
|
|
86
|
-
}
|
|
87
|
-
/** A thrown value's details, when it carries them. */
|
|
88
|
-
function errorDetails(error) {
|
|
89
|
-
return error instanceof CodedError ? error.details : void 0;
|
|
90
|
-
}
|
|
91
|
-
/** Details that came from another process, checked before they're trusted. Anything malformed reads as none. */
|
|
92
|
-
function readErrorDetails(value) {
|
|
93
|
-
return errorDetailsSchema.safeParse(value).data;
|
|
94
|
-
}
|
|
95
|
-
z.record(z.string(), z.unknown());
|
|
96
|
-
/** Text with something besides whitespace, trimmed. */
|
|
97
|
-
const nonBlankString = z.string().trim().min(1, "can't be blank");
|
|
98
|
-
z.number();
|
|
99
|
-
/** JSON text holding what `schema` checks. Text that isn't JSON fails as `expected JSON`. */
|
|
100
|
-
function jsonText(schema) {
|
|
101
|
-
return z.string().transform((text, context) => {
|
|
102
|
-
try {
|
|
103
|
-
return JSON.parse(text);
|
|
104
|
-
} catch {
|
|
105
|
-
context.addIssue({
|
|
106
|
-
code: "custom",
|
|
107
|
-
message: "expected JSON"
|
|
108
|
-
});
|
|
109
|
-
return z.NEVER;
|
|
110
|
-
}
|
|
111
|
-
}).pipe(schema);
|
|
112
|
-
}
|
|
113
|
-
export { errorCodes as a, unknownReference as c, closest as i, nonBlankString as n, errorDetails as o, CodedError as r, readErrorDetails as s, jsonText as t };
|
package/dist/src-5CrSA_RX.mjs
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { p as parseLibraryManifest, u as libraryManifestExtension } from "./src-C4faIpux.mjs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
6
|
-
import semver from "semver";
|
|
7
|
-
// ../registry/src/index.ts
|
|
8
|
-
const require = createRequire(import.meta.url);
|
|
9
|
-
/**
|
|
10
|
-
* The folder the registry's files are in. The published CLI bundles this module and ships the files beside it, where
|
|
11
|
-
* the package can't be resolved. Otherwise they're found through the package's own `package.json`, so it's the same
|
|
12
|
-
* whether this module runs from source or bundled into the app.
|
|
13
|
-
*/
|
|
14
|
-
function registryDir() {
|
|
15
|
-
const bundled = join(import.meta.dirname, "libraries");
|
|
16
|
-
if (existsSync(bundled)) return bundled;
|
|
17
|
-
return join(dirname(require.resolve("@parity-app/registry/package.json")), "libraries");
|
|
18
|
-
}
|
|
19
|
-
let cache;
|
|
20
|
-
/** Every file in the registry, read once. One that doesn't parse is skipped with a warning. */
|
|
21
|
-
function registryEntries(dir = registryDir()) {
|
|
22
|
-
if (dir !== registryDir()) return readEntries(dir);
|
|
23
|
-
cache ??= readEntries(dir);
|
|
24
|
-
return cache;
|
|
25
|
-
}
|
|
26
|
-
async function readEntries(dir) {
|
|
27
|
-
const files = (await readdir(dir).catch(() => [])).filter((file) => file.endsWith(libraryManifestExtension)).sort();
|
|
28
|
-
const entries = [];
|
|
29
|
-
for (const file of files) {
|
|
30
|
-
const path = join(dir, file);
|
|
31
|
-
try {
|
|
32
|
-
const manifest = parseLibraryManifest(JSON.parse(await readFile(path, "utf8")));
|
|
33
|
-
if (!manifest.package) throw new TypeError("/package: a registry file names the package it describes");
|
|
34
|
-
entries.push({
|
|
35
|
-
file,
|
|
36
|
-
path,
|
|
37
|
-
manifest
|
|
38
|
-
});
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.warn(`Skipping registry file ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return entries;
|
|
44
|
-
}
|
|
45
|
-
/** Whether a manifest describes this version of its package. A manifest without a range covers every version. */
|
|
46
|
-
function covers(manifest, version) {
|
|
47
|
-
const range = manifest.package?.range;
|
|
48
|
-
if (!range) return true;
|
|
49
|
-
if (!version) return false;
|
|
50
|
-
const parsed = semver.coerce(version, { includePrerelease: true });
|
|
51
|
-
return parsed !== null && semver.satisfies(parsed, range, { includePrerelease: true });
|
|
52
|
-
}
|
|
53
|
-
export { registryDir as n, registryEntries as r, covers as t };
|
package/dist/src-Cr8pfFJE.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { t as covers, n as registryDir, r as registryEntries } from "./src-5CrSA_RX.mjs";
|
package/dist/src-p0vFxRBz.mjs
DELETED