lambder 14.1.1 → 15.0.2
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/CHANGELOG.md +429 -0
- package/README.md +14 -17
- package/dist/api/LambderApiDeclarations.d.ts +11 -5
- package/dist/api/LambderApiDefinition.d.ts +2 -1
- package/dist/api/LambderApiEnvelope.d.ts +2 -2
- package/dist/api/LambderApiEnvelope.js +8 -2
- package/dist/api/LambderApiGuards.d.ts +44 -5
- package/dist/api/LambderApiGuards.js +27 -0
- package/dist/api/LambderApiIdempotency.d.ts +14 -7
- package/dist/api/LambderApiIdempotency.js +39 -27
- package/dist/api/LambderApiPipeline.d.ts +25 -11
- package/dist/api/LambderApiPipeline.js +34 -17
- package/dist/api/LambderApiRateLimits.d.ts +28 -21
- package/dist/api/LambderApiRateLimits.js +55 -35
- package/dist/api/LambderApiRefusals.d.ts +10 -4
- package/dist/api/LambderApiRefusals.js +31 -5
- package/dist/api/LambderApiRequest.d.ts +21 -1
- package/dist/api/LambderApiRequest.js +31 -2
- package/dist/build/checkApiRefusals.d.ts +8 -3
- package/dist/build/checkApiRefusals.js +80 -29
- package/dist/build/contractPrinterProcess.d.ts +11 -0
- package/dist/build/contractPrinterProcess.js +17 -0
- package/dist/build/generateApiFiles.d.ts +26 -5
- package/dist/build/generateApiFiles.js +68 -7
- package/dist/build/writeApiSchemas.d.ts +109 -0
- package/dist/build/writeApiSchemas.js +308 -0
- package/dist/build.d.ts +3 -1
- package/dist/build.js +2 -0
- package/dist/client/LambderCaller.d.ts +25 -11
- package/dist/client/LambderCaller.js +57 -49
- package/dist/client/LambderUploadRunner.d.ts +55 -27
- package/dist/client/LambderUploadRunner.js +89 -34
- package/dist/client.d.ts +6 -6
- package/dist/client.js +2 -2
- package/dist/core/Lambder.d.ts +31 -21
- package/dist/core/Lambder.js +79 -23
- package/dist/core/LambderCallSummary.d.ts +1 -1
- package/dist/core/LambderContext.d.ts +59 -7
- package/dist/core/LambderContext.js +31 -15
- package/dist/core/LambderCrashHandling.d.ts +5 -0
- package/dist/core/LambderCrashHandling.js +11 -1
- package/dist/core/LambderCreateOptions.d.ts +28 -17
- package/dist/core/LambderCreateOptions.js +14 -7
- package/dist/core/LambderResolver.d.ts +3 -2
- package/dist/core/LambderResponseBuilder.d.ts +20 -9
- package/dist/core/LambderResponseBuilder.js +39 -8
- package/dist/core/LambderTemplatingEngine.d.ts +24 -6
- package/dist/core/LambderTemplatingEngine.js +23 -3
- package/dist/index.d.ts +15 -12
- package/dist/index.js +7 -5
- package/dist/invoke/LambderInvokeCaller.d.ts +25 -4
- package/dist/invoke/LambderInvokeCaller.js +47 -9
- package/dist/invoke/LambderInvokeOutcome.d.ts +7 -6
- package/dist/mock/LambderMockAdapterDoor.d.ts +40 -0
- package/dist/mock/LambderMockAdapterDoor.js +10 -0
- package/dist/mock/LambderMockApiSchemas.d.ts +28 -0
- package/dist/mock/LambderMockApiSchemas.js +150 -0
- package/dist/mock/LambderMockApp.d.ts +56 -48
- package/dist/mock/LambderMockApp.js +107 -62
- package/dist/mock/LambderMockBrowserCookies.js +18 -5
- package/dist/mock/LambderMockCreateOptions.d.ts +51 -4
- package/dist/mock/LambderMockFailureInjector.d.ts +12 -3
- package/dist/mock/LambderMockFailureInjector.js +12 -8
- package/dist/mock/LambderMockTypes.d.ts +8 -4
- package/dist/mock/lambderMockInvokeTransport.js +2 -9
- package/dist/mock/lambderMockMswHandler.d.ts +19 -13
- package/dist/mock/lambderMockMswHandler.js +25 -22
- package/dist/mock.d.ts +1 -0
- package/dist/secrets/LambderOneShotSecrets.d.ts +1 -1
- package/dist/secrets/LambderOneShotSecrets.js +6 -36
- package/dist/secrets/LambderPasswordHasher.d.ts +56 -0
- package/dist/secrets/LambderPasswordHasher.js +168 -0
- package/dist/session/LambderSessionController.d.ts +37 -4
- package/dist/session/LambderSessionController.js +36 -6
- package/dist/session/LambderSessionManager.d.ts +33 -3
- package/dist/session/LambderSessionManager.js +55 -16
- package/dist/shared/LambderHtml.d.ts +23 -4
- package/dist/shared/LambderHtml.js +17 -5
- package/dist/shared/LambderI18n.d.ts +106 -16
- package/dist/shared/LambderI18n.js +259 -74
- package/dist/shared/contracts/LambderCache.d.ts +14 -1
- package/dist/shared/contracts/LambderRateLimiter.d.ts +5 -6
- package/dist/shared/transport/LambderApiTransport.d.ts +3 -2
- package/dist/shared/util/LambderBackoffTimer.d.ts +24 -13
- package/dist/shared/util/LambderBackoffTimer.js +40 -12
- package/dist/shared/util/LambderCallAbort.d.ts +22 -6
- package/dist/shared/util/LambderCallAbort.js +37 -9
- package/dist/shared/util/LambderErrorReportMark.d.ts +4 -0
- package/dist/shared/util/LambderErrorReportMark.js +22 -0
- package/dist/shared/util/LambderKeyFieldDigest.d.ts +46 -0
- package/dist/shared/util/LambderKeyFieldDigest.js +75 -0
- package/dist/shared/util/LambderSignedClaims.d.ts +19 -0
- package/dist/shared/util/LambderSignedClaims.js +54 -0
- package/dist/shared/util/LambderSwappableInstances.d.ts +29 -0
- package/dist/shared/util/LambderSwappableInstances.js +54 -0
- package/dist/shared/util/LambderTestingDoors.d.ts +6 -2
- package/dist/shared/util/LambderTestingDoors.js +6 -2
- package/dist/shared/util/LambderTextDigest.d.ts +5 -5
- package/dist/shared/util/LambderTextDigest.js +5 -5
- package/dist/shared/wire/LambderApiContract.d.ts +1 -1
- package/dist/shared/wire/LambderApiOptionEntries.d.ts +9 -1
- package/dist/shared/wire/LambderApiOptionEntries.js +15 -0
- package/dist/shared/wire/LambderApiOptionValues.d.ts +3 -2
- package/dist/shared/wire/LambderApiOutcome.d.ts +37 -19
- package/dist/shared/wire/LambderApiOutcome.js +1 -1
- package/dist/shared/wire/LambderApiRefusal.d.ts +39 -12
- package/dist/shared/wire/LambderApiRefusal.js +3 -3
- package/dist/shared/wire/LambderApiSchemaEntries.d.ts +21 -0
- package/dist/shared/wire/LambderApiSchemaEntries.js +18 -0
- package/dist/shared/wire/LambderCallOptions.d.ts +3 -3
- package/dist/shared/wire/LambderCallOutcome.d.ts +2 -1
- package/dist/shared/wire/LambderCallOutcome.js +3 -2
- package/dist/shared/wire/LambderIdempotencyKeyScope.d.ts +5 -3
- package/dist/shared/wire/LambderIdempotencyKeyScope.js +5 -3
- package/dist/shared/wire/LambderInvokeApiId.d.ts +3 -3
- package/dist/shared/wire/LambderInvokeApiId.js +3 -3
- package/dist/shared/wire/LambderOutcomeAssertions.d.ts +7 -6
- package/dist/shared/wire/LambderOutcomeAssertions.js +1 -1
- package/dist/stores/LambderCacheValues.d.ts +2 -5
- package/dist/stores/LambderDdbCache.d.ts +15 -9
- package/dist/stores/LambderDdbCache.js +25 -6
- package/dist/stores/LambderDdbIdempotencyStore.d.ts +6 -4
- package/dist/stores/LambderDdbIdempotencyStore.js +32 -52
- package/dist/stores/LambderDdbOneShotSecretStore.d.ts +11 -0
- package/dist/stores/LambderDdbOneShotSecretStore.js +17 -5
- package/dist/stores/LambderDdbSdk.d.ts +59 -29
- package/dist/stores/LambderDdbSdk.js +116 -44
- package/dist/stores/LambderDdbSessionStore.d.ts +26 -11
- package/dist/stores/LambderDdbSessionStore.js +133 -68
- package/dist/stores/LambderMemoryCache.d.ts +2 -2
- package/dist/stores/LambderS3FileSource.d.ts +3 -2
- package/dist/stores/LambderS3FileSource.js +11 -13
- package/dist/stores/LambderS3UploadBucket.d.ts +12 -0
- package/dist/stores/LambderS3UploadBucket.js +23 -0
- package/dist/stores/LambderStorageBackedCache.d.ts +2 -2
- package/dist/stores/LambderStoredText.d.ts +26 -0
- package/dist/stores/LambderStoredText.js +25 -0
- package/dist/testing/LambderConformanceRunner.d.ts +9 -2
- package/dist/testing/LambderConformanceRunner.js +9 -2
- package/dist/testing/LambderTestApp.d.ts +65 -7
- package/dist/testing/LambderTestApp.js +101 -6
- package/dist/testing/LambderTestVisitor.d.ts +43 -12
- package/dist/testing/LambderTestVisitor.js +35 -11
- package/dist/testing/bootLambdaPackage.d.ts +105 -0
- package/dist/testing/bootLambdaPackage.js +265 -0
- package/dist/testing/lambdaPackageBootProcess.d.ts +39 -0
- package/dist/testing/lambdaPackageBootProcess.js +130 -0
- package/dist/testing/lambderCacheConformance.d.ts +26 -0
- package/dist/testing/lambderCacheConformance.js +287 -0
- package/dist/testing/lambderCacheStorageConformance.d.ts +25 -0
- package/dist/testing/lambderCacheStorageConformance.js +159 -0
- package/dist/testing/lambderSessionStoreConformance.d.ts +3 -3
- package/dist/testing/lambderSessionStoreConformance.js +3 -3
- package/dist/testing.d.ts +7 -1
- package/dist/testing.js +5 -0
- package/package.json +1 -6
- package/dist/shared/util/boundKeyField.d.ts +0 -20
- package/dist/shared/util/boundKeyField.js +0 -34
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { LambderApiOutputValidationError } from "../api/LambderApiOutputValidationError.js";
|
|
3
|
+
import { LAMBDER_STRIP_UNKNOWN_KEYS } from "../shared/wire/LambderApiSchemaEntries.js";
|
|
4
|
+
/** The schemas z.fromJSONSchema builds that hold no other schema: nothing in them to walk. */
|
|
5
|
+
const LEAF_TYPES = new Set(["string", "number", "boolean", "null", "any", "unknown", "never", "literal", "enum", "transform"]);
|
|
6
|
+
/**
|
|
7
|
+
* The schema with its definition changed, built the way zod builds a copy
|
|
8
|
+
* (clone). The definition is copied with its accessors, so what zod computes
|
|
9
|
+
* on each read (a default's value, copied fresh for every parse) is still
|
|
10
|
+
* computed on each read.
|
|
11
|
+
*/
|
|
12
|
+
const cloneWith = (schema, changes) => {
|
|
13
|
+
const def = Object.defineProperties({}, Object.getOwnPropertyDescriptors(schema._zod.def));
|
|
14
|
+
for (const [key, value] of Object.entries(changes)) {
|
|
15
|
+
Object.defineProperty(def, key, { value, enumerable: true, writable: true, configurable: true });
|
|
16
|
+
}
|
|
17
|
+
return schema.clone(def);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* A schema z.fromJSONSchema built, with every object the writer marked made
|
|
21
|
+
* to drop the keys it does not declare. `marks` is the registry the build
|
|
22
|
+
* recorded the marks in: fromJSONSchema files a keyword it does not read as
|
|
23
|
+
* metadata of the schema it built for that node, which for an object with a
|
|
24
|
+
* default, a readOnly or key rules is the wrapper around the object, so the
|
|
25
|
+
* mark is carried down to the object inside.
|
|
26
|
+
*/
|
|
27
|
+
const withStrippedObjects = (built, marks) => {
|
|
28
|
+
const walked = new Map();
|
|
29
|
+
const walk = (schema, stripFromWrapper = false) => {
|
|
30
|
+
const strip = stripFromWrapper || marks.get(schema)?.[LAMBDER_STRIP_UNKNOWN_KEYS] === true;
|
|
31
|
+
// A schema met again (a $ref, a recursive one through z.lazy) is the
|
|
32
|
+
// same walked schema; one the mark reached from its wrapper is met
|
|
33
|
+
// only through that wrapper.
|
|
34
|
+
const known = stripFromWrapper ? undefined : walked.get(schema);
|
|
35
|
+
if (known)
|
|
36
|
+
return known;
|
|
37
|
+
const def = schema._zod.def;
|
|
38
|
+
let result;
|
|
39
|
+
switch (def.type) {
|
|
40
|
+
case "object": {
|
|
41
|
+
const shape = Object.fromEntries(Object.entries(def.shape).map(([key, field]) => [key, walk(field)]));
|
|
42
|
+
result = cloneWith(schema, { shape, catchall: strip ? undefined : def.catchall && walk(def.catchall) });
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case "default":
|
|
46
|
+
case "readonly":
|
|
47
|
+
result = cloneWith(schema, { innerType: walk(def.innerType, strip) });
|
|
48
|
+
break;
|
|
49
|
+
case "pipe":
|
|
50
|
+
// Key rules (propertyNames, min and max properties) run on
|
|
51
|
+
// the raw object ahead of the object itself.
|
|
52
|
+
result = cloneWith(schema, { in: walk(def.in), out: walk(def.out, strip) });
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
if (strip)
|
|
56
|
+
throw new Error(`LambderMockApp: a "${def.type}" schema is marked to drop unknown keys, which only an object can. The apiSchemas table was not written by writeApiSchemas: regenerate it.`);
|
|
57
|
+
result = walkContainer(schema, def);
|
|
58
|
+
}
|
|
59
|
+
if (!stripFromWrapper)
|
|
60
|
+
walked.set(schema, result);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
const walkContainer = (schema, def) => {
|
|
64
|
+
switch (def.type) {
|
|
65
|
+
case "array": return cloneWith(schema, { element: walk(def.element) });
|
|
66
|
+
case "tuple": return cloneWith(schema, { items: def.items.map((item) => walk(item)), rest: def.rest ? walk(def.rest) : def.rest });
|
|
67
|
+
case "union": return cloneWith(schema, { options: def.options.map((option) => walk(option)) });
|
|
68
|
+
case "intersection": return cloneWith(schema, { left: walk(def.left), right: walk(def.right) });
|
|
69
|
+
case "record": return cloneWith(schema, { keyType: walk(def.keyType), valueType: walk(def.valueType) });
|
|
70
|
+
case "optional":
|
|
71
|
+
case "nullable": return cloneWith(schema, { innerType: walk(def.innerType) });
|
|
72
|
+
case "lazy": return z.lazy(() => walk(def.getter()));
|
|
73
|
+
default:
|
|
74
|
+
if (LEAF_TYPES.has(def.type))
|
|
75
|
+
return schema;
|
|
76
|
+
throw new Error(`LambderMockApp: z.fromJSONSchema built a "${def.type}" schema, which the mock cannot carry the server's unknown-key handling through. The installed zod builds what this version of lambder does not know.`);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return walk(built);
|
|
80
|
+
};
|
|
81
|
+
/** One written schema as zod: rebuilt, then made to drop unknown keys where the server's does. */
|
|
82
|
+
const rebuildSchema = (written) => {
|
|
83
|
+
// A registry of its own, so the marks never reach zod's global registry,
|
|
84
|
+
// which the app's own z.toJSONSchema calls read.
|
|
85
|
+
const marks = z.registry();
|
|
86
|
+
const built = z.fromJSONSchema(written, { defaultTarget: "draft-2020-12", registry: marks });
|
|
87
|
+
return withStrippedObjects(built, marks);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The generated `apiSchemas` table, as the schemas the mock validates every
|
|
91
|
+
* call's input with and parses every answer through.
|
|
92
|
+
*/
|
|
93
|
+
export class LambderMockApiSchemas {
|
|
94
|
+
table;
|
|
95
|
+
rebuilt = new Map();
|
|
96
|
+
constructor(table) {
|
|
97
|
+
this.table = table;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The schema an entry's input is validated with, as the pipeline takes it
|
|
101
|
+
* at registration: lazy, so it is rebuilt on the first call that reaches
|
|
102
|
+
* it. A name the table does not hold throws here, when the entry is
|
|
103
|
+
* registered, rather than on its first call.
|
|
104
|
+
*/
|
|
105
|
+
inputOf(apiName) {
|
|
106
|
+
this.assertHeld(apiName);
|
|
107
|
+
return z.lazy(() => this.rebuiltSchema(apiName, "input"));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* An answer a handler returned, parsed through the server's output schema
|
|
111
|
+
* as the server parses its own: what the schema does not declare dropped,
|
|
112
|
+
* its defaults filled. What it rejects, or a parse that throws, is the
|
|
113
|
+
* handler breaking its contract, the error the server crashes with.
|
|
114
|
+
*/
|
|
115
|
+
parseOutput(apiName, returned) {
|
|
116
|
+
const output = this.rebuiltSchema(apiName, "output");
|
|
117
|
+
let parsed;
|
|
118
|
+
try {
|
|
119
|
+
parsed = output.safeParse(returned);
|
|
120
|
+
}
|
|
121
|
+
catch (thrown) {
|
|
122
|
+
throw new LambderApiOutputValidationError(apiName, { thrown });
|
|
123
|
+
}
|
|
124
|
+
if (!parsed.success)
|
|
125
|
+
throw new LambderApiOutputValidationError(apiName, { zodError: parsed.error });
|
|
126
|
+
return parsed.data;
|
|
127
|
+
}
|
|
128
|
+
assertHeld(apiName) {
|
|
129
|
+
if (!Object.prototype.hasOwnProperty.call(this.table, apiName)) {
|
|
130
|
+
throw new Error(`LambderMockApp: "${apiName}" has no entry in the apiSchemas table given to create(). The table predates this endpoint: regenerate it with writeApiSchemas.`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** One of an API's schemas, rebuilt the first time it is asked for and kept. */
|
|
134
|
+
rebuiltSchema(apiName, direction) {
|
|
135
|
+
const key = `${direction} ${apiName}`;
|
|
136
|
+
const known = this.rebuilt.get(key);
|
|
137
|
+
if (known)
|
|
138
|
+
return known;
|
|
139
|
+
this.assertHeld(apiName);
|
|
140
|
+
let schema;
|
|
141
|
+
try {
|
|
142
|
+
schema = rebuildSchema(this.table[apiName][direction]);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
throw new Error(`LambderMockApp: the ${direction} schema of "${apiName}" in the apiSchemas table could not be rebuilt.`, { cause: err });
|
|
146
|
+
}
|
|
147
|
+
this.rebuilt.set(key, schema);
|
|
148
|
+
return schema;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -6,7 +6,8 @@ import { type LambderDeclaredRefuse, type LambderRefusalMessage } from "../share
|
|
|
6
6
|
import { type LambderDeclaredVocabulary, type LambderHandlerRefusalsOf, type LambderRefusalVocabulary, type LambderRefusalVocabularyOption, type LambderRefusalVocabularyOptionChecks, type LambderMergedRefusalVocabulary } from "../api/LambderApiRefusals.js";
|
|
7
7
|
import { type LambderApiTransport, type LambderApiTransportRequest } from "../shared/transport/LambderApiTransport.js";
|
|
8
8
|
import { LambderCookieJar } from "../shared/transport/LambderCookieJar.js";
|
|
9
|
-
import { type LambderApiGuard
|
|
9
|
+
import { type LambderApiGuard } from "../api/LambderApiGuards.js";
|
|
10
|
+
import { LAMBDER_MOCK_ADAPTER_DOOR, type LambderMockAdapterDoor } from "./LambderMockAdapterDoor.js";
|
|
10
11
|
import { LambderMemoryRateLimiter } from "../stores/LambderMemoryRateLimiter.js";
|
|
11
12
|
import { LambderMemoryIdempotencyStore } from "../stores/LambderMemoryIdempotencyStore.js";
|
|
12
13
|
import { LambderMemorySessionStore } from "../stores/LambderMemorySessionStore.js";
|
|
@@ -49,6 +50,21 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
49
50
|
readonly defaultClientIp: string;
|
|
50
51
|
/** The host this runtime's cookies belong to (see the cookieHost option). */
|
|
51
52
|
readonly cookieHost: string;
|
|
53
|
+
/**
|
|
54
|
+
* The page's cookie jar: where the browser this runtime serves keeps the
|
|
55
|
+
* cookies no page script can read, the HttpOnly session cookie among
|
|
56
|
+
* them. signIn and signOut plant into it and clear it when they are given
|
|
57
|
+
* no jar, and the MSW adapter carries its calls' cookies in it when it is
|
|
58
|
+
* given none, so the session signIn starts is the one the page's next
|
|
59
|
+
* call through the worker sends. The runtime's own: reset() empties it.
|
|
60
|
+
*/
|
|
61
|
+
readonly pageCookieJar: LambderCookieJar;
|
|
62
|
+
/**
|
|
63
|
+
* What the MSW adapter asks of the runtime and tells it beyond handing it
|
|
64
|
+
* a call, behind a key no entry point exports (see
|
|
65
|
+
* LAMBDER_MOCK_ADAPTER_DOOR): the adapter's bookkeeping, not the app's.
|
|
66
|
+
*/
|
|
67
|
+
readonly [LAMBDER_MOCK_ADAPTER_DOOR]: LambderMockAdapterDoor;
|
|
52
68
|
/**
|
|
53
69
|
* The API core, every protocol step of it. Private: the mock's surface is
|
|
54
70
|
* the app, and a consumer reaching past it would be configuring the
|
|
@@ -69,6 +85,8 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
69
85
|
private readonly registry;
|
|
70
86
|
/** The server's declared options per API, when create() was given the generated table; the entries' declarations come from here. */
|
|
71
87
|
private readonly apiOptions;
|
|
88
|
+
/** The server's schemas, when create() was given the generated table: every entry's input is validated, and every answer parsed, through them. */
|
|
89
|
+
private readonly apiSchemas;
|
|
72
90
|
/** The mock's own guards as create() was given them: which of them need a session, for an entry's mode without the apiOptions table. */
|
|
73
91
|
private readonly mockGuards;
|
|
74
92
|
/** The server's guard declarations, when create() was given the generated table: the refusal codes a declared guard adds to an entry. */
|
|
@@ -120,6 +138,13 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
120
138
|
private declaredRefusalsOf;
|
|
121
139
|
/** The mode the apiOptions table gives a name, or null without a table or for a name it does not hold. */
|
|
122
140
|
private declaredModeOf;
|
|
141
|
+
/**
|
|
142
|
+
* The schema an entry's input is validated with: the server's, from the
|
|
143
|
+
* apiSchemas table when create() was given it, then the entry's own where
|
|
144
|
+
* it restates one, run on what the server's leaves (the payload stripped
|
|
145
|
+
* and defaulted as on the server). Either alone where only one is given.
|
|
146
|
+
*/
|
|
147
|
+
private entryInputOf;
|
|
123
148
|
private buildEntry;
|
|
124
149
|
/**
|
|
125
150
|
* A mock for an endpoint: a handler, or the handler with the endpoint's
|
|
@@ -195,16 +220,6 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
195
220
|
restoreOverrides(): void;
|
|
196
221
|
/** The registered endpoint names. */
|
|
197
222
|
get registeredNames(): string[];
|
|
198
|
-
/**
|
|
199
|
-
* Whether a call to this name would be answered from the registry, which
|
|
200
|
-
* is what an adapter asks before passing one on.
|
|
201
|
-
*
|
|
202
|
-
* True for every name once a rest entry is registered, since it answers
|
|
203
|
-
* whatever nothing else claimed. That makes a rest entry and the MSW
|
|
204
|
-
* adapter's `onUnmocked: "passthrough"` alternatives rather than layers:
|
|
205
|
-
* with one registered, nothing is handed on to the network.
|
|
206
|
-
*/
|
|
207
|
-
hasRegisteredEntry(apiName: string): boolean;
|
|
208
223
|
private entryFor;
|
|
209
224
|
/**
|
|
210
225
|
* The entry that answers a name nothing registered, when register() was
|
|
@@ -216,7 +231,7 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
216
231
|
* restore, and for a session endpoint the session read).
|
|
217
232
|
*/
|
|
218
233
|
private restNotMockedEntry;
|
|
219
|
-
/** The next call to the endpoint fails this way; several calls queue in order. An injected refusal names one of the endpoint's declared codes, its data as a handler raises it (see LambderMockRefusalsOf), and is checked and sent as a real one is. */
|
|
234
|
+
/** The next call to the endpoint fails this way; several calls queue in order. An injected refusal names one of the endpoint's declared codes, its data as a handler raises it (see LambderMockRefusalsOf), and is checked and sent as a real one is. An injected sessionExpired, or a refusal whose code is declared so, ends the session the call carries, as the server's does. */
|
|
220
235
|
failNext<K extends keyof C & string>(apiName: K, failure: LambderMockFailure<LambderRefusalMessage<LambderMockRefusalsOf<C, K, TVocabulary>>> | LambderMockFailureReason): void;
|
|
221
236
|
/** Every call to the endpoint fails this way until cleared with null. */
|
|
222
237
|
setFailure<K extends keyof C & string>(apiName: K, failure: LambderMockFailure<LambderRefusalMessage<LambderMockRefusalsOf<C, K, TVocabulary>>> | LambderMockFailureReason | null): void;
|
|
@@ -226,13 +241,14 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
226
241
|
/**
|
|
227
242
|
* Rewinds the runtime: sessions, rate-limit counters, replay records,
|
|
228
243
|
* overrides, injected failures, the offline switch, the configured
|
|
229
|
-
* latency, the call log and its numbering, the cookies its own
|
|
230
|
-
*
|
|
244
|
+
* latency, the call log and its numbering, the cookies its own jars hold,
|
|
245
|
+
* then onReset, so the app rewinds its own data too.
|
|
231
246
|
*
|
|
232
247
|
* The cookies matter as much as the sessions: a jar still holding the
|
|
233
248
|
* token of an emptied store's session reads as signed in until an answer
|
|
234
|
-
* says sessionExpired. So every jar transport() built
|
|
235
|
-
* emptied, and the cookies
|
|
249
|
+
* says sessionExpired. So the page's jar and every jar transport() built
|
|
250
|
+
* for itself are emptied, and the cookies mirrored into document.cookie
|
|
251
|
+
* are expired at the scope each was set at.
|
|
236
252
|
*
|
|
237
253
|
* The registry survives, being configuration rather than accumulated
|
|
238
254
|
* state. Subscriptions survive too, being how a test watches the runtime;
|
|
@@ -254,9 +270,10 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
254
270
|
/**
|
|
255
271
|
* Starts a session without a login endpoint: creates it through the
|
|
256
272
|
* session controller, the way a login handler does, plants its cookies
|
|
257
|
-
* into the jar
|
|
258
|
-
* from its next call, and
|
|
259
|
-
* the
|
|
273
|
+
* into the jar given, or the page's (pageCookieJar) when none is, so that
|
|
274
|
+
* jar's transport or the MSW adapter is signed in from its next call, and
|
|
275
|
+
* mirrors the readable ones into document.cookie the way an answer's
|
|
276
|
+
* cookies are. Returns the raw tokens too.
|
|
260
277
|
*/
|
|
261
278
|
signIn(sessionKey: string, data: S, options?: {
|
|
262
279
|
jar?: LambderCookieJar;
|
|
@@ -265,8 +282,8 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
265
282
|
}): Promise<LambderCreatedSession<S>>;
|
|
266
283
|
/**
|
|
267
284
|
* Ends every session of the subject ("log this subject out everywhere")
|
|
268
|
-
* and clears what signIn planted: the cookies in the jar given,
|
|
269
|
-
* copies in document.cookie.
|
|
285
|
+
* and clears what signIn planted: the cookies in the jar given, or the
|
|
286
|
+
* page's when none is, and the copies in document.cookie.
|
|
270
287
|
*
|
|
271
288
|
* Symmetric on purpose, the way reset() is. The records alone leave the
|
|
272
289
|
* jar and the page carrying a token for a session that no longer exists,
|
|
@@ -291,14 +308,6 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
291
308
|
private createContext;
|
|
292
309
|
/** What a call looks like on the way in, for the runtime's own calls and for one an adapter passes on. */
|
|
293
310
|
private requestEvent;
|
|
294
|
-
/**
|
|
295
|
-
* Records a call an adapter handed on instead of answering: the MSW
|
|
296
|
-
* adapter's passthrough. Without it a name the registry does not know
|
|
297
|
-
* leaves no trace at all, and a mistyped endpoint reaches the real
|
|
298
|
-
* network with nothing in the call log or on the subscription to say so,
|
|
299
|
-
* which is the one failure the log exists to make visible.
|
|
300
|
-
*/
|
|
301
|
-
notePassthrough(request: LambderApiRequest): void;
|
|
302
311
|
/** What every record of one call repeats (see LambderMockCallFacts). */
|
|
303
312
|
private callFacts;
|
|
304
313
|
/** One call from a parsed request to its answer, events included. The entry point every transport and adapter shares. */
|
|
@@ -320,21 +329,6 @@ export declare class LambderMockApp<C extends LambderApiContractShape, S = any,
|
|
|
320
329
|
* not create itself, and reset() empties it.
|
|
321
330
|
*/
|
|
322
331
|
transport(options?: LambderMockTransportOptions): LambderMockTransport;
|
|
323
|
-
/**
|
|
324
|
-
* Mirrors an answer's non-HttpOnly cookies into document.cookie and
|
|
325
|
-
* remembers them, so reset() expires them again. The direct transport's
|
|
326
|
-
* "document" mode and the MSW adapter both come through here: one
|
|
327
|
-
* implementation of the mirror, one record of what was planted.
|
|
328
|
-
*/
|
|
329
|
-
mirrorCookiesIntoDocument(setCookies: readonly string[]): void;
|
|
330
|
-
/**
|
|
331
|
-
* Takes a jar an adapter built for itself as the runtime's own, so reset()
|
|
332
|
-
* empties it with the rest. The MSW adapter's jar holds the session
|
|
333
|
-
* cookies of calls that never touch transport(); left full after a reset,
|
|
334
|
-
* the next request would carry a token for a session the emptied store no
|
|
335
|
-
* longer has.
|
|
336
|
-
*/
|
|
337
|
-
adoptCookieJar(jar: LambderCookieJar): void;
|
|
338
332
|
/** caller.setTransport(mockApp.transport(options)); returns the transport, its jar on it. */
|
|
339
333
|
attach(caller: {
|
|
340
334
|
setTransport(transport: LambderApiTransport): unknown;
|
|
@@ -361,8 +355,15 @@ export declare const initLambderMock: <C extends LambderApiContractShape, S = an
|
|
|
361
355
|
declareRefusals<const TVocabulary extends LambderRefusalVocabularyOption, const TRequireCodes extends boolean = false>(refusals: TVocabulary & LambderRefusalVocabularyOptionChecks<TVocabulary>, options?: {
|
|
362
356
|
requireCodes?: TRequireCodes;
|
|
363
357
|
}): {
|
|
364
|
-
/**
|
|
365
|
-
|
|
358
|
+
/**
|
|
359
|
+
* Builds a mock guard: the server guard's shape, the handler seeing the
|
|
360
|
+
* mock's contexts. Bound to the vocabulary the mock declared, as the
|
|
361
|
+
* server init's builder is to the server's: its ctx.refuse is typed to the
|
|
362
|
+
* guard's own `refusals`, data in the schema's input form, and a code the
|
|
363
|
+
* vocabulary does not hold is refused as the guard is built. A mock that
|
|
364
|
+
* declared none checks nothing here.
|
|
365
|
+
*/
|
|
366
|
+
guard: import("../api/LambderApiGuards.js").LambderGuardBuilder<LambderMockCallContext<S>, LambderMockSessionCallContext<S>, LambderMergedRefusalVocabulary<TVocabulary>, TRequireCodes>;
|
|
366
367
|
/**
|
|
367
368
|
* Builds a mock rate-limit key, the counterpart of `guard`. Bound to the
|
|
368
369
|
* mock's own call context, because the server's lambderRateLimitKey() is
|
|
@@ -390,8 +391,15 @@ export declare const initLambderMock: <C extends LambderApiContractShape, S = an
|
|
|
390
391
|
*/
|
|
391
392
|
create<const G extends Record<string, LambderApiGuard<any, any, any, LambderMockCallContext<S>, LambderMockSessionCallContext<S>>> = {}, const P extends LambderMockRateLimitPolicies<S> = {}, I extends boolean | LambderMockIdempotencyOptions<S> = boolean | LambderMockIdempotencyOptions<S>, const D extends Record<string, LambderGuardDeclarationEntry> = {}, const A extends Record<string, LambderApiOptionEntry> | undefined = undefined>(options: LambderMockAppOptions<C, S, G, P, I, D, A>): LambderMockApp<C, S, G, [A] extends [undefined] ? false : true, LambderMergedRefusalVocabulary<TVocabulary>, TRequireCodes>;
|
|
392
393
|
};
|
|
393
|
-
/**
|
|
394
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Builds a mock guard: the server guard's shape, the handler seeing the
|
|
396
|
+
* mock's contexts. Bound to the vocabulary the mock declared, as the
|
|
397
|
+
* server init's builder is to the server's: its ctx.refuse is typed to the
|
|
398
|
+
* guard's own `refusals`, data in the schema's input form, and a code the
|
|
399
|
+
* vocabulary does not hold is refused as the guard is built. A mock that
|
|
400
|
+
* declared none checks nothing here.
|
|
401
|
+
*/
|
|
402
|
+
guard: import("../api/LambderApiGuards.js").LambderGuardBuilder<LambderMockCallContext<S>, LambderMockSessionCallContext<S>, never, false>;
|
|
395
403
|
/**
|
|
396
404
|
* Builds a mock rate-limit key, the counterpart of `guard`. Bound to the
|
|
397
405
|
* mock's own call context, because the server's lambderRateLimitKey() is
|