toiljs 0.0.56 → 0.0.57
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/CHANGELOG.md +10 -0
- package/README.md +72 -14
- package/build/backend/.tsbuildinfo +1 -1
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/index.js +284 -137
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/dev/devtools.js +1 -1
- package/build/client/routing/hooks.js +2 -2
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/template-build.d.ts +5 -2
- package/build/compiler/template-build.js +18 -6
- package/build/devserver/.tsbuildinfo +1 -1
- package/build/devserver/database.d.ts +1 -1
- package/build/devserver/database.js +2 -0
- package/build/devserver/host.js +18 -1
- package/examples/basic/server/routes/Auth.ts +2 -7
- package/examples/basic/server/routes/Guestbook.ts +2 -4
- package/package.json +26 -26
- package/src/cli/create.ts +19 -4
- package/src/cli/diagnostics.ts +48 -0
- package/src/cli/doctor.ts +145 -6
- package/src/client/dev/devtools.tsx +5 -1
- package/src/client/routing/hooks.ts +5 -3
- package/src/compiler/template-build.ts +41 -4
- package/src/devserver/database.ts +19 -1
- package/src/devserver/host.ts +32 -1
- package/test/devserver-secrets.test.ts +59 -0
- package/test/doctor.test.ts +30 -0
package/build/cli/index.js
CHANGED
|
@@ -609,8 +609,8 @@ function block({
|
|
|
609
609
|
return;
|
|
610
610
|
}
|
|
611
611
|
if (!o2) return;
|
|
612
|
-
const i2 = a3 === "return" ? 0 : -1,
|
|
613
|
-
l.moveCursor(r2, i2,
|
|
612
|
+
const i2 = a3 === "return" ? 0 : -1, m2 = a3 === "return" ? -1 : 0;
|
|
613
|
+
l.moveCursor(r2, i2, m2, () => {
|
|
614
614
|
l.clearLine(r2, 1, () => {
|
|
615
615
|
e.once("keypress", n2);
|
|
616
616
|
});
|
|
@@ -628,9 +628,9 @@ function wrapTextWithPrefix(e, r2, o2, t2 = o2, s = o2, n2) {
|
|
|
628
628
|
hard: true,
|
|
629
629
|
trim: false
|
|
630
630
|
}).split(`
|
|
631
|
-
`).map((c2, i2,
|
|
632
|
-
const
|
|
633
|
-
return i2 === 0 ? `${t2}${
|
|
631
|
+
`).map((c2, i2, m2) => {
|
|
632
|
+
const d = n2 ? n2(c2, i2) : c2;
|
|
633
|
+
return i2 === 0 ? `${t2}${d}` : i2 === m2.length - 1 ? `${s}${d}` : `${o2}${d}`;
|
|
634
634
|
}).join(`
|
|
635
635
|
`);
|
|
636
636
|
}
|
|
@@ -941,7 +941,7 @@ function isUnicodeSupported() {
|
|
|
941
941
|
}
|
|
942
942
|
var unicode = isUnicodeSupported();
|
|
943
943
|
var isCI = () => process.env.CI === "true";
|
|
944
|
-
var unicodeOr = (
|
|
944
|
+
var unicodeOr = (o2, e) => unicode ? o2 : e;
|
|
945
945
|
var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
|
|
946
946
|
var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
|
|
947
947
|
var S_STEP_ERROR = unicodeOr("\u25B2", "x");
|
|
@@ -967,8 +967,8 @@ var S_INFO = unicodeOr("\u25CF", "\u2022");
|
|
|
967
967
|
var S_SUCCESS = unicodeOr("\u25C6", "*");
|
|
968
968
|
var S_WARN = unicodeOr("\u25B2", "!");
|
|
969
969
|
var S_ERROR = unicodeOr("\u25A0", "x");
|
|
970
|
-
var symbol = (
|
|
971
|
-
switch (
|
|
970
|
+
var symbol = (o2) => {
|
|
971
|
+
switch (o2) {
|
|
972
972
|
case "initial":
|
|
973
973
|
case "active":
|
|
974
974
|
return styleText2("cyan", S_STEP_ACTIVE);
|
|
@@ -980,8 +980,8 @@ var symbol = (e) => {
|
|
|
980
980
|
return styleText2("green", S_STEP_SUBMIT);
|
|
981
981
|
}
|
|
982
982
|
};
|
|
983
|
-
var symbolBar = (
|
|
984
|
-
switch (
|
|
983
|
+
var symbolBar = (o2) => {
|
|
984
|
+
switch (o2) {
|
|
985
985
|
case "initial":
|
|
986
986
|
case "active":
|
|
987
987
|
return styleText2("cyan", S_BAR);
|
|
@@ -993,6 +993,10 @@ var symbolBar = (e) => {
|
|
|
993
993
|
return styleText2("green", S_BAR);
|
|
994
994
|
}
|
|
995
995
|
};
|
|
996
|
+
function formatInstructionFooter(o2, e) {
|
|
997
|
+
const r2 = [`${e ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" \u2022 ")}`];
|
|
998
|
+
return e && r2.push(styleText2("cyan", S_BAR_END)), r2;
|
|
999
|
+
}
|
|
996
1000
|
var E$1 = (l2, o2, g, c2, h2, O = false) => {
|
|
997
1001
|
let r2 = o2, w = 0;
|
|
998
1002
|
if (O)
|
|
@@ -1012,19 +1016,19 @@ var limitOptions = ({
|
|
|
1012
1016
|
columnPadding: O = 0,
|
|
1013
1017
|
rowPadding: r2 = 4
|
|
1014
1018
|
}) => {
|
|
1015
|
-
const i2 = getColumns(c2) - O, I = getRows(c2), C2 = styleText2("dim", "..."), x = Math.max(I - r2, 0),
|
|
1019
|
+
const i2 = getColumns(c2) - O, I = getRows(c2), C2 = styleText2("dim", "..."), x = Math.max(I - r2, 0), m2 = Math.max(Math.min(h2, x), 5);
|
|
1016
1020
|
let p = 0;
|
|
1017
|
-
l2 >=
|
|
1018
|
-
Math.min(l2 -
|
|
1021
|
+
l2 >= m2 - 3 && (p = Math.max(
|
|
1022
|
+
Math.min(l2 - m2 + 3, o2.length - m2),
|
|
1019
1023
|
0
|
|
1020
1024
|
));
|
|
1021
|
-
let f =
|
|
1025
|
+
let f = m2 < o2.length && p > 0, u3 = m2 < o2.length && p + m2 < o2.length;
|
|
1022
1026
|
const W2 = Math.min(
|
|
1023
|
-
p +
|
|
1027
|
+
p + m2,
|
|
1024
1028
|
o2.length
|
|
1025
1029
|
), e = [];
|
|
1026
|
-
let
|
|
1027
|
-
f &&
|
|
1030
|
+
let d = 0;
|
|
1031
|
+
f && d++, u3 && d++;
|
|
1028
1032
|
const v = p + (f ? 1 : 0), P = W2 - (u3 ? 1 : 0);
|
|
1029
1033
|
for (let t2 = v; t2 < P; t2++) {
|
|
1030
1034
|
const n2 = wrapAnsi(g(o2[t2], t2 === l2), i2, {
|
|
@@ -1032,10 +1036,10 @@ var limitOptions = ({
|
|
|
1032
1036
|
trim: false
|
|
1033
1037
|
}).split(`
|
|
1034
1038
|
`);
|
|
1035
|
-
e.push(n2),
|
|
1039
|
+
e.push(n2), d += n2.length;
|
|
1036
1040
|
}
|
|
1037
|
-
if (
|
|
1038
|
-
let t2 = 0, n2 = 0, s =
|
|
1041
|
+
if (d > x) {
|
|
1042
|
+
let t2 = 0, n2 = 0, s = d;
|
|
1039
1043
|
const M = l2 - v;
|
|
1040
1044
|
let a3 = x;
|
|
1041
1045
|
const T = () => E$1(e, s, 0, M, a3), L = () => E$1(
|
|
@@ -1095,42 +1099,29 @@ ${g}
|
|
|
1095
1099
|
}
|
|
1096
1100
|
}).prompt();
|
|
1097
1101
|
};
|
|
1098
|
-
var
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1106
|
-
i2.write(`${e}${o2}
|
|
1107
|
-
`);
|
|
1108
|
-
};
|
|
1109
|
-
var outro = (o2 = "", t2) => {
|
|
1110
|
-
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1111
|
-
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1112
|
-
i2.write(`${e}${o2}
|
|
1113
|
-
|
|
1114
|
-
`);
|
|
1115
|
-
};
|
|
1116
|
-
var d = (n2, a3) => n2.split(`
|
|
1117
|
-
`).map((m) => a3(m)).join(`
|
|
1102
|
+
var MULTISELECT_INSTRUCTIONS = [
|
|
1103
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1104
|
+
`${styleText2("dim", "Space:")} select`,
|
|
1105
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1106
|
+
];
|
|
1107
|
+
var m = (n2, o2) => n2.split(`
|
|
1108
|
+
`).map((d) => o2(d)).join(`
|
|
1118
1109
|
`);
|
|
1119
1110
|
var multiselect = (n2) => {
|
|
1120
|
-
const
|
|
1111
|
+
const o2 = (t2, a3) => {
|
|
1121
1112
|
const r2 = t2.label ?? String(t2.value);
|
|
1122
|
-
return
|
|
1123
|
-
},
|
|
1113
|
+
return a3 === "disabled" ? `${styleText2("gray", S_CHECKBOX_INACTIVE)} ${m(r2, (l2) => styleText2(["strikethrough", "gray"], l2))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a3 === "active" ? `${styleText2("cyan", S_CHECKBOX_ACTIVE)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${m(r2, (l2) => styleText2("dim", l2))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "cancelled" ? `${m(r2, (l2) => styleText2(["strikethrough", "dim"], l2))}` : a3 === "active-selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "submitted" ? `${m(r2, (l2) => styleText2("dim", l2))}` : `${styleText2("dim", S_CHECKBOX_INACTIVE)} ${m(r2, (l2) => styleText2("dim", l2))}`;
|
|
1114
|
+
}, d = n2.required ?? true;
|
|
1124
1115
|
return new a$1({
|
|
1125
1116
|
options: n2.options,
|
|
1126
1117
|
signal: n2.signal,
|
|
1127
1118
|
input: n2.input,
|
|
1128
1119
|
output: n2.output,
|
|
1129
1120
|
initialValues: n2.initialValues,
|
|
1130
|
-
required:
|
|
1121
|
+
required: d,
|
|
1131
1122
|
cursorAt: n2.cursorAt,
|
|
1132
1123
|
validate(t2) {
|
|
1133
|
-
if (
|
|
1124
|
+
if (d && (t2 === void 0 || t2.length === 0))
|
|
1134
1125
|
return `Please select at least one option.
|
|
1135
1126
|
${styleText2(
|
|
1136
1127
|
"reset",
|
|
@@ -1144,22 +1135,22 @@ ${styleText2(
|
|
|
1144
1135
|
)}`;
|
|
1145
1136
|
},
|
|
1146
1137
|
render() {
|
|
1147
|
-
const t2 = n2.withGuide ?? settings.withGuide,
|
|
1138
|
+
const t2 = n2.withGuide ?? settings.withGuide, a3 = wrapTextWithPrefix(
|
|
1148
1139
|
n2.output,
|
|
1149
1140
|
n2.message,
|
|
1150
1141
|
t2 ? `${symbolBar(this.state)} ` : "",
|
|
1151
1142
|
`${symbol(this.state)} `
|
|
1152
1143
|
), r2 = `${t2 ? `${styleText2("gray", S_BAR)}
|
|
1153
|
-
` : ""}${
|
|
1154
|
-
`, l2 = this.value ?? [],
|
|
1144
|
+
` : ""}${a3}
|
|
1145
|
+
`, l2 = this.value ?? [], p = (i2, u3) => {
|
|
1155
1146
|
if (i2.disabled)
|
|
1156
|
-
return
|
|
1147
|
+
return o2(i2, "disabled");
|
|
1157
1148
|
const s = l2.includes(i2.value);
|
|
1158
|
-
return u3 && s ?
|
|
1149
|
+
return u3 && s ? o2(i2, "active-selected") : s ? o2(i2, "selected") : o2(i2, u3 ? "active" : "inactive");
|
|
1159
1150
|
};
|
|
1160
1151
|
switch (this.state) {
|
|
1161
1152
|
case "submit": {
|
|
1162
|
-
const i2 = this.options.filter(({ value: s }) => l2.includes(s)).map((s) =>
|
|
1153
|
+
const i2 = this.options.filter(({ value: s }) => l2.includes(s)).map((s) => o2(s, "submitted")).join(styleText2("dim", ", ")) || styleText2("dim", "none"), u3 = wrapTextWithPrefix(
|
|
1163
1154
|
n2.output,
|
|
1164
1155
|
i2,
|
|
1165
1156
|
t2 ? `${styleText2("gray", S_BAR)} ` : ""
|
|
@@ -1167,7 +1158,7 @@ ${styleText2(
|
|
|
1167
1158
|
return `${r2}${u3}`;
|
|
1168
1159
|
}
|
|
1169
1160
|
case "cancel": {
|
|
1170
|
-
const i2 = this.options.filter(({ value: s }) => l2.includes(s)).map((s) =>
|
|
1161
|
+
const i2 = this.options.filter(({ value: s }) => l2.includes(s)).map((s) => o2(s, "cancelled")).join(styleText2("dim", ", "));
|
|
1171
1162
|
if (i2.trim() === "")
|
|
1172
1163
|
return `${r2}${styleText2("gray", S_BAR)}`;
|
|
1173
1164
|
const u3 = wrapTextWithPrefix(
|
|
@@ -1181,10 +1172,10 @@ ${styleText2("gray", S_BAR)}` : ""}`;
|
|
|
1181
1172
|
case "error": {
|
|
1182
1173
|
const i2 = t2 ? `${styleText2("yellow", S_BAR)} ` : "", u3 = this.error.split(`
|
|
1183
1174
|
`).map(
|
|
1184
|
-
(
|
|
1175
|
+
($, x) => x === 0 ? `${t2 ? `${styleText2("yellow", S_BAR_END)} ` : ""}${styleText2("yellow", $)}` : ` ${$}`
|
|
1185
1176
|
).join(`
|
|
1186
1177
|
`), s = r2.split(`
|
|
1187
|
-
`).length,
|
|
1178
|
+
`).length, g = u3.split(`
|
|
1188
1179
|
`).length + 1;
|
|
1189
1180
|
return `${r2}${i2}${limitOptions({
|
|
1190
1181
|
output: n2.output,
|
|
@@ -1192,8 +1183,8 @@ ${styleText2("gray", S_BAR)}` : ""}`;
|
|
|
1192
1183
|
cursor: this.cursor,
|
|
1193
1184
|
maxItems: n2.maxItems,
|
|
1194
1185
|
columnPadding: i2.length,
|
|
1195
|
-
rowPadding: s +
|
|
1196
|
-
style:
|
|
1186
|
+
rowPadding: s + g,
|
|
1187
|
+
style: p
|
|
1197
1188
|
}).join(`
|
|
1198
1189
|
${i2}`)}
|
|
1199
1190
|
${u3}
|
|
@@ -1201,53 +1192,72 @@ ${u3}
|
|
|
1201
1192
|
}
|
|
1202
1193
|
default: {
|
|
1203
1194
|
const i2 = t2 ? `${styleText2("cyan", S_BAR)} ` : "", u3 = r2.split(`
|
|
1204
|
-
`).length, s = t2
|
|
1195
|
+
`).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2), g = s.join(`
|
|
1196
|
+
`), $ = s.length + 1;
|
|
1205
1197
|
return `${r2}${i2}${limitOptions({
|
|
1206
1198
|
output: n2.output,
|
|
1207
1199
|
options: this.options,
|
|
1208
1200
|
cursor: this.cursor,
|
|
1209
1201
|
maxItems: n2.maxItems,
|
|
1210
1202
|
columnPadding: i2.length,
|
|
1211
|
-
rowPadding: u3 +
|
|
1212
|
-
style:
|
|
1203
|
+
rowPadding: u3 + $,
|
|
1204
|
+
style: p
|
|
1213
1205
|
}).join(`
|
|
1214
1206
|
${i2}`)}
|
|
1215
|
-
${
|
|
1207
|
+
${g}
|
|
1216
1208
|
`;
|
|
1217
1209
|
}
|
|
1218
1210
|
}
|
|
1219
1211
|
}
|
|
1220
1212
|
}).prompt();
|
|
1221
1213
|
};
|
|
1222
|
-
var
|
|
1214
|
+
var cancel = (o2 = "", t2) => {
|
|
1215
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1216
|
+
i2.write(`${e}${styleText2("red", o2)}
|
|
1217
|
+
|
|
1218
|
+
`);
|
|
1219
|
+
};
|
|
1220
|
+
var intro = (o2 = "", t2) => {
|
|
1221
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1222
|
+
i2.write(`${e}${o2}
|
|
1223
|
+
`);
|
|
1224
|
+
};
|
|
1225
|
+
var outro = (o2 = "", t2) => {
|
|
1226
|
+
const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1227
|
+
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1228
|
+
i2.write(`${e}${o2}
|
|
1229
|
+
|
|
1230
|
+
`);
|
|
1231
|
+
};
|
|
1232
|
+
var W$1 = (o2) => o2;
|
|
1223
1233
|
var C = (o2, e, s) => {
|
|
1224
1234
|
const a3 = {
|
|
1225
1235
|
hard: true,
|
|
1226
1236
|
trim: false
|
|
1227
1237
|
}, i2 = wrapAnsi(o2, e, a3).split(`
|
|
1228
|
-
`), c2 = i2.reduce((n2,
|
|
1238
|
+
`), c2 = i2.reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), u3 = i2.map(s).reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), g = e - (u3 - c2);
|
|
1229
1239
|
return wrapAnsi(o2, g, a3);
|
|
1230
1240
|
};
|
|
1231
1241
|
var note = (o2 = "", e = "", s) => {
|
|
1232
1242
|
const a3 = s?.output ?? process$1.stdout, i2 = s?.withGuide ?? settings.withGuide, c2 = s?.format ?? W$1, g = ["", ...C(o2, getColumns(a3) - 6, c2).split(`
|
|
1233
|
-
`).map(c2), ""], n2 = dist_default2(e),
|
|
1234
|
-
g.reduce((
|
|
1243
|
+
`).map(c2), ""], n2 = dist_default2(e), t2 = Math.max(
|
|
1244
|
+
g.reduce((m2, F) => {
|
|
1235
1245
|
const O = dist_default2(F);
|
|
1236
|
-
return O >
|
|
1246
|
+
return O > m2 ? O : m2;
|
|
1237
1247
|
}, 0),
|
|
1238
1248
|
n2
|
|
1239
1249
|
) + 2, h2 = g.map(
|
|
1240
|
-
(
|
|
1250
|
+
(m2) => `${styleText2("gray", S_BAR)} ${m2}${" ".repeat(t2 - dist_default2(m2))}${styleText2("gray", S_BAR)}`
|
|
1241
1251
|
).join(`
|
|
1242
1252
|
`), T = i2 ? `${styleText2("gray", S_BAR)}
|
|
1243
1253
|
` : "", l$1 = i2 ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;
|
|
1244
1254
|
a3.write(
|
|
1245
1255
|
`${T}${styleText2("green", S_STEP_SUBMIT)} ${styleText2("reset", e)} ${styleText2(
|
|
1246
1256
|
"gray",
|
|
1247
|
-
S_BAR_H.repeat(Math.max(
|
|
1257
|
+
S_BAR_H.repeat(Math.max(t2 - n2 - 1, 1)) + S_CORNER_TOP_RIGHT
|
|
1248
1258
|
)}
|
|
1249
1259
|
${h2}
|
|
1250
|
-
${styleText2("gray", l$1 + S_BAR_H.repeat(
|
|
1260
|
+
${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
|
|
1251
1261
|
`
|
|
1252
1262
|
);
|
|
1253
1263
|
};
|
|
@@ -1260,18 +1270,18 @@ var spinner = ({
|
|
|
1260
1270
|
errorMessage: O,
|
|
1261
1271
|
frames: E = unicode ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"],
|
|
1262
1272
|
delay: F = unicode ? 80 : 120,
|
|
1263
|
-
signal:
|
|
1273
|
+
signal: m2,
|
|
1264
1274
|
...I
|
|
1265
1275
|
} = {}) => {
|
|
1266
1276
|
const u3 = isCI();
|
|
1267
|
-
let M, T,
|
|
1277
|
+
let M, T, d = false, S = false, s = "", p, w = performance.now();
|
|
1268
1278
|
const x = getColumns(n2), k = I?.styleFrame ?? W, g = (e) => {
|
|
1269
1279
|
const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1270
|
-
S = e === 1,
|
|
1280
|
+
S = e === 1, d && (a3(r2, e), S && typeof h2 == "function" && h2());
|
|
1271
1281
|
}, f = () => g(2), i2 = () => g(1), A = () => {
|
|
1272
|
-
process.on("uncaughtExceptionMonitor", f), process.on("unhandledRejection", f), process.on("SIGINT", i2), process.on("SIGTERM", i2), process.on("exit", g),
|
|
1282
|
+
process.on("uncaughtExceptionMonitor", f), process.on("unhandledRejection", f), process.on("SIGINT", i2), process.on("SIGTERM", i2), process.on("exit", g), m2 && m2.addEventListener("abort", i2);
|
|
1273
1283
|
}, H = () => {
|
|
1274
|
-
process.removeListener("uncaughtExceptionMonitor", f), process.removeListener("unhandledRejection", f), process.removeListener("SIGINT", i2), process.removeListener("SIGTERM", i2), process.removeListener("exit", g),
|
|
1284
|
+
process.removeListener("uncaughtExceptionMonitor", f), process.removeListener("unhandledRejection", f), process.removeListener("SIGINT", i2), process.removeListener("SIGTERM", i2), process.removeListener("exit", g), m2 && m2.removeEventListener("abort", i2);
|
|
1275
1285
|
}, y = () => {
|
|
1276
1286
|
if (p === void 0) return;
|
|
1277
1287
|
u3 && n2.write(`
|
|
@@ -1286,7 +1296,7 @@ var spinner = ({
|
|
|
1286
1296
|
const r2 = (performance.now() - e) / 1e3, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
|
|
1287
1297
|
return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
|
|
1288
1298
|
}, N = I.withGuide ?? settings.withGuide, P = (e = "") => {
|
|
1289
|
-
|
|
1299
|
+
d = true, M = block({ output: n2 }), s = C2(e), w = performance.now(), N && n2.write(`${styleText2("gray", S_BAR)}
|
|
1290
1300
|
`);
|
|
1291
1301
|
let r2 = 0, t2 = 0;
|
|
1292
1302
|
A(), T = setInterval(() => {
|
|
@@ -1310,8 +1320,8 @@ var spinner = ({
|
|
|
1310
1320
|
n2.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
|
|
1311
1321
|
}, F);
|
|
1312
1322
|
}, a3 = (e = "", r2 = 0, t2 = false) => {
|
|
1313
|
-
if (!
|
|
1314
|
-
|
|
1323
|
+
if (!d) return;
|
|
1324
|
+
d = false, clearInterval(T), y();
|
|
1315
1325
|
const o2 = r2 === 0 ? styleText2("green", S_STEP_SUBMIT) : r2 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
|
|
1316
1326
|
s = e ?? s, t2 || (l2 === "timer" ? n2.write(`${o2} ${s} ${_(w)}
|
|
1317
1327
|
`) : n2.write(`${o2} ${s}
|
|
@@ -1336,20 +1346,24 @@ var u2 = {
|
|
|
1336
1346
|
heavy: unicodeOr("\u2501", "="),
|
|
1337
1347
|
block: unicodeOr("\u2588", "#")
|
|
1338
1348
|
};
|
|
1339
|
-
var
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
var
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1349
|
+
var SELECT_INSTRUCTIONS = [
|
|
1350
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1351
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1352
|
+
];
|
|
1353
|
+
var c = (t2, a3) => t2.includes(`
|
|
1354
|
+
`) ? t2.split(`
|
|
1355
|
+
`).map((i2) => a3(i2)).join(`
|
|
1356
|
+
`) : a3(t2);
|
|
1357
|
+
var select = (t2) => {
|
|
1358
|
+
const a3 = (i2, m2) => {
|
|
1359
|
+
const s = i2.label ?? String(i2.value);
|
|
1360
|
+
switch (m2) {
|
|
1347
1361
|
case "disabled":
|
|
1348
|
-
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${
|
|
1362
|
+
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${i2.hint ? ` ${styleText2("dim", `(${i2.hint ?? "disabled"})`)}` : ""}`;
|
|
1349
1363
|
case "selected":
|
|
1350
1364
|
return `${c(s, (n2) => styleText2("dim", n2))}`;
|
|
1351
1365
|
case "active":
|
|
1352
|
-
return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${
|
|
1366
|
+
return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${i2.hint ? ` ${styleText2("dim", `(${i2.hint})`)}` : ""}`;
|
|
1353
1367
|
case "cancelled":
|
|
1354
1368
|
return `${c(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
|
|
1355
1369
|
default:
|
|
@@ -1357,52 +1371,53 @@ var select = (e) => {
|
|
|
1357
1371
|
}
|
|
1358
1372
|
};
|
|
1359
1373
|
return new a2({
|
|
1360
|
-
options:
|
|
1361
|
-
signal:
|
|
1362
|
-
input:
|
|
1363
|
-
output:
|
|
1364
|
-
initialValue:
|
|
1374
|
+
options: t2.options,
|
|
1375
|
+
signal: t2.signal,
|
|
1376
|
+
input: t2.input,
|
|
1377
|
+
output: t2.output,
|
|
1378
|
+
initialValue: t2.initialValue,
|
|
1365
1379
|
render() {
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1368
|
-
|
|
1380
|
+
const i2 = t2.withGuide ?? settings.withGuide, m2 = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(
|
|
1381
|
+
t2.output,
|
|
1382
|
+
t2.message,
|
|
1369
1383
|
s,
|
|
1370
|
-
|
|
1371
|
-
), u3 = `${
|
|
1384
|
+
m2
|
|
1385
|
+
), u3 = `${i2 ? `${styleText2("gray", S_BAR)}
|
|
1372
1386
|
` : ""}${n2}
|
|
1373
1387
|
`;
|
|
1374
1388
|
switch (this.state) {
|
|
1375
1389
|
case "submit": {
|
|
1376
|
-
const r2 =
|
|
1377
|
-
|
|
1390
|
+
const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
|
|
1391
|
+
t2.output,
|
|
1378
1392
|
a3(this.options[this.cursor], "selected"),
|
|
1379
1393
|
r2
|
|
1380
1394
|
);
|
|
1381
|
-
return `${u3}${
|
|
1395
|
+
return `${u3}${o2}`;
|
|
1382
1396
|
}
|
|
1383
1397
|
case "cancel": {
|
|
1384
|
-
const r2 =
|
|
1385
|
-
|
|
1398
|
+
const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
|
|
1399
|
+
t2.output,
|
|
1386
1400
|
a3(this.options[this.cursor], "cancelled"),
|
|
1387
1401
|
r2
|
|
1388
1402
|
);
|
|
1389
|
-
return `${u3}${
|
|
1403
|
+
return `${u3}${o2}${i2 ? `
|
|
1390
1404
|
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1391
1405
|
}
|
|
1392
1406
|
default: {
|
|
1393
|
-
const r2 =
|
|
1394
|
-
`).length,
|
|
1407
|
+
const r2 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u3.split(`
|
|
1408
|
+
`).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i2), h2 = $.join(`
|
|
1409
|
+
`), b = $.length + 1;
|
|
1395
1410
|
return `${u3}${r2}${limitOptions({
|
|
1396
|
-
output:
|
|
1411
|
+
output: t2.output,
|
|
1397
1412
|
cursor: this.cursor,
|
|
1398
1413
|
options: this.options,
|
|
1399
|
-
maxItems:
|
|
1414
|
+
maxItems: t2.maxItems,
|
|
1400
1415
|
columnPadding: r2.length,
|
|
1401
|
-
rowPadding:
|
|
1402
|
-
style: (p,
|
|
1416
|
+
rowPadding: o2 + b,
|
|
1417
|
+
style: (p, x) => a3(p, p.disabled ? "disabled" : x ? "active" : "inactive")
|
|
1403
1418
|
}).join(`
|
|
1404
1419
|
${r2}`)}
|
|
1405
|
-
${
|
|
1420
|
+
${h2}
|
|
1406
1421
|
`;
|
|
1407
1422
|
}
|
|
1408
1423
|
}
|
|
@@ -1424,10 +1439,10 @@ var text = (t2) => new n({
|
|
|
1424
1439
|
`, c2 = t2.placeholder ? styleText2("inverse", t2.placeholder[0]) + styleText2("dim", t2.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c2, a3 = this.value ?? "";
|
|
1425
1440
|
switch (this.state) {
|
|
1426
1441
|
case "error": {
|
|
1427
|
-
const n2 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "",
|
|
1442
|
+
const n2 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
|
|
1428
1443
|
return `${s.trim()}
|
|
1429
1444
|
${r2}${o2}
|
|
1430
|
-
${
|
|
1445
|
+
${d}${n2}
|
|
1431
1446
|
`;
|
|
1432
1447
|
}
|
|
1433
1448
|
case "submit": {
|
|
@@ -1588,11 +1603,11 @@ function capture(cmd, args, cwd) {
|
|
|
1588
1603
|
const child = onWindows ? spawn([cmd, ...args].join(" "), { cwd, shell: true }) : spawn(cmd, args, { cwd });
|
|
1589
1604
|
let stdout2 = "";
|
|
1590
1605
|
let stderr = "";
|
|
1591
|
-
child.stdout?.on("data", (
|
|
1592
|
-
stdout2 +=
|
|
1606
|
+
child.stdout?.on("data", (d) => {
|
|
1607
|
+
stdout2 += d.toString();
|
|
1593
1608
|
});
|
|
1594
|
-
child.stderr?.on("data", (
|
|
1595
|
-
stderr +=
|
|
1609
|
+
child.stderr?.on("data", (d) => {
|
|
1610
|
+
stderr += d.toString();
|
|
1596
1611
|
});
|
|
1597
1612
|
child.on("error", reject);
|
|
1598
1613
|
child.on("close", (code) => {
|
|
@@ -2023,7 +2038,7 @@ function scaffold(name, template, features, aiTools, images) {
|
|
|
2023
2038
|
"@types/react-dom": "^19.2.3",
|
|
2024
2039
|
eslint: "^10.2.0",
|
|
2025
2040
|
prettier: "^3.8.1",
|
|
2026
|
-
toilscript: "^0.1.
|
|
2041
|
+
toilscript: "^0.1.35",
|
|
2027
2042
|
typescript: "^6.0.3"
|
|
2028
2043
|
};
|
|
2029
2044
|
for (const dep of requiredPackages(features).sort()) {
|
|
@@ -2065,9 +2080,18 @@ export default defineConfig({
|
|
|
2065
2080
|
// Generated files don't need formatting. (toilscript server decorators like @main /
|
|
2066
2081
|
// @remote-on-functions are handled by the toiljs/prettier-plugin, so server/ is not ignored.)
|
|
2067
2082
|
".prettierignore": "node_modules\nbuild\n.toil\nshared/server.ts\ntoil-env.d.ts\ntoil-routes.d.ts\nserver/_emails.ts\nserver/toil-server-env.d.ts\n",
|
|
2068
|
-
".gitignore": "node_modules\nbuild\n.toil\nshared/server.ts\ntoil-env.d.ts\ntoil-routes.d.ts\n# Local dev env vars/secrets (never commit)\n.env\n.env.secrets\n",
|
|
2069
|
-
// Use the project's pinned TypeScript (node_modules) instead of VS Code's bundled
|
|
2070
|
-
|
|
2083
|
+
".gitignore": "node_modules\nbuild\n.toil\nshared/server.ts\ntoil-env.d.ts\ntoil-routes.d.ts\nhosts/*/_tmpl/\n# Local dev env vars/secrets (never commit)\n.env\n.env.secrets\n",
|
|
2084
|
+
// Use the project's pinned TypeScript (node_modules) instead of VS Code's bundled
|
|
2085
|
+
// version, and prompt to switch, so the editor loads the toilscript LS plugin wired
|
|
2086
|
+
// in server/tsconfig.json (which clears the @database / @data editor false positives).
|
|
2087
|
+
".vscode/settings.json": JSON.stringify(
|
|
2088
|
+
{
|
|
2089
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
2090
|
+
"typescript.enablePromptUseWorkspaceTsdk": true
|
|
2091
|
+
},
|
|
2092
|
+
null,
|
|
2093
|
+
4
|
|
2094
|
+
) + "\n",
|
|
2071
2095
|
"toil-env.d.ts": TOIL_ENV_DTS,
|
|
2072
2096
|
// Stub typed-routes augmentation (RoutePath = string until the first dev/build regenerates it).
|
|
2073
2097
|
"toil-routes.d.ts": "// AUTO-GENERATED by toil, do not edit.\nexport {};\n",
|
|
@@ -2118,9 +2142,15 @@ export default defineConfig({
|
|
|
2118
2142
|
null,
|
|
2119
2143
|
4
|
|
2120
2144
|
) + "\n",
|
|
2145
|
+
// The toilscript LS plugin teaches the editor about compiler-injected members
|
|
2146
|
+
// (`@database` static collections like `Db.users`, the `@data` codec, `@user`), so
|
|
2147
|
+
// stock TypeScript stops false-flagging them as TS2339. Editor-only; ignored by tsc.
|
|
2121
2148
|
"server/tsconfig.json": JSON.stringify(
|
|
2122
2149
|
{
|
|
2123
2150
|
extends: "toilscript/std/assembly.json",
|
|
2151
|
+
compilerOptions: {
|
|
2152
|
+
plugins: [{ name: "toilscript/std/ts-plugin.cjs" }]
|
|
2153
|
+
},
|
|
2124
2154
|
include: ["./**/*.ts"]
|
|
2125
2155
|
},
|
|
2126
2156
|
null,
|
|
@@ -2511,9 +2541,9 @@ import {
|
|
|
2511
2541
|
|
|
2512
2542
|
// src/cli/diagnostics.ts
|
|
2513
2543
|
function parseVersion(v) {
|
|
2514
|
-
const
|
|
2515
|
-
if (!
|
|
2516
|
-
return [Number(
|
|
2544
|
+
const m2 = /(\d+)(?:\.(\d+))?(?:\.(\d+))?/.exec(v);
|
|
2545
|
+
if (!m2) return [0, 0, 0];
|
|
2546
|
+
return [Number(m2[1]), Number(m2[2] ?? 0), Number(m2[3] ?? 0)];
|
|
2517
2547
|
}
|
|
2518
2548
|
function satisfiesMin(version2, range) {
|
|
2519
2549
|
const [a3, b, c2] = parseVersion(version2);
|
|
@@ -2684,9 +2714,9 @@ function findRelativeAssets(files) {
|
|
|
2684
2714
|
const lines = file.source.split("\n");
|
|
2685
2715
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
2686
2716
|
attr.lastIndex = 0;
|
|
2687
|
-
let
|
|
2688
|
-
while ((
|
|
2689
|
-
const value =
|
|
2717
|
+
let m2;
|
|
2718
|
+
while ((m2 = attr.exec(lines[i2])) !== null) {
|
|
2719
|
+
const value = m2[1] ?? m2[2] ?? "";
|
|
2690
2720
|
if (isBrokenRelativeAsset(value)) {
|
|
2691
2721
|
issues.push({ file: file.path, line: i2 + 1, value });
|
|
2692
2722
|
}
|
|
@@ -2840,6 +2870,27 @@ function checkRestDispatch(f) {
|
|
|
2840
2870
|
fix: "In your handler add `const hit = Rest.dispatch(req); if (hit != null) return hit;`, or set `Server.handler = () => new RestHandler()`."
|
|
2841
2871
|
};
|
|
2842
2872
|
}
|
|
2873
|
+
function checkServerTsPlugin(present) {
|
|
2874
|
+
return present ? { id: "server-ts-plugin", label: "toilscript editor plugin", status: "pass" } : {
|
|
2875
|
+
id: "server-ts-plugin",
|
|
2876
|
+
label: "toilscript editor plugin",
|
|
2877
|
+
status: "warn",
|
|
2878
|
+
detail: "server tsconfig is missing the toilscript LS plugin, so the editor wrongly flags @database static collections (e.g. GuestbookDb.totals) and @data members as TS2339",
|
|
2879
|
+
fix: 'Run `toiljs doctor --fix` to add { "plugins": [{ "name": "toilscript/std/ts-plugin.cjs" }] } to your server tsconfig, then pick the workspace TypeScript version and restart the TS server.'
|
|
2880
|
+
};
|
|
2881
|
+
}
|
|
2882
|
+
function checkAuthSecrets(f) {
|
|
2883
|
+
if (!f.usesAuth || f.sessionSecretSet) {
|
|
2884
|
+
return { id: "auth-secrets", label: "Session secret", status: "pass" };
|
|
2885
|
+
}
|
|
2886
|
+
return {
|
|
2887
|
+
id: "auth-secrets",
|
|
2888
|
+
label: "Session secret",
|
|
2889
|
+
status: "warn",
|
|
2890
|
+
detail: "auth is used but AUTH_SESSION_SECRET is unset: sessions fall back to a PUBLISHED key, so anyone can forge a session cookie and skip login",
|
|
2891
|
+
fix: `Set AUTH_SESSION_SECRET to a long random value in .env.secrets (local) and on your deploy target (also AUTH_OPRF_SEED / AUTH_KEM_SK if you use password login). Generate one: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))".`
|
|
2892
|
+
};
|
|
2893
|
+
}
|
|
2843
2894
|
function summarize(groups) {
|
|
2844
2895
|
let pass = 0;
|
|
2845
2896
|
let warn2 = 0;
|
|
@@ -2971,6 +3022,41 @@ function gatherRestFacts(root, toilconfig) {
|
|
|
2971
3022
|
}
|
|
2972
3023
|
return { hasControllers, dispatched };
|
|
2973
3024
|
}
|
|
3025
|
+
function secretDefined(root, key) {
|
|
3026
|
+
const raw = readFile(path5.join(root, ".env.secrets"));
|
|
3027
|
+
if (raw === null) return false;
|
|
3028
|
+
return new RegExp(`^\\s*(?:export\\s+)?${key}\\s*=\\s*\\S`, "m").test(raw);
|
|
3029
|
+
}
|
|
3030
|
+
function gatherAuthFacts(root, toilconfig) {
|
|
3031
|
+
let usesAuth = false;
|
|
3032
|
+
for (const src of serverSources(root, toilconfig)) {
|
|
3033
|
+
if (/\bAuthService\b/.test(src) || /@user\b/.test(src) || /@auth\b/.test(src)) {
|
|
3034
|
+
usesAuth = true;
|
|
3035
|
+
break;
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
return { usesAuth, sessionSecretSet: secretDefined(root, "AUTH_SESSION_SECRET") };
|
|
3039
|
+
}
|
|
3040
|
+
var TS_PLUGIN_NAME = "toilscript/std/ts-plugin.cjs";
|
|
3041
|
+
function serverTsconfigPath(root, toilconfig) {
|
|
3042
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
3043
|
+
const entries = Array.isArray(toilconfig?.entries) ? toilconfig.entries.filter((e) => typeof e === "string") : [];
|
|
3044
|
+
for (const e of entries) dirs.add(path5.dirname(path5.resolve(root, e)));
|
|
3045
|
+
if (dirs.size === 0) dirs.add(path5.join(root, "server"));
|
|
3046
|
+
for (const dir of dirs) {
|
|
3047
|
+
const p = path5.join(dir, "tsconfig.json");
|
|
3048
|
+
if (fs4.existsSync(p)) return p;
|
|
3049
|
+
}
|
|
3050
|
+
return null;
|
|
3051
|
+
}
|
|
3052
|
+
function tsconfigHasToilPlugin(tsconfig) {
|
|
3053
|
+
const plugins = asRecord(tsconfig?.compilerOptions)?.plugins;
|
|
3054
|
+
if (!Array.isArray(plugins)) return false;
|
|
3055
|
+
return plugins.some((p) => {
|
|
3056
|
+
const name = asRecord(p)?.name;
|
|
3057
|
+
return typeof name === "string" && name.includes("ts-plugin");
|
|
3058
|
+
});
|
|
3059
|
+
}
|
|
2974
3060
|
function applyRpcFix(root) {
|
|
2975
3061
|
const changed = [];
|
|
2976
3062
|
const skipped = [];
|
|
@@ -3158,6 +3244,50 @@ function applyPrettierFix(root, pkg) {
|
|
|
3158
3244
|
changed.push(".prettierrc.json");
|
|
3159
3245
|
return { changed, skipped };
|
|
3160
3246
|
}
|
|
3247
|
+
function applyServerEditorFix(root, toilconfig) {
|
|
3248
|
+
const changed = [];
|
|
3249
|
+
const skipped = [];
|
|
3250
|
+
const tsPath = serverTsconfigPath(root, toilconfig);
|
|
3251
|
+
if (tsPath === null) {
|
|
3252
|
+
skipped.push("server/tsconfig.json (not found; add the toilscript ts-plugin by hand)");
|
|
3253
|
+
} else {
|
|
3254
|
+
const rel = path5.relative(root, tsPath);
|
|
3255
|
+
const raw = readFile(tsPath);
|
|
3256
|
+
const parsed = raw !== null ? readJsonObject(tsPath) : null;
|
|
3257
|
+
if (parsed === null) {
|
|
3258
|
+
skipped.push(`${rel} (JSON with comments; add the "${TS_PLUGIN_NAME}" plugin by hand)`);
|
|
3259
|
+
} else if (!tsconfigHasToilPlugin(parsed)) {
|
|
3260
|
+
const co = asRecord(parsed.compilerOptions) ?? {};
|
|
3261
|
+
const existingPlugins = Array.isArray(co.plugins) ? co.plugins : [];
|
|
3262
|
+
co.plugins = [...existingPlugins, { name: TS_PLUGIN_NAME }];
|
|
3263
|
+
parsed.compilerOptions = co;
|
|
3264
|
+
writeFile(tsPath, JSON.stringify(parsed, null, 4) + "\n");
|
|
3265
|
+
changed.push(rel);
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
const vsPath = path5.join(root, ".vscode", "settings.json");
|
|
3269
|
+
const vsRaw = readFile(vsPath);
|
|
3270
|
+
const vs = vsRaw !== null ? readJsonObject(vsPath) : {};
|
|
3271
|
+
if (vs === null) {
|
|
3272
|
+
skipped.push(".vscode/settings.json (unparseable; set typescript.tsdk by hand)");
|
|
3273
|
+
} else {
|
|
3274
|
+
let touched = false;
|
|
3275
|
+
if (vs["typescript.tsdk"] !== "node_modules/typescript/lib") {
|
|
3276
|
+
vs["typescript.tsdk"] = "node_modules/typescript/lib";
|
|
3277
|
+
touched = true;
|
|
3278
|
+
}
|
|
3279
|
+
if (vs["typescript.enablePromptUseWorkspaceTsdk"] !== true) {
|
|
3280
|
+
vs["typescript.enablePromptUseWorkspaceTsdk"] = true;
|
|
3281
|
+
touched = true;
|
|
3282
|
+
}
|
|
3283
|
+
if (touched) {
|
|
3284
|
+
fs4.mkdirSync(path5.dirname(vsPath), { recursive: true });
|
|
3285
|
+
writeFile(vsPath, JSON.stringify(vs, null, 4) + "\n");
|
|
3286
|
+
changed.push(".vscode/settings.json");
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
return { changed, skipped };
|
|
3290
|
+
}
|
|
3161
3291
|
function frameworkMeta() {
|
|
3162
3292
|
const pkgPath = path5.resolve(
|
|
3163
3293
|
path5.dirname(fileURLToPath3(import.meta.url)),
|
|
@@ -3292,15 +3422,28 @@ async function runDoctor(opts) {
|
|
|
3292
3422
|
const peerChecks = Object.keys(meta.peers).map(peerName);
|
|
3293
3423
|
const rpcFix = serverPresent && opts.fix ? applyRpcFix(root) : null;
|
|
3294
3424
|
const prettierFix = serverPresent && opts.fix ? applyPrettierFix(root, projectPkg) : null;
|
|
3425
|
+
const editorFix = serverPresent && opts.fix ? applyServerEditorFix(root, toilconfig) : null;
|
|
3295
3426
|
const rpcFacts = gatherRpcFacts(root);
|
|
3296
3427
|
const restFacts = gatherRestFacts(root, toilconfig);
|
|
3428
|
+
const authFacts = gatherAuthFacts(root, toilconfig);
|
|
3297
3429
|
const prettierPresent = prettierPluginPresent(
|
|
3298
3430
|
root,
|
|
3299
3431
|
readJsonObject(path5.join(root, "package.json"))
|
|
3300
3432
|
);
|
|
3301
|
-
const
|
|
3302
|
-
|
|
3303
|
-
|
|
3433
|
+
const serverTsPath = serverPresent ? serverTsconfigPath(root, toilconfig) : null;
|
|
3434
|
+
const serverTsParsed = serverTsPath ? readJsonObject(serverTsPath) : null;
|
|
3435
|
+
const serverTsPluginPresent = serverTsPath === null || serverTsParsed === null ? true : tsconfigHasToilPlugin(serverTsParsed);
|
|
3436
|
+
const serverFix = rpcFix || prettierFix || editorFix ? {
|
|
3437
|
+
changed: [
|
|
3438
|
+
...rpcFix?.changed ?? [],
|
|
3439
|
+
...prettierFix?.changed ?? [],
|
|
3440
|
+
...editorFix?.changed ?? []
|
|
3441
|
+
],
|
|
3442
|
+
skipped: [
|
|
3443
|
+
...rpcFix?.skipped ?? [],
|
|
3444
|
+
...prettierFix?.skipped ?? [],
|
|
3445
|
+
...editorFix?.skipped ?? []
|
|
3446
|
+
]
|
|
3304
3447
|
} : null;
|
|
3305
3448
|
const groups = [
|
|
3306
3449
|
{
|
|
@@ -3358,10 +3501,14 @@ async function runDoctor(opts) {
|
|
|
3358
3501
|
checkWasmBuilt(wasmExists),
|
|
3359
3502
|
checkRpcWiring(rpcFacts),
|
|
3360
3503
|
checkRestDispatch(restFacts),
|
|
3361
|
-
checkPrettierPlugin(prettierPresent)
|
|
3504
|
+
checkPrettierPlugin(prettierPresent),
|
|
3505
|
+
checkServerTsPlugin(serverTsPluginPresent)
|
|
3362
3506
|
] : [checkToilconfig(false)]
|
|
3363
3507
|
}
|
|
3364
3508
|
];
|
|
3509
|
+
if (serverPresent) {
|
|
3510
|
+
groups.push({ title: "Security", checks: [checkAuthSecrets(authFacts)] });
|
|
3511
|
+
}
|
|
3365
3512
|
const summary = summarize(groups);
|
|
3366
3513
|
if (opts.json) {
|
|
3367
3514
|
process.stdout.write(JSON.stringify({ groups, summary, fixed: serverFix }, null, 2) + "\n");
|
|
@@ -3380,14 +3527,14 @@ async function runDoctor(opts) {
|
|
|
3380
3527
|
function renderRpcFix(result) {
|
|
3381
3528
|
const out = [];
|
|
3382
3529
|
if (result.changed.length > 0) {
|
|
3383
|
-
out.push(" " + success("fixed
|
|
3530
|
+
out.push(" " + success("fixed server wiring") + dim(` ${result.changed.join(", ")}`));
|
|
3384
3531
|
if (result.changed.includes("package.json")) {
|
|
3385
3532
|
out.push(
|
|
3386
3533
|
" " + dim("run your installer (npm/pnpm/yarn) if the toilscript version changed.")
|
|
3387
3534
|
);
|
|
3388
3535
|
}
|
|
3389
3536
|
} else {
|
|
3390
|
-
out.push(" " + dim("
|
|
3537
|
+
out.push(" " + dim("server wiring already in place, nothing to fix."));
|
|
3391
3538
|
}
|
|
3392
3539
|
for (const item of result.skipped) out.push(" " + warn("skipped") + dim(` ${item}`));
|
|
3393
3540
|
process.stdout.write(out.join("\n") + "\n\n");
|
|
@@ -3405,9 +3552,9 @@ import path6 from "node:path";
|
|
|
3405
3552
|
|
|
3406
3553
|
// src/cli/updates.ts
|
|
3407
3554
|
function parseVersion2(v) {
|
|
3408
|
-
const
|
|
3409
|
-
if (!
|
|
3410
|
-
return [Number(
|
|
3555
|
+
const m2 = /(\d+)(?:\.(\d+))?(?:\.(\d+))?/.exec(v);
|
|
3556
|
+
if (!m2) return [0, 0, 0];
|
|
3557
|
+
return [Number(m2[1]), Number(m2[2] ?? 0), Number(m2[3] ?? 0)];
|
|
3411
3558
|
}
|
|
3412
3559
|
function classifyBump(from, to) {
|
|
3413
3560
|
const [fa, fb, fc] = parseVersion2(from);
|
|
@@ -3573,9 +3720,9 @@ function isCacheFresh(cache, now, ttlMs = CHECK_TTL_MS) {
|
|
|
3573
3720
|
return cache.checkedAt <= now && now - cache.checkedAt < ttlMs;
|
|
3574
3721
|
}
|
|
3575
3722
|
function parseSemver(v) {
|
|
3576
|
-
const
|
|
3577
|
-
if (!
|
|
3578
|
-
return { nums: [Number(
|
|
3723
|
+
const m2 = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/.exec(v.trim());
|
|
3724
|
+
if (!m2) return { nums: [0, 0, 0], pre: null };
|
|
3725
|
+
return { nums: [Number(m2[1]), Number(m2[2]), Number(m2[3])], pre: m2[4] ?? null };
|
|
3579
3726
|
}
|
|
3580
3727
|
function compareSemver(a3, b) {
|
|
3581
3728
|
const pa = parseSemver(a3);
|