socket-function 1.2.34 → 1.2.36
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/SocketFunction.d.ts +0 -1
- package/index.d.ts +1 -15
- package/package.json +1 -1
- package/require/RequireController.d.ts +0 -1
- package/require/extMapper.d.ts +0 -1
- package/src/CallFactory.d.ts +0 -1
- package/src/JSONLACKS/JSONLACKS.d.ts +0 -1
- package/src/Zip.d.ts +0 -1
- package/src/bits.d.ts +0 -1
- package/src/buffers.d.ts +0 -1
- package/src/callHTTPHandler.d.ts +0 -1
- package/src/certStore.d.ts +0 -1
- package/src/https.d.ts +0 -1
- package/src/lz4/LZ4.d.ts +0 -1
- package/src/misc.d.ts +0 -1
- package/src/runPromise.d.ts +1 -0
- package/src/runPromise.ts +4 -1
- package/src/tlsParsing.d.ts +0 -1
- package/src/upreal.ts +189 -67
- package/src/webSocketServer.d.ts +0 -1
package/SocketFunction.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/// <reference path="require/RequireController.d.ts" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
3
|
import { SocketExposedInterface, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, CallerContext, FullCallType, SocketRegisterType } from "./SocketFunctionTypes";
|
|
5
4
|
import { SocketServerConfig } from "./src/webSocketServer";
|
|
6
5
|
import { Args, MaybePromise } from "./src/types";
|
package/index.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ declare module "socket-function/SetProcessVariables" {
|
|
|
9
9
|
declare module "socket-function/SocketFunction" {
|
|
10
10
|
/// <reference path="require/RequireController.d.ts" />
|
|
11
11
|
/// <reference types="node" />
|
|
12
|
-
/// <reference types="node" />
|
|
13
12
|
import { SocketExposedInterface, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, CallerContext, FullCallType, SocketRegisterType } from "socket-function/SocketFunctionTypes";
|
|
14
13
|
import { SocketServerConfig } from "socket-function/src/webSocketServer";
|
|
15
14
|
import { Args, MaybePromise } from "socket-function/src/types";
|
|
@@ -321,7 +320,6 @@ declare module "socket-function/require/CSSShim" {
|
|
|
321
320
|
declare module "socket-function/require/RequireController" {
|
|
322
321
|
/// <reference path="../../typenode/index.d.ts" />
|
|
323
322
|
/// <reference types="node" />
|
|
324
|
-
/// <reference types="node" />
|
|
325
323
|
declare global {
|
|
326
324
|
namespace NodeJS {
|
|
327
325
|
interface Module {
|
|
@@ -451,7 +449,6 @@ declare module "socket-function/require/compileFlags" {
|
|
|
451
449
|
}
|
|
452
450
|
|
|
453
451
|
declare module "socket-function/require/extMapper" {
|
|
454
|
-
/// <reference types="node" />
|
|
455
452
|
/// <reference types="node" />
|
|
456
453
|
export declare function getExtContentType(ext: string): string;
|
|
457
454
|
export declare function getContentTypeFromBuffer(buffer: Buffer): string | undefined;
|
|
@@ -477,7 +474,6 @@ declare module "socket-function/require/require" {
|
|
|
477
474
|
}
|
|
478
475
|
|
|
479
476
|
declare module "socket-function/src/CallFactory" {
|
|
480
|
-
/// <reference types="node" />
|
|
481
477
|
/// <reference types="node" />
|
|
482
478
|
/// <reference types="node" />
|
|
483
479
|
import { CallType } from "socket-function/SocketFunctionTypes";
|
|
@@ -536,7 +532,6 @@ declare module "socket-function/src/CallFactory" {
|
|
|
536
532
|
}
|
|
537
533
|
|
|
538
534
|
declare module "socket-function/src/JSONLACKS/JSONLACKS" {
|
|
539
|
-
/// <reference types="node" />
|
|
540
535
|
/// <reference types="node" />
|
|
541
536
|
export interface JSONLACKS_ParseConfig {
|
|
542
537
|
extended?: boolean;
|
|
@@ -572,7 +567,6 @@ declare module "socket-function/src/JSONLACKS/JSONLACKS.generated.js" {
|
|
|
572
567
|
}
|
|
573
568
|
|
|
574
569
|
declare module "socket-function/src/Zip" {
|
|
575
|
-
/// <reference types="node" />
|
|
576
570
|
/// <reference types="node" />
|
|
577
571
|
import { MaybePromise } from "socket-function/src/types";
|
|
578
572
|
export declare class Zip {
|
|
@@ -660,7 +654,6 @@ declare module "socket-function/src/batching" {
|
|
|
660
654
|
}
|
|
661
655
|
|
|
662
656
|
declare module "socket-function/src/bits" {
|
|
663
|
-
/// <reference types="node" />
|
|
664
657
|
/// <reference types="node" />
|
|
665
658
|
/** Subtracts the smallest possible value from a number (a double). This makes it possible to convert an exclusive range end
|
|
666
659
|
* to an inclusive range end, which is sometimes required (as in, < x is the same as <= minusEpsilon(x)).
|
|
@@ -687,7 +680,6 @@ declare module "socket-function/src/bits" {
|
|
|
687
680
|
}
|
|
688
681
|
|
|
689
682
|
declare module "socket-function/src/buffers" {
|
|
690
|
-
/// <reference types="node" />
|
|
691
683
|
/// <reference types="node" />
|
|
692
684
|
export type ArrayBufferViewTypes = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float64Array | Float32Array | Uint8ClampedArray;
|
|
693
685
|
export type BufferType = ArrayBuffer | SharedArrayBuffer | ArrayBufferViewTypes;
|
|
@@ -765,7 +757,6 @@ declare module "socket-function/src/caching" {
|
|
|
765
757
|
}
|
|
766
758
|
|
|
767
759
|
declare module "socket-function/src/callHTTPHandler" {
|
|
768
|
-
/// <reference types="node" />
|
|
769
760
|
/// <reference types="node" />
|
|
770
761
|
/// <reference types="node" />
|
|
771
762
|
import http from "http";
|
|
@@ -820,7 +811,6 @@ declare module "socket-function/src/callManager" {
|
|
|
820
811
|
}
|
|
821
812
|
|
|
822
813
|
declare module "socket-function/src/certStore" {
|
|
823
|
-
/// <reference types="node" />
|
|
824
814
|
/// <reference types="node" />
|
|
825
815
|
/** Must be populated before the server starts */
|
|
826
816
|
export declare function trustCertificate(cert: string | Buffer): void;
|
|
@@ -1056,7 +1046,6 @@ declare module "socket-function/src/getUniqueTime" {
|
|
|
1056
1046
|
}
|
|
1057
1047
|
|
|
1058
1048
|
declare module "socket-function/src/https" {
|
|
1059
|
-
/// <reference types="node" />
|
|
1060
1049
|
/// <reference types="node" />
|
|
1061
1050
|
export interface HttpsResponseInfo {
|
|
1062
1051
|
statusCode?: number;
|
|
@@ -1076,7 +1065,6 @@ declare module "socket-function/src/https" {
|
|
|
1076
1065
|
}
|
|
1077
1066
|
|
|
1078
1067
|
declare module "socket-function/src/lz4/LZ4" {
|
|
1079
|
-
/// <reference types="node" />
|
|
1080
1068
|
/// <reference types="node" />
|
|
1081
1069
|
export declare class LZ4 {
|
|
1082
1070
|
static compress(data: Buffer): Buffer;
|
|
@@ -1144,7 +1132,6 @@ declare module "socket-function/src/lz4/lz4_wasm_nodejs_bg.wasm" {
|
|
|
1144
1132
|
}
|
|
1145
1133
|
|
|
1146
1134
|
declare module "socket-function/src/misc" {
|
|
1147
|
-
/// <reference types="node" />
|
|
1148
1135
|
/// <reference types="node" />
|
|
1149
1136
|
import { MaybePromise } from "socket-function/src/types";
|
|
1150
1137
|
export declare const timeInSecond = 1000;
|
|
@@ -1510,6 +1497,7 @@ declare module "socket-function/src/runPromise" {
|
|
|
1510
1497
|
quiet?: boolean;
|
|
1511
1498
|
nothrow?: boolean;
|
|
1512
1499
|
detach?: boolean;
|
|
1500
|
+
includeStderrInOutput?: boolean;
|
|
1513
1501
|
}): Promise<string>;
|
|
1514
1502
|
|
|
1515
1503
|
}
|
|
@@ -1575,7 +1563,6 @@ declare module "socket-function/src/storagePath" {
|
|
|
1575
1563
|
}
|
|
1576
1564
|
|
|
1577
1565
|
declare module "socket-function/src/tlsParsing" {
|
|
1578
|
-
/// <reference types="node" />
|
|
1579
1566
|
/// <reference types="node" />
|
|
1580
1567
|
export declare function parseTLSHello(buffer: Buffer): {
|
|
1581
1568
|
extensions: {
|
|
@@ -1605,7 +1592,6 @@ declare module "socket-function/src/upreal" {
|
|
|
1605
1592
|
}
|
|
1606
1593
|
|
|
1607
1594
|
declare module "socket-function/src/webSocketServer" {
|
|
1608
|
-
/// <reference types="node" />
|
|
1609
1595
|
/// <reference types="node" />
|
|
1610
1596
|
/// <reference types="node" />
|
|
1611
1597
|
import https from "https";
|
package/package.json
CHANGED
package/require/extMapper.d.ts
CHANGED
package/src/CallFactory.d.ts
CHANGED
package/src/Zip.d.ts
CHANGED
package/src/bits.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
/** Subtracts the smallest possible value from a number (a double). This makes it possible to convert an exclusive range end
|
|
4
3
|
* to an inclusive range end, which is sometimes required (as in, < x is the same as <= minusEpsilon(x)).
|
|
5
4
|
*/
|
package/src/buffers.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
export type ArrayBufferViewTypes = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float64Array | Float32Array | Uint8ClampedArray;
|
|
4
3
|
export type BufferType = ArrayBuffer | SharedArrayBuffer | ArrayBufferViewTypes;
|
|
5
4
|
export declare function cloneBuffer(data: Buffer): Buffer;
|
package/src/callHTTPHandler.d.ts
CHANGED
package/src/certStore.d.ts
CHANGED
package/src/https.d.ts
CHANGED
package/src/lz4/LZ4.d.ts
CHANGED
package/src/misc.d.ts
CHANGED
package/src/runPromise.d.ts
CHANGED
package/src/runPromise.ts
CHANGED
|
@@ -9,6 +9,7 @@ export async function runPromise(command: string, config?: {
|
|
|
9
9
|
// Never throw, just return the full output
|
|
10
10
|
nothrow?: boolean;
|
|
11
11
|
detach?: boolean;
|
|
12
|
+
includeStderrInOutput?: boolean;
|
|
12
13
|
}) {
|
|
13
14
|
return new Promise<string>((resolve, reject) => {
|
|
14
15
|
if (!config?.quiet) {
|
|
@@ -38,7 +39,9 @@ export async function runPromise(command: string, config?: {
|
|
|
38
39
|
childProc.stderr?.on("data", (data) => {
|
|
39
40
|
const chunk = data.toString();
|
|
40
41
|
stderr += chunk;
|
|
41
|
-
|
|
42
|
+
if (config?.includeStderrInOutput) {
|
|
43
|
+
fullOutput += chunk;
|
|
44
|
+
}
|
|
42
45
|
|
|
43
46
|
// Stream to console unless quiet mode
|
|
44
47
|
if (!config?.quiet) {
|
package/src/tlsParsing.d.ts
CHANGED
package/src/upreal.ts
CHANGED
|
@@ -11,10 +11,23 @@ const DEP_SECTIONS = [
|
|
|
11
11
|
"peerDependencies",
|
|
12
12
|
] as const;
|
|
13
13
|
|
|
14
|
+
// yarn can re-fetch a requesting package's real manifest (instead of trusting our rewritten lockfile entry),
|
|
15
|
+
// which re-introduces the old pinned range. Re-running the rewrite converges then, so allow a few passes.
|
|
16
|
+
const MAX_DEDUPE_PASSES = 3;
|
|
17
|
+
|
|
18
|
+
// Depth at which yarn.lock lists a block's dependencies. Block fields ("version", "resolved") sit shallower,
|
|
19
|
+
// so this is what keeps us from mistaking a field for a dependency entry.
|
|
20
|
+
const LOCK_DEPENDENCY_INDENT = 4;
|
|
21
|
+
|
|
22
|
+
// Yarn itself spells this "--dry-run", so accept that plus every spelling anyone reasonably reaches for.
|
|
23
|
+
const DRY_RUN_FLAGS = ["--dry", "-dry", "--dryrun", "-dryrun", "--dry-run", "-dry-run", "--dry_run", "-dry_run"];
|
|
24
|
+
|
|
14
25
|
async function main() {
|
|
15
|
-
let
|
|
26
|
+
let args = process.argv.slice(2);
|
|
27
|
+
let packageName = args.find(arg => !arg.startsWith("-"));
|
|
28
|
+
let dryRun = args.some(arg => DRY_RUN_FLAGS.includes(arg.toLowerCase()));
|
|
16
29
|
if (!packageName) {
|
|
17
|
-
console.error("Usage: yarn upreal <package-name>");
|
|
30
|
+
console.error("Usage: yarn upreal <package-name> [--dry-run]");
|
|
18
31
|
process.exit(1);
|
|
19
32
|
return;
|
|
20
33
|
}
|
|
@@ -23,60 +36,73 @@ async function main() {
|
|
|
23
36
|
let packageJsonPath = path.join(projectRoot, "package.json");
|
|
24
37
|
let lockPath = path.join(projectRoot, "yarn.lock");
|
|
25
38
|
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
[section: string]: { [name: string]: string } | undefined;
|
|
29
|
-
};
|
|
39
|
+
let latest = await getLatestVersion(packageName);
|
|
40
|
+
console.log(`Latest version of ${packageName}: ${latest}`);
|
|
30
41
|
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
let newRange = updatePackageJson(packageJsonPath, packageName, latest);
|
|
43
|
+
console.log(`Forcing every reference to ${packageName} onto ${newRange}`);
|
|
44
|
+
|
|
45
|
+
for (let pass = 1; pass <= MAX_DEDUPE_PASSES; pass++) {
|
|
46
|
+
if (fs.existsSync(lockPath)) {
|
|
47
|
+
let result = forceLockRange(lockPath, packageName, newRange);
|
|
48
|
+
console.log(`Lockfile pass ${pass}: dropped ${result.removedBlocks} entr${result.removedBlocks === 1 ? "y" : "ies"} for ${packageName}, repointed ${result.rewrittenRequests} request${result.rewrittenRequests === 1 ? "" : "s"} for it to ${newRange}.`);
|
|
49
|
+
for (let skipped of result.skippedRequests) {
|
|
50
|
+
console.log(`Left ${skipped.requestedBy} asking for ${packageName}@${skipped.range} (not a registry range, so it can't be moved).`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
37
53
|
|
|
38
|
-
|
|
54
|
+
if (dryRun) {
|
|
55
|
+
console.log(`Dry run: package.json and yarn.lock are rewritten, skipping yarn install.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
console.log(`Running yarn install...`);
|
|
60
|
+
await runYarnInstall(projectRoot);
|
|
42
61
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
packageJsonRaw = replaceRange(packageJsonRaw, packageName, currentRange, newRange);
|
|
48
|
-
fs.writeFileSync(packageJsonPath, packageJsonRaw);
|
|
49
|
-
console.log(`Updated package.json: ${packageName} ${currentRange} -> ${newRange}`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Drop every lockfile entry for this package so `yarn install` re-resolves each of its ranges (ours and any
|
|
53
|
-
// transitive ones) to the newest version they can reach. This is what makes "everything that could be updated"
|
|
54
|
-
// update in one shot, rather than yarn pinning the previously-locked versions.
|
|
55
|
-
if (fs.existsSync(lockPath)) {
|
|
56
|
-
let lockRaw = fs.readFileSync(lockPath, "utf8");
|
|
57
|
-
let { lock, removed } = removeLockEntries(lockRaw, packageName);
|
|
58
|
-
if (removed > 0) {
|
|
59
|
-
fs.writeFileSync(lockPath, lock);
|
|
60
|
-
console.log(`Removed ${removed} lockfile entr${removed === 1 ? "y" : "ies"} for ${packageName} so they re-resolve.`);
|
|
62
|
+
let versions = getLockedVersions(lockPath, packageName);
|
|
63
|
+
if (versions.length <= 1) {
|
|
64
|
+
console.log(`Done. ${packageName} resolves to a single version: ${versions[0] ?? latest}`);
|
|
65
|
+
return;
|
|
61
66
|
}
|
|
67
|
+
console.log(`${packageName} still resolves to ${versions.length} versions (${versions.join(", ")}); rewriting again.`);
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
let versions = getLockedVersions(lockPath, packageName);
|
|
71
|
+
console.error(`Failed to collapse ${packageName} onto one version after ${MAX_DEDUPE_PASSES} passes; still at ${versions.join(", ")}`);
|
|
72
|
+
process.exit(1);
|
|
67
73
|
}
|
|
68
74
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
// Point every package.json section that mentions the package at the latest version, keeping each section's
|
|
76
|
+
// existing range operator, and return the range we are forcing everything else onto.
|
|
77
|
+
function updatePackageJson(packageJsonPath: string, packageName: string, latest: string): string {
|
|
78
|
+
let raw = fs.readFileSync(packageJsonPath, "utf8");
|
|
79
|
+
let packageJson = JSON.parse(raw) as {
|
|
80
|
+
[section: string]: { [name: string]: string } | undefined;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
let newRange: string | undefined;
|
|
73
84
|
for (let section of DEP_SECTIONS) {
|
|
74
85
|
let deps = packageJson[section];
|
|
75
|
-
if (deps
|
|
76
|
-
|
|
86
|
+
if (!deps || !(packageName in deps)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
let currentRange = deps[packageName];
|
|
90
|
+
let sectionRange = applyPrefix(currentRange, latest);
|
|
91
|
+
newRange = newRange ?? sectionRange;
|
|
92
|
+
if (sectionRange === currentRange) {
|
|
93
|
+
console.log(`package.json ${section}.${packageName} already ${currentRange}`);
|
|
94
|
+
continue;
|
|
77
95
|
}
|
|
96
|
+
raw = replaceRange(raw, packageName, currentRange, sectionRange);
|
|
97
|
+
fs.writeFileSync(packageJsonPath, raw);
|
|
98
|
+
console.log(`Updated package.json ${section}.${packageName}: ${currentRange} -> ${sectionRange}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (newRange === undefined) {
|
|
102
|
+
console.log(`${packageName} is not a direct dependency; only deduplicating transitive references.`);
|
|
103
|
+
return "^" + latest;
|
|
78
104
|
}
|
|
79
|
-
return
|
|
105
|
+
return newRange;
|
|
80
106
|
}
|
|
81
107
|
|
|
82
108
|
async function getLatestVersion(packageName: string): Promise<string> {
|
|
@@ -120,37 +146,50 @@ function replaceRange(packageJsonRaw: string, packageName: string, oldRange: str
|
|
|
120
146
|
return packageJsonRaw.replace(keyPattern, `$1${newRange}$2`);
|
|
121
147
|
}
|
|
122
148
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
interface LockBlock {
|
|
150
|
+
// Index of the header line, and the exclusive end of the block (trailing blank lines included).
|
|
151
|
+
start: number;
|
|
152
|
+
end: number;
|
|
153
|
+
specs: string[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
interface LockFile {
|
|
157
|
+
lines: string[];
|
|
158
|
+
eol: string;
|
|
159
|
+
blocks: LockBlock[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function readLock(lockPath: string): LockFile {
|
|
163
|
+
let raw = fs.readFileSync(lockPath, "utf8");
|
|
164
|
+
let eol = raw.includes("\r\n") ? "\r\n" : "\n";
|
|
165
|
+
let lines = raw.split(/\r?\n/);
|
|
166
|
+
|
|
167
|
+
let blocks: LockBlock[] = [];
|
|
168
|
+
let current: LockBlock | undefined;
|
|
169
|
+
for (let i = 0; i < lines.length; i++) {
|
|
170
|
+
let line = lines[i];
|
|
171
|
+
if (isBlockHeader(line)) {
|
|
172
|
+
if (current) {
|
|
173
|
+
current.end = i;
|
|
174
|
+
}
|
|
175
|
+
current = { start: i, end: lines.length, specs: parseHeaderSpecs(line) };
|
|
176
|
+
blocks.push(current);
|
|
134
177
|
}
|
|
135
|
-
kept.push(block);
|
|
136
178
|
}
|
|
137
|
-
return {
|
|
179
|
+
return { lines, eol, blocks };
|
|
138
180
|
}
|
|
139
181
|
|
|
140
|
-
function
|
|
141
|
-
|
|
142
|
-
if (!headerLine || !headerLine.trimEnd().endsWith(":")) {
|
|
182
|
+
function isBlockHeader(line: string): boolean {
|
|
183
|
+
if (!line || line.startsWith("#") || /^\s/.test(line)) {
|
|
143
184
|
return false;
|
|
144
185
|
}
|
|
145
|
-
|
|
186
|
+
return line.trimEnd().endsWith(":");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function parseHeaderSpecs(headerLine: string): string[] {
|
|
190
|
+
// e.g. `"pkg@^1.0.0", "pkg@~1.2.0":` -> ["pkg@^1.0.0", "pkg@~1.2.0"]
|
|
146
191
|
let specsPart = headerLine.trimEnd().replace(/:$/, "");
|
|
147
|
-
|
|
148
|
-
for (let spec of specs) {
|
|
149
|
-
if (specNamePackage(spec) === packageName) {
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return false;
|
|
192
|
+
return specsPart.split(",").map(spec => spec.trim().replace(/^"|"$/g, ""));
|
|
154
193
|
}
|
|
155
194
|
|
|
156
195
|
// Extract the package name from a lock spec like `@scope/name@^1.0.0` or `name@~1.2.0`.
|
|
@@ -163,6 +202,89 @@ function specNamePackage(spec: string): string {
|
|
|
163
202
|
return spec.slice(0, atIndex);
|
|
164
203
|
}
|
|
165
204
|
|
|
205
|
+
// Ranges that don't come from the registry (git urls, file:, link:, npm: aliases) can't be pointed at a
|
|
206
|
+
// version number, so they have to stay as they are.
|
|
207
|
+
function isRegistryRange(range: string): boolean {
|
|
208
|
+
return !range.includes(":") && !range.includes("/");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Force the whole tree onto one version: drop every block for the package (so yarn re-resolves it), and
|
|
212
|
+
// repoint every *other* block's request for it at the new range, so nothing is left asking for an old
|
|
213
|
+
// pinned version that yarn would then have to resolve into a second entry.
|
|
214
|
+
function forceLockRange(lockPath: string, packageName: string, newRange: string): {
|
|
215
|
+
removedBlocks: number;
|
|
216
|
+
rewrittenRequests: number;
|
|
217
|
+
skippedRequests: { requestedBy: string; range: string }[];
|
|
218
|
+
} {
|
|
219
|
+
let lock = readLock(lockPath);
|
|
220
|
+
let removeLines = new Set<number>();
|
|
221
|
+
let removedBlocks = 0;
|
|
222
|
+
let rewrittenRequests = 0;
|
|
223
|
+
let skippedRequests: { requestedBy: string; range: string }[] = [];
|
|
224
|
+
|
|
225
|
+
for (let block of lock.blocks) {
|
|
226
|
+
if (block.specs.some(spec => specNamePackage(spec) === packageName)) {
|
|
227
|
+
removedBlocks++;
|
|
228
|
+
for (let i = block.start; i < block.end; i++) {
|
|
229
|
+
removeLines.add(i);
|
|
230
|
+
}
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
for (let i = block.start + 1; i < block.end; i++) {
|
|
235
|
+
let parsed = parseDependencyLine(lock.lines[i]);
|
|
236
|
+
if (!parsed || parsed.name !== packageName) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (!isRegistryRange(parsed.range)) {
|
|
240
|
+
skippedRequests.push({ requestedBy: block.specs[0], range: parsed.range });
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (parsed.range === newRange) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
lock.lines[i] = parsed.prefix + `"${newRange}"`;
|
|
247
|
+
rewrittenRequests++;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let kept = lock.lines.filter((_, i) => !removeLines.has(i));
|
|
252
|
+
fs.writeFileSync(lockPath, kept.join(lock.eol));
|
|
253
|
+
return { removedBlocks, rewrittenRequests, skippedRequests };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function parseDependencyLine(line: string): { prefix: string; name: string; range: string } | undefined {
|
|
257
|
+
let match = /^(\s+)("?)([^"\s]+)\2 "([^"]*)"$/.exec(line);
|
|
258
|
+
if (!match) {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
let [, indent, quote, name, range] = match;
|
|
262
|
+
if (indent.length < LOCK_DEPENDENCY_INDENT) {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
return { prefix: `${indent}${quote}${name}${quote} `, name, range };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function getLockedVersions(lockPath: string, packageName: string): string[] {
|
|
269
|
+
if (!fs.existsSync(lockPath)) {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
let lock = readLock(lockPath);
|
|
273
|
+
let versions = new Set<string>();
|
|
274
|
+
for (let block of lock.blocks) {
|
|
275
|
+
if (!block.specs.some(spec => specNamePackage(spec) === packageName)) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
for (let i = block.start + 1; i < block.end; i++) {
|
|
279
|
+
let match = /^\s+version "(.*)"$/.exec(lock.lines[i]);
|
|
280
|
+
if (match) {
|
|
281
|
+
versions.add(match[1]);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return Array.from(versions);
|
|
286
|
+
}
|
|
287
|
+
|
|
166
288
|
function escapeRegExp(value: string): string {
|
|
167
289
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
168
290
|
}
|