@b9g/shovel 0.2.14 → 0.2.16
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 +39 -0
- package/bin/cli.js +2 -2
- package/bin/create.js +25 -13
- package/package.json +2 -2
- package/src/_chunks/{build-YOORTV6F.js → build-EGT4OE4O.js} +1 -1
- package/src/_chunks/{chunk-DRCLXHTF.js → chunk-TPEOHBYY.js} +4 -2
- package/src/_chunks/{develop-I74XUWOE.js → develop-BR7WCNBK.js} +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Shovel will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.16] - 2026-02-26
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **`@b9g/shovel`** - `build.minify` config in `shovel.json` now propagates to client asset builds. Previously client JS/CSS was always minified regardless of the setting (closes #67)
|
|
10
|
+
|
|
11
|
+
## @b9g/router 0.2.5 - 2026-02-25
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- **`@b9g/router`** - Trailing slash middleware now also redirects when a catch-all route or error-handling middleware returns a 404 Response (not just thrown `NotFound` errors). In 0.2.4 the middleware only caught thrown errors, so catch-all routes returning 404 responses would not trigger the redirect
|
|
16
|
+
|
|
17
|
+
## @b9g/router 0.2.4 - 2026-02-25
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **`@b9g/router`** - Trailing slash middleware now only redirects as a last resort. Previously it eagerly redirected before route matching, so routes explicitly defined with (or without) a trailing slash would always be redirected. Now the middleware yields to route matching first and only redirects on 404
|
|
22
|
+
- **`@b9g/router`** - Added `"append"` as an alias for `"add"` in `trailingSlash()` mode
|
|
23
|
+
|
|
24
|
+
## [0.2.15] - 2026-02-25
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
- **`create-shovel`** - Fixed linting in generated JS projects (missing browser globals)
|
|
29
|
+
- **`create-shovel`** - Fixed linting in generated Crank projects (now uses `eslint-plugin-crank`)
|
|
30
|
+
- **`create-shovel`** - Fixed Crank `Counter` to use `this.refresh()` callback pattern
|
|
31
|
+
|
|
32
|
+
## [0.2.14] - 2026-02-24
|
|
33
|
+
|
|
34
|
+
### Features
|
|
35
|
+
|
|
36
|
+
- **`create-shovel`** - All static-site and full-stack templates now use bundled client entry points through Shovel's asset pipeline instead of CDN links or inline scripts
|
|
37
|
+
- **`create-shovel`** - Added type declarations (`env.d.ts`) for htmx and Alpine in TypeScript projects
|
|
38
|
+
- **`create-shovel`** - Generated projects include ESLint configuration
|
|
39
|
+
|
|
40
|
+
### Bug Fixes
|
|
41
|
+
|
|
42
|
+
- **`@b9g/platform`** - Added `Window.addEventListener` overload for ServiceWorker event types in `globals.d.ts`
|
|
43
|
+
|
|
5
44
|
## [0.2.13] - 2026-02-24
|
|
6
45
|
|
|
7
46
|
### Bug Fixes
|
package/bin/cli.js
CHANGED
|
@@ -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-
|
|
78
|
+
const { developCommand } = await import("../src/_chunks/develop-BR7WCNBK.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-
|
|
94
|
+
const { buildCommand } = await import("../src/_chunks/build-EGT4OE4O.js");
|
|
95
95
|
await buildCommand(entrypoint, options, config);
|
|
96
96
|
process.exit(0);
|
|
97
97
|
});
|
package/bin/create.js
CHANGED
|
@@ -294,6 +294,11 @@ async function createProject(config, projectPath) {
|
|
|
294
294
|
devDependencies["@eslint/js"] = "^10.0.0";
|
|
295
295
|
if (config.typescript) {
|
|
296
296
|
devDependencies["typescript-eslint"] = "^8.0.0";
|
|
297
|
+
} else {
|
|
298
|
+
devDependencies["globals"] = "^16.0.0";
|
|
299
|
+
}
|
|
300
|
+
if (isCrank) {
|
|
301
|
+
devDependencies["eslint-plugin-crank"] = "^0.2.0";
|
|
297
302
|
}
|
|
298
303
|
}
|
|
299
304
|
const scripts = {
|
|
@@ -358,23 +363,34 @@ async function createProject(config, projectPath) {
|
|
|
358
363
|
);
|
|
359
364
|
}
|
|
360
365
|
if (hasClientBundle) {
|
|
366
|
+
const crankImport = isCrank ? `import crank from "eslint-plugin-crank";
|
|
367
|
+
` : "";
|
|
368
|
+
const crankConfig = isCrank ? `
|
|
369
|
+
{ plugins: { crank }, rules: crank.configs.recommended.rules },` : "";
|
|
361
370
|
let eslintConfig;
|
|
362
371
|
if (config.typescript) {
|
|
363
372
|
eslintConfig = `import js from "@eslint/js";
|
|
364
373
|
import tseslint from "typescript-eslint";
|
|
365
|
-
|
|
374
|
+
${crankImport}
|
|
366
375
|
export default tseslint.config(
|
|
367
376
|
js.configs.recommended,
|
|
368
377
|
tseslint.configs.recommended,
|
|
369
|
-
{ ignores: ["dist/"] }
|
|
378
|
+
{ ignores: ["dist/"] },${crankConfig}
|
|
370
379
|
);
|
|
371
380
|
`;
|
|
372
381
|
} else {
|
|
382
|
+
let langOpts = "globals: globals.browser";
|
|
383
|
+
let filesOpt = "";
|
|
384
|
+
if (isCrank && config.useJSX) {
|
|
385
|
+
filesOpt = `files: ["**/*.{js,jsx}"], `;
|
|
386
|
+
langOpts += ", parserOptions: { ecmaFeatures: { jsx: true } }";
|
|
387
|
+
}
|
|
373
388
|
eslintConfig = `import js from "@eslint/js";
|
|
374
|
-
|
|
389
|
+
import globals from "globals";
|
|
390
|
+
${crankImport}
|
|
375
391
|
export default [
|
|
376
|
-
js.configs.recommended,
|
|
377
|
-
{ ignores: ["dist/"] }
|
|
392
|
+
{ ${filesOpt}...js.configs.recommended, languageOptions: { ${langOpts} } },
|
|
393
|
+
{ ignores: ["dist/"] },${crankConfig}
|
|
378
394
|
];
|
|
379
395
|
`;
|
|
380
396
|
}
|
|
@@ -783,8 +799,7 @@ export function Page({title, children, clientUrl}${t ? ": {title: string, childr
|
|
|
783
799
|
export function *Counter(${t ? "this: Context" : ""}) {
|
|
784
800
|
let count = 0;
|
|
785
801
|
const handleClick = () => {
|
|
786
|
-
count
|
|
787
|
-
this.refresh();
|
|
802
|
+
this.refresh(() => count++);
|
|
788
803
|
};
|
|
789
804
|
for ({} of this) {
|
|
790
805
|
yield <button onclick={handleClick}>Clicked: {count}</button>;
|
|
@@ -866,8 +881,7 @@ export function Page({title, children, clientUrl}${t ? ": {title: string, childr
|
|
|
866
881
|
export function *Counter(${t ? "this: Context" : ""}) {
|
|
867
882
|
let count = 0;
|
|
868
883
|
const handleClick = () => {
|
|
869
|
-
count
|
|
870
|
-
this.refresh();
|
|
884
|
+
this.refresh(() => count++);
|
|
871
885
|
};
|
|
872
886
|
for ({} of this) {
|
|
873
887
|
yield jsx\`<button onclick=\${handleClick}>Clicked: \${count}</button>\`;
|
|
@@ -1261,8 +1275,7 @@ export function Page({title, children, clientUrl}${t ? ": {title: string, childr
|
|
|
1261
1275
|
export function *Counter(${t ? "this: Context" : ""}) {
|
|
1262
1276
|
let count = 0;
|
|
1263
1277
|
const handleClick = () => {
|
|
1264
|
-
count
|
|
1265
|
-
this.refresh();
|
|
1278
|
+
this.refresh(() => count++);
|
|
1266
1279
|
};
|
|
1267
1280
|
for ({} of this) {
|
|
1268
1281
|
yield <button onclick={handleClick}>Clicked: {count}</button>;
|
|
@@ -1363,8 +1376,7 @@ export function Page({title, children, clientUrl}${t ? ": {title: string, childr
|
|
|
1363
1376
|
export function *Counter(${t ? "this: Context" : ""}) {
|
|
1364
1377
|
let count = 0;
|
|
1365
1378
|
const handleClick = () => {
|
|
1366
|
-
count
|
|
1367
|
-
this.refresh();
|
|
1379
|
+
this.refresh(() => count++);
|
|
1368
1380
|
};
|
|
1369
1381
|
for ({} of this) {
|
|
1370
1382
|
yield jsx\`<button onclick=\${handleClick}>Clicked: \${count}</button>\`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b9g/shovel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
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": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@b9g/assets": "^0.2.1",
|
|
36
36
|
"@b9g/crank": "^0.7.7",
|
|
37
37
|
"@b9g/libuild": "^0.1.24",
|
|
38
|
-
"@b9g/router": "^0.2.
|
|
38
|
+
"@b9g/router": "^0.2.5",
|
|
39
39
|
"@eslint/js": "^9.0.0",
|
|
40
40
|
"@logtape/file": "^2.0.0",
|
|
41
41
|
"@types/bun": "^1.3.4",
|
|
@@ -44,6 +44,7 @@ function normalizePath(basePath) {
|
|
|
44
44
|
}
|
|
45
45
|
function assetsPlugin(options = {}) {
|
|
46
46
|
const outDir = options.outDir ?? "dist";
|
|
47
|
+
const minify = options.minify ?? true;
|
|
47
48
|
const sharedManifest = options.sharedManifest;
|
|
48
49
|
const manifest = {
|
|
49
50
|
assets: {},
|
|
@@ -114,7 +115,7 @@ function assetsPlugin(options = {}) {
|
|
|
114
115
|
target: ["es2022", "chrome90"],
|
|
115
116
|
platform: "browser",
|
|
116
117
|
write: false,
|
|
117
|
-
minify
|
|
118
|
+
minify,
|
|
118
119
|
// outdir is required for esbuild to know where to put extracted CSS and chunks
|
|
119
120
|
outdir: outDir,
|
|
120
121
|
// Apply polyfills and user-provided build options
|
|
@@ -216,7 +217,7 @@ function assetsPlugin(options = {}) {
|
|
|
216
217
|
entryPoints: [entryPath],
|
|
217
218
|
bundle: true,
|
|
218
219
|
write: false,
|
|
219
|
-
minify
|
|
220
|
+
minify,
|
|
220
221
|
// outdir required for esbuild to generate output paths
|
|
221
222
|
outdir: outDir,
|
|
222
223
|
plugins,
|
|
@@ -871,6 +872,7 @@ var ServerBundler = class {
|
|
|
871
872
|
assetsPlugin({
|
|
872
873
|
outDir: outputDir,
|
|
873
874
|
plugins: userPlugins,
|
|
875
|
+
minify,
|
|
874
876
|
jsx: jsxOptions.jsx,
|
|
875
877
|
jsxFactory: jsxOptions.jsxFactory,
|
|
876
878
|
jsxFragment: jsxOptions.jsxFragment,
|