@augment-vir/node 32.2.0 → 32.2.2
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/dist/augments/fs/dir-contents.d.ts +4 -0
- package/dist/augments/fs/dir-contents.js +12 -1
- package/dist/augments/fs/grep.js +71 -58
- package/dist/augments/fs/json.js +1 -1
- package/dist/augments/fs/read-dir.js +3 -1
- package/dist/augments/fs/read-file.js +1 -1
- package/dist/augments/npm/package-json.js +3 -1
- package/dist/augments/npm/read-package-json.js +4 -2
- package/dist/augments/path/contains.js +4 -2
- package/dist/augments/path/os-path.d.ts +6 -0
- package/dist/augments/path/os-path.js +6 -0
- package/dist/augments/terminal/run-cli-script.js +5 -3
- package/dist/augments/typescript/read-tsconfig.js +3 -1
- package/dist/scripts/fix-src-imports.script.js +1 -1
- package/dist/scripts/fix-ts-bin.script.js +3 -4
- package/package.json +13 -13
- package/src/augments/fs/dir-contents.ts +18 -1
- package/src/augments/fs/grep.ts +61 -58
- package/src/augments/fs/json.ts +1 -1
- package/src/augments/fs/read-dir.ts +3 -3
- package/src/augments/fs/read-file.ts +1 -1
- package/src/augments/npm/package-json.ts +3 -3
- package/src/augments/npm/read-package-json.ts +3 -3
- package/src/augments/path/contains.ts +3 -3
- package/src/augments/path/os-path.ts +6 -0
- package/src/augments/terminal/run-cli-script.ts +8 -8
- package/src/augments/typescript/read-tsconfig.ts +3 -3
- package/src/scripts/fix-src-imports.script.ts +1 -1
- package/src/scripts/fix-ts-bin.script.ts +3 -4
|
@@ -30,6 +30,10 @@ export declare function resetDirContents(rootDir: string, contents: Readonly<Dir
|
|
|
30
30
|
/**
|
|
31
31
|
* Write {@link DirContents} to a directory.
|
|
32
32
|
*
|
|
33
|
+
* Keys are always relative to `rootDir`. A key that traverses above it (such as `'../escaped.txt'`)
|
|
34
|
+
* throws instead of writing, so contents built from an untrusted source cannot reach outside the
|
|
35
|
+
* directory they were meant for.
|
|
36
|
+
*
|
|
33
37
|
* @category Node : File
|
|
34
38
|
* @category Package : @augment-vir/node
|
|
35
39
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -2,6 +2,7 @@ import { check } from '@augment-vir/assert';
|
|
|
2
2
|
import { getObjectTypedEntries } from '@augment-vir/common';
|
|
3
3
|
import { readdir, readFile, rm, stat } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
+
import { doesPathContain } from '../path/contains.js';
|
|
5
6
|
import { writeFileAndDir } from './write.js';
|
|
6
7
|
/**
|
|
7
8
|
* Read all contents within a directory and store them in an object. Optionally recursive.
|
|
@@ -26,7 +27,7 @@ export async function readAllDirContents(dir, { recursive = false, excludeList,
|
|
|
26
27
|
}
|
|
27
28
|
const isFile = (await stat(filePath)).isFile();
|
|
28
29
|
const contents = isFile
|
|
29
|
-
?
|
|
30
|
+
? await readFile(filePath, 'utf8')
|
|
30
31
|
: recursive
|
|
31
32
|
? await readAllDirContents(filePath, {
|
|
32
33
|
recursive,
|
|
@@ -63,6 +64,10 @@ export async function resetDirContents(rootDir, contents) {
|
|
|
63
64
|
/**
|
|
64
65
|
* Write {@link DirContents} to a directory.
|
|
65
66
|
*
|
|
67
|
+
* Keys are always relative to `rootDir`. A key that traverses above it (such as `'../escaped.txt'`)
|
|
68
|
+
* throws instead of writing, so contents built from an untrusted source cannot reach outside the
|
|
69
|
+
* directory they were meant for.
|
|
70
|
+
*
|
|
66
71
|
* @category Node : File
|
|
67
72
|
* @category Package : @augment-vir/node
|
|
68
73
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -70,6 +75,12 @@ export async function resetDirContents(rootDir, contents) {
|
|
|
70
75
|
export async function writeDirContents(rootDir, contents) {
|
|
71
76
|
await Promise.all(getObjectTypedEntries(contents).map(async ([relativePath, content,]) => {
|
|
72
77
|
const fullPath = join(rootDir, relativePath);
|
|
78
|
+
if (!doesPathContain({
|
|
79
|
+
potentialParentPath: rootDir,
|
|
80
|
+
potentialChildPath: fullPath,
|
|
81
|
+
})) {
|
|
82
|
+
throw new Error(`Cannot write '${relativePath}': it resolves outside of '${rootDir}'.`);
|
|
83
|
+
}
|
|
73
84
|
if (check.isString(content)) {
|
|
74
85
|
await writeFileAndDir(fullPath, content);
|
|
75
86
|
}
|
package/dist/augments/fs/grep.js
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
import { assert, check } from '@augment-vir/assert';
|
|
2
|
-
import { awaitedBlockingMap, getObjectTypedKeys, log, typedObjectFromEntries, } from '@augment-vir/common';
|
|
2
|
+
import { awaitedBlockingMap, getObjectTypedKeys, log, shellQuote, typedObjectFromEntries, } from '@augment-vir/common';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { lstat, readdir, stat } from 'node:fs/promises';
|
|
5
5
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
6
6
|
import { isOperatingSystem, OperatingSystem } from '../os/operating-system.js';
|
|
7
7
|
const grepBinPath = '/usr/bin/grep';
|
|
8
|
-
function shellQuote(input) {
|
|
9
|
-
return [
|
|
10
|
-
"'",
|
|
11
|
-
input.replaceAll("'", String.raw `'\''`),
|
|
12
|
-
"'",
|
|
13
|
-
].join('');
|
|
14
|
-
}
|
|
15
8
|
function recursiveFlag({ recursive, followSymLinks, }) {
|
|
16
9
|
if (!recursive) {
|
|
17
10
|
return '';
|
|
18
11
|
}
|
|
19
|
-
else if (
|
|
12
|
+
else if (followSymLinks) {
|
|
13
|
+
/**
|
|
14
|
+
* BSD `grep` (macOS) requires `-S` to follow symlinks while recursing, but GNU `grep`
|
|
15
|
+
* (Linux) has no `-S` flag and instead follows all symlinks with `-R`. Only one of these
|
|
16
|
+
* branches can run on a given operating system.
|
|
17
|
+
*/
|
|
18
|
+
/* node:coverage ignore next */
|
|
19
|
+
return isOperatingSystem(OperatingSystem.Mac) ? '-RS' : '-R';
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
20
22
|
return '--recursive';
|
|
21
23
|
}
|
|
22
|
-
/**
|
|
23
|
-
* BSD `grep` (macOS) requires `-S` to follow symlinks while recursing, but GNU `grep` (Linux)
|
|
24
|
-
* has no `-S` flag and instead follows all symlinks with `-R`. Only one of these branches can
|
|
25
|
-
* run on a given operating system.
|
|
26
|
-
*/
|
|
27
|
-
/* node:coverage ignore next */
|
|
28
|
-
return isOperatingSystem(OperatingSystem.Mac) ? '-RS' : '-R';
|
|
29
24
|
}
|
|
30
25
|
function isValidMaxCount(maxCount) {
|
|
31
26
|
return (maxCount == undefined ||
|
|
@@ -156,12 +151,14 @@ function formatGrepCommand(args) {
|
|
|
156
151
|
const operandDelimiterIndex = args.indexOf('--');
|
|
157
152
|
return [
|
|
158
153
|
'grep',
|
|
159
|
-
...args.map((arg, index) =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
154
|
+
...args.map((arg, index) => {
|
|
155
|
+
return shellQuote(redactGrepArgForLogging({
|
|
156
|
+
arg,
|
|
157
|
+
index,
|
|
158
|
+
operandDelimiterIndex,
|
|
159
|
+
previousArg: args[index - 1],
|
|
160
|
+
}));
|
|
161
|
+
}),
|
|
165
162
|
].join(' ');
|
|
166
163
|
}
|
|
167
164
|
function replaceGrepCountOutputArg({ args, replacement, }) {
|
|
@@ -186,7 +183,9 @@ function extractOptionalStringArray(input) {
|
|
|
186
183
|
else if (!check.isArray(input) || !input.every(check.isString)) {
|
|
187
184
|
return undefined;
|
|
188
185
|
}
|
|
189
|
-
|
|
186
|
+
else {
|
|
187
|
+
return input.filter(check.isTruthy);
|
|
188
|
+
}
|
|
190
189
|
}
|
|
191
190
|
function extractString(input) {
|
|
192
191
|
return check.isString(input) && input ? input : undefined;
|
|
@@ -247,18 +246,20 @@ function createSearchLocation(grepSearchLocation) {
|
|
|
247
246
|
],
|
|
248
247
|
};
|
|
249
248
|
}
|
|
250
|
-
else if (grepSearchLocation.dirs
|
|
249
|
+
else if (grepSearchLocation.dirs == undefined) {
|
|
250
|
+
return dir
|
|
251
|
+
? {
|
|
252
|
+
dirs: [
|
|
253
|
+
dir,
|
|
254
|
+
],
|
|
255
|
+
}
|
|
256
|
+
: undefined;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
251
259
|
return {
|
|
252
260
|
dirs: extractStringArray(grepSearchLocation.dirs),
|
|
253
261
|
};
|
|
254
262
|
}
|
|
255
|
-
return dir
|
|
256
|
-
? {
|
|
257
|
-
dirs: [
|
|
258
|
-
dir,
|
|
259
|
-
],
|
|
260
|
-
}
|
|
261
|
-
: undefined;
|
|
262
263
|
}
|
|
263
264
|
function resolveSearchPart({ cwd, searchPart, }) {
|
|
264
265
|
return cwd && !isAbsolute(searchPart) ? resolve(cwd, searchPart) : searchPart;
|
|
@@ -322,11 +323,13 @@ async function createSearchParts({ cwd, followSymLinks, recursive, searchLocatio
|
|
|
322
323
|
return searchLocation.dirs
|
|
323
324
|
? recursive
|
|
324
325
|
? filteredSearchParts
|
|
325
|
-
: (await awaitedBlockingMap(filteredSearchParts, (dir) =>
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
326
|
+
: (await awaitedBlockingMap(filteredSearchParts, (dir) => {
|
|
327
|
+
return readDirectDirSearchParts({
|
|
328
|
+
cwd,
|
|
329
|
+
dir,
|
|
330
|
+
followSymLinks,
|
|
331
|
+
});
|
|
332
|
+
})).flat()
|
|
330
333
|
: filteredSearchParts;
|
|
331
334
|
}
|
|
332
335
|
function createGrepCountEntry({ countString, fileName }) {
|
|
@@ -364,7 +367,7 @@ function parseNullDelimitedGrepRecords({ stdout }) {
|
|
|
364
367
|
}
|
|
365
368
|
return records;
|
|
366
369
|
}
|
|
367
|
-
/* node:coverage ignore next
|
|
370
|
+
/* node:coverage ignore next 28 */
|
|
368
371
|
function parseColonDelimitedGrepCountOutput(stdout) {
|
|
369
372
|
return typedObjectFromEntries(stdout
|
|
370
373
|
.trimEnd()
|
|
@@ -380,12 +383,14 @@ function parseColonDelimitedGrepCountOutput(stdout) {
|
|
|
380
383
|
});
|
|
381
384
|
})
|
|
382
385
|
.filter(check.isTruthy)
|
|
383
|
-
.map((entry) =>
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
386
|
+
.map((entry) => {
|
|
387
|
+
return [
|
|
388
|
+
entry.key,
|
|
389
|
+
entry.value,
|
|
390
|
+
];
|
|
391
|
+
}));
|
|
387
392
|
}
|
|
388
|
-
/* node:coverage ignore next
|
|
393
|
+
/* node:coverage ignore next 22 */
|
|
389
394
|
function parseGrepCountOutput(stdout) {
|
|
390
395
|
return stdout.includes('\0')
|
|
391
396
|
? typedObjectFromEntries(parseNullDelimitedGrepRecords({
|
|
@@ -398,10 +403,12 @@ function parseGrepCountOutput(stdout) {
|
|
|
398
403
|
});
|
|
399
404
|
})
|
|
400
405
|
.filter(check.isTruthy)
|
|
401
|
-
.map((entry) =>
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
406
|
+
.map((entry) => {
|
|
407
|
+
return [
|
|
408
|
+
entry.key,
|
|
409
|
+
entry.value,
|
|
410
|
+
];
|
|
411
|
+
}))
|
|
405
412
|
: parseColonDelimitedGrepCountOutput(stdout);
|
|
406
413
|
}
|
|
407
414
|
/* node:coverage ignore next 7 */
|
|
@@ -478,20 +485,24 @@ async function runGrepCountFallback({ cwd, grepArgs, }) {
|
|
|
478
485
|
});
|
|
479
486
|
}))
|
|
480
487
|
.filter(check.isTruthy)
|
|
481
|
-
.map((entry) =>
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
488
|
+
.map((entry) => {
|
|
489
|
+
return [
|
|
490
|
+
entry.key,
|
|
491
|
+
entry.value,
|
|
492
|
+
];
|
|
493
|
+
}));
|
|
485
494
|
}
|
|
486
495
|
function parseGrepFilesOnlyOutput(stdout) {
|
|
487
496
|
return typedObjectFromEntries(
|
|
488
497
|
/* node:coverage ignore next */
|
|
489
498
|
(stdout.includes('\0') ? stdout.split('\0') : stdout.trimEnd().split('\n'))
|
|
490
499
|
.filter(check.isTruthy)
|
|
491
|
-
.map((entry) =>
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
500
|
+
.map((entry) => {
|
|
501
|
+
return [
|
|
502
|
+
entry,
|
|
503
|
+
[],
|
|
504
|
+
];
|
|
505
|
+
}));
|
|
495
506
|
}
|
|
496
507
|
function parseGrepNormalOutput(stdout) {
|
|
497
508
|
const fileMatches = new Map();
|
|
@@ -580,10 +591,12 @@ export async function grep(grepSearchPattern, grepSearchLocation, options = {})
|
|
|
580
591
|
? grepOptionArrays.includeFiles.map((includeFile) => `--include=${includeFile}`)
|
|
581
592
|
: []),
|
|
582
593
|
grepOptions.binary ? '--binary' : '',
|
|
583
|
-
...searchPatterns.flatMap((searchPattern) =>
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
594
|
+
...searchPatterns.flatMap((searchPattern) => {
|
|
595
|
+
return [
|
|
596
|
+
'-e',
|
|
597
|
+
searchPattern,
|
|
598
|
+
];
|
|
599
|
+
}),
|
|
587
600
|
'--',
|
|
588
601
|
...searchParts,
|
|
589
602
|
].filter(check.isTruthy);
|
package/dist/augments/fs/json.js
CHANGED
|
@@ -41,5 +41,7 @@ export async function readDirRecursive(dirPath) {
|
|
|
41
41
|
export async function readDirFilesByExtension({ dirPath, extension, extensions, }) {
|
|
42
42
|
const extensionsToCheck = extensions || [extension];
|
|
43
43
|
const fileNames = await readdir(dirPath);
|
|
44
|
-
return fileNames.filter((fileName) =>
|
|
44
|
+
return fileNames.filter((fileName) => {
|
|
45
|
+
return extensionsToCheck.some((extensionToCheck) => fileName.endsWith(extensionToCheck));
|
|
46
|
+
});
|
|
45
47
|
}
|
|
@@ -15,7 +15,9 @@ import { findAncestor, joinFilesToDir } from '../path/ancestor.js';
|
|
|
15
15
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
16
16
|
*/
|
|
17
17
|
export async function findAllPackageJsonFilePaths(startDirPath) {
|
|
18
|
-
const packageRootDir = findAncestor(startDirPath, (dir) =>
|
|
18
|
+
const packageRootDir = findAncestor(startDirPath, (dir) => {
|
|
19
|
+
return existsSync(join(dir, 'package-lock.json'));
|
|
20
|
+
});
|
|
19
21
|
if (!packageRootDir) {
|
|
20
22
|
throw new Error(`Cannot find all package.json files: failed to find any directory with a package-lock.json file. Started at '${startDirPath}'.`);
|
|
21
23
|
}
|
|
@@ -16,8 +16,10 @@ export async function readPackageJson(dirPath) {
|
|
|
16
16
|
if (!packageJson) {
|
|
17
17
|
throw new TypeError(`package.json file does not exist in '${dirPath}'`);
|
|
18
18
|
}
|
|
19
|
-
else if (
|
|
19
|
+
else if (check.isObject(packageJson)) {
|
|
20
|
+
return packageJson;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
20
23
|
throw new TypeError(`Parsing package.json file did not return an object in '${dirPath}'`);
|
|
21
24
|
}
|
|
22
|
-
return packageJson;
|
|
23
25
|
}
|
|
@@ -23,8 +23,10 @@ export function doesPathContain({ potentialParentPath, potentialChildPath, optio
|
|
|
23
23
|
/** On Windows, paths on different drives yield an absolute relative path. */
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
else {
|
|
27
|
+
/** Contained if it does not traverse up out of parent. */
|
|
28
|
+
return relativePath !== '..' && !relativePath.startsWith('..' + sep);
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
function normalizePath(inputPath) {
|
|
30
32
|
const absolutePath = normalize(resolve(inputPath));
|
|
@@ -18,6 +18,12 @@ export declare function toPosixPath(maybeWindowsPath: string): string;
|
|
|
18
18
|
* Use this to interpolate paths into bash commands. If the given path is not a Windows path, the
|
|
19
19
|
* path structure will not be modified.
|
|
20
20
|
*
|
|
21
|
+
* Each round of bash parsing halves the backslashes, so the count here assumes _two_ rounds: a
|
|
22
|
+
* command string that bash parses and then hands to something which parses it again. Four
|
|
23
|
+
* backslashes arrive as one. For a command that bash parses only once, this over-escapes; use
|
|
24
|
+
* `shellQuote` from `@augment-vir/common` instead, which needs no multiplication because bash does
|
|
25
|
+
* no escape processing inside single quotes.
|
|
26
|
+
*
|
|
21
27
|
* @category Path : Node
|
|
22
28
|
* @category Package : @augment-vir/node
|
|
23
29
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -34,6 +34,12 @@ export function toPosixPath(maybeWindowsPath) {
|
|
|
34
34
|
* Use this to interpolate paths into bash commands. If the given path is not a Windows path, the
|
|
35
35
|
* path structure will not be modified.
|
|
36
36
|
*
|
|
37
|
+
* Each round of bash parsing halves the backslashes, so the count here assumes _two_ rounds: a
|
|
38
|
+
* command string that bash parses and then hands to something which parses it again. Four
|
|
39
|
+
* backslashes arrive as one. For a command that bash parses only once, this over-escapes; use
|
|
40
|
+
* `shellQuote` from `@augment-vir/common` instead, which needs no multiplication because bash does
|
|
41
|
+
* no escape processing inside single quotes.
|
|
42
|
+
*
|
|
37
43
|
* @category Path : Node
|
|
38
44
|
* @category Package : @augment-vir/node
|
|
39
45
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* node:coverage disable */
|
|
2
2
|
/** This file cannot be tested because it calls `process.exit`. */
|
|
3
3
|
import { check } from '@augment-vir/assert';
|
|
4
|
+
import { shellQuote } from '@augment-vir/common';
|
|
4
5
|
import { dirname, extname } from 'node:path';
|
|
5
6
|
import { findNpmBinPath } from '../npm/find-bin-path.js';
|
|
6
|
-
import { interpolationSafeWindowsPath } from '../path/os-path.js';
|
|
7
7
|
import { extractRelevantArgs } from './relevant-args.js';
|
|
8
8
|
import { runShellCommand } from './shell.js';
|
|
9
9
|
/**
|
|
@@ -44,11 +44,13 @@ export async function runCliScript({ scriptPath, cliScriptFilePath, binName, })
|
|
|
44
44
|
binName: runner.npx,
|
|
45
45
|
startPath: dirname(cliScriptFilePath),
|
|
46
46
|
}) || runner.npx;
|
|
47
|
-
const results = await runShellCommand(
|
|
47
|
+
const results = await runShellCommand([
|
|
48
48
|
runnerPath,
|
|
49
49
|
scriptPath,
|
|
50
50
|
...args,
|
|
51
|
-
]
|
|
51
|
+
]
|
|
52
|
+
.map(shellQuote)
|
|
53
|
+
.join(' '), {
|
|
52
54
|
hookUpToConsole: true,
|
|
53
55
|
});
|
|
54
56
|
process.exit(results.exitCode || 0);
|
|
@@ -11,7 +11,9 @@ import { findAncestor } from '../path/ancestor.js';
|
|
|
11
11
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
12
12
|
*/
|
|
13
13
|
export function readTsconfig(startingPath) {
|
|
14
|
-
const tsconfigDirPath = findAncestor(startingPath, (ancestorPath) =>
|
|
14
|
+
const tsconfigDirPath = findAncestor(startingPath, (ancestorPath) => {
|
|
15
|
+
return existsSync(join(ancestorPath, 'tsconfig.json'));
|
|
16
|
+
});
|
|
15
17
|
const tsconfigPath = tsconfigDirPath ? join(tsconfigDirPath, 'tsconfig.json') : undefined;
|
|
16
18
|
if (!tsconfigPath) {
|
|
17
19
|
return undefined;
|
|
@@ -57,7 +57,7 @@ async function updateAllPackageJsonPaths(monoRepoPath) {
|
|
|
57
57
|
async function fixAllSrcImports(monoRepoPath) {
|
|
58
58
|
const filePaths = await findFilesThatNeedImportFixes(monoRepoPath);
|
|
59
59
|
await Promise.all(filePaths.map(async (filePath) => {
|
|
60
|
-
const contents =
|
|
60
|
+
const contents = await readFile(filePath, 'utf8');
|
|
61
61
|
const fixedContents = contents.replaceAll(/(from ["'][^'"]+?)\/src\/([^'"]+)['"];/g, "$1/dist/$2';");
|
|
62
62
|
await writeFile(filePath, fixedContents);
|
|
63
63
|
log.faint(`Fixed imports in ${relative(monoRepoPath, filePath)}`);
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
import { log } from '@augment-vir/common';
|
|
18
|
-
import {
|
|
19
|
-
import { readFile, rm, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { chmod, readFile, rm, writeFile } from 'node:fs/promises';
|
|
20
19
|
import { join, sep } from 'node:path/posix';
|
|
21
20
|
const packagesToFix = [
|
|
22
21
|
{
|
|
@@ -63,7 +62,7 @@ async function fixTsBin(packageToFix) {
|
|
|
63
62
|
force: true,
|
|
64
63
|
});
|
|
65
64
|
await writeFile(binFilePath, createBinFileContents(packageToFix));
|
|
66
|
-
await
|
|
65
|
+
await chmod(binFilePath, 0o755);
|
|
67
66
|
await fixPackageJson(packageToFix);
|
|
68
67
|
log.success(`Fixed ${packageToFix.packageName} bin.`);
|
|
69
68
|
}
|
|
@@ -72,7 +71,7 @@ async function fixPackageJson(packageToFix) {
|
|
|
72
71
|
return;
|
|
73
72
|
}
|
|
74
73
|
const packageJsonPath = join(process.cwd(), 'node_modules', packageToFix.packageName, 'package.json');
|
|
75
|
-
const original =
|
|
74
|
+
const original = await readFile(packageJsonPath, 'utf8');
|
|
76
75
|
await writeFile(packageJsonPath, original
|
|
77
76
|
.replace('"main": "dist/index.js"', '"main": "src/index.ts"')
|
|
78
77
|
.replace('"module": "dist/index.js"', '"module": "src/index.ts"'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augment-vir/node",
|
|
3
|
-
"version": "32.2.
|
|
3
|
+
"version": "32.2.2",
|
|
4
4
|
"description": "A collection of augments, helpers types, functions, and classes only for Node.js (backend) JavaScript environments.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augment",
|
|
@@ -38,22 +38,22 @@
|
|
|
38
38
|
"test:update": "npm test"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@augment-vir/assert": "^32.2.
|
|
42
|
-
"@augment-vir/common": "^32.2.
|
|
43
|
-
"@date-vir/duration": "^
|
|
44
|
-
"ansi-styles": "^
|
|
41
|
+
"@augment-vir/assert": "^32.2.2",
|
|
42
|
+
"@augment-vir/common": "^32.2.2",
|
|
43
|
+
"@date-vir/duration": "^9.0.0",
|
|
44
|
+
"ansi-styles": "^7.0.0",
|
|
45
45
|
"sanitize-filename": "^1.6.4",
|
|
46
46
|
"terminate": "^2.8.0",
|
|
47
|
-
"tsx": "^4.
|
|
48
|
-
"typed-event-target": "^4.3.
|
|
47
|
+
"tsx": "^4.23.11",
|
|
48
|
+
"typed-event-target": "^4.3.3"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@augment-vir/test": "^32.2.
|
|
52
|
-
"@types/node": "^26.0
|
|
53
|
-
"@web/dev-server-esbuild": "^
|
|
54
|
-
"@web/test-runner": "^0.
|
|
55
|
-
"@web/test-runner-playwright": "^0.
|
|
56
|
-
"c8": "^
|
|
51
|
+
"@augment-vir/test": "^32.2.2",
|
|
52
|
+
"@types/node": "^26.2.0",
|
|
53
|
+
"@web/dev-server-esbuild": "^2.0.0",
|
|
54
|
+
"@web/test-runner": "^1.0.0",
|
|
55
|
+
"@web/test-runner-playwright": "^1.0.0",
|
|
56
|
+
"c8": "^12.0.0",
|
|
57
57
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
58
58
|
"typescript": "^6.0.3"
|
|
59
59
|
},
|
|
@@ -2,6 +2,7 @@ import {check} from '@augment-vir/assert';
|
|
|
2
2
|
import {getObjectTypedEntries} from '@augment-vir/common';
|
|
3
3
|
import {readdir, readFile, rm, stat} from 'node:fs/promises';
|
|
4
4
|
import {join} from 'node:path';
|
|
5
|
+
import {doesPathContain} from '../path/contains.js';
|
|
5
6
|
import {writeFileAndDir} from './write.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -52,7 +53,7 @@ export async function readAllDirContents(
|
|
|
52
53
|
|
|
53
54
|
const isFile = (await stat(filePath)).isFile();
|
|
54
55
|
const contents = isFile
|
|
55
|
-
?
|
|
56
|
+
? await readFile(filePath, 'utf8')
|
|
56
57
|
: recursive
|
|
57
58
|
? await readAllDirContents(filePath, {
|
|
58
59
|
recursive,
|
|
@@ -98,6 +99,10 @@ export async function resetDirContents(
|
|
|
98
99
|
/**
|
|
99
100
|
* Write {@link DirContents} to a directory.
|
|
100
101
|
*
|
|
102
|
+
* Keys are always relative to `rootDir`. A key that traverses above it (such as `'../escaped.txt'`)
|
|
103
|
+
* throws instead of writing, so contents built from an untrusted source cannot reach outside the
|
|
104
|
+
* directory they were meant for.
|
|
105
|
+
*
|
|
101
106
|
* @category Node : File
|
|
102
107
|
* @category Package : @augment-vir/node
|
|
103
108
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -113,6 +118,18 @@ export async function writeDirContents(
|
|
|
113
118
|
content,
|
|
114
119
|
]) => {
|
|
115
120
|
const fullPath = join(rootDir, relativePath);
|
|
121
|
+
|
|
122
|
+
if (
|
|
123
|
+
!doesPathContain({
|
|
124
|
+
potentialParentPath: rootDir,
|
|
125
|
+
potentialChildPath: fullPath,
|
|
126
|
+
})
|
|
127
|
+
) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Cannot write '${relativePath}': it resolves outside of '${rootDir}'.`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
116
133
|
if (check.isString(content)) {
|
|
117
134
|
await writeFileAndDir(fullPath, content);
|
|
118
135
|
} else {
|
package/src/augments/fs/grep.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
awaitedBlockingMap,
|
|
4
4
|
getObjectTypedKeys,
|
|
5
5
|
log,
|
|
6
|
+
shellQuote,
|
|
6
7
|
typedObjectFromEntries,
|
|
7
8
|
type IsEqual,
|
|
8
9
|
type PartialWithUndefined,
|
|
@@ -180,31 +181,23 @@ export type GrepSearchPattern = RequireExactlyOne<{
|
|
|
180
181
|
|
|
181
182
|
const grepBinPath = '/usr/bin/grep';
|
|
182
183
|
|
|
183
|
-
function shellQuote(input: string) {
|
|
184
|
-
return [
|
|
185
|
-
"'",
|
|
186
|
-
input.replaceAll("'", String.raw`'\''`),
|
|
187
|
-
"'",
|
|
188
|
-
].join('');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
184
|
function recursiveFlag({
|
|
192
185
|
recursive,
|
|
193
186
|
followSymLinks,
|
|
194
187
|
}: Readonly<Pick<GrepOptions, 'recursive' | 'followSymLinks'>>): string {
|
|
195
188
|
if (!recursive) {
|
|
196
189
|
return '';
|
|
197
|
-
} else if (
|
|
190
|
+
} else if (followSymLinks) {
|
|
191
|
+
/**
|
|
192
|
+
* BSD `grep` (macOS) requires `-S` to follow symlinks while recursing, but GNU `grep`
|
|
193
|
+
* (Linux) has no `-S` flag and instead follows all symlinks with `-R`. Only one of these
|
|
194
|
+
* branches can run on a given operating system.
|
|
195
|
+
*/
|
|
196
|
+
/* node:coverage ignore next */
|
|
197
|
+
return isOperatingSystem(OperatingSystem.Mac) ? '-RS' : '-R';
|
|
198
|
+
} else {
|
|
198
199
|
return '--recursive';
|
|
199
200
|
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* BSD `grep` (macOS) requires `-S` to follow symlinks while recursing, but GNU `grep` (Linux)
|
|
203
|
-
* has no `-S` flag and instead follows all symlinks with `-R`. Only one of these branches can
|
|
204
|
-
* run on a given operating system.
|
|
205
|
-
*/
|
|
206
|
-
/* node:coverage ignore next */
|
|
207
|
-
return isOperatingSystem(OperatingSystem.Mac) ? '-RS' : '-R';
|
|
208
201
|
}
|
|
209
202
|
|
|
210
203
|
function isValidMaxCount(maxCount: unknown) {
|
|
@@ -380,16 +373,16 @@ function formatGrepCommand(args: ReadonlyArray<string>) {
|
|
|
380
373
|
|
|
381
374
|
return [
|
|
382
375
|
'grep',
|
|
383
|
-
...args.map((arg, index) =>
|
|
384
|
-
shellQuote(
|
|
376
|
+
...args.map((arg, index) => {
|
|
377
|
+
return shellQuote(
|
|
385
378
|
redactGrepArgForLogging({
|
|
386
379
|
arg,
|
|
387
380
|
index,
|
|
388
381
|
operandDelimiterIndex,
|
|
389
382
|
previousArg: args[index - 1],
|
|
390
383
|
}),
|
|
391
|
-
)
|
|
392
|
-
),
|
|
384
|
+
);
|
|
385
|
+
}),
|
|
393
386
|
].join(' ');
|
|
394
387
|
}
|
|
395
388
|
|
|
@@ -430,9 +423,9 @@ function extractOptionalStringArray(input: unknown) {
|
|
|
430
423
|
return [];
|
|
431
424
|
} else if (!check.isArray(input) || !input.every(check.isString)) {
|
|
432
425
|
return undefined;
|
|
426
|
+
} else {
|
|
427
|
+
return input.filter(check.isTruthy);
|
|
433
428
|
}
|
|
434
|
-
|
|
435
|
-
return input.filter(check.isTruthy);
|
|
436
429
|
}
|
|
437
430
|
|
|
438
431
|
function extractString(input: unknown) {
|
|
@@ -519,19 +512,19 @@ function createSearchLocation(
|
|
|
519
512
|
file,
|
|
520
513
|
],
|
|
521
514
|
};
|
|
522
|
-
} else if (grepSearchLocation.dirs
|
|
515
|
+
} else if (grepSearchLocation.dirs == undefined) {
|
|
516
|
+
return dir
|
|
517
|
+
? {
|
|
518
|
+
dirs: [
|
|
519
|
+
dir,
|
|
520
|
+
],
|
|
521
|
+
}
|
|
522
|
+
: undefined;
|
|
523
|
+
} else {
|
|
523
524
|
return {
|
|
524
525
|
dirs: extractStringArray(grepSearchLocation.dirs),
|
|
525
526
|
};
|
|
526
527
|
}
|
|
527
|
-
|
|
528
|
-
return dir
|
|
529
|
-
? {
|
|
530
|
-
dirs: [
|
|
531
|
-
dir,
|
|
532
|
-
],
|
|
533
|
-
}
|
|
534
|
-
: undefined;
|
|
535
528
|
}
|
|
536
529
|
|
|
537
530
|
function resolveSearchPart({
|
|
@@ -657,13 +650,13 @@ async function createSearchParts({
|
|
|
657
650
|
? recursive
|
|
658
651
|
? filteredSearchParts
|
|
659
652
|
: (
|
|
660
|
-
await awaitedBlockingMap(filteredSearchParts, (dir) =>
|
|
661
|
-
readDirectDirSearchParts({
|
|
653
|
+
await awaitedBlockingMap(filteredSearchParts, (dir) => {
|
|
654
|
+
return readDirectDirSearchParts({
|
|
662
655
|
cwd,
|
|
663
656
|
dir,
|
|
664
657
|
followSymLinks,
|
|
665
|
-
})
|
|
666
|
-
)
|
|
658
|
+
});
|
|
659
|
+
})
|
|
667
660
|
).flat()
|
|
668
661
|
: filteredSearchParts;
|
|
669
662
|
}
|
|
@@ -724,7 +717,7 @@ function parseNullDelimitedGrepRecords({stdout}: Readonly<{stdout: string}>) {
|
|
|
724
717
|
return records;
|
|
725
718
|
}
|
|
726
719
|
|
|
727
|
-
/* node:coverage ignore next
|
|
720
|
+
/* node:coverage ignore next 28 */
|
|
728
721
|
function parseColonDelimitedGrepCountOutput(stdout: string) {
|
|
729
722
|
return typedObjectFromEntries(
|
|
730
723
|
stdout
|
|
@@ -745,14 +738,16 @@ function parseColonDelimitedGrepCountOutput(stdout: string) {
|
|
|
745
738
|
});
|
|
746
739
|
})
|
|
747
740
|
.filter(check.isTruthy)
|
|
748
|
-
.map((entry) =>
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
741
|
+
.map((entry) => {
|
|
742
|
+
return [
|
|
743
|
+
entry.key,
|
|
744
|
+
entry.value,
|
|
745
|
+
];
|
|
746
|
+
}),
|
|
752
747
|
);
|
|
753
748
|
}
|
|
754
749
|
|
|
755
|
-
/* node:coverage ignore next
|
|
750
|
+
/* node:coverage ignore next 22 */
|
|
756
751
|
function parseGrepCountOutput(stdout: string) {
|
|
757
752
|
return stdout.includes('\0')
|
|
758
753
|
? typedObjectFromEntries(
|
|
@@ -766,10 +761,12 @@ function parseGrepCountOutput(stdout: string) {
|
|
|
766
761
|
});
|
|
767
762
|
})
|
|
768
763
|
.filter(check.isTruthy)
|
|
769
|
-
.map((entry) =>
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
764
|
+
.map((entry) => {
|
|
765
|
+
return [
|
|
766
|
+
entry.key,
|
|
767
|
+
entry.value,
|
|
768
|
+
];
|
|
769
|
+
}),
|
|
773
770
|
)
|
|
774
771
|
: parseColonDelimitedGrepCountOutput(stdout);
|
|
775
772
|
}
|
|
@@ -885,10 +882,12 @@ async function runGrepCountFallback({
|
|
|
885
882
|
)
|
|
886
883
|
)
|
|
887
884
|
.filter(check.isTruthy)
|
|
888
|
-
.map((entry) =>
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
885
|
+
.map((entry) => {
|
|
886
|
+
return [
|
|
887
|
+
entry.key,
|
|
888
|
+
entry.value,
|
|
889
|
+
];
|
|
890
|
+
}),
|
|
892
891
|
);
|
|
893
892
|
}
|
|
894
893
|
|
|
@@ -897,10 +896,12 @@ function parseGrepFilesOnlyOutput(stdout: string) {
|
|
|
897
896
|
/* node:coverage ignore next */
|
|
898
897
|
(stdout.includes('\0') ? stdout.split('\0') : stdout.trimEnd().split('\n'))
|
|
899
898
|
.filter(check.isTruthy)
|
|
900
|
-
.map((entry) =>
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
899
|
+
.map((entry) => {
|
|
900
|
+
return [
|
|
901
|
+
entry,
|
|
902
|
+
[],
|
|
903
|
+
];
|
|
904
|
+
}),
|
|
904
905
|
);
|
|
905
906
|
}
|
|
906
907
|
|
|
@@ -1025,10 +1026,12 @@ export async function grep<const CountOnly extends boolean = false>(
|
|
|
1025
1026
|
? grepOptionArrays.includeFiles.map((includeFile) => `--include=${includeFile}`)
|
|
1026
1027
|
: []),
|
|
1027
1028
|
grepOptions.binary ? '--binary' : '',
|
|
1028
|
-
...searchPatterns.flatMap((searchPattern) =>
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1029
|
+
...searchPatterns.flatMap((searchPattern) => {
|
|
1030
|
+
return [
|
|
1031
|
+
'-e',
|
|
1032
|
+
searchPattern,
|
|
1033
|
+
];
|
|
1034
|
+
}),
|
|
1032
1035
|
'--',
|
|
1033
1036
|
...searchParts,
|
|
1034
1037
|
].filter(check.isTruthy);
|
package/src/augments/fs/json.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {writeFileAndDir} from './write.js';
|
|
|
22
22
|
*/
|
|
23
23
|
export async function readJsonFile(path: string): Promise<JsonCompatibleValue | undefined> {
|
|
24
24
|
try {
|
|
25
|
-
const contents =
|
|
25
|
+
const contents = await readFile(path, 'utf8');
|
|
26
26
|
return JSON.parse(contents);
|
|
27
27
|
} catch {
|
|
28
28
|
return undefined;
|
|
@@ -63,7 +63,7 @@ export async function readDirFilesByExtension({
|
|
|
63
63
|
|
|
64
64
|
const fileNames = await readdir(dirPath);
|
|
65
65
|
|
|
66
|
-
return fileNames.filter((fileName) =>
|
|
67
|
-
extensionsToCheck.some((extensionToCheck) => fileName.endsWith(extensionToCheck))
|
|
68
|
-
);
|
|
66
|
+
return fileNames.filter((fileName) => {
|
|
67
|
+
return extensionsToCheck.some((extensionToCheck) => fileName.endsWith(extensionToCheck));
|
|
68
|
+
});
|
|
69
69
|
}
|
|
@@ -11,7 +11,7 @@ import {readFile} from 'node:fs/promises';
|
|
|
11
11
|
*/
|
|
12
12
|
export async function readFileIfExists(path: string): Promise<string | undefined> {
|
|
13
13
|
if (existsSync(path)) {
|
|
14
|
-
return
|
|
14
|
+
return await readFile(path, 'utf8');
|
|
15
15
|
} else {
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
@@ -16,9 +16,9 @@ import {findAncestor, joinFilesToDir} from '../path/ancestor.js';
|
|
|
16
16
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
17
17
|
*/
|
|
18
18
|
export async function findAllPackageJsonFilePaths(startDirPath: string) {
|
|
19
|
-
const packageRootDir = findAncestor(startDirPath, (dir) =>
|
|
20
|
-
existsSync(join(dir, 'package-lock.json'))
|
|
21
|
-
);
|
|
19
|
+
const packageRootDir = findAncestor(startDirPath, (dir) => {
|
|
20
|
+
return existsSync(join(dir, 'package-lock.json'));
|
|
21
|
+
});
|
|
22
22
|
|
|
23
23
|
if (!packageRootDir) {
|
|
24
24
|
throw new Error(
|
|
@@ -18,9 +18,9 @@ export async function readPackageJson(dirPath: string): Promise<PackageJson> {
|
|
|
18
18
|
|
|
19
19
|
if (!packageJson) {
|
|
20
20
|
throw new TypeError(`package.json file does not exist in '${dirPath}'`);
|
|
21
|
-
} else if (
|
|
21
|
+
} else if (check.isObject(packageJson)) {
|
|
22
|
+
return packageJson;
|
|
23
|
+
} else {
|
|
22
24
|
throw new TypeError(`Parsing package.json file did not return an object in '${dirPath}'`);
|
|
23
25
|
}
|
|
24
|
-
|
|
25
|
-
return packageJson;
|
|
26
26
|
}
|
|
@@ -41,10 +41,10 @@ export function doesPathContain({
|
|
|
41
41
|
} else if (isAbsolute(relativePath)) {
|
|
42
42
|
/** On Windows, paths on different drives yield an absolute relative path. */
|
|
43
43
|
return false;
|
|
44
|
+
} else {
|
|
45
|
+
/** Contained if it does not traverse up out of parent. */
|
|
46
|
+
return relativePath !== '..' && !relativePath.startsWith('..' + sep);
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
/** Contained if it does not traverse up out of parent. */
|
|
47
|
-
return relativePath !== '..' && !relativePath.startsWith('..' + sep);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function normalizePath(inputPath: string): string {
|
|
@@ -36,6 +36,12 @@ export function toPosixPath(maybeWindowsPath: string): string {
|
|
|
36
36
|
* Use this to interpolate paths into bash commands. If the given path is not a Windows path, the
|
|
37
37
|
* path structure will not be modified.
|
|
38
38
|
*
|
|
39
|
+
* Each round of bash parsing halves the backslashes, so the count here assumes _two_ rounds: a
|
|
40
|
+
* command string that bash parses and then hands to something which parses it again. Four
|
|
41
|
+
* backslashes arrive as one. For a command that bash parses only once, this over-escapes; use
|
|
42
|
+
* `shellQuote` from `@augment-vir/common` instead, which needs no multiplication because bash does
|
|
43
|
+
* no escape processing inside single quotes.
|
|
44
|
+
*
|
|
39
45
|
* @category Path : Node
|
|
40
46
|
* @category Package : @augment-vir/node
|
|
41
47
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/** This file cannot be tested because it calls `process.exit`. */
|
|
3
3
|
|
|
4
4
|
import {check} from '@augment-vir/assert';
|
|
5
|
+
import {shellQuote} from '@augment-vir/common';
|
|
5
6
|
import {dirname, extname} from 'node:path';
|
|
6
7
|
import {findNpmBinPath} from '../npm/find-bin-path.js';
|
|
7
|
-
import {interpolationSafeWindowsPath} from '../path/os-path.js';
|
|
8
8
|
import {extractRelevantArgs} from './relevant-args.js';
|
|
9
9
|
import {runShellCommand} from './shell.js';
|
|
10
10
|
|
|
@@ -57,13 +57,13 @@ export async function runCliScript({
|
|
|
57
57
|
}) || runner.npx;
|
|
58
58
|
|
|
59
59
|
const results = await runShellCommand(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
[
|
|
61
|
+
runnerPath,
|
|
62
|
+
scriptPath,
|
|
63
|
+
...args,
|
|
64
|
+
]
|
|
65
|
+
.map(shellQuote)
|
|
66
|
+
.join(' '),
|
|
67
67
|
{
|
|
68
68
|
hookUpToConsole: true,
|
|
69
69
|
},
|
|
@@ -12,9 +12,9 @@ import {findAncestor} from '../path/ancestor.js';
|
|
|
12
12
|
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
13
13
|
*/
|
|
14
14
|
export function readTsconfig(startingPath: string) {
|
|
15
|
-
const tsconfigDirPath = findAncestor(startingPath, (ancestorPath) =>
|
|
16
|
-
existsSync(join(ancestorPath, 'tsconfig.json'))
|
|
17
|
-
);
|
|
15
|
+
const tsconfigDirPath = findAncestor(startingPath, (ancestorPath) => {
|
|
16
|
+
return existsSync(join(ancestorPath, 'tsconfig.json'));
|
|
17
|
+
});
|
|
18
18
|
const tsconfigPath = tsconfigDirPath ? join(tsconfigDirPath, 'tsconfig.json') : undefined;
|
|
19
19
|
|
|
20
20
|
if (!tsconfigPath) {
|
|
@@ -76,7 +76,7 @@ async function fixAllSrcImports(monoRepoPath: string) {
|
|
|
76
76
|
|
|
77
77
|
await Promise.all(
|
|
78
78
|
filePaths.map(async (filePath) => {
|
|
79
|
-
const contents =
|
|
79
|
+
const contents = await readFile(filePath, 'utf8');
|
|
80
80
|
const fixedContents = contents.replaceAll(
|
|
81
81
|
/(from ["'][^'"]+?)\/src\/([^'"]+)['"];/g,
|
|
82
82
|
"$1/dist/$2';",
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import {log} from '@augment-vir/common';
|
|
20
|
-
import {
|
|
21
|
-
import {readFile, rm, writeFile} from 'node:fs/promises';
|
|
20
|
+
import {chmod, readFile, rm, writeFile} from 'node:fs/promises';
|
|
22
21
|
import {join, sep} from 'node:path/posix';
|
|
23
22
|
|
|
24
23
|
type PackageToFix = {
|
|
@@ -75,7 +74,7 @@ async function fixTsBin(packageToFix: Readonly<PackageToFix>) {
|
|
|
75
74
|
force: true,
|
|
76
75
|
});
|
|
77
76
|
await writeFile(binFilePath, createBinFileContents(packageToFix));
|
|
78
|
-
await
|
|
77
|
+
await chmod(binFilePath, 0o755);
|
|
79
78
|
await fixPackageJson(packageToFix);
|
|
80
79
|
log.success(`Fixed ${packageToFix.packageName} bin.`);
|
|
81
80
|
}
|
|
@@ -91,7 +90,7 @@ async function fixPackageJson(packageToFix: Readonly<PackageToFix>) {
|
|
|
91
90
|
packageToFix.packageName,
|
|
92
91
|
'package.json',
|
|
93
92
|
);
|
|
94
|
-
const original =
|
|
93
|
+
const original = await readFile(packageJsonPath, 'utf8');
|
|
95
94
|
await writeFile(
|
|
96
95
|
packageJsonPath,
|
|
97
96
|
original
|