UNPKG

3.46 kBJavaScriptView Raw
1import { addQueryParameters } from "./util/add-query-parameters";
2import { extractUrlVariableNames } from "./util/extract-url-variable-names";
3import { omit } from "./util/omit";
4import { parseUrl } from "./util/url-template";
5export function parse(options) {
6 // https://fetch.spec.whatwg.org/#methods
7 let method = options.method.toUpperCase();
8 // replace :varname with {varname} to make it RFC 6570 compatible
9 let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
10 let headers = Object.assign({}, options.headers);
11 let body;
12 let parameters = omit(options, [
13 "method",
14 "baseUrl",
15 "url",
16 "headers",
17 "request",
18 "mediaType",
19 ]);
20 // extract variable names from URL to calculate remaining variables later
21 const urlVariableNames = extractUrlVariableNames(url);
22 url = parseUrl(url).expand(parameters);
23 if (!/^http/.test(url)) {
24 url = options.baseUrl + url;
25 }
26 const omittedParameters = Object.keys(options)
27 .filter((option) => urlVariableNames.includes(option))
28 .concat("baseUrl");
29 const remainingParameters = omit(parameters, omittedParameters);
30 const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
31 if (!isBinaryRequest) {
32 if (options.mediaType.format) {
33 // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
34 headers.accept = headers.accept
35 .split(/,/)
36 .map((preview) => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
37 .join(",");
38 }
39 if (options.mediaType.previews.length) {
40 const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
41 headers.accept = previewsFromAcceptHeader
42 .concat(options.mediaType.previews)
43 .map((preview) => {
44 const format = options.mediaType.format
45 ? `.${options.mediaType.format}`
46 : "+json";
47 return `application/vnd.github.${preview}-preview${format}`;
48 })
49 .join(",");
50 }
51 }
52 // for GET/HEAD requests, set URL query parameters from remaining parameters
53 // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
54 if (["GET", "HEAD"].includes(method)) {
55 url = addQueryParameters(url, remainingParameters);
56 }
57 else {
58 if ("data" in remainingParameters) {
59 body = remainingParameters.data;
60 }
61 else {
62 if (Object.keys(remainingParameters).length) {
63 body = remainingParameters;
64 }
65 }
66 }
67 // default content-type for JSON if body is set
68 if (!headers["content-type"] && typeof body !== "undefined") {
69 headers["content-type"] = "application/json; charset=utf-8";
70 }
71 // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
72 // fetch does not allow to set `content-length` header, but we can set body to an empty string
73 if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
74 body = "";
75 }
76 // Only return body/request keys if present
77 return Object.assign({ method, url, headers }, typeof body !== "undefined" ? { body } : null, options.request ? { request: options.request } : null);
78}