lambder 7.0.2 → 7.1.4

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/api/LambderApiDefinition.d.ts +6 -3
  3. package/dist/api/LambderApiEnvelope.d.ts +1 -1
  4. package/dist/api/LambderApiEnvelope.js +1 -1
  5. package/dist/api/LambderApiGuards.d.ts +5 -0
  6. package/dist/api/LambderApiGuards.js +2 -2
  7. package/dist/api/LambderApiPipeline.d.ts +30 -14
  8. package/dist/api/LambderApiPipeline.js +28 -18
  9. package/dist/api/LambderApiRequest.d.ts +3 -1
  10. package/dist/api/LambderApiRequest.js +1 -0
  11. package/dist/api/LambderApiSignature.d.ts +41 -0
  12. package/dist/api/LambderApiSignature.js +91 -0
  13. package/dist/client/LambderCaller.d.ts +13 -0
  14. package/dist/client/LambderCaller.js +21 -1
  15. package/dist/client/LambderReloadLoopBreaker.d.ts +38 -0
  16. package/dist/client/LambderReloadLoopBreaker.js +71 -0
  17. package/dist/client.d.ts +3 -0
  18. package/dist/client.js +3 -0
  19. package/dist/core/Lambder.d.ts +15 -1
  20. package/dist/core/Lambder.js +30 -7
  21. package/dist/core/LambderCreateOptions.d.ts +6 -0
  22. package/dist/core/LambderCreateOptions.js +0 -5
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.js +4 -0
  25. package/dist/invoke/LambderInvokeCaller.d.ts +12 -1
  26. package/dist/invoke/LambderInvokeCaller.js +10 -1
  27. package/dist/invoke/LambderLambdaEvent.d.ts +1 -0
  28. package/dist/invoke/LambderLambdaEvent.js +1 -0
  29. package/dist/mock/LambderMockApp.d.ts +2 -2
  30. package/dist/mock/LambderMockApp.js +21 -13
  31. package/dist/mock/LambderMockCreateOptions.d.ts +10 -1
  32. package/dist/mock/LambderMockCreateOptions.js +0 -8
  33. package/dist/mock/LambderMockTypes.d.ts +2 -0
  34. package/dist/shared/transport/LambderApiTransport.d.ts +3 -0
  35. package/dist/shared/transport/LambderApiTransport.js +2 -0
  36. package/dist/shared/wire/LambderApiSignature.d.ts +33 -0
  37. package/dist/shared/wire/LambderApiSignature.js +44 -0
  38. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ import { sha256HexOf } from "../util/LambderTextDigest.js";
2
+ /**
3
+ * How many hex characters a key and a signature keep. This is change
4
+ * detection, not authentication: 64 bits cannot collide by accident across
5
+ * the shapes one endpoint takes over its life, and the map stays small.
6
+ */
7
+ export const API_SIGNATURE_HEX_LENGTH = 16;
8
+ /** Domain-separated, so a name's key can never equal a signature computed over a description that happens to read the same. */
9
+ const API_NAME_KEY_PREFIX = "lambder-api-name:";
10
+ /** Memoized per name: a caller hashes each endpoint it calls once per process. */
11
+ const nameKeys = new Map();
12
+ /** The key an endpoint's signature is stored under: SHA-256 over the prefixed name, cut to API_SIGNATURE_HEX_LENGTH hex characters. */
13
+ export const apiNameKeyOf = (apiName) => {
14
+ let pending = nameKeys.get(apiName);
15
+ if (!pending) {
16
+ pending = sha256HexOf(API_NAME_KEY_PREFIX + apiName).then((hex) => hex.slice(0, API_SIGNATURE_HEX_LENGTH));
17
+ nameKeys.set(apiName, pending);
18
+ // A failed digest (no WebCrypto) is not kept, so a later call in a
19
+ // context that has it succeeds instead of replaying the rejection.
20
+ pending.catch(() => nameKeys.delete(apiName));
21
+ }
22
+ return pending;
23
+ };
24
+ /** The map's signature for one endpoint, or null when the map holds none for it. */
25
+ export const lookupApiSignature = async (signatures, apiName) => {
26
+ const key = await apiNameKeyOf(apiName);
27
+ // Own properties only: the map is a plain object, and a key that happened
28
+ // to spell a prototype member would otherwise read a function.
29
+ const signature = Object.prototype.hasOwnProperty.call(signatures, key) ? signatures[key] : undefined;
30
+ return typeof signature === "string" ? signature : null;
31
+ };
32
+ /**
33
+ * The signature a caller sends for one endpoint. A name the map does not
34
+ * hold throws: the map was generated from a server that did not have this
35
+ * endpoint, so the file is stale, and a call sent without a signature would
36
+ * run instead of saying so.
37
+ */
38
+ export const readApiSignature = async (signatures, apiName) => {
39
+ const signature = await lookupApiSignature(signatures, apiName);
40
+ if (signature === null) {
41
+ throw new Error(`Lambder: apiSignatures holds no signature for API "${apiName}". The map predates this endpoint; regenerate it from the server's apiSignatures().`);
42
+ }
43
+ return signature;
44
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "7.0.2",
3
+ "version": "7.1.4",
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": [