@gfdelarue/testkit 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -110
- package/dist/app/bugs/draft.js +2 -2
- package/dist/app/bugs/guide.js +1 -1
- package/dist/app/bugs/record.js +2 -2
- package/dist/app/campaigns/index.js +2 -2
- package/dist/app/destroy/index.js +1 -1
- package/dist/app/discover/index.js +2 -2
- package/dist/app/environments/static-values.js +1 -1
- package/dist/app/environments/supplied.js +1 -1
- package/dist/app/inspect/index.js +1 -1
- package/dist/app/lint/native.js +1 -1
- package/dist/app/lint/options.js +1 -1
- package/dist/app/run/engine-orchestration.js +1 -1
- package/dist/app/run/environment.js +1 -1
- package/dist/app/run/orchestrator.js +1 -1
- package/dist/app/run/request.js +1 -1
- package/dist/app/run/run-finalization.js +1 -1
- package/dist/app/run/task-batches.js +1 -1
- package/dist/app/run/worker-loop.js +1 -1
- package/dist/app/status/model.js +1 -1
- package/dist/app/status/runs.js +1 -1
- package/dist/app/typecheck/index.js +4 -4
- package/dist/cli/command-catalog.js +1 -1
- package/dist/cli/command-flags.js +1 -1
- package/dist/cli/commands/artifacts.js +2 -2
- package/dist/cli/commands/discover.js +1 -1
- package/dist/cli/commands/guard/unsafe-entrypoint.js +1 -1
- package/dist/cli/commands/run.js +2 -2
- package/dist/cli/commands/typecheck.js +1 -1
- package/dist/cli/commands/workspace.js +1 -1
- package/dist/config/authoring/database-fixture-discovery.js +1 -0
- package/dist/config/authoring/index.js +1 -1
- package/dist/config/loader/config-loader.js +1 -1
- package/dist/config/loader/decode-discovery.js +1 -1
- package/dist/config/loader/discover-tests.js +1 -1
- package/dist/config/loader/discovery.js +2 -2
- package/dist/config/loader/file-metadata.js +1 -1
- package/dist/config/loader/groups.js +2 -1
- package/dist/config/loader/load.js +1 -1
- package/dist/config/loader/managed-configs.js +1 -1
- package/dist/config/loader/owned-discovery.js +1 -1
- package/dist/config/loader/runtime-isolation.js +1 -1
- package/dist/config/loader/skip-config.js +1 -1
- package/dist/database/admin.js +2 -2
- package/dist/database/configured-steps.js +1 -1
- package/dist/domain/identifiers.js +1 -1
- package/dist/domain/retired-test-types.js +1 -1
- package/dist/domain/suite-selection.js +1 -1
- package/dist/domain/test-types.js +1 -1
- package/dist/engines/catalog.js +1 -1
- package/dist/engines/definitions.js +1 -1
- package/dist/engines/environment/index.js +1 -1
- package/dist/engines/installations/node-vitest.js +1 -1
- package/dist/engines/installations/playwright.js +1 -1
- package/dist/engines/managed-module-resolution.js +6 -2
- package/dist/engines/node-vitest/adapter/adapter.js +1 -1
- package/dist/engines/node-vitest/adapter/driver.js +2 -2
- package/dist/engines/node-vitest/adapter/evidence.js +2 -2
- package/dist/engines/node-vitest/adapter/workspace.js +8 -24
- package/dist/engines/node-vitest/inventory/index.js +2 -2
- package/dist/engines/node-vitest/inventory/list-files.js +3 -3
- package/dist/engines/node-vitest/runtime/data/index.js +1 -1
- package/dist/engines/node-vitest/runtime/data/report.js +1 -1
- package/dist/engines/node-vitest/runtime/data/scenario.js +2 -2
- package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
- package/dist/engines/playwright/adapter/adapter.js +1 -1
- package/dist/engines/playwright/adapter/config.js +2 -2
- package/dist/engines/playwright/runtime/managed-test.js +1 -0
- package/dist/environment/lifecycle.js +1 -1
- package/dist/environment/run-environment.js +1 -1
- package/dist/evidence/artifact-config.js +1 -1
- package/dist/evidence/maintenance.js +1 -0
- package/dist/evidence/read-run.js +1 -1
- package/dist/kernel/known-keys.js +1 -0
- package/dist/process/execa-bundle.json +1 -1
- package/dist/repo/fingerprint-policy.js +1 -1
- package/dist/steps/configured-step-testkit-modules.js +1 -1
- package/dist/toolchains/index.js +2 -2
- package/dist/toolchains/vitest/index.js +1 -1
- package/dist/types/config.d.ts +7 -86
- package/dist/types/environment.d.ts +6 -0
- package/dist/types/node-vitest-data.d.ts +2 -218
- package/dist/types/workspace.d.ts +27 -11
- package/docs/bug-records.md +3 -8
- package/docs/engines.md +63 -17
- package/docs/release-notes.md +2116 -0
- package/docs/test-types.md +19 -69
- package/package.json +2 -5
- package/testkit-config-schema.md +65 -128
- package/dist/app/lint/rules/data.js +0 -1
- package/dist/config/authoring/runtime.js +0 -1
- package/dist/engines/node-vitest/runtime/contract/index.js +0 -1
- package/dist/engines/node-vitest/runtime/data/http.js +0 -1
- package/dist/engines/node-vitest/runtime/data/runner.js +0 -1
- package/dist/types/node-vitest-contract.d.ts +0 -75
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isEngineId as O,isPublicTestType as U,isRunnerProfileId as x}from"../domain/identifiers.js";import{isEngineProfileIdentity as P}from"../engines/definitions.js";import{isUnknownRecord as z}from"../kernel/unknown-values.js";import{requireObjectRecord as u,requireNumber as g,requireStringArray as j,optionalBoolean as I,optionalNonNegativeNumber as y,requireUnknownArray as k,requireString as c,requireResultsReferencePath as R,optionalStringValue as o,optionalNullableStringValue as m,optionalNumberOrStringValue as _,optionalNullableNumberValue as F}from"./read-fields.js";export function readRunDocument(t,e){const n=u(t,e);if(n.schemaVersion===19)return H(n,e);if(n.schemaVersion===20)return G(n,e);throw new Error(`${e}.schemaVersion must be 19 or 20`)}function G(t,e){const n=w(t.run,`${e}.run`),i=a(t.groups,`${e}.groups`,(d,p)=>C(d,p,!0))??[];N(t,e);const s=t.summary===void 0?void 0:D(t.summary,`${e}.summary`,"group"),r=t.environment===void 0?void 0:J(t.environment,`${e}.environment`);return{...t,schemaVersion:20,...s===void 0?{}:{summary:{...s.record,files:s.files,groups:s.owners,suites:s.suites}},run:n,groups:i,...r===void 0?{}:{environment:r}}}function H(t,e){const n=w(t.run,`${e}.run`),i=a(t.services,`${e}.services`,C)??[];N(t,e);const s=t.summary===void 0?void 0:D(t.summary,`${e}.summary`,"service"),r=t.environment===void 0?void 0:K(t.environment,`${e}.environment`),d=t.logs===void 0?void 0:E(t.logs,`${e}.logs`),p=t.setup===void 0?void 0:Q(t.setup,`${e}.setup`);return{...t,schemaVersion:19,...s===void 0?{}:{summary:{...s.record,files:s.files,services:s.owners,suites:s.suites}},run:n,services:i,...r===void 0?{}:{environment:r},...d===void 0?{}:{logs:d},...p===void 0?{}:{setup:p}}}function w(t,e){const n=u(t,e);return F(n.durationMs,`${e}.durationMs`),a(n.types,`${e}.types`,c),{...n,finishedAt:m(n.finishedAt,`${e}.finishedAt`)??null,id:m(n.id,`${e}.id`)??null,startedAt:c(n.startedAt,`${e}.startedAt`),status:c(n.status,`${e}.status`)}}function N(t,e){t.archive!==void 0&&u(t.archive,`${e}.archive`),t.finalizationFailure!==void 0&&se(t.finalizationFailure,`${e}.finalizationFailure`),o(t.generatedAt,`${e}.generatedAt`)}function J(t,e){const n=u(t,e),i=n.capacity===void 0?void 0:u(n.capacity,`${e}.capacity`),s=i?.runtimeStats===void 0?void 0:k(i.runtimeStats,`${e}.capacity.runtimeStats`),r=n.logs===void 0?void 0:E(n.logs,`${e}.logs`),d=a(n.services,`${e}.services`,A),p=a(n.setupOperations,`${e}.setupOperations`,q);return{...n,...i===void 0?{}:{capacity:{...i,...s===void 0?{}:{runtimeStats:s}}},...r===void 0?{}:{logs:r},...d===void 0?{}:{services:d},...p===void 0?{}:{setupOperations:p}}}function K(t,e){const n=u(t,e),i=a(n.services,`${e}.services`,A);return{...n,...i===void 0?{}:{services:i}}}function A(t,e){const n=u(t,e);return{...n,attempts:a(n.attempts,`${e}.attempts`,(i,s)=>{const r=u(i,s);return{...r,outcome:c(r.outcome,`${s}.outcome`),port:g(r.port,`${s}.port`)}})??[],baseUrl:m(n.baseUrl,`${e}.baseUrl`)??null,port:g(n.port,`${e}.port`),readyUrl:m(n.readyUrl,`${e}.readyUrl`)??null,runtimeLabel:c(n.runtimeLabel,`${e}.runtimeLabel`),serviceName:c(n.serviceName,`${e}.serviceName`)}}function E(t,e){const n=u(t,e),i=a(n.services,`${e}.services`,ne),s=a(n.setup,`${e}.setup`,B);return{...n,...i===void 0?{}:{services:i},...s===void 0?{}:{setup:s}}}function Q(t,e){const n=u(t,e),i=a(n.operations,`${e}.operations`,q);return{...n,...i===void 0?{}:{operations:i}}}function C(t,e,n=!1){const i=u(t,e),s=a(i.suites,`${e}.suites`,(r,d)=>X(r,d,n))??[];return{...i,name:c(i.name,`${e}.name`),suites:s}}const W=Object.freeze([...["int","e2e","load","scenario"].map(t=>({engineId:"k6",profileId:"k6-http",testType:t})),{engineId:"k6",profileId:"k6-dal",testType:"dal"},{engineId:"node-vitest",profileId:"node-vitest-contract",testType:"contract"},{engineId:"node-vitest",profileId:"node-vitest-data",testType:"data"}]);function X(t,e,n){const i=u(t,e),s=W.find($=>$.testType===i.testType),r=s?.testType??(U(i.testType)?i.testType:void 0);if(r===void 0&&!(n&&i.testType===void 0))throw new Error(`${e}.testType must be a public test type`);const d=s!==void 0&&i.engineId===s.engineId?s.engineId:O(i.engineId)?i.engineId:void 0;if(d===void 0)throw new Error(`${e}.engineId must be a supported engine id`);const p=s!==void 0&&i.profileId===s.profileId?s.profileId:x(i.profileId)?i.profileId:void 0;if(p===void 0)throw new Error(`${e}.profileId must be a supported runner profile id`);if(!(s===void 0?P(i):d===s.engineId&&p===s.profileId))throw new Error(`${e}.profileId does not match ${d}/${r??"untyped"}`);const f=a(i.files,`${e}.files`,Y);return I(i.failed,`${e}.failed`),L(i.diagnostics,`${e}.diagnostics`),y(i.completedFileCount,`${e}.completedFileCount`),y(i.failedFileCount,`${e}.failedFileCount`),y(i.fileCount,`${e}.fileCount`),y(i.passedFileCount,`${e}.passedFileCount`),y(i.skippedFileCount,`${e}.skippedFileCount`),{...i,files:f,name:c(i.name,`${e}.name`),...r===void 0?{}:{testType:r},engineId:d,profileId:p}}function Y(t,e){const n=u(t,e),i=a(n.artifacts,`${e}.artifacts`,Z),s=a(n.failureDetails,`${e}.failureDetails`,l);return I(n.blockedByRuntime,`${e}.blockedByRuntime`),I(n.failed,`${e}.failed`),I(n.infraFailed,`${e}.infraFailed`),m(n.reason,`${e}.reason`),m(n.runtimeIsolation,`${e}.runtimeIsolation`),n.runtimeBatch!=null&&te(n.runtimeBatch,`${e}.runtimeBatch`),a(n.runtimeResets,`${e}.runtimeResets`,ie),{...n,error:m(n.error,`${e}.error`),artifacts:i,durationMs:F(n.durationMs,`${e}.durationMs`),failureDetails:s,path:c(n.path,`${e}.path`),status:c(n.status,`${e}.status`)}}function Z(t,e){const n=u(t,e);return{...n,contentType:m(n.contentType,`${e}.contentType`),kind:m(n.kind,`${e}.kind`),summary:m(n.summary,`${e}.summary`),name:c(n.name,`${e}.name`),path:R(n.path,`${e}.path`)}}function l(t,e){const n=u(t,e),i=n.request===void 0?void 0:b(n.request,`${e}.request`),s=n.response===void 0?void 0:ee(n.response,`${e}.response`),r=n.location===void 0?void 0:u(n.location,`${e}.location`);return r!==void 0&&(o(r.path,`${e}.location.path`),r.line!==void 0&&g(r.line,`${e}.location.line`),r.column!==void 0&&g(r.column,`${e}.location.column`)),{...n,key:o(n.key,`${e}.key`),kind:o(n.kind,`${e}.kind`),message:o(n.message,`${e}.message`),stack:o(n.stack,`${e}.stack`),location:r,request:i,response:s,title:c(n.title,`${e}.title`)}}function b(t,e){const n=u(t,e);return{...n,method:o(n.method,`${e}.method`),path:o(n.path,`${e}.path`),requestId:o(n.requestId,`${e}.requestId`)}}function ee(t,e){const n=u(t,e);return{...n,bodyPreview:o(n.bodyPreview,`${e}.bodyPreview`),contentType:o(n.contentType,`${e}.contentType`),status:_(n.status,`${e}.status`)}}function ne(t,e){const n=u(t,e);return{...n,path:R(n.path,`${e}.path`),runtimeLabel:c(n.runtimeLabel,`${e}.runtimeLabel`),serviceName:c(n.serviceName,`${e}.serviceName`)}}function q(t,e){const n=u(t,e),i=n.logRef==null?n.logRef:B(n.logRef,`${e}.logRef`);return{...n,durationMs:F(n.durationMs,`${e}.durationMs`),error:m(n.error,`${e}.error`),summary:m(n.summary,`${e}.summary`),logRef:i,serviceName:c(n.serviceName,`${e}.serviceName`),stage:c(n.stage,`${e}.stage`),startedAt:o(n.startedAt,`${e}.startedAt`),status:c(n.status,`${e}.status`)}}function B(t,e){const n=u(t,e);return o(n.runtimeLabel,`${e}.runtimeLabel`),o(n.serviceName,`${e}.serviceName`),o(n.stage,`${e}.stage`),{...n,path:R(n.path,`${e}.path`)}}function D(t,e,n){const i=u(t,e),s=n==="group"?"groups":"services",r=$=>i[$]===void 0?{}:u(i[$],`${e}.${$}`),[d,p,h]=[r("files"),r(s),r("suites")],f=($,T,M)=>{const v=$[T];if(v===void 0)return 0;if(typeof v!="number"||!Number.isFinite(v)||v<0)throw new Error(`${e}.${M}.${T} must be a non-negative finite number`);return v};return L(i.diagnostics,`${e}.diagnostics`),{record:i,files:{blockedByRuntime:f(d,"blockedByRuntime","files"),cancelled:f(d,"cancelled","files"),failed:f(d,"failed","files"),infraFailed:f(d,"infraFailed","files"),interrupted:f(d,"interrupted","files"),notRun:f(d,"notRun","files"),passed:f(d,"passed","files"),skipped:f(d,"skipped","files"),total:f(d,"total","files")},owners:{blockedByRuntime:f(p,"blockedByRuntime",s),failed:f(p,"failed",s),infraFailed:f(p,"infraFailed",s),passed:f(p,"passed",s),skipped:f(p,"skipped",s),total:f(p,"total",s)},suites:{completed:f(h,"completed","suites"),failed:f(h,"failed","suites"),passed:f(h,"passed","suites"),skipped:f(h,"skipped","suites"),total:f(h,"total","suites")}}}function L(t,e){if(t!==void 0)return k(t,e).map((n,i)=>{const s=`${e}[${String(i)}]`,r=u(n,s);return{...r,code:c(r.code,`${s}.code`),group:o(r.group,`${s}.group`),message:c(r.message,`${s}.message`),service:o(r.service,`${s}.service`),suite:o(r.suite,`${s}.suite`)}})}function te(t,e){const n=u(t,e);return{...n,id:o(n.id,`${e}.id`),fileCount:y(n.fileCount,`${e}.fileCount`),index:y(n.index,`${e}.index`),files:n.files===void 0?void 0:j(n.files,`${e}.files`)}}function ie(t,e){const n=u(t,e);return{...n,position:o(n.position,`${e}.position`),reason:o(n.reason,`${e}.reason`),runtimeIsolation:o(n.runtimeIsolation,`${e}.runtimeIsolation`),trigger:o(n.trigger,`${e}.trigger`)}}function se(t,e){const n=u(t,e),i=n.operation===void 0?void 0:u(n.operation,`${e}.operation`);return{...n,name:c(n.name,`${e}.name`),message:c(n.message,`${e}.message`),code:o(n.code,`${e}.code`),stack:o(n.stack,`${e}.stack`),phase:o(n.phase,`${e}.phase`),exitCode:n.exitCode===void 0?void 0:g(n.exitCode,`${e}.exitCode`),status:n.status===void 0?void 0:g(n.status,`${e}.status`),diagnostics:n.diagnostics===void 0?void 0:S(n.diagnostics,`${e}.diagnostics`),operation:i===void 0?void 0:{...i,id:o(i.id,`${e}.operation.id`),source:c(i.source,`${e}.operation.source`),name:c(i.name,`${e}.operation.name`),kind:c(i.kind,`${e}.operation.kind`),summary:o(i.summary,`${e}.operation.summary`),status:o(i.status,`${e}.operation.status`),error:o(i.error,`${e}.operation.error`),scope:S(i.scope,`${e}.operation.scope`)}}}function S(t,e){return Object.fromEntries(Object.entries(u(t,e)).map(([n,i])=>[n,V(i,`${e}.${n}`)]))}function V(t,e){return t===null||typeof t=="string"||typeof t=="boolean"?t:Array.isArray(t)?k(t,e).map((n,i)=>V(n,`${e}[${String(i)}]`)):z(t)?S(t,e):g(t,e)}function a(t,e,n){return t===void 0?void 0:k(t,e).map((i,s)=>n(i,`${e}[${String(s)}]`))}
|
|
1
|
+
import{isEngineId as M,isPublicTestType as O,isRunnerProfileId as U}from"../domain/identifiers.js";import{isEngineProfileIdentity as P}from"../engines/definitions.js";import{isUnknownRecord as z}from"../kernel/unknown-values.js";import{requireObjectRecord as u,requireNumber as g,requireStringArray as j,optionalBoolean as I,optionalNonNegativeNumber as y,requireUnknownArray as k,requireString as c,requireResultsReferencePath as R,optionalStringValue as o,optionalNullableStringValue as m,optionalNumberOrStringValue as _,optionalNullableNumberValue as F}from"./read-fields.js";export function readRunDocument(t,e){const n=u(t,e);if(n.schemaVersion===19)return H(n,e);if(n.schemaVersion===20)return G(n,e);throw new Error(`${e}.schemaVersion must be 19 or 20`)}function G(t,e){const n=w(t.run,`${e}.run`),i=a(t.groups,`${e}.groups`,(d,p)=>C(d,p,!0))??[];N(t,e);const s=t.summary===void 0?void 0:D(t.summary,`${e}.summary`,"group"),r=t.environment===void 0?void 0:J(t.environment,`${e}.environment`);return{...t,schemaVersion:20,...s===void 0?{}:{summary:{...s.record,files:s.files,groups:s.owners,suites:s.suites}},run:n,groups:i,...r===void 0?{}:{environment:r}}}function H(t,e){const n=w(t.run,`${e}.run`),i=a(t.services,`${e}.services`,C)??[];N(t,e);const s=t.summary===void 0?void 0:D(t.summary,`${e}.summary`,"service"),r=t.environment===void 0?void 0:K(t.environment,`${e}.environment`),d=t.logs===void 0?void 0:E(t.logs,`${e}.logs`),p=t.setup===void 0?void 0:Q(t.setup,`${e}.setup`);return{...t,schemaVersion:19,...s===void 0?{}:{summary:{...s.record,files:s.files,services:s.owners,suites:s.suites}},run:n,services:i,...r===void 0?{}:{environment:r},...d===void 0?{}:{logs:d},...p===void 0?{}:{setup:p}}}function w(t,e){const n=u(t,e);return F(n.durationMs,`${e}.durationMs`),a(n.types,`${e}.types`,c),{...n,finishedAt:m(n.finishedAt,`${e}.finishedAt`)??null,id:m(n.id,`${e}.id`)??null,startedAt:c(n.startedAt,`${e}.startedAt`),status:c(n.status,`${e}.status`)}}function N(t,e){t.archive!==void 0&&u(t.archive,`${e}.archive`),t.finalizationFailure!==void 0&&ie(t.finalizationFailure,`${e}.finalizationFailure`),o(t.generatedAt,`${e}.generatedAt`)}function J(t,e){const n=u(t,e),i=n.capacity===void 0?void 0:u(n.capacity,`${e}.capacity`),s=i?.runtimeStats===void 0?void 0:k(i.runtimeStats,`${e}.capacity.runtimeStats`),r=n.logs===void 0?void 0:E(n.logs,`${e}.logs`),d=a(n.services,`${e}.services`,A),p=a(n.setupOperations,`${e}.setupOperations`,q);return{...n,...i===void 0?{}:{capacity:{...i,...s===void 0?{}:{runtimeStats:s}}},...r===void 0?{}:{logs:r},...d===void 0?{}:{services:d},...p===void 0?{}:{setupOperations:p}}}function K(t,e){const n=u(t,e),i=a(n.services,`${e}.services`,A);return{...n,...i===void 0?{}:{services:i}}}function A(t,e){const n=u(t,e);return{...n,attempts:a(n.attempts,`${e}.attempts`,(i,s)=>{const r=u(i,s);return{...r,outcome:c(r.outcome,`${s}.outcome`),port:g(r.port,`${s}.port`)}})??[],baseUrl:m(n.baseUrl,`${e}.baseUrl`)??null,port:g(n.port,`${e}.port`),readyUrl:m(n.readyUrl,`${e}.readyUrl`)??null,runtimeLabel:c(n.runtimeLabel,`${e}.runtimeLabel`),serviceName:c(n.serviceName,`${e}.serviceName`)}}function E(t,e){const n=u(t,e),i=a(n.services,`${e}.services`,ee),s=a(n.setup,`${e}.setup`,B);return{...n,...i===void 0?{}:{services:i},...s===void 0?{}:{setup:s}}}function Q(t,e){const n=u(t,e),i=a(n.operations,`${e}.operations`,q);return{...n,...i===void 0?{}:{operations:i}}}function C(t,e,n=!1){const i=u(t,e),s=a(i.suites,`${e}.suites`,(r,d)=>W(r,d,n))??[];return{...i,name:c(i.name,`${e}.name`),suites:s}}export const RETIRED_SUITE_IDENTITIES=Object.freeze([...["int","e2e","load","scenario"].map(t=>({engineId:"k6",profileId:"k6-http",testType:t})),{engineId:"k6",profileId:"k6-dal",testType:"dal"},{engineId:"node-vitest",profileId:"node-vitest-contract",testType:"contract"},{engineId:"node-vitest",profileId:"node-vitest-data",testType:"data"}]);function W(t,e,n){const i=u(t,e),s=RETIRED_SUITE_IDENTITIES.find($=>$.testType===i.testType),r=s?.testType??(O(i.testType)?i.testType:void 0);if(r===void 0&&!(n&&i.testType===void 0))throw new Error(`${e}.testType must be a public test type`);const d=s!==void 0&&i.engineId===s.engineId?s.engineId:M(i.engineId)?i.engineId:void 0;if(d===void 0)throw new Error(`${e}.engineId must be a supported engine id`);const p=s!==void 0&&i.profileId===s.profileId?s.profileId:U(i.profileId)?i.profileId:void 0;if(p===void 0)throw new Error(`${e}.profileId must be a supported runner profile id`);if(!(s===void 0?P(i):d===s.engineId&&p===s.profileId))throw new Error(`${e}.profileId does not match ${d}/${r??"untyped"}`);const f=a(i.files,`${e}.files`,X);return I(i.failed,`${e}.failed`),L(i.diagnostics,`${e}.diagnostics`),y(i.completedFileCount,`${e}.completedFileCount`),y(i.failedFileCount,`${e}.failedFileCount`),y(i.fileCount,`${e}.fileCount`),y(i.passedFileCount,`${e}.passedFileCount`),y(i.skippedFileCount,`${e}.skippedFileCount`),{...i,files:f,name:c(i.name,`${e}.name`),...r===void 0?{}:{testType:r},engineId:d,profileId:p}}function X(t,e){const n=u(t,e),i=a(n.artifacts,`${e}.artifacts`,Y),s=a(n.failureDetails,`${e}.failureDetails`,Z);return I(n.blockedByRuntime,`${e}.blockedByRuntime`),I(n.failed,`${e}.failed`),I(n.infraFailed,`${e}.infraFailed`),m(n.reason,`${e}.reason`),m(n.runtimeIsolation,`${e}.runtimeIsolation`),n.runtimeBatch!=null&&ne(n.runtimeBatch,`${e}.runtimeBatch`),a(n.runtimeResets,`${e}.runtimeResets`,te),{...n,error:m(n.error,`${e}.error`),artifacts:i,durationMs:F(n.durationMs,`${e}.durationMs`),failureDetails:s,path:c(n.path,`${e}.path`),status:c(n.status,`${e}.status`)}}function Y(t,e){const n=u(t,e);return{...n,contentType:m(n.contentType,`${e}.contentType`),kind:m(n.kind,`${e}.kind`),summary:m(n.summary,`${e}.summary`),name:c(n.name,`${e}.name`),path:R(n.path,`${e}.path`)}}function Z(t,e){const n=u(t,e),i=n.request===void 0?void 0:l(n.request,`${e}.request`),s=n.response===void 0?void 0:b(n.response,`${e}.response`),r=n.location===void 0?void 0:u(n.location,`${e}.location`);return r!==void 0&&(o(r.path,`${e}.location.path`),r.line!==void 0&&g(r.line,`${e}.location.line`),r.column!==void 0&&g(r.column,`${e}.location.column`)),{...n,key:o(n.key,`${e}.key`),kind:o(n.kind,`${e}.kind`),message:o(n.message,`${e}.message`),stack:o(n.stack,`${e}.stack`),location:r,request:i,response:s,title:c(n.title,`${e}.title`)}}function l(t,e){const n=u(t,e);return{...n,method:o(n.method,`${e}.method`),path:o(n.path,`${e}.path`),requestId:o(n.requestId,`${e}.requestId`)}}function b(t,e){const n=u(t,e);return{...n,bodyPreview:o(n.bodyPreview,`${e}.bodyPreview`),contentType:o(n.contentType,`${e}.contentType`),status:_(n.status,`${e}.status`)}}function ee(t,e){const n=u(t,e);return{...n,path:R(n.path,`${e}.path`),runtimeLabel:c(n.runtimeLabel,`${e}.runtimeLabel`),serviceName:c(n.serviceName,`${e}.serviceName`)}}function q(t,e){const n=u(t,e),i=n.logRef==null?n.logRef:B(n.logRef,`${e}.logRef`);return{...n,durationMs:F(n.durationMs,`${e}.durationMs`),error:m(n.error,`${e}.error`),summary:m(n.summary,`${e}.summary`),logRef:i,serviceName:c(n.serviceName,`${e}.serviceName`),stage:c(n.stage,`${e}.stage`),startedAt:o(n.startedAt,`${e}.startedAt`),status:c(n.status,`${e}.status`)}}function B(t,e){const n=u(t,e);return o(n.runtimeLabel,`${e}.runtimeLabel`),o(n.serviceName,`${e}.serviceName`),o(n.stage,`${e}.stage`),{...n,path:R(n.path,`${e}.path`)}}function D(t,e,n){const i=u(t,e),s=n==="group"?"groups":"services",r=$=>i[$]===void 0?{}:u(i[$],`${e}.${$}`),[d,p,h]=[r("files"),r(s),r("suites")],f=($,T,x)=>{const v=$[T];if(v===void 0)return 0;if(typeof v!="number"||!Number.isFinite(v)||v<0)throw new Error(`${e}.${x}.${T} must be a non-negative finite number`);return v};return L(i.diagnostics,`${e}.diagnostics`),{record:i,files:{blockedByRuntime:f(d,"blockedByRuntime","files"),cancelled:f(d,"cancelled","files"),failed:f(d,"failed","files"),infraFailed:f(d,"infraFailed","files"),interrupted:f(d,"interrupted","files"),notRun:f(d,"notRun","files"),passed:f(d,"passed","files"),skipped:f(d,"skipped","files"),total:f(d,"total","files")},owners:{blockedByRuntime:f(p,"blockedByRuntime",s),failed:f(p,"failed",s),infraFailed:f(p,"infraFailed",s),passed:f(p,"passed",s),skipped:f(p,"skipped",s),total:f(p,"total",s)},suites:{completed:f(h,"completed","suites"),failed:f(h,"failed","suites"),passed:f(h,"passed","suites"),skipped:f(h,"skipped","suites"),total:f(h,"total","suites")}}}function L(t,e){if(t!==void 0)return k(t,e).map((n,i)=>{const s=`${e}[${String(i)}]`,r=u(n,s);return{...r,code:c(r.code,`${s}.code`),group:o(r.group,`${s}.group`),message:c(r.message,`${s}.message`),service:o(r.service,`${s}.service`),suite:o(r.suite,`${s}.suite`)}})}function ne(t,e){const n=u(t,e);return{...n,id:o(n.id,`${e}.id`),fileCount:y(n.fileCount,`${e}.fileCount`),index:y(n.index,`${e}.index`),files:n.files===void 0?void 0:j(n.files,`${e}.files`)}}function te(t,e){const n=u(t,e);return{...n,position:o(n.position,`${e}.position`),reason:o(n.reason,`${e}.reason`),runtimeIsolation:o(n.runtimeIsolation,`${e}.runtimeIsolation`),trigger:o(n.trigger,`${e}.trigger`)}}function ie(t,e){const n=u(t,e),i=n.operation===void 0?void 0:u(n.operation,`${e}.operation`);return{...n,name:c(n.name,`${e}.name`),message:c(n.message,`${e}.message`),code:o(n.code,`${e}.code`),stack:o(n.stack,`${e}.stack`),phase:o(n.phase,`${e}.phase`),exitCode:n.exitCode===void 0?void 0:g(n.exitCode,`${e}.exitCode`),status:n.status===void 0?void 0:g(n.status,`${e}.status`),diagnostics:n.diagnostics===void 0?void 0:S(n.diagnostics,`${e}.diagnostics`),operation:i===void 0?void 0:{...i,id:o(i.id,`${e}.operation.id`),source:c(i.source,`${e}.operation.source`),name:c(i.name,`${e}.operation.name`),kind:c(i.kind,`${e}.operation.kind`),summary:o(i.summary,`${e}.operation.summary`),status:o(i.status,`${e}.operation.status`),error:o(i.error,`${e}.operation.error`),scope:S(i.scope,`${e}.operation.scope`)}}}function S(t,e){return Object.fromEntries(Object.entries(u(t,e)).map(([n,i])=>[n,V(i,`${e}.${n}`)]))}function V(t,e){return t===null||typeof t=="string"||typeof t=="boolean"?t:Array.isArray(t)?k(t,e).map((n,i)=>V(n,`${e}[${String(i)}]`)):z(t)?S(t,e):g(t,e)}function a(t,e,n){return t===void 0?void 0:k(t,e).map((i,s)=>n(i,`${e}[${String(s)}]`))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function unknownKeysMessage(r,e,s){const n=Object.keys(r).filter(t=>!e.includes(t));if(n.length===0)return null;const o=n.map(t=>{const l=c(t,e);return l===null?JSON.stringify(t):`${JSON.stringify(t)} (mispelled ${JSON.stringify(l)}?)`});return`${s} has unknown ${n.length===1?"key":"keys"} ${o.join(", ")}; it accepts ${e.join(", ")}`}export function rejectUnknownKeys(r,e,s){const n=unknownKeysMessage(r,e,s);if(n!==null)throw new Error(n)}function c(r,e){let s=null,n=Math.max(1,Math.floor(r.length/3))+1;for(const o of e){const t=i(r.toLowerCase(),o.toLowerCase());t<n&&(s=o,n=t)}return s}function i(r,e){let s=Array.from({length:e.length+1},(n,o)=>o);for(let n=0;n<r.length;n+=1){const o=[n+1];for(let t=0;t<e.length;t+=1){const l=r.charCodeAt(n)===e.charCodeAt(t)?0:1;o.push(Math.min((s[t+1]??0)+1,(o[t]??0)+1,(s[t]??0)+l))}s=o}return s[e.length]??0}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"entrypoint": "dist/process/process.js",
|
|
4
4
|
"sourceSha256": "6607c0273f046a00eb72ed4a0cac0f9b1c54d638be535b11188e1c8e20cdea67",
|
|
5
5
|
"bundleSha256": "6ce5a9db43a95cc11dd3f265a67cbad9bd4c492ea2f33187c6c2474150ce16df",
|
|
6
|
-
"packageLockSha256": "
|
|
6
|
+
"packageLockSha256": "d04d8e8ba948c50a5890e5ed3a9ac8885c1f197d493bb9e615afd0948c84985e",
|
|
7
7
|
"esbuildVersion": "0.28.1",
|
|
8
8
|
"options": {
|
|
9
9
|
"format": "esm",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import x from"fs";import f from"path";import{physicalNodeMode as u,readPhysicalDirectoryEntries as y,readPhysicalNode as b}from"./physical-tree.js";import{rejectUnknownKeys as w}from"../kernel/known-keys.js";import{isUnknownArray as $,isUnknownRecord as E}from"../kernel/unknown-values.js";const z=[".testkit",".next-testkit"],l={exclude:[],include:[]};export function normalizeFingerprintPolicy(t={}){if(t==null)return{exclude:[],include:[]};if(!E(t))throw new Error("testkit.config.ts fingerprints must be an object");return w(t,["exclude","include"],"testkit.config.ts fingerprints"),{exclude:m(t.exclude,"fingerprints.exclude"),include:m(t.include,"fingerprints.include")}}export function shouldIgnoreCanonicalFingerprintPath(t,n=l){return shouldIgnoreCanonicalFingerprintPathAtPrefix(t,"",n)}export function shouldIgnoreCanonicalFingerprintPathAtPrefix(t,n,e=l){const r=normalizeCanonicalRelativePath(t),i=g(n,r);return!i||d(i,e.include)?!1:T(r)?!0:d(i,e.exclude)}export function hasIncludedFingerprintDescendantAtPrefix(t,n,e){const r=g(n,t);if(!r)return e.include.length>0;const i=`${r}/`;return e.include.some(c=>{const o=normalizeCanonicalRelativePath(c);if(o.includes("*")){const a=S(o);return a.length===0||r.startsWith(a)||a.startsWith(i)}return h(o).startsWith(i)})}export function appendFingerprintPathToHash(t,n,e,r=l){const i=normalizeRelativePath(n,e),c=x.realpathSync.native(f.resolve(n));P(t,c,i,r)}export function normalizeRelativePath(t,n){const e=f.isAbsolute(n)?f.relative(t,n):n;return f.isAbsolute(n)?normalizeCanonicalRelativePath(e.split(f.sep).join("/")):normalizePath(e)}export function normalizePath(t){return t.split(f.sep).join("/").replace(/\\/g,"/").replace(/^\.\/+/,"").replace(/\/+$/,"")}function m(t,n){if(t==null)return[];if(!$(t))throw new Error(`testkit.config.ts ${n} must be an array of paths`);return t.map((e,r)=>{if(typeof e!="string")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a string path`);const i=normalizeCanonicalRelativePath(e.trim());if(!i)throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a non-empty path`);if(L(i))throw new Error(`testkit.config.ts ${n}[${String(r)}] must use "/" as the path separator; a literal backslash is written doubled`);if(i.startsWith("/")||/^[a-z]:\//iu.test(i)||i.startsWith("../")||i==="..")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be relative to the product directory`);return i})}function d(t,n){return n.some(e=>I(t,e))}function T(t){return d(t,z)}function I(t,n){const e=normalizeCanonicalRelativePath(t),r=normalizeCanonicalRelativePath(n);if(!r)return!1;const i=h(r);if(e===i||e.startsWith(`${i}/`))return!0;if(!r.includes("*"))return!1;const c=W(r);let o=e;for(;o;){if(c.test(o))return!0;const a=o.lastIndexOf("/");if(a<0)break;o=o.slice(0,a)}return!1}export function normalizeCanonicalRelativePath(t){return t.replace(/^\.\/+/,"").replace(/\/+$/,"")}function L(t){for(let n=0;n<t.length;n+=1)if(t[n]==="\\"){if(t[n+1]!=="\\")return!0;n+=1}return!1}function h(t){return t.replace(/\\\\/g,"\\")}function S(t){let n="";for(let e=0;e<t.length;e+=1){const r=t[e];if(r==="*")break;r==="\\"&&t[e+1]==="\\"?(n+="\\",e+=1):n+=r}return n}function P(t,n,e,r){const i=b(n,e),c=shouldIgnoreCanonicalFingerprintPath(e,r);if(!(c&&(i.kind!=="directory"||!hasIncludedFingerprintDescendantAtPrefix(e,"",r)))&&(c||R(t,e,i),i.kind==="directory"))for(const o of y(n,e))P(t,n,g(e,o),r)}function R(t,n,e){switch(t.update("node\0"),s(t,"path",n),s(t,"kind",e.kind),e.kind){case"file":s(t,"mode",u(e.mode)),p(t,"contents",e.contents);break;case"directory":s(t,"mode",u(e.mode));break;case"symlink":case"ancestor-symlink":"obstaclePath"in e&&s(t,"obstacle",e.obstaclePath),p(t,"target",e.target);break;case"ancestor-missing":s(t,"obstacle",e.obstaclePath);break;case"ancestor-non-directory":s(t,"obstacle",e.obstaclePath),s(t,"mode",u(e.mode));break;case"missing":break}}function s(t,n,e){p(t,n,Buffer.from(e))}function p(t,n,e){t.update(`${n}\0${e.byteLength.toString()}\0`),t.update(e),t.update("\0")}function g(t,n){const e=normalizeCanonicalRelativePath(t),r=normalizeCanonicalRelativePath(n);return e?r?`${e}/${r}`:e:r}function W(t){let n="^";for(let e=0;e<t.length;e+=1){const r=t[e],i=t[e+1];r==="\\"&&i==="\\"?(n+=k("\\"),e+=1):r==="*"&&i==="*"?(n+=".*",e+=1):r==="*"?n+="[^/]*":n+=k(r)}return n+="$",new RegExp(n)}function k(t){return t.replace(/[\\^$+?.()|[\]{}]/g,"\\$&")}export function appendFileToHash(t,n,e,r={}){appendFingerprintPathToHash(t,n,e,normalizeFingerprintPolicy(r))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS=["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"];const n=new Set(["@gfdelarue/testkit/environment","@gfdelarue/testkit/node-vitest/
|
|
1
|
+
export const CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS=["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"];const n=new Set(["@gfdelarue/testkit/environment","@gfdelarue/testkit/node-vitest/data","@gfdelarue/testkit/playwright"]);export const CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS={"@gfdelarue/testkit":["index"],"@gfdelarue/testkit/config":["config","authoring","index"],"@gfdelarue/testkit/config/build-assets":["config","runtime","build-assets"],"@gfdelarue/testkit/config/database-steps":["database","steps"],"@gfdelarue/testkit/config/next-runtime-tsconfig":["config","runtime","next-runtime-tsconfig"],"@gfdelarue/testkit/drizzle":["database","drizzle","index"],"@gfdelarue/testkit/env":["config","runtime","env","index"],"@gfdelarue/testkit/tooling/vitest":["toolchains","vitest","index"]};export function isTestkitPackageSpecifier(t){return t==="@gfdelarue/testkit"||t.startsWith("@gfdelarue/testkit/")}export function requireConfiguredStepTestkitModuleSpecifier(t){if(n.has(t))throw new Error(`Configured lifecycle modules run in Node and may not import engine authoring module ${JSON.stringify(t)}`);const e=CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS.find(i=>i===t);if(!e)throw new Error(`Unsupported configured Testkit module specifier ${JSON.stringify(t)}`);return e}
|
package/dist/toolchains/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _ from"crypto";import h from"fs";import m from"path";import{prepareCommandForSpawn as I,resolveCommandForSpawn as A}from"../process/host/platform.js";import{normalizeContainedRelativePath as
|
|
2
|
-
`),v=new WeakMap,y=new WeakSet;export function normalizeToolchainRegistry(n){if(n==null)return{};if(!N(n))throw new Error("testkit.config.ts toolchains must be an object");const e={};for(const[o,r]of Object.entries(n))e[o]=x(r,`testkit.config.ts toolchains.${o}`);return e}export function normalizeRuntimeToolchain(n,e,o={}){if(n==null)return null;if(typeof n=="string"){const t=n.trim();if(!t)throw new Error(`${e} must reference a non-empty toolchain name`);const i=o[t];if(!i)throw new Error(`${e} references unknown toolchain "${t}"`);return{...i,refName:t,sourceLabel:`${e} -> ${t}`}}return{...x(n,e),refName:null,sourceLabel:e}}export async function resolveConfiguredToolchain(n,e={}){const o=n?.testkit?.runtime?.toolchain;if(!n||!o)return null;let r=v.get(n);if(r===void 0){r=P(i=>J(n,o,{...e,signal:i})),v.set(n,r);const t=r;r.promise.catch(()=>{v.get(n)===t&&v.delete(n)})}return R(r,e.signal)}export function announceResolvedToolchain(n,e,o=null){return!e||y.has(n)||(y.add(n),o?.toolchainResolved&&o.toolchainResolved({serviceName:n.name,runtimeLabel:n.runtimeLabel||n.name},e.summary)),Promise.resolve()}export function applyToolchainEnv(n,e,o=process.env){if(!e)return{...n};const r={...n,PATH:
|
|
1
|
+
import _ from"crypto";import h from"fs";import m from"path";import{prepareCommandForSpawn as I,resolveCommandForSpawn as A}from"../process/host/platform.js";import{normalizeContainedRelativePath as k,resolveContainedPath as V}from"../process/files/contained-path.js";import{deriveSemverMinimum as D,isExactSemver as L,normalizeSemver as f,satisfiesSemver as g}from"./semver.js";import{managedHostProcessInfrastructureError as M,runManagedHostProcess as j}from"../process/index.js";import{managedNodeRelease as H}from"./managed-node-releases.js";import{createSharedToolchainOperation as P,waitForSharedToolchainOperation as R}from"./shared-operation.js";import{TOOLCHAIN_METADATA_TIMEOUT_MS as O}from"./timeouts.js";import{rejectUnknownKeys as F}from"../kernel/known-keys.js";import{isUnknownRecord as N,normalizeOptionalString as l}from"../kernel/unknown-values.js";import{readJsonFileOrNull as W}from"../process/files/json-file.js";const z=".",q="auto",U="require-host",B=600*1e3,K=['"use strict";','const { spawn } = require("node:child_process");',"const [command, ...args] = process.argv.slice(1);",'if (typeof command !== "string" || command.length === 0) {',' process.stderr.write("Missing Windows toolchain command\\n");'," process.exitCode = 126;","} else {"," let spawnFailed = false;"," const child = spawn(command, args, {"," shell: false,",' stdio: "inherit",'," windowsHide: true,"," windowsVerbatimArguments: true,"," });",' child.once("error", (error) => {'," spawnFailed = true;"," process.stderr.write(`${error.stack ?? String(error)}\\n`);"," process.exitCode = 126;"," });",' child.once("close", (code, signal) => {'," if (spawnFailed) return;"," if (signal !== null) {"," process.stderr.write(`Windows toolchain command exited on signal ${signal}\\n`);"," process.exitCode = 1;"," return;"," }"," process.exitCode = code ?? 1;"," });","}"].join(`
|
|
2
|
+
`),v=new WeakMap,y=new WeakSet;export function normalizeToolchainRegistry(n){if(n==null)return{};if(!N(n))throw new Error("testkit.config.ts toolchains must be an object");const e={};for(const[o,r]of Object.entries(n))e[o]=x(r,`testkit.config.ts toolchains.${o}`);return e}export function normalizeRuntimeToolchain(n,e,o={}){if(n==null)return null;if(typeof n=="string"){const t=n.trim();if(!t)throw new Error(`${e} must reference a non-empty toolchain name`);const i=o[t];if(!i)throw new Error(`${e} references unknown toolchain "${t}"`);return{...i,refName:t,sourceLabel:`${e} -> ${t}`}}return{...x(n,e),refName:null,sourceLabel:e}}export async function resolveConfiguredToolchain(n,e={}){const o=n?.testkit?.runtime?.toolchain;if(!n||!o)return null;let r=v.get(n);if(r===void 0){r=P(i=>J(n,o,{...e,signal:i})),v.set(n,r);const t=r;r.promise.catch(()=>{v.get(n)===t&&v.delete(n)})}return R(r,e.signal)}export function announceResolvedToolchain(n,e,o=null){return!e||y.has(n)||(y.add(n),o?.toolchainResolved&&o.toolchainResolved({serviceName:n.name,runtimeLabel:n.runtimeLabel||n.name},e.summary)),Promise.resolve()}export function applyToolchainEnv(n,e,o=process.env){if(!e)return{...n};const r={...n,PATH:ne(e.binDir,n.PATH||o.PATH||""),TESTKIT_TOOLCHAIN_KIND:"node",TESTKIT_TOOLCHAIN_NODE_VERSION:e.nodeVersion,TESTKIT_TOOLCHAIN_NODE_SOURCE:e.nodeSource,TESTKIT_TOOLCHAIN_INSTALL_MODE:e.install};return e.npmVersion&&(r.TESTKIT_TOOLCHAIN_NPM_VERSION=e.npmVersion,r.TESTKIT_TOOLCHAIN_NPM_SOURCE=e.npmSource),r}function x(n,e){if(!N(n))throw new Error(`${e} must be an object`);F(n,["cwd","detect","install","node","npm"],e);const o=k(l(n.cwd)||z,`${e}.cwd`),r=l(n.detect)||q,t=l(n.install)||U;if(r!=="auto"&&r!=="off")throw new Error(`${e}.detect must be "auto" or "off"`);if(t!=="require-host"&&t!=="download")throw new Error(`${e}.install must be "require-host" or "download"`);return{cwd:o,detect:r,install:t,node:l(n.node),npm:l(n.npm)}}async function J(n,e,o){const r=n.productDir,t=V(r,e.cwd,`${e.sourceLabel}.cwd`),i=G(t),s=e.node||(e.detect==="auto"?i.nodeSpec:null),a=e.node?"toolchain.node":e.detect==="auto"?i.nodeSource??"none":"none",d=e.npm||(e.detect==="auto"?i.npmSpec:null),c=e.npm?"toolchain.npm":e.detect==="auto"?i.npmSource??"none":"none";if(!s&&!d)throw new Error(`Service "${n.name}" enables runtime.toolchain but no Node/npm version could be resolved in ${e.cwd}`);return e.install==="require-host"?Q({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:d,npmSource:c,toolchain:e,options:o}):X({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:d,npmSource:c,toolchain:e,options:o})}function G(n){const e=m.join(n,"package.json"),o=W(e),r=ee(m.join(n,".tool-versions")),t=b(m.join(n,".nvmrc")),i=b(m.join(n,".node-version")),s=l(p(o,"volta","node")),a=l(p(o,"engines","node")),d=l(r.nodejs),c=s||t||i||d||a;let u=null;s?u="package.json#volta.node":t?u=".nvmrc":i?u=".node-version":d?u=".tool-versions#nodejs":a&&(u="package.json#engines.node");const E=l(p(o,"volta","npm")),$=l(p(o,"engines","npm")),T=Z(p(o,"packageManager")),C=E||(T?.name==="npm"?T.version:null)||$;let w=null;return E?w="package.json#volta.npm":T?.name==="npm"?w="package.json#packageManager":$&&(w="package.json#engines.npm"),{nodeSpec:c,nodeSource:u,npmSpec:C,npmSource:w}}async function Q({config:n,cwd:e,nodeSpec:o,nodeSource:r,npmSpec:t,npmSource:i,toolchain:s,options:a}){const d=f(a.hostNodeVersion||process.versions.node);if(o&&!g(d,o))throw new Error(`Service "${n.name}" requires Node ${o} (${r}), but host Node is ${d}`);let c=null;if(t&&(c=f(a.hostNpmVersion||await Y({command:"npm",args:["--version"],cwd:e,env:process.env,commandExecutor:a.commandExecutor,signal:a.signal})),!g(c,t)))throw new Error(`Service "${n.name}" requires npm ${t} (${i}), but host npm is ${c}`);return{install:s.install,cwd:s.cwd,nodeVersion:d,nodeSource:r,nodeSpec:o,npmVersion:c,npmSource:i,npmSpec:t,nodeExecutable:process.execPath,binDir:m.dirname(process.execPath),toolchainDir:m.dirname(process.execPath),fingerprint:S({install:s.install,nodeVersion:d,npmVersion:c,nodeSource:r,npmSource:i}),summary:`${s.install} node=${d}${c?` npm=${c}`:""} (${r})`}}async function X({config:n,nodeSpec:e,nodeSource:o,npmSpec:r,npmSource:t,toolchain:i,options:s}){if(!e)throw new Error(`Service "${n.name}" download toolchain mode requires a resolvable Node version`);const a=L(e)?f(e):D(e);if(!a)throw new Error(`Service "${n.name}" cannot deterministically provision Node from "${e}". Provide an exact version in runtime.toolchain.node, .nvmrc, .node-version, .tool-versions, or package.json#volta.node.`);const d=await provisionNodeToolchain({productDir:n.productDir,version:a,fetchImpl:s.fetchImpl||fetchToolchain,commandExecutor:s.commandExecutor||executeToolchainCommand,signal:s.signal});if(!g(a,e))throw new Error(`Service "${n.name}" resolved Node ${a}, which does not satisfy ${e}`);const c=d.npmVersion?f(d.npmVersion):null;if(r&&(!c||!g(c,r)))throw new Error(`Service "${n.name}" requires npm ${r} (${t}), but Node ${a} bundles npm ${c||"unknown"}`);return{install:i.install,cwd:i.cwd,nodeVersion:a,nodeSource:o,nodeSpec:e,npmVersion:c,npmSource:t,npmSpec:r,nodeExecutable:d.nodeExecutable,binDir:d.binDir,toolchainDir:d.toolchainDir,fingerprint:S({install:i.install,nodeVersion:a,npmVersion:c,nodeSource:o,npmSource:t}),summary:`download node=${a}${c?` npm=${c}`:""} (${o})`}}export async function provisionNodeToolchain({productDir:n,version:e,fetchImpl:o=fetchToolchain,commandExecutor:r=executeToolchainCommand,signal:t}){const i=f(e);if(e!==i)throw new Error(`Downloaded Node toolchain version must use canonical x.y.z form; received ${JSON.stringify(e)}`);const s=H(i),{provisionNodeToolchainWithRelease:a}=await import("./node-provisioning.js");return a({commandExecutor:r,fetchImpl:o,productDir:n,release:s,signal:t})}function S(n){return _.createHash("sha256").update(JSON.stringify({kind:"node",...n})).digest("hex")}async function Y({command:n,args:e,cwd:o,env:r,commandExecutor:t=executeToolchainCommand,signal:i}){const s=await t(n,e,{cwd:o,env:r,signal:i,stdio:"pipe",timeoutMs:O,windowsHide:!0});return s.stdout==null?"":typeof s.stdout=="string"?s.stdout.trim():Buffer.from(s.stdout).toString().trim()}function Z(n){const e=l(n);if(!e)return null;const o=e.lastIndexOf("@");return o<=0||o===e.length-1?null:{name:e.slice(0,o),version:e.slice(o+1)}}function b(n){if(!h.existsSync(n))return null;const o=h.readFileSync(n,"utf8").split(/\r?\n/).find(r=>r.trim().length>0);return o?o.trim():null}function ee(n){if(!h.existsSync(n))return{};const e={};for(const o of h.readFileSync(n,"utf8").split(/\r?\n/)){const r=o.trim();if(!r||r.startsWith("#"))continue;const[t,i]=r.split(/\s+/,2);t&&i&&(e[t]=i.trim())}return e}function ne(n,e){const o=l(n);if(!o)return e;const r=(e||"").split(m.delimiter).filter(Boolean).filter(t=>t!==o);return[o,...r].join(m.delimiter)}export async function fetchToolchain(n,e={}){const o=AbortSignal.timeout(B),r=await fetch(n,{signal:e.signal===void 0?o:AbortSignal.any([e.signal,o])});return{arrayBuffer:()=>r.arrayBuffer(),body:r.body===null?null:oe(r.body),ok:r.ok,status:r.status}}async function*oe(n){const e=n.getReader();let o=!1;try{for(;;){const r=await e.read();if(r.done){o=!0;return}yield r.value}}finally{o||await e.cancel(),e.releaseLock()}}export function prepareToolchainCommandForManagedHost(n,e,o={}){const r={env:o.env||process.env,platform:o.platform},t=A(n,r),i=I(t,e,r);return i.windowsVerbatimArguments?(re(t,e),{executable:o.hostNodeExecutable||process.execPath,args:["--input-type=commonjs","--eval",K,"--",i.command,...i.args]}):{executable:i.command,args:i.args}}function re(n,e){if(/[%!"\0\r\n]/u.test(n))throw new Error(`Windows batch toolchain commands cannot safely preserve command path ${JSON.stringify(n)}`);const o=e.find(r=>/[%!"\0\r\n]/u.test(r)||r.endsWith("\\"));if(o!==void 0)throw new Error(`Windows batch toolchain commands cannot safely preserve argument ${JSON.stringify(o)}`)}export async function executeToolchainCommand(n,e,o={}){const r=te(o.timeoutMs),t=m.resolve(o.cwd||process.cwd()),i=prepareToolchainCommandForManagedHost(n,e,{env:o.env||process.env}),s=await j({args:i.args,cwd:t,displayLabel:`Toolchain command ${n}`,env:o.env||process.env,executable:i.executable,signal:o.signal,timeoutMs:r}),a=M(`Toolchain command ${n}`,s);if(a)throw a;if(s.exitCode!==0)throw new Error(`Toolchain command ${n} exited with code ${String(s.exitCode)}${ie(s.stdout,s.stderr)}`);return{stdout:s.stdout}}function te(n){const e=n??O;if(!Number.isSafeInteger(e)||e<=0)throw new Error("Toolchain command timeout must be a positive safe integer in milliseconds");return e}function ie(n,e){const o=[n,e].map(r=>r.trim()).filter(Boolean).join(`
|
|
3
3
|
`);return o?`
|
|
4
4
|
${o.slice(-4e3)}`:""}function p(n,...e){let o=n;for(const r of e){if(!N(o))return;o=o[r]}return o}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isUnknownRecord as
|
|
1
|
+
import{isUnknownRecord as i}from"../../kernel/unknown-values.js";const o=["**/*.ui.testkit.ts"];export function defineConfig(e={},r={}){const t=Reflect.get(e,"test"),n={...i(t)?t:{}},s=new Set([...c(n.exclude,"config.test.exclude"),...r.exclude??[],...o]);return{...e,test:{...n,exclude:[...s]}}}export function testkitExcludes(){return[...o]}function c(e,r){if(e===void 0)return[];if(!Array.isArray(e)||!e.every(t=>typeof t=="string"))throw new TypeError(`${r} must be an array of strings`);return e}
|
package/dist/types/config.d.ts
CHANGED
|
@@ -3,79 +3,6 @@ declare const RUNTIME_ISOLATION_POLICIES: readonly [
|
|
|
3
3
|
"resetBefore"
|
|
4
4
|
];
|
|
5
5
|
export type RuntimeIsolationPolicy = (typeof RUNTIME_ISOLATION_POLICIES)[number];
|
|
6
|
-
export type RuntimeMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
7
|
-
export interface RuntimeHeaders {
|
|
8
|
-
[key: string]: string;
|
|
9
|
-
}
|
|
10
|
-
export interface RuntimeCookie {
|
|
11
|
-
value: string;
|
|
12
|
-
}
|
|
13
|
-
export interface RuntimeEnv {
|
|
14
|
-
BASE: string;
|
|
15
|
-
rawEnv?: Record<string, string | undefined>;
|
|
16
|
-
}
|
|
17
|
-
export interface HttpRequestParams {
|
|
18
|
-
[key: string]: unknown;
|
|
19
|
-
headers?: RuntimeHeaders;
|
|
20
|
-
}
|
|
21
|
-
export type HttpProfileEnvironment = Readonly<Record<string, string | undefined>>;
|
|
22
|
-
export interface HttpProfileEnv {
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
BASE?: string;
|
|
25
|
-
rawEnv?: HttpProfileEnvironment;
|
|
26
|
-
}
|
|
27
|
-
export type HttpProfileResolvedEnv = HttpProfileEnv & RuntimeEnv;
|
|
28
|
-
export interface HttpProfileHeaderContext {
|
|
29
|
-
actor?: string | null;
|
|
30
|
-
env?: HttpProfileEnv;
|
|
31
|
-
}
|
|
32
|
-
export type HttpProfileHeaderBuilder<TSetup = unknown> = (setupData: TSetup | null, context?: HttpProfileHeaderContext & {
|
|
33
|
-
env: HttpProfileResolvedEnv;
|
|
34
|
-
}) => RuntimeHeaders | undefined;
|
|
35
|
-
/** Response shape the in-process profile setup client resolves to. */
|
|
36
|
-
export interface HttpProfileResponse {
|
|
37
|
-
body: string;
|
|
38
|
-
cookies?: Record<string, RuntimeCookie[] | undefined>;
|
|
39
|
-
headers?: Record<string, string>;
|
|
40
|
-
status: number;
|
|
41
|
-
}
|
|
42
|
-
export type HttpProfileRequestMethod = "del" | "get" | "patch" | "post" | "put";
|
|
43
|
-
/** HTTP verbs an execution engine hands to a profile's setup step. */
|
|
44
|
-
export type HttpProfileRequestClient<TResult = Promise<HttpProfileResponse>> = {
|
|
45
|
-
[Method in HttpProfileRequestMethod]: Method extends "get" ? (url: string, params?: HttpRequestParams) => TResult : (url: string, body?: unknown, params?: HttpRequestParams) => TResult;
|
|
46
|
-
};
|
|
47
|
-
export interface HttpProfileSetupContext {
|
|
48
|
-
env: HttpProfileResolvedEnv;
|
|
49
|
-
http: HttpProfileRequestClient;
|
|
50
|
-
json(response: unknown): unknown;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Explicit, test-owned authentication for a named HTTP profile. The data
|
|
54
|
-
* profile runs `setup` or `setupAsync` once and passes the
|
|
55
|
-
* result to `headers` for every request.
|
|
56
|
-
*/
|
|
57
|
-
export interface HttpProfileAuth<TSetup = unknown> {
|
|
58
|
-
headers?: HttpProfileHeaderBuilder<TSetup>;
|
|
59
|
-
setup?(context: HttpProfileSetupContext): TSetup;
|
|
60
|
-
setupAsync?(context: HttpProfileSetupContext): Promise<TSetup>;
|
|
61
|
-
}
|
|
62
|
-
export interface HttpProfileConfig<TSetup = unknown> {
|
|
63
|
-
[key: string]: unknown;
|
|
64
|
-
auth?: HttpProfileAuth<TSetup> | null;
|
|
65
|
-
baseUrl?: string;
|
|
66
|
-
env?: HttpProfileEnv;
|
|
67
|
-
headers?: HttpProfileHeaderBuilder<TSetup>;
|
|
68
|
-
rawHeaders?: HttpProfileHeaderBuilder<TSetup>;
|
|
69
|
-
}
|
|
70
|
-
export interface RepoConfig {
|
|
71
|
-
[key: string]: unknown;
|
|
72
|
-
profiles?: {
|
|
73
|
-
http?: Record<string, HttpProfileConfig>;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
export declare function registerRepoConfig(config: RepoConfig | null | undefined): void;
|
|
77
|
-
export declare function getRepoConfig(): RepoConfig | null;
|
|
78
|
-
export declare function clearRepoConfig(): void;
|
|
79
6
|
export interface DatabaseBindingEnvConfig {
|
|
80
7
|
prefix: string;
|
|
81
8
|
service: string;
|
|
@@ -128,6 +55,7 @@ export interface StepsBuildConfigInput extends BuildConfigInputBase {
|
|
|
128
55
|
steps?: ConfiguredStepInput[];
|
|
129
56
|
}
|
|
130
57
|
export type BuildConfigInput = TscBuildConfigInput | ScriptBuildConfigInput | NextBuildConfigInput | StepsBuildConfigInput;
|
|
58
|
+
export type RuntimeMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
131
59
|
export type TemplateCommandStepConfig = ConfiguredCommandStepInput;
|
|
132
60
|
export type TemplateSqlFileStepConfig = ConfiguredSqlFileStepInput;
|
|
133
61
|
export type TemplateModuleStepConfig = ConfiguredModuleStepInput;
|
|
@@ -251,7 +179,7 @@ export interface RuntimeIsolationConfig {
|
|
|
251
179
|
export interface TestkitExecutionConfig {
|
|
252
180
|
fileTimeoutSeconds?: number;
|
|
253
181
|
taskConcurrency?: number;
|
|
254
|
-
/** @deprecated Use taskConcurrency.
|
|
182
|
+
/** @deprecated Use taskConcurrency. */
|
|
255
183
|
workers?: number;
|
|
256
184
|
}
|
|
257
185
|
export interface FingerprintConfig {
|
|
@@ -267,7 +195,7 @@ export interface TestkitBoundaryLintRuleConfig extends TestkitLintRuleConfig {
|
|
|
267
195
|
allowed?: string[];
|
|
268
196
|
trackedOnly?: boolean;
|
|
269
197
|
}
|
|
270
|
-
export type TestkitLintRuleName = "engineImports" | "uiSpecShape" | "
|
|
198
|
+
export type TestkitLintRuleName = "engineImports" | "uiSpecShape" | "configImports" | "testkitBoundary" | "unitTestBoundaries";
|
|
271
199
|
export interface TestkitLintConfig {
|
|
272
200
|
rules?: Partial<Record<Exclude<TestkitLintRuleName, "testkitBoundary">, boolean | TestkitLintRuleConfig>> & {
|
|
273
201
|
testkitBoundary?: boolean | TestkitBoundaryLintRuleConfig;
|
|
@@ -313,9 +241,6 @@ export interface ServiceConfig {
|
|
|
313
241
|
envFiles?: string[];
|
|
314
242
|
local?: false | ServiceLocalConfig;
|
|
315
243
|
runtime?: RuntimeConfig;
|
|
316
|
-
runtimeIsolation?: RuntimeIsolationPolicy | RuntimeIsolationConfig;
|
|
317
|
-
requirements?: ServiceRequirementConfig;
|
|
318
|
-
skip?: SkipConfig;
|
|
319
244
|
}
|
|
320
245
|
export interface AppServiceConfig extends ServiceConfig {
|
|
321
246
|
local: ServiceLocalConfig;
|
|
@@ -328,9 +253,6 @@ export interface PresetServiceOptions extends Record<string, unknown> {
|
|
|
328
253
|
discovery?: DiscoveryConfig;
|
|
329
254
|
envFile?: string;
|
|
330
255
|
envFiles?: string[];
|
|
331
|
-
runtimeIsolation?: RuntimeIsolationPolicy | RuntimeIsolationConfig;
|
|
332
|
-
requirements?: ServiceRequirementConfig;
|
|
333
|
-
skip?: SkipConfig;
|
|
334
256
|
}
|
|
335
257
|
export interface AppRuntimeOptions {
|
|
336
258
|
instances?: number;
|
|
@@ -378,7 +300,7 @@ export interface NodeNextPresetOptions {
|
|
|
378
300
|
node?: string;
|
|
379
301
|
npm?: string;
|
|
380
302
|
taskConcurrency?: number;
|
|
381
|
-
/** @deprecated Use taskConcurrency.
|
|
303
|
+
/** @deprecated Use taskConcurrency. */
|
|
382
304
|
workers?: number;
|
|
383
305
|
}
|
|
384
306
|
export interface AreaConfig {
|
|
@@ -408,15 +330,14 @@ export interface TestkitConfig {
|
|
|
408
330
|
fingerprints?: FingerprintConfig;
|
|
409
331
|
groups?: Record<string, GroupConfig>;
|
|
410
332
|
lint?: TestkitLintConfig;
|
|
411
|
-
profiles?: {
|
|
412
|
-
http?: Record<string, HttpProfileConfig>;
|
|
413
|
-
};
|
|
414
333
|
redact?: string[];
|
|
415
334
|
services?: Record<string, ServiceConfig>;
|
|
416
335
|
toolchains?: Record<string, ToolchainConfig>;
|
|
417
336
|
ui?: UiConfig;
|
|
418
337
|
}
|
|
419
|
-
export declare function defineConfig<const TConfig extends TestkitConfig>(config: TConfig
|
|
338
|
+
export declare function defineConfig<const TConfig extends TestkitConfig>(config: TConfig & {
|
|
339
|
+
readonly [Key in Exclude<keyof TConfig, keyof TestkitConfig>]: never;
|
|
340
|
+
}): TConfig;
|
|
420
341
|
declare function commandStep(run: string, options?: ConfiguredStepBaseInput): ConfiguredCommandStepInput;
|
|
421
342
|
declare function sqlFileStep(filePath: string, options?: ConfiguredStepBaseInput): ConfiguredSqlFileStepInput;
|
|
422
343
|
declare function moduleStep(target: string, options?: ConfiguredStepBaseInput): ConfiguredModuleStepInput;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export type JsonPrimitive = boolean | null | number | string;
|
|
2
|
+
export type JsonValue = JsonPrimitive | readonly JsonValue[] | JsonObject;
|
|
3
|
+
export interface JsonObject {
|
|
4
|
+
readonly [key: string]: JsonValue;
|
|
5
|
+
}
|
|
1
6
|
export interface CapturedRequest {
|
|
2
7
|
readonly bodyBytes: number;
|
|
3
8
|
readonly bodyText: string;
|
|
@@ -36,5 +41,6 @@ export declare class EnvironmentValueMissingError extends Error {
|
|
|
36
41
|
export declare function endpoint(name: string): string;
|
|
37
42
|
export declare function database(name: string): string;
|
|
38
43
|
export declare function handle(name: string): EnvironmentHandle;
|
|
44
|
+
export declare function setupData(): JsonValue;
|
|
39
45
|
|
|
40
46
|
export {};
|
|
@@ -1,78 +1,10 @@
|
|
|
1
|
-
import { TestContext
|
|
1
|
+
import { TestContext } from 'vitest';
|
|
2
2
|
|
|
3
|
-
export type RuntimeMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
4
|
-
export interface RuntimeHeaders {
|
|
5
|
-
[key: string]: string;
|
|
6
|
-
}
|
|
7
|
-
export interface RuntimeCookie {
|
|
8
|
-
value: string;
|
|
9
|
-
}
|
|
10
|
-
export interface RuntimeEnv {
|
|
11
|
-
BASE: string;
|
|
12
|
-
rawEnv?: Record<string, string | undefined>;
|
|
13
|
-
}
|
|
14
|
-
export interface HttpRequestParams {
|
|
15
|
-
[key: string]: unknown;
|
|
16
|
-
headers?: RuntimeHeaders;
|
|
17
|
-
}
|
|
18
|
-
export type HttpProfileEnvironment = Readonly<Record<string, string | undefined>>;
|
|
19
|
-
export interface HttpProfileEnv {
|
|
20
|
-
[key: string]: unknown;
|
|
21
|
-
BASE?: string;
|
|
22
|
-
rawEnv?: HttpProfileEnvironment;
|
|
23
|
-
}
|
|
24
|
-
export type HttpProfileResolvedEnv = HttpProfileEnv & RuntimeEnv;
|
|
25
|
-
export interface HttpProfileHeaderContext {
|
|
26
|
-
actor?: string | null;
|
|
27
|
-
env?: HttpProfileEnv;
|
|
28
|
-
}
|
|
29
|
-
export type HttpProfileHeaderBuilder<TSetup = unknown> = (setupData: TSetup | null, context?: HttpProfileHeaderContext & {
|
|
30
|
-
env: HttpProfileResolvedEnv;
|
|
31
|
-
}) => RuntimeHeaders | undefined;
|
|
32
|
-
/** Response shape the in-process profile setup client resolves to. */
|
|
33
|
-
export interface HttpProfileResponse {
|
|
34
|
-
body: string;
|
|
35
|
-
cookies?: Record<string, RuntimeCookie[] | undefined>;
|
|
36
|
-
headers?: Record<string, string>;
|
|
37
|
-
status: number;
|
|
38
|
-
}
|
|
39
|
-
export type HttpProfileRequestMethod = "del" | "get" | "patch" | "post" | "put";
|
|
40
|
-
/** HTTP verbs an execution engine hands to a profile's setup step. */
|
|
41
|
-
export type HttpProfileRequestClient<TResult = Promise<HttpProfileResponse>> = {
|
|
42
|
-
[Method in HttpProfileRequestMethod]: Method extends "get" ? (url: string, params?: HttpRequestParams) => TResult : (url: string, body?: unknown, params?: HttpRequestParams) => TResult;
|
|
43
|
-
};
|
|
44
|
-
export interface HttpProfileSetupContext {
|
|
45
|
-
env: HttpProfileResolvedEnv;
|
|
46
|
-
http: HttpProfileRequestClient;
|
|
47
|
-
json(response: unknown): unknown;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Explicit, test-owned authentication for a named HTTP profile. The data
|
|
51
|
-
* profile runs `setup` or `setupAsync` once and passes the
|
|
52
|
-
* result to `headers` for every request.
|
|
53
|
-
*/
|
|
54
|
-
export interface HttpProfileAuth<TSetup = unknown> {
|
|
55
|
-
headers?: HttpProfileHeaderBuilder<TSetup>;
|
|
56
|
-
setup?(context: HttpProfileSetupContext): TSetup;
|
|
57
|
-
setupAsync?(context: HttpProfileSetupContext): Promise<TSetup>;
|
|
58
|
-
}
|
|
59
|
-
export interface HttpMethods<Response, Extra extends unknown[]> {
|
|
60
|
-
get: (path: string, ...extra: Extra) => Response;
|
|
61
|
-
delete: (path: string, body?: unknown, ...extra: Extra) => Response;
|
|
62
|
-
post: (path: string, body?: unknown, ...extra: Extra) => Response;
|
|
63
|
-
put: (path: string, body?: unknown, ...extra: Extra) => Response;
|
|
64
|
-
patch: (path: string, body?: unknown, ...extra: Extra) => Response;
|
|
65
|
-
}
|
|
66
3
|
declare const DATA_ARTIFACT_KIND = "testkit.data-flow";
|
|
67
4
|
declare const DATA_SCHEMA_VERSION = 1;
|
|
68
5
|
export type DataFindingSeverity = "error" | "info" | "waste" | "watch";
|
|
69
6
|
export type DataMetricBudgetOperator = "<" | "<=" | "==" | ">" | ">=" | "exists";
|
|
70
7
|
export type DataSequenceBudgetOperator = "exists" | "sequence==" | "sequenceOnly";
|
|
71
|
-
export interface DataScenarioOptions {
|
|
72
|
-
description?: string;
|
|
73
|
-
timeout?: number;
|
|
74
|
-
timeoutMs?: number;
|
|
75
|
-
}
|
|
76
8
|
export interface DataMetricOptions {
|
|
77
9
|
description?: string;
|
|
78
10
|
dimensions?: Record<string, unknown>;
|
|
@@ -102,136 +34,21 @@ export interface DataSequenceBudget {
|
|
|
102
34
|
includesOnly(values: readonly unknown[], options?: DataBudgetOptions): this;
|
|
103
35
|
required(options?: DataBudgetOptions): this;
|
|
104
36
|
}
|
|
105
|
-
export interface DataFixture {
|
|
106
|
-
buffer(): Buffer;
|
|
107
|
-
contentType: string;
|
|
108
|
-
filename: string;
|
|
109
|
-
json(): unknown;
|
|
110
|
-
path: string;
|
|
111
|
-
sha256: string;
|
|
112
|
-
sizeBytes: number;
|
|
113
|
-
text(encoding?: BufferEncoding): string;
|
|
114
|
-
}
|
|
115
|
-
export interface DataHttpResponse {
|
|
116
|
-
body: string;
|
|
117
|
-
cookies: Record<string, Array<{
|
|
118
|
-
value: string;
|
|
119
|
-
}>>;
|
|
120
|
-
durationMs: number;
|
|
121
|
-
headers: Record<string, string>;
|
|
122
|
-
json(): unknown;
|
|
123
|
-
method: string;
|
|
124
|
-
path: string;
|
|
125
|
-
status: number;
|
|
126
|
-
url: string;
|
|
127
|
-
}
|
|
128
|
-
export interface DataHttpRequestOptions {
|
|
129
|
-
contentTypeJson?: boolean;
|
|
130
|
-
signal?: AbortSignal;
|
|
131
|
-
}
|
|
132
|
-
export interface DataActorSession {
|
|
133
|
-
[key: string]: unknown;
|
|
134
|
-
actorIndex?: number;
|
|
135
|
-
email?: string | null;
|
|
136
|
-
name?: string | null;
|
|
137
|
-
organizationKey?: string | null;
|
|
138
|
-
organizationName?: string | null;
|
|
139
|
-
session?: Record<string, unknown> | null;
|
|
140
|
-
}
|
|
141
|
-
export interface DataSessionBundle {
|
|
142
|
-
actors: Record<string, DataActorSession | undefined>;
|
|
143
|
-
primaryActor: string | null;
|
|
144
|
-
}
|
|
145
|
-
export interface DataHttpHeaderContext {
|
|
146
|
-
actor: DataActorSession | null;
|
|
147
|
-
actorName: string | null;
|
|
148
|
-
sessionBundle: DataSessionBundle | null;
|
|
149
|
-
}
|
|
150
|
-
export type DataHttpHeaderBuilder = (context: DataHttpHeaderContext) => Record<string, string>;
|
|
151
|
-
export interface DataHttpClientOptions {
|
|
152
|
-
baseUrl?: string;
|
|
153
|
-
defaultActor?: string;
|
|
154
|
-
defaultHeaders?: Record<string, string>;
|
|
155
|
-
getHeaders?: DataHttpHeaderBuilder;
|
|
156
|
-
getRawHeaders?: DataHttpHeaderBuilder;
|
|
157
|
-
profile?: string;
|
|
158
|
-
recorder?: DataHttpRecorder;
|
|
159
|
-
sessionBundle?: DataSessionBundle;
|
|
160
|
-
trace?: DataHttpRecorder;
|
|
161
|
-
}
|
|
162
|
-
export interface DataHttpRequest {
|
|
163
|
-
(method: string, path: string, body?: unknown, headers?: Record<string, string>, options?: DataHttpRequestOptions): Promise<DataHttpResponse>;
|
|
164
|
-
}
|
|
165
|
-
export type DataActorRawRequest = DataHttpRequest & HttpMethods<Promise<DataHttpResponse>, [
|
|
166
|
-
headers?: Record<string, string>,
|
|
167
|
-
options?: DataHttpRequestOptions
|
|
168
|
-
]>;
|
|
169
|
-
export interface DataRootRawRequest extends DataHttpRequest, Pick<HttpMethods<Promise<DataHttpResponse>, [
|
|
170
|
-
headers?: Record<string, string>,
|
|
171
|
-
options?: DataHttpRequestOptions
|
|
172
|
-
]>, "get" | "post"> {
|
|
173
|
-
as(actorName: string): DataActorRawRequest;
|
|
174
|
-
}
|
|
175
|
-
export interface DataHttpMethods extends HttpMethods<Promise<DataHttpResponse>, [
|
|
176
|
-
headers?: Record<string, string>,
|
|
177
|
-
options?: DataHttpRequestOptions
|
|
178
|
-
]> {
|
|
179
|
-
headers(extraHeaders?: Record<string, string>): Record<string, string>;
|
|
180
|
-
rawHeaders(extraHeaders?: Record<string, string>): Record<string, string>;
|
|
181
|
-
request(method: string, path: string, body?: unknown, headers?: Record<string, string>, options?: DataHttpRequestOptions): Promise<DataHttpResponse>;
|
|
182
|
-
}
|
|
183
|
-
export interface DataActorHttpClient extends DataHttpMethods {
|
|
184
|
-
raw: DataActorRawRequest;
|
|
185
|
-
rawReq: DataActorRawRequest;
|
|
186
|
-
}
|
|
187
|
-
export interface DataHttpActor {
|
|
188
|
-
email: string | null;
|
|
189
|
-
headers: Record<string, string>;
|
|
190
|
-
index: number;
|
|
191
|
-
key: string;
|
|
192
|
-
name: string | null;
|
|
193
|
-
organizationKey: string | null;
|
|
194
|
-
organizationName: string | null;
|
|
195
|
-
rawHeaders: Record<string, string>;
|
|
196
|
-
rawReq: DataActorRawRequest;
|
|
197
|
-
req: DataActorHttpClient;
|
|
198
|
-
session: Record<string, unknown> | null;
|
|
199
|
-
}
|
|
200
|
-
export interface DataHttpActors {
|
|
201
|
-
get(name: string): DataHttpActor;
|
|
202
|
-
has(name: string): boolean;
|
|
203
|
-
list(): DataHttpActor[];
|
|
204
|
-
names: string[];
|
|
205
|
-
primary: DataHttpActor | null;
|
|
206
|
-
}
|
|
207
|
-
export interface DataHttpClient extends DataHttpMethods {
|
|
208
|
-
actor?: DataHttpActor | null;
|
|
209
|
-
actors?: DataHttpActors;
|
|
210
|
-
as(actorName: string): DataActorHttpClient;
|
|
211
|
-
baseUrl: string;
|
|
212
|
-
env?: HttpProfileEnv;
|
|
213
|
-
raw: DataRootRawRequest;
|
|
214
|
-
rawReq: DataRootRawRequest;
|
|
215
|
-
}
|
|
216
37
|
export interface DataHttpRequestRecord {
|
|
217
38
|
bodyBytes?: number;
|
|
218
39
|
durationMs?: number;
|
|
219
40
|
method: string;
|
|
220
41
|
path: string;
|
|
221
|
-
requestHeaders?: Record<string, string>;
|
|
222
42
|
responseBytes?: number;
|
|
223
43
|
status?: number;
|
|
224
44
|
}
|
|
225
|
-
export interface DataHttpRecorder {
|
|
226
|
-
recordHttpRequest(entry: DataHttpRequestRecord): unknown;
|
|
227
|
-
}
|
|
228
45
|
export interface DataExternalCallDetails extends DataEvidenceDetails {
|
|
229
46
|
costMinor?: number;
|
|
230
47
|
durationMs?: number;
|
|
231
48
|
requestBytes?: number;
|
|
232
49
|
responseBytes?: number;
|
|
233
50
|
}
|
|
234
|
-
export interface DataFlow
|
|
51
|
+
export interface DataFlow {
|
|
235
52
|
addFinding(severity: string, message: string, details?: Record<string, unknown>): this;
|
|
236
53
|
actor(name: string, details?: DataEvidenceDetails): this;
|
|
237
54
|
budget(metricName: string): DataMetricBudget;
|
|
@@ -268,30 +85,6 @@ export interface DataFlow extends DataHttpRecorder {
|
|
|
268
85
|
system(name: string, details?: DataEvidenceDetails): this;
|
|
269
86
|
transition(name: string, details?: DataEvidenceDetails): this;
|
|
270
87
|
}
|
|
271
|
-
export interface DataScenarioContext extends DataFlow, DataRuntimeContext {
|
|
272
|
-
fixture(name: string): DataFixture;
|
|
273
|
-
http(options?: DataHttpProfileOptions): Promise<DataHttpClient>;
|
|
274
|
-
}
|
|
275
|
-
export interface DataRuntimeContext extends Record<string, unknown> {
|
|
276
|
-
baseUrl?: string | null;
|
|
277
|
-
engineId?: "node-vitest";
|
|
278
|
-
readonly env: Readonly<Record<string, string>>;
|
|
279
|
-
profileId?: "node-vitest-data";
|
|
280
|
-
serviceName?: string;
|
|
281
|
-
task?: {
|
|
282
|
-
file?: string;
|
|
283
|
-
id?: number | string;
|
|
284
|
-
suiteName?: string;
|
|
285
|
-
testType: "data";
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
export type DataHttpProfileAuth = HttpProfileAuth<DataSessionBundle>;
|
|
289
|
-
export interface DataHttpProfileOptions extends DataHttpClientOptions {
|
|
290
|
-
auth?: DataHttpProfileAuth | null;
|
|
291
|
-
env?: HttpProfileEnv;
|
|
292
|
-
headers?: HttpProfileHeaderBuilder<DataSessionBundle>;
|
|
293
|
-
rawHeaders?: HttpProfileHeaderBuilder<DataSessionBundle>;
|
|
294
|
-
}
|
|
295
88
|
export interface DataMetric {
|
|
296
89
|
aggregation?: string;
|
|
297
90
|
description: string | null;
|
|
@@ -358,7 +151,6 @@ export type DataBudgetResult = (Omit<DataMetricBudgetInput, "expected" | "messag
|
|
|
358
151
|
export interface DataScenarioReport {
|
|
359
152
|
budgetFailures: DataBudgetResult[];
|
|
360
153
|
budgets: DataBudgetResult[];
|
|
361
|
-
description: string | null;
|
|
362
154
|
durationMs: number;
|
|
363
155
|
error: SerializedDataError | null;
|
|
364
156
|
events: DataEvent[];
|
|
@@ -391,17 +183,9 @@ export interface DataFlowReport {
|
|
|
391
183
|
summaryText: string;
|
|
392
184
|
taskId: string | null;
|
|
393
185
|
}
|
|
394
|
-
export declare function createHttpClient(options?: DataHttpClientOptions): DataHttpClient;
|
|
395
|
-
export declare function readDataContext(): DataRuntimeContext;
|
|
396
186
|
export declare function renderDataFlowMarkdown(report: DataFlowReport): string;
|
|
397
|
-
export declare function dataScenario(name: string, run: (context: DataScenarioContext) => unknown): void;
|
|
398
|
-
export declare function dataScenario(name: string, options: DataScenarioOptions, run: (context: DataScenarioContext) => unknown): void;
|
|
399
187
|
export declare function dataFlow(context: TestContext): DataFlow;
|
|
400
188
|
export declare function measureJsonBytes(value: unknown): number;
|
|
401
189
|
export declare function stableHash(value: unknown): string;
|
|
402
190
|
|
|
403
|
-
export {
|
|
404
|
-
expect,
|
|
405
|
-
};
|
|
406
|
-
|
|
407
191
|
export {};
|