@pajh/buldng 0.0.4 → 0.0.6
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 +7 -2
- package/src/MIME.json +11 -0
- package/src/buldng-async.js +20 -0
- package/src/buldng-files.js +59 -0
- package/src/buldng-html.js +262 -0
- package/src/buldng-lib.js +67 -411
- package/src/buldng-modal.ts +348 -0
- package/src/buldng-ops.js +21 -6
- package/src/buldng-typescript.js +77 -0
- package/src/buldng-validate.js +11 -4
- package/src/buldng-web.ts +55 -180
- package/src/buldng.css +130 -0
- package/src/dev-errors.js +16 -0
- package/src/layout-err.ts +171 -0
- package/src/layout.ts +4 -0
- package/src/serve-lib.js +574 -0
- package/src/serve.js +194 -0
- package/src/types/global.d.ts +9 -0
- package/src/wrapper.html +2 -0
- package/src/buldng-dev-errors.js +0 -84
package/src/buldng-lib.js
CHANGED
|
@@ -1,465 +1,121 @@
|
|
|
1
|
-
//
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
1
|
+
// buldng-lib.js — the main buldng build library
|
|
4
2
|
import esbuild from "esbuild";
|
|
5
|
-
|
|
6
|
-
|
|
7
3
|
import { fileURLToPath } from "node:url";
|
|
8
4
|
import { dirname, join } from "node:path";
|
|
5
|
+
import fs from "node:fs";
|
|
9
6
|
import { readFileSync } from "node:fs";
|
|
10
7
|
import { createRequire } from "node:module";
|
|
11
8
|
import { WorkFile } from "./workfile.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
from "./buldng-
|
|
16
|
-
|
|
9
|
+
import {
|
|
10
|
+
getDest, setSource, setDest, assertDestWrite, assertSourceRead, getInputs, trackInput, looksLikeFilename, looksLikeHTML,
|
|
11
|
+
looksLikeCSS, looksLikeJS, ensureLeadingSlash, ensureWorkFile
|
|
12
|
+
} from "./buldng-validate.js";
|
|
13
|
+
import { file, literal, wrap, append, replace, compile, materialise }
|
|
14
|
+
from "./buldng-ops.js";
|
|
15
|
+
export { file, literal, wrap, append, replace, compile, materialise }
|
|
17
16
|
from "./buldng-ops.js";
|
|
18
|
-
export {
|
|
19
|
-
|
|
17
|
+
export {
|
|
18
|
+
assertSourceRead, assertDestWrite, setSource, setDest, looksLikeFilename,
|
|
19
|
+
looksLikeHTML, looksLikeCSS, looksLikeJS, ensureWorkFile, ensureLeadingSlash,
|
|
20
|
+
trackInput
|
|
21
|
+
} from "./buldng-validate.js";
|
|
22
|
+
import { task, parallel, finalise } from "./buldng-async.js";
|
|
23
|
+
import { typescriptCheck } from "./buldng-typescript.js";
|
|
24
|
+
import { mkdir, deepCopy } from "./buldng-files.js";
|
|
25
|
+
import {
|
|
26
|
+
reg,
|
|
27
|
+
csslink,
|
|
28
|
+
scriptlink,
|
|
29
|
+
pageHTML,
|
|
30
|
+
buldngHTMLWrapper
|
|
31
|
+
} from "./buldng-html.js";
|
|
20
32
|
|
|
21
33
|
export default {
|
|
22
34
|
setSource,
|
|
23
35
|
setDest,
|
|
24
36
|
mkdir,
|
|
25
37
|
deepCopy,
|
|
38
|
+
task,
|
|
39
|
+
parallel,
|
|
40
|
+
finalise,
|
|
26
41
|
file,
|
|
27
42
|
literal,
|
|
28
43
|
wrap,
|
|
29
44
|
append,
|
|
30
45
|
replace,
|
|
31
|
-
materialise,
|
|
32
46
|
compile,
|
|
47
|
+
materialise,
|
|
48
|
+
task,
|
|
49
|
+
parallel,
|
|
50
|
+
finalise,
|
|
33
51
|
csslink,
|
|
34
52
|
scriptlink,
|
|
35
53
|
pageHTML,
|
|
36
54
|
buldngHTMLWrapper,
|
|
37
55
|
reg,
|
|
38
56
|
printHeader,
|
|
39
|
-
typescriptCheck
|
|
57
|
+
typescriptCheck,
|
|
58
|
+
writeBuildInputsManifest
|
|
40
59
|
};
|
|
41
60
|
|
|
42
61
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
43
62
|
const pkg = JSON.parse(readFileSync(join(here, "../package.json"), "utf8"));
|
|
44
|
-
const registry = new Map();
|
|
45
|
-
|
|
46
|
-
export function reg(key, value) {
|
|
47
|
-
if (typeof key !== "string") {
|
|
48
|
-
throw new Error(`reg(): key must be a string`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const wf = ensureWorkFile(value, "reg");
|
|
52
|
-
|
|
53
|
-
if (registry.has(key)) {
|
|
54
|
-
console.log(`reg(): overwriting existing key '${key}'`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
registry.set(key, wf);
|
|
58
|
-
return wf;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function findTSC() {
|
|
62
|
-
const localTSC = path.resolve("node_modules/.bin/tsc");
|
|
63
|
-
|
|
64
|
-
if (fs.existsSync(localTSC)) {
|
|
65
|
-
return localTSC; // Local compiler — correct
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const globalTSC = execSync("which tsc").toString().trim();
|
|
70
|
-
return globalTSC; // Global compiler — acceptable
|
|
71
|
-
} catch {
|
|
72
|
-
return null; // No compiler found
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function typescriptCheck() {
|
|
77
|
-
let hasTS = false;
|
|
78
|
-
const require = createRequire(import.meta.url);
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
// Detect ANY installed TypeScript (local or global)
|
|
82
|
-
require.resolve("typescript");
|
|
83
|
-
|
|
84
|
-
hasTS = true;
|
|
85
|
-
} catch {
|
|
86
|
-
hasTS = false;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!hasTS) {
|
|
90
|
-
console.log("TypeScript not found — skipping TS checks");
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const { execSync } = require("node:child_process");
|
|
95
|
-
const tscPath = findTSC();
|
|
96
|
-
|
|
97
|
-
if (!tscPath) {
|
|
98
|
-
console.error("TypeScript compiler not found (local or global)");
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
console.log("Using TypeScript compiler:", tscPath);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
// npx will run local tsc if present, otherwise global tsc
|
|
107
|
-
execSync(`${tscPath} --noEmit`, { stdio: "inherit" });
|
|
108
|
-
} catch (err) {
|
|
109
|
-
throw new Error("TypeScript check failed");
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
63
|
|
|
114
64
|
let headerPrinted = false;
|
|
115
65
|
export function printHeader(importMeta) {
|
|
116
66
|
if (headerPrinted) return;
|
|
117
67
|
headerPrinted = true;
|
|
118
|
-
|
|
68
|
+
|
|
119
69
|
const version = pkg.version;
|
|
120
70
|
const timestamp = new Date().toLocaleString("en-IE", { hour12: false });
|
|
121
|
-
|
|
71
|
+
|
|
122
72
|
const callerFile = fileURLToPath(importMeta.url);
|
|
123
73
|
const callerDir = dirname(callerFile);
|
|
124
|
-
|
|
74
|
+
|
|
125
75
|
console.log(`*local* buldng build system v${version} — ${timestamp}`);
|
|
126
76
|
console.log(`${callerDir}/${callerFile.split("/").pop()}`);
|
|
127
77
|
}
|
|
128
78
|
|
|
129
|
-
export function
|
|
130
|
-
|
|
131
|
-
const post = `">`;
|
|
132
|
-
|
|
133
|
-
// --------------------------------------------------
|
|
134
|
-
// Case 1: string
|
|
135
|
-
// --------------------------------------------------
|
|
136
|
-
if (typeof input === "string") {
|
|
137
|
-
if (!input.endsWith(".css")) {
|
|
138
|
-
throw new Error(`csslink(): expected a .css filename, got '${input}'`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return new WorkFile(
|
|
142
|
-
"literal",
|
|
143
|
-
{ value: pre + ensureLeadingSlash(input) + post },
|
|
144
|
-
[],
|
|
145
|
-
"csslink"
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// --------------------------------------------------
|
|
150
|
-
// Case 2: WorkFile
|
|
151
|
-
// --------------------------------------------------
|
|
152
|
-
if (input instanceof WorkFile) {
|
|
153
|
-
return new WorkFile(
|
|
154
|
-
"wrap",
|
|
155
|
-
{ pre, post },
|
|
156
|
-
[input],
|
|
157
|
-
"csslink"
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
throw new Error(`csslink(): expected string or WorkFile, got ${typeof input}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function scriptlink(input) {
|
|
165
|
-
const pre = `<script type="module" src="/`;
|
|
166
|
-
const post = `"></script>`;
|
|
167
|
-
|
|
168
|
-
// --------------------------------------------------
|
|
169
|
-
// Case 1: string
|
|
170
|
-
// --------------------------------------------------
|
|
171
|
-
if (typeof input === "string") {
|
|
172
|
-
if (!input.endsWith(".js")) {
|
|
173
|
-
throw new Error(`scriptlink(): expected a .js filename, got '${input}'`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return new WorkFile(
|
|
177
|
-
"literal",
|
|
178
|
-
{ value: pre + input + post },
|
|
179
|
-
[],
|
|
180
|
-
"scriptlink"
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// --------------------------------------------------
|
|
185
|
-
// Case 2: WorkFile
|
|
186
|
-
// --------------------------------------------------
|
|
187
|
-
if (input instanceof WorkFile) {
|
|
188
|
-
return new WorkFile(
|
|
189
|
-
"wrap",
|
|
190
|
-
{ pre, post },
|
|
191
|
-
[input],
|
|
192
|
-
"scriptlink"
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
throw new Error(`scriptlink(): expected string or WorkFile, got ${typeof input}`);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// --------------------------------------------------
|
|
201
|
-
// mkdir("puzzle")
|
|
202
|
-
// --------------------------------------------------
|
|
203
|
-
export function mkdir(relDir) {
|
|
204
|
-
const abs = assertDestWrite(relDir);
|
|
205
|
-
fs.mkdirSync(abs, { recursive: true });
|
|
79
|
+
export function header() {
|
|
80
|
+
printHeader(import.meta);
|
|
206
81
|
}
|
|
207
82
|
|
|
208
83
|
// --------------------------------------------------
|
|
209
|
-
//
|
|
84
|
+
// Development input manifest
|
|
210
85
|
// --------------------------------------------------
|
|
211
|
-
export function
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
console.log(`deepCopy: ${from} → ${to}`);
|
|
215
|
-
|
|
216
|
-
const absFrom = path.resolve(from);
|
|
217
|
-
|
|
218
|
-
if (to.includes("..")) {
|
|
219
|
-
throw new Error("SECURITY: Illegal path traversal in deepCopy()");
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const absTo = to === "/" ? DEST : path.resolve(DEST, to);
|
|
223
|
-
|
|
224
|
-
if (!absTo.startsWith(DEST)) {
|
|
225
|
-
throw new Error(`SECURITY: deepCopy target escapes dest:
|
|
226
|
-
dest: ${DEST}
|
|
227
|
-
target: ${absTo}`);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (!fs.existsSync(absFrom)) {
|
|
231
|
-
throw new Error(`deepCopy: source does not exist: ${absFrom}`);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function copyRecursive(src, dst) {
|
|
235
|
-
const stat = fs.statSync(src);
|
|
236
|
-
|
|
237
|
-
if (stat.isDirectory()) {
|
|
238
|
-
fs.mkdirSync(dst, { recursive: true });
|
|
239
|
-
const entries = fs.readdirSync(src);
|
|
240
|
-
for (const entry of entries) {
|
|
241
|
-
copyRecursive(path.join(src, entry), path.join(dst, entry));
|
|
242
|
-
}
|
|
243
|
-
} else {
|
|
244
|
-
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
245
|
-
fs.copyFileSync(src, dst);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
copyRecursive(absFrom, absTo);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export function header() {
|
|
253
|
-
printHeader(import.meta);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
function packageFileAbs(filename) {
|
|
258
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
259
|
-
const __dirname = dirname(__filename);
|
|
260
|
-
return join(__dirname, filename);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// wraps whatever you provide in the overall buldng html wrapper.
|
|
264
|
-
// also compiles buldng's layout.ts and saves layout.js to the site root.
|
|
265
|
-
export function buldngHTMLWrapper(source) {
|
|
266
|
-
const srcWF = ensureWorkFile(source, "source");
|
|
267
|
-
|
|
268
|
-
// 1. Compile buldng's layout.ts (lazy)
|
|
269
|
-
const layoutTS = new WorkFile("file", { absPath: packageFileAbs("layout.ts") }, []);
|
|
270
|
-
const layoutJS = compile(layoutTS);
|
|
271
|
-
|
|
272
|
-
// 2. Save compiled layout.js to the site root (this triggers execution)
|
|
273
|
-
layoutJS.save("layout.js");
|
|
274
|
-
|
|
275
|
-
// 2.5 Save camera.css to the site root (this triggers execution)
|
|
276
|
-
const buldngCSS = new WorkFile("file", { absPath: packageFileAbs("buldng.css") }, []);
|
|
277
|
-
buldngCSS.save("buldng.css");
|
|
278
|
-
|
|
279
|
-
const devErrors = new WorkFile("file", { absPath: packageFileAbs("buldng-dev-errors.js") }, []);
|
|
280
|
-
devErrors.save("buldng-dev-errors.js");
|
|
281
|
-
|
|
282
|
-
// 3. Wrap project shell in buldng's wrapper.html
|
|
283
|
-
const wrapperWF = new WorkFile("file", { absPath: packageFileAbs("wrapper.html") }, []);
|
|
284
|
-
return replace(wrapperWF, "<!--CAMERA-STYLE-->", srcWF);
|
|
86
|
+
export function writeBuildInputsManifest(additionalInputs = []) {
|
|
87
|
+
for (const input of additionalInputs) {
|
|
88
|
+
trackInput(input);
|
|
285
89
|
}
|
|
286
|
-
|
|
287
90
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
export function pageHTML({ app, css = null, js = null, out }) {
|
|
295
|
-
if (!out || typeof out !== "string") {
|
|
296
|
-
throw new Error("pageHTML(): 'out' must be a non-empty string");
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (!app) {
|
|
300
|
-
throw new Error("pageHTML(): 'app' is required and cannot be null");
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const appWF = ensureWorkFile(app, "app");
|
|
304
|
-
|
|
305
|
-
// Look up optional registered assets
|
|
306
|
-
const shellWF = registry.get("shell") ?? null;
|
|
307
|
-
const projectCSS = registry.get("projectCSS") ?? null;
|
|
308
|
-
|
|
309
|
-
// One-time warnings
|
|
310
|
-
if (!shellWF && !_warned.shell) {
|
|
311
|
-
console.warn(
|
|
312
|
-
"pageHTML(): no 'shell' registered — building raw page HTML.\n" +
|
|
313
|
-
"To register a shell use: reg('shell', file`layout/shell.html`)"
|
|
314
|
-
);
|
|
315
|
-
_warned.shell = true;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (!projectCSS && !_warned.projectCSS) {
|
|
319
|
-
console.warn(
|
|
320
|
-
"pageHTML(): no 'projectCSS' registered — page will not include project CSS.\n" +
|
|
321
|
-
"To register project CSS use: reg('projectCSS', file`layout/buldng.css`)"
|
|
322
|
-
);
|
|
323
|
-
_warned.projectCSS = true;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// --------------------------------------------------
|
|
327
|
-
// Build HTML WorkFile lazily
|
|
328
|
-
// --------------------------------------------------
|
|
329
|
-
|
|
330
|
-
let htmlWF;
|
|
331
|
-
|
|
332
|
-
if (shellWF) {
|
|
333
|
-
htmlWF = replace(shellWF, "<!--APP-->", appWF);
|
|
334
|
-
} else {
|
|
335
|
-
htmlWF = appWF;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Insert JS lazily
|
|
339
|
-
if (js) {
|
|
340
|
-
const jsWF = resolveAsset(js, {
|
|
341
|
-
ext: ".js",
|
|
342
|
-
tag: "scriptlink",
|
|
343
|
-
wrap: scriptlink,
|
|
344
|
-
autoPrefix: "js"
|
|
345
|
-
});
|
|
346
|
-
htmlWF = replace(htmlWF, "<!--SCRIPTS-->", jsWF);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Insert CSS lazily (project first)
|
|
350
|
-
const cssWFs = [];
|
|
351
|
-
|
|
352
|
-
if (projectCSS) {
|
|
353
|
-
cssWFs.push(resolveAsset(projectCSS, {
|
|
354
|
-
ext: ".css",
|
|
355
|
-
tag: "csslink",
|
|
356
|
-
wrap: csslink,
|
|
357
|
-
autoPrefix: "css"
|
|
358
|
-
}));
|
|
359
|
-
console.log(`${out}: has projectCSS`);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
if (css) {
|
|
363
|
-
cssWFs.push(resolveAsset(css, {
|
|
364
|
-
ext: ".css",
|
|
365
|
-
tag: "csslink",
|
|
366
|
-
wrap: csslink,
|
|
367
|
-
autoPrefix: "css"
|
|
368
|
-
}));
|
|
369
|
-
console.log(`${out}: has pageCSS`);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (cssWFs.length === 0) {
|
|
373
|
-
// No CSS at all → do nothing
|
|
374
|
-
// (This is allowed)
|
|
375
|
-
} else if (cssWFs.length === 1) {
|
|
376
|
-
// One CSS → inject directly
|
|
377
|
-
htmlWF = replace(htmlWF, "<!--CSS-->", cssWFs[0]);
|
|
378
|
-
} else {
|
|
379
|
-
// Two CSS → append them
|
|
380
|
-
const cssListWF = append(...cssWFs);
|
|
381
|
-
htmlWF = replace(htmlWF, "<!--CSS-->", cssListWF);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// The ONLY public collapse operator
|
|
385
|
-
return htmlWF.save(out);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
let autoCounter = 1;
|
|
389
|
-
|
|
390
|
-
function resolveAsset(input, {
|
|
391
|
-
ext, // ".css" or ".js"
|
|
392
|
-
tag, // "csslink" or "jslink"
|
|
393
|
-
wrap, // csslink() or stylelink()
|
|
394
|
-
autoPrefix // "css" or "js"
|
|
395
|
-
}) {
|
|
396
|
-
if (input == null) return null;
|
|
397
|
-
|
|
398
|
-
// Case 1: string
|
|
399
|
-
if (typeof input === "string") {
|
|
400
|
-
if (!input.endsWith(ext)) {
|
|
401
|
-
throw new Error(`pageHTML(${ext}): expected a ${ext} filename, got '${input}'`);
|
|
402
|
-
}
|
|
403
|
-
return wrap(input);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Case 2: must be WorkFile
|
|
407
|
-
if (!(input instanceof WorkFile)) {
|
|
408
|
-
throw new Error(`pageHTML(${ext}): expected string or WorkFile, got ${typeof input}`);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Case 3: already a link
|
|
412
|
-
if (input.tag === tag) {
|
|
413
|
-
return input;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Case 4: literal WorkFile
|
|
417
|
-
if (input.op === "literal") {
|
|
418
|
-
const value = input.config.value;
|
|
91
|
+
const manifest = Array.from(getInputs())
|
|
92
|
+
.filter(input => fs.existsSync(input) && fs.statSync(input).isFile())
|
|
93
|
+
.sort();
|
|
94
|
+
const out = assertDestWrite("build-inputs.json");
|
|
419
95
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
96
|
+
fs.writeFileSync(out, JSON.stringify(manifest, null, 2));
|
|
97
|
+
fs.chmodSync(out, 0o444);
|
|
98
|
+
console.log(`build-inputs.json: ${manifest.length} files recorded`);
|
|
423
99
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Case 5a: materialise WorkFile
|
|
430
|
-
if (input.op === "materialise") {
|
|
431
|
-
const target = input.config.target;
|
|
432
|
-
|
|
433
|
-
if (!target.endsWith(ext)) {
|
|
434
|
-
throw new Error(
|
|
435
|
-
`pageHTML(${ext}): materialise target '${target}' does not end in ${ext}`
|
|
436
|
-
);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return wrap(input);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// Case 5b: blob → auto-materialise
|
|
443
|
-
const autoName = `${autoPrefix}${autoCounter++}${ext}`;
|
|
100
|
+
return manifest;
|
|
101
|
+
}
|
|
444
102
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
103
|
+
function requestedBuildInputsManifest() {
|
|
104
|
+
return process.argv.slice(2).includes("--manifest");
|
|
105
|
+
}
|
|
448
106
|
|
|
449
|
-
|
|
450
|
-
|
|
107
|
+
function projectRootInputs() {
|
|
108
|
+
const buildScript = process.argv[1];
|
|
109
|
+
const projectRoot = dirname(buildScript);
|
|
110
|
+
return [
|
|
111
|
+
buildScript,
|
|
112
|
+
join(projectRoot, "package.json"),
|
|
113
|
+
join(projectRoot, "tsconfig.json"),
|
|
114
|
+
join(projectRoot, "safe_clean.sh")
|
|
115
|
+
].filter(input => fs.existsSync(input));
|
|
451
116
|
}
|
|
452
117
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
process.on("exit", () => {
|
|
458
|
-
if (process.env.BULDNG_HOT !== "1") return;
|
|
459
|
-
let DEST = getDest();
|
|
460
|
-
let INPUTS = getInputs();
|
|
461
|
-
const manifest = Array.from(INPUTS);
|
|
462
|
-
const out = path.join(DEST, "build-inputs.json");
|
|
463
|
-
fs.writeFileSync(out, JSON.stringify(manifest, null, 2));
|
|
464
|
-
});
|
|
465
|
-
|
|
118
|
+
process.on("exit", exitCode => {
|
|
119
|
+
if (exitCode !== 0 || !requestedBuildInputsManifest()) return;
|
|
120
|
+
writeBuildInputsManifest(projectRootInputs());
|
|
121
|
+
});
|