@bobfrankston/npmglobalize 1.0.199 → 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/lib/ignore.d.ts DELETED
@@ -1,24 +0,0 @@
1
- /**
2
- * Ignore-file management and conformance.
3
- * Handles .gitignore, .npmignore, and .gitattributes creation/updating.
4
- */
5
- /** Check if ignore files need updates; separates security (auto-fix) from recommended (prompt) */
6
- export declare function checkIgnoreFiles(cwd: string, options: {
7
- conform?: boolean;
8
- asis?: boolean;
9
- verbose?: boolean;
10
- }): {
11
- needsUpdate: boolean;
12
- changes: string[];
13
- securityChanges: string[];
14
- };
15
- /** Update ignore files to conform to best practices.
16
- * securityOnly: if true, only add security patterns (auto-fix without prompting). */
17
- export declare function conformIgnoreFiles(cwd: string, securityOnly?: boolean): void;
18
- /** Ensure .gitignore exists and includes node_modules */
19
- export declare function ensureGitignore(cwd: string): void;
20
- /** Ensure .npmignore exists with recommended patterns */
21
- export declare function ensureNpmignore(cwd: string): void;
22
- /** Ensure .gitattributes exists for LF line endings (per programming.md) */
23
- export declare function ensureGitattributes(cwd: string): void;
24
- //# sourceMappingURL=ignore.d.ts.map
package/lib/ignore.js DELETED
@@ -1,346 +0,0 @@
1
- /**
2
- * Ignore-file management and conformance.
3
- * Handles .gitignore, .npmignore, and .gitattributes creation/updating.
4
- */
5
- import fs from 'fs';
6
- import path from 'path';
7
- import JSON5 from 'json5';
8
- import { colors } from './types.js';
9
- import { runCommand, detectCredentialsType } from './git.js';
10
- function loadIgnorePatterns() {
11
- const patternsPath = path.join(path.dirname(import.meta.filename), '..', 'ignorepatterns.json5');
12
- const content = fs.readFileSync(patternsPath, 'utf-8');
13
- return JSON5.parse(content);
14
- }
15
- const IGNORE_PATTERNS = loadIgnorePatterns();
16
- /** All .gitignore patterns (security + recommended + presenceOnly) */
17
- const ALL_GITIGNORE = [...IGNORE_PATTERNS.gitignore.security, ...IGNORE_PATTERNS.gitignore.recommended, ...(IGNORE_PATTERNS.gitignore.presenceOnly ?? [])];
18
- /** All .npmignore patterns (security + recommended) */
19
- const ALL_NPMIGNORE = [...IGNORE_PATTERNS.npmignore.security, ...IGNORE_PATTERNS.npmignore.recommended];
20
- /** Patterns that should NOT be in .npmignore for noEmit projects (TS files are the runtime files) */
21
- const TS_NPMIGNORE_PATTERNS = new Set(['*.ts', '!*.d.ts', '*.map', 'tsconfig.json']);
22
- /** Check if target project uses noEmit (TS files run directly, no compilation) */
23
- function isNoEmitProject(cwd) {
24
- const tsconfigPath = path.join(cwd, 'tsconfig.json');
25
- if (!fs.existsSync(tsconfigPath))
26
- return false;
27
- try {
28
- const content = fs.readFileSync(tsconfigPath, 'utf-8');
29
- const tsconfig = JSON5.parse(content);
30
- return tsconfig.compilerOptions?.noEmit === true;
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
- /** Get applicable npmignore patterns, excluding TS patterns for noEmit projects */
37
- function getApplicableNpmignorePatterns(cwd) {
38
- if (isNoEmitProject(cwd)) {
39
- return ALL_NPMIGNORE.filter(p => !TS_NPMIGNORE_PATTERNS.has(p));
40
- }
41
- return ALL_NPMIGNORE;
42
- }
43
- /** Presence-only extensions derived from data file */
44
- const PRESENCE_ONLY_EXTENSIONS = new Set((IGNORE_PATTERNS.gitignore.presenceOnly ?? [])
45
- .map(p => p.match(/^\*(\.\w+)$/)?.[1])
46
- .filter((e) => !!e));
47
- /** Check if any files with the given extension exist in dir (skips node_modules, .git, prev) */
48
- function hasFilesWithExtension(dir, ext) {
49
- const skip = new Set(['node_modules', '.git', 'prev']);
50
- function check(d) {
51
- try {
52
- for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
53
- if (skip.has(entry.name))
54
- continue;
55
- if (entry.isFile() && entry.name.endsWith(ext))
56
- return true;
57
- if (entry.isDirectory() && check(path.join(d, entry.name)))
58
- return true;
59
- }
60
- }
61
- catch { }
62
- return false;
63
- }
64
- return check(dir);
65
- }
66
- /** Filter gitignore patterns to skip presence-only patterns when no matching files exist */
67
- function getApplicableGitignorePatterns(cwd) {
68
- return ALL_GITIGNORE.filter(pattern => {
69
- const extMatch = pattern.match(/^\*(\.\w+)$/);
70
- if (extMatch && PRESENCE_ONLY_EXTENSIONS.has(extMatch[1])) {
71
- return hasFilesWithExtension(cwd, extMatch[1]);
72
- }
73
- return true;
74
- });
75
- }
76
- /** Security-only gitignore patterns (always applicable) */
77
- function getSecurityGitignorePatterns() {
78
- return IGNORE_PATTERNS.gitignore.security;
79
- }
80
- /** Security-only npmignore patterns */
81
- function getSecurityNpmignorePatterns() {
82
- return IGNORE_PATTERNS.npmignore.security;
83
- }
84
- /** Check if a pattern is present in a list of lines (with or without trailing slash) */
85
- function lineHasPattern(lines, pattern) {
86
- return lines.some(line => line === pattern || line === pattern.replace('/', ''));
87
- }
88
- /** Ensure credentials.json is handled correctly in ignore files based on OAuth type.
89
- * "installed" apps: client_secret is just a public app registration ID — must be INCLUDED.
90
- * "web" apps: client_secret is a real secret — must be IGNORED. */
91
- function conformCredentialsIgnore(cwd) {
92
- const credType = detectCredentialsType(cwd);
93
- if (!credType)
94
- return;
95
- for (const ignoreFile of ['.gitignore', '.npmignore']) {
96
- const ignorePath = path.join(cwd, ignoreFile);
97
- if (!fs.existsSync(ignorePath))
98
- continue;
99
- const content = fs.readFileSync(ignorePath, 'utf-8');
100
- const lines = content.split('\n');
101
- const trimmed = lines.map(l => l.trim());
102
- if (credType === 'installed') {
103
- // Ensure credentials.json is NOT ignored — add negation if it's being blocked
104
- const hasBlock = trimmed.some(l => l === 'credentials.json' || l === 'credentials.json/');
105
- const hasNegation = trimmed.some(l => l === '!credentials.json');
106
- if (hasBlock && !hasNegation) {
107
- // Add negation after the blocking line
108
- const newLines = [...lines];
109
- const blockIdx = trimmed.findIndex(l => l === 'credentials.json' || l === 'credentials.json/');
110
- newLines.splice(blockIdx + 1, 0, '!credentials.json');
111
- fs.writeFileSync(ignorePath, newLines.join('\n'));
112
- console.log(colors.cyan(` ✓ ${ignoreFile}: added !credentials.json (installed app — public OAuth app ID)`));
113
- }
114
- else if (!hasBlock && !hasNegation) {
115
- // No block exists, but add negation defensively in case a broader pattern catches it
116
- const newContent = content.trimEnd() + '\n!credentials.json\n';
117
- fs.writeFileSync(ignorePath, newContent);
118
- console.log(colors.cyan(` ✓ ${ignoreFile}: added !credentials.json (installed app — public OAuth app ID)`));
119
- }
120
- }
121
- else if (credType === 'web') {
122
- // Ensure credentials.json IS ignored
123
- const hasBlock = trimmed.some(l => l === 'credentials.json');
124
- if (!hasBlock) {
125
- const newContent = content.trimEnd() + '\ncredentials.json\n';
126
- fs.writeFileSync(ignorePath, newContent);
127
- console.log(colors.cyan(` ✓ ${ignoreFile}: added credentials.json to ignore (web app — real secret)`));
128
- }
129
- // Remove any negation that would un-ignore it
130
- const negIdx = trimmed.findIndex(l => l === '!credentials.json');
131
- if (negIdx >= 0) {
132
- const newLines = [...lines];
133
- newLines.splice(negIdx, 1);
134
- fs.writeFileSync(ignorePath, newLines.join('\n'));
135
- console.log(colors.yellow(` ✓ ${ignoreFile}: removed !credentials.json (web app — must not be public)`));
136
- }
137
- }
138
- }
139
- }
140
- /** Check if ignore files need updates; separates security (auto-fix) from recommended (prompt) */
141
- export function checkIgnoreFiles(cwd, options) {
142
- const changes = [];
143
- const securityChanges = [];
144
- // Check if asis is set in config or passed as option
145
- if (options.asis) {
146
- if (options.verbose) {
147
- console.log(colors.yellow(' Skipping ignore file checks (--asis or asis in config)'));
148
- }
149
- return { needsUpdate: false, changes: [], securityChanges: [] };
150
- }
151
- const securityGit = new Set(getSecurityGitignorePatterns());
152
- const securityNpm = new Set(getSecurityNpmignorePatterns());
153
- // Check .gitignore
154
- const gitignorePath = path.join(cwd, '.gitignore');
155
- if (fs.existsSync(gitignorePath)) {
156
- const content = fs.readFileSync(gitignorePath, 'utf-8');
157
- const lines = content.split('\n').map(l => l.trim());
158
- for (const pattern of getApplicableGitignorePatterns(cwd)) {
159
- if (!lineHasPattern(lines, pattern)) {
160
- if (securityGit.has(pattern)) {
161
- securityChanges.push(` .gitignore missing: ${pattern}`);
162
- }
163
- else {
164
- changes.push(` .gitignore missing: ${pattern}`);
165
- }
166
- }
167
- }
168
- }
169
- // Check .npmignore
170
- const npmignorePath = path.join(cwd, '.npmignore');
171
- if (fs.existsSync(npmignorePath)) {
172
- const content = fs.readFileSync(npmignorePath, 'utf-8');
173
- const lines = content.split('\n').map(l => l.trim());
174
- const applicableNpm = getApplicableNpmignorePatterns(cwd);
175
- for (const pattern of applicableNpm) {
176
- if (!lineHasPattern(lines, pattern)) {
177
- if (securityNpm.has(pattern)) {
178
- securityChanges.push(` .npmignore missing: ${pattern}`);
179
- }
180
- else {
181
- changes.push(` .npmignore missing: ${pattern}`);
182
- }
183
- }
184
- }
185
- }
186
- const needsUpdate = changes.length > 0 || securityChanges.length > 0;
187
- return { needsUpdate, changes, securityChanges };
188
- }
189
- /** Update ignore files to conform to best practices.
190
- * securityOnly: if true, only add security patterns (auto-fix without prompting). */
191
- export function conformIgnoreFiles(cwd, securityOnly = false) {
192
- if (!securityOnly) {
193
- // Ensure .gitattributes for LF line endings (use proper helper)
194
- ensureGitattributes(cwd);
195
- // Configure git for LF line endings if in a git repo
196
- if (fs.existsSync(path.join(cwd, '.git'))) {
197
- try {
198
- const result1 = runCommand('git', ['config', 'core.autocrlf', 'false'], { cwd, silent: true });
199
- const result2 = runCommand('git', ['config', 'core.eol', 'lf'], { cwd, silent: true });
200
- if (result1.success && result2.success) {
201
- console.log(colors.green(' ✓ Configured git for LF line endings'));
202
- }
203
- }
204
- catch (error) {
205
- // Silently ignore git config errors
206
- }
207
- }
208
- }
209
- const patternsGit = securityOnly ? getSecurityGitignorePatterns() : getApplicableGitignorePatterns(cwd);
210
- const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd);
211
- const noEmit = isNoEmitProject(cwd);
212
- // Update .gitignore
213
- const gitignorePath = path.join(cwd, '.gitignore');
214
- if (fs.existsSync(gitignorePath)) {
215
- const content = fs.readFileSync(gitignorePath, 'utf-8');
216
- const lines = new Set(content.split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#')));
217
- let updated = false;
218
- for (const pattern of patternsGit) {
219
- const normalized = pattern.replace('/', '');
220
- if (!lines.has(pattern) && !lines.has(normalized)) {
221
- lines.add(pattern);
222
- updated = true;
223
- }
224
- }
225
- if (updated) {
226
- const newContent = Array.from(lines).sort().join('\n') + '\n';
227
- fs.writeFileSync(gitignorePath, newContent);
228
- console.log(colors.cyan(' ✓ Auto-added security patterns to .gitignore'));
229
- }
230
- }
231
- // Update .npmignore
232
- const npmignorePath = path.join(cwd, '.npmignore');
233
- if (fs.existsSync(npmignorePath)) {
234
- const content = fs.readFileSync(npmignorePath, 'utf-8');
235
- const lines = content.split('\n').map(l => l.trim());
236
- const newLines = new Set(lines.filter(l => l));
237
- let updated = false;
238
- if (!securityOnly && !noEmit) {
239
- // Add TypeScript exclusions (only in full conform, skip for noEmit projects)
240
- for (const ts of ['*.ts', '!*.d.ts', '*.map']) {
241
- if (!newLines.has(ts)) {
242
- newLines.add(ts);
243
- updated = true;
244
- }
245
- }
246
- }
247
- // For noEmit projects, remove TS patterns that shouldn't be ignored
248
- if (noEmit) {
249
- for (const ts of TS_NPMIGNORE_PATTERNS) {
250
- if (newLines.has(ts)) {
251
- newLines.delete(ts);
252
- updated = true;
253
- }
254
- }
255
- }
256
- for (const pattern of patternsNpm) {
257
- if (!newLines.has(pattern)) {
258
- newLines.add(pattern);
259
- updated = true;
260
- }
261
- }
262
- if (updated) {
263
- const newContent = Array.from(newLines).join('\n') + '\n';
264
- fs.writeFileSync(npmignorePath, newContent);
265
- if (noEmit) {
266
- console.log(colors.cyan(' ✓ .npmignore updated (noEmit: kept *.ts files)'));
267
- }
268
- else {
269
- console.log(colors.cyan(' ✓ Auto-added security patterns to .npmignore'));
270
- }
271
- }
272
- }
273
- }
274
- /** Ensure .gitignore exists and includes node_modules */
275
- export function ensureGitignore(cwd) {
276
- const gitignorePath = path.join(cwd, '.gitignore');
277
- let content = '';
278
- let needsUpdate = false;
279
- // Read existing .gitignore if it exists
280
- if (fs.existsSync(gitignorePath)) {
281
- content = fs.readFileSync(gitignorePath, 'utf-8');
282
- // Check if node_modules is already ignored
283
- const lines = content.split('\n').map(l => l.trim());
284
- const hasNodeModules = lines.some(line => line === 'node_modules' ||
285
- line === 'node_modules/' ||
286
- line === '/node_modules' ||
287
- line === '/node_modules/');
288
- if (!hasNodeModules) {
289
- console.log(colors.yellow(' Warning: node_modules not found in .gitignore, adding it...'));
290
- needsUpdate = true;
291
- }
292
- }
293
- else {
294
- console.log(' Creating .gitignore...');
295
- needsUpdate = true;
296
- }
297
- // Update .gitignore if needed
298
- if (needsUpdate) {
299
- if (!content || content.trim() === '') {
300
- // Create new .gitignore from applicable patterns plus extras
301
- const extras = ['*certs*/', 'configuration.json', 'cruft/', 'prev/', 'tests/'];
302
- content = [...getApplicableGitignorePatterns(cwd), ...extras].join('\n') + '\n';
303
- }
304
- else {
305
- // Add node_modules to existing .gitignore
306
- if (!content.endsWith('\n')) {
307
- content += '\n';
308
- }
309
- content = 'node_modules/\n' + content;
310
- }
311
- fs.writeFileSync(gitignorePath, content);
312
- console.log(colors.green(' ✓ .gitignore updated'));
313
- }
314
- }
315
- /** Ensure .npmignore exists with recommended patterns */
316
- export function ensureNpmignore(cwd) {
317
- const npmignorePath = path.join(cwd, '.npmignore');
318
- if (!fs.existsSync(npmignorePath)) {
319
- console.log(' Creating .npmignore...');
320
- const patterns = getApplicableNpmignorePatterns(cwd);
321
- const content = patterns.join('\n') + '\n';
322
- fs.writeFileSync(npmignorePath, content);
323
- console.log(colors.green(' ✓ .npmignore created'));
324
- }
325
- }
326
- /** Ensure .gitattributes exists for LF line endings (per programming.md) */
327
- export function ensureGitattributes(cwd) {
328
- const gitattributesPath = path.join(cwd, '.gitattributes');
329
- if (!fs.existsSync(gitattributesPath)) {
330
- console.log(' Creating .gitattributes...');
331
- const content = `# Force LF line endings for all text files
332
- * text=auto eol=lf
333
-
334
- # Ensure these are always LF
335
- *.ts text eol=lf
336
- *.js text eol=lf
337
- *.json text eol=lf
338
- *.md text eol=lf
339
- *.yml text eol=lf
340
- *.yaml text eol=lf
341
- `;
342
- fs.writeFileSync(gitattributesPath, content);
343
- console.log(colors.green(' ✓ .gitattributes created (LF line endings)'));
344
- }
345
- }
346
- //# sourceMappingURL=ignore.js.map
package/lib/npm.d.ts DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * npm registry operations: version checks, access control, authentication, dependency updates
3
- */
4
- /** Get the latest version of a package from npm */
5
- export declare function getLatestVersion(packageName: string): string | null;
6
- /** Check if a specific version of a package exists on npm */
7
- export declare function checkVersionExists(packageName: string, version: string): boolean;
8
- /** Check if a package exists on npm (any version) */
9
- export declare function checkPackageExists(packageName: string): boolean;
10
- /** Check npm package access level (public/restricted/null if not published) */
11
- export declare function checkNpmAccess(packageName: string): 'public' | 'restricted' | null;
12
- /** Check if public package has private/inaccessible dependencies */
13
- export declare function checkPrivateDependencies(pkg: any, verbose?: boolean): {
14
- name: string;
15
- depType: string;
16
- }[];
17
- /** Update existing npm dependencies to latest versions */
18
- export declare function updateNpmDeps(pkg: any, verbose?: boolean, allowMajor?: boolean): {
19
- updated: boolean;
20
- changes: string[];
21
- majorAvailable: Array<{
22
- name: string;
23
- current: string;
24
- latest: string;
25
- }>;
26
- };
27
- /** Check npm authentication status */
28
- export declare function checkNpmAuth(): {
29
- authenticated: boolean;
30
- username?: string;
31
- error?: string;
32
- };
33
- //# sourceMappingURL=npm.d.ts.map