Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(oas-to-snippet): plugin architecture #834

Merged
merged 4 commits into from
Nov 6, 2023
Merged

Conversation

erunion
Copy link
Member

@erunion erunion commented Nov 2, 2023

🧰 Changes

This pulls in the new plugin architecture I added to @readme/httpsnippet in readmeio/httpsnippet#206 so we can now do a couple great things:

  • Decouple httpsnippet-client-api completely from this library. httpsnippet-client-api depending on oas and being used here has historically made bumping major oas releases a lot more problematic than it should be.
    • I'm going to treat this as a breaking change since api snippets will no longer be natively supported by this library without the httpsnippet-client-api plugin for it.
  • Allow for the dynamic installation of any new HTTPSnippet-compatible plugin, thereby extending our code snippet generation to custom externally developed language clients.
    • For example a certain unnamed finance company could create a new package on NPM httpsnippet-plugin-companyname and we could generate snippets with a new [node, companyname] language 🧙 like magic 🪄

I've also refactored our /supportedLanguages export to now be a getSupportedLanguages function we'll call to retrieve the languages we support. Had to make this change in order to load custom plugins into the supported languages configuration and make them be available as a supported language. 🐔 🥚

I don't have any docs written on the plugin system but will write those at some point before this work goes live in our API Explorer.

@erunion erunion added the enhancement New feature or request label Nov 2, 2023
@erunion erunion marked this pull request as ready for review November 2, 2023 22:41
@@ -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,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trimmed these Markdown code snippet lines down to 100 character lengths because 120 looks like shit on small screens on NPM and Github.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw i don't think this is a huge deal since both npm and github support side-scrolling on these code samples and even 100 characters is still too wide for certain screens like mobile etc.

httpclient: { name: 'HttpClient' },
restsharp: {
name: 'RestSharp',
install: 'dotnet add package RestSharp',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This supportedLanguages config now lives at the DEFAULT_LANGAUGES config in languages.ts and is largely the same except for two changes:

  • api is no longer listed here under node because that's been offloaded to our httpsnippet-client-api plugin.
  • install has moved directly into @readme/httpsnippet client configurations so that information is as close to the snippet generator as possible.

let language: TargetId;
let target: ClientId;

switch (lang) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks so much cleaner than that big if statement!

Copy link
Member

@kanadgupta kanadgupta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few initial questions, i might set up a proper sandbox environment to test this out with @darrenyong later today!

packages/oas-to-snippet/package.json Show resolved Hide resolved
packages/oas-to-snippet/src/index.ts Show resolved Hide resolved
packages/oas-to-snippet/src/languages.ts Outdated Show resolved Hide resolved
packages/oas-to-snippet/README.md Show resolved Hide resolved
packages/oas-to-snippet/README.md Show resolved Hide resolved
Comment on lines +94 to +101
// Our `httpsnippet-client-api` plugin uses these options so we need to pass them along.
if (plugin.target === 'node' && plugin.client.info.key === 'api') {
targetOpts.api = {
definition: oas ? oas.getDefinition() : null,
identifier: opts?.openapi?.variableName,
registryURI: opts?.openapi?.registryIdentifier,
};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe i'm misunderstanding how all of this fits together, but i feel like this logic (and its corresponding opts) should be in the plugin code, not here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is, but these options need to get passed along from here into the plugin and the plugin wants these options as an api object. im not really sure on the best way to handle a plugin that has its own options like this other than this thing i've got here.

*
* @example @developers/v2.0#17273l2glm9fq4l5
*/
registryIdentifier?: string,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i imagine other plugins might want custom installation steps similar to api does, could we make this (and its corresponding JSDocs) more generic (i.e., call it packageName)?

Copy link
Member Author

@erunion erunion Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this work is a little confusing but the registryIdentifier here is the npx api install <registry identifier> part of things and variableName is the eventual post-installation package name (as that ties into the custom SDK variable name support).

Copy link
Member Author

@erunion erunion Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could maybe have the config for the plugin supplied alongside the plugin but that's going to require a lot of work to httpsnippet as it doesn't support options like this

const snippet = await oasToSnippet(
  petstore,
  petstore.operation('/user/login', 'get'),
  formData,
  auth,
  ['node', 'api'],
  {
    plugins: [httpsnippetClientAPIPlugin({ 
      api: { 
        registryIdentifier: '@petstore/v2.0#17273l2glm9fq4l5',
      }
     })],
  },
);

@erunion erunion requested a review from kanadgupta November 3, 2023 17:08
packages/oas-to-snippet/README.md Outdated Show resolved Hide resolved
Co-authored-by: Kanad Gupta <[email protected]>
@erunion erunion merged commit a01e319 into main Nov 6, 2023
5 checks passed
@erunion erunion deleted the feat/snippet-plugin-system branch November 6, 2023 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants