appstage 0.2.5 → 0.2.7

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,15 +433,19 @@ async function getEntryPoints(path) {
291
433
  }
292
434
 
293
435
  // src/scripts/utils/buildClient.ts
294
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
295
- let clientEntries = await getEntryPoints(["ui/index"]);
436
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
437
+ let clientEntries = await getEntryPoints([
438
+ "ui/index",
439
+ "client/index",
440
+ "index"
441
+ ]);
296
442
  let buildOptions = {
297
443
  ...commonBuildOptions,
298
444
  entryPoints: clientEntries.map(({ path }) => path),
299
445
  bundle: true,
300
446
  splitting: true,
301
447
  format: "esm",
302
- outdir: `${publicAssetsDir}/-`,
448
+ outdir: clientDir,
303
449
  outbase: "src/entries",
304
450
  minify: process.env.NODE_ENV !== "development",
305
451
  plugins
@@ -357,14 +503,14 @@ ${content}
357
503
 
358
504
  // src/scripts/utils/buildServer.ts
359
505
  async function buildServer(params, plugins) {
360
- let { targetDir, watch, watchServer } = params;
506
+ let { serverDir, watch, watchServer } = params;
361
507
  await populateEntries(params);
362
508
  let buildOptions = {
363
509
  ...commonBuildOptions,
364
510
  entryPoints: ["src/server/index.ts"],
365
511
  bundle: true,
366
512
  splitting: true,
367
- outdir: `${targetDir}/server`,
513
+ outdir: `${serverDir}/server`,
368
514
  platform: "node",
369
515
  format: "esm",
370
516
  packages: "external",
@@ -382,7 +528,7 @@ async function buildServer(params, plugins) {
382
528
 
383
529
  // src/scripts/utils/buildServerCSS.ts
384
530
  import esbuild3 from "esbuild";
385
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
531
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
386
532
  let serverEntries = await getEntryPoints(["server", "server/index"]);
387
533
  let buildOptions = {
388
534
  ...commonBuildOptions,
@@ -392,7 +538,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
392
538
  })),
393
539
  bundle: true,
394
540
  splitting: false,
395
- outdir: `${targetDir}/server-css`,
541
+ outdir: `${serverDir}/server-css`,
396
542
  platform: "node",
397
543
  format: "esm",
398
544
  packages: "external",
@@ -410,7 +556,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
410
556
 
411
557
  // src/scripts/utils/createPostbuildPlugins.ts
412
558
  import { mkdir, readdir as readdir2, rename, rm } from "node:fs/promises";
413
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
559
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
414
560
  let serverPlugins = [
415
561
  {
416
562
  name: "skip-css",
@@ -432,19 +578,19 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
432
578
  name: "postbuild-server-css",
433
579
  setup(build2) {
434
580
  build2.onEnd(async () => {
435
- let dir = `${targetDir}/server-css`;
581
+ let dir = `${serverDir}/server-css`;
436
582
  try {
437
583
  let files = (await readdir2(dir)).filter(
438
584
  (name) => name.endsWith(".css")
439
585
  );
440
586
  if (files.length === 0) return;
441
- await mkdir(`${publicAssetsDir}/-`, { recursive: true });
587
+ await mkdir(clientDir, { recursive: true });
442
588
  await Promise.all(
443
589
  files.map(async (name) => {
444
- let dir2 = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
590
+ let dir2 = `${clientDir}/${name.slice(0, -4)}`;
445
591
  await mkdir(dir2, { recursive: true });
446
592
  await rename(
447
- `${targetDir}/server-css/${name}`,
593
+ `${serverDir}/server-css/${name}`,
448
594
  `${dir2}/index.css`
449
595
  );
450
596
  })
@@ -480,7 +626,7 @@ async function build(params) {
480
626
  inited = true;
481
627
  }
482
628
  if (params.start)
483
- serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], {
629
+ serverProcess = spawn("node", [`${params.serverDir}/server/index.js`], {
484
630
  stdio: "inherit"
485
631
  });
486
632
  }
@@ -496,38 +642,32 @@ async function build(params) {
496
642
  }
497
643
 
498
644
  // src/scripts/cli.ts
499
- var defaultTargetDir = "dist";
500
- async function clean({ targetDir, publicAssetsDir }) {
501
- let dirs = [
502
- `${targetDir}/server`,
503
- `${targetDir}/server-css`,
504
- `${publicAssetsDir}/-`
505
- ];
645
+ async function clean({ serverDir, clientDir }) {
646
+ let dirs = [`${serverDir}/server`, `${serverDir}/server-css`, clientDir];
506
647
  return Promise.all(
507
648
  dirs.map((dir) => rm2(dir, { recursive: true, force: true }))
508
649
  );
509
650
  }
510
- async function cli(args = []) {
511
- let publicAssetsDir = args[0];
512
- let targetDir = args[1];
513
- if (!publicAssetsDir || publicAssetsDir.startsWith("--"))
514
- throw new Error("Public assets directory is undefined");
515
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
651
+ async function cli(input = []) {
652
+ let args = new import_args_json.Args(input);
653
+ let clientDir = args.getValue("--client-dir");
654
+ let serverDir = args.getValue("--server-dir", "dist");
655
+ if (!clientDir) throw new Error("Public assets directory is undefined");
516
656
  let params = {
517
- targetDir,
518
- publicAssetsDir,
519
- silent: args.includes("--silent"),
520
- watch: args.includes("--watch"),
521
- watchServer: args.includes("--watch-server"),
522
- watchClient: args.includes("--watch-client"),
523
- start: args.includes("--start")
657
+ serverDir,
658
+ clientDir,
659
+ silent: args.hasKey("--silent"),
660
+ watch: args.hasKey("--watch"),
661
+ watchServer: args.hasKey("--watch-server"),
662
+ watchClient: args.hasKey("--watch-client"),
663
+ start: args.hasKey("--start")
524
664
  };
525
- if (args.includes("--no-auto-entries")) params.entriesPath = null;
526
- if (args.includes("--clean-only")) {
665
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
666
+ if (args.hasKey("--clean-only")) {
527
667
  await clean(params);
528
668
  return;
529
669
  }
530
- if (args.includes("--clean")) await clean(params);
670
+ if (args.hasKey("--clean")) await clean(params);
531
671
  await build(params);
532
672
  }
533
673
 
@@ -545,15 +685,16 @@ async function run() {
545
685
  }
546
686
  if (scriptName === "build") return await cli(args);
547
687
  let nodeEnv = nodeEnvMap[scriptName];
548
- let host = args.shift();
549
688
  if (nodeEnv !== void 0) process.env.NODE_ENV = nodeEnv;
550
- if (host) {
551
- let [hostname, port] = host.split(":");
689
+ if (args.length !== 0 && !(0, import_args_json2.isKey)(args[0])) {
690
+ let [hostname, port] = args[0].split(":");
552
691
  if (hostname) process.env.APP_HOST = hostname;
553
692
  if (port) process.env.APP_PORT = port;
693
+ args.shift();
554
694
  }
695
+ if (!(0, import_args_json2.hasKey)("--client-dir")) args.push("--client-dir", "src/public/-");
555
696
  await cli(
556
- nodeEnv === "development" ? ["src/public", "--clean", "--start", "--watch", ...args] : ["src/public", "--clean", "--start", "--silent", ...args]
697
+ nodeEnv === "development" ? ["--clean", "--start", "--watch", ...args] : ["--clean", "--start", "--silent", ...args]
557
698
  );
558
699
  }
559
700
  await run();
package/dist/index.cjs CHANGED
@@ -29,6 +29,7 @@ let node_http = require("node:http");
29
29
  let node_child_process = require("node:child_process");
30
30
  let esbuild = require("esbuild");
31
31
  esbuild = __toESM(esbuild);
32
+ let args_json = require("args-json");
32
33
  let node_events = require("node:events");
33
34
  node_events = __toESM(node_events);
34
35
  let express = require("express");
@@ -363,20 +364,21 @@ async function getEntryPoints(path) {
363
364
  }
364
365
 
365
366
  /**
366
- * Builds the client-side code from the 'src/entries/<entry_name>/ui'
367
- * directories. The directories should preferrably be called 'ui' rather
368
- * than client since their contents can also be used with the server-side
369
- * rendering.
367
+ * Builds the client-side code.
370
368
  */
371
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
372
- let clientEntries = await getEntryPoints(["ui/index"]);
369
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
370
+ let clientEntries = await getEntryPoints([
371
+ "ui/index",
372
+ "client/index",
373
+ "index"
374
+ ]);
373
375
  let buildOptions = {
374
376
  ...commonBuildOptions,
375
377
  entryPoints: clientEntries.map(({ path }) => path),
376
378
  bundle: true,
377
379
  splitting: true,
378
380
  format: "esm",
379
- outdir: `${publicAssetsDir}/-`,
381
+ outdir: clientDir,
380
382
  outbase: "src/entries",
381
383
  minify: process.env.NODE_ENV !== "development",
382
384
  plugins
@@ -416,14 +418,14 @@ ${content}
416
418
  }
417
419
 
418
420
  async function buildServer(params, plugins) {
419
- let { targetDir, watch, watchServer } = params;
421
+ let { serverDir, watch, watchServer } = params;
420
422
  await populateEntries(params);
421
423
  let buildOptions = {
422
424
  ...commonBuildOptions,
423
425
  entryPoints: ["src/server/index.ts"],
424
426
  bundle: true,
425
427
  splitting: true,
426
- outdir: `${targetDir}/server`,
428
+ outdir: `${serverDir}/server`,
427
429
  platform: "node",
428
430
  format: "esm",
429
431
  packages: "external",
@@ -439,7 +441,7 @@ async function buildServer(params, plugins) {
439
441
  await esbuild.default.build(buildOptions);
440
442
  }
441
443
 
442
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
444
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
443
445
  let serverEntries = await getEntryPoints(["server", "server/index"]);
444
446
  let buildOptions = {
445
447
  ...commonBuildOptions,
@@ -449,7 +451,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
449
451
  })),
450
452
  bundle: true,
451
453
  splitting: false,
452
- outdir: `${targetDir}/server-css`,
454
+ outdir: `${serverDir}/server-css`,
453
455
  platform: "node",
454
456
  format: "esm",
455
457
  packages: "external",
@@ -465,7 +467,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
465
467
  await esbuild.default.build(buildOptions);
466
468
  }
467
469
 
468
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
470
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
469
471
  return {
470
472
  serverPlugins: [{
471
473
  name: "skip-css",
@@ -485,15 +487,15 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
485
487
  name: "postbuild-server-css",
486
488
  setup(build) {
487
489
  build.onEnd(async () => {
488
- let dir = `${targetDir}/server-css`;
490
+ let dir = `${serverDir}/server-css`;
489
491
  try {
490
492
  let files = (await (0, node_fs_promises.readdir)(dir)).filter((name) => name.endsWith(".css"));
491
493
  if (files.length === 0) return;
492
- await (0, node_fs_promises.mkdir)(`${publicAssetsDir}/-`, { recursive: true });
494
+ await (0, node_fs_promises.mkdir)(clientDir, { recursive: true });
493
495
  await Promise.all(files.map(async (name) => {
494
- let dir = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
496
+ let dir = `${clientDir}/${name.slice(0, -4)}`;
495
497
  await (0, node_fs_promises.mkdir)(dir, { recursive: true });
496
- await (0, node_fs_promises.rename)(`${targetDir}/server-css/${name}`, `${dir}/index.css`);
498
+ await (0, node_fs_promises.rename)(`${serverDir}/server-css/${name}`, `${dir}/index.css`);
497
499
  }));
498
500
  await (0, node_fs_promises.rm)(dir, {
499
501
  recursive: true,
@@ -521,7 +523,7 @@ async function build(params) {
521
523
  log(`Build completed +${(0, dateshape.formatDuration)(Date.now() - startTime)}`);
522
524
  inited = true;
523
525
  }
524
- if (params.start) serverProcess = (0, node_child_process.spawn)("node", [`${params.targetDir}/server/index.js`], { stdio: "inherit" });
526
+ if (params.start) serverProcess = (0, node_child_process.spawn)("node", [`${params.serverDir}/server/index.js`], { stdio: "inherit" });
525
527
  }
526
528
  let { serverPlugins, serverCSSPlugins } = createPostbuildPlugins(params, handleServerRebuild);
527
529
  await Promise.all([
@@ -531,38 +533,37 @@ async function build(params) {
531
533
  ]);
532
534
  }
533
535
 
534
- const defaultTargetDir = "dist";
535
- async function clean({ targetDir, publicAssetsDir }) {
536
+ async function clean({ serverDir, clientDir }) {
536
537
  let dirs = [
537
- `${targetDir}/server`,
538
- `${targetDir}/server-css`,
539
- `${publicAssetsDir}/-`
538
+ `${serverDir}/server`,
539
+ `${serverDir}/server-css`,
540
+ clientDir
540
541
  ];
541
542
  return Promise.all(dirs.map((dir) => (0, node_fs_promises.rm)(dir, {
542
543
  recursive: true,
543
544
  force: true
544
545
  })));
545
546
  }
546
- async function cli(args = []) {
547
- let publicAssetsDir = args[0];
548
- let targetDir = args[1];
549
- if (!publicAssetsDir || publicAssetsDir.startsWith("--")) throw new Error("Public assets directory is undefined");
550
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
547
+ async function cli(input = []) {
548
+ let args = new args_json.Args(input);
549
+ let clientDir = args.getValue("--client-dir");
550
+ let serverDir = args.getValue("--server-dir", "dist");
551
+ if (!clientDir) throw new Error("Public assets directory is undefined");
551
552
  let params = {
552
- targetDir,
553
- publicAssetsDir,
554
- silent: args.includes("--silent"),
555
- watch: args.includes("--watch"),
556
- watchServer: args.includes("--watch-server"),
557
- watchClient: args.includes("--watch-client"),
558
- start: args.includes("--start")
553
+ serverDir,
554
+ clientDir,
555
+ silent: args.hasKey("--silent"),
556
+ watch: args.hasKey("--watch"),
557
+ watchServer: args.hasKey("--watch-server"),
558
+ watchClient: args.hasKey("--watch-client"),
559
+ start: args.hasKey("--start")
559
560
  };
560
- if (args.includes("--no-auto-entries")) params.entriesPath = null;
561
- if (args.includes("--clean-only")) {
561
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
562
+ if (args.hasKey("--clean-only")) {
562
563
  await clean(params);
563
564
  return;
564
565
  }
565
- if (args.includes("--clean")) await clean(params);
566
+ if (args.hasKey("--clean")) await clean(params);
566
567
  await build(params);
567
568
  }
568
569
 
package/dist/index.d.ts CHANGED
@@ -131,8 +131,8 @@ 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;
@@ -151,7 +151,7 @@ type BuildParams = {
151
151
 
152
152
  declare function build(params: BuildParams): Promise<void>;
153
153
 
154
- declare function cli(args?: string[]): Promise<void>;
154
+ declare function cli(input?: string[]): Promise<void>;
155
155
 
156
156
  type LogLevel = "error" | "debug" | "info" | "warn";
157
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
 
@@ -337,20 +338,21 @@ async function getEntryPoints(path) {
337
338
  }
338
339
 
339
340
  /**
340
- * Builds the client-side code from the 'src/entries/<entry_name>/ui'
341
- * directories. The directories should preferrably be called 'ui' rather
342
- * than client since their contents can also be used with the server-side
343
- * rendering.
341
+ * Builds the client-side code.
344
342
  */
345
- async function buildClient({ publicAssetsDir, watch, watchClient }, plugins) {
346
- let clientEntries = await getEntryPoints(["ui/index"]);
343
+ async function buildClient({ clientDir, watch, watchClient }, plugins) {
344
+ let clientEntries = await getEntryPoints([
345
+ "ui/index",
346
+ "client/index",
347
+ "index"
348
+ ]);
347
349
  let buildOptions = {
348
350
  ...commonBuildOptions,
349
351
  entryPoints: clientEntries.map(({ path }) => path),
350
352
  bundle: true,
351
353
  splitting: true,
352
354
  format: "esm",
353
- outdir: `${publicAssetsDir}/-`,
355
+ outdir: clientDir,
354
356
  outbase: "src/entries",
355
357
  minify: process.env.NODE_ENV !== "development",
356
358
  plugins
@@ -390,14 +392,14 @@ ${content}
390
392
  }
391
393
 
392
394
  async function buildServer(params, plugins) {
393
- let { targetDir, watch, watchServer } = params;
395
+ let { serverDir, watch, watchServer } = params;
394
396
  await populateEntries(params);
395
397
  let buildOptions = {
396
398
  ...commonBuildOptions,
397
399
  entryPoints: ["src/server/index.ts"],
398
400
  bundle: true,
399
401
  splitting: true,
400
- outdir: `${targetDir}/server`,
402
+ outdir: `${serverDir}/server`,
401
403
  platform: "node",
402
404
  format: "esm",
403
405
  packages: "external",
@@ -413,7 +415,7 @@ async function buildServer(params, plugins) {
413
415
  await esbuild.build(buildOptions);
414
416
  }
415
417
 
416
- async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
418
+ async function buildServerCSS({ serverDir, watch, watchServer }, plugins) {
417
419
  let serverEntries = await getEntryPoints(["server", "server/index"]);
418
420
  let buildOptions = {
419
421
  ...commonBuildOptions,
@@ -423,7 +425,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
423
425
  })),
424
426
  bundle: true,
425
427
  splitting: false,
426
- outdir: `${targetDir}/server-css`,
428
+ outdir: `${serverDir}/server-css`,
427
429
  platform: "node",
428
430
  format: "esm",
429
431
  packages: "external",
@@ -439,7 +441,7 @@ async function buildServerCSS({ targetDir, watch, watchServer }, plugins) {
439
441
  await esbuild.build(buildOptions);
440
442
  }
441
443
 
442
- function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild) {
444
+ function createPostbuildPlugins({ serverDir, clientDir }, onServerRebuild) {
443
445
  return {
444
446
  serverPlugins: [{
445
447
  name: "skip-css",
@@ -459,15 +461,15 @@ function createPostbuildPlugins({ targetDir, publicAssetsDir }, onServerRebuild)
459
461
  name: "postbuild-server-css",
460
462
  setup(build) {
461
463
  build.onEnd(async () => {
462
- let dir = `${targetDir}/server-css`;
464
+ let dir = `${serverDir}/server-css`;
463
465
  try {
464
466
  let files = (await readdir(dir)).filter((name) => name.endsWith(".css"));
465
467
  if (files.length === 0) return;
466
- await mkdir(`${publicAssetsDir}/-`, { recursive: true });
468
+ await mkdir(clientDir, { recursive: true });
467
469
  await Promise.all(files.map(async (name) => {
468
- let dir = `${publicAssetsDir}/-/${name.slice(0, -4)}`;
470
+ let dir = `${clientDir}/${name.slice(0, -4)}`;
469
471
  await mkdir(dir, { recursive: true });
470
- await rename(`${targetDir}/server-css/${name}`, `${dir}/index.css`);
472
+ await rename(`${serverDir}/server-css/${name}`, `${dir}/index.css`);
471
473
  }));
472
474
  await rm(dir, {
473
475
  recursive: true,
@@ -495,7 +497,7 @@ async function build(params) {
495
497
  log(`Build completed +${formatDuration(Date.now() - startTime)}`);
496
498
  inited = true;
497
499
  }
498
- if (params.start) serverProcess = spawn("node", [`${params.targetDir}/server/index.js`], { stdio: "inherit" });
500
+ if (params.start) serverProcess = spawn("node", [`${params.serverDir}/server/index.js`], { stdio: "inherit" });
499
501
  }
500
502
  let { serverPlugins, serverCSSPlugins } = createPostbuildPlugins(params, handleServerRebuild);
501
503
  await Promise.all([
@@ -505,38 +507,37 @@ async function build(params) {
505
507
  ]);
506
508
  }
507
509
 
508
- const defaultTargetDir = "dist";
509
- async function clean({ targetDir, publicAssetsDir }) {
510
+ async function clean({ serverDir, clientDir }) {
510
511
  let dirs = [
511
- `${targetDir}/server`,
512
- `${targetDir}/server-css`,
513
- `${publicAssetsDir}/-`
512
+ `${serverDir}/server`,
513
+ `${serverDir}/server-css`,
514
+ clientDir
514
515
  ];
515
516
  return Promise.all(dirs.map((dir) => rm(dir, {
516
517
  recursive: true,
517
518
  force: true
518
519
  })));
519
520
  }
520
- async function cli(args = []) {
521
- let publicAssetsDir = args[0];
522
- let targetDir = args[1];
523
- if (!publicAssetsDir || publicAssetsDir.startsWith("--")) throw new Error("Public assets directory is undefined");
524
- if (!targetDir || targetDir.startsWith("--")) targetDir = defaultTargetDir;
521
+ async function cli(input = []) {
522
+ let args = new Args(input);
523
+ let clientDir = args.getValue("--client-dir");
524
+ let serverDir = args.getValue("--server-dir", "dist");
525
+ if (!clientDir) throw new Error("Public assets directory is undefined");
525
526
  let params = {
526
- targetDir,
527
- publicAssetsDir,
528
- silent: args.includes("--silent"),
529
- watch: args.includes("--watch"),
530
- watchServer: args.includes("--watch-server"),
531
- watchClient: args.includes("--watch-client"),
532
- start: args.includes("--start")
527
+ serverDir,
528
+ clientDir,
529
+ silent: args.hasKey("--silent"),
530
+ watch: args.hasKey("--watch"),
531
+ watchServer: args.hasKey("--watch-server"),
532
+ watchClient: args.hasKey("--watch-client"),
533
+ start: args.hasKey("--start")
533
534
  };
534
- if (args.includes("--no-auto-entries")) params.entriesPath = null;
535
- if (args.includes("--clean-only")) {
535
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
536
+ if (args.hasKey("--clean-only")) {
536
537
  await clean(params);
537
538
  return;
538
539
  }
539
- if (args.includes("--clean")) await clean(params);
540
+ if (args.hasKey("--clean")) await clean(params);
540
541
  await build(params);
541
542
  }
542
543
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appstage",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
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.shift();
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", ...args]
36
- : ["src/public", "--clean", "--start", "--silent", ...args],
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,48 +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("--no-auto-entries")) params.entriesPath = null;
32
+ if (args.hasKey("--no-auto-entries")) params.entriesPath = null;
39
33
 
40
- if (args.includes("--clean-only")) {
34
+ if (args.hasKey("--clean-only")) {
41
35
  await clean(params);
42
36
  return;
43
37
  }
44
38
 
45
- if (args.includes("--clean")) await clean(params);
39
+ if (args.hasKey("--clean")) await clean(params);
46
40
 
47
41
  await build(params);
48
42
  }
@@ -1,6 +1,6 @@
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;
@@ -4,16 +4,17 @@ import type { BuildParams } from "../types/BuildParams.ts";
4
4
  import { getEntryPoints } from "./getEntryPoints.ts";
5
5
 
6
6
  /**
7
- * Builds the client-side code from the 'src/entries/<entry_name>/ui'
8
- * directories. The directories should preferrably be called 'ui' rather
9
- * than client since their contents can also be used with the server-side
10
- * rendering.
7
+ * Builds the client-side code.
11
8
  */
12
9
  export async function buildClient(
13
- { publicAssetsDir, watch, watchClient }: BuildParams,
10
+ { clientDir, watch, watchClient }: BuildParams,
14
11
  plugins?: Plugin[],
15
12
  ) {
16
- let clientEntries = await getEntryPoints(["ui/index"]);
13
+ let clientEntries = await getEntryPoints([
14
+ "ui/index",
15
+ "client/index",
16
+ "index",
17
+ ]);
17
18
 
18
19
  let buildOptions: BuildOptions = {
19
20
  ...commonBuildOptions,
@@ -21,7 +22,7 @@ export async function buildClient(
21
22
  bundle: true,
22
23
  splitting: true,
23
24
  format: "esm",
24
- outdir: `${publicAssetsDir}/-`,
25
+ outdir: clientDir,
25
26
  outbase: "src/entries",
26
27
  minify: process.env.NODE_ENV !== "development",
27
28
  plugins,
@@ -4,7 +4,7 @@ import type { BuildParams } from "../types/BuildParams.ts";
4
4
  import { populateEntries } from "./populateEntries.ts";
5
5
 
6
6
  export async function buildServer(params: BuildParams, plugins?: Plugin[]) {
7
- let { targetDir, watch, watchServer } = params;
7
+ let { serverDir, watch, watchServer } = params;
8
8
 
9
9
  await populateEntries(params);
10
10
 
@@ -13,7 +13,7 @@ export async function buildServer(params: BuildParams, plugins?: Plugin[]) {
13
13
  entryPoints: ["src/server/index.ts"],
14
14
  bundle: true,
15
15
  splitting: true,
16
- outdir: `${targetDir}/server`,
16
+ outdir: `${serverDir}/server`,
17
17
  platform: "node",
18
18
  format: "esm",
19
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
  }),