libmodulor 0.18.1 → 0.19.0
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/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/dist/esm/apps/Helper/src/lib/project.js +4 -4
- package/dist/esm/error/index.d.ts +3 -0
- package/dist/esm/error/index.js +3 -0
- package/dist/esm/error/internal/NotAvailableError.d.ts +3 -0
- package/dist/esm/error/internal/NotAvailableError.js +7 -0
- package/dist/esm/error/internal/NotCallableError.d.ts +4 -0
- package/dist/esm/error/internal/NotCallableError.js +7 -0
- package/dist/esm/error/internal/NotImplementedError.d.ts +3 -0
- package/dist/esm/error/internal/NotImplementedError.js +7 -0
- package/dist/esm/index.cloudflare-worker-hono.d.ts +5 -0
- package/dist/esm/index.cloudflare-worker-hono.js +5 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.node-express.d.ts +2 -0
- package/dist/esm/index.node-express.js +2 -0
- package/dist/esm/index.node-hono.d.ts +1 -0
- package/dist/esm/index.node-hono.js +1 -0
- package/dist/esm/product/index.d.ts +1 -0
- package/dist/esm/product/index.js +1 -0
- package/dist/esm/product/workers/SyncProductUCsLoader.d.ts +15 -0
- package/dist/esm/product/workers/SyncProductUCsLoader.js +52 -0
- package/dist/esm/std/impl/FakeFSManager.js +2 -1
- package/dist/esm/std/impl/FakeJobManager.d.ts +1 -0
- package/dist/esm/std/impl/FakeJobManager.js +3 -0
- package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +2 -0
- package/dist/esm/std/impl/SimpleMapI18nManager.js +14 -8
- package/dist/esm/std/impl/UCDataStoreExternalResourceManager.js +1 -1
- package/dist/esm/std/impl/WebCryptoManager.js +5 -4
- package/dist/esm/std/impl/WebFSManager.js +15 -14
- package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts +32 -0
- package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js +87 -0
- package/dist/esm/target/lib/mcp-server/MCPServerBooter.d.ts +3 -2
- package/dist/esm/target/lib/mcp-server/MCPServerBooter.js +10 -6
- package/dist/esm/target/lib/server/ServerBooter.d.ts +1 -0
- package/dist/esm/target/lib/server/ServerBooter.js +41 -44
- package/dist/esm/target/lib/server/ServerManager.d.ts +7 -0
- package/dist/esm/target/lib/server/SyncEdgeWorkerInitializer.d.ts +17 -0
- package/dist/esm/target/lib/server/SyncEdgeWorkerInitializer.js +76 -0
- package/dist/esm/target/lib/server/funcs.d.ts +3 -0
- package/dist/esm/target/lib/server/funcs.js +11 -0
- package/dist/esm/target/lib/server-express/HelmetMiddlewareBuilder.d.ts +12 -0
- package/dist/esm/target/lib/server-express/HelmetMiddlewareBuilder.js +39 -0
- package/dist/esm/target/lib/server-express/funcs.d.ts +15 -0
- package/dist/esm/target/lib/server-express/funcs.js +103 -0
- package/dist/esm/target/lib/server-hono/funcs.d.ts +10 -0
- package/dist/esm/target/lib/server-hono/funcs.js +72 -0
- package/dist/esm/target/lib/server-node/funcs.d.ts +5 -0
- package/dist/esm/target/lib/server-node/funcs.js +25 -0
- package/dist/esm/target/lib/server-node/types.d.ts +2 -0
- package/dist/esm/target/nextjs-server/NextJSServerManager.d.ts +2 -0
- package/dist/esm/target/nextjs-server/NextJSServerManager.js +6 -0
- package/dist/esm/target/node-core-cli/NodeCoreCLIManager.d.ts +3 -1
- package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +8 -5
- package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +6 -5
- package/dist/esm/target/node-express-server/NodeExpressServerManager.js +16 -103
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +7 -5
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +16 -67
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +5 -1
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +42 -29
- package/dist/esm/testing/UCDataStoreTester.js +3 -3
- package/dist/esm/uc/data-store.d.ts +3 -4
- package/dist/esm/uc/helpers/UCOutputBuilder.js +1 -0
- package/dist/esm/uc/impl/CloudflareD1UCDataStore.d.ts +34 -0
- package/dist/esm/uc/impl/CloudflareD1UCDataStore.js +201 -0
- package/dist/esm/uc/impl/InMemoryUCDataStore.d.ts +3 -2
- package/dist/esm/uc/impl/InMemoryUCDataStore.js +17 -14
- package/dist/esm/uc/impl/KnexUCDataStore.d.ts +3 -2
- package/dist/esm/uc/impl/KnexUCDataStore.js +9 -5
- package/dist/esm/uc/impl/SimpleUCManager.d.ts +1 -1
- package/dist/esm/uc/impl/SimpleUCManager.js +2 -2
- package/dist/esm/uc/manager.d.ts +1 -1
- package/dist/esm/uc/settings/consts.js +1 -1
- package/dist/esm/utils/concerns/Initializable.d.ts +1 -0
- package/dist/esm/utils/ioc/bindCloudflareWorker.d.ts +2 -0
- package/dist/esm/utils/ioc/bindCloudflareWorker.js +15 -0
- package/package.json +12 -9
|
@@ -22,5 +22,6 @@ export declare class ServerBooter implements Configurable<S>, Worker<Input, Prom
|
|
|
22
22
|
constructor(emailManager: EmailManager, fsManager: FSManager, i18nManager: I18nManager, jobManager: JobManager, logger: Logger, productUCsLoader: ProductUCsLoader, serverManager: ServerManager, serverInstaller: ServerInstaller, settingsManager: SettingsManager<S>, ucManager: UCManager);
|
|
23
23
|
s(): S;
|
|
24
24
|
exec({ appsRootPath, autoMountUCs, srcImporter, }: Input): Promise<void>;
|
|
25
|
+
private mountUC;
|
|
25
26
|
}
|
|
26
27
|
export {};
|
|
@@ -12,7 +12,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from 'inversify';
|
|
14
14
|
import { ProductUCsLoader } from '../../../product/index.js';
|
|
15
|
-
import {
|
|
15
|
+
import { ucHTTPContract, } from '../../../uc/index.js';
|
|
16
|
+
import { shouldMountUC } from './funcs.js';
|
|
16
17
|
import { ServerInstaller } from './ServerInstaller.js';
|
|
17
18
|
let ServerBooter = class ServerBooter {
|
|
18
19
|
emailManager;
|
|
@@ -52,53 +53,49 @@ let ServerBooter = class ServerBooter {
|
|
|
52
53
|
await this.jobManager.init();
|
|
53
54
|
this.logger.info('Verifying email manager');
|
|
54
55
|
await this.emailManager.verify();
|
|
55
|
-
this.logger.info('
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const { lifecycle: { server }, sec, } = uc.def;
|
|
65
|
-
const contract = ucHTTPContract(uc);
|
|
66
|
-
const { mountingPoint } = contract;
|
|
67
|
-
if (typeof server !== 'object' ||
|
|
68
|
-
server.execMode === UCExecMode.AUTO) {
|
|
69
|
-
this.logger.debug(`Not mounting ${mountingPoint}`, {
|
|
70
|
-
reason: typeof server !== 'object'
|
|
71
|
-
? 'no ucd.lifecycle.server'
|
|
72
|
-
: 'execMode is AUTO',
|
|
73
|
-
});
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
this.logger.info(`Mounting ${mountingPoint}`, {
|
|
77
|
-
contract,
|
|
78
|
-
sec,
|
|
79
|
-
});
|
|
80
|
-
await this.ucManager.initServer(uc);
|
|
81
|
-
await this.serverManager.mount(uc.appManifest, uc.def, contract);
|
|
82
|
-
}
|
|
56
|
+
this.logger.info('Initializing server manager');
|
|
57
|
+
await this.serverManager.init();
|
|
58
|
+
if (autoMountUCs) {
|
|
59
|
+
const ucs = await this.productUCsLoader.exec({
|
|
60
|
+
appsRootPath,
|
|
61
|
+
srcImporter,
|
|
62
|
+
});
|
|
63
|
+
for await (const uc of ucs) {
|
|
64
|
+
await this.mountUC(uc);
|
|
83
65
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
this.logger.info('Mounting static dir', { staticDirPath });
|
|
90
|
-
await this.serverManager.mountStaticDir(staticDirPath);
|
|
91
|
-
}
|
|
92
|
-
const tmpDirPath = this.s().server_tmp_path;
|
|
93
|
-
if (!(await this.fsManager.exists(tmpDirPath))) {
|
|
94
|
-
await this.fsManager.mkdir(tmpDirPath);
|
|
66
|
+
}
|
|
67
|
+
const staticDirPath = this.s().server_static_dir_path;
|
|
68
|
+
if (staticDirPath) {
|
|
69
|
+
if (!(await this.fsManager.exists(staticDirPath))) {
|
|
70
|
+
throw new Error(`Static dir '${staticDirPath}' does not exist`);
|
|
95
71
|
}
|
|
96
|
-
|
|
97
|
-
await this.serverManager.
|
|
72
|
+
this.logger.info('Mounting static dir', { staticDirPath });
|
|
73
|
+
await this.serverManager.mountStaticDir(staticDirPath);
|
|
98
74
|
}
|
|
99
|
-
|
|
100
|
-
|
|
75
|
+
const tmpDirPath = this.s().server_tmp_path;
|
|
76
|
+
if (!(await this.fsManager.exists(tmpDirPath))) {
|
|
77
|
+
await this.fsManager.mkdir(tmpDirPath);
|
|
78
|
+
}
|
|
79
|
+
await this.serverManager.warmUp();
|
|
80
|
+
await this.serverManager.start();
|
|
81
|
+
}
|
|
82
|
+
async mountUC(uc) {
|
|
83
|
+
const { sec } = uc.def;
|
|
84
|
+
const contract = ucHTTPContract(uc);
|
|
85
|
+
const { mountingPoint } = contract;
|
|
86
|
+
const shouldNotMountReason = shouldMountUC(uc.def);
|
|
87
|
+
if (shouldNotMountReason) {
|
|
88
|
+
this.logger.debug(`Not mounting ${mountingPoint}`, {
|
|
89
|
+
reason: shouldNotMountReason,
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
101
92
|
}
|
|
93
|
+
this.logger.info(`Mounting ${mountingPoint}`, {
|
|
94
|
+
contract,
|
|
95
|
+
sec,
|
|
96
|
+
});
|
|
97
|
+
await this.ucManager.initServer(uc);
|
|
98
|
+
await this.serverManager.mount(uc.appManifest, uc.def, contract);
|
|
102
99
|
}
|
|
103
100
|
};
|
|
104
101
|
ServerBooter = __decorate([
|
|
@@ -38,6 +38,13 @@ export interface ServerManager extends Initializable {
|
|
|
38
38
|
* @param contract
|
|
39
39
|
*/
|
|
40
40
|
mount<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Mount the use case as an endpoint
|
|
43
|
+
* @param appManifest
|
|
44
|
+
* @param ucd
|
|
45
|
+
* @param contract
|
|
46
|
+
*/
|
|
47
|
+
mountSync<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): void;
|
|
41
48
|
/**
|
|
42
49
|
* Mount the static directory at `/`
|
|
43
50
|
* @param dirPath
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AppUCsLoaderOutput } from '../../../app/index.js';
|
|
2
|
+
import type { I18nManager, JobManager, Logger, Worker } from '../../../std/index.js';
|
|
3
|
+
import type { ServerManager } from './ServerManager.js';
|
|
4
|
+
type Input = {
|
|
5
|
+
autoMountUCs?: boolean;
|
|
6
|
+
ucs: AppUCsLoaderOutput;
|
|
7
|
+
};
|
|
8
|
+
export declare class SyncEdgeWorkerInitializer implements Worker<Input, void> {
|
|
9
|
+
private i18nManager;
|
|
10
|
+
private jobManager;
|
|
11
|
+
private logger;
|
|
12
|
+
private serverManager;
|
|
13
|
+
constructor(i18nManager: I18nManager, jobManager: JobManager, logger: Logger, serverManager: ServerManager);
|
|
14
|
+
exec({ autoMountUCs, ucs }: Input): void;
|
|
15
|
+
private mountUC;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject, injectable } from 'inversify';
|
|
14
|
+
import { ucHTTPContract, } from '../../../uc/index.js';
|
|
15
|
+
import { shouldMountUC } from './funcs.js';
|
|
16
|
+
let SyncEdgeWorkerInitializer = class SyncEdgeWorkerInitializer {
|
|
17
|
+
i18nManager;
|
|
18
|
+
jobManager;
|
|
19
|
+
logger;
|
|
20
|
+
serverManager;
|
|
21
|
+
constructor(i18nManager, jobManager, logger, serverManager) {
|
|
22
|
+
this.i18nManager = i18nManager;
|
|
23
|
+
this.jobManager = jobManager;
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
this.serverManager = serverManager;
|
|
26
|
+
}
|
|
27
|
+
exec({ autoMountUCs = true, ucs }) {
|
|
28
|
+
this.logger.info('Initializing i18n manager');
|
|
29
|
+
this.i18nManager.initSync();
|
|
30
|
+
// Not available as a sync method yet
|
|
31
|
+
// this.logger.info('Installing');
|
|
32
|
+
// await this.serverInstaller.exec();
|
|
33
|
+
this.logger.info('Initializing job manager');
|
|
34
|
+
this.jobManager.initSync();
|
|
35
|
+
// Not available as a sync method yet
|
|
36
|
+
// this.logger.info('Verifying email manager');
|
|
37
|
+
// await this.emailManager.verify();
|
|
38
|
+
this.logger.info('Initializing server manager');
|
|
39
|
+
this.serverManager.initSync();
|
|
40
|
+
if (autoMountUCs) {
|
|
41
|
+
for (const uc of ucs) {
|
|
42
|
+
this.mountUC(uc);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
mountUC(uc) {
|
|
47
|
+
const { lifecycle, sec } = uc.def;
|
|
48
|
+
const contract = ucHTTPContract(uc);
|
|
49
|
+
const { mountingPoint } = contract;
|
|
50
|
+
const shouldNotMountReason = shouldMountUC(uc.def);
|
|
51
|
+
if (shouldNotMountReason) {
|
|
52
|
+
this.logger.debug(`Not mounting ${mountingPoint}`, {
|
|
53
|
+
reason: shouldNotMountReason,
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.logger.info(`Mounting ${mountingPoint}`, {
|
|
58
|
+
contract,
|
|
59
|
+
sec,
|
|
60
|
+
});
|
|
61
|
+
if (typeof lifecycle.server === 'object' && lifecycle.server?.init) {
|
|
62
|
+
throw new Error('lifecycle.server.init is not available in SyncEdgeWorkerInitializer yet');
|
|
63
|
+
// await this.ucManager.initServer(uc);
|
|
64
|
+
}
|
|
65
|
+
this.serverManager.mountSync(uc.appManifest, uc.def, contract);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
SyncEdgeWorkerInitializer = __decorate([
|
|
69
|
+
injectable(),
|
|
70
|
+
__param(0, inject('I18nManager')),
|
|
71
|
+
__param(1, inject('JobManager')),
|
|
72
|
+
__param(2, inject('Logger')),
|
|
73
|
+
__param(3, inject('ServerManager')),
|
|
74
|
+
__metadata("design:paramtypes", [Object, Object, Object, Object])
|
|
75
|
+
], SyncEdgeWorkerInitializer);
|
|
76
|
+
export { SyncEdgeWorkerInitializer };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type UCDef, type UCInput, type UCOPIBase } from '../../../uc/index.js';
|
|
2
|
+
export type ShouldNotMountReason = string;
|
|
3
|
+
export declare function shouldMountUC<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(ucd: UCDef<I, OPI0, OPI1>): ShouldNotMountReason | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UCExecMode, } from '../../../uc/index.js';
|
|
2
|
+
export function shouldMountUC(ucd) {
|
|
3
|
+
const { lifecycle: { server }, } = ucd;
|
|
4
|
+
if (typeof server !== 'object') {
|
|
5
|
+
return 'no ucd.lifecycle.server';
|
|
6
|
+
}
|
|
7
|
+
if (server.execMode === UCExecMode.AUTO) {
|
|
8
|
+
return 'execMode is AUTO';
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import type { Worker } from '../../../std/index.js';
|
|
3
|
+
import { CSPDirectivesBuilder } from '../server/CSPDirectivesBuilder.js';
|
|
4
|
+
interface Input {
|
|
5
|
+
}
|
|
6
|
+
type Output = RequestHandler;
|
|
7
|
+
export declare class HelmetMiddlewareBuilder implements Worker<Input, Output> {
|
|
8
|
+
private cspDirectivesBuilder;
|
|
9
|
+
constructor(cspDirectivesBuilder: CSPDirectivesBuilder);
|
|
10
|
+
exec(_input: Input): Output;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import helmet from 'helmet';
|
|
14
|
+
import { inject, injectable } from 'inversify';
|
|
15
|
+
import { CSPDirectivesBuilder, } from '../server/CSPDirectivesBuilder.js';
|
|
16
|
+
let HelmetMiddlewareBuilder = class HelmetMiddlewareBuilder {
|
|
17
|
+
cspDirectivesBuilder;
|
|
18
|
+
constructor(cspDirectivesBuilder) {
|
|
19
|
+
this.cspDirectivesBuilder = cspDirectivesBuilder;
|
|
20
|
+
}
|
|
21
|
+
exec(_input) {
|
|
22
|
+
const defaultDirectives = helmet.contentSecurityPolicy.getDefaultDirectives();
|
|
23
|
+
const { directives } = this.cspDirectivesBuilder.exec({
|
|
24
|
+
defaultDirectives,
|
|
25
|
+
});
|
|
26
|
+
return helmet({
|
|
27
|
+
contentSecurityPolicy: {
|
|
28
|
+
directives,
|
|
29
|
+
useDefaults: false,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
HelmetMiddlewareBuilder = __decorate([
|
|
35
|
+
injectable(),
|
|
36
|
+
__param(0, inject(CSPDirectivesBuilder)),
|
|
37
|
+
__metadata("design:paramtypes", [CSPDirectivesBuilder])
|
|
38
|
+
], HelmetMiddlewareBuilder);
|
|
39
|
+
export { HelmetMiddlewareBuilder };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Express, type Request, type RequestHandler, type Response } from 'express';
|
|
2
|
+
import fileUpload from 'express-fileupload';
|
|
3
|
+
import type { AppManifest } from '../../../app/index.js';
|
|
4
|
+
import type { File } from '../../../dt/index.js';
|
|
5
|
+
import type { LoggerLevel } from '../../../std/index.js';
|
|
6
|
+
import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
|
|
7
|
+
import type { ServerManagerSettings } from '../server/ServerManager.js';
|
|
8
|
+
import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
|
|
9
|
+
import type { HelmetMiddlewareBuilder } from './HelmetMiddlewareBuilder.js';
|
|
10
|
+
export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager): RequestHandler;
|
|
11
|
+
export declare function init(helmetMB: HelmetMiddlewareBuilder, loggerLevel: LoggerLevel, serverTmpPath: ServerManagerSettings['server_tmp_path']): Express;
|
|
12
|
+
export declare function mountHandler(contract: UCHTTPContract, express: Express, handler: RequestHandler): void;
|
|
13
|
+
export declare function toFile(f: fileUpload.UploadedFile): File;
|
|
14
|
+
export declare function toReq(req: Request): ServerRequestHandlerReq;
|
|
15
|
+
export declare function toRes(res: Response): ServerRequestHandlerRes;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import cookieParser from 'cookie-parser';
|
|
2
|
+
import express, {} from 'express';
|
|
3
|
+
import fileUpload from 'express-fileupload';
|
|
4
|
+
export function buildHandler(appManifest, ucd, contract, serverRequestHandler, ucManager) {
|
|
5
|
+
const { envelope } = contract;
|
|
6
|
+
const handler = async (req, res) => {
|
|
7
|
+
const { body, status } = await serverRequestHandler.exec({
|
|
8
|
+
appManifest,
|
|
9
|
+
envelope,
|
|
10
|
+
req: toReq(req),
|
|
11
|
+
res: toRes(res),
|
|
12
|
+
ucd,
|
|
13
|
+
ucManager,
|
|
14
|
+
});
|
|
15
|
+
if (!body) {
|
|
16
|
+
res.status(status).send();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
res.status(status).send(body);
|
|
20
|
+
};
|
|
21
|
+
return handler;
|
|
22
|
+
}
|
|
23
|
+
export function init(helmetMB, loggerLevel, serverTmpPath) {
|
|
24
|
+
const app = express();
|
|
25
|
+
app.use(helmetMB.exec({}));
|
|
26
|
+
app.use(fileUpload({
|
|
27
|
+
createParentPath: true,
|
|
28
|
+
debug: loggerLevel === 'trace',
|
|
29
|
+
tempFileDir: serverTmpPath,
|
|
30
|
+
useTempFiles: true,
|
|
31
|
+
}));
|
|
32
|
+
app.use(express.json());
|
|
33
|
+
app.use(express.urlencoded({ extended: true }));
|
|
34
|
+
app.use(cookieParser());
|
|
35
|
+
return app;
|
|
36
|
+
}
|
|
37
|
+
export function mountHandler(contract, express, handler) {
|
|
38
|
+
const { method, path, pathAliases } = contract;
|
|
39
|
+
const httpMethod = method.toLowerCase();
|
|
40
|
+
express[httpMethod](path, handler);
|
|
41
|
+
for (const pathAlias of pathAliases) {
|
|
42
|
+
express[httpMethod](pathAlias, handler);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function toFile(f) {
|
|
46
|
+
return {
|
|
47
|
+
name: f.name,
|
|
48
|
+
path: f.tempFilePath,
|
|
49
|
+
type: f.mimetype,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function toReq(req) {
|
|
53
|
+
return {
|
|
54
|
+
bodyFromFormData: async () => {
|
|
55
|
+
// Since express v5, if the request contains only a file, `req.body` is `undefined`, hence the fallback on `{}`
|
|
56
|
+
const input = req.body ?? {};
|
|
57
|
+
// files is present when using express-fileupload
|
|
58
|
+
if ('files' in req && req.files) {
|
|
59
|
+
for (const [field, value] of Object.entries(req.files)) {
|
|
60
|
+
input[field] = Array.isArray(value)
|
|
61
|
+
? value.map(toFile)
|
|
62
|
+
: toFile(value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const [k, v] of Object.entries(input)) {
|
|
66
|
+
const isMultiple = k.endsWith('[]'); // e.g. 'tags[]': 'Electronic'
|
|
67
|
+
const key = isMultiple ? k.replaceAll('[]', '') : k;
|
|
68
|
+
if (isMultiple) {
|
|
69
|
+
input[key] = Array.isArray(v) ? v : [v];
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
input[key] = v;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return input;
|
|
76
|
+
},
|
|
77
|
+
bodyFromJSON: async () => req.body,
|
|
78
|
+
bodyFromQueryParams: async () => req.query,
|
|
79
|
+
bodyRaw: req.body,
|
|
80
|
+
cookie: (name) => req.cookies[name],
|
|
81
|
+
header: async (name) => {
|
|
82
|
+
const h = req.headers[name.toLowerCase()];
|
|
83
|
+
if (Array.isArray(h)) {
|
|
84
|
+
return h[0];
|
|
85
|
+
}
|
|
86
|
+
return h;
|
|
87
|
+
},
|
|
88
|
+
method: req.method,
|
|
89
|
+
secure: req.secure,
|
|
90
|
+
url: req.url,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function toRes(res) {
|
|
94
|
+
return {
|
|
95
|
+
clearCookie: async (name) => {
|
|
96
|
+
res.clearCookie(name);
|
|
97
|
+
},
|
|
98
|
+
redirect: async (location) => res.redirect(location),
|
|
99
|
+
setCookie: async ({ name, opts, val }) => {
|
|
100
|
+
res.cookie(name, val, opts);
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Context, type Handler, Hono } from 'hono';
|
|
2
|
+
import type { BlankEnv, Env } from 'hono/types';
|
|
3
|
+
import type { AppManifest } from '../../../app/index.js';
|
|
4
|
+
import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
|
|
5
|
+
import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
|
|
6
|
+
export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager, beforeExec?: (c: Context) => Promise<void>): Handler;
|
|
7
|
+
export declare function init<E extends Env = BlankEnv>(): Hono<E>;
|
|
8
|
+
export declare function mountHandler(contract: UCHTTPContract, hono: Hono, handler: Handler): void;
|
|
9
|
+
export declare function toReq(c: Context): ServerRequestHandlerReq;
|
|
10
|
+
export declare function toRes(c: Context): ServerRequestHandlerRes;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { deleteCookie, getCookie, setCookie } from 'hono/cookie';
|
|
3
|
+
import { logger } from 'hono/logger';
|
|
4
|
+
import { secureHeaders } from 'hono/secure-headers';
|
|
5
|
+
import { NotFoundError } from '../../../error/index.js';
|
|
6
|
+
import { fromFormData } from '../../../utils/index.js';
|
|
7
|
+
export function buildHandler(appManifest, ucd, contract, serverRequestHandler, ucManager, beforeExec) {
|
|
8
|
+
const { envelope } = contract;
|
|
9
|
+
const handler = async (c) => {
|
|
10
|
+
await beforeExec?.(c);
|
|
11
|
+
const { body, status } = await serverRequestHandler.exec({
|
|
12
|
+
appManifest,
|
|
13
|
+
envelope,
|
|
14
|
+
req: toReq(c),
|
|
15
|
+
res: toRes(c),
|
|
16
|
+
ucd,
|
|
17
|
+
ucManager,
|
|
18
|
+
});
|
|
19
|
+
if (!body) {
|
|
20
|
+
return c.newResponse(null, status);
|
|
21
|
+
}
|
|
22
|
+
return c.json(body, status);
|
|
23
|
+
};
|
|
24
|
+
return handler;
|
|
25
|
+
}
|
|
26
|
+
export function init() {
|
|
27
|
+
const app = new Hono();
|
|
28
|
+
app.use(secureHeaders());
|
|
29
|
+
app.use(logger());
|
|
30
|
+
app.notFound((c) => {
|
|
31
|
+
const err = new NotFoundError();
|
|
32
|
+
return c.json(err.toObj(), err.httpStatus);
|
|
33
|
+
});
|
|
34
|
+
return app;
|
|
35
|
+
}
|
|
36
|
+
export function mountHandler(contract, hono, handler) {
|
|
37
|
+
const { method, path, pathAliases } = contract;
|
|
38
|
+
const httpMethod = method.toLowerCase();
|
|
39
|
+
if (httpMethod === 'connect' ||
|
|
40
|
+
httpMethod === 'head' ||
|
|
41
|
+
httpMethod === 'trace') {
|
|
42
|
+
throw new Error(`Unsupported HTTP method : ${httpMethod}`);
|
|
43
|
+
}
|
|
44
|
+
hono[httpMethod](path, handler);
|
|
45
|
+
for (const pathAlias of pathAliases) {
|
|
46
|
+
hono[httpMethod](pathAlias, handler);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function toReq(c) {
|
|
50
|
+
return {
|
|
51
|
+
bodyFromFormData: async () => fromFormData(await c.req.formData()),
|
|
52
|
+
bodyFromJSON: () => c.req.json(),
|
|
53
|
+
bodyFromQueryParams: async () => c.req.queries(),
|
|
54
|
+
bodyRaw: c.req.raw,
|
|
55
|
+
cookie: async (name) => getCookie(c, name),
|
|
56
|
+
header: async (name) => c.req.header(name),
|
|
57
|
+
method: c.req.method,
|
|
58
|
+
secure: c.req.url.startsWith('https://'),
|
|
59
|
+
url: c.req.url,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function toRes(c) {
|
|
63
|
+
return {
|
|
64
|
+
clearCookie: async (name) => {
|
|
65
|
+
deleteCookie(c, name);
|
|
66
|
+
},
|
|
67
|
+
redirect: async (location) => {
|
|
68
|
+
c.redirect(location);
|
|
69
|
+
},
|
|
70
|
+
setCookie: async ({ name, opts, val }) => setCookie(c, name, val, opts),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Logger, SettingsManager } from '../../../std/index.js';
|
|
2
|
+
import type { EntrypointsBuilder } from '../server/EntrypointsBuilder.js';
|
|
3
|
+
import type { ListenSettings, Server } from './types.js';
|
|
4
|
+
export declare function listen(server: Server, entrypointsBuilder: EntrypointsBuilder, logger: Logger, settingsManager: SettingsManager<ListenSettings>): void;
|
|
5
|
+
export declare function stop(server: Server): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function listen(server, entrypointsBuilder, logger, settingsManager) {
|
|
2
|
+
const host = settingsManager.get()('server_binding_host');
|
|
3
|
+
const port = settingsManager.get()('server_binding_port');
|
|
4
|
+
server.listen(port, host, () => {
|
|
5
|
+
logger.info(`Listening on ${entrypointsBuilder.exec().http}`);
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export async function stop(server) {
|
|
9
|
+
if (!server?.listening) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
// As stated in the docs of `close`, only awaiting `.close` is not enough to make sure all the connections are closed.
|
|
13
|
+
// Hence the wrapping in a promise, where the callback is called when the 'close' event is emitted.
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
if (!server) {
|
|
16
|
+
return resolve();
|
|
17
|
+
}
|
|
18
|
+
server.close((err) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
return reject(err);
|
|
21
|
+
}
|
|
22
|
+
resolve();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type http from 'node:http';
|
|
2
2
|
import type https from 'node:https';
|
|
3
|
+
import type { ServerManagerSettings } from '../server/ServerManager.js';
|
|
3
4
|
export type Server = http.Server | https.Server;
|
|
5
|
+
export type ListenSettings = Pick<ServerManagerSettings, 'server_binding_host' | 'server_binding_port'>;
|
|
@@ -5,7 +5,9 @@ import type { ServerManager } from '../lib/server/ServerManager.js';
|
|
|
5
5
|
export declare class NextJSServerManager implements ServerManager {
|
|
6
6
|
overrideUCManager(_ucManager: UCManager): void;
|
|
7
7
|
init(): Promise<void>;
|
|
8
|
+
initSync(): void;
|
|
8
9
|
mount<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(_appManifest: AppManifest, _ucd: UCDef<I, OPI0, OPI1>, _contract: UCHTTPContract): Promise<void>;
|
|
10
|
+
mountSync<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(_appManifest: AppManifest, _ucd: UCDef<I, OPI0, OPI1>, _contract: UCHTTPContract): void;
|
|
9
11
|
mountStaticDir(_dirPath: DirPath): Promise<void>;
|
|
10
12
|
start(): Promise<void>;
|
|
11
13
|
stop(): Promise<void>;
|
|
@@ -12,9 +12,15 @@ let NextJSServerManager = class NextJSServerManager {
|
|
|
12
12
|
async init() {
|
|
13
13
|
// Nothing to do
|
|
14
14
|
}
|
|
15
|
+
initSync() {
|
|
16
|
+
// Nothing to do
|
|
17
|
+
}
|
|
15
18
|
async mount(_appManifest, _ucd, _contract) {
|
|
16
19
|
// Nothing to do
|
|
17
20
|
}
|
|
21
|
+
mountSync(_appManifest, _ucd, _contract) {
|
|
22
|
+
// Nothing to do
|
|
23
|
+
}
|
|
18
24
|
async mountStaticDir(_dirPath) {
|
|
19
25
|
// Nothing to do
|
|
20
26
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { WordingManager } from '../../i18n/index.js';
|
|
2
2
|
import { ProductUCsLoader } from '../../product/index.js';
|
|
3
|
+
import type { I18nManager } from '../../std/index.js';
|
|
3
4
|
import type { CLIManager, Input, Output } from '../lib/cli/CLIManager.js';
|
|
4
5
|
import { CommandExecutor } from '../lib/cli/CommandExecutor.js';
|
|
5
6
|
export declare class NodeCoreCLIManager implements CLIManager {
|
|
6
7
|
private commandExecutor;
|
|
8
|
+
private i18nManager;
|
|
7
9
|
private productUCsLoader;
|
|
8
10
|
private wordingManager;
|
|
9
|
-
constructor(commandExecutor: CommandExecutor, productUCsLoader: ProductUCsLoader, wordingManager: WordingManager);
|
|
11
|
+
constructor(commandExecutor: CommandExecutor, i18nManager: I18nManager, productUCsLoader: ProductUCsLoader, wordingManager: WordingManager);
|
|
10
12
|
handleCommand({ appsRootPath, srcImporter, }: Input): Promise<Output>;
|
|
11
13
|
private parseArgsConfig;
|
|
12
14
|
}
|
|
@@ -21,14 +21,17 @@ import { print } from '../lib/cli/renderer.js';
|
|
|
21
21
|
import { showHelp } from './commands.js';
|
|
22
22
|
let NodeCoreCLIManager = class NodeCoreCLIManager {
|
|
23
23
|
commandExecutor;
|
|
24
|
+
i18nManager;
|
|
24
25
|
productUCsLoader;
|
|
25
26
|
wordingManager;
|
|
26
|
-
constructor(commandExecutor, productUCsLoader, wordingManager) {
|
|
27
|
+
constructor(commandExecutor, i18nManager, productUCsLoader, wordingManager) {
|
|
27
28
|
this.commandExecutor = commandExecutor;
|
|
29
|
+
this.i18nManager = i18nManager;
|
|
28
30
|
this.productUCsLoader = productUCsLoader;
|
|
29
31
|
this.wordingManager = wordingManager;
|
|
30
32
|
}
|
|
31
33
|
async handleCommand({ appsRootPath, srcImporter, }) {
|
|
34
|
+
await this.i18nManager.init();
|
|
32
35
|
const command = process.argv[2] ?? '';
|
|
33
36
|
const ucs = await this.productUCsLoader.exec({
|
|
34
37
|
appsRootPath,
|
|
@@ -84,10 +87,10 @@ let NodeCoreCLIManager = class NodeCoreCLIManager {
|
|
|
84
87
|
NodeCoreCLIManager = __decorate([
|
|
85
88
|
injectable(),
|
|
86
89
|
__param(0, inject(CommandExecutor)),
|
|
87
|
-
__param(1, inject(
|
|
88
|
-
__param(2, inject(
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
__param(1, inject('I18nManager')),
|
|
91
|
+
__param(2, inject(ProductUCsLoader)),
|
|
92
|
+
__param(3, inject(WordingManager)),
|
|
93
|
+
__metadata("design:paramtypes", [CommandExecutor, Object, ProductUCsLoader,
|
|
91
94
|
WordingManager])
|
|
92
95
|
], NodeCoreCLIManager);
|
|
93
96
|
export { NodeCoreCLIManager };
|
|
@@ -7,8 +7,9 @@ import { EntrypointsBuilder } from '../lib/server/EntrypointsBuilder.js';
|
|
|
7
7
|
import type { ServerManager, ServerManagerSettings } from '../lib/server/ServerManager.js';
|
|
8
8
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
9
9
|
import { ServerSSLCertLoader } from '../lib/server/ServerSSLCertLoader.js';
|
|
10
|
-
import { HelmetMiddlewareBuilder } from '
|
|
11
|
-
type
|
|
10
|
+
import { HelmetMiddlewareBuilder } from '../lib/server-express/HelmetMiddlewareBuilder.js';
|
|
11
|
+
import type { ListenSettings } from '../lib/server-node/types.js';
|
|
12
|
+
type S = ListenSettings & Pick<LoggerSettings, 'logger_level'> & Pick<ServerManagerSettings, 'server_tmp_path'>;
|
|
12
13
|
export declare class NodeExpressServerManager implements Configurable<S>, ServerManager {
|
|
13
14
|
private entrypointsBuilder;
|
|
14
15
|
protected environmentManager: EnvironmentManager;
|
|
@@ -25,14 +26,14 @@ export declare class NodeExpressServerManager implements Configurable<S>, Server
|
|
|
25
26
|
getRuntime(): Express;
|
|
26
27
|
overrideUCManager(ucManager: UCManager): void;
|
|
27
28
|
init(): Promise<void>;
|
|
29
|
+
initSync(): void;
|
|
28
30
|
mount<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): Promise<void>;
|
|
31
|
+
mountSync<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): void;
|
|
29
32
|
mountStaticDir(dirPath: DirPath): Promise<void>;
|
|
30
33
|
start(): Promise<void>;
|
|
31
34
|
stop(): Promise<void>;
|
|
32
35
|
warmUp(): Promise<void>;
|
|
33
36
|
private createServer;
|
|
34
|
-
private
|
|
35
|
-
private toReq;
|
|
36
|
-
private toRes;
|
|
37
|
+
private mountCommon;
|
|
37
38
|
}
|
|
38
39
|
export {};
|