-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathtransform.ts
122 lines (110 loc) · 5.72 KB
/
transform.ts
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as path from "path";
import * as fs from "fs-extra";
import { Flags, Command } from "@oclif/core";
import { TransformationController, Transformation, Client, ApiError, ExportFormats } from "@apimatic/sdk";
import { AuthenticationError, loggers } from "../../types/utils";
import { SDKClient } from "../../client-utils/sdk-client";
import { printValidationMessages } from "../../utils/utils";
import { getFileNameFromPath, replaceHTML } from "../../utils/utils";
import { DestinationFormats } from "../../types/api/transform";
import { getValidFormat, getTransformationId, downloadTransformationFile } from "../../controllers/api/transform";
const formats: string = Object.keys(ExportFormats).join("|");
export default class Transform extends Command {
static description = `Transform API specifications from one format to another. Supports [10+ different formats](https://www.apimatic.io/transformer/#supported-formats) including OpenApi/Swagger, RAML, WSDL and Postman Collections.`;
static examples = [
`$ apimatic api:transform --format="OpenApi3Json" --file="./specs/sample.json" --destination="D:/"
Success! Your transformed file is located at D:/Transformed_OpenApi3Json.json
`,
`$ apimatic api:transform --format=RAML --url="https://petstore.swagger.io/v2/swagger.json" --destination="D:/"
Success! Your transformed file is located at D:/swagger_raml.yaml
`
];
static flags = {
format: Flags.string({
parse: async (format: string) => getValidFormat(format.toUpperCase()),
required: true,
description: `specification format to transform API specification into
${formats}`
}),
file: Flags.string({
parse: async (input) => path.resolve(input),
default: "",
description: "path to the API specification file to transform"
}),
url: Flags.string({
default: "",
description:
"URL to the API specification file to transform. Can be used in place of the --file option if the API specification is publicly available."
}),
destination: Flags.string({
parse: async (input) => path.resolve(input),
default: path.resolve("./"),
description: "directory to download transformed file to"
}),
force: Flags.boolean({ char: "f", default: false, description: "overwrite if same file exist in the destination" }),
"auth-key": Flags.string({ description: "override current authentication state with an authentication key" })
};
async run() {
const { flags } = await this.parse(Transform);
const fileName = flags.file ? getFileNameFromPath(flags.file) : getFileNameFromPath(flags.url);
const destinationFormat: string = DestinationFormats[flags.format as keyof typeof DestinationFormats];
const destinationFilePath: string = path.join(
flags.destination,
`${fileName}_${flags.format}.${destinationFormat}`.toLowerCase()
);
// Check if destination file already exist and throw error if force flag is not set
if (fs.existsSync(destinationFilePath) && !flags.force) {
throw new Error(`Can't download transformed file to path ${destinationFilePath}, because it already exists`);
}
try {
// Check if paths provided are valid
if (flags.file && !(await fs.pathExists(flags.file))) {
throw new Error(`Transformation file: ${flags.file} does not exist`);
} else if (!(await fs.pathExists(flags.destination))) {
throw new Error(`Destination path: ${flags.destination} does not exist`);
}
const overrideAuthKey = flags["auth-key"] ? flags["auth-key"] : null;
const client: Client = await SDKClient.getInstance().getClient(overrideAuthKey, this.config.configDir);
const transformationController: TransformationController = new TransformationController(client);
const { id, apiValidationSummary }: Transformation = await getTransformationId(flags, transformationController);
const logFunctions: loggers = {
log: (message) => this.log(message),
warn: (message) => this.warn(message),
error: (message) => this.error(message)
};
printValidationMessages(apiValidationSummary, logFunctions);
const savedTransformationFile: string = await downloadTransformationFile({
id,
destinationFilePath,
transformationController
});
this.log(`Success! Your transformed file is located at ${savedTransformationFile}`);
} catch (error) {
if ((error as ApiError).result) {
const apiError = error as ApiError;
// TODO: Hopefully, this type-cast won't be necessary when the SDK is
// updated to throw the right exception type for this status code.
const result = apiError.result as Record<string, unknown> | undefined;
if (apiError.statusCode === 422 && result && "errors" in result && Array.isArray(result.errors)) {
this.error(replaceHTML(`${result.errors}`));
} else if (apiError.statusCode === 422 && apiError.body && typeof apiError.body === "string") {
this.error(JSON.parse(apiError.body)["dto.FileUrl"][0]);
} else if (apiError.statusCode === 401 && apiError.body && typeof apiError.body === "string") {
this.error("You are not authorized to perform this action");
} else if (apiError.statusCode === 500) {
this.error(apiError.message);
}
} else if ((error as AuthenticationError).statusCode === 401) {
this.error("You are not authorized to perform this action");
} else if (
(error as AuthenticationError).statusCode === 402 &&
(error as AuthenticationError).body &&
typeof (error as AuthenticationError).body === "string"
) {
this.error((error as AuthenticationError).body);
} else {
this.error(`${(error as Error).message}`);
}
}
}
}