@nectar-js/nectar 0.2.0 → 0.3.0

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-DJg1-t94.js","names":["COMMAND_TYPE","OPTION_TYPE","indent","relative","fail","relative","relative","info","info","info","info","note"],"sources":["../src/registration/targets.ts","../src/typegen/emit.ts","../src/autocomplete/compile.ts","../src/commands/validate.ts","../src/commands/compile.ts","../src/events/compile.ts","../src/compiler/chains.ts","../src/compiler/discover.ts","../src/compiler/identity.ts","../src/compiler/routes.ts","../src/compiler/graph.ts","../src/cli/ui.ts","../src/cli/compile.ts","../src/cli/io.ts","../src/cli/project.ts","../src/cli/build.ts","../src/cli/routes.ts","../src/cli/sync.ts","../src/dev/classify.ts","../src/dev/server.ts","../src/dev/watch.ts","../src/cli/dev.ts","../src/cli/manifest.ts","../src/cli/misc.ts","../src/cli/start.ts","../src/cli/index.ts"],"sourcesContent":["import type { NectarConfig } from \"../config.js\";\nimport type { Env } from \"../runtime/types.js\";\nimport type { Scope } from \"./remote.js\";\n\n/**\n * Where this environment registers commands. Development and test use `dev.guilds` only, so a\n * project without dev guilds registers nothing until some are configured. Production uses\n * `commands.target`, global by default.\n */\nexport function registrationScopes(\n config: Pick<NectarConfig, \"dev\" | \"commands\">,\n env: Env,\n): Scope[] {\n if (env !== \"production\") return (config.dev?.guilds ?? []).map((guild) => ({ guild }));\n const target = config.commands?.target ?? \"global\";\n return target === \"global\" ? [\"global\"] : target.map((guild) => ({ guild }));\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { ApplicationCommandOptionType, ApplicationCommandType } from \"discord-api-types/v10\";\nimport type { RouteGraph } from \"../compiler/graph.js\";\nimport type { Route } from \"../compiler/routes.js\";\nimport { type NectarPlugin, PluginError, pluginGraph } from \"../plugins/index.js\";\n\nexport const TYPES_FILE = \"types.d.ts\";\n\nconst PACKAGE = \"@nectar-js/nectar\";\n\nconst COMMAND_TYPE: Record<number, string> = {\n [ApplicationCommandType.ChatInput]: \"chatInput\",\n [ApplicationCommandType.User]: \"user\",\n [ApplicationCommandType.Message]: \"message\",\n};\n\nconst OPTION_TYPE: Record<number, string> = {\n [ApplicationCommandOptionType.String]: \"string\",\n [ApplicationCommandOptionType.Integer]: \"integer\",\n [ApplicationCommandOptionType.Number]: \"number\",\n [ApplicationCommandOptionType.Boolean]: \"boolean\",\n [ApplicationCommandOptionType.User]: \"user\",\n [ApplicationCommandOptionType.Channel]: \"channel\",\n [ApplicationCommandOptionType.Role]: \"role\",\n [ApplicationCommandOptionType.Mentionable]: \"mentionable\",\n [ApplicationCommandOptionType.Attachment]: \"attachment\",\n};\n\n/**\n * Renders `types.d.ts`: a module augmentation of `@nectar-js/nectar` that lists every route with\n * its parameters, options, and the context its middleware chain adds. Handler and middleware\n * types are pulled in with `import()` type queries relative to `outDir`. Whatever a plugin's\n * `types` hook returns is appended after the augmentation.\n */\nexport function toTypes(\n graph: RouteGraph,\n outDir: string,\n plugins: readonly NectarPlugin[] = [],\n): string {\n const absoluteOut = path.resolve(outDir);\n const middlewareAliases = new Map<string, string>();\n const aliasFor = (file: string): string => {\n let alias = middlewareAliases.get(file);\n if (alias === undefined) {\n alias = `M${middlewareAliases.size}`;\n middlewareAliases.set(file, alias);\n }\n return alias;\n };\n const contextOf = (route: Route): string => {\n const files = graph.chains.get(route.file)?.middleware ?? [];\n return files.length === 0 ? \"{}\" : files.map(aliasFor).join(\" & \");\n };\n\n const commands: string[] = [];\n for (const command of [...graph.commands].sort((a, b) => a.name.localeCompare(b.name))) {\n for (const [key, route] of Object.entries(command.handlers)) {\n const options = Object.entries(optionsAt(command.payload, key))\n .map(([name, type]) => `${quote(name)}: ${quote(type)}`)\n .join(\"; \");\n commands.push(\n ` ${quote(route.path)}: { type: ${quote(COMMAND_TYPE[command.type] ?? \"chatInput\")}; options: {${options === \"\" ? \"\" : ` ${options} `}}; context: ${contextOf(route)} };`,\n );\n }\n }\n commands.sort();\n\n // The compiler allows one handler per component path, so each path has one kind.\n const components = [...graph.components]\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((route) => {\n const params = route.params\n .map((name) => `${quote(name)}: ${name === route.catchAll ? \"string[]\" : \"string\"}`)\n .join(\"; \");\n const kind = route.kind === \"select\" ? `select:${route.selectKind}` : route.kind;\n return ` ${quote(route.path)}: { kind: ${quote(kind)}; params: {${params === \"\" ? \"\" : ` ${params} `}}; context: ${contextOf(route)} };`;\n });\n\n const events = graph.events.map((e) => ` ${quote(e.name)}: true;`);\n const autocomplete = graph.autocomplete\n .map((a) => ` ${quote(a.route.path)}: ${a.options.map(quote).join(\" | \") || \"never\"};`)\n .sort();\n\n const aliases = [...middlewareAliases].map(\n ([file, alias]) =>\n `type ${alias} = MiddlewareExtension<typeof import(${quote(importPath(absoluteOut, file))})>;`,\n );\n\n return [\n \"// Generated by Nectar. Do not edit.\",\n `import type { MiddlewareExtension } from ${quote(PACKAGE)};`,\n ...(aliases.length === 0 ? [] : [\"\", ...aliases]),\n \"\",\n `declare module ${quote(PACKAGE)} {`,\n \" interface NectarRoutes {\",\n \" commands: {\",\n ...commands.map(indent),\n \" };\",\n \" components: {\",\n ...components.map(indent),\n \" };\",\n \" events: {\",\n ...events.map(indent),\n \" };\",\n \" autocomplete: {\",\n ...autocomplete.map(indent),\n \" };\",\n \" }\",\n \"}\",\n \"\",\n \"export {};\",\n \"\",\n ...pluginTypes(graph, plugins),\n ].join(\"\\n\");\n}\n\nfunction pluginTypes(graph: RouteGraph, plugins: readonly NectarPlugin[]): string[] {\n const lines: string[] = [];\n for (const plugin of plugins) {\n if (plugin.types === undefined) continue;\n let extra: unknown;\n try {\n extra = plugin.types(pluginGraph(graph));\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new PluginError(plugin.name, `types failed: ${detail}`);\n }\n if (typeof extra !== \"string\" || extra.trim() === \"\") continue;\n lines.push(`// From plugin ${JSON.stringify(plugin.name)}`, extra.trim(), \"\");\n }\n return lines;\n}\n\nexport function writeTypes(\n graph: RouteGraph,\n outDir: string,\n plugins: readonly NectarPlugin[] = [],\n): string {\n mkdirSync(outDir, { recursive: true });\n const file = path.join(outDir, TYPES_FILE);\n writeFileSync(file, toTypes(graph, outDir, plugins));\n return file;\n}\n\ninterface PayloadNode {\n name?: string;\n type?: number;\n options?: PayloadNode[];\n}\n\n/** Option name to option type name for one handler position of a command payload. */\nfunction optionsAt(payload: unknown, key: string): Record<string, string> {\n let options = (payload as PayloadNode).options;\n for (const part of key === \"\" ? [] : key.split(\"/\")) {\n options = options?.find((o) => o.name === part)?.options;\n }\n const out: Record<string, string> = {};\n for (const option of options ?? []) {\n const type = option.type === undefined ? undefined : OPTION_TYPE[option.type];\n if (option.name !== undefined && type !== undefined) out[option.name] = type;\n }\n return out;\n}\n\n/** `../app/middleware.ts` becomes `../app/middleware.js`, which NodeNext resolves back to the source. */\nfunction importPath(fromDir: string, file: string): string {\n const relative = path.relative(fromDir, file).split(path.sep).join(\"/\");\n const mapped = relative.replace(/\\.mts$/, \".mjs\").replace(/\\.ts$/, \".js\");\n return mapped.startsWith(\".\") ? mapped : `./${mapped}`;\n}\n\nfunction quote(value: string): string {\n return JSON.stringify(value);\n}\n\nfunction indent(line: string): string {\n return ` ${line}`;\n}\n","import path from \"node:path\";\nimport type { CompiledCommand } from \"../commands/compile.js\";\nimport { Diagnostics } from \"../compiler/diagnostics.js\";\nimport { loadModule } from \"../compiler/load.js\";\nimport type { Route, RouteTable } from \"../compiler/routes.js\";\n\nexport interface CompiledAutocomplete {\n /** The `autocomplete.ts` route. Shares its identity with the sibling `command.ts`. */\n route: Route;\n /** The command route these handlers serve. */\n command: Route;\n /** Option names with a handler, sorted. Each is a named export of the file. */\n options: string[];\n}\n\nexport interface CompiledAutocompletes {\n autocomplete: CompiledAutocomplete[];\n diagnostics: Diagnostics;\n}\n\n/**\n * Links every `autocomplete.ts` to its sibling command and checks that each named export\n * matches an option declared with `autocomplete: true`, and that no such option is left\n * without a handler.\n */\nexport async function compileAutocomplete(\n table: RouteTable,\n commands: CompiledCommand[],\n): Promise<CompiledAutocompletes> {\n const diagnostics = new Diagnostics();\n const routes = table.routes.filter((r) => r.kind === \"autocomplete\");\n\n const targets = new Map<string, { command: Route; options: Set<string> }>();\n for (const command of commands) {\n for (const [key, route] of Object.entries(command.handlers)) {\n targets.set(route.id, { command: route, options: autocompleteOptions(command, key) });\n }\n }\n\n const results = await Promise.all(\n routes.map(async (route): Promise<CompiledAutocomplete | null> => {\n const target = targets.get(route.id);\n if (target === undefined) {\n // A command.ts that failed to compile has its own diagnostic already.\n if (table.routes.some((r) => r.id === route.id && r.kind === \"command\")) return null;\n diagnostics.error(\n \"autocomplete-without-command\",\n \"There's no command.ts next to this autocomplete.ts. Autocomplete answers the options of the command in the same directory, so move it next to that command.ts.\",\n { file: route.file, route: route.id },\n );\n return null;\n }\n\n let module: Record<string, unknown>;\n try {\n module = await loadModule(route.file);\n } catch (error) {\n diagnostics.error(\n \"module-load-failed\",\n `The compiler imports every route file to read its exports, and this one threw: ${error instanceof Error ? error.message : String(error)}`,\n { file: route.file, route: route.id },\n );\n return null;\n }\n\n const exported = Object.keys(module)\n .filter((name) => name !== \"default\")\n .sort();\n let ok = true;\n\n for (const name of exported) {\n if (typeof module[name] !== \"function\") {\n diagnostics.error(\n \"autocomplete-export-not-function\",\n `Export \"${name}\" isn't a function. Each export of autocomplete.ts is a function that answers the option with the same name.`,\n { file: route.file, route: route.id },\n );\n ok = false;\n continue;\n }\n if (!target.options.has(name)) {\n diagnostics.error(\n \"autocomplete-unknown-option\",\n `Export \"${name}\" doesn't match an option with autocomplete: true in ${relative(target.command.file)}. ${expected(target.options)} Rename the export, or set autocomplete: true on the option.`,\n { file: route.file, route: route.id },\n );\n ok = false;\n }\n }\n\n for (const name of [...target.options].sort()) {\n if (exported.includes(name)) continue;\n diagnostics.error(\n \"autocomplete-missing-handler\",\n `Option \"${name}\" has autocomplete: true, but this file doesn't export a function named \"${name}\" to answer it.`,\n { file: route.file, route: route.id },\n );\n ok = false;\n }\n\n return ok ? { route, command: target.command, options: exported } : null;\n }),\n );\n\n for (const [id, target] of targets) {\n if (target.options.size === 0 || routes.some((r) => r.id === id)) continue;\n const names = [...target.options].map((o) => `\"${o}\"`);\n diagnostics.error(\n \"autocomplete-missing-file\",\n names.length === 1\n ? `Option ${names[0]} has autocomplete: true, but there's no autocomplete.ts next to this command. Add one that exports a function named ${names[0]}.`\n : `Options ${new Intl.ListFormat(\"en\").format(names)} have autocomplete: true, but there's no autocomplete.ts next to this command. Add one that exports a function named after each of them.`,\n { file: target.command.file, route: id },\n );\n }\n\n return {\n autocomplete: results.filter((r): r is CompiledAutocomplete => r !== null),\n diagnostics,\n };\n}\n\n/** Names of the options with `autocomplete: true` for one handler position of a command. */\nfunction autocompleteOptions(command: CompiledCommand, key: string): Set<string> {\n let options = (command.payload as PayloadNode).options;\n for (const part of key === \"\" ? [] : key.split(\"/\")) {\n options = options?.find((o) => o.name === part)?.options;\n }\n return new Set(\n (options ?? []).filter((o) => o.autocomplete === true).map((o) => o.name as string),\n );\n}\n\n/** The parts of a registration payload the option walk needs. */\ninterface PayloadNode {\n name?: string;\n autocomplete?: boolean;\n options?: PayloadNode[];\n}\n\nfunction expected(options: Set<string>): string {\n const names = [...options].sort().map((o) => `\"${o}\"`);\n if (names.length === 0) return \"That command has no autocomplete options.\";\n return names.length === 1\n ? `Its autocomplete option is ${names[0]}.`\n : `Its autocomplete options are ${new Intl.ListFormat(\"en\").format(names)}.`;\n}\n\nfunction relative(file: string): string {\n return path.relative(process.cwd(), file).split(path.sep).join(\"/\");\n}\n","import { type DiagnosticCode, type Diagnostics, typeOf } from \"../compiler/diagnostics.js\";\nimport type { CommandMeta, CommandOption, CommandRouteMeta, OptionChoice } from \"./meta.js\";\n\nexport const COMMAND_NAME = /^[-_\\p{L}\\p{N}\\p{sc=Deva}\\p{sc=Thai}]{1,32}$/u;\n\nconst OPTION_TYPES = new Set([\n \"string\",\n \"integer\",\n \"number\",\n \"boolean\",\n \"user\",\n \"channel\",\n \"role\",\n \"mentionable\",\n \"attachment\",\n]);\n\nconst COMMAND_TYPES = new Set([\"chatInput\", \"user\", \"message\"]);\n\nconst TOP_LEVEL_KEYS = [\n \"defaultMemberPermissions\",\n \"nsfw\",\n \"contexts\",\n \"integrationTypes\",\n] as const;\n\ninterface Ctx {\n diagnostics: Diagnostics;\n file: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Validates the `meta` export of a `command.ts`. Returns null after reporting when unusable. */\nexport function validateCommandMeta(\n value: unknown,\n file: string,\n diagnostics: Diagnostics,\n): CommandMeta | null {\n const ctx = { diagnostics, file };\n if (value === undefined) {\n diagnostics.error(\n \"missing-meta\",\n 'This command.ts doesn\\'t export meta. Discord needs a description for every slash command, so add export const meta = { description: \"...\" }. A context menu command sets type instead, like { type: \"user\" }.',\n { file },\n );\n return null;\n }\n if (!isRecord(value)) {\n fail(\n ctx,\n \"invalid-meta\",\n `meta is ${typeOf(value)}. Export an object, like { description: \"...\" }.`,\n );\n return null;\n }\n\n let ok = true;\n const type = value.type ?? \"chatInput\";\n if (typeof type !== \"string\" || !COMMAND_TYPES.has(type)) {\n ok = fail(\n ctx,\n \"invalid-meta\",\n `meta.type is ${JSON.stringify(type)}. Use \"chatInput\" for a slash command, or \"user\" or \"message\" for a context menu command.`,\n );\n }\n\n if (value.name !== undefined)\n ok = checkName(ctx, value.name, \"meta.name\", type === \"chatInput\") && ok;\n\n if (type === \"chatInput\") {\n ok = checkDescription(ctx, value.description, \"meta.description\") && ok;\n if (value.options !== undefined) ok = checkOptions(ctx, value.options) && ok;\n } else {\n if (value.description !== undefined && value.description !== \"\") {\n ok = fail(\n ctx,\n \"invalid-meta\",\n \"Discord doesn't allow a description on context menu commands. Remove meta.description.\",\n );\n }\n if (value.options !== undefined) {\n ok = fail(\n ctx,\n \"invalid-meta\",\n \"Discord doesn't allow options on context menu commands. Remove meta.options.\",\n );\n }\n }\n\n ok = checkLocalizations(ctx, value.nameLocalizations, \"meta.nameLocalizations\") && ok;\n ok =\n checkLocalizations(ctx, value.descriptionLocalizations, \"meta.descriptionLocalizations\") && ok;\n ok = checkTopLevel(ctx, value) && ok;\n\n return ok ? (value as unknown as CommandMeta) : null;\n}\n\n/** Validates the `meta` export of a `route.ts` under `commands/`. */\nexport function validateCommandRouteMeta(\n value: unknown,\n file: string,\n diagnostics: Diagnostics,\n): CommandRouteMeta | null {\n const ctx = { diagnostics, file };\n if (value === undefined) {\n diagnostics.error(\n \"missing-meta\",\n 'This route.ts doesn\\'t export meta. It holds the description Discord shows for the command or subcommand group, so add export const meta = { description: \"...\" }.',\n { file },\n );\n return null;\n }\n if (!isRecord(value)) {\n fail(\n ctx,\n \"invalid-meta\",\n `meta is ${typeOf(value)}. Export an object, like { description: \"...\" }.`,\n );\n return null;\n }\n let ok = checkDescription(ctx, value.description, \"meta.description\");\n if (value.name !== undefined) ok = checkName(ctx, value.name, \"meta.name\", true) && ok;\n ok = checkLocalizations(ctx, value.nameLocalizations, \"meta.nameLocalizations\") && ok;\n ok =\n checkLocalizations(ctx, value.descriptionLocalizations, \"meta.descriptionLocalizations\") && ok;\n ok = checkTopLevel(ctx, value) && ok;\n return ok ? (value as unknown as CommandRouteMeta) : null;\n}\n\n/** Reports any top-level-only field so callers can reject them on nested commands. */\nexport function topLevelKeysUsed(meta: object): string[] {\n return TOP_LEVEL_KEYS.filter(\n (key) => key in meta && (meta as Record<string, unknown>)[key] !== undefined,\n );\n}\n\nfunction fail(ctx: Ctx, code: DiagnosticCode, message: string): false {\n ctx.diagnostics.error(code, message, { file: ctx.file });\n return false;\n}\n\n/** What a text field holds, for length errors: `empty`, `140 characters`, or its type. */\nfunction sizeOf(value: unknown): string {\n if (typeof value !== \"string\") return typeOf(value);\n return value === \"\" ? \"empty\" : `${value.length} characters`;\n}\n\nfunction checkName(ctx: Ctx, name: unknown, label: string, chatInput: boolean): boolean {\n if (typeof name !== \"string\" || name.length === 0 || name.length > 32) {\n return fail(\n ctx,\n \"invalid-name\",\n `${label} is ${sizeOf(name)}. Discord needs a name of 1 to 32 characters.`,\n );\n }\n if (chatInput) {\n if (!COMMAND_NAME.test(name) || name !== name.toLowerCase()) {\n return fail(\n ctx,\n \"invalid-name\",\n `${label} is \"${name}\". Discord only allows lowercase letters, digits, hyphens, and underscores in slash command and option names.`,\n );\n }\n }\n return true;\n}\n\nfunction checkDescription(ctx: Ctx, description: unknown, label: string): boolean {\n if (typeof description !== \"string\" || description.length === 0 || description.length > 100) {\n return fail(\n ctx,\n \"invalid-description\",\n `${label} is ${sizeOf(description)}. Discord needs a description of 1 to 100 characters.`,\n );\n }\n return true;\n}\n\nfunction checkLocalizations(ctx: Ctx, value: unknown, label: string): boolean {\n if (value === undefined) return true;\n if (!isRecord(value)) {\n return fail(\n ctx,\n \"invalid-meta\",\n `${label} is ${typeOf(value)}. Use an object of locale to text, like { fr: \"...\" }.`,\n );\n }\n for (const [locale, text] of Object.entries(value)) {\n if (typeof text !== \"string\") {\n return fail(ctx, \"invalid-meta\", `${label}.${locale} is ${typeOf(text)}, not a string.`);\n }\n }\n return true;\n}\n\nfunction checkTopLevel(ctx: Ctx, value: Record<string, unknown>): boolean {\n let ok = true;\n const perms = value.defaultMemberPermissions;\n if (\n perms !== undefined &&\n perms !== null &&\n typeof perms !== \"bigint\" &&\n typeof perms !== \"string\" &&\n typeof perms !== \"number\"\n ) {\n ok = fail(\n ctx,\n \"invalid-meta\",\n `meta.defaultMemberPermissions is ${typeOf(perms)}. Use a permission bitfield, like PermissionFlagsBits.BanMembers from discord.js, or null.`,\n );\n }\n if (value.nsfw !== undefined && typeof value.nsfw !== \"boolean\") {\n ok = fail(ctx, \"invalid-meta\", `meta.nsfw is ${typeOf(value.nsfw)}. Use true or false.`);\n }\n ok =\n checkEnumArray(ctx, value.contexts, \"meta.contexts\", \"InteractionContextType\", [0, 1, 2]) && ok;\n ok =\n checkEnumArray(\n ctx,\n value.integrationTypes,\n \"meta.integrationTypes\",\n \"ApplicationIntegrationType\",\n [0, 1],\n ) && ok;\n return ok;\n}\n\nfunction checkEnumArray(\n ctx: Ctx,\n value: unknown,\n label: string,\n enumName: string,\n allowed: number[],\n): boolean {\n if (value === undefined) return true;\n if (!Array.isArray(value) || value.some((v) => !allowed.includes(v))) {\n return fail(\n ctx,\n \"invalid-meta\",\n `${label} has to be an array of ${enumName} values from discord.js.`,\n );\n }\n return true;\n}\n\nfunction checkOptions(ctx: Ctx, options: unknown): boolean {\n if (!Array.isArray(options)) {\n return fail(ctx, \"invalid-option\", `meta.options is ${typeOf(options)}, not an array.`);\n }\n if (options.length > 25) {\n return fail(\n ctx,\n \"invalid-option\",\n `meta.options has ${options.length} options. Discord allows 25 per command.`,\n );\n }\n let ok = true;\n const names = new Set<string>();\n let seenOptional = false;\n for (const [index, option] of options.entries()) {\n const label = `meta.options[${index}]`;\n if (!isRecord(option)) {\n ok = fail(ctx, \"invalid-option\", `${label} is ${typeOf(option)}, not an object.`);\n continue;\n }\n const typedOk = checkOption(ctx, option, label);\n ok = typedOk && ok;\n if (!typedOk) continue;\n const typed = option as unknown as CommandOption;\n if (names.has(typed.name)) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label} reuses the name \"${typed.name}\". Discord needs option names to be unique within a command.`,\n );\n }\n names.add(typed.name);\n if (typed.required) {\n if (seenOptional) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}, \"${typed.name}\", is required but comes after an optional option. Discord needs required options first, so move it up.`,\n );\n }\n } else {\n seenOptional = true;\n }\n }\n return ok;\n}\n\n/** The option types each type-specific field works on. */\nconst FIELD_TYPES: Record<string, readonly string[]> = {\n choices: [\"string\", \"integer\", \"number\"],\n autocomplete: [\"string\", \"integer\", \"number\"],\n minLength: [\"string\"],\n maxLength: [\"string\"],\n minValue: [\"integer\", \"number\"],\n maxValue: [\"integer\", \"number\"],\n channelTypes: [\"channel\"],\n};\n\nconst quoted = (items: Iterable<string>, type: \"conjunction\" | \"disjunction\") =>\n new Intl.ListFormat(\"en\", { type }).format([...items].map((item) => `\"${item}\"`));\n\nfunction checkOption(ctx: Ctx, option: Record<string, unknown>, label: string): boolean {\n let ok = true;\n if (typeof option.type !== \"string\" || !OPTION_TYPES.has(option.type)) {\n return fail(\n ctx,\n \"invalid-option\",\n `${label}.type is ${option.type === undefined ? \"missing\" : JSON.stringify(option.type)}. Use ${quoted(OPTION_TYPES, \"disjunction\")}.`,\n );\n }\n ok = checkName(ctx, option.name, `${label}.name`, true) && ok;\n ok = checkDescription(ctx, option.description, `${label}.description`) && ok;\n if (option.required !== undefined && typeof option.required !== \"boolean\") {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.required is ${typeOf(option.required)}. Use true or false.`,\n );\n }\n ok = checkLocalizations(ctx, option.nameLocalizations, `${label}.nameLocalizations`) && ok;\n ok =\n checkLocalizations(ctx, option.descriptionLocalizations, `${label}.descriptionLocalizations`) &&\n ok;\n\n const type = option.type;\n for (const [key, types] of Object.entries(FIELD_TYPES)) {\n if (option[key] === undefined || types.includes(type)) continue;\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.${key} only works on ${quoted(types, \"conjunction\")} options, and this one is \"${type}\".`,\n );\n }\n\n if (option.autocomplete !== undefined && typeof option.autocomplete !== \"boolean\") {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.autocomplete is ${typeOf(option.autocomplete)}. Use true or false.`,\n );\n }\n if (option.choices !== undefined) {\n if (option.autocomplete === true) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label} has both choices and autocomplete. Discord allows one or the other.`,\n );\n }\n ok = checkChoices(ctx, option.choices, `${label}.choices`, type === \"string\") && ok;\n }\n for (const key of [\"minLength\", \"maxLength\", \"minValue\", \"maxValue\"]) {\n const v = option[key];\n if (v !== undefined && typeof v !== \"number\") {\n ok = fail(ctx, \"invalid-option\", `${label}.${key} is ${typeOf(v)}, not a number.`);\n }\n }\n if (typeof option.minLength === \"number\" && (option.minLength < 0 || option.minLength > 6000)) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.minLength is ${option.minLength}. Discord allows 0 to 6000.`,\n );\n }\n if (typeof option.maxLength === \"number\" && (option.maxLength < 1 || option.maxLength > 6000)) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.maxLength is ${option.maxLength}. Discord allows 1 to 6000.`,\n );\n }\n if (option.channelTypes !== undefined) {\n if (\n !Array.isArray(option.channelTypes) ||\n option.channelTypes.some((c) => typeof c !== \"number\")\n ) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${label}.channelTypes has to be an array of ChannelType values from discord.js.`,\n );\n }\n }\n return ok;\n}\n\nfunction checkChoices(ctx: Ctx, choices: unknown, label: string, isString: boolean): boolean {\n if (!Array.isArray(choices)) {\n return fail(ctx, \"invalid-option\", `${label} is ${typeOf(choices)}, not an array.`);\n }\n if (choices.length > 25) {\n return fail(\n ctx,\n \"invalid-option\",\n `${label} has ${choices.length} entries. Discord allows 25 per option.`,\n );\n }\n let ok = true;\n for (const [index, choice] of choices.entries()) {\n const at = `${label}[${index}]`;\n if (!isRecord(choice)) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${at} is ${typeOf(choice)}. Each choice is an object like { name: \"Red\", value: \"red\" }.`,\n );\n continue;\n }\n const typed = choice as Partial<OptionChoice>;\n if (typeof typed.name !== \"string\" || typed.name.length === 0 || typed.name.length > 100) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${at}.name is ${sizeOf(typed.name)}. Discord needs a name of 1 to 100 characters.`,\n );\n }\n if (isString) {\n if (typeof typed.value !== \"string\" || typed.value.length === 0 || typed.value.length > 100) {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${at}.value is ${sizeOf(typed.value)}. A string option's choices need a value of 1 to 100 characters.`,\n );\n }\n } else if (typeof typed.value !== \"number\") {\n ok = fail(\n ctx,\n \"invalid-option\",\n `${at}.value is ${typeOf(typed.value)}. A numeric option's choices need a number value.`,\n );\n }\n ok = checkLocalizations(ctx, typed.nameLocalizations, `${at}.nameLocalizations`) && ok;\n }\n return ok;\n}\n","import path from \"node:path\";\nimport {\n ApplicationCommandOptionType,\n ApplicationCommandType,\n type RESTPostAPIApplicationCommandsJSONBody,\n} from \"discord-api-types/v10\";\nimport { Diagnostics } from \"../compiler/diagnostics.js\";\nimport { loadModule } from \"../compiler/load.js\";\nimport type { Boundary, Route, RouteTable } from \"../compiler/routes.js\";\nimport { formatSegment } from \"../compiler/segments.js\";\nimport { checkHandler } from \"../components/compile.js\";\nimport type { CommandMeta, CommandOption, CommandRouteMeta, TopLevelMeta } from \"./meta.js\";\nimport { topLevelKeysUsed, validateCommandMeta, validateCommandRouteMeta } from \"./validate.js\";\n\nexport interface CompiledCommand {\n name: string;\n type: ApplicationCommandType;\n /**\n * Handler routes keyed by their position inside the command, using the registered names:\n * `\"\"` for a plain command, `\"ban\"` for a subcommand, `\"group/sub\"` inside a subcommand group.\n */\n handlers: Record<string, Route>;\n payload: RESTPostAPIApplicationCommandsJSONBody;\n /** Every file that contributed to this command. */\n files: string[];\n}\n\nexport interface CompiledCommands {\n commands: CompiledCommand[];\n diagnostics: Diagnostics;\n}\n\nconst OPTION_TYPE: Record<CommandOption[\"type\"], ApplicationCommandOptionType> = {\n string: ApplicationCommandOptionType.String,\n integer: ApplicationCommandOptionType.Integer,\n number: ApplicationCommandOptionType.Number,\n boolean: ApplicationCommandOptionType.Boolean,\n user: ApplicationCommandOptionType.User,\n channel: ApplicationCommandOptionType.Channel,\n role: ApplicationCommandOptionType.Role,\n mentionable: ApplicationCommandOptionType.Mentionable,\n attachment: ApplicationCommandOptionType.Attachment,\n};\n\nconst COMMAND_TYPE = {\n chatInput: ApplicationCommandType.ChatInput,\n user: ApplicationCommandType.User,\n message: ApplicationCommandType.Message,\n} as const;\n\nconst TYPE_LABEL: Record<number, string> = {\n [ApplicationCommandType.ChatInput]: \"slash command\",\n [ApplicationCommandType.User]: \"user context menu command\",\n [ApplicationCommandType.Message]: \"message context menu command\",\n};\n\n/** How many commands of each type Discord takes, globally and in each server. */\nconst COMMAND_LIMITS: Record<number, number> = {\n [ApplicationCommandType.ChatInput]: 100,\n [ApplicationCommandType.User]: 15,\n [ApplicationCommandType.Message]: 15,\n};\n\ninterface LoadedRoute {\n route: Route;\n parts: string[];\n meta: CommandMeta;\n}\n\ninterface LoadedRouteMeta {\n boundary: Boundary;\n meta: CommandRouteMeta;\n used: boolean;\n}\n\n/** Compiles the command routes of a route table into Discord command definitions. */\nexport async function compileCommands(table: RouteTable): Promise<CompiledCommands> {\n const diagnostics = new Diagnostics();\n const commands: CompiledCommand[] = [];\n\n const [loaded, routeMetas] = await Promise.all([\n loadRoutes(table.routes, diagnostics),\n loadRouteMetas(table.boundaries, diagnostics),\n ]);\n\n const byTopLevel = new Map<string, LoadedRoute[]>();\n for (const entry of loaded) {\n const top = entry.parts[0] as string;\n byTopLevel.set(top, [...(byTopLevel.get(top) ?? []), entry]);\n }\n\n for (const [top, entries] of [...byTopLevel].sort(([a], [b]) => a.localeCompare(b))) {\n const command = compileTopLevel(top, entries, routeMetas, diagnostics);\n if (command !== null) commands.push(command);\n }\n\n for (const entry of routeMetas.values()) {\n if (!entry.used) {\n diagnostics.warn(\n \"unused-route-meta\",\n \"This route.ts has no effect because there are no subcommands below it. A plain command's meta goes in its command.ts.\",\n { file: entry.boundary.file },\n );\n }\n }\n\n detectDuplicateNames(commands, diagnostics);\n checkLimits(commands, diagnostics);\n commands.sort((a, b) => a.type - b.type || a.name.localeCompare(b.name));\n return { commands, diagnostics };\n}\n\nfunction checkLimits(commands: CompiledCommand[], diagnostics: Diagnostics): void {\n for (const [type, limit] of Object.entries(COMMAND_LIMITS)) {\n const ofType = commands.filter((c) => c.type === Number(type));\n const first = ofType[0];\n if (first === undefined || ofType.length <= limit) continue;\n const slash = Number(type) === ApplicationCommandType.ChatInput;\n diagnostics.error(\n \"too-many-commands\",\n `The app has ${ofType.length} ${TYPE_LABEL[Number(type)]}s, and Discord allows ${limit}, globally and in each server. ${slash ? \"Subcommands don't count toward it, so group related commands under one.\" : \"Remove some.\"}`,\n { file: commandsDir(first) },\n );\n }\n}\n\n/** The `commands/` directory, found by walking up from one of the command's handlers. */\nfunction commandsDir(command: CompiledCommand): string {\n const route = Object.values(command.handlers)[0] as Route;\n let dir = path.dirname(route.file);\n for (let i = 0; i < route.segments.length; i++) dir = path.dirname(dir);\n return dir;\n}\n\nasync function loadRoutes(routes: Route[], diagnostics: Diagnostics): Promise<LoadedRoute[]> {\n const commandRoutes = routes.filter((r) => r.kind === \"command\");\n const results = await Promise.all(\n commandRoutes.map(async (route): Promise<LoadedRoute | null> => {\n const module = await importOrReport(route.file, diagnostics);\n if (module === null) return null;\n if (!checkHandler(module, route, diagnostics)) return null;\n const meta = validateCommandMeta(module.meta, route.file, diagnostics);\n if (meta === null) return null;\n return { route, parts: route.path.split(\"/\"), meta };\n }),\n );\n return results.filter((r): r is LoadedRoute => r !== null);\n}\n\nasync function loadRouteMetas(\n boundaries: Boundary[],\n diagnostics: Diagnostics,\n): Promise<Map<string, LoadedRouteMeta>> {\n const map = new Map<string, LoadedRouteMeta>();\n const relevant = boundaries.filter((b) => b.kind === \"route\" && b.category === \"command\");\n await Promise.all(\n relevant.map(async (boundary) => {\n const key = boundary.segments\n .filter((s) => s.type !== \"group\")\n .map(formatSegment)\n .join(\"/\");\n if (key === \"\") {\n diagnostics.error(\n \"route-meta-without-path\",\n \"This route.ts isn't inside a command's directory, so it doesn't describe a command. Move it into the command's directory, like commands/moderation/route.ts.\",\n { file: boundary.file },\n );\n return;\n }\n const module = await importOrReport(boundary.file, diagnostics);\n if (module === null) return;\n const meta = validateCommandRouteMeta(module.meta, boundary.file, diagnostics);\n if (meta === null) return;\n map.set(key, { boundary, meta, used: false });\n }),\n );\n return map;\n}\n\nasync function importOrReport(\n file: string,\n diagnostics: Diagnostics,\n): Promise<Record<string, unknown> | null> {\n try {\n return await loadModule(file);\n } catch (error) {\n diagnostics.error(\n \"module-load-failed\",\n `The compiler imports every route file to read its exports, and this one threw: ${error instanceof Error ? error.message : String(error)}`,\n { file },\n );\n return null;\n }\n}\n\nfunction compileTopLevel(\n top: string,\n entries: LoadedRoute[],\n routeMetas: Map<string, LoadedRouteMeta>,\n diagnostics: Diagnostics,\n): CompiledCommand | null {\n const direct = entries.filter((e) => e.parts.length === 1);\n const nested = entries.filter((e) => e.parts.length > 1);\n\n // Two command.ts files for one command, like ping/ and (group)/ping/. The route table\n // already reported them as a duplicate route.\n if (direct.length > 1) return null;\n\n if (direct.length > 0 && nested.length > 0) {\n for (const entry of nested) {\n diagnostics.error(\n \"mixed-command-and-subcommands\",\n `\"${top}\" has a command.ts and also subcommands, like this one. Discord doesn't let a command with subcommands run by itself. Replace ${relative(direct[0]?.route.file)} with a route.ts, or move this file out of ${top}/.`,\n { file: entry.route.file, route: entry.route.id },\n );\n }\n return null;\n }\n\n const tooDeep = nested.filter((e) => e.parts.length > 3);\n if (tooDeep.length > 0) {\n for (const entry of tooDeep) {\n diagnostics.error(\n \"command-too-deep\",\n `\"${entry.route.path}\" is ${entry.parts.length} levels deep. Discord commands go three levels at most: command, subcommand group, and subcommand. Remove a level of directories.`,\n { file: entry.route.file, route: entry.route.id },\n );\n }\n return null;\n }\n\n if (direct.length === 1) return compilePlainCommand(direct[0] as LoadedRoute, diagnostics);\n\n return compileParentCommand(top, nested, routeMetas, diagnostics);\n}\n\nfunction compilePlainCommand(entry: LoadedRoute, diagnostics: Diagnostics): CompiledCommand | null {\n const { route, meta } = entry;\n const name = meta.name ?? route.path;\n const type = COMMAND_TYPE[meta.type ?? \"chatInput\"];\n\n if (type === ApplicationCommandType.ChatInput && !isValidChatInputName(name)) {\n reportDirectoryName(route, name, diagnostics);\n return null;\n }\n\n const payload: Record<string, unknown> = {\n name,\n type,\n ...localizations(meta),\n ...topLevelPayload(meta),\n };\n if (type === ApplicationCommandType.ChatInput) {\n payload.description = meta.description;\n if (meta.options !== undefined) payload.options = meta.options.map(optionPayload);\n }\n\n return {\n name,\n type,\n handlers: { \"\": route },\n payload: compact(payload) as unknown as RESTPostAPIApplicationCommandsJSONBody,\n files: [route.file],\n };\n}\n\nfunction compileParentCommand(\n top: string,\n nested: LoadedRoute[],\n routeMetas: Map<string, LoadedRouteMeta>,\n diagnostics: Diagnostics,\n): CompiledCommand | null {\n const parent = requireRouteMeta(top, nested[0] as LoadedRoute, routeMetas, diagnostics);\n if (parent === null) return null;\n const name = parent.meta.name ?? top;\n if (!isValidChatInputName(name)) {\n reportDirectoryName(nested[0]?.route as Route, name, diagnostics, parent.boundary.file);\n return null;\n }\n\n const handlers: Record<string, Route> = {};\n const files = [parent.boundary.file];\n const options: Record<string, unknown>[] = [];\n let ok = true;\n\n const bySecond = new Map<string, LoadedRoute[]>();\n for (const entry of nested) {\n const second = entry.parts[1] as string;\n bySecond.set(second, [...(bySecond.get(second) ?? []), entry]);\n }\n\n if (bySecond.size > 25) {\n diagnostics.error(\n \"too-many-subcommands\",\n `\"${top}\" has ${bySecond.size} subcommands and groups. Discord allows 25 per command. Move some into a subcommand group or another command.`,\n { file: parent.boundary.file },\n );\n ok = false;\n }\n\n for (const [second, entries] of [...bySecond].sort(([a], [b]) => a.localeCompare(b))) {\n const subs = entries.filter((e) => e.parts.length === 2);\n const grouped = entries.filter((e) => e.parts.length === 3);\n\n if (subs.length > 0 && grouped.length > 0) {\n for (const entry of grouped) {\n diagnostics.error(\n \"mixed-subcommand-and-group\",\n `${relative(subs[0]?.route.file)} makes \"${top} ${second}\" a subcommand, and this file makes it a subcommand group. Discord doesn't allow both. Move that command.ts into its own directory under ${second}/, or move this file out.`,\n { file: entry.route.file, route: entry.route.id },\n );\n }\n ok = false;\n continue;\n }\n\n if (subs.length === 1) {\n const sub = compileSubcommand(subs[0] as LoadedRoute, diagnostics);\n if (sub === null) {\n ok = false;\n continue;\n }\n handlers[sub.name] = sub.route;\n files.push(sub.route.file);\n options.push(sub.payload);\n continue;\n }\n\n const groupKey = `${top}/${second}`;\n const group = requireRouteMeta(groupKey, grouped[0] as LoadedRoute, routeMetas, diagnostics);\n if (group === null) {\n ok = false;\n continue;\n }\n const groupName = group.meta.name ?? second;\n if (!isValidChatInputName(groupName)) {\n reportDirectoryName(grouped[0]?.route as Route, groupName, diagnostics, group.boundary.file);\n ok = false;\n continue;\n }\n const extra = topLevelKeysUsed(group.meta);\n if (extra.length > 0) {\n diagnostics.error(\n \"top-level-field-on-group\",\n `${fieldList(extra)} can't be set on a subcommand group. Discord applies ${extra.length === 1 ? \"it\" : \"them\"} to the whole command, so move ${extra.length === 1 ? \"it\" : \"them\"} to ${relative(parent.boundary.file)}.`,\n { file: group.boundary.file },\n );\n ok = false;\n continue;\n }\n if (grouped.length > 25) {\n diagnostics.error(\n \"too-many-subcommands\",\n `The \"${groupKey}\" group has ${grouped.length} subcommands. Discord allows 25 per group. Move some into another group.`,\n { file: group.boundary.file },\n );\n ok = false;\n continue;\n }\n files.push(group.boundary.file);\n const groupOptions: Record<string, unknown>[] = [];\n for (const entry of grouped.sort((a, b) => a.route.path.localeCompare(b.route.path))) {\n const sub = compileSubcommand(entry, diagnostics);\n if (sub === null) {\n ok = false;\n continue;\n }\n handlers[`${groupName}/${sub.name}`] = sub.route;\n files.push(sub.route.file);\n groupOptions.push(sub.payload);\n }\n options.push(\n compact({\n type: ApplicationCommandOptionType.SubcommandGroup,\n name: groupName,\n description: group.meta.description,\n ...localizations(group.meta),\n options: groupOptions,\n }),\n );\n }\n\n if (!ok) return null;\n\n const payload = compact({\n name,\n type: ApplicationCommandType.ChatInput,\n description: parent.meta.description,\n ...localizations(parent.meta),\n ...topLevelPayload(parent.meta),\n options,\n }) as RESTPostAPIApplicationCommandsJSONBody;\n\n return { name, type: ApplicationCommandType.ChatInput, handlers, payload, files };\n}\n\nfunction compileSubcommand(\n entry: LoadedRoute,\n diagnostics: Diagnostics,\n): { name: string; route: Route; payload: Record<string, unknown> } | null {\n const { route, meta } = entry;\n if (meta.type !== undefined && meta.type !== \"chatInput\") {\n diagnostics.error(\n \"context-menu-nested\",\n `This is a context menu command, but it's nested under ${entry.parts[0]}/ as a subcommand. Discord doesn't allow context menu subcommands. Move it to its own directory directly under commands/, like commands/${entry.parts.at(-1)}/command.ts.`,\n { file: route.file, route: route.id },\n );\n return null;\n }\n const extra = topLevelKeysUsed(meta);\n if (extra.length > 0) {\n diagnostics.error(\n \"top-level-field-on-subcommand\",\n `${fieldList(extra)} can't be set on a subcommand. Discord applies ${extra.length === 1 ? \"it\" : \"them\"} to the whole command, so move ${extra.length === 1 ? \"it\" : \"them\"} to the route.ts in ${entry.parts[0]}/.`,\n { file: route.file, route: route.id },\n );\n return null;\n }\n const name = meta.name ?? (entry.parts.at(-1) as string);\n if (!isValidChatInputName(name)) {\n reportDirectoryName(route, name, diagnostics);\n return null;\n }\n const payload = compact({\n type: ApplicationCommandOptionType.Subcommand,\n name,\n description: meta.description,\n ...localizations(meta),\n options: meta.options?.map(optionPayload),\n });\n return { name, route, payload };\n}\n\nfunction requireRouteMeta(\n key: string,\n child: LoadedRoute,\n routeMetas: Map<string, LoadedRouteMeta>,\n diagnostics: Diagnostics,\n): LoadedRouteMeta | null {\n const entry = routeMetas.get(key);\n if (entry !== undefined) {\n entry.used = true;\n return entry;\n }\n const dir = directoryForPath(child.route, key.split(\"/\").length);\n diagnostics.error(\n \"missing-route-meta\",\n `\"${key}\" has subcommands but no route.ts. Discord needs a description for it, and without a command.ts that goes in route.ts. Add ${relative(path.join(dir, \"route.ts\"))} with export const meta = { description: \"...\" }.`,\n { file: child.route.file, route: child.route.id },\n );\n return null;\n}\n\n/** Directory of the Nth non-group segment of a route, walking up from the handler file. */\nfunction directoryForPath(route: Route, depth: number): string {\n let seen = 0;\n let index = route.segments.length;\n for (let i = 0; i < route.segments.length; i++) {\n if (route.segments[i]?.type === \"group\") continue;\n seen++;\n if (seen === depth) {\n index = i;\n break;\n }\n }\n const levelsUp = route.segments.length - index - 1;\n let dir = path.dirname(route.file);\n for (let i = 0; i < levelsUp; i++) dir = path.dirname(dir);\n return dir;\n}\n\nfunction isValidChatInputName(name: string): boolean {\n return /^[-_\\p{L}\\p{N}\\p{sc=Deva}\\p{sc=Thai}]{1,32}$/u.test(name) && name === name.toLowerCase();\n}\n\nfunction reportDirectoryName(route: Route, name: string, diagnostics: Diagnostics, file?: string) {\n diagnostics.error(\n \"invalid-name\",\n `\"${name}\" isn't a valid slash command name. Discord only allows lowercase letters, digits, hyphens, and underscores, up to 32 characters. Rename the directory, or set meta.name.`,\n { file: file ?? route.file, route: route.id },\n );\n}\n\n/** `meta.nsfw and meta.contexts` */\nfunction fieldList(keys: string[]): string {\n return new Intl.ListFormat(\"en\").format(keys.map((key) => `meta.${key}`));\n}\n\nfunction detectDuplicateNames(commands: CompiledCommand[], diagnostics: Diagnostics): void {\n const seen = new Map<string, CompiledCommand>();\n for (const command of commands) {\n const key = `${command.type}:${command.name}`;\n const existing = seen.get(key);\n if (existing === undefined) {\n seen.set(key, command);\n continue;\n }\n diagnostics.error(\n \"duplicate-command-name\",\n `${relative(existing.files[0])} and ${relative(command.files[0])} both register a ${TYPE_LABEL[command.type]} named \"${command.name}\". Discord needs the names to be unique, so change meta.name or the directory of one of them.`,\n { file: command.files[0] as string },\n );\n }\n}\n\nfunction optionPayload(option: CommandOption): Record<string, unknown> {\n const base: Record<string, unknown> = {\n type: OPTION_TYPE[option.type],\n name: option.name,\n description: option.description,\n required: option.required,\n ...localizations(option),\n };\n switch (option.type) {\n case \"string\":\n base.choices = option.choices?.map(choicePayload);\n base.autocomplete = option.autocomplete;\n base.min_length = option.minLength;\n base.max_length = option.maxLength;\n break;\n case \"integer\":\n case \"number\":\n base.choices = option.choices?.map(choicePayload);\n base.autocomplete = option.autocomplete;\n base.min_value = option.minValue;\n base.max_value = option.maxValue;\n break;\n case \"channel\":\n base.channel_types = option.channelTypes;\n break;\n }\n return compact(base);\n}\n\nfunction choicePayload(choice: {\n name: string;\n value: string | number;\n nameLocalizations?: unknown;\n}) {\n return compact({\n name: choice.name,\n value: choice.value,\n name_localizations: choice.nameLocalizations,\n });\n}\n\nfunction localizations(meta: { nameLocalizations?: unknown; descriptionLocalizations?: unknown }) {\n return {\n name_localizations: meta.nameLocalizations,\n description_localizations: meta.descriptionLocalizations,\n };\n}\n\nfunction topLevelPayload(meta: TopLevelMeta): Record<string, unknown> {\n const perms = meta.defaultMemberPermissions;\n return {\n default_member_permissions:\n perms === undefined ? undefined : perms === null ? null : String(perms),\n nsfw: meta.nsfw,\n contexts: meta.contexts,\n integration_types: meta.integrationTypes,\n };\n}\n\nfunction compact<T extends Record<string, unknown>>(object: T): T {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(object)) {\n if (value !== undefined) out[key] = value;\n }\n return out as T;\n}\n\nfunction relative(file: string | undefined): string {\n return file === undefined ? \"?\" : path.relative(process.cwd(), file).split(path.sep).join(\"/\");\n}\n","import { Events } from \"discord.js\";\nimport { Diagnostics } from \"../compiler/diagnostics.js\";\nimport { loadModule } from \"../compiler/load.js\";\nimport type { Route, RouteTable } from \"../compiler/routes.js\";\nimport { formatSegment } from \"../compiler/segments.js\";\nimport { checkHandler } from \"../components/compile.js\";\n\n/** `export const meta` in an `event.ts`. Every field is optional. */\nexport interface EventMeta {\n /** Remove the listener after the first call. */\n once?: boolean;\n /** Handlers of the same event run in ascending order. Ties break on route identity. Defaults to 0. */\n order?: number;\n /**\n * How the handlers of this event run relative to each other. Every handler that sets it\n * must agree. Defaults to `\"sequential\"`.\n */\n mode?: EventMode;\n}\n\nexport type EventMode = \"sequential\" | \"concurrent\";\n\nexport interface EventHandler {\n route: Route;\n once: boolean;\n order: number;\n}\n\nexport interface CompiledEvent {\n /** discord.js event name, for example `guildMemberAdd`. */\n name: string;\n mode: EventMode;\n /** In execution order. */\n handlers: EventHandler[];\n}\n\nexport interface CompiledEvents {\n events: CompiledEvent[];\n diagnostics: Diagnostics;\n}\n\nconst EVENT_NAMES: ReadonlySet<string> = new Set(Object.values(Events));\n\n/** Renamed events whose old name still shows up in older discord.js code. */\nconst RENAMED: Record<string, string> = {\n ready: Events.ClientReady,\n};\n\ninterface LoadedHandler extends EventHandler {\n name: string;\n mode: EventMode | undefined;\n}\n\n/** Groups event routes by discord.js event and validates their names and `meta`. */\nexport async function compileEvents(table: RouteTable): Promise<CompiledEvents> {\n const diagnostics = new Diagnostics();\n const routes = table.routes.filter((r) => r.kind === \"event\");\n\n const loaded = await Promise.all(routes.map((route) => loadHandler(route, diagnostics)));\n\n const byName = new Map<string, LoadedHandler[]>();\n for (const handler of loaded) {\n if (handler === null) continue;\n byName.set(handler.name, [...(byName.get(handler.name) ?? []), handler]);\n }\n\n const events: CompiledEvent[] = [];\n for (const [name, handlers] of [...byName].sort(([a], [b]) => a.localeCompare(b))) {\n const modes = new Set(handlers.map((h) => h.mode).filter((m) => m !== undefined));\n if (modes.size > 1) {\n for (const handler of handlers) {\n if (handler.mode === undefined) continue;\n diagnostics.error(\n \"event-mode-conflict\",\n `Handlers of \"${name}\" set meta.mode to both \"concurrent\" and \"sequential\". The mode applies to all of an event's handlers, so set it in one file, or make them match.`,\n { file: handler.route.file, route: handler.route.id },\n );\n }\n continue;\n }\n handlers.sort((a, b) => a.order - b.order || a.route.id.localeCompare(b.route.id));\n events.push({\n name,\n mode: modes.values().next().value ?? \"sequential\",\n handlers: handlers.map(({ route, once, order }) => ({ route, once, order })),\n });\n }\n\n return { events, diagnostics };\n}\n\nasync function loadHandler(route: Route, diagnostics: Diagnostics): Promise<LoadedHandler | null> {\n const name = eventName(route, diagnostics);\n if (name === null) return null;\n\n let module: Record<string, unknown>;\n try {\n module = await loadModule(route.file);\n } catch (error) {\n diagnostics.error(\n \"module-load-failed\",\n `The compiler imports every route file to read its exports, and this one threw: ${error instanceof Error ? error.message : String(error)}`,\n { file: route.file, route: route.id },\n );\n return null;\n }\n\n if (!checkHandler(module, route, diagnostics, name)) return null;\n const meta = validateEventMeta(module.meta, route, diagnostics);\n if (meta === null) return null;\n return { route, name, once: meta.once ?? false, order: meta.order ?? 0, mode: meta.mode };\n}\n\nfunction eventName(route: Route, diagnostics: Diagnostics): string | null {\n const statics = route.segments.filter((s) => s.type !== \"group\");\n const first = statics[0];\n if (first === undefined || first.type !== \"static\") return null;\n\n if (statics.length > 1) {\n diagnostics.error(\n \"event-nested-path\",\n `\"${route.path}\" has ${statics.slice(1).map(formatSegment).join(\"/\")}/ below the event name, and event handlers go directly in events/<eventName>/. To split an event across files, use route groups, like events/${first.name}/(${statics[1]?.name})/event.ts.`,\n { file: route.file, route: route.id },\n );\n return null;\n }\n\n const name = first.name;\n if (EVENT_NAMES.has(name)) return name;\n\n const renamed = RENAMED[name];\n const hint =\n renamed !== undefined\n ? `discord.js renamed it to \"${renamed}\".`\n : closest(name)\n ? `Did you mean \"${closest(name)}\"?`\n : \"Event directories are named after a value of discord.js's Events enum, like messageCreate.\";\n diagnostics.error(\n \"unknown-event\",\n `\"${name}\" isn't a discord.js event. ${hint} Rename the directory.`,\n { file: route.file, route: route.id },\n );\n return null;\n}\n\nfunction validateEventMeta(\n value: unknown,\n route: Route,\n diagnostics: Diagnostics,\n): EventMeta | null {\n if (value === undefined) return {};\n const fail = (message: string) => {\n diagnostics.error(\"invalid-meta\", message, { file: route.file, route: route.id });\n return null;\n };\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return fail(\"meta has to be an object, like { order: 1 }.\");\n }\n const meta = value as Record<string, unknown>;\n if (meta.once !== undefined && typeof meta.once !== \"boolean\") {\n return fail(\"meta.once has to be true or false.\");\n }\n if (\n meta.order !== undefined &&\n (typeof meta.order !== \"number\" || !Number.isFinite(meta.order))\n ) {\n return fail(`meta.order is ${String(meta.order)}. Use a finite number.`);\n }\n if (meta.mode !== undefined && meta.mode !== \"sequential\" && meta.mode !== \"concurrent\") {\n return fail(`meta.mode is ${JSON.stringify(meta.mode)}. Use \"sequential\" or \"concurrent\".`);\n }\n return meta as EventMeta;\n}\n\n/** Case-insensitive match against known events, to catch `GuildMemberAdd` or `guildmemberadd`. */\nfunction closest(name: string): string | null {\n const lower = name.toLowerCase();\n for (const known of EVENT_NAMES) if (known.toLowerCase() === lower) return known;\n return null;\n}\n","import type { Boundary, Route } from \"./routes.js\";\nimport type { Segment } from \"./segments.js\";\n\nexport interface RouteChains {\n /** Middleware files from the app root down to the route's directory, in execution order. */\n middleware: string[];\n /** Error boundary files from the route's directory up to the app root, nearest first. */\n errors: string[];\n}\n\n/**\n * Picks the boundaries that apply to a route: everything at the app root, plus every\n * boundary in the route's category whose directory is an ancestor of (or equal to) the\n * route's directory. Route groups count as directories here, so a middleware inside\n * `(admin)/` covers only that group.\n */\nexport function resolveChains(route: Route, boundaries: readonly Boundary[]): RouteChains {\n const applicable = boundaries.filter(\n (b) =>\n (b.category === null || b.category === route.category) &&\n isPrefix(b.segments, route.segments),\n );\n const byDepth = (a: Boundary, b: Boundary) => depth(a) - depth(b);\n\n return {\n // Event handlers take discord.js's arguments, not an interaction context, so the runtime\n // runs no middleware for them.\n middleware:\n route.category === \"event\"\n ? []\n : applicable\n .filter((b) => b.kind === \"middleware\")\n .sort(byDepth)\n .map((b) => b.file),\n errors: applicable\n .filter((b) => b.kind === \"error\")\n .sort(byDepth)\n .reverse()\n .map((b) => b.file),\n };\n}\n\n/** Root boundaries sit above the category directory, so they sort before category-level ones. */\nfunction depth(boundary: Boundary): number {\n return boundary.category === null ? -1 : boundary.segments.length;\n}\n\nfunction isPrefix(prefix: readonly Segment[], segments: readonly Segment[]): boolean {\n if (prefix.length > segments.length) return false;\n return prefix.every((s, i) => s.type === segments[i]?.type && s.name === segments[i]?.name);\n}\n","import { readdirSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type FileKind =\n | \"command\"\n | \"autocomplete\"\n | \"button\"\n | \"select\"\n | \"modal\"\n | \"event\"\n | \"middleware\"\n | \"error\"\n | \"route\";\n\nexport interface SourceFile {\n kind: FileKind;\n /** Absolute path. */\n file: string;\n /** Directory names from the app root down to the file's directory. */\n dirs: string[];\n}\n\nconst RESERVED: Record<string, FileKind> = {\n command: \"command\",\n autocomplete: \"autocomplete\",\n button: \"button\",\n select: \"select\",\n modal: \"modal\",\n event: \"event\",\n middleware: \"middleware\",\n error: \"error\",\n route: \"route\",\n};\n\nconst EXTENSIONS = new Set([\".ts\", \".js\", \".mts\", \".mjs\"]);\n\n/** The route file kind a filename denotes, or `undefined` for ordinary application code. */\nexport function reservedKind(fileName: string): FileKind | undefined {\n const ext = path.extname(fileName);\n if (!EXTENSIONS.has(ext)) return undefined;\n const base = fileName.slice(0, -ext.length);\n if (base.endsWith(\".test\") || base.endsWith(\".spec\")) return undefined;\n return RESERVED[base];\n}\n\n/**\n * Walks the app directory and returns every reserved file, sorted by path.\n * Anything that is not a reserved filename is ordinary application code and is skipped.\n */\nexport function discover(appDir: string): SourceFile[] {\n const files: SourceFile[] = [];\n walk(path.resolve(appDir), [], files);\n files.sort((a, b) => (a.file < b.file ? -1 : a.file > b.file ? 1 : 0));\n return files;\n}\n\nfunction walk(dir: string, dirs: string[], out: SourceFile[]): void {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(full, [...dirs, entry.name], out);\n continue;\n }\n if (!entry.isFile()) continue;\n const kind = reservedKind(entry.name);\n if (kind === undefined) continue;\n out.push({ kind, file: full, dirs });\n }\n}\n","import { createHash } from \"node:crypto\";\n\n/**\n * Short, stable identifier used inside custom IDs.\n * First 6 base36 characters of the SHA-256 of the canonical route identity.\n */\nexport function shortId(routeId: string): string {\n const hex = createHash(\"sha256\").update(routeId).digest(\"hex\").slice(0, 16);\n return BigInt(`0x${hex}`).toString(36).padStart(6, \"0\").slice(0, 6);\n}\n","import path from \"node:path\";\nimport { Diagnostics } from \"./diagnostics.js\";\nimport { discover, type FileKind, type SourceFile } from \"./discover.js\";\nimport { shortId } from \"./identity.js\";\nimport { formatSegment, parseSegment, type Segment } from \"./segments.js\";\n\nexport type RouteCategory = \"command\" | \"component\" | \"event\";\n\nexport type RouteKind = \"command\" | \"autocomplete\" | \"button\" | \"select\" | \"modal\" | \"event\";\n\nexport interface Route {\n /** Canonical identity, `<category>:<path>`. */\n id: string;\n /** Six character hash of `id`, used in custom IDs. */\n shortId: string;\n category: RouteCategory;\n kind: RouteKind;\n /** Segments joined by `/`. Groups are stripped, except for events where they keep handlers distinct. */\n path: string;\n /** Every segment below the category directory, groups included. */\n segments: Segment[];\n /** Dynamic and catch-all parameter names, in route order. */\n params: string[];\n /** Absolute path of the handler file. */\n file: string;\n}\n\nexport type BoundaryKind = \"middleware\" | \"error\" | \"route\";\n\nexport interface Boundary {\n kind: BoundaryKind;\n /** `null` at the app root, otherwise the category the boundary lives under. */\n category: RouteCategory | null;\n /** Segments below the category directory, groups included. Empty at the category root. */\n segments: Segment[];\n file: string;\n}\n\nexport interface RouteTable {\n routes: Route[];\n boundaries: Boundary[];\n diagnostics: Diagnostics;\n}\n\nconst CATEGORY_DIRS: Record<string, RouteCategory> = {\n commands: \"command\",\n components: \"component\",\n events: \"event\",\n};\n\nconst HANDLER_KINDS: Record<RouteCategory, ReadonlySet<FileKind>> = {\n command: new Set([\"command\", \"autocomplete\"]),\n component: new Set([\"button\", \"select\", \"modal\"]),\n event: new Set([\"event\"]),\n};\n\nconst BOUNDARY_KINDS: ReadonlySet<FileKind> = new Set([\"middleware\", \"error\", \"route\"]);\n\n/** A directory name for the examples in messages. */\nconst EXAMPLE_DIR: Record<RouteCategory, string> = {\n command: \"ping\",\n component: \"confirm\",\n event: \"messageCreate\",\n};\n\n/** Discovers the app directory and builds the route table. */\nexport function buildRouteTable(appDir: string): RouteTable {\n return buildRouteTableFromFiles(discover(appDir));\n}\n\nexport function buildRouteTableFromFiles(files: SourceFile[]): RouteTable {\n const diagnostics = new Diagnostics();\n const routes: Route[] = [];\n const boundaries: Boundary[] = [];\n\n for (const source of files) {\n const [categoryDir, ...rest] = source.dirs;\n\n if (categoryDir === undefined) {\n if (source.kind === \"middleware\" || source.kind === \"error\") {\n boundaries.push({ kind: source.kind, category: null, segments: [], file: source.file });\n } else {\n diagnostics.error(\n \"file-outside-category\",\n `${path.basename(source.file)} is directly in the app directory, where only middleware and error files go. Move it under commands/, components/, or events/.`,\n { file: source.file },\n );\n }\n continue;\n }\n\n const category = CATEGORY_DIRS[categoryDir];\n if (category === undefined) {\n const name = path.basename(source.file);\n diagnostics.error(\n \"unknown-category\",\n `${name} is in ${categoryDir}/, which isn't a route directory. Nectar treats every file named ${name} as a route file, so move it under commands/, components/, or events/, or rename it.`,\n { file: source.file },\n );\n continue;\n }\n\n const segments = parseSegments(rest, source, diagnostics);\n if (segments === null) continue;\n\n if (BOUNDARY_KINDS.has(source.kind)) {\n boundaries.push({\n kind: source.kind as BoundaryKind,\n category,\n segments,\n file: source.file,\n });\n continue;\n }\n\n if (!HANDLER_KINDS[category].has(source.kind)) {\n const home = Object.entries(CATEGORY_DIRS).find(([, c]) => HANDLER_KINDS[c].has(source.kind));\n diagnostics.error(\n \"file-in-wrong-category\",\n `${path.basename(source.file)} belongs under ${home?.[0]}/, not ${categoryDir}/.`,\n { file: source.file },\n );\n continue;\n }\n\n const route = makeRoute(category, source.kind as RouteKind, segments, source.file, diagnostics);\n if (route !== null) routes.push(route);\n }\n\n detectDuplicates(routes, diagnostics);\n\n return { routes, boundaries, diagnostics };\n}\n\nfunction parseSegments(\n dirs: string[],\n source: SourceFile,\n diagnostics: Diagnostics,\n): Segment[] | null {\n const segments: Segment[] = [];\n for (const dir of dirs) {\n const result = parseSegment(dir);\n if (!result.ok) {\n diagnostics.error(\"invalid-segment\", result.reason, { file: source.file });\n return null;\n }\n segments.push(result.segment);\n }\n return segments;\n}\n\nfunction makeRoute(\n category: RouteCategory,\n kind: RouteKind,\n segments: Segment[],\n file: string,\n diagnostics: Diagnostics,\n): Route | null {\n const name = path.basename(file);\n const dir = `${category}s`;\n if (segments.length === 0) {\n diagnostics.error(\n \"route-without-path\",\n `${name} is directly in ${dir}/, so it has no route path. Put it in a named directory, like ${dir}/${EXAMPLE_DIR[category]}/${name}.`,\n { file },\n );\n return null;\n }\n\n // Events keep their groups in the path, but still need a directory for the event name.\n if (segments.every((segment) => segment.type === \"group\")) {\n const groups = segments.map(formatSegment).join(\"/\");\n const example =\n category === \"event\"\n ? `${dir}/${EXAMPLE_DIR[category]}/${groups}/${name}`\n : `${dir}/${groups}/${EXAMPLE_DIR[category]}/${name}`;\n diagnostics.error(\n \"route-without-path\",\n `${name} is only inside route groups, and groups aren't part of the route path. Put it in a named directory, like ${example}.`,\n { file },\n );\n return null;\n }\n\n const params: string[] = [];\n for (const [index, segment] of segments.entries()) {\n if (segment.type === \"dynamic\" || segment.type === \"catchAll\") {\n if (category !== \"component\") {\n diagnostics.error(\n \"dynamic-segment-not-allowed\",\n `${formatSegment(segment)} is a parameter, and only component routes can have parameters. ${\n category === \"command\"\n ? \"Discord registers commands under fixed names, so take input with meta.options instead.\"\n : \"The directory has to be named after a discord.js event, like events/messageCreate/.\"\n }`,\n { file },\n );\n return null;\n }\n if (params.includes(segment.name)) {\n diagnostics.error(\n \"duplicate-param\",\n `The parameter \"${segment.name}\" appears twice in this route. Each parameter becomes a key of ctx.params, so the names have to differ. Rename one of the directories.`,\n { file },\n );\n return null;\n }\n if (segment.type === \"catchAll\" && index !== segments.length - 1) {\n diagnostics.error(\n \"catch-all-not-last\",\n `${formatSegment(segment)} has more directories after it. A catch-all takes all the remaining values, so it has to be the last segment. Use [${segment.name}] if it only needs one value.`,\n { file },\n );\n return null;\n }\n params.push(segment.name);\n }\n }\n\n const routePath = segments\n .filter((segment) => segment.type !== \"group\" || category === \"event\")\n .map(formatSegment)\n .join(\"/\");\n\n const id = `${category}:${routePath}`;\n return { id, shortId: shortId(id), category, kind, path: routePath, segments, params, file };\n}\n\n/**\n * A command and its autocomplete share an ID. A component route has exactly one handler of any\n * kind, since the handler's types come from the path alone.\n */\nfunction detectDuplicates(routes: Route[], diagnostics: Diagnostics): void {\n const seen = new Map<string, Route>();\n for (const route of routes) {\n const key = route.category === \"component\" ? route.id : `${route.id}#${route.kind}`;\n const existing = seen.get(key);\n if (existing === undefined) {\n seen.set(key, route);\n continue;\n }\n const other = relative(existing.file);\n diagnostics.error(\n \"duplicate-route\",\n existing.kind !== route.kind\n ? `${other} handles the same route, ${route.id}. customId() and the generated types identify a component by its path alone, so each path takes one button.ts, select.ts, or modal.ts. Move one of them into its own directory.`\n : path.dirname(existing.file) === path.dirname(route.file)\n ? `${other} is in the same directory and handles the same route, ${route.id}. Keep one of them.`\n : `${other} is the same route, ${route.id}. Route groups aren't part of the path, so they don't tell the two apart. Rename one of the directories.`,\n { file: route.file, route: route.id },\n );\n }\n}\n\nfunction relative(file: string): string {\n return path.relative(process.cwd(), file).split(path.sep).join(\"/\");\n}\n","import path from \"node:path\";\nimport { type CompiledAutocomplete, compileAutocomplete } from \"../autocomplete/compile.js\";\nimport { type CompiledCommand, compileCommands } from \"../commands/compile.js\";\nimport { type ComponentRoute, compileComponents } from \"../components/compile.js\";\nimport { type CompiledEvent, compileEvents } from \"../events/compile.js\";\nimport { type RouteChains, resolveChains } from \"./chains.js\";\nimport { Diagnostics } from \"./diagnostics.js\";\nimport { type Boundary, buildRouteTable, type Route } from \"./routes.js\";\n\n/**\n * Everything the compiler knows about an app, after every category has been validated.\n * The manifest is a serialization of this.\n */\nexport interface RouteGraph {\n /** Absolute path of the app directory. */\n appDir: string;\n /** Every handler route, in discovery order. */\n routes: Route[];\n boundaries: Boundary[];\n /** Middleware and error chains keyed by the route's handler file. */\n chains: Map<string, RouteChains>;\n commands: CompiledCommand[];\n components: ComponentRoute[];\n events: CompiledEvent[];\n autocomplete: CompiledAutocomplete[];\n /** Plugin names that changed a route's chains, keyed by handler file. Filled by `applyPlugins`. */\n plugins: Map<string, string[]>;\n /** Diagnostics from every stage, in pipeline order. */\n diagnostics: Diagnostics;\n}\n\n/** Runs the whole compiler pipeline on an app directory. */\nexport async function buildGraph(appDir: string): Promise<RouteGraph> {\n const absolute = path.resolve(appDir);\n const table = buildRouteTable(absolute);\n const diagnostics = new Diagnostics();\n diagnostics.items.push(...table.diagnostics.items);\n\n const [commands, components, events] = await Promise.all([\n compileCommands(table),\n compileComponents(table),\n compileEvents(table),\n ]);\n const autocomplete = await compileAutocomplete(table, commands.commands);\n\n for (const stage of [commands, components, events, autocomplete]) {\n diagnostics.items.push(...stage.diagnostics.items);\n }\n\n const chains = new Map<string, RouteChains>();\n for (const route of table.routes) chains.set(route.file, resolveChains(route, table.boundaries));\n\n return {\n appDir: absolute,\n routes: table.routes,\n boundaries: table.boundaries,\n chains,\n commands: commands.commands,\n components: components.routes,\n events: events.events,\n autocomplete: autocomplete.autocomplete,\n plugins: new Map(),\n diagnostics,\n };\n}\n","import { styleText } from \"node:util\";\n\n/**\n * Terminal formatting for the CLI and dev server. Colors are off until the bin turns them on\n * for a TTY, so tests and piped output see plain text with the same glyphs.\n */\nlet colors = false;\n\nexport function setColors(enabled: boolean): void {\n colors = enabled;\n}\n\ntype Style = Parameters<typeof styleText>[0];\n\nconst paint =\n (style: Style) =>\n (text: string): string =>\n colors ? styleText(style, text) : text;\n\nexport const c = {\n bold: paint(\"bold\"),\n dim: paint(\"dim\"),\n red: paint(\"red\"),\n green: paint(\"green\"),\n yellow: paint(\"yellow\"),\n cyan: paint(\"cyan\"),\n magenta: paint(\"magenta\"),\n underline: paint(\"underline\"),\n};\n\nexport const ok = (text: string): string => `${c.green(\"✔\")} ${text}`;\nexport const fail = (text: string): string => `${c.red(\"✖\")} ${text}`;\nexport const warn = (text: string): string => `${c.yellow(\"▲\")} ${text}`;\nexport const info = (text: string): string => `${c.cyan(\"›\")} ${text}`;\nexport const link = (url: string): string => c.underline(c.cyan(url));\n\nexport const PORTAL_URL = \"https://discord.com/developers/applications\";\n\nexport function indent(lines: readonly string[], by = 2): string[] {\n return lines.map((line) => (line === \"\" ? \"\" : `${\" \".repeat(by)}${line}`));\n}\n\n/** A headline followed by indented detail lines, as one multi-line string. */\nexport function block(head: string, details: readonly string[] = []): string {\n return details.length === 0 ? head : [head, \"\", ...indent(details)].join(\"\\n\");\n}\n\n/** Two-column rows with dim keys, aligned on the widest key. */\nexport function table(rows: readonly (readonly [string, string])[]): string[] {\n const width = Math.max(0, ...rows.map(([key]) => key.length));\n return rows.map(([key, value]) => `${c.dim(key.padEnd(width))} ${value}`);\n}\n\n/** `HH:MM:SS`, dimmed. Prefix for dev server lines that happen while it runs. */\nexport function stamp(): string {\n return c.dim(new Date().toTimeString().slice(0, 8));\n}\n\n/** How to supply a credential, shared by every command that needs one. */\nexport function credentialHint(kind: \"token\" | \"applicationId\", configName: string): string[] {\n const variable = kind === \"token\" ? \"DISCORD_TOKEN\" : \"DISCORD_APPLICATION_ID\";\n const where =\n kind === \"token\"\n ? \"your application → Bot → Reset Token\"\n : \"your application → General Information → Application ID\";\n return [\n `Put ${c.bold(`${variable}=...`)} in ${c.bold(\".env\")} next to ${configName}, or export it.`,\n `The config reads it with ${c.bold(`${kind}: process.env.${variable}`)}; without that line the`,\n \"variable is used directly.\",\n `Get it from the Developer Portal under ${where}:`,\n link(PORTAL_URL),\n ];\n}\n","import path from \"node:path\";\nimport { type Diagnostic, docsUrl } from \"../compiler/diagnostics.js\";\nimport { buildGraph, type RouteGraph } from \"../compiler/graph.js\";\nimport { checkIntents } from \"../events/index.js\";\nimport { applyPlugins } from \"../plugins/index.js\";\nimport type { CliIo } from \"./io.js\";\nimport type { Project } from \"./project.js\";\nimport { c, fail, indent, link, warn } from \"./ui.js\";\n\n/**\n * Compiles the app, runs plugin transforms, and prints every diagnostic. Returns `null` when\n * any is an error.\n */\nexport async function compileProject(project: Project, io: CliIo): Promise<RouteGraph | null> {\n const graph = await buildGraph(project.appDir);\n graph.diagnostics.items.push(\n ...checkIntents(graph.events, project.config.intents, path.basename(project.configFile)),\n );\n if (!graph.diagnostics.hasErrors) await applyPlugins(graph, project.config.plugins ?? []);\n for (const diagnostic of graph.diagnostics.items) {\n io.err(formatDiagnostic(diagnostic, project.root));\n }\n if (graph.diagnostics.hasErrors) {\n const errors = graph.diagnostics.items.filter((d) => d.severity === \"error\").length;\n io.err(fail(`${errors} error${errors === 1 ? \"\" : \"s\"}. Fix the files above and run again.`));\n return null;\n }\n return graph;\n}\n\n/**\n * One diagnostic as a headline, an indented message, and the code's reference entry:\n *\n * ✖ error invalid-name app/commands/Ping/command.ts\n * \"Ping\" isn't a valid slash command name. ...\n * https://nectar-js.github.io/nectar/reference/diagnostics#invalid-name\n */\nexport function formatDiagnostic(diagnostic: Diagnostic, root: string): string {\n const mark = diagnostic.severity === \"error\" ? fail(c.red(\"error\")) : warn(c.yellow(\"warning\"));\n const where = diagnostic.file === undefined ? \"\" : ` ${relative(root, diagnostic.file)}`;\n const docs = docsUrl(diagnostic.code);\n return [\n `${mark} ${c.dim(diagnostic.code)}${where}`,\n ...indent([diagnostic.message, ...(docs === undefined ? [] : [link(docs)])]),\n ].join(\"\\n\");\n}\n\nexport function relative(root: string, file: string): string {\n return path.relative(root, file).split(path.sep).join(\"/\");\n}\n\nexport function summary(graph: RouteGraph): string {\n const n = (count: number, noun: string) => `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n return [\n n(graph.commands.length, \"command\"),\n n(graph.components.length, \"component route\"),\n n(graph.events.length, \"event\"),\n ].join(\", \");\n}\n","import type { Client } from \"discord.js\";\nimport type { NectarConfig } from \"../config.js\";\nimport type { CommandRest } from \"../registration/index.js\";\n\n/** What a CLI command can touch. The bin passes the real process; tests pass buffers. */\nexport interface CliIo {\n cwd: string;\n env: NodeJS.ProcessEnv;\n out(line: string): void;\n err(line: string): void;\n /** Builds the REST client `sync` talks to. Tests swap in a fake. */\n rest?: (token: string) => Promise<CommandRest>;\n /** Builds the discord.js client `dev` and `start` run. Tests swap in a fake that never logs in. */\n client?: (config: NectarConfig) => Client;\n}\n\nexport const EXIT_OK = 0;\nexport const EXIT_FAILURE = 1;\nexport const EXIT_USAGE = 2;\n\n/**\n * A problem the user can fix. Printed without a stack trace: the message as the headline,\n * then `details` indented under it (what went wrong in full, and what to do about it).\n */\nexport class CliError extends Error {\n readonly code: number;\n readonly details: readonly string[];\n\n constructor(message: string, options: { code?: number; details?: readonly string[] } = {}) {\n super(message);\n this.name = \"CliError\";\n this.code = options.code ?? EXIT_FAILURE;\n this.details = options.details ?? [];\n }\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { loadModule } from \"../compiler/load.js\";\nimport { ConfigError, configFor, type NectarConfig, validateConfig } from \"../config.js\";\nimport type { Env } from \"../runtime/types.js\";\nimport { CliError } from \"./io.js\";\nimport { c } from \"./ui.js\";\n\nexport const CONFIG_FILES = [\"nectar.config.ts\", \"nectar.config.js\"];\n\nexport interface Project {\n /** Directory holding the config file. Every relative config path resolves against it. */\n root: string;\n configFile: string;\n /** With the overrides for `env` applied. */\n config: NectarConfig;\n appDir: string;\n outDir: string;\n env: Env;\n}\n\n/** Finds and validates `nectar.config.ts` in `cwd`. */\nexport async function loadProject(cwd: string, env: NodeJS.ProcessEnv): Promise<Project> {\n const configFile = CONFIG_FILES.map((name) => path.join(cwd, name)).find((f) => existsSync(f));\n if (configFile === undefined) {\n throw new CliError(`No ${CONFIG_FILES[0]} in ${cwd}.`, {\n details: [\n \"Run nectar from the directory that holds your config file.\",\n `Starting fresh? ${c.bold(\"npm create @nectar-js\")} sets up a project.`,\n ],\n });\n }\n const name = path.basename(configFile);\n let loaded: NectarConfig;\n try {\n const module = await loadModule(configFile);\n loaded = validateConfig(module.default, name);\n } catch (error) {\n if (error instanceof ConfigError) {\n throw new CliError(`${name} is not valid.`, { details: [error.detail] });\n }\n throw new CliError(`Could not load ${name}.`, { details: [describe(error)] });\n }\n const projectEnv = loaded.env ?? envFrom(env.NODE_ENV);\n const config = configFor(loaded, projectEnv);\n const root = path.dirname(configFile);\n const appDir = path.resolve(root, config.appDir ?? \"app\");\n if (!existsSync(appDir)) {\n throw new CliError(`App directory ${path.relative(root, appDir) || \".\"}/ does not exist.`, {\n details: [`Create it, or point ${c.bold(\"appDir\")} in ${name} at the right place.`],\n });\n }\n return {\n root,\n configFile,\n config,\n appDir,\n outDir: path.resolve(root, config.outDir ?? \".nectar\"),\n env: projectEnv,\n };\n}\n\nexport function envFrom(value: string | undefined): Env {\n return value === \"production\" || value === \"test\" ? value : \"development\";\n}\n\nexport function describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { toManifest, writeManifest } from \"../manifest/index.js\";\nimport { writeTypes } from \"../typegen/index.js\";\nimport { compileProject, relative, summary } from \"./compile.js\";\nimport { type CliIo, EXIT_FAILURE, EXIT_OK } from \"./io.js\";\nimport { loadProject, type Project } from \"./project.js\";\nimport { c, ok, warn } from \"./ui.js\";\n\n/** `.mjs` so it loads as ESM whatever the project's `package.json` says, and PM2 imports it. */\nconst START_FILE = \"start.mjs\";\n\n/** `nectar build`: compile, then write the manifest, generated types, and `start.mjs` into `outDir`. */\nexport async function build(io: CliIo): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const graph = await compileProject(project, io);\n if (graph === null) return EXIT_FAILURE;\n\n const manifestFile = writeManifest(toManifest(graph, project.outDir), project.outDir);\n const typesFile = writeTypes(graph, project.outDir, project.config.plugins);\n const startFile = writeStart(project);\n io.out(ok(`Built ${summary(graph)}.`));\n for (const file of [manifestFile, typesFile, startFile]) {\n io.out(` ${c.dim(relative(project.root, file))}`);\n }\n return EXIT_OK;\n}\n\n/**\n * `node .nectar/start.mjs` does what `nectar start` does, from any working directory. It is the\n * file to hand a ShardingManager or cluster manager: each shard loads the manifest itself and\n * none of them registers commands.\n */\nfunction writeStart(project: Project): string {\n const root = path.relative(project.outDir, project.root).split(path.sep).join(\"/\");\n const file = path.join(project.outDir, START_FILE);\n writeFileSync(\n file,\n [\n \"// Written by nectar build. Runs the bot from this build, like `nectar start`.\",\n 'import { start } from \"@nectar-js/nectar/start\";',\n \"\",\n `await start(new URL(${JSON.stringify(`${root || \".\"}/`)}, import.meta.url));`,\n \"\",\n ].join(\"\\n\"),\n );\n return file;\n}\n\n/** `nectar check`: compile and report, writing nothing. */\nexport async function check(io: CliIo): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const graph = await compileProject(project, io);\n if (graph === null) return EXIT_FAILURE;\n const warnings = graph.diagnostics.items.length;\n io.out(\n warnings === 0\n ? ok(\n `No problems. ${summary(graph)} in ${path.relative(project.root, project.appDir) || \".\"}/.`,\n )\n : warn(`${warnings} warning${warnings === 1 ? \"\" : \"s\"}, no errors.`),\n );\n return EXIT_OK;\n}\n","import path from \"node:path\";\nimport { ApplicationCommandType } from \"discord-api-types/v10\";\nimport type { RouteGraph } from \"../compiler/graph.js\";\nimport type { Route } from \"../compiler/routes.js\";\nimport type { ComponentRoute } from \"../components/compile.js\";\nimport { compileProject, relative } from \"./compile.js\";\nimport { type CliIo, EXIT_FAILURE, EXIT_OK } from \"./io.js\";\nimport { loadProject } from \"./project.js\";\nimport { c } from \"./ui.js\";\n\n/** `nectar routes`: print the app tree with what every file and directory means. */\nexport async function routes(io: CliIo): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const graph = await compileProject(project, io);\n if (graph === null) return EXIT_FAILURE;\n io.out(renderRoutes(graph, project.root));\n return EXIT_OK;\n}\n\ninterface Node {\n name: string;\n notes: string[];\n children: Map<string, Node>;\n /** Files sort before directories. */\n file: boolean;\n}\n\n/**\n * A directory tree of the app. Handler files annotate their directory; middleware, error, and\n * route files appear as leaves so the scope of each is where it sits in the tree.\n */\nexport function renderRoutes(graph: RouteGraph, root: string): string {\n const tree: Node = {\n name: relative(root, graph.appDir) || \".\",\n notes: [],\n children: new Map(),\n file: false,\n };\n const nodeFor = (file: string, asFile: boolean): Node => {\n const parts = relative(graph.appDir, asFile ? file : path.dirname(file)).split(\"/\");\n let node = tree;\n for (const part of parts.filter((p) => p !== \"\" && p !== \".\")) {\n let child = node.children.get(part);\n if (child === undefined) {\n child = { name: part, notes: [], children: new Map(), file: false };\n node.children.set(part, child);\n }\n node = child;\n }\n node.file = asFile;\n return node;\n };\n const annotate = (route: Route, note: string) => nodeFor(route.file, false).notes.push(note);\n\n for (const command of graph.commands) {\n for (const [position, route] of Object.entries(command.handlers)) {\n annotate(route, commandLabel(command.type, command.name, position));\n }\n }\n for (const entry of graph.autocomplete) {\n annotate(entry.route, `autocomplete: ${entry.options.join(\", \")}`);\n }\n for (const route of graph.components) annotate(route, componentLabel(route));\n for (const event of graph.events) {\n for (const handler of event.handlers) {\n const flags = [handler.once ? \"once\" : null, event.handlers.length > 1 ? event.mode : null];\n annotate(handler.route, `event ${event.name}${suffix(flags)}`);\n }\n }\n for (const boundary of graph.boundaries) {\n const node = nodeFor(boundary.file, true);\n if (boundary.kind === \"route\") {\n node.notes.push(\"command metadata\");\n continue;\n }\n const covered = graph.routes.filter((r) => {\n const chain = graph.chains.get(r.file);\n return (boundary.kind === \"middleware\" ? chain?.middleware : chain?.errors)?.includes(\n boundary.file,\n );\n }).length;\n node.notes.push(\n `${boundary.kind === \"middleware\" ? \"middleware\" : \"error boundary\"} for ${covered} route${covered === 1 ? \"\" : \"s\"}`,\n );\n }\n\n const lines: [string, string][] = [];\n print(tree, \"\", true, true, lines);\n const width = Math.max(...lines.map(([left]) => left.length));\n return lines\n .map(([left, right]) => (right === \"\" ? left : `${left.padEnd(width)} ${c.dim(right)}`))\n .join(\"\\n\");\n}\n\nfunction print(\n node: Node,\n prefix: string,\n last: boolean,\n isRoot: boolean,\n out: [string, string][],\n) {\n const branch = isRoot ? \"\" : last ? \"└── \" : \"├── \";\n out.push([`${prefix}${branch}${node.name}`, node.notes.join(\" · \")]);\n const children = [...node.children.values()].sort(\n (a, b) => Number(b.file) - Number(a.file) || a.name.localeCompare(b.name),\n );\n const childPrefix = isRoot ? \"\" : `${prefix}${last ? \" \" : \"│ \"}`;\n children.forEach((child, i) => {\n print(child, childPrefix, i === children.length - 1, false, out);\n });\n}\n\nfunction commandLabel(type: ApplicationCommandType, name: string, position: string): string {\n if (type === ApplicationCommandType.User) return `user context menu \"${name}\"`;\n if (type === ApplicationCommandType.Message) return `message context menu \"${name}\"`;\n return `/${[name, ...position.split(\"/\").filter((p) => p !== \"\")].join(\" \")}`;\n}\n\nfunction componentLabel(route: ComponentRoute): string {\n const kind = route.kind === \"select\" ? `select (${route.selectKind})` : route.kind;\n const pattern = [\n `n:${route.shortId}`,\n ...route.params.map((p) => (p === route.catchAll ? `<...${p}>` : `<${p}>`)),\n ].join(\":\");\n return `${kind} ${pattern}`;\n}\n\nfunction suffix(flags: (string | null)[]): string {\n const present = flags.filter((f): f is string => f !== null);\n return present.length === 0 ? \"\" : ` (${present.join(\", \")})`;\n}\n","import type { RouteGraph } from \"../compiler/graph.js\";\nimport {\n type CommandRest,\n RegistrationError,\n registrationScopes,\n type ScopeSync,\n type SyncResult,\n scopeKey,\n syncCommands,\n UnsafeSyncError,\n} from \"../registration/index.js\";\nimport type { LoginError } from \"../runtime/index.js\";\nimport { compileProject } from \"./compile.js\";\nimport { CliError, type CliIo, EXIT_FAILURE, EXIT_OK } from \"./io.js\";\nimport { describe, loadProject, type Project } from \"./project.js\";\nimport { c, credentialHint, info, link, ok, PORTAL_URL, warn } from \"./ui.js\";\n\nexport const TOKEN_VAR = \"DISCORD_TOKEN\";\nexport const APPLICATION_ID_VAR = \"DISCORD_APPLICATION_ID\";\n\n/** `nectar sync [--dry-run] [--force]`: register the compiled commands with Discord. */\nexport async function sync(io: CliIo, dryRun: boolean, force: boolean): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const graph = await compileProject(project, io);\n if (graph === null) return EXIT_FAILURE;\n if (registrationScopes(project.config, project.env).length === 0) {\n throw new CliError(`No registration target for ${project.env}.`, {\n details: registrationHint(project),\n });\n }\n const result = await registerCommands(project, graph, io, { dryRun, force });\n for (const scope of result.scopes) io.out(describeScope(scope, dryRun));\n if (result.unsafe.length > 0) {\n io.err(warn(force ? \"Forced past the safety guard:\" : \"The safety guard would refuse this:\"));\n for (const reason of result.unsafe) io.err(` ${reason}`);\n }\n return EXIT_OK;\n}\n\n/**\n * Registers a compiled graph's commands in this environment's scopes. Missing credentials,\n * the safety guard, and Discord validation failures all surface as `CliError`.\n */\nexport async function registerCommands(\n project: Project,\n graph: RouteGraph,\n io: CliIo,\n options: { dryRun?: boolean; force?: boolean } = {},\n): Promise<SyncResult> {\n const token = credential(project, io, \"token\");\n const applicationId = credential(project, io, \"applicationId\");\n const rest = await (io.rest ?? discordRest)(token);\n try {\n return await syncCommands({\n rest,\n applicationId,\n commands: graph.commands.map((cmd) => cmd.payload),\n scopes: registrationScopes(project.config, project.env),\n cacheDir: project.outDir,\n dryRun: options.dryRun ?? false,\n force: options.force ?? false,\n });\n } catch (error) {\n if (error instanceof UnsafeSyncError) {\n throw new CliError(\"Refusing to register commands: this looks destructive.\", {\n details: [\n ...error.reasons,\n \"\",\n `If that is what you want, run again with ${c.bold(\"--force\")}.`,\n ],\n });\n }\n if (error instanceof RegistrationError) {\n throw new CliError(`Discord rejected the ${scopeKey(error.scope)} command registration.`, {\n details: error.problems.map(\n (p) =>\n `${c.bold(p.command ?? \"(request)\")}${p.field === \"\" ? \"\" : ` ${c.dim(p.field)}`}: ${p.message}`,\n ),\n });\n }\n throw error;\n }\n}\n\n/** One line per scope: what changed there and whether it was written. */\nexport function describeScope({ scope, diff, applied }: ScopeSync, dryRun = false): string {\n const key = c.bold(scopeKey(scope));\n if (diff === null) return ok(`${key}: unchanged since last sync.`);\n if (!diff.hasChanges) return ok(`${key}: up to date, ${diff.unchanged.length} command(s).`);\n const parts = [\n ...diff.added.map((n) => c.green(`+${n}`)),\n ...diff.changed.map((n) => c.yellow(`~${n}`)),\n ...diff.removed.map((n) => c.red(`-${n}`)),\n ].join(\" \");\n if (dryRun) return info(`${key}: ${parts} ${c.dim(\"(would apply)\")}`);\n return applied\n ? ok(`${key}: ${parts} ${c.dim(\"(applied)\")}`)\n : warn(`${key}: ${parts} ${c.dim(\"(not applied)\")}`);\n}\n\nexport type Credential = \"token\" | \"applicationId\";\n\nexport const CREDENTIAL_VARS: Record<Credential, string> = {\n token: TOKEN_VAR,\n applicationId: APPLICATION_ID_VAR,\n};\n\n/** The config field wins; the env var is the fallback. Empty strings count as unset. */\nexport function findCredential(project: Project, io: CliIo, kind: Credential): string | null {\n const value = project.config[kind] || io.env[CREDENTIAL_VARS[kind]];\n return value === undefined || value === \"\" ? null : value;\n}\n\nexport function credential(project: Project, io: CliIo, kind: Credential): string {\n const value = findCredential(project, io, kind);\n if (value === null) {\n throw new CliError(`${CREDENTIAL_VARS[kind]} is not set.`, {\n details: credentialHint(kind, projectConfigName(project)),\n });\n }\n return value;\n}\n\n/** A failed login as something to fix: the token, or the connection to Discord. */\nexport function loginFailure(error: LoginError, project: Project): CliError {\n if (!error.invalidToken) {\n return new CliError(\"Could not log in to Discord.\", { details: [describe(error.cause)] });\n }\n const source = project.config.token\n ? `${c.bold(\"token\")} in ${projectConfigName(project)}`\n : c.bold(TOKEN_VAR);\n return new CliError(\"Discord rejected the bot token.\", {\n details: [\n `The token from ${source} is wrong, or it was reset.`,\n \"Get a new one from the Developer Portal under your application → Bot → Reset Token:\",\n link(PORTAL_URL),\n ],\n });\n}\n\nexport function registrationHint(project: Project): string[] {\n return [\n `Add your test server's ID to ${c.bold(\"dev.guilds\")} in ${projectConfigName(project)}.`,\n \"Find it in Discord: Server Settings → Widget → Server ID, or right-click the server\",\n \"with Developer Mode on and choose Copy Server ID.\",\n ];\n}\n\nasync function discordRest(token: string): Promise<CommandRest> {\n const { REST } = await import(\"discord.js\");\n return new REST().setToken(token);\n}\n\nexport function projectConfigName(project: Project): string {\n return project.configFile.split(/[\\\\/]/).at(-1) ?? \"nectar.config.ts\";\n}\n","import path from \"node:path\";\nimport { reservedKind } from \"../compiler/discover.js\";\nimport { stableStringify } from \"../manifest/emit.js\";\nimport type { Manifest } from \"../manifest/schema.js\";\n\n/**\n * What a changed path means for the dev server, decided from the path alone.\n *\n * - `config`: the config file. The runtime restarts.\n * - `route`: a reserved file or a directory under the app directory. The app recompiles and\n * the manifest diff decides what else follows.\n * - `dependency`: any other source file. Every module evaluates again on next use, since\n * nothing tracks who imports it.\n * - `ignored`: build output, `node_modules`, `.git`, tests, non-source files.\n */\nexport type ChangeKind = \"config\" | \"route\" | \"dependency\" | \"ignored\";\n\nexport interface ProjectPaths {\n configFile: string;\n appDir: string;\n outDir: string;\n}\n\nconst SOURCE_EXTENSIONS = new Set([\".ts\", \".js\", \".mts\", \".mjs\", \".cts\", \".cjs\", \".json\"]);\n\nexport function classifyPath(file: string, project: ProjectPaths): ChangeKind {\n const absolute = path.resolve(file);\n if (absolute === path.resolve(project.configFile)) return \"config\";\n const parts = absolute.split(path.sep);\n if (\n parts.includes(\"node_modules\") ||\n parts.includes(\".git\") ||\n within(project.outDir, absolute)\n ) {\n return \"ignored\";\n }\n const name = path.basename(absolute);\n if (within(project.appDir, absolute)) {\n // No extension: a directory was created, renamed, or removed. Its files may not report.\n if (path.extname(name) === \"\" || reservedKind(name) !== undefined) return \"route\";\n }\n if (!SOURCE_EXTENSIONS.has(path.extname(name))) return \"ignored\";\n if (/\\.(test|spec)\\.[cm]?[jt]s$/.test(name)) return \"ignored\";\n return \"dependency\";\n}\n\nfunction within(dir: string, file: string): boolean {\n const rel = path.relative(path.resolve(dir), file);\n return rel !== \"\" && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n}\n\n/** What a recompile changed, and therefore what the running app must do about it. */\nexport interface ManifestDelta {\n /** Routes, chains, events, or handler positions differ. Dispatch tables must be rebuilt. */\n structure: boolean;\n /** Registration payloads differ. Dev guild commands must be re-registered. */\n commands: boolean;\n}\n\nexport function diffManifests(before: Manifest, after: Manifest): ManifestDelta {\n const payloads = (m: Manifest) => stableStringify(m.commands.map((c) => c.payload));\n const shape = (m: Manifest) =>\n stableStringify({\n routes: m.routes,\n events: m.events,\n commands: m.commands.map(({ payload: _payload, ...rest }) => rest),\n });\n return {\n structure: shape(before) !== shape(after),\n commands: payloads(before) !== payloads(after),\n };\n}\n","import { existsSync } from \"node:fs\";\nimport { type Client, Events } from \"discord.js\";\nimport { compileProject, relative, summary } from \"../cli/compile.js\";\nimport { CliError, type CliIo } from \"../cli/io.js\";\nimport { loadProject, type Project } from \"../cli/project.js\";\nimport { renderRoutes } from \"../cli/routes.js\";\nimport {\n APPLICATION_ID_VAR,\n credential,\n describeScope,\n findCredential,\n loginFailure,\n projectConfigName,\n registerCommands,\n registrationHint,\n} from \"../cli/sync.js\";\nimport { block, c, credentialHint, fail, indent, info, ok, stamp, warn } from \"../cli/ui.js\";\nimport type { RouteGraph } from \"../compiler/graph.js\";\nimport { enableModuleReloading, invalidateModuleGraph } from \"../compiler/load.js\";\nimport { type Manifest, toManifest, writeManifest } from \"../manifest/index.js\";\nimport { registrationScopes, scopeKey } from \"../registration/index.js\";\nimport {\n createLogger,\n createRuntime,\n createSignals,\n HandlerLoadError,\n type Logger,\n LoginError,\n type LogSink,\n manifestFiles,\n type Runtime,\n} from \"../runtime/index.js\";\nimport { writeTypes } from \"../typegen/index.js\";\nimport { classifyPath, diffManifests } from \"./classify.js\";\n\nexport interface DevServerOptions {\n /** Print the full route tree and discord.js warnings. */\n verbose?: boolean;\n}\n\nexport interface DevServer {\n /** Compiles, registers dev guild commands, and starts the bot. Waits for a fix if the app does not compile. */\n start(): Promise<void>;\n /** Reacts to a batch of changed paths: reload handlers, rebuild routes, re-register, or restart. */\n apply(files: string[]): Promise<void>;\n stop(): Promise<void>;\n}\n\n/**\n * The state behind `nectar dev`: the compiled manifest and the runtime serving it. Changes are\n * handled in the smallest way that keeps the running bot correct, and the gateway connection\n * survives everything but a config change.\n */\nexport function createDevServer(\n project: Project,\n io: CliIo,\n options: DevServerOptions = {},\n): DevServer {\n const verbose = options.verbose ?? false;\n let current = project;\n let manifest: Manifest | null = null;\n let runtime: Runtime | null = null;\n let token = \"\";\n let started = false;\n const warned = new Set<string>();\n\n /** Lines printed while the server is running carry a timestamp; startup lines do not. */\n const say = (line: string) => io.out(started ? `${stamp()} ${line}` : line);\n const complain = (line: string) => io.err(started ? `${stamp()} ${line}` : line);\n\n /** Framework log records in the dev server's format. The default when the config has no sink. */\n const print: LogSink = ({ level, message, fields }) => {\n if (level === \"debug\") {\n const pairs = Object.entries(fields)\n .filter(([key, value]) => key !== \"error\" && value !== undefined && value !== null)\n .map(([key, value]) => `${key}=${String(value)}`);\n say(c.dim([message, ...pairs].join(\" \")));\n } else if (level === \"info\") {\n say(info(message));\n } else if (level === \"warn\") {\n complain(warn(message));\n } else {\n const [head = \"\", ...rest] = message.split(\"\\n\");\n const stack = fields.error === undefined ? [] : describeError(fields.error);\n // block() indents the details itself. Strip only the report's own two spaces, so\n // continuation lines stay aligned with the column above them.\n complain(block(fail(c.bold(head)), [...rest.map((l) => l.replace(/^ {2}/, \"\")), ...stack]));\n }\n };\n /** The config's `logger`, with `--verbose` lowering the level to debug. */\n const loggerFor = ({ config }: Project): Logger =>\n createLogger({\n level: verbose ? \"debug\" : (config.logger?.level ?? \"info\"),\n sink: config.logger?.sink ?? print,\n });\n\n // Both fresh per boot, so a reloaded config's `logger` applies and its `observe` is\n // subscribed once.\n let logger = loggerFor(current);\n let signals = createSignals(logger);\n\n function warnOnce(head: string, details: string[] = []): void {\n if (warned.has(head)) return;\n warned.add(head);\n complain(block(warn(head), details));\n }\n\n function emit(graph: RouteGraph): Manifest {\n const next = toManifest(graph, current.outDir);\n writeManifest(next, current.outDir);\n writeTypes(graph, current.outDir, current.config.plugins);\n return next;\n }\n\n async function register(graph: RouteGraph): Promise<void> {\n const scopes = registrationScopes(current.config, current.env);\n if (scopes.length === 0) {\n warnOnce(\"Commands are not registered anywhere yet.\", registrationHint(current));\n return;\n }\n if (findCredential(current, io, \"applicationId\") === null) {\n warnOnce(\n `Commands are not registered: ${APPLICATION_ID_VAR} is not set.`,\n credentialHint(\"applicationId\", projectConfigName(current)),\n );\n return;\n }\n signals.emit({ type: \"registration:start\", scopes: scopes.map(scopeKey) });\n const startedAt = Date.now();\n try {\n const result = await registerCommands(current, graph, io);\n signals.emit({\n type: \"registration:complete\",\n scopes: result.scopes.map((s) => ({ scope: scopeKey(s.scope), applied: s.applied })),\n duration: Date.now() - startedAt,\n });\n for (const scope of result.scopes) {\n if (scope.diff !== null || verbose) say(describeScope(scope));\n }\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n complain(\n block(\n fail(error.message),\n error.details.map((line) => line.replace(\"run again with\", \"run nectar sync with\")),\n ),\n );\n }\n }\n\n async function launch(): Promise<void> {\n if (manifest === null) return;\n const next = createRuntime({\n manifest,\n appDir: current.appDir,\n config: current.config,\n env: current.env,\n logger,\n signals,\n ...(io.client === undefined ? {} : { client: io.client(current.config) }),\n });\n watchConnection(next.client);\n runtime = next;\n try {\n await next.start({ token, signals: false });\n } catch (error) {\n throw error instanceof LoginError ? loginFailure(error, current) : error;\n }\n }\n\n function watchConnection(client: Client): void {\n client.once(Events.ClientReady, (ready) => say(ok(`Logged in as ${c.bold(ready.user.tag)}.`)));\n client.on(Events.ShardDisconnect, (event) => {\n complain(warn(`Disconnected from the gateway ${c.dim(`(code ${event.code})`)}.`));\n });\n client.on(Events.ShardReconnecting, () => say(info(\"Reconnecting to the gateway.\")));\n client.on(Events.ShardResume, () => say(ok(\"Gateway connection resumed.\")));\n client.on(Events.Error, (error) => complain(fail(`Gateway error: ${error.message}`)));\n if (verbose) client.on(Events.Warn, (message) => complain(warn(`discord.js: ${message}`)));\n }\n\n /** Full start: compile, write output, print routes, register, run. */\n async function boot(): Promise<void> {\n logger = loggerFor(current);\n signals = createSignals(logger);\n const graph = await compileProject(current, io);\n if (graph === null) {\n complain(warn(\"Waiting for changes.\"));\n return;\n }\n manifest = emit(graph);\n say(ok(`${summary(graph)} in ${c.bold(appLabel())}`));\n if (verbose)\n for (const line of indent(renderRoutes(graph, current.root).split(\"\\n\"))) say(line);\n await register(graph);\n await launch();\n }\n\n async function stopRuntime(): Promise<void> {\n const running = runtime;\n runtime = null;\n manifest = null;\n if (running !== null) await running.stop();\n }\n\n async function restart(): Promise<void> {\n await stopRuntime();\n try {\n current = await loadProject(io.cwd, io.env);\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n complain(block(fail(error.message), error.details));\n complain(warn(\"Waiting for changes.\"));\n return;\n }\n say(info(`Restarting with the new ${c.bold(projectConfigName(current))}.`));\n await boot();\n }\n\n /** Imports files now so a broken module shows up here, not on the next interaction. */\n async function preload(files: string[]): Promise<void> {\n if (runtime === null) return;\n const results = await Promise.allSettled(files.map((file) => runtime?.modules.load(file)));\n for (const result of results) {\n if (result.status === \"fulfilled\") continue;\n const error: unknown = result.reason;\n complain(\n error instanceof HandlerLoadError\n ? block(fail(`${c.bold(relative(current.root, error.file))} failed to load.`), [\n error.detail,\n ])\n : fail(String(error)),\n );\n }\n }\n\n function appLabel(): string {\n return `${relative(current.root, current.appDir) || \".\"}/`;\n }\n\n return {\n async start() {\n token = credential(current, io, \"token\");\n enableModuleReloading(current.root);\n await boot();\n started = true;\n },\n\n async apply(files) {\n const kinds = new Map(files.map((file) => [file, classifyPath(file, current)] as const));\n const changed = files.filter((file) => kinds.get(file) !== \"ignored\");\n if (changed.length === 0) return;\n for (const file of changed) {\n const gone = !existsSync(file);\n say(`${gone ? c.red(\"-\") : c.yellow(\"~\")} ${relative(current.root, file)}`);\n }\n\n if (changed.some((file) => kinds.get(file) === \"config\")) {\n await restart();\n return;\n }\n const dependency = changed.some((file) => kinds.get(file) === \"dependency\");\n if (dependency) invalidateModuleGraph();\n\n if (runtime === null || manifest === null) {\n await boot();\n return;\n }\n\n const graph = await compileProject(current, io);\n if (graph === null) {\n complain(warn(\"Keeping the previous routes until this is fixed.\"));\n return;\n }\n const next = toManifest(graph, current.outDir);\n const delta = diffManifests(manifest, next);\n const done: string[] = [];\n if (delta.structure || delta.commands) manifest = emit(graph);\n if (delta.structure) {\n runtime.update(manifest);\n done.push(`routes rebuilt ${c.dim(`(${summary(graph)})`)}`);\n if (verbose) {\n for (const line of indent(renderRoutes(graph, current.root).split(\"\\n\"))) say(line);\n }\n }\n if (delta.commands) await register(graph);\n\n const all = manifestFiles(manifest, current.appDir);\n const stale = dependency ? [...all] : changed.filter((file) => all.has(file));\n runtime.modules.invalidate(dependency ? undefined : stale);\n await preload(stale);\n if (dependency) done.push(\"every module reloaded\");\n else if (stale.length > 0) {\n done.push(`${stale.length} handler module${stale.length === 1 ? \"\" : \"s\"} reloaded`);\n }\n\n say(done.length === 0 ? info(\"Nothing to reload.\") : ok(`${capitalize(done.join(\", \"))}.`));\n },\n\n stop: stopRuntime,\n };\n}\n\nfunction capitalize(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n\nfunction describeError(error: unknown): string[] {\n const text = error instanceof Error ? (error.stack ?? error.message) : String(error);\n return text.split(\"\\n\").map((line) => c.dim(line));\n}\n","import { type FSWatcher, watch } from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface Watcher {\n close(): void;\n}\n\nexport interface WatchOptions {\n /** Milliseconds to wait for more events before reporting a batch. Defaults to 80. */\n debounce?: number;\n onError?: (error: Error) => void;\n}\n\n/**\n * Watches a directory tree and reports changed paths in debounced batches. Editors write a\n * file in several steps and `fs.watch` reports each one, so a batch collapses them to one\n * change and lets several files saved together be handled together.\n */\nexport function watchTree(\n root: string,\n onChange: (files: string[]) => void,\n options: WatchOptions = {},\n): Watcher {\n const { debounce = 80, onError } = options;\n const pending = new Set<string>();\n let timer: NodeJS.Timeout | null = null;\n\n const flush = () => {\n timer = null;\n const files = [...pending];\n pending.clear();\n onChange(files);\n };\n\n const watcher: FSWatcher = watch(root, { recursive: true }, (_event, filename) => {\n if (filename === null) return;\n pending.add(path.join(root, filename.toString()));\n if (timer !== null) clearTimeout(timer);\n timer = setTimeout(flush, debounce);\n });\n if (onError !== undefined) watcher.on(\"error\", onError);\n\n return {\n close() {\n if (timer !== null) clearTimeout(timer);\n watcher.close();\n },\n };\n}\n","import { createDevServer } from \"../dev/server.js\";\nimport { watchTree } from \"../dev/watch.js\";\nimport { version } from \"../version.js\";\nimport { relative } from \"./compile.js\";\nimport { CliError, type CliIo, EXIT_OK } from \"./io.js\";\nimport { describe, loadProject } from \"./project.js\";\nimport { block, c, fail, info, stamp } from \"./ui.js\";\n\n/** `nectar dev [--verbose]`: compile, register dev guild commands, run, and react to file changes. */\nexport async function dev(io: CliIo, verbose: boolean): Promise<number> {\n io.out(`${c.bold(\"nectar dev\")} ${c.dim(`v${version}`)}`);\n io.out(\"\");\n const project = await loadProject(io.cwd, io.env);\n const server = createDevServer(project, io, { verbose });\n await server.start();\n io.out(\n info(\n `Watching ${c.bold(`${relative(project.root, project.appDir) || \".\"}/`)}, ${c.bold(relative(project.root, project.configFile))}, and the files they import. ${c.dim(\"Ctrl+C stops.\")}`,\n ),\n );\n\n // Batches are handled one at a time, in order, so a rebuild never races a reload.\n let queue = Promise.resolve();\n const watcher = watchTree(\n project.root,\n (files) => {\n queue = queue\n .then(() => server.apply(files))\n .catch((error: unknown) => {\n io.err(\n `${stamp()} ${error instanceof CliError ? block(fail(error.message), error.details) : fail(describe(error))}`,\n );\n });\n },\n { onError: (error) => io.err(`${stamp()} ${fail(`Watcher error: ${error.message}`)}`) },\n );\n\n await new Promise<void>((resolve) => {\n process.once(\"SIGINT\", () => resolve());\n process.once(\"SIGTERM\", () => resolve());\n });\n io.out(\"\");\n io.out(info(\"Stopping.\"));\n watcher.close();\n await queue;\n await server.stop();\n return EXIT_OK;\n}\n","import {\n type Manifest,\n type ManifestRoute,\n stableStringify,\n toManifest,\n} from \"../manifest/index.js\";\nimport { compileProject } from \"./compile.js\";\nimport { CliError, type CliIo, EXIT_FAILURE, EXIT_OK } from \"./io.js\";\nimport { loadProject } from \"./project.js\";\n\n/** `nectar manifest [--route <id>]`: print the compiled manifest, or everything about one route. */\nexport async function manifest(io: CliIo, route: string | undefined): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const graph = await compileProject(project, io);\n if (graph === null) return EXIT_FAILURE;\n const compiled = toManifest(graph, project.outDir);\n\n if (route === undefined) {\n io.out(stableStringify(compiled));\n return EXIT_OK;\n }\n const matches = compiled.routes.filter((r) => r.id === route || r.path === route);\n if (matches.length === 0) {\n const known = [...new Set(compiled.routes.map((r) => r.id))].sort();\n throw new CliError(`No route \"${route}\".`, {\n details: [\"Known routes:\", ...known.map((id) => ` ${id}`)],\n });\n }\n io.out(stableStringify(matches.map((r) => describeRoute(r, compiled))));\n return EXIT_OK;\n}\n\n/** The route record plus what the manifest links it to: its command payload, custom ID, or event. */\nexport function describeRoute(route: ManifestRoute, compiled: Manifest): Record<string, unknown> {\n const detail: Record<string, unknown> = { ...route };\n if (route.kind === \"command\" || route.kind === \"autocomplete\") {\n for (const command of compiled.commands) {\n const position = Object.entries(command.handlers).find(([, id]) => id === route.id)?.[0];\n if (position === undefined) continue;\n detail.command = { name: command.name, position, payload: command.payload };\n if (route.kind === \"autocomplete\") {\n detail.commandRoute = compiled.routes.find(\n (r) => r.kind === \"command\" && r.id === route.id,\n )?.file;\n }\n }\n } else if (route.kind === \"event\") {\n const event = compiled.events.find((e) => e.name === route.event);\n if (event !== undefined) detail.eventHandlers = { mode: event.mode, handlers: event.handlers };\n } else {\n detail.customId = [\n `n:${route.shortId}`,\n ...route.params.map((p) => (p === route.catchAll ? `<...${p}>` : `<${p}>`)),\n ].join(\":\");\n }\n return detail;\n}\n","import { existsSync, rmSync } from \"node:fs\";\nimport { registrationScopes, scopeKey } from \"../registration/index.js\";\nimport { version } from \"../version.js\";\nimport { relative } from \"./compile.js\";\nimport { CliError, type CliIo, EXIT_OK } from \"./io.js\";\nimport { loadProject } from \"./project.js\";\nimport { APPLICATION_ID_VAR, findCredential, TOKEN_VAR } from \"./sync.js\";\nimport { c, info as note, ok, table } from \"./ui.js\";\n\n/** `nectar clean`: delete the build output directory. */\nexport async function clean(io: CliIo): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const label = `${relative(project.root, project.outDir)}/`;\n if (!existsSync(project.outDir)) {\n io.out(note(`Nothing to remove, ${c.bold(label)} does not exist.`));\n return EXIT_OK;\n }\n rmSync(project.outDir, { recursive: true, force: true });\n io.out(ok(`Removed ${c.bold(label)}`));\n return EXIT_OK;\n}\n\n/** `nectar info`: versions, environment, and the config values that decide runtime behaviour. */\nexport async function info(io: CliIo): Promise<number> {\n const rows: [string, string][] = [\n [\"nectar\", version],\n [\"node\", process.version],\n [\"discord.js\", await discordVersion()],\n [\"platform\", `${process.platform} ${process.arch}`],\n ];\n\n try {\n const project = await loadProject(io.cwd, io.env);\n const { config } = project;\n const scopes = registrationScopes(config, project.env);\n rows.push(\n [TOKEN_VAR, present(findCredential(project, io, \"token\"))],\n [APPLICATION_ID_VAR, present(findCredential(project, io, \"applicationId\"))],\n [\"config\", relative(project.root, project.configFile)],\n [\"env\", project.env],\n [\"appDir\", relative(project.root, project.appDir) || \".\"],\n [\"outDir\", relative(project.root, project.outDir)],\n [\"intents\", describeBitfield(config.intents)],\n [\"partials\", config.partials === undefined ? \"none\" : String(config.partials.length)],\n [\"eager\", String(config.eager ?? project.env === \"production\")],\n [\"registration\", scopes.length === 0 ? c.yellow(\"none\") : scopes.map(scopeKey).join(\", \")],\n [\"plugins\", (config.plugins ?? []).map((p) => p.name).join(\", \") || \"none\"],\n );\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n rows.push(\n [TOKEN_VAR, present(io.env[TOKEN_VAR] || null)],\n [APPLICATION_ID_VAR, present(io.env[APPLICATION_ID_VAR] || null)],\n [\"config\", c.yellow(error.message)],\n );\n }\n\n for (const line of table(rows)) io.out(line);\n return EXIT_OK;\n}\n\nasync function discordVersion(): Promise<string> {\n try {\n const { version: v } = await import(\"discord.js\");\n return v;\n } catch {\n return c.yellow(\"not installed\");\n }\n}\n\nfunction present(value: string | null): string {\n return value === null || value === \"\" ? c.yellow(\"not set\") : c.green(\"set\");\n}\n\nfunction describeBitfield(value: unknown): string {\n if (Array.isArray(value)) return value.length === 0 ? \"none\" : value.map(String).join(\", \");\n return String(value);\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Client } from \"discord.js\";\nimport { loadManifest, MANIFEST_FILE } from \"../manifest/index.js\";\nimport { createRuntime, LoginError } from \"../runtime/index.js\";\nimport { relative } from \"./compile.js\";\nimport { CliError, type CliIo, EXIT_OK } from \"./io.js\";\nimport { loadProject } from \"./project.js\";\nimport { credential, loginFailure } from \"./sync.js\";\nimport { c, ok } from \"./ui.js\";\n\n/** `nectar start`: run the bot from the last `nectar build`. No source discovery happens here. */\nexport async function start(io: CliIo): Promise<number> {\n const project = await loadProject(io.cwd, io.env);\n const manifestFile = path.join(project.outDir, MANIFEST_FILE);\n if (!existsSync(manifestFile)) {\n throw new CliError(`${relative(project.root, manifestFile)} not found.`, {\n details: [`Run ${c.bold(\"nectar build\")} first, then ${c.bold(\"nectar start\")} again.`],\n });\n }\n const token = credential(project, io, \"token\");\n\n const { manifest, appDir } = loadManifest(manifestFile);\n const runtime = createRuntime({\n manifest,\n appDir,\n config: project.config,\n env: project.env,\n ...(io.client === undefined ? {} : { client: io.client(project.config) }),\n });\n runtime.client.once(\"clientReady\", (client) => {\n io.out(ok(`Logged in as ${c.bold(client.user.tag)} (${project.env}${shards(client)}).`));\n });\n try {\n await runtime.start({ token });\n } catch (error) {\n throw error instanceof LoginError ? loginFailure(error, project) : error;\n }\n return EXIT_OK;\n}\n\n/** `, shard 2 of 4` when the bot is sharded, so each shard process's line says which it is. */\nfunction shards(client: Client): string {\n const { shards: ids, shardCount } = client.options;\n if (!Array.isArray(ids) || shardCount === undefined || shardCount < 2) return \"\";\n return `, shard${ids.length === 1 ? \"\" : \"s\"} ${ids.join(\", \")} of ${shardCount}`;\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport { PluginError } from \"../plugins/index.js\";\nimport { version } from \"../version.js\";\nimport { build, check } from \"./build.js\";\nimport { dev } from \"./dev.js\";\nimport { CliError, type CliIo, EXIT_FAILURE, EXIT_OK, EXIT_USAGE } from \"./io.js\";\nimport { manifest } from \"./manifest.js\";\nimport { clean, info } from \"./misc.js\";\nimport { CONFIG_FILES, describe, loadProject } from \"./project.js\";\nimport { routes } from \"./routes.js\";\nimport { start } from \"./start.js\";\nimport { sync } from \"./sync.js\";\nimport { block, c, fail, indent, setColors } from \"./ui.js\";\n\nexport type { CliIo } from \"./io.js\";\nexport { EXIT_FAILURE, EXIT_OK, EXIT_USAGE } from \"./io.js\";\n\ninterface Command {\n usage: string;\n description: string;\n options?: Record<string, { type: \"boolean\" | \"string\"; description: string }>;\n run(io: CliIo, flags: Record<string, string | boolean | undefined>): Promise<number>;\n}\n\nconst COMMANDS: Record<string, Command> = {\n dev: {\n usage: \"dev [--verbose]\",\n description: \"Compile, register dev guild commands, run the bot, and reload on changes.\",\n options: {\n verbose: { type: \"boolean\", description: \"Print the route tree and discord.js warnings.\" },\n },\n run: (io, flags) => dev(io, flags.verbose === true),\n },\n build: {\n usage: \"build\",\n description: \"Compile the app and write the manifest and types.\",\n run: (io) => build(io),\n },\n check: {\n usage: \"check\",\n description: \"Compile and report problems without writing anything.\",\n run: (io) => check(io),\n },\n routes: {\n usage: \"routes\",\n description: \"Show the app tree: commands, components, events, middleware, error boundaries.\",\n run: (io) => routes(io),\n },\n manifest: {\n usage: \"manifest [--route <id>]\",\n description: \"Print the compiled manifest, or everything about one route.\",\n options: {\n route: { type: \"string\", description: \"Route ID or path, e.g. command:moderation/ban.\" },\n },\n run: (io, flags) => manifest(io, flags.route as string | undefined),\n },\n sync: {\n usage: \"sync [--dry-run] [--force]\",\n description: \"Register commands with Discord, writing only scopes that changed.\",\n options: {\n \"dry-run\": { type: \"boolean\", description: \"Show the diff without changing anything.\" },\n force: { type: \"boolean\", description: \"Proceed even when the change looks destructive.\" },\n },\n run: (io, flags) => sync(io, flags[\"dry-run\"] === true, flags.force === true),\n },\n start: {\n usage: \"start\",\n description: \"Run the bot from the last build.\",\n run: (io) => start(io),\n },\n clean: {\n usage: \"clean\",\n description: \"Delete the build output directory.\",\n run: (io) => clean(io),\n },\n info: {\n usage: \"info\",\n description: \"Show versions, environment, and the effective config.\",\n run: (io) => info(io),\n },\n};\n\n/**\n * Commands contributed by the config's plugins. Loading the config can fail; for help that is\n * silent, for a command it is the error the user needs to see.\n */\nasync function pluginCommands(io: CliIo, tolerant: boolean): Promise<Record<string, Command>> {\n if (!CONFIG_FILES.some((file) => existsSync(path.join(io.cwd, file)))) return {};\n const commands: Record<string, Command> = {};\n try {\n const project = await loadProject(io.cwd, io.env);\n for (const plugin of project.config.plugins ?? []) {\n for (const command of plugin.commands ?? []) {\n const options = command.options ?? {};\n const usage = [\n command.name,\n ...Object.entries(options).map(\n ([key, opt]) => `[--${key}${opt.type === \"string\" ? \" <value>\" : \"\"}]`,\n ),\n ].join(\" \");\n commands[command.name] = {\n usage,\n description: command.description,\n options,\n run: async (io, flags) => command.run({ project, flags, out: io.out, err: io.err }),\n };\n }\n }\n } catch (error) {\n if (!tolerant || !(error instanceof CliError)) throw error;\n }\n return commands;\n}\n\n/** Runs `run` for this process: loads `cwd/.env`, colors a TTY, prints to the console. */\nexport async function main(argv: string[], cwd: string): Promise<number> {\n const envFile = path.join(cwd, \".env\");\n if (existsSync(envFile)) process.loadEnvFile(envFile);\n\n const wantsColor = process.env.NO_COLOR === undefined || process.env.NO_COLOR === \"\";\n setColors(process.env.FORCE_COLOR !== undefined || (wantsColor && process.stdout.isTTY === true));\n\n return run(argv, {\n cwd,\n env: process.env,\n out: (line) => console.log(line),\n err: (line) => console.error(line),\n });\n}\n\n/** Runs one CLI invocation. `argv` excludes the node and script entries. */\nexport async function run(argv: string[], io: CliIo): Promise<number> {\n const [name, ...rest] = argv;\n if (name === undefined || name === \"--help\" || name === \"-h\" || name === \"help\") {\n io.out(help(await pluginCommands(io, true)));\n return name === undefined ? EXIT_USAGE : EXIT_OK;\n }\n if (name === \"--version\" || name === \"-v\") {\n io.out(version);\n return EXIT_OK;\n }\n let command = COMMANDS[name];\n if (command === undefined) {\n try {\n command = (await pluginCommands(io, false))[name];\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n io.err(block(fail(error.message), error.details));\n return error.code;\n }\n }\n if (command === undefined) {\n io.err(\n block(fail(`Unknown command ${c.bold(`\"${name}\"`)}.`), [\n `Run ${c.bold(\"nectar --help\")} to see the commands.`,\n ]),\n );\n return EXIT_USAGE;\n }\n\n let flags: Record<string, string | boolean | undefined>;\n try {\n const parsed = parseArgs({\n args: rest,\n options: {\n ...Object.fromEntries(\n Object.entries(command.options ?? {}).map(([key, opt]) => [key, { type: opt.type }]),\n ),\n help: { type: \"boolean\" },\n },\n strict: true,\n allowPositionals: false,\n });\n flags = parsed.values;\n } catch (error) {\n io.err(fail(describe(error)));\n io.err(\"\");\n io.err(commandHelp(command));\n return EXIT_USAGE;\n }\n if (flags.help === true) {\n io.out(commandHelp(command));\n return EXIT_OK;\n }\n\n try {\n return await command.run(io, flags);\n } catch (error) {\n if (error instanceof CliError) {\n io.err(block(fail(error.message), error.details));\n return error.code;\n }\n if (error instanceof PluginError) {\n io.err(block(fail(error.message), [`Fix or remove the plugin in your config.`]));\n return EXIT_FAILURE;\n }\n io.err(\n block(fail(\"Something went wrong inside Nectar.\"), [\n \"This is a bug in Nectar, not in your app. The details:\",\n \"\",\n ...(error instanceof Error ? (error.stack ?? error.message) : String(error))\n .split(\"\\n\")\n .map((line) => c.dim(line)),\n ]),\n );\n return EXIT_FAILURE;\n }\n}\n\nfunction help(plugins: Record<string, Command>): string {\n const all = [...Object.values(COMMANDS), ...Object.values(plugins)];\n const width = Math.max(...all.map((cmd) => cmd.usage.length));\n const row = (cmd: Command) => ` ${c.cyan(cmd.usage.padEnd(width))} ${c.dim(cmd.description)}`;\n return [\n `${c.bold(\"nectar\")} ${c.dim(`v${version}`)} A filesystem-based meta-framework for discord.js.`,\n \"\",\n `${c.bold(\"Usage:\")} nectar <command> [options]`,\n \"\",\n c.bold(\"Commands:\"),\n ...Object.values(COMMANDS).map(row),\n ...(Object.keys(plugins).length === 0\n ? []\n : [\"\", c.bold(\"Plugin commands:\"), ...Object.values(plugins).map(row)]),\n \"\",\n c.bold(\"Options:\"),\n ` ${c.cyan(\"--help, -h\".padEnd(width))} ${c.dim(\"Show help for nectar or a command.\")}`,\n ` ${c.cyan(\"--version, -v\".padEnd(width))} ${c.dim(\"Print the version.\")}`,\n ].join(\"\\n\");\n}\n\nfunction commandHelp(command: Command): string {\n const options = Object.entries(command.options ?? {});\n const lines = [`${c.bold(\"Usage:\")} nectar ${command.usage}`, \"\", command.description];\n if (options.length > 0) {\n const width = Math.max(...options.map(([key]) => key.length));\n lines.push(\n \"\",\n c.bold(\"Options:\"),\n ...indent(\n options.map(\n ([key, opt]) => `${c.cyan(`--${key.padEnd(width)}`)} ${c.dim(opt.description)}`,\n ),\n ),\n );\n }\n return lines.join(\"\\n\");\n}\n"],"mappings":"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"}