@webstir-io/webstir-frontend 0.1.40 → 0.1.41
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 +124 -60
- package/dist/assets/imageOptimizer.js +10 -15
- package/dist/assets/precompression.js +1 -1
- package/dist/builders/contentBuilder.js +102 -90
- package/dist/builders/cssBuilder.js +25 -19
- package/dist/builders/htmlBuilder.js +57 -42
- package/dist/builders/index.js +1 -1
- package/dist/builders/jsBuilder.js +219 -76
- package/dist/builders/staticAssetsBuilder.js +27 -9
- package/dist/builders/types.d.ts +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +6 -30
- package/dist/config/manifest.js +7 -6
- package/dist/config/paths.js +2 -2
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.js +7 -6
- package/dist/config/setup.js +1 -1
- package/dist/config/workspace.js +11 -9
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/constants.js +5 -5
- package/dist/core/diagnostics.js +1 -1
- package/dist/core/pages.js +4 -4
- package/dist/hooks.js +3 -3
- package/dist/html/criticalCss.js +6 -3
- package/dist/html/htmlSecurity.d.ts +6 -1
- package/dist/html/htmlSecurity.js +28 -14
- package/dist/html/lazyLoad.js +1 -1
- package/dist/html/pageScaffold.js +1 -1
- package/dist/html/resourceHints.js +5 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/inspect.d.ts +2 -0
- package/dist/inspect.js +110 -0
- package/dist/modes/ssg/metadata.js +4 -4
- package/dist/modes/ssg/routing.js +2 -5
- package/dist/modes/ssg/seo.js +5 -5
- package/dist/modes/ssg/views.js +17 -11
- package/dist/operations.js +18 -10
- package/dist/pipeline.d.ts +1 -0
- package/dist/pipeline.js +6 -1
- package/dist/provider.js +28 -24
- package/dist/runtime/boundary.d.ts +28 -0
- package/dist/runtime/boundary.js +247 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/utils/fs.d.ts +11 -10
- package/dist/utils/fs.js +48 -20
- package/dist/utils/glob.d.ts +8 -0
- package/dist/utils/glob.js +21 -0
- package/dist/utils/hash.js +1 -2
- package/dist/utils/pagePaths.js +2 -2
- package/package.json +19 -14
- package/scripts/publish.sh +2 -94
- package/scripts/update-contract.sh +12 -10
- package/src/assets/assetManifest.ts +39 -29
- package/src/assets/imageOptimizer.ts +91 -82
- package/src/assets/precompression.ts +22 -16
- package/src/builders/contentBuilder.ts +1224 -1149
- package/src/builders/cssBuilder.ts +466 -417
- package/src/builders/htmlBuilder.ts +511 -448
- package/src/builders/index.ts +7 -7
- package/src/builders/jsBuilder.ts +538 -280
- package/src/builders/staticAssetsBuilder.ts +166 -135
- package/src/builders/types.ts +7 -6
- package/src/cli.ts +66 -90
- package/src/config/manifest.ts +16 -14
- package/src/config/paths.ts +5 -5
- package/src/config/schema.ts +38 -37
- package/src/config/setup.ts +7 -7
- package/src/config/workspace.ts +118 -116
- package/src/config/workspaceManifest.ts +14 -14
- package/src/core/constants.ts +62 -62
- package/src/core/diagnostics.ts +26 -26
- package/src/core/pages.ts +19 -19
- package/src/hooks.ts +128 -118
- package/src/html/criticalCss.ts +84 -77
- package/src/html/htmlSecurity.ts +107 -66
- package/src/html/lazyLoad.ts +22 -19
- package/src/html/pageScaffold.ts +37 -28
- package/src/html/resourceHints.ts +83 -74
- package/src/index.ts +2 -0
- package/src/inspect.ts +158 -0
- package/src/modes/ssg/metadata.ts +53 -51
- package/src/modes/ssg/routing.ts +177 -177
- package/src/modes/ssg/seo.ts +208 -200
- package/src/modes/ssg/validation.ts +31 -25
- package/src/modes/ssg/views.ts +257 -238
- package/src/operations.ts +105 -95
- package/src/pipeline.ts +81 -69
- package/src/provider.ts +184 -176
- package/src/runtime/boundary.ts +325 -0
- package/src/runtime/index.ts +1 -0
- package/src/types.ts +107 -48
- package/src/utils/changedFile.ts +22 -22
- package/src/utils/fs.ts +73 -26
- package/src/utils/glob.ts +38 -0
- package/src/utils/hash.ts +2 -4
- package/src/utils/pagePaths.ts +35 -23
- package/src/utils/pathMatch.ts +26 -23
- package/tests/add-page-defaults.test.js +44 -39
- package/tests/bundlerParity.test.js +252 -0
- package/tests/cli.contract.test.js +13 -0
- package/tests/content-pages.test.js +108 -13
- package/tests/css-app-imports.test.js +22 -11
- package/tests/css-page-imports.test.js +26 -13
- package/tests/diagnostics.test.js +39 -36
- package/tests/features.test.js +48 -43
- package/tests/hooks.test.js +58 -42
- package/tests/htmlSecurity.test.js +66 -0
- package/tests/inspect.test.js +148 -0
- package/tests/provider.integration.test.js +71 -20
- package/tests/runtime.test.js +493 -0
- package/tests/ssg-defaults.test.js +284 -177
- package/tests/ssg-guardrails.test.js +51 -51
- package/tsconfig.json +3 -10
- package/dist/watch/frontendFiles.d.ts +0 -3
- package/dist/watch/frontendFiles.js +0 -25
- package/dist/watch/hotUpdateTracker.d.ts +0 -51
- package/dist/watch/hotUpdateTracker.js +0 -205
- package/dist/watch/pipelineHelpers.d.ts +0 -26
- package/dist/watch/pipelineHelpers.js +0 -177
- package/dist/watch/types.d.ts +0 -27
- package/dist/watch/types.js +0 -1
- package/dist/watch/watchCoordinator.d.ts +0 -36
- package/dist/watch/watchCoordinator.js +0 -551
- package/dist/watch/watchDaemon.d.ts +0 -17
- package/dist/watch/watchDaemon.js +0 -127
- package/dist/watch/watchReporter.d.ts +0 -21
- package/dist/watch/watchReporter.js +0 -64
- package/scripts/smoke.mjs +0 -35
- package/src/watch/frontendFiles.ts +0 -32
- package/src/watch/hotUpdateTracker.ts +0 -285
- package/src/watch/pipelineHelpers.ts +0 -242
- package/src/watch/types.ts +0 -23
- package/src/watch/watchCoordinator.ts +0 -666
- package/src/watch/watchDaemon.ts +0 -144
- package/src/watch/watchReporter.ts +0 -98
package/dist/utils/fs.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare function ensureDir(
|
|
3
|
-
export declare function emptyDir(
|
|
4
|
-
export declare function remove(
|
|
1
|
+
import type { Stats } from 'node:fs';
|
|
2
|
+
export declare function ensureDir(targetPath: string): Promise<void>;
|
|
3
|
+
export declare function emptyDir(targetPath: string): Promise<void>;
|
|
4
|
+
export declare function remove(targetPath: string): Promise<void>;
|
|
5
5
|
export declare function copy(source: string, destination: string): Promise<void>;
|
|
6
|
-
export declare function pathExists(
|
|
7
|
-
export declare function stat(
|
|
8
|
-
export declare function readJson<T>(
|
|
9
|
-
export declare function writeJson(
|
|
10
|
-
export declare function readFile(
|
|
11
|
-
export declare function
|
|
6
|
+
export declare function pathExists(targetPath: string): Promise<boolean>;
|
|
7
|
+
export declare function stat(targetPath: string): Promise<Stats>;
|
|
8
|
+
export declare function readJson<T>(targetPath: string): Promise<T | null>;
|
|
9
|
+
export declare function writeJson(targetPath: string, data: unknown): Promise<void>;
|
|
10
|
+
export declare function readFile(targetPath: string): Promise<string>;
|
|
11
|
+
export declare function readBinaryFile(targetPath: string): Promise<Uint8Array>;
|
|
12
|
+
export declare function writeFile(targetPath: string, contents: string): Promise<void>;
|
package/dist/utils/fs.js
CHANGED
|
@@ -1,25 +1,49 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { lstat, mkdir, readdir, rm, stat as statFs } from 'node:fs/promises';
|
|
3
|
+
function getBunRuntime() {
|
|
4
|
+
const runtime = globalThis;
|
|
5
|
+
if (typeof runtime.Bun?.file === 'function' && typeof runtime.Bun?.write === 'function') {
|
|
6
|
+
return runtime.Bun;
|
|
7
|
+
}
|
|
8
|
+
throw new Error('[webstir-frontend] Bun runtime is required for package-level IO.');
|
|
9
|
+
}
|
|
10
|
+
export async function ensureDir(targetPath) {
|
|
11
|
+
await mkdir(targetPath, { recursive: true });
|
|
4
12
|
}
|
|
5
|
-
export async function emptyDir(
|
|
6
|
-
await
|
|
13
|
+
export async function emptyDir(targetPath) {
|
|
14
|
+
await rm(targetPath, { recursive: true, force: true });
|
|
15
|
+
await mkdir(targetPath, { recursive: true });
|
|
7
16
|
}
|
|
8
|
-
export async function remove(
|
|
9
|
-
await
|
|
17
|
+
export async function remove(targetPath) {
|
|
18
|
+
await rm(targetPath, { recursive: true, force: true });
|
|
10
19
|
}
|
|
11
20
|
export async function copy(source, destination) {
|
|
12
|
-
await
|
|
21
|
+
const sourceInfo = await lstat(source);
|
|
22
|
+
if (sourceInfo.isDirectory()) {
|
|
23
|
+
await ensureDir(destination);
|
|
24
|
+
const entries = await readdir(source, { withFileTypes: true });
|
|
25
|
+
await Promise.all(entries.map((entry) => copy(path.join(source, entry.name), path.join(destination, entry.name))));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
await ensureDir(path.dirname(destination));
|
|
29
|
+
const bun = getBunRuntime();
|
|
30
|
+
await bun.write(destination, bun.file(source));
|
|
13
31
|
}
|
|
14
|
-
export async function pathExists(
|
|
15
|
-
|
|
32
|
+
export async function pathExists(targetPath) {
|
|
33
|
+
try {
|
|
34
|
+
await statFs(targetPath);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
16
40
|
}
|
|
17
|
-
export async function stat(
|
|
18
|
-
return
|
|
41
|
+
export async function stat(targetPath) {
|
|
42
|
+
return await statFs(targetPath);
|
|
19
43
|
}
|
|
20
|
-
export async function readJson(
|
|
44
|
+
export async function readJson(targetPath) {
|
|
21
45
|
try {
|
|
22
|
-
return await
|
|
46
|
+
return JSON.parse(await readFile(targetPath));
|
|
23
47
|
}
|
|
24
48
|
catch (error) {
|
|
25
49
|
if (error.code === 'ENOENT') {
|
|
@@ -28,12 +52,16 @@ export async function readJson(path) {
|
|
|
28
52
|
throw error;
|
|
29
53
|
}
|
|
30
54
|
}
|
|
31
|
-
export async function writeJson(
|
|
32
|
-
await
|
|
55
|
+
export async function writeJson(targetPath, data) {
|
|
56
|
+
await writeFile(targetPath, JSON.stringify(data, undefined, 2));
|
|
57
|
+
}
|
|
58
|
+
export async function readFile(targetPath) {
|
|
59
|
+
return await getBunRuntime().file(targetPath).text();
|
|
33
60
|
}
|
|
34
|
-
export async function
|
|
35
|
-
return
|
|
61
|
+
export async function readBinaryFile(targetPath) {
|
|
62
|
+
return new Uint8Array(await getBunRuntime().file(targetPath).arrayBuffer());
|
|
36
63
|
}
|
|
37
|
-
export async function writeFile(
|
|
38
|
-
await
|
|
64
|
+
export async function writeFile(targetPath, contents) {
|
|
65
|
+
await ensureDir(path.dirname(targetPath));
|
|
66
|
+
await getBunRuntime().write(targetPath, contents);
|
|
39
67
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface GlobScanOptions {
|
|
2
|
+
readonly cwd: string;
|
|
3
|
+
readonly absolute?: boolean;
|
|
4
|
+
readonly dot?: boolean;
|
|
5
|
+
readonly onlyFiles?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function scanGlob(pattern: string, options: GlobScanOptions): Promise<string[]>;
|
|
8
|
+
export declare function scanDirectories(pattern: string, options: Omit<GlobScanOptions, 'onlyFiles'>): Promise<string[]>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { stat } from './fs.js';
|
|
3
|
+
export async function scanGlob(pattern, options) {
|
|
4
|
+
const glob = new Bun.Glob(pattern);
|
|
5
|
+
const matches = await Array.fromAsync(glob.scan(options));
|
|
6
|
+
matches.sort((a, b) => a.localeCompare(b));
|
|
7
|
+
return matches;
|
|
8
|
+
}
|
|
9
|
+
export async function scanDirectories(pattern, options) {
|
|
10
|
+
const matches = await scanGlob(pattern, { ...options, onlyFiles: false });
|
|
11
|
+
const directories = await Promise.all(matches.map(async (match) => {
|
|
12
|
+
const absolutePath = options.absolute || path.isAbsolute(match) ? match : path.join(options.cwd, match);
|
|
13
|
+
const info = await stat(absolutePath).catch(() => null);
|
|
14
|
+
if (!info?.isDirectory()) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const normalized = match.replace(/[\\/]+$/, '');
|
|
18
|
+
return normalized.length > 0 ? normalized : null;
|
|
19
|
+
}));
|
|
20
|
+
return directories.filter((value) => value !== null);
|
|
21
|
+
}
|
package/dist/utils/hash.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
1
|
export function hashContent(content, length = 8) {
|
|
3
|
-
const hash =
|
|
2
|
+
const hash = new Bun.CryptoHasher('sha256').update(content).digest('hex');
|
|
4
3
|
return hash.slice(0, length);
|
|
5
4
|
}
|
package/dist/utils/pagePaths.js
CHANGED
|
@@ -27,8 +27,8 @@ export function resolvePageHtmlDir(pagesRoot, pageName, useRootIndex) {
|
|
|
27
27
|
}
|
|
28
28
|
function joinUrl(...segments) {
|
|
29
29
|
const cleaned = segments
|
|
30
|
-
.map(segment => trimSlashes(segment))
|
|
31
|
-
.filter(segment => segment.length > 0);
|
|
30
|
+
.map((segment) => trimSlashes(segment))
|
|
31
|
+
.filter((segment) => segment.length > 0);
|
|
32
32
|
return `/${cleaned.join('/')}`;
|
|
33
33
|
}
|
|
34
34
|
function trimSlashes(value) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstir-io/webstir-frontend",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"description": "Frontend build and publish tooling for Webstir workspaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"import": "./dist/builders/index.js",
|
|
22
22
|
"default": "./dist/builders/index.js"
|
|
23
23
|
},
|
|
24
|
+
"./runtime": {
|
|
25
|
+
"types": "./dist/runtime/index.d.ts",
|
|
26
|
+
"import": "./dist/runtime/index.js",
|
|
27
|
+
"default": "./dist/runtime/index.js"
|
|
28
|
+
},
|
|
24
29
|
"./cli": {
|
|
25
30
|
"import": "./dist/cli.js",
|
|
26
31
|
"default": "./dist/cli.js"
|
|
@@ -33,9 +38,7 @@
|
|
|
33
38
|
"scripts": {
|
|
34
39
|
"build": "tsc -p tsconfig.json",
|
|
35
40
|
"clean": "rm -rf dist",
|
|
36
|
-
"test": "
|
|
37
|
-
"prepare": "npm run build",
|
|
38
|
-
"smoke": "npm run build && node scripts/smoke.mjs",
|
|
41
|
+
"test": "tsc -p tsconfig.json && BASELINE_BROWSER_MAPPING_IGNORE_OLD_DATA=true BROWSERSLIST_IGNORE_OLD_DATA=true bun test tests",
|
|
39
42
|
"release": "bash scripts/publish.sh"
|
|
40
43
|
},
|
|
41
44
|
"files": [
|
|
@@ -43,16 +46,20 @@
|
|
|
43
46
|
"src",
|
|
44
47
|
"scripts",
|
|
45
48
|
"tests",
|
|
46
|
-
"tsconfig.json"
|
|
47
|
-
"package-lock.json"
|
|
49
|
+
"tsconfig.json"
|
|
48
50
|
],
|
|
49
51
|
"engines": {
|
|
50
|
-
"
|
|
52
|
+
"bun": ">=1.3.11"
|
|
51
53
|
},
|
|
52
54
|
"license": "MIT",
|
|
53
55
|
"repository": {
|
|
54
56
|
"type": "git",
|
|
55
|
-
"url": "https://github.com/webstir-io/webstir
|
|
57
|
+
"url": "git+https://github.com/webstir-io/webstir.git",
|
|
58
|
+
"directory": "packages/tooling/webstir-frontend"
|
|
59
|
+
},
|
|
60
|
+
"homepage": "https://github.com/webstir-io/webstir/tree/main/packages/tooling/webstir-frontend#readme",
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/webstir-io/webstir/issues"
|
|
56
63
|
},
|
|
57
64
|
"keywords": [
|
|
58
65
|
"webstir",
|
|
@@ -65,14 +72,13 @@
|
|
|
65
72
|
"access": "public"
|
|
66
73
|
},
|
|
67
74
|
"dependencies": {
|
|
68
|
-
"@webstir-io/module-contract": "^0.1.
|
|
75
|
+
"@webstir-io/module-contract": "^0.1.16",
|
|
69
76
|
"autoprefixer": "^10.4.18",
|
|
70
77
|
"cheerio": "^1.0.0-rc.12",
|
|
71
78
|
"commander": "^12.1.0",
|
|
72
79
|
"csso": "^5.0.5",
|
|
80
|
+
"domhandler": "^5.0.3",
|
|
73
81
|
"esbuild": "^0.25.10",
|
|
74
|
-
"fs-extra": "^11.2.0",
|
|
75
|
-
"glob": "^10.4.1",
|
|
76
82
|
"highlight.js": "^11.11.1",
|
|
77
83
|
"html-minifier-terser": "^7.2.0",
|
|
78
84
|
"marked": "^12.0.2",
|
|
@@ -82,11 +88,10 @@
|
|
|
82
88
|
"zod": "^3.23.8"
|
|
83
89
|
},
|
|
84
90
|
"devDependencies": {
|
|
91
|
+
"@types/bun": "^1.3.11",
|
|
85
92
|
"@types/csso": "^5.0.4",
|
|
86
|
-
"@types/fs-extra": "^11.0.4",
|
|
87
|
-
"@types/glob": "^8.1.0",
|
|
88
93
|
"@types/html-minifier-terser": "^7.0.2",
|
|
89
|
-
"@types/node": "^
|
|
94
|
+
"@types/node": "^25.5.0",
|
|
90
95
|
"typescript": "^5.7.2"
|
|
91
96
|
}
|
|
92
97
|
}
|
package/scripts/publish.sh
CHANGED
|
@@ -2,100 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
|
-
usage() {
|
|
6
|
-
cat <<'EOF'
|
|
7
|
-
Usage: scripts/publish.sh <patch|minor|major|x.y.z> [--no-push]
|
|
8
|
-
|
|
9
|
-
Examples:
|
|
10
|
-
scripts/publish.sh patch
|
|
11
|
-
scripts/publish.sh 0.1.0
|
|
12
|
-
|
|
13
|
-
The script requires a clean git worktree and npm publish access to
|
|
14
|
-
@webstir-io. Publishing is handled by GitHub Actions via npm trusted
|
|
15
|
-
publishing (OIDC) after the version tag is pushed.
|
|
16
|
-
|
|
17
|
-
By default, the script pushes the version bump commit and tag. To skip pushing,
|
|
18
|
-
pass --no-push or set PUBLISH_NO_PUSH=1.
|
|
19
|
-
EOF
|
|
20
|
-
exit 1
|
|
21
|
-
}
|
|
22
|
-
|
|
23
5
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
6
|
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
7
|
+
MONOREPO_ROOT="$(git -C "$ROOT_DIR" rev-parse --show-toplevel)"
|
|
25
8
|
|
|
26
|
-
|
|
27
|
-
if [[ $# -lt 1 ]]; then
|
|
28
|
-
echo "error: version bump argument missing" >&2
|
|
29
|
-
usage
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
local bump="$1"; shift || true
|
|
33
|
-
local no_push="false"
|
|
34
|
-
|
|
35
|
-
while [[ $# -gt 0 ]]; do
|
|
36
|
-
case "$1" in
|
|
37
|
-
--no-push)
|
|
38
|
-
no_push="true"
|
|
39
|
-
;;
|
|
40
|
-
*)
|
|
41
|
-
echo "error: unknown option '$1'" >&2
|
|
42
|
-
usage
|
|
43
|
-
;;
|
|
44
|
-
esac
|
|
45
|
-
shift || true
|
|
46
|
-
done
|
|
47
|
-
|
|
48
|
-
if [[ ! $bump =~ ^(patch|minor|major)$ && ! $bump =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
49
|
-
echo "error: invalid bump '$bump'" >&2
|
|
50
|
-
usage
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
ensure_clean_git
|
|
54
|
-
|
|
55
|
-
cd "$ROOT_DIR"
|
|
56
|
-
|
|
57
|
-
echo "› npm version $bump"
|
|
58
|
-
npm version "$bump" -m "v%s"
|
|
59
|
-
|
|
60
|
-
echo "› npm install --package-lock-only"
|
|
61
|
-
npm install --package-lock-only
|
|
62
|
-
|
|
63
|
-
echo "› npm run clean"
|
|
64
|
-
npm run clean
|
|
65
|
-
|
|
66
|
-
echo "› npm run build"
|
|
67
|
-
npm run build
|
|
68
|
-
|
|
69
|
-
echo "› npm test"
|
|
70
|
-
npm test
|
|
71
|
-
|
|
72
|
-
echo "› npm run smoke"
|
|
73
|
-
npm run smoke
|
|
74
|
-
|
|
75
|
-
echo "› Skipping direct npm publish; pushing commit+tag will trigger the release workflow."
|
|
76
|
-
|
|
77
|
-
if [[ "$no_push" == "true" || "${PUBLISH_NO_PUSH:-}" =~ ^([Yy][Ee][Ss]|[Yy]|1|true)$ ]]; then
|
|
78
|
-
echo "› Skipping git push (no-push)."
|
|
79
|
-
echo " To publish upstream later, run: git push && git push --tags"
|
|
80
|
-
return 0
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
echo "› git push"
|
|
84
|
-
git push
|
|
85
|
-
echo "› git push --tags"
|
|
86
|
-
git push --tags
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
ensure_clean_git() {
|
|
90
|
-
cd "$ROOT_DIR"
|
|
91
|
-
if ! git diff --quiet --ignore-submodules HEAD; then
|
|
92
|
-
echo "error: git worktree has uncommitted changes" >&2
|
|
93
|
-
exit 1
|
|
94
|
-
fi
|
|
95
|
-
if ! git diff --quiet --cached --ignore-submodules; then
|
|
96
|
-
echo "error: git index has staged changes" >&2
|
|
97
|
-
exit 1
|
|
98
|
-
fi
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
main "$@"
|
|
9
|
+
exec bun "$MONOREPO_ROOT/tools/release-package.mjs" --package-dir "$ROOT_DIR" "$@"
|
|
@@ -22,6 +22,8 @@ EOF
|
|
|
22
22
|
|
|
23
23
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
24
|
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
25
|
+
MONOREPO_ROOT="$(git -C "$ROOT_DIR" rev-parse --show-toplevel)"
|
|
26
|
+
PACKAGE_NAME="$(node -p "require('./package.json').name" 2>/dev/null)"
|
|
25
27
|
|
|
26
28
|
has_script() {
|
|
27
29
|
local script_name="$1"
|
|
@@ -83,34 +85,34 @@ main() {
|
|
|
83
85
|
echo "› Setting @webstir-io/module-contract to $spec"
|
|
84
86
|
npm pkg set "dependencies.@webstir-io/module-contract=$spec"
|
|
85
87
|
|
|
86
|
-
echo "›
|
|
88
|
+
echo "› bun install (refresh workspace lockfile)"
|
|
87
89
|
if [[ "$fast" == "true" ]]; then
|
|
88
|
-
|
|
90
|
+
bun install --cwd "$MONOREPO_ROOT" --filter "$PACKAGE_NAME" --lockfile-only
|
|
89
91
|
else
|
|
90
|
-
|
|
92
|
+
bun install --cwd "$MONOREPO_ROOT" --filter "$PACKAGE_NAME"
|
|
91
93
|
fi
|
|
92
94
|
|
|
93
95
|
local frontend_ver
|
|
94
96
|
frontend_ver="$(node -p "require('./package.json').version" 2>/dev/null || echo 'unknown')"
|
|
95
97
|
local installed_contract
|
|
96
|
-
installed_contract="$(
|
|
98
|
+
installed_contract="$(node -p "try { require('@webstir-io/module-contract/package.json').version } catch { 'unknown' }" 2>/dev/null || echo 'unknown')"
|
|
97
99
|
echo "› Frontend package: @webstir-io/webstir-frontend@${frontend_ver}"
|
|
98
100
|
echo "› Contract installed: @webstir-io/module-contract@${installed_contract}"
|
|
99
101
|
|
|
100
102
|
if [[ "$fast" != "true" ]]; then
|
|
101
103
|
if has_script build; then
|
|
102
|
-
echo "›
|
|
103
|
-
|
|
104
|
+
echo "› bun run build"
|
|
105
|
+
bun run build
|
|
104
106
|
fi
|
|
105
107
|
|
|
106
108
|
if has_script test; then
|
|
107
|
-
echo "›
|
|
108
|
-
|
|
109
|
+
echo "› bun run test"
|
|
110
|
+
bun run test
|
|
109
111
|
fi
|
|
110
112
|
|
|
111
113
|
if has_script smoke; then
|
|
112
|
-
echo "›
|
|
113
|
-
|
|
114
|
+
echo "› bun run smoke"
|
|
115
|
+
bun run smoke
|
|
114
116
|
fi
|
|
115
117
|
fi
|
|
116
118
|
|
|
@@ -2,50 +2,60 @@ import path from 'node:path';
|
|
|
2
2
|
import { readJson, writeJson, ensureDir } from '../utils/fs.js';
|
|
3
3
|
|
|
4
4
|
export interface PageAssetManifest {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
js?: string;
|
|
6
|
+
css?: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export interface AssetManifest {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
pages: Record<string, PageAssetManifest>;
|
|
11
|
+
shared?: SharedAssets;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface SharedAssets {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
css?: string;
|
|
16
|
+
js?: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const MANIFEST_FILENAME = 'manifest.json';
|
|
20
20
|
|
|
21
|
-
export async function updatePageManifest(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
export async function updatePageManifest(
|
|
22
|
+
directory: string,
|
|
23
|
+
pageName: string,
|
|
24
|
+
updater: (value: PageAssetManifest) => void,
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
const manifestPath = path.join(directory, MANIFEST_FILENAME);
|
|
27
|
+
await ensureDir(directory);
|
|
28
|
+
const manifest = (await readJson<AssetManifest>(manifestPath)) ?? { pages: {} };
|
|
29
|
+
const pageManifest: PageAssetManifest = manifest.pages[pageName] ?? {};
|
|
30
|
+
updater(pageManifest);
|
|
31
|
+
manifest.pages[pageName] = pageManifest;
|
|
32
|
+
await writeJson(manifestPath, manifest);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
export async function readPageManifest(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
export async function readPageManifest(
|
|
36
|
+
directory: string,
|
|
37
|
+
pageName: string,
|
|
38
|
+
): Promise<PageAssetManifest> {
|
|
39
|
+
const manifestPath = path.join(directory, MANIFEST_FILENAME);
|
|
40
|
+
const manifest = (await readJson<AssetManifest>(manifestPath)) ?? { pages: {} };
|
|
41
|
+
return manifest.pages[pageName] ?? {};
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
export async function updateSharedAssets(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
export async function updateSharedAssets(
|
|
45
|
+
directory: string,
|
|
46
|
+
updater: (value: SharedAssets) => void,
|
|
47
|
+
): Promise<void> {
|
|
48
|
+
const manifestPath = path.join(directory, MANIFEST_FILENAME);
|
|
49
|
+
await ensureDir(directory);
|
|
50
|
+
const manifest = (await readJson<AssetManifest>(manifestPath)) ?? { pages: {} };
|
|
51
|
+
const shared: SharedAssets = manifest.shared ?? {};
|
|
52
|
+
updater(shared);
|
|
53
|
+
manifest.shared = shared;
|
|
54
|
+
await writeJson(manifestPath, manifest);
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
export async function readSharedAssets(directory: string): Promise<SharedAssets | null> {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
const manifestPath = path.join(directory, MANIFEST_FILENAME);
|
|
59
|
+
const manifest = await readJson<AssetManifest>(manifestPath);
|
|
60
|
+
return manifest?.shared ?? null;
|
|
51
61
|
}
|