@suss/contract-aws-apigateway 0.3.2 → 0.5.0

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/README.md CHANGED
@@ -4,11 +4,11 @@ Generate suss `BehavioralSummary[]` for AWS API Gateway resources (REST + HTTP A
4
4
 
5
5
  ## What this package is
6
6
 
7
- `@suss/contract-aws-apigateway` is a **resource-semantics stub**: it knows what an API Gateway endpoint *does* (status codes, authorizer behavior, CORS preflight, throttling) given a normalized configuration. It does **not** know how that configuration was authored; that's the job of a manifest reader (`@suss/contract-cloudformation`, future CDK/Terraform readers), which parses its source format and hands a normalized config to this package.
7
+ `@suss/contract-aws-apigateway` is a **resource-semantics stub**: given a normalized configuration, it knows what an API Gateway endpoint *does* (status codes, authorizer behavior, CORS preflight, throttling). It does **not** know how someone wrote that configuration; a manifest reader does that job (`@suss/contract-cloudformation`, future CDK/Terraform readers), parsing its source format and handing a normalized config to this package.
8
8
 
9
9
  This separation means: configure your API in CloudFormation, CDK, SAM, or Terraform, and the same resource semantics produce the same summary.
10
10
 
11
- ## Where it sits
11
+ ## Where it fits
12
12
 
13
13
  ```
14
14
  packages/contract/
@@ -23,7 +23,7 @@ packages/contract/
23
23
 
24
24
  A handler that only returns `200` produces a *much* larger behavioral envelope once it's deployed behind API Gateway: an authorizer adds `401`/`403`, request validation adds `400`, throttling adds `429`, integration timeouts add `504`, CORS adds an `OPTIONS` preflight endpoint. Without modeling these, a consumer that handles `429` looks like it has a dead branch, when in reality the platform produces `429` even though the handler doesn't.
25
25
 
26
- These transitions are emitted with `confidence.source: "derived"` and an opaque `Predicate` of the form `platform:apiGateway:<contract>`. Per-transition `metadata` carries attribution (which configuration field introduced this transition) for `inspect`/`diff` output, without forcing consumers to disambiguate platform causes.
26
+ These transitions are emitted with `confidence.source: "derived"` and an opaque `Predicate` of the form `platform:apiGateway:<contract>`. Each transition's `metadata` records where the transition came from (which configuration field introduced it) for `inspect`/`diff` output, so consumers do not have to work out the platform cause themselves.
27
27
 
28
28
  ## Coverage
29
29
 
package/dist/index.cjs CHANGED
@@ -303,11 +303,13 @@ function buildRouteSummary(route, parsed, api, sourceFile) {
303
303
  transitions,
304
304
  gaps: [],
305
305
  confidence: { source: "derived", level: "high" },
306
- metadata: {
307
- apiId: api.id,
308
- apiVersion: "v2",
309
- integrationType: route.integration.type,
310
- http: {
306
+ metadata: (0, import_behavioral_ir2.withHttpMetadata)(
307
+ {
308
+ apiId: api.id,
309
+ apiVersion: "v2",
310
+ integrationType: route.integration.type
311
+ },
312
+ {
311
313
  declaredContract: {
312
314
  framework: FRAMEWORK,
313
315
  provenance: "independent",
@@ -321,7 +323,7 @@ function buildRouteSummary(route, parsed, api, sourceFile) {
321
323
  // REST binding.
322
324
  ...route.implementingHandler !== void 0 ? { implementingHandler: route.implementingHandler } : {}
323
325
  }
324
- }
326
+ )
325
327
  };
326
328
  }
327
329
  function collectPlatformContributions(route, api) {
@@ -475,16 +477,19 @@ function buildEndpointSummary(endpoint, api, sourceFile) {
475
477
  transitions,
476
478
  gaps: [],
477
479
  confidence: { source: "derived", level: "high" },
478
- metadata: {
479
- apiId: api.id,
480
- integrationType: endpoint.integration.type,
481
- http: {
480
+ metadata: (0, import_behavioral_ir3.withHttpMetadata)(
481
+ {
482
+ apiId: api.id,
483
+ integrationType: endpoint.integration.type
484
+ },
485
+ {
482
486
  // The integration's declared status codes (from MethodResponses
483
- // in the CFN template) are the declared contract here. Platform-
484
- // injected transitions (authorizer 401/403, throttle 429, etc.)
485
- // come from SEPARATE config fields and so are independent from
486
- // this contract — contract-consistency comparison is meaningful
487
- // and will surface template-internal inconsistencies.
487
+ // in the CFN template) are the declared contract here.
488
+ // Platform-injected transitions (authorizer 401/403, throttle
489
+ // 429, etc.) come from SEPARATE config fields and so are
490
+ // independent from this contract: contract-consistency
491
+ // comparison is meaningful and will surface template-internal
492
+ // inconsistencies.
488
493
  declaredContract: {
489
494
  framework: FRAMEWORK,
490
495
  provenance: "independent",
@@ -498,7 +503,7 @@ function buildEndpointSummary(endpoint, api, sourceFile) {
498
503
  // same REST binding.
499
504
  ...endpoint.implementingHandler !== void 0 ? { implementingHandler: endpoint.implementingHandler } : {}
500
505
  }
501
- }
506
+ )
502
507
  };
503
508
  }
504
509
  function collectPlatformContributions2(endpoint, api) {
package/dist/index.d.cts CHANGED
@@ -55,13 +55,13 @@ interface RequestValidationConfig {
55
55
  /**
56
56
  * Pointer from a declared route to the code that implements it. A
57
57
  * manifest reader (CFN/SAM, CDK, Terraform) fills this in when it knows
58
- * which module + export backs the route — e.g. a SAM Lambda proxy
59
- * integration whose `Handler` names the file and export. The fields are
58
+ * which module + export backs the route, e.g. a SAM Lambda proxy
59
+ * integration whose `Handler` gives the file and export. The fields are
60
60
  * generic "where is the code" identity, not any one manifest's
61
- * semantics; `aws-apigateway` carries the pointer onto the summary
61
+ * semantics; `aws-apigateway` puts the pointer onto the summary
62
62
  * (`metadata.http.implementingHandler`) without interpreting it, so a
63
63
  * checker can later correlate the declared route with the extracted
64
- * handler summary that carries the same REST binding.
64
+ * handler summary with the same REST binding.
65
65
  */
66
66
  interface HandlerPointer {
67
67
  /** Raw handler reference, e.g. "src/handlers/confirmToken.handler". */
@@ -90,7 +90,7 @@ interface IntegrationConfig {
90
90
  * Status codes the backend integration can produce. For proxy
91
91
  * integrations this is what the handler emits; for non-proxy it's
92
92
  * what `IntegrationResponses` map to. Empty array is allowed and
93
- * means "we don't know" — only platform-injected transitions will
93
+ * means "we don't know", only platform-injected transitions will
94
94
  * be emitted.
95
95
  */
96
96
  statusCodes: number[];
@@ -122,7 +122,7 @@ interface RestEndpointConfig {
122
122
  */
123
123
  name?: string;
124
124
  /**
125
- * Code that implements this endpoint, when the manifest names it
125
+ * Code that implements this endpoint, when the manifest says which
126
126
  * (SAM Lambda proxy `Handler`). Emitted as
127
127
  * `metadata.http.implementingHandler`; purely additive.
128
128
  */
@@ -138,7 +138,7 @@ interface RestApiConfig {
138
138
  /** API-level defaults that cascade onto endpoints unless overridden. */
139
139
  defaultAuthorizer?: AuthorizerConfig;
140
140
  defaultThrottle?: ThrottleConfig;
141
- /** API-level CORS — produces an OPTIONS endpoint per resource path. */
141
+ /** API-level CORS: produces an OPTIONS endpoint per resource path. */
142
142
  cors?: CorsConfig;
143
143
  /** Binary media types declared on the API; doesn't affect transitions. */
144
144
  binaryMediaTypes?: string[];
@@ -161,7 +161,7 @@ interface HttpRouteConfig {
161
161
  throttle?: ThrottleConfig;
162
162
  name?: string;
163
163
  /**
164
- * Code that implements this route, when the manifest names it (SAM
164
+ * Code that implements this route, when the manifest says which (SAM
165
165
  * Lambda proxy `Handler`). Emitted as
166
166
  * `metadata.http.implementingHandler`; purely additive.
167
167
  */
package/dist/index.d.ts CHANGED
@@ -55,13 +55,13 @@ interface RequestValidationConfig {
55
55
  /**
56
56
  * Pointer from a declared route to the code that implements it. A
57
57
  * manifest reader (CFN/SAM, CDK, Terraform) fills this in when it knows
58
- * which module + export backs the route — e.g. a SAM Lambda proxy
59
- * integration whose `Handler` names the file and export. The fields are
58
+ * which module + export backs the route, e.g. a SAM Lambda proxy
59
+ * integration whose `Handler` gives the file and export. The fields are
60
60
  * generic "where is the code" identity, not any one manifest's
61
- * semantics; `aws-apigateway` carries the pointer onto the summary
61
+ * semantics; `aws-apigateway` puts the pointer onto the summary
62
62
  * (`metadata.http.implementingHandler`) without interpreting it, so a
63
63
  * checker can later correlate the declared route with the extracted
64
- * handler summary that carries the same REST binding.
64
+ * handler summary with the same REST binding.
65
65
  */
66
66
  interface HandlerPointer {
67
67
  /** Raw handler reference, e.g. "src/handlers/confirmToken.handler". */
@@ -90,7 +90,7 @@ interface IntegrationConfig {
90
90
  * Status codes the backend integration can produce. For proxy
91
91
  * integrations this is what the handler emits; for non-proxy it's
92
92
  * what `IntegrationResponses` map to. Empty array is allowed and
93
- * means "we don't know" — only platform-injected transitions will
93
+ * means "we don't know", only platform-injected transitions will
94
94
  * be emitted.
95
95
  */
96
96
  statusCodes: number[];
@@ -122,7 +122,7 @@ interface RestEndpointConfig {
122
122
  */
123
123
  name?: string;
124
124
  /**
125
- * Code that implements this endpoint, when the manifest names it
125
+ * Code that implements this endpoint, when the manifest says which
126
126
  * (SAM Lambda proxy `Handler`). Emitted as
127
127
  * `metadata.http.implementingHandler`; purely additive.
128
128
  */
@@ -138,7 +138,7 @@ interface RestApiConfig {
138
138
  /** API-level defaults that cascade onto endpoints unless overridden. */
139
139
  defaultAuthorizer?: AuthorizerConfig;
140
140
  defaultThrottle?: ThrottleConfig;
141
- /** API-level CORS — produces an OPTIONS endpoint per resource path. */
141
+ /** API-level CORS: produces an OPTIONS endpoint per resource path. */
142
142
  cors?: CorsConfig;
143
143
  /** Binary media types declared on the API; doesn't affect transitions. */
144
144
  binaryMediaTypes?: string[];
@@ -161,7 +161,7 @@ interface HttpRouteConfig {
161
161
  throttle?: ThrottleConfig;
162
162
  name?: string;
163
163
  /**
164
- * Code that implements this route, when the manifest names it (SAM
164
+ * Code that implements this route, when the manifest says which (SAM
165
165
  * Lambda proxy `Handler`). Emitted as
166
166
  * `metadata.http.implementingHandler`; purely additive.
167
167
  */
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/http.ts
2
- import { restBinding as restBinding2 } from "@suss/behavioral-ir";
2
+ import { restBinding as restBinding2, withHttpMetadata } from "@suss/behavioral-ir";
3
3
 
4
4
  // src/shared.ts
5
5
  import { restBinding } from "@suss/behavioral-ir";
@@ -276,11 +276,13 @@ function buildRouteSummary(route, parsed, api, sourceFile) {
276
276
  transitions,
277
277
  gaps: [],
278
278
  confidence: { source: "derived", level: "high" },
279
- metadata: {
280
- apiId: api.id,
281
- apiVersion: "v2",
282
- integrationType: route.integration.type,
283
- http: {
279
+ metadata: withHttpMetadata(
280
+ {
281
+ apiId: api.id,
282
+ apiVersion: "v2",
283
+ integrationType: route.integration.type
284
+ },
285
+ {
284
286
  declaredContract: {
285
287
  framework: FRAMEWORK,
286
288
  provenance: "independent",
@@ -294,7 +296,7 @@ function buildRouteSummary(route, parsed, api, sourceFile) {
294
296
  // REST binding.
295
297
  ...route.implementingHandler !== void 0 ? { implementingHandler: route.implementingHandler } : {}
296
298
  }
297
- }
299
+ )
298
300
  };
299
301
  }
300
302
  function collectPlatformContributions(route, api) {
@@ -362,7 +364,7 @@ function uniquePaths(routes) {
362
364
  }
363
365
 
364
366
  // src/rest.ts
365
- import { restBinding as restBinding3 } from "@suss/behavioral-ir";
367
+ import { restBinding as restBinding3, withHttpMetadata as withHttpMetadata2 } from "@suss/behavioral-ir";
366
368
  function restApiToSummaries(config) {
367
369
  const sourceFile = config.source ?? `aws-apigateway:${config.id}`;
368
370
  const summaries = [];
@@ -448,16 +450,19 @@ function buildEndpointSummary(endpoint, api, sourceFile) {
448
450
  transitions,
449
451
  gaps: [],
450
452
  confidence: { source: "derived", level: "high" },
451
- metadata: {
452
- apiId: api.id,
453
- integrationType: endpoint.integration.type,
454
- http: {
453
+ metadata: withHttpMetadata2(
454
+ {
455
+ apiId: api.id,
456
+ integrationType: endpoint.integration.type
457
+ },
458
+ {
455
459
  // The integration's declared status codes (from MethodResponses
456
- // in the CFN template) are the declared contract here. Platform-
457
- // injected transitions (authorizer 401/403, throttle 429, etc.)
458
- // come from SEPARATE config fields and so are independent from
459
- // this contract — contract-consistency comparison is meaningful
460
- // and will surface template-internal inconsistencies.
460
+ // in the CFN template) are the declared contract here.
461
+ // Platform-injected transitions (authorizer 401/403, throttle
462
+ // 429, etc.) come from SEPARATE config fields and so are
463
+ // independent from this contract: contract-consistency
464
+ // comparison is meaningful and will surface template-internal
465
+ // inconsistencies.
461
466
  declaredContract: {
462
467
  framework: FRAMEWORK,
463
468
  provenance: "independent",
@@ -471,7 +476,7 @@ function buildEndpointSummary(endpoint, api, sourceFile) {
471
476
  // same REST binding.
472
477
  ...endpoint.implementingHandler !== void 0 ? { implementingHandler: endpoint.implementingHandler } : {}
473
478
  }
474
- }
479
+ )
475
480
  };
476
481
  }
477
482
  function collectPlatformContributions2(endpoint, api) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/contract-aws-apigateway",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "Generate suss behavioral summaries for AWS API Gateway resources (REST + HTTP API), independent of how they were deployed.",
6
6
  "keywords": [
@@ -45,7 +45,7 @@
45
45
  "typecheck": "tsc --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@suss/behavioral-ir": "0.3.2"
48
+ "@suss/behavioral-ir": "0.5.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "tsup": "*",