everything-dev 1.25.0 → 1.26.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/src/cli/init.ts CHANGED
@@ -378,7 +378,6 @@ export async function personalizeConfig(
378
378
  staging?: unknown;
379
379
  },
380
380
  ): Promise<void> {
381
- const isInit = opts.mode !== "sync";
382
381
  const has = (section: OverrideSection) => opts.overrides.includes(section);
383
382
 
384
383
  const configPath = join(destination, "bos.config.json");
@@ -395,20 +394,18 @@ export async function personalizeConfig(
395
394
  }
396
395
  if (opts.repository) {
397
396
  config.repository = opts.repository;
398
- } else if (isInit) {
397
+ } else {
399
398
  delete config.repository;
400
399
  }
401
400
 
402
- if (isInit) {
403
- const inheritableFields = ["title", "description", "testnet", "staging"] as const;
404
- for (const field of inheritableFields) {
405
- if (!(field in opts)) {
406
- delete config[field];
407
- }
401
+ const inheritableFields = ["title", "description", "testnet", "staging"] as const;
402
+ for (const field of inheritableFields) {
403
+ if (!(field in opts)) {
404
+ delete config[field];
408
405
  }
409
406
  }
410
407
 
411
- if (isInit && config.app && typeof config.app === "object") {
408
+ if (config.app && typeof config.app === "object") {
412
409
  const app = config.app as Record<string, unknown>;
413
410
 
414
411
  for (const entryKey of Object.keys(app)) {
@@ -447,6 +444,7 @@ export async function personalizeConfig(
447
444
  plugins[pluginKey] = pluginObj;
448
445
  } else if (plugin && typeof plugin === "object") {
449
446
  pluginObj = { ...(plugin as Record<string, unknown>) };
447
+ plugins[pluginKey] = pluginObj;
450
448
  } else {
451
449
  continue;
452
450
  }
@@ -455,7 +453,7 @@ export async function personalizeConfig(
455
453
  }
456
454
 
457
455
  if (Object.keys(plugins).length === 0) {
458
- config.plugins = {};
456
+ delete config.plugins;
459
457
  }
460
458
  }
461
459
  } else {
@@ -475,12 +473,21 @@ export async function personalizeConfig(
475
473
  ws.packages = ws.packages.filter((p: string) => {
476
474
  if (p.startsWith("packages/")) return false;
477
475
  if (p === "host") return has("host");
478
- if (p === "plugins/*") return has("plugins") && (opts.plugins?.length ?? 0) > 0;
476
+ if (p === "plugins/*") return false;
479
477
  const pluginMatch = p.match(/^plugins\/([^/]+)/);
480
478
  if (pluginMatch)
481
479
  return has("plugins") && (opts.plugins?.includes(pluginMatch[1]) ?? true);
482
480
  return true;
483
481
  });
482
+
483
+ if (has("plugins") && (opts.plugins?.length ?? 0) > 0) {
484
+ for (const plugin of opts.plugins ?? []) {
485
+ const pluginWorkspace = `plugins/${plugin}`;
486
+ if (!ws.packages.includes(pluginWorkspace)) {
487
+ ws.packages.push(pluginWorkspace);
488
+ }
489
+ }
490
+ }
484
491
  }
485
492
  }
486
493
 
@@ -762,6 +769,11 @@ export function stripOrphanedWorkspacesFromLockfile(
762
769
  }
763
770
  }
764
771
 
772
+ export function removeInitLockfile(lockfilePath: string): void {
773
+ if (!existsSync(lockfilePath)) return;
774
+ rmSync(lockfilePath, { force: true });
775
+ }
776
+
765
777
  const WORKSPACE_LOCAL_PATHS: Record<string, string> = {
766
778
  "everything-dev": "packages/everything-dev",
767
779
  "every-plugin": "packages/every-plugin",
@@ -89,7 +89,7 @@ export async function promptInitOptions(input: {
89
89
  const overrides =
90
90
  input.overrides ??
91
91
  ((await p.multiselect({
92
- message: "Which sections to override locally?",
92
+ message: "Which sections would you like to customize",
93
93
  options: OVERRIDE_OPTIONS,
94
94
  initialValues: ["ui", "api"] as OverrideSection[],
95
95
  required: false,
@@ -96,7 +96,7 @@ export const cliCommandMeta = {
96
96
  description: "Comma-separated plugin keys to include (requires --overrides=plugins)",
97
97
  },
98
98
  overrides: {
99
- description: "Comma-separated sections to override locally: ui,api,host,plugins",
99
+ description: "Comma-separated sections to customize locally: ui,api,host,plugins",
100
100
  },
101
101
  noInteractive: { description: "Skip prompts, use flags only" },
102
102
  noInstall: { description: "Skip bun install" },
package/src/plugin.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { basename, dirname, join, resolve } from "node:path";
3
+ import process from "node:process";
3
4
  import * as p from "@clack/prompts";
4
5
  import { Effect } from "effect";
5
6
  import { syncApiContractBridge } from "./api-contract";
@@ -12,11 +13,13 @@ import {
12
13
  generateDatabaseMigrations,
13
14
  personalizeConfig,
14
15
  readTemplatekeep,
16
+ removeInitLockfile,
15
17
  resolveSourceDir,
16
18
  runBunInstall,
17
19
  runDockerComposeUp,
18
20
  runTypesGen,
19
21
  scaffoldMinimalProject,
22
+ stripOrphanedWorkspacesFromLockfile,
20
23
  writeInitSnapshot,
21
24
  } from "./cli/init";
22
25
  import { promptInitOptions } from "./cli/prompts";
@@ -1234,6 +1237,8 @@ export default createPlugin({
1234
1237
 
1235
1238
  if (!input.noInteractive) {
1236
1239
  s.stop("Config fetched");
1240
+ const initialExtendsAccount = extendsAccount;
1241
+ const initialExtendsGateway = extendsGateway;
1237
1242
  const prompted = await promptInitOptions({
1238
1243
  extends: `bos://${extendsAccount}/${extendsGateway}`,
1239
1244
  directory,
@@ -1250,6 +1255,58 @@ export default createPlugin({
1250
1255
  domain = prompted.domain;
1251
1256
  plugins = prompted.plugins;
1252
1257
  overrides = prompted.overrides;
1258
+
1259
+ if (
1260
+ !parentConfig ||
1261
+ prompted.extendsAccount !== initialExtendsAccount ||
1262
+ prompted.extendsGateway !== initialExtendsGateway
1263
+ ) {
1264
+ try {
1265
+ parentConfig = await timePhase(
1266
+ timings,
1267
+ "parent config",
1268
+ () => fetchParentConfig(prompted.extendsAccount, prompted.extendsGateway),
1269
+ s,
1270
+ );
1271
+ if (parentConfig?.plugins && typeof parentConfig.plugins === "object") {
1272
+ parentPluginKeys = Object.keys(parentConfig.plugins);
1273
+ } else {
1274
+ parentPluginKeys = [];
1275
+ }
1276
+ } catch {
1277
+ return {
1278
+ status: "error" as const,
1279
+ directory,
1280
+ extendsRef: `bos://${prompted.extendsAccount}/${prompted.extendsGateway}`,
1281
+ account,
1282
+ domain,
1283
+ extends: `bos://${prompted.extendsAccount}/${prompted.extendsGateway}`,
1284
+ plugins,
1285
+ overrides,
1286
+ filesCopied: 0,
1287
+ timings,
1288
+ error: `No config found at bos://${prompted.extendsAccount}/${prompted.extendsGateway} — are you sure this is the right parent?`,
1289
+ };
1290
+ }
1291
+ s.stop("Config fetched");
1292
+ }
1293
+
1294
+ if (
1295
+ typeof parentConfig?.title === "string" &&
1296
+ parentConfig.title.trim() &&
1297
+ typeof parentConfig.description === "string" &&
1298
+ parentConfig.description.trim()
1299
+ ) {
1300
+ const shouldContinue = await p.confirm({
1301
+ message: `You will be extending ${parentConfig.title} - ${parentConfig.description}. Continue?`,
1302
+ initialValue: true,
1303
+ });
1304
+
1305
+ if (p.isCancel(shouldContinue) || !shouldContinue) {
1306
+ process.exit(0);
1307
+ }
1308
+ }
1309
+
1253
1310
  s.start("Setting up project");
1254
1311
  }
1255
1312
 
@@ -1429,9 +1486,9 @@ export default createPlugin({
1429
1486
  }
1430
1487
 
1431
1488
  const lockfilePath = join(targetDir, "bun.lock");
1432
- if (existsSync(lockfilePath)) {
1433
- rmSync(lockfilePath, { force: true });
1434
- }
1489
+ const allowedWorkspaces = computeAllowedWorkspaces(overrides, plugins);
1490
+ stripOrphanedWorkspacesFromLockfile(lockfilePath, allowedWorkspaces);
1491
+ removeInitLockfile(lockfilePath);
1435
1492
 
1436
1493
  const initConfig = await timePhase(
1437
1494
  timings,
@@ -1747,3 +1804,18 @@ function extractTransactionHash(error: unknown) {
1747
1804
  const match = message.match(/Transaction ID:\s*([A-Za-z0-9]+)/i);
1748
1805
  return match?.[1];
1749
1806
  }
1807
+
1808
+ function computeAllowedWorkspaces(overrides: string[], plugins?: string[]): string[] {
1809
+ const workspaces: string[] = [];
1810
+ for (const section of overrides) {
1811
+ if (section === "host") workspaces.push("host");
1812
+ if (section === "ui") workspaces.push("ui");
1813
+ if (section === "api") workspaces.push("api");
1814
+ }
1815
+ if (plugins) {
1816
+ for (const plugin of plugins) {
1817
+ workspaces.push(`plugins/${plugin}`);
1818
+ }
1819
+ }
1820
+ return workspaces;
1821
+ }