diff --git a/package-lock.json b/package-lock.json index 3256ce63b9..848ba98615 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ }, "engines": { "node": ">=22", - "pnpm": "10.15.0" + "pnpm": "10.17.0" } }, "node_modules/husky": { diff --git a/package.json b/package.json index 6ac08513ce..36abb86f74 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "create-translation": "turbo run create-translation", "include-oss-in-artifact": "pnpm --filter @mendix/automation-utils run include-oss-in-artifact", "postinstall": "turbo run agent-rules", + "start:mcp": "pnpm --filter pluggable-widgets-mcp run start", "lint": "turbo run lint --continue --concurrency 1", "oss-clearance": "pnpm --filter @mendix/automation-utils run oss-clearance", "prepare": "husky install", diff --git a/packages/pluggable-widgets-mcp/.gitignore b/packages/pluggable-widgets-mcp/.gitignore new file mode 100644 index 0000000000..e6cd8c7e6d --- /dev/null +++ b/packages/pluggable-widgets-mcp/.gitignore @@ -0,0 +1,3 @@ +dist/ +generations/ +node_modules/ \ No newline at end of file diff --git a/packages/pluggable-widgets-mcp/.prettierrc.cjs b/packages/pluggable-widgets-mcp/.prettierrc.cjs new file mode 100644 index 0000000000..0892704ab0 --- /dev/null +++ b/packages/pluggable-widgets-mcp/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("@mendix/prettier-config-web-widgets"); diff --git a/packages/pluggable-widgets-mcp/AGENTS.md b/packages/pluggable-widgets-mcp/AGENTS.md new file mode 100644 index 0000000000..e6af325552 --- /dev/null +++ b/packages/pluggable-widgets-mcp/AGENTS.md @@ -0,0 +1,116 @@ +# Pluggable Widgets MCP Server + +MCP server enabling AI assistants to scaffold and manage Mendix pluggable widgets via STDIO (default) or HTTP transport. + +## Quick Reference + +```bash +pnpm dev # Development with hot reload +pnpm build # TypeScript compilation + path alias resolution +pnpm start # Build and run (STDIO mode, default) +pnpm start:http # Build and run (HTTP mode, port 3100) +pnpm lint # ESLint check +``` + +## Project Structure + +``` +src/ +├── index.ts # Entry point - transport mode selection +├── config.ts # Server configuration and constants +├── security/ # Path traversal & extension validation +├── server/ # HTTP and STDIO transport setup +├── resources/ # MCP resources (guidelines) +├── generators/ # XML and TSX code generators +└── tools/ # MCP tool implementations +``` + +## Adding Tools + +1. Create `src/tools/my-feature.tools.ts`: + +```typescript +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; + +export function registerMyTools(server: McpServer): void { + server.registerTool( + "my-tool", + { + title: "My Tool", + description: "Description shown to LLM", + inputSchema: z.object({ param: z.string().describe("Parameter description") }) + }, + async ({ param }) => ({ + content: [{ type: "text", text: "Success" }] + }) + ); +} +``` + +2. Register in `src/tools/index.ts`: + +```typescript +import { registerMyTools } from "./my-feature.tools"; + +export function registerAllTools(server: McpServer): void { + // ... existing registrations + registerMyTools(server); +} +``` + +## Code Patterns + +- **Imports**: Use `@/` path alias for absolute imports from `src/` +- **Schemas**: All tool inputs require Zod schemas +- **Errors**: Use `createErrorResponse()` from `@/tools/utils/response` +- **Long operations**: Use `ProgressTracker` from `@/tools/utils/progress-tracker` + +## Notification Behavior (Important for AI Agents) + +When using this MCP server, understand where different types of output appear: + +| Output Type | Visibility | Purpose | +| -------------------------- | -------------------------- | ------------------------------------------------------- | +| **Tool Results** | ✅ Visible in conversation | Final outcomes, structured data, success/error messages | +| **Progress Notifications** | ❌ Not in conversation | Client UI indicators only (spinners, progress bars) | +| **Log Messages** | ❌ Not in conversation | Debug console/MCP Inspector only | + +**Key Implications for AI Agents:** + +1. **Don't expect intermediate progress in chat**: Long operations (scaffolding, building) will show results only when complete. The conversation won't contain step-by-step progress updates. + +2. **Tool results are authoritative**: Only tool result content appears in the conversation history. Use this for: + + - Success confirmations with file paths + - Structured error messages with suggestions + - Any information the AI needs to continue the workflow + +3. **Progress tracking is for humans**: `sendProgress()` and `sendLogMessage()` are for human observers using MCP Inspector or UI indicators, not for AI decision-making. + +4. **When debugging**: + - If operations seem to "hang", check MCP Inspector's Notifications/Logs panels + - Progress notifications confirm the server is working, even if the chat is quiet + - This is per MCP specification, not a bug + +**Example Workflow:** + +```typescript +// ❌ This progress won't appear in AI's context +await sendProgress(context, 50, "Scaffolding widget..."); + +// ✅ This result WILL appear in AI's context +return createToolResponse(`Widget created at ${widgetPath}`); +``` + +## Testing + +```bash +npx @modelcontextprotocol/inspector node dist/index.js +``` + +## Security + +**Read before implementing file operations**: [docs/agent/security.md](docs/agent/security.md) + +All file operation tools must use `validateFilePath()` from `@/security` to prevent path traversal attacks. diff --git a/packages/pluggable-widgets-mcp/CHANGELOG.md b/packages/pluggable-widgets-mcp/CHANGELOG.md new file mode 100644 index 0000000000..8c63b9710f --- /dev/null +++ b/packages/pluggable-widgets-mcp/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this MCP server will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- We introduce pluggable-widgets-mcp. diff --git a/packages/pluggable-widgets-mcp/README.md b/packages/pluggable-widgets-mcp/README.md new file mode 100644 index 0000000000..b6bedabee5 --- /dev/null +++ b/packages/pluggable-widgets-mcp/README.md @@ -0,0 +1,276 @@ +# Mendix Pluggable Widgets MCP Server + +> **Work in Progress** - This is an MVP focused on widget scaffolding. Widget editing capabilities coming soon. + +A Model Context Protocol (MCP) server that enables AI assistants to scaffold Mendix pluggable widgets programmatically. + +## Quick Start + +```bash +pnpm install +pnpm build # Build the server +pnpm start # STDIO mode (default) +pnpm start:stdio # STDIO mode +``` + +## Global Installation + +For use with MCP clients (Cursor, Claude Desktop, LMStudio), install globally: + +```bash +# Build first +pnpm build + +# Link globally using npm (NOT pnpm - better MCP client compatibility) +npm link + +# Verify installation +which pluggable-widgets-mcp +``` + +## Transport Modes + +### STDIO Mode (default) + +Runs via stdin/stdout for CLI-based MCP clients (Claude Desktop, etc.). + +```bash +pnpm start +pnpm start:stdio +``` + +### HTTP Mode + +Runs an HTTP server for web-based MCP clients. + +```bash +pnpm start:http +``` + +- Server runs on `http://localhost:3100` (override with `PORT` env var) +- Health check: `GET /health` +- MCP endpoint: `POST /mcp` + +## MCP Client Configuration + +### HTTP + +```json +{ + "mcpServers": { + "pluggable-widgets-mcp": { + "url": "http://localhost:3100/mcp" + } + } +} +``` + +### STDIO + +**_Some client setups like Claude Desktop support STDIO only (for now)_** + +**Option 1: Global command (after `npm link`)** + +```json +{ + "mcpServers": { + "pluggable-widgets-mcp": { + "command": "pluggable-widgets-mcp", + "args": ["stdio"] + } + } +} +``` + +**Option 2: Absolute path (more reliable during development)** + +```json +{ + "mcpServers": { + "pluggable-widgets-mcp": { + "command": "node", + "args": ["/path/to/pluggable-widgets-mcp/dist/index.js", "stdio"] + } + } +} +``` + +> **Note:** After rebuilding the server, you may need to restart/reconnect your MCP client to pick up changes. + +## Available Tools + +### create-widget + +Scaffolds a new Mendix pluggable widget using `@mendix/generator-widget`. + +| Parameter | Required | Default | Description | +| --------------------- | -------- | ------------ | ------------------------------------ | +| `name` | Yes | - | Widget name (PascalCase recommended) | +| `description` | Yes | - | Brief description of the widget | +| `version` | No | `1.0.0` | Initial version (semver) | +| `author` | No | `Mendix` | Author name | +| `license` | No | `Apache-2.0` | License type | +| `organization` | No | `Mendix` | Organization namespace | +| `template` | No | `empty` | `full` (sample code) or `empty` | +| `programmingLanguage` | No | `typescript` | `typescript` or `javascript` | +| `unitTests` | No | `true` | Include unit test setup (Jest/TS) | +| `e2eTests` | No | `false` | Include E2E test setup (Playwright) | + +Generated widgets are placed in `generations/` directory within this package. + +### File Operation Tools + +| Tool | Description | +| ------------------- | ------------------------------------------------------------------------------------- | +| `list-widget-files` | Lists all files in a widget directory, grouped by type | +| `read-widget-file` | Reads the contents of a file from a widget directory | +| `write-widget-file` | Writes content to a file (creates parent dirs). Supports single-file and batch modes. | + +**Security:** All file operations are protected by `src/security/guardrails.ts`: + +- Path traversal is blocked (no `..` escapes) +- Extension whitelist: `.tsx`, `.ts`, `.xml`, `.scss`, `.css`, `.json`, `.md` + +### Code Generation Tools + +| Tool | Description | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `generate-widget-code` | Generates widget XML + TSX + SCSS from property definitions. Saves a `.widget-definition.json` snapshot. | +| `update-widget-properties` | Incrementally adds, removes, or modifies widget properties. Requires `generate-widget-code` to have been run first. | + +### build-widget + +Builds a widget using `pluggable-widgets-tools`, producing an `.mpk` file. + +| Parameter | Required | Description | +| ------------ | -------- | ------------------------------------- | +| `widgetPath` | Yes | Absolute path to the widget directory | + +Returns structured errors for TypeScript, XML, or dependency issues. + +## Available Resources + +| URI | Description | +| ------------------------------------- | -------------------------------------------------------------------------- | +| `mendix://guidelines/property-types` | Complete reference for all Mendix widget property types | +| `mendix://guidelines/widget-patterns` | Reusable patterns for common widget types (Button, Input, Container, etc.) | + +## Development + +```bash +pnpm dev # Development mode with hot reload +pnpm build # Build for production +pnpm start # Build and run +``` + +## Testing with MCP Inspector + +The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) is an interactive debugging tool for testing MCP servers. It provides a web UI to connect to your server, explore available tools, and execute them with custom inputs. + +### Quick Start + +```bash +# Run Inspector against this server (STDIO mode) +npx @modelcontextprotocol/inspector node dist/index.js stdio + +# Or for HTTP mode, start the server first then connect via Inspector +pnpm start +npx @modelcontextprotocol/inspector +# Then enter http://localhost:3100/mcp as the server URL +``` + +### Using the Inspector + +1. **Connect** - The Inspector will automatically connect to your MCP server +2. **Explore Tools** - View all registered tools (`create-widget`, etc.) with their schemas +3. **Execute Tools** - Fill in parameters and run tools to test behavior +4. **View Responses** - See JSON responses, progress notifications, and logs in real-time + +### Example: Testing `create-widget` + +1. Start the Inspector: `npx @modelcontextprotocol/inspector node dist/index.js stdio` +2. Select the `create-widget` tool from the tools list +3. Fill in required parameters: + ```json + { + "name": "TestWidget", + "description": "A test widget", + ... // Defaults for other optional values if not entered + } + ``` +4. Click "Execute" and watch progress notifications as the widget is scaffolded +5. Check `generations/testWidget/` for the created widget + +This is useful for verifying tool behavior without needing a full AI client integration. + +## Understanding Feedback and Notifications + +This server uses MCP's notification system to provide progress updates and logging. However, **different types of feedback appear in different places**—not all feedback shows up in your chat conversation. + +### Where Different Types of Feedback Appear + +| Feedback Type | Where It Appears | Example | +| -------------------------- | -------------------------------------- | ----------------------------------------------------------------- | +| **Tool Results** | ✅ Chat conversation | Widget created at `/path/to/widget`, Build completed successfully | +| **Progress Notifications** | ⚙️ Client UI (spinners, progress bars) | "Scaffolding widget...", "Building widget..." | +| **Log Messages** | 🔍 Debug console (MCP Inspector) | Detailed operation logs, debug info | + +### Why Progress Doesn't Show in Chat + +**This is by design per the MCP specification**, not a bug. The MCP architecture separates concerns: + +- **`notifications/progress`** → Routed to client UI indicators (loading spinners, status bars) +- **`notifications/message`** → Routed to debug/inspector consoles for developers +- **Tool results** → Returned to the conversation when operations complete + +This means: + +- Long operations (scaffolding, building) will show **results** when complete +- You won't see intermediate progress steps in the chat history +- MCP Inspector shows all notifications in real-time (bottom-right panel) + +### Viewing Debug Output + +**With MCP Inspector:** + +1. Run: `npx @modelcontextprotocol/inspector node dist/index.js stdio` +2. Execute a tool (e.g., `create-widget`) +3. Watch the **Notifications panel** (bottom-right) for progress updates +4. Check the **Logs panel** for detailed debug output + +**With Claude Desktop:** + +- Progress notifications may appear as UI indicators (client-dependent) +- Check Claude Desktop's developer console for log messages (if available) +- Tool results will always appear in the conversation + +### Expected Behavior Examples + +**During widget scaffolding:** + +- Chat shows: "Starting scaffolding..." → (wait) → "Widget created at `/path`" +- Inspector shows: Progress notifications (start → installing dependencies → complete) + +**During widget building:** + +- Chat shows: "Building..." → (wait) → "Build successful" or structured error +- Inspector shows: TypeScript compilation progress, dependency resolution + +## Roadmap + +- [x] Widget scaffolding (`create-widget`) +- [x] HTTP transport +- [x] STDIO transport +- [x] Progress notifications +- [x] File operations (list, read, write) +- [x] Build tool (`build-widget`) +- [x] Guideline resources (property-types, widget-patterns) +- [x] Code generation (`generate-widget-code`) +- [x] Incremental property update tool (`update-widget-properties`) +- [ ] Batch widget generation +- [ ] Widget testing helpers +- [ ] TypeScript error recovery suggestions + +## License + +Apache-2.0 - Mendix Technology BV 2025 diff --git a/packages/pluggable-widgets-mcp/docs/agent/security.md b/packages/pluggable-widgets-mcp/docs/agent/security.md new file mode 100644 index 0000000000..816e26ff25 --- /dev/null +++ b/packages/pluggable-widgets-mcp/docs/agent/security.md @@ -0,0 +1,20 @@ +# Security + +All security validation is centralized in `src/security/guardrails.ts`: + +```typescript +import { validateFilePath, ALLOWED_EXTENSIONS } from "@/security"; + +// Validates path traversal and extension whitelist +validateFilePath(widgetPath, filePath, true); // true = check extension +``` + +## Security Measures + +| Protection | Function | Description | +| ------------------- | ------------------------- | ------------------------------------------------------------------- | +| Path Traversal | `validateFilePath()` | Blocks `..` sequences and resolved path escapes | +| Extension Whitelist | `isExtensionAllowed()` | Only allows: `.tsx`, `.ts`, `.xml`, `.scss`, `.css`, `.json`, `.md` | +| Directory Boundary | `isPathWithinDirectory()` | Ensures files stay within widget directory | + +**Rule**: When adding file operation tools, always use `validateFilePath()` from the security module. diff --git a/packages/pluggable-widgets-mcp/docs/property-types.md b/packages/pluggable-widgets-mcp/docs/property-types.md new file mode 100644 index 0000000000..792334849a --- /dev/null +++ b/packages/pluggable-widgets-mcp/docs/property-types.md @@ -0,0 +1,499 @@ +# Mendix Widget Property Types Reference + +This document defines all available property types for Mendix pluggable widgets. Use this reference when defining properties in the JSON schema for XML generation. + +> **Note:** XML is generated automatically by the `generate-widget-code` tool. You only need to provide JSON property definitions — no XML knowledge required. + +## Property Definition Schema + +When defining properties for the XML generator, use this JSON structure: + +```json +{ + "key": "propertyName", + "type": "string", + "caption": "Display Caption", + "description": "Optional description shown in Studio Pro", + "required": false, + "defaultValue": "optional default" +} +``` + +--- + +## Basic Types + +### string + +Simple text input. + +```json +{ + "key": "label", + "type": "string", + "caption": "Label", + "description": "Text label for the widget", + "defaultValue": "Click me" +} +``` + +--- + +### boolean + +True/false toggle. + +```json +{ + "key": "showIcon", + "type": "boolean", + "caption": "Show icon", + "description": "Display an icon next to the text", + "defaultValue": true +} +``` + +--- + +### integer + +Whole number input. + +```json +{ + "key": "maxItems", + "type": "integer", + "caption": "Maximum items", + "description": "Maximum number of items to display", + "defaultValue": 10 +} +``` + +--- + +### decimal + +Decimal number input. + +```json +{ + "key": "opacity", + "type": "decimal", + "caption": "Opacity", + "description": "Opacity level (0-1)", + "defaultValue": 0.8 +} +``` + +--- + +## Text Types + +### textTemplate + +Text with parameter substitution. Allows dynamic text with placeholders. + +```json +{ + "key": "legend", + "type": "textTemplate", + "caption": "Legend", + "description": "Text template with parameters", + "required": false +} +``` + +--- + +### expression + +Dynamic expression that can reference attributes and return computed values. + +```json +{ + "key": "visibleExpression", + "type": "expression", + "caption": "Visible", + "description": "Expression to determine visibility", + "defaultValue": "true" +} +``` + +**With return type:** + +```json +{ + "key": "valueExpression", + "type": "expression", + "caption": "Value", + "returnType": "String" +} +``` + +--- + +## Action Types + +### action + +Event handler that triggers actions (microflows, nanoflows, etc.). + +```json +{ + "key": "onClick", + "type": "action", + "caption": "On click", + "description": "Action to execute when clicked", + "required": false +} +``` + +--- + +## Data Types + +### attribute + +Links to an entity attribute. Must specify allowed attribute types. + +```json +{ + "key": "value", + "type": "attribute", + "caption": "Value", + "description": "Attribute to store the value", + "required": true, + "attributeTypes": ["String"] +} +``` + +**Multiple attribute types:** + +```json +{ + "key": "numberValue", + "type": "attribute", + "attributeTypes": ["Integer", "Decimal", "Long"] +} +``` + +**Valid attributeTypes:** + +- `String` +- `Integer` +- `Long` +- `Decimal` +- `Boolean` +- `DateTime` +- `Enum` +- `HashString` +- `Binary` +- `AutoNumber` + +--- + +### datasource + +Data source for list-based widgets. + +```json +{ + "key": "dataSource", + "type": "datasource", + "caption": "Data source", + "description": "Source of items to display", + "isList": true, + "required": false +} +``` + +--- + +### association + +Links to an entity association. + +```json +{ + "key": "parent", + "type": "association", + "caption": "Parent association", + "required": false +} +``` + +--- + +### selection + +Represents the selection mode for a widget (e.g., for data grids). + +| Field | Type | Required | Description | +| ----------- | ----------- | -------- | --------------------------- | +| key | string | ✅ | camelCase identifier | +| type | "selection" | ✅ | Must be "selection" | +| caption | string | ✅ | Display label in Studio Pro | +| description | string | | Help text | +| required | boolean | | Whether required | + +**Example:** + +```json +{ + "key": "selection", + "type": "selection", + "caption": "Selection" +} +``` + +--- + +## Selection Types + +### enumeration + +Dropdown with predefined options. Must include `enumValues` array. + +```json +{ + "key": "alignment", + "type": "enumeration", + "caption": "Alignment", + "defaultValue": "left", + "enumValues": [ + { "key": "left", "caption": "Left" }, + { "key": "center", "caption": "Center" }, + { "key": "right", "caption": "Right" } + ] +} +``` + +--- + +### icon + +Icon picker. + +```json +{ + "key": "icon", + "type": "icon", + "caption": "Icon", + "required": false +} +``` + +--- + +### image + +Image picker. + +```json +{ + "key": "image", + "type": "image", + "caption": "Image", + "required": false +} +``` + +--- + +### file + +File selector. + +```json +{ + "key": "document", + "type": "file", + "caption": "Document" +} +``` + +--- + +## Container Types + +### widgets + +Container for child widgets. Used to create widget slots. + +```json +{ + "key": "content", + "type": "widgets", + "caption": "Content", + "description": "Widgets to display inside" +} +``` + +**With datasource reference:** + +```json +{ + "key": "content", + "type": "widgets", + "caption": "Content", + "dataSource": "dataSource" +} +``` + +--- + +### object + +Complex nested property with sub-properties. Used for repeating structures. + +```json +{ + "key": "columns", + "type": "object", + "caption": "Columns", + "isList": true, + "properties": [ + { + "key": "header", + "type": "textTemplate", + "caption": "Header" + }, + { + "key": "width", + "type": "integer", + "caption": "Width", + "defaultValue": 100 + } + ] +} +``` + +--- + +## System Properties + +System properties are predefined by Mendix. Reference them by key only. + +```json +{ + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +**Available system properties:** + +- `Name` - Widget name in Studio Pro +- `TabIndex` - Tab order for accessibility +- `Visibility` - Conditional visibility settings + +--- + +## Property Groups + +Properties can be organized into groups for better Studio Pro UI. + +```json +{ + "propertyGroups": [ + { + "caption": "General", + "properties": ["label", "showIcon"] + }, + { + "caption": "Events", + "properties": ["onClick", "onHover"] + } + ] +} +``` + +--- + +## Property Organization + +### Auto-Grouping Behavior + +If `propertyGroups` is omitted from the widget definition, the `generate-widget-code` tool applies automatic grouping: + +- Non-action properties (all types except `action`) are placed in a **"General"** group. +- Action properties (`type: "action"`) are placed in an **"Events"** group. + +This means you rarely need to define `propertyGroups` explicitly for simple widgets. Only add it when you need custom group names or a specific ordering of groups. + +### Incrementally Updating Properties + +Once a widget has been generated with `generate-widget-code`, you do not need to regenerate all files to change the property list. Use the `update-widget-properties` tool to: + +- **Add** new properties to an existing widget +- **Remove** properties that are no longer needed +- **Modify** property attributes (e.g., change a caption or default value) + +The `update-widget-properties` tool reads the `.widget-definition.json` snapshot saved during `generate-widget-code` and applies only the requested delta, then regenerates the affected files. + +> **Requirement:** `generate-widget-code` must have been run at least once before `update-widget-properties` can be used, because it depends on the `.widget-definition.json` snapshot. + +--- + +## Full Widget Definition Example + +```json +{ + "name": "TooltipButton", + "description": "A button with tooltip on hover", + "properties": [ + { + "key": "buttonText", + "type": "textTemplate", + "caption": "Button text", + "description": "Text to display on the button" + }, + { + "key": "tooltipText", + "type": "textTemplate", + "caption": "Tooltip text", + "description": "Text to show on hover" + }, + { + "key": "buttonStyle", + "type": "enumeration", + "caption": "Style", + "defaultValue": "primary", + "enumValues": [ + { "key": "primary", "caption": "Primary" }, + { "key": "secondary", "caption": "Secondary" }, + { "key": "danger", "caption": "Danger" } + ] + }, + { + "key": "onClick", + "type": "action", + "caption": "On click", + "required": false + } + ], + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +--- + +## Type Quick Reference + +| Type | Use Case | Requires | +| -------------- | ---------------- | ----------------------- | +| `string` | Simple text | - | +| `boolean` | Toggle | `defaultValue` | +| `integer` | Whole numbers | - | +| `decimal` | Decimal numbers | - | +| `textTemplate` | Dynamic text | - | +| `expression` | Computed values | `returnType` (optional) | +| `action` | Event handlers | - | +| `attribute` | Entity binding | `attributeTypes` | +| `datasource` | List data | `isList: true` | +| `enumeration` | Dropdown | `enumValues` | +| `widgets` | Child widgets | - | +| `object` | Nested structure | `properties`, `isList` | +| `icon` | Icon picker | - | +| `image` | Image picker | - | +| `association` | Entity relation | - | +| `selection` | Selection mode | - | diff --git a/packages/pluggable-widgets-mcp/docs/widget-patterns.md b/packages/pluggable-widgets-mcp/docs/widget-patterns.md new file mode 100644 index 0000000000..6cf76aa6c4 --- /dev/null +++ b/packages/pluggable-widgets-mcp/docs/widget-patterns.md @@ -0,0 +1,556 @@ +# Mendix Widget Patterns + +This document provides reusable patterns for common widget types. Use these as templates when implementing widget components. + +--- + +## Pattern: Display Widget + +Display widgets show read-only data. Examples: Badge, Progress Bar, Label. + +### Typical Properties + +```json +{ + "properties": [ + { "key": "value", "type": "textTemplate", "caption": "Value" }, + { "key": "type", "type": "enumeration", "caption": "Style", "enumValues": [...] }, + { "key": "onClick", "type": "action", "caption": "On click", "required": false } + ], + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +### TSX Structure + +```tsx +import { ReactNode, useCallback } from "react"; +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; +import { MyWidgetContainerProps } from "../typings/MyWidgetProps"; +import "./ui/MyWidget.scss"; + +export default function MyWidget(props: MyWidgetContainerProps): ReactNode { + const { value, type, onClick, tabIndex, class: className, style } = props; + + const handleClick = useCallback(() => { + executeAction(onClick); + }, [onClick]); + + const isClickable = onClick?.canExecute; + + return ( +
+ {value?.value ?? ""} +
+ ); +} +``` + +### SCSS Structure + +```scss +.widget-mywidget { + display: inline-block; + padding: 4px 8px; + border-radius: 4px; + + &-primary { + background-color: var(--brand-primary); + color: white; + } + + &-secondary { + background-color: var(--brand-secondary); + color: white; + } +} +``` + +--- + +## Pattern: Button Widget + +Button widgets trigger actions on click. May include icons, loading states. + +### Typical Properties + +```json +{ + "properties": [ + { "key": "caption", "type": "textTemplate", "caption": "Caption" }, + { "key": "icon", "type": "icon", "caption": "Icon", "required": false }, + { + "key": "buttonStyle", + "type": "enumeration", + "caption": "Style", + "defaultValue": "primary", + "enumValues": [ + { "key": "primary", "caption": "Primary" }, + { "key": "secondary", "caption": "Secondary" }, + { "key": "danger", "caption": "Danger" } + ] + }, + { "key": "onClick", "type": "action", "caption": "On click" } + ], + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +### TSX Structure + +```tsx +import { ReactNode, useCallback, KeyboardEvent } from "react"; +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; +import { MyButtonContainerProps } from "../typings/MyButtonProps"; +import "./ui/MyButton.scss"; + +export default function MyButton(props: MyButtonContainerProps): ReactNode { + const { caption, icon, buttonStyle, onClick, tabIndex, class: className, style } = props; + + const handleClick = useCallback(() => { + executeAction(onClick); + }, [onClick]); + + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + handleClick(); + } + }, + [handleClick] + ); + + const isDisabled = !onClick?.canExecute; + + return ( + + ); +} +``` + +### SCSS Structure + +```scss +.widget-mybutton { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 16px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &-primary { + background-color: var(--brand-primary); + color: white; + } + + &-secondary { + background-color: transparent; + border: 1px solid var(--brand-primary); + color: var(--brand-primary); + } + + &-danger { + background-color: var(--brand-danger); + color: white; + } +} +``` + +--- + +## Pattern: Input Widget + +Input widgets bind to entity attributes for data entry. + +### Typical Properties + +```json +{ + "properties": [ + { + "key": "value", + "type": "attribute", + "caption": "Value", + "attributeTypes": ["String"], + "required": true + }, + { "key": "placeholder", "type": "textTemplate", "caption": "Placeholder", "required": false }, + { "key": "readOnly", "type": "boolean", "caption": "Read-only", "defaultValue": false }, + { "key": "onChange", "type": "action", "caption": "On change", "required": false }, + { "key": "onEnter", "type": "action", "caption": "On enter", "required": false } + ], + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +### TSX Structure + +```tsx +import { ReactNode, useCallback, ChangeEvent, KeyboardEvent } from "react"; +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; +import { MyInputContainerProps } from "../typings/MyInputProps"; +import "./ui/MyInput.scss"; + +export default function MyInput(props: MyInputContainerProps): ReactNode { + const { value, placeholder, readOnly, onChange, onEnter, tabIndex, class: className, style } = props; + + const handleChange = useCallback( + (event: ChangeEvent) => { + if (value?.status === "available" && !value.readOnly) { + value.setValue(event.target.value); + executeAction(onChange); + } + }, + [value, onChange] + ); + + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + if (event.key === "Enter") { + executeAction(onEnter); + } + }, + [onEnter] + ); + + const isReadOnly = readOnly || value?.readOnly; + + return ( + + ); +} +``` + +### SCSS Structure + +```scss +.widget-myinput { + width: 100%; + padding: 8px 12px; + border: 1px solid var(--border-color); + border-radius: 4px; + font-size: 14px; + + &:focus { + outline: none; + border-color: var(--brand-primary); + box-shadow: 0 0 0 2px rgba(var(--brand-primary-rgb), 0.2); + } + + &:read-only { + background-color: var(--bg-color-secondary); + } +} +``` + +--- + +## Pattern: Container Widget + +Container widgets hold child widgets. Examples: Fieldset, Card, Accordion. + +### Typical Properties + +```json +{ + "properties": [ + { "key": "content", "type": "widgets", "caption": "Content" }, + { "key": "header", "type": "textTemplate", "caption": "Header", "required": false }, + { "key": "collapsible", "type": "boolean", "caption": "Collapsible", "defaultValue": false } + ], + "systemProperties": ["Name", "TabIndex", "Visibility"] +} +``` + +### TSX Structure + +```tsx +import { ReactNode, useState, useCallback } from "react"; +import { MyContainerContainerProps } from "../typings/MyContainerProps"; +import "./ui/MyContainer.scss"; + +export default function MyContainer(props: MyContainerContainerProps): ReactNode { + const { content, header, collapsible, tabIndex, class: className, style } = props; + const [isOpen, setIsOpen] = useState(true); + + const handleToggle = useCallback(() => { + if (collapsible) { + setIsOpen(prev => !prev); + } + }, [collapsible]); + + return ( +
+ {header?.value && ( +
+ {header.value} + {collapsible && } +
+ )} + {isOpen &&
{content}
} +
+ ); +} +``` + +### SCSS Structure + +```scss +.widget-mycontainer { + border: 1px solid var(--border-color); + border-radius: 4px; + overflow: hidden; + + &-header { + padding: 12px 16px; + background-color: var(--bg-color-secondary); + font-weight: 600; + display: flex; + justify-content: space-between; + align-items: center; + + &[role="button"] { + cursor: pointer; + } + } + + &-toggle { + transition: transform 0.2s; + + &.open { + transform: rotate(180deg); + } + } + + &-content { + padding: 16px; + } +} +``` + +--- + +## Pattern: Data List Widget + +Data list widgets display items from a datasource. + +### Typical Properties + +```json +{ + "properties": [ + { "key": "dataSource", "type": "datasource", "caption": "Data source", "isList": true }, + { "key": "content", "type": "widgets", "caption": "Content", "dataSource": "dataSource" }, + { "key": "emptyMessage", "type": "textTemplate", "caption": "Empty message", "required": false }, + { "key": "onItemClick", "type": "action", "caption": "On item click", "required": false } + ], + "systemProperties": ["Name", "Visibility"] +} +``` + +### TSX Structure + +```tsx +import { ReactNode, useCallback } from "react"; +import { ValueStatus, ObjectItem } from "mendix"; +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; +import { MyListContainerProps } from "../typings/MyListProps"; +import "./ui/MyList.scss"; + +export default function MyList(props: MyListContainerProps): ReactNode { + const { dataSource, content, emptyMessage, onItemClick, class: className, style } = props; + + // Loading state + if (dataSource?.status !== ValueStatus.Available) { + return ( +
+ Loading... +
+ ); + } + + const items = dataSource?.items ?? []; + + // Empty state + if (items.length === 0) { + return ( +
+ {emptyMessage?.value ?? "No items"} +
+ ); + } + + return ( +
+ {items.map((item: ObjectItem) => ( +
executeAction(onItemClick)}> + {content?.get(item)} +
+ ))} +
+ ); +} +``` + +### SCSS Structure + +```scss +.widget-mylist { + display: flex; + flex-direction: column; + gap: 8px; + + &-loading, + &-empty { + padding: 16px; + text-align: center; + color: var(--text-color-secondary); + } + + &-item { + padding: 12px; + border: 1px solid var(--border-color); + border-radius: 4px; + + &:hover { + background-color: var(--bg-color-hover); + } + } +} +``` + +--- + +## Common Imports + +Every widget typically needs these imports: + +```tsx +// React +import { ReactNode, useCallback, useState } from "react"; + +// Mendix helpers +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; +import { ValueStatus } from "mendix"; + +// Generated types (from XML via pwt build) +import { MyWidgetContainerProps } from "../typings/MyWidgetProps"; + +// Styles +import "./ui/MyWidget.scss"; +``` + +--- + +## Key Patterns + +### Action Execution + +Always use `executeAction` from the platform helpers: + +```tsx +import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action"; + +const handleClick = useCallback(() => { + executeAction(props.onClick); +}, [props.onClick]); + +// Check if action can execute +const isClickable = props.onClick?.canExecute; +``` + +### Attribute Value Handling + +Check status before reading/writing: + +```tsx +// Reading +const displayValue = props.value?.value ?? ""; + +// Writing +if (props.value?.status === "available" && !props.value.readOnly) { + props.value.setValue(newValue); +} +``` + +### Loading States + +Handle datasource loading: + +```tsx +if (props.dataSource?.status !== ValueStatus.Available) { + return
Loading...
; +} +``` + +### Accessibility + +Always include proper accessibility attributes: + +```tsx + + ); +} +`; +} + +/** + * Generates the Input pattern component. + */ +function generateInputPattern(widgetName: string, properties: PropertyDefinition[]): string { + const imports = generateImports(widgetName, properties, "input"); + + // Find relevant properties + const attributeProps = properties.filter(p => p.type === "attribute"); + const mainAttribute = attributeProps[0]; + const actionProps = properties.filter(p => p.type === "action"); + const textProps = properties.filter(p => p.type === "textTemplate" || p.type === "string"); + + // Generate destructuring + const allProps = [...attributeProps, ...actionProps, ...textProps]; + const propsToDestructure = ["class: className", "style", "tabIndex", ...allProps.map(p => p.key)]; + + // Determine input type based on attribute type + const attrType = mainAttribute?.attributeTypes?.[0] ?? "String"; + let inputType = "text"; + if (attrType === "Integer" || attrType === "Long" || attrType === "Decimal") { + inputType = "number"; + } else if (attrType === "Boolean") { + inputType = "checkbox"; + } + + const mainKey = mainAttribute?.key ?? "value"; + + // Find change action + const changeAction = actionProps.find(p => p.key.toLowerCase().includes("change")); + const changeHandler = changeAction ? true : false; + + // Determine if we need Big conversion for numeric attributes + const usesBig = inputType === "number"; + const valueExtraction = usesBig ? `${mainKey}?.value?.toNumber() ?? 0` : `${mainKey}?.value ?? ""`; + const valueConversion = usesBig ? `new Big(Number(event.target.value))` : `event.target.value`; + + return `${imports} + +export default function ${widgetName}(props: ${widgetName}ContainerProps): ReactElement { + const { ${propsToDestructure.join(", ")} } = props; + + const currentValue = ${valueExtraction}; + const isReadOnly = ${mainKey}?.readOnly ?? false; + + const handleInputChange = useCallback((event: React.ChangeEvent) => { + if (${mainKey}?.status === "available" && !${mainKey}.readOnly) { + ${mainKey}.setValue(${valueConversion}); + }${changeHandler ? `\n executeAction(${changeAction?.key});` : ""} + }, [${mainKey}${changeHandler ? `, ${changeAction?.key}` : ""}]); + + return ( + + ); +} +`; +} + +/** + * Generates the Container pattern component. + */ +function generateContainerPattern(widgetName: string, properties: PropertyDefinition[]): string { + const imports = generateImports(widgetName, properties, "container"); + + // Find relevant properties + const widgetProps = properties.filter(p => p.type === "widgets"); + const mainContent = widgetProps[0]; + const textProps = properties.filter(p => p.type === "textTemplate" || p.type === "string"); + const headerProp = textProps.find(p => p.key === "header" || p.key === "title") || textProps[0]; + const boolProps = properties.filter(p => p.type === "boolean"); + const collapsibleProp = boolProps.find(p => p.key === "collapsible"); + + // Generate destructuring + const allProps = [...widgetProps, ...textProps, ...boolProps]; + const propsToDestructure = ["class: className", "style", "tabIndex", ...allProps.map(p => p.key)]; + + const contentKey = mainContent?.key ?? "content"; + const headerValue = headerProp ? `${headerProp.key}?.value` : "undefined"; + const isCollapsible = collapsibleProp?.key ?? "false"; + + return `${imports} + +export default function ${widgetName}(props: ${widgetName}ContainerProps): ReactElement { + const { ${propsToDestructure.join(", ")} } = props; + + const [isOpen, setIsOpen] = useState(true); + + const handleToggle = useCallback(() => { + if (${isCollapsible}) { + setIsOpen(prev => !prev); + } + }, [${isCollapsible}]); + + const headerValue = ${headerValue}; + + return ( +
+ {headerValue && ( +
+ {headerValue} + {${isCollapsible} && } +
+ )} + {isOpen &&
{${contentKey}}
} +
+ ); +} +`; +} + +/** + * Generates the Data List pattern component. + */ +function generateDataListPattern(widgetName: string, properties: PropertyDefinition[]): string { + const imports = generateImports(widgetName, properties, "dataList"); + + // Find relevant properties + const datasourceProp = properties.find(p => p.type === "datasource"); + const widgetProps = properties.filter(p => p.type === "widgets"); + const contentProp = widgetProps.find(p => p.dataSource) || widgetProps[0]; + const textProps = properties.filter(p => p.type === "textTemplate" || p.type === "string"); + const emptyMessageProp = textProps.find(p => p.key.toLowerCase().includes("empty")); + const actionProps = properties.filter(p => p.type === "action"); + const itemClickAction = actionProps.find(p => p.key.toLowerCase().includes("item")); + + // Generate destructuring + const allProps = [datasourceProp, contentProp, emptyMessageProp, itemClickAction].filter( + Boolean + ) as PropertyDefinition[]; + const propsToDestructure = ["class: className", "style", ...allProps.map(p => p.key)]; + + // Generate action handlers + const actionHandlers = itemClickAction ? [generateActionHandler(itemClickAction)] : []; + + const dsKey = datasourceProp?.key ?? "dataSource"; + const contentKey = contentProp?.key ?? "content"; + const emptyMessage = emptyMessageProp ? `${emptyMessageProp.key}?.value ?? "No items"` : '"No items"'; + const itemHandler = itemClickAction + ? `handle${itemClickAction.key.charAt(0).toUpperCase() + itemClickAction.key.slice(1)}` + : "undefined"; + + return `${imports} +import { ObjectItem } from "mendix"; + +export default function ${widgetName}(props: ${widgetName}ContainerProps): ReactElement { + const { ${propsToDestructure.join(", ")} } = props; + + ${actionHandlers.join("\n\n ")} + + // Loading state + if (${dsKey}?.status !== ValueStatus.Available) { + return ( +
+ Loading... +
+ ); + } + + const items = ${dsKey}?.items ?? []; + + // Empty state + if (items.length === 0) { + return ( +
+ {${emptyMessage}} +
+ ); + } + + return ( +
+ {items.map((item: ObjectItem) => ( +
+ {${contentKey}?.get(item)} +
+ ))} +
+ ); +} +`; +} + +/** + * Generates the complete widget TSX from a widget definition. + */ +export function generateWidgetTsx( + widgetName: string, + properties: PropertyDefinition[], + pattern?: WidgetPattern +): TsxGeneratorResult { + try { + // Detect pattern if not specified + const detectedPattern = pattern ?? detectWidgetPattern(properties); + + let mainComponent: string; + + switch (detectedPattern) { + case "display": + mainComponent = generateDisplayPattern(widgetName, properties); + break; + case "button": + mainComponent = generateButtonPattern(widgetName, properties); + break; + case "input": + mainComponent = generateInputPattern(widgetName, properties); + break; + case "container": + mainComponent = generateContainerPattern(widgetName, properties); + break; + case "dataList": + mainComponent = generateDataListPattern(widgetName, properties); + break; + default: + mainComponent = generateDisplayPattern(widgetName, properties); + } + + return { + success: true, + mainComponent, + pattern: detectedPattern + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } +} diff --git a/packages/pluggable-widgets-mcp/src/generators/types.ts b/packages/pluggable-widgets-mcp/src/generators/types.ts new file mode 100644 index 0000000000..96ad1172a6 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/generators/types.ts @@ -0,0 +1,161 @@ +/** + * Type definitions for widget generation. + * These types define the JSON schema that AI fills in, + * which is then transformed into valid XML by the generator. + */ + +/** + * Mendix property types supported in widget XML. + */ +export type MendixPropertyType = + | "string" + | "boolean" + | "integer" + | "decimal" + | "textTemplate" + | "expression" + | "action" + | "attribute" + | "datasource" + | "association" + | "selection" + | "enumeration" + | "icon" + | "image" + | "file" + | "widgets" + | "object"; + +/** + * Attribute types for attribute properties. + */ +export type AttributeType = + | "String" + | "Integer" + | "Long" + | "Decimal" + | "Boolean" + | "DateTime" + | "Enum" + | "HashString" + | "Binary" + | "AutoNumber"; + +/** + * Enumeration value for enumeration properties. + */ +export interface EnumValue { + key: string; + caption: string; +} + +/** + * Definition for a single widget property. + * This is the JSON structure AI fills in. + */ +export interface PropertyDefinition { + /** Property key (camelCase identifier) */ + key: string; + + /** Property type */ + type: MendixPropertyType; + + /** Display caption in Studio Pro */ + caption: string; + + /** Optional description shown in Studio Pro */ + description?: string; + + /** Whether the property is required */ + required?: boolean; + + /** Default value (for string, boolean, integer, decimal, enumeration) */ + defaultValue?: string | number | boolean; + + /** For enumeration type: list of allowed values */ + enumValues?: EnumValue[]; + + /** For attribute type: allowed attribute types */ + attributeTypes?: AttributeType[]; + + /** For datasource type: whether it returns a list */ + isList?: boolean; + + /** For widgets type: reference to datasource property key */ + dataSource?: string; + + /** For object type: nested properties */ + properties?: PropertyDefinition[]; + + /** For expression type: return type */ + returnType?: "String" | "Integer" | "Decimal" | "Boolean" | "DateTime"; +} + +/** + * System properties available in Mendix widgets. + */ +export type SystemProperty = "Name" | "TabIndex" | "Visibility"; + +/** + * Property group for organizing properties in Studio Pro. + */ +export interface PropertyGroup { + /** Group caption displayed in Studio Pro */ + caption: string; + + /** Property keys in this group */ + properties: string[]; +} + +/** + * Complete widget definition. + * This is the full JSON structure AI provides for widget generation. + */ +export interface WidgetDefinition { + /** Widget name (PascalCase) */ + name: string; + + /** Widget description */ + description: string; + + /** Widget ID (e.g., "com.mendix.widget.custom.mywidget.MyWidget") */ + id?: string; + + /** Organization namespace */ + organization?: string; + + /** Studio Pro category */ + studioCategory?: string; + + /** Whether widget needs entity context */ + needsEntityContext?: boolean; + + /** Whether widget supports offline */ + offlineCapable?: boolean; + + /** Help URL */ + helpUrl?: string; + + /** Property definitions */ + properties: PropertyDefinition[]; + + /** System properties to include */ + systemProperties?: SystemProperty[]; + + /** Optional property grouping */ + propertyGroups?: PropertyGroup[]; +} + +/** + * Result of XML generation. + */ +export interface GeneratorResult { + /** Whether generation succeeded */ + success: boolean; + + /** Generated XML content (if success) */ + xml?: string; + + /** Error message (if failed) */ + error?: string; +} diff --git a/packages/pluggable-widgets-mcp/src/generators/xml-generator.ts b/packages/pluggable-widgets-mcp/src/generators/xml-generator.ts new file mode 100644 index 0000000000..9b299a9d25 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/generators/xml-generator.ts @@ -0,0 +1,264 @@ +/** + * XML Generator for Mendix Widget Definitions. + * + * Transforms a WidgetDefinition JSON structure into valid Mendix widget XML. + * This is a deterministic transformation - same input always produces same output. + */ + +import type { EnumValue, GeneratorResult, PropertyDefinition, SystemProperty, WidgetDefinition } from "./types"; + +/** + * Escapes special XML characters in text content. + */ +function escapeXml(text: string): string { + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +/** + * Generates XML for enumeration values. + */ +function generateEnumValues(values: EnumValue[], indent: string): string { + const lines = values.map( + v => `${indent} ${escapeXml(v.caption)}` + ); + return `${indent}\n${lines.join("\n")}\n${indent}`; +} + +/** + * Generates XML for attribute types. + */ +function generateAttributeTypes(types: string[], indent: string): string { + const lines = types.map(t => `${indent} `); + return `${indent}\n${lines.join("\n")}\n${indent}`; +} + +/** + * Generates XML for a single property. + */ +function generateProperty(prop: PropertyDefinition, indent: string): string { + const attrs: string[] = [`key="${escapeXml(prop.key)}"`, `type="${prop.type}"`]; + + // Add optional attributes + if (prop.required !== undefined) { + attrs.push(`required="${prop.required}"`); + } + if (prop.defaultValue !== undefined) { + attrs.push(`defaultValue="${escapeXml(String(prop.defaultValue))}"`); + } + if (prop.isList) { + attrs.push(`isList="true"`); + } + if (prop.dataSource) { + attrs.push(`dataSource="${escapeXml(prop.dataSource)}"`); + } + + const attrString = attrs.join(" "); + const innerIndent = indent + " "; + const lines: string[] = []; + + lines.push(`${indent}`); + lines.push(`${innerIndent}${escapeXml(prop.caption)}`); + + if (prop.description) { + lines.push(`${innerIndent}${escapeXml(prop.description)}`); + } else { + lines.push(`${innerIndent}`); + } + + // Type-specific content + if (prop.type === "enumeration" && prop.enumValues) { + lines.push(generateEnumValues(prop.enumValues, innerIndent)); + } + + if (prop.type === "attribute" && prop.attributeTypes) { + lines.push(generateAttributeTypes(prop.attributeTypes, innerIndent)); + } + + if (prop.type === "expression" && prop.returnType) { + lines.push(`${innerIndent}`); + } + + if (prop.type === "object" && prop.properties) { + lines.push(`${innerIndent}`); + lines.push(`${innerIndent} `); + for (const nestedProp of prop.properties) { + lines.push(generateProperty(nestedProp, innerIndent + " ")); + } + lines.push(`${innerIndent} `); + lines.push(`${innerIndent}`); + } + + lines.push(`${indent}`); + + return lines.join("\n"); +} + +/** + * Generates XML for system properties. + */ +function generateSystemProperty(key: SystemProperty, indent: string): string { + return `${indent}`; +} + +/** + * Generates the complete widget XML from a widget definition. + */ +export function generateWidgetXml(widget: WidgetDefinition): GeneratorResult { + try { + // Derive defaults + const organization = widget.organization ?? "mendix"; + const widgetNameLower = widget.name.toLowerCase(); + const widgetId = widget.id ?? `com.${organization}.widget.custom.${widgetNameLower}.${widget.name}`; + const studioCategory = widget.studioCategory ?? "Display"; + const needsEntityContext = widget.needsEntityContext ?? false; + const offlineCapable = widget.offlineCapable ?? true; + + // Build widget attributes + const widgetAttrs = [ + `id="${escapeXml(widgetId)}"`, + `pluginWidget="true"`, + needsEntityContext ? `needsEntityContext="true"` : null, + `offlineCapable="${offlineCapable}"`, + `xmlns="http://www.mendix.com/widget/1.0/"`, + `xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"`, + `xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../../../../node_modules/mendix/custom_widget.xsd"` + ] + .filter(Boolean) + .join(" "); + + const lines: string[] = []; + lines.push(``); + lines.push(``); + lines.push(` ${escapeXml(widget.name)}`); + lines.push(` ${widget.description ? escapeXml(widget.description) : ""}`); + lines.push(` ${escapeXml(studioCategory)}`); + lines.push(` ${escapeXml(studioCategory)}`); + + if (widget.helpUrl) { + lines.push(` ${escapeXml(widget.helpUrl)}`); + } + + lines.push(` `); + + // Group properties if grouping is specified + if (widget.propertyGroups && widget.propertyGroups.length > 0) { + for (const group of widget.propertyGroups) { + lines.push(` `); + for (const propKey of group.properties) { + const prop = widget.properties.find(p => p.key === propKey); + if (prop) { + lines.push(generateProperty(prop, " ")); + } + } + lines.push(` `); + } + } else { + // Default grouping: General for non-action properties, Events for actions + lines.push(` `); + for (const prop of widget.properties.filter(p => p.type !== "action")) { + lines.push(generateProperty(prop, " ")); + } + lines.push(` `); + + const actionProps = widget.properties.filter(p => p.type === "action"); + if (actionProps.length > 0) { + lines.push(` `); + for (const prop of actionProps) { + lines.push(generateProperty(prop, " ")); + } + lines.push(` `); + } + } + + // System properties + if (widget.systemProperties && widget.systemProperties.length > 0) { + const visibilityProps = widget.systemProperties.filter(p => p === "Visibility"); + const commonProps = widget.systemProperties.filter(p => p !== "Visibility"); + + if (visibilityProps.length > 0) { + lines.push(` `); + for (const sysProp of visibilityProps) { + lines.push(generateSystemProperty(sysProp, " ")); + } + lines.push(` `); + } + + if (commonProps.length > 0) { + lines.push(` `); + for (const sysProp of commonProps) { + lines.push(generateSystemProperty(sysProp, " ")); + } + lines.push(` `); + } + } + + lines.push(` `); + lines.push(``); + + return { + success: true, + xml: lines.join("\n") + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } +} + +/** + * Validates a widget definition before generation. + * Returns an array of validation errors (empty if valid). + */ +export function validateWidgetDefinition(widget: WidgetDefinition): string[] { + const errors: string[] = []; + + if (!widget.name || widget.name.trim() === "") { + errors.push("Widget name is required"); + } else if (!/^[A-Z][a-zA-Z0-9]*$/.test(widget.name)) { + errors.push("Widget name must be PascalCase (e.g., MyWidget)"); + } + + if (!widget.properties || widget.properties.length === 0) { + errors.push("Widget must have at least one property"); + } + + for (const prop of widget.properties ?? []) { + if (!prop.key || prop.key.trim() === "") { + errors.push("Property key is required"); + } else if (!/^[a-z][a-zA-Z0-9]*$/.test(prop.key)) { + errors.push(`Property key "${prop.key}" must be camelCase`); + } + + if (!prop.caption || prop.caption.trim() === "") { + errors.push(`Property "${prop.key}" must have a caption`); + } + + if (prop.type === "enumeration" && (!prop.enumValues || prop.enumValues.length === 0)) { + errors.push(`Enumeration property "${prop.key}" must have enumValues`); + } + + if (prop.type === "attribute" && (!prop.attributeTypes || prop.attributeTypes.length === 0)) { + errors.push(`Attribute property "${prop.key}" must have attributeTypes`); + } + } + + if (widget.propertyGroups) { + const propertyKeys = new Set(widget.properties.map(p => p.key)); + for (const group of widget.propertyGroups) { + for (const key of group.properties) { + if (!propertyKeys.has(key)) { + errors.push(`Property group "${group.caption}" references unknown property key: "${key}"`); + } + } + } + } + + return errors; +} diff --git a/packages/pluggable-widgets-mcp/src/index.ts b/packages/pluggable-widgets-mcp/src/index.ts new file mode 100644 index 0000000000..5e4fe00721 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/index.ts @@ -0,0 +1,16 @@ +#!/usr/bin/env node +import { startHttpServer } from "@/server/http"; +import { startStdioServer } from "@/server/stdio"; + +type TransportMode = "http" | "stdio"; + +const mode = (process.argv[2] as TransportMode) || "stdio"; + +if (mode === "http") { + startHttpServer(); +} else { + startStdioServer().catch(err => { + console.error("Fatal error:", err); + process.exit(1); + }); +} diff --git a/packages/pluggable-widgets-mcp/src/resources/guidelines.ts b/packages/pluggable-widgets-mcp/src/resources/guidelines.ts new file mode 100644 index 0000000000..49e7cb7947 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/resources/guidelines.ts @@ -0,0 +1,78 @@ +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; +import { DOCS_DIR } from "@/config"; + +/** + * Definition for a guideline resource. + */ +export interface GuidelineResource { + /** Unique resource name */ + name: string; + /** Resource URI (e.g., mendix://guidelines/frontend) */ + uri: string; + /** Human-readable title */ + title: string; + /** Description of what this guideline covers */ + description: string; + /** Source markdown file name */ + filename: string; +} + +/** + * All available guideline resources. + */ +export const GUIDELINE_RESOURCES: GuidelineResource[] = [ + { + name: "property-types", + uri: "mendix://guidelines/property-types", + title: "Property Types Reference", + description: + "Complete reference for all Mendix widget property types (string, boolean, action, attribute, etc.) with JSON schema and XML output examples", + filename: "property-types.md" + }, + { + name: "widget-patterns", + uri: "mendix://guidelines/widget-patterns", + title: "Widget Patterns", + description: + "Reusable patterns for common widget types (button, input, display, container, data list) with TSX and SCSS templates", + filename: "widget-patterns.md" + } +]; + +/** + * Cache for loaded guideline content to avoid repeated file reads. + */ +const guidelineCache = new Map(); + +/** + * Loads the content of a guideline file. + * Caches content after first load for performance. + * + * @param filename - The markdown filename to load + * @returns The file content as a string + */ +export async function loadGuidelineContent(filename: string): Promise { + // Check cache first + if (guidelineCache.has(filename)) { + return guidelineCache.get(filename)!; + } + + const filePath = join(DOCS_DIR, filename); + + try { + const content = await readFile(filePath, "utf-8"); + guidelineCache.set(filename, content); + return content; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Failed to load guideline ${filename}: ${message}`); + } +} + +/** + * Clears the guideline cache. Useful for testing or hot-reloading. + */ +export function clearGuidelineCache(): void { + guidelineCache.clear(); +} diff --git a/packages/pluggable-widgets-mcp/src/resources/index.ts b/packages/pluggable-widgets-mcp/src/resources/index.ts new file mode 100644 index 0000000000..2ef570bfb3 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/resources/index.ts @@ -0,0 +1,44 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { GUIDELINE_RESOURCES, loadGuidelineContent } from "./guidelines"; + +/** + * Registers all MCP resources with the server. + * + * Resources are read-only data sources that clients can fetch on-demand. + * We expose the Mendix widget development guidelines as resources so LLMs + * can access them when implementing widget functionality. + */ +export function registerResources(server: McpServer): void { + registerGuidelineResources(server); +} + +/** + * Registers guideline documentation as MCP resources. + */ +function registerGuidelineResources(server: McpServer): void { + for (const resource of GUIDELINE_RESOURCES) { + server.registerResource( + resource.name, + resource.uri, + { + title: resource.title, + description: resource.description, + mimeType: "text/markdown" + }, + async uri => { + const content = await loadGuidelineContent(resource.filename); + return { + contents: [ + { + uri: uri.href, + mimeType: "text/markdown", + text: content + } + ] + }; + } + ); + } + + console.error(`[resources] Registered ${GUIDELINE_RESOURCES.length} guideline resources`); +} diff --git a/packages/pluggable-widgets-mcp/src/security/guardrails.ts b/packages/pluggable-widgets-mcp/src/security/guardrails.ts new file mode 100644 index 0000000000..07f9515483 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/security/guardrails.ts @@ -0,0 +1,130 @@ +/** + * Security Guardrails for File Operations + * + * This module centralizes all security validation to: + * 1. Prevent path traversal attacks (directory escape) + * 2. Restrict file operations to safe extensions + * 3. Ensure operations stay within widget boundaries + * + * @module security/guardrails + */ + +import { extname, resolve } from "node:path"; + +// ============================================================================= +// Configuration +// ============================================================================= + +/** + * Allowed file extensions for write operations. + * Only widget-related source files are permitted. + */ +export const ALLOWED_EXTENSIONS = [".tsx", ".ts", ".xml", ".scss", ".css", ".json", ".md"]; + +/** + * Config files allowed without extensions (e.g., tsconfig, package) + */ +const ALLOWED_EXTENSIONLESS_PATTERNS = ["package", "tsconfig", "eslintrc"]; + +/** + * Specific dot-files allowed (explicit allowlist to prevent arbitrary dotfile access). + */ +const ALLOWED_DOT_FILES = [".gitignore", ".prettierrc", ".eslintrc", ".editorconfig"]; + +// ============================================================================= +// Path Traversal Prevention +// ============================================================================= + +/** + * Validates that a file path is within the allowed widget directory. + * Prevents directory traversal attacks. + * + * Uses path.resolve() to canonicalize paths, catching tricks like: + * - /widget/../../../etc/passwd + * - encoded sequences + * + * @param basePath - The base widget directory path + * @param relativePath - The relative file path to validate + * @returns true if the path is safe, false otherwise + * + * @example + * isPathWithinDirectory("/widgets/foo", "src/Bar.tsx") // true + * isPathWithinDirectory("/widgets/foo", "../secret.txt") // false + */ +export function isPathWithinDirectory(basePath: string, relativePath: string): boolean { + // Resolve both paths to absolute paths + const resolvedBase = resolve(basePath); + const resolvedFull = resolve(basePath, relativePath); + + // Check that the resolved path starts with the base path + // This prevents ../ traversal attacks + return resolvedFull.startsWith(resolvedBase + "/") || resolvedFull === resolvedBase; +} + +// ============================================================================= +// Extension Whitelist +// ============================================================================= + +/** + * Validates that a file extension is allowed for write operations. + * + * @param filePath - The file path to check + * @returns true if the extension is allowed, false otherwise + * + * @example + * isExtensionAllowed("Button.tsx") // true + * isExtensionAllowed("script.exe") // false + */ +export function isExtensionAllowed(filePath: string): boolean { + const ext = extname(filePath).toLowerCase(); + // Also allow files without extension (like .gitignore patterns) + // and special config files + if (ext === "") { + const filename = filePath.split("/").pop() || ""; + // Allow common config files without extensions, or specific dot-files + return ( + ALLOWED_EXTENSIONLESS_PATTERNS.some(name => filename.includes(name)) || ALLOWED_DOT_FILES.includes(filename) + ); + } + return ALLOWED_EXTENSIONS.includes(ext); +} + +// ============================================================================= +// Combined Validation (High-Level API) +// ============================================================================= + +/** + * Validates widget path and file path for security. + * Throws an error if validation fails. + * + * @param widgetPath - The base widget directory path + * @param filePath - The relative file path to validate + * @param checkExtension - Whether to also validate file extension (for write operations) + * + * @throws {Error} If path traversal detected ('..' in path) + * @throws {Error} If path escapes widget directory + * @throws {Error} If extension not allowed (when checkExtension=true) + * + * @example + * // Read operation (no extension check) + * validateFilePath("/widgets/foo", "src/Bar.tsx"); + * + * // Write operation (with extension check) + * validateFilePath("/widgets/foo", "src/Bar.tsx", true); + */ +export function validateFilePath(widgetPath: string, filePath: string, checkExtension = false): void { + // Check for obvious path traversal attempts + if (filePath.includes("..")) { + throw new Error("Path traversal not allowed: '..' detected in file path"); + } + + // Validate path is within widget directory + if (!isPathWithinDirectory(widgetPath, filePath)) { + throw new Error("File path must be within the widget directory"); + } + + // For write operations, check extension + if (checkExtension && !isExtensionAllowed(filePath)) { + throw new Error(`File extension not allowed. Allowed extensions: ${ALLOWED_EXTENSIONS.join(", ")}`); + } +} diff --git a/packages/pluggable-widgets-mcp/src/security/index.ts b/packages/pluggable-widgets-mcp/src/security/index.ts new file mode 100644 index 0000000000..708da7c7b7 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/security/index.ts @@ -0,0 +1,14 @@ +/** + * Security module exports. + * + * This module provides security guardrails for file operations: + * - Path traversal prevention + * - Extension whitelist validation + * + * @example + * import { validateFilePath, ALLOWED_EXTENSIONS } from "@/security"; + * + * validateFilePath(widgetPath, filePath, true); // Throws if invalid + */ + +export { ALLOWED_EXTENSIONS, isExtensionAllowed, isPathWithinDirectory, validateFilePath } from "./guardrails"; diff --git a/packages/pluggable-widgets-mcp/src/server/http.ts b/packages/pluggable-widgets-mcp/src/server/http.ts new file mode 100644 index 0000000000..3f54654dba --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/server/http.ts @@ -0,0 +1,39 @@ +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import cors from "cors"; +import { PORT } from "@/config"; +import { setupRoutes } from "./routes"; +import { sessionManager } from "./session"; + +/** + * Starts the MCP server with HTTP/Streamable transport. + * Supports multiple concurrent sessions via Express. + */ +export function startHttpServer(): void { + const app = createMcpExpressApp(); + app.use( + cors({ + origin: true, + methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"], + allowedHeaders: "*", + exposedHeaders: ["mcp-session-id"], + credentials: true + }) + ); + + setupRoutes(app); + + const server = app.listen(PORT, () => { + console.log(`[HTTP] MCP Server started on port ${PORT}`); + console.log(`[HTTP] Health check: http://localhost:${PORT}/health`); + console.log(`[HTTP] MCP endpoint: http://localhost:${PORT}/mcp`); + }); + + const shutdown = async (): Promise => { + console.log("\n[HTTP] Shutting down server..."); + await sessionManager.closeAll(); + server.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/packages/pluggable-widgets-mcp/src/server/routes.ts b/packages/pluggable-widgets-mcp/src/server/routes.ts new file mode 100644 index 0000000000..38cdbc1d64 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/server/routes.ts @@ -0,0 +1,93 @@ +import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; +import type { Express, Request, Response } from "express"; +import { SERVER_NAME, SERVER_VERSION } from "@/config"; +import { createMcpServer } from "./server"; +import { sessionManager } from "./session"; + +/** + * Sets up all routes for the Express application. + */ +export function setupRoutes(app: Express): void { + setupHealthRoute(app); + setupMcpRoute(app); +} + +/** + * Health check endpoint for monitoring. + */ +function setupHealthRoute(app: Express): void { + app.get("/health", (_req: Request, res: Response) => { + res.json({ + status: "ok", + server: SERVER_NAME, + version: SERVER_VERSION, + sessions: sessionManager.sessionCount + }); + }); +} + +/** + * Main MCP endpoint handling session management and request routing. + */ +function setupMcpRoute(app: Express): void { + // Handle CORS preflight explicitly + app.options("/mcp", (_req: Request, res: Response) => { + res.status(204).end(); + }); + + app.all("/mcp", async (req: Request, res: Response) => { + const sessionId = req.headers["mcp-session-id"] as string | undefined; + + try { + // Case 1: Existing session - reuse transport + if (sessionId && sessionManager.hasSession(sessionId)) { + const transport = sessionManager.getTransport(sessionId)!; + await transport.handleRequest(req, res, req.body); + return; + } + + // Case 2: New session via POST with initialize request + if (req.method === "POST" && !sessionId && isInitializeRequest(req.body)) { + const transport = sessionManager.createTransport(); + const server = createMcpServer(); + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + return; + } + + // Case 3: GET request for SSE - create new session + // StreamableHTTP uses GET for server-to-client event streams + if (req.method === "GET") { + const transport = sessionManager.createTransport(); + const server = createMcpServer(); + await server.connect(transport); + await transport.handleRequest(req, res); + return; + } + + // Case 4: Invalid request + sendJsonRpcError(res, 400, "Bad Request: No valid session ID provided"); + } catch (error) { + console.error("[MCP] Route error:", error); + sendJsonRpcError( + res, + 400, + "Invalid session. Send an initialize request without session ID to start a new session." + ); + } + }); +} + +/** + * Sends a JSON-RPC error response. + */ +function sendJsonRpcError(res: Response, statusCode: number, message: string): void { + res.status(statusCode).json({ + jsonrpc: "2.0", + error: { + code: -32000, + message + }, + id: null + }); +} diff --git a/packages/pluggable-widgets-mcp/src/server/server.ts b/packages/pluggable-widgets-mcp/src/server/server.ts new file mode 100644 index 0000000000..a0c2630ecf --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/server/server.ts @@ -0,0 +1,32 @@ +import { SERVER_ICON, SERVER_INSTRUCTIONS, SERVER_NAME, SERVER_VERSION, SERVER_WEBSITE_URL } from "@/config"; +import { registerResources } from "@/resources"; +import { registerAllTools } from "@/tools"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; + +/** + * Creates and configures a new MCP server instance with all registered tools and resources. + */ +export function createMcpServer(): McpServer { + const server = new McpServer( + { + name: SERVER_NAME, + version: SERVER_VERSION, + icons: [SERVER_ICON], + websiteUrl: SERVER_WEBSITE_URL + }, + { + capabilities: { + logging: {}, + prompts: {}, + resources: {}, + tools: {} + }, + instructions: SERVER_INSTRUCTIONS + } + ); + + registerAllTools(server); + registerResources(server); + + return server; +} diff --git a/packages/pluggable-widgets-mcp/src/server/session.ts b/packages/pluggable-widgets-mcp/src/server/session.ts new file mode 100644 index 0000000000..4015739e11 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/server/session.ts @@ -0,0 +1,77 @@ +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import { randomUUID } from "node:crypto"; + +export interface Session { + transport: StreamableHTTPServerTransport; + createdAt: Date; +} + +/** + * Manages MCP sessions and their associated transports. + */ +export class SessionManager { + private sessions = new Map(); + + /** + * Creates a new transport with session lifecycle callbacks. + * The transport is added to sessions when initialized via the callback. + */ + createTransport(): StreamableHTTPServerTransport { + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: () => randomUUID(), + onsessioninitialized: sessionId => { + this.sessions.set(sessionId, { + transport, + createdAt: new Date() + }); + console.log(`[MCP] Session initialized: ${sessionId}`); + }, + onsessionclosed: sessionId => { + this.sessions.delete(sessionId); + console.log(`[MCP] Session closed: ${sessionId}`); + } + }); + + return transport; + } + + /** + * Gets an existing session's transport by session ID. + */ + getTransport(sessionId: string): StreamableHTTPServerTransport | undefined { + return this.sessions.get(sessionId)?.transport; + } + + /** + * Checks if a session exists. + */ + hasSession(sessionId: string): boolean { + return this.sessions.has(sessionId); + } + + /** + * Gets the count of active sessions. + */ + get sessionCount(): number { + return this.sessions.size; + } + + /** + * Closes all sessions gracefully. + */ + async closeAll(): Promise { + const closePromises = Array.from(this.sessions.entries()).map(async ([sessionId, session]) => { + try { + console.log(`[MCP] Closing session: ${sessionId}`); + await session.transport.close(); + } catch (error) { + console.error(`[MCP] Error closing session ${sessionId}:`, error); + } + }); + + await Promise.all(closePromises); + this.sessions.clear(); + } +} + +export const sessionManager = new SessionManager(); diff --git a/packages/pluggable-widgets-mcp/src/server/stdio.ts b/packages/pluggable-widgets-mcp/src/server/stdio.ts new file mode 100644 index 0000000000..96039e6cd6 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/server/stdio.ts @@ -0,0 +1,31 @@ +import { createMcpServer } from "./server"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; + +/** + * Starts the MCP server with STDIO transport. + * Communicates via stdin/stdout for CLI-based MCP clients. + */ +export async function startStdioServer(): Promise { + const server = createMcpServer(); + const transport = new StdioServerTransport(); + + // Log to stderr since stdout is used for MCP communication + console.error("[STDIO] Starting MCP server..."); + + await server.connect(transport); + + console.error("[STDIO] MCP server connected and ready"); + + setupGracefulShutdown(transport); +} + +function setupGracefulShutdown(transport: StdioServerTransport): void { + const shutdown = async (): Promise => { + console.error("\n[STDIO] Shutting down server..."); + await transport.close(); + process.exit(0); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/build.tools.ts b/packages/pluggable-widgets-mcp/src/tools/build.tools.ts new file mode 100644 index 0000000000..2773a52ca6 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/build.tools.ts @@ -0,0 +1,463 @@ +/** + * Build tools for Mendix pluggable widgets. + * Wraps pluggable-widget-tools for building and validating widgets. + */ + +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { spawn } from "node:child_process"; +import { existsSync, readdirSync } from "node:fs"; +import { join, resolve } from "node:path"; +import { z } from "zod"; +import { GENERATIONS_DIR } from "@/config"; +import type { ToolContext, ToolResponse } from "./types"; +import { ProgressTracker } from "./utils/progress-tracker"; +import { + createStructuredError, + createStructuredErrorResponse, + createToolResponse, + type StructuredError +} from "./utils/response"; + +/** + * Input schema for build-widget tool. + */ +const buildWidgetSchema = z.object({ + widgetPath: z.string().describe("Absolute path to the widget directory (containing package.json)") +}); + +type BuildWidgetInput = z.infer; + +/** + * Parsed error with location information. + */ +interface ParsedError { + message: string; + file?: string; + line?: number; + column?: number; + tsCode?: string; // e.g., "TS2339" + category: "typescript" | "xml" | "dependency" | "unknown"; +} + +/** + * Result of parsing build output. + */ +interface BuildResult { + success: boolean; + mpkPath?: string; + errors: ParsedError[]; + warnings: string[]; + output: string; +} + +/** + * TypeScript error pattern: src/Component.tsx(42,5): error TS2339: Property 'x' does not exist + * Also matches: src/Component.tsx:42:5 - error TS2339: Property 'x' does not exist + */ +const TS_ERROR_PATTERN = /^(.+?)[:(](\d+)[,:](\d+)[):]?\s*[-:]?\s*error\s+(TS\d+):\s*(.+)$/; + +/** + * Simple TS error pattern: error TS2339: Property 'x' does not exist + */ +const TS_ERROR_SIMPLE_PATTERN = /^error\s+(TS\d+):\s*(.+)$/; + +/** + * XML error patterns + */ +const XML_ERROR_PATTERNS = [/XML.*error/i, /invalid.*xml/i, /schema.*validation.*failed/i, /widget\.xml.*error/i]; + +/** + * Dependency error patterns + */ +const DEP_ERROR_PATTERNS = [/cannot find module/i, /module not found/i, /npm ERR!/i, /ENOENT.*node_modules/i]; + +/** + * Parses a TypeScript error line to extract file, line, column, code, and message. + */ +function parseTypeScriptError(line: string): ParsedError | null { + // Try full pattern with file location + const fullMatch = line.match(TS_ERROR_PATTERN); + if (fullMatch) { + return { + file: fullMatch[1], + line: parseInt(fullMatch[2], 10), + column: parseInt(fullMatch[3], 10), + tsCode: fullMatch[4], + message: fullMatch[5], + category: "typescript" + }; + } + + // Try simple pattern without file location + const simpleMatch = line.match(TS_ERROR_SIMPLE_PATTERN); + if (simpleMatch) { + return { + tsCode: simpleMatch[1], + message: simpleMatch[2], + category: "typescript" + }; + } + + return null; +} + +/** + * Parses the build output to extract meaningful errors and warnings. + */ +function parseBuildOutput(stdout: string, stderr: string): BuildResult { + const output = stdout + "\n" + stderr; + const errors: ParsedError[] = []; + const warnings: string[] = []; + let mpkPath: string | undefined; + + const lines = output.split("\n"); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + + // TypeScript errors (try to parse with location) + if (trimmed.includes("error TS") || trimmed.match(/:\s*error\s+TS/)) { + const parsed = parseTypeScriptError(trimmed); + if (parsed) { + errors.push(parsed); + continue; + } + } + + // XML validation errors + if (XML_ERROR_PATTERNS.some(pattern => pattern.test(trimmed))) { + errors.push({ + message: trimmed, + category: "xml" + }); + continue; + } + + // Dependency errors + if (DEP_ERROR_PATTERNS.some(pattern => pattern.test(trimmed))) { + errors.push({ + message: trimmed, + category: "dependency" + }); + continue; + } + + // General errors (fallback) + if (trimmed.startsWith("error:") || trimmed.startsWith("Error:")) { + errors.push({ + message: trimmed.replace(/^[Ee]rror:\s*/, ""), + category: "unknown" + }); + continue; + } + + // Warnings + if (trimmed.startsWith("warning:") || trimmed.startsWith("Warning:")) { + warnings.push(trimmed); + } + + // MPK output path + if (trimmed.includes(".mpk")) { + const mpkMatch = trimmed.match(/([^\s]+\.mpk)/); + if (mpkMatch) { + mpkPath = mpkMatch[1]; + } + } + } + + // Check for success indicators + // pluggable-widgets-tools outputs "created dist/..." when successful + const hasCreatedOutput = output.includes("created dist/") || output.includes("created dist\\"); + const success = + errors.length === 0 && + (output.includes("Build completed") || output.includes("successfully") || hasCreatedOutput || mpkPath); + + return { + success: !!success, + mpkPath, + errors, + warnings, + output + }; +} + +/** + * Build progress phases for user-friendly messages. + */ +const BUILD_PHASES = { + START: { progress: 0, message: "Starting build process..." }, + VALIDATING: { progress: 20, message: "Validating widget XML schema..." }, + GENERATING_TYPES: { progress: 40, message: "Generating TypeScript types from XML..." }, + COMPILING: { progress: 60, message: "Compiling TypeScript..." }, + BUNDLING: { progress: 80, message: "Bundling widget..." }, + COMPLETE: { progress: 100, message: "Build complete!" } +} as const; + +/** + * Runs the build command and returns the result. + */ +async function runBuild(widgetPath: string, tracker?: ProgressTracker): Promise { + return new Promise(resolve => { + // Report start + tracker?.progress(BUILD_PHASES.START.progress, BUILD_PHASES.START.message); + + // Use npm run build to run pluggable-widgets-tools (correct package name) + const buildProcess = spawn("npm", ["run", "build"], { + cwd: widgetPath, + shell: true, + env: { + ...globalThis.process.env, + FORCE_COLOR: "0" // Disable colors for easier parsing + } + }); + + let stdout = ""; + let stderr = ""; + + buildProcess.stdout?.on("data", (data: Buffer) => { + const chunk = data.toString(); + stdout += chunk; + + // Update progress based on build output + if (tracker) { + if (chunk.includes("Validating") || chunk.includes("XML")) { + tracker.progress(BUILD_PHASES.VALIDATING.progress, BUILD_PHASES.VALIDATING.message); + tracker.updateStep("validating"); + } else if (chunk.includes("Generating") || chunk.includes("types")) { + tracker.progress(BUILD_PHASES.GENERATING_TYPES.progress, BUILD_PHASES.GENERATING_TYPES.message); + tracker.updateStep("generating-types"); + } else if (chunk.includes("Compiling") || chunk.includes("tsc")) { + tracker.progress(BUILD_PHASES.COMPILING.progress, BUILD_PHASES.COMPILING.message); + tracker.updateStep("compiling"); + } else if (chunk.includes("Bundling") || chunk.includes("rollup") || chunk.includes("webpack")) { + tracker.progress(BUILD_PHASES.BUNDLING.progress, BUILD_PHASES.BUNDLING.message); + tracker.updateStep("bundling"); + } + } + }); + + buildProcess.stderr?.on("data", (data: Buffer) => { + stderr += data.toString(); + }); + + buildProcess.on("close", code => { + const result = parseBuildOutput(stdout, stderr); + + // If exit code is non-zero and we didn't detect errors, add generic error + if (code !== 0 && result.errors.length === 0) { + result.errors.push({ + message: `Build failed with exit code ${code}`, + category: "unknown" + }); + result.success = false; + } + + // Report completion + if (tracker) { + if (result.success) { + tracker.progress(BUILD_PHASES.COMPLETE.progress, BUILD_PHASES.COMPLETE.message); + tracker.markComplete(); + } else { + tracker.error(`Build failed with ${result.errors.length} error(s)`); + } + } + + resolve(result); + }); + + buildProcess.on("error", err => { + tracker?.error(`Failed to start build: ${err.message}`); + resolve({ + success: false, + errors: [{ message: `Failed to start build process: ${err.message}`, category: "unknown" }], + warnings: [], + output: "" + }); + }); + }); +} + +/** + * Converts a parsed error to a structured error with suggestions. + */ +function toStructuredError(error: ParsedError): StructuredError { + const suggestions: Record = { + typescript: + "Check the TypeScript code at the specified location. Ensure props match the generated types from widget XML.", + xml: "Verify your widget.xml follows the Mendix schema. Check property types and required attributes.", + dependency: + "Run 'npm install' in the widget directory. If the issue persists, check that all dependencies are listed in package.json.", + unknown: "Review the build output for more details. Try running 'npx pluggable-widget-tools build' manually." + }; + + const codeMap: Record = { + typescript: "ERR_BUILD_TS", + xml: "ERR_BUILD_XML", + dependency: "ERR_BUILD_MISSING_DEP", + unknown: "ERR_BUILD_UNKNOWN" + }; + + return createStructuredError(codeMap[error.category], error.message, { + suggestion: suggestions[error.category], + file: error.file, + line: error.line, + column: error.column + }); +} + +/** + * Finds the most recently created MPK file in the widget's dist directory. + */ +function findMpkFile(widgetPath: string): string | undefined { + const distPath = join(widgetPath, "dist"); + if (!existsSync(distPath)) return undefined; + + try { + // Search for .mpk files recursively (usually in dist/x.x.x/) + const searchDir = (dir: string): string | undefined => { + const entries = readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + const found = searchDir(fullPath); + if (found) return found; + } else if (entry.name.endsWith(".mpk")) { + return fullPath; + } + } + return undefined; + }; + return searchDir(distPath); + } catch { + return undefined; + } +} + +/** + * Handler for the build-widget tool. + */ +async function handleBuildWidget(args: BuildWidgetInput, context: ToolContext): Promise { + const { widgetPath } = args; + + // Validate path exists + if (!existsSync(widgetPath)) { + return createStructuredErrorResponse( + createStructuredError("ERR_NOT_FOUND", `Widget directory not found: ${widgetPath}`, { + suggestion: "Verify the widget path is correct and the directory exists." + }) + ); + } + + // Validate path is within allowed directories + const resolvedWidgetPath = resolve(widgetPath); + const allowedBuildPaths = [ + resolve(GENERATIONS_DIR), + ...(process.env.MCP_ALLOWED_BUILD_PATHS ?? "") + .split(":") + .filter(Boolean) + .map(p => resolve(p)) + ]; + const isAllowedPath = allowedBuildPaths.some( + allowed => resolvedWidgetPath.startsWith(allowed + "/") || resolvedWidgetPath === allowed + ); + if (!isAllowedPath) { + return createStructuredErrorResponse( + createStructuredError("ERR_NOT_FOUND", `Widget path is not within an allowed directory: ${widgetPath}`, { + suggestion: `Widget must be within ${GENERATIONS_DIR} or set MCP_ALLOWED_BUILD_PATHS env var (colon-separated paths).` + }) + ); + } + + // Check for package.json + const packageJsonPath = join(widgetPath, "package.json"); + if (!existsSync(packageJsonPath)) { + return createStructuredErrorResponse( + createStructuredError("ERR_NOT_FOUND", `No package.json found in ${widgetPath}`, { + suggestion: "Ensure this is a valid widget directory created with create-widget tool." + }) + ); + } + + // Create progress tracker + const tracker = new ProgressTracker({ + context, + logger: "build", + totalSteps: 5 // 5 phases: start, validate, generate, compile, bundle + }); + + tracker.start("initializing"); + + try { + // Run build with progress tracking + const result = await runBuild(widgetPath, tracker); + + // Try to find MPK file if not already detected + const mpkPath = result.mpkPath || findMpkFile(widgetPath); + + if (result.success) { + let message = `✅ Build successful!`; + + if (mpkPath) { + message += `\n\n📦 MPK output: ${mpkPath}`; + } + + if (result.warnings.length > 0) { + message += `\n\n⚠️ Warnings:\n${result.warnings.map(w => ` - ${w}`).join("\n")}`; + } + + return createToolResponse(message); + } else { + // Return first error as structured error (most relevant) + if (result.errors.length > 0) { + const primaryError = toStructuredError(result.errors[0]); + + // Add additional errors to raw output if multiple + if (result.errors.length > 1) { + const additionalErrors = result.errors + .slice(1) + .map(e => { + const loc = e.file ? `${e.file}${e.line ? `:${e.line}` : ""}` : ""; + return loc ? `[${loc}] ${e.message}` : e.message; + }) + .join("\n"); + + primaryError.details = { + ...primaryError.details, + rawOutput: `Additional errors (${result.errors.length - 1}):\n${additionalErrors}` + }; + } + + return createStructuredErrorResponse(primaryError); + } + + // Fallback for unknown failures + return createStructuredErrorResponse( + createStructuredError("ERR_BUILD_UNKNOWN", "Build failed with unknown error", { + suggestion: "Check the raw build output for details.", + rawOutput: result.output.slice(0, 1000) + }) + ); + } + } finally { + tracker.stop(); + } +} + +/** + * Registers the build tools with the MCP server. + */ +export function registerBuildTools(server: McpServer): void { + server.registerTool( + "build-widget", + { + title: "Build Widget", + description: + "Builds a Mendix pluggable widget using pluggable-widget-tools. " + + "Validates XML, compiles TypeScript, generates types, and produces an .mpk file. " + + "Returns build errors if any, which can be used to fix issues.", + inputSchema: buildWidgetSchema + }, + handleBuildWidget + ); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/code-generation.tools.ts b/packages/pluggable-widgets-mcp/src/tools/code-generation.tools.ts new file mode 100644 index 0000000000..7d39394228 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/code-generation.tools.ts @@ -0,0 +1,485 @@ +/** + * Code Generation Tools for Mendix Pluggable Widgets. + * + * Provides the `generate-widget-code` tool that transforms widget descriptions + * and property definitions into working XML and TSX code. + */ + +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { mkdir, stat, writeFile } from "node:fs/promises"; +import { basename, dirname, join } from "node:path"; +import { z } from "zod"; +import { generateWidgetXml, validateWidgetDefinition } from "@/generators/xml-generator"; +import { detectWidgetPattern, generateWidgetTsx, type WidgetPattern } from "@/generators/tsx-generator"; +import type { PropertyDefinition, WidgetDefinition } from "@/generators/types"; +import { validateFilePath } from "@/security"; +import type { ToolResponse } from "@/tools/types"; +import { createErrorResponse, createToolResponse } from "@/tools/utils/response"; + +// ============================================================================= +// Schemas +// ============================================================================= + +/** + * Schema for enumeration values. + */ +const enumValueSchema = z.object({ + key: z.string().min(1).describe("Unique identifier for this enum value"), + caption: z.string().min(1).describe("Display caption shown in Studio Pro") +}); + +/** + * Schema for property definitions. + * Matches the PropertyDefinition type from generators/types.ts + */ +const propertyDefinitionSchema = z.object({ + key: z + .string() + .min(1) + .regex(/^[a-z][a-zA-Z0-9]*$/, "Must be camelCase (e.g., 'myProperty')") + .describe("Property key in camelCase"), + type: z + .enum([ + "string", + "boolean", + "integer", + "decimal", + "textTemplate", + "expression", + "action", + "attribute", + "datasource", + "association", + "selection", + "enumeration", + "icon", + "image", + "file", + "widgets", + "object" + ]) + .describe("Mendix property type"), + caption: z.string().min(1).describe("Display caption shown in Studio Pro"), + description: z.string().optional().describe("Help text shown in Studio Pro"), + required: z.boolean().optional().describe("Whether this property is required"), + defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional().describe("Default value for this property"), + enumValues: z.array(enumValueSchema).optional().describe("Allowed values for enumeration type"), + attributeTypes: z + .array( + z.enum([ + "String", + "Integer", + "Long", + "Decimal", + "Boolean", + "DateTime", + "Enum", + "HashString", + "Binary", + "AutoNumber" + ]) + ) + .optional() + .describe("Allowed attribute types for attribute property"), + isList: z.boolean().optional().describe("Whether datasource returns a list"), + dataSource: z.string().optional().describe("Reference to datasource property key (for widgets type)"), + returnType: z + .enum(["String", "Integer", "Decimal", "Boolean", "DateTime"]) + .optional() + .describe("Return type for expression property") +}); + +/** + * Schema for property group definitions. + */ +const propertyGroupSchema = z.object({ + caption: z.string().min(1).describe("Group caption displayed in Studio Pro"), + properties: z.array(z.string().min(1)).min(1).describe("Property keys in this group") +}); + +/** + * Schema for the generate-widget-code tool input. + */ +const generateWidgetCodeSchema = z.object({ + widgetPath: z.string().min(1).describe("Absolute path to the scaffolded widget directory"), + description: z.string().min(1).describe("Description of what the widget should do"), + properties: z + .array(propertyDefinitionSchema) + .optional() + .describe("Array of property definitions. If not provided, returns suggestions."), + widgetPattern: z + .enum(["display", "button", "input", "container", "dataList"]) + .optional() + .describe("Optional hint for TSX generation pattern"), + systemProperties: z + .array(z.enum(["Name", "TabIndex", "Visibility"])) + .optional() + .describe( + 'System properties to include. Defaults to ["Name", "TabIndex", "Visibility"]. Pass empty array to include none.' + ), + propertyGroups: z + .array(propertyGroupSchema) + .optional() + .describe( + "Optional property grouping. If not provided, non-action properties go in 'General' and action properties go in 'Events' automatically." + ) +}); + +type GenerateWidgetCodeInput = z.infer; + +// ============================================================================= +// Helper Functions +// ============================================================================= + +/** + * Extracts widget name from path (e.g., /path/to/MyWidget -> MyWidget) + */ +function extractWidgetName(widgetPath: string): string { + const base = basename(widgetPath); + // Convert to PascalCase if needed + return base.charAt(0).toUpperCase() + base.slice(1); +} + +/** + * Generates property suggestions based on widget description. + */ +function generatePropertySuggestions(description: string): string { + const descLower = description.toLowerCase(); + + // Common patterns to suggest + const suggestions: Array<{ + key: string; + type: string; + caption: string; + purpose: string; + }> = []; + + // Counter-like widgets + if (descLower.includes("counter") || descLower.includes("count") || descLower.includes("increment")) { + suggestions.push( + { + key: "value", + type: "attribute", + caption: "Value", + purpose: "Current counter value (bind to Integer attribute)" + }, + { key: "step", type: "integer", caption: "Step", purpose: "Amount to increment/decrement (default: 1)" }, + { key: "minValue", type: "integer", caption: "Minimum", purpose: "Lower bound (optional)" }, + { key: "maxValue", type: "integer", caption: "Maximum", purpose: "Upper bound (optional)" }, + { key: "onIncrement", type: "action", caption: "On Increment", purpose: "Action when value increases" }, + { key: "onDecrement", type: "action", caption: "On Decrement", purpose: "Action when value decreases" } + ); + } + + // Display/badge-like widgets + if ( + descLower.includes("display") || + descLower.includes("show") || + descLower.includes("badge") || + descLower.includes("label") + ) { + suggestions.push( + { key: "value", type: "textTemplate", caption: "Value", purpose: "Text to display" }, + { key: "type", type: "enumeration", caption: "Style", purpose: "Visual style variant" }, + { key: "onClick", type: "action", caption: "On Click", purpose: "Action when clicked" } + ); + } + + // Button-like widgets + if (descLower.includes("button") || descLower.includes("click") || descLower.includes("trigger")) { + suggestions.push( + { key: "caption", type: "textTemplate", caption: "Caption", purpose: "Button text" }, + { key: "icon", type: "icon", caption: "Icon", purpose: "Button icon (optional)" }, + { key: "buttonStyle", type: "enumeration", caption: "Style", purpose: "Button appearance variant" }, + { key: "onClick", type: "action", caption: "On Click", purpose: "Action when clicked" } + ); + } + + // Input-like widgets + if ( + descLower.includes("input") || + descLower.includes("edit") || + descLower.includes("enter") || + descLower.includes("form") + ) { + suggestions.push( + { key: "value", type: "attribute", caption: "Value", purpose: "Bound attribute for data entry" }, + { key: "placeholder", type: "textTemplate", caption: "Placeholder", purpose: "Hint text when empty" }, + { key: "onChange", type: "action", caption: "On Change", purpose: "Action when value changes" }, + { key: "onEnter", type: "action", caption: "On Enter", purpose: "Action when Enter key pressed" } + ); + } + + // List-like widgets + if ( + descLower.includes("list") || + descLower.includes("items") || + descLower.includes("collection") || + descLower.includes("data") + ) { + suggestions.push( + { key: "dataSource", type: "datasource", caption: "Data Source", purpose: "Source of items to display" }, + { key: "content", type: "widgets", caption: "Content", purpose: "Template for each item" }, + { key: "emptyMessage", type: "textTemplate", caption: "Empty Message", purpose: "Text when no items" }, + { key: "onItemClick", type: "action", caption: "On Item Click", purpose: "Action when item clicked" } + ); + } + + // Container-like widgets + if ( + descLower.includes("container") || + descLower.includes("card") || + descLower.includes("panel") || + descLower.includes("section") + ) { + suggestions.push( + { key: "content", type: "widgets", caption: "Content", purpose: "Child widgets" }, + { key: "header", type: "textTemplate", caption: "Header", purpose: "Container title" }, + { key: "collapsible", type: "boolean", caption: "Collapsible", purpose: "Allow expand/collapse" } + ); + } + + // Default suggestions if nothing matched + if (suggestions.length === 0) { + suggestions.push( + { key: "value", type: "textTemplate", caption: "Value", purpose: "Main display value" }, + { key: "onClick", type: "action", caption: "On Click", purpose: "Action when clicked" } + ); + } + + // Detect pattern from suggestions + let suggestedPattern: WidgetPattern = "display"; + const types = suggestions.map(s => s.type); + if (types.includes("datasource") && types.includes("widgets")) { + suggestedPattern = "dataList"; + } else if (types.includes("widgets")) { + suggestedPattern = "container"; + } else if (types.includes("attribute")) { + suggestedPattern = "input"; + } else if (suggestions.length <= 4 && types.includes("action")) { + suggestedPattern = "button"; + } + + // Build markdown table + const table = [ + "| Property | Type | Caption | Purpose |", + "|----------|------|---------|---------|", + ...suggestions.map(s => `| ${s.key} | ${s.type} | ${s.caption} | ${s.purpose} |`) + ].join("\n"); + + return `📋 Widget requirements analysis needed + +Based on your description "${description}", suggested properties: + +${table} + +Suggested pattern: **${suggestedPattern}** (${getPatternDescription(suggestedPattern)}) + +Please call generate-widget-code again with the properties array to generate the widget code. + +Example: +\`\`\`json +{ + "widgetPath": "", + "description": "${description}", + "properties": [ + { "key": "value", "type": "textTemplate", "caption": "Value" }, + { "key": "onClick", "type": "action", "caption": "On Click" } + ] +} +\`\`\``; +} + +/** + * Returns a human-readable description of a widget pattern. + */ +function getPatternDescription(pattern: WidgetPattern): string { + switch (pattern) { + case "display": + return "read-only data display"; + case "button": + return "action trigger with click handler"; + case "input": + return "data entry with attribute binding"; + case "container": + return "holds child widgets"; + case "dataList": + return "renders items from datasource"; + default: + return "general purpose"; + } +} + +// ============================================================================= +// Tool Handler +// ============================================================================= + +async function handleGenerateWidgetCode(args: GenerateWidgetCodeInput): Promise { + const { widgetPath, description, properties, widgetPattern } = args; + + try { + // Verify widget directory exists + const pathStats = await stat(widgetPath); + if (!pathStats.isDirectory()) { + return createErrorResponse(`Widget path is not a directory: ${widgetPath}`); + } + + // If no properties provided, return suggestions + if (!properties || properties.length === 0) { + console.error(`[code-generation] No properties provided, returning suggestions`); + return createToolResponse(generatePropertySuggestions(description)); + } + + // Extract widget name from path + const widgetName = extractWidgetName(widgetPath); + + console.error(`[code-generation] Generating code for ${widgetName} with ${properties.length} properties`); + + // Build widget definition for XML generator + const widgetDefinition: WidgetDefinition = { + name: widgetName, + description, + properties: properties as PropertyDefinition[], + systemProperties: args.systemProperties ?? ["Name", "TabIndex", "Visibility"], + propertyGroups: args.propertyGroups + }; + + // Validate widget definition + const validationErrors = validateWidgetDefinition(widgetDefinition); + if (validationErrors.length > 0) { + return createErrorResponse( + [ + "❌ Widget definition validation failed:", + "", + ...validationErrors.map(e => ` • ${e}`), + "", + "Please fix the above issues and try again." + ].join("\n") + ); + } + + // Generate XML + console.error(`[code-generation] Generating XML...`); + const xmlResult = generateWidgetXml(widgetDefinition); + if (!xmlResult.success || !xmlResult.xml) { + return createErrorResponse(`XML generation failed: ${xmlResult.error}`); + } + + // Detect or use provided pattern + const pattern = widgetPattern ?? detectWidgetPattern(properties as PropertyDefinition[]); + console.error(`[code-generation] Using pattern: ${pattern}`); + + // Generate TSX + console.error(`[code-generation] Generating TSX...`); + const tsxResult = generateWidgetTsx(widgetName, properties as PropertyDefinition[], pattern); + if (!tsxResult.success || !tsxResult.mainComponent) { + return createErrorResponse(`TSX generation failed: ${tsxResult.error}`); + } + + // Prepare files to write + const filesToWrite = [ + { path: `src/${widgetName}.xml`, content: xmlResult.xml }, + { path: `src/${widgetName}.tsx`, content: tsxResult.mainComponent }, + { path: `src/ui/${widgetName}.scss`, content: `.widget-${widgetName.toLowerCase()} {\n}\n` }, + { path: `src/.widget-definition.json`, content: JSON.stringify(widgetDefinition, null, 2) } + ]; + + // Validate and write files + const writtenFiles: string[] = []; + for (const file of filesToWrite) { + try { + validateFilePath(widgetPath, file.path, true); + const fullPath = join(widgetPath, file.path); + + // Ensure parent directory exists + const parentDir = dirname(fullPath); + await mkdir(parentDir, { recursive: true }); + + // Write file + await writeFile(fullPath, file.content, "utf-8"); + writtenFiles.push(file.path); + console.error(`[code-generation] Wrote: ${fullPath}`); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return createErrorResponse(`Failed to write ${file.path}: ${message}`); + } + } + + // Build success response + const propSummary = properties.map(p => p.key).join(", "); + + return createToolResponse( + [ + `✅ Widget code generated successfully!`, + "", + `📁 Files written:`, + ` • src/${widgetName}.xml - Widget definition with ${properties.length} properties (${propSummary})`, + ` • src/${widgetName}.tsx - Component using ${pattern} pattern`, + ` • src/ui/${widgetName}.scss - Empty SCSS placeholder`, + ` • src/.widget-definition.json - Widget definition snapshot (used by update-widget-properties)`, + "", + `🔨 Next steps:`, + ` 1. Run build-widget to compile and validate`, + ` 2. Review and customize generated code`, + ` 3. Update src/${widgetName}.editorPreview.tsx for Studio Pro design mode preview`, + ` 4. Test in Mendix Studio Pro` + ].join("\n") + ); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(`[code-generation] Error: ${message}`); + return createErrorResponse(`Widget code generation failed: ${message}`); + } +} + +// ============================================================================= +// Tool Registration +// ============================================================================= + +const GENERATE_WIDGET_CODE_DESCRIPTION = `Generates XML properties and TSX component code for a Mendix pluggable widget. + +**Usage:** + +1. **With properties (generates code):** + Provide widgetPath, description, and properties array to generate XML + TSX files. + +2. **Without properties (gets suggestions):** + Provide only widgetPath and description to receive suggested properties based on your description. + +**Supported property types:** +- Basic: string, boolean, integer, decimal +- Dynamic: textTemplate, expression +- Interactive: action, attribute (for data binding) +- Complex: datasource, widgets (for containers/lists), enumeration + +**Pattern detection:** +The tool automatically detects the appropriate widget pattern (display, button, input, container, dataList) based on property types, or you can specify it explicitly. + +**Example - Counter widget:** +\`\`\`json +{ + "widgetPath": "/path/to/CounterWidget", + "description": "A counter that increments and decrements", + "properties": [ + { "key": "value", "type": "attribute", "caption": "Value", "attributeTypes": ["Integer"] }, + { "key": "onIncrement", "type": "action", "caption": "On Increment" } + ] +} +\`\`\``; + +/** + * Registers code generation tools for creating widget XML and TSX. + */ +export function registerCodeGenerationTools(server: McpServer): void { + server.registerTool( + "generate-widget-code", + { + title: "Generate Widget Code", + description: GENERATE_WIDGET_CODE_DESCRIPTION, + inputSchema: generateWidgetCodeSchema + }, + handleGenerateWidgetCode + ); + + console.error("[code-generation] Registered 1 tool"); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/file-operations.tools.ts b/packages/pluggable-widgets-mcp/src/tools/file-operations.tools.ts new file mode 100644 index 0000000000..b3aec8856d --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/file-operations.tools.ts @@ -0,0 +1,284 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises"; +import { dirname, extname, join } from "node:path"; +import { z } from "zod"; +import { ALLOWED_EXTENSIONS, validateFilePath } from "@/security"; +import type { ToolResponse } from "@/tools/types"; +import { createErrorResponse, createToolResponse } from "@/tools/utils/response"; + +// ============================================================================= +// Schemas +// ============================================================================= + +const listWidgetFilesSchema = z.object({ + widgetPath: z.string().min(1).describe("Absolute path to the widget directory (returned by create-widget tool)") +}); + +const readWidgetFileSchema = z.object({ + widgetPath: z.string().min(1).describe("Absolute path to the widget directory"), + filePath: z + .string() + .min(1) + .describe("Relative path to the file within the widget directory (e.g., 'src/MyWidget.tsx')") +}); + +const writeWidgetFileSchema = z + .object({ + widgetPath: z.string().min(1).describe("Absolute path to the widget directory"), + // Single file mode + filePath: z + .string() + .optional() + .describe("Relative path to the file (single file mode, e.g., 'src/components/MyComponent.tsx')"), + content: z.string().optional().describe("File content (single file mode)"), + // Batch mode + files: z + .array( + z.object({ + relativePath: z.string().min(1).describe("Relative path within the widget directory"), + content: z.string().describe("File content to write") + }) + ) + .optional() + .describe("Array of files to write (batch mode)") + }) + .refine( + data => + (data.filePath !== undefined && data.content !== undefined) || + (data.files !== undefined && data.files.length > 0), + { message: "Either provide (filePath + content) for single file mode, or files array for batch mode" } + ); + +type ListWidgetFilesInput = z.infer; +type ReadWidgetFileInput = z.infer; +type WriteWidgetFileInput = z.infer; + +// ============================================================================= +// Tool Handlers +// ============================================================================= + +/** + * Recursively lists all files in a directory. + */ +async function listFilesRecursive( + dir: string, + basePath: string, + files: Array<{ path: string; type: string }> = [] +): Promise> { + const entries = await readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = join(dir, entry.name); + const relativePath = fullPath.replace(basePath + "/", ""); + + if (entry.isDirectory()) { + // Skip node_modules and other common non-source directories + if (["node_modules", ".git", "dist", "build"].includes(entry.name)) { + continue; + } + await listFilesRecursive(fullPath, basePath, files); + } else { + const ext = extname(entry.name).toLowerCase(); + files.push({ + path: relativePath, + type: ext || "file" + }); + } + } + + return files; +} + +async function handleListWidgetFiles(args: ListWidgetFilesInput): Promise { + try { + // Verify the directory exists + const stats = await stat(args.widgetPath); + if (!stats.isDirectory()) { + return createErrorResponse(`Path is not a directory: ${args.widgetPath}`); + } + + const files = await listFilesRecursive(args.widgetPath, args.widgetPath); + + // Group files by type for better readability + const byType = files.reduce>((acc, file) => { + const type = file.type || "other"; + if (!acc[type]) acc[type] = []; + acc[type].push(file.path); + return acc; + }, {}); + + const output = [`Widget files in ${args.widgetPath}:`, "", `Total: ${files.length} files`, ""]; + + // Sort types for consistent output + const sortedTypes = Object.keys(byType).sort(); + for (const type of sortedTypes) { + output.push(`${type} files (${byType[type].length}):`); + for (const path of byType[type].sort()) { + output.push(` - ${path}`); + } + output.push(""); + } + + return createToolResponse(output.join("\n")); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return createErrorResponse(`Failed to list widget files: ${message}`); + } +} + +async function handleReadWidgetFile(args: ReadWidgetFileInput): Promise { + try { + validateFilePath(args.widgetPath, args.filePath); + + const fullPath = join(args.widgetPath, args.filePath); + const content = await readFile(fullPath, "utf-8"); + + return createToolResponse( + [`File: ${args.filePath}`, `Path: ${fullPath}`, "", "Content:", "```", content, "```"].join("\n") + ); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return createErrorResponse(`Failed to read file: ${message}`); + } +} + +async function handleWriteWidgetFile(args: WriteWidgetFileInput): Promise { + // Normalize to array: single file mode → wrap in array; batch mode → use directly + const filesToWrite = + args.filePath !== undefined && args.content !== undefined + ? [{ relativePath: args.filePath, content: args.content }] + : (args.files ?? []); + + const results: Array<{ path: string; success: boolean; error?: string }> = []; + + // Validate all paths first before writing anything + for (const file of filesToWrite) { + try { + validateFilePath(args.widgetPath, file.relativePath, true); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return createErrorResponse(`Validation failed for ${file.relativePath}: ${message}`); + } + } + + // Write all files + for (const file of filesToWrite) { + try { + const fullPath = join(args.widgetPath, file.relativePath); + + // Ensure parent directory exists + const parentDir = dirname(fullPath); + await mkdir(parentDir, { recursive: true }); + + // Write the file + await writeFile(fullPath, file.content, "utf-8"); + + console.error(`[file-operations] Wrote file: ${fullPath}`); + results.push({ path: file.relativePath, success: true }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + results.push({ path: file.relativePath, success: false, error: message }); + } + } + + const successful = results.filter(r => r.success); + const failed = results.filter(r => !r.success); + + if (failed.length === 0) { + return createToolResponse( + [`Successfully wrote ${successful.length} file(s):`, "", ...successful.map(r => ` - ${r.path}`)].join("\n") + ); + } else if (successful.length === 0) { + return createErrorResponse( + [`Failed to write all ${failed.length} file(s):`, "", ...failed.map(r => ` - ${r.path}: ${r.error}`)].join( + "\n" + ) + ); + } else { + return createToolResponse( + [ + `Partial success: ${successful.length} written, ${failed.length} failed`, + "", + "Written:", + ...successful.map(r => ` - ${r.path}`), + "", + "Failed:", + ...failed.map(r => ` - ${r.path}: ${r.error}`) + ].join("\n") + ); + } +} + +// ============================================================================= +// Tool Definitions +// ============================================================================= + +const LIST_WIDGET_FILES_DESCRIPTION = `Lists all files in a widget directory. + +Use this tool after scaffolding a widget to understand its structure. +Returns files grouped by type (.tsx, .xml, .scss, etc.). + +Excludes: node_modules, .git, dist, build directories.`; + +const READ_WIDGET_FILE_DESCRIPTION = `Reads the contents of a file from a widget directory. + +Use this to inspect existing code before making modifications. +The file path should be relative to the widget directory. + +Examples: + - src/MyWidget.tsx (main component) + - src/MyWidget.xml (properties definition) + - src/components/Header.tsx (sub-component)`; + +const WRITE_WIDGET_FILE_DESCRIPTION = `Writes one or more files to a widget directory. + +**Single file mode:** provide filePath + content. +**Batch mode:** provide files array (each with relativePath + content). + +Validates all paths before writing. Creates parent directories if needed. + +IMPORTANT: Follow Mendix widget development guidelines: + - Use TypeScript and React + - Follow Atlas UI styling conventions + - Use proper Mendix API types (EditableValue, ActionValue, etc.) + - Fetch mendix://guidelines/* resources for detailed instructions + +Allowed file types: ${ALLOWED_EXTENSIONS.join(", ")}`; + +/** + * Registers file operation tools for reading and writing widget files. + * + * These tools enable LLMs to implement widget functionality after scaffolding + * by reading existing code and writing new/updated files. + */ +export function registerFileOperationTools(server: McpServer): void { + server.registerTool( + "list-widget-files", + { + title: "List Widget Files", + description: LIST_WIDGET_FILES_DESCRIPTION, + inputSchema: listWidgetFilesSchema + }, + handleListWidgetFiles + ); + + server.registerTool( + "read-widget-file", + { + title: "Read Widget File", + description: READ_WIDGET_FILE_DESCRIPTION, + inputSchema: readWidgetFileSchema + }, + handleReadWidgetFile + ); + + server.registerTool( + "write-widget-file", + { + title: "Write Widget File", + description: WRITE_WIDGET_FILE_DESCRIPTION, + inputSchema: writeWidgetFileSchema + }, + handleWriteWidgetFile + ); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/index.ts b/packages/pluggable-widgets-mcp/src/tools/index.ts new file mode 100644 index 0000000000..0941d00c7c --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/index.ts @@ -0,0 +1,27 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { registerBuildTools } from "./build.tools"; +import { registerCodeGenerationTools } from "./code-generation.tools"; +import { registerFileOperationTools } from "./file-operations.tools"; +import { registerPropertyUpdateTools } from "./property-update.tools"; +import { registerScaffoldingTools } from "./scaffolding.tools"; + +/** + * Registers all tools with the MCP server. + * + * Tools are organized by category: + * - Scaffolding: Widget creation (create-widget) + * - File Operations: Read/write widget files (list-widget-files, read-widget-file, write-widget-file) + * - Build: Widget building and validation (build-widget) + * - Code Generation: Generate widget XML and TSX (generate-widget-code) + * - Property Update: Incremental property updates (update-widget-properties) + * + * Each category registers its tools directly with the server, preserving + * full type safety through the SDK's generic inference. + */ +export function registerAllTools(server: McpServer): void { + registerScaffoldingTools(server); + registerFileOperationTools(server); + registerBuildTools(server); + registerCodeGenerationTools(server); + registerPropertyUpdateTools(server); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/property-update.tools.ts b/packages/pluggable-widgets-mcp/src/tools/property-update.tools.ts new file mode 100644 index 0000000000..79e7704318 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/property-update.tools.ts @@ -0,0 +1,303 @@ +/** + * Property Update Tool for Mendix Pluggable Widgets. + * + * Provides the `update-widget-properties` tool that incrementally modifies + * widget property definitions without full regeneration. + */ + +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { readFile, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { z } from "zod"; +import { generateWidgetXml, validateWidgetDefinition } from "@/generators/xml-generator"; +import type { PropertyDefinition, PropertyGroup, SystemProperty, WidgetDefinition } from "@/generators/types"; +import { validateFilePath } from "@/security"; +import type { ToolResponse } from "@/tools/types"; +import { createErrorResponse, createToolResponse } from "@/tools/utils/response"; + +// ============================================================================= +// Schemas +// ============================================================================= + +/** + * Schema for a single property definition (reuse same structure as code-generation.tools.ts). + */ +const propertyDefinitionSchema = z.object({ + key: z + .string() + .min(1) + .regex(/^[a-z][a-zA-Z0-9]*$/, "Must be camelCase (e.g., 'myProperty')") + .describe("Property key in camelCase"), + type: z + .enum([ + "string", + "boolean", + "integer", + "decimal", + "textTemplate", + "expression", + "action", + "attribute", + "datasource", + "association", + "selection", + "enumeration", + "icon", + "image", + "file", + "widgets", + "object" + ]) + .describe("Mendix property type"), + caption: z.string().min(1).describe("Display caption shown in Studio Pro"), + description: z.string().optional().describe("Help text shown in Studio Pro"), + required: z.boolean().optional().describe("Whether this property is required"), + defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional().describe("Default value for this property"), + enumValues: z + .array(z.object({ key: z.string().min(1), caption: z.string().min(1) })) + .optional() + .describe("Allowed values for enumeration type"), + attributeTypes: z + .array( + z.enum([ + "String", + "Integer", + "Long", + "Decimal", + "Boolean", + "DateTime", + "Enum", + "HashString", + "Binary", + "AutoNumber" + ]) + ) + .optional() + .describe("Allowed attribute types for attribute property"), + isList: z.boolean().optional().describe("Whether datasource returns a list"), + dataSource: z.string().optional().describe("Reference to datasource property key (for widgets type)"), + returnType: z + .enum(["String", "Integer", "Decimal", "Boolean", "DateTime"]) + .optional() + .describe("Return type for expression property") +}); + +const operationSchema = z.discriminatedUnion("action", [ + z.object({ + action: z.literal("add"), + property: propertyDefinitionSchema.describe("Property definition to add") + }), + z.object({ + action: z.literal("remove"), + propertyKey: z.string().min(1).describe("Key of the property to remove") + }), + z.object({ + action: z.literal("modify"), + propertyKey: z.string().min(1).describe("Key of the property to modify"), + updates: z.record(z.string(), z.unknown()).describe("Fields to merge into the existing property definition") + }) +]); + +const updateWidgetPropertiesSchema = z.object({ + widgetPath: z.string().min(1).describe("Absolute path to the widget directory"), + operations: z + .array(operationSchema) + .min(1) + .describe("List of operations to apply sequentially (add/remove/modify)"), + systemProperties: z + .array(z.enum(["Name", "TabIndex", "Visibility"])) + .optional() + .describe("Replaces current system properties if provided"), + propertyGroups: z + .array( + z.object({ + caption: z.string().min(1).describe("Group caption"), + properties: z.array(z.string().min(1)).min(1).describe("Property keys in this group") + }) + ) + .optional() + .describe("Replaces current property groups if provided") +}); + +type UpdateWidgetPropertiesInput = z.infer; + +// ============================================================================= +// Tool Handler +// ============================================================================= + +async function handleUpdateWidgetProperties(args: UpdateWidgetPropertiesInput): Promise { + const { widgetPath, operations, systemProperties, propertyGroups } = args; + + try { + // Read the widget definition snapshot + const snapshotPath = "src/.widget-definition.json"; + let widgetDefinition: WidgetDefinition; + + try { + validateFilePath(widgetPath, snapshotPath); + const fullSnapshotPath = join(widgetPath, snapshotPath); + const raw = await readFile(fullSnapshotPath, "utf-8"); + widgetDefinition = JSON.parse(raw) as WidgetDefinition; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + if (message.includes("ENOENT") || message.includes("no such file")) { + return createErrorResponse( + [ + `❌ Widget definition snapshot not found at ${widgetPath}/src/.widget-definition.json`, + "", + "The snapshot is created by the generate-widget-code tool. Please run it first to generate the initial widget code.", + "", + "Example: call generate-widget-code with your widgetPath, description, and properties." + ].join("\n") + ); + } + return createErrorResponse(`Failed to read widget definition: ${message}`); + } + + // Apply operations sequentially + const changeLog: string[] = []; + + for (const op of operations) { + if (op.action === "add") { + const existing = widgetDefinition.properties.find(p => p.key === op.property.key); + if (existing) { + return createErrorResponse( + `Cannot add property: key "${op.property.key}" already exists. Use action "modify" to update it.` + ); + } + widgetDefinition.properties.push(op.property as PropertyDefinition); + changeLog.push(`+ Added property "${op.property.key}" (${op.property.type})`); + } else if (op.action === "remove") { + const idx = widgetDefinition.properties.findIndex(p => p.key === op.propertyKey); + if (idx === -1) { + return createErrorResponse(`Cannot remove property: key "${op.propertyKey}" not found.`); + } + widgetDefinition.properties.splice(idx, 1); + changeLog.push(`- Removed property "${op.propertyKey}"`); + } else if (op.action === "modify") { + const prop = widgetDefinition.properties.find(p => p.key === op.propertyKey); + if (!prop) { + return createErrorResponse(`Cannot modify property: key "${op.propertyKey}" not found.`); + } + Object.assign(prop, op.updates); + changeLog.push(`~ Modified property "${op.propertyKey}": ${Object.keys(op.updates).join(", ")}`); + } + } + + // Replace systemProperties / propertyGroups if provided + if (systemProperties !== undefined) { + widgetDefinition.systemProperties = systemProperties as SystemProperty[]; + changeLog.push(`~ Updated systemProperties: [${systemProperties.join(", ")}]`); + } + + if (propertyGroups !== undefined) { + widgetDefinition.propertyGroups = propertyGroups as PropertyGroup[]; + changeLog.push(`~ Updated propertyGroups (${propertyGroups.length} groups)`); + } + + // Validate updated definition + const validationErrors = validateWidgetDefinition(widgetDefinition); + if (validationErrors.length > 0) { + return createErrorResponse( + [ + "❌ Updated widget definition is invalid:", + "", + ...validationErrors.map(e => ` • ${e}`), + "", + "Please fix the above issues. Operations were NOT saved." + ].join("\n") + ); + } + + // Regenerate XML + const xmlResult = generateWidgetXml(widgetDefinition); + if (!xmlResult.success || !xmlResult.xml) { + return createErrorResponse(`XML regeneration failed: ${xmlResult.error}`); + } + + // Write updated XML and snapshot + const xmlPath = `src/${widgetDefinition.name}.xml`; + const filesToWrite = [ + { path: xmlPath, content: xmlResult.xml }, + { path: snapshotPath, content: JSON.stringify(widgetDefinition, null, 2) } + ]; + + for (const file of filesToWrite) { + try { + validateFilePath(widgetPath, file.path, true); + const fullPath = join(widgetPath, file.path); + await writeFile(fullPath, file.content, "utf-8"); + console.error(`[property-update] Wrote: ${fullPath}`); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return createErrorResponse(`Failed to write ${file.path}: ${message}`); + } + } + + return createToolResponse( + [ + `✅ Widget properties updated successfully!`, + "", + `📝 Changes applied (${changeLog.length}):`, + ...changeLog.map(c => ` ${c}`), + "", + `📁 Files updated:`, + ` • ${xmlPath} - Regenerated with ${widgetDefinition.properties.length} properties`, + ` • ${snapshotPath} - Snapshot updated`, + "", + `🔨 Next steps:`, + ` 1. Run build-widget to compile and validate`, + ` 2. Update src/${widgetDefinition.name}.tsx if new properties need to be wired up` + ].join("\n") + ); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(`[property-update] Error: ${message}`); + return createErrorResponse(`Widget property update failed: ${message}`); + } +} + +// ============================================================================= +// Tool Registration +// ============================================================================= + +const UPDATE_WIDGET_PROPERTIES_DESCRIPTION = `Incrementally updates widget properties without full regeneration. + +Reads the widget definition snapshot (src/.widget-definition.json created by generate-widget-code), +applies the specified operations, validates the result, and regenerates the XML. + +**Operations:** +- \`add\`: Add a new property +- \`remove\`: Remove an existing property by key +- \`modify\`: Merge updates into an existing property + +**Prerequisites:** +- Widget must have been generated with generate-widget-code first (creates the snapshot) + +**Example — add a property and remove another:** +\`\`\`json +{ + "widgetPath": "/path/to/MyWidget", + "operations": [ + { "action": "add", "property": { "key": "label", "type": "textTemplate", "caption": "Label" } }, + { "action": "remove", "propertyKey": "oldProp" } + ] +} +\`\`\``; + +/** + * Registers the property update tool with the MCP server. + */ +export function registerPropertyUpdateTools(server: McpServer): void { + server.registerTool( + "update-widget-properties", + { + title: "Update Widget Properties", + description: UPDATE_WIDGET_PROPERTIES_DESCRIPTION, + inputSchema: updateWidgetPropertiesSchema + }, + handleUpdateWidgetProperties + ); + + console.error("[property-update] Registered 1 tool"); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/scaffolding.tools.ts b/packages/pluggable-widgets-mcp/src/tools/scaffolding.tools.ts new file mode 100644 index 0000000000..6c216eb0f2 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/scaffolding.tools.ts @@ -0,0 +1,225 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { GENERATIONS_DIR } from "@/config"; +import { DEFAULT_WIDGET_OPTIONS, type ToolContext, type ToolResponse, widgetOptionsSchema } from "@/tools/types"; +import { buildWidgetOptions, runWidgetGenerator, SCAFFOLD_PROGRESS } from "@/tools/utils/generator"; +import { ProgressTracker } from "@/tools/utils/progress-tracker"; +import { + createStructuredError, + createStructuredErrorResponse, + createToolResponse, + type ErrorCode +} from "@/tools/utils/response"; +import { access, mkdir } from "node:fs/promises"; +import { dirname, resolve } from "node:path"; +import { z } from "zod"; + +/** + * Schema for create-widget tool input. + * Extends the base widgetOptionsSchema with tool-specific options like outputPath. + */ +const createWidgetSchema = widgetOptionsSchema.extend({ + outputPath: z + .string() + .optional() + .describe( + "[OPTIONAL] Directory where widget will be created. Defaults to ./generations/ in the current working directory. For desktop clients without a clear working directory, ask the user for their preferred location." + ) +}); + +type CreateWidgetInput = z.infer; + +const CREATE_WIDGET_DESCRIPTION = `Scaffolds a new Mendix pluggable widget using the official @mendix/generator-widget. + +BEFORE RUNNING: Please confirm all options with the user. Show them the full list of configurable parameters: + +REQUIRED: + • name: Widget name in PascalCase (e.g., "MyAwesomeWidget") + • description: Brief description of what the widget does + +OPTIONAL (with defaults): + • version: Initial version (default: "${DEFAULT_WIDGET_OPTIONS.version}") + • author: Author name (default: "${DEFAULT_WIDGET_OPTIONS.author}") + • license: License type (default: "${DEFAULT_WIDGET_OPTIONS.license}") + • organization: Namespace organization (default: "${DEFAULT_WIDGET_OPTIONS.organization}") + • template: "full" (with examples) or "empty" (minimal) (default: "${DEFAULT_WIDGET_OPTIONS.template}") + • programmingLanguage: "typescript" or "javascript" (default: "${DEFAULT_WIDGET_OPTIONS.programmingLanguage}") + • unitTests: Include Jest test setup (default: ${DEFAULT_WIDGET_OPTIONS.unitTests}) + • e2eTests: Include Playwright E2E tests (default: ${DEFAULT_WIDGET_OPTIONS.e2eTests}) + • outputPath: Directory where widget will be created (default: ./generations/) + +Ask the user if they want to customize any options before proceeding.`; + +/** + * Registers scaffolding-related tools for widget creation and management. + * + * Currently registers the create-widget tool. This modular pattern allows + * easy addition of related tools such as: + * - Widget property editing + * - XML configuration management + * - Build and deployment automation + * + * @see AGENTS.md Roadmap Context section for planned additions + */ +export function registerScaffoldingTools(server: McpServer): void { + server.registerTool( + "create-widget", + { + title: "Create Widget", + description: CREATE_WIDGET_DESCRIPTION, + inputSchema: createWidgetSchema + }, + handleCreateWidget + ); +} + +async function handleCreateWidget(args: CreateWidgetInput, context: ToolContext): Promise { + const options = buildWidgetOptions(args); + const outputDir = args.outputPath ?? GENERATIONS_DIR; + + // Validate user-provided outputPath is within allowed directories + if (args.outputPath) { + const resolvedOutputPath = resolve(args.outputPath); + const allowedOutputPaths = [ + resolve(GENERATIONS_DIR), + ...(process.env.MCP_ALLOWED_OUTPUT_PATHS ?? "") + .split(":") + .filter(Boolean) + .map(p => resolve(p)) + ]; + const isAllowedPath = allowedOutputPaths.some( + allowed => resolvedOutputPath.startsWith(allowed + "/") || resolvedOutputPath === allowed + ); + if (!isAllowedPath) { + return createStructuredErrorResponse( + createStructuredError( + "ERR_OUTPUT_PATH_INVALID", + `Output path is not within an allowed directory: ${args.outputPath}`, + { + suggestion: `Output must be within ${GENERATIONS_DIR} or set MCP_ALLOWED_OUTPUT_PATHS env var (colon-separated paths).` + } + ) + ); + } + } + + const tracker = new ProgressTracker({ + context, + logger: "scaffolding", + totalSteps: 3 + }); + + try { + // Pre-validate ONLY for default path (catches Claude Desktop's non-existent cwd) + // For user-provided paths, let mkdir try and give a specific error if it fails + if (!args.outputPath) { + const parentDir = dirname(outputDir); + try { + await access(parentDir); + } catch { + return createStructuredErrorResponse( + createStructuredError("ERR_OUTPUT_PATH_REQUIRED", "Cannot create widget in default location", { + suggestion: + "The default output directory is not accessible (common in Claude Desktop). Please provide an explicit 'outputPath' parameter with a valid directory path on your system (e.g., '/Users/yourname/Projects/widgets', '~/widgets', or '/tmp/widgets').", + rawOutput: `Default path "${outputDir}" is not accessible. The working directory may not exist in this environment.` + }) + ); + } + } + + console.error(`[create-widget] Starting widget scaffolding for "${options.name}"...`); + await tracker.progress(SCAFFOLD_PROGRESS.START, `Starting widget scaffolding for "${options.name}"...`); + await tracker.info(`Starting widget scaffolding for "${options.name}"...`, { + widgetName: options.name, + template: options.template, + organization: options.organization, + outputDir + }); + + // Ensure output directory exists + await mkdir(outputDir, { recursive: true }); + + // The generator creates the widget folder itself (camelCase: first letter lowered) + const widgetFolder = options.name.charAt(0).toLowerCase() + options.name.slice(1); + const widgetPath = `${outputDir}/${widgetFolder}`; + + // Run generator inside outputDir — it creates the widget subfolder + await runWidgetGenerator(options, tracker, outputDir); + + console.error(`[create-widget] Widget created successfully at ${widgetPath}`); + await tracker.progress(SCAFFOLD_PROGRESS.COMPLETE, "Widget created successfully!"); + await tracker.info("Widget created successfully!", { + widgetName: options.name, + path: widgetPath + }); + + return createToolResponse( + [ + `Widget "${options.name}" created successfully!`, + "", + `Location: ${widgetPath}`, + "", + "=== TO IMPLEMENT WIDGET FUNCTIONALITY ===", + "", + "1. FETCH GUIDELINES (MCP Resources):", + " - mendix://guidelines/property-types (all widget property types with JSON schema)", + " - mendix://guidelines/widget-patterns (reusable TSX/SCSS patterns for common widget types)", + "", + "2. EXPLORE WIDGET STRUCTURE:", + ` Use list-widget-files tool with widgetPath: "${widgetPath}"`, + "", + "3. READ EXISTING CODE:", + ` Use read-widget-file tool to inspect:`, + ` - src/${options.name}.tsx (main component entry point)`, + ` - src/${options.name}.xml (widget properties definition)`, + ` - src/components/ (UI components - create if needed)`, + "", + "4. IMPLEMENT CHANGES:", + ` Use write-widget-file tool to create/update files`, + "", + "=== KEY FILES ===", + `- ${widgetPath}/src/${options.name}.tsx - Main widget component`, + `- ${widgetPath}/src/${options.name}.xml - Properties configuration`, + `- ${widgetPath}/src/${options.name}.editorPreview.tsx - Studio Pro preview`, + "", + "=== BUILD & TEST ===", + `1. cd ${widgetPath}`, + "2. npm install", + "3. npm start (builds and watches for changes)", + "", + "The widget will be available in Mendix Studio Pro after syncing the app directory." + ].join("\n") + ); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + await tracker.error(`Failed to create widget: ${message}`, { + widgetName: options.name, + error: message + }); + + // Categorize the error for structured response + let code: ErrorCode = "ERR_SCAFFOLD_FAILED"; + let suggestion = "Check the error details and try again. Ensure you have npm/npx available."; + + if (message.includes("timed out")) { + code = "ERR_SCAFFOLD_TIMEOUT"; + suggestion = + "The generator took too long. Check your network connection and npm registry access. Try running 'npx @mendix/generator-widget' manually."; + } else if (message.includes("ENOENT") || message.includes("not found")) { + code = "ERR_NOT_FOUND"; + // Check if this is a path issue vs a command issue + if (message.includes("mkdir") || message.includes(outputDir)) { + suggestion = `Cannot create directory "${outputDir}". Try a different 'outputPath' that you have write access to.`; + } else { + suggestion = + "The generator-widget binary was not found. Run: cd /path/to/widgets-tools/packages/generator-widget && npm link. Then ensure the MCP server runs under the same Node.js version."; + } + } + + return createStructuredErrorResponse( + createStructuredError(code, `Failed to create widget "${options.name}"`, { + suggestion, + rawOutput: message + }) + ); + } +} diff --git a/packages/pluggable-widgets-mcp/src/tools/types.ts b/packages/pluggable-widgets-mcp/src/tools/types.ts new file mode 100644 index 0000000000..b89f2087c4 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/types.ts @@ -0,0 +1,128 @@ +import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js"; +import type { ServerNotification, ServerRequest } from "@modelcontextprotocol/sdk/types.js"; +import { z } from "zod"; + +// ============================================================================= +// MCP Core Types +// ============================================================================= + +/** + * Standard response format for MCP tool handlers. + * Index signature required for MCP SDK compatibility. + */ +export interface ToolResponse { + [key: string]: unknown; + content: Array<{ type: "text"; text: string }>; +} + +/** + * Extra context provided to tool handlers by the MCP server. + */ +export type ToolContext = RequestHandlerExtra; + +/** + * Log levels supported by MCP logging notifications. + */ +export type LogLevel = "debug" | "info" | "notice" | "warning" | "error"; + +// ============================================================================= +// Widget Generator Types +// ============================================================================= + +/** + * Default values for widget options. + * Centralized here to be used by both schema descriptions and buildWidgetOptions(). + */ +export const DEFAULT_WIDGET_OPTIONS = { + version: "1.0.0", + author: "Mendix", + license: "Apache-2.0", + organization: "Mendix", + template: "empty" as const, + programmingLanguage: "typescript" as const, + unitTests: true, + e2eTests: false +} as const; + +/** + * Zod schema for widget creation options. + * Single source of truth for widget options - type is derived via z.infer. + */ +export const widgetOptionsSchema = z.object({ + name: z + .string() + .min(1) + .max(100) + .describe("[REQUIRED] The name of the widget in PascalCase (e.g., 'MyAwesomeWidget', 'DataChart')"), + description: z.string().min(1).max(200).describe("[REQUIRED] A brief description of what the widget does"), + version: z + .string() + .regex(/^\d+\.\d+\.\d+$/, "Version must be in semver format: x.y.z") + .optional() + .describe(`[OPTIONAL] Initial version in semver format. Default: "${DEFAULT_WIDGET_OPTIONS.version}"`), + author: z + .string() + .min(1) + .max(100) + .optional() + .describe(`[OPTIONAL] Author name. Default: "${DEFAULT_WIDGET_OPTIONS.author}"`), + license: z + .string() + .min(1) + .max(50) + .optional() + .describe(`[OPTIONAL] License type. Default: "${DEFAULT_WIDGET_OPTIONS.license}"`), + organization: z + .string() + .min(1) + .max(100) + .optional() + .describe( + `[OPTIONAL] Organization name for the widget namespace. Default: "${DEFAULT_WIDGET_OPTIONS.organization}"` + ), + template: z + .enum(["full", "empty"]) + .optional() + .describe( + `[OPTIONAL] Widget template: "full" includes sample code and examples, "empty" is minimal/blank. Default: "${DEFAULT_WIDGET_OPTIONS.template}"` + ), + programmingLanguage: z + .enum(["typescript", "javascript"]) + .optional() + .describe( + `[OPTIONAL] Programming language for the widget source code. Default: "${DEFAULT_WIDGET_OPTIONS.programmingLanguage}"` + ), + unitTests: z + .boolean() + .optional() + .describe(`[OPTIONAL] Include unit test setup with Jest. Default: ${DEFAULT_WIDGET_OPTIONS.unitTests}`), + e2eTests: z + .boolean() + .optional() + .describe( + `[OPTIONAL] Include end-to-end test setup with Playwright. Default: ${DEFAULT_WIDGET_OPTIONS.e2eTests}` + ) +}); + +/** + * Input options for creating a new Mendix pluggable widget (with optional fields). + * Derived from widgetOptionsSchema to ensure type-schema consistency. + */ +export type WidgetOptionsInput = z.infer; + +/** + * Resolved widget options with all defaults applied (all fields required). + * This is the type returned by buildWidgetOptions() after applying defaults. + */ +export interface WidgetOptions { + name: string; + description: string; + version: string; + author: string; + license: string; + organization: string; + template: "full" | "empty"; + programmingLanguage: "typescript" | "javascript"; + unitTests: boolean; + e2eTests: boolean; +} diff --git a/packages/pluggable-widgets-mcp/src/tools/utils/generator.ts b/packages/pluggable-widgets-mcp/src/tools/utils/generator.ts new file mode 100644 index 0000000000..be7b338ffa --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/utils/generator.ts @@ -0,0 +1,159 @@ +import { spawn } from "node:child_process"; +import { resolve } from "node:path"; +import { GENERATIONS_DIR, PACKAGE_ROOT, SCAFFOLD_TIMEOUT_MS } from "@/config"; +import { DEFAULT_WIDGET_OPTIONS, type WidgetOptions, type WidgetOptionsInput } from "@/tools/types"; +import { ProgressTracker } from "./progress-tracker"; + +// Re-export for backward compatibility with existing imports +export { DEFAULT_WIDGET_OPTIONS }; + +/** + * Progress milestones for widget scaffolding. + */ +export const SCAFFOLD_PROGRESS = { + START: 0, + INSTALLING: 50, + COMPLETE: 100 +} as const; + +/** + * Builds widget options from input arguments with defaults applied. + * Takes the schema-validated input (with optional fields) and returns + * fully resolved options (all fields required). + */ +export function buildWidgetOptions(args: WidgetOptionsInput): WidgetOptions { + return { + name: args.name, + description: args.description, + version: args.version ?? DEFAULT_WIDGET_OPTIONS.version, + author: args.author ?? DEFAULT_WIDGET_OPTIONS.author, + license: args.license ?? DEFAULT_WIDGET_OPTIONS.license, + organization: args.organization ?? DEFAULT_WIDGET_OPTIONS.organization, + template: args.template ?? DEFAULT_WIDGET_OPTIONS.template, + programmingLanguage: args.programmingLanguage ?? DEFAULT_WIDGET_OPTIONS.programmingLanguage, + unitTests: args.unitTests ?? DEFAULT_WIDGET_OPTIONS.unitTests, + e2eTests: args.e2eTests ?? DEFAULT_WIDGET_OPTIONS.e2eTests + }; +} + +/** + * Returns the path to the generator-widget binary installed in this package's node_modules. + * Using a direct path (rather than npx) ensures we always use the correct version + * regardless of the spawn cwd (which is set to outputDir for widget placement). + */ +function getGeneratorBinPath(): string { + return resolve(PACKAGE_ROOT, "node_modules/.bin/generator-widget"); +} + +/** + * Maps WidgetOptions to CLI flags for the non-interactive generator. + * Requires @mendix/generator-widget with --default flag support (commit 16cf75e). + */ +function buildWidgetFlags(options: WidgetOptions): string[] { + return [ + "--default", + "--description", + options.description, + "--organization", + options.organization, + "--copyright", + "© Mendix Technology BV 2026", + "--license", + options.license, + "--version", + options.version, + "--author", + options.author, + "--projectPath", + "../", + "--programmingLanguage", + options.programmingLanguage, + "--programmingStyle", + "function", + "--platform", + "web", + "--boilerplate", + options.template, + ...(options.unitTests ? ["--hasUnitTests"] : []), + ...(options.e2eTests ? ["--hasE2eTests"] : []) + ]; +} + +/** + * Runs the Mendix widget generator using non-interactive CLI flags. + * Replaces the previous node-pty / interactive-prompt approach. + * + * @param options - Widget configuration options + * @param tracker - Progress tracker for notifications + * @param outputDir - Directory where the widget folder will be created + */ +export async function runWidgetGenerator( + options: WidgetOptions, + tracker: ProgressTracker, + outputDir: string = GENERATIONS_DIR +): Promise { + const flags = buildWidgetFlags(options); + const generatorBin = getGeneratorBinPath(); + + return new Promise((resolve, reject) => { + tracker.start("initializing"); + + let stdout = ""; + let stderr = ""; + let installingNotified = false; + + const child = spawn(generatorBin, [options.name, ...flags], { + cwd: outputDir, + env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1", DO_NOT_TRACK: "1" }, + stdio: ["ignore", "pipe", "pipe"] + }); + + child.stdout.on("data", (data: Buffer) => { + const chunk = data.toString(); + stdout += chunk; + console.error(`[create-widget] stdout: ${chunk.trim()}`); + + if (!installingNotified && stdout.includes("npm install")) { + installingNotified = true; + tracker.updateStep("installing", 2); + tracker.progress(SCAFFOLD_PROGRESS.INSTALLING, "Installing dependencies...").catch(() => undefined); + tracker.info("Installing dependencies...").catch(() => undefined); + } + }); + + child.stderr.on("data", (data: Buffer) => { + const chunk = data.toString(); + stderr += chunk; + console.error(`[create-widget] stderr: ${chunk.trim()}`); + }); + + const timeout = setTimeout(() => { + tracker.stop(); + child.kill(); + reject(new Error("Widget scaffold timed out after 5 minutes")); + }, SCAFFOLD_TIMEOUT_MS); + + child.on("close", (exitCode: number | null) => { + clearTimeout(timeout); + tracker.stop(); + + if (exitCode === 0) { + console.error(`[create-widget] Widget scaffolded successfully`); + resolve(); + } else { + console.error(`[create-widget] Widget scaffold failed with exit code ${exitCode}`); + reject( + new Error( + `Generator exited with code ${exitCode}\nStderr: ${stderr.slice(-2000)}\nStdout: ${stdout.slice(-1000)}` + ) + ); + } + }); + + child.on("error", (err: Error) => { + clearTimeout(timeout); + tracker.stop(); + reject(new Error(`Failed to spawn generator: ${err.message}`)); + }); + }); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/utils/notifications.ts b/packages/pluggable-widgets-mcp/src/tools/utils/notifications.ts new file mode 100644 index 0000000000..7ecbef307f --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/utils/notifications.ts @@ -0,0 +1,65 @@ +import type { LogLevel, ToolContext } from "@/tools/types"; + +/** + * Sends a progress notification to the MCP client. + * Only sends if the client provided a progressToken in the request. + * + * **Where this appears:** + * - ⚙️ Client UI indicators (spinners, progress bars, status indicators) + * - 🔍 MCP Inspector's Notifications panel (for debugging) + * - ❌ NOT in the chat conversation history + * + * **MCP Specification Behavior:** + * Progress notifications are routed to the client's UI layer, not the conversation. + * This is by design—use tool results for chat-visible output. + * + * @param context - Tool execution context with notification sender + * @param progress - Progress value (0-100) + * @param message - Optional progress description + */ +export async function sendProgress(context: ToolContext, progress: number, message?: string): Promise { + const progressToken = context._meta?.progressToken; + if (progressToken) { + await context.sendNotification({ + method: "notifications/progress", + params: { progressToken, progress, total: 100, message } + }); + } +} + +/** + * Sends a logging message notification to the MCP client. + * Works independently of progressToken and provides detailed context. + * + * **Where this appears:** + * - 🔍 MCP Inspector's Logs panel (for debugging) + * - 🛠️ Client developer consoles (if supported) + * - ❌ NOT in the chat conversation history + * + * **MCP Specification Behavior:** + * Log notifications are routed to debug/inspector layers, not the conversation. + * These are intended for developers debugging MCP servers, not end-user feedback. + * For chat-visible messages, use tool result content instead. + * + * @param context - Tool execution context with notification sender + * @param level - Log severity level (debug, info, warning, error) + * @param message - Human-readable log message + * @param data - Additional structured data for debugging + * @param logger - Logger name/category (defaults to "mcp-tools") + */ +export async function sendLogMessage( + context: ToolContext, + level: LogLevel, + message: string, + data?: Record, + logger = "mcp-tools" +): Promise { + await context.sendNotification({ + method: "notifications/message", + params: { + level, + logger, + data: { message, ...data } + } + }); +} diff --git a/packages/pluggable-widgets-mcp/src/tools/utils/progress-tracker.ts b/packages/pluggable-widgets-mcp/src/tools/utils/progress-tracker.ts new file mode 100644 index 0000000000..87d74637db --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/utils/progress-tracker.ts @@ -0,0 +1,237 @@ +import type { LogLevel, ToolContext } from "@/tools/types"; +import { sendLogMessage, sendProgress } from "./notifications"; + +/** + * Default timing constants for progress tracking. + */ +const DEFAULT_HEARTBEAT_INTERVAL_MS = 3000; +const DEFAULT_STUCK_WARNING_MS = 10000; + +/** + * Configuration options for the ProgressTracker. + */ +export interface ProgressTrackerOptions { + /** MCP tool context for sending notifications */ + context: ToolContext; + /** Logger name used in notifications/message (e.g., "scaffolding", "build") */ + logger: string; + /** Interval in ms between heartbeat logs (default: 3000) */ + heartbeatIntervalMs?: number; + /** Time in ms before sending a stuck warning (default: 10000) */ + stuckWarningMs?: number; + /** Total number of steps for progress calculation */ + totalSteps?: number; +} + +/** + * Current state snapshot from the tracker. + */ +export interface ProgressTrackerState { + step: string; + stepIndex: number; + elapsedSeconds: number; + isComplete: boolean; +} + +/** + * A reusable progress tracker for MCP tools. + * + * Provides: + * - Heartbeat logging at regular intervals + * - Stuck detection with warnings + * - Convenient logging methods (info, warning, error, debug) + * - Progress notification helpers + * - Step tracking with timing + * + * @example + * ```typescript + * const tracker = new ProgressTracker({ + * context, + * logger: "scaffolding", + * totalSteps: 10 + * }); + * + * tracker.start("initializing"); + * + * // Update step when progressing + * tracker.updateStep("configuring", 1); + * await tracker.info("Configuration started"); + * + * // On completion + * tracker.stop(); + * await tracker.info("Complete!"); + * ``` + */ +export class ProgressTracker { + private readonly context: ToolContext; + private readonly logger: string; + private readonly heartbeatIntervalMs: number; + private readonly stuckWarningMs: number; + private readonly totalSteps: number; + + private startTime: number = 0; + private lastStepTime: number = 0; + private currentStep: string = "idle"; + private currentStepIndex: number = 0; + private stuckWarningShown: boolean = false; + private isComplete: boolean = false; + private heartbeatInterval?: ReturnType; + + constructor(options: ProgressTrackerOptions) { + this.context = options.context; + this.logger = options.logger; + this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS; + this.stuckWarningMs = options.stuckWarningMs ?? DEFAULT_STUCK_WARNING_MS; + this.totalSteps = options.totalSteps ?? 0; + } + + /** + * Starts the progress tracker with optional initial step. + * Begins heartbeat interval for periodic status updates. + */ + start(initialStep = "starting"): void { + this.startTime = Date.now(); + this.lastStepTime = Date.now(); + this.currentStep = initialStep; + this.currentStepIndex = 0; + this.stuckWarningShown = false; + this.isComplete = false; + + this.heartbeatInterval = setInterval(() => { + this.sendHeartbeat(); + this.checkStuckWarning(); + }, this.heartbeatIntervalMs); + } + + /** + * Stops the progress tracker and cleans up intervals. + * Should be called when the operation completes or fails. + */ + stop(): void { + if (this.heartbeatInterval) { + clearInterval(this.heartbeatInterval); + this.heartbeatInterval = undefined; + } + } + + /** + * Updates the current step being tracked. + * Resets the stuck warning timer. + */ + updateStep(step: string, index?: number): void { + this.currentStep = step; + if (index !== undefined) { + this.currentStepIndex = index; + } + this.lastStepTime = Date.now(); + this.stuckWarningShown = false; + } + + /** + * Marks the tracker as complete. + * Subsequent stuck warnings will not be sent. + */ + markComplete(): void { + this.isComplete = true; + } + + /** + * Gets the elapsed time in seconds since start. + */ + get elapsedSeconds(): number { + if (this.startTime === 0) { + return 0; + } + return Math.round((Date.now() - this.startTime) / 1000); + } + + /** + * Gets the current state snapshot. + */ + get state(): ProgressTrackerState { + return { + step: this.currentStep, + stepIndex: this.currentStepIndex, + elapsedSeconds: this.elapsedSeconds, + isComplete: this.isComplete + }; + } + + /** + * Sends a log message with the specified level. + */ + async log(level: LogLevel, message: string, data?: Record): Promise { + await sendLogMessage(this.context, level, message, data, this.logger); + } + + /** + * Sends an info-level log message. + */ + async info(message: string, data?: Record): Promise { + await this.log("info", message, data); + } + + /** + * Sends a warning-level log message. + */ + async warning(message: string, data?: Record): Promise { + await this.log("warning", message, data); + } + + /** + * Sends an error-level log message. + */ + async error(message: string, data?: Record): Promise { + await this.log("error", message, data); + } + + /** + * Sends a debug-level log message. + */ + async debug(message: string, data?: Record): Promise { + await this.log("debug", message, data); + } + + /** + * Sends a progress notification to the client. + */ + async progress(value: number, message?: string): Promise { + await sendProgress(this.context, value, message); + } + + /** + * Sends a heartbeat debug log with current status. + */ + private sendHeartbeat(): void { + const elapsed = this.elapsedSeconds; + const stepInfo = this.totalSteps > 0 ? ` [${this.currentStepIndex}/${this.totalSteps}]` : ""; + + this.debug(`In progress...${stepInfo} (${elapsed}s elapsed)`, { + step: this.currentStep, + stepIndex: this.currentStepIndex, + totalSteps: this.totalSteps, + elapsedSeconds: elapsed + }).catch(() => undefined); + } + + /** + * Checks if the current step has exceeded the stuck warning threshold. + */ + private checkStuckWarning(): void { + if (this.isComplete || this.stuckWarningShown) { + return; + } + + const timeSinceLastStep = Date.now() - this.lastStepTime; + if (timeSinceLastStep > this.stuckWarningMs) { + this.stuckWarningShown = true; + const waitingSec = Math.round(timeSinceLastStep / 1000); + + this.warning(`Waiting for response (step: ${this.currentStep}, ${waitingSec}s elapsed)`, { + step: this.currentStep, + stepIndex: this.currentStepIndex, + waitingSeconds: waitingSec + }).catch(() => undefined); + } + } +} diff --git a/packages/pluggable-widgets-mcp/src/tools/utils/response.ts b/packages/pluggable-widgets-mcp/src/tools/utils/response.ts new file mode 100644 index 0000000000..e436113080 --- /dev/null +++ b/packages/pluggable-widgets-mcp/src/tools/utils/response.ts @@ -0,0 +1,125 @@ +import type { ToolResponse } from "@/tools/types"; + +/** + * Error codes for structured error responses. + * These help clients categorize and handle errors appropriately. + */ +export type ErrorCode = + | "ERR_BUILD_TS" // TypeScript compilation error + | "ERR_BUILD_XML" // XML validation error + | "ERR_BUILD_MISSING_DEP" // Missing dependency + | "ERR_BUILD_UNKNOWN" // Unknown build error + | "ERR_SCAFFOLD_TIMEOUT" // Scaffolding timed out + | "ERR_SCAFFOLD_FAILED" // Generic scaffold failure + | "ERR_FILE_PATH" // Invalid file path + | "ERR_FILE_WRITE" // File write failure + | "ERR_NOT_FOUND" // Resource not found + | "ERR_OUTPUT_PATH_REQUIRED" // Output path required (e.g., in Claude Desktop) + | "ERR_OUTPUT_PATH_INVALID"; // Output path is not accessible + +/** + * Structured error with code, message, and optional details. + * Provides actionable information for debugging and fixing issues. + */ +export interface StructuredError { + code: ErrorCode; + message: string; + suggestion?: string; + details?: { + file?: string; + line?: number; + column?: number; + rawOutput?: string; + }; +} + +/** + * Creates a successful tool response with text content. + */ +export function createToolResponse(text: string): ToolResponse { + return { + content: [{ type: "text", text }] + }; +} + +/** + * Creates an error tool response with a message. + */ +export function createErrorResponse(message: string): ToolResponse { + return { + isError: true, + content: [{ type: "text", text: message }] + }; +} + +/** + * Creates a structured error response with code, message, and details. + * Formats the error for both human readability and machine parsing. + */ +export function createStructuredErrorResponse(error: StructuredError): ToolResponse { + const lines: string[] = []; + + // Header with error code + lines.push(`❌ [${error.code}] ${error.message}`); + + // File location if available + if (error.details?.file) { + let location = ` 📁 File: ${error.details.file}`; + if (error.details.line) { + location += `:${error.details.line}`; + if (error.details.column) { + location += `:${error.details.column}`; + } + } + lines.push(location); + } + + // Suggestion for fixing + if (error.suggestion) { + lines.push(` 💡 Suggestion: ${error.suggestion}`); + } + + // Raw output for debugging (truncated) + if (error.details?.rawOutput) { + const truncated = + error.details.rawOutput.length > 500 + ? error.details.rawOutput.slice(0, 500) + "...(truncated)" + : error.details.rawOutput; + lines.push(` 📝 Details:\n${truncated}`); + } + + return { + isError: true, + content: [{ type: "text", text: lines.join("\n") }] + }; +} + +/** + * Creates a structured error object (for use with createStructuredErrorResponse). + */ +export function createStructuredError( + code: ErrorCode, + message: string, + options?: { + suggestion?: string; + file?: string; + line?: number; + column?: number; + rawOutput?: string; + } +): StructuredError { + return { + code, + message, + suggestion: options?.suggestion, + details: + options?.file || options?.line || options?.rawOutput + ? { + file: options?.file, + line: options?.line, + column: options?.column, + rawOutput: options?.rawOutput + } + : undefined + }; +} diff --git a/packages/pluggable-widgets-mcp/tsconfig.json b/packages/pluggable-widgets-mcp/tsconfig.json new file mode 100644 index 0000000000..75d03a23fa --- /dev/null +++ b/packages/pluggable-widgets-mcp/tsconfig.json @@ -0,0 +1,34 @@ +{ + "include": ["./src", "config.ts"], + "compilerOptions": { + "lib": ["ES2022"], + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "module": "preserve", + "moduleResolution": "bundler", + "target": "ES2022", + "outDir": "./dist", + "rootDir": "./src", + "types": ["node"], + "strict": true, + "noEmitOnError": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "declaration": true, + "sourceMap": true, + "declarationMap": true, + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "useUnknownInCatchVariables": false, + "exactOptionalPropertyTypes": false + }, + "exclude": ["node_modules", "dist"] +} diff --git a/packages/pluggable-widgets-mcp/tscpaths.json b/packages/pluggable-widgets-mcp/tscpaths.json new file mode 100644 index 0000000000..b8f0327956 --- /dev/null +++ b/packages/pluggable-widgets-mcp/tscpaths.json @@ -0,0 +1,4 @@ +{ + "resolveFullPaths": true, + "resolveFullExtension": ".js" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8654faf3a..a23c8b7b85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,7 +80,7 @@ importers: version: 2.0.1 node-fetch: specifier: ^2.7.0 - version: 2.7.0 + version: 2.7.0(encoding@0.1.13) shelljs: specifier: ^0.8.5 version: 0.8.5 @@ -178,7 +178,7 @@ importers: version: 11.0.3 node-fetch: specifier: ^2.7.0 - version: 2.7.0 + version: 2.7.0(encoding@0.1.13) ora: specifier: ^5.4.1 version: 5.4.1 @@ -236,7 +236,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -401,6 +401,43 @@ importers: specifier: ^16.0.0 version: 16.4.0 + packages/pluggable-widgets-mcp: + dependencies: + '@mendix/generator-widget': + specifier: github:rahmanunver/widgets-tools#generator-widget-noninteractive-defaults&path:packages/generator-widget + version: https://codeload.github.com/rahmanunver/widgets-tools/tar.gz/17537779fb5d4cdc72a023251ce51121ea1914cf#path:packages/generator-widget(@types/node@22.14.1)(encoding@0.1.13)(mem-fs@2.3.0) + '@modelcontextprotocol/sdk': + specifier: ^1.24.2 + version: 1.25.2(hono@4.11.3)(zod@4.3.5) + cors: + specifier: ^2.8.5 + version: 2.8.5 + express: + specifier: ^5.1.0 + version: 5.2.1 + zod: + specifier: ^4.1.13 + version: 4.3.5 + devDependencies: + '@types/cors': + specifier: ^2.8.19 + version: 2.8.19 + '@types/express': + specifier: ^5.0.6 + version: 5.0.6 + '@types/node': + specifier: ~22.14.0 + version: 22.14.1 + tsc-alias: + specifier: ^1.8.16 + version: 1.8.16 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + typescript: + specifier: '>5.8.0' + version: 5.9.3 + packages/pluggableWidgets/accessibility-helper-web: dependencies: '@mendix/widget-plugin-component-kit': @@ -415,7 +452,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -440,7 +477,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -480,7 +517,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -508,7 +545,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -539,7 +576,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -579,7 +616,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -610,7 +647,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -647,7 +684,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -693,7 +730,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -724,7 +761,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -770,7 +807,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -819,7 +856,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -890,7 +927,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -936,7 +973,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -982,7 +1019,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1016,7 +1053,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1074,7 +1111,7 @@ importers: version: 18.0.1 '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1111,7 +1148,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1157,7 +1194,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1197,7 +1234,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1255,7 +1292,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1322,7 +1359,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1368,7 +1405,7 @@ importers: version: 7.27.1(@babel/core@7.28.4) '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/rollup-web-widgets': specifier: workspace:* version: link:../../shared/rollup-web-widgets @@ -1390,7 +1427,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1436,7 +1473,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1473,7 +1510,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1516,7 +1553,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1574,7 +1611,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1611,7 +1648,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1645,7 +1682,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1676,7 +1713,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1704,7 +1741,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1738,7 +1775,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1775,7 +1812,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1818,7 +1855,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1867,7 +1904,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1919,7 +1956,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1950,7 +1987,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -1981,7 +2018,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2015,7 +2052,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2055,7 +2092,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2092,7 +2129,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2171,7 +2208,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2247,7 +2284,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2284,7 +2321,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2324,7 +2361,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2355,7 +2392,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2401,7 +2438,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2432,7 +2469,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2466,7 +2503,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2497,7 +2534,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2525,7 +2562,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -2695,7 +2732,7 @@ importers: devDependencies: '@mendix/pluggable-widgets-tools': specifier: 10.21.2 - version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) rollup-plugin-copy: specifier: ^3.5.0 version: 3.5.0 @@ -3897,6 +3934,162 @@ packages: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3964,6 +4157,9 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + '@googlemaps/jest-mocks@2.22.6': resolution: {integrity: sha512-t3n0l03OdGPEUCfWVC1a4xGgcE21+58tGdNsIjGWsTbsaMZBOfCxwTHvzmAx/H0dyPeKZ4uWmtahsyUQIcGInA==} @@ -3971,6 +4167,12 @@ packages: resolution: {integrity: sha512-Tt1oSC7yBwM05j6/SOLagOAJ/NW7XrXKKqUwcuBY++OZO9YyEWF/i72jFSc3DGW4ZAHfc6HHsTIkhayxyy+DsA==} engines: {node: '>=20.0.0'} + '@hono/node-server@1.19.7': + resolution: {integrity: sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -4001,6 +4203,15 @@ packages: peerDependencies: react: '>=18.0.0 <19.0.0' + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': ~22.14.0 + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -4013,6 +4224,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/string-locale-compare@1.1.0': + resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==} + '@isaacs/ttlcache@1.4.1': resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} engines: {node: '>=12'} @@ -4046,10 +4260,6 @@ packages: resolution: {integrity: sha512-44F4l4Enf+MirJN8X/NhdGkl71k5rBYiwdVlo4HxOwbu0sHV8QKrGEedb1VUU4K3W7fBKE0HGfbn7eZm0Ti3zg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/diff-sequences@30.0.1': - resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/environment@29.7.0': resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4058,10 +4268,6 @@ packages: resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/expect-utils@30.2.0': - resolution: {integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect@29.7.0': resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4070,10 +4276,6 @@ packages: resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/get-type@30.1.0': - resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/globals@29.7.0': resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4214,11 +4416,27 @@ packages: '@melloware/coloris@0.25.0': resolution: {integrity: sha512-RBWVFLjWbup7GRkOXb9g3+ZtR9AevFtJinrRz2cYPLjZ3TCkNRGMWuNbmQWbZ5cF3VU7aQDZwUsYgIY/bGrh2g==} + '@mendix/generator-widget@https://codeload.github.com/rahmanunver/widgets-tools/tar.gz/17537779fb5d4cdc72a023251ce51121ea1914cf#path:packages/generator-widget': + resolution: {path: packages/generator-widget, tarball: https://codeload.github.com/rahmanunver/widgets-tools/tar.gz/17537779fb5d4cdc72a023251ce51121ea1914cf} + version: 10.24.0 + engines: {node: '>=16'} + hasBin: true + '@mendix/pluggable-widgets-tools@10.21.2': resolution: {integrity: sha512-czo6GfQuifMR0uBen4y+K8y3koI6PQPc5YXgEy1wzuSvctYCNvgf3KfyfOuyX+AFZVYPWdKKsDXAQMWRFUsNIQ==} engines: {node: '>=20'} hasBin: true + '@modelcontextprotocol/sdk@1.25.2': + resolution: {integrity: sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -4231,6 +4449,126 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/arborist@4.3.1': + resolution: {integrity: sha512-yMRgZVDpwWjplorzt9SFSaakWx6QIK248Nw4ZFgkrAy/GvJaFRaSZzE6nD7JBK5r8g/+PTxFq5Wj/sfciE7x+A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} + hasBin: true + + '@npmcli/fs@1.1.1': + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + + '@npmcli/fs@2.1.2': + resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/git@2.1.0': + resolution: {integrity: sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==} + + '@npmcli/git@4.1.0': + resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/installed-package-contents@1.0.7': + resolution: {integrity: sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==} + engines: {node: '>= 10'} + hasBin: true + + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + '@npmcli/map-workspaces@2.0.4': + resolution: {integrity: sha512-bMo0aAfwhVwqoVM5UzX1DJnlvVvzDCHae821jv48L1EsrYwfOZChlqWYXEtto/+BkBXetPbEWgau++/brh4oVg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/metavuln-calculator@2.0.0': + resolution: {integrity: sha512-VVW+JhWCKRwCTE+0xvD6p3uV4WpqocNYYtzyvenqL/u1Q3Xx6fGTJ+6UoIoii07fbuEO9U3IIyuGY0CYHDv1sg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} + + '@npmcli/move-file@1.1.2': + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + + '@npmcli/move-file@2.0.1': + resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs + + '@npmcli/name-from-folder@1.0.1': + resolution: {integrity: sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==} + + '@npmcli/node-gyp@1.0.3': + resolution: {integrity: sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==} + + '@npmcli/node-gyp@3.0.0': + resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/package-json@1.0.1': + resolution: {integrity: sha512-y6jnu76E9C23osz8gEMBayZmaZ69vFOIk8vR1FJL/wbEJ54+9aVG9rLTjQKSXfgYZEr50nw1txBBFfBZZe+bYg==} + + '@npmcli/promise-spawn@1.3.2': + resolution: {integrity: sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==} + + '@npmcli/promise-spawn@6.0.2': + resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/run-script@2.0.0': + resolution: {integrity: sha512-fSan/Pu11xS/TdaTpTB0MRn9guwGU8dye+x56mEVgBEd/QsybBbYcAL0phPXi8SGWFEChkQd6M9qL4y6VOpFig==} + + '@npmcli/run-script@6.0.2': + resolution: {integrity: sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@octokit/auth-token@2.5.0': + resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} + + '@octokit/core@3.6.0': + resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} + + '@octokit/endpoint@6.0.12': + resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} + + '@octokit/graphql@4.8.0': + resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} + + '@octokit/openapi-types@12.11.0': + resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==} + + '@octokit/plugin-paginate-rest@2.21.3': + resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} + peerDependencies: + '@octokit/core': '>=2' + + '@octokit/plugin-request-log@1.0.4': + resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/plugin-rest-endpoint-methods@5.16.2': + resolution: {integrity: sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/request-error@2.1.0': + resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} + + '@octokit/request@5.6.3': + resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} + + '@octokit/rest@18.12.0': + resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} + + '@octokit/types@6.41.0': + resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} + '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} @@ -4652,6 +4990,22 @@ packages: rollup: optional: true + '@sigstore/bundle@1.1.0': + resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.2.1': + resolution: {integrity: sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/sign@1.0.0': + resolution: {integrity: sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/tuf@1.0.3': + resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -4778,6 +5132,10 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@tootallnate/once@1.1.2': + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -4798,6 +5156,14 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tufjs/canonical-json@1.0.0': + resolution: {integrity: sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@tufjs/models@1.0.4': + resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@turf/area@7.2.0': resolution: {integrity: sha512-zuTTdQ4eoTI9nSSjerIy4QwgvxqwJVciQJ8tOPuMHbXJ9N/dNjI7bU8tasjhxas/Cx3NE9NxVHtNpYHL0FSzoA==} @@ -4831,12 +5197,21 @@ packages: '@types/big.js@6.2.2': resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + '@types/cheerio@0.22.35': resolution: {integrity: sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/conventional-commits-parser@5.0.1': resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@types/cross-zip@4.0.2': resolution: {integrity: sha512-yvTQ6/tWlGdykh6qkVigwmq42gi51qHPdi7e60KRmPCxeYj5QcX8RX0T6jCDIWcHNWLMVw1IuoMehGcwDuzrYw==} @@ -4861,6 +5236,15 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/expect@1.20.4': + resolution: {integrity: sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==} + + '@types/express-serve-static-core@5.1.0': + resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} + + '@types/express@5.0.6': + resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} + '@types/fs-extra@8.1.5': resolution: {integrity: sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==} @@ -4879,6 +5263,9 @@ packages: '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -4891,9 +5278,6 @@ packages: '@types/jest@29.4.0': resolution: {integrity: sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==} - '@types/jest@30.0.0': - resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} - '@types/js-beautify@1.14.3': resolution: {integrity: sha512-FMbQHz+qd9DoGvgLHxeqqVPaNRffpIu5ZjozwV8hf9JAGpIOzuAf4wGbRSo8LNITHqGjmmVjaMggTT5P4v4IHg==} @@ -4936,6 +5320,9 @@ packages: '@types/node@22.14.1': resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/pbf@3.0.5': resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==} @@ -4948,6 +5335,12 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/rc-slider@8.6.6': resolution: {integrity: sha512-2Q3vwKrSm3PbgiMNwzxMkOaMtcAGi0xQ8WPeVKoabk1vNYHiVR44DMC3mr9jC2lhbxCBgGBJWF9sBhmnSDQ8Bg==} @@ -4996,6 +5389,12 @@ packages: '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-static@2.2.0': + resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} + '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -5011,6 +5410,9 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/vinyl@2.0.12': + resolution: {integrity: sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==} + '@types/warning@3.0.3': resolution: {integrity: sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==} @@ -5299,6 +5701,9 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -5314,6 +5719,10 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} @@ -5350,6 +5759,14 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -5358,6 +5775,14 @@ packages: ajv: optional: true + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-keywords@5.1.0: resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: @@ -5412,6 +5837,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + archiver-utils@2.1.0: resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} engines: {node: '>= 6'} @@ -5420,6 +5848,16 @@ packages: resolution: {integrity: sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==} engines: {node: '>= 6'} + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -5447,6 +5885,10 @@ packages: resolution: {integrity: sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==} engines: {node: '>=0.10.0'} + array-differ@3.0.0: + resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} + engines: {node: '>=8'} + array-find-index@1.0.2: resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} engines: {node: '>=0.10.0'} @@ -5507,6 +5949,10 @@ packages: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -5524,6 +5970,9 @@ packages: async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5600,6 +6049,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-arraybuffer@1.0.2: resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} engines: {node: '>= 0.6.0'} @@ -5611,12 +6064,19 @@ packages: resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} hasBin: true + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bin-links@3.0.3: + resolution: {integrity: sha512-zKdnMPWEdh4F5INR07/eBrodC7QrF5JKvqskjz/ZZRXg5YSAZIbn8zGhbhUrElzHBZ2fvEQdOU59RHcTG3GiwA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -5624,6 +6084,10 @@ packages: binary-search-bounds@2.0.5: resolution: {integrity: sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==} + binaryextensions@4.19.0: + resolution: {integrity: sha512-DRxnVbOi/1OgA5pA9EDiRT8gvVYeqfuN7TmPfLyt6cyho3KbHCi3EtDQf39TTmGDrR5dZ9CspdXhPkL/j/WGbg==} + engines: {node: '>=0.8'} + bit-twiddle@1.0.2: resolution: {integrity: sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==} @@ -5636,6 +6100,10 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -5645,6 +6113,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.3: + resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -5679,6 +6151,28 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtins@1.0.3: + resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + + cacache@16.1.3: + resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -5742,6 +6236,9 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + cheerio-select@1.6.0: resolution: {integrity: sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==} @@ -5763,6 +6260,10 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + chrome-launcher@0.15.2: resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} engines: {node: '>=12.13.0'} @@ -5795,6 +6296,10 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -5803,6 +6308,14 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-table@0.3.11: + resolution: {integrity: sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==} + engines: {node: '>= 0.2.0'} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -5814,18 +6327,36 @@ packages: resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} engines: {node: '>=20'} + clone-buffer@1.0.0: + resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} + engines: {node: '>= 0.10'} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} + clone-stats@1.0.0: + resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + cloneable-readable@1.1.3: + resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cmd-shim@5.0.0: + resolution: {integrity: sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -5873,6 +6404,10 @@ packages: color-space@2.3.2: resolution: {integrity: sha512-BcKnbOEsOarCwyoLstcoEztwT0IJxqqQkNwDuA3a65sICvvHL2yoeV13psoDFh5IuiOMnIOKdQDwB4Mk3BypiA==} + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -5882,6 +6417,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colors@1.0.3: + resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} + engines: {node: '>=0.1.90'} + colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} @@ -5901,6 +6440,10 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@7.1.0: + resolution: {integrity: sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==} + engines: {node: '>= 10'} + commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -5909,9 +6452,16 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + commenting@1.1.0: resolution: {integrity: sha512-YeNK4tavZwtH7jEgK1ZINXzLKm6DZdEMfsaaieOsCAN0S8vsY7UeuO3Q7d/M018EFgE+IeUAuBOKkFccBZsUZA==} + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -5950,6 +6500,17 @@ packages: resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} engines: {node: '>= 0.10.0'} + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + conventional-changelog-angular@7.0.0: resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} engines: {node: '>=16'} @@ -5966,6 +6527,14 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + copy-and-watch@0.1.8: resolution: {integrity: sha512-Prw3k4Za+C/m/OutNtjy1+7Fq+JTiryrFc5JiR0wRrYQ+yPUnsXV8DNPna7plzEcmNbm8x87fqegp9+ogNqKNQ==} engines: {node: '>=10'} @@ -5986,6 +6555,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + cosmiconfig-typescript-loader@6.2.0: resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} engines: {node: '>=v18'} @@ -6194,6 +6767,10 @@ packages: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} + dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + dargs@8.1.0: resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} engines: {node: '>=12'} @@ -6230,6 +6807,9 @@ packages: date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dayjs@1.11.18: resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} @@ -6258,6 +6838,10 @@ packages: supports-color: optional: true + debuglog@1.0.1: + resolution: {integrity: sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} @@ -6306,10 +6890,16 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -6342,6 +6932,9 @@ packages: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6350,6 +6943,10 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + diff@5.2.2: + resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -6463,6 +7060,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + electron-to-chromium@1.5.237: resolution: {integrity: sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==} @@ -6497,6 +7099,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -6540,6 +7145,9 @@ packages: enzyme@3.11.0: resolution: {integrity: sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -6550,6 +7158,9 @@ packages: error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + error@10.4.0: + resolution: {integrity: sha512-YxIFEJuhgcICugOUvRx5th0UM+ActZ9sjY0QJmeVwsQdvosZ7kYzc9QqS0Da3R5iUmgU5meGIxh0xBeZpMVeLw==} + es-abstract@1.24.0: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} @@ -6605,6 +7216,11 @@ packages: es6-weak-map@2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6863,6 +7479,14 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -6879,13 +7503,19 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - expect@30.2.0: - resolution: {integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + express-rate-limit@7.5.1: + resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} @@ -6943,6 +7573,10 @@ packages: picomatch: optional: true + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6955,6 +7589,10 @@ packages: resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} engines: {node: '>= 12'} + filelist@1.0.5: + resolution: {integrity: sha512-ct/ckWBV/9Dg3MlvCXsLcSUyoWwv9mCKqlhLNB2DAuXR/NZolSXlQqP5dyy6guWlPXBhodZyZ5lGPQcbQDxrEQ==} + engines: {node: 20 || >=22} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -6963,6 +7601,10 @@ packages: resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-free-port@2.0.0: resolution: {integrity: sha512-J1j8gfEVf5FN4PR5w5wrZZ7NYs2IvqsHcd03cAeQx3Ec/mo+lKceaVNhpsRKoZpZKbId88o8qh+dwUwzBV6WCg==} @@ -6978,6 +7620,13 @@ packages: resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} engines: {node: '>=18'} + find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + + first-chunk-stream@2.0.0: + resolution: {integrity: sha512-X8Z+b/0L4lToKYq+lwnKqi9X/Zek0NibLpsJgVsSxpoYq7JtiCtRb5HqKVEjEw/qAb/4AKKRLOwwKHlWNpm2Eg==} + engines: {node: '>=0.10.0'} + flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -7017,10 +7666,18 @@ packages: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} @@ -7035,6 +7692,14 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -7061,6 +7726,16 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + generator-function@2.0.1: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} @@ -7109,6 +7784,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + git-hooks-list@4.1.1: resolution: {integrity: sha512-cmP497iLq54AZnv4YRAEMnEyQ1eIn4tGKbmswqwmFV4GBnAqE8NLtWxxdXa++AalfgL5EBH4IxTPyquEuGY/jA==} @@ -7120,6 +7798,10 @@ packages: github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + github-username@6.0.0: + resolution: {integrity: sha512-7TTrRjxblSI5l6adk9zd+cV5d6i1OrJSo3Vr9xdGqFLBQo0mz5P9eIfKCDJ7eekVGGFLbce0qbPSnktXV2BjDQ==} + engines: {node: '>=10'} + gl-mat4@1.2.0: resolution: {integrity: sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA==} @@ -7157,6 +7839,11 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + glob@9.3.5: resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} engines: {node: '>=16 || 14 >=14.17'} @@ -7259,6 +7946,10 @@ packages: grid-index@1.1.0: resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==} + grouped-queue@2.1.0: + resolution: {integrity: sha512-c5NDCWO0XiXuJAhOegMiNotkDmgORN+VNo3+YHMhWpoWG/u2+8im8byqsOe3/myI9YcC//plRdqGa2AE3Qsdjw==} + engines: {node: '>=8.0.0'} + handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} @@ -7304,6 +7995,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + has@1.0.4: resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} engines: {node: '>= 0.4.0'} @@ -7324,6 +8018,21 @@ packages: hoist-non-react-statics@2.5.5: resolution: {integrity: sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==} + hono@4.11.3: + resolution: {integrity: sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==} + engines: {node: '>=16.9.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@6.1.3: + resolution: {integrity: sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + html-element-map@1.3.1: resolution: {integrity: sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==} @@ -7340,10 +8049,21 @@ packages: htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} @@ -7360,6 +8080,9 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + husky@8.0.3: resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} engines: {node: '>=14'} @@ -7373,6 +8096,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.1: + resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} + engines: {node: '>=0.10.0'} + icss-replace-symbols@1.1.0: resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} @@ -7389,6 +8116,14 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore-walk@4.0.1: + resolution: {integrity: sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw==} + engines: {node: '>=10'} + + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} @@ -7440,6 +8175,9 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -7458,6 +8196,10 @@ packages: resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} + engines: {node: '>=12.0.0'} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -7473,9 +8215,17 @@ packages: invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + ip@2.0.1: resolution: {integrity: sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + is-arguments@1.2.0: resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} engines: {node: '>= 0.4'} @@ -7567,6 +8317,9 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -7604,6 +8357,10 @@ packages: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -7616,9 +8373,16 @@ packages: resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} engines: {node: '>=0.10.0'} + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} @@ -7626,6 +8390,10 @@ packages: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-scoped@2.1.0: + resolution: {integrity: sha512-Cv4OpPTHAK9kHYzkzCrof3VJh7H/PrG2MBUMvvJebaaUMbqhm0YAtXnvh0I3Hnj2tMZWwrRROWLSgfJrKqWmlQ==} + engines: {node: '>=8'} + is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} @@ -7667,6 +8435,9 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -7692,6 +8463,14 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isbinaryfile@4.0.10: + resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} + engines: {node: '>= 8.0.0'} + + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} + engines: {node: '>= 18.0.0'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -7738,6 +8517,11 @@ packages: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + jasmine-core@3.99.1: resolution: {integrity: sha512-Hu1dmuoGcZ7AfyynN3LsfruwMbxMALMka+YtZeGoLuDEySVmVAPaonkNoBRIw/ectu8b9tVQCJNgp4a4knp+tg==} @@ -7782,10 +8566,6 @@ packages: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-diff@30.2.0: - resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-docblock@29.7.0: resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7831,26 +8611,14 @@ packages: resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-matcher-utils@30.2.0: - resolution: {integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-message-util@29.7.0: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-message-util@30.2.0: - resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-mock@29.7.0: resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-mock@30.2.0: - resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} @@ -7929,6 +8697,9 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -7975,15 +8746,25 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-nice@1.1.4: + resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==} + json-stringify-pretty-compact@4.0.0: resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==} @@ -8020,6 +8801,12 @@ packages: resolution: {integrity: sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==} engines: {node: '>=0.10.0'} + just-diff-apply@5.5.0: + resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==} + + just-diff@5.2.0: + resolution: {integrity: sha512-6ufhP9SHjb7jibNFrNxyFZ6od3g+An6Ai9mhGRvcYe8UJlH0prseN64M+6ZBBUoKYHZsitDP42gAJ8+eVWr3lw==} + katex@0.16.25: resolution: {integrity: sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==} hasBin: true @@ -8083,6 +8870,10 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + loader-runner@4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -8195,6 +8986,14 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + luxon@3.7.2: resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} @@ -8226,6 +9025,18 @@ packages: make-event-props@1.6.2: resolution: {integrity: sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==} + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + make-fetch-happen@9.1.0: + resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} + engines: {node: '>= 10'} + makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -8271,6 +9082,23 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + mem-fs-editor@9.7.0: + resolution: {integrity: sha512-ReB3YD24GNykmu4WeUL/FDIQtkoyGB6zfJv60yfCo3QjKeimNcTqv2FT83bP0ccs6uu+sm5zyoBlspAzigmsdg==} + engines: {node: '>=12.10.0'} + peerDependencies: + mem-fs: ^2.1.0 + peerDependenciesMeta: + mem-fs: + optional: true + + mem-fs@2.3.0: + resolution: {integrity: sha512-GftCCBs6EN8sz3BoWO1bCj8t7YBtT713d8bUgbhg9Iel5kFSqnSvCK06TYIDJAtJ51cSiWkM/YemlT0dfoFycw==} + engines: {node: '>=12'} + memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -8287,6 +9115,10 @@ packages: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-refs@1.3.0: resolution: {integrity: sha512-nqXPXbso+1dcKDpPCXvwZyJILz+vSLqGGOnDrYHQYE+B8n9JTCekVLC65AfCpR4ggVyA/45Y0iR9LDyS2iI+zA==} peerDependencies: @@ -8374,10 +9206,18 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -8419,9 +9259,21 @@ packages: resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} + minimatch@10.2.2: + resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.4: resolution: {integrity: sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@7.4.7: + resolution: {integrity: sha512-t3SrsBRdssa8F/nFEadAxveFpnbhlbq7FiizzOMqx69w9EbmNEzcKiPkc60udvrOkWsTMm6jmnQP1c5rbdVfSA==} + engines: {node: '>=10'} + minimatch@8.0.4: resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} engines: {node: '>=16 || 14 >=14.17'} @@ -8437,20 +9289,67 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@1.4.1: + resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} + engines: {node: '>=8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-json-stream@1.0.2: + resolution: {integrity: sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + minipass@4.2.8: resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} engines: {node: '>=8'} + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp-infer-owner@2.0.0: + resolution: {integrity: sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==} + engines: {node: '>=10'} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -8510,9 +9409,20 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multimatch@5.0.0: + resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} + engines: {node: '>=10'} + murmurhash-js@1.0.0: resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==} + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mylas@2.1.14: + resolution: {integrity: sha512-BzQguy9W9NJgoVn2mRWzbFrFWWztGCcng2QI9+41frfk+Athwgx3qhqhvStz7ExeUUu7Kzw427sNzHpEZNINog==} + engines: {node: '>=16.0.0'} + nanoevents@9.1.0: resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8547,6 +9457,10 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -8569,17 +9483,44 @@ packages: encoding: optional: true + node-gyp@8.4.1: + resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} + engines: {node: '>= 10.12.0'} + hasBin: true + + node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} node-releases@2.0.23: resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + nopt@7.2.1: resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@5.0.0: + resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -8594,10 +9535,77 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + npm-bundled@1.1.2: + resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} + + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-install-checks@4.0.0: + resolution: {integrity: sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==} + engines: {node: '>=10'} + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@1.0.1: + resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} + + npm-normalize-package-bin@2.0.0: + resolution: {integrity: sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@10.1.0: + resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@8.1.5: + resolution: {integrity: sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==} + engines: {node: '>=10'} + + npm-packlist@3.0.0: + resolution: {integrity: sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ==} + engines: {node: '>=10'} + hasBin: true + + npm-packlist@7.0.4: + resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@6.1.1: + resolution: {integrity: sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==} + + npm-pick-manifest@8.0.2: + resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-registry-fetch@12.0.2: + resolution: {integrity: sha512-Df5QT3RaJnXYuOwtXBXS9BWs+tHH2olvkCLh6jcR/b/u3DvPMlp3J0TvvYwplPKxHMOwfg287PYih9QqaVFoKA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} + + npm-registry-fetch@14.0.5: + resolution: {integrity: sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -8716,6 +9724,10 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -8724,6 +9736,10 @@ packages: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} + p-transform@1.3.0: + resolution: {integrity: sha512-UJKdSzgd3KOnXXAtqN5+/eeHcvTn1hBkesEmElVgvO/NAYcxAvmjzIGmnNd3Tb/gRAvMBdNRFD4qAWdHxY6QXg==} + engines: {node: '>=12.10.0'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -8740,6 +9756,16 @@ packages: resolution: {integrity: sha512-gFL35q7kbE/zBaPA3UKhp2vSzcPYx2ecbYuwv1ucE9Il6IIgBDweBlH8D68UFGZic2MkllKa2KHCfC1IQBQUYA==} engines: {node: '>=12'} + pacote@12.0.3: + resolution: {integrity: sha512-CdYEl03JDrRO3x18uHjBYA9TyoW8gy+ThVcypcDkxPtKlw76e4ejhYB6i9lJ+/cebbjpqPW/CijjqxwDTts8Ow==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} + hasBin: true + + pacote@15.2.0: + resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -8753,6 +9779,10 @@ packages: parenthesis@3.1.8: resolution: {integrity: sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==} + parse-conflict-json@2.0.2: + resolution: {integrity: sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -8806,6 +9836,9 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -8848,6 +9881,10 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + pify@5.0.0: resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} engines: {node: '>=10'} @@ -8856,6 +9893,10 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -8873,6 +9914,10 @@ packages: engines: {node: '>=18'} hasBin: true + plimit-lit@1.6.1: + resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} + engines: {node: '>=12'} + plotly.js-dist-min@3.1.1: resolution: {integrity: sha512-eyuiESylUXW4kaF+v9J2gy9eZ+YT2uSVLILM4w1Afxnuv9u4UX9OnZnHR1OdF9ybq4x7+9chAzWUUbQ6HvBb3g==} @@ -9136,7 +10181,11 @@ packages: engines: {node: '>=10'} hasBin: true - prelude-ls@1.2.1: + preferred-pm@3.1.4: + resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==} + engines: {node: '>=10'} + + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -9157,6 +10206,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -9165,10 +10218,6 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-format@30.2.0: - resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - pretty-quick@4.2.2: resolution: {integrity: sha512-uAh96tBW1SsD34VhhDmWuEmqbpfYc/B3j++5MC/6b3Cb8Ow7NJsvKFhg0eoGu2xXX+o9RkahkTK6sUdd8E7g5w==} engines: {node: '>=14'} @@ -9179,13 +10228,42 @@ packages: probe-image-size@7.2.3: resolution: {integrity: sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==} + proc-log@1.0.0: + resolution: {integrity: sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promise-all-reject-late@1.0.1: + resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==} + + promise-call-limit@1.0.2: + resolution: {integrity: sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA==} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + promise.series@0.2.0: resolution: {integrity: sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==} engines: {node: '>=0.12'} @@ -9214,6 +10292,10 @@ packages: protocol-buffers-schema@3.6.0: resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} @@ -9239,9 +10321,17 @@ packages: peerDependencies: react: '>=18.0.0 <19.0.0' + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + engines: {node: '>=0.6'} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-lit@1.5.2: + resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} + engines: {node: '>=12'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -9282,6 +10372,10 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -9433,6 +10527,31 @@ packages: read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-cmd-shim@3.0.1: + resolution: {integrity: sha512-kEmDUoYf/CDy8yZbLTmhB1X9kkjf9Q80PCNsDMb7ufrGd6zZSQA1+UyjrO+pZm5K/S4OXCWJeiIt1JA8kAsa6g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + read-package-json-fast@2.0.3: + resolution: {integrity: sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==} + engines: {node: '>=10'} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json@6.0.4: + resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. Please use @npmcli/package-json instead. + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + readable-stream@1.0.34: resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} @@ -9443,6 +10562,14 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-scoped-modules@1.1.0: + resolution: {integrity: sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==} + deprecated: This functionality has been moved to @npmcli/fs + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -9526,6 +10653,13 @@ packages: remove-accents@0.5.0: resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + replace-ext@1.0.1: + resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} + engines: {node: '>= 0.10'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -9549,6 +10683,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve-protobuf-schema@2.1.0: resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} @@ -9576,6 +10713,10 @@ packages: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -9640,9 +10781,17 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + rst-selector-parser@2.2.3: resolution: {integrity: sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==} + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -9653,6 +10802,9 @@ packages: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -9718,6 +10870,14 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + scoped-regex@2.1.0: + resolution: {integrity: sha512-g3WxHrqSWCZHGHlSrF51VXFdjImhwvH8ZO/pryFH56Qi0cDsZfylQa/t0jCzVQFNbNvM00HfHjkDPEuarKDSWQ==} + engines: {node: '>=8'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -9731,6 +10891,10 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + serialize-error@2.1.0: resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} engines: {node: '>=0.10.0'} @@ -9742,6 +10906,13 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -9824,6 +10995,11 @@ packages: signum@1.0.0: resolution: {integrity: sha512-yodFGwcyt59XRh7w5W3jPcIQb3Bwi21suEfT7MAWnBX3iCdklJpgDgvGT9o04UonglZN5SNMfJFkHIR/jO8GHw==} + sigstore@1.9.0: + resolution: {integrity: sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} @@ -9849,9 +11025,29 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + socks-proxy-agent@6.2.1: + resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} + engines: {node: '>= 10'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sort-keys@4.2.0: + resolution: {integrity: sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==} + engines: {node: '>=8'} + sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} @@ -9916,6 +11112,18 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + stable@0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' @@ -9945,6 +11153,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -10013,6 +11225,22 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-bom-buf@1.0.0: + resolution: {integrity: sha512-1sUIL1jck0T1mhOLP2c696BIznzT525Lkub+n4jjMHjhjhoAQA6Ye659DxdlZBr0aLDMQoTxKIpnlqxgtwjsuQ==} + engines: {node: '>=4'} + + strip-bom-stream@2.0.0: + resolution: {integrity: sha512-yH0+mD8oahBZWnY43vxs4pSinn8SMKAdml/EOGBewoe1Y0Eitd0h2Mg3ZRiXruUW6L4P+lvZiEgbh0NgUGia1w==} + engines: {node: '>=0.10.0'} + + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-bom@4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -10123,6 +11351,11 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + terser-webpack-plugin@5.3.14: resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} engines: {node: '>= 10.13.0'} @@ -10155,6 +11388,10 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + textextensions@5.16.0: + resolution: {integrity: sha512-7D/r3s6uPZyU//MCYrX6I14nzauDwJ5CxazouuRGNuvSCihW87ufN6VLoROLCrHg6FblLuJrT6N2BVaPVzqElw==} + engines: {node: '>=0.8'} + throat@5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} @@ -10228,6 +11465,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + treeverse@1.0.4: + resolution: {integrity: sha512-whw60l7r+8ZU8Tu/Uc2yxtc4ZTZbR/PF3u1IPNKGQ6p8EICLb3Z2lAgoqw9bqYd8IkgnsaOcLzYHFckjqNsf0g==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -10286,6 +11526,11 @@ packages: '@swc/wasm': optional: true + tsc-alias@1.8.16: + resolution: {integrity: sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==} + engines: {node: '>=16.20.2'} + hasBin: true + tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -10298,6 +11543,15 @@ packages: peerDependencies: typescript: '>5.8.0' + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + tuf-js@1.1.7: + resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -10351,14 +11605,26 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} @@ -10441,6 +11707,31 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -10460,6 +11751,10 @@ packages: unquote@1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -10504,10 +11799,29 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-name@3.0.0: + resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + validate-npm-package-name@6.0.2: resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} engines: {node: ^18.17.0 || >=20.5.0} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vinyl-file@3.0.0: + resolution: {integrity: sha512-BoJDj+ca3D9xOuPEM6RWVtWQtvEPQiQYn82LvdxhLWplfQsBzBqtgK0yhCP0s1BNTi6dH9BO+dzybvyQIacifg==} + engines: {node: '>=4'} + + vinyl@2.2.1: + resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} + engines: {node: '>= 0.10'} + vlq@0.2.3: resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==} @@ -10524,6 +11838,9 @@ packages: resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} engines: {node: '>=14'} + walk-up-path@1.0.0: + resolution: {integrity: sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -10621,6 +11938,10 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} + which-pm@2.2.0: + resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==} + engines: {node: '>=8.15'} + which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} @@ -10630,11 +11951,19 @@ packages: engines: {node: '>= 8'} hasBin: true + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + which@4.0.0: resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -10648,6 +11977,10 @@ packages: world-calendars@1.0.4: resolution: {integrity: sha512-VGRnLJS+xJmGDPodgJRnGIDwGu0s+Cr9V2HB3EzlDZ5n0qb8h5SJtGUEkjrphZYAglEiXZ6kiXdmk0H/h/uu/w==} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -10744,6 +12077,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -10777,6 +12113,20 @@ packages: resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yeoman-environment@3.19.3: + resolution: {integrity: sha512-/+ODrTUHtlDPRH9qIC0JREH8+7nsRcjDl3Bxn2Xo/rvAaVvixH5275jHwg0C85g4QsF4P6M2ojfScPPAl+pLAg==} + engines: {node: '>=12.10.0'} + hasBin: true + + yeoman-generator@5.10.0: + resolution: {integrity: sha512-iDUKykV7L4nDNzeYSedRmSeJ5eMYFucnKDi6KN1WNASXErgPepKqsQw55TgXPHnmpcyOh2Dd/LAZkyc+f0qaAw==} + engines: {node: '>=12.10.0'} + peerDependencies: + yeoman-environment: ^3.2.0 + peerDependenciesMeta: + yeoman-environment: + optional: true + yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} @@ -10796,9 +12146,17 @@ packages: resolution: {integrity: sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==} engines: {node: '>= 6'} + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + snapshots: '@adobe/css-tools@4.4.4': {} @@ -11932,6 +13290,84 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + '@eslint-community/eslint-utils@4.9.0(eslint@7.32.0)': dependencies: eslint: 7.32.0 @@ -12024,6 +13460,8 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@gar/promisify@1.1.3': {} + '@googlemaps/jest-mocks@2.22.6': {} '@happy-dom/jest-environment@18.0.1': @@ -12037,6 +13475,10 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 + '@hono/node-server@1.19.7(hono@4.11.3)': + dependencies: + hono: 4.11.3 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -12062,6 +13504,13 @@ snapshots: dependencies: react: 18.3.1 + '@inquirer/external-editor@1.0.3(@types/node@22.14.1)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.1 + optionalDependencies: + '@types/node': 22.14.1 + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -12077,6 +13526,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/string-locale-compare@1.1.0': {} + '@isaacs/ttlcache@1.4.1': {} '@istanbuljs/load-nyc-config@1.1.0': @@ -12141,8 +13592,6 @@ snapshots: dependencies: '@jest/types': 30.2.0 - '@jest/diff-sequences@30.0.1': {} - '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -12154,10 +13603,6 @@ snapshots: dependencies: jest-get-type: 29.6.3 - '@jest/expect-utils@30.2.0': - dependencies: - '@jest/get-type': 30.1.0 - '@jest/expect@29.7.0': dependencies: expect: 29.7.0 @@ -12174,8 +13619,6 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - '@jest/get-type@30.1.0': {} - '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 @@ -12392,7 +13835,20 @@ snapshots: '@melloware/coloris@0.25.0': {} - '@mendix/pluggable-widgets-tools@10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1)': + '@mendix/generator-widget@https://codeload.github.com/rahmanunver/widgets-tools/tar.gz/17537779fb5d4cdc72a023251ce51121ea1914cf#path:packages/generator-widget(@types/node@22.14.1)(encoding@0.1.13)(mem-fs@2.3.0)': + dependencies: + chalk: 4.1.2 + semver: 7.7.3 + yeoman-environment: 3.19.3(@types/node@22.14.1) + yeoman-generator: 5.10.0(encoding@0.1.13)(mem-fs@2.3.0)(yeoman-environment@3.19.3(@types/node@22.14.1)) + transitivePeerDependencies: + - '@types/node' + - bluebird + - encoding + - mem-fs + - supports-color + + '@mendix/pluggable-widgets-tools@10.21.2(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(encoding@0.1.13)(jest-util@30.2.0)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.28.4)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1)': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.4) @@ -12453,7 +13909,7 @@ snapshots: mendix: 10.24.75382 metro-react-native-babel-preset: 0.74.1(@babel/core@7.28.4) mime: 3.0.0 - node-fetch: 2.7.0 + node-fetch: 2.7.0(encoding@0.1.13) postcss: 8.5.6 postcss-import: 14.1.0(postcss@8.5.6) postcss-url: 10.1.3(postcss@8.5.6) @@ -12499,6 +13955,28 @@ snapshots: - tslib - utf-8-validate + '@modelcontextprotocol/sdk@1.25.2(hono@4.11.3)(zod@4.3.5)': + dependencies: + '@hono/node-server': 1.19.7(hono@4.11.3) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 7.5.1(express@5.2.1) + jose: 6.1.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.5 + zod-to-json-schema: 3.25.1(zod@4.3.5) + transitivePeerDependencies: + - hono + - supports-color + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12511,25 +13989,256 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@one-ini/wasm@0.1.1': {} + '@npmcli/arborist@4.3.1': + dependencies: + '@isaacs/string-locale-compare': 1.1.0 + '@npmcli/installed-package-contents': 1.0.7 + '@npmcli/map-workspaces': 2.0.4 + '@npmcli/metavuln-calculator': 2.0.0 + '@npmcli/move-file': 1.1.2 + '@npmcli/name-from-folder': 1.0.1 + '@npmcli/node-gyp': 1.0.3 + '@npmcli/package-json': 1.0.1 + '@npmcli/run-script': 2.0.0 + bin-links: 3.0.3 + cacache: 15.3.0 + common-ancestor-path: 1.0.1 + json-parse-even-better-errors: 2.3.1 + json-stringify-nice: 1.1.4 + mkdirp: 1.0.4 + mkdirp-infer-owner: 2.0.0 + npm-install-checks: 4.0.0 + npm-package-arg: 8.1.5 + npm-pick-manifest: 6.1.1 + npm-registry-fetch: 12.0.2 + pacote: 12.0.3 + parse-conflict-json: 2.0.2 + proc-log: 1.0.0 + promise-all-reject-late: 1.0.1 + promise-call-limit: 1.0.2 + read-package-json-fast: 2.0.3 + readdir-scoped-modules: 1.1.0 + rimraf: 3.0.2 + semver: 7.7.3 + ssri: 8.0.1 + treeverse: 1.0.4 + walk-up-path: 1.0.0 + transitivePeerDependencies: + - bluebird + - supports-color - '@parcel/watcher-android-arm64@2.5.1': - optional: true + '@npmcli/fs@1.1.1': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.7.3 - '@parcel/watcher-darwin-arm64@2.5.1': - optional: true + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.7.3 - '@parcel/watcher-darwin-x64@2.5.1': - optional: true + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.7.3 - '@parcel/watcher-freebsd-x64@2.5.1': - optional: true + '@npmcli/git@2.1.0': + dependencies: + '@npmcli/promise-spawn': 1.3.2 + lru-cache: 6.0.0 + mkdirp: 1.0.4 + npm-pick-manifest: 6.1.1 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.7.3 + which: 2.0.2 + transitivePeerDependencies: + - bluebird - '@parcel/watcher-linux-arm-glibc@2.5.1': - optional: true + '@npmcli/git@4.1.0': + dependencies: + '@npmcli/promise-spawn': 6.0.2 + lru-cache: 7.18.3 + npm-pick-manifest: 8.0.2 + proc-log: 3.0.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.7.3 + which: 3.0.1 + transitivePeerDependencies: + - bluebird - '@parcel/watcher-linux-arm-musl@2.5.1': - optional: true + '@npmcli/installed-package-contents@1.0.7': + dependencies: + npm-bundled: 1.1.2 + npm-normalize-package-bin: 1.0.1 + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/map-workspaces@2.0.4': + dependencies: + '@npmcli/name-from-folder': 1.0.1 + glob: 8.1.0 + minimatch: 5.1.6 + read-package-json-fast: 2.0.3 + + '@npmcli/metavuln-calculator@2.0.0': + dependencies: + cacache: 15.3.0 + json-parse-even-better-errors: 2.3.1 + pacote: 12.0.3 + semver: 7.7.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/move-file@1.1.2': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/name-from-folder@1.0.1': {} + + '@npmcli/node-gyp@1.0.3': {} + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/package-json@1.0.1': + dependencies: + json-parse-even-better-errors: 2.3.1 + + '@npmcli/promise-spawn@1.3.2': + dependencies: + infer-owner: 1.0.4 + + '@npmcli/promise-spawn@6.0.2': + dependencies: + which: 3.0.1 + + '@npmcli/run-script@2.0.0': + dependencies: + '@npmcli/node-gyp': 1.0.3 + '@npmcli/promise-spawn': 1.3.2 + node-gyp: 8.4.1 + read-package-json-fast: 2.0.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@npmcli/run-script@6.0.2': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/promise-spawn': 6.0.2 + node-gyp: 9.4.1 + read-package-json-fast: 3.0.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@octokit/auth-token@2.5.0': + dependencies: + '@octokit/types': 6.41.0 + + '@octokit/core@3.6.0(encoding@0.1.13)': + dependencies: + '@octokit/auth-token': 2.5.0 + '@octokit/graphql': 4.8.0(encoding@0.1.13) + '@octokit/request': 5.6.3(encoding@0.1.13) + '@octokit/request-error': 2.1.0 + '@octokit/types': 6.41.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/endpoint@6.0.12': + dependencies: + '@octokit/types': 6.41.0 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@4.8.0(encoding@0.1.13)': + dependencies: + '@octokit/request': 5.6.3(encoding@0.1.13) + '@octokit/types': 6.41.0 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/openapi-types@12.11.0': {} + + '@octokit/plugin-paginate-rest@2.21.3(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/types': 6.41.0 + + '@octokit/plugin-request-log@1.0.4(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + + '@octokit/plugin-rest-endpoint-methods@5.16.2(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/types': 6.41.0 + deprecation: 2.3.1 + + '@octokit/request-error@2.1.0': + dependencies: + '@octokit/types': 6.41.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@5.6.3(encoding@0.1.13)': + dependencies: + '@octokit/endpoint': 6.0.12 + '@octokit/request-error': 2.1.0 + '@octokit/types': 6.41.0 + is-plain-object: 5.0.0 + node-fetch: 2.7.0(encoding@0.1.13) + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/rest@18.12.0(encoding@0.1.13)': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/plugin-paginate-rest': 2.21.3(@octokit/core@3.6.0(encoding@0.1.13)) + '@octokit/plugin-request-log': 1.0.4(@octokit/core@3.6.0(encoding@0.1.13)) + '@octokit/plugin-rest-endpoint-methods': 5.16.2(@octokit/core@3.6.0(encoding@0.1.13)) + transitivePeerDependencies: + - encoding + + '@octokit/types@6.41.0': + dependencies: + '@octokit/openapi-types': 12.11.0 + + '@one-ini/wasm@0.1.1': {} + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true '@parcel/watcher-linux-arm64-glibc@2.5.1': optional: true @@ -12927,6 +14636,27 @@ snapshots: optionalDependencies: rollup: 3.29.5 + '@sigstore/bundle@1.1.0': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + + '@sigstore/protobuf-specs@0.2.1': {} + + '@sigstore/sign@1.0.0': + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@1.0.3': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + tuf-js: 1.1.7 + transitivePeerDependencies: + - supports-color + '@sinclair/typebox@0.27.8': {} '@sinclair/typebox@0.34.41': {} @@ -13035,6 +14765,8 @@ snapshots: dependencies: '@testing-library/dom': 8.20.1 + '@tootallnate/once@1.1.2': {} + '@tootallnate/once@2.0.0': {} '@trysound/sax@0.2.0': {} @@ -13047,6 +14779,13 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tufjs/canonical-json@1.0.0': {} + + '@tufjs/models@1.0.4': + dependencies: + '@tufjs/canonical-json': 1.0.0 + minimatch: 9.0.5 + '@turf/area@7.2.0': dependencies: '@turf/helpers': 7.2.0 @@ -13103,14 +14842,27 @@ snapshots: '@types/big.js@6.2.2': {} + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.14.1 + '@types/cheerio@0.22.35': dependencies: '@types/node': 22.14.1 + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.14.1 + '@types/conventional-commits-parser@5.0.1': dependencies: '@types/node': 22.14.1 + '@types/cors@2.8.19': + dependencies: + '@types/node': 22.14.1 + '@types/cross-zip@4.0.2': {} '@types/date-arithmetic@4.1.4': {} @@ -13136,6 +14888,21 @@ snapshots: '@types/estree@1.0.8': {} + '@types/expect@1.20.4': {} + + '@types/express-serve-static-core@5.1.0': + dependencies: + '@types/node': 22.14.1 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@5.0.6': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 5.1.0 + '@types/serve-static': 2.2.0 + '@types/fs-extra@8.1.5': dependencies: '@types/node': 22.14.1 @@ -13157,6 +14924,8 @@ snapshots: dependencies: '@types/node': 22.14.1 + '@types/http-errors@2.0.5': {} + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -13172,11 +14941,6 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 - '@types/jest@30.0.0': - dependencies: - expect: 30.2.0 - pretty-format: 30.2.0 - '@types/js-beautify@1.14.3': {} '@types/jsdom@20.0.1': @@ -13223,6 +14987,8 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/normalize-package-data@2.4.4': {} + '@types/pbf@3.0.5': {} '@types/plotly.js-dist-min@2.3.4': @@ -13233,6 +14999,10 @@ snapshots: '@types/prop-types@15.7.15': {} + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + '@types/rc-slider@8.6.6': dependencies: '@types/rc-tooltip': 3.7.14 @@ -13299,6 +15069,15 @@ snapshots: '@types/semver@7.7.1': {} + '@types/send@1.2.1': + dependencies: + '@types/node': 22.14.1 + + '@types/serve-static@2.2.0': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 22.14.1 + '@types/stack-utils@2.0.3': {} '@types/supercluster@7.1.3': @@ -13307,13 +15086,18 @@ snapshots: '@types/testing-library__jest-dom@5.14.9': dependencies: - '@types/jest': 30.0.0 + '@types/jest': 29.4.0 '@types/tough-cookie@4.0.5': {} '@types/trusted-types@2.0.7': optional: true + '@types/vinyl@2.0.12': + dependencies: + '@types/expect': 1.20.4 + '@types/node': 22.14.1 + '@types/warning@3.0.3': {} '@types/whatwg-mimetype@3.0.2': {} @@ -13703,6 +15487,8 @@ snapshots: abab@2.0.6: {} + abbrev@1.1.1: {} + abbrev@2.0.0: {} abort-controller@3.0.0: @@ -13716,6 +15502,11 @@ snapshots: mime-types: 2.1.35(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) negotiator: 0.6.3 + accepts@2.0.0: + dependencies: + mime-types: 3.0.2(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) + negotiator: 1.0.0 + acorn-globals@7.0.1: dependencies: acorn: 8.15.0 @@ -13749,10 +15540,23 @@ snapshots: agent-base@7.1.4: {} + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + ajv-keywords@5.1.0(ajv@8.17.1): dependencies: ajv: 8.17.1 @@ -13803,6 +15607,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + aproba@2.1.0: {} + archiver-utils@2.1.0: dependencies: glob: 7.2.3 @@ -13826,6 +15632,16 @@ snapshots: tar-stream: 2.2.0 zip-stream: 2.1.3 + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + arg@4.1.3: {} argparse@1.0.10: @@ -13849,6 +15665,8 @@ snapshots: array-differ@1.0.0: {} + array-differ@3.0.0: {} + array-find-index@1.0.2: {} array-ify@1.0.0: {} @@ -13932,6 +15750,8 @@ snapshots: arrify@1.0.1: {} + arrify@2.0.1: {} + asap@2.0.6: {} astral-regex@2.0.0: {} @@ -13944,6 +15764,8 @@ snapshots: dependencies: lodash: 4.17.23 + async@3.2.6: {} + asynckit@0.4.0: {} at-least-node@1.0.0: {} @@ -14055,20 +15877,35 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-arraybuffer@1.0.2: {} base64-js@1.5.1: {} baseline-browser-mapping@2.8.16: {} + before-after-hook@2.2.3: {} + big.js@5.2.2: {} big.js@6.2.2: {} + bin-links@3.0.3: + dependencies: + cmd-shim: 5.0.0 + mkdirp-infer-owner: 2.0.0 + npm-normalize-package-bin: 2.0.0 + read-cmd-shim: 3.0.1 + rimraf: 3.0.2 + write-file-atomic: 4.0.2 + binary-extensions@2.3.0: {} binary-search-bounds@2.0.5: {} + binaryextensions@4.19.0: {} + bit-twiddle@1.0.2: {} bitmap-sdf@1.0.4: {} @@ -14084,6 +15921,20 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.0 + iconv-lite: 0.7.1 + on-finished: 2.4.1 + qs: 6.14.1 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + boolbase@1.0.0: {} brace-expansion@1.1.12: @@ -14095,6 +15946,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.3: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -14131,6 +15986,76 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtins@1.0.3: {} + + bytes@3.1.2: {} + + cacache@15.3.0: + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.2.1 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + cacache@17.1.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 7.18.3 + minipass: 7.1.2 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -14197,6 +16122,8 @@ snapshots: char-regex@1.0.2: {} + chardet@2.1.1: {} + cheerio-select@1.6.0: dependencies: css-select: 4.3.0 @@ -14238,6 +16165,8 @@ snapshots: chownr@1.1.4: optional: true + chownr@2.0.0: {} + chrome-launcher@0.15.2: dependencies: '@types/node': 22.14.1 @@ -14264,7 +16193,8 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.1: {} + ci-info@4.3.1: + optional: true cjs-module-lexer@1.4.3: {} @@ -14272,12 +16202,20 @@ snapshots: classnames@2.5.1: {} + clean-stack@2.2.0: {} + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 cli-spinners@2.9.2: {} + cli-table@0.3.11: + dependencies: + colors: 1.0.3 + + cli-width@3.0.0: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -14296,16 +16234,32 @@ snapshots: strip-ansi: 7.1.2 wrap-ansi: 9.0.2 + clone-buffer@1.0.0: {} + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 kind-of: 6.0.3 shallow-clone: 3.0.1 + clone-stats@1.0.0: {} + clone@1.0.4: {} + clone@2.1.2: {} + + cloneable-readable@1.1.3: + dependencies: + inherits: 2.0.4 + process-nextick-args: 2.0.1 + readable-stream: 2.3.8 + clsx@2.1.1: {} + cmd-shim@5.0.0: + dependencies: + mkdirp-infer-owner: 2.0.0 + co@4.6.0: {} codemirror@6.0.2: @@ -14366,12 +16320,16 @@ snapshots: color-space@2.3.2: {} + color-support@1.1.3: {} + colord@2.9.3: {} colorette@1.4.0: {} colorette@2.0.20: {} + colors@1.0.3: {} + colors@1.4.0: {} combined-stream@1.0.8: @@ -14384,12 +16342,18 @@ snapshots: commander@2.20.3: {} + commander@7.1.0: {} + commander@7.2.0: {} commander@8.3.0: {} + commander@9.5.0: {} + commenting@1.1.0: {} + common-ancestor-path@1.0.1: {} + commondir@1.0.1: {} compare-func@2.0.0: @@ -14446,6 +16410,12 @@ snapshots: transitivePeerDependencies: - supports-color + console-control-strings@1.1.0: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + conventional-changelog-angular@7.0.0: dependencies: compare-func: 2.0.0 @@ -14463,6 +16433,10 @@ snapshots: convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + copy-and-watch@0.1.8: dependencies: chokidar: 3.6.0 @@ -14488,6 +16462,11 @@ snapshots: core-util-is@1.0.3: {} + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + cosmiconfig-typescript-loader@6.2.0(@types/node@22.14.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): dependencies: '@types/node': 22.14.1 @@ -14725,6 +16704,8 @@ snapshots: es5-ext: 0.10.64 type: 2.7.3 + dargs@7.0.0: {} + dargs@8.1.0: {} data-urls@3.0.2: @@ -14763,6 +16744,8 @@ snapshots: date-fns@4.1.0: {} + dateformat@4.6.3: {} + dayjs@1.11.18: {} debug@2.6.9: @@ -14777,6 +16760,8 @@ snapshots: dependencies: ms: 2.1.3 + debuglog@1.0.1: {} + decimal.js@10.6.0: {} decompress-response@6.0.0: @@ -14807,8 +16792,7 @@ snapshots: which-collection: 1.0.2 which-typed-array: 1.1.19 - deep-extend@0.6.0: - optional: true + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -14834,8 +16818,12 @@ snapshots: delayed-stream@1.0.0: {} + delegates@1.0.0: {} + depd@2.0.0: {} + deprecation@2.3.1: {} + dequal@2.0.3: {} destroy@1.2.0: {} @@ -14854,10 +16842,17 @@ snapshots: detect-newline@4.0.1: {} + dezalgo@1.0.4: + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + diff-sequences@29.6.3: {} diff@4.0.2: {} + diff@5.2.2: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -14994,6 +16989,10 @@ snapshots: ee-first@1.1.1: {} + ejs@3.1.10: + dependencies: + jake: 10.9.4 + electron-to-chromium@1.5.237: {} element-size@1.1.1: {} @@ -15016,6 +17015,11 @@ snapshots: encodeurl@2.0.0: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -15077,6 +17081,8 @@ snapshots: rst-selector-parser: 2.2.3 string.prototype.trim: 1.2.10 + err-code@2.0.3: {} + errno@0.1.8: dependencies: prr: 1.0.1 @@ -15089,6 +17095,8 @@ snapshots: dependencies: stackframe: 1.3.4 + error@10.4.0: {} + es-abstract@1.24.0: dependencies: array-buffer-byte-length: 1.0.2 @@ -15231,6 +17239,35 @@ snapshots: es6-iterator: 2.0.3 es6-symbol: 3.1.4 + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -15558,6 +17595,12 @@ snapshots: events@3.3.0: {} + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -15583,25 +17626,53 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - expect@30.2.0: - dependencies: - '@jest/expect-utils': 30.2.0 - '@jest/get-type': 30.1.0 - jest-matcher-utils: 30.2.0 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - exponential-backoff@3.1.3: {} - ext@1.7.0: + express-rate-limit@7.5.1(express@5.2.1): dependencies: - type: 2.7.3 + express: 5.2.1 - falafel@2.2.5: + express@5.2.1: dependencies: - acorn: 7.4.1 - isarray: 2.0.5 + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.2(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.1 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.1 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext@1.7.0: + dependencies: + type: 2.7.3 + + falafel@2.2.5: + dependencies: + acorn: 7.4.1 + isarray: 2.0.5 fast-deep-equal@3.1.3: {} @@ -15647,6 +17718,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -15659,6 +17734,10 @@ snapshots: dependencies: tslib: 2.8.1 + filelist@1.0.5: + dependencies: + minimatch: 10.2.2 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -15675,6 +17754,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + find-free-port@2.0.0: {} find-up@4.1.0: @@ -15693,6 +17783,15 @@ snapshots: path-exists: 5.0.0 unicorn-magic: 0.1.0 + find-yarn-workspace-root2@1.2.16: + dependencies: + micromatch: 4.0.8 + pkg-dir: 4.2.0 + + first-chunk-stream@2.0.0: + dependencies: + readable-stream: 2.3.8 + flat-cache@3.2.0: dependencies: flatted: 3.3.3 @@ -15739,8 +17838,12 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) + forwarded@0.2.0: {} + fresh@0.5.2: {} + fresh@2.0.0: {} + from2@2.3.0: dependencies: inherits: 2.0.4 @@ -15761,6 +17864,14 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -15784,6 +17895,29 @@ snapshots: functions-have-names@1.2.3: {} + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + gauge@4.0.4: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + generator-function@2.0.1: {} generic-names@4.0.0: @@ -15830,6 +17964,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + git-hooks-list@4.1.1: {} git-raw-commits@4.0.0: @@ -15841,6 +17979,12 @@ snapshots: github-from-package@0.0.0: optional: true + github-username@6.0.0(encoding@0.1.13): + dependencies: + '@octokit/rest': 18.12.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + gl-mat4@1.2.0: {} gl-matrix@3.4.4: {} @@ -15912,6 +18056,14 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + glob@9.3.5: dependencies: fs.realpath: 1.0.0 @@ -16062,6 +18214,8 @@ snapshots: grid-index@1.1.0: {} + grouped-queue@2.1.0: {} + handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -16107,6 +18261,8 @@ snapshots: dependencies: has-symbols: 1.1.0 + has-unicode@2.0.1: {} + has@1.0.4: {} hasown@2.0.2: @@ -16123,6 +18279,18 @@ snapshots: hoist-non-react-statics@2.5.5: {} + hono@4.11.3: {} + + hosted-git-info@2.8.9: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@6.1.3: + dependencies: + lru-cache: 7.18.3 + html-element-map@1.3.1: dependencies: array.prototype.filter: 1.0.4 @@ -16148,6 +18316,8 @@ snapshots: domutils: 2.8.0 entities: 2.2.0 + http-cache-semantics@4.2.0: {} + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -16156,6 +18326,22 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-proxy-agent@4.0.1: + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 @@ -16180,6 +18366,10 @@ snapshots: human-signals@2.1.0: {} + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + husky@8.0.3: {} iconv-lite@0.4.24: @@ -16190,6 +18380,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.1: + dependencies: + safer-buffer: 2.1.2 + icss-replace-symbols@1.1.0: {} icss-utils@5.1.0(postcss@8.5.6): @@ -16202,6 +18396,14 @@ snapshots: ieee754@1.2.1: {} + ignore-walk@4.0.1: + dependencies: + minimatch: 3.1.4 + + ignore-walk@6.0.5: + dependencies: + minimatch: 9.0.5 + ignore@4.0.6: {} ignore@5.3.2: {} @@ -16240,6 +18442,8 @@ snapshots: indent-string@4.0.0: {} + infer-owner@1.0.4: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -16253,6 +18457,26 @@ snapshots: ini@4.1.3: {} + inquirer@8.2.7(@types/node@22.14.1): + dependencies: + '@inquirer/external-editor': 1.0.3(@types/node@22.14.1) + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + figures: 3.2.0 + lodash: 4.17.23 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -16267,8 +18491,12 @@ snapshots: dependencies: loose-envify: 1.4.0 + ip-address@10.1.0: {} + ip@2.0.1: {} + ipaddr.js@1.9.1: {} + is-arguments@1.2.0: dependencies: call-bound: 1.0.4 @@ -16354,6 +18582,8 @@ snapshots: is-interactive@1.0.0: {} + is-lambda@1.0.1: {} + is-map@2.0.3: {} is-mobile@4.0.0: {} @@ -16377,6 +18607,8 @@ snapshots: is-plain-obj@1.1.0: {} + is-plain-obj@2.1.0: {} + is-plain-obj@4.1.0: {} is-plain-object@2.0.4: @@ -16385,8 +18617,12 @@ snapshots: is-plain-object@3.0.1: {} + is-plain-object@5.0.0: {} + is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} + is-reference@1.2.1: dependencies: '@types/estree': 1.0.8 @@ -16398,6 +18634,10 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-scoped@2.1.0: + dependencies: + scoped-regex: 2.1.0 + is-set@2.0.3: {} is-shared-array-buffer@1.0.4: @@ -16433,6 +18673,8 @@ snapshots: is-unicode-supported@0.1.0: {} + is-utf8@0.2.1: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -16454,6 +18696,10 @@ snapshots: isarray@2.0.5: {} + isbinaryfile@4.0.10: {} + + isbinaryfile@5.0.7: {} + isexe@2.0.0: {} isexe@3.1.1: {} @@ -16520,6 +18766,12 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.5 + picocolors: 1.1.1 + jasmine-core@3.99.1: {} jasmine@3.99.0: @@ -16621,13 +18873,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-diff@30.2.0: - dependencies: - '@jest/diff-sequences': 30.0.1 - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - pretty-format: 30.2.0 - jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 @@ -16723,13 +18968,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-matcher-utils@30.2.0: - dependencies: - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - jest-diff: 30.2.0 - pretty-format: 30.2.0 - jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.27.1 @@ -16742,30 +18980,12 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-message-util@30.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 30.2.0 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 30.2.0 - slash: 3.0.0 - stack-utils: 2.0.6 - jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 22.14.1 jest-util: 29.7.0 - jest-mock@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.14.1 - jest-util: 30.2.0 - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 @@ -16892,6 +19112,7 @@ snapshots: ci-info: 4.3.1 graceful-fs: 4.2.11 picomatch: 4.0.3 + optional: true jest-validate@29.7.0: dependencies: @@ -16940,6 +19161,8 @@ snapshots: jiti@2.6.1: {} + jose@6.1.3: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -17004,12 +19227,18 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@3.0.2: {} + json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} + json-schema-typed@8.0.2: {} + json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-nice@1.1.4: {} + json-stringify-pretty-compact@4.0.0: {} json5@2.2.3: {} @@ -17051,6 +19280,10 @@ snapshots: junk@1.0.3: {} + just-diff-apply@5.5.0: {} + + just-diff@5.2.0: {} + katex@0.16.25: dependencies: commander: 8.3.0 @@ -17113,6 +19346,13 @@ snapshots: - bufferutil - utf-8-validate + load-yaml-file@0.2.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + loader-runner@4.3.1: {} loader-utils@1.4.2: @@ -17198,6 +19438,12 @@ snapshots: dependencies: yallist: 3.1.1 + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@7.18.3: {} + luxon@3.7.2: {} lz-string@1.5.0: {} @@ -17224,6 +19470,70 @@ snapshots: make-event-props@1.6.2: {} + make-fetch-happen@10.2.1: + dependencies: + agentkeepalive: 4.6.0 + cacache: 16.1.3 + http-cache-semantics: 4.2.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 2.1.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + make-fetch-happen@11.1.1: + dependencies: + agentkeepalive: 4.6.0 + cacache: 17.1.4 + http-cache-semantics: 4.2.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + make-fetch-happen@9.1.0: + dependencies: + agentkeepalive: 4.6.0 + cacache: 15.3.0 + http-cache-semantics: 4.2.0 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 1.4.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 6.2.1 + ssri: 8.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -17319,6 +19629,30 @@ snapshots: mdurl@2.0.0: {} + media-typer@1.1.0: {} + + mem-fs-editor@9.7.0(mem-fs@2.3.0): + dependencies: + binaryextensions: 4.19.0 + commondir: 1.0.1 + deep-extend: 0.6.0 + ejs: 3.1.10 + globby: 11.1.0 + isbinaryfile: 5.0.7 + minimatch: 7.4.7 + multimatch: 5.0.0 + normalize-path: 3.0.0 + textextensions: 5.16.0 + optionalDependencies: + mem-fs: 2.3.0 + + mem-fs@2.3.0: + dependencies: + '@types/node': 22.14.1 + '@types/vinyl': 2.0.12 + vinyl: 2.2.1 + vinyl-file: 3.0.0 + memoize-one@5.2.1: {} memoize-one@6.0.0: {} @@ -17335,6 +19669,8 @@ snapshots: meow@12.1.1: {} + merge-descriptors@2.0.0: {} + merge-refs@1.3.0(@types/react@19.2.2): optionalDependencies: '@types/react': 19.2.2 @@ -17568,10 +19904,16 @@ snapshots: mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb): dependencies: mime-db: 1.52.0 + mime-types@3.0.2(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb): + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mime@2.5.2: {} @@ -17597,10 +19939,22 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.0 + minimatch@10.2.2: + dependencies: + brace-expansion: 5.0.3 + minimatch@3.1.4: dependencies: brace-expansion: 1.1.12 + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.2 + + minimatch@7.4.7: + dependencies: + brace-expansion: 2.0.2 + minimatch@8.0.4: dependencies: brace-expansion: 2.0.2 @@ -17615,15 +19969,77 @@ snapshots: minimist@1.2.8: {} + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@1.4.1: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-fetch@2.1.2: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-json-stream@1.0.2: + dependencies: + jsonparse: 1.3.1 + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + minipass@4.2.8: {} + minipass@5.0.0: {} + minipass@7.1.2: {} + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + mitt@3.0.1: {} mkdirp-classic@0.5.3: optional: true + mkdirp-infer-owner@2.0.0: + dependencies: + chownr: 2.0.0 + infer-owner: 1.0.4 + mkdirp: 1.0.4 + mkdirp@0.5.6: dependencies: minimist: 1.2.8 @@ -17687,8 +20103,20 @@ snapshots: ms@2.1.3: {} + multimatch@5.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.1.4 + murmurhash-js@1.0.0: {} + mute-stream@0.0.8: {} + + mylas@2.1.14: {} + nanoevents@9.1.0: {} nanoid@3.3.11: {} @@ -17719,6 +20147,8 @@ snapshots: negotiator@0.6.3: {} + negotiator@1.0.0: {} + neo-async@2.6.2: {} next-tick@1.1.0: {} @@ -17731,18 +20161,75 @@ snapshots: node-addon-api@7.1.1: optional: true - node-fetch@2.7.0: + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-gyp@8.4.1: + dependencies: + env-paths: 2.2.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 9.1.0 + nopt: 5.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.7.3 + tar: 6.2.1 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + + node-gyp@9.4.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 10.2.1 + nopt: 6.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.7.3 + tar: 6.2.1 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color node-int64@0.4.0: {} node-releases@2.0.23: {} + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + nopt@6.0.0: + dependencies: + abbrev: 1.1.1 + nopt@7.2.1: dependencies: abbrev: 2.0.0 + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.10 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@5.0.0: + dependencies: + hosted-git-info: 6.1.3 + is-core-module: 2.16.1 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} normalize-svg-path@0.1.0: {} @@ -17753,10 +20240,108 @@ snapshots: normalize-url@6.1.0: {} + npm-bundled@1.1.2: + dependencies: + npm-normalize-package-bin: 1.0.1 + + npm-bundled@3.0.1: + dependencies: + npm-normalize-package-bin: 3.0.1 + + npm-install-checks@4.0.0: + dependencies: + semver: 7.7.3 + + npm-install-checks@6.3.0: + dependencies: + semver: 7.7.3 + + npm-normalize-package-bin@1.0.1: {} + + npm-normalize-package-bin@2.0.0: {} + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@10.1.0: + dependencies: + hosted-git-info: 6.1.3 + proc-log: 3.0.0 + semver: 7.7.3 + validate-npm-package-name: 5.0.1 + + npm-package-arg@8.1.5: + dependencies: + hosted-git-info: 4.1.0 + semver: 7.7.3 + validate-npm-package-name: 3.0.0 + + npm-packlist@3.0.0: + dependencies: + glob: 7.2.3 + ignore-walk: 4.0.1 + npm-bundled: 1.1.2 + npm-normalize-package-bin: 1.0.1 + + npm-packlist@7.0.4: + dependencies: + ignore-walk: 6.0.5 + + npm-pick-manifest@6.1.1: + dependencies: + npm-install-checks: 4.0.0 + npm-normalize-package-bin: 1.0.1 + npm-package-arg: 8.1.5 + semver: 7.7.3 + + npm-pick-manifest@8.0.2: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 10.1.0 + semver: 7.7.3 + + npm-registry-fetch@12.0.2: + dependencies: + make-fetch-happen: 10.2.1 + minipass: 3.3.6 + minipass-fetch: 1.4.1 + minipass-json-stream: 1.0.2 + minizlib: 2.1.2 + npm-package-arg: 8.1.5 + transitivePeerDependencies: + - bluebird + - supports-color + + npm-registry-fetch@14.0.5: + dependencies: + make-fetch-happen: 11.1.1 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-json-stream: 1.0.2 + minizlib: 2.1.2 + npm-package-arg: 10.1.0 + proc-log: 3.0.0 + transitivePeerDependencies: + - supports-color + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + npmlog@6.0.2: + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -17900,6 +20485,10 @@ snapshots: dependencies: p-limit: 4.0.0 + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -17909,6 +20498,13 @@ snapshots: dependencies: p-finally: 1.0.0 + p-transform@1.3.0: + dependencies: + debug: 4.4.3 + p-queue: 6.6.2 + transitivePeerDependencies: + - supports-color + p-try@2.2.0: {} package-json-from-dist@1.0.1: {} @@ -17921,6 +20517,55 @@ snapshots: package-name-regex@2.0.6: {} + pacote@12.0.3: + dependencies: + '@npmcli/git': 2.1.0 + '@npmcli/installed-package-contents': 1.0.7 + '@npmcli/promise-spawn': 1.3.2 + '@npmcli/run-script': 2.0.0 + cacache: 15.3.0 + chownr: 2.0.0 + fs-minipass: 2.1.0 + infer-owner: 1.0.4 + minipass: 3.3.6 + mkdirp: 1.0.4 + npm-package-arg: 8.1.5 + npm-packlist: 3.0.0 + npm-pick-manifest: 6.1.1 + npm-registry-fetch: 12.0.2 + promise-retry: 2.0.1 + read-package-json-fast: 2.0.3 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.2.1 + transitivePeerDependencies: + - bluebird + - supports-color + + pacote@15.2.0: + dependencies: + '@npmcli/git': 4.1.0 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/promise-spawn': 6.0.2 + '@npmcli/run-script': 6.0.2 + cacache: 17.1.4 + fs-minipass: 3.0.3 + minipass: 5.0.0 + npm-package-arg: 10.1.0 + npm-packlist: 7.0.4 + npm-pick-manifest: 8.0.2 + npm-registry-fetch: 14.0.5 + proc-log: 3.0.0 + promise-retry: 2.0.1 + read-package-json: 6.0.4 + read-package-json-fast: 3.0.2 + sigstore: 1.9.0 + ssri: 10.0.6 + tar: 6.2.1 + transitivePeerDependencies: + - bluebird + - supports-color + pako@1.0.11: {} parchment@3.0.0: {} @@ -17931,6 +20576,12 @@ snapshots: parenthesis@3.1.8: {} + parse-conflict-json@2.0.2: + dependencies: + json-parse-even-better-errors: 2.3.1 + just-diff: 5.2.0 + just-diff-apply: 5.5.0 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 @@ -17978,6 +20629,8 @@ snapshots: lru-cache: 11.2.2 minipass: 7.1.2 + path-to-regexp@8.3.0: {} + path-type@4.0.0: {} path2d@0.2.2: @@ -18007,10 +20660,14 @@ snapshots: pify@2.3.0: {} + pify@4.0.1: {} + pify@5.0.0: {} pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -18025,6 +20682,10 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + plimit-lit@1.6.1: + dependencies: + queue-lit: 1.5.2 + plotly.js-dist-min@3.1.1: {} plotly.js@3.1.1(mapbox-gl@1.13.3): @@ -18338,6 +20999,13 @@ snapshots: tunnel-agent: 0.6.0 optional: true + preferred-pm@3.1.4: + dependencies: + find-up: 5.0.0 + find-yarn-workspace-root2: 1.2.16 + path-exists: 4.0.0 + which-pm: 2.2.0 + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -18353,6 +21021,8 @@ snapshots: prettier@3.5.3: {} + pretty-bytes@5.6.0: {} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -18365,12 +21035,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - pretty-quick@4.2.2(prettier@3.5.3): dependencies: '@pkgr/core': 0.2.9 @@ -18390,10 +21054,27 @@ snapshots: transitivePeerDependencies: - supports-color + proc-log@1.0.0: {} + + proc-log@3.0.0: {} + process-nextick-args@2.0.1: {} + process@0.11.10: {} + progress@2.0.3: {} + promise-all-reject-late@1.0.1: {} + + promise-call-limit@1.0.2: {} + + promise-inflight@1.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + promise.series@0.2.0: {} promise@7.3.1: @@ -18425,6 +21106,11 @@ snapshots: protocol-buffers-schema@3.6.0: {} + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + prr@1.0.1: {} psl@1.15.0: @@ -18447,8 +21133,14 @@ snapshots: dependencies: react: 18.3.1 + qs@6.14.1: + dependencies: + side-channel: 1.1.0 + querystringify@2.2.0: {} + queue-lit@1.5.2: {} + queue-microtask@1.2.3: {} queue@6.0.2: @@ -18491,6 +21183,13 @@ snapshots: range-parser@1.2.1: {} + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.1 + unpipe: 1.0.0 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -18743,6 +21442,38 @@ snapshots: dependencies: pify: 2.3.0 + read-cmd-shim@3.0.1: {} + + read-package-json-fast@2.0.3: + dependencies: + json-parse-even-better-errors: 2.3.1 + npm-normalize-package-bin: 1.0.1 + + read-package-json-fast@3.0.2: + dependencies: + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 + + read-package-json@6.0.4: + dependencies: + glob: 10.5.0 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 5.0.0 + npm-normalize-package-bin: 3.0.1 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + readable-stream@1.0.34: dependencies: core-util-is: 1.0.3 @@ -18766,6 +21497,21 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-scoped-modules@1.1.0: + dependencies: + debuglog: 1.0.1 + dezalgo: 1.0.4 + graceful-fs: 4.2.11 + once: 1.4.0 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -18912,6 +21658,10 @@ snapshots: remove-accents@0.5.0: {} + remove-trailing-separator@1.1.0: {} + + replace-ext@1.0.1: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -18926,6 +21676,8 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve-protobuf-schema@2.1.0: dependencies: protocol-buffers-schema: 3.6.0 @@ -18953,6 +21705,8 @@ snapshots: ret@0.1.15: {} + retry@0.12.0: {} + reusify@1.1.0: {} right-now@1.0.0: {} @@ -19055,11 +21809,23 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + rst-selector-parser@2.2.3: dependencies: lodash.flattendeep: 4.4.0 nearley: 2.20.1 + run-async@2.4.1: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -19070,6 +21836,10 @@ snapshots: dependencies: tslib: 1.14.1 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -19131,6 +21901,10 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) + scoped-regex@2.1.0: {} + + semver@5.7.2: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -19153,6 +21927,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + serialize-error@2.1.0: {} serialize-javascript@6.0.2: @@ -19168,6 +21958,17 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -19261,6 +22062,16 @@ snapshots: signum@1.0.0: {} + sigstore@1.9.0: + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + '@sigstore/sign': 1.0.0 + '@sigstore/tuf': 1.0.3 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + simple-concat@1.0.1: optional: true @@ -19285,8 +22096,35 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 + smart-buffer@4.2.0: {} + smob@1.5.0: {} + socks-proxy-agent@6.2.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.1.0 + smart-buffer: 4.2.0 + + sort-keys@4.2.0: + dependencies: + is-plain-obj: 2.1.0 + sort-object-keys@1.1.3: {} sort-package-json@3.4.0: @@ -19355,6 +22193,18 @@ snapshots: sprintf-js@1.0.3: {} + ssri@10.0.6: + dependencies: + minipass: 7.1.2 + + ssri@8.0.1: + dependencies: + minipass: 3.3.6 + + ssri@9.0.1: + dependencies: + minipass: 3.3.6 + stable@0.1.8: {} stack-trace@0.0.9: {} @@ -19377,6 +22227,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -19481,6 +22333,21 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-bom-buf@1.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom-stream@2.0.0: + dependencies: + first-chunk-stream: 2.0.0 + strip-bom: 2.0.0 + + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom@3.0.0: {} + strip-bom@4.0.0: {} strip-final-newline@2.0.0: {} @@ -19597,6 +22464,15 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + terser-webpack-plugin@5.3.14(@swc/core@1.13.5)(webpack@5.102.1): dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -19625,6 +22501,8 @@ snapshots: text-table@0.2.0: {} + textextensions@5.16.0: {} + throat@5.0.0: {} through2@0.6.5: @@ -19693,6 +22571,8 @@ snapshots: tree-kill@1.2.2: {} + treeverse@1.0.4: {} + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -19749,6 +22629,16 @@ snapshots: optionalDependencies: '@swc/core': 1.13.5 + tsc-alias@1.8.16: + dependencies: + chokidar: 3.6.0 + commander: 9.5.0 + get-tsconfig: 4.13.0 + globby: 11.1.0 + mylas: 2.1.14 + normalize-path: 3.0.0 + plimit-lit: 1.6.1 + tslib@1.14.1: {} tslib@2.8.1: {} @@ -19758,6 +22648,21 @@ snapshots: tslib: 1.14.1 typescript: 5.9.3 + tsx@4.21.0: + dependencies: + esbuild: 0.27.2 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + tuf-js@1.1.7: + dependencies: + '@tufjs/models': 1.0.4 + debug: 4.4.3 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -19800,10 +22705,20 @@ snapshots: type-fest@0.21.3: {} + type-fest@0.6.0: {} + type-fest@0.7.1: {} + type-fest@0.8.1: {} + type-fest@4.41.0: {} + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) + type@2.7.3: {} typed-array-buffer@1.0.3: @@ -19899,6 +22814,32 @@ snapshots: unicorn-magic@0.1.0: {} + unique-filename@1.1.1: + dependencies: + unique-slug: 2.0.2 + + unique-filename@2.0.1: + dependencies: + unique-slug: 3.0.0 + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@2.0.2: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@3.0.0: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + universal-user-agent@6.0.1: {} + universalify@0.1.2: {} universalify@0.2.0: {} @@ -19909,6 +22850,8 @@ snapshots: unquote@1.1.1: {} + untildify@4.0.0: {} + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: browserslist: 4.26.3 @@ -19951,8 +22894,33 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validate-npm-package-name@3.0.0: + dependencies: + builtins: 1.0.3 + + validate-npm-package-name@5.0.1: {} + validate-npm-package-name@6.0.2: {} + vary@1.1.2: {} + + vinyl-file@3.0.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + strip-bom-buf: 1.0.0 + strip-bom-stream: 2.0.0 + vinyl: 2.2.1 + + vinyl@2.2.1: + dependencies: + clone: 2.1.2 + clone-buffer: 1.0.0 + clone-stats: 1.0.0 + cloneable-readable: 1.1.3 + remove-trailing-separator: 1.1.0 + replace-ext: 1.0.1 + vlq@0.2.3: {} vlq@1.0.1: {} @@ -19969,6 +22937,8 @@ snapshots: dependencies: xml-name-validator: 4.0.0 + walk-up-path@1.0.0: {} + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -20112,6 +23082,11 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 + which-pm@2.2.0: + dependencies: + load-yaml-file: 0.2.0 + path-exists: 4.0.0 + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 @@ -20126,10 +23101,18 @@ snapshots: dependencies: isexe: 2.0.0 + which@3.0.1: + dependencies: + isexe: 2.0.0 + which@4.0.0: dependencies: isexe: 3.1.1 + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + wildcard@2.0.1: {} word-wrap@1.2.5: {} @@ -20140,6 +23123,12 @@ snapshots: dependencies: object-assign: 4.1.1 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -20200,6 +23189,8 @@ snapshots: yallist@3.1.1: {} + yallist@4.0.0: {} + yaml@1.10.2: {} yaml@2.8.1: {} @@ -20239,6 +23230,75 @@ snapshots: y18n: 5.0.8 yargs-parser: 22.0.0 + yeoman-environment@3.19.3(@types/node@22.14.1): + dependencies: + '@npmcli/arborist': 4.3.1 + are-we-there-yet: 2.0.0 + arrify: 2.0.1 + binaryextensions: 4.19.0 + chalk: 4.1.2 + cli-table: 0.3.11 + commander: 7.1.0 + dateformat: 4.6.3 + debug: 4.4.3 + diff: 5.2.2 + error: 10.4.0 + escape-string-regexp: 4.0.0 + execa: 5.1.1 + find-up: 5.0.0 + globby: 11.1.0 + grouped-queue: 2.1.0 + inquirer: 8.2.7(@types/node@22.14.1) + is-scoped: 2.1.0 + isbinaryfile: 4.0.10 + lodash: 4.17.23 + log-symbols: 4.1.0 + mem-fs: 2.3.0 + mem-fs-editor: 9.7.0(mem-fs@2.3.0) + minimatch: 3.1.4 + npmlog: 5.0.1 + p-queue: 6.6.2 + p-transform: 1.3.0 + pacote: 12.0.3 + preferred-pm: 3.1.4 + pretty-bytes: 5.6.0 + readable-stream: 4.7.0 + semver: 7.7.3 + slash: 3.0.0 + strip-ansi: 6.0.1 + text-table: 0.2.0 + textextensions: 5.16.0 + untildify: 4.0.0 + transitivePeerDependencies: + - '@types/node' + - bluebird + - supports-color + + yeoman-generator@5.10.0(encoding@0.1.13)(mem-fs@2.3.0)(yeoman-environment@3.19.3(@types/node@22.14.1)): + dependencies: + chalk: 4.1.2 + dargs: 7.0.0 + debug: 4.4.3 + execa: 5.1.1 + github-username: 6.0.0(encoding@0.1.13) + lodash: 4.17.23 + mem-fs-editor: 9.7.0(mem-fs@2.3.0) + minimist: 1.2.8 + pacote: 15.2.0 + read-pkg-up: 7.0.1 + run-async: 2.4.1 + semver: 7.7.3 + shelljs: 0.8.5 + sort-keys: 4.2.0 + text-table: 0.2.0 + optionalDependencies: + yeoman-environment: 3.19.3(@types/node@22.14.1) + transitivePeerDependencies: + - bluebird + - encoding + - mem-fs + - supports-color + yn@3.1.1: {} yocto-queue@0.1.0: {} @@ -20255,4 +23315,10 @@ snapshots: compress-commons: 2.1.1 readable-stream: 3.6.2 + zod-to-json-schema@3.25.1(zod@4.3.5): + dependencies: + zod: 4.3.5 + zod@3.25.76: {} + + zod@4.3.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4c37007e1c..5a173015b8 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - - "packages/*/*" - - "automation/*" + - "packages/*/*" + - "packages/pluggable-widgets-mcp/" + - "automation/*" catalog: - rollup: "3.29" + rollup: "3.29"