Commit graph

37314 commits

Author SHA1 Message Date
tmpln
38bb2bfeb6 fix(core): improve input writes migration in best effort mode
Currently, signal migration schematics in best effort mode doesn't do a very good job migrating input writes when there is a nested property access in templates.

In event handlers, no attempt is made to migrate a nested access in the left-hand-side of assignments or anything in their right-hand-side. E.g., nothing will happen here:

`(ngModelChange)="inputD.prop = $event + inputF"`.

Additionally, when a migration attempt is made, parentheses are often incorrectly placed on the parent, both in event handlers and two-way bindings:

`(ngModelChange)="inputC = $event"` is migrated to `(ngModelChange)="inputC = $event()"`.

`[(ngModel)]="inputB.prop.prop"` is migrated to `[(ngModel)]="inputB.prop().prop"`.
2026-05-08 12:33:43 +00:00
Kristiyan Kostadinov
c72ebcb1ad fix(core): allow service with factory on abstract classes
Some checks are pending
CI (push) / zone-js (push) Waiting to run
DevInfra / assistant_to_the_branch_manager (push) Waiting to run
CI (push) / lint (push) Waiting to run
CI (push) / devtools (push) Waiting to run
CI (push) / test (push) Waiting to run
CI (push) / integration-tests (push) Waiting to run
CI (push) / publish-snapshots (push) Waiting to run
CI (push) / adev (push) Waiting to run
CI (push) / vscode-ng-language-service (push) Waiting to run
CI (push) / adev-deploy (push) Blocked by required conditions
Update ADEV Cross Repo Docs / Update Cross Repo ADEV Docs (push) Waiting to run
Performance Tracking / list (push) Waiting to run
Performance Tracking / workflow (push) Blocked by required conditions
OpenSSF Scorecard / Scorecards analysis (push) Waiting to run
Fixes that setting a `@Service` with a `factory` on an abstract class was resulting in a compilation error.
2026-05-08 10:16:15 +02:00
Michael Small
89ee8a8162 docs: fix signal forms async validator typings
docs: add response types for form async `onSuccess`

docs: set defined fallback for async validator params

docs: replace `this.` w/`const`

docs: give fallback string for form async validators

docs: replace `onError` overwritten by `onSuccess`

docs: use `undefined!` for now w/async validators

chore: lint form's `async-operations.md`
2026-05-07 18:17:57 -06:00
SkyZeroZx
a0b998e293 docs(docs-infra): use signals & improve types
Use signals to avoid markForCheck.

Simplify takeUntilDestroyed usage by relying on implicit DestroyRef.

Improve type safety by typing inject(ElementRef).
2026-05-07 18:17:29 -06:00
SkyZeroZx
307723a352 docs: add documentation for de-duplicate host directives 2026-05-07 17:53:42 -06:00
Matthieu Riegler
a7dab601fa refactor(core): use the @Service decorator where possible.
A few bytes to win.
Added only on the services that don't rely on constructor DI.
2026-05-07 17:03:30 -06:00
Michael Small
7b4791f474 docs: add FormField/FormRoot imports + move comment w/backticks 2026-05-07 16:56:45 -06:00
Michael Small
44c0293a3e docs: fix applyWhenValue form example 2026-05-07 16:54:06 -06:00
Michael Small
0ef43c5ff3 docs: rename outdated validateTree example's model 2026-05-07 16:53:41 -06:00
Angular Robot
28e7bfaf77 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2026-05-07 16:51:57 -06:00
Andrew Scott
932a163cb6 refactor(compiler-cli): fix path normalization and trailing comments (#68454)
Ensure paths are normalized before comparison and key generation in tcb_adapter.ts to avoid failures on Windows.
Ensure a newline before appending imports in TypeCheckFile.render to prevent trailing comments from neutralizing them.

PR Close #68454
2026-05-07 15:42:33 -07:00
Andrew Scott
4f9c824dd9 feat(language-service): Typecheck templates which would require inline typecheck blocks (#68454)
This change updates the language service to generate TCBs for templates that would previously
have required inlining. The new strategy is to copy the original source and then do inlining
in the external TCB. This allows language features and type-checking in templates of non-exported
classes (such as test components) or classes with local, non exported dependencies.

PR Close #68454
2026-05-07 15:42:33 -07:00
Andrew Scott
7f0265e43a feat(language-service): compile non-exported classes if standalone (#68454)
Langauge service previously never compiled non-exported classes. This avoided issues
where test modules would cause diagnostic noise due to components appearing in
declarations of two modules, for example. This change updates the logic to ensure
non-exported, but standalone classes _are_ still compiled.

fixes #65515

PR Close #68454
2026-05-07 15:42:32 -07:00
Angular Robot
3ac11a5e02 build: update pnpm to v10.33.4
See associated pull request for more information.
2026-05-07 16:40:35 -06:00
Angular Robot
827781ea12 build: update all non-major dependencies
See associated pull request for more information.
2026-05-07 16:39:49 -06:00
Angular Robot
17d8be4a76 build: update bazel dependencies
See associated pull request for more information.
2026-05-07 16:37:18 -06:00
Alan Agius
60552a73e8 fix(platform-server): add allowedHosts option to renderModule and renderApplication
In server-side rendering (SSR) setups, passing request URLs directly to the lower-level rendering APIs `renderModule` or `renderApplication` can expose applications to Server-Side Request Forgery (SSRF) or Host Header Injection attacks via absolute-form request URLs.
To mitigate these vulnerabilities at the framework layer, this commit introduces the `allowedHosts` option to `PlatformConfig` (supporting exact hostnames, wildcards like `*.example.com`, or `*` to allow all).

During platform initialization inside `createServerPlatform`, the hostname of the request `url` is validated against the `allowedHosts` list. If the hostname is not authorized, bootstrap immediately throws a host validation error, preventing unauthorized rendering and silent SSRF bypasses.

Closes #68436
2026-05-07 16:30:03 -06:00
Angular Robot
3bf1b10bcf build: update all github actions
See associated pull request for more information.
2026-05-07 16:28:57 -06:00
Kristiyan Kostadinov
1f238ab567 fix(docs-infra): switch remaining adev services to @Service
Reworks all the remaining injectables in adev to use `@Service`.
2026-05-07 16:23:26 -06:00
Matthew Beck
b1699da827 test: remove invalid css that was causing issues with the postcss parser
These tests happened to use garbage "{c}" declaration lists which caused
the parser to choke. Given that we already have tests demonstrating
similar behavior and that's not what these tests were meant to
demonstrate, I've updated them to use empty declaration lists.
2026-05-07 16:20:16 -06:00
Alan Agius
5b421c61cd
fix(core): disallow event attribute bindings in host bindings unconditionally
Moves the event attribute validation check outside of `ngDevMode` in the `elementAttributeInternal` instruction to ensure that bindings to event attributes like `on*` are always blocked at runtime.
2026-05-07 16:19:22 -06:00
Andrew Scott
bc655d006f refactor(compiler): Update indexer API to be generic
Rather than requiring TS AST in the indexer API, this update makes it generic with adapters to provide necessary information. This allows other analysis pipelines that don't use TS AST to work with the indexer.
2026-05-07 16:16:59 -06:00
Kam
ed333c3992 docs: normalize product name casing across docs
Several user-facing docs, tooltips, and tutorial code samples used
non-canonical spellings of product names. This normalizes them to
the form each project uses for its own brand.
2026-05-07 16:09:44 -06:00
Alan Agius
d8e5514f30 docs: update Node.js version requirements in version reference table 2026-05-07 16:06:38 -06:00
Bhuvansh855
dc4b3172df docs(animations): improve grammar and clarity across animation guides 2026-05-07 16:03:41 -06:00
SUMIDA, Ippei
2fcfffbc7d docs: Update error display for password field in signal forms playground
Change error message display from paragraph to list format in signal forms playground.
2026-05-07 15:53:07 -06:00
Alan Agius
f1738b5032 fix(migrations): remove compiler import from safe optional chaining migration
Removes the @angular/compiler import from the safe optional chaining migration. This import is not needed as the compiler package import is side-effectful and has no functional use here.
2026-05-07 15:44:08 -06:00
Alex Rickabaugh
e3dc87cbd8 release: cut the zone.js-0.16.2 release 2026-05-06 16:44:48 -07:00
Alex Rickabaugh
853a91e928 docs: release notes for the v22.0.0-next.11 release 2026-05-06 16:31:53 -07:00
Alex Rickabaugh
b2c08dfead release: bump the next branch to v22.1.0-next.0 2026-05-06 16:31:53 -07:00
Alex Rickabaugh
8b3973aaad docs: release notes for the v21.2.12 release 2026-05-06 15:49:14 -07:00
Alex Rickabaugh
a02ac76866 docs: release notes for the v20.3.20 release 2026-05-06 15:30:20 -07:00
Douglas Parker
3b0ae5fef0 feat(core): add provideWebMcpTools
Some checks are pending
DevInfra / assistant_to_the_branch_manager (push) Waiting to run
This is an ergonomic wrapper around `declareWebMcpTool`, allowing a user to define multiple tools directly on an injector's providers, rather than needing to find an injection context.

Example:

```typescript
import {bootstrapApplication, provideWebMcpTools} from '@angular/core';

await bootstrapApplication(RootComp, {
  providers: [
    provideWebMcpTools([
      {
        name: 'hello',
        description: 'Says hello',
        inputSchema: {type: 'object', properties: {}},
        execute: async () => ({content: [{type: 'text', text: 'Hello, World!'}]});
      },
    ]),
  ],
});
```

The `execute` function is invoked in the injection context of the `Injector` it is provided to, meaning you can easily `inject` dependencies and invoke them.

This also works particularly well with route `providers` and `withExperimentalAutoCleanupInjectors`, registering the tools when the router is navigated to and then automatically unregistering them when navigating away. Note that `withExperimentalAutoCleanupInjectors` is required for unregistration to work.

```typescript
import {provideWebMcpTools} from '@angular/core';
import {provideRouter} from '@angular/router';

provideRouter(
  [
    {
      path: '',
      component: Home,
      providers: [
        provideWebMcpTools([
          {
            name: 'hello',
            description: 'Says hello',
            inputSchema: {type: 'object', properties: {}},
            execute: async () => ({content: [{type: 'text', text: 'Hello, World!'}]}),
          },
        ]),
      ],
    },
  ],
  withExperimentalAutoCleanupInjectors(),
);
```
2026-05-06 14:13:20 -07:00
Douglas Parker
77ec83782f refactor(core): run declareWebMcpTool callback in an injection context
This uses the injection context the tool is registered in for the `execute` callback and makes it a little more ergonomic to inject and use services in this context.
2026-05-06 14:13:20 -07:00
Douglas Parker
ef1810197b feat(core): export experimental declareWebMcpTool support
This exports `declareWebMcpTool`, a mechanism for registering WebMCP tools and tying them to Angular's `Injector` lifecycle. This function immediately registers the given tool and automatically unregisters it once the associated `Injector` is destroyed.

This exports the function and all transitively reachable types *except* for JSON Schema types as there are quite a lot and we don't want to couple to this particular implementation will likely be obsoleted by built-in types as the standard develops. If users want to leverage those, they should add their own dependency on `@mcp-b/webmcp-types`.
2026-05-06 14:13:20 -07:00
Douglas Parker
b2c0c91f8f refactor(core): implement declareWebMcpTool
This is a relatively light wrapper around `navigator.modelContext.registerTool` which ties tool registration to the lifecycle of an `Injector`. When the `Injector` is destroyed, the tool is automatically unregistered. This makes it easier to create WebMCP tools without having to worry about managing unregistration.

I went a little off-spec by providing the `AbortSignal` to the `execute` function. I suspect something like this will be added eventually and there are some early discussions of that, but AFAICT, this behavior is not defined yet so I'm making something up instead so the `execute` function can observe a cancellation based on the `Injector` being destroyed.

This uses `@mcp-b/webmcp-polyfill` for testing, as it provides a small `modelContextTesting` utility for listing and invoking WebMCP tools. Unfortunately it is slightly out of date of the current Chrome spec (it requires `modelContext.unregisterTool` to be called, whereas the spec recently removed this option and expects you to provide an `AbortSignal` to `registerTool`). My slightly hacky solution for the moment is to both trigger the `AbortSignal` and also call `unregisterTool` safely. In production, only the `AbortSignal` happens, but in testing the `unregisterTool` code path is used. Hopefully this will get smoothed out as the spec matures and `@mcp-b/webmcp-polyfill` updates over time.
2026-05-06 14:13:20 -07:00
Douglas Parker
5387e13b10 refactor(core): vendor @mcp-b/webmcp-types
This copies WebMCP types into `@angular/core` and redistributes them. Ideally this would just be a regular dependency, but we need to do this vendoring for API extractor to properly process the types, since they will inform `@angular/core` public API.

One downside of this approach is that the dependency is not visible in Intellisense, breaking type inference.
2026-05-06 14:13:20 -07:00
kirjs
043055f6de refactor(forms): support when consistently for maxDate and minDate validators
This commit updates maxDate and minDate to consistently check and apply the 'when' option for conditional validation.
2026-05-06 14:10:12 -07:00
kirjs
f9e2b8d902 refactor(forms): update API golden files for signal forms overloads
Regenerated public API golden files after adding overloads for hidden, disabled, and readonly.
2026-05-06 14:10:12 -07:00
kirjs
0806b2f02b refactor(forms): use overloads and JSDoc for deprecations
This commit removes runtime console warnings and uses TypeScript overloads with JSDoc @deprecated annotations to handle backward compatibility for conditional rules.
2026-05-06 14:10:12 -07:00
kirjs
3f3b85ca44 refactor(forms): regenerate API golden files for signal forms
Regenerated public API golden files after updating rules and validators to use 'when' parameter.
2026-05-06 14:10:12 -07:00
kirjs
7d9862f0be refactor(forms): support deprecated signatures for backward compatibility
This commit restores support for passing functions directly to hidden, disabled, and readonly rules, marking them as deprecated.
2026-05-06 14:10:12 -07:00
kirjs
df54e6a7b2 refactor(forms): use when consistently for conditional rules and validators
This commit updates the signal forms API to use a consistent 'when' parameter for conditional rules and validators, replacing direct function arguments.
2026-05-06 14:10:12 -07:00
Alex Rickabaugh
7745365910 feat(forms): graduate signal forms APIs to public API
Replaced `@experimental` tags with `@publicApi 22.0` across all Signal Forms APIs under `packages/forms/signals` to mark them as ready for general use in v22.

TAG=agy
CONV=0af6c644-225a-4212-a49a-5843d17ec638
2026-05-06 12:01:41 -07:00
Leon Senft
1f30aacbe5 refactor(forms): bind formatted date string to min/max for minDate/maxDate (#68001)
* Test that `minDate`/`maxDate` binds to `min`/`max` on date and time inputs
* Test that `min`/`max` attribute can be set directly on date and time inputs
* Relax type checker to allow `min`/`max` bindings on date and time inputs

PR Close #68001
2026-05-06 11:59:18 -07:00
Leon Senft
276c917b34 refactor(forms): add validation rules for date constraints (#68001)
- Added `minDate()` and `maxDate()` for validating constraints on `Date` inputs.
- `ReadonlyFieldState.min` and `.max` now return
  `Signal<NonNullable<TValue>`. This ensures that `min` and `max` inputs
  on custom controls can accept a reliable type (matching their value
  type).
- Made the `TWrite` type parameter of `MetadataKey` contravariant to
  properly indicate that it's writable.
- Added `LimitKey` as a convenience type for defining validation limit
  metadata (e.g. `MAX_NUMBER`, `MIN_DATE`).
- Added `LimitSelectionKey` which can be used to bind a `LimitKey` with
  value-specific aggregation logic, to a generic metadata key (e.g. use
  `MAX_NUMBER` to aggregate numbers for `MAX`).

PR Close #68001
2026-05-06 11:59:18 -07:00
Leon Senft
592a12d6c9 refactor(forms): remove string support from min and max validation rules (#68001)
The `min` and `max` validation rules previously handled `string` values
to accommodate numbers bound to text inputs. However, this is no longer
necessary as the control binding itself handles the conversion.

This change removes string support from these rules, simplifying the
types to `number | null`. The validation logic has been updated to use
concrete checks (`value === null || Number.isNaN(value)`) to ensure safe
TypeScript narrowing.

Associated tests have been updated to:
- Remove string-specific validation checks.
- Add coverage for text input bindings.
- Add coverage for empty input handling (standard behavior where empty
  sets model to null and skips validation).

BREAKING CHANGE: `min` and `max` validation rules no longer support
string values. Bound values must be numbers or null.

PR Close #68001
2026-05-06 11:59:18 -07:00
Alex Rickabaugh
849dba6c65 fix(forms): implement custom control reset propagation
Introduce a highly decoupled FVC and CVA custom control reset mechanism, and implement the framework-wide automatic `transformedValue` and native controls clearing bridge for both new Signal Forms and legacy forms (Template-driven and Reactive).

1. Custom Control Reset Propagation (Bug #2):
- Establish agnostic custom control resetting via `FormFieldBindingOptions.reset` in `FormField`.
- Ensure that `FieldNode.reset()` unconditionally triggers `writeValue` updates on CVA custom controls.
- Protect against duplicate writes during subsequent change detection updates in `control_cva.ts` by verifying and tracking previous written values in the local bindings cache.

2. Unified Framework-wide FormControl Integration:
- Introduce a monorepo-wide private InjectionToken `ɵFORM_CONTROL_INTEGRATION` and `ɵFormControlIntegration` interface to act as the single, decoupled bridge for hooking up FVC parse errors and receiving control resets across both Signal and legacy forms architectures.
- Simplify Signal Forms: make `FormField` implements `ɵFormControlIntegration` directly, removing the intermediate context object and reducing DI boilerplate down to a clean `useExisting: FormField` provider. Triggers the `onReset` callback directly inside `FormField.reset()`.
- Upgrade Legacy Forms: `NG_CONTROL_INTEGRATION_PROVIDER` provides the renamed token. `NgControl` handles the event subscription internally (`set onReset(callback)`) to recursively listen to `control.events` (`FormResetEvent`) lazily only when assigned, resolving all `FormControl` swapping timing and lifecycle cleanup races automatically.

3. Automatic `transformedValue` and Native Controls Utility Clearing:
- Make `Parser.reset()` method required in the interface for a cleaner and non-defensive execution.
- Wire `transformedValue` into the new integration token `ɵFORM_CONTROL_INTEGRATION` to clear validation parsing states on resets.
- Lazily resets the UI-facing `rawValue` linked signal utilizing the original native `linkedSignal.set` callback (`originalSet`), correctly bypassing the UI-to-model parser loopback and preventing redundant model writes during `reset()`.
- Wire up Native Controls (`control_native.ts\Device`): Hook `parent.onReset` inside native element creation to automatically trigger the native `parser.reset()` and force DOM writes (`setNativeControlValue`) back down to the DOM input value during resets, ensuring native elements with pending parsing validation errors are successfully cleared and synced on form resets.

TAG=agy
CONV=8b4cee1e-2117-42a4-b242-c8ec7bf01752
2026-05-06 10:45:40 -07:00
Suraj Yadav
68c3abbe09 fix(forms): synchronize controls with the model on reset
Synchronize `controlValue` with the model `value` following `reset()`. This
ensures the UI will reflect the form model in cases where a control had a
pending change–delayed by debouncing–at the time it was reset.
2026-05-06 10:45:40 -07:00
Matthieu Riegler
5a7c1e62dc
feat(core): add ability to cache resources for SSR
This commit adds a `transferCacheKey` option to enable easy caching for `resource`/ `rxResource`.
2026-05-06 09:57:49 -07:00