@apimatic/cli 0.0.0-alpha.2
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 +258 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/lib/client-utils/auth-manager.d.ts +17 -0
- package/lib/client-utils/auth-manager.js +33 -0
- package/lib/client-utils/sdk-client.d.ts +23 -0
- package/lib/client-utils/sdk-client.js +119 -0
- package/lib/commands/api/transform.d.ts +14 -0
- package/lib/commands/api/transform.js +105 -0
- package/lib/commands/api/validate.d.ts +11 -0
- package/lib/commands/api/validate.js +64 -0
- package/lib/commands/auth/login.d.ts +9 -0
- package/lib/commands/auth/login.js +60 -0
- package/lib/commands/auth/logout.d.ts +6 -0
- package/lib/commands/auth/logout.js +23 -0
- package/lib/commands/auth/status.d.ts +6 -0
- package/lib/commands/auth/status.js +23 -0
- package/lib/commands/portal/generate.d.ts +13 -0
- package/lib/commands/portal/generate.js +102 -0
- package/lib/commands/sdk/generate.d.ts +15 -0
- package/lib/commands/sdk/generate.js +129 -0
- package/lib/config/env.d.ts +1 -0
- package/lib/config/env.js +4 -0
- package/lib/controllers/api/transform.d.ts +7 -0
- package/lib/controllers/api/transform.js +59 -0
- package/lib/controllers/api/validate.d.ts +5 -0
- package/lib/controllers/api/validate.js +32 -0
- package/lib/controllers/portal/generate.d.ts +2 -0
- package/lib/controllers/portal/generate.js +49 -0
- package/lib/controllers/sdk/generate.d.ts +4 -0
- package/lib/controllers/sdk/generate.js +64 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -0
- package/lib/types/api/transform.d.ts +34 -0
- package/lib/types/api/transform.js +18 -0
- package/lib/types/api/validate.d.ts +12 -0
- package/lib/types/api/validate.js +2 -0
- package/lib/types/portal/generate.d.ts +9 -0
- package/lib/types/portal/generate.js +2 -0
- package/lib/types/sdk/generate.d.ts +22 -0
- package/lib/types/sdk/generate.js +12 -0
- package/lib/utils/utils.d.ts +18 -0
- package/lib/utils/utils.js +107 -0
- package/oclif.manifest.json +1 -0
- package/package.json +107 -0
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
@apimatic/cli
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
The official CLI for APIMatic.
|
|
5
|
+
|
|
6
|
+
[](https://oclif.io)
|
|
7
|
+
[](https://npmjs.org/package/@apimatic/cli)
|
|
8
|
+
[](https://npmjs.org/package/@apimatic/cli)
|
|
9
|
+
[](https://github.com/apimatic/apimatic-cli/blob/master/package.json)
|
|
10
|
+
|
|
11
|
+
<!-- toc -->
|
|
12
|
+
* [Usage](#usage)
|
|
13
|
+
* [Commands](#commands)
|
|
14
|
+
<!-- tocstop -->
|
|
15
|
+
# Usage
|
|
16
|
+
<!-- usage -->
|
|
17
|
+
```sh-session
|
|
18
|
+
$ npm install -g @apimatic/cli
|
|
19
|
+
$ apimatic COMMAND
|
|
20
|
+
running command...
|
|
21
|
+
$ apimatic (-v|--version|version)
|
|
22
|
+
@apimatic/cli/0.0.0-alpha.2 linux-x64 node-v16.13.0
|
|
23
|
+
$ apimatic --help [COMMAND]
|
|
24
|
+
USAGE
|
|
25
|
+
$ apimatic COMMAND
|
|
26
|
+
...
|
|
27
|
+
```
|
|
28
|
+
<!-- usagestop -->
|
|
29
|
+
|
|
30
|
+
# Commands
|
|
31
|
+
<!-- commands -->
|
|
32
|
+
* [`apimatic api:transform`](#apimatic-apitransform)
|
|
33
|
+
* [`apimatic api:validate`](#apimatic-apivalidate)
|
|
34
|
+
* [`apimatic auth:login`](#apimatic-authlogin)
|
|
35
|
+
* [`apimatic auth:logout`](#apimatic-authlogout)
|
|
36
|
+
* [`apimatic auth:status`](#apimatic-authstatus)
|
|
37
|
+
* [`apimatic autocomplete [SHELL]`](#apimatic-autocomplete-shell)
|
|
38
|
+
* [`apimatic help [COMMAND]`](#apimatic-help-command)
|
|
39
|
+
* [`apimatic portal:generate`](#apimatic-portalgenerate)
|
|
40
|
+
* [`apimatic sdk:generate`](#apimatic-sdkgenerate)
|
|
41
|
+
|
|
42
|
+
## `apimatic api:transform`
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
USAGE
|
|
48
|
+
$ apimatic api:transform
|
|
49
|
+
|
|
50
|
+
OPTIONS
|
|
51
|
+
-f, --force overwrite if same file exist in the destination
|
|
52
|
+
--auth-key=auth-key override current authentication state with an authentication key
|
|
53
|
+
|
|
54
|
+
--destination=destination [default: /home/runner/work/apimatic-cli/apimatic-cli/cli] directory to download
|
|
55
|
+
transformed file to
|
|
56
|
+
|
|
57
|
+
--file=file path to the API specification file to transform
|
|
58
|
+
|
|
59
|
+
--format=format (required) specification format to transform API specification into
|
|
60
|
+
APIMATIC|WADL2009|WSDL|SWAGGER10|SWAGGER20|SWAGGERYAML|OAS3|OPENAPI3YAML|APIBLUEPRINT|RAML|
|
|
61
|
+
RAML10|POSTMAN10|POSTMAN20|GRAPHQLSCHEMA
|
|
62
|
+
|
|
63
|
+
--url=url URL to the API specification file to transform. Can be used in place of the --file option
|
|
64
|
+
if the API specification is publicly available.
|
|
65
|
+
|
|
66
|
+
EXAMPLES
|
|
67
|
+
$ apimatic api:transform --format="OpenApi3Json" --file="./specs/sample.json" --destination="D:/"
|
|
68
|
+
Success! Your transformed file is located at D:/Transformed_OpenApi3Json.json
|
|
69
|
+
|
|
70
|
+
$ apimatic api:transform --format=RAML --url="https://petstore.swagger.io/v2/swagger.json" --destination="D:/"
|
|
71
|
+
Success! Your transformed file is located at D:/swagger_raml.yaml
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
_See code: [src/commands/api/transform.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/api/transform.ts)_
|
|
75
|
+
|
|
76
|
+
## `apimatic api:validate`
|
|
77
|
+
|
|
78
|
+
Validate the syntactic and semantic correctness of an API specification
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
USAGE
|
|
82
|
+
$ apimatic api:validate
|
|
83
|
+
|
|
84
|
+
OPTIONS
|
|
85
|
+
--auth-key=auth-key override current authentication state with an authentication key
|
|
86
|
+
--file=file Path to the API specification file to validate
|
|
87
|
+
|
|
88
|
+
--url=url URL to the specification file to validate. Can be used in place of the --file option if the API
|
|
89
|
+
specification is publicly available.
|
|
90
|
+
|
|
91
|
+
EXAMPLES
|
|
92
|
+
$ apimatic api:validate --file="./specs/sample.json"
|
|
93
|
+
Specification file provided is valid
|
|
94
|
+
|
|
95
|
+
$ apimatic api:validate --url=https://petstore.swagger.io/v2/swagger.json
|
|
96
|
+
Specification file provided is valid
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
_See code: [src/commands/api/validate.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/api/validate.ts)_
|
|
100
|
+
|
|
101
|
+
## `apimatic auth:login`
|
|
102
|
+
|
|
103
|
+
Login using your APIMatic credentials or an API Key
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
USAGE
|
|
107
|
+
$ apimatic auth:login
|
|
108
|
+
|
|
109
|
+
OPTIONS
|
|
110
|
+
--auth-key=auth-key Set authentication key for all commands
|
|
111
|
+
|
|
112
|
+
EXAMPLES
|
|
113
|
+
$ apimatic auth:login
|
|
114
|
+
Please enter your registered email: apimatic-user@gmail.com
|
|
115
|
+
Please enter your password: *********
|
|
116
|
+
|
|
117
|
+
You have successfully logged into APIMatic
|
|
118
|
+
|
|
119
|
+
$ apimatic auth:login --auth-key=xxxxxx
|
|
120
|
+
Authentication key successfully set
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
_See code: [src/commands/auth/login.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/auth/login.ts)_
|
|
124
|
+
|
|
125
|
+
## `apimatic auth:logout`
|
|
126
|
+
|
|
127
|
+
Clear local login credentials
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
USAGE
|
|
131
|
+
$ apimatic auth:logout
|
|
132
|
+
|
|
133
|
+
EXAMPLE
|
|
134
|
+
$ apimatic auth:logout
|
|
135
|
+
Logged out
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
_See code: [src/commands/auth/logout.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/auth/logout.ts)_
|
|
139
|
+
|
|
140
|
+
## `apimatic auth:status`
|
|
141
|
+
|
|
142
|
+
View current authentication state
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
USAGE
|
|
146
|
+
$ apimatic auth:status
|
|
147
|
+
|
|
148
|
+
EXAMPLE
|
|
149
|
+
$ apimatic auth:status
|
|
150
|
+
Currently logged in as apimatic-client@gmail.com
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
_See code: [src/commands/auth/status.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/auth/status.ts)_
|
|
154
|
+
|
|
155
|
+
## `apimatic autocomplete [SHELL]`
|
|
156
|
+
|
|
157
|
+
display autocomplete installation instructions
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
USAGE
|
|
161
|
+
$ apimatic autocomplete [SHELL]
|
|
162
|
+
|
|
163
|
+
ARGUMENTS
|
|
164
|
+
SHELL shell type
|
|
165
|
+
|
|
166
|
+
OPTIONS
|
|
167
|
+
-r, --refresh-cache Refresh cache (ignores displaying instructions)
|
|
168
|
+
|
|
169
|
+
EXAMPLES
|
|
170
|
+
$ apimatic autocomplete
|
|
171
|
+
$ apimatic autocomplete bash
|
|
172
|
+
$ apimatic autocomplete zsh
|
|
173
|
+
$ apimatic autocomplete --refresh-cache
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v0.3.0/src/commands/autocomplete/index.ts)_
|
|
177
|
+
|
|
178
|
+
## `apimatic help [COMMAND]`
|
|
179
|
+
|
|
180
|
+
display help for apimatic
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
USAGE
|
|
184
|
+
$ apimatic help [COMMAND]
|
|
185
|
+
|
|
186
|
+
ARGUMENTS
|
|
187
|
+
COMMAND command to show help for
|
|
188
|
+
|
|
189
|
+
OPTIONS
|
|
190
|
+
--all see all commands in CLI
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.14/src/commands/help.ts)_
|
|
194
|
+
|
|
195
|
+
## `apimatic portal:generate`
|
|
196
|
+
|
|
197
|
+
Generate and download a static API Documentation portal. Requires an input directory containing API specifications, a config file and optionally, markdown guides. For details, refer to the [documentation](https://portal-api-docs.apimatic.io/#/http/generating-api-portal/build-file)
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
USAGE
|
|
201
|
+
$ apimatic portal:generate
|
|
202
|
+
|
|
203
|
+
OPTIONS
|
|
204
|
+
-f, --force overwrite if a portal exists in the destination
|
|
205
|
+
--auth-key=auth-key override current authentication state with an authentication key
|
|
206
|
+
--destination=destination [default: /home/runner/work/apimatic-cli/apimatic-cli/cli] path to the downloaded portal
|
|
207
|
+
--folder=folder [default: ./] path to the input directory containing API specifications and config files
|
|
208
|
+
--zip download the generated portal as a .zip archive
|
|
209
|
+
|
|
210
|
+
EXAMPLE
|
|
211
|
+
$ apimatic portal:generate --folder="./portal/" --destination="D:/"
|
|
212
|
+
Your portal has been generated at D:/
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
_See code: [src/commands/portal/generate.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/portal/generate.ts)_
|
|
216
|
+
|
|
217
|
+
## `apimatic sdk:generate`
|
|
218
|
+
|
|
219
|
+
Generate SDK for your APIs
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
USAGE
|
|
223
|
+
$ apimatic sdk:generate
|
|
224
|
+
|
|
225
|
+
OPTIONS
|
|
226
|
+
-f, --force overwrite if an SDK already exists in the destination
|
|
227
|
+
--auth-key=auth-key override current authentication state with an authentication key
|
|
228
|
+
|
|
229
|
+
--destination=destination [default: /home/runner/work/apimatic-cli/apimatic-cli/cli] directory to download the
|
|
230
|
+
generated SDK to
|
|
231
|
+
|
|
232
|
+
--file=file path to the API specification to generate SDKs for
|
|
233
|
+
|
|
234
|
+
--platform=platform (required) language platform for sdk
|
|
235
|
+
Simple: CSHARP|JAVA|PYTHON|RUBY|PHP|TYPESCRIPT
|
|
236
|
+
Legacy: CS_NET_STANDARD_LIB|CS_PORTABLE_NET_LIB|CS_UNIVERSAL_WINDOWS_PLATFORM_LIB|
|
|
237
|
+
JAVA_ECLIPSE_JRE_LIB|PHP_GENERIC_LIB|PYTHON_GENERIC_LIB|RUBY_GENERIC_LIB|
|
|
238
|
+
TS_GENERIC_LIB
|
|
239
|
+
|
|
240
|
+
--url=url URL to the API specification to generate SDKs for. Can be used in place of the --file
|
|
241
|
+
option if the API specification is publicly available.
|
|
242
|
+
|
|
243
|
+
--zip download the generated SDK as a .zip archive
|
|
244
|
+
|
|
245
|
+
EXAMPLES
|
|
246
|
+
$ apimatic sdk:generate --platform="CSHARP" --file="./specs/sample.json"
|
|
247
|
+
Generating SDK... done
|
|
248
|
+
Downloading SDK... done
|
|
249
|
+
Success! Your SDK is located at swagger_sdk_csharp
|
|
250
|
+
|
|
251
|
+
$ apimatic sdk:generate --platform="CSHARP" --url=https://petstore.swagger.io/v2/swagger.json
|
|
252
|
+
Generating SDK... done
|
|
253
|
+
Downloading SDK... done
|
|
254
|
+
Success! Your SDK is located at swagger_sdk_csharp
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
_See code: [src/commands/sdk/generate.ts](https://github.com/apimatic/apimatic-cli/blob/v0.0.0-alpha.2/src/commands/sdk/generate.ts)_
|
|
258
|
+
<!-- commandsstop -->
|
package/bin/run
ADDED
package/bin/run.cmd
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare type AuthInfo = {
|
|
2
|
+
email: string;
|
|
3
|
+
authKey: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} configDir <- Directory with user configuration
|
|
8
|
+
* //Function to get credentials
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAuthInfo(configDir: string): Promise<AuthInfo | null>;
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {AuthInfo} credentials
|
|
14
|
+
* @param {string} configDir <- Directory with user configuration
|
|
15
|
+
* //Function to set credentials.
|
|
16
|
+
*/
|
|
17
|
+
export declare function setAuthInfo(credentials: AuthInfo, configDir: string): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setAuthInfo = exports.getAuthInfo = void 0;
|
|
4
|
+
const fs = require("fs-extra");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {string} configDir <- Directory with user configuration
|
|
9
|
+
* //Function to get credentials
|
|
10
|
+
*/
|
|
11
|
+
async function getAuthInfo(configDir) {
|
|
12
|
+
try {
|
|
13
|
+
const data = JSON.parse(await fs.readFile(path.join(configDir, "config.json"), "utf8"));
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.getAuthInfo = getAuthInfo;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {AuthInfo} credentials
|
|
24
|
+
* @param {string} configDir <- Directory with user configuration
|
|
25
|
+
* //Function to set credentials.
|
|
26
|
+
*/
|
|
27
|
+
async function setAuthInfo(credentials, configDir) {
|
|
28
|
+
const configFilePath = path.join(configDir, "config.json");
|
|
29
|
+
if (!fs.existsSync(configFilePath))
|
|
30
|
+
fs.createFileSync(configFilePath);
|
|
31
|
+
return await fs.writeFile(configFilePath, JSON.stringify(credentials));
|
|
32
|
+
}
|
|
33
|
+
exports.setAuthInfo = setAuthInfo;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Client } from "@apimatic/sdk";
|
|
2
|
+
export declare class SDKClient {
|
|
3
|
+
private static instance;
|
|
4
|
+
private static authAPI;
|
|
5
|
+
static client: Client;
|
|
6
|
+
/**
|
|
7
|
+
* The static method that controls the access to the SDKClient instance.
|
|
8
|
+
*
|
|
9
|
+
* This implementation let you subclass the SDKClient class while keeping
|
|
10
|
+
* just one instance of each subclass around.
|
|
11
|
+
*/
|
|
12
|
+
static getInstance(): SDKClient;
|
|
13
|
+
/**
|
|
14
|
+
* Finally, any SDKClient should define some business logic, which can be
|
|
15
|
+
* executed on its instance.
|
|
16
|
+
*/
|
|
17
|
+
login(email: string, password: string, configDir: string): Promise<string>;
|
|
18
|
+
logout(configDir: string): Promise<string>;
|
|
19
|
+
status(configDir: string): Promise<string>;
|
|
20
|
+
getClient(overrideAuthKey: string | null, configDir: string): Promise<Client>;
|
|
21
|
+
private getAuthKey;
|
|
22
|
+
setAuthKey: (authKey: string, configDir: string) => string;
|
|
23
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SDKClient = void 0;
|
|
4
|
+
const base64 = require("base-64");
|
|
5
|
+
const axios_1 = require("axios");
|
|
6
|
+
const sdk_1 = require("@apimatic/sdk");
|
|
7
|
+
const auth_manager_1 = require("./auth-manager");
|
|
8
|
+
const env_1 = require("../config/env");
|
|
9
|
+
class SDKClient {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.setAuthKey = (authKey, configDir) => {
|
|
12
|
+
auth_manager_1.setAuthInfo({
|
|
13
|
+
email: "",
|
|
14
|
+
authKey
|
|
15
|
+
}, configDir);
|
|
16
|
+
return "Authentication key successfully set";
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The static method that controls the access to the SDKClient instance.
|
|
21
|
+
*
|
|
22
|
+
* This implementation let you subclass the SDKClient class while keeping
|
|
23
|
+
* just one instance of each subclass around.
|
|
24
|
+
*/
|
|
25
|
+
static getInstance() {
|
|
26
|
+
if (!SDKClient.instance) {
|
|
27
|
+
SDKClient.instance = new SDKClient();
|
|
28
|
+
}
|
|
29
|
+
return SDKClient.instance;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Finally, any SDKClient should define some business logic, which can be
|
|
33
|
+
* executed on its instance.
|
|
34
|
+
*/
|
|
35
|
+
async login(email, password, configDir) {
|
|
36
|
+
let storedAuthInfo = await auth_manager_1.getAuthInfo(configDir);
|
|
37
|
+
// If no config file or no credentials exist in the config file
|
|
38
|
+
if (!storedAuthInfo) {
|
|
39
|
+
storedAuthInfo = { email: "", authKey: "" };
|
|
40
|
+
}
|
|
41
|
+
const credentials = { email, password };
|
|
42
|
+
const authKey = await this.getAuthKey(credentials);
|
|
43
|
+
if (storedAuthInfo.email !== email) {
|
|
44
|
+
auth_manager_1.setAuthInfo({
|
|
45
|
+
email,
|
|
46
|
+
authKey
|
|
47
|
+
}, configDir);
|
|
48
|
+
return "Logged in";
|
|
49
|
+
}
|
|
50
|
+
else if (authKey === storedAuthInfo.authKey) {
|
|
51
|
+
return "Already logged in";
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
auth_manager_1.setAuthInfo({
|
|
55
|
+
email,
|
|
56
|
+
authKey
|
|
57
|
+
}, configDir);
|
|
58
|
+
return "Logged in";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async logout(configDir) {
|
|
62
|
+
auth_manager_1.setAuthInfo({
|
|
63
|
+
email: "",
|
|
64
|
+
authKey: ""
|
|
65
|
+
}, configDir);
|
|
66
|
+
return "Logged out";
|
|
67
|
+
}
|
|
68
|
+
async status(configDir) {
|
|
69
|
+
try {
|
|
70
|
+
let storedAuthInfo = await auth_manager_1.getAuthInfo(configDir);
|
|
71
|
+
if (!storedAuthInfo) {
|
|
72
|
+
// If no config file or no credentials exist in the config file
|
|
73
|
+
storedAuthInfo = { email: "", authKey: "" };
|
|
74
|
+
}
|
|
75
|
+
return storedAuthInfo.email === "" && storedAuthInfo.authKey === ""
|
|
76
|
+
? "Not logged in"
|
|
77
|
+
: storedAuthInfo.email === "" && storedAuthInfo.authKey !== ""
|
|
78
|
+
? "Logged in with authentication key"
|
|
79
|
+
: `Currently logged in as ${storedAuthInfo.email}`;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async getClient(overrideAuthKey, configDir) {
|
|
86
|
+
if (overrideAuthKey) {
|
|
87
|
+
return new sdk_1.Client({
|
|
88
|
+
timeout: 0,
|
|
89
|
+
authorization: `X-Auth-Key ${overrideAuthKey}`
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
let storedAuthInfo = await auth_manager_1.getAuthInfo(configDir);
|
|
93
|
+
if (!storedAuthInfo) {
|
|
94
|
+
// If no config file or no credentials exist in the config file
|
|
95
|
+
storedAuthInfo = { email: "", authKey: "" };
|
|
96
|
+
}
|
|
97
|
+
if (storedAuthInfo.authKey !== "") {
|
|
98
|
+
return new sdk_1.Client({
|
|
99
|
+
timeout: 0,
|
|
100
|
+
authorization: `X-Auth-Key ${storedAuthInfo.authKey}`
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw new Error("Please login first or provide an authKey");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async getAuthKey(credentials) {
|
|
108
|
+
const config = {
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: `Basic ${base64.encode(`${credentials.email}:${credentials.password}`)}`
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const response = await axios_1.default.get(SDKClient.authAPI, config);
|
|
114
|
+
const authKey = response.data.EncryptedValue;
|
|
115
|
+
return authKey;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.SDKClient = SDKClient;
|
|
119
|
+
SDKClient.authAPI = `${env_1.baseURL}/account/authkey`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { flags, Command } from "@oclif/command";
|
|
2
|
+
export default class Transform extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
format: flags.IOptionFlag<string>;
|
|
7
|
+
file: flags.IOptionFlag<string>;
|
|
8
|
+
url: flags.IOptionFlag<string>;
|
|
9
|
+
destination: flags.IOptionFlag<string>;
|
|
10
|
+
force: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
11
|
+
"auth-key": flags.IOptionFlag<string | undefined>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs-extra");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const sdk_1 = require("@apimatic/sdk");
|
|
6
|
+
const command_1 = require("@oclif/command");
|
|
7
|
+
const sdk_client_1 = require("../../client-utils/sdk-client");
|
|
8
|
+
const utils_1 = require("../../utils/utils");
|
|
9
|
+
const transform_1 = require("../../types/api/transform");
|
|
10
|
+
const transform_2 = require("../../controllers/api/transform");
|
|
11
|
+
const formats = Object.keys(sdk_1.ExportFormats).join("|");
|
|
12
|
+
class Transform extends command_1.Command {
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = this.parse(Transform);
|
|
15
|
+
const fileName = flags.file ? utils_1.getFileNameFromPath(flags.file) : utils_1.getFileNameFromPath(flags.url);
|
|
16
|
+
const destinationFormat = transform_1.DestinationFormats[flags.format];
|
|
17
|
+
const destinationFilePath = path.join(flags.destination, `${fileName}_${flags.format}.${destinationFormat}`.toLowerCase());
|
|
18
|
+
// Check if destination file already exist and throw error if force flag is not set
|
|
19
|
+
if (fs.existsSync(destinationFilePath) && !flags.force) {
|
|
20
|
+
throw new Error(`Can't download transformed file to path ${destinationFilePath}, because it already exists`);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
// Check if paths provided are valid
|
|
24
|
+
if (flags.file && !(await fs.pathExists(flags.file))) {
|
|
25
|
+
throw new Error(`Transformation file: ${flags.file} does not exist`);
|
|
26
|
+
}
|
|
27
|
+
else if (!(await fs.pathExists(flags.destination))) {
|
|
28
|
+
throw new Error(`Destination path: ${flags.destination} does not exist`);
|
|
29
|
+
}
|
|
30
|
+
const overrideAuthKey = flags["auth-key"] ? flags["auth-key"] : null;
|
|
31
|
+
const client = await sdk_client_1.SDKClient.getInstance().getClient(overrideAuthKey, this.config.configDir);
|
|
32
|
+
const transformationController = new sdk_1.TransformationController(client);
|
|
33
|
+
const { id, apiValidationSummary } = await transform_2.getTransformationId(flags, transformationController);
|
|
34
|
+
transform_2.printValidationMessages(apiValidationSummary, this.warn, this.error);
|
|
35
|
+
const savedTransformationFile = await transform_2.downloadTransformationFile({
|
|
36
|
+
id,
|
|
37
|
+
destinationFilePath,
|
|
38
|
+
transformationController
|
|
39
|
+
});
|
|
40
|
+
this.log(`Success! Your transformed file is located at ${savedTransformationFile}`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.result) {
|
|
44
|
+
const apiError = error;
|
|
45
|
+
// TODO: Hopefully, this type-cast won't be necessary when the SDK is
|
|
46
|
+
// updated to throw the right exception type for this status code.
|
|
47
|
+
const result = apiError.result;
|
|
48
|
+
if (apiError.statusCode === 422 && result && "errors" in result && Array.isArray(result.errors)) {
|
|
49
|
+
this.error(utils_1.replaceHTML(`${result.errors}`));
|
|
50
|
+
}
|
|
51
|
+
else if (apiError.statusCode === 422 && apiError.body && typeof apiError.body === "string") {
|
|
52
|
+
this.error(JSON.parse(apiError.body)["dto.FileUrl"][0]);
|
|
53
|
+
}
|
|
54
|
+
else if (apiError.statusCode === 401 && apiError.body && typeof apiError.body === "string") {
|
|
55
|
+
this.error(apiError.body);
|
|
56
|
+
}
|
|
57
|
+
else if (apiError.statusCode === 500) {
|
|
58
|
+
this.error(apiError.message);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (error.statusCode === 401 &&
|
|
62
|
+
error.body &&
|
|
63
|
+
typeof error.body === "string") {
|
|
64
|
+
this.error(error.body);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.error(`${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.default = Transform;
|
|
73
|
+
Transform.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.`;
|
|
74
|
+
Transform.examples = [
|
|
75
|
+
`$ apimatic api:transform --format="OpenApi3Json" --file="./specs/sample.json" --destination="D:/"
|
|
76
|
+
Success! Your transformed file is located at D:/Transformed_OpenApi3Json.json
|
|
77
|
+
`,
|
|
78
|
+
`$ apimatic api:transform --format=RAML --url="https://petstore.swagger.io/v2/swagger.json" --destination="D:/"
|
|
79
|
+
Success! Your transformed file is located at D:/swagger_raml.yaml
|
|
80
|
+
`
|
|
81
|
+
];
|
|
82
|
+
Transform.flags = {
|
|
83
|
+
format: command_1.flags.string({
|
|
84
|
+
parse: (format) => transform_2.getValidFormat(format.toUpperCase()),
|
|
85
|
+
required: true,
|
|
86
|
+
description: `specification format to transform API specification into
|
|
87
|
+
${formats}`
|
|
88
|
+
}),
|
|
89
|
+
file: command_1.flags.string({
|
|
90
|
+
parse: (input) => path.resolve(input),
|
|
91
|
+
default: "",
|
|
92
|
+
description: "path to the API specification file to transform"
|
|
93
|
+
}),
|
|
94
|
+
url: command_1.flags.string({
|
|
95
|
+
default: "",
|
|
96
|
+
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."
|
|
97
|
+
}),
|
|
98
|
+
destination: command_1.flags.string({
|
|
99
|
+
parse: (input) => path.resolve(input),
|
|
100
|
+
default: path.resolve("./"),
|
|
101
|
+
description: "directory to download transformed file to"
|
|
102
|
+
}),
|
|
103
|
+
force: command_1.flags.boolean({ char: "f", default: false, description: "overwrite if same file exist in the destination" }),
|
|
104
|
+
"auth-key": command_1.flags.string({ description: "override current authentication state with an authentication key" })
|
|
105
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { flags, Command } from "@oclif/command";
|
|
2
|
+
export default class Validate extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
file: flags.IOptionFlag<string>;
|
|
7
|
+
url: flags.IOptionFlag<string>;
|
|
8
|
+
"auth-key": flags.IOptionFlag<string | undefined>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs-extra");
|
|
4
|
+
const sdk_1 = require("@apimatic/sdk");
|
|
5
|
+
const command_1 = require("@oclif/command");
|
|
6
|
+
const sdk_client_1 = require("../../client-utils/sdk-client");
|
|
7
|
+
const utils_1 = require("../../utils/utils");
|
|
8
|
+
const transform_1 = require("../../controllers/api/transform");
|
|
9
|
+
const validate_1 = require("../../controllers/api/validate");
|
|
10
|
+
class Validate extends command_1.Command {
|
|
11
|
+
async run() {
|
|
12
|
+
const { flags } = this.parse(Validate);
|
|
13
|
+
try {
|
|
14
|
+
if (flags.file && !(await fs.pathExists(flags.file))) {
|
|
15
|
+
throw new Error(`Validation file: ${flags.file} does not exist`);
|
|
16
|
+
}
|
|
17
|
+
const overrideAuthKey = flags["auth-key"] ? flags["auth-key"] : null;
|
|
18
|
+
const client = await sdk_client_1.SDKClient.getInstance().getClient(overrideAuthKey, this.config.configDir);
|
|
19
|
+
const apiValidationController = new sdk_1.APIValidationExternalApisController(client);
|
|
20
|
+
const validationSummary = await validate_1.getValidation(flags, apiValidationController);
|
|
21
|
+
transform_1.printValidationMessages(validationSummary, this.warn, this.error);
|
|
22
|
+
validationSummary.success
|
|
23
|
+
? this.log("Specification file provided is valid")
|
|
24
|
+
: this.error("Specification file provided is invalid");
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error.result) {
|
|
28
|
+
const apiError = error;
|
|
29
|
+
const result = apiError.result;
|
|
30
|
+
if (result.modelState["exception Error"] && apiError.statusCode === 400) {
|
|
31
|
+
this.error(utils_1.replaceHTML(result.modelState["exception Error"][0]));
|
|
32
|
+
}
|
|
33
|
+
else if (error.body && apiError.statusCode === 401) {
|
|
34
|
+
this.error(error.body);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.error(error.message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.error(`${error.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.default = Validate;
|
|
47
|
+
Validate.description = "Validate the syntactic and semantic correctness of an API specification";
|
|
48
|
+
Validate.examples = [
|
|
49
|
+
`$ apimatic api:validate --file="./specs/sample.json"
|
|
50
|
+
Specification file provided is valid
|
|
51
|
+
`,
|
|
52
|
+
`$ apimatic api:validate --url=https://petstore.swagger.io/v2/swagger.json
|
|
53
|
+
Specification file provided is valid
|
|
54
|
+
`
|
|
55
|
+
];
|
|
56
|
+
Validate.flags = {
|
|
57
|
+
file: command_1.flags.string({ default: "", description: "Path to the API specification file to validate" }),
|
|
58
|
+
url: command_1.flags.string({
|
|
59
|
+
default: "",
|
|
60
|
+
description: "URL to the specification file to validate. Can be used in place of the --file option if the API specification is publicly available."
|
|
61
|
+
}),
|
|
62
|
+
// docs: flags.boolean({ default: false, description: "Validate specification for docs generation" }), // Next tier, not included in API spec
|
|
63
|
+
"auth-key": command_1.flags.string({ description: "override current authentication state with an authentication key" })
|
|
64
|
+
};
|