@h3ravel/http
Version:
HTTP kernel, middleware pipeline, request/response classes for H3ravel.
361 lines (353 loc) • 7.91 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/Middleware.ts
var Middleware = class {
static {
__name(this, "Middleware");
}
};
// src/Request.ts
import { getQuery, getRouterParams, readBody } from "h3";
import { safeDot } from "@h3ravel/support";
var Request = class {
static {
__name(this, "Request");
}
app;
/**
* Gets route parameters.
* @returns An object containing route parameters.
*/
params;
/**
* Gets query parameters.
* @returns An object containing query parameters.
*/
query;
/**
* Gets the request headers.
* @returns An object containing request headers.
*/
headers;
/**
* The current H3 H3Event instance
*/
event;
constructor(event, app) {
this.app = app;
this.event = event;
this.query = getQuery(this.event);
this.params = getRouterParams(this.event);
this.headers = this.event.req.headers;
}
/**
* Get all input data (query + body).
*/
async all() {
let data = {
...getRouterParams(this.event),
...getQuery(this.event)
};
if (this.event.req.method === "POST") {
data = Object.assign({}, data, Object.fromEntries((await this.event.req.formData()).entries()));
} else if (this.event.req.method === "PUT") {
data = Object.fromEntries(Object.entries(await readBody(this.event)));
}
return data;
}
/**
* Get a single input field from query or body.
*/
async input(key, defaultValue) {
const data = await this.all();
return data[key] ?? defaultValue;
}
getEvent(key) {
return safeDot(this.event, key);
}
};
// src/Response.ts
import { safeDot as safeDot2 } from "@h3ravel/support";
import { html, redirect } from "h3";
var Response = class {
static {
__name(this, "Response");
}
app;
/**
* The current H3 H3Event instance
*/
event;
statusCode = 200;
headers = {};
constructor(event, app) {
this.app = app;
this.event = event;
}
/**
* Set HTTP status code.
*/
setStatusCode(code) {
this.statusCode = code;
this.event.res.status = code;
return this;
}
/**
* Set a header.
*/
setHeader(name, value) {
this.headers[name] = value;
return this;
}
html(content) {
this.applyHeaders();
return html(this.event, content);
}
/**
* Send a JSON response.
*/
json(data) {
this.setHeader("content-type", "application/json; charset=utf-8");
this.applyHeaders();
return data;
}
/**
* Send plain text.
*/
text(data) {
this.setHeader("content-type", "text/plain; charset=utf-8");
this.applyHeaders();
return data;
}
/**
* Redirect to another URL.
*/
redirect(url, status = 302) {
this.setStatusCode(status);
return redirect(this.event, url, this.statusCode);
}
/**
* Apply headers before sending response.
*/
applyHeaders() {
Object.entries(this.headers).forEach(([key, value]) => {
this.event.res.headers.set(key, value);
});
}
getEvent(key) {
return safeDot2(this.event, key);
}
};
// src/Contracts/HttpContract.ts
import { HttpContext } from "@h3ravel/shared";
// src/Middleware/LogRequests.ts
var LogRequests = class extends Middleware {
static {
__name(this, "LogRequests");
}
async handle({ request }, next) {
const url = request.getEvent("url");
console.log(`[${request.getEvent("method")}] ${url.pathname + url.search}`);
return next();
}
};
// src/Providers/HttpServiceProvider.ts
import { H3, serve } from "h3";
import { ServiceProvider } from "@h3ravel/core";
var HttpServiceProvider = class extends ServiceProvider {
static {
__name(this, "HttpServiceProvider");
}
static priority = 998;
register() {
this.app.singleton("http.app", () => {
return new H3();
});
this.app.singleton("http.serve", () => serve);
}
};
// src/Resources/JsonResource.ts
var JsonResource = class {
static {
__name(this, "JsonResource");
}
event;
/**
* The request instance
*/
request;
/**
* The response instance
*/
response;
/**
* The data to send to the client
*/
resource;
/**
* The final response data object
*/
body = {
data: {}
};
/**
* Flag to track if response should be sent automatically
*/
shouldSend = false;
/**
* Flag to track if response has been sent
*/
responseSent = false;
/**
* @param req The request instance
* @param res The response instance
* @param rsc The data to send to the client
*/
constructor(event, rsc) {
this.event = event;
this.request = event.req;
this.response = event.res;
this.resource = rsc;
for (const key of Object.keys(rsc)) {
if (!(key in this)) {
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get: () => this.resource[key],
set: (value) => {
this.resource[key] = value;
}
});
}
}
}
/**
* Return the data in the expected format
*
* @returns
*/
data() {
return this.resource;
}
/**
* Build the response object
* @returns this
*/
json() {
this.shouldSend = true;
this.response.status = 200;
const resource = this.data();
let data = Array.isArray(resource) ? [
...resource
] : {
...resource
};
if (typeof data.data !== "undefined") {
data = data.data;
}
if (!Array.isArray(resource)) {
delete data.pagination;
}
this.body = {
data
};
if (!Array.isArray(resource) && resource.pagination) {
const meta = this.body.meta ?? {};
meta.pagination = resource.pagination;
this.body.meta = meta;
}
if (this.resource.pagination && !this.body.meta?.pagination) {
const meta = this.body.meta ?? {};
meta.pagination = this.resource.pagination;
this.body.meta = meta;
}
return this;
}
/**
* Add context data to the response object
* @param data Context data
* @returns this
*/
additional(data) {
this.shouldSend = true;
delete data.data;
delete data.pagination;
this.body = {
...this.body,
...data
};
return this;
}
/**
* Send the output to the client
* @returns this
*/
send() {
this.shouldSend = false;
if (!this.responseSent) {
this.#send();
}
return this;
}
/**
* Set the status code for this response
* @param code Status code
* @returns this
*/
status(code) {
this.response.status = code;
return this;
}
/**
* Private method to send the response
*/
#send() {
if (!this.responseSent) {
this.event.context.this.response.json(this.body);
this.responseSent = true;
}
}
/**
* Check if send should be triggered automatically
*/
checkSend() {
if (this.shouldSend && !this.responseSent) {
this.#send();
}
}
};
// src/Resources/ApiResource.ts
function ApiResource(instance) {
return new Proxy(instance, {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver);
if (typeof value === "function") {
if (prop === "json" || prop === "additional") {
return (...args) => {
const result = value.apply(target, args);
setImmediate(() => target["checkSend"]());
return result;
};
} else if (prop === "send") {
return (...args) => {
target["shouldSend"] = false;
return value.apply(target, args);
};
}
}
return value;
}
});
}
__name(ApiResource, "ApiResource");
export {
ApiResource,
HttpContext,
HttpServiceProvider,
JsonResource,
LogRequests,
Middleware,
Request,
Response
};
//# sourceMappingURL=index.js.map