@sern/cli
Version:
Official CLI for @sern/handler
221 lines (220 loc) • 7.97 kB
JavaScript
import { create } from './chunk-PAIOQOOR.js';
import { mkdir, writeFile, readdir } from 'fs/promises';
import { resolve, basename, posix } from 'node:path';
import { pathExistsSync } from 'find-up';
import assert from 'assert';
import { once } from 'node:events';
import { cyanBright, redBright, greenBright } from 'colorette';
import { inspect } from 'node:util';
import ora from 'ora';
async function* readPaths(dir, shouldDebug) {
const files = await readdir(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = posix.join(dir, file.name);
if (file.isDirectory()) {
if (!file.name.startsWith("!")) {
yield* readPaths(fullPath);
}
} else if (!file.name.startsWith("!")) {
yield "file:///" + resolve(fullPath);
}
}
}
var [{ config, preloads, commandDir }] = await once(process, "message");
var { paths } = config;
for (const preload of preloads) {
console.log("preloading: ", preload);
await import("file:///" + resolve(preload));
}
var commandsPath = commandDir ? resolve(commandDir) : resolve(paths.base, paths.commands);
var filePaths = readPaths(commandsPath);
var modules = [];
var PUBLISHABLE = 14;
for await (const absPath of filePaths) {
let mod = await import(absPath);
let commandModule = mod.default;
let config2 = mod.config;
if ("default" in commandModule) {
commandModule = commandModule.default;
}
if ((PUBLISHABLE & commandModule.type) != 0) {
const filename = basename(absPath);
const filenameNoExtension = filename.substring(0, filename.lastIndexOf("."));
commandModule.name ??= filenameNoExtension;
commandModule.description ??= "";
commandModule.meta = {
absPath
};
commandModule.absPath = absPath;
if (typeof config2 === "function") {
config2 = config2(absPath, commandModule);
}
modules.push({ commandModule, config: config2 });
}
}
var cacheDir = resolve("./.sern");
if (!pathExistsSync(cacheDir)) {
await mkdir(cacheDir);
}
var optionsTransformer = (ops) => {
return ops.map((el) => {
if ("command" in el) {
const { command, ...rest2 } = el;
return rest2;
}
return el;
});
};
var intoApplicationType = (type) => {
if (type === 3) {
return 1;
}
return Math.log2(type);
};
var makeDescription = (type, desc) => {
if (type !== 1 && desc !== "") {
console.warn("Found context menu that has non empty description field. Implictly publishing with empty description");
return "";
}
return desc;
};
var serialize = (permissions) => {
if (typeof permissions === "bigint" || typeof permissions === "number") {
return permissions.toString();
}
if (Array.isArray(permissions)) {
return permissions.reduce((acc, cur) => acc | cur, BigInt(0)).toString();
}
return null;
};
var makePublishData = ({ commandModule, config: config2 }) => {
const applicationType = intoApplicationType(commandModule.type);
return {
data: {
name: commandModule.name,
type: applicationType,
description: makeDescription(applicationType, commandModule.description),
absPath: commandModule.absPath,
options: optionsTransformer(commandModule?.options ?? []),
dm_permission: config2?.dmPermission ?? false,
default_member_permissions: serialize(config2?.defaultMemberPermissions),
//@ts-ignore
integration_types: (config2?.integrationTypes ?? ["Guild"]).map(
(s) => {
if (s === "Guild") {
return "0";
} else if (s == "User") {
return "1";
} else {
throw Error("IntegrationType is not one of Guild (0) or User (1)");
}
}
),
//@ts-ignore
contexts: config2?.contexts ?? void 0,
name_localizations: commandModule.name_localizations,
description_localizations: commandModule.description_localizations
},
config: config2
};
};
var publishableData = modules.map(makePublishData);
var token = process.env.token || process.env.DISCORD_TOKEN;
assert(token, "Could not find a token for this bot in .env or commandline. Do you have DISCORD_TOKEN in env?");
var [globalCommands, guildedCommands] = publishableData.reduce(
([globals, guilded], module) => {
const isPublishableGlobally = !module.config || !Array.isArray(module.config.guildIds);
if (isPublishableGlobally) {
return [[module, ...globals], guilded];
}
return [globals, [module, ...guilded]];
},
[[], []]
);
var spin = ora(`Publishing ${cyanBright("Global")} commands`);
globalCommands.length && spin.start();
var rest = await create(token);
var res = await rest.updateGlobal(globalCommands);
var globalCommandsResponse;
if (res.ok) {
globalCommands.length && spin.succeed(`All ${cyanBright("Global")} commands published`);
globalCommandsResponse = await res.json();
} else {
spin.fail(`Failed to publish global commands [Code: ${redBright(res.status)}]`);
console.error("Status Text ", res.statusText);
switch (res.status) {
case 400: {
const validation_errors = await res.json();
console.error("errors:", inspect(validation_errors, { depth: Infinity }));
console.error("Modules with validation errors:" + inspect(Object.keys(validation_errors.errors).map((idx) => globalCommands[idx])));
throw Error("400: Ensure your commands have proper fields and data with nothing left out");
}
case 404: {
console.error("errors:", inspect(await res.json(), { depth: Infinity }));
throw Error("Forbidden 404. Is you application id and/or token correct?");
}
case 429:
{
console.error("errors:", inspect(await res.json(), { depth: Infinity }));
}
break;
default: {
console.error("errors:", inspect(await res.json(), { depth: Infinity }));
throw Error(res.status.toString() + " error");
}
}
}
function associateGuildIdsWithData(data) {
const guildIdMap = /* @__PURE__ */ new Map();
data.forEach((entry) => {
const { data: data2, config: config2 } = entry;
const { guildIds } = config2 || {};
if (guildIds) {
guildIds.forEach((guildId) => {
if (guildIdMap.has(guildId)) {
guildIdMap.get(guildId)?.push(data2);
} else {
guildIdMap.set(guildId, [data2]);
}
});
}
});
return guildIdMap;
}
var guildCommandMap = associateGuildIdsWithData(guildedCommands);
var guildCommandMapResponse = /* @__PURE__ */ new Map();
for (const [guildId, array] of guildCommandMap.entries()) {
const spin2 = ora(`[${cyanBright(guildId)}] Updating commands for guild`);
spin2.start();
const response = await rest.putGuildCommands(guildId, array);
const result = await response.json();
if (response.ok) {
guildCommandMapResponse.set(guildId, result);
spin2.succeed(`[${greenBright(guildId)}] Successfully updated commands for guild`);
} else {
spin2.fail(`[${redBright(guildId)}] Failed to update commands for guild, Reason: ${result.message}`);
switch (response.status) {
case 400: {
console.error(inspect(result, { depth: Infinity }));
console.error("Modules with validation errors:" + inspect(Object.keys(result.errors).map((idx) => array[idx])));
throw Error("400: Ensure your commands have proper fields and data and nothing left out");
}
case 404: {
console.error(inspect(result, { depth: Infinity }));
throw Error("Forbidden 404. Is you application id and/or token correct?");
}
case 429: {
console.error(inspect(result, { depth: Infinity }));
throw Error("Chill out homie, too many requests");
}
}
}
}
var remoteData = {
global: globalCommandsResponse,
...Object.fromEntries(guildCommandMapResponse)
};
await writeFile(resolve(cacheDir, "command-data-remote.json"), JSON.stringify(remoteData, null, 4), "utf8");
process.exit(0);
//# sourceMappingURL=out.js.map
//# sourceMappingURL=create-publish.js.map