create-absolutejs 0.1.10 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
+ // @bun
2
3
  var __create = Object.create;
3
4
  var __getProtoOf = Object.getPrototypeOf;
4
5
  var __defProp = Object.defineProperty;
@@ -146,8 +147,7 @@ var require_picocolors = __commonJS((exports, module) => {
146
147
  });
147
148
 
148
149
  // src/index.ts
149
- import { argv, exit as exit4 } from "node:process";
150
- import { parseArgs } from "node:util";
150
+ import { exit as exit5 } from "process";
151
151
 
152
152
  // node_modules/@clack/core/dist/index.mjs
153
153
  var import_sisteransi = __toESM(require_src(), 1);
@@ -637,17 +637,284 @@ var q = u("●", "•");
637
637
  var D = u("◆", "*");
638
638
  var U = u("▲", "!");
639
639
  var K2 = u("■", "x");
640
+ var Se = (t = "") => {
641
+ process.stdout.write(`${import_picocolors2.default.gray(o)}
642
+ ${import_picocolors2.default.gray(d2)} ${t}
643
+
644
+ `);
645
+ };
646
+ var J2 = `${import_picocolors2.default.gray(o)} `;
647
+
648
+ // src/messages.ts
649
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
650
+
651
+ // src/data.ts
652
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
653
+ var availableFrontends = [
654
+ "react",
655
+ "html",
656
+ "svelte",
657
+ "htmx"
658
+ ];
659
+ var availableAuthProviders = ["absoluteAuth", "none"];
660
+ var availableLanguages = ["ts", "js"];
661
+ var availableHTMLScriptOptions = ["js", "ts", "none"];
662
+ var availableDatabaseEngines = [
663
+ "postgresql",
664
+ "mysql",
665
+ "sqlite",
666
+ "mongodb",
667
+ "redis",
668
+ "singlestore",
669
+ "cockroachdb",
670
+ "mssql",
671
+ "none"
672
+ ];
673
+ var availableDirectoryConfigurations = ["default", "custom"];
674
+ var availableORMs = ["drizzle", "prisma", "none"];
675
+ var availableDatabaseHosts = [
676
+ "neon",
677
+ "planetscale",
678
+ "supabase",
679
+ "turso",
680
+ "vercel",
681
+ "upstash",
682
+ "atlas",
683
+ "none"
684
+ ];
685
+ var availableCodeQualityTools = ["eslint+prettier", "biome"];
686
+ var frontendLabels = {
687
+ react: import_picocolors3.cyan("React"),
688
+ html: "HTML",
689
+ svelte: import_picocolors3.magenta("Svelte"),
690
+ htmx: "HTMX"
691
+ };
692
+ var availablePlugins = [
693
+ {
694
+ imports: [{ config: null, isPlugin: true, packageName: "cors" }],
695
+ label: import_picocolors3.cyan("⚙️ @elysiajs/cors"),
696
+ latestVersion: "1.3.3",
697
+ value: "@elysiajs/cors"
698
+ },
699
+ {
700
+ imports: [{ config: null, isPlugin: true, packageName: "swagger" }],
701
+ label: import_picocolors3.cyan("\uD83D\uDCD1 @elysiajs/swagger"),
702
+ latestVersion: "1.3.0",
703
+ value: "@elysiajs/swagger"
704
+ },
705
+ {
706
+ imports: [{ config: null, isPlugin: true, packageName: "rateLimit" }],
707
+ label: import_picocolors3.green("\uD83D\uDEE0️ elysia-rate-limit"),
708
+ latestVersion: "4.3.0",
709
+ value: "elysia-rate-limit"
710
+ }
711
+ ];
712
+ var absoluteAuthPlugin = {
713
+ imports: [
714
+ {
715
+ config: { providersConfiguration: {} },
716
+ isPlugin: true,
717
+ packageName: "absoluteAuth"
718
+ }
719
+ ],
720
+ latestVersion: "0.3.2",
721
+ value: "@absolutejs/auth"
722
+ };
723
+ var eslintAndPrettierDependencies = [
724
+ {
725
+ latestVersion: "9.27.0",
726
+ value: "eslint"
727
+ },
728
+ {
729
+ latestVersion: "3.5.3",
730
+ value: "prettier"
731
+ }
732
+ ];
733
+ var defaultDependencies = [
734
+ {
735
+ imports: [{ isPlugin: false, packageName: "Elysia" }],
736
+ latestVersion: "1.3.1",
737
+ value: "elysia"
738
+ }
739
+ ];
740
+ var defaultPlugins = [
741
+ {
742
+ imports: [
743
+ { isPlugin: false, packageName: "build" },
744
+ { isPlugin: true, packageName: "networkingPlugin" }
745
+ ],
746
+ latestVersion: "0.8.14",
747
+ value: "@absolutejs/absolute"
748
+ },
749
+ {
750
+ imports: [
751
+ {
752
+ config: { assets: "./build", prefix: "" },
753
+ isPlugin: true,
754
+ packageName: "staticPlugin"
755
+ }
756
+ ],
757
+ latestVersion: "1.3.0",
758
+ value: "@elysiajs/static"
759
+ }
760
+ ];
761
+
762
+ // src/messages.ts
763
+ var helpMessage = `
764
+ Usage: create-absolute [options] [${import_picocolors4.magenta("project-name")}]
765
+
766
+ Arguments:
767
+ ${import_picocolors4.magenta("project-name")} Name of the application to create.
768
+ If omitted, you'll be prompted to enter one.
769
+
770
+ Options:
771
+ ${import_picocolors4.cyan("--help, -h")} Show this help message and exit
772
+ ${import_picocolors4.cyan("--debug, -d")} Display a summary of the project configuration after creation
773
+
774
+ ${import_picocolors4.cyan("--angular")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an Angular frontend
775
+ ${import_picocolors4.cyan("--assets")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for your static assets
776
+ ${import_picocolors4.cyan("--auth")} ${import_picocolors4.dim(import_picocolors4.cyan("<plugin>"))} Preconfigured auth plugin (currently only "absolute-auth") or 'none' to skip auth setup
777
+ ${import_picocolors4.cyan("--build")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Output directory for build artifacts
778
+ ${import_picocolors4.cyan("--database")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for your database files
779
+ ${import_picocolors4.cyan("--directory")} ${import_picocolors4.dim(import_picocolors4.cyan("<mode>"))} Directory-naming strategy: "default" or "custom"
780
+ ${import_picocolors4.cyan("--engine")} ${import_picocolors4.dim(import_picocolors4.cyan("<engine>"))} Database engine (postgresql | mysql | sqlite | mongodb | redis | singlestore | cockroachdb | mssql) or 'none' to skip database setup
781
+ ${import_picocolors4.cyan("--frontend")} ${import_picocolors4.dim(import_picocolors4.cyan("<name>"))} Frontend framework(s) to include: one or more of "react", "svelte", "html", "htmx", "vue", "angular"
782
+ ${import_picocolors4.cyan("--git")} Initialize a Git repository
783
+ ${import_picocolors4.cyan("--host")} ${import_picocolors4.dim(import_picocolors4.cyan("<host>"))} Database host provider (neon | planetscale | supabase | turso | vercel | upstash | atlas) or 'none' to skip database host setup
784
+ ${import_picocolors4.cyan("--html")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an HTML frontend
785
+ ${import_picocolors4.cyan("--htmx")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an HTMX frontend
786
+ ${import_picocolors4.cyan("--lang")} ${import_picocolors4.dim(import_picocolors4.cyan("<lang>"))} Language: "ts" or "js"
787
+ ${import_picocolors4.cyan("--lts")} Use LTS versions of required packages
788
+ ${import_picocolors4.cyan("--npm")} Use the package manager that invoked this command to install dependencies
789
+ ${import_picocolors4.cyan("--orm")} ${import_picocolors4.dim(import_picocolors4.cyan("<orm>"))} ORM to configure: "drizzle" or "prisma" or 'none' to skip ORM setup
790
+ ${import_picocolors4.cyan("--plugin")} ${import_picocolors4.dim(import_picocolors4.cyan("<plugin>"))} Elysia plugin(s) to include (can be specified multiple times), passing 'none' will skip plugin setup and ignore any other plugin options
791
+ ${import_picocolors4.cyan("--quality")} ${import_picocolors4.dim(import_picocolors4.cyan("<tool>"))} Code quality tool: "eslint+prettier" or "biome"
792
+ ${import_picocolors4.cyan("--react")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a React frontend
793
+ ${import_picocolors4.cyan("--script")} ${import_picocolors4.dim(import_picocolors4.cyan("<option>"))} HTML scripting option: "ts" or "js" or 'none' to skip HTML scripting setup
794
+ ${import_picocolors4.cyan("--skip")} Skips non required prompts and uses 'none' for all optional configurations
795
+ ${import_picocolors4.cyan("--svelte")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a Svelte frontend
796
+ ${import_picocolors4.cyan("--tailwind")} Include Tailwind CSS setup
797
+ ${import_picocolors4.cyan("--tailwind-input")} ${import_picocolors4.dim(import_picocolors4.cyan("<file>"))} Path to your Tailwind CSS entry file
798
+ ${import_picocolors4.cyan("--tailwind-output")} ${import_picocolors4.dim(import_picocolors4.cyan("<file>"))} Path for the generated Tailwind CSS bundle
799
+ ${import_picocolors4.cyan("--vue")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a Vue frontend
800
+ `;
801
+ var getOutroMessage = ({
802
+ projectName,
803
+ packageManager,
804
+ installDependenciesNow
805
+ }) => `${import_picocolors4.green("Created successfully")}, you can now run:
806
+
807
+ ` + `${import_picocolors4.cyan("cd")} ${projectName}
808
+ ` + `${installDependenciesNow ? "" : `${import_picocolors4.cyan(`${packageManager} install`)}
809
+ `}` + `${import_picocolors4.cyan(`${packageManager} dev`)}`;
810
+ var getDebugMessage = ({
811
+ response: {
812
+ projectName,
813
+ language,
814
+ codeQualityTool,
815
+ directoryConfig,
816
+ useTailwind,
817
+ tailwind,
818
+ frontends,
819
+ htmlScriptOption,
820
+ frontendDirectories,
821
+ buildDirectory,
822
+ assetsDirectory,
823
+ databaseEngine,
824
+ databaseHost,
825
+ databaseDirectory,
826
+ orm,
827
+ authProvider,
828
+ plugins,
829
+ initializeGitNow,
830
+ installDependenciesNow
831
+ },
832
+ packageManager
833
+ }) => {
834
+ const htmlLabels = {
835
+ js: import_picocolors4.yellow("JavaScript"),
836
+ none: import_picocolors4.dim("None"),
837
+ ts: import_picocolors4.blueBright("TypeScript")
838
+ };
839
+ const htmlScriptingValue = htmlScriptOption ? htmlLabels[htmlScriptOption] : import_picocolors4.dim("None");
840
+ const frameworkConfig = frontends.map((name) => `${frontendLabels[name]}: src/frontend/${frontendDirectories[name]}`).join(`
841
+ `);
842
+ const tailwindSection = useTailwind && tailwind ? `Input: ${tailwind.input}
843
+ Output: ${tailwind.output}` : import_picocolors4.dim("None");
844
+ const isCustomConfig = directoryConfig === "custom";
845
+ const lines = [
846
+ ["Project Name", projectName],
847
+ ["Package Manager", packageManager],
848
+ ["Config Type", isCustomConfig ? import_picocolors4.green("Custom") : import_picocolors4.dim("Default")],
849
+ ["Language", language === "ts" ? import_picocolors4.blueBright("TypeScript") : import_picocolors4.yellow("JavaScript")],
850
+ ["Linting", codeQualityTool === "eslint+prettier" ? "ESLint + Prettier" : "Biome"],
851
+ ["Tailwind Configuration", tailwindSection],
852
+ [frontends.length === 1 ? "Frontend" : "Frontends", frontends.map((name) => frontendLabels[name]).join(", ")],
853
+ ["HTML Scripting", frontends.includes("html") ? htmlScriptingValue : import_picocolors4.dim("None")],
854
+ ["Build Directory", buildDirectory],
855
+ ["Assets Directory", assetsDirectory],
856
+ ["Database Engine", databaseEngine && databaseEngine !== "none" ? databaseEngine : import_picocolors4.dim("None")],
857
+ ["Database Host", databaseHost && databaseHost !== "none" ? databaseHost : import_picocolors4.dim("None")],
858
+ ["Database Directory", databaseDirectory ?? import_picocolors4.dim("None")],
859
+ ["ORM", orm ?? import_picocolors4.dim("None")],
860
+ ["Auth Provider", authProvider && authProvider !== "none" ? authProvider : import_picocolors4.dim("None")],
861
+ ["Plugins", plugins.length && !plugins.includes("none") ? plugins.join(", ") : import_picocolors4.dim("None")],
862
+ ["Initialize Git", initializeGitNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")],
863
+ ["Install Dependencies", installDependenciesNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")],
864
+ ["Framework Config", frameworkConfig]
865
+ ];
866
+ const maxLabelLength = Math.max(...lines.map(([label]) => label.length));
867
+ const body = `
868
+
869
+ ${lines.map(([label, value]) => {
870
+ const gap = " ".repeat(maxLabelLength - label.length);
871
+ return `${import_picocolors4.magenta(label)}:${gap} ${value}`;
872
+ }).join(`
873
+ `)}`;
874
+ return body;
875
+ };
876
+
877
+ // node_modules/@clack/prompts/dist/index.mjs
878
+ var import_picocolors5 = __toESM(require_picocolors(), 1);
879
+ var import_sisteransi3 = __toESM(require_src(), 1);
880
+ import y3 from "node:process";
881
+ function ce2() {
882
+ return y3.platform !== "win32" ? y3.env.TERM !== "linux" : !!y3.env.CI || !!y3.env.WT_SESSION || !!y3.env.TERMINUS_SUBLIME || y3.env.ConEmuTask === "{cmd::Cmder}" || y3.env.TERM_PROGRAM === "Terminus-Sublime" || y3.env.TERM_PROGRAM === "vscode" || y3.env.TERM === "xterm-256color" || y3.env.TERM === "alacritty" || y3.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
883
+ }
884
+ var V3 = ce2();
885
+ var u2 = (t, n) => V3 ? t : n;
886
+ var le2 = u2("◆", "*");
887
+ var L3 = u2("■", "x");
888
+ var W3 = u2("▲", "x");
889
+ var C3 = u2("◇", "o");
890
+ var ue2 = u2("┌", "T");
891
+ var o2 = u2("│", "|");
892
+ var d3 = u2("└", "—");
893
+ var k3 = u2("●", ">");
894
+ var P3 = u2("○", " ");
895
+ var A3 = u2("◻", "[•]");
896
+ var T2 = u2("◼", "[+]");
897
+ var F2 = u2("◻", "[ ]");
898
+ var $e2 = u2("▪", "•");
899
+ var _3 = u2("─", "-");
900
+ var me2 = u2("╮", "+");
901
+ var de2 = u2("├", "+");
902
+ var pe2 = u2("╯", "+");
903
+ var q2 = u2("●", "•");
904
+ var D2 = u2("◆", "*");
905
+ var U2 = u2("▲", "!");
906
+ var K3 = u2("■", "x");
640
907
  var b2 = (t) => {
641
908
  switch (t) {
642
909
  case "initial":
643
910
  case "active":
644
- return import_picocolors2.default.cyan(le);
911
+ return import_picocolors5.default.cyan(le2);
645
912
  case "cancel":
646
- return import_picocolors2.default.red(L2);
913
+ return import_picocolors5.default.red(L3);
647
914
  case "error":
648
- return import_picocolors2.default.yellow(W2);
915
+ return import_picocolors5.default.yellow(W3);
649
916
  case "submit":
650
- return import_picocolors2.default.green(C2);
917
+ return import_picocolors5.default.green(C3);
651
918
  }
652
919
  };
653
920
  var G2 = (t) => {
@@ -657,45 +924,45 @@ var G2 = (t) => {
657
924
  const $2 = a < r.length && l2 > 0, g2 = a < r.length && l2 + a < r.length;
658
925
  return r.slice(l2, l2 + a).map((p2, v2, f) => {
659
926
  const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
660
- return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
927
+ return j2 || E ? import_picocolors5.default.dim("...") : i(p2, v2 + l2 === n);
661
928
  });
662
929
  };
663
930
  var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
664
- const n = `${import_picocolors2.default.gray(o)}
931
+ const n = `${import_picocolors5.default.gray(o2)}
665
932
  ${b2(this.state)} ${t.message}
666
- `, r = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r;
933
+ `, r = t.placeholder ? import_picocolors5.default.inverse(t.placeholder[0]) + import_picocolors5.default.dim(t.placeholder.slice(1)) : import_picocolors5.default.inverse(import_picocolors5.default.hidden("_")), i = this.value ? this.valueWithCursor : r;
667
934
  switch (this.state) {
668
935
  case "error":
669
936
  return `${n.trim()}
670
- ${import_picocolors2.default.yellow(o)} ${i}
671
- ${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(this.error)}
937
+ ${import_picocolors5.default.yellow(o2)} ${i}
938
+ ${import_picocolors5.default.yellow(d3)} ${import_picocolors5.default.yellow(this.error)}
672
939
  `;
673
940
  case "submit":
674
- return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(this.value || t.placeholder)}`;
941
+ return `${n}${import_picocolors5.default.gray(o2)} ${import_picocolors5.default.dim(this.value || t.placeholder)}`;
675
942
  case "cancel":
676
- return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
677
- ${import_picocolors2.default.gray(o)}` : ""}`;
943
+ return `${n}${import_picocolors5.default.gray(o2)} ${import_picocolors5.default.strikethrough(import_picocolors5.default.dim(this.value ?? ""))}${this.value?.trim() ? `
944
+ ${import_picocolors5.default.gray(o2)}` : ""}`;
678
945
  default:
679
- return `${n}${import_picocolors2.default.cyan(o)} ${i}
680
- ${import_picocolors2.default.cyan(d2)}
946
+ return `${n}${import_picocolors5.default.cyan(o2)} ${i}
947
+ ${import_picocolors5.default.cyan(d3)}
681
948
  `;
682
949
  }
683
950
  } }).prompt();
684
951
  var ye = (t) => {
685
952
  const n = t.active ?? "Yes", r = t.inactive ?? "No";
686
953
  return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
687
- const i = `${import_picocolors2.default.gray(o)}
954
+ const i = `${import_picocolors5.default.gray(o2)}
688
955
  ${b2(this.state)} ${t.message}
689
956
  `, s = this.value ? n : r;
690
957
  switch (this.state) {
691
958
  case "submit":
692
- return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
959
+ return `${i}${import_picocolors5.default.gray(o2)} ${import_picocolors5.default.dim(s)}`;
693
960
  case "cancel":
694
- return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
695
- ${import_picocolors2.default.gray(o)}`;
961
+ return `${i}${import_picocolors5.default.gray(o2)} ${import_picocolors5.default.strikethrough(import_picocolors5.default.dim(s))}
962
+ ${import_picocolors5.default.gray(o2)}`;
696
963
  default:
697
- return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r)}` : `${import_picocolors2.default.green(k2)} ${r}`}
698
- ${import_picocolors2.default.cyan(d2)}
964
+ return `${i}${import_picocolors5.default.cyan(o2)} ${this.value ? `${import_picocolors5.default.green(k3)} ${n}` : `${import_picocolors5.default.dim(P3)} ${import_picocolors5.default.dim(n)}`} ${import_picocolors5.default.dim("/")} ${this.value ? `${import_picocolors5.default.dim(P3)} ${import_picocolors5.default.dim(r)}` : `${import_picocolors5.default.green(k3)} ${r}`}
965
+ ${import_picocolors5.default.cyan(d3)}
699
966
  `;
700
967
  }
701
968
  } }).prompt();
@@ -705,29 +972,29 @@ var ve = (t) => {
705
972
  const s = r.label ?? String(r.value);
706
973
  switch (i) {
707
974
  case "selected":
708
- return `${import_picocolors2.default.dim(s)}`;
975
+ return `${import_picocolors5.default.dim(s)}`;
709
976
  case "active":
710
- return `${import_picocolors2.default.green(k2)} ${s} ${r.hint ? import_picocolors2.default.dim(`(${r.hint})`) : ""}`;
977
+ return `${import_picocolors5.default.green(k3)} ${s} ${r.hint ? import_picocolors5.default.dim(`(${r.hint})`) : ""}`;
711
978
  case "cancelled":
712
- return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
979
+ return `${import_picocolors5.default.strikethrough(import_picocolors5.default.dim(s))}`;
713
980
  default:
714
- return `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(s)}`;
981
+ return `${import_picocolors5.default.dim(P3)} ${import_picocolors5.default.dim(s)}`;
715
982
  }
716
983
  };
717
984
  return new LD({ options: t.options, initialValue: t.initialValue, render() {
718
- const r = `${import_picocolors2.default.gray(o)}
985
+ const r = `${import_picocolors5.default.gray(o2)}
719
986
  ${b2(this.state)} ${t.message}
720
987
  `;
721
988
  switch (this.state) {
722
989
  case "submit":
723
- return `${r}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
990
+ return `${r}${import_picocolors5.default.gray(o2)} ${n(this.options[this.cursor], "selected")}`;
724
991
  case "cancel":
725
- return `${r}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
726
- ${import_picocolors2.default.gray(o)}`;
992
+ return `${r}${import_picocolors5.default.gray(o2)} ${n(this.options[this.cursor], "cancelled")}
993
+ ${import_picocolors5.default.gray(o2)}`;
727
994
  default:
728
- return `${r}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
729
- ${import_picocolors2.default.cyan(o)} `)}
730
- ${import_picocolors2.default.cyan(d2)}
995
+ return `${r}${import_picocolors5.default.cyan(o2)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
996
+ ${import_picocolors5.default.cyan(o2)} `)}
997
+ ${import_picocolors5.default.cyan(d3)}
731
998
  `;
732
999
  }
733
1000
  } }).prompt();
@@ -735,14 +1002,14 @@ ${import_picocolors2.default.cyan(d2)}
735
1002
  var fe = (t) => {
736
1003
  const n = (r, i) => {
737
1004
  const s = r.label ?? String(r.value);
738
- return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r.hint ? import_picocolors2.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r.hint ? import_picocolors2.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r.hint ? import_picocolors2.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
1005
+ return i === "active" ? `${import_picocolors5.default.cyan(A3)} ${s} ${r.hint ? import_picocolors5.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors5.default.green(T2)} ${import_picocolors5.default.dim(s)} ${r.hint ? import_picocolors5.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors5.default.strikethrough(import_picocolors5.default.dim(s))}` : i === "active-selected" ? `${import_picocolors5.default.green(T2)} ${s} ${r.hint ? import_picocolors5.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors5.default.dim(s)}` : `${import_picocolors5.default.dim(F2)} ${import_picocolors5.default.dim(s)}`;
739
1006
  };
740
1007
  return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r) {
741
1008
  if (this.required && r.length === 0)
742
1009
  return `Please select at least one option.
743
- ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
1010
+ ${import_picocolors5.default.reset(import_picocolors5.default.dim(`Press ${import_picocolors5.default.gray(import_picocolors5.default.bgWhite(import_picocolors5.default.inverse(" space ")))} to select, ${import_picocolors5.default.gray(import_picocolors5.default.bgWhite(import_picocolors5.default.inverse(" enter ")))} to submit`))}`;
744
1011
  }, render() {
745
- const r = `${import_picocolors2.default.gray(o)}
1012
+ const r = `${import_picocolors5.default.gray(o2)}
746
1013
  ${b2(this.state)} ${t.message}
747
1014
  `, i = (s, c) => {
748
1015
  const a = this.value.includes(s.value);
@@ -750,43 +1017,37 @@ ${b2(this.state)} ${t.message}
750
1017
  };
751
1018
  switch (this.state) {
752
1019
  case "submit":
753
- return `${r}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
1020
+ return `${r}${import_picocolors5.default.gray(o2)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors5.default.dim(", ")) || import_picocolors5.default.dim("none")}`;
754
1021
  case "cancel": {
755
- const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
756
- return `${r}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
757
- ${import_picocolors2.default.gray(o)}` : ""}`;
1022
+ const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors5.default.dim(", "));
1023
+ return `${r}${import_picocolors5.default.gray(o2)} ${s.trim() ? `${s}
1024
+ ${import_picocolors5.default.gray(o2)}` : ""}`;
758
1025
  }
759
1026
  case "error": {
760
1027
  const s = this.error.split(`
761
- `).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
1028
+ `).map((c, a) => a === 0 ? `${import_picocolors5.default.yellow(d3)} ${import_picocolors5.default.yellow(c)}` : ` ${c}`).join(`
762
1029
  `);
763
- return `${r + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
764
- ${import_picocolors2.default.yellow(o)} `)}
1030
+ return `${r + import_picocolors5.default.yellow(o2)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
1031
+ ${import_picocolors5.default.yellow(o2)} `)}
765
1032
  ${s}
766
1033
  `;
767
1034
  }
768
1035
  default:
769
- return `${r}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
770
- ${import_picocolors2.default.cyan(o)} `)}
771
- ${import_picocolors2.default.cyan(d2)}
1036
+ return `${r}${import_picocolors5.default.cyan(o2)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
1037
+ ${import_picocolors5.default.cyan(o2)} `)}
1038
+ ${import_picocolors5.default.cyan(d3)}
772
1039
  `;
773
1040
  }
774
1041
  } }).prompt();
775
1042
  };
776
1043
  var xe = (t = "") => {
777
- process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
1044
+ process.stdout.write(`${import_picocolors5.default.gray(d3)} ${import_picocolors5.default.red(t)}
778
1045
 
779
1046
  `);
780
1047
  };
781
- var Se = (t = "") => {
782
- process.stdout.write(`${import_picocolors2.default.gray(o)}
783
- ${import_picocolors2.default.gray(d2)} ${t}
784
-
785
- `);
786
- };
787
- var J2 = `${import_picocolors2.default.gray(o)} `;
1048
+ var J3 = `${import_picocolors5.default.gray(o2)} `;
788
1049
  var Y2 = ({ indicator: t = "dots" } = {}) => {
789
- const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r = V2 ? 80 : 120, i = process.env.CI === "true";
1050
+ const n = V3 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r = V3 ? 80 : 120, i = process.env.CI === "true";
790
1051
  let s, c, a = false, l2 = "", $2, g2 = performance.now();
791
1052
  const p2 = (m2) => {
792
1053
  const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
@@ -802,19 +1063,19 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
802
1063
  `);
803
1064
  const m2 = $2.split(`
804
1065
  `);
805
- process.stdout.write(import_sisteransi2.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(m2.length));
1066
+ process.stdout.write(import_sisteransi3.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi3.erase.down(m2.length));
806
1067
  }, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
807
1068
  const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
808
1069
  return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
809
1070
  }, H2 = (m2 = "") => {
810
- a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
1071
+ a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors5.default.gray(o2)}
811
1072
  `);
812
1073
  let h2 = 0, w2 = 0;
813
1074
  j2(), c = setInterval(() => {
814
1075
  if (i && l2 === $2)
815
1076
  return;
816
1077
  B2(), $2 = l2;
817
- const I2 = import_picocolors2.default.magenta(n[h2]);
1078
+ const I2 = import_picocolors5.default.magenta(n[h2]);
818
1079
  if (i)
819
1080
  process.stdout.write(`${I2} ${l2}...`);
820
1081
  else if (t === "timer")
@@ -827,7 +1088,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
827
1088
  }, r);
828
1089
  }, N2 = (m2 = "", h2 = 0) => {
829
1090
  a = false, clearInterval(c), B2();
830
- const w2 = h2 === 0 ? import_picocolors2.default.green(C2) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
1091
+ const w2 = h2 === 0 ? import_picocolors5.default.green(C3) : h2 === 1 ? import_picocolors5.default.red(L3) : import_picocolors5.default.red(W3);
831
1092
  l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
832
1093
  `) : process.stdout.write(`${w2} ${l2}
833
1094
  `), E(), s();
@@ -837,186 +1098,8 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
837
1098
  } };
838
1099
  };
839
1100
 
840
- // src/constants.ts
841
- var UNFOUND_INDEX = -1;
842
- var DEFAULT_ARG_LENGTH = 2;
843
- var TWO_THIRDS = 2 / 3;
844
-
845
- // src/data.ts
846
- var import_picocolors3 = __toESM(require_picocolors(), 1);
847
- var availableFrontends = {
848
- react: { label: import_picocolors3.cyan("React"), name: "React" },
849
- html: { label: "HTML", name: "HTML" },
850
- angular: { label: import_picocolors3.red("Angular"), name: "Angular" },
851
- vue: { label: import_picocolors3.green("Vue"), name: "Vue" },
852
- svelte: { label: import_picocolors3.magenta("Svelte"), name: "Svelte" },
853
- htmx: { label: "HTMX", name: "HTMX" },
854
- solid: { label: import_picocolors3.blueBright("Solid"), name: "Solid" }
855
- };
856
- var availablePlugins = [
857
- {
858
- imports: [{ config: null, isPlugin: true, packageName: "cors" }],
859
- label: import_picocolors3.cyan("⚙️ @elysiajs/cors"),
860
- latestVersion: "1.3.3",
861
- value: "@elysiajs/cors"
862
- },
863
- {
864
- imports: [{ config: null, isPlugin: true, packageName: "swagger" }],
865
- label: import_picocolors3.cyan("\uD83D\uDCD1 @elysiajs/swagger"),
866
- latestVersion: "1.3.0",
867
- value: "@elysiajs/swagger"
868
- },
869
- {
870
- imports: [{ config: null, isPlugin: true, packageName: "rateLimit" }],
871
- label: import_picocolors3.green("\uD83D\uDEE0️ elysia-rate-limit"),
872
- latestVersion: "4.3.0",
873
- value: "elysia-rate-limit"
874
- }
875
- ];
876
- var absoluteAuthPlugin = {
877
- imports: [
878
- {
879
- config: { providersConfiguration: {} },
880
- isPlugin: true,
881
- packageName: "absoluteAuth"
882
- }
883
- ],
884
- latestVersion: "0.3.2",
885
- value: "@absolutejs/auth"
886
- };
887
- var eslintAndPrettierDependencies = [
888
- {
889
- latestVersion: "9.27.0",
890
- value: "eslint"
891
- },
892
- {
893
- latestVersion: "3.5.3",
894
- value: "prettier"
895
- }
896
- ];
897
- var defaultDependencies = [
898
- {
899
- imports: [{ isPlugin: false, packageName: "Elysia" }],
900
- latestVersion: "1.3.1",
901
- value: "elysia"
902
- }
903
- ];
904
- var defaultPlugins = [
905
- {
906
- imports: [
907
- { isPlugin: false, packageName: "build" },
908
- { isPlugin: true, packageName: "networkingPlugin" }
909
- ],
910
- latestVersion: "0.6.0",
911
- value: "@absolutejs/absolute"
912
- },
913
- {
914
- imports: [
915
- {
916
- config: { assets: "./build", prefix: "" },
917
- isPlugin: true,
918
- packageName: "staticPlugin"
919
- }
920
- ],
921
- latestVersion: "1.3.0",
922
- value: "@elysiajs/static"
923
- }
924
- ];
925
-
926
- // src/messages.ts
927
- var import_picocolors4 = __toESM(require_picocolors(), 1);
928
- var helpMessage = `
929
- Usage: create-absolute [options] [dir]
930
-
931
- Arguments:
932
- dir The name of the created application.
933
- If not specified, the user will be prompted during creation.
934
-
935
- Options:
936
- -h, --help Show this help message and exit
937
- -d, --debug Show a summary of the project configuration after creation
938
- -l, --latest Fetch and use the latest version of required packages
939
- `;
940
- var getOutroMessage = ({
941
- projectName,
942
- packageManager,
943
- installDependenciesNow
944
- }) => `${import_picocolors4.green("Created successfully")}, you can now run:
945
-
946
- ` + `${import_picocolors4.cyan("cd")} ${projectName}
947
- ` + `${import_picocolors4.cyan(`${packageManager} dev`)}${installDependenciesNow ? "" : `
948
- ${import_picocolors4.cyan(`${packageManager} install`)}`}`;
949
- var getDebugMessage = ({
950
- response: {
951
- projectName,
952
- language,
953
- codeQualityTool,
954
- configType,
955
- useTailwind,
956
- tailwind,
957
- frontends,
958
- htmlScriptOption,
959
- frontendConfigurations,
960
- buildDirectory,
961
- assetsDirectory,
962
- databaseEngine,
963
- databaseHost,
964
- databaseDirectory,
965
- orm,
966
- authProvider,
967
- plugins,
968
- initializeGitNow,
969
- installDependenciesNow
970
- },
971
- packageManager,
972
- availableFrontends: availableFrontends2
973
- }) => {
974
- const htmlLabels = {
975
- js: import_picocolors4.yellow("JavaScript"),
976
- "js+ssr": import_picocolors4.yellow("JavaScript + SSR"),
977
- ts: import_picocolors4.blueBright("TypeScript"),
978
- "ts+ssr": import_picocolors4.blueBright("TypeScript + SSR")
979
- };
980
- const htmlScriptingValue = htmlScriptOption !== undefined ? htmlLabels[htmlScriptOption] : import_picocolors4.dim("None");
981
- const htmlScriptingLine = frontends.includes("html") ? `
982
- ${import_picocolors4.magenta("HTML Scripting")}: ${htmlScriptingValue}` : "";
983
- const frontendLabels = frontends.map((name) => availableFrontends2[name]?.label ?? name);
984
- const frontendHeading = frontends.length === 1 ? import_picocolors4.magenta("Frontend") : import_picocolors4.magenta("Frontends");
985
- const configString = frontendConfigurations.reduce((acc, { name, directory }, idx, arr) => {
986
- const label = availableFrontends2[name]?.label ?? name;
987
- const segment = `${label}: src/frontend/${directory}${idx < arr.length - 1 ? `
988
- ` : ""}`;
989
- return acc + segment;
990
- }, "");
991
- const tailwindSection = tailwind && useTailwind ? `
992
- ${import_picocolors4.cyan("Input")}: ${tailwind.input}
993
- ${import_picocolors4.cyan("Output")}: ${tailwind.output}` : import_picocolors4.dim("None");
994
- return `
995
- ${import_picocolors4.magenta("Project Name")}: ${projectName}
996
- ${import_picocolors4.magenta("Package Manager")}: ${packageManager}
997
- ${import_picocolors4.magenta("Config Type")}: ${configType === "custom" ? import_picocolors4.green("Custom") : import_picocolors4.dim("Default")}
998
- ${import_picocolors4.magenta("Language")}: ${language === "ts" ? import_picocolors4.blueBright("TypeScript") : import_picocolors4.yellow("JavaScript")}
999
- ${import_picocolors4.magenta("Linting")}: ${codeQualityTool === "eslint+prettier" ? "ESLint + Prettier" : "Biome"}
1000
- ${import_picocolors4.magenta("Tailwind Configuration")}: ${tailwindSection}
1001
- ${frontendHeading}: ${frontendLabels.join(", ")}${htmlScriptingLine}
1002
- ${import_picocolors4.magenta("Build Directory")}: ${buildDirectory}
1003
- ${import_picocolors4.magenta("Assets Directory")}: ${assetsDirectory}
1004
- ${import_picocolors4.magenta("Database Engine")}: ${databaseEngine ?? import_picocolors4.dim("None")}
1005
- ${import_picocolors4.magenta("Database Host")}: ${databaseHost ?? import_picocolors4.dim("None")}
1006
- ${import_picocolors4.magenta("Database Directory")}: ${databaseDirectory ?? import_picocolors4.dim("None")}
1007
- ${import_picocolors4.magenta("ORM")}: ${orm ?? import_picocolors4.dim("None")}
1008
- ${import_picocolors4.magenta("Authorization Provider")}: ${authProvider ?? import_picocolors4.dim("None")}
1009
- ${import_picocolors4.magenta("Plugins")}: ${plugins.length ? plugins.join(", ") : import_picocolors4.dim("None")}
1010
- ${import_picocolors4.magenta("Initialize Git")}: ${initializeGitNow ? import_picocolors4.green("Yes") : import_picocolors4.dim("No")}
1011
- ${import_picocolors4.magenta("Install Dependencies")}: ${installDependenciesNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")}
1012
- ${import_picocolors4.magenta("Framework Config")}:
1013
- ${configString}
1014
-
1015
- `;
1016
- };
1017
-
1018
1101
  // src/questions/authProvider.ts
1019
- var import_picocolors5 = __toESM(require_picocolors(), 1);
1102
+ var import_picocolors6 = __toESM(require_picocolors(), 1);
1020
1103
 
1021
1104
  // src/utils/abort.ts
1022
1105
  import { exit } from "node:process";
@@ -1031,7 +1114,7 @@ var getAuthProvider = async () => {
1031
1114
  message: "Auth provider:",
1032
1115
  options: [
1033
1116
  { label: "None", value: "none" },
1034
- { label: import_picocolors5.cyan("Absolute Auth"), value: "absoluteAuth" }
1117
+ { label: import_picocolors6.cyan("Absolute Auth"), value: "absoluteAuth" }
1035
1118
  ]
1036
1119
  });
1037
1120
  if (pD(authProvider))
@@ -1040,16 +1123,16 @@ var getAuthProvider = async () => {
1040
1123
  };
1041
1124
 
1042
1125
  // src/questions/codeQualityTool.ts
1043
- var import_picocolors6 = __toESM(require_picocolors(), 1);
1126
+ var import_picocolors7 = __toESM(require_picocolors(), 1);
1044
1127
  var getCodeQualityTool = async () => {
1045
1128
  const codeQualityTool = await ve({
1046
1129
  message: "Choose linting and formatting tool:",
1047
1130
  options: [
1048
1131
  {
1049
- label: import_picocolors6.blueBright("ESLint + Prettier"),
1132
+ label: import_picocolors7.blueBright("ESLint + Prettier"),
1050
1133
  value: "eslint+prettier"
1051
1134
  },
1052
- { label: import_picocolors6.yellow("Biome"), value: "biome" }
1135
+ { label: import_picocolors7.yellow("Biome"), value: "biome" }
1053
1136
  ]
1054
1137
  });
1055
1138
  if (pD(codeQualityTool))
@@ -1058,35 +1141,35 @@ var getCodeQualityTool = async () => {
1058
1141
  };
1059
1142
 
1060
1143
  // src/questions/configurationType.ts
1061
- var import_picocolors7 = __toESM(require_picocolors(), 1);
1144
+ var import_picocolors8 = __toESM(require_picocolors(), 1);
1062
1145
  var getConfigurationType = async () => {
1063
- const configType = await ve({
1146
+ const directoryConfig = await ve({
1064
1147
  message: "Choose folder naming configuration:",
1065
1148
  options: [
1066
- { label: import_picocolors7.blueBright("Default"), value: "default" },
1067
- { label: import_picocolors7.yellow("Custom"), value: "custom" }
1149
+ { label: import_picocolors8.blueBright("Default"), value: "default" },
1150
+ { label: import_picocolors8.yellow("Custom"), value: "custom" }
1068
1151
  ]
1069
1152
  });
1070
- if (pD(configType))
1153
+ if (pD(directoryConfig))
1071
1154
  abort();
1072
- return configType;
1155
+ return directoryConfig;
1073
1156
  };
1074
1157
 
1075
1158
  // src/questions/databaseEngine.ts
1076
- var import_picocolors8 = __toESM(require_picocolors(), 1);
1159
+ var import_picocolors9 = __toESM(require_picocolors(), 1);
1077
1160
  var getDatabaseEngine = async () => {
1078
1161
  const databaseDialectResponse = await ve({
1079
1162
  message: "Database engine:",
1080
1163
  options: [
1081
1164
  { label: "None", value: "none" },
1082
- { label: import_picocolors8.cyan("PostgreSQL"), value: "postgresql" },
1083
- { label: import_picocolors8.magenta("SQLite"), value: "sqlite" },
1084
- { label: import_picocolors8.green("MySQL"), value: "mysql" },
1085
- { label: import_picocolors8.red("Redis"), value: "redis" },
1086
- { label: import_picocolors8.green("MongoDB"), value: "mongodb" },
1087
- { label: import_picocolors8.magenta("SingleStore"), value: "singlestore" },
1088
- { label: import_picocolors8.yellow("SQL Server"), value: "mssql" },
1089
- { label: import_picocolors8.cyan("CockroachDB"), value: "cockroachdb" }
1165
+ { label: import_picocolors9.cyan("PostgreSQL"), value: "postgresql" },
1166
+ { label: import_picocolors9.magenta("SQLite"), value: "sqlite" },
1167
+ { label: import_picocolors9.green("MySQL"), value: "mysql" },
1168
+ { label: import_picocolors9.red("Redis"), value: "redis" },
1169
+ { label: import_picocolors9.green("MongoDB"), value: "mongodb" },
1170
+ { label: import_picocolors9.magenta("SingleStore"), value: "singlestore" },
1171
+ { label: import_picocolors9.yellow("SQL Server"), value: "mssql" },
1172
+ { label: import_picocolors9.cyan("CockroachDB"), value: "cockroachdb" }
1090
1173
  ]
1091
1174
  });
1092
1175
  if (pD(databaseDialectResponse))
@@ -1095,14 +1178,14 @@ var getDatabaseEngine = async () => {
1095
1178
  };
1096
1179
 
1097
1180
  // src/questions/databaseHost.ts
1098
- var import_picocolors9 = __toESM(require_picocolors(), 1);
1181
+ var import_picocolors10 = __toESM(require_picocolors(), 1);
1099
1182
  var getDatabaseHost = async (databaseEngine) => {
1100
1183
  if (databaseEngine === "postgresql") {
1101
1184
  const databaseHost = await ve({
1102
1185
  message: "Select database host:",
1103
1186
  options: [
1104
- { label: import_picocolors9.cyan("Neon"), value: "neon" },
1105
- { label: import_picocolors9.cyan("Supabase"), value: "supabase" },
1187
+ { label: import_picocolors10.cyan("Neon"), value: "neon" },
1188
+ { label: import_picocolors10.cyan("Supabase"), value: "supabase" },
1106
1189
  { label: "None", value: "none" }
1107
1190
  ]
1108
1191
  });
@@ -1147,28 +1230,29 @@ var getDatabaseHost = async (databaseEngine) => {
1147
1230
 
1148
1231
  // src/questions/directoryConfiguration.ts
1149
1232
  var getDirectoryConfiguration = async ({
1150
- configType,
1233
+ directoryConfig,
1151
1234
  useTailwind,
1152
- databaseEngine
1235
+ databaseEngine,
1236
+ argumentConfiguration
1153
1237
  }) => {
1154
- if (configType === "default") {
1238
+ if (directoryConfig === "default") {
1155
1239
  return {
1156
- assetsDirectory: "src/backend/assets",
1157
- buildDirectory: "build",
1158
- databaseDirectory: databaseEngine && "db",
1240
+ assetsDirectory: argumentConfiguration.assetsDirectory ?? "src/backend/assets",
1241
+ buildDirectory: argumentConfiguration.buildDirectory ?? "build",
1242
+ databaseDirectory: databaseEngine ? argumentConfiguration.databaseDirectory ?? "db" : undefined,
1159
1243
  tailwind: useTailwind ? {
1160
- input: "./src/frontend/styles/tailwind.css",
1161
- output: "/assets/css/tailwind.generated.css"
1244
+ input: argumentConfiguration.tailwind?.input ?? "./src/frontend/styles/tailwind.css",
1245
+ output: argumentConfiguration.tailwind?.output ?? "/assets/css/tailwind.generated.css"
1162
1246
  } : undefined
1163
1247
  };
1164
1248
  }
1165
- const buildDirectory = await he({
1249
+ const buildDirectory = argumentConfiguration.buildDirectory ?? await he({
1166
1250
  message: "Build directory:",
1167
1251
  placeholder: "build"
1168
1252
  });
1169
1253
  if (pD(buildDirectory))
1170
1254
  abort();
1171
- const assetsDirectory = await he({
1255
+ const assetsDirectory = argumentConfiguration.assetsDirectory ?? await he({
1172
1256
  message: "Assets directory:",
1173
1257
  placeholder: "src/backend/assets"
1174
1258
  });
@@ -1176,13 +1260,13 @@ var getDirectoryConfiguration = async ({
1176
1260
  abort();
1177
1261
  let tailwind;
1178
1262
  if (useTailwind) {
1179
- const input = await he({
1263
+ const input = argumentConfiguration.tailwind?.input ?? await he({
1180
1264
  message: "Tailwind input CSS file:",
1181
1265
  placeholder: "./src/frontend/styles/tailwind.css"
1182
1266
  });
1183
1267
  if (pD(input))
1184
1268
  abort();
1185
- const output = await he({
1269
+ const output = argumentConfiguration.tailwind?.output ?? await he({
1186
1270
  message: "Tailwind output CSS file:",
1187
1271
  placeholder: "/assets/css/tailwind.generated.css"
1188
1272
  });
@@ -1194,7 +1278,7 @@ var getDirectoryConfiguration = async ({
1194
1278
  }
1195
1279
  let databaseDirectory;
1196
1280
  if (databaseEngine !== undefined) {
1197
- databaseDirectory = await he({
1281
+ databaseDirectory = argumentConfiguration.databaseDirectory ?? await he({
1198
1282
  message: "Database directory:",
1199
1283
  placeholder: "db"
1200
1284
  });
@@ -1210,62 +1294,66 @@ var getDirectoryConfiguration = async ({
1210
1294
  };
1211
1295
 
1212
1296
  // src/questions/frontendDirectoryConfigurations.ts
1213
- var getFrontendDirectoryConfigurations = async (configType, frontends) => {
1214
- let frontendConfigurations;
1215
- const single = frontends.length === 1;
1216
- if (configType === "custom") {
1217
- frontendConfigurations = await frontends.reduce(async (prevP, frontend) => {
1218
- const prev = await prevP;
1219
- const pretty = availableFrontends[frontend]?.name ?? frontend;
1220
- const base = single ? "" : `${frontend}`;
1221
- const defDir = base;
1222
- const frontendDirectory = await he({
1223
- message: `${pretty} directory:`,
1224
- placeholder: defDir
1225
- });
1226
- if (pD(frontendDirectory))
1227
- abort();
1228
- return [
1229
- ...prev,
1230
- { directory: frontendDirectory, frontend, name: frontend }
1231
- ];
1232
- }, Promise.resolve([]));
1233
- } else {
1234
- frontendConfigurations = frontends.map((frontend) => ({
1235
- directory: single ? "" : frontend,
1236
- frontend,
1237
- name: frontend
1238
- }));
1239
- }
1240
- return frontendConfigurations;
1297
+ var getDirectoryForFrontend = async (directoryConfiguration, frontend, isSingleFrontend) => {
1298
+ if (directoryConfiguration !== "custom")
1299
+ return isSingleFrontend ? "" : frontend;
1300
+ const response = await he({
1301
+ message: `${frontendLabels[frontend]} directory:`,
1302
+ placeholder: isSingleFrontend ? "" : frontend
1303
+ });
1304
+ if (pD(response))
1305
+ abort();
1306
+ return response;
1241
1307
  };
1308
+ var getFrontendDirectoryConfigurations = async (directoryConfiguration, frontends, passedFrontendDirectories) => {
1309
+ const isSingleFrontend = frontends.length === 1;
1310
+ const frontendDirectories = {};
1311
+ const frontendsToPrompt = [];
1312
+ for (const frontend of frontends) {
1313
+ const prefilled = passedFrontendDirectories?.[frontend];
1314
+ if (prefilled === undefined)
1315
+ frontendsToPrompt.push(frontend);
1316
+ else
1317
+ frontendDirectories[frontend] = prefilled;
1318
+ }
1319
+ const promptedDirectories = await Promise.all(frontendsToPrompt.map((name) => getDirectoryForFrontend(directoryConfiguration, name, isSingleFrontend)));
1320
+ frontendsToPrompt.forEach((name, index) => frontendDirectories[name] = promptedDirectories[index]);
1321
+ return frontendDirectories;
1322
+ };
1323
+
1324
+ // src/typeGuards.ts
1325
+ var isLanguage = (value) => value === "ts" || value === "js";
1326
+ var isAuthProvider = (value) => value === "absoluteAuth" || value === "none" || value === undefined;
1327
+ var isDirectoryConfig = (value) => value === "default" || value === "custom";
1328
+ var isDatabaseEngine = (value) => value === "postgresql" || value === "mysql" || value === "sqlite" || value === "mongodb" || value === "redis" || value === "singlestore" || value === "cockroachdb" || value === "mssql" || value === "none" || value === undefined;
1329
+ var isDatabaseHost = (value) => value === "neon" || value === "planetscale" || value === "supabase" || value === "turso" || value === "vercel" || value === "upstash" || value === "atlas" || value === undefined;
1330
+ var isORM = (value) => value === "drizzle" || value === "prisma" || value === undefined;
1331
+ var isCodeQualityTool = (value) => value === "eslint+prettier" || value === "biome" || value === undefined;
1332
+ var isHTMLScriptOption = (value) => value === "ts" || value === "js" || value === "ts+ssr" || value === "js+ssr" || value === "none" || value === undefined;
1333
+ var isFrontend = (value) => value !== undefined && Object.keys(frontendLabels).includes(value);
1242
1334
 
1243
1335
  // src/questions/frontends.ts
1244
1336
  var getFrontends = async () => {
1245
1337
  const frontends = await fe({
1246
1338
  message: "Frontend(s) (space to select, enter to finish):",
1247
- options: Object.entries(availableFrontends).map(([value, { label }]) => ({ label, value }))
1339
+ options: Object.entries(frontendLabels).map(([value, label]) => ({
1340
+ label,
1341
+ value
1342
+ }))
1248
1343
  });
1249
1344
  if (pD(frontends))
1250
1345
  abort();
1251
- return frontends;
1346
+ return frontends.filter(isFrontend);
1252
1347
  };
1253
1348
 
1254
1349
  // src/questions/htmlScriptingOption.ts
1255
- var import_picocolors10 = __toESM(require_picocolors(), 1);
1256
1350
  var getHtmlScriptingOption = async (language) => {
1257
- const langLabel = language === "ts" ? import_picocolors10.blueBright("TypeScript") : import_picocolors10.yellow("JavaScript");
1258
- const htmlScriptOption = await ve({
1259
- message: `Add HTML scripting option (${langLabel}):`,
1260
- options: [
1261
- { label: `${langLabel} + SSR`, value: `${language}+ssr` },
1262
- { label: langLabel, value: language },
1263
- { label: "None", value: "none" }
1264
- ]
1351
+ const useScripts = await ye({
1352
+ message: "Would you like to use scripts for your HTML pages?"
1265
1353
  });
1266
- if (pD(htmlScriptOption))
1354
+ if (pD(useScripts))
1267
1355
  abort();
1268
- return htmlScriptOption === "none" ? undefined : htmlScriptOption;
1356
+ return useScripts ? language : undefined;
1269
1357
  };
1270
1358
 
1271
1359
  // src/questions/initializeGitNow.ts
@@ -1351,37 +1439,40 @@ var getUseTailwind = async () => {
1351
1439
  };
1352
1440
 
1353
1441
  // src/prompt.ts
1354
- var prompt = async () => {
1355
- const projectName = await getProjectName();
1356
- const language = await getLanguage();
1357
- const codeQualityTool = await getCodeQualityTool();
1358
- const useTailwind = await getUseTailwind();
1359
- const frontends = await getFrontends();
1360
- const htmlScriptOption = frontends.includes("html") ? await getHtmlScriptingOption(language) : undefined;
1361
- const databaseEngine = await getDatabaseEngine();
1362
- const databaseHost = await getDatabaseHost(databaseEngine);
1363
- const orm = databaseEngine !== undefined ? await getORM() : undefined;
1364
- const configType = await getConfigurationType();
1442
+ var prompt = async (argumentConfiguration) => {
1443
+ const projectName = argumentConfiguration.projectName ?? await getProjectName();
1444
+ const language = argumentConfiguration.language ?? await getLanguage();
1445
+ const codeQualityTool = argumentConfiguration.codeQualityTool ?? await getCodeQualityTool();
1446
+ const useTailwind = argumentConfiguration.useTailwind ?? await getUseTailwind();
1447
+ const frontends = argumentConfiguration.frontends?.filter((frontend) => frontend !== undefined) ?? await getFrontends();
1448
+ const htmlScriptOption = !frontends.includes("html") || argumentConfiguration.htmlScriptOption === "none" ? undefined : argumentConfiguration.htmlScriptOption ?? await getHtmlScriptingOption(language);
1449
+ const databaseEngine = argumentConfiguration.databaseEngine ?? await getDatabaseEngine();
1450
+ const databaseHost = argumentConfiguration.databaseHost ?? await getDatabaseHost(databaseEngine);
1451
+ const orm = databaseEngine !== undefined && databaseEngine !== "none" ? argumentConfiguration.orm ?? await getORM() : undefined;
1452
+ let directoryConfig = argumentConfiguration.directoryConfig ?? await getConfigurationType();
1365
1453
  const { buildDirectory, assetsDirectory, tailwind, databaseDirectory } = await getDirectoryConfiguration({
1366
- configType,
1454
+ argumentConfiguration,
1367
1455
  databaseEngine,
1456
+ directoryConfig,
1368
1457
  useTailwind
1369
1458
  });
1370
- const frontendConfigurations = await getFrontendDirectoryConfigurations(configType, frontends);
1371
- const authProvider = await getAuthProvider();
1372
- const plugins = await getPlugins();
1373
- const initializeGitNow = await getInitializeGit();
1374
- const installDependenciesNow = await getInstallDependencies();
1459
+ const frontendDirectories = await getFrontendDirectoryConfigurations(directoryConfig, frontends, argumentConfiguration.frontendDirectories);
1460
+ if (argumentConfiguration.frontendDirectories !== undefined)
1461
+ directoryConfig = "custom";
1462
+ const authProvider = argumentConfiguration.authProvider ?? await getAuthProvider();
1463
+ const plugins = argumentConfiguration.plugins?.filter((plugin) => plugin !== undefined) ?? await getPlugins();
1464
+ const initializeGitNow = argumentConfiguration.initializeGitNow ?? await getInitializeGit();
1465
+ const installDependenciesNow = argumentConfiguration.installDependenciesNow ?? await getInstallDependencies();
1375
1466
  const values = {
1376
1467
  assetsDirectory,
1377
1468
  authProvider,
1378
1469
  buildDirectory,
1379
1470
  codeQualityTool,
1380
- configType,
1381
1471
  databaseDirectory,
1382
1472
  databaseEngine,
1383
1473
  databaseHost,
1384
- frontendConfigurations,
1474
+ directoryConfig,
1475
+ frontendDirectories,
1385
1476
  frontends,
1386
1477
  htmlScriptOption,
1387
1478
  initializeGitNow,
@@ -1398,7 +1489,7 @@ var prompt = async () => {
1398
1489
 
1399
1490
  // src/scaffold.ts
1400
1491
  import { copyFileSync as copyFileSync4 } from "node:fs";
1401
- import { join as join9, dirname } from "node:path";
1492
+ import { join as join10, dirname } from "node:path";
1402
1493
  import { fileURLToPath } from "node:url";
1403
1494
 
1404
1495
  // src/commands/formatProject.ts
@@ -1461,13 +1552,32 @@ var installDependencies = async ({
1461
1552
 
1462
1553
  // src/generators/configurations/addConfigurationFiles.ts
1463
1554
  var import_picocolors15 = __toESM(require_picocolors(), 1);
1464
- import { copyFileSync } from "fs";
1555
+ import { copyFileSync, writeFileSync } from "fs";
1465
1556
  import { join } from "path";
1557
+
1558
+ // src/generators/configurations/generatePrettierrc.ts
1559
+ var generatePrettierrc = (frontends) => {
1560
+ const usesSvelte = frontends.some((frontend) => frontend === "svelte");
1561
+ return `{
1562
+ "endOfLine": "auto",
1563
+ "printWidth": 80,
1564
+ "semi": true,
1565
+ "singleQuote": true,
1566
+ "tabWidth": 4,
1567
+ "trailingComma": "none",
1568
+ "useTabs": true
1569
+ ${usesSvelte ? `,"plugins": ["prettier-plugin-svelte"],
1570
+ "overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]` : ""}
1571
+ }`;
1572
+ };
1573
+
1574
+ // src/generators/configurations/addConfigurationFiles.ts
1466
1575
  var addConfigurationFiles = ({
1467
1576
  tailwind,
1468
1577
  templatesDirectory,
1469
1578
  language,
1470
1579
  codeQualityTool,
1580
+ frontends,
1471
1581
  initializeGitNow,
1472
1582
  projectName
1473
1583
  }) => {
@@ -1482,14 +1592,15 @@ var addConfigurationFiles = ({
1482
1592
  if (codeQualityTool === "eslint+prettier") {
1483
1593
  copyFileSync(join(templatesDirectory, "configurations", "eslint.config.mjs"), join(projectName, "eslint.config.mjs"));
1484
1594
  copyFileSync(join(templatesDirectory, "configurations", ".prettierignore"), join(projectName, ".prettierignore"));
1485
- copyFileSync(join(templatesDirectory, "configurations", ".prettierrc.json"), join(projectName, ".prettierrc.json"));
1595
+ const prettierrc = generatePrettierrc(frontends);
1596
+ writeFileSync(join(projectName, ".prettierrc.json"), prettierrc);
1486
1597
  } else
1487
1598
  console.warn(`${import_picocolors15.dim("│")}
1488
1599
  ${import_picocolors15.yellow("▲")} Biome support not implemented yet`);
1489
1600
  };
1490
1601
 
1491
- // src/generators/configurations/createPackageJson.ts
1492
- import { writeFileSync } from "fs";
1602
+ // src/generators/configurations/generatePackageJson.ts
1603
+ import { writeFileSync as writeFileSync2 } from "fs";
1493
1604
  import { join as join2 } from "path";
1494
1605
  var import_picocolors16 = __toESM(require_picocolors(), 1);
1495
1606
 
@@ -1506,14 +1617,14 @@ var getPackageVersion = (packageName) => {
1506
1617
  }
1507
1618
  };
1508
1619
 
1509
- // src/generators/configurations/createPackageJson.ts
1620
+ // src/generators/configurations/generatePackageJson.ts
1510
1621
  var createPackageJson = ({
1511
1622
  projectName,
1512
1623
  authProvider,
1513
1624
  plugins,
1514
1625
  useTailwind,
1515
1626
  latest,
1516
- frontendConfigurations,
1627
+ frontendDirectories,
1517
1628
  codeQualityTool
1518
1629
  }) => {
1519
1630
  const s = Y2();
@@ -1521,6 +1632,8 @@ var createPackageJson = ({
1521
1632
  const resolveVersion = (name, listed) => latest ? getPackageVersion(name) ?? listed : listed;
1522
1633
  const dependencies = {};
1523
1634
  const devDependencies = {};
1635
+ const usesReact = frontendDirectories["react"] !== undefined;
1636
+ const usesSvelte = frontendDirectories["svelte"] !== undefined;
1524
1637
  for (const p2 of defaultPlugins) {
1525
1638
  dependencies[p2.value] = resolveVersion(p2.value, p2.latestVersion);
1526
1639
  }
@@ -1544,16 +1657,20 @@ var createPackageJson = ({
1544
1657
  devDependencies["tailwindcss"] = resolveVersion("tailwindcss", "4.1.7");
1545
1658
  devDependencies["@tailwindcss/cli"] = resolveVersion("@tailwindcss/cli", "4.1.7");
1546
1659
  }
1547
- if (frontendConfigurations.some((f) => f.name === "react")) {
1660
+ if (usesReact) {
1548
1661
  dependencies["react"] = resolveVersion("react", "19.1.0");
1549
1662
  dependencies["react-dom"] = resolveVersion("react-dom", "19.1.0");
1550
1663
  devDependencies["@types/react"] = resolveVersion("@types/react", "19.1.5");
1551
1664
  devDependencies["@types/react-dom"] = resolveVersion("@types/react-dom", "19.1.5");
1552
1665
  }
1666
+ if (usesSvelte) {
1667
+ dependencies["svelte"] = resolveVersion("svelte", "5.34.7");
1668
+ codeQualityTool === "eslint+prettier" && (devDependencies["prettier-plugin-svelte"] = resolveVersion("prettier-plugin-svelte", "3.4.0"));
1669
+ }
1553
1670
  latest && s.stop(import_picocolors16.green("Package versions resolved"));
1554
1671
  const scripts = {
1555
1672
  dev: "bun run src/backend/server.ts",
1556
- format: 'prettier --write "./**/*.{js,jsx,ts,tsx,css,json,mjs,md}"',
1673
+ format: `prettier --write "./**/*.{js,ts,css,json,mjs,md${usesReact ? ",jsx,tsx" : ""}${usesSvelte ? ",svelte" : ""}}"`,
1557
1674
  lint: "eslint ./src",
1558
1675
  test: 'echo "Error: no test specified" && exit 1',
1559
1676
  typecheck: "bun run tsc --noEmit"
@@ -1566,7 +1683,7 @@ var createPackageJson = ({
1566
1683
  type: "module",
1567
1684
  version: "0.1.0"
1568
1685
  };
1569
- writeFileSync(join2(projectName, "package.json"), JSON.stringify(packageJson));
1686
+ writeFileSync2(join2(projectName, "package.json"), JSON.stringify(packageJson));
1570
1687
  };
1571
1688
 
1572
1689
  // src/generators/configurations/initializeRoot.ts
@@ -1596,8 +1713,8 @@ var import_picocolors17 = __toESM(require_picocolors(), 1);
1596
1713
  import { mkdirSync as mkdirSync2 } from "fs";
1597
1714
  import { join as join5 } from "path";
1598
1715
 
1599
- // src/generators/configurations/createDrizzleConfig.ts
1600
- import { writeFileSync as writeFileSync2 } from "fs";
1716
+ // src/generators/configurations/generateDrizzleConfig.ts
1717
+ import { writeFileSync as writeFileSync3 } from "fs";
1601
1718
  import { join as join4 } from "path";
1602
1719
  var createDrizzleConfig = ({
1603
1720
  projectName,
@@ -1609,7 +1726,7 @@ var createDrizzleConfig = ({
1609
1726
  dialect: '${databaseEngine}'
1610
1727
  });
1611
1728
  `;
1612
- writeFileSync2(join4(projectName, "drizzle.config.ts"), drizzleConfig);
1729
+ writeFileSync3(join4(projectName, "drizzle.config.ts"), drizzleConfig);
1613
1730
  };
1614
1731
 
1615
1732
  // src/generators/db/scaffoldDatabase.ts
@@ -1620,20 +1737,31 @@ var scaffoldDatabase = ({
1620
1737
  orm
1621
1738
  }) => {
1622
1739
  mkdirSync2(join5(projectName, databaseDirectory), { recursive: true });
1623
- if (databaseEngine !== "postgresql") {
1740
+ if (databaseEngine !== "postgresql" && databaseEngine !== "none") {
1624
1741
  console.warn(`${import_picocolors17.dim("│")}
1625
1742
  ${import_picocolors17.yellow("▲")} Only PostgreSQL support is implemented so far`);
1626
1743
  }
1627
1744
  if (orm === "drizzle") {
1628
1745
  createDrizzleConfig({ databaseEngine, projectName });
1629
1746
  }
1747
+ if (orm === "prisma") {
1748
+ console.warn(`${import_picocolors17.dim("│")}
1749
+ ${import_picocolors17.yellow("▲")} Prisma support is not implemented yet`);
1750
+ }
1630
1751
  };
1631
1752
 
1632
- // src/generators/project/createServer.ts
1633
- import { writeFileSync as writeFileSync3 } from "fs";
1753
+ // src/generators/project/generateServer.ts
1754
+ import { writeFileSync as writeFileSync4 } from "fs";
1755
+
1756
+ // src/constants.ts
1757
+ var UNFOUND_INDEX = -1;
1758
+ var DEFAULT_ARG_LENGTH = 2;
1759
+ var TWO_THIRDS = 2 / 3;
1760
+
1761
+ // src/generators/project/generateServer.ts
1634
1762
  var createServerFile = ({
1635
1763
  tailwind,
1636
- frontendConfigurations,
1764
+ frontendDirectories,
1637
1765
  serverFilePath,
1638
1766
  authProvider,
1639
1767
  availablePlugins: availablePlugins2,
@@ -1641,200 +1769,208 @@ var createServerFile = ({
1641
1769
  assetsDirectory,
1642
1770
  plugins
1643
1771
  }) => {
1644
- const requiresHtml = frontendConfigurations.some((configuration) => configuration.name === "html");
1645
- const requiresReact = frontendConfigurations.some((configuration) => configuration.name === "react");
1646
- const isSingleFrontend = frontendConfigurations.length === 1;
1647
- const selectedCustomPlugins = availablePlugins2.filter((plugin) => plugins.indexOf(plugin.value) !== UNFOUND_INDEX);
1648
- const authenticationPlugins = [];
1649
- if (authProvider === "absoluteAuth") {
1650
- authenticationPlugins.push(absoluteAuthPlugin);
1651
- }
1652
- const combinedDependencies = [
1772
+ const htmlDirectory = frontendDirectories["html"];
1773
+ const reactDirectory = frontendDirectories["react"];
1774
+ const svelteDirectory = frontendDirectories["svelte"];
1775
+ const requiresHtml = htmlDirectory !== undefined;
1776
+ const requiresReact = reactDirectory !== undefined;
1777
+ const requiresSvelte = svelteDirectory !== undefined;
1778
+ const selectedCustomPlugins = availablePlugins2.filter(({ value }) => plugins.indexOf(value) !== UNFOUND_INDEX);
1779
+ const authenticationPlugins = authProvider === "absoluteAuth" ? [absoluteAuthPlugin] : [];
1780
+ const allDependencies = [
1653
1781
  ...defaultDependencies,
1654
1782
  ...defaultPlugins,
1655
1783
  ...selectedCustomPlugins,
1656
1784
  ...authenticationPlugins
1657
1785
  ];
1658
- const uniqueDependencies = [];
1659
- combinedDependencies.forEach((dependency) => {
1660
- if (!uniqueDependencies.some((existingDependency) => existingDependency.value === dependency.value)) {
1661
- uniqueDependencies.push(dependency);
1662
- }
1663
- });
1664
- uniqueDependencies.sort((firstDependency, secondDependency) => firstDependency.value.localeCompare(secondDependency.value));
1665
- const importLines = uniqueDependencies.flatMap((dependency) => {
1666
- const importsArray = dependency.imports ?? [];
1667
- return importsArray.length > 0 ? [
1668
- `import { ${importsArray.map((importEntry) => importEntry.packageName).join(", ")} } from '${dependency.value}';`
1669
- ] : [];
1670
- });
1671
- const absoluteImportLineIndex = importLines.findIndex((importLine) => importLine.includes("from '@absolutejs/absolute'"));
1672
- if (absoluteImportLineIndex >= 0) {
1673
- const originalImportLine = importLines[absoluteImportLineIndex];
1674
- importLines[absoluteImportLineIndex] = originalImportLine.replace(/import\s*\{([\s\S]*?)\}\s*from '@absolutejs\/absolute';/, (_fullMatch, importList) => {
1675
- const importedItems = importList.split(",").map((item) => item.trim()).filter(Boolean);
1676
- if (requiresHtml && !importedItems.includes("handleHTMLPageRequest")) {
1677
- importedItems.push("handleHTMLPageRequest");
1678
- }
1679
- if (requiresReact && !importedItems.includes("handleReactPageRequest")) {
1680
- importedItems.push("handleReactPageRequest");
1681
- }
1682
- return `import { ${importedItems.join(", ")} } from '@absolutejs/absolute';`;
1683
- });
1684
- }
1685
- if (requiresReact) {
1686
- const reactImportSource = isSingleFrontend ? "../frontend/pages/ReactExample" : "../frontend/react/pages/ReactExample";
1786
+ const uniqueDependencies = Array.from(new Map(allDependencies.map((dependency) => [dependency.value, dependency])).values()).sort((a, b3) => a.value.localeCompare(b3.value));
1787
+ const importLines = uniqueDependencies.flatMap(({ value, imports }) => imports && imports.length > 0 ? [
1788
+ `import { ${imports.map(({ packageName }) => packageName).join(", ")} } from '${value}';`
1789
+ ] : []);
1790
+ const absoluteImportIdx = importLines.findIndex((line) => line.includes("from '@absolutejs/absolute'"));
1791
+ if (absoluteImportIdx !== UNFOUND_INDEX && importLines[absoluteImportIdx]) {
1792
+ const existingItems = importLines[absoluteImportIdx].replace(/import\s*\{\s*|\}\s*from.*$/g, "").split(",").map((item) => item.trim()).filter((value) => value.length > 0);
1793
+ const additionalItems = [
1794
+ requiresHtml && !existingItems.includes("handleHTMLPageRequest") && "handleHTMLPageRequest",
1795
+ requiresReact && !existingItems.includes("handleReactPageRequest") && "handleReactPageRequest",
1796
+ requiresSvelte && !existingItems.includes("handleSveltePageRequest") && "handleSveltePageRequest"
1797
+ ].filter((value) => typeof value === "string");
1798
+ importLines[absoluteImportIdx] = `import { ${[...existingItems, ...additionalItems].join(", ")} } from '@absolutejs/absolute';`;
1799
+ }
1800
+ if (reactDirectory !== undefined) {
1801
+ const reactImportSource = reactDirectory === "" ? "../frontend/pages/ReactExample" : `../frontend/${reactDirectory}/pages/ReactExample`;
1687
1802
  importLines.push(`import { ReactExample } from '${reactImportSource}';`);
1688
1803
  }
1689
- const useStatements = uniqueDependencies.flatMap((dependency) => dependency.imports).filter((importEntry) => importEntry?.isPlugin).map((importEntry) => {
1690
- if (importEntry?.config === undefined) {
1691
- return `.use(${importEntry?.packageName})`;
1692
- }
1693
- if (importEntry.config === null) {
1694
- return `.use(${importEntry.packageName}())`;
1695
- }
1696
- return `.use(${importEntry.packageName}(${JSON.stringify(importEntry.config)}))`;
1804
+ if (requiresSvelte) {
1805
+ const svelteImportSource = svelteDirectory === "" ? "../frontend/pages/SvelteExample" : `../frontend/${svelteDirectory}/pages/SvelteExample`;
1806
+ importLines.push(`import SvelteExample from '${svelteImportSource}.svelte';`);
1807
+ }
1808
+ const useStatements = uniqueDependencies.flatMap(({ imports }) => imports ?? []).filter((entry) => entry.isPlugin).map((entry) => {
1809
+ if (entry.config === undefined)
1810
+ return `.use(${entry.packageName})`;
1811
+ if (entry.config === null)
1812
+ return `.use(${entry.packageName}())`;
1813
+ return `.use(${entry.packageName}(${JSON.stringify(entry.config)}))`;
1697
1814
  });
1698
1815
  const manifestOptions = [
1699
- `buildDirectory: '${buildDirectory}'`,
1700
1816
  `assetsDirectory: '${assetsDirectory}'`,
1701
- ...frontendConfigurations.map((configuration) => configuration.directory ? `${configuration.name}Directory: './src/frontend/${configuration.directory}'` : `${configuration.name}Directory: './src/frontend/'`).filter((option) => option !== ""),
1817
+ `buildDirectory: '${buildDirectory}'`,
1818
+ ...Object.entries(frontendDirectories).map(([frameworkName, directory]) => `${frameworkName}Directory: './src/frontend/${directory}'`),
1702
1819
  tailwind ? `tailwind: ${JSON.stringify(tailwind)}` : ""
1703
- ];
1704
- const buildStatement = `const manifest = await build({
1820
+ ].filter(Boolean);
1821
+ const manifestDeclaration = `const manifest = await build({
1705
1822
  ${manifestOptions.join(`,
1706
1823
  `)}
1707
1824
  });`;
1708
- let guardStatements = `if (manifest === null) throw new Error('Manifest was not generated');`;
1709
- if (requiresReact) {
1710
- guardStatements += `
1711
- const { ReactExampleIndex } = manifest;
1712
- if (ReactExampleIndex === undefined) throw new Error('ReactExampleIndex was not generated');`;
1713
- }
1714
- let routeDefinitions = "";
1715
- frontendConfigurations.forEach((configuration, index) => {
1716
- const routePath = index === 0 ? "/" : `/${configuration.name}`;
1717
- if (configuration.name === "html") {
1718
- routeDefinitions += `
1719
- .get('${routePath}', () =>
1720
- handleHTMLPageRequest(\`${buildDirectory}/html/pages/HtmlExample.html\`)
1721
- )`;
1722
- } else if (configuration.name === "react") {
1723
- routeDefinitions += `
1724
- .get('${routePath}', () =>
1725
- handleReactPageRequest(ReactExample, ReactExampleIndex)
1726
- )`;
1825
+ const guardStatements = [
1826
+ `if (manifest === null) throw new Error('Manifest was not generated');`,
1827
+ requiresReact ? `const { ReactExampleIndex } = manifest;
1828
+ if (ReactExampleIndex === undefined) throw new Error('ReactExampleIndex was not generated');` : ""
1829
+ ].filter(Boolean).join(`
1830
+ `);
1831
+ const routes = Object.entries(frontendDirectories).map(([frameworkName, directory], index) => {
1832
+ const routePath = index === 0 ? "/" : `/${frameworkName}`;
1833
+ if (frameworkName === "html") {
1834
+ return `.get('${routePath}', () => handleHTMLPageRequest(\`${buildDirectory}/${directory}/pages/HTMLExample.html\`))`;
1727
1835
  }
1728
- });
1729
- let serverFileContent = `${importLines.join(`
1836
+ if (frameworkName === "react") {
1837
+ return `.get('${routePath}', () => handleReactPageRequest(ReactExample, ReactExampleIndex))`;
1838
+ }
1839
+ if (frameworkName === "svelte") {
1840
+ return `.get('${routePath}', () => handleSveltePageRequest(SvelteExample, manifest))`;
1841
+ }
1842
+ return "";
1843
+ }).filter(Boolean).join(`
1844
+ `);
1845
+ const serverFileContent = `${importLines.join(`
1730
1846
  `)}
1731
1847
 
1732
- ${buildStatement}
1848
+ ${manifestDeclaration}
1733
1849
 
1734
1850
  ${guardStatements}
1735
1851
 
1736
- new Elysia()${routeDefinitions}`;
1737
- useStatements.forEach((statement) => {
1738
- serverFileContent += `
1739
- ${statement}`;
1740
- });
1741
- serverFileContent += `
1742
- .on('error', (error) => {
1743
- const { request } = error;
1744
- console.error(\`Server error on \${request.method} \${request.url}: \${error.message}\`);
1852
+ new Elysia()${routes}
1853
+ ${useStatements.map((s) => ` ${s}`).join(`
1854
+ `)}
1855
+ .on('error', (err) => {
1856
+ const { request } = err;
1857
+ console.error(\`Server error on \${request.method} \${request.url}: \${err.message}\`);
1745
1858
  });
1746
1859
  `;
1747
- writeFileSync3(serverFilePath, serverFileContent);
1860
+ writeFileSync4(serverFilePath, serverFileContent);
1748
1861
  };
1749
1862
 
1750
1863
  // src/generators/project/scaffoldFrontends.ts
1751
- import { copyFileSync as copyFileSync3, mkdirSync as mkdirSync5 } from "node:fs";
1752
- import { join as join8 } from "node:path";
1864
+ import { copyFileSync as copyFileSync3, mkdirSync as mkdirSync6 } from "node:fs";
1865
+ import { join as join9 } from "node:path";
1753
1866
 
1754
1867
  // src/generators/html/scaffoldHTML.ts
1755
- import { cpSync as cpSync2, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
1868
+ import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync5 } from "fs";
1756
1869
  import { join as join6 } from "path";
1757
1870
 
1758
- // src/generators/html/getSSRScript.ts
1759
- var getSSRScript = (language, isSingle) => `import { HOURS_IN_DAY, TWO_THIRDS } from '${!isSingle ? "../" : ""}../../constants';
1760
-
1761
- document.addEventListener('DOMContentLoaded', () => {
1762
- const greeting = document.getElementById('greeting');
1763
- const date = new Date();
1764
- const hours = date.getHours();
1765
-
1766
- if (greeting === null) {
1767
- throw new Error('Greeting element not found');
1768
- }
1769
-
1770
- if (hours < HOURS_IN_DAY / 2) {
1771
- greeting.textContent = 'Good Morning, welcome to AbsoluteJS !';
1772
- } else if (hours < HOURS_IN_DAY * TWO_THIRDS) {
1773
- greeting.textContent = 'Good Afternoon, welcome to AbsoluteJS !';
1774
- } else {
1775
- greeting.textContent = 'Good Evening, welcome to AbsoluteJS !';
1776
- }
1777
-
1778
- const button = document.getElementById('counter-button');
1779
- const counter = document.getElementById('counter');
1780
- let count = 0;
1781
-
1782
- if (button === null || counter === null) {
1783
- throw new Error('Button or counter element not found');
1784
- }
1871
+ // src/generators/html/generateHTMLPage.ts
1872
+ var generateHTMLPage = (htmlScriptOption) => {
1873
+ let scriptTag = "";
1874
+ if (htmlScriptOption === "js") {
1875
+ scriptTag = `<script src="/html/scripts/javascriptExample.js"></script>`;
1876
+ } else if (htmlScriptOption === "ts") {
1877
+ scriptTag = `<script src="/html/scripts/typescriptExample.ts"></script>`;
1878
+ }
1879
+ return `<!DOCTYPE html>
1880
+ <html>
1881
+ <head>
1882
+ <title>Html Home</title>
1883
+ <link rel="stylesheet" type="text/css" href="/assets/css/HtmlHome.css">
1884
+ <link rel="icon" href="/assets/ico/favicon.ico" />
1885
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
1886
+ </head>
1887
+ <body>
1888
+ <header>
1889
+ <img id="logo" src="/assets/svg/brand_logo.svg" alt="AbsoluteJS Logo">
1890
+ <h1 id="greeting"></h1>
1891
+ </header>
1892
+ <main>
1893
+ <p>Welcome to AbsoluteJS, the next generation JavaScript framework. We're glad you're here.</p>
1894
+ <button id="counter-button">Click me!</button>
1895
+ <p id="counter">0</p>
1896
+ <nav id="links">
1897
+ <a href="/react" id="react-link">React</a>
1898
+ <a href="/vue" id="vue-link">Vue</a>
1899
+ <a href="/angular" id="angular-link">Angular</a>
1900
+ <a href="/svelte" id="svelte-link">Svelte</a>
1901
+ <a href="/ember" id="ember-link">Ember</a>
1902
+ <a href="/htmx" id="htmx-link">HTMX</a>
1903
+ </nav>
1904
+ </main>
1905
+ <footer>
1906
+ <p id="footer-text"></p>
1907
+ </footer>${scriptTag ? `
1908
+ ${scriptTag}` : ""}
1909
+ </body>
1910
+ </html>`;
1911
+ };
1785
1912
 
1786
- button.addEventListener('click', () => {
1787
- count++;
1788
- counter.textContent = count.toString();
1789
- });
1913
+ // src/generators/html/generateHTMLScript.ts
1914
+ var getHTMLScript = (htmlScriptOption, isSingleFrontend) => `import { HOURS_IN_DAY, TWO_THIRDS } from '${!isSingleFrontend ? "../" : ""}../../constants';
1790
1915
 
1791
- const links = document.querySelectorAll${language === "ts" && "<HTMLAnchorElement>"}('#links a');
1792
- links.forEach((link) => {
1793
- link.addEventListener('mouseover', () => {
1794
- link.style.transform = 'scale(1.2)';
1795
- });
1796
- link.addEventListener('mouseout', () => {
1797
- link.style.transform = 'scale(1)';
1798
- });
1799
- });
1916
+ const greeting = document.getElementById('greeting');
1917
+ const date = new Date();
1918
+ const hours = date.getHours();
1919
+ if (!greeting) throw new Error('Greeting element not found');
1800
1920
 
1801
- const footerText = document.getElementById('footer-text');
1921
+ if (hours < HOURS_IN_DAY / 2) {
1922
+ greeting.textContent = 'Good Morning, welcome to AbsoluteJS !';
1923
+ } else if (hours < HOURS_IN_DAY * TWO_THIRDS) {
1924
+ greeting.textContent = 'Good Afternoon, welcome to AbsoluteJS !';
1925
+ } else {
1926
+ greeting.textContent = 'Good Evening, welcome to AbsoluteJS !';
1927
+ }
1802
1928
 
1803
- if (footerText === null) {
1804
- throw new Error('Footer text element not found');
1805
- }
1929
+ const button = document.getElementById('counter-button');
1930
+ const counter = document.getElementById('counter');
1931
+ if (!button || !counter) throw new Error('Button or counter element not found');
1932
+ let count = 0;
1933
+ button.addEventListener('click', () => {
1934
+ count++;
1935
+ counter.textContent = count.toString();
1936
+ });
1806
1937
 
1807
- footerText.textContent = \`© ${new Date().getFullYear()} AbsoluteJS\`;
1938
+ const links = document.querySelectorAll${htmlScriptOption === "ts" ? "<HTMLAnchorElement>" : ""}('#links a');
1939
+ links.forEach((link) => {
1940
+ link.addEventListener('mouseover', () => link.style.transform = 'scale(1.2)');
1941
+ link.addEventListener('mouseout', () => link.style.transform = 'scale(1)');
1808
1942
  });
1943
+
1944
+ const footerText = document.getElementById('footer-text');
1945
+ if (!footerText) throw new Error('Footer text element not found');
1946
+ footerText.textContent = \`© ${new Date().getFullYear()} AbsoluteJS\`;
1809
1947
  `;
1810
1948
 
1811
1949
  // src/generators/html/scaffoldHTML.ts
1812
1950
  var scaffoldHTML = ({
1813
- templatesDirectory,
1814
- isSingle,
1951
+ isSingleFrontend,
1815
1952
  targetDirectory,
1816
- htmlScriptOption,
1817
- language
1953
+ htmlScriptOption
1818
1954
  }) => {
1819
- const htmlTemplates = join6(templatesDirectory, "html");
1820
- cpSync2(join6(htmlTemplates, "pages"), join6(targetDirectory, "pages"), {
1821
- recursive: true
1822
- });
1823
- const scriptsDir = join6(targetDirectory, "scripts");
1824
- mkdirSync3(scriptsDir);
1825
- if (htmlScriptOption?.includes("ssr")) {
1826
- const ssrScript = getSSRScript(language, isSingle);
1827
- const ssrFileName = language === "ts" ? "typescriptSSRExample.ts" : "javascriptSSRExample.js";
1828
- writeFileSync4(join6(scriptsDir, ssrFileName), ssrScript);
1955
+ const htmlPage = generateHTMLPage(htmlScriptOption);
1956
+ const htmlPagesDirectory = join6(targetDirectory, "pages");
1957
+ mkdirSync3(htmlPagesDirectory, { recursive: true });
1958
+ writeFileSync5(join6(htmlPagesDirectory, "HTMLExample.html"), htmlPage);
1959
+ if (htmlScriptOption !== undefined && htmlScriptOption !== "none") {
1960
+ const scriptsDir = join6(targetDirectory, "scripts");
1961
+ mkdirSync3(scriptsDir, { recursive: true });
1962
+ const script = getHTMLScript(htmlScriptOption, isSingleFrontend);
1963
+ const scriptFileName = htmlScriptOption === "ts" ? "typescriptExample.ts" : "javascriptExample.js";
1964
+ writeFileSync5(join6(scriptsDir, scriptFileName), script);
1829
1965
  }
1830
1966
  };
1831
1967
 
1832
1968
  // src/generators/react/scaffoldReact.ts
1833
- import { cpSync as cpSync3, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
1969
+ import { cpSync as cpSync2, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
1834
1970
  import { join as join7 } from "node:path";
1835
1971
 
1836
1972
  // src/generators/react/generateHeadComponent.ts
1837
- var generateHeadComponent = (isSingle) => `import { styleReset } from '${isSingle ? "../../styles" : "../../../styles/react"}/defaultStyles';
1973
+ var generateHeadComponent = (isSingleFrontend) => `import { styleReset } from '${isSingleFrontend ? "../../styles" : "../../../styles/react"}/defaultStyles';
1838
1974
 
1839
1975
  type HeadProps = {
1840
1976
  title?: string;
@@ -1869,13 +2005,13 @@ export const Head = ({
1869
2005
  `;
1870
2006
 
1871
2007
  // src/generators/react/generateReactPage.ts
1872
- var generateReactPage = (isSingle) => `import { useState } from 'react';
2008
+ var generateReactPage = (isSingleFrontend) => `import { useState } from 'react';
1873
2009
  import { Head } from '../components/utils/Head';
1874
2010
  import {
1875
2011
  bodyDefault,
1876
2012
  htmlDefault,
1877
2013
  mainDefault
1878
- } from '${isSingle ? "../styles" : "../../styles/react"}/defaultStyles';
2014
+ } from '${isSingleFrontend ? "../styles" : "../../styles/react"}/defaultStyles';
1879
2015
 
1880
2016
  export const ReactExample = () => {
1881
2017
  const [count, setCount] = useState(0);
@@ -1956,7 +2092,7 @@ export const ReactExample = () => {
1956
2092
  fontFamily: 'monospace'
1957
2093
  }}
1958
2094
  >
1959
- src/frontend/${isSingle ? "" : "react"}/pages/ReactExample.tsx
2095
+ src/frontend/${isSingleFrontend ? "" : "react"}/pages/ReactExample.tsx
1960
2096
  </code>{' '}
1961
2097
  to edit this page
1962
2098
  </p>
@@ -1972,77 +2108,136 @@ export const ReactExample = () => {
1972
2108
  var scaffoldReact = ({
1973
2109
  stylesDirectory,
1974
2110
  templatesDirectory,
1975
- isSingle,
2111
+ isSingleFrontend,
1976
2112
  targetDirectory
1977
2113
  }) => {
1978
2114
  const reactStylesSrc = join7(templatesDirectory, "react", "styles");
1979
2115
  const reactTemplates = join7(templatesDirectory, "react");
1980
2116
  const pagesDirectory = join7(targetDirectory, "pages");
1981
2117
  const componentsDirectory = join7(targetDirectory, "components");
1982
- const pageExample = generateReactPage(isSingle);
1983
- const headComponent = generateHeadComponent(isSingle);
1984
- mkdirSync4(pagesDirectory);
1985
- writeFileSync5(join7(pagesDirectory, "ReactExample.tsx"), pageExample);
2118
+ const pageExample = generateReactPage(isSingleFrontend);
2119
+ const headComponent = generateHeadComponent(isSingleFrontend);
2120
+ mkdirSync4(pagesDirectory, { recursive: true });
2121
+ writeFileSync6(join7(pagesDirectory, "ReactExample.tsx"), pageExample);
1986
2122
  mkdirSync4(join7(componentsDirectory, "utils"), { recursive: true });
1987
- writeFileSync5(join7(componentsDirectory, "utils", "Head.tsx"), headComponent);
1988
- cpSync3(join7(reactTemplates, "hooks"), join7(targetDirectory, "hooks"), {
2123
+ writeFileSync6(join7(componentsDirectory, "utils", "Head.tsx"), headComponent);
2124
+ cpSync2(join7(reactTemplates, "hooks"), join7(targetDirectory, "hooks"), {
1989
2125
  recursive: true
1990
2126
  });
1991
- if (isSingle) {
1992
- cpSync3(reactStylesSrc, stylesDirectory, {
2127
+ if (isSingleFrontend) {
2128
+ cpSync2(reactStylesSrc, stylesDirectory, {
1993
2129
  recursive: true
1994
2130
  });
1995
2131
  } else {
1996
2132
  const dest = join7(stylesDirectory, "react");
1997
- mkdirSync4(dest);
1998
- cpSync3(reactStylesSrc, dest, {
2133
+ mkdirSync4(dest, { recursive: true });
2134
+ cpSync2(reactStylesSrc, dest, {
1999
2135
  recursive: true
2000
2136
  });
2001
2137
  }
2002
2138
  };
2003
2139
 
2140
+ // src/generators/svelte/scaffoldSvelte.ts
2141
+ import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
2142
+ import { join as join8 } from "node:path";
2143
+
2144
+ // src/generators/svelte/generateSveltePage.ts
2145
+ var generateSveltePage = (language) => {
2146
+ const scriptTag = language === "ts" ? `<script lang="ts">` : `<script>`;
2147
+ return `${scriptTag}
2148
+ let count = $state(0);
2149
+
2150
+ const year = new Date().getFullYear();
2151
+ </script>
2152
+
2153
+ <svelte:head>
2154
+ <meta charset="utf-8" />
2155
+ <title>Svelte Home</title>
2156
+ <meta name="description" content="Welcome to AbsoluteJS" />
2157
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
2158
+ <link rel="icon" href="/assets/ico/favicon.ico" />
2159
+ </svelte:head>
2160
+
2161
+ <main>
2162
+ <header><h1>This page was built with Svelte</h1></header>
2163
+
2164
+ <p>Welcome to the Svelte home page. This page was built using Svelte.</p>
2165
+
2166
+ <p>Counter: {count}</p>
2167
+ <button onclick={() => (count += 1)}>Increment</button>
2168
+
2169
+ <div id="links">
2170
+ <a href="/">Html</a>
2171
+ <a href="/vue">Vue</a>
2172
+ </div>
2173
+
2174
+ <footer><p>© {year} AbsoluteJS</p></footer>
2175
+ </main>
2176
+ `;
2177
+ };
2178
+
2179
+ // src/generators/svelte/scaffoldSvelte.ts
2180
+ var scaffoldSvelte = ({
2181
+ targetDirectory,
2182
+ language
2183
+ }) => {
2184
+ const pageExample = generateSveltePage(language);
2185
+ const pagesDirectory = join8(targetDirectory, "pages");
2186
+ const componentsDirectory = join8(targetDirectory, "components");
2187
+ mkdirSync5(pagesDirectory, { recursive: true });
2188
+ writeFileSync7(join8(pagesDirectory, "SvelteExample.svelte"), pageExample);
2189
+ mkdirSync5(join8(componentsDirectory), { recursive: true });
2190
+ };
2191
+
2004
2192
  // src/generators/project/scaffoldFrontends.ts
2005
2193
  var scaffoldFrontends = ({
2006
2194
  frontendDirectory,
2007
- language,
2008
2195
  templatesDirectory,
2009
- frontendConfigurations,
2196
+ frontendDirectories,
2197
+ language,
2010
2198
  tailwind,
2011
2199
  htmlScriptOption
2012
2200
  }) => {
2013
- const isSingle = frontendConfigurations.length === 1;
2014
- const stylesDirectory = join8(frontendDirectory, "styles");
2015
- mkdirSync5(stylesDirectory);
2016
- if (tailwind !== undefined) {
2017
- copyFileSync3(join8(templatesDirectory, "tailwind", "tailwind.css"), join8(stylesDirectory, "tailwind.css"));
2018
- }
2019
- const dirMap = new Map;
2020
- frontendConfigurations.forEach(({ name, directory }) => {
2021
- const dir = directory?.trim() ?? (isSingle ? "" : name);
2022
- if (dirMap.has(dir)) {
2023
- throw new Error(`Frontend directory collision: "${dir}" is assigned to both "${dirMap.get(dir)}" and "${name}". Please pick unique directories.`);
2201
+ const frontendEntries = Object.entries(frontendDirectories);
2202
+ const isSingleFrontend = frontendEntries.length === 1;
2203
+ const stylesDirectory = join9(frontendDirectory, "styles");
2204
+ const needsStylesDir = !(isSingleFrontend && frontendEntries[0]?.[0] === "svelte");
2205
+ if (needsStylesDir)
2206
+ mkdirSync6(stylesDirectory);
2207
+ if (needsStylesDir && tailwind !== undefined) {
2208
+ copyFileSync3(join9(templatesDirectory, "tailwind", "tailwind.css"), join9(stylesDirectory, "tailwind.css"));
2209
+ }
2210
+ const directoryMap = new Map;
2211
+ for (const [frontendName, rawDirectory] of frontendEntries) {
2212
+ const directory = rawDirectory?.trim() ?? (isSingleFrontend ? "" : frontendName);
2213
+ if (directoryMap.has(directory)) {
2214
+ throw new Error(`Frontend directory collision: "${directory}" is assigned to both "${directoryMap.get(directory)}" and "${frontendName}". Please pick unique directories.`);
2024
2215
  }
2025
- dirMap.set(dir, name);
2026
- const targetDirectory = join8(frontendDirectory, dir);
2027
- !isSingle && mkdirSync5(targetDirectory);
2028
- if (name === "react") {
2029
- scaffoldReact({
2030
- isSingle,
2031
- stylesDirectory,
2032
- targetDirectory,
2033
- templatesDirectory
2034
- });
2035
- }
2036
- if (name === "html") {
2037
- scaffoldHTML({
2038
- htmlScriptOption,
2039
- isSingle,
2040
- language,
2041
- targetDirectory,
2042
- templatesDirectory
2043
- });
2216
+ directoryMap.set(directory, frontendName);
2217
+ const targetDirectory = join9(frontendDirectory, directory);
2218
+ if (!isSingleFrontend)
2219
+ mkdirSync6(targetDirectory);
2220
+ switch (frontendName) {
2221
+ case "react":
2222
+ scaffoldReact({
2223
+ isSingleFrontend,
2224
+ stylesDirectory,
2225
+ targetDirectory,
2226
+ templatesDirectory
2227
+ });
2228
+ break;
2229
+ case "svelte":
2230
+ scaffoldSvelte({ language, targetDirectory });
2231
+ break;
2232
+ case "html":
2233
+ scaffoldHTML({
2234
+ htmlScriptOption,
2235
+ isSingleFrontend,
2236
+ targetDirectory
2237
+ });
2238
+ break;
2044
2239
  }
2045
- });
2240
+ }
2046
2241
  };
2047
2242
 
2048
2243
  // src/scaffold.ts
@@ -2053,28 +2248,29 @@ var scaffold = ({
2053
2248
  codeQualityTool,
2054
2249
  initializeGitNow,
2055
2250
  databaseEngine,
2056
- databaseHost,
2057
2251
  htmlScriptOption,
2058
2252
  useTailwind,
2059
2253
  databaseDirectory,
2060
2254
  orm,
2255
+ frontends,
2061
2256
  plugins,
2062
2257
  authProvider,
2063
2258
  buildDirectory,
2064
2259
  assetsDirectory,
2065
2260
  tailwind,
2066
2261
  installDependenciesNow,
2067
- frontendConfigurations
2262
+ frontendDirectories
2068
2263
  },
2069
2264
  latest,
2070
2265
  packageManager
2071
2266
  }) => {
2072
2267
  const __dirname2 = dirname(fileURLToPath(import.meta.url));
2073
- const templatesDirectory = join9(__dirname2, "/templates");
2268
+ const templatesDirectory = join10(__dirname2, "/templates");
2074
2269
  const { frontendDirectory, backendDirectory } = initalizeRoot(projectName, templatesDirectory);
2075
- copyFileSync4(join9(templatesDirectory, "README.md"), join9(projectName, "README.md"));
2270
+ copyFileSync4(join10(templatesDirectory, "README.md"), join10(projectName, "README.md"));
2076
2271
  addConfigurationFiles({
2077
2272
  codeQualityTool,
2273
+ frontends,
2078
2274
  initializeGitNow,
2079
2275
  language,
2080
2276
  projectName,
@@ -2084,19 +2280,19 @@ var scaffold = ({
2084
2280
  createPackageJson({
2085
2281
  authProvider,
2086
2282
  codeQualityTool,
2087
- frontendConfigurations,
2283
+ frontendDirectories,
2088
2284
  latest,
2089
2285
  plugins,
2090
2286
  projectName,
2091
2287
  useTailwind
2092
2288
  });
2093
- const serverFilePath = join9(backendDirectory, "server.ts");
2289
+ const serverFilePath = join10(backendDirectory, "server.ts");
2094
2290
  createServerFile({
2095
2291
  assetsDirectory,
2096
2292
  authProvider,
2097
2293
  availablePlugins,
2098
2294
  buildDirectory,
2099
- frontendConfigurations,
2295
+ frontendDirectories,
2100
2296
  plugins,
2101
2297
  serverFilePath,
2102
2298
  tailwind
@@ -2108,7 +2304,7 @@ var scaffold = ({
2108
2304
  projectName
2109
2305
  });
2110
2306
  scaffoldFrontends({
2111
- frontendConfigurations,
2307
+ frontendDirectories,
2112
2308
  frontendDirectory,
2113
2309
  htmlScriptOption,
2114
2310
  language,
@@ -2124,6 +2320,174 @@ var scaffold = ({
2124
2320
  });
2125
2321
  };
2126
2322
 
2323
+ // src/utils/parseCommandLineOptions.ts
2324
+ import { argv, exit as exit4 } from "node:process";
2325
+ import { parseArgs } from "node:util";
2326
+ var parseCommandLineOptions = () => {
2327
+ const { values, positionals } = parseArgs({
2328
+ allowNegative: true,
2329
+ allowPositionals: true,
2330
+ args: argv.slice(DEFAULT_ARG_LENGTH),
2331
+ options: {
2332
+ angular: { type: "string" },
2333
+ assets: { type: "string" },
2334
+ auth: { type: "string" },
2335
+ build: { type: "string" },
2336
+ database: { type: "string" },
2337
+ debug: { default: false, short: "d", type: "boolean" },
2338
+ directory: { type: "string" },
2339
+ engine: { type: "string" },
2340
+ frontend: { multiple: true, type: "string" },
2341
+ git: { type: "boolean" },
2342
+ help: { default: false, short: "h", type: "boolean" },
2343
+ host: { type: "string" },
2344
+ html: { type: "string" },
2345
+ htmx: { type: "string" },
2346
+ lang: { type: "string" },
2347
+ lts: { default: false, type: "boolean" },
2348
+ npm: { type: "boolean" },
2349
+ orm: { type: "string" },
2350
+ plugin: { multiple: true, type: "string" },
2351
+ quality: { type: "string" },
2352
+ react: { type: "string" },
2353
+ script: { type: "string" },
2354
+ skip: { type: "boolean" },
2355
+ svelte: { type: "string" },
2356
+ tailwind: { type: "boolean" },
2357
+ "tailwind-input": { type: "string" },
2358
+ "tailwind-output": { type: "string" },
2359
+ vue: { type: "string" }
2360
+ }
2361
+ });
2362
+ const errors = [];
2363
+ let authProvider;
2364
+ if (values.auth !== undefined && !isAuthProvider(values.auth)) {
2365
+ errors.push(`Invalid auth provider: "${values.auth}". Expected: [ ${availableAuthProviders.join(", ")} ]`);
2366
+ } else if (values.auth !== undefined) {
2367
+ authProvider = values.auth;
2368
+ } else if (values.skip) {
2369
+ authProvider = "none";
2370
+ }
2371
+ let databaseEngine;
2372
+ if (values.engine !== undefined && !isDatabaseEngine(values.engine)) {
2373
+ errors.push(`Invalid database engine: "${values.engine}". Expected: [ ${availableDatabaseEngines.join(", ")} ]`);
2374
+ } else if (values.engine !== undefined) {
2375
+ databaseEngine = values.engine;
2376
+ } else if (values.skip) {
2377
+ databaseEngine = "none";
2378
+ }
2379
+ let databaseHost;
2380
+ if (values.host !== undefined && !isDatabaseHost(values.host)) {
2381
+ errors.push(`Invalid database host: "${values.host}". Expected: [ ${availableDatabaseHosts.join(", ")} ]`);
2382
+ } else if (values.host !== undefined) {
2383
+ databaseHost = values.host;
2384
+ } else if (values.skip) {
2385
+ databaseHost = "none";
2386
+ }
2387
+ const { orm: ormValue } = values;
2388
+ let orm;
2389
+ if (ormValue !== undefined && !isORM(ormValue)) {
2390
+ errors.push(`Invalid ORM: "${values.orm}". Expected: [ ${availableORMs.join(", ")} ]`);
2391
+ } else if (ormValue !== undefined) {
2392
+ orm = ormValue;
2393
+ } else if (values.skip) {
2394
+ orm = "none";
2395
+ }
2396
+ const codeQualityTool = isCodeQualityTool(values.quality) ? values.quality : undefined;
2397
+ if (values.quality !== undefined && codeQualityTool === undefined) {
2398
+ errors.push(`Invalid code quality tool: "${values.quality}". Expected: [ ${availableCodeQualityTools.join(", ")} ]`);
2399
+ }
2400
+ let htmlScriptOption;
2401
+ if (values.script !== undefined && !isHTMLScriptOption(values.script)) {
2402
+ errors.push(`Invalid HTML script option: "${values.script}". Expected: [ ${availableHTMLScriptOptions.join(", ")} ]`);
2403
+ } else if (values.script !== undefined) {
2404
+ htmlScriptOption = values.script;
2405
+ } else if (values.skip) {
2406
+ htmlScriptOption = "none";
2407
+ }
2408
+ const language = values.lang !== undefined && isLanguage(values.lang) ? values.lang : undefined;
2409
+ if (values.lang !== undefined && language === undefined) {
2410
+ errors.push(`Invalid language: "${values.lang}". Expected: [ ${availableLanguages.join(", ")} ]`);
2411
+ }
2412
+ const directoryConfig = values.directory !== undefined && isDirectoryConfig(values.directory) ? values.directory : undefined;
2413
+ if (values.directory !== undefined && directoryConfig === undefined) {
2414
+ errors.push(`Invalid directory configuration: "${values.directory}". Expected: [ ${availableDirectoryConfigurations.join(", ")} ]`);
2415
+ }
2416
+ for (const f of values.frontend || []) {
2417
+ if (isFrontend(f))
2418
+ continue;
2419
+ errors.push(`Invalid frontend: "${f}". Expected: [ ${availableFrontends.join(", ")} ]`);
2420
+ }
2421
+ if (errors.length > 0) {
2422
+ console.error(errors.join(`
2423
+ `));
2424
+ exit4(1);
2425
+ }
2426
+ if (databaseEngine === "none" && databaseHost !== "none") {
2427
+ console.warn("Warning: Setting the database host without a database engine has no effect.");
2428
+ }
2429
+ if (databaseEngine === "none" && orm !== "none") {
2430
+ console.warn("Warning: Setting an ORM without a database engine has no effect.");
2431
+ }
2432
+ let databaseDirectory = values.database;
2433
+ if (databaseEngine === "none" && databaseDirectory !== undefined) {
2434
+ console.warn("Warning: Setting a database directory without a database engine has no effect.");
2435
+ databaseDirectory = undefined;
2436
+ }
2437
+ const frontendsWithDirectory = availableFrontends.filter((f) => values[f] !== undefined);
2438
+ const frontendDirectories = {};
2439
+ for (const frontend of frontendsWithDirectory) {
2440
+ frontendDirectories[frontend] = values[frontend];
2441
+ }
2442
+ const originalFrontends = values.frontend;
2443
+ const collector = new Set(originalFrontends ?? []);
2444
+ for (const frontend of frontendsWithDirectory) {
2445
+ collector.add(frontend);
2446
+ }
2447
+ values.frontend = collector.size > 0 ? Array.from(collector) : undefined;
2448
+ if (values.plugin === undefined && values.skip) {
2449
+ values.plugin = ["none"];
2450
+ }
2451
+ const plugins = values.plugin && values.plugin[0] === "none" ? [] : values.plugin;
2452
+ const hasTailwindFiles = values["tailwind-input"] !== undefined || values["tailwind-output"] !== undefined;
2453
+ let tailwind = hasTailwindFiles ? {
2454
+ input: values["tailwind-input"],
2455
+ output: values["tailwind-output"]
2456
+ } : undefined;
2457
+ const useTailwind = values.tailwind ?? (hasTailwindFiles ? true : undefined);
2458
+ if (useTailwind === false && hasTailwindFiles) {
2459
+ console.warn("Warning: Tailwind CSS input/output files are specified but Tailwind is disabled.");
2460
+ tailwind = undefined;
2461
+ }
2462
+ const argumentConfiguration = {
2463
+ assetsDirectory: values.assets,
2464
+ authProvider,
2465
+ buildDirectory: values.build,
2466
+ codeQualityTool,
2467
+ databaseDirectory,
2468
+ databaseEngine,
2469
+ databaseHost,
2470
+ directoryConfig,
2471
+ frontendDirectories,
2472
+ frontends: values.frontend?.filter(isFrontend),
2473
+ htmlScriptOption,
2474
+ initializeGitNow: values.git,
2475
+ installDependenciesNow: values.npm,
2476
+ language,
2477
+ orm,
2478
+ plugins,
2479
+ projectName: positionals[0],
2480
+ tailwind,
2481
+ useTailwind
2482
+ };
2483
+ return {
2484
+ argumentConfiguration,
2485
+ debug: values.debug,
2486
+ help: values.help,
2487
+ latest: values.lts
2488
+ };
2489
+ };
2490
+
2127
2491
  // src/utils/t3-utils.ts
2128
2492
  import { env } from "node:process";
2129
2493
  var getUserPackageManager = () => {
@@ -2142,24 +2506,15 @@ var getUserPackageManager = () => {
2142
2506
  };
2143
2507
 
2144
2508
  // src/index.ts
2145
- var { values } = parseArgs({
2146
- args: argv.slice(DEFAULT_ARG_LENGTH),
2147
- options: {
2148
- debug: { default: false, short: "d", type: "boolean" },
2149
- help: { default: false, short: "h", type: "boolean" },
2150
- latest: { default: false, short: "l", type: "boolean" }
2151
- },
2152
- strict: false
2153
- });
2154
2509
  var packageManager = getUserPackageManager();
2155
- if (values.help === true) {
2510
+ var { help, argumentConfiguration, latest, debug } = parseCommandLineOptions();
2511
+ if (help === true) {
2156
2512
  console.log(helpMessage);
2157
- exit4(0);
2513
+ exit5(0);
2158
2514
  }
2159
- var response = await prompt();
2160
- scaffold({ latest: values.latest === true, packageManager, response });
2161
- var debugMessage = values.debug !== false ? getDebugMessage({
2162
- availableFrontends,
2515
+ var response = await prompt(argumentConfiguration);
2516
+ scaffold({ latest, packageManager, response });
2517
+ var debugMessage = debug !== false ? getDebugMessage({
2163
2518
  packageManager,
2164
2519
  response
2165
2520
  }) : "";
@@ -2168,4 +2523,4 @@ var outroMessage = getOutroMessage({
2168
2523
  packageManager,
2169
2524
  projectName: response.projectName
2170
2525
  });
2171
- Se(debugMessage + outroMessage);
2526
+ Se(outroMessage + debugMessage);