Skip to content

feat: provide a convenient experimental API for code extension #35

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

Merged
merged 5 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/build.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import "./clean";

import { cherryPick } from "./tools/cherry-pick";
import { copyPackageSet } from "./tools/copyPackageSet";
import { generateExportsField } from "./tools/dualPackageSupport";
import { shell } from "./tools/shell";
import { cherryPick } from "./tools/cherry-pick";

const main = async () => {
await Promise.all([
Expand Down
28 changes: 14 additions & 14 deletions scripts/testCodeGen.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "fs";
import { posix as path } from "path";

import { CodeGenerator, GeneratorTemplate } from "../lib";
import { CodeGenerator, CustomCodeGenerator } from "../lib";
import * as Templates from "../lib/templates";

const writeText = (filename: string, text: string): void => {
Expand Down Expand Up @@ -34,7 +34,7 @@ const generateTemplateCodeOnly = (
});
}

const apiClientGeneratorTemplate: GeneratorTemplate<Templates.ApiClient.Option> = {
const apiClientGeneratorTemplate: CustomCodeGenerator<Templates.ApiClient.Option> = {
generator: Templates.ApiClient.generator,
option: option,
};
Expand All @@ -58,11 +58,7 @@ const generateTypedefWithTemplateCode = (
}

const code = codeGenerator.generateTypeDefinition([
{
generator: () => {
return codeGenerator.getAdditionalTypeStatements();
},
},
codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),
{
generator: Templates.ApiClient.generator,
option: option,
Expand All @@ -75,9 +71,9 @@ const generateTypedefWithTemplateCode = (
const generateSplitCode = (inputFilename: string, outputDir: string) => {
const codeGenerator = new CodeGenerator(inputFilename);

const apiClientGeneratorTemplate: GeneratorTemplate<Templates.ApiClient.Option> = {
const apiClientGeneratorTemplate: CustomCodeGenerator<Templates.ApiClient.Option> = {
generator: Templates.ApiClient.generator,
option: { sync: false },
option: { sync: false, additionalMethodComment: true },
};

const typeDefCode = codeGenerator.generateTypeDefinition();
Expand All @@ -87,18 +83,19 @@ const generateSplitCode = (inputFilename: string, outputDir: string) => {
return [`import { Schemas } from "./types";`];
},
},
{
generator: () => {
return codeGenerator.getAdditionalTypeStatements();
},
},
codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),
apiClientGeneratorTemplate,
]);

writeText(path.join(outputDir, "types.ts"), typeDefCode);
writeText(path.join(outputDir, "apiClient.ts"), apiClientCode);
};

const generateParameter = (inputFilename: string, outputFilename: string) => {
const codeGenerator = new CodeGenerator(inputFilename);
writeText(outputFilename, JSON.stringify(codeGenerator.getCodeGeneratorParamsArray(), null, 2));
};

const main = () => {
generateTypedefCodeOnly("test/api.test.domain/index.yml", "test/code/typedef-only/api.test.domain.ts", true);
generateTypedefCodeOnly("test/infer.domain/index.yml", "test/code/typedef-only/infer.domain.ts", false);
Expand All @@ -116,6 +113,9 @@ const main = () => {
generateTypedefWithTemplateCode("test/infer.domain/index.yml", "test/code/typedef-with-template/infer.domain.ts", false, { sync: false });

generateSplitCode("test/api.test.domain/index.yml", "test/code/split");

generateParameter("test/api.test.domain/index.yml", "test/code/parameter/api.test.domain.json");
generateParameter("test/infer.domain/index.yml", "test/code/parameter/infer.domain.json");
};

main();
1 change: 0 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export * as OpenApiTools from "./internal/OpenApiTools";
export { FileSystem } from "./internal/FileSystem";
export * as ResolveReference from "./internal/ResolveReference";
export * as Validator from "./internal/Validator";

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ts from "typescript";

import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import type { Option } from "../types";

const httpMethodList: string[] = ["GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"];

Expand Down Expand Up @@ -104,7 +105,7 @@ const createObjectLikeInterface = (factory: TsGenerator.Factory.Type) => {
});
};

export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: { sync?: boolean }): ts.Statement[] => {
export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): ts.Statement[] => {
const objectLikeOrAnyType = factory.UnionTypeNode.create({
typeNodes: [
factory.TypeReferenceNode.create({
Expand Down
11 changes: 8 additions & 3 deletions src/code-templates/api-client/ApiClientClass/Method.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { EOL } from "os";

import ts from "typescript";

import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import type { Option } from "../types";
import * as MethodBody from "./MethodBody";

export { MethodBody };
Expand Down Expand Up @@ -36,7 +39,7 @@ const generateResponseReturnType = (
factory: TsGenerator.Factory.Type,
successResponseNameList: string[],
successResponseContentTypeList: string[],
option: { sync?: boolean },
option: Option,
) => {
let objectType: ts.TypeNode = factory.TypeNode.create({
type: "void",
Expand Down Expand Up @@ -121,7 +124,7 @@ const methodTypeParameters = (factory: TsGenerator.Factory.Type, params: CodeGen
*
* }
*/
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: { sync?: boolean }): ts.MethodDeclaration => {
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): ts.MethodDeclaration => {
const typeParameters: ts.TypeParameterDeclaration[] = methodTypeParameters(factory, params);
const methodArguments: ts.ParameterDeclaration[] = [];
const hasParamsArguments =
Expand All @@ -148,7 +151,9 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
name: params.functionName,
async: !option.sync,
parameters: methodArguments,
comment: params.comment,
comment: option.additionalMethodComment
? [params.comment, `operationId: ${params.operationId}`, `Request URI: ${params.rawRequestUri}`].filter(t => !!t).join(EOL)
: params.comment,
deprecated: params.deprecated,
type: returnType,
typeParameters: typeParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ export const isPathParameter = (params: any): params is CodeGenerator.PickedPara
/**
* const url = this.baseUrl + `[head]${params.parameter.[parameterName]}`;
*/
const generateUrlVariableStatement = (factory: TsGenerator.Factory.Type, urlTemplate: Utils.Params$TemplateExpression): ts.VariableStatement => {
const generateUrlVariableStatement = (
factory: TsGenerator.Factory.Type,
urlTemplate: Utils.Params$TemplateExpression,
): ts.VariableStatement => {
return factory.VariableStatement.create({
declarationList: factory.VariableDeclarationList.create({
declarations: [
Expand Down Expand Up @@ -93,7 +96,11 @@ export const generateUrlTemplateExpression = (
return urlTemplate;
};

export const create = (factory: TsGenerator.Factory.Type, requestUri: string, pathParameters: CodeGenerator.PickedParameter[]): ts.VariableStatement => {
export const create = (
factory: TsGenerator.Factory.Type,
requestUri: string,
pathParameters: CodeGenerator.PickedParameter[],
): ts.VariableStatement => {
if (pathParameters.length > 0) {
const urlTemplate = generateUrlTemplateExpression(factory, requestUri, pathParameters);
return generateUrlVariableStatement(factory, urlTemplate);
Expand Down
3 changes: 2 additions & 1 deletion src/code-templates/api-client/ApiClientClass/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import ts from "typescript";

import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import type { Option } from "../types";
import * as ApiClientInterface from "./ApiClientInterface";
import * as Class from "./Class";
import * as Constructor from "./Constructor";
import * as Method from "./Method";

export { Method };

export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: { sync?: boolean }): ts.Statement[] => {
export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): ts.Statement[] => {
const methodList = list.map(params => {
return Method.create(factory, params, option);
});
Expand Down
5 changes: 2 additions & 3 deletions src/code-templates/api-client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
import * as ApiClientArgument from "./ApiClientArgument";
import * as ApiClientClass from "./ApiClientClass";
import type { Option } from "./types";

export interface Option {
sync?: boolean;
}
export { Option };

export const generator: CodeGenerator.GenerateFunction<Option> = (
codeGeneratorParamsList: CodeGenerator.Params[],
Expand Down
6 changes: 6 additions & 0 deletions src/code-templates/api-client/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Option {
/** default false */
sync?: boolean;
/** default false */
additionalMethodComment?: boolean;
}
19 changes: 12 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { EOL } from "os";

import ts from "typescript";

import * as Api from "./api";
import type * as Types from "./types";

export interface GeneratorTemplate<T> {
export interface CustomCodeGenerator<T> {
generator: Types.CodeGenerator.GenerateFunction<T>;
option?: T;
}
Expand Down Expand Up @@ -43,7 +41,7 @@ export class CodeGenerator {
* @param generatorTemplate Template for when you want to change the code following a type definition
* @returns String of generated code
*/
public generateTypeDefinition(generatorTemplates?: GeneratorTemplate<any>[]): string {
public generateTypeDefinition(generatorTemplates?: CustomCodeGenerator<any>[]): string {
const create = () => {
const statements = this.parser.getOpenApiTypeDefinitionStatements();
generatorTemplates?.forEach(generatorTemplate => {
Expand All @@ -62,7 +60,7 @@ export class CodeGenerator {
* @param generatorTemplate
* @returns String of generated code
*/
public generateCode(generatorTemplates: GeneratorTemplate<any>[]): string {
public generateCode(generatorTemplates: CustomCodeGenerator<any>[]): string {
const payload = this.parser.getCodeGeneratorParamsArray();
const create = () => {
return generatorTemplates
Expand All @@ -81,7 +79,14 @@ export class CodeGenerator {
return this.parser.getCodeGeneratorParamsArray();
}

public getAdditionalTypeStatements(): ts.Statement[] {
return this.parser.getAdditionalTypeStatements();
/**
* Provides types for parameters for Templates.ApiClient.
*
* This API will be moved to Templates in the future.
*/
public getAdditionalTypeDefinitionCustomCodeGenerator(): CustomCodeGenerator<undefined> {
return {
generator: () => this.parser.getAdditionalTypeStatements(),
};
}
}
6 changes: 3 additions & 3 deletions src/internal/FileSystem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface Type {

export class FileSystem {
private static FRAGMENT = "#/";
private static internalLoadJsonOrYaml (filename: string): any {
private static internalLoadJsonOrYaml(filename: string): any {
const ext = path.extname(filename);
const data = fs.readFileSync(filename, { encoding: "utf-8" });
switch (ext) {
Expand All @@ -25,7 +25,7 @@ export class FileSystem {
default:
throw new UnSupportError(`Not support file: ${filename}`);
}
};
}

public static existSync(entryPoint: string): boolean {
return !!(fs.existsSync(entryPoint) && fs.statSync(entryPoint).isFile());
Expand All @@ -39,5 +39,5 @@ export class FileSystem {
return Dot.get(data, fragment.replace(/\//g, "."));
}
return this.internalLoadJsonOrYaml(entryPoint);
};
}
}
5 changes: 3 additions & 2 deletions src/internal/OpenApiTools/Extractor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CodeGenerator, OpenApi } from "../../types";
import type { CodeGenerator, OpenApi, Experimental } from "../../types";
import * as ConverterContext from "./ConverterContext";
import { Store } from "./store";

Expand Down Expand Up @@ -111,7 +111,8 @@ export const generateCodeGeneratorParamsArray = (
//
hasAdditionalHeaders: hasOver2RequestContentTypes || hasOver2SuccessNames,
hasQueryParameters: hasQueryParameters(item.parameters),
// Response Success Name

experimentalOpenApiOperation: item,
};
params.push(formatParams);
});
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/TypeNodeContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as Path from "path";

import ts from "typescript";

import * as TypeScriptCodeGenerator from "../TsGenerator";
import { DevelopmentError } from "../Exception";
import * as TypeScriptCodeGenerator from "../TsGenerator";
import * as ConverterContext from "./ConverterContext";
import { Store } from "./store";
import * as ToTypeNode from "./toTypeNode";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/Headers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { UndefinedComponent } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConverterContext from "../ConverterContext";
import * as Guard from "../Guard";
import * as Name from "../Name";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/Parameters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { UnSupportError } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConverterContext from "../ConverterContext";
import * as Guard from "../Guard";
import * as Name from "../Name";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/PathItems.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { FeatureDevelopmentError, UnSupportError } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConverterContext from "../ConverterContext";
import * as Guard from "../Guard";
import * as Name from "../Name";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/Responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import * as path from "path";
import ts from "typescript";

import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { UndefinedComponent } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConverterContext from "../ConverterContext";
import * as Guard from "../Guard";
import * as Name from "../Name";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/Schema.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ts from "typescript";

import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { FeatureDevelopmentError } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConvertContext from "../ConverterContext";
import * as Guard from "../Guard";
import { Store } from "../store";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/Schemas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { UnSupportError } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as ConverterContext from "../ConverterContext";
import * as Guard from "../Guard";
import * as InferredType from "../InferredType";
Expand Down
2 changes: 1 addition & 1 deletion src/internal/OpenApiTools/components/SecuritySchemas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OpenApi } from "../../../types";
import { Factory } from "../../TsGenerator";
import { UndefinedComponent } from "../../Exception";
import { Factory } from "../../TsGenerator";
import * as Guard from "../Guard";
import * as Name from "../Name";
import { Store } from "../store";
Expand Down
Loading