@procore/core-http
Version:
A HTTP Client
219 lines (211 loc) • 6.72 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
authPlugin: () => authPlugin,
createClient: () => createClient,
isJsonifiable: () => import_up_fetch3.isJsonifiable,
isResponseError: () => import_up_fetch3.isResponseError,
isValidationError: () => import_up_fetch3.isValidationError,
request: () => request,
requestJSON: () => requestJSON
});
module.exports = __toCommonJS(index_exports);
var import_up_fetch3 = require("up-fetch");
// src/authPlugin.ts
var import_up_fetch = require("up-fetch");
var import_web_sdk_events = require("@procore/web-sdk-events");
var systemEvents = new import_web_sdk_events.SystemEvents("core-http");
function detectAndPublishStepUp(response, request2) {
if (response.status === 401 && response.headers.get("www-authenticate")) {
const eventData = {
type: import_web_sdk_events.SystemEventNames.NETWORKING_STEPUP_REQUIRED,
url: request2 == null ? void 0 : request2.url,
status: response.status,
wwwAuthenticate: response.headers.get("www-authenticate") || "",
timestamp: Date.now()
};
systemEvents.publish(import_web_sdk_events.SystemEventNames.NETWORKING_EXCEPTION, eventData);
}
}
var authPlugin = {
onSuccess: (response, request2) => {
if (response instanceof Response) {
detectAndPublishStepUp(response, request2);
}
},
onError: (error, request2) => {
if ((0, import_up_fetch.isResponseError)(error)) {
const response = error.response;
if (response instanceof Response) {
detectAndPublishStepUp(response, request2);
}
}
}
};
// src/create-client.ts
var import_web_sdk_events3 = require("@procore/web-sdk-events");
var import_up_fetch2 = require("up-fetch");
// src/utils.ts
function collectFunctions(plugins, fnName) {
const functions = [];
for (const plugin of plugins) {
if (plugin[fnName]) {
functions.push(plugin[fnName]);
}
}
return functions;
}
function createFunctionChain(fns) {
return fns.length === 0 ? void 0 : fns.length === 1 ? fns[0] : async (...args) => {
for (const fn of fns) {
await fn(...args);
}
};
}
// src/error-reporter-plugin.ts
var import_web_sdk_events2 = require("@procore/web-sdk-events");
function normalizeError(error) {
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack
};
}
return {
name: "UnknownError",
message: String(error),
stack: void 0
};
}
function createErrorReporterPlugin(systemEvents2, errorReportingApiKey) {
return {
onError: (error) => {
if (!errorReportingApiKey) return;
systemEvents2.publish(import_web_sdk_events2.SystemEventNames.UNCAUGHT_EXCEPTION, {
errorReportingApiKey,
error: normalizeError(error)
});
}
};
}
// src/create-client.ts
var SERVICE_NAME = "core-http";
function getCSRFToken() {
const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
if ((token == null ? void 0 : token[2]) && token[2] !== "") {
return decodeURIComponent(token[2]);
}
return void 0;
}
function resolveDefaultErrorHandling(options, fallback) {
if (options && typeof options === "object" && "defaultErrorHandling" in options) {
const v = options.defaultErrorHandling;
if (typeof v === "boolean") return v;
}
return fallback;
}
function createClient({
// This grabs a reference to window.fetch on each request, rather than hard-coding it at initialization time.
fetchFn = (input, options) => fetch(input, options),
defaults = () => ({}),
plugins = [],
defaultErrorHandling = true,
errorReportingApiKey,
systemEvents: systemEvents2
}) {
const upFetch = (0, import_up_fetch2.up)(fetchFn, async (input, fetcherOpts, ctx) => {
const defaultOptions = await defaults(input, fetcherOpts, ctx);
const shouldReportErrors = resolveDefaultErrorHandling(fetcherOpts, defaultErrorHandling) && Boolean(errorReportingApiKey);
const allPlugins = [
defaultOptions,
...plugins,
...shouldReportErrors ? [
createErrorReporterPlugin(
systemEvents2 ?? new import_web_sdk_events3.SystemEvents(SERVICE_NAME),
errorReportingApiKey
)
] : []
];
const onError = createFunctionChain(collectFunctions(allPlugins, "onError"));
const onRequest = createFunctionChain(
collectFunctions(allPlugins, "onRequest")
);
const onSuccess = createFunctionChain(
collectFunctions(allPlugins, "onSuccess")
);
const csrfToken = getCSRFToken();
return {
credentials: "same-origin",
mode: "same-origin",
...defaultOptions,
headers: {
...defaultOptions.headers,
...csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}
},
onError,
onRequest,
onSuccess
};
});
return (input, options) => upFetch(input, options);
}
// src/request.ts
function request(url, requestParams = {}) {
const {
signal,
baseUrl,
errorReportingApiKey = "",
systemEvents: systemEvents2,
...options
} = requestParams;
return createClient({
errorReportingApiKey,
...systemEvents2 && { systemEvents: systemEvents2 },
defaults: () => ({
...baseUrl ? { baseUrl: new URL(baseUrl, document.baseURI).toString() } : {},
// Skips the default parseResponse and reject so that
// the function behaves like default fetch.
parseResponse(response) {
return response;
},
reject: () => false
})
})(url, {
...options,
signal: signal ?? void 0
});
}
function requestJSON(url, requestParams = {}) {
return request(url, requestParams).then(
(response) => response.json()
);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
authPlugin,
createClient,
isJsonifiable,
isResponseError,
isValidationError,
request,
requestJSON
});