Skip to content

Commit

Permalink
[typescript] Add importFileExtension option to support ECMAScript m…
Browse files Browse the repository at this point in the history
…odule resolution (#14371)

* Rename 'extensionForDeno' to 'importFileExtension'

* Add importFileExtension option to typescript generator

* Fix typo, update docs

* Update docstring
  • Loading branch information
danmichaelo authored Jan 3, 2023
1 parent 38fdbe0 commit 3dd313d
Show file tree
Hide file tree
Showing 17 changed files with 67 additions and 62 deletions.
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

0 comments on commit 3dd313d

Please sign in to comment.