@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,316 @@
1
+ import { createRequire } from "node:module";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
+ //#region \0rolldown/runtime.js
5
+ var __create = Object.create;
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
+ key = keys[i];
15
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: ((k) => from[k]).bind(null, key),
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
27
+ //#endregion
28
+ //#region src/project/fs.ts
29
+ /** Parses JSON or JSONC (tsconfig): comments and trailing commas are dropped. */
30
+ function readJson(file) {
31
+ if (!existsSync(file)) return void 0;
32
+ const text = readFileSync(file, "utf8").replace(/("(?:\\.|[^"\\])*")|\/\/[^\n]*|\/\*[\s\S]*?\*\//g, (_, str) => str ?? "").replace(/,(\s*[}\]])/g, "$1");
33
+ try {
34
+ const value = JSON.parse(text);
35
+ return isRecord(value) ? value : void 0;
36
+ } catch {
37
+ return;
38
+ }
39
+ }
40
+ function isRecord(value) {
41
+ return typeof value === "object" && value !== null && !Array.isArray(value);
42
+ }
43
+ const toPosix = (path) => path.split(sep).join("/");
44
+ /** `dir` and each parent up to the filesystem root. */
45
+ function* ancestors(dir) {
46
+ let current = dir;
47
+ while (true) {
48
+ yield current;
49
+ const parent = dirname(current);
50
+ if (parent === current) return;
51
+ current = parent;
52
+ }
53
+ }
54
+ //#endregion
55
+ //#region src/project/config.ts
56
+ function flavour(raw) {
57
+ const schema = typeof raw.$schema === "string" ? raw.$schema : "";
58
+ if (schema.includes("shadcn-svelte.com")) return "svelte";
59
+ if (schema.includes("ui.shadcn.com")) return "react";
60
+ if ("tsx" in raw || "rsc" in raw) return "react";
61
+ if ("typescript" in raw || "registry" in raw) return "svelte";
62
+ }
63
+ /** Reads `components.json` as-is; we never write keys into it (shadcn's schema is strict). */
64
+ function readComponentsConfig(root) {
65
+ const raw = readJson(join(root, "components.json"));
66
+ return raw ? parseComponentsConfig(raw) : void 0;
67
+ }
68
+ function parseComponentsConfig(raw) {
69
+ const tailwind = isRecord(raw.tailwind) ? raw.tailwind : {};
70
+ const aliases = {};
71
+ if (isRecord(raw.aliases)) {
72
+ for (const [key, value] of Object.entries(raw.aliases)) if (typeof value === "string") aliases[key] = value;
73
+ }
74
+ return {
75
+ framework: flavour(raw),
76
+ css: typeof tailwind.css === "string" ? tailwind.css : void 0,
77
+ aliases,
78
+ raw
79
+ };
80
+ }
81
+ //#endregion
82
+ //#region src/project/pm.ts
83
+ const PACKAGE_MANAGERS = [
84
+ "pnpm",
85
+ "bun",
86
+ "yarn",
87
+ "npm"
88
+ ];
89
+ const LOCKFILES = [
90
+ ["pnpm-lock.yaml", "pnpm"],
91
+ ["bun.lock", "bun"],
92
+ ["bun.lockb", "bun"],
93
+ ["yarn.lock", "yarn"],
94
+ ["package-lock.json", "npm"]
95
+ ];
96
+ function isPackageManager(value) {
97
+ return PACKAGE_MANAGERS.some((pm) => pm === value);
98
+ }
99
+ function detectPm(root, pkg, stop) {
100
+ for (const dir of ancestors(root)) {
101
+ for (const [file, pm] of LOCKFILES) if (existsSync(join(dir, file))) return {
102
+ pm,
103
+ pmSource: "lockfile"
104
+ };
105
+ if (dir === stop) break;
106
+ }
107
+ const declared = String(pkg?.packageManager ?? "").split("@")[0] ?? "";
108
+ if (isPackageManager(declared)) return {
109
+ pm: declared,
110
+ pmSource: "packageManager"
111
+ };
112
+ const agent = (process.env.npm_config_user_agent ?? "").split("/")[0] ?? "";
113
+ if (isPackageManager(agent)) return {
114
+ pm: agent,
115
+ pmSource: "user agent"
116
+ };
117
+ return {
118
+ pm: "npm",
119
+ pmSource: "default"
120
+ };
121
+ }
122
+ //#endregion
123
+ //#region src/project/detect.ts
124
+ function dependencyVersions(pkg) {
125
+ const versions = {};
126
+ for (const field of [
127
+ "dependencies",
128
+ "devDependencies",
129
+ "peerDependencies"
130
+ ]) {
131
+ const block = pkg?.[field];
132
+ if (!isRecord(block)) continue;
133
+ for (const [name, range] of Object.entries(block)) if (typeof range === "string") versions[name] ??= range;
134
+ }
135
+ return versions;
136
+ }
137
+ function detectMeta(deps) {
138
+ if (deps.has("next")) return "next";
139
+ if (deps.has("@tanstack/react-start")) return "tanstack-start";
140
+ if (deps.has("react-router") || deps.has("@react-router/dev")) return "react-router";
141
+ if (deps.has("@sveltejs/kit")) return "sveltekit";
142
+ if (deps.has("svelte")) return "vite-svelte";
143
+ if (deps.has("react")) return "vite-react";
144
+ }
145
+ const META_FRAMEWORK = {
146
+ next: "react",
147
+ "tanstack-start": "react",
148
+ "react-router": "react",
149
+ "vite-react": "react",
150
+ sveltekit: "svelte",
151
+ "vite-svelte": "svelte"
152
+ };
153
+ function tsconfigPaths(file, seen = /* @__PURE__ */ new Set()) {
154
+ if (seen.has(file)) return void 0;
155
+ seen.add(file);
156
+ const config = readJson(file);
157
+ if (!config) return void 0;
158
+ const dir = dirname(file);
159
+ const options = isRecord(config.compilerOptions) ? config.compilerOptions : {};
160
+ const baseUrl = typeof options.baseUrl === "string" ? resolve(dir, options.baseUrl) : void 0;
161
+ if (isRecord(options.paths)) return {
162
+ paths: options.paths,
163
+ base: baseUrl ?? dir
164
+ };
165
+ const parents = [config.extends].flat().filter((p) => typeof p === "string");
166
+ for (const parent of parents.reverse()) {
167
+ if (!parent.startsWith(".")) continue;
168
+ const target = resolve(dir, parent);
169
+ const found = tsconfigPaths(target.endsWith(".json") ? target : `${target}.json`, seen);
170
+ if (found) return baseUrl ? {
171
+ ...found,
172
+ base: baseUrl
173
+ } : found;
174
+ }
175
+ }
176
+ function detectAliases(root, pkg) {
177
+ const aliases = [];
178
+ const tsconfig = ["tsconfig.json", "jsconfig.json"].map((name) => join(root, name)).find((file) => existsSync(file));
179
+ const ts = tsconfig ? tsconfigPaths(tsconfig) : void 0;
180
+ for (const [key, targets] of Object.entries(ts?.paths ?? {})) {
181
+ const target = Array.isArray(targets) ? targets[0] : void 0;
182
+ if (!key.endsWith("/*") || typeof target !== "string" || !target.endsWith("/*")) continue;
183
+ aliases.push({
184
+ prefix: key.slice(0, -1),
185
+ dir: resolve(ts?.base ?? root, target.slice(0, -2)),
186
+ withExtension: false
187
+ });
188
+ }
189
+ const imports = isRecord(pkg?.imports) ? pkg.imports : {};
190
+ for (const [key, target] of Object.entries(imports)) {
191
+ if (!key.endsWith("/*") || typeof target !== "string" || !target.endsWith("/*")) continue;
192
+ aliases.push({
193
+ prefix: key.slice(0, -1),
194
+ dir: resolve(root, target.slice(0, -2)),
195
+ withExtension: true
196
+ });
197
+ }
198
+ return aliases;
199
+ }
200
+ function kitMajor(root, versions) {
201
+ const installed = readJson(join(root, "node_modules", "@sveltejs", "kit", "package.json"));
202
+ const version = String(installed?.version ?? versions["@sveltejs/kit"] ?? "");
203
+ const major = /(\d+)/.exec(version)?.[1];
204
+ return major === void 0 ? 3 : Number(major);
205
+ }
206
+ /** Detects one project directory; `stop` bounds the upward lockfile search (workspace root). */
207
+ function detectProject(root, stop = root) {
208
+ const pkg = readJson(join(root, "package.json"));
209
+ const versions = dependencyVersions(pkg);
210
+ const dependencies = new Set(Object.keys(versions));
211
+ const config = readComponentsConfig(root);
212
+ const meta = detectMeta(dependencies);
213
+ const fromDeps = meta ? META_FRAMEWORK[meta] : void 0;
214
+ const framework = config?.framework ?? fromDeps;
215
+ return {
216
+ root,
217
+ name: typeof pkg?.name === "string" ? pkg.name : void 0,
218
+ framework,
219
+ frameworkSource: config?.framework ? "components.json" : fromDeps ? "dependencies" : void 0,
220
+ meta,
221
+ ...detectPm(root, pkg, stop),
222
+ config,
223
+ dependencies,
224
+ aliases: detectAliases(root, pkg),
225
+ dollarLib: meta === "sveltekit" && kitMajor(root, versions) < 3
226
+ };
227
+ }
228
+ //#endregion
229
+ //#region src/project/targets.ts
230
+ async function pnpmPatterns(file) {
231
+ const { parse } = await import("./dist-CxDndWiZ.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1));
232
+ const doc = parse(readFileSync(file, "utf8"));
233
+ const packages = isRecord(doc) ? doc.packages : void 0;
234
+ return Array.isArray(packages) ? packages.filter((p) => typeof p === "string") : [];
235
+ }
236
+ function npmPatterns(workspaces) {
237
+ const list = isRecord(workspaces) ? workspaces.packages : workspaces;
238
+ return Array.isArray(list) ? list.filter((p) => typeof p === "string") : void 0;
239
+ }
240
+ async function findRoot(cwd) {
241
+ let nearest;
242
+ for (const dir of ancestors(resolve(cwd))) {
243
+ const pnpm = join(dir, "pnpm-workspace.yaml");
244
+ if (existsSync(pnpm)) return {
245
+ workspace: {
246
+ root: dir,
247
+ patterns: await pnpmPatterns(pnpm)
248
+ },
249
+ nearest
250
+ };
251
+ const pkg = readJson(join(dir, "package.json"));
252
+ const patterns = npmPatterns(pkg?.workspaces);
253
+ if (patterns) return {
254
+ workspace: {
255
+ root: dir,
256
+ patterns
257
+ },
258
+ nearest
259
+ };
260
+ if (pkg && !nearest) nearest = dir;
261
+ }
262
+ return { workspace: {
263
+ root: nearest ?? resolve(cwd),
264
+ patterns: []
265
+ } };
266
+ }
267
+ /**
268
+ * The workspace containing `cwd`. A package inside a workspace folder that its patterns
269
+ * don't list (a scratch app, an example) is treated as its own single-app workspace.
270
+ */
271
+ async function findWorkspace(cwd) {
272
+ const { workspace, nearest } = await findRoot(cwd);
273
+ if (!nearest || nearest === workspace.root) return workspace;
274
+ return (await packageDirs(workspace)).includes(nearest) ? workspace : {
275
+ root: nearest,
276
+ patterns: []
277
+ };
278
+ }
279
+ async function packageDirs(workspace) {
280
+ if (!workspace.patterns.length) return [workspace.root];
281
+ const { glob } = await import("./dist-Bs-3vZ2T.js");
282
+ const include = workspace.patterns.filter((p) => !p.startsWith("!"));
283
+ const ignore = workspace.patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
284
+ const dirs = (await glob(include.map((p) => `${p.replace(/\/$/, "")}/package.json`), {
285
+ cwd: workspace.root,
286
+ ignore: [...ignore, "**/node_modules/**"],
287
+ absolute: true
288
+ })).map((file) => resolve(file, ".."));
289
+ return [workspace.root, ...dirs.sort()];
290
+ }
291
+ /** Every package that has a components.json or a React/Svelte dependency. */
292
+ async function discoverTargets(workspace) {
293
+ const dirs = await packageDirs(workspace);
294
+ const monorepo = workspace.patterns.length > 0;
295
+ return dirs.map((dir) => ({
296
+ ...detectProject(dir, workspace.root),
297
+ path: toPosix(relative(workspace.root, dir)) || "."
298
+ })).filter((t) => t.framework !== void 0).filter((t) => !(monorepo && t.path === "." && !t.config));
299
+ }
300
+ /** The deepest target containing `cwd`, so running inside a package picks that package. */
301
+ function targetAt(targets, cwd) {
302
+ const here = resolve(cwd);
303
+ return targets.filter((t) => {
304
+ const rest = relative(t.root, here);
305
+ return !rest.startsWith("..") && !isAbsolute(rest);
306
+ }).sort((a, b) => b.root.length - a.root.length)[0];
307
+ }
308
+ /** Matches `--target` against package name or workspace-relative path. */
309
+ function matchTarget(targets, query) {
310
+ const path = toPosix(query).replace(/^\.\//, "").replace(/\/$/, "") || ".";
311
+ return targets.find((t) => t.name === query || t.path === path);
312
+ }
313
+ //#endregion
314
+ export { parseComponentsConfig as a, toPosix as c, __toESM as d, targetAt as i, __commonJSMin as l, findWorkspace as n, ancestors as o, matchTarget as r, isRecord as s, discoverTargets as t, __require as u };
315
+
316
+ //# sourceMappingURL=targets-Bpv2h7C4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets-Bpv2h7C4.js","names":[],"sources":["../src/project/fs.ts","../src/project/config.ts","../src/project/pm.ts","../src/project/detect.ts","../src/project/targets.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, sep } from \"node:path\";\n\nexport type Json = Record<string, unknown>;\n\n/** Parses JSON or JSONC (tsconfig): comments and trailing commas are dropped. */\nexport function readJson(file: string): Json | undefined {\n\tif (!existsSync(file)) return undefined;\n\tconst text = readFileSync(file, \"utf8\")\n\t\t.replace(/(\"(?:\\\\.|[^\"\\\\])*\")|\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g, (_, str) => str ?? \"\")\n\t\t.replace(/,(\\s*[}\\]])/g, \"$1\");\n\ttry {\n\t\tconst value: unknown = JSON.parse(text);\n\t\treturn isRecord(value) ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function isRecord(value: unknown): value is Json {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport const toPosix = (path: string) => path.split(sep).join(\"/\");\n\n/** `dir` and each parent up to the filesystem root. */\nexport function* ancestors(dir: string): Generator<string> {\n\tlet current = dir;\n\twhile (true) {\n\t\tyield current;\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) return;\n\t\tcurrent = parent;\n\t}\n}\n","import { join } from \"node:path\";\nimport { isRecord, type Json, readJson } from \"./fs.ts\";\n\nexport type Framework = \"react\" | \"svelte\";\n\nexport interface ComponentsConfig {\n\treadonly framework: Framework | undefined;\n\treadonly css: string | undefined;\n\treadonly aliases: Readonly<Record<string, string>>;\n\treadonly raw: Json;\n}\n\n// shadcn writes `tsx`/`rsc`, shadcn-svelte writes `typescript`/`registry`; `$schema` is optional.\nfunction flavour(raw: Json): Framework | undefined {\n\tconst schema = typeof raw.$schema === \"string\" ? raw.$schema : \"\";\n\tif (schema.includes(\"shadcn-svelte.com\")) return \"svelte\";\n\tif (schema.includes(\"ui.shadcn.com\")) return \"react\";\n\tif (\"tsx\" in raw || \"rsc\" in raw) return \"react\";\n\tif (\"typescript\" in raw || \"registry\" in raw) return \"svelte\";\n\treturn undefined;\n}\n\n/** Reads `components.json` as-is; we never write keys into it (shadcn's schema is strict). */\nexport function readComponentsConfig(root: string): ComponentsConfig | undefined {\n\tconst raw = readJson(join(root, \"components.json\"));\n\treturn raw ? parseComponentsConfig(raw) : undefined;\n}\n\nexport function parseComponentsConfig(raw: Json): ComponentsConfig {\n\tconst tailwind = isRecord(raw.tailwind) ? raw.tailwind : {};\n\tconst aliases: Record<string, string> = {};\n\tif (isRecord(raw.aliases)) {\n\t\tfor (const [key, value] of Object.entries(raw.aliases)) {\n\t\t\tif (typeof value === \"string\") aliases[key] = value;\n\t\t}\n\t}\n\treturn {\n\t\tframework: flavour(raw),\n\t\tcss: typeof tailwind.css === \"string\" ? tailwind.css : undefined,\n\t\taliases,\n\t\traw,\n\t};\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { ancestors, type Json } from \"./fs.ts\";\n\nexport const PACKAGE_MANAGERS = [\"pnpm\", \"bun\", \"yarn\", \"npm\"] as const;\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\nexport type PmSource = \"flag\" | \"lockfile\" | \"packageManager\" | \"user agent\" | \"default\";\n\nconst LOCKFILES: ReadonlyArray<[string, PackageManager]> = [\n\t[\"pnpm-lock.yaml\", \"pnpm\"],\n\t[\"bun.lock\", \"bun\"],\n\t[\"bun.lockb\", \"bun\"],\n\t[\"yarn.lock\", \"yarn\"],\n\t[\"package-lock.json\", \"npm\"],\n];\n\nexport function isPackageManager(value: string): value is PackageManager {\n\treturn PACKAGE_MANAGERS.some((pm) => pm === value);\n}\n\n// Monorepo packages have no lockfile of their own, so the search walks up to `stop`.\nexport function detectPm(\n\troot: string,\n\tpkg: Json | undefined,\n\tstop: string,\n): { pm: PackageManager; pmSource: PmSource } {\n\tfor (const dir of ancestors(root)) {\n\t\tfor (const [file, pm] of LOCKFILES) {\n\t\t\tif (existsSync(join(dir, file))) return { pm, pmSource: \"lockfile\" };\n\t\t}\n\t\tif (dir === stop) break;\n\t}\n\tconst declared = String(pkg?.packageManager ?? \"\").split(\"@\")[0] ?? \"\";\n\tif (isPackageManager(declared)) return { pm: declared, pmSource: \"packageManager\" };\n\tconst agent = (process.env.npm_config_user_agent ?? \"\").split(\"/\")[0] ?? \"\";\n\tif (isPackageManager(agent)) return { pm: agent, pmSource: \"user agent\" };\n\treturn { pm: \"npm\", pmSource: \"default\" };\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type ComponentsConfig, type Framework, readComponentsConfig } from \"./config.ts\";\nimport { isRecord, type Json, readJson } from \"./fs.ts\";\nimport { detectPm, type PackageManager, type PmSource } from \"./pm.ts\";\n\nexport type { Framework } from \"./config.ts\";\n\nexport type Meta =\n\t| \"next\"\n\t| \"tanstack-start\"\n\t| \"react-router\"\n\t| \"vite-react\"\n\t| \"sveltekit\"\n\t| \"vite-svelte\";\n\nexport type FrameworkSource = \"components.json\" | \"dependencies\";\n\n/** An import prefix mapped to a directory, from tsconfig `paths` or package.json `imports`. */\nexport interface Alias {\n\treadonly prefix: string;\n\treadonly dir: string;\n\t/** Package `imports` resolve exact files, so specifiers need the extension. */\n\treadonly withExtension: boolean;\n}\n\nexport interface Project {\n\treadonly root: string;\n\treadonly name: string | undefined;\n\treadonly framework: Framework | undefined;\n\treadonly frameworkSource: FrameworkSource | undefined;\n\treadonly meta: Meta | undefined;\n\treadonly pm: PackageManager;\n\treadonly pmSource: PmSource;\n\treadonly config: ComponentsConfig | undefined;\n\treadonly dependencies: ReadonlySet<string>;\n\treadonly aliases: readonly Alias[];\n\t/** SvelteKit before 3 aliases `src/lib` as `$lib`; Kit 3 uses package.json `imports`. */\n\treadonly dollarLib: boolean;\n}\n\nfunction dependencyVersions(pkg: Json | undefined): Record<string, string> {\n\tconst versions: Record<string, string> = {};\n\tfor (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n\t\tconst block = pkg?.[field];\n\t\tif (!isRecord(block)) continue;\n\t\tfor (const [name, range] of Object.entries(block)) {\n\t\t\tif (typeof range === \"string\") versions[name] ??= range;\n\t\t}\n\t}\n\treturn versions;\n}\n\nexport function detectMeta(deps: ReadonlySet<string>): Meta | undefined {\n\tif (deps.has(\"next\")) return \"next\";\n\tif (deps.has(\"@tanstack/react-start\")) return \"tanstack-start\";\n\tif (deps.has(\"react-router\") || deps.has(\"@react-router/dev\")) return \"react-router\";\n\tif (deps.has(\"@sveltejs/kit\")) return \"sveltekit\";\n\tif (deps.has(\"svelte\")) return \"vite-svelte\";\n\tif (deps.has(\"react\")) return \"vite-react\";\n\treturn undefined;\n}\n\nconst META_FRAMEWORK: Record<Meta, Framework> = {\n\tnext: \"react\",\n\t\"tanstack-start\": \"react\",\n\t\"react-router\": \"react\",\n\t\"vite-react\": \"react\",\n\tsveltekit: \"svelte\",\n\t\"vite-svelte\": \"svelte\",\n};\n\ninterface TsPaths {\n\tpaths: Record<string, unknown>;\n\tbase: string;\n}\n\n// `paths` resolve against `baseUrl`, else the dir of the tsconfig declaring them; children override.\nfunction tsconfigPaths(file: string, seen = new Set<string>()): TsPaths | undefined {\n\tif (seen.has(file)) return undefined;\n\tseen.add(file);\n\tconst config = readJson(file);\n\tif (!config) return undefined;\n\tconst dir = dirname(file);\n\tconst options = isRecord(config.compilerOptions) ? config.compilerOptions : {};\n\tconst baseUrl =\n\t\ttypeof options.baseUrl === \"string\" ? resolve(dir, options.baseUrl) : undefined;\n\tif (isRecord(options.paths)) return { paths: options.paths, base: baseUrl ?? dir };\n\n\tconst parents = [config.extends].flat().filter((p) => typeof p === \"string\");\n\tfor (const parent of parents.reverse()) {\n\t\tif (!parent.startsWith(\".\")) continue;\n\t\tconst target = resolve(dir, parent);\n\t\tconst found = tsconfigPaths(\n\t\t\ttarget.endsWith(\".json\") ? target : `${target}.json`,\n\t\t\tseen,\n\t\t);\n\t\tif (found) return baseUrl ? { ...found, base: baseUrl } : found;\n\t}\n\treturn undefined;\n}\n\nfunction detectAliases(root: string, pkg: Json | undefined): Alias[] {\n\tconst aliases: Alias[] = [];\n\tconst tsconfig = [\"tsconfig.json\", \"jsconfig.json\"]\n\t\t.map((name) => join(root, name))\n\t\t.find((file) => existsSync(file));\n\tconst ts = tsconfig ? tsconfigPaths(tsconfig) : undefined;\n\tfor (const [key, targets] of Object.entries(ts?.paths ?? {})) {\n\t\tconst target = Array.isArray(targets) ? targets[0] : undefined;\n\t\tif (!key.endsWith(\"/*\") || typeof target !== \"string\" || !target.endsWith(\"/*\"))\n\t\t\tcontinue;\n\t\taliases.push({\n\t\t\tprefix: key.slice(0, -1),\n\t\t\tdir: resolve(ts?.base ?? root, target.slice(0, -2)),\n\t\t\twithExtension: false,\n\t\t});\n\t}\n\tconst imports = isRecord(pkg?.imports) ? pkg.imports : {};\n\tfor (const [key, target] of Object.entries(imports)) {\n\t\tif (!key.endsWith(\"/*\") || typeof target !== \"string\" || !target.endsWith(\"/*\"))\n\t\t\tcontinue;\n\t\taliases.push({\n\t\t\tprefix: key.slice(0, -1),\n\t\t\tdir: resolve(root, target.slice(0, -2)),\n\t\t\twithExtension: true,\n\t\t});\n\t}\n\treturn aliases;\n}\n\n// The installed version wins; the declared range covers an app whose install hasn't run yet.\nfunction kitMajor(root: string, versions: Record<string, string>): number {\n\tconst installed = readJson(\n\t\tjoin(root, \"node_modules\", \"@sveltejs\", \"kit\", \"package.json\"),\n\t);\n\tconst version = String(installed?.version ?? versions[\"@sveltejs/kit\"] ?? \"\");\n\tconst major = /(\\d+)/.exec(version)?.[1];\n\treturn major === undefined ? 3 : Number(major);\n}\n\n/** Detects one project directory; `stop` bounds the upward lockfile search (workspace root). */\nexport function detectProject(root: string, stop = root): Project {\n\tconst pkg = readJson(join(root, \"package.json\"));\n\tconst versions = dependencyVersions(pkg);\n\tconst dependencies = new Set(Object.keys(versions));\n\tconst config = readComponentsConfig(root);\n\tconst meta = detectMeta(dependencies);\n\tconst fromDeps = meta ? META_FRAMEWORK[meta] : undefined;\n\tconst framework = config?.framework ?? fromDeps;\n\treturn {\n\t\troot,\n\t\tname: typeof pkg?.name === \"string\" ? pkg.name : undefined,\n\t\tframework,\n\t\tframeworkSource: config?.framework\n\t\t\t? \"components.json\"\n\t\t\t: fromDeps\n\t\t\t\t? \"dependencies\"\n\t\t\t\t: undefined,\n\t\tmeta,\n\t\t...detectPm(root, pkg, stop),\n\t\tconfig,\n\t\tdependencies,\n\t\taliases: detectAliases(root, pkg),\n\t\tdollarLib: meta === \"sveltekit\" && kitMajor(root, versions) < 3,\n\t};\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join, relative, resolve } from \"node:path\";\nimport { detectProject, type Project } from \"./detect.ts\";\nimport { ancestors, isRecord, readJson, toPosix } from \"./fs.ts\";\n\nexport interface Workspace {\n\treadonly root: string;\n\t/** Package globs from pnpm-workspace.yaml or package.json `workspaces`; empty for a single app. */\n\treadonly patterns: readonly string[];\n}\n\nexport interface Target extends Project {\n\t/** Path from the workspace root, `.` for the root itself. */\n\treadonly path: string;\n}\n\nasync function pnpmPatterns(file: string): Promise<string[]> {\n\tconst { parse } = await import(\"yaml\");\n\tconst doc: unknown = parse(readFileSync(file, \"utf8\"));\n\tconst packages = isRecord(doc) ? doc.packages : undefined;\n\treturn Array.isArray(packages) ? packages.filter((p) => typeof p === \"string\") : [];\n}\n\nfunction npmPatterns(workspaces: unknown): string[] | undefined {\n\tconst list = isRecord(workspaces) ? workspaces.packages : workspaces;\n\treturn Array.isArray(list) ? list.filter((p) => typeof p === \"string\") : undefined;\n}\n\nasync function findRoot(\n\tcwd: string,\n): Promise<{ workspace: Workspace; nearest?: string }> {\n\tlet nearest: string | undefined;\n\tfor (const dir of ancestors(resolve(cwd))) {\n\t\tconst pnpm = join(dir, \"pnpm-workspace.yaml\");\n\t\tif (existsSync(pnpm)) {\n\t\t\treturn { workspace: { root: dir, patterns: await pnpmPatterns(pnpm) }, nearest };\n\t\t}\n\t\tconst pkg = readJson(join(dir, \"package.json\"));\n\t\tconst patterns = npmPatterns(pkg?.workspaces);\n\t\tif (patterns) return { workspace: { root: dir, patterns }, nearest };\n\t\tif (pkg && !nearest) nearest = dir;\n\t}\n\treturn { workspace: { root: nearest ?? resolve(cwd), patterns: [] } };\n}\n\n/**\n * The workspace containing `cwd`. A package inside a workspace folder that its patterns\n * don't list (a scratch app, an example) is treated as its own single-app workspace.\n */\nexport async function findWorkspace(cwd: string): Promise<Workspace> {\n\tconst { workspace, nearest } = await findRoot(cwd);\n\tif (!nearest || nearest === workspace.root) return workspace;\n\tconst members = await packageDirs(workspace);\n\treturn members.includes(nearest) ? workspace : { root: nearest, patterns: [] };\n}\n\nasync function packageDirs(workspace: Workspace): Promise<string[]> {\n\tif (!workspace.patterns.length) return [workspace.root];\n\tconst { glob } = await import(\"tinyglobby\");\n\tconst include = workspace.patterns.filter((p) => !p.startsWith(\"!\"));\n\tconst ignore = workspace.patterns\n\t\t.filter((p) => p.startsWith(\"!\"))\n\t\t.map((p) => p.slice(1));\n\tconst manifests = await glob(\n\t\tinclude.map((p) => `${p.replace(/\\/$/, \"\")}/package.json`),\n\t\t{ cwd: workspace.root, ignore: [...ignore, \"**/node_modules/**\"], absolute: true },\n\t);\n\tconst dirs = manifests.map((file) => resolve(file, \"..\"));\n\treturn [workspace.root, ...dirs.sort()];\n}\n\n/** Every package that has a components.json or a React/Svelte dependency. */\nexport async function discoverTargets(workspace: Workspace): Promise<Target[]> {\n\tconst dirs = await packageDirs(workspace);\n\tconst monorepo = workspace.patterns.length > 0;\n\treturn (\n\t\tdirs\n\t\t\t.map((dir) => ({\n\t\t\t\t...detectProject(dir, workspace.root),\n\t\t\t\tpath: toPosix(relative(workspace.root, dir)) || \".\",\n\t\t\t}))\n\t\t\t.filter((t) => t.framework !== undefined)\n\t\t\t// A monorepo root often carries react as a tooling devDependency; only its config counts.\n\t\t\t.filter((t) => !(monorepo && t.path === \".\" && !t.config))\n\t);\n}\n\n/** The deepest target containing `cwd`, so running inside a package picks that package. */\nexport function targetAt(targets: readonly Target[], cwd: string): Target | undefined {\n\tconst here = resolve(cwd);\n\treturn targets\n\t\t.filter((t) => {\n\t\t\tconst rest = relative(t.root, here);\n\t\t\treturn !rest.startsWith(\"..\") && !isAbsolute(rest);\n\t\t})\n\t\t.sort((a, b) => b.root.length - a.root.length)[0];\n}\n\n/** Matches `--target` against package name or workspace-relative path. */\nexport function matchTarget(\n\ttargets: readonly Target[],\n\tquery: string,\n): Target | undefined {\n\tconst path = toPosix(query).replace(/^\\.\\//, \"\").replace(/\\/$/, \"\") || \".\";\n\treturn targets.find((t) => t.name === query || t.path === path);\n}\n"],"mappings":"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"}
@@ -0,0 +1,226 @@
1
+ import { o as ancestors } from "./targets-Bpv2h7C4.js";
2
+ import { a as object, n as array, r as boolean, s as string } from "./schemas-DwMX1h2B.js";
3
+ import { c as sha256, o as relativeTo, r as STATE_DIR } from "./shared-BJaaV-dl.js";
4
+ import { existsSync } from "node:fs";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { mkdir, readFile, readdir, rm, rmdir, writeFile } from "node:fs/promises";
7
+ //#region src/write/tx.ts
8
+ const SideSchema = object({
9
+ exists: boolean(),
10
+ hash: string().optional()
11
+ });
12
+ const JournalSchema = object({
13
+ id: string(),
14
+ command: string(),
15
+ createdAt: string(),
16
+ ops: array(object({
17
+ path: string(),
18
+ before: SideSchema.extend({ snapshot: string().optional() }),
19
+ after: SideSchema
20
+ })),
21
+ /** Root-relative dirs this transaction created, removed again on revert if empty. */
22
+ createdDirs: array(string()),
23
+ revertOf: string().optional(),
24
+ revertedBy: string().optional()
25
+ });
26
+ const historyDir = (root) => join(root, STATE_DIR, "history");
27
+ async function readText(path) {
28
+ try {
29
+ return await readFile(path, "utf8");
30
+ } catch {
31
+ return;
32
+ }
33
+ }
34
+ const stamp = (ms) => new Date(ms).toISOString().replace(/[-:T.Z]/g, "");
35
+ async function newId(root) {
36
+ let ids = [];
37
+ try {
38
+ ids = await readdir(historyDir(root));
39
+ } catch {}
40
+ const newest = ids.sort().at(-1);
41
+ let ms = Date.now();
42
+ while (newest && stamp(ms) <= newest) ms++;
43
+ return stamp(ms);
44
+ }
45
+ async function ensureStateDir(root) {
46
+ const ignore = join(root, STATE_DIR, ".gitignore");
47
+ if (existsSync(ignore)) return;
48
+ await mkdir(dirname(ignore), { recursive: true });
49
+ await writeFile(ignore, "# Undo snapshots stay local; lock.json is committed.\nhistory/\n");
50
+ }
51
+ function missingDirs(root, file) {
52
+ const out = [];
53
+ for (const dir of ancestors(dirname(file))) {
54
+ if (existsSync(dir) || resolve(dir) === resolve(root)) break;
55
+ out.push(dir);
56
+ }
57
+ return out;
58
+ }
59
+ async function apply(op) {
60
+ if (op.content === null) await rm(op.path, { force: true });
61
+ else {
62
+ await mkdir(dirname(op.path), { recursive: true });
63
+ await writeFile(op.path, op.content);
64
+ }
65
+ }
66
+ /**
67
+ * Snapshots every target, applies all ops, and journals them so `revert` can undo. A failure
68
+ * midway restores what was already written.
69
+ */
70
+ async function commit(root, command, ops, extra = {}) {
71
+ await ensureStateDir(root);
72
+ const id = await newId(root);
73
+ const dir = join(historyDir(root), id);
74
+ await mkdir(join(dir, "files"), { recursive: true });
75
+ const createdDirs = /* @__PURE__ */ new Set();
76
+ const entries = [];
77
+ const before = [];
78
+ for (const [index, op] of ops.entries()) {
79
+ const previous = await readText(op.path);
80
+ before.push(previous);
81
+ for (const created of missingDirs(root, op.path)) createdDirs.add(relativeTo(root, created));
82
+ let snapshot;
83
+ if (previous !== void 0) {
84
+ snapshot = `files/${index}`;
85
+ await writeFile(join(dir, snapshot), previous);
86
+ }
87
+ entries.push({
88
+ path: relativeTo(root, op.path),
89
+ before: {
90
+ exists: previous !== void 0,
91
+ hash: previous === void 0 ? void 0 : sha256(previous),
92
+ snapshot
93
+ },
94
+ after: {
95
+ exists: op.content !== null,
96
+ hash: op.content === null ? void 0 : sha256(op.content)
97
+ }
98
+ });
99
+ }
100
+ const journal = {
101
+ id,
102
+ command,
103
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
104
+ ops: entries,
105
+ createdDirs: [...createdDirs].sort((a, b) => b.length - a.length),
106
+ ...extra
107
+ };
108
+ const done = [];
109
+ try {
110
+ for (const [index, op] of ops.entries()) {
111
+ await apply(op);
112
+ done.push(index);
113
+ }
114
+ } catch (error) {
115
+ for (const index of done.reverse()) {
116
+ const op = ops[index];
117
+ if (op) await apply({
118
+ path: op.path,
119
+ content: before[index] ?? null
120
+ });
121
+ }
122
+ await removeEmptyDirs(root, journal.createdDirs);
123
+ await rm(dir, {
124
+ recursive: true,
125
+ force: true
126
+ });
127
+ throw error;
128
+ }
129
+ await writeFile(join(dir, "journal.json"), `${JSON.stringify(journal, null, " ")}\n`);
130
+ await prune(root);
131
+ return journal;
132
+ }
133
+ async function removeEmptyDirs(root, dirs) {
134
+ for (const dir of dirs) try {
135
+ await rmdir(join(root, dir));
136
+ } catch {}
137
+ }
138
+ async function listJournals(root) {
139
+ let ids;
140
+ try {
141
+ ids = await readdir(historyDir(root));
142
+ } catch {
143
+ return [];
144
+ }
145
+ return (await Promise.all(ids.map((id) => readJournal(root, id)))).filter((j) => j !== void 0).sort((a, b) => b.id.localeCompare(a.id));
146
+ }
147
+ async function readJournal(root, id) {
148
+ const text = await readText(join(historyDir(root), id, "journal.json"));
149
+ if (text === void 0) return void 0;
150
+ const parsed = JournalSchema.safeParse(JSON.parse(text));
151
+ return parsed.success ? parsed.data : void 0;
152
+ }
153
+ async function prune(root) {
154
+ const journals = await listJournals(root);
155
+ for (const old of journals.slice(20)) await rm(join(historyDir(root), old.id), {
156
+ recursive: true,
157
+ force: true
158
+ });
159
+ }
160
+ /** Files changed after the journal wrote them; reverting would discard those edits. */
161
+ async function conflicts(root, journal) {
162
+ const found = [];
163
+ for (const op of journal.ops) {
164
+ const current = await readText(join(root, op.path));
165
+ if (op.after.exists && current === void 0) found.push({
166
+ path: op.path,
167
+ reason: "deleted"
168
+ });
169
+ else if (!op.after.exists && current !== void 0) found.push({
170
+ path: op.path,
171
+ reason: "recreated"
172
+ });
173
+ else if (current !== void 0 && sha256(current) !== op.after.hash) found.push({
174
+ path: op.path,
175
+ reason: "edited"
176
+ });
177
+ }
178
+ return found;
179
+ }
180
+ /** Re-hashes files changed after commit by a tool we ran (the package manager on package.json). */
181
+ async function amend(root, journal, paths) {
182
+ const ops = await Promise.all(journal.ops.map(async (op) => {
183
+ if (!paths.includes(op.path)) return op;
184
+ const current = await readText(join(root, op.path));
185
+ return {
186
+ ...op,
187
+ after: {
188
+ exists: current !== void 0,
189
+ hash: current === void 0 ? void 0 : sha256(current)
190
+ }
191
+ };
192
+ }));
193
+ const next = {
194
+ ...journal,
195
+ ops
196
+ };
197
+ const file = join(historyDir(root), journal.id, "journal.json");
198
+ await writeFile(file, `${JSON.stringify(next, null, " ")}\n`);
199
+ return next;
200
+ }
201
+ /** Restores every file the journal touched, as a new journal that can itself be reverted. */
202
+ async function revert(root, journal) {
203
+ const dir = join(historyDir(root), journal.id);
204
+ const ops = [];
205
+ for (const op of [...journal.ops].reverse()) {
206
+ const content = op.before.snapshot ? await readFile(join(dir, op.before.snapshot), "utf8") : null;
207
+ ops.push({
208
+ path: join(root, op.path),
209
+ content
210
+ });
211
+ }
212
+ const result = await commit(root, `revert ${journal.id}`, ops, { revertOf: journal.id });
213
+ await removeEmptyDirs(root, journal.createdDirs);
214
+ if (existsSync(dir)) {
215
+ const marked = {
216
+ ...journal,
217
+ revertedBy: result.id
218
+ };
219
+ await writeFile(join(dir, "journal.json"), `${JSON.stringify(marked, null, " ")}\n`);
220
+ }
221
+ return result;
222
+ }
223
+ //#endregion
224
+ export { readJournal as a, listJournals as i, commit as n, revert as o, conflicts as r, amend as t };
225
+
226
+ //# sourceMappingURL=tx-DBnjY8eR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-DBnjY8eR.js","names":["z.object","z.boolean","z.string","z.array"],"sources":["../src/write/tx.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { mkdir, readdir, readFile, rm, rmdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { ancestors } from \"../project/fs.ts\";\nimport { relativeTo, STATE_DIR, sha256 } from \"./lock.ts\";\n\n/** One file to write, or delete when `content` is null. */\nexport interface FileOp {\n\treadonly path: string;\n\treadonly content: string | null;\n}\n\nconst SideSchema = z.object({ exists: z.boolean(), hash: z.string().optional() });\n\nconst JournalSchema = z.object({\n\tid: z.string(),\n\tcommand: z.string(),\n\tcreatedAt: z.string(),\n\tops: z.array(\n\t\tz.object({\n\t\t\tpath: z.string(),\n\t\t\tbefore: SideSchema.extend({ snapshot: z.string().optional() }),\n\t\t\tafter: SideSchema,\n\t\t}),\n\t),\n\t/** Root-relative dirs this transaction created, removed again on revert if empty. */\n\tcreatedDirs: z.array(z.string()),\n\trevertOf: z.string().optional(),\n\trevertedBy: z.string().optional(),\n});\n\nexport type Journal = z.infer<typeof JournalSchema>;\n\nexport const KEEP = 20;\nconst historyDir = (root: string) => join(root, STATE_DIR, \"history\");\n\nasync function readText(path: string): Promise<string | undefined> {\n\ttry {\n\t\treturn await readFile(path, \"utf8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nconst stamp = (ms: number) => new Date(ms).toISOString().replace(/[-:T.Z]/g, \"\");\n\n// Millisecond stamps, bumped past the newest journal so ids always sort in commit order.\nasync function newId(root: string): Promise<string> {\n\tlet ids: string[] = [];\n\ttry {\n\t\tids = await readdir(historyDir(root));\n\t} catch {}\n\tconst newest = ids.sort().at(-1);\n\tlet ms = Date.now();\n\twhile (newest && stamp(ms) <= newest) ms++;\n\treturn stamp(ms);\n}\n\nasync function ensureStateDir(root: string): Promise<void> {\n\tconst ignore = join(root, STATE_DIR, \".gitignore\");\n\tif (existsSync(ignore)) return;\n\tawait mkdir(dirname(ignore), { recursive: true });\n\tawait writeFile(\n\t\tignore,\n\t\t\"# Undo snapshots stay local; lock.json is committed.\\nhistory/\\n\",\n\t);\n}\n\nfunction missingDirs(root: string, file: string): string[] {\n\tconst out: string[] = [];\n\tfor (const dir of ancestors(dirname(file))) {\n\t\tif (existsSync(dir) || resolve(dir) === resolve(root)) break;\n\t\tout.push(dir);\n\t}\n\treturn out;\n}\n\nasync function apply(op: FileOp): Promise<void> {\n\tif (op.content === null) await rm(op.path, { force: true });\n\telse {\n\t\tawait mkdir(dirname(op.path), { recursive: true });\n\t\tawait writeFile(op.path, op.content);\n\t}\n}\n\n/**\n * Snapshots every target, applies all ops, and journals them so `revert` can undo. A failure\n * midway restores what was already written.\n */\nexport async function commit(\n\troot: string,\n\tcommand: string,\n\tops: readonly FileOp[],\n\textra: Pick<Journal, \"revertOf\"> = {},\n): Promise<Journal> {\n\tawait ensureStateDir(root);\n\tconst id = await newId(root);\n\tconst dir = join(historyDir(root), id);\n\tawait mkdir(join(dir, \"files\"), { recursive: true });\n\n\tconst createdDirs = new Set<string>();\n\tconst entries: Journal[\"ops\"] = [];\n\tconst before: Array<string | undefined> = [];\n\tfor (const [index, op] of ops.entries()) {\n\t\tconst previous = await readText(op.path);\n\t\tbefore.push(previous);\n\t\tfor (const created of missingDirs(root, op.path)) {\n\t\t\tcreatedDirs.add(relativeTo(root, created));\n\t\t}\n\t\tlet snapshot: string | undefined;\n\t\tif (previous !== undefined) {\n\t\t\tsnapshot = `files/${index}`;\n\t\t\tawait writeFile(join(dir, snapshot), previous);\n\t\t}\n\t\tentries.push({\n\t\t\tpath: relativeTo(root, op.path),\n\t\t\tbefore: {\n\t\t\t\texists: previous !== undefined,\n\t\t\t\thash: previous === undefined ? undefined : sha256(previous),\n\t\t\t\tsnapshot,\n\t\t\t},\n\t\t\tafter: {\n\t\t\t\texists: op.content !== null,\n\t\t\t\thash: op.content === null ? undefined : sha256(op.content),\n\t\t\t},\n\t\t});\n\t}\n\n\tconst journal: Journal = {\n\t\tid,\n\t\tcommand,\n\t\tcreatedAt: new Date().toISOString(),\n\t\tops: entries,\n\t\tcreatedDirs: [...createdDirs].sort((a, b) => b.length - a.length),\n\t\t...extra,\n\t};\n\n\tconst done: number[] = [];\n\ttry {\n\t\tfor (const [index, op] of ops.entries()) {\n\t\t\tawait apply(op);\n\t\t\tdone.push(index);\n\t\t}\n\t} catch (error) {\n\t\tfor (const index of done.reverse()) {\n\t\t\tconst op = ops[index];\n\t\t\tif (op) await apply({ path: op.path, content: before[index] ?? null });\n\t\t}\n\t\tawait removeEmptyDirs(root, journal.createdDirs);\n\t\tawait rm(dir, { recursive: true, force: true });\n\t\tthrow error;\n\t}\n\n\tawait writeFile(join(dir, \"journal.json\"), `${JSON.stringify(journal, null, \"\\t\")}\\n`);\n\tawait prune(root);\n\treturn journal;\n}\n\nasync function removeEmptyDirs(root: string, dirs: readonly string[]): Promise<void> {\n\tfor (const dir of dirs) {\n\t\ttry {\n\t\t\tawait rmdir(join(root, dir));\n\t\t} catch {}\n\t}\n}\n\nexport async function listJournals(root: string): Promise<Journal[]> {\n\tlet ids: string[];\n\ttry {\n\t\tids = await readdir(historyDir(root));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst journals = await Promise.all(ids.map((id) => readJournal(root, id)));\n\treturn journals\n\t\t.filter((j): j is Journal => j !== undefined)\n\t\t.sort((a, b) => b.id.localeCompare(a.id));\n}\n\nexport async function readJournal(\n\troot: string,\n\tid: string,\n): Promise<Journal | undefined> {\n\tconst text = await readText(join(historyDir(root), id, \"journal.json\"));\n\tif (text === undefined) return undefined;\n\tconst parsed = JournalSchema.safeParse(JSON.parse(text));\n\treturn parsed.success ? parsed.data : undefined;\n}\n\nasync function prune(root: string): Promise<void> {\n\tconst journals = await listJournals(root);\n\tfor (const old of journals.slice(KEEP)) {\n\t\tawait rm(join(historyDir(root), old.id), { recursive: true, force: true });\n\t}\n}\n\nexport interface Conflict {\n\treadonly path: string;\n\treadonly reason: \"edited\" | \"deleted\" | \"recreated\";\n}\n\n/** Files changed after the journal wrote them; reverting would discard those edits. */\nexport async function conflicts(root: string, journal: Journal): Promise<Conflict[]> {\n\tconst found: Conflict[] = [];\n\tfor (const op of journal.ops) {\n\t\tconst current = await readText(join(root, op.path));\n\t\tif (op.after.exists && current === undefined)\n\t\t\tfound.push({ path: op.path, reason: \"deleted\" });\n\t\telse if (!op.after.exists && current !== undefined) {\n\t\t\tfound.push({ path: op.path, reason: \"recreated\" });\n\t\t} else if (current !== undefined && sha256(current) !== op.after.hash) {\n\t\t\tfound.push({ path: op.path, reason: \"edited\" });\n\t\t}\n\t}\n\treturn found;\n}\n\n/** Re-hashes files changed after commit by a tool we ran (the package manager on package.json). */\nexport async function amend(root: string, journal: Journal, paths: readonly string[]) {\n\tconst ops = await Promise.all(\n\t\tjournal.ops.map(async (op) => {\n\t\t\tif (!paths.includes(op.path)) return op;\n\t\t\tconst current = await readText(join(root, op.path));\n\t\t\treturn {\n\t\t\t\t...op,\n\t\t\t\tafter: {\n\t\t\t\t\texists: current !== undefined,\n\t\t\t\t\thash: current === undefined ? undefined : sha256(current),\n\t\t\t\t},\n\t\t\t};\n\t\t}),\n\t);\n\tconst next: Journal = { ...journal, ops };\n\tconst file = join(historyDir(root), journal.id, \"journal.json\");\n\tawait writeFile(file, `${JSON.stringify(next, null, \"\\t\")}\\n`);\n\treturn next;\n}\n\n/** Restores every file the journal touched, as a new journal that can itself be reverted. */\nexport async function revert(root: string, journal: Journal): Promise<Journal> {\n\tconst dir = join(historyDir(root), journal.id);\n\tconst ops: FileOp[] = [];\n\tfor (const op of [...journal.ops].reverse()) {\n\t\tconst content = op.before.snapshot\n\t\t\t? await readFile(join(dir, op.before.snapshot), \"utf8\")\n\t\t\t: null;\n\t\tops.push({ path: join(root, op.path), content });\n\t}\n\tconst result = await commit(root, `revert ${journal.id}`, ops, {\n\t\trevertOf: journal.id,\n\t});\n\tawait removeEmptyDirs(root, journal.createdDirs);\n\t// The commit may have pruned this journal if it was the oldest one kept.\n\tif (existsSync(dir)) {\n\t\tconst marked: Journal = { ...journal, revertedBy: result.id };\n\t\tawait writeFile(join(dir, \"journal.json\"), `${JSON.stringify(marked, null, \"\\t\")}\\n`);\n\t}\n\treturn result;\n}\n"],"mappings":"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"}