@nodefony/http 10.0.0-alpha.1
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/LICENSE +544 -0
- package/README.md +77 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateParam.js +8 -0
- package/dist/index.js +108 -0
- package/dist/nodefony/command/assetsPublishCommand.js +102 -0
- package/dist/nodefony/command/certificatesCommand.js +47 -0
- package/dist/nodefony/command/networkCommand.js +27 -0
- package/dist/nodefony/command/proxyGenerateCommand.js +66 -0
- package/dist/nodefony/config/config.js +335 -0
- package/dist/nodefony/config/defineModuleConfig.js +93 -0
- package/dist/nodefony/interfaces/IContext.js +1 -0
- package/dist/nodefony/interfaces/ICookie.js +1 -0
- package/dist/nodefony/interfaces/IErrorRenderer.js +1 -0
- package/dist/nodefony/interfaces/IHttpConfig.js +1 -0
- package/dist/nodefony/interfaces/IHttpKernel.js +1 -0
- package/dist/nodefony/interfaces/IRequest.js +1 -0
- package/dist/nodefony/interfaces/IRequestLogger.js +1 -0
- package/dist/nodefony/interfaces/IResponse.js +1 -0
- package/dist/nodefony/interfaces/ISession.js +1 -0
- package/dist/nodefony/interfaces/IUpload.js +1 -0
- package/dist/nodefony/interfaces/index.js +1 -0
- package/dist/nodefony/service/HttpAdminApi.js +376 -0
- package/dist/nodefony/service/ProfilerAdminApi.js +73 -0
- package/dist/nodefony/service/audit-logger.js +159 -0
- package/dist/nodefony/service/certificates.js +545 -0
- package/dist/nodefony/service/error-renderer.js +320 -0
- package/dist/nodefony/service/http-kernel.js +948 -0
- package/dist/nodefony/service/pretty-request-logger.js +72 -0
- package/dist/nodefony/service/request-logger.js +54 -0
- package/dist/nodefony/service/servers/clientError.js +20 -0
- package/dist/nodefony/service/servers/server-http.js +135 -0
- package/dist/nodefony/service/servers/server-https.js +204 -0
- package/dist/nodefony/service/servers/server-static.js +192 -0
- package/dist/nodefony/service/servers/server-websocket-secure.js +104 -0
- package/dist/nodefony/service/servers/server-websocket.js +104 -0
- package/dist/nodefony/service/servers/serverShutdown.js +31 -0
- package/dist/nodefony/service/servers/wsHeartbeat.js +64 -0
- package/dist/nodefony/service/sessions/sessions-service.js +580 -0
- package/dist/nodefony/service/trace.js +72 -0
- package/dist/nodefony/service/upload/upload-service.js +171 -0
- package/dist/nodefony/src/assets/collectAssets.js +34 -0
- package/dist/nodefony/src/assets/prebuiltUi.js +125 -0
- package/dist/nodefony/src/context/Context.js +415 -0
- package/dist/nodefony/src/context/domainMatcher.js +88 -0
- package/dist/nodefony/src/context/forwarded.js +185 -0
- package/dist/nodefony/src/context/http/HttpContext.js +309 -0
- package/dist/nodefony/src/context/http/Request.js +543 -0
- package/dist/nodefony/src/context/http/Response.js +368 -0
- package/dist/nodefony/src/context/http/parser.js +188 -0
- package/dist/nodefony/src/context/http/urlFastPath.js +103 -0
- package/dist/nodefony/src/context/http2/Request.js +29 -0
- package/dist/nodefony/src/context/http2/Response.js +97 -0
- package/dist/nodefony/src/context/metaData.js +47 -0
- package/dist/nodefony/src/context/requestId.js +41 -0
- package/dist/nodefony/src/context/trustProxy.js +167 -0
- package/dist/nodefony/src/context/websocket/Response.js +181 -0
- package/dist/nodefony/src/context/websocket/WebsocketContext.js +389 -0
- package/dist/nodefony/src/context/websocket/wsBackpressure.js +56 -0
- package/dist/nodefony/src/context/websocket/wsLogContent.js +68 -0
- package/dist/nodefony/src/cookies/cookie.js +258 -0
- package/dist/nodefony/src/errors/httpError.js +69 -0
- package/dist/nodefony/src/profiler/FrameProfile.js +95 -0
- package/dist/nodefony/src/profiler/Profiler.js +139 -0
- package/dist/nodefony/src/proxy/generateProxyConfig.js +157 -0
- package/dist/nodefony/src/rateLimit/IRateLimitStore.js +1 -0
- package/dist/nodefony/src/rateLimit/MemoryRateLimitStore.js +146 -0
- package/dist/nodefony/src/rateLimit/WsConnectionCounter.js +64 -0
- package/dist/nodefony/src/rateLimit/rateLimitFilters.js +20 -0
- package/dist/nodefony/src/servers/portBinder.js +114 -0
- package/dist/nodefony/src/session/session.js +390 -0
- package/dist/nodefony/src/session/storage/MemorySessionStorage.js +185 -0
- package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +137 -0
- package/dist/nodefony/src/session/storage/sessionFilters.js +83 -0
- package/dist/nodefony/src/session/storage/sessionSort.js +53 -0
- package/dist/types/index.d.ts +83 -0
- package/dist/types/nodefony/command/assetsPublishCommand.d.ts +23 -0
- package/dist/types/nodefony/command/certificatesCommand.d.ts +17 -0
- package/dist/types/nodefony/command/networkCommand.d.ts +8 -0
- package/dist/types/nodefony/command/proxyGenerateCommand.d.ts +19 -0
- package/dist/types/nodefony/config/config.d.ts +197 -0
- package/dist/types/nodefony/config/defineModuleConfig.d.ts +39 -0
- package/dist/types/nodefony/interfaces/IContext.d.ts +138 -0
- package/dist/types/nodefony/interfaces/ICookie.d.ts +47 -0
- package/dist/types/nodefony/interfaces/IErrorRenderer.d.ts +55 -0
- package/dist/types/nodefony/interfaces/IHttpConfig.d.ts +12 -0
- package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -0
- package/dist/types/nodefony/interfaces/IRequest.d.ts +35 -0
- package/dist/types/nodefony/interfaces/IRequestLogger.d.ts +31 -0
- package/dist/types/nodefony/interfaces/IResponse.d.ts +39 -0
- package/dist/types/nodefony/interfaces/ISession.d.ts +283 -0
- package/dist/types/nodefony/interfaces/IUpload.d.ts +66 -0
- package/dist/types/nodefony/interfaces/index.d.ts +7 -0
- package/dist/types/nodefony/service/HttpAdminApi.d.ts +18 -0
- package/dist/types/nodefony/service/ProfilerAdminApi.d.ts +23 -0
- package/dist/types/nodefony/service/audit-logger.d.ts +143 -0
- package/dist/types/nodefony/service/certificates.d.ts +246 -0
- package/dist/types/nodefony/service/error-renderer.d.ts +74 -0
- package/dist/types/nodefony/service/http-kernel.d.ts +377 -0
- package/dist/types/nodefony/service/pretty-request-logger.d.ts +25 -0
- package/dist/types/nodefony/service/request-logger.d.ts +18 -0
- package/dist/types/nodefony/service/servers/clientError.d.ts +14 -0
- package/dist/types/nodefony/service/servers/server-http.d.ts +42 -0
- package/dist/types/nodefony/service/servers/server-https.d.ts +41 -0
- package/dist/types/nodefony/service/servers/server-static.d.ts +62 -0
- package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +29 -0
- package/dist/types/nodefony/service/servers/server-websocket.d.ts +29 -0
- package/dist/types/nodefony/service/servers/serverShutdown.d.ts +27 -0
- package/dist/types/nodefony/service/servers/wsHeartbeat.d.ts +46 -0
- package/dist/types/nodefony/service/sessions/sessions-service.d.ts +218 -0
- package/dist/types/nodefony/service/trace.d.ts +39 -0
- package/dist/types/nodefony/service/upload/upload-service.d.ts +61 -0
- package/dist/types/nodefony/src/assets/collectAssets.d.ts +35 -0
- package/dist/types/nodefony/src/assets/prebuiltUi.d.ts +99 -0
- package/dist/types/nodefony/src/context/Context.d.ts +195 -0
- package/dist/types/nodefony/src/context/domainMatcher.d.ts +67 -0
- package/dist/types/nodefony/src/context/forwarded.d.ts +95 -0
- package/dist/types/nodefony/src/context/http/HttpContext.d.ts +85 -0
- package/dist/types/nodefony/src/context/http/Request.d.ts +203 -0
- package/dist/types/nodefony/src/context/http/Response.d.ts +68 -0
- package/dist/types/nodefony/src/context/http/parser.d.ts +65 -0
- package/dist/types/nodefony/src/context/http/urlFastPath.d.ts +52 -0
- package/dist/types/nodefony/src/context/http2/Request.d.ts +14 -0
- package/dist/types/nodefony/src/context/http2/Response.d.ts +20 -0
- package/dist/types/nodefony/src/context/metaData.d.ts +58 -0
- package/dist/types/nodefony/src/context/requestId.d.ts +28 -0
- package/dist/types/nodefony/src/context/trustProxy.d.ts +77 -0
- package/dist/types/nodefony/src/context/websocket/Response.d.ts +53 -0
- package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +125 -0
- package/dist/types/nodefony/src/context/websocket/wsBackpressure.d.ts +73 -0
- package/dist/types/nodefony/src/context/websocket/wsLogContent.d.ts +37 -0
- package/dist/types/nodefony/src/cookies/cookie.d.ts +88 -0
- package/dist/types/nodefony/src/errors/httpError.d.ts +15 -0
- package/dist/types/nodefony/src/profiler/FrameProfile.d.ts +110 -0
- package/dist/types/nodefony/src/profiler/Profiler.d.ts +192 -0
- package/dist/types/nodefony/src/proxy/generateProxyConfig.d.ts +76 -0
- package/dist/types/nodefony/src/rateLimit/IRateLimitStore.d.ts +98 -0
- package/dist/types/nodefony/src/rateLimit/MemoryRateLimitStore.d.ts +40 -0
- package/dist/types/nodefony/src/rateLimit/WsConnectionCounter.d.ts +37 -0
- package/dist/types/nodefony/src/rateLimit/rateLimitFilters.d.ts +18 -0
- package/dist/types/nodefony/src/servers/portBinder.d.ts +102 -0
- package/dist/types/nodefony/src/session/session.d.ts +171 -0
- package/dist/types/nodefony/src/session/storage/MemorySessionStorage.d.ts +77 -0
- package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +81 -0
- package/dist/types/nodefony/src/session/storage/sessionFilters.d.ts +102 -0
- package/dist/types/nodefony/src/session/storage/sessionSort.d.ts +45 -0
- package/docs/cookies.md +365 -0
- package/docs/index.md +163 -0
- package/docs/observabilite.md +460 -0
- package/docs/rate-limit.md +372 -0
- package/docs/servers.md +935 -0
- package/docs/session.md +768 -0
- package/docs/upload.md +460 -0
- package/package.json +101 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import config, { httpConfigSchema } from "./nodefony/config/config.js";
|
|
2
|
+
import { defineHttpConfig, httpConfigJsonSchema } from "./nodefony/config/defineModuleConfig.js";
|
|
3
|
+
import { createHttpAdminApi } from "./nodefony/service/HttpAdminApi.js";
|
|
4
|
+
import { createProfilerAdminApi } from "./nodefony/service/ProfilerAdminApi.js";
|
|
5
|
+
import { Profiler } from "./nodefony/src/profiler/Profiler.js";
|
|
6
|
+
import HttpError from "./nodefony/src/errors/httpError.js";
|
|
7
|
+
import { MemoryRateLimitStore } from "./nodefony/src/rateLimit/MemoryRateLimitStore.js";
|
|
8
|
+
import { compileDomainPattern, compileDomainPatterns, compileTrustedHosts, isDomainAllowed } from "./nodefony/src/context/domainMatcher.js";
|
|
9
|
+
import Cookie from "./nodefony/src/cookies/cookie.js";
|
|
10
|
+
import Context from "./nodefony/src/context/Context.js";
|
|
11
|
+
import { decideSend, readBackpressureOptions } from "./nodefony/src/context/websocket/wsBackpressure.js";
|
|
12
|
+
import WebsocketResponse from "./nodefony/src/context/websocket/Response.js";
|
|
13
|
+
import { FrameProfile } from "./nodefony/src/profiler/FrameProfile.js";
|
|
14
|
+
import WebsocketContext from "./nodefony/src/context/websocket/WebsocketContext.js";
|
|
15
|
+
import HttpRequest from "./nodefony/src/context/http/Request.js";
|
|
16
|
+
import HttpResponse from "./nodefony/src/context/http/Response.js";
|
|
17
|
+
import Http2Request from "./nodefony/src/context/http2/Request.js";
|
|
18
|
+
import Http2Response from "./nodefony/src/context/http2/Response.js";
|
|
19
|
+
import HttpContext from "./nodefony/src/context/http/HttpContext.js";
|
|
20
|
+
import DefaultErrorRenderer, { schemaMismatchOf } from "./nodefony/service/error-renderer.js";
|
|
21
|
+
import DefaultRequestLogger from "./nodefony/service/request-logger.js";
|
|
22
|
+
import JsonAuditLogger from "./nodefony/service/audit-logger.js";
|
|
23
|
+
import PrettyRequestLogger from "./nodefony/service/pretty-request-logger.js";
|
|
24
|
+
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js";
|
|
25
|
+
import __decorate from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js";
|
|
26
|
+
import http_kernel_default from "./nodefony/service/http-kernel.js";
|
|
27
|
+
import server_http_default from "./nodefony/service/servers/server-http.js";
|
|
28
|
+
import server_https_default from "./nodefony/service/servers/server-https.js";
|
|
29
|
+
import server_websocket_default from "./nodefony/service/servers/server-websocket.js";
|
|
30
|
+
import server_websocket_secure_default from "./nodefony/service/servers/server-websocket-secure.js";
|
|
31
|
+
import Statics from "./nodefony/service/servers/server-static.js";
|
|
32
|
+
import Network from "./nodefony/command/networkCommand.js";
|
|
33
|
+
import Certificates from "./nodefony/command/certificatesCommand.js";
|
|
34
|
+
import ProxyGenerate from "./nodefony/command/proxyGenerateCommand.js";
|
|
35
|
+
import AssetsPublish from "./nodefony/command/assetsPublishCommand.js";
|
|
36
|
+
import Session from "./nodefony/src/session/session.js";
|
|
37
|
+
import { SESSION_COLUMN_ALIASES, SESSION_DEFAULT_ORDER, SESSION_DEFAULT_ORDER_SQL, SESSION_SORTABLE_FIELDS } from "./nodefony/src/session/storage/sessionSort.js";
|
|
38
|
+
import sessions_service_default from "./nodefony/service/sessions/sessions-service.js";
|
|
39
|
+
import Certificate from "./nodefony/service/certificates.js";
|
|
40
|
+
import upload_service_default from "./nodefony/service/upload/upload-service.js";
|
|
41
|
+
import { PrebuiltUi, resolveUiDelivery } from "./nodefony/src/assets/prebuiltUi.js";
|
|
42
|
+
import { Kernel, Module, services } from "nodefony";
|
|
43
|
+
//#region index.ts
|
|
44
|
+
let Http = class Http extends Module {
|
|
45
|
+
constructor(kernel) {
|
|
46
|
+
super("http", kernel, import.meta.url, config);
|
|
47
|
+
this.addCommand(Network);
|
|
48
|
+
this.addCommand(Certificates);
|
|
49
|
+
this.addCommand(ProxyGenerate);
|
|
50
|
+
this.addCommand(AssetsPublish);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Expose le JSON Schema de la config http (dérivé du schéma Zod, flags `meta()`
|
|
54
|
+
* inclus) au data plane admin → Studio rend la config en réglages documentés
|
|
55
|
+
* (type, défaut, état, valeur effective) au lieu d'un dump brut. Override du
|
|
56
|
+
* seam {@link Module.configSchema}.
|
|
57
|
+
*/
|
|
58
|
+
configSchema() {
|
|
59
|
+
return httpConfigJsonSchema();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Phase `onRegister` : valide la config (défauts + override `module-http` +
|
|
63
|
+
* défauts kernel) via `defineHttpConfig`, puis la ré-assigne à `this.options`
|
|
64
|
+
* AVANT l'instanciation des `@services` (phase `onBoot`). Plante propre avec
|
|
65
|
+
* messages clairs si la config est invalide (convention Zod figée 2026-05-28).
|
|
66
|
+
*
|
|
67
|
+
* Config NON gelée : les services mutent `module.options` (upload `uploadDir`,
|
|
68
|
+
* certificats `serialNumber`) — cf `defineHttpConfig`.
|
|
69
|
+
*/
|
|
70
|
+
async onKernelRegister() {
|
|
71
|
+
this.options = defineHttpConfig(this.options ?? {}, this.kernel);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Phase `onBoot` : s'enregistre comme producteur admin (`/nodefony/http/api/*`)
|
|
76
|
+
* auprès du broker, AVANT que framework ne monte le data plane à `onReady`.
|
|
77
|
+
*
|
|
78
|
+
* Importe seulement `IAdminRegistry` (core) — jamais `@nodefony/framework`
|
|
79
|
+
* (dépendance circulaire). Le broker est résolu du container partagé.
|
|
80
|
+
*/
|
|
81
|
+
async onKernelBoot() {
|
|
82
|
+
const registry = this.kernel?.container?.get("adminBroker");
|
|
83
|
+
if (registry && !registry.has("http")) registry.register(createHttpAdminApi(this));
|
|
84
|
+
if (this.kernel?.environment !== "production") {
|
|
85
|
+
const profiler = new Profiler();
|
|
86
|
+
this.container?.set("profiler", profiler);
|
|
87
|
+
if (registry && !registry.has("profiler")) registry.register(createProfilerAdminApi(profiler));
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
async onKernelReady() {
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
Http = __decorate([services([
|
|
96
|
+
http_kernel_default,
|
|
97
|
+
Certificate,
|
|
98
|
+
sessions_service_default,
|
|
99
|
+
Statics,
|
|
100
|
+
server_http_default,
|
|
101
|
+
server_https_default,
|
|
102
|
+
server_websocket_default,
|
|
103
|
+
server_websocket_secure_default,
|
|
104
|
+
upload_service_default
|
|
105
|
+
]), __decorateMetadata("design:paramtypes", [typeof Kernel === "undefined" ? Object : Kernel])], Http);
|
|
106
|
+
var http_default = Http;
|
|
107
|
+
//#endregion
|
|
108
|
+
export { Context, Cookie, DefaultErrorRenderer, DefaultRequestLogger, FrameProfile, Http2Request, Http2Response, HttpContext, HttpError, http_kernel_default as HttpKernel, HttpRequest, HttpResponse, HttpResponse as Response, JsonAuditLogger, MemoryRateLimitStore, PrebuiltUi, PrettyRequestLogger, Profiler, SESSION_COLUMN_ALIASES, SESSION_DEFAULT_ORDER, SESSION_DEFAULT_ORDER_SQL, SESSION_SORTABLE_FIELDS, Session, sessions_service_default as SessionsService, WebsocketContext, WebsocketResponse, WebsocketResponse as wsResponse, compileDomainPattern, compileDomainPatterns, compileTrustedHosts, decideSend, http_default as default, defineHttpConfig, httpConfigJsonSchema, httpConfigSchema, isDomainAllowed, readBackpressureOptions, resolveUiDelivery, schemaMismatchOf };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { planAssetPublish } from "../src/assets/collectAssets.js";
|
|
2
|
+
import { Command } from "nodefony";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import fsp from "node:fs/promises";
|
|
5
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
//#region nodefony/command/assetsPublishCommand.ts
|
|
7
|
+
const options = {
|
|
8
|
+
helpGroup: "FRONT ET RÉSEAU",
|
|
9
|
+
showBanner: false,
|
|
10
|
+
kernelEvent: "onReady"
|
|
11
|
+
};
|
|
12
|
+
/** Compte récursivement les fichiers d'un dossier (borné par le FS). */
|
|
13
|
+
async function countFiles(dir) {
|
|
14
|
+
let n = 0;
|
|
15
|
+
let entries;
|
|
16
|
+
try {
|
|
17
|
+
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
18
|
+
} catch {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
for (const e of entries) if (e.isDirectory()) n += await countFiles(join(dir, e.name));
|
|
22
|
+
else n += 1;
|
|
23
|
+
return n;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Commande CLI `assets:publish` — assemble TOUS les assets statiques servables
|
|
27
|
+
* (publics de module montés sous `/<module>/` + bundles `@nodefony/frontend`
|
|
28
|
+
* sous `/_assets/<name>/`) dans UN arbre `dist-assets/` miroir des préfixes
|
|
29
|
+
* d'URL, plus un `manifest.json`.
|
|
30
|
+
*
|
|
31
|
+
* Provider-agnostic — Nodefony ASSEMBLE, l'orchestrateur PUBLIE (cloud-native) :
|
|
32
|
+
* `aws s3 sync dist-assets s3://bucket`, `rsync`, upload CI… Pas de dépendance
|
|
33
|
+
* cloud embarquée dans le framework. Combine avec `frontend.assetBaseUrl` pour
|
|
34
|
+
* que les URLs émises pointent le CDN qui sert cet arbre.
|
|
35
|
+
*/
|
|
36
|
+
var AssetsPublish = class extends Command {
|
|
37
|
+
constructor(cli) {
|
|
38
|
+
super("assets:publish", "rassemble les fichiers statiques pour un CDN", cli, options);
|
|
39
|
+
this.addOption("-o, --out <dir>", "output directory (default ./dist-assets)");
|
|
40
|
+
this.addOption("--clean", "remove the output directory first");
|
|
41
|
+
this.addOption("--json", "print a machine-readable summary");
|
|
42
|
+
}
|
|
43
|
+
async generate(opts) {
|
|
44
|
+
const outDir = opts.out ? isAbsolute(opts.out) ? opts.out : resolve(process.cwd(), opts.out) : join(process.cwd(), "dist-assets");
|
|
45
|
+
const sources = this.collectSources();
|
|
46
|
+
if (sources.length === 0) {
|
|
47
|
+
this.log("Aucune source d'assets (0 mount natif, 0 bundle frontend) — rien à publier.", "WARNING");
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
if (opts.clean && existsSync(outDir)) await fsp.rm(outDir, {
|
|
51
|
+
recursive: true,
|
|
52
|
+
force: true
|
|
53
|
+
});
|
|
54
|
+
const plan = planAssetPublish(sources, outDir);
|
|
55
|
+
const manifest = {
|
|
56
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57
|
+
outDir,
|
|
58
|
+
sources: []
|
|
59
|
+
};
|
|
60
|
+
for (const p of plan) {
|
|
61
|
+
if (!existsSync(p.dir)) {
|
|
62
|
+
this.log(`Source absente, ignorée : ${p.prefix} → ${p.dir} (build manquant ?)`, "WARNING");
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
await fsp.mkdir(p.target, { recursive: true });
|
|
66
|
+
await fsp.cp(p.dir, p.target, { recursive: true });
|
|
67
|
+
const files = await countFiles(p.target);
|
|
68
|
+
manifest.sources.push({
|
|
69
|
+
prefix: p.prefix,
|
|
70
|
+
dir: p.dir,
|
|
71
|
+
files
|
|
72
|
+
});
|
|
73
|
+
this.log(`publish ${p.prefix} → ${p.target} (${files} fichiers)`, "INFO");
|
|
74
|
+
}
|
|
75
|
+
await fsp.writeFile(join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
76
|
+
if (opts.json) process.stdout.write(JSON.stringify(manifest, null, 2) + "\n");
|
|
77
|
+
else {
|
|
78
|
+
const total = manifest.sources.reduce((s, x) => s + x.files, 0);
|
|
79
|
+
this.log(`${manifest.sources.length} source(s), ${total} fichiers → ${outDir}. Déployez avec votre outil (ex. \`aws s3 sync ${outDir} s3://bucket\`).`, "INFO");
|
|
80
|
+
}
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
/** Sources = mounts natifs (`server-static`) + bundles `@nodefony/frontend`. */
|
|
84
|
+
collectSources() {
|
|
85
|
+
const modules = this.kernel?.getModules?.() ?? {};
|
|
86
|
+
const sources = [];
|
|
87
|
+
const staticSvc = modules["http"]?.get("server-static");
|
|
88
|
+
staticSvc?.mountModulePublics?.();
|
|
89
|
+
for (const m of staticSvc?.mounts ?? []) sources.push({
|
|
90
|
+
prefix: m.prefix,
|
|
91
|
+
dir: m.dir
|
|
92
|
+
});
|
|
93
|
+
const frontendSvc = modules["frontend"]?.get("frontend");
|
|
94
|
+
for (const e of frontendSvc?.listEntries?.() ?? []) sources.push({
|
|
95
|
+
prefix: e.publicPath,
|
|
96
|
+
dir: e.outDir
|
|
97
|
+
});
|
|
98
|
+
return sources;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
//#endregion
|
|
102
|
+
export { AssetsPublish as default };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Command } from "nodefony";
|
|
2
|
+
import { inspect } from "node:util";
|
|
3
|
+
//#region nodefony/command/certificatesCommand.ts
|
|
4
|
+
const options = {
|
|
5
|
+
helpGroup: "FRONT ET RÉSEAU",
|
|
6
|
+
showBanner: false,
|
|
7
|
+
kernelEvent: "onBoot"
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Commande CLI `certificates` — (re)génère et inspecte le certificat TLS de
|
|
11
|
+
* DÉVELOPPEMENT. La génération reste un confort de dev : en production, fournir
|
|
12
|
+
* un vrai certificat (`certificates.strategy: "explicit"`).
|
|
13
|
+
*
|
|
14
|
+
* Réutilise le service `certificates` du module `@nodefony/http` (source unique)
|
|
15
|
+
* → la commande, le boot auto et un futur endpoint Studio appellent le même code.
|
|
16
|
+
*/
|
|
17
|
+
var Certificates = class extends Command {
|
|
18
|
+
constructor(cli) {
|
|
19
|
+
super("http:certificates", "engendre ou inspecte le certificat TLS de dev", cli, options);
|
|
20
|
+
this.addOption("-f, --force", "regenerate even if a valid certificate already exists");
|
|
21
|
+
this.addOption("-j, --json", "output the certificate summary as JSON");
|
|
22
|
+
}
|
|
23
|
+
async generate(opts) {
|
|
24
|
+
const service = (this.kernel?.getModules()?.["http"])?.get("certificates") ?? null;
|
|
25
|
+
if (!service) {
|
|
26
|
+
this.log("Service 'certificates' introuvable (module @nodefony/http non chargé).", "ERROR");
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
await service.loadForge();
|
|
30
|
+
await service.generateServerCertificates(Boolean(opts.force));
|
|
31
|
+
const info = await service.describe();
|
|
32
|
+
if (opts.json) process.stdout.write(`${JSON.stringify(info, void 0, 2)}\n`);
|
|
33
|
+
else {
|
|
34
|
+
process.stdout.write(`${inspect(info, {
|
|
35
|
+
colors: process.stdout.isTTY,
|
|
36
|
+
depth: 4
|
|
37
|
+
})}\n`);
|
|
38
|
+
if (info.caPath) process.stdout.write(`
|
|
39
|
+
Requête vérifiée (NE PAS utiliser -k / rejectUnauthorized:false) :
|
|
40
|
+
curl --cacert ${info.caPath} https://localhost:5152/\n NODE_EXTRA_CA_CERTS=${info.caPath} node mon-script.mjs\n`);
|
|
41
|
+
else process.stdout.write("\nCA dans le trust store système (mkcert) → requête vérifiée sans flag :\n curl https://localhost:5152/\n");
|
|
42
|
+
}
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { Certificates as default };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from "nodefony";
|
|
2
|
+
import { inspect } from "node:util";
|
|
3
|
+
//#region nodefony/command/networkCommand.ts
|
|
4
|
+
const options = {
|
|
5
|
+
helpGroup: "FRONT ET RÉSEAU",
|
|
6
|
+
showBanner: false,
|
|
7
|
+
kernelEvent: "onRegister"
|
|
8
|
+
};
|
|
9
|
+
var Network = class extends Command {
|
|
10
|
+
constructor(cli) {
|
|
11
|
+
super("http:network", "les interfaces réseau et adresses de cette machine", cli, options);
|
|
12
|
+
this.addArgument("[interface]", "Selection interface example eth0 ");
|
|
13
|
+
this.addOption("-j, --json", "get json");
|
|
14
|
+
}
|
|
15
|
+
async generate(arg, opts) {
|
|
16
|
+
let network = this.kernel?.getNetwork();
|
|
17
|
+
let result = {};
|
|
18
|
+
if (arg) {
|
|
19
|
+
if (network?.interfaces[arg]) result = network?.interfaces[arg];
|
|
20
|
+
} else result = network?.interfaces;
|
|
21
|
+
if (opts.json) process.stdout.write(`${JSON.stringify(result, void 0, " ")}\n`);
|
|
22
|
+
else process.stdout.write(`${inspect(result, { colors: process.stdout.isTTY })}\n`);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Network as default };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defaultIntrospection, generateHaproxyConfig, generateNginxConfig } from "../src/proxy/generateProxyConfig.js";
|
|
2
|
+
import { Command } from "nodefony";
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
|
+
//#region nodefony/command/proxyGenerateCommand.ts
|
|
5
|
+
const options = {
|
|
6
|
+
helpGroup: "FRONT ET RÉSEAU",
|
|
7
|
+
showBanner: false,
|
|
8
|
+
kernelEvent: "onReady"
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Commande CLI `proxy:generate <nginx|haproxy>` — génère une configuration
|
|
12
|
+
* reverse-proxy DÉRIVÉE de l'introspection Nodefony (domaines de confiance,
|
|
13
|
+
* dossiers statiques servis, ports). Évite d'écrire la conf à la main et de la
|
|
14
|
+
* laisser diverger ; résout le « trou statiques multi-modules » côté nginx.
|
|
15
|
+
*/
|
|
16
|
+
var ProxyGenerate = class extends Command {
|
|
17
|
+
constructor(cli) {
|
|
18
|
+
super("proxy:generate", "engendre une configuration nginx ou haproxy", cli, options);
|
|
19
|
+
this.addArgument("<target>", "nginx | haproxy");
|
|
20
|
+
this.addOption("-o, --out <file>", "write to file instead of stdout");
|
|
21
|
+
this.addOption("-b, --backend <host>", "backend host the proxy connects to (default 127.0.0.1)");
|
|
22
|
+
this.addOption("-l, --listen <port>", "proxy listen port (default 80)");
|
|
23
|
+
this.addOption("--reencrypt", "re-encrypt to the HTTPS backend (TLS proxy↔backend) instead of clear");
|
|
24
|
+
}
|
|
25
|
+
async generate(target, opts) {
|
|
26
|
+
if (target !== "nginx" && target !== "haproxy") {
|
|
27
|
+
this.log(`Cible inconnue '${target}' — attendu: nginx | haproxy.`, "ERROR");
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
const intro = this.buildIntrospection(opts);
|
|
31
|
+
const conf = target === "nginx" ? generateNginxConfig(intro) : generateHaproxyConfig(intro);
|
|
32
|
+
if (opts.out) {
|
|
33
|
+
await fsp.writeFile(opts.out, conf, "utf8");
|
|
34
|
+
this.log(`Configuration ${target} écrite → ${opts.out}`, "INFO");
|
|
35
|
+
} else process.stdout.write(conf);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
/** Construit le modèle d'introspection depuis le kernel + le service statique. */
|
|
39
|
+
buildIntrospection(opts) {
|
|
40
|
+
const module = this.kernel?.getModules()?.["http"];
|
|
41
|
+
const httpOpts = module?.options ?? {};
|
|
42
|
+
const servers = (this.kernel?.options)?.servers;
|
|
43
|
+
const staticSvc = module?.get("server-static");
|
|
44
|
+
staticSvc?.mountModulePublics?.();
|
|
45
|
+
const staticRoots = staticSvc?.servers ? Object.keys(staticSvc.servers) : [];
|
|
46
|
+
const mounts = (staticSvc?.mounts ?? []).map((m) => ({
|
|
47
|
+
prefix: m.prefix,
|
|
48
|
+
dir: m.dir
|
|
49
|
+
}));
|
|
50
|
+
return {
|
|
51
|
+
...defaultIntrospection,
|
|
52
|
+
domains: httpOpts.trustedHosts ?? [],
|
|
53
|
+
backendHost: opts.backend ?? "127.0.0.1",
|
|
54
|
+
httpPort: Number(servers?.http?.port) || defaultIntrospection.httpPort,
|
|
55
|
+
httpsPort: Number(servers?.https?.port) || defaultIntrospection.httpsPort,
|
|
56
|
+
staticRoots,
|
|
57
|
+
mounts,
|
|
58
|
+
listen: opts.listen ? Number(opts.listen) : defaultIntrospection.listen,
|
|
59
|
+
reencrypt: Boolean(opts.reencrypt),
|
|
60
|
+
maxBodyBytes: Number(httpOpts.maxBodySize) || 0,
|
|
61
|
+
keepaliveIntervalMs: Number(httpOpts.websocket?.keepaliveInterval) || 0
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { ProxyGenerate as default };
|