@readme/api-core 7.0.0-alpha.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 ADDED
@@ -0,0 +1,18 @@
1
+ Copyright © 2023 ReadMe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the “Software”), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OUT OF OR IN CONNECTION WITH THE
18
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # @readme/api-core
2
+
3
+ <p align="center">
4
+ <a href="https://npm.im/@readme/api-core"><img src="https://img.shields.io/npm/v/@readme/api-core?style=for-the-badge" alt="NPM Version"></a>
5
+ <a href="https://npm.im/@readme/api-core"><img src="https://img.shields.io/node/v/@readme/api-core?style=for-the-badge" alt="Node Version"></a>
6
+ <a href="https://npm.im/@readme/api-core"><img src="https://img.shields.io/npm/l/@readme/api-core?style=for-the-badge" alt="MIT License"></a>
7
+ <a href="https://github.com/readmeio/api"><img src="https://img.shields.io/github/actions/workflow/status/readmeio/api/ci.yml?branch=main&style=for-the-badge" alt="Build status"></a>
8
+ </p>
9
+
10
+ <p align="center">
11
+ The magic behind <code>api</code> 🧙
12
+ </p>
13
+
14
+ <p align="center">
15
+ Check out <a href="https://api.readme.dev">api.readme.dev</a> for more details.
16
+ </p>
@@ -0,0 +1,12 @@
1
+ declare class FetchError<Status = number, Data = unknown> extends Error {
2
+ /** HTTP Status */
3
+ status: Status;
4
+ /** The content of the response. */
5
+ data: Data;
6
+ /** The Headers of the response. */
7
+ headers: Headers;
8
+ /** The raw `Response` object. */
9
+ res: Response;
10
+ constructor(status: Status, data: Data, headers: Headers, res: Response);
11
+ }
12
+ export default FetchError;
@@ -0,0 +1,36 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ var FetchError = /** @class */ (function (_super) {
19
+ __extends(FetchError, _super);
20
+ function FetchError(status, data, headers, res) {
21
+ var _this = _super.call(this, res.statusText) || this;
22
+ _this.name = 'FetchError';
23
+ _this.status = status;
24
+ _this.data = data;
25
+ _this.headers = headers;
26
+ _this.res = res;
27
+ // We could fix this by updating our target to ES2015 but because we support exporting to CJS
28
+ // we can't.
29
+ //
30
+ // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
31
+ Object.setPrototypeOf(_this, FetchError.prototype);
32
+ return _this;
33
+ }
34
+ return FetchError;
35
+ }(Error));
36
+ exports.default = FetchError;
@@ -0,0 +1,49 @@
1
+ import type Oas from 'oas';
2
+ import type { Operation } from 'oas';
3
+ import type { HttpMethods } from 'oas/dist/rmoas.types';
4
+ import getJSONSchemaDefaults from './lib/getJSONSchemaDefaults';
5
+ import parseResponse from './lib/parseResponse';
6
+ import prepareAuth from './lib/prepareAuth';
7
+ import prepareParams from './lib/prepareParams';
8
+ import prepareServer from './lib/prepareServer';
9
+ export interface ConfigOptions {
10
+ /**
11
+ * Override the default `fetch` request timeout of 30 seconds. This number should be represented
12
+ * in milliseconds.
13
+ */
14
+ timeout?: number;
15
+ }
16
+ export interface FetchResponse<HTTPStatus, Data> {
17
+ data: Data;
18
+ headers: Headers;
19
+ res: Response;
20
+ status: HTTPStatus;
21
+ }
22
+ type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc['length']]>;
23
+ export type HTTPMethodRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
24
+ export { getJSONSchemaDefaults, parseResponse, prepareAuth, prepareParams, prepareServer };
25
+ export default class APICore {
26
+ spec: Oas;
27
+ private auth;
28
+ private server;
29
+ private config;
30
+ private userAgent;
31
+ constructor(spec?: Oas, userAgent?: string);
32
+ setSpec(spec: Oas): void;
33
+ setConfig(config: ConfigOptions): this;
34
+ setUserAgent(userAgent: string): this;
35
+ setAuth(...values: string[] | number[]): this;
36
+ setServer(url: string, variables?: Record<string, string | number>): this;
37
+ fetch<HTTPStatus extends number = number>(path: string, method: HttpMethods, body?: unknown, metadata?: Record<string, unknown>): Promise<{
38
+ data: any;
39
+ status: HTTPStatus;
40
+ headers: Headers;
41
+ res: Response;
42
+ }>;
43
+ fetchOperation<HTTPStatus extends number = number>(operation: Operation, body?: unknown, metadata?: Record<string, unknown>): Promise<{
44
+ data: any;
45
+ status: HTTPStatus;
46
+ headers: Headers;
47
+ res: Response;
48
+ }>;
49
+ }
package/dist/index.js ADDED
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ 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;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.prepareServer = exports.prepareParams = exports.prepareAuth = exports.parseResponse = exports.getJSONSchemaDefaults = void 0;
54
+ var oas_to_har_1 = __importDefault(require("@readme/oas-to-har"));
55
+ var fetch_har_1 = __importDefault(require("fetch-har"));
56
+ var fetchError_1 = __importDefault(require("./errors/fetchError"));
57
+ var getJSONSchemaDefaults_1 = __importDefault(require("./lib/getJSONSchemaDefaults"));
58
+ exports.getJSONSchemaDefaults = getJSONSchemaDefaults_1.default;
59
+ var parseResponse_1 = __importDefault(require("./lib/parseResponse"));
60
+ exports.parseResponse = parseResponse_1.default;
61
+ var prepareAuth_1 = __importDefault(require("./lib/prepareAuth"));
62
+ exports.prepareAuth = prepareAuth_1.default;
63
+ var prepareParams_1 = __importDefault(require("./lib/prepareParams"));
64
+ exports.prepareParams = prepareParams_1.default;
65
+ var prepareServer_1 = __importDefault(require("./lib/prepareServer"));
66
+ exports.prepareServer = prepareServer_1.default;
67
+ var APICore = /** @class */ (function () {
68
+ function APICore(spec, userAgent) {
69
+ this.auth = [];
70
+ this.server = false;
71
+ this.config = {};
72
+ if (spec)
73
+ this.spec = spec;
74
+ if (userAgent)
75
+ this.userAgent = userAgent;
76
+ }
77
+ APICore.prototype.setSpec = function (spec) {
78
+ this.spec = spec;
79
+ };
80
+ APICore.prototype.setConfig = function (config) {
81
+ this.config = config;
82
+ return this;
83
+ };
84
+ APICore.prototype.setUserAgent = function (userAgent) {
85
+ this.userAgent = userAgent;
86
+ return this;
87
+ };
88
+ APICore.prototype.setAuth = function () {
89
+ var values = [];
90
+ for (var _i = 0; _i < arguments.length; _i++) {
91
+ values[_i] = arguments[_i];
92
+ }
93
+ this.auth = values;
94
+ return this;
95
+ };
96
+ APICore.prototype.setServer = function (url, variables) {
97
+ if (variables === void 0) { variables = {}; }
98
+ this.server = { url: url, variables: variables };
99
+ return this;
100
+ };
101
+ APICore.prototype.fetch = function (path, method, body, metadata) {
102
+ return __awaiter(this, void 0, void 0, function () {
103
+ var operation;
104
+ return __generator(this, function (_a) {
105
+ operation = this.spec.operation(path, method);
106
+ return [2 /*return*/, this.fetchOperation(operation, body, metadata)];
107
+ });
108
+ });
109
+ };
110
+ APICore.prototype.fetchOperation = function (operation, body, metadata) {
111
+ return __awaiter(this, void 0, void 0, function () {
112
+ var _this = this;
113
+ return __generator(this, function (_a) {
114
+ return [2 /*return*/, (0, prepareParams_1.default)(operation, body, metadata).then(function (params) {
115
+ var data = __assign({}, params);
116
+ // If `sdk.server()` has been issued data then we need to do some extra work to figure out
117
+ // how to use that supplied server, and also handle any server variables that were sent
118
+ // alongside it.
119
+ if (_this.server) {
120
+ var preparedServer = (0, prepareServer_1.default)(_this.spec, _this.server.url, _this.server.variables);
121
+ if (preparedServer) {
122
+ data.server = preparedServer;
123
+ }
124
+ }
125
+ // @ts-expect-error `this.auth` typing is off. FIXME
126
+ var har = (0, oas_to_har_1.default)(_this.spec, operation, data, (0, prepareAuth_1.default)(_this.auth, operation));
127
+ var timeoutSignal;
128
+ var init = {};
129
+ if (_this.config.timeout) {
130
+ var controller_1 = new AbortController();
131
+ timeoutSignal = setTimeout(function () { return controller_1.abort(); }, _this.config.timeout);
132
+ init.signal = controller_1.signal;
133
+ }
134
+ return (0, fetch_har_1.default)(har, {
135
+ files: data.files || {},
136
+ init: init,
137
+ userAgent: _this.userAgent,
138
+ })
139
+ .then(function (res) { return __awaiter(_this, void 0, void 0, function () {
140
+ var parsed;
141
+ return __generator(this, function (_a) {
142
+ switch (_a.label) {
143
+ case 0: return [4 /*yield*/, (0, parseResponse_1.default)(res)];
144
+ case 1:
145
+ parsed = _a.sent();
146
+ if (res.status >= 400 && res.status <= 599) {
147
+ throw new fetchError_1.default(parsed.status, parsed.data, parsed.headers, parsed.res);
148
+ }
149
+ return [2 /*return*/, parsed];
150
+ }
151
+ });
152
+ }); })
153
+ .finally(function () {
154
+ if (_this.config.timeout) {
155
+ clearTimeout(timeoutSignal);
156
+ }
157
+ });
158
+ })];
159
+ });
160
+ });
161
+ };
162
+ return APICore;
163
+ }());
164
+ exports.default = APICore;
@@ -0,0 +1,14 @@
1
+ import type { SchemaWrapper } from 'oas/dist/operation/get-parameters-as-json-schema';
2
+ /**
3
+ * Run through a JSON Schema object and compose up an object containing default data for any schema
4
+ * property that is required and also has a defined default.
5
+ *
6
+ * Code partially adapted from the `json-schema-default` package but modified to only return
7
+ * defaults of required properties.
8
+ *
9
+ * @todo This is a good candidate to be moved into a core `oas` library method.
10
+ * @see {@link https://github.com/mdornseif/json-schema-default}
11
+ */
12
+ export default function getJSONSchemaDefaults(jsonSchemas: SchemaWrapper[]): {
13
+ [x: string]: Record<string, unknown>;
14
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var json_schema_traverse_1 = __importDefault(require("json-schema-traverse"));
7
+ /**
8
+ * Run through a JSON Schema object and compose up an object containing default data for any schema
9
+ * property that is required and also has a defined default.
10
+ *
11
+ * Code partially adapted from the `json-schema-default` package but modified to only return
12
+ * defaults of required properties.
13
+ *
14
+ * @todo This is a good candidate to be moved into a core `oas` library method.
15
+ * @see {@link https://github.com/mdornseif/json-schema-default}
16
+ */
17
+ function getJSONSchemaDefaults(jsonSchemas) {
18
+ return jsonSchemas
19
+ .map(function (_a) {
20
+ var _b;
21
+ var payloadType = _a.type, jsonSchema = _a.schema;
22
+ var defaults = {};
23
+ (0, json_schema_traverse_1.default)(jsonSchema, function (schema, pointer, rootSchema, parentPointer, parentKeyword, parentSchema, indexProperty) {
24
+ if (!pointer.startsWith('/properties/')) {
25
+ return;
26
+ }
27
+ if (Array.isArray(parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.required) && (parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.required.includes(String(indexProperty)))) {
28
+ if (schema.type === 'object' && indexProperty) {
29
+ defaults[indexProperty] = {};
30
+ }
31
+ var destination_1 = defaults;
32
+ if (parentPointer) {
33
+ // To map nested objects correct we need to pick apart the parent pointer.
34
+ parentPointer
35
+ .replace(/\/properties/g, '')
36
+ .split('/')
37
+ .forEach(function (subSchema) {
38
+ if (subSchema === '') {
39
+ return;
40
+ }
41
+ destination_1 = (destination_1 === null || destination_1 === void 0 ? void 0 : destination_1[subSchema]) || {};
42
+ });
43
+ }
44
+ if (schema.default !== undefined) {
45
+ if (indexProperty !== undefined) {
46
+ destination_1[indexProperty] = schema.default;
47
+ }
48
+ }
49
+ }
50
+ });
51
+ if (!Object.keys(defaults).length) {
52
+ return {};
53
+ }
54
+ return _b = {},
55
+ // @todo should we filter out empty and undefined objects from here with `remove-undefined-objects`?
56
+ _b[payloadType] = defaults,
57
+ _b;
58
+ })
59
+ .reduce(function (prev, next) { return Object.assign(prev, next); });
60
+ }
61
+ exports.default = getJSONSchemaDefaults;
@@ -0,0 +1,6 @@
1
+ export default function parseResponse<HTTPStatus extends number = number>(response: Response): Promise<{
2
+ data: any;
3
+ status: HTTPStatus;
4
+ headers: Headers;
5
+ res: Response;
6
+ }>;
@@ -0,0 +1,71 @@
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 (g && (g = 0, op[0] && (_ = 0)), _) 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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var oas_1 = require("oas");
40
+ var matchesMimeType = oas_1.utils.matchesMimeType;
41
+ function parseResponse(response) {
42
+ return __awaiter(this, void 0, void 0, function () {
43
+ var contentType, isJSON, responseBody, data;
44
+ return __generator(this, function (_a) {
45
+ switch (_a.label) {
46
+ case 0:
47
+ contentType = response.headers.get('Content-Type');
48
+ isJSON = contentType && (matchesMimeType.json(contentType) || matchesMimeType.wildcard(contentType));
49
+ return [4 /*yield*/, response.text()];
50
+ case 1:
51
+ responseBody = _a.sent();
52
+ data = responseBody;
53
+ if (isJSON) {
54
+ try {
55
+ data = JSON.parse(responseBody);
56
+ }
57
+ catch (e) {
58
+ // If our JSON parsing failed then we can just return plaintext instead.
59
+ }
60
+ }
61
+ return [2 /*return*/, {
62
+ data: data,
63
+ status: response.status,
64
+ headers: response.headers,
65
+ res: response,
66
+ }];
67
+ }
68
+ });
69
+ });
70
+ }
71
+ exports.default = parseResponse;
@@ -0,0 +1,5 @@
1
+ import type { Operation } from 'oas';
2
+ export default function prepareAuth(authKey: (number | string)[], operation: Operation): Record<string, string | number | {
3
+ pass: string | number;
4
+ user: string | number;
5
+ }>;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function prepareAuth(authKey, operation) {
4
+ if (authKey.length === 0) {
5
+ return {};
6
+ }
7
+ var preparedAuth = {};
8
+ var security = operation.getSecurity();
9
+ if (security.length === 0) {
10
+ // If there's no auth configured on this operation, don't prepare anything (even if it was
11
+ // supplied by the user).
12
+ return {};
13
+ }
14
+ // Does this operation require multiple forms of auth?
15
+ if (security.every(function (s) { return Object.keys(s).length > 1; })) {
16
+ throw new Error("Sorry, this operation currently requires multiple forms of authentication which this library doesn't yet support.");
17
+ }
18
+ // Since we can only handle single auth security configurations, let's pull those out. This code
19
+ // is a bit opaque but `security` here may look like `[{ basic: [] }, { oauth2: [], basic: []}]`
20
+ // and are filtering it down to only single-auth requirements of `[{ basic: [] }]`.
21
+ var usableSecurity = security
22
+ .map(function (s) {
23
+ return Object.keys(s).length === 1 ? s : false;
24
+ })
25
+ .filter(Boolean);
26
+ var usableSecuritySchemes = usableSecurity.map(function (s) { return Object.keys(s); }).reduce(function (prev, next) { return prev.concat(next); }, []);
27
+ var preparedSecurity = operation.prepareSecurity();
28
+ // If we have two auth tokens present let's look for Basic Auth in their configuration.
29
+ if (authKey.length >= 2) {
30
+ // If this operation doesn't support HTTP Basic auth but we have two tokens, that's a paddlin.
31
+ if (!('Basic' in preparedSecurity)) {
32
+ throw new Error('Multiple auth tokens were supplied for this endpoint but only a single token is needed.');
33
+ }
34
+ // If we have two auth keys for Basic Auth but Basic isn't a usable security scheme (maybe it's
35
+ // part of an AND or auth configuration -- which we don't support) then we need to error out.
36
+ var schemes_1 = preparedSecurity.Basic.filter(function (s) { return usableSecuritySchemes.includes(s._key); });
37
+ if (!schemes_1.length) {
38
+ throw new Error('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.');
39
+ }
40
+ var scheme_1 = schemes_1.shift();
41
+ preparedAuth[scheme_1._key] = {
42
+ user: authKey[0],
43
+ pass: authKey.length === 2 ? authKey[1] : '',
44
+ };
45
+ return preparedAuth;
46
+ }
47
+ // If we know we don't need to use HTTP Basic auth because we have a username+password then we
48
+ // can pick the first usable security scheme available and try to use that. This might not always
49
+ // be the auth scheme that the user wants, but we don't have any other way for the user to tell
50
+ // us what they want with the current `sdk.auth()` API.
51
+ var usableScheme = usableSecuritySchemes[0];
52
+ var schemes = Object.entries(preparedSecurity)
53
+ .map(function (_a) {
54
+ var ps = _a[1];
55
+ return ps.filter(function (s) { return usableScheme === s._key; });
56
+ })
57
+ .reduce(function (prev, next) { return prev.concat(next); }, []);
58
+ var scheme = schemes.shift();
59
+ switch (scheme.type) {
60
+ case 'http':
61
+ if (scheme.scheme === 'basic') {
62
+ preparedAuth[scheme._key] = {
63
+ user: authKey[0],
64
+ pass: authKey.length === 2 ? authKey[1] : '',
65
+ };
66
+ }
67
+ else if (scheme.scheme === 'bearer') {
68
+ preparedAuth[scheme._key] = authKey[0];
69
+ }
70
+ break;
71
+ case 'oauth2':
72
+ preparedAuth[scheme._key] = authKey[0];
73
+ break;
74
+ case 'apiKey':
75
+ if (scheme.in === 'query' || scheme.in === 'header' || scheme.in === 'cookie') {
76
+ preparedAuth[scheme._key] = authKey[0];
77
+ }
78
+ break;
79
+ default:
80
+ throw new Error("Sorry, this API currently uses a security scheme, ".concat(scheme.type, ", which this library doesn't yet support."));
81
+ }
82
+ return preparedAuth;
83
+ }
84
+ exports.default = prepareAuth;
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import type { Operation } from 'oas';
3
+ /**
4
+ * With potentially supplied body and/or metadata we need to run through them against a given API
5
+ * operation to see what's what and prepare any available parameters to be used in an API request
6
+ * with `@readme/oas-to-har`.
7
+ *
8
+ */
9
+ export default function prepareParams(operation: Operation, body?: unknown, metadata?: Record<string, unknown>): Promise<{
10
+ body?: any;
11
+ cookie?: Record<string, string | number | boolean> | undefined;
12
+ files?: Record<string, Buffer> | undefined;
13
+ formData?: any;
14
+ header?: Record<string, string | number | boolean> | undefined;
15
+ path?: Record<string, string | number | boolean> | undefined;
16
+ query?: Record<string, string | number | boolean> | undefined;
17
+ server?: {
18
+ selected: number;
19
+ variables: Record<string, string | number>;
20
+ } | undefined;
21
+ }>;