@webpieces/http-server 0.3.279 → 0.3.281

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/src/index.js CHANGED
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FilterDefinition = exports.FilterMatcher = exports.FilterWithMeta = exports.RouteHandlerWithMeta = exports.RouteBuilderImpl = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.WebpiecesModule = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.ServiceAuthFilter = exports.RecordingFilter = exports.LogApiFilter = exports.ContextFilter = exports.InProcessApiClientFactory = exports.WebpiecesRouteCreator = exports.WebpiecesMiddleware = exports.WebpiecesFactory = void 0;
4
- var WebpiecesFactory_1 = require("./WebpiecesFactory");
5
- Object.defineProperty(exports, "WebpiecesFactory", { enumerable: true, get: function () { return WebpiecesFactory_1.WebpiecesFactory; } });
3
+ exports.FilterDefinition = exports.FilterMatcher = exports.FilterWithMeta = exports.RouteHandlerWithMeta = exports.RouteBuilderImpl = exports.MethodMeta = exports.RouteHandler = exports.HeaderRegistry = exports.WebpiecesCoreHeaders = exports.WebpiecesModule = exports.recordable = exports.SpecGenerator = exports.TestCaseRecorderImpl = exports.ServiceAuthFilter = exports.RecordingFilter = exports.LogApiFilter = exports.ContextFilter = exports.InProcessApiClientFactory = exports.WebpiecesRouteCreator = exports.WebpiecesMiddleware = exports.WebpiecesExpress = void 0;
4
+ // Express adapter (the only place express lifecycle lives) over the node-only WebpiecesRouter
5
+ var WebpiecesExpress_1 = require("./WebpiecesExpress");
6
+ Object.defineProperty(exports, "WebpiecesExpress", { enumerable: true, get: function () { return WebpiecesExpress_1.WebpiecesExpress; } });
6
7
  var WebpiecesMiddleware_1 = require("./WebpiecesMiddleware");
7
8
  Object.defineProperty(exports, "WebpiecesMiddleware", { enumerable: true, get: function () { return WebpiecesMiddleware_1.WebpiecesMiddleware; } });
8
9
  var WebpiecesRouteCreator_1 = require("./WebpiecesRouteCreator");
9
10
  Object.defineProperty(exports, "WebpiecesRouteCreator", { enumerable: true, get: function () { return WebpiecesRouteCreator_1.WebpiecesRouteCreator; } });
10
- var InProcessApiClientFactory_1 = require("./InProcessApiClientFactory");
11
- Object.defineProperty(exports, "InProcessApiClientFactory", { enumerable: true, get: function () { return InProcessApiClientFactory_1.InProcessApiClientFactory; } });
11
+ // InProcessApiClientFactory moved to node-only http-routing; re-export for back-compat
12
+ var http_routing_1 = require("@webpieces/http-routing");
13
+ Object.defineProperty(exports, "InProcessApiClientFactory", { enumerable: true, get: function () { return http_routing_1.InProcessApiClientFactory; } });
12
14
  var ContextFilter_1 = require("./filters/ContextFilter");
13
15
  Object.defineProperty(exports, "ContextFilter", { enumerable: true, get: function () { return ContextFilter_1.ContextFilter; } });
14
16
  var LogApiFilter_1 = require("./filters/LogApiFilter");
@@ -33,12 +35,12 @@ var core_util_1 = require("@webpieces/core-util");
33
35
  Object.defineProperty(exports, "HeaderRegistry", { enumerable: true, get: function () { return core_util_1.HeaderRegistry; } });
34
36
  // Re-export from http-routing for backward compatibility
35
37
  // (FilterDefinition re-exported for one-import adapter ergonomics)
36
- var http_routing_1 = require("@webpieces/http-routing");
37
- Object.defineProperty(exports, "RouteHandler", { enumerable: true, get: function () { return http_routing_1.RouteHandler; } });
38
- Object.defineProperty(exports, "MethodMeta", { enumerable: true, get: function () { return http_routing_1.MethodMeta; } });
39
- Object.defineProperty(exports, "RouteBuilderImpl", { enumerable: true, get: function () { return http_routing_1.RouteBuilderImpl; } });
40
- Object.defineProperty(exports, "RouteHandlerWithMeta", { enumerable: true, get: function () { return http_routing_1.RouteHandlerWithMeta; } });
41
- Object.defineProperty(exports, "FilterWithMeta", { enumerable: true, get: function () { return http_routing_1.FilterWithMeta; } });
42
- Object.defineProperty(exports, "FilterMatcher", { enumerable: true, get: function () { return http_routing_1.FilterMatcher; } });
43
- Object.defineProperty(exports, "FilterDefinition", { enumerable: true, get: function () { return http_routing_1.FilterDefinition; } });
38
+ var http_routing_2 = require("@webpieces/http-routing");
39
+ Object.defineProperty(exports, "RouteHandler", { enumerable: true, get: function () { return http_routing_2.RouteHandler; } });
40
+ Object.defineProperty(exports, "MethodMeta", { enumerable: true, get: function () { return http_routing_2.MethodMeta; } });
41
+ Object.defineProperty(exports, "RouteBuilderImpl", { enumerable: true, get: function () { return http_routing_2.RouteBuilderImpl; } });
42
+ Object.defineProperty(exports, "RouteHandlerWithMeta", { enumerable: true, get: function () { return http_routing_2.RouteHandlerWithMeta; } });
43
+ Object.defineProperty(exports, "FilterWithMeta", { enumerable: true, get: function () { return http_routing_2.FilterWithMeta; } });
44
+ Object.defineProperty(exports, "FilterMatcher", { enumerable: true, get: function () { return http_routing_2.FilterMatcher; } });
45
+ Object.defineProperty(exports, "FilterDefinition", { enumerable: true, get: function () { return http_routing_2.FilterDefinition; } });
44
46
  //# sourceMappingURL=index.js.map
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":";;;AACA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,yEAAwE;AAA/D,sIAAA,yBAAyB,OAAA;AAClC,yDAAwD;AAA/C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,4GAAA,YAAY,OAAA;AACrB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,iEAAgE;AAAvD,sHAAA,iBAAiB,OAAA;AAE1B,+DAA+D;AAC/D,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,oDAAmD;AAA1C,wGAAA,UAAU,OAAA;AAEnB,mBAAmB;AACnB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,uEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,kDAAsD;AAA7C,2GAAA,cAAc,OAAA;AAEvB,yDAAyD;AACzD,mEAAmE;AACnE,wDAUiC;AAT7B,4GAAA,YAAY,OAAA;AAEZ,0GAAA,UAAU,OAAA;AACV,gHAAA,gBAAgB,OAAA;AAChB,oHAAA,oBAAoB,OAAA;AACpB,8GAAA,cAAc,OAAA;AAEd,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA","sourcesContent":["export { WebpiecesServer } from './WebpiecesServer';\nexport { WebpiecesFactory } from './WebpiecesFactory';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\nexport { WebpiecesRouteCreator } from './WebpiecesRouteCreator';\nexport { InProcessApiClientFactory } from './InProcessApiClientFactory';\nexport { ContextFilter } from './filters/ContextFilter';\nexport { LogApiFilter } from './filters/LogApiFilter';\nexport { RecordingFilter } from './filters/RecordingFilter';\nexport { ServiceAuthFilter } from './filters/ServiceAuthFilter';\n\n// Test-case recording (contract lives in @webpieces/core-util)\nexport { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';\nexport { SpecGenerator } from './recorder/SpecGenerator';\nexport { recordable } from './recorder/recordable';\n\n// Platform Headers\nexport { WebpiecesModule } from './modules/WebpiecesModule';\nexport { WebpiecesCoreHeaders } from './headers/WebpiecesCoreHeaders';\nexport { HeaderRegistry } from '@webpieces/core-util';\n\n// Re-export from http-routing for backward compatibility\n// (FilterDefinition re-exported for one-import adapter ergonomics)\nexport {\n RouteHandler,\n ExpressRouteHandler,\n MethodMeta,\n RouteBuilderImpl,\n RouteHandlerWithMeta,\n FilterWithMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n} from '@webpieces/http-routing';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/index.ts"],"names":[],"mappings":";;;AAAA,8FAA8F;AAC9F,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,uFAAuF;AACvF,wDAAoE;AAA3D,yHAAA,yBAAyB,OAAA;AAClC,yDAAwD;AAA/C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,4GAAA,YAAY,OAAA;AACrB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,iEAAgE;AAAvD,sHAAA,iBAAiB,OAAA;AAE1B,+DAA+D;AAC/D,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,oDAAmD;AAA1C,wGAAA,UAAU,OAAA;AAEnB,mBAAmB;AACnB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,uEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,kDAAsD;AAA7C,2GAAA,cAAc,OAAA;AAEvB,yDAAyD;AACzD,mEAAmE;AACnE,wDASiC;AAR7B,4GAAA,YAAY,OAAA;AACZ,0GAAA,UAAU,OAAA;AACV,gHAAA,gBAAgB,OAAA;AAChB,oHAAA,oBAAoB,OAAA;AACpB,8GAAA,cAAc,OAAA;AAEd,6GAAA,aAAa,OAAA;AACb,gHAAA,gBAAgB,OAAA","sourcesContent":["// Express adapter (the only place express lifecycle lives) over the node-only WebpiecesRouter\nexport { WebpiecesExpress } from './WebpiecesExpress';\nexport { WebpiecesMiddleware } from './WebpiecesMiddleware';\nexport { WebpiecesRouteCreator } from './WebpiecesRouteCreator';\n// InProcessApiClientFactory moved to node-only http-routing; re-export for back-compat\nexport { InProcessApiClientFactory } from '@webpieces/http-routing';\nexport { ContextFilter } from './filters/ContextFilter';\nexport { LogApiFilter } from './filters/LogApiFilter';\nexport { RecordingFilter } from './filters/RecordingFilter';\nexport { ServiceAuthFilter } from './filters/ServiceAuthFilter';\n\n// Test-case recording (contract lives in @webpieces/core-util)\nexport { TestCaseRecorderImpl } from './recorder/TestCaseRecorderImpl';\nexport { SpecGenerator } from './recorder/SpecGenerator';\nexport { recordable } from './recorder/recordable';\n\n// Platform Headers\nexport { WebpiecesModule } from './modules/WebpiecesModule';\nexport { WebpiecesCoreHeaders } from './headers/WebpiecesCoreHeaders';\nexport { HeaderRegistry } from '@webpieces/core-util';\n\n// Re-export from http-routing for backward compatibility\n// (FilterDefinition re-exported for one-import adapter ergonomics)\nexport {\n RouteHandler,\n MethodMeta,\n RouteBuilderImpl,\n RouteHandlerWithMeta,\n FilterWithMeta,\n HttpFilter,\n FilterMatcher,\n FilterDefinition,\n} from '@webpieces/http-routing';\n// ExpressRouteHandler now lives in http-server (express adapter), not node-only http-routing\nexport { ExpressRouteHandler } from './WebpiecesMiddleware';\n"]}
@@ -1,34 +0,0 @@
1
- import { RouteBuilderImpl } from '@webpieces/http-routing';
2
- /**
3
- * InProcessApiClientFactory - Creates API client proxies that invoke routes
4
- * in-process (full filter chain + controller) WITHOUT any HTTP overhead.
5
- *
6
- * Extracted from WebpiecesServerImpl so both the full server
7
- * (WebpiecesServer.createApiClient) and the embeddable adapter
8
- * (WebpiecesRouteCreator.createApiClient) share one code path.
9
- *
10
- * The client uses the ApiPrototype class to discover routes via decorators,
11
- * then creates pre-configured invoker functions for each API method.
12
- *
13
- * IMPORTANT: This loops over the API methods (from decorators), NOT all routes.
14
- * For each API method, it sets up the filter chain ONCE during proxy creation,
15
- * so subsequent calls reuse the same filter chain (efficient!).
16
- */
17
- export declare class InProcessApiClientFactory {
18
- private routeBuilder;
19
- constructor(routeBuilder: RouteBuilderImpl);
20
- /**
21
- * Create an API client proxy for testing.
22
- *
23
- * @param apiPrototype - The API prototype class with routing decorators (can be abstract)
24
- * @returns A proxy that implements the API interface
25
- *
26
- * Example:
27
- * ```typescript
28
- * const saveApi = factory.createApiClient<SaveApi>(SaveApi);
29
- * const response = await saveApi.save(request);
30
- * ```
31
- */
32
- createApiClient<T>(apiPrototype: abstract new (...args: any[]) => T): T;
33
- private runMethod;
34
- }
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InProcessApiClientFactory = void 0;
4
- const http_routing_1 = require("@webpieces/http-routing");
5
- const core_context_1 = require("@webpieces/core-context");
6
- /**
7
- * InProcessApiClientFactory - Creates API client proxies that invoke routes
8
- * in-process (full filter chain + controller) WITHOUT any HTTP overhead.
9
- *
10
- * Extracted from WebpiecesServerImpl so both the full server
11
- * (WebpiecesServer.createApiClient) and the embeddable adapter
12
- * (WebpiecesRouteCreator.createApiClient) share one code path.
13
- *
14
- * The client uses the ApiPrototype class to discover routes via decorators,
15
- * then creates pre-configured invoker functions for each API method.
16
- *
17
- * IMPORTANT: This loops over the API methods (from decorators), NOT all routes.
18
- * For each API method, it sets up the filter chain ONCE during proxy creation,
19
- * so subsequent calls reuse the same filter chain (efficient!).
20
- */
21
- class InProcessApiClientFactory {
22
- routeBuilder;
23
- constructor(routeBuilder) {
24
- this.routeBuilder = routeBuilder;
25
- }
26
- /**
27
- * Create an API client proxy for testing.
28
- *
29
- * @param apiPrototype - The API prototype class with routing decorators (can be abstract)
30
- * @returns A proxy that implements the API interface
31
- *
32
- * Example:
33
- * ```typescript
34
- * const saveApi = factory.createApiClient<SaveApi>(SaveApi);
35
- * const response = await saveApi.save(request);
36
- * ```
37
- */
38
- // webpieces-disable no-any-unknown -- abstract constructor signature requires any[] args
39
- createApiClient(apiPrototype) {
40
- // Get endpoints from the API prototype using @ApiPath/@Endpoint decorators
41
- const basePath = (0, http_routing_1.getApiPath)(apiPrototype) || '';
42
- const endpoints = (0, http_routing_1.getEndpoints)(apiPrototype) || {};
43
- // Create proxy object
44
- // webpieces-disable no-any-unknown -- proxy holds methods of arbitrary API shapes
45
- const proxy = {};
46
- // Loop over API endpoints and create proxy functions
47
- for (const [methodName, endpointPath] of Object.entries(endpoints)) {
48
- const httpMethod = 'POST';
49
- const path = basePath + endpointPath;
50
- const authMeta = (0, http_routing_1.getAuthMeta)(apiPrototype, methodName);
51
- const routeMeta = new http_routing_1.RouteMetadata(httpMethod, path, methodName, apiPrototype.name, authMeta);
52
- // Create invoker service ONCE (sets up filter chain once, not on every call!)
53
- const service = this.routeBuilder.createRouteInvoker(httpMethod, path);
54
- // Proxy method creates MethodMeta and calls the pre-configured service
55
- // webpieces-disable no-any-unknown -- request/response DTO types are erased at proxy level
56
- proxy[methodName] = async (requestDto) => {
57
- // Auto-activate a RequestContext if the test did not wrap the call itself
58
- if (!core_context_1.RequestContext.isActive()) {
59
- return core_context_1.RequestContext.run(async () => {
60
- return await this.runMethod(routeMeta, requestDto, service);
61
- });
62
- }
63
- return await this.runMethod(routeMeta, requestDto, service);
64
- };
65
- }
66
- return proxy;
67
- }
68
- // webpieces-disable no-any-unknown -- DTO types are erased at the routing layer
69
- async runMethod(routeMeta, requestDto, service) {
70
- // Create MethodMeta without headers (in-process mode - no HTTP involved)
71
- const meta = new http_routing_1.MethodMeta(routeMeta, undefined, requestDto);
72
- const responseWrapper = await service.invoke(meta);
73
- return responseWrapper.response;
74
- }
75
- }
76
- exports.InProcessApiClientFactory = InProcessApiClientFactory;
77
- //# sourceMappingURL=InProcessApiClientFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"InProcessApiClientFactory.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/InProcessApiClientFactory.ts"],"names":[],"mappings":";;;AAAA,0DAOiC;AACjC,0DAAyD;AAGzD;;;;;;;;;;;;;;GAcG;AACH,MAAa,yBAAyB;IACd;IAApB,YAAoB,YAA8B;QAA9B,iBAAY,GAAZ,YAAY,CAAkB;IAAG,CAAC;IAEtD;;;;;;;;;;;OAWG;IACH,yFAAyF;IACzF,eAAe,CAAI,YAAgD;QAC/D,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,IAAA,yBAAU,EAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAEnD,sBAAsB;QACtB,kFAAkF;QAClF,MAAM,KAAK,GAA4B,EAAE,CAAC;QAE1C,qDAAqD;QACrD,KAAK,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACjE,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,IAAI,GAAG,QAAQ,GAAG,YAAY,CAAC;YAErC,MAAM,QAAQ,GAAG,IAAA,0BAAW,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,4BAAa,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAE/F,8EAA8E;YAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAEvE,uEAAuE;YACvE,2FAA2F;YAC3F,KAAK,CAAC,UAAU,CAAC,GAAG,KAAK,EAAE,UAAmB,EAAoB,EAAE;gBAChE,0EAA0E;gBAC1E,IAAI,CAAC,6BAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;oBAC7B,OAAO,6BAAc,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;wBACjC,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;oBAChE,CAAC,CAAC,CAAC;gBACP,CAAC;gBACD,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAChE,CAAC,CAAC;QACN,CAAC;QAED,OAAO,KAAU,CAAC;IACtB,CAAC;IAED,gFAAgF;IACxE,KAAK,CAAC,SAAS,CAAC,SAAwB,EAAE,UAAmB,EAAE,OAAiD;QACpH,yEAAyE;QACzE,MAAM,IAAI,GAAG,IAAI,yBAAU,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,OAAO,eAAe,CAAC,QAAQ,CAAC;IACpC,CAAC;CACJ;AA3DD,8DA2DC","sourcesContent":["import {\n getApiPath,\n getAuthMeta,\n getEndpoints,\n MethodMeta,\n RouteBuilderImpl,\n RouteMetadata,\n} from '@webpieces/http-routing';\nimport { RequestContext } from '@webpieces/core-context';\nimport { Service, WpResponse } from '@webpieces/http-filters';\n\n/**\n * InProcessApiClientFactory - Creates API client proxies that invoke routes\n * in-process (full filter chain + controller) WITHOUT any HTTP overhead.\n *\n * Extracted from WebpiecesServerImpl so both the full server\n * (WebpiecesServer.createApiClient) and the embeddable adapter\n * (WebpiecesRouteCreator.createApiClient) share one code path.\n *\n * The client uses the ApiPrototype class to discover routes via decorators,\n * then creates pre-configured invoker functions for each API method.\n *\n * IMPORTANT: This loops over the API methods (from decorators), NOT all routes.\n * For each API method, it sets up the filter chain ONCE during proxy creation,\n * so subsequent calls reuse the same filter chain (efficient!).\n */\nexport class InProcessApiClientFactory {\n constructor(private routeBuilder: RouteBuilderImpl) {}\n\n /**\n * Create an API client proxy for testing.\n *\n * @param apiPrototype - The API prototype class with routing decorators (can be abstract)\n * @returns A proxy that implements the API interface\n *\n * Example:\n * ```typescript\n * const saveApi = factory.createApiClient<SaveApi>(SaveApi);\n * const response = await saveApi.save(request);\n * ```\n */\n // webpieces-disable no-any-unknown -- abstract constructor signature requires any[] args\n createApiClient<T>(apiPrototype: abstract new (...args: any[]) => T): T {\n // Get endpoints from the API prototype using @ApiPath/@Endpoint decorators\n const basePath = getApiPath(apiPrototype) || '';\n const endpoints = getEndpoints(apiPrototype) || {};\n\n // Create proxy object\n // webpieces-disable no-any-unknown -- proxy holds methods of arbitrary API shapes\n const proxy: Record<string, unknown> = {};\n\n // Loop over API endpoints and create proxy functions\n for (const [methodName, endpointPath] of Object.entries(endpoints)) {\n const httpMethod = 'POST';\n const path = basePath + endpointPath;\n\n const authMeta = getAuthMeta(apiPrototype, methodName);\n const routeMeta = new RouteMetadata(httpMethod, path, methodName, apiPrototype.name, authMeta);\n\n // Create invoker service ONCE (sets up filter chain once, not on every call!)\n const service = this.routeBuilder.createRouteInvoker(httpMethod, path);\n\n // Proxy method creates MethodMeta and calls the pre-configured service\n // webpieces-disable no-any-unknown -- request/response DTO types are erased at proxy level\n proxy[methodName] = async (requestDto: unknown): Promise<unknown> => {\n // Auto-activate a RequestContext if the test did not wrap the call itself\n if (!RequestContext.isActive()) {\n return RequestContext.run(async () => {\n return await this.runMethod(routeMeta, requestDto, service);\n });\n }\n return await this.runMethod(routeMeta, requestDto, service);\n };\n }\n\n return proxy as T;\n }\n\n // webpieces-disable no-any-unknown -- DTO types are erased at the routing layer\n private async runMethod(routeMeta: RouteMetadata, requestDto: unknown, service: Service<MethodMeta, WpResponse<unknown>>): Promise<unknown> {\n // Create MethodMeta without headers (in-process mode - no HTTP involved)\n const meta = new MethodMeta(routeMeta, undefined, requestDto);\n const responseWrapper = await service.invoke(meta);\n return responseWrapper.response;\n }\n}\n"]}
@@ -1,66 +0,0 @@
1
- import { ContainerModule } from 'inversify';
2
- import { WebAppMeta, WebpiecesConfig } from '@webpieces/http-routing';
3
- import { WebpiecesServer } from './WebpiecesServer';
4
- /**
5
- * WebpiecesFactory - Factory for creating WebPieces server instances.
6
- *
7
- * This factory encapsulates the server creation and initialization logic:
8
- * 1. Creates the WebPieces DI container
9
- * 2. Loads the provider module for @provideSingleton decorators
10
- * 3. Resolves WebpiecesServerImpl from DI
11
- * 4. Calls initialize() with the container and meta
12
- * 5. Returns the server as the WebpiecesServer interface
13
- *
14
- * The returned WebpiecesServer interface only exposes start() and stop(),
15
- * hiding the internal initialize() method from consumers.
16
- *
17
- * Usage:
18
- * ```typescript
19
- * // Production
20
- * const config = new WebpiecesConfig();
21
- * const server = WebpiecesFactory.create(new ProdServerMeta(), config);
22
- * server.start(8080);
23
- *
24
- * // Testing with appOverrides
25
- * const appOverrides = new ContainerModule((bind) => {
26
- * bind(TYPES.RemoteApi).toConstantValue(mockRemoteApi);
27
- * });
28
- * const server = WebpiecesFactory.create(new ProdServerMeta(), config, appOverrides);
29
- * const api = server.createApiClient(SaveApi);
30
- * ```
31
- *
32
- * This pattern:
33
- * - Enforces proper initialization order
34
- * - Hides implementation details from consumers
35
- * - Makes the API simpler and harder to misuse
36
- * - Follows the principle of least privilege
37
- */
38
- export declare class WebpiecesFactory {
39
- /**
40
- * Create a new WebPieces server instance.
41
- *
42
- * This method:
43
- * 1. Creates the WebPieces framework DI container
44
- * 2. Loads framework bindings via buildProviderModule()
45
- * 3. Resolves the server implementation from DI
46
- * 4. Initializes the server with the container and meta
47
- * 5. Loads optional override module (for testing)
48
- *
49
- * @param meta - User-provided WebAppMeta with DI modules and routes
50
- * @param appOverrides - Optional ContainerModule for test overrides (loaded LAST to override bindings)
51
- * @returns A fully initialized WebpiecesServer ready to start()
52
- */
53
- /**
54
- * Create a new WebPieces server instance asynchronously.
55
- *
56
- * Use this method when you need async operations in your override modules
57
- * (e.g., rebind() in new Inversify versions).
58
- *
59
- * @param meta - User-provided WebAppMeta with DI modules and routes
60
- * @param config - Server configuration (CORS, etc.)
61
- * @param appOverrides - Optional ContainerModule for app test overrides (can use async operations)
62
- * @param testMode - Optional flag for test mode (skips Express server)
63
- * @returns Promise of a fully initialized WebpiecesServer ready to start()
64
- */
65
- static create(meta: WebAppMeta, config: WebpiecesConfig, appOverrides?: ContainerModule, testMode?: boolean): Promise<WebpiecesServer>;
66
- }
@@ -1,87 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebpiecesFactory = void 0;
4
- const inversify_1 = require("inversify");
5
- const binding_decorators_1 = require("@inversifyjs/binding-decorators");
6
- const http_routing_1 = require("@webpieces/http-routing");
7
- const WebpiecesServerImpl_1 = require("./WebpiecesServerImpl");
8
- /**
9
- * WebpiecesFactory - Factory for creating WebPieces server instances.
10
- *
11
- * This factory encapsulates the server creation and initialization logic:
12
- * 1. Creates the WebPieces DI container
13
- * 2. Loads the provider module for @provideSingleton decorators
14
- * 3. Resolves WebpiecesServerImpl from DI
15
- * 4. Calls initialize() with the container and meta
16
- * 5. Returns the server as the WebpiecesServer interface
17
- *
18
- * The returned WebpiecesServer interface only exposes start() and stop(),
19
- * hiding the internal initialize() method from consumers.
20
- *
21
- * Usage:
22
- * ```typescript
23
- * // Production
24
- * const config = new WebpiecesConfig();
25
- * const server = WebpiecesFactory.create(new ProdServerMeta(), config);
26
- * server.start(8080);
27
- *
28
- * // Testing with appOverrides
29
- * const appOverrides = new ContainerModule((bind) => {
30
- * bind(TYPES.RemoteApi).toConstantValue(mockRemoteApi);
31
- * });
32
- * const server = WebpiecesFactory.create(new ProdServerMeta(), config, appOverrides);
33
- * const api = server.createApiClient(SaveApi);
34
- * ```
35
- *
36
- * This pattern:
37
- * - Enforces proper initialization order
38
- * - Hides implementation details from consumers
39
- * - Makes the API simpler and harder to misuse
40
- * - Follows the principle of least privilege
41
- */
42
- class WebpiecesFactory {
43
- /**
44
- * Create a new WebPieces server instance.
45
- *
46
- * This method:
47
- * 1. Creates the WebPieces framework DI container
48
- * 2. Loads framework bindings via buildProviderModule()
49
- * 3. Resolves the server implementation from DI
50
- * 4. Initializes the server with the container and meta
51
- * 5. Loads optional override module (for testing)
52
- *
53
- * @param meta - User-provided WebAppMeta with DI modules and routes
54
- * @param appOverrides - Optional ContainerModule for test overrides (loaded LAST to override bindings)
55
- * @returns A fully initialized WebpiecesServer ready to start()
56
- */
57
- /**
58
- * Create a new WebPieces server instance asynchronously.
59
- *
60
- * Use this method when you need async operations in your override modules
61
- * (e.g., rebind() in new Inversify versions).
62
- *
63
- * @param meta - User-provided WebAppMeta with DI modules and routes
64
- * @param config - Server configuration (CORS, etc.)
65
- * @param appOverrides - Optional ContainerModule for app test overrides (can use async operations)
66
- * @param testMode - Optional flag for test mode (skips Express server)
67
- * @returns Promise of a fully initialized WebpiecesServer ready to start()
68
- */
69
- static async create(meta, config, appOverrides, testMode) {
70
- // Create WebPieces container for framework-level bindings
71
- const webpiecesContainer = new inversify_1.Container();
72
- // Bind WebAppMeta so it can be injected into framework classes
73
- webpiecesContainer.bind(http_routing_1.WEBAPP_META_TOKEN).toConstantValue(meta);
74
- // Bind WebpiecesConfig so it can be injected into framework classes
75
- webpiecesContainer.bind(http_routing_1.WEBPIECES_CONFIG_TOKEN).toConstantValue(config);
76
- // Load buildProviderModule to auto-scan for @provideSingleton decorators
77
- await webpiecesContainer.load((0, binding_decorators_1.buildProviderModule)());
78
- // Resolve WebpiecesServerImpl from DI container
79
- const serverImpl = webpiecesContainer.get(WebpiecesServerImpl_1.WebpiecesServerImpl);
80
- // Initialize the server asynchronously (loads app DI modules, registers routes)
81
- await serverImpl.initialize(webpiecesContainer, appOverrides);
82
- // Return as interface to hide initialize() from consumers
83
- return serverImpl;
84
- }
85
- }
86
- exports.WebpiecesFactory = WebpiecesFactory;
87
- //# sourceMappingURL=WebpiecesFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WebpiecesFactory.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/WebpiecesFactory.ts"],"names":[],"mappings":";;;AAAA,yCAAuD;AACvD,wEAAsE;AACtE,0DAAiH;AAEjH,+DAA4D;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAa,gBAAgB;IACzB;;;;;;;;;;;;;OAaG;IAEH;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CACf,IAAgB,EAChB,MAAuB,EACvB,YAA8B,EAC9B,QAAkB;QAElB,0DAA0D;QAC1D,MAAM,kBAAkB,GAAG,IAAI,qBAAS,EAAE,CAAC;QAE3C,+DAA+D;QAC/D,kBAAkB,CAAC,IAAI,CAAa,gCAAiB,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAE7E,oEAAoE;QACpE,kBAAkB,CAAC,IAAI,CAAkB,qCAAsB,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAEzF,yEAAyE;QACzE,MAAM,kBAAkB,CAAC,IAAI,CAAC,IAAA,wCAAmB,GAAE,CAAC,CAAC;QAErD,gDAAgD;QAChD,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,yCAAmB,CAAC,CAAC;QAE/D,gFAAgF;QAChF,MAAM,UAAU,CAAC,UAAU,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;QAE9D,0DAA0D;QAC1D,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AAvDD,4CAuDC","sourcesContent":["import { Container, ContainerModule } from 'inversify';\nimport { buildProviderModule } from '@inversifyjs/binding-decorators';\nimport { WebAppMeta, WEBAPP_META_TOKEN, WebpiecesConfig, WEBPIECES_CONFIG_TOKEN } from '@webpieces/http-routing';\nimport { WebpiecesServer } from './WebpiecesServer';\nimport { WebpiecesServerImpl } from './WebpiecesServerImpl';\n\n/**\n * WebpiecesFactory - Factory for creating WebPieces server instances.\n *\n * This factory encapsulates the server creation and initialization logic:\n * 1. Creates the WebPieces DI container\n * 2. Loads the provider module for @provideSingleton decorators\n * 3. Resolves WebpiecesServerImpl from DI\n * 4. Calls initialize() with the container and meta\n * 5. Returns the server as the WebpiecesServer interface\n *\n * The returned WebpiecesServer interface only exposes start() and stop(),\n * hiding the internal initialize() method from consumers.\n *\n * Usage:\n * ```typescript\n * // Production\n * const config = new WebpiecesConfig();\n * const server = WebpiecesFactory.create(new ProdServerMeta(), config);\n * server.start(8080);\n *\n * // Testing with appOverrides\n * const appOverrides = new ContainerModule((bind) => {\n * bind(TYPES.RemoteApi).toConstantValue(mockRemoteApi);\n * });\n * const server = WebpiecesFactory.create(new ProdServerMeta(), config, appOverrides);\n * const api = server.createApiClient(SaveApi);\n * ```\n *\n * This pattern:\n * - Enforces proper initialization order\n * - Hides implementation details from consumers\n * - Makes the API simpler and harder to misuse\n * - Follows the principle of least privilege\n */\nexport class WebpiecesFactory {\n /**\n * Create a new WebPieces server instance.\n *\n * This method:\n * 1. Creates the WebPieces framework DI container\n * 2. Loads framework bindings via buildProviderModule()\n * 3. Resolves the server implementation from DI\n * 4. Initializes the server with the container and meta\n * 5. Loads optional override module (for testing)\n *\n * @param meta - User-provided WebAppMeta with DI modules and routes\n * @param appOverrides - Optional ContainerModule for test overrides (loaded LAST to override bindings)\n * @returns A fully initialized WebpiecesServer ready to start()\n */\n\n /**\n * Create a new WebPieces server instance asynchronously.\n *\n * Use this method when you need async operations in your override modules\n * (e.g., rebind() in new Inversify versions).\n *\n * @param meta - User-provided WebAppMeta with DI modules and routes\n * @param config - Server configuration (CORS, etc.)\n * @param appOverrides - Optional ContainerModule for app test overrides (can use async operations)\n * @param testMode - Optional flag for test mode (skips Express server)\n * @returns Promise of a fully initialized WebpiecesServer ready to start()\n */\n static async create(\n meta: WebAppMeta,\n config: WebpiecesConfig,\n appOverrides?: ContainerModule,\n testMode?: boolean\n ): Promise<WebpiecesServer> {\n // Create WebPieces container for framework-level bindings\n const webpiecesContainer = new Container();\n\n // Bind WebAppMeta so it can be injected into framework classes\n webpiecesContainer.bind<WebAppMeta>(WEBAPP_META_TOKEN).toConstantValue(meta);\n\n // Bind WebpiecesConfig so it can be injected into framework classes\n webpiecesContainer.bind<WebpiecesConfig>(WEBPIECES_CONFIG_TOKEN).toConstantValue(config);\n\n // Load buildProviderModule to auto-scan for @provideSingleton decorators\n await webpiecesContainer.load(buildProviderModule());\n\n // Resolve WebpiecesServerImpl from DI container\n const serverImpl = webpiecesContainer.get(WebpiecesServerImpl);\n\n // Initialize the server asynchronously (loads app DI modules, registers routes)\n await serverImpl.initialize(webpiecesContainer, appOverrides);\n\n // Return as interface to hide initialize() from consumers\n return serverImpl;\n }\n}\n"]}
@@ -1,71 +0,0 @@
1
- import { Container } from 'inversify';
2
- /**
3
- * WebpiecesServer - Public interface for WebPieces server.
4
- *
5
- * This interface exposes the methods needed by application code:
6
- * - start(): Start the HTTP server
7
- * - stop(): Stop the HTTP server
8
- * - createApiClient(): Create API client proxy for testing (no HTTP!)
9
- * - getContainer(): Access DI container for verification
10
- *
11
- * The initialization logic is hidden inside WebpiecesFactory.create().
12
- * This provides a clean API and prevents accidental re-initialization.
13
- *
14
- * Usage:
15
- * ```typescript
16
- * // Production
17
- * const server = WebpiecesFactory.create(new ProdServerMeta());
18
- * await server.start(8080);
19
- *
20
- * // Testing (no HTTP needed!)
21
- * const server = WebpiecesFactory.create(new ProdServerMeta(), overrides);
22
- * const api = server.createApiClient(SaveApi);
23
- * const response = await api.save(request);
24
- * ```
25
- */
26
- export interface WebpiecesServer {
27
- /**
28
- * Start the HTTP server with Express.
29
- * Returns a Promise that resolves when the server is listening,
30
- * or rejects if the server fails to start.
31
- *
32
- * @param port - The port to listen on (default: 8080)
33
- * @returns Promise that resolves when server is ready
34
- */
35
- start(port?: number): Promise<void>;
36
- /**
37
- * Stop the HTTP server.
38
- * Returns a Promise that resolves when the server is stopped,
39
- * or rejects if there's an error stopping the server.
40
- *
41
- * @returns Promise that resolves when server is stopped
42
- */
43
- stop(): Promise<void>;
44
- /**
45
- * Create an API client proxy for testing.
46
- *
47
- * This creates a client that routes calls through the full filter chain
48
- * and controller, but WITHOUT any HTTP overhead. Perfect for testing!
49
- *
50
- * The client uses the ApiPrototype class to discover routes via decorators,
51
- * then invokes the corresponding controller method through the filter chain.
52
- *
53
- * @param apiPrototype - The API prototype class with routing decorators (can be abstract)
54
- * @returns A proxy that implements the API interface
55
- *
56
- * Example:
57
- * ```typescript
58
- * const saveApi = server.createApiClient<SaveApi>(SaveApi);
59
- * const response = await saveApi.save(request);
60
- * ```
61
- */
62
- createApiClient<T>(apiPrototype: abstract new (...args: any[]) => T): T;
63
- /**
64
- * Get the application DI container.
65
- *
66
- * Useful for testing to verify state or access services directly.
67
- *
68
- * @returns The application Container
69
- */
70
- getContainer(): Container;
71
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=WebpiecesServer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WebpiecesServer.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/WebpiecesServer.ts"],"names":[],"mappings":"","sourcesContent":["import { Container } from 'inversify';\n\n/**\n * WebpiecesServer - Public interface for WebPieces server.\n *\n * This interface exposes the methods needed by application code:\n * - start(): Start the HTTP server\n * - stop(): Stop the HTTP server\n * - createApiClient(): Create API client proxy for testing (no HTTP!)\n * - getContainer(): Access DI container for verification\n *\n * The initialization logic is hidden inside WebpiecesFactory.create().\n * This provides a clean API and prevents accidental re-initialization.\n *\n * Usage:\n * ```typescript\n * // Production\n * const server = WebpiecesFactory.create(new ProdServerMeta());\n * await server.start(8080);\n *\n * // Testing (no HTTP needed!)\n * const server = WebpiecesFactory.create(new ProdServerMeta(), overrides);\n * const api = server.createApiClient(SaveApi);\n * const response = await api.save(request);\n * ```\n */\nexport interface WebpiecesServer {\n /**\n * Start the HTTP server with Express.\n * Returns a Promise that resolves when the server is listening,\n * or rejects if the server fails to start.\n *\n * @param port - The port to listen on (default: 8080)\n * @returns Promise that resolves when server is ready\n */\n start(port?: number): Promise<void>;\n\n /**\n * Stop the HTTP server.\n * Returns a Promise that resolves when the server is stopped,\n * or rejects if there's an error stopping the server.\n *\n * @returns Promise that resolves when server is stopped\n */\n stop(): Promise<void>;\n\n /**\n * Create an API client proxy for testing.\n *\n * This creates a client that routes calls through the full filter chain\n * and controller, but WITHOUT any HTTP overhead. Perfect for testing!\n *\n * The client uses the ApiPrototype class to discover routes via decorators,\n * then invokes the corresponding controller method through the filter chain.\n *\n * @param apiPrototype - The API prototype class with routing decorators (can be abstract)\n * @returns A proxy that implements the API interface\n *\n * Example:\n * ```typescript\n * const saveApi = server.createApiClient<SaveApi>(SaveApi);\n * const response = await saveApi.save(request);\n * ```\n */\n createApiClient<T>(apiPrototype: abstract new (...args: any[]) => T): T;\n\n /**\n * Get the application DI container.\n *\n * Useful for testing to verify state or access services directly.\n *\n * @returns The application Container\n */\n getContainer(): Container;\n}\n"]}
@@ -1,103 +0,0 @@
1
- import { Container, ContainerModule } from 'inversify';
2
- import { RouteBuilderImpl, WebAppMeta } from '@webpieces/http-routing';
3
- import { WebpiecesServer } from './WebpiecesServer';
4
- import { WebpiecesMiddleware } from './WebpiecesMiddleware';
5
- export declare class WebpiecesServerImpl implements WebpiecesServer {
6
- private meta;
7
- private routeBuilder;
8
- private middleware;
9
- private webpiecesContainer;
10
- /**
11
- * Application container: User's application bindings.
12
- * This is a child container of webpiecesContainer, so it can access
13
- * framework bindings while keeping app bindings separate.
14
- */
15
- private appContainer;
16
- private initialized;
17
- private app?;
18
- private server?;
19
- private port;
20
- constructor(meta: WebAppMeta, routeBuilder: RouteBuilderImpl, middleware: WebpiecesMiddleware);
21
- /**
22
- * Initialize the server asynchronously.
23
- * This is called by WebpiecesFactory.create() after resolving this class from DI.
24
- * This method is internal and not exposed on the WebpiecesServer interface.
25
- *
26
- * @param webpiecesContainer - The framework container
27
- * @param meta - User-provided WebAppMeta with DI modules and routes
28
- * @param appOverrides - Optional ContainerModule for app test overrides (loaded LAST)
29
- */
30
- initialize(webpiecesContainer: Container, appOverrides?: ContainerModule): Promise<void>;
31
- /**
32
- * Load DI modules from WebAppMeta.
33
- *
34
- * Currently, all user modules are loaded into the application container.
35
- * In the future, we could separate:
36
- * - WebPieces framework modules -> webpiecesContainer
37
- * - Application modules -> appContainer
38
- *
39
- * For now, everything goes into appContainer which has access to webpiecesContainer.
40
- *
41
- * @param appOverrides - Optional ContainerModule for app test overrides (loaded LAST to override bindings)
42
- */
43
- private loadDIModules;
44
- /**
45
- * Register routes from WebAppMeta.
46
- *
47
- * Creates an explicit RouteBuilderImpl instead of an anonymous object.
48
- * This improves:
49
- * - Traceability: Can Cmd+Click on addRoute to see implementation
50
- * - Debugging: Explicit class shows up in stack traces
51
- * - Understanding: Clear class name vs anonymous object
52
- */
53
- private registerRoutes;
54
- /**
55
- * Start the HTTP server with Express.
56
- * Returns a Promise that resolves when the server is listening,
57
- * or rejects if the server fails to start.
58
- *
59
- * @param port - The port to listen on (default: 8080)
60
- * @returns Promise that resolves when server is ready
61
- */
62
- start(port?: number, testMode?: boolean): Promise<void>;
63
- /**
64
- * Stop the HTTP server.
65
- * Returns a Promise that resolves when the server is stopped,
66
- * or rejects if there's an error stopping the server.
67
- *
68
- * @returns Promise that resolves when server is stopped
69
- */
70
- stop(): Promise<void>;
71
- /**
72
- * Get the application DI container.
73
- *
74
- * Useful for testing to verify state or access services directly.
75
- *
76
- * @returns The application Container
77
- */
78
- getContainer(): Container;
79
- /**
80
- * Create an API client proxy for testing.
81
- *
82
- * This creates a client that routes calls through the full filter chain
83
- * and controller, but WITHOUT any HTTP overhead. Perfect for testing!
84
- *
85
- * The client uses the ApiPrototype class to discover routes via decorators,
86
- * then creates pre-configured invoker functions for each API method.
87
- *
88
- * IMPORTANT: This loops over the API methods (from decorators), NOT all routes.
89
- * For each API method, it sets up the filter chain ONCE during proxy creation,
90
- * so subsequent calls reuse the same filter chain (efficient!).
91
- *
92
- * @param apiPrototype - The abstract API prototype whose routing decorators declare the routes
93
- * @returns A proxy that implements the API interface
94
- *
95
- * Example:
96
- * ```typescript
97
- * const saveApi = server.createApiClient<SaveApi>(SaveApi);
98
- * const response = await saveApi.save(request);
99
- * ```
100
- */
101
- createApiClient<T>(apiPrototype: abstract new (...args: any[]) => T): T;
102
- private clientFactory?;
103
- }