lambder 11.0.1 → 12.0.1
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 +154 -0
- package/README.md +18 -13
- package/dist/api/LambderApiDeclarations.d.ts +194 -0
- package/dist/api/LambderApiDeclarations.js +52 -0
- package/dist/api/LambderApiDefinition.d.ts +1 -1
- package/dist/api/LambderApiGuards.d.ts +21 -22
- package/dist/api/LambderApiGuards.js +1 -1
- package/dist/api/LambderApiRateLimits.d.ts +19 -19
- package/dist/api/LambderApiRateLimits.js +1 -1
- package/dist/api/LambderApiRequest.d.ts +15 -6
- package/dist/api/LambderApiRequest.js +8 -9
- package/dist/build/generatedTables.d.ts +2 -1
- package/dist/build/generatedTables.js +1 -1
- package/dist/client/LambderCaller.d.ts +36 -23
- package/dist/client/LambderCaller.js +88 -67
- package/dist/client/lambderFetchTransport.js +2 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +2 -0
- package/dist/core/Lambder.d.ts +203 -87
- package/dist/core/Lambder.js +265 -86
- package/dist/core/LambderContext.d.ts +1 -1
- package/dist/core/LambderContext.js +13 -5
- package/dist/core/LambderCreateOptions.d.ts +28 -39
- package/dist/core/LambderCreateOptions.js +2 -3
- package/dist/core/LambderPublicFiles.d.ts +8 -1
- package/dist/core/LambderPublicFiles.js +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +2 -0
- package/dist/invoke/LambderInvokeCaller.d.ts +48 -31
- package/dist/invoke/LambderInvokeCaller.js +110 -94
- package/dist/invoke/LambderLambdaEvent.d.ts +0 -1
- package/dist/invoke/LambderLambdaEvent.js +0 -1
- package/dist/invoke/lambderHandlerTransport.js +2 -1
- package/dist/mock/LambderMockApp.d.ts +31 -25
- package/dist/mock/LambderMockApp.js +52 -45
- package/dist/mock/LambderMockCreateOptions.d.ts +6 -7
- package/dist/mock/LambderMockTypes.d.ts +44 -7
- package/dist/mock/lambderMockInvokeTransport.d.ts +9 -1
- package/dist/mock/lambderMockInvokeTransport.js +15 -7
- package/dist/mock/lambderMockMswHandler.js +8 -4
- package/dist/mock.d.ts +2 -2
- package/dist/shared/transport/LambderApiTransport.d.ts +3 -2
- package/dist/shared/transport/LambderApiTransport.js +2 -3
- package/dist/shared/transport/lambderCookieJarTransport.js +2 -1
- package/dist/shared/util/LambderTypeUtilities.d.ts +1 -1
- package/dist/shared/wire/LambderApiContract.d.ts +4 -18
- package/dist/shared/wire/LambderApiContract.js +1 -1
- package/dist/shared/wire/LambderApiGroupCalls.d.ts +31 -0
- package/dist/shared/wire/LambderApiGroupCalls.js +68 -0
- package/dist/shared/wire/LambderApiNames.d.ts +55 -0
- package/dist/shared/wire/LambderApiNames.js +81 -0
- package/dist/shared/wire/LambderUploadSchemas.js +2 -1
- package/dist/testing/LambderTestApp.d.ts +5 -1
- package/dist/testing/LambderTestVisitor.d.ts +16 -8
- package/dist/testing/LambderTestVisitor.js +33 -25
- package/package.json +1 -1
|
@@ -173,7 +173,7 @@ export type LambderGuardsMap<TSessionData = any> = Record<string, LambderApiGuar
|
|
|
173
173
|
export type LambderRateLimitPoliciesMap = Record<string, LambderApiRateLimitPolicyConfig<LambderRenderContext>>;
|
|
174
174
|
/** The `rateLimits` option of create(): the engine's config, with `policies` as one map or a list of maps. */
|
|
175
175
|
export type LambderCreateRateLimitsOption = Omit<LambderApiRateLimitsConfig<LambderRateLimitPoliciesMap>, "policies"> & {
|
|
176
|
-
/** Named policies referenced (typed) from
|
|
176
|
+
/** Named policies referenced (typed) from defineApi: one map, or a list of maps merged in order. */
|
|
177
177
|
policies: LambderNamedMapsOption<LambderRateLimitPoliciesMap>;
|
|
178
178
|
};
|
|
179
179
|
/** The options as the instance holds them: the guards and the rate-limit policies merged into one map each. */
|
|
@@ -276,7 +276,7 @@ export type LambderCreateOptions<TSessionData = any> = {
|
|
|
276
276
|
trustedHostHeaders?: readonly string[];
|
|
277
277
|
/** CORS: true allows any origin; or pass a LambderCorsConfig. Default: off. */
|
|
278
278
|
cors?: boolean | LambderCorsConfig;
|
|
279
|
-
/** Sessions over a store of your choosing; required for
|
|
279
|
+
/** Sessions over a store of your choosing; required for a guard that needs a session, and for addSessionRoute. */
|
|
280
280
|
session?: LambderSessionOptions<TSessionData>;
|
|
281
281
|
/**
|
|
282
282
|
* Declarative per-API rate limiting: your limiter plus named policies APIs
|
|
@@ -318,58 +318,50 @@ export type LambderCreateOptions<TSessionData = any> = {
|
|
|
318
318
|
*/
|
|
319
319
|
requireRefusalCodes?: boolean;
|
|
320
320
|
/**
|
|
321
|
-
* Make an authorization declaration part of
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
* throws). An API whose session is the whole authorization (the
|
|
325
|
-
* signed-in user's own account) declares a named no-op session guard, so
|
|
326
|
-
* every opt-out is explicit and one grep lists them all. Needs a guards
|
|
327
|
-
* map to pick from. Default: false.
|
|
328
|
-
*/
|
|
329
|
-
requireSessionApiGuards?: boolean;
|
|
330
|
-
/**
|
|
331
|
-
* The same for public APIs: every addApi must declare `guards`, at the
|
|
332
|
-
* type level and at registration.
|
|
321
|
+
* Make an authorization declaration part of declaring an endpoint: every
|
|
322
|
+
* defineApi must declare `guards`, at the type level (a missing `guards`
|
|
323
|
+
* is a compile error) and at registration (a plain-JS caller throws).
|
|
333
324
|
*
|
|
334
|
-
*
|
|
335
|
-
* off unless an app decides otherwise. Turned on,
|
|
336
|
-
*
|
|
337
|
-
* anybody may call
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
325
|
+
* An endpoint is open by default, which is the right default, so this is
|
|
326
|
+
* off unless an app decides otherwise. Turned on, every endpoint's
|
|
327
|
+
* authorization becomes a written decision rather than an omission: one
|
|
328
|
+
* anybody may call declares a named no-op guard carrying the reason, one
|
|
329
|
+
* whose session is the whole authorization (the signed-in user's own
|
|
330
|
+
* account) a named no-op session guard, and one that authorizes its
|
|
331
|
+
* caller some other way (a signature, a device secret, a one-shot token)
|
|
332
|
+
* names where that happens. One grep over the guard names then lists
|
|
333
|
+
* every door and why it opens. Needs a guards map to pick from. Default:
|
|
334
|
+
* false.
|
|
342
335
|
*/
|
|
343
|
-
|
|
336
|
+
requireApiGuards?: boolean;
|
|
344
337
|
/** Declarative idempotency: your store plus replay defaults; APIs opt in via `idempotency: true | { ttlSeconds }`. */
|
|
345
338
|
idempotency?: LambderApiIdempotencyConfig;
|
|
346
339
|
/** Crash reporting on every path, and who may read a crash in the answer. See LambderCrashOptions. */
|
|
347
340
|
crashes?: LambderCrashOptions;
|
|
348
341
|
};
|
|
349
342
|
/**
|
|
350
|
-
* What the `guards` field asks for when an API on a
|
|
343
|
+
* What the `guards` field asks for when an API on a requireApiGuards
|
|
351
344
|
* instance declares none. With nothing to infer from, the inference parameter
|
|
352
345
|
* defaults to `never`, and "Property 'guards' is missing ... but required in
|
|
353
346
|
* type { guards: never }" would read as though nothing could be written
|
|
354
347
|
* there; the property name says what is wanted.
|
|
355
348
|
*/
|
|
356
349
|
type LambderGuardsDeclarationRequired = {
|
|
357
|
-
readonly "lambder: this instance requires every API
|
|
350
|
+
readonly "lambder: this instance requires every API to declare guards. Name the guard that authorizes this API, or the named no-op guard that records why it needs nothing more.": never;
|
|
358
351
|
};
|
|
359
352
|
/**
|
|
360
|
-
* What
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
353
|
+
* What addSessionRoute needs of the instance it is called on. Nothing
|
|
354
|
+
* satisfies it without the session option, so registering a session route
|
|
355
|
+
* on an instance that has no sessions is a compile error rather than only a
|
|
356
|
+
* throw when it is first requested.
|
|
364
357
|
*/
|
|
365
358
|
type LambderSessionOptionRequired = {
|
|
366
|
-
readonly "lambder: sessions are not configured on this instance. Pass the session option to create() before registering a session
|
|
359
|
+
readonly "lambder: sessions are not configured on this instance. Pass the session option to create() before registering a session route.": never;
|
|
367
360
|
};
|
|
368
361
|
/**
|
|
369
|
-
* Intersected into what
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* away to nothing.
|
|
362
|
+
* Intersected into what addSessionRoute takes, so an instance created
|
|
363
|
+
* without the session option refuses the registration at the call site.
|
|
364
|
+
* `unknown` once sessions are configured, which intersects away to nothing.
|
|
373
365
|
*/
|
|
374
366
|
export type LambderSessionEnabledInstance<TSessionsEnabled extends boolean> = TSessionsEnabled extends true ? unknown : LambderSessionOptionRequired;
|
|
375
367
|
/**
|
|
@@ -412,11 +404,8 @@ type LambderRateLimitSliceCheck<TLacking> = [TLacking] extends [never] ? unknown
|
|
|
412
404
|
};
|
|
413
405
|
/**
|
|
414
406
|
* The `guards` field of an API's options: optional by default, required once
|
|
415
|
-
* create() received
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* One type for both kinds: the requirement is the same shape either way, and
|
|
419
|
-
* only which flag switches it on differs.
|
|
407
|
+
* create() received requireApiGuards, so that an authorization declaration
|
|
408
|
+
* cannot be forgotten at the type level.
|
|
420
409
|
*/
|
|
421
410
|
export type LambderRequirableGuardsField<TRequired extends boolean, TGuardsOpt> = TRequired extends true ? {
|
|
422
411
|
/** Named guards, run in declared order before input validation (after it for a guard declared runAt: "afterInputValidation"): a name, a non-empty list of names, or a non-empty { name: param } map for parameterized guards. Required on this instance: an API that needs no authorization declares a named no-op guard, so every opt-out is explicit and one grep lists them all. Their input requirements merge into this API's contract input; their return values land typed on ctx.guardData. */
|
|
@@ -53,8 +53,7 @@ export const assertCreateOptions = (options) => {
|
|
|
53
53
|
if (options.requireRefusalCodes && !vocabulary) {
|
|
54
54
|
throw new Error("Lambder: requireRefusalCodes needs a refusals vocabulary to name codes from; declare one with initLambder().declareRefusals().");
|
|
55
55
|
}
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
throw new Error(`Lambder: ${requireFlag} needs a guards map at creation for APIs to declare from.`);
|
|
56
|
+
if (options.requireApiGuards && !options.guards) {
|
|
57
|
+
throw new Error("Lambder: requireApiGuards needs a guards map at creation for APIs to declare from.");
|
|
59
58
|
}
|
|
60
59
|
};
|
|
@@ -13,7 +13,14 @@ export type LambderPublicFilesOptions = {
|
|
|
13
13
|
* mapper. Return null/undefined to skip. Default: the file path as it is.
|
|
14
14
|
*/
|
|
15
15
|
path?: (ctx: LambderRenderContext, filePath: string) => string | null | undefined;
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Cache-Control for served files that do not match immutablePattern; the
|
|
18
|
+
* function receives the relative file path. Default: "no-cache". Such a
|
|
19
|
+
* file keeps its name when its bytes change (a service worker, a web
|
|
20
|
+
* manifest, a favicon), so a shared cache holding it for a while serves
|
|
21
|
+
* the old copy after a deploy; revalidating instead costs a 304, since
|
|
22
|
+
* every GET or HEAD 200 carries an ETag.
|
|
23
|
+
*/
|
|
17
24
|
cacheControl?: string | ((ctx: LambderRenderContext, relativePath: string) => string);
|
|
18
25
|
/** Relative paths matching this get immutableCacheControl. Default: content-hashed names in a bundler's output folder (assets/, static/, _next/static/). Set false to disable. */
|
|
19
26
|
immutablePattern?: RegExp | false;
|
|
@@ -29,7 +29,7 @@ const EXACT_BUNDLER_HASH = "-(?=[\\w-]{0,7}[a-z])(?:(?=[\\w-]{0,7}[A-Z])(?=[\\w-
|
|
|
29
29
|
const LONG_BUNDLER_HASH = "[-.](?=\\w*[A-Za-z])(?=\\w*\\d)\\w{8,}";
|
|
30
30
|
const DEFAULT_IMMUTABLE_PATTERN = new RegExp(`(?:^|/)_next/static/|(?:^|/)(?:assets|static)/(?:[^/]+/)*[^/]*(?:${EXACT_BUNDLER_HASH}|${LONG_BUNDLER_HASH})(?:\\.chunk)?\\.[A-Za-z0-9]+$`);
|
|
31
31
|
const DEFAULT_IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
32
|
-
const DEFAULT_CACHE_CONTROL = "
|
|
32
|
+
const DEFAULT_CACHE_CONTROL = "no-cache";
|
|
33
33
|
/**
|
|
34
34
|
* Terminal public-file handler registered via lambder.servePublicFiles().
|
|
35
35
|
* Runs only when no route matched, so it can never shadow routes registered
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,12 @@ import Lambder from './core/Lambder.js';
|
|
|
2
2
|
export default Lambder;
|
|
3
3
|
export { initLambder } from './core/Lambder.js';
|
|
4
4
|
export type { LambderCreatedHook } from './core/Lambder.js';
|
|
5
|
+
export type { LambderAppTypes, LambderPlainAppTypes, LambderApiDeclaration, LambderApiDeclarations, LambderApiGroup, LambderLazyApiGroup, LambderRegistrableApiGroup, LambderApiModeOf, LambderEntryOf, LambderContractOfGroups, } from './api/LambderApiDeclarations.js';
|
|
6
|
+
export { apiCallPath, apiNameOfCallPath, splitApiName, isGroupName, isActionName, LAMBDER_API_NAME_SEGMENT, LAMBDER_CALLER_MEMBER_NAMES, LAMBDER_RESERVED_GROUP_NAMES, LAMBDER_RESERVED_ACTION_NAMES, } from './shared/wire/LambderApiNames.js';
|
|
7
|
+
export type { LambderReservedGroupName, LambderReservedActionName } from './shared/wire/LambderApiNames.js';
|
|
8
|
+
export type { LambderContractGroupsOf, LambderContractNamesInGroup, LambderContractActionOf } from './shared/wire/LambderApiGroupCalls.js';
|
|
5
9
|
export { default as LambderCaller } from "./client/LambderCaller.js";
|
|
6
|
-
export type { LambderApiOutcome, LambderApiFailureReason, LambderValidationError, LambderCallOptions, LambderCallerOptions, LambderGuardInputsProvider, LambderProvidedGuardInputs, LambderLogListHandler } from "./client/LambderCaller.js";
|
|
10
|
+
export type { LambderApiOutcome, LambderApiFailureReason, LambderValidationError, LambderCallOptions, LambderCallerOptions, LambderGuardInputsProvider, LambderProvidedGuardInputs, LambderLogListHandler, LambderCallerEndpoint, LambderCallerGroupCalls, LambderCallerMembers } from "./client/LambderCaller.js";
|
|
7
11
|
export { createIdempotencyKey, createIdempotencyKeyScope } from "./shared/wire/LambderIdempotencyKeyScope.js";
|
|
8
12
|
export type { LambderIdempotencyKeyScope } from "./shared/wire/LambderIdempotencyKeyScope.js";
|
|
9
13
|
export { lambderFetchTransport } from "./client/lambderFetchTransport.js";
|
|
@@ -46,7 +50,7 @@ export { checkedRefusal } from "./api/LambderApiRefusals.js";
|
|
|
46
50
|
export { LambderInvokeError, isLambderInvokeError } from "./invoke/LambderInvokeOutcome.js";
|
|
47
51
|
export type { LambderInvokeOutcome, LambderInvokeFailure, LambderInvokeValidationFailure, LambderInvokeCrashFailure, LambderInvokePayloadTooLargeFailure, LambderInvokeEnvelopeFailure, LambderInvokeDeliveryFailure, LambderInvokeFailureReason, LambderInvokeFunctionError, } from "./invoke/LambderInvokeOutcome.js";
|
|
48
52
|
export { default as LambderInvokeCaller, LAMBDER_INVOKE_MAX_EVENT_BYTES, } from "./invoke/LambderInvokeCaller.js";
|
|
49
|
-
export type { LambderInvokeCallerOptions, LambderInvokeCallOptions, LambderInvokeFailureHandler, LambderInvokeLogListHandler, LambderInvokeTransport, LambderInvokeTransportResult, LambderInvokeRequestInit, LambderInvokeEventInit, } from "./invoke/LambderInvokeCaller.js";
|
|
53
|
+
export type { LambderInvokeCallerOptions, LambderInvokeCallOptions, LambderInvokeFailureHandler, LambderInvokeCallCheck, LambderInvokeLogListHandler, LambderInvokeTransport, LambderInvokeTransportResult, LambderInvokeRequestInit, LambderInvokeEventInit, LambderInvokeEndpoint, LambderInvokeGroupCalls, } from "./invoke/LambderInvokeCaller.js";
|
|
50
54
|
export { describeCrash, errorFromCrashDetail } from "./shared/wire/LambderCrashDetail.js";
|
|
51
55
|
export type { LambderCrashDetail, LambderCrashCause } from "./shared/wire/LambderCrashDetail.js";
|
|
52
56
|
export { LambderApiRefusal, isLambderApiRefusal, isLambderRefusalCode, refuse, refusalMessageOf, LAMBDER_REFUSAL_CODES } from "./shared/wire/LambderApiRefusal.js";
|
|
@@ -140,7 +144,7 @@ export { apiGuardParam } from "./shared/wire/LambderApiOptionEntries.js";
|
|
|
140
144
|
export type { LambderApiOptionEntries, LambderApiOptionEntry, LambderRateLimitPolicyEntry, LambderGuardDeclarationEntry, LambderApisWithGuard, LambderApisGuardedBy, LambderApisWithMode, LambderGuardParamOf, } from "./shared/wire/LambderApiOptionEntries.js";
|
|
141
145
|
export { createLambderI18n } from "./shared/LambderI18n.js";
|
|
142
146
|
export type { LambderLanguageMeta, LambderI18nConfig, LambderI18nInstance, LambderI18nTranslator, LambderI18nExtractParams, LambderI18nDictionaryLoader, LambderI18nCodes, LambderI18nKeys, LambderI18nTranslatorFor, } from "./shared/LambderI18n.js";
|
|
143
|
-
export type { LambderApiContractShape, LambderApiMode, LambderApiEnvelopeBody, LambderApiSuccessEnvelope, LambderApiRefusalEnvelope, LambderRefusalEnvelopeFields, LambderApiRefusalConfig, LambderContractEntry,
|
|
147
|
+
export type { LambderApiContractShape, LambderApiMode, LambderApiEnvelopeBody, LambderApiSuccessEnvelope, LambderApiRefusalEnvelope, LambderRefusalEnvelopeFields, LambderApiRefusalConfig, LambderContractEntry, LambderGuardNamesIn, LambderContractMode, LambderContractKeysWithMode, LambderContractKeysWithGuard, LambderJsonOf, LambderContractRefusalsOf, LambderContractRefusalMessage, LambderContractRefusals, LambderContractAnyRefusalMessage, LambderContractGuardsOf, LambderContractGuardNames, LambderContractGuardInputsOf, LambderContractGuardInput, LambderContractGuardInputNames, LambderContractRateLimitOf, LambderContractRateLimitNames, LambderContractIdempotencyOf, } from "./shared/wire/LambderApiContract.js";
|
|
144
148
|
export type { LambderRenderContext, LambderSessionRenderContext, LambderHttpEvent, LambderHttpEventFormat } from "./core/LambderContext.js";
|
|
145
149
|
export type { LambderApiAnswerOutcome, LambderApiSuccessOutcome, LambderApiCallFailure, LambderApiValidationFailure, LambderApiEnvelopeFailure, LambderApiHttpAnswer, } from "./shared/wire/LambderApiOutcome.js";
|
|
146
150
|
export { resolveApiOutcome } from "./shared/wire/LambderApiOutcome.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Lambder from './core/Lambder.js';
|
|
2
2
|
export default Lambder;
|
|
3
3
|
export { initLambder } from './core/Lambder.js';
|
|
4
|
+
// How an endpoint is named, and where a call to it goes.
|
|
5
|
+
export { apiCallPath, apiNameOfCallPath, splitApiName, isGroupName, isActionName, LAMBDER_API_NAME_SEGMENT, LAMBDER_CALLER_MEMBER_NAMES, LAMBDER_RESERVED_GROUP_NAMES, LAMBDER_RESERVED_ACTION_NAMES, } from './shared/wire/LambderApiNames.js';
|
|
4
6
|
export { default as LambderCaller } from "./client/LambderCaller.js";
|
|
5
7
|
export { createIdempotencyKey, createIdempotencyKeyScope } from "./shared/wire/LambderIdempotencyKeyScope.js";
|
|
6
8
|
// Transports: how a caller reaches a server (fetch in production, a handler in-process for tests, a cookie jar over either)
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* LambderInvokeCaller.localTransport runs a callee's handler in-process for
|
|
21
21
|
* tests.
|
|
22
22
|
*/
|
|
23
|
+
import { type LambderContractActionOf, type LambderContractGroupsOf, type LambderContractNamesInGroup } from "../shared/wire/LambderApiGroupCalls.js";
|
|
23
24
|
import type { APIGatewayProxyEventV2, Context } from "aws-lambda";
|
|
24
25
|
import { type LambderInvokeFailure, type LambderInvokeOutcome } from "./LambderInvokeOutcome.js";
|
|
25
26
|
import { type LambderApiSignatureMap } from "../shared/wire/LambderApiSignatureMap.js";
|
|
@@ -52,6 +53,10 @@ export type LambderInvokeTransport = (event: APIGatewayProxyEventV2, options: {
|
|
|
52
53
|
}) => Promise<LambderInvokeTransportResult>;
|
|
53
54
|
/** The onLogList option: each answer's logList, success or failure, when it has entries. */
|
|
54
55
|
export type LambderInvokeLogListHandler = (apiName: string, logList: unknown[]) => void | Promise<void>;
|
|
56
|
+
/** The beforeCall option: every call, by its endpoint name or `METHOD path`, before anything is built or sent. */
|
|
57
|
+
export type LambderInvokeCallCheck = (name: string, info: {
|
|
58
|
+
functionName: string;
|
|
59
|
+
}) => void;
|
|
55
60
|
/** The onFailure option: every failed call, once, awaited before api() throws or apiOutcome() returns. */
|
|
56
61
|
export type LambderInvokeFailureHandler = (failure: LambderInvokeFailure, info: {
|
|
57
62
|
apiName: string;
|
|
@@ -119,6 +124,15 @@ type LambderInvokeCallerBaseOptions = {
|
|
|
119
124
|
* apiOutcome() never throws.
|
|
120
125
|
*/
|
|
121
126
|
onFailure?: LambderInvokeFailureHandler;
|
|
127
|
+
/**
|
|
128
|
+
* Run before every call, api(), apiOutcome(), a group's call and
|
|
129
|
+
* request() alike, before anything is built or sent: the place for a
|
|
130
|
+
* rule the calling code must keep, such as never calling out while a
|
|
131
|
+
* database transaction is open. What it throws is thrown to the caller,
|
|
132
|
+
* from apiOutcome() too, and is no failure of the callee: nothing was
|
|
133
|
+
* sent, so onFailure is not told.
|
|
134
|
+
*/
|
|
135
|
+
beforeCall?: LambderInvokeCallCheck;
|
|
122
136
|
/** The session token cookie's name, when a session is carried and the callee uses a non-default `tokenCookieKey`. The CSRF value rides in the envelope's `token` field, which has no name to configure. */
|
|
123
137
|
sessionTokenCookieKey?: string;
|
|
124
138
|
/** Replaces the Lambda SDK. */
|
|
@@ -159,26 +173,15 @@ export type LambderInvokeEventInit = {
|
|
|
159
173
|
sessionTokenCookieKey?: string;
|
|
160
174
|
};
|
|
161
175
|
/**
|
|
176
|
+
* The invoke caller itself, before the groups: what LambderInvokeCaller is,
|
|
177
|
+
* less the callee's endpoints by group (LambderInvokeGroupCalls), which the
|
|
178
|
+
* constructor adds.
|
|
179
|
+
*
|
|
162
180
|
* @typeParam TContract - The callee's API contract (`typeof lambder.ApiContract`, imported type-only), for typed names, payloads, results and guard inputs.
|
|
163
181
|
* @typeParam TProvidedGuards - Guard names guardInputsProvider covers; those APIs' options argument becomes optional.
|
|
164
182
|
*/
|
|
165
|
-
|
|
166
|
-
private
|
|
167
|
-
private readonly apiPath;
|
|
168
|
-
private readonly apiVersion?;
|
|
169
|
-
private readonly apiSignatures?;
|
|
170
|
-
private readonly host;
|
|
171
|
-
private readonly requestCompression;
|
|
172
|
-
private readonly maxResponsePayloadBytes;
|
|
173
|
-
private readonly timeoutMs?;
|
|
174
|
-
private readonly onLogList?;
|
|
175
|
-
private readonly onFailure?;
|
|
176
|
-
private readonly guardInputsProvider?;
|
|
177
|
-
private readonly sessionTokenCookieKey;
|
|
178
|
-
private readonly transport;
|
|
179
|
-
private readonly clientConfig;
|
|
180
|
-
private client;
|
|
181
|
-
private sdk;
|
|
183
|
+
declare class LambderInvokeCallerCore<TContract extends LambderApiContractShape = any, TProvidedGuards extends string = never> {
|
|
184
|
+
#private;
|
|
182
185
|
constructor(options: LambderInvokeCallerOptions<TContract, TProvidedGuards>);
|
|
183
186
|
/**
|
|
184
187
|
* The event api() would send for this call, with a plain payload. For
|
|
@@ -195,19 +198,6 @@ export default class LambderInvokeCaller<TContract extends LambderApiContractSha
|
|
|
195
198
|
* completion regardless, but timeoutMs still frees the caller.
|
|
196
199
|
*/
|
|
197
200
|
static localTransport(handler: (event: APIGatewayProxyEventV2, context: Context) => Promise<unknown>, context?: Partial<Context>): LambderInvokeTransport;
|
|
198
|
-
private loadSdk;
|
|
199
|
-
private invokeThroughSdk;
|
|
200
|
-
/** Delivers one event, serialized exactly once; an event over the invoke cap, a rejected transport, or one that answered after the call was given up on, is a failure. */
|
|
201
|
-
private deliverEvent;
|
|
202
|
-
/** Builds the failure and its error, reports it once, and hands it back. */
|
|
203
|
-
private failureOutcome;
|
|
204
|
-
private surfaceLogs;
|
|
205
|
-
/**
|
|
206
|
-
* One call, one outcome. Never throws; api() is what throws. A key scope
|
|
207
|
-
* is told how the attempt ended, as it is on LambderCaller.
|
|
208
|
-
*/
|
|
209
|
-
private dispatch;
|
|
210
|
-
private dispatchAttempt;
|
|
211
201
|
/**
|
|
212
202
|
* Full-fidelity call: resolves to a discriminated LambderInvokeOutcome
|
|
213
203
|
* instead of throwing, for sites that degrade gracefully. The output type
|
|
@@ -231,4 +221,31 @@ export default class LambderInvokeCaller<TContract extends LambderApiContractSha
|
|
|
231
221
|
*/
|
|
232
222
|
request(init: LambderInvokeRequestInit): Promise<LambderLambdaHttpResult>;
|
|
233
223
|
}
|
|
234
|
-
|
|
224
|
+
/**
|
|
225
|
+
* One endpoint of the callee as the invoke caller hands it out on its group:
|
|
226
|
+
* called, it is `api` for that endpoint (the output, or a thrown
|
|
227
|
+
* LambderInvokeError); `.outcome` is `apiOutcome` (the outcome, never
|
|
228
|
+
* throwing).
|
|
229
|
+
*/
|
|
230
|
+
export type LambderInvokeEndpoint<TContract, TName extends keyof TContract & string, TProvidedGuards extends string> = {
|
|
231
|
+
(...args: LambderCallArgs<TContract, TName, TProvidedGuards, LambderInvokeCallOptions>): Promise<LambderContractOutputOf<TContract, TName>>;
|
|
232
|
+
outcome(...args: LambderCallArgs<TContract, TName, TProvidedGuards, LambderInvokeCallOptions>): Promise<LambderInvokeOutcome<LambderContractOutputOf<TContract, TName>, LambderContractRefusalMessage<TContract, TName>>>;
|
|
233
|
+
};
|
|
234
|
+
/** Every endpoint of the callee's contract, by group: `caller.email.send(input)`. */
|
|
235
|
+
export type LambderInvokeGroupCalls<TContract, TProvidedGuards extends string> = {
|
|
236
|
+
readonly [TGroup in LambderContractGroupsOf<TContract>]: {
|
|
237
|
+
readonly [TName in LambderContractNamesInGroup<TContract, TGroup> as LambderContractActionOf<TName>]: LambderInvokeEndpoint<TContract, TName, TProvidedGuards>;
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* A typed client of another Lambder function, over a direct Lambda invoke:
|
|
242
|
+
* `caller.email.send(input)` for the callee's endpoint `email.send`,
|
|
243
|
+
* `.outcome(input)` for its outcome, and `caller.api("email.send", input)`
|
|
244
|
+
* for code that has the name as a value.
|
|
245
|
+
*/
|
|
246
|
+
type LambderInvokeCaller<TContract extends LambderApiContractShape = any, TProvidedGuards extends string = never> = LambderInvokeCallerCore<TContract, TProvidedGuards> & LambderInvokeGroupCalls<TContract, TProvidedGuards>;
|
|
247
|
+
declare const LambderInvokeCaller: Omit<typeof LambderInvokeCallerCore, "prototype"> & {
|
|
248
|
+
new <TContract extends LambderApiContractShape = any, TProvidedGuards extends string = never>(options: LambderInvokeCallerOptions<TContract, TProvidedGuards>): LambderInvokeCaller<TContract, TProvidedGuards>;
|
|
249
|
+
readonly prototype: LambderInvokeCallerCore<any, any>;
|
|
250
|
+
};
|
|
251
|
+
export default LambderInvokeCaller;
|