create-authenik8-app 2.0.6 → 2.0.8
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/README.md +19 -13
- package/dist/bin/index.d.ts +5 -0
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +500 -302
- package/dist/bin/index.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +262 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +25 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/process.d.ts +7 -0
- package/dist/lib/process.d.ts.map +1 -0
- package/dist/lib/process.js +56 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/lib/state.d.ts +8 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +31 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/types.d.ts +16 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/ui.d.ts +7 -0
- package/dist/lib/ui.d.ts.map +1 -0
- package/dist/lib/ui.js +124 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/steps/configurePrisma.d.ts +3 -0
- package/dist/steps/configurePrisma.d.ts.map +1 -0
- package/dist/steps/configurePrisma.js +41 -0
- package/dist/steps/configurePrisma.js.map +1 -0
- package/dist/steps/createProject.d.ts +4 -0
- package/dist/steps/createProject.d.ts.map +1 -0
- package/dist/steps/createProject.js +16 -0
- package/dist/steps/createProject.js.map +1 -0
- package/dist/steps/finalSetup.d.ts +4 -0
- package/dist/steps/finalSetup.d.ts.map +1 -0
- package/dist/steps/finalSetup.js +52 -0
- package/dist/steps/finalSetup.js.map +1 -0
- package/dist/steps/installAuth.d.ts +2 -0
- package/dist/steps/installAuth.d.ts.map +1 -0
- package/dist/steps/installAuth.js +34 -0
- package/dist/steps/installAuth.js.map +1 -0
- package/dist/steps/installDeps.d.ts +3 -0
- package/dist/steps/installDeps.d.ts.map +1 -0
- package/dist/steps/installDeps.js +31 -0
- package/dist/steps/installDeps.js.map +1 -0
- package/dist/steps/prompts.d.ts +3 -0
- package/dist/steps/prompts.d.ts.map +1 -0
- package/dist/steps/prompts.js +47 -0
- package/dist/steps/prompts.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +41 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/output.d.ts +3 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +62 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +7 -4
- package/templates/express-auth+/src/auth/protected.routes.ts +2 -2
- package/templates/express-auth/ecosystem.config.ts +0 -16
- package/templates/express-auth+/ecosystem.config.ts +0 -16
- package/templates/express-base/ecosystem.config.ts +0 -16
package/dist/bin/index.js
CHANGED
|
@@ -5,39 +5,86 @@ import chalk from "chalk";
|
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import { ExitPromptError } from "@inquirer/core";
|
|
7
7
|
import ora from "ora";
|
|
8
|
-
import { execSync } from "child_process";
|
|
8
|
+
import { execSync, ChildProcess } from "child_process";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
|
-
import { spawnSync } from "child_process";
|
|
10
|
+
import { spawnSync, spawn } from "child_process";
|
|
11
11
|
import os from "os";
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const spinner = ora().start();
|
|
13
|
+
const activeProcesses = new Set();
|
|
14
|
+
export function run(cmd, args, options) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const child = spawn(cmd, args, {
|
|
17
|
+
cwd: options.cwd,
|
|
18
|
+
stdio: "ignore",
|
|
19
|
+
});
|
|
20
|
+
activeProcesses.add(child);
|
|
21
|
+
child.on("exit", (code) => {
|
|
22
|
+
activeProcesses.delete(child);
|
|
23
|
+
if (code === 0) {
|
|
24
|
+
resolve();
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
reject(new Error(`${cmd} exited with code ${code}`));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
child.on("error", (err) => {
|
|
31
|
+
activeProcesses.delete(child);
|
|
32
|
+
reject(err);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function killAllProcesses() {
|
|
37
|
+
for (const proc of activeProcesses) {
|
|
38
|
+
try {
|
|
39
|
+
proc.kill("SIGINT");
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
}
|
|
43
|
+
activeProcesses.clear();
|
|
14
44
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
45
|
+
function getCommand(cmd) {
|
|
46
|
+
const isWin = process.platform === "win32";
|
|
47
|
+
if (cmd === "npm")
|
|
48
|
+
return isWin ? "npm.cmd" : "npm";
|
|
49
|
+
if (cmd === "npx")
|
|
50
|
+
return isWin ? "npx.cmd" : "npx";
|
|
51
|
+
if (cmd === "git")
|
|
52
|
+
return isWin ? "git.exe" : "git";
|
|
53
|
+
return cmd;
|
|
21
54
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
55
|
+
//make sure steps are completed
|
|
56
|
+
function stepActuallyCompleted(step) {
|
|
57
|
+
switch (step) {
|
|
58
|
+
case "deps-installed":
|
|
59
|
+
return fs.existsSync(path.join(targetDir, "node_modules"));
|
|
60
|
+
case "prisma-generated":
|
|
61
|
+
return fs.existsSync(path.join(targetDir, "node_modules/.prisma/client"));
|
|
62
|
+
case "git-initialized":
|
|
63
|
+
return fs.existsSync(path.join(targetDir, ".git"));
|
|
64
|
+
default:
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
27
67
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
68
|
+
const args = process.argv.slice(2);
|
|
69
|
+
const projectNameArg = args.find(arg => !arg.startsWith("--"));
|
|
70
|
+
//const projectNameArg = process.argv[2];
|
|
71
|
+
if (!projectNameArg) {
|
|
72
|
+
console.log(chalk.red("❌ Please provide a project name"));
|
|
73
|
+
process.exit(1);
|
|
32
74
|
}
|
|
33
|
-
const
|
|
75
|
+
const projectName = projectNameArg;
|
|
76
|
+
//let answers:any = {};
|
|
77
|
+
let state = {
|
|
78
|
+
step: "start",
|
|
79
|
+
projectName,
|
|
80
|
+
};
|
|
34
81
|
const platform = os.platform();
|
|
35
82
|
// 'linux' | 'darwin' | 'win32'
|
|
36
83
|
const isTermux = process.env.PREFIX?.includes("com.termux") ||
|
|
37
84
|
process.env.TERMUX === "true";
|
|
38
85
|
function getBestHashLib() {
|
|
39
86
|
if (isTermux)
|
|
40
|
-
return "bcryptjs";
|
|
87
|
+
return "bcryptjs";
|
|
41
88
|
if (platform === "win32")
|
|
42
89
|
return "bcryptjs";
|
|
43
90
|
// avoids build tools issues for most users
|
|
@@ -49,17 +96,6 @@ function getBestHashLib() {
|
|
|
49
96
|
// but still fallback later if needed
|
|
50
97
|
return "bcryptjs";
|
|
51
98
|
}
|
|
52
|
-
function createSaver(projectName, ctx) {
|
|
53
|
-
return (step, extra) => {
|
|
54
|
-
saveState(projectName, {
|
|
55
|
-
step,
|
|
56
|
-
projectName,
|
|
57
|
-
...ctx.state,
|
|
58
|
-
...ctx.answers,
|
|
59
|
-
...extra,
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
99
|
function generateHashModule(hashLib) {
|
|
64
100
|
if (hashLib === "argon2") {
|
|
65
101
|
return `
|
|
@@ -88,122 +124,181 @@ return bcrypt.compare(password, hash);
|
|
|
88
124
|
}
|
|
89
125
|
const __filename = fileURLToPath(import.meta.url);
|
|
90
126
|
const __dirname = path.dirname(__filename);
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
96
|
-
const isProduction = process.argv.includes("--production-ready");
|
|
97
|
-
const targetDir = path.join(process.cwd(), projectName);
|
|
127
|
+
const isProduction = args.includes("--production-ready");
|
|
128
|
+
const isResume = args.includes("--resume");
|
|
129
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
98
130
|
let projectCreated = false;
|
|
99
|
-
const
|
|
100
|
-
|
|
131
|
+
const stepOrder = [
|
|
132
|
+
"start",
|
|
133
|
+
"prompts",
|
|
134
|
+
"project-created",
|
|
135
|
+
"auth-installed",
|
|
136
|
+
"prisma-configured",
|
|
137
|
+
"deps-installed",
|
|
138
|
+
"prisma-generated",
|
|
139
|
+
"production-configured",
|
|
140
|
+
"git-initialized",
|
|
141
|
+
"done",
|
|
142
|
+
];
|
|
143
|
+
const stepLabels = {
|
|
144
|
+
start: "Starting",
|
|
145
|
+
prompts: "Collecting inputs",
|
|
146
|
+
"project-created": "Project scaffold",
|
|
147
|
+
"auth-installed": "Auth setup",
|
|
148
|
+
"prisma-configured": "Prisma setup",
|
|
149
|
+
"deps-installed": "Dependencies install",
|
|
150
|
+
"prisma-generated": "Prisma generate",
|
|
151
|
+
"production-configured": "Production setup",
|
|
152
|
+
"git-initialized": "Git init",
|
|
153
|
+
done: "Completed",
|
|
154
|
+
};
|
|
155
|
+
const globalStateDir = path.join(process.cwd(), ".authenik8");
|
|
156
|
+
const stateFile = path.join(globalStateDir, `${projectName}.json`);
|
|
157
|
+
function hasReachedStep(currentStep, targetStep) {
|
|
158
|
+
return stepOrder.indexOf(currentStep) >= stepOrder.indexOf(targetStep);
|
|
101
159
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// trigger resume logic
|
|
160
|
+
//function saveState(step: StepName, extra: Partial<CliState> = {}) {
|
|
161
|
+
function saveState(update) {
|
|
162
|
+
state = { ...state, ...update };
|
|
163
|
+
fs.ensureDirSync(path.dirname(stateFile));
|
|
164
|
+
fs.writeJsonSync(stateFile, state, { spaces: 2 });
|
|
165
|
+
}
|
|
166
|
+
function loadState() {
|
|
167
|
+
if (!fs.existsSync(stateFile))
|
|
168
|
+
return null;
|
|
169
|
+
return fs.readJsonSync(stateFile);
|
|
170
|
+
}
|
|
171
|
+
function clearState() {
|
|
172
|
+
if (fs.existsSync(stateFile)) {
|
|
173
|
+
fs.removeSync(stateFile);
|
|
117
174
|
}
|
|
118
|
-
|
|
119
|
-
|
|
175
|
+
}
|
|
176
|
+
function renderStep(current) {
|
|
177
|
+
console.clear();
|
|
178
|
+
renderHeader();
|
|
179
|
+
for (const step of stepOrder) {
|
|
180
|
+
const label = stepLabels[step];
|
|
181
|
+
if (step === "production-configured" && !isProduction) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (step === current) {
|
|
185
|
+
console.log(chalk.yellow(`⏳ ${label}...`));
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
if (hasReachedStep(current, step)) {
|
|
189
|
+
console.log(chalk.green(`✔ ${label}`));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log(chalk.gray(`○ ${label}`));
|
|
193
|
+
}
|
|
120
194
|
}
|
|
121
|
-
|
|
122
|
-
|
|
195
|
+
console.log("");
|
|
196
|
+
}
|
|
197
|
+
function isInterruptedError(err) {
|
|
198
|
+
return (typeof err === "object" &&
|
|
199
|
+
err !== null &&
|
|
200
|
+
"signal" in err &&
|
|
201
|
+
(err.signal === "SIGINT" ||
|
|
202
|
+
err.signal === "SIGTERM"));
|
|
203
|
+
}
|
|
204
|
+
async function exitForInterrupt(err) {
|
|
205
|
+
if (isInterruptedError(err)) {
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async function cleanupIncompleteProject() {
|
|
210
|
+
if (projectCreated && fs.existsSync(targetDir)) {
|
|
211
|
+
await fs.remove(targetDir);
|
|
212
|
+
console.log("🧹 Cleaned up incomplete project.");
|
|
123
213
|
}
|
|
124
214
|
}
|
|
125
215
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
126
|
-
const cleanLogo = `
|
|
127
|
-
|
|
128
|
-
█████╗ █████╗
|
|
129
|
-
██╔══██╗ ██╔══██╗
|
|
130
|
-
███████║ ╚█████╔╝
|
|
131
|
-
██╔══██║ ██╔══██╗
|
|
132
|
-
██║ ██║ ╚█████╔╝
|
|
133
|
-
╚═╝ ╚═╝ ╚════╝
|
|
134
|
-
|
|
135
|
-
A8
|
|
136
|
-
|
|
137
|
-
Authenik8 CLI
|
|
138
|
-
Build Faster
|
|
139
|
-
More , Secure
|
|
216
|
+
const cleanLogo = `
|
|
217
|
+
|
|
218
|
+
█████╗ █████╗
|
|
219
|
+
██╔══██╗ ██╔══██╗
|
|
220
|
+
███████║ ╚█████╔╝
|
|
221
|
+
██╔══██║ ██╔══██╗
|
|
222
|
+
██║ ██║ ╚█████╔╝
|
|
223
|
+
╚═╝ ╚═╝ ╚════╝
|
|
224
|
+
|
|
225
|
+
A8
|
|
226
|
+
|
|
227
|
+
Authenik8 CLI
|
|
228
|
+
Build Faster
|
|
229
|
+
More , Secure
|
|
140
230
|
`;
|
|
141
231
|
const glitchFrames = [
|
|
142
232
|
`
|
|
143
|
-
█████╗ █████╗
|
|
144
|
-
██╔══██╗ ██▒▒▒▒██
|
|
145
|
-
███████║ ╚█████╔╝
|
|
146
|
-
██╔══██║ ██▒▒▒▒██
|
|
147
|
-
██║ ██║ ╚█████╔╝
|
|
148
|
-
╚═╝ ╚═╝ ╚════╝
|
|
149
|
-
|
|
233
|
+
█████╗ █████╗
|
|
234
|
+
██╔══██╗ ██▒▒▒▒██
|
|
235
|
+
███████║ ╚█████╔╝
|
|
236
|
+
██╔══██║ ██▒▒▒▒██
|
|
237
|
+
██║ ██║ ╚█████╔╝
|
|
238
|
+
╚═╝ ╚═╝ ╚════╝
|
|
239
|
+
|
|
150
240
|
A8
|
|
151
241
|
Authenik8 CLI
|
|
152
|
-
|
|
153
|
-
More
|
|
242
|
+
|
|
243
|
+
More
|
|
154
244
|
`,
|
|
155
|
-
`
|
|
156
|
-
██▓▓██╗ ██▓▓██╗
|
|
157
|
-
██▒▒██╔╝ ██▒▒██╔╝
|
|
158
|
-
██▒▒▒▒██ ╚█████╔╝
|
|
159
|
-
██▓▓██╔╝ ██▒▒██╗
|
|
160
|
-
██▒▒██║ ╚█████╔╝
|
|
161
|
-
╚═════╝ ╚════╝
|
|
162
|
-
|
|
245
|
+
`
|
|
246
|
+
██▓▓██╗ ██▓▓██╗
|
|
247
|
+
██▒▒██╔╝ ██▒▒██╔╝
|
|
248
|
+
██▒▒▒▒██ ╚█████╔╝
|
|
249
|
+
██▓▓██╔╝ ██▒▒██╗
|
|
250
|
+
██▒▒██║ ╚█████╔╝
|
|
251
|
+
╚═════╝ ╚════╝
|
|
252
|
+
|
|
163
253
|
A8
|
|
164
254
|
Authenik8 CLI
|
|
165
|
-
Faster
|
|
255
|
+
Faster
|
|
166
256
|
`,
|
|
167
|
-
`
|
|
168
|
-
██▒▒██╗ ██▒▒██╗
|
|
169
|
-
██▓▓██╔╝ ██▓▓██╔╝
|
|
170
|
-
██▒▒▒▒██ ╚█████╔╝
|
|
171
|
-
██▓▓██╔╝ ██▓▓██╗
|
|
172
|
-
██▒▒██║ ╚█████╔╝
|
|
173
|
-
╚═════╝ ╚════╝
|
|
174
|
-
|
|
257
|
+
`
|
|
258
|
+
██▒▒██╗ ██▒▒██╗
|
|
259
|
+
██▓▓██╔╝ ██▓▓██╔╝
|
|
260
|
+
██▒▒▒▒██ ╚█████╔╝
|
|
261
|
+
██▓▓██╔╝ ██▓▓██╗
|
|
262
|
+
██▒▒██║ ╚█████╔╝
|
|
263
|
+
╚═════╝ ╚════╝
|
|
264
|
+
|
|
175
265
|
A8
|
|
176
266
|
Authenik8 CLI
|
|
177
|
-
Build
|
|
267
|
+
Build
|
|
178
268
|
`,
|
|
179
|
-
`
|
|
180
|
-
██▓▓██╗ ██▓▓██╗
|
|
181
|
-
██▒▒██╔╝ ██▒▒██╔╝
|
|
182
|
-
██▒▒▒▒██ ╚█████╔╝
|
|
183
|
-
██▓▓██╔╝ ██▒▒██╗
|
|
184
|
-
██▒▒██║ ╚█████╔╝
|
|
185
|
-
╚═════╝ ╚════╝
|
|
186
|
-
|
|
269
|
+
`
|
|
270
|
+
██▓▓██╗ ██▓▓██╗
|
|
271
|
+
██▒▒██╔╝ ██▒▒██╔╝
|
|
272
|
+
██▒▒▒▒██ ╚█████╔╝
|
|
273
|
+
██▓▓██╔╝ ██▒▒██╗
|
|
274
|
+
██▒▒██║ ╚█████╔╝
|
|
275
|
+
╚═════╝ ╚════╝
|
|
276
|
+
|
|
187
277
|
A8
|
|
188
|
-
Authenik8 CLI
|
|
189
|
-
|
|
278
|
+
Authenik8 CLI
|
|
279
|
+
|
|
190
280
|
`
|
|
191
281
|
];
|
|
282
|
+
function renderHeader() {
|
|
283
|
+
console.log(chalk.cyan.bold("Happy building \nAuthenik8 CLI"));
|
|
284
|
+
console.log(chalk.gray("────────────────────"));
|
|
285
|
+
console.log("");
|
|
286
|
+
}
|
|
192
287
|
async function showBootLogo() {
|
|
193
288
|
console.clear();
|
|
194
|
-
|
|
195
|
-
// Phase 1: clean → unstable
|
|
289
|
+
spinner.text = "Initializing Authenik8 engine...";
|
|
290
|
+
// Phase 1: clean → unstable
|
|
196
291
|
console.clear();
|
|
197
292
|
console.log(chalk.cyan(cleanLogo));
|
|
198
293
|
await sleep(200);
|
|
199
|
-
// Phase 2: glitch burst (irregular feel)
|
|
294
|
+
// Phase 2: glitch burst (irregular feel)
|
|
200
295
|
for (let i = 0; i < 5; i++) {
|
|
201
296
|
console.clear();
|
|
202
297
|
const frame = glitchFrames[Math.floor(Math.random() * glitchFrames.length)];
|
|
203
298
|
console.log(chalk.cyan(frame));
|
|
204
299
|
await sleep(120 + Math.random() * 120);
|
|
205
300
|
}
|
|
206
|
-
// Phase 3: stabilization flicker
|
|
301
|
+
// Phase 3: stabilization flicker
|
|
207
302
|
for (let i = 0; i < 2; i++) {
|
|
208
303
|
console.clear();
|
|
209
304
|
console.log(chalk.cyan(cleanLogo));
|
|
@@ -212,14 +307,21 @@ async function showBootLogo() {
|
|
|
212
307
|
console.log(chalk.gray(cleanLogo));
|
|
213
308
|
await sleep(120);
|
|
214
309
|
}
|
|
215
|
-
// Final render
|
|
310
|
+
// Final render
|
|
216
311
|
console.clear();
|
|
217
312
|
console.log(chalk.cyan.bold(cleanLogo));
|
|
218
313
|
await sleep(800);
|
|
219
|
-
|
|
314
|
+
spinner.succeed("Engine ready");
|
|
220
315
|
}
|
|
221
|
-
//const isResume = process.argv.includes("--resume");
|
|
222
316
|
async function main() {
|
|
317
|
+
process.on("SIGINT", async () => {
|
|
318
|
+
console.log("\n");
|
|
319
|
+
spinner.stop();
|
|
320
|
+
killAllProcesses();
|
|
321
|
+
console.log(chalk.yellow("⏸ Setup interrupted."));
|
|
322
|
+
console.log(chalk.gray(`↻ Resume with: create-authenik8-app ${projectName} --resume`));
|
|
323
|
+
process.exit(0);
|
|
324
|
+
});
|
|
223
325
|
try {
|
|
224
326
|
await showBootLogo();
|
|
225
327
|
if (process.argv.includes("--help")) {
|
|
@@ -272,227 +374,320 @@ Features:
|
|
|
272
374
|
• Prisma ORM (optional)
|
|
273
375
|
• Git initialization (optional)
|
|
274
376
|
• OAuth + Auth
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
`));
|
|
380
|
+
const savedState = loadState();
|
|
381
|
+
let currentStep = "start";
|
|
382
|
+
if (!isResume && fs.existsSync(targetDir)) {
|
|
383
|
+
if (savedState) {
|
|
384
|
+
console.log(chalk.red(`❌ "${projectName}" already contains an incomplete Authenik8 setup. Run again with --resume.`));
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
console.log(chalk.red(`❌ Directory "${projectName}" already exists.`));
|
|
388
|
+
}
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
if (isResume || fs.existsSync(stateFile)) {
|
|
392
|
+
console.log(chalk.gray(`
|
|
393
|
+
Resumable steps:
|
|
394
|
+
✔ project scaffold
|
|
395
|
+
✔ auth install
|
|
396
|
+
✔ prisma setup
|
|
397
|
+
✔ deps install
|
|
398
|
+
✔ prisma generate
|
|
399
|
+
✔ git init
|
|
275
400
|
`));
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
choices: ["Express", "Fastify (coming soon)"],
|
|
282
|
-
default: state.framework ?? "Express",
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
type: "confirm",
|
|
286
|
-
name: "usePrisma",
|
|
287
|
-
message: "Use Prisma?",
|
|
288
|
-
default: state.usePrisma ?? true,
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
type: "list",
|
|
292
|
-
name: "database",
|
|
293
|
-
message: "Choose database:",
|
|
294
|
-
choices: [
|
|
295
|
-
{ name: "PostgreSQL", value: "postgresql" },
|
|
296
|
-
{ name: "SQLite ", value: "sqlite" }
|
|
297
|
-
],
|
|
298
|
-
when: (answers) => answers.usePrisma,
|
|
299
|
-
default: state.database ?? "sqlite",
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
type: "confirm",
|
|
303
|
-
name: "useGit",
|
|
304
|
-
message: "Initialize git?",
|
|
305
|
-
default: state.useGit ?? true,
|
|
306
|
-
}, {
|
|
307
|
-
type: "list",
|
|
308
|
-
name: "authMode",
|
|
309
|
-
message: "Choose authentication setup:",
|
|
310
|
-
choices: [
|
|
311
|
-
{ name: "JWT only", value: "base" },
|
|
312
|
-
{ name: "Email + Password Auth", value: "auth" },
|
|
313
|
-
{ name: "Full Auth (Password + OAuth)", value: "auth-oauth" },
|
|
314
|
-
],
|
|
315
|
-
default: state.authMode ?? "base"
|
|
401
|
+
}
|
|
402
|
+
if (isResume) {
|
|
403
|
+
if (!savedState) {
|
|
404
|
+
console.log(chalk.red(`❌ No saved setup state found for "${projectName}".`));
|
|
405
|
+
process.exit(1);
|
|
316
406
|
}
|
|
317
|
-
|
|
407
|
+
state = savedState;
|
|
408
|
+
currentStep = state.step;
|
|
409
|
+
console.log(chalk.yellow(`\n↻ Resuming setup for ${projectName} from "${currentStep}"...\n`));
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
const promptAnswers = await inquirer.prompt([
|
|
413
|
+
{
|
|
414
|
+
type: "list",
|
|
415
|
+
name: "framework",
|
|
416
|
+
message: "Choose framework:",
|
|
417
|
+
choices: ["Express", "Fastify (coming soon)"],
|
|
418
|
+
default: "Express",
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
type: "confirm",
|
|
422
|
+
name: "usePrisma",
|
|
423
|
+
message: "Use Prisma?",
|
|
424
|
+
default: true,
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
type: "list",
|
|
428
|
+
name: "database",
|
|
429
|
+
message: "Choose database:",
|
|
430
|
+
choices: [
|
|
431
|
+
{ name: "PostgreSQL", value: "postgresql" },
|
|
432
|
+
{ name: "SQLite ", value: "sqlite" }
|
|
433
|
+
],
|
|
434
|
+
when: (answers) => answers.usePrisma,
|
|
435
|
+
default: "sqlite",
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
type: "confirm",
|
|
439
|
+
name: "useGit",
|
|
440
|
+
message: "Initialize git?",
|
|
441
|
+
default: true,
|
|
442
|
+
}, {
|
|
443
|
+
type: "list",
|
|
444
|
+
name: "authMode",
|
|
445
|
+
message: "Choose authentication setup:",
|
|
446
|
+
choices: [
|
|
447
|
+
{ name: "JWT only", value: "base" },
|
|
448
|
+
{ name: "Email + Password Auth", value: "auth" },
|
|
449
|
+
{ name: "Full Auth (Password + OAuth)", value: "auth-oauth" },
|
|
450
|
+
],
|
|
451
|
+
default: "base"
|
|
452
|
+
}
|
|
453
|
+
]);
|
|
454
|
+
//saveState({
|
|
455
|
+
//...promptAnswers,
|
|
456
|
+
//step:"prompts"});
|
|
457
|
+
state = {
|
|
458
|
+
...state,
|
|
459
|
+
...promptAnswers,
|
|
460
|
+
step: "prompts"
|
|
461
|
+
};
|
|
462
|
+
saveState({
|
|
463
|
+
...state
|
|
464
|
+
});
|
|
465
|
+
currentStep = "prompts";
|
|
466
|
+
}
|
|
318
467
|
function assertRequired(value, name) {
|
|
319
468
|
if (value === undefined || value === null || value === "") {
|
|
320
469
|
console.log(`❌ Missing required input: ${name}`);
|
|
321
470
|
process.exit(1);
|
|
322
471
|
}
|
|
323
472
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
finalConfig.database = "sqlite";
|
|
332
|
-
}
|
|
333
|
-
if (finalConfig.usePrisma) {
|
|
334
|
-
assertRequired(finalConfig.database, "database");
|
|
335
|
-
}
|
|
336
|
-
if (finalConfig.usePrisma && !answers.database && !state.database) {
|
|
337
|
-
console.log(chalk.gray("ℹ️ Defaulting to SQLite (quick start)"));
|
|
338
|
-
}
|
|
339
|
-
if (!answers.authMode || !answers.framework) {
|
|
340
|
-
console.log("❌ Invalid setup state. Restart CLI.");
|
|
341
|
-
process.exit(1);
|
|
473
|
+
assertRequired(state.framework, "framework");
|
|
474
|
+
assertRequired(state.authMode, "authMode");
|
|
475
|
+
if (state.usePrisma) {
|
|
476
|
+
if (!state.database) {
|
|
477
|
+
state.database = "sqlite";
|
|
478
|
+
}
|
|
479
|
+
assertRequired(state.database, "database");
|
|
342
480
|
}
|
|
343
|
-
console.log(chalk.cyan("\
|
|
481
|
+
console.log(chalk.cyan("\nSetting up your project\n"));
|
|
344
482
|
const templateRoot = path.resolve(__dirname, "../../templates");
|
|
345
483
|
let templateName = "express-base";
|
|
346
|
-
if (
|
|
484
|
+
if (state.authMode === "auth") {
|
|
347
485
|
templateName = "express-auth";
|
|
348
486
|
}
|
|
349
|
-
if (
|
|
487
|
+
if (state.authMode === "auth-oauth") {
|
|
350
488
|
templateName = "express-auth+";
|
|
351
489
|
}
|
|
352
490
|
const templatePath = path.join(templateRoot, templateName);
|
|
353
491
|
// 📁 Create project (SPINNER)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
await fs.copy(templatePath, targetDir);
|
|
357
|
-
projectCreated = true;
|
|
358
|
-
createSpinner.succeed("Project files created");
|
|
359
|
-
}
|
|
360
|
-
catch (err) {
|
|
361
|
-
createSpinner.fail("Failed to create project");
|
|
362
|
-
console.error(err);
|
|
363
|
-
process.exit(1);
|
|
364
|
-
}
|
|
365
|
-
let selectedHash = "bcryptjs"; // default safe fallback
|
|
366
|
-
if (answers.authMode !== "base") {
|
|
367
|
-
const authSpinner = ora("Installing password auth...").start();
|
|
368
|
-
selectedHash = getBestHashLib();
|
|
492
|
+
if (!hasReachedStep(currentStep, "project-created")) {
|
|
493
|
+
renderStep("project-created");
|
|
369
494
|
try {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
495
|
+
await fs.copy(templatePath, targetDir);
|
|
496
|
+
projectCreated = true;
|
|
497
|
+
saveState({ step: "project-created" });
|
|
498
|
+
currentStep = "project-created";
|
|
499
|
+
renderStep(currentStep);
|
|
375
500
|
}
|
|
376
501
|
catch (err) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
502
|
+
console.error(err);
|
|
503
|
+
process.exit(1);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
console.log(chalk.gray("↷ Skipping project creation (already completed)"));
|
|
508
|
+
}
|
|
509
|
+
let selectedHash = "bcryptjs"; // default safe fallback
|
|
510
|
+
if (!hasReachedStep(currentStep, "auth-installed")) {
|
|
511
|
+
if (state.authMode !== "base") {
|
|
512
|
+
spinner.start("Installing password auth...");
|
|
513
|
+
selectedHash = getBestHashLib();
|
|
514
|
+
try {
|
|
515
|
+
const installResult = await run(getCommand("npm"), ["install", selectedHash], {
|
|
380
516
|
cwd: targetDir,
|
|
381
|
-
stdio: "ignore"
|
|
517
|
+
stdio: "ignore"
|
|
382
518
|
});
|
|
383
|
-
selectedHash = "bcryptjs";
|
|
384
|
-
authSpinner.succeed("Password auth ready (bcryptjs fallback)");
|
|
385
519
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
520
|
+
catch {
|
|
521
|
+
if (selectedHash !== "bcryptjs") {
|
|
522
|
+
spinner.warn(`${selectedHash} failed, falling back to bcryptjs`);
|
|
523
|
+
const fallbackResult = await run(getCommand("npm"), ["install", "bcryptjs"], {
|
|
524
|
+
cwd: targetDir,
|
|
525
|
+
stdio: "ignore",
|
|
526
|
+
});
|
|
527
|
+
spinner.stop();
|
|
528
|
+
selectedHash = "bcryptjs";
|
|
529
|
+
renderStep("auth-installed");
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
spinner.fail("Failed to install password auth");
|
|
533
|
+
process.exit(1);
|
|
534
|
+
spinner.fail("Failed to install password auth");
|
|
535
|
+
process.exit(1);
|
|
536
|
+
}
|
|
389
537
|
}
|
|
390
538
|
}
|
|
539
|
+
renderStep("auth-installed");
|
|
540
|
+
if (state.authMode !== "base") {
|
|
541
|
+
spinner.start("Installing password auth...");
|
|
542
|
+
const hashLib = selectedHash;
|
|
543
|
+
await fs.writeFile(path.join(targetDir, "src/utils/hash.ts"), generateHashModule(hashLib));
|
|
544
|
+
}
|
|
545
|
+
saveState({ step: "auth-installed", ...(state.authMode !== "base" && { hashLib: selectedHash })
|
|
546
|
+
});
|
|
547
|
+
currentStep = "auth-installed";
|
|
548
|
+
renderStep(currentStep);
|
|
391
549
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
550
|
+
else {
|
|
551
|
+
selectedHash = savedState?.hashLib ?? selectedHash;
|
|
552
|
+
console.log(chalk.gray("↷ Skipping auth setup (already completed)"));
|
|
553
|
+
}
|
|
554
|
+
if (!hasReachedStep(currentStep, "prisma-configured")) {
|
|
555
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
556
|
+
const pkg = await fs.readJson(pkgPath);
|
|
557
|
+
pkg.dependencies = {
|
|
558
|
+
...pkg.dependencies,
|
|
559
|
+
ioredis: "^5.8.1",
|
|
560
|
+
};
|
|
561
|
+
if (state.usePrisma) {
|
|
562
|
+
spinner.start("Adding Prisma setup...");
|
|
563
|
+
try {
|
|
564
|
+
const dbType = state.database ===
|
|
565
|
+
"postgresql" ? "postgresql" :
|
|
566
|
+
"sqlite";
|
|
567
|
+
const prismaTemplatePath = path.join(templateRoot, `prisma/${dbType}`);
|
|
568
|
+
// Copy prisma schema
|
|
569
|
+
await fs.copy(path.join(prismaTemplatePath, "schema.prisma"), path.join(targetDir, "prisma/schema.prisma"));
|
|
570
|
+
// Copy env
|
|
571
|
+
await fs.copy(path.join(prismaTemplatePath, ".env"), path.join(targetDir, ".env"));
|
|
572
|
+
// Inject dependencies
|
|
573
|
+
pkg.dependencies = {
|
|
574
|
+
...pkg.dependencies,
|
|
575
|
+
"@prisma/client": "5.22.0",
|
|
576
|
+
};
|
|
577
|
+
pkg.devDependencies = {
|
|
578
|
+
...pkg.devDependencies,
|
|
579
|
+
prisma: "5.22.0",
|
|
580
|
+
};
|
|
581
|
+
// Add scripts
|
|
582
|
+
pkg.scripts = {
|
|
583
|
+
...pkg.scripts,
|
|
584
|
+
"prisma:generate": "prisma generate",
|
|
585
|
+
"prisma:migrate": "prisma migrate dev",
|
|
586
|
+
};
|
|
587
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
588
|
+
spinner.succeed(`Prisma (${dbType}) configured`);
|
|
589
|
+
}
|
|
590
|
+
catch (err) {
|
|
591
|
+
spinner.fail("Failed to setup Prisma");
|
|
592
|
+
exitForInterrupt(err);
|
|
593
|
+
}
|
|
405
594
|
}
|
|
406
|
-
;
|
|
595
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
596
|
+
saveState({ step: "prisma-configured", ...(state.authMode !== "base" && { hashLib: selectedHash })
|
|
597
|
+
});
|
|
598
|
+
currentStep = "prisma-configured";
|
|
599
|
+
renderStep(currentStep);
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
console.log(chalk.gray(" Skipping Prisma/package setup (already completed)"));
|
|
407
603
|
}
|
|
408
|
-
if (
|
|
409
|
-
|
|
604
|
+
if (!hasReachedStep(currentStep, "deps-installed")) {
|
|
605
|
+
renderStep("deps-installed");
|
|
606
|
+
spinner.start("Installing dependencies...(this may take a few minutes)");
|
|
410
607
|
try {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
: "
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
await fs.copy(path.join(prismaTemplatePath, "schema.prisma"), path.join(targetDir, "prisma/schema.prisma"));
|
|
417
|
-
// Copy env
|
|
418
|
-
await fs.copy(path.join(prismaTemplatePath, ".env"), path.join(targetDir, ".env"));
|
|
419
|
-
const pkgPath = path.join(targetDir, "package.json");
|
|
420
|
-
const pkg = await fs.readJson(pkgPath);
|
|
421
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
422
|
-
// Inject dependencies
|
|
423
|
-
pkg.dependencies = {
|
|
424
|
-
...pkg.dependencies,
|
|
425
|
-
"@prisma/client": "5.22.0",
|
|
426
|
-
};
|
|
427
|
-
pkg.devDependencies = {
|
|
428
|
-
...pkg.devDependencies,
|
|
429
|
-
prisma: "5.22.0",
|
|
430
|
-
};
|
|
431
|
-
// Add scripts
|
|
432
|
-
pkg.scripts = {
|
|
433
|
-
...pkg.scripts,
|
|
434
|
-
"prisma:generate": "prisma generate",
|
|
435
|
-
"prisma:migrate": "prisma migrate dev",
|
|
436
|
-
};
|
|
437
|
-
prismaSpinner.succeed(`Prisma (${dbType}) configured`);
|
|
608
|
+
await run(getCommand("npm"), ["install"], {
|
|
609
|
+
cwd: targetDir,
|
|
610
|
+
stdio: "ignore",
|
|
611
|
+
});
|
|
612
|
+
spinner.stop();
|
|
438
613
|
}
|
|
439
614
|
catch (err) {
|
|
440
|
-
|
|
441
|
-
|
|
615
|
+
spinner.fail("Failed to install dependencies");
|
|
616
|
+
exitForInterrupt(err);
|
|
442
617
|
}
|
|
443
|
-
|
|
444
|
-
|
|
618
|
+
saveState({ step: "deps-installed", ...(state.authMode !== "base" && { hashLib: selectedHash })
|
|
619
|
+
});
|
|
620
|
+
currentStep = "deps-installed";
|
|
621
|
+
renderStep(currentStep);
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
await run(getCommand("npm"), ["install"], {
|
|
625
|
+
cwd: targetDir,
|
|
626
|
+
stdio: "ignore",
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
if (!hasReachedStep(currentStep, "prisma-generated")) {
|
|
630
|
+
if (state.usePrisma) {
|
|
631
|
+
spinner.start("Generating Prisma client...");
|
|
445
632
|
try {
|
|
446
|
-
|
|
633
|
+
await run(getCommand("npx"), ["prisma@5.22.0", "generate"], {
|
|
447
634
|
cwd: targetDir,
|
|
448
635
|
stdio: "ignore"
|
|
449
636
|
});
|
|
450
|
-
|
|
637
|
+
spinner.stop();
|
|
451
638
|
}
|
|
452
639
|
catch (err) {
|
|
453
|
-
|
|
454
|
-
|
|
640
|
+
spinner.fail("Failed to generate Prisma client");
|
|
641
|
+
exitForInterrupt(err);
|
|
455
642
|
}
|
|
456
643
|
}
|
|
457
|
-
|
|
644
|
+
saveState({ step: "prisma-generated", ...(state.authMode !== "base" && { hashLib: selectedHash })
|
|
645
|
+
});
|
|
646
|
+
currentStep = "prisma-generated";
|
|
647
|
+
renderStep(currentStep);
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
console.log(chalk.gray("↷ Skipping Prisma client generation (already completed)"));
|
|
651
|
+
}
|
|
652
|
+
if (isProduction && !hasReachedStep(currentStep, "production-configured")) {
|
|
653
|
+
spinner.start("Setting up production mode (PM2)...");
|
|
458
654
|
try {
|
|
459
|
-
|
|
655
|
+
await run(getCommand("npm"), ["install pm2"], {
|
|
460
656
|
cwd: targetDir,
|
|
461
657
|
stdio: "ignore",
|
|
462
658
|
});
|
|
463
|
-
|
|
659
|
+
spinner.stop();
|
|
464
660
|
}
|
|
465
661
|
catch (err) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
process.exit(1);
|
|
662
|
+
spinner.fail("Failed to install PM2");
|
|
663
|
+
exitForInterrupt(err);
|
|
469
664
|
}
|
|
470
|
-
|
|
471
|
-
|
|
665
|
+
saveState({ step: "production-configured", ...(state.authMode !== "base" && { hashLib: selectedHash })
|
|
666
|
+
});
|
|
667
|
+
currentStep = "production-configured";
|
|
668
|
+
renderStep(currentStep);
|
|
669
|
+
}
|
|
670
|
+
if (!hasReachedStep(currentStep, "git-initialized")) {
|
|
671
|
+
if (state.useGit) {
|
|
672
|
+
renderStep("git-initialized");
|
|
472
673
|
try {
|
|
473
|
-
|
|
674
|
+
await run(getCommand("git"), ["init"], {
|
|
474
675
|
cwd: targetDir,
|
|
475
676
|
stdio: "ignore",
|
|
476
677
|
});
|
|
477
|
-
|
|
678
|
+
spinner.stop();
|
|
478
679
|
}
|
|
479
680
|
catch (err) {
|
|
480
|
-
|
|
681
|
+
spinner.fail("Git init failed");
|
|
481
682
|
}
|
|
482
683
|
}
|
|
684
|
+
saveState({ step: "git-initialized", ...(state.authMode !== "base" && { hashLib: selectedHash }),
|
|
685
|
+
});
|
|
686
|
+
currentStep = "git-initialized";
|
|
687
|
+
renderStep("done");
|
|
483
688
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
try {
|
|
487
|
-
execSync("git init", {
|
|
488
|
-
cwd: targetDir,
|
|
489
|
-
stdio: "ignore",
|
|
490
|
-
});
|
|
491
|
-
gitSpinner.succeed("Git initialized");
|
|
492
|
-
}
|
|
493
|
-
catch (err) {
|
|
494
|
-
gitSpinner.fail("Git init failed");
|
|
495
|
-
}
|
|
689
|
+
else {
|
|
690
|
+
console.log(chalk.gray("↷ Skipping git init (already completed)"));
|
|
496
691
|
}
|
|
497
692
|
console.log(chalk.green.bold("\n🎉 Authenik8 app created successfully!\n"));
|
|
498
693
|
if (isProduction) {
|
|
@@ -524,28 +719,28 @@ redis-server --daemonize yes
|
|
|
524
719
|
npm run dev
|
|
525
720
|
|
|
526
721
|
Auth Features:
|
|
527
|
-
${
|
|
722
|
+
${state.authMode === "base"
|
|
528
723
|
? "✓ JWT only"
|
|
529
|
-
:
|
|
724
|
+
: state.authMode === "auth"
|
|
530
725
|
? "✓ Email + Password"
|
|
531
726
|
: "✓ Password + OAuth (Google/GitHub)"}
|
|
532
727
|
|
|
533
728
|
🛠 Stack:
|
|
534
729
|
✔ Express
|
|
535
|
-
✔ ${
|
|
536
|
-
✔ ${
|
|
730
|
+
✔ ${state.usePrisma ? (state.database === "postgresql" ? "PostgreSQL" : "SQLite") : "No database"}
|
|
731
|
+
✔ ${state.usePrisma ? "Prisma ORM" : "No ORM"}
|
|
537
732
|
|
|
538
733
|
📡 API Routes:
|
|
539
|
-
${
|
|
734
|
+
${state.authMode === "base"
|
|
540
735
|
? `
|
|
541
736
|
GET /public
|
|
542
737
|
GET /guest
|
|
543
738
|
GET /protected
|
|
544
739
|
POST /refresh
|
|
545
740
|
`
|
|
546
|
-
:
|
|
741
|
+
: state.authMode === "auth"
|
|
547
742
|
? `
|
|
548
|
-
POST /auth/register
|
|
743
|
+
POST /auth/register
|
|
549
744
|
POST /auth/login
|
|
550
745
|
POST /auth/refresh
|
|
551
746
|
GET /protected
|
|
@@ -573,26 +768,29 @@ Run:
|
|
|
573
768
|
npm run pm2:start
|
|
574
769
|
`);
|
|
575
770
|
}
|
|
771
|
+
saveState({ step: "done", ...(state.authMode !== "base" && { hashLib: selectedHash }),
|
|
772
|
+
});
|
|
773
|
+
clearState();
|
|
576
774
|
}
|
|
577
775
|
catch (err) {
|
|
578
|
-
|
|
579
|
-
|
|
776
|
+
if (err instanceof ExitPromptError) {
|
|
777
|
+
throw err;
|
|
778
|
+
console.error("Fatal error", err);
|
|
779
|
+
process.exit(1);
|
|
780
|
+
}
|
|
580
781
|
}
|
|
581
782
|
}
|
|
582
|
-
process.on("SIGINT", () => {
|
|
583
|
-
console.log("\n👋 Cancelled.");
|
|
584
|
-
process.exit(0);
|
|
585
|
-
});
|
|
586
783
|
main().catch(async (err) => {
|
|
587
784
|
if (err instanceof ExitPromptError) {
|
|
588
|
-
console.log("\n👋 Authenik8 setup cancelled.");
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
785
|
+
console.log("\n👋 Authenik8 setup cancelled.You can --resume later");
|
|
786
|
+
killAllProcesses();
|
|
787
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
788
|
+
console.log(chalk.bgYellow.black(" SETUP CANCELLED "));
|
|
789
|
+
await cleanupIncompleteProject();
|
|
593
790
|
process.exit(0);
|
|
594
791
|
}
|
|
595
|
-
console.error("❌ Unexpected error:", err);
|
|
792
|
+
console.error(chalk.red("\n❌ Unexpected error:"), err);
|
|
793
|
+
await cleanupIncompleteProject();
|
|
596
794
|
process.exit(1);
|
|
597
795
|
});
|
|
598
796
|
//# sourceMappingURL=index.js.map
|