everything-dev 1.22.0 → 1.24.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.
package/src/cli/init.ts CHANGED
@@ -91,10 +91,16 @@ export async function readTemplatekeep(sourceDir: string): Promise<string[]> {
91
91
  }
92
92
 
93
93
  const content = readFileSync(keepFile, "utf-8");
94
- return content
94
+ const patterns = content
95
95
  .split("\n")
96
96
  .map((line) => line.trim())
97
97
  .filter((line) => line.length > 0 && !line.startsWith("#"));
98
+
99
+ if (!patterns.includes(".templatekeep")) {
100
+ patterns.unshift(".templatekeep");
101
+ }
102
+
103
+ return patterns;
98
104
  }
99
105
 
100
106
  export async function fetchParentConfig(
@@ -366,6 +372,10 @@ export async function personalizeConfig(
366
372
  workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };
367
373
  mode?: "init" | "sync";
368
374
  repository?: string;
375
+ title?: string;
376
+ description?: string;
377
+ testnet?: string;
378
+ staging?: unknown;
369
379
  },
370
380
  ): Promise<void> {
371
381
  const isInit = opts.mode !== "sync";
@@ -385,6 +395,17 @@ export async function personalizeConfig(
385
395
  }
386
396
  if (opts.repository) {
387
397
  config.repository = opts.repository;
398
+ } else if (isInit) {
399
+ delete config.repository;
400
+ }
401
+
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
+ }
408
+ }
388
409
  }
389
410
 
390
411
  if (isInit && config.app && typeof config.app === "object") {
@@ -489,6 +510,10 @@ export async function personalizeConfig(
489
510
  scripts.typecheck = scripts.typecheck.replace(/bun run --cwd host tsc --noEmit & ?/, "");
490
511
  }
491
512
  }
513
+
514
+ if (!scripts.bos) {
515
+ scripts.bos = "node_modules/.bin/bos";
516
+ }
492
517
  }
493
518
 
494
519
  if (pkg.devDependencies && typeof pkg.devDependencies === "object") {
@@ -514,8 +539,12 @@ export async function personalizeConfig(
514
539
  workspaces.catalog["everything-dev"] = spec.rootCatalog["everything-dev"];
515
540
  workspaces.catalog["every-plugin"] = spec.rootCatalog["every-plugin"];
516
541
  }
517
- if (!deps["everything-dev"] && spec) deps["everything-dev"] = "catalog:";
518
- if (!deps["every-plugin"] && spec) deps["every-plugin"] = "catalog:";
542
+ const frameworkCatalog = resolveFrameworkCatalog();
543
+ for (const [name, version] of Object.entries(frameworkCatalog)) {
544
+ workspaces.catalog[name] = version;
545
+ }
546
+ if (!deps["everything-dev"]) deps["everything-dev"] = "catalog:";
547
+ if (!deps["every-plugin"]) deps["every-plugin"] = "catalog:";
519
548
 
520
549
  writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
521
550
  }
@@ -630,18 +659,108 @@ export interface AuthServices {
630
659
  `;
631
660
  }
632
661
 
633
- export async function runBunInstall(destination: string): Promise<void> {
634
- await execCommand("bun", ["install", "--ignore-scripts"], destination, { stdio: "inherit" });
662
+ export async function runBunInstall(
663
+ destination: string,
664
+ spinner?: { message: (msg: string) => void },
665
+ ): Promise<void> {
666
+ await runWithProgress(
667
+ "bun",
668
+ ["install", "--ignore-scripts"],
669
+ destination,
670
+ spinner,
671
+ "Installing dependencies",
672
+ );
635
673
  }
636
674
 
637
- export async function runTypesGen(destination: string): Promise<void> {
638
- await execCommand("node_modules/.bin/bos", ["types", "gen"], destination, { stdio: "inherit" });
675
+ export async function runBunInstallForUpgrade(
676
+ destination: string,
677
+ spinner?: { message: (msg: string) => void },
678
+ ): Promise<void> {
679
+ const lockfilePath = join(destination, "bun.lock");
680
+ if (existsSync(lockfilePath)) {
681
+ rmSync(lockfilePath, { force: true });
682
+ }
683
+
684
+ await runWithProgress("bun", ["install"], destination, spinner, "Installing dependencies");
685
+ }
686
+
687
+ export async function runTypesGen(
688
+ destination: string,
689
+ spinner?: { message: (msg: string) => void },
690
+ ): Promise<void> {
691
+ await runWithProgress(
692
+ "node_modules/.bin/bos",
693
+ ["types", "gen"],
694
+ destination,
695
+ spinner,
696
+ "Generating types",
697
+ );
639
698
  }
640
699
 
641
700
  export async function runDockerComposeUp(destination: string): Promise<void> {
642
701
  await execCommand("docker", ["compose", "up", "-d", "--wait"], destination, { stdio: "inherit" });
643
702
  }
644
703
 
704
+ async function runWithProgress(
705
+ command: string,
706
+ args: string[],
707
+ cwd: string,
708
+ spinner: { message: (msg: string) => void } | undefined,
709
+ label: string,
710
+ ): Promise<void> {
711
+ const timeout = COMMAND_TIMEOUTS[command] ?? 2 * 60_000;
712
+ const child = execa(command, args, { cwd, stdio: "inherit", timeout });
713
+
714
+ if (spinner) {
715
+ const start = Date.now();
716
+ const interval = setInterval(() => {
717
+ const elapsed = Math.round((Date.now() - start) / 1000);
718
+ spinner.message(`${label}... (${elapsed}s)`);
719
+ }, 2000);
720
+ try {
721
+ await child;
722
+ } finally {
723
+ clearInterval(interval);
724
+ }
725
+ } else {
726
+ await child;
727
+ }
728
+ }
729
+
730
+ export function stripOrphanedWorkspacesFromLockfile(
731
+ lockfilePath: string,
732
+ allowedWorkspaces: string[],
733
+ ): void {
734
+ if (!existsSync(lockfilePath)) return;
735
+
736
+ const content = readFileSync(lockfilePath, "utf-8");
737
+ let lockfile: Record<string, unknown>;
738
+ try {
739
+ lockfile = JSON.parse(content) as Record<string, unknown>;
740
+ } catch {
741
+ return;
742
+ }
743
+
744
+ const workspaces = lockfile.workspaces;
745
+ if (!workspaces || typeof workspaces !== "object") return;
746
+
747
+ const workspaceMap = workspaces as Record<string, unknown>;
748
+ const allowed = new Set(["", ...allowedWorkspaces]);
749
+
750
+ const keys = Object.keys(workspaceMap);
751
+ let changed = false;
752
+ for (const key of keys) {
753
+ if (!allowed.has(key)) {
754
+ delete workspaceMap[key];
755
+ changed = true;
756
+ }
757
+ }
758
+
759
+ if (changed) {
760
+ writeFileSync(lockfilePath, `${JSON.stringify(lockfile, null, 2)}\n`);
761
+ }
762
+ }
763
+
645
764
  const WORKSPACE_LOCAL_PATHS: Record<string, string> = {
646
765
  "everything-dev": "packages/everything-dev",
647
766
  "every-plugin": "packages/every-plugin",
@@ -649,6 +768,49 @@ const WORKSPACE_LOCAL_PATHS: Record<string, string> = {
649
768
 
650
769
  function resolveFrameworkCatalog(): Record<string, string> {
651
770
  const catalog: Record<string, string> = {};
771
+
772
+ try {
773
+ const selfPkgPath = require.resolve("everything-dev/package.json");
774
+ const selfPkgDir = dirname(selfPkgPath);
775
+ const monorepoPkgPath = join(selfPkgDir, "..", "..", "package.json");
776
+ if (existsSync(monorepoPkgPath)) {
777
+ const monorepoPkg = JSON.parse(readFileSync(monorepoPkgPath, "utf-8")) as {
778
+ workspaces?: { catalog?: Record<string, string> };
779
+ };
780
+ const sourceCatalog = monorepoPkg.workspaces?.catalog;
781
+ if (sourceCatalog && typeof sourceCatalog === "object") {
782
+ for (const [name, version] of Object.entries(sourceCatalog)) {
783
+ if (typeof version === "string") {
784
+ catalog[name] = version;
785
+ }
786
+ }
787
+ }
788
+ }
789
+ } catch {}
790
+
791
+ try {
792
+ const selfPkgPath = require.resolve("everything-dev/package.json");
793
+ const selfPkg = JSON.parse(readFileSync(selfPkgPath, "utf-8")) as {
794
+ version?: string;
795
+ workspaces?: { catalog?: Record<string, string> };
796
+ };
797
+ if (selfPkg.version && !catalog["everything-dev"]) {
798
+ catalog["everything-dev"] = `^${selfPkg.version}`;
799
+ }
800
+ const sourceCatalog = selfPkg.workspaces?.catalog;
801
+ if (sourceCatalog && typeof sourceCatalog === "object") {
802
+ for (const [name, version] of Object.entries(sourceCatalog)) {
803
+ if (typeof version === "string" && !catalog[name]) {
804
+ catalog[name] = version;
805
+ }
806
+ }
807
+ }
808
+ } catch {}
809
+
810
+ if (Object.keys(catalog).length > 0) {
811
+ return catalog;
812
+ }
813
+
652
814
  for (const packageName of FRAMEWORK_PACKAGES) {
653
815
  try {
654
816
  const resolved = require.resolve(`${packageName}/package.json`);
@@ -672,6 +834,8 @@ export async function scaffoldMinimalProject(
672
834
  plugins?: string[];
673
835
  overrides: OverrideSection[];
674
836
  repository?: string;
837
+ title?: string;
838
+ description?: string;
675
839
  },
676
840
  ): Promise<number> {
677
841
  mkdirSync(destination, { recursive: true });
@@ -683,6 +847,8 @@ export async function scaffoldMinimalProject(
683
847
  account: opts.account || opts.extendsAccount,
684
848
  ...(opts.domain ? { domain: opts.domain } : {}),
685
849
  ...(opts.repository ? { repository: opts.repository } : {}),
850
+ ...(opts.title ? { title: opts.title } : {}),
851
+ ...(opts.description ? { description: opts.description } : {}),
686
852
  };
687
853
 
688
854
  if (parentConfig.app && typeof parentConfig.app === "object") {
@@ -760,6 +926,7 @@ export async function scaffoldMinimalProject(
760
926
  typecheck: "node_modules/.bin/bos types gen && tsc --noEmit",
761
927
  postinstall: "node_modules/.bin/bos types gen || true",
762
928
  "types:gen": "node_modules/.bin/bos types gen",
929
+ bos: "node_modules/.bin/bos",
763
930
  },
764
931
  dependencies: {
765
932
  "everything-dev": "catalog:",
@@ -7,7 +7,7 @@ import type { PhaseTiming, UpgradeOptions, UpgradeResult } from "../contract";
7
7
  import { resolveExtendsRef } from "../merge";
8
8
  import { saveBosConfig } from "../utils/save-config";
9
9
  import { readInstalledFrameworkVersion } from "./framework-version";
10
- import { fetchParentConfig, runBunInstall, runTypesGen } from "./init";
10
+ import { fetchParentConfig, runBunInstallForUpgrade, runTypesGen } from "./init";
11
11
  import { syncTemplate } from "./sync";
12
12
  import { timePhase } from "./timing";
13
13
 
@@ -781,7 +781,7 @@ export async function upgradeTemplate(
781
781
  }
782
782
 
783
783
  if ((hasUpdates || addedPlugins.length > 0) && !options.noInstall) {
784
- await timePhase(timings, "install dependencies", () => runBunInstall(projectDir));
784
+ await timePhase(timings, "install dependencies", () => runBunInstallForUpgrade(projectDir));
785
785
  await timePhase(timings, "generate types", () => runTypesGen(projectDir));
786
786
  }
787
787
 
package/src/plugin.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { basename, dirname, join, resolve } from "node:path";
3
3
  import * as p from "@clack/prompts";
4
4
  import { Effect } from "effect";
@@ -1428,6 +1428,11 @@ export default createPlugin({
1428
1428
  );
1429
1429
  }
1430
1430
 
1431
+ const lockfilePath = join(targetDir, "bun.lock");
1432
+ if (existsSync(lockfilePath)) {
1433
+ rmSync(lockfilePath, { force: true });
1434
+ }
1435
+
1431
1436
  const initConfig = await timePhase(
1432
1437
  timings,
1433
1438
  "resolve config",
@@ -1454,8 +1459,12 @@ export default createPlugin({
1454
1459
  );
1455
1460
 
1456
1461
  if (!input.noInstall) {
1457
- await timePhase(timings, "install dependencies", () => runBunInstall(targetDir), s);
1458
- await timePhase(timings, "generate types", () => runTypesGen(targetDir), s);
1462
+ await timePhase(timings, "install dependencies", () =>
1463
+ runBunInstall(targetDir, s ?? undefined),
1464
+ );
1465
+ await timePhase(timings, "generate types", () =>
1466
+ runTypesGen(targetDir, s ?? undefined),
1467
+ );
1459
1468
  await timePhase(
1460
1469
  timings,
1461
1470
  "generate migrations",