Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[typescript] Add importFileExtension option to support ECMAScript module resolution #14371

Merged
merged 4 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/generators/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)| |Buffer|
|framework|Specify the framework which should be used in the client code.|<dl><dt>**fetch-api**</dt><dd>fetch-api</dd><dt>**jquery**</dt><dd>jquery</dd></dl>|fetch-api|
|importFileExtension|File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.| |null|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
private static final String PLATFORM_SWITCH = "platform";
private static final String PLATFORM_SWITCH_DESC = "Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.";
private static final String[] PLATFORMS = { "browser", "node", "deno" };
private static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension";
private static final String IMPORT_FILE_EXTENSION_SWITCH_DESC = "File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.";
private static final String FILE_CONTENT_DATA_TYPE= "fileContentDataType";
private static final String FILE_CONTENT_DATA_TYPE_DESC = "Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)";
private static final String USE_RXJS_SWITCH = "useRxJS";
Expand Down Expand Up @@ -198,6 +200,7 @@ public TypeScriptClientCodegen() {
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_INVERSIFY_SWITCH, TypeScriptClientCodegen.USE_INVERSIFY_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));

CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
Expand Down Expand Up @@ -835,8 +838,9 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
}

if ("deno".equals(propPlatform)) {
additionalProperties.put("extensionForDeno", ".ts");
Object fileExtension = additionalProperties.get(IMPORT_FILE_EXTENSION_SWITCH);
if (fileExtension == null && "deno".equals(propPlatform)) {
additionalProperties.put(IMPORT_FILE_EXTENSION_SWITCH, ".ts");
}

final boolean useRxJS = convertPropertyToBooleanAndWriteBack(USE_RXJS_SWITCH);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
// TODO: better import syntax?
import {BaseAPIRequestFactory, RequiredError, COLLECTION_FORMATS} from './baseapi{{extensionForDeno}}';
import {Configuration} from '../configuration{{extensionForDeno}}';
import {RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http{{extensionForDeno}}';
import {BaseAPIRequestFactory, RequiredError, COLLECTION_FORMATS} from './baseapi{{importFileExtension}}';
import {Configuration} from '../configuration{{importFileExtension}}';
import {RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http{{importFileExtension}}';
{{#platforms}}
{{#node}}
import {{^supportsES6}}* as{{/supportsES6}} FormData from "form-data";
import { URLSearchParams } from 'url';
{{/node}}
{{/platforms}}
import {ObjectSerializer} from '../models/ObjectSerializer{{extensionForDeno}}';
import {ApiException} from './exception{{extensionForDeno}}';
import {canConsumeForm, isCodeInRange} from '../util{{extensionForDeno}}';
import {SecurityAuthentication} from '../auth/auth{{extensionForDeno}}';
import {ObjectSerializer} from '../models/ObjectSerializer{{importFileExtension}}';
import {ApiException} from './exception{{importFileExtension}}';
import {canConsumeForm, isCodeInRange} from '../util{{importFileExtension}}';
import {SecurityAuthentication} from '../auth/auth{{importFileExtension}}';

{{#useInversify}}
import { injectable } from "inversify";
{{/useInversify}}

{{#imports}}
import { {{classname}} } from '{{filename}}{{extensionForDeno}}';
import { {{classname}} } from '{{filename}}{{importFileExtension}}';
{{/imports}}
{{#operations}}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Configuration } from '../configuration{{extensionForDeno}}'
import { Configuration } from '../configuration{{importFileExtension}}'
{{#useInversify}}
import { injectable, inject } from "inversify";
import { AbstractConfiguration } from "../services/configuration";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {RequestContext, ResponseContext} from './http/http{{extensionForDeno}}';
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'./rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import {RequestContext, ResponseContext} from './http/http{{importFileExtension}}';
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'./rxjsStub{{importFileExtension}}'{{/useRxJS}};

/**
* Defines the contract for a middleware intercepting requests before
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RequestContext } from "../http/http{{extensionForDeno}}";
import { RequestContext } from "../http/http{{importFileExtension}}";
{{#useInversify}}
import { injectable, inject, named } from "inversify";
import { AbstractTokenProvider } from "../services/configuration";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { HttpLibrary } from "./http/http{{extensionForDeno}}";
import { Middleware, PromiseMiddleware, PromiseMiddlewareWrapper } from "./middleware{{extensionForDeno}}";
import { HttpLibrary } from "./http/http{{importFileExtension}}";
import { Middleware, PromiseMiddleware, PromiseMiddlewareWrapper } from "./middleware{{importFileExtension}}";
{{#frameworks}}
{{#fetch-api}}
import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "./http/isomorphic-fetch{{extensionForDeno}}";
import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "./http/isomorphic-fetch{{importFileExtension}}";
{{/fetch-api}}
{{#jquery}}
import { JQueryHttpLibrary as DefaultHttpLibrary } from "./http/jquery";
{{/jquery}}
{{/frameworks}}
import { BaseServerConfiguration, server1 } from "./servers{{extensionForDeno}}";
import { configureAuthMethods, AuthMethods, AuthMethodsConfiguration } from "./auth/auth{{extensionForDeno}}";
import { BaseServerConfiguration, server1 } from "./servers{{importFileExtension}}";
import { configureAuthMethods, AuthMethods, AuthMethodsConfiguration } from "./auth/auth{{importFileExtension}}";

export interface Configuration {
readonly baseServer: BaseServerConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as https from 'https';
import {{^supportsES6}}* as{{/supportsES6}} URLParse from "url-parse";
{{/deno}}
{{/platforms}}
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};

{{#platforms}}
{{^deno}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {HttpLibrary, RequestContext, ResponseContext} from './http{{extensionForDeno}}';
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import {HttpLibrary, RequestContext, ResponseContext} from './http{{importFileExtension}}';
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};
{{#platforms}}
{{#node}}
import fetch from "node-fetch";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RequestContext, HttpMethod } from "./http/http{{extensionForDeno}}";
import { RequestContext, HttpMethod } from "./http/http{{importFileExtension}}";

export interface BaseServerConfiguration {
makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
export * from "./http/http{{extensionForDeno}}";
export * from "./auth/auth{{extensionForDeno}}";
export * from "./models/all{{extensionForDeno}}";
export { createConfiguration } from "./configuration{{extensionForDeno}}"
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { Configuration } from "./configuration{{extensionForDeno}}"
export * from "./apis/exception{{extensionForDeno}}";
export * from "./servers{{extensionForDeno}}";
export { RequiredError } from "./apis/baseapi{{extensionForDeno}}";
export * from "./http/http{{importFileExtension}}";
export * from "./auth/auth{{importFileExtension}}";
export * from "./models/all{{importFileExtension}}";
export { createConfiguration } from "./configuration{{importFileExtension}}"
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { Configuration } from "./configuration{{importFileExtension}}"
export * from "./apis/exception{{importFileExtension}}";
export * from "./servers{{importFileExtension}}";
export { RequiredError } from "./apis/baseapi{{importFileExtension}}";

{{#useRxJS}}
export { Middleware } from './middleware{{extensionForDeno}}';
export { Middleware } from './middleware{{importFileExtension}}';
{{/useRxJS}}
{{^useRxJS}}
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { PromiseMiddleware as Middleware } from './middleware{{extensionForDeno}}';
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { PromiseMiddleware as Middleware } from './middleware{{importFileExtension}}';
{{/useRxJS}}
{{#useObjectParameters}}
export { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{classname}}{{operationIdCamelCase}}Request, {{/operation}}Object{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObjectParamAPI{{extensionForDeno}}';
export { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{classname}}{{operationIdCamelCase}}Request, {{/operation}}Object{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObjectParamAPI{{importFileExtension}}';
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Observable{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObservableAPI{{extensionForDeno}}';
export { {{#apiInfo}}{{#apis}}{{#operations}}Observable{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObservableAPI{{importFileExtension}}';
{{/useRxJS}}
{{^useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Promise{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/PromiseAPI{{extensionForDeno}}';
export { {{#apiInfo}}{{#apis}}{{#operations}}Promise{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/PromiseAPI{{importFileExtension}}';
{{/useRxJS}}
{{/useObjectParameters}}

{{#useInversify}}
export * from "./services/index{{extensionForDeno}}";
export * from "./services/index{{importFileExtension}}";
{{#useObjectParameters}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractObject{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/ObjectParamAPI';
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractObservable{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/ObservableAPI{{extensionForDeno}}';
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractObservable{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/ObservableAPI{{importFileExtension}}';
{{/useRxJS}}
{{^useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractPromise{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/PromiseAPI{{extensionForDeno}}';
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractPromise{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/PromiseAPI{{importFileExtension}}';
{{/useRxJS}}
{{/useObjectParameters}}
{{/useInversify}}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{{#models}}
{{#model}}
export * from '{{{ importPath }}}{{extensionForDeno}}';
export * from '{{{ importPath }}}{{importFileExtension}}';
{{/model}}
{{/models}}

{{#models}}
{{#model}}
import { {{classname}}{{#hasEnums}}{{#vars}}{{#isEnum}}, {{classname}}{{enumName}} {{/isEnum}} {{/vars}}{{/hasEnums}} } from '{{{ importPath }}}{{extensionForDeno}}';
import { {{classname}}{{#hasEnums}}{{#vars}}{{#isEnum}}, {{classname}}{{enumName}} {{/isEnum}} {{/vars}}{{/hasEnums}} } from '{{{ importPath }}}{{importFileExtension}}';
{{/model}}
{{/models}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
{{#models}}
{{#model}}
{{#tsImports}}
import { {{classname}} } from '{{filename}}{{extensionForDeno}}';
import { {{classname}} } from '{{filename}}{{importFileExtension}}';
{{/tsImports}}
import { HttpFile } from '../http/http{{extensionForDeno}}';
import { HttpFile } from '../http/http{{importFileExtension}}';

{{#description}}
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{#models}}
{{#model}}
export * from '{{{ importPath }}}{{extensionForDeno}}'
export * from '{{{ importPath }}}{{importFileExtension}}'
{{/model}}
{{/models}}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{importFileExtension}}';
import { Configuration} from '../configuration{{importFileExtension}}'
{{#useRxJS}}
import { Observable } from 'rxjs';
{{/useRxJS}}

{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
import { {{{ classname }}} } from '{{{ importPath }}}{{importFileExtension}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}

{{#operations}}
import { Observable{{classname}} } from "./ObservableAPI{{extensionForDeno}}";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
import { Observable{{classname}} } from "./ObservableAPI{{importFileExtension}}";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{importFileExtension}}";

{{#operation}}
export interface {{classname}}{{operationIdCamelCase}}Request {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
import { Observable, of, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import {mergeMap, map} from {{#useRxJS}}'rxjs/operators'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{importFileExtension}}';
import { Configuration} from '../configuration{{importFileExtension}}'
import { Observable, of, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};
import {mergeMap, map} from {{#useRxJS}}'rxjs/operators'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}};
{{#useInversify}}
import { injectable, inject, optional } from "inversify";
import { AbstractConfiguration } from "../services/configuration{{extensionForDeno}}";
import { AbstractConfiguration } from "../services/configuration{{importFileExtension}}";
{{/useInversify}}
{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
import { {{{ classname }}} } from '{{{ importPath }}}{{importFileExtension}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}

{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{importFileExtension}}";
{{#useInversify}}
import { Abstract{{classname}}RequestFactory, Abstract{{classname}}ResponseProcessor } from "../apis/{{classname}}.service{{extensionForDeno}}";
import { Abstract{{classname}}RequestFactory, Abstract{{classname}}ResponseProcessor } from "../apis/{{classname}}.service{{importFileExtension}}";

@injectable()
{{/useInversify}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{importFileExtension}}';
import { Configuration} from '../configuration{{importFileExtension}}'
{{#useInversify}}
import { injectable, inject, optional } from "inversify";
import { AbstractConfiguration } from "../services/configuration";
{{/useInversify}}

{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
import { {{{ classname }}} } from '{{{ importPath }}}{{importFileExtension}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
import { Observable{{classname}} } from './ObservableAPI{{extensionForDeno}}';
import { Observable{{classname}} } from './ObservableAPI{{importFileExtension}}';

{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{importFileExtension}}";
{{#useInversify}}
import { Abstract{{classname}}RequestFactory, Abstract{{classname}}ResponseProcessor } from "../apis/{{classname}}.service";

Expand Down