appstage 0.2.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/LICENSE +21 -0
- package/README.md +0 -0
- package/dist/bin/build.js +532 -0
- package/dist/bin/startDev.js +545 -0
- package/dist/bin/startProd.js +545 -0
- package/dist/index.cjs +671 -0
- package/dist/index.d.ts +1162 -0
- package/dist/index.mjs +622 -0
- package/index.ts +32 -0
- package/package.json +39 -0
- package/src/controllers/dir.ts +119 -0
- package/src/controllers/unhandledError.ts +15 -0
- package/src/controllers/unhandledRoute.ts +14 -0
- package/src/lib/lang/getEffectiveLocale.ts +52 -0
- package/src/lib/lang/getLocales.ts +10 -0
- package/src/lib/lang/toLanguage.ts +3 -0
- package/src/lib/logger/LogOptions.ts +8 -0
- package/src/lib/logger/ansiEscapeCodes.ts +6 -0
- package/src/lib/logger/levelColors.ts +4 -0
- package/src/lib/logger/log.ts +82 -0
- package/src/middleware/init.ts +22 -0
- package/src/middleware/lang.ts +83 -0
- package/src/middleware/requestEvents.ts +29 -0
- package/src/scripts/bin/build.ts +5 -0
- package/src/scripts/bin/startDev.ts +5 -0
- package/src/scripts/bin/startProd.ts +5 -0
- package/src/scripts/build.ts +45 -0
- package/src/scripts/cli.ts +46 -0
- package/src/scripts/const/commonBuildOptions.ts +13 -0
- package/src/scripts/const/entryExtensions.ts +1 -0
- package/src/scripts/start.ts +18 -0
- package/src/scripts/types/BuildParams.ts +9 -0
- package/src/scripts/utils/buildClient.ts +41 -0
- package/src/scripts/utils/buildServer.ts +35 -0
- package/src/scripts/utils/buildServerCSS.ts +38 -0
- package/src/scripts/utils/createPostbuildPlugins.ts +66 -0
- package/src/scripts/utils/getEntries.ts +22 -0
- package/src/scripts/utils/getEntryPoints.ts +25 -0
- package/src/scripts/utils/getFirstAvailable.ts +22 -0
- package/src/scripts/utils/populateEntries.ts +28 -0
- package/src/scripts/utils/toImportPath.ts +12 -0
- package/src/types/Controller.ts +4 -0
- package/src/types/ErrorController.ts +3 -0
- package/src/types/LogEventPayload.ts +12 -0
- package/src/types/LogLevel.ts +1 -0
- package/src/types/Middleware.ts +7 -0
- package/src/types/MiddlewareSet.ts +3 -0
- package/src/types/RenderStatus.ts +9 -0
- package/src/types/ReqCtx.ts +11 -0
- package/src/types/TransformContent.ts +11 -0
- package/src/types/express.d.ts +15 -0
- package/src/types/global.d.ts +17 -0
- package/src/utils/createApp.ts +44 -0
- package/src/utils/cspNonce.ts +6 -0
- package/src/utils/emitLog.ts +18 -0
- package/src/utils/getEntries.ts +22 -0
- package/src/utils/getStatusMessage.ts +5 -0
- package/src/utils/injectNonce.ts +7 -0
- package/src/utils/renderStatus.ts +20 -0
- package/src/utils/resolveFilePath.ts +78 -0
- package/src/utils/serializeState.ts +3 -0
- package/src/utils/servePipeableStream.ts +32 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
|
|
28
|
+
// node_modules/dateshape/dist/index.cjs
|
|
29
|
+
var require_dist = __commonJS({
|
|
30
|
+
"node_modules/dateshape/dist/index.cjs"(exports) {
|
|
31
|
+
var SEC = 1e3;
|
|
32
|
+
var MIN = 60 * SEC;
|
|
33
|
+
var HOUR = 60 * MIN;
|
|
34
|
+
var DAY = 24 * HOUR;
|
|
35
|
+
var INVALID_DATE_STRING = (/* @__PURE__ */ new Date("-")).toString();
|
|
36
|
+
function escapeRegExp(s) {
|
|
37
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
38
|
+
}
|
|
39
|
+
function fill(template, data, transformMap) {
|
|
40
|
+
let s = template;
|
|
41
|
+
for (let [key, value] of Object.entries(data)) {
|
|
42
|
+
let transform = transformMap?.[key];
|
|
43
|
+
s = s.replace(new RegExp(escapeRegExp(`{${key}}`), "g"), String(transform ? transform(data) : value));
|
|
44
|
+
}
|
|
45
|
+
if (transformMap) for (let [key, transform] of Object.entries(transformMap)) {
|
|
46
|
+
if (key in data) continue;
|
|
47
|
+
s = s.replace(new RegExp(escapeRegExp(`{${key}}`), "g"), String(transform(data)));
|
|
48
|
+
}
|
|
49
|
+
return s;
|
|
50
|
+
}
|
|
51
|
+
function getTimezone(dateString) {
|
|
52
|
+
if (!dateString) return;
|
|
53
|
+
if (/(^|T|\s)\d\d:\d\d:\d\d(\.\d{3})?Z(\s|$)/.test(dateString)) return "Z";
|
|
54
|
+
return dateString.match(/[+-]\d\d:?\d\d\b/)?.[0];
|
|
55
|
+
}
|
|
56
|
+
function getTimezoneOffset(timezone) {
|
|
57
|
+
if (timezone === "Z") return 0;
|
|
58
|
+
let [, sign2, h, m] = timezone?.match(/^([+-])?(\d\d):?(\d\d)$/) ?? [];
|
|
59
|
+
if (!sign2 || !h || !m) return;
|
|
60
|
+
return (sign2 === "-" ? 1 : -1) * (parseInt(h, 10) * 60 + parseInt(m, 10));
|
|
61
|
+
}
|
|
62
|
+
function toTimestamp(x) {
|
|
63
|
+
return (x instanceof Date ? x : new Date(x)).getTime();
|
|
64
|
+
}
|
|
65
|
+
function isInvalidDate(date) {
|
|
66
|
+
return Number.isNaN(toTimestamp(date));
|
|
67
|
+
}
|
|
68
|
+
function pad(x, length, padding = "0") {
|
|
69
|
+
return String(x).padStart(length, padding);
|
|
70
|
+
}
|
|
71
|
+
var { abs: abs$1, floor: floor$1, sign: sign$1 } = Math;
|
|
72
|
+
function getDateComponents(date, targetTimezone) {
|
|
73
|
+
if (isInvalidDate(date)) return;
|
|
74
|
+
let d = date instanceof Date ? date : new Date(date);
|
|
75
|
+
let tzOffset = d.getTimezoneOffset();
|
|
76
|
+
let targetTzOffset = getTimezoneOffset(targetTimezone);
|
|
77
|
+
if (typeof date === "string") {
|
|
78
|
+
let originalTzOffset = getTimezoneOffset(getTimezone(date));
|
|
79
|
+
if (originalTzOffset !== void 0) {
|
|
80
|
+
if (targetTzOffset === void 0) targetTzOffset = originalTzOffset;
|
|
81
|
+
d.setTime(d.getTime() + (tzOffset - targetTzOffset) * MIN);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (targetTzOffset !== void 0) tzOffset = targetTzOffset;
|
|
85
|
+
let year = d.getFullYear();
|
|
86
|
+
let month = d.getMonth();
|
|
87
|
+
let day = d.getDate();
|
|
88
|
+
let weekDay = d.getDay();
|
|
89
|
+
let Y = String(year);
|
|
90
|
+
let M = String(month + 1);
|
|
91
|
+
let D = String(day);
|
|
92
|
+
let absYear = abs$1(year);
|
|
93
|
+
let yearSign = sign$1(year) === -1 ? "-" : "";
|
|
94
|
+
let YY = `${yearSign}${pad(absYear, 2)}`;
|
|
95
|
+
let MM = pad(M, 2);
|
|
96
|
+
let DD = pad(D, 2);
|
|
97
|
+
let YYYY = `${yearSign}${pad(absYear, 4)}`;
|
|
98
|
+
let yy = pad(absYear % 100, 2);
|
|
99
|
+
let hours = d.getHours();
|
|
100
|
+
let minutes = d.getMinutes();
|
|
101
|
+
let seconds = d.getSeconds();
|
|
102
|
+
let milliseconds = d.getMilliseconds();
|
|
103
|
+
let H = String(hours);
|
|
104
|
+
let m = String(minutes);
|
|
105
|
+
let s = String(seconds);
|
|
106
|
+
let HH = pad(H, 2);
|
|
107
|
+
let mm = pad(m, 2);
|
|
108
|
+
let ss = pad(s, 2);
|
|
109
|
+
let ms = pad(milliseconds, 3);
|
|
110
|
+
let YE = String(year < 1 ? abs$1(year - 1) : year);
|
|
111
|
+
let E = year < 1 ? -1 : 1;
|
|
112
|
+
let CE = year < 1 ? -1 : 1;
|
|
113
|
+
let hours12 = hours % 12 || 12;
|
|
114
|
+
let h = String(hours12);
|
|
115
|
+
let hh = pad(h, 2);
|
|
116
|
+
let a = hours < 12 ? "AM" : "PM";
|
|
117
|
+
let tzSign = -sign$1(tzOffset);
|
|
118
|
+
let absTzOffset = abs$1(tzOffset);
|
|
119
|
+
let tzHours = floor$1(absTzOffset / 60);
|
|
120
|
+
let tzMinutes = absTzOffset - tzHours * 60;
|
|
121
|
+
let tz = `${tzSign === -1 ? "-" : "+"}${pad(tzHours, 2)}:${pad(tzMinutes, 2)}`;
|
|
122
|
+
let isoDate = `${YYYY}-${MM}-${DD}`;
|
|
123
|
+
let isoTime = `${HH}:${mm}:${ss}`;
|
|
124
|
+
let isoTimeMs = `${isoTime}.${ms}`;
|
|
125
|
+
let iso = `${isoDate}T${isoTimeMs}${tz}`;
|
|
126
|
+
return {
|
|
127
|
+
input: date,
|
|
128
|
+
date: d,
|
|
129
|
+
timestamp: d.getTime(),
|
|
130
|
+
year,
|
|
131
|
+
month,
|
|
132
|
+
day,
|
|
133
|
+
weekDay,
|
|
134
|
+
Y,
|
|
135
|
+
M,
|
|
136
|
+
D,
|
|
137
|
+
YY,
|
|
138
|
+
YYYY,
|
|
139
|
+
yy,
|
|
140
|
+
MM,
|
|
141
|
+
DD,
|
|
142
|
+
YE,
|
|
143
|
+
E,
|
|
144
|
+
CE,
|
|
145
|
+
hours,
|
|
146
|
+
minutes,
|
|
147
|
+
seconds,
|
|
148
|
+
milliseconds,
|
|
149
|
+
hours12,
|
|
150
|
+
H,
|
|
151
|
+
m,
|
|
152
|
+
s,
|
|
153
|
+
ms,
|
|
154
|
+
h,
|
|
155
|
+
a,
|
|
156
|
+
tz,
|
|
157
|
+
HH,
|
|
158
|
+
mm,
|
|
159
|
+
ss,
|
|
160
|
+
hh,
|
|
161
|
+
isoDate,
|
|
162
|
+
isoTime,
|
|
163
|
+
isoTimeMs,
|
|
164
|
+
iso,
|
|
165
|
+
timezoneOffset: tzOffset
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function formatDate(date, template = "{iso}", transform, targetTimezone) {
|
|
169
|
+
if (isInvalidDate(date)) return INVALID_DATE_STRING;
|
|
170
|
+
if (typeof template === "object") {
|
|
171
|
+
let options = template;
|
|
172
|
+
transform = options.transform;
|
|
173
|
+
targetTimezone = options.targetTimezone;
|
|
174
|
+
template = options.template;
|
|
175
|
+
} else if (typeof transform === "string") {
|
|
176
|
+
targetTimezone = transform;
|
|
177
|
+
transform = void 0;
|
|
178
|
+
}
|
|
179
|
+
let dateComponents = getDateComponents(date, targetTimezone);
|
|
180
|
+
if (!dateComponents) return INVALID_DATE_STRING;
|
|
181
|
+
return fill(typeof template === "function" ? template(dateComponents) : template, dateComponents, transform);
|
|
182
|
+
}
|
|
183
|
+
var { abs, floor, sign } = Math;
|
|
184
|
+
function formatDuration2(duration) {
|
|
185
|
+
let durationSign = sign(duration);
|
|
186
|
+
let absDuration = abs(duration);
|
|
187
|
+
let d = floor(absDuration / DAY);
|
|
188
|
+
let h = floor((absDuration - d * DAY) / HOUR);
|
|
189
|
+
let m = floor((absDuration - d * DAY - h * HOUR) / MIN);
|
|
190
|
+
let s = floor((absDuration - d * DAY - h * HOUR - m * MIN) / SEC);
|
|
191
|
+
let ms = absDuration - d * DAY - h * HOUR - m * MIN - s * SEC;
|
|
192
|
+
let value = "";
|
|
193
|
+
value += d === 0 ? "" : `${d}d`;
|
|
194
|
+
value += value ? `${pad(h, 2)}h` : h === 0 ? "" : `${h}h`;
|
|
195
|
+
value += value ? `${pad(m, 2)}'` : m === 0 ? "" : `${m}'`;
|
|
196
|
+
value += `${value ? pad(s, 2) : s}.${pad(ms, 3)}"`;
|
|
197
|
+
return `${durationSign === -1 ? "-" : ""}${value}`;
|
|
198
|
+
}
|
|
199
|
+
function toLocalISOString(date) {
|
|
200
|
+
return formatDate(date, "{iso}");
|
|
201
|
+
}
|
|
202
|
+
exports.DAY = DAY;
|
|
203
|
+
exports.HOUR = HOUR;
|
|
204
|
+
exports.INVALID_DATE_STRING = INVALID_DATE_STRING;
|
|
205
|
+
exports.MIN = MIN;
|
|
206
|
+
exports.SEC = SEC;
|
|
207
|
+
exports.formatDate = formatDate;
|
|
208
|
+
exports.formatDuration = formatDuration2;
|
|
209
|
+
exports.getDateComponents = getDateComponents;
|
|
210
|
+
exports.getTimezone = getTimezone;
|
|
211
|
+
exports.getTimezoneOffset = getTimezoneOffset;
|
|
212
|
+
exports.isInvalidDate = isInvalidDate;
|
|
213
|
+
exports.toLocalISOString = toLocalISOString;
|
|
214
|
+
exports.toTimestamp = toTimestamp;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// src/scripts/cli.ts
|
|
219
|
+
import { rm as rm2 } from "node:fs/promises";
|
|
220
|
+
|
|
221
|
+
// src/scripts/build.ts
|
|
222
|
+
var import_dateshape = __toESM(require_dist(), 1);
|
|
223
|
+
import { spawn } from "node:child_process";
|
|
224
|
+
|
|
225
|
+
// src/scripts/utils/buildClient.ts
|
|
226
|
+
import esbuild from "esbuild";
|
|
227
|
+
|
|
228
|
+
// src/scripts/const/commonBuildOptions.ts
|
|
229
|
+
var commonBuildOptions = {
|
|
230
|
+
format: "cjs",
|
|
231
|
+
jsx: "automatic",
|
|
232
|
+
jsxDev: process.env.NODE_ENV === "development",
|
|
233
|
+
loader: {
|
|
234
|
+
".png": "dataurl",
|
|
235
|
+
".svg": "dataurl",
|
|
236
|
+
".html": "text",
|
|
237
|
+
".txt": "text"
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// src/scripts/utils/getEntries.ts
|
|
242
|
+
import { lstat, readdir } from "node:fs/promises";
|
|
243
|
+
import { join } from "node:path";
|
|
244
|
+
async function getEntries() {
|
|
245
|
+
let cwd = process.cwd();
|
|
246
|
+
try {
|
|
247
|
+
let list = await readdir(join(cwd, "src/entries"));
|
|
248
|
+
let dirs = await Promise.all(
|
|
249
|
+
list.map(async (name) => {
|
|
250
|
+
let itemStat = await lstat(join(cwd, "src/entries", name));
|
|
251
|
+
return itemStat.isDirectory() ? name : void 0;
|
|
252
|
+
})
|
|
253
|
+
);
|
|
254
|
+
return dirs.filter((dir) => dir !== void 0);
|
|
255
|
+
} catch {
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/scripts/utils/getFirstAvailable.ts
|
|
261
|
+
import { access } from "node:fs/promises";
|
|
262
|
+
import { join as join2 } from "node:path";
|
|
263
|
+
|
|
264
|
+
// src/scripts/const/entryExtensions.ts
|
|
265
|
+
var entryExtensions = ["js", "jsx", "ts", "tsx"];
|
|
266
|
+
|
|
267
|
+
// src/scripts/utils/getFirstAvailable.ts
|
|
268
|
+
async function getFirstAvailable(dirPath, path) {
|
|
269
|
+
let paths = Array.isArray(path) ? path : [path];
|
|
270
|
+
for (let filePath of paths) {
|
|
271
|
+
for (let ext of entryExtensions) {
|
|
272
|
+
let path2 = join2(process.cwd(), dirPath, `${filePath}.${ext}`);
|
|
273
|
+
try {
|
|
274
|
+
await access(path2);
|
|
275
|
+
return path2;
|
|
276
|
+
} catch {
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/scripts/utils/getEntryPoints.ts
|
|
283
|
+
async function getEntryPoints(path) {
|
|
284
|
+
let entries = await getEntries();
|
|
285
|
+
return (await Promise.all(
|
|
286
|
+
entries.map(async (name) => {
|
|
287
|
+
let resolvedPath = await getFirstAvailable(`src/entries/${name}`, path);
|
|
288
|
+
return resolvedPath === void 0 ? void 0 : { name, path: resolvedPath };
|
|
289
|
+
})
|
|
290
|
+
)).filter((item) => item !== void 0);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// src/scripts/utils/buildClient.ts
|
|
294
|
+
async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
|
|
295
|
+
let clientEntries = await getEntryPoints(["ui/index"]);
|
|
296
|
+
let buildOptions = {
|
|
297
|
+
...commonBuildOptions,
|
|
298
|
+
entryPoints: clientEntries.map(({ path }) => path),
|
|
299
|
+
bundle: true,
|
|
300
|
+
splitting: true,
|
|
301
|
+
format: "esm",
|
|
302
|
+
outdir: `${publicAssetsDir}/-`,
|
|
303
|
+
outbase: "src/entries",
|
|
304
|
+
minify: process.env.NODE_ENV !== "development",
|
|
305
|
+
plugins
|
|
306
|
+
};
|
|
307
|
+
if (watch || watchClient) {
|
|
308
|
+
let ctx = await esbuild.context(buildOptions);
|
|
309
|
+
await ctx.watch();
|
|
310
|
+
return async () => {
|
|
311
|
+
await ctx.dispose();
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
await esbuild.build(buildOptions);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/scripts/utils/buildServer.ts
|
|
318
|
+
import esbuild2 from "esbuild";
|
|
319
|
+
|
|
320
|
+
// src/scripts/utils/populateEntries.ts
|
|
321
|
+
import { writeFile } from "node:fs/promises";
|
|
322
|
+
|
|
323
|
+
// src/scripts/utils/toImportPath.ts
|
|
324
|
+
import { join as join3, posix, relative, sep } from "node:path";
|
|
325
|
+
function toImportPath(relativePath, referencePath = ".") {
|
|
326
|
+
let cwd = process.cwd();
|
|
327
|
+
let importPath = posix.join(
|
|
328
|
+
...relative(join3(cwd, referencePath), relativePath).split(sep)
|
|
329
|
+
);
|
|
330
|
+
if (importPath && !/^\.+\//.test(importPath)) importPath = `./${importPath}`;
|
|
331
|
+
return importPath;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/scripts/utils/populateEntries.ts
|
|
335
|
+
async function populateEntries() {
|
|
336
|
+
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
337
|
+
let content = "";
|
|
338
|
+
if (serverEntries.length === 0) content = "export const entries = [];";
|
|
339
|
+
else {
|
|
340
|
+
content = "export const entries = (\n await Promise.all([";
|
|
341
|
+
for (let i = 0; i < serverEntries.length; i++) {
|
|
342
|
+
content += `
|
|
343
|
+
// ${serverEntries[i].name}
|
|
344
|
+
import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
345
|
+
}
|
|
346
|
+
content += "\n ])\n).map(({ server }) => server);";
|
|
347
|
+
}
|
|
348
|
+
await writeFile(
|
|
349
|
+
"src/server/entries.ts",
|
|
350
|
+
`// Populated automatically during the build phase by picking
|
|
351
|
+
// all server exports from 'src/entries/<entry_name>/server(/index)?.(js|ts)'
|
|
352
|
+
${content}
|
|
353
|
+
`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/scripts/utils/buildServer.ts
|
|
358
|
+
async function buildServer({ targetDir, watch, watchServer }, plugins) {
|
|
359
|
+
await populateEntries();
|
|
360
|
+
let buildOptions = {
|
|
361
|
+
...commonBuildOptions,
|
|
362
|
+
entryPoints: ["src/server/index.ts"],
|
|
363
|
+
bundle: true,
|
|
364
|
+
splitting: true,
|
|
365
|
+
outdir: `${targetDir}/server`,
|
|
366
|
+
platform: "node",
|
|
367
|
+
format: "esm",
|
|
368
|
+
packages: "external",
|
|
369
|
+
plugins
|
|
370
|
+
};
|
|
371
|
+
if (watch || watchServer) {
|
|
372
|
+
let ctx = await esbuild2.context(buildOptions);
|
|
373
|
+
await ctx.watch();
|
|
374
|
+
return async () => {
|
|
375
|
+
await ctx.dispose();
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
await esbuild2.build(buildOptions);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/scripts/utils/buildServerCSS.ts
|
|
382
|
+
import esbuild3 from "esbuild";
|
|
383
|
+
async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
|
|
384
|
+
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
385
|
+
let buildOptions = {
|
|
386
|
+
...commonBuildOptions,
|
|
387
|
+
entryPoints: serverEntries.map(({ name, path }) => ({
|
|
388
|
+
in: path,
|
|
389
|
+
out: name
|
|
390
|
+
})),
|
|
391
|
+
bundle: true,
|
|
392
|
+
splitting: false,
|
|
393
|
+
outdir: `${targetDir}/server-css`,
|
|
394
|
+
platform: "node",
|
|
395
|
+
format: "esm",
|
|
396
|
+
packages: "external",
|
|
397
|
+
plugins
|
|
398
|
+
};
|
|
399
|
+
if (watch || watchServer) {
|
|
400
|
+
let ctx = await esbuild3.context(buildOptions);
|
|
401
|
+
await ctx.watch();
|
|
402
|
+
return async () => {
|
|
403
|
+
await ctx.dispose();
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
await esbuild3.build(buildOptions);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// src/scripts/utils/createPostbuildPlugins.ts
|
|
410
|
+
import { mkdir, readdir as readdir2, rename, rm } from "node:fs/promises";
|
|
411
|
+
function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
|
|
412
|
+
let serverPlugins = [
|
|
413
|
+
{
|
|
414
|
+
name: "skip-css",
|
|
415
|
+
setup(build2) {
|
|
416
|
+
build2.onLoad({ filter: /\.css$/ }, () => ({ contents: "" }));
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
name: "postbuild-server",
|
|
421
|
+
setup(build2) {
|
|
422
|
+
build2.onEnd(() => {
|
|
423
|
+
onServerRebuild();
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
];
|
|
428
|
+
let serverCSSPlugins = [
|
|
429
|
+
{
|
|
430
|
+
name: "postbuild-server-css",
|
|
431
|
+
setup(build2) {
|
|
432
|
+
build2.onEnd(async () => {
|
|
433
|
+
let dir = `${targetDir}/server-css`;
|
|
434
|
+
try {
|
|
435
|
+
let files = (await readdir2(dir)).filter(
|
|
436
|
+
(name) => name.endsWith(".css")
|
|
437
|
+
);
|
|
438
|
+
if (files.length === 0) return;
|
|
439
|
+
await mkdir(`${publicAssetsDir}/-`, { recursive: true });
|
|
440
|
+
await Promise.all(
|
|
441
|
+
files.map(async (name) => {
|
|
442
|
+
let dir2 = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
|
|
443
|
+
await mkdir(dir2, { recursive: true });
|
|
444
|
+
await rename(
|
|
445
|
+
`${targetDir}/server-css/${name}`,
|
|
446
|
+
`${dir2}/index.css`
|
|
447
|
+
);
|
|
448
|
+
})
|
|
449
|
+
);
|
|
450
|
+
await rm(dir, { recursive: true, force: true });
|
|
451
|
+
} catch {
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
];
|
|
457
|
+
return {
|
|
458
|
+
serverPlugins,
|
|
459
|
+
serverCSSPlugins
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// src/scripts/build.ts
|
|
464
|
+
async function build(params) {
|
|
465
|
+
let startTime = Date.now();
|
|
466
|
+
let log = params.silent ? () => {
|
|
467
|
+
} : console.log;
|
|
468
|
+
log("Build started");
|
|
469
|
+
let serverProcess = null;
|
|
470
|
+
let inited = false;
|
|
471
|
+
function handleServerRebuild() {
|
|
472
|
+
if (serverProcess) {
|
|
473
|
+
serverProcess.kill();
|
|
474
|
+
serverProcess = null;
|
|
475
|
+
}
|
|
476
|
+
if (!inited) {
|
|
477
|
+
log(`Build completed +${(0, import_dateshape.formatDuration)(Date.now() - startTime)}`);
|
|
478
|
+
inited = true;
|
|
479
|
+
}
|
|
480
|
+
if (params.start)
|
|
481
|
+
serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], {
|
|
482
|
+
stdio: "inherit"
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
let { serverPlugins, serverCSSPlugins } = createPostbuildPlugins(
|
|
486
|
+
params,
|
|
487
|
+
handleServerRebuild
|
|
488
|
+
);
|
|
489
|
+
await Promise.all([
|
|
490
|
+
buildServer(params, serverPlugins),
|
|
491
|
+
buildServerCSS(params, serverCSSPlugins),
|
|
492
|
+
buildClient(params)
|
|
493
|
+
]);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/scripts/cli.ts
|
|
497
|
+
var defaultTargetDir = "dist";
|
|
498
|
+
async function clean({ targetDir, publicAssetsDir }) {
|
|
499
|
+
let dirs = [
|
|
500
|
+
`${targetDir}/server`,
|
|
501
|
+
`${targetDir}/server-css`,
|
|
502
|
+
`${publicAssetsDir}/-`
|
|
503
|
+
];
|
|
504
|
+
return Promise.all(
|
|
505
|
+
dirs.map((dir) => rm2(dir, { recursive: true, force: true }))
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
async function cli(args = []) {
|
|
509
|
+
let publicAssetsDir = args[0];
|
|
510
|
+
let targetDir = args[1];
|
|
511
|
+
if (!publicAssetsDir || publicAssetsDir.startsWith("--"))
|
|
512
|
+
throw new Error("Public assets directory is undefined");
|
|
513
|
+
if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
|
|
514
|
+
let params = {
|
|
515
|
+
targetDir,
|
|
516
|
+
publicAssetsDir,
|
|
517
|
+
silent: args.includes("--silent"),
|
|
518
|
+
watch: args.includes("--watch"),
|
|
519
|
+
watchServer: args.includes("--watch-server"),
|
|
520
|
+
watchClient: args.includes("--watch-client"),
|
|
521
|
+
start: args.includes("--start")
|
|
522
|
+
};
|
|
523
|
+
if (args.includes("--clean-only")) {
|
|
524
|
+
await clean(params);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (args.includes("--clean")) await clean(params);
|
|
528
|
+
await build(params);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// src/scripts/start.ts
|
|
532
|
+
async function start(nodeEnv = "development", host) {
|
|
533
|
+
if (nodeEnv) process.env.NODE_ENV = nodeEnv;
|
|
534
|
+
if (host) {
|
|
535
|
+
let [hostname, port] = host.split(":");
|
|
536
|
+
if (hostname) process.env.APP_HOST = hostname;
|
|
537
|
+
if (port) process.env.APP_PORT = port;
|
|
538
|
+
}
|
|
539
|
+
await cli(
|
|
540
|
+
nodeEnv === "development" ? ["src/public", "--clean", "--start", "--watch"] : ["src/public", "--clean", "--start", "--silent"]
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// src/scripts/bin/startDev.ts
|
|
545
|
+
await start("development", process.argv[2]);
|