winterspec
Version:
Write Winter-CG compatible routes with filesystem routing and tons of features
99 lines (98 loc) • 3.08 kB
JavaScript
export class WinterSpecResponse {
statusCode() {
return this.options.status ?? 200;
}
status(status) {
this.options.status = status;
return this;
}
header(key, value) {
this.options.headers = mergeHeaders(this.options.headers, {
[key]: value,
});
return this;
}
headers(headers) {
this.options.headers = mergeHeaders(this.options.headers, headers);
return this;
}
statusText(statusText) {
this.options.statusText = statusText;
return this;
}
constructor(options = {}) {
this.options = options;
}
static json(...args) {
return new WinterSpecJsonResponse(...args);
}
static multipartFormData(...args) {
return new WinterSpecMultiPartFormDataResponse(...args);
}
static custom(...args) {
return new WinterSpecCustomResponse(...args);
}
}
export class WinterSpecJsonResponse extends WinterSpecResponse {
constructor(data, options = {}) {
super(options);
this.data = data;
this.options.headers = mergeHeaders(this.options.headers, {
"Content-Type": "application/json",
});
}
serializeToResponse(schema) {
return new Response(JSON.stringify(schema.parse(this.data)), this.options);
}
}
export class WinterSpecCustomResponse extends WinterSpecResponse {
constructor(data, contentType, options = {}) {
super(options);
this.data = data;
this.contentType = contentType;
this.options.headers = mergeHeaders(this.options.headers, {
"Content-Type": contentType,
});
}
serializeToResponse(schema) {
return new Response(schema.parse(this.data), this.options);
}
}
export class MiddlewareResponseData extends WinterSpecResponse {
constructor(options = {}) {
super(options);
}
serializeToResponse() {
return new Response(undefined, this.options);
}
}
export class WinterSpecMultiPartFormDataResponse extends WinterSpecResponse {
constructor(data, options = {}) {
super(options);
this.data = data;
this.options.headers = mergeHeaders(this.options.headers, {
"Content-Type": "multipart/form-data",
});
}
serializeToResponse(schema) {
const formData = new FormData();
for (const [key, value] of Object.entries(schema.parse(this.data))) {
// TODO: nested objects?
formData.append(key, value instanceof Blob ? value : String(value));
}
return new Response(formData, this.options);
}
}
export function createWinterSpecRequest(request, options) {
return Object.assign(request, options);
}
export function mergeHeaders(h1, h2) {
return new Headers(Object.fromEntries([
...(h1 instanceof Headers
? h1
: new Headers(h1 ?? undefined).entries() ?? []),
...(h2 instanceof Headers
? h2
: new Headers(h2 ?? undefined).entries() ?? []),
]));
}