@useshortcut/client 1.0.0-beta.1 → 1.1.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/README.md +19 -13
- package/lib/ShortcutClient.js +5 -36
- package/lib/generated/Api.d.ts +201 -119
- package/lib/generated/Api.js +184 -466
- package/lib/generated/data-contracts.d.ts +1489 -609
- package/lib/generated/http-client.d.ts +14 -12
- package/lib/generated/http-client.js +50 -90
- package/lib/index.js +5 -1
- package/package.json +33 -31
- package/lib/ShortcutApi.d.ts +0 -5
- package/lib/ShortcutApi.js +0 -45
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType } from
|
|
2
|
-
export
|
|
3
|
-
export interface FullRequestParams extends Omit<AxiosRequestConfig,
|
|
1
|
+
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType } from 'axios';
|
|
2
|
+
export type QueryParamsType = Record<string | number, any>;
|
|
3
|
+
export interface FullRequestParams extends Omit<AxiosRequestConfig, 'data' | 'params' | 'url' | 'responseType'> {
|
|
4
4
|
/** set parameter to `true` for call `securityWorker` for this request */
|
|
5
5
|
secure?: boolean;
|
|
6
6
|
/** request path */
|
|
@@ -14,8 +14,8 @@ export interface FullRequestParams extends Omit<AxiosRequestConfig, "data" | "pa
|
|
|
14
14
|
/** request body */
|
|
15
15
|
body?: unknown;
|
|
16
16
|
}
|
|
17
|
-
export
|
|
18
|
-
export interface ApiConfig<SecurityDataType = unknown> extends Omit<AxiosRequestConfig,
|
|
17
|
+
export type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query' | 'path'>;
|
|
18
|
+
export interface ApiConfig<SecurityDataType = unknown> extends Omit<AxiosRequestConfig, 'data' | 'cancelToken'> {
|
|
19
19
|
securityWorker?: (securityData: SecurityDataType | null) => Promise<AxiosRequestConfig | void> | AxiosRequestConfig | void;
|
|
20
20
|
secure?: boolean;
|
|
21
21
|
format?: ResponseType;
|
|
@@ -23,12 +23,13 @@ export interface ApiConfig<SecurityDataType = unknown> extends Omit<AxiosRequest
|
|
|
23
23
|
export declare enum ContentType {
|
|
24
24
|
Json = "application/json",
|
|
25
25
|
FormData = "multipart/form-data",
|
|
26
|
-
UrlEncoded = "application/x-www-form-urlencoded"
|
|
26
|
+
UrlEncoded = "application/x-www-form-urlencoded",
|
|
27
|
+
Text = "text/plain"
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
29
|
-
* @internal
|
|
30
|
-
* @private
|
|
31
|
-
*/
|
|
30
|
+
* @internal
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
32
33
|
export declare class HttpClient<SecurityDataType = unknown> {
|
|
33
34
|
instance: AxiosInstance;
|
|
34
35
|
private securityData;
|
|
@@ -37,7 +38,8 @@ export declare class HttpClient<SecurityDataType = unknown> {
|
|
|
37
38
|
private format?;
|
|
38
39
|
constructor({ securityWorker, secure, format, ...axiosConfig }?: ApiConfig<SecurityDataType>);
|
|
39
40
|
setSecurityData: (data: SecurityDataType | null) => void;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
protected mergeRequestParams(params1: AxiosRequestConfig, params2?: AxiosRequestConfig): AxiosRequestConfig;
|
|
42
|
+
protected stringifyFormItem(formItem: unknown): string;
|
|
43
|
+
protected createFormData(input: Record<string, unknown>): FormData;
|
|
44
|
+
request: <T = any, _E = any>({ secure, path, type, query, format, body, ...params }: FullRequestParams) => Promise<AxiosResponse<T, any>>;
|
|
43
45
|
}
|
|
@@ -9,17 +9,6 @@
|
|
|
9
9
|
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
|
|
10
10
|
* ---------------------------------------------------------------
|
|
11
11
|
*/
|
|
12
|
-
var __assign = (this && this.__assign) || function () {
|
|
13
|
-
__assign = Object.assign || function(t) {
|
|
14
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
15
|
-
s = arguments[i];
|
|
16
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
17
|
-
t[p] = s[p];
|
|
18
|
-
}
|
|
19
|
-
return t;
|
|
20
|
-
};
|
|
21
|
-
return __assign.apply(this, arguments);
|
|
22
|
-
};
|
|
23
12
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
24
13
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
25
14
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -29,33 +18,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
29
18
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
30
19
|
});
|
|
31
20
|
};
|
|
32
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
33
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
34
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
35
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
36
|
-
function step(op) {
|
|
37
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
38
|
-
while (_) try {
|
|
39
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
40
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
41
|
-
switch (op[0]) {
|
|
42
|
-
case 0: case 1: t = op; break;
|
|
43
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
44
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
45
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
46
|
-
default:
|
|
47
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
48
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
49
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
50
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
51
|
-
if (t[2]) _.ops.pop();
|
|
52
|
-
_.trys.pop(); continue;
|
|
53
|
-
}
|
|
54
|
-
op = body.call(thisArg, _);
|
|
55
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
56
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
21
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
60
22
|
var t = {};
|
|
61
23
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -69,70 +31,68 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
69
31
|
};
|
|
70
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
33
|
exports.HttpClient = exports.ContentType = void 0;
|
|
72
|
-
|
|
73
|
-
var FormData = require("form-data");
|
|
34
|
+
const axios_1 = require("axios");
|
|
74
35
|
var ContentType;
|
|
75
36
|
(function (ContentType) {
|
|
76
37
|
ContentType["Json"] = "application/json";
|
|
77
38
|
ContentType["FormData"] = "multipart/form-data";
|
|
78
39
|
ContentType["UrlEncoded"] = "application/x-www-form-urlencoded";
|
|
79
|
-
|
|
40
|
+
ContentType["Text"] = "text/plain";
|
|
41
|
+
})(ContentType || (exports.ContentType = ContentType = {}));
|
|
80
42
|
/**
|
|
81
|
-
* @internal
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
var
|
|
87
|
-
if (_a === void 0) { _a = {}; }
|
|
88
|
-
var securityWorker = _a.securityWorker, secure = _a.secure, format = _a.format, axiosConfig = __rest(_a, ["securityWorker", "secure", "format"]);
|
|
43
|
+
* @internal
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
class HttpClient {
|
|
47
|
+
constructor(_a = {}) {
|
|
48
|
+
var { securityWorker, secure, format } = _a, axiosConfig = __rest(_a, ["securityWorker", "secure", "format"]);
|
|
89
49
|
this.securityData = null;
|
|
90
|
-
this.setSecurityData =
|
|
91
|
-
|
|
50
|
+
this.setSecurityData = (data) => {
|
|
51
|
+
this.securityData = data;
|
|
92
52
|
};
|
|
93
|
-
this.request =
|
|
94
|
-
var
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
responseFormat = (format && this.format) || void 0;
|
|
111
|
-
if (type === ContentType.FormData && body && body !== null && typeof body === "object") {
|
|
112
|
-
requestParams.headers.common = { Accept: "*/*" };
|
|
113
|
-
requestParams.headers.post = {};
|
|
114
|
-
requestParams.headers.put = {};
|
|
115
|
-
body = this.createFormData(body);
|
|
116
|
-
}
|
|
117
|
-
return [2 /*return*/, this.instance.request(__assign(__assign({}, requestParams), { headers: __assign(__assign(__assign({}, (type && type !== ContentType.FormData ? { "Content-Type": type } : {})), (body instanceof FormData ? { "Content-Type": body.getHeaders()["content-type"] } : {})), (requestParams.headers || {})), params: query, responseType: responseFormat, data: body, url: path }))];
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}); };
|
|
121
|
-
this.instance = axios_1.default.create(__assign(__assign({}, axiosConfig), { baseURL: axiosConfig.baseURL || "https://api.app.shortcut.com" }));
|
|
53
|
+
this.request = (_b) => __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var { secure, path, type, query, format, body } = _b, params = __rest(_b, ["secure", "path", "type", "query", "format", "body"]);
|
|
55
|
+
const secureParams = ((typeof secure === 'boolean' ? secure : this.secure) &&
|
|
56
|
+
this.securityWorker &&
|
|
57
|
+
(yield this.securityWorker(this.securityData))) ||
|
|
58
|
+
{};
|
|
59
|
+
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
60
|
+
const responseFormat = format || this.format || undefined;
|
|
61
|
+
if (type === ContentType.FormData && body && body !== null && typeof body === 'object') {
|
|
62
|
+
body = this.createFormData(body);
|
|
63
|
+
}
|
|
64
|
+
if (type === ContentType.Text && body && body !== null && typeof body !== 'string') {
|
|
65
|
+
body = JSON.stringify(body);
|
|
66
|
+
}
|
|
67
|
+
return this.instance.request(Object.assign(Object.assign({}, requestParams), { headers: Object.assign(Object.assign({}, (requestParams.headers || {})), (type && type !== ContentType.FormData ? { 'Content-Type': type } : {})), params: query, responseType: responseFormat, data: body, url: path }));
|
|
68
|
+
});
|
|
69
|
+
this.instance = axios_1.default.create(Object.assign(Object.assign({}, axiosConfig), { baseURL: axiosConfig.baseURL || 'https://api.app.shortcut.com' }));
|
|
122
70
|
this.secure = secure;
|
|
123
71
|
this.format = format;
|
|
124
72
|
this.securityWorker = securityWorker;
|
|
125
73
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
74
|
+
mergeRequestParams(params1, params2) {
|
|
75
|
+
const method = params1.method || (params2 && params2.method);
|
|
76
|
+
return Object.assign(Object.assign(Object.assign(Object.assign({}, this.instance.defaults), params1), (params2 || {})), { headers: Object.assign(Object.assign(Object.assign({}, ((method && this.instance.defaults.headers[method.toLowerCase()]) || {})), (params1.headers || {})), ((params2 && params2.headers) || {})) });
|
|
77
|
+
}
|
|
78
|
+
stringifyFormItem(formItem) {
|
|
79
|
+
if (typeof formItem === 'object' && formItem !== null) {
|
|
80
|
+
return JSON.stringify(formItem);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return `${formItem}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
createFormData(input) {
|
|
87
|
+
return Object.keys(input || {}).reduce((formData, key) => {
|
|
88
|
+
const property = input[key];
|
|
89
|
+
const propertyContent = property instanceof Array ? property : [property];
|
|
90
|
+
for (const formItem of propertyContent) {
|
|
91
|
+
const isFileType = formItem instanceof Blob;
|
|
92
|
+
formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));
|
|
93
|
+
}
|
|
133
94
|
return formData;
|
|
134
95
|
}, new FormData());
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
}());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
138
98
|
exports.HttpClient = HttpClient;
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useshortcut/client",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A Promise based library to the Shortcut
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "A Promise based library to the Shortcut REST API",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -18,43 +18,45 @@
|
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "yarn build:client && tsc",
|
|
22
|
-
"build:client": "swagger-typescript-api -p ./schema/shortcut.swagger.json -o ./src/generated --clean-output --axios --modular --templates ./templates
|
|
23
|
-
"build:
|
|
24
|
-
"
|
|
25
|
-
"validate:schema": "swagger-cli validate ./schema/shortcut.swagger.json",
|
|
21
|
+
"build": "yarn build:client && yarn build:add-typedoc-comments && tsc",
|
|
22
|
+
"build:client": "swagger-typescript-api -p ./schema/shortcut.swagger.json -o ./src/generated --clean-output --axios --modular --templates ./templates",
|
|
23
|
+
"build:add-typedoc-comments": "npx jscodeshift -t scripts/add-typedoc-comments.ts --extensions=ts --parser=ts src/generated/**",
|
|
24
|
+
"build:docs": "typedoc ./src --exclude 'src/__tests__/**'",
|
|
26
25
|
"validate:examples": "npx tsc examples/*.ts --noEmit",
|
|
27
|
-
"
|
|
26
|
+
"prepublishOnly": "yarn build",
|
|
27
|
+
"sync:schema": "curl --silent https://developer.shortcut.com/api/rest/v3/shortcut.swagger.json --output ./schema/shortcut.swagger.json && yarn validate:schema",
|
|
28
|
+
"validate:schema": "swagger-cli validate ./schema/shortcut.swagger.json",
|
|
28
29
|
"lint": "eslint 'src/**/*.{js,ts}'",
|
|
29
30
|
"test": "jest",
|
|
30
|
-
"
|
|
31
|
+
"format": "prettier --write -l *.{json,md,prettierrc} '{src,scripts}/**/*.ts'",
|
|
32
|
+
"format:check": "prettier --check *.{json,md,prettierrc} '{src,scripts}/**/*.ts'"
|
|
31
33
|
},
|
|
32
34
|
"dependencies": {
|
|
33
|
-
"axios": "^
|
|
34
|
-
"form-data": "^4.0.0"
|
|
35
|
+
"axios": "^1.5.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"@types/jest": "^
|
|
38
|
-
"@types/
|
|
39
|
-
"@
|
|
40
|
-
"@typescript-eslint/
|
|
41
|
-
"eslint": "^
|
|
42
|
-
"eslint
|
|
43
|
-
"eslint-config-
|
|
44
|
-
"eslint-
|
|
45
|
-
"eslint-plugin-
|
|
46
|
-
"eslint-plugin-
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"prettier": "
|
|
51
|
-
"rimraf": "^
|
|
38
|
+
"@types/jest": "^29.5.4",
|
|
39
|
+
"@types/jscodeshift": "0.11.6",
|
|
40
|
+
"@types/node": "^20.5.7",
|
|
41
|
+
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
|
42
|
+
"@typescript-eslint/parser": "^6.5.0",
|
|
43
|
+
"eslint": "^8.48.0",
|
|
44
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
45
|
+
"eslint-config-prettier": "^9.0.0",
|
|
46
|
+
"eslint-plugin-import": "^2.28.1",
|
|
47
|
+
"eslint-plugin-jest": "^27.2.3",
|
|
48
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
49
|
+
"jest": "^29.6.4",
|
|
50
|
+
"jscodeshift": "^0.15.0",
|
|
51
|
+
"prettier": "^3.0.3",
|
|
52
|
+
"rimraf": "^5.0.1",
|
|
53
|
+
"stream-to-blob": "^2.0.1",
|
|
52
54
|
"swagger-cli": "^4.0.4",
|
|
53
|
-
"swagger-typescript-api": "
|
|
54
|
-
"ts-jest": "^
|
|
55
|
-
"typedoc": "0.
|
|
56
|
-
"typedoc-plugin-merge-modules": "
|
|
57
|
-
"typescript": "
|
|
55
|
+
"swagger-typescript-api": "^13.0.3",
|
|
56
|
+
"ts-jest": "^29.1.1",
|
|
57
|
+
"typedoc": "0.25.0",
|
|
58
|
+
"typedoc-plugin-merge-modules": "5.1.0",
|
|
59
|
+
"typescript": "^5.2.2"
|
|
58
60
|
},
|
|
59
61
|
"jest": {
|
|
60
62
|
"preset": "ts-jest",
|
package/lib/ShortcutApi.d.ts
DELETED
package/lib/ShortcutApi.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __assign = (this && this.__assign) || function () {
|
|
18
|
-
__assign = Object.assign || function(t) {
|
|
19
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
-
s = arguments[i];
|
|
21
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
-
t[p] = s[p];
|
|
23
|
-
}
|
|
24
|
-
return t;
|
|
25
|
-
};
|
|
26
|
-
return __assign.apply(this, arguments);
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.ShortcutApi = void 0;
|
|
30
|
-
var Api_1 = require("./generated/Api");
|
|
31
|
-
var ShortcutApi = /** @class */ (function (_super) {
|
|
32
|
-
__extends(ShortcutApi, _super);
|
|
33
|
-
function ShortcutApi(apiToken, config) {
|
|
34
|
-
if (config === void 0) { config = {}; }
|
|
35
|
-
var _this = this;
|
|
36
|
-
if (apiToken == null || typeof apiToken !== 'string') {
|
|
37
|
-
// eslint-disable-next-line no-console
|
|
38
|
-
console.error('You need to supply an API Token.');
|
|
39
|
-
}
|
|
40
|
-
_this = _super.call(this, __assign({ headers: __assign({ 'Shortcut-Token': apiToken }, config.headers) }, config)) || this;
|
|
41
|
-
return _this;
|
|
42
|
-
}
|
|
43
|
-
return ShortcutApi;
|
|
44
|
-
}(Api_1.Api));
|
|
45
|
-
exports.ShortcutApi = ShortcutApi;
|