everything-dev 1.16.1 → 1.16.3

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 (75) hide show
  1. package/dist/api-contract.cjs +16 -5
  2. package/dist/api-contract.cjs.map +1 -1
  3. package/dist/api-contract.mjs +16 -5
  4. package/dist/api-contract.mjs.map +1 -1
  5. package/dist/cli/infra.cjs +127 -0
  6. package/dist/cli/infra.cjs.map +1 -0
  7. package/dist/cli/infra.mjs +124 -0
  8. package/dist/cli/infra.mjs.map +1 -0
  9. package/dist/cli/init.cjs +9 -0
  10. package/dist/cli/init.cjs.map +1 -1
  11. package/dist/cli/init.d.cts +2 -1
  12. package/dist/cli/init.d.cts.map +1 -1
  13. package/dist/cli/init.d.mts +2 -1
  14. package/dist/cli/init.d.mts.map +1 -1
  15. package/dist/cli/init.mjs +9 -1
  16. package/dist/cli/init.mjs.map +1 -1
  17. package/dist/cli/sync.cjs +6 -0
  18. package/dist/cli/sync.cjs.map +1 -1
  19. package/dist/cli/sync.mjs +6 -0
  20. package/dist/cli/sync.mjs.map +1 -1
  21. package/dist/cli/timing.cjs +30 -0
  22. package/dist/cli/timing.cjs.map +1 -0
  23. package/dist/cli/timing.mjs +27 -0
  24. package/dist/cli/timing.mjs.map +1 -0
  25. package/dist/cli/upgrade.cjs +66 -47
  26. package/dist/cli/upgrade.cjs.map +1 -1
  27. package/dist/cli/upgrade.mjs +66 -47
  28. package/dist/cli/upgrade.mjs.map +1 -1
  29. package/dist/cli.cjs +9 -0
  30. package/dist/cli.cjs.map +1 -1
  31. package/dist/cli.mjs +9 -0
  32. package/dist/cli.mjs.map +1 -1
  33. package/dist/components/dev-view.cjs +1 -1
  34. package/dist/components/dev-view.mjs +1 -1
  35. package/dist/components/streaming-view.cjs +1 -1
  36. package/dist/components/streaming-view.mjs +1 -1
  37. package/dist/contract.cjs +7 -0
  38. package/dist/contract.cjs.map +1 -1
  39. package/dist/contract.d.cts +22 -1
  40. package/dist/contract.d.cts.map +1 -1
  41. package/dist/contract.d.mts +22 -1
  42. package/dist/contract.d.mts.map +1 -1
  43. package/dist/contract.mjs +7 -1
  44. package/dist/contract.mjs.map +1 -1
  45. package/dist/dev-session.cjs +5 -3
  46. package/dist/dev-session.cjs.map +1 -1
  47. package/dist/dev-session.mjs +3 -3
  48. package/dist/dev-session.mjs.map +1 -1
  49. package/dist/index.cjs +1 -0
  50. package/dist/index.d.cts +2 -2
  51. package/dist/index.d.mts +2 -2
  52. package/dist/index.mjs +2 -2
  53. package/dist/near-cli.cjs +1 -1
  54. package/dist/near-cli.mjs +1 -1
  55. package/dist/orchestrator.cjs +1 -1
  56. package/dist/orchestrator.mjs +1 -1
  57. package/dist/plugin.cjs +56 -39
  58. package/dist/plugin.cjs.map +1 -1
  59. package/dist/plugin.d.cts +8 -0
  60. package/dist/plugin.d.cts.map +1 -1
  61. package/dist/plugin.d.mts +8 -0
  62. package/dist/plugin.d.mts.map +1 -1
  63. package/dist/plugin.mjs +54 -37
  64. package/dist/plugin.mjs.map +1 -1
  65. package/package.json +1 -1
  66. package/src/api-contract.ts +21 -3
  67. package/src/cli/infra.ts +190 -0
  68. package/src/cli/init.ts +4 -0
  69. package/src/cli/sync.ts +9 -0
  70. package/src/cli/timing.ts +36 -0
  71. package/src/cli/upgrade.ts +82 -53
  72. package/src/cli.ts +15 -0
  73. package/src/contract.ts +8 -0
  74. package/src/dev-session.ts +1 -1
  75. package/src/plugin.ts +98 -67
package/src/plugin.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { randomBytes } from "node:crypto";
2
1
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
2
  import { basename, dirname, join, resolve } from "node:path";
4
3
  import * as p from "@clack/prompts";
5
4
  import { Effect } from "effect";
6
5
  import { syncApiContractBridge } from "./api-contract";
7
6
  import { buildRuntimeConfig, detectLocalPackages, prepareDevelopmentRuntimeConfig } from "./app";
7
+ import { ensureEnvFile, writeGeneratedInfra } from "./cli/infra";
8
8
  import {
9
9
  copyFilteredFiles,
10
10
  fetchParentConfig,
@@ -13,12 +13,14 @@ import {
13
13
  readTemplatekeep,
14
14
  resolveSourceDir,
15
15
  runBunInstall,
16
+ runDockerComposeUp,
16
17
  runTypesGen,
17
18
  writeInitSnapshot,
18
19
  } from "./cli/init";
19
20
  import { promptInitOptions } from "./cli/prompts";
20
21
  import { getStatus } from "./cli/status";
21
22
  import { syncTemplate } from "./cli/sync";
23
+ import { timePhase } from "./cli/timing";
22
24
  import { upgradeTemplate } from "./cli/upgrade";
23
25
  import {
24
26
  buildRuntimePluginsForConfig,
@@ -29,8 +31,12 @@ import {
29
31
  resolveLocalDevelopmentPath,
30
32
  writeResolvedConfig,
31
33
  } from "./config";
32
- import { type BosConfigResult, bosContract, type PluginListResult } from "./contract";
33
- import { devApp, startApp } from "./dev-session";
34
+ import {
35
+ type BosConfigResult,
36
+ bosContract,
37
+ type PhaseTiming,
38
+ type PluginListResult,
39
+ } from "./contract";
34
40
  import {
35
41
  buildRegistryConfigUrl,
36
42
  buildRegistryConfigUrlForNetwork,
@@ -57,36 +63,8 @@ import { run } from "./utils/run";
57
63
  import { saveBosConfig } from "./utils/save-config";
58
64
  import { colors } from "./utils/theme";
59
65
 
60
- function ensureEnvFile(configDir: string, opts?: { domain?: string }): void {
61
- const envPath = join(configDir, ".env");
62
- const examplePath = join(configDir, ".env.example");
63
-
64
- if (existsSync(envPath)) return;
65
-
66
- if (!existsSync(examplePath)) return;
67
-
68
- const content = readFileSync(examplePath, "utf-8");
69
- const lines = content.split("\n");
70
-
71
- const secret = randomBytes(32).toString("base64url");
72
- const corsOrigin = opts?.domain
73
- ? `http://localhost:3000,https://${opts.domain}`
74
- : "http://localhost:3000";
75
-
76
- const updated = lines
77
- .map((line) => {
78
- if (/^BETTER_AUTH_SECRET=/.test(line)) {
79
- return `BETTER_AUTH_SECRET=${secret}`;
80
- }
81
- if (/^CORS_ORIGIN=/.test(line)) {
82
- return `CORS_ORIGIN=${corsOrigin}`;
83
- }
84
- return line;
85
- })
86
- .join("\n");
87
-
88
- writeFileSync(envPath, updated);
89
- p.log.info(`Created .env from .env.example with generated BETTER_AUTH_SECRET`);
66
+ async function loadDevSession() {
67
+ return import("./dev-session");
90
68
  }
91
69
 
92
70
  const buildCommands: Record<string, { cmd: string; args: string[] }> = {
@@ -869,6 +847,7 @@ export default createPlugin({
869
847
  interactive: input.interactive,
870
848
  };
871
849
 
850
+ const { devApp } = await loadDevSession();
872
851
  devApp(orchestrator, services, runtimeConfig);
873
852
 
874
853
  return {
@@ -1029,6 +1008,7 @@ export default createPlugin({
1029
1008
  noLogs: true,
1030
1009
  };
1031
1010
 
1011
+ const { startApp } = await loadDevSession();
1032
1012
  startApp(orchestrator, services, runtimeConfig);
1033
1013
  return {
1034
1014
  status: "running" as const,
@@ -1292,6 +1272,7 @@ export default createPlugin({
1292
1272
 
1293
1273
  init: builder.init.handler(async ({ input }) => {
1294
1274
  try {
1275
+ const timings: PhaseTiming[] = [];
1295
1276
  let extendsAccount = input.extendsAccount;
1296
1277
  let extendsGateway = input.extendsGateway;
1297
1278
  let directory = input.directory;
@@ -1314,7 +1295,9 @@ export default createPlugin({
1314
1295
  let parentPluginKeys: string[] = [];
1315
1296
  let parentConfig: BosConfig | null = null;
1316
1297
  try {
1317
- parentConfig = await fetchParentConfig(extendsAccount, extendsGateway);
1298
+ parentConfig = await timePhase(timings, "parent config", () =>
1299
+ fetchParentConfig(extendsAccount!, extendsGateway!),
1300
+ );
1318
1301
  if (parentConfig?.plugins && typeof parentConfig.plugins === "object") {
1319
1302
  parentPluginKeys = Object.keys(parentConfig.plugins);
1320
1303
  }
@@ -1342,11 +1325,14 @@ export default createPlugin({
1342
1325
  }
1343
1326
 
1344
1327
  directory = directory || domain || extendsGateway;
1328
+ const targetDir = resolve(directory);
1345
1329
  plugins = plugins ?? [];
1346
1330
 
1347
1331
  if (!parentConfig) {
1348
1332
  try {
1349
- parentConfig = await fetchParentConfig(extendsAccount, extendsGateway);
1333
+ parentConfig = await timePhase(timings, "parent config", () =>
1334
+ fetchParentConfig(extendsAccount!, extendsGateway!),
1335
+ );
1350
1336
  } catch {
1351
1337
  return {
1352
1338
  status: "error" as const,
@@ -1358,6 +1344,7 @@ export default createPlugin({
1358
1344
  extends: `bos://${extendsAccount}/${extendsGateway}`,
1359
1345
  plugins: plugins ?? [],
1360
1346
  filesCopied: 0,
1347
+ timings,
1361
1348
  error: `No config found at bos://${extendsAccount}/${extendsGateway} — are you sure this is the right parent?`,
1362
1349
  };
1363
1350
  }
@@ -1367,11 +1354,13 @@ export default createPlugin({
1367
1354
  sourceDir,
1368
1355
  parentConfig: resolvedParentConfig,
1369
1356
  cleanup,
1370
- } = await resolveSourceDir({
1371
- extendsAccount,
1372
- extendsGateway,
1373
- source: input.source,
1374
- });
1357
+ } = await timePhase(timings, "template source", () =>
1358
+ resolveSourceDir({
1359
+ extendsAccount,
1360
+ extendsGateway,
1361
+ source: input.source,
1362
+ }),
1363
+ );
1375
1364
 
1376
1365
  parentConfig = resolvedParentConfig;
1377
1366
 
@@ -1405,44 +1394,84 @@ export default createPlugin({
1405
1394
  const s = p.spinner();
1406
1395
  s.start("Setting up project");
1407
1396
 
1408
- const filesCopied = await copyFilteredFiles(sourceDir, directory, patterns, {
1409
- withHost,
1410
- plugins,
1411
- pluginRoutes,
1412
- });
1397
+ const filesCopied = await timePhase(timings, "copy files", () =>
1398
+ copyFilteredFiles(sourceDir, targetDir, patterns, {
1399
+ withHost,
1400
+ plugins,
1401
+ pluginRoutes,
1402
+ }),
1403
+ );
1413
1404
 
1414
- await personalizeConfig(directory, {
1415
- extendsAccount,
1416
- extendsGateway,
1417
- account: account || extendsAccount,
1418
- domain: domain || extendsGateway,
1419
- plugins,
1420
- pluginRoutes,
1421
- workspaceOpts: { sourceDir },
1422
- withHost,
1423
- });
1405
+ await timePhase(timings, "personalize config", () =>
1406
+ personalizeConfig(targetDir, {
1407
+ extendsAccount,
1408
+ extendsGateway,
1409
+ account: account || extendsAccount,
1410
+ domain: domain || extendsGateway,
1411
+ plugins,
1412
+ pluginRoutes,
1413
+ workspaceOpts: { sourceDir },
1414
+ withHost,
1415
+ }),
1416
+ );
1424
1417
 
1425
- await writeInitSnapshot(directory, extendsAccount, extendsGateway, sourceDir, patterns, {
1426
- withHost,
1427
- plugins,
1428
- pluginRoutes,
1429
- });
1418
+ await timePhase(timings, "write snapshot", () =>
1419
+ writeInitSnapshot(targetDir, extendsAccount, extendsGateway, sourceDir, patterns, {
1420
+ withHost,
1421
+ plugins,
1422
+ pluginRoutes,
1423
+ }),
1424
+ );
1430
1425
 
1431
- ensureEnvFile(directory, { domain });
1426
+ const initConfig = await timePhase(timings, "resolve config", () =>
1427
+ loadConfig({ cwd: targetDir }),
1428
+ );
1429
+ if (initConfig?.runtime) {
1430
+ await timePhase(timings, "generate env/docker", async () => {
1431
+ writeGeneratedInfra(targetDir, initConfig.runtime);
1432
+ });
1433
+ }
1434
+ await timePhase(timings, "create env file", async () => {
1435
+ ensureEnvFile(targetDir);
1436
+ });
1432
1437
 
1433
1438
  if (!input.noInstall) {
1434
- await runBunInstall(directory);
1435
- await runTypesGen(directory);
1436
- await generateDatabaseMigrations(directory);
1439
+ await timePhase(timings, "install dependencies", () => runBunInstall(targetDir));
1440
+ await timePhase(timings, "generate types", () => runTypesGen(targetDir));
1441
+ await timePhase(timings, "generate migrations", () =>
1442
+ generateDatabaseMigrations(targetDir),
1443
+ );
1437
1444
  }
1438
1445
 
1439
- const initConfig = await loadConfig({ cwd: directory });
1440
- if (initConfig?.config) {
1441
- await generateCodeArtifacts(directory, initConfig.config);
1446
+ if (input.noInstall && initConfig?.config) {
1447
+ await timePhase(timings, "generate code artifacts", () =>
1448
+ generateCodeArtifacts(targetDir, initConfig.config),
1449
+ );
1442
1450
  }
1443
1451
 
1444
1452
  s.stop("Project initialized");
1445
1453
 
1454
+ if (!input.noInteractive) {
1455
+ const shouldStartDocker = await p.confirm({
1456
+ message: "Run docker compose up -d --wait?",
1457
+ initialValue: true,
1458
+ });
1459
+
1460
+ if (shouldStartDocker === true) {
1461
+ const dockerSpinner = p.spinner();
1462
+ dockerSpinner.start("Starting Docker services");
1463
+ try {
1464
+ await timePhase(timings, "docker compose up", () => runDockerComposeUp(targetDir));
1465
+ dockerSpinner.stop("Docker services ready");
1466
+ } catch (error) {
1467
+ dockerSpinner.stop("Docker services not started");
1468
+ p.log.warn(
1469
+ `docker compose up -d --wait failed: ${error instanceof Error ? error.message : error}`,
1470
+ );
1471
+ }
1472
+ }
1473
+ }
1474
+
1446
1475
  return {
1447
1476
  status: "initialized" as const,
1448
1477
  directory,
@@ -1453,6 +1482,7 @@ export default createPlugin({
1453
1482
  extends: `bos://${extendsAccount}/${extendsGateway}`,
1454
1483
  plugins,
1455
1484
  filesCopied,
1485
+ timings,
1456
1486
  };
1457
1487
  } finally {
1458
1488
  await cleanup();
@@ -1471,6 +1501,7 @@ export default createPlugin({
1471
1501
  : "",
1472
1502
  plugins: input.plugins ?? [],
1473
1503
  filesCopied: 0,
1504
+ timings: [],
1474
1505
  error: error instanceof Error ? error.message : "Unknown error",
1475
1506
  };
1476
1507
  }