@fulgurjs/federation 0.4.2

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.
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/config.ts
31
+ var config_exports = {};
32
+ __export(config_exports, {
33
+ defineFulgurConfig: () => defineFulgurConfig,
34
+ loadFulgurConfig: () => loadFulgurConfig
35
+ });
36
+ module.exports = __toCommonJS(config_exports);
37
+ var import_meta = {};
38
+ function defineFulgurConfig(config) {
39
+ return config;
40
+ }
41
+ async function loadFulgurConfig(configPath) {
42
+ const { pathToFileURL, fileURLToPath } = await import("url");
43
+ const { createRequire } = await import("module");
44
+ const fs = await import("fs");
45
+ const os = await import("os");
46
+ const path = await import("path");
47
+ const selfDir = path.dirname(fileURLToPath(import_meta.url));
48
+ const selfConfigJs = path.join(selfDir, "config.js");
49
+ const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@fulgur-federation-config-unavailable";
50
+ const rewriteSelfImports = (source) => source.replace(/(['"])@fulgur\/federation\/config\1/g, (_m, q) => `${q}${SELF_SPEC}${q}`);
51
+ const importConfigs = async (cacheKey) => {
52
+ return await import(`${cacheKey}?t=${Date.now()}`);
53
+ };
54
+ let mod;
55
+ if (configPath.endsWith(".json")) {
56
+ mod = { default: JSON.parse(fs.readFileSync(configPath, "utf8")) };
57
+ } else {
58
+ const source = rewriteSelfImports(fs.readFileSync(configPath, "utf8"));
59
+ const tmpBase = path.join(os.tmpdir(), `fulgur-config-${Date.now()}`);
60
+ if (/\.(ts|mts|cts)$/.test(configPath)) {
61
+ try {
62
+ const tmpTs = `${tmpBase}.ts`;
63
+ fs.writeFileSync(tmpTs, source);
64
+ mod = await importConfigs(pathToFileURL(tmpTs).href);
65
+ } catch (e) {
66
+ if (!/Unexpected|SyntaxError|ERR_UNSUPPORTED_NODE_MODULES|ERR_UNKNOWN_FILE_EXTENSION|ERR_IMPORT_ATTRIBUTE/.test(String(e)) && process.version.startsWith("v2")) {
67
+ throw e;
68
+ }
69
+ const requireFromConfig = createRequire(configPath);
70
+ let esbuild;
71
+ try {
72
+ esbuild = requireFromConfig("esbuild");
73
+ } catch {
74
+ const requireFromSelf = createRequire(import_meta.url);
75
+ esbuild = requireFromSelf("esbuild");
76
+ }
77
+ const out = esbuild.buildSync({ entryPoints: [configPath], bundle: false, write: false, format: "esm", target: "node18" });
78
+ const jsFile = `${tmpBase}.mjs`;
79
+ fs.writeFileSync(jsFile, rewriteSelfImports(out.outputFiles[0].text));
80
+ mod = await importConfigs(pathToFileURL(jsFile).href);
81
+ }
82
+ } else {
83
+ const jsFile = `${tmpBase}.mjs`;
84
+ fs.writeFileSync(jsFile, source);
85
+ mod = await importConfigs(pathToFileURL(jsFile).href);
86
+ }
87
+ }
88
+ const cfg = mod.default;
89
+ if (!cfg?.root) {
90
+ throw new Error(
91
+ `[fulgur:init] \u914D\u7F6E\u7F3A\u5C11 root\uFF08\u5DE5\u7A0B\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09
92
+ \u6839\u56E0\uFF1ACLI \u9700\u8981\u77E5\u9053\u5728\u54EA\u4E2A\u5DE5\u7A0B\u4E0A\u505A\u96C6\u6210
93
+ \u4FEE\u6CD5\uFF1Afulgur.config.ts \u9876\u5C42\u8865 root: '/abs/path/to/repo'\uFF08\u8D77\u6B65\u6A21\u677F\uFF1Afulgur init\uFF09`
94
+ );
95
+ }
96
+ if (!Array.isArray(cfg.apps) || cfg.apps.length === 0) {
97
+ throw new Error("[fulgur:init] \u914D\u7F6E\u7F3A\u5C11 apps\uFF08\u81F3\u5C11\u4E00\u4E2A\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u5E94\u7528\uFF09");
98
+ }
99
+ for (const app of cfg.apps) {
100
+ if (!app.host && !app.remote) {
101
+ throw new Error(
102
+ `[fulgur:init] \u5E94\u7528 "${app.path}" \u65E2\u65E0 host \u4E5F\u65E0 remote \u89D2\u8272
103
+ \u6839\u56E0\uFF1A\u5E94\u7528\u5FC5\u987B\u81F3\u5C11\u58F0\u660E\u4E00\u4E2A\u89D2\u8272
104
+ \u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u8865 host: { pages, remotePrefixes, remotes }\uFF0C\u8FDC\u7A0B\u8865 remote: { exposes }`
105
+ );
106
+ }
107
+ }
108
+ return cfg;
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ defineFulgurConfig,
113
+ loadFulgurConfig
114
+ });
@@ -0,0 +1,79 @@
1
+ /**
2
+ * W1 fulgur.config.ts:单配置文件驱动的 schema + 加载器(项目无关,决策见排期文档 §4:
3
+ * 主包内置 bin + 单配置文件驱动,可入库可复跑)。
4
+ * init 只消费该配置生成通用样板(见 init.ts);插件运行时(federation())不读取本文件。
5
+ */
6
+ interface FulgurPageEntry {
7
+ /** 宿主路由路径(参数段用 :xx) */
8
+ route: string;
9
+ /** 路由 name(命名跳转依赖) */
10
+ name?: string;
11
+ /** 远程 exposes 键(显式覆盖默认推导 pages/<去前缀去参数段>) */
12
+ spec?: string;
13
+ /** 页签标题 */
14
+ title?: string;
15
+ }
16
+ interface FulgurRemoteAddress {
17
+ dev: string;
18
+ prod: string;
19
+ }
20
+ interface FulgurHostConfig {
21
+ /** 页面路由表 */
22
+ pages: FulgurPageEntry[];
23
+ /** 路由前缀 → 远程名 */
24
+ remotePrefixes: Record<string, string>;
25
+ /** 消费的远程地址(键 = import 前缀;裸 URL,对象形式不支持 name@ 前缀) */
26
+ remotes: Record<string, FulgurRemoteAddress>;
27
+ }
28
+ interface FulgurRemoteConfig {
29
+ /** exposes:./键 → 源文件(独立页) */
30
+ exposes: Record<string, string>;
31
+ /** 反向消费的远程(双向联邦时;dev 下自身源码参与协商需 devSharedSelf: true) */
32
+ remotes?: Record<string, FulgurRemoteAddress>;
33
+ }
34
+ interface FulgurAppConfig {
35
+ /** 相对 root 的应用目录 */
36
+ path: string;
37
+ /** 联邦容器名 */
38
+ name: string;
39
+ /** dev 端口 */
40
+ port: number;
41
+ /** 部署/dev 的 URL 前缀,如 /main */
42
+ base: string;
43
+ /** 部署目录名(缺省取 base 去斜杠) */
44
+ deployDir?: string;
45
+ /** 宿主角色 */
46
+ host?: FulgurHostConfig;
47
+ /** 远程角色 */
48
+ remote?: FulgurRemoteConfig;
49
+ /** 该应用的 shared 表(缺省建议 vue/vue-router/pinia singleton,见 init 输出的样板) */
50
+ shared?: Record<string, {
51
+ singleton?: boolean;
52
+ requiredVersion?: string;
53
+ }>;
54
+ }
55
+ interface FulgurDeployConfig {
56
+ /** NGINX 站点根(样板输出用,可选) */
57
+ webRoot?: string;
58
+ /** 监听端口(样板输出用,可选) */
59
+ listen?: number;
60
+ }
61
+ interface FulgurRepoConfig {
62
+ /** 工程根(monorepo 根或单应用仓库根) */
63
+ root: string;
64
+ apps: FulgurAppConfig[];
65
+ deploy?: FulgurDeployConfig;
66
+ }
67
+ type FulgurUserConfig = Partial<FulgurRepoConfig>;
68
+ /** 用户配置文件入口:仅做类型收窄(identity),不引入运行时逻辑 */
69
+ declare function defineFulgurConfig(config: FulgurUserConfig): FulgurUserConfig;
70
+ /**
71
+ * 加载 fulgur.config.ts(或 .js/.json)。
72
+ * - 配置内的 `@fulgurjs/federation/config` 导入被重写为本包 dist/config.js 绝对路径——
73
+ * init 之前工程依赖尚未安装(鸡生蛋),重写后零依赖可加载;
74
+ * - TS 走 Node 原生类型剥离(Node ≥23.6 默认开启;配置文件须用可擦除语法——纯对象无 enum/namespace);
75
+ * 老版本 Node 回退 esbuild 转译(先试配置工程,再试 CLI 自带依赖树)。
76
+ */
77
+ declare function loadFulgurConfig(configPath: string): Promise<FulgurRepoConfig>;
78
+
79
+ export { type FulgurAppConfig, type FulgurDeployConfig, type FulgurHostConfig, type FulgurPageEntry, type FulgurRemoteAddress, type FulgurRemoteConfig, type FulgurRepoConfig, type FulgurUserConfig, defineFulgurConfig, loadFulgurConfig };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * W1 fulgur.config.ts:单配置文件驱动的 schema + 加载器(项目无关,决策见排期文档 §4:
3
+ * 主包内置 bin + 单配置文件驱动,可入库可复跑)。
4
+ * init 只消费该配置生成通用样板(见 init.ts);插件运行时(federation())不读取本文件。
5
+ */
6
+ interface FulgurPageEntry {
7
+ /** 宿主路由路径(参数段用 :xx) */
8
+ route: string;
9
+ /** 路由 name(命名跳转依赖) */
10
+ name?: string;
11
+ /** 远程 exposes 键(显式覆盖默认推导 pages/<去前缀去参数段>) */
12
+ spec?: string;
13
+ /** 页签标题 */
14
+ title?: string;
15
+ }
16
+ interface FulgurRemoteAddress {
17
+ dev: string;
18
+ prod: string;
19
+ }
20
+ interface FulgurHostConfig {
21
+ /** 页面路由表 */
22
+ pages: FulgurPageEntry[];
23
+ /** 路由前缀 → 远程名 */
24
+ remotePrefixes: Record<string, string>;
25
+ /** 消费的远程地址(键 = import 前缀;裸 URL,对象形式不支持 name@ 前缀) */
26
+ remotes: Record<string, FulgurRemoteAddress>;
27
+ }
28
+ interface FulgurRemoteConfig {
29
+ /** exposes:./键 → 源文件(独立页) */
30
+ exposes: Record<string, string>;
31
+ /** 反向消费的远程(双向联邦时;dev 下自身源码参与协商需 devSharedSelf: true) */
32
+ remotes?: Record<string, FulgurRemoteAddress>;
33
+ }
34
+ interface FulgurAppConfig {
35
+ /** 相对 root 的应用目录 */
36
+ path: string;
37
+ /** 联邦容器名 */
38
+ name: string;
39
+ /** dev 端口 */
40
+ port: number;
41
+ /** 部署/dev 的 URL 前缀,如 /main */
42
+ base: string;
43
+ /** 部署目录名(缺省取 base 去斜杠) */
44
+ deployDir?: string;
45
+ /** 宿主角色 */
46
+ host?: FulgurHostConfig;
47
+ /** 远程角色 */
48
+ remote?: FulgurRemoteConfig;
49
+ /** 该应用的 shared 表(缺省建议 vue/vue-router/pinia singleton,见 init 输出的样板) */
50
+ shared?: Record<string, {
51
+ singleton?: boolean;
52
+ requiredVersion?: string;
53
+ }>;
54
+ }
55
+ interface FulgurDeployConfig {
56
+ /** NGINX 站点根(样板输出用,可选) */
57
+ webRoot?: string;
58
+ /** 监听端口(样板输出用,可选) */
59
+ listen?: number;
60
+ }
61
+ interface FulgurRepoConfig {
62
+ /** 工程根(monorepo 根或单应用仓库根) */
63
+ root: string;
64
+ apps: FulgurAppConfig[];
65
+ deploy?: FulgurDeployConfig;
66
+ }
67
+ type FulgurUserConfig = Partial<FulgurRepoConfig>;
68
+ /** 用户配置文件入口:仅做类型收窄(identity),不引入运行时逻辑 */
69
+ declare function defineFulgurConfig(config: FulgurUserConfig): FulgurUserConfig;
70
+ /**
71
+ * 加载 fulgur.config.ts(或 .js/.json)。
72
+ * - 配置内的 `@fulgurjs/federation/config` 导入被重写为本包 dist/config.js 绝对路径——
73
+ * init 之前工程依赖尚未安装(鸡生蛋),重写后零依赖可加载;
74
+ * - TS 走 Node 原生类型剥离(Node ≥23.6 默认开启;配置文件须用可擦除语法——纯对象无 enum/namespace);
75
+ * 老版本 Node 回退 esbuild 转译(先试配置工程,再试 CLI 自带依赖树)。
76
+ */
77
+ declare function loadFulgurConfig(configPath: string): Promise<FulgurRepoConfig>;
78
+
79
+ export { type FulgurAppConfig, type FulgurDeployConfig, type FulgurHostConfig, type FulgurPageEntry, type FulgurRemoteAddress, type FulgurRemoteConfig, type FulgurRepoConfig, type FulgurUserConfig, defineFulgurConfig, loadFulgurConfig };
package/dist/config.js ADDED
@@ -0,0 +1,77 @@
1
+ // src/config.ts
2
+ function defineFulgurConfig(config) {
3
+ return config;
4
+ }
5
+ async function loadFulgurConfig(configPath) {
6
+ const { pathToFileURL, fileURLToPath } = await import("url");
7
+ const { createRequire } = await import("module");
8
+ const fs = await import("fs");
9
+ const os = await import("os");
10
+ const path = await import("path");
11
+ const selfDir = path.dirname(fileURLToPath(import.meta.url));
12
+ const selfConfigJs = path.join(selfDir, "config.js");
13
+ const SELF_SPEC = fs.existsSync(selfConfigJs) ? pathToFileURL(selfConfigJs).href : "@fulgur-federation-config-unavailable";
14
+ const rewriteSelfImports = (source) => source.replace(/(['"])@fulgur\/federation\/config\1/g, (_m, q) => `${q}${SELF_SPEC}${q}`);
15
+ const importConfigs = async (cacheKey) => {
16
+ return await import(`${cacheKey}?t=${Date.now()}`);
17
+ };
18
+ let mod;
19
+ if (configPath.endsWith(".json")) {
20
+ mod = { default: JSON.parse(fs.readFileSync(configPath, "utf8")) };
21
+ } else {
22
+ const source = rewriteSelfImports(fs.readFileSync(configPath, "utf8"));
23
+ const tmpBase = path.join(os.tmpdir(), `fulgur-config-${Date.now()}`);
24
+ if (/\.(ts|mts|cts)$/.test(configPath)) {
25
+ try {
26
+ const tmpTs = `${tmpBase}.ts`;
27
+ fs.writeFileSync(tmpTs, source);
28
+ mod = await importConfigs(pathToFileURL(tmpTs).href);
29
+ } catch (e) {
30
+ if (!/Unexpected|SyntaxError|ERR_UNSUPPORTED_NODE_MODULES|ERR_UNKNOWN_FILE_EXTENSION|ERR_IMPORT_ATTRIBUTE/.test(String(e)) && process.version.startsWith("v2")) {
31
+ throw e;
32
+ }
33
+ const requireFromConfig = createRequire(configPath);
34
+ let esbuild;
35
+ try {
36
+ esbuild = requireFromConfig("esbuild");
37
+ } catch {
38
+ const requireFromSelf = createRequire(import.meta.url);
39
+ esbuild = requireFromSelf("esbuild");
40
+ }
41
+ const out = esbuild.buildSync({ entryPoints: [configPath], bundle: false, write: false, format: "esm", target: "node18" });
42
+ const jsFile = `${tmpBase}.mjs`;
43
+ fs.writeFileSync(jsFile, rewriteSelfImports(out.outputFiles[0].text));
44
+ mod = await importConfigs(pathToFileURL(jsFile).href);
45
+ }
46
+ } else {
47
+ const jsFile = `${tmpBase}.mjs`;
48
+ fs.writeFileSync(jsFile, source);
49
+ mod = await importConfigs(pathToFileURL(jsFile).href);
50
+ }
51
+ }
52
+ const cfg = mod.default;
53
+ if (!cfg?.root) {
54
+ throw new Error(
55
+ `[fulgur:init] \u914D\u7F6E\u7F3A\u5C11 root\uFF08\u5DE5\u7A0B\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09
56
+ \u6839\u56E0\uFF1ACLI \u9700\u8981\u77E5\u9053\u5728\u54EA\u4E2A\u5DE5\u7A0B\u4E0A\u505A\u96C6\u6210
57
+ \u4FEE\u6CD5\uFF1Afulgur.config.ts \u9876\u5C42\u8865 root: '/abs/path/to/repo'\uFF08\u8D77\u6B65\u6A21\u677F\uFF1Afulgur init\uFF09`
58
+ );
59
+ }
60
+ if (!Array.isArray(cfg.apps) || cfg.apps.length === 0) {
61
+ throw new Error("[fulgur:init] \u914D\u7F6E\u7F3A\u5C11 apps\uFF08\u81F3\u5C11\u4E00\u4E2A\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u5E94\u7528\uFF09");
62
+ }
63
+ for (const app of cfg.apps) {
64
+ if (!app.host && !app.remote) {
65
+ throw new Error(
66
+ `[fulgur:init] \u5E94\u7528 "${app.path}" \u65E2\u65E0 host \u4E5F\u65E0 remote \u89D2\u8272
67
+ \u6839\u56E0\uFF1A\u5E94\u7528\u5FC5\u987B\u81F3\u5C11\u58F0\u660E\u4E00\u4E2A\u89D2\u8272
68
+ \u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u8865 host: { pages, remotePrefixes, remotes }\uFF0C\u8FDC\u7A0B\u8865 remote: { exposes }`
69
+ );
70
+ }
71
+ }
72
+ return cfg;
73
+ }
74
+ export {
75
+ defineFulgurConfig,
76
+ loadFulgurConfig
77
+ };