@webpieces/http-api 0.3.166 → 0.3.168

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-api",
3
- "version": "0.3.166",
3
+ "version": "0.3.168",
4
4
  "description": "HTTP API decorators for defining REST APIs",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -22,6 +22,6 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@webpieces/core-util": "0.3.166"
25
+ "@webpieces/core-util": "0.3.168"
26
26
  }
27
27
  }
@@ -14,6 +14,28 @@ exports.PlatformHeader = void 0;
14
14
  * This is a data-only class with no business logic methods.
15
15
  */
16
16
  class PlatformHeader {
17
+ /**
18
+ * The HTTP header name (e.g., 'x-request-id', 'x-tenant-id').
19
+ * Also used as the MDC logging key in RequestContext.
20
+ * Case-insensitive per HTTP spec, but stored in canonical form.
21
+ */
22
+ headerName;
23
+ /**
24
+ * Whether this header should be transferred from HTTP request to RequestContext.
25
+ * If false, header is defined but not automatically transferred.
26
+ * Only headers with isWantTransferred=true are copied from incoming requests.
27
+ */
28
+ isWantTransferred;
29
+ /**
30
+ * Whether this header contains sensitive data that should be secured/masked in logs.
31
+ * Examples: Authorization tokens, passwords, API keys.
32
+ */
33
+ isSecured;
34
+ /**
35
+ * Whether this header should be used as a dimension for metrics/monitoring.
36
+ * Examples: x-tenant-id, x-request-id (for distributed tracing).
37
+ */
38
+ isDimensionForMetrics;
17
39
  constructor(headerName, isWantTransferred = true, isSecured = false, isDimensionForMetrics = false) {
18
40
  this.headerName = headerName;
19
41
  this.isWantTransferred = isWantTransferred;
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformHeader.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/PlatformHeader.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACH,MAAa,cAAc;IA2BvB,YACI,UAAkB,EAClB,oBAA6B,IAAI,EACjC,YAAqB,KAAK,EAC1B,wBAAiC,KAAK;QAEtC,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;IACvD,CAAC;IAED;;;OAGG;IACH,aAAa;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;CACJ;AA9CD,wCA8CC","sourcesContent":["import { Header } from '@webpieces/core-util';\n\n/**\n * PlatformHeader - Defines an HTTP header that can be transferred between services.\n *\n * Simplified from Java PlatformHeaders:\n * - Single headerName field (used for both HTTP header and MDC logging key)\n * - No separate getLoggerMDCKey() - just use headerName\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 constructor(\n headerName: string,\n isWantTransferred: boolean = true,\n isSecured: boolean = false,\n isDimensionForMetrics: boolean = false\n ) {\n this.headerName = headerName;\n this.isWantTransferred = isWantTransferred;\n this.isSecured = isSecured;\n this.isDimensionForMetrics = isDimensionForMetrics;\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"]}
1
+ {"version":3,"file":"PlatformHeader.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/PlatformHeader.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACH,MAAa,cAAc;IACvB;;;;OAIG;IACM,UAAU,CAAS;IAE5B;;;;OAIG;IACM,iBAAiB,CAAU;IAEpC;;;OAGG;IACM,SAAS,CAAU;IAE5B;;;OAGG;IACM,qBAAqB,CAAU;IAExC,YACI,UAAkB,EAClB,oBAA6B,IAAI,EACjC,YAAqB,KAAK,EAC1B,wBAAiC,KAAK;QAEtC,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;IACvD,CAAC;IAED;;;OAGG;IACH,aAAa;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;CACJ;AA9CD,wCA8CC","sourcesContent":["import { Header } from '@webpieces/core-util';\n\n/**\n * PlatformHeader - Defines an HTTP header that can be transferred between services.\n *\n * Simplified from Java PlatformHeaders:\n * - Single headerName field (used for both HTTP header and MDC logging key)\n * - No separate getLoggerMDCKey() - just use headerName\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 constructor(\n headerName: string,\n isWantTransferred: boolean = true,\n isSecured: boolean = false,\n isDimensionForMetrics: boolean = false\n ) {\n this.headerName = headerName;\n this.isWantTransferred = isWantTransferred;\n this.isSecured = isSecured;\n this.isDimensionForMetrics = isDimensionForMetrics;\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"]}
@@ -40,6 +40,10 @@ exports.PlatformHeadersExtension = void 0;
40
40
  * ```
41
41
  */
42
42
  class PlatformHeadersExtension {
43
+ /**
44
+ * The set of platform headers contributed by this extension.
45
+ */
46
+ headers;
43
47
  constructor(headers) {
44
48
  this.headers = headers;
45
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformHeadersExtension.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/PlatformHeadersExtension.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAa,wBAAwB;IAMjC,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"]}
1
+ {"version":3,"file":"PlatformHeadersExtension.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/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"]}
package/src/decorators.js CHANGED
@@ -26,6 +26,11 @@ exports.METADATA_KEYS = {
26
26
  * and ApiRoutingFactory.
27
27
  */
28
28
  class RouteMetadata {
29
+ httpMethod;
30
+ path;
31
+ methodName;
32
+ controllerClassName;
33
+ authMeta;
29
34
  constructor(httpMethod, path, methodName, controllerClassName, authMeta) {
30
35
  this.httpMethod = httpMethod;
31
36
  this.path = path;
@@ -44,6 +49,8 @@ exports.RouteMetadata = RouteMetadata;
44
49
  * - authenticated=false + roles → INVALID (caught at decorator time)
45
50
  */
46
51
  class AuthMeta {
52
+ authenticated;
53
+ roles;
47
54
  constructor(authenticated, roles) {
48
55
  this.authenticated = authenticated;
49
56
  this.roles = roles ?? [];
@@ -98,6 +105,8 @@ function Endpoint(path) {
98
105
  * Authentication config passed to @Authentication() decorator.
99
106
  */
100
107
  class AuthenticationConfig {
108
+ authenticated;
109
+ roles;
101
110
  constructor(authenticated, roles) {
102
111
  this.authenticated = authenticated;
103
112
  this.roles = roles;
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\n\n/**\n * Metadata keys for storing API routing information.\n * These keys are used by both server-side (routing) and client-side (client generation).\n */\nexport const METADATA_KEYS = {\n API_PATH: 'webpieces:api-path',\n ENDPOINTS: 'webpieces:endpoints',\n AUTH_META: 'webpieces:auth-meta',\n};\n\n/**\n * Route metadata stored per-method at runtime.\n * Used internally by http-routing and http-client as the runtime representation\n * of a route. Constructed from @ApiPath + @Endpoint metadata by createApiClient\n * and ApiRoutingFactory.\n */\nexport class RouteMetadata {\n httpMethod: string;\n path: string;\n methodName: string;\n controllerClassName?: string;\n authMeta?: AuthMeta;\n\n constructor(\n httpMethod: string,\n path: string,\n methodName: string,\n controllerClassName?: string,\n authMeta?: AuthMeta,\n ) {\n this.httpMethod = httpMethod;\n this.path = path;\n this.methodName = methodName;\n this.controllerClassName = controllerClassName;\n this.authMeta = authMeta;\n }\n}\n\n/**\n * Auth metadata attached to a class or method via @Authentication().\n *\n * - authenticated=false → public endpoint (no auth check)\n * - authenticated=true, no roles → requires authentication\n * - authenticated=true, roles=['admin'] → requires authentication + specific roles\n * - authenticated=false + roles → INVALID (caught at decorator time)\n */\nexport class AuthMeta {\n authenticated: boolean;\n roles: string[];\n\n constructor(authenticated: boolean, roles?: string[]) {\n this.authenticated = authenticated;\n this.roles = roles ?? [];\n }\n}\n\n/**\n * @ApiPath(basePath) - Class decorator that marks a class as an API definition\n * and sets the base path for all endpoints.\n *\n * Usage:\n * ```typescript\n * @Authentication({authenticated: true})\n * @ApiPath('/api/save')\n * abstract class SaveApi {\n * @Endpoint('/item')\n * save(request: SaveRequest): Promise<SaveResponse> { ... }\n * }\n * ```\n */\nexport function ApiPath(basePath: string): ClassDecorator {\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any) => {\n Reflect.defineMetadata(METADATA_KEYS.API_PATH, basePath, target);\n\n // Initialize endpoints map if not exists\n if (!Reflect.hasMetadata(METADATA_KEYS.ENDPOINTS, target)) {\n Reflect.defineMetadata(METADATA_KEYS.ENDPOINTS, {}, target);\n }\n };\n}\n\n/**\n * @Endpoint(path) - Method decorator that registers a POST endpoint at the given path.\n *\n * All endpoints are POST-only (matching gRPC/thrift style).\n *\n * Usage:\n * ```typescript\n * @Endpoint('/item')\n * save(request: SaveRequest): Promise<SaveResponse> { ... }\n * ```\n */\nexport function Endpoint(path: string): MethodDecorator {\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any, propertyKey: string | symbol, _descriptor: PropertyDescriptor) => {\n const metadataTarget = typeof target === 'function' ? target : target.constructor;\n\n const endpoints: Record<string, string> =\n Reflect.getMetadata(METADATA_KEYS.ENDPOINTS, metadataTarget) || {};\n\n endpoints[propertyKey as string] = path;\n\n Reflect.defineMetadata(METADATA_KEYS.ENDPOINTS, endpoints, metadataTarget);\n };\n}\n\n/**\n * Authentication config passed to @Authentication() decorator.\n */\nexport class AuthenticationConfig {\n authenticated: boolean;\n roles?: string[];\n\n constructor(authenticated: boolean, roles?: string[]) {\n this.authenticated = authenticated;\n this.roles = roles;\n }\n}\n\n/**\n * @Authentication(config) - Class or method decorator for auth requirements.\n *\n * Single decorator replaces @Public/@Authenticated/@Roles:\n * - @Authentication({authenticated: false}) → public, no auth check\n * - @Authentication({authenticated: true}) → requires authentication\n * - @Authentication({authenticated: true, roles: ['admin']}) → requires auth + roles\n *\n * Class-level is required. Methods can override class-level.\n * Throws if authenticated=false but roles are specified (contradictory).\n */\nexport function Authentication(config: AuthenticationConfig): ClassDecorator & MethodDecorator {\n // Validate: can't be public with roles\n if (!config.authenticated && config.roles && config.roles.length > 0) {\n throw new Error(\n `Invalid @Authentication config: authenticated=false but roles=${JSON.stringify(config.roles)}. ` +\n `Cannot require roles on a public endpoint. Set authenticated=true or remove roles.`\n );\n }\n\n const authMeta = new AuthMeta(config.authenticated, config.roles);\n\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any, propertyKey?: string | symbol, _descriptor?: PropertyDescriptor) => {\n if (propertyKey !== undefined) {\n // Method decorator\n const metadataTarget = typeof target === 'function' ? target : target.constructor;\n validateNoConflictingDecorators(metadataTarget, propertyKey as string);\n Reflect.defineMetadata(METADATA_KEYS.AUTH_META, authMeta, metadataTarget, propertyKey);\n } else {\n // Class decorator\n validateNoConflictingDecorators(target, undefined);\n Reflect.defineMetadata(METADATA_KEYS.AUTH_META, authMeta, target);\n }\n };\n}\n\n// ============================================================\n// Helper functions\n// ============================================================\n\n/**\n * Get the base path from @ApiPath decorator.\n */\nexport function getApiPath(apiClass: Function): string | undefined {\n return Reflect.getMetadata(METADATA_KEYS.API_PATH, apiClass);\n}\n\n/**\n * Get all endpoints from @Endpoint decorators.\n * Returns a record of methodName -> endpoint path.\n */\nexport function getEndpoints(apiClass: Function): Record<string, string> | undefined {\n return Reflect.getMetadata(METADATA_KEYS.ENDPOINTS, apiClass);\n}\n\n/**\n * Check if a class has @ApiPath decorator.\n */\nexport function isApiPath(apiClass: Function): boolean {\n return Reflect.hasMetadata(METADATA_KEYS.API_PATH, apiClass);\n}\n\n/**\n * Get auth metadata for a specific method, falling back to class-level auth.\n * Method-level auth takes precedence over class-level auth.\n */\nexport function getAuthMeta(apiClass: Function, methodName?: string): AuthMeta | undefined {\n // Check method-level first\n if (methodName) {\n const methodAuth = Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass, methodName);\n if (methodAuth) {\n return methodAuth;\n }\n }\n\n // Fall back to class-level\n return Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass);\n}\n\n/**\n * Validate that a class/method doesn't have conflicting auth decorators.\n * @throws Error if multiple @Authentication decorators are found on the same target.\n */\nexport function validateNoConflictingDecorators(apiClass: Function, methodName: string | undefined): void {\n const existing = methodName\n ? Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass, methodName)\n : Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass);\n\n if (existing) {\n const targetName = apiClass.name || 'Unknown';\n const location = methodName ? `method '${methodName}' of ${targetName}` : `class ${targetName}`;\n throw new Error(\n `Conflicting @Authentication on ${location}. ` +\n `Only one @Authentication() decorator allowed per target.`\n );\n }\n}\n"]}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/decorators.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\n\n/**\n * Metadata keys for storing API routing information.\n * These keys are used by both server-side (routing) and client-side (client generation).\n */\nexport const METADATA_KEYS = {\n API_PATH: 'webpieces:api-path',\n ENDPOINTS: 'webpieces:endpoints',\n AUTH_META: 'webpieces:auth-meta',\n};\n\n/**\n * Route metadata stored per-method at runtime.\n * Used internally by http-routing and http-client as the runtime representation\n * of a route. Constructed from @ApiPath + @Endpoint metadata by createApiClient\n * and ApiRoutingFactory.\n */\nexport class RouteMetadata {\n httpMethod: string;\n path: string;\n methodName: string;\n controllerClassName?: string;\n authMeta?: AuthMeta;\n\n constructor(\n httpMethod: string,\n path: string,\n methodName: string,\n controllerClassName?: string,\n authMeta?: AuthMeta,\n ) {\n this.httpMethod = httpMethod;\n this.path = path;\n this.methodName = methodName;\n this.controllerClassName = controllerClassName;\n this.authMeta = authMeta;\n }\n}\n\n/**\n * Auth metadata attached to a class or method via @Authentication().\n *\n * - authenticated=false → public endpoint (no auth check)\n * - authenticated=true, no roles → requires authentication\n * - authenticated=true, roles=['admin'] → requires authentication + specific roles\n * - authenticated=false + roles → INVALID (caught at decorator time)\n */\nexport class AuthMeta {\n authenticated: boolean;\n roles: string[];\n\n constructor(authenticated: boolean, roles?: string[]) {\n this.authenticated = authenticated;\n this.roles = roles ?? [];\n }\n}\n\n/**\n * @ApiPath(basePath) - Class decorator that marks a class as an API definition\n * and sets the base path for all endpoints.\n *\n * Usage:\n * ```typescript\n * @Authentication({authenticated: true})\n * @ApiPath('/api/save')\n * abstract class SaveApi {\n * @Endpoint('/item')\n * save(request: SaveRequest): Promise<SaveResponse> { ... }\n * }\n * ```\n */\nexport function ApiPath(basePath: string): ClassDecorator {\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any) => {\n Reflect.defineMetadata(METADATA_KEYS.API_PATH, basePath, target);\n\n // Initialize endpoints map if not exists\n if (!Reflect.hasMetadata(METADATA_KEYS.ENDPOINTS, target)) {\n Reflect.defineMetadata(METADATA_KEYS.ENDPOINTS, {}, target);\n }\n };\n}\n\n/**\n * @Endpoint(path) - Method decorator that registers a POST endpoint at the given path.\n *\n * All endpoints are POST-only (matching gRPC/thrift style).\n *\n * Usage:\n * ```typescript\n * @Endpoint('/item')\n * save(request: SaveRequest): Promise<SaveResponse> { ... }\n * ```\n */\nexport function Endpoint(path: string): MethodDecorator {\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any, propertyKey: string | symbol, _descriptor: PropertyDescriptor) => {\n const metadataTarget = typeof target === 'function' ? target : target.constructor;\n\n const endpoints: Record<string, string> =\n Reflect.getMetadata(METADATA_KEYS.ENDPOINTS, metadataTarget) || {};\n\n endpoints[propertyKey as string] = path;\n\n Reflect.defineMetadata(METADATA_KEYS.ENDPOINTS, endpoints, metadataTarget);\n };\n}\n\n/**\n * Authentication config passed to @Authentication() decorator.\n */\nexport class AuthenticationConfig {\n authenticated: boolean;\n roles?: string[];\n\n constructor(authenticated: boolean, roles?: string[]) {\n this.authenticated = authenticated;\n this.roles = roles;\n }\n}\n\n/**\n * @Authentication(config) - Class or method decorator for auth requirements.\n *\n * Single decorator replaces @Public/@Authenticated/@Roles:\n * - @Authentication({authenticated: false}) → public, no auth check\n * - @Authentication({authenticated: true}) → requires authentication\n * - @Authentication({authenticated: true, roles: ['admin']}) → requires auth + roles\n *\n * Class-level is required. Methods can override class-level.\n * Throws if authenticated=false but roles are specified (contradictory).\n */\nexport function Authentication(config: AuthenticationConfig): ClassDecorator & MethodDecorator {\n // Validate: can't be public with roles\n if (!config.authenticated && config.roles && config.roles.length > 0) {\n throw new Error(\n `Invalid @Authentication config: authenticated=false but roles=${JSON.stringify(config.roles)}. ` +\n `Cannot require roles on a public endpoint. Set authenticated=true or remove roles.`\n );\n }\n\n const authMeta = new AuthMeta(config.authenticated, config.roles);\n\n // webpieces-disable no-any-unknown -- reflect-metadata decorator API requires any\n return (target: any, propertyKey?: string | symbol, _descriptor?: PropertyDescriptor) => {\n if (propertyKey !== undefined) {\n // Method decorator\n const metadataTarget = typeof target === 'function' ? target : target.constructor;\n validateNoConflictingDecorators(metadataTarget, propertyKey as string);\n Reflect.defineMetadata(METADATA_KEYS.AUTH_META, authMeta, metadataTarget, propertyKey);\n } else {\n // Class decorator\n validateNoConflictingDecorators(target, undefined);\n Reflect.defineMetadata(METADATA_KEYS.AUTH_META, authMeta, target);\n }\n };\n}\n\n// ============================================================\n// Helper functions\n// ============================================================\n\n/**\n * Get the base path from @ApiPath decorator.\n */\nexport function getApiPath(apiClass: Function): string | undefined {\n return Reflect.getMetadata(METADATA_KEYS.API_PATH, apiClass);\n}\n\n/**\n * Get all endpoints from @Endpoint decorators.\n * Returns a record of methodName -> endpoint path.\n */\nexport function getEndpoints(apiClass: Function): Record<string, string> | undefined {\n return Reflect.getMetadata(METADATA_KEYS.ENDPOINTS, apiClass);\n}\n\n/**\n * Check if a class has @ApiPath decorator.\n */\nexport function isApiPath(apiClass: Function): boolean {\n return Reflect.hasMetadata(METADATA_KEYS.API_PATH, apiClass);\n}\n\n/**\n * Get auth metadata for a specific method, falling back to class-level auth.\n * Method-level auth takes precedence over class-level auth.\n */\nexport function getAuthMeta(apiClass: Function, methodName?: string): AuthMeta | undefined {\n // Check method-level first\n if (methodName) {\n const methodAuth = Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass, methodName);\n if (methodAuth) {\n return methodAuth;\n }\n }\n\n // Fall back to class-level\n return Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass);\n}\n\n/**\n * Validate that a class/method doesn't have conflicting auth decorators.\n * @throws Error if multiple @Authentication decorators are found on the same target.\n */\nexport function validateNoConflictingDecorators(apiClass: Function, methodName: string | undefined): void {\n const existing = methodName\n ? Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass, methodName)\n : Reflect.getMetadata(METADATA_KEYS.AUTH_META, apiClass);\n\n if (existing) {\n const targetName = apiClass.name || 'Unknown';\n const location = methodName ? `method '${methodName}' of ${targetName}` : `class ${targetName}`;\n throw new Error(\n `Conflicting @Authentication on ${location}. ` +\n `Only one @Authentication() decorator allowed per target.`\n );\n }\n}\n"]}
package/src/errors.js CHANGED
@@ -10,6 +10,13 @@ exports.HttpUserError = exports.HttpVendorError = exports.HttpInternalServerErro
10
10
  * This is what gets serialized and sent to the client.
11
11
  */
12
12
  class ProtocolError {
13
+ message;
14
+ subType;
15
+ field;
16
+ waitSeconds;
17
+ name;
18
+ guiAlertMessage;
19
+ errorCode;
13
20
  }
14
21
  exports.ProtocolError = ProtocolError;
15
22
  /**
@@ -17,6 +24,9 @@ exports.ProtocolError = ProtocolError;
17
24
  * All specific HTTP errors extend this class.
18
25
  */
19
26
  class HttpError extends Error {
27
+ code;
28
+ subType;
29
+ httpCause;
20
30
  constructor(message, code, subType, cause) {
21
31
  super(message);
22
32
  this.code = code;
@@ -61,6 +71,8 @@ exports.EndpointNotFoundError = EndpointNotFoundError;
61
71
  * Used for validation errors with optional field and GUI message.
62
72
  */
63
73
  class HttpBadRequestError extends HttpError {
74
+ field;
75
+ guiMessage;
64
76
  constructor(message, field, guiMessage, cause) {
65
77
  super(message, 400, undefined, cause);
66
78
  this.name = 'BadRequest';
@@ -143,6 +155,7 @@ exports.HttpInternalServerError = HttpInternalServerError;
143
155
  * Custom status code for vendor/external service errors with retry hint.
144
156
  */
145
157
  class HttpVendorError extends HttpError {
158
+ waitSeconds;
146
159
  constructor(message, waitSeconds = 30, cause) {
147
160
  super(message, 598, undefined, cause);
148
161
  this.waitSeconds = waitSeconds;
@@ -164,6 +177,7 @@ exports.HttpVendorError = HttpVendorError;
164
177
  * Examples: "Email already exists", "Invalid password format", "Required field missing"
165
178
  */
166
179
  class HttpUserError extends HttpError {
180
+ errorCode;
167
181
  constructor(message, errorCode, cause) {
168
182
  super(message, 266, 'USER_ERROR', cause);
169
183
  this.name = 'UserError';
package/src/errors.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP Error classes for webpieces-ts.\n * These errors are used throughout the framework for consistent error handling.\n */\n\n/**\n * ProtocolError - Data class for error response body.\n * This is what gets serialized and sent to the client.\n */\nexport class ProtocolError {\n public message?: string;\n public subType?: string;\n public field?: string;\n public waitSeconds?: number;\n public name?: string;\n public guiAlertMessage?: string;\n public errorCode?: string;\n}\n\n/**\n * HttpError - Base error class with HTTP status code.\n * All specific HTTP errors extend this class.\n */\nexport class HttpError extends Error {\n public code: number;\n public subType?: string;\n public readonly httpCause?: Error;\n\n constructor(\n message: string,\n code: number,\n subType?: string,\n cause?: Error,\n ) {\n super(message);\n this.code = code;\n this.subType = subType;\n this.httpCause = cause;\n }\n}\n\n// Error subtype constants\nexport const ENTITY_NOT_FOUND = 'EntityNotFoundError';\nexport const WRONG_LOGIN_TYPE = 'wrongLoginType';\nexport const WRONG_LOGIN = 'wronglogin';\nexport const NOT_APPROVED = 'notapproved';\nexport const EMAIL_NOT_CONFIRMED = 'email_not_confirmed';\nexport const WRONG_DOMAIN = 'wrongdomain';\nexport const WRONG_COMPANY = 'wrongcompany';\nexport const NO_REG_CODE = 'noregcode';\n\n/**\n * HttpNotFoundError - 404 Not Found.\n */\nexport class HttpNotFoundError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 404, undefined, cause);\n this.name = ENTITY_NOT_FOUND;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * EndpointNotFoundError - 404 for missing endpoints.\n */\nexport class EndpointNotFoundError extends HttpNotFoundError {\n constructor(message: string, cause?: Error) {\n super(message, cause);\n this.name = 'EndpointNotFoundError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpBadRequestError - 400 Bad Request.\n * Used for validation errors with optional field and GUI message.\n */\nexport class HttpBadRequestError extends HttpError {\n public field?: string;\n public guiMessage?: string;\n\n constructor(message: string, field?: string, guiMessage?: string, cause?: Error) {\n super(message, 400, undefined, cause);\n this.name = 'BadRequest';\n this.field = field;\n this.guiMessage = guiMessage;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpUnauthorizedError - 401 Unauthorized.\n */\nexport class HttpUnauthorizedError extends HttpError {\n constructor(message: string, subType?: string, cause?: Error) {\n super(message, 401, subType, cause);\n this.name = 'Unauthorized';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpForbiddenError - 403 Forbidden.\n */\nexport class HttpForbiddenError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 403, undefined, cause);\n this.name = 'Forbidden';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpTimeoutError - 408 Request Timeout.\n */\nexport class HttpTimeoutError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 408, undefined, cause);\n this.name = 'Timeout';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpBadGatewayError - 502 Bad Gateway.\n */\nexport class HttpBadGatewayError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 502, undefined, cause);\n this.name = 'HttpBadGatewayError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpGatewayTimeoutError - 504 Gateway Timeout.\n * SHOULD NOT BE USED SERVER SIDE SINCE ALBs will return 504 and it will not be translated\n * to json body 'ProtocolError'.\n */\nexport class HttpGatewayTimeoutError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 504, undefined, cause);\n this.name = 'HttpGatewayTimeoutError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpInternalServerError - 500 Internal Server Error.\n */\nexport class HttpInternalServerError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 500, undefined, cause);\n this.name = 'InternalServerError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpVendorError - 598 Vendor Error.\n * Custom status code for vendor/external service errors with retry hint.\n */\nexport class HttpVendorError extends HttpError {\n constructor(\n message: string,\n public waitSeconds = 30,\n cause?: Error,\n ) {\n super(message, 598, undefined, cause);\n this.name = 'VendorError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpUserError - User validation error with 2xx status code.\n *\n * Uses HTTP 266 (non-standard 2xx code) intentionally because:\n * 1. User validation errors are \"successful\" from server perspective - user just made a mistake\n * 2. Browser DevTools show 4xx/5xx codes in RED, which is confusing for user validation\n * 3. Allows error to propagate up the stack via throw without triggering error monitoring\n * 4. Avoids polluting logs with \"errors\" that are actually expected user behavior\n *\n * This is a deliberate design pattern - do NOT change to 4xx codes.\n * Examples: \"Email already exists\", \"Invalid password format\", \"Required field missing\"\n */\nexport class HttpUserError extends HttpError {\n public errorCode?: string;\n\n constructor(message: string, errorCode?: string, cause?: Error) {\n super(message, 266, 'USER_ERROR', cause);\n this.name = 'UserError';\n this.errorCode = errorCode;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../../packages/http/http-api/src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP Error classes for webpieces-ts.\n * These errors are used throughout the framework for consistent error handling.\n */\n\n/**\n * ProtocolError - Data class for error response body.\n * This is what gets serialized and sent to the client.\n */\nexport class ProtocolError {\n public message?: string;\n public subType?: string;\n public field?: string;\n public waitSeconds?: number;\n public name?: string;\n public guiAlertMessage?: string;\n public errorCode?: string;\n}\n\n/**\n * HttpError - Base error class with HTTP status code.\n * All specific HTTP errors extend this class.\n */\nexport class HttpError extends Error {\n public code: number;\n public subType?: string;\n public readonly httpCause?: Error;\n\n constructor(\n message: string,\n code: number,\n subType?: string,\n cause?: Error,\n ) {\n super(message);\n this.code = code;\n this.subType = subType;\n this.httpCause = cause;\n }\n}\n\n// Error subtype constants\nexport const ENTITY_NOT_FOUND = 'EntityNotFoundError';\nexport const WRONG_LOGIN_TYPE = 'wrongLoginType';\nexport const WRONG_LOGIN = 'wronglogin';\nexport const NOT_APPROVED = 'notapproved';\nexport const EMAIL_NOT_CONFIRMED = 'email_not_confirmed';\nexport const WRONG_DOMAIN = 'wrongdomain';\nexport const WRONG_COMPANY = 'wrongcompany';\nexport const NO_REG_CODE = 'noregcode';\n\n/**\n * HttpNotFoundError - 404 Not Found.\n */\nexport class HttpNotFoundError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 404, undefined, cause);\n this.name = ENTITY_NOT_FOUND;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * EndpointNotFoundError - 404 for missing endpoints.\n */\nexport class EndpointNotFoundError extends HttpNotFoundError {\n constructor(message: string, cause?: Error) {\n super(message, cause);\n this.name = 'EndpointNotFoundError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpBadRequestError - 400 Bad Request.\n * Used for validation errors with optional field and GUI message.\n */\nexport class HttpBadRequestError extends HttpError {\n public field?: string;\n public guiMessage?: string;\n\n constructor(message: string, field?: string, guiMessage?: string, cause?: Error) {\n super(message, 400, undefined, cause);\n this.name = 'BadRequest';\n this.field = field;\n this.guiMessage = guiMessage;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpUnauthorizedError - 401 Unauthorized.\n */\nexport class HttpUnauthorizedError extends HttpError {\n constructor(message: string, subType?: string, cause?: Error) {\n super(message, 401, subType, cause);\n this.name = 'Unauthorized';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpForbiddenError - 403 Forbidden.\n */\nexport class HttpForbiddenError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 403, undefined, cause);\n this.name = 'Forbidden';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpTimeoutError - 408 Request Timeout.\n */\nexport class HttpTimeoutError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 408, undefined, cause);\n this.name = 'Timeout';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpBadGatewayError - 502 Bad Gateway.\n */\nexport class HttpBadGatewayError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 502, undefined, cause);\n this.name = 'HttpBadGatewayError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpGatewayTimeoutError - 504 Gateway Timeout.\n * SHOULD NOT BE USED SERVER SIDE SINCE ALBs will return 504 and it will not be translated\n * to json body 'ProtocolError'.\n */\nexport class HttpGatewayTimeoutError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 504, undefined, cause);\n this.name = 'HttpGatewayTimeoutError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpInternalServerError - 500 Internal Server Error.\n */\nexport class HttpInternalServerError extends HttpError {\n constructor(message: string, cause?: Error) {\n super(message, 500, undefined, cause);\n this.name = 'InternalServerError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpVendorError - 598 Vendor Error.\n * Custom status code for vendor/external service errors with retry hint.\n */\nexport class HttpVendorError extends HttpError {\n constructor(\n message: string,\n public waitSeconds = 30,\n cause?: Error,\n ) {\n super(message, 598, undefined, cause);\n this.name = 'VendorError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * HttpUserError - User validation error with 2xx status code.\n *\n * Uses HTTP 266 (non-standard 2xx code) intentionally because:\n * 1. User validation errors are \"successful\" from server perspective - user just made a mistake\n * 2. Browser DevTools show 4xx/5xx codes in RED, which is confusing for user validation\n * 3. Allows error to propagate up the stack via throw without triggering error monitoring\n * 4. Avoids polluting logs with \"errors\" that are actually expected user behavior\n *\n * This is a deliberate design pattern - do NOT change to 4xx codes.\n * Examples: \"Email already exists\", \"Invalid password format\", \"Required field missing\"\n */\nexport class HttpUserError extends HttpError {\n public errorCode?: string;\n\n constructor(message: string, errorCode?: string, cause?: Error) {\n super(message, 266, 'USER_ERROR', cause);\n this.name = 'UserError';\n this.errorCode = errorCode;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n"]}