@absolutejs/changelog 0.1.2 → 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 +46 -0
- package/README.md +41 -4
- package/changelog.json +194 -40
- package/dist/apply.d.ts +3 -5
- package/dist/cli.js +337 -140
- package/dist/cli.js.map +11 -11
- package/dist/entries.d.ts +24 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +513 -230
- package/dist/index.js.map +11 -11
- package/dist/read.d.ts +1 -1
- package/dist/reconcile.d.ts +14 -3
- package/dist/registry.d.ts +1 -0
- package/dist/surface.d.ts +21 -22
- package/dist/types.d.ts +41 -9
- package/dist/write.d.ts +9 -0
- package/package.json +74 -70
package/dist/reconcile.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SurfaceDiff } from "./surface";
|
|
2
2
|
import { type Change } from "./types";
|
|
3
3
|
export type Unannounced = {
|
|
4
|
-
/**
|
|
5
|
-
kind: "removed" | "parameters" | "members";
|
|
4
|
+
/** Gone entirely, or what about its declaration moved. */
|
|
5
|
+
kind: "removed" | "parameters" | "members" | "types";
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
8
|
export type Reconciliation = {
|
|
9
|
+
/** Entries whose migration does not describe what the package did. */
|
|
10
|
+
wrongMigrations: string[];
|
|
9
11
|
/** Exports that moved with nothing written about them. */
|
|
10
12
|
unannounced: Unannounced[];
|
|
11
13
|
/** Names entries claim that this package has never exported. A typo, or
|
|
@@ -15,9 +17,18 @@ export type Reconciliation = {
|
|
|
15
17
|
/** What to print when it fails, in the order somebody fixes them. */
|
|
16
18
|
export declare const describeReconciliation: (found: Reconciliation) => string[];
|
|
17
19
|
export declare const reconcile: (input: {
|
|
20
|
+
/** Every entry that speaks for the versions being compared: the ones
|
|
21
|
+
* waiting for a release, and the ones a release already consumed but the
|
|
22
|
+
* registry has not seen yet. */
|
|
18
23
|
changes: readonly Change[];
|
|
19
24
|
diff: SurfaceDiff;
|
|
20
25
|
/** Every name the package exported before or after, for catching entries
|
|
21
26
|
* that name something that was never there. */
|
|
22
27
|
known: ReadonlySet<string>;
|
|
28
|
+
/** What the package exports now, for checking that a migration describes
|
|
29
|
+
* what it says it describes. */
|
|
30
|
+
after?: ReadonlySet<string>;
|
|
31
|
+
/** The package's entry points, so a migration cannot point at one that is
|
|
32
|
+
* not there. Empty means "not known", and the check is skipped. */
|
|
33
|
+
subpaths?: ReadonlySet<string>;
|
|
23
34
|
}) => Reconciliation;
|
package/dist/registry.d.ts
CHANGED
package/dist/surface.d.ts
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The exported names of one declaration file, each with the declaration it
|
|
3
|
-
* stands for.
|
|
4
|
-
*
|
|
5
|
-
* Overloads and merged declarations share a name; they are joined, so adding
|
|
6
|
-
* an overload reads as a change to that name rather than as a replacement.
|
|
7
|
-
*/
|
|
8
|
-
export declare const exportedDeclarations: (source: string) => Map<string, string>;
|
|
9
1
|
export type PackageSurface = Map<string, string>;
|
|
2
|
+
/** Whether a manifest claims to ship types at all. A package that ships none
|
|
3
|
+
* has no promise of this kind to check; one that claims some and has none is
|
|
4
|
+
* a package about to publish types it did not build. */
|
|
5
|
+
export declare const declaresTypes: (manifest: unknown) => boolean;
|
|
10
6
|
/** The surface of a package tarball, already gunzipped. */
|
|
11
|
-
export declare const surfaceOfArchive: (archive: Uint8Array) => PackageSurface;
|
|
7
|
+
export declare const surfaceOfArchive: (archive: Uint8Array) => PackageSurface | undefined;
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* A name usually appears twice: where it is declared, and in the index that
|
|
16
|
-
* passes it along. The declaration wins wherever both are found, whichever
|
|
17
|
-
* file the archive happened to put first -- otherwise the same package reads
|
|
18
|
-
* as `export { syncSocket }` in one version and as its full signature in the
|
|
19
|
-
* next, and the two compare as a change nobody made.
|
|
9
|
+
* The public surface of a package: what its entry points export, and what
|
|
10
|
+
* each of those names is declared as.
|
|
20
11
|
*/
|
|
21
|
-
export declare const surfaceOfFiles: (files:
|
|
12
|
+
export declare const surfaceOfFiles: (files: ReadonlyMap<string, string>, entries: readonly string[]) => PackageSurface;
|
|
13
|
+
/** The declaration files a manifest points at, as paths inside the package. */
|
|
14
|
+
export declare const typeEntriesOf: (manifest: unknown, files: ReadonlyMap<string, string>) => string[];
|
|
22
15
|
declare const SHAPE: {
|
|
23
16
|
readonly members: "members";
|
|
24
17
|
readonly parameters: "parameters";
|
|
@@ -44,12 +37,18 @@ export type SurfaceDiff = {
|
|
|
44
37
|
/**
|
|
45
38
|
* What moved between two surfaces.
|
|
46
39
|
*
|
|
47
|
-
* Removed is the one that breaks a build outright. Changed is the one that
|
|
48
|
-
* a widened parameter is not a break and a narrowed one is, and telling
|
|
49
|
-
* apart is a job for whoever reads the two declarations -- so both are
|
|
50
|
-
* rather than judged here.
|
|
40
|
+
* Removed is the one that breaks a build outright. Changed is the one that
|
|
41
|
+
* may: a widened parameter is not a break and a narrowed one is, and telling
|
|
42
|
+
* them apart is a job for whoever reads the two declarations -- so both are
|
|
43
|
+
* carried rather than judged here.
|
|
51
44
|
*/
|
|
52
45
|
export declare const diffSurface: (before: PackageSurface, after: PackageSurface) => SurfaceDiff;
|
|
53
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* The changes a consumer would notice, for an advisor deciding what to put in
|
|
48
|
+
* front of somebody.
|
|
49
|
+
*
|
|
50
|
+
* Not for the gate: `types` changes are still changes, and the package that
|
|
51
|
+
* made one is the party that can say in one line whether it matters.
|
|
52
|
+
*/
|
|
54
53
|
export declare const notable: (diff: SurfaceDiff) => SurfaceChange[];
|
|
55
54
|
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -19,12 +19,12 @@ export type DisruptiveKind = (typeof DISRUPTIVE_KINDS)[number];
|
|
|
19
19
|
* `manual` is the honest escape hatch. A changed meaning is not a rewrite
|
|
20
20
|
* anybody should automate, and pretending otherwise is worse than saying so.
|
|
21
21
|
*/
|
|
22
|
-
export type Migration =
|
|
22
|
+
export type Migration<TSymbol extends string = string> =
|
|
23
23
|
/** An export kept its meaning and changed its name. */
|
|
24
24
|
{
|
|
25
25
|
readonly instruction: string;
|
|
26
26
|
readonly rename: {
|
|
27
|
-
readonly from:
|
|
27
|
+
readonly from: TSymbol;
|
|
28
28
|
readonly to: string;
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -32,7 +32,7 @@ export type Migration =
|
|
|
32
32
|
| {
|
|
33
33
|
readonly instruction: string;
|
|
34
34
|
readonly moved: {
|
|
35
|
-
readonly symbol:
|
|
35
|
+
readonly symbol: TSymbol;
|
|
36
36
|
readonly from: string;
|
|
37
37
|
readonly to: string;
|
|
38
38
|
};
|
|
@@ -50,6 +50,38 @@ export type Migration =
|
|
|
50
50
|
readonly instruction: string;
|
|
51
51
|
readonly manual: true;
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* The names a package exports, for an entry that wants them checked.
|
|
55
|
+
*
|
|
56
|
+
* An entry can be written against the package's own public API:
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* import type * as Api from "../../src/index";
|
|
60
|
+
* import type { Change } from "@absolutejs/changelog";
|
|
61
|
+
*
|
|
62
|
+
* export const change: Change<typeof Api> = {
|
|
63
|
+
* kind: "fixed",
|
|
64
|
+
* summary: "stops throwing on an empty list",
|
|
65
|
+
* symbols: ["listen"] // an export, or the compiler says so
|
|
66
|
+
* };
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* Suggested rather than required, for two reasons that both matter. A
|
|
70
|
+
* disruptive change is usually about something that has just stopped
|
|
71
|
+
* existing -- the release that removes `start` is the release that writes the
|
|
72
|
+
* entry about it -- and `typeof Api` cannot see type-only exports at all, so
|
|
73
|
+
* insisting would reject an entry about `Change` or `Release` for being
|
|
74
|
+
* something this package definitely exports.
|
|
75
|
+
*
|
|
76
|
+
* What that leaves is an editor that completes the name and a gate that is
|
|
77
|
+
* certain: the release check reads the published `.d.ts`, which does carry
|
|
78
|
+
* the type exports, and refuses an entry naming something the package has
|
|
79
|
+
* never exported.
|
|
80
|
+
*/
|
|
81
|
+
type Exported<TApi> = TApi extends object ? Extract<keyof TApi, string> : string;
|
|
82
|
+
/** Autocompleted, not restricted: an entry may name an export that has just
|
|
83
|
+
* stopped being one. */
|
|
84
|
+
type Suggested<TApi> = Exported<TApi> | (string & {});
|
|
53
85
|
type ChangeBase = {
|
|
54
86
|
/** One line, imperative, in the reader's terms rather than the
|
|
55
87
|
* implementation's. */
|
|
@@ -66,19 +98,19 @@ type ChangeBase = {
|
|
|
66
98
|
* the package's published types, and what lets a project be told whether the
|
|
67
99
|
* change reaches any of its files. An entry without it can only ever be read.
|
|
68
100
|
*/
|
|
69
|
-
export type DisruptiveChange = ChangeBase & {
|
|
101
|
+
export type DisruptiveChange<TApi = unknown> = ChangeBase & {
|
|
70
102
|
readonly kind: DisruptiveKind;
|
|
71
|
-
readonly symbols: NonEmpty<
|
|
72
|
-
readonly migration: Migration
|
|
103
|
+
readonly symbols: NonEmpty<Suggested<TApi>>;
|
|
104
|
+
readonly migration: Migration<Suggested<TApi>>;
|
|
73
105
|
};
|
|
74
|
-
export type OrdinaryChange = ChangeBase & {
|
|
106
|
+
export type OrdinaryChange<TApi = unknown> = ChangeBase & {
|
|
75
107
|
readonly kind: Exclude<ChangeKind, DisruptiveKind>;
|
|
76
108
|
/** Optional here, and still worth filling in: it is what connects a fix
|
|
77
109
|
* to the export somebody is looking at. */
|
|
78
|
-
readonly symbols?: readonly
|
|
110
|
+
readonly symbols?: readonly Suggested<TApi>[];
|
|
79
111
|
readonly migration?: never;
|
|
80
112
|
};
|
|
81
|
-
export type Change = DisruptiveChange | OrdinaryChange
|
|
113
|
+
export type Change<TApi = unknown> = DisruptiveChange<TApi> | OrdinaryChange<TApi>;
|
|
82
114
|
export type Release = {
|
|
83
115
|
readonly version: string;
|
|
84
116
|
/** ISO date, the day it was published. */
|
package/dist/write.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { type Changelog } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* The line that says this file was generated.
|
|
4
|
+
*
|
|
5
|
+
* Load-bearing: adopting a package reads whatever `CHANGELOG.md` said before
|
|
6
|
+
* and keeps it as history, and on a second adoption the file it generated the
|
|
7
|
+
* first time is what it finds. Without a way to recognise its own output it
|
|
8
|
+
* files that as history and prints the header underneath itself.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GENERATED_MARKER = "This file is generated by `absolute-changelog`";
|
|
2
11
|
export type MarkdownOptions = {
|
|
3
12
|
/** Whatever the package's changelog said before it was generated, kept
|
|
4
13
|
* under the releases that came after it. History is not noise. */
|
package/package.json
CHANGED
|
@@ -1,72 +1,76 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
2
|
+
"name": "@absolutejs/changelog",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "The changelog contract for the AbsoluteJS packages. Changes are written as typed entries the compiler checks, the release gate reconciles them against the package's own published types so a change nobody wrote down cannot ship, and migrations are data rather than prose so an upgrade can be applied instead of read.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/absolutejs/changelog.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/absolutejs/changelog",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/absolutejs/changelog/issues"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "Alex Kahn",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"absolute-changelog": "dist/cli.js"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"CHANGELOG.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"README.md",
|
|
36
|
+
"changelog.json",
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "rm -rf dist && bun build src/index.ts src/cli.ts --outdir dist --root src --sourcemap --target=bun --external typescript && tsc --project tsconfig.build.json",
|
|
41
|
+
"test": "bun test tests/",
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"format": "prettier --write \"./**/*.{ts,json,md}\"",
|
|
44
|
+
"lint": "eslint . --max-warnings 0",
|
|
45
|
+
"changelog": "bun src/cli.ts",
|
|
46
|
+
"check:package": "bun run typecheck && bun run lint && bun run test && bun run build && bun src/cli.ts check",
|
|
47
|
+
"release": "bun run format && bun run check:package && bun publish",
|
|
48
|
+
"prepublishOnly": "bun src/cli.ts check"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"absolutejs",
|
|
52
|
+
"changelog",
|
|
53
|
+
"codemod",
|
|
54
|
+
"migration",
|
|
55
|
+
"release",
|
|
56
|
+
"semver",
|
|
57
|
+
"upgrade"
|
|
58
|
+
],
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^10.0.1",
|
|
61
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
62
|
+
"@types/bun": "^1.3.14",
|
|
63
|
+
"@typescript-eslint/parser": "^8.68.0",
|
|
64
|
+
"eslint": "^10.9.1",
|
|
65
|
+
"eslint-plugin-absolute": "^0.11.34",
|
|
66
|
+
"eslint-plugin-promise": "^7.3.0",
|
|
67
|
+
"eslint-plugin-security": "^4.0.1",
|
|
68
|
+
"globals": "^17.11.0",
|
|
69
|
+
"prettier": "^3.5.3",
|
|
70
|
+
"typescript": "^5.8.3",
|
|
71
|
+
"typescript-eslint": "^8.56.0"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"typescript": "^5.8.3"
|
|
75
|
+
}
|
|
72
76
|
}
|