diff --git a/package-lock.json b/package-lock.json index 624e6daf..88a2e023 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22734,7 +22734,6 @@ "license": "MIT", "dependencies": { "@readme/api-core": "file:../core", - "@readme/oas-to-har": "^23.0.14", "@readme/openapi-parser": "^2.4.0", "chalk": "^5.3.0", "commander": "^11.1.0", diff --git a/packages/api/package.json b/packages/api/package.json index d92e87c3..17c181db 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -44,7 +44,6 @@ ], "dependencies": { "@readme/api-core": "file:../core", - "@readme/oas-to-har": "^23.0.14", "@readme/openapi-parser": "^2.4.0", "chalk": "^5.3.0", "commander": "^11.1.0", diff --git a/packages/api/src/lib/suggestedOperations.ts b/packages/api/src/lib/suggestedOperations.ts index e2b20283..4571c49b 100644 --- a/packages/api/src/lib/suggestedOperations.ts +++ b/packages/api/src/lib/suggestedOperations.ts @@ -2,7 +2,7 @@ import type { AuthForHAR } from '@readme/oas-to-har/lib/types'; import type Oas from 'oas'; import type Operation from 'oas/operation'; -import oasToHar from '@readme/oas-to-har'; +import APICore from '@readme/api-core'; import client from 'httpsnippet-client-api'; import { Webhook } from 'oas/operation'; @@ -55,8 +55,19 @@ export function getSuggestedOperation(oas: Oas) { * Generate an example code snippet for a given (suggested) operation. We'll show this to users * post-codegeneration so they can see how to use the SDK we created for them. * + * We're intentionally using `httpsnippet-client-api` and not `@readme/oas-to-snippet` here, + * which would handle HAR and snippet generation, because don't need the entire `oas-to-snippet` + * and `@readme/httpsnippet` libraries for what we're doing here. + * + * All we want to do is generate a very simple code example for `api` snippets and as we're + * controlling which kinds of endpoints we're generating these for the HAR dataset we're working + * with is a mostly fully known object. + * */ export async function buildCodeSnippetForOperation(oas: Oas, operation: Operation, opts: { identifier: string }) { + const core = new APICore(); + core.setSpec(oas); + // If this endpoint has authentication on it then we should try to flesh out some placeholder // values in the `.auth()` SDK method for them so they can see how to use auth. let auth: AuthForHAR = {}; @@ -80,12 +91,7 @@ export async function buildCodeSnippetForOperation(oas: Oas, operation: Operatio auth = oas.getAuth(auth) as AuthForHAR; } - // We're pulling in `@reamde/oas-to-har` and `httpsnippet-client-api` here instead of using - // `@readme/oas-to-snippet`, which would handle both, because we don't need the entire - // `oas-to-snippet` for what we're doing here. All we want to do is generate a very simple code - // example for `api` snippets and because we're controlling which kinds of endpoints we're - // generating this for the HAR dataset we're working with here is mostly a fully known object. - const har = oasToHar(oas, operation, undefined, auth)?.log?.entries?.[0]?.request; + const har = core.getHARForRequest(operation, {}, auth)?.log?.entries?.[0]?.request; if (!har) { return false; } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 168c7163..a91d7f4f 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,4 +1,5 @@ import type { ConfigOptions } from './types.js'; +import type { AuthForHAR, DataForHAR } from '@readme/oas-to-har/lib/types'; import type { Har } from 'har-format'; import type Operation from 'oas/operation'; import type { HttpMethods, OASDocument } from 'oas/rmoas.types'; @@ -66,6 +67,15 @@ export default class APICore { return this.fetchOperation(operation, body, metadata); } + /** + * Retrieve a HAR for a given HTTP request. + * + * @internal + */ + getHARForRequest(operation: Operation, data: DataForHAR, auth: AuthForHAR) { + return oasToHar(this.spec, operation, data, auth); + } + async fetchOperation( operation: Operation, body?: unknown, @@ -84,8 +94,7 @@ export default class APICore { } } - // @ts-expect-error `this.auth` typing is off. FIXME - const har = oasToHar(this.spec, operation, data, prepareAuth(this.auth, operation)); + const har = this.getHARForRequest(operation, data, prepareAuth(this.auth, operation)); let timeoutSignal: NodeJS.Timeout; const init: RequestInit = {}; diff --git a/packages/core/src/lib/prepareAuth.ts b/packages/core/src/lib/prepareAuth.ts index 0fb8ff45..ed2674da 100644 --- a/packages/core/src/lib/prepareAuth.ts +++ b/packages/core/src/lib/prepareAuth.ts @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +import type { AuthForHAR } from '@readme/oas-to-har/lib/types'; import type Operation from 'oas/operation'; import type { KeyedSecuritySchemeObject } from 'oas/rmoas.types'; @@ -7,15 +8,7 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope return {}; } - const preparedAuth: Record< - string, - | string - | number - | { - pass: string | number; - user: string | number; - } - > = {}; + const preparedAuth: AuthForHAR = {}; const security = operation.getSecurity(); if (security.length === 0) { @@ -61,8 +54,8 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope const scheme = schemes.shift() as KeyedSecuritySchemeObject; preparedAuth[scheme._key] = { - user: authKey[0], - pass: authKey.length === 2 ? authKey[1] : '', + user: String(authKey[0]), + pass: authKey.length === 2 ? String(authKey[1]) : '', }; return preparedAuth; @@ -82,8 +75,8 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope case 'http': if (scheme.scheme === 'basic') { preparedAuth[scheme._key] = { - user: authKey[0], - pass: authKey.length === 2 ? authKey[1] : '', + user: String(authKey[0]), + pass: authKey.length === 2 ? String(authKey[1]) : '', }; } else if (scheme.scheme === 'bearer') { preparedAuth[scheme._key] = authKey[0];