@jterrazz/test 18.1.0 → 18.3.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 +1 -1
- package/dist/checker.js +5 -5
- package/dist/config.js +1 -1
- package/dist/index.d.ts +205 -64
- package/dist/index.js +615 -51
- package/dist/oxlint.cjs +1 -1
- package/dist/shared-exchange.js +1 -1
- package/dist/shared-in-place.js +1 -1
- package/dist/shared-manifest.js +1 -1
- package/dist/shared-route-coverage.global-setup.js +1 -1
- package/dist/shared-session-ledger.js +1 -1
- package/dist/shared-stub-server.js +13 -0
- package/dist/shared-testcontainers.adapter.js +1 -1
- package/dist/stubs.js +1 -1
- package/dist/vitest.js +1 -1
- package/docs/README.md +1 -1
- package/docs/concepts/architecture.md +12 -12
- package/docs/guides/api-specs.md +172 -3
- package/docs/guides/website-specs.md +1 -1
- package/docs/reference/assertions.md +8 -0
- package/docs/reference/glossary.md +1 -0
- package/docs/reference/linting.md +1 -1
- package/docs/reference/tokens.md +1 -0
- package/docs/start/getting-started.md +1 -1
- package/docs/start/set-up-a-project.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ An ES module project on Node 24, vitest 5 and `@jterrazz/typescript` 11 is requi
|
|
|
52
52
|
| [Component](docs/guides/component-specs.md) | A React component, hook or DOM function in a real Chromium | `component.render()` |
|
|
53
53
|
| [Website](docs/guides/website-specs.md) | A served page, fetched or driven in a browser | `specification.website()` |
|
|
54
54
|
| [Mobile](docs/guides/mobile-specs.md) | A native app on an iOS simulator | `specification.mobile()` |
|
|
55
|
-
| [API](docs/guides/api-specs.md) | An HTTP app,
|
|
55
|
+
| [API](docs/guides/api-specs.md) | An HTTP app, in this process or deployed at a `url` | `specification.api()` |
|
|
56
56
|
| [Job](docs/guides/job-specs.md) | A pipeline triggered by name | `specification.job()` |
|
|
57
57
|
| [CLI](docs/guides/cli-specs.md) | A binary in a fresh working directory, often as a YAML document | `specification.cli()` |
|
|
58
58
|
| [Lint](docs/guides/lint-specs.md) | The rules a project ships, over fixture trees | `specification.lint()` |
|
package/dist/checker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as parsedJson } from "./shared-json-shape.js";
|
|
2
1
|
import { t as CATALOGUE_CHAPTER } from "./shared-chapter.js";
|
|
2
|
+
import { n as parsedJson } from "./shared-json-shape.js";
|
|
3
3
|
import { i as findUnknownTokens, n as findKnownTokens, r as findMalformedRefs, t as TOKEN_KINDS } from "./shared-tokens.js";
|
|
4
4
|
import { a as RUN_KEYS, c as isRelativePath, o as SPEC_EXTENSION, s as SpecSyntaxError, t as DOCUMENT_KEYS } from "./shared-spec-grammar.js";
|
|
5
5
|
import { i as literalEnd, n as argumentsOf, o as openersAt, r as closingOf, s as skipString, t as argumentSpans } from "./shared-source-scan.js";
|
|
@@ -1767,16 +1767,16 @@ function firstLine(text) {
|
|
|
1767
1767
|
}
|
|
1768
1768
|
const GRAMMAR = {
|
|
1769
1769
|
request: {
|
|
1770
|
-
line: /^(?<method>GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)
|
|
1770
|
+
line: /^(?<method>GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS) (?:\/|https?:\/\/)/u,
|
|
1771
1771
|
teaching: (name) => ({
|
|
1772
|
-
fix: `start ${name} with its request line, \`GET /path\` or another method`,
|
|
1772
|
+
fix: `start ${name} with its request line, \`GET /path\`, \`GET https://host/path\` or another method`,
|
|
1773
1773
|
found: `the first line of ${name} is no request line`
|
|
1774
1774
|
})
|
|
1775
1775
|
},
|
|
1776
1776
|
response: {
|
|
1777
|
-
line: /^HTTP\/\d(?:\.\d)? \d{3}\b/u,
|
|
1777
|
+
line: /^(?:HTTP\/\d(?:\.\d)? \d{3}\b|unreachable: \S)/u,
|
|
1778
1778
|
teaching: (name) => ({
|
|
1779
|
-
fix: `start ${name} with its status line, \`HTTP/1.1 200 OK\` or the status it expects
|
|
1779
|
+
fix: `start ${name} with its status line, \`HTTP/1.1 200 OK\` or the status it expects, or \`unreachable: <reason>\``,
|
|
1780
1780
|
found: `the first line of ${name} is no status line`
|
|
1781
1781
|
})
|
|
1782
1782
|
}
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as isRecord } from "./shared-json-shape.js";
|
|
2
1
|
import { t as CATALOGUE_CHAPTER } from "./shared-chapter.js";
|
|
2
|
+
import { t as isRecord } from "./shared-json-shape.js";
|
|
3
3
|
import { n as specificationModules, t as derivedProjects } from "./shared-derived-projects.js";
|
|
4
4
|
import { t as TEST_SECTION } from "./shared-test-section.js";
|
|
5
5
|
import { n as recommendedRules, t as consumerRows } from "./shared-manifest.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -279,6 +279,15 @@ type ServerResponse = {
|
|
|
279
279
|
body: unknown;
|
|
280
280
|
/** Response headers as a flat key-value map. */
|
|
281
281
|
headers: Record<string, string>;
|
|
282
|
+
/** Why no response came back (`refused`, `timeout`, `dns`, `tls CERT_HAS_EXPIRED` ...): set only when the exchange never answered, and then the status is 0, the headers empty and the body null. */
|
|
283
|
+
unreachable?: string | undefined;
|
|
284
|
+
};
|
|
285
|
+
/** What update mode writes into a golden that states nothing yet: which headers it records, and whether a golden stating no body keeps stating none. */
|
|
286
|
+
type ResponseRecording = {
|
|
287
|
+
/** A golden that states no body keeps stating none: the body is claimed by writing it. */
|
|
288
|
+
readonly bodyKeptAbsent: boolean;
|
|
289
|
+
/** The header names a fresh golden records, those the response carries. */
|
|
290
|
+
readonly headers: readonly string[];
|
|
282
291
|
};
|
|
283
292
|
/** Read-only accessor for an HTTP response, compared by `expect(...).toMatch(...)`. */
|
|
284
293
|
declare class ResponseAccessor {
|
|
@@ -288,12 +297,173 @@ declare class ResponseAccessor {
|
|
|
288
297
|
readonly captures: CaptureScope;
|
|
289
298
|
/** Response headers as a flat, lower-cased key-value map. */
|
|
290
299
|
readonly headers: Record<string, string>;
|
|
300
|
+
/** @internal */
|
|
301
|
+
readonly recording: ResponseRecording;
|
|
291
302
|
readonly status: number;
|
|
292
303
|
/** @internal */
|
|
293
304
|
readonly testDir: string;
|
|
294
|
-
|
|
305
|
+
/** Why the exchange never answered, a golden's `unreachable: <reason>` line; undefined when it answered. */
|
|
306
|
+
readonly unreachable: string | undefined;
|
|
307
|
+
constructor(response: ServerResponse, testDir: string, captures?: CaptureScope, recording?: ResponseRecording);
|
|
308
|
+
}
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/specifications/api/deployed/tls-facts.d.ts
|
|
311
|
+
/** The certificate an HTTPS exchange was presented, and what the client made of it. */
|
|
312
|
+
type TlsFacts = {
|
|
313
|
+
/** The names the certificate is valid for (its subjectAltName), each without its `DNS:` or `IP Address:` prefix. */
|
|
314
|
+
readonly altNames: readonly string[];
|
|
315
|
+
/** The code the trust check refused with (`DEPTH_ZERO_SELF_SIGNED_CERT`, `CERT_HAS_EXPIRED`, `ERR_TLS_CERT_ALTNAME_INVALID` ...), undefined when trusted. */
|
|
316
|
+
readonly authorizationError: string | undefined;
|
|
317
|
+
/** Whether the certificate chains to a trusted authority and covers the URL's host. */
|
|
318
|
+
readonly authorized: boolean;
|
|
319
|
+
/** Whole days from the exchange to `validTo`, negative once it has expired. */
|
|
320
|
+
readonly daysRemaining: number;
|
|
321
|
+
/** The issuer's common name, or its organisation when it states none. */
|
|
322
|
+
readonly issuer: string;
|
|
323
|
+
/** The TLS version negotiated (`TLSv1.3`). */
|
|
324
|
+
readonly protocol: string | undefined;
|
|
325
|
+
/** The subject's common name; empty when it states none. */
|
|
326
|
+
readonly subject: string;
|
|
327
|
+
readonly validFrom: Date;
|
|
328
|
+
readonly validTo: Date;
|
|
329
|
+
/** Whether the certificate is valid for `host`, wildcards read as a client reads them. */
|
|
330
|
+
covers: (host: string) => boolean;
|
|
331
|
+
};
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region src/specifications/api/deployed/exchange.result.d.ts
|
|
334
|
+
/** What one request to a deployed api hands back: the response, or why none came, and the certificate it came over; no table and no disk, which a deployed api keeps to itself. */
|
|
335
|
+
declare class ExchangeResult {
|
|
336
|
+
private readonly answer;
|
|
337
|
+
private readonly recording;
|
|
338
|
+
private readonly scope;
|
|
339
|
+
private readonly testDir;
|
|
340
|
+
/** The certificate an https request was presented and the trust check's verdict; undefined over http, or when no handshake completed. */
|
|
341
|
+
readonly tls: TlsFacts | undefined;
|
|
342
|
+
constructor(options: {
|
|
343
|
+
recording: ResponseRecording;
|
|
344
|
+
response: ServerResponse;
|
|
345
|
+
testDir: string;
|
|
346
|
+
tls: TlsFacts | undefined;
|
|
347
|
+
});
|
|
348
|
+
/** The whole response (status, headers, body), or `unreachable: <reason>`, compared whole: `toMatch(<.http text>)` or `toMatch(file(...))`. */
|
|
349
|
+
get response(): ResponseAccessor;
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/chain/action.d.ts
|
|
353
|
+
type SliceReader = <Slice>(capability: {
|
|
354
|
+
readonly initial: Slice;
|
|
355
|
+
readonly name: string;
|
|
356
|
+
}) => Slice;
|
|
357
|
+
type Action<Name extends string, Args extends readonly unknown[], Result, Signature extends ChainSignature = ChainSignature, Needs extends object = Record<never, never>, Config extends ChainConfig = ChainConfig> = {
|
|
358
|
+
readonly accessors: readonly MatrixRow[];
|
|
359
|
+
readonly targets?: readonly MatrixRow[];
|
|
360
|
+
readonly kind: 'action';
|
|
361
|
+
readonly name: Name;
|
|
362
|
+
readonly options?: readonly ActionOption<string>[];
|
|
363
|
+
readonly row: MatrixRow;
|
|
364
|
+
/** A type alone, never set at runtime: `ChainOf` reads it. */
|
|
365
|
+
readonly signature?: Signature;
|
|
366
|
+
readonly verbs?: readonly MatrixRow[];
|
|
367
|
+
prepare?(args: Args, read: SliceReader): Promise<{
|
|
368
|
+
readonly workDir: null | string;
|
|
369
|
+
}> | {
|
|
370
|
+
readonly workDir: null | string;
|
|
371
|
+
};
|
|
372
|
+
perform(args: Args, read: SliceReader, adapters: Needs, run: Run<Config>): Promise<Result>;
|
|
373
|
+
};
|
|
374
|
+
type AnyAction = Action<string, readonly unknown[], unknown, ChainSignature, object>;
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/specifications/api/deployed/request.action.d.ts
|
|
377
|
+
type ExchangeSignature = ChainSignature & {
|
|
378
|
+
readonly chain: {
|
|
379
|
+
/** Send a GET to a URL, written whole or as a path from the specification's `url`, and resolve with what came back. */
|
|
380
|
+
get: (target: string) => Promise<ExchangeResult>;
|
|
381
|
+
/** Send a complete request: its `.http` text written in the test, or `file('./__requests__/<name>.http')`; its first line names the URL whole or a path. */
|
|
382
|
+
request: (source: DiskFile<'.http'> | string) => Promise<ExchangeResult>;
|
|
383
|
+
};
|
|
384
|
+
};
|
|
385
|
+
//#endregion
|
|
386
|
+
//#region src/specifications/api/deployed/connect.capability.d.ts
|
|
387
|
+
type ConnectChain<Self> = {
|
|
388
|
+
/** Open the socket on this address instead of the URL's host and port, as curl's `--connect-to`: the Host header and the TLS server name stay the URL's; a later call wins. */
|
|
389
|
+
connect: (address: string) => Self;
|
|
390
|
+
};
|
|
391
|
+
interface ConnectSignature extends ChainSignature {
|
|
392
|
+
readonly chain: ConnectChain<this['self']>;
|
|
393
|
+
}
|
|
394
|
+
//#endregion
|
|
395
|
+
//#region src/chain/context/headers.capability.d.ts
|
|
396
|
+
type HeadersMethod<Self> = (headers: Record<string, string>) => Self;
|
|
397
|
+
type HeadersChain<Self> = {
|
|
398
|
+
/** Set HTTP headers for the exchange. Multiple calls merge. */
|
|
399
|
+
headers: HeadersMethod<Self>;
|
|
400
|
+
};
|
|
401
|
+
interface HeadersSignature extends ChainSignature {
|
|
402
|
+
readonly chain: HeadersChain<this['self']>;
|
|
295
403
|
}
|
|
296
404
|
//#endregion
|
|
405
|
+
//#region src/chain/define-specification.d.ts
|
|
406
|
+
type Composition = {
|
|
407
|
+
readonly actions: readonly AnyAction[];
|
|
408
|
+
readonly capabilities: readonly (AnyCapability | Sharing)[];
|
|
409
|
+
readonly options: Readonly<Record<string, MatrixRow>>;
|
|
410
|
+
};
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/chain/chain.d.ts
|
|
413
|
+
type Names<List extends readonly {
|
|
414
|
+
readonly name: string;
|
|
415
|
+
}[]> = List[number]['name'];
|
|
416
|
+
type ContextOf<C extends Composition> = C['capabilities'][number] extends (infer Member) ? Member extends Capability<string, infer _Slice, infer _Args, infer _Signature, infer _Needs, infer Key> ? Key : never : never;
|
|
417
|
+
type SharingOf<C extends Composition, Self> = 'with' extends Names<C['capabilities']> ? {
|
|
418
|
+
with: (context: Pick<ChainContext, ContextOf<C>>) => Self;
|
|
419
|
+
} : unknown;
|
|
420
|
+
type MethodsOf<Member, P extends SpecificationParams, Self> = Member extends {
|
|
421
|
+
readonly signature?: infer Signature;
|
|
422
|
+
} ? Signature extends ChainSignature ? (Signature & {
|
|
423
|
+
readonly params: P;
|
|
424
|
+
readonly self: Self;
|
|
425
|
+
})['chain'] : never : never;
|
|
426
|
+
type Methods<C extends Composition, P extends SpecificationParams, Self> = Intersect<MethodsOf<C['actions'][number] | C['capabilities'][number], P, Self>>;
|
|
427
|
+
type ChainOf<C extends Composition, P extends SpecificationParams, Self> = Pick<Methods<C, P, Self>, Extract<Names<C['actions']> | Names<C['capabilities']>, keyof Methods<C, P, Self>>> & SharingOf<C, Self>;
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region src/specifications/api/deployed/deployed.composition.d.ts
|
|
430
|
+
declare const composition$8: {
|
|
431
|
+
readonly actions: readonly [Action<"request", [source: string | DiskFile<".http">], ExchangeResult, ExchangeSignature, Record<never, never>, ApiDeployedConfig>, Action<"get", [target: string], ExchangeResult, ExchangeSignature, Record<never, never>, ApiDeployedConfig>];
|
|
432
|
+
readonly capabilities: readonly [Capability<"connect", string | null, [address: string], ConnectSignature, Record<never, never>, never, ChainConfig>, Capability<"headers", Readonly<Record<string, string>>, [headers: Record<string, string>], HeadersSignature, Record<never, never>, "headers", ChainConfig>, Sharing];
|
|
433
|
+
readonly options: {
|
|
434
|
+
ca: {
|
|
435
|
+
group: "Constructor option";
|
|
436
|
+
name: string;
|
|
437
|
+
probe: string;
|
|
438
|
+
};
|
|
439
|
+
insecure: {
|
|
440
|
+
group: "Constructor option";
|
|
441
|
+
name: string;
|
|
442
|
+
probe: string;
|
|
443
|
+
};
|
|
444
|
+
recordedHeaders: {
|
|
445
|
+
group: "Constructor option";
|
|
446
|
+
name: string;
|
|
447
|
+
probe: string;
|
|
448
|
+
};
|
|
449
|
+
timeout: {
|
|
450
|
+
group: "Constructor option";
|
|
451
|
+
name: string;
|
|
452
|
+
probe: string;
|
|
453
|
+
};
|
|
454
|
+
url: {
|
|
455
|
+
group: "Constructor option";
|
|
456
|
+
name: string;
|
|
457
|
+
probe: string;
|
|
458
|
+
};
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
/** The chain `specification.api({ url })` hands out: requests to the deployed api, over the network. */
|
|
462
|
+
interface ApiDeployedSpecification extends ChainOf<typeof composition$8, {
|
|
463
|
+
databaseKey: string;
|
|
464
|
+
services: Record<string, unknown>;
|
|
465
|
+
}, ApiDeployedSpecification> {}
|
|
466
|
+
//#endregion
|
|
297
467
|
//#region src/specifications/api/server/server.port.d.ts
|
|
298
468
|
/** What a request carries beside its method, path and body. */
|
|
299
469
|
type ServerRequestOptions = {
|
|
@@ -334,30 +504,6 @@ type HonoApp = {
|
|
|
334
504
|
routes?: readonly TableEntry[];
|
|
335
505
|
};
|
|
336
506
|
//#endregion
|
|
337
|
-
//#region src/chain/action.d.ts
|
|
338
|
-
type SliceReader = <Slice>(capability: {
|
|
339
|
-
readonly initial: Slice;
|
|
340
|
-
readonly name: string;
|
|
341
|
-
}) => Slice;
|
|
342
|
-
type Action<Name extends string, Args extends readonly unknown[], Result, Signature extends ChainSignature = ChainSignature, Needs extends object = Record<never, never>, Config extends ChainConfig = ChainConfig> = {
|
|
343
|
-
readonly accessors: readonly MatrixRow[];
|
|
344
|
-
readonly targets?: readonly MatrixRow[];
|
|
345
|
-
readonly kind: 'action';
|
|
346
|
-
readonly name: Name;
|
|
347
|
-
readonly options?: readonly ActionOption<string>[];
|
|
348
|
-
readonly row: MatrixRow;
|
|
349
|
-
/** A type alone, never set at runtime: `ChainOf` reads it. */
|
|
350
|
-
readonly signature?: Signature;
|
|
351
|
-
readonly verbs?: readonly MatrixRow[];
|
|
352
|
-
prepare?(args: Args, read: SliceReader): Promise<{
|
|
353
|
-
readonly workDir: null | string;
|
|
354
|
-
}> | {
|
|
355
|
-
readonly workDir: null | string;
|
|
356
|
-
};
|
|
357
|
-
perform(args: Args, read: SliceReader, adapters: Needs, run: Run<Config>): Promise<Result>;
|
|
358
|
-
};
|
|
359
|
-
type AnyAction = Action<string, readonly unknown[], unknown, ChainSignature, object>;
|
|
360
|
-
//#endregion
|
|
361
507
|
//#region src/specifications/api/request/route.d.ts
|
|
362
508
|
type RouteParamNames<Path extends string> = Path extends `${infer Route}?${string}` ? RouteParamNames<Route> : Path extends `${string}/:${infer Rest}` ? Rest extends `${infer Name}/${infer Tail}` ? Name | RouteParamNames<`/${Tail}`> : Rest : never;
|
|
363
509
|
type RouteOptions<Path extends string> = [RouteParamNames<Path>] extends [never] ? {
|
|
@@ -402,16 +548,6 @@ interface ClockSignature extends ChainSignature {
|
|
|
402
548
|
readonly chain: ClockChain<this['self']>;
|
|
403
549
|
}
|
|
404
550
|
//#endregion
|
|
405
|
-
//#region src/chain/context/headers.capability.d.ts
|
|
406
|
-
type HeadersMethod<Self> = (headers: Record<string, string>) => Self;
|
|
407
|
-
type HeadersChain<Self> = {
|
|
408
|
-
/** Set HTTP headers for the exchange. Multiple calls merge. */
|
|
409
|
-
headers: HeadersMethod<Self>;
|
|
410
|
-
};
|
|
411
|
-
interface HeadersSignature extends ChainSignature {
|
|
412
|
-
readonly chain: HeadersChain<this['self']>;
|
|
413
|
-
}
|
|
414
|
-
//#endregion
|
|
415
551
|
//#region src/stubs/intercept/intercept.port.d.ts
|
|
416
552
|
type InterceptPort = {
|
|
417
553
|
/** Refuse the setup when this adapter cannot serve a stub at all. */
|
|
@@ -440,30 +576,6 @@ type SeedPort = {
|
|
|
440
576
|
readonly target: (database?: string) => DatabasePort;
|
|
441
577
|
};
|
|
442
578
|
//#endregion
|
|
443
|
-
//#region src/chain/define-specification.d.ts
|
|
444
|
-
type Composition = {
|
|
445
|
-
readonly actions: readonly AnyAction[];
|
|
446
|
-
readonly capabilities: readonly (AnyCapability | Sharing)[];
|
|
447
|
-
readonly options: Readonly<Record<string, MatrixRow>>;
|
|
448
|
-
};
|
|
449
|
-
//#endregion
|
|
450
|
-
//#region src/chain/chain.d.ts
|
|
451
|
-
type Names<List extends readonly {
|
|
452
|
-
readonly name: string;
|
|
453
|
-
}[]> = List[number]['name'];
|
|
454
|
-
type ContextOf<C extends Composition> = C['capabilities'][number] extends (infer Member) ? Member extends Capability<string, infer _Slice, infer _Args, infer _Signature, infer _Needs, infer Key> ? Key : never : never;
|
|
455
|
-
type SharingOf<C extends Composition, Self> = 'with' extends Names<C['capabilities']> ? {
|
|
456
|
-
with: (context: Pick<ChainContext, ContextOf<C>>) => Self;
|
|
457
|
-
} : unknown;
|
|
458
|
-
type MethodsOf<Member, P extends SpecificationParams, Self> = Member extends {
|
|
459
|
-
readonly signature?: infer Signature;
|
|
460
|
-
} ? Signature extends ChainSignature ? (Signature & {
|
|
461
|
-
readonly params: P;
|
|
462
|
-
readonly self: Self;
|
|
463
|
-
})['chain'] : never : never;
|
|
464
|
-
type Methods<C extends Composition, P extends SpecificationParams, Self> = Intersect<MethodsOf<C['actions'][number] | C['capabilities'][number], P, Self>>;
|
|
465
|
-
type ChainOf<C extends Composition, P extends SpecificationParams, Self> = Pick<Methods<C, P, Self>, Extract<Names<C['actions']> | Names<C['capabilities']>, keyof Methods<C, P, Self>>> & SharingOf<C, Self>;
|
|
466
|
-
//#endregion
|
|
467
579
|
//#region src/specifications/api/api.composition.d.ts
|
|
468
580
|
declare const composition$7: {
|
|
469
581
|
readonly actions: readonly [Action<"request", [source: string | DiskFile<".http">], HttpResult, RequestSignature, {
|
|
@@ -514,8 +626,8 @@ interface ApiSpecification<DatabaseKey extends string = string> extends ChainOf<
|
|
|
514
626
|
}, ApiSpecification<DatabaseKey>> {}
|
|
515
627
|
//#endregion
|
|
516
628
|
//#region src/specifications/api/api.handle.d.ts
|
|
517
|
-
/**
|
|
518
|
-
type
|
|
629
|
+
/** The app built in this process, from the services the specification starts. */
|
|
630
|
+
type ApiServedOptions<Services extends ServiceRecord = ServiceRecord> = {
|
|
519
631
|
/** Project root override; by default the nearest `package.json` above the specification file (`no-redundant-root`). */
|
|
520
632
|
root?: string;
|
|
521
633
|
/** The app factory: receives the started services record, returns the Hono app. */
|
|
@@ -523,7 +635,30 @@ type ApiSpecificationOptions<Services extends ServiceRecord = ServiceRecord> = {
|
|
|
523
635
|
/** Named infrastructure record: the keys are the `database` vocabulary, and name the init-script folder. */
|
|
524
636
|
services?: Services;
|
|
525
637
|
};
|
|
526
|
-
/**
|
|
638
|
+
/** The api already deployed, met over the network at its URL. */
|
|
639
|
+
type ApiDeployedOptions = {
|
|
640
|
+
/** A certificate authority trusted beside the ones node trusts: its PEM text, a value like any string. */
|
|
641
|
+
ca?: string;
|
|
642
|
+
/** Accept a certificate the trust check refuses (self-signed, expired, another host's); `result.tls` still says why. Default `false`. */
|
|
643
|
+
insecure?: boolean;
|
|
644
|
+
/** The headers update mode records into a golden that states none yet, those the response carries. Default `['content-type', 'location']`. */
|
|
645
|
+
recordedHeaders?: readonly string[];
|
|
646
|
+
/** The milliseconds one request may take, connection to last byte, before it reads `unreachable: timeout`. Default `5000`. */
|
|
647
|
+
timeout?: number;
|
|
648
|
+
/** The deployed api's base URL: a path is read from it (`.get('/health')`), a URL written whole reaches any host. */
|
|
649
|
+
url: string;
|
|
650
|
+
};
|
|
651
|
+
type Absent<Options> = { [Key in keyof Options]?: never; };
|
|
652
|
+
/** Options for {@link startApi | specification.api}: `server` or `url`, exclusive by type. */
|
|
653
|
+
type ApiSpecificationOptions<Services extends ServiceRecord = ServiceRecord> = (Absent<ApiDeployedOptions> & ApiServedOptions<Services>) | (Absent<ApiServedOptions> & ApiDeployedOptions);
|
|
654
|
+
type ApiDeployedConfig = ChainConfig & {
|
|
655
|
+
baseUrl: string;
|
|
656
|
+
ca: string | undefined;
|
|
657
|
+
insecure: boolean;
|
|
658
|
+
recording: ResponseRecording;
|
|
659
|
+
timeout: number;
|
|
660
|
+
};
|
|
661
|
+
/** What `specification.api({ server })` returns: `const { api, cleanup, docker } = ...` (`no-runner-alias`). */
|
|
527
662
|
type ApiHandle<DatabaseKey extends string = string> = {
|
|
528
663
|
api: ApiSpecification<DatabaseKey>;
|
|
529
664
|
/** Stop all infrastructure started by this specification. */
|
|
@@ -531,7 +666,13 @@ type ApiHandle<DatabaseKey extends string = string> = {
|
|
|
531
666
|
/** Read a running container by id. */
|
|
532
667
|
docker: (containerId: string) => ContainerAccessor;
|
|
533
668
|
};
|
|
534
|
-
|
|
669
|
+
/** What `specification.api({ url })` returns: `const { api, cleanup } = ...`; it starts nothing, so `cleanup` releases nothing and there is no container to read. */
|
|
670
|
+
type ApiDeployedHandle = {
|
|
671
|
+
api: ApiDeployedSpecification;
|
|
672
|
+
cleanup: () => Promise<void>;
|
|
673
|
+
};
|
|
674
|
+
declare function startApi(options: Absent<ApiServedOptions> & ApiDeployedOptions): Promise<ApiDeployedHandle>;
|
|
675
|
+
declare function startApi<Services extends ServiceRecord = ServiceRecord>(options: Absent<ApiDeployedOptions> & ApiServedOptions<Services>): Promise<ApiHandle<DatabaseKeys<Services>>>;
|
|
535
676
|
//#endregion
|
|
536
677
|
//#region src/services/startup/startup-report.d.ts
|
|
537
678
|
type AppInfo = {
|
|
@@ -1912,5 +2053,5 @@ declare module 'vitest' {
|
|
|
1912
2053
|
}
|
|
1913
2054
|
}
|
|
1914
2055
|
//#endregion
|
|
1915
|
-
export { type ApiHandle, type ApiSpecification, type ApiSpecificationOptions, type BaseResult, type BrowserConsoleMessage, type BrowserLinkElement, type BrowserMetaElement, type BrowserOpenOptions, type BrowserPage, type BrowserPort, type CallResult, type CaptureScope, type CliEnv, type CliHandle, type CliInput, type CliOutput, type CliPort, type CliResult, type CliSpecification, type CliSpecificationOptions, type ComponentChain, type ComponentScenario, type ComponentUi, type ComponentVisitor, type ContainerAccessor, type DeviceOpenOptions, type DevicePort, type DeviceScreen, type DeviceTimeouts, type DirectoryAccessor, type DiskDirectory, type DiskFile, type DiskTarget, type DockerSpecConfig, type DomMount, type ElementKind, type ElementMatch, type ExecOptions, type FetchResult, type FileAccessor, type FileAt, type FilesystemAccessor, type HonoApp, type HttpResult, type IntegrationHandle, type IntegrationSpecification, type IntegrationSpecificationOptions, type Job, type JobHandle, type JobResult, type JobSpecification, type JobSpecificationOptions, type JsonAccessor, type LandmarkKind, type LintConfig, type LintHandle, type LintResult, type LintRules, type LintRunOptions, type LintSpecification, type LintSpecificationOptions, type LiterateRunFlags, type LiterateServeRegistration, type MatchFixtureOptions, Matcher, type MatcherKind, type MobileBackendOptions, type MobileElementKind, type MobileElementMatch, type MobileHandle, type MobileScenario, type MobileSpecification, type MobileSpecificationOptions, type MobileVisitor, type MockOfOptions, type MockPort, type PackedPackage, type PageResult, type PinnedClock, type PositionedCases, type PositionedRuleTester, type PrepareStep, type RelativePath, type RenderResult, type RenderSubject, type RenderedText, type ResponseAccessor, type ScreenNode, type ScreenResult, type ServerPort, type ServerRequestOptions, type ServerResponse, type ServerSpec, type SpecDocument, type SpecEnvToken, type SpecFileAssertion, type SpecFixture, type SpecRun, type SpecServeEntry, type SpecStream, type TableAccessor, type Target, type TargetOptions, type TextAccessor, type VisitScenario, type WaitUntilOptions, type WebsiteBackendOptions, type WebsiteHandle, type WebsiteSpecification, type WebsiteSpecificationOptions, type WebsiteVisitor, directory, file, match };
|
|
2056
|
+
export { type ApiDeployedHandle, type ApiDeployedOptions, type ApiDeployedSpecification, type ApiHandle, type ApiServedOptions, type ApiSpecification, type ApiSpecificationOptions, type BaseResult, type BrowserConsoleMessage, type BrowserLinkElement, type BrowserMetaElement, type BrowserOpenOptions, type BrowserPage, type BrowserPort, type CallResult, type CaptureScope, type CliEnv, type CliHandle, type CliInput, type CliOutput, type CliPort, type CliResult, type CliSpecification, type CliSpecificationOptions, type ComponentChain, type ComponentScenario, type ComponentUi, type ComponentVisitor, type ContainerAccessor, type DeviceOpenOptions, type DevicePort, type DeviceScreen, type DeviceTimeouts, type DirectoryAccessor, type DiskDirectory, type DiskFile, type DiskTarget, type DockerSpecConfig, type DomMount, type ElementKind, type ElementMatch, type ExchangeResult, type ExecOptions, type FetchResult, type FileAccessor, type FileAt, type FilesystemAccessor, type HonoApp, type HttpResult, type IntegrationHandle, type IntegrationSpecification, type IntegrationSpecificationOptions, type Job, type JobHandle, type JobResult, type JobSpecification, type JobSpecificationOptions, type JsonAccessor, type LandmarkKind, type LintConfig, type LintHandle, type LintResult, type LintRules, type LintRunOptions, type LintSpecification, type LintSpecificationOptions, type LiterateRunFlags, type LiterateServeRegistration, type MatchFixtureOptions, Matcher, type MatcherKind, type MobileBackendOptions, type MobileElementKind, type MobileElementMatch, type MobileHandle, type MobileScenario, type MobileSpecification, type MobileSpecificationOptions, type MobileVisitor, type MockOfOptions, type MockPort, type PackedPackage, type PageResult, type PinnedClock, type PositionedCases, type PositionedRuleTester, type PrepareStep, type RelativePath, type RenderResult, type RenderSubject, type RenderedText, type ResponseAccessor, type ScreenNode, type ScreenResult, type ServerPort, type ServerRequestOptions, type ServerResponse, type ServerSpec, type SpecDocument, type SpecEnvToken, type SpecFileAssertion, type SpecFixture, type SpecRun, type SpecServeEntry, type SpecStream, type TableAccessor, type Target, type TargetOptions, type TextAccessor, type TlsFacts, type VisitScenario, type WaitUntilOptions, type WebsiteBackendOptions, type WebsiteHandle, type WebsiteSpecification, type WebsiteSpecificationOptions, type WebsiteVisitor, directory, file, match };
|
|
1916
2057
|
//# sourceMappingURL=index.d.ts.map
|