api 4.5.0 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +4 -5
- package/bin/api +2 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +91 -0
- package/dist/cache.d.ts +30 -0
- package/dist/cache.js +217 -0
- package/dist/cli/codegen/index.d.ts +4 -0
- package/dist/cli/codegen/index.js +23 -0
- package/dist/cli/codegen/language.d.ts +27 -0
- package/dist/cli/codegen/language.js +19 -0
- package/dist/cli/codegen/languages/typescript.d.ts +99 -0
- package/dist/cli/codegen/languages/typescript.js +762 -0
- package/dist/cli/commands/index.d.ts +4 -0
- package/dist/cli/commands/index.js +9 -0
- package/dist/cli/commands/install.d.ts +3 -0
- package/dist/cli/commands/install.js +230 -0
- package/dist/cli/lib/prompt.d.ts +9 -0
- package/dist/cli/lib/prompt.js +81 -0
- package/dist/cli/logger.d.ts +1 -0
- package/dist/cli/logger.js +16 -0
- package/dist/cli/storage.d.ts +105 -0
- package/dist/cli/storage.js +264 -0
- package/dist/core/getJSONSchemaDefaults.d.ts +15 -0
- package/dist/core/getJSONSchemaDefaults.js +62 -0
- package/dist/core/index.d.ts +32 -0
- package/dist/core/index.js +143 -0
- package/dist/core/parseResponse.d.ts +1 -0
- package/dist/core/parseResponse.js +65 -0
- package/dist/core/prepareAuth.d.ts +5 -0
- package/dist/core/prepareAuth.js +55 -0
- package/dist/core/prepareParams.d.ts +24 -0
- package/dist/core/prepareParams.js +351 -0
- package/dist/core/prepareServer.d.ts +13 -0
- package/dist/core/prepareServer.js +50 -0
- package/dist/fetcher.d.ts +53 -0
- package/dist/fetcher.js +149 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +276 -0
- package/dist/packageInfo.d.ts +2 -0
- package/dist/packageInfo.js +6 -0
- package/package.json +65 -26
- package/src/.sink.d.ts +1 -0
- package/src/bin.ts +20 -0
- package/src/cache.ts +212 -0
- package/src/cli/codegen/index.ts +31 -0
- package/src/cli/codegen/language.ts +47 -0
- package/src/cli/codegen/languages/typescript.ts +798 -0
- package/src/cli/commands/index.ts +5 -0
- package/src/cli/commands/install.ts +196 -0
- package/src/cli/lib/prompt.ts +29 -0
- package/src/cli/logger.ts +10 -0
- package/src/cli/storage.ts +297 -0
- package/src/core/getJSONSchemaDefaults.ts +74 -0
- package/src/core/index.ts +108 -0
- package/src/{lib/parseResponse.js → core/parseResponse.ts} +5 -7
- package/src/core/prepareAuth.ts +85 -0
- package/src/core/prepareParams.ts +338 -0
- package/src/{lib/prepareServer.js → core/prepareServer.ts} +13 -12
- package/src/fetcher.ts +126 -0
- package/src/index.ts +212 -0
- package/src/packageInfo.ts +3 -0
- package/src/typings.d.ts +3 -0
- package/tsconfig.json +24 -0
- package/src/cache.js +0 -214
- package/src/index.js +0 -177
- package/src/lib/getSchema.js +0 -34
- package/src/lib/index.js +0 -11
- package/src/lib/prepareAuth.js +0 -69
- package/src/lib/prepareParams.js +0 -198
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ npm install api --save
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## Usage
|
|
23
|
-
|
|
23
|
+
All you need to use `api` is to supply it an OpenAPI definition and then use the SDK as you would any other!
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
26
|
const sdk = require('api')('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore.json');
|
|
@@ -40,7 +40,7 @@ sdk.auth('myApiToken');
|
|
|
40
40
|
sdk.listPets().then(...);
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
With the exception of OpenID, it supports all forms of authentication supported by the OpenAPI specification!
|
|
43
|
+
With the exception of OpenID, it supports all forms of authentication supported by the OpenAPI specification! Supply `.auth()` with your auth credentials and it'll magically figure out how to use it according to the API you're using. 🧙♀️
|
|
44
44
|
|
|
45
45
|
For example:
|
|
46
46
|
|
|
@@ -56,7 +56,7 @@ When supplying parameters and/or request body payloads to an API request, you do
|
|
|
56
56
|
* `body`: This will contain all data required for a request body payload for a POST, PUT, etc. request. It can either be an array or an object — whichever you need to use the API operation you're using.
|
|
57
57
|
* `metadata`: This is an object where all parameters (path, query, header, cookie) go. Again, don't worry about telling the SDK that a path parameter is for the path, that's all handled for you.
|
|
58
58
|
|
|
59
|
-
For example, if you wanted to make a
|
|
59
|
+
For example, if you wanted to make a GET request:
|
|
60
60
|
|
|
61
61
|
```js
|
|
62
62
|
sdk.showPetById({ petId: 1234 }).then(...)
|
|
@@ -143,7 +143,7 @@ At the moment it does not. If you wish to use an API that has a Swagger 2.0 file
|
|
|
143
143
|
Not yet, unfortunately. For APIs that use OAuth 2, you'll need a fully-qualified token already for `api` to make requests.
|
|
144
144
|
|
|
145
145
|
#### Does this support APIs that use multiple forms of authentication on a single request?
|
|
146
|
-
Not yet! This is something we're thinking about how to handle, but it's difficult with the
|
|
146
|
+
Not yet! This is something we're thinking about how to handle, but it's difficult with the simplified nature of the `.auth()` method as it currently does not require the user to inform the SDK of what kind of authentication scheme the token they're supplying it should match up against.
|
|
147
147
|
|
|
148
148
|
#### Will this work in browsers?
|
|
149
149
|
Not at the moment as the library requires some filesystem handling in order to manage its cache state, but it's something we're actively thinking about. If you'd like to help us out in making this compatible with browsers we'd love to help you out on a pull request.
|
|
@@ -173,7 +173,6 @@ By default the cache is configured with the [find-cache-dir](https://npm.im/find
|
|
|
173
173
|
const sdk = require('api')('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore.json', {
|
|
174
174
|
cacheDir: './path/to/my/custom/cache/dir',
|
|
175
175
|
});
|
|
176
|
-
|
|
177
176
|
sdk.listPets().then(res => {
|
|
178
177
|
console.log(`My pets name is ${res[0].name}!`);
|
|
179
178
|
});
|
package/bin/api
ADDED
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
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);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (_) try {
|
|
41
|
+
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;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
+
};
|
|
64
|
+
exports.__esModule = true;
|
|
65
|
+
var commander_1 = require("commander");
|
|
66
|
+
var pkg = __importStar(require("./packageInfo"));
|
|
67
|
+
var commands_1 = __importDefault(require("./cli/commands"));
|
|
68
|
+
(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
69
|
+
var program;
|
|
70
|
+
return __generator(this, function (_a) {
|
|
71
|
+
switch (_a.label) {
|
|
72
|
+
case 0:
|
|
73
|
+
program = new commander_1.Command();
|
|
74
|
+
program.name(pkg.PACKAGE_NAME);
|
|
75
|
+
program.version(pkg.PACKAGE_VERSION);
|
|
76
|
+
/**
|
|
77
|
+
* Instead of using Commander's `executableDir` API for loading in external command files we're
|
|
78
|
+
* programatically doing it like this because it's cleaner for us to let Commander manage option
|
|
79
|
+
* and argument parsing within this file than having each command manage that itself.
|
|
80
|
+
*/
|
|
81
|
+
Object.entries(commands_1["default"]).forEach(function (_a) {
|
|
82
|
+
var cmd = _a[1];
|
|
83
|
+
program.addCommand(cmd);
|
|
84
|
+
});
|
|
85
|
+
return [4 /*yield*/, program.parseAsync(process.argv)];
|
|
86
|
+
case 1:
|
|
87
|
+
_a.sent();
|
|
88
|
+
return [2 /*return*/];
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}); })();
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { OASDocument } from 'oas/@types/rmoas.types';
|
|
2
|
+
import 'isomorphic-fetch';
|
|
3
|
+
import Fetcher from './fetcher';
|
|
4
|
+
declare type CacheStore = Record<string, {
|
|
5
|
+
hash: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
original: string | OASDocument;
|
|
8
|
+
title?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
}>;
|
|
11
|
+
export default class Cache {
|
|
12
|
+
static dir: string;
|
|
13
|
+
static cacheStore: string;
|
|
14
|
+
static specsCache: string;
|
|
15
|
+
uri: string | OASDocument;
|
|
16
|
+
uriHash: string;
|
|
17
|
+
cached: false | CacheStore;
|
|
18
|
+
fetcher: Fetcher;
|
|
19
|
+
constructor(uri: string | OASDocument, cacheDir?: string | false);
|
|
20
|
+
static getCacheHash(file: string | OASDocument): string;
|
|
21
|
+
static setCacheDir(dir?: string | false): void;
|
|
22
|
+
static reset(): Promise<void>;
|
|
23
|
+
static validate(json: any): Promise<import("openapi-types").OpenAPI.Document<{}>>;
|
|
24
|
+
isCached(): boolean;
|
|
25
|
+
getCache(): CacheStore;
|
|
26
|
+
get(): any;
|
|
27
|
+
load(): Promise<OASDocument>;
|
|
28
|
+
save(spec: OASDocument): OASDocument;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
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;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
exports.__esModule = true;
|
|
42
|
+
require("isomorphic-fetch");
|
|
43
|
+
var openapi_parser_1 = __importDefault(require("@readme/openapi-parser"));
|
|
44
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
45
|
+
var find_cache_dir_1 = __importDefault(require("find-cache-dir"));
|
|
46
|
+
var fs_1 = __importDefault(require("fs"));
|
|
47
|
+
var os_1 = __importDefault(require("os"));
|
|
48
|
+
var path_1 = __importDefault(require("path"));
|
|
49
|
+
var make_dir_1 = __importDefault(require("make-dir"));
|
|
50
|
+
var packageInfo_1 = require("./packageInfo");
|
|
51
|
+
var fetcher_1 = __importDefault(require("./fetcher"));
|
|
52
|
+
var Cache = /** @class */ (function () {
|
|
53
|
+
function Cache(uri, cacheDir) {
|
|
54
|
+
if (cacheDir === void 0) { cacheDir = false; }
|
|
55
|
+
Cache.setCacheDir(cacheDir);
|
|
56
|
+
Cache.cacheStore = path_1["default"].join(Cache.dir, 'cache.json');
|
|
57
|
+
Cache.specsCache = path_1["default"].join(Cache.dir, 'specs');
|
|
58
|
+
this.fetcher = new fetcher_1["default"](uri);
|
|
59
|
+
this.uri = this.fetcher.uri;
|
|
60
|
+
this.uriHash = Cache.getCacheHash(this.uri);
|
|
61
|
+
// This should default to false so we have awareness if we've looked at the cache yet.
|
|
62
|
+
this.cached = false;
|
|
63
|
+
}
|
|
64
|
+
Cache.getCacheHash = function (file) {
|
|
65
|
+
var data;
|
|
66
|
+
if (typeof file === 'object') {
|
|
67
|
+
// Under certain unit testing circumstances, we might be supplying the class with a raw JSON
|
|
68
|
+
// object so we'll need to convert it to a string in order to hand it off to the crypto
|
|
69
|
+
// module.
|
|
70
|
+
data = JSON.stringify(file);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
data = file;
|
|
74
|
+
}
|
|
75
|
+
return crypto_1["default"].createHash('md5').update(data).digest('hex');
|
|
76
|
+
};
|
|
77
|
+
Cache.setCacheDir = function (dir) {
|
|
78
|
+
if (dir) {
|
|
79
|
+
Cache.dir = dir;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
else if (Cache.dir) {
|
|
83
|
+
// If we already have a cache dir set and aren't explicitly it to something new then we
|
|
84
|
+
// shouldn't overwrite what we've already got.
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
Cache.dir = (0, find_cache_dir_1["default"])({ name: packageInfo_1.PACKAGE_NAME });
|
|
88
|
+
if (typeof Cache.dir === 'undefined') {
|
|
89
|
+
// The `find-cache-dir` module returns `undefined` if the `node_modules/` directory isn't
|
|
90
|
+
// writable, or there's no `package.json` in the root-most directory. If this happens, we can
|
|
91
|
+
// instead adhoc create a cache directory in the users OS temp directory and store our data
|
|
92
|
+
// there.
|
|
93
|
+
//
|
|
94
|
+
// @link https://github.com/avajs/find-cache-dir/issues/29
|
|
95
|
+
Cache.dir = make_dir_1["default"].sync(path_1["default"].join(os_1["default"].tmpdir(), packageInfo_1.PACKAGE_NAME));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
Cache.reset = function () {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
100
|
+
return __generator(this, function (_a) {
|
|
101
|
+
switch (_a.label) {
|
|
102
|
+
case 0:
|
|
103
|
+
if (!Cache.cacheStore) return [3 /*break*/, 2];
|
|
104
|
+
return [4 /*yield*/, fs_1["default"].promises.rm(Cache.cacheStore)["catch"](function () {
|
|
105
|
+
// no-op
|
|
106
|
+
})];
|
|
107
|
+
case 1:
|
|
108
|
+
_a.sent();
|
|
109
|
+
_a.label = 2;
|
|
110
|
+
case 2:
|
|
111
|
+
if (!Cache.specsCache) return [3 /*break*/, 4];
|
|
112
|
+
return [4 /*yield*/, fs_1["default"].promises.rm(Cache.specsCache, { recursive: true })["catch"](function () {
|
|
113
|
+
// no-op
|
|
114
|
+
})];
|
|
115
|
+
case 3:
|
|
116
|
+
_a.sent();
|
|
117
|
+
_a.label = 4;
|
|
118
|
+
case 4: return [2 /*return*/];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
Cache.validate = function (json) {
|
|
124
|
+
if (json.swagger) {
|
|
125
|
+
throw new Error('Sorry, this module only supports OpenAPI definitions.');
|
|
126
|
+
}
|
|
127
|
+
// The `validate` method handles dereferencing for us.
|
|
128
|
+
return openapi_parser_1["default"].validate(json, {
|
|
129
|
+
dereference: {
|
|
130
|
+
// If circular `$refs` are ignored they'll remain in the API definition as `$ref: String`.
|
|
131
|
+
// This allows us to not only do easy circular reference detection but also stringify and
|
|
132
|
+
// save dereferenced API definitions back into the cache directory.
|
|
133
|
+
circular: 'ignore'
|
|
134
|
+
}
|
|
135
|
+
})["catch"](function (err) {
|
|
136
|
+
if (/is not a valid openapi definition/i.test(err.message)) {
|
|
137
|
+
throw new Error("Sorry, that doesn't look like a valid OpenAPI definition.");
|
|
138
|
+
}
|
|
139
|
+
throw err;
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
Cache.prototype.isCached = function () {
|
|
143
|
+
var cache = this.getCache();
|
|
144
|
+
return cache && this.uriHash in cache;
|
|
145
|
+
};
|
|
146
|
+
Cache.prototype.getCache = function () {
|
|
147
|
+
if (typeof this.cached === 'object') {
|
|
148
|
+
return this.cached;
|
|
149
|
+
}
|
|
150
|
+
this.cached = {};
|
|
151
|
+
if (fs_1["default"].existsSync(Cache.cacheStore)) {
|
|
152
|
+
this.cached = JSON.parse(fs_1["default"].readFileSync(Cache.cacheStore, 'utf8'));
|
|
153
|
+
}
|
|
154
|
+
return this.cached;
|
|
155
|
+
};
|
|
156
|
+
Cache.prototype.get = function () {
|
|
157
|
+
// If the class was supplied a raw object, just go ahead and bypass the caching system and
|
|
158
|
+
// return that.
|
|
159
|
+
if (typeof this.uri === 'object') {
|
|
160
|
+
return this.uri;
|
|
161
|
+
}
|
|
162
|
+
if (!this.isCached()) {
|
|
163
|
+
throw new Error("".concat(this.uri, " has not been cached yet and must do so before being retrieved."));
|
|
164
|
+
}
|
|
165
|
+
var cache = this.getCache();
|
|
166
|
+
// Prior to v4.5.0 we were putting a fully resolved path to the API definition in the cache
|
|
167
|
+
// store but if you had specified a custom caching directory and would generate the cache on
|
|
168
|
+
// your system, that filepath would obviously not be the same in other environments. For this
|
|
169
|
+
// reason the `path` was removed from the cache store in favor of storing the `hash` instead.
|
|
170
|
+
//
|
|
171
|
+
// If we still have `path` in the config cache for backwards compatibility we should use it.
|
|
172
|
+
if ('path' in cache[this.uriHash]) {
|
|
173
|
+
return JSON.parse(fs_1["default"].readFileSync(cache[this.uriHash].path, 'utf8'));
|
|
174
|
+
}
|
|
175
|
+
return JSON.parse(fs_1["default"].readFileSync(path_1["default"].join(Cache.specsCache, "".concat(cache[this.uriHash].hash, ".json")), 'utf8'));
|
|
176
|
+
};
|
|
177
|
+
Cache.prototype.load = function () {
|
|
178
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
179
|
+
var _this = this;
|
|
180
|
+
return __generator(this, function (_a) {
|
|
181
|
+
// If the class was supplied a raw object, just go ahead and bypass the caching system and
|
|
182
|
+
// return that.
|
|
183
|
+
if (typeof this.uri === 'object') {
|
|
184
|
+
return [2 /*return*/, this.uri];
|
|
185
|
+
}
|
|
186
|
+
return [2 /*return*/, this.fetcher.load().then(function (spec) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
187
|
+
return [2 /*return*/, this.save(spec)];
|
|
188
|
+
}); }); })];
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
Cache.prototype.save = function (spec) {
|
|
193
|
+
if (!fs_1["default"].existsSync(Cache.dir)) {
|
|
194
|
+
fs_1["default"].mkdirSync(Cache.dir, { recursive: true });
|
|
195
|
+
}
|
|
196
|
+
if (!fs_1["default"].existsSync(Cache.specsCache)) {
|
|
197
|
+
fs_1["default"].mkdirSync(Cache.specsCache, { recursive: true });
|
|
198
|
+
}
|
|
199
|
+
var cache = this.getCache();
|
|
200
|
+
if (!(this.uriHash in cache)) {
|
|
201
|
+
var saved = JSON.stringify(spec, null, 2);
|
|
202
|
+
var fileHash = crypto_1["default"].createHash('md5').update(saved).digest('hex');
|
|
203
|
+
cache[this.uriHash] = {
|
|
204
|
+
hash: fileHash,
|
|
205
|
+
original: this.uri,
|
|
206
|
+
title: 'title' in spec.info ? spec.info.title : undefined,
|
|
207
|
+
version: 'version' in spec.info ? spec.info.version : undefined
|
|
208
|
+
};
|
|
209
|
+
fs_1["default"].writeFileSync(path_1["default"].join(Cache.specsCache, "".concat(fileHash, ".json")), saved);
|
|
210
|
+
fs_1["default"].writeFileSync(Cache.cacheStore, JSON.stringify(cache, null, 2));
|
|
211
|
+
this.cached = cache;
|
|
212
|
+
}
|
|
213
|
+
return spec;
|
|
214
|
+
};
|
|
215
|
+
return Cache;
|
|
216
|
+
}());
|
|
217
|
+
exports["default"] = Cache;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type Oas from 'oas';
|
|
2
|
+
import type CodeGeneratorLanguage from './language';
|
|
3
|
+
export declare type SupportedLanguages = 'js' | 'js-cjs' | 'js-esm' | 'ts';
|
|
4
|
+
export default function codegen(language: SupportedLanguages, spec: Oas, specPath: string, identifier: string): CodeGeneratorLanguage;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
var typescript_1 = __importDefault(require("./languages/typescript"));
|
|
7
|
+
function codegen(language, spec, specPath, identifier) {
|
|
8
|
+
switch (language) {
|
|
9
|
+
case 'js':
|
|
10
|
+
throw new TypeError('An export format of CommonJS or ECMAScript is required for JavaScript compilation.');
|
|
11
|
+
case 'js-cjs':
|
|
12
|
+
case 'js-esm':
|
|
13
|
+
case 'ts':
|
|
14
|
+
return new typescript_1["default"](spec, specPath, identifier, {
|
|
15
|
+
outputJS: ['js-cjs', 'js-esm'].includes(language),
|
|
16
|
+
// TS will always generate with ESM-like exports.
|
|
17
|
+
compilerTarget: language === 'js-cjs' ? 'cjs' : 'esm'
|
|
18
|
+
});
|
|
19
|
+
default:
|
|
20
|
+
throw new TypeError("Unsupported language supplied: ".concat(language));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports["default"] = codegen;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type Oas from 'oas';
|
|
2
|
+
import type Storage from '../storage';
|
|
3
|
+
export interface InstallerOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Will initiate a dry run install process. Used for simulating installations within a unit test.
|
|
6
|
+
*/
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Used for stubbing out the logger that we use within the installation process so it can be
|
|
10
|
+
* easily introspected without having to mock out `console.*`.
|
|
11
|
+
*/
|
|
12
|
+
logger?: (msg: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export default abstract class CodeGeneratorLanguage {
|
|
15
|
+
spec: Oas;
|
|
16
|
+
specPath: string;
|
|
17
|
+
identifier: string;
|
|
18
|
+
userAgent: string;
|
|
19
|
+
requiredPackages: Record<string, {
|
|
20
|
+
reason: string;
|
|
21
|
+
url: string;
|
|
22
|
+
}>;
|
|
23
|
+
constructor(spec: Oas, specPath: string, identifier: string);
|
|
24
|
+
abstract generator(): Promise<Record<string, string>>;
|
|
25
|
+
abstract installer(storage: Storage, opts?: InstallerOptions): Promise<void>;
|
|
26
|
+
hasRequiredPackages(): boolean;
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
var packageInfo_1 = require("../../packageInfo");
|
|
4
|
+
var CodeGeneratorLanguage = /** @class */ (function () {
|
|
5
|
+
function CodeGeneratorLanguage(spec, specPath, identifier) {
|
|
6
|
+
this.spec = spec;
|
|
7
|
+
this.specPath = specPath;
|
|
8
|
+
// User agents should be contextual to the spec in question and the version of `api` that was
|
|
9
|
+
// used to generate the SDK. For example, this'll look like `petstore/1.0.0 (api/4.2.0)` for
|
|
10
|
+
// a `petstore` spec installed on api@4.2.0.
|
|
11
|
+
var info = spec.getDefinition().info;
|
|
12
|
+
this.userAgent = "".concat(identifier, "/").concat(info.version, " (").concat(packageInfo_1.PACKAGE_NAME, "/").concat(packageInfo_1.PACKAGE_VERSION, ")");
|
|
13
|
+
}
|
|
14
|
+
CodeGeneratorLanguage.prototype.hasRequiredPackages = function () {
|
|
15
|
+
return Boolean(Object.keys(this.requiredPackages));
|
|
16
|
+
};
|
|
17
|
+
return CodeGeneratorLanguage;
|
|
18
|
+
}());
|
|
19
|
+
exports["default"] = CodeGeneratorLanguage;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type Oas from 'oas';
|
|
2
|
+
import type { Operation } from 'oas';
|
|
3
|
+
import type { JSONSchema, SchemaObject } from 'oas/@types/rmoas.types';
|
|
4
|
+
import type { ClassDeclaration, MethodDeclaration } from 'ts-morph';
|
|
5
|
+
import type Storage from '../../storage';
|
|
6
|
+
import type { InstallerOptions } from '../language';
|
|
7
|
+
import CodeGeneratorLanguage from '../language';
|
|
8
|
+
import { Project } from 'ts-morph';
|
|
9
|
+
declare type OperationTypeHousing = {
|
|
10
|
+
types: {
|
|
11
|
+
params?: false | Record<'body' | 'formData' | 'metadata', string>;
|
|
12
|
+
responses?: Record<string, string>;
|
|
13
|
+
};
|
|
14
|
+
operation: Operation;
|
|
15
|
+
};
|
|
16
|
+
export default class TSGenerator extends CodeGeneratorLanguage {
|
|
17
|
+
project: Project;
|
|
18
|
+
outputJS: boolean;
|
|
19
|
+
compilerTarget: 'cjs' | 'esm';
|
|
20
|
+
types: Map<string, string>;
|
|
21
|
+
files: Record<string, string>;
|
|
22
|
+
methodGenerics: Map<string, MethodDeclaration>;
|
|
23
|
+
sdk: ClassDeclaration;
|
|
24
|
+
schemas: Map<string, {
|
|
25
|
+
schema: SchemaObject;
|
|
26
|
+
name: string;
|
|
27
|
+
tsType?: string;
|
|
28
|
+
}>;
|
|
29
|
+
constructor(spec: Oas, specPath: string, identifier: string, opts?: {
|
|
30
|
+
outputJS?: boolean;
|
|
31
|
+
compilerTarget?: 'cjs' | 'esm';
|
|
32
|
+
});
|
|
33
|
+
static formatter(content: string): string;
|
|
34
|
+
installer(storage: Storage, opts?: InstallerOptions): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Compile the current OpenAPI definition into a TypeScript library.
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
generator(): Promise<{
|
|
40
|
+
[x: string]: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Create a generic HTTP method accessor on the SDK.
|
|
44
|
+
*
|
|
45
|
+
* @param method
|
|
46
|
+
*/
|
|
47
|
+
createGenericMethodAccessor(method: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Create operation accessors on the SDK.
|
|
50
|
+
*
|
|
51
|
+
* @param operation
|
|
52
|
+
* @param operationId
|
|
53
|
+
* @param paramTypes
|
|
54
|
+
* @param responseTypes
|
|
55
|
+
*/
|
|
56
|
+
createOperationAccessor(operation: Operation, operationId: string, paramTypes?: OperationTypeHousing['types']['params'], responseTypes?: OperationTypeHousing['types']['responses']): void;
|
|
57
|
+
/**
|
|
58
|
+
* Convert a JSON Schema object into a readily available TypeScript type or interface along with
|
|
59
|
+
* any `$ref` pointers that are in use and turn those into TS types too.
|
|
60
|
+
*
|
|
61
|
+
* Under the hood this uses https://npm.im/json-schema-to-typescript for all composition and
|
|
62
|
+
* conversion.
|
|
63
|
+
*
|
|
64
|
+
* @param schema
|
|
65
|
+
* @param name
|
|
66
|
+
*/
|
|
67
|
+
convertJSONSchemaToTypescript(schema: JSONSchema, name: string): Promise<{
|
|
68
|
+
primaryType: string;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Scour through the current OpenAPI definition and compile a store of every operation, along
|
|
72
|
+
* with every HTTP method that's in use, and their available TypeScript types that we can use,
|
|
73
|
+
* along with every HTTP method that's in use.
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
loadOperationsAndMethods(): Promise<{
|
|
77
|
+
operations: Record<string, OperationTypeHousing>;
|
|
78
|
+
methods: Set<unknown>;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Compile the parameter (path, query, cookie, and header) schemas for an API operation into
|
|
82
|
+
* usable TypeScript types.
|
|
83
|
+
*
|
|
84
|
+
* @param operation
|
|
85
|
+
* @param operationId
|
|
86
|
+
*/
|
|
87
|
+
prepareParameterTypesForOperation(operation: Operation, operationId: string): false | Record<"formData" | "body" | "metadata", string>;
|
|
88
|
+
/**
|
|
89
|
+
* Compile the response schemas for an API operation into usable TypeScript types.
|
|
90
|
+
*
|
|
91
|
+
* @todo what does this do for a spec that has no responses?
|
|
92
|
+
* @param operation
|
|
93
|
+
* @param operationId
|
|
94
|
+
*/
|
|
95
|
+
prepareResponseTypesForOperation(operation: Operation, operationId: string): {
|
|
96
|
+
[x: string]: string;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export {};
|