socket-function 1.2.36 → 1.2.37
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 +1 -0
- package/index.d.ts +15 -0
- package/package.json +1 -1
- package/require/RequireController.d.ts +1 -0
- package/require/extMapper.d.ts +1 -0
- package/src/CallFactory.d.ts +1 -0
- package/src/JSONLACKS/JSONLACKS.d.ts +1 -0
- package/src/Zip.d.ts +1 -0
- package/src/bits.d.ts +1 -0
- package/src/buffers.d.ts +1 -0
- package/src/callHTTPHandler.d.ts +1 -0
- package/src/certStore.d.ts +1 -0
- package/src/dnsCache.ts +6 -4
- package/src/https.d.ts +1 -0
- package/src/lz4/LZ4.d.ts +1 -0
- package/src/misc.d.ts +1 -0
- package/src/tlsParsing.d.ts +1 -0
- package/src/upreal.ts +161 -78
- package/src/webSocketServer.d.ts +1 -0
package/SocketFunction.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference path="require/RequireController.d.ts" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import { SocketExposedInterface, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, CallerContext, FullCallType, SocketRegisterType } from "./SocketFunctionTypes";
|
|
4
5
|
import { SocketServerConfig } from "./src/webSocketServer";
|
|
5
6
|
import { Args, MaybePromise } from "./src/types";
|
package/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ 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" />
|
|
12
13
|
import { SocketExposedInterface, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, CallerContext, FullCallType, SocketRegisterType } from "socket-function/SocketFunctionTypes";
|
|
13
14
|
import { SocketServerConfig } from "socket-function/src/webSocketServer";
|
|
14
15
|
import { Args, MaybePromise } from "socket-function/src/types";
|
|
@@ -320,6 +321,7 @@ declare module "socket-function/require/CSSShim" {
|
|
|
320
321
|
declare module "socket-function/require/RequireController" {
|
|
321
322
|
/// <reference path="../../typenode/index.d.ts" />
|
|
322
323
|
/// <reference types="node" />
|
|
324
|
+
/// <reference types="node" />
|
|
323
325
|
declare global {
|
|
324
326
|
namespace NodeJS {
|
|
325
327
|
interface Module {
|
|
@@ -449,6 +451,7 @@ declare module "socket-function/require/compileFlags" {
|
|
|
449
451
|
}
|
|
450
452
|
|
|
451
453
|
declare module "socket-function/require/extMapper" {
|
|
454
|
+
/// <reference types="node" />
|
|
452
455
|
/// <reference types="node" />
|
|
453
456
|
export declare function getExtContentType(ext: string): string;
|
|
454
457
|
export declare function getContentTypeFromBuffer(buffer: Buffer): string | undefined;
|
|
@@ -474,6 +477,7 @@ declare module "socket-function/require/require" {
|
|
|
474
477
|
}
|
|
475
478
|
|
|
476
479
|
declare module "socket-function/src/CallFactory" {
|
|
480
|
+
/// <reference types="node" />
|
|
477
481
|
/// <reference types="node" />
|
|
478
482
|
/// <reference types="node" />
|
|
479
483
|
import { CallType } from "socket-function/SocketFunctionTypes";
|
|
@@ -532,6 +536,7 @@ declare module "socket-function/src/CallFactory" {
|
|
|
532
536
|
}
|
|
533
537
|
|
|
534
538
|
declare module "socket-function/src/JSONLACKS/JSONLACKS" {
|
|
539
|
+
/// <reference types="node" />
|
|
535
540
|
/// <reference types="node" />
|
|
536
541
|
export interface JSONLACKS_ParseConfig {
|
|
537
542
|
extended?: boolean;
|
|
@@ -567,6 +572,7 @@ declare module "socket-function/src/JSONLACKS/JSONLACKS.generated.js" {
|
|
|
567
572
|
}
|
|
568
573
|
|
|
569
574
|
declare module "socket-function/src/Zip" {
|
|
575
|
+
/// <reference types="node" />
|
|
570
576
|
/// <reference types="node" />
|
|
571
577
|
import { MaybePromise } from "socket-function/src/types";
|
|
572
578
|
export declare class Zip {
|
|
@@ -654,6 +660,7 @@ declare module "socket-function/src/batching" {
|
|
|
654
660
|
}
|
|
655
661
|
|
|
656
662
|
declare module "socket-function/src/bits" {
|
|
663
|
+
/// <reference types="node" />
|
|
657
664
|
/// <reference types="node" />
|
|
658
665
|
/** Subtracts the smallest possible value from a number (a double). This makes it possible to convert an exclusive range end
|
|
659
666
|
* to an inclusive range end, which is sometimes required (as in, < x is the same as <= minusEpsilon(x)).
|
|
@@ -680,6 +687,7 @@ declare module "socket-function/src/bits" {
|
|
|
680
687
|
}
|
|
681
688
|
|
|
682
689
|
declare module "socket-function/src/buffers" {
|
|
690
|
+
/// <reference types="node" />
|
|
683
691
|
/// <reference types="node" />
|
|
684
692
|
export type ArrayBufferViewTypes = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float64Array | Float32Array | Uint8ClampedArray;
|
|
685
693
|
export type BufferType = ArrayBuffer | SharedArrayBuffer | ArrayBufferViewTypes;
|
|
@@ -757,6 +765,7 @@ declare module "socket-function/src/caching" {
|
|
|
757
765
|
}
|
|
758
766
|
|
|
759
767
|
declare module "socket-function/src/callHTTPHandler" {
|
|
768
|
+
/// <reference types="node" />
|
|
760
769
|
/// <reference types="node" />
|
|
761
770
|
/// <reference types="node" />
|
|
762
771
|
import http from "http";
|
|
@@ -811,6 +820,7 @@ declare module "socket-function/src/callManager" {
|
|
|
811
820
|
}
|
|
812
821
|
|
|
813
822
|
declare module "socket-function/src/certStore" {
|
|
823
|
+
/// <reference types="node" />
|
|
814
824
|
/// <reference types="node" />
|
|
815
825
|
/** Must be populated before the server starts */
|
|
816
826
|
export declare function trustCertificate(cert: string | Buffer): void;
|
|
@@ -1046,6 +1056,7 @@ declare module "socket-function/src/getUniqueTime" {
|
|
|
1046
1056
|
}
|
|
1047
1057
|
|
|
1048
1058
|
declare module "socket-function/src/https" {
|
|
1059
|
+
/// <reference types="node" />
|
|
1049
1060
|
/// <reference types="node" />
|
|
1050
1061
|
export interface HttpsResponseInfo {
|
|
1051
1062
|
statusCode?: number;
|
|
@@ -1065,6 +1076,7 @@ declare module "socket-function/src/https" {
|
|
|
1065
1076
|
}
|
|
1066
1077
|
|
|
1067
1078
|
declare module "socket-function/src/lz4/LZ4" {
|
|
1079
|
+
/// <reference types="node" />
|
|
1068
1080
|
/// <reference types="node" />
|
|
1069
1081
|
export declare class LZ4 {
|
|
1070
1082
|
static compress(data: Buffer): Buffer;
|
|
@@ -1132,6 +1144,7 @@ declare module "socket-function/src/lz4/lz4_wasm_nodejs_bg.wasm" {
|
|
|
1132
1144
|
}
|
|
1133
1145
|
|
|
1134
1146
|
declare module "socket-function/src/misc" {
|
|
1147
|
+
/// <reference types="node" />
|
|
1135
1148
|
/// <reference types="node" />
|
|
1136
1149
|
import { MaybePromise } from "socket-function/src/types";
|
|
1137
1150
|
export declare const timeInSecond = 1000;
|
|
@@ -1563,6 +1576,7 @@ declare module "socket-function/src/storagePath" {
|
|
|
1563
1576
|
}
|
|
1564
1577
|
|
|
1565
1578
|
declare module "socket-function/src/tlsParsing" {
|
|
1579
|
+
/// <reference types="node" />
|
|
1566
1580
|
/// <reference types="node" />
|
|
1567
1581
|
export declare function parseTLSHello(buffer: Buffer): {
|
|
1568
1582
|
extensions: {
|
|
@@ -1592,6 +1606,7 @@ declare module "socket-function/src/upreal" {
|
|
|
1592
1606
|
}
|
|
1593
1607
|
|
|
1594
1608
|
declare module "socket-function/src/webSocketServer" {
|
|
1609
|
+
/// <reference types="node" />
|
|
1595
1610
|
/// <reference types="node" />
|
|
1596
1611
|
/// <reference types="node" />
|
|
1597
1612
|
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,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
/** Subtracts the smallest possible value from a number (a double). This makes it possible to convert an exclusive range end
|
|
3
4
|
* to an inclusive range end, which is sometimes required (as in, < x is the same as <= minusEpsilon(x)).
|
|
4
5
|
*/
|
package/src/buffers.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
export type ArrayBufferViewTypes = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float64Array | Float32Array | Uint8ClampedArray;
|
|
3
4
|
export type BufferType = ArrayBuffer | SharedArrayBuffer | ArrayBufferViewTypes;
|
|
4
5
|
export declare function cloneBuffer(data: Buffer): Buffer;
|
package/src/callHTTPHandler.d.ts
CHANGED
package/src/certStore.d.ts
CHANGED
package/src/dnsCache.ts
CHANGED
|
@@ -158,19 +158,21 @@ export async function resolveHost(hostname: string, family = 0): Promise<DNSReco
|
|
|
158
158
|
// the socket use our cache instead of getaddrinfo. Always resolves via our cache; happy eyeballs
|
|
159
159
|
// (autoSelectFamily) then races the returned addresses.
|
|
160
160
|
export const dnsCacheLookup: net.LookupFunction = function dnsCacheLookup(hostname, options, callback) {
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
// Node's own callers pass the family as a number, but the option is documented as accepting "IPv4"/"IPv6"
|
|
162
|
+
// too, so handle both even though the typings only admit the number.
|
|
163
|
+
let rawFamily: number | string = typeof options === "number" ? options : options.family ?? 0;
|
|
164
|
+
let family = rawFamily === "IPv4" ? 4 : rawFamily === "IPv6" ? 6 : Number(rawFamily) || 0;
|
|
163
165
|
let all = typeof options === "object" && options.all;
|
|
164
166
|
resolveHost(hostname, family).then(
|
|
165
167
|
records => {
|
|
166
168
|
if (all) {
|
|
167
|
-
callback(null, records.map(r => ({ address: r.address, family: r.family })));
|
|
169
|
+
callback(null, records.map(r => ({ address: r.address, family: r.family })), family);
|
|
168
170
|
} else {
|
|
169
171
|
let record = records[0];
|
|
170
172
|
callback(null, record.address, record.family);
|
|
171
173
|
}
|
|
172
174
|
},
|
|
173
|
-
(err: NodeJS.ErrnoException) => callback(err, "",
|
|
175
|
+
(err: NodeJS.ErrnoException) => callback(err, "", family)
|
|
174
176
|
);
|
|
175
177
|
};
|
|
176
178
|
|
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.ts
CHANGED
|
@@ -11,17 +11,17 @@ 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
14
|
// Yarn itself spells this "--dry-run", so accept that plus every spelling anyone reasonably reaches for.
|
|
23
15
|
const DRY_RUN_FLAGS = ["--dry", "-dry", "--dryrun", "-dryrun", "--dry-run", "-dry-run", "--dry_run", "-dry_run"];
|
|
24
16
|
|
|
17
|
+
// yarn install can still decide to re-resolve and re-split; re-running the merge converges in that case.
|
|
18
|
+
const MAX_MERGE_PASSES = 3;
|
|
19
|
+
|
|
20
|
+
// yarn v1 rewrites npm registry urls to its own mirror, so entries we synthesize have to match or yarn
|
|
21
|
+
// churns the lockfile back on the next install.
|
|
22
|
+
const NPM_REGISTRY_HOST = "registry.npmjs.org";
|
|
23
|
+
const YARN_REGISTRY_HOST = "registry.yarnpkg.com";
|
|
24
|
+
|
|
25
25
|
async function main() {
|
|
26
26
|
let args = process.argv.slice(2);
|
|
27
27
|
let packageName = args.find(arg => !arg.startsWith("-"));
|
|
@@ -36,18 +36,20 @@ async function main() {
|
|
|
36
36
|
let packageJsonPath = path.join(projectRoot, "package.json");
|
|
37
37
|
let lockPath = path.join(projectRoot, "yarn.lock");
|
|
38
38
|
|
|
39
|
-
let
|
|
40
|
-
console.log(`Latest version of ${packageName}: ${
|
|
39
|
+
let manifest = await getLatestManifest(packageName);
|
|
40
|
+
console.log(`Latest version of ${packageName}: ${manifest.version}`);
|
|
41
41
|
|
|
42
|
-
let newRange = updatePackageJson(packageJsonPath, packageName,
|
|
43
|
-
console.log(`Forcing every reference to ${packageName} onto ${newRange}`);
|
|
42
|
+
let newRange = updatePackageJson(packageJsonPath, packageName, manifest.version);
|
|
44
43
|
|
|
45
|
-
for (let pass = 1; pass <=
|
|
44
|
+
for (let pass = 1; pass <= MAX_MERGE_PASSES; pass++) {
|
|
46
45
|
if (fs.existsSync(lockPath)) {
|
|
47
|
-
let result =
|
|
48
|
-
console.log(`Lockfile pass ${pass}:
|
|
49
|
-
for (let
|
|
50
|
-
console.log(`
|
|
46
|
+
let result = mergeLockEntries(lockPath, packageName, manifest, newRange);
|
|
47
|
+
console.log(`Lockfile pass ${pass}: ${result.specs.length} spec${result.specs.length === 1 ? "" : "s"} for ${packageName} now share one entry at ${manifest.version}: ${result.specs.join(", ")}`);
|
|
48
|
+
for (let moved of result.movedFrom) {
|
|
49
|
+
console.log(` ${moved.spec} was resolving to ${moved.version}`);
|
|
50
|
+
}
|
|
51
|
+
for (let left of result.leftAlone) {
|
|
52
|
+
console.log(` left ${left} alone (not a registry range, so it can't point at a version)`);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -61,19 +63,19 @@ async function main() {
|
|
|
61
63
|
|
|
62
64
|
let versions = getLockedVersions(lockPath, packageName);
|
|
63
65
|
if (versions.length <= 1) {
|
|
64
|
-
console.log(`Done. ${packageName} resolves to a single version: ${versions[0] ??
|
|
66
|
+
console.log(`Done. ${packageName} resolves to a single version: ${versions[0] ?? manifest.version}`);
|
|
65
67
|
return;
|
|
66
68
|
}
|
|
67
|
-
console.log(`${packageName} still resolves to ${versions.length} versions (${versions.join(", ")});
|
|
69
|
+
console.log(`${packageName} still resolves to ${versions.length} versions (${versions.join(", ")}); merging again.`);
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
let versions = getLockedVersions(lockPath, packageName);
|
|
71
|
-
console.error(`Failed to collapse ${packageName} onto one version after ${
|
|
73
|
+
console.error(`Failed to collapse ${packageName} onto one version after ${MAX_MERGE_PASSES} passes; still at ${versions.join(", ")}`);
|
|
72
74
|
process.exit(1);
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
// 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
|
|
78
|
+
// existing range operator, and return the range the lockfile entry has to satisfy.
|
|
77
79
|
function updatePackageJson(packageJsonPath: string, packageName: string, latest: string): string {
|
|
78
80
|
let raw = fs.readFileSync(packageJsonPath, "utf8");
|
|
79
81
|
let packageJson = JSON.parse(raw) as {
|
|
@@ -99,28 +101,35 @@ function updatePackageJson(packageJsonPath: string, packageName: string, latest:
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
if (newRange === undefined) {
|
|
102
|
-
console.log(`${packageName} is not a direct dependency; only
|
|
104
|
+
console.log(`${packageName} is not a direct dependency; only merging the transitive references.`);
|
|
103
105
|
return "^" + latest;
|
|
104
106
|
}
|
|
105
107
|
return newRange;
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
interface Manifest {
|
|
111
|
+
version: string;
|
|
112
|
+
dist?: { tarball?: string; shasum?: string; integrity?: string };
|
|
113
|
+
dependencies?: { [name: string]: string };
|
|
114
|
+
optionalDependencies?: { [name: string]: string };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function getLatestManifest(packageName: string): Promise<Manifest> {
|
|
109
118
|
// Scoped names ("@scope/name") must have their slash encoded in the registry path.
|
|
110
119
|
let encodedName = packageName.startsWith("@")
|
|
111
120
|
? "@" + encodeURIComponent(packageName.slice(1))
|
|
112
121
|
: encodeURIComponent(packageName);
|
|
113
|
-
let url = `https
|
|
122
|
+
let url = `https://${NPM_REGISTRY_HOST}/${encodedName}/latest`;
|
|
114
123
|
|
|
115
124
|
// Via httpsRequest so registry lookups go through the DNS cache (and its re-resolve/retry), rather
|
|
116
125
|
// than getaddrinfo, which caches certain failures forever.
|
|
117
126
|
let body = (await httpsRequest(url)).toString("utf8");
|
|
118
127
|
|
|
119
|
-
let parsed = JSON.parse(body) as
|
|
128
|
+
let parsed = JSON.parse(body) as Manifest;
|
|
120
129
|
if (!parsed.version) {
|
|
121
130
|
throw new Error(`Registry response for ${packageName} had no version field`);
|
|
122
131
|
}
|
|
123
|
-
return parsed
|
|
132
|
+
return parsed;
|
|
124
133
|
}
|
|
125
134
|
|
|
126
135
|
// Keep whatever range operator the user already chose (^, ~, exact, or *) and point it at the new version.
|
|
@@ -167,14 +176,14 @@ function readLock(lockPath: string): LockFile {
|
|
|
167
176
|
let blocks: LockBlock[] = [];
|
|
168
177
|
let current: LockBlock | undefined;
|
|
169
178
|
for (let i = 0; i < lines.length; i++) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (current) {
|
|
173
|
-
current.end = i;
|
|
174
|
-
}
|
|
175
|
-
current = { start: i, end: lines.length, specs: parseHeaderSpecs(line) };
|
|
176
|
-
blocks.push(current);
|
|
179
|
+
if (!isBlockHeader(lines[i])) {
|
|
180
|
+
continue;
|
|
177
181
|
}
|
|
182
|
+
if (current) {
|
|
183
|
+
current.end = i;
|
|
184
|
+
}
|
|
185
|
+
current = { start: i, end: lines.length, specs: parseHeaderSpecs(lines[i]) };
|
|
186
|
+
blocks.push(current);
|
|
178
187
|
}
|
|
179
188
|
return { lines, eol, blocks };
|
|
180
189
|
}
|
|
@@ -202,67 +211,143 @@ function specNamePackage(spec: string): string {
|
|
|
202
211
|
return spec.slice(0, atIndex);
|
|
203
212
|
}
|
|
204
213
|
|
|
214
|
+
function specRange(spec: string): string {
|
|
215
|
+
return spec.slice(specNamePackage(spec).length + 1);
|
|
216
|
+
}
|
|
217
|
+
|
|
205
218
|
// Ranges that don't come from the registry (git urls, file:, link:, npm: aliases) can't be pointed at a
|
|
206
|
-
// version number, so
|
|
219
|
+
// version number, so their entry has to stay separate.
|
|
207
220
|
function isRegistryRange(range: string): boolean {
|
|
208
221
|
return !range.includes(":") && !range.includes("/");
|
|
209
222
|
}
|
|
210
223
|
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
224
|
+
// yarn.lock quotes a token only when it would otherwise be ambiguous, and rewriting a token with different
|
|
225
|
+
// quoting than yarn would use makes every later install churn the file.
|
|
226
|
+
function quoteToken(value: string): string {
|
|
227
|
+
let needsQuotes = /[:\s\n\\",[\]]/.test(value) || !/^[a-zA-Z]/.test(value);
|
|
228
|
+
return needsQuotes ? `"${value}"` : value;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function formatHeader(specs: string[]): string {
|
|
232
|
+
return specs.map(quoteToken).join(", ") + ":";
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Put every registry spec for the package onto ONE entry resolving to the latest version. Nothing is deleted:
|
|
236
|
+
// a spec that asked for an old version (`pkg@1.2.3`) stays in the header and now points at the new version,
|
|
237
|
+
// which is what stops yarn from re-creating a second entry the next time something re-resolves.
|
|
238
|
+
function mergeLockEntries(lockPath: string, packageName: string, manifest: Manifest, newRange: string): {
|
|
239
|
+
specs: string[];
|
|
240
|
+
movedFrom: { spec: string; version: string }[];
|
|
241
|
+
leftAlone: string[];
|
|
218
242
|
} {
|
|
219
243
|
let lock = readLock(lockPath);
|
|
244
|
+
let specs = new Set<string>([`${packageName}@${newRange}`]);
|
|
245
|
+
let movedFrom: { spec: string; version: string }[] = [];
|
|
246
|
+
let leftAlone: string[] = [];
|
|
220
247
|
let removeLines = new Set<number>();
|
|
221
|
-
let
|
|
222
|
-
let
|
|
223
|
-
let skippedRequests: { requestedBy: string; range: string }[] = [];
|
|
248
|
+
let insertAt: number | undefined;
|
|
249
|
+
let body: string[] | undefined;
|
|
224
250
|
|
|
225
251
|
for (let block of lock.blocks) {
|
|
226
|
-
if (block.specs.some(spec => specNamePackage(spec) === packageName)) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
252
|
+
if (!block.specs.some(spec => specNamePackage(spec) === packageName)) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
let mergeable = block.specs.filter(spec => specNamePackage(spec) === packageName && isRegistryRange(specRange(spec)));
|
|
256
|
+
let keep = block.specs.filter(spec => !mergeable.includes(spec));
|
|
257
|
+
if (mergeable.length === 0) {
|
|
258
|
+
leftAlone.push(...block.specs);
|
|
231
259
|
continue;
|
|
232
260
|
}
|
|
233
261
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (!
|
|
237
|
-
|
|
262
|
+
let version = getBlockVersion(lock, block);
|
|
263
|
+
for (let spec of mergeable) {
|
|
264
|
+
if (!specs.has(spec) && version !== manifest.version) {
|
|
265
|
+
movedFrom.push({ spec, version: version ?? "?" });
|
|
238
266
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
lock.lines[i] = parsed.prefix + `"${newRange}"`;
|
|
247
|
-
rewrittenRequests++;
|
|
267
|
+
specs.add(spec);
|
|
268
|
+
}
|
|
269
|
+
// Reuse the real entry when the lockfile already holds the latest version, so we keep yarn's own
|
|
270
|
+
// resolved url and integrity hash rather than synthesizing them.
|
|
271
|
+
if (version === manifest.version && !body) {
|
|
272
|
+
body = lock.lines.slice(block.start + 1, blockBodyEnd(lock, block));
|
|
248
273
|
}
|
|
274
|
+
if (keep.length > 0) {
|
|
275
|
+
lock.lines[block.start] = formatHeader(keep);
|
|
276
|
+
leftAlone.push(...keep);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
insertAt = insertAt ?? block.start;
|
|
280
|
+
for (let i = block.start; i < block.end; i++) {
|
|
281
|
+
removeLines.add(i);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
let merged = [formatHeader(Array.from(specs).sort()), ...(body ?? synthesizeBody(manifest)), ""];
|
|
286
|
+
|
|
287
|
+
let output: string[] = [];
|
|
288
|
+
for (let i = 0; i < lock.lines.length; i++) {
|
|
289
|
+
if (i === insertAt) {
|
|
290
|
+
output.push(...merged);
|
|
291
|
+
}
|
|
292
|
+
if (removeLines.has(i)) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
output.push(lock.lines[i]);
|
|
296
|
+
}
|
|
297
|
+
if (insertAt === undefined) {
|
|
298
|
+
// The package wasn't in the lockfile at all; append and let yarn sort it.
|
|
299
|
+
output.push(...merged);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
fs.writeFileSync(lockPath, output.join(lock.eol));
|
|
303
|
+
return { specs: Array.from(specs).sort(), movedFrom, leftAlone };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// The lines a block owns, excluding the blank line(s) separating it from the next block.
|
|
307
|
+
function blockBodyEnd(lock: LockFile, block: LockBlock): number {
|
|
308
|
+
let end = block.end;
|
|
309
|
+
while (end > block.start + 1 && lock.lines[end - 1].trim() === "") {
|
|
310
|
+
end--;
|
|
249
311
|
}
|
|
312
|
+
return end;
|
|
313
|
+
}
|
|
250
314
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
315
|
+
function getBlockVersion(lock: LockFile, block: LockBlock): string | undefined {
|
|
316
|
+
for (let i = block.start + 1; i < block.end; i++) {
|
|
317
|
+
let match = /^\s+version "(.*)"$/.exec(lock.lines[i]);
|
|
318
|
+
if (match) {
|
|
319
|
+
return match[1];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return undefined;
|
|
254
323
|
}
|
|
255
324
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
325
|
+
// Build a lockfile entry for a version the lockfile has never seen, from the registry's own metadata.
|
|
326
|
+
function synthesizeBody(manifest: Manifest): string[] {
|
|
327
|
+
let tarball = manifest.dist?.tarball;
|
|
328
|
+
if (!tarball) {
|
|
329
|
+
throw new Error(`Registry response for ${manifest.version} had no dist.tarball, so no lockfile entry can be written`);
|
|
330
|
+
}
|
|
331
|
+
let resolved = tarball.replace(NPM_REGISTRY_HOST, YARN_REGISTRY_HOST);
|
|
332
|
+
if (manifest.dist?.shasum) {
|
|
333
|
+
resolved += "#" + manifest.dist.shasum;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
let lines = [` version ${quoteToken(manifest.version)}`, ` resolved ${quoteToken(resolved)}`];
|
|
337
|
+
if (manifest.dist?.integrity) {
|
|
338
|
+
lines.push(` integrity ${quoteToken(manifest.dist.integrity)}`);
|
|
260
339
|
}
|
|
261
|
-
let
|
|
262
|
-
|
|
263
|
-
|
|
340
|
+
for (let section of ["dependencies", "optionalDependencies"] as const) {
|
|
341
|
+
let deps = manifest[section];
|
|
342
|
+
if (!deps || Object.keys(deps).length === 0) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
lines.push(` ${section}:`);
|
|
346
|
+
for (let name of Object.keys(deps).sort()) {
|
|
347
|
+
lines.push(` ${quoteToken(name)} ${quoteToken(deps[name])}`);
|
|
348
|
+
}
|
|
264
349
|
}
|
|
265
|
-
return
|
|
350
|
+
return lines;
|
|
266
351
|
}
|
|
267
352
|
|
|
268
353
|
function getLockedVersions(lockPath: string, packageName: string): string[] {
|
|
@@ -275,11 +360,9 @@ function getLockedVersions(lockPath: string, packageName: string): string[] {
|
|
|
275
360
|
if (!block.specs.some(spec => specNamePackage(spec) === packageName)) {
|
|
276
361
|
continue;
|
|
277
362
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
versions.add(match[1]);
|
|
282
|
-
}
|
|
363
|
+
let version = getBlockVersion(lock, block);
|
|
364
|
+
if (version) {
|
|
365
|
+
versions.add(version);
|
|
283
366
|
}
|
|
284
367
|
}
|
|
285
368
|
return Array.from(versions);
|