socket-function 1.2.9 → 1.2.11
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 +3 -3
- package/SocketFunction.ts +3 -3
- package/bin/upreal.js +4 -0
- package/index.d.ts +8 -17
- package/package.json +6 -2
- package/require/RequireController.d.ts +0 -1
- package/require/extMapper.d.ts +0 -1
- package/src/CallFactory.d.ts +0 -1
- package/src/CallFactory.ts +3 -3
- 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/tlsParsing.d.ts +0 -1
- package/src/upreal.d.ts +1 -0
- package/src/upreal.ts +197 -0
- 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";
|
|
@@ -11,11 +10,12 @@ type ExtractShape<ClassType, Shape> = {
|
|
|
11
10
|
export declare class SocketFunction {
|
|
12
11
|
static logMessages: boolean;
|
|
13
12
|
static trackMessageSizes: {
|
|
14
|
-
upload: ((size: number) => void)[];
|
|
15
|
-
download: ((size: number) => void)[];
|
|
13
|
+
upload: ((size: number, nodeId: string) => void)[];
|
|
14
|
+
download: ((size: number, nodeId: string) => void)[];
|
|
16
15
|
callTimes: ((obj: {
|
|
17
16
|
start: number;
|
|
18
17
|
end: number;
|
|
18
|
+
nodeId: string;
|
|
19
19
|
}) => void)[];
|
|
20
20
|
};
|
|
21
21
|
static MAX_MESSAGE_SIZE: number;
|
package/SocketFunction.ts
CHANGED
|
@@ -58,9 +58,9 @@ type ExtractShape<ClassType, Shape> = {
|
|
|
58
58
|
export class SocketFunction {
|
|
59
59
|
public static logMessages = false;
|
|
60
60
|
public static trackMessageSizes = {
|
|
61
|
-
upload: [] as ((size: number) => void)[],
|
|
62
|
-
download: [] as ((size: number) => void)[],
|
|
63
|
-
callTimes: [] as ((obj: { start: number; end: number; }) => void)[],
|
|
61
|
+
upload: [] as ((size: number, nodeId: string) => void)[],
|
|
62
|
+
download: [] as ((size: number, nodeId: string) => void)[],
|
|
63
|
+
callTimes: [] as ((obj: { start: number; end: number; nodeId: string; }) => void)[],
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
public static MAX_MESSAGE_SIZE = 1024 * 1024 * 32;
|
package/bin/upreal.js
ADDED
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";
|
|
@@ -20,11 +19,12 @@ declare module "socket-function/SocketFunction" {
|
|
|
20
19
|
export declare class SocketFunction {
|
|
21
20
|
static logMessages: boolean;
|
|
22
21
|
static trackMessageSizes: {
|
|
23
|
-
upload: ((size: number) => void)[];
|
|
24
|
-
download: ((size: number) => void)[];
|
|
22
|
+
upload: ((size: number, nodeId: string) => void)[];
|
|
23
|
+
download: ((size: number, nodeId: string) => void)[];
|
|
25
24
|
callTimes: ((obj: {
|
|
26
25
|
start: number;
|
|
27
26
|
end: number;
|
|
27
|
+
nodeId: string;
|
|
28
28
|
}) => void)[];
|
|
29
29
|
};
|
|
30
30
|
static MAX_MESSAGE_SIZE: number;
|
|
@@ -315,7 +315,6 @@ declare module "socket-function/require/CSSShim" {
|
|
|
315
315
|
declare module "socket-function/require/RequireController" {
|
|
316
316
|
/// <reference path="../../typenode/index.d.ts" />
|
|
317
317
|
/// <reference types="node" />
|
|
318
|
-
/// <reference types="node" />
|
|
319
318
|
declare global {
|
|
320
319
|
namespace NodeJS {
|
|
321
320
|
interface Module {
|
|
@@ -445,7 +444,6 @@ declare module "socket-function/require/compileFlags" {
|
|
|
445
444
|
}
|
|
446
445
|
|
|
447
446
|
declare module "socket-function/require/extMapper" {
|
|
448
|
-
/// <reference types="node" />
|
|
449
447
|
/// <reference types="node" />
|
|
450
448
|
export declare function getExtContentType(ext: string): string;
|
|
451
449
|
export declare function getContentTypeFromBuffer(buffer: Buffer): string | undefined;
|
|
@@ -471,7 +469,6 @@ declare module "socket-function/require/require" {
|
|
|
471
469
|
}
|
|
472
470
|
|
|
473
471
|
declare module "socket-function/src/CallFactory" {
|
|
474
|
-
/// <reference types="node" />
|
|
475
472
|
/// <reference types="node" />
|
|
476
473
|
/// <reference types="node" />
|
|
477
474
|
import { CallType } from "socket-function/SocketFunctionTypes";
|
|
@@ -530,7 +527,6 @@ declare module "socket-function/src/CallFactory" {
|
|
|
530
527
|
}
|
|
531
528
|
|
|
532
529
|
declare module "socket-function/src/JSONLACKS/JSONLACKS" {
|
|
533
|
-
/// <reference types="node" />
|
|
534
530
|
/// <reference types="node" />
|
|
535
531
|
export interface JSONLACKS_ParseConfig {
|
|
536
532
|
extended?: boolean;
|
|
@@ -566,7 +562,6 @@ declare module "socket-function/src/JSONLACKS/JSONLACKS.generated.js" {
|
|
|
566
562
|
}
|
|
567
563
|
|
|
568
564
|
declare module "socket-function/src/Zip" {
|
|
569
|
-
/// <reference types="node" />
|
|
570
565
|
/// <reference types="node" />
|
|
571
566
|
import { MaybePromise } from "socket-function/src/types";
|
|
572
567
|
export declare class Zip {
|
|
@@ -654,7 +649,6 @@ declare module "socket-function/src/batching" {
|
|
|
654
649
|
}
|
|
655
650
|
|
|
656
651
|
declare module "socket-function/src/bits" {
|
|
657
|
-
/// <reference types="node" />
|
|
658
652
|
/// <reference types="node" />
|
|
659
653
|
/** Subtracts the smallest possible value from a number (a double). This makes it possible to convert an exclusive range end
|
|
660
654
|
* to an inclusive range end, which is sometimes required (as in, < x is the same as <= minusEpsilon(x)).
|
|
@@ -681,7 +675,6 @@ declare module "socket-function/src/bits" {
|
|
|
681
675
|
}
|
|
682
676
|
|
|
683
677
|
declare module "socket-function/src/buffers" {
|
|
684
|
-
/// <reference types="node" />
|
|
685
678
|
/// <reference types="node" />
|
|
686
679
|
export type ArrayBufferViewTypes = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float64Array | Float32Array | Uint8ClampedArray;
|
|
687
680
|
export type BufferType = ArrayBuffer | SharedArrayBuffer | ArrayBufferViewTypes;
|
|
@@ -759,7 +752,6 @@ declare module "socket-function/src/caching" {
|
|
|
759
752
|
}
|
|
760
753
|
|
|
761
754
|
declare module "socket-function/src/callHTTPHandler" {
|
|
762
|
-
/// <reference types="node" />
|
|
763
755
|
/// <reference types="node" />
|
|
764
756
|
/// <reference types="node" />
|
|
765
757
|
import http from "http";
|
|
@@ -814,7 +806,6 @@ declare module "socket-function/src/callManager" {
|
|
|
814
806
|
}
|
|
815
807
|
|
|
816
808
|
declare module "socket-function/src/certStore" {
|
|
817
|
-
/// <reference types="node" />
|
|
818
809
|
/// <reference types="node" />
|
|
819
810
|
/** Must be populated before the server starts */
|
|
820
811
|
export declare function trustCertificate(cert: string | Buffer): void;
|
|
@@ -975,7 +966,6 @@ declare module "socket-function/src/getUniqueTime" {
|
|
|
975
966
|
}
|
|
976
967
|
|
|
977
968
|
declare module "socket-function/src/https" {
|
|
978
|
-
/// <reference types="node" />
|
|
979
969
|
/// <reference types="node" />
|
|
980
970
|
export declare function httpsRequest(url: string, payload?: Buffer | Buffer[], method?: string, sendSessionCookies?: boolean, config?: {
|
|
981
971
|
headers?: {
|
|
@@ -987,7 +977,6 @@ declare module "socket-function/src/https" {
|
|
|
987
977
|
}
|
|
988
978
|
|
|
989
979
|
declare module "socket-function/src/lz4/LZ4" {
|
|
990
|
-
/// <reference types="node" />
|
|
991
980
|
/// <reference types="node" />
|
|
992
981
|
export declare class LZ4 {
|
|
993
982
|
static compress(data: Buffer): Buffer;
|
|
@@ -1055,7 +1044,6 @@ declare module "socket-function/src/lz4/lz4_wasm_nodejs_bg.wasm" {
|
|
|
1055
1044
|
}
|
|
1056
1045
|
|
|
1057
1046
|
declare module "socket-function/src/misc" {
|
|
1058
|
-
/// <reference types="node" />
|
|
1059
1047
|
/// <reference types="node" />
|
|
1060
1048
|
import { MaybePromise } from "socket-function/src/types";
|
|
1061
1049
|
export declare const timeInSecond = 1000;
|
|
@@ -1485,7 +1473,6 @@ declare module "socket-function/src/storagePath" {
|
|
|
1485
1473
|
}
|
|
1486
1474
|
|
|
1487
1475
|
declare module "socket-function/src/tlsParsing" {
|
|
1488
|
-
/// <reference types="node" />
|
|
1489
1476
|
/// <reference types="node" />
|
|
1490
1477
|
export declare function parseTLSHello(buffer: Buffer): {
|
|
1491
1478
|
extensions: {
|
|
@@ -1509,8 +1496,12 @@ declare module "socket-function/src/types" {
|
|
|
1509
1496
|
|
|
1510
1497
|
}
|
|
1511
1498
|
|
|
1499
|
+
declare module "socket-function/src/upreal" {
|
|
1500
|
+
export {};
|
|
1501
|
+
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1512
1504
|
declare module "socket-function/src/webSocketServer" {
|
|
1513
|
-
/// <reference types="node" />
|
|
1514
1505
|
/// <reference types="node" />
|
|
1515
1506
|
/// <reference types="node" />
|
|
1516
1507
|
import https from "https";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "socket-function",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.11",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
@@ -12,13 +12,17 @@
|
|
|
12
12
|
"preact": "10.24.3",
|
|
13
13
|
"typedev": "^0.4.0",
|
|
14
14
|
"typenode": "^6.0.1",
|
|
15
|
-
"ws": "^8.
|
|
15
|
+
"ws": "^8.21.0"
|
|
16
16
|
},
|
|
17
17
|
"optionalDependencies": {
|
|
18
18
|
"lmdb": "^3.5.1"
|
|
19
19
|
},
|
|
20
20
|
"types": "index.d.ts",
|
|
21
|
+
"bin": {
|
|
22
|
+
"upreal": "./bin/upreal.js"
|
|
23
|
+
},
|
|
21
24
|
"scripts": {
|
|
25
|
+
"upreal": "yarn typenode ./src/upreal.ts",
|
|
22
26
|
"test": "yarn typenode ./test.ts",
|
|
23
27
|
"test-all": "node run-test.js",
|
|
24
28
|
"type": "yarn tsc --noEmit",
|
package/require/extMapper.d.ts
CHANGED
package/src/CallFactory.d.ts
CHANGED
package/src/CallFactory.ts
CHANGED
|
@@ -277,7 +277,7 @@ export async function createCallFactory(
|
|
|
277
277
|
{
|
|
278
278
|
let resultSize = data.map(x => x.length).reduce((a, b) => a + b, 0);
|
|
279
279
|
for (let callback of SocketFunction.trackMessageSizes.upload) {
|
|
280
|
-
callback(resultSize);
|
|
280
|
+
callback(resultSize, nodeId);
|
|
281
281
|
}
|
|
282
282
|
if (SocketFunction.logMessages) {
|
|
283
283
|
let fncHack = "";
|
|
@@ -568,7 +568,7 @@ export async function createCallFactory(
|
|
|
568
568
|
}
|
|
569
569
|
let parseTime = Date.now() - time;
|
|
570
570
|
for (let callback of SocketFunction.trackMessageSizes.download) {
|
|
571
|
-
callback(resultSize);
|
|
571
|
+
callback(resultSize, nodeId);
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
let receiveStats: CompressionStats = {
|
|
@@ -659,7 +659,7 @@ export async function createCallFactory(
|
|
|
659
659
|
let start = time;
|
|
660
660
|
let end = Date.now();
|
|
661
661
|
for (let fnc of SocketFunction.trackMessageSizes.callTimes) {
|
|
662
|
-
fnc({ start, end });
|
|
662
|
+
fnc({ start, end, nodeId });
|
|
663
663
|
}
|
|
664
664
|
}
|
|
665
665
|
|
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/tlsParsing.d.ts
CHANGED
package/src/upreal.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/src/upreal.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as https from "https";
|
|
4
|
+
import { spawn } from "child_process";
|
|
5
|
+
|
|
6
|
+
// Dependency sections in package.json that upreal is willing to update, in the order we search them.
|
|
7
|
+
const DEP_SECTIONS = [
|
|
8
|
+
"dependencies",
|
|
9
|
+
"devDependencies",
|
|
10
|
+
"optionalDependencies",
|
|
11
|
+
"peerDependencies",
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
async function main() {
|
|
15
|
+
let packageName = process.argv.slice(2).find(arg => !arg.startsWith("-"));
|
|
16
|
+
if (!packageName) {
|
|
17
|
+
console.error("Usage: yarn upreal <package-name>");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let projectRoot = process.cwd();
|
|
23
|
+
let packageJsonPath = path.join(projectRoot, "package.json");
|
|
24
|
+
let lockPath = path.join(projectRoot, "yarn.lock");
|
|
25
|
+
|
|
26
|
+
let packageJsonRaw = fs.readFileSync(packageJsonPath, "utf8");
|
|
27
|
+
let packageJson = JSON.parse(packageJsonRaw) as {
|
|
28
|
+
[section: string]: { [name: string]: string } | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
let currentRange = findCurrentRange(packageJson, packageName);
|
|
32
|
+
if (currentRange === undefined) {
|
|
33
|
+
console.error(`Package "${packageName}" is not listed in ${DEP_SECTIONS.join(", ")} of package.json`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(`Current range for ${packageName}: ${currentRange}`);
|
|
39
|
+
|
|
40
|
+
let latest = await getLatestVersion(packageName);
|
|
41
|
+
console.log(`Latest version of ${packageName}: ${latest}`);
|
|
42
|
+
|
|
43
|
+
let newRange = applyPrefix(currentRange, latest);
|
|
44
|
+
if (newRange === currentRange) {
|
|
45
|
+
console.log(`package.json range unchanged (${currentRange}); will still re-resolve the lockfile.`);
|
|
46
|
+
} else {
|
|
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.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`Running yarn install...`);
|
|
65
|
+
await runYarnInstall(projectRoot);
|
|
66
|
+
console.log(`Done. ${packageName} is now at ${newRange}.`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function findCurrentRange(
|
|
70
|
+
packageJson: { [section: string]: { [name: string]: string } | undefined },
|
|
71
|
+
packageName: string
|
|
72
|
+
): string | undefined {
|
|
73
|
+
for (let section of DEP_SECTIONS) {
|
|
74
|
+
let deps = packageJson[section];
|
|
75
|
+
if (deps && packageName in deps) {
|
|
76
|
+
return deps[packageName];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function getLatestVersion(packageName: string): Promise<string> {
|
|
83
|
+
// Scoped names ("@scope/name") must have their slash encoded in the registry path.
|
|
84
|
+
let encodedName = packageName.startsWith("@")
|
|
85
|
+
? "@" + encodeURIComponent(packageName.slice(1))
|
|
86
|
+
: encodeURIComponent(packageName);
|
|
87
|
+
let url = `https://registry.npmjs.org/${encodedName}/latest`;
|
|
88
|
+
|
|
89
|
+
let body = await new Promise<string>((resolve, reject) => {
|
|
90
|
+
https.get(url, res => {
|
|
91
|
+
if (res.statusCode !== 200) {
|
|
92
|
+
res.resume();
|
|
93
|
+
reject(new Error(`Registry returned ${res.statusCode} for ${url}`));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let chunks: Buffer[] = [];
|
|
97
|
+
res.on("data", chunk => chunks.push(chunk));
|
|
98
|
+
res.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
99
|
+
}).on("error", reject);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
let parsed = JSON.parse(body) as { version?: string };
|
|
103
|
+
if (!parsed.version) {
|
|
104
|
+
throw new Error(`Registry response for ${packageName} had no version field`);
|
|
105
|
+
}
|
|
106
|
+
return parsed.version;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Keep whatever range operator the user already chose (^, ~, exact, or *) and point it at the new version.
|
|
110
|
+
function applyPrefix(currentRange: string, latest: string): string {
|
|
111
|
+
if (currentRange === "*" || currentRange === "" || currentRange === "latest") {
|
|
112
|
+
return currentRange;
|
|
113
|
+
}
|
|
114
|
+
if (currentRange.startsWith("^")) {
|
|
115
|
+
return "^" + latest;
|
|
116
|
+
}
|
|
117
|
+
if (currentRange.startsWith("~")) {
|
|
118
|
+
return "~" + latest;
|
|
119
|
+
}
|
|
120
|
+
return latest;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function replaceRange(packageJsonRaw: string, packageName: string, oldRange: string, newRange: string): string {
|
|
124
|
+
// Rewrite the value in place (rather than JSON.stringify) so the file keeps its exact formatting and tab style.
|
|
125
|
+
let keyPattern = new RegExp(`("${escapeRegExp(packageName)}"\\s*:\\s*")${escapeRegExp(oldRange)}(")`);
|
|
126
|
+
if (!keyPattern.test(packageJsonRaw)) {
|
|
127
|
+
throw new Error(`Could not locate "${packageName}": "${oldRange}" in package.json to update`);
|
|
128
|
+
}
|
|
129
|
+
return packageJsonRaw.replace(keyPattern, `$1${newRange}$2`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Remove all yarn.lock v1 blocks that resolve the given package (across every range variant of it).
|
|
133
|
+
function removeLockEntries(lockRaw: string, packageName: string): { lock: string; removed: number } {
|
|
134
|
+
// yarn.lock v1 blocks are separated by blank lines; the first line of each block is the comma-separated
|
|
135
|
+
// list of specs it satisfies, e.g. `"pkg@^1.0.0", "pkg@~1.2.0":`.
|
|
136
|
+
let blocks = lockRaw.split(/\r?\n\r?\n/);
|
|
137
|
+
let removed = 0;
|
|
138
|
+
let kept: string[] = [];
|
|
139
|
+
for (let block of blocks) {
|
|
140
|
+
if (blockResolvesPackage(block, packageName)) {
|
|
141
|
+
removed++;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
kept.push(block);
|
|
145
|
+
}
|
|
146
|
+
return { lock: kept.join("\n\n"), removed };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function blockResolvesPackage(block: string, packageName: string): boolean {
|
|
150
|
+
let headerLine = block.split(/\r?\n/).find(line => line.trim().length > 0 && !line.startsWith("#"));
|
|
151
|
+
if (!headerLine || !headerLine.trimEnd().endsWith(":")) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
// Strip the trailing colon, then split on commas into individual quoted-or-bare specs.
|
|
155
|
+
let specsPart = headerLine.trimEnd().replace(/:$/, "");
|
|
156
|
+
let specs = specsPart.split(",").map(spec => spec.trim().replace(/^"|"$/g, ""));
|
|
157
|
+
for (let spec of specs) {
|
|
158
|
+
if (specNamePackage(spec) === packageName) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Extract the package name from a lock spec like `@scope/name@^1.0.0` or `name@~1.2.0`.
|
|
166
|
+
function specNamePackage(spec: string): string {
|
|
167
|
+
let atIndex = spec.lastIndexOf("@");
|
|
168
|
+
// A leading "@" (scoped package) is part of the name, not the name/range separator.
|
|
169
|
+
if (atIndex <= 0) {
|
|
170
|
+
return spec;
|
|
171
|
+
}
|
|
172
|
+
return spec.slice(0, atIndex);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function escapeRegExp(value: string): string {
|
|
176
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function runYarnInstall(cwd: string): Promise<void> {
|
|
180
|
+
await new Promise<void>((resolve, reject) => {
|
|
181
|
+
// yarn is a .cmd shim on Windows, so it must be spawned through the shell.
|
|
182
|
+
let child = spawn("yarn", ["install"], { cwd, stdio: "inherit", shell: true });
|
|
183
|
+
child.on("error", reject);
|
|
184
|
+
child.on("exit", code => {
|
|
185
|
+
if (code === 0) {
|
|
186
|
+
resolve();
|
|
187
|
+
} else {
|
|
188
|
+
reject(new Error(`yarn install exited with code ${code}`));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
main().catch(e => {
|
|
195
|
+
console.error(e.stack ?? e);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
});
|