@bobfrankston/npmglobalize 1.0.200 → 1.0.201

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -112,6 +112,7 @@ Other Options:
112
112
  -force Continue despite git errors
113
113
  -dry-run Preview what would happen
114
114
  -quiet Suppress npm warnings (default)
115
+ -noquiet Show npm warnings (without -verbose's extra detail)
115
116
  -verbose Show detailed output
116
117
  -conform Update .gitignore/.npmignore to best practices
117
118
  (noEmit projects: removes TS ignores from .npmignore)
@@ -268,6 +269,10 @@ function parseArgs(args) {
268
269
  case '-quiet':
269
270
  options.quiet = true;
270
271
  break;
272
+ case '-noquiet':
273
+ options.quiet = false;
274
+ options.explicitKeys.add('quiet');
275
+ break;
271
276
  case '-verbose':
272
277
  options.verbose = true;
273
278
  options.quiet = false;
package/lib.js CHANGED
@@ -5334,9 +5334,9 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
5334
5334
  if (configOptions.link)
5335
5335
  settings.push('--link');
5336
5336
  if (configOptions.npmVisibility)
5337
- settings.push(`--npm-visibility ${configOptions.npmVisibility}`);
5337
+ settings.push(`-npm ${configOptions.npmVisibility}`);
5338
5338
  if (configOptions.gitVisibility)
5339
- settings.push(`--git-visibility ${configOptions.gitVisibility}`);
5339
+ settings.push(`-git ${configOptions.gitVisibility}`);
5340
5340
  if (configOptions.conform)
5341
5341
  settings.push('--conform');
5342
5342
  if (configOptions.asis)
@@ -5358,15 +5358,15 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
5358
5358
  if (configOptions.dryRun)
5359
5359
  settings.push('--dry-run');
5360
5360
  if (configOptions.bump)
5361
- settings.push(`--bump ${configOptions.bump}`);
5361
+ settings.push(`-${configOptions.bump}`);
5362
5362
  if (configOptions.cleanup)
5363
5363
  settings.push('--cleanup');
5364
5364
  if (configOptions.wsl)
5365
5365
  settings.push('--wsl');
5366
5366
  if (configOptions.files === false)
5367
- settings.push('--no-files');
5367
+ settings.push('-nofiles');
5368
5368
  if (configOptions.quiet === false)
5369
- settings.push('--no-quiet');
5369
+ settings.push('-noquiet');
5370
5370
  if (configOptions.publishDeps === false)
5371
5371
  settings.push('--no-publish-deps');
5372
5372
  if (configOptions.forcePublish)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.200",
3
+ "version": "1.0.201",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@bobfrankston/freezepak": "^0.1.9",
35
- "@bobfrankston/importgen": "^0.1.39",
35
+ "@bobfrankston/importgen": "^0.1.40",
36
36
  "@bobfrankston/themecolors": "^0.1.8",
37
37
  "@bobfrankston/userconfig": "^1.0.10",
38
38
  "@npmcli/package-json": "^7.0.4",
@@ -60,7 +60,7 @@
60
60
  ".transformedSnapshot": {
61
61
  "dependencies": {
62
62
  "@bobfrankston/freezepak": "^0.1.9",
63
- "@bobfrankston/importgen": "^0.1.39",
63
+ "@bobfrankston/importgen": "^0.1.40",
64
64
  "@bobfrankston/themecolors": "^0.1.8",
65
65
  "@bobfrankston/userconfig": "^1.0.10",
66
66
  "@npmcli/package-json": "^7.0.4",
package/lib/config.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import { type NpmCommonConfig } from '@bobfrankston/userconfig';
2
- import { type GlobalizeOptions } from './types.js';
3
- /** Read and parse package.json from a directory */
4
- export declare function readPackageJson(dir: string): any;
5
- /** Global npm config from %USERPROFILE%\.userconfig\npm.json5 — via @bobfrankston/userconfig */
6
- export type UserNpmConfig = NpmCommonConfig;
7
- /** Get the .userconfig directory path (%USERPROFILE%\.userconfig) */
8
- export declare function getUserConfigDir(): string;
9
- /** Read global npm config from %USERPROFILE%\.userconfig\npm.json5 */
10
- export declare function readUserNpmConfig(): UserNpmConfig;
11
- /** Write global npm config to %USERPROFILE%\.userconfig\npm.json5 */
12
- export declare function writeUserNpmConfig(config: UserNpmConfig): void;
13
- /** Read .globalize.json5 config file */
14
- export declare function readConfig(dir: string): Partial<GlobalizeOptions>;
15
- /** Write .globalize.json5 config file */
16
- export declare function writeConfig(dir: string, config: Partial<GlobalizeOptions>, explicitKeys?: Set<string>): void;
17
- /** Write package.json to a directory */
18
- export declare function writePackageJson(dir: string, pkg: any): void;
19
- /** Resolve a file: path to absolute path */
20
- export declare function resolveFilePath(fileRef: string, baseDir: string): string;
21
- /** Check if a dependency value is a file: reference */
22
- export declare function isFileRef(value: string): boolean;
23
- //# sourceMappingURL=config.d.ts.map
package/lib/config.js DELETED
@@ -1,163 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import JSON5 from 'json5';
4
- import { readConfig as readUserConfig, writeConfig as writeUserConfig, configDir } from '@bobfrankston/userconfig';
5
- /** Read and parse package.json from a directory */
6
- export function readPackageJson(dir) {
7
- const pkgPath = path.join(dir, 'package.json');
8
- if (!fs.existsSync(pkgPath)) {
9
- throw new Error(`package.json not found: ${pkgPath}`);
10
- }
11
- try {
12
- return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
13
- }
14
- catch (error) {
15
- throw new Error(`Failed to parse ${pkgPath}: ${error.message}`);
16
- }
17
- }
18
- /** Get the .userconfig directory path (%USERPROFILE%\.userconfig) */
19
- export function getUserConfigDir() {
20
- return configDir;
21
- }
22
- /** Read global npm config from %USERPROFILE%\.userconfig\npm.json5 */
23
- export function readUserNpmConfig() {
24
- return readUserConfig();
25
- }
26
- /** Write global npm config to %USERPROFILE%\.userconfig\npm.json5 */
27
- export function writeUserNpmConfig(config) {
28
- const existing = readUserConfig();
29
- const merged = { ...existing, ...config };
30
- writeUserConfig(merged);
31
- }
32
- /** Read .globalize.json5 config file */
33
- export function readConfig(dir) {
34
- const configPath = path.join(dir, '.globalize.json5');
35
- if (!fs.existsSync(configPath)) {
36
- return {};
37
- }
38
- try {
39
- const content = fs.readFileSync(configPath, 'utf-8');
40
- return JSON5.parse(content);
41
- }
42
- catch (error) {
43
- console.warn(`Warning: Could not parse .globalize.json5 config: ${error.message}`);
44
- return {};
45
- }
46
- }
47
- /** Write .globalize.json5 config file */
48
- export function writeConfig(dir, config, explicitKeys) {
49
- const configPath = path.join(dir, '.globalize.json5');
50
- // Define defaults to omit
51
- const defaults = {
52
- bump: 'patch',
53
- files: true,
54
- quiet: true,
55
- gitVisibility: 'private',
56
- npmVisibility: 'private',
57
- install: false,
58
- wsl: false,
59
- force: false,
60
- verbose: false,
61
- freeze: false,
62
- usePaths: true
63
- };
64
- // Read existing config to preserve values
65
- const existing = readConfig(dir);
66
- // Filter out temporary flags and default values (unless explicitly set)
67
- const filtered = {};
68
- const omitKeys = new Set(['cleanup', 'init', 'dryRun', 'message', 'conform', 'asis', 'help', 'error', 'updateDeps', 'updateMajor', 'publishDeps', 'publicDeps', 'forcePublish', 'once', 'cleanNestedModules']);
69
- for (const [key, value] of Object.entries(config)) {
70
- if (omitKeys.has(key))
71
- continue;
72
- // Keep if: already in config, explicitly set via CLI, or differs from default
73
- const isExplicit = explicitKeys?.has(key);
74
- const wasInConfig = key in existing;
75
- const differsFromDefault = defaults[key] !== value;
76
- if (isExplicit || wasInConfig || differsFromDefault) {
77
- filtered[key] = value;
78
- }
79
- }
80
- // Build content with comments
81
- const lines = [
82
- '{',
83
- ' // npmglobalize configuration (JSON5 format - trailing commas OK)',
84
- ' // Explicitly set values are preserved here',
85
- ''
86
- ];
87
- // Add configured values
88
- const entries = Object.entries(filtered);
89
- if (entries.length > 0) {
90
- entries.forEach(([key, value]) => {
91
- const jsonValue = typeof value === 'string' ? `"${value}"` : JSON.stringify(value);
92
- const comma = ','; // JSON5 allows trailing commas
93
- // Add inline comment for clarity
94
- let comment = '';
95
- if (key === 'install')
96
- comment = ' // Auto-install globally after publish (from registry)';
97
- else if (key === 'link')
98
- comment = ' // Install globally via symlink (npm install -g .)';
99
- else if (key === 'wsl')
100
- comment = ' // Also install in WSL';
101
- else if (key === 'files')
102
- comment = ' // Keep file: paths after publish';
103
- else if (key === 'force')
104
- comment = ' // Continue despite git errors';
105
- else if (key === 'quiet')
106
- comment = ' // Suppress npm warnings';
107
- else if (key === 'verbose')
108
- comment = ' // Show detailed output';
109
- else if (key === 'gitVisibility')
110
- comment = ' // private (default) or public';
111
- else if (key === 'npmVisibility')
112
- comment = ' // private (default) or public';
113
- else if (key === 'bump')
114
- comment = ' // patch (default), minor, or major';
115
- else if (key === 'fix')
116
- comment = ' // Auto-run npm audit fix';
117
- else if (key === 'local')
118
- comment = ' // Local install only (skip transform/publish)';
119
- else if (key === 'noPublish')
120
- comment = ' // Transform but don\'t publish';
121
- else if (key === 'freeze')
122
- comment = ' // Freeze node_modules (replace symlinks with real copies)';
123
- else if (key === 'usePaths')
124
- comment = ' // Resolve file: deps from sibling checkouts (set false for standalone packages)';
125
- lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
126
- });
127
- lines.push('');
128
- }
129
- // Add commented reference for all options
130
- lines.push(' // Defaults (omitted above):');
131
- lines.push(' // "bump": "patch" // Version bump: patch, minor, major');
132
- lines.push(' // "install": false // Auto-install globally after publish (from registry)');
133
- lines.push(' // "link": false // Install globally via symlink (npm install -g .)');
134
- lines.push(' // "wsl": false // Also install in WSL');
135
- lines.push(' // "files": true // Keep file: paths after publish');
136
- lines.push(' // "force": false // Continue despite git errors');
137
- lines.push(' // "quiet": true // Suppress npm warnings');
138
- lines.push(' // "verbose": false // Show detailed output');
139
- lines.push(' // "gitVisibility": "private" // Git repo: private or public');
140
- lines.push(' // "npmVisibility": "private" // npm package: private or public');
141
- lines.push(' // "fix": false // Auto-run npm audit fix');
142
- lines.push(' // "local": false // Local install only (skip transform/publish)');
143
- lines.push(' // "noPublish": false // Transform but don\'t publish');
144
- lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
145
- lines.push(' // "usePaths": true // Resolve file: deps from siblings; false = use latest npm version (standalone)');
146
- lines.push('}');
147
- fs.writeFileSync(configPath, lines.join('\n') + '\n');
148
- }
149
- /** Write package.json to a directory */
150
- export function writePackageJson(dir, pkg) {
151
- const pkgPath = path.join(dir, 'package.json');
152
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
153
- }
154
- /** Resolve a file: path to absolute path */
155
- export function resolveFilePath(fileRef, baseDir) {
156
- const relativePath = fileRef.replace(/^file:/, '');
157
- return path.resolve(baseDir, relativePath);
158
- }
159
- /** Check if a dependency value is a file: reference */
160
- export function isFileRef(value) {
161
- return typeof value === 'string' && value.startsWith('file:');
162
- }
163
- //# sourceMappingURL=config.js.map
package/lib/deps.d.ts DELETED
@@ -1,42 +0,0 @@
1
- /**
2
- * npmglobalize dependency analysis, transformation, and restoration.
3
- * Handles file: ref discovery, workspace graphs, topological sorting,
4
- * and transforming file: deps to npm versions for publishing.
5
- */
6
- /** Get all file: dependencies from package.json */
7
- export declare function getFileRefs(pkg: any): Map<string, {
8
- key: string;
9
- name: string;
10
- value: string;
11
- }>;
12
- /** Resolve workspace entries to package info. Skips dirs without package.json or with private:true. */
13
- export declare function resolveWorkspacePackages(rootDir: string): Array<{
14
- name: string;
15
- dir: string;
16
- pkg: any;
17
- }>;
18
- /** Build a dependency graph among workspace packages. Returns Map<name, Set<depName>>. */
19
- export declare function buildDependencyGraph(packages: Array<{
20
- name: string;
21
- dir: string;
22
- pkg: any;
23
- }>): Map<string, Set<string>>;
24
- /** Topological sort with cycle detection. Returns package names in dependency order. */
25
- export declare function topologicalSort(graph: Map<string, Set<string>>): string[];
26
- /** Transform file: dependencies to npm versions */
27
- export declare function transformDeps(pkg: any, baseDir: string, verbose?: boolean, forcePublish?: boolean): {
28
- transformed: boolean;
29
- unpublished: Array<{
30
- name: string;
31
- version: string;
32
- path: string;
33
- }>;
34
- };
35
- /** Build and print a dependency tree of file: references.
36
- * Recursively walks file: deps showing the full hierarchy with indentation. */
37
- export declare function printDepTree(baseDir: string, indent?: number, visited?: Set<string>): void;
38
- /** Restore file: dependencies from .dependencies */
39
- export declare function restoreDeps(pkg: any, verbose?: boolean): boolean;
40
- /** Check if .dependencies exist (already transformed) */
41
- export declare function hasBackup(pkg: any): boolean;
42
- //# sourceMappingURL=deps.d.ts.map
package/lib/deps.js DELETED
@@ -1,298 +0,0 @@
1
- /**
2
- * npmglobalize dependency analysis, transformation, and restoration.
3
- * Handles file: ref discovery, workspace graphs, topological sorting,
4
- * and transforming file: deps to npm versions for publishing.
5
- */
6
- import fs from 'fs';
7
- import path from 'path';
8
- import { spawnSafe, colors, DEP_KEYS } from './types.js';
9
- import { readPackageJson, isFileRef, resolveFilePath } from './config.js';
10
- import { checkVersionExists } from './npm.js';
11
- /** Get all file: dependencies from package.json */
12
- export function getFileRefs(pkg) {
13
- const refs = new Map();
14
- for (const key of DEP_KEYS) {
15
- if (!pkg[key])
16
- continue;
17
- for (const [name, value] of Object.entries(pkg[key])) {
18
- if (isFileRef(value)) {
19
- refs.set(`${key}:${name}`, { key, name, value: value });
20
- }
21
- }
22
- }
23
- return refs;
24
- }
25
- // ─── Workspace helpers ───────────────────────────────────────────────
26
- /** Resolve workspace entries to package info. Skips dirs without package.json or with private:true. */
27
- export function resolveWorkspacePackages(rootDir) {
28
- const rootPkg = readPackageJson(rootDir);
29
- const workspaces = rootPkg.workspaces;
30
- if (!Array.isArray(workspaces))
31
- return [];
32
- const results = [];
33
- for (const entry of workspaces) {
34
- const pkgDir = path.resolve(rootDir, entry);
35
- const pkgJsonPath = path.join(pkgDir, 'package.json');
36
- if (!fs.existsSync(pkgJsonPath))
37
- continue;
38
- const pkg = readPackageJson(pkgDir);
39
- if (pkg.private)
40
- continue; // skip private packages (they can't be published)
41
- results.push({ name: pkg.name || entry, dir: pkgDir, pkg });
42
- }
43
- return results;
44
- }
45
- /** Build a dependency graph among workspace packages. Returns Map<name, Set<depName>>. */
46
- export function buildDependencyGraph(packages) {
47
- const nameSet = new Set(packages.map(p => p.name));
48
- const dirToName = new Map();
49
- for (const p of packages) {
50
- dirToName.set(p.dir, p.name);
51
- }
52
- const graph = new Map();
53
- for (const p of packages) {
54
- const deps = new Set();
55
- for (const depKey of DEP_KEYS) {
56
- if (!p.pkg[depKey])
57
- continue;
58
- for (const [depName, depValue] of Object.entries(p.pkg[depKey])) {
59
- // Check by npm name
60
- if (nameSet.has(depName)) {
61
- deps.add(depName);
62
- continue;
63
- }
64
- // Check file: refs that resolve to a sibling workspace dir
65
- if (isFileRef(depValue)) {
66
- const resolved = resolveFilePath(depValue, p.dir);
67
- const resolvedNorm = path.resolve(resolved);
68
- const match = dirToName.get(resolvedNorm);
69
- if (match) {
70
- deps.add(match);
71
- }
72
- }
73
- }
74
- }
75
- graph.set(p.name, deps);
76
- }
77
- return graph;
78
- }
79
- /** Topological sort with cycle detection. Returns package names in dependency order. */
80
- export function topologicalSort(graph) {
81
- const visited = new Set();
82
- const visiting = new Set(); // cycle detection
83
- const result = [];
84
- function visit(node) {
85
- if (visited.has(node))
86
- return;
87
- if (visiting.has(node)) {
88
- throw new Error(`Circular dependency detected involving: ${node}`);
89
- }
90
- visiting.add(node);
91
- const deps = graph.get(node);
92
- if (deps) {
93
- for (const dep of deps) {
94
- if (dep === node)
95
- continue; // skip self-references
96
- if (graph.has(dep)) { // only visit workspace-internal deps
97
- visit(dep);
98
- }
99
- }
100
- }
101
- visiting.delete(node);
102
- visited.add(node);
103
- result.push(node);
104
- }
105
- for (const node of graph.keys()) {
106
- visit(node);
107
- }
108
- return result;
109
- }
110
- /** Check if a published npm package has broken deps (file: paths or unpublished transitive deps).
111
- * Also checks local file: deps for unpublished versions. */
112
- function hasUnpublishedTransitiveDeps(packageName, pkg, baseDir, verbose) {
113
- // Check 1: Does the npm-published version have file: paths in its deps?
114
- try {
115
- const result = spawnSafe('npm', ['view', packageName, 'dependencies', '--json'], {
116
- encoding: 'utf-8',
117
- stdio: 'pipe',
118
- shell: true
119
- });
120
- if (result.status === 0 && result.stdout.trim()) {
121
- const npmDeps = JSON.parse(result.stdout.trim());
122
- for (const [depName, depValue] of Object.entries(npmDeps)) {
123
- if (isFileRef(depValue)) {
124
- if (verbose) {
125
- console.log(colors.yellow(` npm copy has file: dep ${depName} → ${depValue}`));
126
- }
127
- return true;
128
- }
129
- }
130
- }
131
- }
132
- catch {
133
- // Can't check npm — fall through to local check
134
- }
135
- // Check 2: Do local file: deps have unpublished versions?
136
- for (const key of DEP_KEYS) {
137
- if (!pkg[key])
138
- continue;
139
- for (const [depName, depValue] of Object.entries(pkg[key])) {
140
- if (!isFileRef(depValue))
141
- continue;
142
- try {
143
- const depPath = resolveFilePath(depValue, baseDir);
144
- const depPkg = readPackageJson(depPath);
145
- if (!checkVersionExists(depName, depPkg.version)) {
146
- if (verbose) {
147
- console.log(colors.yellow(` transitive dep ${depName}@${depPkg.version} not on npm`));
148
- }
149
- return true;
150
- }
151
- }
152
- catch {
153
- return true;
154
- }
155
- }
156
- }
157
- return false;
158
- }
159
- /** Transform file: dependencies to npm versions */
160
- export function transformDeps(pkg, baseDir, verbose = false, forcePublish = false) {
161
- let transformed = false;
162
- const unpublished = [];
163
- for (const key of DEP_KEYS) {
164
- if (!pkg[key])
165
- continue;
166
- const dotKey = '.' + key;
167
- // If .dependencies already exists, restore it and merge any new dependencies
168
- if (pkg[dotKey]) {
169
- // Save any new dependencies that aren't in .dependencies
170
- const currentDeps = { ...pkg[key] };
171
- // Restore .dependencies back to dependencies
172
- pkg[key] = { ...pkg[dotKey] };
173
- // Merge in any NEW dependencies that were added since transformation
174
- for (const [name, value] of Object.entries(currentDeps)) {
175
- if (!(name in pkg[dotKey])) {
176
- // This is a new dependency, add it
177
- pkg[key][name] = value;
178
- // Also add to .dependencies backup
179
- pkg[dotKey][name] = value;
180
- if (verbose) {
181
- console.log(` Merged new dependency: ${name}`);
182
- }
183
- }
184
- }
185
- }
186
- const hasFileRefs = Object.values(pkg[key]).some(v => isFileRef(v));
187
- if (!hasFileRefs)
188
- continue;
189
- // Backup original (or update existing backup with merged deps)
190
- if (!pkg[dotKey]) {
191
- pkg[dotKey] = { ...pkg[key] };
192
- }
193
- // Transform file: refs to npm versions
194
- for (const [name, value] of Object.entries(pkg[key])) {
195
- if (isFileRef(value)) {
196
- const targetPath = resolveFilePath(value, baseDir);
197
- console.log(colors.blue(` + ${name} → ${value}`));
198
- try {
199
- const targetPkg = readPackageJson(targetPath);
200
- const targetVersion = targetPkg.version;
201
- const npmVersion = '^' + targetVersion;
202
- // Check if this version exists on npm (or if force publish)
203
- const versionExists = forcePublish ? false : checkVersionExists(name, targetVersion);
204
- if (!versionExists) {
205
- unpublished.push({ name, version: targetVersion, path: targetPath });
206
- if (forcePublish) {
207
- console.log(colors.yellow(` ⟳ ${name}@${targetVersion} will be republished (--force-publish)`));
208
- }
209
- else {
210
- console.log(colors.red(` ⚠ ${name}@${targetVersion} not found on npm (local: ${value})`));
211
- }
212
- }
213
- else {
214
- if (verbose) {
215
- console.log(colors.green(` ✓ ${name}@${targetVersion} exists on npm`));
216
- }
217
- // Check transitive file: deps — if any are unpublished, this dep needs republishing
218
- if (hasUnpublishedTransitiveDeps(name, targetPkg, targetPath, verbose)) {
219
- unpublished.push({ name, version: targetVersion, path: targetPath });
220
- console.log(colors.yellow(` ⟳ ${name}@${targetVersion} has unpublished transitive deps — will republish`));
221
- }
222
- }
223
- pkg[key][name] = npmVersion;
224
- if (verbose) {
225
- console.log(` ${name}: ${value} -> ${npmVersion}`);
226
- }
227
- transformed = true;
228
- }
229
- catch (error) {
230
- throw new Error(`Failed to resolve ${name} at ${targetPath}: ${error.message}`);
231
- }
232
- }
233
- }
234
- }
235
- return { transformed, unpublished };
236
- }
237
- /** Build and print a dependency tree of file: references.
238
- * Recursively walks file: deps showing the full hierarchy with indentation. */
239
- export function printDepTree(baseDir, indent = 0, visited = new Set()) {
240
- const realDir = fs.realpathSync(baseDir);
241
- if (visited.has(realDir))
242
- return;
243
- visited.add(realDir);
244
- let pkg;
245
- try {
246
- pkg = readPackageJson(baseDir);
247
- }
248
- catch {
249
- return;
250
- }
251
- for (const key of DEP_KEYS) {
252
- if (!pkg[key])
253
- continue;
254
- // Use the backup (.dependencies) if present — it has the original file: refs
255
- const deps = pkg['.' + key] || pkg[key];
256
- for (const [name, value] of Object.entries(deps)) {
257
- if (!isFileRef(value))
258
- continue;
259
- const prefix = ' '.repeat(indent * 2);
260
- let targetPath;
261
- let version = '?';
262
- try {
263
- targetPath = resolveFilePath(value, baseDir);
264
- const targetPkg = readPackageJson(targetPath);
265
- version = targetPkg.version || '?';
266
- }
267
- catch {
268
- console.log(`${prefix} ${name} → ${value} ${colors.red('(unresolvable)')}`);
269
- continue;
270
- }
271
- const exists = checkVersionExists(name, version);
272
- const marker = exists ? colors.green('✓') : colors.red('✗');
273
- console.log(`${prefix} ${marker} ${name}@${version} → ${value}`);
274
- printDepTree(targetPath, indent + 1, visited);
275
- }
276
- }
277
- }
278
- /** Restore file: dependencies from .dependencies */
279
- export function restoreDeps(pkg, verbose = false) {
280
- let restored = false;
281
- for (const key of DEP_KEYS) {
282
- const dotKey = '.' + key;
283
- if (pkg[dotKey]) {
284
- pkg[key] = pkg[dotKey];
285
- delete pkg[dotKey];
286
- restored = true;
287
- if (verbose) {
288
- console.log(` Restored ${key} from ${dotKey}`);
289
- }
290
- }
291
- }
292
- return restored;
293
- }
294
- /** Check if .dependencies exist (already transformed) */
295
- export function hasBackup(pkg) {
296
- return DEP_KEYS.some(key => pkg['.' + key]);
297
- }
298
- //# sourceMappingURL=deps.js.map