@vercel/python-analysis 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +105 -40
- package/dist/index.d.ts +1 -1
- package/dist/index.js +105 -41
- package/dist/manifest/dist-metadata.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -66,9 +66,10 @@ __export(src_exports, {
|
|
|
66
66
|
containsAppOrHandler: () => containsAppOrHandler,
|
|
67
67
|
createMinimalManifest: () => createMinimalManifest,
|
|
68
68
|
discoverPythonPackage: () => discoverPythonPackage,
|
|
69
|
+
extendDistRecord: () => extendDistRecord,
|
|
69
70
|
getStringConstant: () => getStringConstant,
|
|
70
71
|
isPrivatePackageSource: () => isPrivatePackageSource,
|
|
71
|
-
normalizePackageName: () =>
|
|
72
|
+
normalizePackageName: () => normalizePackageName2,
|
|
72
73
|
parseDjangoSettingsModule: () => parseDjangoSettingsModule,
|
|
73
74
|
parseUvLock: () => parseUvLock,
|
|
74
75
|
scanDistributions: () => scanDistributions,
|
|
@@ -139,8 +140,51 @@ async function parseDjangoSettingsModule(content) {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
// src/manifest/dist-metadata.ts
|
|
143
|
+
var import_node_crypto = require("crypto");
|
|
144
|
+
var import_node_fs = require("fs");
|
|
142
145
|
var import_promises2 = require("fs/promises");
|
|
143
146
|
var import_node_path2 = require("path");
|
|
147
|
+
|
|
148
|
+
// src/manifest/pep508.ts
|
|
149
|
+
var EXTRAS_REGEX = /^(.+)\[([^\]]+)\]$/;
|
|
150
|
+
function splitExtras(spec) {
|
|
151
|
+
const match = EXTRAS_REGEX.exec(spec);
|
|
152
|
+
if (!match) {
|
|
153
|
+
return [spec, void 0];
|
|
154
|
+
}
|
|
155
|
+
const extras = match[2].split(",").map((e) => e.trim());
|
|
156
|
+
return [match[1], extras];
|
|
157
|
+
}
|
|
158
|
+
function normalizePackageName(name) {
|
|
159
|
+
return name.toLowerCase().replace(/[-_.]+/g, "-");
|
|
160
|
+
}
|
|
161
|
+
function formatPep508(req) {
|
|
162
|
+
let result = req.name;
|
|
163
|
+
if (req.extras && req.extras.length > 0) {
|
|
164
|
+
result += `[${req.extras.join(",")}]`;
|
|
165
|
+
}
|
|
166
|
+
if (req.url) {
|
|
167
|
+
result += ` @ ${req.url}`;
|
|
168
|
+
} else if (req.version && req.version !== "*") {
|
|
169
|
+
result += req.version;
|
|
170
|
+
}
|
|
171
|
+
if (req.markers) {
|
|
172
|
+
result += ` ; ${req.markers}`;
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
function mergeExtras(existing, additional) {
|
|
177
|
+
const result = new Set(existing || []);
|
|
178
|
+
if (additional) {
|
|
179
|
+
const additionalArray = Array.isArray(additional) ? additional : [additional];
|
|
180
|
+
for (const extra of additionalArray) {
|
|
181
|
+
result.add(extra);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return result.size > 0 ? Array.from(result) : void 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/manifest/dist-metadata.ts
|
|
144
188
|
async function readDistInfoFile(distInfoDir, filename) {
|
|
145
189
|
try {
|
|
146
190
|
return await (0, import_promises2.readFile)((0, import_node_path2.join)(distInfoDir, filename), "utf-8");
|
|
@@ -227,6 +271,62 @@ async function scanDistributions(sitePackagesDir) {
|
|
|
227
271
|
}
|
|
228
272
|
return index;
|
|
229
273
|
}
|
|
274
|
+
function hashFile(filePath) {
|
|
275
|
+
return new Promise((resolve, reject) => {
|
|
276
|
+
const h = (0, import_node_crypto.createHash)("sha256");
|
|
277
|
+
let size = 0;
|
|
278
|
+
const stream = (0, import_node_fs.createReadStream)(filePath);
|
|
279
|
+
stream.on("data", (chunk) => {
|
|
280
|
+
size += chunk.length;
|
|
281
|
+
h.update(chunk);
|
|
282
|
+
});
|
|
283
|
+
stream.on("error", reject);
|
|
284
|
+
stream.on("end", () => {
|
|
285
|
+
resolve({ hash: h.digest("base64url"), size });
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async function extendDistRecord(sitePackagesDir, packageName, paths) {
|
|
290
|
+
const normalizedTarget = normalizePackageName(packageName);
|
|
291
|
+
const entries = await (0, import_promises2.readdir)(sitePackagesDir);
|
|
292
|
+
const distInfoDirName = entries.find((e) => {
|
|
293
|
+
if (!e.endsWith(".dist-info"))
|
|
294
|
+
return false;
|
|
295
|
+
const withoutSuffix = e.slice(0, -".dist-info".length);
|
|
296
|
+
const lastHyphen = withoutSuffix.lastIndexOf("-");
|
|
297
|
+
if (lastHyphen === -1)
|
|
298
|
+
return false;
|
|
299
|
+
const dirName = withoutSuffix.slice(0, lastHyphen);
|
|
300
|
+
return normalizePackageName(dirName) === normalizedTarget;
|
|
301
|
+
});
|
|
302
|
+
if (!distInfoDirName) {
|
|
303
|
+
throw new Error(
|
|
304
|
+
`No .dist-info directory found for package "${packageName}" in ${sitePackagesDir}`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const recordPath = (0, import_node_path2.join)(sitePackagesDir, distInfoDirName, "RECORD");
|
|
308
|
+
let existingRecord;
|
|
309
|
+
try {
|
|
310
|
+
existingRecord = await (0, import_promises2.readFile)(recordPath, "utf-8");
|
|
311
|
+
} catch {
|
|
312
|
+
throw new Error(`RECORD file not found in ${distInfoDirName}`);
|
|
313
|
+
}
|
|
314
|
+
const existingPaths = new Set(
|
|
315
|
+
existingRecord.split("\n").filter((line) => line.length > 0).map((line) => line.split(",")[0])
|
|
316
|
+
);
|
|
317
|
+
const newEntries = paths.filter((p) => !existingPaths.has(p));
|
|
318
|
+
if (newEntries.length > 0) {
|
|
319
|
+
const prefix = existingRecord.length > 0 && !existingRecord.endsWith("\n") ? "\n" : "";
|
|
320
|
+
const lines = [];
|
|
321
|
+
for (const p of newEntries) {
|
|
322
|
+
const fullPath = (0, import_node_path2.join)(sitePackagesDir, p);
|
|
323
|
+
const { hash, size } = await hashFile(fullPath);
|
|
324
|
+
lines.push(`${p},sha256=${hash},${size}`);
|
|
325
|
+
}
|
|
326
|
+
await (0, import_promises2.appendFile)(recordPath, prefix + lines.join("\n") + "\n");
|
|
327
|
+
}
|
|
328
|
+
return newEntries.length;
|
|
329
|
+
}
|
|
230
330
|
|
|
231
331
|
// src/manifest/package.ts
|
|
232
332
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
@@ -447,42 +547,6 @@ var PipfileLikeSchema = pipfileLikeSchema;
|
|
|
447
547
|
var PipfileLockMetaSchema = pipfileLockMetaSchema.passthrough();
|
|
448
548
|
var PipfileLockLikeSchema = pipfileLockLikeSchema;
|
|
449
549
|
|
|
450
|
-
// src/manifest/pep508.ts
|
|
451
|
-
var EXTRAS_REGEX = /^(.+)\[([^\]]+)\]$/;
|
|
452
|
-
function splitExtras(spec) {
|
|
453
|
-
const match = EXTRAS_REGEX.exec(spec);
|
|
454
|
-
if (!match) {
|
|
455
|
-
return [spec, void 0];
|
|
456
|
-
}
|
|
457
|
-
const extras = match[2].split(",").map((e) => e.trim());
|
|
458
|
-
return [match[1], extras];
|
|
459
|
-
}
|
|
460
|
-
function formatPep508(req) {
|
|
461
|
-
let result = req.name;
|
|
462
|
-
if (req.extras && req.extras.length > 0) {
|
|
463
|
-
result += `[${req.extras.join(",")}]`;
|
|
464
|
-
}
|
|
465
|
-
if (req.url) {
|
|
466
|
-
result += ` @ ${req.url}`;
|
|
467
|
-
} else if (req.version && req.version !== "*") {
|
|
468
|
-
result += req.version;
|
|
469
|
-
}
|
|
470
|
-
if (req.markers) {
|
|
471
|
-
result += ` ; ${req.markers}`;
|
|
472
|
-
}
|
|
473
|
-
return result;
|
|
474
|
-
}
|
|
475
|
-
function mergeExtras(existing, additional) {
|
|
476
|
-
const result = new Set(existing || []);
|
|
477
|
-
if (additional) {
|
|
478
|
-
const additionalArray = Array.isArray(additional) ? additional : [additional];
|
|
479
|
-
for (const extra of additionalArray) {
|
|
480
|
-
result.add(extra);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return result.size > 0 ? Array.from(result) : void 0;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
550
|
// src/util/type.ts
|
|
487
551
|
function isPlainObject(value) {
|
|
488
552
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -2280,7 +2344,7 @@ function isPrivatePackageSource(source) {
|
|
|
2280
2344
|
}
|
|
2281
2345
|
return false;
|
|
2282
2346
|
}
|
|
2283
|
-
function
|
|
2347
|
+
function normalizePackageName2(name) {
|
|
2284
2348
|
return name.toLowerCase().replace(/[-_.]+/g, "-");
|
|
2285
2349
|
}
|
|
2286
2350
|
function classifyPackages(options) {
|
|
@@ -2288,9 +2352,9 @@ function classifyPackages(options) {
|
|
|
2288
2352
|
const privatePackages = [];
|
|
2289
2353
|
const publicPackages = [];
|
|
2290
2354
|
const packageVersions = {};
|
|
2291
|
-
const excludeSet = new Set(excludePackages.map(
|
|
2355
|
+
const excludeSet = new Set(excludePackages.map(normalizePackageName2));
|
|
2292
2356
|
for (const pkg of lockFile.packages) {
|
|
2293
|
-
if (excludeSet.has(
|
|
2357
|
+
if (excludeSet.has(normalizePackageName2(pkg.name))) {
|
|
2294
2358
|
continue;
|
|
2295
2359
|
}
|
|
2296
2360
|
packageVersions[pkg.name] = pkg.version;
|
|
@@ -2490,6 +2554,7 @@ var HashDigestSchema = hashDigestSchema;
|
|
|
2490
2554
|
containsAppOrHandler,
|
|
2491
2555
|
createMinimalManifest,
|
|
2492
2556
|
discoverPythonPackage,
|
|
2557
|
+
extendDistRecord,
|
|
2493
2558
|
getStringConstant,
|
|
2494
2559
|
isPrivatePackageSource,
|
|
2495
2560
|
normalizePackageName,
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { containsAppOrHandler, getStringConstant, parseDjangoSettingsModule, } from './semantic/entrypoints';
|
|
10
10
|
export type { Distribution, DistributionIndex, PackagePath, DirectUrlInfo, } from './manifest/dist-metadata';
|
|
11
|
-
export { scanDistributions } from './manifest/dist-metadata';
|
|
11
|
+
export { extendDistRecord, scanDistributions } from './manifest/dist-metadata';
|
|
12
12
|
export type { PythonConfig, PythonConfigs, PythonLockFile, PythonManifest, PythonManifestOrigin, PythonPackage, PythonVersionConfig, } from './manifest/package';
|
|
13
13
|
export { discoverPythonPackage, PythonConfigKind, PythonLockFileKind, PythonManifestConvertedKind, PythonManifestKind, } from './manifest/package';
|
|
14
14
|
export { createMinimalManifest, stringifyManifest, type CreateMinimalManifestOptions, } from './manifest/serialize';
|
package/dist/index.js
CHANGED
|
@@ -60,8 +60,51 @@ async function parseDjangoSettingsModule(content) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// src/manifest/dist-metadata.ts
|
|
63
|
-
import {
|
|
63
|
+
import { createHash } from "crypto";
|
|
64
|
+
import { createReadStream } from "fs";
|
|
65
|
+
import { appendFile, readdir, readFile as readFile2 } from "fs/promises";
|
|
64
66
|
import { join as join2 } from "path";
|
|
67
|
+
|
|
68
|
+
// src/manifest/pep508.ts
|
|
69
|
+
var EXTRAS_REGEX = /^(.+)\[([^\]]+)\]$/;
|
|
70
|
+
function splitExtras(spec) {
|
|
71
|
+
const match = EXTRAS_REGEX.exec(spec);
|
|
72
|
+
if (!match) {
|
|
73
|
+
return [spec, void 0];
|
|
74
|
+
}
|
|
75
|
+
const extras = match[2].split(",").map((e) => e.trim());
|
|
76
|
+
return [match[1], extras];
|
|
77
|
+
}
|
|
78
|
+
function normalizePackageName(name) {
|
|
79
|
+
return name.toLowerCase().replace(/[-_.]+/g, "-");
|
|
80
|
+
}
|
|
81
|
+
function formatPep508(req) {
|
|
82
|
+
let result = req.name;
|
|
83
|
+
if (req.extras && req.extras.length > 0) {
|
|
84
|
+
result += `[${req.extras.join(",")}]`;
|
|
85
|
+
}
|
|
86
|
+
if (req.url) {
|
|
87
|
+
result += ` @ ${req.url}`;
|
|
88
|
+
} else if (req.version && req.version !== "*") {
|
|
89
|
+
result += req.version;
|
|
90
|
+
}
|
|
91
|
+
if (req.markers) {
|
|
92
|
+
result += ` ; ${req.markers}`;
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function mergeExtras(existing, additional) {
|
|
97
|
+
const result = new Set(existing || []);
|
|
98
|
+
if (additional) {
|
|
99
|
+
const additionalArray = Array.isArray(additional) ? additional : [additional];
|
|
100
|
+
for (const extra of additionalArray) {
|
|
101
|
+
result.add(extra);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return result.size > 0 ? Array.from(result) : void 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/manifest/dist-metadata.ts
|
|
65
108
|
async function readDistInfoFile(distInfoDir, filename) {
|
|
66
109
|
try {
|
|
67
110
|
return await readFile2(join2(distInfoDir, filename), "utf-8");
|
|
@@ -148,6 +191,62 @@ async function scanDistributions(sitePackagesDir) {
|
|
|
148
191
|
}
|
|
149
192
|
return index;
|
|
150
193
|
}
|
|
194
|
+
function hashFile(filePath) {
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
const h = createHash("sha256");
|
|
197
|
+
let size = 0;
|
|
198
|
+
const stream = createReadStream(filePath);
|
|
199
|
+
stream.on("data", (chunk) => {
|
|
200
|
+
size += chunk.length;
|
|
201
|
+
h.update(chunk);
|
|
202
|
+
});
|
|
203
|
+
stream.on("error", reject);
|
|
204
|
+
stream.on("end", () => {
|
|
205
|
+
resolve({ hash: h.digest("base64url"), size });
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async function extendDistRecord(sitePackagesDir, packageName, paths) {
|
|
210
|
+
const normalizedTarget = normalizePackageName(packageName);
|
|
211
|
+
const entries = await readdir(sitePackagesDir);
|
|
212
|
+
const distInfoDirName = entries.find((e) => {
|
|
213
|
+
if (!e.endsWith(".dist-info"))
|
|
214
|
+
return false;
|
|
215
|
+
const withoutSuffix = e.slice(0, -".dist-info".length);
|
|
216
|
+
const lastHyphen = withoutSuffix.lastIndexOf("-");
|
|
217
|
+
if (lastHyphen === -1)
|
|
218
|
+
return false;
|
|
219
|
+
const dirName = withoutSuffix.slice(0, lastHyphen);
|
|
220
|
+
return normalizePackageName(dirName) === normalizedTarget;
|
|
221
|
+
});
|
|
222
|
+
if (!distInfoDirName) {
|
|
223
|
+
throw new Error(
|
|
224
|
+
`No .dist-info directory found for package "${packageName}" in ${sitePackagesDir}`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
const recordPath = join2(sitePackagesDir, distInfoDirName, "RECORD");
|
|
228
|
+
let existingRecord;
|
|
229
|
+
try {
|
|
230
|
+
existingRecord = await readFile2(recordPath, "utf-8");
|
|
231
|
+
} catch {
|
|
232
|
+
throw new Error(`RECORD file not found in ${distInfoDirName}`);
|
|
233
|
+
}
|
|
234
|
+
const existingPaths = new Set(
|
|
235
|
+
existingRecord.split("\n").filter((line) => line.length > 0).map((line) => line.split(",")[0])
|
|
236
|
+
);
|
|
237
|
+
const newEntries = paths.filter((p) => !existingPaths.has(p));
|
|
238
|
+
if (newEntries.length > 0) {
|
|
239
|
+
const prefix = existingRecord.length > 0 && !existingRecord.endsWith("\n") ? "\n" : "";
|
|
240
|
+
const lines = [];
|
|
241
|
+
for (const p of newEntries) {
|
|
242
|
+
const fullPath = join2(sitePackagesDir, p);
|
|
243
|
+
const { hash, size } = await hashFile(fullPath);
|
|
244
|
+
lines.push(`${p},sha256=${hash},${size}`);
|
|
245
|
+
}
|
|
246
|
+
await appendFile(recordPath, prefix + lines.join("\n") + "\n");
|
|
247
|
+
}
|
|
248
|
+
return newEntries.length;
|
|
249
|
+
}
|
|
151
250
|
|
|
152
251
|
// src/manifest/package.ts
|
|
153
252
|
import path3 from "path";
|
|
@@ -371,42 +470,6 @@ var PipfileLikeSchema = pipfileLikeSchema;
|
|
|
371
470
|
var PipfileLockMetaSchema = pipfileLockMetaSchema.passthrough();
|
|
372
471
|
var PipfileLockLikeSchema = pipfileLockLikeSchema;
|
|
373
472
|
|
|
374
|
-
// src/manifest/pep508.ts
|
|
375
|
-
var EXTRAS_REGEX = /^(.+)\[([^\]]+)\]$/;
|
|
376
|
-
function splitExtras(spec) {
|
|
377
|
-
const match = EXTRAS_REGEX.exec(spec);
|
|
378
|
-
if (!match) {
|
|
379
|
-
return [spec, void 0];
|
|
380
|
-
}
|
|
381
|
-
const extras = match[2].split(",").map((e) => e.trim());
|
|
382
|
-
return [match[1], extras];
|
|
383
|
-
}
|
|
384
|
-
function formatPep508(req) {
|
|
385
|
-
let result = req.name;
|
|
386
|
-
if (req.extras && req.extras.length > 0) {
|
|
387
|
-
result += `[${req.extras.join(",")}]`;
|
|
388
|
-
}
|
|
389
|
-
if (req.url) {
|
|
390
|
-
result += ` @ ${req.url}`;
|
|
391
|
-
} else if (req.version && req.version !== "*") {
|
|
392
|
-
result += req.version;
|
|
393
|
-
}
|
|
394
|
-
if (req.markers) {
|
|
395
|
-
result += ` ; ${req.markers}`;
|
|
396
|
-
}
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
function mergeExtras(existing, additional) {
|
|
400
|
-
const result = new Set(existing || []);
|
|
401
|
-
if (additional) {
|
|
402
|
-
const additionalArray = Array.isArray(additional) ? additional : [additional];
|
|
403
|
-
for (const extra of additionalArray) {
|
|
404
|
-
result.add(extra);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return result.size > 0 ? Array.from(result) : void 0;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
473
|
// src/util/type.ts
|
|
411
474
|
function isPlainObject(value) {
|
|
412
475
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -2204,7 +2267,7 @@ function isPrivatePackageSource(source) {
|
|
|
2204
2267
|
}
|
|
2205
2268
|
return false;
|
|
2206
2269
|
}
|
|
2207
|
-
function
|
|
2270
|
+
function normalizePackageName2(name) {
|
|
2208
2271
|
return name.toLowerCase().replace(/[-_.]+/g, "-");
|
|
2209
2272
|
}
|
|
2210
2273
|
function classifyPackages(options) {
|
|
@@ -2212,9 +2275,9 @@ function classifyPackages(options) {
|
|
|
2212
2275
|
const privatePackages = [];
|
|
2213
2276
|
const publicPackages = [];
|
|
2214
2277
|
const packageVersions = {};
|
|
2215
|
-
const excludeSet = new Set(excludePackages.map(
|
|
2278
|
+
const excludeSet = new Set(excludePackages.map(normalizePackageName2));
|
|
2216
2279
|
for (const pkg of lockFile.packages) {
|
|
2217
|
-
if (excludeSet.has(
|
|
2280
|
+
if (excludeSet.has(normalizePackageName2(pkg.name))) {
|
|
2218
2281
|
continue;
|
|
2219
2282
|
}
|
|
2220
2283
|
packageVersions[pkg.name] = pkg.version;
|
|
@@ -2413,9 +2476,10 @@ export {
|
|
|
2413
2476
|
containsAppOrHandler,
|
|
2414
2477
|
createMinimalManifest,
|
|
2415
2478
|
discoverPythonPackage,
|
|
2479
|
+
extendDistRecord,
|
|
2416
2480
|
getStringConstant,
|
|
2417
2481
|
isPrivatePackageSource,
|
|
2418
|
-
normalizePackageName,
|
|
2482
|
+
normalizePackageName2 as normalizePackageName,
|
|
2419
2483
|
parseDjangoSettingsModule,
|
|
2420
2484
|
parseUvLock,
|
|
2421
2485
|
scanDistributions,
|
|
@@ -101,3 +101,17 @@ export type DistributionIndex = Map<string, Distribution>;
|
|
|
101
101
|
* @returns Map of normalized package name to distribution info
|
|
102
102
|
*/
|
|
103
103
|
export declare function scanDistributions(sitePackagesDir: string): Promise<DistributionIndex>;
|
|
104
|
+
/**
|
|
105
|
+
* Append new file entries to a distribution's RECORD file.
|
|
106
|
+
*
|
|
107
|
+
* Finds the `.dist-info` directory for the given package, reads its RECORD,
|
|
108
|
+
* and appends any paths not already tracked. The caller is responsible for
|
|
109
|
+
* scanning directories and building the path list.
|
|
110
|
+
*
|
|
111
|
+
* @param sitePackagesDir - Absolute path to a site-packages directory
|
|
112
|
+
* @param packageName - Distribution name (matched via PEP 503 normalization)
|
|
113
|
+
* @param paths - File paths relative to site-packages to add
|
|
114
|
+
* @returns Count of new entries appended (skips paths already in RECORD)
|
|
115
|
+
* @throws If the dist-info directory or RECORD file is not found
|
|
116
|
+
*/
|
|
117
|
+
export declare function extendDistRecord(sitePackagesDir: string, packageName: string, paths: string[]): Promise<number>;
|