New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@sitecore-jss/sitecore-jss

Package Overview
Dependencies
Maintainers
0
Versions
1438
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sitecore-jss/sitecore-jss - npm Package Compare versions

Comparing version 22.4.0-canary.9 to 22.4.0-canary.10

31

dist/cjs/data-fetcher.js
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResponseError = void 0;
exports.checkStatus = checkStatus;
exports.fetchData = fetchData;

@@ -16,24 +24,11 @@ const utils_1 = require("./utils/utils");

/**
* @param {HttpResponse<T>} response the response to check
* @throws {ResponseError} if response code is not ok
*/
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new ResponseError(response.statusText, response);
throw error;
}
/**
* @param {string} url the URL to request; may include query string
* @param {HttpDataFetcher} fetcher the fetcher to use to perform the request
* @param {HttpDataFetcher<T> | NativeDataFetcherFunction<T>} fetcher the fetcher to use to perform the request
* @param {ParsedUrlQueryInput} params the query string parameters to send with the request
*/
function fetchData(url, fetcher, params = {}) {
return fetcher((0, utils_1.resolveUrl)(url, params))
.then(checkStatus)
.then((response) => {
// axios auto-parses JSON responses, don't need to JSON.parse
function fetchData(url_1, fetcher_1) {
return __awaiter(this, arguments, void 0, function* (url, fetcher, params = {}) {
const response = yield fetcher((0, utils_1.resolveUrl)(url, params));
return response.data;
});
}

@@ -113,3 +113,3 @@ "use strict";

// Note we don't have access to raw request/response with graphql-request
// (or nice hooks like we have with Axios), but we should log whatever we have.
// but we should log whatever we have.
this.debug('request: %o', {

@@ -116,0 +116,0 @@ url: this.endpoint,

@@ -16,3 +16,3 @@ "use strict";

exports.RestDictionaryService = void 0;
const axios_fetcher_1 = require("../axios-fetcher");
const native_fetcher_1 = require("../native-fetcher");
const data_fetcher_1 = require("../data-fetcher");

@@ -23,3 +23,3 @@ const dictionary_service_1 = require("./dictionary-service");

* Fetch dictionary data using the Sitecore Dictionary Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments DictionaryServiceBase

@@ -33,9 +33,9 @@ */

/**
* Provides default @see AxiosDataFetcher data fetcher
* Provides default @see NativeDataFetcher data fetcher
*/
get defaultFetcher() {
const dataFetcher = new axios_fetcher_1.AxiosDataFetcher({
const dataFetcher = new native_fetcher_1.NativeDataFetcher({
debugger: debug_1.default.dictionary,
// CORS issue: Sitecore provides 'Access-Control-Allow-Origin' as wildcard '*', so we can't include credentials for the dictionary service
withCredentials: false,
credentials: 'omit',
});

@@ -42,0 +42,0 @@ return (url) => dataFetcher.fetch(url);

@@ -31,3 +31,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.constants = exports.NativeDataFetcher = exports.ClientError = exports.MemoryCacheClient = exports.AxiosDataFetcher = exports.GraphQLRequestClient = exports.DefaultRetryStrategy = exports.fetchData = exports.enableDebug = exports.debug = void 0;
exports.constants = exports.NativeDataFetcher = exports.ClientError = exports.MemoryCacheClient = exports.GraphQLRequestClient = exports.DefaultRetryStrategy = exports.ResponseError = exports.fetchData = exports.enableDebug = exports.debug = void 0;
const constants = __importStar(require("./constants"));

@@ -40,7 +40,6 @@ exports.constants = constants;

Object.defineProperty(exports, "fetchData", { enumerable: true, get: function () { return data_fetcher_1.fetchData; } });
Object.defineProperty(exports, "ResponseError", { enumerable: true, get: function () { return data_fetcher_1.ResponseError; } });
var graphql_request_client_1 = require("./graphql-request-client");
Object.defineProperty(exports, "DefaultRetryStrategy", { enumerable: true, get: function () { return graphql_request_client_1.DefaultRetryStrategy; } });
Object.defineProperty(exports, "GraphQLRequestClient", { enumerable: true, get: function () { return graphql_request_client_1.GraphQLRequestClient; } });
var axios_fetcher_1 = require("./axios-fetcher");
Object.defineProperty(exports, "AxiosDataFetcher", { enumerable: true, get: function () { return axios_fetcher_1.AxiosDataFetcher; } });
var cache_client_1 = require("./cache-client");

@@ -47,0 +46,0 @@ Object.defineProperty(exports, "MemoryCacheClient", { enumerable: true, get: function () { return cache_client_1.MemoryCacheClient; } });

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -8,3 +17,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const layout_service_1 = require("./layout-service");
const axios_fetcher_1 = require("../axios-fetcher");
const native_fetcher_1 = require("../native-fetcher");
const data_fetcher_1 = require("../data-fetcher");

@@ -14,3 +23,3 @@ const debug_1 = __importDefault(require("../debug"));

* Fetch layout data using the Sitecore Layout Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments LayoutServiceBase

@@ -42,3 +51,4 @@ */

/**
* Provides default @see AxiosDataFetcher data fetcher
* Returns a fetcher function pre-configured with headers from the incoming request.
* Provides default @see NativeDataFetcher data fetcher
* @param {IncomingMessage} [req] Request instance

@@ -49,14 +59,15 @@ * @param {ServerResponse} [res] Response instance

this.getDefaultFetcher = (req, res) => {
const config = {
debugger: debug_1.default.layout,
};
if (req && res) {
config.onReq = this.setupReqHeaders(req);
config.onRes = this.setupResHeaders(res);
const config = { debugger: debug_1.default.layout };
let headers;
if (req) {
headers = this.setupReqHeaders(req);
}
const axiosFetcher = new axios_fetcher_1.AxiosDataFetcher(config);
const fetcher = (url, data) => {
return axiosFetcher.fetch(url, data);
};
return fetcher;
const nativeFetcher = new native_fetcher_1.NativeDataFetcher(config);
return (url, data) => __awaiter(this, void 0, void 0, function* () {
const response = yield nativeFetcher.fetch(url, Object.assign(Object.assign({}, data), { headers }));
if (res) {
this.setupResHeaders(res, response);
}
return response;
});
};

@@ -74,24 +85,29 @@ }

fetchLayoutData(itemPath, language, req, res) {
const querystringParams = this.getFetchParams(language);
debug_1.default.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
const fetcher = this.getFetcher(req, res);
const fetchUrl = this.resolveLayoutServiceUrl('render');
return (0, data_fetcher_1.fetchData)(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams)).catch((error) => {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
// Aligned with response of GraphQL Layout Service in case if layout is not found.
// When 404 Rest Layout Service returns
// {
// sitecore: {
// context: {
// pageEditing: false,
// language
// },
// route: null
// },
// }
//
return error.response.data;
const querystringParams = this.getFetchParams(language);
debug_1.default.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
const fetcher = this.getFetcher(req, res);
const fetchUrl = this.resolveLayoutServiceUrl('render');
try {
return yield (0, data_fetcher_1.fetchData)(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams));
}
throw error;
catch (error) {
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
// Aligned with response of GraphQL Layout Service in case if layout is not found.
// When 404 Rest Layout Service returns
// {
// sitecore: {
// context: {
// pageEditing: false,
// language
// },
// route: null
// },
// }
//
return error.response.data;
}
throw error;
}
});

@@ -129,12 +145,22 @@ }

/**
* Setup request headers
* @param {IncomingMessage} req Request instance
* @returns {AxiosRequestConfig} axios request config
* Creates an HTTP `Headers` object populated with headers from the incoming request.
* @param {IncomingMessage} [req] - The incoming HTTP request, used to extract headers.
* @returns {Headers} - An instance of the `Headers` object populated with the extracted headers.
*/
setupReqHeaders(req) {
return (reqConfig) => {
debug_1.default.layout('performing request header passing');
reqConfig.headers.common = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, reqConfig.headers.common), (req.headers.cookie && { cookie: req.headers.cookie })), (req.headers.referer && { referer: req.headers.referer })), (req.headers['user-agent'] && { 'user-agent': req.headers['user-agent'] })), (req.connection.remoteAddress && { 'X-Forwarded-For': req.connection.remoteAddress }));
return reqConfig;
};
const headers = new Headers();
if (req === null || req === void 0 ? void 0 : req.headers) {
// Copy all headers from req.headers
Object.entries(req.headers).forEach(([key, value]) => {
if (value) {
headers.set(key, Array.isArray(value) ? value.join(', ') : value);
}
});
// Add or override specific headers
req.headers.cookie && headers.set('cookie', req.headers.cookie);
req.headers.referer && headers.set('referer', req.headers.referer);
req.headers['user-agent'] && headers.set('user-agent', req.headers['user-agent']);
req.socket.remoteAddress && headers.set('X-Forwarded-For', req.socket.remoteAddress);
}
return headers;
}

@@ -144,13 +170,17 @@ /**

* @param {ServerResponse} res Response instance
* @returns {AxiosResponse} response
* @param {NativeDataFetcherResponse<T>} serverRes
* @returns {NativeDataFetcherResponse} response
*/
setupResHeaders(res) {
return (serverRes) => {
debug_1.default.layout('performing response header passing');
serverRes.headers['set-cookie'] &&
res.setHeader('set-cookie', serverRes.headers['set-cookie']);
return serverRes;
};
setupResHeaders(res, serverRes) {
debug_1.default.layout('performing response header passing');
const headers = serverRes.headers;
if (headers instanceof Headers) {
const setCookieHeader = headers.get('set-cookie');
if (setCookieHeader) {
res.setHeader('set-cookie', setCookieHeader);
}
}
return serverRes;
}
}
exports.RestLayoutService = RestLayoutService;

@@ -34,9 +34,9 @@ "use strict";

/**
* Implements a data fetcher. @see HttpDataFetcher<T> type for implementation details/notes.
* @param {string} url The URL to request; may include query string
* @param {unknown} [data] Optional data to POST with the request.
* @returns {Promise<HttpResponse<T>>} response
* Implements a data fetcher.
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Optional fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
fetch(url, data) {
return __awaiter(this, void 0, void 0, function* () {
fetch(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
var _a;

@@ -47,3 +47,3 @@ const _b = this.config, { debugger: debugOverride, fetch: fetchOverride } = _b, init = __rest(_b, ["debugger", "fetch"]);

const debug = debugOverride || debug_1.default.http;
const requestInit = this.getRequestInit(init, data);
const requestInit = this.getRequestInit(Object.assign(Object.assign({}, init), options));
const fetchWithOptionalTimeout = [fetchImpl(url, requestInit)];

@@ -54,54 +54,96 @@ if (init.timeout) {

}
// Note a goal here is to provide consistent debug logging and error handling
// as we do in AxiosDataFetcher and GraphQLRequestClient
const { headers: reqHeaders } = requestInit, rest = __rest(requestInit, ["headers"]);
debug('request: %o', Object.assign({ url, headers: this.extractDebugHeaders(reqHeaders) }, rest));
const response = yield Promise.race(fetchWithOptionalTimeout)
.then((res) => {
var _a;
debug('Request initiated: %o', Object.assign({ url, headers: this.extractDebugHeaders(requestInit.headers) }, requestInit));
try {
const response = yield Promise.race(fetchWithOptionalTimeout).then((res) => {
var _a;
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
return res;
});
const respData = yield this.parseResponse(response, debug);
if (!response.ok) {
const error = this.createError(response, respData);
debug('Response error: %o', error.response);
throw error;
}
debug('Response in %dms: %o', Date.now() - startTimestamp, {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
url: response.url,
data: respData,
});
return Object.assign(Object.assign({}, response), { data: respData });
}
catch (error) {
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
return res;
})
.catch((error) => {
var _a;
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
debug('request error: %o', error);
debug('Request failed: %o', error);
throw error;
});
// Note even an error status may send useful json data in response (which we want for logging)
let respData = undefined;
const isJson = (_a = response.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('application/json');
if (isJson) {
respData = yield response.json().catch((error) => {
debug('response.json() error: %o', error);
});
}
const debugResponse = {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
url: response.url,
redirected: response.redirected,
data: respData,
};
if (!response.ok) {
debug('response error: %o', debugResponse);
throw new Error(`HTTP ${response.status} ${response.statusText}`);
}
debug('response in %dms: %o', Date.now() - startTimestamp, debugResponse);
return Object.assign(Object.assign({}, response), { data: respData });
});
}
/**
* Perform a GET request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
get(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
return this.fetch(url, Object.assign({ method: 'GET' }, options));
});
}
/**
* Perform a POST request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
post(url_1, body_1) {
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
return this.fetch(url, Object.assign({ method: 'POST', body: JSON.stringify(body) }, options));
});
}
/**
* Perform a DELETE request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
delete(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
return this.fetch(url, Object.assign({ method: 'DELETE' }, options));
});
}
/**
* Perform a PUT request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
put(url_1, body_1) {
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
return this.fetch(url, Object.assign({ method: 'PUT', body: JSON.stringify(body) }, options));
});
}
/**
* Perform a HEAD request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
head(url, options = {}) {
return this.fetch(url, Object.assign({ method: 'HEAD' }, options));
}
/**
* Determines settings for the request
* @param {RequestInit} init Custom settings for request
* @param {unknown} [data] Optional data to POST with the request
* @returns {RequestInit} The final request settings
*/
getRequestInit(init = {}, data) {
// This is a focused implementation (GET or POST only using JSON input/output)
// so we are opinionated about method, body, and Content-Type
init.method = data ? 'POST' : 'GET';
init.body = data ? JSON.stringify(data) : undefined;
getRequestInit(init = {}) {
const headers = new Headers(init.headers);
if (!init.method) {
init.method = init.body ? 'POST' : 'GET';
}
headers.set('Content-Type', 'application/json');

@@ -125,3 +167,38 @@ init.headers = headers;

}
/**
* Parses the response data.
* @param {Response} response - The fetch response object.
* @param {Function} debug - The debug logger function.
* @returns {Promise<unknown>} - The parsed response data.
*/
parseResponse(response, debug) {
return __awaiter(this, void 0, void 0, function* () {
const contentType = response.headers.get('Content-Type') || '';
try {
if (contentType.includes('application/json')) {
return yield response.json();
}
return yield response.text();
}
catch (error) {
debug('Response parsing error: %o', error);
return undefined;
}
});
}
/**
* Creates a custom error for fetch failures.
* @param {Response} response - The fetch response object.
* @param {unknown} data - The parsed response data.
* @returns {NativeDataFetcherError} - The constructed error object.
*/
createError(response, data) {
return Object.assign(Object.assign({}, new Error(`HTTP ${response.status} ${response.statusText}`)), { response: {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
data,
} });
}
}
exports.NativeDataFetcher = NativeDataFetcher;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkStatus = checkStatus;
exports.trackEvent = trackEvent;
const utils_1 = require("./../utils");
class ResponseError extends Error {
constructor(message, response) {
super(message);
Object.setPrototypeOf(this, ResponseError.prototype);
this.response = response;
}
}
/**
* @param {HttpResponse<T>} response response from fetch
* @returns {HttpResponse<T>} response
*/
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new ResponseError(response.statusText, response);
throw error;
}
/**
* Note: axios needs to use `withCredentials: true` in order for Sitecore cookies to be included in CORS requests
* Note: fetch api needs to use `credentials: include` in order for Sitecore cookies to be included in CORS requests
* which is necessary for analytics and such

@@ -32,8 +22,10 @@ * @param {string} url url to fetch

*/
function fetchData(url, data, fetcher, params = {}) {
return fetcher((0, utils_1.resolveUrl)(url, params), data)
.then(checkStatus)
.then((response) => {
// axios auto-parses JSON responses, don't need to JSON.parse
return response.data;
function fetchData(url_1, data_1, fetcher_1) {
return __awaiter(this, arguments, void 0, function* (url, data, fetcher, params = {}) {
const requestData = Object.assign(Object.assign({}, (typeof data === 'object' && data !== null ? data : {})), { method: 'POST', headers: Object.assign({ 'Content-Type': 'application/json' }, (typeof data === 'object' && data !== null && 'headers' in data
? data.headers
: {})), body: JSON.stringify(data) });
return fetcher((0, utils_1.resolveUrl)(url, params), requestData).then((response) => {
return response.data;
});
});

@@ -40,0 +32,0 @@ }

@@ -68,7 +68,3 @@ "use strict";

var _a;
return (error.code === '408' ||
error.code === 'ECONNABORTED' ||
error.code === 'ETIMEDOUT' ||
((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 408 ||
error.name === 'AbortError');
return ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 408 || error.name === 'AbortError';
};

@@ -75,0 +71,0 @@ exports.isTimeoutError = isTimeoutError;

@@ -0,1 +1,10 @@

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { resolveUrl } from './utils/utils';

@@ -10,24 +19,11 @@ export class ResponseError extends Error {

/**
* @param {HttpResponse<T>} response the response to check
* @throws {ResponseError} if response code is not ok
*/
export function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new ResponseError(response.statusText, response);
throw error;
}
/**
* @param {string} url the URL to request; may include query string
* @param {HttpDataFetcher} fetcher the fetcher to use to perform the request
* @param {HttpDataFetcher<T> | NativeDataFetcherFunction<T>} fetcher the fetcher to use to perform the request
* @param {ParsedUrlQueryInput} params the query string parameters to send with the request
*/
export function fetchData(url, fetcher, params = {}) {
return fetcher(resolveUrl(url, params))
.then(checkStatus)
.then((response) => {
// axios auto-parses JSON responses, don't need to JSON.parse
export function fetchData(url_1, fetcher_1) {
return __awaiter(this, arguments, void 0, function* (url, fetcher, params = {}) {
const response = yield fetcher(resolveUrl(url, params));
return response.data;
});
}

@@ -106,3 +106,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

// Note we don't have access to raw request/response with graphql-request
// (or nice hooks like we have with Axios), but we should log whatever we have.
// but we should log whatever we have.
this.debug('request: %o', {

@@ -109,0 +109,0 @@ url: this.endpoint,

@@ -10,3 +10,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import { AxiosDataFetcher } from '../axios-fetcher';
import { NativeDataFetcher } from '../native-fetcher';
import { fetchData } from '../data-fetcher';

@@ -17,3 +17,3 @@ import { DictionaryServiceBase } from './dictionary-service';

* Fetch dictionary data using the Sitecore Dictionary Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments DictionaryServiceBase

@@ -27,9 +27,9 @@ */

/**
* Provides default @see AxiosDataFetcher data fetcher
* Provides default @see NativeDataFetcher data fetcher
*/
get defaultFetcher() {
const dataFetcher = new AxiosDataFetcher({
const dataFetcher = new NativeDataFetcher({
debugger: debug.dictionary,
// CORS issue: Sitecore provides 'Access-Control-Allow-Origin' as wildcard '*', so we can't include credentials for the dictionary service
withCredentials: false,
credentials: 'omit',
});

@@ -36,0 +36,0 @@ return (url) => dataFetcher.fetch(url);

@@ -5,8 +5,7 @@ // NOTE: all imports are now named as to not make breaking changes

export { default as debug, enableDebug } from './debug';
export { fetchData } from './data-fetcher';
export { fetchData, ResponseError } from './data-fetcher';
export { DefaultRetryStrategy, GraphQLRequestClient, } from './graphql-request-client';
export { AxiosDataFetcher } from './axios-fetcher';
export { MemoryCacheClient } from './cache-client';
export { ClientError } from 'graphql-request';
export { NativeDataFetcher } from './native-fetcher';
export { NativeDataFetcher, } from './native-fetcher';
export { constants };

@@ -0,3 +1,12 @@

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { LayoutServiceBase } from './layout-service';
import { AxiosDataFetcher } from '../axios-fetcher';
import { NativeDataFetcher, } from '../native-fetcher';
import { fetchData } from '../data-fetcher';

@@ -7,3 +16,3 @@ import debug from '../debug';

* Fetch layout data using the Sitecore Layout Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments LayoutServiceBase

@@ -35,3 +44,4 @@ */

/**
* Provides default @see AxiosDataFetcher data fetcher
* Returns a fetcher function pre-configured with headers from the incoming request.
* Provides default @see NativeDataFetcher data fetcher
* @param {IncomingMessage} [req] Request instance

@@ -42,14 +52,15 @@ * @param {ServerResponse} [res] Response instance

this.getDefaultFetcher = (req, res) => {
const config = {
debugger: debug.layout,
};
if (req && res) {
config.onReq = this.setupReqHeaders(req);
config.onRes = this.setupResHeaders(res);
const config = { debugger: debug.layout };
let headers;
if (req) {
headers = this.setupReqHeaders(req);
}
const axiosFetcher = new AxiosDataFetcher(config);
const fetcher = (url, data) => {
return axiosFetcher.fetch(url, data);
};
return fetcher;
const nativeFetcher = new NativeDataFetcher(config);
return (url, data) => __awaiter(this, void 0, void 0, function* () {
const response = yield nativeFetcher.fetch(url, Object.assign(Object.assign({}, data), { headers }));
if (res) {
this.setupResHeaders(res, response);
}
return response;
});
};

@@ -67,24 +78,29 @@ }

fetchLayoutData(itemPath, language, req, res) {
const querystringParams = this.getFetchParams(language);
debug.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
const fetcher = this.getFetcher(req, res);
const fetchUrl = this.resolveLayoutServiceUrl('render');
return fetchData(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams)).catch((error) => {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
// Aligned with response of GraphQL Layout Service in case if layout is not found.
// When 404 Rest Layout Service returns
// {
// sitecore: {
// context: {
// pageEditing: false,
// language
// },
// route: null
// },
// }
//
return error.response.data;
const querystringParams = this.getFetchParams(language);
debug.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
const fetcher = this.getFetcher(req, res);
const fetchUrl = this.resolveLayoutServiceUrl('render');
try {
return yield fetchData(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams));
}
throw error;
catch (error) {
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
// Aligned with response of GraphQL Layout Service in case if layout is not found.
// When 404 Rest Layout Service returns
// {
// sitecore: {
// context: {
// pageEditing: false,
// language
// },
// route: null
// },
// }
//
return error.response.data;
}
throw error;
}
});

@@ -122,12 +138,22 @@ }

/**
* Setup request headers
* @param {IncomingMessage} req Request instance
* @returns {AxiosRequestConfig} axios request config
* Creates an HTTP `Headers` object populated with headers from the incoming request.
* @param {IncomingMessage} [req] - The incoming HTTP request, used to extract headers.
* @returns {Headers} - An instance of the `Headers` object populated with the extracted headers.
*/
setupReqHeaders(req) {
return (reqConfig) => {
debug.layout('performing request header passing');
reqConfig.headers.common = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, reqConfig.headers.common), (req.headers.cookie && { cookie: req.headers.cookie })), (req.headers.referer && { referer: req.headers.referer })), (req.headers['user-agent'] && { 'user-agent': req.headers['user-agent'] })), (req.connection.remoteAddress && { 'X-Forwarded-For': req.connection.remoteAddress }));
return reqConfig;
};
const headers = new Headers();
if (req === null || req === void 0 ? void 0 : req.headers) {
// Copy all headers from req.headers
Object.entries(req.headers).forEach(([key, value]) => {
if (value) {
headers.set(key, Array.isArray(value) ? value.join(', ') : value);
}
});
// Add or override specific headers
req.headers.cookie && headers.set('cookie', req.headers.cookie);
req.headers.referer && headers.set('referer', req.headers.referer);
req.headers['user-agent'] && headers.set('user-agent', req.headers['user-agent']);
req.socket.remoteAddress && headers.set('X-Forwarded-For', req.socket.remoteAddress);
}
return headers;
}

@@ -137,12 +163,16 @@ /**

* @param {ServerResponse} res Response instance
* @returns {AxiosResponse} response
* @param {NativeDataFetcherResponse<T>} serverRes
* @returns {NativeDataFetcherResponse} response
*/
setupResHeaders(res) {
return (serverRes) => {
debug.layout('performing response header passing');
serverRes.headers['set-cookie'] &&
res.setHeader('set-cookie', serverRes.headers['set-cookie']);
return serverRes;
};
setupResHeaders(res, serverRes) {
debug.layout('performing response header passing');
const headers = serverRes.headers;
if (headers instanceof Headers) {
const setCookieHeader = headers.get('set-cookie');
if (setCookieHeader) {
res.setHeader('set-cookie', setCookieHeader);
}
}
return serverRes;
}
}

@@ -28,9 +28,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

/**
* Implements a data fetcher. @see HttpDataFetcher<T> type for implementation details/notes.
* @param {string} url The URL to request; may include query string
* @param {unknown} [data] Optional data to POST with the request.
* @returns {Promise<HttpResponse<T>>} response
* Implements a data fetcher.
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Optional fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
fetch(url, data) {
return __awaiter(this, void 0, void 0, function* () {
fetch(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
var _a;

@@ -41,3 +41,3 @@ const _b = this.config, { debugger: debugOverride, fetch: fetchOverride } = _b, init = __rest(_b, ["debugger", "fetch"]);

const debug = debugOverride || debuggers.http;
const requestInit = this.getRequestInit(init, data);
const requestInit = this.getRequestInit(Object.assign(Object.assign({}, init), options));
const fetchWithOptionalTimeout = [fetchImpl(url, requestInit)];

@@ -48,54 +48,96 @@ if (init.timeout) {

}
// Note a goal here is to provide consistent debug logging and error handling
// as we do in AxiosDataFetcher and GraphQLRequestClient
const { headers: reqHeaders } = requestInit, rest = __rest(requestInit, ["headers"]);
debug('request: %o', Object.assign({ url, headers: this.extractDebugHeaders(reqHeaders) }, rest));
const response = yield Promise.race(fetchWithOptionalTimeout)
.then((res) => {
var _a;
debug('Request initiated: %o', Object.assign({ url, headers: this.extractDebugHeaders(requestInit.headers) }, requestInit));
try {
const response = yield Promise.race(fetchWithOptionalTimeout).then((res) => {
var _a;
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
return res;
});
const respData = yield this.parseResponse(response, debug);
if (!response.ok) {
const error = this.createError(response, respData);
debug('Response error: %o', error.response);
throw error;
}
debug('Response in %dms: %o', Date.now() - startTimestamp, {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
url: response.url,
data: respData,
});
return Object.assign(Object.assign({}, response), { data: respData });
}
catch (error) {
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
return res;
})
.catch((error) => {
var _a;
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
debug('request error: %o', error);
debug('Request failed: %o', error);
throw error;
});
// Note even an error status may send useful json data in response (which we want for logging)
let respData = undefined;
const isJson = (_a = response.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('application/json');
if (isJson) {
respData = yield response.json().catch((error) => {
debug('response.json() error: %o', error);
});
}
const debugResponse = {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
url: response.url,
redirected: response.redirected,
data: respData,
};
if (!response.ok) {
debug('response error: %o', debugResponse);
throw new Error(`HTTP ${response.status} ${response.statusText}`);
}
debug('response in %dms: %o', Date.now() - startTimestamp, debugResponse);
return Object.assign(Object.assign({}, response), { data: respData });
});
}
/**
* Perform a GET request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
get(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
return this.fetch(url, Object.assign({ method: 'GET' }, options));
});
}
/**
* Perform a POST request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
post(url_1, body_1) {
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
return this.fetch(url, Object.assign({ method: 'POST', body: JSON.stringify(body) }, options));
});
}
/**
* Perform a DELETE request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
delete(url_1) {
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
return this.fetch(url, Object.assign({ method: 'DELETE' }, options));
});
}
/**
* Perform a PUT request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
put(url_1, body_1) {
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
return this.fetch(url, Object.assign({ method: 'PUT', body: JSON.stringify(body) }, options));
});
}
/**
* Perform a HEAD request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
head(url, options = {}) {
return this.fetch(url, Object.assign({ method: 'HEAD' }, options));
}
/**
* Determines settings for the request
* @param {RequestInit} init Custom settings for request
* @param {unknown} [data] Optional data to POST with the request
* @returns {RequestInit} The final request settings
*/
getRequestInit(init = {}, data) {
// This is a focused implementation (GET or POST only using JSON input/output)
// so we are opinionated about method, body, and Content-Type
init.method = data ? 'POST' : 'GET';
init.body = data ? JSON.stringify(data) : undefined;
getRequestInit(init = {}) {
const headers = new Headers(init.headers);
if (!init.method) {
init.method = init.body ? 'POST' : 'GET';
}
headers.set('Content-Type', 'application/json');

@@ -119,2 +161,37 @@ init.headers = headers;

}
/**
* Parses the response data.
* @param {Response} response - The fetch response object.
* @param {Function} debug - The debug logger function.
* @returns {Promise<unknown>} - The parsed response data.
*/
parseResponse(response, debug) {
return __awaiter(this, void 0, void 0, function* () {
const contentType = response.headers.get('Content-Type') || '';
try {
if (contentType.includes('application/json')) {
return yield response.json();
}
return yield response.text();
}
catch (error) {
debug('Response parsing error: %o', error);
return undefined;
}
});
}
/**
* Creates a custom error for fetch failures.
* @param {Response} response - The fetch response object.
* @param {unknown} data - The parsed response data.
* @returns {NativeDataFetcherError} - The constructed error object.
*/
createError(response, data) {
return Object.assign(Object.assign({}, new Error(`HTTP ${response.status} ${response.statusText}`)), { response: {
status: response.status,
statusText: response.statusText,
headers: this.extractDebugHeaders(response.headers),
data,
} });
}
}

@@ -0,22 +1,13 @@

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { isServer, resolveUrl } from './../utils';
class ResponseError extends Error {
constructor(message, response) {
super(message);
Object.setPrototypeOf(this, ResponseError.prototype);
this.response = response;
}
}
/**
* @param {HttpResponse<T>} response response from fetch
* @returns {HttpResponse<T>} response
*/
export function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new ResponseError(response.statusText, response);
throw error;
}
/**
* Note: axios needs to use `withCredentials: true` in order for Sitecore cookies to be included in CORS requests
* Note: fetch api needs to use `credentials: include` in order for Sitecore cookies to be included in CORS requests
* which is necessary for analytics and such

@@ -28,8 +19,10 @@ * @param {string} url url to fetch

*/
function fetchData(url, data, fetcher, params = {}) {
return fetcher(resolveUrl(url, params), data)
.then(checkStatus)
.then((response) => {
// axios auto-parses JSON responses, don't need to JSON.parse
return response.data;
function fetchData(url_1, data_1, fetcher_1) {
return __awaiter(this, arguments, void 0, function* (url, data, fetcher, params = {}) {
const requestData = Object.assign(Object.assign({}, (typeof data === 'object' && data !== null ? data : {})), { method: 'POST', headers: Object.assign({ 'Content-Type': 'application/json' }, (typeof data === 'object' && data !== null && 'headers' in data
? data.headers
: {})), body: JSON.stringify(data) });
return fetcher(resolveUrl(url, params), requestData).then((response) => {
return response.data;
});
});

@@ -36,0 +29,0 @@ }

@@ -60,7 +60,3 @@ import isServer from './is-server';

var _a;
return (error.code === '408' ||
error.code === 'ECONNABORTED' ||
error.code === 'ETIMEDOUT' ||
((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 408 ||
error.name === 'AbortError');
return ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 408 || error.name === 'AbortError';
};

@@ -67,0 +63,0 @@ /**

{
"name": "@sitecore-jss/sitecore-jss",
"version": "22.4.0-canary.9",
"version": "22.4.0-canary.10",
"main": "dist/cjs/index.js",

@@ -50,3 +50,3 @@ "module": "dist/esm/index.js",

"mocha": "^10.2.0",
"nock": "^13.0.5",
"nock": "14.0.0-beta.7",
"nyc": "^15.1.0",

@@ -59,3 +59,2 @@ "sinon": "^17.0.1",

"dependencies": {
"axios": "^0.21.1",
"chalk": "^4.1.0",

@@ -71,3 +70,3 @@ "debug": "^4.3.1",

"types": "types/index.d.ts",
"gitHead": "5d94e2017b872ca4c798162ff0392da0628ce69d",
"gitHead": "1220b71aa4c565d5f8dffde56f362543d6fda3f7",
"files": [

@@ -74,0 +73,0 @@ "dist",

@@ -0,1 +1,2 @@

import { NativeDataFetcherFunction } from './native-fetcher';
import { ParsedUrlQueryInput } from 'querystring';

@@ -16,3 +17,3 @@ /**

* Describes functions that fetch data asynchronously (i.e. from an API endpoint).
* This interface conforms to Axios' public API, but is adaptable to other HTTP libraries and
* This interface conforms to 'fetch' public API, but is adaptable to other HTTP libraries and
* fetch polyfills.

@@ -30,11 +31,6 @@ * The interface implementation must:

/**
* @param {HttpResponse<T>} response the response to check
* @throws {ResponseError} if response code is not ok
*/
export declare function checkStatus<T>(response: HttpResponse<T>): HttpResponse<T>;
/**
* @param {string} url the URL to request; may include query string
* @param {HttpDataFetcher} fetcher the fetcher to use to perform the request
* @param {HttpDataFetcher<T> | NativeDataFetcherFunction<T>} fetcher the fetcher to use to perform the request
* @param {ParsedUrlQueryInput} params the query string parameters to send with the request
*/
export declare function fetchData<T>(url: string, fetcher: HttpDataFetcher<T>, params?: ParsedUrlQueryInput): Promise<T>;
export declare function fetchData<T>(url: string, fetcher: HttpDataFetcher<T> | NativeDataFetcherFunction<T>, params?: ParsedUrlQueryInput): Promise<T>;

@@ -31,3 +31,3 @@ import { HttpDataFetcher } from '../data-fetcher';

* Fetch dictionary data using the Sitecore Dictionary Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments DictionaryServiceBase

@@ -39,3 +39,3 @@ */

/**
* Provides default @see AxiosDataFetcher data fetcher
* Provides default @see NativeDataFetcher data fetcher
*/

@@ -42,0 +42,0 @@ get defaultFetcher(): HttpDataFetcher<RestDictionaryServiceData>;

import * as constants from './constants';
export { default as debug, Debugger, enableDebug } from './debug';
export { HttpDataFetcher, HttpResponse, fetchData } from './data-fetcher';
export { HttpDataFetcher, HttpResponse, fetchData, ResponseError } from './data-fetcher';
export { RetryStrategy, DefaultRetryStrategy, GraphQLClient, GraphQLRequestClient, GraphQLRequestClientConfig, GraphQLRequestClientFactory, GraphQLRequestClientFactoryConfig, } from './graphql-request-client';
export { AxiosDataFetcher, AxiosDataFetcherConfig } from './axios-fetcher';
export { CacheClient, CacheOptions, MemoryCacheClient } from './cache-client';
export { AxiosResponse } from 'axios';
export { ClientError } from 'graphql-request';
export { NativeDataFetcher, NativeDataFetcherConfig } from './native-fetcher';
export { NativeDataFetcher, NativeDataFetcherError, NativeDataFetcherConfig, NativeDataFetcherResponse, } from './native-fetcher';
export { HTMLLink } from './models';
export { constants };

@@ -1,5 +0,5 @@

import { AxiosRequestConfig, AxiosResponse } from 'axios';
import { IncomingMessage, ServerResponse } from 'http';
import { LayoutServiceBase } from './layout-service';
import { PlaceholderData, LayoutServiceData } from './models';
import { NativeDataFetcherFunction, NativeDataFetcherResponse } from '../native-fetcher';
import { HttpDataFetcher } from '../data-fetcher';

@@ -47,6 +47,6 @@ interface FetchParams {

*/
export type DataFetcherResolver = <T>(req?: IncomingMessage, res?: ServerResponse) => HttpDataFetcher<T>;
export type DataFetcherResolver = <T>(req?: IncomingMessage, res?: ServerResponse) => HttpDataFetcher<T> | NativeDataFetcherFunction<T>;
/**
* Fetch layout data using the Sitecore Layout Service REST API.
* Uses Axios as the default data fetcher (@see AxiosDataFetcher).
* Uses NativeDataFetcher as the default data fetcher (@see NativeDataFetcher).
* @augments LayoutServiceBase

@@ -85,3 +85,3 @@ */

protected getFetchParams: (language?: string) => FetchParams;
protected getFetcher: (req?: IncomingMessage, res?: ServerResponse) => HttpDataFetcher<LayoutServiceData>;
protected getFetcher: (req?: IncomingMessage, res?: ServerResponse) => HttpDataFetcher<LayoutServiceData> | NativeDataFetcherFunction<LayoutServiceData>;
/**

@@ -94,3 +94,4 @@ * Resolves layout service url

/**
* Provides default @see AxiosDataFetcher data fetcher
* Returns a fetcher function pre-configured with headers from the incoming request.
* Provides default @see NativeDataFetcher data fetcher
* @param {IncomingMessage} [req] Request instance

@@ -100,16 +101,17 @@ * @param {ServerResponse} [res] Response instance

*/
protected getDefaultFetcher: <T>(req?: IncomingMessage, res?: ServerResponse) => (url: string, data?: unknown) => Promise<AxiosResponse<T>>;
protected getDefaultFetcher: <T>(req?: IncomingMessage, res?: ServerResponse) => (url: string, data?: RequestInit) => Promise<NativeDataFetcherResponse<T>>;
/**
* Setup request headers
* @param {IncomingMessage} req Request instance
* @returns {AxiosRequestConfig} axios request config
* Creates an HTTP `Headers` object populated with headers from the incoming request.
* @param {IncomingMessage} [req] - The incoming HTTP request, used to extract headers.
* @returns {Headers} - An instance of the `Headers` object populated with the extracted headers.
*/
protected setupReqHeaders(req: IncomingMessage): (reqConfig: AxiosRequestConfig) => AxiosRequestConfig;
protected setupReqHeaders(req?: IncomingMessage): Headers;
/**
* Setup response headers based on response from layout service
* @param {ServerResponse} res Response instance
* @returns {AxiosResponse} response
* @param {NativeDataFetcherResponse<T>} serverRes
* @returns {NativeDataFetcherResponse} response
*/
protected setupResHeaders(res: ServerResponse): (serverRes: AxiosResponse) => AxiosResponse<any>;
protected setupResHeaders<T>(res: ServerResponse, serverRes: NativeDataFetcherResponse<T>): NativeDataFetcherResponse<T>;
}
export {};

@@ -1,2 +0,1 @@

import { HttpResponse } from './data-fetcher';
import { Debugger } from './debug';

@@ -17,2 +16,29 @@ type NativeDataFetcherOptions = {

};
/**
* Response data for an HTTP request sent to an API
* @template T the type of data model requested
*/
export interface NativeDataFetcherResponse<T> {
/** HTTP status code of the response (i.e. 200, 404) */
status: number;
/** HTTP status text of the response (i.e. 'OK', 'Bad Request') */
statusText: string;
/** Response content */
data: T;
/** Response headers */
headers?: HeadersInit;
}
/**
* Native fetcher error type to include response text and status
*/
export type NativeDataFetcherError = Error & {
response: NativeDataFetcherResponse<unknown>;
};
/**
* A function that fetches data from a given URL and returns a `NativeDataFetcherResponse`.
* @param {string} url The URL to request (can include query string parameters).
* @param {unknown} [data] Optional data to send with the request (e.g., for POST or PUT requests).
* @returns {Promise<NativeDataFetcherResponse<T>>} A promise that resolves to a `NativeDataFetcherResponse<T>`,
*/
export type NativeDataFetcherFunction<T> = (url: string, data?: RequestInit) => Promise<NativeDataFetcherResponse<T>>;
export type NativeDataFetcherConfig = NativeDataFetcherOptions & RequestInit;

@@ -24,15 +50,51 @@ export declare class NativeDataFetcher {

/**
* Implements a data fetcher. @see HttpDataFetcher<T> type for implementation details/notes.
* @param {string} url The URL to request; may include query string
* @param {unknown} [data] Optional data to POST with the request.
* @returns {Promise<HttpResponse<T>>} response
* Implements a data fetcher.
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Optional fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
fetch<T>(url: string, data?: unknown): Promise<HttpResponse<T>>;
fetch<T>(url: string, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Perform a GET request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
get<T>(url: string, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Perform a POST request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
post<T>(url: string, body: unknown, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Perform a DELETE request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
delete<T>(url: string, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Perform a PUT request
* @param {string} url The URL to request (may include query string)
* @param {unknown} body The data to send with the request
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
put<T>(url: string, body: unknown, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Perform a HEAD request
* @param {string} url The URL to request (may include query string)
* @param {RequestInit} [options] Fetch options
* @returns {Promise<NativeDataFetcherResponse<T>>} response
*/
head<T>(url: string, options?: RequestInit): Promise<NativeDataFetcherResponse<T>>;
/**
* Determines settings for the request
* @param {RequestInit} init Custom settings for request
* @param {unknown} [data] Optional data to POST with the request
* @returns {RequestInit} The final request settings
*/
protected getRequestInit(init?: RequestInit, data?: unknown): RequestInit;
protected getRequestInit(init?: RequestInit): RequestInit;
/**

@@ -46,3 +108,17 @@ * Safely extract all headers for debug logging

};
/**
* Parses the response data.
* @param {Response} response - The fetch response object.
* @param {Function} debug - The debug logger function.
* @returns {Promise<unknown>} - The parsed response data.
*/
private parseResponse;
/**
* Creates a custom error for fetch failures.
* @param {Response} response - The fetch response object.
* @param {unknown} data - The parsed response data.
* @returns {NativeDataFetcherError} - The constructed error object.
*/
private createError;
}
export {};
import { CampaignInstance, EventInstance, GoalInstance, OutcomeInstance, PageViewInstance } from './dataModels';
import { TrackingRequestOptions } from './trackingRequestOptions';
import { HttpResponse } from './../data-fetcher';
/**
* @param {HttpResponse<T>} response response from fetch
* @returns {HttpResponse<T>} response
*/
export declare function checkStatus<T>(response: HttpResponse<T>): HttpResponse<T>;
/**
* Makes a request to Sitecore Layout Service for the specified route item path.

@@ -11,0 +5,0 @@ * @param {Array<EventInstance | GoalInstance | OutcomeInstance | CampaignInstance | PageViewInstance>} events events to send

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc