@webpieces/http-server 0.3.278 → 0.3.280
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 +9 -7
- package/src/WebpiecesExpress.d.ts +44 -0
- package/src/WebpiecesExpress.js +71 -0
- package/src/WebpiecesExpress.js.map +1 -0
- package/src/WebpiecesMiddleware.d.ts +6 -0
- package/src/WebpiecesMiddleware.js +1 -1
- package/src/WebpiecesMiddleware.js.map +1 -1
- package/src/WebpiecesRouteCreator.js +1 -2
- package/src/WebpiecesRouteCreator.js.map +1 -1
- package/src/filters/ContextFilter.js +1 -1
- package/src/filters/ContextFilter.js.map +1 -1
- package/src/filters/LogApiFilter.js +1 -1
- package/src/filters/LogApiFilter.js.map +1 -1
- package/src/filters/RecordingFilter.js +1 -1
- package/src/filters/RecordingFilter.js.map +1 -1
- package/src/filters/ServiceAuthFilter.js +1 -1
- package/src/filters/ServiceAuthFilter.js.map +1 -1
- package/src/index.d.ts +4 -4
- package/src/index.js +15 -13
- package/src/index.js.map +1 -1
- package/src/InProcessApiClientFactory.d.ts +0 -34
- package/src/InProcessApiClientFactory.js +0 -77
- package/src/InProcessApiClientFactory.js.map +0 -1
- package/src/WebpiecesFactory.d.ts +0 -66
- package/src/WebpiecesFactory.js +0 -87
- package/src/WebpiecesFactory.js.map +0 -1
- package/src/WebpiecesServer.d.ts +0 -71
- package/src/WebpiecesServer.js +0 -3
- package/src/WebpiecesServer.js.map +0 -1
- package/src/WebpiecesServerImpl.d.ts +0 -103
- package/src/WebpiecesServerImpl.js +0 -255
- package/src/WebpiecesServerImpl.js.map +0 -1
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.
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
|
37
|
-
Object.defineProperty(exports, "RouteHandler", { enumerable: true, get: function () { return
|
|
38
|
-
Object.defineProperty(exports, "MethodMeta", { enumerable: true, get: function () { return
|
|
39
|
-
Object.defineProperty(exports, "RouteBuilderImpl", { enumerable: true, get: function () { return
|
|
40
|
-
Object.defineProperty(exports, "RouteHandlerWithMeta", { enumerable: true, get: function () { return
|
|
41
|
-
Object.defineProperty(exports, "FilterWithMeta", { enumerable: true, get: function () { return
|
|
42
|
-
Object.defineProperty(exports, "FilterMatcher", { enumerable: true, get: function () { return
|
|
43
|
-
Object.defineProperty(exports, "FilterDefinition", { enumerable: true, get: function () { return
|
|
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":";;;
|
|
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
|
-
}
|
package/src/WebpiecesFactory.js
DELETED
|
@@ -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"]}
|
package/src/WebpiecesServer.d.ts
DELETED
|
@@ -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
|
-
}
|
package/src/WebpiecesServer.js
DELETED
|
@@ -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
|
-
}
|