everything-dev 1.16.3 → 1.19.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 (83) hide show
  1. package/dist/cli/init.cjs +167 -87
  2. package/dist/cli/init.cjs.map +1 -1
  3. package/dist/cli/init.d.cts +14 -2
  4. package/dist/cli/init.d.cts.map +1 -1
  5. package/dist/cli/init.d.mts +14 -2
  6. package/dist/cli/init.d.mts.map +1 -1
  7. package/dist/cli/init.mjs +166 -88
  8. package/dist/cli/init.mjs.map +1 -1
  9. package/dist/cli/prompts.cjs +12 -14
  10. package/dist/cli/prompts.cjs.map +1 -1
  11. package/dist/cli/prompts.mjs +12 -14
  12. package/dist/cli/prompts.mjs.map +1 -1
  13. package/dist/cli/sync.cjs +3 -5
  14. package/dist/cli/sync.cjs.map +1 -1
  15. package/dist/cli/sync.mjs +3 -5
  16. package/dist/cli/sync.mjs.map +1 -1
  17. package/dist/cli/upgrade.cjs +214 -2
  18. package/dist/cli/upgrade.cjs.map +1 -1
  19. package/dist/cli/upgrade.mjs +214 -2
  20. package/dist/cli/upgrade.mjs.map +1 -1
  21. package/dist/config.cjs +125 -74
  22. package/dist/config.cjs.map +1 -1
  23. package/dist/config.d.cts +9 -2
  24. package/dist/config.d.cts.map +1 -1
  25. package/dist/config.d.mts +9 -2
  26. package/dist/config.d.mts.map +1 -1
  27. package/dist/config.mjs +126 -76
  28. package/dist/config.mjs.map +1 -1
  29. package/dist/contract.cjs +1 -4
  30. package/dist/contract.cjs.map +1 -1
  31. package/dist/contract.d.cts +40 -22
  32. package/dist/contract.d.cts.map +1 -1
  33. package/dist/contract.d.mts +40 -22
  34. package/dist/contract.d.mts.map +1 -1
  35. package/dist/contract.meta.cjs +5 -5
  36. package/dist/contract.meta.cjs.map +1 -1
  37. package/dist/contract.meta.d.cts +9 -9
  38. package/dist/contract.meta.d.mts +9 -9
  39. package/dist/contract.meta.mjs +5 -5
  40. package/dist/contract.meta.mjs.map +1 -1
  41. package/dist/contract.mjs +1 -4
  42. package/dist/contract.mjs.map +1 -1
  43. package/dist/index.cjs +2 -0
  44. package/dist/index.d.cts +3 -3
  45. package/dist/index.d.mts +3 -3
  46. package/dist/index.mjs +3 -3
  47. package/dist/merge.cjs +1 -0
  48. package/dist/merge.mjs +1 -1
  49. package/dist/plugin.cjs +70 -114
  50. package/dist/plugin.cjs.map +1 -1
  51. package/dist/plugin.d.cts +38 -17
  52. package/dist/plugin.d.cts.map +1 -1
  53. package/dist/plugin.d.mts +38 -17
  54. package/dist/plugin.d.mts.map +1 -1
  55. package/dist/plugin.mjs +71 -115
  56. package/dist/plugin.mjs.map +1 -1
  57. package/dist/sidebar.cjs +6 -14
  58. package/dist/sidebar.cjs.map +1 -1
  59. package/dist/sidebar.d.cts +3 -3
  60. package/dist/sidebar.d.cts.map +1 -1
  61. package/dist/sidebar.d.mts +3 -3
  62. package/dist/sidebar.d.mts.map +1 -1
  63. package/dist/sidebar.mjs +6 -14
  64. package/dist/sidebar.mjs.map +1 -1
  65. package/dist/types.cjs +10 -16
  66. package/dist/types.cjs.map +1 -1
  67. package/dist/types.d.cts +56 -12
  68. package/dist/types.d.cts.map +1 -1
  69. package/dist/types.d.mts +56 -12
  70. package/dist/types.d.mts.map +1 -1
  71. package/dist/types.mjs +10 -17
  72. package/dist/types.mjs.map +1 -1
  73. package/package.json +1 -1
  74. package/src/cli/init.ts +225 -131
  75. package/src/cli/prompts.ts +17 -22
  76. package/src/cli/sync.ts +5 -8
  77. package/src/cli/upgrade.ts +326 -2
  78. package/src/config.ts +250 -107
  79. package/src/contract.meta.ts +6 -8
  80. package/src/contract.ts +1 -4
  81. package/src/plugin.ts +120 -183
  82. package/src/sidebar.ts +9 -31
  83. package/src/types.ts +10 -15
@@ -70,6 +70,314 @@ function parseBosRef(ref: string): { account: string; gateway: string } | null {
70
70
  return { account: match[1], gateway: match[2] };
71
71
  }
72
72
 
73
+ function parseTargetedRef(ref: string): { configRef: string; targetPath?: string } {
74
+ const hashIndex = ref.indexOf("#");
75
+ if (hashIndex === -1) {
76
+ return { configRef: ref };
77
+ }
78
+ return {
79
+ configRef: ref.slice(0, hashIndex),
80
+ targetPath: ref.slice(hashIndex + 1) || undefined,
81
+ };
82
+ }
83
+
84
+ function ensureTargetedRef(ref: string, targetPath: string): string {
85
+ const parsed = parseTargetedRef(ref);
86
+ if (parsed.targetPath) return ref;
87
+ return `${parsed.configRef}#${targetPath}`;
88
+ }
89
+
90
+ function rewriteExtendsTarget(
91
+ entry: Record<string, unknown> | undefined,
92
+ targetPath: string,
93
+ ): boolean {
94
+ if (!entry?.extends) return false;
95
+
96
+ if (typeof entry.extends === "string") {
97
+ const next = ensureTargetedRef(entry.extends, targetPath);
98
+ if (next === entry.extends) return false;
99
+ entry.extends = next;
100
+ return true;
101
+ }
102
+
103
+ if (typeof entry.extends === "object") {
104
+ let changed = false;
105
+ for (const [key, value] of Object.entries(entry.extends as Record<string, unknown>)) {
106
+ if (typeof value !== "string") continue;
107
+ const next = ensureTargetedRef(value, targetPath);
108
+ if (next !== value) {
109
+ (entry.extends as Record<string, unknown>)[key] = next;
110
+ changed = true;
111
+ }
112
+ }
113
+ return changed;
114
+ }
115
+
116
+ return false;
117
+ }
118
+
119
+ function migrateRootConfigTargets(config: Record<string, unknown>): boolean {
120
+ let changed = false;
121
+ const app =
122
+ config.app && typeof config.app === "object"
123
+ ? (config.app as Record<string, unknown>)
124
+ : undefined;
125
+
126
+ if (app?.api && typeof app.api === "object") {
127
+ changed = rewriteExtendsTarget(app.api as Record<string, unknown>, "app.api") || changed;
128
+ }
129
+ if (app?.auth && typeof app.auth === "object") {
130
+ changed = rewriteExtendsTarget(app.auth as Record<string, unknown>, "app.auth") || changed;
131
+ }
132
+
133
+ if (config.plugins && typeof config.plugins === "object") {
134
+ for (const [pluginKey, pluginValue] of Object.entries(
135
+ config.plugins as Record<string, unknown>,
136
+ )) {
137
+ if (typeof pluginValue === "string") {
138
+ const next = ensureTargetedRef(pluginValue, `plugins.${pluginKey}`);
139
+ if (next !== pluginValue) {
140
+ (config.plugins as Record<string, unknown>)[pluginKey] = next;
141
+ changed = true;
142
+ }
143
+ continue;
144
+ }
145
+ if (!pluginValue || typeof pluginValue !== "object") continue;
146
+ changed =
147
+ rewriteExtendsTarget(pluginValue as Record<string, unknown>, `plugins.${pluginKey}`) ||
148
+ changed;
149
+ }
150
+ }
151
+
152
+ return changed;
153
+ }
154
+
155
+ function migratePluginProviderConfig(config: Record<string, unknown>, pluginKey: string): boolean {
156
+ let changed = false;
157
+ if (!config.plugins || typeof config.plugins !== "object") {
158
+ return false;
159
+ }
160
+
161
+ const plugins = config.plugins as Record<string, unknown>;
162
+ const entry = plugins[pluginKey];
163
+ if (!entry || typeof entry !== "object") return false;
164
+
165
+ const pluginEntry = entry as Record<string, unknown>;
166
+
167
+ if ("name" in pluginEntry) {
168
+ delete pluginEntry.name;
169
+ changed = true;
170
+ }
171
+
172
+ if (typeof pluginEntry.development === "string" && pluginEntry.development.startsWith("local:")) {
173
+ if ("extends" in pluginEntry) {
174
+ delete pluginEntry.extends;
175
+ changed = true;
176
+ }
177
+ }
178
+
179
+ changed = rewriteExtendsTarget(pluginEntry, `plugins.${pluginKey}`) || changed;
180
+
181
+ return changed;
182
+ }
183
+
184
+ function mergePluginConfigIntoRoot(
185
+ rootConfig: Record<string, unknown>,
186
+ pluginKey: string,
187
+ pluginConfig: Record<string, unknown>,
188
+ ): boolean {
189
+ let changed = false;
190
+
191
+ if (!rootConfig.plugins || typeof rootConfig.plugins !== "object") {
192
+ rootConfig.plugins = {};
193
+ changed = true;
194
+ }
195
+ const plugins = rootConfig.plugins as Record<string, unknown>;
196
+ if (!plugins[pluginKey] || typeof plugins[pluginKey] !== "object") {
197
+ plugins[pluginKey] = {};
198
+ changed = true;
199
+ }
200
+
201
+ const entry = plugins[pluginKey] as Record<string, unknown>;
202
+
203
+ const pluginData = extractPluginEntry(pluginConfig, pluginKey);
204
+
205
+ const apiData = getApiEntry(pluginConfig);
206
+
207
+ if (pluginData) {
208
+ for (const key of [
209
+ "secrets",
210
+ "variables",
211
+ "routes",
212
+ "sidebar",
213
+ "production",
214
+ "integrity",
215
+ "proxy",
216
+ ] as const) {
217
+ if (pluginData[key] !== undefined && entry[key] === undefined) {
218
+ entry[key] = pluginData[key];
219
+ changed = true;
220
+ }
221
+ }
222
+
223
+ if (typeof pluginData.development === "string" && pluginData.development.startsWith("local:")) {
224
+ pluginData.development = `local:plugins/${pluginKey}`;
225
+ }
226
+ if (entry.development === undefined && pluginData.development !== undefined) {
227
+ entry.development = pluginData.development;
228
+ changed = true;
229
+ }
230
+ }
231
+
232
+ if (apiData) {
233
+ for (const key of [
234
+ "production",
235
+ "integrity",
236
+ "proxy",
237
+ "variables",
238
+ "secrets",
239
+ "sidebar",
240
+ "routes",
241
+ ] as const) {
242
+ if (apiData[key] !== undefined && entry[key] === undefined) {
243
+ entry[key] = apiData[key];
244
+ changed = true;
245
+ }
246
+ }
247
+ }
248
+
249
+ if ("extends" in entry) {
250
+ const extendsStr = typeof entry.extends === "string" ? entry.extends : undefined;
251
+ if (!extendsStr || extendsStr.includes(`#plugins.${pluginKey}`)) {
252
+ delete entry.extends;
253
+ changed = true;
254
+ }
255
+ }
256
+
257
+ if ("name" in entry) {
258
+ delete entry.name;
259
+ changed = true;
260
+ }
261
+
262
+ if (configHasTopLevelFields(pluginConfig, pluginKey)) {
263
+ if (entry.routes === undefined && Array.isArray(pluginConfig.routes)) {
264
+ entry.routes = pluginConfig.routes;
265
+ changed = true;
266
+ }
267
+ if (entry.sidebar === undefined && Array.isArray(pluginConfig.sidebar)) {
268
+ entry.sidebar = pluginConfig.sidebar;
269
+ changed = true;
270
+ }
271
+ const api = getApiEntry(pluginConfig);
272
+ if (api) {
273
+ if (entry.routes === undefined && Array.isArray(api.routes)) {
274
+ entry.routes = api.routes;
275
+ changed = true;
276
+ }
277
+ if (entry.sidebar === undefined && Array.isArray(api.sidebar)) {
278
+ entry.sidebar = api.sidebar;
279
+ changed = true;
280
+ }
281
+ }
282
+ }
283
+
284
+ return changed;
285
+ }
286
+
287
+ function extractPluginEntry(
288
+ pluginConfig: Record<string, unknown>,
289
+ pluginKey: string,
290
+ ): Record<string, unknown> | null {
291
+ if (
292
+ pluginConfig.plugins &&
293
+ typeof pluginConfig.plugins === "object" &&
294
+ (pluginConfig.plugins as Record<string, unknown>)[pluginKey] &&
295
+ typeof (pluginConfig.plugins as Record<string, unknown>)[pluginKey] === "object"
296
+ ) {
297
+ return (pluginConfig.plugins as Record<string, unknown>)[pluginKey] as Record<string, unknown>;
298
+ }
299
+
300
+ const fallback: Record<string, unknown> = {};
301
+ if (pluginConfig.sidebar !== undefined) {
302
+ fallback.sidebar = pluginConfig.sidebar;
303
+ }
304
+ if (pluginConfig.routes !== undefined) {
305
+ fallback.routes = pluginConfig.routes;
306
+ }
307
+ if (Object.keys(fallback).length > 0) {
308
+ return fallback;
309
+ }
310
+
311
+ return null;
312
+ }
313
+
314
+ function configHasTopLevelFields(
315
+ pluginConfig: Record<string, unknown>,
316
+ _pluginKey: string,
317
+ ): boolean {
318
+ return (
319
+ (pluginConfig.routes !== undefined && Array.isArray(pluginConfig.routes)) ||
320
+ (pluginConfig.sidebar !== undefined && Array.isArray(pluginConfig.sidebar)) ||
321
+ getApiEntry(pluginConfig) !== null
322
+ );
323
+ }
324
+
325
+ function getApiEntry(pluginConfig: Record<string, unknown>): Record<string, unknown> | null {
326
+ if (!pluginConfig.app || typeof pluginConfig.app !== "object") return null;
327
+ const app = pluginConfig.app as Record<string, unknown>;
328
+ if (!app.api || typeof app.api !== "object") return null;
329
+ return app.api as Record<string, unknown>;
330
+ }
331
+
332
+ export async function migrateBosConfigFiles(projectDir: string): Promise<string[]> {
333
+ const migrated: string[] = [];
334
+ const rootConfigPath = join(projectDir, "bos.config.json");
335
+
336
+ if (existsSync(rootConfigPath)) {
337
+ const rootConfig = JSON.parse(readFileSync(rootConfigPath, "utf-8")) as Record<string, unknown>;
338
+ let rootChanged = migrateRootConfigTargets(rootConfig);
339
+
340
+ const pluginConfigPaths = await glob("plugins/*/bos.config.json", {
341
+ cwd: projectDir,
342
+ nodir: true,
343
+ dot: false,
344
+ absolute: false,
345
+ });
346
+
347
+ for (const relativePath of pluginConfigPaths) {
348
+ const match = relativePath.match(/^plugins\/([^/]+)\/bos\.config\.json$/);
349
+ const pluginKey = match?.[1];
350
+ if (!pluginKey) continue;
351
+
352
+ const filePath = join(projectDir, relativePath);
353
+ try {
354
+ const pluginConfig = JSON.parse(readFileSync(filePath, "utf-8")) as Record<string, unknown>;
355
+ rootChanged = mergePluginConfigIntoRoot(rootConfig, pluginKey, pluginConfig) || rootChanged;
356
+ } catch {}
357
+
358
+ try {
359
+ rmSync(filePath);
360
+ migrated.push(relativePath);
361
+ } catch {}
362
+ }
363
+
364
+ if (rootConfig.plugins && typeof rootConfig.plugins === "object") {
365
+ for (const pluginKey of Object.keys(rootConfig.plugins as Record<string, unknown>)) {
366
+ rootChanged = migratePluginProviderConfig(rootConfig, pluginKey) || rootChanged;
367
+ }
368
+ }
369
+
370
+ if (rootChanged || migrated.length > 0) {
371
+ await saveBosConfig(projectDir, rootConfig);
372
+ if (!migrated.includes("bos.config.json")) {
373
+ migrated.push("bos.config.json");
374
+ }
375
+ }
376
+ }
377
+
378
+ return migrated;
379
+ }
380
+
73
381
  async function loadParentPluginOptions(projectDir: string): Promise<{
74
382
  localConfig: Record<string, unknown>;
75
383
  parentPlugins: Record<string, unknown>;
@@ -142,7 +450,16 @@ async function addSelectedParentPlugins(projectDir: string): Promise<string[]> {
142
450
  : {};
143
451
  const nextPlugins = { ...localPlugins };
144
452
  for (const key of selected) {
145
- nextPlugins[key] = pluginOptions.parentPlugins[key];
453
+ const parentPlugin = pluginOptions.parentPlugins[key];
454
+ if (parentPlugin && typeof parentPlugin === "object") {
455
+ const nextPlugin = structuredClone(parentPlugin as Record<string, unknown>);
456
+ rewriteExtendsTarget(nextPlugin, `plugins.${key}`);
457
+ nextPlugins[key] = nextPlugin;
458
+ } else if (typeof parentPlugin === "string") {
459
+ nextPlugins[key] = ensureTargetedRef(parentPlugin, `plugins.${key}`);
460
+ } else {
461
+ nextPlugins[key] = parentPlugin;
462
+ }
146
463
  }
147
464
 
148
465
  pluginOptions.localConfig.plugins = nextPlugins;
@@ -442,6 +759,10 @@ export async function upgradeTemplate(
442
759
  }
443
760
  });
444
761
 
762
+ const migratedBosConfigs = await timePhase(timings, "migrate bos configs", () =>
763
+ migrateBosConfigFiles(projectDir),
764
+ );
765
+
445
766
  let syncResult: UpgradeResult["sync"];
446
767
  let addedPlugins: string[] = [];
447
768
  if (!options.noSync) {
@@ -465,7 +786,10 @@ export async function upgradeTemplate(
465
786
  }
466
787
 
467
788
  const migratedFiles = await timePhase(timings, "clean obsolete files", async () => {
468
- const nextMigratedFiles = await rewriteLegacyUiImports(projectDir);
789
+ const nextMigratedFiles = [
790
+ ...migratedBosConfigs,
791
+ ...(await rewriteLegacyUiImports(projectDir)),
792
+ ];
469
793
  for (const file of OBSOLETE_FILES) {
470
794
  const filePath = join(projectDir, file);
471
795
  if (existsSync(filePath)) {