@lovo/matter-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/add-RALAFFV2.js +10 -0
- package/dist/add-RALAFFV2.js.map +1 -0
- package/dist/add-WFXJ7HFS.js +10 -0
- package/dist/add-WFXJ7HFS.js.map +1 -0
- package/dist/chunk-EBCJ5BNB.js +90 -0
- package/dist/chunk-EBCJ5BNB.js.map +1 -0
- package/dist/chunk-PWYRLP7T.js +90 -0
- package/dist/chunk-PWYRLP7T.js.map +1 -0
- package/dist/chunk-QTD5MDLV.js +75 -0
- package/dist/chunk-QTD5MDLV.js.map +1 -0
- package/dist/chunk-QVVHELUY.js +92 -0
- package/dist/chunk-QVVHELUY.js.map +1 -0
- package/dist/chunk-V774PVEJ.js +92 -0
- package/dist/chunk-V774PVEJ.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/init-UZXT3TDQ.js +26 -0
- package/dist/init-UZXT3TDQ.js.map +1 -0
- package/dist/init-W2VK6JT2.js +26 -0
- package/dist/init-W2VK6JT2.js.map +1 -0
- package/dist/list-BS5GAYO3.js +39 -0
- package/dist/list-BS5GAYO3.js.map +1 -0
- package/dist/list-E4KR6FTJ.js +39 -0
- package/dist/list-E4KR6FTJ.js.map +1 -0
- package/dist/update-JRITSIKU.js +75 -0
- package/dist/update-JRITSIKU.js.map +1 -0
- package/dist/update-TAPYOHLT.js +75 -0
- package/dist/update-TAPYOHLT.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
fetchComponentSource,
|
|
4
|
+
fetchRegistry,
|
|
5
|
+
resolveRef
|
|
6
|
+
} from "./chunk-QTD5MDLV.js";
|
|
7
|
+
import {
|
|
8
|
+
readMatterConfig
|
|
9
|
+
} from "./chunk-PWYRLP7T.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/add.ts
|
|
12
|
+
import { access, mkdir, writeFile } from "fs/promises";
|
|
13
|
+
import { dirname, join } from "path";
|
|
14
|
+
|
|
15
|
+
// src/transforms/rewriteImports.ts
|
|
16
|
+
function rewriteImports(source, aliases) {
|
|
17
|
+
const sortedAliases = Object.entries(aliases).sort(([a], [b]) => b.length - a.length);
|
|
18
|
+
if (sortedAliases.length === 0) return source;
|
|
19
|
+
const importRe = /(\bfrom\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;
|
|
20
|
+
return source.replace(importRe, (full, lead, quote, spec) => {
|
|
21
|
+
for (const [key, value] of sortedAliases) {
|
|
22
|
+
if (spec.startsWith(key)) {
|
|
23
|
+
return `${lead}${quote}${value}${spec.slice(key.length)}${quote}`;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return full;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/commands/add.ts
|
|
31
|
+
async function runAdd(components, opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
32
|
+
if (components.length === 0) {
|
|
33
|
+
throw new Error("add: at least one component name is required");
|
|
34
|
+
}
|
|
35
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
36
|
+
const baseUrl = opts.registry ?? cfg.registryUrl;
|
|
37
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
38
|
+
const registryUrl = baseUrl.replace("${ref}", ref);
|
|
39
|
+
const registry = await fetchRegistry(registryUrl);
|
|
40
|
+
const resolved = components.map((slug) => resolveComponent(slug, registry, registryUrl));
|
|
41
|
+
if (!opts.force) {
|
|
42
|
+
for (const r of resolved) {
|
|
43
|
+
const targetPath = join(io.cwd, cfg.componentsDir, r.entry.file);
|
|
44
|
+
if (await fileExists(targetPath)) {
|
|
45
|
+
throw new Error(`${targetPath} already exists. Pass --force to overwrite.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const fetched = await Promise.all(
|
|
50
|
+
resolved.map(async (r) => {
|
|
51
|
+
const source = await fetchComponentSource(registryUrl, r.entry.file);
|
|
52
|
+
return { ...r, source };
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
56
|
+
for (const f of fetched) {
|
|
57
|
+
const targetPath = join(io.cwd, cfg.componentsDir, f.entry.file);
|
|
58
|
+
const rewritten = rewriteImports(f.source, cfg.aliases);
|
|
59
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
60
|
+
await writeFile(targetPath, rewritten, "utf-8");
|
|
61
|
+
io.log(`Wrote ${targetPath}`);
|
|
62
|
+
for (const dep of f.entry.dependencies) allDeps.add(dep);
|
|
63
|
+
}
|
|
64
|
+
const sortedDeps = [...allDeps].sort();
|
|
65
|
+
io.log("");
|
|
66
|
+
io.log(`This component requires: ${sortedDeps.join(", ")}`);
|
|
67
|
+
io.log("Install with your package manager, e.g.:");
|
|
68
|
+
io.log(`npm install ${sortedDeps.join(" ")}`);
|
|
69
|
+
}
|
|
70
|
+
function resolveComponent(slug, registry, registryUrl) {
|
|
71
|
+
const entry = registry.components[slug];
|
|
72
|
+
if (!entry) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Component "${slug}" not found in registry at ${registryUrl}. Run \`matter-cli list\` to see available components.`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return { slug, entry };
|
|
78
|
+
}
|
|
79
|
+
async function fileExists(p) {
|
|
80
|
+
try {
|
|
81
|
+
await access(p);
|
|
82
|
+
return true;
|
|
83
|
+
} catch (err) {
|
|
84
|
+
if (err.code === "ENOENT") return false;
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
runAdd
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-QVVHELUY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/add.ts","../src/transforms/rewriteImports.ts"],"sourcesContent":["import { access, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { readMatterConfig } from '../config/matterConfig.js'\nimport {\n fetchComponentSource,\n fetchRegistry,\n type Registry,\n type RegistryEntry,\n} from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\nimport { rewriteImports } from '../transforms/rewriteImports.js'\n\nexport interface AddOptions {\n registry?: string\n ref?: string\n force?: boolean\n cliVersion: string\n}\n\nexport interface AddIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runAdd(\n components: string[],\n opts: AddOptions,\n io: AddIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n if (components.length === 0) {\n throw new Error('add: at least one component name is required')\n }\n\n const cfg = await readMatterConfig(io.cwd)\n const baseUrl = opts.registry ?? cfg.registryUrl\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const registryUrl = baseUrl.replace('${ref}', ref)\n const registry = await fetchRegistry(registryUrl)\n\n // Resolve every component up front so we fail fast on missing slugs\n // before any disk write.\n const resolved = components.map((slug) => resolveComponent(slug, registry, registryUrl))\n\n // Pre-flight overwrite check on every target.\n if (!opts.force) {\n for (const r of resolved) {\n const targetPath = join(io.cwd, cfg.componentsDir, r.entry.file)\n if (await fileExists(targetPath)) {\n throw new Error(`${targetPath} already exists. Pass --force to overwrite.`)\n }\n }\n }\n\n // Fetch all sources concurrently. If any fetch fails, the throw\n // propagates before we touch disk — no partial-write states.\n const fetched = await Promise.all(\n resolved.map(async (r) => {\n const source = await fetchComponentSource(registryUrl, r.entry.file)\n return { ...r, source }\n }),\n )\n\n // Now write sequentially (mkdir + writeFile per target). Sequential\n // here is fine: the bottleneck has already passed.\n const allDeps = new Set<string>()\n for (const f of fetched) {\n const targetPath = join(io.cwd, cfg.componentsDir, f.entry.file)\n const rewritten = rewriteImports(f.source, cfg.aliases)\n await mkdir(dirname(targetPath), { recursive: true })\n await writeFile(targetPath, rewritten, 'utf-8')\n io.log(`Wrote ${targetPath}`)\n for (const dep of f.entry.dependencies) allDeps.add(dep)\n }\n\n // Dedup + alphabetize install hint.\n const sortedDeps = [...allDeps].sort()\n io.log('')\n io.log(`This component requires: ${sortedDeps.join(', ')}`)\n io.log('Install with your package manager, e.g.:')\n io.log(`npm install ${sortedDeps.join(' ')}`)\n}\n\nfunction resolveComponent(\n slug: string,\n registry: Registry,\n registryUrl: string,\n): { slug: string; entry: RegistryEntry } {\n const entry = registry.components[slug]\n if (!entry) {\n throw new Error(\n `Component \"${slug}\" not found in registry at ${registryUrl}. Run \\`matter-cli list\\` to see available components.`,\n )\n }\n return { slug, entry }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw err\n }\n}\n","/**\n * Rewrite import specifiers in a TS/TSX source string per a prefix-match\n * alias map. Each alias key is treated as a literal prefix; if a specifier\n * starts with the key, the prefix is replaced with the value.\n *\n * v1's Tier 1 components don't actually use any internal aliases — every\n * import resolves to a published npm package (`@lovo/matter`,\n * `@lovo/matter-react`, `react`, `three`). The synthetic test fixture\n * imports `@matter-internal/lib` to exercise this code path. When future\n * components do share internal utilities, this rewriter is what shapes\n * those imports per the user's project layout.\n *\n * Longer alias keys win over shorter ones (so `@matter-internal/` beats\n * `@/` when both match).\n */\nexport function rewriteImports(source: string, aliases: Record<string, string>): string {\n const sortedAliases = Object.entries(aliases).sort(([a], [b]) => b.length - a.length)\n if (sortedAliases.length === 0) return source\n\n // Match `from '...'` / `from \"...\"` / `import('...')` / `import(\"...\")`.\n const importRe = /(\\bfrom\\s+|\\bimport\\s*\\(\\s*)(['\"])([^'\"]+)\\2/g\n\n return source.replace(importRe, (full, lead: string, quote: string, spec: string) => {\n for (const [key, value] of sortedAliases) {\n if (spec.startsWith(key)) {\n return `${lead}${quote}${value}${spec.slice(key.length)}${quote}`\n }\n }\n return full\n })\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
fetchComponentSource,
|
|
4
|
+
fetchRegistry,
|
|
5
|
+
resolveRef
|
|
6
|
+
} from "./chunk-QTD5MDLV.js";
|
|
7
|
+
import {
|
|
8
|
+
readMatterConfig
|
|
9
|
+
} from "./chunk-EBCJ5BNB.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/add.ts
|
|
12
|
+
import { access, mkdir, writeFile } from "fs/promises";
|
|
13
|
+
import { dirname, join } from "path";
|
|
14
|
+
|
|
15
|
+
// src/transforms/rewriteImports.ts
|
|
16
|
+
function rewriteImports(source, aliases) {
|
|
17
|
+
const sortedAliases = Object.entries(aliases).sort(([a], [b]) => b.length - a.length);
|
|
18
|
+
if (sortedAliases.length === 0) return source;
|
|
19
|
+
const importRe = /(\bfrom\s+|\bimport\s*\(\s*)(['"])([^'"]+)\2/g;
|
|
20
|
+
return source.replace(importRe, (full, lead, quote, spec) => {
|
|
21
|
+
for (const [key, value] of sortedAliases) {
|
|
22
|
+
if (spec.startsWith(key)) {
|
|
23
|
+
return `${lead}${quote}${value}${spec.slice(key.length)}${quote}`;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return full;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/commands/add.ts
|
|
31
|
+
async function runAdd(components, opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
32
|
+
if (components.length === 0) {
|
|
33
|
+
throw new Error("add: at least one component name is required");
|
|
34
|
+
}
|
|
35
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
36
|
+
const baseUrl = opts.registry ?? cfg.registryUrl;
|
|
37
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
38
|
+
const registryUrl = baseUrl.replace("${ref}", ref);
|
|
39
|
+
const registry = await fetchRegistry(registryUrl);
|
|
40
|
+
const resolved = components.map((slug) => resolveComponent(slug, registry, registryUrl));
|
|
41
|
+
if (!opts.force) {
|
|
42
|
+
for (const r of resolved) {
|
|
43
|
+
const targetPath = join(io.cwd, cfg.componentsDir, r.entry.file);
|
|
44
|
+
if (await fileExists(targetPath)) {
|
|
45
|
+
throw new Error(`${targetPath} already exists. Pass --force to overwrite.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const fetched = await Promise.all(
|
|
50
|
+
resolved.map(async (r) => {
|
|
51
|
+
const source = await fetchComponentSource(registryUrl, r.entry.file);
|
|
52
|
+
return { ...r, source };
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
56
|
+
for (const f of fetched) {
|
|
57
|
+
const targetPath = join(io.cwd, cfg.componentsDir, f.entry.file);
|
|
58
|
+
const rewritten = rewriteImports(f.source, cfg.aliases);
|
|
59
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
60
|
+
await writeFile(targetPath, rewritten, "utf-8");
|
|
61
|
+
io.log(`Wrote ${targetPath}`);
|
|
62
|
+
for (const dep of f.entry.dependencies) allDeps.add(dep);
|
|
63
|
+
}
|
|
64
|
+
const sortedDeps = [...allDeps].sort();
|
|
65
|
+
io.log("");
|
|
66
|
+
io.log(`This component requires: ${sortedDeps.join(", ")}`);
|
|
67
|
+
io.log("Install with your package manager, e.g.:");
|
|
68
|
+
io.log(`npm install ${sortedDeps.join(" ")}`);
|
|
69
|
+
}
|
|
70
|
+
function resolveComponent(slug, registry, registryUrl) {
|
|
71
|
+
const entry = registry.components[slug];
|
|
72
|
+
if (!entry) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Component "${slug}" not found in registry at ${registryUrl}. Run \`matter-cli list\` to see available components.`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return { slug, entry };
|
|
78
|
+
}
|
|
79
|
+
async function fileExists(p) {
|
|
80
|
+
try {
|
|
81
|
+
await access(p);
|
|
82
|
+
return true;
|
|
83
|
+
} catch (err) {
|
|
84
|
+
if (err.code === "ENOENT") return false;
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
runAdd
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-V774PVEJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/add.ts","../src/transforms/rewriteImports.ts"],"sourcesContent":["import { access, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { readMatterConfig } from '../config/matterConfig.js'\nimport {\n fetchComponentSource,\n fetchRegistry,\n type Registry,\n type RegistryEntry,\n} from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\nimport { rewriteImports } from '../transforms/rewriteImports.js'\n\nexport interface AddOptions {\n registry?: string\n ref?: string\n force?: boolean\n cliVersion: string\n}\n\nexport interface AddIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runAdd(\n components: string[],\n opts: AddOptions,\n io: AddIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n if (components.length === 0) {\n throw new Error('add: at least one component name is required')\n }\n\n const cfg = await readMatterConfig(io.cwd)\n const baseUrl = opts.registry ?? cfg.registryUrl\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const registryUrl = baseUrl.replace('${ref}', ref)\n const registry = await fetchRegistry(registryUrl)\n\n // Resolve every component up front so we fail fast on missing slugs\n // before any disk write.\n const resolved = components.map((slug) => resolveComponent(slug, registry, registryUrl))\n\n // Pre-flight overwrite check on every target.\n if (!opts.force) {\n for (const r of resolved) {\n const targetPath = join(io.cwd, cfg.componentsDir, r.entry.file)\n if (await fileExists(targetPath)) {\n throw new Error(`${targetPath} already exists. Pass --force to overwrite.`)\n }\n }\n }\n\n // Fetch all sources concurrently. If any fetch fails, the throw\n // propagates before we touch disk — no partial-write states.\n const fetched = await Promise.all(\n resolved.map(async (r) => {\n const source = await fetchComponentSource(registryUrl, r.entry.file)\n return { ...r, source }\n }),\n )\n\n // Now write sequentially (mkdir + writeFile per target). Sequential\n // here is fine: the bottleneck has already passed.\n const allDeps = new Set<string>()\n for (const f of fetched) {\n const targetPath = join(io.cwd, cfg.componentsDir, f.entry.file)\n const rewritten = rewriteImports(f.source, cfg.aliases)\n await mkdir(dirname(targetPath), { recursive: true })\n await writeFile(targetPath, rewritten, 'utf-8')\n io.log(`Wrote ${targetPath}`)\n for (const dep of f.entry.dependencies) allDeps.add(dep)\n }\n\n // Dedup + alphabetize install hint.\n const sortedDeps = [...allDeps].sort()\n io.log('')\n io.log(`This component requires: ${sortedDeps.join(', ')}`)\n io.log('Install with your package manager, e.g.:')\n io.log(`npm install ${sortedDeps.join(' ')}`)\n}\n\nfunction resolveComponent(\n slug: string,\n registry: Registry,\n registryUrl: string,\n): { slug: string; entry: RegistryEntry } {\n const entry = registry.components[slug]\n if (!entry) {\n throw new Error(\n `Component \"${slug}\" not found in registry at ${registryUrl}. Run \\`matter-cli list\\` to see available components.`,\n )\n }\n return { slug, entry }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw err\n }\n}\n","/**\n * Rewrite import specifiers in a TS/TSX source string per a prefix-match\n * alias map. Each alias key is treated as a literal prefix; if a specifier\n * starts with the key, the prefix is replaced with the value.\n *\n * v1's Tier 1 components don't actually use any internal aliases — every\n * import resolves to a published npm package (`@lovo/matter`,\n * `@lovo/matter-react`, `react`, `three`). The synthetic test fixture\n * imports `@matter-internal/lib` to exercise this code path. When future\n * components do share internal utilities, this rewriter is what shapes\n * those imports per the user's project layout.\n *\n * Longer alias keys win over shorter ones (so `@matter-internal/` beats\n * `@/` when both match).\n */\nexport function rewriteImports(source: string, aliases: Record<string, string>): string {\n const sortedAliases = Object.entries(aliases).sort(([a], [b]) => b.length - a.length)\n if (sortedAliases.length === 0) return source\n\n // Match `from '...'` / `from \"...\"` / `import('...')` / `import(\"...\")`.\n const importRe = /(\\bfrom\\s+|\\bimport\\s*\\(\\s*)(['\"])([^'\"]+)\\2/g\n\n return source.replace(importRe, (full, lead: string, quote: string, spec: string) => {\n for (const [key, value] of sortedAliases) {\n if (spec.startsWith(key)) {\n return `${lead}${quote}${value}${spec.slice(key.length)}${quote}`\n }\n }\n return full\n })\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
function fail(err) {
|
|
6
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7
|
+
process.stderr.write(`error: ${message}
|
|
8
|
+
`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
var program = new Command();
|
|
12
|
+
program.name("matter-cli").description("CLI for Matter \u2014 copy-paste components from the registry into your project").version("0.1.0");
|
|
13
|
+
program.command("init").description("one-time project setup \u2014 writes matter.config.json").option("--force", "overwrite an existing matter.config.json").action(async (opts) => {
|
|
14
|
+
try {
|
|
15
|
+
const { runInit } = await import("./init-UZXT3TDQ.js");
|
|
16
|
+
await runInit(opts);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
fail(err);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
program.command("list").description("show available components in the registry").option("--registry <url>", "override the registryUrl from matter.config.json").option("--ref <ref>", "tag, branch, or commit (defaults to the CLI version)").action(async (opts) => {
|
|
22
|
+
try {
|
|
23
|
+
const { runList } = await import("./list-E4KR6FTJ.js");
|
|
24
|
+
await runList({ ...opts, cliVersion: "0.1.0" });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
fail(err);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
program.command("add").description("copy one or more components from the registry into componentsDir").argument("<components...>", 'component slugs (e.g. "linear-gradient")').option("--registry <url>", "override the registryUrl from matter.config.json").option("--ref <ref>", "tag, branch, or commit (defaults to the CLI version)").option("--force", "overwrite existing files in componentsDir").action(async (components, opts) => {
|
|
30
|
+
try {
|
|
31
|
+
const { runAdd } = await import("./add-WFXJ7HFS.js");
|
|
32
|
+
await runAdd(components, { ...opts, cliVersion: "0.1.0" });
|
|
33
|
+
} catch (err) {
|
|
34
|
+
fail(err);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
program.command("update").description("re-fetch a previously-added component (or all, if no name given)").argument("[components...]", "component slugs; omit to update every component in componentsDir").option("--registry <url>", "override the registryUrl from matter.config.json").option("--ref <ref>", "tag, branch, or commit (defaults to the CLI version)").option("--force", "overwrite files even if they have local edits").action(async (components, opts) => {
|
|
38
|
+
try {
|
|
39
|
+
const { runUpdate } = await import("./update-JRITSIKU.js");
|
|
40
|
+
await runUpdate(components ?? [], { ...opts, cliVersion: "0.1.0" });
|
|
41
|
+
} catch (err) {
|
|
42
|
+
fail(err);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
await program.parseAsync(process.argv);
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from 'commander'\n\ndeclare const __VERSION__: string\n\nfunction fail(err: unknown): never {\n const message = err instanceof Error ? err.message : String(err)\n process.stderr.write(`error: ${message}\\n`)\n process.exit(1)\n}\n\nconst program = new Command()\n\nprogram\n .name('matter-cli')\n .description('CLI for Matter — copy-paste components from the registry into your project')\n .version(__VERSION__)\n\nprogram\n .command('init')\n .description('one-time project setup — writes matter.config.json')\n .option('--force', 'overwrite an existing matter.config.json')\n .action(async (opts: { force?: boolean }) => {\n try {\n const { runInit } = await import('./commands/init.js')\n await runInit(opts)\n } catch (err) {\n fail(err)\n }\n })\n\nprogram\n .command('list')\n .description('show available components in the registry')\n .option('--registry <url>', 'override the registryUrl from matter.config.json')\n .option('--ref <ref>', 'tag, branch, or commit (defaults to the CLI version)')\n .action(async (opts: { registry?: string; ref?: string }) => {\n try {\n const { runList } = await import('./commands/list.js')\n await runList({ ...opts, cliVersion: __VERSION__ })\n } catch (err) {\n fail(err)\n }\n })\n\nprogram\n .command('add')\n .description('copy one or more components from the registry into componentsDir')\n .argument('<components...>', 'component slugs (e.g. \"linear-gradient\")')\n .option('--registry <url>', 'override the registryUrl from matter.config.json')\n .option('--ref <ref>', 'tag, branch, or commit (defaults to the CLI version)')\n .option('--force', 'overwrite existing files in componentsDir')\n .action(async (\n components: string[],\n opts: { registry?: string; ref?: string; force?: boolean },\n ) => {\n try {\n const { runAdd } = await import('./commands/add.js')\n await runAdd(components, { ...opts, cliVersion: __VERSION__ })\n } catch (err) {\n fail(err)\n }\n })\n\nprogram\n .command('update')\n .description('re-fetch a previously-added component (or all, if no name given)')\n .argument('[components...]', 'component slugs; omit to update every component in componentsDir')\n .option('--registry <url>', 'override the registryUrl from matter.config.json')\n .option('--ref <ref>', 'tag, branch, or commit (defaults to the CLI version)')\n .option('--force', 'overwrite files even if they have local edits')\n .action(async (\n components: string[],\n opts: { registry?: string; ref?: string; force?: boolean },\n ) => {\n try {\n const { runUpdate } = await import('./commands/update.js')\n await runUpdate(components ?? [], { ...opts, cliVersion: __VERSION__ })\n } catch (err) {\n fail(err)\n }\n })\n\nawait program.parseAsync(process.argv)\n"],"mappings":";;;AAAA,SAAS,eAAe;AAIxB,SAAS,KAAK,KAAqB;AACjC,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAQ,OAAO,MAAM,UAAU,OAAO;AAAA,CAAI;AAC1C,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,YAAY,EACjB,YAAY,iFAA4E,EACxF,QAAQ,OAAW;AAEtB,QACG,QAAQ,MAAM,EACd,YAAY,yDAAoD,EAChE,OAAO,WAAW,0CAA0C,EAC5D,OAAO,OAAO,SAA8B;AAC3C,MAAI;AACF,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,oBAAoB;AACrD,UAAM,QAAQ,IAAI;AAAA,EACpB,SAAS,KAAK;AACZ,SAAK,GAAG;AAAA,EACV;AACF,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,2CAA2C,EACvD,OAAO,oBAAoB,kDAAkD,EAC7E,OAAO,eAAe,sDAAsD,EAC5E,OAAO,OAAO,SAA8C;AAC3D,MAAI;AACF,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,oBAAoB;AACrD,UAAM,QAAQ,EAAE,GAAG,MAAM,YAAY,QAAY,CAAC;AAAA,EACpD,SAAS,KAAK;AACZ,SAAK,GAAG;AAAA,EACV;AACF,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,kEAAkE,EAC9E,SAAS,mBAAmB,0CAA0C,EACtE,OAAO,oBAAoB,kDAAkD,EAC7E,OAAO,eAAe,sDAAsD,EAC5E,OAAO,WAAW,2CAA2C,EAC7D,OAAO,OACN,YACA,SACG;AACH,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,OAAO,mBAAmB;AACnD,UAAM,OAAO,YAAY,EAAE,GAAG,MAAM,YAAY,QAAY,CAAC;AAAA,EAC/D,SAAS,KAAK;AACZ,SAAK,GAAG;AAAA,EACV;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,kEAAkE,EAC9E,SAAS,mBAAmB,kEAAkE,EAC9F,OAAO,oBAAoB,kDAAkD,EAC7E,OAAO,eAAe,sDAAsD,EAC5E,OAAO,WAAW,+CAA+C,EACjE,OAAO,OACN,YACA,SACG;AACH,MAAI;AACF,UAAM,EAAE,UAAU,IAAI,MAAM,OAAO,sBAAsB;AACzD,UAAM,UAAU,cAAc,CAAC,GAAG,EAAE,GAAG,MAAM,YAAY,QAAY,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,SAAK,GAAG;AAAA,EACV;AACF,CAAC;AAEH,MAAM,QAAQ,WAAW,QAAQ,IAAI;","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_MATTER_CONFIG,
|
|
4
|
+
configExists,
|
|
5
|
+
configPath,
|
|
6
|
+
writeMatterConfig
|
|
7
|
+
} from "./chunk-PWYRLP7T.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/init.ts
|
|
10
|
+
async function runInit(opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
11
|
+
const exists = await configExists(io.cwd);
|
|
12
|
+
if (exists && !opts.force) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`matter.config.json already exists in ${io.cwd}. Pass --force to overwrite.`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
await writeMatterConfig(io.cwd, DEFAULT_MATTER_CONFIG);
|
|
18
|
+
io.log(`Created matter.config.json at ${configPath(io.cwd)}`);
|
|
19
|
+
io.log(
|
|
20
|
+
"Edit `componentsDir` if your project uses a different layout, and adjust `aliases` to match your tsconfig paths."
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
runInit
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=init-UZXT3TDQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["import {\n DEFAULT_MATTER_CONFIG,\n configExists,\n configPath,\n writeMatterConfig,\n} from '../config/matterConfig.js'\n\nexport interface InitOptions {\n force?: boolean\n}\n\nexport interface InitIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runInit(\n opts: InitOptions,\n io: InitIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n const exists = await configExists(io.cwd)\n if (exists && !opts.force) {\n throw new Error(\n `matter.config.json already exists in ${io.cwd}. Pass --force to overwrite.`,\n )\n }\n await writeMatterConfig(io.cwd, DEFAULT_MATTER_CONFIG)\n io.log(`Created matter.config.json at ${configPath(io.cwd)}`)\n io.log(\n 'Edit `componentsDir` if your project uses a different layout, ' +\n 'and adjust `aliases` to match your tsconfig paths.',\n )\n}\n"],"mappings":";;;;;;;;;AAgBA,eAAsB,QACpB,MACA,KAAa,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACrC;AACf,QAAM,SAAS,MAAM,aAAa,GAAG,GAAG;AACxC,MAAI,UAAU,CAAC,KAAK,OAAO;AACzB,UAAM,IAAI;AAAA,MACR,wCAAwC,GAAG,GAAG;AAAA,IAChD;AAAA,EACF;AACA,QAAM,kBAAkB,GAAG,KAAK,qBAAqB;AACrD,KAAG,IAAI,iCAAiC,WAAW,GAAG,GAAG,CAAC,EAAE;AAC5D,KAAG;AAAA,IACD;AAAA,EAEF;AACF;","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_MATTER_CONFIG,
|
|
4
|
+
configExists,
|
|
5
|
+
configPath,
|
|
6
|
+
writeMatterConfig
|
|
7
|
+
} from "./chunk-EBCJ5BNB.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/init.ts
|
|
10
|
+
async function runInit(opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
11
|
+
const exists = await configExists(io.cwd);
|
|
12
|
+
if (exists && !opts.force) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`matter.config.json already exists in ${io.cwd}. Pass --force to overwrite.`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
await writeMatterConfig(io.cwd, DEFAULT_MATTER_CONFIG);
|
|
18
|
+
io.log(`Created matter.config.json at ${configPath(io.cwd)}`);
|
|
19
|
+
io.log(
|
|
20
|
+
"Edit `componentsDir` if your project uses a different layout, and adjust `aliases` to match your tsconfig paths."
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
runInit
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=init-W2VK6JT2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["import {\n DEFAULT_MATTER_CONFIG,\n configExists,\n configPath,\n writeMatterConfig,\n} from '../config/matterConfig.js'\n\nexport interface InitOptions {\n force?: boolean\n}\n\nexport interface InitIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runInit(\n opts: InitOptions,\n io: InitIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n const exists = await configExists(io.cwd)\n if (exists && !opts.force) {\n throw new Error(\n `matter.config.json already exists in ${io.cwd}. Pass --force to overwrite.`,\n )\n }\n await writeMatterConfig(io.cwd, DEFAULT_MATTER_CONFIG)\n io.log(`Created matter.config.json at ${configPath(io.cwd)}`)\n io.log(\n 'Edit `componentsDir` if your project uses a different layout, ' +\n 'and adjust `aliases` to match your tsconfig paths.',\n )\n}\n"],"mappings":";;;;;;;;;AAgBA,eAAsB,QACpB,MACA,KAAa,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACrC;AACf,QAAM,SAAS,MAAM,aAAa,GAAG,GAAG;AACxC,MAAI,UAAU,CAAC,KAAK,OAAO;AACzB,UAAM,IAAI;AAAA,MACR,wCAAwC,GAAG,GAAG;AAAA,IAChD;AAAA,EACF;AACA,QAAM,kBAAkB,GAAG,KAAK,qBAAqB;AACrD,KAAG,IAAI,iCAAiC,WAAW,GAAG,GAAG,CAAC,EAAE;AAC5D,KAAG;AAAA,IACD;AAAA,EAEF;AACF;","names":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
fetchRegistry,
|
|
4
|
+
resolveRef
|
|
5
|
+
} from "./chunk-QTD5MDLV.js";
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_MATTER_CONFIG,
|
|
8
|
+
configExists,
|
|
9
|
+
readMatterConfig
|
|
10
|
+
} from "./chunk-EBCJ5BNB.js";
|
|
11
|
+
|
|
12
|
+
// src/commands/list.ts
|
|
13
|
+
async function runList(opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
14
|
+
let baseUrl;
|
|
15
|
+
if (opts.registry !== void 0 && opts.registry !== "") {
|
|
16
|
+
baseUrl = opts.registry;
|
|
17
|
+
} else if (await configExists(io.cwd)) {
|
|
18
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
19
|
+
baseUrl = cfg.registryUrl;
|
|
20
|
+
} else {
|
|
21
|
+
baseUrl = DEFAULT_MATTER_CONFIG.registryUrl;
|
|
22
|
+
}
|
|
23
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
24
|
+
const url = baseUrl.replace("${ref}", ref);
|
|
25
|
+
const registry = await fetchRegistry(url);
|
|
26
|
+
const entries = Object.entries(registry.components).sort(([a], [b]) => a.localeCompare(b));
|
|
27
|
+
if (entries.length === 0) {
|
|
28
|
+
io.log("No components in registry.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const [slug, entry] of entries) {
|
|
32
|
+
const description = entry.description ?? "(no description)";
|
|
33
|
+
io.log(`${slug} \xB7 ${description} \xB7 tier ${entry.tier}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
runList
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=list-BS5GAYO3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/list.ts"],"sourcesContent":["import { DEFAULT_MATTER_CONFIG, configExists, readMatterConfig } from '../config/matterConfig.js'\nimport { fetchRegistry } from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\n\nexport interface ListOptions {\n registry?: string\n ref?: string\n cliVersion: string\n}\n\nexport interface ListIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runList(\n opts: ListOptions,\n io: ListIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n // URL resolution: --registry > matter.config.json > built-in default.\n // Missing config → default (lets users `list` before `init`). Malformed\n // config (invalid JSON, missing fields) → propagate so the user sees the\n // problem instead of silently falling back to the GitHub URL.\n let baseUrl: string\n if (opts.registry !== undefined && opts.registry !== '') {\n baseUrl = opts.registry\n } else if (await configExists(io.cwd)) {\n const cfg = await readMatterConfig(io.cwd)\n baseUrl = cfg.registryUrl\n } else {\n baseUrl = DEFAULT_MATTER_CONFIG.registryUrl\n }\n\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const url = baseUrl.replace('${ref}', ref)\n const registry = await fetchRegistry(url)\n const entries = Object.entries(registry.components).sort(([a], [b]) => a.localeCompare(b))\n\n if (entries.length === 0) {\n io.log('No components in registry.')\n return\n }\n\n for (const [slug, entry] of entries) {\n const description = entry.description ?? '(no description)'\n io.log(`${slug} · ${description} · tier ${entry.tier}`)\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,eAAsB,QACpB,MACA,KAAa,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACrC;AAKf,MAAI;AACJ,MAAI,KAAK,aAAa,UAAa,KAAK,aAAa,IAAI;AACvD,cAAU,KAAK;AAAA,EACjB,WAAW,MAAM,aAAa,GAAG,GAAG,GAAG;AACrC,UAAM,MAAM,MAAM,iBAAiB,GAAG,GAAG;AACzC,cAAU,IAAI;AAAA,EAChB,OAAO;AACL,cAAU,sBAAsB;AAAA,EAClC;AAEA,QAAM,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;AAChD,QAAM,MAAM,QAAQ,QAAQ,UAAU,GAAG;AACzC,QAAM,WAAW,MAAM,cAAc,GAAG;AACxC,QAAM,UAAU,OAAO,QAAQ,SAAS,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAEzF,MAAI,QAAQ,WAAW,GAAG;AACxB,OAAG,IAAI,4BAA4B;AACnC;AAAA,EACF;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,UAAM,cAAc,MAAM,eAAe;AACzC,OAAG,IAAI,GAAG,IAAI,SAAM,WAAW,cAAW,MAAM,IAAI,EAAE;AAAA,EACxD;AACF;","names":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
fetchRegistry,
|
|
4
|
+
resolveRef
|
|
5
|
+
} from "./chunk-QTD5MDLV.js";
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_MATTER_CONFIG,
|
|
8
|
+
configExists,
|
|
9
|
+
readMatterConfig
|
|
10
|
+
} from "./chunk-PWYRLP7T.js";
|
|
11
|
+
|
|
12
|
+
// src/commands/list.ts
|
|
13
|
+
async function runList(opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
14
|
+
let baseUrl;
|
|
15
|
+
if (opts.registry !== void 0 && opts.registry !== "") {
|
|
16
|
+
baseUrl = opts.registry;
|
|
17
|
+
} else if (await configExists(io.cwd)) {
|
|
18
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
19
|
+
baseUrl = cfg.registryUrl;
|
|
20
|
+
} else {
|
|
21
|
+
baseUrl = DEFAULT_MATTER_CONFIG.registryUrl;
|
|
22
|
+
}
|
|
23
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
24
|
+
const url = baseUrl.replace("${ref}", ref);
|
|
25
|
+
const registry = await fetchRegistry(url);
|
|
26
|
+
const entries = Object.entries(registry.components).sort(([a], [b]) => a.localeCompare(b));
|
|
27
|
+
if (entries.length === 0) {
|
|
28
|
+
io.log("No components in registry.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const [slug, entry] of entries) {
|
|
32
|
+
const description = entry.description ?? "(no description)";
|
|
33
|
+
io.log(`${slug} \xB7 ${description} \xB7 tier ${entry.tier}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
runList
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=list-E4KR6FTJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/list.ts"],"sourcesContent":["import { DEFAULT_MATTER_CONFIG, configExists, readMatterConfig } from '../config/matterConfig.js'\nimport { fetchRegistry } from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\n\nexport interface ListOptions {\n registry?: string\n ref?: string\n cliVersion: string\n}\n\nexport interface ListIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runList(\n opts: ListOptions,\n io: ListIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n // URL resolution: --registry > matter.config.json > built-in default.\n // Missing config → default (lets users `list` before `init`). Malformed\n // config (invalid JSON, missing fields) → propagate so the user sees the\n // problem instead of silently falling back to the GitHub URL.\n let baseUrl: string\n if (opts.registry !== undefined && opts.registry !== '') {\n baseUrl = opts.registry\n } else if (await configExists(io.cwd)) {\n const cfg = await readMatterConfig(io.cwd)\n baseUrl = cfg.registryUrl\n } else {\n baseUrl = DEFAULT_MATTER_CONFIG.registryUrl\n }\n\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const url = baseUrl.replace('${ref}', ref)\n const registry = await fetchRegistry(url)\n const entries = Object.entries(registry.components).sort(([a], [b]) => a.localeCompare(b))\n\n if (entries.length === 0) {\n io.log('No components in registry.')\n return\n }\n\n for (const [slug, entry] of entries) {\n const description = entry.description ?? '(no description)'\n io.log(`${slug} · ${description} · tier ${entry.tier}`)\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,eAAsB,QACpB,MACA,KAAa,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACrC;AAKf,MAAI;AACJ,MAAI,KAAK,aAAa,UAAa,KAAK,aAAa,IAAI;AACvD,cAAU,KAAK;AAAA,EACjB,WAAW,MAAM,aAAa,GAAG,GAAG,GAAG;AACrC,UAAM,MAAM,MAAM,iBAAiB,GAAG,GAAG;AACzC,cAAU,IAAI;AAAA,EAChB,OAAO;AACL,cAAU,sBAAsB;AAAA,EAClC;AAEA,QAAM,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;AAChD,QAAM,MAAM,QAAQ,QAAQ,UAAU,GAAG;AACzC,QAAM,WAAW,MAAM,cAAc,GAAG;AACxC,QAAM,UAAU,OAAO,QAAQ,SAAS,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAEzF,MAAI,QAAQ,WAAW,GAAG;AACxB,OAAG,IAAI,4BAA4B;AACnC;AAAA,EACF;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,UAAM,cAAc,MAAM,eAAe;AACzC,OAAG,IAAI,GAAG,IAAI,SAAM,WAAW,cAAW,MAAM,IAAI,EAAE;AAAA,EACxD;AACF;","names":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runAdd
|
|
4
|
+
} from "./chunk-QVVHELUY.js";
|
|
5
|
+
import {
|
|
6
|
+
fetchRegistry,
|
|
7
|
+
resolveRef
|
|
8
|
+
} from "./chunk-QTD5MDLV.js";
|
|
9
|
+
import {
|
|
10
|
+
readMatterConfig
|
|
11
|
+
} from "./chunk-PWYRLP7T.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/update.ts
|
|
14
|
+
import { readdir } from "fs/promises";
|
|
15
|
+
import { extname, join } from "path";
|
|
16
|
+
async function runUpdate(components, opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
17
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
18
|
+
const baseUrl = opts.registry ?? cfg.registryUrl;
|
|
19
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
20
|
+
const registryUrl = baseUrl.replace("${ref}", ref);
|
|
21
|
+
const componentsDir = join(io.cwd, cfg.componentsDir);
|
|
22
|
+
const localFiles = await safeReaddir(componentsDir);
|
|
23
|
+
const localSlugs = localFiles.filter((f) => extname(f) === ".tsx" || extname(f) === ".ts").map((f) => f.replace(/\.(tsx|ts)$/, ""));
|
|
24
|
+
const registry = await fetchRegistry(registryUrl);
|
|
25
|
+
let toUpdate;
|
|
26
|
+
if (components.length === 0) {
|
|
27
|
+
if (localSlugs.length === 0) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`No components found in ${componentsDir}. Run \`matter-cli add <name>\` first.`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
toUpdate = localSlugs.filter((slug) => slugIsInRegistry(slug, registry));
|
|
33
|
+
if (toUpdate.length === 0) {
|
|
34
|
+
throw new Error(`No components in ${componentsDir} match any registry entry.`);
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
for (const slug of components) {
|
|
38
|
+
const file = registry.components[slug]?.file;
|
|
39
|
+
const present = file !== void 0 && localSlugs.includes(slug);
|
|
40
|
+
if (!present) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Component "${slug}" is not present in ${componentsDir}. Use \`matter-cli add ${slug}\` instead.`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
toUpdate = components;
|
|
47
|
+
}
|
|
48
|
+
io.log(`Updating ${toUpdate.length} component(s) from ${registryUrl}\u2026`);
|
|
49
|
+
await runAdd(
|
|
50
|
+
toUpdate,
|
|
51
|
+
{
|
|
52
|
+
registry: registryUrl,
|
|
53
|
+
ref: void 0,
|
|
54
|
+
force: opts.force,
|
|
55
|
+
cliVersion: opts.cliVersion
|
|
56
|
+
},
|
|
57
|
+
io
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
async function safeReaddir(path) {
|
|
61
|
+
try {
|
|
62
|
+
return await readdir(path);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (err.code === "ENOENT") return [];
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function slugIsInRegistry(slug, registry) {
|
|
69
|
+
const entry = registry.components[slug];
|
|
70
|
+
return entry !== void 0 && entry.file.replace(/\.(tsx|ts)$/, "") === slug;
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
runUpdate
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=update-JRITSIKU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/update.ts"],"sourcesContent":["import { readdir } from 'node:fs/promises'\nimport { extname, join } from 'node:path'\nimport { readMatterConfig } from '../config/matterConfig.js'\nimport { fetchRegistry, type Registry } from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\nimport { runAdd } from './add.js'\n\nexport interface UpdateOptions {\n registry?: string\n ref?: string\n force?: boolean\n cliVersion: string\n}\n\nexport interface UpdateIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runUpdate(\n components: string[],\n opts: UpdateOptions,\n io: UpdateIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n const cfg = await readMatterConfig(io.cwd)\n const baseUrl = opts.registry ?? cfg.registryUrl\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const registryUrl = baseUrl.replace('${ref}', ref)\n\n const componentsDir = join(io.cwd, cfg.componentsDir)\n const localFiles = await safeReaddir(componentsDir)\n const localSlugs = localFiles\n .filter((f) => extname(f) === '.tsx' || extname(f) === '.ts')\n .map((f) => f.replace(/\\.(tsx|ts)$/, ''))\n\n const registry = await fetchRegistry(registryUrl)\n\n let toUpdate: string[]\n if (components.length === 0) {\n if (localSlugs.length === 0) {\n throw new Error(\n `No components found in ${componentsDir}. Run \\`matter-cli add <name>\\` first.`,\n )\n }\n toUpdate = localSlugs.filter((slug) => slugIsInRegistry(slug, registry))\n if (toUpdate.length === 0) {\n throw new Error(`No components in ${componentsDir} match any registry entry.`)\n }\n } else {\n for (const slug of components) {\n const file = registry.components[slug]?.file\n const present = file !== undefined && localSlugs.includes(slug)\n if (!present) {\n throw new Error(\n `Component \"${slug}\" is not present in ${componentsDir}. Use \\`matter-cli add ${slug}\\` instead.`,\n )\n }\n }\n toUpdate = components\n }\n\n io.log(`Updating ${toUpdate.length} component(s) from ${registryUrl}…`)\n // registryUrl already has ${ref} substituted above; pass ref: undefined so\n // runAdd doesn't try to resolve again over an already-substituted URL.\n await runAdd(\n toUpdate,\n {\n registry: registryUrl,\n ref: undefined,\n force: opts.force,\n cliVersion: opts.cliVersion,\n },\n io,\n )\n}\n\nasync function safeReaddir(path: string): Promise<string[]> {\n try {\n return await readdir(path)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n}\n\n// Convention in v1: slug equals the basename of entry.file. update keys off\n// the local filename, so a registry whose slug and filename diverge would\n// silently get skipped here. The single check guards both invariants.\nfunction slugIsInRegistry(slug: string, registry: Registry): boolean {\n const entry = registry.components[slug]\n return entry !== undefined && entry.file.replace(/\\.(tsx|ts)$/, '') === slug\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;AAkB9B,eAAsB,UACpB,YACA,MACA,KAAe,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACvC;AACf,QAAM,MAAM,MAAM,iBAAiB,GAAG,GAAG;AACzC,QAAM,UAAU,KAAK,YAAY,IAAI;AACrC,QAAM,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;AAChD,QAAM,cAAc,QAAQ,QAAQ,UAAU,GAAG;AAEjD,QAAM,gBAAgB,KAAK,GAAG,KAAK,IAAI,aAAa;AACpD,QAAM,aAAa,MAAM,YAAY,aAAa;AAClD,QAAM,aAAa,WAChB,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,UAAU,QAAQ,CAAC,MAAM,KAAK,EAC3D,IAAI,CAAC,MAAM,EAAE,QAAQ,eAAe,EAAE,CAAC;AAE1C,QAAM,WAAW,MAAM,cAAc,WAAW;AAEhD,MAAI;AACJ,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,WAAW,WAAW,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,0BAA0B,aAAa;AAAA,MACzC;AAAA,IACF;AACA,eAAW,WAAW,OAAO,CAAC,SAAS,iBAAiB,MAAM,QAAQ,CAAC;AACvE,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,MAAM,oBAAoB,aAAa,4BAA4B;AAAA,IAC/E;AAAA,EACF,OAAO;AACL,eAAW,QAAQ,YAAY;AAC7B,YAAM,OAAO,SAAS,WAAW,IAAI,GAAG;AACxC,YAAM,UAAU,SAAS,UAAa,WAAW,SAAS,IAAI;AAC9D,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR,cAAc,IAAI,uBAAuB,aAAa,0BAA0B,IAAI;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,EACb;AAEA,KAAG,IAAI,YAAY,SAAS,MAAM,sBAAsB,WAAW,QAAG;AAGtE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,KAAK;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,YAAY,MAAiC;AAC1D,MAAI;AACF,WAAO,MAAM,QAAQ,IAAI;AAAA,EAC3B,SAAS,KAAK;AACZ,QAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,UAAM;AAAA,EACR;AACF;AAKA,SAAS,iBAAiB,MAAc,UAA6B;AACnE,QAAM,QAAQ,SAAS,WAAW,IAAI;AACtC,SAAO,UAAU,UAAa,MAAM,KAAK,QAAQ,eAAe,EAAE,MAAM;AAC1E;","names":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runAdd
|
|
4
|
+
} from "./chunk-V774PVEJ.js";
|
|
5
|
+
import {
|
|
6
|
+
fetchRegistry,
|
|
7
|
+
resolveRef
|
|
8
|
+
} from "./chunk-QTD5MDLV.js";
|
|
9
|
+
import {
|
|
10
|
+
readMatterConfig
|
|
11
|
+
} from "./chunk-EBCJ5BNB.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/update.ts
|
|
14
|
+
import { readdir } from "fs/promises";
|
|
15
|
+
import { extname, join } from "path";
|
|
16
|
+
async function runUpdate(components, opts, io = { cwd: process.cwd(), log: console.log }) {
|
|
17
|
+
const cfg = await readMatterConfig(io.cwd);
|
|
18
|
+
const baseUrl = opts.registry ?? cfg.registryUrl;
|
|
19
|
+
const ref = resolveRef(opts.ref, opts.cliVersion);
|
|
20
|
+
const registryUrl = baseUrl.replace("${ref}", ref);
|
|
21
|
+
const componentsDir = join(io.cwd, cfg.componentsDir);
|
|
22
|
+
const localFiles = await safeReaddir(componentsDir);
|
|
23
|
+
const localSlugs = localFiles.filter((f) => extname(f) === ".tsx" || extname(f) === ".ts").map((f) => f.replace(/\.(tsx|ts)$/, ""));
|
|
24
|
+
const registry = await fetchRegistry(registryUrl);
|
|
25
|
+
let toUpdate;
|
|
26
|
+
if (components.length === 0) {
|
|
27
|
+
if (localSlugs.length === 0) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`No components found in ${componentsDir}. Run \`matter-cli add <name>\` first.`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
toUpdate = localSlugs.filter((slug) => slugIsInRegistry(slug, registry));
|
|
33
|
+
if (toUpdate.length === 0) {
|
|
34
|
+
throw new Error(`No components in ${componentsDir} match any registry entry.`);
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
for (const slug of components) {
|
|
38
|
+
const file = registry.components[slug]?.file;
|
|
39
|
+
const present = file !== void 0 && localSlugs.includes(slug);
|
|
40
|
+
if (!present) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Component "${slug}" is not present in ${componentsDir}. Use \`matter-cli add ${slug}\` instead.`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
toUpdate = components;
|
|
47
|
+
}
|
|
48
|
+
io.log(`Updating ${toUpdate.length} component(s) from ${registryUrl}\u2026`);
|
|
49
|
+
await runAdd(
|
|
50
|
+
toUpdate,
|
|
51
|
+
{
|
|
52
|
+
registry: registryUrl,
|
|
53
|
+
ref: void 0,
|
|
54
|
+
force: opts.force,
|
|
55
|
+
cliVersion: opts.cliVersion
|
|
56
|
+
},
|
|
57
|
+
io
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
async function safeReaddir(path) {
|
|
61
|
+
try {
|
|
62
|
+
return await readdir(path);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (err.code === "ENOENT") return [];
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function slugIsInRegistry(slug, registry) {
|
|
69
|
+
const entry = registry.components[slug];
|
|
70
|
+
return entry !== void 0 && entry.file.replace(/\.(tsx|ts)$/, "") === slug;
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
runUpdate
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=update-TAPYOHLT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/update.ts"],"sourcesContent":["import { readdir } from 'node:fs/promises'\nimport { extname, join } from 'node:path'\nimport { readMatterConfig } from '../config/matterConfig.js'\nimport { fetchRegistry, type Registry } from '../registry/fetchRegistry.js'\nimport { resolveRef } from '../registry/ref.js'\nimport { runAdd } from './add.js'\n\nexport interface UpdateOptions {\n registry?: string\n ref?: string\n force?: boolean\n cliVersion: string\n}\n\nexport interface UpdateIO {\n cwd: string\n log: (line: string) => void\n}\n\nexport async function runUpdate(\n components: string[],\n opts: UpdateOptions,\n io: UpdateIO = { cwd: process.cwd(), log: console.log },\n): Promise<void> {\n const cfg = await readMatterConfig(io.cwd)\n const baseUrl = opts.registry ?? cfg.registryUrl\n const ref = resolveRef(opts.ref, opts.cliVersion)\n const registryUrl = baseUrl.replace('${ref}', ref)\n\n const componentsDir = join(io.cwd, cfg.componentsDir)\n const localFiles = await safeReaddir(componentsDir)\n const localSlugs = localFiles\n .filter((f) => extname(f) === '.tsx' || extname(f) === '.ts')\n .map((f) => f.replace(/\\.(tsx|ts)$/, ''))\n\n const registry = await fetchRegistry(registryUrl)\n\n let toUpdate: string[]\n if (components.length === 0) {\n if (localSlugs.length === 0) {\n throw new Error(\n `No components found in ${componentsDir}. Run \\`matter-cli add <name>\\` first.`,\n )\n }\n toUpdate = localSlugs.filter((slug) => slugIsInRegistry(slug, registry))\n if (toUpdate.length === 0) {\n throw new Error(`No components in ${componentsDir} match any registry entry.`)\n }\n } else {\n for (const slug of components) {\n const file = registry.components[slug]?.file\n const present = file !== undefined && localSlugs.includes(slug)\n if (!present) {\n throw new Error(\n `Component \"${slug}\" is not present in ${componentsDir}. Use \\`matter-cli add ${slug}\\` instead.`,\n )\n }\n }\n toUpdate = components\n }\n\n io.log(`Updating ${toUpdate.length} component(s) from ${registryUrl}…`)\n // registryUrl already has ${ref} substituted above; pass ref: undefined so\n // runAdd doesn't try to resolve again over an already-substituted URL.\n await runAdd(\n toUpdate,\n {\n registry: registryUrl,\n ref: undefined,\n force: opts.force,\n cliVersion: opts.cliVersion,\n },\n io,\n )\n}\n\nasync function safeReaddir(path: string): Promise<string[]> {\n try {\n return await readdir(path)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n}\n\n// Convention in v1: slug equals the basename of entry.file. update keys off\n// the local filename, so a registry whose slug and filename diverge would\n// silently get skipped here. The single check guards both invariants.\nfunction slugIsInRegistry(slug: string, registry: Registry): boolean {\n const entry = registry.components[slug]\n return entry !== undefined && entry.file.replace(/\\.(tsx|ts)$/, '') === slug\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;AAkB9B,eAAsB,UACpB,YACA,MACA,KAAe,EAAE,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GACvC;AACf,QAAM,MAAM,MAAM,iBAAiB,GAAG,GAAG;AACzC,QAAM,UAAU,KAAK,YAAY,IAAI;AACrC,QAAM,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;AAChD,QAAM,cAAc,QAAQ,QAAQ,UAAU,GAAG;AAEjD,QAAM,gBAAgB,KAAK,GAAG,KAAK,IAAI,aAAa;AACpD,QAAM,aAAa,MAAM,YAAY,aAAa;AAClD,QAAM,aAAa,WAChB,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,UAAU,QAAQ,CAAC,MAAM,KAAK,EAC3D,IAAI,CAAC,MAAM,EAAE,QAAQ,eAAe,EAAE,CAAC;AAE1C,QAAM,WAAW,MAAM,cAAc,WAAW;AAEhD,MAAI;AACJ,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,WAAW,WAAW,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,0BAA0B,aAAa;AAAA,MACzC;AAAA,IACF;AACA,eAAW,WAAW,OAAO,CAAC,SAAS,iBAAiB,MAAM,QAAQ,CAAC;AACvE,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,MAAM,oBAAoB,aAAa,4BAA4B;AAAA,IAC/E;AAAA,EACF,OAAO;AACL,eAAW,QAAQ,YAAY;AAC7B,YAAM,OAAO,SAAS,WAAW,IAAI,GAAG;AACxC,YAAM,UAAU,SAAS,UAAa,WAAW,SAAS,IAAI;AAC9D,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR,cAAc,IAAI,uBAAuB,aAAa,0BAA0B,IAAI;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,EACb;AAEA,KAAG,IAAI,YAAY,SAAS,MAAM,sBAAsB,WAAW,QAAG;AAGtE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,KAAK;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,YAAY,MAAiC;AAC1D,MAAI;AACF,WAAO,MAAM,QAAQ,IAAI;AAAA,EAC3B,SAAS,KAAK;AACZ,QAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,UAAM;AAAA,EACR;AACF;AAKA,SAAS,iBAAiB,MAAc,UAA6B;AACnE,QAAM,QAAQ,SAAS,WAAW,IAAI;AACtC,SAAO,UAAU,UAAa,MAAM,KAAK,QAAQ,eAAe,EAAE,MAAM;AAC1E;","names":[]}
|