everything-dev 1.17.0 → 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 (47) hide show
  1. package/dist/cli/init.cjs +165 -84
  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 +164 -85
  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/upgrade.cjs +114 -49
  14. package/dist/cli/upgrade.cjs.map +1 -1
  15. package/dist/cli/upgrade.mjs +114 -49
  16. package/dist/cli/upgrade.mjs.map +1 -1
  17. package/dist/contract.cjs +1 -4
  18. package/dist/contract.cjs.map +1 -1
  19. package/dist/contract.d.cts +6 -12
  20. package/dist/contract.d.cts.map +1 -1
  21. package/dist/contract.d.mts +6 -12
  22. package/dist/contract.d.mts.map +1 -1
  23. package/dist/contract.meta.cjs +5 -5
  24. package/dist/contract.meta.cjs.map +1 -1
  25. package/dist/contract.meta.d.cts +9 -9
  26. package/dist/contract.meta.d.mts +9 -9
  27. package/dist/contract.meta.mjs +5 -5
  28. package/dist/contract.meta.mjs.map +1 -1
  29. package/dist/contract.mjs +1 -4
  30. package/dist/contract.mjs.map +1 -1
  31. package/dist/plugin.cjs +64 -106
  32. package/dist/plugin.cjs.map +1 -1
  33. package/dist/plugin.d.cts +4 -7
  34. package/dist/plugin.d.cts.map +1 -1
  35. package/dist/plugin.d.mts +4 -7
  36. package/dist/plugin.d.mts.map +1 -1
  37. package/dist/plugin.mjs +65 -107
  38. package/dist/plugin.mjs.map +1 -1
  39. package/dist/types.d.cts +2 -2
  40. package/dist/types.d.mts +2 -2
  41. package/package.json +1 -1
  42. package/src/cli/init.ts +224 -162
  43. package/src/cli/prompts.ts +17 -22
  44. package/src/cli/upgrade.ts +173 -56
  45. package/src/contract.meta.ts +6 -8
  46. package/src/contract.ts +1 -4
  47. package/src/plugin.ts +118 -187
package/src/plugin.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  runBunInstall,
16
16
  runDockerComposeUp,
17
17
  runTypesGen,
18
+ scaffoldMinimalProject,
18
19
  writeInitSnapshot,
19
20
  } from "./cli/init";
20
21
  import { promptInitOptions } from "./cli/prompts";
@@ -58,7 +59,7 @@ import {
58
59
  } from "./service-descriptor";
59
60
  import { syncAndGenerateSharedUi } from "./shared";
60
61
  import { writePluginSidebarGen } from "./sidebar";
61
- import type { BosConfig, BosPluginRef, RuntimeConfig, SourceMode } from "./types";
62
+ import type { BosConfig, BosConfigInput, BosPluginRef, RuntimeConfig, SourceMode } from "./types";
62
63
  import { run } from "./utils/run";
63
64
  import { saveBosConfig } from "./utils/save-config";
64
65
  import { colors } from "./utils/theme";
@@ -646,96 +647,32 @@ export default createPlugin({
646
647
  const version = manifest?.plugin.version ?? pkgJson.version;
647
648
 
648
649
  if (publishedUrl) {
649
- const pluginConfigPath = join(localPath, "bos.config.json");
650
- if (existsSync(pluginConfigPath)) {
651
- try {
652
- const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8")) as Record<
653
- string,
654
- unknown
655
- >;
656
- if (!pluginConfig.plugins || typeof pluginConfig.plugins !== "object") {
657
- pluginConfig.plugins = {};
658
- }
659
- const plugins = pluginConfig.plugins as Record<string, unknown>;
660
- if (!plugins[input.key] || typeof plugins[input.key] !== "object") {
661
- plugins[input.key] = {};
662
- }
663
- const entry = plugins[input.key] as Record<string, unknown>;
664
- entry.production = publishedUrl;
665
- if (integrity) {
666
- entry.integrity = integrity;
667
- } else {
668
- delete entry.integrity;
669
- }
670
- writeFileSync(pluginConfigPath, `${JSON.stringify(pluginConfig, null, 2)}\n`);
671
- console.log(` ✅ Updated ${pluginConfigPath}: plugins.${input.key}.production`);
672
- } catch (err) {
673
- console.error(
674
- ` ❌ Failed to update plugin bos.config.json:`,
675
- err instanceof Error ? err.message : err,
676
- );
677
- }
678
- }
679
-
680
- const account = deps.bosConfig.account;
681
- const network = getNetworkIdForAccount(account);
682
-
683
- let pluginDomain: string | undefined;
684
- if (existsSync(pluginConfigPath)) {
685
- try {
686
- const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
687
- if (typeof pluginConfig.domain === "string") {
688
- pluginDomain = pluginConfig.domain;
689
- }
690
- } catch {}
691
- }
692
- if (!pluginDomain) {
693
- pluginDomain = `${input.key}.${deps.bosConfig.domain ?? "everything.dev"}`;
694
- }
695
-
650
+ const rootConfigPath = join(deps.configDir, "bos.config.json");
696
651
  try {
697
- const registryEntries: Record<string, string> = {};
698
-
699
- if (existsSync(pluginConfigPath)) {
700
- try {
701
- const publishedPluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
702
- delete publishedPluginConfig.development;
703
- registryEntries[`apps/${account}/${pluginDomain}/bos.config.json`] =
704
- JSON.stringify(publishedPluginConfig);
705
- } catch {}
652
+ const rootConfig = JSON.parse(readFileSync(rootConfigPath, "utf-8")) as Record<
653
+ string,
654
+ unknown
655
+ >;
656
+ if (!rootConfig.plugins || typeof rootConfig.plugins !== "object") {
657
+ rootConfig.plugins = {};
706
658
  }
707
-
708
- if (Object.keys(registryEntries).length > 0) {
709
- const payload = JSON.stringify(registryEntries);
710
- const argsBase64 = Buffer.from(payload).toString("base64");
711
- const privateKey = process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;
712
-
713
- await Effect.runPromise(ensureNearCli);
714
- try {
715
- await Effect.runPromise(
716
- executeTransaction({
717
- account,
718
- contract: getRegistryNamespaceForNetwork(network),
719
- method: "__fastdata_kv",
720
- argsBase64,
721
- network,
722
- privateKey,
723
- gas: "50Tgas",
724
- deposit: "0NEAR",
725
- }),
726
- );
727
- } catch (registryError) {
728
- const txHash = extractTransactionHash(registryError);
729
- if (!txHash) {
730
- console.warn(
731
- `[publish] Plugin registry write failed: ${registryError instanceof Error ? registryError.message : registryError}`,
732
- );
733
- }
734
- }
659
+ const plugins = rootConfig.plugins as Record<string, unknown>;
660
+ if (!plugins[input.key] || typeof plugins[input.key] !== "object") {
661
+ plugins[input.key] = {};
735
662
  }
736
- } catch (registryError) {
737
- console.warn(
738
- `[publish] Plugin registry write skipped: ${registryError instanceof Error ? registryError.message : registryError}`,
663
+ const entry = plugins[input.key] as Record<string, unknown>;
664
+ entry.production = publishedUrl;
665
+ if (integrity) {
666
+ entry.integrity = integrity;
667
+ } else {
668
+ delete entry.integrity;
669
+ }
670
+ writeFileSync(rootConfigPath, `${JSON.stringify(rootConfig, null, 2)}\n`);
671
+ console.log(` ✅ Updated bos.config.json: plugins.${input.key}.production`);
672
+ } catch (err) {
673
+ console.error(
674
+ ` ❌ Failed to update bos.config.json:`,
675
+ err instanceof Error ? err.message : err,
739
676
  );
740
677
  }
741
678
 
@@ -1143,29 +1080,6 @@ export default createPlugin({
1143
1080
  [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishConfig),
1144
1081
  };
1145
1082
 
1146
- for (const [pluginKey, pluginEntry] of Object.entries(publishConfig.plugins ?? {})) {
1147
- const pluginRef = getPluginRef(pluginEntry);
1148
- if (!pluginRef?.development?.startsWith("local:")) continue;
1149
-
1150
- const localPath = join(deps.configDir, pluginRef.development.slice("local:".length));
1151
- const pluginConfigPath = join(localPath, "bos.config.json");
1152
- if (!existsSync(pluginConfigPath)) continue;
1153
-
1154
- try {
1155
- const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8")) as Record<
1156
- string,
1157
- unknown
1158
- >;
1159
- const pluginDomain =
1160
- typeof pluginConfig.domain === "string"
1161
- ? pluginConfig.domain
1162
- : `${pluginKey}.${gateway}`;
1163
- delete pluginConfig.development;
1164
- registryEntries[`apps/${account}/${pluginDomain}/bos.config.json`] =
1165
- JSON.stringify(pluginConfig);
1166
- } catch {}
1167
- }
1168
-
1169
1083
  const payload = JSON.stringify(registryEntries);
1170
1084
  const argsBase64 = Buffer.from(payload).toString("base64");
1171
1085
  const privateKey =
@@ -1277,8 +1191,8 @@ export default createPlugin({
1277
1191
  init: builder.init.handler(async ({ input }) => {
1278
1192
  try {
1279
1193
  const timings: PhaseTiming[] = [];
1280
- let extendsAccount = input.extendsAccount;
1281
- let extendsGateway = input.extendsGateway;
1194
+ let extendsAccount = "";
1195
+ let extendsGateway = "";
1282
1196
  let directory = input.directory;
1283
1197
  let account = input.account;
1284
1198
  let domain = input.domain;
@@ -1286,10 +1200,13 @@ export default createPlugin({
1286
1200
  let plugins = input.plugins;
1287
1201
 
1288
1202
  if (input.extends) {
1289
- const match = input.extends.match(/^(?:bos:\/\/)?([^/]+)\/(.+)$/);
1203
+ const normalized = input.extends.startsWith("bos://")
1204
+ ? input.extends
1205
+ : `bos://${input.extends}`;
1206
+ const match = normalized.match(/^bos:\/\/([^/]+)\/(.+)$/);
1290
1207
  if (match) {
1291
- if (!extendsAccount) extendsAccount = match[1];
1292
- if (!extendsGateway) extendsGateway = match[2];
1208
+ extendsAccount = match[1];
1209
+ extendsGateway = match[2];
1293
1210
  }
1294
1211
  }
1295
1212
 
@@ -1300,7 +1217,7 @@ export default createPlugin({
1300
1217
  let parentConfig: BosConfig | null = null;
1301
1218
  try {
1302
1219
  parentConfig = await timePhase(timings, "parent config", () =>
1303
- fetchParentConfig(extendsAccount!, extendsGateway!),
1220
+ fetchParentConfig(extendsAccount, extendsGateway),
1304
1221
  );
1305
1222
  if (parentConfig?.plugins && typeof parentConfig.plugins === "object") {
1306
1223
  parentPluginKeys = Object.keys(parentConfig.plugins);
@@ -1309,9 +1226,7 @@ export default createPlugin({
1309
1226
 
1310
1227
  if (!input.noInteractive) {
1311
1228
  const prompted = await promptInitOptions({
1312
- extendsAccount,
1313
- extendsGateway,
1314
- extends: input.extends,
1229
+ extends: `bos://${extendsAccount}/${extendsGateway}`,
1315
1230
  directory,
1316
1231
  account,
1317
1232
  domain,
@@ -1331,25 +1246,25 @@ export default createPlugin({
1331
1246
  directory = directory || domain || extendsGateway;
1332
1247
  const targetDir = resolve(directory);
1333
1248
  plugins = plugins ?? [];
1249
+ const extendsRef = `bos://${extendsAccount}/${extendsGateway}`;
1334
1250
 
1335
1251
  if (!parentConfig) {
1336
1252
  try {
1337
1253
  parentConfig = await timePhase(timings, "parent config", () =>
1338
- fetchParentConfig(extendsAccount!, extendsGateway!),
1254
+ fetchParentConfig(extendsAccount, extendsGateway),
1339
1255
  );
1340
1256
  } catch {
1341
1257
  return {
1342
1258
  status: "error" as const,
1343
1259
  directory,
1344
- extendsAccount,
1345
- extendsGateway,
1260
+ extendsRef,
1346
1261
  account,
1347
1262
  domain,
1348
- extends: `bos://${extendsAccount}/${extendsGateway}`,
1263
+ extends: extendsRef,
1349
1264
  plugins: plugins ?? [],
1350
1265
  filesCopied: 0,
1351
1266
  timings,
1352
- error: `No config found at bos://${extendsAccount}/${extendsGateway} — are you sure this is the right parent?`,
1267
+ error: `No config found at ${extendsRef} — are you sure this is the right parent?`,
1353
1268
  };
1354
1269
  }
1355
1270
  }
@@ -1368,66 +1283,82 @@ export default createPlugin({
1368
1283
 
1369
1284
  parentConfig = resolvedParentConfig;
1370
1285
 
1286
+ const isMinimalScaffold = sourceDir === "";
1287
+
1371
1288
  try {
1372
- const patterns = await readTemplatekeep(sourceDir);
1373
- if (patterns.length === 0) {
1374
- return {
1375
- status: "error" as const,
1376
- directory,
1377
- extendsAccount,
1378
- extendsGateway,
1379
- account,
1380
- domain,
1381
- extends: `bos://${extendsAccount}/${extendsGateway}`,
1382
- plugins: plugins ?? [],
1383
- filesCopied: 0,
1384
- error: "No .templatekeep found in template source",
1385
- };
1386
- }
1289
+ const s = p.spinner();
1290
+ s.start("Setting up project");
1387
1291
 
1388
- const pluginRoutes: Record<string, string[]> = {};
1389
- const parentRuntimePlugins = await buildRuntimePluginsForConfig(
1390
- parentConfig as BosConfig,
1391
- sourceDir,
1392
- "production",
1393
- );
1394
- for (const [key, plugin] of Object.entries(parentRuntimePlugins ?? {})) {
1395
- if (plugin.routes && plugin.routes.length > 0) {
1396
- pluginRoutes[key] = plugin.routes;
1292
+ let filesCopied: number;
1293
+
1294
+ if (isMinimalScaffold) {
1295
+ filesCopied = await timePhase(timings, "scaffold project", () =>
1296
+ scaffoldMinimalProject(targetDir, parentConfig as unknown as BosConfigInput, {
1297
+ extendsAccount,
1298
+ extendsGateway,
1299
+ account: account || extendsAccount,
1300
+ domain,
1301
+ plugins,
1302
+ withHost,
1303
+ }),
1304
+ );
1305
+ } else {
1306
+ const patterns = await readTemplatekeep(sourceDir);
1307
+ if (patterns.length === 0) {
1308
+ return {
1309
+ status: "error" as const,
1310
+ directory,
1311
+ extendsRef,
1312
+ account,
1313
+ domain,
1314
+ extends: extendsRef,
1315
+ plugins: plugins ?? [],
1316
+ filesCopied: 0,
1317
+ error: "No .templatekeep found in template source",
1318
+ };
1397
1319
  }
1398
- }
1399
1320
 
1400
- const s = p.spinner();
1401
- s.start("Setting up project");
1321
+ const pluginRoutes: Record<string, string[]> = {};
1322
+ const parentRuntimePlugins = await buildRuntimePluginsForConfig(
1323
+ parentConfig as BosConfig,
1324
+ sourceDir,
1325
+ "production",
1326
+ );
1327
+ for (const [key, plugin] of Object.entries(parentRuntimePlugins ?? {})) {
1328
+ if (plugin.routes && plugin.routes.length > 0) {
1329
+ pluginRoutes[key] = plugin.routes;
1330
+ }
1331
+ }
1402
1332
 
1403
- const filesCopied = await timePhase(timings, "copy files", () =>
1404
- copyFilteredFiles(sourceDir, targetDir, patterns, {
1405
- withHost,
1406
- plugins,
1407
- pluginRoutes,
1408
- }),
1409
- );
1333
+ filesCopied = await timePhase(timings, "copy files", () =>
1334
+ copyFilteredFiles(sourceDir, targetDir, patterns, {
1335
+ withHost,
1336
+ plugins,
1337
+ pluginRoutes,
1338
+ }),
1339
+ );
1410
1340
 
1411
- await timePhase(timings, "personalize config", () =>
1412
- personalizeConfig(targetDir, {
1413
- extendsAccount,
1414
- extendsGateway,
1415
- account: account || extendsAccount,
1416
- domain: domain || extendsGateway,
1417
- plugins,
1418
- pluginRoutes,
1419
- workspaceOpts: { sourceDir },
1420
- withHost,
1421
- }),
1422
- );
1341
+ await timePhase(timings, "personalize config", () =>
1342
+ personalizeConfig(targetDir, {
1343
+ extendsAccount,
1344
+ extendsGateway,
1345
+ account: account || extendsAccount,
1346
+ domain: domain || extendsGateway,
1347
+ plugins,
1348
+ pluginRoutes,
1349
+ workspaceOpts: { sourceDir },
1350
+ withHost,
1351
+ }),
1352
+ );
1423
1353
 
1424
- await timePhase(timings, "write snapshot", () =>
1425
- writeInitSnapshot(targetDir, extendsAccount, extendsGateway, sourceDir, patterns, {
1426
- withHost,
1427
- plugins,
1428
- pluginRoutes,
1429
- }),
1430
- );
1354
+ await timePhase(timings, "write snapshot", () =>
1355
+ writeInitSnapshot(targetDir, extendsAccount, extendsGateway, sourceDir, patterns, {
1356
+ withHost,
1357
+ plugins,
1358
+ pluginRoutes,
1359
+ }),
1360
+ );
1361
+ }
1431
1362
 
1432
1363
  const initConfig = await timePhase(timings, "resolve config", () =>
1433
1364
  loadConfig({ cwd: targetDir }),
@@ -1481,11 +1412,10 @@ export default createPlugin({
1481
1412
  return {
1482
1413
  status: "initialized" as const,
1483
1414
  directory,
1484
- extendsAccount,
1485
- extendsGateway,
1415
+ extendsRef,
1486
1416
  account,
1487
1417
  domain,
1488
- extends: `bos://${extendsAccount}/${extendsGateway}`,
1418
+ extends: extendsRef,
1489
1419
  plugins,
1490
1420
  filesCopied,
1491
1421
  timings,
@@ -1494,17 +1424,18 @@ export default createPlugin({
1494
1424
  await cleanup();
1495
1425
  }
1496
1426
  } catch (error) {
1427
+ const extendsRef = input.extends
1428
+ ? input.extends.startsWith("bos://")
1429
+ ? input.extends
1430
+ : `bos://${input.extends}`
1431
+ : "bos://dev.everything.near/everything.dev";
1497
1432
  return {
1498
1433
  status: "error" as const,
1499
1434
  directory: input.directory ?? "",
1500
- extendsAccount: input.extendsAccount ?? "",
1501
- extendsGateway: input.extendsGateway ?? "",
1435
+ extendsRef,
1502
1436
  account: input.account,
1503
1437
  domain: input.domain,
1504
- extends:
1505
- input.extendsAccount && input.extendsGateway
1506
- ? `bos://${input.extendsAccount}/${input.extendsGateway}`
1507
- : "",
1438
+ extends: extendsRef,
1508
1439
  plugins: input.plugins ?? [],
1509
1440
  filesCopied: 0,
1510
1441
  timings: [],