@dbx-tools/projen 0.6.44 → 0.6.46

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/package.json CHANGED
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "main": "index.ts",
52
52
  "license": "Apache-2.0",
53
- "version": "0.6.44",
53
+ "version": "0.6.46",
54
54
  "packageManager": "pnpm@10.33.0",
55
55
  "types": "index.ts",
56
56
  "type": "module",
package/src/bun-app.ts CHANGED
@@ -131,6 +131,7 @@ export class BunBuildFile extends TextFile {
131
131
  readonly: true,
132
132
  lines: String.raw`
133
133
  import { existsSync } from "node:fs";
134
+ import { basename } from "node:path";
134
135
  import tailwind from "bun-plugin-tailwind";
135
136
 
136
137
  // Unmanaged override (${BUN_BUILD_OVERRIDE}): its default export is merged over
@@ -155,6 +156,26 @@ if (!result.success) {
155
156
  for (const message of result.logs) console.error(message);
156
157
  process.exit(1);
157
158
  }
159
+
160
+ // Fix a Bun bug: with \`splitting: true\` and an HTML entrypoint, the emitted
161
+ // HTML's <script src> is wired to an arbitrary chunk instead of the JS
162
+ // entry-point, so the app never boots (a blank page). Rewrite the HTML script
163
+ // (and stylesheet) to the real entry-point outputs. No-op when they already
164
+ // match (e.g. splitting off), so it is always safe to run.
165
+ const htmlOut = result.outputs.find((o) => o.path.endsWith(".html"));
166
+ const entryJs = result.outputs.find((o) => o.kind === "entry-point" && o.path.endsWith(".js"));
167
+ const entryCss = result.outputs.find((o) => o.kind === "entry-point" && o.path.endsWith(".css"));
168
+ if (htmlOut && entryJs) {
169
+ let html = await Bun.file(htmlOut.path).text();
170
+ const jsName = basename(entryJs.path);
171
+ html = html.replace(/(<script[^>]*\bsrc=")([^"]*\/)?[^"/]+\.js(")/i, "$1$2" + jsName + "$3");
172
+ if (entryCss) {
173
+ const cssName = basename(entryCss.path);
174
+ html = html.replace(/(<link[^>]*\bhref=")([^"]*\/)?[^"/]+\.css(")/i, "$1$2" + cssName + "$3");
175
+ }
176
+ await Bun.write(htmlOut.path, html);
177
+ }
178
+
158
179
  console.log("built " + result.outputs.length + " files to " + options.outdir);
159
180
  `
160
181
  .trimStart()
package/src/project.ts CHANGED
@@ -913,6 +913,9 @@ function initProject(
913
913
  // them to a project. ESLint still cannot parse them.
914
914
  eslint.addIgnorePattern("**/dev.ts");
915
915
  eslint.addIgnorePattern("**/build.ts");
916
+ // A deploy-staging helper that lives at a package root (outside any `src/**`
917
+ // tsconfig), same parse-resolution problem as the bun app scripts above.
918
+ eslint.addIgnorePattern("**/stage-deploy.ts");
916
919
  for (const override of BUN_APP_OVERRIDES) {
917
920
  eslint.addIgnorePattern(`**/${override}`);
918
921
  }
package/tasks/publish.ts CHANGED
@@ -18,8 +18,17 @@
18
18
  * while the on-disk manifest keeps the protocols.) Setting each member's
19
19
  * version first is the only prerequisite, so a sibling resolves the release
20
20
  * version rather than the disk default of `0.0.0`;
21
- * - **`publishConfig` substitution** (compiled `lib/` entry points) and the
22
- * `prepack` (compile) run are `bun publish`'s own pack behavior.
21
+ * - **`publishConfig` substitution** (compiled `lib/` entry points) is done
22
+ * HERE, by {@link applyPublishConfig}, NOT by bun: unlike pnpm/npm, `bun
23
+ * publish`/`bun pm pack` do NOT fold `publishConfig`'s `main`/`types`/`bin`/
24
+ * `exports` into the packed manifest (verified: the packed manifest keeps the
25
+ * raw `.ts` source paths and an inert `publishConfig`). Left unsubstituted, a
26
+ * published CLI's `bin` points at `./bin/x.ts`, and because the bin runs via
27
+ * its `#!/usr/bin/env node` shebang, node chokes on the `.ts`
28
+ * (ERR_UNKNOWN_FILE_EXTENSION). We merge `publishConfig` onto the top-level
29
+ * manifest before packing so the tarball advertises the compiled `lib/` tree;
30
+ * - the **`prepack` (compile) run** that emits that `lib/` tree is `bun
31
+ * publish`'s own pack behavior.
23
32
  *
24
33
  * `--dry-run` forwards to `bun publish`: it packs + validates (running prepack)
25
34
  * but uploads nothing, so the `release` workflow is testable end-to-end via a
@@ -32,7 +41,7 @@
32
41
  * this unlocks each only long enough to set the version + publish. The next
33
42
  * `projen` synth restores them - the release version lives in the git tag.
34
43
  */
35
- import { chmodSync, existsSync, readFileSync, rmSync, statSync } from "node:fs";
44
+ import { chmodSync, existsSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
36
45
  import { dirname, join, resolve } from "node:path";
37
46
  import { exec } from "@dbx-tools/core";
38
47
  import { log } from "@dbx-tools/shared-core";
@@ -70,6 +79,31 @@ function unlockManifest(pkgPath: string): void {
70
79
  chmodSync(pkgPath, statSync(pkgPath).mode | 0o200);
71
80
  }
72
81
 
82
+ /** Entry-point fields projen writes as `.ts` source in-repo and rewrites to `lib/` for publish. */
83
+ const PUBLISH_CONFIG_ENTRY_FIELDS = ["main", "types", "bin", "exports"] as const;
84
+
85
+ /**
86
+ * Fold a package's `publishConfig` entry-point fields onto the top-level manifest,
87
+ * the way pnpm/npm do at pack time but `bun publish` does NOT (see the module
88
+ * doc). Idempotent, writes only when something changes, and leaves `publishConfig`
89
+ * in place (npm ignores it once the top-level fields already point at `lib/`). The
90
+ * manifest must already be unlocked. The next `projen` synth restores the `.ts`
91
+ * entry points, so this only affects the packed tarball - like the version stamp.
92
+ */
93
+ function applyPublishConfig(pkgPath: string): void {
94
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8")) as Record<string, unknown>;
95
+ const publishConfig = pkg.publishConfig as Record<string, unknown> | undefined;
96
+ if (!publishConfig) return;
97
+ let changed = false;
98
+ for (const field of PUBLISH_CONFIG_ENTRY_FIELDS) {
99
+ if (field in publishConfig) {
100
+ pkg[field] = publishConfig[field];
101
+ changed = true;
102
+ }
103
+ }
104
+ if (changed) writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
105
+ }
106
+
73
107
  /**
74
108
  * PATH with the workspace-root `node_modules/.bin` prepended. `bun publish` runs
75
109
  * each package's `prepack` (compile) through projen's dax shell, which resolves
@@ -149,6 +183,11 @@ for (const dir of members) {
149
183
  logger.info(`skip private ${pkg.name ?? dirname(dir)}`);
150
184
  continue;
151
185
  }
186
+ // bun won't fold publishConfig into the packed manifest, so do it ourselves -
187
+ // otherwise the tarball's `bin`/`main`/`exports` stay pointed at `.ts` source.
188
+ const manifestPath = join(dir, "package.json");
189
+ unlockManifest(manifestPath);
190
+ applyPublishConfig(manifestPath);
152
191
  logger.info(`${dryRun ? "dry-run publishing" : "publishing"} ${pkg.name} @ ${version}`);
153
192
  run(dir, "bun", ["publish", ...publishArgs], path);
154
193
  published += 1;