@webpieces/http-server 0.4.404 → 0.4.405

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.4.404",
3
+ "version": "0.4.405",
4
4
  "description": "WebPieces server with filter chain and dependency injection",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -22,10 +22,10 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@webpieces/core-context": "0.4.404",
26
- "@webpieces/core-util": "0.4.404",
27
- "@webpieces/gcp-identity": "0.4.404",
28
- "@webpieces/http-routing": "0.4.404",
25
+ "@webpieces/core-context": "0.4.405",
26
+ "@webpieces/core-util": "0.4.405",
27
+ "@webpieces/gcp-identity": "0.4.405",
28
+ "@webpieces/http-routing": "0.4.405",
29
29
  "cors": "2.8.5",
30
30
  "express": "5.1.0",
31
31
  "inversify": "7.10.4"
@@ -4,9 +4,9 @@ import { Filter, WpResponse, Service } from '@webpieces/http-routing';
4
4
  * RecordingFilter - Records a request as a replayable test case (port of Java
5
5
  * RecordingFilter).
6
6
  *
7
- * Suggested priority: 1850 (after ContextFilter 2000 so the RECORDING header
8
- * has been transferred to the context, after AuthFilter 1900 so only real
9
- * authorized flows are recorded, before LogApiFilter 1800).
7
+ * Suggested priority: 1850 a user-filter priority that runs BELOW the fixed
8
+ * framework filters (LogApiFilter 1,000,000 outermost, AuthFilter 900,000), so
9
+ * only real authorized flows are recorded.
10
10
  *
11
11
  * Activates when WebpiecesConfig.recordingAlwaysOn is set OR the request
12
12
  * carries WebpiecesCoreHeaders.RECORDING (x-webpieces-recording). While
@@ -12,9 +12,9 @@ const TestCaseRecorderImpl_1 = require("../recorder/TestCaseRecorderImpl");
12
12
  * RecordingFilter - Records a request as a replayable test case (port of Java
13
13
  * RecordingFilter).
14
14
  *
15
- * Suggested priority: 1850 (after ContextFilter 2000 so the RECORDING header
16
- * has been transferred to the context, after AuthFilter 1900 so only real
17
- * authorized flows are recorded, before LogApiFilter 1800).
15
+ * Suggested priority: 1850 a user-filter priority that runs BELOW the fixed
16
+ * framework filters (LogApiFilter 1,000,000 outermost, AuthFilter 900,000), so
17
+ * only real authorized flows are recorded.
18
18
  *
19
19
  * Activates when WebpiecesConfig.recordingAlwaysOn is set OR the request
20
20
  * carries WebpiecesCoreHeaders.RECORDING (x-webpieces-recording). While
@@ -1 +1 @@
1
- {"version":3,"file":"RecordingFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/RecordingFilter.ts"],"names":[],"mappings":";;;;AAAA,yCAAmC;AACnC,0DAKiC;AACjC,0DAAyD;AACzD,0DAAsE;AACtE,oDAM8B;AAE9B,2EAAwE;AAExE;;;;;;;;;;;;;;;;;GAiBG;AAGI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,qBAAuC;IAG5B;IAD5C,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,6BAAc,CAAC,cAAc,EAAE,CAAC;QAC/C,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,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,mBAAmB,IAAI,YAAY,CAAC;QAC7F,OAAO,IAAI,4BAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1F,CAAC;CACJ,CAAA;AAxDY,0CAAe;0BAAf,eAAe;IAF3B,IAAA,wCAAyB,GAAE;IAC5B,sGAAsG;;IAI7F,mBAAA,IAAA,kBAAM,EAAC,qCAAsB,CAAC,CAAA;6CAAiB,8BAAe;GAH1D,eAAe,CAwD3B","sourcesContent":["import { inject } from 'inversify';\nimport {\n provideFrameworkSingleton,\n MethodMeta,\n WebpiecesConfig,\n WEBPIECES_CONFIG_TOKEN,\n} from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-routing';\nimport {\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// webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\nexport class RecordingFilter extends Filter<MethodMeta, WpResponse<unknown>> {\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 = RequestContext.buildLogFields();\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.apiName ?? meta.routeMeta.controllerClassName ?? 'UnknownApi';\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,yCAAmC;AACnC,0DAKiC;AACjC,0DAAyD;AACzD,0DAAsE;AACtE,oDAM8B;AAE9B,2EAAwE;AAExE;;;;;;;;;;;;;;;;;GAiBG;AAGI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,qBAAuC;IAG5B;IAD5C,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,6BAAc,CAAC,cAAc,EAAE,CAAC;QAC/C,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,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,mBAAmB,IAAI,YAAY,CAAC;QAC7F,OAAO,IAAI,4BAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1F,CAAC;CACJ,CAAA;AAxDY,0CAAe;0BAAf,eAAe;IAF3B,IAAA,wCAAyB,GAAE;IAC5B,sGAAsG;;IAI7F,mBAAA,IAAA,kBAAM,EAAC,qCAAsB,CAAC,CAAA;6CAAiB,8BAAe;GAH1D,eAAe,CAwD3B","sourcesContent":["import { inject } from 'inversify';\nimport {\n provideFrameworkSingleton,\n MethodMeta,\n WebpiecesConfig,\n WEBPIECES_CONFIG_TOKEN,\n} from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Filter, WpResponse, Service } from '@webpieces/http-routing';\nimport {\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 a user-filter priority that runs BELOW the fixed\n * framework filters (LogApiFilter 1,000,000 outermost, AuthFilter 900,000), so\n * only real authorized flows are recorded.\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// webpieces-disable no-any-unknown -- Filter generic params use unknown for response type flexibility\nexport class RecordingFilter extends Filter<MethodMeta, WpResponse<unknown>> {\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 = RequestContext.buildLogFields();\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.apiName ?? meta.routeMeta.controllerClassName ?? 'UnknownApi';\n return new RecordedEndpoint(apiName, meta.methodName, [meta.requestDto], ctxSnapshot);\n }\n}\n"]}
package/src/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export { WebpiecesExpressRouter } from './WebpiecesExpressRouter';
2
2
  export { WebpiecesMiddleware } from './WebpiecesMiddleware';
3
- export { LogApiFilter } from './filters/LogApiFilter';
4
3
  export { RecordingFilter } from './filters/RecordingFilter';
5
4
  export { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';
6
5
  export { SpecGenerator } from './recorder/SpecGenerator';
package/src/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SharedSecrets = exports.AuthValues = exports.AuthConfig = exports.HttpRequest = exports.ApiClient = exports.FilterDefinition = exports.FilterMatcher = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.RecordingFilter = exports.LogApiFilter = exports.WebpiecesMiddleware = exports.WebpiecesExpressRouter = void 0;
3
+ exports.SharedSecrets = exports.AuthValues = exports.AuthConfig = exports.HttpRequest = exports.ApiClient = exports.FilterDefinition = exports.FilterMatcher = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.RecordingFilter = exports.WebpiecesMiddleware = exports.WebpiecesExpressRouter = void 0;
4
4
  // Express adapter (the only place express lifecycle lives) over the node-only ApiFactory
5
5
  var WebpiecesExpressRouter_1 = require("./WebpiecesExpressRouter");
6
6
  Object.defineProperty(exports, "WebpiecesExpressRouter", { enumerable: true, get: function () { return WebpiecesExpressRouter_1.WebpiecesExpressRouter; } });
7
7
  var WebpiecesMiddleware_1 = require("./WebpiecesMiddleware");
8
8
  Object.defineProperty(exports, "WebpiecesMiddleware", { enumerable: true, get: function () { return WebpiecesMiddleware_1.WebpiecesMiddleware; } });
9
- var LogApiFilter_1 = require("./filters/LogApiFilter");
10
- Object.defineProperty(exports, "LogApiFilter", { enumerable: true, get: function () { return LogApiFilter_1.LogApiFilter; } });
9
+ // LogApiFilter is now a FIXED framework filter auto-installed by WebpiecesRouter (outermost, at
10
+ // priority 1,000,000, above AuthFilter). Apps must NOT install it themselves it is no longer
11
+ // exported here. Remove any `router.addFilter(new FilterDefinition(1800, LogApiFilter, '*'))`.
11
12
  var RecordingFilter_1 = require("./filters/RecordingFilter");
12
13
  Object.defineProperty(exports, "RecordingFilter", { enumerable: true, get: function () { return RecordingFilter_1.RecordingFilter; } });
13
14
  // Test-case recording (contract lives in @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,yFAAyF;AACzF,mEAAkE;AAAzD,gIAAA,sBAAsB,OAAA;AAC/B,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,uDAAsD;AAA7C,4GAAA,YAAY,OAAA;AACrB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AAExB,+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,gEAAgE;AAChE,wDAYiC;AAX7B,4GAAA,YAAY,OAAA;AACZ,0GAAA,UAAU,OAAA;AAEV,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA;AAEhB,yGAAA,SAAS,OAAA;AACT,2GAAA,WAAW,OAAA;AACX,0GAAA,UAAU,OAAA;AACV,0GAAA,UAAU,OAAA;AACV,6GAAA,aAAa,OAAA","sourcesContent":["// Express adapter (the only place express lifecycle lives) over the node-only ApiFactory\nexport { WebpiecesExpressRouter } from './WebpiecesExpressRouter';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\nexport { LogApiFilter } from './filters/LogApiFilter';\nexport { RecordingFilter } from './filters/RecordingFilter';\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 one-import adapter ergonomics\nexport {\n RouteHandler,\n MethodMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n ApiFactory,\n ApiClient,\n HttpRequest,\n AuthConfig,\n AuthValues,\n SharedSecrets,\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,yFAAyF;AACzF,mEAAkE;AAAzD,gIAAA,sBAAsB,OAAA;AAC/B,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,gGAAgG;AAChG,+FAA+F;AAC/F,+FAA+F;AAC/F,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AAExB,+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,gEAAgE;AAChE,wDAYiC;AAX7B,4GAAA,YAAY,OAAA;AACZ,0GAAA,UAAU,OAAA;AAEV,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA;AAEhB,yGAAA,SAAS,OAAA;AACT,2GAAA,WAAW,OAAA;AACX,0GAAA,UAAU,OAAA;AACV,0GAAA,UAAU,OAAA;AACV,6GAAA,aAAa,OAAA","sourcesContent":["// Express adapter (the only place express lifecycle lives) over the node-only ApiFactory\nexport { WebpiecesExpressRouter } from './WebpiecesExpressRouter';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\n// LogApiFilter is now a FIXED framework filter auto-installed by WebpiecesRouter (outermost, at\n// priority 1,000,000, above AuthFilter). Apps must NOT install it themselves — it is no longer\n// exported here. Remove any `router.addFilter(new FilterDefinition(1800, LogApiFilter, '*'))`.\nexport { RecordingFilter } from './filters/RecordingFilter';\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 one-import adapter ergonomics\nexport {\n RouteHandler,\n MethodMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n ApiFactory,\n ApiClient,\n HttpRequest,\n AuthConfig,\n AuthValues,\n SharedSecrets,\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,5 +0,0 @@
1
- import { MethodMeta } from '@webpieces/http-routing';
2
- import { Filter, WpResponse, Service } from '@webpieces/http-routing';
3
- export declare class LogApiFilter extends Filter<MethodMeta, WpResponse<unknown>> {
4
- filter(meta: MethodMeta, nextFilter: Service<MethodMeta, WpResponse<unknown>>): Promise<WpResponse<unknown>>;
5
- }
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LogApiFilter = void 0;
4
- const tslib_1 = require("tslib");
5
- const http_routing_1 = require("@webpieces/http-routing");
6
- const http_routing_2 = require("@webpieces/http-routing");
7
- const core_util_1 = require("@webpieces/core-util");
8
- const core_util_2 = require("@webpieces/core-util");
9
- const core_context_1 = require("@webpieces/core-context");
10
- /**
11
- * LogApiFilter - Structured API logging for all requests/responses.
12
- * Priority: 1800 (after ContextFilter at 2000, before custom filters)
13
- *
14
- * Logging patterns (via LogApiCall):
15
- * - [API-server-req] Class.method /url request={...}
16
- * - [API-server-resp-SUCCESS] Class.method response={...}
17
- * - [API-server-resp-FAIL] Class.method error=... (server errors: 500, 502, 504)
18
- * - [API-server-resp-OTHER] Class.method errorType=... (user errors: 400, 401, 403, 404, 266)
19
- *
20
- * Headers are read from RequestContext (NOT from meta.requestHeaders which is undefined
21
- * after ContextFilter runs at priority 2000).
22
- *
23
- * User errors (HttpBadRequestError, etc.) are logged as OTHER, not FAIL,
24
- * because they are expected behavior from the server's perspective.
25
- */
26
- const log = core_util_1.LogManager.getLogger('LogApiFilter');
27
- let LogApiFilter = class LogApiFilter extends http_routing_2.Filter {
28
- async filter(meta, nextFilter) {
29
- // Wrap nextFilter.invoke in a method that returns the response
30
- const method = async () => {
31
- const wpResponse = await nextFilter.invoke(meta);
32
- return wpResponse.response;
33
- };
34
- // LogApiCall is a singleton (use it directly, no `new`). It logs the text lines AND stamps the
35
- // structured `api={method:{side:'server',...},...}` tag into RequestContext, so every log line
36
- // during the request carries jsonPayload.api. Correlation fields (requestId, ...) are added by
37
- // the backend. apiClass is the CONTRACT name (routeMeta.apiName, e.g. 'SaveApi') so a server log
38
- // line MATCHES the client's for the same call; controllerName keeps the impl (e.g. 'SaveController').
39
- const rm = meta.routeMeta;
40
- // Stamp the routed endpoint's IMPLEMENTATION identity onto the request context so EVERY log line
41
- // of this request (not just the api req/resp lines) carries the concrete controller class +
42
- // handler method name — what you actually grep for, and more useful than the raw requestPath. GCP
43
- // gets them as separate jsonPayload.controller / jsonPayload.method; the local console formatters
44
- // render them together as a compact [Controller.method] bracket. They clear with the request scope.
45
- if (rm.controllerClassName) {
46
- core_context_1.RequestContext.putHeader(core_util_1.WebpiecesCoreHeaders.CONTROLLER, rm.controllerClassName);
47
- }
48
- if (rm.methodName) {
49
- core_context_1.RequestContext.putHeader(core_util_1.WebpiecesCoreHeaders.METHOD, rm.methodName);
50
- }
51
- const info = new core_util_2.ApiMethodInfo('server', rm.apiName ?? rm.controllerClassName ?? 'Unknown', rm.methodName, rm.controllerClassName);
52
- const response = await core_util_2.LogApiCall.execute(info, meta.requestDto, method);
53
- return new http_routing_2.WpResponse(response);
54
- }
55
- };
56
- exports.LogApiFilter = LogApiFilter;
57
- exports.LogApiFilter = LogApiFilter = tslib_1.__decorate([
58
- (0, http_routing_1.provideFrameworkSingleton)()
59
- ], LogApiFilter);
60
- //# sourceMappingURL=LogApiFilter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LogApiFilter.js","sourceRoot":"","sources":["../../../../../../packages/http/http-server/src/filters/LogApiFilter.ts"],"names":[],"mappings":";;;;AAAA,0DAA8E;AAC9E,0DAAsE;AACtE,oDAAwE;AACxE,oDAAiE;AACjE,0DAAyD;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,GAAG,GAAG,sBAAU,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAG1C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,qBAAuC;IAErE,KAAK,CAAC,MAAM,CACR,IAAgB,EAChB,UAAoD;QAEpD,+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,+FAA+F;QAC/F,+FAA+F;QAC/F,+FAA+F;QAC/F,iGAAiG;QACjG,sGAAsG;QACtG,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAE1B,iGAAiG;QACjG,4FAA4F;QAC5F,kGAAkG;QAClG,kGAAkG;QAClG,oGAAoG;QACpG,IAAI,EAAE,CAAC,mBAAmB,EAAE,CAAC;YACzB,6BAAc,CAAC,SAAS,CAAC,gCAAoB,CAAC,UAAU,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;YAChB,6BAAc,CAAC,SAAS,CAAC,gCAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,yBAAa,CAC1B,QAAQ,EACR,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,mBAAmB,IAAI,SAAS,EACjD,EAAE,CAAC,UAAU,EACb,EAAE,CAAC,mBAAmB,CACzB,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,sBAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACzE,OAAO,IAAI,yBAAU,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACJ,CAAA;AAxCY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,wCAAyB,GAAE;GACf,YAAY,CAwCxB","sourcesContent":["import {provideFrameworkSingleton, MethodMeta} from '@webpieces/http-routing';\nimport { Filter, WpResponse, Service } from '@webpieces/http-routing';\nimport { LogManager, WebpiecesCoreHeaders } from '@webpieces/core-util';\nimport { LogApiCall, ApiMethodInfo } from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\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-server-req] Class.method /url request={...}\n * - [API-server-resp-SUCCESS] Class.method response={...}\n * - [API-server-resp-FAIL] Class.method error=... (server errors: 500, 502, 504)\n * - [API-server-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()\nexport class LogApiFilter extends Filter<MethodMeta, WpResponse<unknown>> {\n\n async filter(\n meta: MethodMeta,\n nextFilter: Service<MethodMeta, WpResponse<unknown>>,\n ): Promise<WpResponse<unknown>> {\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 // LogApiCall is a singleton (use it directly, no `new`). It logs the text lines AND stamps the\n // structured `api={method:{side:'server',...},...}` tag into RequestContext, so every log line\n // during the request carries jsonPayload.api. Correlation fields (requestId, ...) are added by\n // the backend. apiClass is the CONTRACT name (routeMeta.apiName, e.g. 'SaveApi') so a server log\n // line MATCHES the client's for the same call; controllerName keeps the impl (e.g. 'SaveController').\n const rm = meta.routeMeta;\n\n // Stamp the routed endpoint's IMPLEMENTATION identity onto the request context so EVERY log line\n // of this request (not just the api req/resp lines) carries the concrete controller class +\n // handler method name — what you actually grep for, and more useful than the raw requestPath. GCP\n // gets them as separate jsonPayload.controller / jsonPayload.method; the local console formatters\n // render them together as a compact [Controller.method] bracket. They clear with the request scope.\n if (rm.controllerClassName) {\n RequestContext.putHeader(WebpiecesCoreHeaders.CONTROLLER, rm.controllerClassName);\n }\n if (rm.methodName) {\n RequestContext.putHeader(WebpiecesCoreHeaders.METHOD, rm.methodName);\n }\n\n const info = new ApiMethodInfo(\n 'server',\n rm.apiName ?? rm.controllerClassName ?? 'Unknown',\n rm.methodName,\n rm.controllerClassName,\n );\n const response = await LogApiCall.execute(info, meta.requestDto, method);\n return new WpResponse(response);\n }\n}\n"]}