@sapphire/plugin-api 6.1.2-next.fc6b7cf.0 → 7.0.0-next.03b2a90

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 -45
  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 -31
  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 -45
  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 -10
  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 +7 -7
  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.fc6b7cf.0";
24
+ var version = "7.0.0-next.03b2a90";
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.fc6b7cf.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.03b2a90';\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';
@@ -224,10 +224,6 @@ interface ParsedPart {
224
224
  type: TypeState;
225
225
  }
226
226
 
227
- 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';
228
- declare const methods: Record<Methods, symbol>;
229
- declare const methodEntries: readonly [Methods, symbol][];
230
-
231
227
  declare enum MimeTypes {
232
228
  ApplicationFormUrlEncoded = "application/x-www-form-urlencoded",
233
229
  ApplicationJson = "application/json",
@@ -354,28 +350,16 @@ declare class ApiResponse<Request extends IncomingMessage = IncomingMessage> ext
354
350
  setContentType(contentType: MimeTypes): this;
355
351
  }
356
352
 
357
- interface MethodCallback {
358
- (request: ApiRequest, response: ApiResponse): unknown;
359
- }
360
- interface RouteMatch {
361
- route: Route;
362
- cb: MethodCallback;
363
- }
364
- /**
365
- * @since 1.0.0
366
- */
367
- declare class RouteStore extends Store<Route, 'routes'> {
368
- readonly table: Collection<Methods, Collection<Route<RouteOptions>, MethodCallback>>;
369
- constructor();
370
- match(request: ApiRequest): RouteMatch | null;
371
- private parseURL;
372
- }
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"];
373
355
 
374
356
  interface RouteOptions extends Piece.Options {
375
357
  /**
376
358
  * The route the piece should represent.
377
359
  * @since 1.0.0
378
- * @default ''
360
+ *
361
+ * @defaultValue The filesystem-based path, or the name if the location is virtual.
362
+ *
379
363
  * @example
380
364
  * ```typescript
381
365
  * '/users'
@@ -383,7 +367,7 @@ interface RouteOptions extends Piece.Options {
383
367
  * ```
384
368
  * @example
385
369
  * ```typescript
386
- * '/guilds/:guild/members/:member/'
370
+ * '/guilds/[guild]/members/[member]'
387
371
  * // request.params -> { guild: '...', member: '...' }
388
372
  * ```
389
373
  */
@@ -391,18 +375,61 @@ interface RouteOptions extends Piece.Options {
391
375
  /**
392
376
  * (RFC 7230 3.3.2) The maximum decimal number of octets.
393
377
  * @since 1.0.0
394
- * @default this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50
378
+ *
379
+ * @defaultValue this.context.server.options.maximumBodyLength ?? 1024 * 1024 * 50
395
380
  */
396
381
  maximumBodyLength?: number;
397
382
  /**
398
383
  * The accepted content types for this route. If set to null, the route will accept any data.
399
384
  * @since 1.3.0
400
- * @default this.context.server.options.acceptedContentMimeTypes ?? null
385
+ *
386
+ * @defaultValue this.context.server.options.acceptedContentMimeTypes ?? null
401
387
  */
402
- 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[];
403
396
  }
404
397
  /**
405
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
+ * ```
406
433
  */
407
434
  declare abstract class Route<Options extends Route.Options = Route.Options> extends Piece<Options, 'routes'> {
408
435
  /**
@@ -420,18 +447,9 @@ declare abstract class Route<Options extends Route.Options = Route.Options> exte
420
447
  /**
421
448
  * The methods this route accepts.
422
449
  */
423
- readonly methods: Collection<Methods, MethodCallback>;
450
+ readonly methods: ReadonlySet<MethodName>;
424
451
  constructor(context: Route.LoaderContext, options?: Options);
425
- /**
426
- * Per-piece listener that is called when the piece is loaded into the store.
427
- * Useful to set-up asynchronous initialization tasks.
428
- */
429
- onLoad(): Awaitable<unknown>;
430
- /**
431
- * Per-piece listener that is called when the piece is unloaded from the store.
432
- * Useful to set-up clean-up tasks.
433
- */
434
- onUnload(): Awaitable<unknown>;
452
+ abstract run(request: Route.Request, response: Route.Response): Awaitable<unknown>;
435
453
  }
436
454
  declare namespace Route {
437
455
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -440,6 +458,8 @@ declare namespace Route {
440
458
  type Options = RouteOptions;
441
459
  type JSON = Piece.JSON;
442
460
  type LocationJSON = Piece.LocationJSON;
461
+ type Request = ApiRequest;
462
+ type Response = ApiResponse;
443
463
  }
444
464
 
445
465
  /**
@@ -452,7 +472,7 @@ declare abstract class MediaParser<Options extends MediaParser.Options = MediaPa
452
472
  * Parses the body data from an API request.
453
473
  * @since 1.3.0
454
474
  */
455
- abstract run(request: ApiRequest): Awaitable<unknown>;
475
+ abstract run(request: MediaParser.Request): Awaitable<unknown>;
456
476
  /**
457
477
  * Checks if a route accepts the media type from this parser.
458
478
  * @since 1.3.0
@@ -464,19 +484,19 @@ declare abstract class MediaParser<Options extends MediaParser.Options = MediaPa
464
484
  * @since 1.3.0
465
485
  * @param request The request to read the body from.
466
486
  */
467
- protected readString(request: ApiRequest): Promise<string>;
487
+ protected readString(request: MediaParser.Request): Promise<string>;
468
488
  /**
469
489
  * Reads the content body as a buffer, this is useful for parsing/reading binary data.
470
490
  * @since 1.3.0
471
491
  * @param request The request to read the body from.
472
492
  */
473
- protected readBuffer(request: ApiRequest): Promise<Buffer>;
493
+ protected readBuffer(request: MediaParser.Request): Promise<Buffer>;
474
494
  /**
475
495
  * Reads the content stream from a request, piping the data through a transformer stream.
476
496
  * @since 1.3.0
477
497
  * @param request The request to read the body from.
478
498
  */
479
- protected contentStream(request: ApiRequest): ApiRequest | Gunzip | null;
499
+ protected contentStream(request: MediaParser.Request): MediaParser.Request | Gunzip | null;
480
500
  }
481
501
  declare namespace MediaParser {
482
502
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -485,6 +505,7 @@ declare namespace MediaParser {
485
505
  type Options = Piece.Options;
486
506
  type JSON = Piece.JSON;
487
507
  type LocationJSON = Piece.LocationJSON;
508
+ type Request = ApiRequest;
488
509
  }
489
510
 
490
511
  /**
@@ -533,7 +554,7 @@ declare abstract class Middleware<Options extends Middleware.Options = Middlewar
533
554
  * @param response The server's response.
534
555
  * @param route The route that matched this request, will be `null` if none matched.
535
556
  */
536
- 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>;
537
558
  }
538
559
  declare namespace Middleware {
539
560
  /** @deprecated Use {@linkcode LoaderContext} instead. */
@@ -542,6 +563,8 @@ declare namespace Middleware {
542
563
  type Options = MiddlewareOptions;
543
564
  type JSON = Piece.JSON;
544
565
  type LocationJSON = Piece.LocationJSON;
566
+ type Request = ApiRequest;
567
+ type Response = ApiResponse;
545
568
  }
546
569
 
547
570
  /**
@@ -553,12 +576,22 @@ declare class MiddlewareStore extends Store<Middleware, 'middlewares'> {
553
576
  */
554
577
  readonly sortedMiddlewares: Middleware[];
555
578
  constructor();
556
- run(request: ApiRequest, response: ApiResponse, route: Route | null): Promise<void>;
579
+ run(request: Middleware.Request, response: Middleware.Response, route: Route | null): Promise<void>;
557
580
  set(key: string, value: Middleware): this;
558
581
  delete(key: string): boolean;
559
582
  clear(): void;
560
583
  }
561
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
+
562
595
  declare enum ServerEvents {
563
596
  Error = "error",
564
597
  Request = "request",
@@ -724,7 +757,7 @@ interface MiddlewareErrorContext {
724
757
  * The route match.
725
758
  * @since 1.2.0
726
759
  */
727
- match: RouteMatch;
760
+ route: Route;
728
761
  }
729
762
 
730
763
  declare enum HttpCodes {
@@ -1139,4 +1172,4 @@ declare module '@sapphire/pieces' {
1139
1172
  */
1140
1173
  declare const version: string;
1141
1174
 
1142
- 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"]}
@@ -1,43 +1,38 @@
1
1
  'use strict';
2
2
 
3
3
  var pieces = require('@sapphire/pieces');
4
+ var utilities = require('@sapphire/utilities');
4
5
  var discord_js = require('discord.js');
5
6
  var url = require('url');
6
- var HttpMethods_cjs = require('./http/HttpMethods.cjs');
7
7
  var Route_cjs = require('./Route.cjs');
8
+ var RouteLoaderStrategy_cjs = require('./RouteLoaderStrategy.cjs');
8
9
 
9
10
  var __defProp = Object.defineProperty;
10
11
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
12
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
12
- var __publicField = (obj, key, value) => {
13
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
14
- return value;
15
- };
13
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
16
14
  var slash = "/".charCodeAt(0);
17
15
  var _RouteStore = class _RouteStore extends pieces.Store {
18
16
  constructor() {
19
- super(Route_cjs.Route, { name: "routes" });
20
- __publicField(this, "table", new discord_js.Collection());
21
- for (const [method] of HttpMethods_cjs.methodEntries)
22
- this.table.set(method, new discord_js.Collection());
17
+ super(Route_cjs.Route, { name: "routes", strategy: new RouteLoaderStrategy_cjs.RouteLoaderStrategy() });
18
+ __publicField(this, "methods", new discord_js.Collection());
23
19
  }
24
20
  match(request) {
25
21
  const { method } = request;
26
22
  if (typeof method === "undefined") {
27
23
  return null;
28
24
  }
29
- const methodTable = this.table.get(method);
30
- if (typeof methodTable === "undefined") {
25
+ const methodTable = this.methods.get(method);
26
+ if (utilities.isNullish(methodTable)) {
31
27
  return null;
32
28
  }
33
29
  const { splits, querystring } = this.parseURL(request.url);
34
- for (const [route, cb] of methodTable.entries()) {
35
- const result = route.router.match(splits);
36
- if (result === null)
37
- continue;
30
+ for (const [route, router] of methodTable.entries()) {
31
+ const result = router.match(splits);
32
+ if (result === null) continue;
38
33
  request.params = result;
39
34
  request.query = Object.fromEntries(new url.URLSearchParams(querystring).entries());
40
- return { route, cb };
35
+ return route;
41
36
  }
42
37
  return null;
43
38
  }
@@ -52,10 +47,8 @@ var _RouteStore = class _RouteStore extends pieces.Store {
52
47
  pathname = url.substring(0, index);
53
48
  querystring = url.substring(index + 1);
54
49
  }
55
- if (pathname.charCodeAt(0) === slash)
56
- pathname = pathname.substring(1);
57
- if (pathname.length > 0 && pathname.charCodeAt(pathname.length - 1) === slash)
58
- pathname = pathname.substring(0, pathname.length - 1);
50
+ if (pathname.charCodeAt(0) === slash) pathname = pathname.substring(1);
51
+ if (pathname.length > 0 && pathname.charCodeAt(pathname.length - 1) === slash) pathname = pathname.substring(0, pathname.length - 1);
59
52
  const splits = pathname.split("/");
60
53
  return { splits, querystring };
61
54
  }