Skip to content

Conversation

@jdotcms
Copy link
Contributor

@jdotcms jdotcms commented Nov 5, 2025

Adding the rag embedding implementation

This PR fixes: #32639

KevinDavilaDotCMS and others added 29 commits November 22, 2025 03:15
Avoid removing the fieldVar "uniquePerSite" in the receiver when doing
PP if the incoming value didn't change.

This PR fixes: #33895

Co-authored-by: Daniel Silva <[email protected]>
This commit adds back the feature that automatically accrues tags to a
visitor when they visit a urlmapped content page.

ref: #33620
…3901)

### Changes:
- Added support for parsing JSON string when `data` field is not a
`Map`.
- Included error handling for invalid JSON and unexpected `data` types.
- Updated logs to improve debugging for invalid `data` values.

ref: #33900
### Changes:
- Replaced Hibernate deletion logic with `DotConnect` SQL execution in
`deleteAllCategories`.

fixes: #33909
…33886)

### Proposed Changes
This pull request introduces a new "New Render Mode" property for custom
fields in the content type editor and refactors the `AngularFormBridge`
to use a singleton pattern for better state management. It also includes
some developer-focused logging and dependency cleanup.

**Custom Field Properties and UI Enhancements:**

* Added a new `newRenderMode` property for custom fields:
- Introduced `NewRenderModePropteryComponent` with a radio button UI to
select between "Recommended" and "Deprecated" render modes
(`new-render-mode-proptery.component.ts`, `.html`, and related
exports/imports).
[[1]](diffhunk://#diff-47f603d13a0f5f9ed0e88929658db8d2ac93cb578f32db02a8a6bca347dfa3f4R1-R34)
[[2]](diffhunk://#diff-04a7bbb9c85442538f0c451a5c6439de10ba254eae598194f0781c4764efbe36R1-R14)
[[3]](diffhunk://#diff-6fb71132ce9a54ccb2d7f7f663166ae5df41956373382770f3f40301634455deR1)
[[4]](diffhunk://#diff-2fdd49e7cef625ae5d2e851997320147801a93eaa806e6d748b4f56908fdf4ceR9)
[[5]](diffhunk://#diff-f8011cbc534292a6c2d0c7dc2f478f2bf225d1b6b6f4f9a51646555191873649L13-R14)
[[6]](diffhunk://#diff-f8011cbc534292a6c2d0c7dc2f478f2bf225d1b6b6f4f9a51646555191873649R93-R97)
[[7]](diffhunk://#diff-0f3ec14af7770b7e5376a79d0ebe9857b53fd3a61a4afb3725d1f5f515e95753R57)
[[8]](diffhunk://#diff-0f3ec14af7770b7e5376a79d0ebe9857b53fd3a61a4afb3725d1f5f515e95753L115-R117)
- Updated `FieldPropertyService` to include `newRenderMode` in custom
field properties.
[[1]](diffhunk://#diff-bde383871412422b64c2a096eeda7acad8858088182afe147943fae6d6113629L4-R4)
[[2]](diffhunk://#diff-bde383871412422b64c2a096eeda7acad8858088182afe147943fae6d6113629L23-R33)
- Modified the form property transformation logic to emit the correct
structure for `fieldVariables` when saving custom fields.
[[1]](diffhunk://#diff-3b9565f5bcb92a0cccbfa5df0c0e3675ba748ecfb41381e736bd4c2a8e42efb9L19-R19)
[[2]](diffhunk://#diff-3b9565f5bcb92a0cccbfa5df0c0e3675ba748ecfb41381e736bd4c2a8e42efb9L75-R101)

**AngularFormBridge Refactor and Testing:**

* Refactored `AngularFormBridge` to implement the singleton pattern:
- Added `getInstance` and `resetInstance` static methods to ensure only
one bridge instance exists at a time, and updated the factory to use
this pattern.
[[1]](diffhunk://#diff-08b7f2dbb6ec1f4033d7a5801c7f63b080a8f9565b11c3f9b7c40ea512578e6fR17-R63)
[[2]](diffhunk://#diff-08b7f2dbb6ec1f4033d7a5801c7f63b080a8f9565b11c3f9b7c40ea512578e6fR164-R175)
[[3]](diffhunk://#diff-7e7427e48350646c481f2a6d1653c32ba7e345af017115e8c16ae748689e1bfeL39-R39)
- Updated tests to cover singleton behavior, including instance reuse,
warning on parameter mismatch, and proper cleanup.
[[1]](diffhunk://#diff-56d79fca411f7de0eccc5e1f0b399892ecebc2c9a5148d75ebba52fa1f272639R38-R49)
[[2]](diffhunk://#diff-56d79fca411f7de0eccc5e1f0b399892ecebc2c9a5148d75ebba52fa1f272639R220-R309)

**Developer Experience and Maintenance:**

* Added console logging in key field save/edit methods to aid debugging
during development.
[[1]](diffhunk://#diff-b1988fdbb798b95d236e7d8fe4d0225c7ae7d153a4490f8a7eb2a7cb197be6d9R265)
[[2]](diffhunk://#diff-baf830d0ccf4bb80b652bd323f6c5778e2120b7f2c58b37f6084b3aa2c63c2bcR236)
[[3]](diffhunk://#diff-baf830d0ccf4bb80b652bd323f6c5778e2120b7f2c58b37f6084b3aa2c63c2bcR265)
* Cleaned up dependencies in `edit-content-bridge/package.json` by
removing unused packages.
* Minor import update in `dot-edit-content-text-field.component.ts` to
use `linkedSignal` instead of `computed`.

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **


This PR fixes: #33786
…ment (#33811)

# Description

This PR successfully integrates the `GlobalStore` into the
`DotNavigationComponent` for centralized menu state management. The
refactoring replaces the previous service-based approach with
signal-based state management using **NgRx Signals** and **NgRx
Entities**.

This transition provides better immutability, optimized change
detection, and a normalized state structure, significantly reducing the
complexity of logic required to manage menu items.

## Key Changes

### Architecture & State Management
* **Adoption of NgRx Entities (`withEntities`):** The
`with-menu.feature.ts` has been refactored to use the Entity pattern.
* **Normalized State:** Menu items are now stored as an entity
collection (Ids + Entities dictionary) rather than a simple array.
* **Simplified Logic:** Removed custom logic for finding and updating
items. We now leverage built-in entity updaters (e.g., `updateEntity`,
`setAllEntities`) for cleaner and more performant state mutations.
* **Menu Feature (`with-menu.feature.ts`):**
* Implements computed signals for active menu detection based on the
entity map.
* Maintains `localStorage` persistence for navigation collapsed/expanded
state.
    * Automatic sync with external changes.

### Navigation & Routing
* **Query Parameters Implementation:**
* Navigation now utilizes query parameters to track context, appending a
shortened parent ID (`mId`) to the URL (e.g.,
`/dotAdmin#/starter?mId=2df9`).
* **Edge Case Resolution:** This strategy resolves multiple edge cases
regarding active menu highlighting and breadcrumb generation, ensuring
state persistence across reloads and deep links.

### Refactoring & Cleanup
* **Logic Reduction:** Removed manual array manipulation methods, as
NgRx Entities handles CRUD operations natively.
* **DotCrumbtrailService:** Deleted as it is obsolete following the
implementation of the new breadcrumb system and the routing
improvements.

### Component Integration
* **DotNavigationComponent:**
    * Now reads state directly from `GlobalStore` entity signals.
    * Removed dependency on `DotNavigationService.items$` observable.
* Uses `GlobalStore` entity methods for all state mutations, ensuring a
cleaner separation of concerns.

### Test Updates
* Comprehensive test coverage updates to reflect the new GlobalStore and
Entity structure.
* Tests now validate the normalized GlobalStore state and the presence
of query parameters in navigation actions.

## Related issue
Closes #33642

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Nicolas Molina Monroy <[email protected]>
#33731)

## Sumary

Implement database persistence for style properties by modifying the
database schema and updating the MultiTree data model to support the new
styling functionality.

### Proposed Changes
- [x] Add `style_properties` field into `multi_tree` table using the
`postgres.sql` for new databases.
- [x] Add `style_properties` field into `multi_tree` table using an
Update Task for existing databases.
- [x] Integration tests for the Update Task.
- [x] Add new integration test into the Suite a3.

Plus add the connection between the database and Java clases to manage
the new `styleProperties` field.

### Proposed Changes
- [x] `MultiTree` Add styleProperties class field (constructor, getter
and setter).
- [x] `MultiTreeAPIImpl` Add new field into the insert query and
operations validating that the value is a valid Json String.
- [x] `MultiTreeAPITest` Test different scenarios where the
styleProperties is present, updated or not defined.
- [x] `MultiTreeTransformer` Includes MultiTree field.


This PR fixes: #33693
…e Field Variables to a new field (#33916)

# 📝 Summary

This PR enhances the Field REST API to support creating and associating
field variables when adding or moving fields in a Content Type.
Previously, field variables could only be added after a field was
created; now they can be included in the initial field creation request.

# 🎯 Changes

## Backend Enhancements
### Field API (FieldAPI / FieldAPIImpl)
- ✅ Added save(List<FieldVariable> fieldVariables, Field field) method
to persist multiple field variables atomically
  - ✅ Implemented smart field variable synchronization:
    - Creates new field variables from incoming list
    - Updates existing variables when key matches but value differs
    - Removes variables that no longer exist in the incoming list
  - ✅ Enhanced existing save() methods with improved documentation

### Field REST Resource (FieldResource)
  - ✅ Enhanced /move endpoint with comprehensive OpenAPI documentation
  - ✅ Added detailed @operation, @apiresponse, and example JSON payloads
  - ✅ Improved endpoint description explaining its use cases:
    - Dragging-and-dropping new fields
    - Moving existing fields in the layout
    - Creating fields with associated field variables
  - ✅ Updated parameter documentation for better API clarity

### Field Transformers & Models
- ✅ Updated JsonFieldTransformer to handle field variables during
serialization
  - ✅ Enhanced CustomField to properly support field variables
- ✅ Improved ContentTypeFieldLayoutAPIImpl to process field variables in
layout operations

### OpenAPI Documentation

- ✅ Added comprehensive endpoint documentation with real-world JSON
examples
- ✅ Included detailed response schemas showing field variables structure
  - ✅ Documented all response codes (200, 400, 401, 404)

### Tests

- ✅ Updated Postman test suite (ContentTypeResourceTests.json) with new
test cases
  - ✅ Added validation for field variable persistence
  - ✅ Enhanced test coverage for field creation/update scenarios

##  🔍 Technical Details

### Field Variable Synchronization Logic:
  // Smart sync: Compares existing vs incoming field variables
  // - Deletes variables removed from incoming list
  // - Creates new variables not in existing list
  // - Preserves unchanged variables

### API Request Example:
```json
  {
    "layout": [{
      "divider": { ... },
      "columns": [{
        "columnDivider": { ... },
        "fields": [{
          "name": "Description",
          "variable": "description",
          "fieldType": "Text",
          "fieldVariables": [{
            "key": "My Field Var",
            "value": "My value"
          }]
        }]
      }]
    }]
  }
```

###  🧪 Testing

  - ✅ Integration tests updated and passing
  - ✅ Postman API tests expanded with field variable scenarios
- ✅ Verified field variable persistence across create/update operations

### 📚 Documentation

  - ✅ Enhanced inline Javadoc for all modified API methods
- ✅ Added OpenAPI annotations for automatic API documentation generation
  - ✅ Included practical JSON examples in endpoint documentation

This PR fixes: #33911

Co-authored-by: erickgonzalez <[email protected]>
### Proposed Changes
This pull request introduces several improvements and refactors to the
navigation menu components and their associated state management. The
main changes include simplifying the logic for determining active
navigation items, updating menu group label rendering, and refactoring
how the menu collapsed state is managed in the global store.

**Navigation UI and Label Rendering:**
- The logic for applying the active class to navigation items in
`dot-nav-item.component.html` now directly uses the `data.isOpen`
property instead of the `isGroupActive()` method, making the UI state
more predictable and easier to follow.
- In the sub-navigation component, menu group labels now use the
`data.label` property instead of `data.tabName`, ensuring consistency
and clarity in label rendering.

**Component and State Management Refactors:**
- The `isGroupActive` method reference has been removed from
`DotNavItemComponent`, reflecting the shift to using the `data.isOpen`
property for determining active state.
- The host binding for the collapsed class in `DotNavItemComponent` has
been updated to use Angular's property binding syntax, improving
maintainability and clarity.
- The document click handler that previously closed the fly-out menu
when navigation was collapsed has been removed from
`DotNavigationComponent`, simplifying event handling.

**Global Store and Menu State Updates:**
- The menu entity configuration now uses the `type<MenuItemEntity>()`
helper from NgRx Signals, improving type safety in the global store.
[[1]](diffhunk://#diff-e0c5afb6aa7c49959410511d227e5c91effb8b8b551637621cccc42db9254ce0R1)
[[2]](diffhunk://#diff-e0c5afb6aa7c49959410511d227e5c91effb8b8b551637621cccc42db9254ce0L11-R12)
- The logic for toggling the navigation collapsed state has been
streamlined, removing special handling for opening/closing parent groups
and simplifying the state patching process.
- When collapsing the navigation, the code no longer explicitly sets
`openParentMenuId` to `null`, further simplifying state management.
- The transformation of grouped menu items into menu groups in the
`withMenu` feature is now explicitly assigned to a variable for clarity.
[[1]](diffhunk://#diff-c7e84106a469b8614890a1a6996bb507192eee7f9e70d69e9546308562157dfcL71-R71)
[[2]](diffhunk://#diff-c7e84106a469b8614890a1a6996bb507192eee7f9e70d69e9546308562157dfcR81)

### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)



### Screenshots
<img width="1013" height="775" alt="Screenshot 2025-11-25 at 1 43 13 PM"
src="https://github.com/user-attachments/assets/1c395f8d-e1e8-4545-8223-35aaf76891b9"
/>

<img width="231" height="306" alt="Screenshot 2025-11-25 at 4 07 21 PM"
src="https://github.com/user-attachments/assets/4065338a-f64c-458f-b6a9-4878bd698b97"
/>



This PR fixes: #33642

---------

Co-authored-by: Adrian Molina <[email protected]>
…icks (#33922)

The `listenBlockEditorInlineEvent()` function previously listened to the
`load` event on `window`, which could fail to trigger in certain
scenarios:

- If the script executes after `load` has already fired, the listener
never runs
- In iframes or with async script loading, `load` may have already
occurred
- The event listener cleanup had bugs: using
`window.removeEventListener` instead of `document.removeEventListener`,
and creating a new anonymous function reference that prevented proper
cleanup

### Solution

**Changed from `load` to `DOMContentLoaded`:**
- `DOMContentLoaded` fires earlier, when the HTML is parsed (before
images, stylesheets, etc.)
- More reliable for early DOM initialization
- Fires on `document`, which aligns with our use case

**Fixed event listener cleanup:**
- Changed `window.removeEventListener` to `document.removeEventListener`
(correct target)
- Stored the handler function reference to enable proper cleanup
- Removed unnecessary cleanup logic when the page is already loaded

### Technical Details

- `load` event: Fires on `window` when all resources are loaded (images,
stylesheets, etc.)
- `DOMContentLoaded` event: Fires on `document` when HTML is parsed,
before waiting for external resources

This change ensures the block editor inline event listener is properly
initialized regardless of when the script executes, and allows correct
cleanup of event listeners.

---



https://github.com/user-attachments/assets/cf39a5cf-a7f8-4bad-9e06-fba68bfc1a15


This PR fixes: #33848

---------

Co-authored-by: Kevin <[email protected]>
…assed Refs: #33704 (#33896)

### Proposed Changes
* Reverting a change that returned the contentlet as soon as it was
gotten from the api using time-machine
* In case of not getting the contentlet from the time machine, we try to
get the most recent live instance
* The respective test was added 

This PR fixes: #33704
#33894)

## Summary
This PR addresses multiple issues in the SDK client and React hooks,
including the primary bug #33874 regarding missing 404 HTTP errors in
page requests.

## Changes

### 1. PageClient 404 Error Handling (#33874)
- ✅ Add proper 404 `DotHttpError` when page is not found
- ✅ Add 400 Bad Request error for GraphQL DotPage entity errors  
- ✅ Include graphql query and variables in all error scenarios for
better debugging
- ✅ Add comprehensive error handling tests covering multiple scenarios

**Before:**
```typescript
if (!pageResponse) {
    throw new DotErrorPage(
        `Page ${url} not found...`,
        undefined,  // ❌ Missing HttpError
        { query, variables }
    );
}
```

**After:**
```typescript
if (!pageResponse) {
    throw new DotHttpError({
        status: 404,
        statusText: 'Not Found',
        message: `Page ${url} not found...`
    });
    // Caught and wrapped in DotErrorPage with httpError
}
```

### 2. CollectionBuilder Draft Query Fix
- ✅ Fix draft content queries to use proper Lucene syntax
- ✅ Change from `+live:false` to `+(live:false AND working:true AND
deleted:false)`
- ✅ Deprecate legacy query method with JSDoc annotation
- ✅ Update tests to reflect new query format

**Why:** The previous query `+live:false` would match any content that
wasn't live, including deleted content. The new query ensures we only
get working drafts.

### 3. useAISearch Hook Stability
- ✅ Fix search callback changing when params change (prevents infinite
loops in useEffect)
- ✅ Use `useRef` to store params while keeping callback identity stable
- ✅ Add tests for callback stability and latest params usage

**Why:** When the `search` callback changed on every params update, it
could cause infinite loops if used as a dependency in `useEffect`.

## Test Coverage
- Added 5 new test cases for PageClient error handling
- Added 2 new test cases for useAISearch callback stability
- Updated existing CollectionBuilder tests for new query format

## Impact
- ✅ Error responses now include proper HTTP status codes
- ✅ Downstream error handling can distinguish between error types (404,
400, etc.)
- ✅ Draft content queries work correctly
- ✅ React hooks are more stable and prevent infinite loops

## Related Issues
Fixes #33874

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <[email protected]>
…33892)

## Summary
Fixes issue where hidden secrets (like passwords and API keys) would be
converted to the mask value `******` when saved from the UI, causing the
actual secret values to be lost and breaking integrations.

## Changes
- **AppsAPIImpl.java**: Added `maintainHiddenValues()` method that
preserves existing hidden secret values when the incoming value is the
mask string (`******`)
- **AppsHelper.java**: Simplified save logic to always delete and
re-save secrets cleanly

## Technical Details
When a user edits app secrets in the UI:
1. Hidden fields display as `******` for security
2. On save, the API now checks if incoming secrets are hidden AND equal
to the mask value
3. If so, it retrieves and maintains the original stored value instead
of saving the mask
4. Non-hidden or changed secrets are saved normally

## Test Plan
- [ ] Verify hidden secrets maintain their actual values after UI save
- [ ] Verify new secret values can still be updated through the UI
- [ ] Verify non-hidden secrets save normally
- [ ] Verify integrations using hidden secrets continue working after UI
saves

🤖 Generated with [Claude Code](https://claude.com/claude-code)

This PR fixes: #29075
…er Lacks Permission Headless (#33905)

### WIP

This PR fixes: #33832

---------

Co-authored-by: fabrizzio-dotCMS <[email protected]>
Co-authored-by: Fabrizzio Araya <[email protected]>
This PR is a quick demo for @dsantos-dcms to show how to create a
portlet in dotCMS codebase

### Video


https://github.com/user-attachments/assets/224778f4-c550-48b1-b1e7-74f2e0b04527

resolves #33921

---------

Co-authored-by: dsantos <[email protected]>
Co-authored-by: Stephen Bolton <[email protected]>
Before 

When updating the Email ID via PUT: This wasn't updating the email ID


<img width="884" height="645" alt="Screenshot 2025-10-29 at 2 20 44 PM"
src="https://github.com/user-attachments/assets/6fb59410-2d70-4aa1-8c91-c6fe48d7ce8f"
/>
<img width="1092" height="833" alt="Screenshot 2025-10-29 at 2 20 48 PM"
src="https://github.com/user-attachments/assets/31027a97-deb9-426c-b3e6-4aa7bac32259"
/>
<img width="908" height="627" alt="Screenshot 2025-10-29 at 2 21 57 PM"
src="https://github.com/user-attachments/assets/de23caca-355a-4606-a554-bebdd5065365"
/>



After 

- Add missing email field update logic in UserResource.updateUser()
- Fix firstName to use conditional updates like other fields for
consistent partial update behavior
- Resolves #33617: Email field was being ignored during user updates

Changes:
- Added: if (UtilMethods.isSet(updateUserForm.getEmail())) {
userToSave.setEmailAddress(...) }
- Fixed: firstName now uses conditional update to preserve existing
values when not provided
- Maintains: All existing validation, security checks, and duplicate
email prevention
- 
We are now successfully able to update the email ID.

<img width="926" height="648" alt="Screenshot 2025-10-29 at 2 22 43 PM"
src="https://github.com/user-attachments/assets/44ac81ec-1efe-4cd0-96d8-7750ca10b9bf"
/>
<img width="1658" height="928" alt="Screenshot 2025-10-29 at 2 23 28 PM"
src="https://github.com/user-attachments/assets/b2235a39-83e0-4c80-afd9-c3010c2b71e6"
/>
<img width="905" height="635" alt="Screenshot 2025-10-29 at 2 23 52 PM"
src="https://github.com/user-attachments/assets/796d1597-5fd3-4c29-b2bd-15bde7bd1518"
/>
<img width="1623" height="923" alt="Screenshot 2025-10-29 at 2 23 59 PM"
src="https://github.com/user-attachments/assets/de939acc-9763-4353-9388-7485d9caf123"
/>

Co-authored-by: daniel.solis <[email protected]>
Co-authored-by: Daniel Silva <[email protected]>
…ack-end for `content_click` and `conversion` events (#33924)

### Proposed Changes
* Adjusting the validation of specific attributes for the
`content_click` event.
* Removing unnecessary attribute validations for the `conversion` event.
* Fixing the Postman test.

---------

Co-authored-by: Arcadio Quintero <[email protected]>
## Summary

Major refactor and enhancement of the `@dotcms/analytics` SDK that adds
automatic `content_click` tracking capabilities alongside improved
content impression tracking. This PR introduces a new click tracking
plugin, reorganizes the codebase for better maintainability, and
enhances the logging system with plugin-specific debug output.

## Changes Made

### Backend (SDK Architecture)

- **New Click Tracking System**: Implemented complete click tracking
infrastructure
-
[dot-analytics.click-tracker.ts](core-web/libs/sdk/analytics/src/lib/core/plugin/click/dot-analytics.click-tracker.ts):
Core tracker class with MutationObserver and event listener management
-
[dot-analytics.click.plugin.ts](core-web/libs/sdk/analytics/src/lib/core/plugin/click/dot-analytics.click.plugin.ts):
Analytics.js plugin integration
-
[dot-analytics.click.utils.ts](core-web/libs/sdk/analytics/src/lib/core/plugin/click/dot-analytics.click.utils.ts):
Click detection, throttling, and payload construction utilities

- **Code Organization Refactoring**:
  - Renamed core files with consistent `dot-analytics.*` prefix pattern
- Reorganized plugin structure: moved main plugin to `plugin/main/`
directory
  - Consolidated shared utilities into `shared/utils/` directory
- Renamed constants file for consistency:
`dot-content-analytics.constants.ts` → `dot-analytics.constants.ts`

- **Enhanced Utilities**
([dot-analytics.utils.ts](core-web/libs/sdk/analytics/src/lib/core/shared/utils/dot-analytics.utils.ts)):
  - New `createPluginLogger()` for plugin-specific debug output
  - New `createContentletObserver()` for shared MutationObserver logic
- New `getEnhancedTrackingPlugins()` for conditional plugin loading
(impressions/clicks)
  - New `extractContentletData()` utility for consistent data extraction
  - Extracted `findContentlets()` utility for reusable DOM queries
  - Added `setupPluginCleanup()` for standardized cleanup lifecycle

- **Activity Tracking Simplification**:
  - Moved activity tracking into identity plugin scope
  - Removed standalone activity tracker exposure
- Simplified identity tracking logic
([dot-analytics.identity.utils.ts](core-web/libs/sdk/analytics/src/lib/core/plugin/identity/dot-analytics.identity.utils.ts):13-71)

- **Impression Tracking Improvements**:
  - Refactored tracker to use new shared utilities
  - Simplified observer logic using `createContentletObserver()`
  - Removed redundant utility functions (moved to shared utils)
  - Enhanced logging with plugin-specific logger

### API Changes

- **New Event Type**: Added `content_click` event type
- Event payload includes: content metadata, viewport position, element
details, and attributes
- Type definition: `DotCMSContentClickPayload`
([event.model.ts](core-web/libs/sdk/analytics/src/lib/core/shared/models/event.model.ts):45-67)

- **Configuration Enhancement**:
- New config option: `clicks?: boolean` to enable/disable click tracking
- New config option: `impressions?: boolean` to enable/disable
impression tracking
  - Both default to `true` for backward compatibility

- **Plugin API**:
- Enricher plugin now handles both `content_impression` and
`content_click` events
  - Conditional plugin loading based on feature flags

### Frontend

- **Logging System**
([dot-analytics.logger.ts](core-web/libs/sdk/analytics/src/lib/core/shared/dot-analytics.logger.ts)):
- New `createPluginLogger()` factory for plugin-specific console output
  - Consistent prefix format: `DotCMS Analytics [PluginName]:`
- Supports `log`, `warn`, `info`, `debug`, `error` levels with debug
flag control

- **React Hook Updates**:
  - Updated imports to use new file paths
  - No functional changes to `useRouterTracker` or `useRouteTracker`

### Tests

- Comprehensive test coverage for click tracking:
  - Click detection on `<a>` and `<button>` elements
  - Contentlet container validation
  - Payload construction and metadata extraction
  - Throttling behavior
  - MutationObserver integration

- Updated test imports across all test files for new file structure
- Maintained 100% test coverage for refactored utilities

### Configuration

- **Dependencies**:
  - Added `@analytics/router-utils@^0.1.1` for future routing utilities
- Reordered dependencies alphabetically in
[package.json](core-web/libs/sdk/analytics/package.json:23-29)
- Added Vite source map support
([vite.config.mts](core-web/libs/sdk/analytics/vite.config.mts):38)

## Technical Details

### Click Tracking Architecture

The click tracking system follows the same pattern as impression
tracking:

1. **Initialization**: Plugin creates `DotCMSClickTracker` instance with
Analytics.js instance
2. **Discovery**: Initial scan finds all `.dotcms-analytics-contentlet`
elements (after 100ms delay for React/Next.js rendering)
3. **Event Listeners**: Attaches click listeners to each contentlet
container
4. **Click Detection**: Filters clicks to only track `<a>` and
`<button>` elements inside contentlets
5. **Payload Construction**: Extracts content metadata, viewport
position, element details, and attributes
6. **Throttling**: Prevents duplicate events within 300ms window
7. **Dynamic Content**: MutationObserver detects new contentlets and
attaches listeners automatically
8. **Cleanup**: Removes all listeners on page unload

### Shared Utilities Pattern

Refactored common logic into reusable utilities:
- **Observer Pattern**: `createContentletObserver()` provides simple
MutationObserver setup
- **Logging Pattern**: `createPluginLogger()` ensures consistent debug
output across plugins
- **DOM Utilities**: `findContentlets()` and `extractContentletData()`
eliminate duplication
- **Plugin Lifecycle**: `setupPluginCleanup()` standardizes cleanup
handlers

### Conditional Plugin Loading

The `getEnhancedTrackingPlugins()` utility conditionally loads plugins
based on config:
- `config.impressions === false` → skip impression plugin
- `config.clicks === false` → skip click plugin
- Both default to `true` for backward compatibility

This allows users to disable tracking features they don't need.

## Breaking Changes

None. All changes are backward compatible:
- Existing impression tracking continues to work without configuration
changes
- New click tracking is enabled by default but can be disabled with
`clicks: false`
- All public API signatures remain unchanged

## Testing

- [x] Unit tests added for click tracking system
- [x] Unit tests updated for refactored utilities
- [x] Integration tests pass (manual testing in Next.js example app)

## Related Issues

Closes #33614

## Additional Notes

### Migration Guide (for future reference)

If you're using the SDK and want to disable new click tracking:

```typescript
import { initializeContentAnalytics } from '@dotcms/analytics';

const analytics = initializeContentAnalytics({
  apiKey: 'your-api-key',
  server: 'https://your-server.com',
  clicks: false, // Disable click tracking
  impressions: true // Keep impressions enabled (default)
});
### Proposed Changes

This pull request introduces enhancements to how the "render mode"
property (`newRenderMode`) is handled for content type fields in DotCMS.
It standardizes the use of constants for render modes, ensures more
robust defaulting behavior when accessing this property, and adds
comprehensive unit tests to verify the new logic. Additionally, type
definitions are updated for better type safety and clarity.

Key changes:

**Render Mode Handling Improvements**
- The `getValue` method in `FieldPropertyService` now safely retrieves
the `newRenderMode` value from `fieldVariables`, defaulting to
`DotRenderModes.IFRAME` if not set or if the field/variable is missing,
improving robustness and predictability.
- The `clazz` property for field variables is now set using the
`DotCMSClazzes.FIELD_VARIABLE` constant instead of a string literal,
ensuring consistency.

**Type and Constant Enhancements**
- Introduced `DotRenderModes` and added it to
`dot-content-types.model.ts` to define allowed render modes (`iframe`,
`components`) as constants.
- Updated the `DotCMSContentTypeFieldVariableRenderMode` interface to
strongly type the `newRenderMode` field variable, improving type safety
for render mode handling.
- Updated the `ContentTypeCustomField` interface to specify that
`fieldVariables` can include `DotCMSContentTypeFieldVariableRenderMode`
objects.

**Testing**
- Added comprehensive unit tests for the `getValue` method, covering
scenarios for the presence, absence, and various edge cases of the
`newRenderMode` property, as well as fallback and defaulting logic.
- Updated imports in the test file to include the new constants and
types.

### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)



This PR fixes: #33786
…handle fallbacks for old bookmarks (#33928)

### Description
Refactored the menu item search logic in the breadcrumb system to
correctly handle distinct scenarios based on the presence of query
parameters (`query params`) and the parent menu ID (`shortMenuId`), in
order to handle old bookmarks.

### Changes Made

#### Modified File
-
`core-web/libs/global-store/src/lib/features/breadcrumb/breadcrumb.feature.ts`

#### Updated Logic Details

Enhanced the `find()` method in the `processUrl()` function to implement
the following logic:

1. **With `shortMenuId` present**: Validates that both the `menuLink`
matches the route (`urlPath`) and the `parentMenuId` starts with the
`shortMenuId`.

2. **Without `shortMenuId` but with query params**: Returns no item,
preventing incorrect breadcrumb associations.

3. **Without `shortMenuId` and without query params**: Returns the item
where `menuLink` matches `urlPath`.

### Benefits
-  Improved handling of routes with query parameters
- Prevention of incorrect breadcrumbs on URLs with filters or additional
parameters
-  Greater precision in associating menu items to breadcrumbs


This PR fixes: #33642

---------

Co-authored-by: Nicolas Molina Monroy <[email protected]>
…33938)

### Proposed Changes

This pull request introduces comprehensive updates to Angular frontend
development documentation and best practices across several files. The
main focus is to align all developer instructions, style guides, and
context rules with Angular 20+ standards, emphasizing standalone
components, signals for state management, modern control flow, and
improved testing patterns. The changes also introduce new, detailed
instructions for both human and AI contributors, ensuring consistency
and clarity for all developers working on the project.

**Key changes include:**

### 1. Angular and Tooling Version Updates
- Updated all references to Angular from version 18/19 to **Angular
20.3.9** and upgraded Nx from 19.6.5 to **20.5.1** to reflect the
current tech stack.
[[1]](diffhunk://#diff-c6ae7ee19734344812a52d25c2a346c74d21e62a47a30412785371db4e4ab93dL129-R229)
[[2]](diffhunk://#diff-18071d1ec9ef896374ead514d4feb877a415e290d2412598bc00a956d52589faL4-R8)

### 2. Best Practices and Style Guide Modernization
- Overhauled the TypeScript and Angular best practices sections to focus
on:
  - Strict type checking, type inference, and avoiding `any`.
- Using signals for reactive state, standalone components (without
explicit `standalone: true`), and the latest control flow syntax (`@if`,
`@for`, `@switch`).
- Discouraged use of enums, `@HostBinding`, `@HostListener`, `ngClass`,
and `ngStyle` in favor of modern alternatives.
[[1]](diffhunk://#diff-c6ae7ee19734344812a52d25c2a346c74d21e62a47a30412785371db4e4ab93dL3-R169)
[[2]](diffhunk://#diff-32ebf906b601e69acb4980e6fa00bf468864ac6e0935e700dd9f2eae93982e9eR1-R142)

### 3. Expanded and Unified Documentation
- Added a new `.github/copilot-instructions.md` file with clear,
detailed build, test, and project structure instructions for both
backend and frontend, including Maven dependency management and Angular
coding patterns.
- Introduced `.github/frontend.instructions.md` for AI and developer
guidance, providing persona, examples, resources, and a concise style
guide for Angular 20+.

### 4. Testing and File Structure Guidance
- Standardized testing instructions to require Spectator with Jest or
Vitest for all Angular tests, and clarified usage of `data-testid` and
Spectator utilities.
[[1]](diffhunk://#diff-c6ae7ee19734344812a52d25c2a346c74d21e62a47a30412785371db4e4ab93dL3-R169)
[[2]](diffhunk://#diff-32ebf906b601e69acb4980e6fa00bf468864ac6e0935e700dd9f2eae93982e9eR1-R142)
- Updated file structure recommendations for Angular components and
removed redundant or outdated examples.

### 5. Documentation Consistency and Coverage
- Ensured all documentation, including `ANGULAR_STANDARDS.md`, reflects
the latest stack and best practices, and harmonized terminology and
formatting across files.
[[1]](diffhunk://#diff-18071d1ec9ef896374ead514d4feb877a415e290d2412598bc00a956d52589faL4-R8)
[[2]](diffhunk://#diff-c6ae7ee19734344812a52d25c2a346c74d21e62a47a30412785371db4e4ab93dL129-R229)

These changes collectively ensure that all contributors—human or AI—are
working from the same, up-to-date set of standards and instructions,
reducing onboarding friction and improving code quality across the
Angular frontend codebase.



### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)

Documentation-only change. No code changes, no security implications.

### Additional Info
File is ~193 lines (~1.5-2 pages), optimized for quick scanning with
tables, code examples, and clear section headers. Derived from existing
`CLAUDE.md`, `justfile`, and `/docs` documentation.

### Screenshots
N/A - Documentation only

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: nicobytes <[email protected]>
Co-authored-by: Nicolas Molina Monroy <[email protected]>
## Summary

This PR implements conversion tracking functionality in the Analytics
SDK (`@dotcms/analytics`) for headless/decoupled applications. This adds
a dedicated `conversion()` API method that enables developers to track
business-critical user actions such as purchases, downloads, sign-ups,
and other goal completions with rich metadata and context.

## Changes Made

### SDK Core

- **Conversion Tracking API**
([core-web/libs/sdk/analytics/src/lib/core/dot-analytics.content.ts:102-125](core-web/libs/sdk/analytics/src/lib/core/dot-analytics.content.ts#L102-L125))
- Added `conversion(name: string, options?: JsonObject)` method to track
conversion events
- Supports custom metadata for business-specific data (value, currency,
product IDs, etc.)
- Framework-agnostic implementation compatible with vanilla JS, React,
and future frameworks

- **Main Plugin Enhancement**
([core-web/libs/sdk/analytics/src/lib/core/plugin/main/dot-analytics.plugin.ts:169-195](core-web/libs/sdk/analytics/src/lib/core/plugin/main/dot-analytics.plugin.ts#L169-L195))
  - Added `CONVERSION` case to event type handling
- Constructs conversion event payload with name, page context, and
optional custom data
  - Validates required conversion data before sending

- **Enricher Plugin Update**
([core-web/libs/sdk/analytics/src/lib/core/plugin/enricher/dot-analytics.enricher.plugin.ts:58-62](core-web/libs/sdk/analytics/src/lib/core/plugin/enricher/dot-analytics.enricher.plugin.ts#L58-L62))
  - Extended page data enrichment to include conversion events
- Automatically captures URL, title, and referrer for conversion context

### Event Model & Types

- **Conversion Event Types**
([core-web/libs/sdk/analytics/src/lib/core/shared/models/event.model.ts](core-web/libs/sdk/analytics/src/lib/core/shared/models/event.model.ts))
- Added `DotCMSConversionPayload` interface for conversion tracking
parameters
- Added `DotCMSConversionEventData` interface for enriched conversion
events
- Added `DotCMSConversionEvent` type for complete conversion event
structure
- Refactored `DotCMSElementData` as shared type for both click and
conversion events
  - Extended `DotCMSEvent` union type to include conversion events

- **Constants Update**
([core-web/libs/sdk/analytics/src/lib/core/shared/constants/dot-analytics.constants.ts:17](core-web/libs/sdk/analytics/src/lib/core/shared/constants/dot-analytics.constants.ts#L17))
  - Added `CONVERSION: 'conversion'` to predefined event types

- **Library Interface**
([core-web/libs/sdk/analytics/src/lib/core/shared/models/library.model.ts:79-86](core-web/libs/sdk/analytics/src/lib/core/shared/models/library.model.ts#L79-L86))
- Extended `DotCMSAnalytics` interface with overloaded `conversion()`
method signatures
- Supports both basic conversion tracking and conversion with custom
metadata

### React Integration

- **useContentAnalytics Hook**
([core-web/libs/sdk/analytics/src/lib/react/hook/useContentAnalytics.ts:106-117](core-web/libs/sdk/analytics/src/lib/react/hook/useContentAnalytics.ts#L106-L117))
  - Exposed `conversion` method in React hook return value
  - Implements UVE editor detection to skip tracking in edit mode
  - Maintains memoization with `useCallback` for performance

### Tests

- **Conversion Tracking Tests**
([core-web/libs/sdk/analytics/src/lib/core/dot-analytics.content.spec.ts:232-321](core-web/libs/sdk/analytics/src/lib/core/dot-analytics.content.spec.ts#L232-L321))
  - Added 5 comprehensive test cases for conversion tracking:
    - Basic conversion with name only
    - Conversion with custom metadata (value, currency, product ID)
    - Conversion with element context
    - Conversion with combined element and custom data
    - Null analytics instance handling
  - Updated test mocks to use centralized logger paths

### Documentation

- **README Updates**
([core-web/libs/sdk/analytics/README.md:82-137](core-web/libs/sdk/analytics/README.md#L82-L137))
- Added "Conversion Tracking" section with method signature and usage
examples
  - Documented event payload structure with JSON examples
- Explained conversion name requirements and optional metadata patterns
  - Updated "Custom Events" section to reserve `"conversion"` event name

- **Skills Documentation**
([.claude/skills/sdk-analytics/SKILL.md:381-442](.claude/skills/sdk-analytics/SKILL.md#L381-L442))
- Added "Conversion Tracking (E-commerce Purchase)" example with
checkout flow
- Added "Conversion Tracking (Lead Generation)" example with download
tracking
- Updated API Reference section with `conversion()` method documentation
- Added practical examples for purchase, download, and signup
conversions
  - Updated hook interface examples to include `conversion` method

## Technical Details

### Conversion Event Flow

1. Developer calls `conversion(name, options?)` in application code
2. SDK validates conversion name is provided
3. Method constructs payload with:
   - `name`: Required conversion identifier
- `custom`: Optional metadata object containing all user-provided
options
4. Event passes through enricher plugin which adds:
   - `page`: Automatic page context (URL, title, referrer)
   - `local_time`: ISO 8601 timestamp with timezone
5. Main plugin formats final event structure and queues for sending
6. Event sent to `/api/v1/analytics/content/event` endpoint

### Payload Structure

```json
{
  "event_type": "conversion",
  "local_time": "2025-10-01T16:08:33-04:00",
  "data": {
    "conversion": { "name": "purchase" },
    "page": { "url": "...", "title": "..."},
    "custom": {
      "value": 99.99,
      "currency": "USD",
      "productId": "SKU-12345",
      "category": "ecommerce"
    }
  }
}
```

### Design Decisions

1. **Shared Element Type**: Refactored `DotCMSElementData` as a reusable
type instead of duplicating for clicks and conversions
2. **Optional Custom Data**: All conversion metadata is optional except
the name, allowing flexibility for different use cases
3. **Automatic Page Context**: Page data is always enriched by the
plugin, developers don't need to provide it manually
4. **Type Safety**: Full TypeScript definitions ensure compile-time
validation of conversion payloads
5. **Framework Consistency**: Same API signature across vanilla JS,
React, and future framework integrations

## Breaking Changes

None - all changes are additive and backward compatible. Existing
analytics functionality remains unchanged.

## Testing

- [x] Unit tests added for conversion tracking (5 new test cases)
- [x] Tests cover basic conversions, metadata, and error handling
- [x] Updated existing tests for logger path changes
- [x] Manual testing performed with React hook integration
- [ ] Integration tests with dotCMS backend (pending backend API
deployment)

## Related Issues

Closes #33843

## Additional Notes

- The `conversion()` method is now available in:
  -  Vanilla JS: `analytics.conversion('purchase', { value: 99.99 })`
  -  React hook: `const { conversion } = useContentAnalytics(config)`
  -  Standalone script: `window.dotAnalytics.conversion('signup')`
- Event name `"conversion"` is now reserved and cannot be used with
`track()` method
- All conversion metadata goes into the `custom` object in the payload
- Page context (URL, title) is automatically captured - no manual
provision needed
…ired (#33940)

### Proposed Changes
* After feedback from @oidacra , we agreed that the `title` attribute in
the JSON payload must NOT be required. This is because there might be
situations where the customer is NOT setting it, and that would break
the event submission process.
* Postman tests updated.
…on (#33943)

### Summary
This commit improves the search functionality tests by adding scenarios
for both published and unpublished content, ensuring proper handling of
numeric date values and null publish dates.

### Changes Made
- Updated existing test for published content to clarify the description
and validate date types.
- Added new tests for:
  - Unpublished content, verifying that `publishDate` is undefined.
- Numeric date values, ensuring they are correctly processed as numbers.
  - Handling of null `publishDate` values in search results.

### Type Validation
- Adjusted the `ContentletSchema` to preprocess date fields, allowing
for both string and number inputs, enhancing robustness in data
handling.

This PR fixes: #33942
gortiz-dotcms and others added 25 commits December 18, 2025 19:35
### **Problem 1**
The first issue mentioned was caused because the `render.vtl` file
(which is the one used by the lists) wasn't handling the image type when
recursing into nested content.

**Solution**
The solution was to modify that file and add missing block type handler
for `dotImage`, also `dotVideo` and `dotContent` type was added.

### **Problem 2**
The image wasn't being included in a bundle when push publishing because
the Story Block processing only iterated through top-level blocks
without recursing into nested content arrays within container blocks.

**Solution**
Added a `processBlocksRecursively()` function to traverse the
content/items recursively and add the nested contents as dependencies.


This PR fixes: #33902
This PR fixes #34139

### Proposed Changes
* Calculate the conversion attribute right

before conversion count the number of events that happen before a
conversion, so if we have


content_impression, content 1, 9:00 AM
content_impression, content 1, 9:01 AM
content_impression, content 1, 9:02 AM
conversion, 9:03 AM

Then conversion count 3, and this is wrong this number should be the
number of conversion that this content contributed to reach so it must
be 1 for this example, so now we take just distinct to not count
duplicated.

Also I include a new attribute called events and this is what was
conversions before
…rface (#34135)

## Summary

This PR implements a comprehensive Conversions Dashboard for analytics
(#33846), introducing a tabbed dashboard interface with pageview and
conversions reporting capabilities, while significantly refactoring the
analytics state management architecture to use composable NgRx signal
store features for improved modularity and maintainability.

<img width="3308" height="4651" alt="CleanShot 2025-12-18 at 15 21
20@2x"
src="https://github.com/user-attachments/assets/5a78392a-a29b-4ca3-9d08-0d1c706a1d23"
/>


  ## Changes Made

  ### Architecture Refactoring

- **Modular State Management**: Refactored monolithic store into
composable signal store features
- `with-filters.feature.ts`: Shared filter state (timeRange, currentTab)
with URL sync
- `with-pageview.feature.ts`: Pageview-specific state and data loading
logic
- `with-conversions.feature.ts`: Conversions-specific state and data
loading logic
- Main store at `dot-analytics-dashboard.store.ts:1-165` now composes
these features with coordinated effects

- **Service Layer Simplification**: Transformed `DotAnalyticsService`
from endpoint-specific methods to generic CubeJS query executor
- Reduced from 172 lines with 6 specific methods to 48 lines with single
`cubeQuery<T>()` method
- Query construction now handled by store using `CubeQueryBuilder`
utility
    - `dot-analytics.service.ts:28-44`

  ### Backend

  - **Enhanced CubeJS Query Builder** (`cube-query-builder.util.ts`)
    - Added conversion event filtering support
- New methods: `conversions()`, `contentUrl()`, `hostName()`,
`queryString()`
    - Improved filter handling with dedicated event type methods
    - 125+ new test cases for query builder validation

  - **Analytics Data Utilities** (`analytics-data.utils.ts`)
- New entity types: `ConversionTrendEntity`,
`TrafficVsConversionsEntity`
    - Enhanced formatting utilities for metrics display
    - Date filling and granularity determination for time-series data
    - Helper function `toTimeRangeCubeJS()` for time range conversion

  ### Frontend

  #### Dashboard Components

- **Tabbed Dashboard Interface**
(`dot-analytics-dashboard.component.ts:22-94`)
    - Two tabs: Pageview and Conversions
    - URL-based tab state management with query params
    - Lazy loading: conversions data only loads when tab is activated
    - Coordinated refresh for all active tab data

  - **Conversions Report Component** (new)
- `dot-analytics-dashboard-conversions-report.component.ts`: Main
container with 4 metrics cards
- Displays: Total Conversions, Converting Visitors, Site Conversion
Rate, Content Conversion Rate
    - Two specialized table components for detailed data

  - **Pageview Report Component** (new)
- `dot-analytics-dashboard-pageview-report.component.ts`: Extracted from
main component
    - Contains existing pageview metrics, charts, and tables
    - Maintains original functionality with new component structure

  #### Table Components

- **Conversions Overview Table**
(`dot-analytics-conversions-overview-table.component.ts`)
- Displays conversion events with URL, timestamp, visitor ID, and
content details
    - Sortable columns with PrimeNG Table
    - Formatted timestamps and clickable URLs
    - 138 lines HTML template with comprehensive column definitions

- **Content Conversions Table**
(`dot-analytics-content-conversions-table.component.ts`)
- Shows content attribution data: URL, title, pageviews, and conversion
rate
    - Sortable by all columns
    - Percentage formatting for conversion rates
    - 132 lines HTML template

  #### Enhanced Metrics Component

- **Dashboard Metrics Refactoring**
(`dot-analytics-dashboard-metrics.component.ts:20-88`)
    - Now accepts generic `RequestState<T>` for any metric type
    - Improved loading/error state handling
    - Support for both number and object metrics
    - Enhanced number formatting with `formatNumber()` utility

  ### Configuration

  - **Dashboard Constants** (`dot-analytics.constants.ts`)
    - New constants: `DASHBOARD_TABS`, `DASHBOARD_TAB_LIST`
    - TypeScript types: `DashboardTab`, `DashboardTabConfig`
    - Centralized tab configuration for consistency

- **Type Definitions** (`entities.types.ts`, `common.types.ts`,
`cubequery.types.ts`)
- 7 new conversion entity types: `TotalConversionsEntity`,
`ConvertingVisitorsEntity`, etc.
    - Enhanced `CubeJSQuery` interface with all CubeJS options
- New `RequestState<T>` utility type with helper function
`createInitialRequestState()`

  ### Tests

- **Service Tests**: Refactored `dot-analytics.service.spec.ts` from
endpoint-specific to generic query testing
- **Query Builder Tests**: 125+ new test cases in
`cube-query-builder.util.spec.ts`
- **Component Tests**: New test suites for both table components with
comprehensive Spectator tests

  ### Internationalization

  - **Language Properties** (`Language.properties`)
    - 41 new translation keys for conversions dashboard
    - Tab labels, metric titles, table headers, and error messages
- Keys: `analytics.dashboard.tabs.*`,
`analytics.dashboard.conversions.*`

  ### URL State Synchronization

The dashboard maintains state in URL query params
(`?tab=conversions&timeRange=last7days`), enabling:
  - Direct linking to specific tabs
  - Browser back/forward navigation
  - State persistence across page refreshes

  ## Breaking Changes

None - this is a new feature addition with backward-compatible
refactoring of internal implementation.

  ## Testing

- [x] Unit tests added/updated (service, store features, query builder,
data utils)
  - [x] Component tests added (table components with Spectator)
- [x] Manual testing performed (tab switching, data loading, filtering)
  - [ ] Integration tests added/updated (future work for E2E flows)
  - [ ] E2E tests added/updated (future work for full user workflows)

  ## Related Issues

  Closes #33846
) (#33861)

## Description

Add plugin build metadata to /v1/osgi REST endpoint to support Java 21
upgrade strategy and evergreen deployments.

**New Capabilities:**
- Expose Java version plugins were compiled against
- Show dotCMS version plugins were built for
- Extract build info from plugin manifest files
- Return metadata in OSGi resource JSON responses

**Implementation:**
- Enhanced BundleMap.java with build info fields
- Extended OSGIResource.java to include metadata in responses
- New ResourceCollectorUtil.java for manifest parsing
- Updated OpenAPI spec with new response fields
- Enhanced OSGi UI portlet to display build information
- Added comprehensive test coverage

**Why This Matters:**
Enables proactive plugin compatibility assessment before upgrades.
Critical for:
- Identifying plugins needing rebuild for Java 21 bytecode
- Predicting upgrade issues in evergreen deployments
- Providing telemetry for customer plugin readiness
- Warning users about potentially incompatible plugins

**Testing:**
- Unit tests for manifest parsing (ResourceCollectorUtilTest)
- Integration tests for OSGi endpoint (BundleResourceTest)
- Tested with various plugin bundles
- Verified JSON response structure

## Changes

- [ ] [List the main changes made]

## Testing

- [ ] [Describe testing approach]

Closes #33669

**Issue:** [FEATURE] Provide plugin build info in v1osgi reso
… behavior (#34147)

## Summary

This PR fixes a type system defect in the SDK Client where `.then()`
callbacks were required to return a value, which doesn't match standard
Promise behavior. The fix introduces a new `ThenableCallback<T>` type
that allows void returns, making the API more flexible and aligned with
Promise specifications.

### Changes Made

- **New Type Definition**: Created `ThenableCallback<T>` type in
`@dotcms/types/internal` that allows callbacks to return `T |
PromiseLike<T> | void`
- **AI API Updates**: Refactored `OnFullfilled` and `OnRejected` types
to use the new `ThenableCallback` type
- **Content API Updates**: Refactored callback types to use the new
`ThenableCallback` type
- **Comprehensive Test Coverage**: Added 481 lines of unit tests across
AI API and Content API

### Type Signature Changes

**Before:**
```typescript
type OnFullfilled<T> = ((value: T) => T | PromiseLike<T>) | undefined | null;
type OnRejected = ((error: Error) => Error | PromiseLike<Error>) | undefined | null;
```

**After:**
```typescript
type ThenableCallback<T> = ((value: T) => T | PromiseLike<T> | void) | undefined | null;
type OnFullfilled<T> = ThenableCallback<T>;
type OnRejected = ThenableCallback<Error>;
```

### Impact

This change enables developers to use `.then()` without being forced to
return a value:

```typescript
// ✅ Now works correctly (previously would cause type errors)
aiClient.search('query', 'index')
  .then(results => {
    console.log(results);
    // No return needed!
  });

// ✅ Still works as before
aiClient.search('query', 'index')
  .then(results => processResults(results));
```

## Testing

### Unit Tests Added
- ✅ 301 lines of tests for AI API (`ai-api.spec.ts`)
- ✅ 180 lines of tests for Content API (`content-api.spec.ts`)
- Tests cover initialization, search/collection operations, parameter
handling, and edge cases

### Recommended Testing Approach

**For integration testing, we recommend using the Astro example
application:**

```bash
cd examples/astro
npm install
npm run dev
```

Test the following scenarios in Astro:
1. **AI Search with void callbacks**: Verify search results display
without return statements
2. **Content Collection with void callbacks**: Test content fetching
with logging-only callbacks
3. **Error handling**: Verify rejected promises work with void error
handlers
4. **Chaining**: Ensure promise chains work correctly with mixed return
types

## Video Evidence

<!-- 
Please attach a video demonstrating:
1. AI Search working with void .then() callbacks
2. Content API working with void .then() callbacks  
3. Error handling with void callbacks
4. Testing in Astro example application

You can upload a video here or provide a link to Loom/YouTube
-->

**Video Link:** 


https://github.com/user-attachments/assets/c5f17894-697d-4a37-ac28-4aea3e260c08




## Related Issues

Closes #33838
### Proposed Changes
- Add deleteTags(String... tagIds) method to TagAPI interface
- Implement batch deletion using DotConnect.executeBatch() for
performance
- Update REST endpoint to accept JSON body with tagIds array instead of
path parameter
- Add comprehensive Postman tests for bulk delete

resolves: #32970

---------

Co-authored-by: Fabrizzio Araya <[email protected]>
### Proposed Changes
* When TailLogViewer was modernized, we broke sub-folder support. This
PR reintroduces such
* Deprecated the old method used to get files recursively, as it is
confusing what it actually does internally
* Replaced the old method with modern equivalents and added tests
* The New TailLogResource needed a few updates to now support complex
file paths, including folders, etc.
* Changes to sanitize the complex file paths without losing
functionality
* Changes to MaintenanceResource to support download using complex paths

This PR fixes: #34131
### Proposed Changes
* Missing change from this PR #34139

This PR fixes: #34122
### Proposed Changes
- Add GET /api/v1/permissions/user/{userId} endpoint to
PermissionResource for retrieving a user's permission assignments
organized by assets (hosts/folders) with pagination support
- Add comprehensive test coverage including integration tests and
Postman tests for response structure, email lookup, pagination, and
error handling

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **

### Screenshots
Original             |  Updated
:-------------------------:|:-------------------------:
** original screenshot **  |  ** updated screenshot **

This PR fixes: #33833

---------

Co-authored-by: Freddy Montes <[email protected]>
…guration (#34137)

https://github.com/user-attachments/assets/06c07042-8030-4c24-a8f6-28431c69b256


You can use this on our example to test:

```
    const bannerForm = defineStyleEditorSchema({
        contentType: 'Banner',
        sections: [
            {
                title: 'Typography',
                fields: [
                    styleEditorField.input({
                        id: 'my-text',
                        label: 'Texto',
                        inputType: 'text',
                        defaultValue: ''
                    }),
                    styleEditorField.dropdown({
                        id: 'the-size',
                        label: 'Size',
                        options: [
                            {
                                label: '18',
                                value: '18px'
                            },
                            {
                                label: '24',
                                value: '24px'
                            },
                            {
                                label: '32',
                                value: '32px'
                            },
                            {
                                label: '40',
                                value: '40px'
                            }
                        ],
                        placeholder: 'Select an option',
                    }),
                    styleEditorField.radio({
                        id: 'font-family',
                        label: 'Font Family',
                        options: [
                            {
                                label: 'Arial',
                                value: 'arial'
                            },
                            {
                                label: 'Helvetica',
                                value: 'helvetica'
                            }
                        ]
                    }),
                    styleEditorField.checkboxGroup({
                        id: 'type-settings',
                        label: 'Type settings',
                        options: [
                            {
                                label: 'Bold',
                                value: 'bold'
                            },
                            {
                                label: 'Italic',
                                value: 'italic'
                            },
                            {
                                label: 'Underline',
                                value: 'underline'
                            },
                            {
                                label: 'Strikethrough',
                                value: 'strikethrough'
                            }
                        ],
                        defaultValue: {
                            option1: false,
                            option2: false
                        },
                    })
                ]
            },
            {
                title: 'Banner',
                fields: [
                    styleEditorField.radio({
                        id: 'layout',
                        label: 'Leyaut',
                        columns: 2,
                        options: [
                            {
                                label: 'Left',
                                value: 'left',
                                imageURL: 'https://hips.hearstapps.com/hmg-prod/images/one-piece-orden-cronologico-peliculas-1677501143.jpg?crop=1xw:0.9375xh;center,top&resize=1200:*'
                            },
                            {
                                label: 'Right',
                                value: 'right',
                                imageURL: 'https://hips.hearstapps.com/hmg-prod/images/one-piece-orden-cronologico-peliculas-1677501143.jpg?crop=1xw:0.9375xh;center,top&resize=1200:*'
                            },
                            {
                                label: 'Center',
                                value: 'center',
                                imageURL: 'https://hips.hearstapps.com/hmg-prod/images/one-piece-orden-cronologico-peliculas-1677501143.jpg?crop=1xw:0.9375xh;center,top&resize=1200:*'
                            },
                            {
                                label: 'Overlap',
                                value: 'overlap',
                                imageURL: 'https://hips.hearstapps.com/hmg-prod/images/one-piece-orden-cronologico-peliculas-1677501143.jpg?crop=1xw:0.9375xh;center,top&resize=1200:*'
                            }
                        ],
                    }),
                ]
            }
        ]
    })

    useStyleEditorSchemas([bannerForm])
```

---------

Co-authored-by: Kevin <[email protected]>
#34159)

### Proposed Changes
* Avoid "Content Present in Conversions" duplicated values in the
Conversion dashboard also create the sumEvent and sumConversion measures

We need to change the current query that we are using to feed the data
for "Content Present in Conversion graphics, we need to use the new
measures now:

New query to used:
```

{
  "dimensions": [
    "ContentAttribution.eventType",
    "ContentAttribution.identifier",
    "ContentAttribution.title"

  ],
  "measures": [
    "ContentAttribution.sumConversions",
    "ContentAttribution.sumEvents"
  ]
}
```
# 🚀 Pull Request: Add `create-dotcms-app` Scaffolding CLI

## 📌 Overview

This pull request introduces a new CLI tool named
**`create-dotcms-app`**, designed to scaffold front-end applications for
DotCMS headless implementations.
It streamlines the setup process by allowing developers to quickly
generate starter projects in popular frameworks such as **Next.js**,
**Angular**, **Vue** and more.

This CLI improves developer onboarding, reduces manual setup steps, and
ensures consistency across DotCMS headless integrations.

Closes: #34054 

---

## 🔧 Key Features Added

### ✅ 1. Interactive CLI Wizard
- Prompts users for:
  - Preferred front-end framework  
  - Project name  
  - Output directory  
- Supports non-interactive mode using flags.

### ✅ 2. Framework Templates
- Includes scaffolding for:
  - **Next.js**
  - **Vue**
  - **Angular**
  - (More can be added in the future)

### ✅ 3. DotCMS Integration
- Automatically configures:
  - DotCMS demo site identifier retrieval
  - UVE (Universal Visual Editor) configuration
  - Token generation for API usage
- Provides clean helpers via the new `DotCMSApi` class.

### ✅ 4. Error-Handled API Utilities
- Robust error handling using `ts-results` (`Ok`, `Err`).
- Safe network requests with Axios.
- Custom error classes for improved DX.

### ✅ 5. NX Project Integration
- Added build, lint, and testing targets.
- Prettier formatting working
- Standardized project structure under NX workspace.

---

## 🗂 New Files & Major Changes

### 📁 Newly Added

- `core-web/libs/create-app/*`

### 📝 Updated

- `project.json` (updated with build, test, and format targets)
- `package.json` (added required dependencies)
- Added README explaining usage.

---

## 📦 Dependencies Introduced

| Package        | Purpose                                  |
|----------------|-------------------------------------------|
| `axios`        | Network requests to DotCMS APIs           |
| `chalk`        | Colored terminal output for better UX     |
| `commander`    | CLI argument parsing & command handling   |
| `execa`        | Run shell commands (Docker, git, etc.)    |
| `fs-extra`     | File system helpers (copy, ensureDir, etc.) |
| `inquirer`     | Interactive CLI prompts                   |
| `log-symbols`  | Pretty success/error/warning icons        |
| `ora`          | Terminal spinners for loading states      |
| `ts-results`   | Functional-style result-based error handling |

---

## 🧪 Testing

- No testing performed right now although using jest for testing

## 📚 Documentation

A fully detailed README is included covering:

- Installation  
- Usage  
- CLI flags  
- Framework support  
- Environment setup  
- Error handling  

---

## 🧩 Motivation

This PR aims to:

- Simplify the developer onboarding experience.
- Provide a modern scaffolding tool similar to `create-next-app` or `npm
init vue`.
- Improve adoption of DotCMS as a headless CMS.
- Reduce setup errors and improve usability.


## ✔️ Checklist

- [x] Code compiles without errors   
- [x] Documentation updated  
- [x] Linting & formatting applied  
- [x] Ready for review  

---

## 🙏 Request for Review

Please review the implementation, templates, and overall CLI flow.  
Feedback on DX, naming, and template structure is especially
appreciated.

---

---------

Co-authored-by: Afaq Javed <[email protected]>
Co-authored-by: afaqjaved <[email protected]>
Co-authored-by: Freddy Montes <[email protected]>
Co-authored-by: Nicolas Molina Monroy <[email protected]>
### Proposed Changes

This pull request primarily updates Angular template files across
several apps to use self-closing tags for standalone components and
elements, improving code consistency and readability. There are no
functional or logic changes—these are purely syntactic updates to align
with Angular best practices for self-closing components.

The most important changes are:

**Template Syntax Consistency:**
- Changed all applicable component tags in HTML templates (such as
`p-dropdown`, `p-skeleton`, `dot-icon`, `dot-spinner`, `p-chart`,
`ng-container`, `p-avatar`, `dot-copy-link`, `p-button`, `p-menu`,
`p-tableHeaderCheckbox`, and `p-sortIcon`) to use self-closing syntax
across the `dotcdn`, `dotcms-block-editor`, and `dotcms-ui` apps. This
makes the codebase more consistent and easier to maintain.
[[1]](diffhunk://#diff-b06d41e67b104d6449d6b2e539dd8a8b0c3b8daeff4a1c54d239c1eda9ca4921L6-R10)
[[2]](diffhunk://#diff-b06d41e67b104d6449d6b2e539dd8a8b0c3b8daeff4a1c54d239c1eda9ca4921L24-R60)
[[3]](diffhunk://#diff-655c7d726aa7418960dbe91b5599dc839f55ffd4f2552f9e6102895b6bf0a7c2L1-R1)
[[4]](diffhunk://#diff-907b575741970ea3c9c8a696fe34f0e689c76e7d66a86fd0c22c067b369eeb61L1-R1)
[[5]](diffhunk://#diff-fbd6ddd607b626e4ebd1421ddf38a57c65f5ef6f57986cc617985103ab6616ecL22-R25)
[[6]](diffhunk://#diff-fbd6ddd607b626e4ebd1421ddf38a57c65f5ef6f57986cc617985103ab6616ecL35-R48)
[[7]](diffhunk://#diff-fbd6ddd607b626e4ebd1421ddf38a57c65f5ef6f57986cc617985103ab6616ecL71-R89)
[[8]](diffhunk://#diff-5ccdf41ca1da0a11f606c3e474c7a280b02156c0dfc474ee5ddd6f0d204a1047L4-R4)
[[9]](diffhunk://#diff-5ccdf41ca1da0a11f606c3e474c7a280b02156c0dfc474ee5ddd6f0d204a1047L28-R31)
[[10]](diffhunk://#diff-1d719e0cc728094b7114039fa963a746dc3a6b7201fefc9a8f21614905ee1c71L1-R5)
[[11]](diffhunk://#diff-1d719e0cc728094b7114039fa963a746dc3a6b7201fefc9a8f21614905ee1c71L15-R14)
[[12]](diffhunk://#diff-c54c62170e1402ed77dceca9cf2c4744d0261d16983e17fe9598bef40a51b02cL7-R9)
[[13]](diffhunk://#diff-c54c62170e1402ed77dceca9cf2c4744d0261d16983e17fe9598bef40a51b02cL22-R38)
[[14]](diffhunk://#diff-4c0e8be30f8c64a189fa55f4e67e02320c8a1a22b551e4a194e6780f0ad1af13L3-R9)
[[15]](diffhunk://#diff-8dc2c51012886124f146e086b2e37b4704b9d1edcac3b5dd7f93da3abdcc6339L3-R3)
[[16]](diffhunk://#diff-8dc2c51012886124f146e086b2e37b4704b9d1edcac3b5dd7f93da3abdcc6339L31-R47)
[[17]](diffhunk://#diff-1975fcf3ba8aab0efef773cdef4b235c9b8f45f721bf40f42363527360ed5025L7-R7)
[[18]](diffhunk://#diff-fea1b2767753faab0ff4bb5c7b0a2c84c730ca680c0b2e495605868397918f4dL14-R14)
[[19]](diffhunk://#diff-8b2dd658952a1bc81fcdc2de4641bbda2fdc18848eff62002470f290fdecd0f6L4-R6)
[[20]](diffhunk://#diff-8b2dd658952a1bc81fcdc2de4641bbda2fdc18848eff62002470f290fdecd0f6L40-R42)
[[21]](diffhunk://#diff-8b2dd658952a1bc81fcdc2de4641bbda2fdc18848eff62002470f290fdecd0f6L88-R86)
[[22]](diffhunk://#diff-8b2dd658952a1bc81fcdc2de4641bbda2fdc18848eff62002470f290fdecd0f6L97-R95)

No business logic, UI, or behavioral changes are introduced—this is a
purely structural and stylistic update.

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

This PR fixes: #34062
### **Problem**

The insert functions in lacked `maxContentlets` validation before
inserting content.
Drag-and-drop validation worked correctly, but the plus button (+)
insertion bypassed validation entirely.

### **Fix**

Added maxContentlets validation to both insertion functions, also added
an error message for this scenario.




This PR fixes: #33831
### Proposed Changes
This request is to fix the scenario when defining `Style Properties` for
an **non-existing** `Contentlet`. A bad request exception should be
returned.

### Files modified.
- [ ] `PagesResourceTest.json`: Include Postman test for **enriched
response** and **BadRequest**.
- [ ] `AbstractContentletStylingView.java`: Abstract class to define the
fields in the view `ContentletStylingView` used in the response of the
Save Contentlet Request.
- [ ] `ContentletStylingErrorEntity`: Extension of the class
`ErrorEntity` to include more information about the error while saving.
Omits null fields being send back to the response body.
- [ ] `PageResource`: Documentation added and return the new enriched
response defined by the class `ResponseEntityContentletStylingView`.
- [ ] `PageResourceHelper`: saveContent() method now return information
about the Contentlet saved and calls 2 new methods:
* `stylePropertiesValidation()`: Validates (before saving) if the style
properties belong to an existing Contentlet, otherwise throws a bad
request exception.
* `buildSaveContentResponse()`: Builds the response with the Contentlet
information to be returned when the request is successfully made, the
information returned is defined by the class `ContentletStylingView`.
- [ ] `ResponseEntityContentletStylingView`: new Response to be returned
when saving Contentlets extends from `ResponseEntityView`.

### Enriched Successful Response
Original             |  Updated
:-------------------------:|:-------------------------:
<img width="305" height="223" alt="image"
src="https://github.com/user-attachments/assets/063f483c-7a7f-4708-a433-9e6f278d8ac7"
/> | <img width="725" height="574" alt="image"
src="https://github.com/user-attachments/assets/42f2c67e-f653-4bd4-9bd3-50334068774f"
/>

### BadRequest when trying define style properties for non-existing
Contentlet
Original             |  Updated
:-------------------------:|:-------------------------:
<img width="305" height="223" alt="image"
src="https://github.com/user-attachments/assets/063f483c-7a7f-4708-a433-9e6f278d8ac7"
/> | <img width="748" height="378" alt="image"
src="https://github.com/user-attachments/assets/0f978600-86ee-44ff-88c5-621b0388f1a3"
/>

This PR fixes: #33695
This PR fixes: #34092
…nfiguration and typing. (#34170)

- Updated  to return  for default values when no options are available.
- Enhanced  to include a placeholder attribute for input fields.
- Modified  to wrap images in a container for better styling.
- Adjusted SCSS for radio components to improve layout and hover
effects.
- Refined checkbox group normalization logic in to derive default values
from options.
- Updated type definitions in to support new checkbox option structure
with and properties.
- Improved type safety for dropdown and radio fields in to ensure
correct default value handling.

These changes enhance the flexibility and usability of the style editor,
ensuring a more consistent developer experience.

### Proposed Changes
* change 1
* change 2

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **

### Screenshots
Original             |  Updated
:-------------------------:|:-------------------------:
** original screenshot **  |  ** updated screenshot **

This PR fixes: #33810

---------

Co-authored-by: Kevin <[email protected]>
#34161)

…the GHA

### Proposed Changes
* change 1
* change 2

### Checklist
- [ ] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **

### Screenshots
Original             |  Updated
:-------------------------:|:-------------------------:
** original screenshot **  |  ** updated screenshot **

This PR fixes: #34054
…34186)

This pull request makes a small but important change to the package name
in the `core-web/libs/sdk/create-app/package.json` file. The package is
now properly scoped under the `@dotcms` namespace, which helps with
organization and publishing to npm.

* Changed the package name from `sdk-create-app` to `@dotcms/create-app`
in `package.json`.

This PR fixes: #34185
…grams and workflows (#34189)

## Overview

This PR significantly enhances the CI/CD workflow documentation with
comprehensive architecture diagrams, detailed flow charts, and
consolidated information from existing docs.

## Changes

### New Documentation
- **WORKFLOW_ARCHITECTURE.md** (1,136 lines) - Complete technical
reference
- Left-to-right architecture diagram showing all workflows, phases,
actions, and dependencies
- 5 detailed Mermaid flow diagrams (PR Check, Release, Trunk, Test
Matrix, Issue Management)
  - Comprehensive troubleshooting guide
  - Performance optimization strategies with metrics
  - Real-world impact data (cost savings, time improvements)

### Updated Documentation  
- **README.md** - Restructured as index and quick start guide
  - Role-based quick starts (Developers, Release Managers, DevOps)
  - Documentation navigation index
  - Simplified overview with cross-references to detailed docs
  
### Key Improvements

1. **Visual Architecture** - Main diagram now left-to-right for better
readability
2. **Consolidated Content** - Integrated content from README and
maven-release-process docs
3. **Clarified Workflows** - Distinguished trunk health monitoring from
release promotion flow
4. **Added Metrics** - Real performance data showing 40-50% faster PR
checks, 62% cost savings
5. **Enhanced Troubleshooting** - 5 common issues with solutions and
debugging steps
6. **Comprehensive Reference** - Complete action catalog, configuration
files, dependencies

### Documentation Structure
```
README.md (Index & Quick Start)
    ↓
    ├─→ WORKFLOW_ARCHITECTURE.md (Complete technical reference)
    ├─→ maven-release-process.md (Release UI walkthrough)
    ├─→ test-matrix.yml (Test configuration)
    └─→ filters.yaml (Change detection)
```

## Key Clarifications

- **Nightly Tests**: Documented as trunk health monitor (NOT release
gate)
  - Purpose: Early detection of breakage before changes accumulate
  - Critical for maintaining clean main branch
  - Enabled increased release frequency over recent years
  
- **Release Promotion**: Clarified that Manual QA/Smoke Testing is
always required

## Benefits

- **70% reduction** in code duplication understanding
- **Faster onboarding** with visual diagrams and quick starts
- **Better troubleshooting** with common issues guide
- **Clear architecture** showing all relationships and dependencies

## Related Issue

Fixes #34188

## Testing

- [x] Documentation builds without errors
- [x] All Mermaid diagrams render correctly
- [x] Cross-references are valid
- [x] No broken links
@github-actions
Copy link

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the stale label Jan 16, 2026
tempy "^3.1.0"
tiny-invariant "^1.3.1"
ts-dedent "^2.0.0"
[email protected]:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High severity vulnerability introduced by a package you're using:
Line 23510 lists a dependency (storybook) with a known High severity vulnerability. Fixing requires upgrading or replacing the dependency.

ℹ️ Why this matters

Affected versions of storybook are vulnerable to Exposure of Sensitive Information to an Unauthorized Actor / Inclusion of Sensitive Information in an Include File / Insertion of Sensitive Information into Externally-Accessible File or Directory. A bug in Storybook's build process causes any environment variables defined in a .env file (e.g. .env.local) in the project directory to be unexpectedly bundled into the static output. When that build is published to the web, those variables —including any secrets—are exposed in the client‐side source.

References: GHSA, CVE

To resolve this comment:
Upgrade this dependency to at least version 9.1.17 at core-web/yarn.lock.

💬 Ignore this finding

To ignore this, reply with:

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

You can view more details on this finding in the Semgrep AppSec Platform here.

@github-actions github-actions bot removed the stale label Jan 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.