Skip to content

Commit

Permalink
fix(typescript-angular): fix new angular dependency cli option usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Thibaud SOWA committed Dec 4, 2024
1 parent 0183620 commit a127430
Show file tree
Hide file tree
Showing 74 changed files with 2,911 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v19-with-angular-dependency-params/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 19.0.1
npmName: sample-angular-19-0-0-with-angular-dependency-params
supportsES6: true
tsVersion: 5.7.0
zonejsVersion: 0.15.0
ngPackagrVersion: 19.0.1
rxjsVersion: 6.5.3
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default
outputDir: samples/client/petstore/typescript-angular-v19/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 19.0.0
npmName: sample-angular-19-0-0
supportsES6: true
2 changes: 1 addition & 1 deletion docs/generators/typescript-angular.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|
|useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|zoneJsVersion|The version of zone.js compatible with Angular (see ngVersion option).| |null|
|zonejsVersion|The version of zone.js compatible with Angular (see ngVersion option).| |null|

## IMPORT MAPPING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static enum PROVIDED_IN_LEVEL {none, root, any, platform}
public static final String TS_VERSION = "tsVersion";
public static final String RXJS_VERSION = "rxjsVersion";
public static final String NGPACKAGR_VERSION = "ngPackagrVersion";
public static final String ZONEJS_VERSION = "zoneJsVersion";
public static final String ZONEJS_VERSION = "zonejsVersion";

protected String ngVersion = "19.0.0";
@Getter @Setter
Expand Down Expand Up @@ -321,21 +321,21 @@ private void addNpmPackageGeneration(SemVer ngVersion) {
.map(Map.Entry::getValue)
.orElseThrow(() -> new IllegalArgumentException("Invalid ngVersion. Only Angular v9+ is supported."));

additionalProperties.put(TS_VERSION, additionalProperties.containsKey(TS_VERSION)
? additionalProperties.containsKey(TS_VERSION)
: angularDependencies.getTsVersion());
if (!additionalProperties.containsKey(TS_VERSION)) {
additionalProperties.put(TS_VERSION, angularDependencies.getTsVersion());
}

additionalProperties.put(RXJS_VERSION, additionalProperties.containsKey(RXJS_VERSION)
? additionalProperties.containsKey(RXJS_VERSION)
: angularDependencies.getRxjsVersion());
if (!additionalProperties.containsKey(RXJS_VERSION)) {
additionalProperties.put(RXJS_VERSION, angularDependencies.getRxjsVersion());
}

additionalProperties.put(NGPACKAGR_VERSION, additionalProperties.containsKey(NGPACKAGR_VERSION)
? additionalProperties.containsKey(NGPACKAGR_VERSION)
: angularDependencies.getNgPackagrVersion());
if (!additionalProperties.containsKey(NGPACKAGR_VERSION)) {
additionalProperties.put(NGPACKAGR_VERSION, angularDependencies.getNgPackagrVersion());
}

additionalProperties.put("zonejsVersion", additionalProperties.containsKey(ZONEJS_VERSION)
? additionalProperties.containsKey(ZONEJS_VERSION)
: angularDependencies.getZonejsVersion());
if (!additionalProperties.containsKey(ZONEJS_VERSION)) {
additionalProperties.put(ZONEJS_VERSION, angularDependencies.getZonejsVersion());
}

if (angularDependencies.getTsickleVersion() != null) {
additionalProperties.put("tsickleVersion", angularDependencies.getTsickleVersion());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public class TypeScriptAngularClientOptionsProvider implements TypeScriptSharedClientOptionsProvider {
public static final String STRING_ENUMS_VALUE = "false";
private static final String NPM_REPOSITORY = "https://registry.npmjs.org";
public static final String NG_VERSION = "12";
public static final String NG_VERSION = "19";
public static final String FILE_NAMING_VALUE = "camelCase";
public static final String API_MODULE_PREFIX = "";
public static final String CONFIGURATION_PREFIX = "";
Expand All @@ -37,7 +37,7 @@ public class TypeScriptAngularClientOptionsProvider implements TypeScriptSharedC
public static final String MODEL_FILE_SUFFIX = "";
public static final String TS_VERSION = "";
public static final String RXJS_VERSION = "";
public static final String NGPACKAGR_VERSION = " ";
public static final String NGPACKAGR_VERSION = "";
public static final String ZONEJS_VERSION = "";

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;


@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR})
public class TypeScriptAngularClientCodegenTest {
Expand Down Expand Up @@ -344,4 +346,48 @@ public void testModelNameMappings() throws Exception {
"files?: Array<SystemFile>;" // ensure it's an array of SystemFile (not Any)
);
}

@Test
public void testAngularDependenciesFromCliOptions() {
// GIVEN
OpenAPI openAPI = TestUtils.createOpenAPI();

TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
codegen.additionalProperties().put("tsVersion", "12");
codegen.additionalProperties().put("rxjsVersion", "23");
codegen.additionalProperties().put("ngPackagrVersion", "34");
codegen.additionalProperties().put("zonejsVersion", "45");

// WHEN
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);

// THEN
assertThat(codegen.additionalProperties()).containsEntry("tsVersion", "12");
assertThat(codegen.additionalProperties()).containsEntry("rxjsVersion", "23");
assertThat(codegen.additionalProperties()).containsEntry("ngPackagrVersion", "34");
assertThat(codegen.additionalProperties()).containsEntry("zonejsVersion", "45");
}

@Test
public void testAngularDependenciesFromConfigFile() {
// GIVEN
OpenAPI openAPI = TestUtils.createOpenAPI();

TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
// We fix ngVersion to do not update this test on every new angular release.
codegen.additionalProperties().put("ngVersion", "19.0.0");

// WHEN
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);

// THEN
assertThat(codegen.additionalProperties()).containsEntry("tsVersion", ">=5.5.0 <5.7.0");
assertThat(codegen.additionalProperties()).containsEntry("rxjsVersion", "7.4.0");
assertThat(codegen.additionalProperties()).containsEntry("ngPackagrVersion", "19.0.0");
assertThat(codegen.additionalProperties()).containsEntry("zonejsVersion", "0.15.0");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ model/order.ts
model/pet.ts
model/tag.ts
model/user.ts
ng-package.json
package.json
param.ts
tsconfig.json
variables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# [email protected]

This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.

The version of the OpenAPI document: 1.0.0

## Building

To install the required dependencies and to build the typescript sources run:

```console
npm install
npm run build
```

## Publishing

First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!)

## Consuming

Navigate to the folder of your consuming project and run one of next commands.

_published:_

```console
npm install [email protected] --save
```

_without publishing (not recommended):_

```console
npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save
```

_It's important to take the tgz file, otherwise you'll get trouble with links on windows_

_using `npm link`:_

In PATH_TO_GENERATED_PACKAGE/dist:

```console
npm link
```

In your project:

```console
npm link sample-angular-19-0-0-with-angular-dependency-params
```

__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages.
Please refer to this issue <https://github.com/angular/angular-cli/issues/8284> for a solution / workaround.
Published packages are not effected by this issue.

### General usage

In your Angular project:

```typescript
// without configuring providers
import { ApiModule } from 'sample-angular-19-0-0-with-angular-dependency-params';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
imports: [
ApiModule,
// make sure to import the HttpClientModule in the AppModule only,
// see https://github.com/angular/angular/issues/20575
HttpClientModule
],
declarations: [ AppComponent ],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

```typescript
// configuring providers
import { ApiModule, Configuration, ConfigurationParameters } from 'sample-angular-19-0-0-with-angular-dependency-params';

export function apiConfigFactory (): Configuration {
const params: ConfigurationParameters = {
// set configuration parameters here.
}
return new Configuration(params);
}

@NgModule({
imports: [ ApiModule.forRoot(apiConfigFactory) ],
declarations: [ AppComponent ],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

```typescript
// configuring providers with an authentication service that manages your access tokens
import { ApiModule, Configuration } from 'sample-angular-19-0-0-with-angular-dependency-params';

@NgModule({
imports: [ ApiModule ],
declarations: [ AppComponent ],
providers: [
{
provide: Configuration,
useFactory: (authService: AuthService) => new Configuration(
{
basePath: environment.apiUrl,
accessToken: authService.getAccessToken.bind(authService)
}
),
deps: [AuthService],
multi: false
}
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

```typescript
import { DefaultApi } from 'sample-angular-19-0-0-with-angular-dependency-params';

export class AppComponent {
constructor(private apiGateway: DefaultApi) { }
}
```

Note: The ApiModule is restricted to being instantiated once app wide.
This is to ensure that all services are treated as singletons.

### Using multiple OpenAPI files / APIs / ApiModules

In order to use multiple `ApiModules` generated from different OpenAPI files,
you can create an alias name when importing the modules
in order to avoid naming conflicts:

```typescript
import { ApiModule } from 'my-api-path';
import { ApiModule as OtherApiModule } from 'my-other-api-path';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
imports: [
ApiModule,
OtherApiModule,
// make sure to import the HttpClientModule in the AppModule only,
// see https://github.com/angular/angular/issues/20575
HttpClientModule
]
})
export class AppModule {

}
```

### Set service base path

If different than the generated base path, during app bootstrap, you can provide the base path to your service.

```typescript
import { BASE_PATH } from 'sample-angular-19-0-0-with-angular-dependency-params';

bootstrap(AppComponent, [
{ provide: BASE_PATH, useValue: 'https://your-web-service.com' },
]);
```

or

```typescript
import { BASE_PATH } from 'sample-angular-19-0-0-with-angular-dependency-params';

@NgModule({
imports: [],
declarations: [ AppComponent ],
providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

### Using @angular/cli

First extend your `src/environments/*.ts` files by adding the corresponding base path:

```typescript
export const environment = {
production: false,
API_BASE_PATH: 'http://127.0.0.1:8080'
};
```

In the src/app/app.module.ts:

```typescript
import { BASE_PATH } from 'sample-angular-19-0-0-with-angular-dependency-params';
import { environment } from '../environments/environment';

@NgModule({
declarations: [
AppComponent
],
imports: [ ],
providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }],
bootstrap: [ AppComponent ]
})
export class AppModule { }
```

### Customizing path parameter encoding

Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple'
and Dates for format 'date-time' are encoded correctly.

Other styles (e.g. "matrix") are not that easy to encode
and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]).

To implement your own parameter encoding (or call another library),
pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object
(see [General Usage](#general-usage) above).

Example value for use in your Configuration-Provider:

```typescript
new Configuration({
encodeParam: (param: Param) => myFancyParamEncoder(param),
})
```

[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations
[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values
[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander
Loading

0 comments on commit a127430

Please sign in to comment.