@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.
Files changed (155) hide show
  1. package/LICENSE +544 -0
  2. package/README.md +77 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateParam.js +8 -0
  6. package/dist/index.js +108 -0
  7. package/dist/nodefony/command/assetsPublishCommand.js +102 -0
  8. package/dist/nodefony/command/certificatesCommand.js +47 -0
  9. package/dist/nodefony/command/networkCommand.js +27 -0
  10. package/dist/nodefony/command/proxyGenerateCommand.js +66 -0
  11. package/dist/nodefony/config/config.js +335 -0
  12. package/dist/nodefony/config/defineModuleConfig.js +93 -0
  13. package/dist/nodefony/interfaces/IContext.js +1 -0
  14. package/dist/nodefony/interfaces/ICookie.js +1 -0
  15. package/dist/nodefony/interfaces/IErrorRenderer.js +1 -0
  16. package/dist/nodefony/interfaces/IHttpConfig.js +1 -0
  17. package/dist/nodefony/interfaces/IHttpKernel.js +1 -0
  18. package/dist/nodefony/interfaces/IRequest.js +1 -0
  19. package/dist/nodefony/interfaces/IRequestLogger.js +1 -0
  20. package/dist/nodefony/interfaces/IResponse.js +1 -0
  21. package/dist/nodefony/interfaces/ISession.js +1 -0
  22. package/dist/nodefony/interfaces/IUpload.js +1 -0
  23. package/dist/nodefony/interfaces/index.js +1 -0
  24. package/dist/nodefony/service/HttpAdminApi.js +376 -0
  25. package/dist/nodefony/service/ProfilerAdminApi.js +73 -0
  26. package/dist/nodefony/service/audit-logger.js +159 -0
  27. package/dist/nodefony/service/certificates.js +545 -0
  28. package/dist/nodefony/service/error-renderer.js +320 -0
  29. package/dist/nodefony/service/http-kernel.js +948 -0
  30. package/dist/nodefony/service/pretty-request-logger.js +72 -0
  31. package/dist/nodefony/service/request-logger.js +54 -0
  32. package/dist/nodefony/service/servers/clientError.js +20 -0
  33. package/dist/nodefony/service/servers/server-http.js +135 -0
  34. package/dist/nodefony/service/servers/server-https.js +204 -0
  35. package/dist/nodefony/service/servers/server-static.js +192 -0
  36. package/dist/nodefony/service/servers/server-websocket-secure.js +104 -0
  37. package/dist/nodefony/service/servers/server-websocket.js +104 -0
  38. package/dist/nodefony/service/servers/serverShutdown.js +31 -0
  39. package/dist/nodefony/service/servers/wsHeartbeat.js +64 -0
  40. package/dist/nodefony/service/sessions/sessions-service.js +580 -0
  41. package/dist/nodefony/service/trace.js +72 -0
  42. package/dist/nodefony/service/upload/upload-service.js +171 -0
  43. package/dist/nodefony/src/assets/collectAssets.js +34 -0
  44. package/dist/nodefony/src/assets/prebuiltUi.js +125 -0
  45. package/dist/nodefony/src/context/Context.js +415 -0
  46. package/dist/nodefony/src/context/domainMatcher.js +88 -0
  47. package/dist/nodefony/src/context/forwarded.js +185 -0
  48. package/dist/nodefony/src/context/http/HttpContext.js +309 -0
  49. package/dist/nodefony/src/context/http/Request.js +543 -0
  50. package/dist/nodefony/src/context/http/Response.js +368 -0
  51. package/dist/nodefony/src/context/http/parser.js +188 -0
  52. package/dist/nodefony/src/context/http/urlFastPath.js +103 -0
  53. package/dist/nodefony/src/context/http2/Request.js +29 -0
  54. package/dist/nodefony/src/context/http2/Response.js +97 -0
  55. package/dist/nodefony/src/context/metaData.js +47 -0
  56. package/dist/nodefony/src/context/requestId.js +41 -0
  57. package/dist/nodefony/src/context/trustProxy.js +167 -0
  58. package/dist/nodefony/src/context/websocket/Response.js +181 -0
  59. package/dist/nodefony/src/context/websocket/WebsocketContext.js +389 -0
  60. package/dist/nodefony/src/context/websocket/wsBackpressure.js +56 -0
  61. package/dist/nodefony/src/context/websocket/wsLogContent.js +68 -0
  62. package/dist/nodefony/src/cookies/cookie.js +258 -0
  63. package/dist/nodefony/src/errors/httpError.js +69 -0
  64. package/dist/nodefony/src/profiler/FrameProfile.js +95 -0
  65. package/dist/nodefony/src/profiler/Profiler.js +139 -0
  66. package/dist/nodefony/src/proxy/generateProxyConfig.js +157 -0
  67. package/dist/nodefony/src/rateLimit/IRateLimitStore.js +1 -0
  68. package/dist/nodefony/src/rateLimit/MemoryRateLimitStore.js +146 -0
  69. package/dist/nodefony/src/rateLimit/WsConnectionCounter.js +64 -0
  70. package/dist/nodefony/src/rateLimit/rateLimitFilters.js +20 -0
  71. package/dist/nodefony/src/servers/portBinder.js +114 -0
  72. package/dist/nodefony/src/session/session.js +390 -0
  73. package/dist/nodefony/src/session/storage/MemorySessionStorage.js +185 -0
  74. package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +137 -0
  75. package/dist/nodefony/src/session/storage/sessionFilters.js +83 -0
  76. package/dist/nodefony/src/session/storage/sessionSort.js +53 -0
  77. package/dist/types/index.d.ts +83 -0
  78. package/dist/types/nodefony/command/assetsPublishCommand.d.ts +23 -0
  79. package/dist/types/nodefony/command/certificatesCommand.d.ts +17 -0
  80. package/dist/types/nodefony/command/networkCommand.d.ts +8 -0
  81. package/dist/types/nodefony/command/proxyGenerateCommand.d.ts +19 -0
  82. package/dist/types/nodefony/config/config.d.ts +197 -0
  83. package/dist/types/nodefony/config/defineModuleConfig.d.ts +39 -0
  84. package/dist/types/nodefony/interfaces/IContext.d.ts +138 -0
  85. package/dist/types/nodefony/interfaces/ICookie.d.ts +47 -0
  86. package/dist/types/nodefony/interfaces/IErrorRenderer.d.ts +55 -0
  87. package/dist/types/nodefony/interfaces/IHttpConfig.d.ts +12 -0
  88. package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -0
  89. package/dist/types/nodefony/interfaces/IRequest.d.ts +35 -0
  90. package/dist/types/nodefony/interfaces/IRequestLogger.d.ts +31 -0
  91. package/dist/types/nodefony/interfaces/IResponse.d.ts +39 -0
  92. package/dist/types/nodefony/interfaces/ISession.d.ts +283 -0
  93. package/dist/types/nodefony/interfaces/IUpload.d.ts +66 -0
  94. package/dist/types/nodefony/interfaces/index.d.ts +7 -0
  95. package/dist/types/nodefony/service/HttpAdminApi.d.ts +18 -0
  96. package/dist/types/nodefony/service/ProfilerAdminApi.d.ts +23 -0
  97. package/dist/types/nodefony/service/audit-logger.d.ts +143 -0
  98. package/dist/types/nodefony/service/certificates.d.ts +246 -0
  99. package/dist/types/nodefony/service/error-renderer.d.ts +74 -0
  100. package/dist/types/nodefony/service/http-kernel.d.ts +377 -0
  101. package/dist/types/nodefony/service/pretty-request-logger.d.ts +25 -0
  102. package/dist/types/nodefony/service/request-logger.d.ts +18 -0
  103. package/dist/types/nodefony/service/servers/clientError.d.ts +14 -0
  104. package/dist/types/nodefony/service/servers/server-http.d.ts +42 -0
  105. package/dist/types/nodefony/service/servers/server-https.d.ts +41 -0
  106. package/dist/types/nodefony/service/servers/server-static.d.ts +62 -0
  107. package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +29 -0
  108. package/dist/types/nodefony/service/servers/server-websocket.d.ts +29 -0
  109. package/dist/types/nodefony/service/servers/serverShutdown.d.ts +27 -0
  110. package/dist/types/nodefony/service/servers/wsHeartbeat.d.ts +46 -0
  111. package/dist/types/nodefony/service/sessions/sessions-service.d.ts +218 -0
  112. package/dist/types/nodefony/service/trace.d.ts +39 -0
  113. package/dist/types/nodefony/service/upload/upload-service.d.ts +61 -0
  114. package/dist/types/nodefony/src/assets/collectAssets.d.ts +35 -0
  115. package/dist/types/nodefony/src/assets/prebuiltUi.d.ts +99 -0
  116. package/dist/types/nodefony/src/context/Context.d.ts +195 -0
  117. package/dist/types/nodefony/src/context/domainMatcher.d.ts +67 -0
  118. package/dist/types/nodefony/src/context/forwarded.d.ts +95 -0
  119. package/dist/types/nodefony/src/context/http/HttpContext.d.ts +85 -0
  120. package/dist/types/nodefony/src/context/http/Request.d.ts +203 -0
  121. package/dist/types/nodefony/src/context/http/Response.d.ts +68 -0
  122. package/dist/types/nodefony/src/context/http/parser.d.ts +65 -0
  123. package/dist/types/nodefony/src/context/http/urlFastPath.d.ts +52 -0
  124. package/dist/types/nodefony/src/context/http2/Request.d.ts +14 -0
  125. package/dist/types/nodefony/src/context/http2/Response.d.ts +20 -0
  126. package/dist/types/nodefony/src/context/metaData.d.ts +58 -0
  127. package/dist/types/nodefony/src/context/requestId.d.ts +28 -0
  128. package/dist/types/nodefony/src/context/trustProxy.d.ts +77 -0
  129. package/dist/types/nodefony/src/context/websocket/Response.d.ts +53 -0
  130. package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +125 -0
  131. package/dist/types/nodefony/src/context/websocket/wsBackpressure.d.ts +73 -0
  132. package/dist/types/nodefony/src/context/websocket/wsLogContent.d.ts +37 -0
  133. package/dist/types/nodefony/src/cookies/cookie.d.ts +88 -0
  134. package/dist/types/nodefony/src/errors/httpError.d.ts +15 -0
  135. package/dist/types/nodefony/src/profiler/FrameProfile.d.ts +110 -0
  136. package/dist/types/nodefony/src/profiler/Profiler.d.ts +192 -0
  137. package/dist/types/nodefony/src/proxy/generateProxyConfig.d.ts +76 -0
  138. package/dist/types/nodefony/src/rateLimit/IRateLimitStore.d.ts +98 -0
  139. package/dist/types/nodefony/src/rateLimit/MemoryRateLimitStore.d.ts +40 -0
  140. package/dist/types/nodefony/src/rateLimit/WsConnectionCounter.d.ts +37 -0
  141. package/dist/types/nodefony/src/rateLimit/rateLimitFilters.d.ts +18 -0
  142. package/dist/types/nodefony/src/servers/portBinder.d.ts +102 -0
  143. package/dist/types/nodefony/src/session/session.d.ts +171 -0
  144. package/dist/types/nodefony/src/session/storage/MemorySessionStorage.d.ts +77 -0
  145. package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +81 -0
  146. package/dist/types/nodefony/src/session/storage/sessionFilters.d.ts +102 -0
  147. package/dist/types/nodefony/src/session/storage/sessionSort.d.ts +45 -0
  148. package/docs/cookies.md +365 -0
  149. package/docs/index.md +163 -0
  150. package/docs/observabilite.md +460 -0
  151. package/docs/rate-limit.md +372 -0
  152. package/docs/servers.md +935 -0
  153. package/docs/session.md +768 -0
  154. package/docs/upload.md +460 -0
  155. 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 };