@sapphire/plugin-api
Version:
Plugin for @sapphire/framework to expose a REST API
1 lines • 10.1 kB
Source Map (JSON)
{"version":3,"sources":["../../../../../src/lib/structures/http/Server.ts"],"names":["ServerEvent","AsyncEventEmitter","container","httpCreateServer","ApiRequest","ApiResponse","RouteStore","MiddlewareStore","Auth","error"],"mappings":"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","file":"Server.cjs","sourcesContent":["import { container } from '@sapphire/pieces';\nimport { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';\nimport { Server as HttpServer, createServer as httpCreateServer, type ServerOptions as HttpOptions } from 'node:http';\nimport type { ListenOptions } from 'node:net';\nimport { MiddlewareStore } from '../MiddlewareStore';\nimport type { Route } from '../Route';\nimport { RouteStore } from '../RouteStore';\nimport { ApiRequest } from '../api/ApiRequest';\nimport { ApiResponse } from '../api/ApiResponse';\nimport type { RouterBranch } from '../router/RouterBranch';\nimport { Auth, type ServerOptionsAuth } from './Auth';\n\nexport enum ServerEvent {\n\tError = 'error',\n\tRequest = 'request',\n\tRouterBranchNotFound = 'routerBranchNotFound',\n\tRouterBranchMethodNotAllowed = 'routerBranchMethodNotAllowed',\n\tRouterFound = 'routerFound',\n\tRouteError = 'routeError',\n\tMiddlewareFailure = 'middlewareFailure',\n\tMiddlewareError = 'middlewareError',\n\tMiddlewareSuccess = 'middlewareSuccess'\n}\n\nexport interface ServerEvents {\n\t[ServerEvent.Error]: [error: Error, request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.Request]: [request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.RouterBranchNotFound]: [request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.RouterBranchMethodNotAllowed]: [request: ApiRequest, response: ApiResponse, node: RouterBranch];\n\t[ServerEvent.RouterFound]: [request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.RouteError]: [error: Error, request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.MiddlewareFailure]: [request: ApiRequest, response: ApiResponse];\n\t[ServerEvent.MiddlewareSuccess]: [request: Route.Request, response: Route.Response, route: Route];\n\t[ServerEvent.MiddlewareError]: [error: Error, request: ApiRequest, response: ApiResponse];\n}\n\n/**\n * @since 1.0.0\n */\nexport class Server extends AsyncEventEmitter<ServerEvents> {\n\t/**\n\t * The routes this server holds.\n\t * @since 1.0.0\n\t */\n\tpublic readonly routes: RouteStore;\n\n\t/**\n\t * The middlewares this server holds.\n\t * @since 1.0.0\n\t */\n\tpublic readonly middlewares: MiddlewareStore;\n\n\t/**\n\t * The authentication system.\n\t * @since 1.0.0\n\t */\n\tpublic readonly auth: Auth | null;\n\n\t/**\n\t * The http.Server instance that manages the recieved HTTP requests.\n\t * @since 1.0.0\n\t */\n\tpublic readonly server: HttpServer;\n\n\t/**\n\t * The options for this server.\n\t * @since 1.0.0\n\t */\n\tpublic readonly options: AuthLessServerOptions;\n\n\t/**\n\t * @since 1.0.0\n\t * @param options The options for this server\n\t */\n\tpublic constructor({ auth, ...options }: ServerOptions = {}) {\n\t\tsuper();\n\n\t\tcontainer.server = this;\n\n\t\tthis.options = options;\n\t\tthis.server = httpCreateServer({\n\t\t\tIncomingMessage: ApiRequest,\n\t\t\tServerResponse: ApiResponse,\n\t\t\t...(options.server ?? {})\n\t\t});\n\t\tthis.routes = new RouteStore();\n\t\tthis.middlewares = new MiddlewareStore();\n\t\tthis.auth = Auth.create(auth);\n\t\tthis.server.on('error', this.emit.bind(this, ServerEvent.Error));\n\t\tthis.server.on('request', this.emit.bind(this, ServerEvent.Request));\n\t}\n\n\tpublic connect() {\n\t\tconst { server } = this;\n\t\tserver.listen({\n\t\t\tport: 4000,\n\t\t\t...(this.options.listenOptions ?? {})\n\t\t});\n\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tfunction listening() {\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t}\n\n\t\t\tfunction error(error: Error) {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t}\n\n\t\t\tfunction close() {\n\t\t\t\tcleanup();\n\t\t\t\treject(new Error('Closed unexpectedly.'));\n\t\t\t}\n\n\t\t\tfunction cleanup() {\n\t\t\t\tserver.off('listening', listening);\n\t\t\t\tserver.off('error', error);\n\t\t\t\tserver.off('close', close);\n\t\t\t}\n\n\t\t\tserver.on('listening', listening);\n\t\t\tserver.on('error', error);\n\t\t\tserver.on('close', close);\n\t\t});\n\t}\n\n\tpublic disconnect() {\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tthis.server.close((error) => (error ? reject(error) : resolve()));\n\t\t});\n\t}\n}\n\n/**\n * RFC 1341 4: Defines a Content-Type's type, which follows the following structure:\n *\n * - `type` = `text` | `multipart` | `message` | `image` | `audio` | `video` | `application` | x-token\n * - `x-token` = The two characters \"X-\" followed, with no intervening white space, by any token\n * @since 1.3.0\n */\nexport type ContentTypeType = 'text' | 'multipart' | 'message' | 'image' | 'audio' | 'video' | 'application' | `X-${string}`;\n\n/**\n * RFC 1341 4: Defines a Content-Type's parameter, which follows the following structure:\n *\n * - `parameter` = `attribute` \"=\" `value`\n * - `attribute` = `token`\n * - `value` = `token` / `quoted-string`\n * - `token` = `1*<any CHAR except \"SPACE\", \"CTLs\", or \"tspecials\">`\n * - `tspecials` = `(` | `)` | `<` | `>` | `@` | `,` | `;` | `:` | `\\` | `\"` | `/` | `[` | `]` | `?` | `.` | `=`\n *\n * @note `tspecials` must be in quoted-string, to use within parameter values.\n * @note The definition of `tspecials` is the same as the RFC 822 definition of `specials` with the addition of the\n * three characters `/`, `?`, and `=`.\n * @since 1.3.0\n */\nexport type ContentTypeParameter = `; ${string}=${string}`;\n\n/**\n * RFC 1341 4: Defines the syntax for a Content-Type field without parameters, which follows the following structure:\n * `type \"/\" subtype`.\n * @since 7.0.0\n */\nexport type GenericMimeType = `${ContentTypeType}/${string}`;\n\n/**\n * RFC 1341 4: Defines the syntax for a Content-Type field, which follows the following structure:\n * `type \"/\" subtype *[\";\" parameter]`.\n * @since 7.0.0\n */\nexport type GenericParametrizedMimeType = `${GenericMimeType}${'' | ContentTypeParameter}`;\n\n/**\n * The API options.\n * @since 1.0.0\n */\nexport interface ServerOptions {\n\t/**\n\t * The prefix for all routes, e.g. `v1/`.\n\t * @since 1.0.0\n\t * @default ''\n\t */\n\tprefix?: string;\n\n\t/**\n\t * The origin header to be set on every request at 'Access-Control-Allow-Origin'.\n\t * @since 1.0.0\n\t * @default '*'\n\t */\n\torigin?: 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 1024 * 1024 * 50\n\t */\n\tmaximumBodyLength?: number;\n\n\t/**\n\t * The HTTP server options.\n\t * @since 1.0.0\n\t * @default {}\n\t */\n\tserver?: HttpOptions;\n\n\t/**\n\t * The HTTP listen options.\n\t * @since 1.0.0\n\t * @default { port: 4000 }\n\t */\n\tlistenOptions?: ListenOptions;\n\n\t/**\n\t * The auth options. If neither `auth` nor `auth.secret` are defined, auth-related routes and middlewares will be\n\t * automatically disabled.\n\t * @since 1.0.0\n\t * @default {}\n\t */\n\tauth?: ServerOptionsAuth;\n\n\t/**\n\t * Whether the server should connect upon being when the plugin is loaded.\n\t * @since 3.2.0\n\t * @default true\n\t */\n\tautomaticallyConnect?: boolean;\n}\n\n/**\n * The {@link ServerOptions} without {@link ServerOptions.auth}.\n * @since 1.0.0\n */\nexport type AuthLessServerOptions = Omit<ServerOptions, 'auth'>;\n"]}