@alaarab/ogrid-mcp 2.16.0 → 2.17.1
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/LICENSE +21 -0
- package/bundled-docs/api/headless-hooks.mdx +4 -3
- package/bundled-docs/features/csv-export.mdx +8 -5
- package/bundled-docs/features/xlsx-import.mdx +7 -0
- package/dist/esm/bridge-client.d.ts +6 -8
- package/dist/esm/bridge.d.ts +83 -0
- package/dist/esm/docsLoader.d.ts +24 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +55 -1
- package/dist/esm/server.d.ts +4 -0
- package/package.json +15 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Ala Arab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -68,7 +68,7 @@ const grid = useHeadlessGrid({
|
|
|
68
68
|
| Field | Description |
|
|
69
69
|
|---|---|
|
|
70
70
|
| `rows` | Current page rows after sort + filter |
|
|
71
|
-
| `allFilteredRows` |
|
|
71
|
+
| `allFilteredRows` | Every filtered+sorted row across pages (client mode), or the current page (server mode) |
|
|
72
72
|
| `columns` | Resolved columns |
|
|
73
73
|
| `totalCount` | Post-filter total |
|
|
74
74
|
| `totalPages` | Total pages at current page size |
|
|
@@ -246,13 +246,14 @@ useEffect(() => {
|
|
|
246
246
|
| `columns` | `IColumnDef<T>[]` |
|
|
247
247
|
| `onCellEdit` | `(events: ICellValueChangedEvent<T>[]) => void` |
|
|
248
248
|
| `clipboard?` | `{ readText, writeText }` override (defaults to `navigator.clipboard`) |
|
|
249
|
+
| `onClipboardError?` | `(error: unknown) => void`, called when a clipboard read/write fails (e.g. permission denied) |
|
|
249
250
|
|
|
250
251
|
### Returns
|
|
251
252
|
|
|
252
253
|
| Field | Description |
|
|
253
254
|
|---|---|
|
|
254
|
-
| `copyRange()`, `cutRange()`, `pasteRange()` | Async actions |
|
|
255
|
-
| `canPaste` | `boolean` (feature detection) |
|
|
255
|
+
| `copyRange()`, `cutRange()`, `pasteRange()` | Async actions. They resolve (never reject) when the clipboard is unavailable or denied; see `onClipboardError`. |
|
|
256
|
+
| `canPaste` | `boolean` (feature detection). `false` until mounted, so server-rendered markup hydrates cleanly. |
|
|
256
257
|
| `activeCutRange`, `activeCopyRange` | Marching-ants tracking |
|
|
257
258
|
| `clearClipboard()` | Dismiss markers (bind to Escape) |
|
|
258
259
|
|
|
@@ -61,8 +61,9 @@ The `OGrid` component has the same props across all React UI packages. To switch
|
|
|
61
61
|
exportToCsv<T>(
|
|
62
62
|
items: T[],
|
|
63
63
|
columns: CsvColumn[],
|
|
64
|
-
getValue: (item: T, columnId: string) =>
|
|
65
|
-
filename?: string
|
|
64
|
+
getValue: (item: T, columnId: string) => unknown,
|
|
65
|
+
filename?: string,
|
|
66
|
+
formulaOptions?: FormulaExportOptions
|
|
66
67
|
): void
|
|
67
68
|
```
|
|
68
69
|
|
|
@@ -71,13 +72,15 @@ exportToCsv<T>(
|
|
|
71
72
|
| `items` | `T[]` | The row data to export |
|
|
72
73
|
| `columns` | `CsvColumn[]` | Array of `{ columnId, name }` defining which columns to include and their header names |
|
|
73
74
|
| `getValue` | `(item, columnId) => string` | Function to extract the display value for each cell |
|
|
74
|
-
| `filename` | `string` (optional) | Download filename (default: `
|
|
75
|
+
| `filename` | `string` (optional) | Download filename (default: `export_YYYY-MM-DD.csv`) |
|
|
76
|
+
| `formulaOptions` | `FormulaExportOptions` (optional) | Formula export settings, plus `preventFormulaInjection` (default `true`) |
|
|
75
77
|
|
|
76
78
|
The function:
|
|
77
79
|
1. Builds a CSV header row from `columns[].name`.
|
|
78
80
|
2. Iterates over each item and calls `getValue` for each column.
|
|
79
|
-
3. Escapes values containing commas, quotes, or
|
|
80
|
-
4.
|
|
81
|
+
3. Escapes values containing commas, quotes, or line breaks.
|
|
82
|
+
4. Guards against CSV (formula) injection: text starting with `=`, `+`, `-`, `@`, a tab or a carriage return is prefixed with `'`, so a spreadsheet opening the file shows it as text instead of running it. Plain numbers such as `-5` are left alone. Pass `{ preventFormulaInjection: false }` to turn this off, for example when a trusted consumer needs the raw text. Formulas written with `exportMode: 'formulas'` are never prefixed.
|
|
83
|
+
5. Triggers a browser download with the specified filename.
|
|
81
84
|
|
|
82
85
|
### Context Menu Integration
|
|
83
86
|
|
|
@@ -64,6 +64,13 @@ function SingleSheet({ file }: { file: Blob }) {
|
|
|
64
64
|
| `density` | `'compact' \| 'normal' \| 'comfortable'` | `'compact'` | Row height. |
|
|
65
65
|
| `onSheetChange` | `(name: string) => void` | — | Fired when the user clicks a sheet tab. |
|
|
66
66
|
| `headerRow` | `'auto' \| 'header' \| 'none'` | `'auto'` | Whether to promote row 1 to the header. `'auto'` detects strings-only top rows; `'header'` forces it; `'none'` uses A/B/C letters. |
|
|
67
|
+
| `limits` | `{ maxRows?, maxCols?, maxCells? }` | 1,048,576 rows / 1,000 cols / 5,000,000 cells | Load caps per sheet. A small file can declare a huge used range; anything past the caps is dropped and a notice is shown above the grid. |
|
|
68
|
+
|
|
69
|
+
### Untrusted files
|
|
70
|
+
|
|
71
|
+
Only populated cells are read, and each sheet is capped by `limits`. `sheetToGridData(sheet, { maxRows, maxCols, maxCells })` applies the same caps and returns `truncated: { rowCount, columnCount }` (the full size) when it cut the sheet.
|
|
72
|
+
|
|
73
|
+
`@alaarab/ogrid-react-xlsx` requires React 18 or 19.
|
|
67
74
|
|
|
68
75
|
### Format support
|
|
69
76
|
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
*
|
|
26
26
|
* This module contains NO Node.js-specific imports - safe to bundle in browsers.
|
|
27
27
|
*/
|
|
28
|
-
interface BridgeColumnInfo {
|
|
28
|
+
export interface BridgeColumnInfo {
|
|
29
29
|
columnId: string;
|
|
30
30
|
headerName?: string;
|
|
31
31
|
type?: string;
|
|
32
32
|
}
|
|
33
|
-
interface BridgeCommand {
|
|
33
|
+
export interface BridgeCommand {
|
|
34
34
|
id: string;
|
|
35
35
|
type: 'update_cell' | 'set_filter' | 'clear_filters' | 'set_sort' | 'go_to_page';
|
|
36
36
|
payload: Record<string, unknown>;
|
|
37
37
|
}
|
|
38
38
|
/** Minimal subset of IOGridApi used by the bridge. */
|
|
39
|
-
interface BridgeGridApi {
|
|
39
|
+
export interface BridgeGridApi {
|
|
40
40
|
updateSort?: (model: Array<{
|
|
41
41
|
columnId: string;
|
|
42
42
|
direction: 'asc' | 'desc';
|
|
@@ -46,7 +46,7 @@ interface BridgeGridApi {
|
|
|
46
46
|
goToPage?: (page: number) => void;
|
|
47
47
|
getSelectedRows?: () => unknown[];
|
|
48
48
|
}
|
|
49
|
-
interface ConnectGridOptions {
|
|
49
|
+
export interface ConnectGridOptions {
|
|
50
50
|
/** Unique identifier for this grid instance (shown in list_grids). */
|
|
51
51
|
gridId: string;
|
|
52
52
|
/** Returns the currently displayed rows. Called on every state push. */
|
|
@@ -76,12 +76,10 @@ interface ConnectGridOptions {
|
|
|
76
76
|
/** How often to push state and poll commands (ms, default: 500). */
|
|
77
77
|
pollIntervalMs?: number;
|
|
78
78
|
}
|
|
79
|
-
interface BridgeConnection {
|
|
79
|
+
export interface BridgeConnection {
|
|
80
80
|
/** Stop polling and disconnect. */
|
|
81
81
|
disconnect: () => void;
|
|
82
82
|
/** Manually push current state immediately. */
|
|
83
83
|
push: () => Promise<void>;
|
|
84
84
|
}
|
|
85
|
-
declare function connectGridToBridge(options: ConnectGridOptions): BridgeConnection;
|
|
86
|
-
|
|
87
|
-
export { type BridgeColumnInfo, type BridgeCommand, type BridgeConnection, type BridgeGridApi, type ConnectGridOptions, connectGridToBridge };
|
|
85
|
+
export declare function connectGridToBridge(options: ConnectGridOptions): BridgeConnection;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OGrid Live Testing Bridge
|
|
3
|
+
*
|
|
4
|
+
* An HTTP server (default port 7890) that running OGrid instances connect to.
|
|
5
|
+
* The MCP server holds a BridgeStore in-process and queries it directly when
|
|
6
|
+
* tools like list_grids / get_grid_state / send_grid_command are invoked.
|
|
7
|
+
*
|
|
8
|
+
* Protocol (used by bridge-client.ts in the browser):
|
|
9
|
+
* POST /grids/connect - register / heartbeat
|
|
10
|
+
* PUT /grids/:id/state - push current grid state
|
|
11
|
+
* GET /grids/:id/commands - poll for pending commands
|
|
12
|
+
* POST /grids/:id/commands/:cmdId/result - post command result
|
|
13
|
+
*
|
|
14
|
+
* Internal (used by MCP tools via BridgeStore directly):
|
|
15
|
+
* bridgeStore.listGrids()
|
|
16
|
+
* bridgeStore.getState(gridId)
|
|
17
|
+
* bridgeStore.enqueueCommand(gridId, cmd)
|
|
18
|
+
* bridgeStore.waitForResult(cmdId, timeoutMs)
|
|
19
|
+
*/
|
|
20
|
+
import { type IncomingMessage } from 'node:http';
|
|
21
|
+
export interface GridColumnInfo {
|
|
22
|
+
columnId: string;
|
|
23
|
+
headerName?: string;
|
|
24
|
+
type?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface GridStateSnapshot {
|
|
27
|
+
gridId: string;
|
|
28
|
+
connectedAt: number;
|
|
29
|
+
lastSeen: number;
|
|
30
|
+
rowCount: number;
|
|
31
|
+
totalCount: number;
|
|
32
|
+
page: number;
|
|
33
|
+
pageSize: number;
|
|
34
|
+
pageCount: number;
|
|
35
|
+
data: unknown[];
|
|
36
|
+
columns: GridColumnInfo[];
|
|
37
|
+
sortModel: Array<{
|
|
38
|
+
columnId: string;
|
|
39
|
+
direction: 'asc' | 'desc';
|
|
40
|
+
}>;
|
|
41
|
+
filterModel: Record<string, unknown>;
|
|
42
|
+
selectedRowIndices: number[];
|
|
43
|
+
}
|
|
44
|
+
export type GridCommandType = 'update_cell' | 'set_filter' | 'clear_filters' | 'set_sort' | 'go_to_page';
|
|
45
|
+
export interface GridCommand {
|
|
46
|
+
id: string;
|
|
47
|
+
type: GridCommandType;
|
|
48
|
+
payload: Record<string, unknown>;
|
|
49
|
+
createdAt: number;
|
|
50
|
+
status: 'pending' | 'completed' | 'error';
|
|
51
|
+
result?: unknown;
|
|
52
|
+
error?: string;
|
|
53
|
+
}
|
|
54
|
+
export declare class BridgeStore {
|
|
55
|
+
private readonly grids;
|
|
56
|
+
private readonly commandQueues;
|
|
57
|
+
private readonly commandResults;
|
|
58
|
+
private cmdSeq;
|
|
59
|
+
/** Drop stale grids, commands and results so a long-running bridge doesn't grow without bound. */
|
|
60
|
+
prune(now?: number): void;
|
|
61
|
+
upsertGrid(gridId: string, partial: Partial<GridStateSnapshot>): void;
|
|
62
|
+
popPendingCommands(gridId: string): GridCommand[];
|
|
63
|
+
resolveCommand(cmdId: string, result: unknown, error?: string): void;
|
|
64
|
+
listGrids(): GridStateSnapshot[];
|
|
65
|
+
getState(gridId: string): GridStateSnapshot | undefined;
|
|
66
|
+
enqueueCommand(gridId: string, type: GridCommandType, payload: Record<string, unknown>): GridCommand | null;
|
|
67
|
+
waitForResult(cmdId: string, timeoutMs?: number): Promise<GridCommand>;
|
|
68
|
+
}
|
|
69
|
+
/** Grid snapshots include row data, so allow a generous but finite body. */
|
|
70
|
+
export declare const MAX_BODY_BYTES: number;
|
|
71
|
+
/**
|
|
72
|
+
* Why a request must be refused, or null if it may proceed.
|
|
73
|
+
*
|
|
74
|
+
* CORS alone doesn't protect the bridge: "simple" requests (GET, or POST with
|
|
75
|
+
* a text/plain body) reach the server without a preflight, and their side
|
|
76
|
+
* effects happen even though the page can't read the response. So:
|
|
77
|
+
* - any Origin that isn't localhost is refused outright;
|
|
78
|
+
* - the Host must be loopback (blocks DNS rebinding, where a public name
|
|
79
|
+
* resolves to 127.0.0.1);
|
|
80
|
+
* - writes must be application/json, which forces a browser preflight.
|
|
81
|
+
*/
|
|
82
|
+
export declare function rejectReason(req: IncomingMessage): string | null;
|
|
83
|
+
export declare function startBridgeServer(store: BridgeStore, port?: number): Promise<() => Promise<void>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface CodeBlock {
|
|
2
|
+
language: string;
|
|
3
|
+
code: string;
|
|
4
|
+
framework?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DocEntry {
|
|
7
|
+
path: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description: string;
|
|
10
|
+
category: string;
|
|
11
|
+
content: string;
|
|
12
|
+
codeBlocks: CodeBlock[];
|
|
13
|
+
}
|
|
14
|
+
export interface DocsIndex {
|
|
15
|
+
entries: DocEntry[];
|
|
16
|
+
search(query: string, limit?: number): DocEntry[];
|
|
17
|
+
getByPath(path: string): DocEntry | undefined;
|
|
18
|
+
getByCategory(category: string): DocEntry[];
|
|
19
|
+
getCodeExamples(query: string, framework?: string): Array<{
|
|
20
|
+
entry: DocEntry;
|
|
21
|
+
block: CodeBlock;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
export declare function loadDocsIndex(docsDir: string): DocsIndex;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/index.js
CHANGED
|
@@ -858,6 +858,8 @@ Command: ${JSON.stringify({ type, payload }, null, 2)}`
|
|
|
858
858
|
}
|
|
859
859
|
return server2;
|
|
860
860
|
}
|
|
861
|
+
var GRID_TTL_MS = 10 * 6e4;
|
|
862
|
+
var COMMAND_TTL_MS = 5 * 6e4;
|
|
861
863
|
var BridgeStore = class {
|
|
862
864
|
constructor() {
|
|
863
865
|
this.grids = /* @__PURE__ */ new Map();
|
|
@@ -865,6 +867,22 @@ var BridgeStore = class {
|
|
|
865
867
|
this.commandResults = /* @__PURE__ */ new Map();
|
|
866
868
|
this.cmdSeq = 0;
|
|
867
869
|
}
|
|
870
|
+
/** Drop stale grids, commands and results so a long-running bridge doesn't grow without bound. */
|
|
871
|
+
prune(now = Date.now()) {
|
|
872
|
+
for (const [id, grid] of this.grids) {
|
|
873
|
+
if (now - grid.lastSeen > GRID_TTL_MS) {
|
|
874
|
+
this.grids.delete(id);
|
|
875
|
+
this.commandQueues.delete(id);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
for (const [id, queue] of this.commandQueues) {
|
|
879
|
+
const live = queue.filter((c) => now - c.createdAt <= COMMAND_TTL_MS);
|
|
880
|
+
if (live.length !== queue.length) this.commandQueues.set(id, live);
|
|
881
|
+
}
|
|
882
|
+
for (const [id, cmd] of this.commandResults) {
|
|
883
|
+
if (now - cmd.createdAt > COMMAND_TTL_MS) this.commandResults.delete(id);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
868
886
|
// ---- Called by HTTP handler ----
|
|
869
887
|
upsertGrid(gridId, partial) {
|
|
870
888
|
const existing = this.grids.get(gridId);
|
|
@@ -908,6 +926,7 @@ var BridgeStore = class {
|
|
|
908
926
|
cmd.result = result;
|
|
909
927
|
cmd.error = error;
|
|
910
928
|
this.commandResults.set(cmdId, { ...cmd });
|
|
929
|
+
queue.splice(queue.indexOf(cmd), 1);
|
|
911
930
|
return;
|
|
912
931
|
}
|
|
913
932
|
}
|
|
@@ -940,6 +959,7 @@ var BridgeStore = class {
|
|
|
940
959
|
const poll = () => {
|
|
941
960
|
const cmd = this.commandResults.get(cmdId);
|
|
942
961
|
if (cmd) {
|
|
962
|
+
this.commandResults.delete(cmdId);
|
|
943
963
|
resolve(cmd);
|
|
944
964
|
return;
|
|
945
965
|
}
|
|
@@ -953,10 +973,22 @@ var BridgeStore = class {
|
|
|
953
973
|
});
|
|
954
974
|
}
|
|
955
975
|
};
|
|
976
|
+
var MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
977
|
+
var PayloadTooLargeError = class extends Error {
|
|
978
|
+
};
|
|
956
979
|
function readBody(req) {
|
|
957
980
|
return new Promise((resolve, reject) => {
|
|
958
981
|
const chunks = [];
|
|
959
|
-
|
|
982
|
+
let size = 0;
|
|
983
|
+
req.on("data", (c) => {
|
|
984
|
+
size += c.length;
|
|
985
|
+
if (size > MAX_BODY_BYTES) {
|
|
986
|
+
req.destroy();
|
|
987
|
+
reject(new PayloadTooLargeError(`Body exceeds ${MAX_BODY_BYTES} bytes`));
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
chunks.push(c);
|
|
991
|
+
});
|
|
960
992
|
req.on("end", () => {
|
|
961
993
|
try {
|
|
962
994
|
resolve(JSON.parse(Buffer.concat(chunks).toString("utf-8") || "null"));
|
|
@@ -968,10 +1000,22 @@ function readBody(req) {
|
|
|
968
1000
|
});
|
|
969
1001
|
}
|
|
970
1002
|
var LOCALHOST_ORIGIN = /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/;
|
|
1003
|
+
var LOCALHOST_HOST = /^(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/;
|
|
971
1004
|
function corsOrigin(req) {
|
|
972
1005
|
const origin = req.headers.origin;
|
|
973
1006
|
return origin && LOCALHOST_ORIGIN.test(origin) ? origin : "";
|
|
974
1007
|
}
|
|
1008
|
+
function rejectReason(req) {
|
|
1009
|
+
const host = req.headers.host ?? "";
|
|
1010
|
+
if (!LOCALHOST_HOST.test(host)) return "Host must be localhost";
|
|
1011
|
+
const origin = req.headers.origin;
|
|
1012
|
+
if (origin && !LOCALHOST_ORIGIN.test(origin)) return "Origin not allowed";
|
|
1013
|
+
if (req.method === "POST" || req.method === "PUT") {
|
|
1014
|
+
const type = (req.headers["content-type"] ?? "").split(";")[0]?.trim().toLowerCase();
|
|
1015
|
+
if (type !== "application/json") return "Content-Type must be application/json";
|
|
1016
|
+
}
|
|
1017
|
+
return null;
|
|
1018
|
+
}
|
|
975
1019
|
function send(req, res, status, body) {
|
|
976
1020
|
const json = JSON.stringify(body);
|
|
977
1021
|
const headers = {
|
|
@@ -1001,6 +1045,12 @@ function startBridgeServer(store, port = 7890) {
|
|
|
1001
1045
|
res.end();
|
|
1002
1046
|
return;
|
|
1003
1047
|
}
|
|
1048
|
+
const refused = rejectReason(req);
|
|
1049
|
+
if (refused) {
|
|
1050
|
+
send(req, res, 403, { error: refused });
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
store.prune();
|
|
1004
1054
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
1005
1055
|
const parts = url.pathname.replace(/^\//, "").split("/");
|
|
1006
1056
|
try {
|
|
@@ -1043,6 +1093,10 @@ function startBridgeServer(store, port = 7890) {
|
|
|
1043
1093
|
}
|
|
1044
1094
|
send(req, res, 404, { error: "Not found" });
|
|
1045
1095
|
} catch (err) {
|
|
1096
|
+
if (err instanceof PayloadTooLargeError) {
|
|
1097
|
+
send(req, res, 413, { error: err.message });
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1046
1100
|
send(req, res, 500, { error: String(err) });
|
|
1047
1101
|
}
|
|
1048
1102
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.1",
|
|
4
4
|
"description": "MCP server for OGrid documentation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -12,12 +12,22 @@
|
|
|
12
12
|
"ogrid-mcp": "./dist/esm/index.js"
|
|
13
13
|
},
|
|
14
14
|
"main": "./dist/esm/index.js",
|
|
15
|
+
"types": "dist/esm/index.d.ts",
|
|
16
|
+
"typesVersions": {
|
|
17
|
+
"*": {
|
|
18
|
+
"bridge-client": [
|
|
19
|
+
"dist/esm/bridge-client.d.ts"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
15
23
|
"exports": {
|
|
16
24
|
".": {
|
|
25
|
+
"types": "./dist/esm/index.d.ts",
|
|
17
26
|
"import": "./dist/esm/index.js",
|
|
18
27
|
"default": "./dist/esm/index.js"
|
|
19
28
|
},
|
|
20
29
|
"./bridge-client": {
|
|
30
|
+
"types": "./dist/esm/bridge-client.d.ts",
|
|
21
31
|
"import": "./dist/esm/bridge-client.js",
|
|
22
32
|
"default": "./dist/esm/bridge-client.js"
|
|
23
33
|
}
|
|
@@ -28,18 +38,18 @@
|
|
|
28
38
|
],
|
|
29
39
|
"scripts": {
|
|
30
40
|
"prebuild": "node scripts/bundle-docs.mjs",
|
|
31
|
-
"build": "tsup",
|
|
41
|
+
"build": "tsup && tsc -p tsconfig.json --emitDeclarationOnly --outDir dist/esm && node ../../scripts/fix-dts-extensions.mjs dist/esm",
|
|
32
42
|
"dev": "tsup --watch",
|
|
33
43
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
34
44
|
"test": "bun test --preload ../../bun-test.setup.ts"
|
|
35
45
|
},
|
|
36
46
|
"dependencies": {
|
|
37
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
38
|
-
"zod": "^4.4
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
48
|
+
"zod": "^4.5.4"
|
|
39
49
|
},
|
|
40
50
|
"devDependencies": {
|
|
41
51
|
"tsup": "^8.5.1",
|
|
42
|
-
"typescript": "^
|
|
52
|
+
"typescript": "^7.0.2"
|
|
43
53
|
},
|
|
44
54
|
"engines": {
|
|
45
55
|
"node": ">=18"
|