socket-function 1.2.35 → 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.
@@ -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;
@@ -1576,7 +1563,6 @@ declare module "socket-function/src/storagePath" {
1576
1563
  }
1577
1564
 
1578
1565
  declare module "socket-function/src/tlsParsing" {
1579
- /// <reference types="node" />
1580
1566
  /// <reference types="node" />
1581
1567
  export declare function parseTLSHello(buffer: Buffer): {
1582
1568
  extensions: {
@@ -1606,7 +1592,6 @@ declare module "socket-function/src/upreal" {
1606
1592
  }
1607
1593
 
1608
1594
  declare module "socket-function/src/webSocketServer" {
1609
- /// <reference types="node" />
1610
1595
  /// <reference types="node" />
1611
1596
  /// <reference types="node" />
1612
1597
  import https from "https";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket-function",
3
- "version": "1.2.35",
3
+ "version": "1.2.36",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
@@ -1,6 +1,5 @@
1
1
  /// <reference path="../../typenode/index.d.ts" />
2
2
  /// <reference types="node" />
3
- /// <reference types="node" />
4
3
  declare global {
5
4
  namespace NodeJS {
6
5
  interface Module {
@@ -1,4 +1,3 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  export declare function getExtContentType(ext: string): string;
4
3
  export declare function getContentTypeFromBuffer(buffer: Buffer): string | undefined;
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- /// <reference types="node" />
4
3
  import { CallType } from "../SocketFunctionTypes";
5
4
  import * as ws from "ws";
6
5
  import * as tls from "tls";
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  export interface JSONLACKS_ParseConfig {
4
3
  extended?: boolean;
5
4
  discardMissingReferences?: boolean;
package/src/Zip.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  import { MaybePromise } from "./types";
4
3
  export declare class Zip {
5
4
  static gzip(buffer: Buffer, level?: number): Promise<Buffer>;
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;
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- /// <reference types="node" />
4
3
  import http from "http";
5
4
  import { CallType } from "../SocketFunctionTypes";
6
5
  export declare function setDefaultHTTPCall(call: CallType): void;
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  /** Must be populated before the server starts */
4
3
  export declare function trustCertificate(cert: string | Buffer): void;
5
4
  export declare function getTrustedCertificates(): string[];
package/src/https.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  export interface HttpsResponseInfo {
4
3
  statusCode?: number;
5
4
  statusMessage?: string;
package/src/lz4/LZ4.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  export declare class LZ4 {
4
3
  static compress(data: Buffer): Buffer;
5
4
  static compressUntracked(data: Buffer): Buffer;
package/src/misc.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  import { MaybePromise } from "./types";
4
3
  export declare const timeInSecond = 1000;
5
4
  export declare const timeInMinute: number;
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  export declare function parseTLSHello(buffer: Buffer): {
4
3
  extensions: {
5
4
  type: number;
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 packageName = process.argv.slice(2).find(arg => !arg.startsWith("-"));
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 packageJsonRaw = fs.readFileSync(packageJsonPath, "utf8");
27
- let packageJson = JSON.parse(packageJsonRaw) as {
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 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
- }
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
- console.log(`Current range for ${packageName}: ${currentRange}`);
54
+ if (dryRun) {
55
+ console.log(`Dry run: package.json and yarn.lock are rewritten, skipping yarn install.`);
56
+ return;
57
+ }
39
58
 
40
- let latest = await getLatestVersion(packageName);
41
- console.log(`Latest version of ${packageName}: ${latest}`);
59
+ console.log(`Running yarn install...`);
60
+ await runYarnInstall(projectRoot);
42
61
 
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.`);
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
- console.log(`Running yarn install...`);
65
- await runYarnInstall(projectRoot);
66
- console.log(`Done. ${packageName} is now at ${newRange}.`);
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
- function findCurrentRange(
70
- packageJson: { [section: string]: { [name: string]: string } | undefined },
71
- packageName: string
72
- ): string | undefined {
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 && packageName in deps) {
76
- return deps[packageName];
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 undefined;
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
- // Remove all yarn.lock v1 blocks that resolve the given package (across every range variant of it).
124
- function removeLockEntries(lockRaw: string, packageName: string): { lock: string; removed: number } {
125
- // yarn.lock v1 blocks are separated by blank lines; the first line of each block is the comma-separated
126
- // list of specs it satisfies, e.g. `"pkg@^1.0.0", "pkg@~1.2.0":`.
127
- let blocks = lockRaw.split(/\r?\n\r?\n/);
128
- let removed = 0;
129
- let kept: string[] = [];
130
- for (let block of blocks) {
131
- if (blockResolvesPackage(block, packageName)) {
132
- removed++;
133
- continue;
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 { lock: kept.join("\n\n"), removed };
179
+ return { lines, eol, blocks };
138
180
  }
139
181
 
140
- function blockResolvesPackage(block: string, packageName: string): boolean {
141
- let headerLine = block.split(/\r?\n/).find(line => line.trim().length > 0 && !line.startsWith("#"));
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
- // Strip the trailing colon, then split on commas into individual quoted-or-bare specs.
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
- let specs = specsPart.split(",").map(spec => spec.trim().replace(/^"|"$/g, ""));
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
  }
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- /// <reference types="node" />
4
3
  import https from "https";
5
4
  import { Watchable } from "./misc";
6
5
  export type SocketServerConfig = (https.ServerOptions & {