mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6027c9128c | |||
| b108ece707 | |||
| 3cc549c723 | |||
| e817f8c830 | |||
| 1ea5c97703 | |||
| d81f8ea0f6 | |||
| 654ed6512b | |||
| 134742fb7b | |||
| 5594a535c1 | |||
| 5097df84b4 | |||
| c4784bd39e | |||
| d576ea577d | |||
| 230b65cc81 | |||
| 6d3b09326a | |||
| 9a764e0f5f | |||
| 9c1a5a5433 | |||
| a649fc8f57 | |||
| 8f16846dd9 | |||
| 114d03f6a6 | |||
| bf5db2b8d3 | |||
| c8b1b15143 | |||
| 559797c19d | |||
| 33ea12a797 | |||
| 1dd06f5e5c | |||
| 76a6984d7b | |||
| f5ed514b41 | |||
| 3396943fd0 | |||
| eecbdc078e | |||
| 40864e85da | |||
| b1c68e66a7 | |||
| 757e0cfd26 | |||
| 532633301b | |||
| 8474277b49 | |||
| 5ad2e1bae0 | |||
| ab86c4dfaf | |||
| 0587bb77ad | |||
| 79f979a673 | |||
| cc066cb31f | |||
| 3932bab633 | |||
| e66a8ef0da | |||
| ed5b62a140 | |||
| 1f47e885fd | |||
| d1f6bcdacd | |||
| ed292e398a | |||
| 3954dc278b | |||
| 8cf3a72d57 | |||
| 481557e69f | |||
| 13a7ee8424 | |||
| fd3253e093 | |||
| addccead9b | |||
| 8f451b5647 | |||
| e4dcd72926 | |||
| 204aacadb4 | |||
| e9cb3cbefb | |||
| 4871131136 | |||
| fb21801827 | |||
| 3de709f41b | |||
| 47d89c8ca2 | |||
| c7d6053797 | |||
| 03e2b36826 | |||
| 29f074a93f | |||
| 62d7533ca6 | |||
| a59f51f0e6 | |||
| a201d33e0c | |||
| 0875deab8d | |||
| dd37fd821e | |||
| 7b396e8bb2 | |||
| 24b0920755 | |||
| f3a7b3ab67 | |||
| 1c055aa268 | |||
| 0c23d02944 | |||
| 83bac5adc9 | |||
| e01dcae4c5 | |||
| 4cdf4d5760 | |||
| f41d721ce0 | |||
| 0fd8477f3f | |||
| 5dd2f2bb98 | |||
| ca57165c7e | |||
| 4391c44801 | |||
| 985bdeefd3 | |||
| 95bc06d6c3 | |||
| 2c3a067bb6 | |||
| 2c74475969 | |||
| 74af7d85e5 | |||
| 6ad2ef6bd8 |
@@ -1 +0,0 @@
|
||||
../../AGENTS.md
|
||||
@@ -1 +0,0 @@
|
||||
../.gemini/skills
|
||||
+1
-1
@@ -1 +1 @@
|
||||
8.6.0
|
||||
8.5.1
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
description = "Researches part of the codebase and creates a skill for it"
|
||||
prompt="""
|
||||
## Role
|
||||
|
||||
You are an experienced senior developer specializing in reverse engineering and understanding
|
||||
complex code, prompt engineering, and context engineering.
|
||||
|
||||
Your task is to build a complete understanding of the mental model and architecture of the code,
|
||||
and to create an efficient context file that allows a coding agent to understand and work with the
|
||||
code.
|
||||
|
||||
## Guiding Principles
|
||||
|
||||
1. **Deep Analysis:** Understand the _why_ behind the code. Not just a surface level listing of
|
||||
files and classes.
|
||||
|
||||
2. **Curiosity:** Be curious. If something is unclear, confusing, or unexpected you _MUST_
|
||||
investigate further until you fully understand.
|
||||
|
||||
3. **Efficient Token Use:** The final output will be directly included into the context of the
|
||||
coding assistant, so be sure to make efficient use of tokens. Think deeply, but only capture the
|
||||
most important information for the coding agent in the final output
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Fully explore the code before first, with a focus on understanding the architecture and how all
|
||||
of the pieces fit together.
|
||||
|
||||
2. Develop an understanding of the mental model behind the architecture. _Why_ is the code is
|
||||
architected this way? How should developers think about the system?
|
||||
|
||||
3. Document your findings using the given output format described in the next section.
|
||||
|
||||
## Output Format
|
||||
|
||||
Note the following placeholders below:
|
||||
|
||||
- `[package]`: is a unique identifier for the current code package (for example if you're looking at
|
||||
code under `packages/forms/signals` you might use `signal-forms` as the `[package]`)
|
||||
- `[code-location]`: is the location of the current code within the larger repository
|
||||
- `[context]`: is the context to add to the coding agent when it is working with this code.
|
||||
|
||||
With those placeholders in mind, write a file create a new directory under `.gemini/skills` with the
|
||||
name `reference-[package]/`, and under that directory add a `SKILL.md` file with the following
|
||||
content:
|
||||
|
||||
```md
|
||||
---
|
||||
name: reference-[package]
|
||||
description: Explains the mental model and architecture of the code under `[code-location]`. You MUST use this skill any time you plan to work with code in `[code-location]`
|
||||
---
|
||||
|
||||
[context]
|
||||
```
|
||||
|
||||
## Additional User Instructions
|
||||
|
||||
The user may have additional instructions.
|
||||
|
||||
- The user should indicate what package to research
|
||||
- The user may indicate that they want to update a package that has already been researched. In this
|
||||
case, read the existing skill and make any required updates based on your research
|
||||
- The user may request supplemental information be added to the skill (if so, add this to the
|
||||
existing skill in a new markdown file under a `references` directory within the skill. Add a
|
||||
section to the main `SKILL.md` that mentions what supplemental information is available)
|
||||
|
||||
Here are the user's additional instructions:
|
||||
|
||||
{{args}}
|
||||
"""
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"context": {
|
||||
"fileName": ["AGENTS.md", "GEMINI.md"]
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
---
|
||||
name: adev-writing-guide
|
||||
description: Comprehensive writing guide for Angular documentation (adev). Covers Google Technical Writing standards, Angular-specific markdown extensions, code blocks, and components. Use when authoring or reviewing content in adev/src/content.
|
||||
---
|
||||
|
||||
# Angular Documentation (adev) Writing Guide
|
||||
|
||||
This skill provides comprehensive guidelines for authoring content in `adev/src/content`. It combines Google's technical writing standards with Angular-specific markdown conventions, components, and best practices.
|
||||
|
||||
## I. Google Technical Writing Guidelines
|
||||
|
||||
### Tone and Content
|
||||
|
||||
- **Be conversational and friendly:** Maintain a helpful yet professional tone. Avoid being overly casual.
|
||||
- **Write accessibly:** Ensure documentation is understandable to a diverse global audience, including non-native English speakers.
|
||||
- **Audience-first:** Focus on what the user needs to do, not just what the system does.
|
||||
- **Avoid pre-announcing:** Do not mention unreleased features or make unsupported claims.
|
||||
- **Use descriptive link text:** Link text should clearly indicate the destination (e.g., avoid "click here").
|
||||
|
||||
### Language and Grammar
|
||||
|
||||
- **Use second person ("you"):** Address the reader directly.
|
||||
- **Prefer active voice:** Clearly state who or what is performing the action (e.g., "The system generates a token" vs "A token is generated").
|
||||
- **Standard American English:** Use standard American spelling and punctuation.
|
||||
- **Conditional clauses first:** Place "if" or "when" clauses before the instruction (e.g., "If you encounter an error, check the logs").
|
||||
- **Define terms:** Introduce new or unfamiliar terms/acronyms upon first use.
|
||||
- **Consistent terminology:** Use the same term for the same concept throughout the document.
|
||||
- **Conciseness:** Aim for one idea per sentence. Keep sentences short.
|
||||
|
||||
### Formatting and Organization
|
||||
|
||||
- **Sentence case for headings:** Capitalize only the first word and proper nouns in titles and headings.
|
||||
- **Lists:**
|
||||
- **Numbered lists:** Use for sequential steps or prioritized items.
|
||||
- **Bulleted lists:** Use for unordered collections of items.
|
||||
- **Description lists:** Use for term-definition pairs.
|
||||
- **Serial commas:** Use the Oxford comma (comma before the last item in a list of three or more).
|
||||
- **Code formatting:** Use code font for code-related text (filenames, variables, commands).
|
||||
- **UI Elements:** formatting user interface elements in **bold**.
|
||||
- **Date formatting:** Use unambiguous formats (e.g., "September 4, 2024" rather than "9/4/2024").
|
||||
- **Structure:** Use logical hierarchy with clear introductions and navigation. Headings should be task-based where possible.
|
||||
|
||||
### Images and Code Samples
|
||||
|
||||
- **Images:** Use simple, clear illustrations to enhance understanding.
|
||||
- **Captions:** Write captions that support the image.
|
||||
- **Code Samples:**
|
||||
- Ensure code is correct and builds without errors.
|
||||
- Follow language-specific conventions.
|
||||
- **Comments:** Focus on _why_, not _what_. Avoid commenting on obvious code.
|
||||
|
||||
### Reference Hierarchy
|
||||
|
||||
1. Project-specific style guidelines (if any exist in `CONTRIBUTING.md` or similar).
|
||||
2. Google Developer Documentation Style Guide.
|
||||
3. Merriam-Webster (spelling).
|
||||
4. Chicago Manual of Style (non-technical).
|
||||
5. Microsoft Writing Style Guide (technical).
|
||||
|
||||
---
|
||||
|
||||
## II. Angular Documentation Specifics
|
||||
|
||||
### Code Blocks
|
||||
|
||||
Use the appropriate language identifier for syntax highlighting:
|
||||
|
||||
- **TypeScript (Angular):** Use `angular-ts` when TypeScript code examples contain inline templates.
|
||||
- **HTML (Angular):** Use `angular-html` for Angular templates.
|
||||
- **TypeScript (Generic):** Use `ts` for plain TypeScript.
|
||||
- **HTML (Generic):** Use `html` for plain HTML.
|
||||
- **Shell/Terminal:** Use `shell` or `bash`.
|
||||
- **Mermaid Diagrams:** Use `mermaid`.
|
||||
|
||||
#### Attributes
|
||||
|
||||
You can enhance code blocks with attributes in curly braces `{}` after the language identifier:
|
||||
|
||||
- `header="Title"`: Adds a title to the code block.
|
||||
- `linenums`: Enables line numbering.
|
||||
- `highlight="[1, 3-5]"`: Highlights specific lines.
|
||||
- `hideCopy`: Hides the copy button.
|
||||
- `prefer`: Marks code as a preferred example (green border/check).
|
||||
- `avoid`: Marks code as an example to avoid (red border/cross).
|
||||
|
||||
**Example:**
|
||||
|
||||
````markdown
|
||||
```angular-ts {header:"My Component", linenums, highlight="[2]"}
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<h1>Hello</h1>',
|
||||
})
|
||||
export class App {}
|
||||
```
|
||||
````
|
||||
|
||||
#### `<docs-code>` Component
|
||||
|
||||
For more advanced code block features, use the `<docs-code>` component:
|
||||
|
||||
- `path`: Path to a source file (e.g., `adev/src/content/examples/...`).
|
||||
- `header`: Custom header text.
|
||||
- `language`: Language identifier (e.g., `angular-ts`).
|
||||
- `linenums`: Boolean attribute.
|
||||
- `highlight`: Array of line numbers/ranges (e.g., `[[3,7], 9]`).
|
||||
- `diff`: Path to diff file.
|
||||
- `visibleLines`: Range of lines to show initially (collapsible).
|
||||
- `region`: Region to extract from source file.
|
||||
- `preview`: Boolean. Renders a live preview (StackBlitz). _Only works with standalone examples._
|
||||
- `hideCode`: Boolean. Collapses code by default.
|
||||
|
||||
**Multifile Example:**
|
||||
|
||||
```html
|
||||
<docs-code-multifile path="..." preview>
|
||||
<docs-code path="..." />
|
||||
<docs-code path="..." />
|
||||
</docs-code-multifile>
|
||||
```
|
||||
|
||||
### Alerts / Admonitions
|
||||
|
||||
Use specific keywords followed by a colon for alerts. These render as styled blocks.
|
||||
|
||||
- `NOTE:` For ancillary information.
|
||||
- `TIP:` For helpful hints or shortcuts.
|
||||
- `IMPORTANT:` For crucial information.
|
||||
- `CRITICAL:` For warnings about potential data loss or severe issues.
|
||||
- `TODO`: For incomplete documentation.
|
||||
- `QUESTION:` To pose a question to the reader.
|
||||
- `SUMMARY:` For section summaries.
|
||||
- `TLDR:` For concise summaries.
|
||||
- `HELPFUL:` For best practices.
|
||||
|
||||
**Example:**
|
||||
|
||||
```markdown
|
||||
TIP: Use `ng serve` to run your application locally.
|
||||
```
|
||||
|
||||
### Custom Components
|
||||
|
||||
- **Cards (`<docs-card>`):**
|
||||
- Must be inside `<docs-card-container>`.
|
||||
- Attributes: `title`, `link`, `href`.
|
||||
- **Callouts (`<docs-callout>`):**
|
||||
- Attributes: `title`, `important`, `critical`.
|
||||
- **Pills (`<docs-pill>`):**
|
||||
- Must be inside `<docs-pill-row>`.
|
||||
- Attributes: `title`, `href`.
|
||||
- **Steps / Workflow (`<docs-step>`):**
|
||||
- Must be inside `<docs-workflow>`.
|
||||
- Attributes: `title`.
|
||||
- **Tabs (`<docs-tab>`):**
|
||||
- Must be inside `<docs-tab-group>`.
|
||||
- Attributes: `label`.
|
||||
- **Videos (`<docs-video>`):**
|
||||
- Attributes: `src` (YouTube embed URL), `alt`.
|
||||
|
||||
### Images
|
||||
|
||||
Use standard markdown syntax with optional attributes for sizing and loading behavior.
|
||||
|
||||
- `#small`, `#medium`: Append to image URL for sizing.
|
||||
- `{loading: 'lazy'}`: Add attribute for lazy loading.
|
||||
|
||||
**Example:**
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
### Headers
|
||||
|
||||
- Use markdown headers (`#`, `##`, `###`).
|
||||
- Ensure a logical hierarchy (don't skip levels).
|
||||
- `h2` and `h3` are most common for content structure.
|
||||
@@ -1,91 +0,0 @@
|
||||
---
|
||||
name: reference-compiler-cli
|
||||
description: Explains the mental model and architecture of the code under `packages/compiler-cli`. You MUST use this skill any time you plan to work with code in `packages/compiler-cli`
|
||||
---
|
||||
|
||||
# Angular Compiler CLI (`ngtsc`) Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
The `packages/compiler-cli` package contains the Angular Compiler (Ivy), often referred to as `ngtsc`. It is a wrapper around the TypeScript compiler (`tsc`) that extends it with Angular-specific capabilities.
|
||||
|
||||
The core goal of `ngtsc` is to compile Angular decorators (like `@Component`, `@Directive`, `@Pipe`) into static properties on the class (Ivy instructions, e.g., `static ɵcmp = ...`). It also performs template type checking and ahead-of-time (AOT) compilation.
|
||||
|
||||
## Mental Model
|
||||
|
||||
The compiler is designed as a **lazy, incremental, and partial** compilation pipeline.
|
||||
|
||||
1. **Wrapper Pattern**: `NgtscProgram` wraps the standard `ts.Program`. It intercepts calls to act as a drop-in replacement for standard tooling.
|
||||
2. **Traits System**: Every class with an Angular decorator is considered a "Trait". The compiler manages the state of these traits through a state machine:
|
||||
- **Pending**: Detected but not processed.
|
||||
- **Analyzed**: Metadata extracted, template parsed (but dependencies not yet linked).
|
||||
- **Resolved**: Dependencies (directives/pipes in template) resolved, import cycles handled.
|
||||
- **Skipped**: Not an Angular class.
|
||||
3. **Lazy Analysis**: Analysis only happens when necessary (e.g., when diagnostics are requested or emit is prepared).
|
||||
4. **Output AST**: The compiler generates an intermediate "Output AST" (`o.Expression`) for the generated code, which is then translated into TypeScript AST nodes during the emit phase.
|
||||
|
||||
## Key Subsystems
|
||||
|
||||
### 1. Core Orchestration (`ngtsc/core`)
|
||||
|
||||
- **`NgtscProgram`**: The public API implementing `api.Program`. It manages the `ts.Program` and the `NgCompiler`.
|
||||
- **`NgCompiler`**: The brain of the compiler. It orchestrates the compilation phases (Analysis, Resolution, Type Checking, Emit). It holds the `TraitCompiler`.
|
||||
|
||||
### 2. Trait Compilation (`ngtsc/transform`)
|
||||
|
||||
- **`TraitCompiler`**: Manages the lifecycle of "Traits". It iterates over source files, identifies decorated classes, and delegates to the appropriate `DecoratorHandler`.
|
||||
- **`Trait`**: A state container for a class, holding its handler, analysis results, and resolution results.
|
||||
|
||||
### 3. Decorator Handlers (`ngtsc/annotations`)
|
||||
|
||||
- **`DecoratorHandler`**: An interface for handling specific decorators.
|
||||
- **`ComponentDecoratorHandler`**: The most complex handler. It:
|
||||
- Extracts metadata (selector, inputs, outputs).
|
||||
- Parses the template.
|
||||
- Resolves used directives and pipes (`R3TargetBinder`).
|
||||
- Generates the `ɵcmp` instruction.
|
||||
- **`DirectiveDecoratorHandler`**, **`PipeDecoratorHandler`**, **`NgModuleDecoratorHandler`**: Handle their respective decorators.
|
||||
|
||||
### 4. Template Type Checking (`ngtsc/typecheck`)
|
||||
|
||||
- **`TemplateTypeChecker`**: Generates "Type Check Blocks" (TCBs). A TCB is a block of TypeScript code that represents the template's logic in a way `tsc` can understand and check for errors.
|
||||
- **`TypeCheckBlock`**: The actual generated code that validates bindings, events, and structural directives.
|
||||
|
||||
### 5. Metadata & Scope (`ngtsc/metadata`, `ngtsc/scope`)
|
||||
|
||||
- **`MetadataReader`**: Reads Angular metadata from source files (using `LocalMetadataRegistry`) and `.d.ts` files (using `DtsMetadataReader`).
|
||||
- **`ScopeRegistry`**: Determines the "compilation scope" of a component (which directives/pipes are available to it), handling `NgModule` transitive exports and Standalone Component imports.
|
||||
|
||||
### 6. Emit & Transformation (`ngtsc/transform`)
|
||||
|
||||
- **`ivyTransformFactory`**: A TypeScript transformer factory.
|
||||
- **`IvyCompilationVisitor`**: Visits classes, triggers compilation via `TraitCompiler`, and collects the Output AST.
|
||||
- **`IvyTransformationVisitor`**: Translates the Output AST into TypeScript AST, injects the `static ɵ...` fields, and removes the original decorators.
|
||||
|
||||
## Compilation Phases
|
||||
|
||||
1. **Construction**: `NgtscProgram` creates `NgCompiler`, which sets up all registries and the `TraitCompiler`.
|
||||
2. **Analysis** (`analyzeSync`):
|
||||
- The `TraitCompiler` scans files.
|
||||
- `DecoratorHandler`s extract metadata and parse templates.
|
||||
- No cross-file resolution happens here (allowing for parallelism and caching).
|
||||
3. **Resolution** (`resolve`):
|
||||
- `TraitCompiler` resolves traits.
|
||||
- Components link their templates to specific Directives and Pipes (found via `ScopeRegistry`).
|
||||
- Import cycles are detected and handled (e.g., via "remote scoping").
|
||||
4. **Type Checking**:
|
||||
- `TemplateTypeChecker` creates TCBs for all components.
|
||||
- TypeScript diagnostics are retrieved for these TCBs.
|
||||
5. **Emit** (`prepareEmit`):
|
||||
- `ivyTransformFactory` is created.
|
||||
- TS `emit` is called.
|
||||
- The transformers run, injecting the compiled Ivy instructions into the JS/DTS output.
|
||||
|
||||
## Important File Locations
|
||||
|
||||
- `packages/compiler-cli/src/ngtsc/program.ts`: Entry point (`NgtscProgram`).
|
||||
- `packages/compiler-cli/src/ngtsc/core/src/compiler.ts`: Core logic (`NgCompiler`).
|
||||
- `packages/compiler-cli/src/ngtsc/transform/src/trait.ts`: Trait state machine.
|
||||
- `packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts`: Component compilation logic.
|
||||
- `packages/compiler-cli/src/ngtsc/typecheck/src/template_type_checker.ts`: Type checking logic.
|
||||
- `packages/compiler-cli/src/ngtsc/transform/src/transform.ts`: AST transformation logic.
|
||||
@@ -1,96 +0,0 @@
|
||||
---
|
||||
name: reference-core
|
||||
description: Explains the mental model and architecture of the code under `packages/core`. You MUST use this skill any time you plan to work with code in `packages/core`
|
||||
---
|
||||
|
||||
# Angular Core (`packages/core`) Mental Model
|
||||
|
||||
This document outlines the architecture and mental model for `packages/core`, the heart of the Angular framework.
|
||||
|
||||
## 1. High-Level Architecture
|
||||
|
||||
`packages/core` contains the runtime logic for Angular. Its primary responsibilities are:
|
||||
|
||||
1. **Rendering (Ivy/Render3)**: Transforming templates into DOM updates.
|
||||
2. **Dependency Injection (DI)**: Managing object creation and lifetime.
|
||||
3. **Change Detection**: Synchronizing the model with the view.
|
||||
4. **Reactivity**: Signals and Zone.js integration.
|
||||
|
||||
## 2. Rendering Engine (Ivy / Render3)
|
||||
|
||||
The rendering engine (located in `packages/core/src/render3`) uses an **instruction-based** approach.
|
||||
|
||||
### Key Concepts
|
||||
|
||||
- **Instructions**: The Angular compiler transforms templates into a sequence of instruction calls (e.g., `ɵɵelementStart`, `ɵɵtext`, `ɵɵproperty`). These instructions are executed at runtime to create and update the view.
|
||||
- _Location_: `packages/core/src/render3/instructions`
|
||||
|
||||
- **LView (Logical View)**: An array containing the _state_ of a specific view instance. It holds:
|
||||
- DOM nodes (`RElement`, `RText`).
|
||||
- Binding values (for change detection).
|
||||
- Directive/Component instances.
|
||||
- _Context_: `packages/core/src/render3/interfaces/view.ts`
|
||||
|
||||
- **TView (Template View)**: An array containing the _static structure_ of a view. It is shared across all instances (`LView`s) of the same component/template. It holds:
|
||||
- Property names for bindings.
|
||||
- Node relationship information.
|
||||
- Compiled directive definitions.
|
||||
- _Context_: `packages/core/src/render3/interfaces/view.ts`
|
||||
|
||||
- **Memory Layout**: `LView` and `TView` are parallel arrays. Index `i` in `LView` corresponds to metadata at index `i` in `TView`.
|
||||
- `HEADER`: Fixed size, contains context (Parent, Host, etc.).
|
||||
- `DECLS`: Static nodes (elements, text, pipes).
|
||||
- `VARS`: Binding values.
|
||||
- `EXPANDO`: Dynamic data (host bindings, injectors).
|
||||
|
||||
### The Render Cycle
|
||||
|
||||
1. **Creation Mode**: Instructions create DOM nodes and store them in `LView`.
|
||||
2. **Update Mode**: Instructions check current values against previous values stored in `LView`. If changed, they update the DOM.
|
||||
|
||||
## 3. Dependency Injection (DI)
|
||||
|
||||
DI in Angular is hierarchical and split into two systems that interact:
|
||||
|
||||
### Module Injector (`R3Injector`)
|
||||
|
||||
- Configured via `@NgModule.providers` or `providedIn: 'root'`.
|
||||
- Stored in a hierarchy of `R3Injector` instances.
|
||||
- _Location_: `packages/core/src/di/r3_injector.ts`
|
||||
|
||||
### Node Injector
|
||||
|
||||
- Configured via `@Component.providers` or `@Directive.providers`.
|
||||
- **Not a class**, but a data structure embedded in the `LView` ("Expando" section).
|
||||
- Uses **Bloom Filters** (`TView.data`) to quickly check if a token is present at a specific node index before traversing up the tree.
|
||||
- Resolves tokens starting from the current node, walking up the view tree (Element Injector hierarchy), and falling back to the Module Injector if not found.
|
||||
|
||||
## 4. Change Detection
|
||||
|
||||
- **Dirty Checking**: Angular checks if values bound in templates have changed.
|
||||
- **Strategies**:
|
||||
- `Default`: Checks everything.
|
||||
- `OnPush`: Checks only if inputs change, events fire, or signals update.
|
||||
- **Signals**: The new reactivity primitive. Signals notify the scheduler when they change, potentially allowing for fine-grained updates (Zoneless).
|
||||
|
||||
## 5. Key Directories to Know
|
||||
|
||||
- `src/render3`: The Ivy rendering engine.
|
||||
- `instructions`: The runtime instructions called by compiled code.
|
||||
- `interfaces`: `LView`, `TView`, `TNode` definitions.
|
||||
- `src/di`: Dependency injection system.
|
||||
- `src/change_detection`: Change detection logic.
|
||||
- `src/zone`: Zone.js integration.
|
||||
- `src/signal`: Signals implementation (if present in this version, otherwise likely in `primitives`).
|
||||
|
||||
## 6. Conventions & Gotchas
|
||||
|
||||
- **Prefixes**: Private/Internal exports often start with `ɵ`.
|
||||
- **Global State**: Ivy relies heavily on global state (e.g., `getLView()`) during instruction execution to avoid passing context arguments everywhere. This is for performance and code size.
|
||||
- **Performance**: The code is highly optimized for performance and memory. You will see arrays used instead of objects, bitmasks, and manual memory management patterns. **Respect these patterns.**
|
||||
|
||||
## 7. How to Modify Core
|
||||
|
||||
1. **Understand the Instruction**: If modifying runtime behavior, find the corresponding instruction in `src/render3/instructions`.
|
||||
2. **Check `LView`/`TView` Impact**: If adding state, understand where it fits in the `LView` array.
|
||||
3. **Tests**: Core has extensive tests. Run them using Bazel.
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
name: reference-signal-forms
|
||||
description: Explains the mental model and architecture of the code under `packages/forms/signals`. You MUST use this skill any time you plan to work with code in `packages/forms/signals`
|
||||
---
|
||||
|
||||
# Signal Forms Architecture
|
||||
|
||||
The `packages/forms/signals` directory contains an experimental, signal-based forms API for Angular.
|
||||
This system differs significantly from the existing Reactive and Template-driven forms.
|
||||
|
||||
## Mental Model
|
||||
|
||||
1. **Model-Driven**: The system is built around a `WritableSignal<T>` which serves as the **single source of truth**.
|
||||
Unlike Reactive Forms where the `FormControl` holds the value, here the `Signal` holds the value.
|
||||
The form is merely a _view_ or _projection_ of that signal, adding form-specific state (validity, dirty, touched).
|
||||
|
||||
2. **Proxy-Based Traversal**: The form API (`form(signal)`) returns a `FieldTree`. This object is a **Proxy**.
|
||||
It allows accessing nested fields (e.g., `myForm.user.name`) without manually creating control groups.
|
||||
Accessing a property on the proxy lazily resolves or creates the corresponding `FieldNode`.
|
||||
|
||||
3. **Schema-Based Logic**: Validation, disabled state, and other metadata are defined separately via **Schemas**.
|
||||
Schemas are applied to the form structure using functions like `apply`, `applyEach` (for arrays), and `applyWhen`.
|
||||
This separates the _structure_ of the data from the _rules_ governing it.
|
||||
|
||||
4. **Directives as Glue**: The `[formField]` directive binds a DOM element (native input or custom control) to a `FieldNode`.
|
||||
It handles:
|
||||
- Syncing the value between the DOM and the Signal.
|
||||
- Reflecting state (valid, touched, etc.) to the UI.
|
||||
- Handling user interaction events (blur, input).
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. `FieldNode` (`src/field/node.ts`)
|
||||
|
||||
The central internal class representing a single field in the form graph. It aggregates several state managers:
|
||||
|
||||
- `structure`: Manages parent/child relationships and signal slicing.
|
||||
- `validationState`: Computes `valid`, `invalid`, `errors` signals.
|
||||
- `nodeState`: Tracks `touched`, `dirty`, `pristine`.
|
||||
- `metadataState`: Stores metadata like `min`, `max`, `required`.
|
||||
- `submitState`: Tracks submission status and server errors.
|
||||
|
||||
### 2. `ValidationState` (`src/field/validation.ts`)
|
||||
|
||||
Manages the complexity of validation:
|
||||
|
||||
- **Synchronous Errors**: Derived from schema rules.
|
||||
- **Asynchronous Errors**: Handled via signals, including 'pending' states.
|
||||
- **Tree Errors**: Errors that bubble up or are targeted at specific fields.
|
||||
- **Submission Errors**: Server-side errors injected imperatively via `submit()`.
|
||||
|
||||
### 3. `FormField` Directive (`src/directive/form_field_directive.ts`)
|
||||
|
||||
The bridge between the `FieldNode` and the DOM.
|
||||
|
||||
- Selector: `[formField]`
|
||||
- It supports:
|
||||
- **Native Elements**: `<input>`, `<select>`, `<textarea>`.
|
||||
- **Custom Controls**: Components implementing `FormUiControl` or `FormValueControl`.
|
||||
- **Legacy Interop**: Components implementing `ControlValueAccessor` (via `InteropNgControl`).
|
||||
|
||||
### 4. `Schema` (`src/api/structure.ts` & `src/api/rules`)
|
||||
|
||||
Defines the behavior.
|
||||
|
||||
- Created via `schema(fn)`.
|
||||
- Applied via `apply(path, schema)`.
|
||||
- Rules include validators (`required`, `pattern`, `min`, `max`) and state modifiers (`disabled`, `hidden`).
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. **Read**: `form.field.value()` reads directly from the underlying signal (projected to the specific path).
|
||||
2. **Write**: Writing to the form (e.g., via UI) updates the underlying signal.
|
||||
3. **Validation**: A computed effect observes the value signal and runs validators defined in the schema.
|
||||
|
||||
## Usage Example (Conceptual)
|
||||
|
||||
```typescript
|
||||
// 1. Define Model
|
||||
const user = signal({name: '', age: 0});
|
||||
|
||||
// 2. Define Schema
|
||||
const userRules = schema((u) => {
|
||||
required(u.name);
|
||||
min(u.age, 18);
|
||||
});
|
||||
|
||||
// 3. Create Form
|
||||
const userForm = form(user, userRules); // OR apply(userForm, userRules)
|
||||
|
||||
// 4. Bind in Template
|
||||
// <input [formField]="userForm.name">
|
||||
```
|
||||
|
||||
## Important Files
|
||||
|
||||
- `packages/forms/signals/src/api/structure.ts`: Public API entry points (`form`, `apply`).
|
||||
- `packages/forms/signals/src/api/control.ts`: Interfaces for custom controls (`FormUiControl`).
|
||||
- `packages/forms/signals/src/field/node.ts`: The `FieldNode` implementation.
|
||||
- `packages/forms/signals/src/directive/form_field_directive.ts`: The `[formField]` directive.
|
||||
|
||||
## Supplemental Information
|
||||
|
||||
- [Compiler & Core Integration](references/integration.md): Details how `[formField]` hooks into type-checking and the runtime.
|
||||
@@ -1,46 +0,0 @@
|
||||
# Signal Forms Integration: Compiler & Core
|
||||
|
||||
This document explains how the Signal Forms system hooks into the Angular compiler and runtime to provide seamless type-checking and efficient updates.
|
||||
|
||||
## 1. Compiler-CLI Integration (Type Checking)
|
||||
|
||||
The `packages/compiler-cli` package contains specific logic to support `[formField]`. This is primarily handled in `src/ngtsc/typecheck/src/ops/signal_forms.ts`.
|
||||
|
||||
### Key Mechanisms:
|
||||
|
||||
- **Detection**: The compiler identifies a directive as a "Field Directive" if it has the `ɵNgFieldDirective` property or comes from `@angular/forms/signals`.
|
||||
- **Synthetic Binding Expansion**: When you write `<input [formField]="mySignal" />`, the type checker doesn't just check `formField`. It synthetically expands this into a set of bindings for validation:
|
||||
- `[value]="mySignal()"` (or `checked` for checkboxes)
|
||||
- `[disabled]="mySignal.disabled()"`
|
||||
- `[required]="mySignal.required()"`
|
||||
- ...and so on.
|
||||
- This ensures that `mySignal` (the `FieldNode`) has all the necessary properties to drive the form control.
|
||||
- **Conflict Detection**: It actively prevents "double binding". If you bind `[formField]`, you are _banned_ from also binding `[value]`, `[disabled]`, `[required]`, etc., as the signal form should be the single source of truth.
|
||||
- **Element Type Validation**:
|
||||
- **Native Elements**: Checks that the signal's value type matches the element type (e.g., `<input type="checkbox">` requires a `boolean` signal).
|
||||
- **Custom Controls**: Detects if a custom component is a "Form Value Control" (has a `value` input/output) or "Form Checkbox Control" (has a `checked` input/output) and validates against that.
|
||||
|
||||
### Relevant Files:
|
||||
|
||||
- `packages/compiler-cli/src/ngtsc/typecheck/src/ops/signal_forms.ts`: The core logic for `TcbNativeFieldOp` and `SignalFormFieldOp`.
|
||||
|
||||
## 2. Core Runtime Integration
|
||||
|
||||
The `packages/core` package provides the low-level instructions that power the `FormField` directive. This allows it to do things normal directives cannot, like efficiently syncing state without change detection overhead for every property.
|
||||
|
||||
### Key Mechanisms:
|
||||
|
||||
- **`ɵngControlCreate` Hook**: The `FormField` directive defines a special method `ɵngControlCreate`.
|
||||
- **`ɵɵcontrol` Instructions**: When the compiler sees `ɵngControlCreate`, it emits:
|
||||
- `ɵɵcontrolCreate`: Called during the creation phase.
|
||||
- `ɵɵcontrol`: Called during the update phase.
|
||||
- **`ControlDirectiveHost`**: These instructions provide the directive with a `ControlDirectiveHost`. This is a privileged interface that allows the `FormField` directive to:
|
||||
- **Access the Element**: Get direct access to the native element or component instance.
|
||||
- **Set Inputs**: Write directly to inputs of _other directives_ on the same node (e.g., setting the `value` input of a custom control).
|
||||
- **Listen to Outputs**: Subscribe to outputs of other directives (e.g., `valueChange`).
|
||||
- **Bypass Templates**: It effectively acts as a "meta-directive" that manages the bindings for you, bypassing the need for explicit template syntax for every property.
|
||||
|
||||
### Relevant Files:
|
||||
|
||||
- `packages/core/src/render3/instructions/control.ts`: Implementation of `ɵɵcontrol` instructions.
|
||||
- `packages/forms/signals/src/directive/form_field_directive.ts`: The directive that implements the hook.
|
||||
@@ -1,48 +0,0 @@
|
||||
name: 'VSCode Angular Language Service extension'
|
||||
description: Report an issue or suggest a feature for the VSCode Angular Language Service extension
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: bug-report-or-feature-request
|
||||
attributes:
|
||||
label: Is this a bug report or a feature request?
|
||||
description: Select one.
|
||||
options:
|
||||
- label: Bug Report
|
||||
- label: Feature Request
|
||||
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Please provide the steps to reproduce the issue [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: expected-vs-actual-behavior
|
||||
attributes:
|
||||
label: Please provide the expected behavior vs the actual behavior you encountered [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Please provide a screenshot if possible [Bug Report only]
|
||||
|
||||
- type: textarea
|
||||
id: exception-or-error
|
||||
attributes:
|
||||
label: Please provide the exception or error you saw [Bug Report only]
|
||||
render: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: Proposed solution [Feature Request only]
|
||||
|
||||
- type: textarea
|
||||
id: alternatives-considered
|
||||
attributes:
|
||||
label: Alternatives considered [Feature Request only]
|
||||
+22979
-20338
File diff suppressed because one or more lines are too long
@@ -5,9 +5,9 @@ runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/saucelabs@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Starting Saucelabs tunnel service
|
||||
shell: bash
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
|
||||
@@ -21,17 +21,17 @@ jobs:
|
||||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Build adev
|
||||
# `snapshot-build` config is used to stamp the exact version with sha in the footer.
|
||||
run: pnpm bazel build //adev:build.production --config=snapshot-build
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
||||
with:
|
||||
token: '${{secrets.GITHUB_TOKEN}}'
|
||||
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
|
||||
@@ -14,9 +14,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.repository.fork == false
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
# Specify repository as the PR branch might be from a fork.
|
||||
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
|
||||
+26
-28
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Check code lint
|
||||
@@ -32,8 +32,6 @@ jobs:
|
||||
run: pnpm ng-dev pullapprove verify
|
||||
- name: Validate angular robot configuration
|
||||
run: pnpm ng-dev ngbot verify
|
||||
- name: Validate agent skills
|
||||
run: pnpm ng-dev ai skills validate
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: pnpm check-tooling-setup
|
||||
|
||||
@@ -41,13 +39,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
disable-package-manager-cache: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -57,7 +55,7 @@ jobs:
|
||||
- name: Test build
|
||||
run: pnpm devtools:build:chrome
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@bc22e01685c56e89e7813fd8e26f33dc47f87e15 # v7.1.5
|
||||
uses: cypress-io/github-action@2ad32e649e4db26c07674ebae31a297601dbcbaf # v6.10.8
|
||||
with:
|
||||
command: pnpm devtools:test:e2e
|
||||
start: pnpm bazel run //devtools/src:devserver
|
||||
@@ -69,11 +67,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -85,11 +83,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -102,11 +100,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -121,11 +119,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -138,11 +136,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
@@ -154,11 +152,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
|
||||
- name: Install node modules
|
||||
@@ -208,11 +206,11 @@ jobs:
|
||||
runs-on: ubuntu-latest-8core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Build adev
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
ANGULAR_READONLY_GITHUB_TOKEN: ${{ secrets.READONLY_GITHUB_TOKEN }}
|
||||
|
||||
- name: Create a PR (if necessary)
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
|
||||
with:
|
||||
token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
|
||||
push-to-fork: 'angular-robot/angular'
|
||||
|
||||
@@ -3,36 +3,23 @@ name: DevInfra
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
issues:
|
||||
types: [opened, reopened]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
pull_request_labels:
|
||||
if: github.event_name == 'pull_request_target'
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: angular/dev-infra/github-actions/labeling/pull-request@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: angular/dev-infra/github-actions/pull-request-labeling@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
labels: '{"requires: TGP": ["packages/core/primitives/**/{*,.*}"]}'
|
||||
post_approval_changes:
|
||||
if: github.event_name == 'pull_request_target'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
issue_labels:
|
||||
if: github.event_name == 'issues'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/labeling/issue@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }}
|
||||
|
||||
@@ -13,8 +13,8 @@ jobs:
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -13,15 +13,15 @@ jobs:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/saucelabs@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: pnpm bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
|
||||
@@ -9,6 +9,6 @@ jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
workflows: ${{ steps.workflows.outputs.workflows }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- id: workflows
|
||||
@@ -36,9 +36,9 @@ jobs:
|
||||
workflow: ${{ fromJSON(needs.list.outputs.workflows) }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
|
||||
|
||||
+21
-23
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Check code lint
|
||||
@@ -32,14 +32,12 @@ jobs:
|
||||
run: pnpm ng-dev ngbot verify
|
||||
- name: Confirm code builds with typescript as expected
|
||||
run: pnpm check-tooling-setup
|
||||
- name: Validate agent skills
|
||||
run: pnpm ng-dev ai skills validate
|
||||
- name: Check commit message
|
||||
run: pnpm ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Check code format
|
||||
run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
|
||||
- name: Check Package Licenses
|
||||
uses: angular/dev-infra/github-actions/linting/licenses@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/linting/licenses@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
allow-dependencies-licenses: 'pkg:npm/google-protobuf@'
|
||||
|
||||
@@ -47,13 +45,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
with:
|
||||
disable-package-manager-cache: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
@@ -61,7 +59,7 @@ jobs:
|
||||
- name: Test build
|
||||
run: pnpm devtools:build:chrome
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@bc22e01685c56e89e7813fd8e26f33dc47f87e15 # v7.1.5
|
||||
uses: cypress-io/github-action@2ad32e649e4db26c07674ebae31a297601dbcbaf # v6.10.8
|
||||
with:
|
||||
command: pnpm devtools:test:e2e
|
||||
start: pnpm bazel run //devtools/src:devserver
|
||||
@@ -73,11 +71,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run CI tests for framework
|
||||
@@ -97,11 +95,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run integration CI tests for framework
|
||||
@@ -112,11 +110,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run tests
|
||||
@@ -129,11 +127,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- name: Run tests
|
||||
@@ -144,11 +142,11 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e4dcda13e469f50a6bd92667e2ded8b98173bf2c
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@1ce250a660eca5f613794a32cbae6d0f7a449918
|
||||
- name: Install node modules
|
||||
run: pnpm install --frozen-lockfile
|
||||
- run: |
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ export const github = {
|
||||
name: 'angular',
|
||||
mainBranchName: 'main',
|
||||
mergeMode: 'caretaker-only',
|
||||
requireReleaseModeForRelease: false,
|
||||
requireReleaseModeForRelease: true,
|
||||
};
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
"packages/docs/**",
|
||||
"packages/elements/schematics/**",
|
||||
"packages/examples/**",
|
||||
"packages/forms/signals/src/api/rules/validation/standard_schema.ts",
|
||||
"packages/localize/**",
|
||||
"packages/private/**",
|
||||
"packages/service-worker/**",
|
||||
|
||||
+1
-7
@@ -30,16 +30,10 @@ vscode-ng-language-service/syntaxes/test/data/*.html
|
||||
# Ignore goldens MD files
|
||||
goldens/**/*.api.md
|
||||
|
||||
# Ignore golden symbol json files
|
||||
packages/**/*.golden_symbols.json
|
||||
|
||||
# adev generated files
|
||||
adev/src/content/aria/**/*.json
|
||||
adev/src/content/cli/**/*.json
|
||||
adev/src/content/cdk/**/*.json
|
||||
|
||||
# Antigravity rules
|
||||
.agent/rules/agents.md
|
||||
|
||||
CHANGELOG.md
|
||||
CHANGELOG_ARCHIVE.md
|
||||
CHANGELOG_ARCHIVE.md
|
||||
+23
-28
@@ -106,6 +106,7 @@ groups:
|
||||
- thePunderWoman
|
||||
- kirjs
|
||||
- JoostK
|
||||
- mmalerba
|
||||
- ~amishne
|
||||
- ~leonsenft
|
||||
- ~mattrbeck
|
||||
@@ -150,8 +151,10 @@ groups:
|
||||
- crisbeto
|
||||
- devversion
|
||||
- kirjs
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- ~pkozlowski-opensource
|
||||
- mmalerba
|
||||
- JeanMeche
|
||||
- ~amishne
|
||||
- ~leonsenft
|
||||
@@ -178,9 +181,9 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- ~alxhub
|
||||
- jelbourn
|
||||
- josephperrott
|
||||
- ~pkozlowski-opensource
|
||||
- alan-agius4
|
||||
reviews:
|
||||
request: -1 # request reviews from everyone
|
||||
required: 2 # require at least 2 approvals
|
||||
@@ -199,6 +202,7 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- ~JiaLiPassion
|
||||
- ~jelbourn
|
||||
- ~alxhub
|
||||
- AndrewKushnir
|
||||
- atscott
|
||||
@@ -207,6 +211,7 @@ groups:
|
||||
- kirjs
|
||||
- thePunderWoman
|
||||
- ~pkozlowski-opensource
|
||||
- mmalerba
|
||||
- ~amishne
|
||||
- ~leonsenft
|
||||
- ~mattrbeck
|
||||
@@ -243,8 +248,6 @@ groups:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'adev/**/{*,.*}',
|
||||
'tools/manual_api_docs/blocks/**/*.md',
|
||||
'tools/manual_api_docs/elements/**/*.md',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
@@ -256,12 +259,14 @@ groups:
|
||||
- crisbeto
|
||||
- kirjs
|
||||
- JeanMeche
|
||||
- jelbourn
|
||||
- thePunderWoman
|
||||
- devversion
|
||||
- josephperrott
|
||||
- ~pkozlowski-opensource
|
||||
- ~mgechev
|
||||
- MarkTechson
|
||||
- mmalerba
|
||||
- ~hawkgs
|
||||
- ~amishne
|
||||
- ~leonsenft
|
||||
@@ -297,13 +302,8 @@ groups:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files
|
||||
.exclude('.pullapprove.yml')
|
||||
.exclude('tools/manual_api_docs/blocks/**/*.md')
|
||||
.exclude('tools/manual_api_docs/elements/**/*.md'),
|
||||
[
|
||||
contains_any_globs(files.exclude('.pullapprove.yml'), [
|
||||
'{*,.*}',
|
||||
'.agent/**/{*,.*}',
|
||||
'.devcontainer/**/{*,.*}',
|
||||
'.github/**/{*,.*}',
|
||||
'.husky/**/{*,.*}',
|
||||
@@ -340,7 +340,6 @@ groups:
|
||||
- author not in ["angular-robot"]
|
||||
reviewers:
|
||||
users:
|
||||
- alan-agius4
|
||||
- devversion
|
||||
- josephperrott
|
||||
|
||||
@@ -375,9 +374,11 @@ groups:
|
||||
- AndrewKushnir
|
||||
- ~alxhub
|
||||
- atscott
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- ~pkozlowski-opensource
|
||||
- kirjs
|
||||
- mmalerba
|
||||
- crisbeto
|
||||
- devversion
|
||||
- JeanMeche
|
||||
@@ -411,8 +412,10 @@ groups:
|
||||
- AndrewKushnir
|
||||
- atscott
|
||||
- kirjs
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- ~pkozlowski-opensource
|
||||
- mmalerba
|
||||
- ~amishne
|
||||
- ~leonsenft
|
||||
- ~mattrbeck
|
||||
@@ -421,24 +424,6 @@ groups:
|
||||
required: 1 # Require that 1 person approve
|
||||
reviewed_for: required
|
||||
|
||||
# =========================================================
|
||||
# Agent Skills
|
||||
# =========================================================
|
||||
agent-skills:
|
||||
<<: *defaults
|
||||
conditions:
|
||||
- >
|
||||
contains_any_globs(files, [
|
||||
'skills/{*,.*}',
|
||||
'skills/**/{*,.*}',
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- marktechson
|
||||
- kirjs
|
||||
- ~JeanMeche
|
||||
- ~dgp1130
|
||||
|
||||
####################################################################################
|
||||
# Special Cases
|
||||
####################################################################################
|
||||
@@ -459,6 +444,7 @@ groups:
|
||||
- AndrewKushnir
|
||||
- andrewseguin
|
||||
- dgp1130
|
||||
- ~jelbourn
|
||||
- thePunderWoman
|
||||
- josephperrott
|
||||
|
||||
@@ -481,6 +467,10 @@ groups:
|
||||
- thePunderWoman # Jessica Janiuk
|
||||
- AndrewKushnir # Andrew Kushnir
|
||||
- atscott # Andrew Scott
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
rejected: 'requires: TGP'
|
||||
|
||||
# External team required reviews
|
||||
primitives-shared:
|
||||
@@ -498,6 +488,10 @@ groups:
|
||||
- tbondwilkinson # Tom Wilkinson
|
||||
- rahatarmanahmed # Rahat Ahmed
|
||||
- ENAML # Ethan Cline
|
||||
labels:
|
||||
pending: 'requires: TGP'
|
||||
approved: 'requires: TGP'
|
||||
rejected: 'requires: TGP'
|
||||
|
||||
####################################################################################
|
||||
# Override managed result groups
|
||||
@@ -520,6 +514,7 @@ groups:
|
||||
reviewers:
|
||||
users:
|
||||
- alxhub
|
||||
- jelbourn
|
||||
- josephperrott
|
||||
reviews:
|
||||
request: 0
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
This is the source code for the Angular framework. This guide outlines standard practices for AI agents working in this repository.
|
||||
|
||||
## Environment
|
||||
|
||||
- Use `pnpm` for package management.
|
||||
- Use `pnpm bazel test //target` to run tests.
|
||||
|
||||
## Key Documentation
|
||||
|
||||
- [Building and Testing](contributing-docs/building-and-testing-angular.md): definitive guide for running targets.
|
||||
- [Coding Standards](contributing-docs/coding-standards.md): style guide for TypeScript and other files.
|
||||
- [Commit Guidelines](contributing-docs/commit-message-guidelines.md): format for commit messages and PR titles.
|
||||
|
||||
## Testing
|
||||
|
||||
- **Zoneless & Async-First:** Assume a zoneless environment where state changes schedule updates asynchronously.
|
||||
- **Do NOT** use `fixture.detectChanges()` to manually trigger updates.
|
||||
- **ALWAYS** use the "Act, Wait, Assert" pattern:
|
||||
1. **Act:** Update state or perform an action.
|
||||
2. **Wait:** `await fixture.whenStable()` to allow the framework to process the scheduled update.
|
||||
3. **Assert:** Verify the output.
|
||||
- To keep tests fast, minimize the need for waiting:
|
||||
- Use `useAutoTick()` (from `packages/private/testing/src/utils.ts`) to fast-forward time via the mock clock.
|
||||
- When waiting is necessary, use real async tests (`it('...', async () => { ... })`) along with:
|
||||
- `await timeout(ms)` (from `packages/private/testing/src/utils.ts`) to wait a specific number of milliseconds.
|
||||
- `await fixture.whenStable()` to wait for framework stability.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
- Use the `gh` CLI (GitHub CLI) for creating and managing pull requests.
|
||||
-211
@@ -1,200 +1,3 @@
|
||||
<a name="21.2.2"></a>
|
||||
# 21.2.2 (2026-03-09)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1df1697c6e](https://github.com/angular/angular/commit/1df1697c6e3a6b1d302f7692b495146943faa12f) | fix | prevent mutation of children array in RecursiveVisitor |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c822bf8e76](https://github.com/angular/angular/commit/c822bf8e76611afde332b6625f5e7bae2fe9c3f3) | fix | always parenthesize object literals in TCB |
|
||||
| [05d022d5e6](https://github.com/angular/angular/commit/05d022d5e61cca7ac90d5b2b2ba3fc738b364ad9) | fix | ignore generated ngDevMode signal branch for code coverage |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [670d1660c4](https://github.com/angular/angular/commit/670d1660c40504e3f55e094c3ebbcccad14163f3) | feat | add 'blur' option to debounce rule |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.2.1"></a>
|
||||
# 21.2.1 (2026-03-04)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e2e9a9a531](https://github.com/angular/angular/commit/e2e9a9a531c9e9a69701e549f28354cc5d5edd77) | fix | adds transfer cache to httpResource to fix hydration |
|
||||
| [b4ec3cc4e4](https://github.com/angular/angular/commit/b4ec3cc4e41f2948ad0830eb14aa05d14fa3a9ed) | fix | prevent child animation elements from being orphaned |
|
||||
| [e923d88398](https://github.com/angular/angular/commit/e923d8839868c79989502ab3503e13d93c78516a) | fix | Prevent removal of elements during drag and drop |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [277ade97ac](https://github.com/angular/angular/commit/277ade97ac2a3a7f2a5b513acaa93e7663cdc55f) | fix | correctly cache blob responses in transfer cache ([#67002](https://github.com/angular/angular/pull/67002)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.2.0"></a>
|
||||
# 21.2.0 (2026-02-25)
|
||||
### common
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [18003a33bb](https://github.com/angular/angular/commit/18003a33bb0d6bb09def8a0e5939fa24069696eb) | feat | add an 'outlet' injector option for ngTemplateOutlet |
|
||||
| [8bbe6dc46c](https://github.com/angular/angular/commit/8bbe6dc46c9dc13bafa81a60c7613b84b5ca3761) | feat | Add Location strategies to manage trailing slash on write |
|
||||
| [51cc914807](https://github.com/angular/angular/commit/51cc91480761b7275c15b5600381207f8ca00ee5) | feat | support height in ImageLoaderConfig and built-in loaders |
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [72534e2a34](https://github.com/angular/angular/commit/72534e2a3458df4e1bb097973872f00bbb92be42) | feat | Add support for the `instanceof` binary operator |
|
||||
| [95b3f37d4a](https://github.com/angular/angular/commit/95b3f37d4a7d9a38f616d56df746dfcda3c2139b) | feat | Exhaustive checks for switch blocks |
|
||||
| [04ba09a8d9](https://github.com/angular/angular/commit/04ba09a8d9454013bebdd643eacb737642161952) | feat | support `AstVisitor.visitEmptyExpr()` |
|
||||
| [ce80136e7b](https://github.com/angular/angular/commit/ce80136e7b9f0024d49fce835cffa024c4505855) | fix | optimize away unnecessary restore/reset view calls |
|
||||
| [3242a61bae](https://github.com/angular/angular/commit/3242a61bae02253d13abb510b666376c665e61ac) | fix | variable counter visiting some expressions twice |
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [473dd3e1cb](https://github.com/angular/angular/commit/473dd3e1cbd4fe3fa88ae4d5358eee35c11acb1b) | fix | attach source spans to object literal keys in TCB |
|
||||
| [a904d9f77b](https://github.com/angular/angular/commit/a904d9f77b56feab407f75f8d0527fa512d5dafb) | fix | support nested component declaration |
|
||||
| [2ea6dfc6c9](https://github.com/angular/angular/commit/2ea6dfc6c9ca11e96a2654510c980419899f8d04) | fix | update diagnostic to flag no-op arrow functions in listeners |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8d5210c9fe](https://github.com/angular/angular/commit/8d5210c9fedd8abdd810d7a89ec7ee9a1234f5c1) | feat | add ChangeDetectionStrategy.Eager alias for Default |
|
||||
| [92d2498910](https://github.com/angular/angular/commit/92d2498910caed06c182b67e39726e1441418698) | feat | add host node to DeferBlockData ([#66546](https://github.com/angular/angular/pull/66546)) |
|
||||
| [ea2016a6dc](https://github.com/angular/angular/commit/ea2016a6dce58f95ecab7c773d5dcde274354e1a) | feat | add support for nested animations |
|
||||
| [81cabc1477](https://github.com/angular/angular/commit/81cabc14777a3b4966c29d60e1505aca8c29b71c) | feat | add support for TypeScript 6 |
|
||||
| [1ba9b7ac50](https://github.com/angular/angular/commit/1ba9b7ac5001b315cc9df78c518964dbf479d647) | feat | resource composition via snapshots |
|
||||
| [d9923b72a2](https://github.com/angular/angular/commit/d9923b72a20972ba6bf728d78f1afac6936ade18) | feat | support arrow functions in expressions |
|
||||
| [a7e8abbb7e](https://github.com/angular/angular/commit/a7e8abbb7e738ba338c3f50c76934c99925954e5) | fix | correctly handle SkipSelf when resolving from embedded view injector |
|
||||
| [0806ee3826](https://github.com/angular/angular/commit/0806ee38269b664f535e10d4d501b88370d3b44c) | fix | prevent animated element duplication with dynamic components in zoneless mode |
|
||||
| [ed78fa05c7](https://github.com/angular/angular/commit/ed78fa05c710ebafb355ae00a85b190a118b6cc4) | fix | Remove note to skip arrow functions in best practices |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [f56bb07d83](https://github.com/angular/angular/commit/f56bb07d83a015b0ac12e74fdb0cf1550ff36b97) | feat | add field param to submit action and onInvalid |
|
||||
| [ba009b6031](https://github.com/angular/angular/commit/ba009b603119299a03f9d844f93882d42d47d150) | feat | add form directive |
|
||||
| [22afbb2f36](https://github.com/angular/angular/commit/22afbb2f36be89c2ae575df343571a918dec5985) | feat | add parsing support to native inputs ([#66917](https://github.com/angular/angular/pull/66917)) |
|
||||
| [95c386469c](https://github.com/angular/angular/commit/95c386469c7a2f09dd731601c2061bdb10d25717) | feat | Add passing focus options to form field |
|
||||
| [95ecce8334](https://github.com/angular/angular/commit/95ecce8334299defe55fb2b74264e5258ffd137c) | feat | allow setting submit options at form-level |
|
||||
| [ebae211add](https://github.com/angular/angular/commit/ebae211add37700858adeb8fc5d87bf503a59721) | feat | introduce parse errors in signal forms |
|
||||
| [3937afc316](https://github.com/angular/angular/commit/3937afc3167ce409eebb06d91d5fb122eea4e33d) | feat | introduce SignalFormControl for Reactive Forms compatibility |
|
||||
| [30f0914754](https://github.com/angular/angular/commit/30f09147545b67185f93efb9796e37c1db76733a) | feat | support binding null to number input ([#66917](https://github.com/angular/angular/pull/66917)) |
|
||||
| [dd208ca259](https://github.com/angular/angular/commit/dd208ca2595258fcd1e289374f812ce0b56c7011) | feat | update submit function to accept options object |
|
||||
| [27397b3f4f](https://github.com/angular/angular/commit/27397b3f4f3182ce00d6e2f8690285c316e2a274) | fix | clear parse errors when model updates ([#66917](https://github.com/angular/angular/pull/66917)) |
|
||||
| [63d8005703](https://github.com/angular/angular/commit/63d80057039928b3e878b59c1fe6b93ef1c6b701) | fix | preserve custom-control focus context in signal forms |
|
||||
| [631f60d1f9](https://github.com/angular/angular/commit/631f60d1f9be72cb68330308a6ff18cc195babb8) | fix | preserve parse errors when parse returns value |
|
||||
| [adfb83146b](https://github.com/angular/angular/commit/adfb83146b0c149734f43961563b389e00cc1d85) | fix | simplify design of parse errors |
|
||||
| [fb05fc86d0](https://github.com/angular/angular/commit/fb05fc86d0f12ffafd94c7c1420118d8a79f7e59) | fix | sort error summary by DOM order |
|
||||
| [567f292e8e](https://github.com/angular/angular/commit/567f292e8e0f9d2b5ddebadfa1c6d6dd6c456f39) | fix | support custom controls as host directives |
|
||||
| [bdfb60f3e3](https://github.com/angular/angular/commit/bdfb60f3e33065e047183dc1890c36e527e2b304) | fix | use consistent error format returned from parse |
|
||||
| [d75046bc09](https://github.com/angular/angular/commit/d75046bc091699bbadcb5f2032be627e983ee6fa) | fix | warn when showing hidden field state |
|
||||
### language-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [ebc90c26f5](https://github.com/angular/angular/commit/ebc90c26f5ff1ba1e0ca9b775a44e301ebfb9473) | feat | Add completions and hover info for inline styles |
|
||||
| [26fd0839c3](https://github.com/angular/angular/commit/26fd0839c32d2ebeaa5e3ecc10ed70ab9ca17749) | feat | Add folding range support for inline styles |
|
||||
| [573aadef7e](https://github.com/angular/angular/commit/573aadef7eb8b6b5e83b82a16f95d2a556f27c01) | feat | Add quick info for inline styles |
|
||||
| [6fb39d9b62](https://github.com/angular/angular/commit/6fb39d9b62cbb634e95ec00fe5ef85d84da3bdbd) | feat | Support client-side file watching via `onDidChangeWatchedFiles` |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [496967e7b1](https://github.com/angular/angular/commit/496967e7b13dfe1ebdde69724cd62880914beb60) | feat | add JSON schema for angularCompilerOptions |
|
||||
| [8c21866f49](https://github.com/angular/angular/commit/8c21866f49ff74344551395ae0a5df1841d54c0d) | feat | add linked editing ranges for HTML tag synchronization |
|
||||
| [d2137928e8](https://github.com/angular/angular/commit/d2137928e8f075527016a3c011dd8efc4d4e1ebd) | perf | use lightweight project warmup for Angular analysis |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [b51bab583d](https://github.com/angular/angular/commit/b51bab583d84e38f16dea489e4119edc34e2a491) | feat | Add partial ActivatedRouteSnapshot information to `canMatch` params |
|
||||
| [cf9620f7d0](https://github.com/angular/angular/commit/cf9620f7d072897f13b7f281b7bca6f51f69cfd0) | feat | Make match options optional in isActive |
|
||||
| [907a94dcec](https://github.com/angular/angular/commit/907a94dcec2926a5c7d0c4d36249bd62e31a2ae3) | feat | Update `IsActiveMatchOptions` APIs to accept a Partial |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.5"></a>
|
||||
# 21.1.5 (2026-02-18)
|
||||
No user facing changes in this release
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.4"></a>
|
||||
# 21.1.4 (2026-02-11)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [caab23dfe6](https://github.com/angular/angular/commit/caab23dfe6acf06c3b859af091f5e078b08f1c4c) | fix | add geolocation element to schema |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b99eaa019](https://github.com/angular/angular/commit/2b99eaa019b5551a2e2fcf9ff8cd0a796e1e857b) | fix | capture animation dependencies eagerly to avoid destroyed injector |
|
||||
| [d6aeac504c](https://github.com/angular/angular/commit/d6aeac504c6181f15e5d8afdca3d9c3e3b32652c) | fix | Fix flakey test due to document injection |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0d1acd0165](https://github.com/angular/angular/commit/0d1acd0165511b57ce853f29486d9b92d0215959) | feat | support signal-based schemas in validateStandardSchema |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3905015ccc](https://github.com/angular/angular/commit/3905015ccc53399a606dd8e4f3c4d0cce628a08e) | fix | correctly parse ArrayBuffer and Blob in transfer cache |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.3"></a>
|
||||
# 21.1.3 (2026-02-04)
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [2b254bc050](https://github.com/angular/angular/commit/2b254bc0508b73aab8991c3b1a9a703c339cb735) | fix | `linkedSignal.update` should propagate errors |
|
||||
| [e5110b4fa1](https://github.com/angular/angular/commit/e5110b4fa155e4669ed507f3460d2d29026a28ab) | fix | export DirectiveWithBindings |
|
||||
| [2cf4da0ea1](https://github.com/angular/angular/commit/2cf4da0ea11f5746eb7ae4dfd775f757576e4d98) | fix | hold constructors weakly in DepsTracker cache |
|
||||
| [70a5b651be](https://github.com/angular/angular/commit/70a5b651be29f1421eb25150b560bfe154aad6bc) | fix | prevent element duplication with dynamic components |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [6f75b6e3f6](https://github.com/angular/angular/commit/6f75b6e3f60dc2a4f33e13562649931dc95eb52b) | fix | Resolves debounce promise on abort in debounceForDuration |
|
||||
### localize
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [4c7126d23b](https://github.com/angular/angular/commit/4c7126d23be3e43b1d5bd6f2fb13119d185c3682) | fix | add support for unit-test builder in ng-add schematic |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d6268c0bbb](https://github.com/angular/angular/commit/d6268c0bbbdc92abaaaeb8eebee3bc45decab9c9) | fix | limit UrlParser recursion depth to prevent stack overflow |
|
||||
| [49a36f4cc7](https://github.com/angular/angular/commit/49a36f4cc7254420bc34fff4e0f0242e00970280) | perf | Use .bind to avoid holding other closures in memory |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.2"></a>
|
||||
# 21.1.2 (2026-01-28)
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [9f99b14882](https://github.com/angular/angular/commit/9f99b14882bc4f883aa33295856010a8bca900fa) | fix | only touch visible, interactive fields on submit |
|
||||
### language-service
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c57b0355b5](https://github.com/angular/angular/commit/c57b0355b51f5aee5abd822f203fc3bcc3e85acd) | fix | Detect local project version on creation |
|
||||
### router
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [21ecdc036a](https://github.com/angular/angular/commit/21ecdc036a46c487d6c5b6bd25c2bbc3e53a60f9) | fix | Do not intercept reload events with Navigation integration |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.1"></a>
|
||||
# 21.1.1 (2026-01-21)
|
||||
### compiler-cli
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [0e1f1ed573](https://github.com/angular/angular/commit/0e1f1ed5732f3bb4d5dfbd1f0ee5a5be840594e4) | fix | drop .tsx extension for generated relative imports |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [05adfcf8f2](https://github.com/angular/angular/commit/05adfcf8f26013ac20c38f2b08847b5142e4fd85) | fix | handle Set in class bindings |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d89a80a970](https://github.com/angular/angular/commit/d89a80a970d9590df0509d8b94090904a99b7aca) | feat | Ability to manually register a form field binding in signal forms |
|
||||
| [cb75f9ce85](https://github.com/angular/angular/commit/cb75f9ce85160b2e4359610c06294929ac1169c0) | fix | fix control value syncing on touch |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.1.0"></a>
|
||||
# 21.1.0 (2026-01-14)
|
||||
## Deprecations
|
||||
@@ -245,20 +48,6 @@ No user facing changes in this release
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.0.9"></a>
|
||||
# 21.0.9 (2026-01-14)
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [82d556a8fb](https://github.com/angular/angular/commit/82d556a8fb38cd2024e3d098c55254305ba12b6b) | fix | Ensure the control instruction comes after the other bindings |
|
||||
| [0055f3cc79](https://github.com/angular/angular/commit/0055f3cc79f387b8dec6ce5e1a33fad5486f9341) | fix | Rename signal form [field] to [formField] |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e4bfa5c9e7](https://github.com/angular/angular/commit/e4bfa5c9e7feec48d3c4e9425a21a2ccf6532bdb) | fix | prevent duplicate imports in common-to-standalone migration |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="21.0.8"></a>
|
||||
# 21.0.8 (2026-01-08)
|
||||
### core
|
||||
|
||||
+24
-23
@@ -5,27 +5,27 @@ module(
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_pkg", version = "1.2.0")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.7.3")
|
||||
bazel_dep(name = "aspect_rules_ts", version = "3.8.5")
|
||||
bazel_dep(name = "aspect_rules_js", version = "2.9.2")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.6.2")
|
||||
bazel_dep(name = "aspect_rules_ts", version = "3.8.1")
|
||||
bazel_dep(name = "aspect_rules_js", version = "2.8.3")
|
||||
bazel_dep(name = "aspect_rules_esbuild", version = "0.25.0")
|
||||
bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4")
|
||||
bazel_dep(name = "aspect_rules_jasmine", version = "2.0.2")
|
||||
bazel_dep(name = "aspect_rules_rollup", version = "2.0.1")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.9.0")
|
||||
bazel_dep(name = "aspect_bazel_lib", version = "2.22.5")
|
||||
bazel_dep(name = "tar.bzl", version = "0.9.0")
|
||||
bazel_dep(name = "yq.bzl", version = "0.3.5")
|
||||
bazel_dep(name = "aspect_bazel_lib", version = "2.22.2")
|
||||
bazel_dep(name = "tar.bzl", version = "0.7.0")
|
||||
bazel_dep(name = "yq.bzl", version = "0.3.4")
|
||||
bazel_dep(name = "rules_angular")
|
||||
git_override(
|
||||
module_name = "rules_angular",
|
||||
commit = "d746c4f75e42cffe389d1ab077f4639be2bc78d1",
|
||||
remote = "https://github.com/angular/rules_angular.git",
|
||||
commit = "7133b97252508f8528e5c5818a9a73cacc2e2a0e",
|
||||
remote = "https://github.com/devversion/rules_angular.git",
|
||||
)
|
||||
|
||||
bazel_dep(name = "devinfra")
|
||||
git_override(
|
||||
module_name = "devinfra",
|
||||
commit = "e4dcda13e469f50a6bd92667e2ded8b98173bf2c",
|
||||
commit = "1ce250a660eca5f613794a32cbae6d0f7a449918",
|
||||
remote = "https://github.com/angular/dev-infra.git",
|
||||
)
|
||||
|
||||
@@ -33,14 +33,14 @@ bazel_dep(name = "rules_sass")
|
||||
git_override(
|
||||
module_name = "rules_sass",
|
||||
commit = "1184a80751a21af8348f308abc5b38a41f26850e",
|
||||
remote = "https://github.com/angular/rules_sass.git",
|
||||
remote = "https://github.com/devversion/rules_sass.git",
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_browsers")
|
||||
git_override(
|
||||
module_name = "rules_browsers",
|
||||
commit = "8231142fc5516323b040883bf774ba8362645387",
|
||||
remote = "https://github.com/angular/rules_browsers.git",
|
||||
commit = "5f0e50d17d15c70e6ab5546f1659338ae94c4072",
|
||||
remote = "https://github.com/devversion/rules_browsers.git",
|
||||
)
|
||||
|
||||
yq = use_extension("@yq.bzl//yq:extensions.bzl", "yq")
|
||||
@@ -49,15 +49,15 @@ use_repo(yq, "yq_toolchains")
|
||||
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
|
||||
node.toolchain(
|
||||
node_repositories = {
|
||||
"22.22.1-darwin_arm64": ("node-v22.22.1-darwin-arm64.tar.gz", "node-v22.22.1-darwin-arm64", "679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"),
|
||||
"22.22.1-darwin_amd64": ("node-v22.22.1-darwin-x64.tar.gz", "node-v22.22.1-darwin-x64", "07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"),
|
||||
"22.22.1-linux_arm64": ("node-v22.22.1-linux-arm64.tar.xz", "node-v22.22.1-linux-arm64", "0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"),
|
||||
"22.22.1-linux_ppc64le": ("node-v22.22.1-linux-ppc64le.tar.xz", "node-v22.22.1-linux-ppc64le", "a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"),
|
||||
"22.22.1-linux_s390x": ("node-v22.22.1-linux-s390x.tar.xz", "node-v22.22.1-linux-s390x", "e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"),
|
||||
"22.22.1-linux_amd64": ("node-v22.22.1-linux-x64.tar.xz", "node-v22.22.1-linux-x64", "9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"),
|
||||
"22.22.1-windows_amd64": ("node-v22.22.1-win-x64.zip", "node-v22.22.1-win-x64", "877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"),
|
||||
"22.22.0-darwin_arm64": ("node-v22.22.0-darwin-arm64.tar.gz", "node-v22.22.0-darwin-arm64", "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"),
|
||||
"22.22.0-darwin_amd64": ("node-v22.22.0-darwin-x64.tar.gz", "node-v22.22.0-darwin-x64", "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"),
|
||||
"22.22.0-linux_arm64": ("node-v22.22.0-linux-arm64.tar.xz", "node-v22.22.0-linux-arm64", "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"),
|
||||
"22.22.0-linux_ppc64le": ("node-v22.22.0-linux-ppc64le.tar.xz", "node-v22.22.0-linux-ppc64le", "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"),
|
||||
"22.22.0-linux_s390x": ("node-v22.22.0-linux-s390x.tar.xz", "node-v22.22.0-linux-s390x", "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"),
|
||||
"22.22.0-linux_amd64": ("node-v22.22.0-linux-x64.tar.xz", "node-v22.22.0-linux-x64", "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"),
|
||||
"22.22.0-windows_amd64": ("node-v22.22.0-win-x64.zip", "node-v22.22.0-win-x64", "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"),
|
||||
},
|
||||
node_version = "22.22.1",
|
||||
node_version = "22.22.0",
|
||||
)
|
||||
use_repo(node, "nodejs_toolchains")
|
||||
use_repo(node, "nodejs_darwin_amd64")
|
||||
@@ -71,8 +71,8 @@ use_repo(node, "nodejs_windows_amd64")
|
||||
pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm")
|
||||
pnpm.pnpm(
|
||||
name = "pnpm",
|
||||
pnpm_version = "10.30.3",
|
||||
pnpm_version_integrity = "sha512-yWHR4KLY41TsqlFmuCJRZmi39Ey1vZUSLVkN2Bki9gb1RzttI+xKW+Bef80Y6EiNR9l4u+mBhy8RRdBumnQAFw==",
|
||||
pnpm_version = "10.28.0",
|
||||
pnpm_version_integrity = "sha512-Bd9x0UIfITmeBT/eVnzqNNRG+gLHZXFEG/wceVbpjjYwiJgtlARl/TRIDU2QoGaLwSNi+KqIAApk6D0LDke+SA==",
|
||||
)
|
||||
use_repo(pnpm, "pnpm")
|
||||
|
||||
@@ -83,6 +83,7 @@ npm.npm_translate_lock(
|
||||
"//:.pnpmfile.cjs",
|
||||
"//:package.json",
|
||||
"//:pnpm-workspace.yaml",
|
||||
"//:tools/pnpm-patches/dagre-d3-es+7.0.11.patch",
|
||||
"//adev:package.json",
|
||||
"//adev/shared-docs:package.json",
|
||||
"//adev/shared-docs/pipeline/api-gen:package.json",
|
||||
|
||||
Generated
+297
-303
@@ -13,28 +13,28 @@
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "e118477db5c49419a88d78ebc7a2c2cea9d49600fe0f490c1903324a2c16ecd9",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.11.0/MODULE.bazel": "cb1ba9f9999ed0bc08600c221f532c1ddd8d217686b32ba7d45b0713b5131452",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.2/MODULE.bazel": "30dfabbfae0139b1f0036e01c201dd4c0167da3017f0b7ef3820d78e07622989",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.17.1/MODULE.bazel": "9b027af55f619c7c444cead71061578fab6587e5e1303fa4ed61d49d2b1a7262",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/MODULE.bazel": "004ba890363d05372a97248c37205ae64b6fa31047629cd2c0895a9d0c7779e8",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.2/MODULE.bazel": "6b735f3fdd64978e217c9725f4ff0d84bf606554c8e77d20e90977841d7ff2ed",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.2/source.json": "58fffa2d722cff47cb8d921c8bbed7701c53f233009d9ca82beb4a0fb8fb9418",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838",
|
||||
"https://bcr.bazel.build/modules/aspect_bazel_lib/2.9.3/MODULE.bazel": "66baf724dbae7aff4787bf2245cc188d50cb08e07789769730151c0943587c14",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.0/MODULE.bazel": "5fef5ec709c837312823f9bcf0f276661e2cb48ad52f17c4e01176bbf1e9bf58",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.0/source.json": "5e42968c6d23ab8bd95c02634b16864d866334347827cb6a8425b86c11cc4363",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/MODULE.bazel": "fbb819eb8b7e5d7f67fdd38f7cecb413e287594cd666ce192c72c8828527775a",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.2/MODULE.bazel": "45f054400ff242c4433f6d7f20f6123a9a72739cb7a1f44247d738db1644f46c",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.2/source.json": "3ed399a5654259a822448f9cdbf21f6c738f16ccd7f89249c7507e374cbdd1e3",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.4.2/MODULE.bazel": "0d01db38b96d25df7ed952a5e96eac4b3802723d146961974bf020f6dd07591d",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.6.2/MODULE.bazel": "ed2a871f4ab8fbde0cab67c425745069d84ea64b64313fa1a2954017326511f5",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.9.2/MODULE.bazel": "93fd5b85e6e912fb0712cbab453c43271d4ea33a093f84fd587638fbc9f8c145",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.9.2/source.json": "4bff7c03ab387b60deb15649ba575688e62f2a71a7544cbc7a660b19ec473808",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.8.3/MODULE.bazel": "807ce5f624124a8bc586c743394d174e85f0f9c6c4e0e2410b4088aebe790ac8",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_js/2.8.3/source.json": "c35cb4e04f61a09c17f8c569894b80de884b1e3dee2d33829704786e3f778037",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_rollup/2.0.1/MODULE.bazel": "296e3a053658c2af989ba9bd62a205e6d1fa84bdd6dd5249196546e6b84770ec",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_rollup/2.0.1/source.json": "2fe8ac1ccb4de74bf884761e070010280b272d94e3997205b361b91c75409726",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.6.3/MODULE.bazel": "d09db394970f076176ce7bab5b5fa7f0d560fd4f30b8432ea5e2c2570505b130",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.7.0/MODULE.bazel": "5aace216caf88638950ef061245d23c36f57c8359e56e97f02a36f70bb09c50f",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.8.5/MODULE.bazel": "bcf8f0b6b9375f0f74451e2f70671efae9bb366acef8fdc04675305eaf137f06",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.8.5/source.json": "fa35e43f6359f654e4b70ce55efdf280d0b06c0b3ef9fc0b06ba52327a0e6311",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.8.1/MODULE.bazel": "796622c65ae3008374fc2d77c32ddb4ef6da9fe891826ce648f70033a48b3667",
|
||||
"https://bcr.bazel.build/modules/aspect_rules_ts/3.8.1/source.json": "a7c4f332f5c21f4e63d073f8dda40bf278d5307499fb307b35058dba558f417a",
|
||||
"https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.3/MODULE.bazel": "20f53b145f40957a51077ae90b37b7ce83582a1daf9350349f0f86179e19dd0d",
|
||||
"https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.6/MODULE.bazel": "cafb8781ad591bc57cc765dca5fefab08cf9f65af363d162b79d49205c7f8af7",
|
||||
"https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679",
|
||||
@@ -47,11 +47,9 @@
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.39.0/source.json": "f63cbeb4c602098484d57001e5a07d31cb02bbccde9b5e2c9bf0b29d05283e93",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.34.0/source.json": "dfa5c4b01110313153b484a735764d247fee5624bbab63d25289e43b151a657a",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
|
||||
@@ -77,8 +75,7 @@
|
||||
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
|
||||
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
|
||||
"https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8",
|
||||
"https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/MODULE.bazel": "f1b7bb2dd53e8f2ef984b39485ec8a44e9076dda5c4b8efd2fb4c6a6e856a31d",
|
||||
"https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/source.json": "ebe931bfe362e4b41e59ee00a528db6074157ff2ced92eb9e970acab2e1089c9",
|
||||
"https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2",
|
||||
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
|
||||
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
|
||||
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
|
||||
@@ -125,9 +122,7 @@
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.16/source.json": "d03d5cde49376d87e14ec14b666c56075e5e3926930327fd5d0484a1ff2ac1cc",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.1.1/source.json": "d61627377bd7dd1da4652063e368d9366fc9a73920bfa396798ad92172cf645c",
|
||||
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
|
||||
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
|
||||
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
|
||||
@@ -162,11 +157,10 @@
|
||||
"https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.3.3/MODULE.bazel": "b66eadebd10f1f1b25f52f95ab5213a57e82c37c3f656fcd9a57ad04d2264ce7",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.5.2/MODULE.bazel": "7f9ea68a0ce6d82905ce9f74e76ab8a8b4531ed4c747018c9d76424ad0b3370d",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.7.3/source.json": "a3f966f4415a8a6545e560ee5449eac95cc633f96429d08e87c87775c72f5e09",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.6.2/MODULE.bazel": "9fdb5e1d50246a25761f150fcc820dc47e4052330a8408451e628804f9ca64a6",
|
||||
"https://bcr.bazel.build/modules/rules_nodejs/6.6.2/source.json": "6e8c1ecc64ff8da147c1620f862ad77d7b19c5d1b52b3aa5e847d5b3d0de4cc3",
|
||||
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
|
||||
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
|
||||
"https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e",
|
||||
@@ -200,14 +194,14 @@
|
||||
"https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.9.0/MODULE.bazel": "452a22d7f02b1c9d7a22ab25edf20f46f3e1101f0f67dc4bfbf9a474ddf02445",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.9.0/source.json": "c732760a374831a2cf5b08839e4be75017196b4d796a5aa55235272ee17cd839",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.7.0/MODULE.bazel": "cc1acd85da33c80e430b65219a620d54d114628df24a618c3a5fa0b65e988da9",
|
||||
"https://bcr.bazel.build/modules/tar.bzl/0.7.0/source.json": "9becb80306f42d4810bfa16379fb48aad0b01ce5342bc12fe47dcd6af3ac4d7a",
|
||||
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.2.0/MODULE.bazel": "6f3a675677db8885be4d607fde14cc51829715e3a879fb016eb9bf336786ce6d",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.3.2/MODULE.bazel": "0384efa70e8033d842ea73aa4b7199fa099709e236a7264345c03937166670b6",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.3.5/MODULE.bazel": "130c603e54be717bdf84100210f06598a0d2b4b4e01888fb01b70f50f41767ec",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.3.5/source.json": "1ae7bdc03cb26aaa8bd2bceadf65e90d90f0b2d03008ba9a0564da2e21396c39",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.3.4/MODULE.bazel": "d3a270662f5d766cd7229732d65a5a5bc485240c3007343dd279edfb60c9ae27",
|
||||
"https://bcr.bazel.build/modules/yq.bzl/0.3.4/source.json": "786dafdc2843722da3416e4343ee1a05237227f068590779a6e8496a2064c0f9",
|
||||
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
|
||||
@@ -217,7 +211,7 @@
|
||||
"moduleExtensions": {
|
||||
"@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "fzdwsWU1Px4bYL57Cw1rvU/mgOqB7f0AF51JxT5kAs8=",
|
||||
"bzlTransitiveDigest": "9odiC0alKLq5PUYv/CZiw2yiMHsGpxvEhPsqt//fRRk=",
|
||||
"usagesDigest": "ToTaCONCN/E05krnHXLM1kpV1zrHNxHrGpUip973II4=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
@@ -418,8 +412,8 @@
|
||||
},
|
||||
"@@aspect_rules_js+//npm:extensions.bzl%pnpm": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "9Zmqluz9ltvCoc6pskOslTkQpkH6CIINjWVkgam9aa4=",
|
||||
"usagesDigest": "k3HnPWCDfdjPprODR4rLNwRc8pEk4QMKpK9YbIwIkkk=",
|
||||
"bzlTransitiveDigest": "VaGKuK2sKVTWlq9QBZfNc4fhigCeN9Wt4YhnhdGUkv8=",
|
||||
"usagesDigest": "V3eYj3dhR+UR/L7u17ZGfCuqJZpobNrN/6oEZPkZgDc=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -428,11 +422,11 @@
|
||||
"repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule",
|
||||
"attributes": {
|
||||
"package": "pnpm",
|
||||
"version": "10.30.3",
|
||||
"version": "10.28.0",
|
||||
"root_package": "",
|
||||
"link_workspace": "",
|
||||
"link_packages": {},
|
||||
"integrity": "sha512-yWHR4KLY41TsqlFmuCJRZmi39Ey1vZUSLVkN2Bki9gb1RzttI+xKW+Bef80Y6EiNR9l4u+mBhy8RRdBumnQAFw==",
|
||||
"integrity": "sha512-Bd9x0UIfITmeBT/eVnzqNNRG+gLHZXFEG/wceVbpjjYwiJgtlARl/TRIDU2QoGaLwSNi+KqIAApk6D0LDke+SA==",
|
||||
"url": "",
|
||||
"commit": "",
|
||||
"patch_args": [
|
||||
@@ -455,7 +449,7 @@
|
||||
"repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links",
|
||||
"attributes": {
|
||||
"package": "pnpm",
|
||||
"version": "10.30.3",
|
||||
"version": "10.28.0",
|
||||
"dev": false,
|
||||
"root_package": "",
|
||||
"link_packages": {},
|
||||
@@ -572,10 +566,10 @@
|
||||
},
|
||||
"@@aspect_rules_ts+//ts:extensions.bzl%ext": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "6NyLUdrb79stFKm8oWIBK2q65cT5Upbr8IR2Qwsywu8=",
|
||||
"usagesDigest": "ZXlhH7TrNEERA0ibuRRxAjYv2fVuXoFGNd3v+0UK1/g=",
|
||||
"bzlTransitiveDigest": "7k3bewVApw4Kc6Rpho1Rrs1nrW/5jphUA5Mh1iHE2U4=",
|
||||
"usagesDigest": "BIPOUwqzuuYqLOw/0p3h5GwHIDeBVXvNcxNoG5YlsHQ=",
|
||||
"recordedFileInputs": {
|
||||
"@@rules_browsers+//package.json": "772d873d450a539e2133635aeb5e63744cf1cec86e6b37aeecd9267a147fb0d7"
|
||||
"@@rules_browsers+//package.json": "84dc1ba9b1c667a25894e97218bd8f247d54f24bb694efb397a881be3c06a4c5"
|
||||
},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -639,7 +633,7 @@
|
||||
"@@aspect_tools_telemetry+//:extension.bzl%telemetry": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=",
|
||||
"usagesDigest": "fkarigrHiiNAt/BwClRuO51QOEo6226baK6LoK/IWdU=",
|
||||
"usagesDigest": "c8kIEi+rX5/1OpfMZW0mHrM7sAvw+nu7pOep2xSjFb4=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -648,10 +642,10 @@
|
||||
"repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository",
|
||||
"attributes": {
|
||||
"deps": {
|
||||
"aspect_rules_ts": "3.8.5",
|
||||
"aspect_rules_js": "2.9.2",
|
||||
"aspect_rules_ts": "3.8.1",
|
||||
"aspect_rules_js": "2.8.3",
|
||||
"aspect_rules_esbuild": "0.25.0",
|
||||
"aspect_rules_jasmine": "2.0.4",
|
||||
"aspect_rules_jasmine": "2.0.2",
|
||||
"aspect_tools_telemetry": "0.3.3"
|
||||
}
|
||||
}
|
||||
@@ -673,7 +667,7 @@
|
||||
},
|
||||
"@@pybind11_bazel+//:python_configure.bzl%extension": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "D2/qWHU6yQFwRG7Bb+caqrYMha5avsASao2vERrxK24=",
|
||||
"bzlTransitiveDigest": "c9ZWWeXeu6bctL4/SsY2otFWyeFN0JJ20+ymGyJZtWk=",
|
||||
"usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=",
|
||||
"recordedFileInputs": {
|
||||
"@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e"
|
||||
@@ -733,8 +727,8 @@
|
||||
},
|
||||
"@@rules_browsers+//browsers:extensions.bzl%browsers": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "Bm6fiKpWy96aLohOlLCP36ARVxRLZm/R+smhsb2HzmI=",
|
||||
"usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=",
|
||||
"bzlTransitiveDigest": "agkaLQ8wE1r/5IX6pkERzFxI/z0M42Em+ICNO6TXsVo=",
|
||||
"usagesDigest": "FS7q5WaIwg3KirS3njhuPFkTIBYvDaTInVGrlzu0XL8=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -742,9 +736,9 @@
|
||||
"rules_browsers_chrome_linux": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "1ac33f89306327af43be159c03ca4a26486de0858f42fe52394acdef50364143",
|
||||
"sha256": "0a2ff0fc9eb5958b7b420f20e3968f424be7423fef89739e71565a48aa073a57",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/linux64/chrome-headless-shell-linux64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/linux64/chrome-headless-shell-linux64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell"
|
||||
@@ -760,9 +754,9 @@
|
||||
"rules_browsers_chrome_mac": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "169ff49c465cfda52931395e61861e146dfc5013e92c01ca792db5acea858d0b",
|
||||
"sha256": "e6076b1201d86f74c5eab982a239d5af83e66b1aa4d780bcb792698790e01d87",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-x64/chrome-headless-shell-mac-x64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-x64/chrome-headless-shell-mac-x64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell"
|
||||
@@ -778,9 +772,9 @@
|
||||
"rules_browsers_chrome_mac_arm": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "aeaaaaa4d68193a21bed04c44ddeb1230232707b4ea1d845a92925787509cd8e",
|
||||
"sha256": "b74dbcf5543d916b02d0a133e2e7c6a4de251f06733f72c2c15ea8c42213f63b",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-arm64/chrome-headless-shell-mac-arm64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-arm64/chrome-headless-shell-mac-arm64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell"
|
||||
@@ -796,9 +790,9 @@
|
||||
"rules_browsers_chrome_win64": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "4d6d79bcbcb22084df6e3a3d3a2caff67d6c0fa488d63f0c7ec1526f9553db8c",
|
||||
"sha256": "df1e612dc3b1615e182a1f11821052995913c39df37caa52699de21a68d030d2",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/win64/chrome-headless-shell-win64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/win64/chrome-headless-shell-win64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe"
|
||||
@@ -814,9 +808,9 @@
|
||||
"rules_browsers_chromedriver_linux": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "0607ccf6810a07ae08cac6443beac8b23f88dd53c7f1e0299e22d65f7cd2d020",
|
||||
"sha256": "69c504306399d979a2766fea603c3fb9d3d87d46c75bddc9f2a049b4f636d57c",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/linux64/chromedriver-linux64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/linux64/chromedriver-linux64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROMEDRIVER": "chromedriver-linux64/chromedriver"
|
||||
@@ -830,9 +824,9 @@
|
||||
"rules_browsers_chromedriver_mac": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "0f512a9dd683ed4c41e609d8d02c07807497dbad3ab2f95f0d583486be7b8cff",
|
||||
"sha256": "5fc9d6f594fc5f2568a15145f25116dd8e9c9a60baa8da4bb21a17650fb00e7e",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-x64/chromedriver-mac-x64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-x64/chromedriver-mac-x64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROMEDRIVER": "chromedriver-mac-x64/chromedriver"
|
||||
@@ -846,9 +840,9 @@
|
||||
"rules_browsers_chromedriver_mac_arm": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "7d6fc6d17de1733eb6739d1ea16d085c8df1568bcf9fa0d130c2784b27f38268",
|
||||
"sha256": "14e92294c2c3639ca4e7d27e850588b619d698e2f8905cee368f07db2e1bf1e9",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-arm64/chromedriver-mac-arm64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-arm64/chromedriver-mac-arm64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver"
|
||||
@@ -862,9 +856,9 @@
|
||||
"rules_browsers_chromedriver_win64": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "f4e9fb7bbf692fde7979b24e8d737b3cef4baafbc7a370e5d0abc4a8450fd830",
|
||||
"sha256": "cf641d2e176db95bcc158cd90eafd347ad4928fa0458a5f3bfd56c6d983e70db",
|
||||
"urls": [
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/win64/chromedriver-win64.zip"
|
||||
"https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/win64/chromedriver-win64.zip"
|
||||
],
|
||||
"named_files": {
|
||||
"CHROMEDRIVER": "chromedriver-win64/chromedriver.exe"
|
||||
@@ -878,9 +872,9 @@
|
||||
"rules_browsers_firefox_linux": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "f055b9c0d7346a10d22edc7f10e08679af2ea495367381ab2be9cab3ec6add97",
|
||||
"sha256": "8d56f479cc398a537a60a3fa20dca92d8a41925113d3a67f534881a4e4d7e344",
|
||||
"urls": [
|
||||
"https://archive.mozilla.org/pub/firefox/releases/147.0/linux-x86_64/en-US/firefox-147.0.tar.xz"
|
||||
"https://archive.mozilla.org/pub/firefox/releases/146.0/linux-x86_64/en-US/firefox-146.0.tar.xz"
|
||||
],
|
||||
"named_files": {
|
||||
"FIREFOX": "firefox/firefox"
|
||||
@@ -894,9 +888,9 @@
|
||||
"rules_browsers_firefox_mac": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "48485e2068bc726e2f30cf5855fc2da1fc75c1272bc243a5394f428ffae3ba35",
|
||||
"sha256": "4b1645313887972d466cd82166ea571485c2c40a167f84624e3f3ca739993cc9",
|
||||
"urls": [
|
||||
"https://archive.mozilla.org/pub/firefox/releases/147.0/mac/en-US/Firefox%20147.0.dmg"
|
||||
"https://archive.mozilla.org/pub/firefox/releases/146.0/mac/en-US/Firefox%20146.0.dmg"
|
||||
],
|
||||
"named_files": {
|
||||
"FIREFOX": "Firefox.app/Contents/MacOS/firefox"
|
||||
@@ -910,9 +904,9 @@
|
||||
"rules_browsers_firefox_mac_arm": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "48485e2068bc726e2f30cf5855fc2da1fc75c1272bc243a5394f428ffae3ba35",
|
||||
"sha256": "4b1645313887972d466cd82166ea571485c2c40a167f84624e3f3ca739993cc9",
|
||||
"urls": [
|
||||
"https://archive.mozilla.org/pub/firefox/releases/147.0/mac/en-US/Firefox%20147.0.dmg"
|
||||
"https://archive.mozilla.org/pub/firefox/releases/146.0/mac/en-US/Firefox%20146.0.dmg"
|
||||
],
|
||||
"named_files": {
|
||||
"FIREFOX": "Firefox.app/Contents/MacOS/firefox"
|
||||
@@ -926,9 +920,9 @@
|
||||
"rules_browsers_firefox_win64": {
|
||||
"repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo",
|
||||
"attributes": {
|
||||
"sha256": "36ff9e150875aa48a0af9eec3eb67f66dddd8efac5c743265371a72ae3e796c4",
|
||||
"sha256": "216870c89648f32450cfefb5cec417fcd66d480d5dc83f894bf99f5fd7f38dbb",
|
||||
"urls": [
|
||||
"https://archive.mozilla.org/pub/firefox/releases/147.0/win64/en-US/Firefox%20Setup%20147.0.exe"
|
||||
"https://archive.mozilla.org/pub/firefox/releases/146.0/win64/en-US/Firefox%20Setup%20146.0.exe"
|
||||
],
|
||||
"named_files": {
|
||||
"FIREFOX": "core/firefox.exe"
|
||||
@@ -945,7 +939,7 @@
|
||||
},
|
||||
"@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "4LouzhF/yT117s7peGnNs9ROomiJXC6Zl5R0oI21jho=",
|
||||
"bzlTransitiveDigest": "WHRlQQnxW7e7XMRBhq7SARkDarLDOAbg6iLaJpk5QYM=",
|
||||
"usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
@@ -1028,7 +1022,7 @@
|
||||
},
|
||||
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "nvW/NrBXlAmiQw99EMGKkLaD2KbNp2mQDlxdfpr+0Ls=",
|
||||
"bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=",
|
||||
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
@@ -1092,8 +1086,8 @@
|
||||
},
|
||||
"@@rules_nodejs+//nodejs:extensions.bzl%node": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "4pUxCNc22K4I+6+4Nxu52Hur12tFRfa1JMsN5mdDv60=",
|
||||
"usagesDigest": "pjXeuItYQffkhMcQv+aU/G0SB0QAmyOC9W7iq63eW08=",
|
||||
"bzlTransitiveDigest": "NwcLXHrbh2hoorA/Ybmcpjxsn/6avQmewDglodkDrgo=",
|
||||
"usagesDigest": "JCQTSBqneRVlPU6lK5eO3tfMlb29Zvh+cPUZ8rY2q8U=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
@@ -1103,46 +1097,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "linux_amd64"
|
||||
}
|
||||
@@ -1152,46 +1146,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "linux_arm64"
|
||||
}
|
||||
@@ -1201,46 +1195,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "linux_s390x"
|
||||
}
|
||||
@@ -1250,46 +1244,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "linux_ppc64le"
|
||||
}
|
||||
@@ -1299,46 +1293,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "darwin_amd64"
|
||||
}
|
||||
@@ -1348,46 +1342,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "darwin_arm64"
|
||||
}
|
||||
@@ -1397,46 +1391,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "windows_amd64"
|
||||
}
|
||||
@@ -1446,46 +1440,46 @@
|
||||
"attributes": {
|
||||
"node_download_auth": {},
|
||||
"node_repositories": {
|
||||
"22.22.1-darwin_arm64": [
|
||||
"node-v22.22.1-darwin-arm64.tar.gz",
|
||||
"node-v22.22.1-darwin-arm64",
|
||||
"679ad4966339e4ef4900f57996714864e4211b898825bb840c3086c419fbcef2"
|
||||
"22.22.0-darwin_arm64": [
|
||||
"node-v22.22.0-darwin-arm64.tar.gz",
|
||||
"node-v22.22.0-darwin-arm64",
|
||||
"5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"
|
||||
],
|
||||
"22.22.1-darwin_amd64": [
|
||||
"node-v22.22.1-darwin-x64.tar.gz",
|
||||
"node-v22.22.1-darwin-x64",
|
||||
"07b13722d558790fca20bb1ecf61bde24b7a4863111f7be77fc57251a407359a"
|
||||
"22.22.0-darwin_amd64": [
|
||||
"node-v22.22.0-darwin-x64.tar.gz",
|
||||
"node-v22.22.0-darwin-x64",
|
||||
"5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"
|
||||
],
|
||||
"22.22.1-linux_arm64": [
|
||||
"node-v22.22.1-linux-arm64.tar.xz",
|
||||
"node-v22.22.1-linux-arm64",
|
||||
"0f3550d58d45e5d3cf7103d9e3f69937f09fe82fb5dd474c66a5d816fa58c9ee"
|
||||
"22.22.0-linux_arm64": [
|
||||
"node-v22.22.0-linux-arm64.tar.xz",
|
||||
"node-v22.22.0-linux-arm64",
|
||||
"1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"
|
||||
],
|
||||
"22.22.1-linux_ppc64le": [
|
||||
"node-v22.22.1-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.1-linux-ppc64le",
|
||||
"a65a44cf0224505f052b90357b763dbc1ea9148f4f5f2284f0596cf2000f819b"
|
||||
"22.22.0-linux_ppc64le": [
|
||||
"node-v22.22.0-linux-ppc64le.tar.xz",
|
||||
"node-v22.22.0-linux-ppc64le",
|
||||
"d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"
|
||||
],
|
||||
"22.22.1-linux_s390x": [
|
||||
"node-v22.22.1-linux-s390x.tar.xz",
|
||||
"node-v22.22.1-linux-s390x",
|
||||
"e08b3a73d0bd840e008f589e4be4a2ef3d4a0c59015f4f20a04ed7fc968042a2"
|
||||
"22.22.0-linux_s390x": [
|
||||
"node-v22.22.0-linux-s390x.tar.xz",
|
||||
"node-v22.22.0-linux-s390x",
|
||||
"5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"
|
||||
],
|
||||
"22.22.1-linux_amd64": [
|
||||
"node-v22.22.1-linux-x64.tar.xz",
|
||||
"node-v22.22.1-linux-x64",
|
||||
"9a6bc82f9b491279147219f6a18add1e18424dce90d41d2a5fcd69d4924ba3aa"
|
||||
"22.22.0-linux_amd64": [
|
||||
"node-v22.22.0-linux-x64.tar.xz",
|
||||
"node-v22.22.0-linux-x64",
|
||||
"9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"
|
||||
],
|
||||
"22.22.1-windows_amd64": [
|
||||
"node-v22.22.1-win-x64.zip",
|
||||
"node-v22.22.1-win-x64",
|
||||
"877cb93829e14fffbbc7903e7d8037336c9a79f3ea43c5d0b8c2379b79da56de"
|
||||
"22.22.0-windows_amd64": [
|
||||
"node-v22.22.0-win-x64.zip",
|
||||
"node-v22.22.0-win-x64",
|
||||
"c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"
|
||||
]
|
||||
},
|
||||
"node_urls": [
|
||||
"https://nodejs.org/dist/v{version}/{filename}"
|
||||
],
|
||||
"node_version": "22.22.1",
|
||||
"node_version": "22.22.0",
|
||||
"include_headers": false,
|
||||
"platform": "windows_arm64"
|
||||
}
|
||||
@@ -1514,7 +1508,7 @@
|
||||
},
|
||||
"@@rules_python+//python/extensions:pip.bzl%pip": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "LFkevJ0u48WgTVCyU07LkRD8iYwsRUs2M7uSFHkQAW0=",
|
||||
"bzlTransitiveDigest": "rPZpN8uoLnuu3B+LRiijfMadoMlO1/dxOO8/emPCZV4=",
|
||||
"usagesDigest": "/9NP3RV6/DWuNdYAsIU/8UCgCX0TdPUJr0X6O+0lrtk=",
|
||||
"recordedFileInputs": {
|
||||
"@@protobuf+//python/requirements.txt": "983be60d3cec4b319dcab6d48aeb3f5b2f7c3350f26b3a9e97486c37967c73c5",
|
||||
@@ -4308,8 +4302,8 @@
|
||||
},
|
||||
"@@yq.bzl+//yq:extensions.bzl%yq": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=",
|
||||
"usagesDigest": "LPHUB1lzZAsPKLeNh6HnzS3+5eXDr8A5CKmoD+VBOA4=",
|
||||
"bzlTransitiveDigest": "tDqk+ntWTdxNAWPDjRY1uITgHbti2jcXR5ZdinltBs0=",
|
||||
"usagesDigest": "fKeGl7m4X6ZwRQS4Up/5Bzx+9laXzZyKEn6s9ODJQTc=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
|
||||
@@ -60,7 +60,6 @@ APPLICATION_DEPS = [
|
||||
":node_modules/@lezer/highlight",
|
||||
":node_modules/@lezer/javascript",
|
||||
":node_modules/@stackblitz/sdk",
|
||||
":node_modules/shiki",
|
||||
":node_modules/@typescript/vfs",
|
||||
":node_modules/@webcontainer/api",
|
||||
":node_modules/@xterm/addon-fit",
|
||||
@@ -92,30 +91,6 @@ APPLICATION_DEPS = [
|
||||
":node_modules/crelt",
|
||||
":node_modules/style-mod",
|
||||
":node_modules/w3c-keyname",
|
||||
#
|
||||
":node_modules/@shikijs/themes",
|
||||
":node_modules/@shikijs/langs",
|
||||
":node_modules/@shikijs/engine-oniguruma",
|
||||
":node_modules/@shikijs/core",
|
||||
":node_modules/@shikijs/engine-javascript",
|
||||
":node_modules/@shikijs/types",
|
||||
":node_modules/@shikijs/vscode-textmate",
|
||||
":node_modules/hast-util-to-html",
|
||||
# ":node_modules/oniguruma-to-es",
|
||||
":node_modules/ccount",
|
||||
":node_modules/comma-separated-tokens",
|
||||
":node_modules/hast-util-whitespace",
|
||||
":node_modules/html-void-elements",
|
||||
# ":node_modules/oniguruma-parser",
|
||||
":node_modules/property-information",
|
||||
# ":node_modules/regex-recursion",
|
||||
# ":node_modules/regex",
|
||||
":node_modules/space-separated-tokens",
|
||||
":node_modules/stringify-entities",
|
||||
":node_modules/zwitch",
|
||||
":node_modules/character-entities-html4",
|
||||
":node_modules/character-entities-legacy",
|
||||
# ":node_modules/regex-utilities",
|
||||
]
|
||||
|
||||
TEST_FILES = APPLICATION_FILES + glob(["src/app/**/*.spec.ts"])
|
||||
|
||||
+30
-48
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@algolia/client-common": "5.48.0",
|
||||
"@algolia/client-search": "5.48.0",
|
||||
"@algolia/requester-browser-xhr": "5.48.0",
|
||||
"@algolia/requester-node-http": "5.48.0",
|
||||
"@algolia/client-common": "5.46.2",
|
||||
"@algolia/client-search": "5.46.2",
|
||||
"@algolia/requester-browser-xhr": "5.46.2",
|
||||
"@algolia/requester-node-http": "5.46.2",
|
||||
"@angular/animations": "workspace:*",
|
||||
"@angular/aria": "21.2.0",
|
||||
"@angular/build": "21.2.0",
|
||||
"@angular/cdk": "21.2.0",
|
||||
"@angular/cli": "21.2.0",
|
||||
"@angular/aria": "21.1.0",
|
||||
"@angular/build": "21.1.0-rc.0",
|
||||
"@angular/cdk": "21.1.0",
|
||||
"@angular/cli": "21.1.0-rc.0",
|
||||
"@angular/common": "workspace:*",
|
||||
"@angular/compiler": "workspace:*",
|
||||
"@angular/compiler-cli": "workspace:*",
|
||||
"@angular/core": "workspace:*",
|
||||
"@angular/docs": "workspace:*",
|
||||
"@angular/forms": "workspace:*",
|
||||
"@angular/material": "21.2.0",
|
||||
"@angular/material": "21.1.0",
|
||||
"@angular/platform-browser": "workspace:*",
|
||||
"@angular/platform-server": "workspace:*",
|
||||
"@angular/router": "workspace:*",
|
||||
"@angular/ssr": "21.2.0",
|
||||
"@angular/ssr": "21.1.0-rc.0",
|
||||
"@codemirror/autocomplete": "6.20.0",
|
||||
"@codemirror/commands": "6.10.1",
|
||||
"@codemirror/lang-angular": "0.1.4",
|
||||
@@ -28,75 +28,57 @@
|
||||
"@codemirror/lang-javascript": "6.2.4",
|
||||
"@codemirror/lang-sass": "6.0.2",
|
||||
"@codemirror/language": "6.12.1",
|
||||
"@codemirror/lint": "6.9.3",
|
||||
"@codemirror/search": "6.6.0",
|
||||
"@codemirror/state": "6.5.4",
|
||||
"@codemirror/view": "6.39.12",
|
||||
"@lezer/common": "1.5.1",
|
||||
"@codemirror/lint": "6.9.2",
|
||||
"@codemirror/search": "6.5.11",
|
||||
"@codemirror/state": "6.5.3",
|
||||
"@codemirror/view": "6.39.9",
|
||||
"@lezer/common": "1.5.0",
|
||||
"@lezer/css": "1.3.0",
|
||||
"@lezer/highlight": "1.2.3",
|
||||
"@lezer/html": "1.3.13",
|
||||
"@lezer/javascript": "1.5.4",
|
||||
"@lezer/lr": "1.4.8",
|
||||
"@lezer/lr": "1.4.7",
|
||||
"@lezer/sass": "1.1.0",
|
||||
"@marijn/find-cluster-break": "1.0.2",
|
||||
"@shikijs/core": "^3.21.0",
|
||||
"@shikijs/engine-javascript": "^3.21.0",
|
||||
"@shikijs/engine-oniguruma": "^3.21.0",
|
||||
"@shikijs/langs": "^3.21.0",
|
||||
"@shikijs/themes": "^3.21.0",
|
||||
"@shikijs/types": "^3.21.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2",
|
||||
"@stackblitz/sdk": "1.11.0",
|
||||
"@types/dom-navigation": "1.0.6",
|
||||
"@types/jasmine": "6.0.0",
|
||||
"@types/jasmine": "5.1.13",
|
||||
"@types/jsdom": "27.0.0",
|
||||
"@types/node": "24.10.11",
|
||||
"@types/node": "24.10.4",
|
||||
"@typescript/vfs": "1.6.2",
|
||||
"@webcontainer/api": "1.6.1",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/xterm": "6.0.0",
|
||||
"algoliasearch": "5.48.0",
|
||||
"algoliasearch": "5.46.2",
|
||||
"angular-split": "20.0.0",
|
||||
"ccount": "^2.0.1",
|
||||
"character-entities-html4": "^2.1.0",
|
||||
"character-entities-legacy": "^3.0.0",
|
||||
"comma-separated-tokens": "^2.0.3",
|
||||
"crelt": "1.0.6",
|
||||
"diff": "8.0.3",
|
||||
"diff": "8.0.2",
|
||||
"emoji-regex": "10.6.0",
|
||||
"fflate": "0.8.2",
|
||||
"hast-util-to-html": "^9.0.5",
|
||||
"hast-util-whitespace": "^3.0.0",
|
||||
"html-void-elements": "^3.0.0",
|
||||
"jsdom": "28.0.0",
|
||||
"jasmine-core": "6.1.0",
|
||||
"jasmine-core": "5.13.0",
|
||||
"jsdom": "27.4.0",
|
||||
"karma-chrome-launcher": "3.2.0",
|
||||
"karma-coverage": "2.2.1",
|
||||
"karma-jasmine": "5.1.0",
|
||||
"karma-jasmine-html-reporter": "2.2.0",
|
||||
"karma-jasmine-html-reporter": "2.1.0",
|
||||
"marked": "17.0.1",
|
||||
"mermaid": "11.12.2",
|
||||
"ngx-progressbar": "14.0.0",
|
||||
"open-in-idx": "0.1.1",
|
||||
"playwright-core": "1.58.1",
|
||||
"preact": "10.28.3",
|
||||
"preact-render-to-string": "6.6.6",
|
||||
"prettier": "3.8.1",
|
||||
"property-information": "^7.1.0",
|
||||
"playwright-core": "1.57.0",
|
||||
"preact": "10.28.2",
|
||||
"preact-render-to-string": "6.6.5",
|
||||
"prettier": "3.7.4",
|
||||
"rxjs": "7.8.2",
|
||||
"shiki": "3.22.0",
|
||||
"space-separated-tokens": "^2.0.2",
|
||||
"stringify-entities": "^4.0.4",
|
||||
"shiki": "3.21.0",
|
||||
"style-mod": "4.1.3",
|
||||
"tinyglobby": "0.2.15",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.9.3",
|
||||
"w3c-keyname": "2.2.8",
|
||||
"zwitch": "^2.0.4"
|
||||
"w3c-keyname": "2.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "10.4.24",
|
||||
"autoprefixer": "10.4.23",
|
||||
"karma": "~6.4.4",
|
||||
"postcss": "8.5.6",
|
||||
"tailwindcss": "3.4.19"
|
||||
|
||||
@@ -19,8 +19,7 @@ ts_project(
|
||||
tsconfig = {
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext",
|
||||
"moduleResolution": "node",
|
||||
"types": ["node"],
|
||||
"rootDir": ".",
|
||||
"skipLibCheck": True,
|
||||
@@ -29,7 +28,6 @@ ts_project(
|
||||
deps = [
|
||||
"//adev:node_modules/@angular/docs",
|
||||
"//adev:node_modules/@types/node",
|
||||
"//adev/shared-docs/pipeline/shared:heading",
|
||||
"//adev/src/app/routing/navigation-entries",
|
||||
"//adev/src/content/reference/errors:route-nav-items",
|
||||
"//adev/src/content/reference/extended-diagnostics:route-nav-items",
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ALL_ITEMS} from '../../src/app/routing/navigation-entries/index.js';
|
||||
import {getIdFromHeading} from '../../shared-docs/pipeline/shared/heading.mjs';
|
||||
import {ALL_ITEMS} from '../../src/app/routing/navigation-entries';
|
||||
import {NavigationItem} from '@angular/docs';
|
||||
import {writeFileSync, readFileSync} from 'fs';
|
||||
import {join, resolve} from 'path';
|
||||
@@ -73,3 +72,11 @@ function main() {
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
// TODO: refactor so this function is shared with the generation pipeline (adev/shared-docs/pipeline/shared/marked/transformations/heading.mts)
|
||||
function getIdFromHeading(heading: string): string {
|
||||
return heading
|
||||
.toLowerCase()
|
||||
.replace(/\s|\//g, '-') // replace spaces and slashes with dashes
|
||||
.replace(/[^\p{L}\d\-]/gu, ''); // only keep letters, digits & dashes
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {NgTemplateOutlet} from '@angular/common';
|
||||
import {ChangeDetectionStrategy, Component, inject, input, output} from '@angular/core';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
import {RouterLink, RouterLinkActive} from '@angular/router';
|
||||
import {NavigationItem} from '../../interfaces/index';
|
||||
import {IsActiveNavigationItem} from '../../pipes';
|
||||
@@ -23,7 +23,7 @@ import {IconComponent} from '../icon/icon.component';
|
||||
IconComponent,
|
||||
IsActiveNavigationItem,
|
||||
NgTemplateOutlet,
|
||||
MatTooltip,
|
||||
MatTooltipModule,
|
||||
],
|
||||
templateUrl: './navigation-list.component.html',
|
||||
styleUrls: ['./navigation-list.component.scss'],
|
||||
|
||||
@@ -137,14 +137,14 @@ dialog {
|
||||
.docs-search-results__start-typing,
|
||||
.docs-search-results__no-results {
|
||||
padding: 0.75rem;
|
||||
color: var(--quaternary-contrast);
|
||||
color: var(--gray-400);
|
||||
}
|
||||
|
||||
.docs-search-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--quaternary-contrast);
|
||||
color: var(--gray-400);
|
||||
padding: 1rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
|
||||
@@ -95,6 +95,9 @@ export class SearchDialog {
|
||||
if (!this.dialog().nativeElement.open) {
|
||||
this.dialog().nativeElement.showModal?.();
|
||||
}
|
||||
// We want to select the pre-existing text on opening
|
||||
// In order to change the search input with minimal user interaction.
|
||||
this.searchForm().focusBoundControl();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ ng_project(
|
||||
"//adev/shared-docs/components:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"//adev:node_modules/@angular/aria",
|
||||
"//adev:node_modules/@angular/common",
|
||||
"//adev:node_modules/@angular/core",
|
||||
"//adev:node_modules/@angular/forms",
|
||||
|
||||
@@ -1,61 +1,10 @@
|
||||
<div ngCombobox #outerCombobox="ngCombobox" [readonly]="true" [disabled]="disabled()">
|
||||
<div class="docs-select-input-container">
|
||||
<input
|
||||
ngComboboxInput
|
||||
[attr.id]="id()"
|
||||
[attr.name]="name()"
|
||||
[value]="displayValue()"
|
||||
placeholder="Select an option..."
|
||||
readonly
|
||||
/>
|
||||
<span class="material-symbols-outlined docs-select-arrow" translate="no" aria-hidden="true"
|
||||
>arrow_drop_down</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<ng-template ngComboboxPopupContainer>
|
||||
<dialog ngComboboxDialog class="docs-select-dialog">
|
||||
<div ngCombobox #innerCombobox="ngCombobox" filterMode="manual" [alwaysExpanded]="true">
|
||||
<div class="docs-select-search-container">
|
||||
<span
|
||||
class="material-symbols-outlined docs-select-search-icon"
|
||||
translate="no"
|
||||
aria-hidden="true"
|
||||
>search</span
|
||||
>
|
||||
<input
|
||||
ngComboboxInput
|
||||
class="docs-select-search-input"
|
||||
placeholder="Search..."
|
||||
[(value)]="searchString"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ng-template ngComboboxPopupContainer>
|
||||
@if (filteredOptions().length === 0) {
|
||||
<div class="docs-select-no-results">No results found</div>
|
||||
}
|
||||
|
||||
<div ngListbox [(values)]="selectedValues" class="docs-select-listbox">
|
||||
@for (option of filteredOptions(); track option.value) {
|
||||
<div
|
||||
ngOption
|
||||
[value]="option.value"
|
||||
[label]="option.label"
|
||||
class="docs-select-option"
|
||||
>
|
||||
<span class="docs-select-option-label">{{ option.label }}</span>
|
||||
<span
|
||||
class="material-symbols-outlined docs-select-check-icon"
|
||||
translate="no"
|
||||
aria-hidden="true"
|
||||
>check</span
|
||||
>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
</dialog>
|
||||
</ng-template>
|
||||
</div>
|
||||
<select
|
||||
[attr.id]="id()"
|
||||
[attr.name]="name()"
|
||||
[value]="value()"
|
||||
(change)="setOption($any($event.target).value)"
|
||||
>
|
||||
@for (item of options(); track item) {
|
||||
<option [value]="item.value" [selected]="value() === item.value">{{ item.label }}</option>
|
||||
}
|
||||
</select>
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
:host {
|
||||
--border-color: color-mix(in srgb, var(--full-contrast) 20%, var(--page-background));
|
||||
}
|
||||
|
||||
[ngCombobox] {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.docs-select-input-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
[ngComboboxInput] {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
[ngComboboxInput][readonly='true'] {
|
||||
cursor: pointer;
|
||||
padding: 0.7rem 1rem;
|
||||
}
|
||||
|
||||
[ngCombobox]:focus-within [ngComboboxInput]:not(.docs-select-search-input) {
|
||||
outline: 1.5px solid var(--vivid-pink);
|
||||
box-shadow: 0 0 0 4px color-mix(in srgb, var(--vivid-pink) 25%, transparent);
|
||||
}
|
||||
|
||||
.docs-select-arrow {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 20px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
pointer-events: none;
|
||||
padding: 0 0.5rem;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
opacity: 0.8;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
[ngComboboxInput][aria-expanded='true'] + .docs-select-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
[ngComboboxInput] {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 1rem;
|
||||
padding: 0.7rem 1rem 0.7rem 2.5rem;
|
||||
background-color: var(--septenary-contrast);
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
|
||||
.docs-select-dialog {
|
||||
position: absolute;
|
||||
left: auto;
|
||||
right: auto;
|
||||
top: auto;
|
||||
bottom: auto;
|
||||
padding: 0;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.25rem;
|
||||
background-color: var(--septenary-contrast);
|
||||
color: inherit;
|
||||
|
||||
.docs-select-input-container {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
[ngCombobox],
|
||||
.docs-select-input-container {
|
||||
border: none;
|
||||
}
|
||||
|
||||
[ngComboboxInput] {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
[ngCombobox]:focus-within [ngComboboxInput] {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.docs-select-search-input:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.docs-select-search-container {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
&::backdrop {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-select-search-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.docs-select-search-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 20px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
padding: 0 0.5rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.docs-select-search-input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 0.875rem;
|
||||
padding: 0.5rem 0.75rem 0.5rem 2rem;
|
||||
background-color: var(--septenary-contrast);
|
||||
color: var(--primary-contrast);
|
||||
}
|
||||
|
||||
.docs-select-no-results {
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
font-size: 0.875rem;
|
||||
color: var(--primary-contrast);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.docs-select-listbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 12rem;
|
||||
overflow: auto;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.docs-select-option {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
&:hover {
|
||||
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
|
||||
}
|
||||
|
||||
&[data-active='true'] {
|
||||
outline-offset: -2px;
|
||||
outline: 2px solid var(--vivid-pink);
|
||||
}
|
||||
|
||||
&[aria-selected='true'] {
|
||||
color: var(--vivid-pink);
|
||||
background-color: color-mix(in srgb, var(--vivid-pink) 5%, transparent);
|
||||
}
|
||||
|
||||
&:not([aria-selected='true']) .docs-select-check-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.docs-select-option-label {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.docs-select-check-icon {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@@ -6,26 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxDialog,
|
||||
ComboboxInput,
|
||||
ComboboxPopupContainer,
|
||||
} from '@angular/aria/combobox';
|
||||
import {Listbox, Option} from '@angular/aria/listbox';
|
||||
import {
|
||||
afterRenderEffect,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
model,
|
||||
signal,
|
||||
untracked,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, input, model} from '@angular/core';
|
||||
import {FormValueControl} from '@angular/forms/signals';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
type SelectOptionValue = string | number | boolean;
|
||||
|
||||
@@ -37,17 +19,11 @@ export interface SelectOption {
|
||||
@Component({
|
||||
selector: 'docs-select',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
Combobox,
|
||||
ComboboxDialog,
|
||||
ComboboxInput,
|
||||
ComboboxPopupContainer,
|
||||
FormsModule,
|
||||
Listbox,
|
||||
Option,
|
||||
],
|
||||
templateUrl: './select.component.html',
|
||||
styleUrls: ['./select.component.scss'],
|
||||
host: {
|
||||
class: 'docs-form-element',
|
||||
},
|
||||
})
|
||||
export class Select implements FormValueControl<string | null> {
|
||||
readonly value = model<string | null>(null);
|
||||
@@ -57,66 +33,11 @@ export class Select implements FormValueControl<string | null> {
|
||||
readonly options = input.required<SelectOption[]>();
|
||||
readonly disabled = input(false);
|
||||
|
||||
readonly dialog = viewChild(ComboboxDialog);
|
||||
readonly listbox = viewChild<Listbox<SelectOptionValue>>(Listbox);
|
||||
readonly combobox = viewChild<Combobox<SelectOptionValue>>(Combobox);
|
||||
|
||||
readonly searchString = signal('');
|
||||
|
||||
readonly filteredOptions = computed(() => {
|
||||
const search = this.searchString().toLowerCase();
|
||||
if (!search) {
|
||||
return this.options();
|
||||
}
|
||||
return this.options().filter((option) => option.label.toLowerCase().includes(search));
|
||||
});
|
||||
|
||||
readonly displayValue = computed(() => {
|
||||
const currentValue = this.value();
|
||||
if (currentValue === null) {
|
||||
return '';
|
||||
}
|
||||
const option = this.options().find((opt) => opt.value === currentValue);
|
||||
return option ? option.label : '';
|
||||
});
|
||||
|
||||
readonly selectedValues = signal<SelectOptionValue[]>([]);
|
||||
|
||||
constructor() {
|
||||
afterRenderEffect(() => {
|
||||
if (this.dialog() && this.combobox()?.expanded()) {
|
||||
untracked(() => this.listbox()?.gotoFirst());
|
||||
this.positionDialog();
|
||||
}
|
||||
});
|
||||
|
||||
afterRenderEffect(() => {
|
||||
const selected = this.selectedValues();
|
||||
if (selected.length > 0) {
|
||||
untracked(() => this.dialog()?.close());
|
||||
this.value.set(selected[0] as string);
|
||||
this.searchString.set('');
|
||||
}
|
||||
});
|
||||
|
||||
afterRenderEffect(() => this.listbox()?.scrollActiveItemIntoView());
|
||||
}
|
||||
// TODO: Improve once CDK overlay is fixed https://github.com/angular/components/issues/32504
|
||||
private positionDialog(): void {
|
||||
const dialog = this.dialog();
|
||||
const combobox = this.combobox();
|
||||
|
||||
if (!dialog || !combobox) {
|
||||
setOption($event: SelectOptionValue): void {
|
||||
if (this.disabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const comboboxRect = combobox.inputElement()?.getBoundingClientRect();
|
||||
const scrollY = window.scrollY;
|
||||
|
||||
if (comboboxRect) {
|
||||
dialog.element.style.width = `${comboboxRect.width}px`;
|
||||
dialog.element.style.top = `${comboboxRect.bottom + scrollY + 4}px`;
|
||||
dialog.element.style.left = `${comboboxRect.left}px`;
|
||||
}
|
||||
this.value.set($event as string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,32 +32,4 @@ describe('TabGroup', () => {
|
||||
expect(tabs[0].textContent.trim()).toBe('tab 1');
|
||||
expect(tabpanels[0].textContent.trim()).toBe('panel 1');
|
||||
});
|
||||
|
||||
it('should generate unique ids for tabs and tabpanels', async () => {
|
||||
const testPanel1 = document.createElement('div');
|
||||
testPanel1.textContent = 'panel 1';
|
||||
const testPanel2 = document.createElement('div');
|
||||
testPanel2.textContent = 'panel 2';
|
||||
fixture.componentRef.setInput('tabs', [
|
||||
{label: 'tab 1', panel: testPanel1},
|
||||
{label: 'tab 2', panel: testPanel2},
|
||||
]);
|
||||
await fixture.whenStable();
|
||||
|
||||
const tabs = fixture.nativeElement.querySelectorAll('.docs-tab');
|
||||
const tabpanels = fixture.nativeElement.querySelectorAll('.docs-tab-panel');
|
||||
expect(tabs[0].id).not.toBe(tabs[1].id);
|
||||
expect(tabpanels[0].id).not.toBe(tabpanels[1].id);
|
||||
|
||||
const fixture2 = TestBed.createComponent(TabGroup);
|
||||
fixture2.componentRef.setInput('tabs', [
|
||||
{label: 'tab 1', panel: testPanel1},
|
||||
{label: 'tab 2', panel: testPanel2},
|
||||
]);
|
||||
await fixture2.whenStable();
|
||||
const tabs2 = fixture2.nativeElement.querySelectorAll('.docs-tab');
|
||||
const tabpanels2 = fixture2.nativeElement.querySelectorAll('.docs-tab-panel');
|
||||
expect(tabs[0].id).not.toBe(tabs2[0].id);
|
||||
expect(tabpanels[0].id).not.toBe(tabpanels2[0].id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,19 +7,18 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
afterRenderEffect,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
ElementRef,
|
||||
inject,
|
||||
input,
|
||||
inject,
|
||||
computed,
|
||||
linkedSignal,
|
||||
Renderer2,
|
||||
viewChildren,
|
||||
afterRenderEffect,
|
||||
Renderer2,
|
||||
ElementRef,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
|
||||
let idCounter = 0;
|
||||
import {_IdGenerator} from '@angular/cdk/a11y';
|
||||
|
||||
/**
|
||||
* A simple tabs implementation with proper aria roles.
|
||||
@@ -37,24 +36,20 @@ let idCounter = 0;
|
||||
})
|
||||
export class TabGroup {
|
||||
private readonly _renderer = inject(Renderer2);
|
||||
private readonly _idGenerator = inject(_IdGenerator);
|
||||
private readonly _tabpanels = viewChildren<ElementRef<HTMLDivElement>>('tabpanel');
|
||||
|
||||
readonly tabs = input<{label: string; panel: HTMLElement}[]>();
|
||||
|
||||
readonly computedTabs = computed(() => {
|
||||
return (
|
||||
this.tabs()?.map((tab) => {
|
||||
const id = idCounter++;
|
||||
|
||||
return {
|
||||
tabId: `docs-tab-${id}`,
|
||||
tabPanelId: `docs-tab-panel-${id}`,
|
||||
label: tab.label,
|
||||
panel: tab.panel,
|
||||
};
|
||||
}) ?? []
|
||||
);
|
||||
});
|
||||
readonly computedTabs = computed(
|
||||
() =>
|
||||
this.tabs()?.map((tab) => ({
|
||||
tabId: this._idGenerator.getId('docs-tab-'),
|
||||
tabPanelId: this._idGenerator.getId('docs-tab-panel-'),
|
||||
label: tab.label,
|
||||
panel: tab.panel,
|
||||
})) ?? [],
|
||||
);
|
||||
|
||||
readonly selectedTab = linkedSignal(() => this.computedTabs()[0]?.tabId);
|
||||
|
||||
|
||||
@@ -8,19 +8,11 @@
|
||||
top: 0;
|
||||
height: fit-content;
|
||||
width: 14rem;
|
||||
padding-right: 1rem;
|
||||
padding-right: 2rem;
|
||||
max-height: 100vh;
|
||||
overflow-y: scroll;
|
||||
box-sizing: border-box;
|
||||
|
||||
@include mq.for-large-desktop-up {
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
@include mq.for-extra-large-desktop-up {
|
||||
width: 25rem;
|
||||
}
|
||||
|
||||
aside {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ import {IconComponent} from '../icon/icon.component';
|
||||
class: 'docs-form-element',
|
||||
},
|
||||
})
|
||||
export class TextField implements FormValueControl<string> {
|
||||
export class TextField implements FormValueControl<string | null> {
|
||||
readonly input = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');
|
||||
readonly name = input<string>('');
|
||||
readonly value = model<string>('');
|
||||
readonly value = model<string | null>(null);
|
||||
readonly placeholder = input<string | null>(null);
|
||||
readonly disabled = model<boolean>(false);
|
||||
readonly hideIcon = input<boolean>(false);
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
height: fit-content;
|
||||
|
||||
docs-icon {
|
||||
color: var(--quaternary-contrast);
|
||||
color: var(--gray-400);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
fill="var(--quaternary-contrast)"
|
||||
fill="var(--gray-400)"
|
||||
d="M3.4 22 2 20.6 8.6 14H4v-2h8v8h-2v-4.6L3.4 22ZM12 12V4h2v4.6L20.6 2 22 3.4 15.4 10H20v2h-8Z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
.docs-example-viewer-preview {
|
||||
.docs-dark-mode & {
|
||||
color: var(--primary-contrast);
|
||||
background: var(--primary-constrast);
|
||||
background: var(--gray-900);
|
||||
}
|
||||
@media screen and (prefers-color-scheme: dark) {
|
||||
color: var(--primary-contrast);
|
||||
background: var(--primary-constrast);
|
||||
background: var(--gray-900);
|
||||
}
|
||||
.docs-light-mode & {
|
||||
background: var(--page-background);
|
||||
@@ -70,7 +70,7 @@
|
||||
cursor: pointer;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
color: var(--quaternary-contrast);
|
||||
color: var(--gray-400);
|
||||
|
||||
path {
|
||||
transition: fill 0.3s ease;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import {
|
||||
afterNextRender,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
computed,
|
||||
ElementRef,
|
||||
@@ -19,13 +20,13 @@ import {
|
||||
Type,
|
||||
} from '@angular/core';
|
||||
import {DOCUMENT, NgComponentOutlet, NgTemplateOutlet} from '@angular/common';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
import {MatTabsModule} from '@angular/material/tabs';
|
||||
import {Clipboard} from '@angular/cdk/clipboard';
|
||||
import {CopySourceCodeButton} from '../../copy-source-code-button/copy-source-code-button.component';
|
||||
import {IconComponent} from '../../icon/icon.component';
|
||||
import {ExampleMetadata, Snippet} from '../../../interfaces/index';
|
||||
import {EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers/index';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
|
||||
export const CODE_LINE_NUMBER_CLASS_NAME = 'shiki-ln-number';
|
||||
export const CODE_LINE_CLASS_NAME = 'line';
|
||||
@@ -36,9 +37,8 @@ export const HIDDEN_CLASS_NAME = 'hidden';
|
||||
selector: 'docs-example-viewer',
|
||||
imports: [
|
||||
CopySourceCodeButton,
|
||||
MatTabGroup,
|
||||
MatTab,
|
||||
MatTooltip,
|
||||
MatTabsModule,
|
||||
MatTooltipModule,
|
||||
IconComponent,
|
||||
NgTemplateOutlet,
|
||||
NgComponentOutlet,
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
"name": "@angular/docs",
|
||||
"version": "0.0.0-PLACEHOLDER",
|
||||
"peerDependencies": {
|
||||
"@angular/cdk": "^21.2.0-next",
|
||||
"@angular/common": "^21.2.0-next",
|
||||
"@angular/core": "^21.2.0-next",
|
||||
"@angular/forms": "^21.2.0-next",
|
||||
"@angular/material": "^21.2.0-next",
|
||||
"@angular/platform-browser": "^21.2.0-next",
|
||||
"@angular/router": "^21.2.0-next",
|
||||
"@angular/ssr": "^21.2.0-next",
|
||||
"@angular/cdk": "^21.1.0-next",
|
||||
"@angular/common": "^21.1.0-next",
|
||||
"@angular/core": "^21.1.0-next",
|
||||
"@angular/forms": "^21.1.0-next",
|
||||
"@angular/material": "^21.1.0-next",
|
||||
"@angular/platform-browser": "^21.1.0-next",
|
||||
"@angular/router": "^21.1.0-next",
|
||||
"@angular/ssr": "^21.1.0-next",
|
||||
"algoliasearch": "^5.0.0",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
@@ -18,7 +18,7 @@
|
||||
"diff": "~8.0.0",
|
||||
"emoji-regex": "~10.6.0",
|
||||
"fflate": "^0.8.2",
|
||||
"jsdom": "~28.0.0",
|
||||
"jsdom": "~27.4.0",
|
||||
"marked": "~17.0.0",
|
||||
"mermaid": "^11.0.0",
|
||||
"shiki": "^3.0.0",
|
||||
|
||||
@@ -47,7 +47,6 @@ js_binary(
|
||||
"//adev:node_modules/jsdom",
|
||||
"//adev:node_modules/mermaid",
|
||||
"//adev:node_modules/playwright-core",
|
||||
"//adev:node_modules/typescript",
|
||||
"@rules_browsers//browsers/chromium",
|
||||
],
|
||||
entry_point = "//adev/shared-docs/pipeline/guides:guides.mjs",
|
||||
@@ -62,7 +61,6 @@ js_binary(
|
||||
name = "markdown_no_mermaid",
|
||||
data = [
|
||||
"//adev:node_modules/jsdom",
|
||||
"//adev:node_modules/typescript",
|
||||
],
|
||||
entry_point = "//adev/shared-docs/pipeline/guides:guides-no-mermaid.mjs",
|
||||
visibility = ["//visibility:public"],
|
||||
|
||||
@@ -7,7 +7,6 @@ esbuild(
|
||||
entry_point = ":index.mts",
|
||||
external = [
|
||||
"@angular/compiler-cli",
|
||||
"typescript",
|
||||
],
|
||||
format = "esm",
|
||||
output = "bin.mjs",
|
||||
|
||||
@@ -8,7 +8,6 @@ esbuild(
|
||||
external = [
|
||||
"jsdom",
|
||||
"playwright-core",
|
||||
"typescript",
|
||||
],
|
||||
format = "esm",
|
||||
output = "bin.mjs",
|
||||
|
||||
@@ -167,9 +167,11 @@ export type CliCommandRenderable = CliCommand & {
|
||||
htmlDescription: string;
|
||||
cards: CliCardRenderable[];
|
||||
argumentsLabel: string;
|
||||
optionsLabel: string;
|
||||
hasOptions: boolean;
|
||||
subcommands?: CliCommandRenderable[];
|
||||
};
|
||||
|
||||
export interface InitializerApiFunctionRenderable
|
||||
extends Omit<InitializerApiFunctionEntry, 'jsdocTags'>, DocEntryRenderable, HasRenderableToc {}
|
||||
extends Omit<InitializerApiFunctionEntry, 'jsdocTags'>,
|
||||
DocEntryRenderable,
|
||||
HasRenderableToc {}
|
||||
|
||||
@@ -22,10 +22,6 @@ export interface HasJsDocTags {
|
||||
jsdocTags: JsDocTagEntry[];
|
||||
}
|
||||
|
||||
export interface MaybeJsDocTags {
|
||||
jsdocTags?: JsDocTagEntry[];
|
||||
}
|
||||
|
||||
export interface HasAdditionalLinks {
|
||||
additionalLinks: LinkEntryRenderable[];
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import {RawHtml} from './raw-html';
|
||||
import {DeprecationWarning} from './deprecation-warning';
|
||||
import {codeToHtml} from '../../../shared/shiki.mjs';
|
||||
import {getHighlighterInstance} from '../shiki/shiki.mjs';
|
||||
import {getSymbolsAsApiEntries} from '../symbol-context.mjs';
|
||||
|
||||
/** Component to render a class API reference document. */
|
||||
export function ClassReference(
|
||||
@@ -44,7 +43,6 @@ export function ClassReference(
|
||||
<RawHtml
|
||||
value={codeToHtml(getHighlighterInstance(), (entry as PipeEntry).usage, {
|
||||
language: 'angular-html',
|
||||
apiEntries: getSymbolsAsApiEntries(),
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -26,15 +26,19 @@ export function CliCommandReference(entry: CliCommandRenderable) {
|
||||
<code>
|
||||
<div className={'shiki line cli'}>
|
||||
ng {commandName(entry, command)}
|
||||
{entry.argumentsLabel && (
|
||||
{entry.argumentsLabel ? (
|
||||
<button member-id={'Arguments'} className="shiki-ln-line-argument">
|
||||
{entry.argumentsLabel}
|
||||
</button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{entry.optionsLabel && (
|
||||
{entry.hasOptions ? (
|
||||
<button member-id={'Options'} className="shiki-ln-line-option">
|
||||
{entry.optionsLabel}
|
||||
[options]
|
||||
</button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</code>
|
||||
|
||||
@@ -73,14 +73,13 @@ export function FunctionReference(entry: FunctionEntryRenderable) {
|
||||
<DeprecationWarning entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.signatures.length > 1 &&
|
||||
entry.signatures.map((s, i) =>
|
||||
signatureCard(s.name, getFunctionMetadataRenderable(s, entry.moduleName, entry.repo), {
|
||||
id: `${s.name}_${i}`,
|
||||
printSignaturesAsHeader,
|
||||
hideUsageNotes: true,
|
||||
}),
|
||||
)}
|
||||
{entry.signatures.map((s, i) =>
|
||||
signatureCard(s.name, getFunctionMetadataRenderable(s, entry.moduleName, entry.repo), {
|
||||
id: `${s.name}_${i}`,
|
||||
printSignaturesAsHeader,
|
||||
hideUsageNotes: true,
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
|
||||
<SectionDescription entry={entry} />
|
||||
|
||||
@@ -10,14 +10,10 @@ import {h} from 'preact';
|
||||
import {RawHtml} from './raw-html';
|
||||
import {codeToHtml} from '../../../shared/shiki.mjs';
|
||||
import {getHighlighterInstance} from '../shiki/shiki.mjs';
|
||||
import {getSymbolsAsApiEntries} from '../symbol-context.mjs';
|
||||
|
||||
/** Component to render a header of the CLI page. */
|
||||
export function HighlightTypeScript(props: {code: string}) {
|
||||
const result = codeToHtml(getHighlighterInstance(), props.code, {
|
||||
language: 'typescript',
|
||||
apiEntries: getSymbolsAsApiEntries(),
|
||||
});
|
||||
const result = codeToHtml(getHighlighterInstance(), props.code, {language: 'typescript'});
|
||||
const withScrollTrack = result.replace(/^(<pre class="shiki)/, '$1 docs-mini-scroll-track');
|
||||
|
||||
return <RawHtml value={withScrollTrack} className="docs-code" />;
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('CLI docs to html', () => {
|
||||
const cliTocs = fragment.querySelectorAll('.docs-reference-cli-toc')!;
|
||||
expect(cliTocs.length).toBe(2);
|
||||
|
||||
expect(cliTocs[0].textContent).toContain('ng component [name] [options]');
|
||||
expect(cliTocs[1].textContent).toContain('ng c [name] [options]');
|
||||
expect(cliTocs[0].textContent).toContain('ng component[name][options]');
|
||||
expect(cliTocs[1].textContent).toContain('ng c[name][options]');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
import {readFile} from 'fs/promises';
|
||||
import {JSDOM} from 'jsdom';
|
||||
import {resolve} from 'path';
|
||||
import {initHighlighter} from '../../../shared/shiki.mjs';
|
||||
import {getRenderable} from '../processing.mjs';
|
||||
import {renderEntry} from '../rendering.mjs';
|
||||
import {setHighlighterInstance} from '../shiki/shiki.mjs';
|
||||
import {setSymbols} from '../symbol-context.mjs';
|
||||
import {resolve} from 'path';
|
||||
import {initHighlighter} from '../../../shared/shiki.mjs';
|
||||
import {setHighlighterInstance} from '../shiki/shiki.mjs';
|
||||
|
||||
// Note: The tests will probably break if the schema of the api extraction changes.
|
||||
// All entries in the fake-entries are extracted from Angular's api.
|
||||
@@ -69,7 +69,7 @@ describe('markdown to html', () => {
|
||||
it('should render multiple {@link} blocks', () => {
|
||||
const provideClientHydrationEntry = entries.get('provideClientHydration')!;
|
||||
expect(provideClientHydrationEntry).toBeDefined();
|
||||
const cardItem = provideClientHydrationEntry.querySelector('.docs-api')!;
|
||||
const cardItem = provideClientHydrationEntry.querySelector('.docs-reference-card-item')!;
|
||||
expect(cardItem.innerHTML).not.toContain('@link');
|
||||
});
|
||||
|
||||
|
||||
+194
-217
@@ -17,207 +17,204 @@ import {
|
||||
|
||||
// @ts-ignore This compiles fine, but Webstorm doesn't like the ESM import in a CJS context.
|
||||
describe('jsdoc transforms', () => {
|
||||
describe('addHtmlAdditionalLinks', () => {
|
||||
it('should transform links', () => {
|
||||
setCurrentSymbol('Router');
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'test'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
it('should transform links', () => {
|
||||
setCurrentSymbol('Router');
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'test'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io "Angular")',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route Something else}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethod}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethodWithParenthesis()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link FormGroup.someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev/api/core/ApplicationRef}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /cli/build ng build}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: 'Angular',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Route',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[3]).toEqual({
|
||||
label: 'Something else',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[4]).toEqual({
|
||||
label: 'someMethod',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[5]).toEqual({
|
||||
label: 'someMethodWithParenthesis()',
|
||||
url: '/api/test/Router#someMethodWithParenthesis',
|
||||
});
|
||||
expect(entry.additionalLinks[6]).toEqual({
|
||||
label: 'someMethod()',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[7]).toEqual({
|
||||
label: 'FormGroup.someMethod()',
|
||||
url: '/api/test/FormGroup#someMethod',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[8]).toEqual({
|
||||
label: 'ApplicationRef',
|
||||
url: 'https://angular.dev/api/core/ApplicationRef',
|
||||
});
|
||||
expect(entry.additionalLinks[9]).toEqual({
|
||||
label: 'angular.dev',
|
||||
url: 'https://angular.dev',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[10]).toEqual({
|
||||
label: 'ng build',
|
||||
url: '/cli/build',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[11]).toEqual({
|
||||
label: 'Output Interop',
|
||||
url: '/ecosystem/rxjs-interop/output-interop',
|
||||
});
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io "Angular")',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route Something else}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethod}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethodWithParenthesis()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link FormGroup.someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev/api/core/ApplicationRef}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /cli/build ng build}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
it('should convert backticks to code tags in markdown links', () => {
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Method with `backticks` in title](https://example.com "Title with `code`")',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Host view using <code>ViewContainerRef.createComponent</code>',
|
||||
url: 'guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label:
|
||||
'Popup attached to <code>document.body</code> with <code>createComponent</code> + <code>hostElement</code>',
|
||||
url: 'guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Method with <code>backticks</code> in title',
|
||||
url: 'https://example.com',
|
||||
title: 'Title with `code`',
|
||||
});
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
it('should throw on invalid relatie @link', () => {
|
||||
const entryFn = () =>
|
||||
addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link cli/build ng build}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: 'Angular',
|
||||
});
|
||||
|
||||
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Route',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[3]).toEqual({
|
||||
label: 'Something else',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[4]).toEqual({
|
||||
label: 'someMethod',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[5]).toEqual({
|
||||
label: 'someMethodWithParenthesis()',
|
||||
url: '/api/test/Router#someMethodWithParenthesis',
|
||||
});
|
||||
expect(entry.additionalLinks[6]).toEqual({
|
||||
label: 'someMethod()',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[7]).toEqual({
|
||||
label: 'FormGroup.someMethod()',
|
||||
url: '/api/test/FormGroup#someMethod',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[8]).toEqual({
|
||||
label: 'ApplicationRef',
|
||||
url: 'https://angular.dev/api/core/ApplicationRef',
|
||||
});
|
||||
expect(entry.additionalLinks[9]).toEqual({
|
||||
label: 'angular.dev',
|
||||
url: 'https://angular.dev',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[10]).toEqual({
|
||||
label: 'ng build',
|
||||
url: '/cli/build',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[11]).toEqual({
|
||||
label: 'Output Interop',
|
||||
url: '/ecosystem/rxjs-interop/output-interop',
|
||||
});
|
||||
});
|
||||
|
||||
describe('addHtmlDescription', () => {
|
||||
it('should parse markdown in descriptions', async () => {
|
||||
setHighlighterInstance(await initHighlighter());
|
||||
it('should convert backticks to code tags in markdown links', () => {
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Method with `backticks` in title](https://example.com "Title with `code`")',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'angular/router'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Host view using <code>ViewContainerRef.createComponent</code>',
|
||||
url: 'guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
const entry = addHtmlDescription({
|
||||
description: `
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label:
|
||||
'Popup attached to <code>document.body</code> with <code>createComponent</code> + <code>hostElement</code>',
|
||||
url: 'guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Method with <code>backticks</code> in title',
|
||||
url: 'https://example.com',
|
||||
title: 'Title with `code`',
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw on invalid relatie @link', () => {
|
||||
const entryFn = () =>
|
||||
addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link cli/build ng build}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
|
||||
});
|
||||
|
||||
it('should parse markdown in descriptions', async () => {
|
||||
setHighlighterInstance(await initHighlighter());
|
||||
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'angular/router'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
|
||||
const entry = addHtmlDescription({
|
||||
description: `
|
||||
\`\`\`angular-ts
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@@ -226,36 +223,16 @@ function setupRouter() {
|
||||
}
|
||||
\`\`\`
|
||||
`,
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
// Should have some shiki variables (meaning the description was highlighted).
|
||||
expect(entry.htmlDescription).toContain('--shiki');
|
||||
|
||||
// Having docs-code means that the description was parsed and formatted correctly (by the shared marked renderer)
|
||||
expect(entry.htmlDescription).toContain('class="docs-code"');
|
||||
|
||||
expect(entry.htmlDescription).toContain('/api/angular/router/Router');
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
it('should transform entry with different description & description tag', () => {
|
||||
const entry = addHtmlDescription({
|
||||
'description':
|
||||
"Enables interop with the browser's `Navigation` API for router navigations.",
|
||||
'jsdocTags': [
|
||||
{
|
||||
'name': 'description',
|
||||
'comment': 'This feature is _highly_ experimental ...',
|
||||
},
|
||||
],
|
||||
'moduleName': 'platform-browser',
|
||||
});
|
||||
// Should have some shiki variables (meaning the description was highlighted).
|
||||
expect(entry.htmlDescription).toContain('--shiki');
|
||||
|
||||
expect(entry.htmlDescription).toBe(`<p>This feature is <em>highly</em> experimental ...</p>`);
|
||||
expect(entry.shortHtmlDescription).toBe(
|
||||
`<p>Enables interop with the browser's <code>Navigation</code> API for router navigations.</p>`,
|
||||
);
|
||||
});
|
||||
// Having docs-code means that the description was parsed and formatted correctly (by the shared marked renderer)
|
||||
expect(entry.htmlDescription).toContain('class="docs-code"');
|
||||
|
||||
expect(entry.htmlDescription).toContain('/api/angular/router/Router');
|
||||
});
|
||||
|
||||
it('should only mark as deprecated if all overloads are deprecated', () => {
|
||||
|
||||
@@ -27,7 +27,7 @@ export function getCliRenderable(command: CliCommand): CliCommandRenderable {
|
||||
}),
|
||||
cards: getCliCardsRenderable(command),
|
||||
argumentsLabel: getArgumentsLabel(command),
|
||||
optionsLabel: getOptionsLabel(command),
|
||||
hasOptions: getOptions(command).length > 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,12 +66,7 @@ function getArgumentsLabel(command: CliCommand): string {
|
||||
if (args.length === 0) {
|
||||
return '';
|
||||
}
|
||||
const label = command.command.replace(/^ng\s+/, '').replace(`${command.name} `, '');
|
||||
return ` ${label}`;
|
||||
}
|
||||
|
||||
function getOptionsLabel(command: CliCommand): string {
|
||||
return getOptions(command).length > 0 ? ' [options]' : '';
|
||||
return command.command.replace(`${command.name} `, '');
|
||||
}
|
||||
|
||||
function getArgs(command: CliCommand): CliOption[] {
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
insertParenthesesForDecoratorInShikiHtml,
|
||||
replaceKeywordFromShikiHtml,
|
||||
} from '../shiki/shiki.mjs';
|
||||
import {getSymbolsAsApiEntries, getSymbolUrl} from '../symbol-context.mjs';
|
||||
import {getSymbolUrl} from '../symbol-context.mjs';
|
||||
|
||||
import {codeToHtml} from '../../../shared/shiki.mjs';
|
||||
import {formatJs} from './format-code.mjs';
|
||||
@@ -92,10 +92,7 @@ export async function addRenderableCodeToc<T extends DocEntry & HasModuleName>(
|
||||
let codeWithSyntaxHighlighting = codeToHtml(
|
||||
getHighlighterInstance(),
|
||||
formattedCode ?? metadata?.contents,
|
||||
{
|
||||
language: 'typescript',
|
||||
apiEntries: getSymbolsAsApiEntries(),
|
||||
},
|
||||
{language: 'typescript'},
|
||||
);
|
||||
|
||||
if (isDecoratorEntry(entry)) {
|
||||
@@ -114,6 +111,11 @@ export async function addRenderableCodeToc<T extends DocEntry & HasModuleName>(
|
||||
// }
|
||||
}
|
||||
|
||||
// Note: Don't expect enum value in signatures to be linked correctly
|
||||
// as shiki already splits them into separate span blocks.
|
||||
// Only the enum itself will recieve a link
|
||||
codeWithSyntaxHighlighting = addApiLinksToHtml(codeWithSyntaxHighlighting);
|
||||
|
||||
// shiki returns the lines wrapped by 2 node : 1 pre node, 1 code node.
|
||||
// As leveraging jsdom isn't trivial here, we rely on a regex to extract the line nodes
|
||||
const pattern = /(.*?)<code.*?>(.*?)<\/code>(.*)/s;
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
HasModuleName,
|
||||
HasRenderableJsDocTags,
|
||||
HasStableFlag,
|
||||
MaybeJsDocTags,
|
||||
} from '../entities/traits.mjs';
|
||||
|
||||
import {parseMarkdown} from '../../../shared/marked/parse.mjs';
|
||||
@@ -44,7 +43,7 @@ const jsDoclinkRegex = /\{\s*@link\s+([^}]+)\s*\}/;
|
||||
const jsDoclinkRegexGlobal = new RegExp(jsDoclinkRegex.source, 'g');
|
||||
|
||||
/** Given an entity with a description, gets the entity augmented with an `htmlDescription`. */
|
||||
export function addHtmlDescription<T extends HasDescription & HasModuleName & MaybeJsDocTags>(
|
||||
export function addHtmlDescription<T extends HasDescription & HasModuleName>(
|
||||
entry: T,
|
||||
): T & HasHtmlDescription {
|
||||
const firstParagraphRule = /(.*?)(?:\n\n|$)/s;
|
||||
@@ -57,17 +56,10 @@ export function addHtmlDescription<T extends HasDescription & HasModuleName & Ma
|
||||
?.comment ?? '';
|
||||
}
|
||||
|
||||
let description = entry.description || jsDocDescription;
|
||||
let shortDescription = description.match(firstParagraphRule)?.[0] ?? '';
|
||||
|
||||
// For the cases where the @description tag is after a short description
|
||||
if (jsDocDescription && description !== jsDocDescription) {
|
||||
shortDescription = entry.description;
|
||||
description = jsDocDescription;
|
||||
}
|
||||
|
||||
const description = !!entry.description ? entry.description : jsDocDescription;
|
||||
const shortTextMatch = description.match(firstParagraphRule);
|
||||
const htmlDescription = getHtmlForJsDocText(description).trim();
|
||||
const shortHtmlDescription = getHtmlForJsDocText(shortDescription).trim();
|
||||
const shortHtmlDescription = getHtmlForJsDocText(shortTextMatch ? shortTextMatch[0] : '').trim();
|
||||
|
||||
return {...entry, htmlDescription, shortHtmlDescription};
|
||||
}
|
||||
@@ -145,9 +137,6 @@ function getHtmlAdditionalLinks<T extends HasJsDocTags>(entry: T): LinkEntryRend
|
||||
.filter((tag) => tag.name === JS_DOC_SEE_TAG)
|
||||
.map((tag) => tag.comment)
|
||||
.map((comment) => {
|
||||
// TODO: Throw when the comment is an absolute link.
|
||||
// With TS 5.9 this is not possible as the ts api that extracts comments from tags strips the "http" part of links.
|
||||
|
||||
const markdownLinkMatch = comment.match(markdownLinkRule);
|
||||
|
||||
if (markdownLinkMatch) {
|
||||
@@ -213,6 +202,10 @@ function convertLinks(text: string) {
|
||||
}
|
||||
|
||||
function parseAtLink(link: string): {label: string; url: string} | undefined {
|
||||
// Because of microsoft/TypeScript/issues/59679
|
||||
// getTextOfJSDocComment introduces an extra space between the symbol and a trailing ()
|
||||
link = link.replace(/ \(\)$/, '');
|
||||
|
||||
let [rawSymbol, description] = link.split(/\s(.+)/);
|
||||
if (rawSymbol.startsWith('#')) {
|
||||
rawSymbol = rawSymbol.substring(1);
|
||||
|
||||
@@ -14,7 +14,6 @@ esbuild(
|
||||
external = [
|
||||
"jsdom",
|
||||
"playwright-core",
|
||||
"typescript",
|
||||
],
|
||||
format = "esm",
|
||||
output = "guides.mjs",
|
||||
@@ -39,7 +38,6 @@ esbuild(
|
||||
entry_point = ":index.mts",
|
||||
external = [
|
||||
"jsdom",
|
||||
"typescript",
|
||||
],
|
||||
output = "guides-no-mermaid.mjs",
|
||||
platform = "node",
|
||||
|
||||
@@ -10,15 +10,6 @@ ts_project(
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "heading",
|
||||
srcs = ["heading.mts"],
|
||||
visibility = [
|
||||
"//adev/scripts/routes:__subpackages__",
|
||||
"//adev/shared-docs/pipeline:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "shiki",
|
||||
srcs = ["shiki.mts"],
|
||||
@@ -26,9 +17,7 @@ ts_project(
|
||||
"//adev/shared-docs/pipeline:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":linking",
|
||||
"//adev:node_modules/shiki",
|
||||
"//adev:node_modules/typescript",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -45,17 +34,3 @@ zoneless_jasmine_test(
|
||||
name = "linking_test",
|
||||
data = [":linking_test_lib"],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "heading_test_lib",
|
||||
testonly = True,
|
||||
srcs = ["test/heading.spec.mts"],
|
||||
deps = [
|
||||
":heading",
|
||||
],
|
||||
)
|
||||
|
||||
zoneless_jasmine_test(
|
||||
name = "heading_test",
|
||||
data = [":heading_test_lib"],
|
||||
)
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extracts the ID from a heading text.
|
||||
* Supports custom ID syntax: `## My Heading {#custom-id}`
|
||||
*/
|
||||
export function getIdFromHeading(heading: string): string {
|
||||
// extract the extended markdown heading id
|
||||
// ex: ## MyHeading {# myId}
|
||||
// This is recommended in case we end up having duplicate Ids but we still want the same heading text.
|
||||
// We don't want to make Id generation stateful/too complex to handle duplicates automatically.
|
||||
const customIdRegex = /{#\s*([\w-]+)\s*}/g;
|
||||
const customId = customIdRegex.exec(heading)?.[1];
|
||||
|
||||
if (customId) {
|
||||
return customId;
|
||||
}
|
||||
|
||||
return heading
|
||||
.toLowerCase()
|
||||
.replace(/\s|\//g, '-') // replace spaces and slashes with dashes
|
||||
.replace(/[^\p{L}\d\-]/gu, ''); // only keep letters, digits & dashes
|
||||
}
|
||||
@@ -23,15 +23,6 @@ const LINK_EXEMPT = new Set([
|
||||
'animation',
|
||||
'transition',
|
||||
'trigger',
|
||||
'group()',
|
||||
'keyframes',
|
||||
'@keyframes',
|
||||
'input',
|
||||
'Event',
|
||||
'form',
|
||||
'type',
|
||||
'Host',
|
||||
'filter',
|
||||
]);
|
||||
|
||||
export function shouldLinkSymbol(symbol: string): boolean {
|
||||
|
||||
@@ -18,7 +18,6 @@ ts_project(
|
||||
"//adev:node_modules/mermaid",
|
||||
"//adev:node_modules/playwright-core",
|
||||
"//adev:node_modules/shiki",
|
||||
"//adev/shared-docs/pipeline/shared:heading",
|
||||
"//adev/shared-docs/pipeline/shared:linking",
|
||||
"//adev/shared-docs/pipeline/shared:shiki",
|
||||
"//adev/shared-docs/pipeline/shared/regions",
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ interface DocsCardContainerToken extends Tokens.Generic {
|
||||
// Capture group 1: all attributes on the opening tag
|
||||
// Capture group 2: all content between the open and close tags
|
||||
const cardContainerRule =
|
||||
/^\s*<docs-card-container(?:\s([^>]*))?>((?:.(?!\/docs-card-container))*)<\/docs-card-container>/s;
|
||||
/^[^<]*<docs-card-container(?:\s([^>]*))?>((?:.(?!\/docs-card-container))*)<\/docs-card-container>/s;
|
||||
const headerTitleRule = /headerTitle="([^"]*)"/;
|
||||
const headerImgSrcRule = /headerImgSrc="([^"]*)"/;
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {RendererThis, Token, TokenizerThis, Tokens} from 'marked';
|
||||
import {anchorTarget, loadWorkspaceRelativeFile} from '../../helpers.mjs';
|
||||
import {AdevDocsRenderer} from '../../renderer.mjs';
|
||||
import {Tokens, Token, RendererThis, TokenizerThis} from 'marked';
|
||||
import {loadWorkspaceRelativeFile, anchorTarget} from '../../helpers.mjs';
|
||||
import {setInsideLink} from '../../transformations/link.mjs';
|
||||
|
||||
interface DocsCardToken extends Tokens.Generic {
|
||||
type: 'docs-card';
|
||||
@@ -23,7 +23,7 @@ interface DocsCardToken extends Tokens.Generic {
|
||||
|
||||
// Capture group 1: all attributes on the opening tag
|
||||
// Capture group 2: all content between the open and close tags
|
||||
const cardRule = /^\s*<docs-card(?:\s([^>]*))?>((?:.(?!\/docs-card))*)<\/docs-card>/s;
|
||||
const cardRule = /^[^<]*<docs-card(?:\s([^>]*))?>((?:.(?!\/docs-card))*)<\/docs-card>/s;
|
||||
|
||||
const titleRule = /title="([^"]*)"/;
|
||||
const linkRule = /link="([^"]*)"/;
|
||||
@@ -67,13 +67,11 @@ export const docsCardExtension = {
|
||||
return undefined;
|
||||
},
|
||||
renderer(this: RendererThis, token: DocsCardToken) {
|
||||
return token.imgSrc
|
||||
? getCardWithSvgIllustration(this, token)
|
||||
: getStandardCard(this.parser.renderer as AdevDocsRenderer, token);
|
||||
return token.imgSrc ? getCardWithSvgIllustration(this, token) : getStandardCard(this, token);
|
||||
},
|
||||
};
|
||||
|
||||
function getStandardCard(renderer: AdevDocsRenderer, token: DocsCardToken) {
|
||||
function getStandardCard(renderer: RendererThis, token: DocsCardToken) {
|
||||
if (token.iconImgSrc && token.href) {
|
||||
// We can assume that all icons are svg files since they are custom.
|
||||
// We need to read svg content, instead of renering svg with `img`,
|
||||
@@ -112,11 +110,13 @@ function getStandardCard(renderer: AdevDocsRenderer, token: DocsCardToken) {
|
||||
`;
|
||||
}
|
||||
|
||||
function parseWithoutCreatingLinks(renderer: AdevDocsRenderer, token: DocsCardToken) {
|
||||
renderer.context.disableAutoLinking = true;
|
||||
const parsed = renderer.parser.parse(token.tokens);
|
||||
renderer.context.disableAutoLinking = false;
|
||||
return parsed;
|
||||
function parseWithoutCreatingLinks(renderer: RendererThis, token: DocsCardToken) {
|
||||
setInsideLink(true);
|
||||
try {
|
||||
return renderer.parser.parse(token.tokens);
|
||||
} finally {
|
||||
setInsideLink(false);
|
||||
}
|
||||
}
|
||||
|
||||
function getCardWithSvgIllustration(renderer: RendererThis, token: DocsCardToken) {
|
||||
|
||||
@@ -41,7 +41,6 @@ export const docsCodeBlockExtension = {
|
||||
const headerRule = /header\s*:\s*(['"`])([^'"`]+)\1/; // The 2nd capture matters here
|
||||
const highlightRule = /highlight\s*:\s*(.*)([^,])/;
|
||||
const hideCopyRule = /hideCopy/;
|
||||
const hideDollarRule = /hideDollar/;
|
||||
const preferRule = /\b(prefer|avoid)\b/;
|
||||
const linenumsRule = /linenums/;
|
||||
|
||||
@@ -53,7 +52,6 @@ export const docsCodeBlockExtension = {
|
||||
header: headerRule.exec(metadataStr)?.[2],
|
||||
highlight: highlightRule.exec(metadataStr)?.[1],
|
||||
hideCopy: hideCopyRule.test(metadataStr),
|
||||
hideDollar: hideDollarRule.test(metadataStr),
|
||||
style: preferRule.exec(metadataStr)?.[1] as 'prefer' | 'avoid' | undefined,
|
||||
linenums: linenumsRule.test(metadataStr),
|
||||
};
|
||||
|
||||
@@ -32,7 +32,6 @@ const visibleLinesRule = /visibleLines="([^"]*)"/;
|
||||
const regionRule = /region="([^"]*)"/;
|
||||
const previewRule = /preview/;
|
||||
const hideCodeRule = /hideCode/;
|
||||
const hideDollarRule = /hideDollar/;
|
||||
const preferRule = /\b(prefer|avoid)\b/;
|
||||
|
||||
export const docsCodeExtension = {
|
||||
@@ -53,9 +52,8 @@ export const docsCodeExtension = {
|
||||
const language = languageRule.exec(attr);
|
||||
const visibleLines = visibleLinesRule.exec(attr);
|
||||
const region = regionRule.exec(attr);
|
||||
const preview = previewRule.test(attr);
|
||||
const hideCode = hideCodeRule.test(attr);
|
||||
const hideDollar = hideDollarRule.test(attr);
|
||||
const preview = previewRule.exec(attr) ? true : false;
|
||||
const hideCode = hideCodeRule.exec(attr) ? true : false;
|
||||
const classes = classRule.exec(attr);
|
||||
const style = preferRule.exec(attr);
|
||||
|
||||
@@ -80,7 +78,6 @@ export const docsCodeExtension = {
|
||||
region: region?.[1],
|
||||
preview: preview,
|
||||
hideCode,
|
||||
hideDollar,
|
||||
style: style?.[1] as 'prefer' | 'avoid' | undefined,
|
||||
classes: classes?.[1]?.split(' '),
|
||||
};
|
||||
|
||||
@@ -11,18 +11,13 @@ import {expandRangeStringValues} from './range.mjs';
|
||||
import {JSDOM} from 'jsdom';
|
||||
import {HighlighterGeneric} from 'shiki';
|
||||
import {codeToHtml} from '../../../../shiki.mjs';
|
||||
import {RendererContext} from '../../../renderer.mjs';
|
||||
|
||||
const lineNumberClassName: string = 'shiki-ln-number';
|
||||
|
||||
/**
|
||||
* Updates the provided token's code value to include syntax highlighting.
|
||||
*/
|
||||
export function highlightCode(
|
||||
highlighter: HighlighterGeneric<any, any>,
|
||||
token: CodeToken,
|
||||
context: RendererContext,
|
||||
) {
|
||||
export function highlightCode(highlighter: HighlighterGeneric<any, any>, token: CodeToken) {
|
||||
// TODO(josephperrott): Handle mermaid usages i.e. language == mermaidClassName
|
||||
if (token.language !== 'none' && token.language !== 'file') {
|
||||
// Decode the code content to replace HTML entities to characters
|
||||
@@ -32,11 +27,7 @@ export function highlightCode(
|
||||
? new Set(expandRangeStringValues(token.highlight))
|
||||
: undefined;
|
||||
|
||||
token.code = codeToHtml(highlighter, token.code, {
|
||||
language,
|
||||
highlight,
|
||||
apiEntries: context.apiEntries,
|
||||
});
|
||||
token.code = codeToHtml(highlighter, token.code, {language, highlight});
|
||||
}
|
||||
|
||||
if (token.linenums) {
|
||||
|
||||
@@ -39,8 +39,6 @@ export interface CodeToken extends Tokens.Generic {
|
||||
highlight?: string;
|
||||
/** Whether to hide the copy button */
|
||||
hideCopy?: boolean;
|
||||
/** Whether to hide the dollar sign in the shell code */
|
||||
hideDollar?: boolean;
|
||||
|
||||
// additional classes for the element
|
||||
classes?: string[];
|
||||
@@ -52,7 +50,7 @@ export function formatCode(token: CodeToken, context: RendererContext): string {
|
||||
}
|
||||
|
||||
extractRegions(token);
|
||||
highlightCode(context.highlighter, token, context);
|
||||
highlightCode(context.highlighter, token);
|
||||
|
||||
const containerEl = JSDOM.fragment(`
|
||||
<div class="docs-code${token.style ? ' docs-code-' + token.style : ''}">
|
||||
@@ -134,10 +132,6 @@ function applyContainerAttributesAndClasses(el: Element, token: CodeToken) {
|
||||
if (token.hideCopy) {
|
||||
el.setAttribute('hideCopy', 'true');
|
||||
}
|
||||
if (token.hideDollar) {
|
||||
el.setAttribute('hideDollar', 'true');
|
||||
}
|
||||
|
||||
const language = token.language;
|
||||
|
||||
if (language === 'mermaid') {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {Token, Tokens, RendererThis, TokenizerThis} from 'marked';
|
||||
import {anchorTarget} from '../../helpers.mjs';
|
||||
import {anchorTarget, isExternalLink} from '../../helpers.mjs';
|
||||
import {AdevDocsRenderer} from '../../renderer.mjs';
|
||||
|
||||
interface DocsPillToken extends Tokens.Generic {
|
||||
@@ -70,7 +70,11 @@ export const docsPillExtension = {
|
||||
|
||||
return `
|
||||
<a class="docs-pill" href="${token.href}"${targetAttr}${downloadAttr}>
|
||||
${this.parser.parseInline(token.tokens)}
|
||||
${this.parser.parseInline(token.tokens)}${
|
||||
isExternalLink(token.href)
|
||||
? '<docs-icon class="docs-icon-small">open_in_new</docs-icon>'
|
||||
: ''
|
||||
}
|
||||
</a>
|
||||
`;
|
||||
},
|
||||
|
||||
@@ -31,8 +31,6 @@ export interface RendererContext {
|
||||
apiEntries?: Record<string, {moduleName: string; aliases?: string[]}>;
|
||||
highlighter: HighlighterGeneric<any, any>;
|
||||
headerIds: Map<string, number>;
|
||||
/** In the case we want to disable auto-linking because anchor blocks might be incompatible where some code blocks are being rendered */
|
||||
disableAutoLinking: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-37
@@ -1,39 +1,4 @@
|
||||
Introductory paragraph that should be preserved before any card containers.
|
||||
|
||||
## First Section
|
||||
|
||||
This section contains important information about the feature status.
|
||||
|
||||
### Available features
|
||||
|
||||
- Feature one
|
||||
- Feature two
|
||||
- Feature three
|
||||
|
||||
### In progress
|
||||
|
||||
The following items are currently being developed:
|
||||
|
||||
1. Item A with description
|
||||
2. Item B with description
|
||||
|
||||
<docs-card-container>
|
||||
<docs-card title="Card One"></docs-card>
|
||||
<docs-card title="Card Two"></docs-card>
|
||||
<docs-card></docs-card>
|
||||
<docs-card></docs-card>
|
||||
</docs-card-container>
|
||||
|
||||
### Additional context
|
||||
|
||||
More text after the first card container that should also be preserved.
|
||||
|
||||
## Second Section
|
||||
|
||||
Another paragraph before the second card container.
|
||||
|
||||
<docs-card-container>
|
||||
<docs-card title="Card Three"></docs-card>
|
||||
</docs-card-container>
|
||||
|
||||
## Final Section
|
||||
|
||||
Concluding remarks at the end of the document.
|
||||
|
||||
+4
-54
@@ -20,60 +20,10 @@ describe('markdown to html', () => {
|
||||
markdownDocument = JSDOM.fragment(await parseMarkdown(markdownContent, rendererContext));
|
||||
});
|
||||
|
||||
it('creates multiple card containers with correct card counts', () => {
|
||||
const containers = markdownDocument.querySelectorAll('.docs-card-grid');
|
||||
it('creates card containers containing multiple cards', () => {
|
||||
const containerEl = markdownDocument.querySelector('.docs-card-grid');
|
||||
|
||||
expect(containers.length).toBe(2);
|
||||
expect(containers[0].children.length).toBe(2);
|
||||
expect(containers[1].children.length).toBe(1);
|
||||
});
|
||||
|
||||
it('preserves all h2 section headings', () => {
|
||||
const h2Elements = markdownDocument.querySelectorAll('h2');
|
||||
|
||||
expect(h2Elements.length).toBe(3);
|
||||
expect(h2Elements[0].textContent).toContain('First Section');
|
||||
expect(h2Elements[1].textContent).toContain('Second Section');
|
||||
expect(h2Elements[2].textContent).toContain('Final Section');
|
||||
});
|
||||
|
||||
it('preserves all h3 subsection headings outside card containers', () => {
|
||||
// Card titles also render as h3, so we filter to only h3s not inside card containers
|
||||
const allH3s = Array.from(markdownDocument.querySelectorAll('h3'));
|
||||
const sectionH3s = allH3s.filter((h3) => !h3.closest('.docs-card-grid'));
|
||||
|
||||
expect(sectionH3s.length).toBe(3);
|
||||
expect(sectionH3s[0].textContent).toContain('Available features');
|
||||
expect(sectionH3s[1].textContent).toContain('In progress');
|
||||
expect(sectionH3s[2].textContent).toContain('Additional context');
|
||||
});
|
||||
|
||||
it('preserves unordered lists before card containers', () => {
|
||||
const ulElements = markdownDocument.querySelectorAll('ul');
|
||||
|
||||
expect(ulElements.length).toBeGreaterThanOrEqual(1);
|
||||
expect(ulElements[0].children.length).toBe(3);
|
||||
expect(ulElements[0].textContent).toContain('Feature one');
|
||||
});
|
||||
|
||||
it('preserves ordered lists before card containers', () => {
|
||||
const olElements = markdownDocument.querySelectorAll('ol');
|
||||
|
||||
expect(olElements.length).toBe(1);
|
||||
expect(olElements[0].children.length).toBe(2);
|
||||
expect(olElements[0].textContent).toContain('Item A');
|
||||
});
|
||||
|
||||
it('preserves paragraphs throughout the document', () => {
|
||||
const paragraphs = markdownDocument.querySelectorAll('p');
|
||||
|
||||
expect(paragraphs.length).toBeGreaterThanOrEqual(5);
|
||||
|
||||
const paragraphTexts = Array.from(paragraphs).map((p) => p.textContent);
|
||||
expect(paragraphTexts.some((t) => t?.includes('Introductory paragraph'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('important information'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('More text after'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('Another paragraph'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('Concluding remarks'))).toBeTrue();
|
||||
expect(containerEl!.children.length).toBe(2);
|
||||
expect(containerEl!.classList.contains('docs-card-grid')).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,3 @@ this is a code block
|
||||
```
|
||||
code block without language
|
||||
```
|
||||
|
||||
```shell {hideDollar}
|
||||
echo "hello"
|
||||
```
|
||||
|
||||
+2
-7
@@ -27,10 +27,10 @@ describe('markdown to html', () => {
|
||||
expect(codeBlock?.textContent?.trim()).toBe('this is a code block');
|
||||
});
|
||||
|
||||
it('should parse all 4 code blocks', () => {
|
||||
it('should parse all 3 code blocks', () => {
|
||||
const codeBlocks = markdownDocument.querySelectorAll('.docs-code');
|
||||
|
||||
expect(codeBlocks.length).toBe(4);
|
||||
expect(codeBlocks.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should deindent code blocks correctly', () => {
|
||||
@@ -42,9 +42,4 @@ describe('markdown to html', () => {
|
||||
const codeBlock = markdownDocument.querySelectorAll('.docs-code')[2];
|
||||
expect(codeBlock).toBeDefined();
|
||||
});
|
||||
|
||||
it('should parse the hideDollar attribute', () => {
|
||||
const codeBlock = markdownDocument.querySelectorAll('.docs-code')[3];
|
||||
expect(codeBlock.getAttribute('hideDollar')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,5 +12,3 @@ const form = {
|
||||
state: ['']
|
||||
};
|
||||
</docs-code>
|
||||
|
||||
<docs-code hideDollar code="echo 'hello world'" />
|
||||
|
||||
@@ -52,9 +52,4 @@ describe('markdown to html', () => {
|
||||
const codeBlock = markdownDocument.querySelectorAll('code')[4];
|
||||
expect(codeBlock?.innerHTML).not.toContain('<a href="/api/animations/state">state</a>');
|
||||
});
|
||||
|
||||
it('should parse the hideDollar attribute', () => {
|
||||
const codeBlock = markdownDocument.querySelectorAll('.docs-code')[5];
|
||||
expect(codeBlock.getAttribute('hideDollar')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,10 +25,11 @@ describe('markdown to html', () => {
|
||||
expect(samePageEl.textContent?.trim()).toBe('Same Page');
|
||||
});
|
||||
|
||||
it('should render external links with _blank target', () => {
|
||||
it('should render external links with _blank target and iconography', () => {
|
||||
const samePageEl = markdownDocument.querySelectorAll('a.docs-pill')[1];
|
||||
expect(samePageEl.getAttribute('target')).toBe('_blank');
|
||||
expect(samePageEl.textContent?.trim()).toBe('External Page');
|
||||
expect(samePageEl.textContent?.trim()).toContain('External Page');
|
||||
expect(samePageEl.querySelector('docs-icon')?.textContent).toBe('open_in_new');
|
||||
});
|
||||
|
||||
it('should render internal links that are relative paths', () => {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {parseMarkdown} from '../../parse.mjs';
|
||||
import {resolve} from 'node:path';
|
||||
import {readFile} from 'fs/promises';
|
||||
import {JSDOM} from 'jsdom';
|
||||
import {resolve} from 'node:path';
|
||||
import {parseMarkdown} from '../../parse.mjs';
|
||||
import {rendererContext} from '../renderer-context.mjs';
|
||||
|
||||
describe('markdown to html', () => {
|
||||
@@ -104,10 +104,6 @@ describe('markdown to html', () => {
|
||||
|
||||
expect(h2HeaderId).toBe('my-custom-id');
|
||||
expect(h2AnchorHref).toBe(`#${h2HeaderId}`);
|
||||
|
||||
// Verify that the custom ID syntax is removed from the displayed text
|
||||
expect(h2Anchor?.textContent?.trim()).toBe('My heading');
|
||||
expect(h2Anchor?.textContent).not.toContain('{#');
|
||||
});
|
||||
|
||||
it('should be able to parse heading with a valid tag in a code block', () => {
|
||||
@@ -122,17 +118,4 @@ describe('markdown to html', () => {
|
||||
|
||||
expect(h2.firstElementChild!.innerHTML).toBe('Query for the <code><h1></code>');
|
||||
});
|
||||
|
||||
it('shoud now link symbols in headings', () => {
|
||||
const markdownDocument = JSDOM.fragment(
|
||||
parseMarkdown('## Hello **NEW** `Router` ', rendererContext),
|
||||
);
|
||||
const h2 = markdownDocument.querySelector('h2')!;
|
||||
|
||||
// The anchor element should be to only child, no nested anchor
|
||||
expect(h2.children.length).toBe(1);
|
||||
|
||||
// We ensure that we still style the heading content
|
||||
expect(markdownDocument.querySelector('strong')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,6 @@ export const rendererContext: RendererContext = {
|
||||
Router: {moduleName: 'angular/router'},
|
||||
},
|
||||
headerIds: new Map<string, number>(),
|
||||
disableAutoLinking: false,
|
||||
};
|
||||
|
||||
export async function setHighlighter() {
|
||||
|
||||
@@ -8,15 +8,12 @@
|
||||
|
||||
import {Tokens} from 'marked';
|
||||
import {AdevDocsRenderer} from '../renderer.mjs';
|
||||
import {getIdFromHeading} from '../../heading.mjs';
|
||||
|
||||
export function headingRender(
|
||||
this: AdevDocsRenderer,
|
||||
{depth, tokens, text: headingText, raw}: Tokens.Heading,
|
||||
): string {
|
||||
this.context.disableAutoLinking = true;
|
||||
const parsedText = this?.parser.parseInline(tokens, this);
|
||||
this.context.disableAutoLinking = false;
|
||||
const parsedText = this?.parser.parseInline(tokens);
|
||||
if (depth === 1) {
|
||||
return `
|
||||
<header class="docs-header">
|
||||
@@ -26,11 +23,16 @@ export function headingRender(
|
||||
`;
|
||||
}
|
||||
|
||||
const link = getIdFromHeading(headingText);
|
||||
// extract the extended markdown heading id
|
||||
// ex: ## MyHeading {# myId}
|
||||
// This is recommended in case we end up having duplicate Ids but we still want the same heading text.
|
||||
// We don't want to make Id generation stateful/too complex to handle duplicates automatically.
|
||||
const customIdRegex = /{#\s*([\w-]+)\s*}/g;
|
||||
const customId = customIdRegex.exec(headingText)?.[1];
|
||||
|
||||
// Replace code backticks and remove custom ID syntax from the displayed label
|
||||
let label = parsedText.replace(/`(.*?)`/g, '<code>$1</code>');
|
||||
label = label.replace(/{#\s*[\w-]+\s*}/g, '').trim();
|
||||
const link = customId ?? getIdFromHeading(headingText);
|
||||
|
||||
const label = parsedText.replace(/`(.*?)`/g, '<code>$1</code>');
|
||||
const normalizedLabel = label.replace(/<\/?code>/g, '');
|
||||
|
||||
return `
|
||||
@@ -61,3 +63,10 @@ export function getPageTitle(text: string, filePath?: string): string {
|
||||
}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getIdFromHeading(heading: string): string {
|
||||
return heading
|
||||
.toLowerCase()
|
||||
.replace(/\s|\//g, '-') // replace spaces and slashes with dashes
|
||||
.replace(/[^\p{L}\d\-]/gu, ''); // only keep letters, digits & dashes
|
||||
}
|
||||
|
||||
@@ -6,10 +6,20 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Tokens} from 'marked';
|
||||
import {anchorTarget} from '../helpers.mjs';
|
||||
import {Renderer, Tokens} from 'marked';
|
||||
import {AdevDocsRenderer} from '../renderer.mjs';
|
||||
|
||||
/**
|
||||
* Tracks whether the current renderer is inside a link.
|
||||
*
|
||||
* This is necessary because nested links are invalid HTML and can cause rendering issues.
|
||||
*/
|
||||
let insideLink = false;
|
||||
export function setInsideLink(value: boolean) {
|
||||
insideLink = value;
|
||||
}
|
||||
|
||||
export function linkRender(this: AdevDocsRenderer, {href, title, tokens}: Tokens.Link) {
|
||||
// We have render-time check that we don't create absolute links (which are rendered as external links)
|
||||
// in our guides
|
||||
@@ -30,7 +40,7 @@ export function linkRender(this: AdevDocsRenderer, {href, title, tokens}: Tokens
|
||||
);
|
||||
}
|
||||
|
||||
if (this.context.disableAutoLinking) {
|
||||
if (insideLink) {
|
||||
return this.parser.parseInline(tokens);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import ts from 'typescript';
|
||||
import {HighlighterGeneric, ShikiTransformer} from 'shiki';
|
||||
import {ApiEntries, getSymbolUrl} from './linking.mjs';
|
||||
|
||||
const scanner = ts.createScanner(ts.ScriptTarget.Latest, true);
|
||||
const LIGHT_THEME = 'github-light';
|
||||
const DARK_THEME = 'github-dark';
|
||||
|
||||
@@ -39,7 +36,6 @@ export function codeToHtml(
|
||||
highlighter: HighlighterGeneric<any, any>,
|
||||
code: string,
|
||||
config: {
|
||||
apiEntries?: ApiEntries;
|
||||
language?: string;
|
||||
highlight?: Set<number>;
|
||||
},
|
||||
@@ -52,12 +48,9 @@ export function codeToHtml(
|
||||
},
|
||||
cssVariablePrefix: '--shiki-',
|
||||
defaultColor: false,
|
||||
transformers: [
|
||||
removeWhitespaceTransformer(),
|
||||
highlightTransformer(config.highlight),
|
||||
linkApiEntriesTransformer(config.apiEntries),
|
||||
],
|
||||
transformers: [removeWhitespaceTransformer(), highlightTransformer(config.highlight)],
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
@@ -73,7 +66,7 @@ function highlightTransformer(highlight?: Set<number>): ShikiTransformer {
|
||||
}
|
||||
|
||||
/** A custom transformer which removes all of the whitespace between lines of code in the generated output. */
|
||||
function removeWhitespaceTransformer(): ShikiTransformer {
|
||||
function removeWhitespaceTransformer(highlight?: Set<number>): ShikiTransformer {
|
||||
return {
|
||||
code(code) {
|
||||
code.children = code.children.filter(
|
||||
@@ -82,38 +75,3 @@ function removeWhitespaceTransformer(): ShikiTransformer {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** A custom transformer which adds a link to local API entries whenever a matching identifier is discovered in the code block. */
|
||||
function linkApiEntriesTransformer(apiEntries?: ApiEntries): ShikiTransformer {
|
||||
if (apiEntries === undefined) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
preprocess(code, options) {
|
||||
options.decorations ??= [];
|
||||
scanner.setText(code);
|
||||
let token = scanner.scan();
|
||||
|
||||
while (token !== ts.SyntaxKind.EndOfFileToken) {
|
||||
if (token === ts.SyntaxKind.Identifier) {
|
||||
const symbolUrl = getSymbolUrl(scanner.getTokenText(), apiEntries);
|
||||
if (symbolUrl !== undefined) {
|
||||
options.decorations.push({
|
||||
transform: (el) => {
|
||||
el.tagName = 'a';
|
||||
el.properties['href'] = symbolUrl;
|
||||
return el;
|
||||
},
|
||||
start: scanner.getTokenStart(),
|
||||
end: scanner.getTokenEnd(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
token = scanner.scan();
|
||||
}
|
||||
|
||||
return code;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {getIdFromHeading} from '../heading.mjs';
|
||||
|
||||
describe('getIdFromHeading', () => {
|
||||
it('should generate id from simple text', () => {
|
||||
expect(getIdFromHeading('My Heading')).toBe('my-heading');
|
||||
});
|
||||
|
||||
it('should generate id from text with special characters', () => {
|
||||
expect(getIdFromHeading('Step 2 - Add component')).toBe('step-2---add-component');
|
||||
});
|
||||
|
||||
it('should extract custom id when present', () => {
|
||||
expect(getIdFromHeading('My Heading {#custom-id}')).toBe('custom-id');
|
||||
});
|
||||
|
||||
it('should extract custom id ignoring surrounding spaces', () => {
|
||||
expect(getIdFromHeading('My Heading {# custom-id }')).toBe('custom-id');
|
||||
});
|
||||
|
||||
it('should prioritize custom id over text content', () => {
|
||||
expect(getIdFromHeading('Duplicate Heading {#unique-id}')).toBe('unique-id');
|
||||
});
|
||||
});
|
||||
@@ -47,7 +47,7 @@
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/assets", "src/public"],
|
||||
"assets": ["src/favicon.ico", "src/assets"],
|
||||
"styles": ["src/styles.css"],
|
||||
"scripts": []
|
||||
},
|
||||
|
||||
@@ -5,19 +5,6 @@
|
||||
// as well as better human-readability
|
||||
// --> https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch
|
||||
|
||||
// Grays
|
||||
$gray-1000: oklch(16.93% 0.004 285.95); // #0f0f11
|
||||
$gray-900: oklch(19.37% 0.006 300.98); // #151417
|
||||
$gray-800: oklch(25.16% 0.008 308.11); // #232125
|
||||
$gray-700: oklch(36.98% 0.014 302.71); // #413e46
|
||||
$gray-600: oklch(44% 0.019 306.08); // #55505b
|
||||
$gray-500: oklch(54.84% 0.023 304.99); // #746e7c
|
||||
$gray-400: oklch(70.9% 0.015 304.04); // #a39fa9
|
||||
$gray-300: oklch(84.01% 0.009 308.34); // #ccc9cf
|
||||
$gray-200: oklch(91.75% 0.004 301.42); // #e4e3e6
|
||||
$gray-100: oklch(97.12% 0.002 325.59); // #f6f5f6
|
||||
$gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
|
||||
@mixin root-definitions() {
|
||||
// PRIMITIVES
|
||||
// Colors
|
||||
@@ -60,6 +47,19 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
--symbolic-brown: oklch(49.06% 0.128 46.41); // #994411
|
||||
--symbolic-lime: oklch(70.33% 0.2078857836035299 135.66843631046476); // #5dba00
|
||||
|
||||
// Grays
|
||||
--gray-1000: oklch(16.93% 0.004 285.95); // #0f0f11
|
||||
--gray-900: oklch(19.37% 0.006 300.98); // #151417
|
||||
--gray-800: oklch(25.16% 0.008 308.11); // #232125
|
||||
--gray-700: oklch(36.98% 0.014 302.71); // #413e46
|
||||
--gray-600: oklch(44% 0.019 306.08); // #55505b
|
||||
--gray-500: oklch(54.84% 0.023 304.99); // #746e7c
|
||||
--gray-400: oklch(70.9% 0.015 304.04); // #a39fa9
|
||||
--gray-300: oklch(84.01% 0.009 308.34); // #ccc9cf
|
||||
--gray-200: oklch(91.75% 0.004 301.42); // #e4e3e6
|
||||
--gray-100: oklch(97.12% 0.002 325.59); // #f6f5f6
|
||||
--gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
|
||||
// GRADIENTS
|
||||
--red-to-pink-horizontal-gradient: linear-gradient(
|
||||
90deg,
|
||||
@@ -124,7 +124,7 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
--pink-to-white-horizontal-gradient: linear-gradient(
|
||||
90deg,
|
||||
var(--vivid-pink) 0%,
|
||||
#{$gray-200} 60%
|
||||
var(--gray-200) 60%
|
||||
);
|
||||
|
||||
--light-pink-to-light-purple-horizontal-gradient: linear-gradient(
|
||||
@@ -166,7 +166,7 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
--black-to-gray-vertical-gradient: linear-gradient(
|
||||
0deg,
|
||||
var(--primary-contrast) 0%,
|
||||
#{$gray-400} 100%
|
||||
var(--gray-400) 100%
|
||||
);
|
||||
|
||||
--red-to-pink-vertical-gradient: linear-gradient(0deg, var(--hot-red) 0%, var(--vivid-pink) 100%);
|
||||
@@ -217,35 +217,35 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
// LIGHT MODE is default
|
||||
// contrast - light mode
|
||||
--full-contrast: black;
|
||||
--primary-contrast: #{$gray-900};
|
||||
--secondary-contrast: #{$gray-800};
|
||||
--tertiary-contrast: #{$gray-700};
|
||||
--quaternary-contrast: #{$gray-500};
|
||||
--quinary-contrast: #{$gray-300};
|
||||
--senary-contrast: #{$gray-200};
|
||||
--septenary-contrast: #{$gray-100};
|
||||
--octonary-contrast: #{$gray-50};
|
||||
--primary-contrast: var(--gray-900);
|
||||
--secondary-contrast: var(--gray-800);
|
||||
--tertiary-contrast: var(--gray-700);
|
||||
--quaternary-contrast: var(--gray-500);
|
||||
--quinary-contrast: var(--gray-300);
|
||||
--senary-contrast: var(--gray-200);
|
||||
--septenary-contrast: var(--gray-100);
|
||||
--octonary-contrast: var(--gray-50);
|
||||
--page-background: white;
|
||||
|
||||
// Home page
|
||||
// for the "unfilled" portion of the word that hasn't
|
||||
// been highlighted by the gradient
|
||||
--gray-unfilled: #{$gray-400};
|
||||
--webgl-page-background: var(var(--page-background)) --webgl-gray-unfilled: #{$gray-400};
|
||||
--gray-unfilled: var(--gray-400);
|
||||
--webgl-page-background: var(var(--page-background)) --webgl-gray-unfilled: var(--gray-400);
|
||||
}
|
||||
|
||||
@mixin dark-mode-definitions() {
|
||||
// Contrasts
|
||||
--full-contrast: white;
|
||||
--primary-contrast: #{$gray-50};
|
||||
--secondary-contrast: #{$gray-300};
|
||||
--tertiary-contrast: #{$gray-300};
|
||||
--quaternary-contrast: #{$gray-400};
|
||||
--quinary-contrast: #{$gray-500};
|
||||
--senary-contrast: #{$gray-700};
|
||||
--septenary-contrast: #{$gray-800};
|
||||
--octonary-contrast: #{$gray-900};
|
||||
--page-background: #{$gray-1000};
|
||||
--primary-contrast: var(--gray-50);
|
||||
--secondary-contrast: var(--gray-300);
|
||||
--tertiary-contrast: var(--gray-300);
|
||||
--quaternary-contrast: var(--gray-400);
|
||||
--quinary-contrast: var(--gray-500);
|
||||
--senary-contrast: var(--gray-700);
|
||||
--septenary-contrast: var(--gray-800);
|
||||
--octonary-contrast: var(--gray-900);
|
||||
--page-background: var(--gray-1000);
|
||||
|
||||
--bright-blue: color-mix(in srgb, oklch(51.01% 0.274 263.83), var(--full-contrast) 60%);
|
||||
--indigo-blue: color-mix(in srgb, oklch(51.64% 0.229 281.65), var(--full-contrast) 70%);
|
||||
@@ -260,7 +260,7 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
--orange-red: color-mix(in srgb, oklch(63.32% 0.24 31.68), var(--full-contrast) 60%);
|
||||
--super-green: color-mix(in srgb, oklch(79.12% 0.257 155.13), var(--full-contrast) 70%);
|
||||
--light-vivid-pink-to-light-electric-violet-horizontal-gradient:
|
||||
linear-gradient(hsl(from #{$gray-1000} h s l / 0.9), hsl(from #{$gray-1000} h s l / 0.9)),
|
||||
linear-gradient(hsl(from var(--gray-1000) h s l / 0.9), hsl(from var(--gray-1000) h s l / 0.9)),
|
||||
linear-gradient(
|
||||
hsl(from var(--full-contrast) h s l / 0.2),
|
||||
hsl(from var(--full-contrast) h s l / 0.2)
|
||||
@@ -319,9 +319,9 @@ $gray-50: oklch(98.81% 0 0); // #fbfbfb
|
||||
);
|
||||
|
||||
// Home page - dark mode
|
||||
--gray-unfilled: #{$gray-700};
|
||||
--webgl-page-background: #{$gray-1000};
|
||||
--webgl-gray-unfilled: #{$gray-700};
|
||||
--gray-unfilled: var(--gray-700);
|
||||
--webgl-page-background: var(--gray-1000);
|
||||
--webgl-gray-unfilled: var(--gray-700);
|
||||
|
||||
.docs-toggle {
|
||||
input {
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
|
||||
.docs-reference-category {
|
||||
color: var(--quaternary-contrast);
|
||||
color: var(--gray-400);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.4rem;
|
||||
@@ -260,7 +260,7 @@
|
||||
background-color: var(--septenary-contrast);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
&:focus {
|
||||
background-color: var(--senary-contrast);
|
||||
|
||||
span {
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
.ͼ1 .cm-button {
|
||||
background-image: linear-gradient(var(--octonary-contrast), var(--page-background));
|
||||
|
||||
&:focus-visible {
|
||||
&:focus {
|
||||
background-image: linear-gradient(var(--senary-contrast), var(--page-background));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user