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: remove node_native option from request snippets plugin #7181

Merged
merged 2 commits into from
Apr 14, 2021

Conversation

tim-lai
Copy link
Contributor

@tim-lai tim-lai commented Apr 14, 2021

  • snippet generator support intended for different shell options only
  • will not maintain snippet generator for various languages

Description

Remove the node_native generator from the Request Snippets Plugin

Motivation and Context

The original intent was to only support additional shell options, and not different languages. Language support is difficult to maintain. For users who would like to customize their own versions of SwaggerUI, language support is still possible via custom plugin, but will not be officially supported or maintained by SwaggerUI.

How Has This Been Tested?

visually checked local build that the node_native option has been removed.

Screenshots (if appropriate):

Checklist

My PR contains...

  • No code changes (src/ is unmodified: changes to documentation, CI, metadata, etc.)
  • Dependency changes (any modification to dependencies in package.json)
  • Bug fixes (non-breaking change which fixes an issue)
  • Improvements (misc. changes to existing features)
  • Features (non-breaking change which adds functionality)

My changes...

  • are breaking changes to a public API (config options, System API, major UI change, etc).
  • are breaking changes to a private API (Redux, component props, utility functions, etc.).
  • are breaking changes to a developer API (npm script behavior changes, new dev system dependencies, etc).
  • are not breaking changes.

Documentation

  • My changes do not require a change to the project documentation.
  • My changes require a change to the project documentation.
  • If yes to above: I have updated the documentation accordingly.

Automated tests

  • My changes can not or do not need to be tested.
  • My changes can and should be tested by unit and/or integration tests.
  • If yes to above: I have added tests to cover my changes.
  • If yes to above: I have taken care to cover edge cases in my tests.
  • All new and existing tests passed.

tim-lai added 2 commits April 14, 2021 10:20
* snippet generator support intended for different shell options only
* will not maintain snippet generator for various languages
@tim-lai tim-lai merged commit 2373a83 into swagger-api:master Apr 14, 2021
@tim-lai
Copy link
Contributor Author

tim-lai commented Apr 14, 2021

@mathis-m FYI.

@RobertLowe
Copy link

@tim-lai @mathis-m could this be reimplemented using https://github.com/ErikWittern/openapi-snippet which would handle all the language/shell/target specifics

@mathis-m
Copy link
Contributor

mathis-m commented Sep 14, 2021

@RobertLowe yes it can! I'll create documentation PR for this and will post the specific solution here.

@mathis-m
Copy link
Contributor

mathis-m commented Sep 15, 2021

@RobertLowe

For swagger-ui:

// Case Plain swagger-ui constructor config can be used :
const configForNotReact = {
  requestSnippetsEnabled: true,
  requestSnippets: {
    generators: {
      "node_native": {
        title: "NodeJs Native",
        syntax: "javascript"
      }
    }
  }
}

const SnippedGeneratorNotReact = {
  statePlugins: {
    // extend some internals to gain information about current path, method and spec in the generator function metioned later
    spec: {
      wrapSelectors: {
        requestFor: (ori, system) => (state, path, method) => {
          return ori(path, method)
            ?.set("spec", state.get("json", {}))
            ?.setIn(["oasPathMethod", "path"], path)
            ?.setIn(["oasPathMethod", "method"], method);
        },
        mutatedRequestFor: (ori) => (state, path, method) => {
          return ori(path, method)
            ?.set("spec", state.get("json", {}))
            ?.setIn(["oasPathMethod", "path"], path)
            ?.setIn(["oasPathMethod", "method"], method);
        }
      }
    }
  },
  fn: {
    // use `requestSnippetGenerator_` + key from config (node_native) for generator fn
    requestSnippetGenerator_node_native: (req) => {
      // get extended info about request
      const { spec, oasPathMethod } = req.toJS();
      const { path, method } = oasPathMethod;
      
      // run OpenAPISnippet for target node
      const targets = ["node_native"];
      let snippet;
      try {
        // set request snippet content
        snippet = OpenAPISnippet.getEndpointSnippets(
          spec,
          path,
          method,
          targets
        ).snippets[0].content;
      } catch (err) {
        // set to error in case it happens the npm package has some flaws
        snippet = JSON.stringify(snippet);
      }
      // return stringified snipped
      return snippet;
    }
  }
}

const notReactSwaggerUI = SwaggerUIBundle({
  "dom_id": "#swagger-ui",
  deepLinking: true,
  presets: [
    SwaggerUIBundle.presets.apis,
    SwaggerUIStandalonePreset
  ],
  plugins: [
    SwaggerUIBundle.plugins.DownloadUrl,
    SnippedGeneratorNotReact
  ],
  layout: "StandaloneLayout",
  validatorUrl: "https://validator.swagger.io/validator",
  url: "https://petstore.swagger.io/v2/swagger.json",
  ...configForNotReact,
})

For swagger-ui-react it's a bit more hacky because the configuration for the snippets was not integrated but still doable:
Live Example in sandbox:)

import React from "react";
import ReactDOM from "react-dom";
import SwaggerUI from "swagger-ui-react";
import * as OpenAPISnippet from "openapi-snippet";
import "swagger-ui-react/swagger-ui.css";

// Since swagger-ui-react was not configured to change the request snippets some workarounds required
// configuration will be added programatically
// Custom Plugin
const SnippedGenerator = {
  statePlugins: {
    // extend some internals to gain information about current path, method and spec in the generator function metioned later
    spec: {
      wrapSelectors: {
        requestFor: (ori, system) => (state, path, method) => {
          return ori(path, method)
            ?.set("spec", state.get("json", {}))
            ?.setIn(["oasPathMethod", "path"], path)
            ?.setIn(["oasPathMethod", "method"], method);
        },
        mutatedRequestFor: (ori) => (state, path, method) => {
          return ori(path, method)
            ?.set("spec", state.get("json", {}))
            ?.setIn(["oasPathMethod", "path"], path)
            ?.setIn(["oasPathMethod", "method"], method);
        }
      }
    },
    // extend the request snippets core plugin
    requestSnippets: {
      wrapSelectors: {
        // add additional snippet generators here
        getSnippetGenerators: (ori, system) => (state, ...args) =>
          ori(state, ...args)
            // add node native snippet generator
            .set(
              // key
              "node_native",
              // config and generator function
              system.Im.fromJS({
                title: "NodeJs Native",
                syntax: "javascript",
                fn: (req) => {
                  // get extended info about request
                  const { spec, oasPathMethod } = req.toJS();
                  const { path, method } = oasPathMethod;
                  
                  // run OpenAPISnippet for target node
                  const targets = ["node_native"];
                  let snippet;
                  try {
                    // set request snippet content
                    snippet = OpenAPISnippet.getEndpointSnippets(
                      spec,
                      path,
                      method,
                      targets
                    ).snippets[0].content;
                  } catch (err) {
                    // set to error in case it happens the npm package has some flaws
                    snippet = JSON.stringify(snippet);
                  }
                  // return stringified snipped
                  return snippet;
                }
              })
          )
      }
    }
  }
};

const ref = React.createRef();
const ui = (
  <SwaggerUI
    url="https://raw.githubusercontent.com/ErikWittern/openapi-snippet/main/test/petstore_oas.json"
    ref={ref}
    plugins={[SnippedGenerator]}
  />
);
function App() {
  return <div className="App">{ui}</div>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ref.current.system.getConfigs().requestSnippetsEnabled = true;

FYI: the generator package has some flaws and does not work in all the cases that are valid in OAS.

@andrei572
Copy link

andrei572 commented Aug 31, 2022

The react demo in https://yjjgj.csb.app/ doesn't display the Snippets section and there may be some errors in the console. Is there a working instance of SwaggerUI somewhere with requesSnippets working as shown in the video in #6910? I can't find one.

@mathis-m
Copy link
Contributor

mathis-m commented Sep 2, 2022

The react demo in https://yjjgj.csb.app/ doesn't display the Snippets section and there may be some errors in the console. Is there a working instance of SwaggerUI somewhere with requesSnippets working as shown in the video in #6910? I can't find one.

It does display the section.
Click on Execute of any Methode and you will see the snipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants