Skip to content

Commit

Permalink
feat(oas31): enable overrides for samples plugin (#8731)
Browse files Browse the repository at this point in the history
These overrides are specific to OpenAPI 3.1.0
and JSON Schema 2020-12.

Refs #8577
  • Loading branch information
char0n committed Jun 1, 2023
1 parent 2ce9d08 commit df9aadf
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 73 deletions.
25 changes: 13 additions & 12 deletions src/core/plugins/json-schema-2020-12/samples-extensions/fn.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
import XML from "xml"
import RandExp from "randexp"
import isEmpty from "lodash/isEmpty"

import { objectify, isFunc, normalizeArray, deeplyStripKey } from "core/utils"
import memoizeN from "../../../../helpers/memoizeN"

const generateStringFromRegex = (pattern) => {
try {
const randexp = new RandExp(pattern)
return randexp.gen()
} catch (e) {
// Invalid regex should not cause a crash (regex syntax varies across languages)
} catch {
// invalid regex should not cause a crash (regex syntax varies across languages)
return "string"
}
}
Expand All @@ -36,17 +37,16 @@ const primitives = {

const primitive = (schema) => {
schema = objectify(schema)
let { type, format } = schema

let fn = primitives[`${type}_${format}`] || primitives[type]

if (isFunc(fn)) return fn(schema)
const { type, format } = schema
const fn = primitives[`${type}_${format}`] || primitives[type]

return "Unknown Type: " + schema.type
return typeof fn === "function" ? fn(schema) : `Unknown Type: ${schema.type}`
}

// do a couple of quick sanity tests to ensure the value
// looks like a $$ref that swagger-client generates.
/**
* Do a couple of quick sanity tests to ensure the value
* looks like a $$ref that swagger-client generates.
*/
const sanitizeRef = (value) =>
deeplyStripKey(
value,
Expand Down Expand Up @@ -720,8 +720,9 @@ export const createXMLExample = (schema, config, o) => {
return XML(json, { declaration: true, indent: "\t" })
}

export const sampleFromSchema = (schema, config, o) =>
sampleFromSchemaGeneric(schema, config, o, false)
export const sampleFromSchema = (schema, config, o) => {
return sampleFromSchemaGeneric(schema, config, o, false)
}

const resolver = (arg1, arg2, arg3) => [
arg1,
Expand Down
38 changes: 38 additions & 0 deletions src/core/plugins/oas31/after-load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @prettier
*/
import {
makeIsExpandable,
getProperties,
} from "./json-schema-2020-12-extensions/fn"
import { wrapOAS31Fn } from "./fn"

function afterLoad({ fn, getSystem }) {
// overrides for fn.jsonSchema202012
if (fn.jsonSchema202012) {
const isExpandable = makeIsExpandable(
fn.jsonSchema202012.isExpandable,
getSystem
)

Object.assign(this.fn.jsonSchema202012, { isExpandable, getProperties })
}

// wraps schema generators from samples plugin and make them specific to OpenAPI 3.1 version
if (typeof fn.sampleFromSchema === "function" && fn.jsonSchema202012) {
const wrappedFns = wrapOAS31Fn(
{
sampleFromSchema: fn.jsonSchema202012.sampleFromSchema,
sampleFromSchemaGeneric: fn.jsonSchema202012.sampleFromSchemaGeneric,
createXMLExample: fn.jsonSchema202012.createXMLExample,
memoizedSampleFromSchema: fn.jsonSchema202012.memoizedSampleFromSchema,
memoizedCreateXMLExample: fn.jsonSchema202012.memoizedCreateXMLExample,
},
getSystem()
)

Object.assign(this.fn, wrappedFns)
}
}

export default afterLoad
46 changes: 23 additions & 23 deletions src/core/plugins/oas31/fn.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,28 +97,28 @@ export const createOnlyOAS31ComponentWrapper =
}
/* eslint-enable react/jsx-filename-extension */

/** Utilize JSON Schema 2020-12 samples **/
const wrapSampleFn =
(fnName) =>
(getSystem) =>
(...args) => {
const { fn, specSelectors } = getSystem()

if (specSelectors.isOpenAPI31()) {
return fn.jsonSchema202012[fnName](...args)
}
/**
* Runs the fn replacement implementation when spec is OpenAPI 3.1.
* Runs the fn original implementation otherwise.
*
* @param fn
* @param system
* @returns {{[p: string]: function(...[*]): *}}
*/
export const wrapOAS31Fn = (fn, system) => {
const { fn: systemFn, specSelectors } = system

return fn[fnName](...args)
}
return Object.fromEntries(
Object.entries(fn).map(([name, newImpl]) => {
const oriImpl = systemFn[name]
const impl = (...args) =>
specSelectors.isOAS31()
? newImpl(...args)
: typeof oriImpl === "function"
? oriImpl(...args)
: undefined

export const wrapSampleFromSchema = wrapSampleFn("sampleFromSchema")
export const wrapSampleFromSchemaGeneric = wrapSampleFn(
"sampleFromSchemaGeneric"
)
export const wrapCreateXMLExample = wrapSampleFn("createXMLExample")
export const wrapMemoizedSampleFromSchema = wrapSampleFn(
"memoizedSampleFromSchema"
)
export const wrapMemoizedCreateXMLExample = wrapSampleFn(
"memoizedCreateXMLExample"
)
return [name, impl]
})
)
}
42 changes: 8 additions & 34 deletions src/core/plugins/oas31/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ import {
isOAS31 as isOAS31Fn,
createOnlyOAS31Selector as createOnlyOAS31SelectorFn,
createSystemSelector as createSystemSelectorFn,
wrapSampleFromSchema,
wrapSampleFromSchemaGeneric,
wrapCreateXMLExample,
wrapMemoizedSampleFromSchema,
wrapMemoizedCreateXMLExample,
} from "./fn"
import {
license as selectLicense,
Expand Down Expand Up @@ -64,40 +59,19 @@ import JSONSchema202012KeywordExternalDocs from "./json-schema-2020-12-extension
import JSONSchema202012KeywordDescriptionWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Description"
import JSONSchema202012KeywordDefaultWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Default"
import JSONSchema202012KeywordPropertiesWrapper from "./json-schema-2020-12-extensions/wrap-components/keywords/Properties"
import {
makeIsExpandable,
getProperties,
} from "./json-schema-2020-12-extensions/fn"
import afterLoad from "./after-load"

const OAS31Plugin = ({ getSystem }) => {
const system = getSystem()
const { fn } = system
const OAS31Plugin = ({ fn }) => {
const createSystemSelector = fn.createSystemSelector || createSystemSelectorFn
const createOnlyOAS31Selector = fn.createOnlyOAS31Selector || createOnlyOAS31SelectorFn // prettier-ignore

const pluginFn = {
isOAs31: isOAS31Fn,
createSystemSelector: createSystemSelectorFn,
createOnlyOAS31Selector: createOnlyOAS31SelectorFn,
}
if (typeof fn.jsonSchema202012?.isExpandable === "function") {
pluginFn.jsonSchema202012 = {
...fn.jsonSchema202012,
isExpandable: makeIsExpandable(fn.jsonSchema202012.isExpandable, system),
getProperties,
}
}
// wraps schema generators and make them specific to OpenAPI version
if (typeof system.fn.inferSchema === "function") {
pluginFn.sampleFromSchema = wrapSampleFromSchema(getSystem)
pluginFn.sampleFromSchemaGeneric = wrapSampleFromSchemaGeneric(getSystem)
pluginFn.createXMLExample = wrapCreateXMLExample(getSystem)
pluginFn.memoizedSampleFromSchema = wrapMemoizedSampleFromSchema(getSystem)
pluginFn.memoizedCreateXMLExample = wrapMemoizedCreateXMLExample(getSystem)
}

return {
fn: pluginFn,
afterLoad,
fn: {
isOAS31: isOAS31Fn,
createSystemSelector: createSystemSelectorFn,
createOnlyOAS31Selector: createOnlyOAS31SelectorFn,
},
components: {
Webhooks,
JsonSchemaDialect,
Expand Down
4 changes: 3 additions & 1 deletion src/core/plugins/oas31/json-schema-2020-12-extensions/fn.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/**
* @prettier
*/
export const makeIsExpandable = (original, { fn }) => {
export const makeIsExpandable = (original, getSystem) => {
const { fn } = getSystem()

if (typeof original !== "function") {
return null
}
Expand Down
8 changes: 5 additions & 3 deletions src/core/plugins/oas31/wrap-components/models.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
} from "../json-schema-2020-12-extensions/fn"

const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
const system = getSystem()
const { getComponent, fn, getConfigs } = system
const { getComponent, fn, getConfigs } = getSystem()
const configs = getConfigs()

if (ModelsWrapper.ModelsWithJSONSchemaContext) {
Expand Down Expand Up @@ -135,7 +134,10 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
},
fn: {
upperFirst: fn.upperFirst,
isExpandable: makeIsExpandable(fn.jsonSchema202012.isExpandable, system),
isExpandable: makeIsExpandable(
fn.jsonSchema202012.isExpandable,
getSystem
),
getProperties,
},
})
Expand Down

0 comments on commit df9aadf

Please sign in to comment.