create-absolutejs 0.1.9 → 0.2.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
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
var __create = Object.create;
|
|
3
2
|
var __getProtoOf = Object.getPrototypeOf;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
@@ -146,8 +145,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
146
145
|
});
|
|
147
146
|
|
|
148
147
|
// src/index.ts
|
|
149
|
-
import {
|
|
150
|
-
import { parseArgs } from "node:util";
|
|
148
|
+
import { exit as exit5 } from "node:process";
|
|
151
149
|
|
|
152
150
|
// node_modules/@clack/core/dist/index.mjs
|
|
153
151
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
@@ -837,21 +835,49 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
837
835
|
} };
|
|
838
836
|
};
|
|
839
837
|
|
|
840
|
-
// src/
|
|
841
|
-
var
|
|
842
|
-
var DEFAULT_ARG_LENGTH = 2;
|
|
843
|
-
var TWO_THIRDS = 2 / 3;
|
|
838
|
+
// src/messages.ts
|
|
839
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
844
840
|
|
|
845
841
|
// src/data.ts
|
|
846
842
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
847
|
-
var availableFrontends =
|
|
848
|
-
react
|
|
849
|
-
html
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
843
|
+
var availableFrontends = [
|
|
844
|
+
"react",
|
|
845
|
+
"html",
|
|
846
|
+
"svelte",
|
|
847
|
+
"htmx"
|
|
848
|
+
];
|
|
849
|
+
var availableAuthProviders = ["absoluteAuth", "none"];
|
|
850
|
+
var availableLanguages = ["ts", "js"];
|
|
851
|
+
var availableHTMLScriptOptions = ["js", "ts", "none"];
|
|
852
|
+
var availableDatabaseEngines = [
|
|
853
|
+
"postgresql",
|
|
854
|
+
"mysql",
|
|
855
|
+
"sqlite",
|
|
856
|
+
"mongodb",
|
|
857
|
+
"redis",
|
|
858
|
+
"singlestore",
|
|
859
|
+
"cockroachdb",
|
|
860
|
+
"mssql",
|
|
861
|
+
"none"
|
|
862
|
+
];
|
|
863
|
+
var availableDirectoryConfigurations = ["default", "custom"];
|
|
864
|
+
var availableORMs = ["drizzle", "prisma", "none"];
|
|
865
|
+
var availableDatabaseHosts = [
|
|
866
|
+
"neon",
|
|
867
|
+
"planetscale",
|
|
868
|
+
"supabase",
|
|
869
|
+
"turso",
|
|
870
|
+
"vercel",
|
|
871
|
+
"upstash",
|
|
872
|
+
"atlas",
|
|
873
|
+
"none"
|
|
874
|
+
];
|
|
875
|
+
var availableCodeQualityTools = ["eslint+prettier", "biome"];
|
|
876
|
+
var frontendLabels = {
|
|
877
|
+
react: import_picocolors3.cyan("React"),
|
|
878
|
+
html: "HTML",
|
|
879
|
+
svelte: import_picocolors3.magenta("Svelte"),
|
|
880
|
+
htmx: "HTMX"
|
|
855
881
|
};
|
|
856
882
|
var availablePlugins = [
|
|
857
883
|
{
|
|
@@ -907,7 +933,7 @@ var defaultPlugins = [
|
|
|
907
933
|
{ isPlugin: false, packageName: "build" },
|
|
908
934
|
{ isPlugin: true, packageName: "networkingPlugin" }
|
|
909
935
|
],
|
|
910
|
-
latestVersion: "0.
|
|
936
|
+
latestVersion: "0.8.14",
|
|
911
937
|
value: "@absolutejs/absolute"
|
|
912
938
|
},
|
|
913
939
|
{
|
|
@@ -924,18 +950,43 @@ var defaultPlugins = [
|
|
|
924
950
|
];
|
|
925
951
|
|
|
926
952
|
// src/messages.ts
|
|
927
|
-
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
928
953
|
var helpMessage = `
|
|
929
|
-
Usage: create-absolute [options] [
|
|
954
|
+
Usage: create-absolute [options] [${import_picocolors4.magenta("project-name")}]
|
|
930
955
|
|
|
931
956
|
Arguments:
|
|
932
|
-
|
|
933
|
-
|
|
957
|
+
${import_picocolors4.magenta("project-name")} Name of the application to create.
|
|
958
|
+
If omitted, you'll be prompted to enter one.
|
|
934
959
|
|
|
935
960
|
Options:
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
961
|
+
${import_picocolors4.cyan("--help, -h")} Show this help message and exit
|
|
962
|
+
${import_picocolors4.cyan("--debug, -d")} Display a summary of the project configuration after creation
|
|
963
|
+
|
|
964
|
+
${import_picocolors4.cyan("--angular")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an Angular frontend
|
|
965
|
+
${import_picocolors4.cyan("--assets")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for your static assets
|
|
966
|
+
${import_picocolors4.cyan("--auth")} ${import_picocolors4.dim(import_picocolors4.cyan("<plugin>"))} Preconfigured auth plugin (currently only "absolute-auth") or 'none' to skip auth setup
|
|
967
|
+
${import_picocolors4.cyan("--build")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Output directory for build artifacts
|
|
968
|
+
${import_picocolors4.cyan("--database")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for your database files
|
|
969
|
+
${import_picocolors4.cyan("--directory")} ${import_picocolors4.dim(import_picocolors4.cyan("<mode>"))} Directory-naming strategy: "default" or "custom"
|
|
970
|
+
${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
|
|
971
|
+
${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"
|
|
972
|
+
${import_picocolors4.cyan("--git")} Initialize a Git repository
|
|
973
|
+
${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
|
|
974
|
+
${import_picocolors4.cyan("--html")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an HTML frontend
|
|
975
|
+
${import_picocolors4.cyan("--htmx")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for an HTMX frontend
|
|
976
|
+
${import_picocolors4.cyan("--lang")} ${import_picocolors4.dim(import_picocolors4.cyan("<lang>"))} Language: "ts" or "js"
|
|
977
|
+
${import_picocolors4.cyan("--lts")} Use LTS versions of required packages
|
|
978
|
+
${import_picocolors4.cyan("--npm")} Use the package manager that invoked this command to install dependencies
|
|
979
|
+
${import_picocolors4.cyan("--orm")} ${import_picocolors4.dim(import_picocolors4.cyan("<orm>"))} ORM to configure: "drizzle" or "prisma" or 'none' to skip ORM setup
|
|
980
|
+
${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
|
|
981
|
+
${import_picocolors4.cyan("--quality")} ${import_picocolors4.dim(import_picocolors4.cyan("<tool>"))} Code quality tool: "eslint+prettier" or "biome"
|
|
982
|
+
${import_picocolors4.cyan("--react")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a React frontend
|
|
983
|
+
${import_picocolors4.cyan("--script")} ${import_picocolors4.dim(import_picocolors4.cyan("<option>"))} HTML scripting option: "ts" or "js" or 'none' to skip HTML scripting setup
|
|
984
|
+
${import_picocolors4.cyan("--skip")} Skips non required prompts and uses 'none' for all optional configurations
|
|
985
|
+
${import_picocolors4.cyan("--svelte")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a Svelte frontend
|
|
986
|
+
${import_picocolors4.cyan("--tailwind")} Include Tailwind CSS setup
|
|
987
|
+
${import_picocolors4.cyan("--tailwind-input")} ${import_picocolors4.dim(import_picocolors4.cyan("<file>"))} Path to your Tailwind CSS entry file
|
|
988
|
+
${import_picocolors4.cyan("--tailwind-output")} ${import_picocolors4.dim(import_picocolors4.cyan("<file>"))} Path for the generated Tailwind CSS bundle
|
|
989
|
+
${import_picocolors4.cyan("--vue")} ${import_picocolors4.dim(import_picocolors4.cyan("<dir>"))} Directory name for a Vue frontend
|
|
939
990
|
`;
|
|
940
991
|
var getOutroMessage = ({
|
|
941
992
|
projectName,
|
|
@@ -944,19 +995,19 @@ var getOutroMessage = ({
|
|
|
944
995
|
}) => `${import_picocolors4.green("Created successfully")}, you can now run:
|
|
945
996
|
|
|
946
997
|
` + `${import_picocolors4.cyan("cd")} ${projectName}
|
|
947
|
-
` + `${import_picocolors4.cyan(`${packageManager}
|
|
948
|
-
|
|
998
|
+
` + `${installDependenciesNow ? "" : `${import_picocolors4.cyan(`${packageManager} install`)}
|
|
999
|
+
`}` + `${import_picocolors4.cyan(`${packageManager} dev`)}`;
|
|
949
1000
|
var getDebugMessage = ({
|
|
950
1001
|
response: {
|
|
951
1002
|
projectName,
|
|
952
1003
|
language,
|
|
953
1004
|
codeQualityTool,
|
|
954
|
-
|
|
1005
|
+
directoryConfig,
|
|
955
1006
|
useTailwind,
|
|
956
1007
|
tailwind,
|
|
957
1008
|
frontends,
|
|
958
1009
|
htmlScriptOption,
|
|
959
|
-
|
|
1010
|
+
frontendDirectories,
|
|
960
1011
|
buildDirectory,
|
|
961
1012
|
assetsDirectory,
|
|
962
1013
|
databaseEngine,
|
|
@@ -968,51 +1019,49 @@ var getDebugMessage = ({
|
|
|
968
1019
|
initializeGitNow,
|
|
969
1020
|
installDependenciesNow
|
|
970
1021
|
},
|
|
971
|
-
packageManager
|
|
972
|
-
availableFrontends: availableFrontends2
|
|
1022
|
+
packageManager
|
|
973
1023
|
}) => {
|
|
974
1024
|
const htmlLabels = {
|
|
975
1025
|
js: import_picocolors4.yellow("JavaScript"),
|
|
976
|
-
|
|
977
|
-
ts: import_picocolors4.blueBright("TypeScript")
|
|
978
|
-
"ts+ssr": import_picocolors4.blueBright("TypeScript + SSR")
|
|
1026
|
+
none: import_picocolors4.dim("None"),
|
|
1027
|
+
ts: import_picocolors4.blueBright("TypeScript")
|
|
979
1028
|
};
|
|
980
|
-
const htmlScriptingValue = htmlScriptOption
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
const
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
${
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1029
|
+
const htmlScriptingValue = htmlScriptOption ? htmlLabels[htmlScriptOption] : import_picocolors4.dim("None");
|
|
1030
|
+
const frameworkConfig = frontends.map((name) => `${frontendLabels[name]}: src/frontend/${frontendDirectories[name]}`).join(`
|
|
1031
|
+
`);
|
|
1032
|
+
const tailwindSection = useTailwind && tailwind ? `Input: ${tailwind.input}
|
|
1033
|
+
Output: ${tailwind.output}` : import_picocolors4.dim("None");
|
|
1034
|
+
const isCustomConfig = directoryConfig === "custom";
|
|
1035
|
+
const lines = [
|
|
1036
|
+
["Project Name", projectName],
|
|
1037
|
+
["Package Manager", packageManager],
|
|
1038
|
+
["Config Type", isCustomConfig ? import_picocolors4.green("Custom") : import_picocolors4.dim("Default")],
|
|
1039
|
+
["Language", language === "ts" ? import_picocolors4.blueBright("TypeScript") : import_picocolors4.yellow("JavaScript")],
|
|
1040
|
+
["Linting", codeQualityTool === "eslint+prettier" ? "ESLint + Prettier" : "Biome"],
|
|
1041
|
+
["Tailwind Configuration", tailwindSection],
|
|
1042
|
+
[frontends.length === 1 ? "Frontend" : "Frontends", frontends.map((name) => frontendLabels[name]).join(", ")],
|
|
1043
|
+
["HTML Scripting", frontends.includes("html") ? htmlScriptingValue : import_picocolors4.dim("None")],
|
|
1044
|
+
["Build Directory", buildDirectory],
|
|
1045
|
+
["Assets Directory", assetsDirectory],
|
|
1046
|
+
["Database Engine", databaseEngine && databaseEngine !== "none" ? databaseEngine : import_picocolors4.dim("None")],
|
|
1047
|
+
["Database Host", databaseHost && databaseHost !== "none" ? databaseHost : import_picocolors4.dim("None")],
|
|
1048
|
+
["Database Directory", databaseDirectory ?? import_picocolors4.dim("None")],
|
|
1049
|
+
["ORM", orm ?? import_picocolors4.dim("None")],
|
|
1050
|
+
["Auth Provider", authProvider && authProvider !== "none" ? authProvider : import_picocolors4.dim("None")],
|
|
1051
|
+
["Plugins", plugins.length && !plugins.includes("none") ? plugins.join(", ") : import_picocolors4.dim("None")],
|
|
1052
|
+
["Initialize Git", initializeGitNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")],
|
|
1053
|
+
["Install Dependencies", installDependenciesNow ? import_picocolors4.green("Yes") : import_picocolors4.red("No")],
|
|
1054
|
+
["Framework Config", frameworkConfig]
|
|
1055
|
+
];
|
|
1056
|
+
const maxLabelLength = Math.max(...lines.map(([label]) => label.length));
|
|
1057
|
+
const body = `
|
|
1058
|
+
|
|
1059
|
+
${lines.map(([label, value]) => {
|
|
1060
|
+
const gap = " ".repeat(maxLabelLength - label.length);
|
|
1061
|
+
return `${import_picocolors4.magenta(label)}:${gap} ${value}`;
|
|
1062
|
+
}).join(`
|
|
1063
|
+
`)}`;
|
|
1064
|
+
return body;
|
|
1016
1065
|
};
|
|
1017
1066
|
|
|
1018
1067
|
// src/questions/authProvider.ts
|
|
@@ -1060,16 +1109,16 @@ var getCodeQualityTool = async () => {
|
|
|
1060
1109
|
// src/questions/configurationType.ts
|
|
1061
1110
|
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
1062
1111
|
var getConfigurationType = async () => {
|
|
1063
|
-
const
|
|
1112
|
+
const directoryConfig = await ve({
|
|
1064
1113
|
message: "Choose folder naming configuration:",
|
|
1065
1114
|
options: [
|
|
1066
1115
|
{ label: import_picocolors7.blueBright("Default"), value: "default" },
|
|
1067
1116
|
{ label: import_picocolors7.yellow("Custom"), value: "custom" }
|
|
1068
1117
|
]
|
|
1069
1118
|
});
|
|
1070
|
-
if (pD(
|
|
1119
|
+
if (pD(directoryConfig))
|
|
1071
1120
|
abort();
|
|
1072
|
-
return
|
|
1121
|
+
return directoryConfig;
|
|
1073
1122
|
};
|
|
1074
1123
|
|
|
1075
1124
|
// src/questions/databaseEngine.ts
|
|
@@ -1147,28 +1196,29 @@ var getDatabaseHost = async (databaseEngine) => {
|
|
|
1147
1196
|
|
|
1148
1197
|
// src/questions/directoryConfiguration.ts
|
|
1149
1198
|
var getDirectoryConfiguration = async ({
|
|
1150
|
-
|
|
1199
|
+
directoryConfig,
|
|
1151
1200
|
useTailwind,
|
|
1152
|
-
databaseEngine
|
|
1201
|
+
databaseEngine,
|
|
1202
|
+
argumentConfiguration
|
|
1153
1203
|
}) => {
|
|
1154
|
-
if (
|
|
1204
|
+
if (directoryConfig === "default") {
|
|
1155
1205
|
return {
|
|
1156
|
-
assetsDirectory: "src/backend/assets",
|
|
1157
|
-
buildDirectory: "build",
|
|
1158
|
-
databaseDirectory: databaseEngine
|
|
1206
|
+
assetsDirectory: argumentConfiguration.assetsDirectory ?? "src/backend/assets",
|
|
1207
|
+
buildDirectory: argumentConfiguration.buildDirectory ?? "build",
|
|
1208
|
+
databaseDirectory: databaseEngine ? argumentConfiguration.databaseDirectory ?? "db" : undefined,
|
|
1159
1209
|
tailwind: useTailwind ? {
|
|
1160
|
-
input: "./src/frontend/styles/tailwind.css",
|
|
1161
|
-
output: "/assets/css/tailwind.generated.css"
|
|
1210
|
+
input: argumentConfiguration.tailwind?.input ?? "./src/frontend/styles/tailwind.css",
|
|
1211
|
+
output: argumentConfiguration.tailwind?.output ?? "/assets/css/tailwind.generated.css"
|
|
1162
1212
|
} : undefined
|
|
1163
1213
|
};
|
|
1164
1214
|
}
|
|
1165
|
-
const buildDirectory = await he({
|
|
1215
|
+
const buildDirectory = argumentConfiguration.buildDirectory ?? await he({
|
|
1166
1216
|
message: "Build directory:",
|
|
1167
1217
|
placeholder: "build"
|
|
1168
1218
|
});
|
|
1169
1219
|
if (pD(buildDirectory))
|
|
1170
1220
|
abort();
|
|
1171
|
-
const assetsDirectory = await he({
|
|
1221
|
+
const assetsDirectory = argumentConfiguration.assetsDirectory ?? await he({
|
|
1172
1222
|
message: "Assets directory:",
|
|
1173
1223
|
placeholder: "src/backend/assets"
|
|
1174
1224
|
});
|
|
@@ -1176,13 +1226,13 @@ var getDirectoryConfiguration = async ({
|
|
|
1176
1226
|
abort();
|
|
1177
1227
|
let tailwind;
|
|
1178
1228
|
if (useTailwind) {
|
|
1179
|
-
const input = await he({
|
|
1229
|
+
const input = argumentConfiguration.tailwind?.input ?? await he({
|
|
1180
1230
|
message: "Tailwind input CSS file:",
|
|
1181
1231
|
placeholder: "./src/frontend/styles/tailwind.css"
|
|
1182
1232
|
});
|
|
1183
1233
|
if (pD(input))
|
|
1184
1234
|
abort();
|
|
1185
|
-
const output = await he({
|
|
1235
|
+
const output = argumentConfiguration.tailwind?.output ?? await he({
|
|
1186
1236
|
message: "Tailwind output CSS file:",
|
|
1187
1237
|
placeholder: "/assets/css/tailwind.generated.css"
|
|
1188
1238
|
});
|
|
@@ -1194,7 +1244,7 @@ var getDirectoryConfiguration = async ({
|
|
|
1194
1244
|
}
|
|
1195
1245
|
let databaseDirectory;
|
|
1196
1246
|
if (databaseEngine !== undefined) {
|
|
1197
|
-
databaseDirectory = await he({
|
|
1247
|
+
databaseDirectory = argumentConfiguration.databaseDirectory ?? await he({
|
|
1198
1248
|
message: "Database directory:",
|
|
1199
1249
|
placeholder: "db"
|
|
1200
1250
|
});
|
|
@@ -1210,62 +1260,66 @@ var getDirectoryConfiguration = async ({
|
|
|
1210
1260
|
};
|
|
1211
1261
|
|
|
1212
1262
|
// src/questions/frontendDirectoryConfigurations.ts
|
|
1213
|
-
var
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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;
|
|
1263
|
+
var getDirectoryForFrontend = async (directoryConfiguration, frontend, isSingleFrontend) => {
|
|
1264
|
+
if (directoryConfiguration !== "custom")
|
|
1265
|
+
return isSingleFrontend ? "" : frontend;
|
|
1266
|
+
const response = await he({
|
|
1267
|
+
message: `${frontendLabels[frontend]} directory:`,
|
|
1268
|
+
placeholder: isSingleFrontend ? "" : frontend
|
|
1269
|
+
});
|
|
1270
|
+
if (pD(response))
|
|
1271
|
+
abort();
|
|
1272
|
+
return response;
|
|
1241
1273
|
};
|
|
1274
|
+
var getFrontendDirectoryConfigurations = async (directoryConfiguration, frontends, passedFrontendDirectories) => {
|
|
1275
|
+
const isSingleFrontend = frontends.length === 1;
|
|
1276
|
+
const frontendDirectories = {};
|
|
1277
|
+
const frontendsToPrompt = [];
|
|
1278
|
+
for (const frontend of frontends) {
|
|
1279
|
+
const prefilled = passedFrontendDirectories?.[frontend];
|
|
1280
|
+
if (prefilled === undefined)
|
|
1281
|
+
frontendsToPrompt.push(frontend);
|
|
1282
|
+
else
|
|
1283
|
+
frontendDirectories[frontend] = prefilled;
|
|
1284
|
+
}
|
|
1285
|
+
const promptedDirectories = await Promise.all(frontendsToPrompt.map((name) => getDirectoryForFrontend(directoryConfiguration, name, isSingleFrontend)));
|
|
1286
|
+
frontendsToPrompt.forEach((name, index) => frontendDirectories[name] = promptedDirectories[index]);
|
|
1287
|
+
return frontendDirectories;
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
// src/typeGuards.ts
|
|
1291
|
+
var isLanguage = (value) => value === "ts" || value === "js";
|
|
1292
|
+
var isAuthProvider = (value) => value === "absoluteAuth" || value === "none" || value === undefined;
|
|
1293
|
+
var isDirectoryConfig = (value) => value === "default" || value === "custom";
|
|
1294
|
+
var isDatabaseEngine = (value) => value === "postgresql" || value === "mysql" || value === "sqlite" || value === "mongodb" || value === "redis" || value === "singlestore" || value === "cockroachdb" || value === "mssql" || value === "none" || value === undefined;
|
|
1295
|
+
var isDatabaseHost = (value) => value === "neon" || value === "planetscale" || value === "supabase" || value === "turso" || value === "vercel" || value === "upstash" || value === "atlas" || value === undefined;
|
|
1296
|
+
var isORM = (value) => value === "drizzle" || value === "prisma" || value === undefined;
|
|
1297
|
+
var isCodeQualityTool = (value) => value === "eslint+prettier" || value === "biome" || value === undefined;
|
|
1298
|
+
var isHTMLScriptOption = (value) => value === "ts" || value === "js" || value === "ts+ssr" || value === "js+ssr" || value === "none" || value === undefined;
|
|
1299
|
+
var isFrontend = (value) => value !== undefined && Object.keys(frontendLabels).includes(value);
|
|
1242
1300
|
|
|
1243
1301
|
// src/questions/frontends.ts
|
|
1244
1302
|
var getFrontends = async () => {
|
|
1245
1303
|
const frontends = await fe({
|
|
1246
1304
|
message: "Frontend(s) (space to select, enter to finish):",
|
|
1247
|
-
options: Object.entries(
|
|
1305
|
+
options: Object.entries(frontendLabels).map(([value, label]) => ({
|
|
1306
|
+
label,
|
|
1307
|
+
value
|
|
1308
|
+
}))
|
|
1248
1309
|
});
|
|
1249
1310
|
if (pD(frontends))
|
|
1250
1311
|
abort();
|
|
1251
|
-
return frontends;
|
|
1312
|
+
return frontends.filter(isFrontend);
|
|
1252
1313
|
};
|
|
1253
1314
|
|
|
1254
1315
|
// src/questions/htmlScriptingOption.ts
|
|
1255
|
-
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
1256
1316
|
var getHtmlScriptingOption = async (language) => {
|
|
1257
|
-
const
|
|
1258
|
-
|
|
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
|
-
]
|
|
1317
|
+
const useScripts = await ye({
|
|
1318
|
+
message: "Would you like to use scripts for your HTML pages?"
|
|
1265
1319
|
});
|
|
1266
|
-
if (pD(
|
|
1320
|
+
if (pD(useScripts))
|
|
1267
1321
|
abort();
|
|
1268
|
-
return
|
|
1322
|
+
return useScripts ? language : undefined;
|
|
1269
1323
|
};
|
|
1270
1324
|
|
|
1271
1325
|
// src/questions/initializeGitNow.ts
|
|
@@ -1289,13 +1343,13 @@ var getInstallDependencies = async () => {
|
|
|
1289
1343
|
};
|
|
1290
1344
|
|
|
1291
1345
|
// src/questions/language.ts
|
|
1292
|
-
var
|
|
1346
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
1293
1347
|
var getLanguage = async () => {
|
|
1294
1348
|
const language = await ve({
|
|
1295
1349
|
message: "Language:",
|
|
1296
1350
|
options: [
|
|
1297
|
-
{ label:
|
|
1298
|
-
{ label:
|
|
1351
|
+
{ label: import_picocolors10.blueBright("TypeScript"), value: "ts" },
|
|
1352
|
+
{ label: import_picocolors10.yellow("JavaScript"), value: "js" }
|
|
1299
1353
|
]
|
|
1300
1354
|
});
|
|
1301
1355
|
if (pD(language))
|
|
@@ -1304,14 +1358,14 @@ var getLanguage = async () => {
|
|
|
1304
1358
|
};
|
|
1305
1359
|
|
|
1306
1360
|
// src/questions/orm.ts
|
|
1307
|
-
var
|
|
1361
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
1308
1362
|
var getORM = async () => {
|
|
1309
1363
|
const orm = await ve({
|
|
1310
1364
|
message: "Choose an ORM (optional):",
|
|
1311
1365
|
options: [
|
|
1312
1366
|
{ label: "None", value: "none" },
|
|
1313
|
-
{ label:
|
|
1314
|
-
{ label:
|
|
1367
|
+
{ label: import_picocolors11.cyan("Drizzle"), value: "drizzle" },
|
|
1368
|
+
{ label: import_picocolors11.magenta("Prisma"), value: "prisma" }
|
|
1315
1369
|
]
|
|
1316
1370
|
});
|
|
1317
1371
|
if (pD(orm))
|
|
@@ -1351,37 +1405,40 @@ var getUseTailwind = async () => {
|
|
|
1351
1405
|
};
|
|
1352
1406
|
|
|
1353
1407
|
// 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)
|
|
1361
|
-
const databaseEngine = await getDatabaseEngine();
|
|
1362
|
-
const databaseHost = await getDatabaseHost(databaseEngine);
|
|
1363
|
-
const orm = databaseEngine !== undefined ? await getORM() : undefined;
|
|
1364
|
-
|
|
1408
|
+
var prompt = async (argumentConfiguration) => {
|
|
1409
|
+
const projectName = argumentConfiguration.projectName ?? await getProjectName();
|
|
1410
|
+
const language = argumentConfiguration.language ?? await getLanguage();
|
|
1411
|
+
const codeQualityTool = argumentConfiguration.codeQualityTool ?? await getCodeQualityTool();
|
|
1412
|
+
const useTailwind = argumentConfiguration.useTailwind ?? await getUseTailwind();
|
|
1413
|
+
const frontends = argumentConfiguration.frontends?.filter((frontend) => frontend !== undefined) ?? await getFrontends();
|
|
1414
|
+
const htmlScriptOption = !frontends.includes("html") || argumentConfiguration.htmlScriptOption === "none" ? undefined : argumentConfiguration.htmlScriptOption ?? await getHtmlScriptingOption(language);
|
|
1415
|
+
const databaseEngine = argumentConfiguration.databaseEngine ?? await getDatabaseEngine();
|
|
1416
|
+
const databaseHost = argumentConfiguration.databaseHost ?? await getDatabaseHost(databaseEngine);
|
|
1417
|
+
const orm = databaseEngine !== undefined && databaseEngine !== "none" ? argumentConfiguration.orm ?? await getORM() : undefined;
|
|
1418
|
+
let directoryConfig = argumentConfiguration.directoryConfig ?? await getConfigurationType();
|
|
1365
1419
|
const { buildDirectory, assetsDirectory, tailwind, databaseDirectory } = await getDirectoryConfiguration({
|
|
1366
|
-
|
|
1420
|
+
argumentConfiguration,
|
|
1367
1421
|
databaseEngine,
|
|
1422
|
+
directoryConfig,
|
|
1368
1423
|
useTailwind
|
|
1369
1424
|
});
|
|
1370
|
-
const
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
const
|
|
1374
|
-
const
|
|
1425
|
+
const frontendDirectories = await getFrontendDirectoryConfigurations(directoryConfig, frontends, argumentConfiguration.frontendDirectories);
|
|
1426
|
+
if (argumentConfiguration.frontendDirectories !== undefined)
|
|
1427
|
+
directoryConfig = "custom";
|
|
1428
|
+
const authProvider = argumentConfiguration.authProvider ?? await getAuthProvider();
|
|
1429
|
+
const plugins = argumentConfiguration.plugins?.filter((plugin) => plugin !== undefined) ?? await getPlugins();
|
|
1430
|
+
const initializeGitNow = argumentConfiguration.initializeGitNow ?? await getInitializeGit();
|
|
1431
|
+
const installDependenciesNow = argumentConfiguration.installDependenciesNow ?? await getInstallDependencies();
|
|
1375
1432
|
const values = {
|
|
1376
1433
|
assetsDirectory,
|
|
1377
1434
|
authProvider,
|
|
1378
1435
|
buildDirectory,
|
|
1379
1436
|
codeQualityTool,
|
|
1380
|
-
configType,
|
|
1381
1437
|
databaseDirectory,
|
|
1382
1438
|
databaseEngine,
|
|
1383
1439
|
databaseHost,
|
|
1384
|
-
|
|
1440
|
+
directoryConfig,
|
|
1441
|
+
frontendDirectories,
|
|
1385
1442
|
frontends,
|
|
1386
1443
|
htmlScriptOption,
|
|
1387
1444
|
initializeGitNow,
|
|
@@ -1398,13 +1455,13 @@ var prompt = async () => {
|
|
|
1398
1455
|
|
|
1399
1456
|
// src/scaffold.ts
|
|
1400
1457
|
import { copyFileSync as copyFileSync4 } from "node:fs";
|
|
1401
|
-
import { join as
|
|
1458
|
+
import { join as join10, dirname } from "node:path";
|
|
1402
1459
|
import { fileURLToPath } from "node:url";
|
|
1403
1460
|
|
|
1404
1461
|
// src/commands/formatProject.ts
|
|
1405
1462
|
import { execSync } from "child_process";
|
|
1406
1463
|
import { exit as exit2 } from "process";
|
|
1407
|
-
var
|
|
1464
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
1408
1465
|
|
|
1409
1466
|
// src/utils/commandMaps.ts
|
|
1410
1467
|
var formatCommands = {
|
|
@@ -1430,9 +1487,9 @@ var formatProject = ({
|
|
|
1430
1487
|
const fmt = formatCommands[packageManager] ?? "bun run format";
|
|
1431
1488
|
spin.start("Formatting files…");
|
|
1432
1489
|
execSync(fmt, { cwd: projectName, stdio: "pipe" });
|
|
1433
|
-
spin.stop(
|
|
1490
|
+
spin.stop(import_picocolors12.green("Files formatted"));
|
|
1434
1491
|
} catch (err) {
|
|
1435
|
-
spin.stop(
|
|
1492
|
+
spin.stop(import_picocolors12.red("Failed to format files"), 1);
|
|
1436
1493
|
console.error("Error formatting:", err);
|
|
1437
1494
|
exit2(1);
|
|
1438
1495
|
}
|
|
@@ -1441,7 +1498,7 @@ var formatProject = ({
|
|
|
1441
1498
|
// src/commands/installDependencies.ts
|
|
1442
1499
|
import { execSync as execSync2 } from "child_process";
|
|
1443
1500
|
import { exit as exit3 } from "process";
|
|
1444
|
-
var
|
|
1501
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
1445
1502
|
var installDependencies = async ({
|
|
1446
1503
|
projectName,
|
|
1447
1504
|
packageManager
|
|
@@ -1451,23 +1508,42 @@ var installDependencies = async ({
|
|
|
1451
1508
|
try {
|
|
1452
1509
|
spin.start("Installing dependencies…");
|
|
1453
1510
|
execSync2(cmd, { cwd: projectName, stdio: "pipe" });
|
|
1454
|
-
spin.stop(
|
|
1511
|
+
spin.stop(import_picocolors13.green("Dependencies installed"));
|
|
1455
1512
|
} catch (err) {
|
|
1456
|
-
spin.stop(
|
|
1513
|
+
spin.stop(import_picocolors13.red("Installation failed"), 1);
|
|
1457
1514
|
console.error("Error installing dependencies:", err);
|
|
1458
1515
|
exit3(1);
|
|
1459
1516
|
}
|
|
1460
1517
|
};
|
|
1461
1518
|
|
|
1462
1519
|
// src/generators/configurations/addConfigurationFiles.ts
|
|
1463
|
-
var
|
|
1464
|
-
import { copyFileSync } from "fs";
|
|
1520
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
1521
|
+
import { copyFileSync, writeFileSync } from "fs";
|
|
1465
1522
|
import { join } from "path";
|
|
1523
|
+
|
|
1524
|
+
// src/generators/configurations/generatePrettierrc.ts
|
|
1525
|
+
var generatePrettierrc = (frontends) => {
|
|
1526
|
+
const usesSvelte = frontends.some((frontend) => frontend === "svelte");
|
|
1527
|
+
return `{
|
|
1528
|
+
"endOfLine": "auto",
|
|
1529
|
+
"printWidth": 80,
|
|
1530
|
+
"semi": true,
|
|
1531
|
+
"singleQuote": true,
|
|
1532
|
+
"tabWidth": 4,
|
|
1533
|
+
"trailingComma": "none",
|
|
1534
|
+
"useTabs": true
|
|
1535
|
+
${usesSvelte ? `,"plugins": ["prettier-plugin-svelte"],
|
|
1536
|
+
"overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]` : ""}
|
|
1537
|
+
}`;
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
// src/generators/configurations/addConfigurationFiles.ts
|
|
1466
1541
|
var addConfigurationFiles = ({
|
|
1467
1542
|
tailwind,
|
|
1468
1543
|
templatesDirectory,
|
|
1469
1544
|
language,
|
|
1470
1545
|
codeQualityTool,
|
|
1546
|
+
frontends,
|
|
1471
1547
|
initializeGitNow,
|
|
1472
1548
|
projectName
|
|
1473
1549
|
}) => {
|
|
@@ -1482,16 +1558,17 @@ var addConfigurationFiles = ({
|
|
|
1482
1558
|
if (codeQualityTool === "eslint+prettier") {
|
|
1483
1559
|
copyFileSync(join(templatesDirectory, "configurations", "eslint.config.mjs"), join(projectName, "eslint.config.mjs"));
|
|
1484
1560
|
copyFileSync(join(templatesDirectory, "configurations", ".prettierignore"), join(projectName, ".prettierignore"));
|
|
1485
|
-
|
|
1561
|
+
const prettierrc = generatePrettierrc(frontends);
|
|
1562
|
+
writeFileSync(join(projectName, ".prettierrc.json"), prettierrc);
|
|
1486
1563
|
} else
|
|
1487
|
-
console.warn(`${
|
|
1488
|
-
${
|
|
1564
|
+
console.warn(`${import_picocolors14.dim("│")}
|
|
1565
|
+
${import_picocolors14.yellow("▲")} Biome support not implemented yet`);
|
|
1489
1566
|
};
|
|
1490
1567
|
|
|
1491
|
-
// src/generators/configurations/
|
|
1492
|
-
import { writeFileSync } from "fs";
|
|
1568
|
+
// src/generators/configurations/generatePackageJson.ts
|
|
1569
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
1493
1570
|
import { join as join2 } from "path";
|
|
1494
|
-
var
|
|
1571
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
1495
1572
|
|
|
1496
1573
|
// src/utils/getPackageVersion.ts
|
|
1497
1574
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -1506,14 +1583,14 @@ var getPackageVersion = (packageName) => {
|
|
|
1506
1583
|
}
|
|
1507
1584
|
};
|
|
1508
1585
|
|
|
1509
|
-
// src/generators/configurations/
|
|
1586
|
+
// src/generators/configurations/generatePackageJson.ts
|
|
1510
1587
|
var createPackageJson = ({
|
|
1511
1588
|
projectName,
|
|
1512
1589
|
authProvider,
|
|
1513
1590
|
plugins,
|
|
1514
1591
|
useTailwind,
|
|
1515
1592
|
latest,
|
|
1516
|
-
|
|
1593
|
+
frontendDirectories,
|
|
1517
1594
|
codeQualityTool
|
|
1518
1595
|
}) => {
|
|
1519
1596
|
const s = Y2();
|
|
@@ -1521,6 +1598,8 @@ var createPackageJson = ({
|
|
|
1521
1598
|
const resolveVersion = (name, listed) => latest ? getPackageVersion(name) ?? listed : listed;
|
|
1522
1599
|
const dependencies = {};
|
|
1523
1600
|
const devDependencies = {};
|
|
1601
|
+
const usesReact = frontendDirectories["react"] !== undefined;
|
|
1602
|
+
const usesSvelte = frontendDirectories["svelte"] !== undefined;
|
|
1524
1603
|
for (const p2 of defaultPlugins) {
|
|
1525
1604
|
dependencies[p2.value] = resolveVersion(p2.value, p2.latestVersion);
|
|
1526
1605
|
}
|
|
@@ -1544,16 +1623,20 @@ var createPackageJson = ({
|
|
|
1544
1623
|
devDependencies["tailwindcss"] = resolveVersion("tailwindcss", "4.1.7");
|
|
1545
1624
|
devDependencies["@tailwindcss/cli"] = resolveVersion("@tailwindcss/cli", "4.1.7");
|
|
1546
1625
|
}
|
|
1547
|
-
if (
|
|
1626
|
+
if (usesReact) {
|
|
1548
1627
|
dependencies["react"] = resolveVersion("react", "19.1.0");
|
|
1549
1628
|
dependencies["react-dom"] = resolveVersion("react-dom", "19.1.0");
|
|
1550
1629
|
devDependencies["@types/react"] = resolveVersion("@types/react", "19.1.5");
|
|
1551
1630
|
devDependencies["@types/react-dom"] = resolveVersion("@types/react-dom", "19.1.5");
|
|
1552
1631
|
}
|
|
1553
|
-
|
|
1632
|
+
if (usesSvelte) {
|
|
1633
|
+
dependencies["svelte"] = resolveVersion("svelte", "5.34.7");
|
|
1634
|
+
codeQualityTool === "eslint+prettier" && (devDependencies["prettier-plugin-svelte"] = resolveVersion("prettier-plugin-svelte", "3.4.0"));
|
|
1635
|
+
}
|
|
1636
|
+
latest && s.stop(import_picocolors15.green("Package versions resolved"));
|
|
1554
1637
|
const scripts = {
|
|
1555
1638
|
dev: "bun run src/backend/server.ts",
|
|
1556
|
-
format:
|
|
1639
|
+
format: `prettier --write "./**/*.{js,ts,css,json,mjs,md${usesReact ? ",jsx,tsx" : ""}${usesSvelte ? ",svelte" : ""}}"`,
|
|
1557
1640
|
lint: "eslint ./src",
|
|
1558
1641
|
test: 'echo "Error: no test specified" && exit 1',
|
|
1559
1642
|
typecheck: "bun run tsc --noEmit"
|
|
@@ -1566,7 +1649,7 @@ var createPackageJson = ({
|
|
|
1566
1649
|
type: "module",
|
|
1567
1650
|
version: "0.1.0"
|
|
1568
1651
|
};
|
|
1569
|
-
|
|
1652
|
+
writeFileSync2(join2(projectName, "package.json"), JSON.stringify(packageJson));
|
|
1570
1653
|
};
|
|
1571
1654
|
|
|
1572
1655
|
// src/generators/configurations/initializeRoot.ts
|
|
@@ -1592,12 +1675,12 @@ var initalizeRoot = (projectName, templatesDirectory) => {
|
|
|
1592
1675
|
};
|
|
1593
1676
|
|
|
1594
1677
|
// src/generators/db/scaffoldDatabase.ts
|
|
1595
|
-
var
|
|
1678
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
1596
1679
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
1597
1680
|
import { join as join5 } from "path";
|
|
1598
1681
|
|
|
1599
|
-
// src/generators/configurations/
|
|
1600
|
-
import { writeFileSync as
|
|
1682
|
+
// src/generators/configurations/generateDrizzleConfig.ts
|
|
1683
|
+
import { writeFileSync as writeFileSync3 } from "fs";
|
|
1601
1684
|
import { join as join4 } from "path";
|
|
1602
1685
|
var createDrizzleConfig = ({
|
|
1603
1686
|
projectName,
|
|
@@ -1609,7 +1692,7 @@ var createDrizzleConfig = ({
|
|
|
1609
1692
|
dialect: '${databaseEngine}'
|
|
1610
1693
|
});
|
|
1611
1694
|
`;
|
|
1612
|
-
|
|
1695
|
+
writeFileSync3(join4(projectName, "drizzle.config.ts"), drizzleConfig);
|
|
1613
1696
|
};
|
|
1614
1697
|
|
|
1615
1698
|
// src/generators/db/scaffoldDatabase.ts
|
|
@@ -1620,20 +1703,31 @@ var scaffoldDatabase = ({
|
|
|
1620
1703
|
orm
|
|
1621
1704
|
}) => {
|
|
1622
1705
|
mkdirSync2(join5(projectName, databaseDirectory), { recursive: true });
|
|
1623
|
-
if (databaseEngine !== "postgresql") {
|
|
1624
|
-
console.warn(`${
|
|
1625
|
-
${
|
|
1706
|
+
if (databaseEngine !== "postgresql" && databaseEngine !== "none") {
|
|
1707
|
+
console.warn(`${import_picocolors16.dim("│")}
|
|
1708
|
+
${import_picocolors16.yellow("▲")} Only PostgreSQL support is implemented so far`);
|
|
1626
1709
|
}
|
|
1627
1710
|
if (orm === "drizzle") {
|
|
1628
1711
|
createDrizzleConfig({ databaseEngine, projectName });
|
|
1629
1712
|
}
|
|
1713
|
+
if (orm === "prisma") {
|
|
1714
|
+
console.warn(`${import_picocolors16.dim("│")}
|
|
1715
|
+
${import_picocolors16.yellow("▲")} Prisma support is not implemented yet`);
|
|
1716
|
+
}
|
|
1630
1717
|
};
|
|
1631
1718
|
|
|
1632
|
-
// src/generators/project/
|
|
1633
|
-
import { writeFileSync as
|
|
1719
|
+
// src/generators/project/generateServer.ts
|
|
1720
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1721
|
+
|
|
1722
|
+
// src/constants.ts
|
|
1723
|
+
var UNFOUND_INDEX = -1;
|
|
1724
|
+
var DEFAULT_ARG_LENGTH = 2;
|
|
1725
|
+
var TWO_THIRDS = 2 / 3;
|
|
1726
|
+
|
|
1727
|
+
// src/generators/project/generateServer.ts
|
|
1634
1728
|
var createServerFile = ({
|
|
1635
1729
|
tailwind,
|
|
1636
|
-
|
|
1730
|
+
frontendDirectories,
|
|
1637
1731
|
serverFilePath,
|
|
1638
1732
|
authProvider,
|
|
1639
1733
|
availablePlugins: availablePlugins2,
|
|
@@ -1641,200 +1735,208 @@ var createServerFile = ({
|
|
|
1641
1735
|
assetsDirectory,
|
|
1642
1736
|
plugins
|
|
1643
1737
|
}) => {
|
|
1644
|
-
const
|
|
1645
|
-
const
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
const
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
const
|
|
1738
|
+
const htmlDirectory = frontendDirectories["html"];
|
|
1739
|
+
const reactDirectory = frontendDirectories["react"];
|
|
1740
|
+
const svelteDirectory = frontendDirectories["svelte"];
|
|
1741
|
+
const requiresHtml = htmlDirectory !== undefined;
|
|
1742
|
+
const requiresReact = reactDirectory !== undefined;
|
|
1743
|
+
const requiresSvelte = svelteDirectory !== undefined;
|
|
1744
|
+
const selectedCustomPlugins = availablePlugins2.filter(({ value }) => plugins.indexOf(value) !== UNFOUND_INDEX);
|
|
1745
|
+
const authenticationPlugins = authProvider === "absoluteAuth" ? [absoluteAuthPlugin] : [];
|
|
1746
|
+
const allDependencies = [
|
|
1653
1747
|
...defaultDependencies,
|
|
1654
1748
|
...defaultPlugins,
|
|
1655
1749
|
...selectedCustomPlugins,
|
|
1656
1750
|
...authenticationPlugins
|
|
1657
1751
|
];
|
|
1658
|
-
const uniqueDependencies = [];
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
]
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
if (
|
|
1673
|
-
const
|
|
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";
|
|
1752
|
+
const uniqueDependencies = Array.from(new Map(allDependencies.map((dependency) => [dependency.value, dependency])).values()).sort((a, b3) => a.value.localeCompare(b3.value));
|
|
1753
|
+
const importLines = uniqueDependencies.flatMap(({ value, imports }) => imports && imports.length > 0 ? [
|
|
1754
|
+
`import { ${imports.map(({ packageName }) => packageName).join(", ")} } from '${value}';`
|
|
1755
|
+
] : []);
|
|
1756
|
+
const absoluteImportIdx = importLines.findIndex((line) => line.includes("from '@absolutejs/absolute'"));
|
|
1757
|
+
if (absoluteImportIdx !== UNFOUND_INDEX && importLines[absoluteImportIdx]) {
|
|
1758
|
+
const existingItems = importLines[absoluteImportIdx].replace(/import\s*\{\s*|\}\s*from.*$/g, "").split(",").map((item) => item.trim()).filter((value) => value.length > 0);
|
|
1759
|
+
const additionalItems = [
|
|
1760
|
+
requiresHtml && !existingItems.includes("handleHTMLPageRequest") && "handleHTMLPageRequest",
|
|
1761
|
+
requiresReact && !existingItems.includes("handleReactPageRequest") && "handleReactPageRequest",
|
|
1762
|
+
requiresSvelte && !existingItems.includes("handleSveltePageRequest") && "handleSveltePageRequest"
|
|
1763
|
+
].filter((value) => typeof value === "string");
|
|
1764
|
+
importLines[absoluteImportIdx] = `import { ${[...existingItems, ...additionalItems].join(", ")} } from '@absolutejs/absolute';`;
|
|
1765
|
+
}
|
|
1766
|
+
if (reactDirectory !== undefined) {
|
|
1767
|
+
const reactImportSource = reactDirectory === "" ? "../frontend/pages/ReactExample" : `../frontend/${reactDirectory}/pages/ReactExample`;
|
|
1687
1768
|
importLines.push(`import { ReactExample } from '${reactImportSource}';`);
|
|
1688
1769
|
}
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1770
|
+
if (requiresSvelte) {
|
|
1771
|
+
const svelteImportSource = svelteDirectory === "" ? "../frontend/pages/SvelteExample" : `../frontend/${svelteDirectory}/pages/SvelteExample`;
|
|
1772
|
+
importLines.push(`import SvelteExample from '${svelteImportSource}.svelte';`);
|
|
1773
|
+
}
|
|
1774
|
+
const useStatements = uniqueDependencies.flatMap(({ imports }) => imports ?? []).filter((entry) => entry.isPlugin).map((entry) => {
|
|
1775
|
+
if (entry.config === undefined)
|
|
1776
|
+
return `.use(${entry.packageName})`;
|
|
1777
|
+
if (entry.config === null)
|
|
1778
|
+
return `.use(${entry.packageName}())`;
|
|
1779
|
+
return `.use(${entry.packageName}(${JSON.stringify(entry.config)}))`;
|
|
1697
1780
|
});
|
|
1698
1781
|
const manifestOptions = [
|
|
1699
|
-
`buildDirectory: '${buildDirectory}'`,
|
|
1700
1782
|
`assetsDirectory: '${assetsDirectory}'`,
|
|
1701
|
-
|
|
1783
|
+
`buildDirectory: '${buildDirectory}'`,
|
|
1784
|
+
...Object.entries(frontendDirectories).map(([frameworkName, directory]) => `${frameworkName}Directory: './src/frontend/${directory}'`),
|
|
1702
1785
|
tailwind ? `tailwind: ${JSON.stringify(tailwind)}` : ""
|
|
1703
|
-
];
|
|
1704
|
-
const
|
|
1786
|
+
].filter(Boolean);
|
|
1787
|
+
const manifestDeclaration = `const manifest = await build({
|
|
1705
1788
|
${manifestOptions.join(`,
|
|
1706
1789
|
`)}
|
|
1707
1790
|
});`;
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
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
|
-
)`;
|
|
1791
|
+
const guardStatements = [
|
|
1792
|
+
`if (manifest === null) throw new Error('Manifest was not generated');`,
|
|
1793
|
+
requiresReact ? `const { ReactExampleIndex } = manifest;
|
|
1794
|
+
if (ReactExampleIndex === undefined) throw new Error('ReactExampleIndex was not generated');` : ""
|
|
1795
|
+
].filter(Boolean).join(`
|
|
1796
|
+
`);
|
|
1797
|
+
const routes = Object.entries(frontendDirectories).map(([frameworkName, directory], index) => {
|
|
1798
|
+
const routePath = index === 0 ? "/" : `/${frameworkName}`;
|
|
1799
|
+
if (frameworkName === "html") {
|
|
1800
|
+
return `.get('${routePath}', () => handleHTMLPageRequest(\`${buildDirectory}/${directory}/pages/HTMLExample.html\`))`;
|
|
1727
1801
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1802
|
+
if (frameworkName === "react") {
|
|
1803
|
+
return `.get('${routePath}', () => handleReactPageRequest(ReactExample, ReactExampleIndex))`;
|
|
1804
|
+
}
|
|
1805
|
+
if (frameworkName === "svelte") {
|
|
1806
|
+
return `.get('${routePath}', () => handleSveltePageRequest(SvelteExample, manifest))`;
|
|
1807
|
+
}
|
|
1808
|
+
return "";
|
|
1809
|
+
}).filter(Boolean).join(`
|
|
1810
|
+
`);
|
|
1811
|
+
const serverFileContent = `${importLines.join(`
|
|
1730
1812
|
`)}
|
|
1731
1813
|
|
|
1732
|
-
${
|
|
1814
|
+
${manifestDeclaration}
|
|
1733
1815
|
|
|
1734
1816
|
${guardStatements}
|
|
1735
1817
|
|
|
1736
|
-
new Elysia()${
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
.on('error', (error) => {
|
|
1743
|
-
const { request } = error;
|
|
1744
|
-
console.error(\`Server error on \${request.method} \${request.url}: \${error.message}\`);
|
|
1818
|
+
new Elysia()${routes}
|
|
1819
|
+
${useStatements.map((s) => ` ${s}`).join(`
|
|
1820
|
+
`)}
|
|
1821
|
+
.on('error', (err) => {
|
|
1822
|
+
const { request } = err;
|
|
1823
|
+
console.error(\`Server error on \${request.method} \${request.url}: \${err.message}\`);
|
|
1745
1824
|
});
|
|
1746
1825
|
`;
|
|
1747
|
-
|
|
1826
|
+
writeFileSync4(serverFilePath, serverFileContent);
|
|
1748
1827
|
};
|
|
1749
1828
|
|
|
1750
1829
|
// src/generators/project/scaffoldFrontends.ts
|
|
1751
|
-
import { copyFileSync as copyFileSync3, mkdirSync as
|
|
1752
|
-
import { join as
|
|
1830
|
+
import { copyFileSync as copyFileSync3, mkdirSync as mkdirSync6 } from "node:fs";
|
|
1831
|
+
import { join as join9 } from "node:path";
|
|
1753
1832
|
|
|
1754
1833
|
// src/generators/html/scaffoldHTML.ts
|
|
1755
|
-
import {
|
|
1834
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
1756
1835
|
import { join as join6 } from "path";
|
|
1757
1836
|
|
|
1758
|
-
// src/generators/html/
|
|
1759
|
-
var
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1837
|
+
// src/generators/html/generateHTMLPage.ts
|
|
1838
|
+
var generateHTMLPage = (htmlScriptOption) => {
|
|
1839
|
+
let scriptTag = "";
|
|
1840
|
+
if (htmlScriptOption === "js") {
|
|
1841
|
+
scriptTag = `<script src="/html/scripts/javascriptExample.js"></script>`;
|
|
1842
|
+
} else if (htmlScriptOption === "ts") {
|
|
1843
|
+
scriptTag = `<script src="/html/scripts/typescriptExample.ts"></script>`;
|
|
1844
|
+
}
|
|
1845
|
+
return `<!DOCTYPE html>
|
|
1846
|
+
<html>
|
|
1847
|
+
<head>
|
|
1848
|
+
<title>Html Home</title>
|
|
1849
|
+
<link rel="stylesheet" type="text/css" href="/assets/css/HtmlHome.css">
|
|
1850
|
+
<link rel="icon" href="/assets/ico/favicon.ico" />
|
|
1851
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1852
|
+
</head>
|
|
1853
|
+
<body>
|
|
1854
|
+
<header>
|
|
1855
|
+
<img id="logo" src="/assets/svg/brand_logo.svg" alt="AbsoluteJS Logo">
|
|
1856
|
+
<h1 id="greeting"></h1>
|
|
1857
|
+
</header>
|
|
1858
|
+
<main>
|
|
1859
|
+
<p>Welcome to AbsoluteJS, the next generation JavaScript framework. We're glad you're here.</p>
|
|
1860
|
+
<button id="counter-button">Click me!</button>
|
|
1861
|
+
<p id="counter">0</p>
|
|
1862
|
+
<nav id="links">
|
|
1863
|
+
<a href="/react" id="react-link">React</a>
|
|
1864
|
+
<a href="/vue" id="vue-link">Vue</a>
|
|
1865
|
+
<a href="/angular" id="angular-link">Angular</a>
|
|
1866
|
+
<a href="/svelte" id="svelte-link">Svelte</a>
|
|
1867
|
+
<a href="/ember" id="ember-link">Ember</a>
|
|
1868
|
+
<a href="/htmx" id="htmx-link">HTMX</a>
|
|
1869
|
+
</nav>
|
|
1870
|
+
</main>
|
|
1871
|
+
<footer>
|
|
1872
|
+
<p id="footer-text"></p>
|
|
1873
|
+
</footer>${scriptTag ? `
|
|
1874
|
+
${scriptTag}` : ""}
|
|
1875
|
+
</body>
|
|
1876
|
+
</html>`;
|
|
1877
|
+
};
|
|
1785
1878
|
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
counter.textContent = count.toString();
|
|
1789
|
-
});
|
|
1879
|
+
// src/generators/html/generateHTMLScript.ts
|
|
1880
|
+
var getHTMLScript = (htmlScriptOption, isSingleFrontend) => `import { HOURS_IN_DAY, TWO_THIRDS } from '${!isSingleFrontend ? "../" : ""}../../constants';
|
|
1790
1881
|
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
});
|
|
1796
|
-
link.addEventListener('mouseout', () => {
|
|
1797
|
-
link.style.transform = 'scale(1)';
|
|
1798
|
-
});
|
|
1799
|
-
});
|
|
1882
|
+
const greeting = document.getElementById('greeting');
|
|
1883
|
+
const date = new Date();
|
|
1884
|
+
const hours = date.getHours();
|
|
1885
|
+
if (!greeting) throw new Error('Greeting element not found');
|
|
1800
1886
|
|
|
1801
|
-
|
|
1887
|
+
if (hours < HOURS_IN_DAY / 2) {
|
|
1888
|
+
greeting.textContent = 'Good Morning, welcome to AbsoluteJS !';
|
|
1889
|
+
} else if (hours < HOURS_IN_DAY * TWO_THIRDS) {
|
|
1890
|
+
greeting.textContent = 'Good Afternoon, welcome to AbsoluteJS !';
|
|
1891
|
+
} else {
|
|
1892
|
+
greeting.textContent = 'Good Evening, welcome to AbsoluteJS !';
|
|
1893
|
+
}
|
|
1802
1894
|
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1895
|
+
const button = document.getElementById('counter-button');
|
|
1896
|
+
const counter = document.getElementById('counter');
|
|
1897
|
+
if (!button || !counter) throw new Error('Button or counter element not found');
|
|
1898
|
+
let count = 0;
|
|
1899
|
+
button.addEventListener('click', () => {
|
|
1900
|
+
count++;
|
|
1901
|
+
counter.textContent = count.toString();
|
|
1902
|
+
});
|
|
1806
1903
|
|
|
1807
|
-
|
|
1904
|
+
const links = document.querySelectorAll${htmlScriptOption === "ts" ? "<HTMLAnchorElement>" : ""}('#links a');
|
|
1905
|
+
links.forEach((link) => {
|
|
1906
|
+
link.addEventListener('mouseover', () => link.style.transform = 'scale(1.2)');
|
|
1907
|
+
link.addEventListener('mouseout', () => link.style.transform = 'scale(1)');
|
|
1808
1908
|
});
|
|
1909
|
+
|
|
1910
|
+
const footerText = document.getElementById('footer-text');
|
|
1911
|
+
if (!footerText) throw new Error('Footer text element not found');
|
|
1912
|
+
footerText.textContent = \`© ${new Date().getFullYear()} AbsoluteJS\`;
|
|
1809
1913
|
`;
|
|
1810
1914
|
|
|
1811
1915
|
// src/generators/html/scaffoldHTML.ts
|
|
1812
1916
|
var scaffoldHTML = ({
|
|
1813
|
-
|
|
1814
|
-
isSingle,
|
|
1917
|
+
isSingleFrontend,
|
|
1815
1918
|
targetDirectory,
|
|
1816
|
-
htmlScriptOption
|
|
1817
|
-
language
|
|
1919
|
+
htmlScriptOption
|
|
1818
1920
|
}) => {
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1921
|
+
const htmlPage = generateHTMLPage(htmlScriptOption);
|
|
1922
|
+
const htmlPagesDirectory = join6(targetDirectory, "pages");
|
|
1923
|
+
mkdirSync3(htmlPagesDirectory, { recursive: true });
|
|
1924
|
+
writeFileSync5(join6(htmlPagesDirectory, "HTMLExample.html"), htmlPage);
|
|
1925
|
+
if (htmlScriptOption !== undefined && htmlScriptOption !== "none") {
|
|
1926
|
+
const scriptsDir = join6(targetDirectory, "scripts");
|
|
1927
|
+
mkdirSync3(scriptsDir, { recursive: true });
|
|
1928
|
+
const script = getHTMLScript(htmlScriptOption, isSingleFrontend);
|
|
1929
|
+
const scriptFileName = htmlScriptOption === "ts" ? "typescriptExample.ts" : "javascriptExample.js";
|
|
1930
|
+
writeFileSync5(join6(scriptsDir, scriptFileName), script);
|
|
1829
1931
|
}
|
|
1830
1932
|
};
|
|
1831
1933
|
|
|
1832
1934
|
// src/generators/react/scaffoldReact.ts
|
|
1833
|
-
import { cpSync as
|
|
1935
|
+
import { cpSync as cpSync2, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
1834
1936
|
import { join as join7 } from "node:path";
|
|
1835
1937
|
|
|
1836
1938
|
// src/generators/react/generateHeadComponent.ts
|
|
1837
|
-
var generateHeadComponent = (
|
|
1939
|
+
var generateHeadComponent = (isSingleFrontend) => `import { styleReset } from '${isSingleFrontend ? "../../styles" : "../../../styles/react"}/defaultStyles';
|
|
1838
1940
|
|
|
1839
1941
|
type HeadProps = {
|
|
1840
1942
|
title?: string;
|
|
@@ -1869,13 +1971,13 @@ export const Head = ({
|
|
|
1869
1971
|
`;
|
|
1870
1972
|
|
|
1871
1973
|
// src/generators/react/generateReactPage.ts
|
|
1872
|
-
var generateReactPage = (
|
|
1974
|
+
var generateReactPage = (isSingleFrontend) => `import { useState } from 'react';
|
|
1873
1975
|
import { Head } from '../components/utils/Head';
|
|
1874
1976
|
import {
|
|
1875
1977
|
bodyDefault,
|
|
1876
1978
|
htmlDefault,
|
|
1877
1979
|
mainDefault
|
|
1878
|
-
} from '${
|
|
1980
|
+
} from '${isSingleFrontend ? "../styles" : "../../styles/react"}/defaultStyles';
|
|
1879
1981
|
|
|
1880
1982
|
export const ReactExample = () => {
|
|
1881
1983
|
const [count, setCount] = useState(0);
|
|
@@ -1956,7 +2058,7 @@ export const ReactExample = () => {
|
|
|
1956
2058
|
fontFamily: 'monospace'
|
|
1957
2059
|
}}
|
|
1958
2060
|
>
|
|
1959
|
-
src/frontend/${
|
|
2061
|
+
src/frontend/${isSingleFrontend ? "" : "react"}/pages/ReactExample.tsx
|
|
1960
2062
|
</code>{' '}
|
|
1961
2063
|
to edit this page
|
|
1962
2064
|
</p>
|
|
@@ -1972,77 +2074,136 @@ export const ReactExample = () => {
|
|
|
1972
2074
|
var scaffoldReact = ({
|
|
1973
2075
|
stylesDirectory,
|
|
1974
2076
|
templatesDirectory,
|
|
1975
|
-
|
|
2077
|
+
isSingleFrontend,
|
|
1976
2078
|
targetDirectory
|
|
1977
2079
|
}) => {
|
|
1978
2080
|
const reactStylesSrc = join7(templatesDirectory, "react", "styles");
|
|
1979
2081
|
const reactTemplates = join7(templatesDirectory, "react");
|
|
1980
2082
|
const pagesDirectory = join7(targetDirectory, "pages");
|
|
1981
2083
|
const componentsDirectory = join7(targetDirectory, "components");
|
|
1982
|
-
const pageExample = generateReactPage(
|
|
1983
|
-
const headComponent = generateHeadComponent(
|
|
1984
|
-
mkdirSync4(pagesDirectory);
|
|
1985
|
-
|
|
2084
|
+
const pageExample = generateReactPage(isSingleFrontend);
|
|
2085
|
+
const headComponent = generateHeadComponent(isSingleFrontend);
|
|
2086
|
+
mkdirSync4(pagesDirectory, { recursive: true });
|
|
2087
|
+
writeFileSync6(join7(pagesDirectory, "ReactExample.tsx"), pageExample);
|
|
1986
2088
|
mkdirSync4(join7(componentsDirectory, "utils"), { recursive: true });
|
|
1987
|
-
|
|
1988
|
-
|
|
2089
|
+
writeFileSync6(join7(componentsDirectory, "utils", "Head.tsx"), headComponent);
|
|
2090
|
+
cpSync2(join7(reactTemplates, "hooks"), join7(targetDirectory, "hooks"), {
|
|
1989
2091
|
recursive: true
|
|
1990
2092
|
});
|
|
1991
|
-
if (
|
|
1992
|
-
|
|
2093
|
+
if (isSingleFrontend) {
|
|
2094
|
+
cpSync2(reactStylesSrc, stylesDirectory, {
|
|
1993
2095
|
recursive: true
|
|
1994
2096
|
});
|
|
1995
2097
|
} else {
|
|
1996
2098
|
const dest = join7(stylesDirectory, "react");
|
|
1997
|
-
mkdirSync4(dest);
|
|
1998
|
-
|
|
2099
|
+
mkdirSync4(dest, { recursive: true });
|
|
2100
|
+
cpSync2(reactStylesSrc, dest, {
|
|
1999
2101
|
recursive: true
|
|
2000
2102
|
});
|
|
2001
2103
|
}
|
|
2002
2104
|
};
|
|
2003
2105
|
|
|
2106
|
+
// src/generators/svelte/scaffoldSvelte.ts
|
|
2107
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
2108
|
+
import { join as join8 } from "node:path";
|
|
2109
|
+
|
|
2110
|
+
// src/generators/svelte/generateSveltePage.ts
|
|
2111
|
+
var generateSveltePage = (language) => {
|
|
2112
|
+
const scriptTag = language === "ts" ? `<script lang="ts">` : `<script>`;
|
|
2113
|
+
return `${scriptTag}
|
|
2114
|
+
let count = $state(0);
|
|
2115
|
+
|
|
2116
|
+
const year = new Date().getFullYear();
|
|
2117
|
+
</script>
|
|
2118
|
+
|
|
2119
|
+
<svelte:head>
|
|
2120
|
+
<meta charset="utf-8" />
|
|
2121
|
+
<title>Svelte Home</title>
|
|
2122
|
+
<meta name="description" content="Welcome to AbsoluteJS" />
|
|
2123
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2124
|
+
<link rel="icon" href="/assets/ico/favicon.ico" />
|
|
2125
|
+
</svelte:head>
|
|
2126
|
+
|
|
2127
|
+
<main>
|
|
2128
|
+
<header><h1>This page was built with Svelte</h1></header>
|
|
2129
|
+
|
|
2130
|
+
<p>Welcome to the Svelte home page. This page was built using Svelte.</p>
|
|
2131
|
+
|
|
2132
|
+
<p>Counter: {count}</p>
|
|
2133
|
+
<button onclick={() => (count += 1)}>Increment</button>
|
|
2134
|
+
|
|
2135
|
+
<div id="links">
|
|
2136
|
+
<a href="/">Html</a>
|
|
2137
|
+
<a href="/vue">Vue</a>
|
|
2138
|
+
</div>
|
|
2139
|
+
|
|
2140
|
+
<footer><p>© {year} AbsoluteJS</p></footer>
|
|
2141
|
+
</main>
|
|
2142
|
+
`;
|
|
2143
|
+
};
|
|
2144
|
+
|
|
2145
|
+
// src/generators/svelte/scaffoldSvelte.ts
|
|
2146
|
+
var scaffoldSvelte = ({
|
|
2147
|
+
targetDirectory,
|
|
2148
|
+
language
|
|
2149
|
+
}) => {
|
|
2150
|
+
const pageExample = generateSveltePage(language);
|
|
2151
|
+
const pagesDirectory = join8(targetDirectory, "pages");
|
|
2152
|
+
const componentsDirectory = join8(targetDirectory, "components");
|
|
2153
|
+
mkdirSync5(pagesDirectory, { recursive: true });
|
|
2154
|
+
writeFileSync7(join8(pagesDirectory, "SvelteExample.svelte"), pageExample);
|
|
2155
|
+
mkdirSync5(join8(componentsDirectory), { recursive: true });
|
|
2156
|
+
};
|
|
2157
|
+
|
|
2004
2158
|
// src/generators/project/scaffoldFrontends.ts
|
|
2005
2159
|
var scaffoldFrontends = ({
|
|
2006
2160
|
frontendDirectory,
|
|
2007
|
-
language,
|
|
2008
2161
|
templatesDirectory,
|
|
2009
|
-
|
|
2162
|
+
frontendDirectories,
|
|
2163
|
+
language,
|
|
2010
2164
|
tailwind,
|
|
2011
2165
|
htmlScriptOption
|
|
2012
2166
|
}) => {
|
|
2013
|
-
const
|
|
2014
|
-
const
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2167
|
+
const frontendEntries = Object.entries(frontendDirectories);
|
|
2168
|
+
const isSingleFrontend = frontendEntries.length === 1;
|
|
2169
|
+
const stylesDirectory = join9(frontendDirectory, "styles");
|
|
2170
|
+
const needsStylesDir = !(isSingleFrontend && frontendEntries[0]?.[0] === "svelte");
|
|
2171
|
+
if (needsStylesDir)
|
|
2172
|
+
mkdirSync6(stylesDirectory);
|
|
2173
|
+
if (needsStylesDir && tailwind !== undefined) {
|
|
2174
|
+
copyFileSync3(join9(templatesDirectory, "tailwind", "tailwind.css"), join9(stylesDirectory, "tailwind.css"));
|
|
2175
|
+
}
|
|
2176
|
+
const directoryMap = new Map;
|
|
2177
|
+
for (const [frontendName, rawDirectory] of frontendEntries) {
|
|
2178
|
+
const directory = rawDirectory?.trim() ?? (isSingleFrontend ? "" : frontendName);
|
|
2179
|
+
if (directoryMap.has(directory)) {
|
|
2180
|
+
throw new Error(`Frontend directory collision: "${directory}" is assigned to both "${directoryMap.get(directory)}" and "${frontendName}". Please pick unique directories.`);
|
|
2024
2181
|
}
|
|
2025
|
-
|
|
2026
|
-
const targetDirectory =
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2182
|
+
directoryMap.set(directory, frontendName);
|
|
2183
|
+
const targetDirectory = join9(frontendDirectory, directory);
|
|
2184
|
+
if (!isSingleFrontend)
|
|
2185
|
+
mkdirSync6(targetDirectory);
|
|
2186
|
+
switch (frontendName) {
|
|
2187
|
+
case "react":
|
|
2188
|
+
scaffoldReact({
|
|
2189
|
+
isSingleFrontend,
|
|
2190
|
+
stylesDirectory,
|
|
2191
|
+
targetDirectory,
|
|
2192
|
+
templatesDirectory
|
|
2193
|
+
});
|
|
2194
|
+
break;
|
|
2195
|
+
case "svelte":
|
|
2196
|
+
scaffoldSvelte({ language, targetDirectory });
|
|
2197
|
+
break;
|
|
2198
|
+
case "html":
|
|
2199
|
+
scaffoldHTML({
|
|
2200
|
+
htmlScriptOption,
|
|
2201
|
+
isSingleFrontend,
|
|
2202
|
+
targetDirectory
|
|
2203
|
+
});
|
|
2204
|
+
break;
|
|
2044
2205
|
}
|
|
2045
|
-
}
|
|
2206
|
+
}
|
|
2046
2207
|
};
|
|
2047
2208
|
|
|
2048
2209
|
// src/scaffold.ts
|
|
@@ -2053,28 +2214,29 @@ var scaffold = ({
|
|
|
2053
2214
|
codeQualityTool,
|
|
2054
2215
|
initializeGitNow,
|
|
2055
2216
|
databaseEngine,
|
|
2056
|
-
databaseHost,
|
|
2057
2217
|
htmlScriptOption,
|
|
2058
2218
|
useTailwind,
|
|
2059
2219
|
databaseDirectory,
|
|
2060
2220
|
orm,
|
|
2221
|
+
frontends,
|
|
2061
2222
|
plugins,
|
|
2062
2223
|
authProvider,
|
|
2063
2224
|
buildDirectory,
|
|
2064
2225
|
assetsDirectory,
|
|
2065
2226
|
tailwind,
|
|
2066
2227
|
installDependenciesNow,
|
|
2067
|
-
|
|
2228
|
+
frontendDirectories
|
|
2068
2229
|
},
|
|
2069
2230
|
latest,
|
|
2070
2231
|
packageManager
|
|
2071
2232
|
}) => {
|
|
2072
2233
|
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
2073
|
-
const templatesDirectory =
|
|
2234
|
+
const templatesDirectory = join10(__dirname2, "/templates");
|
|
2074
2235
|
const { frontendDirectory, backendDirectory } = initalizeRoot(projectName, templatesDirectory);
|
|
2075
|
-
copyFileSync4(
|
|
2236
|
+
copyFileSync4(join10(templatesDirectory, "README.md"), join10(projectName, "README.md"));
|
|
2076
2237
|
addConfigurationFiles({
|
|
2077
2238
|
codeQualityTool,
|
|
2239
|
+
frontends,
|
|
2078
2240
|
initializeGitNow,
|
|
2079
2241
|
language,
|
|
2080
2242
|
projectName,
|
|
@@ -2084,19 +2246,19 @@ var scaffold = ({
|
|
|
2084
2246
|
createPackageJson({
|
|
2085
2247
|
authProvider,
|
|
2086
2248
|
codeQualityTool,
|
|
2087
|
-
|
|
2249
|
+
frontendDirectories,
|
|
2088
2250
|
latest,
|
|
2089
2251
|
plugins,
|
|
2090
2252
|
projectName,
|
|
2091
2253
|
useTailwind
|
|
2092
2254
|
});
|
|
2093
|
-
const serverFilePath =
|
|
2255
|
+
const serverFilePath = join10(backendDirectory, "server.ts");
|
|
2094
2256
|
createServerFile({
|
|
2095
2257
|
assetsDirectory,
|
|
2096
2258
|
authProvider,
|
|
2097
2259
|
availablePlugins,
|
|
2098
2260
|
buildDirectory,
|
|
2099
|
-
|
|
2261
|
+
frontendDirectories,
|
|
2100
2262
|
plugins,
|
|
2101
2263
|
serverFilePath,
|
|
2102
2264
|
tailwind
|
|
@@ -2108,7 +2270,7 @@ var scaffold = ({
|
|
|
2108
2270
|
projectName
|
|
2109
2271
|
});
|
|
2110
2272
|
scaffoldFrontends({
|
|
2111
|
-
|
|
2273
|
+
frontendDirectories,
|
|
2112
2274
|
frontendDirectory,
|
|
2113
2275
|
htmlScriptOption,
|
|
2114
2276
|
language,
|
|
@@ -2124,6 +2286,174 @@ var scaffold = ({
|
|
|
2124
2286
|
});
|
|
2125
2287
|
};
|
|
2126
2288
|
|
|
2289
|
+
// src/utils/parseCommandLineOptions.ts
|
|
2290
|
+
import { argv, exit as exit4 } from "node:process";
|
|
2291
|
+
import { parseArgs } from "node:util";
|
|
2292
|
+
var parseCommandLineOptions = () => {
|
|
2293
|
+
const { values, positionals } = parseArgs({
|
|
2294
|
+
allowNegative: true,
|
|
2295
|
+
allowPositionals: true,
|
|
2296
|
+
args: argv.slice(DEFAULT_ARG_LENGTH),
|
|
2297
|
+
options: {
|
|
2298
|
+
angular: { type: "string" },
|
|
2299
|
+
assets: { type: "string" },
|
|
2300
|
+
auth: { type: "string" },
|
|
2301
|
+
build: { type: "string" },
|
|
2302
|
+
database: { type: "string" },
|
|
2303
|
+
debug: { default: false, short: "d", type: "boolean" },
|
|
2304
|
+
directory: { type: "string" },
|
|
2305
|
+
engine: { type: "string" },
|
|
2306
|
+
frontend: { multiple: true, type: "string" },
|
|
2307
|
+
git: { type: "boolean" },
|
|
2308
|
+
help: { default: false, short: "h", type: "boolean" },
|
|
2309
|
+
host: { type: "string" },
|
|
2310
|
+
html: { type: "string" },
|
|
2311
|
+
htmx: { type: "string" },
|
|
2312
|
+
lang: { type: "string" },
|
|
2313
|
+
lts: { default: false, type: "boolean" },
|
|
2314
|
+
npm: { type: "boolean" },
|
|
2315
|
+
orm: { type: "string" },
|
|
2316
|
+
plugin: { multiple: true, type: "string" },
|
|
2317
|
+
quality: { type: "string" },
|
|
2318
|
+
react: { type: "string" },
|
|
2319
|
+
script: { type: "string" },
|
|
2320
|
+
skip: { type: "boolean" },
|
|
2321
|
+
svelte: { type: "string" },
|
|
2322
|
+
tailwind: { type: "boolean" },
|
|
2323
|
+
"tailwind-input": { type: "string" },
|
|
2324
|
+
"tailwind-output": { type: "string" },
|
|
2325
|
+
vue: { type: "string" }
|
|
2326
|
+
}
|
|
2327
|
+
});
|
|
2328
|
+
const errors = [];
|
|
2329
|
+
let authProvider;
|
|
2330
|
+
if (values.auth !== undefined && !isAuthProvider(values.auth)) {
|
|
2331
|
+
errors.push(`Invalid auth provider: "${values.auth}". Expected: [ ${availableAuthProviders.join(", ")} ]`);
|
|
2332
|
+
} else if (values.auth !== undefined) {
|
|
2333
|
+
authProvider = values.auth;
|
|
2334
|
+
} else if (values.skip) {
|
|
2335
|
+
authProvider = "none";
|
|
2336
|
+
}
|
|
2337
|
+
let databaseEngine;
|
|
2338
|
+
if (values.engine !== undefined && !isDatabaseEngine(values.engine)) {
|
|
2339
|
+
errors.push(`Invalid database engine: "${values.engine}". Expected: [ ${availableDatabaseEngines.join(", ")} ]`);
|
|
2340
|
+
} else if (values.engine !== undefined) {
|
|
2341
|
+
databaseEngine = values.engine;
|
|
2342
|
+
} else if (values.skip) {
|
|
2343
|
+
databaseEngine = "none";
|
|
2344
|
+
}
|
|
2345
|
+
let databaseHost;
|
|
2346
|
+
if (values.host !== undefined && !isDatabaseHost(values.host)) {
|
|
2347
|
+
errors.push(`Invalid database host: "${values.host}". Expected: [ ${availableDatabaseHosts.join(", ")} ]`);
|
|
2348
|
+
} else if (values.host !== undefined) {
|
|
2349
|
+
databaseHost = values.host;
|
|
2350
|
+
} else if (values.skip) {
|
|
2351
|
+
databaseHost = "none";
|
|
2352
|
+
}
|
|
2353
|
+
const { orm: ormValue } = values;
|
|
2354
|
+
let orm;
|
|
2355
|
+
if (ormValue !== undefined && !isORM(ormValue)) {
|
|
2356
|
+
errors.push(`Invalid ORM: "${values.orm}". Expected: [ ${availableORMs.join(", ")} ]`);
|
|
2357
|
+
} else if (ormValue !== undefined) {
|
|
2358
|
+
orm = ormValue;
|
|
2359
|
+
} else if (values.skip) {
|
|
2360
|
+
orm = "none";
|
|
2361
|
+
}
|
|
2362
|
+
const codeQualityTool = isCodeQualityTool(values.quality) ? values.quality : undefined;
|
|
2363
|
+
if (values.quality !== undefined && codeQualityTool === undefined) {
|
|
2364
|
+
errors.push(`Invalid code quality tool: "${values.quality}". Expected: [ ${availableCodeQualityTools.join(", ")} ]`);
|
|
2365
|
+
}
|
|
2366
|
+
let htmlScriptOption;
|
|
2367
|
+
if (values.script !== undefined && !isHTMLScriptOption(values.script)) {
|
|
2368
|
+
errors.push(`Invalid HTML script option: "${values.script}". Expected: [ ${availableHTMLScriptOptions.join(", ")} ]`);
|
|
2369
|
+
} else if (values.script !== undefined) {
|
|
2370
|
+
htmlScriptOption = values.script;
|
|
2371
|
+
} else if (values.skip) {
|
|
2372
|
+
htmlScriptOption = "none";
|
|
2373
|
+
}
|
|
2374
|
+
const language = values.lang !== undefined && isLanguage(values.lang) ? values.lang : undefined;
|
|
2375
|
+
if (values.lang !== undefined && language === undefined) {
|
|
2376
|
+
errors.push(`Invalid language: "${values.lang}". Expected: [ ${availableLanguages.join(", ")} ]`);
|
|
2377
|
+
}
|
|
2378
|
+
const directoryConfig = values.directory !== undefined && isDirectoryConfig(values.directory) ? values.directory : undefined;
|
|
2379
|
+
if (values.directory !== undefined && directoryConfig === undefined) {
|
|
2380
|
+
errors.push(`Invalid directory configuration: "${values.directory}". Expected: [ ${availableDirectoryConfigurations.join(", ")} ]`);
|
|
2381
|
+
}
|
|
2382
|
+
for (const f of values.frontend || []) {
|
|
2383
|
+
if (isFrontend(f))
|
|
2384
|
+
continue;
|
|
2385
|
+
errors.push(`Invalid frontend: "${f}". Expected: [ ${availableFrontends.join(", ")} ]`);
|
|
2386
|
+
}
|
|
2387
|
+
if (errors.length > 0) {
|
|
2388
|
+
console.error(errors.join(`
|
|
2389
|
+
`));
|
|
2390
|
+
exit4(1);
|
|
2391
|
+
}
|
|
2392
|
+
if (databaseEngine === "none" && databaseHost !== "none") {
|
|
2393
|
+
console.warn("Warning: Setting the database host without a database engine has no effect.");
|
|
2394
|
+
}
|
|
2395
|
+
if (databaseEngine === "none" && orm !== "none") {
|
|
2396
|
+
console.warn("Warning: Setting an ORM without a database engine has no effect.");
|
|
2397
|
+
}
|
|
2398
|
+
let databaseDirectory = values.database;
|
|
2399
|
+
if (databaseEngine === "none" && databaseDirectory !== undefined) {
|
|
2400
|
+
console.warn("Warning: Setting a database directory without a database engine has no effect.");
|
|
2401
|
+
databaseDirectory = undefined;
|
|
2402
|
+
}
|
|
2403
|
+
const frontendsWithDirectory = availableFrontends.filter((f) => values[f] !== undefined);
|
|
2404
|
+
const frontendDirectories = {};
|
|
2405
|
+
for (const frontend of frontendsWithDirectory) {
|
|
2406
|
+
frontendDirectories[frontend] = values[frontend];
|
|
2407
|
+
}
|
|
2408
|
+
const originalFrontends = values.frontend;
|
|
2409
|
+
const collector = new Set(originalFrontends ?? []);
|
|
2410
|
+
for (const frontend of frontendsWithDirectory) {
|
|
2411
|
+
collector.add(frontend);
|
|
2412
|
+
}
|
|
2413
|
+
values.frontend = collector.size > 0 ? Array.from(collector) : undefined;
|
|
2414
|
+
if (values.plugin === undefined && values.skip) {
|
|
2415
|
+
values.plugin = ["none"];
|
|
2416
|
+
}
|
|
2417
|
+
const plugins = values.plugin && values.plugin[0] === "none" ? [] : values.plugin;
|
|
2418
|
+
const hasTailwindFiles = values["tailwind-input"] !== undefined || values["tailwind-output"] !== undefined;
|
|
2419
|
+
let tailwind = hasTailwindFiles ? {
|
|
2420
|
+
input: values["tailwind-input"],
|
|
2421
|
+
output: values["tailwind-output"]
|
|
2422
|
+
} : undefined;
|
|
2423
|
+
const useTailwind = values.tailwind ?? (hasTailwindFiles ? true : undefined);
|
|
2424
|
+
if (useTailwind === false && hasTailwindFiles) {
|
|
2425
|
+
console.warn("Warning: Tailwind CSS input/output files are specified but Tailwind is disabled.");
|
|
2426
|
+
tailwind = undefined;
|
|
2427
|
+
}
|
|
2428
|
+
const argumentConfiguration = {
|
|
2429
|
+
assetsDirectory: values.assets,
|
|
2430
|
+
authProvider,
|
|
2431
|
+
buildDirectory: values.build,
|
|
2432
|
+
codeQualityTool,
|
|
2433
|
+
databaseDirectory,
|
|
2434
|
+
databaseEngine,
|
|
2435
|
+
databaseHost,
|
|
2436
|
+
directoryConfig,
|
|
2437
|
+
frontendDirectories,
|
|
2438
|
+
frontends: values.frontend?.filter(isFrontend),
|
|
2439
|
+
htmlScriptOption,
|
|
2440
|
+
initializeGitNow: values.git,
|
|
2441
|
+
installDependenciesNow: values.npm,
|
|
2442
|
+
language,
|
|
2443
|
+
orm,
|
|
2444
|
+
plugins,
|
|
2445
|
+
projectName: positionals[0],
|
|
2446
|
+
tailwind,
|
|
2447
|
+
useTailwind
|
|
2448
|
+
};
|
|
2449
|
+
return {
|
|
2450
|
+
argumentConfiguration,
|
|
2451
|
+
debug: values.debug,
|
|
2452
|
+
help: values.help,
|
|
2453
|
+
latest: values.lts
|
|
2454
|
+
};
|
|
2455
|
+
};
|
|
2456
|
+
|
|
2127
2457
|
// src/utils/t3-utils.ts
|
|
2128
2458
|
import { env } from "node:process";
|
|
2129
2459
|
var getUserPackageManager = () => {
|
|
@@ -2142,24 +2472,15 @@ var getUserPackageManager = () => {
|
|
|
2142
2472
|
};
|
|
2143
2473
|
|
|
2144
2474
|
// 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
2475
|
var packageManager = getUserPackageManager();
|
|
2155
|
-
|
|
2476
|
+
var { help, argumentConfiguration, latest, debug } = parseCommandLineOptions();
|
|
2477
|
+
if (help === true) {
|
|
2156
2478
|
console.log(helpMessage);
|
|
2157
|
-
|
|
2479
|
+
exit5(0);
|
|
2158
2480
|
}
|
|
2159
|
-
var response = await prompt();
|
|
2160
|
-
scaffold({ latest
|
|
2161
|
-
var debugMessage =
|
|
2162
|
-
availableFrontends,
|
|
2481
|
+
var response = await prompt(argumentConfiguration);
|
|
2482
|
+
scaffold({ latest, packageManager, response });
|
|
2483
|
+
var debugMessage = debug !== false ? getDebugMessage({
|
|
2163
2484
|
packageManager,
|
|
2164
2485
|
response
|
|
2165
2486
|
}) : "";
|
|
@@ -2168,4 +2489,4 @@ var outroMessage = getOutroMessage({
|
|
|
2168
2489
|
packageManager,
|
|
2169
2490
|
projectName: response.projectName
|
|
2170
2491
|
});
|
|
2171
|
-
Se(
|
|
2492
|
+
Se(outroMessage + debugMessage);
|