diff --git a/scripts/fetch-api/README.md b/scripts/fetch-api/README.md new file mode 100644 index 00000000..c3cf73b8 --- /dev/null +++ b/scripts/fetch-api/README.md @@ -0,0 +1,54 @@ +# Fetch + +## Description + +The `Fetch` class simplifies HTTP requests in Minecraft Bedrock Edition. It supports common HTTP methods like `GET`, `POST`, `PUT`, and `DELETE`, and automatically handles JSON data. + +### Methods + +#### `constructor(baseURL: string)` +- Initializes a new `Fetch` instance with the specified base URL. + +#### `get(path: string, params?: Object): Promise` +- Sends an HTTP `GET` request to the specified path with optional query parameters. + +#### `post(path: string, data: Object): Promise` +- Sends an HTTP `POST` request to the specified path with the provided data. + +#### `put(path: string, data: Object): Promise` +- Sends an HTTP `PUT` request to the specified path with the provided data. + +#### `delete(path: string): Promise` +- Sends an HTTP `DELETE` request to the specified path. + +### Example +```js +import { Fetch } from './fetch.js'; + +// Initialize Fetch instance +const api = new Fetch("https://jsonplaceholder.typicode.com"); + +// GET example +api.get("/posts", { userId: 1 }).then((data) => console.log(data)); + +// POST example +api.post("/posts", { + title: "foo", + body: "bar", + userId: 1 +}).then((data) => console.log(data)); + +// PUT example +api.put("/posts/1", { + title: "updated title", + body: "updated body", + userId: 1 +}).then((data) => console.log(data)); + +// DELETE example +api.delete("/posts/1").then((data) => console.log(data)); +``` + +## Credits + +These scripts were written by [nperma](https://github.com/nperma) diff --git a/scripts/fetch-api/index.js b/scripts/fetch-api/index.js new file mode 100644 index 00000000..1936a0bf --- /dev/null +++ b/scripts/fetch-api/index.js @@ -0,0 +1,123 @@ +// Script example for ScriptAPI +// Author: nperma +// Project: https://github.com/JaylyDev/ScriptAPI + +import { + http, + HttpHeader, + HttpRequest, + HttpRequestMethod, +} from "@minecraft/server-net"; + +/** + * Class Fetch - Abstraction for HTTP Requests + */ +class Fetch { + /** + * Constructor to initialize the base URL. + * @param {string} baseURL - The base URL for API requests. + */ + constructor(baseURL) { + this.baseURL = baseURL.trim(); + } + + /** + * Performs an HTTP GET request. + * @param {string} path - The API endpoint path. + * @param {Object} [params={}] - Query parameters. + * @returns {Promise} - The response body as JSON. + */ + async get(path, params = {}) { + const queryString = this._buildQueryString(params); + const uri = `${this.baseURL}${path}${queryString}`; + const request = new HttpRequest(uri); + request.method = HttpRequestMethod.Get; + request.headers = [new HttpHeader("Content-Type", "application/json")]; + + const response = await http.request(request); + return this._handleResponse(response); + } + + /** + * Performs an HTTP POST request. + * @param {string} path - The API endpoint path. + * @param {Object} data - The data to send in the request body. + * @returns {Promise} - The response body as JSON. + */ + async post(path, data) { + const uri = `${this.baseURL}${path}`; + const request = new HttpRequest(uri); + request.method = HttpRequestMethod.Post; + request.body = JSON.stringify(data); + request.headers = [new HttpHeader("Content-Type", "application/json")]; + + const response = await http.request(request); + return this._handleResponse(response); + } + + /** + * Performs an HTTP PUT request. + * @param {string} path - The API endpoint path. + * @param {Object} data - The data to send in the request body. + * @returns {Promise} - The response body as JSON. + */ + async put(path, data) { + const uri = `${this.baseURL}${path}`; + const request = new HttpRequest(uri); + request.method = HttpRequestMethod.Put; + request.body = JSON.stringify(data); + request.headers = [new HttpHeader("Content-Type", "application/json")]; + + const response = await http.request(request); + return this._handleResponse(response); + } + + /** + * Performs an HTTP DELETE request. + * @param {string} path - The API endpoint path. + * @returns {Promise} - The response body as JSON. + */ + async delete(path) { + const uri = `${this.baseURL}${path}`; + const request = new HttpRequest(uri); + request.method = HttpRequestMethod.Delete; + request.headers = [new HttpHeader("Content-Type", "application/json")]; + + const response = await http.request(request); + return this._handleResponse(response); + } + + /** + * Handles the response from the server. + * @param {Object} response - The HTTP response object. + * @returns {Promise} - The parsed JSON body. + * @throws {Error} - If the response status is not 200. + */ + async _handleResponse(response) { + if (response.status !== 200) { + throw new Error( + `HTTP Error: ${response.status} - ${response.body}` + ); + } + return JSON.parse(response.body); + } + + /** + * Builds a query string from an object of parameters. + * @param {Object} params - The query parameters. + * @returns {string} - The query string. + */ + _buildQueryString(params) { + const entries = Object.entries(params); + if (entries.length === 0) return ""; + return ( + "?" + + entries + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) + .join("&") + ); + } +} + +export { Fetch }; +