@dbx-tools/projen 0.6.46 → 0.6.47

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/README.md CHANGED
@@ -70,6 +70,19 @@ Built-in tag mixins set runtime defaults for `shared`, `node`, `cli`, `server`,
70
70
  `ui`, and `openapi`. Repo-specific mixins layer package-specific dependencies,
71
71
  scripts, and generated files on top.
72
72
 
73
+ A tag layers over a shared compiler floor every package gets at construction:
74
+ ES2022 plus the web-platform globals available in every runtime, and deliberately
75
+ no DOM lib and no Node types, so agnostic code stays isomorphic. The tags are what
76
+ add an environment on top - `node` adds Node types, `ui` adds the DOM lib. That
77
+ floor is also where `jsx` lives, for a reason worth knowing before moving it:
78
+ packages resolve each other to SOURCE, so a consumer type-checks its dependency's
79
+ files under its own tsconfig. The moment any package re-exports a `.tsx` module,
80
+ every package that imports it - however far down the graph, whatever its tag -
81
+ fails with `TS6142: ... but '--jsx' is not set`. Setting `jsx` per consumer is the
82
+ wrong fix, since the consumer authors no JSX and cannot know a transitive
83
+ dependency started to. The option is inert without JSX in the graph: it selects
84
+ how JSX syntax compiles and adds no lib, global, or type dependency.
85
+
73
86
  ## Work With Package Discovery
74
87
 
75
88
  ```ts
@@ -94,7 +107,11 @@ barrels.generateBarrels();
94
107
  ```
95
108
 
96
109
  `generateCodegen()` reads `package.json` `codegen.inputs` and writes generated
97
- schema modules. `generateBarrels()` writes package-root `index.ts` barrels with
110
+ schema modules. They are written read-only, and the root ESLint task runs with
111
+ `--fix` (which fails on a read-only file), so each generated module is added to
112
+ `ignorePatterns` at synth - named individually via `codegen.codegenModulePaths()`,
113
+ never as a blanket `<package>/src/**`. A codegen package may hold hand-written
114
+ modules beside its generated ones, and those must stay linted. `generateBarrels()` writes package-root `index.ts` barrels with
98
115
  module namespaces and flat unique type exports, returning the number that
99
116
  actually changed. A barrel whose export surface is unchanged is left untouched,
100
117
  read-only bit included, so concurrent writers never collide over it. Every
@@ -167,13 +184,13 @@ file contract as the CLI.
167
184
  - `barrels` / `moduleExports` - public entrypoint generation.
168
185
  - `codegen` - `.d.ts` to zod schema generation.
169
186
  - `openapi` - tsoa/OpenAPI package generation.
170
- - `vite` / `tsconfig` / `vscode` - generated support files/components.
187
+ - `bunApp` / `tsconfig` / `vscode` - generated support files/components.
171
188
  - `generated` / `clean` / `watch` / `scaffold` - read-only file stamping,
172
189
  cleanup, watchers, and synth orchestration.
173
190
  - `publish` - packaging and tag-based release helpers.
174
191
  - `engineRoot` - engine package root resolution for bootstrapped repos.
175
192
 
176
193
  The engine registers its commands as projen tasks on the workspace root, so run
177
- them with `pnpm run <task>` - `sync` (add `--watch`), `barrels`, `openapi`, and
194
+ them with `bun run <task>` - `sync` (add `--watch`), `barrels`, `openapi`, and
178
195
  `clean`. [`@dbx-tools/cli`](../packages/cli/dbx-tools) is only needed to
179
196
  bootstrap a folder that has no `.projenrc.ts` or toolchain yet.
package/package.json CHANGED
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@clack/prompts": "^1.7.0",
29
- "@dbx-tools/core": "^0.6.40",
30
- "@dbx-tools/path": "^0.6.40",
31
- "@dbx-tools/shared-core": "^0.6.40",
29
+ "@dbx-tools/core": "0.6.47",
30
+ "@dbx-tools/path": "0.6.47",
31
+ "@dbx-tools/shared-core": "0.6.47",
32
32
  "commander": "^15.0.0",
33
33
  "concurrently": "^10.0.3",
34
34
  "constructs": "^10.6.0",
@@ -37,21 +37,17 @@
37
37
  "oxc-parser": "^0.90.0",
38
38
  "projen": "^0.101.16",
39
39
  "ts-to-zod": "^5.1.0",
40
- "tsx": "^4.23.0",
41
40
  "yaml": "^2.9.0"
42
41
  },
43
- "pnpm": {},
44
42
  "devEngines": {
45
43
  "packageManager": {
46
- "name": "pnpm",
47
- "version": ">=10",
44
+ "name": "bun",
48
45
  "onFail": "ignore"
49
46
  }
50
47
  },
51
48
  "main": "index.ts",
52
49
  "license": "Apache-2.0",
53
- "version": "0.6.46",
54
- "packageManager": "pnpm@10.33.0",
50
+ "version": "0.6.47",
55
51
  "types": "index.ts",
56
52
  "type": "module",
57
53
  "exports": {
@@ -63,5 +59,5 @@
63
59
  "src",
64
60
  "tasks"
65
61
  ],
66
- "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\"."
62
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
67
63
  }
package/src/clean.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The `clean` task (`pnpm run clean`): enumerate the workspace's generated files (plus every
2
+ * The `clean` task (`bun run clean`): enumerate the workspace's generated files (plus every
3
3
  * `node_modules` directory) and delete a chosen subset. This is the pure filesystem
4
4
  * half - reusable enumerate/remove helpers; the task that drives them (argv `-y`, the
5
5
  * `@clack/prompts` multiselect picker with all preselected, the TTY guard) lives in
@@ -17,8 +17,8 @@
17
17
  * `.projenrc.ts` imports the engine by SOURCE path (relative into the repo, e.g.
18
18
  * `packages/node/projen/src/...`, or from an installed package such as
19
19
  * `@dbx-tools/projen`), so even after deleting every barrel, manifest, and
20
- * `.projen/*`, `pnpm exec projen` still rebuilds the whole tree. Removing `node_modules` additionally requires a
21
- * `pnpm install` first - the engine's runtime deps live there - so a clean that takes
20
+ * `.projen/*`, `bun run default` still rebuilds the whole tree. Removing `node_modules` additionally requires a
21
+ * `bun install` first - the engine's runtime deps live there - so a clean that takes
22
22
  * `node_modules` must be followed by reinstall, then re-synth.
23
23
  */
24
24
  import { existsSync, rmSync, statSync } from "node:fs";
package/src/codegen.ts CHANGED
@@ -89,6 +89,25 @@ function parseInputArg(value: string): CodegenInput {
89
89
  return { source: value.slice(0, eq), name: value.slice(eq + 1) };
90
90
  }
91
91
 
92
+ /**
93
+ * The `src/` modules a set of `codegen.inputs` specs will emit, as package-relative
94
+ * posix paths - WITHOUT resolving or reading any input.
95
+ *
96
+ * This exists so callers that only need to know WHICH files are generated (the
97
+ * ESLint ignore list, above all) can ask without running codegen. The output names
98
+ * are derived from the specs alone, so it is safe to call during synth, before
99
+ * `node_modules` is resolved and before any manifest has been written to disk -
100
+ * hence taking the specs rather than a directory to read them from.
101
+ *
102
+ * Naming a package's generated modules is strictly better than ignoring its whole
103
+ * `src/`: a codegen package may also hold HAND-WRITTEN modules (shared-genie
104
+ * generates `dashboards.ts` next to a hand-written `genie-model.ts`), and those
105
+ * must stay linted.
106
+ */
107
+ export function codegenModulePaths(inputs: readonly string[]): string[] {
108
+ return inputs.map((input) => `src/${parseInputArg(input).name}.ts`);
109
+ }
110
+
92
111
  /**
93
112
  * Resolve a codegen input to an absolute path. A `node_modules/...` source is
94
113
  * searched for in each `node_modules` from the consuming package up to the
package/src/openapi.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  * OpenAPI client generator.
17
17
  *
18
18
  * `tsoa`, `typescript`, and `openapi-typescript` are loaded lazily (heavy, and only
19
- * needed for `pnpm run openapi`), so importing this module stays cheap. `tsoa` and
19
+ * needed for `bun run openapi`), so importing this module stays cheap. `tsoa` and
20
20
  * `typescript` are not engine dependencies at all - both are resolved out of the
21
21
  * consuming workspace, which is where they already live.
22
22
  */
package/src/project.ts CHANGED
@@ -14,7 +14,7 @@ import { dirname, join, relative, resolve } from "node:path";
14
14
  import { Component, IgnoreFile, Project, type TaskOptions, javascript, typescript } from "projen";
15
15
  import { ReleaseTrigger } from "projen/lib/release";
16
16
  import { generateBarrels } from "./barrels.ts";
17
- import { generateCodegen } from "./codegen.ts";
17
+ import { codegenModulePaths, generateCodegen } from "./codegen.ts";
18
18
  import { DBXToolsConfig, type DBXToolsConfigOptions } from "./dbx-tools-config.ts";
19
19
  import { resolvePkgRoot } from "./engine-root.ts";
20
20
  import { PnpmWorkspaceState, type DBXToolsPNPMWorkspaceOptions } from "./pnpm-workspace.ts";
@@ -172,7 +172,6 @@ export function applyCompilerOptions(
172
172
  if (value === undefined) continue;
173
173
  file.addOverride(`compilerOptions.${key}`, value);
174
174
  }
175
- if (compilerOptions.jsx) pkg.tsconfig?.addInclude("src/**/*.tsx");
176
175
  }
177
176
 
178
177
  /**
@@ -287,6 +286,17 @@ export function srcModuleExports(pkg: javascript.NodeProject): Record<string, st
287
286
  * only: the specifier style is a property of the SOURCE, so a `ui` package (which
288
287
  * publishes source and is excluded from the compiled surface) still has to accept
289
288
  * and rewrite it.
289
+ *
290
+ * `jsx` is here for the same reason, and it is NOT a per-tag concern even though
291
+ * only React packages author `.tsx`. Packages resolve each other to SOURCE
292
+ * (`main: index.ts`), so a consumer type-checks its dependency's files under its
293
+ * OWN tsconfig: the moment any package re-exports a `.tsx` module, every package
294
+ * that imports it - however far down the graph, whatever its tag - fails with
295
+ * `TS6142: ... but '--jsx' is not set`. Setting it per consumer is the wrong fix
296
+ * (the consumer does not author JSX and has no way to know a transitive dependency
297
+ * started to), so the floor carries it. The option is inert for a package with no
298
+ * `.tsx` in its graph: it selects how JSX syntax COMPILES and adds no lib, no
299
+ * global, and no type dependency on its own.
290
300
  */
291
301
  const SHARED_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions & {
292
302
  rewriteRelativeImportExtensions: boolean;
@@ -296,6 +306,7 @@ const SHARED_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions & {
296
306
  skipLibCheck: true,
297
307
  allowImportingTsExtensions: true,
298
308
  rewriteRelativeImportExtensions: true,
309
+ jsx: javascript.TypeScriptJsxMode.REACT_JSX,
299
310
  };
300
311
 
301
312
  /** Shared formatting rules, applied by projen's Prettier on whichever project is root. */
@@ -365,6 +376,13 @@ function defaultProjectOptions(options: DBXToolsProjectOptions): DBXToolsProject
365
376
  ...(isRoot ? {} : { npmAccess: javascript.NpmAccess.PUBLIC }),
366
377
  buildWorkflow: false,
367
378
  release: false,
379
+ // No `npm pack` step on any project. projen wires `package` into `build`, so
380
+ // `bunx projen build` would tarball all 36 manifests (root included) into
381
+ // gitignored `dist/js` on every CI run and never read them: publishing here
382
+ // is `bun publish` driving each package's own `prepack` (see
383
+ // {@link applyCompiledPublish} and the `publish` task), and `release: false`
384
+ // means no projen Publisher exists to consume the artifacts either.
385
+ package: false,
368
386
  jest: false,
369
387
  github: false,
370
388
  npmignoreEnabled: false,
@@ -570,8 +588,8 @@ export class DBXToolsNodeProject extends javascript.NodeProject implements DBXTo
570
588
  /**
571
589
  * A single package (usually created by a root's scan), or a standalone
572
590
  * compiling root. The agnostic tsconfig floor is applied at construction; the
573
- * source-first package fields (`main`/`types`/`exports` -> `index.ts`) and an
574
- * optional `vite.config.ts` are applied after. Per-tag deps/tsconfig arrive later
591
+ * source-first package fields (`main`/`types`/`exports` -> `index.ts`) and optional
592
+ * Bun app scaffolding are applied after. Per-tag deps/tsconfig arrive later
575
593
  * via the {@link PACKAGE_TAG_MIXINS} the root applies.
576
594
  */
577
595
  export class DBXToolsTypeScriptProject
@@ -608,6 +626,11 @@ export class DBXToolsTypeScriptProject
608
626
  },
609
627
  });
610
628
  this.scope = scope;
629
+ // Pairs with `jsx` in SHARED_COMPILER_OPTIONS: projen's default `include` is
630
+ // `src/**/*.ts` only, which silently omits a `.tsx` file from the program
631
+ // instead of failing, so authoring a React component would otherwise need
632
+ // per-package tsconfig config to be compiled at all.
633
+ this.tsconfig?.addInclude("src/**/*.tsx");
611
634
  this.dbxToolsConfig = new DBXToolsConfig(this, options);
612
635
  // Source-first entry: point the package at its package-ROOT `index.ts` barrel
613
636
  // so packages resolve each other's `@scope/pkg` imports to source.
@@ -624,9 +647,9 @@ export class DBXToolsTypeScriptProject
624
647
  // directory auto-discovers `*.test.ts` recursively. But `bun test` EXITS 1
625
648
  // when it matches no files (unlike the old `tsx --test 'glob'`, which was a
626
649
  // no-op), so guard it: only invoke when a `*.test.ts` exists, else succeed.
627
- this.testTask.exec(
628
- 'find test -name "*.test.ts" 2>/dev/null | grep -q . && bun test test || true',
629
- );
650
+ this.testTask.exec("bun test test", {
651
+ condition: 'find test -name "*.test.ts" 2>/dev/null | grep -q .',
652
+ });
630
653
  if (options.bunApp ?? false) {
631
654
  new BunfigFile(this);
632
655
  new BunDevServerFile(this);
@@ -661,6 +684,37 @@ class GeneratedSource extends Component {
661
684
  }
662
685
  }
663
686
 
687
+ /**
688
+ * Make the ROOT `compile` / `test` tasks actually validate the workspace.
689
+ *
690
+ * projen gives a monorepo root empty `compile`/`test` tasks - a child's tasks
691
+ * are the child's business - so `bun run build` at the root type-checked nothing
692
+ * and ran no package tests. The fan-out is delegated to bun's own workspace
693
+ * filter rather than one `exec` per member, which matters three ways: bun runs
694
+ * the members in PARALLEL (measured ~2.5x faster across this repo than the
695
+ * sequential per-`cwd` form), a member that does not define the script is
696
+ * skipped instead of needing a guard, and the filter reads the workspace from
697
+ * `package.json` - so it stays correct when a package is added without a
698
+ * re-synth. A non-zero member exit still fails the run.
699
+ *
700
+ * `*` matches every workspace MEMBER and never the root itself, so the root
701
+ * task delegating to it cannot recurse. Members declared outside the scanned
702
+ * package roots (`extraWorkspaceMembers`) are workspace members too, so they are
703
+ * covered by the same filter.
704
+ */
705
+ class WorkspaceValidationTasks extends Component {
706
+ private configured = false;
707
+
708
+ public override preSynthesize(): void {
709
+ if (this.configured) return;
710
+ this.configured = true;
711
+ const project = this.project as javascript.NodeProject;
712
+ for (const task of [project.compileTask, project.testTask]) {
713
+ task.exec(`bun run --filter '*' ${task.name}`);
714
+ }
715
+ }
716
+ }
717
+
664
718
  /**
665
719
  * Ignore each `codegen`-declaring package's `src/` from the root ESLint config.
666
720
  * Those modules are read-only (ts-to-zod); lint `--fix` otherwise EACCES-crashes
@@ -673,10 +727,17 @@ class EslintIgnoreCodegen extends Component {
673
727
  const rootAbs = resolve(this.project.outdir);
674
728
  for (const sub of this.project.subprojects) {
675
729
  if (!(sub instanceof javascript.NodeProject)) continue;
676
- const codegen = sub.package.manifest.codegen as { inputs?: unknown[] } | undefined;
730
+ const codegen = sub.package.manifest.codegen as { inputs?: string[] } | undefined;
677
731
  if (!codegen?.inputs?.length) continue;
678
732
  const rel = toPosix(relative(rootAbs, sub.outdir));
679
- eslint.addIgnorePattern(`${rel}/src/**`);
733
+ // Ignore the generated MODULES, not the package's whole `src/`. A codegen
734
+ // package may hold hand-written modules next to its generated ones
735
+ // (shared-genie generates `dashboards.ts` beside a hand-written
736
+ // `genie-model.ts`), and a blanket `src/**` would silently stop linting
737
+ // them - the failure mode being invisible, since ESLint just reports less.
738
+ for (const module of codegenModulePaths(codegen.inputs)) {
739
+ eslint.addIgnorePattern(`${rel}/${module}`);
740
+ }
680
741
  }
681
742
  }
682
743
  }
@@ -781,7 +842,7 @@ function registerRootTasks(project: javascript.NodeProject): void {
781
842
  barrels: { exec: taskScript(project, "barrels.ts") },
782
843
  openapi: { exec: taskScript(project, "openapi.ts") },
783
844
  clean: { exec: taskScript(project, "clean.ts"), receiveArgs: true },
784
- // `receiveArgs` forwards `--watch`, so `pnpm exec projen sync --watch` syncs once
845
+ // `receiveArgs` forwards `--watch`, so `bun run sync -- --watch` syncs once
785
846
  // then starts the single node-path watcher loop.
786
847
  sync: { exec: taskScript(project, "sync.ts"), receiveArgs: true },
787
848
  });
@@ -901,7 +962,7 @@ function initProject(
901
962
  prettier: Boolean(project.prettier),
902
963
  tsconfigPath: "./tsconfig.json",
903
964
  });
904
- // Generated read-only outputs (barrels, openapi clients, vite configs, codegen).
965
+ // Generated read-only outputs (barrels, openapi clients, app scripts, codegen).
905
966
  // ESLint --fix cannot rewrite them; they are stamped by the barrel generator /
906
967
  // openapi / codegen / projen.
907
968
  for (const root of roots) {
@@ -995,6 +1056,8 @@ function initProject(
995
1056
  project.with(...enabledTagMixins.map((t) => PACKAGE_TAG_MIXINS[t]));
996
1057
  }
997
1058
 
1059
+ new WorkspaceValidationTasks(project);
1060
+
998
1061
  new GeneratedSource(project);
999
1062
  // The `bump` task (compute next version + commit + tag + push) is useful on
1000
1063
  // any root; the actual publish is a tag-triggered GitHub workflow the caller
package/src/publish.ts CHANGED
@@ -148,7 +148,7 @@ export function applyCompiledPublish(pkg: javascript.NodeProject): void {
148
148
  const config = publishConfig(pkg);
149
149
  if (config) pkg.package.addField("publishConfig", config);
150
150
 
151
- // The release workflow publishes straight after `pnpm install`, with no build
151
+ // The release workflow publishes straight after `bun install`, with no build
152
152
  // in between, so the compiled output has to be produced by the pack itself
153
153
  // rather than assumed present. This also covers a bare `pnpm pack` and the
154
154
  // bump task's local-registry publish.
package/src/release.ts CHANGED
@@ -88,7 +88,7 @@ function publishSetupSteps(): JobStep[] {
88
88
  *
89
89
  * Declaring one also enlists it in the root's `bump`, which cuts BOTH tags at one
90
90
  * shared version. The separate tag namespace still lets it be released alone
91
- * (`cd <directory> && pnpm run bump`) for a consumer who wants only this package -
91
+ * (`cd <directory> && bun run bump`) for a consumer who wants only this package -
92
92
  * but a routine root bump no longer leaves it behind, which is how the engine
93
93
  * drifted to 0.1.24 while the packages reached 0.3.41.
94
94
  */
package/src/scaffold.ts CHANGED
@@ -9,7 +9,7 @@ import { repoRoot } from "./packages.ts";
9
9
  * Re-run projen synth by executing `.projenrc.ts` with `node --import tsx` (no
10
10
  * projen network re-exec).
11
11
  *
12
- * `post: true` runs the full flow - projen's post-synth `pnpm install` AND the
12
+ * `post: true` runs the full flow - projen's post-synth `bun install` AND the
13
13
  * post-synth barrels component - which is what the one-shot `sync` task
14
14
  * wants. The default (`post: false`) sets `PROJEN_DISABLE_POST`, skipping both so
15
15
  * the watch loop stays fast; there the caller rebuilds barrels explicitly.
package/src/tags.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tags, expressed as MIXINS (`constructs` `IMixin`).
3
3
  *
4
- * A tag names a target environment (React/Vite, Node, agnostic, ...) - modeled on
4
+ * A tag names a target environment (React/Bun, Node, agnostic, ...) - modeled on
5
5
  * `databricks apps init` (AppKit): `ui`, `server`, `shared`. Any `src`-bearing folder
6
6
  * under a package root is discovered automatically; path-derived tag
7
7
  * candidates plus `packageTagPaths` decide which mixins apply. ("Scope" is
@@ -61,15 +61,18 @@ export const AGNOSTIC_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions = {
61
61
  export const PACKAGE_TAG_MIXINS = {
62
62
  // `ui`: a React COMPONENT LIBRARY (source-first, consumed by apps) - modeled
63
63
  // on `@databricks/appkit-ui`. React + DOM lib + JSX, and the default `tsc`
64
- // compile (typecheck). No vite app build / index.html: a full browser app is an
65
- // `app`-tagged package (see below) that layers vite on top.
64
+ // compile (typecheck). No app build / index.html: a full browser app is an
65
+ // `app`-tagged package (see below) that layers Bun's build tooling on top.
66
66
  ui: create(projectPredicate.hasTag("ui"), (p) => {
67
67
  p.addDeps("react@catalog:", "react-dom@catalog:");
68
68
  p.addDevDeps("@types/react@catalog:", "@types/react-dom@catalog:");
69
+ // `jsx` is not set here: it is in the shared floor for EVERY package, because
70
+ // packages resolve each other to source and so every consumer of a `.tsx`
71
+ // module needs it too (see SHARED_COMPILER_OPTIONS). What this tag adds is the
72
+ // browser part - the DOM lib and React's types.
69
73
  applyCompilerOptions(p, {
70
74
  target: "ES2022",
71
75
  lib: [...DOM_LIB],
72
- jsx: javascript.TypeScriptJsxMode.REACT_JSX,
73
76
  });
74
77
  // A component library's standard subpath surface: `./react` (components),
75
78
  // `./styles.css` (Tailwind entry), and `./package.json`. A package that
@@ -98,7 +101,6 @@ export const PACKAGE_TAG_MIXINS = {
98
101
  applyCompilerOptions(p, {
99
102
  target: "ES2022",
100
103
  lib: [...DOM_LIB],
101
- jsx: javascript.TypeScriptJsxMode.REACT_JSX,
102
104
  // `@types/bun` (a root/subproject devDep) supplies the `Bun.*` globals the
103
105
  // generated `dev.ts`/`build.ts` use; no `vite/client`.
104
106
  types: ["bun"],
@@ -109,10 +111,14 @@ export const PACKAGE_TAG_MIXINS = {
109
111
  });
110
112
  // bun runs the generated scripts directly. `build` resets the compile task so
111
113
  // `compile` bundles with `Bun.build` rather than `tsc`.
114
+ //
115
+ // No `preview` task: that pairing is Vite's, where `dev` runs the dev server
116
+ // and `preview` serves the already-built bundle. `Bun.serve` builds on request,
117
+ // so `preview` could only be spelled the same as `dev` - two names for one
118
+ // command, and a reader would reasonably assume the second one served `dist/`.
112
119
  applyTasks(p, {
113
120
  dev: { exec: "bun dev.ts" },
114
121
  build: { exec: "bun build.ts" },
115
- preview: { exec: "bun dev.ts" },
116
122
  });
117
123
  new BunfigFile(p);
118
124
  new BunDevServerFile(p);
package/src/vscode.ts CHANGED
@@ -45,7 +45,7 @@ export class DBXToolsVsCode extends Component {
45
45
  detail:
46
46
  "projen sync --watch - projenrc (.projenrc.ts + syncResynthPaths re-synth) + barrels + openapi watchers",
47
47
  type: "shell",
48
- command: "pnpm exec projen sync --watch",
48
+ command: "bun run sync -- --watch",
49
49
  isBackground: true,
50
50
  problemMatcher: [],
51
51
  runOptions: { runOn: "folderOpen" },
@@ -59,7 +59,7 @@ export class DBXToolsVsCode extends Component {
59
59
  label: "synth",
60
60
  detail: "projen - synthesize all generated config",
61
61
  type: "shell",
62
- command: "pnpm exec projen",
62
+ command: "bun run default",
63
63
  problemMatcher: [],
64
64
  },
65
65
  ],
package/tasks/barrels.ts CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S npx tsx
1
+ #!/usr/bin/env -S bun
2
2
  import { sep } from "node:path";
3
3
  import { generateBarrels } from "../src/barrels.ts";
4
4
  import { log, string } from "@dbx-tools/shared-core";
@@ -35,7 +35,7 @@ if (process.argv.includes("--watch")) {
35
35
  if (unowned.length) {
36
36
  logger.warn(
37
37
  `no recorded package owns ${string.pluralize(unowned.length, "change")}; ` +
38
- "run `pnpm exec projen` (or touch .projenrc.ts) to pick up a new package folder",
38
+ "run `bun run default` (or touch .projenrc.ts) to pick up a new package folder",
39
39
  );
40
40
  }
41
41
  return;
package/tasks/clean.ts CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S npx tsx
1
+ #!/usr/bin/env -S bun
2
2
  import { relative } from "node:path";
3
3
  import { listGeneratedFiles, listNodeModulesDirs, removePaths } from "../src/clean.ts";
4
4
  import { log, string } from "@dbx-tools/shared-core";
@@ -18,8 +18,8 @@ if (targets.length === 0) {
18
18
 
19
19
  const regenHint = (removedNodeModules: boolean): string =>
20
20
  removedNodeModules
21
- ? "reinstall with `pnpm install`, then `pnpm exec projen`"
22
- : "regenerate with `pnpm exec projen`";
21
+ ? "reinstall with `bun install`, then `bun run default`"
22
+ : "regenerate with `bun run default`";
23
23
 
24
24
  if (yes) {
25
25
  const n = removePaths(targets);
package/tasks/openapi.ts CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S npx tsx
1
+ #!/usr/bin/env -S bun
2
2
  import { generateBarrels } from "../src/barrels.ts";
3
3
  import { log, string } from "@dbx-tools/shared-core";
4
4
  import { generateOpenapi, isTsoaController } from "../src/openapi.ts";
package/tasks/projenrc.ts CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S npx tsx
1
+ #!/usr/bin/env -S bun
2
2
  import { resolve } from "node:path";
3
3
  import { log } from "@dbx-tools/shared-core";
4
4
  import { runSynth } from "../src/scaffold.ts";
@@ -25,7 +25,7 @@ const WATCH_PATHS = resynthWatchPaths();
25
25
  // scoping re-synth (the one expensive, install-bearing step) to those manifests is what
26
26
  // makes the watch intelligent vs stock `projen --watch`, which re-synths on any tree
27
27
  // change. `{ dot: false }` keeps the default dotfile ignore group from pruning dotfile
28
- // targets. (A one-shot "projenrc" is just a synth, i.e. `pnpm exec projen`.)
28
+ // targets. (A one-shot "projenrc" is just a synth, i.e. `bun run default`.)
29
29
  watchLoop(
30
30
  "projenrc",
31
31
  WATCH_PATHS,
package/tasks/sync.ts CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S npx tsx
1
+ #!/usr/bin/env -S bun
2
2
  import { fileURLToPath } from "node:url";
3
3
  import concurrently from "concurrently";
4
4
  import { log } from "@dbx-tools/shared-core";
@@ -54,9 +54,9 @@ if (!process.argv.includes("--watch")) {
54
54
 
55
55
  const { result } = concurrently(
56
56
  [
57
- { command: `tsx "${taskPath("projenrc.ts")}"`, name: "projenrc", prefixColor: "magenta" },
58
- { command: `tsx "${taskPath("barrels.ts")}" --watch`, name: "barrels", prefixColor: "cyan" },
59
- { command: `tsx "${taskPath("openapi.ts")}" --watch`, name: "openapi", prefixColor: "green" },
57
+ { command: `bun "${taskPath("projenrc.ts")}"`, name: "projenrc", prefixColor: "magenta" },
58
+ { command: `bun "${taskPath("barrels.ts")}" --watch`, name: "barrels", prefixColor: "cyan" },
59
+ { command: `bun "${taskPath("openapi.ts")}" --watch`, name: "openapi", prefixColor: "green" },
60
60
  ],
61
61
  {
62
62
  prefix: "name",