nxds-cli 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +59 -18
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -178,17 +178,42 @@ function readJson(file) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
// src/url.ts
|
|
182
|
+
function httpUrl(value) {
|
|
183
|
+
const url = URL.canParse(value) ? new URL(value) : void 0;
|
|
184
|
+
return url?.protocol === "http:" || url?.protocol === "https:" ? url : void 0;
|
|
185
|
+
}
|
|
186
|
+
function assertRegistryUrl(flag, value, privateRegistryHint) {
|
|
187
|
+
const url = httpUrl(value);
|
|
188
|
+
if (!url) {
|
|
189
|
+
throw new UsageError(
|
|
190
|
+
`${flag} is not a valid http or https URL. ${privateRegistryHint}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (url.username || url.password || /[?#]/.test(value)) {
|
|
194
|
+
throw new UsageError(
|
|
195
|
+
`${flag} can't include a user name, password, query or fragment. nxds-cli sends no registry login, and it adds file paths to the URL. ${privateRegistryHint}`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
181
200
|
// src/catalog.ts
|
|
182
201
|
var SETUP = "setup";
|
|
183
202
|
var DEFAULT_REGISTRY = "https://nxds.dev/r";
|
|
184
203
|
var FETCH_TIMEOUT_MS = 3e4;
|
|
185
204
|
var dispatcher = new EnvHttpProxyAgent();
|
|
186
205
|
function isUrl(registry) {
|
|
187
|
-
return
|
|
206
|
+
return /^\s*[a-z][a-z\d+.-]+:/i.test(registry);
|
|
188
207
|
}
|
|
189
208
|
function resolveRegistry(option) {
|
|
190
209
|
if (!option) return DEFAULT_REGISTRY;
|
|
191
|
-
|
|
210
|
+
if (!isUrl(option)) return path2.resolve(option);
|
|
211
|
+
assertRegistryUrl(
|
|
212
|
+
"--registry (or NXDS_REGISTRY_URL)",
|
|
213
|
+
option,
|
|
214
|
+
"For a private registry, download its latest.json and <version>.json files to a folder, and pass the folder with --registry."
|
|
215
|
+
);
|
|
216
|
+
return option.replace(/\/+$/, "");
|
|
192
217
|
}
|
|
193
218
|
function timeoutError(url, error) {
|
|
194
219
|
if (!(error instanceof Error) || error.name !== "TimeoutError") return null;
|
|
@@ -244,7 +269,7 @@ async function fetchRelease(registry, version) {
|
|
|
244
269
|
if (isNewerSchema(value)) {
|
|
245
270
|
const release = version === "latest" ? "The latest nxds release" : `nxds ${version}`;
|
|
246
271
|
throw new CliError(
|
|
247
|
-
`${release} needs a newer nxds-cli than ${"0.4.
|
|
272
|
+
`${release} needs a newer nxds-cli than ${"0.4.1"}. Run \`${CLI_COMMAND}\` to get the newest one.`
|
|
248
273
|
);
|
|
249
274
|
}
|
|
250
275
|
const invalid = (problems) => new CliError(
|
|
@@ -1615,7 +1640,16 @@ var DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
|
|
|
1615
1640
|
var DEFAULT_EXPORT_DIR = "nxds-design-system";
|
|
1616
1641
|
var FETCH_TIMEOUT_MS2 = 6e4;
|
|
1617
1642
|
var dispatcher2 = new EnvHttpProxyAgent2();
|
|
1643
|
+
function redactUrl(url) {
|
|
1644
|
+
const redacted = httpUrl(url);
|
|
1645
|
+
if (!redacted) return "<invalid URL>";
|
|
1646
|
+
redacted.username = "";
|
|
1647
|
+
redacted.password = "";
|
|
1648
|
+
redacted.search = "";
|
|
1649
|
+
return redacted.href;
|
|
1650
|
+
}
|
|
1618
1651
|
async function download(url) {
|
|
1652
|
+
const shown = redactUrl(url);
|
|
1619
1653
|
let response;
|
|
1620
1654
|
try {
|
|
1621
1655
|
response = await fetch2(url, {
|
|
@@ -1624,14 +1658,14 @@ async function download(url) {
|
|
|
1624
1658
|
});
|
|
1625
1659
|
} catch (error) {
|
|
1626
1660
|
const { message, cause } = error;
|
|
1627
|
-
const reason = cause instanceof Error ? cause.message : message;
|
|
1661
|
+
const reason = (cause instanceof Error ? cause.message : message).replaceAll(url, () => shown);
|
|
1628
1662
|
throw new CliError(
|
|
1629
|
-
`Could not reach ${
|
|
1663
|
+
`Could not reach ${shown} (${reason}). Check your connection, or set HTTPS_PROXY if you are behind a proxy, then run the command again.`
|
|
1630
1664
|
);
|
|
1631
1665
|
}
|
|
1632
1666
|
if (!response.ok) {
|
|
1633
1667
|
throw new CliError(
|
|
1634
|
-
`${
|
|
1668
|
+
`${shown} answered ${response.status}. Run the command again later.`
|
|
1635
1669
|
);
|
|
1636
1670
|
}
|
|
1637
1671
|
return Buffer.from(await response.arrayBuffer());
|
|
@@ -1640,6 +1674,11 @@ function packageUrl(registry) {
|
|
|
1640
1674
|
return `${registry.replace(/\/+$/, "")}/${CLAUDE_DESIGN_PACKAGE.replace("/", "%2f")}`;
|
|
1641
1675
|
}
|
|
1642
1676
|
async function resolveTarball(registry, release) {
|
|
1677
|
+
assertRegistryUrl(
|
|
1678
|
+
"--npm-registry (or npm_config_registry)",
|
|
1679
|
+
registry,
|
|
1680
|
+
`For a private registry, unpack the tarball from \`npm pack ${CLAUDE_DESIGN_PACKAGE}\` and pass its package folder with --source.`
|
|
1681
|
+
);
|
|
1643
1682
|
const url = packageUrl(registry);
|
|
1644
1683
|
const body = (await download(url)).toString("utf8");
|
|
1645
1684
|
let packument;
|
|
@@ -1647,7 +1686,7 @@ async function resolveTarball(registry, release) {
|
|
|
1647
1686
|
packument = JSON.parse(body);
|
|
1648
1687
|
} catch {
|
|
1649
1688
|
throw new CliError(
|
|
1650
|
-
`${url} didn't answer with JSON. Check --npm-registry, or your proxy, then run the command again.`
|
|
1689
|
+
`${redactUrl(url)} didn't answer with JSON. Check --npm-registry, or your proxy, then run the command again.`
|
|
1651
1690
|
);
|
|
1652
1691
|
}
|
|
1653
1692
|
const version = packument["dist-tags"]?.[release] ?? release;
|
|
@@ -1664,13 +1703,13 @@ function checkIntegrity(bytes, integrity, tarball) {
|
|
|
1664
1703
|
const expected = integrity.split(/\s+/).find((entry) => entry.startsWith("sha512-"));
|
|
1665
1704
|
if (!expected) {
|
|
1666
1705
|
throw new CliError(
|
|
1667
|
-
`${tarball} has no sha512 integrity to check it against.`
|
|
1706
|
+
`${redactUrl(tarball)} has no sha512 integrity to check it against.`
|
|
1668
1707
|
);
|
|
1669
1708
|
}
|
|
1670
1709
|
const actual = `sha512-${createHash("sha512").update(bytes).digest("base64")}`;
|
|
1671
1710
|
if (actual !== expected) {
|
|
1672
1711
|
throw new CliError(
|
|
1673
|
-
`${tarball} doesn't match its published integrity. Run the command again; if it keeps failing, report it.`
|
|
1712
|
+
`${redactUrl(tarball)} doesn't match its published integrity. Run the command again; if it keeps failing, report it.`
|
|
1674
1713
|
);
|
|
1675
1714
|
}
|
|
1676
1715
|
}
|
|
@@ -2233,12 +2272,13 @@ async function update(cwd, registry, options) {
|
|
|
2233
2272
|
}
|
|
2234
2273
|
|
|
2235
2274
|
// src/cli.ts
|
|
2275
|
+
function cwdOf(command) {
|
|
2276
|
+
const { cwd } = command.optsWithGlobals();
|
|
2277
|
+
return path13.resolve(cwd ?? process.cwd());
|
|
2278
|
+
}
|
|
2236
2279
|
function context(command) {
|
|
2237
|
-
const {
|
|
2238
|
-
return {
|
|
2239
|
-
cwd: path13.resolve(cwd ?? process.cwd()),
|
|
2240
|
-
registry: resolveRegistry(registry)
|
|
2241
|
-
};
|
|
2280
|
+
const { registry } = command.optsWithGlobals();
|
|
2281
|
+
return { cwd: cwdOf(command), registry: resolveRegistry(registry) };
|
|
2242
2282
|
}
|
|
2243
2283
|
function installOptions(command) {
|
|
2244
2284
|
const flags = command.opts();
|
|
@@ -2258,7 +2298,7 @@ function program(done, write) {
|
|
|
2258
2298
|
// Errors are printed once, by `main`, as text or JSON.
|
|
2259
2299
|
outputError: () => {
|
|
2260
2300
|
}
|
|
2261
|
-
}).exitOverride().name(CLI_COMMAND).description("Add nxds to your app.").version("0.4.
|
|
2301
|
+
}).exitOverride().name(CLI_COMMAND).description("Add nxds to your app.").version("0.4.1", "-v, --version", "print the version").helpOption("-h, --help", "show help").helpCommand("help [command]", "show help for a command").option("--json", "print machine-readable JSON").option("--cwd <path>", "run in another folder").addOption(
|
|
2262
2302
|
new Option(
|
|
2263
2303
|
"--registry <url|path>",
|
|
2264
2304
|
"where to get nxds releases (default: https://nxds.dev/r)"
|
|
@@ -2312,7 +2352,7 @@ Docs: https://nxds.dev/getting-started/install`
|
|
|
2312
2352
|
done(await view(cwd, registry, item));
|
|
2313
2353
|
});
|
|
2314
2354
|
cli.command("info").description("show what the CLI detects in this app").action((_options, command) => {
|
|
2315
|
-
done(info(
|
|
2355
|
+
done(info(cwdOf(command)));
|
|
2316
2356
|
});
|
|
2317
2357
|
cli.command("diff").description("compare your nxds files with the latest release").argument("[items...]", "item names (default: every installed item)").action(async (items, _options, command) => {
|
|
2318
2358
|
const { cwd, registry } = context(command);
|
|
@@ -2337,8 +2377,9 @@ Docs: https://nxds.dev/getting-started/install`
|
|
|
2337
2377
|
`npm registry to download from (default: ${DEFAULT_NPM_REGISTRY})`
|
|
2338
2378
|
).env("npm_config_registry")
|
|
2339
2379
|
).action(async (_target, _options, command) => {
|
|
2340
|
-
|
|
2341
|
-
|
|
2380
|
+
done(
|
|
2381
|
+
await exportClaudeDesign(cwdOf(command), command.opts())
|
|
2382
|
+
);
|
|
2342
2383
|
});
|
|
2343
2384
|
cli.command("doctor").description("check that nxds is wired up correctly").action(async (_options, command) => {
|
|
2344
2385
|
const { cwd, registry } = context(command);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nxds-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Install nxds components, blocks and setup into your app.",
|
|
6
6
|
"keywords": [
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"@types/semver": "^7.8.0",
|
|
46
46
|
"tsup": "^8.5.1",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
|
-
"@nxds/
|
|
49
|
-
"@nxds/
|
|
48
|
+
"@nxds/claude-design": "0.8.1",
|
|
49
|
+
"@nxds/catalog": "0.0.0"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"build": "tsup",
|