appstage 0.2.11 → 0.2.13
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/bin.js +12 -12
- package/dist/index.cjs +33 -13
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +33 -13
- package/package.json +1 -1
- package/src/controllers/files.ts +53 -13
- package/src/scripts/utils/buildClient.ts +5 -4
- package/src/scripts/utils/buildServer.ts +2 -2
- package/src/scripts/utils/{populateEntries.ts → setEntriesExport.ts} +5 -6
package/dist/bin.js
CHANGED
|
@@ -434,16 +434,17 @@ async function getEntryPoints(path) {
|
|
|
434
434
|
|
|
435
435
|
// src/scripts/utils/buildClient.ts
|
|
436
436
|
var entryClientPaths = ["ui/index", "client/index", "index", "src/index"];
|
|
437
|
-
async function buildClient({
|
|
437
|
+
async function buildClient({ watch, watchClient }, plugins) {
|
|
438
438
|
let clientEntries = await getEntryPoints(entryClientPaths);
|
|
439
439
|
let buildOptions = {
|
|
440
440
|
...commonBuildOptions,
|
|
441
|
-
entryPoints: clientEntries.map(({ path }) =>
|
|
441
|
+
entryPoints: clientEntries.map(({ path, name }) => ({
|
|
442
|
+
in: path,
|
|
443
|
+
out: `src/entries/${name}/dist/index`
|
|
444
|
+
})),
|
|
442
445
|
bundle: true,
|
|
443
446
|
splitting: true,
|
|
444
447
|
format: "esm",
|
|
445
|
-
outdir: clientDir,
|
|
446
|
-
outbase: "src/entries",
|
|
447
448
|
minify: process.env.NODE_ENV !== "development",
|
|
448
449
|
plugins
|
|
449
450
|
};
|
|
@@ -460,7 +461,7 @@ async function buildClient({ clientDir, watch, watchClient }, plugins) {
|
|
|
460
461
|
// src/scripts/utils/buildServer.ts
|
|
461
462
|
import esbuild2 from "esbuild";
|
|
462
463
|
|
|
463
|
-
// src/scripts/utils/
|
|
464
|
+
// src/scripts/utils/setEntriesExport.ts
|
|
464
465
|
import { writeFile } from "node:fs/promises";
|
|
465
466
|
|
|
466
467
|
// src/scripts/utils/toImportPath.ts
|
|
@@ -474,25 +475,24 @@ function toImportPath(relativePath, referencePath = ".") {
|
|
|
474
475
|
return importPath;
|
|
475
476
|
}
|
|
476
477
|
|
|
477
|
-
// src/scripts/utils/
|
|
478
|
-
async function
|
|
478
|
+
// src/scripts/utils/setEntriesExport.ts
|
|
479
|
+
async function setEntriesExport({ entriesPath }) {
|
|
479
480
|
if (entriesPath === null) return;
|
|
480
481
|
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
481
482
|
let content = "";
|
|
482
483
|
if (serverEntries.length === 0) content = "export const entries = [];";
|
|
483
484
|
else {
|
|
484
485
|
content = "export const entries = (\n await Promise.all([";
|
|
485
|
-
for (let i = 0; i < serverEntries.length; i++)
|
|
486
|
+
for (let i = 0; i < serverEntries.length; i++)
|
|
486
487
|
content += `
|
|
487
|
-
// ${serverEntries[i].name}
|
|
488
488
|
import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
489
|
-
}
|
|
490
489
|
content += "\n ])\n).map(({ server }) => server);";
|
|
491
490
|
}
|
|
492
491
|
await writeFile(
|
|
493
492
|
entriesPath ?? "src/server/entries.ts",
|
|
494
493
|
`// Populated automatically during the build phase by picking
|
|
495
|
-
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
|
|
494
|
+
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)".
|
|
495
|
+
// Ignore this file if a custom set of entry exports is required.
|
|
496
496
|
${content}
|
|
497
497
|
`
|
|
498
498
|
);
|
|
@@ -502,7 +502,7 @@ ${content}
|
|
|
502
502
|
var appServerEntryPoints = ["src/server/index.ts"];
|
|
503
503
|
async function buildServer(params, plugins) {
|
|
504
504
|
let { serverDir, watch, watchServer } = params;
|
|
505
|
-
await
|
|
505
|
+
await setEntriesExport(params);
|
|
506
506
|
let buildOptions = {
|
|
507
507
|
...commonBuildOptions,
|
|
508
508
|
entryPoints: appServerEntryPoints,
|
package/dist/index.cjs
CHANGED
|
@@ -68,6 +68,15 @@ function getLanguageList(req) {
|
|
|
68
68
|
}
|
|
69
69
|
return Array.from(langs);
|
|
70
70
|
}
|
|
71
|
+
function matches(x, matcher) {
|
|
72
|
+
if (matcher === null || matcher === void 0) return true;
|
|
73
|
+
if (typeof matcher === "function") return matcher(x);
|
|
74
|
+
let patterns = Array.isArray(matcher) ? matcher : [matcher];
|
|
75
|
+
for (let pattern of patterns) if (pattern instanceof RegExp) {
|
|
76
|
+
if (pattern.test(x)) return true;
|
|
77
|
+
} else if (pattern === x) return true;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
71
80
|
const defaultExtensions = ["html", "htm"];
|
|
72
81
|
const defaultPath = (req) => req.originalUrl.split("?")[0];
|
|
73
82
|
const defaultLanguages = getLanguageList;
|
|
@@ -82,6 +91,14 @@ const files = (params) => {
|
|
|
82
91
|
return async (req, res) => {
|
|
83
92
|
let langs = (p.languages ?? defaultLanguages)(req);
|
|
84
93
|
let path = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
94
|
+
if (!matches(path, p.matches)) {
|
|
95
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
96
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
97
|
+
code: "unmatched_path",
|
|
98
|
+
path
|
|
99
|
+
}));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
85
102
|
if (path.includes("../")) {
|
|
86
103
|
emitLog(req.app, "Invalid path (potential traversal attempt)", { data: { path } });
|
|
87
104
|
res.status(400).send(await req.app.renderStatus?.(req, res, {
|
|
@@ -93,10 +110,12 @@ const files = (params) => {
|
|
|
93
110
|
let filePath = null;
|
|
94
111
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
95
112
|
let base = bases[k];
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
113
|
+
if (!path.endsWith("/")) {
|
|
114
|
+
for (let i = 0; i < langs.length && filePath === null; i++) filePath = await resolve(base, `${path}.${langs[i]}`);
|
|
115
|
+
if (filePath === null) filePath = await resolve(base, path);
|
|
116
|
+
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${path}.${langs[i]}.${exts[j]}`);
|
|
117
|
+
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, `${path}.${exts[i]}`);
|
|
118
|
+
}
|
|
100
119
|
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${path}.${langs[i]}`, `index.${exts[j]}`);
|
|
101
120
|
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, path, `index.${langs[i]}.${exts[j]}`);
|
|
102
121
|
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, path, `index.${exts[i]}`);
|
|
@@ -380,16 +399,17 @@ const entryClientPaths = [
|
|
|
380
399
|
/**
|
|
381
400
|
* Builds the client-side code.
|
|
382
401
|
*/
|
|
383
|
-
async function buildClient({
|
|
402
|
+
async function buildClient({ watch, watchClient }, plugins) {
|
|
384
403
|
let clientEntries = await getEntryPoints(entryClientPaths);
|
|
385
404
|
let buildOptions = {
|
|
386
405
|
...commonBuildOptions,
|
|
387
|
-
entryPoints: clientEntries.map(({ path }) =>
|
|
406
|
+
entryPoints: clientEntries.map(({ path, name }) => ({
|
|
407
|
+
in: path,
|
|
408
|
+
out: `src/entries/${name}/dist/index`
|
|
409
|
+
})),
|
|
388
410
|
bundle: true,
|
|
389
411
|
splitting: true,
|
|
390
412
|
format: "esm",
|
|
391
|
-
outdir: clientDir,
|
|
392
|
-
outbase: "src/entries",
|
|
393
413
|
minify: process.env.NODE_ENV !== "development",
|
|
394
414
|
plugins
|
|
395
415
|
};
|
|
@@ -410,19 +430,19 @@ function toImportPath(relativePath, referencePath = ".") {
|
|
|
410
430
|
return importPath;
|
|
411
431
|
}
|
|
412
432
|
|
|
413
|
-
async function
|
|
433
|
+
async function setEntriesExport({ entriesPath }) {
|
|
414
434
|
if (entriesPath === null) return;
|
|
415
435
|
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
416
436
|
let content = "";
|
|
417
437
|
if (serverEntries.length === 0) content = "export const entries = [];";
|
|
418
438
|
else {
|
|
419
439
|
content = "export const entries = (\n await Promise.all([";
|
|
420
|
-
for (let i = 0; i < serverEntries.length; i++) content += `\n
|
|
421
|
-
import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
440
|
+
for (let i = 0; i < serverEntries.length; i++) content += `\n import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
422
441
|
content += "\n ])\n).map(({ server }) => server);";
|
|
423
442
|
}
|
|
424
443
|
await (0, node_fs_promises.writeFile)(entriesPath ?? "src/server/entries.ts", `// Populated automatically during the build phase by picking
|
|
425
|
-
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
|
|
444
|
+
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)".
|
|
445
|
+
// Ignore this file if a custom set of entry exports is required.
|
|
426
446
|
${content}
|
|
427
447
|
`);
|
|
428
448
|
}
|
|
@@ -430,7 +450,7 @@ ${content}
|
|
|
430
450
|
const appServerEntryPoints = ["src/server/index.ts"];
|
|
431
451
|
async function buildServer(params, plugins) {
|
|
432
452
|
let { serverDir, watch, watchServer } = params;
|
|
433
|
-
await
|
|
453
|
+
await setEntriesExport(params);
|
|
434
454
|
let buildOptions = {
|
|
435
455
|
...commonBuildOptions,
|
|
436
456
|
entryPoints: appServerEntryPoints,
|
package/dist/index.d.ts
CHANGED
|
@@ -16,9 +16,11 @@ type TransformContent = (req: Request, res: Response, params: {
|
|
|
16
16
|
name?: string;
|
|
17
17
|
}) => string | Promise<string>;
|
|
18
18
|
|
|
19
|
+
type StringMatcher = string | RegExp | (string | RegExp)[] | ((x: string) => boolean) | null;
|
|
19
20
|
type FilesParams = {
|
|
20
21
|
base: string | string[];
|
|
21
|
-
path?: string | ((req: Request) => string);
|
|
22
|
+
path?: string | ((req: Request) => string); /** Specifies which paths should be accepted. */
|
|
23
|
+
matches?: StringMatcher;
|
|
22
24
|
extensions?: string[];
|
|
23
25
|
languages?: (req: Request) => string[];
|
|
24
26
|
transform?: TransformContent[];
|
package/dist/index.mjs
CHANGED
|
@@ -42,6 +42,15 @@ function getLanguageList(req) {
|
|
|
42
42
|
}
|
|
43
43
|
return Array.from(langs);
|
|
44
44
|
}
|
|
45
|
+
function matches(x, matcher) {
|
|
46
|
+
if (matcher === null || matcher === void 0) return true;
|
|
47
|
+
if (typeof matcher === "function") return matcher(x);
|
|
48
|
+
let patterns = Array.isArray(matcher) ? matcher : [matcher];
|
|
49
|
+
for (let pattern of patterns) if (pattern instanceof RegExp) {
|
|
50
|
+
if (pattern.test(x)) return true;
|
|
51
|
+
} else if (pattern === x) return true;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
45
54
|
const defaultExtensions = ["html", "htm"];
|
|
46
55
|
const defaultPath = (req) => req.originalUrl.split("?")[0];
|
|
47
56
|
const defaultLanguages = getLanguageList;
|
|
@@ -56,6 +65,14 @@ const files = (params) => {
|
|
|
56
65
|
return async (req, res) => {
|
|
57
66
|
let langs = (p.languages ?? defaultLanguages)(req);
|
|
58
67
|
let path = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
68
|
+
if (!matches(path, p.matches)) {
|
|
69
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
70
|
+
res.status(404).send(await req.app.renderStatus?.(req, res, {
|
|
71
|
+
code: "unmatched_path",
|
|
72
|
+
path
|
|
73
|
+
}));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
59
76
|
if (path.includes("../")) {
|
|
60
77
|
emitLog(req.app, "Invalid path (potential traversal attempt)", { data: { path } });
|
|
61
78
|
res.status(400).send(await req.app.renderStatus?.(req, res, {
|
|
@@ -67,10 +84,12 @@ const files = (params) => {
|
|
|
67
84
|
let filePath = null;
|
|
68
85
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
69
86
|
let base = bases[k];
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
if (!path.endsWith("/")) {
|
|
88
|
+
for (let i = 0; i < langs.length && filePath === null; i++) filePath = await resolve(base, `${path}.${langs[i]}`);
|
|
89
|
+
if (filePath === null) filePath = await resolve(base, path);
|
|
90
|
+
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${path}.${langs[i]}.${exts[j]}`);
|
|
91
|
+
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, `${path}.${exts[i]}`);
|
|
92
|
+
}
|
|
74
93
|
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${path}.${langs[i]}`, `index.${exts[j]}`);
|
|
75
94
|
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, path, `index.${langs[i]}.${exts[j]}`);
|
|
76
95
|
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, path, `index.${exts[i]}`);
|
|
@@ -354,16 +373,17 @@ const entryClientPaths = [
|
|
|
354
373
|
/**
|
|
355
374
|
* Builds the client-side code.
|
|
356
375
|
*/
|
|
357
|
-
async function buildClient({
|
|
376
|
+
async function buildClient({ watch, watchClient }, plugins) {
|
|
358
377
|
let clientEntries = await getEntryPoints(entryClientPaths);
|
|
359
378
|
let buildOptions = {
|
|
360
379
|
...commonBuildOptions,
|
|
361
|
-
entryPoints: clientEntries.map(({ path }) =>
|
|
380
|
+
entryPoints: clientEntries.map(({ path, name }) => ({
|
|
381
|
+
in: path,
|
|
382
|
+
out: `src/entries/${name}/dist/index`
|
|
383
|
+
})),
|
|
362
384
|
bundle: true,
|
|
363
385
|
splitting: true,
|
|
364
386
|
format: "esm",
|
|
365
|
-
outdir: clientDir,
|
|
366
|
-
outbase: "src/entries",
|
|
367
387
|
minify: process.env.NODE_ENV !== "development",
|
|
368
388
|
plugins
|
|
369
389
|
};
|
|
@@ -384,19 +404,19 @@ function toImportPath(relativePath, referencePath = ".") {
|
|
|
384
404
|
return importPath;
|
|
385
405
|
}
|
|
386
406
|
|
|
387
|
-
async function
|
|
407
|
+
async function setEntriesExport({ entriesPath }) {
|
|
388
408
|
if (entriesPath === null) return;
|
|
389
409
|
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
390
410
|
let content = "";
|
|
391
411
|
if (serverEntries.length === 0) content = "export const entries = [];";
|
|
392
412
|
else {
|
|
393
413
|
content = "export const entries = (\n await Promise.all([";
|
|
394
|
-
for (let i = 0; i < serverEntries.length; i++) content += `\n
|
|
395
|
-
import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
414
|
+
for (let i = 0; i < serverEntries.length; i++) content += `\n import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
396
415
|
content += "\n ])\n).map(({ server }) => server);";
|
|
397
416
|
}
|
|
398
417
|
await writeFile(entriesPath ?? "src/server/entries.ts", `// Populated automatically during the build phase by picking
|
|
399
|
-
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
|
|
418
|
+
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)".
|
|
419
|
+
// Ignore this file if a custom set of entry exports is required.
|
|
400
420
|
${content}
|
|
401
421
|
`);
|
|
402
422
|
}
|
|
@@ -404,7 +424,7 @@ ${content}
|
|
|
404
424
|
const appServerEntryPoints = ["src/server/index.ts"];
|
|
405
425
|
async function buildServer(params, plugins) {
|
|
406
426
|
let { serverDir, watch, watchServer } = params;
|
|
407
|
-
await
|
|
427
|
+
await setEntriesExport(params);
|
|
408
428
|
let buildOptions = {
|
|
409
429
|
...commonBuildOptions,
|
|
410
430
|
entryPoints: appServerEntryPoints,
|
package/package.json
CHANGED
package/src/controllers/files.ts
CHANGED
|
@@ -5,6 +5,13 @@ import type { Controller } from "../types/Controller.ts";
|
|
|
5
5
|
import type { TransformContent } from "../types/TransformContent.ts";
|
|
6
6
|
import { emitLog } from "../utils/emitLog.ts";
|
|
7
7
|
|
|
8
|
+
type StringMatcher =
|
|
9
|
+
| string
|
|
10
|
+
| RegExp
|
|
11
|
+
| (string | RegExp)[]
|
|
12
|
+
| ((x: string) => boolean)
|
|
13
|
+
| null;
|
|
14
|
+
|
|
8
15
|
const maxLanguages = 3;
|
|
9
16
|
|
|
10
17
|
async function resolve(...parts: string[]) {
|
|
@@ -38,9 +45,27 @@ function getLanguageList(req: Request) {
|
|
|
38
45
|
return Array.from(langs);
|
|
39
46
|
}
|
|
40
47
|
|
|
48
|
+
function matches(x: string, matcher: StringMatcher | undefined) {
|
|
49
|
+
if (matcher === null || matcher === undefined) return true;
|
|
50
|
+
|
|
51
|
+
if (typeof matcher === "function") return matcher(x);
|
|
52
|
+
|
|
53
|
+
let patterns = Array.isArray(matcher) ? matcher : [matcher];
|
|
54
|
+
|
|
55
|
+
for (let pattern of patterns) {
|
|
56
|
+
if (pattern instanceof RegExp) {
|
|
57
|
+
if (pattern.test(x)) return true;
|
|
58
|
+
} else if (pattern === x) return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
41
64
|
export type FilesParams = {
|
|
42
65
|
base: string | string[];
|
|
43
66
|
path?: string | ((req: Request) => string);
|
|
67
|
+
/** Specifies which paths should be accepted. */
|
|
68
|
+
matches?: StringMatcher;
|
|
44
69
|
extensions?: string[];
|
|
45
70
|
languages?: (req: Request) => string[];
|
|
46
71
|
transform?: TransformContent[];
|
|
@@ -66,6 +91,19 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
66
91
|
let path =
|
|
67
92
|
typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
68
93
|
|
|
94
|
+
if (!matches(path, p.matches)) {
|
|
95
|
+
emitLog(req.app, "Unmatched path", { data: { path } });
|
|
96
|
+
|
|
97
|
+
res.status(404).send(
|
|
98
|
+
await req.app.renderStatus?.(req, res, {
|
|
99
|
+
code: "unmatched_path",
|
|
100
|
+
path,
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
69
107
|
if (path.includes("../")) {
|
|
70
108
|
emitLog(req.app, "Invalid path (potential traversal attempt)", {
|
|
71
109
|
data: { path },
|
|
@@ -88,22 +126,24 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
88
126
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
89
127
|
let base = bases[k];
|
|
90
128
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
if (!path.endsWith("/")) {
|
|
130
|
+
// /x.en /x.ru
|
|
131
|
+
for (let i = 0; i < langs.length && filePath === null; i++)
|
|
132
|
+
filePath = await resolve(base, `${path}.${langs[i]}`);
|
|
94
133
|
|
|
95
|
-
|
|
96
|
-
|
|
134
|
+
// /x
|
|
135
|
+
if (filePath === null) filePath = await resolve(base, path);
|
|
97
136
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
137
|
+
// /x.en.html /x.en.htm /x.ru.html /x.ru.htm
|
|
138
|
+
for (let i = 0; i < langs.length && filePath === null; i++) {
|
|
139
|
+
for (let j = 0; j < exts.length && filePath === null; j++)
|
|
140
|
+
filePath = await resolve(base, `${path}.${langs[i]}.${exts[j]}`);
|
|
141
|
+
}
|
|
103
142
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
143
|
+
// /x.html /x.htm
|
|
144
|
+
for (let i = 0; i < exts.length && filePath === null; i++)
|
|
145
|
+
filePath = await resolve(base, `${path}.${exts[i]}`);
|
|
146
|
+
}
|
|
107
147
|
|
|
108
148
|
// /x.en/index.html /x.en/index.htm /x.ru/index.html /x.ru/index.htm
|
|
109
149
|
for (let i = 0; i < langs.length && filePath === null; i++) {
|
|
@@ -9,19 +9,20 @@ const entryClientPaths = ["ui/index", "client/index", "index", "src/index"];
|
|
|
9
9
|
* Builds the client-side code.
|
|
10
10
|
*/
|
|
11
11
|
export async function buildClient(
|
|
12
|
-
{
|
|
12
|
+
{ watch, watchClient }: BuildParams,
|
|
13
13
|
plugins?: Plugin[],
|
|
14
14
|
) {
|
|
15
15
|
let clientEntries = await getEntryPoints(entryClientPaths);
|
|
16
16
|
|
|
17
17
|
let buildOptions: BuildOptions = {
|
|
18
18
|
...commonBuildOptions,
|
|
19
|
-
entryPoints: clientEntries.map(({ path }) =>
|
|
19
|
+
entryPoints: clientEntries.map(({ path, name }) => ({
|
|
20
|
+
in: path,
|
|
21
|
+
out: `src/entries/${name}/dist/index`,
|
|
22
|
+
})),
|
|
20
23
|
bundle: true,
|
|
21
24
|
splitting: true,
|
|
22
25
|
format: "esm",
|
|
23
|
-
outdir: clientDir,
|
|
24
|
-
outbase: "src/entries",
|
|
25
26
|
minify: process.env.NODE_ENV !== "development",
|
|
26
27
|
plugins,
|
|
27
28
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import esbuild, { type BuildOptions, type Plugin } from "esbuild";
|
|
2
2
|
import { commonBuildOptions } from "../const/commonBuildOptions.ts";
|
|
3
3
|
import type { BuildParams } from "../types/BuildParams.ts";
|
|
4
|
-
import {
|
|
4
|
+
import { setEntriesExport } from "./setEntriesExport.ts";
|
|
5
5
|
|
|
6
6
|
const appServerEntryPoints = ["src/server/index.ts"];
|
|
7
7
|
|
|
8
8
|
export async function buildServer(params: BuildParams, plugins?: Plugin[]) {
|
|
9
9
|
let { serverDir, watch, watchServer } = params;
|
|
10
10
|
|
|
11
|
-
await
|
|
11
|
+
await setEntriesExport(params);
|
|
12
12
|
|
|
13
13
|
let buildOptions: BuildOptions = {
|
|
14
14
|
...commonBuildOptions,
|
|
@@ -3,7 +3,7 @@ import type { BuildParams } from "../types/BuildParams.ts";
|
|
|
3
3
|
import { getEntryPoints } from "./getEntryPoints.ts";
|
|
4
4
|
import { toImportPath } from "./toImportPath.ts";
|
|
5
5
|
|
|
6
|
-
export async function
|
|
6
|
+
export async function setEntriesExport({ entriesPath }: BuildParams) {
|
|
7
7
|
if (entriesPath === null) return;
|
|
8
8
|
|
|
9
9
|
let serverEntries = await getEntryPoints(["server", "server/index"]);
|
|
@@ -13,10 +13,8 @@ export async function populateEntries({ entriesPath }: BuildParams) {
|
|
|
13
13
|
else {
|
|
14
14
|
content = "export const entries = (\n await Promise.all([";
|
|
15
15
|
|
|
16
|
-
for (let i = 0; i < serverEntries.length; i++)
|
|
17
|
-
content += `\n
|
|
18
|
-
import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
19
|
-
}
|
|
16
|
+
for (let i = 0; i < serverEntries.length; i++)
|
|
17
|
+
content += `\n import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
|
|
20
18
|
|
|
21
19
|
content += "\n ])\n).map(({ server }) => server);";
|
|
22
20
|
}
|
|
@@ -24,7 +22,8 @@ export async function populateEntries({ entriesPath }: BuildParams) {
|
|
|
24
22
|
await writeFile(
|
|
25
23
|
entriesPath ?? "src/server/entries.ts",
|
|
26
24
|
`// Populated automatically during the build phase by picking
|
|
27
|
-
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
|
|
25
|
+
// all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)".
|
|
26
|
+
// Ignore this file if a custom set of entry exports is required.
|
|
28
27
|
${content}
|
|
29
28
|
`,
|
|
30
29
|
);
|