@sapphire/plugin-api 6.1.2-next.fe95a62.0 → 7.0.0-next.08a81b1

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 (130) hide show
  1. package/dist/cjs/index.cjs +1 -1
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +78 -47
  4. package/dist/cjs/lib/structures/MediaParser.cjs +4 -8
  5. package/dist/cjs/lib/structures/MediaParser.cjs.map +1 -1
  6. package/dist/cjs/lib/structures/Middleware.cjs +1 -4
  7. package/dist/cjs/lib/structures/Middleware.cjs.map +1 -1
  8. package/dist/cjs/lib/structures/MiddlewareStore.cjs +6 -14
  9. package/dist/cjs/lib/structures/MiddlewareStore.cjs.map +1 -1
  10. package/dist/cjs/lib/structures/Route.cjs +12 -34
  11. package/dist/cjs/lib/structures/Route.cjs.map +1 -1
  12. package/dist/cjs/lib/structures/RouteLoaderStrategy.cjs +28 -0
  13. package/dist/cjs/lib/structures/RouteLoaderStrategy.cjs.map +1 -0
  14. package/dist/cjs/lib/structures/RouteStore.cjs +13 -20
  15. package/dist/cjs/lib/structures/RouteStore.cjs.map +1 -1
  16. package/dist/cjs/lib/structures/api/ApiRequest.cjs +1 -4
  17. package/dist/cjs/lib/structures/api/ApiRequest.cjs.map +1 -1
  18. package/dist/cjs/lib/structures/api/ApiResponse.cjs +1 -4
  19. package/dist/cjs/lib/structures/api/ApiResponse.cjs.map +1 -1
  20. package/dist/cjs/lib/structures/api/CookieStore.cjs +6 -11
  21. package/dist/cjs/lib/structures/api/CookieStore.cjs.map +1 -1
  22. package/dist/cjs/lib/structures/http/Auth.cjs +13 -33
  23. package/dist/cjs/lib/structures/http/Auth.cjs.map +1 -1
  24. package/dist/cjs/lib/structures/http/HttpMethods.cjs +37 -6
  25. package/dist/cjs/lib/structures/http/HttpMethods.cjs.map +1 -1
  26. package/dist/cjs/lib/structures/http/Server.cjs +1 -4
  27. package/dist/cjs/lib/structures/http/Server.cjs.map +1 -1
  28. package/dist/cjs/lib/utils/RouteData.cjs +10 -21
  29. package/dist/cjs/lib/utils/RouteData.cjs.map +1 -1
  30. package/dist/cjs/listeners/PluginRouteError.cjs +1 -2
  31. package/dist/cjs/listeners/PluginRouteError.cjs.map +1 -1
  32. package/dist/cjs/listeners/PluginServerMatch.cjs +2 -2
  33. package/dist/cjs/listeners/PluginServerMatch.cjs.map +1 -1
  34. package/dist/cjs/listeners/PluginServerMiddlewareError.cjs +1 -2
  35. package/dist/cjs/listeners/PluginServerMiddlewareError.cjs.map +1 -1
  36. package/dist/cjs/listeners/PluginServerMiddlewareSuccess.cjs +3 -3
  37. package/dist/cjs/listeners/PluginServerMiddlewareSuccess.cjs.map +1 -1
  38. package/dist/cjs/listeners/PluginServerNoMatch.cjs +1 -2
  39. package/dist/cjs/listeners/PluginServerNoMatch.cjs.map +1 -1
  40. package/dist/cjs/listeners/PluginServerRequest.cjs +5 -5
  41. package/dist/cjs/listeners/PluginServerRequest.cjs.map +1 -1
  42. package/dist/cjs/mediaParsers/applicationJson.cjs.map +1 -1
  43. package/dist/cjs/mediaParsers/textPlain.cjs.map +1 -1
  44. package/dist/cjs/middlewares/auth.cjs +2 -6
  45. package/dist/cjs/middlewares/auth.cjs.map +1 -1
  46. package/dist/cjs/middlewares/body.cjs +3 -8
  47. package/dist/cjs/middlewares/body.cjs.map +1 -1
  48. package/dist/cjs/middlewares/cookies.cjs +1 -4
  49. package/dist/cjs/middlewares/cookies.cjs.map +1 -1
  50. package/dist/cjs/middlewares/headers.cjs +15 -7
  51. package/dist/cjs/middlewares/headers.cjs.map +1 -1
  52. package/dist/cjs/routes/_load.cjs +4 -4
  53. package/dist/cjs/routes/_load.cjs.map +1 -1
  54. package/dist/cjs/routes/oauth/{callback.cjs → callback.post.cjs} +5 -10
  55. package/dist/cjs/routes/oauth/callback.post.cjs.map +1 -0
  56. package/dist/cjs/routes/oauth/{logout.cjs → logout.post.cjs} +8 -13
  57. package/dist/cjs/routes/oauth/logout.post.cjs.map +1 -0
  58. package/dist/esm/chunk-JTFKMR4I.mjs +15 -0
  59. package/dist/esm/index.d.mts +78 -47
  60. package/dist/esm/index.mjs +2 -2
  61. package/dist/esm/index.mjs.map +1 -1
  62. package/dist/esm/lib/structures/MediaParser.mjs +5 -9
  63. package/dist/esm/lib/structures/MediaParser.mjs.map +1 -1
  64. package/dist/esm/lib/structures/MediaParserStore.mjs +1 -1
  65. package/dist/esm/lib/structures/Middleware.mjs +1 -1
  66. package/dist/esm/lib/structures/Middleware.mjs.map +1 -1
  67. package/dist/esm/lib/structures/MiddlewareStore.mjs +6 -11
  68. package/dist/esm/lib/structures/MiddlewareStore.mjs.map +1 -1
  69. package/dist/esm/lib/structures/Route.mjs +12 -31
  70. package/dist/esm/lib/structures/Route.mjs.map +1 -1
  71. package/dist/esm/lib/structures/RouteLoaderStrategy.mjs +25 -0
  72. package/dist/esm/lib/structures/RouteLoaderStrategy.mjs.map +1 -0
  73. package/dist/esm/lib/structures/RouteStore.mjs +13 -17
  74. package/dist/esm/lib/structures/RouteStore.mjs.map +1 -1
  75. package/dist/esm/lib/structures/api/ApiRequest.mjs +1 -1
  76. package/dist/esm/lib/structures/api/ApiResponse.mjs +1 -1
  77. package/dist/esm/lib/structures/api/CookieStore.mjs +6 -8
  78. package/dist/esm/lib/structures/api/CookieStore.mjs.map +1 -1
  79. package/dist/esm/lib/structures/http/Auth.mjs +6 -12
  80. package/dist/esm/lib/structures/http/Auth.mjs.map +1 -1
  81. package/dist/esm/lib/structures/http/HttpCodes.mjs +1 -1
  82. package/dist/esm/lib/structures/http/HttpMethods.mjs +39 -5
  83. package/dist/esm/lib/structures/http/HttpMethods.mjs.map +1 -1
  84. package/dist/esm/lib/structures/http/Server.mjs +1 -1
  85. package/dist/esm/lib/structures/http/Server.mjs.map +1 -1
  86. package/dist/esm/lib/utils/MimeTypes.mjs +1 -1
  87. package/dist/esm/lib/utils/RouteData.mjs +10 -18
  88. package/dist/esm/lib/utils/RouteData.mjs.map +1 -1
  89. package/dist/esm/listeners/PluginRouteError.mjs +2 -3
  90. package/dist/esm/listeners/PluginRouteError.mjs.map +1 -1
  91. package/dist/esm/listeners/PluginServerMatch.mjs +3 -3
  92. package/dist/esm/listeners/PluginServerMatch.mjs.map +1 -1
  93. package/dist/esm/listeners/PluginServerMiddlewareError.mjs +2 -3
  94. package/dist/esm/listeners/PluginServerMiddlewareError.mjs.map +1 -1
  95. package/dist/esm/listeners/PluginServerMiddlewareSuccess.mjs +4 -4
  96. package/dist/esm/listeners/PluginServerMiddlewareSuccess.mjs.map +1 -1
  97. package/dist/esm/listeners/PluginServerNoMatch.mjs +2 -3
  98. package/dist/esm/listeners/PluginServerNoMatch.mjs.map +1 -1
  99. package/dist/esm/listeners/PluginServerRequest.mjs +6 -6
  100. package/dist/esm/listeners/PluginServerRequest.mjs.map +1 -1
  101. package/dist/esm/listeners/_load.mjs +1 -1
  102. package/dist/esm/mediaParsers/_load.mjs +1 -1
  103. package/dist/esm/mediaParsers/applicationFormUrlEncoded.mjs +1 -1
  104. package/dist/esm/mediaParsers/applicationJson.mjs +1 -1
  105. package/dist/esm/mediaParsers/applicationJson.mjs.map +1 -1
  106. package/dist/esm/mediaParsers/textPlain.mjs +1 -1
  107. package/dist/esm/mediaParsers/textPlain.mjs.map +1 -1
  108. package/dist/esm/middlewares/_load.mjs +1 -1
  109. package/dist/esm/middlewares/auth.mjs +2 -3
  110. package/dist/esm/middlewares/auth.mjs.map +1 -1
  111. package/dist/esm/middlewares/body.mjs +3 -5
  112. package/dist/esm/middlewares/body.mjs.map +1 -1
  113. package/dist/esm/middlewares/cookies.mjs +1 -1
  114. package/dist/esm/middlewares/cookies.mjs.map +1 -1
  115. package/dist/esm/middlewares/headers.mjs +15 -4
  116. package/dist/esm/middlewares/headers.mjs.map +1 -1
  117. package/dist/esm/register.mjs +1 -1
  118. package/dist/esm/routes/_load.mjs +3 -3
  119. package/dist/esm/routes/_load.mjs.map +1 -1
  120. package/dist/esm/routes/oauth/{callback.mjs → callback.post.mjs} +5 -7
  121. package/dist/esm/routes/oauth/callback.post.mjs.map +1 -0
  122. package/dist/esm/routes/oauth/{logout.mjs → logout.post.mjs} +8 -13
  123. package/dist/esm/routes/oauth/logout.post.mjs.map +1 -0
  124. package/package.json +9 -9
  125. package/dist/cjs/routes/oauth/callback.cjs.map +0 -1
  126. package/dist/cjs/routes/oauth/logout.cjs.map +0 -1
  127. package/dist/esm/chunk-PYETHG4R.mjs +0 -29
  128. package/dist/esm/routes/oauth/callback.mjs.map +0 -1
  129. package/dist/esm/routes/oauth/logout.mjs.map +0 -1
  130. /package/dist/esm/{chunk-PYETHG4R.mjs.map → chunk-JTFKMR4I.mjs.map} +0 -0
@@ -21,7 +21,7 @@ var _load_cjs$2 = require('./middlewares/_load.cjs');
21
21
  var _load_cjs$3 = require('./routes/_load.cjs');
22
22
 
23
23
  // src/index.ts
24
- var version = "6.1.2-next.fe95a62.0";
24
+ var version = "7.0.0-next.08a81b1";
25
25
 
26
26
  Object.defineProperty(exports, "loadListeners", {
27
27
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";AAKA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAEd,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AA+BpB,IAAM,UAAkB","sourcesContent":["import type { Server, ServerOptions } from './lib/structures/http/Server';\nimport type { MediaParserStore } from './lib/structures/MediaParserStore';\nimport type { MiddlewareStore } from './lib/structures/MiddlewareStore';\nimport type { RouteStore } from './lib/structures/RouteStore';\n\nexport * from './lib/structures/api/ApiRequest';\nexport * from './lib/structures/api/ApiResponse';\nexport * from './lib/structures/api/CookieStore';\nexport * from './lib/structures/http/Auth';\nexport * from './lib/structures/http/HttpCodes';\nexport * from './lib/structures/http/HttpMethods';\nexport * from './lib/structures/http/Server';\nexport * from './lib/structures/MediaParser';\nexport * from './lib/structures/MediaParserStore';\nexport * from './lib/structures/Middleware';\nexport * from './lib/structures/MiddlewareStore';\nexport * from './lib/structures/Route';\nexport * from './lib/structures/RouteStore';\nexport * from './lib/utils/MimeTypes';\nexport * from './lib/utils/RouteData';\n\nexport { loadListeners } from './listeners/_load';\nexport { loadMediaParsers } from './mediaParsers/_load';\nexport { loadMiddlewares } from './middlewares/_load';\nexport { loadRoutes } from './routes/_load';\n\ndeclare module 'discord.js' {\n\tinterface Client {\n\t\tserver: Server;\n\t}\n\n\tinterface ClientOptions {\n\t\tapi?: ServerOptions;\n\t}\n}\n\ndeclare module '@sapphire/pieces' {\n\tinterface StoreRegistryEntries {\n\t\troutes: RouteStore;\n\t\tmediaParsers: MediaParserStore;\n\t\tmiddlewares: MiddlewareStore;\n\t}\n\n\tinterface Container {\n\t\tserver: Server;\n\t}\n}\n\n/**\n * The [@sapphire/plugin-api](https://github.com/sapphiredev/plugins/blob/main/packages/api) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '6.1.2-next.fe95a62.0';\n"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";AAKA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAEd,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AA+BpB,IAAM,UAAkB","sourcesContent":["import type { Server, ServerOptions } from './lib/structures/http/Server';\nimport type { MediaParserStore } from './lib/structures/MediaParserStore';\nimport type { MiddlewareStore } from './lib/structures/MiddlewareStore';\nimport type { RouteStore } from './lib/structures/RouteStore';\n\nexport * from './lib/structures/api/ApiRequest';\nexport * from './lib/structures/api/ApiResponse';\nexport * from './lib/structures/api/CookieStore';\nexport * from './lib/structures/http/Auth';\nexport * from './lib/structures/http/HttpCodes';\nexport * from './lib/structures/http/HttpMethods';\nexport * from './lib/structures/http/Server';\nexport * from './lib/structures/MediaParser';\nexport * from './lib/structures/MediaParserStore';\nexport * from './lib/structures/Middleware';\nexport * from './lib/structures/MiddlewareStore';\nexport * from './lib/structures/Route';\nexport * from './lib/structures/RouteStore';\nexport * from './lib/utils/MimeTypes';\nexport * from './lib/utils/RouteData';\n\nexport { loadListeners } from './listeners/_load';\nexport { loadMediaParsers } from './mediaParsers/_load';\nexport { loadMiddlewares } from './middlewares/_load';\nexport { loadRoutes } from './routes/_load';\n\ndeclare module 'discord.js' {\n\tinterface Client {\n\t\tserver: Server;\n\t}\n\n\tinterface ClientOptions {\n\t\tapi?: ServerOptions;\n\t}\n}\n\ndeclare module '@sapphire/pieces' {\n\tinterface StoreRegistryEntries {\n\t\troutes: RouteStore;\n\t\tmediaParsers: MediaParserStore;\n\t\tmiddlewares: MiddlewareStore;\n\t}\n\n\tinterface Container {\n\t\tserver: Server;\n\t}\n}\n\n/**\n * The [@sapphire/plugin-api](https://github.com/sapphiredev/plugins/blob/main/packages/api) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '7.0.0-next.08a81b1';\n"]}
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { IncomingMessage, ServerResponse, Server as Server$1, ServerOptions as ServerOptions$1 } from 'node:http';
3
3
  import { ListenOptions } from 'node:net';
4
- import { Store, Piece } from '@sapphire/pieces';
4
+ import { Piece, Store } from '@sapphire/pieces';
5
5
  import { Awaitable } from '@sapphire/utilities';
6
6
  import { Gunzip } from 'zlib';
7
7
  import { Snowflake, OAuth2Scopes, RESTGetAPICurrentUserResult, RESTGetAPICurrentUserGuildsResult, RESTGetAPICurrentUserConnectionsResult, Collection } from 'discord.js';
@@ -45,14 +45,12 @@ declare class Auth {
45
45
  * Encrypts an object with aes-256-cbc to use as a token.
46
46
  * @since 1.0.0
47
47
  * @param data An object to encrypt
48
- * @param secret The secret to encrypt the data with
49
48
  */
50
49
  encrypt(data: AuthData): string;
51
50
  /**
52
51
  * Decrypts an object with aes-256-cbc to use as a token.
53
52
  * @since 1.0.0
54
53
  * @param token An data to decrypt
55
- * @param secret The secret to decrypt the data with
56
54
  */
57
55
  decrypt(token: string): AuthData | null;
58
56
  /**
@@ -226,10 +224,6 @@ interface ParsedPart {
226
224
  type: TypeState;
227
225
  }
228
226
 
229
- type Methods = 'ACL' | 'BIND' | 'CHECKOUT' | 'CONNECT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LINK' | 'LOCK' | 'M-SEARCH' | 'MERGE' | 'MKACTIVITY' | 'MKCALENDAR' | 'MKCOL' | 'MOVE' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PRI' | 'PROPFIND' | 'PROPPATCH' | 'PURGE' | 'PUT' | 'REBIND' | 'REPORT' | 'SEARCH' | 'SOURCE' | 'SUBSCRIBE' | 'TRACE' | 'UNBIND' | 'UNLINK' | 'UNLOCK' | 'UNSUBSCRIBE';
230
- declare const methods: Record<Methods, symbol>;
231
- declare const methodEntries: readonly [Methods, symbol][];
232
-
233
227
  declare enum MimeTypes {
234
228
  ApplicationFormUrlEncoded = "application/x-www-form-urlencoded",
235
229
  ApplicationJson = "application/json",
@@ -356,28 +350,16 @@ declare class ApiResponse<Request extends IncomingMessage = IncomingMessage> ext
356
350
  setContentType(contentType: MimeTypes): this;
357
351
  }
358
352
 
359
- interface MethodCallback {
360
- (request: ApiRequest, response: ApiResponse): unknown;
361
- }
362
- interface RouteMatch {
363
- route: Route;
364
- cb: MethodCallback;
365
- }
366
- /**
367
- * @since 1.0.0
368
- */
369
- declare class RouteStore extends Store<Route, 'routes'> {
370
- readonly table: Collection<Methods, Collection<Route<RouteOptions>, MethodCallback>>;
371
- constructor();
372
- match(request: ApiRequest): RouteMatch | null;
373
- private parseURL;
374
- }
353
+ type MethodName = (typeof MethodNames)[number];
354
+ declare const MethodNames: readonly ["ACL", "BIND", "CHECKOUT", "CONNECT", "COPY", "DELETE", "GET", "HEAD", "LINK", "LOCK", "M-SEARCH", "MERGE", "MKACTIVITY", "MKCALENDAR", "MKCOL", "MOVE", "NOTIFY", "OPTIONS", "PATCH", "POST", "PROPFIND", "PROPPATCH", "PURGE", "PUT", "REBIND", "REPORT", "SEARCH", "SOURCE", "SUBSCRIBE", "TRACE", "UNBIND", "UNLINK", "UNLOCK", "UNSUBSCRIBE"];
375
355
 
376
356
  interface RouteOptions extends Piece.Options {
377
357
  /**
378
358
  * The route the piece should represent.
379
359
  * @since 1.0.0
380
- * @default ''
360
+ *
361
+ * @defaultValue The filesystem-based path, or the name if the location is virtual.
362
+ *
381
363
  * @example
382
364
  * ```typescript
383
365
  * '/users'
@@ -385,7 +367,7 @@ interface RouteOptions extends Piece.Options {
385
367
  * ```
386
368
  * @example
387
369
  * ```typescript
388
- * '/guilds/:guild/members/:member/'
370
+ * '/guilds/[guild]/members/[member]'
389
371
  * // request.params -> { guild: '...', member: '...' }
390
372
  * ```
391
373
  */
@@ -393,18 +375,61 @@ interface RouteOptions extends Piece.Options {
393
375
  /**
394
376
  * (RFC 7230 3.3.2) The maximum decimal number of octets.
395
377
  * @since 1.0.0
396
- * @default this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50
378
+ *
379
+ * @defaultValue this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50
397
380
  */
398
381
  maximumBodyLength?: number;
399
382
  /**
400
383
  * The accepted content types for this route. If set to null, the route will accept any data.
401
384
  * @since 1.3.0
402
- * @default this.context.server.options.acceptedContentMimeTypes ?? null
385
+ *
386
+ * @defaultValue this.context.server.options.acceptedContentMimeTypes ?? null
403
387
  */
404
- acceptedContentMimeTypes?: MimeTypeWithoutParameters[] | null;
388
+ acceptedContentMimeTypes?: readonly MimeTypeWithoutParameters[] | null;
389
+ /**
390
+ * The methods this route accepts.
391
+ * @since 7.0.0
392
+ *
393
+ * @defaultValue The method defined in the piece name, or none if not set.
394
+ */
395
+ methods?: readonly MethodName[];
405
396
  }
406
397
  /**
407
398
  * @since 1.0.0
399
+ *
400
+ * @example A simple GET route that returns a JSON response:
401
+ * ```typescript
402
+ * // hello.get.ts
403
+ * import { Route } from '@sapphire/plugin-api';
404
+ *
405
+ * export class MyRoute extends Route {
406
+ * public run(request: Route.Request, response: Route.Response) {
407
+ * return response.json({ message: 'Hello, World!' });
408
+ * }
409
+ * }
410
+ * ```
411
+ *
412
+ * ```bash
413
+ * $ curl http://localhost:4000/hello
414
+ * {"message":"Hello, World!"}
415
+ * ```
416
+ *
417
+ * @example A simple POST route that reads the body and returns it:
418
+ * ```typescript
419
+ * // echo.post.ts
420
+ * import { Route } from '@sapphire/plugin-api';
421
+ *
422
+ * export class MyRoute extends Route {
423
+ * public run(request: Route.Request, response: Route.Response) {
424
+ * return response.json(request.params);
425
+ * }
426
+ * }
427
+ * ```
428
+ *
429
+ * ```bash
430
+ * $ curl -X POST -H "Content-Type: application/json" -d '{"hello":"world"}' http://localhost:4000/echo
431
+ * {"hello":"world"}
432
+ * ```
408
433
  */
409
434
  declare abstract class Route<Options extends Route.Options = Route.Options> extends Piece<Options, 'routes'> {
410
435
  /**
@@ -422,18 +447,9 @@ declare abstract class Route<Options extends Route.Options = Route.Options> exte
422
447
  /**
423
448
  * The methods this route accepts.
424
449
  */
425
- readonly methods: Collection<Methods, MethodCallback>;
450
+ readonly methods: ReadonlySet<MethodName>;
426
451
  constructor(context: Route.LoaderContext, options?: Options);
427
- /**
428
- * Per-piece listener that is called when the piece is loaded into the store.
429
- * Useful to set-up asynchronous initialization tasks.
430
- */
431
- onLoad(): Awaitable<unknown>;
432
- /**
433
- * Per-piece listener that is called when the piece is unloaded from the store.
434
- * Useful to set-up clean-up tasks.
435
- */
436
- onUnload(): Awaitable<unknown>;
452
+ abstract run(request: Route.Request, response: Route.Response): Awaitable<unknown>;
437
453
  }
438
454
  declare namespace Route {
439
455
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -442,6 +458,8 @@ declare namespace Route {
442
458
  type Options = RouteOptions;
443
459
  type JSON = Piece.JSON;
444
460
  type LocationJSON = Piece.LocationJSON;
461
+ type Request = ApiRequest;
462
+ type Response = ApiResponse;
445
463
  }
446
464
 
447
465
  /**
@@ -454,7 +472,7 @@ declare abstract class MediaParser<Options extends MediaParser.Options = MediaPa
454
472
  * Parses the body data from an API request.
455
473
  * @since 1.3.0
456
474
  */
457
- abstract run(request: ApiRequest): Awaitable<unknown>;
475
+ abstract run(request: MediaParser.Request): Awaitable<unknown>;
458
476
  /**
459
477
  * Checks if a route accepts the media type from this parser.
460
478
  * @since 1.3.0
@@ -466,19 +484,19 @@ declare abstract class MediaParser<Options extends MediaParser.Options = MediaPa
466
484
  * @since 1.3.0
467
485
  * @param request The request to read the body from.
468
486
  */
469
- protected readString(request: ApiRequest): Promise<string>;
487
+ protected readString(request: MediaParser.Request): Promise<string>;
470
488
  /**
471
489
  * Reads the content body as a buffer, this is useful for parsing/reading binary data.
472
490
  * @since 1.3.0
473
491
  * @param request The request to read the body from.
474
492
  */
475
- protected readBuffer(request: ApiRequest): Promise<Buffer>;
493
+ protected readBuffer(request: MediaParser.Request): Promise<Buffer>;
476
494
  /**
477
495
  * Reads the content stream from a request, piping the data through a transformer stream.
478
496
  * @since 1.3.0
479
497
  * @param request The request to read the body from.
480
498
  */
481
- protected contentStream(request: ApiRequest): ApiRequest | Gunzip | null;
499
+ protected contentStream(request: MediaParser.Request): MediaParser.Request | Gunzip | null;
482
500
  }
483
501
  declare namespace MediaParser {
484
502
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -487,6 +505,7 @@ declare namespace MediaParser {
487
505
  type Options = Piece.Options;
488
506
  type JSON = Piece.JSON;
489
507
  type LocationJSON = Piece.LocationJSON;
508
+ type Request = ApiRequest;
490
509
  }
491
510
 
492
511
  /**
@@ -535,7 +554,7 @@ declare abstract class Middleware<Options extends Middleware.Options = Middlewar
535
554
  * @param response The server's response.
536
555
  * @param route The route that matched this request, will be `null` if none matched.
537
556
  */
538
- abstract run(request: ApiRequest, response: ApiResponse, route: Route | null): Awaitable<unknown>;
557
+ abstract run(request: Middleware.Request, response: Middleware.Response, route: Route | null): Awaitable<unknown>;
539
558
  }
540
559
  declare namespace Middleware {
541
560
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -544,6 +563,8 @@ declare namespace Middleware {
544
563
  type Options = MiddlewareOptions;
545
564
  type JSON = Piece.JSON;
546
565
  type LocationJSON = Piece.LocationJSON;
566
+ type Request = ApiRequest;
567
+ type Response = ApiResponse;
547
568
  }
548
569
 
549
570
  /**
@@ -555,12 +576,22 @@ declare class MiddlewareStore extends Store<Middleware, 'middlewares'> {
555
576
  */
556
577
  readonly sortedMiddlewares: Middleware[];
557
578
  constructor();
558
- run(request: ApiRequest, response: ApiResponse, route: Route | null): Promise<void>;
579
+ run(request: Middleware.Request, response: Middleware.Response, route: Route | null): Promise<void>;
559
580
  set(key: string, value: Middleware): this;
560
581
  delete(key: string): boolean;
561
582
  clear(): void;
562
583
  }
563
584
 
585
+ /**
586
+ * @since 1.0.0
587
+ */
588
+ declare class RouteStore extends Store<Route, 'routes'> {
589
+ readonly methods: Collection<"ACL" | "BIND" | "CHECKOUT" | "CONNECT" | "COPY" | "DELETE" | "GET" | "HEAD" | "LINK" | "LOCK" | "M-SEARCH" | "MERGE" | "MKACTIVITY" | "MKCALENDAR" | "MKCOL" | "MOVE" | "NOTIFY" | "OPTIONS" | "PATCH" | "POST" | "PROPFIND" | "PROPPATCH" | "PURGE" | "PUT" | "REBIND" | "REPORT" | "SEARCH" | "SOURCE" | "SUBSCRIBE" | "TRACE" | "UNBIND" | "UNLINK" | "UNLOCK" | "UNSUBSCRIBE", Collection<Route<RouteOptions>, RouteData>>;
590
+ constructor();
591
+ match(request: Route.Request): Route | null;
592
+ private parseURL;
593
+ }
594
+
564
595
  declare enum ServerEvents {
565
596
  Error = "error",
566
597
  Request = "request",
@@ -726,7 +757,7 @@ interface MiddlewareErrorContext {
726
757
  * The route match.
727
758
  * @since 1.2.0
728
759
  */
729
- match: RouteMatch;
760
+ route: Route;
730
761
  }
731
762
 
732
763
  declare enum HttpCodes {
@@ -1141,4 +1172,4 @@ declare module '@sapphire/pieces' {
1141
1172
  */
1142
1173
  declare const version: string;
1143
1174
 
1144
- export { ApiRequest, ApiResponse, Auth, type AuthData, type AuthLessServerOptions, type ContentTypeParameter, type ContentTypeType, CookieStore, HttpCodes, type LoginData, type LoginDataTransformer, type MatchData, MediaParser, MediaParserStore, type MethodCallback, type Methods, Middleware, type MiddlewareErrorContext, type MiddlewareOptions, MiddlewareStore, type MimeType, type MimeTypeWithoutParameters, MimeTypes, type ParsedPart, Route, RouteData, type RouteMatch, type RouteOptions, RouteStore, type SecureCookieStoreSetOptions, Server, ServerEvents, type ServerOptions, type ServerOptionsAuth, TypeState, loadListeners, loadMediaParsers, loadMiddlewares, loadRoutes, methodEntries, methods, version };
1175
+ export { ApiRequest, ApiResponse, Auth, type AuthData, type AuthLessServerOptions, type ContentTypeParameter, type ContentTypeType, CookieStore, HttpCodes, type LoginData, type LoginDataTransformer, type MatchData, MediaParser, MediaParserStore, type MethodName, MethodNames, Middleware, type MiddlewareErrorContext, type MiddlewareOptions, MiddlewareStore, type MimeType, type MimeTypeWithoutParameters, MimeTypes, type ParsedPart, Route, RouteData, type RouteOptions, RouteStore, type SecureCookieStoreSetOptions, Server, ServerEvents, type ServerOptions, type ServerOptionsAuth, TypeState, loadListeners, loadMediaParsers, loadMiddlewares, loadRoutes, version };
@@ -24,11 +24,9 @@ var _MediaParser = class _MediaParser extends pieces.Piece {
24
24
  */
25
25
  async readString(request) {
26
26
  const stream = this.contentStream(request);
27
- if (stream === null)
28
- return "";
27
+ if (stream === null) return "";
29
28
  let body = "";
30
- for await (const chunk of stream)
31
- body += chunk;
29
+ for await (const chunk of stream) body += chunk;
32
30
  return body;
33
31
  }
34
32
  /**
@@ -38,11 +36,9 @@ var _MediaParser = class _MediaParser extends pieces.Piece {
38
36
  */
39
37
  async readBuffer(request) {
40
38
  const stream = this.contentStream(request);
41
- if (stream === null)
42
- return Buffer.alloc(0);
39
+ if (stream === null) return Buffer.alloc(0);
43
40
  const bodies = [];
44
- for await (const chunk of stream)
45
- bodies.push(chunk);
41
+ for await (const chunk of stream) bodies.push(chunk);
46
42
  return Buffer.concat(bodies);
47
43
  }
48
44
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/MediaParser.ts"],"names":[],"mappings":";;;;AAAA,SAAS,aAAa;AAEtB,SAAS,wBAAwB,cAAc,qBAAkC;AAS1E,IAAe,eAAf,MAAe,qBAA+E,MAA+B;AAAA,EAC5H,YAAY,SAAoC,UAAmB,CAAC,GAAc;AACxF,UAAM,SAAS,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,QAAQ,OAAuB;AACrC,WAAO,MAAM,6BAA6B,QAAQ,MAAM,yBAAyB,SAAS,KAAK,IAAiC;AAAA,EACjI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,WAAW,SAAsC;AAChE,UAAM,SAAS,KAAK,cAAc,OAAO;AACzC,QAAI,WAAW;AAAM,aAAO;AAE5B,QAAI,OAAO;AACX,qBAAiB,SAAS;AAAQ,cAAQ;AAE1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,WAAW,SAAsC;AAChE,UAAM,SAAS,KAAK,cAAc,OAAO;AACzC,QAAI,WAAW;AAAM,aAAO,OAAO,MAAM,CAAC;AAE1C,UAAM,SAAmB,CAAC;AAC1B,qBAAiB,SAAS;AAAQ,aAAO,KAAK,KAAK;AAEnD,WAAO,OAAO,OAAO,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,cAAc,SAAiD;AACxE,aAAS,QAAQ,QAAQ,kBAAkB,KAAK,YAAY,YAAY,GAAG;AAAA,MAK1E,KAAK,WAAW;AACf,cAAM,SAAS,cAAc;AAC7B,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAMA,KAAK;AAAA,MACL,KAAK,QAAQ;AACZ,cAAM,SAAS,aAAa;AAC5B,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAKA,KAAK,MAAM;AACV,cAAM,SAAS,uBAAuB;AACtC,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAIA,KAAK,YAAY;AAChB,eAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AACD;AAhGoI;AAA7H,IAAe,cAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport { createBrotliDecompress, createGunzip, createInflate, type Gunzip } from 'zlib';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { MimeTypeWithoutParameters } from './http/Server';\nimport type { Route } from './Route';\n\n/**\n * A media parser\n * @since 1.3.0\n */\nexport abstract class MediaParser<Options extends MediaParser.Options = MediaParser.Options> extends Piece<Options, 'mediaParsers'> {\n\tpublic constructor(context: MediaParser.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\t}\n\n\t/**\n\t * Parses the body data from an API request.\n\t * @since 1.3.0\n\t */\n\tpublic abstract run(request: ApiRequest): Awaitable<unknown>;\n\n\t/**\n\t * Checks if a route accepts the media type from this parser.\n\t * @since 1.3.0\n\t * @param route The route to be checked.\n\t */\n\tpublic accepts(route: Route): boolean {\n\t\treturn route.acceptedContentMimeTypes === null || route.acceptedContentMimeTypes.includes(this.name as MimeTypeWithoutParameters);\n\t}\n\n\t/**\n\t * Reads the content body as a string, this is useful for parsing/reading plain-text data.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected async readString(request: ApiRequest): Promise<string> {\n\t\tconst stream = this.contentStream(request);\n\t\tif (stream === null) return '';\n\n\t\tlet body = '';\n\t\tfor await (const chunk of stream) body += chunk;\n\n\t\treturn body;\n\t}\n\n\t/**\n\t * Reads the content body as a buffer, this is useful for parsing/reading binary data.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected async readBuffer(request: ApiRequest): Promise<Buffer> {\n\t\tconst stream = this.contentStream(request);\n\t\tif (stream === null) return Buffer.alloc(0);\n\n\t\tconst bodies: Buffer[] = [];\n\t\tfor await (const chunk of stream) bodies.push(chunk);\n\n\t\treturn Buffer.concat(bodies);\n\t}\n\n\t/**\n\t * Reads the content stream from a request, piping the data through a transformer stream.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected contentStream(request: ApiRequest): ApiRequest | Gunzip | null {\n\t\tswitch ((request.headers['content-encoding'] ?? 'identity').toLowerCase()) {\n\t\t\t// RFC 7230 4.2.2:\n\t\t\t//\n\t\t\t// The \"deflate\" coding is a \"zlib\" data format (RFC 1950) containing a \"deflate\" compressed data stream\n\t\t\t// (RFC 1951) that uses a combination of the Lempel-Ziv (LZ77) compression algorithm and Huffman coding.\n\t\t\tcase 'deflate': {\n\t\t\t\tconst stream = createInflate();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// RFC 7230 4.2.3\n\t\t\t//\n\t\t\t// The \"gzip\" coding is an LZ77 coding with a 32-bit Cyclic Redundancy Check (CRC) that is commonly produced\n\t\t\t// by the gzip file compression program (RFC 1952).\n\t\t\tcase 'x-gzip':\n\t\t\tcase 'gzip': {\n\t\t\t\tconst stream = createGunzip();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// RFC 7932\n\t\t\t//\n\t\t\t// A format using the Brotli algorithm.\n\t\t\tcase 'br': {\n\t\t\t\tconst stream = createBrotliDecompress();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// An \"identity\" token is used as a synonym for \"no encoding\" in order to communicate when no encoding is\n\t\t\t// preferred.\n\t\t\tcase 'identity': {\n\t\t\t\treturn request;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nexport namespace MediaParser {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'mediaParsers'>;\n\texport type Options = Piece.Options;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/MediaParser.ts"],"names":[],"mappings":";;;;AAAA,SAAS,aAAa;AAEtB,SAAS,wBAAwB,cAAc,qBAAkC;AAS1E,IAAe,eAAf,MAAe,qBAA+E,MAA+B;AAAA,EAC5H,YAAY,SAAoC,UAAmB,CAAC,GAAc;AACxF,UAAM,SAAS,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,QAAQ,OAAuB;AACrC,WAAO,MAAM,6BAA6B,QAAQ,MAAM,yBAAyB,SAAS,KAAK,IAAiC;AAAA,EACjI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,WAAW,SAA+C;AACzE,UAAM,SAAS,KAAK,cAAc,OAAO;AACzC,QAAI,WAAW,KAAM,QAAO;AAE5B,QAAI,OAAO;AACX,qBAAiB,SAAS,OAAQ,SAAQ;AAE1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,WAAW,SAA+C;AACzE,UAAM,SAAS,KAAK,cAAc,OAAO;AACzC,QAAI,WAAW,KAAM,QAAO,OAAO,MAAM,CAAC;AAE1C,UAAM,SAAmB,CAAC;AAC1B,qBAAiB,SAAS,OAAQ,QAAO,KAAK,KAAK;AAEnD,WAAO,OAAO,OAAO,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,cAAc,SAAmE;AAC1F,aAAS,QAAQ,QAAQ,kBAAkB,KAAK,YAAY,YAAY,GAAG;AAAA,MAK1E,KAAK,WAAW;AACf,cAAM,SAAS,cAAc;AAC7B,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAMA,KAAK;AAAA,MACL,KAAK,QAAQ;AACZ,cAAM,SAAS,aAAa;AAC5B,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAKA,KAAK,MAAM;AACV,cAAM,SAAS,uBAAuB;AACtC,gBAAQ,KAAK,MAAM;AACnB,eAAO;AAAA,MACR;AAAA,MAIA,KAAK,YAAY;AAChB,eAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AACD;AAhGoI;AAA7H,IAAe,cAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport { createBrotliDecompress, createGunzip, createInflate, type Gunzip } from 'zlib';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { MimeTypeWithoutParameters } from './http/Server';\nimport type { Route } from './Route';\n\n/**\n * A media parser\n * @since 1.3.0\n */\nexport abstract class MediaParser<Options extends MediaParser.Options = MediaParser.Options> extends Piece<Options, 'mediaParsers'> {\n\tpublic constructor(context: MediaParser.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\t}\n\n\t/**\n\t * Parses the body data from an API request.\n\t * @since 1.3.0\n\t */\n\tpublic abstract run(request: MediaParser.Request): Awaitable<unknown>;\n\n\t/**\n\t * Checks if a route accepts the media type from this parser.\n\t * @since 1.3.0\n\t * @param route The route to be checked.\n\t */\n\tpublic accepts(route: Route): boolean {\n\t\treturn route.acceptedContentMimeTypes === null || route.acceptedContentMimeTypes.includes(this.name as MimeTypeWithoutParameters);\n\t}\n\n\t/**\n\t * Reads the content body as a string, this is useful for parsing/reading plain-text data.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected async readString(request: MediaParser.Request): Promise<string> {\n\t\tconst stream = this.contentStream(request);\n\t\tif (stream === null) return '';\n\n\t\tlet body = '';\n\t\tfor await (const chunk of stream) body += chunk;\n\n\t\treturn body;\n\t}\n\n\t/**\n\t * Reads the content body as a buffer, this is useful for parsing/reading binary data.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected async readBuffer(request: MediaParser.Request): Promise<Buffer> {\n\t\tconst stream = this.contentStream(request);\n\t\tif (stream === null) return Buffer.alloc(0);\n\n\t\tconst bodies: Buffer[] = [];\n\t\tfor await (const chunk of stream) bodies.push(chunk);\n\n\t\treturn Buffer.concat(bodies);\n\t}\n\n\t/**\n\t * Reads the content stream from a request, piping the data through a transformer stream.\n\t * @since 1.3.0\n\t * @param request The request to read the body from.\n\t */\n\tprotected contentStream(request: MediaParser.Request): MediaParser.Request | Gunzip | null {\n\t\tswitch ((request.headers['content-encoding'] ?? 'identity').toLowerCase()) {\n\t\t\t// RFC 7230 4.2.2:\n\t\t\t//\n\t\t\t// The \"deflate\" coding is a \"zlib\" data format (RFC 1950) containing a \"deflate\" compressed data stream\n\t\t\t// (RFC 1951) that uses a combination of the Lempel-Ziv (LZ77) compression algorithm and Huffman coding.\n\t\t\tcase 'deflate': {\n\t\t\t\tconst stream = createInflate();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// RFC 7230 4.2.3\n\t\t\t//\n\t\t\t// The \"gzip\" coding is an LZ77 coding with a 32-bit Cyclic Redundancy Check (CRC) that is commonly produced\n\t\t\t// by the gzip file compression program (RFC 1952).\n\t\t\tcase 'x-gzip':\n\t\t\tcase 'gzip': {\n\t\t\t\tconst stream = createGunzip();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// RFC 7932\n\t\t\t//\n\t\t\t// A format using the Brotli algorithm.\n\t\t\tcase 'br': {\n\t\t\t\tconst stream = createBrotliDecompress();\n\t\t\t\trequest.pipe(stream);\n\t\t\t\treturn stream;\n\t\t\t}\n\n\t\t\t// An \"identity\" token is used as a synonym for \"no encoding\" in order to communicate when no encoding is\n\t\t\t// preferred.\n\t\t\tcase 'identity': {\n\t\t\t\treturn request;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nexport namespace MediaParser {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'mediaParsers'>;\n\texport type Options = Piece.Options;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n\n\texport type Request = ApiRequest;\n}\n"]}
@@ -5,10 +5,7 @@ var pieces = require('@sapphire/pieces');
5
5
  var __defProp = Object.defineProperty;
6
6
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
7
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
- var __publicField = (obj, key, value) => {
9
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
- return value;
11
- };
8
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
12
9
  var _Middleware = class _Middleware extends pieces.Piece {
13
10
  constructor(context, options = {}) {
14
11
  super(context, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/Middleware.ts"],"names":[],"mappings":";;;;;;;;;AAAA,SAAS,aAAa;AASf,IAAe,cAAf,MAAe,oBAA4E,MAA8B;AAAA,EAaxH,YAAY,SAAmC,UAAmB,CAAC,GAAc;AACvF,UAAM,SAAS,OAAO;AAHvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAgB;AAIf,SAAK,WAAW,QAAQ,YAAY;AAAA,EACrC;AASD;AAzBgI;AAAzH,IAAe,aAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport type { Route } from './Route';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { ApiResponse } from './api/ApiResponse';\n\n/**\n * @since 1.0.0\n */\nexport abstract class Middleware<Options extends Middleware.Options = Middleware.Options> extends Piece<Options, 'middlewares'> {\n\t/**\n\t * The position the middleware has. The {@link MiddlewareStore} will run all middlewares with lower position than\n\t * this one.\n\t *\n\t * The built-in middlewares follow the following positions:\n\t * - headers: 10\n\t * - body: 20\n\t * - cookies: 30\n\t * - auth: 40\n\t */\n\tpublic readonly position: number;\n\n\tpublic constructor(context: Middleware.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\t\tthis.position = options.position ?? 1000;\n\t}\n\n\t/**\n\t * The method to be overridden by other middlewares.\n\t * @param request The client's request.\n\t * @param response The server's response.\n\t * @param route The route that matched this request, will be `null` if none matched.\n\t */\n\tpublic abstract run(request: ApiRequest, response: ApiResponse, route: Route | null): Awaitable<unknown>;\n}\n\n/**\n * The options for all middlewares.\n */\nexport interface MiddlewareOptions extends Piece.Options {\n\t/**\n\t * The position to insert the middleware at.\n\t * @see Middleware#position\n\t * @default 1000\n\t */\n\tposition?: number;\n}\n\nexport namespace Middleware {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'middlewares'>;\n\texport type Options = MiddlewareOptions;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/Middleware.ts"],"names":[],"mappings":";;;;;;AAAA,SAAS,aAAa;AASf,IAAe,cAAf,MAAe,oBAA4E,MAA8B;AAAA,EAaxH,YAAY,SAAmC,UAAmB,CAAC,GAAc;AACvF,UAAM,SAAS,OAAO;AAHvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAgB;AAIf,SAAK,WAAW,QAAQ,YAAY;AAAA,EACrC;AASD;AAzBgI;AAAzH,IAAe,aAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport type { Route } from './Route';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { ApiResponse } from './api/ApiResponse';\n\n/**\n * @since 1.0.0\n */\nexport abstract class Middleware<Options extends Middleware.Options = Middleware.Options> extends Piece<Options, 'middlewares'> {\n\t/**\n\t * The position the middleware has. The {@link MiddlewareStore} will run all middlewares with lower position than\n\t * this one.\n\t *\n\t * The built-in middlewares follow the following positions:\n\t * - headers: 10\n\t * - body: 20\n\t * - cookies: 30\n\t * - auth: 40\n\t */\n\tpublic readonly position: number;\n\n\tpublic constructor(context: Middleware.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\t\tthis.position = options.position ?? 1000;\n\t}\n\n\t/**\n\t * The method to be overridden by other middlewares.\n\t * @param request The client's request.\n\t * @param response The server's response.\n\t * @param route The route that matched this request, will be `null` if none matched.\n\t */\n\tpublic abstract run(request: Middleware.Request, response: Middleware.Response, route: Route | null): Awaitable<unknown>;\n}\n\n/**\n * The options for all middlewares.\n */\nexport interface MiddlewareOptions extends Piece.Options {\n\t/**\n\t * The position to insert the middleware at.\n\t * @see Middleware#position\n\t * @default 1000\n\t */\n\tposition?: number;\n}\n\nexport namespace Middleware {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'middlewares'>;\n\texport type Options = MiddlewareOptions;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n\n\texport type Request = ApiRequest;\n\texport type Response = ApiResponse;\n}\n"]}
@@ -6,10 +6,7 @@ var Middleware_cjs = require('./Middleware.cjs');
6
6
  var __defProp = Object.defineProperty;
7
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
8
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __publicField = (obj, key, value) => {
10
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
11
- return value;
12
- };
9
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
10
  var _MiddlewareStore = class _MiddlewareStore extends pieces.Store {
14
11
  constructor() {
15
12
  super(Middleware_cjs.Middleware, { name: "middlewares" });
@@ -20,24 +17,19 @@ var _MiddlewareStore = class _MiddlewareStore extends pieces.Store {
20
17
  }
21
18
  async run(request, response, route) {
22
19
  for (const middleware of this.sortedMiddlewares) {
23
- if (response.writableEnded)
24
- return;
25
- if (middleware.enabled)
26
- await middleware.run(request, response, route);
20
+ if (response.writableEnded) return;
21
+ if (middleware.enabled) await middleware.run(request, response, route);
27
22
  }
28
23
  }
29
24
  set(key, value) {
30
25
  const index = this.sortedMiddlewares.findIndex((middleware) => middleware.position >= value.position);
31
- if (index === -1)
32
- this.sortedMiddlewares.push(value);
33
- else
34
- this.sortedMiddlewares.splice(index, 0, value);
26
+ if (index === -1) this.sortedMiddlewares.push(value);
27
+ else this.sortedMiddlewares.splice(index, 0, value);
35
28
  return super.set(key, value);
36
29
  }
37
30
  delete(key) {
38
31
  const index = this.sortedMiddlewares.findIndex((middleware) => middleware.name === key);
39
- if (index !== -1)
40
- this.sortedMiddlewares.splice(index, 1);
32
+ if (index !== -1) this.sortedMiddlewares.splice(index, 1);
41
33
  return super.delete(key);
42
34
  }
43
35
  clear() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/MiddlewareStore.ts"],"names":[],"mappings":";;;;;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAQpB,IAAM,mBAAN,MAAM,yBAAwB,MAAiC;AAAA,EAM9D,cAAc;AACpB,UAAM,YAAY,EAAE,MAAM,cAAc,CAAC;AAH1C;AAAA;AAAA;AAAA,wBAAgB,qBAAkC,CAAC;AAAA,EAInD;AAAA,EAEA,MAAa,IAAI,SAAqB,UAAuB,OAAoC;AAChG,eAAW,cAAc,KAAK,mBAAmB;AAChD,UAAI,SAAS;AAAe;AAC5B,UAAI,WAAW;AAAS,cAAM,WAAW,IAAI,SAAS,UAAU,KAAK;AAAA,IACtE;AAAA,EACD;AAAA,EAEgB,IAAI,KAAa,OAAyB;AACzD,UAAM,QAAQ,KAAK,kBAAkB,UAAU,CAAC,eAAe,WAAW,YAAY,MAAM,QAAQ;AAGpG,QAAI,UAAU;AAAI,WAAK,kBAAkB,KAAK,KAAK;AAAA;AAC9C,WAAK,kBAAkB,OAAO,OAAO,GAAG,KAAK;AAElD,WAAO,MAAM,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA,EAEgB,OAAO,KAAsB;AAC5C,UAAM,QAAQ,KAAK,kBAAkB,UAAU,CAAC,eAAe,WAAW,SAAS,GAAG;AAGtF,QAAI,UAAU;AAAI,WAAK,kBAAkB,OAAO,OAAO,CAAC;AAExD,WAAO,MAAM,OAAO,GAAG;AAAA,EACxB;AAAA,EAEgB,QAAc;AAC7B,SAAK,kBAAkB,SAAS;AAChC,WAAO,MAAM,MAAM;AAAA,EACpB;AACD;AAxCsE;AAA/D,IAAM,kBAAN","sourcesContent":["import { Store } from '@sapphire/pieces';\nimport { Middleware } from './Middleware';\nimport type { Route } from './Route';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { ApiResponse } from './api/ApiResponse';\n\n/**\n * @since 1.0.0\n */\nexport class MiddlewareStore extends Store<Middleware, 'middlewares'> {\n\t/**\n\t * The sorted middlewares, in ascending order of see {@link Middleware.position}.\n\t */\n\tpublic readonly sortedMiddlewares: Middleware[] = [];\n\n\tpublic constructor() {\n\t\tsuper(Middleware, { name: 'middlewares' });\n\t}\n\n\tpublic async run(request: ApiRequest, response: ApiResponse, route: Route | null): Promise<void> {\n\t\tfor (const middleware of this.sortedMiddlewares) {\n\t\t\tif (response.writableEnded) return;\n\t\t\tif (middleware.enabled) await middleware.run(request, response, route);\n\t\t}\n\t}\n\n\tpublic override set(key: string, value: Middleware): this {\n\t\tconst index = this.sortedMiddlewares.findIndex((middleware) => middleware.position >= value.position);\n\n\t\t// If a middleware with lower priority wasn't found, push to the end of the array\n\t\tif (index === -1) this.sortedMiddlewares.push(value);\n\t\telse this.sortedMiddlewares.splice(index, 0, value);\n\n\t\treturn super.set(key, value);\n\t}\n\n\tpublic override delete(key: string): boolean {\n\t\tconst index = this.sortedMiddlewares.findIndex((middleware) => middleware.name === key);\n\n\t\t// If the middleware was found, remove it\n\t\tif (index !== -1) this.sortedMiddlewares.splice(index, 1);\n\n\t\treturn super.delete(key);\n\t}\n\n\tpublic override clear(): void {\n\t\tthis.sortedMiddlewares.length = 0;\n\t\treturn super.clear();\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/MiddlewareStore.ts"],"names":[],"mappings":";;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAMpB,IAAM,mBAAN,MAAM,yBAAwB,MAAiC;AAAA,EAM9D,cAAc;AACpB,UAAM,YAAY,EAAE,MAAM,cAAc,CAAC;AAH1C;AAAA;AAAA;AAAA,wBAAgB,qBAAkC,CAAC;AAAA,EAInD;AAAA,EAEA,MAAa,IAAI,SAA6B,UAA+B,OAAoC;AAChH,eAAW,cAAc,KAAK,mBAAmB;AAChD,UAAI,SAAS,cAAe;AAC5B,UAAI,WAAW,QAAS,OAAM,WAAW,IAAI,SAAS,UAAU,KAAK;AAAA,IACtE;AAAA,EACD;AAAA,EAEgB,IAAI,KAAa,OAAyB;AACzD,UAAM,QAAQ,KAAK,kBAAkB,UAAU,CAAC,eAAe,WAAW,YAAY,MAAM,QAAQ;AAGpG,QAAI,UAAU,GAAI,MAAK,kBAAkB,KAAK,KAAK;AAAA,QAC9C,MAAK,kBAAkB,OAAO,OAAO,GAAG,KAAK;AAElD,WAAO,MAAM,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA,EAEgB,OAAO,KAAsB;AAC5C,UAAM,QAAQ,KAAK,kBAAkB,UAAU,CAAC,eAAe,WAAW,SAAS,GAAG;AAGtF,QAAI,UAAU,GAAI,MAAK,kBAAkB,OAAO,OAAO,CAAC;AAExD,WAAO,MAAM,OAAO,GAAG;AAAA,EACxB;AAAA,EAEgB,QAAc;AAC7B,SAAK,kBAAkB,SAAS;AAChC,WAAO,MAAM,MAAM;AAAA,EACpB;AACD;AAxCsE;AAA/D,IAAM,kBAAN","sourcesContent":["import { Store } from '@sapphire/pieces';\nimport { Middleware } from './Middleware';\nimport type { Route } from './Route';\n\n/**\n * @since 1.0.0\n */\nexport class MiddlewareStore extends Store<Middleware, 'middlewares'> {\n\t/**\n\t * The sorted middlewares, in ascending order of see {@link Middleware.position}.\n\t */\n\tpublic readonly sortedMiddlewares: Middleware[] = [];\n\n\tpublic constructor() {\n\t\tsuper(Middleware, { name: 'middlewares' });\n\t}\n\n\tpublic async run(request: Middleware.Request, response: Middleware.Response, route: Route | null): Promise<void> {\n\t\tfor (const middleware of this.sortedMiddlewares) {\n\t\t\tif (response.writableEnded) return;\n\t\t\tif (middleware.enabled) await middleware.run(request, response, route);\n\t\t}\n\t}\n\n\tpublic override set(key: string, value: Middleware): this {\n\t\tconst index = this.sortedMiddlewares.findIndex((middleware) => middleware.position >= value.position);\n\n\t\t// If a middleware with lower priority wasn't found, push to the end of the array\n\t\tif (index === -1) this.sortedMiddlewares.push(value);\n\t\telse this.sortedMiddlewares.splice(index, 0, value);\n\n\t\treturn super.set(key, value);\n\t}\n\n\tpublic override delete(key: string): boolean {\n\t\tconst index = this.sortedMiddlewares.findIndex((middleware) => middleware.name === key);\n\n\t\t// If the middleware was found, remove it\n\t\tif (index !== -1) this.sortedMiddlewares.splice(index, 1);\n\n\t\treturn super.delete(key);\n\t}\n\n\tpublic override clear(): void {\n\t\tthis.sortedMiddlewares.length = 0;\n\t\treturn super.clear();\n\t}\n}\n"]}
@@ -1,17 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var pieces = require('@sapphire/pieces');
4
- var discord_js = require('discord.js');
5
4
  var RouteData_cjs = require('../utils/RouteData.cjs');
6
- var HttpMethods_cjs = require('./http/HttpMethods.cjs');
7
5
 
8
6
  var __defProp = Object.defineProperty;
9
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
8
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
11
- var __publicField = (obj, key, value) => {
12
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
- return value;
14
- };
9
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
15
10
  var _Route = class _Route extends pieces.Piece {
16
11
  constructor(context, options = {}) {
17
12
  super(context, options);
@@ -30,39 +25,22 @@ var _Route = class _Route extends pieces.Piece {
30
25
  /**
31
26
  * The methods this route accepts.
32
27
  */
33
- __publicField(this, "methods", new discord_js.Collection());
28
+ __publicField(this, "methods");
34
29
  const api = this.container.server.options;
35
- this.router = new RouteData_cjs.RouteData(`${api.prefix ?? ""}${options.route ?? this.name ?? ""}`);
36
- for (const [method, symbol] of HttpMethods_cjs.methodEntries) {
37
- const value = Reflect.get(this, symbol);
38
- if (typeof value === "function")
39
- this.methods.set(method, value);
30
+ const prefix = api.prefix ? api.prefix.endsWith("/") ? api.prefix : `${api.prefix}/` : "";
31
+ let path = options.route ?? (this.location.virtual ? this.name : this.location.directories.concat(this.name).join("/"));
32
+ const methods = new Set(options.methods);
33
+ const methodIndex = path.lastIndexOf(".");
34
+ if (methodIndex !== -1) {
35
+ const method = path.slice(methodIndex + 1).toUpperCase();
36
+ if (!methods.has(method)) methods.add(method);
37
+ path = path.slice(0, methodIndex);
40
38
  }
39
+ this.methods = methods;
40
+ this.router = new RouteData_cjs.RouteData(`${prefix}${path}`);
41
41
  this.maximumBodyLength = options.maximumBodyLength ?? api.maximumBodyLength ?? 1024 * 1024 * 50;
42
42
  this.acceptedContentMimeTypes = options.acceptedContentMimeTypes ?? api.acceptedContentMimeTypes ?? null;
43
43
  }
44
- /**
45
- * Per-piece listener that is called when the piece is loaded into the store.
46
- * Useful to set-up asynchronous initialization tasks.
47
- */
48
- onLoad() {
49
- const store = this.store;
50
- for (const [method, cb] of this.methods) {
51
- store.table.get(method).set(this, cb.bind(this));
52
- }
53
- return void 0;
54
- }
55
- /**
56
- * Per-piece listener that is called when the piece is unloaded from the store.
57
- * Useful to set-up clean-up tasks.
58
- */
59
- onUnload() {
60
- const store = this.store;
61
- for (const [method] of this.methods) {
62
- store.table.get(method).delete(this);
63
- }
64
- return void 0;
65
- }
66
44
  };
67
45
  __name(_Route, "Route");
68
46
  var Route = _Route;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/structures/Route.ts"],"names":[],"mappings":";;;;;;;;;AAAA,SAAS,aAAa;AAEtB,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,qBAAmC;AAOrC,IAAe,SAAf,MAAe,eAA6D,MAAyB;AAAA,EAqBpG,YAAY,SAA8B,UAAmB,CAAC,GAAc;AAClF,UAAM,SAAS,OAAO;AAlBvB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB,WAAU,IAAI,WAAoC;AAKjE,UAAM,MAAM,KAAK,UAAU,OAAO;AAClC,SAAK,SAAS,IAAI,UAAU,GAAG,IAAI,UAAU,EAAE,GAAG,QAAQ,SAAS,KAAK,QAAQ,EAAE,EAAE;AAEpF,eAAW,CAAC,QAAQ,MAAM,KAAK,eAAe;AAC7C,YAAM,QAAQ,QAAQ,IAAI,MAAM,MAAM;AACtC,UAAI,OAAO,UAAU;AAAY,aAAK,QAAQ,IAAI,QAAQ,KAAK;AAAA,IAChE;AAEA,SAAK,oBAAoB,QAAQ,qBAAqB,IAAI,qBAAqB,OAAO,OAAO;AAC7F,SAAK,2BAA2B,QAAQ,4BAA4B,IAAI,4BAA4B;AAAA,EACrG;AAAA;AAAA;AAAA;AAAA;AAAA,EAMgB,SAA6B;AAC5C,UAAM,QAAQ,KAAK;AAEnB,eAAW,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS;AACxC,YAAM,MAAM,IAAI,MAAM,EAAG,IAAI,MAAM,GAAG,KAAK,IAAI,CAAC;AAAA,IACjD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMgB,WAA+B;AAC9C,UAAM,QAAQ,KAAK;AAEnB,eAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACpC,YAAM,MAAM,IAAI,MAAM,EAAG,OAAO,IAAI;AAAA,IACrC;AAEA,WAAO;AAAA,EACR;AACD;AA/D4G;AAArG,IAAe,QAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport { Collection } from 'discord.js';\nimport { RouteData } from '../utils/RouteData';\nimport { methodEntries, type Methods } from './http/HttpMethods';\nimport type { MimeTypeWithoutParameters } from './http/Server';\nimport type { MethodCallback, RouteStore } from './RouteStore';\n\n/**\n * @since 1.0.0\n */\nexport abstract class Route<Options extends Route.Options = Route.Options> extends Piece<Options, 'routes'> {\n\t/**\n\t * (RFC 7230 3.3.2) The maximum decimal number of octets.\n\t */\n\tpublic readonly maximumBodyLength: number;\n\n\t/**\n\t * The accepted content types.\n\t */\n\tpublic readonly acceptedContentMimeTypes: readonly MimeTypeWithoutParameters[] | null;\n\n\t/**\n\t * The route information.\n\t */\n\tpublic readonly router: RouteData;\n\n\t/**\n\t * The methods this route accepts.\n\t */\n\tpublic readonly methods = new Collection<Methods, MethodCallback>();\n\n\tpublic constructor(context: Route.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\n\t\tconst api = this.container.server.options;\n\t\tthis.router = new RouteData(`${api.prefix ?? ''}${options.route ?? this.name ?? ''}`);\n\n\t\tfor (const [method, symbol] of methodEntries) {\n\t\t\tconst value = Reflect.get(this, symbol) as MethodCallback;\n\t\t\tif (typeof value === 'function') this.methods.set(method, value);\n\t\t}\n\n\t\tthis.maximumBodyLength = options.maximumBodyLength ?? api.maximumBodyLength ?? 1024 * 1024 * 50;\n\t\tthis.acceptedContentMimeTypes = options.acceptedContentMimeTypes ?? api.acceptedContentMimeTypes ?? null;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is loaded into the store.\n\t * Useful to set-up asynchronous initialization tasks.\n\t */\n\tpublic override onLoad(): Awaitable<unknown> {\n\t\tconst store = this.store as unknown as RouteStore;\n\n\t\tfor (const [method, cb] of this.methods) {\n\t\t\tstore.table.get(method)!.set(this, cb.bind(this));\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Per-piece listener that is called when the piece is unloaded from the store.\n\t * Useful to set-up clean-up tasks.\n\t */\n\tpublic override onUnload(): Awaitable<unknown> {\n\t\tconst store = this.store as unknown as RouteStore;\n\n\t\tfor (const [method] of this.methods) {\n\t\t\tstore.table.get(method)!.delete(this);\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n\nexport interface RouteOptions extends Piece.Options {\n\t/**\n\t * The route the piece should represent.\n\t * @since 1.0.0\n\t * @default ''\n\t * @example\n\t * ```typescript\n\t * '/users'\n\t * // request.params -> {}\n\t * ```\n\t * @example\n\t * ```typescript\n\t * '/guilds/:guild/members/:member/'\n\t * // request.params -> { guild: '...', member: '...' }\n\t * ```\n\t */\n\troute?: string;\n\n\t/**\n\t * (RFC 7230 3.3.2) The maximum decimal number of octets.\n\t * @since 1.0.0\n\t * @default this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50\n\t */\n\tmaximumBodyLength?: number;\n\n\t/**\n\t * The accepted content types for this route. If set to null, the route will accept any data.\n\t * @since 1.3.0\n\t * @default this.context.server.options.acceptedContentMimeTypes ?? null\n\t */\n\tacceptedContentMimeTypes?: MimeTypeWithoutParameters[] | null;\n}\n\nexport namespace Route {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'routes'>;\n\texport type Options = RouteOptions;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/structures/Route.ts"],"names":[],"mappings":";;;;;;AAAA,SAAS,aAAa;AAEtB,SAAS,iBAAiB;AA2CnB,IAAe,SAAf,MAAe,eAA6D,MAAyB;AAAA,EAqBpG,YAAY,SAA8B,UAAmB,CAAC,GAAc;AAClF,UAAM,SAAS,OAAO;AAlBvB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKhB;AAAA;AAAA;AAAA,wBAAgB;AAKf,UAAM,MAAM,KAAK,UAAU,OAAO;AAElC,UAAM,SAAS,IAAI,SAAU,IAAI,OAAO,SAAS,GAAG,IAAI,IAAI,SAAS,GAAG,IAAI,MAAM,MAAO;AAIzF,QAAI,OAAO,QAAQ,UAAU,KAAK,SAAS,UAAU,KAAK,OAAO,KAAK,SAAS,YAAY,OAAO,KAAK,IAAI,EAAE,KAAK,GAAG;AAErH,UAAM,UAAU,IAAI,IAAI,QAAQ,OAAO;AAEvC,UAAM,cAAc,KAAK,YAAY,GAAG;AACxC,QAAI,gBAAgB,IAAI;AAEvB,YAAM,SAAS,KAAK,MAAM,cAAc,CAAC,EAAE,YAAY;AACvD,UAAI,CAAC,QAAQ,IAAI,MAAM,EAAG,SAAQ,IAAI,MAAM;AAG5C,aAAO,KAAK,MAAM,GAAG,WAAW;AAAA,IACjC;AAEA,SAAK,UAAU;AACf,SAAK,SAAS,IAAI,UAAU,GAAG,MAAM,GAAG,IAAI,EAAE;AAC9C,SAAK,oBAAoB,QAAQ,qBAAqB,IAAI,qBAAqB,OAAO,OAAO;AAC7F,SAAK,2BAA2B,QAAQ,4BAA4B,IAAI,4BAA4B;AAAA,EACrG;AAGD;AAnD4G;AAArG,IAAe,QAAf","sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport type { Awaitable } from '@sapphire/utilities';\nimport { RouteData } from '../utils/RouteData';\nimport type { ApiRequest } from './api/ApiRequest';\nimport type { ApiResponse } from './api/ApiResponse';\nimport type { MethodName } from './http/HttpMethods';\nimport type { MimeTypeWithoutParameters } from './http/Server';\n\n/**\n * @since 1.0.0\n *\n * @example A simple GET route that returns a JSON response:\n * ```typescript\n * // hello.get.ts\n * import { Route } from '@sapphire/plugin-api';\n *\n * export class MyRoute extends Route {\n * public run(request: Route.Request, response: Route.Response) {\n * return response.json({ message: 'Hello, World!' });\n * }\n * }\n * ```\n *\n * ```bash\n * $ curl http://localhost:4000/hello\n * {\"message\":\"Hello, World!\"}\n * ```\n *\n * @example A simple POST route that reads the body and returns it:\n * ```typescript\n * // echo.post.ts\n * import { Route } from '@sapphire/plugin-api';\n *\n * export class MyRoute extends Route {\n * public run(request: Route.Request, response: Route.Response) {\n * return response.json(request.params);\n * }\n * }\n * ```\n *\n * ```bash\n * $ curl -X POST -H \"Content-Type: application/json\" -d '{\"hello\":\"world\"}' http://localhost:4000/echo\n * {\"hello\":\"world\"}\n * ```\n */\nexport abstract class Route<Options extends Route.Options = Route.Options> extends Piece<Options, 'routes'> {\n\t/**\n\t * (RFC 7230 3.3.2) The maximum decimal number of octets.\n\t */\n\tpublic readonly maximumBodyLength: number;\n\n\t/**\n\t * The accepted content types.\n\t */\n\tpublic readonly acceptedContentMimeTypes: readonly MimeTypeWithoutParameters[] | null;\n\n\t/**\n\t * The route information.\n\t */\n\tpublic readonly router: RouteData;\n\n\t/**\n\t * The methods this route accepts.\n\t */\n\tpublic readonly methods: ReadonlySet<MethodName>;\n\n\tpublic constructor(context: Route.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\n\t\tconst api = this.container.server.options;\n\t\t// Concat a `/` to the prefix if it does not end with it\n\t\tconst prefix = api.prefix ? (api.prefix.endsWith('/') ? api.prefix : `${api.prefix}/`) : '';\n\t\t// Use the defined route, otherwise:\n\t\t// - If the location is virtual, use the name.\n\t\t// - Otherwise, use the directories and the name.\n\t\tlet path = options.route ?? (this.location.virtual ? this.name : this.location.directories.concat(this.name).join('/'));\n\n\t\tconst methods = new Set(options.methods);\n\t\t// If the path contains a method (e.g. `/users.get`), extract it and add it to the methods set:\n\t\tconst methodIndex = path.lastIndexOf('.');\n\t\tif (methodIndex !== -1) {\n\t\t\t// Extract the method from the path:\n\t\t\tconst method = path.slice(methodIndex + 1).toUpperCase() as MethodName;\n\t\t\tif (!methods.has(method)) methods.add(method);\n\n\t\t\t// Update the path to remove the method:\n\t\t\tpath = path.slice(0, methodIndex);\n\t\t}\n\n\t\tthis.methods = methods;\n\t\tthis.router = new RouteData(`${prefix}${path}`);\n\t\tthis.maximumBodyLength = options.maximumBodyLength ?? api.maximumBodyLength ?? 1024 * 1024 * 50;\n\t\tthis.acceptedContentMimeTypes = options.acceptedContentMimeTypes ?? api.acceptedContentMimeTypes ?? null;\n\t}\n\n\tpublic abstract run(request: Route.Request, response: Route.Response): Awaitable<unknown>;\n}\n\nexport interface RouteOptions extends Piece.Options {\n\t/**\n\t * The route the piece should represent.\n\t * @since 1.0.0\n\t *\n\t * @defaultValue The filesystem-based path, or the name if the location is virtual.\n\t *\n\t * @example\n\t * ```typescript\n\t * '/users'\n\t * // request.params -> {}\n\t * ```\n\t * @example\n\t * ```typescript\n\t * '/guilds/[guild]/members/[member]'\n\t * // request.params -> { guild: '...', member: '...' }\n\t * ```\n\t */\n\troute?: string;\n\n\t/**\n\t * (RFC 7230 3.3.2) The maximum decimal number of octets.\n\t * @since 1.0.0\n\t *\n\t * @defaultValue this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50\n\t */\n\tmaximumBodyLength?: number;\n\n\t/**\n\t * The accepted content types for this route. If set to null, the route will accept any data.\n\t * @since 1.3.0\n\t *\n\t * @defaultValue this.context.server.options.acceptedContentMimeTypes ?? null\n\t */\n\tacceptedContentMimeTypes?: readonly MimeTypeWithoutParameters[] | null;\n\n\t/**\n\t * The methods this route accepts.\n\t * @since 7.0.0\n\t *\n\t * @defaultValue The method defined in the piece name, or none if not set.\n\t */\n\tmethods?: readonly MethodName[];\n}\n\nexport namespace Route {\n\t/** @deprecated Use {@linkcode LoaderContext} instead. */\n\texport type Context = LoaderContext;\n\texport type LoaderContext = Piece.LoaderContext<'routes'>;\n\texport type Options = RouteOptions;\n\texport type JSON = Piece.JSON;\n\texport type LocationJSON = Piece.LocationJSON;\n\n\texport type Request = ApiRequest;\n\texport type Response = ApiResponse;\n}\n"]}
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var pieces = require('@sapphire/pieces');
4
+ var discord_js = require('discord.js');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var _RouteLoaderStrategy = class _RouteLoaderStrategy extends pieces.LoaderStrategy {
9
+ onLoad(store, piece) {
10
+ for (const method of piece.methods) {
11
+ store.methods.ensure(method, () => new discord_js.Collection()).set(piece, piece.router);
12
+ }
13
+ }
14
+ onUnload(store, piece) {
15
+ for (const method of piece.methods) {
16
+ const methods = store.methods.get(method);
17
+ if (typeof methods === "undefined") continue;
18
+ methods.delete(piece);
19
+ if (methods.size === 0) store.methods.delete(method);
20
+ }
21
+ }
22
+ };
23
+ __name(_RouteLoaderStrategy, "RouteLoaderStrategy");
24
+ var RouteLoaderStrategy = _RouteLoaderStrategy;
25
+
26
+ exports.RouteLoaderStrategy = RouteLoaderStrategy;
27
+ //# sourceMappingURL=out.js.map
28
+ //# sourceMappingURL=RouteLoaderStrategy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/lib/structures/RouteLoaderStrategy.ts"],"names":[],"mappings":";;;;AAAA,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAIpB,IAAM,uBAAN,MAAM,6BAA4B,eAAsB;AAAA,EAC9C,OAAO,OAAmB,OAAoB;AAC7D,eAAW,UAAU,MAAM,SAAS;AACnC,YAAM,QAAQ,OAAO,QAAQ,MAAM,IAAI,WAAW,CAAC,EAAE,IAAI,OAAO,MAAM,MAAM;AAAA,IAC7E;AAAA,EACD;AAAA,EAEgB,SAAS,OAAmB,OAAoB;AAC/D,eAAW,UAAU,MAAM,SAAS;AACnC,YAAM,UAAU,MAAM,QAAQ,IAAI,MAAM;AACxC,UAAI,OAAO,YAAY,YAAa;AAEpC,cAAQ,OAAO,KAAK;AACpB,UAAI,QAAQ,SAAS,EAAG,OAAM,QAAQ,OAAO,MAAM;AAAA,IACpD;AAAA,EACD;AACD;AAhB+D;AAAxD,IAAM,sBAAN","sourcesContent":["import { LoaderStrategy } from '@sapphire/pieces';\nimport { Collection } from 'discord.js';\nimport type { Route } from './Route';\nimport type { RouteStore } from './RouteStore';\n\nexport class RouteLoaderStrategy extends LoaderStrategy<Route> {\n\tpublic override onLoad(store: RouteStore, piece: Route): void {\n\t\tfor (const method of piece.methods) {\n\t\t\tstore.methods.ensure(method, () => new Collection()).set(piece, piece.router);\n\t\t}\n\t}\n\n\tpublic override onUnload(store: RouteStore, piece: Route): void {\n\t\tfor (const method of piece.methods) {\n\t\t\tconst methods = store.methods.get(method);\n\t\t\tif (typeof methods === 'undefined') continue;\n\n\t\t\tmethods.delete(piece);\n\t\t\tif (methods.size === 0) store.methods.delete(method);\n\t\t}\n\t}\n}\n"]}