Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,89 @@ Each issue includes:

**Note:** This is an offline validation tool that doesn't require API access or token scopes.

#### Validate Expression tool

Validates Mapbox style expressions for syntax, operators, and argument correctness. This offline validation tool performs comprehensive checks on Mapbox expressions without requiring API access.

**Parameters:**

- `expression` (array or string, required): Mapbox expression to validate (array format or JSON string)

**What it validates:**

- Expression syntax and structure
- Valid operator names
- Correct argument counts for each operator
- Nested expression validation
- Expression depth (warns about deeply nested expressions)

**Returns:**

Validation results including:

- `valid` (boolean): Overall validity
- `errors` (array): Critical errors that make the expression invalid
- `warnings` (array): Non-critical issues (e.g., deeply nested expressions)
- `info` (array): Informational messages
- `metadata`: Object with expressionType, returnType, and depth

Each issue includes:

- `severity`: "error", "warning", or "info"
- `message`: Description of the issue
- `path`: Path to the problem in the expression (optional)
- `suggestion`: How to fix the issue (optional)

**Supported expression types:**

- **Data**: get, has, id, geometry-type, feature-state, properties
- **Lookup**: at, in, index-of, slice, length
- **Decision**: case, match, coalesce
- **Ramps & interpolation**: interpolate, step
- **Math**: +, -, \*, /, %, ^, sqrt, log10, log2, ln, abs, etc.
- **String**: concat, downcase, upcase, is-supported-script
- **Color**: rgb, rgba, to-rgba, hsl, hsla
- **Type**: array, boolean, collator, format, image, literal, number, number-format, object, string, to-boolean, to-color, to-number, to-string, typeof
- **Camera**: zoom, pitch, distance-from-center
- **Variable binding**: let, var

**Example:**

```json
{
"expression": ["get", "population"]
}
```

**Returns:**

```json
{
"valid": true,
"errors": [],
"warnings": [],
"info": [
{
"severity": "info",
"message": "Expression validated successfully"
}
],
"metadata": {
"expressionType": "data",
"returnType": "any",
"depth": 1
}
}
```

**Example prompts:**

- "Validate this Mapbox expression: [\"get\", \"population\"]"
- "Check if this interpolation expression is correct"
- "Is this expression syntax valid for Mapbox styles?"

**Note:** This is an offline validation tool that doesn't require API access or token scopes.

#### Coordinate Conversion tool

Convert coordinates between different coordinate reference systems (CRS), specifically between WGS84 (EPSG:4326) and Web Mercator (EPSG:3857).
Expand Down
2 changes: 2 additions & 0 deletions src/tools/toolRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { StyleBuilderTool } from './style-builder-tool/StyleBuilderTool.js';
import { StyleComparisonTool } from './style-comparison-tool/StyleComparisonTool.js';
import { TilequeryTool } from './tilequery-tool/TilequeryTool.js';
import { UpdateStyleTool } from './update-style-tool/UpdateStyleTool.js';
import { ValidateExpressionTool } from './validate-expression-tool/ValidateExpressionTool.js';
import { ValidateGeojsonTool } from './validate-geojson-tool/ValidateGeojsonTool.js';
import { ValidateStyleTool } from './validate-style-tool/ValidateStyleTool.js';
import { httpRequest } from '../utils/httpPipeline.js';
Expand All @@ -45,6 +46,7 @@ export const ALL_TOOLS = [
new GetReferenceTool(),
new StyleComparisonTool(),
new TilequeryTool({ httpRequest }),
new ValidateExpressionTool(),
new ValidateGeojsonTool(),
new ValidateStyleTool()
] as const;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.

import { z } from 'zod';

export const ValidateExpressionInputSchema = z.object({
expression: z
.union([z.string(), z.any()])
.describe(
'Mapbox expression to validate (JSON string or expression array)'
),
context: z
.enum(['style', 'filter', 'layout', 'paint'])
.optional()
.describe('Context where the expression will be used')
});

export type ValidateExpressionInput = z.infer<
typeof ValidateExpressionInputSchema
>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.

import { z } from 'zod';

const ExpressionIssueSchema = z.object({
severity: z.enum(['error', 'warning', 'info']).describe('Issue severity'),
message: z.string().describe('Description of the issue'),
path: z.string().optional().describe('Path to the problem in the expression'),
suggestion: z.string().optional().describe('How to fix the issue')
});

export const ValidateExpressionOutputSchema = z.object({
valid: z.boolean().describe('Whether the expression is valid'),
errors: z.array(ExpressionIssueSchema).describe('Critical errors'),
warnings: z.array(ExpressionIssueSchema).describe('Non-critical warnings'),
info: z.array(ExpressionIssueSchema).describe('Informational messages'),
metadata: z
.object({
expressionType: z
.string()
.optional()
.describe('Detected expression type (e.g., "literal", "get", "match")'),
returnType: z
.string()
.optional()
.describe('Expected return type of the expression'),
depth: z.number().optional().describe('Maximum nesting depth')
})
.describe('Expression metadata')
});

export type ValidateExpressionOutput = z.infer<
typeof ValidateExpressionOutputSchema
>;
export type ExpressionIssue = z.infer<typeof ExpressionIssueSchema>;
Loading
Loading