@adaptabletools/adaptable-mcp 0.0.0-stage → 0.1.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -2
- package/dist/adaptable/loadEntry.js +94 -0
- package/dist/adaptable/loadEntry.js.map +1 -0
- package/dist/adaptable/types.js +13 -0
- package/dist/adaptable/types.js.map +1 -0
- package/dist/cache.js +11 -0
- package/dist/cache.js.map +1 -0
- package/dist/checks/stateRules.js +389 -0
- package/dist/checks/stateRules.js.map +1 -0
- package/dist/checks/stateTypes.js +142 -0
- package/dist/checks/stateTypes.js.map +1 -0
- package/dist/context.js +39 -0
- package/dist/context.js.map +1 -0
- package/dist/docs/corpus.js +114 -0
- package/dist/docs/corpus.js.map +1 -0
- package/dist/docs/search.js +92 -0
- package/dist/docs/search.js.map +1 -0
- package/dist/docs/source.js +151 -0
- package/dist/docs/source.js.map +1 -0
- package/dist/environment.js +181 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.js +84 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.js +59 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.js +23 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/checks.js +250 -0
- package/dist/tools/checks.js.map +1 -0
- package/dist/tools/docs.js +173 -0
- package/dist/tools/docs.js.map +1 -0
- package/dist/tools/environment.js +52 -0
- package/dist/tools/environment.js.map +1 -0
- package/package.json +35 -4
- package/skills/adaptable-dev/SKILL.md +42 -0
package/README.md
CHANGED
|
@@ -1,3 +1,96 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AdapTable MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An [MCP](https://modelcontextprotocol.io) server that helps coding agents write correct [AdapTable](https://www.adaptabletools.com) code for the version a project actually uses.
|
|
4
|
+
|
|
5
|
+
It looks things up and checks them; the agent still writes the code:
|
|
6
|
+
|
|
7
|
+
- detects the project's AdapTable, framework and AG Grid versions, and flags setup mistakes
|
|
8
|
+
- searches the docs for that version and framework
|
|
9
|
+
- validates AdapTableQL expressions and Initial State with the installed AdapTable package
|
|
10
|
+
- migrates expressions and state from older versions
|
|
11
|
+
|
|
12
|
+
For AG Grid itself (column definitions, AG Grid modules, row models, grid API), use AG Grid's [ag-mcp](https://www.ag-grid.com/javascript-data-grid/mcp-server/) alongside this server.
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
Requires Node 20+. The checks need AdapTable 24 or later installed in the project.
|
|
17
|
+
|
|
18
|
+
Cursor (`.cursor/mcp.json`) and other clients that take an `mcpServers` map:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"mcpServers": {
|
|
23
|
+
"adaptable": {
|
|
24
|
+
"command": "npx",
|
|
25
|
+
"args": ["-y", "@adaptabletools/adaptable-mcp"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Claude Code:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
claude mcp add adaptable -- npx -y @adaptabletools/adaptable-mcp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The server finds the project from the client's workspace roots, then the current directory. Pass `projectPath` to any tool, or set `ADAPTABLE_MCP_PROJECT`, to point it elsewhere.
|
|
38
|
+
|
|
39
|
+
## Tools
|
|
40
|
+
|
|
41
|
+
| Tool | What it does |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `detect_environment` | AdapTable and AG Grid packages, framework, peer range, documented AG Grid pairing, warnings |
|
|
44
|
+
| `search_docs` | Docs sections for the project's version and framework, with URLs |
|
|
45
|
+
| `get_doc` | One docs page (or one section of it) as markdown |
|
|
46
|
+
| `check_expression` | Validates an AdapTableQL expression: syntax, functions, types, aggregation rules, the functions its Module offers, columns |
|
|
47
|
+
| `migrate_expression` | Rewrites a pre-v24 expression to v24 syntax |
|
|
48
|
+
| `list_expression_functions` | Built-in AdapTableQL functions with signatures and examples |
|
|
49
|
+
| `check_state` | Initial State: type check against the installed `InitialState`, pre-v24 shapes, Layouts, column references, embedded expressions |
|
|
50
|
+
| `migrate_state` | Upgrades state from an older major version (`AdaptableUpgradeHelper`) |
|
|
51
|
+
|
|
52
|
+
Resources: `adaptable://docs/{major}/{slug}`, `adaptable://api/{major}/{typeName}`, `adaptable://aql/functions`.
|
|
53
|
+
|
|
54
|
+
Prompts: `setup-adaptable` (framework), `upgrade-adaptable` (from, to).
|
|
55
|
+
|
|
56
|
+
## How it works
|
|
57
|
+
|
|
58
|
+
- Docs come from the build-time export of the docs site: `/llms/manifest.json`, `/llms-full.txt` and `/llms/pages.json`. The server picks the site that matches the project's major version (`www` for the latest major, `v{major}` for older ones, `canary` for a major that only has canary releases), caches the files, and re-downloads only when the manifest hash changes.
|
|
59
|
+
- Checks use the `@adaptabletools/adaptable/aql` and `@adaptabletools/adaptable/upgrade` entry points of the installed package, so they match the project's exact version. The package ships as bundler ESM, so each entry is bundled once with esbuild and cached.
|
|
60
|
+
|
|
61
|
+
## Environment variables
|
|
62
|
+
|
|
63
|
+
| Variable | Default | Use |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `ADAPTABLE_MCP_PROJECT` | workspace root | Project to inspect |
|
|
66
|
+
| `ADAPTABLE_MCP_DOCS_URL` | matched docs site | Docs site to read, e.g. `https://dev.adaptabletools.com` |
|
|
67
|
+
| `ADAPTABLE_MCP_DOCS_DIR` | | Local docs build (`documentation/public`) instead of a site |
|
|
68
|
+
| `ADAPTABLE_MCP_ADAPTABLE_SRC` | | AdapTable source folder (`packages/adaptable`) instead of the installed package |
|
|
69
|
+
| `ADAPTABLE_MCP_CACHE_DIR` | `~/.cache/adaptable-mcp` | Cache for docs and bundled entries |
|
|
70
|
+
|
|
71
|
+
## Development
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm install
|
|
75
|
+
npm run build
|
|
76
|
+
npm test
|
|
77
|
+
npm run inspect # MCP Inspector
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Eval
|
|
81
|
+
|
|
82
|
+
`eval/tasks.json` holds the eval tasks: setup per framework, AdapTableQL, state, option placement and upgrades. `eval/grade.mjs` grades a folder of answers (`<task-id>.md`), checking expressions and Initial State (including the type check) with the same code as the tools.
|
|
83
|
+
|
|
84
|
+
`npm test` checks the checks in both directions: every Initial State in the docs demos must pass `check_state` (`test/docsExamples.test.mjs`; known docs issues are listed there until the demos are fixed), and every answer in `eval/known-wrong` (stale answers from a run without the MCP) must fail grading.
|
|
85
|
+
|
|
86
|
+
Eval runs write their answers to `eval/results/<run>/` (gitignored):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
node eval/grade.mjs eval/results/baseline
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`eval/mcp-call.mjs` calls one tool from the command line, for agents that run the eval without MCP support:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
ADAPTABLE_MCP_PROJECT=eval/fixture node eval/mcp-call.mjs search_docs '{"query":"pivot layout"}'
|
|
96
|
+
```
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { pathToFileURL } from 'node:url';
|
|
7
|
+
import { build } from 'esbuild';
|
|
8
|
+
import { getCacheDir } from '../cache.js';
|
|
9
|
+
const loaded = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Entries come from the developer's installed package, so checks match their
|
|
12
|
+
* exact version. `ADAPTABLE_MCP_ADAPTABLE_SRC` points at an AdapTable source
|
|
13
|
+
* folder instead (e.g. `packages/adaptable` in the AdapTable repo).
|
|
14
|
+
*/
|
|
15
|
+
function resolveEntry(projectPath, name) {
|
|
16
|
+
const sourceDir = process.env.ADAPTABLE_MCP_ADAPTABLE_SRC;
|
|
17
|
+
if (sourceDir) {
|
|
18
|
+
const tsconfig = join(sourceDir, 'tsconfig.cjs.json');
|
|
19
|
+
// a source entry changes with every edit to the files it imports
|
|
20
|
+
return {
|
|
21
|
+
entry: join(sourceDir, `${name}.ts`),
|
|
22
|
+
tsconfig: existsSync(tsconfig) ? tsconfig : undefined,
|
|
23
|
+
cacheable: false,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const require = createRequire(join(projectPath, 'package.json'));
|
|
28
|
+
return { entry: require.resolve(`@adaptabletools/adaptable/${name}.js`), cacheable: true };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function readPackageVersion(entry) {
|
|
35
|
+
let dir = dirname(entry);
|
|
36
|
+
for (let i = 0; i < 4; i++) {
|
|
37
|
+
const pkgPath = join(dir, 'package.json');
|
|
38
|
+
if (existsSync(pkgPath)) {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(readFileSync(pkgPath, 'utf8')).version;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
dir = dirname(dir);
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The published package is bundler-only ESM (extensionless relative imports),
|
|
52
|
+
* so each entry is bundled once per version with esbuild and cached.
|
|
53
|
+
*/
|
|
54
|
+
async function bundleAndImport(name, entry, tsconfig, cacheable) {
|
|
55
|
+
const stamp = createHash('sha256')
|
|
56
|
+
.update(entry)
|
|
57
|
+
.update(String(statSync(entry).mtimeMs))
|
|
58
|
+
.update(readPackageVersion(entry) ?? '')
|
|
59
|
+
.update(cacheable ? '' : `${process.pid}-${Date.now()}`)
|
|
60
|
+
.digest('hex')
|
|
61
|
+
.slice(0, 16);
|
|
62
|
+
const outfile = join(cacheable ? getCacheDir('adaptable') : tmpdir(), `adaptable-${name}-${stamp}.mjs`);
|
|
63
|
+
if (!cacheable || !existsSync(outfile)) {
|
|
64
|
+
await build({
|
|
65
|
+
entryPoints: [entry],
|
|
66
|
+
bundle: true,
|
|
67
|
+
platform: 'node',
|
|
68
|
+
format: 'esm',
|
|
69
|
+
outfile,
|
|
70
|
+
tsconfig,
|
|
71
|
+
logLevel: 'silent',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return import(pathToFileURL(outfile).href);
|
|
75
|
+
}
|
|
76
|
+
export function loadEntry(projectPath, name) {
|
|
77
|
+
const resolved = resolveEntry(projectPath, name);
|
|
78
|
+
if (!resolved) {
|
|
79
|
+
return Promise.resolve({
|
|
80
|
+
ok: false,
|
|
81
|
+
reason: `This project has no @adaptabletools/adaptable/${name} entry point (it ships with AdapTable 24 and later). Install AdapTable 24+ in the project first.`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
let result = loaded.get(resolved.entry);
|
|
85
|
+
if (!result) {
|
|
86
|
+
result = bundleAndImport(name, resolved.entry, resolved.tsconfig, resolved.cacheable).then((module) => ({ ok: true, module, source: resolved.entry }), (error) => ({
|
|
87
|
+
ok: false,
|
|
88
|
+
reason: `Could not load ${resolved.entry}: ${error instanceof Error ? error.message : String(error)}`,
|
|
89
|
+
}));
|
|
90
|
+
loaded.set(resolved.entry, result);
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=loadEntry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadEntry.js","sourceRoot":"","sources":["../../src/adaptable/loadEntry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adaptable/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO;IACP,kBAAkB;IAClB,cAAc;IACd,QAAQ;IACR,cAAc;IACd,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,cAAc;CACN,CAAC"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export function getCacheDir(...segments) {
|
|
5
|
+
const base = process.env.ADAPTABLE_MCP_CACHE_DIR ||
|
|
6
|
+
join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'adaptable-mcp');
|
|
7
|
+
const dir = join(base, ...segments);
|
|
8
|
+
mkdirSync(dir, { recursive: true });
|
|
9
|
+
return dir;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,WAAW,CAAC,GAAG,QAAkB;IAC/C,MAAM,IAAI,GACR,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/** Top-level keys of v24 `InitialState` */
|
|
2
|
+
const INITIAL_STATE_KEYS = new Set([
|
|
3
|
+
'Alert',
|
|
4
|
+
'Application',
|
|
5
|
+
'CalculatedColumn',
|
|
6
|
+
'Charting',
|
|
7
|
+
'CustomSort',
|
|
8
|
+
'Dashboard',
|
|
9
|
+
'Export',
|
|
10
|
+
'FlashingCell',
|
|
11
|
+
'FormatColumn',
|
|
12
|
+
'FreeTextColumn',
|
|
13
|
+
'Layout',
|
|
14
|
+
'NamedQuery',
|
|
15
|
+
'Note',
|
|
16
|
+
'PlusMinus',
|
|
17
|
+
'QuickSearch',
|
|
18
|
+
'Shortcut',
|
|
19
|
+
'StatusBar',
|
|
20
|
+
'StyledColumn',
|
|
21
|
+
'Theme',
|
|
22
|
+
'ToolPanel',
|
|
23
|
+
'UserInterface',
|
|
24
|
+
]);
|
|
25
|
+
const GROUP_COLUMN_ID = 'ag-Grid-AutoColumn';
|
|
26
|
+
const SELECTION_COLUMN_ID = 'ag-Grid-SelectionColumn';
|
|
27
|
+
const TABLE_ONLY_KEYS = ['TableColumns', 'TableAggregationColumns', 'RowGroupedColumns'];
|
|
28
|
+
const PIVOT_ONLY_KEYS = [
|
|
29
|
+
'PivotColumns',
|
|
30
|
+
'PivotAggregationColumns',
|
|
31
|
+
'PivotGroupedColumns',
|
|
32
|
+
'PivotExpandLevel',
|
|
33
|
+
];
|
|
34
|
+
const isObj = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
35
|
+
const asArray = (value) => (Array.isArray(value) ? value : []);
|
|
36
|
+
const STRING_LITERAL = /'(?:[^']|'')*'|"(?:[^"\\]|\\.)*"/g;
|
|
37
|
+
/**
|
|
38
|
+
* True when the text calls an aggregation in its catalogue form: braces for
|
|
39
|
+
* `SUM{[price]}`, parens for `PERCENTAGE([price])`
|
|
40
|
+
*/
|
|
41
|
+
export function containsAggregation(expression, aggregations) {
|
|
42
|
+
const text = expression.replace(STRING_LITERAL, "''");
|
|
43
|
+
for (const match of text.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\s*([{(])/g)) {
|
|
44
|
+
const callForm = aggregations.get(match[1].toUpperCase());
|
|
45
|
+
if (callForm && callForm === (match[2] === '{' ? 'brace' : 'paren')) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
/** Keys of the pre-v24 expression wrapper object (`Rule: { BooleanExpression: '...' }`) */
|
|
52
|
+
const LEGACY_WRAPPER_KEYS = [
|
|
53
|
+
'BooleanExpression',
|
|
54
|
+
'ScalarExpression',
|
|
55
|
+
'AggregatedBooleanExpression',
|
|
56
|
+
'AggregatedScalarExpression',
|
|
57
|
+
'AggregatedExpression',
|
|
58
|
+
'ObservableExpression',
|
|
59
|
+
'Expression',
|
|
60
|
+
];
|
|
61
|
+
function expressionSlots(state) {
|
|
62
|
+
const slots = [];
|
|
63
|
+
const section = (key) => (isObj(state[key]) ? state[key] : {});
|
|
64
|
+
const each = (list, owner, fn) => asArray(list).forEach((item, i) => {
|
|
65
|
+
if (isObj(item)) {
|
|
66
|
+
fn(item, `${owner}[${i}]`);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
each(section('NamedQuery').NamedQueries, 'NamedQuery.NamedQueries', (holder, owner) => {
|
|
70
|
+
const returnType = holder.ReturnType ?? 'boolean';
|
|
71
|
+
slots.push({
|
|
72
|
+
owner,
|
|
73
|
+
holder,
|
|
74
|
+
prop: 'Expression',
|
|
75
|
+
legacyProps: LEGACY_WRAPPER_KEYS.filter((k) => k !== 'Expression'),
|
|
76
|
+
required: true,
|
|
77
|
+
module: 'NamedQuery',
|
|
78
|
+
kind: returnType === 'boolean' ? 'boolean' : 'scalar',
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
each(section('CalculatedColumn').CalculatedColumns, 'CalculatedColumn.CalculatedColumns', (holder, owner) => {
|
|
82
|
+
slots.push({
|
|
83
|
+
owner,
|
|
84
|
+
holder,
|
|
85
|
+
prop: 'Expression',
|
|
86
|
+
legacyProps: ['Query'],
|
|
87
|
+
required: true,
|
|
88
|
+
module: 'CalculatedColumn',
|
|
89
|
+
kind: 'scalar',
|
|
90
|
+
aggregatedKind: 'aggregatedScalar',
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
each(section('Alert').AlertDefinitions, 'Alert.AlertDefinitions', (holder, owner) => {
|
|
94
|
+
slots.push({ owner, holder, prop: 'Rule', module: 'Alert', kind: 'boolean', aggregatedKind: 'aggregatedBoolean' });
|
|
95
|
+
});
|
|
96
|
+
const ruleSections = [
|
|
97
|
+
['FlashingCell', 'FlashingCellDefinitions'],
|
|
98
|
+
['FormatColumn', 'FormatColumns'],
|
|
99
|
+
['PlusMinus', 'PlusMinusNudges'],
|
|
100
|
+
];
|
|
101
|
+
for (const [module, list] of ruleSections) {
|
|
102
|
+
each(section(module)[list], `${module}.${list}`, (holder, owner) => {
|
|
103
|
+
slots.push({ owner, holder, prop: 'Rule', module, kind: 'boolean' });
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
each(section('Export').Reports, 'Export.Reports', (holder, owner) => {
|
|
107
|
+
slots.push({ owner, holder, prop: 'Expression', legacyProps: ['Query'], module: 'Export', kind: 'boolean' });
|
|
108
|
+
});
|
|
109
|
+
each(section('StyledColumn').StyledColumns, 'StyledColumn.StyledColumns', (styled, styledPath) => {
|
|
110
|
+
if (isObj(styled.BadgeStyle)) {
|
|
111
|
+
each(styled.BadgeStyle.Badges, `${styledPath}.BadgeStyle.Badges`, (holder, owner) => {
|
|
112
|
+
slots.push({ owner, holder, prop: 'Rule', module: 'StyledColumn', kind: 'boolean' });
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
each(section('Layout').Layouts, 'Layout.Layouts', (layout, layoutPath) => {
|
|
117
|
+
if (isObj(layout.GridFilter)) {
|
|
118
|
+
slots.push({
|
|
119
|
+
owner: `${layoutPath}.GridFilter`,
|
|
120
|
+
holder: layout.GridFilter,
|
|
121
|
+
prop: 'Expression',
|
|
122
|
+
module: 'GridFilter',
|
|
123
|
+
kind: 'boolean',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
each(layout.ColumnFilters, `${layoutPath}.ColumnFilters`, (holder, owner) => {
|
|
127
|
+
slots.push({ owner, holder, prop: 'Expression', module: 'ColumnFilter', kind: 'boolean' });
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
return slots;
|
|
131
|
+
}
|
|
132
|
+
const legacyWrapperText = (value) => LEGACY_WRAPPER_KEYS.map((k) => value[k]).find((v) => typeof v === 'string');
|
|
133
|
+
/** The expression a slot holds, in v24 form or a pre-v24 shape (reported by checkStateRules) */
|
|
134
|
+
function readSlot(slot) {
|
|
135
|
+
for (const prop of [slot.prop, ...(slot.legacyProps ?? [])]) {
|
|
136
|
+
const value = slot.holder[prop];
|
|
137
|
+
if (value === undefined) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const path = `${slot.owner}.${prop}`;
|
|
141
|
+
if (typeof value === 'string') {
|
|
142
|
+
return { path, text: value, legacy: prop !== slot.prop };
|
|
143
|
+
}
|
|
144
|
+
return { path, text: isObj(value) ? legacyWrapperText(value) : undefined, legacy: true };
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
/** Every AdapTableQL string in state, with its Module and the kind that Module evaluates it as */
|
|
149
|
+
export function collectExpressions(state, aggregations) {
|
|
150
|
+
const found = [];
|
|
151
|
+
for (const slot of expressionSlots(state)) {
|
|
152
|
+
const read = readSlot(slot);
|
|
153
|
+
if (!read?.text?.trim()) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
found.push({
|
|
157
|
+
path: read.path,
|
|
158
|
+
expression: read.text,
|
|
159
|
+
module: slot.module,
|
|
160
|
+
kind: slot.aggregatedKind && containsAggregation(read.text, aggregations) ? slot.aggregatedKind : slot.kind,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return found;
|
|
164
|
+
}
|
|
165
|
+
function expressionShapeIssues(state) {
|
|
166
|
+
const issues = [];
|
|
167
|
+
for (const slot of expressionSlots(state)) {
|
|
168
|
+
const read = readSlot(slot);
|
|
169
|
+
if (!read) {
|
|
170
|
+
if (slot.required) {
|
|
171
|
+
issues.push({
|
|
172
|
+
path: `${slot.owner}.${slot.prop}`,
|
|
173
|
+
severity: 'error',
|
|
174
|
+
message: `Missing \`${slot.prop}\` (the AdapTableQL expression string).`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (read.legacy) {
|
|
180
|
+
const v24 = read.text === undefined ? `'...'` : JSON.stringify(read.text);
|
|
181
|
+
issues.push({
|
|
182
|
+
path: read.path,
|
|
183
|
+
severity: 'error',
|
|
184
|
+
message: `Pre-v24 shape. In v24 \`${slot.prop}\` is the expression string itself: \`${slot.prop}: ${v24}\`. To convert a whole older state use migrate_state.`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
eachInSection(state, 'Alert', 'AlertDefinitions', (alert, path) => {
|
|
189
|
+
const rowEvent = typeof alert.Rule === 'string' && alert.Rule.match(/^\s*ROW_(ADDED|REMOVED)\s*[{(]/);
|
|
190
|
+
if (rowEvent) {
|
|
191
|
+
const trigger = rowEvent[1] === 'ADDED' ? 'Added' : 'Removed';
|
|
192
|
+
issues.push({
|
|
193
|
+
path: `${path}.Rule`,
|
|
194
|
+
severity: 'error',
|
|
195
|
+
message: `Pre-v24 row event rule. Use a Row Change Alert: \`Type: 'RowChange', RowChangeTrigger: '${trigger}', Scope: { All: true }\`; \`Rule\` is optional and filters the ${trigger.toLowerCase()} rows (e.g. \`[status] = 'New'\`).`,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
eachInSection(state, 'CalculatedColumn', 'CalculatedColumns', (column, path) => {
|
|
200
|
+
const settings = column.CalculatedColumnSettings;
|
|
201
|
+
if (!isObj(settings) || typeof settings.DataType !== 'string') {
|
|
202
|
+
issues.push({
|
|
203
|
+
path: `${path}.CalculatedColumnSettings${isObj(settings) ? '.DataType' : ''}`,
|
|
204
|
+
severity: 'error',
|
|
205
|
+
message: `Calculated Columns need \`CalculatedColumnSettings: { DataType: ... }\` (the type the Expression returns, e.g. 'number').`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return issues;
|
|
210
|
+
}
|
|
211
|
+
function eachInSection(state, module, list, fn) {
|
|
212
|
+
const sectionValue = state[module];
|
|
213
|
+
if (isObj(sectionValue)) {
|
|
214
|
+
asArray(sectionValue[list]).forEach((item, i) => {
|
|
215
|
+
if (isObj(item)) {
|
|
216
|
+
fn(item, `${module}.${list}[${i}]`);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** Columns the state itself defines (Calculated and FreeText Columns), with their data types */
|
|
222
|
+
export function getStateColumnIds(state) {
|
|
223
|
+
const columns = [];
|
|
224
|
+
for (const [module, list, settings] of [
|
|
225
|
+
['CalculatedColumn', 'CalculatedColumns', 'CalculatedColumnSettings'],
|
|
226
|
+
['FreeTextColumn', 'FreeTextColumns', 'FreeTextColumnSettings'],
|
|
227
|
+
]) {
|
|
228
|
+
const sectionValue = state[module];
|
|
229
|
+
if (isObj(sectionValue)) {
|
|
230
|
+
for (const c of asArray(sectionValue[list])) {
|
|
231
|
+
if (isObj(c) && typeof c.ColumnId === 'string') {
|
|
232
|
+
const dataType = isObj(c[settings]) ? c[settings].DataType : undefined;
|
|
233
|
+
columns.push([c.ColumnId, typeof dataType === 'string' ? dataType : undefined]);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return columns;
|
|
239
|
+
}
|
|
240
|
+
function layoutColumnRefs(layout) {
|
|
241
|
+
const refs = [];
|
|
242
|
+
for (const key of ['TableColumns', 'PivotColumns', 'RowGroupedColumns', 'PivotGroupedColumns']) {
|
|
243
|
+
for (const id of asArray(layout[key])) {
|
|
244
|
+
if (typeof id === 'string') {
|
|
245
|
+
refs.push({ key, columnId: id });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const key of ['ColumnSorts', 'ColumnFilters', 'TableAggregationColumns', 'PivotAggregationColumns']) {
|
|
250
|
+
for (const item of asArray(layout[key])) {
|
|
251
|
+
if (isObj(item) && typeof item.ColumnId === 'string') {
|
|
252
|
+
refs.push({ key, columnId: item.ColumnId });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
for (const key of ['ColumnSizing', 'ColumnPinning', 'ColumnVisibility', 'ColumnHeaders']) {
|
|
257
|
+
if (isObj(layout[key])) {
|
|
258
|
+
for (const id of Object.keys(layout[key])) {
|
|
259
|
+
refs.push({ key, columnId: id });
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return refs;
|
|
264
|
+
}
|
|
265
|
+
const isSpecialColumn = (id) => id === GROUP_COLUMN_ID || id === SELECTION_COLUMN_ID || id.startsWith(`${GROUP_COLUMN_ID}-`);
|
|
266
|
+
/**
|
|
267
|
+
* Semantic rules TypeScript cannot catch, plus the expression shapes agents
|
|
268
|
+
* most often get wrong (with the v24 rewrite); other shape errors are left to
|
|
269
|
+
* the type check
|
|
270
|
+
*/
|
|
271
|
+
export function checkStateRules(state, input) {
|
|
272
|
+
const issues = [];
|
|
273
|
+
if (!isObj(state)) {
|
|
274
|
+
return [{ path: '', severity: 'error', message: 'State must be a JSON object (the value of `initialState`).' }];
|
|
275
|
+
}
|
|
276
|
+
for (const key of Object.keys(state)) {
|
|
277
|
+
if (key === 'PredefinedConfig') {
|
|
278
|
+
issues.push({
|
|
279
|
+
path: key,
|
|
280
|
+
severity: 'error',
|
|
281
|
+
message: '`PredefinedConfig` is not part of AdapTable state: put its contents directly in `initialState`.',
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
else if (!INITIAL_STATE_KEYS.has(key)) {
|
|
285
|
+
issues.push({
|
|
286
|
+
path: key,
|
|
287
|
+
severity: 'warning',
|
|
288
|
+
message: `\`${key}\` is not an Initial State section; AdapTable ignores it. Check search_docs for where this belongs (it may be an Adaptable Option).`,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
issues.push(...expressionShapeIssues(state));
|
|
293
|
+
const layoutState = isObj(state.Layout) ? state.Layout : undefined;
|
|
294
|
+
const layouts = asArray(layoutState?.Layouts);
|
|
295
|
+
if (!layouts.length) {
|
|
296
|
+
issues.push({
|
|
297
|
+
path: 'Layout.Layouts',
|
|
298
|
+
severity: 'warning',
|
|
299
|
+
message: 'No Layouts: Initial State must include at least one Layout unless `layoutOptions.autoCreateLayout` is set.',
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
const known = input.columnIds
|
|
303
|
+
? new Set([...input.columnIds, ...getStateColumnIds(state).map(([id]) => id)])
|
|
304
|
+
: undefined;
|
|
305
|
+
const names = new Map();
|
|
306
|
+
layouts.forEach((layout, i) => {
|
|
307
|
+
const path = `Layout.Layouts[${i}]`;
|
|
308
|
+
if (!isObj(layout)) {
|
|
309
|
+
issues.push({ path, severity: 'error', message: 'Layout must be an object.' });
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const name = layout.Name;
|
|
313
|
+
if (typeof name !== 'string' || !name) {
|
|
314
|
+
issues.push({ path: `${path}.Name`, severity: 'error', message: 'Layout needs a `Name`.' });
|
|
315
|
+
}
|
|
316
|
+
else if (names.has(name)) {
|
|
317
|
+
issues.push({
|
|
318
|
+
path: `${path}.Name`,
|
|
319
|
+
severity: 'error',
|
|
320
|
+
message: `Duplicate Layout name "${name}" (also Layout.Layouts[${names.get(name)}]); Layout names must be unique.`,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
names.set(name, i);
|
|
325
|
+
}
|
|
326
|
+
const isTable = layout.TableColumns !== undefined;
|
|
327
|
+
const isPivot = layout.PivotColumns !== undefined;
|
|
328
|
+
if (isTable && isPivot) {
|
|
329
|
+
issues.push({
|
|
330
|
+
path,
|
|
331
|
+
severity: 'error',
|
|
332
|
+
message: 'A Layout is either a Table Layout (`TableColumns`) or a Pivot Layout (`PivotColumns`), not both.',
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
else if (!isTable && !isPivot) {
|
|
336
|
+
issues.push({
|
|
337
|
+
path,
|
|
338
|
+
severity: 'error',
|
|
339
|
+
message: 'Layout needs `TableColumns` (Table Layout) or `PivotColumns` (Pivot Layout; use [] to show only aggregations).',
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
const wrongKeys = (isTable ? PIVOT_ONLY_KEYS : TABLE_ONLY_KEYS).filter((k) => layout[k] !== undefined);
|
|
344
|
+
for (const key of wrongKeys) {
|
|
345
|
+
issues.push({
|
|
346
|
+
path: `${path}.${key}`,
|
|
347
|
+
severity: 'error',
|
|
348
|
+
message: isTable
|
|
349
|
+
? `\`${key}\` belongs to Pivot Layouts; this is a Table Layout.`
|
|
350
|
+
: `\`${key}\` belongs to Table Layouts; in Pivot Layouts use ${key === 'RowGroupedColumns' ? '`PivotGroupedColumns`' : key === 'TableAggregationColumns' ? '`PivotAggregationColumns`' : '`PivotColumns`'}.`,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (isObj(layout.ColumnSizing)) {
|
|
355
|
+
for (const [columnId, sizing] of Object.entries(layout.ColumnSizing)) {
|
|
356
|
+
if (isObj(sizing) && sizing.Width !== undefined && sizing.Flex !== undefined) {
|
|
357
|
+
issues.push({
|
|
358
|
+
path: `${path}.ColumnSizing.${columnId}`,
|
|
359
|
+
severity: 'error',
|
|
360
|
+
message: 'Column sizing takes `Width` or `Flex`, not both.',
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (known) {
|
|
366
|
+
const reported = new Set();
|
|
367
|
+
for (const { key, columnId } of layoutColumnRefs(layout)) {
|
|
368
|
+
if (!known.has(columnId) && !isSpecialColumn(columnId) && !reported.has(columnId)) {
|
|
369
|
+
reported.add(columnId);
|
|
370
|
+
issues.push({
|
|
371
|
+
path: `${path}.${key}`,
|
|
372
|
+
severity: 'error',
|
|
373
|
+
message: `Column "${columnId}" is not in the grid's columns. If it is an Action Column or another column defined outside columnDefs, add it to columns.`,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
const current = layoutState?.CurrentLayout;
|
|
380
|
+
if (typeof current === 'string' && layouts.length && !names.has(current)) {
|
|
381
|
+
issues.push({
|
|
382
|
+
path: 'Layout.CurrentLayout',
|
|
383
|
+
severity: 'error',
|
|
384
|
+
message: `CurrentLayout "${current}" does not match any Layout Name (${[...names.keys()].map((n) => `"${n}"`).join(', ')}).`,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return issues;
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=stateRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateRules.js","sourceRoot":"","sources":["../../src/checks/stateRules.ts"],"names":[],"mappings":"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"}
|