everything-dev 1.33.6 → 1.35.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/dist/api-contract.cjs +48 -68
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +48 -68
- package/dist/api-contract.mjs.map +1 -1
- package/dist/cli/init.cjs +64 -41
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +65 -42
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/sync.cjs +5 -0
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +5 -0
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +6 -3
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +6 -3
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/config.cjs +12 -4
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +12 -4
- package/dist/config.mjs.map +1 -1
- package/dist/contract.d.cts +62 -46
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +62 -46
- package/dist/contract.d.mts.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/merge.cjs +1 -2
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.d.cts +1 -1
- package/dist/merge.d.cts.map +1 -1
- package/dist/merge.d.mts +1 -1
- package/dist/merge.d.mts.map +1 -1
- package/dist/merge.mjs +1 -2
- package/dist/merge.mjs.map +1 -1
- package/dist/near-cli.cjs +0 -23
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +0 -23
- package/dist/near-cli.mjs.map +1 -1
- package/dist/plugin.cjs +9 -3
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +72 -50
- package/dist/plugin.d.mts +72 -50
- package/dist/plugin.mjs +9 -3
- package/dist/plugin.mjs.map +1 -1
- package/dist/shared-deps.cjs +201 -0
- package/dist/shared-deps.cjs.map +1 -0
- package/dist/shared-deps.mjs +200 -0
- package/dist/shared-deps.mjs.map +1 -0
- package/dist/types.cjs +14 -12
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +88 -40
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +88 -40
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +14 -13
- package/dist/types.mjs.map +1 -1
- package/package.json +4 -4
- package/skills/extends-config/SKILL.md +7 -8
- package/skills/init-upgrade/SKILL.md +5 -2
- package/skills/publish-sync/SKILL.md +1 -1
- package/dist/shared.cjs +0 -155
- package/dist/shared.cjs.map +0 -1
- package/dist/shared.mjs +0 -154
- package/dist/shared.mjs.map +0 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_merge = require('./merge.cjs');
|
|
3
|
+
const require_types = require('./types.cjs');
|
|
4
|
+
let node_fs = require("node:fs");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
7
|
+
|
|
8
|
+
//#region src/shared-deps.ts
|
|
9
|
+
function sha256(input) {
|
|
10
|
+
return (0, node_crypto.createHash)("sha256").update(input).digest("hex");
|
|
11
|
+
}
|
|
12
|
+
function extractSemverExact(input) {
|
|
13
|
+
if (typeof input !== "string") return null;
|
|
14
|
+
const match = input.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
15
|
+
return match ? match[0] : null;
|
|
16
|
+
}
|
|
17
|
+
function caretRange(version) {
|
|
18
|
+
return `^${version}`;
|
|
19
|
+
}
|
|
20
|
+
function stableDepsObject(deps) {
|
|
21
|
+
const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));
|
|
22
|
+
const out = {};
|
|
23
|
+
for (const key of keys) out[key] = deps[key];
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
function normalizeSharedDepConfig(config) {
|
|
27
|
+
return {
|
|
28
|
+
version: config.version,
|
|
29
|
+
requiredVersion: config.requiredVersion ?? false,
|
|
30
|
+
singleton: config.singleton ?? false,
|
|
31
|
+
eager: config.eager ?? false,
|
|
32
|
+
strictVersion: config.strictVersion ?? false,
|
|
33
|
+
shareScope: config.shareScope ?? "default"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function getObject(value) {
|
|
37
|
+
return require_merge.isPlainObject(value) ? value : void 0;
|
|
38
|
+
}
|
|
39
|
+
function getSharedDepsMap(value, source) {
|
|
40
|
+
if (value === void 0) return void 0;
|
|
41
|
+
if (!require_types.SharedDepMapSchema.safeParse(value).success) throw new Error(`Invalid shared dependency map at ${source}`);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
function writeFileIfChanged(filePath, nextContent) {
|
|
45
|
+
try {
|
|
46
|
+
if ((0, node_fs.readFileSync)(filePath, "utf-8") === nextContent) return false;
|
|
47
|
+
} catch {}
|
|
48
|
+
(0, node_fs.writeFileSync)(filePath, nextContent);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
function fingerprintResolved(deps) {
|
|
52
|
+
return sha256(JSON.stringify(stableDepsObject(deps)));
|
|
53
|
+
}
|
|
54
|
+
function isSameSharedDepConfig(a, b) {
|
|
55
|
+
const left = normalizeSharedDepConfig(a);
|
|
56
|
+
const right = normalizeSharedDepConfig(b);
|
|
57
|
+
return left.version === right.version && left.requiredVersion === right.requiredVersion && left.singleton === right.singleton && left.eager === right.eager && left.strictVersion === right.strictVersion && left.shareScope === right.shareScope;
|
|
58
|
+
}
|
|
59
|
+
function collectSharedDepRefs(bosConfig) {
|
|
60
|
+
const refs = /* @__PURE__ */ new Map();
|
|
61
|
+
const app = getObject(bosConfig.app);
|
|
62
|
+
const appUi = getObject(app?.ui);
|
|
63
|
+
const appApi = getObject(app?.api);
|
|
64
|
+
const appAuth = getObject(app?.auth);
|
|
65
|
+
const plugins = getObject(bosConfig.plugins);
|
|
66
|
+
if (appUi && "shared" in appUi) throw new Error("app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.");
|
|
67
|
+
const append = (source, shared) => {
|
|
68
|
+
if (!shared) return;
|
|
69
|
+
for (const [name, config] of Object.entries(shared)) {
|
|
70
|
+
const existing = refs.get(name);
|
|
71
|
+
if (!existing) {
|
|
72
|
+
refs.set(name, [{
|
|
73
|
+
source,
|
|
74
|
+
config
|
|
75
|
+
}]);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!isSameSharedDepConfig(existing[0].config, config)) {
|
|
79
|
+
const previous = existing.map((ref) => ref.source).join(", ");
|
|
80
|
+
throw new Error(`Conflicting shared dependency "${name}" between ${previous} and ${source}`);
|
|
81
|
+
}
|
|
82
|
+
existing.push({
|
|
83
|
+
source,
|
|
84
|
+
config
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
append("app.api", getSharedDepsMap(appApi?.shared, "app.api.shared"));
|
|
89
|
+
append("app.auth", getSharedDepsMap(appAuth?.shared, "app.auth.shared"));
|
|
90
|
+
for (const [pluginId, plugin] of Object.entries(plugins ?? {})) {
|
|
91
|
+
const pluginRecord = getObject(plugin);
|
|
92
|
+
if (!pluginRecord) continue;
|
|
93
|
+
const pluginUi = getObject(getObject(pluginRecord.app)?.ui);
|
|
94
|
+
if (pluginUi && "shared" in pluginUi) throw new Error(`app.ui.shared is no longer supported in plugins.${pluginId}. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.`);
|
|
95
|
+
append(`plugins.${pluginId}`, getSharedDepsMap(pluginRecord.shared, `plugins.${pluginId}.shared`));
|
|
96
|
+
}
|
|
97
|
+
return Object.fromEntries(refs);
|
|
98
|
+
}
|
|
99
|
+
async function syncResolvedSharedDeps(opts) {
|
|
100
|
+
const bosConfigPath = (0, node_path.join)(opts.configDir, "bos.config.json");
|
|
101
|
+
const resolvedConfigPath = (0, node_path.join)(opts.configDir, ".bos", "bos.resolved-config.json");
|
|
102
|
+
const packageJsonPath = (0, node_path.join)(opts.configDir, "package.json");
|
|
103
|
+
const generatedPath = (0, node_path.join)(opts.configDir, ".bos", "generated", "shared-deps.json");
|
|
104
|
+
const bosConfig = opts.bosConfig ?? JSON.parse((0, node_fs.readFileSync)(bosConfigPath, "utf-8"));
|
|
105
|
+
if (!require_merge.isPlainObject(bosConfig)) throw new Error("bos.config.json must be an object");
|
|
106
|
+
const pkgJson = (0, node_fs.existsSync)(packageJsonPath) ? JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8")) : {};
|
|
107
|
+
const originalBos = JSON.stringify(bosConfig);
|
|
108
|
+
const originalPkg = JSON.stringify(pkgJson);
|
|
109
|
+
const mode = opts.hostMode === "local" ? "catalog->bos" : "bos->catalog";
|
|
110
|
+
const refsByName = collectSharedDepRefs(bosConfig);
|
|
111
|
+
const catalog = pkgJson.workspaces?.catalog ?? {};
|
|
112
|
+
const resolvedDeps = {};
|
|
113
|
+
for (const [name, refs] of Object.entries(refsByName)) {
|
|
114
|
+
const first = refs[0];
|
|
115
|
+
if (!first) continue;
|
|
116
|
+
const exactFromConfig = extractSemverExact(first.config.version) ?? extractSemverExact(first.config.requiredVersion);
|
|
117
|
+
const exactFromCatalog = extractSemverExact(catalog[name]);
|
|
118
|
+
const version = mode === "catalog->bos" ? exactFromCatalog ?? exactFromConfig : exactFromConfig ?? exactFromCatalog;
|
|
119
|
+
if (!version) {
|
|
120
|
+
const sources = refs.map((ref) => ref.source).join(", ");
|
|
121
|
+
throw new Error(`Could not resolve exact version for shared dependency "${name}" from ${sources}`);
|
|
122
|
+
}
|
|
123
|
+
if (mode === "catalog->bos" && exactFromCatalog === null && exactFromConfig) catalog[name] = exactFromConfig;
|
|
124
|
+
if (mode === "bos->catalog" && catalog[name] !== version) catalog[name] = version;
|
|
125
|
+
for (const ref of refs) {
|
|
126
|
+
ref.config.version = version;
|
|
127
|
+
ref.config.requiredVersion = caretRange(version);
|
|
128
|
+
ref.config.shareScope = ref.config.shareScope ?? "default";
|
|
129
|
+
}
|
|
130
|
+
resolvedDeps[name] = {
|
|
131
|
+
name,
|
|
132
|
+
version,
|
|
133
|
+
requiredVersion: caretRange(version),
|
|
134
|
+
shareScope: first.config.shareScope ?? "default",
|
|
135
|
+
singleton: first.config.singleton ?? false,
|
|
136
|
+
eager: first.config.eager ?? false,
|
|
137
|
+
strictVersion: first.config.strictVersion ?? false,
|
|
138
|
+
sources: refs.map((ref) => ref.source).sort((a, b) => a.localeCompare(b))
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (!pkgJson.workspaces) pkgJson.workspaces = {
|
|
142
|
+
packages: [],
|
|
143
|
+
catalog: {}
|
|
144
|
+
};
|
|
145
|
+
pkgJson.workspaces.catalog = catalog;
|
|
146
|
+
const nextBos = JSON.stringify(bosConfig);
|
|
147
|
+
const nextPkg = JSON.stringify(pkgJson);
|
|
148
|
+
const bosConfigChanged = nextBos !== originalBos;
|
|
149
|
+
const catalogChanged = nextPkg !== originalPkg;
|
|
150
|
+
if (bosConfigChanged) {
|
|
151
|
+
const resolvedDir = (0, node_path.dirname)(resolvedConfigPath);
|
|
152
|
+
if (!(0, node_fs.existsSync)(resolvedDir)) (0, node_fs.mkdirSync)(resolvedDir, { recursive: true });
|
|
153
|
+
const ordered = require_merge.rebuildOrderedConfig(bosConfig);
|
|
154
|
+
const resolvedOutput = {
|
|
155
|
+
_resolved: {
|
|
156
|
+
env: opts.env ?? "development",
|
|
157
|
+
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
158
|
+
extendsChain: opts.extendsChain ?? [],
|
|
159
|
+
source: "shared-sync"
|
|
160
|
+
},
|
|
161
|
+
...ordered
|
|
162
|
+
};
|
|
163
|
+
writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\n`);
|
|
164
|
+
}
|
|
165
|
+
if (catalogChanged) writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`);
|
|
166
|
+
const stableResolvedDeps = stableDepsObject(resolvedDeps);
|
|
167
|
+
const resolved = {
|
|
168
|
+
deps: stableResolvedDeps,
|
|
169
|
+
fingerprintSha256: fingerprintResolved(stableResolvedDeps)
|
|
170
|
+
};
|
|
171
|
+
const nextGenerated = {
|
|
172
|
+
schemaVersion: 1,
|
|
173
|
+
kind: "everything-dev/shared-deps",
|
|
174
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
175
|
+
deps: stableResolvedDeps,
|
|
176
|
+
fingerprintSha256: resolved.fingerprintSha256,
|
|
177
|
+
inputs: {
|
|
178
|
+
mode,
|
|
179
|
+
hostMode: opts.hostMode
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
let prevFingerprint = null;
|
|
183
|
+
try {
|
|
184
|
+
prevFingerprint = JSON.parse((0, node_fs.readFileSync)(generatedPath, "utf-8"))?.fingerprintSha256 ?? null;
|
|
185
|
+
} catch {}
|
|
186
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(generatedPath), { recursive: true });
|
|
187
|
+
writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\n`);
|
|
188
|
+
const generatedChanged = prevFingerprint !== nextGenerated.fingerprintSha256;
|
|
189
|
+
return {
|
|
190
|
+
mode,
|
|
191
|
+
hostMode: opts.hostMode,
|
|
192
|
+
bosConfigChanged,
|
|
193
|
+
catalogChanged,
|
|
194
|
+
generatedChanged,
|
|
195
|
+
resolved
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
//#endregion
|
|
200
|
+
exports.syncResolvedSharedDeps = syncResolvedSharedDeps;
|
|
201
|
+
//# sourceMappingURL=shared-deps.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-deps.cjs","names":["isPlainObject","SharedDepMapSchema","rebuildOrderedConfig"],"sources":["../src/shared-deps.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { type BosEnv, isPlainObject, type ResolvedConfigMeta, rebuildOrderedConfig } from \"./merge\";\nimport { type SharedDepConfig, SharedDepMapSchema } from \"./types\";\n\ninterface PackageJson {\n workspaces?: {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n}\n\ninterface SharedDepRef {\n source: string;\n config: SharedDepConfig;\n}\n\ntype SharedDepsConfig = Record<string, unknown>;\n\ninterface NormalizedSharedDepConfig {\n version: string;\n requiredVersion: string | false;\n singleton: boolean;\n eager: boolean;\n strictVersion: boolean;\n shareScope: string;\n}\n\nexport interface ResolvedSharedDep {\n name: string;\n version: string;\n requiredVersion: string;\n shareScope: string;\n singleton: boolean;\n eager: boolean;\n strictVersion: boolean;\n sources: string[];\n}\n\nexport interface ResolvedSharedDeps {\n deps: Record<string, ResolvedSharedDep>;\n fingerprintSha256: string;\n}\n\nexport interface SharedDepsSyncResult {\n mode: \"catalog->bos\" | \"bos->catalog\";\n hostMode: \"local\" | \"remote\";\n bosConfigChanged: boolean;\n catalogChanged: boolean;\n generatedChanged: boolean;\n resolved: ResolvedSharedDeps;\n}\n\nfunction sha256(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction extractSemverExact(input: unknown): string | null {\n if (typeof input !== \"string\") return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction caretRange(version: string): string {\n return `^${version}`;\n}\n\nfunction stableDepsObject(\n deps: Record<string, ResolvedSharedDep>,\n): Record<string, ResolvedSharedDep> {\n const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));\n const out: Record<string, ResolvedSharedDep> = {};\n for (const key of keys) {\n out[key] = deps[key]!;\n }\n return out;\n}\n\nfunction normalizeSharedDepConfig(config: SharedDepConfig): NormalizedSharedDepConfig {\n return {\n version: config.version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n eager: config.eager ?? false,\n strictVersion: config.strictVersion ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nfunction getObject(value: unknown): Record<string, unknown> | undefined {\n return isPlainObject(value) ? value : undefined;\n}\n\nfunction getSharedDepsMap(\n value: unknown,\n source: string,\n): Record<string, SharedDepConfig> | undefined {\n if (value === undefined) return undefined;\n const parsed = SharedDepMapSchema.safeParse(value);\n if (!parsed.success) {\n throw new Error(`Invalid shared dependency map at ${source}`);\n }\n return value as Record<string, SharedDepConfig>;\n}\n\nfunction writeFileIfChanged(filePath: string, nextContent: string): boolean {\n try {\n const current = readFileSync(filePath, \"utf-8\");\n if (current === nextContent) return false;\n } catch {\n // file does not exist yet\n }\n\n writeFileSync(filePath, nextContent);\n return true;\n}\n\nfunction fingerprintResolved(deps: Record<string, ResolvedSharedDep>): string {\n return sha256(JSON.stringify(stableDepsObject(deps)));\n}\n\nfunction isSameSharedDepConfig(a: SharedDepConfig, b: SharedDepConfig): boolean {\n const left = normalizeSharedDepConfig(a);\n const right = normalizeSharedDepConfig(b);\n\n return (\n left.version === right.version &&\n left.requiredVersion === right.requiredVersion &&\n left.singleton === right.singleton &&\n left.eager === right.eager &&\n left.strictVersion === right.strictVersion &&\n left.shareScope === right.shareScope\n );\n}\n\nfunction collectSharedDepRefs(bosConfig: SharedDepsConfig): Record<string, SharedDepRef[]> {\n const refs = new Map<string, SharedDepRef[]>();\n\n const app = getObject(bosConfig.app);\n const appUi = getObject(app?.ui);\n const appApi = getObject(app?.api);\n const appAuth = getObject(app?.auth);\n const plugins = getObject(bosConfig.plugins);\n\n if (appUi && \"shared\" in appUi) {\n throw new Error(\n \"app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.\",\n );\n }\n\n const append = (source: string, shared: Record<string, SharedDepConfig> | undefined) => {\n if (!shared) return;\n\n for (const [name, config] of Object.entries(shared)) {\n const existing = refs.get(name);\n if (!existing) {\n refs.set(name, [{ source, config }]);\n continue;\n }\n\n if (!isSameSharedDepConfig(existing[0]!.config, config)) {\n const previous = existing.map((ref) => ref.source).join(\", \");\n throw new Error(\n `Conflicting shared dependency \"${name}\" between ${previous} and ${source}`,\n );\n }\n\n existing.push({ source, config });\n }\n };\n\n append(\"app.api\", getSharedDepsMap(appApi?.shared, \"app.api.shared\"));\n append(\"app.auth\", getSharedDepsMap(appAuth?.shared, \"app.auth.shared\"));\n\n for (const [pluginId, plugin] of Object.entries(plugins ?? {})) {\n const pluginRecord = getObject(plugin);\n if (!pluginRecord) continue;\n\n const pluginApp = getObject(pluginRecord.app);\n const pluginUi = getObject(pluginApp?.ui);\n if (pluginUi && \"shared\" in pluginUi) {\n throw new Error(\n `app.ui.shared is no longer supported in plugins.${pluginId}. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.`,\n );\n }\n append(\n `plugins.${pluginId}`,\n getSharedDepsMap(pluginRecord.shared, `plugins.${pluginId}.shared`),\n );\n }\n\n return Object.fromEntries(refs);\n}\n\nexport async function syncResolvedSharedDeps(opts: {\n configDir: string;\n hostMode: \"local\" | \"remote\";\n bosConfig?: SharedDepsConfig;\n env?: BosEnv;\n extendsChain?: string[];\n}): Promise<SharedDepsSyncResult> {\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n const resolvedConfigPath = join(opts.configDir, \".bos\", \"bos.resolved-config.json\");\n const packageJsonPath = join(opts.configDir, \"package.json\");\n const generatedPath = join(opts.configDir, \".bos\", \"generated\", \"shared-deps.json\");\n\n const bosConfig: unknown = opts.bosConfig ?? JSON.parse(readFileSync(bosConfigPath, \"utf-8\"));\n if (!isPlainObject(bosConfig)) {\n throw new Error(\"bos.config.json must be an object\");\n }\n\n const pkgJson = existsSync(packageJsonPath)\n ? (JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as PackageJson)\n : {};\n\n const originalBos = JSON.stringify(bosConfig);\n const originalPkg = JSON.stringify(pkgJson);\n\n const mode = opts.hostMode === \"local\" ? \"catalog->bos\" : \"bos->catalog\";\n const refsByName = collectSharedDepRefs(bosConfig);\n const catalog = pkgJson.workspaces?.catalog ?? {};\n\n const resolvedDeps: Record<string, ResolvedSharedDep> = {};\n\n for (const [name, refs] of Object.entries(refsByName)) {\n const first = refs[0];\n if (!first) continue;\n\n const exactFromConfig =\n extractSemverExact(first.config.version) ?? extractSemverExact(first.config.requiredVersion);\n const exactFromCatalog = extractSemverExact(catalog[name]);\n const version =\n mode === \"catalog->bos\"\n ? (exactFromCatalog ?? exactFromConfig)\n : (exactFromConfig ?? exactFromCatalog);\n\n if (!version) {\n const sources = refs.map((ref) => ref.source).join(\", \");\n throw new Error(\n `Could not resolve exact version for shared dependency \"${name}\" from ${sources}`,\n );\n }\n\n if (mode === \"catalog->bos\" && exactFromCatalog === null && exactFromConfig) {\n catalog[name] = exactFromConfig;\n }\n\n if (mode === \"bos->catalog\" && catalog[name] !== version) {\n catalog[name] = version;\n }\n\n for (const ref of refs) {\n ref.config.version = version;\n ref.config.requiredVersion = caretRange(version);\n ref.config.shareScope = ref.config.shareScope ?? \"default\";\n }\n\n resolvedDeps[name] = {\n name,\n version,\n requiredVersion: caretRange(version),\n shareScope: first.config.shareScope ?? \"default\",\n singleton: first.config.singleton ?? false,\n eager: first.config.eager ?? false,\n strictVersion: first.config.strictVersion ?? false,\n sources: refs.map((ref) => ref.source).sort((a, b) => a.localeCompare(b)),\n };\n }\n\n if (!pkgJson.workspaces) {\n pkgJson.workspaces = { packages: [], catalog: {} };\n }\n pkgJson.workspaces.catalog = catalog;\n\n const nextBos = JSON.stringify(bosConfig);\n const nextPkg = JSON.stringify(pkgJson);\n const bosConfigChanged = nextBos !== originalBos;\n const catalogChanged = nextPkg !== originalPkg;\n\n if (bosConfigChanged) {\n const resolvedDir = dirname(resolvedConfigPath);\n if (!existsSync(resolvedDir)) {\n mkdirSync(resolvedDir, { recursive: true });\n }\n\n const ordered = rebuildOrderedConfig(bosConfig);\n const meta: ResolvedConfigMeta = {\n env: opts.env ?? \"development\",\n resolvedAt: new Date().toISOString(),\n extendsChain: opts.extendsChain ?? [],\n source: \"shared-sync\",\n };\n const resolvedOutput = {\n _resolved: meta,\n ...ordered,\n };\n\n writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\\n`);\n }\n\n if (catalogChanged) {\n writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\\n`);\n }\n\n const stableResolvedDeps = stableDepsObject(resolvedDeps);\n const resolved: ResolvedSharedDeps = {\n deps: stableResolvedDeps,\n fingerprintSha256: fingerprintResolved(stableResolvedDeps),\n };\n\n const nextGenerated = {\n schemaVersion: 1,\n kind: \"everything-dev/shared-deps\",\n generatedAt: new Date().toISOString(),\n deps: stableResolvedDeps,\n fingerprintSha256: resolved.fingerprintSha256,\n inputs: {\n mode,\n hostMode: opts.hostMode,\n },\n };\n\n let prevFingerprint: string | null = null;\n try {\n const prev = JSON.parse(readFileSync(generatedPath, \"utf-8\"));\n prevFingerprint = prev?.fingerprintSha256 ?? null;\n } catch {\n // ignore\n }\n\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\\n`);\n\n const generatedChanged = prevFingerprint !== nextGenerated.fingerprintSha256;\n\n return {\n mode,\n hostMode: opts.hostMode,\n bosConfigChanged,\n catalogChanged,\n generatedChanged,\n resolved,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { isPlainObject, rebuildOrderedConfig } from "./merge.mjs";
|
|
2
|
+
import { SharedDepMapSchema } from "./types.mjs";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
|
|
7
|
+
//#region src/shared-deps.ts
|
|
8
|
+
function sha256(input) {
|
|
9
|
+
return createHash("sha256").update(input).digest("hex");
|
|
10
|
+
}
|
|
11
|
+
function extractSemverExact(input) {
|
|
12
|
+
if (typeof input !== "string") return null;
|
|
13
|
+
const match = input.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
14
|
+
return match ? match[0] : null;
|
|
15
|
+
}
|
|
16
|
+
function caretRange(version) {
|
|
17
|
+
return `^${version}`;
|
|
18
|
+
}
|
|
19
|
+
function stableDepsObject(deps) {
|
|
20
|
+
const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const key of keys) out[key] = deps[key];
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function normalizeSharedDepConfig(config) {
|
|
26
|
+
return {
|
|
27
|
+
version: config.version,
|
|
28
|
+
requiredVersion: config.requiredVersion ?? false,
|
|
29
|
+
singleton: config.singleton ?? false,
|
|
30
|
+
eager: config.eager ?? false,
|
|
31
|
+
strictVersion: config.strictVersion ?? false,
|
|
32
|
+
shareScope: config.shareScope ?? "default"
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getObject(value) {
|
|
36
|
+
return isPlainObject(value) ? value : void 0;
|
|
37
|
+
}
|
|
38
|
+
function getSharedDepsMap(value, source) {
|
|
39
|
+
if (value === void 0) return void 0;
|
|
40
|
+
if (!SharedDepMapSchema.safeParse(value).success) throw new Error(`Invalid shared dependency map at ${source}`);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function writeFileIfChanged(filePath, nextContent) {
|
|
44
|
+
try {
|
|
45
|
+
if (readFileSync(filePath, "utf-8") === nextContent) return false;
|
|
46
|
+
} catch {}
|
|
47
|
+
writeFileSync(filePath, nextContent);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
function fingerprintResolved(deps) {
|
|
51
|
+
return sha256(JSON.stringify(stableDepsObject(deps)));
|
|
52
|
+
}
|
|
53
|
+
function isSameSharedDepConfig(a, b) {
|
|
54
|
+
const left = normalizeSharedDepConfig(a);
|
|
55
|
+
const right = normalizeSharedDepConfig(b);
|
|
56
|
+
return left.version === right.version && left.requiredVersion === right.requiredVersion && left.singleton === right.singleton && left.eager === right.eager && left.strictVersion === right.strictVersion && left.shareScope === right.shareScope;
|
|
57
|
+
}
|
|
58
|
+
function collectSharedDepRefs(bosConfig) {
|
|
59
|
+
const refs = /* @__PURE__ */ new Map();
|
|
60
|
+
const app = getObject(bosConfig.app);
|
|
61
|
+
const appUi = getObject(app?.ui);
|
|
62
|
+
const appApi = getObject(app?.api);
|
|
63
|
+
const appAuth = getObject(app?.auth);
|
|
64
|
+
const plugins = getObject(bosConfig.plugins);
|
|
65
|
+
if (appUi && "shared" in appUi) throw new Error("app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.");
|
|
66
|
+
const append = (source, shared) => {
|
|
67
|
+
if (!shared) return;
|
|
68
|
+
for (const [name, config] of Object.entries(shared)) {
|
|
69
|
+
const existing = refs.get(name);
|
|
70
|
+
if (!existing) {
|
|
71
|
+
refs.set(name, [{
|
|
72
|
+
source,
|
|
73
|
+
config
|
|
74
|
+
}]);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!isSameSharedDepConfig(existing[0].config, config)) {
|
|
78
|
+
const previous = existing.map((ref) => ref.source).join(", ");
|
|
79
|
+
throw new Error(`Conflicting shared dependency "${name}" between ${previous} and ${source}`);
|
|
80
|
+
}
|
|
81
|
+
existing.push({
|
|
82
|
+
source,
|
|
83
|
+
config
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
append("app.api", getSharedDepsMap(appApi?.shared, "app.api.shared"));
|
|
88
|
+
append("app.auth", getSharedDepsMap(appAuth?.shared, "app.auth.shared"));
|
|
89
|
+
for (const [pluginId, plugin] of Object.entries(plugins ?? {})) {
|
|
90
|
+
const pluginRecord = getObject(plugin);
|
|
91
|
+
if (!pluginRecord) continue;
|
|
92
|
+
const pluginUi = getObject(getObject(pluginRecord.app)?.ui);
|
|
93
|
+
if (pluginUi && "shared" in pluginUi) throw new Error(`app.ui.shared is no longer supported in plugins.${pluginId}. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.`);
|
|
94
|
+
append(`plugins.${pluginId}`, getSharedDepsMap(pluginRecord.shared, `plugins.${pluginId}.shared`));
|
|
95
|
+
}
|
|
96
|
+
return Object.fromEntries(refs);
|
|
97
|
+
}
|
|
98
|
+
async function syncResolvedSharedDeps(opts) {
|
|
99
|
+
const bosConfigPath = join(opts.configDir, "bos.config.json");
|
|
100
|
+
const resolvedConfigPath = join(opts.configDir, ".bos", "bos.resolved-config.json");
|
|
101
|
+
const packageJsonPath = join(opts.configDir, "package.json");
|
|
102
|
+
const generatedPath = join(opts.configDir, ".bos", "generated", "shared-deps.json");
|
|
103
|
+
const bosConfig = opts.bosConfig ?? JSON.parse(readFileSync(bosConfigPath, "utf-8"));
|
|
104
|
+
if (!isPlainObject(bosConfig)) throw new Error("bos.config.json must be an object");
|
|
105
|
+
const pkgJson = existsSync(packageJsonPath) ? JSON.parse(readFileSync(packageJsonPath, "utf-8")) : {};
|
|
106
|
+
const originalBos = JSON.stringify(bosConfig);
|
|
107
|
+
const originalPkg = JSON.stringify(pkgJson);
|
|
108
|
+
const mode = opts.hostMode === "local" ? "catalog->bos" : "bos->catalog";
|
|
109
|
+
const refsByName = collectSharedDepRefs(bosConfig);
|
|
110
|
+
const catalog = pkgJson.workspaces?.catalog ?? {};
|
|
111
|
+
const resolvedDeps = {};
|
|
112
|
+
for (const [name, refs] of Object.entries(refsByName)) {
|
|
113
|
+
const first = refs[0];
|
|
114
|
+
if (!first) continue;
|
|
115
|
+
const exactFromConfig = extractSemverExact(first.config.version) ?? extractSemverExact(first.config.requiredVersion);
|
|
116
|
+
const exactFromCatalog = extractSemverExact(catalog[name]);
|
|
117
|
+
const version = mode === "catalog->bos" ? exactFromCatalog ?? exactFromConfig : exactFromConfig ?? exactFromCatalog;
|
|
118
|
+
if (!version) {
|
|
119
|
+
const sources = refs.map((ref) => ref.source).join(", ");
|
|
120
|
+
throw new Error(`Could not resolve exact version for shared dependency "${name}" from ${sources}`);
|
|
121
|
+
}
|
|
122
|
+
if (mode === "catalog->bos" && exactFromCatalog === null && exactFromConfig) catalog[name] = exactFromConfig;
|
|
123
|
+
if (mode === "bos->catalog" && catalog[name] !== version) catalog[name] = version;
|
|
124
|
+
for (const ref of refs) {
|
|
125
|
+
ref.config.version = version;
|
|
126
|
+
ref.config.requiredVersion = caretRange(version);
|
|
127
|
+
ref.config.shareScope = ref.config.shareScope ?? "default";
|
|
128
|
+
}
|
|
129
|
+
resolvedDeps[name] = {
|
|
130
|
+
name,
|
|
131
|
+
version,
|
|
132
|
+
requiredVersion: caretRange(version),
|
|
133
|
+
shareScope: first.config.shareScope ?? "default",
|
|
134
|
+
singleton: first.config.singleton ?? false,
|
|
135
|
+
eager: first.config.eager ?? false,
|
|
136
|
+
strictVersion: first.config.strictVersion ?? false,
|
|
137
|
+
sources: refs.map((ref) => ref.source).sort((a, b) => a.localeCompare(b))
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (!pkgJson.workspaces) pkgJson.workspaces = {
|
|
141
|
+
packages: [],
|
|
142
|
+
catalog: {}
|
|
143
|
+
};
|
|
144
|
+
pkgJson.workspaces.catalog = catalog;
|
|
145
|
+
const nextBos = JSON.stringify(bosConfig);
|
|
146
|
+
const nextPkg = JSON.stringify(pkgJson);
|
|
147
|
+
const bosConfigChanged = nextBos !== originalBos;
|
|
148
|
+
const catalogChanged = nextPkg !== originalPkg;
|
|
149
|
+
if (bosConfigChanged) {
|
|
150
|
+
const resolvedDir = dirname(resolvedConfigPath);
|
|
151
|
+
if (!existsSync(resolvedDir)) mkdirSync(resolvedDir, { recursive: true });
|
|
152
|
+
const ordered = rebuildOrderedConfig(bosConfig);
|
|
153
|
+
const resolvedOutput = {
|
|
154
|
+
_resolved: {
|
|
155
|
+
env: opts.env ?? "development",
|
|
156
|
+
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
157
|
+
extendsChain: opts.extendsChain ?? [],
|
|
158
|
+
source: "shared-sync"
|
|
159
|
+
},
|
|
160
|
+
...ordered
|
|
161
|
+
};
|
|
162
|
+
writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\n`);
|
|
163
|
+
}
|
|
164
|
+
if (catalogChanged) writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`);
|
|
165
|
+
const stableResolvedDeps = stableDepsObject(resolvedDeps);
|
|
166
|
+
const resolved = {
|
|
167
|
+
deps: stableResolvedDeps,
|
|
168
|
+
fingerprintSha256: fingerprintResolved(stableResolvedDeps)
|
|
169
|
+
};
|
|
170
|
+
const nextGenerated = {
|
|
171
|
+
schemaVersion: 1,
|
|
172
|
+
kind: "everything-dev/shared-deps",
|
|
173
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
174
|
+
deps: stableResolvedDeps,
|
|
175
|
+
fingerprintSha256: resolved.fingerprintSha256,
|
|
176
|
+
inputs: {
|
|
177
|
+
mode,
|
|
178
|
+
hostMode: opts.hostMode
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
let prevFingerprint = null;
|
|
182
|
+
try {
|
|
183
|
+
prevFingerprint = JSON.parse(readFileSync(generatedPath, "utf-8"))?.fingerprintSha256 ?? null;
|
|
184
|
+
} catch {}
|
|
185
|
+
mkdirSync(dirname(generatedPath), { recursive: true });
|
|
186
|
+
writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\n`);
|
|
187
|
+
const generatedChanged = prevFingerprint !== nextGenerated.fingerprintSha256;
|
|
188
|
+
return {
|
|
189
|
+
mode,
|
|
190
|
+
hostMode: opts.hostMode,
|
|
191
|
+
bosConfigChanged,
|
|
192
|
+
catalogChanged,
|
|
193
|
+
generatedChanged,
|
|
194
|
+
resolved
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//#endregion
|
|
199
|
+
export { syncResolvedSharedDeps };
|
|
200
|
+
//# sourceMappingURL=shared-deps.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-deps.mjs","names":[],"sources":["../src/shared-deps.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { type BosEnv, isPlainObject, type ResolvedConfigMeta, rebuildOrderedConfig } from \"./merge\";\nimport { type SharedDepConfig, SharedDepMapSchema } from \"./types\";\n\ninterface PackageJson {\n workspaces?: {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n}\n\ninterface SharedDepRef {\n source: string;\n config: SharedDepConfig;\n}\n\ntype SharedDepsConfig = Record<string, unknown>;\n\ninterface NormalizedSharedDepConfig {\n version: string;\n requiredVersion: string | false;\n singleton: boolean;\n eager: boolean;\n strictVersion: boolean;\n shareScope: string;\n}\n\nexport interface ResolvedSharedDep {\n name: string;\n version: string;\n requiredVersion: string;\n shareScope: string;\n singleton: boolean;\n eager: boolean;\n strictVersion: boolean;\n sources: string[];\n}\n\nexport interface ResolvedSharedDeps {\n deps: Record<string, ResolvedSharedDep>;\n fingerprintSha256: string;\n}\n\nexport interface SharedDepsSyncResult {\n mode: \"catalog->bos\" | \"bos->catalog\";\n hostMode: \"local\" | \"remote\";\n bosConfigChanged: boolean;\n catalogChanged: boolean;\n generatedChanged: boolean;\n resolved: ResolvedSharedDeps;\n}\n\nfunction sha256(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction extractSemverExact(input: unknown): string | null {\n if (typeof input !== \"string\") return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction caretRange(version: string): string {\n return `^${version}`;\n}\n\nfunction stableDepsObject(\n deps: Record<string, ResolvedSharedDep>,\n): Record<string, ResolvedSharedDep> {\n const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));\n const out: Record<string, ResolvedSharedDep> = {};\n for (const key of keys) {\n out[key] = deps[key]!;\n }\n return out;\n}\n\nfunction normalizeSharedDepConfig(config: SharedDepConfig): NormalizedSharedDepConfig {\n return {\n version: config.version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n eager: config.eager ?? false,\n strictVersion: config.strictVersion ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nfunction getObject(value: unknown): Record<string, unknown> | undefined {\n return isPlainObject(value) ? value : undefined;\n}\n\nfunction getSharedDepsMap(\n value: unknown,\n source: string,\n): Record<string, SharedDepConfig> | undefined {\n if (value === undefined) return undefined;\n const parsed = SharedDepMapSchema.safeParse(value);\n if (!parsed.success) {\n throw new Error(`Invalid shared dependency map at ${source}`);\n }\n return value as Record<string, SharedDepConfig>;\n}\n\nfunction writeFileIfChanged(filePath: string, nextContent: string): boolean {\n try {\n const current = readFileSync(filePath, \"utf-8\");\n if (current === nextContent) return false;\n } catch {\n // file does not exist yet\n }\n\n writeFileSync(filePath, nextContent);\n return true;\n}\n\nfunction fingerprintResolved(deps: Record<string, ResolvedSharedDep>): string {\n return sha256(JSON.stringify(stableDepsObject(deps)));\n}\n\nfunction isSameSharedDepConfig(a: SharedDepConfig, b: SharedDepConfig): boolean {\n const left = normalizeSharedDepConfig(a);\n const right = normalizeSharedDepConfig(b);\n\n return (\n left.version === right.version &&\n left.requiredVersion === right.requiredVersion &&\n left.singleton === right.singleton &&\n left.eager === right.eager &&\n left.strictVersion === right.strictVersion &&\n left.shareScope === right.shareScope\n );\n}\n\nfunction collectSharedDepRefs(bosConfig: SharedDepsConfig): Record<string, SharedDepRef[]> {\n const refs = new Map<string, SharedDepRef[]>();\n\n const app = getObject(bosConfig.app);\n const appUi = getObject(app?.ui);\n const appApi = getObject(app?.api);\n const appAuth = getObject(app?.auth);\n const plugins = getObject(bosConfig.plugins);\n\n if (appUi && \"shared\" in appUi) {\n throw new Error(\n \"app.ui.shared is no longer supported. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.\",\n );\n }\n\n const append = (source: string, shared: Record<string, SharedDepConfig> | undefined) => {\n if (!shared) return;\n\n for (const [name, config] of Object.entries(shared)) {\n const existing = refs.get(name);\n if (!existing) {\n refs.set(name, [{ source, config }]);\n continue;\n }\n\n if (!isSameSharedDepConfig(existing[0]!.config, config)) {\n const previous = existing.map((ref) => ref.source).join(\", \");\n throw new Error(\n `Conflicting shared dependency \"${name}\" between ${previous} and ${source}`,\n );\n }\n\n existing.push({ source, config });\n }\n };\n\n append(\"app.api\", getSharedDepsMap(appApi?.shared, \"app.api.shared\"));\n append(\"app.auth\", getSharedDepsMap(appAuth?.shared, \"app.auth.shared\"));\n\n for (const [pluginId, plugin] of Object.entries(plugins ?? {})) {\n const pluginRecord = getObject(plugin);\n if (!pluginRecord) continue;\n\n const pluginApp = getObject(pluginRecord.app);\n const pluginUi = getObject(pluginApp?.ui);\n if (pluginUi && \"shared\" in pluginUi) {\n throw new Error(\n `app.ui.shared is no longer supported in plugins.${pluginId}. Move shared deps to app.api.shared, app.auth.shared, or plugins.*.shared.`,\n );\n }\n append(\n `plugins.${pluginId}`,\n getSharedDepsMap(pluginRecord.shared, `plugins.${pluginId}.shared`),\n );\n }\n\n return Object.fromEntries(refs);\n}\n\nexport async function syncResolvedSharedDeps(opts: {\n configDir: string;\n hostMode: \"local\" | \"remote\";\n bosConfig?: SharedDepsConfig;\n env?: BosEnv;\n extendsChain?: string[];\n}): Promise<SharedDepsSyncResult> {\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n const resolvedConfigPath = join(opts.configDir, \".bos\", \"bos.resolved-config.json\");\n const packageJsonPath = join(opts.configDir, \"package.json\");\n const generatedPath = join(opts.configDir, \".bos\", \"generated\", \"shared-deps.json\");\n\n const bosConfig: unknown = opts.bosConfig ?? JSON.parse(readFileSync(bosConfigPath, \"utf-8\"));\n if (!isPlainObject(bosConfig)) {\n throw new Error(\"bos.config.json must be an object\");\n }\n\n const pkgJson = existsSync(packageJsonPath)\n ? (JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as PackageJson)\n : {};\n\n const originalBos = JSON.stringify(bosConfig);\n const originalPkg = JSON.stringify(pkgJson);\n\n const mode = opts.hostMode === \"local\" ? \"catalog->bos\" : \"bos->catalog\";\n const refsByName = collectSharedDepRefs(bosConfig);\n const catalog = pkgJson.workspaces?.catalog ?? {};\n\n const resolvedDeps: Record<string, ResolvedSharedDep> = {};\n\n for (const [name, refs] of Object.entries(refsByName)) {\n const first = refs[0];\n if (!first) continue;\n\n const exactFromConfig =\n extractSemverExact(first.config.version) ?? extractSemverExact(first.config.requiredVersion);\n const exactFromCatalog = extractSemverExact(catalog[name]);\n const version =\n mode === \"catalog->bos\"\n ? (exactFromCatalog ?? exactFromConfig)\n : (exactFromConfig ?? exactFromCatalog);\n\n if (!version) {\n const sources = refs.map((ref) => ref.source).join(\", \");\n throw new Error(\n `Could not resolve exact version for shared dependency \"${name}\" from ${sources}`,\n );\n }\n\n if (mode === \"catalog->bos\" && exactFromCatalog === null && exactFromConfig) {\n catalog[name] = exactFromConfig;\n }\n\n if (mode === \"bos->catalog\" && catalog[name] !== version) {\n catalog[name] = version;\n }\n\n for (const ref of refs) {\n ref.config.version = version;\n ref.config.requiredVersion = caretRange(version);\n ref.config.shareScope = ref.config.shareScope ?? \"default\";\n }\n\n resolvedDeps[name] = {\n name,\n version,\n requiredVersion: caretRange(version),\n shareScope: first.config.shareScope ?? \"default\",\n singleton: first.config.singleton ?? false,\n eager: first.config.eager ?? false,\n strictVersion: first.config.strictVersion ?? false,\n sources: refs.map((ref) => ref.source).sort((a, b) => a.localeCompare(b)),\n };\n }\n\n if (!pkgJson.workspaces) {\n pkgJson.workspaces = { packages: [], catalog: {} };\n }\n pkgJson.workspaces.catalog = catalog;\n\n const nextBos = JSON.stringify(bosConfig);\n const nextPkg = JSON.stringify(pkgJson);\n const bosConfigChanged = nextBos !== originalBos;\n const catalogChanged = nextPkg !== originalPkg;\n\n if (bosConfigChanged) {\n const resolvedDir = dirname(resolvedConfigPath);\n if (!existsSync(resolvedDir)) {\n mkdirSync(resolvedDir, { recursive: true });\n }\n\n const ordered = rebuildOrderedConfig(bosConfig);\n const meta: ResolvedConfigMeta = {\n env: opts.env ?? \"development\",\n resolvedAt: new Date().toISOString(),\n extendsChain: opts.extendsChain ?? [],\n source: \"shared-sync\",\n };\n const resolvedOutput = {\n _resolved: meta,\n ...ordered,\n };\n\n writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\\n`);\n }\n\n if (catalogChanged) {\n writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\\n`);\n }\n\n const stableResolvedDeps = stableDepsObject(resolvedDeps);\n const resolved: ResolvedSharedDeps = {\n deps: stableResolvedDeps,\n fingerprintSha256: fingerprintResolved(stableResolvedDeps),\n };\n\n const nextGenerated = {\n schemaVersion: 1,\n kind: \"everything-dev/shared-deps\",\n generatedAt: new Date().toISOString(),\n deps: stableResolvedDeps,\n fingerprintSha256: resolved.fingerprintSha256,\n inputs: {\n mode,\n hostMode: opts.hostMode,\n },\n };\n\n let prevFingerprint: string | null = null;\n try {\n const prev = JSON.parse(readFileSync(generatedPath, \"utf-8\"));\n prevFingerprint = prev?.fingerprintSha256 ?? null;\n } catch {\n // ignore\n }\n\n mkdirSync(dirname(generatedPath), { recursive: true });\n writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\\n`);\n\n const generatedChanged = prevFingerprint !== nextGenerated.fingerprintSha256;\n\n return {\n mode,\n hostMode: opts.hostMode,\n bosConfigChanged,\n catalogChanged,\n generatedChanged,\n resolved,\n };\n}\n"],"mappings":"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"}
|
package/dist/types.cjs
CHANGED
|
@@ -28,6 +28,7 @@ const SharedConfigSchema = zod.object({
|
|
|
28
28
|
shareScope: zod.string().optional()
|
|
29
29
|
});
|
|
30
30
|
const SharedDepConfigSchema = SharedConfigSchema;
|
|
31
|
+
const SharedDepMapSchema = zod.record(zod.string(), SharedConfigSchema);
|
|
31
32
|
const FederationEntrySchema = zod.object({
|
|
32
33
|
name: zod.string(),
|
|
33
34
|
url: zod.string(),
|
|
@@ -56,7 +57,8 @@ const ComposableAppEntrySchema = zod.object({
|
|
|
56
57
|
variables: JsonObjectSchema.optional(),
|
|
57
58
|
secrets: zod.array(zod.string()).optional(),
|
|
58
59
|
sidebar: zod.array(SidebarItemSchema).optional(),
|
|
59
|
-
routes: zod.array(zod.string()).optional()
|
|
60
|
+
routes: zod.array(zod.string()).optional(),
|
|
61
|
+
shared: SharedDepMapSchema.optional()
|
|
60
62
|
});
|
|
61
63
|
const ApiPluginConfigSchema = ComposableAppEntrySchema;
|
|
62
64
|
const PluginUiConfigSchema = zod.object({
|
|
@@ -68,7 +70,6 @@ const PluginUiConfigSchema = zod.object({
|
|
|
68
70
|
const BosPluginRefSchema = ComposableAppEntrySchema.extend({
|
|
69
71
|
version: zod.string().optional(),
|
|
70
72
|
app: zod.record(zod.string(), zod.unknown()).optional(),
|
|
71
|
-
shared: zod.record(zod.string(), zod.record(zod.string(), SharedConfigSchema)).optional(),
|
|
72
73
|
plugins: zod.record(zod.string(), zod.unknown()).optional()
|
|
73
74
|
});
|
|
74
75
|
const PluginRuntimeUiSchema = zod.object({
|
|
@@ -91,6 +92,7 @@ const RuntimePluginConfigSchema = zod.object({
|
|
|
91
92
|
variables: JsonObjectSchema.optional(),
|
|
92
93
|
secrets: zod.array(zod.string()).optional(),
|
|
93
94
|
integrity: zod.string().optional(),
|
|
95
|
+
shared: SharedDepMapSchema.optional(),
|
|
94
96
|
ui: PluginRuntimeUiSchema.optional(),
|
|
95
97
|
sidebar: zod.array(SidebarItemSchema).optional(),
|
|
96
98
|
routes: zod.array(zod.string()).optional()
|
|
@@ -102,7 +104,7 @@ const UiConfigSchema = zod.object({
|
|
|
102
104
|
integrity: zod.string().optional(),
|
|
103
105
|
ssr: zod.string().optional(),
|
|
104
106
|
ssrIntegrity: zod.string().optional()
|
|
105
|
-
});
|
|
107
|
+
}).strict();
|
|
106
108
|
const HostConfigSchema = zod.object({
|
|
107
109
|
development: zod.string(),
|
|
108
110
|
production: zod.string(),
|
|
@@ -147,7 +149,6 @@ const BosConfigInputSchema = zod.lazy(() => zod.object({
|
|
|
147
149
|
routes: zod.array(zod.string()).optional(),
|
|
148
150
|
sidebar: zod.array(SidebarItemSchema).optional(),
|
|
149
151
|
app: zod.record(zod.string(), BosConfigInputAppEntrySchema).optional(),
|
|
150
|
-
shared: zod.record(zod.string(), zod.record(zod.string(), SharedConfigSchema)).optional(),
|
|
151
152
|
plugins: zod.record(zod.string(), zod.union([zod.string(), BosConfigInputSchema])).optional(),
|
|
152
153
|
ci: CiConfigSchema.optional()
|
|
153
154
|
}));
|
|
@@ -163,7 +164,6 @@ const BosConfigSchema = zod.object({
|
|
|
163
164
|
staging: BosStagingSchema.optional(),
|
|
164
165
|
repository: zod.string().optional(),
|
|
165
166
|
ci: CiConfigSchema.optional(),
|
|
166
|
-
shared: zod.record(zod.string(), zod.record(zod.string(), SharedConfigSchema)).optional(),
|
|
167
167
|
plugins: zod.record(zod.string(), zod.union([zod.string(), BosPluginRefSchema])).optional(),
|
|
168
168
|
app: zod.object({
|
|
169
169
|
host: HostConfigSchema,
|
|
@@ -190,10 +190,6 @@ const RuntimeConfigSchema = zod.object({
|
|
|
190
190
|
secrets: zod.array(zod.string()).optional(),
|
|
191
191
|
remoteUrl: zod.string().optional()
|
|
192
192
|
}),
|
|
193
|
-
shared: zod.object({
|
|
194
|
-
ui: zod.record(zod.string(), SharedConfigSchema).optional(),
|
|
195
|
-
plugins: zod.record(zod.string(), SharedConfigSchema).optional()
|
|
196
|
-
}).optional(),
|
|
197
193
|
ui: FederationEntrySchema.extend({
|
|
198
194
|
localPath: zod.string().optional(),
|
|
199
195
|
port: zod.number().optional(),
|
|
@@ -205,7 +201,8 @@ const RuntimeConfigSchema = zod.object({
|
|
|
205
201
|
port: zod.number().optional(),
|
|
206
202
|
proxy: zod.string().optional(),
|
|
207
203
|
variables: JsonObjectSchema.optional(),
|
|
208
|
-
secrets: zod.array(zod.string()).optional()
|
|
204
|
+
secrets: zod.array(zod.string()).optional(),
|
|
205
|
+
shared: SharedDepMapSchema.optional()
|
|
209
206
|
}),
|
|
210
207
|
auth: FederationEntrySchema.extend({
|
|
211
208
|
localPath: zod.string().optional(),
|
|
@@ -213,7 +210,8 @@ const RuntimeConfigSchema = zod.object({
|
|
|
213
210
|
proxy: zod.string().optional(),
|
|
214
211
|
variables: JsonObjectSchema.optional(),
|
|
215
212
|
secrets: zod.array(zod.string()).optional(),
|
|
216
|
-
sidebar: zod.array(SidebarItemSchema).optional()
|
|
213
|
+
sidebar: zod.array(SidebarItemSchema).optional(),
|
|
214
|
+
shared: SharedDepMapSchema.optional()
|
|
217
215
|
}).optional(),
|
|
218
216
|
plugins: zod.record(zod.string(), RuntimePluginConfigSchema).optional()
|
|
219
217
|
});
|
|
@@ -242,13 +240,15 @@ const ClientRuntimeConfigSchema = zod.object({
|
|
|
242
240
|
name: zod.string(),
|
|
243
241
|
url: zod.string(),
|
|
244
242
|
entry: zod.string(),
|
|
245
|
-
integrity: zod.string().optional()
|
|
243
|
+
integrity: zod.string().optional(),
|
|
244
|
+
variables: JsonObjectSchema.optional()
|
|
246
245
|
}).optional(),
|
|
247
246
|
auth: zod.object({
|
|
248
247
|
name: zod.string(),
|
|
249
248
|
url: zod.string(),
|
|
250
249
|
entry: zod.string(),
|
|
251
250
|
integrity: zod.string().optional(),
|
|
251
|
+
variables: JsonObjectSchema.optional(),
|
|
252
252
|
sidebar: zod.array(SidebarItemSchema).optional()
|
|
253
253
|
}).optional(),
|
|
254
254
|
plugins: zod.record(zod.string(), zod.object({
|
|
@@ -256,6 +256,7 @@ const ClientRuntimeConfigSchema = zod.object({
|
|
|
256
256
|
url: zod.string(),
|
|
257
257
|
entry: zod.string(),
|
|
258
258
|
integrity: zod.string().optional(),
|
|
259
|
+
variables: JsonObjectSchema.optional(),
|
|
259
260
|
ui: zod.object({
|
|
260
261
|
name: zod.string(),
|
|
261
262
|
url: zod.string(),
|
|
@@ -289,6 +290,7 @@ exports.RuntimeLineageSchema = RuntimeLineageSchema;
|
|
|
289
290
|
exports.RuntimePluginConfigSchema = RuntimePluginConfigSchema;
|
|
290
291
|
exports.SharedConfigSchema = SharedConfigSchema;
|
|
291
292
|
exports.SharedDepConfigSchema = SharedDepConfigSchema;
|
|
293
|
+
exports.SharedDepMapSchema = SharedDepMapSchema;
|
|
292
294
|
exports.SidebarItemSchema = SidebarItemSchema;
|
|
293
295
|
exports.SidebarRoleSchema = SidebarRoleSchema;
|
|
294
296
|
exports.SourceModeSchema = SourceModeSchema;
|