mock-config-server 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +277 -213
  2. package/dist/bin/mock-config-server.d.ts +2 -2
  3. package/dist/bin/mock-config-server.js +67 -65
  4. package/dist/bin/resolveExportsFromSourceCode.d.ts +1 -1
  5. package/dist/bin/resolveExportsFromSourceCode.js +11 -11
  6. package/dist/bin/validateMockServerConfig/validateBaseUrl/validateBaseUrl.d.ts +1 -0
  7. package/dist/bin/validateMockServerConfig/validateBaseUrl/validateBaseUrl.js +12 -0
  8. package/dist/bin/validateMockServerConfig/validateCors/validateCors.d.ts +1 -0
  9. package/dist/bin/validateMockServerConfig/validateCors/validateCors.js +82 -0
  10. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateGraphqlConfig.d.ts +1 -0
  11. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateGraphqlConfig.js +48 -0
  12. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateRoutes/validateRoutes.d.ts +2 -0
  13. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateRoutes/validateRoutes.js +71 -0
  14. package/dist/bin/validateMockServerConfig/validateInterceptors/validateInterceptors.d.ts +1 -0
  15. package/dist/bin/validateMockServerConfig/validateInterceptors/validateInterceptors.js +21 -0
  16. package/dist/bin/validateMockServerConfig/validateMockServerConfig.d.ts +1 -0
  17. package/dist/bin/validateMockServerConfig/validateMockServerConfig.js +34 -0
  18. package/dist/bin/validateMockServerConfig/validatePort/validatePort.d.ts +1 -0
  19. package/dist/bin/validateMockServerConfig/validatePort/validatePort.js +9 -0
  20. package/dist/bin/validateMockServerConfig/validateRestConfig/validateRestConfig.d.ts +1 -0
  21. package/dist/bin/validateMockServerConfig/validateRestConfig/validateRestConfig.js +52 -0
  22. package/dist/bin/validateMockServerConfig/validateRestConfig/validateRoutes/validateRoutes.d.ts +2 -0
  23. package/dist/bin/validateMockServerConfig/validateRestConfig/validateRoutes/validateRoutes.js +104 -0
  24. package/dist/bin/validateMockServerConfig/validateStaticPath/validateStaticPath.d.ts +1 -0
  25. package/dist/bin/validateMockServerConfig/validateStaticPath/validateStaticPath.js +44 -0
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +17 -17
  28. package/dist/src/configs/isEntitiesEqual/isEntityValuesEqual.d.ts +1 -2
  29. package/dist/src/configs/isEntitiesEqual/isEntityValuesEqual.js +29 -29
  30. package/dist/src/cors/corsMiddleware/corsMiddleware.d.ts +3 -3
  31. package/dist/src/cors/corsMiddleware/corsMiddleware.js +44 -32
  32. package/dist/src/cors/getOrigins/getAllowedOrigins.d.ts +2 -2
  33. package/dist/src/cors/getOrigins/getAllowedOrigins.js +13 -16
  34. package/dist/src/cors/noCorsMiddleware/noCorsMiddleware.d.ts +2 -2
  35. package/dist/src/cors/noCorsMiddleware/noCorsMiddleware.js +20 -15
  36. package/dist/src/graphql/createGraphQLRoutes/createGraphQLRoutes.d.ts +3 -0
  37. package/dist/src/graphql/createGraphQLRoutes/createGraphQLRoutes.js +73 -0
  38. package/dist/src/graphql/getGraphQLInput/getGraphQLInput.d.ts +3 -0
  39. package/dist/src/graphql/getGraphQLInput/getGraphQLInput.js +21 -0
  40. package/dist/src/graphql/parseGraphQLRequest/parseGraphQLRequest.d.ts +3 -0
  41. package/dist/src/graphql/parseGraphQLRequest/parseGraphQLRequest.js +12 -0
  42. package/dist/src/graphql/parseQuery/parseQuery.d.ts +7 -0
  43. package/dist/src/graphql/parseQuery/parseQuery.js +21 -0
  44. package/dist/src/graphql/prepareGraphQLRequestConfigs/prepareGraphQLRequestConfigs.d.ts +2 -0
  45. package/dist/src/graphql/prepareGraphQLRequestConfigs/prepareGraphQLRequestConfigs.js +28 -0
  46. package/dist/src/index.d.ts +3 -3
  47. package/dist/src/index.js +19 -19
  48. package/dist/src/notFound/notFoundMiddleware.d.ts +8 -0
  49. package/dist/src/notFound/notFoundMiddleware.js +47 -0
  50. package/dist/src/notFound/urlSuggestions/getGraphqlUrlSuggestions/getGraphqlUrlSuggestions.d.ts +6 -0
  51. package/dist/src/notFound/urlSuggestions/getGraphqlUrlSuggestions/getGraphqlUrlSuggestions.js +18 -0
  52. package/dist/src/notFound/urlSuggestions/getGraphqlUrlSuggestions/index.d.ts +1 -0
  53. package/dist/src/notFound/urlSuggestions/getGraphqlUrlSuggestions/index.js +17 -0
  54. package/dist/src/notFound/urlSuggestions/getLevenshteinDistance/getLevenshteinDistance.d.ts +1 -0
  55. package/dist/src/notFound/urlSuggestions/getLevenshteinDistance/getLevenshteinDistance.js +80 -0
  56. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/getRestUrlSuggestions.d.ts +6 -0
  57. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/getRestUrlSuggestions.js +34 -0
  58. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/getActualRestUrlMeaningfulString/getActualRestUrlMeaningfulString.d.ts +1 -0
  59. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/getActualRestUrlMeaningfulString/getActualRestUrlMeaningfulString.js +7 -0
  60. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/getPatternRestUrlMeaningfulString/getPatternRestUrlMeaningfulString.d.ts +1 -0
  61. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/getPatternRestUrlMeaningfulString/getPatternRestUrlMeaningfulString.js +5 -0
  62. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/index.d.ts +2 -0
  63. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/helpers/index.js +18 -0
  64. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/index.d.ts +1 -0
  65. package/dist/src/notFound/urlSuggestions/getRestUrlSuggestions/index.js +17 -0
  66. package/dist/src/notFound/urlSuggestions/index.d.ts +2 -0
  67. package/dist/src/notFound/urlSuggestions/index.js +18 -0
  68. package/dist/src/rest/createRestRoutes/createRestRoutes.d.ts +3 -0
  69. package/dist/src/{routes/createRoutes/createRoutes.js → rest/createRestRoutes/createRestRoutes.js} +41 -43
  70. package/dist/src/rest/prepareRestRequestConfigs/prepareRestRequestConfigs.d.ts +2 -0
  71. package/dist/src/{configs/prepareRequestConfigs/prepareRequestConfigs.js → rest/prepareRestRequestConfigs/prepareRestRequestConfigs.js} +30 -30
  72. package/dist/src/routes/callRequestInterceptors/callRequestInterceptors.d.ts +12 -12
  73. package/dist/src/routes/callRequestInterceptors/callRequestInterceptors.js +13 -13
  74. package/dist/src/routes/callResponseInterceptors/callResponseInterceptors.d.ts +14 -14
  75. package/dist/src/routes/callResponseInterceptors/callResponseInterceptors.js +31 -31
  76. package/dist/src/server/createMockServer/createMockServer.d.ts +3 -3
  77. package/dist/src/server/createMockServer/createMockServer.js +48 -35
  78. package/dist/src/server/startMockServer/startMockServer.d.ts +2 -2
  79. package/dist/src/server/startMockServer/startMockServer.js +17 -13
  80. package/dist/src/static/staticMiddleware/staticMiddleware.d.ts +3 -3
  81. package/dist/src/static/staticMiddleware/staticMiddleware.js +30 -29
  82. package/dist/src/utils/constants/appPath.d.ts +1 -1
  83. package/dist/src/utils/constants/appPath.js +4 -4
  84. package/dist/src/utils/constants/default.d.ts +11 -10
  85. package/dist/src/utils/constants/default.js +14 -13
  86. package/dist/src/utils/constants/index.d.ts +2 -2
  87. package/dist/src/utils/constants/index.js +18 -18
  88. package/dist/src/utils/helpers/index.d.ts +3 -2
  89. package/dist/src/utils/helpers/index.js +19 -18
  90. package/dist/src/utils/helpers/isPlainObject.d.ts +1 -1
  91. package/dist/src/utils/helpers/isPlainObject.js +5 -5
  92. package/dist/src/utils/helpers/sleep.d.ts +1 -1
  93. package/dist/src/utils/helpers/sleep.js +7 -7
  94. package/dist/src/utils/helpers/url/getUrlParts/getUrlParts.d.ts +1 -0
  95. package/dist/src/utils/helpers/url/getUrlParts/getUrlParts.js +6 -0
  96. package/dist/src/utils/helpers/url/index.d.ts +2 -0
  97. package/dist/src/utils/helpers/url/index.js +18 -0
  98. package/dist/src/utils/helpers/url/removeLeadingAndTrailingSlashes/removeLeadingAndTrailingSlashes.d.ts +1 -0
  99. package/dist/src/utils/helpers/url/removeLeadingAndTrailingSlashes/removeLeadingAndTrailingSlashes.js +5 -0
  100. package/dist/src/utils/types/configs.d.ts +63 -34
  101. package/dist/src/utils/types/configs.js +2 -2
  102. package/dist/src/utils/types/graphql.d.ts +5 -0
  103. package/dist/src/utils/types/graphql.js +2 -0
  104. package/dist/src/utils/types/index.d.ts +4 -3
  105. package/dist/src/utils/types/index.js +20 -19
  106. package/dist/src/utils/types/interceptors.d.ts +15 -15
  107. package/dist/src/utils/types/interceptors.js +2 -2
  108. package/dist/src/utils/types/server.d.ts +32 -24
  109. package/dist/src/utils/types/server.js +2 -2
  110. package/package.json +102 -99
  111. package/dist/src/configs/prepareRequestConfigs/prepareRequestConfigs.d.ts +0 -2
  112. package/dist/src/routes/createRoutes/createRoutes.d.ts +0 -3
@@ -1,3 +1,3 @@
1
- import type { Express } from 'express';
2
- import type { Cors } from '../../utils/types';
3
- export declare const corsMiddleware: (server: Express, cors: Cors) => Promise<void>;
1
+ import type { Express } from 'express';
2
+ import type { Cors } from '../../utils/types';
3
+ export declare const corsMiddleware: (server: Express, cors: Cors) => void;
@@ -1,32 +1,44 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.corsMiddleware = void 0;
4
- const constants_1 = require("../../utils/constants");
5
- const getAllowedOrigins_1 = require("../getOrigins/getAllowedOrigins");
6
- const corsMiddleware = async (server, cors) => {
7
- server.use(async (req, res, next) => {
8
- if (Array.isArray(cors.origin) && !cors.origin.length) {
9
- return next();
10
- }
11
- const allowedOrigins = await (0, getAllowedOrigins_1.getAllowedOrigins)(cors.origin);
12
- const { origin } = req.headers;
13
- if (!allowedOrigins?.length || !origin) {
14
- return next();
15
- }
16
- const isAllowedOrigin = allowedOrigins.some((allowedOrigin) => {
17
- if (typeof allowedOrigin === 'string') {
18
- return allowedOrigin.includes(origin);
19
- }
20
- return allowedOrigin.test(origin);
21
- });
22
- if (isAllowedOrigin) {
23
- res.setHeader('Access-Control-Allow-Origin', origin);
24
- res.setHeader('Access-Control-Allow-Methods', cors.methods ?? constants_1.DEFAULT.CORS.METHODS);
25
- res.setHeader('Access-Control-Allow-Headers', cors.headers ?? constants_1.DEFAULT.CORS.HEADERS);
26
- res.setHeader('Access-Control-Allow-Credentials', `${cors.credentials ?? constants_1.DEFAULT.CORS.CREDENTIALS}`);
27
- res.setHeader('Access-Control-Max-Age', cors.maxAge ?? constants_1.DEFAULT.CORS.MAX_AGE);
28
- }
29
- next();
30
- });
31
- };
32
- exports.corsMiddleware = corsMiddleware;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.corsMiddleware = void 0;
4
+ const constants_1 = require("../../utils/constants");
5
+ const getAllowedOrigins_1 = require("../getOrigins/getAllowedOrigins");
6
+ const corsMiddleware = (server, cors) => {
7
+ server.use(async (req, res, next) => {
8
+ if (Array.isArray(cors.origin) && !cors.origin.length) {
9
+ return next();
10
+ }
11
+ let allowedOrigins = [];
12
+ if (typeof cors.origin === 'function') {
13
+ const origins = await cors.origin(req);
14
+ allowedOrigins = (0, getAllowedOrigins_1.getAllowedOrigins)(origins);
15
+ }
16
+ else {
17
+ allowedOrigins = (0, getAllowedOrigins_1.getAllowedOrigins)(cors.origin);
18
+ }
19
+ const { origin } = req.headers;
20
+ if (!allowedOrigins?.length || !origin) {
21
+ return next();
22
+ }
23
+ const isRequestOriginAllowed = allowedOrigins.some((allowedOrigin) => {
24
+ if (allowedOrigin instanceof RegExp) {
25
+ return new RegExp(allowedOrigin).test(origin);
26
+ }
27
+ return allowedOrigin === origin;
28
+ });
29
+ if (isRequestOriginAllowed) {
30
+ res.setHeader('Access-Control-Allow-Origin', origin);
31
+ res.setHeader('Access-Control-Allow-Credentials', `${cors.credentials ?? constants_1.DEFAULT.CORS.CREDENTIALS}`);
32
+ res.setHeader('Access-Control-Expose-Headers', cors.exposedHeaders ?? constants_1.DEFAULT.CORS.EXPOSED_HEADERS);
33
+ if (req.method === 'OPTIONS') {
34
+ res.setHeader('Access-Control-Allow-Methods', cors.methods ?? constants_1.DEFAULT.CORS.METHODS);
35
+ res.setHeader('Access-Control-Allow-Headers', cors.allowedHeaders ?? constants_1.DEFAULT.CORS.ALLOWED_HEADERS);
36
+ res.setHeader('Access-Control-Max-Age', cors.maxAge ?? constants_1.DEFAULT.CORS.MAX_AGE);
37
+ res.sendStatus(204);
38
+ return res.end();
39
+ }
40
+ }
41
+ return next();
42
+ });
43
+ };
44
+ exports.corsMiddleware = corsMiddleware;
@@ -1,2 +1,2 @@
1
- import type { Cors } from '../../utils/types';
2
- export declare const getAllowedOrigins: (origin: Cors['origin']) => Promise<(string | RegExp)[]>;
1
+ import type { CorsOrigin } from '../../utils/types';
2
+ export declare const getAllowedOrigins: (origin: CorsOrigin) => (string | RegExp)[];
@@ -1,16 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAllowedOrigins = void 0;
4
- const getAllowedOrigins = async (origin) => {
5
- if (Array.isArray(origin)) {
6
- return origin;
7
- }
8
- if (typeof origin === 'string' || origin instanceof RegExp) {
9
- return [origin];
10
- }
11
- if (typeof origin === 'function') {
12
- return (0, exports.getAllowedOrigins)(await origin());
13
- }
14
- throw new Error('Invalid cors origin format');
15
- };
16
- exports.getAllowedOrigins = getAllowedOrigins;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAllowedOrigins = void 0;
4
+ const getAllowedOrigins = (origin) => {
5
+ if (Array.isArray(origin)) {
6
+ return origin;
7
+ }
8
+ if (typeof origin === 'string' || origin instanceof RegExp) {
9
+ return [origin];
10
+ }
11
+ throw new Error('Invalid cors origin format');
12
+ };
13
+ exports.getAllowedOrigins = getAllowedOrigins;
@@ -1,2 +1,2 @@
1
- import type { Express } from 'express';
2
- export declare const noCorsMiddleware: (server: Express) => Promise<void>;
1
+ import type { Express } from 'express';
2
+ export declare const noCorsMiddleware: (server: Express) => void;
@@ -1,15 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noCorsMiddleware = void 0;
4
- const constants_1 = require("../../utils/constants");
5
- const noCorsMiddleware = async (server) => {
6
- server.use(async (_req, res, next) => {
7
- res.setHeader('Access-Control-Allow-Origin', constants_1.DEFAULT.CORS.ORIGIN);
8
- res.setHeader('Access-Control-Allow-Methods', constants_1.DEFAULT.CORS.METHODS);
9
- res.setHeader('Access-Control-Allow-Headers', constants_1.DEFAULT.CORS.HEADERS);
10
- res.setHeader('Access-Control-Allow-Credentials', `${constants_1.DEFAULT.CORS.CREDENTIALS}`);
11
- res.setHeader('Access-Control-Max-Age', constants_1.DEFAULT.CORS.MAX_AGE);
12
- return next();
13
- });
14
- };
15
- exports.noCorsMiddleware = noCorsMiddleware;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noCorsMiddleware = void 0;
4
+ const constants_1 = require("../../utils/constants");
5
+ const noCorsMiddleware = (server) => {
6
+ server.use((req, res, next) => {
7
+ res.setHeader('Access-Control-Allow-Origin', constants_1.DEFAULT.CORS.ORIGIN);
8
+ res.setHeader('Access-Control-Allow-Credentials', `${constants_1.DEFAULT.CORS.CREDENTIALS}`);
9
+ res.setHeader('Access-Control-Expose-Headers', constants_1.DEFAULT.CORS.EXPOSED_HEADERS);
10
+ if (req.method === 'OPTIONS') {
11
+ res.setHeader('Access-Control-Allow-Methods', constants_1.DEFAULT.CORS.METHODS);
12
+ res.setHeader('Access-Control-Allow-Headers', constants_1.DEFAULT.CORS.ALLOWED_HEADERS);
13
+ res.setHeader('Access-Control-Max-Age', constants_1.DEFAULT.CORS.MAX_AGE);
14
+ res.sendStatus(204);
15
+ return res.end();
16
+ }
17
+ return next();
18
+ });
19
+ };
20
+ exports.noCorsMiddleware = noCorsMiddleware;
@@ -0,0 +1,3 @@
1
+ import { IRouter } from 'express';
2
+ import type { GraphQLRequestConfig, Interceptors } from '../../utils/types';
3
+ export declare const createGraphQLRoutes: (router: IRouter, configs: GraphQLRequestConfig[], interceptors?: Interceptors) => IRouter;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createGraphQLRoutes = void 0;
4
+ const isEntityValuesEqual_1 = require("../../configs/isEntitiesEqual/isEntityValuesEqual");
5
+ const callRequestInterceptors_1 = require("../../routes/callRequestInterceptors/callRequestInterceptors");
6
+ const callResponseInterceptors_1 = require("../../routes/callResponseInterceptors/callResponseInterceptors");
7
+ const getGraphQLInput_1 = require("../getGraphQLInput/getGraphQLInput");
8
+ const parseQuery_1 = require("../parseQuery/parseQuery");
9
+ const prepareGraphQLRequestConfigs_1 = require("../prepareGraphQLRequestConfigs/prepareGraphQLRequestConfigs");
10
+ const createGraphQLRoutes = (router, configs, interceptors) => {
11
+ const preparedGraphQLRequestConfig = (0, prepareGraphQLRequestConfigs_1.prepareGraphQLRequestConfigs)(configs);
12
+ const graphqlMiddleware = (request, response, next) => {
13
+ const graphQLInput = (0, getGraphQLInput_1.getGraphQLInput)(request);
14
+ if (!graphQLInput || !graphQLInput.query) {
15
+ return response.status(400).json('Query is missing, you must pass a valid GraphQL query');
16
+ }
17
+ const query = (0, parseQuery_1.parseQuery)(graphQLInput.query);
18
+ if (!query) {
19
+ return response.status(400).json('Query is invalid, you must use a valid GraphQL query');
20
+ }
21
+ if (!query.operationName || !query.operationType) {
22
+ return response
23
+ .status(400)
24
+ .json(`You should to specify operationName and operationType for ${request.method}:${request.baseUrl}${request.path}`);
25
+ }
26
+ const matchedRequestConfig = preparedGraphQLRequestConfig.find((requestConfig) => {
27
+ if (requestConfig.operationName instanceof RegExp) {
28
+ return (new RegExp(requestConfig.operationName).test(query.operationName) &&
29
+ requestConfig.operationType === query.operationType);
30
+ }
31
+ return (requestConfig.operationName === query.operationName &&
32
+ requestConfig.operationType === query.operationType);
33
+ });
34
+ if (!matchedRequestConfig) {
35
+ return next();
36
+ }
37
+ (0, callRequestInterceptors_1.callRequestInterceptors)({
38
+ request,
39
+ interceptors: {
40
+ requestInterceptor: matchedRequestConfig.interceptors?.request,
41
+ serverInterceptor: interceptors?.request
42
+ }
43
+ });
44
+ const matchedRouteConfig = matchedRequestConfig.routes.find(({ entities }) => {
45
+ if (!entities)
46
+ return true;
47
+ return Object.entries(entities).every(([entity, entityValue]) => {
48
+ if (entity === 'variables') {
49
+ return (0, isEntityValuesEqual_1.isEntityValuesEqual)(entityValue, graphQLInput.variables);
50
+ }
51
+ return (0, isEntityValuesEqual_1.isEntityValuesEqual)(entityValue, request[entity]);
52
+ });
53
+ });
54
+ if (!matchedRouteConfig) {
55
+ return next();
56
+ }
57
+ const data = (0, callResponseInterceptors_1.callResponseInterceptors)({
58
+ data: matchedRouteConfig.data,
59
+ request,
60
+ response,
61
+ interceptors: {
62
+ routeInterceptor: matchedRouteConfig.interceptors?.response,
63
+ requestInterceptor: matchedRequestConfig.interceptors?.response,
64
+ serverInterceptor: interceptors?.response
65
+ }
66
+ });
67
+ return response.status(response.statusCode).json(data);
68
+ };
69
+ router.route('/').get(graphqlMiddleware);
70
+ router.route('/').post(graphqlMiddleware);
71
+ return router;
72
+ };
73
+ exports.createGraphQLRoutes = createGraphQLRoutes;
@@ -0,0 +1,3 @@
1
+ import type { Request } from 'express';
2
+ import type { GraphQLInput } from '../../utils/types/graphql';
3
+ export declare const getGraphQLInput: (request: Request) => GraphQLInput;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGraphQLInput = void 0;
4
+ const getGraphQLInput = (request) => {
5
+ if (request.method === 'GET') {
6
+ const { query, variables } = request.query;
7
+ return {
8
+ query: query?.toString(),
9
+ variables: JSON.parse(variables ?? '{}')
10
+ };
11
+ }
12
+ if (request.method === 'POST') {
13
+ const { query, variables } = request.body;
14
+ return {
15
+ query,
16
+ variables: variables ?? {}
17
+ };
18
+ }
19
+ throw new Error('Not allowed request method for graphql request');
20
+ };
21
+ exports.getGraphQLInput = getGraphQLInput;
@@ -0,0 +1,3 @@
1
+ import { Request } from 'express';
2
+ import { parseQuery } from '../parseQuery/parseQuery';
3
+ export declare const parseGraphQLRequest: (request: Request) => ReturnType<typeof parseQuery>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseGraphQLRequest = void 0;
4
+ const getGraphQLInput_1 = require("../getGraphQLInput/getGraphQLInput");
5
+ const parseQuery_1 = require("../parseQuery/parseQuery");
6
+ const parseGraphQLRequest = (request) => {
7
+ const graphQLInput = (0, getGraphQLInput_1.getGraphQLInput)(request);
8
+ if (!graphQLInput.query)
9
+ return null;
10
+ return (0, parseQuery_1.parseQuery)(graphQLInput.query);
11
+ };
12
+ exports.parseGraphQLRequest = parseGraphQLRequest;
@@ -0,0 +1,7 @@
1
+ import type { OperationTypeNode } from 'graphql';
2
+ interface ParseDocumentNodeResult {
3
+ operationType: OperationTypeNode;
4
+ operationName: string;
5
+ }
6
+ export declare const parseQuery: (query: string) => ParseDocumentNodeResult | null;
7
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseQuery = void 0;
4
+ const graphql_1 = require("graphql");
5
+ const parseDocumentNode = (node) => {
6
+ const operationDefinition = node.definitions.find((definition) => definition.kind === 'OperationDefinition');
7
+ return {
8
+ operationType: operationDefinition.operation,
9
+ operationName: operationDefinition.name?.value ?? ''
10
+ };
11
+ };
12
+ const parseQuery = (query) => {
13
+ try {
14
+ const document = (0, graphql_1.parse)(query);
15
+ return parseDocumentNode(document);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ };
21
+ exports.parseQuery = parseQuery;
@@ -0,0 +1,2 @@
1
+ import type { GraphQLRequestConfig } from '../../utils/types';
2
+ export declare const prepareGraphQLRequestConfigs: (requestConfigs: GraphQLRequestConfig[]) => GraphQLRequestConfig[];
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prepareGraphQLRequestConfigs = void 0;
4
+ const helpers_1 = require("../../utils/helpers");
5
+ const calculateRouteConfigWeight = (graphQLRouteConfig) => {
6
+ const { entities } = graphQLRouteConfig;
7
+ if (!entities)
8
+ return 0;
9
+ let routeConfigWeight = 0;
10
+ const { headers, query, variables } = entities;
11
+ if (headers)
12
+ routeConfigWeight += Object.keys(headers).length;
13
+ if (query)
14
+ routeConfigWeight += Object.keys(query).length;
15
+ if (variables)
16
+ routeConfigWeight += (0, helpers_1.isPlainObject)(variables) ? Object.keys(variables).length : 1;
17
+ return routeConfigWeight;
18
+ };
19
+ const prepareGraphQLRequestConfigs = (requestConfigs) => {
20
+ requestConfigs.forEach((requestConfig) => {
21
+ requestConfig.routes.sort((first, second) =>
22
+ // ✅ important:
23
+ // Lift more specific configs for correct working of routes
24
+ calculateRouteConfigWeight(second) - calculateRouteConfigWeight(first));
25
+ });
26
+ return requestConfigs;
27
+ };
28
+ exports.prepareGraphQLRequestConfigs = prepareGraphQLRequestConfigs;
@@ -1,3 +1,3 @@
1
- export * from './server/createMockServer/createMockServer';
2
- export * from './server/startMockServer/startMockServer';
3
- export * from './utils/types';
1
+ export * from './server/createMockServer/createMockServer';
2
+ export * from './server/startMockServer/startMockServer';
3
+ export * from './utils/types';
package/dist/src/index.js CHANGED
@@ -1,19 +1,19 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./server/createMockServer/createMockServer"), exports);
18
- __exportStar(require("./server/startMockServer/startMockServer"), exports);
19
- __exportStar(require("./utils/types"), exports);
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./server/createMockServer/createMockServer"), exports);
18
+ __exportStar(require("./server/startMockServer/startMockServer"), exports);
19
+ __exportStar(require("./utils/types"), exports);
@@ -0,0 +1,8 @@
1
+ import type { Express } from 'express';
2
+ import type { MockServerConfig } from '../utils/types';
3
+ interface NotFoundMiddlewareParams {
4
+ server: Express;
5
+ mockServerConfig: Pick<MockServerConfig, 'baseUrl' | 'rest' | 'graphql'>;
6
+ }
7
+ export declare const notFoundMiddleware: ({ server, mockServerConfig }: NotFoundMiddlewareParams) => void;
8
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.notFoundMiddleware = void 0;
4
+ const parseGraphQLRequest_1 = require("../graphql/parseGraphQLRequest/parseGraphQLRequest");
5
+ const urlSuggestions_1 = require("./urlSuggestions");
6
+ const notFoundMiddleware = ({ server, mockServerConfig }) => {
7
+ const { baseUrl: serverBaseUrl, rest, graphql } = mockServerConfig;
8
+ const operationNames = graphql?.configs.map(({ operationName }) => operationName) ?? [];
9
+ const graphqlPatternUrlMeaningfulStrings = Array.from(operationNames.reduce((acc, operationName) => {
10
+ if (typeof operationName === 'string')
11
+ acc.add(`${serverBaseUrl}${graphql?.baseUrl}/${operationName}`);
12
+ return acc;
13
+ }, new Set()));
14
+ const restPaths = rest?.configs.map(({ path }) => path) ?? [];
15
+ const patternUrls = Array.from(restPaths.reduce((acc, patternPath) => {
16
+ if (typeof patternPath === 'string')
17
+ acc.add(`${serverBaseUrl}${rest?.baseUrl}${patternPath}`);
18
+ return acc;
19
+ }, new Set()));
20
+ server.use((request, response) => {
21
+ const url = new URL(`${request.protocol}://${request.get('host')}${request.originalUrl}`);
22
+ let graphqlUrlSuggestions = [];
23
+ if (graphql) {
24
+ const graphqlQuery = (0, parseGraphQLRequest_1.parseGraphQLRequest)(request);
25
+ if (graphqlQuery) {
26
+ graphqlUrlSuggestions = (0, urlSuggestions_1.getGraphqlUrlSuggestions)({
27
+ url,
28
+ graphqlPatternUrlMeaningfulStrings
29
+ });
30
+ }
31
+ }
32
+ let restUrlSuggestions = [];
33
+ if (rest) {
34
+ restUrlSuggestions = (0, urlSuggestions_1.getRestUrlSuggestions)({
35
+ url,
36
+ patternUrls
37
+ });
38
+ }
39
+ response.status(404).render('notFound', {
40
+ requestMethod: request.method,
41
+ url: `${url.pathname}${url.search}`,
42
+ restUrlSuggestions,
43
+ graphqlUrlSuggestions
44
+ });
45
+ });
46
+ };
47
+ exports.notFoundMiddleware = notFoundMiddleware;
@@ -0,0 +1,6 @@
1
+ interface GetGraphqlUrlSuggestionsParams {
2
+ url: URL;
3
+ graphqlPatternUrlMeaningfulStrings: string[];
4
+ }
5
+ export declare const getGraphqlUrlSuggestions: ({ url, graphqlPatternUrlMeaningfulStrings }: GetGraphqlUrlSuggestionsParams) => string[];
6
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGraphqlUrlSuggestions = void 0;
4
+ const getLevenshteinDistance_1 = require("../getLevenshteinDistance/getLevenshteinDistance");
5
+ const getGraphqlUrlSuggestions = ({ url, graphqlPatternUrlMeaningfulStrings }) => {
6
+ // ✅ important: operationName is always second word in 'query' query param
7
+ const operationName = url.searchParams.get('query')?.split(' ')[1];
8
+ const actualUrlMeaningfulString = `${url.pathname}/${operationName}`;
9
+ const graphqlUrlSuggestions = graphqlPatternUrlMeaningfulStrings.reduce((acc, patternUrlMeaningfulString) => {
10
+ const distance = (0, getLevenshteinDistance_1.getLevenshteinDistance)(actualUrlMeaningfulString, patternUrlMeaningfulString);
11
+ const tolerance = Math.floor(patternUrlMeaningfulString.length / 2);
12
+ if (distance <= tolerance)
13
+ acc.push(patternUrlMeaningfulString);
14
+ return acc;
15
+ }, []);
16
+ return graphqlUrlSuggestions;
17
+ };
18
+ exports.getGraphqlUrlSuggestions = getGraphqlUrlSuggestions;
@@ -0,0 +1 @@
1
+ export * from './getGraphqlUrlSuggestions';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./getGraphqlUrlSuggestions"), exports);
@@ -0,0 +1 @@
1
+ export declare const getLevenshteinDistance: (a: string, b: string) => number;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /* eslint-disable */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.getLevenshteinDistance = void 0;
5
+ const min = (d0, d1, d2, bx, ay) => d0 < d1 || d2 < d1 ? (d0 > d2 ? d2 + 1 : d0 + 1) : bx === ay ? d1 : d1 + 1;
6
+ const getLevenshteinDistance = (a, b) => {
7
+ if (a === b) {
8
+ return 0;
9
+ }
10
+ if (a.length > b.length) {
11
+ const tmp = a;
12
+ a = b;
13
+ b = tmp;
14
+ }
15
+ let la = a.length;
16
+ let lb = b.length;
17
+ while (la > 0 && a.charCodeAt(la - 1) === b.charCodeAt(lb - 1)) {
18
+ la--;
19
+ lb--;
20
+ }
21
+ let offset = 0;
22
+ while (offset < la && a.charCodeAt(offset) === b.charCodeAt(offset)) {
23
+ offset++;
24
+ }
25
+ la -= offset;
26
+ lb -= offset;
27
+ if (la === 0 || lb < 3) {
28
+ return lb;
29
+ }
30
+ let x = 0;
31
+ let y;
32
+ let d0;
33
+ let d1;
34
+ let d2;
35
+ let d3;
36
+ let dd = 0;
37
+ let dy;
38
+ let ay;
39
+ let bx0;
40
+ let bx1;
41
+ let bx2;
42
+ let bx3;
43
+ const vector = [];
44
+ for (y = 0; y < la; y++) {
45
+ vector.push(y + 1);
46
+ vector.push(a.charCodeAt(offset + y));
47
+ }
48
+ const len = vector.length - 1;
49
+ for (; x < lb - 3;) {
50
+ bx0 = b.charCodeAt(offset + (d0 = x));
51
+ bx1 = b.charCodeAt(offset + (d1 = x + 1));
52
+ bx2 = b.charCodeAt(offset + (d2 = x + 2));
53
+ bx3 = b.charCodeAt(offset + (d3 = x + 3));
54
+ dd = x += 4;
55
+ for (y = 0; y < len; y += 2) {
56
+ dy = vector[y];
57
+ ay = vector[y + 1];
58
+ d0 = min(dy, d0, d1, bx0, ay);
59
+ d1 = min(d0, d1, d2, bx1, ay);
60
+ d2 = min(d1, d2, d3, bx2, ay);
61
+ dd = min(d2, d3, dd, bx3, ay);
62
+ vector[y] = dd;
63
+ d3 = d2;
64
+ d2 = d1;
65
+ d1 = d0;
66
+ d0 = dy;
67
+ }
68
+ }
69
+ for (; x < lb;) {
70
+ bx0 = b.charCodeAt(offset + (d0 = x));
71
+ dd = ++x;
72
+ for (y = 0; y < len; y += 2) {
73
+ dy = vector[y];
74
+ vector[y] = dd = min(dy, d0, dd, bx0, vector[y + 1]);
75
+ d0 = dy;
76
+ }
77
+ }
78
+ return dd;
79
+ };
80
+ exports.getLevenshteinDistance = getLevenshteinDistance;
@@ -0,0 +1,6 @@
1
+ interface GetRestUrlSuggestionsParams {
2
+ url: URL;
3
+ patternUrls: string[];
4
+ }
5
+ export declare const getRestUrlSuggestions: ({ url, patternUrls }: GetRestUrlSuggestionsParams) => string[];
6
+ export {};
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRestUrlSuggestions = void 0;
4
+ const helpers_1 = require("../../../utils/helpers");
5
+ const getLevenshteinDistance_1 = require("../getLevenshteinDistance/getLevenshteinDistance");
6
+ const helpers_2 = require("./helpers");
7
+ const getRestUrlSuggestions = ({ url, patternUrls }) => {
8
+ const actualUrlParts = (0, helpers_1.getUrlParts)(url.pathname);
9
+ const restUrlSuggestions = patternUrls.reduce((acc, patternUrl) => {
10
+ const patternUrlParts = (0, helpers_1.getUrlParts)(patternUrl);
11
+ // ✅ important: ignore patterns with different amount of parts
12
+ if (patternUrlParts.length !== actualUrlParts.length)
13
+ return acc;
14
+ const actualUrlMeaningfulString = (0, helpers_2.getActualRestUrlMeaningfulString)(actualUrlParts, patternUrlParts);
15
+ const patternUrlMeaningfulString = (0, helpers_2.getPatternRestUrlMeaningfulString)(patternUrlParts);
16
+ const tolerance = Math.floor(patternUrlMeaningfulString.length / 2);
17
+ const distance = (0, getLevenshteinDistance_1.getLevenshteinDistance)(actualUrlMeaningfulString, patternUrlMeaningfulString);
18
+ if (distance <= tolerance) {
19
+ // replace param names in pattern with param values from actual url
20
+ const urlSuggestion = patternUrlParts
21
+ .map((_patternUrlPart, index) => {
22
+ if (patternUrlParts[index].startsWith(':'))
23
+ return actualUrlParts[index];
24
+ return patternUrlParts[index];
25
+ })
26
+ .join('/');
27
+ const suggestionWithQueryParams = `/${urlSuggestion}${url.search}`;
28
+ acc.push(suggestionWithQueryParams);
29
+ }
30
+ return acc;
31
+ }, []);
32
+ return restUrlSuggestions;
33
+ };
34
+ exports.getRestUrlSuggestions = getRestUrlSuggestions;
@@ -0,0 +1 @@
1
+ export declare const getActualRestUrlMeaningfulString: (actualUrlParts: string[], patternUrlParts: string[]) => string;