api 6.1.0 → 6.1.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 +1 -1
- package/dist/cli/codegen/languages/typescript/util.d.ts +0 -1
- package/dist/cli/codegen/languages/typescript/util.js +7 -16
- package/dist/cli/codegen/languages/typescript.js +6 -6
- package/dist/core/prepareParams.js +10 -7
- package/dist/fetcher.js +0 -1
- package/dist/packageInfo.d.ts +1 -1
- package/dist/packageInfo.js +1 -1
- package/package.json +11 -21
- package/src/cli/codegen/index.ts +1 -1
- package/src/cli/codegen/language.ts +1 -1
- package/src/cli/codegen/languages/typescript/util.ts +3 -12
- package/src/cli/codegen/languages/typescript.ts +10 -10
- package/src/cli/commands/install.ts +2 -2
- package/src/cli/lib/prompt.ts +1 -1
- package/src/core/getJSONSchemaDefaults.ts +2 -2
- package/src/core/index.ts +1 -1
- package/src/core/prepareAuth.ts +3 -3
- package/src/core/prepareParams.ts +15 -10
- package/src/fetcher.ts +2 -3
- package/src/packageInfo.ts +1 -1
- package/tsconfig.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Or you can use it dynamically (though you won't have fancy TypeScript types to h
|
|
|
40
40
|
|
|
41
41
|
```js
|
|
42
42
|
const petstore = require('api')(
|
|
43
|
-
'https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.json'
|
|
43
|
+
'https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.json',
|
|
44
44
|
);
|
|
45
45
|
|
|
46
46
|
petstore.listPets().then(({ data }) => {
|
|
@@ -3,11 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
exports.__esModule = true;
|
|
6
|
-
exports.generateTypeName = exports.toSafeString = exports.docblockEscape = exports.wordWrap =
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var prettier_1 = require("prettier");
|
|
6
|
+
exports.generateTypeName = exports.toSafeString = exports.docblockEscape = exports.wordWrap = void 0;
|
|
7
|
+
var camelCase_1 = __importDefault(require("lodash/camelCase"));
|
|
8
|
+
var deburr_1 = __importDefault(require("lodash/deburr"));
|
|
9
|
+
var startCase_1 = __importDefault(require("lodash/startCase"));
|
|
11
10
|
/**
|
|
12
11
|
* This is a mix of reserved JS words and keywords in TypeScript that might be reserved or
|
|
13
12
|
* allowable but functionally confusing (like `let any = 'buster';`)
|
|
@@ -103,14 +102,6 @@ var RESERVED_WORDS = [
|
|
|
103
102
|
'self',
|
|
104
103
|
'window',
|
|
105
104
|
];
|
|
106
|
-
function formatter(content) {
|
|
107
|
-
return (0, prettier_1.format)(content, {
|
|
108
|
-
parser: 'typescript',
|
|
109
|
-
printWidth: 100,
|
|
110
|
-
singleQuote: true
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
exports.formatter = formatter;
|
|
114
105
|
/**
|
|
115
106
|
* @see {@link https://www.30secondsofcode.org/js/s/word-wrap}
|
|
116
107
|
*/
|
|
@@ -141,7 +132,7 @@ function toSafeString(str) {
|
|
|
141
132
|
// First character: a-zA-Z | _ | $
|
|
142
133
|
// Rest: a-zA-Z | _ | $ | 0-9
|
|
143
134
|
// remove accents, umlauts, ... by their basic latin letters
|
|
144
|
-
return ((0,
|
|
135
|
+
return ((0, deburr_1["default"])(str)
|
|
145
136
|
// if the string starts with a number, prefix it with character that typescript can accept
|
|
146
137
|
// https://github.com/bcherny/json-schema-to-typescript/issues/489
|
|
147
138
|
.replace(/^(\d){1}/, '$$1')
|
|
@@ -170,12 +161,12 @@ function generateTypeName() {
|
|
|
170
161
|
if (parts.length > 1) {
|
|
171
162
|
var last = parts[parts.length - 1];
|
|
172
163
|
if (last.match(/^(\d)XX$/)) {
|
|
173
|
-
str = (0,
|
|
164
|
+
str = (0, startCase_1["default"])((0, camelCase_1["default"])(parts.slice(0, -1).join(' ')));
|
|
174
165
|
str += " ".concat(last);
|
|
175
166
|
}
|
|
176
167
|
}
|
|
177
168
|
if (!str) {
|
|
178
|
-
str = (0,
|
|
169
|
+
str = (0, startCase_1["default"])((0, camelCase_1["default"])(parts.join(' ')));
|
|
179
170
|
}
|
|
180
171
|
if (RESERVED_WORDS.includes(str.toLowerCase())) {
|
|
181
172
|
str = "$".concat(str);
|
|
@@ -77,7 +77,7 @@ exports.__esModule = true;
|
|
|
77
77
|
var fs_1 = __importDefault(require("fs"));
|
|
78
78
|
var path_1 = __importDefault(require("path"));
|
|
79
79
|
var execa_1 = __importDefault(require("execa"));
|
|
80
|
-
var
|
|
80
|
+
var setWith_1 = __importDefault(require("lodash/setWith"));
|
|
81
81
|
var semver_1 = __importDefault(require("semver"));
|
|
82
82
|
var ts_morph_1 = require("ts-morph");
|
|
83
83
|
var logger_1 = __importDefault(require("../../logger"));
|
|
@@ -243,7 +243,7 @@ var TSGenerator = /** @class */ (function (_super) {
|
|
|
243
243
|
// user will have `.d.ts` files for them instead.
|
|
244
244
|
return {};
|
|
245
245
|
}
|
|
246
|
-
var code =
|
|
246
|
+
var code = sourceFile.text;
|
|
247
247
|
if (file === 'index.js' && _this.compilerTarget === 'cjs') {
|
|
248
248
|
/**
|
|
249
249
|
* There's an annoying quirk with `ts-morph` where if we're exporting a default export
|
|
@@ -268,7 +268,7 @@ var TSGenerator = /** @class */ (function (_super) {
|
|
|
268
268
|
return [2 /*return*/, __spreadArray(__spreadArray([], this.project.getSourceFiles().map(function (sourceFile) {
|
|
269
269
|
var _a;
|
|
270
270
|
return (_a = {},
|
|
271
|
-
_a[sourceFile.getBaseName()] =
|
|
271
|
+
_a[sourceFile.getBaseName()] = sourceFile.getFullText(),
|
|
272
272
|
_a);
|
|
273
273
|
}), true), this.project
|
|
274
274
|
.emitToMemory({ emitOnlyDtsFiles: true })
|
|
@@ -276,7 +276,7 @@ var TSGenerator = /** @class */ (function (_super) {
|
|
|
276
276
|
.map(function (sourceFile) {
|
|
277
277
|
var _a;
|
|
278
278
|
return (_a = {},
|
|
279
|
-
_a[path_1["default"].basename(sourceFile.filePath)] =
|
|
279
|
+
_a[path_1["default"].basename(sourceFile.filePath)] = sourceFile.text,
|
|
280
280
|
_a);
|
|
281
281
|
}), true).reduce(function (prev, next) { return Object.assign(prev, next); })];
|
|
282
282
|
});
|
|
@@ -602,7 +602,7 @@ var TSGenerator = /** @class */ (function (_super) {
|
|
|
602
602
|
fetchStmt.write(', ');
|
|
603
603
|
}
|
|
604
604
|
fetchStmt.write(arg.name);
|
|
605
|
-
if (
|
|
605
|
+
if (i !== totalParams - 1) {
|
|
606
606
|
fetchStmt.write(', ');
|
|
607
607
|
}
|
|
608
608
|
});
|
|
@@ -813,7 +813,7 @@ var TSGenerator = /** @class */ (function (_super) {
|
|
|
813
813
|
if (this.types.has(typeName)) {
|
|
814
814
|
return;
|
|
815
815
|
}
|
|
816
|
-
(0,
|
|
816
|
+
(0, setWith_1["default"])(this.schemas, pointer, schema, Object);
|
|
817
817
|
this.types.set(typeName, "FromSchema<typeof schemas.".concat(pointer, ">"));
|
|
818
818
|
};
|
|
819
819
|
return TSGenerator;
|
|
@@ -46,7 +46,7 @@ var caseless_1 = __importDefault(require("caseless"));
|
|
|
46
46
|
var parser_1 = __importDefault(require("datauri/parser"));
|
|
47
47
|
var sync_1 = __importDefault(require("datauri/sync"));
|
|
48
48
|
var get_stream_1 = __importDefault(require("get-stream"));
|
|
49
|
-
var
|
|
49
|
+
var merge_1 = __importDefault(require("lodash/merge"));
|
|
50
50
|
var remove_undefined_objects_1 = __importDefault(require("remove-undefined-objects"));
|
|
51
51
|
var getJSONSchemaDefaults_1 = __importDefault(require("./getJSONSchemaDefaults"));
|
|
52
52
|
// These headers are normally only defined by the OpenAPI definition but we allow the user to
|
|
@@ -82,7 +82,7 @@ function isObject(thing) {
|
|
|
82
82
|
return typeof thing === 'object' && thing !== null && !Array.isArray(thing);
|
|
83
83
|
}
|
|
84
84
|
function isPrimitive(obj) {
|
|
85
|
-
return
|
|
85
|
+
return obj === null || typeof obj === 'number' || typeof obj === 'string';
|
|
86
86
|
}
|
|
87
87
|
function merge(src, target) {
|
|
88
88
|
if (Array.isArray(target)) {
|
|
@@ -92,7 +92,7 @@ function merge(src, target) {
|
|
|
92
92
|
else if (!isObject(target)) {
|
|
93
93
|
return target;
|
|
94
94
|
}
|
|
95
|
-
return (0,
|
|
95
|
+
return (0, merge_1["default"])(src, target);
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Ingest a file path or readable stream into a common object that we can later use to process it
|
|
@@ -343,6 +343,7 @@ function prepareParams(operation, body, metadata) {
|
|
|
343
343
|
if (typeof metadata === 'object' && !isEmpty(metadata)) {
|
|
344
344
|
if (paramName in metadata) {
|
|
345
345
|
value = metadata[paramName];
|
|
346
|
+
metadataHeaderParam = paramName;
|
|
346
347
|
}
|
|
347
348
|
else if (param["in"] === 'header') {
|
|
348
349
|
// Headers are sent case-insensitive so we need to make sure that we're properly
|
|
@@ -387,10 +388,7 @@ function prepareParams(operation, body, metadata) {
|
|
|
387
388
|
// If there's any leftover metadata that hasn't been moved into form data for this request we
|
|
388
389
|
// need to move it or else it'll get tossed.
|
|
389
390
|
if (!isEmpty(metadata)) {
|
|
390
|
-
if (
|
|
391
|
-
params.formData = merge(params.formData, metadata);
|
|
392
|
-
}
|
|
393
|
-
else if (typeof metadata === 'object') {
|
|
391
|
+
if (typeof metadata === 'object') {
|
|
394
392
|
// If the user supplied an `accept` or `authorization` header themselves we should allow it
|
|
395
393
|
// through. Normally these headers are automatically handled by `@readme/oas-to-har` but in
|
|
396
394
|
// the event that maybe the user wants to return XML for an API that normally returns JSON
|
|
@@ -400,9 +398,14 @@ function prepareParams(operation, body, metadata) {
|
|
|
400
398
|
var headerParam = Object.keys(metadata).find(function (m) { return m.toLowerCase() === headerName; });
|
|
401
399
|
if (headerParam) {
|
|
402
400
|
params.header[headerName] = metadata[headerParam];
|
|
401
|
+
// eslint-disable-next-line no-param-reassign
|
|
402
|
+
delete metadata[headerParam];
|
|
403
403
|
}
|
|
404
404
|
});
|
|
405
405
|
}
|
|
406
|
+
if (operation.isFormUrlEncoded()) {
|
|
407
|
+
params.formData = merge(params.formData, metadata);
|
|
408
|
+
}
|
|
406
409
|
else {
|
|
407
410
|
// Any other remaining unused metadata will be unused because we don't know where to place
|
|
408
411
|
// it in the request.
|
package/dist/fetcher.js
CHANGED
|
@@ -158,7 +158,6 @@ var Fetcher = /** @class */ (function () {
|
|
|
158
158
|
* @example @petstore/v1.0#n6kvf10vakpemvplx
|
|
159
159
|
* @example @petstore#n6kvf10vakpemvplx
|
|
160
160
|
*/
|
|
161
|
-
// eslint-disable-next-line unicorn/no-unsafe-regex
|
|
162
161
|
Fetcher.registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;
|
|
163
162
|
return Fetcher;
|
|
164
163
|
}());
|
package/dist/packageInfo.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const PACKAGE_NAME = "api";
|
|
2
|
-
export declare const PACKAGE_VERSION = "6.1.
|
|
2
|
+
export declare const PACKAGE_VERSION = "6.1.2";
|
package/dist/packageInfo.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.2",
|
|
4
4
|
"description": "Magical SDK generation from an OpenAPI definition 🪄",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"debug:bin": "node -r ts-node/register src/bin.ts",
|
|
13
|
+
"lint:types": "tsc --noEmit",
|
|
13
14
|
"prebuild": "rm -rf dist/; npm run version",
|
|
14
15
|
"prepack": "npm run build",
|
|
15
|
-
"test": "
|
|
16
|
-
"test:smoke": "
|
|
16
|
+
"test": "vitest --coverage",
|
|
17
|
+
"test:smoke": "vitest --config=vitest-smoketest.config.ts ",
|
|
17
18
|
"version": "node -p \"'// This file is automatically updated by the build script.\\nexport const PACKAGE_NAME = \\'' + require('./package.json').name + '\\';\\nexport const PACKAGE_VERSION = \\'' + require('./package.json').version + '\\';'\" > src/packageInfo.ts; git add src/packageInfo.ts"
|
|
18
19
|
},
|
|
19
20
|
"repository": {
|
|
@@ -54,16 +55,11 @@
|
|
|
54
55
|
"js-yaml": "^4.1.0",
|
|
55
56
|
"json-schema-to-ts": "^2.6.2-beta.0",
|
|
56
57
|
"json-schema-traverse": "^1.0.0",
|
|
57
|
-
"lodash
|
|
58
|
-
"lodash.deburr": "^4.1.0",
|
|
59
|
-
"lodash.merge": "^4.6.2",
|
|
60
|
-
"lodash.setwith": "^4.3.2",
|
|
61
|
-
"lodash.startcase": "^4.4.0",
|
|
58
|
+
"lodash": "^4.17.21",
|
|
62
59
|
"make-dir": "^3.1.0",
|
|
63
60
|
"node-abort-controller": "^3.1.1",
|
|
64
61
|
"oas": "^20.4.0",
|
|
65
62
|
"ora": "^5.4.1",
|
|
66
|
-
"prettier": "^2.8.3",
|
|
67
63
|
"prompts": "^2.4.2",
|
|
68
64
|
"remove-undefined-objects": "^2.0.2",
|
|
69
65
|
"semver": "^7.3.8",
|
|
@@ -75,27 +71,21 @@
|
|
|
75
71
|
"@readme/oas-examples": "^5.9.0",
|
|
76
72
|
"@types/caseless": "^0.12.2",
|
|
77
73
|
"@types/find-cache-dir": "^3.2.1",
|
|
78
|
-
"@types/jest": "^29.5.2",
|
|
79
74
|
"@types/js-yaml": "^4.0.5",
|
|
80
|
-
"@types/lodash
|
|
81
|
-
"@types/lodash.deburr": "^4.1.7",
|
|
82
|
-
"@types/lodash.merge": "^4.6.7",
|
|
83
|
-
"@types/lodash.setwith": "^4.3.7",
|
|
84
|
-
"@types/lodash.startcase": "^4.4.7",
|
|
75
|
+
"@types/lodash": "^4.17.6",
|
|
85
76
|
"@types/prettier": "^2.7.2",
|
|
86
77
|
"@types/prompts": "^2.4.2",
|
|
87
78
|
"@types/semver": "^7.3.13",
|
|
88
79
|
"@types/ssri": "^7.1.1",
|
|
89
80
|
"@types/validate-npm-package-name": "^4.0.0",
|
|
81
|
+
"@vitest/coverage-v8": "^0.34.1",
|
|
90
82
|
"fetch-mock": "^9.11.0",
|
|
91
|
-
"jest": "^29.6.1",
|
|
92
|
-
"jest-extended": "^4.0.0",
|
|
93
83
|
"oas-normalize": "^8.3.2",
|
|
94
|
-
"
|
|
95
|
-
"type-fest": "^3.5.4",
|
|
84
|
+
"type-fest": "^4.2.0",
|
|
96
85
|
"typescript": "^4.9.5",
|
|
97
|
-
"unique-temp-dir": "^1.0.0"
|
|
86
|
+
"unique-temp-dir": "^1.0.0",
|
|
87
|
+
"vitest": "^0.34.1"
|
|
98
88
|
},
|
|
99
89
|
"prettier": "@readme/eslint-config/prettier",
|
|
100
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "2c3ac4c926af40bd01c4fa1b528251f7f0b4211f"
|
|
101
91
|
}
|
package/src/cli/codegen/index.ts
CHANGED
|
@@ -49,7 +49,7 @@ export default abstract class CodeGeneratorLanguage {
|
|
|
49
49
|
*/
|
|
50
50
|
if (JSON.stringify(spec.api).includes('"$ref":"#/')) {
|
|
51
51
|
throw new Error(
|
|
52
|
-
'Sorry, this library does not yet support generating an SDK for an OpenAPI definition that contains circular references.'
|
|
52
|
+
'Sorry, this library does not yet support generating an SDK for an OpenAPI definition that contains circular references.',
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import camelCase from 'lodash
|
|
2
|
-
import deburr from 'lodash
|
|
3
|
-
import startCase from 'lodash
|
|
4
|
-
import { format as prettier } from 'prettier';
|
|
1
|
+
import camelCase from 'lodash/camelCase';
|
|
2
|
+
import deburr from 'lodash/deburr';
|
|
3
|
+
import startCase from 'lodash/startCase';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* This is a mix of reserved JS words and keywords in TypeScript that might be reserved or
|
|
@@ -100,14 +99,6 @@ const RESERVED_WORDS = [
|
|
|
100
99
|
'window',
|
|
101
100
|
];
|
|
102
101
|
|
|
103
|
-
export function formatter(content: string) {
|
|
104
|
-
return prettier(content, {
|
|
105
|
-
parser: 'typescript',
|
|
106
|
-
printWidth: 100,
|
|
107
|
-
singleQuote: true,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
102
|
/**
|
|
112
103
|
* @see {@link https://www.30secondsofcode.org/js/s/word-wrap}
|
|
113
104
|
*/
|
|
@@ -16,14 +16,14 @@ import fs from 'fs';
|
|
|
16
16
|
import path from 'path';
|
|
17
17
|
|
|
18
18
|
import execa from 'execa';
|
|
19
|
-
import setWith from 'lodash
|
|
19
|
+
import setWith from 'lodash/setWith';
|
|
20
20
|
import semver from 'semver';
|
|
21
21
|
import { IndentationText, Project, QuoteKind, ScriptTarget, VariableDeclarationKind } from 'ts-morph';
|
|
22
22
|
|
|
23
23
|
import logger from '../../logger';
|
|
24
24
|
import CodeGeneratorLanguage from '../language';
|
|
25
25
|
|
|
26
|
-
import { docblockEscape,
|
|
26
|
+
import { docblockEscape, generateTypeName, wordWrap } from './typescript/util';
|
|
27
27
|
|
|
28
28
|
export interface TSGeneratorOptions {
|
|
29
29
|
compilerTarget?: 'cjs' | 'esm';
|
|
@@ -245,7 +245,7 @@ export default class TSGenerator extends CodeGeneratorLanguage {
|
|
|
245
245
|
return {};
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
let code =
|
|
248
|
+
let code = sourceFile.text;
|
|
249
249
|
if (file === 'index.js' && this.compilerTarget === 'cjs') {
|
|
250
250
|
/**
|
|
251
251
|
* There's an annoying quirk with `ts-morph` where if we're exporting a default export
|
|
@@ -271,7 +271,7 @@ export default class TSGenerator extends CodeGeneratorLanguage {
|
|
|
271
271
|
|
|
272
272
|
return [
|
|
273
273
|
...this.project.getSourceFiles().map(sourceFile => ({
|
|
274
|
-
[sourceFile.getBaseName()]:
|
|
274
|
+
[sourceFile.getBaseName()]: sourceFile.getFullText(),
|
|
275
275
|
})),
|
|
276
276
|
|
|
277
277
|
// Because we're returning the raw source files for TS generation we also need to separately
|
|
@@ -281,7 +281,7 @@ export default class TSGenerator extends CodeGeneratorLanguage {
|
|
|
281
281
|
.emitToMemory({ emitOnlyDtsFiles: true })
|
|
282
282
|
.getFiles()
|
|
283
283
|
.map(sourceFile => ({
|
|
284
|
-
[path.basename(sourceFile.filePath)]:
|
|
284
|
+
[path.basename(sourceFile.filePath)]: sourceFile.text,
|
|
285
285
|
})),
|
|
286
286
|
].reduce((prev, next) => Object.assign(prev, next));
|
|
287
287
|
}
|
|
@@ -340,7 +340,7 @@ export default class TSGenerator extends CodeGeneratorLanguage {
|
|
|
340
340
|
{
|
|
341
341
|
tagName: 'param',
|
|
342
342
|
text: wordWrap(
|
|
343
|
-
'config.timeout Override the default `fetch` request timeout of 30 seconds. This number should be represented in milliseconds.'
|
|
343
|
+
'config.timeout Override the default `fetch` request timeout of 30 seconds. This number should be represented in milliseconds.',
|
|
344
344
|
),
|
|
345
345
|
},
|
|
346
346
|
],
|
|
@@ -370,7 +370,7 @@ sdk.auth('username', 'password');
|
|
|
370
370
|
sdk.auth('myBearerToken');
|
|
371
371
|
|
|
372
372
|
@example <caption>API Keys</caption>
|
|
373
|
-
sdk.auth('myApiKey');`)
|
|
373
|
+
sdk.auth('myApiKey');`),
|
|
374
374
|
),
|
|
375
375
|
tags: [
|
|
376
376
|
{ tagName: 'see', text: '{@link https://spec.openapis.org/oas/v3.0.3#fixed-fields-22}' },
|
|
@@ -403,7 +403,7 @@ sdk.server('https://{region}.api.example.com/{basePath}', {
|
|
|
403
403
|
});
|
|
404
404
|
|
|
405
405
|
@example <caption>Fully qualified server URL</caption>
|
|
406
|
-
sdk.server('https://eu.api.example.com/v14');`)
|
|
406
|
+
sdk.server('https://eu.api.example.com/v14');`),
|
|
407
407
|
),
|
|
408
408
|
tags: [
|
|
409
409
|
{ tagName: 'param', text: 'url Server URL' },
|
|
@@ -536,7 +536,7 @@ sdk.server('https://eu.api.example.com/v14');`)
|
|
|
536
536
|
operation: Operation,
|
|
537
537
|
operationId: string,
|
|
538
538
|
paramTypes?: OperationTypeHousing['types']['params'],
|
|
539
|
-
responseTypes?: OperationTypeHousing['types']['responses']
|
|
539
|
+
responseTypes?: OperationTypeHousing['types']['responses'],
|
|
540
540
|
) {
|
|
541
541
|
let docblock: OptionalKind<JSDocStructure> = {};
|
|
542
542
|
const summary = operation.getSummary();
|
|
@@ -676,7 +676,7 @@ sdk.server('https://eu.api.example.com/v14');`)
|
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
fetchStmt.write(arg.name);
|
|
679
|
-
if (
|
|
679
|
+
if (i !== totalParams - 1) {
|
|
680
680
|
fetchStmt.write(', ');
|
|
681
681
|
}
|
|
682
682
|
});
|
|
@@ -24,7 +24,7 @@ cmd
|
|
|
24
24
|
'js-cjs',
|
|
25
25
|
'js-esm',
|
|
26
26
|
'ts',
|
|
27
|
-
])
|
|
27
|
+
]),
|
|
28
28
|
)
|
|
29
29
|
.addOption(new Option('-y, --yes', 'Automatically answer "yes" to any prompts printed'))
|
|
30
30
|
.action(async (uri: string, options: { identifier?: string; lang: string; yes?: boolean }) => {
|
|
@@ -188,7 +188,7 @@ cmd
|
|
|
188
188
|
Examples:
|
|
189
189
|
$ api install @developers/v2.0#nysezql0wwo236
|
|
190
190
|
$ api install https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore-simple.json
|
|
191
|
-
$ api install ./petstore.json
|
|
191
|
+
$ api install ./petstore.json`,
|
|
192
192
|
);
|
|
193
193
|
|
|
194
194
|
export default cmd;
|
package/src/cli/lib/prompt.ts
CHANGED
|
@@ -9,7 +9,7 @@ import prompts from 'prompts';
|
|
|
9
9
|
*/
|
|
10
10
|
export default async function promptTerminal<T extends string = string>(
|
|
11
11
|
question: prompts.PromptObject<T>,
|
|
12
|
-
options?: prompts.Options
|
|
12
|
+
options?: prompts.Options,
|
|
13
13
|
) {
|
|
14
14
|
const enableTerminalCursor = () => {
|
|
15
15
|
process.stdout.write('\x1B[?25h');
|
|
@@ -26,7 +26,7 @@ export default function getJSONSchemaDefaults(jsonSchemas: SchemaWrapper[]) {
|
|
|
26
26
|
parentPointer: string,
|
|
27
27
|
parentKeyword: string,
|
|
28
28
|
parentSchema: SchemaObject,
|
|
29
|
-
indexProperty: string
|
|
29
|
+
indexProperty: string,
|
|
30
30
|
) => {
|
|
31
31
|
if (!pointer.startsWith('/properties/')) {
|
|
32
32
|
return;
|
|
@@ -58,7 +58,7 @@ export default function getJSONSchemaDefaults(jsonSchemas: SchemaWrapper[]) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
}
|
|
61
|
+
},
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
if (!Object.keys(defaults).length) {
|
package/src/core/index.ts
CHANGED
package/src/core/prepareAuth.ts
CHANGED
|
@@ -26,7 +26,7 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope
|
|
|
26
26
|
// Does this operation require multiple forms of auth?
|
|
27
27
|
if (security.every(s => Object.keys(s).length > 1)) {
|
|
28
28
|
throw new Error(
|
|
29
|
-
"Sorry, this operation currently requires multiple forms of authentication which this library doesn't yet support."
|
|
29
|
+
"Sorry, this operation currently requires multiple forms of authentication which this library doesn't yet support.",
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -54,7 +54,7 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope
|
|
|
54
54
|
const schemes = preparedSecurity.Basic.filter(s => usableSecuritySchemes.includes(s._key));
|
|
55
55
|
if (!schemes.length) {
|
|
56
56
|
throw new Error(
|
|
57
|
-
'Credentials for Basic Authentication were supplied but this operation requires another form of auth in that case, which this library does not yet support. This operation does, however, allow supplying a single auth token.'
|
|
57
|
+
'Credentials for Basic Authentication were supplied but this operation requires another form of auth in that case, which this library does not yet support. This operation does, however, allow supplying a single auth token.',
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -101,7 +101,7 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope
|
|
|
101
101
|
|
|
102
102
|
default:
|
|
103
103
|
throw new Error(
|
|
104
|
-
`Sorry, this API currently uses a security scheme, ${scheme.type}, which this library doesn't yet support
|
|
104
|
+
`Sorry, this API currently uses a security scheme, ${scheme.type}, which this library doesn't yet support.`,
|
|
105
105
|
);
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -10,7 +10,7 @@ import caseless from 'caseless';
|
|
|
10
10
|
import DatauriParser from 'datauri/parser';
|
|
11
11
|
import datauri from 'datauri/sync';
|
|
12
12
|
import getStream from 'get-stream';
|
|
13
|
-
import lodashMerge from 'lodash
|
|
13
|
+
import lodashMerge from 'lodash/merge';
|
|
14
14
|
import removeUndefinedObjects from 'remove-undefined-objects';
|
|
15
15
|
|
|
16
16
|
import getJSONSchemaDefaults from './getJSONSchemaDefaults';
|
|
@@ -32,7 +32,7 @@ function digestParameters(parameters: ParameterObject[]): Record<string, Paramet
|
|
|
32
32
|
throw new Error("The OpenAPI document for this operation wasn't dereferenced before processing.");
|
|
33
33
|
} else if (param.name in prev) {
|
|
34
34
|
throw new Error(
|
|
35
|
-
`The operation you are using has the same parameter, ${param.name}, spread across multiple entry points. We unfortunately can't handle this right now
|
|
35
|
+
`The operation you are using has the same parameter, ${param.name}, spread across multiple entry points. We unfortunately can't handle this right now.`,
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -54,7 +54,7 @@ function isObject(thing: any) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function isPrimitive(obj: any) {
|
|
57
|
-
return
|
|
57
|
+
return obj === null || typeof obj === 'number' || typeof obj === 'string';
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function merge(src: any, target: any) {
|
|
@@ -75,7 +75,7 @@ function merge(src: any, target: any) {
|
|
|
75
75
|
*/
|
|
76
76
|
function processFile(
|
|
77
77
|
paramName: string,
|
|
78
|
-
file: string | ReadStream
|
|
78
|
+
file: string | ReadStream,
|
|
79
79
|
): Promise<{ base64: string; buffer: Buffer; filename: string; paramName: string }> {
|
|
80
80
|
if (typeof file === 'string') {
|
|
81
81
|
// In order to support relative pathed files, we need to attempt to resolve them.
|
|
@@ -129,8 +129,8 @@ function processFile(
|
|
|
129
129
|
new TypeError(
|
|
130
130
|
paramName
|
|
131
131
|
? `The data supplied for the \`${paramName}\` request body parameter is not a file handler that we support.`
|
|
132
|
-
: 'The data supplied for the request body payload is not a file handler that we support.'
|
|
133
|
-
)
|
|
132
|
+
: 'The data supplied for the request body payload is not a file handler that we support.',
|
|
133
|
+
),
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -179,7 +179,7 @@ export default async function prepareParams(operation: Operation, body?: unknown
|
|
|
179
179
|
|
|
180
180
|
if (throwNoParamsError) {
|
|
181
181
|
throw new Error(
|
|
182
|
-
"You supplied metadata and/or body data for this operation but it doesn't have any documented parameters or request payloads. If you think this is an error please contact support for the API you're using."
|
|
182
|
+
"You supplied metadata and/or body data for this operation but it doesn't have any documented parameters or request payloads. If you think this is an error please contact support for the API you're using.",
|
|
183
183
|
);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -332,6 +332,7 @@ export default async function prepareParams(operation: Operation, body?: unknown
|
|
|
332
332
|
if (typeof metadata === 'object' && !isEmpty(metadata)) {
|
|
333
333
|
if (paramName in metadata) {
|
|
334
334
|
value = metadata[paramName];
|
|
335
|
+
metadataHeaderParam = paramName;
|
|
335
336
|
} else if (param.in === 'header') {
|
|
336
337
|
// Headers are sent case-insensitive so we need to make sure that we're properly
|
|
337
338
|
// matching them when detecting what our incoming payload looks like.
|
|
@@ -379,9 +380,7 @@ export default async function prepareParams(operation: Operation, body?: unknown
|
|
|
379
380
|
// If there's any leftover metadata that hasn't been moved into form data for this request we
|
|
380
381
|
// need to move it or else it'll get tossed.
|
|
381
382
|
if (!isEmpty(metadata)) {
|
|
382
|
-
if (
|
|
383
|
-
params.formData = merge(params.formData, metadata);
|
|
384
|
-
} else if (typeof metadata === 'object') {
|
|
383
|
+
if (typeof metadata === 'object') {
|
|
385
384
|
// If the user supplied an `accept` or `authorization` header themselves we should allow it
|
|
386
385
|
// through. Normally these headers are automatically handled by `@readme/oas-to-har` but in
|
|
387
386
|
// the event that maybe the user wants to return XML for an API that normally returns JSON
|
|
@@ -391,8 +390,14 @@ export default async function prepareParams(operation: Operation, body?: unknown
|
|
|
391
390
|
const headerParam = Object.keys(metadata).find(m => m.toLowerCase() === headerName);
|
|
392
391
|
if (headerParam) {
|
|
393
392
|
params.header[headerName] = metadata[headerParam] as string;
|
|
393
|
+
// eslint-disable-next-line no-param-reassign
|
|
394
|
+
delete metadata[headerParam];
|
|
394
395
|
}
|
|
395
396
|
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (operation.isFormUrlEncoded()) {
|
|
400
|
+
params.formData = merge(params.formData, metadata);
|
|
396
401
|
} else {
|
|
397
402
|
// Any other remaining unused metadata will be unused because we don't know where to place
|
|
398
403
|
// it in the request.
|
package/src/fetcher.ts
CHANGED
|
@@ -14,7 +14,6 @@ export default class Fetcher {
|
|
|
14
14
|
* @example @petstore/v1.0#n6kvf10vakpemvplx
|
|
15
15
|
* @example @petstore#n6kvf10vakpemvplx
|
|
16
16
|
*/
|
|
17
|
-
// eslint-disable-next-line unicorn/no-unsafe-regex
|
|
18
17
|
static registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;
|
|
19
18
|
|
|
20
19
|
constructor(uri: string | OASDocument) {
|
|
@@ -59,7 +58,7 @@ export default class Fetcher {
|
|
|
59
58
|
async load() {
|
|
60
59
|
if (typeof this.uri !== 'string') {
|
|
61
60
|
throw new TypeError(
|
|
62
|
-
"Something disastrous occurred and a non-string URI was supplied to the Fetcher library. This shouldn't have happened!"
|
|
61
|
+
"Something disastrous occurred and a non-string URI was supplied to the Fetcher library. This shouldn't have happened!",
|
|
63
62
|
);
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -103,7 +102,7 @@ export default class Fetcher {
|
|
|
103
102
|
|
|
104
103
|
if (!fs.existsSync(file)) {
|
|
105
104
|
throw new Error(
|
|
106
|
-
`Sorry, we were unable to load an API definition from ${file}. Please either supply a URL or a path on your filesystem
|
|
105
|
+
`Sorry, we were unable to load an API definition from ${file}. Please either supply a URL or a path on your filesystem.`,
|
|
107
106
|
);
|
|
108
107
|
}
|
|
109
108
|
|
package/src/packageInfo.ts
CHANGED
package/tsconfig.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"noImplicitAny": true,
|
|
9
9
|
"outDir": "dist/",
|
|
10
10
|
"paths": {
|
|
11
|
-
// Because this library uses ES2015+ `#private` syntax that would require us to
|
|
11
|
+
// Because this library uses ES2015+ `#private` syntax that would require us to make this
|
|
12
12
|
// library ESM-only we're overloading its types with a `paths` config with this empty file.
|
|
13
13
|
// This isn't a great solution as we're losing type checks where this library is used, but
|
|
14
14
|
// it's far too early in the ESM lifecycle for us to make API an ESM-only library.
|