diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts b/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts index 3525d9b94..84f202789 100755 --- a/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts +++ b/packages/type-safe-api/scripts/type-safe-api/generators/generate-next.ts @@ -291,6 +291,51 @@ const toJavaType = (property: parseOpenapi.Model): string => { } }; +const toPythonPrimitive = (property: parseOpenapi.Model): string => { + if (property.type === "string" && property.format === "date") { + return "date"; + } else if (property.type === "string" && property.format === "date-time") { + return "datetime" + } else if (property.type === "any") { + return "object"; + } else if (property.type === "binary") { + return "bytearray"; + } else if (property.type === "number") { + if ((property as any).openapiType === "integer") { + return "int"; + } + + switch(property.format) { + case "int32": + case "int64": + return "int"; + case "float": + case "double": + default: + return "float"; + } + } else if (property.type === "boolean") { + return "bool"; + } else if (property.type === "string") { + return "str"; + } + return property.type; +}; + +const toPythonType = (property: parseOpenapi.Model): string => { + switch (property.export) { + case "generic": + case "reference": + return toPythonPrimitive(property); + case "array": + return `List[${property.link ? toPythonType(property.link) : property.type}]`; + case "dictionary": + return `Dict[str, ${property.link ? toPythonType(property.link) : property.type}]`; + default: + return property.type; + } +}; + /** * Mutates the given model to add language specific types and names */ @@ -298,6 +343,7 @@ const mutateModelWithAdditionalTypes = (model: parseOpenapi.Model) => { (model as any).typescriptName = model.name; (model as any).typescriptType = toTypeScriptType(model); (model as any).javaType = toJavaType(model); + (model as any).pythonType = toPythonType(model); (model as any).isPrimitive = PRIMITIVE_TYPES.has(model.type); // Trim any surrounding quotes from name diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/config.yaml b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/config.yaml deleted file mode 100644 index e7ee32d7a..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -files: - api.mustache: - destinationFilename: {{src}}/api.py - templateType: SupportingFiles - init.mustache: - destinationFilename: {{src}}/__init__.py - templateType: SupportingFiles - mockIntegrations.mustache: - destinationFilename: {{src}}/mock_integrations.py - templateType: SupportingFiles - functions.handlebars: - destinationFilename: {{src}}/__functions.py - templateType: SupportingFiles diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/__init__.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/__init__.ejs new file mode 100644 index 000000000..15008cda6 --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/__init__.ejs @@ -0,0 +1,9 @@ +###TSAPI_WRITE_FILE### +{ + "id": "init", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "__init__", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE#### \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.ejs similarity index 62% rename from packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.mustache rename to packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.ejs index cb158e0f3..52272a616 100644 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.mustache +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.ejs @@ -1,10 +1,18 @@ -from dataclasses import fields +###TSAPI_WRITE_FILE### +{ + "id": "api", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "api", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###from dataclasses import fields from aws_pdk.type_safe_api import TypeSafeRestApi, TypeSafeApiIntegration -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.api.operation_config import OperationLookup, OperationConfig +from <%- metadata.runtimeModuleName %>.api.operation_config import OperationLookup, OperationConfig from os import path from pathlib import Path -SPEC_PATH = path.join(str(Path(__file__).absolute().parent), "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-relative-spec-path}}{{/apis.0}}{{/apiInfo}}") +SPEC_PATH = path.join(str(Path(__file__).absolute().parent), "<%- metadata.relativeSpecPath %>") class Api(TypeSafeRestApi): """ diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.ejs new file mode 100644 index 000000000..80b3a0cab --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.ejs @@ -0,0 +1,59 @@ +###TSAPI_WRITE_FILE### +{ + "dir": "<%- metadata.srcDir || 'src' %>", + "name": "functions", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###from aws_cdk import Duration +from aws_cdk.aws_lambda import ( + Function, Runtime, Tracing, Code +) +from aws_pdk.type_safe_api import SnapStartFunction +from os import path +from pathlib import Path + +<%_ allOperations.forEach((operation) => { _%> +<%_ if (operation.vendorExtensions && operation.vendorExtensions['x-handler']) { _%> +<%_ const language = operation.vendorExtensions['x-handler'].language; _%> +<%_ const isTypeScript = language === 'typescript'; _%> +<%_ const isJava = language === 'java'; _%> +<%_ const isPython = language === 'python'; _%> + +class <%- operation.operationIdPascalCase %>Function(<% if (isJava) { %>SnapStart<% } %>Function): + """ + Lambda function construct which points to the <%- language %> implementation of <%- operation.operationIdPascalCase %> + """ + def __init__(self, scope, id, **kwargs): + super().__init__(scope, id, + <%_ if (isTypeScript) { _%> + runtime=Runtime.<%- metadata['x-handlers-node-lambda-runtime-version'] %>, + <%_ } else if (isPython) { _%> + runtime=Runtime.<%- metadata['x-handlers-python-lambda-runtime-version'] %>, + <%_ } else if (isJava) { _%> + runtime=Runtime.<%- metadata['x-handlers-java-lambda-runtime-version'] %>, + <%_ } _%> + <%_ if (isTypeScript) { _%> + handler="index.handler", + <%_ } else if (isPython) { _%> + handler="<%- metadata['x-handlers-python-module'] %>.<%- operation.operationIdSnakeCase %>.handler", + <%_ } else if (isJava) { _%> + handler="<%- metadata['x-handlers-java-package'] %>.<%- operation.operationIdPascalCase %>Handler", + <%_ } _%> + code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", + <%_ if (isTypeScript) { _%> + "<%- metadata['x-handlers-typescript-asset-path'] %>", + "<%- operation.operationIdKebabCase %>", + <%_ } else if (isPython) { _%> + "<%- metadata['x-handlers-python-asset-path'] %>", + <%_ } else if (isJava) { _%> + "<%- metadata['x-handlers-java-asset-path'] %>", + <%_ } _%> + )), + tracing=Tracing.ACTIVE, + timeout=Duration.seconds(30), + **kwargs, + ) + +<%_ } _%> +<%_ }); _%> \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.handlebars b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.handlebars deleted file mode 100644 index eec60267b..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/functions.handlebars +++ /dev/null @@ -1,62 +0,0 @@ -###TSAPI_SPLIT_FILE### -###TSAPI_WRITE_FILE### -{ - "dir": ".", - "name": "functions", - "ext": ".py", - "overwrite": true -} -###/TSAPI_WRITE_FILE###from aws_cdk import Duration -from aws_cdk.aws_lambda import ( - Function, Runtime, Tracing, Code -) -from aws_pdk.type_safe_api import SnapStartFunction -from os import path -from pathlib import Path - -{{#apiInfo ~}} -{{#apis ~}} -{{#operations ~}} -{{#operation ~}} -{{#if vendorExtensions.x-handler}} - -class {{operationIdCamelCase}}Function({{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}Function): - """ - Lambda function construct which points to the {{vendorExtensions.x-handler.language}} implementation of {{operationIdCamelCase}} - """ - def __init__(self, scope, id, **kwargs): - super().__init__(scope, id, - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-node-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}} - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - handler="index.handler", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - handler="{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-module}}{{/apis.0}}{{/apiInfo}}.{{operationIdSnakeCase}}.handler", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - handler="{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-package}}{{/apis.0}}{{/apiInfo}}.{{operationIdCamelCase}}Handler", - {{~/startsWith}} - code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-typescript-asset-path}}{{/apis.0}}{{/apiInfo}}", - "###TSAPI_FN###{ "function": "kebabCase", "args": ["{{operationIdCamelCase}}"] }###/TSAPI_FN###", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-asset-path}}{{/apis.0}}{{/apiInfo}}", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-asset-path}}{{/apis.0}}{{/apiInfo}}", - {{~/startsWith}} - )), - tracing=Tracing.ACTIVE, - timeout=Duration.seconds(30), - **kwargs, - ) - -{{~/if}} -{{~/operation}} -{{~/operations}} -{{~/apis}} -{{~/apiInfo}} \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/init.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/init.mustache deleted file mode 100644 index 4287ca861..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/init.mustache +++ /dev/null @@ -1 +0,0 @@ -# \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.ejs new file mode 100644 index 000000000..8329d6829 --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.ejs @@ -0,0 +1,85 @@ +###TSAPI_WRITE_FILE### +{ + "id": "mock-integrations", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "mock_integrations", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###import json +from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration +from <%- metadata.runtimeModuleName %>.models import * +from <%- metadata.runtimeModuleName %>.api.operation_config import OperationConfig +from os import path +from pathlib import Path + +MOCK_DATA_PATH = path.join(str(Path(__file__).absolute().parent), "..", "mocks") + +class MockIntegrations: + """ + Type-safe mock integrations for API operations + """ + <%_ if (metadata.enableMockIntegrations) { _%> + <%_ allOperations.forEach((operation) => { _%> + <%_ operation.responses.forEach((response) => { _%> + @staticmethod + def <%- operation.operationIdSnakeCase %>_<%- response.code %>(<% if (response.type !== 'void') { %>body: <% if (!response.isPrimitive) { %><%- response.pythonType %> = None<% } else { %>str<% } %><% } %>) -> MockIntegration: + """ + Mock integration to return a <%- response.code %> response from the <%- operation.name %> operation + <%_ if (!response.isPrimitive) { _%> + Call this with no arguments to use a generated mock response + <%_ } _%> + """ + <%_ if (response.type !== 'void') { _%> + <%_ if (!response.isPrimitive) { _%> + response_body = None + if body is None: + with open(path.join(MOCK_DATA_PATH, "{{httpMethod}}{}-{{code}}.json".format("{{path}}".replace("/", "-").lower())), "r") as f: + response_body = f.read() + else: + response_body = body.to_json() + <%_ } _%> + <%_ } _%> + return Integrations.mock( + status_code=<%- response.code %>, + <%_ if (response.type !== 'void') { _%> + <%_ if (!response.isPrimitive) { _%> + body=response_body, + <%_ } else { _%> + body=body, + <%_ } _%> + <%_ } _%> + ) + + <%_ }); _%> + <%_ }); _%> + @staticmethod + def mock_all(**kwargs) -> OperationConfig[TypeSafeApiIntegration]: + """ + Mock all operations for which generated JSON data can be returned. + The first available response is used for each operation. In most cases this is the successful 200 response. + Pass any additional or overridden integrations as kwargs, for example: + + MockIntegrations.mock_all( + say_hello=TypeSafeApiIntegration( + integration=Integrations.lambda_(...) + ) + ) + """ + return OperationConfig(**{ + **{ + <%_ allOperations.forEach((operation) => { _%> + <%_ const firstResponse = operation.results[0] || operation.responses[0]; _%> + <%_ if (firstResponse && !firstResponse.isPrimitive) { _%> + "<%- operation.operationIdSnakeCase %>": TypeSafeApiIntegration( + integration=MockIntegrations.<%- operation.operationIdSnakeCase %>_<%- firstResponse.code %>(), + ), + <%_ } _%> + <%_ }); _%> + }, + **kwargs + }) + <%_ } else { _%> + # No mock integrations have been generated, since mock data generation is disabled. + pass + <%_ } _%> diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.mustache deleted file mode 100644 index 029dd231c..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/mockIntegrations.mustache +++ /dev/null @@ -1,96 +0,0 @@ -import json -from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.models import * -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.api.operation_config import OperationConfig -from os import path -from pathlib import Path - -MOCK_DATA_PATH = path.join(str(Path(__file__).absolute().parent), "..", "mocks") - -class MockIntegrations: - """ - Type-safe mock integrations for API operations - """ - {{#apiInfo}}{{#apis.0}}{{#vendorExtensions.x-enable-mock-integrations}} - {{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} - {{#responses}} - @staticmethod - def {{operationId}}_{{code}}({{^simpleType}}body: {{^isPrimitiveType}}{{dataType}} = None{{/isPrimitiveType}}{{#isPrimitiveType}}str{{/isPrimitiveType}}{{/simpleType}}) -> MockIntegration: - """ - Mock integration to return a {{code}} response from the {{nickname}} operation - {{^simpleType}} - {{^isPrimitiveType}} - Call this with no arguments to use a generated mock response - {{/isPrimitiveType}} - {{/simpleType}} - """ - {{^simpleType}} - {{^isPrimitiveType}} - response_body = None - if body is None: - with open(path.join(MOCK_DATA_PATH, "{{httpMethod}}{}-{{code}}.json".format("{{path}}".replace("/", "-")).lower()), "r") as f: - response_body = f.read() - else: - response_body = body.to_json() - {{/isPrimitiveType}} - {{/simpleType}} - return Integrations.mock( - status_code={{code}}, - {{^simpleType}} - {{^isPrimitiveType}} - body=response_body, - {{/isPrimitiveType}} - {{#isPrimitiveType}} - body=body, - {{/isPrimitiveType}} - {{/simpleType}} - ) - - {{/responses}} - {{/operation}} - {{/operations}} - {{/apis}} - {{/apiInfo}} - @staticmethod - def mock_all(**kwargs) -> OperationConfig[TypeSafeApiIntegration]: - """ - Mock all operations for which generated JSON data can be returned. - The first available response is used for each operation. In most cases this is the successful 200 response. - Pass any additional or overridden integrations as kwargs, for example: - - MockIntegrations.mock_all( - say_hello=TypeSafeApiIntegration( - integration=Integrations.lambda_(...) - ) - ) - """ - return OperationConfig(**{ - **{ - {{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} - {{#responses.0}} - {{^simpleType}} - {{^isPrimitiveType}} - "{{operationId}}": TypeSafeApiIntegration( - integration=MockIntegrations.{{operationId}}_{{code}}(), - ), - {{/isPrimitiveType}} - {{/simpleType}} - {{/responses.0}} - {{/operation}} - {{/operations}} - {{/apis}} - {{/apiInfo}} - }, - **kwargs - }) - {{/vendorExtensions.x-enable-mock-integrations}}{{/apis.0}}{{/apiInfo}} - {{#apiInfo}}{{#apis.0}}{{^vendorExtensions.x-enable-mock-integrations}} - # No mock integrations have been generated, since mock data generation is disabled. - pass - {{/vendorExtensions.x-enable-mock-integrations}}{{/apis.0}}{{/apiInfo}} diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/config.yaml b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/config.yaml deleted file mode 100644 index e7ee32d7a..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -files: - api.mustache: - destinationFilename: {{src}}/api.py - templateType: SupportingFiles - init.mustache: - destinationFilename: {{src}}/__init__.py - templateType: SupportingFiles - mockIntegrations.mustache: - destinationFilename: {{src}}/mock_integrations.py - templateType: SupportingFiles - functions.handlebars: - destinationFilename: {{src}}/__functions.py - templateType: SupportingFiles diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/__init__.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/__init__.ejs new file mode 100644 index 000000000..15008cda6 --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/__init__.ejs @@ -0,0 +1,9 @@ +###TSAPI_WRITE_FILE### +{ + "id": "init", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "__init__", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE#### \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.ejs similarity index 62% rename from packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.mustache rename to packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.ejs index cb158e0f3..52272a616 100644 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-async-cdk-infrastructure/templates/api.mustache +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/api.ejs @@ -1,10 +1,18 @@ -from dataclasses import fields +###TSAPI_WRITE_FILE### +{ + "id": "api", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "api", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###from dataclasses import fields from aws_pdk.type_safe_api import TypeSafeRestApi, TypeSafeApiIntegration -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.api.operation_config import OperationLookup, OperationConfig +from <%- metadata.runtimeModuleName %>.api.operation_config import OperationLookup, OperationConfig from os import path from pathlib import Path -SPEC_PATH = path.join(str(Path(__file__).absolute().parent), "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-relative-spec-path}}{{/apis.0}}{{/apiInfo}}") +SPEC_PATH = path.join(str(Path(__file__).absolute().parent), "<%- metadata.relativeSpecPath %>") class Api(TypeSafeRestApi): """ diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.ejs new file mode 100644 index 000000000..80b3a0cab --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.ejs @@ -0,0 +1,59 @@ +###TSAPI_WRITE_FILE### +{ + "dir": "<%- metadata.srcDir || 'src' %>", + "name": "functions", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###from aws_cdk import Duration +from aws_cdk.aws_lambda import ( + Function, Runtime, Tracing, Code +) +from aws_pdk.type_safe_api import SnapStartFunction +from os import path +from pathlib import Path + +<%_ allOperations.forEach((operation) => { _%> +<%_ if (operation.vendorExtensions && operation.vendorExtensions['x-handler']) { _%> +<%_ const language = operation.vendorExtensions['x-handler'].language; _%> +<%_ const isTypeScript = language === 'typescript'; _%> +<%_ const isJava = language === 'java'; _%> +<%_ const isPython = language === 'python'; _%> + +class <%- operation.operationIdPascalCase %>Function(<% if (isJava) { %>SnapStart<% } %>Function): + """ + Lambda function construct which points to the <%- language %> implementation of <%- operation.operationIdPascalCase %> + """ + def __init__(self, scope, id, **kwargs): + super().__init__(scope, id, + <%_ if (isTypeScript) { _%> + runtime=Runtime.<%- metadata['x-handlers-node-lambda-runtime-version'] %>, + <%_ } else if (isPython) { _%> + runtime=Runtime.<%- metadata['x-handlers-python-lambda-runtime-version'] %>, + <%_ } else if (isJava) { _%> + runtime=Runtime.<%- metadata['x-handlers-java-lambda-runtime-version'] %>, + <%_ } _%> + <%_ if (isTypeScript) { _%> + handler="index.handler", + <%_ } else if (isPython) { _%> + handler="<%- metadata['x-handlers-python-module'] %>.<%- operation.operationIdSnakeCase %>.handler", + <%_ } else if (isJava) { _%> + handler="<%- metadata['x-handlers-java-package'] %>.<%- operation.operationIdPascalCase %>Handler", + <%_ } _%> + code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", + <%_ if (isTypeScript) { _%> + "<%- metadata['x-handlers-typescript-asset-path'] %>", + "<%- operation.operationIdKebabCase %>", + <%_ } else if (isPython) { _%> + "<%- metadata['x-handlers-python-asset-path'] %>", + <%_ } else if (isJava) { _%> + "<%- metadata['x-handlers-java-asset-path'] %>", + <%_ } _%> + )), + tracing=Tracing.ACTIVE, + timeout=Duration.seconds(30), + **kwargs, + ) + +<%_ } _%> +<%_ }); _%> \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.handlebars b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.handlebars deleted file mode 100644 index eec60267b..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/functions.handlebars +++ /dev/null @@ -1,62 +0,0 @@ -###TSAPI_SPLIT_FILE### -###TSAPI_WRITE_FILE### -{ - "dir": ".", - "name": "functions", - "ext": ".py", - "overwrite": true -} -###/TSAPI_WRITE_FILE###from aws_cdk import Duration -from aws_cdk.aws_lambda import ( - Function, Runtime, Tracing, Code -) -from aws_pdk.type_safe_api import SnapStartFunction -from os import path -from pathlib import Path - -{{#apiInfo ~}} -{{#apis ~}} -{{#operations ~}} -{{#operation ~}} -{{#if vendorExtensions.x-handler}} - -class {{operationIdCamelCase}}Function({{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}Function): - """ - Lambda function construct which points to the {{vendorExtensions.x-handler.language}} implementation of {{operationIdCamelCase}} - """ - def __init__(self, scope, id, **kwargs): - super().__init__(scope, id, - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-node-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - runtime=Runtime.{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-lambda-runtime-version}}{{/apis.0}}{{/apiInfo}}, - {{~/startsWith}} - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - handler="index.handler", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - handler="{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-module}}{{/apis.0}}{{/apiInfo}}.{{operationIdSnakeCase}}.handler", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - handler="{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-package}}{{/apis.0}}{{/apiInfo}}.{{operationIdCamelCase}}Handler", - {{~/startsWith}} - code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", - {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-typescript-asset-path}}{{/apis.0}}{{/apiInfo}}", - "###TSAPI_FN###{ "function": "kebabCase", "args": ["{{operationIdCamelCase}}"] }###/TSAPI_FN###", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-asset-path}}{{/apis.0}}{{/apiInfo}}", - {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} - "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-java-asset-path}}{{/apis.0}}{{/apiInfo}}", - {{~/startsWith}} - )), - tracing=Tracing.ACTIVE, - timeout=Duration.seconds(30), - **kwargs, - ) - -{{~/if}} -{{~/operation}} -{{~/operations}} -{{~/apis}} -{{~/apiInfo}} \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/init.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/init.mustache deleted file mode 100644 index 4287ca861..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/init.mustache +++ /dev/null @@ -1 +0,0 @@ -# \ No newline at end of file diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.ejs b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.ejs new file mode 100644 index 000000000..60c7fef99 --- /dev/null +++ b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.ejs @@ -0,0 +1,85 @@ +###TSAPI_WRITE_FILE### +{ + "id": "mock-integrations", + "dir": "<%= metadata.srcDir || 'src' %>", + "name": "mock_integrations", + "ext": ".py", + "overwrite": true +} +###/TSAPI_WRITE_FILE###import json +from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration +from <%- metadata.runtimeModuleName %>.models import * +from <%- metadata.runtimeModuleName %>.api.operation_config import OperationConfig +from os import path +from pathlib import Path + +MOCK_DATA_PATH = path.join(str(Path(__file__).absolute().parent), "..", "mocks") + +class MockIntegrations: + """ + Type-safe mock integrations for API operations + """ + <%_ if (metadata.enableMockIntegrations) { _%> + <%_ allOperations.forEach((operation) => { _%> + <%_ operation.responses.forEach((response) => { _%> + @staticmethod + def <%- operation.operationIdSnakeCase %>_<%- response.code %>(<% if (response.type !== 'void') { %>body: <% if (!response.isPrimitive) { %><%- response.pythonType %> = None<% } else { %>str<% } %><% } %>) -> MockIntegration: + """ + Mock integration to return a <%- response.code %> response from the <%- operation.operationIdSnakeCase %> operation + <%_ if (!response.isPrimitive) { _%> + Call this with no arguments to use a generated mock response + <%_ } _%> + """ + <%_ if (response.type !== 'void') { _%> + <%_ if (!response.isPrimitive) { _%> + response_body = None + if body is None: + with open(path.join(MOCK_DATA_PATH, "<%- operation.method.toLowerCase() %>{}-<%- response.code %>.json".format("<%- operation.path %>".replace("/", "-"))), "r") as f: + response_body = f.read() + else: + response_body = body.to_json() + <%_ } _%> + <%_ } _%> + return Integrations.mock( + status_code=<%- response.code %>, + <%_ if (response.type !== 'void') { _%> + <%_ if (!response.isPrimitive) { _%> + body=response_body, + <%_ } else { _%> + body=body, + <%_ } _%> + <%_ } _%> + ) + + <%_ }); _%> + <%_ }); _%> + @staticmethod + def mock_all(**kwargs) -> OperationConfig[TypeSafeApiIntegration]: + """ + Mock all operations for which generated JSON data can be returned. + The first available response is used for each operation. In most cases this is the successful 200 response. + Pass any additional or overridden integrations as kwargs, for example: + + MockIntegrations.mock_all( + say_hello=TypeSafeApiIntegration( + integration=Integrations.lambda_(...) + ) + ) + """ + return OperationConfig(**{ + **{ + <%_ allOperations.forEach((operation) => { _%> + <%_ const firstResponse = operation.results[0] || operation.responses[0]; _%> + <%_ if (firstResponse && !firstResponse.isPrimitive) { _%> + "<%- operation.operationIdSnakeCase %>": TypeSafeApiIntegration( + integration=MockIntegrations.<%- operation.operationIdSnakeCase %>_<%- firstResponse.code %>(), + ), + <%_ } _%> + <%_ }); _%> + }, + **kwargs + }) + <%_ } else { _%> + # No mock integrations have been generated, since mock data generation is disabled. + pass + <%_ } _%> diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.mustache b/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.mustache deleted file mode 100644 index 029dd231c..000000000 --- a/packages/type-safe-api/scripts/type-safe-api/generators/python-cdk-infrastructure/templates/mockIntegrations.mustache +++ /dev/null @@ -1,96 +0,0 @@ -import json -from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.models import * -from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.api.operation_config import OperationConfig -from os import path -from pathlib import Path - -MOCK_DATA_PATH = path.join(str(Path(__file__).absolute().parent), "..", "mocks") - -class MockIntegrations: - """ - Type-safe mock integrations for API operations - """ - {{#apiInfo}}{{#apis.0}}{{#vendorExtensions.x-enable-mock-integrations}} - {{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} - {{#responses}} - @staticmethod - def {{operationId}}_{{code}}({{^simpleType}}body: {{^isPrimitiveType}}{{dataType}} = None{{/isPrimitiveType}}{{#isPrimitiveType}}str{{/isPrimitiveType}}{{/simpleType}}) -> MockIntegration: - """ - Mock integration to return a {{code}} response from the {{nickname}} operation - {{^simpleType}} - {{^isPrimitiveType}} - Call this with no arguments to use a generated mock response - {{/isPrimitiveType}} - {{/simpleType}} - """ - {{^simpleType}} - {{^isPrimitiveType}} - response_body = None - if body is None: - with open(path.join(MOCK_DATA_PATH, "{{httpMethod}}{}-{{code}}.json".format("{{path}}".replace("/", "-")).lower()), "r") as f: - response_body = f.read() - else: - response_body = body.to_json() - {{/isPrimitiveType}} - {{/simpleType}} - return Integrations.mock( - status_code={{code}}, - {{^simpleType}} - {{^isPrimitiveType}} - body=response_body, - {{/isPrimitiveType}} - {{#isPrimitiveType}} - body=body, - {{/isPrimitiveType}} - {{/simpleType}} - ) - - {{/responses}} - {{/operation}} - {{/operations}} - {{/apis}} - {{/apiInfo}} - @staticmethod - def mock_all(**kwargs) -> OperationConfig[TypeSafeApiIntegration]: - """ - Mock all operations for which generated JSON data can be returned. - The first available response is used for each operation. In most cases this is the successful 200 response. - Pass any additional or overridden integrations as kwargs, for example: - - MockIntegrations.mock_all( - say_hello=TypeSafeApiIntegration( - integration=Integrations.lambda_(...) - ) - ) - """ - return OperationConfig(**{ - **{ - {{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} - {{#responses.0}} - {{^simpleType}} - {{^isPrimitiveType}} - "{{operationId}}": TypeSafeApiIntegration( - integration=MockIntegrations.{{operationId}}_{{code}}(), - ), - {{/isPrimitiveType}} - {{/simpleType}} - {{/responses.0}} - {{/operation}} - {{/operations}} - {{/apis}} - {{/apiInfo}} - }, - **kwargs - }) - {{/vendorExtensions.x-enable-mock-integrations}}{{/apis.0}}{{/apiInfo}} - {{#apiInfo}}{{#apis.0}}{{^vendorExtensions.x-enable-mock-integrations}} - # No mock integrations have been generated, since mock data generation is disabled. - pass - {{/vendorExtensions.x-enable-mock-integrations}}{{/apis.0}}{{/apiInfo}} diff --git a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-async-cdk-infrastructure-project.ts b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-async-cdk-infrastructure-project.ts index fd7fa683c..b55811a97 100644 --- a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-async-cdk-infrastructure-project.ts +++ b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-async-cdk-infrastructure-project.ts @@ -6,7 +6,7 @@ import { GeneratedPythonCdkInfrastructureBaseProjectOptions, } from "./generated-python-cdk-infrastructure-base-project"; import { - GenerationOptions, + CodegenOptions, OtherGenerators, getHandlersProjectVendorExtensions, } from "../../components/utils"; @@ -19,20 +19,14 @@ export class GeneratedPythonAsyncCdkInfrastructureProject extends GeneratedPytho super(options); } - public buildOpenApiGeneratorOptions(): GenerationOptions { + public buildCodegenOptions(): CodegenOptions { return { - generator: "python-nextgen", specPath: this.options.specPath, - generatorDirectory: OtherGenerators.PYTHON_ASYNC_CDK_INFRASTRUCTURE, - // Tell the generator where python source files live - srcDir: this.moduleName, - normalizers: { - KEEP_ONLY_FIRST_TAG_IN_OPERATION: true, - }, - extraVendorExtensions: { - "x-runtime-module-name": this.options.generatedPythonTypes.moduleName, - // Spec path relative to the source directory - "x-relative-spec-path": path.join("..", this.options.specPath), + templateDirs: [OtherGenerators.PYTHON_ASYNC_CDK_INFRASTRUCTURE], + metadata: { + srcDir: this.moduleName, + runtimeModuleName: this.options.generatedPythonTypes.moduleName, + relativeSpecPath: path.join("..", this.options.specPath), ...getHandlersProjectVendorExtensions( this, this.options.generatedHandlers 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 232e42f39..73c6b85ae 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 @@ -7,15 +7,11 @@ import { CodeGenerationSourceOptions, GeneratedWithOpenApiGeneratorOptions, } from "../../../types"; -import { OpenApiGeneratorHandlebarsIgnoreFile } from "../../components/open-api-generator-handlebars-ignore-file"; -import { OpenApiGeneratorIgnoreFile } from "../../components/open-api-generator-ignore-file"; -import { OpenApiToolsJsonFile } from "../../components/open-api-tools-json-file"; import { TypeSafeApiCommandEnvironment } from "../../components/type-safe-api-command-environment"; import { - buildCleanOpenApiGeneratedCodeCommand, - buildInvokeOpenApiGeneratorCommandArgs, + buildCodegenCommandArgs, buildTypeSafeApiExecCommand, - GenerationOptions, + CodegenOptions, TypeSafeApiScript, } from "../../components/utils"; import { GeneratedHandlersProjects } from "../../generate"; @@ -45,7 +41,6 @@ export abstract class GeneratedPythonCdkInfrastructureBaseProject extends Python protected readonly options: GeneratedPythonCdkInfrastructureBaseProjectOptions; protected readonly generateTask: Task; - protected readonly openapiGeneratorIgnore: OpenApiGeneratorIgnoreFile; constructor(options: GeneratedPythonCdkInfrastructureBaseProjectOptions) { super({ @@ -76,38 +71,11 @@ export abstract class GeneratedPythonCdkInfrastructureBaseProject extends Python .filter((dep) => !this.deps.tryGetDependency(dep, DependencyType.RUNTIME)) .forEach((dep) => this.addDependency(dep)); - // Ignore everything but the target files - const openapiGeneratorIgnore = new OpenApiGeneratorIgnoreFile(this); - this.openapiGeneratorIgnore = openapiGeneratorIgnore; - openapiGeneratorIgnore.addPatterns( - "/*", - "**/*", - "*", - `!${this.moduleName}/__init__.py`, - `!${this.moduleName}/api.py` - ); - - const openapiGeneratorHandlebarsIgnore = - new OpenApiGeneratorHandlebarsIgnoreFile(this); - openapiGeneratorHandlebarsIgnore.addPatterns( - "/*", - "**/*", - "*", - `!${this.moduleName}/__functions.py` - ); - - // Add OpenAPI Generator cli configuration - OpenApiToolsJsonFile.ensure(this).addOpenApiGeneratorCliConfig({ - version: "6.6.0", - ...options.openApiGeneratorCliConfig, - }); - const generateTask = this.addTask("generate"); this.generateTask = generateTask; - generateTask.exec(buildCleanOpenApiGeneratedCodeCommand()); generateTask.exec( buildTypeSafeApiExecCommand( - TypeSafeApiScript.GENERATE, + TypeSafeApiScript.GENERATE_NEXT, this.buildGenerateCommandArgs() ) ); @@ -116,15 +84,11 @@ export abstract class GeneratedPythonCdkInfrastructureBaseProject extends Python if (!options.commitGeneratedCode) { // Ignore the generated code - this.gitignore.addPatterns( - this.moduleName, - ".openapi-generator", - "mocks" - ); - } else { - this.gitignore.addPatterns(".openapi-generator"); + this.gitignore.addPatterns(this.moduleName, "mocks"); } + this.gitignore.addPatterns(".openapi-generator", ".tsapi-manifest"); + // 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 // the first time or checking out a fresh copy (since generated code is not checked in to version control). We @@ -140,10 +104,8 @@ export abstract class GeneratedPythonCdkInfrastructureBaseProject extends Python } public buildGenerateCommandArgs = () => { - return buildInvokeOpenApiGeneratorCommandArgs( - this.buildOpenApiGeneratorOptions() - ); + return buildCodegenCommandArgs(this.buildCodegenOptions()); }; - protected abstract buildOpenApiGeneratorOptions(): GenerationOptions; + protected abstract buildCodegenOptions(): CodegenOptions; } diff --git a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-project.ts b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-project.ts index 0500861ce..25e8d4f93 100644 --- a/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-project.ts +++ b/packages/type-safe-api/src/project/codegen/infrastructure/cdk/generated-python-cdk-infrastructure-project.ts @@ -8,7 +8,7 @@ import { import { MockResponseGenerationOptions } from "../../../types"; import { buildInvokeMockDataGeneratorCommand, - GenerationOptions, + CodegenOptions, getHandlersProjectVendorExtensions, OtherGenerators, } from "../../components/utils"; @@ -30,28 +30,17 @@ export class GeneratedPythonCdkInfrastructureProject extends GeneratedPythonCdkI if (!this.options.mockDataOptions?.disable) { this.generateTask.exec(this.buildGenerateMockDataCommand()); } - - this.openapiGeneratorIgnore.addPatterns( - `!${this.moduleName}/mock_integrations.py` - ); } - public buildOpenApiGeneratorOptions(): GenerationOptions { + public buildCodegenOptions(): CodegenOptions { return { - generator: "python-nextgen", specPath: this.options.specPath, - generatorDirectory: OtherGenerators.PYTHON_CDK_INFRASTRUCTURE, - // Tell the generator where python source files live - srcDir: this.moduleName, - normalizers: { - KEEP_ONLY_FIRST_TAG_IN_OPERATION: true, - }, - extraVendorExtensions: { - "x-runtime-module-name": this.options.generatedPythonTypes.moduleName, - // Spec path relative to the source directory - "x-relative-spec-path": path.join("..", this.options.specPath), - // Enable mock integration generation by default - "x-enable-mock-integrations": !this.options.mockDataOptions?.disable, + templateDirs: [OtherGenerators.PYTHON_CDK_INFRASTRUCTURE], + metadata: { + srcDir: this.moduleName, + runtimeModuleName: this.options.generatedPythonTypes.moduleName, + relativeSpecPath: path.join("..", this.options.specPath), + enableMockIntegrations: !this.options.mockDataOptions?.disable, ...getHandlersProjectVendorExtensions( this, this.options.generatedHandlers diff --git a/packages/type-safe-api/src/project/type-safe-websocket-api-project.ts b/packages/type-safe-api/src/project/type-safe-websocket-api-project.ts index 5c250d7b2..6cf08d61c 100644 --- a/packages/type-safe-api/src/project/type-safe-websocket-api-project.ts +++ b/packages/type-safe-api/src/project/type-safe-websocket-api-project.ts @@ -229,9 +229,19 @@ export class TypeSafeWebSocketApiProject extends Project { runtimeLanguages.includes(Language.JAVA) || runtimeLanguages.includes(Language.PYTHON) ) { - throw new Error( - `Python and Java are not yet supported by Type Safe WebSocket API! Support is coming soon...` - ); + const errorMessages = [ + ...(runtimeLanguages.includes(Language.PYTHON) + ? [ + "Python is not supported by Type Safe WebSocket API. Please +1 this issue if needed: https://github.com/aws/aws-pdk/issues/741", + ] + : []), + ...(runtimeLanguages.includes(Language.JAVA) + ? [ + "Java is not supported by Type Safe WebSocket API. Please +1 this issue if needed: https://github.com/aws/aws-pdk/issues/740", + ] + : []), + ]; + throw new Error(errorMessages.join("\n")); } const generatedDir = "generated"; diff --git a/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap b/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap index 5f1359ee6..ae622ba67 100644 --- a/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap +++ b/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap @@ -5,8 +5,12 @@ exports[`Type Safe Api Project Unit Tests Custom OpenAPI Generator CLI Configura "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", + "repository": { + "downloadUrl": "https://my.custom.maven.repo/maven2/\${groupId}/\${artifactId}/\${versionName}/\${artifactId}-\${versionName}.jar", + }, + "storageDir": "~/.my-storage-dir", + "useDocker": true, + "version": "6.2.0", }, "spaces": 2, } @@ -17,8 +21,12 @@ exports[`Type Safe Api Project Unit Tests Custom OpenAPI Generator CLI Configura "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "7.1.0", + "repository": { + "downloadUrl": "https://my.custom.maven.repo/maven2/\${groupId}/\${artifactId}/\${versionName}/\${artifactId}-\${versionName}.jar", + }, + "storageDir": "~/.my-storage-dir", + "useDocker": true, + "version": "6.2.0", }, "spaces": 2, } @@ -10080,9 +10088,6 @@ This directory contains a generated type-safe CDK construct which can provision /.gitattributes linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -10172,39 +10177,12 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json openapi_python_python_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/project.json ", - "generated/infrastructure/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -.gitignore -/* -**/* -* -!openapi_python_python_infra/__init__.py -!openapi_python_python_infra/api.py -!openapi_python_python_infra/mock_integrations.py -", - "generated/infrastructure/python/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -/* -**/* -* -!openapi_python_python_infra/__functions.py -", - "generated/infrastructure/python/.pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, "generated/infrastructure/python/.projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "dependencies": [ @@ -10245,9 +10223,6 @@ mocks "files": [ ".gitattributes", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -10289,14 +10264,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -10311,13 +10278,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path ../../../model/.api.json --output-path . --generator-dir python-cdk-infrastructure --src-dir openapi_python_python_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"openapi_python_python_runtime","x-relative-spec-path":"../../../../model/.api.json","x-enable-mock-integrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath ../../../model/.api.json --outputPath . --templateDirs "python-cdk-infrastructure" --metadata '{"srcDir":"openapi_python_python_infra","runtimeModuleName":"openapi_python_python_runtime","relativeSpecPath":"../../../../model/.api.json","enableMockIntegrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, { "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate-mock-data --specPath ../../../model/.api.json --outputPath .", @@ -10423,13 +10384,6 @@ url = "https://test.pypi.org/legacy/" "cwd": "generated/infrastructure/python", }, }, - "create-openapitools.json": { - "executor": "nx:run-commands", - "options": { - "command": "npx projen create-openapitools.json", - "cwd": "generated/infrastructure/python", - }, - }, "default": { "executor": "nx:run-commands", "options": { @@ -15192,9 +15146,6 @@ This directory contains a generated type-safe CDK construct which can provision /.gitattributes linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -15285,40 +15236,13 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json openapi_python_python_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/project.json !/LICENSE ", - "packages/api/generated/infrastructure/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -.gitignore -/* -**/* -* -!openapi_python_python_infra/__init__.py -!openapi_python_python_infra/api.py -!openapi_python_python_infra/mock_integrations.py -", - "packages/api/generated/infrastructure/python/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -/* -**/* -* -!openapi_python_python_infra/__functions.py -", - "packages/api/generated/infrastructure/python/.pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, "packages/api/generated/infrastructure/python/.projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "dependencies": [ @@ -15359,9 +15283,6 @@ mocks "files": [ ".gitattributes", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -15404,14 +15325,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -15420,13 +15333,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path ../../../model/.api.json --output-path . --generator-dir python-cdk-infrastructure --src-dir openapi_python_python_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"openapi_python_python_runtime","x-relative-spec-path":"../../../../model/.api.json","x-enable-mock-integrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath ../../../model/.api.json --outputPath . --templateDirs "python-cdk-infrastructure" --metadata '{"srcDir":"openapi_python_python_infra","runtimeModuleName":"openapi_python_python_runtime","relativeSpecPath":"../../../../model/.api.json","enableMockIntegrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, { "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate-mock-data --specPath ../../../model/.api.json --outputPath .", @@ -15753,13 +15660,6 @@ url = "https://test.pypi.org/legacy/" "cwd": "packages/api/generated/infrastructure/python", }, }, - "create-openapitools.json": { - "executor": "nx:run-commands", - "options": { - "command": "npx projen create-openapitools.json", - "cwd": "packages/api/generated/infrastructure/python", - }, - }, "default": { "executor": "nx:run-commands", "options": { @@ -60157,9 +60057,6 @@ This directory contains a generated type-safe CDK construct which can provision /.gitattributes linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -60249,39 +60146,12 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json smithy_python_python_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/project.json ", - "generated/infrastructure/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -.gitignore -/* -**/* -* -!smithy_python_python_infra/__init__.py -!smithy_python_python_infra/api.py -!smithy_python_python_infra/mock_integrations.py -", - "generated/infrastructure/python/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -/* -**/* -* -!smithy_python_python_infra/__functions.py -", - "generated/infrastructure/python/.pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, "generated/infrastructure/python/.projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "dependencies": [ @@ -60322,9 +60192,6 @@ mocks "files": [ ".gitattributes", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -60366,14 +60233,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -60388,13 +60247,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path ../../../model/.api.json --output-path . --generator-dir python-cdk-infrastructure --src-dir smithy_python_python_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"smithy_python_python_runtime","x-relative-spec-path":"../../../../model/.api.json","x-enable-mock-integrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath ../../../model/.api.json --outputPath . --templateDirs "python-cdk-infrastructure" --metadata '{"srcDir":"smithy_python_python_infra","runtimeModuleName":"smithy_python_python_runtime","relativeSpecPath":"../../../../model/.api.json","enableMockIntegrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, { "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate-mock-data --specPath ../../../model/.api.json --outputPath .", @@ -60500,13 +60353,6 @@ url = "https://test.pypi.org/legacy/" "cwd": "generated/infrastructure/python", }, }, - "create-openapitools.json": { - "executor": "nx:run-commands", - "options": { - "command": "npx projen create-openapitools.json", - "cwd": "generated/infrastructure/python", - }, - }, "default": { "executor": "nx:run-commands", "options": { @@ -65363,9 +65209,6 @@ This directory contains a generated type-safe CDK construct which can provision /.gitattributes linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -65456,40 +65299,13 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json smithy_python_python_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/project.json !/LICENSE ", - "packages/api/generated/infrastructure/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -.gitignore -/* -**/* -* -!smithy_python_python_infra/__init__.py -!smithy_python_python_infra/api.py -!smithy_python_python_infra/mock_integrations.py -", - "packages/api/generated/infrastructure/python/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -/* -**/* -* -!smithy_python_python_infra/__functions.py -", - "packages/api/generated/infrastructure/python/.pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, "packages/api/generated/infrastructure/python/.projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "dependencies": [ @@ -65530,9 +65346,6 @@ mocks "files": [ ".gitattributes", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -65575,14 +65388,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -65591,13 +65396,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path ../../../model/.api.json --output-path . --generator-dir python-cdk-infrastructure --src-dir smithy_python_python_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"smithy_python_python_runtime","x-relative-spec-path":"../../../../model/.api.json","x-enable-mock-integrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath ../../../model/.api.json --outputPath . --templateDirs "python-cdk-infrastructure" --metadata '{"srcDir":"smithy_python_python_infra","runtimeModuleName":"smithy_python_python_runtime","relativeSpecPath":"../../../../model/.api.json","enableMockIntegrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, { "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate-mock-data --specPath ../../../model/.api.json --outputPath .", @@ -65924,13 +65723,6 @@ url = "https://test.pypi.org/legacy/" "cwd": "packages/api/generated/infrastructure/python", }, }, - "create-openapitools.json": { - "executor": "nx:run-commands", - "options": { - "command": "npx projen create-openapitools.json", - "cwd": "packages/api/generated/infrastructure/python", - }, - }, "default": { "executor": "nx:run-commands", "options": { diff --git a/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-async-cdk-infrastructure-project.test.ts.snap b/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-async-cdk-infrastructure-project.test.ts.snap index 2156ce63d..cda0e0a7a 100644 --- a/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-async-cdk-infrastructure-project.test.ts.snap +++ b/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-async-cdk-infrastructure-project.test.ts.snap @@ -7,9 +7,6 @@ exports[`Generated Python Async Infra Code Unit Tests Synth 1`] = ` /.gitattributes linguist-generated /.github/workflows/pull-request-lint.yml linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -128,38 +125,12 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json test_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/.projenrc.py ", - ".openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". -.gitignore -/* -**/* -* -!test_infra/__init__.py -!test_infra/api.py -", - ".openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". -/* -**/* -* -!test_infra/__functions.py -", - ".pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, ".projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", "dependencies": [ @@ -206,9 +177,6 @@ mocks ".gitattributes", ".github/workflows/pull-request-lint.yml", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -284,14 +252,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -317,13 +277,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path my-spec.json --output-path . --generator-dir python-async-cdk-infrastructure --src-dir test_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"test_client","x-relative-spec-path":"../my-spec.json","x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath my-spec.json --outputPath . --templateDirs "python-async-cdk-infrastructure" --metadata '{"srcDir":"test_infra","runtimeModuleName":"test_client","relativeSpecPath":"../my-spec.json","x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, ], }, diff --git a/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-cdk-infrastructure-project.test.ts.snap b/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-cdk-infrastructure-project.test.ts.snap index eb8fc8eab..d687bcacf 100644 --- a/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-cdk-infrastructure-project.test.ts.snap +++ b/packages/type-safe-api/test/project/codegen/infrastructure/cdk/__snapshots__/generated-python-cdk-infrastructure-project.test.ts.snap @@ -7,9 +7,6 @@ exports[`Generated Python Infra Code Unit Tests Synth 1`] = ` /.gitattributes linguist-generated /.github/workflows/pull-request-lint.yml linguist-generated /.gitignore linguist-generated -/.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated -/.pdk/dynamic-files/openapitools.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated @@ -128,39 +125,12 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -!/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars -!/.pdk/dynamic-files/openapitools.json -/openapitools.json test_infra -.openapi-generator mocks +.openapi-generator +.tsapi-manifest !/.projenrc.py ", - ".openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". -.gitignore -/* -**/* -* -!test_infra/__init__.py -!test_infra/api.py -!test_infra/mock_integrations.py -", - ".openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". -/* -**/* -* -!test_infra/__functions.py -", - ".pdk/dynamic-files/openapitools.json": { - "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", - "generator-cli": { - "storageDir": "~/.open-api-generator-cli", - "version": "6.6.0", - }, - "spaces": 2, - }, ".projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", "dependencies": [ @@ -207,9 +177,6 @@ mocks ".gitattributes", ".github/workflows/pull-request-lint.yml", ".gitignore", - ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", - ".pdk/dynamic-files/openapitools.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", @@ -285,14 +252,6 @@ mocks "description": "Only compile", "name": "compile", }, - "create-openapitools.json": { - "name": "create-openapitools.json", - "steps": [ - { - "exec": "cp -f .pdk/dynamic-files/openapitools.json openapitools.json", - }, - ], - }, "default": { "description": "Synthesize project files", "name": "default", @@ -318,13 +277,7 @@ mocks "name": "generate", "steps": [ { - "spawn": "create-openapitools.json", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.clean-openapi-generated-code --code-path .", - }, - { - "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api.generate --generator python-nextgen --spec-path my-spec.json --output-path . --generator-dir python-cdk-infrastructure --src-dir test_infra --tst-dir test --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"test_client","x-relative-spec-path":"../my-spec.json","x-enable-mock-integrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}' --generate-alias-as-model", + "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate --specPath my-spec.json --outputPath . --templateDirs "python-cdk-infrastructure" --metadata '{"srcDir":"test_infra","runtimeModuleName":"test_client","relativeSpecPath":"../my-spec.json","enableMockIntegrations":true,"x-handlers-python-module":"","x-handlers-java-package":"","x-handlers-typescript-asset-path":"","x-handlers-python-asset-path":"","x-handlers-java-asset-path":"","x-handlers-node-lambda-runtime-version":"","x-handlers-python-lambda-runtime-version":"","x-handlers-java-lambda-runtime-version":""}'", }, { "exec": "npx --yes -p @aws/pdk@$AWS_PDK_VERSION type-safe-api generate-mock-data --specPath my-spec.json --outputPath .", 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 92b1de959..beaf75009 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 @@ -6,8 +6,8 @@ import { NodePackageManager } from "projen/lib/javascript"; import { synthProject, synthSmithyProject } from "./snapshot-utils"; import { DocumentationFormat, - GeneratedPythonInfrastructureOptions, - GeneratedPythonRuntimeOptions, + GeneratedJavaInfrastructureOptions, + GeneratedJavaRuntimeOptions, Language, Library, ModelLanguage, @@ -381,19 +381,19 @@ describe("Type Safe Api Project Unit Tests", () => { `custom-openapi-generator-cli-configuration` ), infrastructure: { - language: Language.PYTHON, + language: Language.JAVA, options: { - typescript: { + java: { openApiGeneratorCliConfig, - } satisfies Partial as any, + } satisfies Partial as any, }, }, runtime: { - languages: [Language.PYTHON], + languages: [Language.JAVA], options: { - typescript: { + java: { openApiGeneratorCliConfig, - } satisfies Partial as any, + } satisfies Partial as any, }, }, model: { @@ -418,8 +418,8 @@ describe("Type Safe Api Project Unit Tests", () => { }); expect(project.runtime.typescript).not.toBeDefined(); - expect(project.runtime.java).not.toBeDefined(); - expect(project.runtime.python).toBeDefined(); + expect(project.runtime.java).toBeDefined(); + expect(project.runtime.python).not.toBeDefined(); expect(project.library.typescriptReactQueryHooks).not.toBeDefined(); @@ -431,7 +431,7 @@ describe("Type Safe Api Project Unit Tests", () => { snapshot[ `${path.relative( project.outdir, - project.infrastructure.python!.outdir + project.infrastructure.java!.outdir )}/.pdk/dynamic-files/openapitools.json` ] ).toMatchSnapshot(); @@ -439,7 +439,7 @@ describe("Type Safe Api Project Unit Tests", () => { snapshot[ `${path.relative( project.outdir, - project.runtime.python!.outdir + project.runtime.java!.outdir )}/.pdk/dynamic-files/openapitools.json` ] ).toMatchSnapshot(); diff --git a/packages/type-safe-api/test/project/type-safe-websocket-api-project.test.ts b/packages/type-safe-api/test/project/type-safe-websocket-api-project.test.ts index 0df1cbfd4..b4b85b91b 100644 --- a/packages/type-safe-api/test/project/type-safe-websocket-api-project.test.ts +++ b/packages/type-safe-api/test/project/type-safe-websocket-api-project.test.ts @@ -382,9 +382,7 @@ describe("Type Safe Api Project Unit Tests", () => { }, }, }); - }).toThrow( - "Python and Java are not yet supported by Type Safe WebSocket API! Support is coming soon..." - ); + }).toThrow(/.*not supported.*/); } ); }); diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap index 71a3d1680..5dcc9d6cd 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap @@ -10,7 +10,6 @@ from os import path from pathlib import Path - class JavaOneFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of JavaOne @@ -27,6 +26,7 @@ class JavaOneFunction(SnapStartFunction): **kwargs, ) + class JavaTwoFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of JavaTwo @@ -43,6 +43,7 @@ class JavaTwoFunction(SnapStartFunction): **kwargs, ) + class PythonOneFunction(Function): """ Lambda function construct which points to the python implementation of PythonOne @@ -59,6 +60,7 @@ class PythonOneFunction(Function): **kwargs, ) + class PythonTwoFunction(Function): """ Lambda function construct which points to the python implementation of PythonTwo @@ -75,6 +77,7 @@ class PythonTwoFunction(Function): **kwargs, ) + class TypescriptOneFunction(Function): """ Lambda function construct which points to the typescript implementation of TypescriptOne @@ -92,6 +95,7 @@ class TypescriptOneFunction(Function): **kwargs, ) + class TypescriptTwoFunction(Function): """ Lambda function construct which points to the typescript implementation of TypescriptTwo @@ -107,7 +111,9 @@ class TypescriptTwoFunction(Function): tracing=Tracing.ACTIVE, timeout=Duration.seconds(30), **kwargs, - )" + ) + +" `; exports[`Python Infrastructure Code Generation Script Unit Tests Generates Functions for inline-body.yaml 1`] = ` @@ -120,7 +126,6 @@ from os import path from pathlib import Path - class JavaTestFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of JavaTest @@ -137,6 +142,7 @@ class JavaTestFunction(SnapStartFunction): **kwargs, ) + class PythonTestFunction(Function): """ Lambda function construct which points to the python implementation of PythonTest @@ -153,6 +159,7 @@ class PythonTestFunction(Function): **kwargs, ) + class TypescriptTestFunction(Function): """ Lambda function construct which points to the typescript implementation of TypescriptTest @@ -168,7 +175,9 @@ class TypescriptTestFunction(Function): tracing=Tracing.ACTIVE, timeout=Duration.seconds(30), **kwargs, - )" + ) + +" `; exports[`Python Infrastructure Code Generation Script Unit Tests Generates With Mocks Disabled 1`] = ` @@ -185,11 +194,8 @@ class MockIntegrations: """ Type-safe mock integrations for API operations """ - - # No mock integrations have been generated, since mock data generation is disabled. pass - " `; @@ -233,7 +239,6 @@ class MockIntegrations: """ Type-safe mock integrations for API operations """ - @staticmethod def any_request_response_200(body: str) -> MockIntegration: """ @@ -261,7 +266,7 @@ class MockIntegrations: """ response_body = None if body is None: - with open(path.join(MOCK_DATA_PATH, "GET{}-200.json".format("/map-response".replace("/", "-")).lower()), "r") as f: + with open(path.join(MOCK_DATA_PATH, "get{}-200.json".format("/map-response".replace("/", "-"))), "r") as f: response_body = f.read() else: response_body = body.to_json() @@ -298,7 +303,7 @@ class MockIntegrations: """ response_body = None if body is None: - with open(path.join(MOCK_DATA_PATH, "POST{}-200.json".format("/path/{pathParam}".replace("/", "-")).lower()), "r") as f: + with open(path.join(MOCK_DATA_PATH, "post{}-200.json".format("/path/{pathParam}".replace("/", "-"))), "r") as f: response_body = f.read() else: response_body = body.to_json() @@ -315,7 +320,7 @@ class MockIntegrations: """ response_body = None if body is None: - with open(path.join(MOCK_DATA_PATH, "POST{}-400.json".format("/path/{pathParam}".replace("/", "-")).lower()), "r") as f: + with open(path.join(MOCK_DATA_PATH, "post{}-400.json".format("/path/{pathParam}".replace("/", "-"))), "r") as f: response_body = f.read() else: response_body = body.to_json() @@ -332,7 +337,7 @@ class MockIntegrations: """ response_body = None if body is None: - with open(path.join(MOCK_DATA_PATH, "DELETE{}-200.json".format("/without-operation-id".replace("/", "-")).lower()), "r") as f: + with open(path.join(MOCK_DATA_PATH, "delete{}-200.json".format("/without-operation-id".replace("/", "-"))), "r") as f: response_body = f.read() else: response_body = body.to_json() @@ -368,7 +373,5 @@ class MockIntegrations: }, **kwargs }) - - " `; diff --git a/packages/type-safe-api/test/scripts/generators/async/__snapshots__/python-cdk-infrastructure.test.ts.snap b/packages/type-safe-api/test/scripts/generators/async/__snapshots__/python-cdk-infrastructure.test.ts.snap index 80ac7dd58..8799dc5fd 100644 --- a/packages/type-safe-api/test/scripts/generators/async/__snapshots__/python-cdk-infrastructure.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/async/__snapshots__/python-cdk-infrastructure.test.ts.snap @@ -10,7 +10,6 @@ from os import path from pathlib import Path - class JavaOneFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of JavaOne @@ -27,6 +26,7 @@ class JavaOneFunction(SnapStartFunction): **kwargs, ) + class JavaTwoFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of JavaTwo @@ -43,6 +43,7 @@ class JavaTwoFunction(SnapStartFunction): **kwargs, ) + class PythonOneFunction(Function): """ Lambda function construct which points to the python implementation of PythonOne @@ -59,6 +60,7 @@ class PythonOneFunction(Function): **kwargs, ) + class PythonTwoFunction(Function): """ Lambda function construct which points to the python implementation of PythonTwo @@ -75,6 +77,7 @@ class PythonTwoFunction(Function): **kwargs, ) + class TypescriptOneFunction(Function): """ Lambda function construct which points to the typescript implementation of TypescriptOne @@ -92,6 +95,7 @@ class TypescriptOneFunction(Function): **kwargs, ) + class TypescriptTwoFunction(Function): """ Lambda function construct which points to the typescript implementation of TypescriptTwo @@ -107,7 +111,9 @@ class TypescriptTwoFunction(Function): tracing=Tracing.ACTIVE, timeout=Duration.seconds(30), **kwargs, - )" + ) + +" `; exports[`Python Async Infrastructure Code Generation Script Unit Tests Generates Functions for inline-body.yaml 1`] = ` @@ -120,7 +126,6 @@ from os import path from pathlib import Path - class JavaFunction(SnapStartFunction): """ Lambda function construct which points to the java implementation of Java @@ -137,6 +142,7 @@ class JavaFunction(SnapStartFunction): **kwargs, ) + class PythonFunction(Function): """ Lambda function construct which points to the python implementation of Python @@ -153,6 +159,7 @@ class PythonFunction(Function): **kwargs, ) + class TypeScriptFunction(Function): """ Lambda function construct which points to the typescript implementation of TypeScript @@ -168,7 +175,9 @@ class TypeScriptFunction(Function): tracing=Tracing.ACTIVE, timeout=Duration.seconds(30), **kwargs, - )" + ) + +" `; exports[`Python Async Infrastructure Code Generation Script Unit Tests Generates With single.yaml 1`] = ` @@ -197,4 +206,21 @@ class Api(TypeSafeRestApi): exports[`Python Async Infrastructure Code Generation Script Unit Tests Generates With single.yaml 2`] = `"#"`; -exports[`Python Async Infrastructure Code Generation Script Unit Tests Generates With single.yaml 3`] = `undefined`; +exports[`Python Async Infrastructure Code Generation Script Unit Tests Generates With single.yaml 3`] = ` +"import json +from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration +from test_client.models import * +from test_client.api.operation_config import OperationConfig +from os import path +from pathlib import Path + +MOCK_DATA_PATH = path.join(str(Path(__file__).absolute().parent), "..", "mocks") + +class MockIntegrations: + """ + Type-safe mock integrations for API operations + """ + # No mock integrations have been generated, since mock data generation is disabled. + pass +" +`; diff --git a/packages/type-safe-api/test/scripts/generators/async/python-cdk-infrastructure.test.ts b/packages/type-safe-api/test/scripts/generators/async/python-cdk-infrastructure.test.ts index ff03841a9..0606a4dbe 100644 --- a/packages/type-safe-api/test/scripts/generators/async/python-cdk-infrastructure.test.ts +++ b/packages/type-safe-api/test/scripts/generators/async/python-cdk-infrastructure.test.ts @@ -42,13 +42,10 @@ describe("Python Async Infrastructure Code Generation Script Unit Tests", () => generatedHandlers: {}, }); project.synth(); - exec(project.tasks.tryFind("create-openapitools.json")!.steps[0].exec!, { - cwd: infraOutdir, - }); exec( `${path.resolve( __dirname, - "../../../../scripts/type-safe-api/generators/generate" + "../../../../scripts/type-safe-api/run.js generate" )} ${project.buildGenerateCommandArgs()}`, { cwd: infraOutdir, @@ -88,14 +85,10 @@ describe("Python Async Infrastructure Code Generation Script Unit Tests", () => generatedHandlers: handlers, }); project.synth(); - exec( - project.tasks.tryFind("create-openapitools.json")!.steps[0].exec!, - { cwd: infraOutdir } - ); exec( `${path.resolve( __dirname, - "../../../../scripts/type-safe-api/generators/generate" + "../../../../scripts/type-safe-api/run.js generate" )} ${project.buildGenerateCommandArgs()}`, { cwd: infraOutdir, diff --git a/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts b/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts index 25ee81986..2638c42db 100644 --- a/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts +++ b/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts @@ -39,13 +39,10 @@ describe("Python Infrastructure Code Generation Script Unit Tests", () => { generatedHandlers: {}, }); project.synth(); - exec(project.tasks.tryFind("create-openapitools.json")!.steps[0].exec!, { - cwd: infraOutdir, - }); exec( `${path.resolve( __dirname, - "../../../scripts/type-safe-api/generators/generate" + "../../../scripts/type-safe-api/run.js generate" )} ${project.buildGenerateCommandArgs()}`, { cwd: infraOutdir, @@ -94,13 +91,10 @@ describe("Python Infrastructure Code Generation Script Unit Tests", () => { generatedHandlers: {}, }); project.synth(); - exec(project.tasks.tryFind("create-openapitools.json")!.steps[0].exec!, { - cwd: infraOutdir, - }); exec( `${path.resolve( __dirname, - "../../../scripts/type-safe-api/generators/generate" + "../../../scripts/type-safe-api/run.js generate" )} ${project.buildGenerateCommandArgs()}`, { cwd: infraOutdir, @@ -138,14 +132,10 @@ describe("Python Infrastructure Code Generation Script Unit Tests", () => { generatedHandlers: handlers, }); project.synth(); - exec( - project.tasks.tryFind("create-openapitools.json")!.steps[0].exec!, - { cwd: infraOutdir } - ); exec( `${path.resolve( __dirname, - "../../../scripts/type-safe-api/generators/generate" + "../../../scripts/type-safe-api/run.js generate" )} ${project.buildGenerateCommandArgs()}`, { cwd: infraOutdir,