appstage 0.2.4 → 0.2.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/dist/bin.js CHANGED
@@ -25,8 +25,146 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  mod
26
26
  ));
27
27
 
28
- // node_modules/dateshape/dist/index.cjs
28
+ // node_modules/args-json/dist/index.cjs
29
29
  var require_dist = __commonJS({
30
+ "node_modules/args-json/dist/index.cjs"(exports) {
31
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
32
+ function isKey2(x) {
33
+ return x.startsWith("-") && x.length === 2 && x !== "--" || x.startsWith("--") && x.length > 2;
34
+ }
35
+ var Args2 = class {
36
+ _values;
37
+ constructor(values) {
38
+ this._values = values ?? process.argv.slice(2);
39
+ }
40
+ hasKey(x) {
41
+ return isKey2(x) && this._values.includes(x);
42
+ }
43
+ getValue(key, fallback) {
44
+ let args = this._values;
45
+ let keys = Array.isArray(key) ? key : [key];
46
+ for (let k of keys) {
47
+ let i = args.indexOf(k);
48
+ if (i !== -1 && args[i + 1] && !isKey2(args[i + 1])) return args[i + 1];
49
+ }
50
+ return fallback;
51
+ }
52
+ getValues(key, fallback) {
53
+ let args = this._values;
54
+ let keys = Array.isArray(key) ? key : [key];
55
+ let values = [];
56
+ for (let k of keys) {
57
+ let i = args.indexOf(k);
58
+ while (i !== -1 && args[i + 1] && !isKey2(args[i + 1])) values.push(args[++i]);
59
+ }
60
+ return values.length === 0 ? fallback : values;
61
+ }
62
+ };
63
+ function getValue(key, fallback) {
64
+ let args = new Args2();
65
+ if (fallback === void 0) return args.getValue(key);
66
+ return args.getValue(key, fallback);
67
+ }
68
+ function getValues(key, fallback) {
69
+ let args = new Args2();
70
+ if (fallback === void 0) return args.getValues(key);
71
+ return args.getValues(key, fallback);
72
+ }
73
+ function hasKey2(x) {
74
+ return new Args2().hasKey(x);
75
+ }
76
+ function split(x) {
77
+ let words = [], word = "";
78
+ let hasOpenSingleQuote = false;
79
+ let hasOpenDoubleQuote = false;
80
+ for (let i = 0; i < x.length; i++) {
81
+ let c = x[i];
82
+ if (/^\s/.test(c) && !hasOpenSingleQuote && !hasOpenDoubleQuote) {
83
+ if (word) words.push(word);
84
+ word = "";
85
+ continue;
86
+ }
87
+ if (c === "'" && x[i - 1] !== "\\") hasOpenSingleQuote = !hasOpenSingleQuote;
88
+ if (c === '"' && x[i - 1] !== "\\") hasOpenDoubleQuote = !hasOpenDoubleQuote;
89
+ word += c;
90
+ }
91
+ if (word) words.push(word);
92
+ return words;
93
+ }
94
+ function toCamelCase(x) {
95
+ let s = x.replace(/^[-_.\s~+]|[-_.\s~+]$/g, "");
96
+ if (!/[-_.\s~+]/.test(s)) return s.slice(0, 1).toLowerCase() + s.slice(1);
97
+ return s.toLowerCase().replace(/[-_.\s~+](\S)/g, (_, match) => match.toUpperCase());
98
+ }
99
+ function toKey(x) {
100
+ if (x === void 0 || !isKey2(x)) return;
101
+ if (x.startsWith("-") && x.length === 2) return toCamelCase(x.slice(1));
102
+ if (x.startsWith("--") && x.length > 2) return toCamelCase(x.slice(2));
103
+ }
104
+ function getDefaultInput() {
105
+ return typeof process === "undefined" ? [] : process.argv;
106
+ }
107
+ function parseArgs(input, map) {
108
+ let normalizedInput;
109
+ let normalizedMap;
110
+ if (input === void 0) normalizedInput = getDefaultInput();
111
+ else if (typeof input === "string") normalizedInput = split(input);
112
+ else if (Array.isArray(input)) normalizedInput = input.map((x) => String(x));
113
+ else if (input !== null && typeof input === "object") {
114
+ normalizedInput = getDefaultInput();
115
+ normalizedMap = input;
116
+ } else normalizedInput = [];
117
+ normalizedInput = normalizedInput.flatMap((item) => {
118
+ let normalizedItem = item.trim();
119
+ let k = normalizedItem.indexOf("=");
120
+ if (k === -1) return normalizedItem;
121
+ let key2 = normalizedItem.slice(0, k);
122
+ let value = normalizedItem.slice(k + 1);
123
+ if (!isKey2(key2)) return normalizedItem;
124
+ return [key2, value];
125
+ });
126
+ if (map) normalizedMap = map;
127
+ let key = "";
128
+ let parsedArgs = {};
129
+ for (let rawValue of normalizedInput) {
130
+ rawValue = rawValue.trim();
131
+ if (rawValue.startsWith('"') && rawValue.endsWith('"')) rawValue = rawValue.slice(1, -1);
132
+ else if (rawValue.startsWith("'") && rawValue.endsWith("'")) rawValue = rawValue.slice(1, -1);
133
+ let parsedKey = toKey(rawValue);
134
+ if (parsedKey !== void 0) {
135
+ let nextKey = normalizedMap?.[parsedKey] ?? parsedKey;
136
+ if (key && nextKey !== key && parsedArgs[key] === void 0) parsedArgs[key] = true;
137
+ key = nextKey;
138
+ continue;
139
+ }
140
+ let parsedValue;
141
+ if (rawValue) try {
142
+ parsedValue = JSON.parse(rawValue);
143
+ } catch {
144
+ parsedValue = rawValue;
145
+ }
146
+ else parsedValue = true;
147
+ let prevValue = parsedArgs[key];
148
+ let value;
149
+ if (prevValue === void 0) value = key === "" ? [parsedValue] : parsedValue;
150
+ else if (Array.isArray(prevValue)) value = [...prevValue, parsedValue];
151
+ else value = [prevValue, parsedValue];
152
+ parsedArgs[key] = value;
153
+ }
154
+ if (key && parsedArgs[key] === void 0) parsedArgs[key] = true;
155
+ return parsedArgs;
156
+ }
157
+ exports.Args = Args2;
158
+ exports.getValue = getValue;
159
+ exports.getValues = getValues;
160
+ exports.hasKey = hasKey2;
161
+ exports.isKey = isKey2;
162
+ exports.parseArgs = parseArgs;
163
+ }
164
+ });
165
+
166
+ // node_modules/dateshape/dist/index.cjs
167
+ var require_dist2 = __commonJS({
30
168
  "node_modules/dateshape/dist/index.cjs"(exports) {
31
169
  var SEC = 1e3;
32
170
  var MIN = 60 * SEC;
@@ -215,11 +353,15 @@ var require_dist = __commonJS({
215
353
  }
216
354
  });
217
355
 
356
+ // src/scripts/bin.ts
357
+ var import_args_json2 = __toESM(require_dist(), 1);
358
+
218
359
  // src/scripts/cli.ts
360
+ var import_args_json = __toESM(require_dist(), 1);
219
361
  import { rm as rm2 } from "node:fs/promises";
220
362
 
221
363
  // src/scripts/build.ts
222
- var import_dateshape = __toESM(require_dist(), 1);
364
+ var import_dateshape = __toESM(require_dist2(), 1);
223
365
  import { spawn } from "node:child_process";
224
366
 
225
367
  // src/scripts/utils/buildClient.ts
@@ -291,7 +433,7 @@ async function getEntryPoints(path) {
291
433
  }
292
434
 
293
435
  // src/scripts/utils/buildClient.ts
294
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
436
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
295
437
  let clientEntries = await getEntryPoints(["ui/index"]);
296
438
  let buildOptions = {
297
439
  ...commonBuildOptions,
@@ -299,7 +441,7 @@ async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
299
441
  bundle: true,
300
442
  splitting: true,
301
443
  format: "esm",
302
- outdir: `${publicAssetsDir}/-`,
444
+ outdir: clientDir,
303
445
  outbase: "src/entries",
304
446
  minify: process.env.NODE_ENV !== "development",
305
447
  plugins
@@ -332,7 +474,8 @@ function toImportPath(relativePath, referencePath = ".") {
332
474
  }
333
475
 
334
476
  // src/scripts/utils/populateEntries.ts
335
- async function populateEntries() {
477
+ async function populateEntries({ entriesPath }) {
478
+ if (entriesPath === null) return;
336
479
  let serverEntries = await getEntryPoints(["server", "server/index"]);
337
480
  let content = "";
338
481
  if (serverEntries.length === 0) content = "export const entries = [];";
@@ -346,7 +489,7 @@ async function populateEntries() {
346
489
  content += "\n ])\n).map(({ server }) => server);";
347
490
  }
348
491
  await writeFile(
349
- "src/server/autoentries.ts",
492
+ entriesPath ?? "src/server/entries.ts",
350
493
  `// Populated automatically during the build phase by picking
351
494
  // all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
352
495
  ${content}
@@ -355,14 +498,15 @@ ${content}
355
498
  }
356
499
 
357
500
  // src/scripts/utils/buildServer.ts
358
- async function buildServer({ targetDir, watch, watchServer }, plugins) {
359
- await populateEntries();
501
+ async function buildServer(params, plugins) {
502
+ let { serverDir, watch, watchServer } = params;
503
+ await populateEntries(params);
360
504
  let buildOptions = {
361
505
  ...commonBuildOptions,
362
506
  entryPoints: ["src/server/index.ts"],
363
507
  bundle: true,
364
508
  splitting: true,
365
- outdir: `${targetDir}/server`,
509
+ outdir: `${serverDir}/server`,
366
510
  platform: "node",
367
511
  format: "esm",
368
512
  packages: "external",
@@ -380,7 +524,7 @@ async function buildServer({ targetDir, watch, watchServer }, plugins) {
380
524
 
381
525
  // src/scripts/utils/buildServerCSS.ts
382
526
  import esbuild3 from "esbuild";
383
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
527
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
384
528
  let serverEntries = await getEntryPoints(["server", "server/index"]);
385
529
  let buildOptions = {
386
530
  ...commonBuildOptions,
@@ -390,7 +534,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
390
534
  })),
391
535
  bundle: true,
392
536
  splitting: false,
393
- outdir: `${targetDir}/server-css`,
537
+ outdir: `${serverDir}/server-css`,
394
538
  platform: "node",
395
539
  format: "esm",
396
540
  packages: "external",
@@ -408,7 +552,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
408
552
 
409
553
  // src/scripts/utils/createPostbuildPlugins.ts
410
554
  import { mkdir, readdir as readdir2, rename, rm } from "node:fs/promises";
411
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
555
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
412
556
  let serverPlugins = [
413
557
  {
414
558
  name: "skip-css",
@@ -430,19 +574,19 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
430
574
  name: "postbuild-server-css",
431
575
  setup(build2) {
432
576
  build2.onEnd(async () => {
433
- let dir = `${targetDir}/server-css`;
577
+ let dir = `${serverDir}/server-css`;
434
578
  try {
435
579
  let files = (await readdir2(dir)).filter(
436
580
  (name) => name.endsWith(".css")
437
581
  );
438
582
  if (files.length === 0) return;
439
- await mkdir(`${publicAssetsDir}/-`, { recursive: true });
583
+ await mkdir(clientDir, { recursive: true });
440
584
  await Promise.all(
441
585
  files.map(async (name) => {
442
- let dir2 = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
586
+ let dir2 = `${clientDir}/${name.slice(0, -4)}`;
443
587
  await mkdir(dir2, { recursive: true });
444
588
  await rename(
445
- `${targetDir}/server-css/${name}`,
589
+ `${serverDir}/server-css/${name}`,
446
590
  `${dir2}/index.css`
447
591
  );
448
592
  })
@@ -478,7 +622,7 @@ async function build(params) {
478
622
  inited = true;
479
623
  }
480
624
  if (params.start)
481
- serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], {
625
+ serverProcess = spawn("node", [`${params.serverDir}/server/index.js`], {
482
626
  stdio: "inherit"
483
627
  });
484
628
  }
@@ -494,37 +638,32 @@ async function build(params) {
494
638
  }
495
639
 
496
640
  // 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
- ];
641
+ async function clean({ serverDir, clientDir }) {
642
+ let dirs = [`${serverDir}/server`, `${serverDir}/server-css`, clientDir];
504
643
  return Promise.all(
505
644
  dirs.map((dir) => rm2(dir, { recursive: true, force: true }))
506
645
  );
507
646
  }
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;
647
+ async function cli(input = []) {
648
+ let args = new import_args_json.Args(input);
649
+ let clientDir = args.getValue("--client-dir");
650
+ let serverDir = args.getValue("--server-dir", "dist");
651
+ if (!clientDir) throw new Error("Public assets directory is undefined");
514
652
  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")
653
+ serverDir,
654
+ clientDir,
655
+ silent: args.hasKey("--silent"),
656
+ watch: args.hasKey("--watch"),
657
+ watchServer: args.hasKey("--watch-server"),
658
+ watchClient: args.hasKey("--watch-client"),
659
+ start: args.hasKey("--start")
522
660
  };
523
- if (args.includes("--clean-only")) {
661
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
662
+ if (args.hasKey("--clean-only")) {
524
663
  await clean(params);
525
664
  return;
526
665
  }
527
- if (args.includes("--clean")) await clean(params);
666
+ if (args.hasKey("--clean")) await clean(params);
528
667
  await build(params);
529
668
  }
530
669
 
@@ -542,15 +681,16 @@ async function run() {
542
681
  }
543
682
  if (scriptName === "build") return await cli(args);
544
683
  let nodeEnv = nodeEnvMap[scriptName];
545
- let host = args[0];
546
684
  if (nodeEnv !== void 0) process.env.NODE_ENV = nodeEnv;
547
- if (host) {
548
- let [hostname, port] = host.split(":");
685
+ if (args.length !== 0 && !(0, import_args_json2.isKey)(args[0])) {
686
+ let [hostname, port] = args[0].split(":");
549
687
  if (hostname) process.env.APP_HOST = hostname;
550
688
  if (port) process.env.APP_PORT = port;
689
+ args.shift();
551
690
  }
691
+ if (!(0, import_args_json2.hasKey)("--client-dir")) args.push("--client-dir", "src/public/-");
552
692
  await cli(
553
- nodeEnv === "development" ? ["src/public", "--clean", "--start", "--watch"] : ["src/public", "--clean", "--start", "--silent"]
693
+ nodeEnv === "development" ? ["--clean", "--start", "--watch", ...args] : ["--clean", "--start", "--silent", ...args]
554
694
  );
555
695
  }
556
696
  await run();
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
 
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -7,16 +7,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
- key = keys[i];
13
- if (!__hasOwnProp.call(to, key) && key !== except) {
14
- __defProp(to, key, {
15
- get: ((k) => from[k]).bind(null, key),
16
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
- });
18
- }
19
- }
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
20
16
  }
21
17
  return to;
22
18
  };
@@ -33,6 +29,7 @@ let node_http = require("node:http");
33
29
  let node_child_process = require("node:child_process");
34
30
  let esbuild = require("esbuild");
35
31
  esbuild = __toESM(esbuild);
32
+ let args_json = require("args-json");
36
33
  let node_events = require("node:events");
37
34
  node_events = __toESM(node_events);
38
35
  let express = require("express");
@@ -372,7 +369,7 @@ async function getEntryPoints(path) {
372
369
  * than client since their contents can also be used with the server-side
373
370
  * rendering.
374
371
  */
375
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
372
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
376
373
  let clientEntries = await getEntryPoints(["ui/index"]);
377
374
  let buildOptions = {
378
375
  ...commonBuildOptions,
@@ -380,7 +377,7 @@ async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
380
377
  bundle: true,
381
378
  splitting: true,
382
379
  format: "esm",
383
- outdir: `${publicAssetsDir}/-`,
380
+ outdir: clientDir,
384
381
  outbase: "src/entries",
385
382
  minify: process.env.NODE_ENV !== "development",
386
383
  plugins
@@ -402,7 +399,8 @@ function toImportPath(relativePath, referencePath = ".") {
402
399
  return importPath;
403
400
  }
404
401
 
405
- async function populateEntries() {
402
+ async function populateEntries({ entriesPath }) {
403
+ if (entriesPath === null) return;
406
404
  let serverEntries = await getEntryPoints(["server", "server/index"]);
407
405
  let content = "";
408
406
  if (serverEntries.length === 0) content = "export const entries = [];";
@@ -412,20 +410,21 @@ async function populateEntries() {
412
410
  import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
413
411
  content += "\n ])\n).map(({ server }) => server);";
414
412
  }
415
- await (0, node_fs_promises.writeFile)("src/server/autoentries.ts", `// Populated automatically during the build phase by picking
413
+ await (0, node_fs_promises.writeFile)(entriesPath ?? "src/server/entries.ts", `// Populated automatically during the build phase by picking
416
414
  // all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
417
415
  ${content}
418
416
  `);
419
417
  }
420
418
 
421
- async function buildServer({ targetDir, watch, watchServer }, plugins) {
422
- await populateEntries();
419
+ async function buildServer(params, plugins) {
420
+ let { serverDir, watch, watchServer } = params;
421
+ await populateEntries(params);
423
422
  let buildOptions = {
424
423
  ...commonBuildOptions,
425
424
  entryPoints: ["src/server/index.ts"],
426
425
  bundle: true,
427
426
  splitting: true,
428
- outdir: `${targetDir}/server`,
427
+ outdir: `${serverDir}/server`,
429
428
  platform: "node",
430
429
  format: "esm",
431
430
  packages: "external",
@@ -441,7 +440,7 @@ async function buildServer({ targetDir, watch, watchServer }, plugins) {
441
440
  await esbuild.default.build(buildOptions);
442
441
  }
443
442
 
444
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
443
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
445
444
  let serverEntries = await getEntryPoints(["server", "server/index"]);
446
445
  let buildOptions = {
447
446
  ...commonBuildOptions,
@@ -451,7 +450,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
451
450
  })),
452
451
  bundle: true,
453
452
  splitting: false,
454
- outdir: `${targetDir}/server-css`,
453
+ outdir: `${serverDir}/server-css`,
455
454
  platform: "node",
456
455
  format: "esm",
457
456
  packages: "external",
@@ -467,7 +466,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
467
466
  await esbuild.default.build(buildOptions);
468
467
  }
469
468
 
470
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
469
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
471
470
  return {
472
471
  serverPlugins: [{
473
472
  name: "skip-css",
@@ -487,15 +486,15 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
487
486
  name: "postbuild-server-css",
488
487
  setup(build) {
489
488
  build.onEnd(async () => {
490
- let dir = `${targetDir}/server-css`;
489
+ let dir = `${serverDir}/server-css`;
491
490
  try {
492
491
  let files = (await (0, node_fs_promises.readdir)(dir)).filter((name) => name.endsWith(".css"));
493
492
  if (files.length === 0) return;
494
- await (0, node_fs_promises.mkdir)(`${publicAssetsDir}/-`, { recursive: true });
493
+ await (0, node_fs_promises.mkdir)(clientDir, { recursive: true });
495
494
  await Promise.all(files.map(async (name) => {
496
- let dir = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
495
+ let dir = `${clientDir}/${name.slice(0, -4)}`;
497
496
  await (0, node_fs_promises.mkdir)(dir, { recursive: true });
498
- await (0, node_fs_promises.rename)(`${targetDir}/server-css/${name}`, `${dir}/index.css`);
497
+ await (0, node_fs_promises.rename)(`${serverDir}/server-css/${name}`, `${dir}/index.css`);
499
498
  }));
500
499
  await (0, node_fs_promises.rm)(dir, {
501
500
  recursive: true,
@@ -523,7 +522,7 @@ async function build(params) {
523
522
  log(`Build completed +${(0, dateshape.formatDuration)(Date.now() - startTime)}`);
524
523
  inited = true;
525
524
  }
526
- if (params.start) serverProcess = (0, node_child_process.spawn)("node", [`${params.targetDir}/server/index.js`], { stdio: "inherit" });
525
+ if (params.start) serverProcess = (0, node_child_process.spawn)("node", [`${params.serverDir}/server/index.js`], { stdio: "inherit" });
527
526
  }
528
527
  let { serverPlugins, serverCSSPlugins } = createPostbuildPlugins(params, handleServerRebuild);
529
528
  await Promise.all([
@@ -533,37 +532,37 @@ async function build(params) {
533
532
  ]);
534
533
  }
535
534
 
536
- const defaultTargetDir = "dist";
537
- async function clean({ targetDir, publicAssetsDir }) {
535
+ async function clean({ serverDir, clientDir }) {
538
536
  let dirs = [
539
- `${targetDir}/server`,
540
- `${targetDir}/server-css`,
541
- `${publicAssetsDir}/-`
537
+ `${serverDir}/server`,
538
+ `${serverDir}/server-css`,
539
+ clientDir
542
540
  ];
543
541
  return Promise.all(dirs.map((dir) => (0, node_fs_promises.rm)(dir, {
544
542
  recursive: true,
545
543
  force: true
546
544
  })));
547
545
  }
548
- async function cli(args = []) {
549
- let publicAssetsDir = args[0];
550
- let targetDir = args[1];
551
- if (!publicAssetsDir || publicAssetsDir.startsWith("--")) throw new Error("Public assets directory is undefined");
552
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
546
+ async function cli(input = []) {
547
+ let args = new args_json.Args(input);
548
+ let clientDir = args.getValue("--client-dir");
549
+ let serverDir = args.getValue("--server-dir", "dist");
550
+ if (!clientDir) throw new Error("Public assets directory is undefined");
553
551
  let params = {
554
- targetDir,
555
- publicAssetsDir,
556
- silent: args.includes("--silent"),
557
- watch: args.includes("--watch"),
558
- watchServer: args.includes("--watch-server"),
559
- watchClient: args.includes("--watch-client"),
560
- start: args.includes("--start")
552
+ serverDir,
553
+ clientDir,
554
+ silent: args.hasKey("--silent"),
555
+ watch: args.hasKey("--watch"),
556
+ watchServer: args.hasKey("--watch-server"),
557
+ watchClient: args.hasKey("--watch-client"),
558
+ start: args.hasKey("--start")
561
559
  };
562
- if (args.includes("--clean-only")) {
560
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
561
+ if (args.hasKey("--clean-only")) {
563
562
  await clean(params);
564
563
  return;
565
564
  }
566
- if (args.includes("--clean")) await clean(params);
565
+ if (args.hasKey("--clean")) await clean(params);
567
566
  await build(params);
568
567
  }
569
568
 
@@ -578,7 +577,7 @@ function createApp(callback) {
578
577
  let app = (0, express.default)();
579
578
  if (!app.events) app.events = new node_events.default();
580
579
  let host = process.env.APP_HOST || "localhost";
581
- let port = Number(process.env.APP_PORT) || 80;
580
+ let port = Number(process.env.APP_PORT) || 3e3;
582
581
  let listen = () => {
583
582
  app.listen(port, host, () => {
584
583
  emitLog(app, `Server running at ${`http://${host}:${port}/`} (${`NODE_ENV=${process.env.NODE_ENV}`})`);
package/dist/index.d.ts CHANGED
@@ -131,18 +131,27 @@ declare const lang$1: Middleware<LangParams | void>;
131
131
  declare const requestEvents: Middleware;
132
132
 
133
133
  type BuildParams = {
134
- targetDir: string;
135
- publicAssetsDir: string;
134
+ serverDir: string;
135
+ clientDir: string;
136
136
  silent?: boolean;
137
137
  watch?: boolean;
138
138
  watchClient?: boolean;
139
139
  watchServer?: boolean;
140
140
  start?: boolean;
141
+ /**
142
+ * A file path that the automatically picked entry exports will be
143
+ * written to.
144
+ *
145
+ * Set it to `null` to skip the automatic picking of entry exports.
146
+ *
147
+ * @default "src/server/entries.ts"
148
+ */
149
+ entriesPath?: string | null;
141
150
  };
142
151
 
143
152
  declare function build(params: BuildParams): Promise<void>;
144
153
 
145
- declare function cli(args?: string[]): Promise<void>;
154
+ declare function cli(input?: string[]): Promise<void>;
146
155
 
147
156
  type LogLevel = "error" | "debug" | "info" | "warn";
148
157
 
package/dist/index.mjs CHANGED
@@ -5,6 +5,7 @@ import { randomBytes } from "node:crypto";
5
5
  import { STATUS_CODES } from "node:http";
6
6
  import { spawn } from "node:child_process";
7
7
  import esbuild from "esbuild";
8
+ import { Args } from "args-json";
8
9
  import EventEmitter from "node:events";
9
10
  import express from "express";
10
11
 
@@ -342,7 +343,7 @@ async function getEntryPoints(path) {
342
343
  * than client since their contents can also be used with the server-side
343
344
  * rendering.
344
345
  */
345
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
346
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
346
347
  let clientEntries = await getEntryPoints(["ui/index"]);
347
348
  let buildOptions = {
348
349
  ...commonBuildOptions,
@@ -350,7 +351,7 @@ async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
350
351
  bundle: true,
351
352
  splitting: true,
352
353
  format: "esm",
353
- outdir: `${publicAssetsDir}/-`,
354
+ outdir: clientDir,
354
355
  outbase: "src/entries",
355
356
  minify: process.env.NODE_ENV !== "development",
356
357
  plugins
@@ -372,7 +373,8 @@ function toImportPath(relativePath, referencePath = ".") {
372
373
  return importPath;
373
374
  }
374
375
 
375
- async function populateEntries() {
376
+ async function populateEntries({ entriesPath }) {
377
+ if (entriesPath === null) return;
376
378
  let serverEntries = await getEntryPoints(["server", "server/index"]);
377
379
  let content = "";
378
380
  if (serverEntries.length === 0) content = "export const entries = [];";
@@ -382,20 +384,21 @@ async function populateEntries() {
382
384
  import("${toImportPath(serverEntries[i].path, "src/server")}"),`;
383
385
  content += "\n ])\n).map(({ server }) => server);";
384
386
  }
385
- await writeFile("src/server/autoentries.ts", `// Populated automatically during the build phase by picking
387
+ await writeFile(entriesPath ?? "src/server/entries.ts", `// Populated automatically during the build phase by picking
386
388
  // all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
387
389
  ${content}
388
390
  `);
389
391
  }
390
392
 
391
- async function buildServer({ targetDir, watch, watchServer }, plugins) {
392
- await populateEntries();
393
+ async function buildServer(params, plugins) {
394
+ let { serverDir, watch, watchServer } = params;
395
+ await populateEntries(params);
393
396
  let buildOptions = {
394
397
  ...commonBuildOptions,
395
398
  entryPoints: ["src/server/index.ts"],
396
399
  bundle: true,
397
400
  splitting: true,
398
- outdir: `${targetDir}/server`,
401
+ outdir: `${serverDir}/server`,
399
402
  platform: "node",
400
403
  format: "esm",
401
404
  packages: "external",
@@ -411,7 +414,7 @@ async function buildServer({ targetDir, watch, watchServer }, plugins) {
411
414
  await esbuild.build(buildOptions);
412
415
  }
413
416
 
414
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
417
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
415
418
  let serverEntries = await getEntryPoints(["server", "server/index"]);
416
419
  let buildOptions = {
417
420
  ...commonBuildOptions,
@@ -421,7 +424,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
421
424
  })),
422
425
  bundle: true,
423
426
  splitting: false,
424
- outdir: `${targetDir}/server-css`,
427
+ outdir: `${serverDir}/server-css`,
425
428
  platform: "node",
426
429
  format: "esm",
427
430
  packages: "external",
@@ -437,7 +440,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
437
440
  await esbuild.build(buildOptions);
438
441
  }
439
442
 
440
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
443
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
441
444
  return {
442
445
  serverPlugins: [{
443
446
  name: "skip-css",
@@ -457,15 +460,15 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
457
460
  name: "postbuild-server-css",
458
461
  setup(build) {
459
462
  build.onEnd(async () => {
460
- let dir = `${targetDir}/server-css`;
463
+ let dir = `${serverDir}/server-css`;
461
464
  try {
462
465
  let files = (await readdir(dir)).filter((name) => name.endsWith(".css"));
463
466
  if (files.length === 0) return;
464
- await mkdir(`${publicAssetsDir}/-`, { recursive: true });
467
+ await mkdir(clientDir, { recursive: true });
465
468
  await Promise.all(files.map(async (name) => {
466
- let dir = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
469
+ let dir = `${clientDir}/${name.slice(0, -4)}`;
467
470
  await mkdir(dir, { recursive: true });
468
- await rename(`${targetDir}/server-css/${name}`, `${dir}/index.css`);
471
+ await rename(`${serverDir}/server-css/${name}`, `${dir}/index.css`);
469
472
  }));
470
473
  await rm(dir, {
471
474
  recursive: true,
@@ -493,7 +496,7 @@ async function build(params) {
493
496
  log(`Build completed +${formatDuration(Date.now() - startTime)}`);
494
497
  inited = true;
495
498
  }
496
- if (params.start) serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], { stdio: "inherit" });
499
+ if (params.start) serverProcess = spawn("node", [`${params.serverDir}/server/index.js`], { stdio: "inherit" });
497
500
  }
498
501
  let { serverPlugins, serverCSSPlugins } = createPostbuildPlugins(params, handleServerRebuild);
499
502
  await Promise.all([
@@ -503,37 +506,37 @@ async function build(params) {
503
506
  ]);
504
507
  }
505
508
 
506
- const defaultTargetDir = "dist";
507
- async function clean({ targetDir, publicAssetsDir }) {
509
+ async function clean({ serverDir, clientDir }) {
508
510
  let dirs = [
509
- `${targetDir}/server`,
510
- `${targetDir}/server-css`,
511
- `${publicAssetsDir}/-`
511
+ `${serverDir}/server`,
512
+ `${serverDir}/server-css`,
513
+ clientDir
512
514
  ];
513
515
  return Promise.all(dirs.map((dir) => rm(dir, {
514
516
  recursive: true,
515
517
  force: true
516
518
  })));
517
519
  }
518
- async function cli(args = []) {
519
- let publicAssetsDir = args[0];
520
- let targetDir = args[1];
521
- if (!publicAssetsDir || publicAssetsDir.startsWith("--")) throw new Error("Public assets directory is undefined");
522
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
520
+ async function cli(input = []) {
521
+ let args = new Args(input);
522
+ let clientDir = args.getValue("--client-dir");
523
+ let serverDir = args.getValue("--server-dir", "dist");
524
+ if (!clientDir) throw new Error("Public assets directory is undefined");
523
525
  let params = {
524
- targetDir,
525
- publicAssetsDir,
526
- silent: args.includes("--silent"),
527
- watch: args.includes("--watch"),
528
- watchServer: args.includes("--watch-server"),
529
- watchClient: args.includes("--watch-client"),
530
- start: args.includes("--start")
526
+ serverDir,
527
+ clientDir,
528
+ silent: args.hasKey("--silent"),
529
+ watch: args.hasKey("--watch"),
530
+ watchServer: args.hasKey("--watch-server"),
531
+ watchClient: args.hasKey("--watch-client"),
532
+ start: args.hasKey("--start")
531
533
  };
532
- if (args.includes("--clean-only")) {
534
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
535
+ if (args.hasKey("--clean-only")) {
533
536
  await clean(params);
534
537
  return;
535
538
  }
536
- if (args.includes("--clean")) await clean(params);
539
+ if (args.hasKey("--clean")) await clean(params);
537
540
  await build(params);
538
541
  }
539
542
 
@@ -548,7 +551,7 @@ function createApp(callback) {
548
551
  let app = express();
549
552
  if (!app.events) app.events = new EventEmitter();
550
553
  let host = process.env.APP_HOST || "localhost";
551
- let port = Number(process.env.APP_PORT) || 80;
554
+ let port = Number(process.env.APP_PORT) || 3e3;
552
555
  let listen = () => {
553
556
  app.listen(port, host, () => {
554
557
  emitLog(app, `Server running at ${`http://${host}:${port}/`} (${`NODE_ENV=${process.env.NODE_ENV}`})`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appstage",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -29,7 +29,8 @@
29
29
  "@types/node": "^25.4.0"
30
30
  },
31
31
  "dependencies": {
32
+ "args-json": "^1.3.3",
32
33
  "dateshape": "^1.1.2",
33
- "esbuild": "^0.27.3"
34
+ "esbuild": "^0.27.4"
34
35
  }
35
36
  }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { hasKey, isKey } from "args-json";
2
3
  import { cli } from "./cli.ts";
3
4
 
4
5
  const availableScriptNames = new Set(["build", "dev", "prod"]);
@@ -19,21 +20,24 @@ async function run() {
19
20
  if (scriptName === "build") return await cli(args);
20
21
 
21
22
  let nodeEnv = nodeEnvMap[scriptName];
22
- let host = args[0];
23
23
 
24
24
  if (nodeEnv !== undefined) process.env.NODE_ENV = nodeEnv;
25
25
 
26
- if (host) {
27
- let [hostname, port] = host.split(":");
26
+ if (args.length !== 0 && !isKey(args[0])) {
27
+ let [hostname, port] = args[0].split(":");
28
28
 
29
29
  if (hostname) process.env.APP_HOST = hostname;
30
30
  if (port) process.env.APP_PORT = port;
31
+
32
+ args.shift();
31
33
  }
32
34
 
35
+ if (!hasKey("--client-dir")) args.push("--client-dir", "src/public/-");
36
+
33
37
  await cli(
34
38
  nodeEnv === "development"
35
- ? ["src/public", "--clean", "--start", "--watch"]
36
- : ["src/public", "--clean", "--start", "--silent"],
39
+ ? ["--clean", "--start", "--watch", ...args]
40
+ : ["--clean", "--start", "--silent", ...args],
37
41
  );
38
42
  }
39
43
 
@@ -27,7 +27,7 @@ export async function build(params: BuildParams) {
27
27
  }
28
28
 
29
29
  if (params.start)
30
- serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], {
30
+ serverProcess = spawn("node", [`${params.serverDir}/server/index.js`], {
31
31
  stdio: "inherit",
32
32
  });
33
33
  }
@@ -1,46 +1,42 @@
1
1
  import { rm } from "node:fs/promises";
2
+ import { Args } from "args-json";
2
3
  import { build } from "./build.ts";
3
4
  import type { BuildParams } from "./types/BuildParams.ts";
4
5
 
5
- const defaultTargetDir = "dist";
6
-
7
- async function clean({ targetDir, publicAssetsDir }: BuildParams) {
8
- let dirs = [
9
- `${targetDir}/server`,
10
- `${targetDir}/server-css`,
11
- `${publicAssetsDir}/-`,
12
- ];
6
+ async function clean({ serverDir, clientDir }: BuildParams) {
7
+ let dirs = [`${serverDir}/server`, `${serverDir}/server-css`, clientDir];
13
8
 
14
9
  return Promise.all(
15
10
  dirs.map((dir) => rm(dir, { recursive: true, force: true })),
16
11
  );
17
12
  }
18
13
 
19
- export async function cli(args: string[] = []) {
20
- let publicAssetsDir = args[0];
21
- let targetDir = args[1];
14
+ export async function cli(input: string[] = []) {
15
+ let args = new Args(input);
22
16
 
23
- if (!publicAssetsDir || publicAssetsDir.startsWith("--"))
24
- throw new Error("Public assets directory is undefined");
17
+ let clientDir = args.getValue("--client-dir");
18
+ let serverDir = args.getValue("--server-dir", "dist");
25
19
 
26
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
20
+ if (!clientDir) throw new Error("Public assets directory is undefined");
27
21
 
28
22
  let params: BuildParams = {
29
- targetDir,
30
- publicAssetsDir,
31
- silent: args.includes("--silent"),
32
- watch: args.includes("--watch"),
33
- watchServer: args.includes("--watch-server"),
34
- watchClient: args.includes("--watch-client"),
35
- start: args.includes("--start"),
23
+ serverDir,
24
+ clientDir,
25
+ silent: args.hasKey("--silent"),
26
+ watch: args.hasKey("--watch"),
27
+ watchServer: args.hasKey("--watch-server"),
28
+ watchClient: args.hasKey("--watch-client"),
29
+ start: args.hasKey("--start"),
36
30
  };
37
31
 
38
- if (args.includes("--clean-only")) {
32
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
33
+
34
+ if (args.hasKey("--clean-only")) {
39
35
  await clean(params);
40
36
  return;
41
37
  }
42
38
 
43
- if (args.includes("--clean")) await clean(params);
39
+ if (args.hasKey("--clean")) await clean(params);
44
40
 
45
41
  await build(params);
46
42
  }
@@ -1,9 +1,18 @@
1
1
  export type BuildParams = {
2
- targetDir: string;
3
- publicAssetsDir: string;
2
+ serverDir: string;
3
+ clientDir: string;
4
4
  silent?: boolean;
5
5
  watch?: boolean;
6
6
  watchClient?: boolean;
7
7
  watchServer?: boolean;
8
8
  start?: boolean;
9
+ /**
10
+ * A file path that the automatically picked entry exports will be
11
+ * written to.
12
+ *
13
+ * Set it to `null` to skip the automatic picking of entry exports.
14
+ *
15
+ * @default "src/server/entries.ts"
16
+ */
17
+ entriesPath?: string | null;
9
18
  };
@@ -10,7 +10,7 @@ import { getEntryPoints } from "./getEntryPoints.ts";
10
10
  * rendering.
11
11
  */
12
12
  export async function buildClient(
13
- { publicAssetsDir, watch, watchClient }: BuildParams,
13
+ { clientDir, watch, watchClient }: BuildParams,
14
14
  plugins?: Plugin[],
15
15
  ) {
16
16
  let clientEntries = await getEntryPoints(["ui/index"]);
@@ -21,7 +21,7 @@ export async function buildClient(
21
21
  bundle: true,
22
22
  splitting: true,
23
23
  format: "esm",
24
- outdir: `${publicAssetsDir}/-`,
24
+ outdir: clientDir,
25
25
  outbase: "src/entries",
26
26
  minify: process.env.NODE_ENV !== "development",
27
27
  plugins,
@@ -3,18 +3,17 @@ import { commonBuildOptions } from "../const/commonBuildOptions.ts";
3
3
  import type { BuildParams } from "../types/BuildParams.ts";
4
4
  import { populateEntries } from "./populateEntries.ts";
5
5
 
6
- export async function buildServer(
7
- { targetDir, watch, watchServer }: BuildParams,
8
- plugins?: Plugin[],
9
- ) {
10
- await populateEntries();
6
+ export async function buildServer(params: BuildParams, plugins?: Plugin[]) {
7
+ let { serverDir, watch, watchServer } = params;
8
+
9
+ await populateEntries(params);
11
10
 
12
11
  let buildOptions: BuildOptions = {
13
12
  ...commonBuildOptions,
14
13
  entryPoints: ["src/server/index.ts"],
15
14
  bundle: true,
16
15
  splitting: true,
17
- outdir: `${targetDir}/server`,
16
+ outdir: `${serverDir}/server`,
18
17
  platform: "node",
19
18
  format: "esm",
20
19
  packages: "external",
@@ -4,7 +4,7 @@ import type { BuildParams } from "../types/BuildParams.ts";
4
4
  import { getEntryPoints } from "./getEntryPoints.ts";
5
5
 
6
6
  export async function buildServerCSS(
7
- { targetDir, watch, watchServer }: BuildParams,
7
+ { serverDir, watch, watchServer }: BuildParams,
8
8
  plugins?: Plugin[],
9
9
  ) {
10
10
  let serverEntries = await getEntryPoints(["server", "server/index"]);
@@ -17,7 +17,7 @@ export async function buildServerCSS(
17
17
  })),
18
18
  bundle: true,
19
19
  splitting: false,
20
- outdir: `${targetDir}/server-css`,
20
+ outdir: `${serverDir}/server-css`,
21
21
  platform: "node",
22
22
  format: "esm",
23
23
  packages: "external",
@@ -3,7 +3,7 @@ import type { Plugin } from "esbuild";
3
3
  import type { BuildParams } from "../types/BuildParams.ts";
4
4
 
5
5
  export function createPostbuildPlugins(
6
- { targetDir, publicAssetsDir }: BuildParams,
6
+ { serverDir, clientDir }: BuildParams,
7
7
  onServerRebuild: () => void,
8
8
  ) {
9
9
  let serverPlugins: Plugin[] = [
@@ -29,7 +29,7 @@ export function createPostbuildPlugins(
29
29
  name: "postbuild-server-css",
30
30
  setup(build) {
31
31
  build.onEnd(async () => {
32
- let dir = `${targetDir}/server-css`;
32
+ let dir = `${serverDir}/server-css`;
33
33
 
34
34
  try {
35
35
  let files = (await readdir(dir)).filter((name) =>
@@ -38,15 +38,15 @@ export function createPostbuildPlugins(
38
38
 
39
39
  if (files.length === 0) return;
40
40
 
41
- await mkdir(`${publicAssetsDir}/-`, { recursive: true });
41
+ await mkdir(clientDir, { recursive: true });
42
42
 
43
43
  await Promise.all(
44
44
  files.map(async (name) => {
45
- let dir = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
45
+ let dir = `${clientDir}/${name.slice(0, -4)}`;
46
46
 
47
47
  await mkdir(dir, { recursive: true });
48
48
  await rename(
49
- `${targetDir}/server-css/${name}`,
49
+ `${serverDir}/server-css/${name}`,
50
50
  `${dir}/index.css`,
51
51
  );
52
52
  }),
@@ -1,8 +1,11 @@
1
1
  import { writeFile } from "node:fs/promises";
2
+ import type { BuildParams } from "../types/BuildParams.ts";
2
3
  import { getEntryPoints } from "./getEntryPoints.ts";
3
4
  import { toImportPath } from "./toImportPath.ts";
4
5
 
5
- export async function populateEntries() {
6
+ export async function populateEntries({ entriesPath }: BuildParams) {
7
+ if (entriesPath === null) return;
8
+
6
9
  let serverEntries = await getEntryPoints(["server", "server/index"]);
7
10
  let content = "";
8
11
 
@@ -19,7 +22,7 @@ export async function populateEntries() {
19
22
  }
20
23
 
21
24
  await writeFile(
22
- "src/server/autoentries.ts",
25
+ entriesPath ?? "src/server/entries.ts",
23
26
  `// Populated automatically during the build phase by picking
24
27
  // all server exports from "src/entries/<entry_name>/server(/index)?.(js|ts)"
25
28
  ${content}
@@ -13,7 +13,7 @@ export function createApp(callback?: () => void | Promise<void>) {
13
13
  if (!app.events) app.events = new EventEmitter();
14
14
 
15
15
  let host = process.env.APP_HOST || "localhost";
16
- let port = Number(process.env.APP_PORT) || 80;
16
+ let port = Number(process.env.APP_PORT) || 3000;
17
17
 
18
18
  let listen = () => {
19
19
  app.listen(port, host, () => {