create-absolutejs 0.0.6 → 0.1.0
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 +1416 -168
- package/package.json +15 -9
package/dist/index.js
CHANGED
|
@@ -145,14 +145,15 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
145
145
|
module.exports.createColors = createColors;
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
// index.ts
|
|
149
|
-
import { argv, exit } from "node:process";
|
|
148
|
+
// src/index.ts
|
|
149
|
+
import { argv, exit as exit4 } from "node:process";
|
|
150
150
|
import { parseArgs } from "node:util";
|
|
151
151
|
|
|
152
152
|
// node_modules/@clack/core/dist/index.mjs
|
|
153
153
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
154
|
-
import { stdin as j, stdout as M } from "node:process";
|
|
155
154
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
155
|
+
import { stdin as j, stdout as M } from "node:process";
|
|
156
|
+
import * as g from "node:readline";
|
|
156
157
|
import O from "node:readline";
|
|
157
158
|
import { Writable as X } from "node:stream";
|
|
158
159
|
function DD({ onlyFirst: e = false } = {}) {
|
|
@@ -385,6 +386,28 @@ function m(e, u) {
|
|
|
385
386
|
const t = e;
|
|
386
387
|
t.isTTY && t.setRawMode(u);
|
|
387
388
|
}
|
|
389
|
+
function fD({ input: e = j, output: u = M, overwrite: t = true, hideCursor: F = true } = {}) {
|
|
390
|
+
const s = g.createInterface({ input: e, output: u, prompt: "", tabSize: 1 });
|
|
391
|
+
g.emitKeypressEvents(e, s), e.isTTY && e.setRawMode(true);
|
|
392
|
+
const i = (D, { name: r, sequence: n }) => {
|
|
393
|
+
const E = String(D);
|
|
394
|
+
if ($([E, r, n], "cancel")) {
|
|
395
|
+
F && u.write(import_sisteransi.cursor.show), process.exit(0);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (!t)
|
|
399
|
+
return;
|
|
400
|
+
const a = r === "return" ? 0 : -1, o = r === "return" ? -1 : 0;
|
|
401
|
+
g.moveCursor(u, a, o, () => {
|
|
402
|
+
g.clearLine(u, 1, () => {
|
|
403
|
+
e.once("keypress", i);
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
};
|
|
407
|
+
return F && u.write(import_sisteransi.cursor.hide), e.once("keypress", i), () => {
|
|
408
|
+
e.off("keypress", i), F && u.write(import_sisteransi.cursor.show), e.isTTY && !AD && e.setRawMode(false), s.terminal = false, s.close();
|
|
409
|
+
};
|
|
410
|
+
}
|
|
388
411
|
var gD = Object.defineProperty;
|
|
389
412
|
var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
390
413
|
var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
@@ -483,6 +506,24 @@ class x {
|
|
|
483
506
|
}
|
|
484
507
|
}
|
|
485
508
|
}
|
|
509
|
+
|
|
510
|
+
class dD extends x {
|
|
511
|
+
get cursor() {
|
|
512
|
+
return this.value ? 0 : 1;
|
|
513
|
+
}
|
|
514
|
+
get _value() {
|
|
515
|
+
return this.cursor === 0;
|
|
516
|
+
}
|
|
517
|
+
constructor(u) {
|
|
518
|
+
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
519
|
+
this.value = this._value;
|
|
520
|
+
}), this.on("confirm", (t) => {
|
|
521
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
|
|
522
|
+
}), this.on("cursor", () => {
|
|
523
|
+
this.value = !this.value;
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
486
527
|
var A;
|
|
487
528
|
A = new WeakMap;
|
|
488
529
|
var kD = Object.defineProperty;
|
|
@@ -613,9 +654,9 @@ var G2 = (t) => {
|
|
|
613
654
|
const { cursor: n, options: r, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
|
|
614
655
|
let l2 = 0;
|
|
615
656
|
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
616
|
-
const $2 = a < r.length && l2 > 0,
|
|
657
|
+
const $2 = a < r.length && l2 > 0, g2 = a < r.length && l2 + a < r.length;
|
|
617
658
|
return r.slice(l2, l2 + a).map((p2, v2, f) => {
|
|
618
|
-
const j2 = v2 === 0 && $2, E = v2 === f.length - 1 &&
|
|
659
|
+
const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
|
|
619
660
|
return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
|
|
620
661
|
});
|
|
621
662
|
};
|
|
@@ -640,6 +681,25 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
640
681
|
`;
|
|
641
682
|
}
|
|
642
683
|
} }).prompt();
|
|
684
|
+
var ye = (t) => {
|
|
685
|
+
const n = t.active ?? "Yes", r = t.inactive ?? "No";
|
|
686
|
+
return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
|
|
687
|
+
const i = `${import_picocolors2.default.gray(o)}
|
|
688
|
+
${b2(this.state)} ${t.message}
|
|
689
|
+
`, s = this.value ? n : r;
|
|
690
|
+
switch (this.state) {
|
|
691
|
+
case "submit":
|
|
692
|
+
return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
|
|
693
|
+
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)}`;
|
|
696
|
+
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)}
|
|
699
|
+
`;
|
|
700
|
+
}
|
|
701
|
+
} }).prompt();
|
|
702
|
+
};
|
|
643
703
|
var ve = (t) => {
|
|
644
704
|
const n = (r, i) => {
|
|
645
705
|
const s = r.label ?? String(r.value);
|
|
@@ -725,189 +785,1377 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
725
785
|
`);
|
|
726
786
|
};
|
|
727
787
|
var J2 = `${import_picocolors2.default.gray(o)} `;
|
|
788
|
+
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
789
|
+
const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
790
|
+
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
791
|
+
const p2 = (m2) => {
|
|
792
|
+
const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
|
|
793
|
+
a && N2(h2, m2);
|
|
794
|
+
}, v2 = () => p2(2), f = () => p2(1), j2 = () => {
|
|
795
|
+
process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
|
|
796
|
+
}, E = () => {
|
|
797
|
+
process.removeListener("uncaughtExceptionMonitor", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
|
|
798
|
+
}, B2 = () => {
|
|
799
|
+
if ($2 === undefined)
|
|
800
|
+
return;
|
|
801
|
+
i && process.stdout.write(`
|
|
802
|
+
`);
|
|
803
|
+
const m2 = $2.split(`
|
|
804
|
+
`);
|
|
805
|
+
process.stdout.write(import_sisteransi2.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(m2.length));
|
|
806
|
+
}, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
|
|
807
|
+
const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
808
|
+
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
809
|
+
}, H2 = (m2 = "") => {
|
|
810
|
+
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
811
|
+
`);
|
|
812
|
+
let h2 = 0, w2 = 0;
|
|
813
|
+
j2(), c = setInterval(() => {
|
|
814
|
+
if (i && l2 === $2)
|
|
815
|
+
return;
|
|
816
|
+
B2(), $2 = l2;
|
|
817
|
+
const I2 = import_picocolors2.default.magenta(n[h2]);
|
|
818
|
+
if (i)
|
|
819
|
+
process.stdout.write(`${I2} ${l2}...`);
|
|
820
|
+
else if (t === "timer")
|
|
821
|
+
process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
|
|
822
|
+
else {
|
|
823
|
+
const z2 = ".".repeat(Math.floor(w2)).slice(0, 3);
|
|
824
|
+
process.stdout.write(`${I2} ${l2}${z2}`);
|
|
825
|
+
}
|
|
826
|
+
h2 = h2 + 1 < n.length ? h2 + 1 : 0, w2 = w2 < n.length ? w2 + 0.125 : 0;
|
|
827
|
+
}, r);
|
|
828
|
+
}, N2 = (m2 = "", h2 = 0) => {
|
|
829
|
+
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);
|
|
831
|
+
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
832
|
+
`) : process.stdout.write(`${w2} ${l2}
|
|
833
|
+
`), E(), s();
|
|
834
|
+
};
|
|
835
|
+
return { start: H2, stop: N2, message: (m2 = "") => {
|
|
836
|
+
l2 = R2(m2 ?? l2);
|
|
837
|
+
} };
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// src/constants.ts
|
|
841
|
+
var UNFOUND_INDEX = -1;
|
|
842
|
+
var DEFAULT_ARG_LENGTH = 2;
|
|
843
|
+
var TWO_THIRDS = 2 / 3;
|
|
728
844
|
|
|
729
|
-
//
|
|
845
|
+
// src/data.ts
|
|
730
846
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
731
|
-
var
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
vue: "Vue"
|
|
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" }
|
|
740
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 defaultDependencies = [
|
|
888
|
+
{
|
|
889
|
+
imports: [{ isPlugin: false, packageName: "Elysia" }],
|
|
890
|
+
latestVersion: "1.3.1",
|
|
891
|
+
value: "elysia"
|
|
892
|
+
}
|
|
893
|
+
];
|
|
894
|
+
var defaultPlugins = [
|
|
895
|
+
{
|
|
896
|
+
imports: [
|
|
897
|
+
{ isPlugin: false, packageName: "build" },
|
|
898
|
+
{ isPlugin: true, packageName: "networkingPlugin" }
|
|
899
|
+
],
|
|
900
|
+
latestVersion: "0.6.0",
|
|
901
|
+
value: "@absolutejs/absolute"
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
imports: [
|
|
905
|
+
{
|
|
906
|
+
config: { assets: "./build", prefix: "" },
|
|
907
|
+
isPlugin: true,
|
|
908
|
+
packageName: "staticPlugin"
|
|
909
|
+
}
|
|
910
|
+
],
|
|
911
|
+
latestVersion: "1.3.0",
|
|
912
|
+
value: "@elysiajs/static"
|
|
913
|
+
}
|
|
914
|
+
];
|
|
915
|
+
|
|
916
|
+
// src/messages.ts
|
|
917
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
918
|
+
var helpMessage = `
|
|
919
|
+
Usage: create-absolute [options] [dir]
|
|
920
|
+
|
|
921
|
+
Arguments:
|
|
922
|
+
dir The name of the created application.
|
|
923
|
+
If not specified, the user will be prompted during creation.
|
|
924
|
+
|
|
925
|
+
Options:
|
|
926
|
+
-h, --help Show this help message and exit
|
|
927
|
+
-d, --debug Show a summary of the project configuration after creation
|
|
928
|
+
-l, --latest Fetch and use the latest version of required packages
|
|
929
|
+
`;
|
|
930
|
+
var getOutroMessage = ({
|
|
931
|
+
projectName,
|
|
932
|
+
packageManager,
|
|
933
|
+
installDependenciesNow
|
|
934
|
+
}) => `${import_picocolors4.green("Created successfully")}, you can now run:
|
|
935
|
+
|
|
936
|
+
` + `${import_picocolors4.cyan("cd")} ${projectName}
|
|
937
|
+
` + `${import_picocolors4.cyan(`${packageManager} dev`)}${installDependenciesNow ? "" : `
|
|
938
|
+
${import_picocolors4.cyan(`${packageManager} install`)}`}`;
|
|
939
|
+
var getDebugMessage = ({
|
|
940
|
+
response: {
|
|
941
|
+
projectName,
|
|
942
|
+
language,
|
|
943
|
+
codeQualityTool,
|
|
944
|
+
configType,
|
|
945
|
+
useTailwind,
|
|
946
|
+
tailwind,
|
|
947
|
+
frontends,
|
|
948
|
+
htmlScriptOption,
|
|
949
|
+
frontendConfigurations,
|
|
950
|
+
buildDirectory,
|
|
951
|
+
assetsDirectory,
|
|
952
|
+
databaseEngine,
|
|
953
|
+
databaseHost,
|
|
954
|
+
databaseDirectory,
|
|
955
|
+
orm,
|
|
956
|
+
authProvider,
|
|
957
|
+
plugins,
|
|
958
|
+
initializeGitNow,
|
|
959
|
+
installDependenciesNow
|
|
960
|
+
},
|
|
961
|
+
packageManager,
|
|
962
|
+
availableFrontends: availableFrontends2
|
|
963
|
+
}) => {
|
|
964
|
+
const htmlLabels = {
|
|
965
|
+
js: import_picocolors4.yellow("JavaScript"),
|
|
966
|
+
"js+ssr": import_picocolors4.yellow("JavaScript + SSR"),
|
|
967
|
+
ts: import_picocolors4.blueBright("TypeScript"),
|
|
968
|
+
"ts+ssr": import_picocolors4.blueBright("TypeScript + SSR")
|
|
969
|
+
};
|
|
970
|
+
const htmlScriptingValue = htmlScriptOption !== undefined ? htmlLabels[htmlScriptOption] : import_picocolors4.dim("None");
|
|
971
|
+
const htmlScriptingLine = frontends.includes("html") ? `
|
|
972
|
+
${import_picocolors4.magenta("HTML Scripting")}: ${htmlScriptingValue}` : "";
|
|
973
|
+
const frontendLabels = frontends.map((name) => availableFrontends2[name]?.label ?? name);
|
|
974
|
+
const frontendHeading = frontends.length === 1 ? import_picocolors4.magenta("Frontend") : import_picocolors4.magenta("Frontends");
|
|
975
|
+
const configString = frontendConfigurations.reduce((acc, { name, directory }, idx, arr) => {
|
|
976
|
+
const label = availableFrontends2[name]?.label ?? name;
|
|
977
|
+
const segment = `${label}: src/frontend/${directory}${idx < arr.length - 1 ? `
|
|
978
|
+
` : ""}`;
|
|
979
|
+
return acc + segment;
|
|
980
|
+
}, "");
|
|
981
|
+
const tailwindSection = tailwind && useTailwind ? `
|
|
982
|
+
${import_picocolors4.cyan("Input")}: ${tailwind.input}
|
|
983
|
+
${import_picocolors4.cyan("Output")}: ${tailwind.output}` : import_picocolors4.dim("None");
|
|
984
|
+
return `
|
|
985
|
+
${import_picocolors4.magenta("Project Name")}: ${projectName}
|
|
986
|
+
${import_picocolors4.magenta("Package Manager")}: ${packageManager}
|
|
987
|
+
${import_picocolors4.magenta("Config Type")}: ${configType === "custom" ? import_picocolors4.green("Custom") : import_picocolors4.dim("Default")}
|
|
988
|
+
${import_picocolors4.magenta("Language")}: ${language === "ts" ? import_picocolors4.blueBright("TypeScript") : import_picocolors4.yellow("JavaScript")}
|
|
989
|
+
${import_picocolors4.magenta("Linting")}: ${codeQualityTool === "eslint+prettier" ? "ESLint + Prettier" : "Biome"}
|
|
990
|
+
${import_picocolors4.magenta("Tailwind Configuration")}: ${tailwindSection}
|
|
991
|
+
${frontendHeading}: ${frontendLabels.join(", ")}${htmlScriptingLine}
|
|
992
|
+
${import_picocolors4.magenta("Build Directory")}: ${buildDirectory}
|
|
993
|
+
${import_picocolors4.magenta("Assets Directory")}: ${assetsDirectory}
|
|
994
|
+
${import_picocolors4.magenta("Database Engine")}: ${databaseEngine ?? import_picocolors4.dim("None")}
|
|
995
|
+
${import_picocolors4.magenta("Database Host")}: ${databaseHost ?? import_picocolors4.dim("None")}
|
|
996
|
+
${import_picocolors4.magenta("Database Directory")}: ${databaseDirectory ?? import_picocolors4.dim("None")}
|
|
997
|
+
${import_picocolors4.magenta("ORM")}: ${orm ?? import_picocolors4.dim("None")}
|
|
998
|
+
${import_picocolors4.magenta("Authorization Provider")}: ${authProvider ?? import_picocolors4.dim("None")}
|
|
999
|
+
${import_picocolors4.magenta("Plugins")}: ${plugins.length ? plugins.join(", ") : import_picocolors4.dim("None")}
|
|
1000
|
+
${import_picocolors4.magenta("Initialize Git")}: ${initializeGitNow ? import_picocolors4.green("Yes") : import_picocolors4.dim("No")}
|
|
1001
|
+
${import_picocolors4.magenta("Install Dependencies")}: ${installDependenciesNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")}
|
|
1002
|
+
${import_picocolors4.magenta("Framework Config")}:
|
|
1003
|
+
${configString}
|
|
1004
|
+
|
|
1005
|
+
`;
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
// src/questions/authProvider.ts
|
|
1009
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
1010
|
+
|
|
1011
|
+
// src/utils/abort.ts
|
|
1012
|
+
import { exit } from "node:process";
|
|
741
1013
|
function abort() {
|
|
742
1014
|
xe("Operation cancelled");
|
|
743
1015
|
exit(0);
|
|
744
1016
|
}
|
|
745
|
-
var DEFAULT_ARG_LENGTH = 2;
|
|
746
|
-
var { values } = parseArgs({
|
|
747
|
-
args: argv.slice(DEFAULT_ARG_LENGTH),
|
|
748
|
-
options: {
|
|
749
|
-
help: { default: false, short: "h", type: "boolean" }
|
|
750
|
-
},
|
|
751
|
-
strict: false
|
|
752
|
-
});
|
|
753
|
-
if (values.help) {
|
|
754
|
-
console.log(`
|
|
755
|
-
Usage: create-absolute [OPTION]...
|
|
756
1017
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
});
|
|
766
|
-
if (pD(
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
});
|
|
784
|
-
if (pD(useTailwind))
|
|
785
|
-
abort();
|
|
786
|
-
var tailwind;
|
|
787
|
-
if (useTailwind) {
|
|
788
|
-
const input = await he({
|
|
789
|
-
message: "Tailwind input CSS file:",
|
|
790
|
-
placeholder: "./example/styles/tailwind.css"
|
|
1018
|
+
// src/questions/authProvider.ts
|
|
1019
|
+
var getAuthProvider = async () => {
|
|
1020
|
+
const authProvider = await ve({
|
|
1021
|
+
message: "Auth provider:",
|
|
1022
|
+
options: [
|
|
1023
|
+
{ label: "None", value: "none" },
|
|
1024
|
+
{ label: import_picocolors5.cyan("Absolute Auth"), value: "absoluteAuth" }
|
|
1025
|
+
]
|
|
1026
|
+
});
|
|
1027
|
+
if (pD(authProvider))
|
|
1028
|
+
abort();
|
|
1029
|
+
return authProvider === "none" ? undefined : authProvider;
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
// src/questions/codeQualityTool.ts
|
|
1033
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
1034
|
+
var getCodeQualityTool = async () => {
|
|
1035
|
+
const codeQualityTool = await ve({
|
|
1036
|
+
message: "Choose linting and formatting tool:",
|
|
1037
|
+
options: [
|
|
1038
|
+
{
|
|
1039
|
+
label: import_picocolors6.blueBright("ESLint + Prettier"),
|
|
1040
|
+
value: "eslint+prettier"
|
|
1041
|
+
},
|
|
1042
|
+
{ label: import_picocolors6.yellow("Biome"), value: "biome" }
|
|
1043
|
+
]
|
|
791
1044
|
});
|
|
792
|
-
if (pD(
|
|
1045
|
+
if (pD(codeQualityTool))
|
|
793
1046
|
abort();
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1047
|
+
return codeQualityTool;
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
// src/questions/configurationType.ts
|
|
1051
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
1052
|
+
var getConfigurationType = async () => {
|
|
1053
|
+
const configType = await ve({
|
|
1054
|
+
message: "Choose folder naming configuration:",
|
|
1055
|
+
options: [
|
|
1056
|
+
{ label: import_picocolors7.blueBright("Default"), value: "default" },
|
|
1057
|
+
{ label: import_picocolors7.yellow("Custom"), value: "custom" }
|
|
1058
|
+
]
|
|
797
1059
|
});
|
|
798
|
-
if (pD(
|
|
1060
|
+
if (pD(configType))
|
|
799
1061
|
abort();
|
|
800
|
-
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
});
|
|
820
|
-
if (pD(
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1062
|
+
return configType;
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
// src/questions/databaseEngine.ts
|
|
1066
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
1067
|
+
var getDatabaseEngine = async () => {
|
|
1068
|
+
const databaseDialectResponse = await ve({
|
|
1069
|
+
message: "Database engine:",
|
|
1070
|
+
options: [
|
|
1071
|
+
{ label: "None", value: "none" },
|
|
1072
|
+
{ label: import_picocolors8.cyan("PostgreSQL"), value: "postgresql" },
|
|
1073
|
+
{ label: import_picocolors8.magenta("SQLite"), value: "sqlite" },
|
|
1074
|
+
{ label: import_picocolors8.green("MySQL"), value: "mysql" },
|
|
1075
|
+
{ label: import_picocolors8.red("Redis"), value: "redis" },
|
|
1076
|
+
{ label: import_picocolors8.green("MongoDB"), value: "mongodb" },
|
|
1077
|
+
{ label: import_picocolors8.magenta("SingleStore"), value: "singlestore" },
|
|
1078
|
+
{ label: import_picocolors8.yellow("SQL Server"), value: "mssql" },
|
|
1079
|
+
{ label: import_picocolors8.cyan("CockroachDB"), value: "cockroachdb" }
|
|
1080
|
+
]
|
|
1081
|
+
});
|
|
1082
|
+
if (pD(databaseDialectResponse))
|
|
1083
|
+
abort();
|
|
1084
|
+
return databaseDialectResponse === "none" ? undefined : databaseDialectResponse;
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
// src/questions/databaseHost.ts
|
|
1088
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
1089
|
+
var getDatabaseHost = async (databaseEngine) => {
|
|
1090
|
+
if (databaseEngine === "postgresql") {
|
|
1091
|
+
const databaseHost = await ve({
|
|
1092
|
+
message: "Select database host:",
|
|
1093
|
+
options: [
|
|
1094
|
+
{ label: import_picocolors9.cyan("Neon"), value: "neon" },
|
|
1095
|
+
{ label: import_picocolors9.cyan("Supabase"), value: "supabase" },
|
|
1096
|
+
{ label: "None", value: "none" }
|
|
1097
|
+
]
|
|
1098
|
+
});
|
|
1099
|
+
if (pD(databaseHost))
|
|
1100
|
+
abort();
|
|
1101
|
+
return databaseHost === "none" ? undefined : databaseHost;
|
|
1102
|
+
}
|
|
1103
|
+
if (databaseEngine === "mysql") {
|
|
1104
|
+
const databaseHost = await ye({
|
|
1105
|
+
message: "Are you using PlanetScale?"
|
|
1106
|
+
});
|
|
1107
|
+
if (pD(databaseHost))
|
|
1108
|
+
abort();
|
|
1109
|
+
return databaseHost ? "planetscale" : undefined;
|
|
1110
|
+
}
|
|
1111
|
+
if (databaseEngine === "sqlite") {
|
|
1112
|
+
const databaseHost = await ye({
|
|
1113
|
+
message: "Are you using Turso?"
|
|
1114
|
+
});
|
|
1115
|
+
if (pD(databaseHost))
|
|
1116
|
+
abort();
|
|
1117
|
+
return databaseHost ? "turso" : undefined;
|
|
1118
|
+
}
|
|
1119
|
+
if (databaseEngine === "mongodb") {
|
|
1120
|
+
const databaseHost = await ye({
|
|
1121
|
+
message: "Are you using Atlas?"
|
|
1122
|
+
});
|
|
1123
|
+
if (pD(databaseHost))
|
|
1124
|
+
abort();
|
|
1125
|
+
return databaseHost ? "atlas" : undefined;
|
|
1126
|
+
}
|
|
1127
|
+
if (databaseEngine === "redis") {
|
|
1128
|
+
const databaseHost = await ye({
|
|
1129
|
+
message: "Are you using Upstash?"
|
|
1130
|
+
});
|
|
1131
|
+
if (pD(databaseHost))
|
|
1132
|
+
abort();
|
|
1133
|
+
return databaseHost ? "upstash" : undefined;
|
|
1134
|
+
}
|
|
1135
|
+
return;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// src/questions/directoryConfiguration.ts
|
|
1139
|
+
var getDirectoryConfiguration = async ({
|
|
1140
|
+
configType,
|
|
1141
|
+
useTailwind,
|
|
1142
|
+
databaseEngine
|
|
1143
|
+
}) => {
|
|
1144
|
+
if (configType === "default") {
|
|
1145
|
+
return {
|
|
1146
|
+
assetsDirectory: "src/backend/assets",
|
|
1147
|
+
buildDirectory: "build",
|
|
1148
|
+
databaseDirectory: databaseEngine && "db",
|
|
1149
|
+
tailwind: useTailwind ? {
|
|
1150
|
+
input: "./src/frontend/styles/tailwind.css",
|
|
1151
|
+
output: "/assets/css/tailwind.generated.css"
|
|
1152
|
+
} : undefined
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
const buildDirectory = await he({
|
|
1156
|
+
message: "Build directory:",
|
|
1157
|
+
placeholder: "build"
|
|
838
1158
|
});
|
|
839
|
-
if (pD(
|
|
1159
|
+
if (pD(buildDirectory))
|
|
840
1160
|
abort();
|
|
841
|
-
const
|
|
842
|
-
message:
|
|
843
|
-
placeholder:
|
|
1161
|
+
const assetsDirectory = await he({
|
|
1162
|
+
message: "Assets directory:",
|
|
1163
|
+
placeholder: "src/backend/assets"
|
|
844
1164
|
});
|
|
845
|
-
if (pD(
|
|
1165
|
+
if (pD(assetsDirectory))
|
|
846
1166
|
abort();
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
1167
|
+
let tailwind;
|
|
1168
|
+
if (useTailwind) {
|
|
1169
|
+
const input = await he({
|
|
1170
|
+
message: "Tailwind input CSS file:",
|
|
1171
|
+
placeholder: "./src/frontend/styles/tailwind.css"
|
|
1172
|
+
});
|
|
1173
|
+
if (pD(input))
|
|
1174
|
+
abort();
|
|
1175
|
+
const output = await he({
|
|
1176
|
+
message: "Tailwind output CSS file:",
|
|
1177
|
+
placeholder: "/assets/css/tailwind.generated.css"
|
|
1178
|
+
});
|
|
1179
|
+
if (pD(output))
|
|
1180
|
+
abort();
|
|
1181
|
+
tailwind = { input, output };
|
|
1182
|
+
} else {
|
|
1183
|
+
tailwind = undefined;
|
|
1184
|
+
}
|
|
1185
|
+
let databaseDirectory;
|
|
1186
|
+
if (databaseEngine !== undefined) {
|
|
1187
|
+
databaseDirectory = await he({
|
|
1188
|
+
message: "Database directory:",
|
|
1189
|
+
placeholder: "db"
|
|
1190
|
+
});
|
|
1191
|
+
if (pD(databaseDirectory))
|
|
1192
|
+
abort();
|
|
1193
|
+
}
|
|
1194
|
+
return {
|
|
1195
|
+
assetsDirectory,
|
|
1196
|
+
buildDirectory,
|
|
1197
|
+
databaseDirectory,
|
|
1198
|
+
tailwind
|
|
1199
|
+
};
|
|
1200
|
+
};
|
|
1201
|
+
|
|
1202
|
+
// src/questions/frontendDirectoryConfigurations.ts
|
|
1203
|
+
var getFrontendDirectoryConfigurations = async (configType, frontends) => {
|
|
1204
|
+
let frontendConfigurations;
|
|
1205
|
+
const single = frontends.length === 1;
|
|
1206
|
+
if (configType === "custom") {
|
|
1207
|
+
frontendConfigurations = await frontends.reduce(async (prevP, frontend) => {
|
|
1208
|
+
const prev = await prevP;
|
|
1209
|
+
const pretty = availableFrontends[frontend]?.name ?? frontend;
|
|
1210
|
+
const base = single ? "" : `${frontend}`;
|
|
1211
|
+
const defDir = base;
|
|
1212
|
+
const frontendDirectory = await he({
|
|
1213
|
+
message: `${pretty} directory:`,
|
|
1214
|
+
placeholder: defDir
|
|
1215
|
+
});
|
|
1216
|
+
if (pD(frontendDirectory))
|
|
1217
|
+
abort();
|
|
1218
|
+
return [
|
|
1219
|
+
...prev,
|
|
1220
|
+
{ directory: frontendDirectory, frontend, name: frontend }
|
|
1221
|
+
];
|
|
1222
|
+
}, Promise.resolve([]));
|
|
1223
|
+
} else {
|
|
1224
|
+
frontendConfigurations = frontends.map((frontend) => ({
|
|
1225
|
+
directory: single ? "" : frontend,
|
|
1226
|
+
frontend,
|
|
1227
|
+
name: frontend
|
|
1228
|
+
}));
|
|
1229
|
+
}
|
|
1230
|
+
return frontendConfigurations;
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1233
|
+
// src/questions/frontends.ts
|
|
1234
|
+
var getFrontends = async () => {
|
|
1235
|
+
const frontends = await fe({
|
|
1236
|
+
message: "Frontend(s) (space to select, enter to finish):",
|
|
1237
|
+
options: Object.entries(availableFrontends).map(([value, { label }]) => ({ label, value }))
|
|
1238
|
+
});
|
|
1239
|
+
if (pD(frontends))
|
|
1240
|
+
abort();
|
|
1241
|
+
return frontends;
|
|
1242
|
+
};
|
|
1243
|
+
|
|
1244
|
+
// src/questions/htmlScriptingOption.ts
|
|
1245
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
1246
|
+
var getHtmlScriptingOption = async (language) => {
|
|
1247
|
+
const langLabel = language === "ts" ? import_picocolors10.blueBright("TypeScript") : import_picocolors10.yellow("JavaScript");
|
|
1248
|
+
const htmlScriptOption = await ve({
|
|
1249
|
+
message: `Add HTML scripting option (${langLabel}):`,
|
|
1250
|
+
options: [
|
|
1251
|
+
{ label: `${langLabel} + SSR`, value: `${language}+ssr` },
|
|
1252
|
+
{ label: langLabel, value: language },
|
|
1253
|
+
{ label: "None", value: "none" }
|
|
1254
|
+
]
|
|
1255
|
+
});
|
|
1256
|
+
if (pD(htmlScriptOption))
|
|
1257
|
+
abort();
|
|
1258
|
+
return htmlScriptOption === "none" ? undefined : htmlScriptOption;
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1261
|
+
// src/questions/initializeGitNow.ts
|
|
1262
|
+
var getInitializeGit = async () => {
|
|
1263
|
+
const initializeGitNow = await ye({
|
|
1264
|
+
message: "Initialize a git repository?"
|
|
1265
|
+
});
|
|
1266
|
+
if (pD(initializeGitNow))
|
|
1267
|
+
abort();
|
|
1268
|
+
return initializeGitNow;
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
// src/questions/installDependenciesNow.ts
|
|
1272
|
+
var getInstallDependencies = async () => {
|
|
1273
|
+
const installDependenciesNow = await ye({
|
|
1274
|
+
message: "Install dependencies now?"
|
|
1275
|
+
});
|
|
1276
|
+
if (pD(installDependenciesNow))
|
|
1277
|
+
abort();
|
|
1278
|
+
return installDependenciesNow;
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1281
|
+
// src/questions/language.ts
|
|
1282
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
1283
|
+
var getLanguage = async () => {
|
|
1284
|
+
const language = await ve({
|
|
1285
|
+
message: "Language:",
|
|
1286
|
+
options: [
|
|
1287
|
+
{ label: import_picocolors11.blueBright("TypeScript"), value: "ts" },
|
|
1288
|
+
{ label: import_picocolors11.yellow("JavaScript"), value: "js" }
|
|
1289
|
+
]
|
|
1290
|
+
});
|
|
1291
|
+
if (pD(language))
|
|
1292
|
+
abort();
|
|
1293
|
+
return language;
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
// src/questions/orm.ts
|
|
1297
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
1298
|
+
var getORM = async () => {
|
|
1299
|
+
const orm = await ve({
|
|
865
1300
|
message: "Choose an ORM (optional):",
|
|
866
1301
|
options: [
|
|
867
|
-
{ label:
|
|
868
|
-
{ label:
|
|
869
|
-
{ label:
|
|
1302
|
+
{ label: "None", value: "none" },
|
|
1303
|
+
{ label: import_picocolors12.cyan("Drizzle"), value: "drizzle" },
|
|
1304
|
+
{ label: import_picocolors12.magenta("Prisma"), value: "prisma" }
|
|
870
1305
|
]
|
|
871
1306
|
});
|
|
872
|
-
if (pD(
|
|
1307
|
+
if (pD(orm))
|
|
873
1308
|
abort();
|
|
874
|
-
orm
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1309
|
+
return orm === "none" ? undefined : orm;
|
|
1310
|
+
};
|
|
1311
|
+
|
|
1312
|
+
// src/questions/plugins.ts
|
|
1313
|
+
var getPlugins = async () => {
|
|
1314
|
+
const plugins = await fe({
|
|
1315
|
+
message: "Select additional Elysia plugins (space to select, enter to submit):",
|
|
1316
|
+
options: availablePlugins,
|
|
1317
|
+
required: false
|
|
1318
|
+
});
|
|
1319
|
+
if (pD(plugins))
|
|
1320
|
+
abort();
|
|
1321
|
+
return plugins;
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
// src/questions/projectName.ts
|
|
1325
|
+
var getProjectName = async () => {
|
|
1326
|
+
const projectName = await he({
|
|
1327
|
+
message: "Project name:",
|
|
1328
|
+
placeholder: "absolutejs-project"
|
|
1329
|
+
});
|
|
1330
|
+
if (pD(projectName))
|
|
1331
|
+
abort();
|
|
1332
|
+
return projectName;
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
// src/questions/useTailwind.ts
|
|
1336
|
+
var getUseTailwind = async () => {
|
|
1337
|
+
const useTailwind = await ye({ message: "Add Tailwind support?" });
|
|
1338
|
+
if (pD(useTailwind))
|
|
1339
|
+
abort();
|
|
1340
|
+
return useTailwind;
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
// src/prompt.ts
|
|
1344
|
+
var prompt = async () => {
|
|
1345
|
+
const projectName = await getProjectName();
|
|
1346
|
+
const language = await getLanguage();
|
|
1347
|
+
const codeQualityTool = await getCodeQualityTool();
|
|
1348
|
+
const useTailwind = await getUseTailwind();
|
|
1349
|
+
const frontends = await getFrontends();
|
|
1350
|
+
const htmlScriptOption = frontends.includes("html") ? await getHtmlScriptingOption(language) : undefined;
|
|
1351
|
+
const databaseEngine = await getDatabaseEngine();
|
|
1352
|
+
const databaseHost = await getDatabaseHost(databaseEngine);
|
|
1353
|
+
const orm = databaseEngine !== undefined ? await getORM() : undefined;
|
|
1354
|
+
const configType = await getConfigurationType();
|
|
1355
|
+
const { buildDirectory, assetsDirectory, tailwind, databaseDirectory } = await getDirectoryConfiguration({
|
|
1356
|
+
configType,
|
|
1357
|
+
databaseEngine,
|
|
1358
|
+
useTailwind
|
|
1359
|
+
});
|
|
1360
|
+
const frontendConfigurations = await getFrontendDirectoryConfigurations(configType, frontends);
|
|
1361
|
+
const authProvider = await getAuthProvider();
|
|
1362
|
+
const plugins = await getPlugins();
|
|
1363
|
+
const initializeGitNow = await getInitializeGit();
|
|
1364
|
+
const installDependenciesNow = await getInstallDependencies();
|
|
1365
|
+
const values = {
|
|
1366
|
+
assetsDirectory,
|
|
1367
|
+
authProvider,
|
|
1368
|
+
buildDirectory,
|
|
1369
|
+
codeQualityTool,
|
|
1370
|
+
configType,
|
|
1371
|
+
databaseDirectory,
|
|
1372
|
+
databaseEngine,
|
|
1373
|
+
databaseHost,
|
|
1374
|
+
frontendConfigurations,
|
|
1375
|
+
frontends,
|
|
1376
|
+
htmlScriptOption,
|
|
1377
|
+
initializeGitNow,
|
|
1378
|
+
installDependenciesNow,
|
|
1379
|
+
language,
|
|
1380
|
+
orm,
|
|
1381
|
+
plugins,
|
|
1382
|
+
projectName,
|
|
1383
|
+
tailwind,
|
|
1384
|
+
useTailwind
|
|
1385
|
+
};
|
|
1386
|
+
return values;
|
|
1387
|
+
};
|
|
1388
|
+
|
|
1389
|
+
// src/scaffold.ts
|
|
1390
|
+
import { copyFileSync as copyFileSync4 } from "node:fs";
|
|
1391
|
+
import { join as join9, dirname } from "node:path";
|
|
1392
|
+
import { fileURLToPath } from "node:url";
|
|
1393
|
+
|
|
1394
|
+
// src/commands/formatProject.ts
|
|
1395
|
+
import { execSync } from "child_process";
|
|
1396
|
+
import { exit as exit2 } from "process";
|
|
1397
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
1398
|
+
|
|
1399
|
+
// src/utils/commandMaps.ts
|
|
1400
|
+
var formatCommands = {
|
|
1401
|
+
bun: "bun run format",
|
|
1402
|
+
npm: "npm run format",
|
|
1403
|
+
pnpm: "pnpm run format",
|
|
1404
|
+
yarn: "yarn format"
|
|
1405
|
+
};
|
|
1406
|
+
var installCommands = {
|
|
1407
|
+
bun: "bun install",
|
|
1408
|
+
npm: "npm install",
|
|
1409
|
+
pnpm: "pnpm install",
|
|
1410
|
+
yarn: "yarn install"
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
// src/commands/formatProject.ts
|
|
1414
|
+
var formatProject = ({
|
|
1415
|
+
projectName,
|
|
1416
|
+
packageManager
|
|
1417
|
+
}) => {
|
|
1418
|
+
const spin = Y2();
|
|
1419
|
+
try {
|
|
1420
|
+
const fmt = formatCommands[packageManager] ?? "bun run format";
|
|
1421
|
+
spin.start("Formatting files…");
|
|
1422
|
+
execSync(fmt, { cwd: projectName, stdio: "pipe" });
|
|
1423
|
+
spin.stop(import_picocolors13.green("Files formatted"));
|
|
1424
|
+
} catch (err) {
|
|
1425
|
+
spin.stop(import_picocolors13.red("Failed to format files"), 1);
|
|
1426
|
+
console.error("Error formatting:", err);
|
|
1427
|
+
exit2(1);
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
// src/commands/installDependencies.ts
|
|
1432
|
+
import { execSync as execSync2 } from "child_process";
|
|
1433
|
+
import { exit as exit3 } from "process";
|
|
1434
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
1435
|
+
var installDependencies = async ({
|
|
1436
|
+
projectName,
|
|
1437
|
+
packageManager
|
|
1438
|
+
}) => {
|
|
1439
|
+
const spin = Y2();
|
|
1440
|
+
const cmd = installCommands[packageManager] ?? "bun install";
|
|
1441
|
+
try {
|
|
1442
|
+
spin.start("Installing dependencies…");
|
|
1443
|
+
execSync2(cmd, { cwd: projectName, stdio: "pipe" });
|
|
1444
|
+
spin.stop(import_picocolors14.green("Dependencies installed"));
|
|
1445
|
+
} catch (err) {
|
|
1446
|
+
spin.stop(import_picocolors14.red("Installation failed"), 1);
|
|
1447
|
+
console.error("Error installing dependencies:", err);
|
|
1448
|
+
exit3(1);
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
|
|
1452
|
+
// src/generators/configurations/addConfigurationFiles.ts
|
|
1453
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
1454
|
+
import { copyFileSync } from "fs";
|
|
1455
|
+
import { join } from "path";
|
|
1456
|
+
var addConfigurationFiles = ({
|
|
1457
|
+
tailwind,
|
|
1458
|
+
templatesDirectory,
|
|
1459
|
+
language,
|
|
1460
|
+
codeQualityTool,
|
|
1461
|
+
initializeGitNow,
|
|
1462
|
+
projectName
|
|
1463
|
+
}) => {
|
|
1464
|
+
if (tailwind) {
|
|
1465
|
+
copyFileSync(join(templatesDirectory, "tailwind", "postcss.config.ts"), join(projectName, "postcss.config.ts"));
|
|
1466
|
+
copyFileSync(join(templatesDirectory, "tailwind", "tailwind.config.ts"), join(projectName, "tailwind.config.ts"));
|
|
1467
|
+
}
|
|
1468
|
+
if (initializeGitNow)
|
|
1469
|
+
copyFileSync(join(templatesDirectory, "git", ".gitignore"), join(projectName, ".gitignore"));
|
|
1470
|
+
if (language === "ts")
|
|
1471
|
+
copyFileSync(join(templatesDirectory, "configurations", "tsconfig.example.json"), join(projectName, "tsconfig.json"));
|
|
1472
|
+
if (codeQualityTool === "eslint+prettier") {
|
|
1473
|
+
copyFileSync(join(templatesDirectory, "configurations", "eslint.config.mjs"), join(projectName, "eslint.config.mjs"));
|
|
1474
|
+
copyFileSync(join(templatesDirectory, "configurations", ".prettierignore"), join(projectName, ".prettierignore"));
|
|
1475
|
+
copyFileSync(join(templatesDirectory, "configurations", ".prettierrc.json"), join(projectName, ".prettierrc.json"));
|
|
1476
|
+
} else
|
|
1477
|
+
console.warn(`${import_picocolors15.dim("│")}
|
|
1478
|
+
${import_picocolors15.yellow("▲")} Biome support not implemented yet`);
|
|
1479
|
+
};
|
|
1480
|
+
|
|
1481
|
+
// src/generators/configurations/createPackageJson.ts
|
|
1482
|
+
import { writeFileSync } from "fs";
|
|
1483
|
+
import { join as join2 } from "path";
|
|
1484
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
1485
|
+
|
|
1486
|
+
// src/utils/getPackageVersion.ts
|
|
1487
|
+
import { execSync as execSync3 } from "child_process";
|
|
1488
|
+
var getPackageVersion = (packageName) => {
|
|
1489
|
+
try {
|
|
1490
|
+
const raw = execSync3(`curl -s https://registry.npmjs.org/${packageName}/latest`);
|
|
1491
|
+
const { version } = JSON.parse(raw.toString());
|
|
1492
|
+
return version;
|
|
1493
|
+
} catch (err) {
|
|
1494
|
+
console.error(`Error fetching version for ${packageName}:`, err);
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
// src/generators/configurations/createPackageJson.ts
|
|
1500
|
+
var createPackageJson = ({
|
|
1501
|
+
projectName,
|
|
1502
|
+
authProvider,
|
|
1503
|
+
plugins,
|
|
1504
|
+
useTailwind,
|
|
1505
|
+
latest,
|
|
1506
|
+
frontendConfigurations
|
|
1507
|
+
}) => {
|
|
1508
|
+
const s = Y2();
|
|
1509
|
+
latest && s.start("Resolving package versions…");
|
|
1510
|
+
const resolveVersion = (name, listed) => latest ? getPackageVersion(name) ?? listed : listed;
|
|
1511
|
+
const dependencies = {};
|
|
1512
|
+
const devDependencies = {};
|
|
1513
|
+
for (const p2 of defaultPlugins) {
|
|
1514
|
+
dependencies[p2.value] = resolveVersion(p2.value, p2.latestVersion);
|
|
1515
|
+
}
|
|
1516
|
+
if (authProvider === "absoluteAuth") {
|
|
1517
|
+
dependencies[absoluteAuthPlugin.value] = resolveVersion(absoluteAuthPlugin.value, absoluteAuthPlugin.latestVersion);
|
|
1518
|
+
}
|
|
1519
|
+
for (const pluginValue of plugins) {
|
|
1520
|
+
const meta = availablePlugins.find((p2) => p2.value === pluginValue);
|
|
1521
|
+
if (!meta)
|
|
1522
|
+
continue;
|
|
1523
|
+
dependencies[meta.value] = resolveVersion(meta.value, meta.latestVersion);
|
|
1524
|
+
}
|
|
1525
|
+
if (useTailwind) {
|
|
1526
|
+
devDependencies["autoprefixer"] = resolveVersion("autoprefixer", "10.4.21");
|
|
1527
|
+
devDependencies["postcss"] = resolveVersion("postcss", "8.5.3");
|
|
1528
|
+
devDependencies["tailwindcss"] = resolveVersion("tailwindcss", "4.1.7");
|
|
1529
|
+
devDependencies["@tailwindcss/cli"] = resolveVersion("@tailwindcss/cli", "4.1.7");
|
|
1530
|
+
}
|
|
1531
|
+
if (frontendConfigurations.some((f) => f.name === "react")) {
|
|
1532
|
+
dependencies["react"] = resolveVersion("react", "19.1.0");
|
|
1533
|
+
dependencies["react-dom"] = resolveVersion("react-dom", "19.1.0");
|
|
1534
|
+
devDependencies["@types/react"] = resolveVersion("@types/react", "19.1.5");
|
|
1535
|
+
devDependencies["@types/react-dom"] = resolveVersion("@types/react-dom", "19.1.5");
|
|
1536
|
+
}
|
|
1537
|
+
latest && s.stop(import_picocolors16.green("Package versions resolved"));
|
|
1538
|
+
const scripts = {
|
|
1539
|
+
dev: "bun run src/backend/server.ts",
|
|
1540
|
+
format: 'prettier --write "./**/*.{js,jsx,ts,tsx,css,json,mjs,md}"',
|
|
1541
|
+
lint: "eslint ./src",
|
|
1542
|
+
test: 'echo "Error: no test specified" && exit 1',
|
|
1543
|
+
typecheck: "bun run tsc --noEmit"
|
|
1544
|
+
};
|
|
1545
|
+
const packageJson = {
|
|
1546
|
+
dependencies,
|
|
1547
|
+
devDependencies,
|
|
1548
|
+
name: projectName,
|
|
1549
|
+
scripts,
|
|
1550
|
+
type: "module",
|
|
1551
|
+
version: "0.1.0"
|
|
1552
|
+
};
|
|
1553
|
+
writeFileSync(join2(projectName, "package.json"), JSON.stringify(packageJson));
|
|
1554
|
+
};
|
|
1555
|
+
|
|
1556
|
+
// src/generators/configurations/initializeRoot.ts
|
|
1557
|
+
import { copyFileSync as copyFileSync2, cpSync, existsSync, mkdirSync } from "node:fs";
|
|
1558
|
+
import { join as join3 } from "node:path";
|
|
1559
|
+
var initalizeRoot = (projectName, templatesDirectory) => {
|
|
1560
|
+
if (existsSync(projectName))
|
|
1561
|
+
throw new Error(`Cannot create project "${projectName}": directory already exists.`);
|
|
1562
|
+
mkdirSync(projectName);
|
|
1563
|
+
const srcDir = join3(projectName, "src");
|
|
1564
|
+
mkdirSync(srcDir);
|
|
1565
|
+
copyFileSync2(join3(templatesDirectory, "constants.ts"), join3(projectName, "src", "constants.ts"));
|
|
1566
|
+
const frontendDirectory = join3(srcDir, "frontend");
|
|
1567
|
+
const backendDirectory = join3(srcDir, "backend");
|
|
1568
|
+
mkdirSync(frontendDirectory);
|
|
1569
|
+
mkdirSync(backendDirectory);
|
|
1570
|
+
mkdirSync(join3(srcDir, "types"));
|
|
1571
|
+
cpSync(join3(templatesDirectory, "assets"), join3(backendDirectory, "assets"), { recursive: true });
|
|
1572
|
+
return {
|
|
1573
|
+
backendDirectory,
|
|
1574
|
+
frontendDirectory
|
|
1575
|
+
};
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
// src/generators/db/scaffoldDatabase.ts
|
|
1579
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
1580
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
1581
|
+
import { join as join5 } from "path";
|
|
1582
|
+
|
|
1583
|
+
// src/generators/configurations/createDrizzleConfig.ts
|
|
1584
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
1585
|
+
import { join as join4 } from "path";
|
|
1586
|
+
var createDrizzleConfig = ({
|
|
1587
|
+
projectName,
|
|
1588
|
+
databaseEngine
|
|
1589
|
+
}) => {
|
|
1590
|
+
const drizzleConfig = `import { defineConfig } from "drizzle-kit";
|
|
1591
|
+
|
|
1592
|
+
export default defineConfig({
|
|
1593
|
+
dialect: '${databaseEngine}'
|
|
1594
|
+
});
|
|
1595
|
+
`;
|
|
1596
|
+
writeFileSync2(join4(projectName, "drizzle.config.ts"), drizzleConfig);
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
// src/generators/db/scaffoldDatabase.ts
|
|
1600
|
+
var scaffoldDatabase = ({
|
|
1601
|
+
projectName,
|
|
1602
|
+
databaseEngine,
|
|
1603
|
+
databaseDirectory,
|
|
1604
|
+
orm
|
|
1605
|
+
}) => {
|
|
1606
|
+
mkdirSync2(join5(projectName, databaseDirectory), { recursive: true });
|
|
1607
|
+
if (databaseEngine !== "postgresql") {
|
|
1608
|
+
console.warn(`${import_picocolors17.dim("│")}
|
|
1609
|
+
${import_picocolors17.yellow("▲")} Only PostgreSQL support is implemented so far`);
|
|
1610
|
+
}
|
|
1611
|
+
if (orm === "drizzle") {
|
|
1612
|
+
createDrizzleConfig({ databaseEngine, projectName });
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
// src/generators/project/createServer.ts
|
|
1617
|
+
import { writeFileSync as writeFileSync3 } from "fs";
|
|
1618
|
+
var createServerFile = ({
|
|
1619
|
+
tailwind,
|
|
1620
|
+
frontendConfigurations,
|
|
1621
|
+
serverFilePath,
|
|
1622
|
+
authProvider,
|
|
1623
|
+
availablePlugins: availablePlugins2,
|
|
1624
|
+
buildDirectory,
|
|
1625
|
+
assetsDirectory,
|
|
1626
|
+
plugins
|
|
1627
|
+
}) => {
|
|
1628
|
+
const requiresHtml = frontendConfigurations.some((configuration) => configuration.name === "html");
|
|
1629
|
+
const requiresReact = frontendConfigurations.some((configuration) => configuration.name === "react");
|
|
1630
|
+
const isSingleFrontend = frontendConfigurations.length === 1;
|
|
1631
|
+
const selectedCustomPlugins = availablePlugins2.filter((plugin) => plugins.indexOf(plugin.value) !== UNFOUND_INDEX);
|
|
1632
|
+
const authenticationPlugins = [];
|
|
1633
|
+
if (authProvider === "absoluteAuth") {
|
|
1634
|
+
authenticationPlugins.push(absoluteAuthPlugin);
|
|
1635
|
+
}
|
|
1636
|
+
const combinedDependencies = [
|
|
1637
|
+
...defaultDependencies,
|
|
1638
|
+
...defaultPlugins,
|
|
1639
|
+
...selectedCustomPlugins,
|
|
1640
|
+
...authenticationPlugins
|
|
1641
|
+
];
|
|
1642
|
+
const uniqueDependencies = [];
|
|
1643
|
+
combinedDependencies.forEach((dependency) => {
|
|
1644
|
+
if (!uniqueDependencies.some((existingDependency) => existingDependency.value === dependency.value)) {
|
|
1645
|
+
uniqueDependencies.push(dependency);
|
|
1646
|
+
}
|
|
1647
|
+
});
|
|
1648
|
+
uniqueDependencies.sort((firstDependency, secondDependency) => firstDependency.value.localeCompare(secondDependency.value));
|
|
1649
|
+
const importLines = uniqueDependencies.flatMap((dependency) => dependency.imports.length > 0 ? [
|
|
1650
|
+
`import { ${dependency.imports.map((importEntry) => importEntry.packageName).join(", ")} } from '${dependency.value}';`
|
|
1651
|
+
] : []);
|
|
1652
|
+
const absoluteImportLineIndex = importLines.findIndex((importLine) => importLine.includes("from '@absolutejs/absolute'"));
|
|
1653
|
+
if (absoluteImportLineIndex >= 0) {
|
|
1654
|
+
const originalImportLine = importLines[absoluteImportLineIndex];
|
|
1655
|
+
importLines[absoluteImportLineIndex] = originalImportLine.replace(/import\s*\{([\s\S]*?)\}\s*from '@absolutejs\/absolute';/, (_fullMatch, importList) => {
|
|
1656
|
+
const importedItems = importList.split(",").map((item) => item.trim()).filter(Boolean);
|
|
1657
|
+
if (requiresHtml && !importedItems.includes("handleHTMLPageRequest")) {
|
|
1658
|
+
importedItems.push("handleHTMLPageRequest");
|
|
1659
|
+
}
|
|
1660
|
+
if (requiresReact && !importedItems.includes("handleReactPageRequest")) {
|
|
1661
|
+
importedItems.push("handleReactPageRequest");
|
|
1662
|
+
}
|
|
1663
|
+
return `import { ${importedItems.join(", ")} } from '@absolutejs/absolute';`;
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
if (requiresReact) {
|
|
1667
|
+
const reactImportSource = isSingleFrontend ? "../frontend/pages/ReactExample" : "../frontend/react/pages/ReactExample";
|
|
1668
|
+
importLines.push(`import { ReactExample } from '${reactImportSource}';`);
|
|
1669
|
+
}
|
|
1670
|
+
const useStatements = uniqueDependencies.flatMap((dependency) => dependency.imports).filter((importEntry) => importEntry.isPlugin).map((importEntry) => {
|
|
1671
|
+
if (importEntry.config === undefined) {
|
|
1672
|
+
return `.use(${importEntry.packageName})`;
|
|
1673
|
+
}
|
|
1674
|
+
if (importEntry.config === null) {
|
|
1675
|
+
return `.use(${importEntry.packageName}())`;
|
|
1676
|
+
}
|
|
1677
|
+
return `.use(${importEntry.packageName}(${JSON.stringify(importEntry.config)}))`;
|
|
1678
|
+
});
|
|
1679
|
+
const manifestOptions = [
|
|
1680
|
+
`buildDirectory: '${buildDirectory}'`,
|
|
1681
|
+
`assetsDirectory: '${assetsDirectory}'`,
|
|
1682
|
+
...frontendConfigurations.map((configuration) => configuration.directory ? `${configuration.name}Directory: './src/frontend/${configuration.directory}'` : "").filter((option) => option !== ""),
|
|
1683
|
+
tailwind ? `tailwind: ${JSON.stringify(tailwind)}` : ""
|
|
1684
|
+
];
|
|
1685
|
+
const buildStatement = `const manifest = await build({
|
|
1686
|
+
${manifestOptions.join(`,
|
|
1687
|
+
`)}
|
|
1688
|
+
});`;
|
|
1689
|
+
let guardStatements = `if (manifest === null) throw new Error('Manifest was not generated');`;
|
|
1690
|
+
if (requiresReact) {
|
|
1691
|
+
guardStatements += `
|
|
1692
|
+
const { ReactExampleIndex } = manifest;
|
|
1693
|
+
if (ReactExampleIndex === undefined) throw new Error('ReactExampleIndex was not generated');`;
|
|
1694
|
+
}
|
|
1695
|
+
let routeDefinitions = "";
|
|
1696
|
+
frontendConfigurations.forEach((configuration, index) => {
|
|
1697
|
+
const routePath = index === 0 ? "/" : `/${configuration.name}`;
|
|
1698
|
+
if (configuration.name === "html") {
|
|
1699
|
+
routeDefinitions += `
|
|
1700
|
+
.get('${routePath}', () =>
|
|
1701
|
+
handleHTMLPageRequest(\`${buildDirectory}/html/pages/HtmlExample.html\`)
|
|
1702
|
+
)`;
|
|
1703
|
+
} else if (configuration.name === "react") {
|
|
1704
|
+
routeDefinitions += `
|
|
1705
|
+
.get('${routePath}', () =>
|
|
1706
|
+
handleReactPageRequest(ReactExample, ReactExampleIndex)
|
|
1707
|
+
)`;
|
|
1708
|
+
}
|
|
1709
|
+
});
|
|
1710
|
+
let serverFileContent = `${importLines.join(`
|
|
1711
|
+
`)}
|
|
1712
|
+
|
|
1713
|
+
${buildStatement}
|
|
1714
|
+
|
|
1715
|
+
${guardStatements}
|
|
1716
|
+
|
|
1717
|
+
new Elysia()${routeDefinitions}`;
|
|
1718
|
+
useStatements.forEach((statement) => {
|
|
1719
|
+
serverFileContent += `
|
|
1720
|
+
${statement}`;
|
|
1721
|
+
});
|
|
1722
|
+
serverFileContent += `
|
|
1723
|
+
.on('error', (error) => {
|
|
1724
|
+
const { request } = error;
|
|
1725
|
+
console.error(\`Server error on \${request.method} \${request.url}: \${error.message}\`);
|
|
1726
|
+
});
|
|
1727
|
+
`;
|
|
1728
|
+
writeFileSync3(serverFilePath, serverFileContent);
|
|
1729
|
+
};
|
|
1730
|
+
|
|
1731
|
+
// src/generators/project/scaffoldFrontends.ts
|
|
1732
|
+
import { copyFileSync as copyFileSync3, mkdirSync as mkdirSync5 } from "node:fs";
|
|
1733
|
+
import { join as join8 } from "node:path";
|
|
1734
|
+
|
|
1735
|
+
// src/generators/html/scaffoldHTML.ts
|
|
1736
|
+
import { cpSync as cpSync2, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
1737
|
+
import { join as join6 } from "path";
|
|
1738
|
+
|
|
1739
|
+
// src/generators/html/getSSRScript.ts
|
|
1740
|
+
var getSSRScript = (language, isSingle) => `import { HOURS_IN_DAY, TWO_THIRDS } from '${!isSingle ? "../" : ""}../../constants';
|
|
1741
|
+
|
|
1742
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
1743
|
+
const greeting = document.getElementById('greeting');
|
|
1744
|
+
const date = new Date();
|
|
1745
|
+
const hours = date.getHours();
|
|
1746
|
+
|
|
1747
|
+
if (greeting === null) {
|
|
1748
|
+
throw new Error('Greeting element not found');
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
if (hours < HOURS_IN_DAY / 2) {
|
|
1752
|
+
greeting.textContent = 'Good Morning, welcome to AbsoluteJS !';
|
|
1753
|
+
} else if (hours < HOURS_IN_DAY * TWO_THIRDS) {
|
|
1754
|
+
greeting.textContent = 'Good Afternoon, welcome to AbsoluteJS !';
|
|
1755
|
+
} else {
|
|
1756
|
+
greeting.textContent = 'Good Evening, welcome to AbsoluteJS !';
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
const button = document.getElementById('counter-button');
|
|
1760
|
+
const counter = document.getElementById('counter');
|
|
1761
|
+
let count = 0;
|
|
1762
|
+
|
|
1763
|
+
if (button === null || counter === null) {
|
|
1764
|
+
throw new Error('Button or counter element not found');
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
button.addEventListener('click', () => {
|
|
1768
|
+
count++;
|
|
1769
|
+
counter.textContent = count.toString();
|
|
1770
|
+
});
|
|
1771
|
+
|
|
1772
|
+
const links = document.querySelectorAll${language === "ts" && "<HTMLAnchorElement>"}('#links a');
|
|
1773
|
+
links.forEach((link) => {
|
|
1774
|
+
link.addEventListener('mouseover', () => {
|
|
1775
|
+
link.style.transform = 'scale(1.2)';
|
|
1776
|
+
});
|
|
1777
|
+
link.addEventListener('mouseout', () => {
|
|
1778
|
+
link.style.transform = 'scale(1)';
|
|
1779
|
+
});
|
|
1780
|
+
});
|
|
1781
|
+
|
|
1782
|
+
const footerText = document.getElementById('footer-text');
|
|
1783
|
+
|
|
1784
|
+
if (footerText === null) {
|
|
1785
|
+
throw new Error('Footer text element not found');
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
footerText.textContent = \`© ${new Date().getFullYear()} AbsoluteJS\`;
|
|
883
1789
|
});
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1790
|
+
`;
|
|
1791
|
+
|
|
1792
|
+
// src/generators/html/scaffoldHTML.ts
|
|
1793
|
+
var scaffoldHTML = ({
|
|
1794
|
+
templatesDirectory,
|
|
1795
|
+
isSingle,
|
|
1796
|
+
targetDirectory,
|
|
1797
|
+
stylesDirectory,
|
|
1798
|
+
htmlScriptOption,
|
|
1799
|
+
language
|
|
1800
|
+
}) => {
|
|
1801
|
+
const htmlTemplates = join6(templatesDirectory, "html");
|
|
1802
|
+
cpSync2(join6(htmlTemplates, "pages"), join6(targetDirectory, "pages"), {
|
|
1803
|
+
recursive: true
|
|
1804
|
+
});
|
|
1805
|
+
const scriptsDir = join6(targetDirectory, "scripts");
|
|
1806
|
+
mkdirSync3(scriptsDir);
|
|
1807
|
+
if (htmlScriptOption?.includes("ssr")) {
|
|
1808
|
+
const ssrScript = getSSRScript(language, isSingle);
|
|
1809
|
+
const ssrFileName = language === "ts" ? "typescriptSSRExample.ts" : "javascriptSSRExample.js";
|
|
1810
|
+
writeFileSync4(join6(scriptsDir, ssrFileName), ssrScript);
|
|
1811
|
+
}
|
|
1812
|
+
const htmlStylesSrc = join6(htmlTemplates, "styles");
|
|
1813
|
+
if (isSingle) {
|
|
1814
|
+
cpSync2(htmlStylesSrc, stylesDirectory, { recursive: true });
|
|
1815
|
+
} else {
|
|
1816
|
+
const dest = join6(stylesDirectory, "html");
|
|
1817
|
+
mkdirSync3(dest);
|
|
1818
|
+
cpSync2(htmlStylesSrc, dest, { recursive: true });
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
|
|
1822
|
+
// src/generators/react/scaffoldReact.ts
|
|
1823
|
+
import { cpSync as cpSync3, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
1824
|
+
import { join as join7 } from "node:path";
|
|
1825
|
+
|
|
1826
|
+
// src/generators/react/generateHeadComponent.ts
|
|
1827
|
+
var generateHeadComponent = (isSingle) => `import { styleReset } from '${isSingle ? "../../styles" : "../../../styles/react"}/defaultStyles';
|
|
1828
|
+
|
|
1829
|
+
type HeadProps = {
|
|
1830
|
+
title?: string;
|
|
1831
|
+
icon?: string;
|
|
1832
|
+
font?: string;
|
|
1833
|
+
};
|
|
1834
|
+
|
|
1835
|
+
export const Head = ({
|
|
1836
|
+
title = 'AbsoluteJS',
|
|
1837
|
+
icon = '/assets/ico/favicon.ico',
|
|
1838
|
+
font = 'Poppins'
|
|
1839
|
+
}: HeadProps) => (
|
|
1840
|
+
<head>
|
|
1841
|
+
<meta charSet="utf-8" />
|
|
1842
|
+
<title>{title}</title>
|
|
1843
|
+
<meta name="description" content="Bun, Elysia & React" />
|
|
1844
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1845
|
+
<link rel="icon" href={icon} />
|
|
1846
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
1847
|
+
<link
|
|
1848
|
+
rel="preconnect"
|
|
1849
|
+
href="https://fonts.gstatic.com"
|
|
1850
|
+
crossOrigin="anonymous"
|
|
1851
|
+
/>
|
|
1852
|
+
<link
|
|
1853
|
+
href={\`https://fonts.googleapis.com/css2?family=\${font}:wght@100..900&display=swap\`}
|
|
1854
|
+
rel="stylesheet"
|
|
1855
|
+
/>
|
|
1856
|
+
<style>{styleReset}</style>
|
|
1857
|
+
</head>
|
|
1858
|
+
);
|
|
1859
|
+
`;
|
|
1860
|
+
|
|
1861
|
+
// src/generators/react/generateReactPage.ts
|
|
1862
|
+
var generateReactPage = (isSingle) => `import { useState } from 'react';
|
|
1863
|
+
import { Head } from '../components/utils/Head';
|
|
1864
|
+
import {
|
|
1865
|
+
bodyDefault,
|
|
1866
|
+
htmlDefault,
|
|
1867
|
+
mainDefault
|
|
1868
|
+
} from '${isSingle ? "../styles" : "../../styles/react"}/defaultStyles';
|
|
1869
|
+
|
|
1870
|
+
export const ReactExample = () => {
|
|
1871
|
+
const [count, setCount] = useState(0);
|
|
1872
|
+
|
|
1873
|
+
return (
|
|
1874
|
+
<html lang="en" style={htmlDefault}>
|
|
1875
|
+
<Head />
|
|
1876
|
+
<body style={bodyDefault}>
|
|
1877
|
+
<main style={mainDefault}>
|
|
1878
|
+
<style>{\`
|
|
1879
|
+
@keyframes spin {
|
|
1880
|
+
from { transform: rotate(0deg); }
|
|
1881
|
+
to { transform: rotate(360deg); }
|
|
1882
|
+
}
|
|
1883
|
+
\`}</style>
|
|
1884
|
+
<div
|
|
1885
|
+
style={{
|
|
1886
|
+
flex: 1,
|
|
1887
|
+
display: 'flex',
|
|
1888
|
+
flexDirection: 'column',
|
|
1889
|
+
justifyContent: 'center',
|
|
1890
|
+
alignItems: 'center',
|
|
1891
|
+
padding: '1rem',
|
|
1892
|
+
gap: '1.5rem'
|
|
1893
|
+
}}
|
|
1894
|
+
>
|
|
1895
|
+
<a
|
|
1896
|
+
href="https://react.dev"
|
|
1897
|
+
target="_blank"
|
|
1898
|
+
rel="noreferrer"
|
|
1899
|
+
style={{
|
|
1900
|
+
textDecoration: 'none'
|
|
1901
|
+
}}
|
|
1902
|
+
>
|
|
1903
|
+
<img
|
|
1904
|
+
src="/assets/svg/react.svg"
|
|
1905
|
+
alt="React logo"
|
|
1906
|
+
style={{
|
|
1907
|
+
animation: 'spin 20s linear infinite',
|
|
1908
|
+
transformOrigin: 'center center',
|
|
1909
|
+
height: 145,
|
|
1910
|
+
display: 'block'
|
|
1911
|
+
}}
|
|
1912
|
+
/>
|
|
1913
|
+
</a>
|
|
1914
|
+
<h1
|
|
1915
|
+
style={{
|
|
1916
|
+
fontSize: '2rem',
|
|
1917
|
+
fontWeight: 600,
|
|
1918
|
+
color: '#333',
|
|
1919
|
+
margin: 0
|
|
1920
|
+
}}
|
|
1921
|
+
>
|
|
1922
|
+
AbsoluteJS + React
|
|
1923
|
+
</h1>
|
|
1924
|
+
<button
|
|
1925
|
+
onClick={() => setCount(prev => prev + 1)}
|
|
1926
|
+
style={{
|
|
1927
|
+
padding: '0.75rem 1.5rem',
|
|
1928
|
+
fontSize: '1rem',
|
|
1929
|
+
fontWeight: 500,
|
|
1930
|
+
backgroundColor: '#0070f3',
|
|
1931
|
+
color: '#fff',
|
|
1932
|
+
border: 'none',
|
|
1933
|
+
borderRadius: '5px',
|
|
1934
|
+
cursor: 'pointer'
|
|
1935
|
+
}}
|
|
1936
|
+
>
|
|
1937
|
+
count is {count}
|
|
1938
|
+
</button>
|
|
1939
|
+
<p style={{ fontSize: '1rem', color: '#555', margin: 0 }}>
|
|
1940
|
+
Edit{' '}
|
|
1941
|
+
<code
|
|
1942
|
+
style={{
|
|
1943
|
+
backgroundColor: '#f5f5f5',
|
|
1944
|
+
padding: '0.2rem 0.4rem',
|
|
1945
|
+
borderRadius: '3px',
|
|
1946
|
+
fontFamily: 'monospace'
|
|
1947
|
+
}}
|
|
1948
|
+
>
|
|
1949
|
+
src/frontend/${isSingle ? "" : "react"}/pages/ReactExample.tsx
|
|
1950
|
+
</code>{' '}
|
|
1951
|
+
to edit this page
|
|
1952
|
+
</p>
|
|
1953
|
+
</div>
|
|
1954
|
+
</main>
|
|
1955
|
+
</body>
|
|
1956
|
+
</html>
|
|
1957
|
+
);
|
|
1958
|
+
};
|
|
1959
|
+
`;
|
|
1960
|
+
|
|
1961
|
+
// src/generators/react/scaffoldReact.ts
|
|
1962
|
+
var scaffoldReact = ({
|
|
1963
|
+
stylesDirectory,
|
|
1964
|
+
templatesDirectory,
|
|
1965
|
+
isSingle,
|
|
1966
|
+
targetDirectory
|
|
1967
|
+
}) => {
|
|
1968
|
+
const reactStylesSrc = join7(templatesDirectory, "react", "styles");
|
|
1969
|
+
const reactTemplates = join7(templatesDirectory, "react");
|
|
1970
|
+
const pagesDirectory = join7(targetDirectory, "pages");
|
|
1971
|
+
const componentsDirectory = join7(targetDirectory, "components");
|
|
1972
|
+
const pageExample = generateReactPage(isSingle);
|
|
1973
|
+
const headComponent = generateHeadComponent(isSingle);
|
|
1974
|
+
mkdirSync4(pagesDirectory);
|
|
1975
|
+
writeFileSync5(join7(pagesDirectory, "ReactExample.tsx"), pageExample);
|
|
1976
|
+
mkdirSync4(join7(componentsDirectory, "utils"), { recursive: true });
|
|
1977
|
+
writeFileSync5(join7(componentsDirectory, "utils", "Head.tsx"), headComponent);
|
|
1978
|
+
cpSync3(join7(reactTemplates, "hooks"), join7(targetDirectory, "hooks"), {
|
|
1979
|
+
recursive: true
|
|
1980
|
+
});
|
|
1981
|
+
if (isSingle) {
|
|
1982
|
+
cpSync3(reactStylesSrc, stylesDirectory, {
|
|
1983
|
+
recursive: true
|
|
1984
|
+
});
|
|
1985
|
+
} else {
|
|
1986
|
+
const dest = join7(stylesDirectory, "react");
|
|
1987
|
+
mkdirSync4(dest);
|
|
1988
|
+
cpSync3(reactStylesSrc, dest, {
|
|
1989
|
+
recursive: true
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1992
|
+
};
|
|
1993
|
+
|
|
1994
|
+
// src/generators/project/scaffoldFrontends.ts
|
|
1995
|
+
var scaffoldFrontends = ({
|
|
1996
|
+
frontendDirectory,
|
|
1997
|
+
language,
|
|
1998
|
+
templatesDirectory,
|
|
1999
|
+
frontendConfigurations,
|
|
2000
|
+
tailwind,
|
|
2001
|
+
htmlScriptOption
|
|
2002
|
+
}) => {
|
|
2003
|
+
const isSingle = frontendConfigurations.length === 1;
|
|
2004
|
+
const stylesDirectory = join8(frontendDirectory, "styles");
|
|
2005
|
+
mkdirSync5(stylesDirectory);
|
|
2006
|
+
if (tailwind !== undefined) {
|
|
2007
|
+
copyFileSync3(join8(templatesDirectory, "tailwind", "tailwind.css"), join8(stylesDirectory, "tailwind.css"));
|
|
2008
|
+
}
|
|
2009
|
+
const dirMap = new Map;
|
|
2010
|
+
frontendConfigurations.forEach(({ name, directory }) => {
|
|
2011
|
+
const dir = directory?.trim() ?? (isSingle ? "" : name);
|
|
2012
|
+
if (dirMap.has(dir)) {
|
|
2013
|
+
throw new Error(`Frontend directory collision: "${dir}" is assigned to both "${dirMap.get(dir)}" and "${name}". Please pick unique directories.`);
|
|
2014
|
+
}
|
|
2015
|
+
dirMap.set(dir, name);
|
|
2016
|
+
const targetDirectory = join8(frontendDirectory, dir);
|
|
2017
|
+
!isSingle && mkdirSync5(targetDirectory);
|
|
2018
|
+
if (name === "react") {
|
|
2019
|
+
scaffoldReact({
|
|
2020
|
+
isSingle,
|
|
2021
|
+
stylesDirectory,
|
|
2022
|
+
targetDirectory,
|
|
2023
|
+
templatesDirectory
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
if (name === "html") {
|
|
2027
|
+
scaffoldHTML({
|
|
2028
|
+
htmlScriptOption,
|
|
2029
|
+
isSingle,
|
|
2030
|
+
language,
|
|
2031
|
+
stylesDirectory,
|
|
2032
|
+
targetDirectory,
|
|
2033
|
+
templatesDirectory
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
// src/scaffold.ts
|
|
2040
|
+
var scaffold = ({
|
|
2041
|
+
response: {
|
|
2042
|
+
projectName,
|
|
2043
|
+
language,
|
|
2044
|
+
codeQualityTool,
|
|
2045
|
+
initializeGitNow,
|
|
2046
|
+
databaseEngine,
|
|
2047
|
+
databaseHost,
|
|
2048
|
+
htmlScriptOption,
|
|
2049
|
+
useTailwind,
|
|
2050
|
+
databaseDirectory,
|
|
2051
|
+
orm,
|
|
2052
|
+
plugins,
|
|
2053
|
+
authProvider,
|
|
2054
|
+
buildDirectory,
|
|
2055
|
+
assetsDirectory,
|
|
2056
|
+
tailwind,
|
|
2057
|
+
installDependenciesNow,
|
|
2058
|
+
frontendConfigurations
|
|
2059
|
+
},
|
|
2060
|
+
latest,
|
|
2061
|
+
packageManager
|
|
2062
|
+
}) => {
|
|
2063
|
+
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
2064
|
+
const templatesDirectory = join9(__dirname2, "/templates");
|
|
2065
|
+
const { frontendDirectory, backendDirectory } = initalizeRoot(projectName, templatesDirectory);
|
|
2066
|
+
copyFileSync4(join9(templatesDirectory, "README.md"), join9(projectName, "README.md"));
|
|
2067
|
+
addConfigurationFiles({
|
|
2068
|
+
codeQualityTool,
|
|
2069
|
+
initializeGitNow,
|
|
2070
|
+
language,
|
|
2071
|
+
projectName,
|
|
2072
|
+
tailwind,
|
|
2073
|
+
templatesDirectory
|
|
2074
|
+
});
|
|
2075
|
+
createPackageJson({
|
|
2076
|
+
authProvider,
|
|
2077
|
+
frontendConfigurations,
|
|
2078
|
+
latest,
|
|
2079
|
+
plugins,
|
|
2080
|
+
projectName,
|
|
2081
|
+
useTailwind
|
|
2082
|
+
});
|
|
2083
|
+
const serverFilePath = join9(backendDirectory, "server.ts");
|
|
2084
|
+
createServerFile({
|
|
2085
|
+
assetsDirectory,
|
|
2086
|
+
authProvider,
|
|
2087
|
+
availablePlugins,
|
|
2088
|
+
buildDirectory,
|
|
2089
|
+
frontendConfigurations,
|
|
2090
|
+
plugins,
|
|
2091
|
+
serverFilePath,
|
|
2092
|
+
tailwind
|
|
2093
|
+
});
|
|
2094
|
+
databaseDirectory !== undefined && scaffoldDatabase({
|
|
2095
|
+
databaseDirectory,
|
|
2096
|
+
databaseEngine,
|
|
2097
|
+
orm,
|
|
2098
|
+
projectName
|
|
2099
|
+
});
|
|
2100
|
+
scaffoldFrontends({
|
|
2101
|
+
frontendConfigurations,
|
|
2102
|
+
frontendDirectory,
|
|
2103
|
+
htmlScriptOption,
|
|
2104
|
+
language,
|
|
2105
|
+
tailwind,
|
|
2106
|
+
templatesDirectory
|
|
2107
|
+
});
|
|
2108
|
+
if (installDependenciesNow) {
|
|
2109
|
+
installDependencies({ packageManager, projectName });
|
|
2110
|
+
}
|
|
2111
|
+
formatProject({
|
|
2112
|
+
packageManager,
|
|
2113
|
+
projectName
|
|
2114
|
+
});
|
|
2115
|
+
};
|
|
2116
|
+
|
|
2117
|
+
// src/utils/t3-utils.ts
|
|
2118
|
+
import { env } from "node:process";
|
|
2119
|
+
var getUserPackageManager = () => {
|
|
2120
|
+
const userAgent = env.npm_config_user_agent;
|
|
2121
|
+
if (userAgent) {
|
|
2122
|
+
if (userAgent.startsWith("yarn")) {
|
|
2123
|
+
return "yarn";
|
|
2124
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
2125
|
+
return "pnpm";
|
|
2126
|
+
} else if (userAgent.startsWith("bun")) {
|
|
2127
|
+
return "bun";
|
|
2128
|
+
}
|
|
2129
|
+
return "npm";
|
|
2130
|
+
}
|
|
2131
|
+
return "npm";
|
|
2132
|
+
};
|
|
2133
|
+
|
|
2134
|
+
// src/index.ts
|
|
2135
|
+
var { values } = parseArgs({
|
|
2136
|
+
args: argv.slice(DEFAULT_ARG_LENGTH),
|
|
2137
|
+
options: {
|
|
2138
|
+
debug: { default: false, short: "d", type: "boolean" },
|
|
2139
|
+
help: { default: false, short: "h", type: "boolean" },
|
|
2140
|
+
latest: { default: false, short: "l", type: "boolean" }
|
|
2141
|
+
},
|
|
2142
|
+
strict: false
|
|
895
2143
|
});
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
2144
|
+
var packageManager = getUserPackageManager();
|
|
2145
|
+
if (values.help === true) {
|
|
2146
|
+
console.log(helpMessage);
|
|
2147
|
+
exit4(0);
|
|
2148
|
+
}
|
|
2149
|
+
var response = await prompt();
|
|
2150
|
+
scaffold({ latest: values.latest === true, packageManager, response });
|
|
2151
|
+
var debugMessage = values.debug !== false ? getDebugMessage({
|
|
2152
|
+
availableFrontends,
|
|
2153
|
+
packageManager,
|
|
2154
|
+
response
|
|
2155
|
+
}) : "";
|
|
2156
|
+
var outroMessage = getOutroMessage({
|
|
2157
|
+
installDependenciesNow: response.installDependenciesNow,
|
|
2158
|
+
packageManager,
|
|
2159
|
+
projectName: response.projectName
|
|
2160
|
+
});
|
|
2161
|
+
Se(debugMessage + outroMessage);
|