everything-dev 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/cli/infra.cjs +1 -1
  2. package/dist/cli/infra.mjs +1 -1
  3. package/dist/cli/init.cjs +7 -9
  4. package/dist/cli/init.cjs.map +1 -1
  5. package/dist/cli/init.d.cts +1 -1
  6. package/dist/cli/init.d.cts.map +1 -1
  7. package/dist/cli/init.d.mts +1 -1
  8. package/dist/cli/init.d.mts.map +1 -1
  9. package/dist/cli/init.mjs +7 -9
  10. package/dist/cli/init.mjs.map +1 -1
  11. package/dist/cli/prompts.cjs +28 -24
  12. package/dist/cli/prompts.cjs.map +1 -1
  13. package/dist/cli/prompts.mjs +27 -24
  14. package/dist/cli/prompts.mjs.map +1 -1
  15. package/dist/cli/sync.cjs +4 -1
  16. package/dist/cli/sync.cjs.map +1 -1
  17. package/dist/cli/sync.mjs +4 -1
  18. package/dist/cli/sync.mjs.map +1 -1
  19. package/dist/cli.cjs +187 -12
  20. package/dist/cli.cjs.map +1 -1
  21. package/dist/cli.mjs +186 -11
  22. package/dist/cli.mjs.map +1 -1
  23. package/dist/contract.cjs +1 -1
  24. package/dist/contract.cjs.map +1 -1
  25. package/dist/contract.d.cts +38 -34
  26. package/dist/contract.d.cts.map +1 -1
  27. package/dist/contract.d.mts +38 -34
  28. package/dist/contract.d.mts.map +1 -1
  29. package/dist/contract.mjs +1 -0
  30. package/dist/contract.mjs.map +1 -1
  31. package/dist/dev-session.cjs +0 -1
  32. package/dist/dev-session.mjs +1 -1
  33. package/dist/index.cjs +0 -2
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.mts +2 -2
  36. package/dist/index.mjs +0 -1
  37. package/dist/near-cli.cjs +1 -1
  38. package/dist/near-cli.mjs +1 -1
  39. package/dist/orchestrator.cjs +1 -1
  40. package/dist/orchestrator.mjs +1 -1
  41. package/dist/plugin.cjs +163 -139
  42. package/dist/plugin.cjs.map +1 -1
  43. package/dist/plugin.d.cts +67 -34
  44. package/dist/plugin.d.cts.map +1 -1
  45. package/dist/plugin.d.mts +66 -34
  46. package/dist/plugin.d.mts.map +1 -1
  47. package/dist/plugin.mjs +153 -130
  48. package/dist/plugin.mjs.map +1 -1
  49. package/dist/service-descriptor.d.cts +34 -0
  50. package/dist/service-descriptor.d.cts.map +1 -0
  51. package/dist/service-descriptor.d.mts +36 -0
  52. package/dist/service-descriptor.d.mts.map +1 -0
  53. package/dist/types.d.cts +2 -2
  54. package/dist/types.d.mts +2 -2
  55. package/package.json +2 -2
  56. package/src/api-contract.ts +0 -623
  57. package/src/app.ts +0 -193
  58. package/src/cli/catalog.ts +0 -49
  59. package/src/cli/framework-version.ts +0 -61
  60. package/src/cli/help.ts +0 -13
  61. package/src/cli/infra.ts +0 -190
  62. package/src/cli/init.ts +0 -1145
  63. package/src/cli/parse.ts +0 -147
  64. package/src/cli/prompts.ts +0 -135
  65. package/src/cli/snapshot.ts +0 -46
  66. package/src/cli/status.ts +0 -99
  67. package/src/cli/sync.ts +0 -429
  68. package/src/cli/timing.ts +0 -63
  69. package/src/cli/upgrade.ts +0 -869
  70. package/src/cli.ts +0 -516
  71. package/src/components/dev-view.tsx +0 -352
  72. package/src/components/streaming-view.ts +0 -177
  73. package/src/config.ts +0 -893
  74. package/src/contract.meta.ts +0 -140
  75. package/src/contract.ts +0 -326
  76. package/src/dev-logs.ts +0 -92
  77. package/src/dev-session.ts +0 -283
  78. package/src/fastkv.ts +0 -181
  79. package/src/index.ts +0 -8
  80. package/src/integrity.ts +0 -138
  81. package/src/internal/manifest-normalizer.ts +0 -290
  82. package/src/merge.ts +0 -187
  83. package/src/mf.ts +0 -147
  84. package/src/near-cli.ts +0 -259
  85. package/src/network.ts +0 -3
  86. package/src/orchestrator.ts +0 -493
  87. package/src/plugin.ts +0 -1799
  88. package/src/sdk.ts +0 -14
  89. package/src/service-descriptor.ts +0 -281
  90. package/src/shared.ts +0 -249
  91. package/src/sidebar.ts +0 -140
  92. package/src/types.ts +0 -330
  93. package/src/ui/head.ts +0 -83
  94. package/src/ui/index.ts +0 -5
  95. package/src/ui/metadata.ts +0 -95
  96. package/src/ui/router.ts +0 -88
  97. package/src/ui/runtime.ts +0 -42
  98. package/src/ui/types.ts +0 -65
  99. package/src/utils/banner.ts +0 -21
  100. package/src/utils/linkify.ts +0 -11
  101. package/src/utils/path-match.ts +0 -16
  102. package/src/utils/run.ts +0 -31
  103. package/src/utils/save-config.ts +0 -20
  104. 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
- }