@baby-ui/cli 0.0.0-stage → 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.
Files changed (44) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +36 -2
  3. package/bin.mjs +20 -0
  4. package/dist/add-Dw_xdBjM.js +8472 -0
  5. package/dist/add-Dw_xdBjM.js.map +1 -0
  6. package/dist/auth-Cqd8NPiR.js +52 -0
  7. package/dist/auth-Cqd8NPiR.js.map +1 -0
  8. package/dist/auth-DLL_PGWB.js +41 -0
  9. package/dist/auth-DLL_PGWB.js.map +1 -0
  10. package/dist/banner-b_aKYU5F.js +23 -0
  11. package/dist/banner-b_aKYU5F.js.map +1 -0
  12. package/dist/core-Cd391zXy.js +142 -0
  13. package/dist/core-Cd391zXy.js.map +1 -0
  14. package/dist/dist-Bs-3vZ2T.js +2712 -0
  15. package/dist/dist-Bs-3vZ2T.js.map +1 -0
  16. package/dist/dist-CxDndWiZ.js +6661 -0
  17. package/dist/dist-CxDndWiZ.js.map +1 -0
  18. package/dist/errors-zXXytRXF.js +16 -0
  19. package/dist/errors-zXXytRXF.js.map +1 -0
  20. package/dist/history-l3B-mc6n.js +55 -0
  21. package/dist/history-l3B-mc6n.js.map +1 -0
  22. package/dist/index.js +3097 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/info-mS7KbPJ_.js +43 -0
  25. package/dist/info-mS7KbPJ_.js.map +1 -0
  26. package/dist/init-DO1txT-A.js +168 -0
  27. package/dist/init-DO1txT-A.js.map +1 -0
  28. package/dist/list-DnQNQUNr.js +48 -0
  29. package/dist/list-DnQNQUNr.js.map +1 -0
  30. package/dist/maintain-DeyqYm5K.js +183 -0
  31. package/dist/maintain-DeyqYm5K.js.map +1 -0
  32. package/dist/schemas-DwMX1h2B.js +5160 -0
  33. package/dist/schemas-DwMX1h2B.js.map +1 -0
  34. package/dist/shared-BJaaV-dl.js +96 -0
  35. package/dist/shared-BJaaV-dl.js.map +1 -0
  36. package/dist/state-CsT6LJsH.js +430 -0
  37. package/dist/state-CsT6LJsH.js.map +1 -0
  38. package/dist/targets-Bpv2h7C4.js +316 -0
  39. package/dist/targets-Bpv2h7C4.js.map +1 -0
  40. package/dist/tx-DBnjY8eR.js +226 -0
  41. package/dist/tx-DBnjY8eR.js.map +1 -0
  42. package/dist/ui-Cthxlfe6.js +206 -0
  43. package/dist/ui-Cthxlfe6.js.map +1 -0
  44. package/package.json +50 -3
@@ -0,0 +1,96 @@
1
+ import { c as toPosix, i as targetAt, n as findWorkspace, r as matchTarget, t as discoverTargets } from "./targets-Bpv2h7C4.js";
2
+ import { t as CliError } from "./errors-zXXytRXF.js";
3
+ import { r as isInteractive } from "./core-Cd391zXy.js";
4
+ import { a as object, i as literal, n as array, o as record, s as string, t as _enum } from "./schemas-DwMX1h2B.js";
5
+ import { i as multiselect } from "./ui-Cthxlfe6.js";
6
+ import { join, relative } from "node:path";
7
+ import { createHash } from "node:crypto";
8
+ import { readFile } from "node:fs/promises";
9
+ //#region src/write/lock.ts
10
+ const STATE_DIR = ".baby-ui";
11
+ const sha256 = (content) => createHash("sha256").update(content).digest("hex");
12
+ const LockItemSchema = object({
13
+ name: string(),
14
+ type: string(),
15
+ framework: _enum(["react", "svelte"]),
16
+ installedAt: string(),
17
+ /** Item JSON hash, so `update` can tell an upstream change from a local one. */
18
+ itemHash: string(),
19
+ /** Root-relative posix path to the sha256 of exactly what we wrote. */
20
+ files: record(string(), string()),
21
+ dependencies: array(string()),
22
+ registryDependencies: array(string())
23
+ });
24
+ /** Items keyed by the URL they were installed from. */
25
+ const LockFileSchema = object({
26
+ version: literal(1),
27
+ items: record(string(), LockItemSchema)
28
+ });
29
+ const lockPath = (root) => join(root, STATE_DIR, "lock.json");
30
+ async function readLock(root) {
31
+ try {
32
+ const parsed = LockFileSchema.safeParse(JSON.parse(await readFile(lockPath(root), "utf8")));
33
+ if (parsed.success) return parsed.data;
34
+ } catch {}
35
+ return {
36
+ version: 1,
37
+ items: {}
38
+ };
39
+ }
40
+ const sortKeys = (record) => Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
41
+ /** Stable output, so the committed lock diffs cleanly. */
42
+ function serializeLock(lock) {
43
+ const items = Object.fromEntries(Object.entries(sortKeys(lock.items)).map(([url, item]) => [url, {
44
+ ...item,
45
+ files: sortKeys(item.files)
46
+ }]));
47
+ return `${JSON.stringify({
48
+ version: 1,
49
+ items
50
+ }, null, " ")}\n`;
51
+ }
52
+ const relativeTo = (root, file) => toPosix(relative(root, file));
53
+ //#endregion
54
+ //#region src/project/select.ts
55
+ const describe = (t) => `${t.path} (${t.name ?? "unnamed"}, ${t.framework})`;
56
+ /** `--target` wins, then `--all`, then the package around `cwd`, then a prompt. */
57
+ async function selectTargets(targets, cwd, flags) {
58
+ const listing = targets.map((t) => ` ${describe(t)}`).join("\n");
59
+ if (!targets.length) throw new CliError("No React or Svelte project found.", { hint: "Run this inside an app, or add react/svelte to its package.json first." });
60
+ if (flags.target?.length) return flags.target.map((query) => {
61
+ const found = matchTarget(targets, query);
62
+ if (!found) throw new CliError(`No target matches "${query}".`, { hint: listing });
63
+ return found;
64
+ });
65
+ if (flags.all) return [...targets];
66
+ const here = targetAt(targets, cwd);
67
+ if (here) return [here];
68
+ const [only] = targets;
69
+ if (only && targets.length === 1) return [only];
70
+ if (!isInteractive()) throw new CliError("Several targets found; pass --target <name|path> or --all.", { hint: listing });
71
+ return multiselect({
72
+ message: "Which projects?",
73
+ options: targets.map((t) => ({
74
+ value: t,
75
+ label: t.path,
76
+ hint: describe(t)
77
+ })),
78
+ required: true
79
+ });
80
+ }
81
+ //#endregion
82
+ //#region src/commands/shared.ts
83
+ /** Targets that have a components.json; standing in one without it points at `init`. */
84
+ async function configuredTargets(options) {
85
+ const workspace = await findWorkspace(options.cwd);
86
+ const all = await discoverTargets(workspace);
87
+ const here = targetAt(all, options.cwd);
88
+ if (here && !here.config && !options.target?.length && !options.all) throw new CliError(`${here.path} has no components.json.`, { hint: "Run `baby-ui init` first." });
89
+ const configured = all.filter((t) => t.config);
90
+ if (!configured.length) throw new CliError("No project with a components.json found.", { hint: "Run `baby-ui init` in your app first." });
91
+ return selectTargets(configured, options.cwd, options);
92
+ }
93
+ //#endregion
94
+ export { readLock as a, sha256 as c, lockPath as i, selectTargets as n, relativeTo as o, STATE_DIR as r, serializeLock as s, configuredTargets as t };
95
+
96
+ //# sourceMappingURL=shared-BJaaV-dl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-BJaaV-dl.js","names":["z.object","z.string","z.enum","z.record","z.array","z.literal"],"sources":["../src/write/lock.ts","../src/project/select.ts","../src/commands/shared.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { z } from \"zod\";\nimport { toPosix } from \"../project/fs.ts\";\n\nexport const STATE_DIR = \".baby-ui\";\n\nexport const sha256 = (content: string) =>\n\tcreateHash(\"sha256\").update(content).digest(\"hex\");\n\nconst LockItemSchema = z.object({\n\tname: z.string(),\n\ttype: z.string(),\n\tframework: z.enum([\"react\", \"svelte\"]),\n\tinstalledAt: z.string(),\n\t/** Item JSON hash, so `update` can tell an upstream change from a local one. */\n\titemHash: z.string(),\n\t/** Root-relative posix path to the sha256 of exactly what we wrote. */\n\tfiles: z.record(z.string(), z.string()),\n\tdependencies: z.array(z.string()),\n\tregistryDependencies: z.array(z.string()),\n});\n\n/** Items keyed by the URL they were installed from. */\nconst LockFileSchema = z.object({\n\tversion: z.literal(1),\n\titems: z.record(z.string(), LockItemSchema),\n});\n\nexport type LockItem = z.infer<typeof LockItemSchema>;\nexport type LockFile = z.infer<typeof LockFileSchema>;\n\nexport const lockPath = (root: string) => join(root, STATE_DIR, \"lock.json\");\n\nexport async function readLock(root: string): Promise<LockFile> {\n\ttry {\n\t\tconst parsed = LockFileSchema.safeParse(\n\t\t\tJSON.parse(await readFile(lockPath(root), \"utf8\")),\n\t\t);\n\t\tif (parsed.success) return parsed.data;\n\t} catch {}\n\treturn { version: 1, items: {} };\n}\n\nconst sortKeys = <T>(record: Readonly<Record<string, T>>) =>\n\tObject.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));\n\n/** Stable output, so the committed lock diffs cleanly. */\nexport function serializeLock(lock: LockFile): string {\n\tconst items = Object.fromEntries(\n\t\tObject.entries(sortKeys(lock.items)).map(([url, item]) => [\n\t\t\turl,\n\t\t\t{ ...item, files: sortKeys(item.files) },\n\t\t]),\n\t);\n\treturn `${JSON.stringify({ version: 1, items }, null, \"\\t\")}\\n`;\n}\n\nexport const relativeTo = (root: string, file: string) => toPosix(relative(root, file));\n\n/** The lock entry that owns `path`, if any. */\nexport function ownerOf(lock: LockFile, path: string): [string, LockItem] | undefined {\n\treturn Object.entries(lock.items).find(([, item]) => path in item.files);\n}\n","import { CliError } from \"../errors.ts\";\nimport { isInteractive, multiselect } from \"../ui/index.ts\";\nimport { matchTarget, type Target, targetAt } from \"./targets.ts\";\n\nexport interface TargetFlags {\n\treadonly target?: readonly string[];\n\treadonly all?: boolean;\n}\n\nconst describe = (t: Target) => `${t.path} (${t.name ?? \"unnamed\"}, ${t.framework})`;\n\n/** `--target` wins, then `--all`, then the package around `cwd`, then a prompt. */\nexport async function selectTargets(\n\ttargets: readonly Target[],\n\tcwd: string,\n\tflags: TargetFlags,\n): Promise<Target[]> {\n\tconst listing = targets.map((t) => ` ${describe(t)}`).join(\"\\n\");\n\tif (!targets.length) {\n\t\tthrow new CliError(\"No React or Svelte project found.\", {\n\t\t\thint: \"Run this inside an app, or add react/svelte to its package.json first.\",\n\t\t});\n\t}\n\tif (flags.target?.length) {\n\t\treturn flags.target.map((query) => {\n\t\t\tconst found = matchTarget(targets, query);\n\t\t\tif (!found) throw new CliError(`No target matches \"${query}\".`, { hint: listing });\n\t\t\treturn found;\n\t\t});\n\t}\n\tif (flags.all) return [...targets];\n\tconst here = targetAt(targets, cwd);\n\tif (here) return [here];\n\tconst [only] = targets;\n\tif (only && targets.length === 1) return [only];\n\tif (!isInteractive()) {\n\t\tthrow new CliError(\"Several targets found; pass --target <name|path> or --all.\", {\n\t\t\thint: listing,\n\t\t});\n\t}\n\treturn multiselect({\n\t\tmessage: \"Which projects?\",\n\t\toptions: targets.map((t) => ({ value: t, label: t.path, hint: describe(t) })),\n\t\trequired: true,\n\t});\n}\n","import { CliError } from \"../errors.ts\";\nimport { selectTargets, type TargetFlags } from \"../project/select.ts\";\nimport {\n\tdiscoverTargets,\n\tfindWorkspace,\n\ttype Target,\n\ttargetAt,\n} from \"../project/targets.ts\";\n\nexport interface CommonOptions extends TargetFlags {\n\treadonly cwd: string;\n}\n\n/** Targets that have a components.json; standing in one without it points at `init`. */\nexport async function configuredTargets(options: CommonOptions): Promise<Target[]> {\n\tconst workspace = await findWorkspace(options.cwd);\n\tconst all = await discoverTargets(workspace);\n\tconst here = targetAt(all, options.cwd);\n\tif (here && !here.config && !options.target?.length && !options.all) {\n\t\tthrow new CliError(`${here.path} has no components.json.`, {\n\t\t\thint: \"Run `baby-ui init` first.\",\n\t\t});\n\t}\n\tconst configured = all.filter((t) => t.config);\n\tif (!configured.length) {\n\t\tthrow new CliError(\"No project with a components.json found.\", {\n\t\t\thint: \"Run `baby-ui init` in your app first.\",\n\t\t});\n\t}\n\treturn selectTargets(configured, options.cwd, options);\n}\n"],"mappings":"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"}
@@ -0,0 +1,430 @@
1
+ import { s as isRecord } from "./targets-Bpv2h7C4.js";
2
+ import { t as CliError } from "./errors-zXXytRXF.js";
3
+ import { d as log } from "./core-Cd391zXy.js";
4
+ import { a as object, c as unknown, n as array, o as record$1, s as string } from "./schemas-DwMX1h2B.js";
5
+ import { n as credential } from "./auth-Cqd8NPiR.js";
6
+ import { a as readLock, c as sha256 } from "./shared-BJaaV-dl.js";
7
+ import { existsSync, readFileSync } from "node:fs";
8
+ import { spawn } from "node:child_process";
9
+ import { extname, join, resolve } from "node:path";
10
+ import { createHash } from "node:crypto";
11
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
12
+ import { homedir } from "node:os";
13
+ import { fileURLToPath, pathToFileURL } from "node:url";
14
+ import { parseSync } from "oxc-parser";
15
+ //#region src/project/paths.ts
16
+ const ALIAS_KEYS = [
17
+ "components",
18
+ "ui",
19
+ "lib",
20
+ "hooks",
21
+ "utils"
22
+ ];
23
+ /** Resolves an import alias (`@/components`, `$lib/hooks`, `#lib/ui`) to a directory. */
24
+ function resolveAlias(alias, project) {
25
+ const sorted = [...project.aliases].sort((a, b) => b.prefix.length - a.prefix.length);
26
+ for (const { prefix, dir } of sorted) {
27
+ if (alias === prefix.slice(0, -1)) return dir;
28
+ if (alias.startsWith(prefix)) return join(dir, alias.slice(prefix.length));
29
+ }
30
+ if (project.dollarLib && (alias === "$lib" || alias.startsWith("$lib/"))) return join(project.root, "src", "lib", alias.slice(4));
31
+ }
32
+ function svelteAliases(raw) {
33
+ const lib = raw.lib ?? "$lib";
34
+ return {
35
+ components: raw.components ?? `${lib}/components`,
36
+ ui: raw.ui ?? `${raw.components ?? `${lib}/components`}/ui`,
37
+ lib,
38
+ hooks: raw.hooks ?? `${lib}/hooks`,
39
+ utils: raw.utils ?? `${lib}/utils`
40
+ };
41
+ }
42
+ function reactAliases(raw) {
43
+ const components = raw.components ?? "@/components";
44
+ const utils = raw.utils ?? "@/lib/utils";
45
+ return {
46
+ components,
47
+ ui: raw.ui ?? `${components}/ui`,
48
+ lib: raw.lib ?? utils.replace(/\/[^/]+$/, ""),
49
+ hooks: raw.hooks ?? `${components.replace(/\/[^/]+$/, "")}/hooks`,
50
+ utils
51
+ };
52
+ }
53
+ /** The resolved install config for a project that has a components.json. */
54
+ function installConfig(project) {
55
+ const config = project.config;
56
+ const framework = project.framework;
57
+ if (!config || !framework) throw new CliError(`${project.root} has no components.json.`, { hint: "Run `baby-ui init` there first." });
58
+ const aliases = framework === "svelte" ? svelteAliases(config.aliases) : reactAliases(config.aliases);
59
+ const missing = [];
60
+ const need = (key) => {
61
+ const dir = resolveAlias(aliases[key], project);
62
+ if (!dir) missing.push(`${key} (${aliases[key]})`);
63
+ return dir ?? "";
64
+ };
65
+ const paths = {
66
+ components: need("components"),
67
+ ui: need("ui"),
68
+ lib: need("lib"),
69
+ hooks: need("hooks"),
70
+ utils: need("utils")
71
+ };
72
+ if (missing.length) throw new CliError(`Could not resolve aliases in ${project.root}: ${missing.join(", ")}.`, { hint: "Map them in tsconfig.json `paths` or package.json `imports`." });
73
+ const raw = config.raw;
74
+ return {
75
+ project,
76
+ framework,
77
+ typescript: framework === "svelte" ? raw.typescript !== false : raw.tsx !== false,
78
+ rsc: raw.rsc === true,
79
+ srcDir: existsSync(join(project.root, "src")),
80
+ aliases,
81
+ declaredAliases: Object.fromEntries(ALIAS_KEYS.flatMap((key) => {
82
+ const value = config.aliases[key];
83
+ return value ? [[key, value]] : [];
84
+ })),
85
+ paths: {
86
+ ...paths,
87
+ css: config.css ? resolve(project.root, config.css) : void 0
88
+ }
89
+ };
90
+ }
91
+ //#endregion
92
+ //#region src/registry/resolve.ts
93
+ const BABY_UI_ORIGIN = "https://baby-ui.pages.dev";
94
+ /** `BABY_UI_REGISTRY_URL` swaps our origin everywhere, including inside items' dependency URLs. */
95
+ const registryOrigin = () => (process.env.BABY_UI_REGISTRY_URL ?? "https://baby-ui.pages.dev").replace(/\/$/, "");
96
+ function babyUiUrl(name, ctx) {
97
+ const route = ctx.framework === "react" ? "r" : "svelte/r";
98
+ return `${registryOrigin()}/${route}${ctx.typescript ? "" : "/js"}/${name}.json`;
99
+ }
100
+ /** shadcn and shadcn-svelte resolve a bare dependency name against their own registry. */
101
+ function upstreamUrl(name, ctx) {
102
+ const style = typeof ctx.config.style === "string" ? ctx.config.style : void 0;
103
+ if (ctx.framework === "react") return `https://ui.shadcn.com/r/styles/${style ?? "new-york-v4"}/${name}.json`;
104
+ return `${(typeof ctx.config.registry === "string" ? ctx.config.registry : "https://shadcn-svelte.com/registry").replace(/\/$/, "")}/styles/${style ?? "vega"}/${name}.json`;
105
+ }
106
+ function expandEnv(value) {
107
+ return value.replace(/\$\{(\w+)\}/g, (_, name) => {
108
+ const found = process.env[name];
109
+ if (found === void 0) throw new CliError(`Environment variable ${name} is not set.`, { hint: "A registry in components.json references it in its url or headers." });
110
+ return found;
111
+ });
112
+ }
113
+ /** Pro items sit under `/pro/` on our registry and need a licence token. */
114
+ function proUrl(name, ctx) {
115
+ const route = ctx.framework === "react" ? "r" : "svelte/r";
116
+ return `${registryOrigin()}/pro/${route}${ctx.typescript ? "" : "/js"}/${name}.json`;
117
+ }
118
+ function namespaced(ns, name, ctx) {
119
+ if (ns === "@baby-ui") return {
120
+ url: babyUiUrl(name, ctx),
121
+ headers: {}
122
+ };
123
+ if (ns === "@baby-ui-pro") return {
124
+ url: proUrl(name, ctx),
125
+ headers: {}
126
+ };
127
+ const entry = (isRecord(ctx.config.registries) ? ctx.config.registries : {})[ns];
128
+ if (entry === void 0) {
129
+ if (ns === "@shadcn") return {
130
+ url: upstreamUrl(name, ctx),
131
+ headers: {}
132
+ };
133
+ throw new CliError(`Unknown registry ${ns}.`, { hint: `Add it under "registries" in components.json, e.g. "${ns}": "https://example.com/r/{name}.json".` });
134
+ }
135
+ const spec = typeof entry === "string" ? { url: entry } : isRecord(entry) ? entry : {};
136
+ if (typeof spec.url !== "string") throw new CliError(`Registry ${ns} has no url.`);
137
+ const style = typeof ctx.config.style === "string" ? ctx.config.style : "";
138
+ const url = new URL(expandEnv(spec.url).replace("{name}", name).replace("{style}", style));
139
+ for (const [key, value] of Object.entries(isRecord(spec.params) ? spec.params : {})) if (typeof value === "string") url.searchParams.set(key, expandEnv(value));
140
+ const headers = {};
141
+ for (const [key, value] of Object.entries(isRecord(spec.headers) ? spec.headers : {})) if (typeof value === "string") headers[key] = expandEnv(value);
142
+ return {
143
+ url: url.toString(),
144
+ headers
145
+ };
146
+ }
147
+ /** A request for a URL from the lock, with headers from the components.json registry it came from. */
148
+ function requestFor(url, ctx) {
149
+ if (url.startsWith("file:")) return {
150
+ url,
151
+ headers: {}
152
+ };
153
+ const registries = isRecord(ctx.config.registries) ? ctx.config.registries : {};
154
+ for (const [ns, entry] of Object.entries(registries)) {
155
+ const spec = typeof entry === "string" ? { url: entry } : isRecord(entry) ? entry : {};
156
+ if (typeof spec.url !== "string") continue;
157
+ const origin = new URL(spec.url.replace(/\{\w+\}/g, "x").replace(/\$\{\w+\}/g, "x")).origin;
158
+ if (new URL(url).origin === origin) return {
159
+ url,
160
+ headers: namespaced(ns, "x", ctx).headers
161
+ };
162
+ }
163
+ return {
164
+ url: withOrigin(url),
165
+ headers: {}
166
+ };
167
+ }
168
+ const withOrigin = (url) => url.startsWith("https://baby-ui.pages.dev") ? registryOrigin() + url.slice(25) : url;
169
+ /** The public URL for the lock, so a local `BABY_UI_REGISTRY_URL` never gets committed. */
170
+ function canonicalUrl(url) {
171
+ const origin = registryOrigin();
172
+ return origin !== "https://baby-ui.pages.dev" && url.startsWith(origin) ? BABY_UI_ORIGIN + url.slice(origin.length) : url;
173
+ }
174
+ /**
175
+ * Turns a user or dependency specifier into a request. Bare names mean Baby UI at the top
176
+ * level and the parent's upstream registry inside a third-party item.
177
+ */
178
+ function resolveSpecifier(spec, ctx, parent) {
179
+ if (/^https?:\/\//.test(spec)) return {
180
+ url: withOrigin(spec),
181
+ headers: {}
182
+ };
183
+ if (spec.startsWith("file:")) return {
184
+ url: spec,
185
+ headers: {}
186
+ };
187
+ const ns = /^(@[\w-]+)\/(.+)$/.exec(spec);
188
+ if (ns?.[1] && ns[2]) return namespaced(ns[1], ns[2], ctx);
189
+ if (parent && (spec.startsWith("./") || spec.startsWith("../"))) return {
190
+ url: new URL(spec, parent).toString(),
191
+ headers: {}
192
+ };
193
+ if (spec.endsWith(".json") && existsSync(resolve(ctx.cwd, spec))) return {
194
+ url: pathToFileURL(resolve(ctx.cwd, spec)).toString(),
195
+ headers: {}
196
+ };
197
+ return {
198
+ url: !parent || parent.startsWith(registryOrigin()) || parent.startsWith("file:") ? babyUiUrl(spec, ctx) : upstreamUrl(spec, ctx),
199
+ headers: {}
200
+ };
201
+ }
202
+ //#endregion
203
+ //#region src/registry/fetch.ts
204
+ function cacheDir() {
205
+ if (process.env.BABY_UI_CACHE_DIR) return process.env.BABY_UI_CACHE_DIR;
206
+ if (process.platform === "win32") return join(process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local"), "baby-ui", "cache");
207
+ if (process.platform === "darwin") return join(homedir(), "Library", "Caches", "baby-ui");
208
+ return join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "baby-ui");
209
+ }
210
+ const entryPath = (url) => join(cacheDir(), `${createHash("sha256").update(url).digest("hex").slice(0, 32)}.json`);
211
+ async function readCache(url) {
212
+ try {
213
+ const entry = JSON.parse(await readFile(entryPath(url), "utf8"));
214
+ if (typeof entry === "object" && entry && "body" in entry && typeof entry.body === "string") return {
215
+ etag: "etag" in entry && typeof entry.etag === "string" ? entry.etag : null,
216
+ body: entry.body
217
+ };
218
+ } catch {}
219
+ }
220
+ async function writeCache(url, entry) {
221
+ try {
222
+ await mkdir(cacheDir(), { recursive: true });
223
+ await writeFile(entryPath(url), JSON.stringify(entry));
224
+ } catch {}
225
+ }
226
+ async function authHeaders(url, headers) {
227
+ if (Object.keys(headers).some((k) => k.toLowerCase() === "authorization") || !url.startsWith(`${registryOrigin()}/`)) return headers;
228
+ const cred = await credential();
229
+ return cred ? {
230
+ ...headers,
231
+ authorization: `Bearer ${cred.token}`
232
+ } : headers;
233
+ }
234
+ /** Fetches text with an ETag cache; offline runs fall back to the cached copy. */
235
+ async function fetchText({ url, headers }) {
236
+ if (url.startsWith("file:")) try {
237
+ return await readFile(fileURLToPath(url), "utf8");
238
+ } catch {
239
+ throw new CliError(`Not found: ${url}`);
240
+ }
241
+ const cached = await readCache(url);
242
+ let response;
243
+ try {
244
+ response = await fetch(url, { headers: {
245
+ ...await authHeaders(url, headers),
246
+ ...cached?.etag ? { "if-none-match": cached.etag } : {}
247
+ } });
248
+ } catch (error) {
249
+ if (cached) {
250
+ log.warn(`Offline, using the cached copy of ${url}`);
251
+ return cached.body;
252
+ }
253
+ throw new CliError(`Could not reach ${url}.`, { hint: String(error) });
254
+ }
255
+ if (response.status === 304 && cached) return cached.body;
256
+ if (response.status === 401 || response.status === 403) throw new CliError(`${url} needs authorisation (HTTP ${response.status}).`, { hint: "Pro items need `baby-ui login`; other registries need their headers in components.json." });
257
+ if (response.status === 404) throw new CliError(`Not found: ${url}`);
258
+ if (!response.ok) throw new CliError(`HTTP ${response.status} from ${url}`);
259
+ const body = await response.text();
260
+ await writeCache(url, {
261
+ etag: response.headers.get("etag"),
262
+ body
263
+ });
264
+ return body;
265
+ }
266
+ async function fetchJson(request) {
267
+ const text = await fetchText(request);
268
+ try {
269
+ return JSON.parse(text);
270
+ } catch {
271
+ throw new CliError(`${request.url} did not return JSON.`);
272
+ }
273
+ }
274
+ //#endregion
275
+ //#region src/registry/schema.ts
276
+ const record = record$1(string(), string());
277
+ const RegistryFileSchema = object({
278
+ path: string(),
279
+ content: string().optional(),
280
+ type: string(),
281
+ target: string().optional()
282
+ });
283
+ const RegistryItemSchema = object({
284
+ name: string(),
285
+ type: string(),
286
+ title: string().optional(),
287
+ description: string().optional(),
288
+ dependencies: array(string()).optional(),
289
+ devDependencies: array(string()).optional(),
290
+ registryDependencies: array(string()).optional(),
291
+ files: array(RegistryFileSchema).optional(),
292
+ cssVars: record$1(string(), record).optional(),
293
+ css: record$1(string(), unknown()).optional(),
294
+ meta: record$1(string(), unknown()).optional()
295
+ });
296
+ const RegistryIndexSchema = array(object({
297
+ name: string(),
298
+ type: string(),
299
+ title: string().optional(),
300
+ description: string().optional()
301
+ }));
302
+ //#endregion
303
+ //#region src/write/deps.ts
304
+ const SPEC = /^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*(@[\w.^~*+-]+)?$/i;
305
+ /** `@scope/pkg@^1` -> `@scope/pkg`. */
306
+ const packageName = (spec) => spec.replace(/(?!^)@.*$/, "");
307
+ function missingPackages(project, specs) {
308
+ const wanted = /* @__PURE__ */ new Map();
309
+ for (const spec of specs) {
310
+ if (!SPEC.test(spec)) throw new CliError(`Refusing to install "${spec}": not a package name.`);
311
+ const name = packageName(spec);
312
+ if (!project.dependencies.has(name)) wanted.set(name, spec);
313
+ }
314
+ return [...wanted.values()].sort();
315
+ }
316
+ function installArgs(pm, packages, dev) {
317
+ return [
318
+ pm === "npm" ? "install" : "add",
319
+ ...dev ? [pm === "bun" ? "--dev" : "-D"] : [],
320
+ ...packages
321
+ ];
322
+ }
323
+ function installCommand(pm, packages, dev) {
324
+ return [pm, ...installArgs(pm, packages, dev)].join(" ");
325
+ }
326
+ /** Runs the project's package manager; specs were validated by `missingPackages`. */
327
+ function install(project, packages, dev) {
328
+ if (!packages.length) return Promise.resolve();
329
+ return new Promise((resolve, reject) => {
330
+ const child = spawn(project.pm, installArgs(project.pm, packages, dev), {
331
+ cwd: project.root,
332
+ stdio: "inherit",
333
+ shell: process.platform === "win32"
334
+ });
335
+ child.on("error", reject);
336
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new CliError(`${installCommand(project.pm, packages, dev)} exited with ${code}.`, { hint: "Files were written; run the install yourself or `baby-ui undo`." })));
337
+ });
338
+ }
339
+ //#endregion
340
+ //#region src/write/state.ts
341
+ const SCRIPT = /* @__PURE__ */ new Set([
342
+ ".ts",
343
+ ".tsx",
344
+ ".js",
345
+ ".jsx",
346
+ ".mjs",
347
+ ".cjs"
348
+ ]);
349
+ const EXT = [
350
+ "",
351
+ ".ts",
352
+ ".tsx",
353
+ ".js",
354
+ ".jsx",
355
+ ".svelte",
356
+ "/index.ts",
357
+ "/index.tsx",
358
+ "/index.js"
359
+ ];
360
+ function specifiers(path, code) {
361
+ const ext = extname(path);
362
+ if (ext === ".svelte") {
363
+ const out = [];
364
+ for (const m of code.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)) {
365
+ const parsed = parseSync("script.ts", m[1] ?? "");
366
+ if (parsed.errors.length) return void 0;
367
+ out.push(...parsed.module.staticImports.map((i) => i.moduleRequest.value));
368
+ }
369
+ return out;
370
+ }
371
+ if (!SCRIPT.has(ext)) return [];
372
+ const parsed = parseSync(path, code);
373
+ if (parsed.errors.length) return void 0;
374
+ return [...parsed.module.staticImports.map((i) => i.moduleRequest.value), ...parsed.module.staticExports.flatMap((e) => e.entries.flatMap((x) => x.moduleRequest?.value ?? []))];
375
+ }
376
+ /** Alias-prefixed imports in `code` that resolve to no file. */
377
+ function unresolvedImports(path, code, project) {
378
+ const found = specifiers(path, code);
379
+ if (!found) return void 0;
380
+ const prefixes = project.aliases.map((a) => a.prefix.slice(0, -1));
381
+ if (project.dollarLib) prefixes.push("$lib");
382
+ return found.filter((spec) => {
383
+ if (!prefixes.some((p) => spec === p || spec.startsWith(`${p}/`))) return false;
384
+ const base = resolveAlias(spec, project);
385
+ if (!base) return true;
386
+ const bare = base.replace(/\.js$/, "");
387
+ return !EXT.some((e) => existsSync(base + e) || existsSync(bare + e));
388
+ });
389
+ }
390
+ function fileState(root, path, hash, project) {
391
+ const abs = join(root, path);
392
+ if (!existsSync(abs)) return {
393
+ path,
394
+ health: "missing",
395
+ unresolved: []
396
+ };
397
+ const code = readFileSync(abs, "utf8");
398
+ const unresolved = unresolvedImports(abs, code, project);
399
+ if (unresolved === void 0) return {
400
+ path,
401
+ health: "broken",
402
+ unresolved: []
403
+ };
404
+ return {
405
+ path,
406
+ health: sha256(code) === hash ? "clean" : "modified",
407
+ unresolved
408
+ };
409
+ }
410
+ /** The local state of every locked item in `cfg`'s project; no network. */
411
+ async function inspect(cfg, lock) {
412
+ const project = cfg.project;
413
+ const { items } = lock ?? await readLock(project.root);
414
+ return Object.entries(items).map(([url, item]) => ({
415
+ url,
416
+ item,
417
+ files: Object.entries(item.files).map(([path, hash]) => fileState(project.root, path, hash, project)),
418
+ missingDeps: item.dependencies.filter((d) => !project.dependencies.has(packageName(d)))
419
+ }));
420
+ }
421
+ /** Lock entries whose name or URL matches one of `names`; all of them when `names` is empty. */
422
+ function matchItems(lock, names) {
423
+ const entries = Object.entries(lock.items);
424
+ if (!names.length) return entries;
425
+ return entries.filter(([url, item]) => names.includes(item.name) || names.includes(url));
426
+ }
427
+ //#endregion
428
+ export { installConfig as _, installCommand as a, RegistryItemSchema as c, babyUiUrl as d, canonicalUrl as f, ALIAS_KEYS as g, resolveSpecifier as h, install as i, fetchJson as l, requestFor as m, matchItems as n, missingPackages as o, registryOrigin as p, unresolvedImports as r, RegistryIndexSchema as s, inspect as t, BABY_UI_ORIGIN as u, resolveAlias as v };
429
+
430
+ //# sourceMappingURL=state-CsT6LJsH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-CsT6LJsH.js","names":["z.record","z.string","z.object","z.array","z.unknown"],"sources":["../src/project/paths.ts","../src/registry/resolve.ts","../src/registry/fetch.ts","../src/registry/schema.ts","../src/write/deps.ts","../src/write/state.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { CliError } from \"../errors.ts\";\nimport type { Project } from \"./detect.ts\";\n\nexport const ALIAS_KEYS = [\"components\", \"ui\", \"lib\", \"hooks\", \"utils\"] as const;\nexport type AliasKey = (typeof ALIAS_KEYS)[number];\n\nexport interface InstallConfig {\n\treadonly project: Project;\n\treadonly framework: \"react\" | \"svelte\";\n\treadonly typescript: boolean;\n\t/** React only: keep `\"use client\"` directives. */\n\treadonly rsc: boolean;\n\treadonly srcDir: boolean;\n\t/** Alias strings as written in components.json, with each CLI's defaults filled in. */\n\treadonly aliases: Readonly<Record<AliasKey, string>>;\n\t/** Only the aliases components.json sets; shadcn's import rewrite branches on absence. */\n\treadonly declaredAliases: Readonly<Partial<Record<AliasKey, string>>>;\n\treadonly paths: Readonly<Record<AliasKey, string>> & {\n\t\treadonly css: string | undefined;\n\t};\n}\n\n/** Resolves an import alias (`@/components`, `$lib/hooks`, `#lib/ui`) to a directory. */\nexport function resolveAlias(alias: string, project: Project): string | undefined {\n\tconst sorted = [...project.aliases].sort((a, b) => b.prefix.length - a.prefix.length);\n\tfor (const { prefix, dir } of sorted) {\n\t\tif (alias === prefix.slice(0, -1)) return dir;\n\t\tif (alias.startsWith(prefix)) return join(dir, alias.slice(prefix.length));\n\t}\n\tif (project.dollarLib && (alias === \"$lib\" || alias.startsWith(\"$lib/\"))) {\n\t\treturn join(project.root, \"src\", \"lib\", alias.slice(\"$lib\".length));\n\t}\n\treturn undefined;\n}\n\nfunction svelteAliases(raw: Record<string, string>): Record<AliasKey, string> {\n\tconst lib = raw.lib ?? \"$lib\";\n\treturn {\n\t\tcomponents: raw.components ?? `${lib}/components`,\n\t\tui: raw.ui ?? `${raw.components ?? `${lib}/components`}/ui`,\n\t\tlib,\n\t\thooks: raw.hooks ?? `${lib}/hooks`,\n\t\tutils: raw.utils ?? `${lib}/utils`,\n\t};\n}\n\nfunction reactAliases(raw: Record<string, string>): Record<AliasKey, string> {\n\tconst components = raw.components ?? \"@/components\";\n\tconst utils = raw.utils ?? \"@/lib/utils\";\n\treturn {\n\t\tcomponents,\n\t\tui: raw.ui ?? `${components}/ui`,\n\t\tlib: raw.lib ?? utils.replace(/\\/[^/]+$/, \"\"),\n\t\thooks: raw.hooks ?? `${components.replace(/\\/[^/]+$/, \"\")}/hooks`,\n\t\tutils,\n\t};\n}\n\n/** The resolved install config for a project that has a components.json. */\nexport function installConfig(project: Project): InstallConfig {\n\tconst config = project.config;\n\tconst framework = project.framework;\n\tif (!config || !framework) {\n\t\tthrow new CliError(`${project.root} has no components.json.`, {\n\t\t\thint: \"Run `baby-ui init` there first.\",\n\t\t});\n\t}\n\tconst aliases =\n\t\tframework === \"svelte\" ? svelteAliases(config.aliases) : reactAliases(config.aliases);\n\tconst missing: string[] = [];\n\tconst need = (key: AliasKey) => {\n\t\tconst dir = resolveAlias(aliases[key], project);\n\t\tif (!dir) missing.push(`${key} (${aliases[key]})`);\n\t\treturn dir ?? \"\";\n\t};\n\tconst paths = {\n\t\tcomponents: need(\"components\"),\n\t\tui: need(\"ui\"),\n\t\tlib: need(\"lib\"),\n\t\thooks: need(\"hooks\"),\n\t\tutils: need(\"utils\"),\n\t};\n\tif (missing.length) {\n\t\tthrow new CliError(\n\t\t\t`Could not resolve aliases in ${project.root}: ${missing.join(\", \")}.`,\n\t\t\t{\n\t\t\t\thint: \"Map them in tsconfig.json `paths` or package.json `imports`.\",\n\t\t\t},\n\t\t);\n\t}\n\tconst raw = config.raw;\n\tconst typescript =\n\t\tframework === \"svelte\" ? raw.typescript !== false : raw.tsx !== false;\n\treturn {\n\t\tproject,\n\t\tframework,\n\t\ttypescript,\n\t\trsc: raw.rsc === true,\n\t\tsrcDir: existsSync(join(project.root, \"src\")),\n\t\taliases,\n\t\tdeclaredAliases: Object.fromEntries(\n\t\t\tALIAS_KEYS.flatMap((key) => {\n\t\t\t\tconst value = config.aliases[key];\n\t\t\t\treturn value ? [[key, value]] : [];\n\t\t\t}),\n\t\t),\n\t\tpaths: { ...paths, css: config.css ? resolve(project.root, config.css) : undefined },\n\t};\n}\n","import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { CliError } from \"../errors.ts\";\nimport type { Framework } from \"../project/config.ts\";\nimport { isRecord, type Json } from \"../project/fs.ts\";\n\nexport const BABY_UI_ORIGIN = \"https://baby-ui.pages.dev\";\n\n/** `BABY_UI_REGISTRY_URL` swaps our origin everywhere, including inside items' dependency URLs. */\nexport const registryOrigin = () =>\n\t(process.env.BABY_UI_REGISTRY_URL ?? BABY_UI_ORIGIN).replace(/\\/$/, \"\");\n\nexport interface RegistryContext {\n\treadonly framework: Framework;\n\t/** False installs the JS dialect our registry builds (`/r/js/`), or fails for others. */\n\treadonly typescript: boolean;\n\treadonly config: Json;\n\treadonly cwd: string;\n}\n\nexport interface ItemRequest {\n\treadonly url: string;\n\treadonly headers: Readonly<Record<string, string>>;\n}\n\nexport function babyUiUrl(name: string, ctx: RegistryContext): string {\n\tconst route = ctx.framework === \"react\" ? \"r\" : \"svelte/r\";\n\treturn `${registryOrigin()}/${route}${ctx.typescript ? \"\" : \"/js\"}/${name}.json`;\n}\n\n/** shadcn and shadcn-svelte resolve a bare dependency name against their own registry. */\nfunction upstreamUrl(name: string, ctx: RegistryContext): string {\n\tconst style = typeof ctx.config.style === \"string\" ? ctx.config.style : undefined;\n\tif (ctx.framework === \"react\") {\n\t\treturn `https://ui.shadcn.com/r/styles/${style ?? \"new-york-v4\"}/${name}.json`;\n\t}\n\tconst base =\n\t\ttypeof ctx.config.registry === \"string\"\n\t\t\t? ctx.config.registry\n\t\t\t: \"https://shadcn-svelte.com/registry\";\n\treturn `${base.replace(/\\/$/, \"\")}/styles/${style ?? \"vega\"}/${name}.json`;\n}\n\nfunction expandEnv(value: string): string {\n\treturn value.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => {\n\t\tconst found = process.env[name];\n\t\tif (found === undefined) {\n\t\t\tthrow new CliError(`Environment variable ${name} is not set.`, {\n\t\t\t\thint: \"A registry in components.json references it in its url or headers.\",\n\t\t\t});\n\t\t}\n\t\treturn found;\n\t});\n}\n\n/** Pro items sit under `/pro/` on our registry and need a licence token. */\nexport function proUrl(name: string, ctx: RegistryContext): string {\n\tconst route = ctx.framework === \"react\" ? \"r\" : \"svelte/r\";\n\treturn `${registryOrigin()}/pro/${route}${ctx.typescript ? \"\" : \"/js\"}/${name}.json`;\n}\n\nfunction namespaced(ns: string, name: string, ctx: RegistryContext): ItemRequest {\n\tif (ns === \"@baby-ui\") return { url: babyUiUrl(name, ctx), headers: {} };\n\t// Our own auth adds the token in fetch, so components.json needs no entry for this.\n\tif (ns === \"@baby-ui-pro\") return { url: proUrl(name, ctx), headers: {} };\n\tconst registries = isRecord(ctx.config.registries) ? ctx.config.registries : {};\n\tconst entry = registries[ns];\n\tif (entry === undefined) {\n\t\tif (ns === \"@shadcn\") return { url: upstreamUrl(name, ctx), headers: {} };\n\t\tthrow new CliError(`Unknown registry ${ns}.`, {\n\t\t\thint: `Add it under \"registries\" in components.json, e.g. \"${ns}\": \"https://example.com/r/{name}.json\".`,\n\t\t});\n\t}\n\tconst spec = typeof entry === \"string\" ? { url: entry } : isRecord(entry) ? entry : {};\n\tif (typeof spec.url !== \"string\") throw new CliError(`Registry ${ns} has no url.`);\n\tconst style = typeof ctx.config.style === \"string\" ? ctx.config.style : \"\";\n\tconst url = new URL(\n\t\texpandEnv(spec.url).replace(\"{name}\", name).replace(\"{style}\", style),\n\t);\n\tfor (const [key, value] of Object.entries(isRecord(spec.params) ? spec.params : {})) {\n\t\tif (typeof value === \"string\") url.searchParams.set(key, expandEnv(value));\n\t}\n\tconst headers: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(isRecord(spec.headers) ? spec.headers : {})) {\n\t\tif (typeof value === \"string\") headers[key] = expandEnv(value);\n\t}\n\treturn { url: url.toString(), headers };\n}\n\n/** A request for a URL from the lock, with headers from the components.json registry it came from. */\nexport function requestFor(url: string, ctx: RegistryContext): ItemRequest {\n\tif (url.startsWith(\"file:\")) return { url, headers: {} };\n\tconst registries = isRecord(ctx.config.registries) ? ctx.config.registries : {};\n\tfor (const [ns, entry] of Object.entries(registries)) {\n\t\tconst spec =\n\t\t\ttypeof entry === \"string\" ? { url: entry } : isRecord(entry) ? entry : {};\n\t\tif (typeof spec.url !== \"string\") continue;\n\t\tconst origin = new URL(spec.url.replace(/\\{\\w+\\}/g, \"x\").replace(/\\$\\{\\w+\\}/g, \"x\"))\n\t\t\t.origin;\n\t\tif (new URL(url).origin === origin)\n\t\t\treturn { url, headers: namespaced(ns, \"x\", ctx).headers };\n\t}\n\treturn { url: withOrigin(url), headers: {} };\n}\n\nconst withOrigin = (url: string) =>\n\turl.startsWith(BABY_UI_ORIGIN)\n\t\t? registryOrigin() + url.slice(BABY_UI_ORIGIN.length)\n\t\t: url;\n\n/** The public URL for the lock, so a local `BABY_UI_REGISTRY_URL` never gets committed. */\nexport function canonicalUrl(url: string): string {\n\tconst origin = registryOrigin();\n\treturn origin !== BABY_UI_ORIGIN && url.startsWith(origin)\n\t\t? BABY_UI_ORIGIN + url.slice(origin.length)\n\t\t: url;\n}\n\n/**\n * Turns a user or dependency specifier into a request. Bare names mean Baby UI at the top\n * level and the parent's upstream registry inside a third-party item.\n */\nexport function resolveSpecifier(\n\tspec: string,\n\tctx: RegistryContext,\n\tparent?: string,\n): ItemRequest {\n\tif (/^https?:\\/\\//.test(spec)) return { url: withOrigin(spec), headers: {} };\n\tif (spec.startsWith(\"file:\")) return { url: spec, headers: {} };\n\tconst ns = /^(@[\\w-]+)\\/(.+)$/.exec(spec);\n\tif (ns?.[1] && ns[2]) return namespaced(ns[1], ns[2], ctx);\n\tif (parent && (spec.startsWith(\"./\") || spec.startsWith(\"../\"))) {\n\t\treturn { url: new URL(spec, parent).toString(), headers: {} };\n\t}\n\tif (spec.endsWith(\".json\") && existsSync(resolve(ctx.cwd, spec))) {\n\t\treturn { url: pathToFileURL(resolve(ctx.cwd, spec)).toString(), headers: {} };\n\t}\n\tconst fromUs =\n\t\t!parent || parent.startsWith(registryOrigin()) || parent.startsWith(\"file:\");\n\treturn { url: fromUs ? babyUiUrl(spec, ctx) : upstreamUrl(spec, ctx), headers: {} };\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { credential } from \"../auth.ts\";\nimport { CliError } from \"../errors.ts\";\nimport { log } from \"../logger.ts\";\nimport { type ItemRequest, registryOrigin } from \"./resolve.ts\";\n\nexport function cacheDir(): string {\n\tif (process.env.BABY_UI_CACHE_DIR) return process.env.BABY_UI_CACHE_DIR;\n\tif (process.platform === \"win32\") {\n\t\treturn join(\n\t\t\tprocess.env.LOCALAPPDATA ?? join(homedir(), \"AppData\", \"Local\"),\n\t\t\t\"baby-ui\",\n\t\t\t\"cache\",\n\t\t);\n\t}\n\tif (process.platform === \"darwin\")\n\t\treturn join(homedir(), \"Library\", \"Caches\", \"baby-ui\");\n\treturn join(process.env.XDG_CACHE_HOME ?? join(homedir(), \".cache\"), \"baby-ui\");\n}\n\ninterface CacheEntry {\n\tetag: string | null;\n\tbody: string;\n}\n\nconst entryPath = (url: string) =>\n\tjoin(cacheDir(), `${createHash(\"sha256\").update(url).digest(\"hex\").slice(0, 32)}.json`);\n\nasync function readCache(url: string): Promise<CacheEntry | undefined> {\n\ttry {\n\t\tconst entry: unknown = JSON.parse(await readFile(entryPath(url), \"utf8\"));\n\t\tif (\n\t\t\ttypeof entry === \"object\" &&\n\t\t\tentry &&\n\t\t\t\"body\" in entry &&\n\t\t\ttypeof entry.body === \"string\"\n\t\t) {\n\t\t\tconst etag = \"etag\" in entry && typeof entry.etag === \"string\" ? entry.etag : null;\n\t\t\treturn { etag, body: entry.body };\n\t\t}\n\t} catch {}\n\treturn undefined;\n}\n\nasync function writeCache(url: string, entry: CacheEntry): Promise<void> {\n\ttry {\n\t\tawait mkdir(cacheDir(), { recursive: true });\n\t\tawait writeFile(entryPath(url), JSON.stringify(entry));\n\t} catch {}\n}\n\n// The licence token only ever goes to our own registry origin, never to third parties.\nasync function authHeaders(url: string, headers: Readonly<Record<string, string>>) {\n\tconst has = Object.keys(headers).some((k) => k.toLowerCase() === \"authorization\");\n\tif (has || !url.startsWith(`${registryOrigin()}/`)) return headers;\n\tconst cred = await credential();\n\treturn cred ? { ...headers, authorization: `Bearer ${cred.token}` } : headers;\n}\n\n/** Fetches text with an ETag cache; offline runs fall back to the cached copy. */\nexport async function fetchText({ url, headers }: ItemRequest): Promise<string> {\n\tif (url.startsWith(\"file:\")) {\n\t\ttry {\n\t\t\treturn await readFile(fileURLToPath(url), \"utf8\");\n\t\t} catch {\n\t\t\tthrow new CliError(`Not found: ${url}`);\n\t\t}\n\t}\n\tconst cached = await readCache(url);\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: {\n\t\t\t\t...(await authHeaders(url, headers)),\n\t\t\t\t...(cached?.etag ? { \"if-none-match\": cached.etag } : {}),\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (cached) {\n\t\t\tlog.warn(`Offline, using the cached copy of ${url}`);\n\t\t\treturn cached.body;\n\t\t}\n\t\tthrow new CliError(`Could not reach ${url}.`, { hint: String(error) });\n\t}\n\tif (response.status === 304 && cached) return cached.body;\n\tif (response.status === 401 || response.status === 403) {\n\t\tthrow new CliError(`${url} needs authorisation (HTTP ${response.status}).`, {\n\t\t\thint: \"Pro items need `baby-ui login`; other registries need their headers in components.json.\",\n\t\t});\n\t}\n\tif (response.status === 404) throw new CliError(`Not found: ${url}`);\n\tif (!response.ok) throw new CliError(`HTTP ${response.status} from ${url}`);\n\tconst body = await response.text();\n\tawait writeCache(url, { etag: response.headers.get(\"etag\"), body });\n\treturn body;\n}\n\nexport async function fetchJson(request: ItemRequest): Promise<unknown> {\n\tconst text = await fetchText(request);\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\tthrow new CliError(`${request.url} did not return JSON.`);\n\t}\n}\n","import { z } from \"zod\";\n\nconst record = z.record(z.string(), z.string());\n\n// Lenient on purpose: third-party registries omit fields our own build always writes.\nexport const RegistryFileSchema = z.object({\n\tpath: z.string(),\n\tcontent: z.string().optional(),\n\ttype: z.string(),\n\ttarget: z.string().optional(),\n});\n\nexport const RegistryItemSchema = z.object({\n\tname: z.string(),\n\ttype: z.string(),\n\ttitle: z.string().optional(),\n\tdescription: z.string().optional(),\n\tdependencies: z.array(z.string()).optional(),\n\tdevDependencies: z.array(z.string()).optional(),\n\tregistryDependencies: z.array(z.string()).optional(),\n\tfiles: z.array(RegistryFileSchema).optional(),\n\tcssVars: z.record(z.string(), record).optional(),\n\tcss: z.record(z.string(), z.unknown()).optional(),\n\tmeta: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type RegistryFile = z.infer<typeof RegistryFileSchema>;\nexport type RegistryItem = z.infer<typeof RegistryItemSchema>;\n\nexport const RegistryIndexSchema = z.array(\n\tz.object({\n\t\tname: z.string(),\n\t\ttype: z.string(),\n\t\ttitle: z.string().optional(),\n\t\tdescription: z.string().optional(),\n\t}),\n);\n\nexport type RegistryIndex = z.infer<typeof RegistryIndexSchema>;\n","import { spawn } from \"node:child_process\";\nimport { CliError } from \"../errors.ts\";\nimport type { Project } from \"../project/detect.ts\";\nimport type { PackageManager } from \"../project/pm.ts\";\n\n// npm names plus a simple range; no spaces, pipes or angle brackets, so the shell sees no syntax.\nconst SPEC = /^(@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*(@[\\w.^~*+-]+)?$/i;\n\n/** `@scope/pkg@^1` -> `@scope/pkg`. */\nexport const packageName = (spec: string) => spec.replace(/(?!^)@.*$/, \"\");\n\nexport function missingPackages(project: Project, specs: Iterable<string>): string[] {\n\tconst wanted = new Map<string, string>();\n\tfor (const spec of specs) {\n\t\tif (!SPEC.test(spec))\n\t\t\tthrow new CliError(`Refusing to install \"${spec}\": not a package name.`);\n\t\tconst name = packageName(spec);\n\t\tif (!project.dependencies.has(name)) wanted.set(name, spec);\n\t}\n\treturn [...wanted.values()].sort();\n}\n\nexport function installArgs(\n\tpm: PackageManager,\n\tpackages: readonly string[],\n\tdev: boolean,\n) {\n\tconst verb = pm === \"npm\" ? \"install\" : \"add\";\n\treturn [verb, ...(dev ? [pm === \"bun\" ? \"--dev\" : \"-D\"] : []), ...packages];\n}\n\nexport function installCommand(\n\tpm: PackageManager,\n\tpackages: readonly string[],\n\tdev: boolean,\n) {\n\treturn [pm, ...installArgs(pm, packages, dev)].join(\" \");\n}\n\n/** Runs the project's package manager; specs were validated by `missingPackages`. */\nexport function install(\n\tproject: Project,\n\tpackages: readonly string[],\n\tdev: boolean,\n): Promise<void> {\n\tif (!packages.length) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\t// Windows package managers are .cmd shims, which only start through a shell.\n\t\tconst child = spawn(project.pm, installArgs(project.pm, packages, dev), {\n\t\t\tcwd: project.root,\n\t\t\tstdio: \"inherit\",\n\t\t\tshell: process.platform === \"win32\",\n\t\t});\n\t\tchild.on(\"error\", reject);\n\t\tchild.on(\"exit\", (code) =>\n\t\t\tcode === 0\n\t\t\t\t? resolve()\n\t\t\t\t: reject(\n\t\t\t\t\t\tnew CliError(\n\t\t\t\t\t\t\t`${installCommand(project.pm, packages, dev)} exited with ${code}.`,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\thint: \"Files were written; run the install yourself or `baby-ui undo`.\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t);\n\t});\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { extname, join } from \"node:path\";\nimport { parseSync } from \"oxc-parser\";\nimport type { Project } from \"../project/detect.ts\";\nimport { type InstallConfig, resolveAlias } from \"../project/paths.ts\";\nimport { packageName } from \"./deps.ts\";\nimport { type LockFile, type LockItem, readLock, sha256 } from \"./lock.ts\";\n\nexport type FileHealth = \"clean\" | \"modified\" | \"missing\" | \"broken\";\n\nexport interface FileState {\n\t/** Root-relative posix path, as the lock stores it. */\n\treadonly path: string;\n\treadonly health: FileHealth;\n\t/** Alias imports that no longer land on a file. */\n\treadonly unresolved: readonly string[];\n}\n\nexport interface ItemState {\n\treadonly url: string;\n\treadonly item: LockItem;\n\treadonly files: readonly FileState[];\n\treadonly missingDeps: readonly string[];\n}\n\nconst SCRIPT = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"]);\nconst EXT = [\n\t\"\",\n\t\".ts\",\n\t\".tsx\",\n\t\".js\",\n\t\".jsx\",\n\t\".svelte\",\n\t\"/index.ts\",\n\t\"/index.tsx\",\n\t\"/index.js\",\n];\n\nfunction specifiers(path: string, code: string): string[] | undefined {\n\tconst ext = extname(path);\n\tif (ext === \".svelte\") {\n\t\tconst out: string[] = [];\n\t\tfor (const m of code.matchAll(/<script[^>]*>([\\s\\S]*?)<\\/script>/g)) {\n\t\t\tconst parsed = parseSync(\"script.ts\", m[1] ?? \"\");\n\t\t\tif (parsed.errors.length) return undefined;\n\t\t\tout.push(...parsed.module.staticImports.map((i) => i.moduleRequest.value));\n\t\t}\n\t\treturn out;\n\t}\n\tif (!SCRIPT.has(ext)) return [];\n\tconst parsed = parseSync(path, code);\n\tif (parsed.errors.length) return undefined;\n\treturn [\n\t\t...parsed.module.staticImports.map((i) => i.moduleRequest.value),\n\t\t...parsed.module.staticExports.flatMap((e) =>\n\t\t\te.entries.flatMap((x) => x.moduleRequest?.value ?? []),\n\t\t),\n\t];\n}\n\n/** Alias-prefixed imports in `code` that resolve to no file. */\nexport function unresolvedImports(\n\tpath: string,\n\tcode: string,\n\tproject: Project,\n): string[] | undefined {\n\tconst found = specifiers(path, code);\n\tif (!found) return undefined;\n\tconst prefixes = project.aliases.map((a) => a.prefix.slice(0, -1));\n\tif (project.dollarLib) prefixes.push(\"$lib\");\n\treturn found.filter((spec) => {\n\t\tif (!prefixes.some((p) => spec === p || spec.startsWith(`${p}/`))) return false;\n\t\tconst base = resolveAlias(spec, project);\n\t\tif (!base) return true;\n\t\tconst bare = base.replace(/\\.js$/, \"\");\n\t\treturn !EXT.some((e) => existsSync(base + e) || existsSync(bare + e));\n\t});\n}\n\nexport function fileState(\n\troot: string,\n\tpath: string,\n\thash: string,\n\tproject: Project,\n): FileState {\n\tconst abs = join(root, path);\n\tif (!existsSync(abs)) return { path, health: \"missing\", unresolved: [] };\n\tconst code = readFileSync(abs, \"utf8\");\n\tconst unresolved = unresolvedImports(abs, code, project);\n\tif (unresolved === undefined) return { path, health: \"broken\", unresolved: [] };\n\treturn { path, health: sha256(code) === hash ? \"clean\" : \"modified\", unresolved };\n}\n\n/** The local state of every locked item in `cfg`'s project; no network. */\nexport async function inspect(cfg: InstallConfig, lock?: LockFile): Promise<ItemState[]> {\n\tconst project = cfg.project;\n\tconst { items } = lock ?? (await readLock(project.root));\n\treturn Object.entries(items).map(([url, item]) => ({\n\t\turl,\n\t\titem,\n\t\tfiles: Object.entries(item.files).map(([path, hash]) =>\n\t\t\tfileState(project.root, path, hash, project),\n\t\t),\n\t\tmissingDeps: item.dependencies.filter(\n\t\t\t(d) => !project.dependencies.has(packageName(d)),\n\t\t),\n\t}));\n}\n\n/** Lock entries whose name or URL matches one of `names`; all of them when `names` is empty. */\nexport function matchItems(\n\tlock: LockFile,\n\tnames: readonly string[],\n): Array<[string, LockItem]> {\n\tconst entries = Object.entries(lock.items);\n\tif (!names.length) return entries;\n\treturn entries.filter(\n\t\t([url, item]) => names.includes(item.name) || names.includes(url),\n\t);\n}\n"],"mappings":"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"}