@alinsafawi/aegis-auth 0.2.2 → 0.2.4
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 +594 -211
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2126,20 +2126,20 @@ var require_range = __commonJS({
|
|
|
2126
2126
|
};
|
|
2127
2127
|
var replaceTilde = (comp, options) => {
|
|
2128
2128
|
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
|
|
2129
|
-
return comp.replace(r, (_, M, m,
|
|
2130
|
-
debug("tilde", comp, _, M, m,
|
|
2129
|
+
return comp.replace(r, (_, M, m, p9, pr) => {
|
|
2130
|
+
debug("tilde", comp, _, M, m, p9, pr);
|
|
2131
2131
|
let ret;
|
|
2132
2132
|
if (isX(M)) {
|
|
2133
2133
|
ret = "";
|
|
2134
2134
|
} else if (isX(m)) {
|
|
2135
2135
|
ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
|
|
2136
|
-
} else if (isX(
|
|
2136
|
+
} else if (isX(p9)) {
|
|
2137
2137
|
ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
|
|
2138
2138
|
} else if (pr) {
|
|
2139
2139
|
debug("replaceTilde pr", pr);
|
|
2140
|
-
ret = `>=${M}.${m}.${
|
|
2140
|
+
ret = `>=${M}.${m}.${p9}-${pr} <${M}.${+m + 1}.0-0`;
|
|
2141
2141
|
} else {
|
|
2142
|
-
ret = `>=${M}.${m}.${
|
|
2142
|
+
ret = `>=${M}.${m}.${p9} <${M}.${+m + 1}.0-0`;
|
|
2143
2143
|
}
|
|
2144
2144
|
debug("tilde return", ret);
|
|
2145
2145
|
return ret;
|
|
@@ -2152,14 +2152,14 @@ var require_range = __commonJS({
|
|
|
2152
2152
|
debug("caret", comp, options);
|
|
2153
2153
|
const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
|
|
2154
2154
|
const z3 = options.includePrerelease ? "-0" : "";
|
|
2155
|
-
return comp.replace(r, (_, M, m,
|
|
2156
|
-
debug("caret", comp, _, M, m,
|
|
2155
|
+
return comp.replace(r, (_, M, m, p9, pr) => {
|
|
2156
|
+
debug("caret", comp, _, M, m, p9, pr);
|
|
2157
2157
|
let ret;
|
|
2158
2158
|
if (isX(M)) {
|
|
2159
2159
|
ret = "";
|
|
2160
2160
|
} else if (isX(m)) {
|
|
2161
2161
|
ret = `>=${M}.0.0${z3} <${+M + 1}.0.0-0`;
|
|
2162
|
-
} else if (isX(
|
|
2162
|
+
} else if (isX(p9)) {
|
|
2163
2163
|
if (M === "0") {
|
|
2164
2164
|
ret = `>=${M}.${m}.0${z3} <${M}.${+m + 1}.0-0`;
|
|
2165
2165
|
} else {
|
|
@@ -2169,23 +2169,23 @@ var require_range = __commonJS({
|
|
|
2169
2169
|
debug("replaceCaret pr", pr);
|
|
2170
2170
|
if (M === "0") {
|
|
2171
2171
|
if (m === "0") {
|
|
2172
|
-
ret = `>=${M}.${m}.${
|
|
2172
|
+
ret = `>=${M}.${m}.${p9}-${pr} <${M}.${m}.${+p9 + 1}-0`;
|
|
2173
2173
|
} else {
|
|
2174
|
-
ret = `>=${M}.${m}.${
|
|
2174
|
+
ret = `>=${M}.${m}.${p9}-${pr} <${M}.${+m + 1}.0-0`;
|
|
2175
2175
|
}
|
|
2176
2176
|
} else {
|
|
2177
|
-
ret = `>=${M}.${m}.${
|
|
2177
|
+
ret = `>=${M}.${m}.${p9}-${pr} <${+M + 1}.0.0-0`;
|
|
2178
2178
|
}
|
|
2179
2179
|
} else {
|
|
2180
2180
|
debug("no pr");
|
|
2181
2181
|
if (M === "0") {
|
|
2182
2182
|
if (m === "0") {
|
|
2183
|
-
ret = `>=${M}.${m}.${
|
|
2183
|
+
ret = `>=${M}.${m}.${p9}${z3} <${M}.${m}.${+p9 + 1}-0`;
|
|
2184
2184
|
} else {
|
|
2185
|
-
ret = `>=${M}.${m}.${
|
|
2185
|
+
ret = `>=${M}.${m}.${p9}${z3} <${M}.${+m + 1}.0-0`;
|
|
2186
2186
|
}
|
|
2187
2187
|
} else {
|
|
2188
|
-
ret = `>=${M}.${m}.${
|
|
2188
|
+
ret = `>=${M}.${m}.${p9} <${+M + 1}.0.0-0`;
|
|
2189
2189
|
}
|
|
2190
2190
|
}
|
|
2191
2191
|
debug("caret return", ret);
|
|
@@ -2199,11 +2199,11 @@ var require_range = __commonJS({
|
|
|
2199
2199
|
var replaceXRange = (comp, options) => {
|
|
2200
2200
|
comp = comp.trim();
|
|
2201
2201
|
const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
|
|
2202
|
-
return comp.replace(r, (ret, gtlt, M, m,
|
|
2203
|
-
debug("xRange", comp, ret, gtlt, M, m,
|
|
2202
|
+
return comp.replace(r, (ret, gtlt, M, m, p9, pr) => {
|
|
2203
|
+
debug("xRange", comp, ret, gtlt, M, m, p9, pr);
|
|
2204
2204
|
const xM = isX(M);
|
|
2205
2205
|
const xm = xM || isX(m);
|
|
2206
|
-
const xp = xm || isX(
|
|
2206
|
+
const xp = xm || isX(p9);
|
|
2207
2207
|
const anyX = xp;
|
|
2208
2208
|
if (gtlt === "=" && anyX) {
|
|
2209
2209
|
gtlt = "";
|
|
@@ -2219,16 +2219,16 @@ var require_range = __commonJS({
|
|
|
2219
2219
|
if (xm) {
|
|
2220
2220
|
m = 0;
|
|
2221
2221
|
}
|
|
2222
|
-
|
|
2222
|
+
p9 = 0;
|
|
2223
2223
|
if (gtlt === ">") {
|
|
2224
2224
|
gtlt = ">=";
|
|
2225
2225
|
if (xm) {
|
|
2226
2226
|
M = +M + 1;
|
|
2227
2227
|
m = 0;
|
|
2228
|
-
|
|
2228
|
+
p9 = 0;
|
|
2229
2229
|
} else {
|
|
2230
2230
|
m = +m + 1;
|
|
2231
|
-
|
|
2231
|
+
p9 = 0;
|
|
2232
2232
|
}
|
|
2233
2233
|
} else if (gtlt === "<=") {
|
|
2234
2234
|
gtlt = "<";
|
|
@@ -2241,7 +2241,7 @@ var require_range = __commonJS({
|
|
|
2241
2241
|
if (gtlt === "<") {
|
|
2242
2242
|
pr = "-0";
|
|
2243
2243
|
}
|
|
2244
|
-
ret = `${gtlt + M}.${m}.${
|
|
2244
|
+
ret = `${gtlt + M}.${m}.${p9}${pr}`;
|
|
2245
2245
|
} else if (xm) {
|
|
2246
2246
|
ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`;
|
|
2247
2247
|
} else if (xp) {
|
|
@@ -6919,14 +6919,14 @@ var require_mask_pattern = __commonJS({
|
|
|
6919
6919
|
const numPatterns = Object.keys(exports2.Patterns).length;
|
|
6920
6920
|
let bestPattern = 0;
|
|
6921
6921
|
let lowerPenalty = Infinity;
|
|
6922
|
-
for (let
|
|
6923
|
-
setupFormatFunc(
|
|
6924
|
-
exports2.applyMask(
|
|
6922
|
+
for (let p9 = 0; p9 < numPatterns; p9++) {
|
|
6923
|
+
setupFormatFunc(p9);
|
|
6924
|
+
exports2.applyMask(p9, data);
|
|
6925
6925
|
const penalty = exports2.getPenaltyN1(data) + exports2.getPenaltyN2(data) + exports2.getPenaltyN3(data) + exports2.getPenaltyN4(data);
|
|
6926
|
-
exports2.applyMask(
|
|
6926
|
+
exports2.applyMask(p9, data);
|
|
6927
6927
|
if (penalty < lowerPenalty) {
|
|
6928
6928
|
lowerPenalty = penalty;
|
|
6929
|
-
bestPattern =
|
|
6929
|
+
bestPattern = p9;
|
|
6930
6930
|
}
|
|
6931
6931
|
}
|
|
6932
6932
|
return bestPattern;
|
|
@@ -10909,7 +10909,7 @@ var require_browser = __commonJS({
|
|
|
10909
10909
|
var QRCode2 = require_qrcode();
|
|
10910
10910
|
var CanvasRenderer = require_canvas();
|
|
10911
10911
|
var SvgRenderer = require_svg_tag();
|
|
10912
|
-
function renderCanvas(renderFunc, canvas,
|
|
10912
|
+
function renderCanvas(renderFunc, canvas, text7, opts, cb) {
|
|
10913
10913
|
const args2 = [].slice.call(arguments, 1);
|
|
10914
10914
|
const argsNum = args2.length;
|
|
10915
10915
|
const isLastArgCb = typeof args2[argsNum - 1] === "function";
|
|
@@ -10921,8 +10921,8 @@ var require_browser = __commonJS({
|
|
|
10921
10921
|
throw new Error("Too few arguments provided");
|
|
10922
10922
|
}
|
|
10923
10923
|
if (argsNum === 2) {
|
|
10924
|
-
cb =
|
|
10925
|
-
|
|
10924
|
+
cb = text7;
|
|
10925
|
+
text7 = canvas;
|
|
10926
10926
|
canvas = opts = void 0;
|
|
10927
10927
|
} else if (argsNum === 3) {
|
|
10928
10928
|
if (canvas.getContext && typeof cb === "undefined") {
|
|
@@ -10930,8 +10930,8 @@ var require_browser = __commonJS({
|
|
|
10930
10930
|
opts = void 0;
|
|
10931
10931
|
} else {
|
|
10932
10932
|
cb = opts;
|
|
10933
|
-
opts =
|
|
10934
|
-
|
|
10933
|
+
opts = text7;
|
|
10934
|
+
text7 = canvas;
|
|
10935
10935
|
canvas = void 0;
|
|
10936
10936
|
}
|
|
10937
10937
|
}
|
|
@@ -10940,16 +10940,16 @@ var require_browser = __commonJS({
|
|
|
10940
10940
|
throw new Error("Too few arguments provided");
|
|
10941
10941
|
}
|
|
10942
10942
|
if (argsNum === 1) {
|
|
10943
|
-
|
|
10943
|
+
text7 = canvas;
|
|
10944
10944
|
canvas = opts = void 0;
|
|
10945
10945
|
} else if (argsNum === 2 && !canvas.getContext) {
|
|
10946
|
-
opts =
|
|
10947
|
-
|
|
10946
|
+
opts = text7;
|
|
10947
|
+
text7 = canvas;
|
|
10948
10948
|
canvas = void 0;
|
|
10949
10949
|
}
|
|
10950
10950
|
return new Promise(function(resolve, reject) {
|
|
10951
10951
|
try {
|
|
10952
|
-
const data = QRCode2.create(
|
|
10952
|
+
const data = QRCode2.create(text7, opts);
|
|
10953
10953
|
resolve(renderFunc(data, canvas, opts));
|
|
10954
10954
|
} catch (e) {
|
|
10955
10955
|
reject(e);
|
|
@@ -10957,7 +10957,7 @@ var require_browser = __commonJS({
|
|
|
10957
10957
|
});
|
|
10958
10958
|
}
|
|
10959
10959
|
try {
|
|
10960
|
-
const data = QRCode2.create(
|
|
10960
|
+
const data = QRCode2.create(text7, opts);
|
|
10961
10961
|
cb(null, renderFunc(data, canvas, opts));
|
|
10962
10962
|
} catch (e) {
|
|
10963
10963
|
cb(e);
|
|
@@ -10982,8 +10982,8 @@ var require_server = __commonJS({
|
|
|
10982
10982
|
var Utf8Renderer = require_utf8();
|
|
10983
10983
|
var TerminalRenderer = require_terminal2();
|
|
10984
10984
|
var SvgRenderer = require_svg();
|
|
10985
|
-
function checkParams(
|
|
10986
|
-
if (typeof
|
|
10985
|
+
function checkParams(text7, opts, cb) {
|
|
10986
|
+
if (typeof text7 === "undefined") {
|
|
10987
10987
|
throw new Error("String required as first argument");
|
|
10988
10988
|
}
|
|
10989
10989
|
if (typeof cb === "undefined") {
|
|
@@ -11030,11 +11030,11 @@ var require_server = __commonJS({
|
|
|
11030
11030
|
return Utf8Renderer;
|
|
11031
11031
|
}
|
|
11032
11032
|
}
|
|
11033
|
-
function render(renderFunc,
|
|
11033
|
+
function render(renderFunc, text7, params) {
|
|
11034
11034
|
if (!params.cb) {
|
|
11035
11035
|
return new Promise(function(resolve, reject) {
|
|
11036
11036
|
try {
|
|
11037
|
-
const data = QRCode2.create(
|
|
11037
|
+
const data = QRCode2.create(text7, params.opts);
|
|
11038
11038
|
return renderFunc(data, params.opts, function(err, data2) {
|
|
11039
11039
|
return err ? reject(err) : resolve(data2);
|
|
11040
11040
|
});
|
|
@@ -11044,7 +11044,7 @@ var require_server = __commonJS({
|
|
|
11044
11044
|
});
|
|
11045
11045
|
}
|
|
11046
11046
|
try {
|
|
11047
|
-
const data = QRCode2.create(
|
|
11047
|
+
const data = QRCode2.create(text7, params.opts);
|
|
11048
11048
|
return renderFunc(data, params.opts, params.cb);
|
|
11049
11049
|
} catch (e) {
|
|
11050
11050
|
params.cb(e);
|
|
@@ -11052,43 +11052,43 @@ var require_server = __commonJS({
|
|
|
11052
11052
|
}
|
|
11053
11053
|
exports2.create = QRCode2.create;
|
|
11054
11054
|
exports2.toCanvas = require_browser().toCanvas;
|
|
11055
|
-
exports2.toString = function toString(
|
|
11056
|
-
const params = checkParams(
|
|
11055
|
+
exports2.toString = function toString(text7, opts, cb) {
|
|
11056
|
+
const params = checkParams(text7, opts, cb);
|
|
11057
11057
|
const type = params.opts ? params.opts.type : void 0;
|
|
11058
11058
|
const renderer = getStringRendererFromType(type);
|
|
11059
|
-
return render(renderer.render,
|
|
11059
|
+
return render(renderer.render, text7, params);
|
|
11060
11060
|
};
|
|
11061
|
-
exports2.toDataURL = function toDataURL(
|
|
11062
|
-
const params = checkParams(
|
|
11061
|
+
exports2.toDataURL = function toDataURL(text7, opts, cb) {
|
|
11062
|
+
const params = checkParams(text7, opts, cb);
|
|
11063
11063
|
const renderer = getRendererFromType(params.opts.type);
|
|
11064
|
-
return render(renderer.renderToDataURL,
|
|
11064
|
+
return render(renderer.renderToDataURL, text7, params);
|
|
11065
11065
|
};
|
|
11066
|
-
exports2.toBuffer = function toBuffer(
|
|
11067
|
-
const params = checkParams(
|
|
11066
|
+
exports2.toBuffer = function toBuffer(text7, opts, cb) {
|
|
11067
|
+
const params = checkParams(text7, opts, cb);
|
|
11068
11068
|
const renderer = getRendererFromType(params.opts.type);
|
|
11069
|
-
return render(renderer.renderToBuffer,
|
|
11069
|
+
return render(renderer.renderToBuffer, text7, params);
|
|
11070
11070
|
};
|
|
11071
|
-
exports2.toFile = function toFile(path6,
|
|
11072
|
-
if (typeof path6 !== "string" || !(typeof
|
|
11071
|
+
exports2.toFile = function toFile(path6, text7, opts, cb) {
|
|
11072
|
+
if (typeof path6 !== "string" || !(typeof text7 === "string" || typeof text7 === "object")) {
|
|
11073
11073
|
throw new Error("Invalid argument");
|
|
11074
11074
|
}
|
|
11075
11075
|
if (arguments.length < 3 && !canPromise()) {
|
|
11076
11076
|
throw new Error("Too few arguments provided");
|
|
11077
11077
|
}
|
|
11078
|
-
const params = checkParams(
|
|
11078
|
+
const params = checkParams(text7, opts, cb);
|
|
11079
11079
|
const type = params.opts.type || getTypeFromFilename(path6);
|
|
11080
11080
|
const renderer = getRendererFromType(type);
|
|
11081
11081
|
const renderToFile = renderer.renderToFile.bind(null, path6);
|
|
11082
|
-
return render(renderToFile,
|
|
11082
|
+
return render(renderToFile, text7, params);
|
|
11083
11083
|
};
|
|
11084
|
-
exports2.toFileStream = function toFileStream(stream,
|
|
11084
|
+
exports2.toFileStream = function toFileStream(stream, text7, opts) {
|
|
11085
11085
|
if (arguments.length < 2) {
|
|
11086
11086
|
throw new Error("Too few arguments provided");
|
|
11087
11087
|
}
|
|
11088
|
-
const params = checkParams(
|
|
11088
|
+
const params = checkParams(text7, opts, stream.emit.bind(stream, "error"));
|
|
11089
11089
|
const renderer = getRendererFromType("png");
|
|
11090
11090
|
const renderToFileStream = renderer.renderToFileStream.bind(null, stream);
|
|
11091
|
-
render(renderToFileStream,
|
|
11091
|
+
render(renderToFileStream, text7, params);
|
|
11092
11092
|
};
|
|
11093
11093
|
}
|
|
11094
11094
|
});
|
|
@@ -16697,16 +16697,16 @@ var require_mail_composer = __commonJS({
|
|
|
16697
16697
|
* @returns {Array} An array of alternative elements. Includes the `text` and `html` values as well
|
|
16698
16698
|
*/
|
|
16699
16699
|
getAlternatives() {
|
|
16700
|
-
let alternatives = [],
|
|
16700
|
+
let alternatives = [], text7, html, watchHtml, amp, icalEvent, eventObject;
|
|
16701
16701
|
if (this.mail.text) {
|
|
16702
16702
|
if (typeof this.mail.text === "object" && (this.mail.text.content || this.mail.text.path || this.mail.text.href || this.mail.text.raw)) {
|
|
16703
|
-
|
|
16703
|
+
text7 = this.mail.text;
|
|
16704
16704
|
} else {
|
|
16705
|
-
|
|
16705
|
+
text7 = {
|
|
16706
16706
|
content: this.mail.text
|
|
16707
16707
|
};
|
|
16708
16708
|
}
|
|
16709
|
-
|
|
16709
|
+
text7.contentType = "text/plain; charset=utf-8";
|
|
16710
16710
|
}
|
|
16711
16711
|
if (this.mail.watchHtml) {
|
|
16712
16712
|
if (typeof this.mail.watchHtml === "object" && (this.mail.watchHtml.content || this.mail.watchHtml.path || this.mail.watchHtml.href || this.mail.watchHtml.raw)) {
|
|
@@ -16759,7 +16759,7 @@ var require_mail_composer = __commonJS({
|
|
|
16759
16759
|
}
|
|
16760
16760
|
html.contentType = "text/html; charset=utf-8";
|
|
16761
16761
|
}
|
|
16762
|
-
[].concat(
|
|
16762
|
+
[].concat(text7 || []).concat(watchHtml || []).concat(amp || []).concat(html || []).concat(eventObject || []).concat(this.mail.alternatives || []).forEach((alternative) => {
|
|
16763
16763
|
let data;
|
|
16764
16764
|
if (/^data:/i.test(alternative.path || alternative.href)) {
|
|
16765
16765
|
alternative = this._processDataUrl(alternative);
|
|
@@ -22296,8 +22296,8 @@ var require_nodemailer = __commonJS({
|
|
|
22296
22296
|
});
|
|
22297
22297
|
|
|
22298
22298
|
// src/commands/init.ts
|
|
22299
|
-
var
|
|
22300
|
-
var
|
|
22299
|
+
var p6 = __toESM(require("@clack/prompts"));
|
|
22300
|
+
var import_chalk7 = __toESM(require("chalk"));
|
|
22301
22301
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
22302
22302
|
var import_path = __toESM(require("path"));
|
|
22303
22303
|
var import_execa = require("execa");
|
|
@@ -22933,41 +22933,6 @@ async function promptInfrastructure() {
|
|
|
22933
22933
|
};
|
|
22934
22934
|
}
|
|
22935
22935
|
|
|
22936
|
-
// src/prompts/style.ts
|
|
22937
|
-
var p6 = __toESM(require("@clack/prompts"));
|
|
22938
|
-
var import_chalk7 = __toESM(require("chalk"));
|
|
22939
|
-
async function promptStyle() {
|
|
22940
|
-
console.log(
|
|
22941
|
-
`
|
|
22942
|
-
${import_chalk7.default.dim("Used on buttons, links, and focus rings in all scaffolded pages.")}
|
|
22943
|
-
${import_chalk7.default.dim("This becomes a CSS variable \u2014 change it any time in globals.css.")}
|
|
22944
|
-
`
|
|
22945
|
-
);
|
|
22946
|
-
const primaryColor = await p6.text({
|
|
22947
|
-
message: "Primary color",
|
|
22948
|
-
initialValue: "oklch(0.6 0.2 240)",
|
|
22949
|
-
validate: (v) => !v ? "Required" : void 0
|
|
22950
|
-
});
|
|
22951
|
-
if (p6.isCancel(primaryColor)) process.exit(0);
|
|
22952
|
-
console.log(
|
|
22953
|
-
`
|
|
22954
|
-
${import_chalk7.default.dim("Accepts any CSS color:")}
|
|
22955
|
-
${import_chalk7.default.dim(" #3b82f6 (hex)")}
|
|
22956
|
-
${import_chalk7.default.dim(" hsl(220 90% 56%) (HSL)")}
|
|
22957
|
-
${import_chalk7.default.dim(" oklch(0.6 0.2 240) (recommended \u2014 perceptually uniform)")}
|
|
22958
|
-
`
|
|
22959
|
-
);
|
|
22960
|
-
const logoUrl = await p6.text({
|
|
22961
|
-
message: "Logo path (optional \u2014 leave blank to skip)",
|
|
22962
|
-
placeholder: "/logo.svg"
|
|
22963
|
-
});
|
|
22964
|
-
if (p6.isCancel(logoUrl)) process.exit(0);
|
|
22965
|
-
return {
|
|
22966
|
-
primaryColor,
|
|
22967
|
-
logoUrl: logoUrl || void 0
|
|
22968
|
-
};
|
|
22969
|
-
}
|
|
22970
|
-
|
|
22971
22936
|
// ../core/dist/index.js
|
|
22972
22937
|
var import_zod = require("zod");
|
|
22973
22938
|
var import_jsonwebtoken = __toESM(require_jsonwebtoken(), 1);
|
|
@@ -23342,8 +23307,8 @@ function serializePermissions(role) {
|
|
|
23342
23307
|
if (mode === "none") return `'none'`;
|
|
23343
23308
|
if (mode === "dynamic") return `'dynamic'`;
|
|
23344
23309
|
const perms = typeof role.permissions === "object" ? role.permissions : {};
|
|
23345
|
-
const lines = Object.entries(perms).map(([key,
|
|
23346
|
-
const def =
|
|
23310
|
+
const lines = Object.entries(perms).map(([key, p9]) => {
|
|
23311
|
+
const def = p9;
|
|
23347
23312
|
return [
|
|
23348
23313
|
` ${key}: {`,
|
|
23349
23314
|
` label: '${def.label}',`,
|
|
@@ -23782,8 +23747,406 @@ function generatePackageJson(name, packageManager) {
|
|
|
23782
23747
|
2
|
|
23783
23748
|
);
|
|
23784
23749
|
}
|
|
23750
|
+
function generatePrismaLib() {
|
|
23751
|
+
return `import { PrismaClient } from '@prisma/client'
|
|
23752
|
+
|
|
23753
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
|
|
23754
|
+
|
|
23755
|
+
export const prisma = globalForPrisma.prisma ?? new PrismaClient()
|
|
23756
|
+
|
|
23757
|
+
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
|
23758
|
+
`;
|
|
23759
|
+
}
|
|
23760
|
+
function generateLoginRoute() {
|
|
23761
|
+
return `import { createLoginHandler } from '@alinsafawi/aegis-auth-next'
|
|
23762
|
+
import { prisma } from '@/lib/prisma'
|
|
23763
|
+
import config from '../../../../../auth.config'
|
|
23764
|
+
|
|
23765
|
+
export const POST = createLoginHandler(config, prisma)
|
|
23766
|
+
`;
|
|
23767
|
+
}
|
|
23768
|
+
function generateLogoutRoute() {
|
|
23769
|
+
return `import { createLogoutHandler } from '@alinsafawi/aegis-auth-next'
|
|
23770
|
+
import config from '../../../../../auth.config'
|
|
23771
|
+
|
|
23772
|
+
export const POST = createLogoutHandler(config)
|
|
23773
|
+
`;
|
|
23774
|
+
}
|
|
23775
|
+
function generateTwoFactorRoute() {
|
|
23776
|
+
return `import { createTwoFactorHandler } from '@alinsafawi/aegis-auth-next'
|
|
23777
|
+
import { prisma } from '@/lib/prisma'
|
|
23778
|
+
import config from '../../../../../auth.config'
|
|
23779
|
+
|
|
23780
|
+
export const POST = createTwoFactorHandler(config, prisma)
|
|
23781
|
+
`;
|
|
23782
|
+
}
|
|
23783
|
+
function generateChangePasswordRoute() {
|
|
23784
|
+
return `import { createChangePasswordHandler } from '@alinsafawi/aegis-auth-next'
|
|
23785
|
+
import { prisma } from '@/lib/prisma'
|
|
23786
|
+
import config from '../../../../../auth.config'
|
|
23787
|
+
|
|
23788
|
+
export const POST = createChangePasswordHandler(config, prisma)
|
|
23789
|
+
`;
|
|
23790
|
+
}
|
|
23791
|
+
function generateForgotPasswordPage(language) {
|
|
23792
|
+
const ts = language === "typescript";
|
|
23793
|
+
return `'use client'
|
|
23794
|
+
|
|
23795
|
+
import { useState } from 'react'
|
|
23796
|
+
|
|
23797
|
+
export default function ForgotPasswordPage() {
|
|
23798
|
+
const [email, setEmail] = useState('')
|
|
23799
|
+
const [sent, setSent] = useState(false)
|
|
23800
|
+
const [error, setError] = useState('')
|
|
23801
|
+
const [loading, setLoading] = useState(false)
|
|
23802
|
+
|
|
23803
|
+
async function handleSubmit(e${ts ? ": React.FormEvent" : ""}) {
|
|
23804
|
+
e.preventDefault()
|
|
23805
|
+
setLoading(true)
|
|
23806
|
+
setError('')
|
|
23807
|
+
const res = await fetch('/api/auth/forgot-password', {
|
|
23808
|
+
method: 'POST',
|
|
23809
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23810
|
+
body: JSON.stringify({ email }),
|
|
23811
|
+
})
|
|
23812
|
+
setLoading(false)
|
|
23813
|
+
if (!res.ok) { setError((await res.json()).error ?? 'Something went wrong'); return }
|
|
23814
|
+
setSent(true)
|
|
23815
|
+
}
|
|
23816
|
+
|
|
23817
|
+
if (sent) {
|
|
23818
|
+
return (
|
|
23819
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
23820
|
+
<div className="w-full max-w-sm text-center space-y-3">
|
|
23821
|
+
<h1 className="text-2xl font-bold">Check your email</h1>
|
|
23822
|
+
<p className="text-[var(--muted)] text-sm">
|
|
23823
|
+
If an account exists for <strong>{email}</strong>, a reset link has been sent.
|
|
23824
|
+
</p>
|
|
23825
|
+
<a href="/login" className="block text-sm text-[var(--muted)] hover:underline mt-4">
|
|
23826
|
+
Back to login
|
|
23827
|
+
</a>
|
|
23828
|
+
</div>
|
|
23829
|
+
</main>
|
|
23830
|
+
)
|
|
23831
|
+
}
|
|
23832
|
+
|
|
23833
|
+
return (
|
|
23834
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
23835
|
+
<div className="w-full max-w-sm">
|
|
23836
|
+
<div className="text-center mb-8">
|
|
23837
|
+
<h1 className="text-2xl font-bold">Forgot password</h1>
|
|
23838
|
+
<p className="text-[var(--muted)] text-sm mt-1">We'll send you a reset link.</p>
|
|
23839
|
+
</div>
|
|
23840
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
23841
|
+
{error && <div className="text-sm text-red-500 bg-red-50 border border-red-200 rounded-md p-3">{error}</div>}
|
|
23842
|
+
<div>
|
|
23843
|
+
<label className="block text-sm font-medium mb-1">Email address</label>
|
|
23844
|
+
<input
|
|
23845
|
+
type="email"
|
|
23846
|
+
value={email}
|
|
23847
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
23848
|
+
required
|
|
23849
|
+
autoComplete="email"
|
|
23850
|
+
className="w-full px-3 py-2 rounded-md border bg-[var(--input)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)]"
|
|
23851
|
+
/>
|
|
23852
|
+
</div>
|
|
23853
|
+
<button
|
|
23854
|
+
type="submit"
|
|
23855
|
+
disabled={loading}
|
|
23856
|
+
style={{ background: 'var(--primary)', color: 'var(--primary-foreground)' }}
|
|
23857
|
+
className="w-full py-2 px-4 rounded-md font-medium disabled:opacity-50 transition-opacity"
|
|
23858
|
+
>
|
|
23859
|
+
{loading ? 'Sending\u2026' : 'Send reset link'}
|
|
23860
|
+
</button>
|
|
23861
|
+
<div className="text-center">
|
|
23862
|
+
<a href="/login" className="text-sm text-[var(--muted)] hover:underline">Back to login</a>
|
|
23863
|
+
</div>
|
|
23864
|
+
</form>
|
|
23865
|
+
</div>
|
|
23866
|
+
</main>
|
|
23867
|
+
)
|
|
23868
|
+
}
|
|
23869
|
+
`;
|
|
23870
|
+
}
|
|
23871
|
+
function generateResetPasswordPage(language) {
|
|
23872
|
+
const ts = language === "typescript";
|
|
23873
|
+
return `'use client'
|
|
23874
|
+
|
|
23875
|
+
import { useState } from 'react'
|
|
23876
|
+
import { useSearchParams, useRouter } from 'next/navigation'
|
|
23877
|
+
|
|
23878
|
+
export default function ResetPasswordPage() {
|
|
23879
|
+
const params = useSearchParams()
|
|
23880
|
+
const router = useRouter()
|
|
23881
|
+
const token = params.get('token') ?? ''
|
|
23882
|
+
const [password, setPassword] = useState('')
|
|
23883
|
+
const [confirm, setConfirm] = useState('')
|
|
23884
|
+
const [error, setError] = useState('')
|
|
23885
|
+
const [loading, setLoading] = useState(false)
|
|
23886
|
+
|
|
23887
|
+
async function handleSubmit(e${ts ? ": React.FormEvent" : ""}) {
|
|
23888
|
+
e.preventDefault()
|
|
23889
|
+
if (password !== confirm) { setError('Passwords do not match'); return }
|
|
23890
|
+
setLoading(true)
|
|
23891
|
+
setError('')
|
|
23892
|
+
const res = await fetch('/api/auth/reset-password', {
|
|
23893
|
+
method: 'POST',
|
|
23894
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23895
|
+
body: JSON.stringify({ token, newPassword: password }),
|
|
23896
|
+
})
|
|
23897
|
+
setLoading(false)
|
|
23898
|
+
if (!res.ok) { setError((await res.json()).error ?? 'Something went wrong'); return }
|
|
23899
|
+
router.push('/login?reset=1')
|
|
23900
|
+
}
|
|
23901
|
+
|
|
23902
|
+
return (
|
|
23903
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
23904
|
+
<div className="w-full max-w-sm">
|
|
23905
|
+
<div className="text-center mb-8">
|
|
23906
|
+
<h1 className="text-2xl font-bold">Reset password</h1>
|
|
23907
|
+
</div>
|
|
23908
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
23909
|
+
{error && <div className="text-sm text-red-500 bg-red-50 border border-red-200 rounded-md p-3">{error}</div>}
|
|
23910
|
+
<div>
|
|
23911
|
+
<label className="block text-sm font-medium mb-1">New password</label>
|
|
23912
|
+
<input
|
|
23913
|
+
type="password"
|
|
23914
|
+
value={password}
|
|
23915
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
23916
|
+
required
|
|
23917
|
+
autoComplete="new-password"
|
|
23918
|
+
className="w-full px-3 py-2 rounded-md border bg-[var(--input)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)]"
|
|
23919
|
+
/>
|
|
23920
|
+
</div>
|
|
23921
|
+
<div>
|
|
23922
|
+
<label className="block text-sm font-medium mb-1">Confirm new password</label>
|
|
23923
|
+
<input
|
|
23924
|
+
type="password"
|
|
23925
|
+
value={confirm}
|
|
23926
|
+
onChange={(e) => setConfirm(e.target.value)}
|
|
23927
|
+
required
|
|
23928
|
+
autoComplete="new-password"
|
|
23929
|
+
className="w-full px-3 py-2 rounded-md border bg-[var(--input)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)]"
|
|
23930
|
+
/>
|
|
23931
|
+
</div>
|
|
23932
|
+
<button
|
|
23933
|
+
type="submit"
|
|
23934
|
+
disabled={loading}
|
|
23935
|
+
style={{ background: 'var(--primary)', color: 'var(--primary-foreground)' }}
|
|
23936
|
+
className="w-full py-2 px-4 rounded-md font-medium disabled:opacity-50 transition-opacity"
|
|
23937
|
+
>
|
|
23938
|
+
{loading ? 'Resetting\u2026' : 'Reset password'}
|
|
23939
|
+
</button>
|
|
23940
|
+
</form>
|
|
23941
|
+
</div>
|
|
23942
|
+
</main>
|
|
23943
|
+
)
|
|
23944
|
+
}
|
|
23945
|
+
`;
|
|
23946
|
+
}
|
|
23947
|
+
function generateTwoFactorPage(language) {
|
|
23948
|
+
const ts = language === "typescript";
|
|
23949
|
+
return `'use client'
|
|
23950
|
+
|
|
23951
|
+
import { useState } from 'react'
|
|
23952
|
+
import { useRouter } from 'next/navigation'
|
|
23953
|
+
|
|
23954
|
+
export default function TwoFactorPage() {
|
|
23955
|
+
const [code, setCode] = useState('')
|
|
23956
|
+
const [error, setError] = useState('')
|
|
23957
|
+
const [loading, setLoading] = useState(false)
|
|
23958
|
+
const router = useRouter()
|
|
23959
|
+
|
|
23960
|
+
async function handleSubmit(e${ts ? ": React.FormEvent" : ""}) {
|
|
23961
|
+
e.preventDefault()
|
|
23962
|
+
setLoading(true)
|
|
23963
|
+
setError('')
|
|
23964
|
+
const res = await fetch('/api/auth/two-factor', {
|
|
23965
|
+
method: 'POST',
|
|
23966
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23967
|
+
body: JSON.stringify({ code }),
|
|
23968
|
+
})
|
|
23969
|
+
const data = await res.json()
|
|
23970
|
+
setLoading(false)
|
|
23971
|
+
if (!res.ok) { setError(data.error ?? 'Invalid code'); return }
|
|
23972
|
+
router.push(\`/\${data.role}/dashboard\`)
|
|
23973
|
+
}
|
|
23974
|
+
|
|
23975
|
+
return (
|
|
23976
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
23977
|
+
<div className="w-full max-w-sm">
|
|
23978
|
+
<div className="text-center mb-8">
|
|
23979
|
+
<h1 className="text-2xl font-bold">Two-factor authentication</h1>
|
|
23980
|
+
<p className="text-[var(--muted)] text-sm mt-1">Enter the 6-digit code from your authenticator app.</p>
|
|
23981
|
+
</div>
|
|
23982
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
23983
|
+
{error && <div className="text-sm text-red-500 bg-red-50 border border-red-200 rounded-md p-3">{error}</div>}
|
|
23984
|
+
<div>
|
|
23985
|
+
<label className="block text-sm font-medium mb-1">Authentication code</label>
|
|
23986
|
+
<input
|
|
23987
|
+
type="text"
|
|
23988
|
+
inputMode="numeric"
|
|
23989
|
+
pattern="[0-9]*"
|
|
23990
|
+
maxLength={6}
|
|
23991
|
+
value={code}
|
|
23992
|
+
onChange={(e) => setCode(e.target.value.replace(/D/g, ''))}
|
|
23993
|
+
required
|
|
23994
|
+
autoComplete="one-time-code"
|
|
23995
|
+
placeholder="000000"
|
|
23996
|
+
className="w-full px-3 py-2 rounded-md border bg-[var(--input)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] text-center tracking-widest text-lg"
|
|
23997
|
+
/>
|
|
23998
|
+
</div>
|
|
23999
|
+
<button
|
|
24000
|
+
type="submit"
|
|
24001
|
+
disabled={loading || code.length !== 6}
|
|
24002
|
+
style={{ background: 'var(--primary)', color: 'var(--primary-foreground)' }}
|
|
24003
|
+
className="w-full py-2 px-4 rounded-md font-medium disabled:opacity-50 transition-opacity"
|
|
24004
|
+
>
|
|
24005
|
+
{loading ? 'Verifying\u2026' : 'Verify'}
|
|
24006
|
+
</button>
|
|
24007
|
+
<div className="text-center">
|
|
24008
|
+
<a href="/login" className="text-sm text-[var(--muted)] hover:underline">Back to login</a>
|
|
24009
|
+
</div>
|
|
24010
|
+
</form>
|
|
24011
|
+
</div>
|
|
24012
|
+
</main>
|
|
24013
|
+
)
|
|
24014
|
+
}
|
|
24015
|
+
`;
|
|
24016
|
+
}
|
|
24017
|
+
function generateVerifyEmailNoticePage() {
|
|
24018
|
+
return `export default function VerifyEmailNoticePage() {
|
|
24019
|
+
return (
|
|
24020
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
24021
|
+
<div className="w-full max-w-sm text-center space-y-3">
|
|
24022
|
+
<h1 className="text-2xl font-bold">Verify your email</h1>
|
|
24023
|
+
<p className="text-[var(--muted)] text-sm">
|
|
24024
|
+
We sent a verification code to your email address. Enter it below to activate your account.
|
|
24025
|
+
</p>
|
|
24026
|
+
<a href="/verify-email" className="block mt-4 text-sm underline" style={{ color: 'var(--primary)' }}>
|
|
24027
|
+
Enter verification code \u2192
|
|
24028
|
+
</a>
|
|
24029
|
+
</div>
|
|
24030
|
+
</main>
|
|
24031
|
+
)
|
|
24032
|
+
}
|
|
24033
|
+
`;
|
|
24034
|
+
}
|
|
24035
|
+
function generateVerifyEmailPage(language) {
|
|
24036
|
+
const ts = language === "typescript";
|
|
24037
|
+
return `'use client'
|
|
24038
|
+
|
|
24039
|
+
import { useState } from 'react'
|
|
24040
|
+
import { useRouter } from 'next/navigation'
|
|
24041
|
+
|
|
24042
|
+
export default function VerifyEmailPage() {
|
|
24043
|
+
const [code, setCode] = useState('')
|
|
24044
|
+
const [error, setError] = useState('')
|
|
24045
|
+
const [loading, setLoading] = useState(false)
|
|
24046
|
+
const router = useRouter()
|
|
24047
|
+
|
|
24048
|
+
async function handleSubmit(e${ts ? ": React.FormEvent" : ""}) {
|
|
24049
|
+
e.preventDefault()
|
|
24050
|
+
setLoading(true)
|
|
24051
|
+
setError('')
|
|
24052
|
+
const res = await fetch('/api/auth/verify-email', {
|
|
24053
|
+
method: 'POST',
|
|
24054
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24055
|
+
body: JSON.stringify({ code }),
|
|
24056
|
+
})
|
|
24057
|
+
const data = await res.json()
|
|
24058
|
+
setLoading(false)
|
|
24059
|
+
if (!res.ok) { setError(data.error ?? 'Invalid code'); return }
|
|
24060
|
+
router.push(\`/\${data.role}/dashboard\`)
|
|
24061
|
+
}
|
|
24062
|
+
|
|
24063
|
+
return (
|
|
24064
|
+
<main className="min-h-screen flex items-center justify-center p-4">
|
|
24065
|
+
<div className="w-full max-w-sm">
|
|
24066
|
+
<div className="text-center mb-8">
|
|
24067
|
+
<h1 className="text-2xl font-bold">Enter verification code</h1>
|
|
24068
|
+
<p className="text-[var(--muted)] text-sm mt-1">Check your email for the 6-digit code.</p>
|
|
24069
|
+
</div>
|
|
24070
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
24071
|
+
{error && <div className="text-sm text-red-500 bg-red-50 border border-red-200 rounded-md p-3">{error}</div>}
|
|
24072
|
+
<div>
|
|
24073
|
+
<label className="block text-sm font-medium mb-1">Verification code</label>
|
|
24074
|
+
<input
|
|
24075
|
+
type="text"
|
|
24076
|
+
inputMode="numeric"
|
|
24077
|
+
pattern="[0-9]*"
|
|
24078
|
+
maxLength={6}
|
|
24079
|
+
value={code}
|
|
24080
|
+
onChange={(e) => setCode(e.target.value.replace(/D/g, ''))}
|
|
24081
|
+
required
|
|
24082
|
+
autoComplete="one-time-code"
|
|
24083
|
+
placeholder="000000"
|
|
24084
|
+
className="w-full px-3 py-2 rounded-md border bg-[var(--input)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] text-center tracking-widest text-lg"
|
|
24085
|
+
/>
|
|
24086
|
+
</div>
|
|
24087
|
+
<button
|
|
24088
|
+
type="submit"
|
|
24089
|
+
disabled={loading || code.length !== 6}
|
|
24090
|
+
style={{ background: 'var(--primary)', color: 'var(--primary-foreground)' }}
|
|
24091
|
+
className="w-full py-2 px-4 rounded-md font-medium disabled:opacity-50 transition-opacity"
|
|
24092
|
+
>
|
|
24093
|
+
{loading ? 'Verifying\u2026' : 'Verify email'}
|
|
24094
|
+
</button>
|
|
24095
|
+
<div className="text-center">
|
|
24096
|
+
<a href="/login" className="text-sm text-[var(--muted)] hover:underline">Back to login</a>
|
|
24097
|
+
</div>
|
|
24098
|
+
</form>
|
|
24099
|
+
</div>
|
|
24100
|
+
</main>
|
|
24101
|
+
)
|
|
24102
|
+
}
|
|
24103
|
+
`;
|
|
24104
|
+
}
|
|
24105
|
+
function generateForgotPasswordRoute(language) {
|
|
24106
|
+
const ts = language === "typescript";
|
|
24107
|
+
return `import { NextRequest, NextResponse } from 'next/server'
|
|
24108
|
+
import { prisma } from '@/lib/prisma'
|
|
24109
|
+
import config from '../../../../../auth.config'
|
|
24110
|
+
|
|
24111
|
+
export async function POST(request${ts ? ": NextRequest" : ""}) {
|
|
24112
|
+
// TODO: implement \u2014 find user by email, generate reset token, send email
|
|
24113
|
+
// You can use: import { sendEmail } from '@alinsafawi/aegis-auth-core'
|
|
24114
|
+
const { email } = await request.json()
|
|
24115
|
+
return NextResponse.json({ success: true })
|
|
24116
|
+
}
|
|
24117
|
+
`;
|
|
24118
|
+
}
|
|
24119
|
+
function generateResetPasswordRoute(language) {
|
|
24120
|
+
const ts = language === "typescript";
|
|
24121
|
+
return `import { NextRequest, NextResponse } from 'next/server'
|
|
24122
|
+
import { prisma } from '@/lib/prisma'
|
|
24123
|
+
import { hashPassword } from '@alinsafawi/aegis-auth-core'
|
|
24124
|
+
import config from '../../../../../auth.config'
|
|
24125
|
+
|
|
24126
|
+
export async function POST(request${ts ? ": NextRequest" : ""}) {
|
|
24127
|
+
// TODO: implement \u2014 verify token, update password hash
|
|
24128
|
+
const { token, newPassword } = await request.json()
|
|
24129
|
+
return NextResponse.json({ success: true })
|
|
24130
|
+
}
|
|
24131
|
+
`;
|
|
24132
|
+
}
|
|
24133
|
+
function generateVerifyEmailRoute(language) {
|
|
24134
|
+
const ts = language === "typescript";
|
|
24135
|
+
return `import { NextRequest, NextResponse } from 'next/server'
|
|
24136
|
+
import { prisma } from '@/lib/prisma'
|
|
24137
|
+
import config from '../../../../../auth.config'
|
|
24138
|
+
|
|
24139
|
+
export async function POST(request${ts ? ": NextRequest" : ""}) {
|
|
24140
|
+
// TODO: implement \u2014 verify code, mark emailVerified = true, return role
|
|
24141
|
+
const { code } = await request.json()
|
|
24142
|
+
return NextResponse.json({ success: true, role: 'user' })
|
|
24143
|
+
}
|
|
24144
|
+
`;
|
|
24145
|
+
}
|
|
23785
24146
|
|
|
23786
24147
|
// src/commands/init.ts
|
|
24148
|
+
var DEFAULT_COLOR = "oklch(0.6 0.2 240)";
|
|
24149
|
+
var DEFAULT_STYLE = { primaryColor: DEFAULT_COLOR, logoUrl: void 0 };
|
|
23787
24150
|
function detectPackageManager() {
|
|
23788
24151
|
if (process.env.npm_config_user_agent?.includes("pnpm")) return "pnpm";
|
|
23789
24152
|
if (process.env.npm_config_user_agent?.includes("yarn")) return "yarn";
|
|
@@ -23793,10 +24156,10 @@ function detectPackageManager() {
|
|
|
23793
24156
|
function isExistingNextProject(dir) {
|
|
23794
24157
|
return import_fs_extra.default.existsSync(import_path.default.join(dir, "next.config.ts")) || import_fs_extra.default.existsSync(import_path.default.join(dir, "next.config.js")) || import_fs_extra.default.existsSync(import_path.default.join(dir, "next.config.mjs"));
|
|
23795
24158
|
}
|
|
23796
|
-
var STEPS = ["PROJECT", "APP", "ROLES", "FEATURES", "INFRA"
|
|
24159
|
+
var STEPS = ["PROJECT", "APP", "ROLES", "FEATURES", "INFRA"];
|
|
23797
24160
|
async function runInit() {
|
|
23798
24161
|
printBanner();
|
|
23799
|
-
const mode = await
|
|
24162
|
+
const mode = await p6.select({
|
|
23800
24163
|
message: "What would you like to do?",
|
|
23801
24164
|
options: [
|
|
23802
24165
|
{
|
|
@@ -23811,8 +24174,8 @@ async function runInit() {
|
|
|
23811
24174
|
}
|
|
23812
24175
|
]
|
|
23813
24176
|
});
|
|
23814
|
-
if (
|
|
23815
|
-
|
|
24177
|
+
if (p6.isCancel(mode)) {
|
|
24178
|
+
p6.cancel("Cancelled.");
|
|
23816
24179
|
process.exit(0);
|
|
23817
24180
|
}
|
|
23818
24181
|
let targetDir = process.cwd();
|
|
@@ -23829,12 +24192,12 @@ async function runInit() {
|
|
|
23829
24192
|
database = project.database;
|
|
23830
24193
|
targetDir = import_path.default.join(process.cwd(), project.name);
|
|
23831
24194
|
if (import_fs_extra.default.existsSync(targetDir)) {
|
|
23832
|
-
const overwrite = await
|
|
24195
|
+
const overwrite = await p6.confirm({
|
|
23833
24196
|
message: `Folder '${project.name}' already exists. Continue anyway?`,
|
|
23834
24197
|
initialValue: false
|
|
23835
24198
|
});
|
|
23836
|
-
if (
|
|
23837
|
-
|
|
24199
|
+
if (p6.isCancel(overwrite) || !overwrite) {
|
|
24200
|
+
p6.cancel("Cancelled.");
|
|
23838
24201
|
process.exit(0);
|
|
23839
24202
|
}
|
|
23840
24203
|
}
|
|
@@ -23850,17 +24213,17 @@ async function runInit() {
|
|
|
23850
24213
|
printStatusList(checks);
|
|
23851
24214
|
language = import_fs_extra.default.existsSync(import_path.default.join(targetDir, "tsconfig.json")) ? "typescript" : "javascript";
|
|
23852
24215
|
if (checks.find((c4) => c4.label === "Next.js")?.status === "error") {
|
|
23853
|
-
|
|
24216
|
+
p6.cancel(`No Next.js project found in ${targetDir}. Run from inside your project folder.`);
|
|
23854
24217
|
process.exit(1);
|
|
23855
24218
|
}
|
|
23856
24219
|
console.log(`
|
|
23857
|
-
${
|
|
24220
|
+
${import_chalk7.default.dim("This wizard will:")}
|
|
23858
24221
|
`);
|
|
23859
|
-
console.log(` ${
|
|
23860
|
-
console.log(` ${
|
|
23861
|
-
console.log(` ${
|
|
23862
|
-
console.log(` ${
|
|
23863
|
-
console.log(` ${
|
|
24222
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} Generate Prisma models for your roles`);
|
|
24223
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} Create API route handlers ${import_chalk7.default.dim("src/app/api/auth/**")}`);
|
|
24224
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} Scaffold auth pages ${import_chalk7.default.dim("(login, 2FA, reset password, etc.)")}`);
|
|
24225
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} Create auth.config.ts`);
|
|
24226
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} Update .env.example
|
|
23864
24227
|
`);
|
|
23865
24228
|
}
|
|
23866
24229
|
printSection(mode === "new" ? `STEP 2 of ${STEPS.length} \u25B8 PROJECT \u2713 \u25B8 APP` : `STEP 1 of ${STEPS.length - 1} \u25B8 APP`);
|
|
@@ -23871,31 +24234,29 @@ async function runInit() {
|
|
|
23871
24234
|
let features = await promptFeatures(Object.keys(roles));
|
|
23872
24235
|
printSection(mode === "new" ? `STEP 5 of ${STEPS.length} \u25B8 ... FEATURES \u2713 \u25B8 INFRA` : `STEP 4 \u25B8 FEATURES \u2713 \u25B8 INFRA`);
|
|
23873
24236
|
let infra = await promptInfrastructure();
|
|
23874
|
-
printSection(mode === "new" ? `STEP 6 of ${STEPS.length} \u25B8 ... INFRA \u2713 \u25B8 STYLE` : `STEP 5 \u25B8 INFRA \u2713 \u25B8 STYLE`);
|
|
23875
|
-
let style = await promptStyle();
|
|
23876
24237
|
let isDry = false;
|
|
23877
24238
|
while (true) {
|
|
23878
24239
|
printSection("REVIEW \xB7 Everything that's about to happen");
|
|
23879
|
-
console.log(` ${
|
|
24240
|
+
console.log(` ${import_chalk7.default.bold("Configuration")}
|
|
23880
24241
|
`);
|
|
23881
|
-
console.log(` App ${
|
|
23882
|
-
console.log(` Cookie prefix ${
|
|
23883
|
-
console.log(` Session ${
|
|
24242
|
+
console.log(` App ${import_chalk7.default.cyan(app.appName)}`);
|
|
24243
|
+
console.log(` Cookie prefix ${import_chalk7.default.cyan(app.cookiePrefix)}`);
|
|
24244
|
+
console.log(` Session ${import_chalk7.default.cyan(app.sessionDuration / 3600 + " hours")}`);
|
|
23884
24245
|
if (mode === "new") {
|
|
23885
|
-
console.log(` Language ${
|
|
23886
|
-
console.log(` Package manager ${
|
|
23887
|
-
console.log(` Database ${
|
|
24246
|
+
console.log(` Language ${import_chalk7.default.cyan(language)}`);
|
|
24247
|
+
console.log(` Package manager ${import_chalk7.default.cyan(packageManager)}`);
|
|
24248
|
+
console.log(` Database ${import_chalk7.default.cyan(database)}`);
|
|
23888
24249
|
}
|
|
23889
24250
|
console.log();
|
|
23890
|
-
console.log(` ${
|
|
24251
|
+
console.log(` ${import_chalk7.default.bold("Roles")}`);
|
|
23891
24252
|
for (const [id, role] of Object.entries(roles)) {
|
|
23892
|
-
console.log(` ${
|
|
24253
|
+
console.log(` ${import_chalk7.default.dim("\xB7")} ${import_chalk7.default.magentaBright(id)} ${import_chalk7.default.dim("\u2192")} ${role.prismaModel} ${import_chalk7.default.dim("(")}${role.loginField}${import_chalk7.default.dim(")")}`);
|
|
23893
24254
|
}
|
|
23894
24255
|
console.log();
|
|
23895
24256
|
const onFeatures = Object.entries(features).filter(([k, v]) => v === true && ["twoFactor", "emailVerification", "passwordReset", "accountLockout", "apiKeys", "auditLog", "sessionTracking"].includes(k)).map(([k]) => k);
|
|
23896
|
-
console.log(` ${
|
|
24257
|
+
console.log(` ${import_chalk7.default.bold("Features")} ${onFeatures.map((f) => import_chalk7.default.cyan(f)).join(import_chalk7.default.dim(" \xB7 "))}`);
|
|
23897
24258
|
console.log();
|
|
23898
|
-
const action = await
|
|
24259
|
+
const action = await p6.select({
|
|
23899
24260
|
message: "Proceed?",
|
|
23900
24261
|
options: [
|
|
23901
24262
|
{ value: "go", label: mode === "new" ? "Create project" : "Create files" },
|
|
@@ -23904,41 +24265,39 @@ async function runInit() {
|
|
|
23904
24265
|
{ value: "no", label: "Cancel" }
|
|
23905
24266
|
]
|
|
23906
24267
|
});
|
|
23907
|
-
if (
|
|
23908
|
-
|
|
24268
|
+
if (p6.isCancel(action) || action === "no") {
|
|
24269
|
+
p6.cancel("Cancelled.");
|
|
23909
24270
|
process.exit(0);
|
|
23910
24271
|
}
|
|
23911
24272
|
if (action === "edit") {
|
|
23912
|
-
const section = await
|
|
24273
|
+
const section = await p6.select({
|
|
23913
24274
|
message: "Which section would you like to change?",
|
|
23914
24275
|
options: [
|
|
23915
24276
|
{ value: "app", label: "App identity (name, cookie prefix, session duration)" },
|
|
23916
24277
|
{ value: "roles", label: "Roles" },
|
|
23917
24278
|
{ value: "features", label: "Features" },
|
|
23918
|
-
{ value: "infra", label: "Infrastructure (SMTP, rate limiting)" }
|
|
23919
|
-
{ value: "style", label: "Style (primary colour, logo)" }
|
|
24279
|
+
{ value: "infra", label: "Infrastructure (SMTP, rate limiting)" }
|
|
23920
24280
|
]
|
|
23921
24281
|
});
|
|
23922
|
-
if (
|
|
23923
|
-
|
|
24282
|
+
if (p6.isCancel(section)) {
|
|
24283
|
+
p6.cancel("Cancelled.");
|
|
23924
24284
|
process.exit(0);
|
|
23925
24285
|
}
|
|
23926
24286
|
if (section === "app") app = await promptApp(projectName);
|
|
23927
24287
|
if (section === "roles") roles = await promptRoles();
|
|
23928
24288
|
if (section === "features") features = await promptFeatures(Object.keys(roles));
|
|
23929
24289
|
if (section === "infra") infra = await promptInfrastructure();
|
|
23930
|
-
if (section === "style") style = await promptStyle();
|
|
23931
24290
|
continue;
|
|
23932
24291
|
}
|
|
23933
24292
|
isDry = action === "dry";
|
|
23934
24293
|
break;
|
|
23935
24294
|
}
|
|
23936
24295
|
printSection(mode === "new" ? `BUILDING ${projectName}` : "INSTALLING");
|
|
23937
|
-
const spin =
|
|
24296
|
+
const spin = p6.spinner();
|
|
23938
24297
|
async function writeFile(relPath, content) {
|
|
23939
24298
|
const full = import_path.default.join(targetDir, relPath);
|
|
23940
24299
|
if (isDry) {
|
|
23941
|
-
console.log(` ${
|
|
24300
|
+
console.log(` ${import_chalk7.default.dim("+")} ${import_chalk7.default.yellow(relPath)}`);
|
|
23942
24301
|
return;
|
|
23943
24302
|
}
|
|
23944
24303
|
await import_fs_extra.default.ensureDir(import_path.default.dirname(full));
|
|
@@ -23947,7 +24306,7 @@ async function runInit() {
|
|
|
23947
24306
|
async function step(label, fn) {
|
|
23948
24307
|
spin.start(label);
|
|
23949
24308
|
await fn();
|
|
23950
|
-
spin.stop(`${
|
|
24309
|
+
spin.stop(`${import_chalk7.default.green("\u2713")} ${label}`);
|
|
23951
24310
|
}
|
|
23952
24311
|
if (mode === "new") {
|
|
23953
24312
|
await step("Scaffolding Next.js project", async () => {
|
|
@@ -23963,9 +24322,9 @@ dist
|
|
|
23963
24322
|
*.tsbuildinfo
|
|
23964
24323
|
`);
|
|
23965
24324
|
await writeFile(".env.local", "");
|
|
23966
|
-
await writeFile("src/app/layout.tsx", generateRootLayout(app.appName,
|
|
23967
|
-
await writeFile("src/app/globals.css", generateGlobalsCss(
|
|
23968
|
-
await writeFile("src/app/page.tsx", generateRootPage(
|
|
24325
|
+
await writeFile("src/app/layout.tsx", generateRootLayout(app.appName, DEFAULT_COLOR, language));
|
|
24326
|
+
await writeFile("src/app/globals.css", generateGlobalsCss(DEFAULT_COLOR));
|
|
24327
|
+
await writeFile("src/app/page.tsx", generateRootPage("/login"));
|
|
23969
24328
|
});
|
|
23970
24329
|
}
|
|
23971
24330
|
await step("Generating Prisma schema", async () => {
|
|
@@ -23986,7 +24345,7 @@ dist
|
|
|
23986
24345
|
await writeFile("prisma/schema.prisma", schema);
|
|
23987
24346
|
});
|
|
23988
24347
|
await step("Creating auth.config.ts", async () => {
|
|
23989
|
-
const config = generateAuthConfig({ appName: app.appName, cookiePrefix: app.cookiePrefix, sessionDuration: app.sessionDuration, roles, features, infra, style, language });
|
|
24348
|
+
const config = generateAuthConfig({ appName: app.appName, cookiePrefix: app.cookiePrefix, sessionDuration: app.sessionDuration, roles, features, infra, style: DEFAULT_STYLE, language });
|
|
23990
24349
|
await writeFile(`auth.config.${language === "typescript" ? "ts" : "js"}`, config);
|
|
23991
24350
|
});
|
|
23992
24351
|
await step("Creating middleware", async () => {
|
|
@@ -23995,9 +24354,35 @@ dist
|
|
|
23995
24354
|
await step("Creating session helpers", async () => {
|
|
23996
24355
|
await writeFile(`src/lib/auth.${language === "typescript" ? "ts" : "js"}`, generateAuthLib(language));
|
|
23997
24356
|
});
|
|
23998
|
-
await step("Scaffolding auth pages", async () => {
|
|
24357
|
+
await step("Scaffolding auth pages and API routes", async () => {
|
|
23999
24358
|
const e = language === "typescript" ? "tsx" : "jsx";
|
|
24000
|
-
|
|
24359
|
+
const r = language === "typescript" ? "ts" : "js";
|
|
24360
|
+
await writeFile(`src/lib/prisma.${r}`, generatePrismaLib());
|
|
24361
|
+
await writeFile(`src/app/api/auth/login/route.${r}`, generateLoginRoute());
|
|
24362
|
+
await writeFile(`src/app/api/auth/logout/route.${r}`, generateLogoutRoute());
|
|
24363
|
+
await writeFile(`src/app/api/auth/change-password/route.${r}`, generateChangePasswordRoute());
|
|
24364
|
+
if (features.twoFactor) {
|
|
24365
|
+
await writeFile(`src/app/api/auth/two-factor/route.${r}`, generateTwoFactorRoute());
|
|
24366
|
+
}
|
|
24367
|
+
if (features.passwordReset) {
|
|
24368
|
+
await writeFile(`src/app/api/auth/forgot-password/route.${r}`, generateForgotPasswordRoute(language));
|
|
24369
|
+
await writeFile(`src/app/api/auth/reset-password/route.${r}`, generateResetPasswordRoute(language));
|
|
24370
|
+
}
|
|
24371
|
+
if (features.emailVerification) {
|
|
24372
|
+
await writeFile(`src/app/api/auth/verify-email/route.${r}`, generateVerifyEmailRoute(language));
|
|
24373
|
+
}
|
|
24374
|
+
await writeFile(`src/app/(auth)/login/page.${e}`, generateLoginPage(app.appName, DEFAULT_COLOR, language));
|
|
24375
|
+
if (features.passwordReset) {
|
|
24376
|
+
await writeFile(`src/app/(auth)/forgot-password/page.${e}`, generateForgotPasswordPage(language));
|
|
24377
|
+
await writeFile(`src/app/(auth)/reset-password/page.${e}`, generateResetPasswordPage(language));
|
|
24378
|
+
}
|
|
24379
|
+
if (features.twoFactor) {
|
|
24380
|
+
await writeFile(`src/app/(auth)/two-factor/page.${e}`, generateTwoFactorPage(language));
|
|
24381
|
+
}
|
|
24382
|
+
if (features.emailVerification) {
|
|
24383
|
+
await writeFile(`src/app/(auth)/verify-email-notice/page.${e}`, generateVerifyEmailNoticePage());
|
|
24384
|
+
await writeFile(`src/app/(auth)/verify-email/page.${e}`, generateVerifyEmailPage(language));
|
|
24385
|
+
}
|
|
24001
24386
|
});
|
|
24002
24387
|
await step("Creating .env and .env.example", async () => {
|
|
24003
24388
|
await writeFile(".env", generateEnvFile(app.cookiePrefix, infra, features));
|
|
@@ -24013,55 +24398,53 @@ dist
|
|
|
24013
24398
|
printNextSteps([
|
|
24014
24399
|
...isNew ? [{
|
|
24015
24400
|
n: 0,
|
|
24016
|
-
title: `Enter your project ${
|
|
24017
|
-
lines: [`${
|
|
24401
|
+
title: `Enter your project ${import_chalk7.default.dim("(run every command below from inside here)")}`,
|
|
24402
|
+
lines: [`${import_chalk7.default.green(`cd ${projectName}`)}`]
|
|
24018
24403
|
}] : [],
|
|
24019
24404
|
{
|
|
24020
24405
|
n: 1,
|
|
24021
|
-
title: `Fill in ${
|
|
24406
|
+
title: `Fill in ${import_chalk7.default.yellow(".env")} ${import_chalk7.default.dim("(created for you \u2014 open it and add your values)")}`,
|
|
24022
24407
|
lines: [
|
|
24023
|
-
`${
|
|
24024
|
-
`${
|
|
24025
|
-
...features.emailVerification || features.passwordReset ? [`${
|
|
24026
|
-
...infra.rateLimitProvider === "upstash" ? [`${
|
|
24408
|
+
`${import_chalk7.default.cyan("DATABASE_URL=")} ${import_chalk7.default.dim("\u2190 your Postgres connection string (Neon, Supabase, local)")}`,
|
|
24409
|
+
`${import_chalk7.default.cyan("AEGIS_JWT_SECRET=")} ${import_chalk7.default.dim(process.platform === "win32" ? "\u2190 [Convert]::ToBase64String((1..32|%{[byte](Get-Random -Max 256)}))" : "\u2190 openssl rand -base64 32")}`,
|
|
24410
|
+
...features.emailVerification || features.passwordReset ? [`${import_chalk7.default.cyan("AEGIS_SMTP_HOST=")} ${import_chalk7.default.dim("\u2190 and SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM")}`] : [],
|
|
24411
|
+
...infra.rateLimitProvider === "upstash" ? [`${import_chalk7.default.cyan("UPSTASH_REDIS_REST_URL=")} ${import_chalk7.default.dim("\u2190 and UPSTASH_REDIS_REST_TOKEN")}`] : []
|
|
24027
24412
|
]
|
|
24028
24413
|
},
|
|
24029
24414
|
{
|
|
24030
24415
|
n: 2,
|
|
24031
24416
|
title: "Apply the database schema",
|
|
24032
24417
|
lines: [
|
|
24033
|
-
...isNew ? [`${
|
|
24034
|
-
`${
|
|
24418
|
+
...isNew ? [`${import_chalk7.default.green(`cd ${projectName}`)} ${import_chalk7.default.dim("\u2190 if not already inside")}`] : [],
|
|
24419
|
+
`${import_chalk7.default.green("npx prisma migrate dev --name init")}`
|
|
24035
24420
|
]
|
|
24036
24421
|
},
|
|
24037
24422
|
{
|
|
24038
24423
|
n: 3,
|
|
24039
24424
|
title: "Create your first user",
|
|
24040
|
-
lines: [`${
|
|
24425
|
+
lines: [`${import_chalk7.default.green("npx aegis-auth seed")}`]
|
|
24041
24426
|
},
|
|
24042
24427
|
{
|
|
24043
24428
|
n: 4,
|
|
24044
24429
|
title: mode === "new" ? "Start building" : "Start your dev server",
|
|
24045
24430
|
lines: [
|
|
24046
|
-
`${
|
|
24431
|
+
`${import_chalk7.default.green(packageManager === "npm" ? "npm run dev" : `${packageManager} dev`)} ${import_chalk7.default.dim("\u2192 http://localhost:3000")}`
|
|
24047
24432
|
]
|
|
24048
24433
|
}
|
|
24049
24434
|
]);
|
|
24050
24435
|
console.log();
|
|
24051
|
-
console.log(
|
|
24052
|
-
|
|
24053
|
-
`
|
|
24054
|
-
);
|
|
24055
|
-
console.log(` ${
|
|
24056
|
-
console.log(` ${
|
|
24057
|
-
console.log(` ${
|
|
24058
|
-
console.log(` ${import_chalk8.default.green("aegis-auth doctor")} ${import_chalk8.default.dim("check env, DB, SMTP, Redis")}`);
|
|
24059
|
-
console.log(` ${import_chalk8.default.green("aegis-auth upgrade")} ${import_chalk8.default.dim("update to a new version")}`);
|
|
24436
|
+
console.log(` ${import_chalk7.default.dim("Commands available any time:")}
|
|
24437
|
+
`);
|
|
24438
|
+
console.log(` ${import_chalk7.default.green("aegis-auth add-role")} ${import_chalk7.default.dim("add a new role")}`);
|
|
24439
|
+
console.log(` ${import_chalk7.default.green("aegis-auth generate")} ${import_chalk7.default.dim("regenerate TypeScript types")}`);
|
|
24440
|
+
console.log(` ${import_chalk7.default.green("aegis-auth validate")} ${import_chalk7.default.dim("check config without hitting DB")}`);
|
|
24441
|
+
console.log(` ${import_chalk7.default.green("aegis-auth doctor")} ${import_chalk7.default.dim("check env, DB, SMTP, Redis")}`);
|
|
24442
|
+
console.log(` ${import_chalk7.default.green("aegis-auth upgrade")} ${import_chalk7.default.dim("update to a new version")}`);
|
|
24060
24443
|
console.log();
|
|
24061
24444
|
}
|
|
24062
24445
|
|
|
24063
24446
|
// src/commands/doctor.ts
|
|
24064
|
-
var
|
|
24447
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
24065
24448
|
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
24066
24449
|
var import_path2 = __toESM(require("path"));
|
|
24067
24450
|
async function runDoctor() {
|
|
@@ -24089,7 +24472,7 @@ async function runDoctor() {
|
|
|
24089
24472
|
"AEGIS_JWT_SECRET_PREVIOUS"
|
|
24090
24473
|
];
|
|
24091
24474
|
console.log(`
|
|
24092
|
-
${
|
|
24475
|
+
${import_chalk8.default.dim("\u2500 Environment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
24093
24476
|
`);
|
|
24094
24477
|
for (const key of requiredEnv) {
|
|
24095
24478
|
const val = process.env[key];
|
|
@@ -24112,20 +24495,20 @@ async function runDoctor() {
|
|
|
24112
24495
|
const warns = results.filter((r) => r.status === "warn");
|
|
24113
24496
|
console.log();
|
|
24114
24497
|
if (errors.length === 0 && warns.length === 0) {
|
|
24115
|
-
console.log(` ${
|
|
24498
|
+
console.log(` ${import_chalk8.default.green("\u2713")} ${import_chalk8.default.green("Everything looks good.")}`);
|
|
24116
24499
|
} else {
|
|
24117
24500
|
console.log(
|
|
24118
|
-
` ${
|
|
24501
|
+
` ${import_chalk8.default.red(errors.length)} error${errors.length !== 1 ? "s" : ""}` + (warns.length ? ` ${import_chalk8.default.yellow(warns.length)} warning${warns.length !== 1 ? "s" : ""}` : "") + ` found.`
|
|
24119
24502
|
);
|
|
24120
24503
|
console.log();
|
|
24121
|
-
console.log(` Fix the above, then re-run: ${
|
|
24504
|
+
console.log(` Fix the above, then re-run: ${import_chalk8.default.green("npx aegis-auth doctor")}`);
|
|
24122
24505
|
}
|
|
24123
24506
|
console.log();
|
|
24124
24507
|
}
|
|
24125
24508
|
|
|
24126
24509
|
// src/commands/add-role.ts
|
|
24127
|
-
var
|
|
24128
|
-
var
|
|
24510
|
+
var p7 = __toESM(require("@clack/prompts"));
|
|
24511
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
24129
24512
|
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
24130
24513
|
var import_path3 = __toESM(require("path"));
|
|
24131
24514
|
async function runAddRole() {
|
|
@@ -24134,25 +24517,25 @@ async function runAddRole() {
|
|
|
24134
24517
|
const cwd = process.cwd();
|
|
24135
24518
|
const configPath = import_fs_extra3.default.existsSync(import_path3.default.join(cwd, "auth.config.ts")) ? import_path3.default.join(cwd, "auth.config.ts") : import_fs_extra3.default.existsSync(import_path3.default.join(cwd, "auth.config.js")) ? import_path3.default.join(cwd, "auth.config.js") : null;
|
|
24136
24519
|
if (!configPath) {
|
|
24137
|
-
|
|
24520
|
+
p7.cancel("No auth.config.ts found. Run: npx aegis-auth init first.");
|
|
24138
24521
|
process.exit(1);
|
|
24139
24522
|
}
|
|
24140
24523
|
console.log(
|
|
24141
24524
|
`
|
|
24142
|
-
${
|
|
24143
|
-
${
|
|
24525
|
+
${import_chalk9.default.dim("Adding a new role to your existing setup.")}
|
|
24526
|
+
${import_chalk9.default.dim("You will need to run npx prisma migrate dev after.")}
|
|
24144
24527
|
`
|
|
24145
24528
|
);
|
|
24146
24529
|
const { id, config } = await promptRole(1, 1);
|
|
24147
24530
|
console.log();
|
|
24148
|
-
console.log(` ${
|
|
24531
|
+
console.log(` ${import_chalk9.default.green("\u2713")} Role ${import_chalk9.default.magentaBright(id)} defined.`);
|
|
24149
24532
|
console.log();
|
|
24150
|
-
console.log(` ${
|
|
24533
|
+
console.log(` ${import_chalk9.default.dim("Next steps:")}`);
|
|
24151
24534
|
console.log();
|
|
24152
24535
|
console.log(` 1 Add to auth.config.ts \u2192 roles:`);
|
|
24153
24536
|
console.log();
|
|
24154
24537
|
console.log(
|
|
24155
|
-
|
|
24538
|
+
import_chalk9.default.dim(
|
|
24156
24539
|
` ${id}: {
|
|
24157
24540
|
label: '${config.label}',
|
|
24158
24541
|
prismaModel: '${config.prismaModel}',
|
|
@@ -24164,15 +24547,15 @@ async function runAddRole() {
|
|
|
24164
24547
|
);
|
|
24165
24548
|
console.log();
|
|
24166
24549
|
console.log(` 2 Apply the schema:`);
|
|
24167
|
-
console.log(` ${
|
|
24550
|
+
console.log(` ${import_chalk9.default.green("npx prisma migrate dev --name add-role-" + id)}`);
|
|
24168
24551
|
console.log();
|
|
24169
24552
|
console.log(` 3 Regenerate types:`);
|
|
24170
|
-
console.log(` ${
|
|
24553
|
+
console.log(` ${import_chalk9.default.green("npx aegis-auth generate")}`);
|
|
24171
24554
|
console.log();
|
|
24172
24555
|
}
|
|
24173
24556
|
|
|
24174
24557
|
// src/commands/generate.ts
|
|
24175
|
-
var
|
|
24558
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
24176
24559
|
var import_fs_extra4 = __toESM(require("fs-extra"));
|
|
24177
24560
|
var import_path4 = __toESM(require("path"));
|
|
24178
24561
|
async function runGenerate() {
|
|
@@ -24180,7 +24563,7 @@ async function runGenerate() {
|
|
|
24180
24563
|
const cwd = process.cwd();
|
|
24181
24564
|
const outPath = import_path4.default.join(cwd, "src", "lib", "auth-types.generated.ts");
|
|
24182
24565
|
console.log(`
|
|
24183
|
-
${
|
|
24566
|
+
${import_chalk10.default.dim("Regenerating TypeScript types from auth.config.ts...")}
|
|
24184
24567
|
`);
|
|
24185
24568
|
const content = `// auto-generated by aegis-auth \u2014 do not edit
|
|
24186
24569
|
// run: npx aegis-auth generate to update
|
|
@@ -24194,13 +24577,13 @@ export type { AegisSession }
|
|
|
24194
24577
|
`;
|
|
24195
24578
|
await import_fs_extra4.default.ensureDir(import_path4.default.dirname(outPath));
|
|
24196
24579
|
await import_fs_extra4.default.writeFile(outPath, content, "utf8");
|
|
24197
|
-
console.log(` ${
|
|
24580
|
+
console.log(` ${import_chalk10.default.green("\u2713")} ${import_chalk10.default.yellow("src/lib/auth-types.generated.ts")} updated`);
|
|
24198
24581
|
console.log();
|
|
24199
24582
|
}
|
|
24200
24583
|
|
|
24201
24584
|
// src/commands/seed.ts
|
|
24202
|
-
var
|
|
24203
|
-
var
|
|
24585
|
+
var p8 = __toESM(require("@clack/prompts"));
|
|
24586
|
+
var import_chalk11 = __toESM(require("chalk"));
|
|
24204
24587
|
var import_fs_extra5 = __toESM(require("fs-extra"));
|
|
24205
24588
|
var import_path5 = __toESM(require("path"));
|
|
24206
24589
|
async function runSeed() {
|
|
@@ -24209,45 +24592,45 @@ async function runSeed() {
|
|
|
24209
24592
|
const cwd = process.cwd();
|
|
24210
24593
|
const hasConfig = import_fs_extra5.default.existsSync(import_path5.default.join(cwd, "auth.config.ts")) || import_fs_extra5.default.existsSync(import_path5.default.join(cwd, "auth.config.js"));
|
|
24211
24594
|
if (!hasConfig) {
|
|
24212
|
-
|
|
24595
|
+
p8.cancel("No auth.config.ts found. Run: npx aegis-auth init first.");
|
|
24213
24596
|
process.exit(1);
|
|
24214
24597
|
}
|
|
24215
24598
|
const hasPrisma = import_fs_extra5.default.existsSync(import_path5.default.join(cwd, "node_modules", ".prisma", "client"));
|
|
24216
24599
|
if (!hasPrisma) {
|
|
24217
|
-
|
|
24600
|
+
p8.cancel("Prisma client not generated. Run: npx prisma generate first.");
|
|
24218
24601
|
process.exit(1);
|
|
24219
24602
|
}
|
|
24220
24603
|
console.log(`
|
|
24221
|
-
${
|
|
24604
|
+
${import_chalk11.default.dim("Creates the first user account in your database.")}
|
|
24222
24605
|
`);
|
|
24223
|
-
const role = await
|
|
24606
|
+
const role = await p8.text({
|
|
24224
24607
|
message: "Role ID",
|
|
24225
24608
|
placeholder: "admin",
|
|
24226
24609
|
validate: (v) => !v ? "Required" : void 0
|
|
24227
24610
|
});
|
|
24228
|
-
if (
|
|
24229
|
-
const loginField = await
|
|
24611
|
+
if (p8.isCancel(role)) process.exit(0);
|
|
24612
|
+
const loginField = await p8.select({
|
|
24230
24613
|
message: "Login field for this role",
|
|
24231
24614
|
options: [
|
|
24232
24615
|
{ value: "email", label: "email" },
|
|
24233
24616
|
{ value: "username", label: "username" }
|
|
24234
24617
|
]
|
|
24235
24618
|
});
|
|
24236
|
-
if (
|
|
24237
|
-
const identifier = await
|
|
24619
|
+
if (p8.isCancel(loginField)) process.exit(0);
|
|
24620
|
+
const identifier = await p8.text({
|
|
24238
24621
|
message: loginField === "email" ? "Email address" : "Username",
|
|
24239
24622
|
validate: (v) => {
|
|
24240
24623
|
if (!v) return "Required";
|
|
24241
24624
|
if (loginField === "email" && !v.includes("@")) return "Enter a valid email address";
|
|
24242
24625
|
}
|
|
24243
24626
|
});
|
|
24244
|
-
if (
|
|
24245
|
-
const password3 = await
|
|
24627
|
+
if (p8.isCancel(identifier)) process.exit(0);
|
|
24628
|
+
const password3 = await p8.password({
|
|
24246
24629
|
message: "Password",
|
|
24247
24630
|
validate: (v) => v.length < 8 ? "At least 8 characters" : void 0
|
|
24248
24631
|
});
|
|
24249
|
-
if (
|
|
24250
|
-
const spin =
|
|
24632
|
+
if (p8.isCancel(password3)) process.exit(0);
|
|
24633
|
+
const spin = p8.spinner();
|
|
24251
24634
|
spin.start("Creating user\u2026");
|
|
24252
24635
|
try {
|
|
24253
24636
|
const envPath = import_path5.default.join(cwd, ".env");
|
|
@@ -24275,18 +24658,18 @@ async function runSeed() {
|
|
|
24275
24658
|
}
|
|
24276
24659
|
});
|
|
24277
24660
|
await prisma.$disconnect();
|
|
24278
|
-
spin.stop(`${
|
|
24661
|
+
spin.stop(`${import_chalk11.default.green("\u2713")} User created`);
|
|
24279
24662
|
console.log();
|
|
24280
|
-
console.log(` ${
|
|
24281
|
-
console.log(` ${
|
|
24663
|
+
console.log(` ${import_chalk11.default.bold("Role")} ${import_chalk11.default.magentaBright(role)}`);
|
|
24664
|
+
console.log(` ${import_chalk11.default.bold(loginField)} ${import_chalk11.default.cyan(identifier)}`);
|
|
24282
24665
|
console.log();
|
|
24283
24666
|
} catch (err) {
|
|
24284
|
-
spin.stop(`${
|
|
24667
|
+
spin.stop(`${import_chalk11.default.red("\u2717")} Failed`);
|
|
24285
24668
|
console.log();
|
|
24286
24669
|
if (err?.code === "P2002") {
|
|
24287
|
-
console.log(` ${
|
|
24670
|
+
console.log(` ${import_chalk11.default.red("A user with that ${loginField} already exists.")}`);
|
|
24288
24671
|
} else {
|
|
24289
|
-
console.log(` ${
|
|
24672
|
+
console.log(` ${import_chalk11.default.red(err?.message ?? String(err))}`);
|
|
24290
24673
|
}
|
|
24291
24674
|
console.log();
|
|
24292
24675
|
process.exit(1);
|
|
@@ -24294,7 +24677,7 @@ async function runSeed() {
|
|
|
24294
24677
|
}
|
|
24295
24678
|
|
|
24296
24679
|
// src/index.ts
|
|
24297
|
-
var
|
|
24680
|
+
var import_chalk12 = __toESM(require("chalk"));
|
|
24298
24681
|
var [, , command, ...args] = process.argv;
|
|
24299
24682
|
var COMMANDS = {
|
|
24300
24683
|
init: runInit,
|
|
@@ -24315,23 +24698,23 @@ var DESCRIPTIONS = {
|
|
|
24315
24698
|
async function main() {
|
|
24316
24699
|
if (!command || command === "--help" || command === "-h") {
|
|
24317
24700
|
printBanner();
|
|
24318
|
-
console.log(` ${
|
|
24701
|
+
console.log(` ${import_chalk12.default.bold("Usage")} ${import_chalk12.default.cyan("npx aegis-auth")} ${import_chalk12.default.yellow("<command>")}`);
|
|
24319
24702
|
console.log();
|
|
24320
|
-
console.log(` ${
|
|
24703
|
+
console.log(` ${import_chalk12.default.bold("Commands")}`);
|
|
24321
24704
|
console.log();
|
|
24322
24705
|
for (const [cmd, desc] of Object.entries(DESCRIPTIONS)) {
|
|
24323
|
-
console.log(` ${
|
|
24706
|
+
console.log(` ${import_chalk12.default.green(cmd.padEnd(14))} ${import_chalk12.default.dim(desc)}`);
|
|
24324
24707
|
}
|
|
24325
24708
|
console.log();
|
|
24326
|
-
console.log(` ${
|
|
24709
|
+
console.log(` ${import_chalk12.default.dim("Run")} ${import_chalk12.default.cyan("npx aegis-auth <command> --help")} ${import_chalk12.default.dim("for more info.")}`);
|
|
24327
24710
|
console.log();
|
|
24328
24711
|
return;
|
|
24329
24712
|
}
|
|
24330
24713
|
const handler = COMMANDS[command];
|
|
24331
24714
|
if (!handler) {
|
|
24332
24715
|
console.error(`
|
|
24333
|
-
${
|
|
24334
|
-
console.error(` Run ${
|
|
24716
|
+
${import_chalk12.default.red("Unknown command:")} ${import_chalk12.default.yellow(command)}`);
|
|
24717
|
+
console.error(` Run ${import_chalk12.default.cyan("npx aegis-auth --help")} for available commands.
|
|
24335
24718
|
`);
|
|
24336
24719
|
process.exit(1);
|
|
24337
24720
|
}
|
|
@@ -24339,7 +24722,7 @@ async function main() {
|
|
|
24339
24722
|
}
|
|
24340
24723
|
main().catch((err) => {
|
|
24341
24724
|
console.error(`
|
|
24342
|
-
${
|
|
24725
|
+
${import_chalk12.default.red("Unexpected error:")} ${err.message}
|
|
24343
24726
|
`);
|
|
24344
24727
|
process.exit(1);
|
|
24345
24728
|
});
|