lattice-ui 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +45 -0
  3. package/dist/cli.d.ts +1 -0
  4. package/dist/cli.js +426 -0
  5. package/dist/commands/add.d.ts +3 -0
  6. package/dist/commands/add.js +156 -0
  7. package/dist/commands/create.d.ts +23 -0
  8. package/dist/commands/create.js +351 -0
  9. package/dist/commands/doctor.d.ts +2 -0
  10. package/dist/commands/doctor.js +164 -0
  11. package/dist/commands/init.d.ts +21 -0
  12. package/dist/commands/init.js +547 -0
  13. package/dist/commands/remove.d.ts +3 -0
  14. package/dist/commands/remove.js +113 -0
  15. package/dist/commands/selection.d.ts +6 -0
  16. package/dist/commands/selection.js +27 -0
  17. package/dist/commands/upgrade.d.ts +3 -0
  18. package/dist/commands/upgrade.js +150 -0
  19. package/dist/core/errors.d.ts +21 -0
  20. package/dist/core/errors.js +52 -0
  21. package/dist/core/fs/copy.d.ts +13 -0
  22. package/dist/core/fs/copy.js +129 -0
  23. package/dist/core/fs/json.d.ts +3 -0
  24. package/dist/core/fs/json.js +163 -0
  25. package/dist/core/fs/patch.d.ts +16 -0
  26. package/dist/core/fs/patch.js +89 -0
  27. package/dist/core/logger.d.ts +27 -0
  28. package/dist/core/logger.js +166 -0
  29. package/dist/core/npm/latest.d.ts +1 -0
  30. package/dist/core/npm/latest.js +40 -0
  31. package/dist/core/output.d.ts +8 -0
  32. package/dist/core/output.js +20 -0
  33. package/dist/core/pm/detect.d.ts +18 -0
  34. package/dist/core/pm/detect.js +147 -0
  35. package/dist/core/pm/npm.d.ts +2 -0
  36. package/dist/core/pm/npm.js +48 -0
  37. package/dist/core/pm/pnpm.d.ts +2 -0
  38. package/dist/core/pm/pnpm.js +48 -0
  39. package/dist/core/pm/types.d.ts +8 -0
  40. package/dist/core/pm/types.js +2 -0
  41. package/dist/core/pm/yarn.d.ts +2 -0
  42. package/dist/core/pm/yarn.js +48 -0
  43. package/dist/core/project/findRoot.d.ts +1 -0
  44. package/dist/core/project/findRoot.js +60 -0
  45. package/dist/core/project/readPackageJson.d.ts +13 -0
  46. package/dist/core/project/readPackageJson.js +41 -0
  47. package/dist/core/project/writePackageJson.d.ts +2 -0
  48. package/dist/core/project/writePackageJson.js +41 -0
  49. package/dist/core/prompt.d.ts +23 -0
  50. package/dist/core/prompt.js +217 -0
  51. package/dist/core/registry/load.d.ts +3 -0
  52. package/dist/core/registry/load.js +59 -0
  53. package/dist/core/registry/schema.d.ts +18 -0
  54. package/dist/core/registry/schema.js +87 -0
  55. package/dist/ctx.d.ts +27 -0
  56. package/dist/ctx.js +75 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.js +21 -0
  59. package/package.json +27 -0
  60. package/registry/components.json +118 -0
  61. package/registry/presets.json +6 -0
  62. package/templates/init/default.project.json.template +67 -0
  63. package/templates/init/package.json +22 -0
  64. package/templates/init/src/client/App.tsx +21 -0
  65. package/templates/init/src/client/main.client.tsx +26 -0
  66. package/templates/init/src/server/main.server.ts +3 -0
  67. package/templates/init/src/shared/constants.ts +1 -0
  68. package/templates/init/tsconfig.json +27 -0
  69. package/templates/init-lint/.prettierrc +7 -0
  70. package/templates/init-lint/eslint.config.mjs +51 -0
  71. package/templates/init-lint/package.json +19 -0
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveComponentSelection = resolveComponentSelection;
4
+ const errors_1 = require("../core/errors");
5
+ function resolveComponentSelection(ctx, input) {
6
+ const selected = new Set();
7
+ for (const name of input.names) {
8
+ if (!ctx.registry.packages[name]) {
9
+ throw (0, errors_1.usageError)(`Unknown component: ${name}`);
10
+ }
11
+ selected.add(name);
12
+ }
13
+ for (const preset of input.presets) {
14
+ const presetMembers = ctx.registry.presets[preset];
15
+ if (!presetMembers) {
16
+ throw (0, errors_1.usageError)(`Unknown preset: ${preset}`);
17
+ }
18
+ for (const member of presetMembers) {
19
+ selected.add(member);
20
+ }
21
+ }
22
+ const sorted = [...selected].sort((left, right) => left.localeCompare(right));
23
+ if (sorted.length === 0) {
24
+ throw (0, errors_1.usageError)("No components selected. Provide component names or --preset.");
25
+ }
26
+ return sorted;
27
+ }
@@ -0,0 +1,3 @@
1
+ import type { CliContext } from "../ctx";
2
+ import { type SelectionInput } from "./selection";
3
+ export declare function runUpgradeCommand(ctx: CliContext, input: SelectionInput): Promise<void>;
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runUpgradeCommand = runUpgradeCommand;
4
+ const errors_1 = require("../core/errors");
5
+ const output_1 = require("../core/output");
6
+ const readPackageJson_1 = require("../core/project/readPackageJson");
7
+ const prompt_1 = require("../core/prompt");
8
+ const selection_1 = require("./selection");
9
+ function getSelectedRegistryPackages(ctx, input) {
10
+ const components = (0, selection_1.resolveComponentSelection)(ctx, input);
11
+ return components.map((component) => ctx.registry.packages[component].npm);
12
+ }
13
+ function normalizeList(values) {
14
+ return [...new Set(values)].sort((left, right) => left.localeCompare(right));
15
+ }
16
+ async function runUpgradeCommand(ctx, input) {
17
+ const packageJson = await (0, readPackageJson_1.readPackageJson)(ctx.projectRoot);
18
+ const dependencies = packageJson.dependencies ?? {};
19
+ const devDependencies = packageJson.devDependencies ?? {};
20
+ const installedLattice = normalizeList([...Object.keys(dependencies), ...Object.keys(devDependencies)].filter((name) => name.startsWith("@lattice-ui/")));
21
+ let targets;
22
+ let missingRequested = [];
23
+ if (input.names.length === 0 && input.presets.length === 0) {
24
+ if (ctx.options.yes) {
25
+ targets = installedLattice;
26
+ }
27
+ else {
28
+ targets = await (0, prompt_1.promptMultiSelect)({ yes: ctx.options.yes }, "Select installed @lattice-ui/* packages to upgrade", installedLattice.map((name) => ({ label: name, value: name })), {
29
+ allowEmpty: false,
30
+ defaultIndices: installedLattice.map((_, index) => index),
31
+ });
32
+ }
33
+ }
34
+ else {
35
+ const requestedRegistryPackages = getSelectedRegistryPackages(ctx, input);
36
+ const installedSet = new Set(installedLattice);
37
+ targets = normalizeList(requestedRegistryPackages.filter((pkg) => installedSet.has(pkg)));
38
+ missingRequested = normalizeList(requestedRegistryPackages.filter((pkg) => !installedSet.has(pkg)));
39
+ }
40
+ const localLattice = (0, output_1.resolveLocalLatticeCommand)(ctx.pmName);
41
+ ctx.logger.section("Selecting");
42
+ ctx.logger.kv("Project", ctx.projectRoot);
43
+ let dependencySpecs = [];
44
+ let devDependencySpecs = [];
45
+ if (targets.length > 0) {
46
+ dependencySpecs = normalizeList(targets.filter((pkg) => dependencies[pkg] !== undefined).map((pkg) => `${pkg}@latest`));
47
+ devDependencySpecs = normalizeList(targets
48
+ .filter((pkg) => dependencies[pkg] === undefined && devDependencies[pkg] !== undefined)
49
+ .map((pkg) => `${pkg}@latest`));
50
+ if (dependencySpecs.length === 0 && devDependencySpecs.length === 0) {
51
+ throw (0, errors_1.usageError)("No upgradable dependency targets were found.");
52
+ }
53
+ }
54
+ ctx.logger.section("Planning");
55
+ const selectedSummary = (0, output_1.summarizeItems)(targets);
56
+ ctx.logger.kv("Selected", String(selectedSummary.total));
57
+ if (selectedSummary.total > 0) {
58
+ ctx.logger.list(selectedSummary.visible);
59
+ if (selectedSummary.hidden > 0) {
60
+ ctx.logger.step(`...and ${selectedSummary.hidden} more`);
61
+ }
62
+ }
63
+ if (missingRequested.length > 0) {
64
+ const missingSummary = (0, output_1.summarizeItems)(missingRequested);
65
+ ctx.logger.kv("Missing requested", String(missingSummary.total));
66
+ ctx.logger.list(missingSummary.visible);
67
+ if (missingSummary.hidden > 0) {
68
+ ctx.logger.step(`...and ${missingSummary.hidden} more`);
69
+ }
70
+ }
71
+ const dependencySummary = (0, output_1.summarizeItems)(dependencySpecs);
72
+ const devDependencySummary = (0, output_1.summarizeItems)(devDependencySpecs);
73
+ ctx.logger.kv("Dependency upgrades", String(dependencySummary.total));
74
+ if (dependencySummary.total > 0) {
75
+ ctx.logger.list(dependencySummary.visible);
76
+ if (dependencySummary.hidden > 0) {
77
+ ctx.logger.step(`...and ${dependencySummary.hidden} more`);
78
+ }
79
+ }
80
+ ctx.logger.kv("Dev dependency upgrades", String(devDependencySummary.total));
81
+ if (devDependencySummary.total > 0) {
82
+ ctx.logger.list(devDependencySummary.visible);
83
+ if (devDependencySummary.hidden > 0) {
84
+ ctx.logger.step(`...and ${devDependencySummary.hidden} more`);
85
+ }
86
+ }
87
+ if (ctx.options.dryRun) {
88
+ ctx.logger.section("Dry Run");
89
+ if (dependencySpecs.length === 0 && devDependencySpecs.length === 0) {
90
+ ctx.logger.step("[dry-run] No install actions required.");
91
+ }
92
+ else {
93
+ if (dependencySpecs.length > 0) {
94
+ ctx.logger.step(`[dry-run] ${ctx.pmName} add ${dependencySpecs.join(" ")}`);
95
+ }
96
+ if (devDependencySpecs.length > 0) {
97
+ ctx.logger.step(`[dry-run] ${ctx.pmName} add -D ${devDependencySpecs.join(" ")}`);
98
+ }
99
+ }
100
+ ctx.logger.step("No files were changed.");
101
+ }
102
+ else {
103
+ ctx.logger.section("Applying");
104
+ if (dependencySpecs.length === 0 && devDependencySpecs.length === 0) {
105
+ ctx.logger.step("No installation required.");
106
+ }
107
+ else {
108
+ if (dependencySpecs.length > 0) {
109
+ ctx.logger.step(`${ctx.pmName} add ${dependencySpecs.join(" ")}`);
110
+ }
111
+ if (devDependencySpecs.length > 0) {
112
+ ctx.logger.step(`${ctx.pmName} add -D ${devDependencySpecs.join(" ")}`);
113
+ }
114
+ const confirmed = await ctx.logger.confirm(`Upgrade ${targets.length} package(s) in ${ctx.projectRoot}?`);
115
+ if (!confirmed) {
116
+ ctx.logger.section("Result");
117
+ ctx.logger.warn("Upgrade cancelled.");
118
+ ctx.logger.section("Next Steps");
119
+ ctx.logger.step(`${localLattice} doctor`);
120
+ return;
121
+ }
122
+ const spinner = ctx.logger.spinner("Upgrading packages...");
123
+ if (dependencySpecs.length > 0) {
124
+ await ctx.pm.add(false, dependencySpecs, ctx.projectRoot);
125
+ }
126
+ if (devDependencySpecs.length > 0) {
127
+ await ctx.pm.add(true, devDependencySpecs, ctx.projectRoot);
128
+ }
129
+ spinner.succeed(`Upgraded ${targets.length} package(s).`);
130
+ }
131
+ }
132
+ if (targets.length === 0) {
133
+ ctx.logger.section("Result");
134
+ ctx.logger.warn("No installed @lattice-ui/* package matched upgrade selection.");
135
+ ctx.logger.section("Next Steps");
136
+ ctx.logger.step(`${localLattice} doctor`);
137
+ return;
138
+ }
139
+ ctx.logger.section("Result");
140
+ if (dependencySpecs.length === 0 && devDependencySpecs.length === 0) {
141
+ ctx.logger.success("No package upgrades were needed.");
142
+ }
143
+ else {
144
+ ctx.logger.success("Upgrade completed.");
145
+ }
146
+ ctx.logger.kv("Dependency upgrades", String(dependencySpecs.length));
147
+ ctx.logger.kv("Dev dependency upgrades", String(devDependencySpecs.length));
148
+ ctx.logger.section("Next Steps");
149
+ ctx.logger.step(`${localLattice} doctor`);
150
+ }
@@ -0,0 +1,21 @@
1
+ export declare enum ExitCode {
2
+ Success = 0,
3
+ Unexpected = 1,
4
+ Usage = 2,
5
+ ProjectNotFound = 3,
6
+ RegistryInvalid = 4,
7
+ PackageManagerFailed = 5
8
+ }
9
+ export type CliErrorKind = "Usage" | "Validation" | "ProjectNotFound" | "RegistryInvalid" | "PackageManagerFailed" | "Unexpected";
10
+ export declare class CliError extends Error {
11
+ readonly kind: CliErrorKind;
12
+ readonly exitCode: ExitCode;
13
+ readonly cause?: unknown;
14
+ constructor(message: string, kind: CliErrorKind, exitCode: ExitCode, cause?: unknown);
15
+ }
16
+ export declare function usageError(message: string): CliError;
17
+ export declare function validationError(message: string): CliError;
18
+ export declare function projectNotFoundError(cwd: string): CliError;
19
+ export declare function registryInvalidError(message: string, cause?: unknown): CliError;
20
+ export declare function packageManagerFailedError(message: string, cause?: unknown): CliError;
21
+ export declare function toCliError(error: unknown): CliError;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CliError = exports.ExitCode = void 0;
4
+ exports.usageError = usageError;
5
+ exports.validationError = validationError;
6
+ exports.projectNotFoundError = projectNotFoundError;
7
+ exports.registryInvalidError = registryInvalidError;
8
+ exports.packageManagerFailedError = packageManagerFailedError;
9
+ exports.toCliError = toCliError;
10
+ var ExitCode;
11
+ (function (ExitCode) {
12
+ ExitCode[ExitCode["Success"] = 0] = "Success";
13
+ ExitCode[ExitCode["Unexpected"] = 1] = "Unexpected";
14
+ ExitCode[ExitCode["Usage"] = 2] = "Usage";
15
+ ExitCode[ExitCode["ProjectNotFound"] = 3] = "ProjectNotFound";
16
+ ExitCode[ExitCode["RegistryInvalid"] = 4] = "RegistryInvalid";
17
+ ExitCode[ExitCode["PackageManagerFailed"] = 5] = "PackageManagerFailed";
18
+ })(ExitCode || (exports.ExitCode = ExitCode = {}));
19
+ class CliError extends Error {
20
+ constructor(message, kind, exitCode, cause) {
21
+ super(message);
22
+ this.name = "CliError";
23
+ this.kind = kind;
24
+ this.exitCode = exitCode;
25
+ this.cause = cause;
26
+ }
27
+ }
28
+ exports.CliError = CliError;
29
+ function usageError(message) {
30
+ return new CliError(message, "Usage", ExitCode.Usage);
31
+ }
32
+ function validationError(message) {
33
+ return new CliError(message, "Validation", ExitCode.Usage);
34
+ }
35
+ function projectNotFoundError(cwd) {
36
+ return new CliError(`Could not find package.json from "${cwd}".`, "ProjectNotFound", ExitCode.ProjectNotFound);
37
+ }
38
+ function registryInvalidError(message, cause) {
39
+ return new CliError(message, "RegistryInvalid", ExitCode.RegistryInvalid, cause);
40
+ }
41
+ function packageManagerFailedError(message, cause) {
42
+ return new CliError(message, "PackageManagerFailed", ExitCode.PackageManagerFailed, cause);
43
+ }
44
+ function toCliError(error) {
45
+ if (error instanceof CliError) {
46
+ return error;
47
+ }
48
+ if (error instanceof Error) {
49
+ return new CliError(error.message, "Unexpected", ExitCode.Unexpected, error);
50
+ }
51
+ return new CliError("Unexpected unknown error.", "Unexpected", ExitCode.Unexpected, error);
52
+ }
@@ -0,0 +1,13 @@
1
+ import type { Logger } from "../logger";
2
+ export interface CopyTemplateOptions {
3
+ dryRun: boolean;
4
+ logger?: Logger;
5
+ replacements?: Record<string, string>;
6
+ shouldIncludeFile?: (relativePath: string) => boolean;
7
+ }
8
+ export interface CopyTemplateReport {
9
+ created: string[];
10
+ merged: string[];
11
+ skipped: string[];
12
+ }
13
+ export declare function copyTemplateSafe(templateDir: string, targetDir: string, options: CopyTemplateOptions): Promise<CopyTemplateReport>;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.copyTemplateSafe = copyTemplateSafe;
37
+ const node_fs_1 = require("node:fs");
38
+ const path = __importStar(require("node:path"));
39
+ const json_1 = require("./json");
40
+ const patch_1 = require("./patch");
41
+ function applyReplacements(content, replacements) {
42
+ if (!replacements) {
43
+ return content;
44
+ }
45
+ let next = content;
46
+ for (const [from, to] of Object.entries(replacements)) {
47
+ next = next.split(from).join(to);
48
+ }
49
+ return next;
50
+ }
51
+ function isJsonFile(filePath) {
52
+ return filePath.endsWith(".json");
53
+ }
54
+ function shouldPreserveJsonKeyOrder(relativePath) {
55
+ return relativePath === "package.json";
56
+ }
57
+ function resolveTargetRelativePath(relativePath) {
58
+ return relativePath.endsWith(".template") ? relativePath.slice(0, -".template".length) : relativePath;
59
+ }
60
+ async function pathExists(targetPath) {
61
+ try {
62
+ await node_fs_1.promises.access(targetPath);
63
+ return true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ async function walkFiles(root) {
70
+ const entries = await node_fs_1.promises.readdir(root, { withFileTypes: true });
71
+ const files = [];
72
+ for (const entry of entries) {
73
+ const absolutePath = path.join(root, entry.name);
74
+ if (entry.isDirectory()) {
75
+ files.push(...(await walkFiles(absolutePath)));
76
+ continue;
77
+ }
78
+ files.push(absolutePath);
79
+ }
80
+ return files;
81
+ }
82
+ async function copyTemplateSafe(templateDir, targetDir, options) {
83
+ const files = await walkFiles(templateDir);
84
+ const report = {
85
+ created: [],
86
+ merged: [],
87
+ skipped: [],
88
+ };
89
+ for (const templateFilePath of files) {
90
+ const relativePath = resolveTargetRelativePath(path.relative(templateDir, templateFilePath));
91
+ if (options.shouldIncludeFile && !options.shouldIncludeFile(relativePath)) {
92
+ continue;
93
+ }
94
+ const targetFilePath = path.join(targetDir, relativePath);
95
+ const exists = await pathExists(targetFilePath);
96
+ if (!exists) {
97
+ if (!options.dryRun) {
98
+ const raw = await node_fs_1.promises.readFile(templateFilePath, "utf8");
99
+ const content = applyReplacements(raw, options.replacements);
100
+ await node_fs_1.promises.mkdir(path.dirname(targetFilePath), { recursive: true });
101
+ await node_fs_1.promises.writeFile(targetFilePath, content, "utf8");
102
+ }
103
+ report.created.push(relativePath);
104
+ continue;
105
+ }
106
+ if (!isJsonFile(relativePath)) {
107
+ report.skipped.push(relativePath);
108
+ continue;
109
+ }
110
+ const templateRaw = await node_fs_1.promises.readFile(templateFilePath, "utf8");
111
+ const templateJson = (0, json_1.parseJsonText)(applyReplacements(templateRaw, options.replacements));
112
+ const currentJson = await (0, json_1.readJsonFile)(targetFilePath);
113
+ const mergedJson = (0, patch_1.mergeMissing)(templateJson, currentJson);
114
+ const mergedText = JSON.stringify(mergedJson);
115
+ const currentText = JSON.stringify(currentJson);
116
+ if (mergedText === currentText) {
117
+ report.skipped.push(relativePath);
118
+ continue;
119
+ }
120
+ if (!options.dryRun) {
121
+ await (0, json_1.writeJsonFile)(targetFilePath, mergedJson, !shouldPreserveJsonKeyOrder(relativePath));
122
+ }
123
+ report.merged.push(relativePath);
124
+ }
125
+ if (options.logger?.verbose) {
126
+ options.logger.debug(`Template copy report: created=${report.created.length}, merged=${report.merged.length}, skipped=${report.skipped.length}`);
127
+ }
128
+ return report;
129
+ }
@@ -0,0 +1,3 @@
1
+ export declare function parseJsonText<T = unknown>(content: string): T;
2
+ export declare function readJsonFile<T = unknown>(filePath: string): Promise<T>;
3
+ export declare function writeJsonFile(filePath: string, value: unknown, stable?: boolean): Promise<void>;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parseJsonText = parseJsonText;
37
+ exports.readJsonFile = readJsonFile;
38
+ exports.writeJsonFile = writeJsonFile;
39
+ const node_fs_1 = require("node:fs");
40
+ const path = __importStar(require("node:path"));
41
+ function isPlainObject(value) {
42
+ return typeof value === "object" && value !== null && !Array.isArray(value);
43
+ }
44
+ function sortValue(value) {
45
+ if (Array.isArray(value)) {
46
+ return value.map((item) => sortValue(item));
47
+ }
48
+ if (!isPlainObject(value)) {
49
+ return value;
50
+ }
51
+ const entries = Object.entries(value).sort(([left], [right]) => left.localeCompare(right));
52
+ return Object.fromEntries(entries.map(([key, item]) => [key, sortValue(item)]));
53
+ }
54
+ function stripJsonComments(content) {
55
+ let output = "";
56
+ let inString = false;
57
+ let escaped = false;
58
+ let inLineComment = false;
59
+ let inBlockComment = false;
60
+ for (let index = 0; index < content.length; index += 1) {
61
+ const current = content[index];
62
+ const next = content[index + 1];
63
+ if (inLineComment) {
64
+ if (current === "\n") {
65
+ inLineComment = false;
66
+ output += current;
67
+ }
68
+ continue;
69
+ }
70
+ if (inBlockComment) {
71
+ if (current === "*" && next === "/") {
72
+ inBlockComment = false;
73
+ index += 1;
74
+ }
75
+ continue;
76
+ }
77
+ if (inString) {
78
+ output += current;
79
+ if (escaped) {
80
+ escaped = false;
81
+ continue;
82
+ }
83
+ if (current === "\\") {
84
+ escaped = true;
85
+ continue;
86
+ }
87
+ if (current === '"') {
88
+ inString = false;
89
+ }
90
+ continue;
91
+ }
92
+ if (current === "/" && next === "/") {
93
+ inLineComment = true;
94
+ index += 1;
95
+ continue;
96
+ }
97
+ if (current === "/" && next === "*") {
98
+ inBlockComment = true;
99
+ index += 1;
100
+ continue;
101
+ }
102
+ output += current;
103
+ if (current === '"') {
104
+ inString = true;
105
+ }
106
+ }
107
+ return output;
108
+ }
109
+ function stripTrailingCommas(content) {
110
+ let output = "";
111
+ let inString = false;
112
+ let escaped = false;
113
+ for (let index = 0; index < content.length; index += 1) {
114
+ const current = content[index];
115
+ if (inString) {
116
+ output += current;
117
+ if (escaped) {
118
+ escaped = false;
119
+ continue;
120
+ }
121
+ if (current === "\\") {
122
+ escaped = true;
123
+ continue;
124
+ }
125
+ if (current === '"') {
126
+ inString = false;
127
+ }
128
+ continue;
129
+ }
130
+ if (current === '"') {
131
+ inString = true;
132
+ output += current;
133
+ continue;
134
+ }
135
+ if (current !== ",") {
136
+ output += current;
137
+ continue;
138
+ }
139
+ let lookahead = index + 1;
140
+ while (lookahead < content.length && /\s/.test(content[lookahead])) {
141
+ lookahead += 1;
142
+ }
143
+ if (content[lookahead] === "}" || content[lookahead] === "]") {
144
+ continue;
145
+ }
146
+ output += current;
147
+ }
148
+ return output;
149
+ }
150
+ function parseJsonText(content) {
151
+ const withoutComments = stripJsonComments(content);
152
+ const normalized = stripTrailingCommas(withoutComments);
153
+ return JSON.parse(normalized);
154
+ }
155
+ async function readJsonFile(filePath) {
156
+ const content = await node_fs_1.promises.readFile(filePath, "utf8");
157
+ return parseJsonText(content);
158
+ }
159
+ async function writeJsonFile(filePath, value, stable = true) {
160
+ const normalized = stable ? sortValue(value) : value;
161
+ await node_fs_1.promises.mkdir(path.dirname(filePath), { recursive: true });
162
+ await node_fs_1.promises.writeFile(filePath, `${JSON.stringify(normalized, null, 2)}\n`, "utf8");
163
+ }
@@ -0,0 +1,16 @@
1
+ export type DependencyField = "dependencies" | "devDependencies" | "peerDependencies" | "optionalDependencies";
2
+ export type PackageJsonLike = {
3
+ dependencies?: Record<string, string>;
4
+ devDependencies?: Record<string, string>;
5
+ peerDependencies?: Record<string, string>;
6
+ optionalDependencies?: Record<string, string>;
7
+ [key: string]: unknown;
8
+ };
9
+ export declare function toPackageName(spec: string): string;
10
+ export declare function getDependencyNames(manifest: PackageJsonLike): Set<string>;
11
+ export declare function upsertDependencySpecs(manifest: PackageJsonLike, field: DependencyField, specs: string[]): {
12
+ changed: boolean;
13
+ added: string[];
14
+ };
15
+ export declare function mergeStringArraysUnique(existing: string[] | undefined, incoming: string[]): string[];
16
+ export declare function mergeMissing(template: unknown, current: unknown): unknown;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPackageName = toPackageName;
4
+ exports.getDependencyNames = getDependencyNames;
5
+ exports.upsertDependencySpecs = upsertDependencySpecs;
6
+ exports.mergeStringArraysUnique = mergeStringArraysUnique;
7
+ exports.mergeMissing = mergeMissing;
8
+ function isPlainObject(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function isStringArray(value) {
12
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
13
+ }
14
+ function sortRecord(record) {
15
+ return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
16
+ }
17
+ function toPackageName(spec) {
18
+ if (spec.startsWith("@")) {
19
+ const slashIndex = spec.indexOf("/");
20
+ if (slashIndex < 0) {
21
+ return spec;
22
+ }
23
+ const versionIndex = spec.indexOf("@", slashIndex + 1);
24
+ return versionIndex < 0 ? spec : spec.slice(0, versionIndex);
25
+ }
26
+ const versionIndex = spec.indexOf("@");
27
+ return versionIndex < 0 ? spec : spec.slice(0, versionIndex);
28
+ }
29
+ function getDependencyNames(manifest) {
30
+ const names = new Set();
31
+ for (const field of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
32
+ const dependencies = manifest[field];
33
+ if (!dependencies || typeof dependencies !== "object") {
34
+ continue;
35
+ }
36
+ for (const name of Object.keys(dependencies)) {
37
+ names.add(name);
38
+ }
39
+ }
40
+ return names;
41
+ }
42
+ function upsertDependencySpecs(manifest, field, specs) {
43
+ const dependencyMap = { ...(manifest[field] ?? {}) };
44
+ let changed = false;
45
+ const added = [];
46
+ for (const spec of specs) {
47
+ const packageName = toPackageName(spec);
48
+ if (!packageName) {
49
+ continue;
50
+ }
51
+ if (dependencyMap[packageName] !== spec) {
52
+ dependencyMap[packageName] = spec;
53
+ changed = true;
54
+ }
55
+ if (!added.includes(packageName)) {
56
+ added.push(packageName);
57
+ }
58
+ }
59
+ manifest[field] = sortRecord(dependencyMap);
60
+ return { changed, added };
61
+ }
62
+ function mergeStringArraysUnique(existing, incoming) {
63
+ const out = [...(existing ?? [])];
64
+ for (const value of incoming) {
65
+ if (!out.includes(value)) {
66
+ out.push(value);
67
+ }
68
+ }
69
+ return out;
70
+ }
71
+ function mergeMissing(template, current) {
72
+ if (current === undefined) {
73
+ return template;
74
+ }
75
+ if (isStringArray(template) && isStringArray(current)) {
76
+ return mergeStringArraysUnique(current, template);
77
+ }
78
+ if (Array.isArray(template) || Array.isArray(current)) {
79
+ return current;
80
+ }
81
+ if (!isPlainObject(template) || !isPlainObject(current)) {
82
+ return current;
83
+ }
84
+ const out = { ...current };
85
+ for (const [key, templateValue] of Object.entries(template)) {
86
+ out[key] = mergeMissing(templateValue, current[key]);
87
+ }
88
+ return out;
89
+ }