@ykdz/template 0.0.35 → 0.0.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.
- package/dist/application.d.ts +2 -1
- package/dist/application.js +64 -75
- package/dist/main.js +6 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +50 -36
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +968 -364
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +24 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +154 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +29 -33
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.d.ts +4 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.js +9 -5
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +0 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +79 -58
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +31 -23
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.d.ts +22 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +53 -25
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.d.ts +26 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +19 -7
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.d.ts +22 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +31 -20
- package/node_modules/@ykdz/template-builtin-presets/package.json +12 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.pnpmfile.mjs +19 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.packing-hook.json +8 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/CHANGELOG.md.template +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/RELEASING.md +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +1271 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/changelog.ts +283 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts +99 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-readiness.ts +66 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/cli-command-identity.ts +4 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +450 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/publish.ts +483 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +1125 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.ts +819 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +119 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/root-tsconfig.json +13 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/tsconfig.json +4 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/turbo.json +6 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/README.md +48 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/CHANGELOG.md.template +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-APACHE-2.0.txt +202 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-MIT.txt +21 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/README.md.template +5 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/bridge.ts +3336 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/setup.sh +221 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts +133 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +4 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +5 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +14 -13
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/cli-command-identity.test.ts +76 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.build.json +2 -0
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +15 -53
- package/node_modules/@ykdz/template-core/dist/module-graph.js +134 -101
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +13 -1
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +92 -0
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +14 -10
- package/node_modules/@ykdz/template-core/dist/preset-definition.d.ts +71 -13
- package/node_modules/@ykdz/template-core/dist/preset-definition.js +16 -1
- package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +56 -0
- package/node_modules/@ykdz/template-core/dist/project-blueprint.js +271 -0
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.js +2 -2
- package/node_modules/@ykdz/template-core/dist/project-projection.d.ts +2 -1
- package/node_modules/@ykdz/template-core/dist/project-projection.js +107 -20
- package/node_modules/@ykdz/template-core/dist/renderer.d.ts +0 -2
- package/node_modules/@ykdz/template-core/dist/renderer.js +17 -38
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +6 -0
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.d.ts +2 -0
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +9 -3
- package/package.json +5 -5
- package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.d.ts +0 -33
- package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.js +0 -182
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
export type ChangelogBlockerCode =
|
|
2
|
+
| "changelog-unreleased-missing"
|
|
3
|
+
| "changelog-unreleased-duplicate"
|
|
4
|
+
| "changelog-target-release-missing"
|
|
5
|
+
| "changelog-target-release-duplicate"
|
|
6
|
+
| "changelog-target-release-date-invalid"
|
|
7
|
+
| "changelog-target-release-body-empty";
|
|
8
|
+
|
|
9
|
+
export type ChangelogBlocker = {
|
|
10
|
+
readonly code: ChangelogBlockerCode;
|
|
11
|
+
readonly observed: string;
|
|
12
|
+
readonly expected: string;
|
|
13
|
+
readonly nextAction: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type PackageReleaseChangelogInspection =
|
|
17
|
+
| {
|
|
18
|
+
readonly blockers: readonly [];
|
|
19
|
+
readonly releaseDate: string;
|
|
20
|
+
readonly releaseNotes: string;
|
|
21
|
+
}
|
|
22
|
+
| {
|
|
23
|
+
readonly blockers: readonly [ChangelogBlocker, ...ChangelogBlocker[]];
|
|
24
|
+
readonly releaseDate?: never;
|
|
25
|
+
readonly releaseNotes?: never;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type SourceLine = {
|
|
29
|
+
readonly text: string;
|
|
30
|
+
readonly start: number;
|
|
31
|
+
readonly end: number;
|
|
32
|
+
readonly outsideFence: boolean;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type Fence = {
|
|
36
|
+
readonly marker: "`" | "~";
|
|
37
|
+
readonly length: number;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function openingFence(text: string): Fence | undefined {
|
|
41
|
+
const match = /^ {0,3}(`{3,}|~{3,})(.*)$/u.exec(text);
|
|
42
|
+
if (match === null) return undefined;
|
|
43
|
+
const run = match[1]!;
|
|
44
|
+
const marker = run[0] as "`" | "~";
|
|
45
|
+
if (marker === "`" && match[2]!.includes("`")) return undefined;
|
|
46
|
+
return { marker, length: run.length };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function closesFence(text: string, fence: Fence): boolean {
|
|
50
|
+
const match = /^ {0,3}(`+|~+)[ \t]*$/u.exec(text);
|
|
51
|
+
return (
|
|
52
|
+
match !== null &&
|
|
53
|
+
match[1]![0] === fence.marker &&
|
|
54
|
+
match[1]!.length >= fence.length
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function sourceLines(source: string): readonly SourceLine[] {
|
|
59
|
+
const lines: SourceLine[] = [];
|
|
60
|
+
let start = 0;
|
|
61
|
+
let fence: Fence | undefined;
|
|
62
|
+
while (start < source.length) {
|
|
63
|
+
const newline = source.indexOf("\n", start);
|
|
64
|
+
const end = newline === -1 ? source.length : newline + 1;
|
|
65
|
+
let contentEnd = newline === -1 ? source.length : newline;
|
|
66
|
+
if (contentEnd > start && source[contentEnd - 1] === "\r") {
|
|
67
|
+
contentEnd -= 1;
|
|
68
|
+
}
|
|
69
|
+
const text = source.slice(start, contentEnd);
|
|
70
|
+
const outsideFence = fence === undefined;
|
|
71
|
+
if (fence === undefined) {
|
|
72
|
+
fence = openingFence(text);
|
|
73
|
+
} else if (closesFence(text, fence)) {
|
|
74
|
+
fence = undefined;
|
|
75
|
+
}
|
|
76
|
+
lines.push({
|
|
77
|
+
text,
|
|
78
|
+
start,
|
|
79
|
+
end,
|
|
80
|
+
outsideFence: outsideFence && fence === undefined,
|
|
81
|
+
});
|
|
82
|
+
start = end;
|
|
83
|
+
}
|
|
84
|
+
return lines;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function blocker(
|
|
88
|
+
code: ChangelogBlockerCode,
|
|
89
|
+
observed: string,
|
|
90
|
+
expected: string,
|
|
91
|
+
nextAction: string,
|
|
92
|
+
): ChangelogBlocker {
|
|
93
|
+
return { code, observed, expected, nextAction };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function releaseHeading(
|
|
97
|
+
text: string,
|
|
98
|
+
): { readonly label: string; readonly suffix: string } | undefined {
|
|
99
|
+
const match = /^## \[([^\]]+)\](.*)$/u.exec(text);
|
|
100
|
+
return match === null ? undefined : { label: match[1]!, suffix: match[2]! };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isGregorianCalendarDate(value: string): boolean {
|
|
104
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/u.exec(value);
|
|
105
|
+
if (match === null) return false;
|
|
106
|
+
const year = Number(match[1]);
|
|
107
|
+
const month = Number(match[2]);
|
|
108
|
+
const day = Number(match[3]);
|
|
109
|
+
if (year === 0 || month < 1 || month > 12) return false;
|
|
110
|
+
const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
111
|
+
const daysInMonth = [
|
|
112
|
+
31,
|
|
113
|
+
leapYear ? 29 : 28,
|
|
114
|
+
31,
|
|
115
|
+
30,
|
|
116
|
+
31,
|
|
117
|
+
30,
|
|
118
|
+
31,
|
|
119
|
+
31,
|
|
120
|
+
30,
|
|
121
|
+
31,
|
|
122
|
+
30,
|
|
123
|
+
31,
|
|
124
|
+
];
|
|
125
|
+
return day >= 1 && day <= daysInMonth[month - 1]!;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function trimBoundaryBlankLines(
|
|
129
|
+
source: string,
|
|
130
|
+
lines: readonly SourceLine[],
|
|
131
|
+
): string {
|
|
132
|
+
const contentLines = lines.filter((line) => line.text.trim().length > 0);
|
|
133
|
+
const first = contentLines.at(0);
|
|
134
|
+
const last = contentLines.at(-1);
|
|
135
|
+
return first === undefined || last === undefined
|
|
136
|
+
? ""
|
|
137
|
+
: source.slice(first.start, last.end);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function isReferenceDefinition(line: SourceLine): boolean {
|
|
141
|
+
return line.outsideFence && /^\[[^\]]+\]:\s+\S/u.test(line.text);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function documentFooterStart(lines: readonly SourceLine[]): number | undefined {
|
|
145
|
+
let index = lines.length - 1;
|
|
146
|
+
while (index >= 0 && lines[index]!.text.trim().length === 0) index -= 1;
|
|
147
|
+
if (index < 0 || !isReferenceDefinition(lines[index]!)) return undefined;
|
|
148
|
+
|
|
149
|
+
let footerStart = lines[index]!.start;
|
|
150
|
+
index -= 1;
|
|
151
|
+
while (index >= 0) {
|
|
152
|
+
const line = lines[index]!;
|
|
153
|
+
if (isReferenceDefinition(line)) {
|
|
154
|
+
footerStart = line.start;
|
|
155
|
+
index -= 1;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (line.text.trim().length === 0) {
|
|
159
|
+
index -= 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
return footerStart;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function inspectPackageReleaseChangelog(
|
|
168
|
+
source: string,
|
|
169
|
+
targetVersion: string,
|
|
170
|
+
): PackageReleaseChangelogInspection {
|
|
171
|
+
const lines = sourceLines(source);
|
|
172
|
+
const blockers: ChangelogBlocker[] = [];
|
|
173
|
+
const unreleased = lines.filter(
|
|
174
|
+
(line) => line.outsideFence && line.text === "## [Unreleased]",
|
|
175
|
+
);
|
|
176
|
+
if (unreleased.length === 0) {
|
|
177
|
+
blockers.push(
|
|
178
|
+
blocker(
|
|
179
|
+
"changelog-unreleased-missing",
|
|
180
|
+
"No Unreleased section was found",
|
|
181
|
+
"Exactly one ## [Unreleased] section",
|
|
182
|
+
"Add the package changelog Unreleased section.",
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
} else if (unreleased.length > 1) {
|
|
186
|
+
blockers.push(
|
|
187
|
+
blocker(
|
|
188
|
+
"changelog-unreleased-duplicate",
|
|
189
|
+
`${unreleased.length} Unreleased sections were found`,
|
|
190
|
+
"Exactly one ## [Unreleased] section",
|
|
191
|
+
"Keep one package changelog Unreleased section.",
|
|
192
|
+
),
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const targets = lines.filter(
|
|
197
|
+
(line) =>
|
|
198
|
+
line.outsideFence && releaseHeading(line.text)?.label === targetVersion,
|
|
199
|
+
);
|
|
200
|
+
if (targets.length === 0) {
|
|
201
|
+
blockers.push(
|
|
202
|
+
blocker(
|
|
203
|
+
"changelog-target-release-missing",
|
|
204
|
+
`No ${targetVersion} release section was found`,
|
|
205
|
+
`Exactly one ## [${targetVersion}] - YYYY-MM-DD section`,
|
|
206
|
+
`Add the ${targetVersion} release section to the package changelog.`,
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
|
+
} else if (targets.length > 1) {
|
|
210
|
+
blockers.push(
|
|
211
|
+
blocker(
|
|
212
|
+
"changelog-target-release-duplicate",
|
|
213
|
+
`${targets.length} ${targetVersion} release sections were found`,
|
|
214
|
+
`Exactly one ## [${targetVersion}] - YYYY-MM-DD section`,
|
|
215
|
+
`Keep one ${targetVersion} release section in the package changelog.`,
|
|
216
|
+
),
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const target = targets.length === 1 ? targets[0] : undefined;
|
|
221
|
+
const dateMatch = /^ - (\d{4}-\d{2}-\d{2})$/u.exec(
|
|
222
|
+
target === undefined ? "" : releaseHeading(target.text)!.suffix,
|
|
223
|
+
);
|
|
224
|
+
const releaseDate = dateMatch?.[1];
|
|
225
|
+
if (
|
|
226
|
+
target !== undefined &&
|
|
227
|
+
(releaseDate === undefined || !isGregorianCalendarDate(releaseDate))
|
|
228
|
+
) {
|
|
229
|
+
blockers.push(
|
|
230
|
+
blocker(
|
|
231
|
+
"changelog-target-release-date-invalid",
|
|
232
|
+
target.text,
|
|
233
|
+
`## [${targetVersion}] - YYYY-MM-DD with a real calendar date`,
|
|
234
|
+
`Correct the ${targetVersion} release heading date.`,
|
|
235
|
+
),
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let releaseNotes = "";
|
|
240
|
+
if (
|
|
241
|
+
target !== undefined &&
|
|
242
|
+
releaseDate !== undefined &&
|
|
243
|
+
isGregorianCalendarDate(releaseDate)
|
|
244
|
+
) {
|
|
245
|
+
const followingHeading = lines.find(
|
|
246
|
+
(line) =>
|
|
247
|
+
line.start >= target.end &&
|
|
248
|
+
line.outsideFence &&
|
|
249
|
+
line.text.startsWith("## "),
|
|
250
|
+
);
|
|
251
|
+
const footerStart = documentFooterStart(lines);
|
|
252
|
+
const sectionEnd = Math.min(
|
|
253
|
+
followingHeading?.start ?? source.length,
|
|
254
|
+
footerStart ?? source.length,
|
|
255
|
+
);
|
|
256
|
+
const sectionLines = lines.filter(
|
|
257
|
+
(line) => line.start >= target.end && line.start < sectionEnd,
|
|
258
|
+
);
|
|
259
|
+
releaseNotes = trimBoundaryBlankLines(source, sectionLines);
|
|
260
|
+
if (releaseNotes.length === 0) {
|
|
261
|
+
blockers.push(
|
|
262
|
+
blocker(
|
|
263
|
+
"changelog-target-release-body-empty",
|
|
264
|
+
`The ${targetVersion} release body is empty`,
|
|
265
|
+
"A non-empty release body after footer definitions are removed",
|
|
266
|
+
`Document the ${targetVersion} user-visible changes.`,
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (blockers.length > 0) {
|
|
273
|
+
return {
|
|
274
|
+
blockers: blockers as [ChangelogBlocker, ...ChangelogBlocker[]],
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
blockers: [],
|
|
280
|
+
releaseDate: releaseDate!,
|
|
281
|
+
releaseNotes,
|
|
282
|
+
};
|
|
283
|
+
}
|
package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import { verifyNpmPublicationArtifact } from "./artifact.ts";
|
|
7
|
+
|
|
8
|
+
const publicCliPackagePath = "{{PUBLIC_CLI_PACKAGE_PATH}}";
|
|
9
|
+
|
|
10
|
+
function oneLine(value: string): string {
|
|
11
|
+
return value.replaceAll(/\s*\r?\n\s*/gu, " ");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const rawArguments = process.argv.slice(2);
|
|
15
|
+
const arguments_ =
|
|
16
|
+
rawArguments[0] === "--" ? rawArguments.slice(1) : rawArguments;
|
|
17
|
+
const outputDirectoryFromEnvironment =
|
|
18
|
+
process.env.PUBLICATION_ARTIFACT_OUTPUT_DIRECTORY;
|
|
19
|
+
const explicitOutputDirectory =
|
|
20
|
+
arguments_.length === 2 &&
|
|
21
|
+
arguments_[0] === "--output-directory" &&
|
|
22
|
+
arguments_[1]!.length > 0
|
|
23
|
+
? path.resolve(arguments_[1]!)
|
|
24
|
+
: undefined;
|
|
25
|
+
const environmentOutputDirectory =
|
|
26
|
+
outputDirectoryFromEnvironment === undefined
|
|
27
|
+
? undefined
|
|
28
|
+
: outputDirectoryFromEnvironment.length === 0 ||
|
|
29
|
+
!path.isAbsolute(outputDirectoryFromEnvironment)
|
|
30
|
+
? null
|
|
31
|
+
: outputDirectoryFromEnvironment;
|
|
32
|
+
const validArguments =
|
|
33
|
+
(arguments_.length === 0 && environmentOutputDirectory !== null) ||
|
|
34
|
+
(explicitOutputDirectory !== undefined &&
|
|
35
|
+
environmentOutputDirectory === undefined);
|
|
36
|
+
if (!validArguments) {
|
|
37
|
+
console.error("ERROR publication-artifact-usage");
|
|
38
|
+
console.error(`Observed: ${JSON.stringify(arguments_)}`);
|
|
39
|
+
console.error(
|
|
40
|
+
"Expected: no arguments, one absolute PUBLICATION_ARTIFACT_OUTPUT_DIRECTORY, or --output-directory <existing-empty-directory>",
|
|
41
|
+
);
|
|
42
|
+
console.error(
|
|
43
|
+
"Next action: Run without arguments for disposable verification, or pass one existing empty directory to retain the tgz, checksum, and receipt.",
|
|
44
|
+
);
|
|
45
|
+
process.exitCode = 2;
|
|
46
|
+
} else {
|
|
47
|
+
const configuredOutputDirectory =
|
|
48
|
+
explicitOutputDirectory ?? environmentOutputDirectory ?? undefined;
|
|
49
|
+
const ownedTemporaryOutput = configuredOutputDirectory === undefined;
|
|
50
|
+
const outputDirectory =
|
|
51
|
+
configuredOutputDirectory ??
|
|
52
|
+
(await mkdtemp(path.join(tmpdir(), "npm-publication-artifact-")));
|
|
53
|
+
try {
|
|
54
|
+
const result = await verifyNpmPublicationArtifact({
|
|
55
|
+
repositoryRoot: process.cwd(),
|
|
56
|
+
packagePath: publicCliPackagePath,
|
|
57
|
+
outputDirectory,
|
|
58
|
+
});
|
|
59
|
+
if (result.kind === "blocked") {
|
|
60
|
+
console.log("npm publication artifact: blocked");
|
|
61
|
+
console.log(`Mode: ${result.readiness.mode}`);
|
|
62
|
+
for (const item of result.readiness.blockers) {
|
|
63
|
+
console.log(`BLOCKER ${item.code}`);
|
|
64
|
+
console.log(`Owner: ${item.owner.path}${item.owner.pointer ?? ""}`);
|
|
65
|
+
console.log(`Observed: ${oneLine(item.observed)}`);
|
|
66
|
+
console.log(`Expected: ${oneLine(item.expected)}`);
|
|
67
|
+
console.log(`Next action: ${oneLine(item.nextAction)}`);
|
|
68
|
+
}
|
|
69
|
+
if (result.readiness.mode === "public-intent") process.exitCode = 1;
|
|
70
|
+
} else if (result.kind === "failed") {
|
|
71
|
+
console.error(`ERROR ${result.failure.code}`);
|
|
72
|
+
console.error(`Observed: ${oneLine(result.failure.observed)}`);
|
|
73
|
+
console.error(`Expected: ${oneLine(result.failure.expected)}`);
|
|
74
|
+
console.error(`Next action: ${oneLine(result.failure.nextAction)}`);
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
} else {
|
|
77
|
+
console.log("npm publication artifact: verified");
|
|
78
|
+
console.log(
|
|
79
|
+
`Package: ${result.receipt.publication.packageName}@${result.receipt.publication.version}`,
|
|
80
|
+
);
|
|
81
|
+
console.log(`Command: ${result.receipt.publication.commandName}`);
|
|
82
|
+
for (const file of result.receipt.files)
|
|
83
|
+
console.log(`File: ${file.path}`);
|
|
84
|
+
console.log(`Integrity: ${result.receipt.artifact.integrity}`);
|
|
85
|
+
console.log(`Checksum: ${result.receipt.artifact.checksumFile}`);
|
|
86
|
+
for (const smoke of result.receipt.smokes)
|
|
87
|
+
console.log(`Smoke: ${smoke.name}`);
|
|
88
|
+
if (!ownedTemporaryOutput) {
|
|
89
|
+
console.log(`Artifact: ${result.artifactPath}`);
|
|
90
|
+
console.log(`Checksum file: ${result.checksumPath}`);
|
|
91
|
+
console.log(`Receipt: ${result.receiptPath}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} finally {
|
|
95
|
+
if (ownedTemporaryOutput) {
|
|
96
|
+
await rm(outputDirectory, { recursive: true, force: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-readiness.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { inspectNpmPublicationReadiness } from "./readiness.ts";
|
|
3
|
+
|
|
4
|
+
const publicCliPackagePath = "{{PUBLIC_CLI_PACKAGE_PATH}}";
|
|
5
|
+
|
|
6
|
+
function oneLine(value: string): string {
|
|
7
|
+
return value.replaceAll(/\s*\r?\n\s*/gu, " ");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const cliArguments = process.argv.slice(2);
|
|
11
|
+
const unknownArguments = cliArguments.filter(
|
|
12
|
+
(argument) => argument !== "--require-ready",
|
|
13
|
+
);
|
|
14
|
+
if (
|
|
15
|
+
unknownArguments.length > 0 ||
|
|
16
|
+
cliArguments.filter((argument) => argument === "--require-ready").length > 1
|
|
17
|
+
) {
|
|
18
|
+
console.error("ERROR publication-readiness-usage");
|
|
19
|
+
console.error(`Observed: ${JSON.stringify(cliArguments)}`);
|
|
20
|
+
console.error("Expected: no arguments or --require-ready");
|
|
21
|
+
console.error(
|
|
22
|
+
"Next action: Run the generated publication:readiness script with a supported option.",
|
|
23
|
+
);
|
|
24
|
+
process.exitCode = 2;
|
|
25
|
+
} else {
|
|
26
|
+
try {
|
|
27
|
+
const result = await inspectNpmPublicationReadiness({
|
|
28
|
+
repositoryRoot: process.cwd(),
|
|
29
|
+
packagePath: publicCliPackagePath,
|
|
30
|
+
});
|
|
31
|
+
if (result.kind === "ready") {
|
|
32
|
+
console.log("npm publication readiness: ready");
|
|
33
|
+
console.log(
|
|
34
|
+
`Package: ${result.publication.packageName}@${result.publication.version}`,
|
|
35
|
+
);
|
|
36
|
+
console.log(`Command: ${result.publication.commandName}`);
|
|
37
|
+
console.log(`Repository: ${result.publication.repository}`);
|
|
38
|
+
} else {
|
|
39
|
+
console.log("npm publication readiness: blocked");
|
|
40
|
+
console.log(`Mode: ${result.mode}`);
|
|
41
|
+
for (const item of result.blockers) {
|
|
42
|
+
console.log(`BLOCKER ${item.code}`);
|
|
43
|
+
console.log(`Owner: ${item.owner.path}${item.owner.pointer ?? ""}`);
|
|
44
|
+
console.log(`Observed: ${oneLine(item.observed)}`);
|
|
45
|
+
console.log(`Expected: ${oneLine(item.expected)}`);
|
|
46
|
+
console.log(`Next action: ${oneLine(item.nextAction)}`);
|
|
47
|
+
}
|
|
48
|
+
if (
|
|
49
|
+
cliArguments.includes("--require-ready") ||
|
|
50
|
+
result.mode === "public-intent"
|
|
51
|
+
) {
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error("ERROR publication-readiness-inspection");
|
|
57
|
+
console.error(
|
|
58
|
+
`Observed: ${oneLine(error instanceof Error ? error.message : String(error))}`,
|
|
59
|
+
);
|
|
60
|
+
console.error("Expected: readable local npm publication owner facts");
|
|
61
|
+
console.error(
|
|
62
|
+
"Next action: Correct the reported repository path or filesystem failure and retry.",
|
|
63
|
+
);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// The Generated Repository projects the implementation source itself to this
|
|
2
|
+
// path. This source-tree adapter keeps direct Template Source checks on the
|
|
3
|
+
// same implementation without creating a third command-identity policy.
|
|
4
|
+
export * from "../src/cli-command-identity.ts";
|