@absolutejs/changelog 0.2.0 → 0.3.0
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/CHANGELOG.md +31 -0
- package/README.md +41 -4
- package/changelog.json +97 -0
- package/dist/apply.d.ts +3 -5
- package/dist/cli.js +244 -133
- package/dist/cli.js.map +9 -9
- package/dist/entries.d.ts +16 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +464 -224
- package/dist/index.js.map +9 -9
- package/dist/reconcile.d.ts +3 -3
- package/dist/registry.d.ts +1 -0
- package/dist/surface.d.ts +21 -22
- package/dist/write.d.ts +9 -0
- package/package.json +74 -71
package/dist/cli.js
CHANGED
|
@@ -269,6 +269,10 @@ var migrationsBetween = (changelog, from, upto) => disruptiveBetween(changelog,
|
|
|
269
269
|
});
|
|
270
270
|
var symbolsDisturbedBetween = (changelog, from, upto) => new Set(disruptiveBetween(changelog, from, upto).flatMap(({ change }) => change.symbols));
|
|
271
271
|
|
|
272
|
+
// src/surface.ts
|
|
273
|
+
import path from "path";
|
|
274
|
+
import ts from "typescript";
|
|
275
|
+
|
|
272
276
|
// src/tarball.ts
|
|
273
277
|
var TAR_BLOCK = 512;
|
|
274
278
|
var NAME_LENGTH = 100;
|
|
@@ -321,114 +325,185 @@ var readTar = (archive, keep, limits = {}) => {
|
|
|
321
325
|
};
|
|
322
326
|
|
|
323
327
|
// src/surface.ts
|
|
324
|
-
var DECLARATION =
|
|
325
|
-
var
|
|
326
|
-
var
|
|
327
|
-
var
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
var
|
|
350
|
-
var reExported = (body) => body.split(",").map((part) => part.trim().replace(/^type\s+/u, "")).filter((clause) => clause !== "").map((clause) => [
|
|
351
|
-
clause.split(/\s+as\s+/u).at(LAST2)?.trim(),
|
|
352
|
-
clause
|
|
353
|
-
]).filter((pair) => pair[0] !== undefined && IDENTIFIER.test(pair[0]));
|
|
354
|
-
var exportedDeclarations = (source) => {
|
|
328
|
+
var DECLARATION = /\.d\.[cm]?ts$/u;
|
|
329
|
+
var parse = (source, name) => ts.createSourceFile(name, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
330
|
+
var normalize = (text) => text.replace(/\s+/gu, " ").trim();
|
|
331
|
+
var resolveFrom = (files, from, specifier) => {
|
|
332
|
+
if (!specifier.startsWith("."))
|
|
333
|
+
return;
|
|
334
|
+
const base = path.posix.join(path.posix.dirname(from), specifier);
|
|
335
|
+
const candidates = [
|
|
336
|
+
base,
|
|
337
|
+
`${base.replace(/\.js$/u, "")}.d.ts`,
|
|
338
|
+
`${base.replace(/\.js$/u, "")}.d.mts`,
|
|
339
|
+
`${base.replace(/\.js$/u, "")}.d.cts`,
|
|
340
|
+
`${base}/index.d.ts`,
|
|
341
|
+
`${base}/index.d.mts`,
|
|
342
|
+
`${base}/index.d.cts`
|
|
343
|
+
];
|
|
344
|
+
return candidates.find((candidate) => files.has(candidate));
|
|
345
|
+
};
|
|
346
|
+
var declaredNameOf = (statement) => {
|
|
347
|
+
if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isEnumDeclaration(statement) || ts.isModuleDeclaration(statement))
|
|
348
|
+
return statement.name !== undefined && ts.isIdentifier(statement.name) ? statement.name.text : undefined;
|
|
349
|
+
return;
|
|
350
|
+
};
|
|
351
|
+
var isExported = (statement) => ts.canHaveModifiers(statement) && ts.getModifiers(statement)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) === true;
|
|
352
|
+
var variableNamesOf = (statement) => statement.declarationList.declarations.map((declaration) => declaration.name).filter((name) => ts.isIdentifier(name)).map((name) => name.text);
|
|
353
|
+
var declarationsIn = (file) => {
|
|
355
354
|
const found = new Map;
|
|
356
|
-
const
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const [, keyword, name] = match;
|
|
363
|
-
if (name === undefined || match.index === undefined)
|
|
355
|
+
for (const statement of file.statements) {
|
|
356
|
+
const text = normalize(statement.getText(file));
|
|
357
|
+
const named = declaredNameOf(statement);
|
|
358
|
+
if (named !== undefined)
|
|
359
|
+
found.set(named, text);
|
|
360
|
+
if (!ts.isVariableStatement(statement))
|
|
364
361
|
continue;
|
|
365
|
-
|
|
362
|
+
for (const name of variableNamesOf(statement))
|
|
363
|
+
found.set(name, text);
|
|
366
364
|
}
|
|
367
|
-
for (const match of source.matchAll(NAMED_EXPORT))
|
|
368
|
-
for (const [exported, clause] of reExported(match[1] ?? ""))
|
|
369
|
-
add(exported, `export { ${clause} }`);
|
|
370
365
|
return found;
|
|
371
366
|
};
|
|
372
|
-
var
|
|
373
|
-
|
|
367
|
+
var declaresTypes = (manifest) => {
|
|
368
|
+
if (typeof manifest !== "object" || manifest === null)
|
|
369
|
+
return false;
|
|
370
|
+
const record = new Map(Object.entries(manifest));
|
|
371
|
+
if (typeof record.get("types") === "string")
|
|
372
|
+
return true;
|
|
373
|
+
if (typeof record.get("typings") === "string")
|
|
374
|
+
return true;
|
|
375
|
+
return JSON.stringify(record.get("exports") ?? {}).includes('"types"');
|
|
376
|
+
};
|
|
377
|
+
var contributionOf = (input) => {
|
|
378
|
+
const { file, files, from, local, seen, statement } = input;
|
|
379
|
+
const nothing = [];
|
|
380
|
+
if (ts.isExportAssignment(statement))
|
|
381
|
+
return [
|
|
382
|
+
[
|
|
383
|
+
statement.isExportEquals === true ? "export=" : "default",
|
|
384
|
+
normalize(statement.getText(file))
|
|
385
|
+
]
|
|
386
|
+
];
|
|
387
|
+
const named = declaredNameOf(statement);
|
|
388
|
+
if (named !== undefined && isExported(statement))
|
|
389
|
+
return [
|
|
390
|
+
[named, local.get(named) ?? normalize(statement.getText(file))]
|
|
391
|
+
];
|
|
392
|
+
if (ts.isVariableStatement(statement) && isExported(statement)) {
|
|
393
|
+
const text = normalize(statement.getText(file));
|
|
394
|
+
return variableNamesOf(statement).map((name) => [name, text]);
|
|
395
|
+
}
|
|
396
|
+
if (!ts.isExportDeclaration(statement))
|
|
397
|
+
return nothing;
|
|
398
|
+
const specifier = statement.moduleSpecifier !== undefined && ts.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : undefined;
|
|
399
|
+
const target = specifier === undefined ? undefined : resolveFrom(files, from, specifier);
|
|
400
|
+
const theirs = target === undefined ? new Map : exportsOf(files, target, new Set(seen));
|
|
401
|
+
const clause = statement.exportClause;
|
|
402
|
+
if (clause === undefined)
|
|
403
|
+
return [...theirs].filter(([name]) => name !== "default" && name !== "export=");
|
|
404
|
+
if (ts.isNamespaceExport(clause))
|
|
405
|
+
return [[clause.name.text, `export * as ${clause.name.text}`]];
|
|
406
|
+
return clause.elements.map((element) => {
|
|
407
|
+
const sourceName = (element.propertyName ?? element.name).text;
|
|
408
|
+
const text = (specifier === undefined ? local.get(sourceName) : theirs.get(sourceName)) ?? `export { ${sourceName} }`;
|
|
409
|
+
return [element.name.text, text];
|
|
410
|
+
});
|
|
411
|
+
};
|
|
412
|
+
var exportsOf = (files, from, seen) => {
|
|
374
413
|
const surface = new Map;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
414
|
+
const source = files.get(from);
|
|
415
|
+
if (source === undefined || seen.has(from))
|
|
416
|
+
return surface;
|
|
417
|
+
seen.add(from);
|
|
418
|
+
const file = parse(source, from);
|
|
419
|
+
const local = declarationsIn(file);
|
|
420
|
+
const contributed = file.statements.flatMap((statement) => contributionOf({ file, files, from, local, seen, statement }));
|
|
421
|
+
for (const [name, text] of contributed)
|
|
422
|
+
surface.set(name, text);
|
|
423
|
+
return surface;
|
|
424
|
+
};
|
|
425
|
+
var surfaceOfArchive = (archive) => {
|
|
426
|
+
const held = readTar(archive, (name) => DECLARATION.test(name) || name === "package.json");
|
|
427
|
+
const files = new Map([...held].map(([name, bytes]) => [name, asText(bytes)]));
|
|
428
|
+
const manifest = files.get("package.json");
|
|
429
|
+
let parsed;
|
|
430
|
+
try {
|
|
431
|
+
parsed = manifest === undefined ? undefined : JSON.parse(manifest);
|
|
432
|
+
} catch {
|
|
433
|
+
parsed = undefined;
|
|
434
|
+
}
|
|
435
|
+
const entries = typeEntriesOf(parsed, files);
|
|
436
|
+
return entries.length === 0 ? undefined : surfaceOfFiles(files, entries);
|
|
437
|
+
};
|
|
438
|
+
var surfaceOfFiles = (files, entries) => {
|
|
439
|
+
const surface = new Map;
|
|
440
|
+
for (const entry of entries)
|
|
441
|
+
for (const [name, text] of exportsOf(files, entry, new Set))
|
|
442
|
+
if (!surface.has(name))
|
|
443
|
+
surface.set(name, text);
|
|
381
444
|
return surface;
|
|
382
445
|
};
|
|
446
|
+
var typeCandidatesIn = (value) => {
|
|
447
|
+
if (typeof value === "string")
|
|
448
|
+
return [value];
|
|
449
|
+
if (typeof value !== "object" || value === null)
|
|
450
|
+
return [];
|
|
451
|
+
return Object.entries(value).flatMap(([key, nested]) => key === "types" || key === "typings" ? typeCandidatesIn(nested) : typeCandidatesIn(nested));
|
|
452
|
+
};
|
|
453
|
+
var typeEntriesOf = (manifest, files) => {
|
|
454
|
+
const record = typeof manifest === "object" && manifest !== null ? new Map(Object.entries(manifest)) : new Map;
|
|
455
|
+
const claimed = [
|
|
456
|
+
record.get("types"),
|
|
457
|
+
record.get("typings"),
|
|
458
|
+
...typeCandidatesIn(record.get("exports"))
|
|
459
|
+
];
|
|
460
|
+
const entries = claimed.filter((value) => typeof value === "string").map((value) => value.replace(/^\.\//u, "")).flatMap((cleaned) => DECLARATION.test(cleaned) ? [cleaned] : [
|
|
461
|
+
cleaned.replace(/\.[cm]?js$/u, ".d.ts"),
|
|
462
|
+
cleaned.replace(/\.[cm]?js$/u, ".d.mts"),
|
|
463
|
+
cleaned.replace(/\.[cm]?js$/u, ".d.cts")
|
|
464
|
+
]).filter((candidate) => files.has(candidate));
|
|
465
|
+
const fallback = entries.length === 0 && files.has("dist/index.d.ts") ? ["dist/index.d.ts"] : [];
|
|
466
|
+
return [...new Set([...entries, ...fallback])];
|
|
467
|
+
};
|
|
383
468
|
var SHAPE = {
|
|
384
469
|
members: "members",
|
|
385
470
|
parameters: "parameters",
|
|
386
471
|
types: "types",
|
|
387
472
|
unknown: "unknown"
|
|
388
473
|
};
|
|
474
|
+
var isStub = (declaration) => declaration.startsWith("export {");
|
|
475
|
+
var signatureOf = (declaration) => {
|
|
476
|
+
const file = parse(`${declaration}
|
|
477
|
+
`, "declaration.d.ts");
|
|
478
|
+
const [statement] = file.statements;
|
|
479
|
+
if (statement === undefined)
|
|
480
|
+
return;
|
|
481
|
+
return statement;
|
|
482
|
+
};
|
|
389
483
|
var parametersOf = (declaration) => {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
return "";
|
|
484
|
+
const statement = signatureOf(declaration);
|
|
485
|
+
if (statement === undefined)
|
|
486
|
+
return "";
|
|
487
|
+
const found = [];
|
|
488
|
+
const visit = (node) => {
|
|
489
|
+
if (ts.isFunctionTypeNode(node) || ts.isFunctionDeclaration(node) || ts.isMethodSignature(node) || ts.isMethodDeclaration(node) || ts.isConstructSignatureDeclaration(node) || ts.isConstructorDeclaration(node))
|
|
490
|
+
found.push(node.parameters.map((parameter) => normalize(parameter.getText())).join(", "));
|
|
491
|
+
ts.forEachChild(node, visit);
|
|
492
|
+
};
|
|
493
|
+
visit(statement);
|
|
494
|
+
return found.join(" | ");
|
|
403
495
|
};
|
|
404
496
|
var membersOf = (declaration) => {
|
|
405
|
-
const
|
|
406
|
-
if (opened < 0)
|
|
407
|
-
return new Set;
|
|
497
|
+
const statement = signatureOf(declaration);
|
|
408
498
|
const members = new Set;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
segment = "";
|
|
499
|
+
if (statement === undefined)
|
|
500
|
+
return members;
|
|
501
|
+
const visit = (node) => {
|
|
502
|
+
if ((ts.isPropertySignature(node) || ts.isMethodSignature(node) || ts.isPropertyDeclaration(node) || ts.isMethodDeclaration(node) || ts.isEnumMember(node)) && node.name !== undefined && (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name)))
|
|
503
|
+
members.add(node.name.text);
|
|
504
|
+
ts.forEachChild(node, visit);
|
|
416
505
|
};
|
|
417
|
-
|
|
418
|
-
const opening = OPENS.has(character);
|
|
419
|
-
const closing = CLOSES.has(character);
|
|
420
|
-
depth += opening ? 1 : 0;
|
|
421
|
-
if (opening && depth === 1)
|
|
422
|
-
segment = "";
|
|
423
|
-
depth -= closing ? 1 : 0;
|
|
424
|
-
if (opening || closing || depth !== 1)
|
|
425
|
-
continue;
|
|
426
|
-
if (character === ";" || character === ",")
|
|
427
|
-
take();
|
|
428
|
-
else
|
|
429
|
-
segment += character;
|
|
430
|
-
}
|
|
431
|
-
take();
|
|
506
|
+
visit(statement);
|
|
432
507
|
return members;
|
|
433
508
|
};
|
|
434
509
|
var sameNames = (left, right) => left.size === right.size && [...left].every((name) => right.has(name));
|
|
@@ -465,9 +540,9 @@ var diffSurface = (before, after) => {
|
|
|
465
540
|
var notable = (diff) => diff.changed.filter((change) => change.shape === "parameters" || change.shape === "members");
|
|
466
541
|
|
|
467
542
|
// src/entries.ts
|
|
468
|
-
var loadEntry = async (
|
|
543
|
+
var loadEntry = async (path2) => {
|
|
469
544
|
try {
|
|
470
|
-
const module = await import(pathToFileURL(
|
|
545
|
+
const module = await import(pathToFileURL(path2).href);
|
|
471
546
|
const named = typeof module === "object" && module !== null && "change" in module ? module.change : undefined;
|
|
472
547
|
const exported = named ?? (typeof module === "object" && module !== null && "default" in module ? module.default : undefined);
|
|
473
548
|
const read = { exported };
|
|
@@ -480,23 +555,28 @@ var loadEntry = async (path) => {
|
|
|
480
555
|
}
|
|
481
556
|
};
|
|
482
557
|
var ENTRY = /\.[cm]?ts$/u;
|
|
483
|
-
var
|
|
484
|
-
|
|
485
|
-
|
|
558
|
+
var DECLARATION2 = /\.d\.[cm]?ts$/u;
|
|
559
|
+
var OUTPUT_DIRECTORIES = ["dist", "build", "lib", "types", "out"];
|
|
560
|
+
var builtSurface = async (packageRoot) => {
|
|
561
|
+
const manifest = await readJsonFile(join(packageRoot, "package.json"));
|
|
562
|
+
const files = new Map;
|
|
486
563
|
const walk = async (directory) => {
|
|
487
|
-
const found = await readdir(directory, {
|
|
564
|
+
const found = await readdir(join(packageRoot, directory), {
|
|
565
|
+
withFileTypes: true
|
|
566
|
+
}).catch(() => []);
|
|
488
567
|
await Promise.all(found.map(async (entry) => {
|
|
489
|
-
const
|
|
568
|
+
const relative = `${directory}/${entry.name}`;
|
|
490
569
|
if (entry.isDirectory())
|
|
491
|
-
return walk(
|
|
492
|
-
if (!entry.name
|
|
570
|
+
return walk(relative);
|
|
571
|
+
if (!DECLARATION2.test(entry.name))
|
|
493
572
|
return;
|
|
494
|
-
|
|
573
|
+
files.set(relative, await readFile(join(packageRoot, relative), "utf8").catch(() => ""));
|
|
495
574
|
return;
|
|
496
575
|
}));
|
|
497
576
|
};
|
|
498
|
-
await walk(
|
|
499
|
-
|
|
577
|
+
await Promise.all(OUTPUT_DIRECTORIES.map((directory) => walk(directory)));
|
|
578
|
+
const entries = typeEntriesOf(manifest, files);
|
|
579
|
+
return entries.length === 0 ? undefined : surfaceOfFiles(files, entries);
|
|
500
580
|
};
|
|
501
581
|
var changelogPaths = (packageRoot) => ({
|
|
502
582
|
history: join(packageRoot, "changelog", "history.md"),
|
|
@@ -522,8 +602,8 @@ var loadUnreleased = async (packageRoot) => {
|
|
|
522
602
|
}
|
|
523
603
|
return { entries, problems };
|
|
524
604
|
};
|
|
525
|
-
var readJsonFile = async (
|
|
526
|
-
const source = await readFile(
|
|
605
|
+
var readJsonFile = async (path2) => {
|
|
606
|
+
const source = await readFile(path2, "utf8").catch(() => {
|
|
527
607
|
return;
|
|
528
608
|
});
|
|
529
609
|
if (source === undefined)
|
|
@@ -546,9 +626,9 @@ var indentOf = (source) => {
|
|
|
546
626
|
const found = /\n([\t ]+)\S/u.exec(source)?.[1];
|
|
547
627
|
return found === undefined || found === "" ? "\t" : found;
|
|
548
628
|
};
|
|
549
|
-
var writeJsonLike = async (
|
|
550
|
-
const source = await readFile2(
|
|
551
|
-
await writeFile(
|
|
629
|
+
var writeJsonLike = async (path2, document) => {
|
|
630
|
+
const source = await readFile2(path2, "utf8").catch(() => "");
|
|
631
|
+
await writeFile(path2, `${JSON.stringify(document, null, indentOf(source))}
|
|
552
632
|
`);
|
|
553
633
|
};
|
|
554
634
|
|
|
@@ -586,8 +666,14 @@ var migrationHolds = (input) => {
|
|
|
586
666
|
};
|
|
587
667
|
var describeReconciliation = (found) => {
|
|
588
668
|
const lines = [];
|
|
669
|
+
const moved = {
|
|
670
|
+
members: "changed the members of its type",
|
|
671
|
+
parameters: "changed what it is called with",
|
|
672
|
+
removed: "is no longer exported",
|
|
673
|
+
types: "changed its declaration"
|
|
674
|
+
};
|
|
589
675
|
for (const entry of found.unannounced)
|
|
590
|
-
lines.push(
|
|
676
|
+
lines.push(`\`${entry.name}\` ${moved[entry.kind]} and no entry says so`);
|
|
591
677
|
for (const name of found.unknownSymbols)
|
|
592
678
|
lines.push(`an entry names \`${name}\`, which this package does not export`);
|
|
593
679
|
lines.push(...found.wrongMigrations);
|
|
@@ -598,10 +684,7 @@ var reconcile = (input) => {
|
|
|
598
684
|
const mentioned = new Set(input.changes.flatMap((change) => [...change.symbols ?? []]));
|
|
599
685
|
const unannounced = [
|
|
600
686
|
...input.diff.removed.filter((name) => !disruptive.has(name)).map((name) => ({ kind: "removed", name })),
|
|
601
|
-
...
|
|
602
|
-
kind: change.shape === "parameters" ? "parameters" : "members",
|
|
603
|
-
name: change.name
|
|
604
|
-
}))
|
|
687
|
+
...input.diff.changed.filter((change) => !mentioned.has(change.name) && change.shape !== "unknown").map((change) => ({ kind: change.shape, name: change.name }))
|
|
605
688
|
];
|
|
606
689
|
const unknownSymbols = [
|
|
607
690
|
...new Set(input.changes.flatMap((change) => [...change.symbols ?? []]).filter((name) => !input.known.has(name)))
|
|
@@ -619,6 +702,16 @@ var reconcile = (input) => {
|
|
|
619
702
|
import { gunzipSync } from "zlib";
|
|
620
703
|
var ABBREVIATED = "application/vnd.npm.install-v1+json";
|
|
621
704
|
var DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
705
|
+
var KIBIBYTE2 = 1024;
|
|
706
|
+
var MEBIBYTE2 = KIBIBYTE2 * KIBIBYTE2;
|
|
707
|
+
var MAX_ARCHIVE_MEBIBYTES = 96;
|
|
708
|
+
var MAX_ARCHIVE_BYTES = MAX_ARCHIVE_MEBIBYTES * MEBIBYTE2;
|
|
709
|
+
var MAX_DOWNLOAD_MEBIBYTES = 32;
|
|
710
|
+
var MAX_DOWNLOAD_BYTES = MAX_DOWNLOAD_MEBIBYTES * MEBIBYTE2;
|
|
711
|
+
var TIMEOUT_MS = 20000;
|
|
712
|
+
var PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/u;
|
|
713
|
+
var MAX_NAME_LENGTH = 214;
|
|
714
|
+
var isPackageName = (name) => name.length <= MAX_NAME_LENGTH && PACKAGE_NAME.test(name);
|
|
622
715
|
var isRecord2 = (value) => typeof value === "object" && value !== null;
|
|
623
716
|
var readPackument = (body) => {
|
|
624
717
|
if (!isRecord2(body) || !isRecord2(body.versions))
|
|
@@ -646,20 +739,30 @@ var packageArchive = async (name, version, options = {}) => {
|
|
|
646
739
|
if (url === undefined)
|
|
647
740
|
return;
|
|
648
741
|
try {
|
|
649
|
-
const response = await call(url
|
|
742
|
+
const response = await call(url, {
|
|
743
|
+
signal: AbortSignal.timeout(TIMEOUT_MS)
|
|
744
|
+
});
|
|
650
745
|
if (!response.ok)
|
|
651
746
|
return;
|
|
652
|
-
|
|
747
|
+
const compressed = new Uint8Array(await response.arrayBuffer());
|
|
748
|
+
if (compressed.byteLength > MAX_DOWNLOAD_BYTES)
|
|
749
|
+
return;
|
|
750
|
+
return new Uint8Array(gunzipSync(compressed, { maxOutputLength: MAX_ARCHIVE_BYTES }));
|
|
653
751
|
} catch {
|
|
654
752
|
return;
|
|
655
753
|
}
|
|
656
754
|
};
|
|
657
755
|
var packageVersions = async (name, options = {}) => {
|
|
756
|
+
if (!isPackageName(name))
|
|
757
|
+
return;
|
|
658
758
|
const call = options.fetch ?? fetch;
|
|
659
759
|
const url = `${options.registry ?? DEFAULT_REGISTRY}/${name.replace("/", "%2f")}`;
|
|
660
760
|
try {
|
|
661
|
-
const abbreviated = await call(url, {
|
|
662
|
-
|
|
761
|
+
const abbreviated = await call(url, {
|
|
762
|
+
headers: { accept: ABBREVIATED },
|
|
763
|
+
signal: AbortSignal.timeout(TIMEOUT_MS)
|
|
764
|
+
});
|
|
765
|
+
const response = abbreviated.ok ? abbreviated : await call(url, { signal: AbortSignal.timeout(TIMEOUT_MS) });
|
|
663
766
|
if (!response.ok)
|
|
664
767
|
return;
|
|
665
768
|
return readPackument(await response.json());
|
|
@@ -671,7 +774,7 @@ var publishedChangelog = async (name, version, options = {}) => {
|
|
|
671
774
|
const archive = await packageArchive(name, version, options);
|
|
672
775
|
if (!archive)
|
|
673
776
|
return;
|
|
674
|
-
const file = readTar(archive, (
|
|
777
|
+
const file = readTar(archive, (path2) => path2 === CHANGELOG_FILE).get(CHANGELOG_FILE);
|
|
675
778
|
if (!file)
|
|
676
779
|
return;
|
|
677
780
|
try {
|
|
@@ -749,6 +852,7 @@ var renderRelease = (release) => {
|
|
|
749
852
|
].join(`
|
|
750
853
|
`);
|
|
751
854
|
};
|
|
855
|
+
var GENERATED_MARKER = "This file is generated by `absolute-changelog`";
|
|
752
856
|
var renderChangelogJson = (changelog) => `${JSON.stringify({
|
|
753
857
|
contract: CHANGELOG_CONTRACT,
|
|
754
858
|
name: changelog.name,
|
|
@@ -774,7 +878,7 @@ var renderMarkdown = (changelog, options = {}) => {
|
|
|
774
878
|
"",
|
|
775
879
|
`All notable changes to \`${changelog.name}\`.`,
|
|
776
880
|
"",
|
|
777
|
-
|
|
881
|
+
`${GENERATED_MARKER} from the entries in`,
|
|
778
882
|
"`changelog/`. Edit an entry, not this file \u2014 and add new ones under",
|
|
779
883
|
"`changelog/unreleased/`."
|
|
780
884
|
].join(`
|
|
@@ -984,7 +1088,7 @@ var check = async (root, flags) => {
|
|
|
984
1088
|
const actual = await readFile3(changelogPaths(root).markdown, "utf8").catch(() => {
|
|
985
1089
|
return;
|
|
986
1090
|
});
|
|
987
|
-
if (
|
|
1091
|
+
if (actual !== expected)
|
|
988
1092
|
failures.push(`${CHANGELOG_MARKDOWN} is not what the entries say it should be \u2014 it is generated; run \`absolute-changelog release\` or restore it`);
|
|
989
1093
|
const tsconfig = await readJsonFile(join2(root, "tsconfig.json"));
|
|
990
1094
|
const include = isPackage(tsconfig) ? tsconfig.include : undefined;
|
|
@@ -998,12 +1102,21 @@ var check = async (root, flags) => {
|
|
|
998
1102
|
failures.push(`package.json does not ship ${file}`);
|
|
999
1103
|
const offline = flags.offline === true;
|
|
1000
1104
|
const built = await builtSurface(root);
|
|
1105
|
+
const shipsTypes = declaresTypes(await readJsonFile(join2(root, "package.json")));
|
|
1106
|
+
if (built === undefined && shipsTypes)
|
|
1107
|
+
failures.push("there are no declaration files where package.json says its types are \u2014 build before the gate, or nothing compares them");
|
|
1108
|
+
if (!shipsTypes)
|
|
1109
|
+
console.warn(" (this package ships no types, so none were compared)");
|
|
1001
1110
|
const versions = offline ? undefined : await packageVersions(manifest.name ?? "");
|
|
1002
|
-
|
|
1003
|
-
|
|
1111
|
+
if (!offline && versions === undefined)
|
|
1112
|
+
failures.push(`the registry did not answer for ${manifest.name}, so nothing was compared \u2014 pass --offline to skip the comparison deliberately`);
|
|
1113
|
+
const baseline = (versions?.published ?? []).filter((version) => compareVersions(version, manifest.version) <= 0).sort(compareVersions).at(LAST2);
|
|
1114
|
+
if (versions !== undefined && baseline === undefined && !offline)
|
|
1115
|
+
console.warn(` (nothing published at or below ${manifest.version}; this looks like a first release)`);
|
|
1116
|
+
if (built !== undefined && baseline !== undefined) {
|
|
1004
1117
|
const published = await publishedSurface(manifest.name ?? "", baseline);
|
|
1005
1118
|
if (published === undefined)
|
|
1006
|
-
|
|
1119
|
+
failures.push(`could not read the published types of ${manifest.name}@${baseline}, so nothing was compared`);
|
|
1007
1120
|
const speaking = [
|
|
1008
1121
|
...entries.map((entry) => entry.change),
|
|
1009
1122
|
...current.releases.filter((entry) => compareVersions(entry.version, baseline) > 0).flatMap((entry) => [...entry.changes])
|
|
@@ -1016,14 +1129,12 @@ var check = async (root, flags) => {
|
|
|
1016
1129
|
subpaths: subpathsOf(manifest)
|
|
1017
1130
|
})));
|
|
1018
1131
|
}
|
|
1019
|
-
if (!offline && built === undefined)
|
|
1020
|
-
console.warn(" (no dist to read, so the types were not checked \u2014 run the build before the gate)");
|
|
1021
1132
|
if (failures.length > 0)
|
|
1022
1133
|
throw new CliError(["This package\u2019s changelog does not hold:", ...failures].join(`
|
|
1023
1134
|
`));
|
|
1024
1135
|
console.log(`${manifest.name}@${manifest.version}: changelog holds (${entries.length} pending, ${current.releases.length} released)`);
|
|
1025
1136
|
};
|
|
1026
|
-
var
|
|
1137
|
+
var LAST2 = -1;
|
|
1027
1138
|
var subpathsOf = (manifest) => {
|
|
1028
1139
|
const { exports } = manifest;
|
|
1029
1140
|
if (typeof exports !== "object" || exports === null)
|
|
@@ -1033,13 +1144,13 @@ var subpathsOf = (manifest) => {
|
|
|
1033
1144
|
var CHECKING_CONFIGS = ["tsconfig.json", "tsconfig.eslint.json"];
|
|
1034
1145
|
var coversEntries = (include) => Array.isArray(include) && include.some((entry) => typeof entry === "string" && entry.startsWith("changelog"));
|
|
1035
1146
|
var includeEntriesIn = async (root, file) => {
|
|
1036
|
-
const
|
|
1037
|
-
const document = await readJsonFile(
|
|
1147
|
+
const path2 = join2(root, file);
|
|
1148
|
+
const document = await readJsonFile(path2);
|
|
1038
1149
|
if (!isPackage(document) || !Array.isArray(document.include))
|
|
1039
1150
|
return false;
|
|
1040
1151
|
if (coversEntries(document.include))
|
|
1041
1152
|
return false;
|
|
1042
|
-
await writeJsonLike(
|
|
1153
|
+
await writeJsonLike(path2, {
|
|
1043
1154
|
...document,
|
|
1044
1155
|
include: [...document.include, "changelog/**/*"]
|
|
1045
1156
|
});
|
|
@@ -1050,8 +1161,8 @@ var includeEntries = async (root) => {
|
|
|
1050
1161
|
return wired.some(Boolean) ? undefined : "no tsconfig include list to wire \u2014 make sure changelog/ is compiled by something";
|
|
1051
1162
|
};
|
|
1052
1163
|
var ignoreGenerated = async (root) => {
|
|
1053
|
-
const
|
|
1054
|
-
const existing = await readFile3(
|
|
1164
|
+
const path2 = join2(root, ".prettierignore");
|
|
1165
|
+
const existing = await readFile3(path2, "utf8").catch(() => "");
|
|
1055
1166
|
const wanted = [CHANGELOG_FILE, CHANGELOG_MARKDOWN].filter((name) => !existing.split(`
|
|
1056
1167
|
`).includes(name));
|
|
1057
1168
|
if (wanted.length === 0)
|
|
@@ -1059,7 +1170,7 @@ var ignoreGenerated = async (root) => {
|
|
|
1059
1170
|
const head = existing.trim() === "" ? `# Generated by absolute-changelog. Edit the entries, not these.
|
|
1060
1171
|
` : `${existing.trimEnd()}
|
|
1061
1172
|
`;
|
|
1062
|
-
await writeFile2(
|
|
1173
|
+
await writeFile2(path2, `${head}${wanted.join(`
|
|
1063
1174
|
`)}
|
|
1064
1175
|
`);
|
|
1065
1176
|
};
|
|
@@ -1078,8 +1189,8 @@ var adopt = async (root) => {
|
|
|
1078
1189
|
const paths = changelogPaths(root);
|
|
1079
1190
|
await mkdir(paths.unreleased, { recursive: true });
|
|
1080
1191
|
await writeFile2(join2(paths.unreleased, ".gitkeep"), "# Entries wait here. One file per change; `absolute-changelog release` consumes them.\n");
|
|
1081
|
-
|
|
1082
|
-
|
|
1192
|
+
const previous = existsSync(paths.markdown) ? await readFile3(paths.markdown, "utf8") : undefined;
|
|
1193
|
+
if (previous !== undefined && !previous.includes(GENERATED_MARKER) && !existsSync(paths.history)) {
|
|
1083
1194
|
await mkdir(join2(root, "changelog"), { recursive: true });
|
|
1084
1195
|
await writeFile2(paths.history, previous.replace(/^#\s+Changelog\s*/u, "").trimStart());
|
|
1085
1196
|
await rm(paths.markdown, { force: true });
|
|
@@ -1120,5 +1231,5 @@ await main().catch((error) => {
|
|
|
1120
1231
|
process.exit(1);
|
|
1121
1232
|
});
|
|
1122
1233
|
|
|
1123
|
-
//# debugId=
|
|
1234
|
+
//# debugId=0E6F1175A8DDD6A464756E2164756E21
|
|
1124
1235
|
//# sourceMappingURL=cli.js.map
|