@webpieces/http-server 0.3.286 → 0.3.287

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/http-server",
3
- "version": "0.3.286",
3
+ "version": "0.3.287",
4
4
  "description": "WebPieces server with filter chain and dependency injection",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -22,11 +22,11 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@webpieces/core-context": "0.3.286",
26
- "@webpieces/core-util": "0.3.286",
27
- "@webpieces/gcp-identity": "0.3.286",
28
- "@webpieces/http-filters": "0.3.286",
29
- "@webpieces/http-routing": "0.3.286",
25
+ "@webpieces/core-context": "0.3.287",
26
+ "@webpieces/core-util": "0.3.287",
27
+ "@webpieces/gcp-identity": "0.3.287",
28
+ "@webpieces/http-filters": "0.3.287",
29
+ "@webpieces/http-routing": "0.3.287",
30
30
  "cors": "2.8.5",
31
31
  "express": "5.1.0",
32
32
  "inversify": "7.10.4"
@@ -1,13 +1,13 @@
1
1
  import { MethodMeta } from '@webpieces/http-routing';
2
2
  import { Filter, WpResponse, Service } from '@webpieces/http-filters';
3
- import { HeaderRegistry } from '@webpieces/core-util';
4
3
  export declare class ContextFilter extends Filter<MethodMeta, WpResponse<unknown>> {
5
- private transferredHeaders;
6
- constructor(registry: HeaderRegistry);
4
+ private transferredKeys;
5
+ constructor();
7
6
  filter(meta: MethodMeta, nextFilter: Service<MethodMeta, WpResponse<unknown>>): Promise<WpResponse<unknown>>;
8
7
  /**
9
- * Transfer platform headers from MethodMeta.requestHeaders to RequestContext.
10
- * Uses HeaderMethods.findTransferHeaders() to filter by isWantTransferred=true.
8
+ * Transfer transferred keys from MethodMeta.requestHeaders to RequestContext.
9
+ * A key is transferred when it has an httpHeader (wire name); the value is read
10
+ * from the incoming request under that httpHeader and stored under the key's name.
11
11
  */
12
12
  private transferHeaders;
13
13
  /**
@@ -31,13 +31,14 @@ const core_util_2 = require("@webpieces/core-util");
31
31
  */
32
32
  const log = core_util_2.LogManager.getLogger('ContextFilter');
33
33
  let ContextFilter = class ContextFilter extends http_filters_1.Filter {
34
- transferredHeaders;
35
- constructor(registry) {
34
+ transferredKeys;
35
+ constructor() {
36
36
  super();
37
- // The registry is the single source of truth (all modules' extensions,
38
- // duplicate-validated at startup)
39
- this.transferredHeaders = registry.getTransferredHeaders();
40
- log.info(`[ContextFilter] Using ${registry.getHeaders().length} platform headers from HeaderRegistry (${this.transferredHeaders.length} transferred)`);
37
+ // The global registry is the single source of truth (configured at startup,
38
+ // duplicate-validated). No DI — HeaderRegistry.configure(...) ran first.
39
+ const registry = core_util_1.HeaderRegistry.get();
40
+ this.transferredKeys = registry.getTransferredKeys();
41
+ log.info(`[ContextFilter] Using ${registry.getKeys().length} context keys from HeaderRegistry (${this.transferredKeys.length} transferred)`);
41
42
  }
42
43
  async filter(meta, nextFilter) {
43
44
  // Transfer platform headers from MethodMeta.requestHeaders to RequestContext
@@ -51,8 +52,9 @@ let ContextFilter = class ContextFilter extends http_filters_1.Filter {
51
52
  // RequestContext is auto-cleared by ExpressWrapper when request completes
52
53
  }
53
54
  /**
54
- * Transfer platform headers from MethodMeta.requestHeaders to RequestContext.
55
- * Uses HeaderMethods.findTransferHeaders() to filter by isWantTransferred=true.
55
+ * Transfer transferred keys from MethodMeta.requestHeaders to RequestContext.
56
+ * A key is transferred when it has an httpHeader (wire name); the value is read
57
+ * from the incoming request under that httpHeader and stored under the key's name.
56
58
  */
57
59
  transferHeaders(meta) {
58
60
  if (!meta.requestHeaders) {
@@ -60,13 +62,12 @@ let ContextFilter = class ContextFilter extends http_filters_1.Filter {
60
62
  this.ensureRequestId();
61
63
  return;
62
64
  }
63
- // Transfer each header to RequestContext using RequestContext.putHeader()
64
- for (const header of this.transferredHeaders) {
65
- // Get values from requestHeaders (case-insensitive lookup)
66
- const values = meta.requestHeaders.get(header.headerName.toLowerCase());
65
+ // Transfer each key to RequestContext (read by wire name, store by key name).
66
+ for (const key of this.transferredKeys) {
67
+ // Get values from requestHeaders (case-insensitive lookup by wire name)
68
+ const values = meta.requestHeaders.get(key.httpHeader.toLowerCase());
67
69
  if (values && values.length > 0) {
68
- // Use RequestContext.putHeader() which calls header.getHeaderName()
69
- core_context_1.RequestContext.putHeader(header, values[0]);
70
+ core_context_1.RequestContext.putHeader(key, values[0]);
70
71
  }
71
72
  }
72
73
  // Clear request headers from MethodMeta - MUST FORCE USAGE of RequestContext!!!
@@ -96,7 +97,6 @@ exports.ContextFilter = ContextFilter;
96
97
  exports.ContextFilter = ContextFilter = tslib_1.__decorate([
97
98
  (0, http_routing_1.provideFrameworkSingleton)(),
98
99
  (0, inversify_1.injectable)(),
99
- tslib_1.__param(0, (0, inversify_1.inject)(core_util_1.HeaderRegistry)),
100
- tslib_1.__metadata("design:paramtypes", [core_util_1.HeaderRegistry])
100
+ tslib_1.__metadata("design:paramtypes", [])
101
101
  ], ContextFilter);
102
102
  //# sourceMappingURL=ContextFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContextFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/ContextFilter.ts"],"names":[],"mappings":"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","sourcesContent":["import {inject, injectable} from 'inversify';\nimport { provideFrameworkSingleton, MethodMeta } from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport { PlatformHeader, HeaderRegistry } from '@webpieces/core-util';\nimport {WebpiecesCoreHeaders} from \"../headers/WebpiecesCoreHeaders\";\nimport {ContextKeys} from \"../headers/ContextKeys\";\nimport { LogManager } from '@webpieces/core-util';\n\n/**\n * ContextFilter - Transfers platform headers and stores request metadata in RequestContext.\n * Priority: 2000 (executes first in filter chain)\n *\n * NEW: Now handles header transfer from RouterRequest to RequestContext\n * - Injects PlatformHeadersExtension instances via @multiInject (safe because filter created after modules load)\n * - Reads headers from RouterRequest (Express-independent)\n * - Transfers only headers marked with isWantTransferred=true\n * - Generates REQUEST_ID if not present\n *\n * RequestContext lifecycle:\n * 1. ExpressWrapper.execute() calls RequestContext.run() (establishes context)\n * 2. ExpressWrapper creates RouterReqResp and MethodMeta\n * 3. Filter chain executes, starting with ContextFilter\n * 4. ContextFilter transfers headers from RouterRequest to RequestContext\n * 5. ContextFilter stores metadata (METHOD_META, REQUEST_PATH, HTTP_METHOD)\n * 6. Downstream filters and controller can access headers + metadata\n * 7. Context auto-clears when RequestContext.run() completes\n */\nconst log = LogManager.getLogger('ContextFilter');\n\n@provideFrameworkSingleton()\n@injectable()\nexport class ContextFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private transferredHeaders: PlatformHeader[];\n\n constructor(\n @inject(HeaderRegistry) registry: HeaderRegistry\n ) {\n super();\n\n // The registry is the single source of truth (all modules' extensions,\n // duplicate-validated at startup)\n this.transferredHeaders = registry.getTransferredHeaders();\n\n log.info(`[ContextFilter] Using ${registry.getHeaders().length} platform headers from HeaderRegistry (${this.transferredHeaders.length} transferred)`);\n }\n\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n // Transfer platform headers from MethodMeta.requestHeaders to RequestContext\n this.transferHeaders(meta);\n\n // Store request metadata in context for other filters/controllers to access\n RequestContext.putHeader(ContextKeys.METHOD_META, meta);\n RequestContext.putHeader(ContextKeys.REQUEST_PATH, meta.path);\n RequestContext.putHeader(ContextKeys.HTTP_METHOD, meta.httpMethod);\n\n // Execute next filter/controller\n return await nextFilter.invoke(meta);\n // RequestContext is auto-cleared by ExpressWrapper when request completes\n }\n\n /**\n * Transfer platform headers from MethodMeta.requestHeaders to RequestContext.\n * Uses HeaderMethods.findTransferHeaders() to filter by isWantTransferred=true.\n */\n private transferHeaders(meta: MethodMeta): void {\n if (!meta.requestHeaders) {\n // No headers in test mode (createApiClient creates context but not headers)\n this.ensureRequestId();\n return;\n }\n\n // Transfer each header to RequestContext using RequestContext.putHeader()\n for (const header of this.transferredHeaders) {\n // Get values from requestHeaders (case-insensitive lookup)\n const values = meta.requestHeaders.get(header.headerName.toLowerCase());\n if (values && values.length > 0) {\n // Use RequestContext.putHeader() which calls header.getHeaderName()\n RequestContext.putHeader(header, values[0]);\n }\n }\n\n // Clear request headers from MethodMeta - MUST FORCE USAGE of RequestContext!!!\n meta.requestHeaders = undefined;\n\n // Generate REQUEST_ID if not present (first service in chain)\n this.ensureRequestId();\n }\n\n /**\n * Ensure REQUEST_ID is set in RequestContext.\n * Generates one if not present.\n */\n private ensureRequestId(): void {\n if (!RequestContext.hasHeader(WebpiecesCoreHeaders.REQUEST_ID)) {\n const requestId = this.generateRequestId();\n RequestContext.putHeader(WebpiecesCoreHeaders.REQUEST_ID, requestId);\n }\n }\n\n /**\n * Generate a unique request ID.\n * Format: req-{timestamp}-{random}\n */\n private generateRequestId(): string {\n return `svrGenReqId-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;\n }\n}\n\n"]}
1
+ {"version":3,"file":"ContextFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/ContextFilter.ts"],"names":[],"mappings":";;;;AAAA,yCAAuC;AACvC,0DAAgF;AAChF,0DAAyD;AACzD,0DAAsE;AACtE,oDAAkE;AAClE,0EAAqE;AACrE,wDAAmD;AACnD,oDAAkD;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,GAAG,GAAG,sBAAU,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;AAI3C,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,qBAAuC;IAC9D,eAAe,CAAe;IAEtC;QACI,KAAK,EAAE,CAAC;QAER,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,QAAQ,GAAG,0BAAc,CAAC,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QAErD,GAAG,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,sCAAsC,IAAI,CAAC,eAAe,CAAC,MAAM,eAAe,CAAC,CAAC;IACjJ,CAAC;IAED,KAAK,CAAC,MAAM,CACR,IAAgB,EAChB,UAAoD;QAEpD,6EAA6E;QAC7E,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAE3B,4EAA4E;QAC5E,6BAAc,CAAC,SAAS,CAAC,yBAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACxD,6BAAc,CAAC,SAAS,CAAC,yBAAW,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,6BAAc,CAAC,SAAS,CAAC,yBAAW,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEnE,iCAAiC;QACjC,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrC,0EAA0E;IAC9E,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,IAAgB;QACpC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvB,4EAA4E;YAC5E,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,OAAO;QACX,CAAC;QAED,8EAA8E;QAC9E,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACrC,wEAAwE;YACxE,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,UAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YACtE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,6BAAc,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QAED,gFAAgF;QAChF,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAEhC,8DAA8D;QAC9D,IAAI,CAAC,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACK,eAAe;QACnB,IAAI,CAAC,6BAAc,CAAC,SAAS,CAAC,2CAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3C,6BAAc,CAAC,SAAS,CAAC,2CAAoB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACzE,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,iBAAiB;QACrB,OAAO,eAAe,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACtF,CAAC;CACJ,CAAA;AA7EY,sCAAa;wBAAb,aAAa;IAFzB,IAAA,wCAAyB,GAAE;IAC3B,IAAA,sBAAU,GAAE;;GACA,aAAa,CA6EzB","sourcesContent":["import { injectable } from 'inversify';\nimport { provideFrameworkSingleton, MethodMeta } from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport { ContextKey, HeaderRegistry } from '@webpieces/core-util';\nimport {WebpiecesCoreHeaders} from \"../headers/WebpiecesCoreHeaders\";\nimport {ContextKeys} from \"../headers/ContextKeys\";\nimport { LogManager } from '@webpieces/core-util';\n\n/**\n * ContextFilter - Transfers platform headers and stores request metadata in RequestContext.\n * Priority: 2000 (executes first in filter chain)\n *\n * NEW: Now handles header transfer from RouterRequest to RequestContext\n * - Injects PlatformHeadersExtension instances via @multiInject (safe because filter created after modules load)\n * - Reads headers from RouterRequest (Express-independent)\n * - Transfers only headers marked with isWantTransferred=true\n * - Generates REQUEST_ID if not present\n *\n * RequestContext lifecycle:\n * 1. ExpressWrapper.execute() calls RequestContext.run() (establishes context)\n * 2. ExpressWrapper creates RouterReqResp and MethodMeta\n * 3. Filter chain executes, starting with ContextFilter\n * 4. ContextFilter transfers headers from RouterRequest to RequestContext\n * 5. ContextFilter stores metadata (METHOD_META, REQUEST_PATH, HTTP_METHOD)\n * 6. Downstream filters and controller can access headers + metadata\n * 7. Context auto-clears when RequestContext.run() completes\n */\nconst log = LogManager.getLogger('ContextFilter');\n\n@provideFrameworkSingleton()\n@injectable()\nexport class ContextFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private transferredKeys: ContextKey[];\n\n constructor() {\n super();\n\n // The global registry is the single source of truth (configured at startup,\n // duplicate-validated). No DI — HeaderRegistry.configure(...) ran first.\n const registry = HeaderRegistry.get();\n this.transferredKeys = registry.getTransferredKeys();\n\n log.info(`[ContextFilter] Using ${registry.getKeys().length} context keys from HeaderRegistry (${this.transferredKeys.length} transferred)`);\n }\n\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n // Transfer platform headers from MethodMeta.requestHeaders to RequestContext\n this.transferHeaders(meta);\n\n // Store request metadata in context for other filters/controllers to access\n RequestContext.putHeader(ContextKeys.METHOD_META, meta);\n RequestContext.putHeader(ContextKeys.REQUEST_PATH, meta.path);\n RequestContext.putHeader(ContextKeys.HTTP_METHOD, meta.httpMethod);\n\n // Execute next filter/controller\n return await nextFilter.invoke(meta);\n // RequestContext is auto-cleared by ExpressWrapper when request completes\n }\n\n /**\n * Transfer transferred keys from MethodMeta.requestHeaders to RequestContext.\n * A key is transferred when it has an httpHeader (wire name); the value is read\n * from the incoming request under that httpHeader and stored under the key's name.\n */\n private transferHeaders(meta: MethodMeta): void {\n if (!meta.requestHeaders) {\n // No headers in test mode (createApiClient creates context but not headers)\n this.ensureRequestId();\n return;\n }\n\n // Transfer each key to RequestContext (read by wire name, store by key name).\n for (const key of this.transferredKeys) {\n // Get values from requestHeaders (case-insensitive lookup by wire name)\n const values = meta.requestHeaders.get(key.httpHeader!.toLowerCase());\n if (values && values.length > 0) {\n RequestContext.putHeader(key, values[0]);\n }\n }\n\n // Clear request headers from MethodMeta - MUST FORCE USAGE of RequestContext!!!\n meta.requestHeaders = undefined;\n\n // Generate REQUEST_ID if not present (first service in chain)\n this.ensureRequestId();\n }\n\n /**\n * Ensure REQUEST_ID is set in RequestContext.\n * Generates one if not present.\n */\n private ensureRequestId(): void {\n if (!RequestContext.hasHeader(WebpiecesCoreHeaders.REQUEST_ID)) {\n const requestId = this.generateRequestId();\n RequestContext.putHeader(WebpiecesCoreHeaders.REQUEST_ID, requestId);\n }\n }\n\n /**\n * Generate a unique request ID.\n * Format: req-{timestamp}-{random}\n */\n private generateRequestId(): string {\n return `svrGenReqId-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;\n }\n}\n\n"]}
@@ -1,10 +1,9 @@
1
1
  import { MethodMeta } from '@webpieces/http-routing';
2
2
  import { Filter, WpResponse, Service } from '@webpieces/http-filters';
3
- import { HeaderMethods, HeaderRegistry } from '@webpieces/core-util';
4
3
  export declare class LogApiFilter extends Filter<MethodMeta, WpResponse<unknown>> {
5
- private headerMethods;
6
4
  private logApiCall;
7
- private allHeaders;
8
- constructor(registry: HeaderRegistry, headerMethods: HeaderMethods);
5
+ private headerMethods;
6
+ private loggedKeys;
7
+ constructor();
9
8
  filter(meta: MethodMeta, nextFilter: Service<MethodMeta, WpResponse<unknown>>): Promise<WpResponse<unknown>>;
10
9
  }
@@ -25,22 +25,21 @@ const core_util_2 = require("@webpieces/core-util");
25
25
  */
26
26
  const log = core_util_1.LogManager.getLogger('LogApiFilter');
27
27
  let LogApiFilter = class LogApiFilter extends http_filters_1.Filter {
28
- headerMethods;
29
28
  logApiCall;
30
- allHeaders;
31
- constructor(registry, headerMethods) {
29
+ headerMethods = new core_util_2.HeaderMethods();
30
+ loggedKeys;
31
+ constructor() {
32
32
  super();
33
- this.headerMethods = headerMethods;
34
- // The registry is the single source of truth (all modules' extensions,
35
- // duplicate-validated at startup). Log map keys use loggerMdcKey when set.
36
- this.allHeaders = registry.getHeaders();
37
- log.info(`[LogApiFilter] Using ${this.allHeaders.length} platform headers from HeaderRegistry`);
33
+ // The global registry is the single source of truth (configured at startup,
34
+ // duplicate-validated). Log map keys off each key's `name`.
35
+ this.loggedKeys = core_util_2.HeaderRegistry.get().getLoggedKeys();
36
+ log.info(`[LogApiFilter] Using ${this.loggedKeys.length} logged context keys from HeaderRegistry`);
38
37
  this.logApiCall = new core_util_2.LogApiCall();
39
38
  }
40
39
  async filter(meta, nextFilter) {
41
- // Build header map from RequestContext (headers are already transferred by ContextFilter)
40
+ // Build log map from RequestContext (keys already transferred by ContextFilter)
42
41
  const contextReader = new http_routing_1.RequestContextReader();
43
- const headers = this.headerMethods.buildSecureMapForLogs(this.allHeaders, contextReader);
42
+ const headers = this.headerMethods.buildSecureMapForLogs(this.loggedKeys, contextReader);
44
43
  // Wrap nextFilter.invoke in a method that returns the response
45
44
  const method = async () => {
46
45
  const wpResponse = await nextFilter.invoke(meta);
@@ -54,9 +53,6 @@ exports.LogApiFilter = LogApiFilter;
54
53
  exports.LogApiFilter = LogApiFilter = tslib_1.__decorate([
55
54
  (0, http_routing_1.provideFrameworkSingleton)(),
56
55
  (0, inversify_1.injectable)(),
57
- tslib_1.__param(0, (0, inversify_1.inject)(core_util_2.HeaderRegistry)),
58
- tslib_1.__param(1, (0, inversify_1.inject)(core_util_2.HeaderMethods)),
59
- tslib_1.__metadata("design:paramtypes", [core_util_2.HeaderRegistry,
60
- core_util_2.HeaderMethods])
56
+ tslib_1.__metadata("design:paramtypes", [])
61
57
  ], LogApiFilter);
62
58
  //# sourceMappingURL=LogApiFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LogApiFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/LogApiFilter.ts"],"names":[],"mappings":";;;;AAAA,yCAA6C;AAC7C,0DAAoG;AACpG,0DAAsE;AACtE,oDAAkD;AAClD,oDAK8B;AAE9B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,GAAG,GAAG,sBAAU,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAI1C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,qBAAuC;IAMlC;IAL3B,UAAU,CAAa;IACvB,UAAU,CAAmB;IAErC,YAC4B,QAAwB,EACjB,aAA4B;QAE3D,KAAK,EAAE,CAAC;QAFuB,kBAAa,GAAb,aAAa,CAAe;QAI3D,uEAAuE;QACvE,2EAA2E;QAC3E,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;QAExC,GAAG,CAAC,IAAI,CAAC,wBAAwB,IAAI,CAAC,UAAU,CAAC,MAAM,uCAAuC,CAAC,CAAC;QAEhG,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAU,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CACR,IAAgB,EAChB,UAAoD;QAEpD,0FAA0F;QAC1F,MAAM,aAAa,GAAG,IAAI,mCAAoB,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEzF,+DAA+D;QAC/D,MAAM,MAAM,GAAG,KAAK,IAAsB,EAAE;YACxC,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,UAAU,CAAC,QAAQ,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACxG,OAAO,IAAI,yBAAU,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACJ,CAAA;AApCY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,wCAAyB,GAAE;IAC3B,IAAA,sBAAU,GAAE;IAMJ,mBAAA,IAAA,kBAAM,EAAC,0BAAc,CAAC,CAAA;IACtB,mBAAA,IAAA,kBAAM,EAAC,yBAAa,CAAC,CAAA;6CADY,0BAAc;QACF,yBAAa;GANtD,YAAY,CAoCxB","sourcesContent":["import {inject, injectable} from 'inversify';\nimport {provideFrameworkSingleton, MethodMeta, RequestContextReader} from '@webpieces/http-routing';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport { LogManager } from '@webpieces/core-util';\nimport {\n PlatformHeader,\n HeaderMethods,\n HeaderRegistry,\n LogApiCall,\n} from '@webpieces/core-util';\n\n/**\n * LogApiFilter - Structured API logging for all requests/responses.\n * Priority: 1800 (after ContextFilter at 2000, before custom filters)\n *\n * Logging patterns (via LogApiCall):\n * - [API-SVR-req] Class.method /url request={...} headers={...}\n * - [API-SVR-resp-SUCCESS] Class.method response={...}\n * - [API-SVR-resp-FAIL] Class.method error=... (server errors: 500, 502, 504)\n * - [API-SVR-resp-OTHER] Class.method errorType=... (user errors: 400, 401, 403, 404, 266)\n *\n * Headers are read from RequestContext (NOT from meta.requestHeaders which is undefined\n * after ContextFilter runs at priority 2000).\n *\n * User errors (HttpBadRequestError, etc.) are logged as OTHER, not FAIL,\n * because they are expected behavior from the server's perspective.\n */\nconst log = LogManager.getLogger('LogApiFilter');\n\n@provideFrameworkSingleton()\n@injectable()\nexport class LogApiFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private logApiCall: LogApiCall;\n private allHeaders: PlatformHeader[];\n\n constructor(\n @inject(HeaderRegistry) registry: HeaderRegistry,\n @inject(HeaderMethods) private headerMethods: HeaderMethods\n ) {\n super();\n\n // The registry is the single source of truth (all modules' extensions,\n // duplicate-validated at startup). Log map keys use loggerMdcKey when set.\n this.allHeaders = registry.getHeaders();\n\n log.info(`[LogApiFilter] Using ${this.allHeaders.length} platform headers from HeaderRegistry`);\n\n this.logApiCall = new LogApiCall();\n }\n\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n // Build header map from RequestContext (headers are already transferred by ContextFilter)\n const contextReader = new RequestContextReader();\n const headers = this.headerMethods.buildSecureMapForLogs(this.allHeaders, contextReader);\n\n // Wrap nextFilter.invoke in a method that returns the response\n const method = async (): Promise<unknown> => {\n const wpResponse = await nextFilter.invoke(meta);\n return wpResponse.response;\n };\n\n const response = await this.logApiCall.execute(\"SVR\", meta.routeMeta, meta.requestDto, headers, method);\n return new WpResponse(response);\n }\n}\n"]}
1
+ {"version":3,"file":"LogApiFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/LogApiFilter.ts"],"names":[],"mappings":";;;;AAAA,yCAAuC;AACvC,0DAAoG;AACpG,0DAAsE;AACtE,oDAAkD;AAClD,oDAK8B;AAE9B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,GAAG,GAAG,sBAAU,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAI1C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,qBAAuC;IAC7D,UAAU,CAAa;IACvB,aAAa,GAAG,IAAI,yBAAa,EAAE,CAAC;IACpC,UAAU,CAAe;IAEjC;QACI,KAAK,EAAE,CAAC;QAER,4EAA4E;QAC5E,4DAA4D;QAC5D,IAAI,CAAC,UAAU,GAAG,0BAAc,CAAC,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;QAEvD,GAAG,CAAC,IAAI,CAAC,wBAAwB,IAAI,CAAC,UAAU,CAAC,MAAM,0CAA0C,CAAC,CAAC;QAEnG,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAU,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CACR,IAAgB,EAChB,UAAoD;QAEpD,gFAAgF;QAChF,MAAM,aAAa,GAAG,IAAI,mCAAoB,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEzF,+DAA+D;QAC/D,MAAM,MAAM,GAAG,KAAK,IAAsB,EAAE;YACxC,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,UAAU,CAAC,QAAQ,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACxG,OAAO,IAAI,yBAAU,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACJ,CAAA;AAlCY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,wCAAyB,GAAE;IAC3B,IAAA,sBAAU,GAAE;;GACA,YAAY,CAkCxB","sourcesContent":["import { injectable } from 'inversify';\nimport {provideFrameworkSingleton, MethodMeta, RequestContextReader} from '@webpieces/http-routing';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport { LogManager } from '@webpieces/core-util';\nimport {\n ContextKey,\n HeaderMethods,\n HeaderRegistry,\n LogApiCall,\n} from '@webpieces/core-util';\n\n/**\n * LogApiFilter - Structured API logging for all requests/responses.\n * Priority: 1800 (after ContextFilter at 2000, before custom filters)\n *\n * Logging patterns (via LogApiCall):\n * - [API-SVR-req] Class.method /url request={...} headers={...}\n * - [API-SVR-resp-SUCCESS] Class.method response={...}\n * - [API-SVR-resp-FAIL] Class.method error=... (server errors: 500, 502, 504)\n * - [API-SVR-resp-OTHER] Class.method errorType=... (user errors: 400, 401, 403, 404, 266)\n *\n * Headers are read from RequestContext (NOT from meta.requestHeaders which is undefined\n * after ContextFilter runs at priority 2000).\n *\n * User errors (HttpBadRequestError, etc.) are logged as OTHER, not FAIL,\n * because they are expected behavior from the server's perspective.\n */\nconst log = LogManager.getLogger('LogApiFilter');\n\n@provideFrameworkSingleton()\n@injectable()\nexport class LogApiFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private logApiCall: LogApiCall;\n private headerMethods = new HeaderMethods();\n private loggedKeys: ContextKey[];\n\n constructor() {\n super();\n\n // The global registry is the single source of truth (configured at startup,\n // duplicate-validated). Log map keys off each key's `name`.\n this.loggedKeys = HeaderRegistry.get().getLoggedKeys();\n\n log.info(`[LogApiFilter] Using ${this.loggedKeys.length} logged context keys from HeaderRegistry`);\n\n this.logApiCall = new LogApiCall();\n }\n\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n // Build log map from RequestContext (keys already transferred by ContextFilter)\n const contextReader = new RequestContextReader();\n const headers = this.headerMethods.buildSecureMapForLogs(this.loggedKeys, contextReader);\n\n // Wrap nextFilter.invoke in a method that returns the response\n const method = async (): Promise<unknown> => {\n const wpResponse = await nextFilter.invoke(meta);\n return wpResponse.response;\n };\n\n const response = await this.logApiCall.execute(\"SVR\", meta.routeMeta, meta.requestDto, headers, method);\n return new WpResponse(response);\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import { MethodMeta, WebpiecesConfig } from '@webpieces/http-routing';
2
2
  import { Filter, WpResponse, Service } from '@webpieces/http-filters';
3
- import { HeaderRegistry } from '@webpieces/core-util';
4
3
  /**
5
4
  * RecordingFilter - Records a request as a replayable test case (port of Java
6
5
  * RecordingFilter).
@@ -21,9 +20,8 @@ import { HeaderRegistry } from '@webpieces/core-util';
21
20
  */
22
21
  export declare class RecordingFilter extends Filter<MethodMeta, WpResponse<unknown>> {
23
22
  private config;
24
- private registry;
25
23
  private headerMethods;
26
- constructor(config: WebpiecesConfig, registry: HeaderRegistry);
24
+ constructor(config: WebpiecesConfig);
27
25
  filter(meta: MethodMeta, nextFilter: Service<MethodMeta, WpResponse<unknown>>): Promise<WpResponse<unknown>>;
28
26
  private isRecordingRequested;
29
27
  private buildServerEndpoint;
@@ -28,12 +28,10 @@ const TestCaseRecorderImpl_1 = require("../recorder/TestCaseRecorderImpl");
28
28
  */
29
29
  let RecordingFilter = class RecordingFilter extends http_filters_1.Filter {
30
30
  config;
31
- registry;
32
31
  headerMethods = new core_util_1.HeaderMethods();
33
- constructor(config, registry) {
32
+ constructor(config) {
34
33
  super();
35
34
  this.config = config;
36
- this.registry = registry;
37
35
  }
38
36
  // webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility
39
37
  async filter(meta, nextFilter) {
@@ -55,7 +53,7 @@ let RecordingFilter = class RecordingFilter extends http_filters_1.Filter {
55
53
  throw err;
56
54
  }
57
55
  finally {
58
- core_context_1.RequestContext.remove(core_util_1.RecorderKeys.RECORDER.getHeaderName());
56
+ core_context_1.RequestContext.remove(core_util_1.RecorderKeys.RECORDER.name);
59
57
  recorder.spitOutTestCase(serverEndpoint, this.config.recordingDir);
60
58
  }
61
59
  }
@@ -67,8 +65,8 @@ let RecordingFilter = class RecordingFilter extends http_filters_1.Filter {
67
65
  return core_context_1.RequestContext.hasHeader(core_util_1.WebpiecesCoreHeaders.RECORDING);
68
66
  }
69
67
  buildServerEndpoint(meta) {
70
- // Masked snapshot of the magic context (secured values masked, MDC keys)
71
- const logMap = this.headerMethods.buildSecureMapForLogs(this.registry.getHeaders(), new http_routing_1.RequestContextReader());
68
+ // Masked snapshot of the magic context (secured values masked, keyed by name)
69
+ const logMap = this.headerMethods.buildSecureMapForLogs(core_util_1.HeaderRegistry.get().getLoggedKeys(), new http_routing_1.RequestContextReader());
72
70
  const ctxSnapshot = {};
73
71
  for (const entry of logMap.entries()) {
74
72
  ctxSnapshot[entry[0]] = entry[1];
@@ -84,8 +82,6 @@ exports.RecordingFilter = RecordingFilter = tslib_1.__decorate([
84
82
  // webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility
85
83
  ,
86
84
  tslib_1.__param(0, (0, inversify_1.inject)(http_routing_1.WEBPIECES_CONFIG_TOKEN)),
87
- tslib_1.__param(1, (0, inversify_1.inject)(core_util_1.HeaderRegistry)),
88
- tslib_1.__metadata("design:paramtypes", [http_routing_1.WebpiecesConfig,
89
- core_util_1.HeaderRegistry])
85
+ tslib_1.__metadata("design:paramtypes", [http_routing_1.WebpiecesConfig])
90
86
  ], RecordingFilter);
91
87
  //# sourceMappingURL=RecordingFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RecordingFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/RecordingFilter.ts"],"names":[],"mappings":"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","sourcesContent":["import { inject, injectable } from 'inversify';\nimport {\n provideFrameworkSingleton,\n MethodMeta,\n RequestContextReader,\n WebpiecesConfig,\n WEBPIECES_CONFIG_TOKEN,\n} from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport {\n HeaderMethods,\n HeaderRegistry,\n RecordedEndpoint,\n RecordedError,\n RecorderKeys,\n WebpiecesCoreHeaders,\n toError,\n} from '@webpieces/core-util';\nimport { TestCaseRecorderImpl } from '../recorder/TestCaseRecorderImpl';\n\n/**\n * RecordingFilter - Records a request as a replayable test case (port of Java\n * RecordingFilter).\n *\n * Suggested priority: 1850 (after ContextFilter 2000 so the RECORDING header\n * has been transferred to the context, after AuthFilter 1900 so only real\n * authorized flows are recorded, before LogApiFilter 1800).\n *\n * Activates when WebpiecesConfig.recordingAlwaysOn is set OR the request\n * carries WebpiecesCoreHeaders.RECORDING (x-webpieces-recording). While\n * active, a TestCaseRecorderImpl travels in the RequestContext under\n * RecorderKeys.RECORDER; the http-client proxy and recordable() wrappers add\n * every downstream call. On completion the fixture + generated spec are\n * logged (and written to config.recordingDir when set).\n *\n * Recording NEVER alters the response - failures inside the recorder are\n * caught and logged.\n */\n@provideFrameworkSingleton()\n@injectable()\n// webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\nexport class RecordingFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private headerMethods = new HeaderMethods();\n\n constructor(\n @inject(WEBPIECES_CONFIG_TOKEN) private config: WebpiecesConfig,\n @inject(HeaderRegistry) private registry: HeaderRegistry,\n ) {\n super();\n }\n\n // webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n if (!this.isRecordingRequested()) {\n return await nextFilter.invoke(meta);\n }\n\n const recorder = new TestCaseRecorderImpl();\n RequestContext.putHeader(RecorderKeys.RECORDER, recorder);\n\n const serverEndpoint = this.buildServerEndpoint(meta);\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- capture failure into the recording, then rethrow unchanged\n try {\n const response = await nextFilter.invoke(meta);\n serverEndpoint.successResponse = response.response;\n return response;\n } catch (err: unknown) {\n const error = toError(err);\n serverEndpoint.failureResponse = new RecordedError(error.name, error.message);\n throw err;\n } finally {\n RequestContext.remove(RecorderKeys.RECORDER.getHeaderName());\n recorder.spitOutTestCase(serverEndpoint, this.config.recordingDir);\n }\n }\n\n private isRecordingRequested(): boolean {\n if (this.config.recordingAlwaysOn) {\n return true;\n }\n // ContextFilter (priority 2000) already transferred the header into context\n return RequestContext.hasHeader(WebpiecesCoreHeaders.RECORDING);\n }\n\n private buildServerEndpoint(meta: MethodMeta): RecordedEndpoint {\n // Masked snapshot of the magic context (secured values masked, MDC keys)\n const logMap = this.headerMethods.buildSecureMapForLogs(this.registry.getHeaders(), new RequestContextReader());\n const ctxSnapshot: Record<string, string> = {};\n for (const entry of logMap.entries()) {\n ctxSnapshot[entry[0]] = entry[1];\n }\n\n const apiName = meta.routeMeta.controllerClassName ?? 'UnknownController';\n return new RecordedEndpoint(apiName, meta.methodName, [meta.requestDto], ctxSnapshot);\n }\n}\n"]}
1
+ {"version":3,"file":"RecordingFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/RecordingFilter.ts"],"names":[],"mappings":";;;;AAAA,yCAA+C;AAC/C,0DAMiC;AACjC,0DAAyD;AACzD,0DAAsE;AACtE,oDAQ8B;AAE9B,2EAAwE;AAExE;;;;;;;;;;;;;;;;;GAiBG;AAII,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,qBAAuC;IAI5B;IAHpC,aAAa,GAAG,IAAI,yBAAa,EAAE,CAAC;IAE5C,YAC4C,MAAuB;QAE/D,KAAK,EAAE,CAAC;QAFgC,WAAM,GAAN,MAAM,CAAiB;IAGnE,CAAC;IAED,sGAAsG;IACtG,KAAK,CAAC,MAAM,CACR,IAAgB,EAChB,UAAoD;QAEpD,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAC/B,OAAO,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,2CAAoB,EAAE,CAAC;QAC5C,6BAAc,CAAC,SAAS,CAAC,wBAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE1D,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAEtD,4HAA4H;QAC5H,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/C,cAAc,CAAC,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC;YACnD,OAAO,QAAQ,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,mBAAO,EAAC,GAAG,CAAC,CAAC;YAC3B,cAAc,CAAC,eAAe,GAAG,IAAI,yBAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9E,MAAM,GAAG,CAAC;QACd,CAAC;gBAAS,CAAC;YACP,6BAAc,CAAC,MAAM,CAAC,wBAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClD,QAAQ,CAAC,eAAe,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACvE,CAAC;IACL,CAAC;IAEO,oBAAoB;QACxB,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,4EAA4E;QAC5E,OAAO,6BAAc,CAAC,SAAS,CAAC,gCAAoB,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;IAEO,mBAAmB,CAAC,IAAgB;QACxC,8EAA8E;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,0BAAc,CAAC,GAAG,EAAE,CAAC,aAAa,EAAE,EAAE,IAAI,mCAAoB,EAAE,CAAC,CAAC;QAC1H,MAAM,WAAW,GAA2B,EAAE,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACnC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,IAAI,mBAAmB,CAAC;QAC1E,OAAO,IAAI,4BAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1F,CAAC;CACJ,CAAA;AAzDY,0CAAe;0BAAf,eAAe;IAH3B,IAAA,wCAAyB,GAAE;IAC3B,IAAA,sBAAU,GAAE;IACb,sGAAsG;;IAK7F,mBAAA,IAAA,kBAAM,EAAC,qCAAsB,CAAC,CAAA;6CAAiB,8BAAe;GAJ1D,eAAe,CAyD3B","sourcesContent":["import { inject, injectable } from 'inversify';\nimport {\n provideFrameworkSingleton,\n MethodMeta,\n RequestContextReader,\n WebpiecesConfig,\n WEBPIECES_CONFIG_TOKEN,\n} from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-filters';\nimport {\n HeaderMethods,\n HeaderRegistry,\n RecordedEndpoint,\n RecordedError,\n RecorderKeys,\n WebpiecesCoreHeaders,\n toError,\n} from '@webpieces/core-util';\n\nimport { TestCaseRecorderImpl } from '../recorder/TestCaseRecorderImpl';\n\n/**\n * RecordingFilter - Records a request as a replayable test case (port of Java\n * RecordingFilter).\n *\n * Suggested priority: 1850 (after ContextFilter 2000 so the RECORDING header\n * has been transferred to the context, after AuthFilter 1900 so only real\n * authorized flows are recorded, before LogApiFilter 1800).\n *\n * Activates when WebpiecesConfig.recordingAlwaysOn is set OR the request\n * carries WebpiecesCoreHeaders.RECORDING (x-webpieces-recording). While\n * active, a TestCaseRecorderImpl travels in the RequestContext under\n * RecorderKeys.RECORDER; the http-client proxy and recordable() wrappers add\n * every downstream call. On completion the fixture + generated spec are\n * logged (and written to config.recordingDir when set).\n *\n * Recording NEVER alters the response - failures inside the recorder are\n * caught and logged.\n */\n@provideFrameworkSingleton()\n@injectable()\n// webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\nexport class RecordingFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n private headerMethods = new HeaderMethods();\n\n constructor(\n @inject(WEBPIECES_CONFIG_TOKEN) private config: WebpiecesConfig,\n ) {\n super();\n }\n\n // webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\n if (!this.isRecordingRequested()) {\n return await nextFilter.invoke(meta);\n }\n\n const recorder = new TestCaseRecorderImpl();\n RequestContext.putHeader(RecorderKeys.RECORDER, recorder);\n\n const serverEndpoint = this.buildServerEndpoint(meta);\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- capture failure into the recording, then rethrow unchanged\n try {\n const response = await nextFilter.invoke(meta);\n serverEndpoint.successResponse = response.response;\n return response;\n } catch (err: unknown) {\n const error = toError(err);\n serverEndpoint.failureResponse = new RecordedError(error.name, error.message);\n throw err;\n } finally {\n RequestContext.remove(RecorderKeys.RECORDER.name);\n recorder.spitOutTestCase(serverEndpoint, this.config.recordingDir);\n }\n }\n\n private isRecordingRequested(): boolean {\n if (this.config.recordingAlwaysOn) {\n return true;\n }\n // ContextFilter (priority 2000) already transferred the header into context\n return RequestContext.hasHeader(WebpiecesCoreHeaders.RECORDING);\n }\n\n private buildServerEndpoint(meta: MethodMeta): RecordedEndpoint {\n // Masked snapshot of the magic context (secured values masked, keyed by name)\n const logMap = this.headerMethods.buildSecureMapForLogs(HeaderRegistry.get().getLoggedKeys(), new RequestContextReader());\n const ctxSnapshot: Record<string, string> = {};\n for (const entry of logMap.entries()) {\n ctxSnapshot[entry[0]] = entry[1];\n }\n\n const apiName = meta.routeMeta.controllerClassName ?? 'UnknownController';\n return new RecordedEndpoint(apiName, meta.methodName, [meta.requestDto], ctxSnapshot);\n }\n}\n"]}
@@ -3,7 +3,8 @@ import { ContextKey } from '@webpieces/core-util';
3
3
  * Framework-level context keys for non-HTTP values stored in RequestContext.
4
4
  *
5
5
  * These are set by ContextFilter and can be read by downstream filters/controllers.
6
- * Unlike PlatformHeader, these don't correspond to HTTP headers.
6
+ * They have no httpHeader (never transferred) and isLogged=false (they hold objects
7
+ * / internal values that must not be serialized into log lines).
7
8
  */
8
9
  export declare class ContextKeys {
9
10
  static readonly METHOD_META: ContextKey;
@@ -6,12 +6,13 @@ const core_util_1 = require("@webpieces/core-util");
6
6
  * Framework-level context keys for non-HTTP values stored in RequestContext.
7
7
  *
8
8
  * These are set by ContextFilter and can be read by downstream filters/controllers.
9
- * Unlike PlatformHeader, these don't correspond to HTTP headers.
9
+ * They have no httpHeader (never transferred) and isLogged=false (they hold objects
10
+ * / internal values that must not be serialized into log lines).
10
11
  */
11
12
  class ContextKeys {
12
- static METHOD_META = new core_util_1.ContextKey('webpieces:method-meta');
13
- static REQUEST_PATH = new core_util_1.ContextKey('webpieces:request-path');
14
- static HTTP_METHOD = new core_util_1.ContextKey('webpieces:http-method');
13
+ static METHOD_META = new core_util_1.ContextKey('webpieces:method-meta', undefined, false, /*isLogged*/ false);
14
+ static REQUEST_PATH = new core_util_1.ContextKey('webpieces:request-path', undefined, false, /*isLogged*/ false);
15
+ static HTTP_METHOD = new core_util_1.ContextKey('webpieces:http-method', undefined, false, /*isLogged*/ false);
15
16
  }
16
17
  exports.ContextKeys = ContextKeys;
17
18
  //# sourceMappingURL=ContextKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContextKeys.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/headers/ContextKeys.ts"],"names":[],"mappings":";;;AAAA,oDAAkD;AAElD;;;;;GAKG;AACH,MAAa,WAAW;IACpB,MAAM,CAAU,WAAW,GAAG,IAAI,sBAAU,CAAC,uBAAuB,CAAC,CAAC;IACtE,MAAM,CAAU,YAAY,GAAG,IAAI,sBAAU,CAAC,wBAAwB,CAAC,CAAC;IACxE,MAAM,CAAU,WAAW,GAAG,IAAI,sBAAU,CAAC,uBAAuB,CAAC,CAAC;;AAH1E,kCAIC","sourcesContent":["import { ContextKey } from '@webpieces/core-util';\n\n/**\n * Framework-level context keys for non-HTTP values stored in RequestContext.\n *\n * These are set by ContextFilter and can be read by downstream filters/controllers.\n * Unlike PlatformHeader, these don't correspond to HTTP headers.\n */\nexport class ContextKeys {\n static readonly METHOD_META = new ContextKey('webpieces:method-meta');\n static readonly REQUEST_PATH = new ContextKey('webpieces:request-path');\n static readonly HTTP_METHOD = new ContextKey('webpieces:http-method');\n}\n"]}
1
+ {"version":3,"file":"ContextKeys.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/headers/ContextKeys.ts"],"names":[],"mappings":";;;AAAA,oDAAkD;AAElD;;;;;;GAMG;AACH,MAAa,WAAW;IACpB,MAAM,CAAU,WAAW,GAAG,IAAI,sBAAU,CAAC,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5G,MAAM,CAAU,YAAY,GAAG,IAAI,sBAAU,CAAC,wBAAwB,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC9G,MAAM,CAAU,WAAW,GAAG,IAAI,sBAAU,CAAC,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;;AAHhH,kCAIC","sourcesContent":["import { ContextKey } from '@webpieces/core-util';\n\n/**\n * Framework-level context keys for non-HTTP values stored in RequestContext.\n *\n * These are set by ContextFilter and can be read by downstream filters/controllers.\n * They have no httpHeader (never transferred) and isLogged=false (they hold objects\n * / internal values that must not be serialized into log lines).\n */\nexport class ContextKeys {\n static readonly METHOD_META = new ContextKey('webpieces:method-meta', undefined, false, /*isLogged*/ false);\n static readonly REQUEST_PATH = new ContextKey('webpieces:request-path', undefined, false, /*isLogged*/ false);\n static readonly HTTP_METHOD = new ContextKey('webpieces:http-method', undefined, false, /*isLogged*/ false);\n}\n"]}
package/src/index.d.ts CHANGED
@@ -9,7 +9,6 @@ export { ServiceAuthFilter } from './filters/ServiceAuthFilter';
9
9
  export { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';
10
10
  export { SpecGenerator } from './recorder/SpecGenerator';
11
11
  export { recordable } from './recorder/recordable';
12
- export { WebpiecesModule } from './modules/WebpiecesModule';
13
12
  export { WebpiecesCoreHeaders } from './headers/WebpiecesCoreHeaders';
14
13
  export { HeaderRegistry } from '@webpieces/core-util';
15
14
  export { RouteHandler, MethodMeta, RouteBuilderImpl, RouteHandlerWithMeta, FilterWithMeta, HttpFilter, FilterMatcher, FilterDefinition, } from '@webpieces/http-routing';
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FilterDefinition = exports.FilterMatcher = exports.FilterWithMeta = exports.RouteHandlerWithMeta = exports.RouteBuilderImpl = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.WebpiecesModule = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.ServiceAuthFilter = exports.RecordingFilter = exports.LogApiFilter = exports.ContextFilter = exports.InProcessApiClientFactory = exports.WebpiecesRouteCreator = exports.WebpiecesMiddleware = exports.WebpiecesExpress = void 0;
3
+ exports.FilterDefinition = exports.FilterMatcher = exports.FilterWithMeta = exports.RouteHandlerWithMeta = exports.RouteBuilderImpl = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.ServiceAuthFilter = exports.RecordingFilter = exports.LogApiFilter = exports.ContextFilter = exports.InProcessApiClientFactory = exports.WebpiecesRouteCreator = exports.WebpiecesMiddleware = exports.WebpiecesExpress = void 0;
4
4
  // Express adapter (the only place express lifecycle lives) over the node-only WebpiecesRouter
5
5
  var WebpiecesExpress_1 = require("./WebpiecesExpress");
6
6
  Object.defineProperty(exports, "WebpiecesExpress", { enumerable: true, get: function () { return WebpiecesExpress_1.WebpiecesExpress; } });
@@ -26,9 +26,7 @@ var SpecGenerator_1 = require("./recorder/SpecGenerator");
26
26
  Object.defineProperty(exports, "SpecGenerator", { enumerable: true, get: function () { return SpecGenerator_1.SpecGenerator; } });
27
27
  var recordable_1 = require("./recorder/recordable");
28
28
  Object.defineProperty(exports, "recordable", { enumerable: true, get: function () { return recordable_1.recordable; } });
29
- // Platform Headers
30
- var WebpiecesModule_1 = require("./modules/WebpiecesModule");
31
- Object.defineProperty(exports, "WebpiecesModule", { enumerable: true, get: function () { return WebpiecesModule_1.WebpiecesModule; } });
29
+ // Context keys + registry (the global magic-context header system)
32
30
  var WebpiecesCoreHeaders_1 = require("./headers/WebpiecesCoreHeaders");
33
31
  Object.defineProperty(exports, "WebpiecesCoreHeaders", { enumerable: true, get: function () { return WebpiecesCoreHeaders_1.WebpiecesCoreHeaders; } });
34
32
  var core_util_1 = require("@webpieces/core-util");
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/index.ts"],"names":[],"mappings":";;;AAAA,8FAA8F;AAC9F,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,uFAAuF;AACvF,wDAAoE;AAA3D,yHAAA,yBAAyB,OAAA;AAClC,yDAAwD;AAA/C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,4GAAA,YAAY,OAAA;AACrB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,iEAAgE;AAAvD,sHAAA,iBAAiB,OAAA;AAE1B,+DAA+D;AAC/D,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,oDAAmD;AAA1C,wGAAA,UAAU,OAAA;AAEnB,mBAAmB;AACnB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,uEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,kDAAsD;AAA7C,2GAAA,cAAc,OAAA;AAEvB,yDAAyD;AACzD,mEAAmE;AACnE,wDASiC;AAR7B,4GAAA,YAAY,OAAA;AACZ,0GAAA,UAAU,OAAA;AACV,gHAAA,gBAAgB,OAAA;AAChB,oHAAA,oBAAoB,OAAA;AACpB,8GAAA,cAAc,OAAA;AAEd,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA","sourcesContent":["// Express adapter (the only place express lifecycle lives) over the node-only WebpiecesRouter\nexport { WebpiecesExpress } from './WebpiecesExpress';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\nexport { WebpiecesRouteCreator } from './WebpiecesRouteCreator';\n// InProcessApiClientFactory moved to node-only http-routing; re-export for back-compat\nexport { InProcessApiClientFactory } from '@webpieces/http-routing';\nexport { ContextFilter } from './filters/ContextFilter';\nexport { LogApiFilter } from './filters/LogApiFilter';\nexport { RecordingFilter } from './filters/RecordingFilter';\nexport { ServiceAuthFilter } from './filters/ServiceAuthFilter';\n\n// Test-case recording (contract lives in @webpieces/core-util)\nexport { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';\nexport { SpecGenerator } from './recorder/SpecGenerator';\nexport { recordable } from './recorder/recordable';\n\n// Platform Headers\nexport { WebpiecesModule } from './modules/WebpiecesModule';\nexport { WebpiecesCoreHeaders } from './headers/WebpiecesCoreHeaders';\nexport { HeaderRegistry } from '@webpieces/core-util';\n\n// Re-export from http-routing for backward compatibility\n// (FilterDefinition re-exported for one-import adapter ergonomics)\nexport {\n RouteHandler,\n MethodMeta,\n RouteBuilderImpl,\n RouteHandlerWithMeta,\n FilterWithMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n} from '@webpieces/http-routing';\n// ExpressRouteHandler now lives in http-server (express adapter), not node-only http-routing\nexport { ExpressRouteHandler } from './WebpiecesMiddleware';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/index.ts"],"names":[],"mappings":";;;AAAA,8FAA8F;AAC9F,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,uFAAuF;AACvF,wDAAoE;AAA3D,yHAAA,yBAAyB,OAAA;AAClC,yDAAwD;AAA/C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,4GAAA,YAAY,OAAA;AACrB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,iEAAgE;AAAvD,sHAAA,iBAAiB,OAAA;AAE1B,+DAA+D;AAC/D,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,oDAAmD;AAA1C,wGAAA,UAAU,OAAA;AAEnB,mEAAmE;AACnE,uEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,kDAAsD;AAA7C,2GAAA,cAAc,OAAA;AAEvB,yDAAyD;AACzD,mEAAmE;AACnE,wDASiC;AAR7B,4GAAA,YAAY,OAAA;AACZ,0GAAA,UAAU,OAAA;AACV,gHAAA,gBAAgB,OAAA;AAChB,oHAAA,oBAAoB,OAAA;AACpB,8GAAA,cAAc,OAAA;AAEd,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA","sourcesContent":["// Express adapter (the only place express lifecycle lives) over the node-only WebpiecesRouter\nexport { WebpiecesExpress } from './WebpiecesExpress';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\nexport { WebpiecesRouteCreator } from './WebpiecesRouteCreator';\n// InProcessApiClientFactory moved to node-only http-routing; re-export for back-compat\nexport { InProcessApiClientFactory } from '@webpieces/http-routing';\nexport { ContextFilter } from './filters/ContextFilter';\nexport { LogApiFilter } from './filters/LogApiFilter';\nexport { RecordingFilter } from './filters/RecordingFilter';\nexport { ServiceAuthFilter } from './filters/ServiceAuthFilter';\n\n// Test-case recording (contract lives in @webpieces/core-util)\nexport { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';\nexport { SpecGenerator } from './recorder/SpecGenerator';\nexport { recordable } from './recorder/recordable';\n\n// Context keys + registry (the global magic-context header system)\nexport { WebpiecesCoreHeaders } from './headers/WebpiecesCoreHeaders';\nexport { HeaderRegistry } from '@webpieces/core-util';\n\n// Re-export from http-routing for backward compatibility\n// (FilterDefinition re-exported for one-import adapter ergonomics)\nexport {\n RouteHandler,\n MethodMeta,\n RouteBuilderImpl,\n RouteHandlerWithMeta,\n FilterWithMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n} from '@webpieces/http-routing';\n// ExpressRouteHandler now lives in http-server (express adapter), not node-only http-routing\nexport { ExpressRouteHandler } from './WebpiecesMiddleware';\n"]}
@@ -1,20 +0,0 @@
1
- import { ContainerModule } from 'inversify';
2
- /**
3
- * WebpiecesModule - Framework-level DI bindings.
4
- *
5
- * This module is loaded by WebpiecesFactory BEFORE application modules.
6
- * It provides core framework services including platform headers.
7
- *
8
- * Platform Headers Pattern (Extension):
9
- * - Create PlatformHeadersExtension with array of headers
10
- * - Bind extension to HEADER_TYPES.PlatformHeadersExtension symbol
11
- * - Multiple modules bind their own extensions
12
- * - Consumer uses @multiInject to collect all extensions
13
- * - Pattern inspired by Guice Multibinder
14
- *
15
- * Module Loading Order:
16
- * 1. WebpiecesModule (framework headers) ← YOU ARE HERE
17
- * 2. CompanyModule (company-wide headers)
18
- * 3. InversifyModule (app-specific headers)
19
- */
20
- export declare const WebpiecesModule: ContainerModule;
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebpiecesModule = void 0;
4
- const inversify_1 = require("inversify");
5
- const core_util_1 = require("@webpieces/core-util");
6
- const WebpiecesCoreHeaders_1 = require("../headers/WebpiecesCoreHeaders");
7
- const core_util_2 = require("@webpieces/core-util");
8
- const log = core_util_2.LogManager.getLogger('WebpiecesModule');
9
- /**
10
- * WebpiecesModule - Framework-level DI bindings.
11
- *
12
- * This module is loaded by WebpiecesFactory BEFORE application modules.
13
- * It provides core framework services including platform headers.
14
- *
15
- * Platform Headers Pattern (Extension):
16
- * - Create PlatformHeadersExtension with array of headers
17
- * - Bind extension to HEADER_TYPES.PlatformHeadersExtension symbol
18
- * - Multiple modules bind their own extensions
19
- * - Consumer uses @multiInject to collect all extensions
20
- * - Pattern inspired by Guice Multibinder
21
- *
22
- * Module Loading Order:
23
- * 1. WebpiecesModule (framework headers) ← YOU ARE HERE
24
- * 2. CompanyModule (company-wide headers)
25
- * 3. InversifyModule (app-specific headers)
26
- */
27
- exports.WebpiecesModule = new inversify_1.ContainerModule((options) => {
28
- const { bind } = options;
29
- // Bind HeaderMethods as singleton (stateless utility, can be shared)
30
- bind(core_util_1.HeaderMethods).toSelf().inSingletonScope();
31
- // Create extension with core headers
32
- const coreExtension = new core_util_1.PlatformHeadersExtension(WebpiecesCoreHeaders_1.WebpiecesCoreHeaders.getAllHeaders());
33
- // Bind extension for multiInject collection
34
- // WebpiecesMiddleware will collect all PlatformHeadersExtension bindings via @multiInject
35
- bind(core_util_1.HEADER_TYPES.PlatformHeadersExtension).toConstantValue(coreExtension);
36
- // HeaderRegistry: the single source of truth for all platform headers.
37
- // Collects EVERY module's PlatformHeadersExtension at first resolution and
38
- // fail-fast validates duplicates/conflicts (port of Java HeaderTranslation).
39
- bind(core_util_1.HeaderRegistry)
40
- .toDynamicValue((ctx) => {
41
- const extensions = ctx.getAll(core_util_1.HEADER_TYPES.PlatformHeadersExtension);
42
- return new core_util_1.HeaderRegistry(extensions);
43
- })
44
- .inSingletonScope();
45
- log.info(`[WebpiecesModule] Registered core platform headers extension with ${coreExtension.headers.length} headers`);
46
- });
47
- //# sourceMappingURL=WebpiecesModule.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WebpiecesModule.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/modules/WebpiecesModule.ts"],"names":[],"mappings":";;;AAAA,yCAA+D;AAC/D,oDAA6G;AAC7G,0EAAuE;AACvE,oDAAkD;AAElD,MAAM,GAAG,GAAG,sBAAU,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,eAAe,GAAG,IAAI,2BAAe,CAAC,CAAC,OAAO,EAAE,EAAE;IAC3D,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,qEAAqE;IACrE,IAAI,CAAgB,yBAAa,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAE/D,qCAAqC;IACrC,MAAM,aAAa,GAAG,IAAI,oCAAwB,CAAC,2CAAoB,CAAC,aAAa,EAAE,CAAC,CAAC;IAEzF,4CAA4C;IAC5C,0FAA0F;IAC1F,IAAI,CAA2B,wBAAY,CAAC,wBAAwB,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IAErG,uEAAuE;IACvE,2EAA2E;IAC3E,6EAA6E;IAC7E,IAAI,CAAiB,0BAAc,CAAC;SAC/B,cAAc,CAAC,CAAC,GAAsB,EAAE,EAAE;QACvC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAA2B,wBAAY,CAAC,wBAAwB,CAAC,CAAC;QAC/F,OAAO,IAAI,0BAAc,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC,CAAC;SACD,gBAAgB,EAAE,CAAC;IAExB,GAAG,CAAC,IAAI,CAAC,qEAAqE,aAAa,CAAC,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;AAC1H,CAAC,CAAC,CAAC","sourcesContent":["import { ContainerModule, ResolutionContext } from 'inversify';\nimport { HEADER_TYPES, PlatformHeadersExtension, HeaderMethods, HeaderRegistry } from '@webpieces/core-util';\nimport { WebpiecesCoreHeaders } from '../headers/WebpiecesCoreHeaders';\nimport { LogManager } from '@webpieces/core-util';\n\nconst log = LogManager.getLogger('WebpiecesModule');\n\n/**\n * WebpiecesModule - Framework-level DI bindings.\n *\n * This module is loaded by WebpiecesFactory BEFORE application modules.\n * It provides core framework services including platform headers.\n *\n * Platform Headers Pattern (Extension):\n * - Create PlatformHeadersExtension with array of headers\n * - Bind extension to HEADER_TYPES.PlatformHeadersExtension symbol\n * - Multiple modules bind their own extensions\n * - Consumer uses @multiInject to collect all extensions\n * - Pattern inspired by Guice Multibinder\n *\n * Module Loading Order:\n * 1. WebpiecesModule (framework headers) ← YOU ARE HERE\n * 2. CompanyModule (company-wide headers)\n * 3. InversifyModule (app-specific headers)\n */\nexport const WebpiecesModule = new ContainerModule((options) => {\n const { bind } = options;\n\n // Bind HeaderMethods as singleton (stateless utility, can be shared)\n bind<HeaderMethods>(HeaderMethods).toSelf().inSingletonScope();\n\n // Create extension with core headers\n const coreExtension = new PlatformHeadersExtension(WebpiecesCoreHeaders.getAllHeaders());\n\n // Bind extension for multiInject collection\n // WebpiecesMiddleware will collect all PlatformHeadersExtension bindings via @multiInject\n bind<PlatformHeadersExtension>(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(coreExtension);\n\n // HeaderRegistry: the single source of truth for all platform headers.\n // Collects EVERY module's PlatformHeadersExtension at first resolution and\n // fail-fast validates duplicates/conflicts (port of Java HeaderTranslation).\n bind<HeaderRegistry>(HeaderRegistry)\n .toDynamicValue((ctx: ResolutionContext) => {\n const extensions = ctx.getAll<PlatformHeadersExtension>(HEADER_TYPES.PlatformHeadersExtension);\n return new HeaderRegistry(extensions);\n })\n .inSingletonScope();\n\n log.info(`[WebpiecesModule] Registered core platform headers extension with ${coreExtension.headers.length} headers`);\n});\n"]}