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

mock-config-server

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mock-config-server - npm Package Compare versions

Comparing version 3.2.0 to 3.3.0

dist/bin/validateMockServerConfig/validateQueue/validateQueue.d.ts

3

dist/bin/validateMockServerConfig/helpers/isDescriptorValueValid/isDescriptorValueValid.d.ts

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

export declare const isDescriptorValueValid: (checkMode: unknown, value: unknown, entityName?: unknown) => boolean;
import type { CheckMode } from '../../../../src/utils/types';
export declare const isDescriptorValueValid: (checkMode: CheckMode, value: unknown) => boolean | undefined;

@@ -8,14 +8,37 @@ "use strict";

var _constants = require("../../../../src/utils/constants");
const isDescriptorValueValid = (checkMode, value, entityName) => {
if (_constants.CHECK_ACTUAL_VALUE_CHECK_MODES.includes(checkMode)) return typeof value === 'undefined';
if (_constants.COMPARE_WITH_DESCRIPTOR_VALUE_CHECK_MODES.includes(checkMode)) {
if (entityName === 'body' || entityName === 'variables') {
return typeof value === 'object' && value !== null && typeof value !== 'function' && !(value instanceof RegExp);
var _helpers = require("../../../../src/utils/helpers");
// ✅ important:
// should validate all properties over nesting
const isObjectOrArrayValid = value => {
if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string' || value === null) {
return true;
}
if (Array.isArray(value)) {
return value.every(isObjectOrArrayValid);
}
if ((0, _helpers.isPlainObject)(value)) {
for (const key in value) {
if (!isObjectOrArrayValid(value[key])) {
return false;
}
}
return true;
}
return false;
};
const isDescriptorValueValid = (checkMode, value) => {
if (_constants.CHECK_ACTUAL_VALUE_CHECK_MODES.includes(checkMode)) {
return typeof value === 'undefined';
}
if (_constants.COMPARE_WITH_DESCRIPTOR_ANY_VALUE_CHECK_MODES.includes(checkMode)) {
const isValueObjectOrArray = (0, _helpers.isPlainObject)(value) || Array.isArray(value);
if (isValueObjectOrArray) return isObjectOrArrayValid(value);
return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string' || value === null;
}
if (_constants.COMPARE_WITH_DESCRIPTOR_STRING_VALUE_CHECK_MODES.includes(checkMode)) {
return typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string';
}
if (checkMode === 'function') return typeof value === 'function';
if (checkMode === 'function') return typeof value === 'function' && value.length <= 2;
if (checkMode === 'regExp') return value instanceof RegExp;
throw new Error('Invalid checkMode');
};
exports.isDescriptorValueValid = isDescriptorValueValid;

@@ -17,11 +17,17 @@ "use strict";

operationType,
operationName
operationName,
query
} = config;
if (typeof operationName === 'undefined' && typeof query === 'undefined') {
throw new Error(`configs[${index}]`);
}
if (operationType !== 'query' && operationType !== 'mutation') {
throw new Error(`configs[${index}].operationType`);
}
const isOperationNameStringOrRegExp = typeof operationName === 'string' || operationName instanceof RegExp;
if (!isOperationNameStringOrRegExp) {
if (typeof operationName !== 'undefined' && typeof operationName !== 'string' && !(operationName instanceof RegExp)) {
throw new Error(`configs[${index}].operationName`);
}
if (typeof query !== 'undefined' && typeof query !== 'string') {
throw new Error(`configs[${index}].query`);
}
try {

@@ -28,0 +34,0 @@ (0, _validateRoutes.validateRoutes)(config.routes, operationType);

@@ -10,2 +10,4 @@ "use strict";

var _validateInterceptors = require("../../validateInterceptors/validateInterceptors");
var _validateQueue = require("../../validateQueue/validateQueue");
var _validateSettings = require("../../validateSettings/validateSettings");
const ALLOWED_ENTITIES_BY_OPERATION_TYPE = {

@@ -16,21 +18,33 @@ query: ['headers', 'cookies', 'query', 'variables'],

const validateEntity = (entity, entityName) => {
const {
checkMode: topLevelCheckMode,
value: topLevelValue
} = (0, _helpers.convertToEntityDescriptor)(entity);
const isVariables = entityName === 'variables';
const isTopLevelDescriptor = (0, _helpers.isEntityDescriptor)(entity);
if (isTopLevelDescriptor && isVariables) {
if (!(0, _helpers2.isCheckModeValid)(topLevelCheckMode, 'variables')) {
const isEntityTopLevelDescriptor = (0, _helpers.isEntityDescriptor)(entity);
if (isEntityTopLevelDescriptor) {
if (!isVariables) {
throw new Error(entityName);
}
if (!(0, _helpers2.isCheckModeValid)(entity.checkMode, 'variables')) {
throw new Error('variables.checkMode');
}
if (!(0, _helpers2.isDescriptorValueValid)(topLevelCheckMode, topLevelValue, 'variables')) {
const errorMessage = 'variables.value';
throw new Error(errorMessage);
const isDescriptorValueObjectOrArray = (0, _helpers.isPlainObject)(entity.value) || Array.isArray(entity.value);
if (!isDescriptorValueObjectOrArray || !(0, _helpers2.isDescriptorValueValid)(entity.checkMode, entity.value)) {
throw new Error('variables.value');
}
return;
}
const isEntityObject = (0, _helpers.isPlainObject)(entity) && !(entity instanceof RegExp);
const isEntityArray = Array.isArray(entity) && isVariables;
if (isEntityObject || isEntityArray) {
Object.entries(topLevelValue).forEach(([key, valueOrDescriptor]) => {
const isEntityArray = Array.isArray(entity);
if (isEntityArray) {
if (!isVariables) {
throw new Error(entityName);
}
entity.forEach((entityElement, index) => {
const isEntityElementObjectOrArray = (0, _helpers.isPlainObject)(entityElement) || Array.isArray(entityElement);
if (!isEntityElementObjectOrArray || !(0, _helpers2.isDescriptorValueValid)('equals', entityElement)) {
throw new Error(`${entityName}[${index}]`);
}
});
return;
}
const isEntityObject = (0, _helpers.isPlainObject)(entity);
if (isEntityObject) {
Object.entries(entity).forEach(([key, valueOrDescriptor]) => {
const {

@@ -46,13 +60,23 @@ checkMode,

const isValueArray = Array.isArray(value);
if (isValueArray && !isVariables) {
if (isValueArray) {
value.forEach((element, index) => {
if (!(0, _helpers2.isDescriptorValueValid)(checkMode, element)) {
if (isVariables) {
if ((0, _helpers2.isDescriptorValueValid)(checkMode, element)) return;
throw new Error(`${errorMessage}[${index}]`);
}
const isElementObjectOrArray = (0, _helpers.isPlainObject)(element) || Array.isArray(element);
if (isElementObjectOrArray || !(0, _helpers2.isDescriptorValueValid)(checkMode, element)) {
throw new Error(`${errorMessage}[${index}]`);
}
});
return;
}
if (!(0, _helpers2.isDescriptorValueValid)(checkMode, value)) {
if (isVariables) {
if ((0, _helpers2.isDescriptorValueValid)(checkMode, value)) return;
throw new Error(errorMessage);
}
const isValueObject = (0, _helpers.isPlainObject)(value);
if (isValueObject || !(0, _helpers2.isDescriptorValueValid)(checkMode, value)) {
throw new Error(errorMessage);
}
});

@@ -90,6 +114,31 @@ return;

const isRouteHasDataProperty = ('data' in route);
if (!isRouteHasDataProperty) {
const isRouteHasQueueProperty = ('queue' in route);
if (!isRouteHasDataProperty && !isRouteHasQueueProperty) {
throw new Error(`routes[${index}]`);
}
if (isRouteHasDataProperty && isRouteHasQueueProperty) {
throw new Error(`routes[${index}]`);
}
const {
settings
} = route;
const isRouteSettingsObject = (0, _helpers.isPlainObject)(settings);
if (isRouteHasQueueProperty) {
try {
(0, _validateQueue.validateQueue)(route.queue);
if (!isRouteSettingsObject) {
throw new Error('settings');
}
if (!(isRouteSettingsObject && settings !== null && settings !== void 0 && settings.polling)) {
throw new Error('settings.polling');
}
} catch (error) {
throw new Error(`routes[${index}].${error.message}`);
}
}
if (isRouteHasDataProperty && isRouteSettingsObject && settings !== null && settings !== void 0 && settings.polling) {
throw new Error(`routes[${index}].settings.polling`);
}
try {
(0, _validateSettings.validateSettings)(route.settings);
validateEntities(route.entities, operationType);

@@ -96,0 +145,0 @@ (0, _validateInterceptors.validateInterceptors)(route.interceptors);

@@ -10,2 +10,4 @@ "use strict";

var _validateInterceptors = require("../../validateInterceptors/validateInterceptors");
var _validateQueue = require("../../validateQueue/validateQueue");
var _validateSettings = require("../../validateSettings/validateSettings");
const ALLOWED_ENTITIES_BY_METHOD = {

@@ -20,21 +22,33 @@ get: ['headers', 'cookies', 'query', 'params'],

const validateEntity = (entity, entityName) => {
const {
checkMode: topLevelCheckMode,
value: topLevelValue
} = (0, _helpers.convertToEntityDescriptor)(entity);
const isBody = entityName === 'body';
const isTopLevelDescriptor = (0, _helpers.isEntityDescriptor)(entity);
if (isTopLevelDescriptor && isBody) {
if (!(0, _helpers2.isCheckModeValid)(topLevelCheckMode, 'body')) {
const isEntityTopLevelDescriptor = (0, _helpers.isEntityDescriptor)(entity);
if (isEntityTopLevelDescriptor) {
if (!isBody) {
throw new Error(entityName);
}
if (!(0, _helpers2.isCheckModeValid)(entity.checkMode, 'body')) {
throw new Error('body.checkMode');
}
if (!(0, _helpers2.isDescriptorValueValid)(topLevelCheckMode, topLevelValue, 'body')) {
const errorMessage = 'body.value';
throw new Error(errorMessage);
const isDescriptorValueObjectOrArray = (0, _helpers.isPlainObject)(entity.value) || Array.isArray(entity.value);
if (!isDescriptorValueObjectOrArray || !(0, _helpers2.isDescriptorValueValid)(entity.checkMode, entity.value)) {
throw new Error('body.value');
}
return;
}
const isEntityObject = (0, _helpers.isPlainObject)(entity) && !(entity instanceof RegExp);
const isEntityArray = Array.isArray(entity) && isBody;
if (isEntityObject || isEntityArray) {
Object.entries(topLevelValue).forEach(([key, valueOrDescriptor]) => {
const isEntityArray = Array.isArray(entity);
if (isEntityArray) {
if (!isBody) {
throw new Error(entityName);
}
entity.forEach((entityElement, index) => {
const isEntityElementObjectOrArray = (0, _helpers.isPlainObject)(entityElement) || Array.isArray(entityElement);
if (!isEntityElementObjectOrArray || !(0, _helpers2.isDescriptorValueValid)('equals', entityElement)) {
throw new Error(`${entityName}[${index}]`);
}
});
return;
}
const isEntityObject = (0, _helpers.isPlainObject)(entity);
if (isEntityObject) {
Object.entries(entity).forEach(([key, valueOrDescriptor]) => {
const {

@@ -50,13 +64,23 @@ checkMode,

const isValueArray = Array.isArray(value);
if (isValueArray && !isBody) {
if (isValueArray) {
value.forEach((element, index) => {
if (!(0, _helpers2.isDescriptorValueValid)(checkMode, element)) {
if (isBody) {
if ((0, _helpers2.isDescriptorValueValid)(checkMode, element)) return;
throw new Error(`${errorMessage}[${index}]`);
}
const isElementObjectOrArray = (0, _helpers.isPlainObject)(element) || Array.isArray(element);
if (isElementObjectOrArray || !(0, _helpers2.isDescriptorValueValid)(checkMode, element)) {
throw new Error(`${errorMessage}[${index}]`);
}
});
return;
}
if (!(0, _helpers2.isDescriptorValueValid)(checkMode, value)) {
if (isBody) {
if ((0, _helpers2.isDescriptorValueValid)(checkMode, value)) return;
throw new Error(errorMessage);
}
const isValueObject = (0, _helpers.isPlainObject)(value);
if (isValueObject || !(0, _helpers2.isDescriptorValueValid)(checkMode, value)) {
throw new Error(errorMessage);
}
});

@@ -94,6 +118,31 @@ return;

const isRouteHasDataProperty = ('data' in route);
if (!isRouteHasDataProperty) {
const isRouteHasQueueProperty = ('queue' in route);
if (!isRouteHasDataProperty && !isRouteHasQueueProperty) {
throw new Error(`routes[${index}]`);
}
if (isRouteHasDataProperty && isRouteHasQueueProperty) {
throw new Error(`routes[${index}]`);
}
const {
settings
} = route;
const isRouteSettingsObject = (0, _helpers.isPlainObject)(settings);
if (isRouteHasQueueProperty) {
try {
(0, _validateQueue.validateQueue)(route.queue);
if (!isRouteSettingsObject) {
throw new Error('settings');
}
if (!(isRouteSettingsObject && settings !== null && settings !== void 0 && settings.polling)) {
throw new Error('settings.polling');
}
} catch (error) {
throw new Error(`routes[${index}].${error.message}`);
}
}
if (isRouteHasDataProperty && isRouteSettingsObject && settings !== null && settings !== void 0 && settings.polling) {
throw new Error(`routes[${index}].settings.polling`);
}
try {
(0, _validateSettings.validateSettings)(route.settings);
validateEntities(route.entities, method);

@@ -100,0 +149,0 @@ (0, _validateInterceptors.validateInterceptors)(route.interceptors);

@@ -9,2 +9,4 @@ "use strict";

var _filter = require("../filter/filter");
var _pagination = require("../pagination/pagination");
var _sort2 = require("../sort/sort");
const createNestedDatabaseRoutes = (router, database, storage) => {

@@ -15,7 +17,48 @@ Object.keys(database).forEach(key => {

router.route(collectionPath).get((request, response) => {
var _request$query;
let data = storage.read(key);
if (request.query && Object.keys(request.query).length) {
data = (0, _filter.filter)(data, request.query);
const {
_page,
_limit,
_begin,
_end,
_sort,
_order,
...filters
} = request.query;
data = (0, _filter.filter)(data, filters);
}
if ((_request$query = request.query) !== null && _request$query !== void 0 && _request$query._page) {
data = (0, _pagination.pagination)(data, request.query);
if (data._link) {
const links = {};
const fullUrl = `${request.protocol}://${request.get('host')}${request.originalUrl}`;
if (data._link.first) {
links.first = fullUrl.replace(`page=${data._link.current}`, `page=${data._link.first}`);
}
if (data._link.prev) {
links.prev = fullUrl.replace(`page=${data._link.current}`, `page=${data._link.prev}`);
}
if (data._link.next) {
links.next = fullUrl.replace(`page=${data._link.current}`, `page=${data._link.next}`);
}
if (data._link.last) {
links.last = fullUrl.replace(`page=${data._link.current}`, `page=${data._link.last}`);
}
data._link = {
...data._link,
...links
};
response.links(links);
}
}
if (request.query && request.query._sort) {
data = (0, _sort2.sort)(data, request.query);
}
if (request.query._begin || request.query._end) {
var _request$query$_begin;
data = data.slice((_request$query$_begin = request.query._begin) !== null && _request$query$_begin !== void 0 ? _request$query$_begin : 0, request.query._end);
response.set('X-Total-Count', data.length);
}
// ✅ important:

@@ -22,0 +65,0 @@ // set 'Cache-Control' header for explicit browsers response revalidate

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

export declare const filter: (array: any[], filters: Record<string, string | string[]>) => any[];
import type { ParsedUrlQuery } from 'node:querystring';
export declare const filter: (array: any[], filters: ParsedUrlQuery) => any[];
import type { IRouter } from 'express';
import type { GraphqlConfig, Interceptors } from '../../../utils/types';
export declare const createGraphQLRoutes: (router: IRouter, graphqlConfig: GraphqlConfig, serverResponseInterceptors?: Interceptors['response']) => IRouter;
interface CreateGraphQLRoutesParams {
router: IRouter;
graphqlConfig: GraphqlConfig;
serverResponseInterceptor?: Interceptors['response'];
}
export declare const createGraphQLRoutes: ({ router, graphqlConfig, serverResponseInterceptor }: CreateGraphQLRoutesParams) => IRouter;
export {};

@@ -10,8 +10,12 @@ "use strict";

var _helpers2 = require("./helpers");
const createGraphQLRoutes = (router, graphqlConfig, serverResponseInterceptors) => {
const createGraphQLRoutes = ({
router,
graphqlConfig,
serverResponseInterceptor
}) => {
const preparedGraphQLRequestConfig = (0, _helpers2.prepareGraphQLRequestConfigs)(graphqlConfig.configs);
const graphqlMiddleware = async (request, response, next) => {
var _matchedRequestConfig, _matchedRouteConfig$e, _matchedRouteConfig$i, _matchedRequestConfig2, _graphqlConfig$interc;
var _matchedRequestConfig, _matchedRouteConfig$s, _matchedRouteConfig$e, _matchedRouteConfig$i, _matchedRequestConfig2, _graphqlConfig$interc;
const graphQLInput = (0, _helpers.getGraphQLInput)(request);
if (!graphQLInput || !graphQLInput.query) {
if (!graphQLInput.query) {
return response.status(400).json({

@@ -27,12 +31,12 @@ message: 'Query is missing, you must pass a valid GraphQL query'

}
if (!query.operationName || !query.operationType) {
return response.status(400).json({
message: `You should to specify operationName and operationType for ${request.method}:${request.baseUrl}${request.path}`
});
}
const matchedRequestConfig = preparedGraphQLRequestConfig.find(requestConfig => {
if (requestConfig.operationName instanceof RegExp) {
return new RegExp(requestConfig.operationName).test(query.operationName) && requestConfig.operationType === query.operationType;
var _graphQLInput$query;
if (requestConfig.operationType !== query.operationType) return false;
if ('query' in requestConfig && requestConfig.query.replace(/\s+/gi, ' ') !== ((_graphQLInput$query = graphQLInput.query) === null || _graphQLInput$query === void 0 ? void 0 : _graphQLInput$query.replace(/\s+/gi, ' '))) return false;
if ('operationName' in requestConfig) {
if (!query.operationName) return false;
if (requestConfig.operationName instanceof RegExp) return new RegExp(requestConfig.operationName).test(query.operationName);
return requestConfig.operationName === query.operationName;
}
return requestConfig.operationName === query.operationName && requestConfig.operationType === query.operationType;
return true;
});

@@ -54,21 +58,25 @@ if (!matchedRequestConfig) {

const entries = Object.entries(entities);
return entries.every(([entityName, valueOrDescriptor]) => {
return entries.every(([entityName, entityDescriptorOrValue]) => {
const {
checkMode,
value: descriptorValue
} = (0, _helpers.convertToEntityDescriptor)(valueOrDescriptor);
value: entityDescriptorValue
} = (0, _helpers.convertToEntityDescriptor)(entityDescriptorOrValue);
// ✅ important: check whole variables as plain value strictly if descriptor used for variables
const isVariablesPlain = entityName === 'variables' && (0, _helpers.isEntityDescriptor)(valueOrDescriptor);
if (isVariablesPlain) {
// ✅ important: getGraphQLInput returns empty object if variables not sent or invalid, so count {} as undefined
return (0, _helpers.resolveEntityValues)(checkMode, Object.keys(graphQLInput.variables).length ? graphQLInput.variables : undefined, descriptorValue);
const isEntityVariablesByTopLevelDescriptor = entityName === 'variables' && (0, _helpers.isEntityDescriptor)(entityDescriptorOrValue);
if (isEntityVariablesByTopLevelDescriptor) {
return (0, _helpers.resolveEntityValues)(checkMode, graphQLInput.variables, entityDescriptorValue);
}
const mappedEntityDescriptors = Object.entries(valueOrDescriptor);
return mappedEntityDescriptors.every(([entityKey, mappedEntityDescriptor]) => {
const isEntityVariablesByTopLevelArray = entityName === 'variables' && Array.isArray(entityDescriptorOrValue);
if (isEntityVariablesByTopLevelArray) {
return entityDescriptorOrValue.some(entityDescriptorOrValueElement => (0, _helpers.resolveEntityValues)(checkMode, graphQLInput.variables, entityDescriptorOrValueElement));
}
const recordOrArrayEntries = Object.entries(entityDescriptorOrValue);
return recordOrArrayEntries.every(([entityKey, entityValue]) => {
const {
checkMode,
value: descriptorValue
} = (0, _helpers.convertToEntityDescriptor)(mappedEntityDescriptor);
} = (0, _helpers.convertToEntityDescriptor)(entityValue);
const flattenEntity = (0, _flat.flatten)(entityName === 'variables' ? graphQLInput.variables : request[entityName]);
// ✅ important: transform header keys to lower case because browsers send headers in lowercase

@@ -82,5 +90,38 @@ return (0, _helpers.resolveEntityValues)(checkMode, flattenEntity[entityName === 'headers' ? entityKey.toLowerCase() : entityKey], descriptorValue);

}
const matchedRouteConfigData = typeof matchedRouteConfig.data === 'function' ? await matchedRouteConfig.data(request, (_matchedRouteConfig$e = matchedRouteConfig.entities) !== null && _matchedRouteConfig$e !== void 0 ? _matchedRouteConfig$e : {}) : matchedRouteConfig.data;
let matchedRouteConfigData = null;
if ((_matchedRouteConfig$s = matchedRouteConfig.settings) !== null && _matchedRouteConfig$s !== void 0 && _matchedRouteConfig$s.polling && 'queue' in matchedRouteConfig) {
var _shallowMatchedRouteC;
if (!matchedRouteConfig.queue.length) return next();
const shallowMatchedRouteConfig = matchedRouteConfig;
let index = (_shallowMatchedRouteC = shallowMatchedRouteConfig.__pollingIndex) !== null && _shallowMatchedRouteC !== void 0 ? _shallowMatchedRouteC : 0;
const {
time,
data
} = matchedRouteConfig.queue[index];
const updateIndex = () => {
if (matchedRouteConfig.queue.length - 1 === index) {
index = 0;
} else {
index += 1;
}
shallowMatchedRouteConfig.__pollingIndex = index;
};
if (time && !shallowMatchedRouteConfig.__timeoutInProgress) {
shallowMatchedRouteConfig.__timeoutInProgress = true;
setTimeout(() => {
shallowMatchedRouteConfig.__timeoutInProgress = false;
updateIndex();
}, time);
}
if (!time && !shallowMatchedRouteConfig.__timeoutInProgress) {
updateIndex();
}
matchedRouteConfigData = data;
}
if ('data' in matchedRouteConfig) {
matchedRouteConfigData = matchedRouteConfig.data;
}
const resolvedData = typeof matchedRouteConfigData === 'function' ? await matchedRouteConfigData(request, (_matchedRouteConfig$e = matchedRouteConfig.entities) !== null && _matchedRouteConfig$e !== void 0 ? _matchedRouteConfig$e : {}) : matchedRouteConfigData;
const data = await (0, _helpers.callResponseInterceptors)({
data: matchedRouteConfigData,
data: resolvedData,
request,

@@ -92,3 +133,3 @@ response,

apiInterceptor: (_graphqlConfig$interc = graphqlConfig.interceptors) === null || _graphqlConfig$interc === void 0 ? void 0 : _graphqlConfig$interc.response,
serverInterceptor: serverResponseInterceptors
serverInterceptor: serverResponseInterceptor
}

@@ -95,0 +136,0 @@ });

@@ -25,5 +25,3 @@ "use strict";

})) !== null && _rest$configs$filter$ !== void 0 ? _rest$configs$filter$ : [];
const graphqlRequestConfigs = (_graphql$configs$filt = graphql === null || graphql === void 0 ? void 0 : graphql.configs.filter(({
operationName
}) => !(operationName instanceof RegExp)).map(request => {
const graphqlRequestConfigs = (_graphql$configs$filt = graphql === null || graphql === void 0 ? void 0 : graphql.configs.filter(request => 'operationName' in request && !(request.operationName instanceof RegExp)).map(request => {
var _graphql$baseUrl;

@@ -30,0 +28,0 @@ return {

import type { Express } from 'express';
import type { RequestInterceptor } from '../../../utils/types';
export declare const requestInterceptorMiddleware: (server: Express, interceptor: RequestInterceptor) => void;
interface RequestInterceptorMiddlewareParams {
server: Express;
path?: string;
interceptor: RequestInterceptor;
}
export declare const requestInterceptorMiddleware: ({ server, path, interceptor }: RequestInterceptorMiddlewareParams) => void;
export {};

@@ -8,4 +8,8 @@ "use strict";

var _helpers = require("../../../utils/helpers");
const requestInterceptorMiddleware = (server, interceptor) => {
server.use((0, _helpers.asyncHandler)(async (request, _response, next) => {
const requestInterceptorMiddleware = ({
server,
path = '*',
interceptor
}) => {
server.use(path, (0, _helpers.asyncHandler)(async (request, _response, next) => {
await (0, _helpers.callRequestInterceptor)({

@@ -12,0 +16,0 @@ request,

import type { IRouter } from 'express';
import type { Interceptors, RestConfig } from '../../../utils/types';
export declare const createRestRoutes: (router: IRouter, restConfig: RestConfig, serverResponseInterceptors?: Interceptors['response']) => IRouter;
interface CreateRestRoutesParams {
router: IRouter;
restConfig: RestConfig;
serverResponseInterceptor?: Interceptors['response'];
}
export declare const createRestRoutes: ({ router, restConfig, serverResponseInterceptor }: CreateRestRoutesParams) => IRouter;
export {};

@@ -10,6 +10,10 @@ "use strict";

var _helpers2 = require("./helpers");
const createRestRoutes = (router, restConfig, serverResponseInterceptors) => {
const createRestRoutes = ({
router,
restConfig,
serverResponseInterceptor
}) => {
(0, _helpers2.prepareRestRequestConfigs)(restConfig.configs).forEach(requestConfig => {
router.route(requestConfig.path)[requestConfig.method]((0, _helpers.asyncHandler)(async (request, response, next) => {
var _requestConfig$interc, _matchedRouteConfig$e, _matchedRouteConfig$i, _requestConfig$interc2, _restConfig$intercept;
var _requestConfig$interc, _matchedRouteConfig$s, _matchedRouteConfig$e, _matchedRouteConfig$i, _requestConfig$interc2, _restConfig$intercept;
const requestInterceptor = (_requestConfig$interc = requestConfig.interceptors) === null || _requestConfig$interc === void 0 ? void 0 : _requestConfig$interc.request;

@@ -27,16 +31,22 @@ if (requestInterceptor) {

const entries = Object.entries(entities);
return entries.every(([entityName, valueOrDescriptor]) => {
return entries.every(([entityName, entityDescriptorOrValue]) => {
const {
checkMode,
value: descriptorValue
} = (0, _helpers.convertToEntityDescriptor)(valueOrDescriptor);
} = (0, _helpers.convertToEntityDescriptor)(entityDescriptorOrValue);
// ✅ important: check whole body as plain value strictly if descriptor used for body
const isBodyPlain = entityName === 'body' && (0, _helpers.isEntityDescriptor)(valueOrDescriptor);
if (isBodyPlain) {
// ✅ important: bodyParser sets body to empty object if body not sent or invalid, so count {} as undefined
const isEntityBodyByTopLevelDescriptor = entityName === 'body' && (0, _helpers.isEntityDescriptor)(entityDescriptorOrValue);
if (isEntityBodyByTopLevelDescriptor) {
// ✅ important: bodyParser sets body to empty object if body not sent or invalid, so assume {} as undefined
return (0, _helpers.resolveEntityValues)(checkMode, Object.keys(request.body).length ? request.body : undefined, descriptorValue);
}
const mappedEntityDescriptors = Object.entries(valueOrDescriptor);
return mappedEntityDescriptors.every(([entityKey, mappedEntityDescriptor]) => {
const isEntityBodyByTopLevelArray = entityName === 'body' && Array.isArray(entityDescriptorOrValue);
if (isEntityBodyByTopLevelArray) {
return entityDescriptorOrValue.some(entityDescriptorOrValueElement =>
// ✅ important: bodyParser sets body to empty object if body not sent or invalid, so assume {} as undefined
(0, _helpers.resolveEntityValues)(checkMode, Object.keys(request.body).length ? request.body : undefined, entityDescriptorOrValueElement));
}
const recordOrArrayEntries = Object.entries(entityDescriptorOrValue);
return recordOrArrayEntries.every(([entityKey, mappedEntityDescriptor]) => {
const {

@@ -55,5 +65,38 @@ checkMode,

}
const matchedRouteConfigData = typeof matchedRouteConfig.data === 'function' ? await matchedRouteConfig.data(request, (_matchedRouteConfig$e = matchedRouteConfig.entities) !== null && _matchedRouteConfig$e !== void 0 ? _matchedRouteConfig$e : {}) : matchedRouteConfig.data;
let matchedRouteConfigData = null;
if ((_matchedRouteConfig$s = matchedRouteConfig.settings) !== null && _matchedRouteConfig$s !== void 0 && _matchedRouteConfig$s.polling && 'queue' in matchedRouteConfig) {
var _shallowMatchedRouteC;
if (!matchedRouteConfig.queue.length) return next();
const shallowMatchedRouteConfig = matchedRouteConfig;
let index = (_shallowMatchedRouteC = shallowMatchedRouteConfig.__pollingIndex) !== null && _shallowMatchedRouteC !== void 0 ? _shallowMatchedRouteC : 0;
const {
time,
data
} = matchedRouteConfig.queue[index];
const updateIndex = () => {
if (matchedRouteConfig.queue.length - 1 === index) {
index = 0;
} else {
index += 1;
}
shallowMatchedRouteConfig.__pollingIndex = index;
};
if (time && !shallowMatchedRouteConfig.__timeoutInProgress) {
shallowMatchedRouteConfig.__timeoutInProgress = true;
setTimeout(() => {
shallowMatchedRouteConfig.__timeoutInProgress = false;
updateIndex();
}, time);
}
if (!time && !shallowMatchedRouteConfig.__timeoutInProgress) {
updateIndex();
}
matchedRouteConfigData = data;
}
if ('data' in matchedRouteConfig) {
matchedRouteConfigData = matchedRouteConfig.data;
}
const resolvedData = typeof matchedRouteConfigData === 'function' ? await matchedRouteConfigData(request, (_matchedRouteConfig$e = matchedRouteConfig.entities) !== null && _matchedRouteConfig$e !== void 0 ? _matchedRouteConfig$e : {}) : matchedRouteConfigData;
const data = await (0, _helpers.callResponseInterceptors)({
data: matchedRouteConfigData,
data: resolvedData,
request,

@@ -65,3 +108,3 @@ response,

apiInterceptor: (_restConfig$intercept = restConfig.interceptors) === null || _restConfig$intercept === void 0 ? void 0 : _restConfig$intercept.response,
serverInterceptor: serverResponseInterceptors
serverInterceptor: serverResponseInterceptor
}

@@ -68,0 +111,0 @@ });

@@ -35,3 +35,6 @@ "use strict";

if (serverRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, serverRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
interceptor: serverRequestInterceptor
});
}

@@ -38,0 +41,0 @@ const baseUrl = (_databaseMockServerCo2 = databaseMockServerConfig.baseUrl) !== null && _databaseMockServerCo2 !== void 0 ? _databaseMockServerCo2 : '/';

@@ -37,3 +37,6 @@ "use strict";

if (serverRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, serverRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
interceptor: serverRequestInterceptor
});
}

@@ -49,5 +52,9 @@ const baseUrl = (_graphqlMockServerCon2 = graphqlMockServerConfig.baseUrl) !== null && _graphqlMockServerCon2 !== void 0 ? _graphqlMockServerCon2 : '/';

}
const routerWithGraphqlRoutes = (0, _graphql.createGraphQLRoutes)(_express.default.Router(), {
configs
}, interceptors === null || interceptors === void 0 ? void 0 : interceptors.response);
const routerWithGraphqlRoutes = (0, _graphql.createGraphQLRoutes)({
router: _express.default.Router(),
graphqlConfig: {
configs
},
serverResponseInterceptor: interceptors === null || interceptors === void 0 ? void 0 : interceptors.response
});
server.use(baseUrl, routerWithGraphqlRoutes);

@@ -54,0 +61,0 @@ if (database) {

@@ -39,3 +39,6 @@ "use strict";

if (serverRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, serverRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
interceptor: serverRequestInterceptor
});
}

@@ -52,19 +55,35 @@ const baseUrl = (_mockServerConfig$bas = mockServerConfig.baseUrl) !== null && _mockServerConfig$bas !== void 0 ? _mockServerConfig$bas : '/';

if (rest) {
var _rest$interceptors, _rest$baseUrl;
const routerWithRestRoutes = (0, _rest.createRestRoutes)(_express.default.Router(), rest, interceptors === null || interceptors === void 0 ? void 0 : interceptors.response);
var _rest$baseUrl, _rest$interceptors;
const routerWithRestRoutes = (0, _rest.createRestRoutes)({
router: _express.default.Router(),
restConfig: rest,
serverResponseInterceptor: interceptors === null || interceptors === void 0 ? void 0 : interceptors.response
});
const restBaseUrl = (0, _helpers.urlJoin)(baseUrl, (_rest$baseUrl = rest.baseUrl) !== null && _rest$baseUrl !== void 0 ? _rest$baseUrl : '/');
const apiRequestInterceptor = (_rest$interceptors = rest.interceptors) === null || _rest$interceptors === void 0 ? void 0 : _rest$interceptors.request;
if (apiRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, apiRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
path: restBaseUrl,
interceptor: apiRequestInterceptor
});
}
const restBaseUrl = (0, _helpers.urlJoin)(baseUrl, (_rest$baseUrl = rest.baseUrl) !== null && _rest$baseUrl !== void 0 ? _rest$baseUrl : '/');
server.use(restBaseUrl, routerWithRestRoutes);
}
if (graphql) {
var _graphql$interceptors, _graphql$baseUrl;
const routerWithGraphQLRoutes = (0, _graphql.createGraphQLRoutes)(_express.default.Router(), graphql, interceptors === null || interceptors === void 0 ? void 0 : interceptors.response);
var _graphql$baseUrl, _graphql$interceptors;
const routerWithGraphQLRoutes = (0, _graphql.createGraphQLRoutes)({
router: _express.default.Router(),
graphqlConfig: graphql,
serverResponseInterceptor: interceptors === null || interceptors === void 0 ? void 0 : interceptors.response
});
const graphqlBaseUrl = (0, _helpers.urlJoin)(baseUrl, (_graphql$baseUrl = graphql.baseUrl) !== null && _graphql$baseUrl !== void 0 ? _graphql$baseUrl : '/');
const apiRequestInterceptor = (_graphql$interceptors = graphql.interceptors) === null || _graphql$interceptors === void 0 ? void 0 : _graphql$interceptors.request;
if (apiRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, apiRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
path: graphqlBaseUrl,
interceptor: apiRequestInterceptor
});
}
const graphqlBaseUrl = (0, _helpers.urlJoin)(baseUrl, (_graphql$baseUrl = graphql.baseUrl) !== null && _graphql$baseUrl !== void 0 ? _graphql$baseUrl : '/');
server.use(graphqlBaseUrl, routerWithGraphQLRoutes);

@@ -71,0 +90,0 @@ }

@@ -37,3 +37,6 @@ "use strict";

if (serverRequestInterceptor) {
(0, _middlewares.requestInterceptorMiddleware)(server, serverRequestInterceptor);
(0, _middlewares.requestInterceptorMiddleware)({
server,
interceptor: serverRequestInterceptor
});
}

@@ -49,5 +52,9 @@ const baseUrl = (_restMockServerConfig2 = restMockServerConfig.baseUrl) !== null && _restMockServerConfig2 !== void 0 ? _restMockServerConfig2 : '/';

}
const routerWithRestRoutes = (0, _rest.createRestRoutes)(_express.default.Router(), {
configs
}, interceptors === null || interceptors === void 0 ? void 0 : interceptors.response);
const routerWithRestRoutes = (0, _rest.createRestRoutes)({
router: _express.default.Router(),
restConfig: {
configs
},
serverResponseInterceptor: interceptors === null || interceptors === void 0 ? void 0 : interceptors.response
});
server.use(baseUrl, routerWithRestRoutes);

@@ -54,0 +61,0 @@ if (database) {

@@ -0,8 +1,8 @@

export * from './createDatabaseMockServer/createDatabaseMockServer';
export * from './createGraphQLMockServer/createGraphQLMockServer';
export * from './createMockServer/createMockServer';
export * from './createRestMockServer/createRestMockServer';
export * from './createGraphQLMockServer/createGraphQLMockServer';
export * from './createDatabaseMockServer/createDatabaseMockServer';
export * from './startRestMockServer/startRestMockServer';
export * from './startDatabaseMockServer/startDatabaseMockServer';
export * from './startGraphQLMockServer/startGraphQLMockServer';
export * from './startMockServer/startMockServer';
export * from './startRestMockServer/startRestMockServer';

@@ -6,24 +6,13 @@ "use strict";

});
var _createMockServer = require("./createMockServer/createMockServer");
Object.keys(_createMockServer).forEach(function (key) {
var _createDatabaseMockServer = require("./createDatabaseMockServer/createDatabaseMockServer");
Object.keys(_createDatabaseMockServer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _createMockServer[key]) return;
if (key in exports && exports[key] === _createDatabaseMockServer[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _createMockServer[key];
return _createDatabaseMockServer[key];
}
});
});
var _createRestMockServer = require("./createRestMockServer/createRestMockServer");
Object.keys(_createRestMockServer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _createRestMockServer[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _createRestMockServer[key];
}
});
});
var _createGraphQLMockServer = require("./createGraphQLMockServer/createGraphQLMockServer");

@@ -40,21 +29,21 @@ Object.keys(_createGraphQLMockServer).forEach(function (key) {

});
var _createDatabaseMockServer = require("./createDatabaseMockServer/createDatabaseMockServer");
Object.keys(_createDatabaseMockServer).forEach(function (key) {
var _createMockServer = require("./createMockServer/createMockServer");
Object.keys(_createMockServer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _createDatabaseMockServer[key]) return;
if (key in exports && exports[key] === _createMockServer[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _createDatabaseMockServer[key];
return _createMockServer[key];
}
});
});
var _startRestMockServer = require("./startRestMockServer/startRestMockServer");
Object.keys(_startRestMockServer).forEach(function (key) {
var _createRestMockServer = require("./createRestMockServer/createRestMockServer");
Object.keys(_createRestMockServer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _startRestMockServer[key]) return;
if (key in exports && exports[key] === _createRestMockServer[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _startRestMockServer[key];
return _createRestMockServer[key];
}

@@ -95,2 +84,13 @@ });

});
});
var _startRestMockServer = require("./startRestMockServer/startRestMockServer");
Object.keys(_startRestMockServer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _startRestMockServer[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _startRestMockServer[key];
}
});
});
document.getElementById('scheme_switcher').addEventListener('click', () => window.switchScheme());

@@ -22,3 +22,3 @@ const lightStyles = document.querySelector(

// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line no-unused-vars
function switchScheme() {

@@ -25,0 +25,0 @@ setScheme(getSavedScheme() === 'light' ? 'dark' : 'light');

@@ -0,0 +0,0 @@ function switchTab(activeTabId) {

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

export declare const isEntityDescriptor: (value: any) => boolean;
import type { EntityDescriptor } from '../../../types';
export declare const isEntityDescriptor: (value: any) => value is EntityDescriptor;
import type { Request } from 'express';
import type { GraphQLInput } from '../../../types';
export declare const getGraphQLInput: (request: Request) => GraphQLInput;
import type { PlainObject } from '../../../types';
interface GetGraphQLInputResult {
query: string | undefined;
variables: PlainObject | undefined;
}
export declare const getGraphQLInput: (request: Request) => GetGraphQLInputResult;
export {};

@@ -9,3 +9,2 @@ "use strict";

if (request.method === 'GET') {
var _ref;
const {

@@ -15,5 +14,8 @@ query,

} = request.query;
// ✅ important:
// if 'variables' was sent as encoded uri component then it already decoded into object and we do not need to use JSON.parse
return {
query: query === null || query === void 0 ? void 0 : query.toString(),
variables: JSON.parse((_ref = variables) !== null && _ref !== void 0 ? _ref : '{}')
variables: typeof variables === 'string' ? JSON.parse(variables) : variables
};

@@ -28,7 +30,7 @@ }

query,
variables: variables !== null && variables !== void 0 ? variables : {}
variables
};
}
throw new Error('Not allowed request method for graphql request');
throw new Error(`Not allowed request method ${request.method} for graphql request`);
};
exports.getGraphQLInput = getGraphQLInput;
import type { OperationTypeNode } from 'graphql';
interface ParseDocumentNodeResult {
operationType: OperationTypeNode;
operationName: string;
operationName: string | undefined;
}
export declare const parseQuery: (query: string) => ParseDocumentNodeResult | null;
export {};

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

operationType: operationDefinition.operation,
operationName: (_operationDefinition$ = (_operationDefinition$2 = operationDefinition.name) === null || _operationDefinition$2 === void 0 ? void 0 : _operationDefinition$2.value) !== null && _operationDefinition$ !== void 0 ? _operationDefinition$ : ''
operationName: (_operationDefinition$ = (_operationDefinition$2 = operationDefinition.name) === null || _operationDefinition$2 === void 0 ? void 0 : _operationDefinition$2.value) !== null && _operationDefinition$ !== void 0 ? _operationDefinition$ : undefined
};

@@ -16,0 +16,0 @@ };

@@ -17,17 +17,26 @@ "use strict";

const getHeaders = () => response.getHeaders();
const getCookie = name => request.cookies[name];
const setHeader = (field, value) => {
response.set(field, value);
};
const appendHeader = (field, value) => {
response.append(field, value);
};
const setStatusCode = statusCode => {
response.statusCode = statusCode;
};
const setHeader = (field, value) => response.set(field, value);
const appendHeader = (field, value) => response.append(field, value);
const getCookie = name => request.cookies[name];
const setCookie = (name, value, options) => {
if (options) {
response.cookie(name, value, options);
return;
}
response.cookie(name, value);
};
const clearCookie = (name, options) => response.clearCookie(name, options);
const attachment = filename => response.attachment(filename);
const ResponseInterceptorParams = {
const clearCookie = (name, options) => {
response.clearCookie(name, options);
};
const attachment = filename => {
response.attachment(filename);
};
const responseInterceptorParams = {
request,

@@ -48,12 +57,12 @@ response,

if (interceptors !== null && interceptors !== void 0 && interceptors.routeInterceptor) {
updatedData = await interceptors.routeInterceptor(updatedData, ResponseInterceptorParams);
updatedData = await interceptors.routeInterceptor(updatedData, responseInterceptorParams);
}
if (interceptors !== null && interceptors !== void 0 && interceptors.requestInterceptor) {
updatedData = await interceptors.requestInterceptor(updatedData, ResponseInterceptorParams);
updatedData = await interceptors.requestInterceptor(updatedData, responseInterceptorParams);
}
if (interceptors !== null && interceptors !== void 0 && interceptors.apiInterceptor) {
updatedData = await interceptors.apiInterceptor(updatedData, ResponseInterceptorParams);
updatedData = await interceptors.apiInterceptor(updatedData, responseInterceptorParams);
}
if (interceptors !== null && interceptors !== void 0 && interceptors.serverInterceptor) {
updatedData = await interceptors.serverInterceptor(updatedData, ResponseInterceptorParams);
updatedData = await interceptors.serverInterceptor(updatedData, responseInterceptorParams);
}

@@ -60,0 +69,0 @@ return updatedData;

import type { Request } from 'express';
import type { CalculateByDescriptorValueCheckMode, CheckActualValueCheckMode, CheckFunction, CheckMode, CompareWithDescriptorAnyValueCheckMode, CompareWithDescriptorValueCheckMode } from './checkModes';
import type { CheckActualValueCheckMode, CheckFunction, CheckMode, CompareWithDescriptorAnyValueCheckMode, CompareWithDescriptorValueCheckMode } from './checkModes';
import type { Interceptors } from './interceptors';
import type { Data, Primitive } from './values';
import type { NestedObjectOrArray } from './utils';
import type { Data } from './values';
export type GraphQLEntityName = 'headers' | 'cookies' | 'query' | 'variables';
export type GraphQLMappedEntityName = string;
type GraphQLPlainEntityValue = string | number | boolean | null;
type GraphQLMappedEntityValue = string | number | boolean;
type GraphQLPlainEntityInnerValue = {
checkMode?: undefined;
call?: undefined;
dotAll?: undefined;
[key: string]: Primitive | GraphQLPlainEntityInnerValue;
};
type GraphQLPlainEntityValue = {
checkMode?: undefined;
call?: undefined;
forEach?: undefined;
dotAll?: undefined;
[key: string]: GraphQLPlainEntityInnerValue | Primitive | GraphQLEntityDescriptor;
};
export type GraphQLOperationType = 'query' | 'mutation';
type GraphQLOperationName = string | RegExp;
interface GraphQLQuery {
operationType: GraphQLOperationType;
operationName: GraphQLOperationName;
}
type GraphQLVariables = Record<string, any>;
export interface GraphQLInput {
query?: string;
variables: GraphQLVariables;
}
type GraphQLEntityValue<EntityName = GraphQLEntityName> = EntityName extends 'variables' ? GraphQLPlainEntityValue : GraphQLMappedEntityValue;
type GraphQLEntityValueOrValues<EntityName = GraphQLEntityName> = GraphQLEntityValue<EntityName> | GraphQLEntityValue<EntityName>[];
type GraphQLEntityDescriptor<EntityName extends GraphQLEntityName = GraphQLEntityName, Check extends CheckMode = CheckMode> = EntityName extends 'variables' ? Check extends Extract<CalculateByDescriptorValueCheckMode, 'function'> ? {
export type GraphQLTopLevelPlainEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: any, checkFunction: CheckFunction) => boolean;
value: (actualValue: NestedObjectOrArray<GraphQLPlainEntityValue>, checkFunction: CheckFunction) => boolean;
} : Check extends CompareWithDescriptorAnyValueCheckMode ? {
checkMode: Check;
value: GraphQLEntityValueOrValues<EntityName>;
value: NestedObjectOrArray<GraphQLPlainEntityValue>;
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value?: undefined;
} : never : Check extends Extract<CalculateByDescriptorValueCheckMode, 'function'> ? {
value: never;
} : never;
type GraphQLPropertyLevelPlainEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: any, checkFunction: CheckFunction) => boolean;
} : Check extends Extract<CalculateByDescriptorValueCheckMode, 'regExp'> ? {
value: (actualValue: GraphQLPlainEntityValue | NestedObjectOrArray<GraphQLPlainEntityValue>, checkFunction: CheckFunction) => boolean;
} : Check extends CompareWithDescriptorAnyValueCheckMode ? {
checkMode: Check;
value: GraphQLPlainEntityValue | NestedObjectOrArray<GraphQLPlainEntityValue>;
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value: never;
} : never;
type GraphQLMappedEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: GraphQLMappedEntityValue, checkFunction: CheckFunction) => boolean;
} : Check extends 'regExp' ? {
checkMode: Check;
value: RegExp | RegExp[];
} : Check extends CompareWithDescriptorValueCheckMode ? {
checkMode: Check;
value: GraphQLEntityValueOrValues<EntityName>;
value: GraphQLMappedEntityValue | GraphQLMappedEntityValue[];
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value?: undefined;
value: never;
} : never;
export type GraphQLEntityDescriptorOrValue<EntityName extends GraphQLEntityName = GraphQLEntityName> = EntityName extends 'variables' ? GraphQLEntityDescriptor<EntityName> | GraphQLEntityValue<EntityName> : Record<GraphQLMappedEntityName, GraphQLEntityDescriptor<EntityName> | GraphQLEntityValueOrValues<EntityName>>;
export type GraphQLEntityDescriptorOnly<EntityName extends GraphQLEntityName = GraphQLEntityName> = EntityName extends 'variables' ? GraphQLEntityDescriptor<EntityName> : Record<GraphQLMappedEntityName, GraphQLEntityDescriptor<EntityName>>;
export interface GraphQLEntityNamesByOperationType {
query: GraphQLEntityName;
mutation: GraphQLEntityName;
}
type GraphQLEntityByEntityName<OperationType extends GraphQLOperationType> = {
[EntityName in GraphQLEntityNamesByOperationType[OperationType]]?: GraphQLEntityDescriptorOrValue<EntityName>;
export type GraphQLEntityDescriptorOrValue<EntityName extends GraphQLEntityName = GraphQLEntityName> = EntityName extends 'variables' ? GraphQLTopLevelPlainEntityDescriptor | Record<string, GraphQLPropertyLevelPlainEntityDescriptor> | NestedObjectOrArray<GraphQLPlainEntityValue> : Record<string, GraphQLMappedEntityDescriptor | GraphQLMappedEntityValue | GraphQLMappedEntityValue[]>;
export type GraphQLOperationType = 'query' | 'mutation';
export type GraphQLOperationName = string | RegExp;
export type GraphQLEntityNamesByOperationType = {
[operationType in GraphQLOperationType]: GraphQLEntityName;
};
export interface GraphQLRouteConfig<OperationType extends GraphQLOperationType = GraphQLOperationType, Entities extends GraphQLEntityByEntityName<OperationType> = GraphQLEntityByEntityName<OperationType>> {
entities?: Entities;
data: ((request: Request, entities: Entities) => Data | Promise<Data>) | Data;
export type GraphQLEntitiesByEntityName = {
[EntityName in GraphQLEntityName]?: GraphQLEntityDescriptorOrValue<EntityName>;
};
type GraphQLSettings = {
readonly polling: boolean;
};
export type GraphQLRouteConfig<Settings extends GraphQLSettings = GraphQLSettings> = ({
settings: Settings & {
polling: true;
};
queue: Array<{
time?: number;
data: ((request: Request, entities: GraphQLEntitiesByEntityName) => Data | Promise<Data>) | Data;
}>;
} | {
settings?: Settings & {
polling?: false;
};
data: ((request: Request, entities: GraphQLEntitiesByEntityName) => Data | Promise<Data>) | Data;
}) & {
entities?: GraphQLEntitiesByEntityName;
interceptors?: Pick<Interceptors, 'response'>;
}
export interface GraphQLRequestConfig extends GraphQLQuery {
};
interface BaseGraphQLRequestConfig {
operationType: GraphQLOperationType;
routes: GraphQLRouteConfig[];
interceptors?: Interceptors;
}
export interface OperationNameGraphQLRequestConfig extends BaseGraphQLRequestConfig {
operationName: GraphQLOperationName;
}
interface QueryGraphQLRequestConfig extends BaseGraphQLRequestConfig {
query: string;
}
export type GraphQLRequestConfig = OperationNameGraphQLRequestConfig | QueryGraphQLRequestConfig;
export {};

@@ -7,2 +7,3 @@ export * from './checkModes';

export * from './server';
export * from './utils';
export * from './values';

@@ -72,2 +72,13 @@ "use strict";

});
var _utils = require("./utils");
Object.keys(_utils).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _utils[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _utils[key];
}
});
});
var _values = require("./values");

@@ -74,0 +85,0 @@ Object.keys(_values).forEach(function (key) {

@@ -11,3 +11,3 @@ import type { CookieOptions, Request, Response } from 'express';

}
export type RequestInterceptor = (params: RequestInterceptorParams) => void;
export type RequestInterceptor = (params: RequestInterceptorParams) => void | Promise<void>;
export interface ResponseInterceptorParams {

@@ -14,0 +14,0 @@ request: Request;

import type { Request } from 'express';
import type { CalculateByDescriptorValueCheckMode, CheckActualValueCheckMode, CheckFunction, CheckMode, CompareWithDescriptorAnyValueCheckMode, CompareWithDescriptorValueCheckMode } from './checkModes';
import type { CheckActualValueCheckMode, CheckFunction, CheckMode, CompareWithDescriptorAnyValueCheckMode, CompareWithDescriptorValueCheckMode } from './checkModes';
import type { Interceptors } from './interceptors';
import type { Data, Primitive } from './values';
import type { NestedObjectOrArray } from './utils';
import type { Data } from './values';
export type RestMethod = 'get' | 'post' | 'delete' | 'put' | 'patch' | 'options';
export type RestEntityName = 'headers' | 'cookies' | 'query' | 'params' | 'body';
export type RestMappedEntityKey = string;
type RestPlainEntityValue = string | number | boolean | null;
type RestMappedEntityValue = string | number | boolean;
type RestPlainEntityInnerValue = {
checkMode?: undefined;
call?: undefined;
dotAll?: undefined;
[key: string]: Primitive | RestPlainEntityInnerValue;
};
type RestPlainEntityValue = {
checkMode?: undefined;
call?: undefined;
dotAll?: undefined;
[key: string]: RestPlainEntityInnerValue | Primitive | RestEntityDescriptor;
} | (RestPlainEntityInnerValue | Primitive | RestEntityDescriptor)[];
type RestEntityValue<EntityName = RestEntityName> = EntityName extends 'body' ? RestPlainEntityValue : RestMappedEntityValue;
type RestEntityValueOrValues<EntityName = RestEntityName> = RestEntityValue<EntityName> | RestEntityValue<EntityName>[];
type RestEntityDescriptor<EntityName extends RestEntityName = RestEntityName, Check extends CheckMode = CheckMode> = EntityName extends 'body' ? Check extends Extract<CalculateByDescriptorValueCheckMode, 'function'> ? {
export type RestTopLevelPlainEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: any, checkFunction: CheckFunction) => boolean;
value: (actualValue: NestedObjectOrArray<RestPlainEntityValue>, checkFunction: CheckFunction) => boolean;
} : Check extends CompareWithDescriptorAnyValueCheckMode ? {
checkMode: Check;
value: RestEntityValueOrValues<EntityName>;
value: NestedObjectOrArray<RestPlainEntityValue>;
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value?: undefined;
} : never : Check extends Extract<CalculateByDescriptorValueCheckMode, 'function'> ? {
value: never;
} : never;
type RestPropertyLevelPlainEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: any, checkFunction: CheckFunction) => boolean;
} : Check extends Extract<CalculateByDescriptorValueCheckMode, 'regExp'> ? {
value: (actualValue: RestPlainEntityValue | NestedObjectOrArray<RestPlainEntityValue>, checkFunction: CheckFunction) => boolean;
} : Check extends CompareWithDescriptorAnyValueCheckMode ? {
checkMode: Check;
value: RestPlainEntityValue | NestedObjectOrArray<RestPlainEntityValue>;
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value: never;
} : never;
type RestMappedEntityDescriptor<Check extends CheckMode = CheckMode> = Check extends 'function' ? {
checkMode: Check;
value: (actualValue: RestMappedEntityValue, checkFunction: CheckFunction) => boolean;
} : Check extends 'regExp' ? {
checkMode: Check;
value: RegExp | RegExp[];
} : Check extends CompareWithDescriptorValueCheckMode ? {
checkMode: Check;
value: RestEntityValueOrValues<EntityName>;
value: RestMappedEntityValue | RestMappedEntityValue[];
} : Check extends CheckActualValueCheckMode ? {
checkMode: Check;
value?: undefined;
value: never;
} : never;
export type RestEntityDescriptorOrValue<EntityName extends RestEntityName = RestEntityName> = EntityName extends 'body' ? RestEntityDescriptor<EntityName> | RestEntityValue<EntityName> : Record<RestMappedEntityKey, RestEntityDescriptor<EntityName> | RestEntityValueOrValues<EntityName>>;
export type RestEntityDescriptorOnly<EntityName extends RestEntityName = RestEntityName> = EntityName extends 'body' ? RestEntityDescriptor<EntityName> : Record<RestMappedEntityKey, RestEntityDescriptor<EntityName>>;
export interface RestEntityNamesByMethod {
get: Exclude<RestEntityName, 'body'>;
delete: Exclude<RestEntityName, 'body'>;
post: RestEntityName;
put: RestEntityName;
patch: RestEntityName;
options: Exclude<RestEntityName, 'body'>;
}
export type RestEntityByEntityName<Method extends RestMethod> = {
export type RestEntityDescriptorOrValue<EntityName extends RestEntityName = RestEntityName> = EntityName extends 'body' ? RestTopLevelPlainEntityDescriptor | Record<string, RestPropertyLevelPlainEntityDescriptor> | NestedObjectOrArray<RestPlainEntityValue> : Record<string, RestMappedEntityDescriptor | RestMappedEntityValue | RestMappedEntityValue[]>;
export type RestEntityNamesByMethod = {
[key in RestMethod]: key extends 'get' | 'delete' | 'options' ? Exclude<RestEntityName, 'body'> : RestEntityName;
};
export type RestEntitiesByEntityName<Method extends RestMethod = RestMethod> = {
[EntityName in RestEntityNamesByMethod[Method]]?: RestEntityDescriptorOrValue<EntityName>;
};
export interface RestRouteConfig<Method extends RestMethod, Entities extends RestEntityByEntityName<Method> = RestEntityByEntityName<Method>> {
interface RestSettings {
readonly polling?: boolean;
}
export type RestRouteConfig<Method extends RestMethod, Entities extends RestEntitiesByEntityName<Method> = RestEntitiesByEntityName<Method>, Settings extends RestSettings = RestSettings> = ({
settings: Settings & {
polling: true;
};
queue: Array<{
time?: number;
data: ((request: Request, entities: Entities) => Data | Promise<Data>) | Data;
}>;
} | {
settings?: Settings & {
polling: false;
};
data: ((request: Request, entities: Entities) => Data | Promise<Data>) | Data;
}) & {
entities?: Entities;
data: ((request: Request, entities: Entities) => Data | Promise<Data>) | Data;
interceptors?: Pick<Interceptors, 'response'>;
}
};
export type RestPathString = `/${string}`;

@@ -64,0 +71,0 @@ interface BaseRestRequestConfig<Method extends RestMethod> {

export type PlainObject = Record<string, any>;
export type PlainFunction = (...args: any[]) => any;
export type Primitive = boolean | number | bigint | string | null | undefined | symbol;
export type Data = boolean | number | string | any[] | Record<any, any> | null | undefined;
{
"name": "mock-config-server",
"version": "3.2.0",
"version": "3.3.0",
"description": "Tool that easily and quickly imitates server operation, create full fake api in few steps",

@@ -5,0 +5,0 @@ "author": {

@@ -76,3 +76,3 @@ # 🎉 Mock Config Server

- `interceptors?` {Interceptors} functions to change request or response parameters, [read](#interceptors)
- `database?` Database config for mock requests [read](#Database)
- `database?` Database config for mock requests [read](#database)
- `data` {Object | string} initial data for database

@@ -103,3 +103,4 @@ - `routes?` {Object | string} map of custom routes for database

- `operationType` {query | mutation} graphql operation type
- `operationName` {string} graphql operation name
- `operationName?` {string | RegExp} graphql operation name
- `query?`: {string} graphql query as string
- `routes` {GraphQLRouteConfig[]} request routes

@@ -111,2 +112,4 @@ - `data` {any} mock data of request

> Every graphql config should contain `operationName` or `query` or both of them
##### Rest example

@@ -276,2 +279,31 @@

Also you can use array as value for REST body and GraphQL variables entities: in this case mock-config-server will iterate
over array until `checkMode=equals` finds a match or return 404
```javascript
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'post',
routes: [
{
entities: {
// if body equals to { key1: 'value1' } or ['value1'] then mock-config-server return data
body: [{ key1: 'value1' }, ['value1']]
},
data: 'Some user data'
}
]
}
]
}
};
module.exports = mockServerConfig;
```
`function checkMode` is the most powerful way to describe your `entities` logic, but in most cases you will be fine using other `checkModes`.

@@ -388,2 +420,62 @@

#### Polling
Routes support polling for data. To add polling for data, you must specify the `polling setting` and change `data` property to `queue`.
> After receiving the last value from polling, the queue is reset and the next request will return the first value from the queue.
```javascript
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ data: { emoji: '🦁', name: 'Nursultan' } },
{ data: { emoji: '☄', name: 'Dmitriy' } }
]
}
]
}
]
}
};
export default mockServerConfig;
```
Using the additional `time` properties in milliseconds, you can specify how much time certain data should be returned
```javascript
/** @type {import('mock-config-server').MockServerConfig} */
const mockServerConfig = {
rest: {
baseUrl: '/api',
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ time: 5000, data: { emoji: '🦁', name: 'Nursultan' } },
{ data: { emoji: '☄', name: 'Dmitriy' } }
]
}
]
}
]
}
};
export default mockServerConfig;
```
#### Static Path

@@ -555,2 +647,60 @@

### Pagination
> Use \_page and optionally \_limit to paginate returned data.
```
GET /users?_page=1
GET /users?_page=1&_limit=5
```
> **\_limit** is 10 by default
The returned data has the format:
```
{
_link: Link,
results: Data[]
}
```
In the **Link** header you'll get **count**, **pages**, **next** and **prev** links.
#### Link
- `count` {number} total count of elements
- `pages` {number} count of pages
- `next` {string | null} query string for next link
- `prev` {string | null} query string for prev link
### Sort
> Use \_sort and \_order, use . to access deep properties
```
GET /users?_sort=name
GET /users/1/transfers?_sort=id&_order=asc
GET /users?_sort=address.city&_order=desc
```
> **\_order** is 'asc' by default
For multiple fields:
```
GET /users?_sort=id&_order=desc&_sort=name&_order=asc
```
### Slice
> X-Total-Count header is included in the response
```
GET /users?_begin=20
GET /users?_begin=20&_end=30
```
Works exactly as [slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice), \_begin and \_end are optional
### File example

@@ -610,3 +760,3 @@

</a>
</td>
</td>
<td align="center" style="word-wrap: break-word; width: 100.0; height: 100.0">

@@ -613,0 +763,0 @@ <a href="https://github.com/RiceWithMeat">

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