Skip to content

Commit

Permalink
feat(oas-to-snippet): plugin architecture (#834)
Browse files Browse the repository at this point in the history
* feat(oas-to-snippet): plugin architecture

* fix: pr feedback

* fix: pr feedback

* Update README.md

Co-authored-by: Kanad Gupta <[email protected]>

---------

Co-authored-by: Kanad Gupta <[email protected]>
  • Loading branch information
erunion and kanadgupta authored Nov 6, 2023
1 parent 00d0e80 commit a01e319
Show file tree
Hide file tree
Showing 16 changed files with 1,130 additions and 548 deletions.
81 changes: 20 additions & 61 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 41 additions & 20 deletions packages/oas-to-snippet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,62 @@ import petstore from './petstore.json';
const apiDefinition = new Oas(petstore);
const operation = apiDefinition.operation('/pets', 'get');

// This is a keyed object containing formData for your operation. Available keys are: path,
// query, cookie, header, formData, and body.
// This is a keyed object containing formData for your operation. Available keys
// are: path, query, cookie, header, formData, and body.
const formData = {
query: { sort: 'desc' },
};

// This is a keyed object containing authentication credentials for the operation. The keys for
// this object should match up with the `securityScheme` on the operation you're accessing, and
// its value should either be a String, or an Object containing `user` and/or `pass` (for Basic
// auth schemes).
// This is a keyed object containing authentication credentials for the
// operation. The keys for this object should match up with the `securityScheme`
// on the operation you're accessing, and its value should either be a String,
// or an Object containing `user` and/or `pass` (for Basic auth schemes).
const auth = {
oauth2: 'bearerToken',
};

// This is the language to generate a snippet to. See below for supported languages.
// This is the language to generate a snippet to. See below for supported
// languages.
//
// For supplying an alternative language target (like `axios` for `node`), you can do so by
// changing this variable to an array: `['node', 'axios']`. For the full list of alternative
// language targets that we support, see below.
// For supplying an alternative language target (like `axios` for `node`), you
// can do so by changing this variable to an array: `['node', 'axios']`. For the
// full list of alternative language targets that we support, see below.
const language = 'node';

// This `registryIdentifier` option is only necessary when using the `['node', 'api']` language
// combination. It controls how these snippets are used according to the code generation tooling
// that we offer with https://api.readme.dev/.
const registryIdentifier: '@petstore/v2.0#17273l2glm9fq4l5';
// This will return an object containing `code` and `highlightMode`. `code` is
// the generated code snippet, while `highlightMode` is the language mode you
// can use to render it for syntax highlighting (with `codemirror` for example).
const { code, highlightMode } = await oasToSnippet(apiDefinition, operation, formData, auth, language);
```

### Plugins

This library also supports the plugin system that we've built into [HTTPSnippet](https://npm.im/@readme/httpsnippet). We have a plugin for generating snippets for [ReadMe's API SDK generator](https://api.readme.dev) and this is how you would integrate and generate snippets for it:

// This will return an object containing `code` and `highlightMode`. `code` is the generated code
// snippet, while `highlightMode` is the language mode you can use to render it for syntax
// highlighting (with @readme/syntax-highlighter, for example).
const { code, highlightMode } = oasToSnippet(apiDefinition, operation, formData, auth, language, { openapi: { registryIdentifier } });
```js
import oasToSnippet from '@readme/oas-to-snippet';
import httpsnippetClientAPIPlugin from 'httpsnippet-client-api';

const snippet = await oasToSnippet(
petstore,
petstore.operation('/user/login', 'get'),
formData,
auth,
// `[node, api]` is not a standard language in `oas-to-snippet` but is
// dynamically made available via this loaded plugin.
['node', 'api'],
{
openapi: {
registryIdentifier: '@petstore/v2.0#17273l2glm9fq4l5',
},
plugins: [httpsnippetClientAPIPlugin],
},
);
```

## Supported Languages

Since this library uses [HTTP Snippet](https://github.com/Kong/httpsnippet), we support most of its languages, and their associated targets, which are the following:
Since this library uses [HTTPSnippet](https://npm.im/@readme/httpsnippet) we support most of its languages and their associated targets which are the following:

<!--
To regenerate the table below, run the following:
Expand All @@ -80,7 +101,7 @@ npm run build && node bin/generate-target-markdown-table.js
| JavaScript | `javascript` | [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), [Axios](https://github.com/axios/axios), [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), [jQuery](http://api.jquery.com/jquery.ajax/)
| JSON | `json` | [Native JSON](https://www.json.org/json-en.html)
| Kotlin | `kotlin` | [OkHttp](http://square.github.io/okhttp/)
| Node.js | `node` | [`api`](https://api.readme.dev), [HTTP](http://nodejs.org/api/http.html#http_http_request_options_callback), [Request](https://github.com/request/request), [Unirest](http://unirest.io/nodejs.html), [Axios](https://github.com/axios/axios), [Fetch](https://github.com/bitinn/node-fetch)
| Node.js | `node` | [HTTP](http://nodejs.org/api/http.html#http_http_request_options_callback), [Request](https://github.com/request/request), [Unirest](http://unirest.io/nodejs.html), [Axios](https://github.com/axios/axios), [Fetch](https://github.com/bitinn/node-fetch)
| Objective-C | `objectivec` | [NSURLSession](https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html)
| OCaml | `ocaml` | [CoHTTP](https://github.com/mirage/ocaml-cohttp)
| PHP | `php` | [cURL](http://php.net/manual/en/book.curl.php), [Guzzle](http://docs.guzzlephp.org/en/stable/), [HTTP v1](http://php.net/manual/en/book.http.php), [HTTP v2](http://devel-m6w6.rhcloud.com/mdref/http)
Expand Down
8 changes: 2 additions & 6 deletions packages/oas-to-snippet/bin/generate-target-markdown-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fs from 'node:fs/promises';

import { availableTargets } from '@readme/httpsnippet';

import supportedLanguages from '@readme/oas-to-snippet/supportedLanguages';
import { getSupportedLanguages } from '@readme/oas-to-snippet/languages';

const targets = availableTargets();

Expand All @@ -16,6 +16,7 @@ function getTarget(targetKey) {
*/
async function run() {
try {
const supportedLanguages = getSupportedLanguages();
const output = ['| Language | Available language mode(s) | Libraries (if applicable)', '| :---- | :---- | :---- |'];

Object.keys(supportedLanguages).forEach(lang => {
Expand Down Expand Up @@ -45,11 +46,6 @@ async function run() {
});
}

// backfill `api` since we're grabbing the clients list from httpsnippet
if (lang === 'node') {
libraries.unshift('[`api`](https://api.readme.dev)');
}

output.push(`| ${languageTitle} | \`${languageMode}\` | ${libraries.join(', ')}`.trim());
});

Expand Down
21 changes: 7 additions & 14 deletions packages/oas-to-snippet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,9 @@
"require": "./dist/index.cjs",
"import": "./dist/index.js"
},
"./supportedLanguages": {
"require": "./dist/supportedLanguages.cjs",
"import": "./dist/supportedLanguages.js"
},
"./types": {
"require": "./dist/types.d.cts",
"import": "./dist/types.d.ts"
},
"./utils": {
"require": "./dist/lib/utils.cjs",
"import": "./dist/lib/utils.js"
"./languages": {
"require": "./dist/languages.cjs",
"import": "./dist/languages.js"
},
"./package.json": "./package.json"
},
Expand All @@ -45,6 +37,7 @@
"scripts": {
"attw": "attw --pack --format table-flipped",
"build": "tsup",
"build:docs": "npm run build && node bin/generate-target-markdown-table.js",
"lint": "npm run lint:types && npm run lint:js",
"lint:js": "eslint . --ext .js,.ts --ignore-path ../../.gitignore",
"lint:types": "tsc --noEmit",
Expand All @@ -53,16 +46,16 @@
"test": "vitest run --coverage"
},
"dependencies": {
"@readme/httpsnippet": "^8.0.1",
"@readme/oas-to-har": "file:../oas-to-har",
"httpsnippet-client-api": "^7.0.0-beta.0"
"@readme/httpsnippet": "^8.1.3",
"@readme/oas-to-har": "file:../oas-to-har"
},
"devDependencies": {
"@readme/oas-examples": "^5.12.0",
"@types/har-format": "^1.2.14",
"@types/node": "^20.8.7",
"@vitest/coverage-v8": "^0.34.6",
"har-examples": "^3.1.1",
"httpsnippet-client-api": "^7.0.0-beta.4",
"oas": "file:../oas",
"tsup": "^7.2.0",
"type-fest": "^4.5.0",
Expand Down
Loading

0 comments on commit a01e319

Please sign in to comment.