everything-dev 1.27.0 → 1.28.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/cli/infra.cjs +1 -1
- package/dist/cli/infra.mjs +1 -1
- package/dist/cli/init.cjs +34 -9
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +2 -1
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +2 -1
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +34 -9
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/prompts.cjs +28 -24
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +27 -24
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/sync.cjs +40 -3
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +40 -3
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli.cjs +187 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +186 -11
- package/dist/cli.mjs.map +1 -1
- package/dist/config.cjs +1 -0
- 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 +1 -0
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +1 -1
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +38 -34
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +38 -34
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.mjs +1 -0
- package/dist/contract.mjs.map +1 -1
- package/dist/dev-session.cjs +0 -1
- package/dist/dev-session.mjs +1 -1
- package/dist/index.cjs +0 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +0 -1
- package/dist/near-cli.cjs +1 -1
- package/dist/near-cli.mjs +1 -1
- package/dist/orchestrator.cjs +1 -1
- package/dist/orchestrator.mjs +1 -1
- package/dist/plugin.cjs +183 -151
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +67 -34
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +66 -34
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +173 -142
- package/dist/plugin.mjs.map +1 -1
- package/dist/service-descriptor.d.cts +34 -0
- package/dist/service-descriptor.d.cts.map +1 -0
- package/dist/service-descriptor.d.mts +36 -0
- package/dist/service-descriptor.d.mts.map +1 -0
- package/dist/types.d.cts +2 -2
- package/dist/types.d.mts +2 -2
- package/dist/utils/run.cjs +9 -20
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs +9 -20
- package/dist/utils/run.mjs.map +1 -1
- package/package.json +2 -2
- package/src/api-contract.ts +0 -623
- package/src/app.ts +0 -193
- package/src/cli/catalog.ts +0 -49
- package/src/cli/framework-version.ts +0 -61
- package/src/cli/help.ts +0 -13
- package/src/cli/infra.ts +0 -190
- package/src/cli/init.ts +0 -1145
- package/src/cli/parse.ts +0 -147
- package/src/cli/prompts.ts +0 -135
- package/src/cli/snapshot.ts +0 -46
- package/src/cli/status.ts +0 -99
- package/src/cli/sync.ts +0 -429
- package/src/cli/timing.ts +0 -63
- package/src/cli/upgrade.ts +0 -869
- package/src/cli.ts +0 -516
- package/src/components/dev-view.tsx +0 -352
- package/src/components/streaming-view.ts +0 -177
- package/src/config.ts +0 -893
- package/src/contract.meta.ts +0 -140
- package/src/contract.ts +0 -326
- package/src/dev-logs.ts +0 -92
- package/src/dev-session.ts +0 -283
- package/src/fastkv.ts +0 -181
- package/src/index.ts +0 -8
- package/src/integrity.ts +0 -138
- package/src/internal/manifest-normalizer.ts +0 -290
- package/src/merge.ts +0 -187
- package/src/mf.ts +0 -147
- package/src/near-cli.ts +0 -259
- package/src/network.ts +0 -3
- package/src/orchestrator.ts +0 -493
- package/src/plugin.ts +0 -1799
- package/src/sdk.ts +0 -14
- package/src/service-descriptor.ts +0 -281
- package/src/shared.ts +0 -249
- package/src/sidebar.ts +0 -140
- package/src/types.ts +0 -330
- package/src/ui/head.ts +0 -83
- package/src/ui/index.ts +0 -5
- package/src/ui/metadata.ts +0 -95
- package/src/ui/router.ts +0 -88
- package/src/ui/runtime.ts +0 -42
- package/src/ui/types.ts +0 -65
- package/src/utils/banner.ts +0 -21
- package/src/utils/linkify.ts +0 -11
- package/src/utils/path-match.ts +0 -16
- package/src/utils/run.ts +0 -31
- package/src/utils/save-config.ts +0 -20
- package/src/utils/theme.ts +0 -39
package/src/sdk.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
createPlugin,
|
|
3
|
-
createPluginRuntime,
|
|
4
|
-
type LoadedPluginWithBinding,
|
|
5
|
-
type Plugin,
|
|
6
|
-
PluginRuntime,
|
|
7
|
-
} from "every-plugin";
|
|
8
|
-
export { Context, Effect, Layer, Scope } from "every-plugin/effect";
|
|
9
|
-
export {
|
|
10
|
-
type AnyContractRouter,
|
|
11
|
-
type AnySchema,
|
|
12
|
-
oc,
|
|
13
|
-
} from "every-plugin/orpc";
|
|
14
|
-
export { z } from "zod";
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import { Context, Layer } from "effect";
|
|
2
|
-
import type { RuntimeConfig, SourceMode } from "./types";
|
|
3
|
-
|
|
4
|
-
export interface ServiceDescriptor {
|
|
5
|
-
key: string;
|
|
6
|
-
source: SourceMode;
|
|
7
|
-
url: string;
|
|
8
|
-
remoteUrl?: string;
|
|
9
|
-
entry: string;
|
|
10
|
-
name: string;
|
|
11
|
-
localPath?: string;
|
|
12
|
-
port?: number;
|
|
13
|
-
readinessPath: string;
|
|
14
|
-
defaultPort: number;
|
|
15
|
-
integrity?: string;
|
|
16
|
-
proxy?: string;
|
|
17
|
-
variables?: Record<string, string>;
|
|
18
|
-
secrets?: string[];
|
|
19
|
-
ssr?: boolean;
|
|
20
|
-
command?: string;
|
|
21
|
-
args?: string[];
|
|
22
|
-
readyPatterns?: RegExp[];
|
|
23
|
-
errorPatterns?: RegExp[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class ServiceDescriptorMap extends Context.Tag("ServiceDescriptorMap")<
|
|
27
|
-
ServiceDescriptorMap,
|
|
28
|
-
Map<string, ServiceDescriptor>
|
|
29
|
-
>() {}
|
|
30
|
-
|
|
31
|
-
export class DevRuntimeConfig extends Context.Tag("DevRuntimeConfig")<
|
|
32
|
-
DevRuntimeConfig,
|
|
33
|
-
RuntimeConfig
|
|
34
|
-
>() {}
|
|
35
|
-
|
|
36
|
-
const PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];
|
|
37
|
-
|
|
38
|
-
const PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];
|
|
39
|
-
|
|
40
|
-
const SERVICE_CONFIGS: Record<
|
|
41
|
-
string,
|
|
42
|
-
Pick<
|
|
43
|
-
ServiceDescriptor,
|
|
44
|
-
"command" | "args" | "readyPatterns" | "errorPatterns" | "defaultPort" | "readinessPath"
|
|
45
|
-
>
|
|
46
|
-
> = {
|
|
47
|
-
host: {
|
|
48
|
-
command: "bun",
|
|
49
|
-
args: ["run", "dev"],
|
|
50
|
-
readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],
|
|
51
|
-
errorPatterns: [/error:/i, /failed/i, /exception/i],
|
|
52
|
-
defaultPort: 3000,
|
|
53
|
-
readinessPath: "/health",
|
|
54
|
-
},
|
|
55
|
-
auth: {
|
|
56
|
-
command: "bun",
|
|
57
|
-
args: ["run", "dev"],
|
|
58
|
-
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
59
|
-
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
60
|
-
defaultPort: 3002,
|
|
61
|
-
readinessPath: "/remoteEntry.js",
|
|
62
|
-
},
|
|
63
|
-
ui: {
|
|
64
|
-
command: "bun",
|
|
65
|
-
args: ["run", "dev"],
|
|
66
|
-
readyPatterns: [/\bready\s+built in\b/i, /\bLocal:\b/i, /\bcompiled\b.*successfully/i],
|
|
67
|
-
errorPatterns: [/error/i, /failed to compile/i],
|
|
68
|
-
defaultPort: 3003,
|
|
69
|
-
readinessPath: "/remoteEntry.js",
|
|
70
|
-
},
|
|
71
|
-
"ui-ssr": {
|
|
72
|
-
command: "bun",
|
|
73
|
-
args: ["run", "dev:ssr"],
|
|
74
|
-
readyPatterns: [/\bready\s+built in\b/i, /\bcompiled\b.*successfully/i],
|
|
75
|
-
errorPatterns: [/error/i, /failed/i],
|
|
76
|
-
defaultPort: 3004,
|
|
77
|
-
readinessPath: "/",
|
|
78
|
-
},
|
|
79
|
-
api: {
|
|
80
|
-
command: "bun",
|
|
81
|
-
args: ["run", "dev"],
|
|
82
|
-
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
83
|
-
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
84
|
-
defaultPort: 3001,
|
|
85
|
-
readinessPath: "/remoteEntry.js",
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export function buildServiceDescriptorMap(
|
|
90
|
-
runtimeConfig: RuntimeConfig,
|
|
91
|
-
options?: { ssr?: boolean; proxy?: boolean },
|
|
92
|
-
): Map<string, ServiceDescriptor> {
|
|
93
|
-
const map = new Map<string, ServiceDescriptor>();
|
|
94
|
-
const ssr = options?.ssr ?? false;
|
|
95
|
-
|
|
96
|
-
const hostIsRemote = runtimeConfig.host.source === "remote";
|
|
97
|
-
const hostProbeUrl = hostIsRemote
|
|
98
|
-
? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)
|
|
99
|
-
: runtimeConfig.host.url;
|
|
100
|
-
map.set("host", {
|
|
101
|
-
key: "host",
|
|
102
|
-
source: runtimeConfig.host.source,
|
|
103
|
-
url: hostProbeUrl,
|
|
104
|
-
remoteUrl: runtimeConfig.host.remoteUrl,
|
|
105
|
-
entry: hostIsRemote
|
|
106
|
-
? hostProbeUrl
|
|
107
|
-
? `${hostProbeUrl}/mf-manifest.json`
|
|
108
|
-
: "/mf-manifest.json"
|
|
109
|
-
: runtimeConfig.host.entry,
|
|
110
|
-
name: runtimeConfig.host.name,
|
|
111
|
-
localPath: runtimeConfig.host.localPath,
|
|
112
|
-
port: runtimeConfig.host.port,
|
|
113
|
-
integrity: runtimeConfig.host.integrity,
|
|
114
|
-
secrets: runtimeConfig.host.secrets,
|
|
115
|
-
...SERVICE_CONFIGS.host,
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
map.set("ui", {
|
|
119
|
-
key: "ui",
|
|
120
|
-
source: runtimeConfig.ui.source,
|
|
121
|
-
url: runtimeConfig.ui.url,
|
|
122
|
-
remoteUrl: runtimeConfig.ui.source === "remote" ? runtimeConfig.ui.url : undefined,
|
|
123
|
-
entry: runtimeConfig.ui.entry,
|
|
124
|
-
name: runtimeConfig.ui.name,
|
|
125
|
-
localPath: runtimeConfig.ui.localPath,
|
|
126
|
-
port: runtimeConfig.ui.port,
|
|
127
|
-
integrity: runtimeConfig.ui.integrity,
|
|
128
|
-
ssr,
|
|
129
|
-
...SERVICE_CONFIGS.ui,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
if (ssr && runtimeConfig.ui.source === "local") {
|
|
133
|
-
map.set("ui-ssr", {
|
|
134
|
-
key: "ui-ssr",
|
|
135
|
-
source: runtimeConfig.ui.source,
|
|
136
|
-
url: runtimeConfig.ui.ssrUrl ?? "",
|
|
137
|
-
entry: "",
|
|
138
|
-
name: "ui-ssr",
|
|
139
|
-
localPath: runtimeConfig.ui.localPath,
|
|
140
|
-
port: runtimeConfig.ui.ssrUrl
|
|
141
|
-
? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)
|
|
142
|
-
: (runtimeConfig.ui.port ?? 3003) + 1,
|
|
143
|
-
...SERVICE_CONFIGS["ui-ssr"],
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
map.set("api", {
|
|
148
|
-
key: "api",
|
|
149
|
-
source: runtimeConfig.api.source,
|
|
150
|
-
url: runtimeConfig.api.url,
|
|
151
|
-
remoteUrl: runtimeConfig.api.source === "remote" ? runtimeConfig.api.url : undefined,
|
|
152
|
-
entry: runtimeConfig.api.entry,
|
|
153
|
-
name: runtimeConfig.api.name,
|
|
154
|
-
localPath: runtimeConfig.api.localPath,
|
|
155
|
-
port: runtimeConfig.api.port,
|
|
156
|
-
integrity: runtimeConfig.api.integrity,
|
|
157
|
-
proxy: runtimeConfig.api.proxy,
|
|
158
|
-
variables: runtimeConfig.api.variables,
|
|
159
|
-
secrets: runtimeConfig.api.secrets,
|
|
160
|
-
...SERVICE_CONFIGS.api,
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
if (runtimeConfig.auth) {
|
|
164
|
-
map.set("auth", {
|
|
165
|
-
key: "auth",
|
|
166
|
-
source: runtimeConfig.auth.source,
|
|
167
|
-
url: runtimeConfig.auth.url,
|
|
168
|
-
remoteUrl: runtimeConfig.auth.source === "remote" ? runtimeConfig.auth.url : undefined,
|
|
169
|
-
entry: runtimeConfig.auth.entry,
|
|
170
|
-
name: runtimeConfig.auth.name,
|
|
171
|
-
localPath: runtimeConfig.auth.localPath,
|
|
172
|
-
port: runtimeConfig.auth.port,
|
|
173
|
-
integrity: runtimeConfig.auth.integrity,
|
|
174
|
-
proxy: runtimeConfig.auth.proxy,
|
|
175
|
-
variables: runtimeConfig.auth.variables,
|
|
176
|
-
secrets: runtimeConfig.auth.secrets,
|
|
177
|
-
...SERVICE_CONFIGS.auth,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (runtimeConfig.plugins) {
|
|
182
|
-
let pluginBasePort = 3010;
|
|
183
|
-
for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {
|
|
184
|
-
const pluginKey = `plugin:${pluginId}`;
|
|
185
|
-
const resolvedPort = pluginConfig.port ?? pluginBasePort;
|
|
186
|
-
pluginBasePort = resolvedPort + 1;
|
|
187
|
-
|
|
188
|
-
map.set(pluginKey, {
|
|
189
|
-
key: pluginKey,
|
|
190
|
-
source: pluginConfig.source,
|
|
191
|
-
url: pluginConfig.url,
|
|
192
|
-
remoteUrl: pluginConfig.source === "remote" ? pluginConfig.url : undefined,
|
|
193
|
-
entry: pluginConfig.entry,
|
|
194
|
-
name: pluginConfig.name,
|
|
195
|
-
localPath: pluginConfig.localPath,
|
|
196
|
-
port: resolvedPort,
|
|
197
|
-
integrity: pluginConfig.integrity,
|
|
198
|
-
proxy: pluginConfig.proxy,
|
|
199
|
-
variables: pluginConfig.variables,
|
|
200
|
-
secrets: pluginConfig.secrets,
|
|
201
|
-
command: "bun",
|
|
202
|
-
args: ["run", "dev"],
|
|
203
|
-
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
204
|
-
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
205
|
-
defaultPort: resolvedPort,
|
|
206
|
-
readinessPath: "/remoteEntry.js",
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
if (pluginConfig.ui?.localPath && pluginConfig.ui.source === "local") {
|
|
210
|
-
const uiKey = `plugin-ui:${pluginId}`;
|
|
211
|
-
const uiPort = pluginConfig.ui.port ?? pluginBasePort;
|
|
212
|
-
pluginBasePort = uiPort + 1;
|
|
213
|
-
|
|
214
|
-
map.set(uiKey, {
|
|
215
|
-
key: uiKey,
|
|
216
|
-
source: pluginConfig.ui.source,
|
|
217
|
-
url: pluginConfig.ui.url,
|
|
218
|
-
entry: pluginConfig.ui.entry,
|
|
219
|
-
name: pluginConfig.ui.name,
|
|
220
|
-
localPath: pluginConfig.ui.localPath,
|
|
221
|
-
port: uiPort,
|
|
222
|
-
integrity: pluginConfig.ui.integrity,
|
|
223
|
-
command: "bun",
|
|
224
|
-
args: ["run", "dev"],
|
|
225
|
-
readyPatterns: PLUGIN_READY_PATTERNS,
|
|
226
|
-
errorPatterns: PLUGIN_ERROR_PATTERNS,
|
|
227
|
-
defaultPort: uiPort,
|
|
228
|
-
readinessPath: "/remoteEntry.js",
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return map;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export interface AppOrchestrator {
|
|
238
|
-
packages: string[];
|
|
239
|
-
description: string;
|
|
240
|
-
env: Record<string, string>;
|
|
241
|
-
port?: number;
|
|
242
|
-
interactive?: boolean;
|
|
243
|
-
noLogs?: boolean;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>
|
|
247
|
-
Layer.succeed(ServiceDescriptorMap, map);
|
|
248
|
-
|
|
249
|
-
export const DevRuntimeConfigLive = (config: RuntimeConfig) =>
|
|
250
|
-
Layer.succeed(DevRuntimeConfig, config);
|
|
251
|
-
|
|
252
|
-
export function buildDescription(map: Map<string, ServiceDescriptor>): string {
|
|
253
|
-
const descriptors = [...map.values()].filter(
|
|
254
|
-
(d) => d.key !== "ui-ssr" && !d.key.startsWith("plugin:"),
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
const allLocal = descriptors.every((d) => d.source === "local");
|
|
258
|
-
const hasProxy = [...map.values()].some((d) => d.proxy && d.source === "local");
|
|
259
|
-
if (allLocal && !hasProxy) return "Full Local Development";
|
|
260
|
-
|
|
261
|
-
const parts: string[] = [];
|
|
262
|
-
for (const d of descriptors) {
|
|
263
|
-
if (d.source === "remote") {
|
|
264
|
-
const label =
|
|
265
|
-
d.key === "host"
|
|
266
|
-
? "Remote Host"
|
|
267
|
-
: d.key === "ui"
|
|
268
|
-
? "Remote UI"
|
|
269
|
-
: d.key === "api"
|
|
270
|
-
? hasProxy
|
|
271
|
-
? undefined
|
|
272
|
-
: "Remote API"
|
|
273
|
-
: d.key === "auth"
|
|
274
|
-
? "Remote Auth"
|
|
275
|
-
: undefined;
|
|
276
|
-
if (label) parts.push(label);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
if (hasProxy) parts.push("Proxy API → Production");
|
|
280
|
-
return parts.join(" + ") || "Remote Mode";
|
|
281
|
-
}
|
package/src/shared.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { type BosEnv, type ResolvedConfigMeta, rebuildOrderedConfig } from "./merge";
|
|
5
|
-
import type { BosConfig, SharedDepConfig } from "./types";
|
|
6
|
-
import { BosConfigSchema } from "./types";
|
|
7
|
-
|
|
8
|
-
interface PackageJson {
|
|
9
|
-
name?: string;
|
|
10
|
-
private?: boolean;
|
|
11
|
-
version?: string;
|
|
12
|
-
workspaces?: {
|
|
13
|
-
packages?: string[];
|
|
14
|
-
catalog?: Record<string, string>;
|
|
15
|
-
};
|
|
16
|
-
dependencies?: Record<string, string>;
|
|
17
|
-
devDependencies?: Record<string, string>;
|
|
18
|
-
scripts?: Record<string, string>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface SharedUiResolvedDep {
|
|
22
|
-
name: string;
|
|
23
|
-
version: string;
|
|
24
|
-
requiredVersion: string;
|
|
25
|
-
shareScope: string;
|
|
26
|
-
singleton: boolean;
|
|
27
|
-
eager: boolean;
|
|
28
|
-
strictVersion: boolean;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface SharedUiResolved {
|
|
32
|
-
deps: Record<string, SharedUiResolvedDep>;
|
|
33
|
-
fingerprintSha256: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface SharedSyncResult {
|
|
37
|
-
mode: "catalog->bos" | "bos->catalog";
|
|
38
|
-
hostMode: "local" | "remote";
|
|
39
|
-
bosConfigChanged: boolean;
|
|
40
|
-
catalogChanged: boolean;
|
|
41
|
-
generatedChanged: boolean;
|
|
42
|
-
resolved: SharedUiResolved;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function sha256(input: string): string {
|
|
46
|
-
return createHash("sha256").update(input).digest("hex");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function extractSemverExact(input: unknown): string | null {
|
|
50
|
-
if (typeof input !== "string") return null;
|
|
51
|
-
const match = input.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
52
|
-
return match ? match[0] : null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function caretRange(version: string): string {
|
|
56
|
-
return `^${version}`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function stableDepsObject(
|
|
60
|
-
deps: Record<string, SharedUiResolvedDep>,
|
|
61
|
-
): Record<string, SharedUiResolvedDep> {
|
|
62
|
-
const keys = Object.keys(deps).sort((a, b) => a.localeCompare(b));
|
|
63
|
-
const out: Record<string, SharedUiResolvedDep> = {};
|
|
64
|
-
for (const k of keys) out[k] = deps[k]!;
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function writeFileIfChanged(filePath: string, nextContent: string): boolean {
|
|
69
|
-
try {
|
|
70
|
-
const current = readFileSync(filePath, "utf-8");
|
|
71
|
-
if (current === nextContent) return false;
|
|
72
|
-
} catch {
|
|
73
|
-
// ignore
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
writeFileSync(filePath, nextContent);
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function fingerprintResolved(deps: Record<string, SharedUiResolvedDep>): string {
|
|
81
|
-
const stable = stableDepsObject(deps);
|
|
82
|
-
return sha256(JSON.stringify(stable));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function getSharedUiDeps(bosConfig: BosConfig): Record<string, SharedDepConfig> {
|
|
86
|
-
const shared = bosConfig.shared ?? {};
|
|
87
|
-
const ui = shared.ui ?? {};
|
|
88
|
-
return ui;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function syncAndGenerateSharedUi(opts: {
|
|
92
|
-
configDir: string;
|
|
93
|
-
hostMode: "local" | "remote";
|
|
94
|
-
bosConfig?: BosConfig;
|
|
95
|
-
env?: BosEnv;
|
|
96
|
-
extendsChain?: string[];
|
|
97
|
-
}): Promise<SharedSyncResult> {
|
|
98
|
-
const bosConfigPath = join(opts.configDir, "bos.config.json");
|
|
99
|
-
const resolvedConfigPath = join(opts.configDir, ".bos", "bos.resolved-config.json");
|
|
100
|
-
const packageJsonPath = join(opts.configDir, "package.json");
|
|
101
|
-
const generatedPath = join(opts.configDir, ".bos", "generated", "shared-ui.json");
|
|
102
|
-
|
|
103
|
-
let bosConfig: BosConfig;
|
|
104
|
-
if (opts.bosConfig) {
|
|
105
|
-
bosConfig = opts.bosConfig;
|
|
106
|
-
} else {
|
|
107
|
-
const raw = JSON.parse(readFileSync(bosConfigPath, "utf-8")) as Record<string, unknown>;
|
|
108
|
-
bosConfig = BosConfigSchema.parse(raw);
|
|
109
|
-
}
|
|
110
|
-
let pkgJson: PackageJson = {};
|
|
111
|
-
try {
|
|
112
|
-
pkgJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as PackageJson;
|
|
113
|
-
} catch {
|
|
114
|
-
// package.json might not exist
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const originalBos = JSON.stringify(bosConfig);
|
|
118
|
-
const originalPkg = JSON.stringify(pkgJson);
|
|
119
|
-
|
|
120
|
-
const catalog = pkgJson?.workspaces?.catalog ?? {};
|
|
121
|
-
const sharedUi = getSharedUiDeps(bosConfig);
|
|
122
|
-
|
|
123
|
-
const mode = opts.hostMode === "local" ? "catalog->bos" : "bos->catalog";
|
|
124
|
-
|
|
125
|
-
if (mode === "catalog->bos") {
|
|
126
|
-
for (const [name, cfg] of Object.entries(sharedUi)) {
|
|
127
|
-
const dep = cfg as SharedDepConfig;
|
|
128
|
-
const version =
|
|
129
|
-
catalog[name] ?? extractSemverExact(dep.version) ?? extractSemverExact(dep.requiredVersion);
|
|
130
|
-
if (!version) continue;
|
|
131
|
-
dep.version = version;
|
|
132
|
-
dep.requiredVersion = caretRange(version);
|
|
133
|
-
dep.shareScope = dep.shareScope ?? "default";
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
for (const [name, cfg] of Object.entries(sharedUi)) {
|
|
137
|
-
const dep = cfg as SharedDepConfig;
|
|
138
|
-
const version = extractSemverExact(dep.version) ?? extractSemverExact(dep.requiredVersion);
|
|
139
|
-
if (!version) continue;
|
|
140
|
-
dep.version = version;
|
|
141
|
-
dep.requiredVersion = caretRange(version);
|
|
142
|
-
dep.shareScope = dep.shareScope ?? "default";
|
|
143
|
-
if (catalog[name] !== version) {
|
|
144
|
-
catalog[name] = version;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (!pkgJson.workspaces) pkgJson.workspaces = { packages: [], catalog: {} };
|
|
148
|
-
pkgJson.workspaces.catalog = catalog;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const nextBos = JSON.stringify(bosConfig);
|
|
152
|
-
const nextPkg = JSON.stringify(pkgJson);
|
|
153
|
-
const bosConfigChanged = nextBos !== originalBos;
|
|
154
|
-
const catalogChanged = nextPkg !== originalPkg;
|
|
155
|
-
|
|
156
|
-
if (bosConfigChanged) {
|
|
157
|
-
if (mode === "catalog->bos") {
|
|
158
|
-
const resolvedDir = dirname(resolvedConfigPath);
|
|
159
|
-
if (!existsSync(resolvedDir)) {
|
|
160
|
-
mkdirSync(resolvedDir, { recursive: true });
|
|
161
|
-
}
|
|
162
|
-
const ordered = rebuildOrderedConfig(bosConfig);
|
|
163
|
-
const meta: ResolvedConfigMeta = {
|
|
164
|
-
env: opts.env ?? "development",
|
|
165
|
-
resolvedAt: new Date().toISOString(),
|
|
166
|
-
extendsChain: opts.extendsChain ?? [],
|
|
167
|
-
source: "shared-sync",
|
|
168
|
-
};
|
|
169
|
-
const resolvedOutput = {
|
|
170
|
-
_resolved: meta,
|
|
171
|
-
...ordered,
|
|
172
|
-
};
|
|
173
|
-
writeFileIfChanged(resolvedConfigPath, `${JSON.stringify(resolvedOutput, null, 2)}\n`);
|
|
174
|
-
} else {
|
|
175
|
-
writeFileIfChanged(bosConfigPath, `${JSON.stringify(bosConfig, null, 2)}\n`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (catalogChanged) {
|
|
179
|
-
writeFileIfChanged(packageJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const resolvedDeps: Record<string, SharedUiResolvedDep> = {};
|
|
183
|
-
for (const [name, cfg] of Object.entries(getSharedUiDeps(bosConfig))) {
|
|
184
|
-
const version =
|
|
185
|
-
catalog[name] ?? extractSemverExact(cfg.version) ?? extractSemverExact(cfg.requiredVersion);
|
|
186
|
-
if (!version) continue;
|
|
187
|
-
resolvedDeps[name] = {
|
|
188
|
-
name,
|
|
189
|
-
version,
|
|
190
|
-
requiredVersion: caretRange(version),
|
|
191
|
-
shareScope: cfg.shareScope ?? "default",
|
|
192
|
-
singleton: cfg.singleton ?? false,
|
|
193
|
-
eager: cfg.eager ?? false,
|
|
194
|
-
strictVersion: cfg.strictVersion ?? false,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const stableResolvedDeps = stableDepsObject(resolvedDeps);
|
|
199
|
-
const resolved: SharedUiResolved = {
|
|
200
|
-
deps: stableResolvedDeps,
|
|
201
|
-
fingerprintSha256: fingerprintResolved(stableResolvedDeps),
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
const nextGenerated = {
|
|
205
|
-
schemaVersion: 1,
|
|
206
|
-
kind: "everything-dev/shared-ui",
|
|
207
|
-
generatedAt: new Date().toISOString(),
|
|
208
|
-
ui: {
|
|
209
|
-
deps: stableResolvedDeps,
|
|
210
|
-
fingerprintSha256: resolved.fingerprintSha256,
|
|
211
|
-
},
|
|
212
|
-
inputs: {
|
|
213
|
-
mode,
|
|
214
|
-
hostMode: opts.hostMode,
|
|
215
|
-
},
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
let prevFingerprint: string | null = null;
|
|
219
|
-
try {
|
|
220
|
-
const prev = JSON.parse(readFileSync(generatedPath, "utf-8"));
|
|
221
|
-
prevFingerprint = prev?.ui?.fingerprintSha256 ?? null;
|
|
222
|
-
} catch {
|
|
223
|
-
// ignore
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
mkdirSync(dirname(generatedPath), { recursive: true });
|
|
227
|
-
writeFileIfChanged(generatedPath, `${JSON.stringify(nextGenerated, null, 2)}\n`);
|
|
228
|
-
|
|
229
|
-
const generatedChanged = prevFingerprint !== nextGenerated.ui.fingerprintSha256;
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
mode,
|
|
233
|
-
hostMode: opts.hostMode,
|
|
234
|
-
bosConfigChanged,
|
|
235
|
-
catalogChanged,
|
|
236
|
-
generatedChanged,
|
|
237
|
-
resolved,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export function loadGeneratedSharedUi(configDir: string): SharedUiResolved | null {
|
|
242
|
-
const generatedPath = join(configDir, ".bos", "generated", "shared-ui.json");
|
|
243
|
-
try {
|
|
244
|
-
const content = JSON.parse(readFileSync(generatedPath, "utf-8"));
|
|
245
|
-
return content?.ui ?? null;
|
|
246
|
-
} catch {
|
|
247
|
-
return null;
|
|
248
|
-
}
|
|
249
|
-
}
|
package/src/sidebar.ts
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import type { RuntimeConfig, SidebarItem } from "./types";
|
|
4
|
-
|
|
5
|
-
const ICON_IMPORTS: Record<string, string> = {
|
|
6
|
-
Home: "lucide-react",
|
|
7
|
-
Globe: "lucide-react",
|
|
8
|
-
FolderKanban: "lucide-react",
|
|
9
|
-
Building2: "lucide-react",
|
|
10
|
-
Settings: "lucide-react",
|
|
11
|
-
User: "lucide-react",
|
|
12
|
-
Users: "lucide-react",
|
|
13
|
-
Shield: "lucide-react",
|
|
14
|
-
LayoutDashboard: "lucide-react",
|
|
15
|
-
CreditCard: "lucide-react",
|
|
16
|
-
Bell: "lucide-react",
|
|
17
|
-
Key: "lucide-react",
|
|
18
|
-
FileText: "lucide-react",
|
|
19
|
-
Database: "lucide-react",
|
|
20
|
-
Activity: "lucide-react",
|
|
21
|
-
BarChart3: "lucide-react",
|
|
22
|
-
Zap: "lucide-react",
|
|
23
|
-
Terminal: "lucide-react",
|
|
24
|
-
Code: "lucide-react",
|
|
25
|
-
Package: "lucide-react",
|
|
26
|
-
Store: "lucide-react",
|
|
27
|
-
ShoppingBag: "lucide-react",
|
|
28
|
-
Wallet: "lucide-react",
|
|
29
|
-
Coins: "lucide-react",
|
|
30
|
-
Plug: "lucide-react",
|
|
31
|
-
Link: "lucide-react",
|
|
32
|
-
ExternalLink: "lucide-react",
|
|
33
|
-
Puzzle: "lucide-react",
|
|
34
|
-
Layers: "lucide-react",
|
|
35
|
-
Grid3X3: "lucide-react",
|
|
36
|
-
AppWindow: "lucide-react",
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
function resolveIconModule(iconName: string): string {
|
|
40
|
-
if (ICON_IMPORTS[iconName]) return ICON_IMPORTS[iconName];
|
|
41
|
-
return "lucide-react";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function collectIconImports(items: SidebarItem[]): Map<string, Set<string>> {
|
|
45
|
-
const moduleMap = new Map<string, Set<string>>();
|
|
46
|
-
for (const item of items) {
|
|
47
|
-
const module = resolveIconModule(item.icon);
|
|
48
|
-
if (!moduleMap.has(module)) moduleMap.set(module, new Set());
|
|
49
|
-
moduleMap.get(module)!.add(item.icon);
|
|
50
|
-
}
|
|
51
|
-
return moduleMap;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function generatePluginSidebarContent(runtimeConfig: RuntimeConfig): string {
|
|
55
|
-
const coreItems: SidebarItem[] = [{ icon: "Home", label: "home", to: "/", roleRequired: "anon" }];
|
|
56
|
-
|
|
57
|
-
if (runtimeConfig.auth?.sidebar) {
|
|
58
|
-
for (const item of runtimeConfig.auth.sidebar) {
|
|
59
|
-
coreItems.push({
|
|
60
|
-
...item,
|
|
61
|
-
to: item.to ?? "/auth",
|
|
62
|
-
roleRequired: item.roleRequired ?? "member",
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const pluginItems: SidebarItem[] = [];
|
|
68
|
-
if (runtimeConfig.plugins) {
|
|
69
|
-
for (const [key, entry] of Object.entries(runtimeConfig.plugins)) {
|
|
70
|
-
const sidebar = entry.sidebar;
|
|
71
|
-
if (!sidebar) continue;
|
|
72
|
-
for (const item of sidebar) {
|
|
73
|
-
pluginItems.push({
|
|
74
|
-
...item,
|
|
75
|
-
to: item.to ?? `/${key}`,
|
|
76
|
-
roleRequired: item.roleRequired ?? "member",
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const allItems = [...coreItems, ...pluginItems];
|
|
83
|
-
const moduleMap = collectIconImports(allItems);
|
|
84
|
-
|
|
85
|
-
const importLines: string[] = [];
|
|
86
|
-
for (const [module, icons] of moduleMap) {
|
|
87
|
-
const iconList = [...icons].join(", ");
|
|
88
|
-
importLines.push(`import { ${iconList} } from "${module}";`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const itemsCode = allItems
|
|
92
|
-
.map(
|
|
93
|
-
(item) =>
|
|
94
|
-
` { icon: ${item.icon}, label: "${item.label}", to: "${item.to}" as const, roleRequired: "${item.roleRequired}" as const },`,
|
|
95
|
-
)
|
|
96
|
-
.join("\n");
|
|
97
|
-
|
|
98
|
-
return `// Auto-generated by bos sync/pluginAdd/pluginRemove. Do not edit.
|
|
99
|
-
${importLines.join("\n")}
|
|
100
|
-
|
|
101
|
-
export type SidebarRole = "anon" | "member" | "admin";
|
|
102
|
-
|
|
103
|
-
export interface SidebarItem {
|
|
104
|
-
icon: React.ComponentType<{ className?: string }>;
|
|
105
|
-
label: string;
|
|
106
|
-
to: string;
|
|
107
|
-
roleRequired: SidebarRole;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const pluginSidebarItems: SidebarItem[] = [
|
|
111
|
-
${itemsCode}
|
|
112
|
-
];
|
|
113
|
-
`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function writePluginSidebarGen(configDir: string, runtimeConfig: RuntimeConfig): string {
|
|
117
|
-
const outputPath = join(configDir, "ui/src/lib/plugin-sidebar.gen.ts");
|
|
118
|
-
|
|
119
|
-
const content = generatePluginSidebarContent(runtimeConfig);
|
|
120
|
-
|
|
121
|
-
const outputDir = dirname(outputPath);
|
|
122
|
-
if (!existsSync(outputDir)) {
|
|
123
|
-
mkdirSync(outputDir, { recursive: true });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
let existingContent: string | null = null;
|
|
127
|
-
try {
|
|
128
|
-
existingContent = existsSync(outputPath)
|
|
129
|
-
? // eslint-disable-next-line no-restricted-syntax
|
|
130
|
-
readFileSync(outputPath, "utf-8")
|
|
131
|
-
: null;
|
|
132
|
-
} catch {
|
|
133
|
-
// file doesn't exist yet
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (existingContent === content) return outputPath;
|
|
137
|
-
|
|
138
|
-
writeFileSync(outputPath, content);
|
|
139
|
-
return outputPath;
|
|
140
|
-
}
|