mirror of
https://github.com/netbirdio/docs.git
synced 2026-04-16 07:26:35 +00:00
Add workflow for api gen and refactor genration script (#60)
* update gitignore * add first version of api generation flow * try to run flow * testing flow * update gen flow * switch flow to macOS * fix * add npm install * test workflow * Update API pages * test workflow with current main * refactor parser * merge examples and schema functions * merge examples and schema functions * merge parameters as well * revert template to single class component * update account * finalizing * update with the newest version of openapi * full flow * update * add docker command * split flow in two jobs * remove testing trigger --------- Co-authored-by: GitHub Actions <no-reply@github.com>
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
# Swagger Codegen Ignore
|
||||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -1 +0,0 @@
|
||||
3.0.42
|
||||
File diff suppressed because it is too large
Load Diff
221
generator/api.ts
221
generator/api.ts
@@ -1,13 +1,12 @@
|
||||
import template from './templates/ApiTemplate'
|
||||
import { slugify, toArrayWithKey, toTitle, writeToDisk } from './helpers'
|
||||
import { OpenAPIV3, OpenAPIV2 } from 'openapi-types'
|
||||
import {OpenAPIV3} from 'openapi-types'
|
||||
import * as fs from 'fs'
|
||||
import * as ejs from 'ejs'
|
||||
|
||||
export default async function gen(inputFileName: string, outputDir: string) {
|
||||
const specRaw = fs.readFileSync(inputFileName, 'utf8')
|
||||
const spec = JSON.parse(specRaw) as any
|
||||
// console.log('spec', spec)
|
||||
|
||||
switch (spec.openapi || spec.swagger) {
|
||||
case '3.0.0':
|
||||
@@ -79,90 +78,7 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
|
||||
})
|
||||
})
|
||||
|
||||
let components = new Map<string, component>();
|
||||
Object.entries(spec.components?.schemas).forEach(([key, val]) => {
|
||||
const schema = val as OpenAPIV3.SchemaObject
|
||||
let outputSchema = new Map<string, any>();
|
||||
let outputExample = new Map<string, any>();
|
||||
let parameters : schemaParameter[] = []
|
||||
if(schema.allOf){
|
||||
schema.allOf.forEach((item) => {
|
||||
if((item as OpenAPIV3.ReferenceObject).$ref){
|
||||
let component = components.get((item as OpenAPIV3.ReferenceObject).$ref.split('/').pop())
|
||||
let schemaMap = new Map(Object.entries(component.schema))
|
||||
let exampleMap = new Map(Object.entries(component.example))
|
||||
schemaMap.forEach((value, key) => {
|
||||
outputSchema.set(key, value)
|
||||
})
|
||||
exampleMap.forEach((value, key) => {
|
||||
outputExample.set(key, value)
|
||||
})
|
||||
parameters = parameters.concat(component.parameters)
|
||||
}
|
||||
if((item as OpenAPIV3.SchemaObject).properties){
|
||||
Object.entries((item as OpenAPIV3.SchemaObject).properties).forEach(([key, val]) => {
|
||||
let property = val as OpenAPIV3.SchemaObject
|
||||
let type, exampleValue
|
||||
if (property.type === "array") {
|
||||
type = new Array(resolveType(property.items, spec.components?.schemas))
|
||||
exampleValue = new Array(resolveExampleValue(property.items, spec.components?.schemas))
|
||||
} else {
|
||||
type = resolveType(property, spec.components?.schemas)
|
||||
exampleValue = resolveExampleValue(property, spec.components?.schemas)
|
||||
}
|
||||
outputSchema.set(key, type)
|
||||
outputExample.set(key, exampleValue)
|
||||
let parameter: schemaParameter = {
|
||||
name: key,
|
||||
type: property.type === "array" ? ((property.items as OpenAPIV3.SchemaObject).type || (property.items as OpenAPIV3.ReferenceObject).$ref.split('/').pop()) + "[]" : property.type,
|
||||
description: property.description,
|
||||
required: schema.required?.includes(key) || false,
|
||||
minimum: property.minimum,
|
||||
maximum: property.maximum,
|
||||
minLength: property.minLength,
|
||||
maxLength: property.maxLength,
|
||||
enum: property.enum
|
||||
}
|
||||
parameters.push(parameter)
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Object.entries(schema.properties).forEach(([key, val]) => {
|
||||
let property = val as OpenAPIV3.SchemaObject
|
||||
let type, exampleValue
|
||||
if(property.type === "array"){
|
||||
type = new Array(resolveType(property.items, spec.components?.schemas))
|
||||
exampleValue = new Array(resolveExampleValue(property.items, spec.components?.schemas))
|
||||
} else {
|
||||
type = resolveType(property, spec.components?.schemas)
|
||||
exampleValue = resolveExampleValue(property, spec.components?.schemas)
|
||||
}
|
||||
outputSchema.set(key, type)
|
||||
outputExample.set(key, exampleValue)
|
||||
let parameter : schemaParameter = {
|
||||
name: key,
|
||||
type: property.type === "array" ? ((property.items as OpenAPIV3.SchemaObject).type || (property.items as OpenAPIV3.ReferenceObject).$ref.split('/').pop()) + "[]" : property.type,
|
||||
description: property.description,
|
||||
required: schema.required?.includes(key) || false,
|
||||
minimum: property.minimum,
|
||||
maximum: property.maximum,
|
||||
minLength: property.minLength,
|
||||
maxLength: property.maxLength,
|
||||
enum: property.enum
|
||||
}
|
||||
parameters.push(parameter)
|
||||
})
|
||||
}
|
||||
|
||||
let output : component = {
|
||||
example: Object.fromEntries(outputExample),
|
||||
schema: Object.fromEntries(outputSchema),
|
||||
parameters: parameters
|
||||
}
|
||||
components.set(key, output)
|
||||
})
|
||||
|
||||
let components = readComponents(spec.components)
|
||||
|
||||
tagGroups.forEach((value: enrichedOperation[], key: string) => {
|
||||
|
||||
@@ -192,42 +108,111 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
|
||||
})
|
||||
}
|
||||
|
||||
function resolveType(items: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | OpenAPIV3.NonArraySchemaObjectType, schemas) : any {
|
||||
if((items as OpenAPIV3.ReferenceObject).$ref){
|
||||
let ref = (items as OpenAPIV3.ReferenceObject).$ref
|
||||
let map = new Map<string, any>()
|
||||
Object.entries(schemas[ref.split('/').pop()].properties).forEach(([key, val]) => {
|
||||
let property = val as OpenAPIV3.SchemaObject
|
||||
let type
|
||||
if(property.type === "array"){
|
||||
type = new Array(resolveType(property.items, schemas))
|
||||
} else {
|
||||
type = resolveType(property, schemas)
|
||||
}
|
||||
map.set(key, type)
|
||||
})
|
||||
return Object.fromEntries(map)
|
||||
function readComponents(components: OpenAPIV3.ComponentsObject) : Map<string, component> {
|
||||
let componentsOutput = new Map<string, component>()
|
||||
|
||||
for (const [key, value] of Object.entries(components.schemas)) {
|
||||
let [schema, example, parameter] = resolveComponents(value, components)
|
||||
let component = {
|
||||
example: example,
|
||||
schema: schema,
|
||||
parameters: parameter
|
||||
}
|
||||
componentsOutput.set(key, component)
|
||||
}
|
||||
return (items as OpenAPIV3.ArraySchemaObject).type
|
||||
|
||||
return componentsOutput
|
||||
}
|
||||
|
||||
function resolveComponents(value: OpenAPIV3.ReferenceObject | OpenAPIV3.ArraySchemaObject | OpenAPIV3.NonArraySchemaObject, components: OpenAPIV3.ComponentsObject) : [Object, Object, schemaParameter[]] {
|
||||
if((value as OpenAPIV3.ReferenceObject).$ref) {
|
||||
let subcomponentName = (value as OpenAPIV3.ReferenceObject).$ref.split('/').pop()
|
||||
let subcomponent = components.schemas[subcomponentName]
|
||||
return resolveComponents(subcomponent, components)
|
||||
}
|
||||
if((value as OpenAPIV3.SchemaObject).properties) {
|
||||
return resolveProperties(value as OpenAPIV3.SchemaObject, components)
|
||||
}
|
||||
if((value as OpenAPIV3.SchemaObject).allOf) {
|
||||
return resolveAllOf(value as OpenAPIV3.SchemaObject, components)
|
||||
}
|
||||
if((value as OpenAPIV3.SchemaObject).type || (value as OpenAPIV3.SchemaObject).example) {
|
||||
return [(value as OpenAPIV3.SchemaObject).type, (value as OpenAPIV3.SchemaObject).example, null]
|
||||
}
|
||||
}
|
||||
|
||||
function resolveAllOf(object: OpenAPIV3.SchemaObject, components: OpenAPIV3.ComponentsObject) : [Object, Object, schemaParameter[]] {
|
||||
let examples = new Map<string, any>()
|
||||
let schemas = new Map<string, any>()
|
||||
let parameters: schemaParameter[] = []
|
||||
for (const [key, value] of Object.entries(object.allOf)) {
|
||||
let example;
|
||||
let schema;
|
||||
let parameter;
|
||||
if((value as OpenAPIV3.ReferenceObject).$ref) {
|
||||
let subcomponentName = (value as OpenAPIV3.ReferenceObject).$ref.split('/').pop()
|
||||
let subcomponent = components.schemas[subcomponentName];
|
||||
[schema, example, parameter] = resolveComponents(subcomponent, components)
|
||||
}
|
||||
if((value as OpenAPIV3.SchemaObject).properties) {
|
||||
[schema, example, parameter] = resolveProperties(value as OpenAPIV3.SchemaObject, components)
|
||||
}
|
||||
if(!(example instanceof Map)) {
|
||||
example = new Map(Object.entries(example))
|
||||
}
|
||||
if(!(schema instanceof Map)) {
|
||||
schema = new Map(Object.entries(schema))
|
||||
}
|
||||
parameters = parameters.concat(parameter)
|
||||
examples = mergeMaps(examples, example)
|
||||
schemas = mergeMaps(schemas, schema)
|
||||
}
|
||||
return [Object.fromEntries(schemas), Object.fromEntries(examples), parameters]
|
||||
}
|
||||
|
||||
|
||||
function resolveExampleValue(items: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | OpenAPIV3.NonArraySchemaObjectType, schemas) : any {
|
||||
if((items as OpenAPIV3.ReferenceObject).$ref){
|
||||
let ref = (items as OpenAPIV3.ReferenceObject).$ref
|
||||
let map = new Map<string, any>()
|
||||
Object.entries(schemas[ref.split('/').pop()].properties).forEach(([key, val]) => {
|
||||
let property = val as OpenAPIV3.SchemaObject
|
||||
let exampleValue
|
||||
if(property.type === "array"){
|
||||
exampleValue = new Array(resolveExampleValue(property.items, schemas))
|
||||
} else {
|
||||
exampleValue = resolveExampleValue(property, schemas)
|
||||
}
|
||||
map.set(key, exampleValue)
|
||||
})
|
||||
return Object.fromEntries(map)
|
||||
function resolveProperties(value: OpenAPIV3.SchemaObject, components: OpenAPIV3.ComponentsObject): [Object, Object, schemaParameter[]] {
|
||||
let examples = new Map<string, Object>()
|
||||
let schemas = new Map<string, Object>()
|
||||
let parameters: schemaParameter[] = []
|
||||
for(const [key, property] of Object.entries(value.properties)) {
|
||||
let type: string = ""
|
||||
if(property["$ref"]) {
|
||||
let [schema, example, parameter] = resolveComponents(property, components)
|
||||
examples.set(key, example)
|
||||
schemas.set(key, schema)
|
||||
parameters = parameters.concat(parameter)
|
||||
continue
|
||||
}
|
||||
switch (property["type"]) {
|
||||
case "array":
|
||||
type = ((property["items"] as OpenAPIV3.SchemaObject).type || (property["items"] as OpenAPIV3.ReferenceObject).$ref.split('/').pop()) + "[]"
|
||||
let [schema, example] = resolveComponents(property["items"], components)
|
||||
examples.set(key, new Array(example))
|
||||
schemas.set(key, new Array(schema))
|
||||
break;
|
||||
case "object":
|
||||
default:
|
||||
type = property["type"]
|
||||
examples.set(key, property["example"])
|
||||
schemas.set(key, property["type"])
|
||||
}
|
||||
let parameter: schemaParameter = {
|
||||
name: key,
|
||||
type: type,
|
||||
description: property["description"],
|
||||
required: value.required?.includes(key) || false,
|
||||
minimum: property["minimum"],
|
||||
maximum: property["maximum"],
|
||||
minLength: property["minLength"],
|
||||
maxLength: property["maxLength"],
|
||||
enum: property["enum"],
|
||||
}
|
||||
parameters.push(parameter)
|
||||
}
|
||||
return (items as OpenAPIV3.ArraySchemaObject).example
|
||||
return [Object.fromEntries(schemas), Object.fromEntries(examples), parameters]
|
||||
}
|
||||
|
||||
function mergeMaps(map1: Map<string, Object>, map2: Map<string, Object>) : Map<string, Object> {
|
||||
return new Map([...Array.from(map1.entries()), ...Array.from(map2.entries())]);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user