@gfdelarue/testkit 0.3.2 → 0.3.4
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/README.md +7 -0
- package/bin/testkit-windows-owner-arm64.exe +0 -0
- package/bin/testkit-windows-owner-x64.exe +0 -0
- package/dist/app/cloud/control.js +2 -2
- package/dist/app/cloud/login.d.ts +4 -4
- package/dist/app/inspect/artifacts.d.ts +4 -4
- package/dist/app/run/engine-failure-stack.d.ts +1 -0
- package/dist/app/run/engine-failure-stack.js +2 -0
- package/dist/app/run/worker-loop.js +1 -1
- package/dist/app/setup/playwright.js +1 -1
- package/dist/app/typecheck/index.js +4 -4
- package/dist/cli/command-catalog.d.ts +24 -24
- package/dist/cli/command-flags.d.ts +3 -3
- package/dist/cli/commands/artifacts.d.ts +16 -16
- package/dist/cli/commands/cleanup.d.ts +1 -1
- package/dist/cli/commands/cloud/login.d.ts +1 -1
- package/dist/cli/commands/cloud/status.d.ts +3 -3
- package/dist/config/loader/discover-tests.d.ts +5 -0
- package/dist/config/loader/discover-tests.js +1 -1
- package/dist/config/loader/file-metadata.d.ts +1 -1
- package/dist/config/loader/file-metadata.js +1 -1
- package/dist/config/loader/index.d.ts +1 -1
- package/dist/config/loader/index.js +1 -1
- package/dist/config/loader/validation.js +1 -1
- package/dist/database/docker-metadata.d.ts +3 -0
- package/dist/database/docker-metadata.js +3 -0
- package/dist/database/docker.js +5 -5
- package/dist/database/index.js +1 -1
- package/dist/database/local-postgres.js +1 -1
- package/dist/database/postgres/index.js +2 -2
- package/dist/database/runtime-config.d.ts +5 -5
- package/dist/database/schema-source.d.ts +4 -1
- package/dist/database/schema-source.js +3 -3
- package/dist/database/template-steps.d.ts +4 -0
- package/dist/database/template-steps.js +4 -4
- package/dist/engines/managed-module-resolution.js +5 -3
- package/dist/engines/node-vitest/adapter/consumer-typescript-paths.js +2 -2
- package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
- package/dist/engines/playwright/runtime/runtime-input.js +1 -1
- package/dist/environment/template.d.ts +20 -20
- package/dist/process/execa-bundle-licenses.txt +411 -0
- package/dist/process/execa-bundle.json +874 -0
- package/dist/process/files/json-file.js +1 -1
- package/dist/process/host-process.d.ts +6 -1
- package/dist/process/host-process.js +1 -1
- package/dist/process/index.d.ts +2 -2
- package/dist/process/locks.js +3 -3
- package/dist/process/process-contracts.d.ts +10 -2
- package/dist/process/process-identity.js +1 -1
- package/dist/process/process.d.ts +3 -2
- package/dist/process/process.js +46 -1
- package/dist/repo/metadata.js +1 -1
- package/dist/repo/state.d.ts +1 -0
- package/dist/repo/state.js +4 -4
- package/dist/steps/configured-step-testkit-modules.d.ts +1 -1
- package/dist/steps/environment.d.ts +6 -0
- package/dist/steps/environment.js +1 -1
- package/dist/steps/index.d.ts +1 -1
- package/dist/steps/index.js +1 -1
- package/dist/steps/run.js +2 -2
- package/dist/toolchains/archive.js +1 -1
- package/dist/toolchains/node-integrity.d.ts +2 -0
- package/dist/toolchains/node-integrity.js +1 -1
- package/dist/toolchains/node-provisioning.js +2 -2
- package/package.json +4 -3
- package/testkit-config-schema.md +52 -0
package/README.md
CHANGED
|
@@ -1068,6 +1068,13 @@ platform's host address.
|
|
|
1068
1068
|
- template fingerprints are derived automatically from env files, source schema
|
|
1069
1069
|
cache, migrate/seed config, and repo contents
|
|
1070
1070
|
|
|
1071
|
+
The service process receives its provisioned database as `DATABASE_URL`. Tasks
|
|
1072
|
+
get it only through declared `env` values: use the `{dbUrl}`, `{dbHost}`,
|
|
1073
|
+
`{dbPort}`, `{dbName}`, `{dbUser}`, `{dbPassword}`, and `{dbSsl}` tokens, with
|
|
1074
|
+
`:serviceName` to read the database of a service listed in `dependsOn`. Testkit
|
|
1075
|
+
resolves them from the database provisioned for the current run. They are
|
|
1076
|
+
env-only; see [`env`](testkit-config-schema.md#env).
|
|
1077
|
+
|
|
1071
1078
|
`db schema refresh` forces a source database dump into the `.testkit` source
|
|
1072
1079
|
schema cache. `db schema verify` prepares local templates and verifies local
|
|
1073
1080
|
replay against the cached/refreshed source schema. `--skip-schema-source-verify`
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{setTimeout as v}from"node:timers/promises";import c from"node:fs";import $ from"node:path";import{randomUUID as I}from"node:crypto";import{execFileSync as R}from"node:child_process";import{CloudAccountClient as E}from"../../cloud/account.js";import{invalidResponse as u}from"../../cloud/transport.js";import{isUnknownRecord as p}from"../../kernel/unknown-values.js";import{cloudToken as k}from"./credentials.js";import{openBrowser as C,selectedCloudOrigin as S}from"./login.js";import{allItems as l,createdResourceDashboardLink as x}from"./control-links.js";export async function controlClient(o={},r=!0){const e=S(o);return new E(e,await k(e,o.env??process.env,r))}async function m(o,r,e,n){const t=r?o.filter(a=>a.id===r||a.slug===r||a.name===r):o;if(t.length>1&&!r&&n){const a=t.map(s=>{if(typeof s.id!="string"||!s.id)throw u(`${e} identity`);return{id:s.id,name:typeof s.name=="string"?s.name:s.id}}),d=await n(e,a);if(!a.some(s=>s.id===d))throw new Error(`Invalid ${e} selection`);return d}if(t.length!==1)throw new Error(`${e} ${r?`"${r}" `:""}${t.length?"is ambiguous":"was not found"}. Select an explicit ID from cloud list ${e==="organisation"?"organisations":"projects"}.`);const i=t[0]?.id;if(typeof i!="string"||!i)throw u(`${e} identity`);return i}export async function resolveOrganisation(o,r,e){const n=await l(o,"/api/v1/organisations");return m(n.map(t=>{if(!p(t.organisation))throw u("organisation");return t.organisation}),r,"organisation",e)}export async function resolveProject(o,r){const e=r.project??(r.env??process.env).TESTKIT_CLOUD_PROJECT_ID;if(e?.startsWith("prj_"))return e;const n=r.organisation?`?organisationId=${encodeURIComponent(await resolveOrganisation(o,r.organisation,r.choose))}`:"",t=await l(o,`/api/v1/projects${n}`),i=e?void 0:g(),a=i?projectsForRepository(t,i):[];return m(a.length?a:t,e,"project",r.choose)}function g(){try{return R("git",["remote","get-url","origin"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}export function projectsForRepository(o,r){let e;try{e=parseRepository(r)}catch{return[]}return o.filter(n=>{const t=n.repository;return p(t)&&t.host===e.host&&`${String(t.owner)}/${String(t.name)}`===e.repository})}export async function applyAccountCommand(o,r={}){const e=o.operation==="token.create";if(r.secretOutput!==void 0&&!e)throw new Error("--secret-output is only supported for token.create.");const n=r.secretOutput?$.resolve(r.secretOutput):void 0;if(e&&!n)throw new Error("Credential creation requires --secret-output <new-file> to save the issued token privately.");const t=n?c.openSync(n,"wx",384):void 0;let i=!1,a=!1,d=!1;try{const s=await controlClient(r);d=e;const f=await s.request("POST","/api/v1/account/commands",o);if(e&&t!==void 0&&n!==void 0){if(i=!0,!p(f)||typeof f.value!="string")throw u("issued credential");c.writeFileSync(t,`${f.value}
|
|
2
|
-
`),c.fsyncSync(t);const y=c.fstatSync(t),h=c.lstatSync(n);if(!h.isFile()||h.ino!==y.ino||h.dev!==y.dev)throw new Error("Credential output was replaced while the command was running");c.closeSync(t),a=!0;const w={...f};return delete w.value,{...w,secretFile:n}}return await waitForConnection(s,f,r)}catch(s){throw d&&n!==void 0?new Error(`Cloud ${i?"issued the credential, but saving it failed":"may have issued the credential before the request failed"}. Retry the same command and idempotency key with --secret-output pointing to a new file to recover it. Output path: ${n}.`,{cause:s}):s}finally{if(t!==void 0&&!a){const s=c.fstatSync(t);c.closeSync(t),!i&&s.size===
|
|
2
|
+
`),c.fsyncSync(t);const y=c.fstatSync(t,{bigint:!0}),h=c.lstatSync(n,{bigint:!0});if(!h.isFile()||h.ino!==y.ino||h.dev!==y.dev)throw new Error("Credential output was replaced while the command was running");c.closeSync(t),a=!0;const w={...f};return delete w.value,{...w,secretFile:n}}return await waitForConnection(s,f,r)}catch(s){throw d&&n!==void 0?new Error(`Cloud ${i?"issued the credential, but saving it failed":"may have issued the credential before the request failed"}. Retry the same command and idempotency key with --secret-output pointing to a new file to recover it. Output path: ${n}.`,{cause:s}):s}finally{if(t!==void 0&&!a){const s=c.fstatSync(t,{bigint:!0});c.closeSync(t),!i&&s.size===0n&&n!==void 0&&b(n,s)}}}function b(o,r){try{const e=c.lstatSync(o,{bigint:!0});e.isFile()&&e.size===0n&&e.ino===r.ino&&e.dev===r.dev&&c.unlinkSync(o)}catch(e){if(!p(e)||e.code!=="ENOENT")throw e}}export async function waitForConnection(o,r,e){if(!p(r)||typeof r.operationId!="string"||r.status==="complete")return r;let n=!1;for(;;){e.signal?.throwIfAborted();const t=await O(o,r.operationId);if(t.status==="complete")return t;if(t.status!=="pending"&&t.status!=="processing")throw new Error(`Repository connection ${r.operationId} is ${String(t.status)}. Inspect with cloud show connection ${r.operationId}; retry the create command with a new request key after checking access.`);if(t.status==="pending"&&!n){if(typeof t.verificationUrl!="string")throw u("repository approval link");const i=new URL(t.verificationUrl);if(i.origin!==o.origin||i.username||i.password||i.pathname!==`/cli/projects/${r.operationId}/authorize`)throw u("repository approval link");if(e.notify?.(`Open ${i.href}
|
|
3
3
|
Waiting for repository authorization. Operation: ${r.operationId}
|
|
4
|
-
`),(e.env??process.env).CI)throw new Error(`Repository authorization requires a person. Open ${i.href}, then retry the same request key. Operation: ${r.operationId}`);e.browser!==!1&&C(i.href),n=!0}if((e.env??process.env).CI)throw new Error(`Repository connection ${r.operationId} is processing. Inspect with cloud show connection ${r.operationId}, then retry the same request key to resume.`);if(typeof t.expiresAt!="string"||!Number.isFinite(Date.parse(t.expiresAt)))throw u("connection expiry");if(Date.now()>=Date.parse(t.expiresAt))throw new Error(`Repository connection ${r.operationId} expired. Start a new request.`);await v(2e3,void 0,{signal:e.signal})}}async function
|
|
4
|
+
`),(e.env??process.env).CI)throw new Error(`Repository authorization requires a person. Open ${i.href}, then retry the same request key. Operation: ${r.operationId}`);e.browser!==!1&&C(i.href),n=!0}if((e.env??process.env).CI)throw new Error(`Repository connection ${r.operationId} is processing. Inspect with cloud show connection ${r.operationId}, then retry the same request key to resume.`);if(typeof t.expiresAt!="string"||!Number.isFinite(Date.parse(t.expiresAt)))throw u("connection expiry");if(Date.now()>=Date.parse(t.expiresAt))throw new Error(`Repository connection ${r.operationId} expired. Start a new request.`);await v(2e3,void 0,{signal:e.signal})}}async function O(o,r){const e=await o.request("GET",`/api/v1/project-connections/${encodeURIComponent(r)}`);if(!p(e)||e.operationId!==r||typeof e.status!="string")throw u("repository connection");return e}export async function createCloudProject(o){const r=o.repository??g();if(!r)throw new Error("Pass --repository owner/repo when outside Git or when origin is unavailable.");const e=parseRepository(r,o.host),n=await controlClient(o),t=await resolveOrganisation(n,o.organisation,o.choose),i=o.requestKey??I();o.notify?.(`Request key: ${i}. Reuse --request-key ${i} to resume this operation.
|
|
5
5
|
`);const a=await applyAccountCommand({schemaVersion:1,idempotencyKey:i,operation:"project.create",organisationId:t,input:{name:o.name??e.repository.split("/")[1],repository:e.repository,host:e.host,provider:o.provider??(e.host==="github.com"?"github":"gitea"),publishDecisions:o.publishDecisions??!1}},o);return x(n,"project",a,o.env??process.env)}export function parseRepository(o,r){let e=o.trim(),n="github.com";if(e.includes("://")){const t=new URL(e);if(!["https:","http:","ssh:","git:"].includes(t.protocol)||t.search||t.hash)throw new Error("Repository must be owner/repo or a Git remote URL.");n=t.protocol==="ssh:"||t.protocol==="git:"?t.hostname:t.host,e=t.pathname.replace(/^\//u,"")}else{const t=/^(?:[^@/]+@)?([^/:]+):(.+)$/.exec(e);t?.[1]&&t[2]&&(n=t[1].toLowerCase(),e=t[2])}if(e=e.replace(/\/+$/u,"").replace(/\.git$/u,""),!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e)||e.split("/").some(t=>t==="."||t===".."))throw new Error("Repository must be owner/repo or a Git remote URL.");return{host:r??n,repository:e}}
|
|
@@ -11,7 +11,6 @@ export declare function selectedCloudOrigin(options: {
|
|
|
11
11
|
env?: NodeJS.ProcessEnv;
|
|
12
12
|
}): string;
|
|
13
13
|
export declare function loginToCloud(options: LoginOptions): Promise<{
|
|
14
|
-
reused: boolean;
|
|
15
14
|
user: {
|
|
16
15
|
id: string;
|
|
17
16
|
email: string;
|
|
@@ -20,6 +19,7 @@ export declare function loginToCloud(options: LoginOptions): Promise<{
|
|
|
20
19
|
expiresAt: string;
|
|
21
20
|
maximumExpiresAt: string;
|
|
22
21
|
origin: string;
|
|
22
|
+
reused: boolean;
|
|
23
23
|
}>;
|
|
24
24
|
export declare function cloudLoginStatus(options: {
|
|
25
25
|
origin?: string;
|
|
@@ -30,10 +30,10 @@ export declare function cloudLoginStatus(options: {
|
|
|
30
30
|
authenticated: null;
|
|
31
31
|
message: string;
|
|
32
32
|
} | {
|
|
33
|
+
message?: undefined;
|
|
33
34
|
origin: string;
|
|
34
35
|
source: "none";
|
|
35
36
|
authenticated: boolean;
|
|
36
|
-
message?: undefined;
|
|
37
37
|
} | {
|
|
38
38
|
user: {
|
|
39
39
|
id: string;
|
|
@@ -42,15 +42,15 @@ export declare function cloudLoginStatus(options: {
|
|
|
42
42
|
};
|
|
43
43
|
expiresAt: string;
|
|
44
44
|
maximumExpiresAt: string;
|
|
45
|
+
message?: undefined;
|
|
45
46
|
origin: string;
|
|
46
47
|
source: "account";
|
|
47
48
|
authenticated: boolean;
|
|
48
|
-
message?: undefined;
|
|
49
49
|
} | {
|
|
50
|
+
message?: undefined;
|
|
50
51
|
origin: string;
|
|
51
52
|
source: "account";
|
|
52
53
|
authenticated: boolean;
|
|
53
|
-
message?: undefined;
|
|
54
54
|
}>;
|
|
55
55
|
export declare function logoutOfCloud(options: {
|
|
56
56
|
origin?: string;
|
|
@@ -8,21 +8,21 @@ export declare function inspectArtifacts(options: Readonly<{
|
|
|
8
8
|
}>): {
|
|
9
9
|
mode: "runs";
|
|
10
10
|
runs: import("../../evidence/contracts.js").RunBundleSummary[];
|
|
11
|
-
runId?: undefined;
|
|
12
11
|
verification?: undefined;
|
|
12
|
+
runId?: undefined;
|
|
13
13
|
entries?: undefined;
|
|
14
14
|
} | {
|
|
15
|
+
runs?: undefined;
|
|
15
16
|
mode: "verify";
|
|
16
17
|
runId: string | null;
|
|
17
18
|
verification: import("../../evidence/contracts.js").RunBundleVerification;
|
|
18
|
-
runs?: undefined;
|
|
19
19
|
entries?: undefined;
|
|
20
20
|
} | {
|
|
21
|
+
runs?: undefined;
|
|
22
|
+
verification?: undefined;
|
|
21
23
|
mode: "artifacts";
|
|
22
24
|
runId: string | null;
|
|
23
25
|
entries: import("../../evidence/reading.js").CollectedArtifactEntry[];
|
|
24
|
-
runs?: undefined;
|
|
25
|
-
verification?: undefined;
|
|
26
26
|
};
|
|
27
27
|
export type ArtifactInspectionEntry = Extract<ReturnType<typeof inspectArtifacts>, {
|
|
28
28
|
mode: "artifacts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatEngineInvocationStack(error: unknown): string | undefined;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{sanitizeErrorMessage as M}from"../../kernel/error-serialization.js";import{redactSensitiveText as _}from"../../kernel/redaction.js";const S=6,d=12,b=4096,T=16384,c="[diagnostic limit reached]";export function formatEngineInvocationStack(n){if(!A(n))return;const f=new WeakSet,e=[],p=[];let g=0,m=0;function r(t){const o=T-c.length-m;if(o<=0)return;const a=`${e.length?`
|
|
2
|
+
`:""}${t}`;e.push(a.slice(0,o)),m+=Math.min(a.length,o)}function h(t,o,a){if(a>S||g>=d){r(`${o}${c}`);return}if(!A(t)){r(`${o}[non-Error cause omitted]`);return}if(f.has(t)){r(`${o}[error already shown]`);return}f.add(t),g+=1;const $=u(t,"cause");$!==void 0&&h($,"Caused by: ",a+1);const y=u(t,"errors");if(x(y)){const s=u(y,"length");if(typeof s=="number"){for(let i=0;i<Math.min(s,d);i+=1){if(g>=d){r(c);break}h(u(y,i.toString()),`Aggregate member ${i.toString()}: `,a+1)}s>d&&r(c)}}r(`${o}${l(t,"name")??"Error"}`);for(const s of["code","errno","syscall","path","dest"]){const i=u(t,s);typeof i=="string"?r(`${s}=${k(i)}`):typeof i=="number"&&Number.isFinite(i)&&r(`${s}=${i.toString()}`)}r(l(t,"message")??"[message unavailable]");const E=l(t,"stack");E!==void 0&&p.push(E)}h(n,"",0);for(const t of p)r(t);return e.join("")+(m>=T-c.length?c:"")}function k(n){return n.length>b?c:_(M(n))}function l(n,f){const e=u(n,f);return typeof e=="string"&&e.length>0?k(e):void 0}function u(n,f){try{const e=Object.getOwnPropertyDescriptor(n,f);return e&&"value"in e?e.value:void 0}catch{return}}function A(n){try{return n instanceof Error}catch{return!1}}function x(n){try{return Array.isArray(n)}catch{return!1}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EngineExecutionBridgeError as
|
|
1
|
+
import{EngineExecutionBridgeError as b,executeEngineTask as W}from"./engine-execution.js";import{formatError as L}from"../../kernel/error-serialization.js";import{formatEngineInvocationStack as q}from"./engine-failure-stack.js";import{DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS as P,invokeBoundedReporterCallback as j}from"./engine-execution-reporting.js";import{taskNeedsLocalRuntime as U}from"./planning.js";import{drainRuntimeFailedTasks as z}from"./runtime-failures.js";import{buildTimingObservation as J}from"./scheduler/observations.js";import{buildTaskBatch as H,claimCompatibleTaskBatch as Q,expandTaskResultOutcomes as V}from"./task-batches.js";export function createWorker(e,t){return{workerId:e,productDir:t,currentGraphKey:null,graphSwitches:0,taskCount:0}}export async function runWorker(e,t,i,r,a,u,l,h,g,d=null){const k=Date.now(),y=[],x=[];try{for(;!i.isStopRequested();){const f=l(t,e.currentGraphKey,n=>i.canAcquire(n));if(!f){const n=z(t,i);if(n.length>0){const o=Date.now(),s=new Set;for(const m of n)h(a,m.task,{status:"not_run",reason:m.reason,durationMs:0,startedAt:o,finishedAt:o,error:null,infraFailed:m.infraFailed,blockedByRuntime:m.blockedByRuntime,failureDetails:m.failureDetails}),s.has(m.graph.key)||(g(a,m.graph,m.message,o,{classification:"infra"}),s.add(m.graph.key));e.taskCount+=n.length;continue}if(t.length===0)break;await ae(10);continue}let w=null,T=[f],E=f,K=!1,O=null,B="acquire",R=[],F=null;try{T=Q(t,f),E=H(T)??f,e.currentGraphKey!==null&&e.currentGraphKey!==f.graphKey&&(e.graphSwitches+=1),e.currentGraphKey=f.graphKey,w=await i.acquire({...E,startApplicationServices:U(E)}),B="execute";const n=await W(r,w,E,i,d);B="mapping";const o=V(n);R=resolveWorkerOutcomeMappings(T,o),R.some(({outcome:s})=>s.infraFailed&&s.blockedByRuntime)&&(K=!0)}catch(n){const o=B==="acquire"?ie(n,i):te(n);O={disposition:o,error:n},K=w!==null&&o.runtimeImpact!=="none"}finally{F=await Z(i,w,K)}const c=[];let I=null;const S=()=>{if(I!==null)return I;try{I=ne(i,w,f)}catch(n){c.push(_("Runtime failure graph resolution failed",n)),I=Y(w,f)}return I};if(O===null){for(const{outcome:o,task:s}of R)await C({operationErrors:c,outcome:o,recordTaskOutcome:h,recordTiming:!0,reporter:d,reportTaskFinished:!1,task:s,timingUpdates:u,trackers:a});e.taskCount+=R.length;const n=R.filter(({outcome:o})=>o.infraFailed&&o.blockedByRuntime);if(n.length>0){const o=n.map(({outcome:s})=>s.reason??s.error??"Runtime readiness failed before engine execution").join("; ");y.push(o),await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(f,o)),await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,o)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),o,Date.now(),{classification:"infra"})})}}else{const{disposition:n,error:o}=O,s=L(o),m=X(T,o);n.status!=="cancelled"&&y.push(s),n.notifyRuntimeError&&await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(m,s)),n.status!=="cancelled"&&(n.runtimeImpact==="fail-graph"&&await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,s)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),s,Date.now(),{classification:n.classification??"product"})}));const N=Date.now();for(const D of T){const A=o instanceof b&&o.completedOutcomesByTaskId.has(String(D.id)),M=ee(D,E,o,n,s,N);await C({operationErrors:c,outcome:M,recordTaskOutcome:h,recordTiming:A,reporter:d,reportTaskFinished:!A,task:D,timingUpdates:u,trackers:a})}e.taskCount+=T.length}if(F!==null){const n=F.message;y.push(n),await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(f,n)),F.recovered||await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,n)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),n,Date.now(),{classification:"infra"})})}if(c.length>0){const n=[...c];for(const s of n)y.push(s.message);const o=n.map(s=>s.message).join("; ");await p(c,"Result graph error recording failed while reporting a Testkit operation failure",()=>{g(a,S(),o,Date.now(),{classification:"infra"})});for(const s of c.slice(n.length))y.push(s.message);c.length>n.length&&x.push(...n.map(s=>s.message),...c.slice(n.length).map(s=>s.message))}}}finally{e.currentGraphKey=null}return{workerId:e.workerId,failed:y.length>0,durationMs:Date.now()-k,taskCount:e.taskCount,graphSwitches:e.graphSwitches,errors:y,unpersistedErrors:x}}async function C({operationErrors:e,outcome:t,recordTaskOutcome:i,recordTiming:r,reporter:a,reportTaskFinished:u,task:l,timingUpdates:h,trackers:g}){await p(e,`Task outcome recording failed for ${l.file}`,()=>{i(g,l,t)}),u&&await v(e,`Task-finished reporter failed for ${l.file}`,()=>a?.taskFinished?.(l,t)),r&&await p(e,`Task timing recording failed for ${l.file}`,()=>{const d=J(l,t);d&&h.push(d)})}async function p(e,t,i){try{await i()}catch(r){e.push(_(t,r))}}async function v(e,t,i){await p(e,t,()=>j(t,i,{timeoutMs:P}))}function _(e,t){const i=G(t);return new Error(`${e}: ${i.message}`,{cause:i})}function X(e,t){const i=e[0];if(!(t instanceof b))return i;if(t.failingTaskId!==null){const r=e.find(a=>String(a.id)===t.failingTaskId);if(r!==void 0)return r}return e.find(r=>!t.completedOutcomesByTaskId.has(String(r.id)))??i}function Y(e,t){return{key:e?.graphKey??t.graphKey,targetNames:e?.targetNames??[t.targetName]}}async function Z(e,t,i){if(t===null)return null;try{return await e.release(t.leaseId,{invalidate:i}),null}catch(r){const a=G(r);try{return await e.release(t.leaseId,{invalidate:!0}),{message:`Runtime lease release failed but recovered on idempotent retry: ${a.message}`,recovered:!0}}catch(u){const l=G(u);return{message:`Runtime lease release failed: ${a.message}; idempotent retry also failed: ${l.message}`,recovered:!1}}}}function ee(e,t,i,r,a,u){const l=q(i),h={kind:"engine-invocation",key:"engine_invocation_failed",title:"Engine invocation failed",count:1,...r.classification===void 0?{}:{classification:r.classification},message:a,...l===void 0?{}:{stack:l}},g=i instanceof b?i.completedOutcomesByTaskId.get(String(e.id)):void 0;if(g!==void 0)return g;const d=i instanceof b?i.artifactReferencesByTaskId.get(String(e.id))??[]:[];return{task:e,status:r.status,error:r.status==="failed"?a:null,reason:r.status==="failed"?null:a,infraFailed:r.classification==="infra",blockedByRuntime:r.status==="not_run",durationMs:0,startedAt:u,finishedAt:u,artifacts:[...d],failureDetails:r.status==="cancelled"?[]:[h],checkDetails:[],..."batchTasks"in t?{runtimeBatch:{id:t.batchId,index:t.batchTasks.findIndex(k=>k.id===e.id&&k.file===e.file),fileCount:t.batchTasks.length,files:t.batchTasks.map(k=>k.file)}}:{}}}function te(e){return e instanceof b?e.disposition:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"none",status:"not_run"}}function ie(e,t){return t.signal.aborted&&e===t.signal.reason?{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"fail-graph",status:"not_run"}}export function resolveWorkerOutcomeMappings(e,t){const i=new Map;for(const a of e){const u=$(a);if(i.has(u))throw new Error(`Worker claimed duplicate task ${a.id.toString()} (${a.file})`);i.set(u,a)}const r=new Map;for(const a of t){const u=$(a.task),l=i.get(u);if(!l)throw new Error(`Task runner returned an outcome for unclaimed task ${a.task.id.toString()} (${a.task.file})`);if(r.has(u))throw new Error(`Task runner returned duplicate outcomes for claimed task ${l.id.toString()} (${l.file})`);r.set(u,{outcome:a,task:l})}for(const a of e)if(!r.has($(a)))throw new Error(`Task runner did not return an outcome for claimed task ${a.id.toString()} (${a.file})`);return[...r.values()]}function $(e){return JSON.stringify([typeof e.id,e.id,e.file])}function ne(e,t,i){return e.getGraph(i.graphKey)??{key:t?.graphKey??i.graphKey,targetNames:t?.targetNames??[i.targetName]}}function ae(e){return new Promise(t=>setTimeout(t,e))}function G(e){return e instanceof Error?e:new Error(String(e))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveProductDir as c}from"../../config/loader/
|
|
1
|
+
import{resolveProductDir as c}from"../../config/loader/paths.js";import u from"node:os";import{runManagedProcess as m}from"../../process/index.js";import{currentLinuxLibc as s,currentPlatformTarget as n}from"../../process/host/platform.js";import{RootPackageResolver as d}from"../../engines/installations/package-resolution.js";import{playwrightRegistryEnvironment as g,requireSupportedPlaywrightHost as f,resolvePlaywrightInstallation as h,resolvePlaywrightPackageFamily as p,resolvePlaywrightRegistry as w,throwIfPlaywrightProcessAborted as P}from"../../engines/installations/playwright.js";export const PLAYWRIGHT_SETUP_TIMEOUT_MS=1200*1e3;export class PlaywrightSetupError extends Error{code="TESTKIT_PLAYWRIGHT_SETUP_FAILED";constructor(e,t){super(`Playwright setup failed: ${e}`,t),this.name="PlaywrightSetupError"}}export function playwrightSetupArguments(r,e){return Object.freeze([r,"install","chromium","--no-shell",...e.withDeps?["--with-deps"]:[],...e.force?["--force"]:[]])}export async function executePlaywrightSetup(r){r.signal.throwIfAborted(),f({linuxLibc:s(),target:n()});const e=Object.freeze({...r.ambientEnvironment??process.env}),t=r.configuredRegistry??e.PLAYWRIGHT_BROWSERS_PATH,a=p(new d),l=w({ambientEnvironment:e,configuredValue:t,homeDirectory:u.homedir(),platform:n().platform,productRoot:r.productRoot}),o=await m({args:playwrightSetupArguments(a.cli,r),cwd:r.productRoot,displayLabel:"Playwright Chromium setup",env:g(e,l),executable:process.execPath,signal:r.signal,timeoutMs:PLAYWRIGHT_SETUP_TIMEOUT_MS}),i=y(o);if(P(r.signal,o,i),i!==null)throw new PlaywrightSetupError(i.message,{cause:i});return h({productRoot:r.productRoot,signal:r.signal},{ambientEnvironment:e,configuredRegistry:t})}function y(r){if(r.terminationError!==null)return r.terminationError;if(r.error!==null)return r.error;if(r.timedOut)return new Error(`Chromium installer exceeded ${PLAYWRIGHT_SETUP_TIMEOUT_MS.toString()} milliseconds`);if(r.cancelled)return new Error("Chromium installer was cancelled");if(r.outputLimitExceeded)return new Error("Chromium installer exceeded the managed output limit");if(r.exitCode!==0){const e=r.stderr.trim();return new Error(`Chromium installer ${r.exitCode===null?`terminated by ${String(r.exitSignal)}`:`exited with code ${r.exitCode.toString()}`}${e.length===0?"":`: ${e}`}`)}return null}export function setupPlaywright(r){return executePlaywrightSetup({...r,productRoot:c(process.cwd(),r.dir)})}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{attachErrorDiagnostics as
|
|
2
|
-
`),s}function
|
|
3
|
-
`),c}function
|
|
4
|
-
`)}`)},t=m.getParsedCommandLineOfConfigFile(e,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:n});for(const s of t?.errors??[])s.code!==18002&&s.code!==18003&&n(s);return t?.fileNames??[]}function
|
|
1
|
+
import{attachErrorDiagnostics as S}from"../../kernel/error-serialization.js";import{isPathWithin as E}from"../../process/files/paths.js";import d from"fs";import r from"path";import{createHash as w}from"crypto";import{createRequire as j}from"module";import{fileURLToPath as _}from"url";import m from"typescript";import{NODE_VITEST_PACKAGE_REQUIREMENTS as O}from"../../engines/installations/node-vitest.js";import{PLAYWRIGHT_PACKAGE_FAMILY_REQUIREMENTS as C}from"../../engines/installations/playwright.js";import{detectNextApp as A,loadDiscoveredConfigContext as $,resolveServiceCwd as R}from"../../config/loader/index.js";import{K6_POSTGRES_DRIVER_SPECIFIER as M,K6_POSTGRES_DRIVER_TYPE_FILE as I,K6_RUNTIME_GLOBAL_TYPE_FILE as F}from"../../engines/k6/authoring-type-paths.js";import{managedHostProcessInfrastructureError as N,runManagedHostProcess as D}from"../../process/index.js";import{CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS as L}from"../../steps/configured-step-testkit-modules.js";import{findPlaywrightConfigFile as G}from"../../engines/playwright/runtime/config-file.js";const U=600*1e3,y=r.resolve(r.dirname(_(import.meta.url)),"..","..",".."),b=j(r.join(y,"package.json")),K={...z(["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"]),"@gfdelarue/testkit/k6":["engines","k6","runtime","index.d.ts"],"@gfdelarue/testkit/playwright":["engines","playwright","runtime","index.d.ts"],"@gfdelarue/testkit/node-vitest/data":["engines","node-vitest","runtime","data","index.d.ts"],"@gfdelarue/testkit/node-vitest/contract":["engines","node-vitest","runtime","contract","index.d.ts"],"@gfdelarue/testkit/workspace":["app","inspect","index.d.ts"]};function z(e){return Object.fromEntries(e.map(n=>{const t=L[n],s=t[t.length-1];return[n,[...t.slice(0,-1),`${s}.d.ts`]]}))}export class TestkitTypecheckError extends Error{result;results;constructor(n,t,s){super(`testkit typecheck failed for ${n}`),this.result=t,this.results=s,S(this,{result:t,results:s})}}export async function runTestkitTypecheck(e={}){const n=ee(e.timeoutMs),{context:t,discovery:s}=await $({dir:e.dir}),o=t.productDir,i=r.join(o,".testkit","_typecheck");d.mkdirSync(i,{recursive:!0});const a=[];if(t.configFile){const p=J({productDir:o,configFile:t.configFile,outputDir:i});a.push({label:"config",cwd:o,tsconfigPath:p})}const c=s.files.map(p=>({engineId:p.engineId,path:p.path})),u=new Set(s.files.filter(p=>p.engineId==="playwright").map(p=>p.service));for(const p of t.configs){if(!u.has(p.name))continue;const k=G(R(o,p.testkit.local?.cwd));k&&c.push({engineId:"playwright",path:k})}const g=B(o,c);for(const p of g){const k=q({...p,outputDir:i,productDir:o});a.push({label:V(p.engineId,p.scopeName),cwd:p.cwd,tsconfigPath:k})}const f=[];for(const p of a){const k=await X(p,n,e.signal);if(f.push(k),!k.ok)throw new TestkitTypecheckError(p.label,k,f)}return{ok:!0,productDir:o,results:f}}function J({productDir:e,configFile:n,outputDir:t}){const s=r.join(t,"config.tsconfig.json"),o=P(e),i={...o?{extends:l(s,o)}:{},compilerOptions:buildTypecheckCompilerOptions({tsconfigPath:s,extendsPath:o,libs:["ES2022"],rootDir:l(s,e),types:["node"]}),files:[l(s,n)],include:[],exclude:[h(s,e,"node_modules"),h(s,e,"dist"),h(s,e,".testkit")]};return d.writeFileSync(s,`${JSON.stringify(i,null,2)}
|
|
2
|
+
`),s}function q({productDir:e,cwd:n,engineId:t,extendsPath:s,files:o,outputDir:i,scopeName:a}){const c=r.join(i,`${t}.${Z(a)}.tsconfig.json`),u=t==="playwright",g=u&&A(n),f={...s?{extends:l(c,s)}:{},compilerOptions:{...buildTypecheckCompilerOptions({engineId:t,tsconfigPath:c,extendsPath:s,libs:W(t),...g?{extraPaths:nextRuntimeTypePaths({tsconfigPath:c,serviceDir:n})}:{},types:Y(t)}),...u?{allowJs:!0,checkJs:!1}:{}},files:[...ie(t,c),...o.map(p=>l(c,p))],include:g?[...d.existsSync(r.join(n,"next-env.d.ts"))?[l(c,r.join(n,"next-env.d.ts"))]:[],h(c,n,"tests/playwright-fixtures/**/*.ts"),h(c,n,"tests/playwright-fixtures/**/*.tsx"),h(c,n,"tests/playwright-fixtures/**/*.mts"),h(c,n,".next/types/**/*.ts"),h(c,n,".next/dev/types/**/*.ts"),h(c,e,".next-testkit/**/dist/types/**/*.ts"),h(c,e,".next-testkit/**/dist/dev/types/**/*.ts")]:[],exclude:["node_modules",".next/cache",".next/dev"]};return d.writeFileSync(c,`${JSON.stringify(f,null,2)}
|
|
3
|
+
`),c}function B(e,n){const t=new Map,s=new Map;for(const o of n){const i=r.resolve(e,o.path),a=[o.engineId,i].join("\0");s.set(a,{...o,path:i})}for(const o of s.values()){const i=o.path,a=o.engineId==="playwright"?v(r.dirname(i),e,["tsconfig.playwright.json"]):null,c=a??v(r.dirname(i),e),u=c?r.dirname(c):e,g=Q(e,u),f=`${o.engineId}\0${c??""}\0${g}`,p=t.get(f);if(p){p.files.push(i);continue}t.set(f,{cwd:u,engineId:o.engineId,extendsPath:c,files:[i,...a?H(a):[]],scopeName:g})}return[...t.values()].map(o=>({...o,files:[...new Set(o.files)].sort((i,a)=>i.localeCompare(a))})).sort((o,i)=>T(o.engineId)-T(i.engineId)||o.scopeName.localeCompare(i.scopeName))}function H(e){const n=s=>{throw new Error(`${e}: ${m.flattenDiagnosticMessageText(s.messageText,`
|
|
4
|
+
`)}`)},t=m.getParsedCommandLineOfConfigFile(e,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:n});for(const s of t?.errors??[])s.code!==18002&&s.code!==18003&&n(s);return t?.fileNames??[]}function Y(e){switch(e){case"k6":return["k6","xk6-sql"];case"node-vitest":case"playwright":return["node"]}}function W(e){return e==="playwright"?["ES2022","DOM","DOM.Iterable"]:["ES2022"]}function T(e){return["k6","node-vitest","playwright"].indexOf(e)}function V(e,n){return n==="repo"?e:`${e}:${n}`}function Q(e,n){const t=r.relative(e,n);return t===""?"repo":t.split(r.sep).join("/")}function Z(e){const n=e.replace(/[^a-zA-Z0-9_-]+/g,"-");if(n===e)return e;const t=w("sha256").update(e).digest("hex").slice(0,12);return`${n}-${t}`}function X({label:e,cwd:n,tsconfigPath:t},s,o){const i=te(n);return D({args:[...i.args,"--noEmit","-p",t],cwd:n,displayLabel:`Testkit typecheck ${e}`,env:process.env,executable:i.command,signal:o,timeoutMs:s}).then(a=>{const c=N(`Testkit typecheck ${e}`,a);if(c)throw c;return{label:e,tsconfigPath:t,ok:a.exitCode===0,exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr}})}function ee(e){const n=e??U;if(!Number.isSafeInteger(n)||n<=0)throw new Error("Testkit typecheck timeout must be a positive safe integer in milliseconds");return n}function te(e){let n=e;for(;;){const s=r.join(n,"node_modules","typescript","bin","tsc");if(d.existsSync(s))return{command:process.execPath,args:[s]};const o=r.dirname(n);if(o===n)break;n=o}const t=r.join(y,"node_modules","typescript","bin","tsc");if(d.existsSync(t))return{command:process.execPath,args:[t]};throw new Error(`TypeScript compiler not found from ${e} upward`)}function P(e,n=["tsconfig.json","tsconfig.build.json"]){for(const t of n){const s=r.join(e,t);if(d.existsSync(s))return s}return null}function v(e,n,t){const s=r.resolve(n);let o=r.resolve(e);for(;;){if(!E(s,o))return null;const i=P(o,t);if(i)return i;if(o===s)return null;const a=r.dirname(o);if(a===o)return null;o=a}}function l(e,n){const t=r.relative(r.dirname(e),n).split(r.sep).join("/");return t.startsWith("../")||r.isAbsolute(t)?t:`./${t}`}function h(e,n,t){return r.join(l(e,n),t).split(r.sep).join("/")}function ne(e){const n={};for(const[t,s]of Object.entries(K))n[t]=[l(e,r.join(y,"dist",...s))];return n}const se=Object.freeze({packages:Object.freeze(O.filter(({authoringResolution:e})=>e==="package-exports").map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"}),oe=Object.freeze({packages:Object.freeze(C.map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"});function re(e,n){const t=ae(e);if(t===null)return{};const s={},o=l(n,r.join(y,"dist","app","typecheck","unavailable.d.ts"));for(const i of t.packages){const a=pe(i.name),c=le(i.name,a);s[`${i.name}/*`]=[o];for(const u of Object.keys(c).sort()){if(u!=="."&&!u.startsWith("./")||u.includes("*"))continue;const g=u==="."?i.name:`${i.name}${u.slice(1)}`,f=de(g,i.name,a);s[g]=[f===null?o:l(n,f)]}}return s}function ie(e,n){return e==="k6"?[l(n,r.join(y,"dist",...F))]:[]}function ce(e,n){return e==="k6"?{[M]:[l(n,r.join(y,"dist",...I))]}:{}}function ae(e){switch(e){case"node-vitest":return se;case"playwright":return oe;case"k6":case void 0:return null}}function pe(e){const n=ue(e);let t;try{t=b.resolve(`${e}/package.json`)}catch(i){throw new Error(`Testkit typecheck requires managed public package ${e}`,{cause:i})}const s=d.realpathSync.native(r.dirname(t)),o=JSON.parse(d.readFileSync(r.join(s,"package.json"),"utf8"));return requireManagedPublicPackageIdentity(o,e,n),s}export function requireManagedPublicPackageIdentity(e,n,t){if(!x(e)||e.name!==n||e.version!==t)throw new Error(`Testkit managed public package has invalid identity: expected ${n}@${t}`)}function ue(e){const n=JSON.parse(d.readFileSync(r.join(y,"package.json"),"utf8"));if(!x(n)||!x(n.dependencies))throw new Error("Testkit package has invalid dependency metadata");const t=n.dependencies[e];if(typeof t!="string"||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(t))throw new Error(`Testkit managed public package ${e} must be an exact root dependency`);return t}function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function le(e,n){const t=JSON.parse(d.readFileSync(r.join(n,"package.json"),"utf8"));if(typeof t!="object"||t===null||Array.isArray(t)||!("name"in t)||t.name!==e||!("exports"in t)||typeof t.exports!="object"||t.exports===null||Array.isArray(t.exports))throw new Error(`Testkit managed public package has invalid exports: ${e}`);return t.exports}function de(e,n,t){const s=m.resolveModuleName(e,r.join(y,"__testkit_managed_public_types__.ts"),{module:m.ModuleKind.ESNext,moduleResolution:m.ModuleResolutionKind.Bundler,resolveJsonModule:!0,target:m.ScriptTarget.ES2022},m.sys).resolvedModule;if(s===void 0)return null;const o=d.realpathSync.native(s.resolvedFileName);if(!E(t,o))throw new Error(`Managed public package type ${e} resolved outside ${n}`);return o}export function buildTypecheckCompilerOptions({engineId:e,tsconfigPath:n,extendsPath:t,rootDir:s,extraPaths:o={},libs:i,types:a}){const u={...t?me({tsconfigPath:n,extendsPath:t}):{},...o,...ne(n),...re(e,n),...ce(e,n)};return{baseUrl:null,lib:[...i],module:"ESNext",moduleResolution:"Bundler",noEmit:!0,...s?{rootDir:s}:{},target:"ES2022",typeRoots:fe(a,n),types:[...a],paths:u}}function fe(e,n){const t=new Set;for(const s of e){if(s==="k6"||s==="xk6-sql"){const c=r.join(y,"dist","engines","k6","runtime","ambient-types");if(!d.existsSync(r.join(c,s,"index.d.ts")))throw new Error(`Testkit typecheck requires bundled ${s} authoring types; rebuild the installed Testkit package`);t.add(c);continue}const o=ge(s);let i;try{i=b.resolve(`${o}/package.json`)}catch(c){throw new Error(`Testkit typecheck requires installed type package ${o}`,{cause:c})}const a=r.dirname(i);t.add(r.dirname(a))}return[...t].map(s=>l(n,s))}function ge(e){return e==="node"||e==="k6"?`@types/${e}`:e}function me({tsconfigPath:e,extendsPath:n}){const t=m.getParsedCommandLineOfConfigFile(n,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:()=>{}}),s=t?.options.paths;if(!s||Object.keys(s).length===0)return{};const o=t.options.baseUrl||(typeof t.options.pathsBasePath=="string"?t.options.pathsBasePath:r.dirname(n)),i={};for(const[a,c]of Object.entries(s))i[a]=c.map(u=>l(e,r.resolve(o,u)));return i}export function nextRuntimeTypePaths({tsconfigPath:e,serviceDir:n}){const t=he(n,[r.join("next","types.d.ts"),r.join("next","types.js")]);if(!t)return{};const s=l(e,t);return{"next/types":[s],"next/types.js":[s]}}function he(e,n){let t=r.resolve(e);for(;;){for(const o of n){const i=r.join(t,"node_modules",o);if(d.existsSync(i))return i}const s=r.dirname(t);if(s===t)return null;t=s}}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { type CommandContext as FrameworkCommandContext } from "./framework/command.js";
|
|
2
2
|
export declare const commandCatalog: Readonly<{
|
|
3
3
|
artifacts: import("./framework/command.js").CommandDefinition<{
|
|
4
|
+
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
5
|
+
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
4
6
|
readonly kind: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
5
|
-
readonly format: import("./framework/definitions.js").FlagDefinition<"
|
|
7
|
+
readonly format: import("./framework/definitions.js").FlagDefinition<"list" | "text">;
|
|
6
8
|
readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
7
9
|
readonly list: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
8
10
|
readonly verify: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
9
|
-
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
10
|
-
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
11
11
|
}, {
|
|
12
12
|
readonly file: import("./framework/definitions.js").ArgumentDefinition<string | undefined>;
|
|
13
13
|
}>;
|
|
14
14
|
cleanup: import("./framework/command.js").CommandDefinition<{
|
|
15
|
-
readonly "dry-run": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
16
|
-
readonly cache: import("./framework/definitions.js").FlagDefinition<("runtime" | "all" | "bundles")[] | undefined>;
|
|
17
|
-
readonly resources: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
18
15
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
19
16
|
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
17
|
+
readonly "dry-run": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
18
|
+
readonly cache: import("./framework/definitions.js").FlagDefinition<("all" | "bundles" | "runtime")[] | undefined>;
|
|
19
|
+
readonly resources: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
20
20
|
}, undefined>;
|
|
21
21
|
"cloud campaign create": import("./framework/command.js").CommandDefinition<{
|
|
22
22
|
readonly url: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
@@ -59,7 +59,7 @@ export declare const commandCatalog: Readonly<{
|
|
|
59
59
|
readonly "root-cause-key": import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
60
60
|
readonly "issue-reference": import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
61
61
|
readonly view: import("./framework/definitions.js").FlagDefinition<"all" | "counted" | "secondary" | undefined>;
|
|
62
|
-
readonly order: import("./framework/definitions.js").FlagDefinition<"
|
|
62
|
+
readonly order: import("./framework/definitions.js").FlagDefinition<"created" | "verified" | undefined>;
|
|
63
63
|
}, {
|
|
64
64
|
readonly resource: import("./framework/definitions.js").ArgumentDefinition<string>;
|
|
65
65
|
}>;
|
|
@@ -69,7 +69,7 @@ export declare const commandCatalog: Readonly<{
|
|
|
69
69
|
readonly project: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
70
70
|
readonly campaign: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
71
71
|
}, {
|
|
72
|
-
readonly resource: import("./framework/definitions.js").ArgumentDefinition<"
|
|
72
|
+
readonly resource: import("./framework/definitions.js").ArgumentDefinition<"account" | "campaign" | "case" | "connection" | "finding" | "organisation" | "performance" | "policy" | "project" | "project-policy" | "receipt" | "run" | "test-file">;
|
|
73
73
|
readonly id: import("./framework/definitions.js").ArgumentDefinition<string | undefined>;
|
|
74
74
|
}>;
|
|
75
75
|
"cloud project create": import("./framework/command.js").CommandDefinition<{
|
|
@@ -77,7 +77,7 @@ export declare const commandCatalog: Readonly<{
|
|
|
77
77
|
readonly org: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
78
78
|
readonly name: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
79
79
|
readonly repository: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
80
|
-
readonly provider: import("./framework/definitions.js").FlagDefinition<"
|
|
80
|
+
readonly provider: import("./framework/definitions.js").FlagDefinition<"gitea" | "github" | undefined>;
|
|
81
81
|
readonly host: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
82
82
|
readonly "publish-decisions": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
83
83
|
readonly "request-key": import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
@@ -150,24 +150,24 @@ export declare const commandCatalog: Readonly<{
|
|
|
150
150
|
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
151
151
|
}, undefined>;
|
|
152
152
|
"db schema verify": import("./framework/command.js").CommandDefinition<{
|
|
153
|
-
readonly "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
154
153
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
155
154
|
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
155
|
+
readonly "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
156
156
|
}, undefined>;
|
|
157
157
|
destroy: import("./framework/command.js").CommandDefinition<{
|
|
158
158
|
dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
159
159
|
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
160
160
|
}, undefined>;
|
|
161
161
|
discover: import("./framework/command.js").CommandDefinition<{
|
|
162
|
+
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
163
|
+
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
162
164
|
readonly type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
163
165
|
readonly suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
164
166
|
readonly file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
165
167
|
readonly "runnable-only": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
166
168
|
readonly strict: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
167
169
|
readonly output: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
168
|
-
readonly "output-mode": import("./framework/definitions.js").FlagDefinition<"
|
|
169
|
-
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
170
|
-
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
170
|
+
readonly "output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "verbose">;
|
|
171
171
|
}, undefined>;
|
|
172
172
|
doctor: import("./framework/command.js").CommandDefinition<{
|
|
173
173
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
@@ -181,19 +181,21 @@ export declare const commandCatalog: Readonly<{
|
|
|
181
181
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
182
182
|
}, undefined>;
|
|
183
183
|
"run status": import("./framework/command.js").CommandDefinition<{
|
|
184
|
-
readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
185
|
-
readonly full: import("./framework/definitions.js").FlagDefinition<boolean | undefined>;
|
|
186
184
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
187
185
|
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
186
|
+
readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
187
|
+
readonly full: import("./framework/definitions.js").FlagDefinition<boolean | undefined>;
|
|
188
188
|
}, undefined>;
|
|
189
189
|
"run stop": import("./framework/command.js").CommandDefinition<{
|
|
190
|
+
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
191
|
+
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
190
192
|
readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
191
193
|
readonly all: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
192
194
|
readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
193
|
-
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
194
|
-
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
195
195
|
}, undefined>;
|
|
196
196
|
run: import("./framework/command.js").CommandDefinition<{
|
|
197
|
+
dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
198
|
+
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
197
199
|
type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
198
200
|
suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
199
201
|
file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
@@ -203,12 +205,10 @@ export declare const commandCatalog: Readonly<{
|
|
|
203
205
|
"allow-empty": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
204
206
|
"ignore-skip-rules": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
205
207
|
"skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
206
|
-
"output-mode": import("./framework/definitions.js").FlagDefinition<"
|
|
208
|
+
"output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "debug" | "events" | undefined>;
|
|
207
209
|
debug: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
208
|
-
dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
209
|
-
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
210
210
|
}, {
|
|
211
|
-
readonly type: import("./framework/definitions.js").ArgumentDefinition<"
|
|
211
|
+
readonly type: import("./framework/definitions.js").ArgumentDefinition<"all" | "contract" | "dal" | "data" | "e2e" | "int" | "load" | "ui" | undefined>;
|
|
212
212
|
}>;
|
|
213
213
|
"setup playwright": import("./framework/command.js").CommandDefinition<{
|
|
214
214
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
@@ -220,18 +220,18 @@ export declare const commandCatalog: Readonly<{
|
|
|
220
220
|
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
221
221
|
}, undefined>;
|
|
222
222
|
stop: import("./framework/command.js").CommandDefinition<{
|
|
223
|
-
readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
224
223
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
225
224
|
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
225
|
+
readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
226
226
|
}, undefined>;
|
|
227
227
|
typecheck: import("./framework/command.js").CommandDefinition<{
|
|
228
228
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
229
229
|
}, undefined>;
|
|
230
230
|
workspace: import("./framework/command.js").CommandDefinition<{
|
|
231
|
-
readonly "target-limit": import("./framework/definitions.js").FlagDefinition<number>;
|
|
232
|
-
readonly "no-status": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
233
231
|
readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
234
232
|
readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
233
|
+
readonly "target-limit": import("./framework/definitions.js").FlagDefinition<number>;
|
|
234
|
+
readonly "no-status": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
235
235
|
}, undefined>;
|
|
236
236
|
}>;
|
|
237
237
|
export type CommandId = keyof typeof commandCatalog;
|
|
@@ -3,6 +3,8 @@ export declare const sharedFlags: {
|
|
|
3
3
|
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
4
4
|
};
|
|
5
5
|
export declare const runFlags: {
|
|
6
|
+
dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
7
|
+
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
6
8
|
type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
7
9
|
suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
8
10
|
file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
|
|
@@ -12,8 +14,6 @@ export declare const runFlags: {
|
|
|
12
14
|
"allow-empty": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
13
15
|
"ignore-skip-rules": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
14
16
|
"skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
15
|
-
"output-mode": import("./framework/definitions.js").FlagDefinition<"
|
|
17
|
+
"output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "debug" | "events" | undefined>;
|
|
16
18
|
debug: import("./framework/definitions.js").FlagDefinition<boolean>;
|
|
17
|
-
dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
18
|
-
service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
|
|
19
19
|
};
|
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
import type { CommandContext } from "../command-catalog.js";
|
|
2
2
|
export default function run({ args, flags, json, log }: CommandContext<"artifacts">): {
|
|
3
|
-
ok: boolean;
|
|
4
|
-
runs: import("../../evidence/contracts.js").RunBundleSummary[];
|
|
5
|
-
count?: undefined;
|
|
6
3
|
verification?: undefined;
|
|
7
4
|
runId?: undefined;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
runs: import("../../evidence/contracts.js").RunBundleSummary[];
|
|
8
7
|
artifacts?: undefined;
|
|
8
|
+
count?: undefined;
|
|
9
9
|
} | {
|
|
10
|
-
ok: boolean;
|
|
11
|
-
count: number;
|
|
12
10
|
runs?: undefined;
|
|
13
11
|
verification?: undefined;
|
|
14
12
|
runId?: undefined;
|
|
13
|
+
ok: boolean;
|
|
14
|
+
count: number;
|
|
15
15
|
artifacts?: undefined;
|
|
16
16
|
} | {
|
|
17
|
-
ok: boolean;
|
|
18
|
-
verification: import("../../evidence/contracts.js").RunBundleVerification;
|
|
19
17
|
runs?: undefined;
|
|
20
|
-
count?: undefined;
|
|
21
18
|
runId?: undefined;
|
|
19
|
+
ok: boolean;
|
|
20
|
+
verification: import("../../evidence/contracts.js").RunBundleVerification;
|
|
22
21
|
artifacts?: undefined;
|
|
22
|
+
count?: undefined;
|
|
23
23
|
} | {
|
|
24
|
+
runs?: undefined;
|
|
25
|
+
verification?: undefined;
|
|
24
26
|
ok: boolean;
|
|
25
27
|
runId: string | null;
|
|
26
28
|
artifacts: {
|
|
27
29
|
file: string;
|
|
28
30
|
service: string;
|
|
29
31
|
suite: {
|
|
30
|
-
engineId: "
|
|
32
|
+
engineId: "k6" | "node-vitest" | "playwright";
|
|
31
33
|
name: string;
|
|
32
|
-
profileId: "k6-
|
|
33
|
-
testType: "contract" | "
|
|
34
|
+
profileId: "k6-dal" | "k6-http" | "node-vitest-contract" | "node-vitest-data" | "playwright-ui";
|
|
35
|
+
testType: "contract" | "dal" | "data" | "e2e" | "int" | "load" | "scenario" | "ui";
|
|
34
36
|
};
|
|
35
37
|
ref: import("../../evidence/reporting-types.js").ReportingArtifactReference;
|
|
36
38
|
payload: import("../../evidence/reading.js").RunArtifactPayload | null;
|
|
37
39
|
}[];
|
|
38
|
-
runs?: undefined;
|
|
39
40
|
count?: undefined;
|
|
40
|
-
verification?: undefined;
|
|
41
41
|
} | {
|
|
42
|
-
ok: boolean;
|
|
43
|
-
runId: string | null;
|
|
44
|
-
count: number;
|
|
45
42
|
runs?: undefined;
|
|
46
43
|
verification?: undefined;
|
|
47
44
|
artifacts?: undefined;
|
|
45
|
+
ok: boolean;
|
|
46
|
+
runId: string | null;
|
|
47
|
+
count: number;
|
|
48
48
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { CommandContext } from "../command-catalog.js";
|
|
2
2
|
export default function run({ flags, json, log }: CommandContext<"cleanup">): Promise<{
|
|
3
|
-
lines: string[];
|
|
4
3
|
bundleCleaned: import("../../engines/bundle-cache.js").BundleCleanupTarget[];
|
|
5
4
|
cleaned: import("../../environment/lifecycle.js").RunManifest[];
|
|
6
5
|
dryRun: boolean;
|
|
@@ -10,4 +9,5 @@ export default function run({ flags, json, log }: CommandContext<"cleanup">): Pr
|
|
|
10
9
|
stoppedActive: import("../../environment/lifecycle.js").RunManifest[];
|
|
11
10
|
targets: import("../../app/cleanup/index.js").CleanupTargets;
|
|
12
11
|
ok: boolean;
|
|
12
|
+
lines: string[];
|
|
13
13
|
}>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { CommandContext } from "../../command-catalog.js";
|
|
2
2
|
export default function run({ flags, json, log }: CommandContext<"cloud login">): Promise<{
|
|
3
|
-
reused: boolean;
|
|
4
3
|
user: {
|
|
5
4
|
id: string;
|
|
6
5
|
email: string;
|
|
@@ -9,5 +8,6 @@ export default function run({ flags, json, log }: CommandContext<"cloud login">)
|
|
|
9
8
|
expiresAt: string;
|
|
10
9
|
maximumExpiresAt: string;
|
|
11
10
|
origin: string;
|
|
11
|
+
reused: boolean;
|
|
12
12
|
ok: boolean;
|
|
13
13
|
}>;
|
|
@@ -6,10 +6,10 @@ export default function run({ flags, json, log }: CommandContext<"cloud status">
|
|
|
6
6
|
message: string;
|
|
7
7
|
ok: boolean;
|
|
8
8
|
} | {
|
|
9
|
+
message?: undefined;
|
|
9
10
|
origin: string;
|
|
10
11
|
source: "none";
|
|
11
12
|
authenticated: boolean;
|
|
12
|
-
message?: undefined;
|
|
13
13
|
ok: boolean;
|
|
14
14
|
} | {
|
|
15
15
|
user: {
|
|
@@ -19,15 +19,15 @@ export default function run({ flags, json, log }: CommandContext<"cloud status">
|
|
|
19
19
|
};
|
|
20
20
|
expiresAt: string;
|
|
21
21
|
maximumExpiresAt: string;
|
|
22
|
+
message?: undefined;
|
|
22
23
|
origin: string;
|
|
23
24
|
source: "account";
|
|
24
25
|
authenticated: boolean;
|
|
25
|
-
message?: undefined;
|
|
26
26
|
ok: boolean;
|
|
27
27
|
} | {
|
|
28
|
+
message?: undefined;
|
|
28
29
|
origin: string;
|
|
29
30
|
source: "account";
|
|
30
31
|
authenticated: boolean;
|
|
31
|
-
message?: undefined;
|
|
32
32
|
ok: boolean;
|
|
33
33
|
}>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EngineId, RunnerProfileId } from "../../domain/identifiers.js";
|
|
2
|
+
import { type NormalizedConfigContext } from "./load.js";
|
|
2
3
|
import { type RunType } from "../../domain/test-types.js";
|
|
3
4
|
import { type PublicTestType } from "../../domain/identifiers.js";
|
|
4
5
|
import { type RuntimeIsolationPolicy as ConfigRuntimeIsolationPolicy } from "./runtime-isolation.js";
|
|
@@ -96,6 +97,10 @@ export interface DiscoverTestsOptions {
|
|
|
96
97
|
type?: null | string | readonly string[];
|
|
97
98
|
}
|
|
98
99
|
export declare function discoverTests(options?: Readonly<DiscoverTestsOptions>): Promise<DiscoveryResult>;
|
|
100
|
+
export declare function loadDiscoveredConfigContext(options?: Readonly<Pick<DiscoverTestsOptions, "dir">>): Promise<{
|
|
101
|
+
context: NormalizedConfigContext;
|
|
102
|
+
discovery: DiscoveryResult;
|
|
103
|
+
}>;
|
|
99
104
|
export declare function formatDisplayName(value: unknown): string;
|
|
100
105
|
export declare function testTypeContract(testType: DiscoveryTestType, engineId: EngineId, profileId: RunnerProfileId): DiscoveryTestContract;
|
|
101
106
|
export declare function fileDisplayName(filePath: string): string;
|