@jterrazz/test 16.1.0 → 17.0.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 +45 -171
- package/dist/browser/index.js +2 -2867
- package/dist/browser/services.js +2 -0
- package/dist/browser/stubs.js +2 -0
- package/dist/checker.d.ts +6 -1
- package/dist/checker.js +4551 -2612
- package/dist/config.d.ts +40 -0
- package/dist/config.js +309 -0
- package/dist/in-place.global-setup.d.ts +11 -0
- package/dist/in-place.global-setup.js +21 -0
- package/dist/index.d.ts +1653 -3002
- package/dist/index.js +5226 -3845
- package/dist/mobile-session.global-setup.d.ts +14 -0
- package/dist/mobile-session.global-setup.js +31 -0
- package/dist/oxlint.cjs +6073 -5616
- package/dist/oxlint.d.cts +43 -7212
- package/dist/oxlint.d.ts +43 -7212
- package/dist/oxlint.js +6065 -5609
- package/dist/route-coverage.global-setup.d.ts +42 -0
- package/dist/route-coverage.global-setup.js +2 -0
- package/dist/services.d.ts +3 -0
- package/dist/services.global-setup.d.ts +43 -0
- package/dist/services.global-setup.js +2 -0
- package/dist/services.js +597 -0
- package/dist/shared-appium.adapter.js +428 -0
- package/dist/shared-artifacts.js +32 -0
- package/dist/shared-chapter.js +7 -0
- package/dist/shared-container.port.d.ts +31 -0
- package/dist/shared-derived-projects.js +58 -0
- package/dist/shared-device.port.d.ts +189 -0
- package/dist/shared-exchange.js +447 -0
- package/dist/shared-in-place.js +172 -0
- package/dist/shared-index.browser.js +3191 -0
- package/dist/shared-index.services.d.ts +346 -0
- package/dist/shared-index.stubs.d.ts +287 -0
- package/dist/shared-json-shape.js +17 -0
- package/dist/shared-landmarks.js +71 -0
- package/dist/shared-ledger.js +68 -0
- package/dist/shared-literate-plugin.js +183 -0
- package/dist/shared-manifest.js +1321 -0
- package/dist/shared-pause.js +11 -0
- package/dist/shared-peer.js +88 -0
- package/dist/shared-playwright.adapter.js +330 -0
- package/dist/shared-process.adapter.js +74 -0
- package/dist/shared-refusal.js +35 -0
- package/dist/shared-resolve.js +24 -0
- package/dist/shared-route-coverage.global-setup.js +187 -0
- package/dist/shared-scenario-failure.js +198 -0
- package/dist/shared-serve.js +365 -0
- package/dist/shared-service-images.js +10 -0
- package/dist/shared-services.global-setup.js +179 -0
- package/dist/shared-session-ledger.js +301 -0
- package/dist/shared-setup-entry.js +12 -0
- package/dist/shared-source-scan.js +133 -0
- package/dist/shared-spec-document.js +365 -0
- package/dist/shared-specifications.js +26 -0
- package/dist/shared-stream-body.js +130 -0
- package/dist/shared-stub-server.js +190 -0
- package/dist/shared-temp-root.global-setup.js +80 -0
- package/dist/shared-test-baseline.js +26 -0
- package/dist/shared-test-section.js +58 -0
- package/dist/shared-testcontainers.adapter.js +203 -0
- package/dist/shared-tokens.js +55 -0
- package/dist/shared-yaml-document.js +119 -0
- package/dist/stubs.d.ts +2 -0
- package/dist/stubs.js +657 -0
- package/dist/temp-root.global-setup.d.ts +7 -0
- package/dist/temp-root.global-setup.js +2 -0
- package/dist/vitest.d.ts +97 -163
- package/dist/vitest.js +374 -507
- package/docs/README.md +82 -36
- package/docs/concepts/architecture.md +118 -0
- package/docs/concepts/conventions.md +333 -0
- package/docs/guides/api-specs.md +374 -0
- package/docs/guides/cli-specs.md +564 -0
- package/docs/guides/component-specs.md +252 -0
- package/docs/guides/develop.md +94 -0
- package/docs/guides/integration-specs.md +181 -0
- package/docs/guides/job-specs.md +180 -0
- package/docs/guides/lint-specs.md +174 -0
- package/docs/guides/mobile-specs.md +319 -0
- package/docs/guides/module-tests.md +149 -0
- package/docs/guides/release.md +43 -0
- package/docs/guides/spec-documents.md +189 -0
- package/docs/guides/website-specs.md +413 -0
- package/docs/reference/assertions.md +345 -0
- package/docs/reference/glossary.md +20 -0
- package/docs/reference/linting.md +483 -0
- package/docs/reference/services.md +236 -0
- package/docs/reference/stubs.md +498 -0
- package/docs/reference/time-and-doubles.md +137 -0
- package/docs/reference/tokens.md +258 -0
- package/docs/reference/visitor.md +221 -0
- package/docs/start/getting-started.md +187 -0
- package/docs/start/set-up-a-project.md +214 -0
- package/package.json +50 -30
- package/schema/spec.schema.json +43 -17
- package/dist/appium.adapter.js +0 -489
- package/dist/artifacts.js +0 -32
- package/dist/fixtures.js +0 -110
- package/dist/literate.js +0 -1747
- package/dist/match.js +0 -804
- package/dist/playwright.adapter.js +0 -349
- package/dist/server.js +0 -160
- package/dist/stream.js +0 -321
- package/dist/substring-warning.js +0 -244
- package/docs/01-architecture.md +0 -95
- package/docs/02-developing.md +0 -351
- package/docs/03-testing.md +0 -495
- package/docs/04-operating.md +0 -101
- package/docs/05-module-tests.md +0 -152
- package/docs/06-integration.md +0 -180
- package/docs/07-component.md +0 -246
- package/docs/08-website.md +0 -404
- package/docs/09-mobile.md +0 -270
- package/docs/10-api.md +0 -264
- package/docs/11-jobs.md +0 -157
- package/docs/12-cli.md +0 -677
- package/docs/13-elements.md +0 -242
- package/docs/14-assertions.md +0 -314
- package/docs/15-tokens.md +0 -253
- package/docs/16-contracts.md +0 -438
- package/docs/17-services.md +0 -188
- package/docs/18-conventions.md +0 -305
- package/docs/19-linting.md +0 -510
- package/docs/decisions/001-v9-conventions-on-three-channels.md +0 -50
- package/docs/decisions/002-the-statique-channel-holds-only-what-upstream-does-not.md +0 -49
- package/docs/decisions/003-a-rendered-component-is-a-facet-on-vitest-browser-mode.md +0 -84
- package/docs/decisions/004-a-module-against-real-services-or-a-golden-is-the-integration-facet.md +0 -81
- package/docs/decisions/005-the-doubles-ladder-is-closed.md +0 -86
- package/docs/decisions/006-the-catalogue-reaches-a-file-by-its-role.md +0 -245
- package/docs/decisions/007-compose-mode-leaves-the-package.md +0 -53
- package/docs/decisions/008-vitest-5-node-24-and-the-native-seams-as-optional-peers.md +0 -75
- package/docs/decisions/_template.md +0 -22
- package/docs/reference/classes/Matcher.md +0 -120
- package/docs/reference/classes/ProcessHandle.md +0 -368
- package/docs/reference/functions/defineContract.md +0 -39
- package/docs/reference/functions/defineContracts.md +0 -36
- package/docs/reference/functions/disabled.md +0 -28
- package/docs/reference/functions/enabled.md +0 -20
- package/docs/reference/functions/focused.md +0 -26
- package/docs/reference/functions/mockOf.md +0 -79
- package/docs/reference/functions/postgres.md +0 -31
- package/docs/reference/functions/process.md +0 -33
- package/docs/reference/functions/redis.md +0 -28
- package/docs/reference/functions/required.md +0 -41
- package/docs/reference/functions/selected.md +0 -26
- package/docs/reference/functions/sqlite.md +0 -33
- package/docs/reference/functions/testId.md +0 -20
- package/docs/reference/functions/text.md +0 -40
- package/docs/reference/functions/valued.md +0 -28
- package/docs/reference/functions/waitUntil.md +0 -46
- package/docs/reference/functions/within.md +0 -29
- package/docs/reference/index.md +0 -196
- package/docs/reference/interfaces/BaseResult.md +0 -87
- package/docs/reference/interfaces/CallResult.md +0 -160
- package/docs/reference/interfaces/CaptureScope.md +0 -82
- package/docs/reference/interfaces/CliResult.md +0 -253
- package/docs/reference/interfaces/ContainerAccessor.md +0 -166
- package/docs/reference/interfaces/DirectoryAccessor.md +0 -33
- package/docs/reference/interfaces/FetchResult.md +0 -180
- package/docs/reference/interfaces/FilesystemAccessor.md +0 -46
- package/docs/reference/interfaces/HttpResult.md +0 -126
- package/docs/reference/interfaces/JsonAccessor.md +0 -46
- package/docs/reference/interfaces/PageResult.md +0 -356
- package/docs/reference/interfaces/RenderResult.md +0 -72
- package/docs/reference/interfaces/RenderedText.md +0 -110
- package/docs/reference/interfaces/ResponseAccessor.md +0 -47
- package/docs/reference/interfaces/ScreenResult.md +0 -128
- package/docs/reference/interfaces/TableAccessor.md +0 -26
- package/docs/reference/interfaces/TextAccessor.md +0 -96
- package/docs/reference/type-aliases/ApiHandle.md +0 -68
- package/docs/reference/type-aliases/ApiSpecification.md +0 -213
- package/docs/reference/type-aliases/ApiSpecificationOptions.md +0 -68
- package/docs/reference/type-aliases/BrowserConsoleMessage.md +0 -30
- package/docs/reference/type-aliases/BrowserLinkElement.md +0 -50
- package/docs/reference/type-aliases/BrowserMetaElement.md +0 -40
- package/docs/reference/type-aliases/BrowserOpenOptions.md +0 -87
- package/docs/reference/type-aliases/BrowserPage.md +0 -132
- package/docs/reference/type-aliases/BrowserPort.md +0 -51
- package/docs/reference/type-aliases/CliEnv.md +0 -11
- package/docs/reference/type-aliases/CliHandle.md +0 -80
- package/docs/reference/type-aliases/CliInput.md +0 -36
- package/docs/reference/type-aliases/CliOutput.md +0 -46
- package/docs/reference/type-aliases/CliPort.md +0 -58
- package/docs/reference/type-aliases/CliSpecification.md +0 -144
- package/docs/reference/type-aliases/CliSpecificationOptions.md +0 -134
- package/docs/reference/type-aliases/ComponentChain.md +0 -156
- package/docs/reference/type-aliases/ComponentScenario.md +0 -20
- package/docs/reference/type-aliases/ComponentUi.md +0 -47
- package/docs/reference/type-aliases/ComponentVisitor.md +0 -10
- package/docs/reference/type-aliases/ContainerPort.md +0 -113
- package/docs/reference/type-aliases/Contract.md +0 -68
- package/docs/reference/type-aliases/ContractInput.md +0 -13
- package/docs/reference/type-aliases/ContractRequest.md +0 -95
- package/docs/reference/type-aliases/ContractResponder.md +0 -23
- package/docs/reference/type-aliases/ContractResponse.md +0 -78
- package/docs/reference/type-aliases/ContractResponseValue.md +0 -13
- package/docs/reference/type-aliases/Contracts.md +0 -48
- package/docs/reference/type-aliases/DatabaseKeys.md +0 -16
- package/docs/reference/type-aliases/DatabasePort.md +0 -72
- package/docs/reference/type-aliases/DeviceOpenOptions.md +0 -46
- package/docs/reference/type-aliases/DevicePort.md +0 -51
- package/docs/reference/type-aliases/DeviceScreen.md +0 -32
- package/docs/reference/type-aliases/DeviceTimeouts.md +0 -39
- package/docs/reference/type-aliases/DockerSpecConfig.md +0 -43
- package/docs/reference/type-aliases/DomMount.md +0 -21
- package/docs/reference/type-aliases/ElementKind.md +0 -27
- package/docs/reference/type-aliases/ElementMatch.md +0 -74
- package/docs/reference/type-aliases/ElementOptions.md +0 -29
- package/docs/reference/type-aliases/ElementRef.md +0 -128
- package/docs/reference/type-aliases/ExecOptions.md +0 -37
- package/docs/reference/type-aliases/FileAccessor.md +0 -54
- package/docs/reference/type-aliases/HonoApp.md +0 -31
- package/docs/reference/type-aliases/HttpContractFilter.md +0 -49
- package/docs/reference/type-aliases/HttpResponseInit.md +0 -46
- package/docs/reference/type-aliases/HttpStreamInit.md +0 -58
- package/docs/reference/type-aliases/IntegrationHandle.md +0 -46
- package/docs/reference/type-aliases/IntegrationSpecification.md +0 -111
- package/docs/reference/type-aliases/IntegrationSpecificationOptions.md +0 -42
- package/docs/reference/type-aliases/Intercept.md +0 -19
- package/docs/reference/type-aliases/InterceptOptions.md +0 -28
- package/docs/reference/type-aliases/InterceptScope.md +0 -11
- package/docs/reference/type-aliases/IsolationStrategy.md +0 -75
- package/docs/reference/type-aliases/JobHandle.md +0 -34
- package/docs/reference/type-aliases/JobsHandle.md +0 -57
- package/docs/reference/type-aliases/JobsResult.md +0 -16
- package/docs/reference/type-aliases/JobsSpecification.md +0 -94
- package/docs/reference/type-aliases/JobsSpecificationOptions.md +0 -56
- package/docs/reference/type-aliases/LandmarkKind.md +0 -20
- package/docs/reference/type-aliases/LiterateRunFlags.md +0 -27
- package/docs/reference/type-aliases/LiterateServeRegistration.md +0 -70
- package/docs/reference/type-aliases/MatchFixtureOptions.md +0 -27
- package/docs/reference/type-aliases/MatchableRequest.md +0 -61
- package/docs/reference/type-aliases/MatcherKind.md +0 -34
- package/docs/reference/type-aliases/MobileBackendOptions.md +0 -28
- package/docs/reference/type-aliases/MobileElementKind.md +0 -14
- package/docs/reference/type-aliases/MobileElementMatch.md +0 -60
- package/docs/reference/type-aliases/MobileElementRef.md +0 -20
- package/docs/reference/type-aliases/MobileHandle.md +0 -65
- package/docs/reference/type-aliases/MobileScenario.md +0 -20
- package/docs/reference/type-aliases/MobileSpecification.md +0 -51
- package/docs/reference/type-aliases/MobileSpecificationOptions.md +0 -126
- package/docs/reference/type-aliases/MobileVisitor.md +0 -81
- package/docs/reference/type-aliases/MockOfOptions.md +0 -26
- package/docs/reference/type-aliases/MockPort.md +0 -10
- package/docs/reference/type-aliases/PinnedClock.md +0 -10
- package/docs/reference/type-aliases/PostgresOptions.md +0 -32
- package/docs/reference/type-aliases/ProcessOptions.md +0 -112
- package/docs/reference/type-aliases/RedisOptions.md +0 -20
- package/docs/reference/type-aliases/RenderSubject.md +0 -12
- package/docs/reference/type-aliases/ScreenNode.md +0 -67
- package/docs/reference/type-aliases/ServerPort.md +0 -36
- package/docs/reference/type-aliases/ServerResponse.md +0 -46
- package/docs/reference/type-aliases/ServerSpec.md +0 -21
- package/docs/reference/type-aliases/ServiceHandle.md +0 -216
- package/docs/reference/type-aliases/ServiceRecord.md +0 -12
- package/docs/reference/type-aliases/SpecDocument.md +0 -84
- package/docs/reference/type-aliases/SpecEnvToken.md +0 -21
- package/docs/reference/type-aliases/SpecFileAssertion.md +0 -27
- package/docs/reference/type-aliases/SpecFixture.md +0 -30
- package/docs/reference/type-aliases/SpecKind.md +0 -8
- package/docs/reference/type-aliases/SpecRun.md +0 -108
- package/docs/reference/type-aliases/SpecServeEntry.md +0 -40
- package/docs/reference/type-aliases/SpecStream.md +0 -32
- package/docs/reference/type-aliases/SpecificationConfig.md +0 -290
- package/docs/reference/type-aliases/SqliteOptions.md +0 -36
- package/docs/reference/type-aliases/SseEvent.md +0 -58
- package/docs/reference/type-aliases/StreamBody.md +0 -61
- package/docs/reference/type-aliases/TextFilter.md +0 -22
- package/docs/reference/type-aliases/VisitScenario.md +0 -20
- package/docs/reference/type-aliases/Visitor.md +0 -215
- package/docs/reference/type-aliases/WaitUntilOptions.md +0 -46
- package/docs/reference/type-aliases/WebsiteBackendOptions.md +0 -37
- package/docs/reference/type-aliases/WebsiteHandle.md +0 -51
- package/docs/reference/type-aliases/WebsiteSpecification.md +0 -118
- package/docs/reference/type-aliases/WebsiteSpecificationOptions.md +0 -40
- package/docs/reference/variables/anthropic.md +0 -19
- package/docs/reference/variables/banner.md +0 -10
- package/docs/reference/variables/button.md +0 -10
- package/docs/reference/variables/clock.md +0 -16
- package/docs/reference/variables/complementary.md +0 -10
- package/docs/reference/variables/component.md +0 -10
- package/docs/reference/variables/content.md +0 -10
- package/docs/reference/variables/contentinfo.md +0 -10
- package/docs/reference/variables/dialog.md +0 -10
- package/docs/reference/variables/field.md +0 -10
- package/docs/reference/variables/form.md +0 -10
- package/docs/reference/variables/heading.md +0 -10
- package/docs/reference/variables/http.md +0 -40
- package/docs/reference/variables/intercept.md +0 -11
- package/docs/reference/variables/link.md +0 -10
- package/docs/reference/variables/listitem.md +0 -10
- package/docs/reference/variables/main.md +0 -10
- package/docs/reference/variables/match.md +0 -8
- package/docs/reference/variables/navigation.md +0 -10
- package/docs/reference/variables/openai.md +0 -21
- package/docs/reference/variables/option.md +0 -17
- package/docs/reference/variables/region.md +0 -10
- package/docs/reference/variables/row.md +0 -10
- package/docs/reference/variables/search.md +0 -10
- package/docs/reference/variables/specification.md +0 -8
- package/docs/reference/variables/status.md +0 -10
- package/docs/reference/variables/table.md +0 -10
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { t as ContainerOptions } from "./shared-container.port.js";
|
|
2
|
+
//#region src/chain/config.d.ts
|
|
3
|
+
type ChainConfig = {
|
|
4
|
+
root?: string | undefined;
|
|
5
|
+
};
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/chain/context/with.capability.d.ts
|
|
8
|
+
/** Merged over `process.env`; a `null` value unsets the variable. */
|
|
9
|
+
type EnvRecord = Record<string, null | string>;
|
|
10
|
+
/** What a file shares on every chain it starts: settings, never state. */
|
|
11
|
+
type ChainContext = {
|
|
12
|
+
/** The instant every chain pins; a chain's own `.clock()` wins. */
|
|
13
|
+
clock?: string;
|
|
14
|
+
/** The environment every command runs with; a chain's own `.env()` merges over it. */
|
|
15
|
+
env?: EnvRecord;
|
|
16
|
+
/** The headers every request carries; a chain's own `.headers()` merges over them. */
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/chain/capability.d.ts
|
|
21
|
+
type MatrixGroup = 'Constructor option' | 'Result accessor' | 'Route option' | 'Setup' | 'Target' | 'Terminal action' | 'Verb';
|
|
22
|
+
/** `probe` is a call in `lint/self/corpus/matrix-calls.ts`'s grammar, or a literal. */
|
|
23
|
+
type MatrixRow = {
|
|
24
|
+
readonly group: MatrixGroup;
|
|
25
|
+
readonly member?: string;
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly probe: string;
|
|
28
|
+
};
|
|
29
|
+
type ContextKey = keyof ChainContext;
|
|
30
|
+
type Intersect<Union> = (Union extends unknown ? (member: Union) => void : never) extends ((all: infer All) => void) ? All : never;
|
|
31
|
+
type SpecificationParams = {
|
|
32
|
+
readonly databaseKey: string;
|
|
33
|
+
readonly services: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
/** Each definition extends this, naming its methods over `this['self']` and `this['params']`; `ChainOf` fills both in. */
|
|
36
|
+
interface ChainSignature {
|
|
37
|
+
readonly chain: object;
|
|
38
|
+
readonly params: SpecificationParams;
|
|
39
|
+
readonly self: unknown;
|
|
40
|
+
}
|
|
41
|
+
type Armed = {
|
|
42
|
+
/** Released in reverse arm order; an adapter may defer it to the test's end. */
|
|
43
|
+
readonly release?: () => void;
|
|
44
|
+
/** Preferred over the action's own error. */
|
|
45
|
+
readonly violation?: () => Error | null;
|
|
46
|
+
};
|
|
47
|
+
type Run<Config extends ChainConfig = ChainConfig> = {
|
|
48
|
+
readonly config: Config;
|
|
49
|
+
readonly testDir: string;
|
|
50
|
+
readonly workDir: null | string;
|
|
51
|
+
};
|
|
52
|
+
type SetupContext<Needs, Config extends ChainConfig = ChainConfig> = {
|
|
53
|
+
readonly config: Config;
|
|
54
|
+
readonly adapters: Needs;
|
|
55
|
+
};
|
|
56
|
+
type Capability<Name extends string, Slice, Args extends readonly unknown[], Signature extends ChainSignature = ChainSignature, Needs extends object = Record<never, never>, Context extends ContextKey = never, Config extends ChainConfig = ChainConfig> = {
|
|
57
|
+
readonly context?: Context;
|
|
58
|
+
readonly initial: Slice;
|
|
59
|
+
readonly kind: 'setup';
|
|
60
|
+
readonly name: Name;
|
|
61
|
+
/** Arm order across the setups of a chain: a lower phase arms first, and each setup states its own. */
|
|
62
|
+
readonly phase: number;
|
|
63
|
+
readonly row: MatrixRow;
|
|
64
|
+
/** A type alone, never set at runtime: `ChainOf` reads it. */
|
|
65
|
+
readonly signature?: Signature;
|
|
66
|
+
/** Absent when the action reads the slice instead. */
|
|
67
|
+
arm?(slice: Slice, adapters: Needs, run: Run<Config>): Armed | Promise<Armed | undefined> | undefined;
|
|
68
|
+
reduce(slice: Slice, args: Args, setup: SetupContext<Needs, Config>): Slice;
|
|
69
|
+
};
|
|
70
|
+
type AnyCapability = Capability<string, unknown, readonly unknown[], ChainSignature, object, ContextKey>;
|
|
71
|
+
type ActionOption<Name extends string> = {
|
|
72
|
+
readonly kind: 'option';
|
|
73
|
+
readonly name: Name;
|
|
74
|
+
readonly row: MatrixRow;
|
|
75
|
+
};
|
|
76
|
+
type Sharing = {
|
|
77
|
+
readonly kind: 'context';
|
|
78
|
+
readonly name: 'with';
|
|
79
|
+
readonly row: MatrixRow;
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/services/database.port.d.ts
|
|
83
|
+
/** Database port for specification runners; implement it to plug in your stack. */
|
|
84
|
+
type DatabasePort = {
|
|
85
|
+
/** Execute raw SQL (for seeding test data). */
|
|
86
|
+
seed: (sql: string) => Promise<void>;
|
|
87
|
+
/** Query a table and return rows as arrays of values. */
|
|
88
|
+
query: (table: string, columns: string[]) => Promise<unknown[][]>;
|
|
89
|
+
/** The table's columns, in the order the table declares them: what a whole-table comparison reads. */
|
|
90
|
+
columns: (table: string) => Promise<string[]>;
|
|
91
|
+
/** Reset database to clean state between tests. */
|
|
92
|
+
reset: () => Promise<void>;
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/services/isolation.port.d.ts
|
|
96
|
+
/** Isolates service state across parallel workers: `acquire()` per worker, `reset()` per run, `release()` at shutdown. */
|
|
97
|
+
type IsolationStrategy = {
|
|
98
|
+
/** Create this worker's isolated namespace, once at worker start. */
|
|
99
|
+
acquire: (workerId: string) => Promise<void>;
|
|
100
|
+
/** Fast reset within the namespace between runs. */
|
|
101
|
+
reset: () => Promise<void>;
|
|
102
|
+
/** Tear down the namespace, once at worker shutdown. */
|
|
103
|
+
release: () => Promise<void>;
|
|
104
|
+
};
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/services/service.port.d.ts
|
|
107
|
+
/** A service handle, as `postgres()` or `redis()` return it; `connectionString` fills in once started. */
|
|
108
|
+
type ServiceHandle = {
|
|
109
|
+
readonly type: string;
|
|
110
|
+
/** The kebab-case record key, assigned at start: `{ analyticsDb: postgres() }` reads `docker/analytics-db/`. */
|
|
111
|
+
serviceName: null | string;
|
|
112
|
+
/** Default container port for this service type. */
|
|
113
|
+
readonly defaultPort: number;
|
|
114
|
+
/** Default Docker image for this service type. */
|
|
115
|
+
readonly defaultImage: string;
|
|
116
|
+
/** Environment variables to pass to the container. */
|
|
117
|
+
readonly environment: Record<string, string>;
|
|
118
|
+
/** How the container runs beyond its image, port and environment; none when absent. */
|
|
119
|
+
readonly containerOptions?: ContainerOptions;
|
|
120
|
+
/** Connection string, populated after start. */
|
|
121
|
+
connectionString: string;
|
|
122
|
+
/** Build the connection string from host and port. */
|
|
123
|
+
buildConnectionString: (host: string, port: number) => string;
|
|
124
|
+
/** Create a DatabasePort adapter (if this is a database). Returns null otherwise. */
|
|
125
|
+
createDatabaseAdapter: () => DatabasePort | null;
|
|
126
|
+
/** Verify the service is ready and accepting connections. Throws with context if not. */
|
|
127
|
+
healthcheck: () => Promise<void>;
|
|
128
|
+
/** Run the init scripts from `<root>/docker/<name>/`; a cache goes under `<root>/.artifacts/`, never a machine-global directory. */
|
|
129
|
+
initialize: (dockerDir: string, root: string) => Promise<void>;
|
|
130
|
+
/** Reset state between tests (truncate tables, flush cache, etc.) */
|
|
131
|
+
reset: () => Promise<void>;
|
|
132
|
+
isolation: () => IsolationStrategy;
|
|
133
|
+
};
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/services/services.d.ts
|
|
136
|
+
/** Services declared as a named record: the keys are the spec's database vocabulary. */
|
|
137
|
+
type ServiceRecord = Record<string, ServiceHandle>;
|
|
138
|
+
/** Keys of a services record whose handles are databases. */
|
|
139
|
+
type DatabaseKeys<Services extends ServiceRecord> = { [K in keyof Services]: Services[K] extends DatabasePort ? K & string : never; }[keyof Services];
|
|
140
|
+
type ServicesConfig = ChainConfig & {
|
|
141
|
+
database?: DatabasePort | undefined;
|
|
142
|
+
/** Drives `database-named-only-when-several-at-runtime`: with 2+ databases `database` is required on `.seed()` / `.table()`, with one it is refused. */
|
|
143
|
+
databaseKeys?: string[] | undefined;
|
|
144
|
+
databases?: Map<string, DatabasePort> | undefined;
|
|
145
|
+
/** In cli mode, drives the `<KEY>_URL` injection (`service-urls-injected`), plus `DATABASE_URL` / `REDIS_URL` when unambiguous. */
|
|
146
|
+
services?: Record<string, ServiceHandle> | undefined;
|
|
147
|
+
};
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/disk/spec-path.d.ts
|
|
150
|
+
/** A path relative to the spec file; `Extension` narrows its tail. */
|
|
151
|
+
type RelativePath<Extension extends string = string> = `../${string}${Extension}` | `./${string}${Extension}`;
|
|
152
|
+
declare const DISK: unique symbol;
|
|
153
|
+
/** A file the spec names, at `Path`. */
|
|
154
|
+
type FileAt<Path extends string> = {
|
|
155
|
+
readonly [DISK]: 'file';
|
|
156
|
+
readonly path: Path;
|
|
157
|
+
};
|
|
158
|
+
/** A file whose path ends in `Extension`: what a verb that reads one file accepts. */
|
|
159
|
+
type DiskFile<Extension extends string = string> = FileAt<RelativePath<Extension>>;
|
|
160
|
+
/** A directory the spec names; its path ends in `/`. */
|
|
161
|
+
type DiskDirectory = {
|
|
162
|
+
readonly [DISK]: 'directory';
|
|
163
|
+
readonly path: RelativePath<'/'>;
|
|
164
|
+
};
|
|
165
|
+
/** Either of the two: what a verb that takes a file or a directory accepts. */
|
|
166
|
+
type DiskTarget = DiskDirectory | DiskFile;
|
|
167
|
+
/** Name one file, by its path from the spec file. */
|
|
168
|
+
declare function file<const Path extends RelativePath>(path: Path extends `${string}/` ? never : Path): FileAt<Path>;
|
|
169
|
+
/** Name one directory, by its path from the spec file, ending in `/`. */
|
|
170
|
+
declare function directory<const Path extends RelativePath<'/'>>(path: Path): DiskDirectory & {
|
|
171
|
+
readonly path: Path;
|
|
172
|
+
};
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/services/postgres/postgres.adapter.d.ts
|
|
175
|
+
type PostgresOptions = {
|
|
176
|
+
/** Override image. */
|
|
177
|
+
image?: string;
|
|
178
|
+
/** Override environment variables. */
|
|
179
|
+
env?: Record<string, string>;
|
|
180
|
+
};
|
|
181
|
+
declare class PostgresHandle implements DatabasePort, ServiceHandle {
|
|
182
|
+
readonly type = "postgres";
|
|
183
|
+
serviceName: null | string;
|
|
184
|
+
readonly defaultPort = 5432;
|
|
185
|
+
readonly defaultImage: string;
|
|
186
|
+
readonly environment: Record<string, string>;
|
|
187
|
+
readonly containerOptions: ContainerOptions;
|
|
188
|
+
connectionString: string;
|
|
189
|
+
private client;
|
|
190
|
+
private template;
|
|
191
|
+
private clone;
|
|
192
|
+
constructor(options?: PostgresOptions);
|
|
193
|
+
buildConnectionString(host: string, port: number): string;
|
|
194
|
+
createDatabaseAdapter(): DatabasePort;
|
|
195
|
+
healthcheck(): Promise<void>;
|
|
196
|
+
initialize(dockerDir: string): Promise<void>;
|
|
197
|
+
private getClient;
|
|
198
|
+
seed(sql: string): Promise<void>;
|
|
199
|
+
reset(): Promise<void>;
|
|
200
|
+
query(table: string, columns: string[]): Promise<unknown[][]>;
|
|
201
|
+
columns(table: string): Promise<string[]>;
|
|
202
|
+
isolation(): IsolationStrategy;
|
|
203
|
+
private closeClient;
|
|
204
|
+
}
|
|
205
|
+
/** Create a PostgreSQL service handle; its record key names the init script folder (`docker/<key>/init.sql`). */
|
|
206
|
+
declare function postgres(options?: PostgresOptions): PostgresHandle;
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/services/redis/redis.adapter.d.ts
|
|
209
|
+
type RedisOptions = {
|
|
210
|
+
/** Override image. */
|
|
211
|
+
image?: string;
|
|
212
|
+
};
|
|
213
|
+
declare class RedisHandle implements ServiceHandle {
|
|
214
|
+
readonly type = "redis";
|
|
215
|
+
serviceName: null | string;
|
|
216
|
+
readonly defaultPort = 6379;
|
|
217
|
+
readonly defaultImage: string;
|
|
218
|
+
readonly environment: Record<string, string>;
|
|
219
|
+
readonly containerOptions: ContainerOptions;
|
|
220
|
+
connectionString: string;
|
|
221
|
+
private dbIndex;
|
|
222
|
+
/** What this handle holds: its slot's release, and the container's own string it extended. */
|
|
223
|
+
private pair;
|
|
224
|
+
constructor(options?: RedisOptions);
|
|
225
|
+
buildConnectionString(host: string, port: number): string;
|
|
226
|
+
createDatabaseAdapter(): DatabasePort | null;
|
|
227
|
+
healthcheck(): Promise<void>;
|
|
228
|
+
initialize(): Promise<void>;
|
|
229
|
+
reset(): Promise<void>;
|
|
230
|
+
isolation(): IsolationStrategy;
|
|
231
|
+
private letGo;
|
|
232
|
+
}
|
|
233
|
+
/** Create a Redis service handle, reported under its record key. */
|
|
234
|
+
declare function redis(options?: RedisOptions): RedisHandle;
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/services/sqlite/sqlite-template.d.ts
|
|
237
|
+
type SqliteOptions = {
|
|
238
|
+
/** Path to a SQL file initializing the schema; exclusive with `prismaSchema`. */
|
|
239
|
+
init?: string;
|
|
240
|
+
/** Path to a Prisma schema, resolved against the cwd and handed to `prisma db push --schema`; exclusive with `init`. */
|
|
241
|
+
prismaSchema?: string;
|
|
242
|
+
};
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/services/sqlite/sqlite.adapter.d.ts
|
|
245
|
+
declare class SqliteHandle implements DatabasePort, ServiceHandle {
|
|
246
|
+
readonly type = "sqlite";
|
|
247
|
+
serviceName: null | string;
|
|
248
|
+
readonly defaultPort = 0;
|
|
249
|
+
readonly defaultImage = "";
|
|
250
|
+
readonly environment: Record<string, string>;
|
|
251
|
+
connectionString: string;
|
|
252
|
+
private db;
|
|
253
|
+
private templatePath;
|
|
254
|
+
private workerDbPath;
|
|
255
|
+
private readonly initSql;
|
|
256
|
+
private readonly prismaSchema;
|
|
257
|
+
private readonly options;
|
|
258
|
+
constructor(options?: SqliteOptions);
|
|
259
|
+
buildConnectionString(): string;
|
|
260
|
+
createDatabaseAdapter(): DatabasePort;
|
|
261
|
+
healthcheck(): Promise<void>;
|
|
262
|
+
/** One worker builds under an exclusive lock, the others wait: two concurrent `prisma db push` on one file is `database is locked`. */
|
|
263
|
+
initialize(_dockerDir?: string, root?: string): Promise<void>;
|
|
264
|
+
/** Built on a private path, then renamed into place: `prisma db push` writes the header long before the tables exist. */
|
|
265
|
+
private buildTemplate;
|
|
266
|
+
private writeTemplate;
|
|
267
|
+
private getDb;
|
|
268
|
+
private closeDb;
|
|
269
|
+
seed(sql: string): Promise<void>;
|
|
270
|
+
query(table: string, columns: string[]): Promise<unknown[][]>;
|
|
271
|
+
columns(table: string): Promise<string[]>;
|
|
272
|
+
reset(): Promise<void>;
|
|
273
|
+
isolation(): IsolationStrategy;
|
|
274
|
+
}
|
|
275
|
+
/** Create a SQLite service handle, isolated per test by file copy. */
|
|
276
|
+
declare function sqlite(options?: SqliteOptions): SqliteHandle;
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/services/process/process.adapter.d.ts
|
|
279
|
+
/** The one shape an external process takes: `website({ server })`, `services: { api: process(...) }`, `serve:`. */
|
|
280
|
+
type ProcessOptions = {
|
|
281
|
+
/** A one-shot command run once per specification before the spawn, which must exit 0. */
|
|
282
|
+
before?: string;
|
|
283
|
+
/** Shell command that starts the process. Receives the chosen port as `PORT`. */
|
|
284
|
+
command: string;
|
|
285
|
+
/** Working directory, relative to the project root. Default: the root itself. A function is called when the process starts, once per file: a spec that lays a fresh project for each file returns the path it laid. */
|
|
286
|
+
cwd?: (() => string) | string;
|
|
287
|
+
/** Environment on top of the runner's; a function receives the services already started. */
|
|
288
|
+
env?: ((services: Record<string, {
|
|
289
|
+
connectionString: string;
|
|
290
|
+
}>) => Record<string, string>) | Record<string, string>;
|
|
291
|
+
/** Fixed port. Default: an OS-assigned free port, injected as `PORT`. */
|
|
292
|
+
port?: number;
|
|
293
|
+
/** Readiness: a path polled until any HTTP status answers (`PORT` injected), or a regex over the output whose one group captures the port. */
|
|
294
|
+
ready?: RegExp | string;
|
|
295
|
+
/** Readiness budget in milliseconds. Default 30 000. */
|
|
296
|
+
timeout?: number;
|
|
297
|
+
};
|
|
298
|
+
declare class ProcessHandle implements ServiceHandle {
|
|
299
|
+
/** Embedded: nothing to pull, nothing to run in a container. */
|
|
300
|
+
readonly defaultImage = "";
|
|
301
|
+
readonly defaultPort = 0;
|
|
302
|
+
readonly environment: Record<string, string>;
|
|
303
|
+
readonly type = "process";
|
|
304
|
+
serviceName: null | string;
|
|
305
|
+
connectionString: string;
|
|
306
|
+
started: boolean;
|
|
307
|
+
private served;
|
|
308
|
+
private readonly options;
|
|
309
|
+
constructor(options: ProcessOptions);
|
|
310
|
+
buildConnectionString(host: string, port: number): string;
|
|
311
|
+
createDatabaseAdapter(): DatabasePort | null;
|
|
312
|
+
healthcheck(): Promise<void>;
|
|
313
|
+
initialize(): Promise<void>;
|
|
314
|
+
/** Isolation is the run's: one child per evaluation of the specification module, told apart by the minted id. */
|
|
315
|
+
isolation(): IsolationStrategy;
|
|
316
|
+
reset(): Promise<void>;
|
|
317
|
+
/** Spawn it and wait until it answers; `services` is every sibling, already started. */
|
|
318
|
+
spawnWith(root: string, services: Record<string, {
|
|
319
|
+
connectionString: string;
|
|
320
|
+
}>, runId: string): Promise<void>;
|
|
321
|
+
/** Terminate the process group. Idempotent. */
|
|
322
|
+
shutdown(): Promise<void>;
|
|
323
|
+
/** What it was declared as: what a specification reads to start it in a slot of its own. */
|
|
324
|
+
get spec(): ProcessOptions;
|
|
325
|
+
/** The base URL it came up on, known only once it is started. */
|
|
326
|
+
get url(): string;
|
|
327
|
+
}
|
|
328
|
+
/** Declare an external process the framework owns for the life of the specification. */
|
|
329
|
+
declare function processService(options: ProcessOptions): ProcessHandle;
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region src/services/seed/seed.capability.d.ts
|
|
332
|
+
/** What `.seed()` takes: a `.sql` file, never the statements themselves: SQL is not written in a test. */
|
|
333
|
+
type SeedSource = DiskFile<'.sql'>;
|
|
334
|
+
type SeedMethod<Self, DatabaseKey extends string> = (source: SeedSource, options?: {
|
|
335
|
+
database?: DatabaseKey;
|
|
336
|
+
}) => Self;
|
|
337
|
+
type SeedChain<Self, DatabaseKey extends string> = {
|
|
338
|
+
/** Queue a SQL seed (`file('./__seeds__/<name>.sql')`) to run before the action. */
|
|
339
|
+
seed: SeedMethod<Self, DatabaseKey>;
|
|
340
|
+
};
|
|
341
|
+
interface SeedSignature extends ChainSignature {
|
|
342
|
+
readonly chain: SeedChain<this['self'], this['params']['databaseKey']>;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
export { Intersect as A, IsolationStrategy as C, Armed as D, AnyCapability as E, ChainContext as F, EnvRecord as I, ChainConfig as L, Run as M, Sharing as N, Capability as O, SpecificationParams as P, ServiceHandle as S, ActionOption as T, directory as _, processService as a, ServiceRecord as b, RedisOptions as c, postgres as d, DiskDirectory as f, RelativePath as g, FileAt as h, ProcessOptions as i, MatrixRow as j, ChainSignature as k, redis as l, DiskTarget as m, SeedSource as n, sqlite as o, DiskFile as p, ProcessHandle as r, SqliteOptions as s, SeedSignature as t, PostgresOptions as u, file as v, DatabasePort as w, ServicesConfig as x, DatabaseKeys as y };
|
|
346
|
+
//# sourceMappingURL=shared-index.services.d.ts.map
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
//#region src/stubs/exchange.d.ts
|
|
2
|
+
/** An observed outgoing request, reduced to what stub matchers inspect. */
|
|
3
|
+
type MatchableRequest = {
|
|
4
|
+
/** Parsed JSON body when the payload is JSON, the raw text otherwise, or `null` when absent. */
|
|
5
|
+
body: unknown;
|
|
6
|
+
/** Request headers, keyed by lowercased header name. */
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
/** Uppercased HTTP method of the observed request. */
|
|
9
|
+
method: string;
|
|
10
|
+
/** The request URL: fully-qualified, or origin-relative for the stub backend. */
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
/** The request half of a stub: an absolute URL, or a path form (`/articles/{{uuid}}`) matching any origin. */
|
|
14
|
+
type StubRequest = {
|
|
15
|
+
/** Adapter name: `http` | `openai` | `anthropic`. */
|
|
16
|
+
adapter: string;
|
|
17
|
+
/** HTTP method to match. `*` matches any method. */
|
|
18
|
+
method: string;
|
|
19
|
+
/** Absolute URL (string | RegExp) or an any-origin path form (`/articles/{{uuid}}`). */
|
|
20
|
+
url: RegExp | string;
|
|
21
|
+
/** Optional request matcher; the stub only fires if this returns true. */
|
|
22
|
+
match?: ((request: MatchableRequest) => boolean) | undefined;
|
|
23
|
+
/** Header names, case-insensitive, whose presence keeps the stub from firing; `http.*` writes them from `without.headers`. */
|
|
24
|
+
absentHeaders?: readonly string[] | undefined;
|
|
25
|
+
/** Transform raw data into a provider-specific response envelope. */
|
|
26
|
+
wrap: (data: unknown) => StubResponse;
|
|
27
|
+
};
|
|
28
|
+
/** The response half of a stub. */
|
|
29
|
+
type StubResponse = {
|
|
30
|
+
/** HTTP status code (default: 200). */
|
|
31
|
+
status?: number;
|
|
32
|
+
/** Response body: an object is JSON, a string text, `null` empty, a `StreamBody` arrives in pieces. */
|
|
33
|
+
body: unknown;
|
|
34
|
+
headers?: Record<string, string> | undefined;
|
|
35
|
+
/** Delay in ms before responding (for timeout testing). */
|
|
36
|
+
delay?: number | undefined;
|
|
37
|
+
/** A transport failure instead of a reply: `fetch` rejects, as no status code can express. */
|
|
38
|
+
transport?: 'network-error' | undefined;
|
|
39
|
+
};
|
|
40
|
+
/** Each adapter serialises an object as JSON, so a stream declared as a plain value would arrive as `{}`: the tag tells them apart. */
|
|
41
|
+
declare const STREAM_BODY = "@jterrazz/test:stream";
|
|
42
|
+
/** A body that arrives in pieces, as `http.stream()` and `http.sse()` build it. */
|
|
43
|
+
type StreamBody = {
|
|
44
|
+
/** The pieces, written in order. */
|
|
45
|
+
chunks: readonly string[];
|
|
46
|
+
/** The `content-type` the stream is served under. */
|
|
47
|
+
contentType: string;
|
|
48
|
+
/** Milliseconds between two chunks. Default 0: everything at once. */
|
|
49
|
+
delayBetweenChunks: number;
|
|
50
|
+
kind: typeof STREAM_BODY;
|
|
51
|
+
};
|
|
52
|
+
/** A response computed from the observed request at serve time. */
|
|
53
|
+
type StubResponder = (request: MatchableRequest) => StubResponse;
|
|
54
|
+
/** A fixed `StubResponse`, or a `StubResponder` evaluated per served request. */
|
|
55
|
+
type StubResponseValue = StubResponder | StubResponse;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/stubs/stub.d.ts
|
|
58
|
+
/** A declared external interaction: what to match and what to reply. */
|
|
59
|
+
type Stub = {
|
|
60
|
+
/** Which outgoing call this stub speaks for. */
|
|
61
|
+
request: StubRequest;
|
|
62
|
+
/** A fixed reply, or a function of the observed request. */
|
|
63
|
+
response: StubResponseValue;
|
|
64
|
+
/** How many times it may serve; omitted is unlimited. `0` with `required` is a never stub: docs/reference/stubs.md#never-a-call-that-must-not-happen. */
|
|
65
|
+
times?: number;
|
|
66
|
+
/** Fail the chain unless it was requested: exactly `times` times when set, so `times: 0` fails it once requested. */
|
|
67
|
+
required?: boolean;
|
|
68
|
+
};
|
|
69
|
+
/** A composite of stubs; `.with()` derives a variant without touching the original. */
|
|
70
|
+
type Stubs = {
|
|
71
|
+
/** The flattened stubs, in selection order. */
|
|
72
|
+
readonly stubs: readonly Stub[];
|
|
73
|
+
/** Overrides replace base stubs of the same route and are prepended, so a more specific override wins first match. */
|
|
74
|
+
with: (...overrides: (Stub | Stub[] | Stubs)[]) => Stubs;
|
|
75
|
+
};
|
|
76
|
+
/** Any accepted stub input: one, a list, or a composite. */
|
|
77
|
+
type StubInput = Stub | Stub[] | Stubs;
|
|
78
|
+
declare function defineStub(stub: Stub): Stub;
|
|
79
|
+
/** Compose stubs, lists and composites, order preserved; `.with()` derives a scenario. */
|
|
80
|
+
declare function defineStubs(...items: StubInput[]): Stubs;
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region lint/kit/project/tokens.d.ts
|
|
83
|
+
declare const TOKEN_KINDS: readonly ["any", "base64", "date", "duration", "email", "float", "hex", "int", "ip", "iso8601", "number", "path", "port", "semver", "sha", "string", "time", "ulid", "url", "uuid", "workdir"];
|
|
84
|
+
type TokenKind = (typeof TOKEN_KINDS)[number];
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/expectations/tokens/match.d.ts
|
|
87
|
+
/** The frozen token vocabulary (rule `no-unknown-token`) plus the code-only kinds. */
|
|
88
|
+
type MatcherKind = 'any' | 'base64' | 'date' | 'duration' | 'email' | 'float' | 'hex' | 'includes' | 'int' | 'ip' | 'iso8601' | 'number' | 'path' | 'port' | 'ref' | 'regex' | 'semver' | 'sha' | 'string' | 'time' | 'ulid' | 'url' | 'uuid' | 'workdir';
|
|
89
|
+
/** A dynamic-value matcher, created through the `match` factories. */
|
|
90
|
+
declare class Matcher {
|
|
91
|
+
/** For kind 'includes': the substring the actual value must contain. */
|
|
92
|
+
readonly includes?: string | undefined;
|
|
93
|
+
readonly kind: MatcherKind;
|
|
94
|
+
/** For kind 'ref': the capture to assert inequality against. */
|
|
95
|
+
readonly notRef?: string | undefined;
|
|
96
|
+
/** For kind 'ref': the capture name. */
|
|
97
|
+
readonly refName?: string | undefined;
|
|
98
|
+
/** For kind 'regex': the pattern the actual value must match. */
|
|
99
|
+
readonly regex?: RegExp | undefined;
|
|
100
|
+
constructor(kind: MatcherKind, options?: {
|
|
101
|
+
includes?: string | undefined;
|
|
102
|
+
notRef?: string | undefined;
|
|
103
|
+
refName?: string | undefined;
|
|
104
|
+
regex?: RegExp | undefined;
|
|
105
|
+
});
|
|
106
|
+
/** Placeholder-style rendering used in failure diffs and serialization. */
|
|
107
|
+
toString(): string;
|
|
108
|
+
toJSON(): string;
|
|
109
|
+
}
|
|
110
|
+
type TypedMatcher = () => Matcher;
|
|
111
|
+
/** Dynamic-value matchers, the code-side mirror of the `{{token}}` grammar (`no-unknown-token`). */
|
|
112
|
+
type MatchFactories = Record<TokenKind, TypedMatcher> & {
|
|
113
|
+
includes: (substring: string) => Matcher;
|
|
114
|
+
ref: (name: string, options?: {
|
|
115
|
+
not?: string;
|
|
116
|
+
}) => Matcher;
|
|
117
|
+
regex: (regex: RegExp) => Matcher;
|
|
118
|
+
};
|
|
119
|
+
declare const match: MatchFactories;
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/stubs/kinds/text-filter.d.ts
|
|
122
|
+
/** A text filter on a provider request builder: a string is exact, a `RegExp` or `match.*` loosens it. */
|
|
123
|
+
type TextFilter = Matcher | RegExp | string;
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/stubs/kinds/anthropic.d.ts
|
|
126
|
+
type AnthropicMessagesFilter = {
|
|
127
|
+
model?: TextFilter;
|
|
128
|
+
system?: TextFilter;
|
|
129
|
+
user?: TextFilter;
|
|
130
|
+
tools?: string[];
|
|
131
|
+
};
|
|
132
|
+
/** Init options for a streamed Anthropic reply. */
|
|
133
|
+
type AnthropicStreamInit = {
|
|
134
|
+
/** Milliseconds between two events. Default 0: every event at once. */
|
|
135
|
+
delay?: number;
|
|
136
|
+
};
|
|
137
|
+
/** Anthropic API stub helpers. */
|
|
138
|
+
declare const anthropic: {
|
|
139
|
+
/** Match Messages API calls, optionally through a gateway URL; a string filter is exact equality. */
|
|
140
|
+
messages(filter?: AnthropicMessagesFilter, url?: string): StubRequest;
|
|
141
|
+
/** A stub the chain fails on if the subject reaches this endpoint: `http.never()`. */
|
|
142
|
+
never(request: StubRequest): Stub;
|
|
143
|
+
/** Response: data wrapped in the Messages format. */
|
|
144
|
+
reply(data: unknown): StubResponse;
|
|
145
|
+
/** Response: the text streamed as server-sent events, one `text_delta` per piece. */
|
|
146
|
+
stream(pieces: readonly string[], init?: AnthropicStreamInit): StubResponse;
|
|
147
|
+
/** Response: return an Anthropic error. */
|
|
148
|
+
error(status: number, message?: string): StubResponse;
|
|
149
|
+
/** Response: simulate a timeout. */
|
|
150
|
+
timeout(): StubResponse;
|
|
151
|
+
};
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/stubs/kinds/http-filter.d.ts
|
|
154
|
+
/** Request filters; a request matches when every provided field matches. */
|
|
155
|
+
type HttpStubFilter = {
|
|
156
|
+
/** An object is a deep subset match (leaves may be `match.*`); a string is containment, a RegExp `test()`s the raw body. */
|
|
157
|
+
body?: object | RegExp | string;
|
|
158
|
+
/** Header subset. Names are case-insensitive; string = exact value, RegExp = `test()`. */
|
|
159
|
+
headers?: Record<string, RegExp | string>;
|
|
160
|
+
/** Query-param subset. string = exact value, RegExp = `test()`. */
|
|
161
|
+
query?: Record<string, RegExp | string>;
|
|
162
|
+
/** Headers the request must not carry; a name present with any value keeps the stub from firing. */
|
|
163
|
+
without?: {
|
|
164
|
+
headers?: readonly string[];
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/stubs/kinds/http.d.ts
|
|
169
|
+
/** Init options for a streamed reply. */
|
|
170
|
+
type HttpStreamInit = {
|
|
171
|
+
/** The `content-type` the stream is served under. Default `application/octet-stream`. */
|
|
172
|
+
contentType?: string;
|
|
173
|
+
/** Milliseconds between two chunks. Default 0: every chunk at once. */
|
|
174
|
+
delay?: number;
|
|
175
|
+
/** Response headers, merged over the builder's own. */
|
|
176
|
+
headers?: Record<string, string>;
|
|
177
|
+
/** HTTP status code. Default 200. */
|
|
178
|
+
status?: number;
|
|
179
|
+
};
|
|
180
|
+
/** One server-sent event, as `http.sse()` frames it. */
|
|
181
|
+
type SseEvent = {
|
|
182
|
+
/** The `data:` payload. An object is serialised as JSON; a string is sent as-is. */
|
|
183
|
+
data: unknown;
|
|
184
|
+
/** The `event:` name. Omitted for an unnamed (default `message`) event. */
|
|
185
|
+
event?: string;
|
|
186
|
+
/** The `id:` the client echoes as `Last-Event-ID` when it reconnects. */
|
|
187
|
+
id?: string;
|
|
188
|
+
/** The `retry:` hint, in milliseconds. */
|
|
189
|
+
retry?: number;
|
|
190
|
+
};
|
|
191
|
+
/** Init options shared by the response builders. */
|
|
192
|
+
type HttpResponseInit = {
|
|
193
|
+
/** Delay in ms before responding (for timeout testing). */
|
|
194
|
+
delay?: number;
|
|
195
|
+
/** Response headers, merged over the builder's own. */
|
|
196
|
+
headers?: Record<string, string>;
|
|
197
|
+
/** HTTP status code. */
|
|
198
|
+
status?: number;
|
|
199
|
+
};
|
|
200
|
+
/** Generic HTTP stub helpers: an absolute URL, or a path form (`/articles/{{uuid}}`) matching any origin. */
|
|
201
|
+
declare const http: {
|
|
202
|
+
any(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
203
|
+
delete(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
204
|
+
get(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
205
|
+
patch(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
206
|
+
post(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
207
|
+
put(url: RegExp | string, filter?: HttpStubFilter): StubRequest;
|
|
208
|
+
/** A stub the chain fails on if the subject reaches its route: `required` with `times: 0`. */
|
|
209
|
+
never(request: StubRequest): Stub;
|
|
210
|
+
/** Response: a body-less reply (204 by default). */
|
|
211
|
+
empty(status?: number): StubResponse;
|
|
212
|
+
/** Response: an error status. Without a body, `{ error: 'HTTP <status>' }`. */
|
|
213
|
+
error(status: number, body?: unknown): StubResponse;
|
|
214
|
+
/** Response: a JSON body (200 by default). */
|
|
215
|
+
json(body: unknown, init?: HttpResponseInit): StubResponse;
|
|
216
|
+
/** Response: no response at all; `fetch` rejects, as when no server is running. */
|
|
217
|
+
unreachable(): StubResponse;
|
|
218
|
+
/** Response: a body that arrives in pieces, written in order. */
|
|
219
|
+
stream(chunks: readonly string[], init?: HttpStreamInit): StubResponse;
|
|
220
|
+
/** Response: a server-sent event stream, served as `text/event-stream`. */
|
|
221
|
+
sse(events: readonly SseEvent[], init?: Omit<HttpStreamInit, "contentType">): StubResponse;
|
|
222
|
+
/** Response: a text body, served as `text/plain` (200 by default). */
|
|
223
|
+
text(body: string, init?: HttpResponseInit): StubResponse;
|
|
224
|
+
};
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region src/stubs/kinds/openai.d.ts
|
|
227
|
+
type OpenAIChatFilter = {
|
|
228
|
+
model?: TextFilter;
|
|
229
|
+
system?: TextFilter;
|
|
230
|
+
user?: TextFilter;
|
|
231
|
+
tools?: string[];
|
|
232
|
+
temperature?: number;
|
|
233
|
+
};
|
|
234
|
+
type OpenAIResponsesFilter = {
|
|
235
|
+
model?: TextFilter;
|
|
236
|
+
system?: TextFilter;
|
|
237
|
+
user?: TextFilter;
|
|
238
|
+
tools?: string[];
|
|
239
|
+
};
|
|
240
|
+
type OpenAIStreamInit = {
|
|
241
|
+
/** The API whose stream is served: Chat Completions (default) or Responses. */
|
|
242
|
+
api?: 'chat' | 'responses';
|
|
243
|
+
/** Milliseconds between two events. Default 0: every event at once. */
|
|
244
|
+
delay?: number;
|
|
245
|
+
/** The tokens the stream reports it spent: a Chat Completions stream ends on a usage chunk, as `stream_options.include_usage` asks, and a Responses stream carries them in its completed response. Default 10 and 10. */
|
|
246
|
+
usage?: {
|
|
247
|
+
completionTokens: number;
|
|
248
|
+
promptTokens: number;
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
/** OpenAI API stub helpers. */
|
|
252
|
+
declare const openai: {
|
|
253
|
+
/** Match Chat Completions calls, at `url` where the client reaches another host; a string filter is exact equality, a RegExp or `match.includes` loosens it. */
|
|
254
|
+
chat(filter?: OpenAIChatFilter, url?: string): StubRequest;
|
|
255
|
+
/** Match Responses API calls; a JSON file is wrapped in the Responses envelope. */
|
|
256
|
+
responses(filter?: OpenAIResponsesFilter, url?: string): StubRequest;
|
|
257
|
+
/** A stub the chain fails on if the subject reaches this endpoint: `http.never()`. */
|
|
258
|
+
never(request: StubRequest): Stub;
|
|
259
|
+
/** Response: data wrapped in the Chat Completions format. */
|
|
260
|
+
reply(data: unknown): StubResponse;
|
|
261
|
+
/** Response: the text streamed as server-sent events; `api` picks Chat Completions (default) or Responses. */
|
|
262
|
+
stream(pieces: readonly string[], init?: OpenAIStreamInit): StubResponse;
|
|
263
|
+
/** Response: return an OpenAI error. */
|
|
264
|
+
error(status: number, message?: string): StubResponse;
|
|
265
|
+
/** Response: return malformed content. */
|
|
266
|
+
malformed(content: string): StubResponse;
|
|
267
|
+
/** Response: simulate a timeout. */
|
|
268
|
+
timeout(): StubResponse;
|
|
269
|
+
};
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/stubs/intercept/intercept.d.ts
|
|
272
|
+
/** Disposed at the end of the declaring scope: handlers dropped, an unmatched request thrown. */
|
|
273
|
+
type InterceptScope = AsyncDisposable;
|
|
274
|
+
/** What a scope may state about the network it declares. */
|
|
275
|
+
type InterceptOptions = {
|
|
276
|
+
/** The base a relative request resolves against for the life of the scope; under node `fetch('/api/posts')` cannot parse. */
|
|
277
|
+
origin?: string;
|
|
278
|
+
};
|
|
279
|
+
/** The module-scope network double; awaited, so the network double listens before the subject runs. */
|
|
280
|
+
type Intercept = ((stubs: StubInput, options?: InterceptOptions) => Promise<InterceptScope>) & ((request: StubRequest, response: StubResponder | StubResponse, options?: InterceptOptions) => Promise<InterceptScope>);
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/stubs/delivery/same-process/intercept.d.ts
|
|
283
|
+
/** The module-scope network double, on msw's node server. */
|
|
284
|
+
declare const intercept: Intercept;
|
|
285
|
+
//#endregion
|
|
286
|
+
export { StubRequest as C, StubResponseValue as E, StreamBody as S, StubResponse as T, StubInput as _, openai as a, defineStubs as b, SseEvent as c, anthropic as d, TextFilter as f, Stub as g, match as h, InterceptScope as i, http as l, MatcherKind as m, Intercept as n, HttpResponseInit as o, Matcher as p, InterceptOptions as r, HttpStreamInit as s, intercept as t, HttpStubFilter as u, Stubs as v, StubResponder as w, MatchableRequest as x, defineStub as y };
|
|
287
|
+
//# sourceMappingURL=shared-index.stubs.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region lint/kit/project/json-shape.ts
|
|
2
|
+
/** `JSON.parse` answers `any`: these read a parsed value field by field, and a field of another shape reads as absent. */
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
/** What a text that is no JSON stands for is the caller's to say. */
|
|
7
|
+
function parsedJson(text, otherwise) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(text);
|
|
10
|
+
} catch {
|
|
11
|
+
return otherwise;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { parsedJson as n, isRecord as t };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=shared-json-shape.js.map
|