diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-html-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-html-documentation-project.ts index 5bee24def..8e91d6d73 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-html-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-html-documentation-project.ts @@ -33,6 +33,8 @@ export class GeneratedAsyncApiHtmlDocumentationProject extends Project { ); this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns("index.html"); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns("index.html"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-markdown-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-markdown-documentation-project.ts index 618b55214..4f4a697b6 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-markdown-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-asyncapi-markdown-documentation-project.ts @@ -33,6 +33,8 @@ export class GeneratedAsyncApiMarkdownDocumentationProject extends Project { ); this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns("index.md"); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns("index.md"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-html-redoc-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-html-redoc-documentation-project.ts index 9b86bce8c..b3c037c1b 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-html-redoc-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-html-redoc-documentation-project.ts @@ -39,6 +39,8 @@ export class GeneratedHtmlRedocDocumentationProject extends Project { ); this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns("index.html"); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns("index.html"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-html2-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-html2-documentation-project.ts index fdc7eea8e..f51560304 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-html2-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-html2-documentation-project.ts @@ -47,6 +47,10 @@ export class GeneratedHtml2DocumentationProject extends Project { this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns(".openapi-generator", "index.html"); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns(".openapi-generator", "index.html"); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-markdown-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-markdown-documentation-project.ts index 2d8d32481..1699bc677 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-markdown-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-markdown-documentation-project.ts @@ -47,11 +47,15 @@ export class GeneratedMarkdownDocumentationProject extends Project { this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns( - ".openapi-generator", - "Apis", - "Models", - "README.md" - ); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns( + ".openapi-generator", + "Apis", + "Models", + "README.md" + ); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/documentation/generated-plantuml-documentation-project.ts b/packages/type-safe-api/src/project/codegen/documentation/generated-plantuml-documentation-project.ts index e1b95ed41..cd6ca8f87 100644 --- a/packages/type-safe-api/src/project/codegen/documentation/generated-plantuml-documentation-project.ts +++ b/packages/type-safe-api/src/project/codegen/documentation/generated-plantuml-documentation-project.ts @@ -47,6 +47,10 @@ export class GeneratedPlantumlDocumentationProject extends Project { this.compileTask.spawn(this.generateTask); - this.gitignore.addPatterns(".openapi-generator", "schemas.plantuml"); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns(".openapi-generator", "schemas.plantuml"); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } } } diff --git a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-base-project.ts b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-base-project.ts index 27c0194bc..013d8e3ef 100644 --- a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-base-project.ts +++ b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-base-project.ts @@ -114,8 +114,16 @@ export abstract class GeneratedPythonCdkInfrastructureBaseProject extends Python this.preCompileTask.spawn(generateTask); - // Ignore the generated code - this.gitignore.addPatterns(this.moduleName, ".openapi-generator", "mocks"); + if (!options.commitGeneratedCode) { + // Ignore the generated code + this.gitignore.addPatterns( + this.moduleName, + ".openapi-generator", + "mocks" + ); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } // The poetry install that runs as part of post synthesis expects there to be some code present, but code isn't // generated until build time. This means that the first install will fail when either generating the project for diff --git a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-typescript-cdk-infrastructure-base-project.ts b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-typescript-cdk-infrastructure-base-project.ts index ff3cb1b25..2d523e490 100644 --- a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-typescript-cdk-infrastructure-base-project.ts +++ b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-typescript-cdk-infrastructure-base-project.ts @@ -159,12 +159,18 @@ export abstract class GeneratedTypescriptCdkInfrastructureBaseProject extends Ty generateTask.exec( `cp -f ${this.options.specPath} ${this.packagedSpecPath}` ); - this.gitignore.addPatterns(`/${this.packagedSpecPath}`); + if (!options.commitGeneratedCode) { + this.gitignore.addPatterns(`/${this.packagedSpecPath}`); + } this.preCompileTask.spawn(generateTask); - // Ignore the generated code - this.gitignore.addPatterns(this.srcdir, ".openapi-generator", "mocks"); + if (!options.commitGeneratedCode) { + // Ignore the generated code + this.gitignore.addPatterns(this.srcdir, ".openapi-generator", "mocks"); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } // If we're not in a monorepo, we need to link the generated types such that the local dependency can be resolved if (!options.isWithinMonorepo) { diff --git a/packages/type-safe-api/src/project/codegen/library/generated-typescript-library-project.ts b/packages/type-safe-api/src/project/codegen/library/generated-typescript-library-project.ts index 44ea657cd..87ae9cb4c 100644 --- a/packages/type-safe-api/src/project/codegen/library/generated-typescript-library-project.ts +++ b/packages/type-safe-api/src/project/codegen/library/generated-typescript-library-project.ts @@ -114,13 +114,15 @@ export abstract class GeneratedTypescriptLibraryProject extends TypeScriptProjec this.preCompileTask.spawn(generateTask); - // Ignore all the generated code - this.gitignore.addPatterns( - "src", - ".npmignore", - "README.md", - ".openapi-generator" - ); + if (!options.commitGeneratedCode) { + // Ignore all the generated code + this.gitignore.addPatterns( + "src", + ".npmignore", + "README.md", + ".openapi-generator" + ); + } // If we're not in a monorepo, we need to link the generated client such that any local dependency on it can be // resolved diff --git a/packages/type-safe-api/src/project/codegen/runtime/generated-java-runtime-base-project.ts b/packages/type-safe-api/src/project/codegen/runtime/generated-java-runtime-base-project.ts index ff18ff40b..3f263dba2 100644 --- a/packages/type-safe-api/src/project/codegen/runtime/generated-java-runtime-base-project.ts +++ b/packages/type-safe-api/src/project/codegen/runtime/generated-java-runtime-base-project.ts @@ -136,14 +136,18 @@ export abstract class GeneratedJavaRuntimeBaseProject extends JavaProject { this.preCompileTask.spawn(generateTask); - // Ignore all the generated code - this.gitignore.addPatterns( - "src", - "docs", - "api", - "README.md", - ".openapi-generator" - ); + if (!options.commitGeneratedCode) { + // Ignore all the generated code + this.gitignore.addPatterns( + "src", + "docs", + "api", + "README.md", + ".openapi-generator" + ); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } } public buildGenerateCommandArgs = () => { diff --git a/packages/type-safe-api/src/project/codegen/runtime/generated-python-runtime-base-project.ts b/packages/type-safe-api/src/project/codegen/runtime/generated-python-runtime-base-project.ts index 0e06ad4a1..2ec88b990 100644 --- a/packages/type-safe-api/src/project/codegen/runtime/generated-python-runtime-base-project.ts +++ b/packages/type-safe-api/src/project/codegen/runtime/generated-python-runtime-base-project.ts @@ -102,13 +102,17 @@ export abstract class GeneratedPythonRuntimeBaseProject extends PythonProject { this.preCompileTask.spawn(generateTask); - // Ignore all the generated code - this.gitignore.addPatterns( - this.moduleName, - "docs", - "README.md", - ".openapi-generator" - ); + if (!this.options.commitGeneratedCode) { + // Ignore all the generated code + this.gitignore.addPatterns( + this.moduleName, + "docs", + "README.md", + ".openapi-generator" + ); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } // The poetry install that runs as part of post synthesis expects there to be some code present, but code isn't // generated until build time. This means that the first install will fail when either generating the project for diff --git a/packages/type-safe-api/src/project/codegen/runtime/generated-typescript-runtime-base-project.ts b/packages/type-safe-api/src/project/codegen/runtime/generated-typescript-runtime-base-project.ts index 5bee0ee53..249f435f0 100644 --- a/packages/type-safe-api/src/project/codegen/runtime/generated-typescript-runtime-base-project.ts +++ b/packages/type-safe-api/src/project/codegen/runtime/generated-typescript-runtime-base-project.ts @@ -127,13 +127,17 @@ export abstract class GeneratedTypescriptRuntimeBaseProject extends TypeScriptPr this.preCompileTask.spawn(generateTask); - // Ignore all the generated code - this.gitignore.addPatterns( - this.srcdir, - ".npmignore", - "README.md", - ".openapi-generator" - ); + if (!options.commitGeneratedCode) { + // Ignore all the generated code + this.gitignore.addPatterns( + this.srcdir, + ".npmignore", + "README.md", + ".openapi-generator" + ); + } else { + this.gitignore.addPatterns(".openapi-generator"); + } // If we're not in a monorepo, we need to link the generated client such that any local dependency on it can be // resolved diff --git a/packages/type-safe-api/src/project/type-safe-api-project.ts b/packages/type-safe-api/src/project/type-safe-api-project.ts index b6afe6c0a..d54b9d662 100644 --- a/packages/type-safe-api/src/project/type-safe-api-project.ts +++ b/packages/type-safe-api/src/project/type-safe-api-project.ts @@ -159,6 +159,11 @@ export interface TypeSafeApiProjectOptions extends ProjectOptions { * fully-fledged runtimes, for example react hooks or clients in languages that aren't supported as runtimes. */ readonly library?: LibraryConfiguration; + /** + * Whether to commit the code generated by the OpenAPI Generator. + * @default false + */ + readonly commitGeneratedCode?: boolean; } /** @@ -265,16 +270,28 @@ export class TypeSafeApiProject extends Project { ProjectUtils.isNamedInstanceOf(this.parent, NodeProject) ? this.parent.package.packageManager : NodePackageManager.PNPM, + commitGeneratedCode: + options.runtime?.options?.typescript?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.runtime?.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", + commitGeneratedCode: + options.runtime?.options?.python?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.runtime?.options?.python, }, javaOptions: { version: "0.0.0", + commitGeneratedCode: + options.runtime?.options?.java?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.runtime?.options?.java, }, }); @@ -327,6 +344,11 @@ export class TypeSafeApiProject extends Project { ProjectUtils.isNamedInstanceOf(this.parent, NodeProject) ? this.parent.package.packageManager : NodePackageManager.PNPM, + commitGeneratedCode: + options.library?.options?.typescriptReactQueryHooks + ?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.library?.options?.typescriptReactQueryHooks, }, }); @@ -396,16 +418,28 @@ export class TypeSafeApiProject extends Project { ProjectUtils.isNamedInstanceOf(this.parent, NodeProject) ? this.parent.package.packageManager : NodePackageManager.PNPM, + commitGeneratedCode: + options.handlers?.options?.typescript?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.handlers?.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", + commitGeneratedCode: + options.handlers?.options?.python?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.handlers?.options?.python, }, javaOptions: { version: "0.0.0", + commitGeneratedCode: + options.handlers?.options?.java?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.handlers?.options?.java, }, generatedRuntimes: { @@ -470,16 +504,28 @@ export class TypeSafeApiProject extends Project { ProjectUtils.isNamedInstanceOf(this.parent, NodeProject) ? this.parent.package.packageManager : NodePackageManager.PNPM, + commitGeneratedCode: + options.infrastructure.options?.typescript?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.infrastructure.options?.typescript, }, pythonOptions: { authorName: "APJ Cope", authorEmail: "apj-cope@amazon.com", version: "0.0.0", + commitGeneratedCode: + options.infrastructure.options?.python?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.infrastructure.options?.python, }, javaOptions: { version: "0.0.0", + commitGeneratedCode: + options.infrastructure.options?.java?.commitGeneratedCode ?? + options.commitGeneratedCode ?? + false, ...options.infrastructure.options?.java, }, generatedRuntimes: { diff --git a/packages/type-safe-api/src/project/types.ts b/packages/type-safe-api/src/project/types.ts index 3e4178d27..9f1b5c991 100644 --- a/packages/type-safe-api/src/project/types.ts +++ b/packages/type-safe-api/src/project/types.ts @@ -139,6 +139,11 @@ export interface OpenApiGeneratorCliConfig { * Options for a code project generated with OpenAPI Generator */ export interface GeneratedWithOpenApiGeneratorOptions { + /** + * Whether to commit the code generated by the OpenAPI Generator. + * @default false + */ + readonly commitGeneratedCode?: boolean; /** * Configuration for the OpenAPI Generator CLI. Overrides default values if specified. * @see https://github.com/OpenAPITools/openapi-generator-cli#configuration @@ -481,12 +486,14 @@ export interface GeneratedPlantumlDocumentationOptions /** * Options for the async api html documentation project */ -export interface GeneratedAsyncApiHtmlDocumentationOptions {} +export interface GeneratedAsyncApiHtmlDocumentationOptions + extends GeneratedWithOpenApiGeneratorOptions {} /** * Options for the async api markdown documentation project */ -export interface GeneratedAsyncApiMarkdownDocumentationOptions {} +export interface GeneratedAsyncApiMarkdownDocumentationOptions + extends GeneratedWithOpenApiGeneratorOptions {} /** * Options for generated documentation projects diff --git a/packages/type-safe-api/test/project/type-safe-api-project.test.ts b/packages/type-safe-api/test/project/type-safe-api-project.test.ts index 1e2c0a1e1..a4b434e6b 100644 --- a/packages/type-safe-api/test/project/type-safe-api-project.test.ts +++ b/packages/type-safe-api/test/project/type-safe-api-project.test.ts @@ -469,4 +469,166 @@ describe("Type Safe Api Project Unit Tests", () => { ] ).toMatchSnapshot(); }); + + it("commitGeneratedCode includes generated code", () => { + const project = new TypeSafeApiProject({ + name: `openapi-commitAll`, + outdir: path.resolve(__dirname, `openapi-commitAll`), + infrastructure: { + language: Language.TYPESCRIPT, + }, + runtime: { + languages: [Language.PYTHON, Language.TYPESCRIPT], + }, + model: { + language: ModelLanguage.OPENAPI, + options: { + openapi: { + title: "MyService", + }, + }, + }, + commitGeneratedCode: true, + }); + + const snapshot = synthProject(project); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.infrastructure.typescript!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.not.arrayContaining([project.infrastructure.typescript!.srcdir]) + ); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.runtime.python!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.not.arrayContaining([ + "README.md", + project.runtime.python!.moduleName, + ]) + ); + }); + + it("commitGeneratedCode override in subproject", () => { + const project = new TypeSafeApiProject({ + name: `openapi-commitOverride`, + outdir: path.resolve(__dirname, `openapi-commitOverride`), + infrastructure: { + language: Language.TYPESCRIPT, + options: { + typescript: { + commitGeneratedCode: false, + }, + }, + }, + runtime: { + languages: [Language.PYTHON, Language.TYPESCRIPT], + }, + model: { + language: ModelLanguage.OPENAPI, + options: { + openapi: { + title: "MyService", + }, + }, + }, + commitGeneratedCode: true, + }); + + const snapshot = synthProject(project); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.infrastructure.typescript!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.arrayContaining([project.infrastructure.typescript!.srcdir]) + ); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.runtime.python!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.not.arrayContaining([ + "README.md", + project.runtime.python!.moduleName, + ]) + ); + }); + + it("commitGeneratedCode only python runtime", () => { + const project = new TypeSafeApiProject({ + name: `openapi-commitRuntime`, + outdir: path.resolve(__dirname, `openapi-commitRuntime`), + infrastructure: { + language: Language.TYPESCRIPT, + }, + runtime: { + languages: [Language.PYTHON, Language.TYPESCRIPT], + options: { + python: { + commitGeneratedCode: true, + }, + }, + }, + model: { + language: ModelLanguage.OPENAPI, + options: { + openapi: { + title: "MyService", + }, + }, + }, + }); + + const snapshot = synthProject(project); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.infrastructure.typescript!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.arrayContaining([project.infrastructure.typescript!.srcdir]) + ); + expect( + ( + snapshot[ + `${path.relative( + project.outdir, + project.runtime.python!.outdir + )}/.gitignore` + ] as string + ).split("\n") + ).toEqual( + expect.not.arrayContaining([ + "README.md", + project.runtime.python!.moduleName, + ]) + ); + }); });