Skip to content

Commit

Permalink
feat: add bun server
Browse files Browse the repository at this point in the history
  • Loading branch information
Snazzah committed Nov 6, 2023
1 parent db3c41a commit 6245616
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Additions:
- Commands can now use the `throttle()` function which takes a CommandContext and allows you to asynchronously ratelimit users before running the command itself.
- slash-create now has a web export for built-in Cloudflare Worker compatibility.
- Added the `USE_EXTERNAL_SOUNDS` permission (1 << 46)
- Support for the Bun runtime with `BunServer`.
- Added the `USE_EXTERNAL_SOUNDS` permission. (1 << 46)
### Fixed:
- **types**: `min_length` and `max_length` to string options now exists
## [5.14.0] - 2023-09-27
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export * from './rest/DiscordRESTError';
export * from './rest/requestHandler';
export * from './rest/sequentialBucket';

export * from './servers/bun';
export * from './servers/cfworker';
export * from './servers/lambda';
export * from './servers/azure';
Expand Down
80 changes: 80 additions & 0 deletions src/servers/bun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Server, ServerRequestHandler } from '../server';

/**
* A server for the Bun runtime.
* @see https://bun.sh/docs/api/http#bun-serve
*/
export class BunServer extends Server {
private _handler?: ServerRequestHandler;
private _options: any = {};

/**
* @param options The options to use when creating a Bun server
*/
constructor(options?: any) {
super();
if (!('Bun' in globalThis)) throw new Error('This can only be used in a Bun runtime.');
this._options = options;
}

/**
* The fetch handler for the server. You can call this function to run the handler or use `listen` to create a server that uses the handler.
* @example
* export const workerServer = new CloudflareWorkerServer();
* creator.withServer(workerServer);
* export default workerServer;
*/
readonly fetch = async (request: Request) => {
if (!this._handler) return new Response('Server has no handler.', { status: 503 });
if (request.method !== 'POST') return new Response('Server only supports POST requests.', { status: 405 });
const body = await request.text();
return new Promise((resolve, reject) => {
this._handler!(
{
headers: Object.fromEntries((request as any).headers.entries()),
body: body ? JSON.parse(body) : body,
request,
response: null
},
async (response) => {
if (response.files) {
const data = new FormData();
for (const file of response.files) data.append(file.name, new Blob([file.file]), file.name);
data.append('payload_json', JSON.stringify(response.body));
resolve(
new Response(data, {
status: response.status || 200,
headers: (response.headers || {}) as Record<string, string>
})
);
} else
resolve(
new Response(JSON.stringify(response.body), {
status: response.status || 200,
headers: {
...((response.headers || {}) as Record<string, string>),
'content-type': 'application/json'
}
})
);
}
).catch(reject);
}) as Promise<Response>;
};

/** @private */
createEndpoint(path: string, handler: ServerRequestHandler) {
this._handler = handler;
}

/** @private */
async listen(port = 8030, host = 'localhost') {
if (this.alreadyListening) return;
(globalThis as any).Bun.serve({
...this._options,
port,
hostname: host,
fetch: this.fetch.bind(this)
});
}
}

0 comments on commit 6245616

Please sign in to comment.