@goast/typescript 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ import { HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
2
+ import { Observable, filter, firstValueFrom } from 'rxjs';
3
+
4
+ export async function waitForResponse<T extends HttpResponse<any> | HttpErrorResponse>(
5
+ httpEvents: Observable<HttpEvent<any>>,
6
+ ): Promise<T> {
7
+ try {
8
+ const response = await firstValueFrom(httpEvents.pipe(filter((event) => event instanceof HttpResponse)));
9
+ return response as T;
10
+ } catch (error) {
11
+ if (error instanceof HttpErrorResponse) {
12
+ return error as T;
13
+ }
14
+ throw error;
15
+ }
16
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.httpResponse = exports.httpContext = exports.httpClient = exports.provider = exports.injectable = exports.inject = void 0;
3
+ exports.httpErrorResponse = exports.httpResponse = exports.httpContext = exports.httpClient = exports.provider = exports.injectable = exports.inject = void 0;
4
4
  const reference_1 = require("../nodes/reference");
5
5
  // @angular/core
6
6
  exports.inject = reference_1.tsReference.factory('inject', '@angular/core');
@@ -10,3 +10,4 @@ exports.provider = reference_1.tsReference.factory('Provider', '@angular/core');
10
10
  exports.httpClient = reference_1.tsReference.factory('HttpClient', '@angular/common/http');
11
11
  exports.httpContext = reference_1.tsReference.factory('HttpContext', '@angular/common/http');
12
12
  exports.httpResponse = reference_1.tsReference.genericFactory('HttpResponse', '@angular/common/http');
13
+ exports.httpErrorResponse = reference_1.tsReference.factory('HttpErrorResponse', '@angular/common/http');
@@ -162,7 +162,12 @@ class DefaultTypeScriptModelGenerator extends file_generator_1.TypeScriptFileGen
162
162
  members: Object.entries(discriminator.mapping).map(([key, value]) => ast_1.ts.property(key, {
163
163
  type: ast_1.ts.intersectionType([
164
164
  ast_1.ts.objectType({
165
- members: [ast_1.ts.property(discriminator.propertyName, { type: ast_1.ts.string(key) })],
165
+ members: [
166
+ ast_1.ts.property(discriminator.propertyName, {
167
+ type: ast_1.ts.string(key),
168
+ readonly: ctx.config.immutableTypes,
169
+ }),
170
+ ],
166
171
  }),
167
172
  this.getType(ctx, value),
168
173
  ]),
@@ -50,15 +50,19 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
50
50
  }
51
51
  result.values.push(ast_1.ts.typeAlias(this.getResponseModelName(ctx, endpoint), ast_1.ts.intersectionType([
52
52
  ast_1.ts.unionType([
53
- ...Object.entries(statusCodes).map(([key, value]) => ast_1.ts.intersectionType([
54
- ast_1.ts.refs.angular.httpResponse([value]),
55
- ast_1.ts.objectType({
56
- members: [
57
- ast_1.ts.property('status', { type: key }),
58
- ast_1.ts.property('ok', { type: key.startsWith('2') ? 'true' : 'false' }),
59
- ],
60
- }),
61
- ])),
53
+ ...Object.entries(statusCodes).map(([key, value]) => {
54
+ const isSuccess = key.startsWith('2');
55
+ return ast_1.ts.intersectionType([
56
+ isSuccess ? ast_1.ts.refs.angular.httpResponse([value]) : ast_1.ts.refs.angular.httpErrorResponse(),
57
+ ast_1.ts.objectType({
58
+ members: [
59
+ isSuccess ? null : ast_1.ts.property('error', { type: ast_1.ts.unionType([value, ast_1.ts.refs.null_()]) }),
60
+ ast_1.ts.property('status', { type: key }),
61
+ ast_1.ts.property('ok', { type: isSuccess ? 'true' : 'false' }),
62
+ ],
63
+ }),
64
+ ]);
65
+ }),
62
66
  !ctx.config.strictResponseTypes
63
67
  ? ast_1.ts.intersectionType([
64
68
  ast_1.ts.refs.angular.httpResponse([this.getAnyType(ctx)]),
@@ -150,9 +154,8 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
150
154
  var _a, _b, _c, _d;
151
155
  const hasParams = this.hasEndpointParams(ctx, endpoint);
152
156
  const paramsOptional = !endpoint.parameters.some((p) => p.required) && !((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.required);
153
- const returnType = ast_1.ts.refs.promise([
154
- ast_1.ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx)),
155
- ]);
157
+ const responseModelType = ast_1.ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx));
158
+ const returnType = ast_1.ts.refs.promise([responseModelType]);
156
159
  const accept = (_d = (_c = (_b = this.getEndpointSuccessResponse(ctx, endpoint)) === null || _b === void 0 ? void 0 : _b.contentOptions[0]) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '*/*';
157
160
  const responseType = accept.includes('json') ? 'json' : 'text';
158
161
  return ast_1.ts.method(this.getEndpointMethodName(ctx, endpoint), {
@@ -191,16 +194,13 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
191
194
  }
192
195
  : null,
193
196
  '',
194
- (0, core_1.builderTemplate) `return ${ast_1.ts.refs.rxjs.firstValueFrom()}(${core_1.builderTemplate.indent `
197
+ (0, core_1.builderTemplate) `return ${ctx.refs.waitForResponse([responseModelType])}(${core_1.builderTemplate.indent `
195
198
  this.http.request(rb.build({${core_1.builderTemplate.indent `
196
199
  responseType: ${ast_1.ts.string(responseType)},
197
200
  accept: ${ast_1.ts.string(accept)},
198
201
  context,`}
199
- })).pipe(${core_1.builderTemplate.indent `
200
- ${ast_1.ts.refs.rxjs.filter()}((r: unknown) => r instanceof ${ast_1.ts.refs.angular.httpResponse.infer()}),
201
- ${ast_1.ts.refs.rxjs.take()}(1),`}
202
- )`}
203
- ) as unknown as ${returnType};`,
202
+ }))`}
203
+ )`,
204
204
  ], '\n'),
205
205
  });
206
206
  }
@@ -46,7 +46,8 @@ class TypeScriptAngularServicesGenerator extends core_1.OpenApiServicesGeneratio
46
46
  const sourceDir = (0, path_1.resolve)((0, path_1.dirname)(require.resolve('@goast/typescript')), '../assets/client/angular');
47
47
  const targetDir = (0, path_1.resolve)(ctx.config.outputDir, ctx.config.utilsDirPath);
48
48
  (0, fs_extra_1.ensureDirSync)(targetDir);
49
- this.copyFile('request builder', sourceDir, targetDir, 'request-builder.ts');
49
+ this.copyFile('Request Builder', sourceDir, targetDir, 'request-builder.ts');
50
+ this.copyFile('Angular Service Utils', sourceDir, targetDir, 'angular-service.utils.ts');
50
51
  file_builder_1.TypeScriptFileBuilder.generate({
51
52
  logName: 'api configuration',
52
53
  filePath: (0, path_1.resolve)(targetDir, 'api-configuration.ts'),
@@ -9,6 +9,8 @@ function getReferenceFactories(options) {
9
9
  var _a, _b;
10
10
  const utilsDirPath = (0, path_1.resolve)(options.outputDir, options.utilsDirPath);
11
11
  return {
12
+ // angular-service.utils.ts
13
+ waitForResponse: ast_1.ts.reference.genericFactory('waitForResponse', (0, path_1.join)(utilsDirPath, 'angular-service.utils.ts')),
12
14
  // request-builder.ts
13
15
  requestBuilder: ast_1.ts.reference.factory('RequestBuilder', (0, path_1.join)(utilsDirPath, 'request-builder.ts')),
14
16
  // api-configuration.ts - generated in angular-services-generator.ts
@@ -7,3 +7,4 @@ export const provider = tsReference.factory('Provider', '@angular/core');
7
7
  export const httpClient = tsReference.factory('HttpClient', '@angular/common/http');
8
8
  export const httpContext = tsReference.factory('HttpContext', '@angular/common/http');
9
9
  export const httpResponse = tsReference.genericFactory('HttpResponse', '@angular/common/http');
10
+ export const httpErrorResponse = tsReference.factory('HttpErrorResponse', '@angular/common/http');
@@ -159,7 +159,12 @@ export class DefaultTypeScriptModelGenerator extends TypeScriptFileGenerator {
159
159
  members: Object.entries(discriminator.mapping).map(([key, value]) => ts.property(key, {
160
160
  type: ts.intersectionType([
161
161
  ts.objectType({
162
- members: [ts.property(discriminator.propertyName, { type: ts.string(key) })],
162
+ members: [
163
+ ts.property(discriminator.propertyName, {
164
+ type: ts.string(key),
165
+ readonly: ctx.config.immutableTypes,
166
+ }),
167
+ ],
163
168
  }),
164
169
  this.getType(ctx, value),
165
170
  ]),
@@ -47,15 +47,19 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
47
47
  }
48
48
  result.values.push(ts.typeAlias(this.getResponseModelName(ctx, endpoint), ts.intersectionType([
49
49
  ts.unionType([
50
- ...Object.entries(statusCodes).map(([key, value]) => ts.intersectionType([
51
- ts.refs.angular.httpResponse([value]),
52
- ts.objectType({
53
- members: [
54
- ts.property('status', { type: key }),
55
- ts.property('ok', { type: key.startsWith('2') ? 'true' : 'false' }),
56
- ],
57
- }),
58
- ])),
50
+ ...Object.entries(statusCodes).map(([key, value]) => {
51
+ const isSuccess = key.startsWith('2');
52
+ return ts.intersectionType([
53
+ isSuccess ? ts.refs.angular.httpResponse([value]) : ts.refs.angular.httpErrorResponse(),
54
+ ts.objectType({
55
+ members: [
56
+ isSuccess ? null : ts.property('error', { type: ts.unionType([value, ts.refs.null_()]) }),
57
+ ts.property('status', { type: key }),
58
+ ts.property('ok', { type: isSuccess ? 'true' : 'false' }),
59
+ ],
60
+ }),
61
+ ]);
62
+ }),
59
63
  !ctx.config.strictResponseTypes
60
64
  ? ts.intersectionType([
61
65
  ts.refs.angular.httpResponse([this.getAnyType(ctx)]),
@@ -147,9 +151,8 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
147
151
  var _a, _b, _c, _d;
148
152
  const hasParams = this.hasEndpointParams(ctx, endpoint);
149
153
  const paramsOptional = !endpoint.parameters.some((p) => p.required) && !((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.required);
150
- const returnType = ts.refs.promise([
151
- ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx)),
152
- ]);
154
+ const responseModelType = ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx));
155
+ const returnType = ts.refs.promise([responseModelType]);
153
156
  const accept = (_d = (_c = (_b = this.getEndpointSuccessResponse(ctx, endpoint)) === null || _b === void 0 ? void 0 : _b.contentOptions[0]) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '*/*';
154
157
  const responseType = accept.includes('json') ? 'json' : 'text';
155
158
  return ts.method(this.getEndpointMethodName(ctx, endpoint), {
@@ -188,16 +191,13 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
188
191
  }
189
192
  : null,
190
193
  '',
191
- s `return ${ts.refs.rxjs.firstValueFrom()}(${s.indent `
194
+ s `return ${ctx.refs.waitForResponse([responseModelType])}(${s.indent `
192
195
  this.http.request(rb.build({${s.indent `
193
196
  responseType: ${ts.string(responseType)},
194
197
  accept: ${ts.string(accept)},
195
198
  context,`}
196
- })).pipe(${s.indent `
197
- ${ts.refs.rxjs.filter()}((r: unknown) => r instanceof ${ts.refs.angular.httpResponse.infer()}),
198
- ${ts.refs.rxjs.take()}(1),`}
199
- )`}
200
- ) as unknown as ${returnType};`,
199
+ }))`}
200
+ )`,
201
201
  ], '\n'),
202
202
  });
203
203
  }
@@ -43,7 +43,8 @@ export class TypeScriptAngularServicesGenerator extends OpenApiServicesGeneratio
43
43
  const sourceDir = resolve(dirname(require.resolve('@goast/typescript')), '../assets/client/angular');
44
44
  const targetDir = resolve(ctx.config.outputDir, ctx.config.utilsDirPath);
45
45
  ensureDirSync(targetDir);
46
- this.copyFile('request builder', sourceDir, targetDir, 'request-builder.ts');
46
+ this.copyFile('Request Builder', sourceDir, targetDir, 'request-builder.ts');
47
+ this.copyFile('Angular Service Utils', sourceDir, targetDir, 'angular-service.utils.ts');
47
48
  TypeScriptFileBuilder.generate({
48
49
  logName: 'api configuration',
49
50
  filePath: resolve(targetDir, 'api-configuration.ts'),
@@ -6,6 +6,8 @@ export function getReferenceFactories(options) {
6
6
  var _a, _b;
7
7
  const utilsDirPath = resolve(options.outputDir, options.utilsDirPath);
8
8
  return {
9
+ // angular-service.utils.ts
10
+ waitForResponse: ts.reference.genericFactory('waitForResponse', join(utilsDirPath, 'angular-service.utils.ts')),
9
11
  // request-builder.ts
10
12
  requestBuilder: ts.reference.factory('RequestBuilder', join(utilsDirPath, 'request-builder.ts')),
11
13
  // api-configuration.ts - generated in angular-services-generator.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goast/typescript",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "repository": "https://github.com/MaSch0212/goast.git",
5
5
  "author": {
6
6
  "name": "Marc Schmidt (MaSch0212)",
@@ -35,3 +35,9 @@ export declare const httpResponse: (<TBuilder extends import("@goast/core").Sour
35
35
  } & {
36
36
  moduleNameOrfilePath: string;
37
37
  };
38
+ export declare const httpErrorResponse: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => import("../nodes/reference").TsReference<TBuilder, never>) & {
39
+ refName: string;
40
+ moduleNameOrfilePath: import("@goast/core").Nullable<string>;
41
+ } & {
42
+ moduleNameOrfilePath: string;
43
+ };
@@ -1,31 +1,38 @@
1
1
  import { ts } from '../../../ast';
2
2
  import type { TypeScriptAngularServicesGeneratorConfig } from './models';
3
3
  export declare function getReferenceFactories(options: TypeScriptAngularServicesGeneratorConfig): {
4
- requestBuilder: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder, never>) & {
4
+ waitForResponse: (<TBuilder extends import("@goast/core").SourceBuilder<never>>(generics: [ts.Type<TBuilder>]) => ts.Reference<TBuilder, never>) & {
5
5
  refName: string;
6
6
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;
7
+ infer: <TBuilder_1 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_1, never>;
7
8
  } & {
8
9
  moduleNameOrfilePath: string;
9
10
  };
10
- apiConfiguration: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder, never>) & {
11
+ requestBuilder: (<TBuilder_2 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_2, never>) & {
11
12
  refName: string;
12
13
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;
13
14
  } & {
14
15
  moduleNameOrfilePath: string;
15
16
  };
16
- apiBaseService: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder, never>) & {
17
+ apiConfiguration: (<TBuilder_2 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_2, never>) & {
17
18
  refName: string;
18
19
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;
19
20
  } & {
20
21
  moduleNameOrfilePath: string;
21
22
  };
22
- httpStatusCode: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder, never>) & {
23
+ apiBaseService: (<TBuilder_2 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_2, never>) & {
23
24
  refName: string;
24
25
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;
25
26
  } & {
26
27
  moduleNameOrfilePath: string;
27
28
  };
28
- provide: (<TBuilder extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder, never>) & {
29
+ httpStatusCode: (<TBuilder_2 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_2, never>) & {
30
+ refName: string;
31
+ moduleNameOrfilePath: import("@goast/core").Nullable<string>;
32
+ } & {
33
+ moduleNameOrfilePath: string;
34
+ };
35
+ provide: (<TBuilder_2 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_2, never>) & {
29
36
  refName: string;
30
37
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;
31
38
  } & {