@theholocron/cli 5.0.0-alpha.190 → 5.0.0-alpha.192
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/cli.mjs +71 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/plugin/capabilities.d.mts +44 -1
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -2898,11 +2898,6 @@ async function runNotificationsChannelAdd(input) {
|
|
|
2898
2898
|
*/
|
|
2899
2899
|
/** Features not built yet, in the order of the table in holocron#1098. Move an entry into a real check when it lands. */
|
|
2900
2900
|
const PLANNED_CHECKS = [
|
|
2901
|
-
{
|
|
2902
|
-
step: 10,
|
|
2903
|
-
id: "server-settings",
|
|
2904
|
-
title: "server verification, notifications and system channels set"
|
|
2905
|
-
},
|
|
2906
2901
|
{
|
|
2907
2902
|
step: 11,
|
|
2908
2903
|
id: "welcome",
|
|
@@ -2939,6 +2934,7 @@ const same = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
|
2939
2934
|
const accessKey = (v) => v === "everyone" ? "everyone" : JSON.stringify([...new Set(v.map((r) => r.toLowerCase()))].sort());
|
|
2940
2935
|
const accessText = (v) => v === "everyone" ? "everyone" : v.length === 0 ? "nobody (bots and webhooks only)" : v.join(", ");
|
|
2941
2936
|
const shown = (s) => sanitizeDetail(s);
|
|
2937
|
+
const SERVER_TITLE = "server verification, notifications and community set";
|
|
2942
2938
|
const ACCESS_TITLE = "channel and category access set";
|
|
2943
2939
|
const ROLE_APPEARANCE_TITLE = "role colour, hoist and permissions set";
|
|
2944
2940
|
const SECRETS_TITLE = "webhook URLs and role id stored as secrets";
|
|
@@ -3058,7 +3054,8 @@ async function runDoctorNotifications(input) {
|
|
|
3058
3054
|
["webhooks", "webhooks on their channels"],
|
|
3059
3055
|
["roles", "roles exist and are mentionable"],
|
|
3060
3056
|
["role-appearance", ROLE_APPEARANCE_TITLE],
|
|
3061
|
-
["access", ACCESS_TITLE]
|
|
3057
|
+
["access", ACCESS_TITLE],
|
|
3058
|
+
["server-settings", SERVER_TITLE]
|
|
3062
3059
|
]) failed(id, title, "not checked: could not read the server");
|
|
3063
3060
|
} else {
|
|
3064
3061
|
const inspected = found;
|
|
@@ -3162,6 +3159,33 @@ async function runDoctorNotifications(input) {
|
|
|
3162
3159
|
}
|
|
3163
3160
|
}
|
|
3164
3161
|
add("access", ACCESS_TITLE, inspected.rolesError && accessDeclared > 0 ? ["not checked: could not read the roles"] : accessProblems, accessDeclared === 0 ? "none declared" : `${accessDeclared} of ${accessDeclared} as declared`);
|
|
3162
|
+
const wantServer = layout.server;
|
|
3163
|
+
const serverProblems = [];
|
|
3164
|
+
if (wantServer) {
|
|
3165
|
+
if (inspected.serverError) serverProblems.push(`not checked: could not read the server settings (${shown(inspected.serverError)})`);
|
|
3166
|
+
else if (!inspected.server) serverProblems.push("the provider did not report the server's settings");
|
|
3167
|
+
else {
|
|
3168
|
+
const have = inspected.server;
|
|
3169
|
+
for (const field of [
|
|
3170
|
+
"verification",
|
|
3171
|
+
"defaultNotifications",
|
|
3172
|
+
"contentFilter",
|
|
3173
|
+
"systemChannel",
|
|
3174
|
+
"rulesChannel",
|
|
3175
|
+
"updatesChannel",
|
|
3176
|
+
"community",
|
|
3177
|
+
"description",
|
|
3178
|
+
"locale"
|
|
3179
|
+
]) {
|
|
3180
|
+
const want = wantServer[field];
|
|
3181
|
+
if (want === void 0) continue;
|
|
3182
|
+
const actual = have[field];
|
|
3183
|
+
if (!((field === "systemChannel" || field === "rulesChannel" || field === "updatesChannel") && typeof want === "string" && typeof actual === "string" ? same(want, actual) : want === actual)) serverProblems.push(`${field} is ${shown(String(actual ?? "not set"))} but the layout says ${shown(String(want))}`);
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
const serverFields = wantServer ? Object.values(wantServer).filter((v) => v !== void 0).length : 0;
|
|
3188
|
+
add("server-settings", SERVER_TITLE, serverProblems, serverFields === 0 ? "none declared" : `${serverFields} of ${serverFields} as declared`);
|
|
3165
3189
|
}
|
|
3166
3190
|
const wanted = [...declaredChannels.filter(({ channel }) => channel.webhook).map(({ channel }) => channel.webhook !== true && channel.webhook && channel.webhook.secret ? channel.webhook.secret : defaultSecretName(channel.name)), ...(layout.roles ?? []).flatMap((r) => r.secret ? [r.secret] : [])];
|
|
3167
3191
|
if (wanted.length === 0) checks.push({
|
|
@@ -3860,6 +3884,25 @@ function accessRoleProblem(layout) {
|
|
|
3860
3884
|
}
|
|
3861
3885
|
}
|
|
3862
3886
|
}
|
|
3887
|
+
/** The first problem with the layout's `server` section that needs no knowledge of the provider, or undefined. */
|
|
3888
|
+
function serverLayoutProblem(layout) {
|
|
3889
|
+
const server = layout.server;
|
|
3890
|
+
if (!server) return void 0;
|
|
3891
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3892
|
+
for (const name of (layout.categories ?? []).flatMap((c) => (c.channels ?? []).map((ch) => ch.name.toLowerCase()))) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
3893
|
+
for (const field of [
|
|
3894
|
+
"systemChannel",
|
|
3895
|
+
"rulesChannel",
|
|
3896
|
+
"updatesChannel"
|
|
3897
|
+
]) {
|
|
3898
|
+
const name = server[field];
|
|
3899
|
+
if (name === void 0) continue;
|
|
3900
|
+
const count = counts.get(name.toLowerCase()) ?? 0;
|
|
3901
|
+
if (count === 0) return `server: \`${field}\` names the channel \`${name}\`, which is not in the layout's channels`;
|
|
3902
|
+
if (count > 1) return `server: \`${field}\` names \`${name}\`, but more than one channel in the layout has that name`;
|
|
3903
|
+
}
|
|
3904
|
+
if (server.community === true && (!server.rulesChannel || !server.updatesChannel)) return "server: `community: true` needs both `rulesChannel` and `updatesChannel`";
|
|
3905
|
+
}
|
|
3863
3906
|
async function runNotificationsSetup(input) {
|
|
3864
3907
|
const print = input.print ?? ((line) => console.log(line));
|
|
3865
3908
|
const logger = input.logger ?? getLogger();
|
|
@@ -3915,10 +3958,18 @@ async function runNotificationsSetup(input) {
|
|
|
3915
3958
|
if (secretProblem) return refuse(secretProblem);
|
|
3916
3959
|
const accessProblem = accessRoleProblem(layout);
|
|
3917
3960
|
if (accessProblem) return refuse(accessProblem);
|
|
3961
|
+
const serverProblem = serverLayoutProblem(layout);
|
|
3962
|
+
if (serverProblem) return refuse(serverProblem);
|
|
3963
|
+
if (layout.server && !notifications.ensureServer) return refuse(`the layout declares \`server\` settings, but the \`${notifications.providerName}\` provider cannot manage them`);
|
|
3918
3964
|
const needsCategories = (layout.categories ?? []).find((c) => c.access);
|
|
3919
3965
|
if (needsCategories && !notifications.ensureCategory) return refuse(`category \`${needsCategories.name}\` declares \`access\`, but the \`${notifications.providerName}\` provider cannot manage categories`);
|
|
3920
3966
|
const providerProblem = notifications.validateLayout?.(layout);
|
|
3921
3967
|
if (providerProblem) return refuse(providerProblem);
|
|
3968
|
+
if (!dryRun && notifications.preflight) try {
|
|
3969
|
+
await notifications.preflight(layout);
|
|
3970
|
+
} catch (err) {
|
|
3971
|
+
return refuse(describeProviderError(err), logReason(err));
|
|
3972
|
+
}
|
|
3922
3973
|
const tally = {
|
|
3923
3974
|
ok: 0,
|
|
3924
3975
|
skip: 0
|
|
@@ -4022,6 +4073,20 @@ async function runNotificationsSetup(input) {
|
|
|
4022
4073
|
});
|
|
4023
4074
|
});
|
|
4024
4075
|
}
|
|
4076
|
+
if (layout.server) {
|
|
4077
|
+
print(`\n${style.header("Server")}`);
|
|
4078
|
+
await attempt("server settings", async () => {
|
|
4079
|
+
if (dryRun) {
|
|
4080
|
+
print(` ${style.skip("would ensure server settings")}`);
|
|
4081
|
+
tally.skip++;
|
|
4082
|
+
return;
|
|
4083
|
+
}
|
|
4084
|
+
const result = await notifications.ensureServer(layout.server);
|
|
4085
|
+
const changed = result.updated.length > 0;
|
|
4086
|
+
print(` ${(changed ? style.success : style.skip)(`${changed ? "updated" : "exists "} server settings${changed ? `: ${result.updated.join(", ")}` : ""}`)}`);
|
|
4087
|
+
made(changed);
|
|
4088
|
+
});
|
|
4089
|
+
}
|
|
4025
4090
|
if (report.failures.length > 0) report.status = "fail";
|
|
4026
4091
|
else if (dryRun) report.status = "dry-run";
|
|
4027
4092
|
print("");
|