@apimatic/cli 1.1.0-alpha.4 → 1.1.0-alpha.6
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/README.md +115 -37
- package/bin/run +5 -1
- package/lib/client-utils/auth-manager.js +3 -3
- package/lib/client-utils/sdk-client.js +1 -0
- package/lib/commands/api/transform.d.ts +7 -7
- package/lib/commands/api/transform.js +18 -15
- package/lib/commands/api/validate.d.ts +4 -4
- package/lib/commands/api/validate.js +13 -10
- package/lib/commands/auth/login.d.ts +2 -2
- package/lib/commands/auth/login.js +29 -12
- package/lib/commands/auth/logout.d.ts +1 -1
- package/lib/commands/auth/logout.js +3 -2
- package/lib/commands/auth/status.d.ts +1 -1
- package/lib/commands/auth/status.js +3 -2
- package/lib/commands/portal/generate.d.ts +6 -6
- package/lib/commands/portal/generate.js +16 -11
- package/lib/commands/portal/quickstart.d.ts +10 -0
- package/lib/commands/portal/quickstart.js +83 -0
- package/lib/commands/portal/serve.d.ts +17 -0
- package/lib/commands/portal/serve.js +143 -0
- package/lib/commands/sdk/generate.d.ts +8 -8
- package/lib/commands/sdk/generate.js +16 -13
- package/lib/config/axios-config.d.ts +2 -0
- package/lib/config/axios-config.js +12 -0
- package/lib/config/env.d.ts +26 -0
- package/lib/config/env.js +28 -1
- package/lib/controllers/api/transform.js +6 -5
- package/lib/controllers/api/validate.d.ts +1 -1
- package/lib/controllers/api/validate.js +25 -8
- package/lib/controllers/portal/generate.d.ts +2 -1
- package/lib/controllers/portal/generate.js +19 -11
- package/lib/controllers/portal/quickstart.d.ts +14 -0
- package/lib/controllers/portal/quickstart.js +206 -0
- package/lib/controllers/portal/serve.d.ts +4 -0
- package/lib/controllers/portal/serve.js +152 -0
- package/lib/controllers/sdk/generate.js +7 -6
- package/lib/index.d.ts +1 -1
- package/lib/index.js +3 -3
- package/lib/prompts/portal/quickstart.d.ts +32 -0
- package/lib/prompts/portal/quickstart.js +216 -0
- package/lib/prompts/portal/serve.d.ts +7 -0
- package/lib/prompts/portal/serve.js +25 -0
- package/lib/services/portal/server.d.ts +11 -0
- package/lib/services/portal/server.js +71 -0
- package/lib/types/api/transform.d.ts +0 -1
- package/lib/types/api/transform.js +1 -0
- package/lib/types/api/validate.js +1 -0
- package/lib/types/portal/generate.js +1 -0
- package/lib/types/portal/quickstart.d.ts +17 -0
- package/lib/types/portal/quickstart.js +3 -0
- package/lib/types/sdk/generate.js +1 -0
- package/lib/types/utils.js +1 -0
- package/lib/utils/utils.d.ts +28 -4
- package/lib/utils/utils.js +289 -53
- package/lib/validators/common/directoryValidator.d.ts +9 -0
- package/lib/validators/common/directoryValidator.js +53 -0
- package/lib/validators/common/portValidator.d.ts +5 -0
- package/lib/validators/common/portValidator.js +20 -0
- package/lib/validators/portal/serveValidator.d.ts +6 -0
- package/lib/validators/portal/serveValidator.js +21 -0
- package/package.json +60 -24
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdHlwZXMvcG9ydGFsL2dlbmVyYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type LoginCredentials = {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
};
|
|
5
|
+
export type SpecFile = {
|
|
6
|
+
filePath: string;
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
export type PortalServerConfig = {
|
|
10
|
+
generatedPortalPath: string;
|
|
11
|
+
targetFolder: string;
|
|
12
|
+
configDir: string;
|
|
13
|
+
authKey: string | null;
|
|
14
|
+
ignoredPaths?: string[];
|
|
15
|
+
port?: number;
|
|
16
|
+
openInBrowser?: boolean;
|
|
17
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpY2tzdGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90eXBlcy9wb3J0YWwvcXVpY2tzdGFydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
|
|
@@ -10,3 +10,4 @@ var SimplePlatforms;
|
|
|
10
10
|
SimplePlatforms["RUBY"] = "RUBY_GENERIC_LIB";
|
|
11
11
|
SimplePlatforms["TYPESCRIPT"] = "TS_GENERIC_LIB";
|
|
12
12
|
})(SimplePlatforms || (exports.SimplePlatforms = SimplePlatforms = {}));
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdHlwZXMvc2RrL2dlbmVyYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWlCQSxJQUFZLGVBT1g7QUFQRCxXQUFZLGVBQWU7SUFDekIsaURBQThCLENBQUE7SUFDOUIsZ0RBQTZCLENBQUE7SUFDN0IsMENBQXVCLENBQUE7SUFDdkIsZ0RBQTZCLENBQUE7SUFDN0IsNENBQXlCLENBQUE7SUFDekIsZ0RBQTZCLENBQUE7QUFDL0IsQ0FBQyxFQVBXLGVBQWUsK0JBQWYsZUFBZSxRQU8xQiJ9
|
package/lib/types/utils.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="mocha" />
|
|
3
1
|
import { loggers, ValidationMessages } from "../types/utils";
|
|
2
|
+
import { ApiValidationSummary } from "@apimatic/sdk";
|
|
4
3
|
export declare const unzipFile: (stream: NodeJS.ReadableStream, destination: string) => Promise<unknown>;
|
|
4
|
+
export declare const createTempDirectory: () => Promise<string>;
|
|
5
|
+
export declare const clearDirectory: (folderPath: string) => Promise<void>;
|
|
6
|
+
export declare const validationMessagesToJson: (validationMessages: ApiValidationSummary) => object;
|
|
7
|
+
interface DirectoryNode {
|
|
8
|
+
[key: string]: DirectoryNode | string | null | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare const directoryToJson: (dirPath: string, parentPath?: string) => DirectoryNode;
|
|
11
|
+
export declare const isValidUrl: (input: string) => boolean;
|
|
5
12
|
export declare const deleteFile: (filePath: string) => Promise<void>;
|
|
6
13
|
export declare const writeFileUsingReadableStream: (stream: NodeJS.ReadableStream, destinationPath: string) => Promise<unknown>;
|
|
14
|
+
export declare const zipDirectoryToStream: (sourcePath: string) => Promise<NodeJS.ReadableStream>;
|
|
7
15
|
/**
|
|
8
16
|
* Packages local files into a ZIP archive
|
|
9
17
|
*
|
|
@@ -12,9 +20,25 @@ export declare const writeFileUsingReadableStream: (stream: NodeJS.ReadableStrea
|
|
|
12
20
|
* return {string}
|
|
13
21
|
*/
|
|
14
22
|
export declare const zipDirectory: (sourcePath: string, destinationPath: string) => Promise<string>;
|
|
15
|
-
export declare const startProgress: (title: string) => void;
|
|
16
|
-
export declare const stopProgress: (isError?: boolean) => void | null;
|
|
17
23
|
export declare const replaceHTML: (string: string) => string;
|
|
18
24
|
export declare const isJSONParsable: (json: string) => boolean;
|
|
19
25
|
export declare const getFileNameFromPath: (filePath: string) => string;
|
|
20
26
|
export declare const printValidationMessages: ({ warnings, errors, messages }: ValidationMessages, { log, warn, error }: loggers) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Extracts a ZIP file to a specified destination directory.
|
|
29
|
+
*
|
|
30
|
+
* @param zipFilePath Path to the ZIP file.
|
|
31
|
+
* @param destinationDir Path to the destination directory where files will be extracted.
|
|
32
|
+
*/
|
|
33
|
+
export declare function extractZipFile(zipFilePath: string, destinationDir: string): Promise<void>;
|
|
34
|
+
export declare function validateAndZipPortalSource(sourceDir: string, outputPath: string, ignoredPaths?: string[]): Promise<string>;
|
|
35
|
+
export declare function cleanUpGeneratedPortalFiles(sourceDir: string): Promise<void>;
|
|
36
|
+
export declare function isPortInUse(port: number): Promise<boolean>;
|
|
37
|
+
export declare const getNonHiddenItemsFromDirectory: (directoryPath: string) => string[];
|
|
38
|
+
export declare const getMessageInOrangeColor: (message: string) => string;
|
|
39
|
+
export declare const getMessageInBlueColor: (message: string) => string;
|
|
40
|
+
export declare const getMessageInCyanColor: (message: string) => string;
|
|
41
|
+
export declare const getMessageInGreenColor: (message: string) => string;
|
|
42
|
+
export declare const getMessageInMagentaColor: (message: string) => string;
|
|
43
|
+
export declare const getMessageInRedColor: (message: string) => string;
|
|
44
|
+
export {};
|
package/lib/utils/utils.js
CHANGED
|
@@ -1,24 +1,127 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.printValidationMessages = exports.getFileNameFromPath = exports.isJSONParsable = exports.replaceHTML = exports.
|
|
4
|
-
|
|
3
|
+
exports.getMessageInRedColor = exports.getMessageInMagentaColor = exports.getMessageInGreenColor = exports.getMessageInCyanColor = exports.getMessageInBlueColor = exports.getMessageInOrangeColor = exports.getNonHiddenItemsFromDirectory = exports.printValidationMessages = exports.getFileNameFromPath = exports.isJSONParsable = exports.replaceHTML = exports.zipDirectory = exports.zipDirectoryToStream = exports.writeFileUsingReadableStream = exports.deleteFile = exports.isValidUrl = exports.directoryToJson = exports.validationMessagesToJson = exports.clearDirectory = exports.createTempDirectory = exports.unzipFile = void 0;
|
|
4
|
+
exports.extractZipFile = extractZipFile;
|
|
5
|
+
exports.validateAndZipPortalSource = validateAndZipPortalSource;
|
|
6
|
+
exports.cleanUpGeneratedPortalFiles = cleanUpGeneratedPortalFiles;
|
|
7
|
+
exports.isPortInUse = isPortInUse;
|
|
8
|
+
const net = require("net");
|
|
5
9
|
const path = require("path");
|
|
6
10
|
const fs = require("fs-extra");
|
|
11
|
+
const os = require("os");
|
|
7
12
|
const archiver = require("archiver");
|
|
8
13
|
const unzipper = require("unzipper");
|
|
9
14
|
const stripTags = require("striptags");
|
|
15
|
+
const stream_1 = require("stream");
|
|
16
|
+
const AdmZip = require("adm-zip");
|
|
10
17
|
const unzipFile = (stream, destination) => {
|
|
11
18
|
return new Promise((resolve, reject) => {
|
|
12
|
-
|
|
13
|
-
stream
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
+
const extractStream = unzipper.Extract({ path: destination });
|
|
20
|
+
stream
|
|
21
|
+
.pipe(extractStream)
|
|
22
|
+
.on("error", (error) => reject(new Error("Error during extraction: " + error.message)));
|
|
23
|
+
extractStream.on("close", () => resolve("Extracted"));
|
|
24
|
+
extractStream.on("error", (error) => reject(new Error("Error during extraction: " + error.message)));
|
|
19
25
|
});
|
|
20
26
|
};
|
|
21
27
|
exports.unzipFile = unzipFile;
|
|
28
|
+
const createTempDirectory = async () => {
|
|
29
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "apimatic-cli-"));
|
|
30
|
+
};
|
|
31
|
+
exports.createTempDirectory = createTempDirectory;
|
|
32
|
+
const clearDirectory = async (folderPath) => {
|
|
33
|
+
if (!fs.existsSync(folderPath)) {
|
|
34
|
+
throw new Error(`Directory ${folderPath} does not exist`);
|
|
35
|
+
}
|
|
36
|
+
const files = await fs.readdir(folderPath);
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
const filePath = path.join(folderPath, file);
|
|
39
|
+
await (0, exports.deleteFile)(filePath);
|
|
40
|
+
}
|
|
41
|
+
await (0, exports.deleteFile)(folderPath);
|
|
42
|
+
};
|
|
43
|
+
exports.clearDirectory = clearDirectory;
|
|
44
|
+
const validationMessagesToJson = (validationMessages) => {
|
|
45
|
+
const structuredValidationMessages = {
|
|
46
|
+
"Validation Messages": {
|
|
47
|
+
Errors: [],
|
|
48
|
+
Warnings: [],
|
|
49
|
+
Messages: []
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
if (validationMessages.errors) {
|
|
53
|
+
validationMessages.errors.forEach((error) => {
|
|
54
|
+
structuredValidationMessages["Validation Messages"]["Errors"].push((0, exports.replaceHTML)(error));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (validationMessages.warnings) {
|
|
58
|
+
validationMessages.warnings.forEach((warning) => {
|
|
59
|
+
structuredValidationMessages["Validation Messages"]["Warnings"].push((0, exports.replaceHTML)(warning));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (validationMessages.messages) {
|
|
63
|
+
validationMessages.messages.forEach((message) => {
|
|
64
|
+
structuredValidationMessages["Validation Messages"]["Messages"].push((0, exports.replaceHTML)(message));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return structuredValidationMessages;
|
|
68
|
+
};
|
|
69
|
+
exports.validationMessagesToJson = validationMessagesToJson;
|
|
70
|
+
const descriptions = Object.entries({
|
|
71
|
+
"APIMATIC-BUILD.json": "# Defines all configurations for the API portal, including programming languages and themes",
|
|
72
|
+
spec: "# Contains all API definition files",
|
|
73
|
+
content: "# Includes custom documentation pages in Markdown",
|
|
74
|
+
"content/toc.yml": "# Controls the structure of the side navigation bar in the API portal",
|
|
75
|
+
static: "# Includes all static files, such as images, GIFs, and PDFs"
|
|
76
|
+
}).reduce((acc, [key, value]) => {
|
|
77
|
+
acc[path.normalize(key)] = value;
|
|
78
|
+
return acc;
|
|
79
|
+
}, {});
|
|
80
|
+
const directoryToJson = (dirPath, parentPath = "") => {
|
|
81
|
+
const directoryStructure = {};
|
|
82
|
+
const items = fs.readdirSync(dirPath);
|
|
83
|
+
items.forEach((item) => {
|
|
84
|
+
if (item === ".git")
|
|
85
|
+
return; // Skip .git directory
|
|
86
|
+
const itemPath = path.join(dirPath, item);
|
|
87
|
+
const relativePath = path.join(parentPath, item);
|
|
88
|
+
const stats = fs.statSync(itemPath);
|
|
89
|
+
if (stats.isDirectory()) {
|
|
90
|
+
const subdirectoryStructure = (0, exports.directoryToJson)(itemPath, relativePath);
|
|
91
|
+
const folderName = descriptions[path.normalize(relativePath)]
|
|
92
|
+
? `${item} : ${descriptions[path.normalize(relativePath)]}`
|
|
93
|
+
: item;
|
|
94
|
+
directoryStructure[folderName] = subdirectoryStructure;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
directoryStructure[descriptions[path.normalize(relativePath)] ? `${item} : ${descriptions[path.normalize(relativePath)]}` : item] = null;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return directoryStructure;
|
|
101
|
+
};
|
|
102
|
+
exports.directoryToJson = directoryToJson;
|
|
103
|
+
const isValidUrl = (input) => {
|
|
104
|
+
if (!input) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const url = new URL(input);
|
|
109
|
+
if (!["http:", "https:"].includes(url.protocol)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (url.protocol === "file:" || fs.existsSync(input)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (!url.host) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
catch (_) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.isValidUrl = isValidUrl;
|
|
22
125
|
const deleteFile = async (filePath) => {
|
|
23
126
|
return await fs.remove(filePath);
|
|
24
127
|
};
|
|
@@ -36,6 +139,22 @@ const writeFileUsingReadableStream = (stream, destinationPath) => {
|
|
|
36
139
|
});
|
|
37
140
|
};
|
|
38
141
|
exports.writeFileUsingReadableStream = writeFileUsingReadableStream;
|
|
142
|
+
const zipDirectoryToStream = async (sourcePath) => {
|
|
143
|
+
// Check if the directory exists for the user or not
|
|
144
|
+
await fs.ensureDir(sourcePath);
|
|
145
|
+
const archive = archiver("zip");
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
archive.on("error", (err) => {
|
|
148
|
+
reject(new Error(err.message));
|
|
149
|
+
});
|
|
150
|
+
const passThroughStream = new stream_1.PassThrough();
|
|
151
|
+
archive.pipe(passThroughStream);
|
|
152
|
+
archive.directory(sourcePath, false);
|
|
153
|
+
archive.finalize().catch(reject);
|
|
154
|
+
resolve(passThroughStream);
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
exports.zipDirectoryToStream = zipDirectoryToStream;
|
|
39
158
|
/**
|
|
40
159
|
* Packages local files into a ZIP archive
|
|
41
160
|
*
|
|
@@ -49,53 +168,22 @@ const zipDirectory = async (sourcePath, destinationPath) => {
|
|
|
49
168
|
const zipPath = path.join(destinationPath, "target.zip");
|
|
50
169
|
const output = fs.createWriteStream(zipPath);
|
|
51
170
|
const archive = archiver("zip");
|
|
52
|
-
|
|
53
|
-
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
archive.on("error", (err) => {
|
|
173
|
+
reject(new Error(err.message));
|
|
174
|
+
});
|
|
175
|
+
output.on("error", (err) => {
|
|
176
|
+
reject(new Error(err.message));
|
|
177
|
+
});
|
|
178
|
+
output.on("close", () => {
|
|
179
|
+
resolve(zipPath);
|
|
180
|
+
});
|
|
181
|
+
archive.pipe(output);
|
|
182
|
+
archive.directory(sourcePath, false);
|
|
183
|
+
archive.finalize().catch(reject);
|
|
54
184
|
});
|
|
55
|
-
archive.pipe(output);
|
|
56
|
-
// append files from a sub-directory, putting its contents at the root of archive
|
|
57
|
-
archive.directory(sourcePath, false);
|
|
58
|
-
await archive.finalize();
|
|
59
|
-
return zipPath;
|
|
60
185
|
};
|
|
61
186
|
exports.zipDirectory = zipDirectory;
|
|
62
|
-
// TODO: Instead of making progressBar a static, you should have "startProgress"
|
|
63
|
-
// return the instance of the progress bar created, the same way "cli.progress"
|
|
64
|
-
// method does.
|
|
65
|
-
let progressBar;
|
|
66
|
-
// TODO: I didn't mean to say that we should create a fake progress bar when we
|
|
67
|
-
// set the requirements to include progress bar. You should get the download or
|
|
68
|
-
// upload progress by tracking how much of the steam has been read/written and
|
|
69
|
-
// compare that with the remaining size of the stream (in case of upload, you
|
|
70
|
-
// get size from the file size and in case of download, you get it from the
|
|
71
|
-
// content-type header). In case the progress can not be calculated, show a
|
|
72
|
-
// spinner.
|
|
73
|
-
const startProgress = (title) => {
|
|
74
|
-
progressBar = cli_ux_1.default.progress({
|
|
75
|
-
format: `${title} | {bar}`,
|
|
76
|
-
barCompleteChar: "\u2588",
|
|
77
|
-
barIncompleteChar: "\u2591"
|
|
78
|
-
});
|
|
79
|
-
progressBar.start();
|
|
80
|
-
const total = 100;
|
|
81
|
-
let count = 0;
|
|
82
|
-
const iv = setInterval(() => {
|
|
83
|
-
count++;
|
|
84
|
-
progressBar.update(count);
|
|
85
|
-
if (count === total - 1) {
|
|
86
|
-
clearInterval(iv);
|
|
87
|
-
}
|
|
88
|
-
}, 50);
|
|
89
|
-
};
|
|
90
|
-
exports.startProgress = startProgress;
|
|
91
|
-
const stopProgress = (isError = false) => {
|
|
92
|
-
if (isError) {
|
|
93
|
-
return progressBar ? progressBar.stop() : null;
|
|
94
|
-
}
|
|
95
|
-
progressBar.update(100);
|
|
96
|
-
return progressBar.stop();
|
|
97
|
-
};
|
|
98
|
-
exports.stopProgress = stopProgress;
|
|
99
187
|
const replaceHTML = (string) => {
|
|
100
188
|
return stripTags(string);
|
|
101
189
|
};
|
|
@@ -129,3 +217,151 @@ const printValidationMessages = ({ warnings, errors, messages }, { log, warn, er
|
|
|
129
217
|
}
|
|
130
218
|
};
|
|
131
219
|
exports.printValidationMessages = printValidationMessages;
|
|
220
|
+
/**
|
|
221
|
+
* Extracts a ZIP file to a specified destination directory.
|
|
222
|
+
*
|
|
223
|
+
* @param zipFilePath Path to the ZIP file.
|
|
224
|
+
* @param destinationDir Path to the destination directory where files will be extracted.
|
|
225
|
+
*/
|
|
226
|
+
async function extractZipFile(zipFilePath, destinationDir) {
|
|
227
|
+
const MAX_ZIP_SIZE = 300 * 1024 * 1024;
|
|
228
|
+
return new Promise((resolve, reject) => {
|
|
229
|
+
try {
|
|
230
|
+
const zip = new AdmZip(zipFilePath);
|
|
231
|
+
const zipEntries = zip.getEntries();
|
|
232
|
+
let totalSize = 0;
|
|
233
|
+
zipEntries.forEach((entry) => {
|
|
234
|
+
totalSize += entry.getData().length;
|
|
235
|
+
const normalizedPath = path.normalize(entry.entryName);
|
|
236
|
+
if (normalizedPath.startsWith("..") || path.isAbsolute(normalizedPath)) {
|
|
237
|
+
return reject(new Error(`Blocked potentially unsafe path: ${normalizedPath}`));
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
if (totalSize > MAX_ZIP_SIZE) {
|
|
241
|
+
return reject(new Error((0, exports.getMessageInRedColor)("Archive size is too large for safe extraction.")));
|
|
242
|
+
}
|
|
243
|
+
if (!fs.existsSync(destinationDir)) {
|
|
244
|
+
fs.mkdirSync(destinationDir, { recursive: true });
|
|
245
|
+
}
|
|
246
|
+
zipEntries.forEach((entry) => {
|
|
247
|
+
const resolvedPath = path.resolve(destinationDir, entry.entryName);
|
|
248
|
+
if (!resolvedPath.startsWith(path.resolve(destinationDir))) {
|
|
249
|
+
return reject(new Error("An error occurred while extracting zip file."));
|
|
250
|
+
}
|
|
251
|
+
zip.extractEntryTo(entry, destinationDir, true, true);
|
|
252
|
+
});
|
|
253
|
+
resolve();
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
return reject(new Error(`Failed to extract ZIP File: ${error}`));
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
async function validateAndZipPortalSource(sourceDir, outputPath, ignoredPaths = []) {
|
|
261
|
+
const output = fs.createWriteStream(outputPath);
|
|
262
|
+
const archive = archiver("zip", {
|
|
263
|
+
zlib: { level: 9 }
|
|
264
|
+
});
|
|
265
|
+
const items = await fs.readdir(sourceDir);
|
|
266
|
+
if (!items.some((item) => item.startsWith("APIMATIC-BUILD"))) {
|
|
267
|
+
throw new Error("APIMatic Build file is missing, portal cannot be generated. Please specify a valid APIMatic build file and try again.");
|
|
268
|
+
}
|
|
269
|
+
return new Promise((resolve, reject) => {
|
|
270
|
+
output.on("close", () => resolve(outputPath));
|
|
271
|
+
output.on("error", (err) => {
|
|
272
|
+
return reject(new Error(`Failed to zip the source directory: ${err.message}`));
|
|
273
|
+
});
|
|
274
|
+
archive.on("error", (err) => {
|
|
275
|
+
return reject(new Error(`Failed to zip the source directory: ${err.message}`));
|
|
276
|
+
});
|
|
277
|
+
archive.pipe(output);
|
|
278
|
+
// Function to recursively add files and directories to the archive, excluding ignored paths
|
|
279
|
+
const addItemsToArchive = async (currentPath, archivePath) => {
|
|
280
|
+
const items = await fs.readdir(currentPath);
|
|
281
|
+
for (const item of items) {
|
|
282
|
+
const fullPath = path.join(currentPath, item);
|
|
283
|
+
const relativePath = path.relative(sourceDir, fullPath);
|
|
284
|
+
// Check if the path is ignored.
|
|
285
|
+
const isIgnored = ignoredPaths.some((ignoredPath) => fullPath === ignoredPath ||
|
|
286
|
+
relativePath === ignoredPath ||
|
|
287
|
+
fullPath === path.resolve(ignoredPath) ||
|
|
288
|
+
relativePath.startsWith(ignoredPath + "/") ||
|
|
289
|
+
relativePath.startsWith(ignoredPath + "\\"));
|
|
290
|
+
if (!isIgnored) {
|
|
291
|
+
const stats = await fs.stat(fullPath);
|
|
292
|
+
if (stats.isDirectory()) {
|
|
293
|
+
await addItemsToArchive(fullPath, archivePath ? path.join(archivePath, item) : item);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
archive.file(fullPath, { name: archivePath ? path.join(archivePath, item) : item });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
// Start adding items from the source directory
|
|
302
|
+
addItemsToArchive(sourceDir, false)
|
|
303
|
+
.then(() => {
|
|
304
|
+
archive.finalize();
|
|
305
|
+
})
|
|
306
|
+
.catch((err) => {
|
|
307
|
+
return reject(new Error(`Failed to add items to the zip created for source directory: ${err.message}`));
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
async function cleanUpGeneratedPortalFiles(sourceDir) {
|
|
312
|
+
const generatedPortalZipFilePath = path.join(sourceDir, "generated_portal.zip");
|
|
313
|
+
const generatedPortalSourceZipFilePath = path.join(sourceDir, "portal_source.zip");
|
|
314
|
+
if (fs.existsSync(generatedPortalZipFilePath)) {
|
|
315
|
+
await (0, exports.deleteFile)(generatedPortalZipFilePath);
|
|
316
|
+
}
|
|
317
|
+
if (fs.existsSync(generatedPortalSourceZipFilePath)) {
|
|
318
|
+
await (0, exports.deleteFile)(generatedPortalSourceZipFilePath);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function isPortInUse(port) {
|
|
322
|
+
return new Promise((resolve) => {
|
|
323
|
+
const server = net.createServer();
|
|
324
|
+
server.once("error", (err) => {
|
|
325
|
+
if (err.code === "EADDRINUSE") {
|
|
326
|
+
resolve(true);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
resolve(false);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
server.once("listening", () => {
|
|
333
|
+
server.close();
|
|
334
|
+
resolve(false);
|
|
335
|
+
});
|
|
336
|
+
server.listen(port);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const getNonHiddenItemsFromDirectory = (directoryPath) => {
|
|
340
|
+
return fs.readdirSync(directoryPath).filter((item) => !item.startsWith("."));
|
|
341
|
+
};
|
|
342
|
+
exports.getNonHiddenItemsFromDirectory = getNonHiddenItemsFromDirectory;
|
|
343
|
+
const getMessageInOrangeColor = (message) => {
|
|
344
|
+
return `\u001b[33m${message}\u001b[0m`;
|
|
345
|
+
};
|
|
346
|
+
exports.getMessageInOrangeColor = getMessageInOrangeColor;
|
|
347
|
+
const getMessageInBlueColor = (message) => {
|
|
348
|
+
return `\u001b[34m${message}\u001b[0m`;
|
|
349
|
+
};
|
|
350
|
+
exports.getMessageInBlueColor = getMessageInBlueColor;
|
|
351
|
+
const getMessageInCyanColor = (message) => {
|
|
352
|
+
return `\u001b[36m${message}\u001b[0m`;
|
|
353
|
+
};
|
|
354
|
+
exports.getMessageInCyanColor = getMessageInCyanColor;
|
|
355
|
+
const getMessageInGreenColor = (message) => {
|
|
356
|
+
return `\u001b[32m${message}\u001b[0m`;
|
|
357
|
+
};
|
|
358
|
+
exports.getMessageInGreenColor = getMessageInGreenColor;
|
|
359
|
+
const getMessageInMagentaColor = (message) => {
|
|
360
|
+
return `\u001b[35m${message}\u001b[0m`;
|
|
361
|
+
};
|
|
362
|
+
exports.getMessageInMagentaColor = getMessageInMagentaColor;
|
|
363
|
+
const getMessageInRedColor = (message) => {
|
|
364
|
+
return `\u001b[31m${message}\u001b[0m`;
|
|
365
|
+
};
|
|
366
|
+
exports.getMessageInRedColor = getMessageInRedColor;
|
|
367
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBbVFBLHdDQXdDQztBQUVELGdFQW1FQztBQUVELGtFQVNDO0FBRUQsa0NBbUJDO0FBaFpELDJCQUEyQjtBQUMzQiw2QkFBNkI7QUFDN0IsK0JBQStCO0FBQy9CLHlCQUF5QjtBQUN6QixxQ0FBcUM7QUFDckMscUNBQXFDO0FBQ3JDLHVDQUF1QztBQUN2QyxtQ0FBcUM7QUFDckMsa0NBQW1DO0FBSzVCLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBNkIsRUFBRSxXQUFtQixFQUFFLEVBQUU7SUFDOUUsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFFOUQsTUFBTTthQUNILElBQUksQ0FBQyxhQUFhLENBQUM7YUFDbkIsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQVksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDJCQUEyQixHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFakcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsYUFBYSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFZLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlHLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBWFcsUUFBQSxTQUFTLGFBV3BCO0FBRUssTUFB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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class DirectoryValidator {
|
|
2
|
+
private readonly error;
|
|
3
|
+
constructor(error: (message: string) => void);
|
|
4
|
+
validateSourceDirectory(sourceDir: string): void;
|
|
5
|
+
validateGeneratedPortalDestinationDirectory(destinationDir: string, portalDir: string): Promise<void>;
|
|
6
|
+
validatePortalSourceDirectory(sourceDir: string): void;
|
|
7
|
+
validatePortalSourceSpecDirectory(sourceDir: string): void;
|
|
8
|
+
validateGeneratedPortalDestinationDirectoryIsEmpty(destinationDir: string): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DirectoryValidator = void 0;
|
|
4
|
+
const fs = require("fs-extra");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const utils_1 = require("../../utils/utils");
|
|
7
|
+
class DirectoryValidator {
|
|
8
|
+
constructor(error) {
|
|
9
|
+
this.error = error;
|
|
10
|
+
}
|
|
11
|
+
validateSourceDirectory(sourceDir) {
|
|
12
|
+
if (!fs.pathExistsSync(sourceDir)) {
|
|
13
|
+
this.error((0, utils_1.getMessageInRedColor)(`The specified source directory does not exist: ${sourceDir}. Please provide a valid source directory to continue.`));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async validateGeneratedPortalDestinationDirectory(destinationDir, portalDir) {
|
|
17
|
+
if (!fs.pathExistsSync(destinationDir) && destinationDir != "./api-portal") {
|
|
18
|
+
this.error((0, utils_1.getMessageInRedColor)(`The specified destination directory does not exist: ${destinationDir}. Please provide a valid destination directory to continue.`));
|
|
19
|
+
}
|
|
20
|
+
if (destinationDir == "./api-portal") {
|
|
21
|
+
await fs.ensureDir(portalDir);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
validatePortalSourceDirectory(sourceDir) {
|
|
25
|
+
const sourceDirItems = (0, utils_1.getNonHiddenItemsFromDirectory)(sourceDir);
|
|
26
|
+
if (sourceDirItems.length == 0) {
|
|
27
|
+
this.error((0, utils_1.getMessageInRedColor)("The source directory is empty. Please ensure that the provided path points to a directory containing a valid build input."));
|
|
28
|
+
}
|
|
29
|
+
if (!sourceDirItems.includes("spec")) {
|
|
30
|
+
this.error((0, utils_1.getMessageInRedColor)("The provided build directory is missing a ‘spec’ directory. Please create a ‘spec’ directory containing a valid API Definition file to continue."));
|
|
31
|
+
}
|
|
32
|
+
if (!sourceDirItems.some((item) => item.startsWith("APIMATIC-BUILD"))) {
|
|
33
|
+
this.error((0, utils_1.getMessageInRedColor)("The provided directory is missing an APIMATIC-BUILD.json file. Please add a valid build file to continue."));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
validatePortalSourceSpecDirectory(sourceDir) {
|
|
37
|
+
const specFolderItems = (0, utils_1.getNonHiddenItemsFromDirectory)(path.join(sourceDir, "spec"));
|
|
38
|
+
if (specFolderItems.length == 0) {
|
|
39
|
+
this.error((0, utils_1.getMessageInRedColor)("The provided build directory is missing an API Definition file. Please add a valid API Definition file to the ‘spec’ directory to continue."));
|
|
40
|
+
}
|
|
41
|
+
if (specFolderItems.length == 1 && specFolderItems.some((item) => item.toLowerCase().startsWith("apimatic-meta"))) {
|
|
42
|
+
this.error((0, utils_1.getMessageInRedColor)("The provided build directory is missing an API Definition file. Please add a valid API Definition file to the ‘spec’ directory to continue."));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
validateGeneratedPortalDestinationDirectoryIsEmpty(destinationDir) {
|
|
46
|
+
const portalDirItems = (0, utils_1.getNonHiddenItemsFromDirectory)(destinationDir);
|
|
47
|
+
if (portalDirItems.length > 0 && destinationDir != "./api-portal") {
|
|
48
|
+
this.error((0, utils_1.getMessageInRedColor)("The destination directory is not empty. Please specify an empty destination directory or empty the provided directory."));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.DirectoryValidator = DirectoryValidator;
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0b3J5VmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3ZhbGlkYXRvcnMvY29tbW9uL2RpcmVjdG9yeVZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsNkJBQTZCO0FBQzdCLDZDQUF5RjtBQUV6RixNQUFhLGtCQUFrQjtJQUM3QixZQUE2QixLQUFnQztRQUFoQyxVQUFLLEdBQUwsS0FBSyxDQUEyQjtJQUFHLENBQUM7SUFFakUsdUJBQXVCLENBQUMsU0FBaUI7UUFDdkMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUEsNEJBQW9CLEVBQUMsa0RBQWtELFNBQVMsd0RBQXdELENBQUMsQ0FBQyxDQUFDO1FBQ3hKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLDJDQUEyQyxDQUFDLGNBQXNCLEVBQUUsU0FBaUI7UUFDekYsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLElBQUksY0FBYyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQzNFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBQSw0QkFBb0IsRUFBQyx1REFBdUQsY0FBYyw2REFBNkQsQ0FBQyxDQUFDLENBQUM7UUFDdkssQ0FBQztRQUVELElBQUksY0FBYyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVELDZCQUE2QixDQUFDLFNBQWlCO1FBQzdDLE1BQU0sY0FBYyxHQUFHLElBQUEsc0NBQThCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDakUsSUFBSSxjQUFjLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBQSw0QkFBb0IsRUFBQywySEFBMkgsQ0FBQyxDQUFDLENBQUM7UUFDaEssQ0FBQztRQUNELElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLEtBQUssQ0FDUixJQUFBLDRCQUFvQixFQUFDLGtKQUFrSixDQUFDLENBQ3pLLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDdEUsSUFBSSxDQUFDLEtBQUssQ0FDUixJQUFBLDRCQUFvQixFQUNsQiwyR0FBMkcsQ0FDNUcsQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxpQ0FBaUMsQ0FBQyxTQUFpQjtRQUNqRCxNQUFNLGVBQWUsR0FBRyxJQUFBLHNDQUE4QixFQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDckYsSUFBSSxlQUFlLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxLQUFLLENBQ1IsSUFBQSw0QkFBb0IsRUFBQyw2SUFBNkksQ0FBQyxDQUNwSyxDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksZUFBZSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDbEgsSUFBSSxDQUFDLEtBQUssQ0FDUixJQUFBLDRCQUFvQixFQUNsQiw2SUFBNkksQ0FDOUksQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxrREFBa0QsQ0FBQyxjQUFzQjtRQUN2RSxNQUFNLGNBQWMsR0FBRyxJQUFBLHNDQUE4QixFQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksY0FBYyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLENBQ1IsSUFBQSw0QkFBb0IsRUFDbEIsd0hBQXdILENBQ3pILENBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFoRUQsZ0RBZ0VDIn0=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PortValidator = void 0;
|
|
4
|
+
const utils_1 = require("../../utils/utils");
|
|
5
|
+
class PortValidator {
|
|
6
|
+
constructor(error) {
|
|
7
|
+
this.error = error;
|
|
8
|
+
}
|
|
9
|
+
async validate(port) {
|
|
10
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
11
|
+
this.error((0, utils_1.getMessageInRedColor)("The specified port number is invalid. Please enter a valid port."));
|
|
12
|
+
}
|
|
13
|
+
const portInUse = await (0, utils_1.isPortInUse)(port);
|
|
14
|
+
if (portInUse) {
|
|
15
|
+
this.error((0, utils_1.getMessageInRedColor)(`Port ${port} is already in use. Please provide an alternative port number to continue.`));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.PortValidator = PortValidator;
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydFZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy92YWxpZGF0b3JzL2NvbW1vbi9wb3J0VmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFzRTtBQUV0RSxNQUFhLGFBQWE7SUFDeEIsWUFBNkIsS0FBZ0M7UUFBaEMsVUFBSyxHQUFMLEtBQUssQ0FBMkI7SUFBRyxDQUFDO0lBRWpFLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBWTtRQUN6QixJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUEsNEJBQW9CLEVBQUMsa0VBQWtFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZHLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUEsbUJBQVcsRUFBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFBLDRCQUFvQixFQUFDLFFBQVEsSUFBSSw0RUFBNEUsQ0FBQyxDQUFDLENBQUM7UUFDN0gsQ0FBQztJQUNILENBQUM7Q0FDRjtBQWJELHNDQWFDIn0=
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PortalServeValidator = void 0;
|
|
4
|
+
const directoryValidator_1 = require("../common/directoryValidator");
|
|
5
|
+
const portValidator_1 = require("../common/portValidator");
|
|
6
|
+
class PortalServeValidator {
|
|
7
|
+
constructor(error) {
|
|
8
|
+
this.portValidator = new portValidator_1.PortValidator(error);
|
|
9
|
+
this.directoryValidator = new directoryValidator_1.DirectoryValidator(error);
|
|
10
|
+
}
|
|
11
|
+
async validate(port, destination, sourceDir, portalDir) {
|
|
12
|
+
await this.portValidator.validate(port);
|
|
13
|
+
this.directoryValidator.validateSourceDirectory(sourceDir);
|
|
14
|
+
await this.directoryValidator.validateGeneratedPortalDestinationDirectory(destination, portalDir);
|
|
15
|
+
this.directoryValidator.validatePortalSourceDirectory(sourceDir);
|
|
16
|
+
this.directoryValidator.validatePortalSourceSpecDirectory(sourceDir);
|
|
17
|
+
this.directoryValidator.validateGeneratedPortalDestinationDirectoryIsEmpty(destination);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.PortalServeValidator = PortalServeValidator;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVWYWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdmFsaWRhdG9ycy9wb3J0YWwvc2VydmVWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQWtFO0FBQ2xFLDJEQUF3RDtBQUV4RCxNQUFhLG9CQUFvQjtJQUkvQixZQUFZLEtBQWdDO1FBQzFDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSw2QkFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLHVDQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUSxDQUFDLElBQVksRUFBRSxXQUFtQixFQUFFLFNBQWlCLEVBQUUsU0FBaUI7UUFDcEYsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsMkNBQTJDLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2xHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyw2QkFBNkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsaUNBQWlDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGtEQUFrRCxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzFGLENBQUM7Q0FDRjtBQWpCRCxvREFpQkMifQ==
|