UNPKG

picnic-api

Version:

Unofficial wrapper for the API of the online supermarket Picnic

73 lines 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Base HTTP client that handles request construction, authentication headers, * and error handling for the Picnic API. */ class HttpClient { constructor(options) { this.countryCode = options?.countryCode || "NL"; this.apiVersion = options?.apiVersion || "15"; this.authKey = options?.authKey || null; this.url = options?.url || `https://storefront-prod.${this.countryCode.toLowerCase()}.picnicinternational.com/api/${this.apiVersion}`; this.deviceId = options?.deviceId || "3C417201548B2E3B"; this.agent = options?.agent || "30100;1.236.1-15553;"; } get baseHeaders() { return { "User-Agent": "okhttp/4.9.0", "Content-Type": "application/json; charset=UTF-8", "Accept-Language": this.countryCode === "DE" ? "de" : (this.countryCode === "FR" ? "fr" : "nl"), ...(this.authKey && { "x-picnic-auth": this.authKey }), }; } get picnicHeaders() { return { "x-picnic-agent": this.agent, "x-picnic-did": this.deviceId, }; } /** * Can be used to send custom requests that are not covered by the domain services. * @param {string} method The HTTP method to use: GET, POST, PUT or DELETE. * @param {string} path The path, optionally including query params. Example: `/cart/set_delivery_slot` or `/my_store?depth=0`. * @param {TRequestData|null} [data=null] The request body, typically for POST or PUT requests. * @param {boolean} [includePicnicHeaders=false] Whether to include x-picnic-agent and x-picnic-did headers. * @param {boolean} [isImageRequest=false] When true, returns an ArrayBuffer instead of JSON. */ async sendRequest(method, path, data = null, includePicnicHeaders = false, isImageRequest = false) { const headers = new Headers({ ...this.baseHeaders, ...(includePicnicHeaders && this.picnicHeaders), }); // `path` may be an absolute URL (e.g. image requests target a different base // than the API), in which case it must be used as-is rather than prefixed. const requestUrl = /^https?:\/\//.test(path) ? path : `${this.url}${path}`; const response = await fetch(requestUrl, { method, headers, body: data ? JSON.stringify(data) : null, }); if (!response.ok) { const body = await response.text(); try { const errorData = JSON.parse(body); throw new Error(`${errorData.error?.message || response.statusText}`); } catch (e) { if (e instanceof Error && !(e instanceof SyntaxError)) throw e; throw new Error(`${response.status} ${response.statusText}${body ? ` - ${body}` : ""}`); } } if (isImageRequest) { return response.arrayBuffer(); } if (response.body !== null) { return response.json(); } return undefined; } } exports.default = HttpClient; //# sourceMappingURL=http-client.js.map