@ykdz/template 0.0.31 → 0.0.33
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/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +10 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +320 -161
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +66 -9
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.d.ts +2 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.js +35 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.d.ts +13 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.js +70 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +2 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +22 -7
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +4 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +4 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +82 -11
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +9 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +27 -10
- package/node_modules/@ykdz/template-builtin-presets/package.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +81 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +55 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-diagnostics.yml +64 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check.yml +24 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/devcontainer.json +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/gitignore +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo.json +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/typescript-config/base.json +15 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/typescript-config/turbo.json +4 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/devcontainer/rust.Dockerfile +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/devcontainer/browser-test.Dockerfile +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/oxc/tsconfig.config.json +2 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.app.json +6 -13
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.node.json +2 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.json +2 -6
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/tsconfig.json +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/tsconfig.json +2 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/tsconfig.json +2 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/devcontainer/docker-client.Dockerfile +3 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/playwright.config.ts +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/scripts/check-standalone-deployment.ts +67 -27
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.app.json +6 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.node.json +2 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.test.json +0 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/playwright.config.ts +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/tsconfig.json +2 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/playwright.config.ts +2 -0
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.d.ts +19 -0
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.js +68 -0
- package/node_modules/@ykdz/template-core/dist/development-container-tool-layer.d.ts +56 -0
- package/node_modules/@ykdz/template-core/dist/development-container-tool-layer.js +361 -0
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +15 -1
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +7 -0
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +1 -0
- package/node_modules/@ykdz/template-core/dist/project-github.d.ts +51 -15
- package/node_modules/@ykdz/template-core/dist/project-github.js +83 -96
- package/node_modules/@ykdz/template-core/dist/project-projection.d.ts +9 -0
- package/node_modules/@ykdz/template-core/dist/project-projection.js +84 -5
- package/node_modules/@ykdz/template-core/dist/renderer.d.ts +1 -0
- package/node_modules/@ykdz/template-core/dist/renderer.js +47 -7
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.d.ts +15 -1
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +183 -1
- package/package.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-playwright.yml +0 -20
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-rust.yml +0 -23
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check.dynamic.template +0 -19
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/rust/.vscode/extensions.json +0 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/rust/.vscode/settings.json +0 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/rust/devcontainer/devcontainer.json +0 -21
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/rust/devcontainer/rust.Dockerfile +0 -18
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/rust/rust-toolchain.toml +0 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/devcontainer/devcontainer.json +0 -21
- package/node_modules/@ykdz/template-core/dist/devcontainer.d.ts +0 -83
- package/node_modules/@ykdz/template-core/dist/devcontainer.js +0 -217
- /package/node_modules/@ykdz/template-builtin-presets/templates/{shared → vike-app}/devcontainer/shellcheck.Dockerfile +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
|
|
4
5
|
const webRoot = path.resolve(import.meta.dirname, "..");
|
|
@@ -194,7 +195,34 @@ async function deploymentLogs(): Promise<string> {
|
|
|
194
195
|
return logs.join("\n");
|
|
195
196
|
}
|
|
196
197
|
|
|
197
|
-
async function
|
|
198
|
+
async function dockerHostGatewayAddress(): Promise<string | undefined> {
|
|
199
|
+
try {
|
|
200
|
+
const routes = await readFile("/proc/net/route", "utf8");
|
|
201
|
+
for (const line of routes.split("\n").slice(1)) {
|
|
202
|
+
const [, destination, gateway] = line.trim().split(/\s+/u);
|
|
203
|
+
if (
|
|
204
|
+
destination !== "00000000" ||
|
|
205
|
+
gateway === undefined ||
|
|
206
|
+
gateway === "00000000"
|
|
207
|
+
) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
const octets = gateway.match(/../gu)?.reverse();
|
|
211
|
+
if (octets === undefined) return undefined;
|
|
212
|
+
return octets
|
|
213
|
+
.map((octet) => String(Number.parseInt(octet, 16)))
|
|
214
|
+
.join(".");
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
// /proc/net/route is Linux-specific. Local Docker-on-host runs still use
|
|
218
|
+
// the loopback candidate below.
|
|
219
|
+
}
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async function publishedBaseUrls(
|
|
224
|
+
container: string,
|
|
225
|
+
): Promise<readonly string[]> {
|
|
198
226
|
const portOutput = await dockerWithTimeout(
|
|
199
227
|
10_000,
|
|
200
228
|
"port",
|
|
@@ -207,26 +235,33 @@ async function publishedBaseUrl(container: string): Promise<string> {
|
|
|
207
235
|
`Could not determine the published web port: ${portOutput}`,
|
|
208
236
|
);
|
|
209
237
|
}
|
|
210
|
-
|
|
238
|
+
const gateway = await dockerHostGatewayAddress();
|
|
239
|
+
return [
|
|
240
|
+
`http://127.0.0.1:${match[1]}`,
|
|
241
|
+
gateway === undefined ? undefined : `http://${gateway}:${match[1]}`,
|
|
242
|
+
].filter((candidate): candidate is string => candidate !== undefined);
|
|
211
243
|
}
|
|
212
244
|
|
|
213
245
|
async function waitForReady(
|
|
214
246
|
phase: "Standalone" | "Runtime",
|
|
215
247
|
container: string,
|
|
216
|
-
|
|
217
|
-
): Promise<
|
|
248
|
+
baseUrls: readonly string[],
|
|
249
|
+
): Promise<string> {
|
|
218
250
|
const timeout = readinessTimeoutMs();
|
|
219
251
|
const deadline = Date.now() + timeout;
|
|
220
252
|
while (Date.now() < deadline) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
253
|
+
for (const baseUrl of baseUrls) {
|
|
254
|
+
try {
|
|
255
|
+
const response = await fetch(baseUrl, {
|
|
256
|
+
signal: AbortSignal.timeout(2_000),
|
|
257
|
+
});
|
|
258
|
+
if (response.ok) {
|
|
259
|
+
return baseUrl;
|
|
260
|
+
}
|
|
261
|
+
} catch {
|
|
262
|
+
// The container may still be starting the server, or this candidate may
|
|
263
|
+
// not be reachable from the current Docker execution topology.
|
|
227
264
|
}
|
|
228
|
-
} catch {
|
|
229
|
-
// The container may still be starting the server.
|
|
230
265
|
}
|
|
231
266
|
|
|
232
267
|
const running = await dockerWithTimeout(
|
|
@@ -244,7 +279,7 @@ async function waitForReady(
|
|
|
244
279
|
}
|
|
245
280
|
|
|
246
281
|
throw new Error(
|
|
247
|
-
`${phase} container was not ready within ${timeout}ms.\n${await containerLogs(container)}`,
|
|
282
|
+
`${phase} container was not ready at ${baseUrls.join(", ")} within ${timeout}ms.\n${await containerLogs(container)}`,
|
|
248
283
|
);
|
|
249
284
|
}
|
|
250
285
|
|
|
@@ -313,17 +348,17 @@ async function runStartedDeployment(
|
|
|
313
348
|
"--network",
|
|
314
349
|
network,
|
|
315
350
|
"--publish",
|
|
316
|
-
"
|
|
351
|
+
"0.0.0.0::3000",
|
|
317
352
|
"--volume",
|
|
318
353
|
`${volume}:/data`,
|
|
319
354
|
image,
|
|
320
355
|
),
|
|
321
356
|
);
|
|
322
|
-
const
|
|
323
|
-
|
|
357
|
+
const baseUrls = await deploymentPhase(mode, "start", async () =>
|
|
358
|
+
publishedBaseUrls(container),
|
|
324
359
|
);
|
|
325
|
-
await deploymentPhase(mode, "readiness", async () =>
|
|
326
|
-
waitForReady(readinessLabel, container,
|
|
360
|
+
const baseUrl = await deploymentPhase(mode, "readiness", async () =>
|
|
361
|
+
waitForReady(readinessLabel, container, baseUrls),
|
|
327
362
|
);
|
|
328
363
|
await deploymentPhase(mode, "identity", async () =>
|
|
329
364
|
assertProcessIdentity(readinessLabel, container),
|
|
@@ -344,12 +379,12 @@ async function assertUnpreparedRuntimeFails(): Promise<void> {
|
|
|
344
379
|
"--network",
|
|
345
380
|
network,
|
|
346
381
|
"--publish",
|
|
347
|
-
"
|
|
382
|
+
"0.0.0.0::3000",
|
|
348
383
|
"--volume",
|
|
349
384
|
`${volumes.unprepared}:/data`,
|
|
350
385
|
runtimeImage,
|
|
351
386
|
);
|
|
352
|
-
const
|
|
387
|
+
const baseUrls = await publishedBaseUrls(containers.unprepared);
|
|
353
388
|
const deadline = Date.now() + 30_000;
|
|
354
389
|
|
|
355
390
|
while (Date.now() < deadline) {
|
|
@@ -362,16 +397,21 @@ async function assertUnpreparedRuntimeFails(): Promise<void> {
|
|
|
362
397
|
(state) => ({ state }),
|
|
363
398
|
(error: unknown) => ({ error }),
|
|
364
399
|
);
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
400
|
+
const probes = await Promise.all(
|
|
401
|
+
baseUrls.map((baseUrl) =>
|
|
402
|
+
fetch(baseUrl, {
|
|
403
|
+
signal: AbortSignal.timeout(500),
|
|
404
|
+
}).then(
|
|
405
|
+
(response) => ({ baseUrl, response }),
|
|
406
|
+
() => ({ baseUrl, response: undefined }),
|
|
407
|
+
),
|
|
408
|
+
),
|
|
370
409
|
);
|
|
371
410
|
|
|
372
|
-
|
|
411
|
+
const servedProbe = probes.find((probe) => probe.response !== undefined);
|
|
412
|
+
if (servedProbe?.response !== undefined) {
|
|
373
413
|
throw new Error(
|
|
374
|
-
`Unprepared runtime served HTTP ${
|
|
414
|
+
`Unprepared runtime served HTTP ${servedProbe.response.status} at ${servedProbe.baseUrl} before exiting.`,
|
|
375
415
|
);
|
|
376
416
|
}
|
|
377
417
|
|
package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.app.json
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends":
|
|
2
|
+
"extends": [
|
|
3
|
+
"@vue/tsconfig/tsconfig.dom.json",
|
|
4
|
+
"{{TYPESCRIPT_CONFIG_PACKAGE}}/base.json"
|
|
5
|
+
],
|
|
3
6
|
"compilerOptions": {
|
|
4
7
|
"composite": true,
|
|
5
8
|
"customConditions": ["source"],
|
|
6
|
-
"exactOptionalPropertyTypes":
|
|
7
|
-
"forceConsistentCasingInFileNames": true,
|
|
8
|
-
"isolatedModules": true,
|
|
9
|
+
"exactOptionalPropertyTypes": false,
|
|
9
10
|
"module": "esnext",
|
|
10
11
|
"moduleResolution": "bundler",
|
|
11
|
-
"noEmitOnError": true,
|
|
12
|
-
"noFallthroughCasesInSwitch": true,
|
|
13
|
-
"noImplicitOverride": true,
|
|
14
|
-
"noImplicitReturns": true,
|
|
15
|
-
"noUncheckedIndexedAccess": true,
|
|
16
12
|
"rewriteRelativeImportExtensions": false,
|
|
17
13
|
"skipLibCheck": true,
|
|
18
|
-
"strict": true,
|
|
19
14
|
"target": "es2023",
|
|
20
15
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
21
|
-
"types": ["node"]
|
|
22
|
-
"verbatimModuleSyntax": true
|
|
16
|
+
"types": ["node"]
|
|
23
17
|
},
|
|
24
18
|
"include": [
|
|
25
19
|
"+server.ts",
|
package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.node.json
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "{{TYPESCRIPT_CONFIG_PACKAGE}}/base.json",
|
|
2
3
|
"compilerOptions": {
|
|
3
4
|
"composite": true,
|
|
4
5
|
"customConditions": ["source"],
|
|
5
6
|
"erasableSyntaxOnly": true,
|
|
6
|
-
"exactOptionalPropertyTypes": true,
|
|
7
|
-
"forceConsistentCasingInFileNames": true,
|
|
8
|
-
"isolatedModules": true,
|
|
9
7
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
10
8
|
"module": "esnext",
|
|
11
9
|
"moduleResolution": "bundler",
|
|
12
|
-
"noEmitOnError": true,
|
|
13
|
-
"noFallthroughCasesInSwitch": true,
|
|
14
|
-
"noImplicitOverride": true,
|
|
15
|
-
"noImplicitReturns": true,
|
|
16
|
-
"noUncheckedIndexedAccess": true,
|
|
17
10
|
"rewriteRelativeImportExtensions": false,
|
|
18
11
|
"skipLibCheck": true,
|
|
19
|
-
"strict": true,
|
|
20
12
|
"target": "es2023",
|
|
21
13
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
22
|
-
"types": ["node"]
|
|
23
|
-
"verbatimModuleSyntax": true
|
|
14
|
+
"types": ["node"]
|
|
24
15
|
},
|
|
25
16
|
"include": [
|
|
26
17
|
"playwright.config.ts",
|
|
@@ -17,8 +17,9 @@ export default defineConfig({
|
|
|
17
17
|
testDir: "./test/e2e",
|
|
18
18
|
use: {
|
|
19
19
|
baseURL: previewUrl,
|
|
20
|
-
trace: "on-
|
|
20
|
+
trace: "retain-on-failure",
|
|
21
21
|
},
|
|
22
|
+
reporter: [["list"], ["html"]],
|
|
22
23
|
webServer: {
|
|
23
24
|
command: `pnpm run preview --host 127.0.0.1 --port ${previewPort}`,
|
|
24
25
|
reuseExistingServer: !process.env.CI,
|
package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/tsconfig.json
CHANGED
|
@@ -1,26 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "{{TYPESCRIPT_CONFIG_PACKAGE}}/base.json",
|
|
2
3
|
"compilerOptions": {
|
|
3
4
|
"composite": true,
|
|
4
5
|
"customConditions": ["source"],
|
|
5
6
|
"declaration": true,
|
|
6
7
|
"declarationMap": true,
|
|
7
8
|
"erasableSyntaxOnly": true,
|
|
8
|
-
"exactOptionalPropertyTypes": true,
|
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
|
10
|
-
"isolatedModules": true,
|
|
11
9
|
"module": "nodenext",
|
|
12
10
|
"moduleResolution": "nodenext",
|
|
13
|
-
"noEmitOnError": true,
|
|
14
|
-
"noFallthroughCasesInSwitch": true,
|
|
15
|
-
"noImplicitOverride": true,
|
|
16
|
-
"noImplicitReturns": true,
|
|
17
|
-
"noUncheckedIndexedAccess": true,
|
|
18
11
|
"rewriteRelativeImportExtensions": true,
|
|
19
|
-
"skipLibCheck": false,
|
|
20
|
-
"strict": true,
|
|
21
12
|
"target": "es2023",
|
|
22
|
-
"types": ["node", "vitest/globals"]
|
|
23
|
-
"verbatimModuleSyntax": true
|
|
13
|
+
"types": ["node", "vitest/globals"]
|
|
24
14
|
},
|
|
25
15
|
"include": ["src/**/*.ts", "test/**/*.ts", "vitest.config.ts"]
|
|
26
16
|
}
|
package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/playwright.config.ts
CHANGED
|
@@ -20,8 +20,10 @@ export default defineConfig({
|
|
|
20
20
|
testDir: "./test/e2e",
|
|
21
21
|
use: {
|
|
22
22
|
baseURL: webBaseUrl,
|
|
23
|
+
trace: "retain-on-failure",
|
|
23
24
|
...devices["Desktop Chrome"],
|
|
24
25
|
},
|
|
26
|
+
reporter: [["list"], ["html"]],
|
|
25
27
|
webServer: [
|
|
26
28
|
{
|
|
27
29
|
command: `PORT=${apiPort} pnpm --dir ../api run start`,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PackageBoundaryOwner } from "./module-graph.ts";
|
|
2
|
+
/** Closed, owner-scoped native evidence a Package Contribution may retain in CI. */
|
|
3
|
+
export type CiDiagnosticArtifactDeclaration = {
|
|
4
|
+
readonly kind: "playwright";
|
|
5
|
+
readonly owner: PackageBoundaryOwner;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Validates the intentionally closed diagnostic declaration surface. It does
|
|
9
|
+
* not accept paths: native paths are derived only after the owner is known.
|
|
10
|
+
*/
|
|
11
|
+
export declare function assertCiDiagnosticArtifactDeclaration(value: unknown): CiDiagnosticArtifactDeclaration;
|
|
12
|
+
/**
|
|
13
|
+
* Composes closed native diagnostics independently of presets and environment
|
|
14
|
+
* preparation. Equivalent declarations collapse into stable owner order.
|
|
15
|
+
*/
|
|
16
|
+
export declare function composeCiDiagnosticArtifacts(options: {
|
|
17
|
+
readonly packagePaths: readonly string[];
|
|
18
|
+
readonly declarations: readonly unknown[];
|
|
19
|
+
}): readonly CiDiagnosticArtifactDeclaration[];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function hasExactKeys(value, keys) {
|
|
5
|
+
const actual = Object.keys(value).toSorted();
|
|
6
|
+
const expected = [...keys].toSorted();
|
|
7
|
+
return (actual.length === expected.length &&
|
|
8
|
+
actual.every((key, index) => key === expected[index]));
|
|
9
|
+
}
|
|
10
|
+
const reservedWorkspaceCollections = new Set([
|
|
11
|
+
".git",
|
|
12
|
+
".github",
|
|
13
|
+
".devcontainer",
|
|
14
|
+
".template",
|
|
15
|
+
"node_modules",
|
|
16
|
+
"dist",
|
|
17
|
+
"target",
|
|
18
|
+
]);
|
|
19
|
+
function isSafePackagePath(value) {
|
|
20
|
+
return (/^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/u.test(value) &&
|
|
21
|
+
!reservedWorkspaceCollections.has(value.split("/", 1)[0]));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validates the intentionally closed diagnostic declaration surface. It does
|
|
25
|
+
* not accept paths: native paths are derived only after the owner is known.
|
|
26
|
+
*/
|
|
27
|
+
export function assertCiDiagnosticArtifactDeclaration(value) {
|
|
28
|
+
if (!isRecord(value) || !hasExactKeys(value, ["kind", "owner"])) {
|
|
29
|
+
throw new Error("CI Diagnostic Artifact declarations may contain only kind and owner");
|
|
30
|
+
}
|
|
31
|
+
if (value.kind !== "playwright") {
|
|
32
|
+
throw new Error("Unsupported CI Diagnostic Artifact kind");
|
|
33
|
+
}
|
|
34
|
+
if (!isRecord(value.owner) || !hasExactKeys(value.owner, ["kind", "path"])) {
|
|
35
|
+
throw new Error("CI Diagnostic Artifact requires a Package Boundary owner");
|
|
36
|
+
}
|
|
37
|
+
if (value.owner.kind !== "package-boundary" ||
|
|
38
|
+
typeof value.owner.path !== "string" ||
|
|
39
|
+
!isSafePackagePath(value.owner.path)) {
|
|
40
|
+
throw new Error("CI Diagnostic Artifact owner has an unsafe Package Boundary path");
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
kind: "playwright",
|
|
44
|
+
owner: { kind: "package-boundary", path: value.owner.path },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Composes closed native diagnostics independently of presets and environment
|
|
49
|
+
* preparation. Equivalent declarations collapse into stable owner order.
|
|
50
|
+
*/
|
|
51
|
+
export function composeCiDiagnosticArtifacts(options) {
|
|
52
|
+
for (const packagePath of options.packagePaths) {
|
|
53
|
+
if (!isSafePackagePath(packagePath)) {
|
|
54
|
+
throw new Error(`CI Diagnostic Artifact Package Boundary path is unsafe: ${packagePath}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const owners = new Set(options.packagePaths);
|
|
58
|
+
const artifacts = new Map();
|
|
59
|
+
for (const value of options.declarations) {
|
|
60
|
+
const declaration = assertCiDiagnosticArtifactDeclaration(value);
|
|
61
|
+
if (!owners.has(declaration.owner.path)) {
|
|
62
|
+
throw new Error(`CI Diagnostic Artifact owner is not a declared Package Boundary: ${declaration.owner.path}`);
|
|
63
|
+
}
|
|
64
|
+
const key = `${declaration.kind}:${declaration.owner.path}`;
|
|
65
|
+
artifacts.set(key, declaration);
|
|
66
|
+
}
|
|
67
|
+
return [...artifacts.values()].toSorted((left, right) => left.owner.path.localeCompare(right.owner.path));
|
|
68
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type TemplateSourceHandle } from "./renderer.ts";
|
|
2
|
+
export type DevelopmentContainerToolLayerBuildArgument = {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly value: string;
|
|
5
|
+
};
|
|
6
|
+
export type DevelopmentContainerToolLayerMount = {
|
|
7
|
+
readonly identity: string;
|
|
8
|
+
readonly type: "bind" | "volume";
|
|
9
|
+
readonly source: string;
|
|
10
|
+
readonly target: string;
|
|
11
|
+
};
|
|
12
|
+
export type DevelopmentContainerToolLayerProbe = {
|
|
13
|
+
readonly identity: string;
|
|
14
|
+
readonly command: string;
|
|
15
|
+
readonly args?: readonly string[] | undefined;
|
|
16
|
+
readonly failureMessage?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
export type DevelopmentContainerToolLayer = {
|
|
19
|
+
readonly identity: string;
|
|
20
|
+
readonly dockerfile: {
|
|
21
|
+
readonly source: TemplateSourceHandle;
|
|
22
|
+
readonly from: string;
|
|
23
|
+
};
|
|
24
|
+
readonly requires?: readonly string[] | undefined;
|
|
25
|
+
readonly buildArguments?: readonly DevelopmentContainerToolLayerBuildArgument[] | undefined;
|
|
26
|
+
readonly mounts?: readonly DevelopmentContainerToolLayerMount[] | undefined;
|
|
27
|
+
readonly probes?: readonly DevelopmentContainerToolLayerProbe[] | undefined;
|
|
28
|
+
};
|
|
29
|
+
export type PlannedDevelopmentContainerToolLayer = DevelopmentContainerToolLayer & {
|
|
30
|
+
readonly kind: "base" | "optional";
|
|
31
|
+
};
|
|
32
|
+
export type DevelopmentContainerToolLayerPlan = {
|
|
33
|
+
readonly layers: readonly PlannedDevelopmentContainerToolLayer[];
|
|
34
|
+
readonly buildArguments: readonly DevelopmentContainerToolLayerBuildArgument[];
|
|
35
|
+
readonly mounts: readonly DevelopmentContainerToolLayerMount[];
|
|
36
|
+
readonly probes: readonly DevelopmentContainerToolLayerProbe[];
|
|
37
|
+
};
|
|
38
|
+
type DevelopmentContainerDockerfileFragment = {
|
|
39
|
+
readonly identity: string;
|
|
40
|
+
readonly kind: "base" | "optional";
|
|
41
|
+
readonly from: string;
|
|
42
|
+
readonly text: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function validateDevelopmentContainerDockerfileFragments(options: {
|
|
45
|
+
readonly baseFragment: Omit<DevelopmentContainerDockerfileFragment, "kind">;
|
|
46
|
+
readonly fragments?: readonly Omit<DevelopmentContainerDockerfileFragment, "kind">[];
|
|
47
|
+
}): void;
|
|
48
|
+
export declare function planDevelopmentContainerToolLayersSync(options: {
|
|
49
|
+
readonly baseLayer: DevelopmentContainerToolLayer;
|
|
50
|
+
readonly layers?: readonly DevelopmentContainerToolLayer[] | undefined;
|
|
51
|
+
}): DevelopmentContainerToolLayerPlan;
|
|
52
|
+
export declare function planDevelopmentContainerToolLayers(options: {
|
|
53
|
+
readonly baseLayer: DevelopmentContainerToolLayer;
|
|
54
|
+
readonly layers?: readonly DevelopmentContainerToolLayer[] | undefined;
|
|
55
|
+
}): Promise<DevelopmentContainerToolLayerPlan>;
|
|
56
|
+
export {};
|