lambder 7.2.4 → 7.2.5
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/dist/core/Lambder.d.ts
CHANGED
|
@@ -60,10 +60,17 @@ export default class Lambder<TSessionData = any, _TContract extends Record<strin
|
|
|
60
60
|
* Type property for extracting the API contract
|
|
61
61
|
* Use this to export your API types to the frontend
|
|
62
62
|
*
|
|
63
|
+
* Export it as an interface extending LambderFlattenContract, not as a
|
|
64
|
+
* type alias. Chaining builds the contract as an intersection one member
|
|
65
|
+
* deep per endpoint, and an interface collapses that into one declared
|
|
66
|
+
* set of members, which every generic read of the contract (a mock
|
|
67
|
+
* registry, a needs map, the typed caller) is then far cheaper against.
|
|
68
|
+
* See LambderFlattenContract for the measurements.
|
|
69
|
+
*
|
|
63
70
|
* @example
|
|
64
71
|
* ```typescript
|
|
65
72
|
* const lambder = new Lambder().addApi(...).addApi(...);
|
|
66
|
-
* export
|
|
73
|
+
* export interface ApiContractType extends LambderFlattenContract<typeof lambder.ApiContract> {}
|
|
67
74
|
* ```
|
|
68
75
|
*/
|
|
69
76
|
readonly ApiContract: _TContract;
|
package/dist/core/Lambder.js
CHANGED
|
@@ -55,10 +55,17 @@ export default class Lambder {
|
|
|
55
55
|
* Type property for extracting the API contract
|
|
56
56
|
* Use this to export your API types to the frontend
|
|
57
57
|
*
|
|
58
|
+
* Export it as an interface extending LambderFlattenContract, not as a
|
|
59
|
+
* type alias. Chaining builds the contract as an intersection one member
|
|
60
|
+
* deep per endpoint, and an interface collapses that into one declared
|
|
61
|
+
* set of members, which every generic read of the contract (a mock
|
|
62
|
+
* registry, a needs map, the typed caller) is then far cheaper against.
|
|
63
|
+
* See LambderFlattenContract for the measurements.
|
|
64
|
+
*
|
|
58
65
|
* @example
|
|
59
66
|
* ```typescript
|
|
60
67
|
* const lambder = new Lambder().addApi(...).addApi(...);
|
|
61
|
-
* export
|
|
68
|
+
* export interface ApiContractType extends LambderFlattenContract<typeof lambder.ApiContract> {}
|
|
62
69
|
* ```
|
|
63
70
|
*/
|
|
64
71
|
ApiContract;
|
package/dist/index.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ export type { LambderApiIdempotencyConfig } from "./api/LambderApiIdempotency.js
|
|
|
104
104
|
export type { LambderGuardsOptionValue, LambderRateLimitOverride, LambderRateLimitOptionValue, LambderApiIdempotencyOption, } from "./shared/wire/LambderApiOptionValues.js";
|
|
105
105
|
export { createLambderI18n } from "./shared/LambderI18n.js";
|
|
106
106
|
export type { LambderLanguageMeta, LambderI18nConfig, LambderI18nInstance, LambderI18nTranslator, LambderI18nExtractParams, LambderI18nDictionaryLoader, LambderI18nCodes, LambderI18nKeys, LambderI18nTranslatorFor, } from "./shared/LambderI18n.js";
|
|
107
|
-
export type { LambderApiContractShape, LambderApiMode, LambderApiEnvelopeBody, LambderApiResponseConfig, LambderApiNullAnswerConfig, LambderContractEntry, LambderMergeContract, LambderGuardNamesIn, LambderContractMode, LambderContractKeysWithMode, LambderContractGuardsOf, LambderContractGuardNames, LambderContractGuardInputsOf, LambderContractGuardInput, LambderContractGuardInputNames, LambderContractRateLimitOf, LambderContractRateLimitNames, LambderContractIdempotencyOf, } from "./shared/wire/LambderApiContract.js";
|
|
107
|
+
export type { LambderApiContractShape, LambderApiMode, LambderApiEnvelopeBody, LambderApiResponseConfig, LambderApiNullAnswerConfig, LambderContractEntry, LambderMergeContract, LambderFlattenContract, LambderGuardNamesIn, LambderContractMode, LambderContractKeysWithMode, LambderContractGuardsOf, LambderContractGuardNames, LambderContractGuardInputsOf, LambderContractGuardInput, LambderContractGuardInputNames, LambderContractRateLimitOf, LambderContractRateLimitNames, LambderContractIdempotencyOf, } from "./shared/wire/LambderApiContract.js";
|
|
108
108
|
export type { LambderRenderContext, LambderSessionRenderContext, LambderHttpEvent, LambderHttpEventFormat } from "./core/LambderContext.js";
|
|
109
109
|
export type { LambderApiAnswerOutcome, LambderApiSuccessOutcome, LambderApiCallFailure, LambderApiValidationFailure, LambderApiEnvelopeFailure, LambderApiHttpAnswer, } from "./shared/wire/LambderApiOutcome.js";
|
|
110
110
|
export { resolveApiOutcome } from "./shared/wire/LambderApiOutcome.js";
|
|
@@ -85,6 +85,56 @@ export type LambderContractEntry<In, Out, Mode extends LambderApiMode, GuardInpu
|
|
|
85
85
|
export type LambderMergeContract<Old, Name extends string, Entry> = Old & {
|
|
86
86
|
[K in Name]: Entry;
|
|
87
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* The contract as one object type, for the `export interface` a consuming
|
|
90
|
+
* app declares its contract through:
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* export interface ApiContractType extends LambderFlattenContract<typeof lambder.ApiContract> {}
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* Chaining leaves the contract an intersection one member deep per endpoint
|
|
97
|
+
* (LambderMergeContract above), and every `C[K]` written against a type
|
|
98
|
+
* parameter then resolves the property across all of them. That lookup is
|
|
99
|
+
* the atom the reading helpers below are built from, so its cost is paid
|
|
100
|
+
* again by each of them, per endpoint, in every app that registers a mock,
|
|
101
|
+
* declares a needs map, or otherwise reads the contract generically: in a
|
|
102
|
+
* 182-endpoint app one indexed access measured ~3,000 type instantiations
|
|
103
|
+
* and one mock registration ~18,000.
|
|
104
|
+
*
|
|
105
|
+
* Extending an interface is what collapses it. An interface's members are
|
|
106
|
+
* declared, so they are resolved once for the whole declaration rather than
|
|
107
|
+
* per lookup, and the same access measured ~6 instantiations after the
|
|
108
|
+
* change: a 182-endpoint app's frontend type check went from 27.8M
|
|
109
|
+
* instantiations to 7.0M and from 20.2s to 10.6s of check time. The alias
|
|
110
|
+
* form (`type C = LambderFlattenContract<...>`) does NOT do this: a mapped
|
|
111
|
+
* type stays deferred and each lookup pays the full cost again, so the
|
|
112
|
+
* `interface ... extends` spelling is the point.
|
|
113
|
+
*
|
|
114
|
+
* Diagnostics are the same ones, and they read better: a message naming the
|
|
115
|
+
* contract prints the interface by name, where the intersection is printed
|
|
116
|
+
* as a truncated spill of entries.
|
|
117
|
+
*
|
|
118
|
+
* Every endpoint name must be a string literal for an interface to extend
|
|
119
|
+
* the result, which registration through addApi/addSessionApi guarantees.
|
|
120
|
+
*
|
|
121
|
+
* Two things quietly undo it, both of which look like tidying:
|
|
122
|
+
*
|
|
123
|
+
* - `@typescript-eslint/no-empty-object-type` reports the empty body as
|
|
124
|
+
* "equivalent to its supertype" and its fix is a type alias, which is the
|
|
125
|
+
* one spelling that does not collapse anything. Disable the rule on the
|
|
126
|
+
* line rather than taking the fix.
|
|
127
|
+
* - Extending anything but a mapped type loses the inferable index signature.
|
|
128
|
+
* An interface has none of its own, so a hand-written `interface C { ... }`
|
|
129
|
+
* is not assignable to LambderApiContractShape and is rejected by
|
|
130
|
+
* initLambderMock<C>, LambderCaller<C> and LambderInvokeCaller<C>;
|
|
131
|
+
* extending this mapped type is what keeps it. api-contract.test.ts pins
|
|
132
|
+
* that, along with the flattened contract being the same type member for
|
|
133
|
+
* member.
|
|
134
|
+
*/
|
|
135
|
+
export type LambderFlattenContract<C> = {
|
|
136
|
+
[K in keyof C]: C[K];
|
|
137
|
+
};
|
|
88
138
|
/** Guard names referenced by a guards option, whichever of its three forms is used. */
|
|
89
139
|
export type LambderGuardNamesIn<TOpt> = TOpt extends string ? TOpt : TOpt extends readonly (infer N extends string)[] ? N : TOpt extends object ? keyof TOpt & string : never;
|
|
90
140
|
/** The endpoint's mode; a contract written without one admits either. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lambder",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.5",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"description": "Opinionated serverless web framework for TypeScript on AWS Lambda: type-safe APIs from Zod schemas, DynamoDB sessions, and declarative rate limits, authorization guards and idempotency.",
|
|
6
6
|
"keywords": [
|