@b9g/shovel 0.2.19 → 0.2.21

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to Shovel will be documented in this file.
4
4
 
5
+ ## [0.2.21] - 2026-07-14
6
+
7
+ ### Security
8
+
9
+ - **Unhandled errors leaked stack traces to clients** — The debug error page renders `error.stack` into the response body, gated on `import.meta.env.MODE !== "production"`. `MODE` was never set at build time, so on platforms with no populated `import.meta.env` (Cloudflare Workers) the check saw `undefined`, concluded "not production", and served stack traces to the public on every unhandled 4xx/5xx. Node and Bun leaked the same way unless `NODE_ENV=production` happened to be set.
10
+
11
+ The build now bakes `MODE` into the bundle, and the error-verbosity gates test `MODE === "development"` so an unset mode **fails closed**. The verbose branch is now a build-time constant and gets eliminated from production bundles entirely. Sites deployed to Cloudflare should upgrade. (fixes [#91](https://github.com/bikeshaving/shovel/issues/91), [#100](https://github.com/bikeshaving/shovel/issues/100); [PR #102](https://github.com/bikeshaving/shovel/pull/102))
12
+
13
+ **Note:** `@b9g/router` used standalone (outside shovel's bundler) now returns the minimal production error response by default instead of the HTML debug page. Set `MODE=development` to restore verbose errors.
14
+
15
+ ## [0.2.20] - 2026-07-13
16
+
17
+ ### Bug Fixes
18
+
19
+ - **Client asset minification restored in production** — PR [#68](https://github.com/bikeshaving/shovel/pull/68) (issue [#67](https://github.com/bikeshaving/shovel/issues/67)) made the client asset path honor `build.minify`, but that option defaults to `false` — so it silently stopped minifying CSS/JS in production for any site that never set it (shovel.js.org's client CSS grew from 10,656 to 13,174 bytes). Client assets now minify in production by default again; an explicit `build.minify` still overrides both paths, and the server bundle stays opt-in. ([PR #93](https://github.com/bikeshaving/shovel/pull/93))
20
+
5
21
  ## [0.2.19] - 2026-03-17
6
22
 
7
23
  ### Bug Fixes
package/bin/cli.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  DEFAULTS,
6
6
  findProjectRoot,
7
7
  loadConfig
8
- } from "../src/_chunks/chunk-MUNERPYV.js";
8
+ } from "../src/_chunks/chunk-2JH5U6L5.js";
9
9
 
10
10
  // bin/cli.ts
11
11
  import { resolve, relative } from "path";
@@ -75,7 +75,7 @@ program.command("develop <entrypoint>").description("Start development server wi
75
75
  DEFAULTS.WORKERS
76
76
  ).option("--platform <name>", "Runtime platform (node, cloudflare, bun)").action(async (entrypoint, options) => {
77
77
  checkPlatformReexec(options);
78
- const { developCommand } = await import("../src/_chunks/develop-Y2BWTIZ6.js");
78
+ const { developCommand } = await import("../src/_chunks/develop-2S2Q2Z6R.js");
79
79
  await developCommand(entrypoint, options, config);
80
80
  });
81
81
  program.command("create [name]").description("Create a new Shovel project").action(async (name) => {
@@ -91,7 +91,7 @@ program.command("build <entrypoint>").description("Build app for production").op
91
91
  "Run ServiceWorker lifecycle after build (install or activate, default: activate)"
92
92
  ).action(async (entrypoint, options) => {
93
93
  checkPlatformReexec(options);
94
- const { buildCommand } = await import("../src/_chunks/build-YQCWR6LD.js");
94
+ const { buildCommand } = await import("../src/_chunks/build-GE2SPTLH.js");
95
95
  await buildCommand(entrypoint, options, config);
96
96
  process.exit(0);
97
97
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/shovel",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
4
4
  "description": "ServiceWorker-first universal deployment platform. Write ServiceWorker apps once, deploy anywhere (Node/Bun/Cloudflare). Registry-based multi-app orchestration.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  "@b9g/router": "^0.2.5",
40
40
  "@eslint/js": "^9.0.0",
41
41
  "@logtape/file": "^2.0.0",
42
- "@types/bun": "^1.3.4",
42
+ "@types/bun": "^1.3.11",
43
43
  "@typescript-eslint/eslint-plugin": "^8.0.0",
44
44
  "@typescript-eslint/parser": "^8.0.0",
45
45
  "eslint": "^9.0.0",
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ServerBundler,
3
3
  loadPlatformModule
4
- } from "./chunk-JY5SZDJK.js";
4
+ } from "./chunk-TVQDBRFO.js";
5
5
  import {
6
6
  findProjectRoot,
7
7
  findWorkspaceRoot
8
- } from "./chunk-MUNERPYV.js";
8
+ } from "./chunk-2JH5U6L5.js";
9
9
 
10
10
  // src/commands/build.ts
11
11
  import { resolve, join, dirname, basename } from "path";
@@ -1060,7 +1060,9 @@ ${issues}`);
1060
1060
  },
1061
1061
  build: {
1062
1062
  target: validated.build?.target ?? "es2022",
1063
- minify: validated.build?.minify ?? false,
1063
+ // Keep undefined when unset — collapsing to false here silently
1064
+ // disables production client-asset minify (regression #68/#67).
1065
+ minify: validated.build?.minify,
1064
1066
  sourcemap: validated.build?.sourcemap ?? false,
1065
1067
  treeShaking: validated.build?.treeShaking ?? true,
1066
1068
  define: validated.build?.define ?? {},
@@ -4,7 +4,7 @@ import {
4
4
  generateStorageTypes,
5
5
  getNodeModulesPath,
6
6
  loadRawConfig
7
- } from "./chunk-MUNERPYV.js";
7
+ } from "./chunk-2JH5U6L5.js";
8
8
 
9
9
  // src/utils/bundler.ts
10
10
  import * as ESBuild2 from "esbuild";
@@ -943,6 +943,7 @@ var ServerBundler = class {
943
943
  const target = userBuildConfig?.target ?? "es2022";
944
944
  const sourcemap = userBuildConfig?.sourcemap ?? (watch2 ? "inline" : false);
945
945
  const minify = userBuildConfig?.minify ?? false;
946
+ const assetMinify = userBuildConfig?.minify ?? (!this.#options.development && !watch2);
946
947
  const treeShaking = userBuildConfig?.treeShaking ?? true;
947
948
  const esbuildEntryPoints = {
948
949
  config: "shovel:config"
@@ -964,7 +965,7 @@ var ServerBundler = class {
964
965
  assetsPlugin({
965
966
  outDir: outputDir,
966
967
  plugins: userPlugins,
967
- minify,
968
+ minify: assetMinify,
968
969
  jsx: jsxOptions.jsx,
969
970
  jsxFactory: jsxOptions.jsxFactory,
970
971
  jsxFragment: jsxOptions.jsxFragment,
@@ -998,6 +999,10 @@ var ServerBundler = class {
998
999
  define: {
999
1000
  ...platformESBuildConfig.define ?? {},
1000
1001
  ...userBuildConfig?.define ?? {},
1002
+ // Error verbosity keys off MODE. Platforms without a populated
1003
+ // import.meta.env (Cloudflare) would otherwise leave it undefined,
1004
+ // so bake it in — the check then folds away at build time.
1005
+ "import.meta.env.MODE": JSON.stringify(mode),
1001
1006
  __SHOVEL_OUTDIR__: JSON.stringify(outputDir),
1002
1007
  __SHOVEL_GIT__: JSON.stringify(getGitSHA(this.#projectRoot))
1003
1008
  },
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  ServerBundler,
3
3
  loadPlatformModule
4
- } from "./chunk-JY5SZDJK.js";
4
+ } from "./chunk-TVQDBRFO.js";
5
5
  import {
6
6
  DEFAULTS
7
- } from "./chunk-MUNERPYV.js";
7
+ } from "./chunk-2JH5U6L5.js";
8
8
 
9
9
  // src/commands/develop.ts
10
10
  import { getLogger } from "@logtape/logtape";