2023-03-08 13:45:06 -08:00
|
|
|
const {fetch, Headers} = require('cross-fetch');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Metadata header names
|
|
|
|
* @enum {string}
|
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
const RequestMetadata = {
|
|
|
|
/** The ID of the project associated with this request */
|
|
|
|
ProjectId: 'X-ProjectId',
|
|
|
|
/** The ID of the project run associated with this request */
|
|
|
|
RunId: 'X-RunId'
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Metadata for requests
|
|
|
|
* @type {Map<string, string>}
|
|
|
|
*/
|
|
|
|
const metadata = new Map();
|
2023-03-08 11:23:10 -08:00
|
|
|
|
|
|
|
/**
|
2023-03-09 09:13:47 -08:00
|
|
|
* Non-destructively merge any metadata state (if any) with the provided options object (if any).
|
|
|
|
* If there is metadata state but no options object is provided, make a new object.
|
|
|
|
* If there is no metadata state, return the provided options parameter without modification.
|
|
|
|
* If there is metadata and an options object is provided, modify a copy and return it.
|
|
|
|
* Headers in the provided options object may override headers generated from metadata state.
|
|
|
|
* @param {RequestInit} [options] The initial request options. May be null or undefined.
|
|
|
|
* @returns {RequestInit|undefined} the provided options parameter without modification, or a new options object.
|
2023-03-08 13:45:06 -08:00
|
|
|
*/
|
2023-03-09 09:13:47 -08:00
|
|
|
const applyMetadata = options => {
|
2023-03-08 13:45:06 -08:00
|
|
|
if (metadata.size > 0) {
|
2023-03-09 09:13:47 -08:00
|
|
|
const augmentedOptions = Object.assign({}, options);
|
2023-03-08 13:45:06 -08:00
|
|
|
augmentedOptions.headers = new Headers(Array.from(metadata));
|
2023-03-09 09:56:13 -08:00
|
|
|
if (options && options.headers) {
|
2023-03-08 13:45:06 -08:00
|
|
|
const overrideHeaders =
|
|
|
|
options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
|
|
for (const [name, value] of overrideHeaders.entries()) {
|
|
|
|
augmentedOptions.headers.set(name, value);
|
|
|
|
}
|
|
|
|
}
|
2023-03-09 09:13:47 -08:00
|
|
|
return augmentedOptions;
|
2023-03-08 13:45:06 -08:00
|
|
|
}
|
2023-03-09 09:13:47 -08:00
|
|
|
return options;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Make a network request.
|
|
|
|
* This is a wrapper for the global fetch method, adding some Scratch-specific functionality.
|
|
|
|
* @param {RequestInfo|URL} resource The resource to fetch.
|
|
|
|
* @param {RequestInit} options Optional object containing custom settings for this request.
|
|
|
|
* @see {@link https://developer.mozilla.org/docs/Web/API/fetch} for more about the fetch API.
|
|
|
|
* @returns {Promise<Response>} A promise for the response to the request.
|
|
|
|
*/
|
|
|
|
const scratchFetch = (resource, options) => {
|
|
|
|
const augmentedOptions = applyMetadata(options);
|
2023-03-08 13:45:06 -08:00
|
|
|
return fetch(resource, augmentedOptions);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {RequestMetadata} name The name of the metadata item to set.
|
|
|
|
* @param {any} value The value to set (will be converted to a string)
|
2023-03-08 11:23:10 -08:00
|
|
|
*/
|
2023-03-08 13:45:06 -08:00
|
|
|
const setMetadata = (name, value) => {
|
|
|
|
metadata.set(name, value);
|
|
|
|
};
|
2023-03-08 11:23:10 -08:00
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
default: scratchFetch,
|
2023-03-09 09:13:47 -08:00
|
|
|
|
|
|
|
RequestMetadata,
|
|
|
|
applyMetadata,
|
2023-03-08 13:45:06 -08:00
|
|
|
scratchFetch,
|
|
|
|
setMetadata
|
2023-03-08 11:23:10 -08:00
|
|
|
};
|