@went.tf/discord-bot-framework 2.0.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.
Files changed (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +550 -0
  3. package/build/.tsbuildinfo +1 -0
  4. package/build/api-client/api-client.d.ts +13 -0
  5. package/build/api-client/api-client.d.ts.map +1 -0
  6. package/build/api-client/api-client.js +147 -0
  7. package/build/api-client/api-client.js.map +1 -0
  8. package/build/api-client/api-http-exception.d.ts +7 -0
  9. package/build/api-client/api-http-exception.d.ts.map +1 -0
  10. package/build/api-client/api-http-exception.js +12 -0
  11. package/build/api-client/api-http-exception.js.map +1 -0
  12. package/build/api-client/index.d.ts +4 -0
  13. package/build/api-client/index.d.ts.map +1 -0
  14. package/build/api-client/index.js +4 -0
  15. package/build/api-client/index.js.map +1 -0
  16. package/build/api-client/types.d.ts +105 -0
  17. package/build/api-client/types.d.ts.map +1 -0
  18. package/build/api-client/types.js +8 -0
  19. package/build/api-client/types.js.map +1 -0
  20. package/build/client/create-bot-client.d.ts +14 -0
  21. package/build/client/create-bot-client.d.ts.map +1 -0
  22. package/build/client/create-bot-client.js +19 -0
  23. package/build/client/create-bot-client.js.map +1 -0
  24. package/build/client/create-shard-manager.d.ts +17 -0
  25. package/build/client/create-shard-manager.d.ts.map +1 -0
  26. package/build/client/create-shard-manager.js +26 -0
  27. package/build/client/create-shard-manager.js.map +1 -0
  28. package/build/client/index.d.ts +3 -0
  29. package/build/client/index.d.ts.map +1 -0
  30. package/build/client/index.js +3 -0
  31. package/build/client/index.js.map +1 -0
  32. package/build/commands/build-application-commands-body.d.ts +39 -0
  33. package/build/commands/build-application-commands-body.d.ts.map +1 -0
  34. package/build/commands/build-application-commands-body.js +127 -0
  35. package/build/commands/build-application-commands-body.js.map +1 -0
  36. package/build/commands/fixed-reply-command-factory.d.ts +10 -0
  37. package/build/commands/fixed-reply-command-factory.d.ts.map +1 -0
  38. package/build/commands/fixed-reply-command-factory.js +19 -0
  39. package/build/commands/fixed-reply-command-factory.js.map +1 -0
  40. package/build/commands/index.d.ts +4 -0
  41. package/build/commands/index.d.ts.map +1 -0
  42. package/build/commands/index.js +4 -0
  43. package/build/commands/index.js.map +1 -0
  44. package/build/commands/registration.d.ts +24 -0
  45. package/build/commands/registration.d.ts.map +1 -0
  46. package/build/commands/registration.js +69 -0
  47. package/build/commands/registration.js.map +1 -0
  48. package/build/commands/schema/application-command-leaf-option.schema.d.ts +230 -0
  49. package/build/commands/schema/application-command-leaf-option.schema.d.ts.map +1 -0
  50. package/build/commands/schema/application-command-leaf-option.schema.js +129 -0
  51. package/build/commands/schema/application-command-leaf-option.schema.js.map +1 -0
  52. package/build/commands/schema/application-command-leaf-option.schema.json +258 -0
  53. package/build/commands/schema/application-command-option-choice.schema.d.ts +18 -0
  54. package/build/commands/schema/application-command-option-choice.schema.d.ts.map +1 -0
  55. package/build/commands/schema/application-command-option-choice.schema.js +12 -0
  56. package/build/commands/schema/application-command-option-choice.schema.js.map +1 -0
  57. package/build/commands/schema/application-command-option-choice.schema.json +23 -0
  58. package/build/commands/schema/application-command-option.schema.d.ts +12 -0
  59. package/build/commands/schema/application-command-option.schema.d.ts.map +1 -0
  60. package/build/commands/schema/application-command-option.schema.js +13 -0
  61. package/build/commands/schema/application-command-option.schema.js.map +1 -0
  62. package/build/commands/schema/application-command-option.schema.json +14 -0
  63. package/build/commands/schema/application-command-subcommand-group.schema.d.ts +28 -0
  64. package/build/commands/schema/application-command-subcommand-group.schema.d.ts.map +1 -0
  65. package/build/commands/schema/application-command-subcommand-group.schema.js +22 -0
  66. package/build/commands/schema/application-command-subcommand-group.schema.js.map +1 -0
  67. package/build/commands/schema/application-command-subcommand-group.schema.json +26 -0
  68. package/build/commands/schema/application-command-subcommand.schema.d.ts +29 -0
  69. package/build/commands/schema/application-command-subcommand.schema.d.ts.map +1 -0
  70. package/build/commands/schema/application-command-subcommand.schema.js +23 -0
  71. package/build/commands/schema/application-command-subcommand.schema.js.map +1 -0
  72. package/build/commands/schema/application-command-subcommand.schema.json +26 -0
  73. package/build/commands/schema/application-command-type.schema.d.ts +6 -0
  74. package/build/commands/schema/application-command-type.schema.d.ts.map +1 -0
  75. package/build/commands/schema/application-command-type.schema.js +6 -0
  76. package/build/commands/schema/application-command-type.schema.js.map +1 -0
  77. package/build/commands/schema/application-command-type.schema.json +9 -0
  78. package/build/commands/schema/application-integration-type.schema.d.ts +6 -0
  79. package/build/commands/schema/application-integration-type.schema.d.ts.map +1 -0
  80. package/build/commands/schema/application-integration-type.schema.js +6 -0
  81. package/build/commands/schema/application-integration-type.schema.js.map +1 -0
  82. package/build/commands/schema/application-integration-type.schema.json +8 -0
  83. package/build/commands/schema/channel-type.schema.d.ts +6 -0
  84. package/build/commands/schema/channel-type.schema.d.ts.map +1 -0
  85. package/build/commands/schema/channel-type.schema.js +6 -0
  86. package/build/commands/schema/channel-type.schema.js.map +1 -0
  87. package/build/commands/schema/channel-type.schema.json +16 -0
  88. package/build/commands/schema/chat-input-command.schema.d.ts +45 -0
  89. package/build/commands/schema/chat-input-command.schema.d.ts.map +1 -0
  90. package/build/commands/schema/chat-input-command.schema.js +34 -0
  91. package/build/commands/schema/chat-input-command.schema.js.map +1 -0
  92. package/build/commands/schema/chat-input-command.schema.json +46 -0
  93. package/build/commands/schema/commands-file.schema.d.ts +18 -0
  94. package/build/commands/schema/commands-file.schema.d.ts.map +1 -0
  95. package/build/commands/schema/commands-file.schema.js +16 -0
  96. package/build/commands/schema/commands-file.schema.js.map +1 -0
  97. package/build/commands/schema/commands-file.schema.json +14 -0
  98. package/build/commands/schema/context-menu-command.schema.d.ts +40 -0
  99. package/build/commands/schema/context-menu-command.schema.d.ts.map +1 -0
  100. package/build/commands/schema/context-menu-command.schema.js +32 -0
  101. package/build/commands/schema/context-menu-command.schema.js.map +1 -0
  102. package/build/commands/schema/context-menu-command.schema.json +40 -0
  103. package/build/commands/schema/context-menu-name.schema.d.ts +7 -0
  104. package/build/commands/schema/context-menu-name.schema.d.ts.map +1 -0
  105. package/build/commands/schema/context-menu-name.schema.js +7 -0
  106. package/build/commands/schema/context-menu-name.schema.js.map +1 -0
  107. package/build/commands/schema/context-menu-name.schema.json +6 -0
  108. package/build/commands/schema/default-member-permissions.schema.d.ts +7 -0
  109. package/build/commands/schema/default-member-permissions.schema.d.ts.map +1 -0
  110. package/build/commands/schema/default-member-permissions.schema.js +7 -0
  111. package/build/commands/schema/default-member-permissions.schema.js.map +1 -0
  112. package/build/commands/schema/default-member-permissions.schema.json +6 -0
  113. package/build/commands/schema/index.d.ts +77 -0
  114. package/build/commands/schema/index.d.ts.map +1 -0
  115. package/build/commands/schema/index.js +48 -0
  116. package/build/commands/schema/index.js.map +1 -0
  117. package/build/commands/schema/interaction-context-type.schema.d.ts +6 -0
  118. package/build/commands/schema/interaction-context-type.schema.d.ts.map +1 -0
  119. package/build/commands/schema/interaction-context-type.schema.js +6 -0
  120. package/build/commands/schema/interaction-context-type.schema.js.map +1 -0
  121. package/build/commands/schema/interaction-context-type.schema.json +9 -0
  122. package/build/commands/schema/option-name.schema.d.ts +7 -0
  123. package/build/commands/schema/option-name.schema.d.ts.map +1 -0
  124. package/build/commands/schema/option-name.schema.js +7 -0
  125. package/build/commands/schema/option-name.schema.js.map +1 -0
  126. package/build/commands/schema/option-name.schema.json +6 -0
  127. package/build/commands/schema/parse-commands-file.d.ts +19 -0
  128. package/build/commands/schema/parse-commands-file.d.ts.map +1 -0
  129. package/build/commands/schema/parse-commands-file.js +19 -0
  130. package/build/commands/schema/parse-commands-file.js.map +1 -0
  131. package/build/db/create-postgres-prisma-db.d.ts +20 -0
  132. package/build/db/create-postgres-prisma-db.d.ts.map +1 -0
  133. package/build/db/create-postgres-prisma-db.js +17 -0
  134. package/build/db/create-postgres-prisma-db.js.map +1 -0
  135. package/build/db/index.d.ts +2 -0
  136. package/build/db/index.d.ts.map +1 -0
  137. package/build/db/index.js +2 -0
  138. package/build/db/index.js.map +1 -0
  139. package/build/dev/create-handler-watcher.d.ts +23 -0
  140. package/build/dev/create-handler-watcher.d.ts.map +1 -0
  141. package/build/dev/create-handler-watcher.js +55 -0
  142. package/build/dev/create-handler-watcher.js.map +1 -0
  143. package/build/dev/create-source-reloader.d.ts +37 -0
  144. package/build/dev/create-source-reloader.d.ts.map +1 -0
  145. package/build/dev/create-source-reloader.js +42 -0
  146. package/build/dev/create-source-reloader.js.map +1 -0
  147. package/build/dev/index.d.ts +3 -0
  148. package/build/dev/index.d.ts.map +1 -0
  149. package/build/dev/index.js +3 -0
  150. package/build/dev/index.js.map +1 -0
  151. package/build/dev/reload-loader.d.ts +11 -0
  152. package/build/dev/reload-loader.d.ts.map +1 -0
  153. package/build/dev/reload-loader.js +28 -0
  154. package/build/dev/reload-loader.js.map +1 -0
  155. package/build/env/define-env.d.ts +25 -0
  156. package/build/env/define-env.d.ts.map +1 -0
  157. package/build/env/define-env.js +24 -0
  158. package/build/env/define-env.js.map +1 -0
  159. package/build/env/helpers.d.ts +9 -0
  160. package/build/env/helpers.d.ts.map +1 -0
  161. package/build/env/helpers.js +9 -0
  162. package/build/env/helpers.js.map +1 -0
  163. package/build/env/index.d.ts +3 -0
  164. package/build/env/index.d.ts.map +1 -0
  165. package/build/env/index.js +3 -0
  166. package/build/env/index.js.map +1 -0
  167. package/build/i18n/create-command-localizer.d.ts +27 -0
  168. package/build/i18n/create-command-localizer.d.ts.map +1 -0
  169. package/build/i18n/create-command-localizer.js +40 -0
  170. package/build/i18n/create-command-localizer.js.map +1 -0
  171. package/build/i18n/create-i18n-initializer.d.ts +18 -0
  172. package/build/i18n/create-i18n-initializer.d.ts.map +1 -0
  173. package/build/i18n/create-i18n-initializer.js +34 -0
  174. package/build/i18n/create-i18n-initializer.js.map +1 -0
  175. package/build/i18n/index.d.ts +3 -0
  176. package/build/i18n/index.d.ts.map +1 -0
  177. package/build/i18n/index.js +3 -0
  178. package/build/i18n/index.js.map +1 -0
  179. package/build/index.d.ts +8 -0
  180. package/build/index.d.ts.map +1 -0
  181. package/build/index.js +12 -0
  182. package/build/index.js.map +1 -0
  183. package/build/interactions/custom-id.d.ts +9 -0
  184. package/build/interactions/custom-id.d.ts.map +1 -0
  185. package/build/interactions/custom-id.js +15 -0
  186. package/build/interactions/custom-id.js.map +1 -0
  187. package/build/interactions/dispatch.d.ts +35 -0
  188. package/build/interactions/dispatch.d.ts.map +1 -0
  189. package/build/interactions/dispatch.js +87 -0
  190. package/build/interactions/dispatch.js.map +1 -0
  191. package/build/interactions/handle-interaction-error.d.ts +22 -0
  192. package/build/interactions/handle-interaction-error.d.ts.map +1 -0
  193. package/build/interactions/handle-interaction-error.js +65 -0
  194. package/build/interactions/handle-interaction-error.js.map +1 -0
  195. package/build/interactions/index.d.ts +7 -0
  196. package/build/interactions/index.d.ts.map +1 -0
  197. package/build/interactions/index.js +7 -0
  198. package/build/interactions/index.js.map +1 -0
  199. package/build/interactions/registry.d.ts +32 -0
  200. package/build/interactions/registry.d.ts.map +1 -0
  201. package/build/interactions/registry.js +49 -0
  202. package/build/interactions/registry.js.map +1 -0
  203. package/build/interactions/router.d.ts +28 -0
  204. package/build/interactions/router.d.ts.map +1 -0
  205. package/build/interactions/router.js +48 -0
  206. package/build/interactions/router.js.map +1 -0
  207. package/build/interactions/types.d.ts +37 -0
  208. package/build/interactions/types.d.ts.map +1 -0
  209. package/build/interactions/types.js +2 -0
  210. package/build/interactions/types.js.map +1 -0
  211. package/build/logger/create-logger.d.ts +27 -0
  212. package/build/logger/create-logger.d.ts.map +1 -0
  213. package/build/logger/create-logger.js +36 -0
  214. package/build/logger/create-logger.js.map +1 -0
  215. package/build/logger/dev-null-logger.d.ts +11 -0
  216. package/build/logger/dev-null-logger.d.ts.map +1 -0
  217. package/build/logger/dev-null-logger.js +19 -0
  218. package/build/logger/dev-null-logger.js.map +1 -0
  219. package/build/logger/discord-webhook-batcher.d.ts +38 -0
  220. package/build/logger/discord-webhook-batcher.d.ts.map +1 -0
  221. package/build/logger/discord-webhook-batcher.js +87 -0
  222. package/build/logger/discord-webhook-batcher.js.map +1 -0
  223. package/build/logger/discord-webhook-transport.d.ts +9 -0
  224. package/build/logger/discord-webhook-transport.d.ts.map +1 -0
  225. package/build/logger/discord-webhook-transport.js +20 -0
  226. package/build/logger/discord-webhook-transport.js.map +1 -0
  227. package/build/logger/index.d.ts +5 -0
  228. package/build/logger/index.d.ts.map +1 -0
  229. package/build/logger/index.js +5 -0
  230. package/build/logger/index.js.map +1 -0
  231. package/build/logger/logger.d.ts +30 -0
  232. package/build/logger/logger.d.ts.map +1 -0
  233. package/build/logger/logger.js +84 -0
  234. package/build/logger/logger.js.map +1 -0
  235. package/build/logger/pino-pretty-options.d.ts +12 -0
  236. package/build/logger/pino-pretty-options.d.ts.map +1 -0
  237. package/build/logger/pino-pretty-options.js +17 -0
  238. package/build/logger/pino-pretty-options.js.map +1 -0
  239. package/build/logger/types.d.ts +6 -0
  240. package/build/logger/types.d.ts.map +1 -0
  241. package/build/logger/types.js +2 -0
  242. package/build/logger/types.js.map +1 -0
  243. package/build/utils/discord-lookups.d.ts +16 -0
  244. package/build/utils/discord-lookups.d.ts.map +1 -0
  245. package/build/utils/discord-lookups.js +39 -0
  246. package/build/utils/discord-lookups.js.map +1 -0
  247. package/build/utils/get-git-data.d.ts +8 -0
  248. package/build/utils/get-git-data.d.ts.map +1 -0
  249. package/build/utils/get-git-data.js +18 -0
  250. package/build/utils/get-git-data.js.map +1 -0
  251. package/build/utils/index.d.ts +7 -0
  252. package/build/utils/index.d.ts.map +1 -0
  253. package/build/utils/index.js +7 -0
  254. package/build/utils/index.js.map +1 -0
  255. package/build/utils/messaging.d.ts +15 -0
  256. package/build/utils/messaging.d.ts.map +1 -0
  257. package/build/utils/messaging.js +71 -0
  258. package/build/utils/messaging.js.map +1 -0
  259. package/build/utils/promises.d.ts +6 -0
  260. package/build/utils/promises.d.ts.map +1 -0
  261. package/build/utils/promises.js +13 -0
  262. package/build/utils/promises.js.map +1 -0
  263. package/build/utils/run-attempts.d.ts +6 -0
  264. package/build/utils/run-attempts.d.ts.map +1 -0
  265. package/build/utils/run-attempts.js +16 -0
  266. package/build/utils/run-attempts.js.map +1 -0
  267. package/build/utils/strings.d.ts +7 -0
  268. package/build/utils/strings.d.ts.map +1 -0
  269. package/build/utils/strings.js +39 -0
  270. package/build/utils/strings.js.map +1 -0
  271. package/package.json +146 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-http-exception.d.ts","sourceRoot":"","sources":["../../src/api-client/api-http-exception.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAiB,SAAQ,KAAK;aACb,OAAO,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;aAAkB,KAAK,CAAC,EAAE,OAAO;gBAAhF,OAAO,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM,EAAkB,KAAK,CAAC,EAAE,OAAO,YAAA;CAG7G"}
@@ -0,0 +1,12 @@
1
+ export class ApiHttpException extends Error {
2
+ message;
3
+ status;
4
+ cause;
5
+ constructor(message, status, cause) {
6
+ super(message);
7
+ this.message = message;
8
+ this.status = status;
9
+ this.cause = cause;
10
+ }
11
+ }
12
+ //# sourceMappingURL=api-http-exception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-http-exception.js","sourceRoot":"","sources":["../../src/api-client/api-http-exception.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACb;IAAiC;IAAgC;IAA7F,YAA4B,OAAe,EAAkB,MAAc,EAAkB,KAAe;QAC1G,KAAK,CAAC,OAAO,CAAC,CAAC;QADW,YAAO,GAAP,OAAO,CAAQ;QAAkB,WAAM,GAAN,MAAM,CAAQ;QAAkB,UAAK,GAAL,KAAK,CAAU;IAE5G,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export * from './api-client.js';
2
+ export * from './api-http-exception.js';
3
+ export * from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api-client/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './api-client.js';
2
+ export * from './api-http-exception.js';
3
+ export * from './types.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api-client/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,105 @@
1
+ export declare enum ApiAuthType {
2
+ QUERY_PARAM = "query_param",
3
+ AUTHORIZATION_HEADER = "bearer",
4
+ CUSTOM_HEADER = "custom_header",
5
+ PATH_SEGMENT = "path_segment"
6
+ }
7
+ export interface BaseApiAuthMethod {
8
+ type: ApiAuthType;
9
+ }
10
+ export interface QueryParamApiAuthMethod extends BaseApiAuthMethod {
11
+ type: ApiAuthType.QUERY_PARAM;
12
+ paramName: string;
13
+ /** Returns the param value, e.g. `() => env.API_TOKEN` */
14
+ getValue: () => string;
15
+ }
16
+ export interface BearerTokenApiAuthMethod extends BaseApiAuthMethod {
17
+ type: ApiAuthType.AUTHORIZATION_HEADER;
18
+ /**
19
+ * @default 'Bearer'
20
+ */
21
+ tokenType?: string;
22
+ /** Returns the bearer token, e.g. `() => env.API_TOKEN` */
23
+ getValue: () => string;
24
+ }
25
+ export interface CustomHeaderApiAuthMethod extends BaseApiAuthMethod {
26
+ type: ApiAuthType.CUSTOM_HEADER;
27
+ headerName: string;
28
+ /** Returns the header value, e.g. `() => env.API_TOKEN` */
29
+ getValue: () => string;
30
+ }
31
+ export interface PathSegmentApiAuthMethod extends BaseApiAuthMethod {
32
+ type: ApiAuthType.PATH_SEGMENT;
33
+ /**
34
+ * Placeholder in `path` to substitute with the token value, e.g. `:token`
35
+ * @default ':token'
36
+ */
37
+ placeholder?: string;
38
+ /** Returns the value to substitute into the path, e.g. `() => env.API_TOKEN` */
39
+ getValue: () => string;
40
+ }
41
+ export type ApiAuthMethod = QueryParamApiAuthMethod | BearerTokenApiAuthMethod | PathSegmentApiAuthMethod | CustomHeaderApiAuthMethod;
42
+ /**
43
+ * Structural subset of typia's `IValidation<T>` shape. Bots that already use
44
+ * typia can pass `typia.createValidate<T>()` directly; bots that don't can
45
+ * hand-write a check or omit `validator` entirely to get `response: unknown`.
46
+ */
47
+ export type ValidationResult<T> = {
48
+ success: true;
49
+ data: T;
50
+ } | {
51
+ success: false;
52
+ errors: unknown[];
53
+ };
54
+ export interface ApiRequest<T> {
55
+ path: string;
56
+ method?: string;
57
+ query?: Record<string, string>;
58
+ body?: unknown;
59
+ /**
60
+ * If true, the response will not be JSON parsed and `raw` stream data is
61
+ * returned instead.
62
+ */
63
+ raw?: boolean;
64
+ /**
65
+ * Validates/narrows the parsed response. If omitted, `response` is typed
66
+ * as `unknown` and no validation is performed.
67
+ */
68
+ validator?: (data: unknown) => ValidationResult<T>;
69
+ /**
70
+ * Throw an error if the response does not pass validation
71
+ * @default true
72
+ */
73
+ failOnInvalidResponse?: boolean;
74
+ }
75
+ export interface ApiResponse<T> {
76
+ responseText: string | undefined;
77
+ response: T;
78
+ validation?: ValidationResult<T>;
79
+ ok: boolean;
80
+ status: number;
81
+ }
82
+ export interface RetryOptions {
83
+ /**
84
+ * Total number of attempts (first try + retries).
85
+ * @default 1 (no retries)
86
+ */
87
+ maxAttempts?: number;
88
+ /**
89
+ * Delay before the first retry in milliseconds. Doubles on each subsequent retry.
90
+ * @default 500
91
+ */
92
+ initialDelayMs?: number;
93
+ /**
94
+ * Return true to retry after this error. By default retries on 5xx and 429.
95
+ */
96
+ shouldRetry?: (error: unknown) => boolean;
97
+ }
98
+ export interface ApiClientOptions {
99
+ baseUrl: string;
100
+ authentication?: Readonly<ApiAuthMethod>;
101
+ fixedHeaders?: Readonly<Record<string, string>>;
102
+ userAgent?: string;
103
+ retry?: RetryOptions;
104
+ }
105
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api-client/types.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,WAAW,gBAAgB;IAC3B,oBAAoB,WAAW;IAC/B,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,EAAE,WAAW,CAAC,oBAAoB,CAAC;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,IAAI,EAAE,WAAW,CAAC,aAAa,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC;IAC/B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,aAAa,GACrB,uBAAuB,GACvB,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAC1B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACnD;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,CAAC,CAAC;IACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB"}
@@ -0,0 +1,8 @@
1
+ export var ApiAuthType;
2
+ (function (ApiAuthType) {
3
+ ApiAuthType["QUERY_PARAM"] = "query_param";
4
+ ApiAuthType["AUTHORIZATION_HEADER"] = "bearer";
5
+ ApiAuthType["CUSTOM_HEADER"] = "custom_header";
6
+ ApiAuthType["PATH_SEGMENT"] = "path_segment";
7
+ })(ApiAuthType || (ApiAuthType = {}));
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api-client/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,0CAA2B,CAAA;IAC3B,8CAA+B,CAAA;IAC/B,8CAA+B,CAAA;IAC/B,4CAA6B,CAAA;AAC/B,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB"}
@@ -0,0 +1,14 @@
1
+ import { Client, ClientOptions, Interaction } from 'discord.js';
2
+ export interface CreateBotClientOptions extends Omit<ClientOptions, 'intents'> {
3
+ intents: ClientOptions['intents'];
4
+ token: string;
5
+ onReady?: (client: Client<true>) => void | Promise<void>;
6
+ onInteraction: (interaction: Interaction) => void | Promise<void>;
7
+ }
8
+ /**
9
+ * Creates and logs in a single (unsharded) discord.js Client, wiring the
10
+ * `ready` and `interactionCreate` events. For bots that shard, see
11
+ * `createShardManager` instead.
12
+ */
13
+ export declare function createBotClient(options: CreateBotClientOptions): Promise<Client<true>>;
14
+ //# sourceMappingURL=create-bot-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-bot-client.d.ts","sourceRoot":"","sources":["../../src/client/create-bot-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAU,WAAW,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC;IAC5E,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,aAAa,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAa5F"}
@@ -0,0 +1,19 @@
1
+ import { Client, Events } from 'discord.js';
2
+ /**
3
+ * Creates and logs in a single (unsharded) discord.js Client, wiring the
4
+ * `ready` and `interactionCreate` events. For bots that shard, see
5
+ * `createShardManager` instead.
6
+ */
7
+ export async function createBotClient(options) {
8
+ const { token, onReady, onInteraction, ...clientOptions } = options;
9
+ const client = new Client(clientOptions);
10
+ if (onReady) {
11
+ client.on(Events.ClientReady, onReady);
12
+ }
13
+ client.on(Events.InteractionCreate, async (interaction) => {
14
+ await onInteraction(interaction);
15
+ });
16
+ await client.login(token);
17
+ return client;
18
+ }
19
+ //# sourceMappingURL=create-bot-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-bot-client.js","sourceRoot":"","sources":["../../src/client/create-bot-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,EAAe,MAAM,YAAY,CAAC;AASxE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA+B;IACnE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC;IAEzC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;QACxD,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,MAAsB,CAAC;AAChC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ShardingManager, ShardingManagerOptions } from 'discord.js';
2
+ import { NestableLogger } from '../logger/types.js';
3
+ export interface CreateShardManagerOptions extends Omit<ShardingManagerOptions, 'token'> {
4
+ token: string;
5
+ botScriptPath: string;
6
+ logger: NestableLogger;
7
+ /** Runs once before shards are spawned, e.g. to sync slash commands. */
8
+ beforeSpawn?: () => Promise<void>;
9
+ }
10
+ /**
11
+ * Thin wrapper over discord.js's `ShardingManager`: forwards shard lifecycle
12
+ * events to the given logger and spawns shards, optionally running a
13
+ * `beforeSpawn` hook first. Kept deliberately minimal — orchestration logic
14
+ * specific to a bot (e.g. what exactly `beforeSpawn` does) stays bot-side.
15
+ */
16
+ export declare function createShardManager(options: CreateShardManagerOptions): Promise<ShardingManager>;
17
+ //# sourceMappingURL=create-shard-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-shard-manager.d.ts","sourceRoot":"","sources":["../../src/client/create-shard-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBrG"}
@@ -0,0 +1,26 @@
1
+ import { ShardingManager } from 'discord.js';
2
+ /**
3
+ * Thin wrapper over discord.js's `ShardingManager`: forwards shard lifecycle
4
+ * events to the given logger and spawns shards, optionally running a
5
+ * `beforeSpawn` hook first. Kept deliberately minimal — orchestration logic
6
+ * specific to a bot (e.g. what exactly `beforeSpawn` does) stays bot-side.
7
+ */
8
+ export async function createShardManager(options) {
9
+ const { token, botScriptPath, logger, beforeSpawn, ...managerOptions } = options;
10
+ if (beforeSpawn) {
11
+ await beforeSpawn();
12
+ }
13
+ logger.log(`Starting recommended number of shards with path ${botScriptPath}`);
14
+ const manager = new ShardingManager(botScriptPath, { token, ...managerOptions });
15
+ manager.on('shardCreate', (shard) => {
16
+ logger.log(`Shard ${shard.id} created`);
17
+ shard.on('spawn', () => logger.log(`Shard ${shard.id} spawned`));
18
+ shard.on('ready', () => logger.log(`Shard ${shard.id} ready`));
19
+ shard.on('disconnect', () => logger.log(`Shard ${shard.id} disconnected`));
20
+ shard.on('reconnecting', () => logger.log(`Shard ${shard.id} reconnecting`));
21
+ shard.on('death', () => logger.log(`Shard ${shard.id} died`));
22
+ });
23
+ await manager.spawn();
24
+ return manager;
25
+ }
26
+ //# sourceMappingURL=create-shard-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-shard-manager.js","sourceRoot":"","sources":["../../src/client/create-shard-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;AAWrE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACzE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,CAAC;IAEjF,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,mDAAmD,aAAa,EAAE,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IAEjF,OAAO,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;QAClC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/D,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;QAC3E,KAAK,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;QAC7E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './create-bot-client.js';
2
+ export * from './create-shard-manager.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './create-bot-client.js';
2
+ export * from './create-shard-manager.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';
2
+ import { NamedChatInputCommand, NamedContextMenuCommand, Registry } from '../interactions/registry.js';
3
+ import { BaseInteractionContext } from '../interactions/types.js';
4
+ import { CommandFileEntry } from './schema/index.js';
5
+ export type DescriptionResolver = (path: readonly string[]) => string | undefined;
6
+ export type LocalizationResolver = (path: readonly string[]) => Record<string, string> | undefined;
7
+ export interface BuildApplicationCommandsBodyOptions {
8
+ /** Merged into every commands.json entry. The entry's own fields win on conflict. */
9
+ sharedMetadata?: Partial<RESTPostAPIApplicationCommandsJSONBody>;
10
+ /**
11
+ * Called with a dot-path-shaped key array (e.g. `['commands', 'search', 'description']`,
12
+ * or `['commands', 'search', 'options', 'query', 'description']`) for every
13
+ * command/option whose commands.json entry has no `description` of its own.
14
+ * Pass a `createCommandLocalizer(...).resolveDescription` here to fill
15
+ * descriptions from i18next at submission time instead of authoring them
16
+ * by hand in commands.json.
17
+ */
18
+ resolveDescription?: DescriptionResolver;
19
+ /** Same path convention as `resolveDescription`, but for `name`/`name_localizations`. */
20
+ localizeNames?: LocalizationResolver;
21
+ /** Same path convention as `resolveDescription`, but for `description_localizations`. */
22
+ localizeDescriptions?: LocalizationResolver;
23
+ }
24
+ export interface BuildApplicationCommandsBodyRegistries<Ctx extends BaseInteractionContext, ChatInputName extends string = string, ContextMenuName extends string = string> {
25
+ chatInput?: Registry<ChatInputName, NamedChatInputCommand<Ctx, ChatInputName>>;
26
+ contextMenu?: Registry<ContextMenuName, NamedContextMenuCommand<Ctx, ContextMenuName>>;
27
+ }
28
+ /**
29
+ * Builds the flat `RESTPostAPIApplicationCommandsJSONBody[]` `createCommandRegistrar`
30
+ * expects from a validated commands.json array plus the bot's handler registries.
31
+ * `commandsFile`'s own order drives the output order (not registry insertion order).
32
+ *
33
+ * Every commands.json entry must have a matching handler, and every handler must have
34
+ * a matching commands.json entry - both directions throw one combined error listing
35
+ * every offender, same as a command/option left with no resolvable description. This
36
+ * never silently sends an incomplete body to Discord's API.
37
+ */
38
+ export declare function buildApplicationCommandsBody<Ctx extends BaseInteractionContext>(commandsFile: readonly CommandFileEntry[], registries: BuildApplicationCommandsBodyRegistries<Ctx>, options?: BuildApplicationCommandsBodyOptions): RESTPostAPIApplicationCommandsJSONBody[];
39
+ //# sourceMappingURL=build-application-commands-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-application-commands-body.d.ts","sourceRoot":"","sources":["../../src/commands/build-application-commands-body.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,sCAAsC,EAAE,MAAM,uBAAuB,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAuD,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1G,MAAM,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS,CAAC;AAClF,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;AAEnG,MAAM,WAAW,mCAAmC;IAClD,qFAAqF;IACrF,cAAc,CAAC,EAAE,OAAO,CAAC,sCAAsC,CAAC,CAAC;IACjE;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;IACzC,yFAAyF;IACzF,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,yFAAyF;IACzF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,MAAM,WAAW,sCAAsC,CACrD,GAAG,SAAS,sBAAsB,EAClC,aAAa,SAAS,MAAM,GAAG,MAAM,EACrC,eAAe,SAAS,MAAM,GAAG,MAAM;IAEvC,SAAS,CAAC,EAAE,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC/E,WAAW,CAAC,EAAE,QAAQ,CAAC,eAAe,EAAE,uBAAuB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;CACxF;AAmED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,SAAS,sBAAsB,EAC7E,YAAY,EAAE,SAAS,gBAAgB,EAAE,EACzC,UAAU,EAAE,sCAAsC,CAAC,GAAG,CAAC,EACvD,OAAO,GAAE,mCAAwC,GAChD,sCAAsC,EAAE,CAyE1C"}
@@ -0,0 +1,127 @@
1
+ function sortRequiredOptionsFirst(options) {
2
+ if (!options)
3
+ return options;
4
+ return [...options]
5
+ .sort((a, b) => Number('required' in b && b.required === true) - Number('required' in a && a.required === true))
6
+ .map((option) => {
7
+ if ('options' in option && option.options) {
8
+ return { ...option, options: sortRequiredOptionsFirst(option.options) };
9
+ }
10
+ return option;
11
+ });
12
+ }
13
+ function resolveOptionsDescriptions(optionsList, basePath, ctx) {
14
+ if (!optionsList)
15
+ return undefined;
16
+ return optionsList.map((option) => {
17
+ const optionPath = [...basePath, 'options', option.name];
18
+ const description = option.description ?? ctx.resolveDescription?.([...optionPath, 'description']);
19
+ if (!description) {
20
+ ctx.missingDescriptions.push(`"${ctx.commandName}" > "${option.name}" (option)`);
21
+ }
22
+ const nameLocalizations = ctx.localizeNames?.([...optionPath, 'name']);
23
+ const descriptionLocalizations = ctx.localizeDescriptions?.([...optionPath, 'description']);
24
+ const nestedOptions = 'options' in option && option.options
25
+ ? resolveOptionsDescriptions(option.options, optionPath, ctx)
26
+ : undefined;
27
+ return {
28
+ ...option,
29
+ description: description ?? '',
30
+ ...(nameLocalizations ? { name_localizations: nameLocalizations } : {}),
31
+ ...(descriptionLocalizations ? { description_localizations: descriptionLocalizations } : {}),
32
+ ...(nestedOptions ? { options: nestedOptions } : {}),
33
+ };
34
+ });
35
+ }
36
+ function formatValidationErrors(unmatchedFileEntries, unmatchedHandlers, missingDescriptions) {
37
+ const sections = [];
38
+ if (unmatchedFileEntries.length) {
39
+ sections.push(['Commands in commands.json with no matching handler:', ...unmatchedFileEntries.map((n) => ` - "${n}"`)].join('\n'));
40
+ }
41
+ if (unmatchedHandlers.length) {
42
+ sections.push(['Handlers registered with no matching commands.json entry:', ...unmatchedHandlers.map((n) => ` - "${n}"`)].join('\n'));
43
+ }
44
+ if (missingDescriptions.length) {
45
+ sections.push(['Commands/options missing a description (in commands.json and localize hook):', ...missingDescriptions.map((n) => ` - ${n}`)].join('\n'));
46
+ }
47
+ return `Command registration validation failed:\n${sections.join('\n')}`;
48
+ }
49
+ /**
50
+ * Builds the flat `RESTPostAPIApplicationCommandsJSONBody[]` `createCommandRegistrar`
51
+ * expects from a validated commands.json array plus the bot's handler registries.
52
+ * `commandsFile`'s own order drives the output order (not registry insertion order).
53
+ *
54
+ * Every commands.json entry must have a matching handler, and every handler must have
55
+ * a matching commands.json entry - both directions throw one combined error listing
56
+ * every offender, same as a command/option left with no resolvable description. This
57
+ * never silently sends an incomplete body to Discord's API.
58
+ */
59
+ export function buildApplicationCommandsBody(commandsFile, registries, options = {}) {
60
+ const { sharedMetadata = {}, resolveDescription, localizeNames, localizeDescriptions } = options;
61
+ const body = [];
62
+ const unmatchedFileEntries = [];
63
+ const missingDescriptions = [];
64
+ const chatInputFileNames = new Set();
65
+ const contextMenuFileNames = new Set();
66
+ for (const entry of commandsFile) {
67
+ const isChatInput = entry.type === 1;
68
+ if (isChatInput) {
69
+ chatInputFileNames.add(entry.name);
70
+ }
71
+ else {
72
+ contextMenuFileNames.add(entry.name);
73
+ }
74
+ const command = isChatInput ? registries.chatInput?.byName[entry.name] : registries.contextMenu?.byName[entry.name];
75
+ if (!command) {
76
+ unmatchedFileEntries.push(entry.name);
77
+ continue;
78
+ }
79
+ if (command.registerCondition && !command.registerCondition())
80
+ continue;
81
+ const nameLocalizations = localizeNames?.(['commands', entry.name, 'name']);
82
+ if (isChatInput) {
83
+ const chatEntry = entry;
84
+ const description = chatEntry.description ?? resolveDescription?.(['commands', chatEntry.name, 'description']);
85
+ if (!description) {
86
+ missingDescriptions.push(`"${chatEntry.name}" (command)`);
87
+ }
88
+ const resolvedOptions = resolveOptionsDescriptions(chatEntry.options, ['commands', chatEntry.name], {
89
+ resolveDescription,
90
+ localizeNames,
91
+ localizeDescriptions,
92
+ missingDescriptions,
93
+ commandName: chatEntry.name,
94
+ });
95
+ const descriptionLocalizations = localizeDescriptions?.(['commands', chatEntry.name, 'description']);
96
+ body.push({
97
+ ...sharedMetadata,
98
+ ...chatEntry,
99
+ description: description ?? '',
100
+ options: sortRequiredOptionsFirst(resolvedOptions),
101
+ ...(nameLocalizations ? { name_localizations: nameLocalizations } : {}),
102
+ ...(descriptionLocalizations ? { description_localizations: descriptionLocalizations } : {}),
103
+ });
104
+ }
105
+ else {
106
+ body.push({
107
+ ...sharedMetadata,
108
+ ...entry,
109
+ ...(nameLocalizations ? { name_localizations: nameLocalizations } : {}),
110
+ });
111
+ }
112
+ }
113
+ const unmatchedHandlers = [];
114
+ for (const name of registries.chatInput?.names ?? []) {
115
+ if (!chatInputFileNames.has(name))
116
+ unmatchedHandlers.push(name);
117
+ }
118
+ for (const name of registries.contextMenu?.names ?? []) {
119
+ if (!contextMenuFileNames.has(name))
120
+ unmatchedHandlers.push(name);
121
+ }
122
+ if (unmatchedFileEntries.length || unmatchedHandlers.length || missingDescriptions.length) {
123
+ throw new Error(formatValidationErrors(unmatchedFileEntries, unmatchedHandlers, missingDescriptions));
124
+ }
125
+ return body;
126
+ }
127
+ //# sourceMappingURL=build-application-commands-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-application-commands-body.js","sourceRoot":"","sources":["../../src/commands/build-application-commands-body.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { BaseInteractionContext, BotChatInputCommand } from '../interactions/types.js';
2
+ /**
3
+ * Builds a chat-input command handler that always replies with the same
4
+ * static content, for trivial "fun" commands with no logic (e.g. `/rekt`,
5
+ * `/yes`). The command's name/description now live in the bot's
6
+ * commands.json file, not here - pair this with a registry entry like
7
+ * `{ name: 'ping', ...fixedReplyCommandFactory('pong') }`.
8
+ */
9
+ export declare function fixedReplyCommandFactory<Ctx extends BaseInteractionContext>(content: string, ephemeral?: boolean): BotChatInputCommand<Ctx>;
10
+ //# sourceMappingURL=fixed-reply-command-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixed-reply-command-factory.d.ts","sourceRoot":"","sources":["../../src/commands/fixed-reply-command-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEvF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,SAAS,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,CASzI"}
@@ -0,0 +1,19 @@
1
+ import { MessageFlags } from 'discord-api-types/v10';
2
+ /**
3
+ * Builds a chat-input command handler that always replies with the same
4
+ * static content, for trivial "fun" commands with no logic (e.g. `/rekt`,
5
+ * `/yes`). The command's name/description now live in the bot's
6
+ * commands.json file, not here - pair this with a registry entry like
7
+ * `{ name: 'ping', ...fixedReplyCommandFactory('pong') }`.
8
+ */
9
+ export function fixedReplyCommandFactory(content, ephemeral = false) {
10
+ return {
11
+ async handle(interaction) {
12
+ await interaction.reply({
13
+ content,
14
+ flags: ephemeral ? MessageFlags.Ephemeral : undefined,
15
+ });
16
+ },
17
+ };
18
+ }
19
+ //# sourceMappingURL=fixed-reply-command-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixed-reply-command-factory.js","sourceRoot":"","sources":["../../src/commands/fixed-reply-command-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAqC,OAAe,EAAE,SAAS,GAAG,KAAK;IAC7G,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,WAAW;YACtB,MAAM,WAAW,CAAC,KAAK,CAAC;gBACtB,OAAO;gBACP,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;aACtD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './registration.js';
2
+ export * from './fixed-reply-command-factory.js';
3
+ export * from './build-application-commands-body.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './registration.js';
2
+ export * from './fixed-reply-command-factory.js';
3
+ export * from './build-application-commands-body.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Snowflake } from 'discord-api-types/globals';
2
+ import { RESTPostAPIApplicationCommandsJSONBody, RESTPutAPIApplicationCommandsResult, RESTPutAPIApplicationGuildCommandsResult } from 'discord-api-types/v10';
3
+ import { REST } from '@discordjs/rest';
4
+ import { NestableLogger } from '../logger/types.js';
5
+ export interface CommandRegistrarOptions {
6
+ rest: REST;
7
+ applicationId: string;
8
+ logger: NestableLogger;
9
+ }
10
+ export interface CommandRegistrar {
11
+ getAuthorizedServers(): Promise<string[]>;
12
+ updateGuildCommands(guildId: Snowflake, body: RESTPostAPIApplicationCommandsJSONBody[]): Promise<RESTPutAPIApplicationGuildCommandsResult | undefined>;
13
+ cleanGuildCommands(guildId: Snowflake): Promise<void>;
14
+ updateGlobalCommands(body: RESTPostAPIApplicationCommandsJSONBody[]): Promise<RESTPutAPIApplicationCommandsResult | undefined>;
15
+ cleanGlobalCommands(): Promise<void>;
16
+ }
17
+ /**
18
+ * Wraps `@discordjs/rest` slash-command (re)registration/cleanup for both
19
+ * global and per-guild scopes. Exits the process on failure, matching the
20
+ * behavior every bot already relies on (a failed startup command sync should
21
+ * not silently continue running with stale commands).
22
+ */
23
+ export declare function createCommandRegistrar({ rest, applicationId, logger: baseLogger }: CommandRegistrarOptions): CommandRegistrar;
24
+ //# sourceMappingURL=registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/commands/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAEL,sCAAsC,EACtC,mCAAmC,EACnC,wCAAwC,EAEzC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,IAAI,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,mBAAmB,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,sCAAsC,EAAE,GAAG,OAAO,CAAC,wCAAwC,GAAG,SAAS,CAAC,CAAC;IACvJ,kBAAkB,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,oBAAoB,CAAC,IAAI,EAAE,sCAAsC,EAAE,GAAG,OAAO,CAAC,mCAAmC,GAAG,SAAS,CAAC,CAAC;IAC/H,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,uBAAuB,GAAG,gBAAgB,CAkE7H"}
@@ -0,0 +1,69 @@
1
+ import { Routes, } from 'discord-api-types/v10';
2
+ /**
3
+ * Wraps `@discordjs/rest` slash-command (re)registration/cleanup for both
4
+ * global and per-guild scopes. Exits the process on failure, matching the
5
+ * behavior every bot already relies on (a failed startup command sync should
6
+ * not silently continue running with stale commands).
7
+ */
8
+ export function createCommandRegistrar({ rest, applicationId, logger: baseLogger }) {
9
+ return {
10
+ async getAuthorizedServers() {
11
+ const logger = baseLogger.nest('getAuthorizedServers');
12
+ logger.log('Getting authorized servers…');
13
+ const guilds = await rest.get(Routes.userGuilds());
14
+ logger.log(`Found ${guilds.length} authorized server${guilds.length === 1 ? '' : 's'}`);
15
+ return guilds.map((guild) => guild.id);
16
+ },
17
+ async updateGuildCommands(guildId, body) {
18
+ const logger = baseLogger.nest(['updateGuildCommands', `Guild#${guildId}`]);
19
+ try {
20
+ logger.log('Started reloading guild commands');
21
+ const result = await rest.put(Routes.applicationGuildCommands(applicationId, guildId), { body });
22
+ logger.log('Successfully reloaded guild commands');
23
+ return result;
24
+ }
25
+ catch (error) {
26
+ logger.error('Failed to reload guild commands', error);
27
+ process.exit(1);
28
+ }
29
+ },
30
+ async cleanGuildCommands(guildId) {
31
+ const logger = baseLogger.nest(['cleanGuildCommands', `Guild#${guildId}`]);
32
+ try {
33
+ logger.log('Started cleaning guild commands');
34
+ await rest.put(Routes.applicationGuildCommands(applicationId, guildId), { body: [] });
35
+ logger.log('Successfully cleaned guild commands');
36
+ }
37
+ catch (error) {
38
+ logger.error('Failed to clean guild commands', error);
39
+ process.exit(1);
40
+ }
41
+ },
42
+ async updateGlobalCommands(body) {
43
+ const logger = baseLogger.nest('updateGlobalCommands');
44
+ try {
45
+ logger.log('Started refreshing application commands');
46
+ const result = await rest.put(Routes.applicationCommands(applicationId), { body });
47
+ logger.log('Successfully reloaded application commands');
48
+ return result;
49
+ }
50
+ catch (error) {
51
+ logger.error('Failed to reload application commands', error);
52
+ process.exit(1);
53
+ }
54
+ },
55
+ async cleanGlobalCommands() {
56
+ const logger = baseLogger.nest('cleanGlobalCommands');
57
+ try {
58
+ logger.log('Started cleaning application commands');
59
+ await rest.put(Routes.applicationCommands(applicationId), { body: [] });
60
+ logger.log('Successfully cleaned application commands');
61
+ }
62
+ catch (error) {
63
+ logger.error('Failed to clean application commands', error);
64
+ process.exit(1);
65
+ }
66
+ },
67
+ };
68
+ }
69
+ //# sourceMappingURL=registration.js.map