@webpieces/core-util 0.3.263 → 0.3.265

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/package.json +1 -1
  2. package/src/http/ContextReader.d.ts +37 -0
  3. package/src/http/ContextReader.js +3 -0
  4. package/src/http/ContextReader.js.map +1 -0
  5. package/src/http/HeaderMethods.d.ts +71 -0
  6. package/src/http/HeaderMethods.js +124 -0
  7. package/src/http/HeaderMethods.js.map +1 -0
  8. package/src/http/HeaderRegistry.d.ts +58 -0
  9. package/src/http/HeaderRegistry.js +121 -0
  10. package/src/http/HeaderRegistry.js.map +1 -0
  11. package/src/http/HeaderTypes.d.ts +29 -0
  12. package/src/http/HeaderTypes.js +33 -0
  13. package/src/http/HeaderTypes.js.map +1 -0
  14. package/src/http/LogApiCall.d.ts +41 -0
  15. package/src/http/LogApiCall.js +83 -0
  16. package/src/http/LogApiCall.js.map +1 -0
  17. package/src/http/PlatformHeader.d.ts +51 -0
  18. package/src/http/PlatformHeader.js +63 -0
  19. package/src/http/PlatformHeader.js.map +1 -0
  20. package/src/http/PlatformHeadersExtension.d.ts +51 -0
  21. package/src/http/PlatformHeadersExtension.js +59 -0
  22. package/src/http/PlatformHeadersExtension.js.map +1 -0
  23. package/src/http/WebpiecesCoreHeaders.d.ts +62 -0
  24. package/src/http/WebpiecesCoreHeaders.js +87 -0
  25. package/src/http/WebpiecesCoreHeaders.js.map +1 -0
  26. package/src/http/datetime.d.ts +284 -0
  27. package/src/http/datetime.js +270 -0
  28. package/src/http/datetime.js.map +1 -0
  29. package/src/http/decorators.d.ts +212 -0
  30. package/src/http/decorators.js +365 -0
  31. package/src/http/decorators.js.map +1 -0
  32. package/src/http/errors.d.ts +118 -0
  33. package/src/http/errors.js +189 -0
  34. package/src/http/errors.js.map +1 -0
  35. package/src/http/recorder/DoNotRecord.d.ts +22 -0
  36. package/src/http/recorder/DoNotRecord.js +39 -0
  37. package/src/http/recorder/DoNotRecord.js.map +1 -0
  38. package/src/http/recorder/RecordSerializer.d.ts +39 -0
  39. package/src/http/recorder/RecordSerializer.js +80 -0
  40. package/src/http/recorder/RecordSerializer.js.map +1 -0
  41. package/src/http/recorder/RecordedEndpoint.d.ts +49 -0
  42. package/src/http/recorder/RecordedEndpoint.js +66 -0
  43. package/src/http/recorder/RecordedEndpoint.js.map +1 -0
  44. package/src/http/recorder/TestCaseRecorder.d.ts +36 -0
  45. package/src/http/recorder/TestCaseRecorder.js +16 -0
  46. package/src/http/recorder/TestCaseRecorder.js.map +1 -0
  47. package/src/http/validators.d.ts +41 -0
  48. package/src/http/validators.js +3 -0
  49. package/src/http/validators.js.map +1 -0
  50. package/src/index.d.ts +22 -0
  51. package/src/index.js +102 -1
  52. package/src/index.js.map +1 -1
  53. package/src/logging/ConsoleLogger.d.ts +25 -0
  54. package/src/logging/ConsoleLogger.js +43 -0
  55. package/src/logging/ConsoleLogger.js.map +1 -0
  56. package/src/logging/ConsoleLoggerFactory.d.ts +13 -0
  57. package/src/logging/ConsoleLoggerFactory.js +24 -0
  58. package/src/logging/ConsoleLoggerFactory.js.map +1 -0
  59. package/src/logging/LogManager.d.ts +36 -0
  60. package/src/logging/LogManager.js +46 -0
  61. package/src/logging/LogManager.js.map +1 -0
  62. package/src/logging/Logger.d.ts +36 -0
  63. package/src/logging/Logger.js +3 -0
  64. package/src/logging/Logger.js.map +1 -0
  65. package/src/logging/LoggerFactory.d.ts +16 -0
  66. package/src/logging/LoggerFactory.js +3 -0
  67. package/src/logging/LoggerFactory.js.map +1 -0
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogApiCall = void 0;
4
+ const errors_1 = require("./errors");
5
+ const errorUtils_1 = require("../lib/errorUtils");
6
+ const LogManager_1 = require("../logging/LogManager");
7
+ const log = LogManager_1.LogManager.getLogger('LogApiCall');
8
+ /**
9
+ * LogApiCall - Generic API call logging utility.
10
+ *
11
+ * Used by both server-side (LogApiFilter) and client-side (ClientFactory) for
12
+ * consistent logging patterns across the framework.
13
+ *
14
+ * Logging format patterns:
15
+ * - [API-{type}-req] ClassName.methodName request={...} headers={...}
16
+ * - [API-{type}-resp-SUCCESS] ClassName.methodName response={...}
17
+ * - [API-{type}-resp-OTHER] ClassName.methodName errorType={...} (user errors)
18
+ * - [API-{type}-resp-FAIL] ClassName.methodName error={...} (server errors)
19
+ */
20
+ class LogApiCall {
21
+ /**
22
+ * Execute an API call with logging around it.
23
+ *
24
+ * @param type - 'SVR' or 'CLIENT'
25
+ * @param meta - Route metadata with controllerClassName and methodName
26
+ * @param requestDto - The request DTO
27
+ * @param headers - Map of header name -> values
28
+ * @param splitHeaders - SplitHeaders with secureHeaders and publicHeaders for masking
29
+ * @param method - The method to execute
30
+ */
31
+ async execute(type, meta, requestDto, headers, method) {
32
+ // Log request - convert Map to Object for JSON serialization
33
+ const headersObj = Object.fromEntries(headers);
34
+ log.info(`[API-${type}-req] ${meta.controllerClassName}.${meta.methodName} ${meta.path} request=${JSON.stringify(requestDto)} headers=${JSON.stringify(headersObj)}`);
35
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- LogApiCall logs errors before re-throwing to caller
36
+ try {
37
+ if (!requestDto)
38
+ throw new Error(`Request cannot be null and was from ${meta.controllerClassName}.${meta.methodName}`);
39
+ const response = await method(requestDto);
40
+ if (!response)
41
+ throw new Error(`Response cannot be null and was from ${meta.controllerClassName}.${meta.methodName}`);
42
+ // Log success response
43
+ log.info(`[API-${type}-resp-SUCCESS] ${meta.controllerClassName}.${meta.methodName} response=${JSON.stringify(response)}`);
44
+ return response;
45
+ }
46
+ catch (err) {
47
+ const error = (0, errorUtils_1.toError)(err);
48
+ const errorType = error.constructor.name;
49
+ const errorMessage = error.message;
50
+ // Log error based on type and re-throw
51
+ if (LogApiCall.isUserError(error)) {
52
+ log.warn(`[API-${type}-resp-OTHER] ${meta.controllerClassName}.${meta.methodName} errorType=${errorType}`);
53
+ }
54
+ else {
55
+ log.error(`[API-${type}-resp-FAIL] ${meta.controllerClassName}.${meta.methodName} errorType=${errorType} error=${errorMessage}`);
56
+ }
57
+ throw error;
58
+ }
59
+ }
60
+ /**
61
+ * Check if an error is a user error (expected behavior from server perspective).
62
+ * User errors are NOT failures - just users making mistakes or validation issues.
63
+ *
64
+ * User errors (logged as OTHER, no stack trace):
65
+ * - HttpBadRequestError (400)
66
+ * - HttpUnauthorizedError (401)
67
+ * - HttpForbiddenError (403)
68
+ * - HttpNotFoundError (404)
69
+ * - HttpUserError (266)
70
+ *
71
+ * @param error - The error to check
72
+ * @returns true if this is a user error, false for server errors
73
+ */
74
+ static isUserError(error) {
75
+ return (error instanceof errors_1.HttpBadRequestError ||
76
+ error instanceof errors_1.HttpUnauthorizedError ||
77
+ error instanceof errors_1.HttpForbiddenError ||
78
+ error instanceof errors_1.HttpNotFoundError ||
79
+ error instanceof errors_1.HttpUserError);
80
+ }
81
+ }
82
+ exports.LogApiCall = LogApiCall;
83
+ //# sourceMappingURL=LogApiCall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogApiCall.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/LogApiCall.ts"],"names":[],"mappings":";;;AACA,qCAMkB;AAClB,kDAA0C;AAC1C,sDAAiD;AAEjD,MAAM,GAAG,GAAG,uBAAU,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;AAG/C;;;;;;;;;;;GAWG;AACH,MAAa,UAAU;IAEnB;;;;;;;;;OASG;IACI,KAAK,CAAC,OAAO,CAChB,IAAY,EACZ,IAAmB,EACnB,UAAe,EACf,OAAyB,EACzB,MAAkC;QAElC,6DAA6D;QAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC/C,GAAG,CAAC,IAAI,CACJ,QAAQ,IAAI,SAAS,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAC9J,CAAC;QAEF,qHAAqH;QACrH,IAAI,CAAC;YACD,IAAG,CAAC,UAAU;gBACV,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAE1G,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YAE1C,IAAG,CAAC,QAAQ;gBACR,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAE3G,uBAAuB;YACvB,GAAG,CAAC,IAAI,CACJ,QAAQ,IAAI,kBAAkB,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,aAAa,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CACnH,CAAC;YAEF,OAAO,QAAQ,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,oBAAO,EAAC,GAAG,CAAC,CAAC;YAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;YACzC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;YAEnC,uCAAuC;YACvC,IAAI,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,GAAG,CAAC,IAAI,CACJ,QAAQ,IAAI,gBAAgB,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,cAAc,SAAS,EAAE,CACnG,CAAC;YACN,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,KAAK,CACL,QAAQ,IAAI,eAAe,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,UAAU,cAAc,SAAS,UAAU,YAAY,EAAE,CACxH,CAAC;YACN,CAAC;YACD,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc;QAC7B,OAAO,CACH,KAAK,YAAY,4BAAmB;YACpC,KAAK,YAAY,8BAAqB;YACtC,KAAK,YAAY,2BAAkB;YACnC,KAAK,YAAY,0BAAiB;YAClC,KAAK,YAAY,sBAAa,CACjC,CAAC;IACN,CAAC;CACJ;AAnFD,gCAmFC","sourcesContent":["import {RouteMetadata} from \"./decorators\";\nimport {\n HttpBadRequestError,\n HttpUnauthorizedError,\n HttpForbiddenError,\n HttpNotFoundError,\n HttpUserError,\n} from './errors';\nimport {toError} from \"../lib/errorUtils\";\nimport {LogManager} from \"../logging/LogManager\";\n\nconst log = LogManager.getLogger('LogApiCall');\n\n\n/**\n * LogApiCall - Generic API call logging utility.\n *\n * Used by both server-side (LogApiFilter) and client-side (ClientFactory) for\n * consistent logging patterns across the framework.\n *\n * Logging format patterns:\n * - [API-{type}-req] ClassName.methodName request={...} headers={...}\n * - [API-{type}-resp-SUCCESS] ClassName.methodName response={...}\n * - [API-{type}-resp-OTHER] ClassName.methodName errorType={...} (user errors)\n * - [API-{type}-resp-FAIL] ClassName.methodName error={...} (server errors)\n */\nexport class LogApiCall {\n\n /**\n * Execute an API call with logging around it.\n *\n * @param type - 'SVR' or 'CLIENT'\n * @param meta - Route metadata with controllerClassName and methodName\n * @param requestDto - The request DTO\n * @param headers - Map of header name -> values\n * @param splitHeaders - SplitHeaders with secureHeaders and publicHeaders for masking\n * @param method - The method to execute\n */\n public async execute(\n type: string,\n meta: RouteMetadata,\n requestDto: any,\n headers: Map<string, any>,\n method: (dto: any) => Promise<any>\n ): Promise<any> {\n // Log request - convert Map to Object for JSON serialization\n const headersObj = Object.fromEntries(headers);\n log.info(\n `[API-${type}-req] ${meta.controllerClassName}.${meta.methodName} ${meta.path} request=${JSON.stringify(requestDto)} headers=${JSON.stringify(headersObj)}`\n );\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- LogApiCall logs errors before re-throwing to caller\n try {\n if(!requestDto)\n throw new Error(`Request cannot be null and was from ${meta.controllerClassName}.${meta.methodName}`);\n \n const response = await method(requestDto);\n\n if(!response)\n throw new Error(`Response cannot be null and was from ${meta.controllerClassName}.${meta.methodName}`);\n\n // Log success response\n log.info(\n `[API-${type}-resp-SUCCESS] ${meta.controllerClassName}.${meta.methodName} response=${JSON.stringify(response)}`\n );\n\n return response;\n } catch (err: unknown) {\n const error = toError(err);\n const errorType = error.constructor.name;\n const errorMessage = error.message;\n\n // Log error based on type and re-throw\n if (LogApiCall.isUserError(error)) {\n log.warn(\n `[API-${type}-resp-OTHER] ${meta.controllerClassName}.${meta.methodName} errorType=${errorType}`\n );\n } else {\n log.error(\n `[API-${type}-resp-FAIL] ${meta.controllerClassName}.${meta.methodName} errorType=${errorType} error=${errorMessage}`\n );\n }\n throw error;\n }\n }\n\n /**\n * Check if an error is a user error (expected behavior from server perspective).\n * User errors are NOT failures - just users making mistakes or validation issues.\n *\n * User errors (logged as OTHER, no stack trace):\n * - HttpBadRequestError (400)\n * - HttpUnauthorizedError (401)\n * - HttpForbiddenError (403)\n * - HttpNotFoundError (404)\n * - HttpUserError (266)\n *\n * @param error - The error to check\n * @returns true if this is a user error, false for server errors\n */\n static isUserError(error: unknown): boolean {\n return (\n error instanceof HttpBadRequestError ||\n error instanceof HttpUnauthorizedError ||\n error instanceof HttpForbiddenError ||\n error instanceof HttpNotFoundError ||\n error instanceof HttpUserError\n );\n }\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import { Header } from '../Header';
2
+ /**
3
+ * PlatformHeader - Defines an HTTP header that can be transferred between services.
4
+ *
5
+ * Port of Java PlatformHeaders, simplified:
6
+ * - No isWantLogged flag (deprecated in Java) - "wants MDC logging" is expressed
7
+ * by setting loggerMdcKey. Headers without one still appear in API logs
8
+ * (masked when isSecured); they just aren't exposed as an MDC dimension key.
9
+ *
10
+ * Implements Header interface from core-util to avoid circular dependencies.
11
+ *
12
+ * Per CLAUDE.md: "All data-only structures MUST be classes, not interfaces."
13
+ * This is a data-only class with no business logic methods.
14
+ */
15
+ export declare class PlatformHeader implements Header {
16
+ /**
17
+ * The HTTP header name (e.g., 'x-request-id', 'x-tenant-id').
18
+ * Also used as the MDC logging key in RequestContext.
19
+ * Case-insensitive per HTTP spec, but stored in canonical form.
20
+ */
21
+ readonly headerName: string;
22
+ /**
23
+ * Whether this header should be transferred from HTTP request to RequestContext.
24
+ * If false, header is defined but not automatically transferred.
25
+ * Only headers with isWantTransferred=true are copied from incoming requests.
26
+ */
27
+ readonly isWantTransferred: boolean;
28
+ /**
29
+ * Whether this header contains sensitive data that should be secured/masked in logs.
30
+ * Examples: Authorization tokens, passwords, API keys.
31
+ */
32
+ readonly isSecured: boolean;
33
+ /**
34
+ * Whether this header should be used as a dimension for metrics/monitoring.
35
+ * Examples: x-tenant-id, x-request-id (for distributed tracing).
36
+ */
37
+ readonly isDimensionForMetrics: boolean;
38
+ /**
39
+ * Key used when exposing this header to the logger's MDC / structured log
40
+ * dimensions. Port of Java getLoggerMDCKey(). When set, log maps key this
41
+ * header by it instead of headerName (e.g. 'requestId' vs 'x-request-id').
42
+ * Undefined = not an MDC dimension (Java: getLoggerMDCKey() == null).
43
+ */
44
+ readonly loggerMdcKey?: string;
45
+ constructor(headerName: string, isWantTransferred?: boolean, isSecured?: boolean, isDimensionForMetrics?: boolean, loggerMdcKey?: string);
46
+ /**
47
+ * Get the header name (implements Header interface).
48
+ * @returns The HTTP header name
49
+ */
50
+ getHeaderName(): string;
51
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PlatformHeader = void 0;
4
+ /**
5
+ * PlatformHeader - Defines an HTTP header that can be transferred between services.
6
+ *
7
+ * Port of Java PlatformHeaders, simplified:
8
+ * - No isWantLogged flag (deprecated in Java) - "wants MDC logging" is expressed
9
+ * by setting loggerMdcKey. Headers without one still appear in API logs
10
+ * (masked when isSecured); they just aren't exposed as an MDC dimension key.
11
+ *
12
+ * Implements Header interface from core-util to avoid circular dependencies.
13
+ *
14
+ * Per CLAUDE.md: "All data-only structures MUST be classes, not interfaces."
15
+ * This is a data-only class with no business logic methods.
16
+ */
17
+ class PlatformHeader {
18
+ /**
19
+ * The HTTP header name (e.g., 'x-request-id', 'x-tenant-id').
20
+ * Also used as the MDC logging key in RequestContext.
21
+ * Case-insensitive per HTTP spec, but stored in canonical form.
22
+ */
23
+ headerName;
24
+ /**
25
+ * Whether this header should be transferred from HTTP request to RequestContext.
26
+ * If false, header is defined but not automatically transferred.
27
+ * Only headers with isWantTransferred=true are copied from incoming requests.
28
+ */
29
+ isWantTransferred;
30
+ /**
31
+ * Whether this header contains sensitive data that should be secured/masked in logs.
32
+ * Examples: Authorization tokens, passwords, API keys.
33
+ */
34
+ isSecured;
35
+ /**
36
+ * Whether this header should be used as a dimension for metrics/monitoring.
37
+ * Examples: x-tenant-id, x-request-id (for distributed tracing).
38
+ */
39
+ isDimensionForMetrics;
40
+ /**
41
+ * Key used when exposing this header to the logger's MDC / structured log
42
+ * dimensions. Port of Java getLoggerMDCKey(). When set, log maps key this
43
+ * header by it instead of headerName (e.g. 'requestId' vs 'x-request-id').
44
+ * Undefined = not an MDC dimension (Java: getLoggerMDCKey() == null).
45
+ */
46
+ loggerMdcKey;
47
+ constructor(headerName, isWantTransferred = true, isSecured = false, isDimensionForMetrics = false, loggerMdcKey) {
48
+ this.headerName = headerName;
49
+ this.isWantTransferred = isWantTransferred;
50
+ this.isSecured = isSecured;
51
+ this.isDimensionForMetrics = isDimensionForMetrics;
52
+ this.loggerMdcKey = loggerMdcKey;
53
+ }
54
+ /**
55
+ * Get the header name (implements Header interface).
56
+ * @returns The HTTP header name
57
+ */
58
+ getHeaderName() {
59
+ return this.headerName;
60
+ }
61
+ }
62
+ exports.PlatformHeader = PlatformHeader;
63
+ //# sourceMappingURL=PlatformHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformHeader.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/PlatformHeader.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;GAYG;AACH,MAAa,cAAc;IACvB;;;;OAIG;IACM,UAAU,CAAS;IAE5B;;;;OAIG;IACM,iBAAiB,CAAU;IAEpC;;;OAGG;IACM,SAAS,CAAU;IAE5B;;;OAGG;IACM,qBAAqB,CAAU;IAExC;;;;;OAKG;IACM,YAAY,CAAU;IAE/B,YACI,UAAkB,EAClB,oBAA6B,IAAI,EACjC,YAAqB,KAAK,EAC1B,wBAAiC,KAAK,EACtC,YAAqB;QAErB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;QACnD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED;;;OAGG;IACH,aAAa;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;CACJ;AAxDD,wCAwDC","sourcesContent":["import { Header } from '../Header';\n\n/**\n * PlatformHeader - Defines an HTTP header that can be transferred between services.\n *\n * Port of Java PlatformHeaders, simplified:\n * - No isWantLogged flag (deprecated in Java) - \"wants MDC logging\" is expressed\n * by setting loggerMdcKey. Headers without one still appear in API logs\n * (masked when isSecured); they just aren't exposed as an MDC dimension key.\n *\n * Implements Header interface from core-util to avoid circular dependencies.\n *\n * Per CLAUDE.md: \"All data-only structures MUST be classes, not interfaces.\"\n * This is a data-only class with no business logic methods.\n */\nexport class PlatformHeader implements Header {\n /**\n * The HTTP header name (e.g., 'x-request-id', 'x-tenant-id').\n * Also used as the MDC logging key in RequestContext.\n * Case-insensitive per HTTP spec, but stored in canonical form.\n */\n readonly headerName: string;\n\n /**\n * Whether this header should be transferred from HTTP request to RequestContext.\n * If false, header is defined but not automatically transferred.\n * Only headers with isWantTransferred=true are copied from incoming requests.\n */\n readonly isWantTransferred: boolean;\n\n /**\n * Whether this header contains sensitive data that should be secured/masked in logs.\n * Examples: Authorization tokens, passwords, API keys.\n */\n readonly isSecured: boolean;\n\n /**\n * Whether this header should be used as a dimension for metrics/monitoring.\n * Examples: x-tenant-id, x-request-id (for distributed tracing).\n */\n readonly isDimensionForMetrics: boolean;\n\n /**\n * Key used when exposing this header to the logger's MDC / structured log\n * dimensions. Port of Java getLoggerMDCKey(). When set, log maps key this\n * header by it instead of headerName (e.g. 'requestId' vs 'x-request-id').\n * Undefined = not an MDC dimension (Java: getLoggerMDCKey() == null).\n */\n readonly loggerMdcKey?: string;\n\n constructor(\n headerName: string,\n isWantTransferred: boolean = true,\n isSecured: boolean = false,\n isDimensionForMetrics: boolean = false,\n loggerMdcKey?: string\n ) {\n this.headerName = headerName;\n this.isWantTransferred = isWantTransferred;\n this.isSecured = isSecured;\n this.isDimensionForMetrics = isDimensionForMetrics;\n this.loggerMdcKey = loggerMdcKey;\n }\n\n /**\n * Get the header name (implements Header interface).\n * @returns The HTTP header name\n */\n getHeaderName(): string {\n return this.headerName;\n }\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import { PlatformHeader } from './PlatformHeader';
2
+ /**
3
+ * PlatformHeadersExtension - Extension that contributes platform headers to the framework.
4
+ *
5
+ * This is a DI-level extension (not an app-level Plugin).
6
+ * Multiple modules can bind PlatformHeadersExtension instances, and the framework
7
+ * collects them via Inversify @multiInject.
8
+ *
9
+ * Two-level plugin system:
10
+ * 1. **Extensions** (DI-level): Contribute specific capabilities to framework
11
+ * - Examples: PlatformHeadersExtension, BodyContentExtension, EntityLookupExtension
12
+ * - Pattern: Bound via multiInject, consumed by framework
13
+ * - Java equivalent: Multibinder<AddPlatformHeaders>, Multibinder<BodyContentBinder>
14
+ *
15
+ * 2. **Plugins** (App-level): Provide complete features with modules + routes
16
+ * - Examples: HibernatePlugin, JacksonPlugin, Auth0Plugin
17
+ * - Pattern: Implements getGuiceModules() + getRouteModules()
18
+ * - Java equivalent: Plugin interface with getGuiceModules() + getRouteModules()
19
+ *
20
+ * Usage:
21
+ * ```typescript
22
+ * // In WebpiecesModule
23
+ * const coreExtension = new PlatformHeadersExtension([
24
+ * WebpiecesCoreHeaders.REQUEST_ID,
25
+ * WebpiecesCoreHeaders.CORRELATION_ID,
26
+ * ]);
27
+ * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(coreExtension);
28
+ *
29
+ * // In CompanyModule
30
+ * const companyExtension = new PlatformHeadersExtension([
31
+ * CompanyHeaders.TENANT_ID,
32
+ * CompanyHeaders.API_VERSION,
33
+ * ]);
34
+ * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(companyExtension);
35
+ *
36
+ * // Framework collects all extensions
37
+ * constructor(@multiInject(HEADER_TYPES.PlatformHeadersExtension) extensions: PlatformHeadersExtension[]) {}
38
+ * ```
39
+ */
40
+ export declare class PlatformHeadersExtension {
41
+ /**
42
+ * The set of platform headers contributed by this extension.
43
+ */
44
+ readonly headers: PlatformHeader[];
45
+ constructor(headers: PlatformHeader[]);
46
+ /**
47
+ * Get all headers from this extension.
48
+ * @returns Array of platform headers
49
+ */
50
+ getHeaders(): PlatformHeader[];
51
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PlatformHeadersExtension = void 0;
4
+ /**
5
+ * PlatformHeadersExtension - Extension that contributes platform headers to the framework.
6
+ *
7
+ * This is a DI-level extension (not an app-level Plugin).
8
+ * Multiple modules can bind PlatformHeadersExtension instances, and the framework
9
+ * collects them via Inversify @multiInject.
10
+ *
11
+ * Two-level plugin system:
12
+ * 1. **Extensions** (DI-level): Contribute specific capabilities to framework
13
+ * - Examples: PlatformHeadersExtension, BodyContentExtension, EntityLookupExtension
14
+ * - Pattern: Bound via multiInject, consumed by framework
15
+ * - Java equivalent: Multibinder<AddPlatformHeaders>, Multibinder<BodyContentBinder>
16
+ *
17
+ * 2. **Plugins** (App-level): Provide complete features with modules + routes
18
+ * - Examples: HibernatePlugin, JacksonPlugin, Auth0Plugin
19
+ * - Pattern: Implements getGuiceModules() + getRouteModules()
20
+ * - Java equivalent: Plugin interface with getGuiceModules() + getRouteModules()
21
+ *
22
+ * Usage:
23
+ * ```typescript
24
+ * // In WebpiecesModule
25
+ * const coreExtension = new PlatformHeadersExtension([
26
+ * WebpiecesCoreHeaders.REQUEST_ID,
27
+ * WebpiecesCoreHeaders.CORRELATION_ID,
28
+ * ]);
29
+ * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(coreExtension);
30
+ *
31
+ * // In CompanyModule
32
+ * const companyExtension = new PlatformHeadersExtension([
33
+ * CompanyHeaders.TENANT_ID,
34
+ * CompanyHeaders.API_VERSION,
35
+ * ]);
36
+ * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(companyExtension);
37
+ *
38
+ * // Framework collects all extensions
39
+ * constructor(@multiInject(HEADER_TYPES.PlatformHeadersExtension) extensions: PlatformHeadersExtension[]) {}
40
+ * ```
41
+ */
42
+ class PlatformHeadersExtension {
43
+ /**
44
+ * The set of platform headers contributed by this extension.
45
+ */
46
+ headers;
47
+ constructor(headers) {
48
+ this.headers = headers;
49
+ }
50
+ /**
51
+ * Get all headers from this extension.
52
+ * @returns Array of platform headers
53
+ */
54
+ getHeaders() {
55
+ return this.headers;
56
+ }
57
+ }
58
+ exports.PlatformHeadersExtension = PlatformHeadersExtension;
59
+ //# sourceMappingURL=PlatformHeadersExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformHeadersExtension.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/PlatformHeadersExtension.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAa,wBAAwB;IACjC;;OAEG;IACM,OAAO,CAAmB;IAEnC,YAAY,OAAyB;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,UAAU;QACN,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;CACJ;AAjBD,4DAiBC","sourcesContent":["import { PlatformHeader } from './PlatformHeader';\n\n/**\n * PlatformHeadersExtension - Extension that contributes platform headers to the framework.\n *\n * This is a DI-level extension (not an app-level Plugin).\n * Multiple modules can bind PlatformHeadersExtension instances, and the framework\n * collects them via Inversify @multiInject.\n *\n * Two-level plugin system:\n * 1. **Extensions** (DI-level): Contribute specific capabilities to framework\n * - Examples: PlatformHeadersExtension, BodyContentExtension, EntityLookupExtension\n * - Pattern: Bound via multiInject, consumed by framework\n * - Java equivalent: Multibinder<AddPlatformHeaders>, Multibinder<BodyContentBinder>\n *\n * 2. **Plugins** (App-level): Provide complete features with modules + routes\n * - Examples: HibernatePlugin, JacksonPlugin, Auth0Plugin\n * - Pattern: Implements getGuiceModules() + getRouteModules()\n * - Java equivalent: Plugin interface with getGuiceModules() + getRouteModules()\n *\n * Usage:\n * ```typescript\n * // In WebpiecesModule\n * const coreExtension = new PlatformHeadersExtension([\n * WebpiecesCoreHeaders.REQUEST_ID,\n * WebpiecesCoreHeaders.CORRELATION_ID,\n * ]);\n * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(coreExtension);\n *\n * // In CompanyModule\n * const companyExtension = new PlatformHeadersExtension([\n * CompanyHeaders.TENANT_ID,\n * CompanyHeaders.API_VERSION,\n * ]);\n * bind(HEADER_TYPES.PlatformHeadersExtension).toConstantValue(companyExtension);\n *\n * // Framework collects all extensions\n * constructor(@multiInject(HEADER_TYPES.PlatformHeadersExtension) extensions: PlatformHeadersExtension[]) {}\n * ```\n */\nexport class PlatformHeadersExtension {\n /**\n * The set of platform headers contributed by this extension.\n */\n readonly headers: PlatformHeader[];\n\n constructor(headers: PlatformHeader[]) {\n this.headers = headers;\n }\n\n /**\n * Get all headers from this extension.\n * @returns Array of platform headers\n */\n getHeaders(): PlatformHeader[] {\n return this.headers;\n }\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { PlatformHeader } from './PlatformHeader';
2
+ /**
3
+ * Core framework headers for distributed tracing and request correlation.
4
+ *
5
+ * These are the minimal headers needed by the WebPieces framework for:
6
+ * - Request tracking across services
7
+ * - Distributed tracing (REQUEST_ID -> PREVIOUS_REQUEST_ID chaining per hop)
8
+ * - Request correlation
9
+ * - Metrics and monitoring
10
+ *
11
+ * Pattern inspired by Java MicroSvcHeader enum. Lives in http-api (browser-safe)
12
+ * so BOTH the http-client (request-id chaining) and http-server can reference it.
13
+ */
14
+ export declare class WebpiecesCoreHeaders {
15
+ /**
16
+ * Unique ID for this request.
17
+ * Generated by the server if not provided.
18
+ * Used for distributed tracing and log correlation.
19
+ */
20
+ static readonly REQUEST_ID: PlatformHeader;
21
+ /**
22
+ * ID of the previous request in the call chain.
23
+ * When service A calls service B, B receives A's REQUEST_ID as PREVIOUS_REQUEST_ID.
24
+ * Used for building distributed trace trees.
25
+ */
26
+ static readonly PREVIOUS_REQUEST_ID: PlatformHeader;
27
+ /**
28
+ * Correlation ID that spans multiple related requests.
29
+ * Typically set by the API gateway or first service in the chain.
30
+ * All services in the call chain use the same CORRELATION_ID.
31
+ */
32
+ static readonly CORRELATION_ID: PlatformHeader;
33
+ /**
34
+ * Turns on test-case recording for this request (Java: x-webpieces-recording).
35
+ * When present, the server records the endpoint + every downstream call it
36
+ * makes into a fixture that can be replayed as a test.
37
+ * Transferred so recording follows the request across service hops.
38
+ */
39
+ static readonly RECORDING: PlatformHeader;
40
+ /**
41
+ * The bearer credential for an authenticated request. Carries BOTH a user-facing
42
+ * JWT (@AuthJwt, validated by the app AuthFilter) and a service-to-service Google
43
+ * OIDC token (@AuthOidc, validated by the framework ServiceAuthFilter) — the two
44
+ * modes are mutually exclusive per endpoint, so one header serves both. When a
45
+ * Cloud Task is delivered, Google injects the OIDC token here as `Authorization`.
46
+ * SECURED — masked in logs.
47
+ */
48
+ static readonly AUTHORIZATION: PlatformHeader;
49
+ /**
50
+ * Shared-secret credential for internal callers that cannot mint OIDC tokens
51
+ * (@AuthSharedSecret, validated by ServiceAuthFilter via constant-time compare).
52
+ * SECURED — masked in logs.
53
+ */
54
+ static readonly SHARED_SECRET: PlatformHeader;
55
+ /**
56
+ * Get all core headers as an array.
57
+ * Used by WebpiecesModule to bind headers to DI container.
58
+ *
59
+ * @returns Array of all core platform headers
60
+ */
61
+ static getAllHeaders(): PlatformHeader[];
62
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebpiecesCoreHeaders = void 0;
4
+ const PlatformHeader_1 = require("./PlatformHeader");
5
+ /**
6
+ * Core framework headers for distributed tracing and request correlation.
7
+ *
8
+ * These are the minimal headers needed by the WebPieces framework for:
9
+ * - Request tracking across services
10
+ * - Distributed tracing (REQUEST_ID -> PREVIOUS_REQUEST_ID chaining per hop)
11
+ * - Request correlation
12
+ * - Metrics and monitoring
13
+ *
14
+ * Pattern inspired by Java MicroSvcHeader enum. Lives in http-api (browser-safe)
15
+ * so BOTH the http-client (request-id chaining) and http-server can reference it.
16
+ */
17
+ class WebpiecesCoreHeaders {
18
+ /**
19
+ * Unique ID for this request.
20
+ * Generated by the server if not provided.
21
+ * Used for distributed tracing and log correlation.
22
+ */
23
+ static REQUEST_ID = new PlatformHeader_1.PlatformHeader('x-request-id', true, // transfer (propagate to downstream services)
24
+ false, // not secured (it's just an ID)
25
+ true, // use for metrics dimensions
26
+ 'requestId' // MDC key (Java MicroSvcHeader parity)
27
+ );
28
+ /**
29
+ * ID of the previous request in the call chain.
30
+ * When service A calls service B, B receives A's REQUEST_ID as PREVIOUS_REQUEST_ID.
31
+ * Used for building distributed trace trees.
32
+ */
33
+ static PREVIOUS_REQUEST_ID = new PlatformHeader_1.PlatformHeader('x-previous-request-id', true, false, false, 'previousId' // MDC key (Java MicroSvcHeader parity)
34
+ );
35
+ /**
36
+ * Correlation ID that spans multiple related requests.
37
+ * Typically set by the API gateway or first service in the chain.
38
+ * All services in the call chain use the same CORRELATION_ID.
39
+ */
40
+ static CORRELATION_ID = new PlatformHeader_1.PlatformHeader('x-correlation-id', true, false, true, // use for metrics dimensions
41
+ 'correlationId' // MDC key
42
+ );
43
+ /**
44
+ * Turns on test-case recording for this request (Java: x-webpieces-recording).
45
+ * When present, the server records the endpoint + every downstream call it
46
+ * makes into a fixture that can be replayed as a test.
47
+ * Transferred so recording follows the request across service hops.
48
+ */
49
+ static RECORDING = new PlatformHeader_1.PlatformHeader('x-webpieces-recording', true, false, false);
50
+ /**
51
+ * The bearer credential for an authenticated request. Carries BOTH a user-facing
52
+ * JWT (@AuthJwt, validated by the app AuthFilter) and a service-to-service Google
53
+ * OIDC token (@AuthOidc, validated by the framework ServiceAuthFilter) — the two
54
+ * modes are mutually exclusive per endpoint, so one header serves both. When a
55
+ * Cloud Task is delivered, Google injects the OIDC token here as `Authorization`.
56
+ * SECURED — masked in logs.
57
+ */
58
+ static AUTHORIZATION = new PlatformHeader_1.PlatformHeader('authorization', true, // transfer into RequestContext
59
+ true, // SECURED - mask in logs
60
+ false);
61
+ /**
62
+ * Shared-secret credential for internal callers that cannot mint OIDC tokens
63
+ * (@AuthSharedSecret, validated by ServiceAuthFilter via constant-time compare).
64
+ * SECURED — masked in logs.
65
+ */
66
+ static SHARED_SECRET = new PlatformHeader_1.PlatformHeader('x-webpieces-shared-secret', true, // transfer into RequestContext
67
+ true, // SECURED - mask in logs
68
+ false);
69
+ /**
70
+ * Get all core headers as an array.
71
+ * Used by WebpiecesModule to bind headers to DI container.
72
+ *
73
+ * @returns Array of all core platform headers
74
+ */
75
+ static getAllHeaders() {
76
+ return [
77
+ WebpiecesCoreHeaders.REQUEST_ID,
78
+ WebpiecesCoreHeaders.PREVIOUS_REQUEST_ID,
79
+ WebpiecesCoreHeaders.CORRELATION_ID,
80
+ WebpiecesCoreHeaders.RECORDING,
81
+ WebpiecesCoreHeaders.AUTHORIZATION,
82
+ WebpiecesCoreHeaders.SHARED_SECRET,
83
+ ];
84
+ }
85
+ }
86
+ exports.WebpiecesCoreHeaders = WebpiecesCoreHeaders;
87
+ //# sourceMappingURL=WebpiecesCoreHeaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebpiecesCoreHeaders.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/WebpiecesCoreHeaders.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAElD;;;;;;;;;;;GAWG;AACH,MAAa,oBAAoB;IAC7B;;;;OAIG;IACH,MAAM,CAAU,UAAU,GAAG,IAAI,+BAAc,CAC3C,cAAc,EACd,IAAI,EAAS,8CAA8C;IAC3D,KAAK,EAAQ,gCAAgC;IAC7C,IAAI,EAAS,6BAA6B;IAC1C,WAAW,CAAE,uCAAuC;KACvD,CAAC;IAEF;;;;OAIG;IACH,MAAM,CAAU,mBAAmB,GAAG,IAAI,+BAAc,CACpD,uBAAuB,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,YAAY,CAAE,uCAAuC;KACxD,CAAC;IAEF;;;;OAIG;IACH,MAAM,CAAU,cAAc,GAAG,IAAI,+BAAc,CAC/C,kBAAkB,EAClB,IAAI,EACJ,KAAK,EACL,IAAI,EAAa,6BAA6B;IAC9C,eAAe,CAAE,UAAU;KAC9B,CAAC;IAEF;;;;;OAKG;IACH,MAAM,CAAU,SAAS,GAAG,IAAI,+BAAc,CAC1C,uBAAuB,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,CACR,CAAC;IAEF;;;;;;;OAOG;IACH,MAAM,CAAU,aAAa,GAAG,IAAI,+BAAc,CAC9C,eAAe,EACf,IAAI,EAAI,+BAA+B;IACvC,IAAI,EAAI,yBAAyB;IACjC,KAAK,CACR,CAAC;IAEF;;;;OAIG;IACH,MAAM,CAAU,aAAa,GAAG,IAAI,+BAAc,CAC9C,2BAA2B,EAC3B,IAAI,EAAI,+BAA+B;IACvC,IAAI,EAAI,yBAAyB;IACjC,KAAK,CACR,CAAC;IAEF;;;;;OAKG;IACH,MAAM,CAAC,aAAa;QAChB,OAAO;YACH,oBAAoB,CAAC,UAAU;YAC/B,oBAAoB,CAAC,mBAAmB;YACxC,oBAAoB,CAAC,cAAc;YACnC,oBAAoB,CAAC,SAAS;YAC9B,oBAAoB,CAAC,aAAa;YAClC,oBAAoB,CAAC,aAAa;SACrC,CAAC;IACN,CAAC;;AA/FL,oDAgGC","sourcesContent":["import { PlatformHeader } from './PlatformHeader';\n\n/**\n * Core framework headers for distributed tracing and request correlation.\n *\n * These are the minimal headers needed by the WebPieces framework for:\n * - Request tracking across services\n * - Distributed tracing (REQUEST_ID -> PREVIOUS_REQUEST_ID chaining per hop)\n * - Request correlation\n * - Metrics and monitoring\n *\n * Pattern inspired by Java MicroSvcHeader enum. Lives in http-api (browser-safe)\n * so BOTH the http-client (request-id chaining) and http-server can reference it.\n */\nexport class WebpiecesCoreHeaders {\n /**\n * Unique ID for this request.\n * Generated by the server if not provided.\n * Used for distributed tracing and log correlation.\n */\n static readonly REQUEST_ID = new PlatformHeader(\n 'x-request-id',\n true, // transfer (propagate to downstream services)\n false, // not secured (it's just an ID)\n true, // use for metrics dimensions\n 'requestId' // MDC key (Java MicroSvcHeader parity)\n );\n\n /**\n * ID of the previous request in the call chain.\n * When service A calls service B, B receives A's REQUEST_ID as PREVIOUS_REQUEST_ID.\n * Used for building distributed trace trees.\n */\n static readonly PREVIOUS_REQUEST_ID = new PlatformHeader(\n 'x-previous-request-id',\n true,\n false,\n false,\n 'previousId' // MDC key (Java MicroSvcHeader parity)\n );\n\n /**\n * Correlation ID that spans multiple related requests.\n * Typically set by the API gateway or first service in the chain.\n * All services in the call chain use the same CORRELATION_ID.\n */\n static readonly CORRELATION_ID = new PlatformHeader(\n 'x-correlation-id',\n true,\n false,\n true, // use for metrics dimensions\n 'correlationId' // MDC key\n );\n\n /**\n * Turns on test-case recording for this request (Java: x-webpieces-recording).\n * When present, the server records the endpoint + every downstream call it\n * makes into a fixture that can be replayed as a test.\n * Transferred so recording follows the request across service hops.\n */\n static readonly RECORDING = new PlatformHeader(\n 'x-webpieces-recording',\n true,\n false,\n false\n );\n\n /**\n * The bearer credential for an authenticated request. Carries BOTH a user-facing\n * JWT (@AuthJwt, validated by the app AuthFilter) and a service-to-service Google\n * OIDC token (@AuthOidc, validated by the framework ServiceAuthFilter) — the two\n * modes are mutually exclusive per endpoint, so one header serves both. When a\n * Cloud Task is delivered, Google injects the OIDC token here as `Authorization`.\n * SECURED — masked in logs.\n */\n static readonly AUTHORIZATION = new PlatformHeader(\n 'authorization',\n true, // transfer into RequestContext\n true, // SECURED - mask in logs\n false\n );\n\n /**\n * Shared-secret credential for internal callers that cannot mint OIDC tokens\n * (@AuthSharedSecret, validated by ServiceAuthFilter via constant-time compare).\n * SECURED — masked in logs.\n */\n static readonly SHARED_SECRET = new PlatformHeader(\n 'x-webpieces-shared-secret',\n true, // transfer into RequestContext\n true, // SECURED - mask in logs\n false\n );\n\n /**\n * Get all core headers as an array.\n * Used by WebpiecesModule to bind headers to DI container.\n *\n * @returns Array of all core platform headers\n */\n static getAllHeaders(): PlatformHeader[] {\n return [\n WebpiecesCoreHeaders.REQUEST_ID,\n WebpiecesCoreHeaders.PREVIOUS_REQUEST_ID,\n WebpiecesCoreHeaders.CORRELATION_ID,\n WebpiecesCoreHeaders.RECORDING,\n WebpiecesCoreHeaders.AUTHORIZATION,\n WebpiecesCoreHeaders.SHARED_SECRET,\n ];\n }\n}\n"]}