From fe8774e512798f312973849df3da819c1966238b Mon Sep 17 00:00:00 2001 From: Himenon Date: Sun, 25 Apr 2021 13:27:22 +0900 Subject: [PATCH] refactor: classified the store --- src/internal/OpenApiTools/Extractor.ts | 2 +- src/internal/OpenApiTools/Parser.ts | 4 +- src/internal/OpenApiTools/TypeNodeContext.ts | 4 +- .../OpenApiTools/components/Headers.ts | 2 +- .../OpenApiTools/components/Operation.ts | 4 +- .../OpenApiTools/components/Parameter.ts | 8 +- .../OpenApiTools/components/Parameters.ts | 4 +- .../OpenApiTools/components/PathItem.ts | 4 +- .../OpenApiTools/components/PathItems.ts | 2 +- .../OpenApiTools/components/RequestBodies.ts | 2 +- .../OpenApiTools/components/RequestBody.ts | 2 +- .../OpenApiTools/components/Response.ts | 6 +- .../OpenApiTools/components/Responses.ts | 6 +- .../OpenApiTools/components/Schema.ts | 2 +- .../OpenApiTools/components/Schemas.ts | 2 +- .../components/SecuritySchemas.ts | 2 +- src/internal/OpenApiTools/paths/index.ts | 2 +- src/internal/OpenApiTools/store/Store.ts | 184 ++++++++---------- src/internal/OpenApiTools/store/index.ts | 2 +- .../store/structure/DataStructure.ts | 2 + .../OpenApiTools/store/structure/index.ts | 4 + 21 files changed, 122 insertions(+), 128 deletions(-) diff --git a/src/internal/OpenApiTools/Extractor.ts b/src/internal/OpenApiTools/Extractor.ts index 1f47ad3b..82350cb5 100644 --- a/src/internal/OpenApiTools/Extractor.ts +++ b/src/internal/OpenApiTools/Extractor.ts @@ -56,7 +56,7 @@ const hasQueryParameters = (parameters?: OpenApi.Parameter[]): boolean => { }; export const generateCodeGeneratorParamsArray = ( - store: Store.Type, + store: Store, converterContext: ConverterContext.Types, allowOperationIds: string[] | undefined, ): CodeGenerator.Params[] => { diff --git a/src/internal/OpenApiTools/Parser.ts b/src/internal/OpenApiTools/Parser.ts index 8647471d..c16ea826 100644 --- a/src/internal/OpenApiTools/Parser.ts +++ b/src/internal/OpenApiTools/Parser.ts @@ -16,7 +16,7 @@ import * as TypeNodeContext from "./TypeNodeContext"; export class Parser { private currentPoint: string; private convertContext: ConvertContext.Types; - private store: Store.Type; + private store: Store; private factory: TypeScriptCodeGenerator.Factory.Type; constructor( private entryPoint: string, @@ -26,7 +26,7 @@ export class Parser { this.currentPoint = entryPoint; this.convertContext = ConvertContext.create(); this.factory = TypeScriptCodeGenerator.Factory.create(); - this.store = Store.create(this.factory, noReferenceOpenApiSchema); + this.store = new Store(this.factory, noReferenceOpenApiSchema); this.initialize(); } diff --git a/src/internal/OpenApiTools/TypeNodeContext.ts b/src/internal/OpenApiTools/TypeNodeContext.ts index 26d2b9a9..e1102ec7 100644 --- a/src/internal/OpenApiTools/TypeNodeContext.ts +++ b/src/internal/OpenApiTools/TypeNodeContext.ts @@ -25,7 +25,7 @@ const generatePath = (entryPoint: string, currentPoint: string, referencePath: s }; }; -const calculateReferencePath = (store: Store.Type, base: string, pathArray: string[]): ToTypeNode.ResolveReferencePath => { +const calculateReferencePath = (store: Store, base: string, pathArray: string[]): ToTypeNode.ResolveReferencePath => { let names: string[] = []; let unresolvedPaths: string[] = []; pathArray.reduce((previous, lastPath, index) => { @@ -75,7 +75,7 @@ const calculateReferencePath = (store: Store.Type, base: string, pathArray: stri export const create = ( entryPoint: string, - store: Store.Type, + store: Store, factory: TypeScriptCodeGenerator.Factory.Type, converterContext: ConverterContext.Types, ): ToTypeNode.Context => { diff --git a/src/internal/OpenApiTools/components/Headers.ts b/src/internal/OpenApiTools/components/Headers.ts index 5553ad12..0e8dc286 100644 --- a/src/internal/OpenApiTools/components/Headers.ts +++ b/src/internal/OpenApiTools/components/Headers.ts @@ -13,7 +13,7 @@ import * as Schema from "./Schema"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, headers: Record, context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/components/Operation.ts b/src/internal/OpenApiTools/components/Operation.ts index a66af8a7..6b86135d 100644 --- a/src/internal/OpenApiTools/components/Operation.ts +++ b/src/internal/OpenApiTools/components/Operation.ts @@ -35,7 +35,7 @@ const generateComment = (operation: OpenApi.Operation): string => { export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentPath: string, name: string, @@ -131,7 +131,7 @@ export const generateNamespace = ( export const generateStatements = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, requestUri: string, httpMethod: string, // PUT POST PATCH diff --git a/src/internal/OpenApiTools/components/Parameter.ts b/src/internal/OpenApiTools/components/Parameter.ts index 6d7e6acb..dc0a7e30 100644 --- a/src/internal/OpenApiTools/components/Parameter.ts +++ b/src/internal/OpenApiTools/components/Parameter.ts @@ -39,7 +39,7 @@ export const generateTypeAlias = ( export const generatePropertySignature = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parameter: OpenApi.Parameter | OpenApi.Reference, context: ToTypeNode.Context, @@ -86,7 +86,7 @@ export const generatePropertySignature = ( export const generatePropertySignatures = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parameters: (OpenApi.Parameter | OpenApi.Reference)[], context: ToTypeNode.Context, @@ -100,7 +100,7 @@ export const generatePropertySignatures = ( export const generateInterface = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, name: string, parameters: [OpenApi.Parameter | OpenApi.Reference], @@ -120,7 +120,7 @@ export const generateInterface = ( export const generateAliasInterface = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, name: string, parameters: (OpenApi.Parameter | OpenApi.Reference)[], diff --git a/src/internal/OpenApiTools/components/Parameters.ts b/src/internal/OpenApiTools/components/Parameters.ts index 9c26f0cb..5f7c8000 100644 --- a/src/internal/OpenApiTools/components/Parameters.ts +++ b/src/internal/OpenApiTools/components/Parameters.ts @@ -13,7 +13,7 @@ import * as Schema from "./Schema"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parameters: Record, context: ToTypeNode.Context, @@ -71,7 +71,7 @@ export const generateNamespace = ( export const generateNamespaceWithList = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parameters: (OpenApi.Parameter | OpenApi.Reference)[], context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/components/PathItem.ts b/src/internal/OpenApiTools/components/PathItem.ts index 014282ae..9f42b23f 100644 --- a/src/internal/OpenApiTools/components/PathItem.ts +++ b/src/internal/OpenApiTools/components/PathItem.ts @@ -12,7 +12,7 @@ import * as Servers from "./Servers"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentPath: string, name: string, @@ -60,7 +60,7 @@ export const generateNamespace = ( export const generateStatements = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, requestUri: string, pathItem: OpenApi.PathItem, diff --git a/src/internal/OpenApiTools/components/PathItems.ts b/src/internal/OpenApiTools/components/PathItems.ts index 11bf6b44..2e7a1c2b 100644 --- a/src/internal/OpenApiTools/components/PathItems.ts +++ b/src/internal/OpenApiTools/components/PathItems.ts @@ -13,7 +13,7 @@ import * as Reference from "./Reference"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, pathItems: Record, context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/components/RequestBodies.ts b/src/internal/OpenApiTools/components/RequestBodies.ts index 07db99d4..d4f6d93c 100644 --- a/src/internal/OpenApiTools/components/RequestBodies.ts +++ b/src/internal/OpenApiTools/components/RequestBodies.ts @@ -13,7 +13,7 @@ import * as RequestBody from "./RequestBody"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, requestBodies: Record, context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/components/RequestBody.ts b/src/internal/OpenApiTools/components/RequestBody.ts index da70b212..82485357 100644 --- a/src/internal/OpenApiTools/components/RequestBody.ts +++ b/src/internal/OpenApiTools/components/RequestBody.ts @@ -34,7 +34,7 @@ export const generateInterface = ( export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentName: string, name: string, diff --git a/src/internal/OpenApiTools/components/Response.ts b/src/internal/OpenApiTools/components/Response.ts index 71d0a742..b07a0288 100644 --- a/src/internal/OpenApiTools/components/Response.ts +++ b/src/internal/OpenApiTools/components/Response.ts @@ -4,7 +4,7 @@ import type { OpenApi } from "../../../types"; import { Factory } from "../../TsGenerator"; import * as ConverterContext from "../ConverterContext"; import * as Name from "../Name"; -import { Store } from "../store"; +import type { Store } from "../store"; import * as ToTypeNode from "../toTypeNode"; import * as Header from "./Header"; import * as MediaType from "./MediaType"; @@ -12,7 +12,7 @@ import * as MediaType from "./MediaType"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentPath: string, name: string, @@ -63,7 +63,7 @@ export const generateNamespace = ( export const generateReferenceNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentPath: string, nameWithStatusCode: string, diff --git a/src/internal/OpenApiTools/components/Responses.ts b/src/internal/OpenApiTools/components/Responses.ts index 27259fab..81ad3c31 100644 --- a/src/internal/OpenApiTools/components/Responses.ts +++ b/src/internal/OpenApiTools/components/Responses.ts @@ -17,7 +17,7 @@ import * as Response from "./Response"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, responses: Record, context: ToTypeNode.Context, @@ -57,7 +57,7 @@ export const generateNamespace = ( export const generateNamespaceWithStatusCode = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, parentPath: string, responses: OpenApi.Responses, @@ -122,7 +122,7 @@ export const generateNamespaceWithStatusCode = ( export const generateInterfacesWithStatusCode = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, operationId: string, responses: OpenApi.Responses, diff --git a/src/internal/OpenApiTools/components/Schema.ts b/src/internal/OpenApiTools/components/Schema.ts index 39f173a7..522bebcc 100644 --- a/src/internal/OpenApiTools/components/Schema.ts +++ b/src/internal/OpenApiTools/components/Schema.ts @@ -159,7 +159,7 @@ export const generateMultiTypeAlias = ( export const addSchema = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, targetPoint: string, declarationName: string, diff --git a/src/internal/OpenApiTools/components/Schemas.ts b/src/internal/OpenApiTools/components/Schemas.ts index 4084ce34..c0998ada 100644 --- a/src/internal/OpenApiTools/components/Schemas.ts +++ b/src/internal/OpenApiTools/components/Schemas.ts @@ -29,7 +29,7 @@ const createNullableTypeNode = (factory: Factory.Type, schema: OpenApi.Schema) = export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, schemas: Record, context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/components/SecuritySchemas.ts b/src/internal/OpenApiTools/components/SecuritySchemas.ts index cd5207d8..207bd9ce 100644 --- a/src/internal/OpenApiTools/components/SecuritySchemas.ts +++ b/src/internal/OpenApiTools/components/SecuritySchemas.ts @@ -10,7 +10,7 @@ import * as SecuritySchema from "./SecuritySchema"; export const generateNamespace = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, requestBodies: Record, ): void => { diff --git a/src/internal/OpenApiTools/paths/index.ts b/src/internal/OpenApiTools/paths/index.ts index 51ae103d..7d287e34 100644 --- a/src/internal/OpenApiTools/paths/index.ts +++ b/src/internal/OpenApiTools/paths/index.ts @@ -12,7 +12,7 @@ import * as ToTypeNode from "../toTypeNode"; export const generateStatements = ( entryPoint: string, currentPoint: string, - store: Store.Type, + store: Store, factory: Factory.Type, paths: OpenApi.Paths, context: ToTypeNode.Context, diff --git a/src/internal/OpenApiTools/store/Store.ts b/src/internal/OpenApiTools/store/Store.ts index ece94703..9412223a 100644 --- a/src/internal/OpenApiTools/store/Store.ts +++ b/src/internal/OpenApiTools/store/Store.ts @@ -12,39 +12,22 @@ import * as Operation from "./Operation"; import * as State from "./State"; import * as Structure from "./structure"; -export interface Type { - addComponent: (componentName: Def.ComponentName, statement: Structure.ComponentParams) => void; - /** - * @params path: "components/headers/hoge" - */ - addStatement: (path: string, statement: Structure.ComponentParams) => void; - getStatement: (path: string, kind: T) => Structure.DataStructure.GetChild | undefined; - /** - * @params path: "components/headers/hoge" - */ - hasStatement: (path: string, types: Structure.DataStructure.Kind[]) => boolean; - addAdditionalStatement: (statements: ts.Statement[]) => void; - getRootStatements: () => ts.Statement[]; - getAdditionalStatements: () => ts.Statement[]; - updateOperationState: (httpMethod: string, requestUri: string, operationId: string, state: Partial) => void; - getNoReferenceOperationState: () => Operation.State; - getPathItem: (localPath: string) => OpenApi.PathItem; - isAfterDefined: (referencePath: string) => boolean; - getParameter: (localPath: string) => OpenApi.Parameter; -} - -export const create = (factory: Factory.Type, rootDocument: OpenApi.Document): Type => { - const state: State.Type = State.createDefaultState(rootDocument); - const { operator, getChildByPaths } = Structure.create(); - const isAfterDefined = (referencePath: string) => { - return !!Dot.get(state.document, referencePath.replace(/\//g, ".")); - }; +class Store { + private state: State.Type; + private operator: Structure.OperatorType; + private getChildByPaths: Structure.GetChildByPaths; + constructor(private factory: Factory.Type, private rootDocument: OpenApi.Document) { + this.state = State.createDefaultState(rootDocument); + const { operator, getChildByPaths } = Structure.create(); + this.operator = operator; + this.getChildByPaths = getChildByPaths; + } - const convertNamespace = (tree: Tree | Structure.NamespaceTree.Item): ts.Statement => { + public convertNamespace(tree: Tree | Structure.NamespaceTree.Item): ts.Statement { const statements: ts.Statement[] = []; Object.values(tree.getChildren()).map(child => { if (child instanceof Tree || child instanceof Structure.NamespaceTree.Item) { - statements.push(convertNamespace(child)); + statements.push(this.convertNamespace(child)); } else if (child instanceof Structure.InterfaceNode.Item) { statements.push(child.value); } else if (child instanceof Structure.TypeAliasNode.Item) { @@ -52,7 +35,7 @@ export const create = (factory: Factory.Type, rootDocument: OpenApi.Document): T } }); if (tree instanceof Structure.NamespaceTree.Item) { - return factory.Namespace.create({ + return this.factory.Namespace.create({ export: true, name: tree.params.name, statements, @@ -60,83 +43,88 @@ export const create = (factory: Factory.Type, rootDocument: OpenApi.Document): T deprecated: tree.params.deprecated, }); } - return factory.Namespace.create({ + return this.factory.Namespace.create({ export: true, name: tree.name, statements, }); - }; - - const getRootStatements = (): ts.Statement[] => { + } + public getRootStatements(): ts.Statement[] { // fs.writeFileSync("debug/tree.json", JSON.stringify(operator.getHierarchy(), null, 2), { encoding: "utf-8" }); const statements = Def.componentNames.reduce((statements, componentName) => { - const treeOfNamespace = getChildByPaths(componentName, "namespace"); + const treeOfNamespace = this.getChildByPaths(componentName, "namespace"); if (treeOfNamespace) { - return statements.concat(convertNamespace(treeOfNamespace)); + return statements.concat(this.convertNamespace(treeOfNamespace)); } return statements; }, []); return statements; - }; - - const getAdditionalStatements = (): ts.Statement[] => { - return state.additionalStatements; - }; + } + public getAdditionalStatements(): ts.Statement[] { + return this.state.additionalStatements; + } + /** + * @params path: "components/headers/hoge" + */ + public hasStatement(path: string, types: Structure.DataStructure.Kind[]): boolean { + const alreadyRegistered = types.some(type => !!this.operator.getChildByPaths(path, type)); + return alreadyRegistered; + } + /** + * @params path: "components/headers/hoge" + */ + public addStatement(path: string, statement: Structure.ComponentParams): void { + if (!path.startsWith("components")) { + throw new UnSupportError(`componentsから始まっていません。path=${path}`); + } + const targetPath = Path.posix.relative("components", path); + this.operator.set(targetPath, Structure.createInstance(statement)); + } + public getStatement(path: string, kind: T): Structure.DataStructure.GetChild | undefined { + const targetPath = Path.posix.relative("components", path); + return this.getChildByPaths(targetPath, kind); + } + public addComponent(componentName: Def.ComponentName, statement: Structure.ComponentParams): void { + this.operator.set(`${componentName}`, Structure.createInstance(statement)); + } + public getNoReferenceOperationState() { + return Operation.create(this.state.document); + } + public updateOperationState(httpMethod: string, requestUri: string, operationId: string, newOperationState: Partial) { + let operationState = this.state.operations[operationId]; + if (operationState) { + operationState = { ...operationState, ...newOperationState }; + } else { + operationState = State.createDefaultOperationState(httpMethod, requestUri, newOperationState); + } + this.state.operations[operationId] = operationState; + } + public addAdditionalStatement(statements: ts.Statement[]) { + this.state.additionalStatements = this.state.additionalStatements.concat(statements); + } + public getPathItem(localPath: string): OpenApi.PathItem { + if (!localPath.startsWith("components/pathItem")) { + throw new Error("Only use start with 'component/pathItems': " + localPath); + } + const result = Dot.get(this.state.document, localPath.replace(/\//g, ".")); + if (!result) { + throw new Error(`Not found ${localPath}`); + } + return result; + } + public getParameter(localPath: string): OpenApi.Parameter { + if (!localPath.startsWith("components/parameters")) { + throw new Error("Only use start with 'component/parameters': " + localPath); + } + const result = Dot.get(this.state.document, localPath.replace(/\//g, ".")); + if (!result) { + throw new Error(`Not found ${localPath}`); + } + return result; + } + public isAfterDefined(referencePath: string): boolean { + return !!Dot.get(this.state.document, referencePath.replace(/\//g, ".")); + } +} - return { - hasStatement: (path: string, types: Structure.DataStructure.Kind[]): boolean => { - const alreadyRegistered = types.some(type => !!operator.getChildByPaths(path, type)); - return alreadyRegistered; - }, - addStatement: (path: string, statement: Structure.ComponentParams): void => { - if (!path.startsWith("components")) { - throw new UnSupportError(`componentsから始まっていません。path=${path}`); - } - const targetPath = Path.posix.relative("components", path); - operator.set(targetPath, Structure.createInstance(statement)); - }, - getStatement: (path: string, kind: T): Structure.DataStructure.GetChild | undefined => { - const targetPath = Path.posix.relative("components", path); - return getChildByPaths(targetPath, kind); - }, - getRootStatements, - getAdditionalStatements, - addComponent: (componentName: Def.ComponentName, statement: Structure.ComponentParams): void => { - operator.set(`${componentName}`, Structure.createInstance(statement)); - }, - getNoReferenceOperationState: () => Operation.create(state.document), - updateOperationState: (httpMethod: string, requestUri: string, operationId: string, newOperationState: Partial) => { - let operationState = state.operations[operationId]; - if (operationState) { - operationState = { ...operationState, ...newOperationState }; - } else { - operationState = State.createDefaultOperationState(httpMethod, requestUri, newOperationState); - } - state.operations[operationId] = operationState; - }, - addAdditionalStatement: (statements: ts.Statement[]) => { - state.additionalStatements = state.additionalStatements.concat(statements); - }, - getPathItem: (localPath: string): OpenApi.PathItem => { - if (!localPath.startsWith("components/pathItem")) { - throw new Error("Only use start with 'component/pathItems': " + localPath); - } - const result = Dot.get(state.document, localPath.replace(/\//g, ".")); - if (!result) { - throw new Error(`Not found ${localPath}`); - } - return result; - }, - getParameter: (localPath: string): OpenApi.Parameter => { - if (!localPath.startsWith("components/parameters")) { - throw new Error("Only use start with 'component/parameters': " + localPath); - } - const result = Dot.get(state.document, localPath.replace(/\//g, ".")); - if (!result) { - throw new Error(`Not found ${localPath}`); - } - return result; - }, - isAfterDefined, - }; -}; +export { Store }; diff --git a/src/internal/OpenApiTools/store/index.ts b/src/internal/OpenApiTools/store/index.ts index 1c641584..412e4745 100644 --- a/src/internal/OpenApiTools/store/index.ts +++ b/src/internal/OpenApiTools/store/index.ts @@ -1,3 +1,3 @@ -export * as Store from "./Store"; +export { Store } from "./Store"; export * as State from "./State"; export * as Def from "./Definition"; diff --git a/src/internal/OpenApiTools/store/structure/DataStructure.ts b/src/internal/OpenApiTools/store/structure/DataStructure.ts index db656e86..0638e1e2 100644 --- a/src/internal/OpenApiTools/store/structure/DataStructure.ts +++ b/src/internal/OpenApiTools/store/structure/DataStructure.ts @@ -20,3 +20,5 @@ export type GetChild = T extends NamespaceTree.Kind export const createGetChildByPaths = (operator: Operator) => (path: string, kind: T): GetChild | undefined => { return operator.getChildByPaths(path, kind) as GetChild | undefined; }; + +export type GetChildByPaths = (path: string, kind: T) => GetChild | undefined; diff --git a/src/internal/OpenApiTools/store/structure/index.ts b/src/internal/OpenApiTools/store/structure/index.ts index 3b052733..52dcf123 100644 --- a/src/internal/OpenApiTools/store/structure/index.ts +++ b/src/internal/OpenApiTools/store/structure/index.ts @@ -43,3 +43,7 @@ export const create = () => { getChildByPaths: DataStructure.createGetChildByPaths(operator), }; }; + +export type OperatorType = Operator; + +export type GetChildByPaths = DataStructure.GetChildByPaths;