everything-dev 1.12.3 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/cli.js +1 -1
  2. package/dist/app.cjs +24 -101
  3. package/dist/app.cjs.map +1 -1
  4. package/dist/app.mjs +25 -102
  5. package/dist/app.mjs.map +1 -1
  6. package/dist/cli/init.cjs +143 -66
  7. package/dist/cli/init.cjs.map +1 -1
  8. package/dist/cli/init.d.cts +1 -1
  9. package/dist/cli/init.d.cts.map +1 -1
  10. package/dist/cli/init.d.mts +1 -1
  11. package/dist/cli/init.d.mts.map +1 -1
  12. package/dist/cli/init.mjs +144 -67
  13. package/dist/cli/init.mjs.map +1 -1
  14. package/dist/cli/prompts.cjs +3 -3
  15. package/dist/cli/prompts.cjs.map +1 -1
  16. package/dist/cli/prompts.mjs +3 -3
  17. package/dist/cli/prompts.mjs.map +1 -1
  18. package/dist/cli/sync.cjs +15 -56
  19. package/dist/cli/sync.cjs.map +1 -1
  20. package/dist/cli/sync.mjs +15 -56
  21. package/dist/cli/sync.mjs.map +1 -1
  22. package/dist/cli/upgrade.cjs +3 -1
  23. package/dist/cli/upgrade.cjs.map +1 -1
  24. package/dist/cli/upgrade.mjs +3 -1
  25. package/dist/cli/upgrade.mjs.map +1 -1
  26. package/dist/config.cjs +223 -81
  27. package/dist/config.cjs.map +1 -1
  28. package/dist/config.d.cts +21 -5
  29. package/dist/config.d.cts.map +1 -1
  30. package/dist/config.d.mts +21 -5
  31. package/dist/config.d.mts.map +1 -1
  32. package/dist/config.mjs +217 -83
  33. package/dist/config.mjs.map +1 -1
  34. package/dist/contract.d.cts +104 -8
  35. package/dist/contract.d.cts.map +1 -1
  36. package/dist/contract.d.mts +104 -8
  37. package/dist/contract.d.mts.map +1 -1
  38. package/dist/host.cjs +34 -1
  39. package/dist/host.cjs.map +1 -1
  40. package/dist/host.d.cts.map +1 -1
  41. package/dist/host.d.mts.map +1 -1
  42. package/dist/host.mjs +34 -1
  43. package/dist/host.mjs.map +1 -1
  44. package/dist/index.cjs +17 -0
  45. package/dist/index.d.cts +5 -3
  46. package/dist/index.d.mts +5 -3
  47. package/dist/index.mjs +5 -3
  48. package/dist/merge.cjs +113 -0
  49. package/dist/merge.cjs.map +1 -0
  50. package/dist/merge.d.cts +7 -0
  51. package/dist/merge.d.cts.map +1 -0
  52. package/dist/merge.d.mts +7 -0
  53. package/dist/merge.d.mts.map +1 -0
  54. package/dist/merge.mjs +107 -0
  55. package/dist/merge.mjs.map +1 -0
  56. package/dist/plugin.cjs +117 -105
  57. package/dist/plugin.cjs.map +1 -1
  58. package/dist/plugin.d.cts +114 -8
  59. package/dist/plugin.d.cts.map +1 -1
  60. package/dist/plugin.d.mts +114 -8
  61. package/dist/plugin.d.mts.map +1 -1
  62. package/dist/plugin.mjs +117 -105
  63. package/dist/plugin.mjs.map +1 -1
  64. package/dist/service-descriptor.cjs +21 -0
  65. package/dist/service-descriptor.cjs.map +1 -1
  66. package/dist/service-descriptor.d.cts +23 -1
  67. package/dist/service-descriptor.d.cts.map +1 -1
  68. package/dist/service-descriptor.d.mts +23 -1
  69. package/dist/service-descriptor.d.mts.map +1 -1
  70. package/dist/service-descriptor.mjs +21 -0
  71. package/dist/service-descriptor.mjs.map +1 -1
  72. package/dist/shared.cjs +24 -2
  73. package/dist/shared.cjs.map +1 -1
  74. package/dist/shared.d.cts +3 -0
  75. package/dist/shared.d.cts.map +1 -1
  76. package/dist/shared.d.mts +3 -0
  77. package/dist/shared.d.mts.map +1 -1
  78. package/dist/shared.mjs +25 -3
  79. package/dist/shared.mjs.map +1 -1
  80. package/dist/sidebar.cjs +124 -0
  81. package/dist/sidebar.cjs.map +1 -0
  82. package/dist/sidebar.d.cts +8 -0
  83. package/dist/sidebar.d.cts.map +1 -0
  84. package/dist/sidebar.d.mts +8 -0
  85. package/dist/sidebar.d.mts.map +1 -0
  86. package/dist/sidebar.mjs +122 -0
  87. package/dist/sidebar.mjs.map +1 -0
  88. package/dist/types.cjs +104 -10
  89. package/dist/types.cjs.map +1 -1
  90. package/dist/types.d.cts +256 -29
  91. package/dist/types.d.cts.map +1 -1
  92. package/dist/types.d.mts +256 -29
  93. package/dist/types.d.mts.map +1 -1
  94. package/dist/types.mjs +100 -11
  95. package/dist/types.mjs.map +1 -1
  96. package/dist/utils/path-match.cjs +18 -0
  97. package/dist/utils/path-match.cjs.map +1 -0
  98. package/dist/utils/path-match.mjs +17 -0
  99. package/dist/utils/path-match.mjs.map +1 -0
  100. package/dist/utils/save-config.cjs +19 -0
  101. package/dist/utils/save-config.cjs.map +1 -0
  102. package/dist/utils/save-config.mjs +18 -0
  103. package/dist/utils/save-config.mjs.map +1 -0
  104. package/package.json +3 -2
  105. package/skills/dev-workflow/SKILL.md +8 -0
  106. package/skills/extends-config/SKILL.md +132 -0
  107. package/skills/init-upgrade/SKILL.md +128 -0
  108. package/skills/publish-sync/SKILL.md +30 -0
  109. package/src/app.ts +23 -118
  110. package/src/cli/init.ts +199 -100
  111. package/src/cli/prompts.ts +2 -2
  112. package/src/cli/sync.ts +27 -96
  113. package/src/cli/upgrade.ts +2 -0
  114. package/src/config.ts +356 -132
  115. package/src/host.ts +45 -0
  116. package/src/index.ts +1 -0
  117. package/src/merge.ts +198 -0
  118. package/src/plugin.ts +340 -318
  119. package/src/service-descriptor.ts +23 -0
  120. package/src/shared.ts +48 -5
  121. package/src/sidebar.ts +162 -0
  122. package/src/types.ts +134 -28
  123. package/src/utils/path-match.ts +16 -0
  124. package/src/utils/save-config.ts +20 -0
package/src/host.ts CHANGED
@@ -54,6 +54,15 @@ function buildClientRuntimeConfig(runtimeConfig: RuntimeConfig): ClientRuntimeCo
54
54
  integrity: runtimeConfig.api.integrity,
55
55
  }
56
56
  : undefined,
57
+ auth: runtimeConfig.auth
58
+ ? {
59
+ name: runtimeConfig.auth.name,
60
+ url: runtimeConfig.auth.url,
61
+ entry: runtimeConfig.auth.entry,
62
+ integrity: runtimeConfig.auth.integrity,
63
+ sidebar: runtimeConfig.auth.sidebar,
64
+ }
65
+ : undefined,
57
66
  plugins: runtimeConfig.plugins
58
67
  ? Object.fromEntries(
59
68
  Object.entries(runtimeConfig.plugins).map(([key, plugin]) => [
@@ -63,6 +72,18 @@ function buildClientRuntimeConfig(runtimeConfig: RuntimeConfig): ClientRuntimeCo
63
72
  url: plugin.url,
64
73
  entry: plugin.entry,
65
74
  integrity: plugin.integrity,
75
+ ...(plugin.ui
76
+ ? {
77
+ ui: {
78
+ name: plugin.ui.name,
79
+ url: plugin.ui.url,
80
+ entry: plugin.ui.entry,
81
+ source: plugin.ui.source,
82
+ integrity: plugin.ui.integrity,
83
+ },
84
+ }
85
+ : {}),
86
+ ...(plugin.sidebar ? { sidebar: plugin.sidebar } : {}),
66
87
  },
67
88
  ]),
68
89
  )
@@ -79,6 +100,15 @@ function renderLoadingShell(runtimeConfig: ClientRuntimeConfig, error?: string |
79
100
  const uiIntegrity = runtimeConfig.ui?.integrity;
80
101
  const sriAttr = uiIntegrity ? ` integrity="${uiIntegrity}" crossorigin="anonymous"` : "";
81
102
 
103
+ const pluginUiScripts = Object.values(runtimeConfig.plugins ?? {})
104
+ .filter((plugin) => plugin.ui?.url && plugin.ui.source === "remote")
105
+ .map((plugin) => {
106
+ const uiIntegrity = plugin.ui!.integrity;
107
+ const sri = uiIntegrity ? ` integrity="${uiIntegrity}" crossorigin="anonymous"` : "";
108
+ return `<script src="${plugin.ui!.url}/remoteEntry.js"${sri}></script>`;
109
+ })
110
+ .join("\n");
111
+
82
112
  return `
83
113
  <!DOCTYPE html>
84
114
  <html lang="en">
@@ -92,6 +122,7 @@ function renderLoadingShell(runtimeConfig: ClientRuntimeConfig, error?: string |
92
122
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
93
123
  </style>
94
124
  ${runtimeConfig.assetsUrl ? `<script src="${runtimeConfig.assetsUrl}/remoteEntry.js"${sriAttr}></script>` : ""}
125
+ ${pluginUiScripts}
95
126
  <script>${bootstrap}</script>
96
127
  </head>
97
128
  <body>
@@ -454,6 +485,20 @@ async function runHostServer(opts: {
454
485
  }
455
486
  }
456
487
 
488
+ for (const [pluginKey, pluginConfig] of Object.entries(runtimeConfig.plugins ?? {})) {
489
+ if (!pluginConfig.ui?.url) continue;
490
+ const pluginUiUrl = pluginConfig.ui.url;
491
+ const proxyPrefix = `/__mf/plugin-ui/${pluginKey}`;
492
+ app.all(`${proxyPrefix}/*`, async (c) => {
493
+ const targetUrl = `${pluginUiUrl}${c.req.path.replace(proxyPrefix, "")}`;
494
+ const response = await fetch(targetUrl, {
495
+ method: c.req.method,
496
+ headers: c.req.header(),
497
+ });
498
+ return response;
499
+ });
500
+ }
501
+
457
502
  app.get("*", async (c) => {
458
503
  const routerModule = await ensureRouterModuleLoaded();
459
504
 
package/src/index.ts CHANGED
@@ -4,4 +4,5 @@ export * from "./contract.meta";
4
4
  export * from "./fastkv";
5
5
  export * from "./plugin";
6
6
  export * from "./sdk";
7
+ export * from "./sidebar";
7
8
  export * from "./types";
package/src/merge.ts ADDED
@@ -0,0 +1,198 @@
1
+ import { createDefu } from "defu";
2
+ import type { BosConfigInput, ExtendsConfig } from "./types";
3
+
4
+ export const BOS_CONFIG_ORDER = [
5
+ "extends",
6
+ "account",
7
+ "domain",
8
+ "testnet",
9
+ "staging",
10
+ "repository",
11
+ "app",
12
+ "plugins",
13
+ "shared",
14
+ ] as const;
15
+
16
+ export type BosConfigFieldName = (typeof BOS_CONFIG_ORDER)[number];
17
+
18
+ export type BosEnv = "development" | "production" | "staging";
19
+
20
+ export interface ResolvedConfigMeta {
21
+ env: BosEnv;
22
+ resolvedAt: string;
23
+ extendsChain: string[];
24
+ source?: string;
25
+ }
26
+
27
+ const ARRAY_UNION_KEYS = new Set(["secrets"]);
28
+
29
+ export function isPlainObject(value: unknown): value is Record<string, unknown> {
30
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
31
+ }
32
+
33
+ function unionArrays(a: unknown, b: unknown): unknown[] | undefined {
34
+ const aArr = Array.isArray(a) ? a : [];
35
+ const bArr = Array.isArray(b) ? b : [];
36
+ if (aArr.length === 0 && bArr.length === 0) return undefined;
37
+ const seen = new Set<string>();
38
+ const result: unknown[] = [];
39
+ for (const item of [...aArr, ...bArr]) {
40
+ if (typeof item === "string") {
41
+ if (seen.has(item)) continue;
42
+ seen.add(item);
43
+ }
44
+ result.push(item);
45
+ }
46
+ return result;
47
+ }
48
+
49
+ function cleanNullSentinels(obj: Record<string, unknown>): Record<string, unknown> {
50
+ const out: Record<string, unknown> = {};
51
+ for (const [key, value] of Object.entries(obj)) {
52
+ if (value === null || value === undefined) continue;
53
+ if (isPlainObject(value)) {
54
+ const cleaned = cleanNullSentinels(value);
55
+ if (Object.keys(cleaned).length > 0) {
56
+ out[key] = cleaned;
57
+ }
58
+ } else {
59
+ out[key] = value;
60
+ }
61
+ }
62
+ return out;
63
+ }
64
+
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ const bosConfigMerger = createDefu((obj: any, key: any, value: any): boolean | undefined => {
67
+ if (obj[key] === null) return true;
68
+ if (value === null) {
69
+ obj[key] = null;
70
+ return true;
71
+ }
72
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
73
+ if (ARRAY_UNION_KEYS.has(key)) {
74
+ obj[key] = unionArrays(obj[key], value);
75
+ } else {
76
+ obj[key] = value;
77
+ }
78
+ return true;
79
+ }
80
+ return false;
81
+ });
82
+
83
+ export function resolveExtendsRef(
84
+ extendsField: string | ExtendsConfig | undefined,
85
+ env: BosEnv,
86
+ ): string | undefined {
87
+ if (!extendsField) return undefined;
88
+ if (typeof extendsField === "string") return extendsField;
89
+ return extendsField[env] ?? extendsField.production ?? Object.values(extendsField).find(Boolean);
90
+ }
91
+
92
+ export function mergeBosConfigWithExtends(
93
+ parent: BosConfigInput,
94
+ child: BosConfigInput,
95
+ ): BosConfigInput {
96
+ const merged = bosConfigMerger(child, parent) as BosConfigInput;
97
+
98
+ if (isPlainObject(parent.plugins) && isPlainObject(child.plugins)) {
99
+ const plugins: Record<string, unknown> = { ...parent.plugins };
100
+ for (const [key, rawValue] of Object.entries(child.plugins)) {
101
+ const value = rawValue as unknown;
102
+ if (value === null || value === false) {
103
+ delete plugins[key];
104
+ } else if (isPlainObject(plugins[key]) && isPlainObject(value)) {
105
+ plugins[key] = bosConfigMerger(
106
+ value as Record<string, unknown>,
107
+ plugins[key] as Record<string, unknown>,
108
+ );
109
+ } else {
110
+ plugins[key] = value;
111
+ }
112
+ }
113
+ (merged as Record<string, unknown>).plugins = plugins;
114
+ } else if (child.plugins !== undefined) {
115
+ (merged as Record<string, unknown>).plugins = cleanNullSentinels(
116
+ child.plugins as Record<string, unknown>,
117
+ );
118
+ }
119
+
120
+ const mergedRecord = merged as Record<string, unknown>;
121
+
122
+ if (isPlainObject(mergedRecord.app)) {
123
+ for (const entryVal of Object.values(mergedRecord.app as Record<string, unknown>)) {
124
+ if (!isPlainObject(entryVal)) continue;
125
+ for (const secretKey of ARRAY_UNION_KEYS) {
126
+ if (Array.isArray(entryVal[secretKey])) {
127
+ entryVal[secretKey] =
128
+ (unionArrays(entryVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(
129
+ Boolean,
130
+ ) ?? entryVal[secretKey];
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ if (isPlainObject(mergedRecord.plugins)) {
137
+ for (const pluginVal of Object.values(mergedRecord.plugins as Record<string, unknown>)) {
138
+ if (!isPlainObject(pluginVal)) continue;
139
+ for (const secretKey of ARRAY_UNION_KEYS) {
140
+ if (Array.isArray(pluginVal[secretKey])) {
141
+ pluginVal[secretKey] =
142
+ (unionArrays(pluginVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(
143
+ Boolean,
144
+ ) ?? pluginVal[secretKey];
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ return rebuildOrderedConfig(mergedRecord) as BosConfigInput;
151
+ }
152
+
153
+ export function mergeBosConfigWithTemplate(
154
+ local: BosConfigInput,
155
+ template: BosConfigInput,
156
+ ): BosConfigInput {
157
+ const merged = mergeJsonValuesPreservingLocalOrder(local, template) as BosConfigInput;
158
+ return rebuildOrderedConfig(merged as Record<string, unknown>) as BosConfigInput;
159
+ }
160
+
161
+ function mergeJsonValuesPreservingLocalOrder(local: unknown, template: unknown): unknown {
162
+ if (isPlainObject(local) && isPlainObject(template)) {
163
+ const merged: Record<string, unknown> = {};
164
+ for (const key of Object.keys(local)) {
165
+ merged[key] = mergeJsonValuesPreservingLocalOrder(
166
+ local[key],
167
+ (template as Record<string, unknown>)[key],
168
+ );
169
+ }
170
+ for (const key of Object.keys(template as Record<string, unknown>)) {
171
+ if (!(key in merged)) {
172
+ merged[key] = (template as Record<string, unknown>)[key];
173
+ }
174
+ }
175
+ return merged;
176
+ }
177
+ return local ?? template;
178
+ }
179
+
180
+ export function rebuildOrderedConfig<T extends Record<string, unknown>>(config: T): T {
181
+ const ordered: Record<string, unknown> = {};
182
+
183
+ for (const key of BOS_CONFIG_ORDER) {
184
+ if (key in config) {
185
+ ordered[key] = config[key];
186
+ }
187
+ }
188
+
189
+ for (const key of Object.keys(config)) {
190
+ if (!BOS_CONFIG_ORDER.includes(key as BosConfigFieldName)) {
191
+ ordered[key] = config[key];
192
+ }
193
+ }
194
+
195
+ return ordered as T;
196
+ }
197
+
198
+ export { bosConfigMerger };