mockapi-msi 2.0.1 → 2.5.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.
- package/LICENSE +164 -164
- package/README.md +357 -120
- package/apiHandlers/myCustomHandler.js +26 -9
- package/main.js +87 -53
- package/modules/HttpException.js +8 -30
- package/modules/banner.js +22 -0
- package/modules/cli.js +110 -107
- package/modules/configWatcher.js +60 -0
- package/modules/configurationParser.js +43 -43
- package/modules/constants.js +95 -95
- package/modules/core.js +381 -111
- package/modules/csv.js +121 -77
- package/modules/log.js +42 -38
- package/modules/moduleProxy.js +51 -54
- package/modules/openApi.js +178 -0
- package/modules/readers.js +42 -42
- package/modules/urlParser.js +53 -22
- package/package.json +38 -20
- package/testdata/data.csv +5 -5
- package/.dockerignore +0 -24
- package/.mockapi-config +0 -48
- package/Dockerfile +0 -8
- package/docker-compose.debug.yml +0 -14
- package/docker-compose.yml +0 -12
package/modules/csv.js
CHANGED
|
@@ -1,78 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
class CSV {
|
|
2
|
+
|
|
3
|
+
constructor(content, properties) {
|
|
4
|
+
this._properties = properties;
|
|
5
|
+
this._currentIndex = properties.startIndex;
|
|
6
|
+
this._data = this._parseCSV(content);
|
|
7
|
+
this._formattedData = [];
|
|
8
|
+
|
|
9
|
+
this._applyFormat(properties.format);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
_parseCSV(content) {
|
|
13
|
+
const rows = [];
|
|
14
|
+
let currentRow = [];
|
|
15
|
+
let currentField = '';
|
|
16
|
+
let insideQuotes = false;
|
|
17
|
+
let i = 0;
|
|
18
|
+
|
|
19
|
+
while (i < content.length) {
|
|
20
|
+
const char = content[i];
|
|
21
|
+
|
|
22
|
+
if (insideQuotes) {
|
|
23
|
+
if (char === '"') {
|
|
24
|
+
if (i + 1 < content.length && content[i + 1] === '"') {
|
|
25
|
+
currentField += '"';
|
|
26
|
+
i += 2;
|
|
27
|
+
} else {
|
|
28
|
+
insideQuotes = false;
|
|
29
|
+
i++;
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
currentField += char;
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
if (char === '"') {
|
|
37
|
+
insideQuotes = true;
|
|
38
|
+
i++;
|
|
39
|
+
} else if (char === ',') {
|
|
40
|
+
currentRow.push(currentField);
|
|
41
|
+
currentField = '';
|
|
42
|
+
i++;
|
|
43
|
+
} else if (char === '\r' && i + 1 < content.length && content[i + 1] === '\n') {
|
|
44
|
+
currentRow.push(currentField);
|
|
45
|
+
currentField = '';
|
|
46
|
+
rows.push(currentRow);
|
|
47
|
+
currentRow = [];
|
|
48
|
+
i += 2;
|
|
49
|
+
} else if (char === '\n' || char === '\r') {
|
|
50
|
+
currentRow.push(currentField);
|
|
51
|
+
currentField = '';
|
|
52
|
+
rows.push(currentRow);
|
|
53
|
+
currentRow = [];
|
|
54
|
+
i++;
|
|
55
|
+
} else {
|
|
56
|
+
currentField += char;
|
|
57
|
+
i++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (currentField || currentRow.length > 0) {
|
|
63
|
+
currentRow.push(currentField);
|
|
64
|
+
rows.push(currentRow);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return rows;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_applyFormat(format) {
|
|
71
|
+
if (typeof this[`_${format}`] === 'function') {
|
|
72
|
+
this[`_${format}`]();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_json() {
|
|
77
|
+
if (this._data.length === 0) return;
|
|
78
|
+
|
|
79
|
+
const propertyNames = this._data[0];
|
|
80
|
+
|
|
81
|
+
for (let i = 1; i < this._data.length; i++) {
|
|
82
|
+
const record = this._data[i];
|
|
83
|
+
const obj = {};
|
|
84
|
+
|
|
85
|
+
for (let j = 0; j < record.length; j++) {
|
|
86
|
+
obj[propertyNames[j]] = record[j];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this._formattedData.push(obj);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_text() {
|
|
94
|
+
this._formattedData = this._data.slice(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_seq() {
|
|
98
|
+
if (this._currentIndex >= this._formattedData.length || this._currentIndex < 0) {
|
|
99
|
+
this._currentIndex = 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const record = this._formattedData[this._currentIndex];
|
|
103
|
+
this._currentIndex++;
|
|
104
|
+
|
|
105
|
+
return record;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
_rand() {
|
|
109
|
+
this._currentIndex = Math.floor(Math.random() * this._formattedData.length);
|
|
110
|
+
return this._formattedData[this._currentIndex];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
read() {
|
|
114
|
+
if (this._currentIndex === -1) {
|
|
115
|
+
return JSON.stringify(this._formattedData);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return JSON.stringify(this[`_${this._properties.direction}`]());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
78
122
|
module.exports = CSV;
|
package/modules/log.js
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
|
-
const constants = require("./constants");
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
1
|
+
const constants = require("./constants");
|
|
2
|
+
|
|
3
|
+
class Log {
|
|
4
|
+
|
|
5
|
+
constructor(logLevel) {
|
|
6
|
+
this._logLevel = logLevel || "verbose";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
_write(message) {
|
|
10
|
+
const date = (new Date()).toISOString();
|
|
11
|
+
console.log(`${date} ${message}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
debug(message) {
|
|
15
|
+
if (this._logLevel === constants.LOG_LEVELS.DEBUG || this._logLevel === constants.LOG_LEVELS.VERBOSE) {
|
|
16
|
+
this._write(`${constants.COLOR.fgYellow}[DEBUG]${constants.COLOR.reset} - ${message}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
error(message) {
|
|
21
|
+
if (this._logLevel === constants.LOG_LEVELS.ERROR || this._logLevel === constants.LOG_LEVELS.VERBOSE) {
|
|
22
|
+
this._write(`${constants.COLOR.fgRed}[ERROR]${constants.COLOR.reset} - ${message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
info(message) {
|
|
27
|
+
if (this._logLevel === constants.LOG_LEVELS.VERBOSE) {
|
|
28
|
+
this._write(`${constants.COLOR.fgYellow}[INFO]${constants.COLOR.reset} - ${message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
detail(message) {
|
|
33
|
+
if (this._logLevel === constants.LOG_LEVELS.VERBOSE) {
|
|
34
|
+
this._write(`${message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
message(message) {
|
|
39
|
+
console.log(message);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
module.exports = Log;
|
package/modules/moduleProxy.js
CHANGED
|
@@ -1,55 +1,52 @@
|
|
|
1
|
-
const constants = require("./constants");
|
|
2
|
-
const HttpException = require('./HttpException');
|
|
3
|
-
|
|
4
|
-
class Proxy {
|
|
5
|
-
|
|
6
|
-
_externalModuleList = {};
|
|
7
|
-
|
|
8
|
-
constructor(externalModulePath, logger) {
|
|
9
|
-
this._externalModuleList = {};
|
|
10
|
-
this._logger = logger;
|
|
11
|
-
this._externalModulePath = externalModulePath;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async load(modules) {
|
|
15
|
-
for (const moduleName in modules) {
|
|
16
|
-
if (Object.hasOwnProperty.call(modules, moduleName)) {
|
|
17
|
-
const moduleFileName = modules[moduleName];
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const modulePath = `${this._externalModulePath}${moduleFileName}.js`;
|
|
21
|
-
|
|
22
|
-
this._logger.info(`Attempting to load module ${moduleName} from ${modulePath}`);
|
|
23
|
-
|
|
24
|
-
const module = await import(modulePath);
|
|
25
|
-
|
|
26
|
-
this._externalModuleList[moduleName] = module;
|
|
27
|
-
|
|
28
|
-
this._logger.info(`Module '${moduleName}' was loaded`);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
this._logger.error(`Module '${moduleName}' failed during loading ${error}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
execute(name, requestInformation, data) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
1
|
+
const constants = require("./constants");
|
|
2
|
+
const HttpException = require('./HttpException');
|
|
3
|
+
|
|
4
|
+
class Proxy {
|
|
5
|
+
|
|
6
|
+
_externalModuleList = {};
|
|
7
|
+
|
|
8
|
+
constructor(externalModulePath, logger) {
|
|
9
|
+
this._externalModuleList = {};
|
|
10
|
+
this._logger = logger;
|
|
11
|
+
this._externalModulePath = externalModulePath;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async load(modules) {
|
|
15
|
+
for (const moduleName in modules) {
|
|
16
|
+
if (Object.hasOwnProperty.call(modules, moduleName)) {
|
|
17
|
+
const moduleFileName = modules[moduleName];
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const modulePath = `${this._externalModulePath}${moduleFileName}.js`;
|
|
21
|
+
|
|
22
|
+
this._logger.info(`Attempting to load module ${moduleName} from ${modulePath}`);
|
|
23
|
+
|
|
24
|
+
const module = await import(modulePath);
|
|
25
|
+
|
|
26
|
+
this._externalModuleList[moduleName] = module;
|
|
27
|
+
|
|
28
|
+
this._logger.info(`Module '${moduleName}' was loaded`);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
this._logger.error(`Module '${moduleName}' failed during loading ${error}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
execute(name, requestInformation, data) {
|
|
37
|
+
const module = this._externalModuleList[name];
|
|
38
|
+
|
|
39
|
+
if (!module) {
|
|
40
|
+
throw new HttpException(constants.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR, `Module ${name} doesn't exist`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
return module.process(requestInformation, data);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new HttpException(constants.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR, `Module ${name} failed. ${error}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
55
52
|
module.exports = Proxy;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const constants = require('./constants');
|
|
3
|
+
|
|
4
|
+
const OPENAPI_VERSION = '3.1.0';
|
|
5
|
+
const DEFAULT_METHODS_FOR_ANY = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
|
|
6
|
+
|
|
7
|
+
const normalizeMethod = (verb) => {
|
|
8
|
+
if (typeof verb !== 'string' || verb.trim() === '') return ['get'];
|
|
9
|
+
|
|
10
|
+
const method = verb.toLowerCase();
|
|
11
|
+
return method === 'any' ? DEFAULT_METHODS_FOR_ANY : [method];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const toOpenApiPath = (endpointPath) => {
|
|
15
|
+
if (typeof endpointPath !== 'string' || endpointPath.trim() === '') return '/';
|
|
16
|
+
return endpointPath.replace(/:([A-Za-z0-9_]+)/g, '{$1}');
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const extractPathParameters = (endpointPath) => {
|
|
20
|
+
if (typeof endpointPath !== 'string' || endpointPath.trim() === '') return [];
|
|
21
|
+
|
|
22
|
+
const pathParameters = endpointPath.match(/:([A-Za-z0-9_]+)/g) || [];
|
|
23
|
+
|
|
24
|
+
return pathParameters.map((parameter) => ({
|
|
25
|
+
name: parameter.substring(1),
|
|
26
|
+
in: 'path',
|
|
27
|
+
required: true,
|
|
28
|
+
schema: { type: 'string' }
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getResponseStatusCode = (endpointConfiguration) => {
|
|
33
|
+
const status = parseInt(endpointConfiguration.responseStatus, 10);
|
|
34
|
+
|
|
35
|
+
if (!Number.isNaN(status) && status >= 100 && status <= 599) {
|
|
36
|
+
return status;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return constants.HTTP_STATUS_CODES.OK;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const buildResponseContent = (contentType) => {
|
|
43
|
+
if (!contentType) return undefined;
|
|
44
|
+
|
|
45
|
+
const isJsonContentType = contentType.toLowerCase().includes('json');
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
[contentType]: {
|
|
49
|
+
schema: isJsonContentType ? {} : { type: 'string' }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const buildOperation = (method, endpointPath, endpointConfiguration) => {
|
|
55
|
+
const responseStatusCode = getResponseStatusCode(endpointConfiguration);
|
|
56
|
+
const responseContentType = endpointConfiguration.responseContentType || constants.DEFAULT_CONTENT_TYPE;
|
|
57
|
+
const responseDescription = http.STATUS_CODES[responseStatusCode] || 'Configured response';
|
|
58
|
+
|
|
59
|
+
const operation = {
|
|
60
|
+
summary: `${method.toUpperCase()} ${toOpenApiPath(endpointPath)}`,
|
|
61
|
+
responses: {
|
|
62
|
+
[responseStatusCode]: {
|
|
63
|
+
description: responseDescription
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const responseContent = buildResponseContent(responseContentType);
|
|
69
|
+
if (responseContent !== undefined) {
|
|
70
|
+
operation.responses[responseStatusCode].content = responseContent;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const parameters = extractPathParameters(endpointPath);
|
|
74
|
+
if (parameters.length > 0) {
|
|
75
|
+
operation.parameters = parameters;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const metadata = {};
|
|
79
|
+
if (endpointConfiguration.data !== undefined) metadata.data = endpointConfiguration.data;
|
|
80
|
+
if (endpointConfiguration.handler !== undefined) metadata.handler = endpointConfiguration.handler;
|
|
81
|
+
if (endpointConfiguration.delay !== undefined) metadata.delay = endpointConfiguration.delay;
|
|
82
|
+
|
|
83
|
+
if (Object.keys(metadata).length > 0) {
|
|
84
|
+
operation['x-mockapi'] = metadata;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return operation;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const buildSpec = (settings, endpointList) => {
|
|
91
|
+
const openApiSettings = settings || {};
|
|
92
|
+
const endpoints = endpointList || {};
|
|
93
|
+
const paths = {};
|
|
94
|
+
|
|
95
|
+
for (const endpointPath in endpoints) {
|
|
96
|
+
if (!Object.hasOwnProperty.call(endpoints, endpointPath)) continue;
|
|
97
|
+
|
|
98
|
+
const endpointConfiguration = endpoints[endpointPath] || {};
|
|
99
|
+
const openApiPath = toOpenApiPath(endpointPath);
|
|
100
|
+
|
|
101
|
+
if (!paths[openApiPath]) {
|
|
102
|
+
paths[openApiPath] = {};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const methods = normalizeMethod(endpointConfiguration.verb);
|
|
106
|
+
for (const method of methods) {
|
|
107
|
+
paths[openApiPath][method] = buildOperation(method, endpointPath, endpointConfiguration);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
openapi: OPENAPI_VERSION,
|
|
113
|
+
info: {
|
|
114
|
+
title: openApiSettings.title || 'MockAPI',
|
|
115
|
+
version: openApiSettings.version || '1.0.0',
|
|
116
|
+
description: openApiSettings.description || 'OpenAPI definition generated from .mockapi-config.'
|
|
117
|
+
},
|
|
118
|
+
servers: [{ url: '/' }],
|
|
119
|
+
paths
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const escapeHtml = (value) => String(value)
|
|
124
|
+
.replace(/&/g, '&')
|
|
125
|
+
.replace(/</g, '<')
|
|
126
|
+
.replace(/>/g, '>')
|
|
127
|
+
.replace(/"/g, '"')
|
|
128
|
+
.replace(/'/g, ''');
|
|
129
|
+
|
|
130
|
+
const escapeJsString = (value) => String(value)
|
|
131
|
+
.replace(/\\/g, '\\\\')
|
|
132
|
+
.replace(/'/g, "\\'");
|
|
133
|
+
|
|
134
|
+
const buildDocsPage = (settings) => {
|
|
135
|
+
const docsSettings = settings || {};
|
|
136
|
+
const title = escapeHtml(docsSettings.title || 'MockAPI');
|
|
137
|
+
const specPath = escapeJsString(docsSettings.specPath || '/openapi.json');
|
|
138
|
+
|
|
139
|
+
return `<!doctype html>
|
|
140
|
+
<html lang="en">
|
|
141
|
+
<head>
|
|
142
|
+
<meta charset="utf-8" />
|
|
143
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
144
|
+
<title>${title} - API Docs</title>
|
|
145
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
|
146
|
+
<style>
|
|
147
|
+
html, body {
|
|
148
|
+
margin: 0;
|
|
149
|
+
background: #f6f8fa;
|
|
150
|
+
}
|
|
151
|
+
#swagger-ui {
|
|
152
|
+
min-height: 100vh;
|
|
153
|
+
}
|
|
154
|
+
</style>
|
|
155
|
+
</head>
|
|
156
|
+
<body>
|
|
157
|
+
<div id="swagger-ui"></div>
|
|
158
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
159
|
+
<script>
|
|
160
|
+
window.onload = function() {
|
|
161
|
+
window.ui = SwaggerUIBundle({
|
|
162
|
+
url: '${specPath}',
|
|
163
|
+
dom_id: '#swagger-ui',
|
|
164
|
+
deepLinking: true,
|
|
165
|
+
presets: [SwaggerUIBundle.presets.apis],
|
|
166
|
+
layout: 'BaseLayout'
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
</script>
|
|
170
|
+
</body>
|
|
171
|
+
</html>`;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
module.exports = {
|
|
175
|
+
buildSpec,
|
|
176
|
+
buildDocsPage,
|
|
177
|
+
toOpenApiPath
|
|
178
|
+
};
|
package/modules/readers.js
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const constants = require("./constants");
|
|
4
|
-
const CSV = require('./csv');
|
|
5
|
-
const HttpException = require('./HttpException');
|
|
6
|
-
|
|
7
|
-
const text_reader = (file) => {
|
|
8
|
-
return () => {
|
|
9
|
-
if (!fs.existsSync(file)) {
|
|
10
|
-
throw new HttpException(constants.HTTP_STATUS_CODES.NOT_FOUND, `File ${file} doesn't exists`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return fs.readFileSync(file, 'utf8');
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const file_exists = (file) => fs.existsSync(file);
|
|
18
|
-
|
|
19
|
-
const folder_reader = (folder) => {
|
|
20
|
-
return (urlInformation) => {
|
|
21
|
-
|
|
22
|
-
if (!urlInformation.hasFile) {
|
|
23
|
-
throw new HttpException(constants.HTTP_STATUS_CODES.NOT_ACCEPTABLE, "File not provided");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const file = path.join(folder, urlInformation.file);
|
|
27
|
-
return text_reader(file)()
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const csv_reader = function (file, parameters) {
|
|
32
|
-
const csvContent = text_reader(file, parameters)();
|
|
33
|
-
const csvReader = new CSV(csvContent, parameters);
|
|
34
|
-
|
|
35
|
-
return csvReader.read.bind(csvReader);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
module.exports = {
|
|
39
|
-
text_reader: text_reader,
|
|
40
|
-
folder_reader: folder_reader,
|
|
41
|
-
csv_reader: csv_reader,
|
|
42
|
-
file_exists: file_exists
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const constants = require("./constants");
|
|
4
|
+
const CSV = require('./csv');
|
|
5
|
+
const HttpException = require('./HttpException');
|
|
6
|
+
|
|
7
|
+
const text_reader = (file) => {
|
|
8
|
+
return () => {
|
|
9
|
+
if (!fs.existsSync(file)) {
|
|
10
|
+
throw new HttpException(constants.HTTP_STATUS_CODES.NOT_FOUND, `File ${file} doesn't exists`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return fs.readFileSync(file, 'utf8');
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const file_exists = (file) => fs.existsSync(file);
|
|
18
|
+
|
|
19
|
+
const folder_reader = (folder) => {
|
|
20
|
+
return (urlInformation) => {
|
|
21
|
+
|
|
22
|
+
if (!urlInformation.hasFile) {
|
|
23
|
+
throw new HttpException(constants.HTTP_STATUS_CODES.NOT_ACCEPTABLE, "File not provided");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const file = path.join(folder, urlInformation.file);
|
|
27
|
+
return text_reader(file)()
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const csv_reader = function (file, parameters) {
|
|
32
|
+
const csvContent = text_reader(file, parameters)();
|
|
33
|
+
const csvReader = new CSV(csvContent, parameters);
|
|
34
|
+
|
|
35
|
+
return csvReader.read.bind(csvReader);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
text_reader: text_reader,
|
|
40
|
+
folder_reader: folder_reader,
|
|
41
|
+
csv_reader: csv_reader,
|
|
42
|
+
file_exists: file_exists
|
|
43
43
|
};
|