@whatalo/cli-kit 1.1.0 → 1.1.1
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/dist/bundle/index.cjs +18 -0
- package/dist/bundle/index.d.cts +5 -0
- package/dist/bundle/index.d.ts +5 -0
- package/dist/bundle/index.mjs +21 -3
- package/package.json +10 -10
package/dist/bundle/index.cjs
CHANGED
|
@@ -105,6 +105,7 @@ var BundleBuilder = class {
|
|
|
105
105
|
`Build output directory "${absoluteOutputDir}" is empty after build.`
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
|
+
await this.validateIndexHtmlForCdn(files);
|
|
108
109
|
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
109
110
|
if (totalSize > MAX_BUNDLE_SIZE_BYTES) {
|
|
110
111
|
throw new Error(
|
|
@@ -114,6 +115,23 @@ var BundleBuilder = class {
|
|
|
114
115
|
const duration = Date.now() - startTime;
|
|
115
116
|
return { files, totalSize, duration };
|
|
116
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Ensures index.html uses relative asset URLs so bundles work under
|
|
120
|
+
* session-scoped CDN paths like /dev-bundles/{sessionId}/.
|
|
121
|
+
*/
|
|
122
|
+
async validateIndexHtmlForCdn(files) {
|
|
123
|
+
const indexFile = files.find((file) => file.relativePath === "index.html");
|
|
124
|
+
if (!indexFile) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const html = await (0, import_promises.readFile)(indexFile.absolutePath, "utf-8");
|
|
128
|
+
const hasRootAbsoluteAssetRefs = /(?:src|href)=["']\/assets\//i.test(html) || /(?:src|href)=["']\/[a-z0-9._-]+\//i.test(html);
|
|
129
|
+
if (hasRootAbsoluteAssetRefs) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
"Build output uses root-absolute asset paths in index.html. CDN dev bundles are served from a subpath, so assets must be relative. If you use Vite, set `base: './'` in vite.config.ts and rebuild."
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
117
135
|
/**
|
|
118
136
|
* Spawns the build process and waits for it to finish.
|
|
119
137
|
* Captures stderr for error reporting on non-zero exit.
|
package/dist/bundle/index.d.cts
CHANGED
|
@@ -40,6 +40,11 @@ declare class BundleBuilder {
|
|
|
40
40
|
* @throws If the build exits with a non-zero code or if total size exceeds 10 MB
|
|
41
41
|
*/
|
|
42
42
|
build(buildCommand: string, outputDir: string, cwd?: string): Promise<BuildResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Ensures index.html uses relative asset URLs so bundles work under
|
|
45
|
+
* session-scoped CDN paths like /dev-bundles/{sessionId}/.
|
|
46
|
+
*/
|
|
47
|
+
private validateIndexHtmlForCdn;
|
|
43
48
|
/**
|
|
44
49
|
* Spawns the build process and waits for it to finish.
|
|
45
50
|
* Captures stderr for error reporting on non-zero exit.
|
package/dist/bundle/index.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ declare class BundleBuilder {
|
|
|
40
40
|
* @throws If the build exits with a non-zero code or if total size exceeds 10 MB
|
|
41
41
|
*/
|
|
42
42
|
build(buildCommand: string, outputDir: string, cwd?: string): Promise<BuildResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Ensures index.html uses relative asset URLs so bundles work under
|
|
45
|
+
* session-scoped CDN paths like /dev-bundles/{sessionId}/.
|
|
46
|
+
*/
|
|
47
|
+
private validateIndexHtmlForCdn;
|
|
43
48
|
/**
|
|
44
49
|
* Spawns the build process and waits for it to finish.
|
|
45
50
|
* Captures stderr for error reporting on non-zero exit.
|
package/dist/bundle/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/bundle/builder.ts
|
|
2
2
|
import { spawn } from "child_process";
|
|
3
|
-
import { readdir, stat } from "fs/promises";
|
|
3
|
+
import { readFile, readdir, stat } from "fs/promises";
|
|
4
4
|
import path from "path";
|
|
5
5
|
var MAX_BUNDLE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
6
6
|
async function collectFiles(dir, rootDir) {
|
|
@@ -66,6 +66,7 @@ var BundleBuilder = class {
|
|
|
66
66
|
`Build output directory "${absoluteOutputDir}" is empty after build.`
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
|
+
await this.validateIndexHtmlForCdn(files);
|
|
69
70
|
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
70
71
|
if (totalSize > MAX_BUNDLE_SIZE_BYTES) {
|
|
71
72
|
throw new Error(
|
|
@@ -75,6 +76,23 @@ var BundleBuilder = class {
|
|
|
75
76
|
const duration = Date.now() - startTime;
|
|
76
77
|
return { files, totalSize, duration };
|
|
77
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Ensures index.html uses relative asset URLs so bundles work under
|
|
81
|
+
* session-scoped CDN paths like /dev-bundles/{sessionId}/.
|
|
82
|
+
*/
|
|
83
|
+
async validateIndexHtmlForCdn(files) {
|
|
84
|
+
const indexFile = files.find((file) => file.relativePath === "index.html");
|
|
85
|
+
if (!indexFile) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const html = await readFile(indexFile.absolutePath, "utf-8");
|
|
89
|
+
const hasRootAbsoluteAssetRefs = /(?:src|href)=["']\/assets\//i.test(html) || /(?:src|href)=["']\/[a-z0-9._-]+\//i.test(html);
|
|
90
|
+
if (hasRootAbsoluteAssetRefs) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"Build output uses root-absolute asset paths in index.html. CDN dev bundles are served from a subpath, so assets must be relative. If you use Vite, set `base: './'` in vite.config.ts and rebuild."
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
78
96
|
/**
|
|
79
97
|
* Spawns the build process and waits for it to finish.
|
|
80
98
|
* Captures stderr for error reporting on non-zero exit.
|
|
@@ -125,7 +143,7 @@ ${output}` : "")
|
|
|
125
143
|
};
|
|
126
144
|
|
|
127
145
|
// src/bundle/uploader.ts
|
|
128
|
-
import { readFile } from "fs/promises";
|
|
146
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
129
147
|
var UPLOAD_TIMEOUT_MS = 6e4;
|
|
130
148
|
var CONTENT_TYPE_MAP = {
|
|
131
149
|
".html": "text/html",
|
|
@@ -224,7 +242,7 @@ var BundleUploader = class {
|
|
|
224
242
|
};
|
|
225
243
|
}
|
|
226
244
|
try {
|
|
227
|
-
const body = await
|
|
245
|
+
const body = await readFile2(file.absolutePath);
|
|
228
246
|
const contentType = getContentType(file.relativePath);
|
|
229
247
|
const response = await fetch(presignedUrl, {
|
|
230
248
|
method: "PUT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whatalo/cli-kit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Shared CLI utilities for Whatalo plugin development tools",
|
|
@@ -76,14 +76,6 @@
|
|
|
76
76
|
"README.md",
|
|
77
77
|
"LICENSE"
|
|
78
78
|
],
|
|
79
|
-
"scripts": {
|
|
80
|
-
"build": "tsup",
|
|
81
|
-
"dev": "tsup --watch",
|
|
82
|
-
"test": "vitest run",
|
|
83
|
-
"test:watch": "vitest",
|
|
84
|
-
"type-check": "tsc --noEmit",
|
|
85
|
-
"clean": "rm -rf dist"
|
|
86
|
-
},
|
|
87
79
|
"dependencies": {
|
|
88
80
|
"@iarna/toml": "^2.2.5",
|
|
89
81
|
"chalk": "^5.4.1",
|
|
@@ -96,5 +88,13 @@
|
|
|
96
88
|
"tsup": "^8.5.0",
|
|
97
89
|
"typescript": "^5.9.3",
|
|
98
90
|
"vitest": "^3.2.4"
|
|
91
|
+
},
|
|
92
|
+
"scripts": {
|
|
93
|
+
"build": "tsup",
|
|
94
|
+
"dev": "tsup --watch",
|
|
95
|
+
"test": "vitest run",
|
|
96
|
+
"test:watch": "vitest",
|
|
97
|
+
"type-check": "tsc --noEmit",
|
|
98
|
+
"clean": "rm -rf dist"
|
|
99
99
|
}
|
|
100
|
-
}
|
|
100
|
+
}
|