lambder 7.2.0 → 7.2.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 CHANGED
@@ -9,6 +9,19 @@ sit on its first published patch, and later patches list only what they changed.
9
9
  Releases up to 3.2.6 carry git tags; the ones after it were published without
10
10
  one, so versions are not cross-linked to tag comparisons here.
11
11
 
12
+ ## [7.2.1] - 2026-09-15
13
+
14
+ ### Added
15
+
16
+ - **`lambder.apiSignatureEntries()`**: the same signatures `apiSignatures()`
17
+ returns, each with the endpoint name it was digested from, sorted by key as
18
+ the map is. The map carries no names, so a generator holding only the map
19
+ could report that four signatures changed but not which endpoints; reading
20
+ the entries it can name them. A build-time view by construction: it comes
21
+ off the server instance, which a generator imports and a client never does.
22
+ `apiSignatures()` is now this with the names dropped, so there is still one
23
+ computation. The `LambderApiSignatureEntry` type is exported from the root.
24
+
12
25
  ## [7.1.5] - 2026-09-15
13
26
 
14
27
  ### Added
@@ -24,7 +37,6 @@ one, so versions are not cross-linked to tag comparisons here.
24
37
  warning, so a mistaken floor cannot refuse the build's own clients.
25
38
  `compareDottedVersions` and `isDottedVersion` are exported from both
26
39
  entries.
27
-
28
40
  ### Changed
29
41
 
30
42
  - **`apiNameKeyOf` memoizes nothing.** It hashed each name it was asked about
@@ -1,5 +1,18 @@
1
1
  import type { LambderApiDefinition } from "./LambderApiDefinition.js";
2
2
  import { type LambderApiGuard } from "./LambderApiGuards.js";
3
+ /**
4
+ * One endpoint as the generator sees it: the key its signature is stored
5
+ * under, the signature, and the name both were computed from. The name is
6
+ * what the shipped map deliberately does not carry, so this is the build-time
7
+ * view of the same data, and the only place a generated map can be diffed by
8
+ * endpoint rather than by opaque key.
9
+ */
10
+ export type LambderApiSignatureEntry = {
11
+ name: string;
12
+ /** The map key: apiNameKeyOf(name). */
13
+ key: string;
14
+ signature: string;
15
+ };
3
16
  /**
4
17
  * The digest of an endpoint's client-facing shape: its name and mode, its
5
18
  * input and output schemas as JSON Schema, every guard it declares with the
@@ -9,6 +9,7 @@ import type LambderSessionController from "../session/LambderSessionController.j
9
9
  import { type LambderPublicFilesOptions } from "./LambderPublicFiles.js";
10
10
  import { type LambderIndexHtmlOptions } from "./LambderIndexHtml.js";
11
11
  import { LambderFiles } from "./LambderFiles.js";
12
+ import { type LambderApiSignatureEntry } from "../api/LambderApiSignature.js";
12
13
  import { type LambderApiSignatureMap } from "../shared/wire/LambderApiSignature.js";
13
14
  import type { LambderApiIdempotencyOption } from "../shared/wire/LambderApiOptionValues.js";
14
15
  import type { LambderApiGuard, LambderGuardMetaMap, LambderGuardsOption, LambderGuardDataOf, LambderGuardInputsOf } from "../api/LambderApiGuards.js";
@@ -181,6 +182,18 @@ export default class Lambder<TSessionData = any, _TContract extends Record<strin
181
182
  * itself. Keys are sorted, so the generated file diffs by endpoint.
182
183
  */
183
184
  apiSignatures(): Promise<LambderApiSignatureMap>;
185
+ /**
186
+ * The same signatures with the endpoint name each one was digested from,
187
+ * sorted by key as the map is. What apiSignatures() leaves out on purpose:
188
+ * the map a client ships lists no names, so a generator that only had the
189
+ * map could report that four signatures changed but not which endpoints.
190
+ * Reading this instead, it can name them.
191
+ *
192
+ * A build-time view by construction. It comes off the server instance,
193
+ * which a generator imports and a client never does, so nothing here
194
+ * reaches a bundle unless the generator writes it there.
195
+ */
196
+ apiSignatureEntries(): Promise<LambderApiSignatureEntry[]>;
184
197
  getResponseBuilder(ctx?: LambderRenderContext): LambderResponseBuilder<any>;
185
198
  private getResolver;
186
199
  getHandler(): LambderHandler;
@@ -298,9 +298,27 @@ export default class Lambder {
298
298
  * itself. Keys are sorted, so the generated file diffs by endpoint.
299
299
  */
300
300
  async apiSignatures() {
301
- const entries = await Promise.all([...this.apiDefinitions.values()].map(async (definition) => [await apiNameKeyOf(definition.name), await apiSignatureOf(definition, this.guards)]));
302
- entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
303
- return Object.fromEntries(entries);
301
+ return Object.fromEntries((await this.apiSignatureEntries()).map(({ key, signature }) => [key, signature]));
302
+ }
303
+ /**
304
+ * The same signatures with the endpoint name each one was digested from,
305
+ * sorted by key as the map is. What apiSignatures() leaves out on purpose:
306
+ * the map a client ships lists no names, so a generator that only had the
307
+ * map could report that four signatures changed but not which endpoints.
308
+ * Reading this instead, it can name them.
309
+ *
310
+ * A build-time view by construction. It comes off the server instance,
311
+ * which a generator imports and a client never does, so nothing here
312
+ * reaches a bundle unless the generator writes it there.
313
+ */
314
+ async apiSignatureEntries() {
315
+ const entries = await Promise.all([...this.apiDefinitions.values()].map(async (definition) => ({
316
+ name: definition.name,
317
+ key: await apiNameKeyOf(definition.name),
318
+ signature: await apiSignatureOf(definition, this.guards),
319
+ })));
320
+ entries.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
321
+ return entries;
304
322
  }
305
323
  getResponseBuilder(ctx) {
306
324
  return new LambderResponseBuilder({
package/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ export { createApiCallContext } from "./api/LambderApiCallContext.js";
26
26
  export type { LambderApiCallContext, LambderApiCallTrace } from "./api/LambderApiCallContext.js";
27
27
  export type { LambderApiDefinition } from "./api/LambderApiDefinition.js";
28
28
  export { apiSignatureOf } from "./api/LambderApiSignature.js";
29
+ export type { LambderApiSignatureEntry } from "./api/LambderApiSignature.js";
29
30
  export { apiNameKeyOf, lookupApiSignature, readApiSignature, API_SIGNATURE_HEX_LENGTH } from "./shared/wire/LambderApiSignature.js";
30
31
  export type { LambderApiSignatureMap } from "./shared/wire/LambderApiSignature.js";
31
32
  export { RELOAD_LOOP_WINDOW_MS } from "./client/LambderReloadLoopBreaker.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "7.2.0",
3
+ "version": "7.2.1",
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": [