@orval/angular 8.0.0-rc.3 → 8.0.0-rc.5

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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { generateFormDataAndUrlEncodedFunction, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, isBoolean, pascal, sanitize, toObjectString } from "@orval/core";
1
+ import { generateFormDataAndUrlEncodedFunction, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, getDefaultContentType, isBoolean, pascal, sanitize, toObjectString } from "@orval/core";
2
2
 
3
3
  //#region src/index.ts
4
4
  const ANGULAR_DEPENDENCIES = [
@@ -113,7 +113,7 @@ const generateImplementation = ({ headers, queryParams, operationName, response,
113
113
  isExactOptionalPropertyTypes
114
114
  });
115
115
  const requestOptions = isRequestOptions ? generateMutatorRequestOptions(override.requestOptions, mutator.hasThirdArg) : "";
116
- return ` ${operationName}<TData = ${dataType}>(\n ${mutator.bodyTypeName && body.definition ? toObjectString(props, "implementation").replace(/* @__PURE__ */ new RegExp(`(\\w*):\\s?${body.definition}`), `$1: ${mutator.bodyTypeName}<${body.definition}>`) : toObjectString(props, "implementation")}\n ${isRequestOptions && mutator.hasThirdArg ? `options?: ThirdParameter<typeof ${mutator.name}>` : ""}) {${bodyForm}
116
+ return ` ${operationName}<TData = ${dataType}>(\n ${mutator.bodyTypeName && body.definition ? toObjectString(props, "implementation").replace(new RegExp(String.raw`(\w*):\s?${body.definition}`), `$1: ${mutator.bodyTypeName}<${body.definition}>`) : toObjectString(props, "implementation")}\n ${isRequestOptions && mutator.hasThirdArg ? `options?: ThirdParameter<typeof ${mutator.name}>` : ""}) {${bodyForm}
117
117
  return ${mutator.name}<TData>(
118
118
  ${mutatorConfig},
119
119
  this.http,
@@ -138,12 +138,73 @@ const generateImplementation = ({ headers, queryParams, operationName, response,
138
138
  hasSignal: false
139
139
  });
140
140
  const propsDefinition = toObjectString(props, "definition");
141
+ const successTypes = response.types.success;
142
+ const uniqueContentTypes = [...new Set(successTypes.map((t) => t.contentType).filter(Boolean))];
143
+ const hasMultipleContentTypes = uniqueContentTypes.length > 1;
144
+ const defaultContentType = hasMultipleContentTypes ? getDefaultContentType(uniqueContentTypes) : uniqueContentTypes[0] ?? "application/json";
145
+ const defaultReturnType = (hasMultipleContentTypes ? successTypes.find((t) => t.contentType === defaultContentType) : void 0)?.value ?? dataType;
141
146
  const isModelType = dataType !== "Blob" && dataType !== "string";
142
147
  let functionName = operationName;
143
- if (isModelType) functionName += `<TData = ${dataType}>`;
144
- return ` ${isRequestOptions ? `${functionName}(${propsDefinition} options?: HttpClientOptions & { observe?: 'body' }): Observable<${isModelType ? "TData" : dataType}>;
148
+ if (isModelType && !hasMultipleContentTypes) functionName += `<TData = ${dataType}>`;
149
+ let contentTypeOverloads = "";
150
+ if (hasMultipleContentTypes && isRequestOptions) {
151
+ const requiredProps = props.filter((p) => p.required && !p.default);
152
+ const optionalProps = props.filter((p) => !p.required || p.default);
153
+ contentTypeOverloads = successTypes.filter((t) => t.contentType).map(({ contentType, value }) => {
154
+ return `${operationName}(${[
155
+ requiredProps.map((p) => p.definition).join(",\n "),
156
+ `accept: '${contentType}'`,
157
+ optionalProps.map((p) => p.definition).join(",\n ")
158
+ ].filter(Boolean).join(",\n ")}, options?: HttpClientOptions): Observable<${value}>;`;
159
+ }).join("\n ");
160
+ const allParams = [
161
+ requiredProps.map((p) => p.definition).join(",\n "),
162
+ "accept?: string",
163
+ optionalProps.map((p) => p.definition).join(",\n ")
164
+ ].filter(Boolean).join(",\n ");
165
+ contentTypeOverloads += `\n ${operationName}(${allParams}, options?: HttpClientOptions): Observable<${defaultReturnType}>;`;
166
+ }
167
+ const observeOverloads = isRequestOptions && !hasMultipleContentTypes ? `${functionName}(${propsDefinition} options?: HttpClientOptions & { observe?: 'body' }): Observable<${isModelType ? "TData" : dataType}>;
145
168
  ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'events' }): Observable<HttpEvent<${isModelType ? "TData" : dataType}>>;
146
- ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'response' }): Observable<AngularHttpResponse<${isModelType ? "TData" : dataType}>>;` : ""}
169
+ ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'response' }): Observable<AngularHttpResponse<${isModelType ? "TData" : dataType}>>;` : "";
170
+ const overloads = contentTypeOverloads || observeOverloads;
171
+ if (hasMultipleContentTypes) {
172
+ const requiredProps = props.filter((p) => p.required && !p.default);
173
+ const optionalProps = props.filter((p) => !p.required || p.default);
174
+ const requiredPart = requiredProps.map((p) => p.implementation).join(",\n ");
175
+ const optionalPart = optionalProps.map((p) => p.implementation).join(",\n ");
176
+ return ` ${overloads}
177
+ ${operationName}(
178
+ ${[
179
+ requiredPart,
180
+ `accept: string = '${defaultContentType}'`,
181
+ optionalPart
182
+ ].filter(Boolean).join(",\n ")},
183
+ ${isRequestOptions ? "options?: HttpClientOptions" : ""}
184
+ ): Observable<any> {${bodyForm}
185
+ if (accept.includes('json') || accept.includes('+json')) {
186
+ return this.http.${verb}<any>(\`${route}\`, {
187
+ ...options,
188
+ responseType: 'json',
189
+ headers: { Accept: accept, ...options?.headers },
190
+ });
191
+ } else if (accept.startsWith('text/') || accept.includes('xml')) {
192
+ return this.http.${verb}(\`${route}\`, {
193
+ ...options,
194
+ responseType: 'text',
195
+ headers: { Accept: accept, ...options?.headers },
196
+ }) as any;
197
+ } else {
198
+ return this.http.${verb}(\`${route}\`, {
199
+ ...options,
200
+ responseType: 'blob',
201
+ headers: { Accept: accept, ...options?.headers },
202
+ }) as any;
203
+ }
204
+ }
205
+ `;
206
+ }
207
+ return ` ${overloads}
147
208
  ${functionName}(
148
209
  ${toObjectString(props, "implementation")} ${isRequestOptions ? `options?: HttpClientOptions & { observe?: any }` : ""}): Observable<any> {${bodyForm}
149
210
  return this.http.${verb}${isModelType ? "<TData>" : ""}(${options});
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["ANGULAR_DEPENDENCIES: GeneratorDependency[]","getAngularDependencies: ClientDependenciesBuilder","generateAngularTitle: ClientTitleBuilder","generateAngularHeader: ClientHeaderBuilder","generateAngularFooter: ClientFooterBuilder","generateAngular: ClientBuilder","angularClientBuilder: ClientGeneratorsBuilder"],"sources":["../src/index.ts"],"sourcesContent":["import {\n type ClientBuilder,\n type ClientDependenciesBuilder,\n type ClientFooterBuilder,\n type ClientGeneratorsBuilder,\n type ClientHeaderBuilder,\n type ClientTitleBuilder,\n generateFormDataAndUrlEncodedFunction,\n generateMutatorConfig,\n generateMutatorRequestOptions,\n generateOptions,\n generateVerbImports,\n type GeneratorDependency,\n type GeneratorOptions,\n type GeneratorVerbOptions,\n isBoolean,\n pascal,\n sanitize,\n toObjectString,\n} from '@orval/core';\n\nconst ANGULAR_DEPENDENCIES: GeneratorDependency[] = [\n {\n exports: [\n { name: 'HttpClient', values: true },\n { name: 'HttpHeaders' },\n { name: 'HttpParams' },\n { name: 'HttpContext' },\n { name: 'HttpResponse', alias: 'AngularHttpResponse' }, // alias to prevent naming conflict with msw\n { name: 'HttpEvent' },\n ],\n dependency: '@angular/common/http',\n },\n {\n exports: [\n { name: 'Injectable', values: true },\n { name: 'inject', values: true },\n ],\n dependency: '@angular/core',\n },\n {\n exports: [{ name: 'Observable', values: true }],\n dependency: 'rxjs',\n },\n {\n exports: [{ name: 'DeepNonNullable' }],\n dependency: '@orval/core',\n },\n];\n\nconst returnTypesToWrite = new Map<string, string>();\n\nexport const getAngularDependencies: ClientDependenciesBuilder = () =>\n ANGULAR_DEPENDENCIES;\n\nexport const generateAngularTitle: ClientTitleBuilder = (title) => {\n const sanTitle = sanitize(title);\n return `${pascal(sanTitle)}Service`;\n};\n\nexport const generateAngularHeader: ClientHeaderBuilder = ({\n title,\n isRequestOptions,\n isMutator,\n isGlobalMutator,\n provideIn,\n}) => `\n${\n isRequestOptions && !isGlobalMutator\n ? `interface HttpClientOptions {\n headers?: HttpHeaders | Record<string, string | string[]>;\n context?: HttpContext;\n params?:\n | HttpParams\n | Record<string, string | number | boolean | ReadonlyArray<string | number | boolean>>;\n reportProgress?: boolean;\n withCredentials?: boolean;\n credentials?: RequestCredentials;\n keepalive?: boolean;\n priority?: RequestPriority;\n cache?: RequestCache;\n mode?: RequestMode;\n redirect?: RequestRedirect;\n referrer?: string;\n integrity?: string;\n transferCache?: {includeHeaders?: string[]} | boolean;\n timeout?: number;\n}`\n : ''\n}\n\n${\n isRequestOptions && isMutator\n ? `// eslint-disable-next-line\n type ThirdParameter<T extends (...args: any) => any> = T extends (\n config: any,\n httpClient: any,\n args: infer P,\n) => any\n ? P\n : never;`\n : ''\n}\n\n@Injectable(${\n provideIn\n ? `{ providedIn: '${isBoolean(provideIn) ? 'root' : provideIn}' }`\n : ''\n})\nexport class ${title} {\n private readonly http = inject(HttpClient);\n`;\n\nexport const generateAngularFooter: ClientFooterBuilder = ({\n operationNames,\n}) => {\n let footer = '};\\n\\n';\n\n for (const operationName of operationNames) {\n if (returnTypesToWrite.has(operationName)) {\n // Map.has ensures Map.get will not return undefined, but TS still complains\n // bug https://github.com/microsoft/TypeScript/issues/13086\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n footer += returnTypesToWrite.get(operationName) + '\\n';\n }\n }\n\n return footer;\n};\n\nconst generateImplementation = (\n {\n headers,\n queryParams,\n operationName,\n response,\n mutator,\n body,\n props,\n verb,\n override,\n formData,\n formUrlEncoded,\n paramsSerializer,\n }: GeneratorVerbOptions,\n { route, context }: GeneratorOptions,\n) => {\n const isRequestOptions = override.requestOptions !== false;\n const isFormData = !override.formData.disabled;\n const isFormUrlEncoded = override.formUrlEncoded !== false;\n const isExactOptionalPropertyTypes =\n !!context.output.tsconfig?.compilerOptions?.exactOptionalPropertyTypes;\n const bodyForm = generateFormDataAndUrlEncodedFunction({\n formData,\n formUrlEncoded,\n body,\n isFormData,\n isFormUrlEncoded,\n });\n\n const dataType = response.definition.success || 'unknown';\n\n returnTypesToWrite.set(\n operationName,\n `export type ${pascal(\n operationName,\n )}ClientResult = NonNullable<${dataType}>`,\n );\n\n if (mutator) {\n const mutatorConfig = generateMutatorConfig({\n route,\n body,\n headers,\n queryParams,\n response,\n verb,\n isFormData,\n isFormUrlEncoded,\n hasSignal: false,\n isExactOptionalPropertyTypes,\n });\n\n const requestOptions = isRequestOptions\n ? generateMutatorRequestOptions(\n override.requestOptions,\n mutator.hasThirdArg,\n )\n : '';\n\n const propsImplementation =\n mutator.bodyTypeName && body.definition\n ? toObjectString(props, 'implementation').replace(\n new RegExp(`(\\\\w*):\\\\s?${body.definition}`),\n `$1: ${mutator.bodyTypeName}<${body.definition}>`,\n )\n : toObjectString(props, 'implementation');\n\n return ` ${operationName}<TData = ${dataType}>(\\n ${propsImplementation}\\n ${\n isRequestOptions && mutator.hasThirdArg\n ? `options?: ThirdParameter<typeof ${mutator.name}>`\n : ''\n }) {${bodyForm}\n return ${mutator.name}<TData>(\n ${mutatorConfig},\n this.http,\n ${requestOptions});\n }\n `;\n }\n\n const options = generateOptions({\n route,\n body,\n headers,\n queryParams,\n response,\n verb,\n requestOptions: override.requestOptions,\n isFormData,\n isFormUrlEncoded,\n paramsSerializer,\n paramsSerializerOptions: override.paramsSerializerOptions,\n isAngular: true,\n isExactOptionalPropertyTypes,\n hasSignal: false,\n });\n\n const propsDefinition = toObjectString(props, 'definition');\n const isModelType = dataType !== 'Blob' && dataType !== 'string';\n let functionName = operationName;\n if (isModelType) functionName += `<TData = ${dataType}>`;\n\n const overloads = isRequestOptions\n ? `${functionName}(${propsDefinition} options?: HttpClientOptions & { observe?: 'body' }): Observable<${isModelType ? 'TData' : dataType}>;\n ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'events' }): Observable<HttpEvent<${isModelType ? 'TData' : dataType}>>;\n ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'response' }): Observable<AngularHttpResponse<${isModelType ? 'TData' : dataType}>>;`\n : '';\n\n return ` ${overloads}\n ${functionName}(\n ${toObjectString(props, 'implementation')} ${\n isRequestOptions ? `options?: HttpClientOptions & { observe?: any }` : ''\n }): Observable<any> {${bodyForm}\n return this.http.${verb}${isModelType ? '<TData>' : ''}(${options});\n }\n`;\n};\n\nexport const generateAngular: ClientBuilder = (verbOptions, options) => {\n const imports = generateVerbImports(verbOptions);\n const implementation = generateImplementation(verbOptions, options);\n\n return { implementation, imports };\n};\n\nconst angularClientBuilder: ClientGeneratorsBuilder = {\n client: generateAngular,\n header: generateAngularHeader,\n dependencies: getAngularDependencies,\n footer: generateAngularFooter,\n title: generateAngularTitle,\n};\n\nexport const builder = () => () => angularClientBuilder;\n\nexport default builder;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["ANGULAR_DEPENDENCIES: GeneratorDependency[]","getAngularDependencies: ClientDependenciesBuilder","generateAngularTitle: ClientTitleBuilder","generateAngularHeader: ClientHeaderBuilder","generateAngularFooter: ClientFooterBuilder","generateAngular: ClientBuilder","angularClientBuilder: ClientGeneratorsBuilder"],"sources":["../src/index.ts"],"sourcesContent":["import {\n type ClientBuilder,\n type ClientDependenciesBuilder,\n type ClientFooterBuilder,\n type ClientGeneratorsBuilder,\n type ClientHeaderBuilder,\n type ClientTitleBuilder,\n generateFormDataAndUrlEncodedFunction,\n generateMutatorConfig,\n generateMutatorRequestOptions,\n generateOptions,\n generateVerbImports,\n type GeneratorDependency,\n type GeneratorOptions,\n type GeneratorVerbOptions,\n getDefaultContentType,\n isBoolean,\n pascal,\n sanitize,\n toObjectString,\n} from '@orval/core';\n\nconst ANGULAR_DEPENDENCIES: GeneratorDependency[] = [\n {\n exports: [\n { name: 'HttpClient', values: true },\n { name: 'HttpHeaders' },\n { name: 'HttpParams' },\n { name: 'HttpContext' },\n { name: 'HttpResponse', alias: 'AngularHttpResponse' }, // alias to prevent naming conflict with msw\n { name: 'HttpEvent' },\n ],\n dependency: '@angular/common/http',\n },\n {\n exports: [\n { name: 'Injectable', values: true },\n { name: 'inject', values: true },\n ],\n dependency: '@angular/core',\n },\n {\n exports: [{ name: 'Observable', values: true }],\n dependency: 'rxjs',\n },\n {\n exports: [{ name: 'DeepNonNullable' }],\n dependency: '@orval/core',\n },\n];\n\nconst returnTypesToWrite = new Map<string, string>();\n\nexport const getAngularDependencies: ClientDependenciesBuilder = () =>\n ANGULAR_DEPENDENCIES;\n\nexport const generateAngularTitle: ClientTitleBuilder = (title) => {\n const sanTitle = sanitize(title);\n return `${pascal(sanTitle)}Service`;\n};\n\nexport const generateAngularHeader: ClientHeaderBuilder = ({\n title,\n isRequestOptions,\n isMutator,\n isGlobalMutator,\n provideIn,\n}) => `\n${\n isRequestOptions && !isGlobalMutator\n ? `interface HttpClientOptions {\n headers?: HttpHeaders | Record<string, string | string[]>;\n context?: HttpContext;\n params?:\n | HttpParams\n | Record<string, string | number | boolean | ReadonlyArray<string | number | boolean>>;\n reportProgress?: boolean;\n withCredentials?: boolean;\n credentials?: RequestCredentials;\n keepalive?: boolean;\n priority?: RequestPriority;\n cache?: RequestCache;\n mode?: RequestMode;\n redirect?: RequestRedirect;\n referrer?: string;\n integrity?: string;\n transferCache?: {includeHeaders?: string[]} | boolean;\n timeout?: number;\n}`\n : ''\n}\n\n${\n isRequestOptions && isMutator\n ? `// eslint-disable-next-line\n type ThirdParameter<T extends (...args: any) => any> = T extends (\n config: any,\n httpClient: any,\n args: infer P,\n) => any\n ? P\n : never;`\n : ''\n}\n\n@Injectable(${\n provideIn\n ? `{ providedIn: '${isBoolean(provideIn) ? 'root' : provideIn}' }`\n : ''\n})\nexport class ${title} {\n private readonly http = inject(HttpClient);\n`;\n\nexport const generateAngularFooter: ClientFooterBuilder = ({\n operationNames,\n}) => {\n let footer = '};\\n\\n';\n\n for (const operationName of operationNames) {\n if (returnTypesToWrite.has(operationName)) {\n // Map.has ensures Map.get will not return undefined, but TS still complains\n // bug https://github.com/microsoft/TypeScript/issues/13086\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n footer += returnTypesToWrite.get(operationName) + '\\n';\n }\n }\n\n return footer;\n};\n\nconst generateImplementation = (\n {\n headers,\n queryParams,\n operationName,\n response,\n mutator,\n body,\n props,\n verb,\n override,\n formData,\n formUrlEncoded,\n paramsSerializer,\n }: GeneratorVerbOptions,\n { route, context }: GeneratorOptions,\n) => {\n const isRequestOptions = override.requestOptions !== false;\n const isFormData = !override.formData.disabled;\n const isFormUrlEncoded = override.formUrlEncoded !== false;\n const isExactOptionalPropertyTypes =\n !!context.output.tsconfig?.compilerOptions?.exactOptionalPropertyTypes;\n const bodyForm = generateFormDataAndUrlEncodedFunction({\n formData,\n formUrlEncoded,\n body,\n isFormData,\n isFormUrlEncoded,\n });\n\n const dataType = response.definition.success || 'unknown';\n\n returnTypesToWrite.set(\n operationName,\n `export type ${pascal(\n operationName,\n )}ClientResult = NonNullable<${dataType}>`,\n );\n\n if (mutator) {\n const mutatorConfig = generateMutatorConfig({\n route,\n body,\n headers,\n queryParams,\n response,\n verb,\n isFormData,\n isFormUrlEncoded,\n hasSignal: false,\n isExactOptionalPropertyTypes,\n });\n\n const requestOptions = isRequestOptions\n ? generateMutatorRequestOptions(\n override.requestOptions,\n mutator.hasThirdArg,\n )\n : '';\n\n const propsImplementation =\n mutator.bodyTypeName && body.definition\n ? toObjectString(props, 'implementation').replace(\n new RegExp(String.raw`(\\w*):\\s?${body.definition}`),\n `$1: ${mutator.bodyTypeName}<${body.definition}>`,\n )\n : toObjectString(props, 'implementation');\n\n return ` ${operationName}<TData = ${dataType}>(\\n ${propsImplementation}\\n ${\n isRequestOptions && mutator.hasThirdArg\n ? `options?: ThirdParameter<typeof ${mutator.name}>`\n : ''\n }) {${bodyForm}\n return ${mutator.name}<TData>(\n ${mutatorConfig},\n this.http,\n ${requestOptions});\n }\n `;\n }\n\n const options = generateOptions({\n route,\n body,\n headers,\n queryParams,\n response,\n verb,\n requestOptions: override.requestOptions,\n isFormData,\n isFormUrlEncoded,\n paramsSerializer,\n paramsSerializerOptions: override.paramsSerializerOptions,\n isAngular: true,\n isExactOptionalPropertyTypes,\n hasSignal: false,\n });\n\n const propsDefinition = toObjectString(props, 'definition');\n\n // Check for multiple content types in success responses\n const successTypes = response.types.success;\n const uniqueContentTypes = [\n ...new Set(successTypes.map((t) => t.contentType).filter(Boolean)),\n ];\n const hasMultipleContentTypes = uniqueContentTypes.length > 1;\n\n // For multiple content types, determine the default\n const defaultContentType = hasMultipleContentTypes\n ? getDefaultContentType(uniqueContentTypes)\n : (uniqueContentTypes[0] ?? 'application/json');\n const defaultType = hasMultipleContentTypes\n ? successTypes.find((t) => t.contentType === defaultContentType)\n : undefined;\n const defaultReturnType = defaultType?.value ?? dataType;\n\n const isModelType = dataType !== 'Blob' && dataType !== 'string';\n let functionName = operationName;\n if (isModelType && !hasMultipleContentTypes) {\n functionName += `<TData = ${dataType}>`;\n }\n\n let contentTypeOverloads = '';\n if (hasMultipleContentTypes && isRequestOptions) {\n const requiredProps = props.filter((p) => p.required && !p.default);\n const optionalProps = props.filter((p) => !p.required || p.default);\n\n contentTypeOverloads = successTypes\n .filter((t) => t.contentType)\n .map(({ contentType, value }) => {\n const requiredPart = requiredProps\n .map((p) => p.definition)\n .join(',\\n ');\n const acceptPart = `accept: '${contentType}'`;\n const optionalPart = optionalProps\n .map((p) => p.definition)\n .join(',\\n ');\n\n const allParams = [requiredPart, acceptPart, optionalPart]\n .filter(Boolean)\n .join(',\\n ');\n return `${operationName}(${allParams}, options?: HttpClientOptions): Observable<${value}>;`;\n })\n .join('\\n ');\n\n const requiredPart = requiredProps.map((p) => p.definition).join(',\\n ');\n const optionalPart = optionalProps.map((p) => p.definition).join(',\\n ');\n const allParams = [requiredPart, 'accept?: string', optionalPart]\n .filter(Boolean)\n .join(',\\n ');\n contentTypeOverloads += `\\n ${operationName}(${allParams}, options?: HttpClientOptions): Observable<${defaultReturnType}>;`;\n }\n\n const observeOverloads =\n isRequestOptions && !hasMultipleContentTypes\n ? `${functionName}(${propsDefinition} options?: HttpClientOptions & { observe?: 'body' }): Observable<${isModelType ? 'TData' : dataType}>;\n ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'events' }): Observable<HttpEvent<${isModelType ? 'TData' : dataType}>>;\n ${functionName}(${propsDefinition} options?: HttpClientOptions & { observe: 'response' }): Observable<AngularHttpResponse<${isModelType ? 'TData' : dataType}>>;`\n : '';\n\n const overloads = contentTypeOverloads || observeOverloads;\n\n if (hasMultipleContentTypes) {\n const requiredProps = props.filter((p) => p.required && !p.default);\n const optionalProps = props.filter((p) => !p.required || p.default);\n\n const requiredPart = requiredProps\n .map((p) => p.implementation)\n .join(',\\n ');\n const optionalPart = optionalProps\n .map((p) => p.implementation)\n .join(',\\n ');\n const allParams = [\n requiredPart,\n `accept: string = '${defaultContentType}'`,\n optionalPart,\n ]\n .filter(Boolean)\n .join(',\\n ');\n\n return ` ${overloads}\n ${operationName}(\n ${allParams},\n ${isRequestOptions ? 'options?: HttpClientOptions' : ''}\n ): Observable<any> {${bodyForm}\n if (accept.includes('json') || accept.includes('+json')) {\n return this.http.${verb}<any>(\\`${route}\\`, {\n ...options,\n responseType: 'json',\n headers: { Accept: accept, ...options?.headers },\n });\n } else if (accept.startsWith('text/') || accept.includes('xml')) {\n return this.http.${verb}(\\`${route}\\`, {\n ...options,\n responseType: 'text',\n headers: { Accept: accept, ...options?.headers },\n }) as any;\n } else {\n return this.http.${verb}(\\`${route}\\`, {\n ...options,\n responseType: 'blob',\n headers: { Accept: accept, ...options?.headers },\n }) as any;\n }\n }\n`;\n }\n\n return ` ${overloads}\n ${functionName}(\n ${toObjectString(props, 'implementation')} ${\n isRequestOptions ? `options?: HttpClientOptions & { observe?: any }` : ''\n }): Observable<any> {${bodyForm}\n return this.http.${verb}${isModelType ? '<TData>' : ''}(${options});\n }\n`;\n};\n\nexport const generateAngular: ClientBuilder = (verbOptions, options) => {\n const imports = generateVerbImports(verbOptions);\n const implementation = generateImplementation(verbOptions, options);\n\n return { implementation, imports };\n};\n\nconst angularClientBuilder: ClientGeneratorsBuilder = {\n client: generateAngular,\n header: generateAngularHeader,\n dependencies: getAngularDependencies,\n footer: generateAngularFooter,\n title: generateAngularTitle,\n};\n\nexport const builder = () => () => angularClientBuilder;\n\nexport default builder;\n"],"mappings":";;;AAsBA,MAAMA,uBAA8C;CAClD;EACE,SAAS;GACP;IAAE,MAAM;IAAc,QAAQ;IAAM;GACpC,EAAE,MAAM,eAAe;GACvB,EAAE,MAAM,cAAc;GACtB,EAAE,MAAM,eAAe;GACvB;IAAE,MAAM;IAAgB,OAAO;IAAuB;GACtD,EAAE,MAAM,aAAa;GACtB;EACD,YAAY;EACb;CACD;EACE,SAAS,CACP;GAAE,MAAM;GAAc,QAAQ;GAAM,EACpC;GAAE,MAAM;GAAU,QAAQ;GAAM,CACjC;EACD,YAAY;EACb;CACD;EACE,SAAS,CAAC;GAAE,MAAM;GAAc,QAAQ;GAAM,CAAC;EAC/C,YAAY;EACb;CACD;EACE,SAAS,CAAC,EAAE,MAAM,mBAAmB,CAAC;EACtC,YAAY;EACb;CACF;AAED,MAAM,qCAAqB,IAAI,KAAqB;AAEpD,MAAaC,+BACX;AAEF,MAAaC,wBAA4C,UAAU;AAEjE,QAAO,GAAG,OADO,SAAS,MAAM,CACN,CAAC;;AAG7B,MAAaC,yBAA8C,EACzD,OACA,kBACA,WACA,iBACA,gBACI;EAEJ,oBAAoB,CAAC,kBACjB;;;;;;;;;;;;;;;;;;KAmBA,GACL;;EAGC,oBAAoB,YAChB;;;;;;;cAQA,GACL;;cAGC,YACI,kBAAkB,UAAU,UAAU,GAAG,SAAS,UAAU,OAC5D,GACL;eACc,MAAM;;;AAIrB,MAAaC,yBAA8C,EACzD,qBACI;CACJ,IAAI,SAAS;AAEb,MAAK,MAAM,iBAAiB,eAC1B,KAAI,mBAAmB,IAAI,cAAc,CAIvC,WAAU,mBAAmB,IAAI,cAAc,GAAG;AAItD,QAAO;;AAGT,MAAM,0BACJ,EACE,SACA,aACA,eACA,UACA,SACA,MACA,OACA,MACA,UACA,UACA,gBACA,oBAEF,EAAE,OAAO,cACN;CACH,MAAM,mBAAmB,SAAS,mBAAmB;CACrD,MAAM,aAAa,CAAC,SAAS,SAAS;CACtC,MAAM,mBAAmB,SAAS,mBAAmB;CACrD,MAAM,+BACJ,CAAC,CAAC,QAAQ,OAAO,UAAU,iBAAiB;CAC9C,MAAM,WAAW,sCAAsC;EACrD;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,WAAW,SAAS,WAAW,WAAW;AAEhD,oBAAmB,IACjB,eACA,eAAe,OACb,cACD,CAAC,6BAA6B,SAAS,GACzC;AAED,KAAI,SAAS;EACX,MAAM,gBAAgB,sBAAsB;GAC1C;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,WAAW;GACX;GACD,CAAC;EAEF,MAAM,iBAAiB,mBACnB,8BACE,SAAS,gBACT,QAAQ,YACT,GACD;AAUJ,SAAO,IAAI,cAAc,WAAW,SAAS,UAP3C,QAAQ,gBAAgB,KAAK,aACzB,eAAe,OAAO,iBAAiB,CAAC,QACtC,IAAI,OAAO,OAAO,GAAG,YAAY,KAAK,aAAa,EACnD,OAAO,QAAQ,aAAa,GAAG,KAAK,WAAW,GAChD,GACD,eAAe,OAAO,iBAAiB,CAE8B,KACzE,oBAAoB,QAAQ,cACxB,mCAAmC,QAAQ,KAAK,KAChD,GACL,KAAK,SAAS;eACJ,QAAQ,KAAK;QACpB,cAAc;;QAEd,eAAe;;;;CAKrB,MAAM,UAAU,gBAAgB;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA,gBAAgB,SAAS;EACzB;EACA;EACA;EACA,yBAAyB,SAAS;EAClC,WAAW;EACX;EACA,WAAW;EACZ,CAAC;CAEF,MAAM,kBAAkB,eAAe,OAAO,aAAa;CAG3D,MAAM,eAAe,SAAS,MAAM;CACpC,MAAM,qBAAqB,CACzB,GAAG,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,CACnE;CACD,MAAM,0BAA0B,mBAAmB,SAAS;CAG5D,MAAM,qBAAqB,0BACvB,sBAAsB,mBAAmB,GACxC,mBAAmB,MAAM;CAI9B,MAAM,qBAHc,0BAChB,aAAa,MAAM,MAAM,EAAE,gBAAgB,mBAAmB,GAC9D,SACmC,SAAS;CAEhD,MAAM,cAAc,aAAa,UAAU,aAAa;CACxD,IAAI,eAAe;AACnB,KAAI,eAAe,CAAC,wBAClB,iBAAgB,YAAY,SAAS;CAGvC,IAAI,uBAAuB;AAC3B,KAAI,2BAA2B,kBAAkB;EAC/C,MAAM,gBAAgB,MAAM,QAAQ,MAAM,EAAE,YAAY,CAAC,EAAE,QAAQ;EACnE,MAAM,gBAAgB,MAAM,QAAQ,MAAM,CAAC,EAAE,YAAY,EAAE,QAAQ;AAEnE,yBAAuB,aACpB,QAAQ,MAAM,EAAE,YAAY,CAC5B,KAAK,EAAE,aAAa,YAAY;AAY/B,UAAO,GAAG,cAAc,GAHN;IARG,cAClB,KAAK,MAAM,EAAE,WAAW,CACxB,KAAK,UAAU;IACC,YAAY,YAAY;IACtB,cAClB,KAAK,MAAM,EAAE,WAAW,CACxB,KAAK,UAAU;IAEwC,CACvD,OAAO,QAAQ,CACf,KAAK,UAAU,CACmB,6CAA6C,MAAM;IACxF,CACD,KAAK,OAAO;EAIf,MAAM,YAAY;GAFG,cAAc,KAAK,MAAM,EAAE,WAAW,CAAC,KAAK,UAAU;GAE1C;GADZ,cAAc,KAAK,MAAM,EAAE,WAAW,CAAC,KAAK,UAAU;GACV,CAC9D,OAAO,QAAQ,CACf,KAAK,UAAU;AAClB,0BAAwB,OAAO,cAAc,GAAG,UAAU,6CAA6C,kBAAkB;;CAG3H,MAAM,mBACJ,oBAAoB,CAAC,0BACjB,GAAG,aAAa,GAAG,gBAAgB,mEAAmE,cAAc,UAAU,SAAS;GAC5I,aAAa,GAAG,gBAAgB,8EAA8E,cAAc,UAAU,SAAS;GAC/I,aAAa,GAAG,gBAAgB,0FAA0F,cAAc,UAAU,SAAS,OACtJ;CAEN,MAAM,YAAY,wBAAwB;AAE1C,KAAI,yBAAyB;EAC3B,MAAM,gBAAgB,MAAM,QAAQ,MAAM,EAAE,YAAY,CAAC,EAAE,QAAQ;EACnE,MAAM,gBAAgB,MAAM,QAAQ,MAAM,CAAC,EAAE,YAAY,EAAE,QAAQ;EAEnE,MAAM,eAAe,cAClB,KAAK,MAAM,EAAE,eAAe,CAC5B,KAAK,UAAU;EAClB,MAAM,eAAe,cAClB,KAAK,MAAM,EAAE,eAAe,CAC5B,KAAK,UAAU;AASlB,SAAO,IAAI,UAAU;IACrB,cAAc;MATI;GAChB;GACA,qBAAqB,mBAAmB;GACxC;GACD,CACE,OAAO,QAAQ,CACf,KAAK,UAAU,CAIN;MACV,mBAAmB,gCAAgC,GAAG;wBACpC,SAAS;;yBAER,KAAK,UAAU,MAAM;;;;;;yBAMrB,KAAK,KAAK,MAAM;;;;;;yBAMhB,KAAK,KAAK,MAAM;;;;;;;;;AAUvC,QAAO,IAAI,UAAU;IACnB,aAAa;MACX,eAAe,OAAO,iBAAiB,CAAC,GACxC,mBAAmB,oDAAoD,GACxE,sBAAsB,SAAS;uBACb,OAAO,cAAc,YAAY,GAAG,GAAG,QAAQ;;;;AAKtE,MAAaC,mBAAkC,aAAa,YAAY;CACtE,MAAM,UAAU,oBAAoB,YAAY;AAGhD,QAAO;EAAE,gBAFc,uBAAuB,aAAa,QAAQ;EAE1C;EAAS;;AAGpC,MAAMC,uBAAgD;CACpD,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,QAAQ;CACR,OAAO;CACR;AAED,MAAa,sBAAsB;AAEnC,kBAAe"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orval/angular",
3
- "version": "8.0.0-rc.3",
3
+ "version": "8.0.0-rc.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -22,13 +22,13 @@
22
22
  "nuke": "rimraf .turbo dist node_modules"
23
23
  },
24
24
  "dependencies": {
25
- "@orval/core": "8.0.0-rc.3"
25
+ "@orval/core": "8.0.0-rc.5"
26
26
  },
27
27
  "devDependencies": {
28
- "eslint": "9.39.1",
29
- "rimraf": "6.1.0",
30
- "tsdown": "0.16.4",
28
+ "eslint": "9.39.2",
29
+ "rimraf": "6.1.2",
30
+ "tsdown": "0.18.2",
31
31
  "typescript": "5.9.3"
32
32
  },
33
- "stableVersion": "8.0.0-rc.2"
33
+ "stableVersion": "8.0.0-rc.4"
34
34
  }