15434 Commits

Author SHA1 Message Date
Matthieu Riegler ab18f5ff0b refactor(core): cleanup Meta service
The service had a rather old implementation. This is mostly a cleanup.

(cherry picked from commit c0eaaedef3)
2026-07-08 11:23:58 -07:00
volkanfilazi eca3395019 removed console log
(cherry picked from commit 8e8c5524bb)
2026-07-08 11:23:05 -07:00
volkanfilazi 171669f7b2 fix(forms/signals): make extractValue reactive for compat AbstractControl values
(cherry picked from commit b542302a23)
2026-07-08 11:23:05 -07:00
Matthieu Riegler ad3693f44f docs(forms): add jsdoc for ReadonlyFieldState
(cherry picked from commit d93e922517)
2026-07-08 10:45:36 -07:00
SkyZeroZx 748faa4f95 docs(docs-infra): Add build-time validation for API and guide links using route manifest
Adds build-time validation to catch broken, stale, or miscased internal documentation links in both JSDoc and markdown, including `/api/` and `/guide/` URLs and their fragments. Updates the documentation pipeline to share the canonical route manifest, ensuring that all references are checked against the current navigation structure.

(cherry picked from commit c1829f6d7c)
2026-07-08 10:24:51 -07:00
P4 534fe81a89 fix(compiler-cli): apply debugName transform to required signal queries
Transform assumed `.required` functions always take options as the first argument.
This is true for `input` and `model`, but not for `viewChild` and `contentChild`,
which take the same arguments as non-required versions.

Change the code to put options for signal queries in the right position,
causing debugName to be correctly generated for signal queries.

(cherry picked from commit eb2a8ff63f)
2026-07-07 11:05:28 -07:00
Cameron Smick c91a951817 refactor(core): move devtools ai tool definition types to primitives
Extract the AI tool definition interfaces from the core debug module to the devtools primitives module. This relocates ToolDefinition, ToolGroup, and DevtoolsToolDiscoveryEvent to the primitives folder, exposing them cleanly via "export type" in the devtools entry point, improving module organization and readability.

(cherry picked from commit bf6dba878e)
2026-07-07 10:18:10 -07:00
rootvector2 8e6d7f7190 fix(router): use safe hasOwnProperty when parsing query params
`parseQueryParam` and the AngularJS-compat `parseKeyValue` accumulate query params into a plain object and check key presence with `obj.hasOwnProperty`, so a `hasOwnProperty` query key clobbers the method and the next lookup throws `TypeError`. Switch both to `Object.hasOwn`, which can't be shadowed by a query key.

(cherry picked from commit e5c37f21de)
2026-07-07 10:09:38 -07:00
cexbrayat d4a926a762 fix(migrations): remove stale model import in model-output migration
Remove the model import after migrating all model() usages in a file.

(cherry picked from commit fbb705e6fd)
2026-07-07 10:08:48 -07:00
arturovt f5e69de1e0 refactor(compiler-cli): use BindingType enum check in suffix-not-supported extended diagnostic
Replaces the `node.keySpan.toString().startsWith('attr.')` string allocation in the `suffixNotSupported` extended template check with an O(1) `node.type === BindingType.Attribute` enum comparison.

The diagnostic message string is also extracted to a module-level constant so it is created once at module load time instead of on every diagnostic emit.

Additionally, this change adds missing test coverage for the `.%` and `.em` suffixes, as well as for a plain `attr.` binding without a style suffix.

Measured with a 100-iteration microbenchmark before and after the change (MacBook Pro 2018, Intel CPU):

```ts
const start = performance.now();
for (let i = 0; i < 100; i++) {
  new ExtendedTemplateCheckerImpl(templateTypeChecker, program.getTypeChecker(),
    [suffixNotSupportedFactory], {}).getDiagnosticsForComponent(component);
}
console.log((performance.now() - start) / 100, 'ms/iter');
```

Before: `~0.24 ms/iter`
After: `~0.14 ms/iter` (~40% faster)
(cherry picked from commit ab618bdc0f)
2026-07-07 10:05:10 -07:00
cexbrayat 3b08201bfb fix(compiler-cli): detect uninvoked signals in bound expressions using ternary
Extend the interpolated signal extended diagnostic to inspect ternary-bound expressions and report uninvoked signal reads in bound bindings.

```
<div [style.width]="width() ? 1 : width"></div>
```

where the false branch should invoke the signal as `width()`.

(cherry picked from commit eac363e92e)
2026-07-07 10:01:55 -07:00
SkyZeroZx 0a6af1496b fix(migrations): preserve transitive NgModule references when pruning
avoids unintended removal of indirectly required modules

Fixes #62865

(cherry picked from commit 0a5a2b768c)
2026-07-07 10:01:17 -07:00
arturovt 3ac3753cd9 refactor(forms): avoid unnecessary Set allocation in maybeRemoveStaleArrayFields
Three small, behavior-neutral cleanups to maybeRemoveStaleArrayFields:

1. Avoid allocating an empty Set when prevData.byTrackingKey is
   undefined. new Set(undefined) previously created an unused empty
   Set on every call for parents with no tracking keys.

2. Guard the per-element tracking-key check on `oldTracking` being
   defined, skipping the isObject/hasOwn check entirely when there's
   nothing to track.

3. Replace childValue.hasOwnProperty(identitySymbol) with
   Object.hasOwn(childValue, identitySymbol). hasOwnProperty throws
   on null-prototype array elements (Object.create(null)), which
   would crash computeChildrenMap. Object.hasOwn is null-prototype-safe
   and preserves "own property" semantics (does not match inherited
   identitySymbol values).

4. Replace `data.byTrackingKey?.delete(id)` with
   `data.byTrackingKey!.delete(id)`. The optional chaining was dead:
   if oldTracking.size > 0, prevData.byTrackingKey (and therefore
   data.byTrackingKey, same Map reference via the spread) is always
   defined. The `?.` masked this invariant; `!` documents it and
   would surface a runtime error instead of a silent no-op if the
   invariant is ever violated.

Verified via performance.mark/measure instrumented directly inside
the function (count=1 call for a single-field edit in both cases).
Total duration dropped from ~0.7ms to ~0.1ms, consistent with the
avoided Set allocation in (1) and (2).

(cherry picked from commit 73ab88e65b)
2026-07-07 09:51:48 -07:00
Shuaib Hasan Akib 45caa92e2a refactor(core): remove unused utility functions
Remove `isIterable` from `util/iterable.ts` and
`newTrustedFunctionForDev` from `util/security/trusted_types.ts`
as they are no longer referenced anywhere in the codebase.

(cherry picked from commit 01bb0a2f28)
2026-07-07 09:48:11 -07:00
arturovt 97197786b3 docs: add NG05200 error reference page for SANITIZATION_UNSAFE_SCRIPT
Adds a reference page for `NG05200`, thrown by `DomSanitizer` when a value is bound to a `<script>` element without being marked trusted via `bypassSecurityTrustScript`. Covers why Angular rejects script content outright, how to reproduce the error, the escape hatch, and the XSS caveat.

(cherry picked from commit 806a3ada26)
2026-07-07 09:09:53 -07:00
Matthieu Riegler fd4ddcafed fix(compiler): use regular optional chaining expression for safe function calls in TCBs
Optional return types should not report non-nullable optional chaning on function calls.

fixes #69609

(cherry picked from commit 997b772f28)
2026-07-06 14:02:44 -07:00
SkyZeroZx 4d2133ec43 test(router): Update tests to use currentNavigation()
Updates router integration tests to use the `currentNavigation()` method instead of deprecated `getCurrentNavigation`.

Also replaces direct `setTimeout` calls with the `timeout()` utility function.

(cherry picked from commit d9639201b3)
2026-07-06 14:01:15 -07:00
Shuaib Hasan Akib c1a951aac3 refactor(forms): improve type safety of RadioControlRegistry._accessors
Replace `any[]` with `[NgControl, RadioControlValueAccessor][]` for the
private `_accessors` field in `RadioControlRegistry`. This aligns the
field type with how it is used in `add()`, `remove()`, `select()`, and
`_isSameGroup()`, which already typed its parameter as
`[NgControl, RadioControlValueAccessor]`.

(cherry picked from commit 0285f558f9)
2026-07-06 13:59:21 -07:00
Matthieu Riegler f03639cfd4 docs: correct docs about the chain behavior.
Even if the chained resource has a value, it might throw an error.

fixes #69330

(cherry picked from commit 5ad937be5e)
2026-07-06 13:37:27 -07:00
SkyZeroZx 8cedaecca8 docs: add @see references to Signal Forms
(cherry picked from commit bbbcf8fc7f)
2026-07-06 13:35:24 -07:00
arshsmith1 c238bd2ad7 fix(router): handle outlet named __proto__ in segment group maps
Outlet maps are keyed by names read verbatim from the url, so a name like
`__proto__` (e.g. `/one(__proto__:two)`) is assigned through the inherited
`__proto__` setter instead of creating an outlet. This drops the outlet and
mutates the map's prototype, and throws under Node's `--disable-proto=throw`.

Build these outlet maps with `Object.create(null)` so `__proto__` is treated as
an ordinary key. Covers `parseParens` and `squashSegmentGroup` in url_tree.ts,
`createSegmentGroup` in apply_redirects.ts, and `replaceSegment` and
`updateSegmentGroupChildren` in create_url_tree.ts.

(cherry picked from commit cbbb1d8ba1)
2026-07-06 13:34:08 -07:00
Shuaib Hasan Akib ca13b42e7c fix(router): fix malformed jsdoc comment for RouterLinkWithHref export
The export statement was incorrectly placed inside the JSDoc comment block,
and there was a stray text fragment "nstead." from the deprecation message.
This moves the export statement outside the comment and removes the stray text.

(cherry picked from commit a74801c59c)
2026-06-30 17:59:40 -07:00
arturovt eb8fb9fe58 fix(common): use Object.hasOwn in I18nSelectPipe to handle null-prototype and shadowed mappings
`I18nSelectPipe.transform()` called `mapping.hasOwnProperty()` directly,
which fails in two edge cases:

- Mappings created with `Object.create(null)` have no prototype and
  therefore no `hasOwnProperty` method, causing a TypeError at runtime.
- Mappings where a key literally named `hasOwnProperty` shadows the
  built-in method return incorrect results silently.

Replace both call sites with `Object.hasOwn(mapping, key)`, which
delegates through `Object` directly and is immune to both issues.

Add two regression tests that demonstrate the broken behaviour before
the fix and pass after it.

(cherry picked from commit 311aff05aa)
2026-06-30 17:46:41 -07:00
SkyZeroZx ced0180b06 fix(core): reject dynamic script host elements
The previous fix for GHSA-692r-grfm-v8x7 was incomplete because it rejected script tags only when locating an explicit host element. Dynamic component instantiation can also infer the host element from the component selector.

Move the script-host rejection to the point where ComponentFactory has resolved the host element for either path, so createComponent rejects script hosts consistently.

(cherry picked from commit d7f70616a0)
2026-06-30 17:29:41 -07:00
Andrew Scott c3be83cfe1 refactor(core): allow AnimationClassBindingFn to return undefined or null
The AnimationClassBindingFn type was too restrictive, only allowing `string | string[]`. However, the runtime (`getClassListFromValue`) safely handles `undefined` and `null` values by treating them as no animation.

This change updates the type to allow `undefined` and `null`, which is consistent with other class/style bindings in Angular and avoids requiring workarounds (like empty strings) in host bindings.

Added a compliance test case to verify that `[animate.enter]` with a potentially `undefined` value compiles correctly.

(cherry picked from commit a7bde662c3)
2026-06-30 17:28:04 -07:00
Alex Rickabaugh af7edd90ca Revert "fix(compiler-cli): include toSignal in debugName transform"
This reverts commit 165995285c. Reason: breaking
in g3 (ngDevMode not defined)

(cherry picked from commit a5f1b20373)
2026-06-30 13:24:21 -07:00
Matthieu Riegler b5ea3408ce refactor(compiler): remove visitAttributeComment
In #69463 we forgot to rename the visitor method after renaming the node class

(cherry picked from commit 74803c75cd)
2026-06-29 16:00:07 -07:00
Paweł Maniecki baf09a9939 fix(compiler-cli): include toSignal in debugName transform
the toSignal function received a debugName option in 0812ac3bec,
but was not covered by the signalMetadataTransform which sets the debugName in dev mode
automatically.

(cherry picked from commit 165995285c)
2026-06-29 14:32:22 -07:00
tmpln e598dc843f 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"`.

(cherry picked from commit 74638cab84)
2026-06-26 10:31:01 -07:00
aparziale fd37f09f37 fix(migrations): resolve migration failure when tsconfig specifies rootDir
When `rootDir` was set in a project's tsconfig (e.g. `rootDir: "src"`),
tsurge-based migrations would fail because `projectRoot` was derived from
`rootDir`, causing `rootRelativePath` to be computed relative to `src/`
instead of the workspace root. This produced paths like `app/app.ts`
instead of `src/app/app.ts`, which the DevKit tree could not resolve.

Fix by overriding `info.projectRoot` to `absoluteFrom(info.program.getCurrentDirectory())`
immediately after program creation, ensuring workspace-relative paths are
used for all tree updates.

(cherry picked from commit 26b0c719ef)
2026-06-26 09:14:52 -07:00
kirjs f4f7f3755c fix(compiler): remove unused import breaking CI in 22.0.x
The import of createContentBlock from ./r3_content_blocks was erroneously included in a cherry-pick but the file does not exist in this branch.
2026-06-25 06:59:05 -04:00
JoostK f90c20df40 fix(compiler): account for NgModule dependencies in JIT-compiled partial declarations
When partial declarations are not preprocessed to AOT by the linker, the `ngDeclareComponent`
call causes them to be compiled ad-hoc. In this mode, NgModule imports in standalone components
would be dropped, deviating from the linker. This commit changes the ad-hoc compilation of
component declarations to pass the NgModule imports along just like the linker does.

Fixes #69451

(cherry picked from commit ecd047578e)
2026-06-24 14:46:48 -04:00
Matthieu Riegler 489d1707d7 refactor(compiler): desable the legacy template syntax
This disables the legacy `bind`, `bindon-`, `on-`, `let-` `ref-` syntax in g3 ONLY.
This is mostly to evaluate the blast radius

(cherry picked from commit f9c4b71488)
2026-06-24 14:35:17 -04:00
Matthieu Riegler 01d58d7ad7 refactor(core): Tree shake the SimpleChanges & co.
Any application that doesn't use the `ngOnChanges` hook shouldn't pull its code.

(cherry picked from commit 4744bab38e)
2026-06-24 13:04:40 -04:00
Matthieu Riegler 2353bf22a5 refactor(forms): widen AsyncValidatorOptions.factory
This is to accept `Resource` and not only `ResourceRef`.

fixes #69443

(cherry picked from commit 63c7ac325d)
2026-06-24 13:03:41 -04:00
arturovt b0569fdb3f fix(zone.js): harden zoneSymbolEventNames and patches against __proto__ key
Initialize `zoneSymbolEventNames` and `patches` with `Object.create(null)` instead of `{}`.

This is a hardening change rather than a fix for an exploitable vulnerability. Calling `addEventListener('__proto__', fn)` is not directly attacker-controlled; its presence already implies an application bug. However, if such a call does occur, the current implementation can behave unexpectedly depending on the environment.

For `zoneSymbolEventNames`, accessing `zoneSymbolEventNames['__proto__']` on a plain object invokes the inherited `__proto__` accessor and returns `Object.prototype`, which is truthy. This causes `prepareEventNames()` to be skipped, leaving `symbolEventName` undefined and eventually leading to a runtime error when `window['undefined'] = []` is executed.

In Node.js environments running with `--disable-proto=throw`, the assignment:

```ts id="z8n4qm"
zoneSymbolEventNames['__proto__'] = {};
```

throws immediately because it triggers the disabled `__proto__` setter.

The `patches` registry has a similar issue. A `__proto__` key passed to `__load_patch()` bypasses the duplicate-patch check and reaches:

```ts id="f3v7kx"
patches['__proto__'] = fn(...);
```

which invokes the `__proto__` setter and changes the prototype of the `patches` object.

Using `Object.create(null)` removes the inherited `__proto__` accessor entirely, causing these keys to behave like ordinary properties rather than interacting with JavaScript's prototype machinery.

As part of this change, `patches.hasOwnProperty(name)` is also updated to:

```ts id="n2c8wp"
Object.prototype.hasOwnProperty.call(patches, name)
```

since null-prototype objects do not inherit `hasOwnProperty`.

(cherry picked from commit 2d33fd55ff)
2026-06-24 12:19:35 -04:00
arturovt bcc648f4b6 fix(upgrade): support model() signals in downgradeComponent
`model()` signals are special because they combine a signal input with a writable output through an internal `OutputEmitterRef`. During upgrade, `setupOutputs()` subscribes to that emitter to keep Angular → AngularJS two-way binding working.

The issue was that `updateInput()` could overwrite the signal property directly when `isSignal` was `false` (which happens in JIT mode and when `unsafelyOverwriteSignalInputs` is enabled). Once that happened, the original `OutputEmitterRef` was lost, so the two-way binding stopped working.

The fix detects `model()` signals at runtime by checking for both `[SIGNAL]` and a writable `.set()` method, which distinguishes them from read-only `input()` signals. When those traits are present, updates are always applied through `applyValueToInputSignal()` instead of replacing the property directly, regardless of the `unsafelyOverwriteSignalInputs` setting.

Fixes #60599

(cherry picked from commit 8d31b82116)
2026-06-24 12:17:38 -04:00
SkyZeroZx a16f9b2263 fix(service-worker): preserve referrer policy in asset requests
Preserve explicit referrer policy when the service worker reconstructs asset requests for cache-busted and redirected asset fetches.

For example, an application can load a script or image with referrerPolicy: 'same-origin' or 'origin' to limit referrer data. Dropping that policy can expose more of the current URL to that resource host.

(cherry picked from commit 6f98f98f1f)
2026-06-24 12:15:20 -04:00
SkyZeroZx b4a5a2fb4e fix(service-worker): preserve referrer in asset requests
Preserve referrer metadata when the service worker reconstructs asset requests for cache-busted and redirected asset fetches.

For example, an attacker with access to asset host logs could receive a reset token embedded in a page URL if the reconstructed request falls back to default referrer behavior instead of carrying referrer: ''.

(cherry picked from commit 716f9eb032)
2026-06-24 12:15:20 -04:00
aparziale 06d854929c fix(compiler-cli): report diagnostic instead of crashing on malformed host binding
`parseHostBindings` throws plain `Error`s for malformed host bindings
(e.g. a property binding with a non-static value, as can happen while
editing in the language service). These were uncaught during directive
analysis, crashing the compiler and the Angular Language Service.

Wrap the call and surface the error as a `FatalDiagnosticError` so it
becomes a diagnostic and analysis can complete normally.

Fixes #69106

(cherry picked from commit 8b2785b597)
2026-06-24 12:14:27 -04:00
Kam d2b613900c docs(forms): clarify debounce('blur') usage with custom FormValueControl
A custom FormValueControl only participates in debounce('blur') if it emits
the touch output on the native blur event. This was undocumented, and the
touch name reads like a focus event, so users wired it to (focus) and
blur-based debouncing silently did nothing.

Add a dedicated guide section with a working example, link the debounce API
reference to it, and clarify the touch JSDoc that it must fire on blur, not
focus.

Fixes #69370

(cherry picked from commit 12fcec8ce9)
2026-06-24 11:38:52 -04:00
SkyZeroZx cd8f472ab4 docs: add documentation for HttpClient response body size limit and related error NG02825
(cherry picked from commit e5098f00d5)
2026-06-24 11:29:25 -04:00
Saurabh Singh 03d1a6444a docs(core): document resource chaining with chain() in params context
Adds a 'Chaining resources' section to the resource guide covering:
- Basic usage of chain() to depend one resource on another
- Status propagation for all ResourceStatus values (idle, loading,
  reloading, error, resolved, local)
- Chaining vs reading .value() directly, shown as an avoid example
- Guidance on passing the chained value directly as params

Also adds an @see link from ResourceParamsContext to the new section.

Closes #69329

(cherry picked from commit 7057b1257f)
2026-06-24 11:23:53 -04:00
arturovt 3d536d7a84 docs: add error guide for NG05102
Adds an error reference page for NG05102 (UNSUPPORTED_EVENT_TARGET) explaining
what triggers it and how to fix it. Also marks the error code as negative (-5102)
so that in dev mode the error message automatically links to the new guide page
on angular.dev/errors, consistent with other documented runtime errors.

(cherry picked from commit ea177257e9)
2026-06-24 10:58:31 -04:00
SkyZeroZx 8cdc202dfc fix(http): prevent caching of responses with Set-Cookie headers
Skip HttpTransferCache serialization for HTTP responses that contain a
Set-Cookie header.

Cookie-setting responses commonly represent session-specific,
user-specific, or security-sensitive state. Serializing their bodies into
SSR TransferState can embed sensitive data into the generated HTML, where
it may be reused during hydration or replayed by a shared cache/CDN.

(cherry picked from commit f76e8a98c1)
2026-06-24 10:57:49 -04:00
Matthieu Riegler 39001be266 refactor(compiler): Move the attribute comment to the HTML AST
This is to help the support for comment formating by third-party tools like prettier.

(cherry picked from commit 826017dd31)
2026-06-24 10:56:39 -04:00
Angular Robot 6ff26e96e4 build: update babel monorepo to v7.29.7
See associated pull request for more information.
2026-06-24 10:35:42 -04:00
Kristiyan Kostadinov 2799304259 fix(core): avoid uncaught promise errors in injectAsync prefetching
Fixes a minor issue where the `preload` function in `injectAsync` might cause an uncaught promise error.

I also fixed that in `onIdle` we were passing the wrong function into `assertInInjectionContext`.

(cherry picked from commit 91d168e74b)
2026-06-23 12:57:30 -04:00
arturovt f598dcfda0 docs: add error guide for NG05101
Adds a new error reference page for NG05101 (NO_PLUGIN_FOR_EVENT),
which is thrown when no registered EventManagerPlugin supports the
event name passed to addEventListener. The page covers the two common
causes: a typo in the event binding and a missing plugin provider.

(cherry picked from commit dead64fbdb)
2026-06-23 11:25:52 -04:00
Kam 59ee51e2d4 docs(forms): update package docs for Signal Forms graduation
After #68581 graduated the Signal Forms APIs to public API and #68654 removed
the experimental warnings from the Signal Forms documentation in adev, the
package READMEs still framed the API as experimental.

Update `packages/forms/signals/PACKAGE.md`: drop the experimental title and
intro, remove the now-shipped entries from "Not yet supported" (interop with
reactive/template forms and strongly-typed binding to UI controls), and remove
the remaining experimental and exploratory wording from the FAQ.

Update `packages/forms/PACKAGE.md`: it listed only two ways to build forms
(reactive and template-driven). Add signal forms as the third.

Fixes #68724

(cherry picked from commit 8b1726a1cf)
2026-06-22 16:29:22 -04:00