Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e000cf7
feat(angular): add httpResource support
Feb 8, 2026
5a291a9
feat(samples/angular): add httpResource demo
Feb 8, 2026
0665317
chore(lint): expand lint tooling
Feb 8, 2026
d60eccd
feat(angular): expand httpResource zod support
Feb 8, 2026
ecf6a2a
fix(mock): normalize MSW delay handling
Feb 8, 2026
3682f86
fix(orval): clean schema dir with object paths
Feb 8, 2026
0dc8fad
chore: reorganize yarn catalogs
Feb 8, 2026
f7a34c9
chore: update vscode markdown formatter
Feb 8, 2026
5cbc72c
feat(angular): add httpResource support
Feb 8, 2026
08d7aea
feat(samples/angular): add httpResource demo
Feb 8, 2026
e0dc4f4
chore(lint): expand lint tooling
Feb 8, 2026
9ebdb94
feat(angular): expand httpResource zod support
Feb 8, 2026
d8f7d45
fix(mock): normalize MSW delay handling
Feb 8, 2026
6425cb6
fix(orval): clean schema dir with object paths
Feb 8, 2026
4f34b33
chore: reorganize yarn catalogs
Feb 8, 2026
ef1c58c
chore: update vscode markdown formatter
Feb 8, 2026
37d0c94
fix(angular): address PR review feedback
Feb 8, 2026
35b1bf9
Merge remote-tracking branch 'refs/remotes/origin/feat/add-angular-ht…
Feb 8, 2026
8e7fc3e
fix(query): align angular mutation callbacks
Feb 8, 2026
065dbb7
chore: align local lint script with CI by excluding unready packages …
froggy1014 Feb 8, 2026
71d5e2c
chore(lint): expand lint tooling
Feb 8, 2026
0179603
chore: reorganize yarn catalogs
Feb 8, 2026
2367fd6
chore: update vscode markdown formatter
Feb 8, 2026
97341c8
feat(angular): add httpResource support
Feb 8, 2026
15ec117
feat(samples/angular): add httpResource demo
Feb 8, 2026
b2c5910
feat(angular): expand httpResource zod support
Feb 8, 2026
d418b52
fix(angular): address PR review feedback
Feb 8, 2026
e810b7d
chore: limit feature scope
Feb 8, 2026
9c5cac2
chore: add angular-app lint config
Feb 8, 2026
2ee7776
build(vscode): revert adding prettier for markdown
Feb 9, 2026
689630d
chore: revert out-of-scope changes
Feb 9, 2026
e8745b8
Merge branch 'pr-angular-httpresource'
Feb 9, 2026
b30c757
build(deps): remove catalogs
Feb 9, 2026
7dd1dd1
chore(samples): revert lint command
Feb 9, 2026
48836b7
chore(deps): use typescript 5.9.3
Feb 9, 2026
0bbe8b1
chore(deps): revert and fix dependencies
Feb 9, 2026
4d76532
fix(query): align angular mutation onSuccess signature
Feb 9, 2026
ed64d7c
chore(mock): revert msw fixes
Feb 9, 2026
f8e8f67
chore: revert out of scope package updates
Feb 9, 2026
66f353e
chore(deps): update catalog for angular
Feb 9, 2026
35724d1
chore(samples/angular-app): fix esling.config merge conflicts
Feb 9, 2026
cde5d29
Merge remote-tracking branch 'origin/master' into feat/add-angular-ht…
Feb 10, 2026
7cf237c
Merge remote-tracking branch 'origin/master' into feat/add-angular-ht…
Feb 10, 2026
3abf026
docs(angular): correct spelling of "Restfull" to "Restful" in README.md
Feb 10, 2026
046eebe
fix(test): repair package-json catalog mocks
Feb 10, 2026
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
},
"[yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
34 changes: 23 additions & 11 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ enableScripts: false
npmPublishAccess: public
npmRegistryServer: https://registry.npmjs.org

# https://yarnpkg.com/features/catalogs
catalog:
eslint: 9.39.2
'@eslint/js': 9.39.2
Expand All @@ -23,18 +22,31 @@ catalog:
'@types/node': 22.18.12
'@scalar/openapi-types': 0.5.3

# https://yarnpkg.com/features/catalogs
# using named catalogs to align packages in /tests with /samples
catalogs:
angular:
# Runtime packages kept in sync (https://github.com/angular/angular/blob/main/tools/bazel/npm_packages.bzl)
'@angular/core': 20.3.16
'@angular/common': 20.3.16
'@angular/compiler': 20.3.16
'@angular/compiler-cli': 20.3.16
'@angular/animations': 20.3.16
'@angular/platform-browser': 20.3.16
'@angular/forms': 20.3.16
'@angular/router': 20.3.16
'@angular/core': 21.1.0
'@angular/common': 21.1.0
'@angular/compiler': 21.1.0
'@angular/compiler-cli': 21.1.0
'@angular/animations': 21.1.0
'@angular/platform-browser': 21.1.0
'@angular/forms': 21.1.0
'@angular/router': 21.1.0
# Build tooling uses last available patch
'@angular/build': 20.3.14
'@angular/cli': 20.3.14
'@angular/build': 21.1.0
'@angular/cli': 21.1.0
# Linting (Angular ESLint)
'@angular-eslint/builder': 21.1.0
'@angular-eslint/eslint-plugin': 21.1.0
'@angular-eslint/eslint-plugin-template': 21.1.0
'@angular-eslint/template-parser': 21.1.0
# Angular related
'@tanstack/angular-query-experimental': 5.62.7
'@testing-library/angular': 19.0.0
build-tools:
tslib: 2.8.1
tooling:
rxjs: 7.8.2
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ corepack enable

- **`yarn build`** - Build the project and make changes available to the workspace. Run this after making code changes to compile TypeScript and prepare the project for use.

### Lint Scripts

- **`yarn lint`** - Run lint checks across all packages.

- **`yarn lint:samples`** - Run lint checks inside the samples workspaces.

- **`yarn lint:generated`** - Lint generated fixtures in `tests/generated`.

### Test Scripts

- **`yarn test`** - Run unit tests in all packages.
Expand All @@ -97,9 +105,11 @@ A typical development workflow would be:
1. Make your code changes
2. Run `yarn build` to compile your changes
3. Run `yarn test` to ensure unit tests pass
4. Run `yarn update-samples` to regenerate sample outputs
5. Run `yarn test:samples` to verify samples work correctly
6. Run `yarn test:cli` to validate TypeScript compilation
4. (Optional) Run `yarn lint` to validate packages
5. (Optional) Run `yarn lint:samples` and `yarn lint:generated` to validate generated outputs
6. Run `yarn update-samples` to regenerate sample outputs
7. Run `yarn test:samples` to verify samples work correctly
8. Run `yarn test:cli` to validate TypeScript compilation

If you encounter issues or want to start completely fresh:

Expand Down
109 changes: 100 additions & 9 deletions docs/content/docs/guides/angular.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Angular
description: Generate Angular services with HttpClient from OpenAPI
description: Generate Angular services with HttpClient and httpResource functions from OpenAPI
---

Generate fully typed Angular services using HttpClient from your OpenAPI specification.
Generate fully typed Angular services using HttpClient or signal-first `httpResource` functions from your OpenAPI specification.

## Configuration

Expand All @@ -30,20 +30,111 @@ export default defineConfig({

## Generated Output

The Angular client generates two classes:
When using the default HttpClient output, the Angular client generates two classes:

1. **Abstract class** — Contains the service definition
2. **Service class** — Contains the implementation

Add the service to your module's providers to use it:
Register the service via DI (standalone or module-based apps both work):

```ts title="app.config.ts"
import { provideHttpClient } from '@angular/common/http';
import { ApplicationConfig } from '@angular/core';

```ts title="app.module.ts"
import { PetstoreService } from './api/petstore';

@NgModule({
providers: [PetstoreService],
})
export class AppModule {}
export const appConfig: ApplicationConfig = {
providers: [provideHttpClient(), PetstoreService],
};
```

If you use `httpResource`, Orval also generates signal-first resource functions
for eligible operations while keeping HttpClient methods for requests that need
explicit bodies or request options.

## httpResource Output (Angular v19.2+)

Enable the experimental `httpResource` client via `override.angular.client`:

```ts title="orval.config.ts"
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
output: {
mode: 'tags-split',
target: 'src/api/http-resource/petstore.ts',
schemas: 'src/api/model',
client: 'angular',
override: {
angular: {
client: 'httpResource',
},
},
},
input: {
target: './petstore.yaml',
},
},
});
```

Generated resource functions use signals and return `HttpResourceRef<T>`:

```ts title="pets.service.ts"
export function showPetByIdResource(
petId: Signal<string>,
): HttpResourceRef<Pet | undefined> {
return httpResource<Pet>(() => `/pets/${petId()}`);
}
```

## httpResource + Zod Runtime Validation

When `schemas.type` is set to `zod`, Orval automatically adds
`{ parse: <ZodSchema>.parse }` for JSON responses in httpResource output. This
validates responses at runtime before they reach your component.

> [!NOTE]
> Zod is a runtime dependency when you enable `schemas.type: 'zod'`.
> Make sure your app installs `zod` (for example, `zod` in `dependencies`).

```ts title="orval.config.ts"
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
output: {
mode: 'tags-split',
target: 'src/api/http-resource-zod/petstore.ts',
schemas: {
type: 'zod',
path: 'src/api/model-zod',
},
client: 'angular',
override: {
angular: {
client: 'httpResource',
runtimeValidation: true,
},
},
},
input: {
target: './petstore.yaml',
},
},
});
```

If you need to disable automatic Zod parsing, set `runtimeValidation: false`:

```ts title="orval.config.ts"
override: {
angular: {
client: 'httpResource',
runtimeValidation: false,
},
},
```

## Setting the Backend URL
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"test:ci": "CI=true yarn test && yarn test:cli && yarn test:samples",
"lint": "turbo run lint --filter='./packages/*' --filter=!@orval/mock --filter=!@orval/core --filter=!@orval/zod --filter=!@orval/solid-start",
"lint:samples": "turbo run lint --filter='./samples/**'",
"lint:generated": "turbo run lint:generated --filter='./tests'",
"dev": "turbo run dev --filter='./packages/*'",
"clean": "rimraf .turbo",
"clean:all": "yarn workspaces foreach -A run clean",
Expand Down
15 changes: 7 additions & 8 deletions packages/angular/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
# Orval Angular

[![npm version](https://badge.fury.io/js/orval.svg)](https://badge.fury.io/js/orval)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![tests](https://github.com/orval-labs/orval/actions/workflows/tests.yaml/badge.svg)](https://github.com/orval-labs/orval/actions/workflows/tests.yaml)

<p align="center">
<img src="./logo/orval-logo-horizontal.svg?raw=true" width="500" height="160" alt="orval - Restfull Client Generator" />
</p>
<h1 align="center">
Visit <a href="https://orval.dev" target="_blank">orval.dev</a> for docs, guides, API and beer!
</h1>
![orval - Restful Client Generator](./logo/orval-logo-horizontal.svg?raw=true)

Visit [orval.dev](https://orval.dev) for docs, guides, API and beer!

### Code Generation
## Code Generation

`orval` generates type-safe JS clients (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in `yaml` or `json` formats.

`Generate`, `valid`, `cache` and `mock` in your React, Vue, Svelte and Angular applications all with your OpenAPI specification.

### Samples
## Samples

You can find below some samples

Expand Down
52 changes: 52 additions & 0 deletions packages/angular/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { GeneratorDependency } from '@orval/core';

export const ANGULAR_HTTP_CLIENT_DEPENDENCIES = [
{
exports: [
{ name: 'HttpClient', values: true },
{ name: 'HttpHeaders' },
{ name: 'HttpParams' },
{ name: 'HttpContext' },
{ name: 'HttpResponse', alias: 'AngularHttpResponse' }, // alias to prevent naming conflict with msw
{ name: 'HttpEvent' },
],
dependency: '@angular/common/http',
},
{
exports: [
{ name: 'Injectable', values: true },
{ name: 'inject', values: true },
],
dependency: '@angular/core',
},
{
exports: [{ name: 'Observable', values: true }],
dependency: 'rxjs',
},
{
exports: [{ name: 'DeepNonNullable' }],
dependency: '@orval/core',
},
] as const satisfies readonly GeneratorDependency[];

export const ANGULAR_HTTP_RESOURCE_DEPENDENCIES = [
{
exports: [
{ name: 'httpResource', values: true },
{ name: 'HttpResourceRef' },
{ name: 'HttpResourceRequest' },
{ name: 'HttpHeaders' },
{ name: 'HttpParams' },
{ name: 'HttpContext' },
],
dependency: '@angular/common/http',
},
{
exports: [{ name: 'Signal', values: true }, { name: 'ResourceStatus' }],
dependency: '@angular/core',
},
{
exports: [{ name: 'DeepNonNullable' }],
dependency: '@orval/core',
},
] as const satisfies readonly GeneratorDependency[];
Loading
Loading