@cyanheads/mcp-ts-core 0.8.11 → 0.8.13
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/CLAUDE.md +2 -1
- package/README.md +1 -1
- package/changelog/0.8.x/0.8.12.md +31 -0
- package/changelog/0.8.x/0.8.13.md +27 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -1
- package/dist/config/index.js.map +1 -1
- package/dist/logs/combined.log +4 -4
- package/dist/logs/error.log +4 -4
- package/dist/services/canvas/core/CanvasInstance.d.ts +16 -5
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js +22 -4
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +5 -11
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +5 -13
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/DataCanvas.d.ts +2 -3
- package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
- package/dist/services/canvas/core/DataCanvas.js +3 -8
- package/dist/services/canvas/core/DataCanvas.js.map +1 -1
- package/dist/services/canvas/core/IDataCanvasProvider.d.ts +24 -6
- package/dist/services/canvas/core/IDataCanvasProvider.d.ts.map +1 -1
- package/dist/services/canvas/core/IDataCanvasProvider.js +4 -4
- package/dist/services/canvas/core/canvasFactory.d.ts +7 -15
- package/dist/services/canvas/core/canvasFactory.d.ts.map +1 -1
- package/dist/services/canvas/core/canvasFactory.js +7 -16
- package/dist/services/canvas/core/canvasFactory.js.map +1 -1
- package/dist/services/canvas/core/sqlGate.d.ts +90 -60
- package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
- package/dist/services/canvas/core/sqlGate.js +231 -84
- package/dist/services/canvas/core/sqlGate.js.map +1 -1
- package/dist/services/canvas/index.d.ts +2 -2
- package/dist/services/canvas/index.d.ts.map +1 -1
- package/dist/services/canvas/index.js +1 -1
- package/dist/services/canvas/index.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +59 -17
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +364 -222
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +13 -25
- package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/exportWriter.js +15 -29
- package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts +19 -26
- package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/schemaSniffer.js +30 -56
- package/dist/services/canvas/providers/duckdb/schemaSniffer.js.map +1 -1
- package/dist/services/canvas/types.d.ts +33 -6
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/services/canvas/types.js +1 -2
- package/dist/services/canvas/types.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +9 -4
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/package.json +2 -2
- package/skills/api-canvas/SKILL.md +42 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataCanvas.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/DataCanvas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"DataCanvas.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/DataCanvas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAepE;;;;;;;;;;;GAWG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,cAAc;IAK3C;;;;OAIG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,cAAc,EACvB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,cAAc,CAAC;IAoB1B;;;OAGG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvE,kDAAkD;IAClD,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM;IAK/C,iDAAiD;IACjD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,kFAAkF;IAC5E,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,wEAAwE;IACxE,WAAW,IAAI,mBAAmB;CAGnC"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview User-facing DataCanvas service. Wraps the provider and registry
|
|
3
|
-
* with debug logging and tenant-id resolution; the registry handles TTL,
|
|
4
|
-
*
|
|
5
|
-
* stays OTel-free in v1 (per issue #97 scope).
|
|
3
|
+
* with debug logging and tenant-id resolution; the registry handles TTL, caps,
|
|
4
|
+
* and provider-keying.
|
|
6
5
|
* @module src/services/canvas/core/DataCanvas
|
|
7
6
|
*/
|
|
8
7
|
import { JsonRpcErrorCode, McpError } from '../../../types-global/errors.js';
|
|
9
8
|
import { logger } from '../../../utils/internal/logger.js';
|
|
10
9
|
import { CanvasInstance } from './CanvasInstance.js';
|
|
11
|
-
/**
|
|
12
|
-
* Resolve the effective tenant ID from the context, throwing when absent.
|
|
13
|
-
* Mirrors `requireTenantId` in StorageService — canvas operations are
|
|
14
|
-
* tenant-scoped by construction.
|
|
15
|
-
*/
|
|
10
|
+
/** Resolve the effective tenant ID; throw when absent. */
|
|
16
11
|
function requireTenantId(context) {
|
|
17
12
|
const tenantId = context.tenantId;
|
|
18
13
|
if (tenantId === undefined || tenantId === null || tenantId === '') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataCanvas.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/DataCanvas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"DataCanvas.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/DataCanvas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,0DAA0D;AAC1D,SAAS,eAAe,CAAC,OAAuB;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACnE,MAAM,IAAI,QAAQ,CAChB,gBAAgB,CAAC,aAAa,EAC9B,uFAAuF,EACvF,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,oBAAoB,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACvF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,UAAU;IAEF;IACA;IAFnB,YACmB,QAA6B,EAC7B,QAAwB;QADxB,aAAQ,GAAR,QAAQ,CAAqB;QAC7B,aAAQ,GAAR,QAAQ,CAAgB;QAEzC,MAAM,CAAC,IAAI,CAAC,yCAAyC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CACX,OAA2B,EAC3B,OAAuB,EACvB,QAAyB;QAEzB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE;YAC/B,GAAG,OAAO;YACV,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ;YACR,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,cAAc,CACvB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,SAAS,EAChB,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,QAAQ,EACb,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,OAAuB;QAClD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED,kDAAkD;IAClD,cAAc,CAAC,OAAuB;QACpC,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,iDAAiD;IACjD,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,QAAQ,CAAC,OAAuB;QACpC,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,wEAAwE;IACxE,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Engine-level provider interface for the DataCanvas primitive.
|
|
3
|
-
* Implementations own
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Implementations own physical resources per canvas (e.g. one DuckDB instance
|
|
4
|
+
* per canvasId) and expose register/query/export/describe keyed by canvasId.
|
|
5
|
+
* The lifecycle wrapper ({@link CanvasRegistry}) handles TTL, caps, and the
|
|
6
|
+
* tenant authorization check before any provider call.
|
|
7
7
|
* @module src/services/canvas/core/IDataCanvasProvider
|
|
8
8
|
*/
|
|
9
9
|
import type { RequestContext } from '../../../utils/internal/requestContext.js';
|
|
10
|
-
import type { DescribeOptions, ExportOptions, ExportResult, ExportTarget, QueryOptions, QueryResult, RegisterRows, RegisterTableOptions, RegisterTableResult, TableInfo } from '../types.js';
|
|
10
|
+
import type { DescribeOptions, ExportOptions, ExportResult, ExportTarget, ImportFromOptions, QueryOptions, QueryResult, RegisterRows, RegisterTableOptions, RegisterTableResult, RegisterViewOptions, RegisterViewResult, TableInfo } from '../types.js';
|
|
11
11
|
/**
|
|
12
12
|
* Engine-level contract. The lifecycle wrapper guarantees `canvasId` is
|
|
13
13
|
* already validated and authorized for the caller's tenant before any of
|
|
@@ -24,12 +24,23 @@ export interface IDataCanvasProvider {
|
|
|
24
24
|
* the canvas throw `NotFound`.
|
|
25
25
|
*/
|
|
26
26
|
destroyCanvas(canvasId: string, context: RequestContext): Promise<void>;
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Drop a single canvas table or view. Returns `true` when found and removed.
|
|
29
|
+
* The provider determines the kind from the catalog; callers don't need to
|
|
30
|
+
* distinguish.
|
|
31
|
+
*/
|
|
28
32
|
drop(canvasId: string, name: string, context: RequestContext): Promise<boolean>;
|
|
29
33
|
/** Export a canvas table to a file or stream target. */
|
|
30
34
|
export(canvasId: string, tableName: string, target: ExportTarget, context: RequestContext, options?: ExportOptions): Promise<ExportResult>;
|
|
31
35
|
/** Liveness check on the underlying engine. */
|
|
32
36
|
healthCheck(): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Copy a table from another canvas (`sourceCanvasId`) into this one as
|
|
39
|
+
* `asName`. Both canvases must already be authorized for the caller —
|
|
40
|
+
* the lifecycle wrapper validates tenancy on both ids before this call.
|
|
41
|
+
* Idempotent: a pre-existing target table with the same name is replaced.
|
|
42
|
+
*/
|
|
43
|
+
importFrom(targetCanvasId: string, sourceCanvasId: string, sourceTableName: string, asName: string, context: RequestContext, options?: ImportFromOptions): Promise<RegisterTableResult>;
|
|
33
44
|
/**
|
|
34
45
|
* Allocate engine resources for a new canvas. Idempotent — calling twice
|
|
35
46
|
* with the same id is a no-op.
|
|
@@ -41,6 +52,13 @@ export interface IDataCanvasProvider {
|
|
|
41
52
|
query(canvasId: string, sql: string, context: RequestContext, options?: QueryOptions): Promise<QueryResult>;
|
|
42
53
|
/** Register a table on the canvas from in-memory or async iterator rows. */
|
|
43
54
|
registerTable(canvasId: string, name: string, rows: RegisterRows, context: RequestContext, options?: RegisterTableOptions): Promise<RegisterTableResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Register a SQL view on the canvas. The provider gates `selectSql` through
|
|
57
|
+
* the same read-only enforcement `query()` applies, then installs the view.
|
|
58
|
+
* Re-registering an existing view replaces it; conflicting with a base
|
|
59
|
+
* table of the same name throws `ValidationError`.
|
|
60
|
+
*/
|
|
61
|
+
registerView(canvasId: string, name: string, selectSql: string, context: RequestContext, options?: RegisterViewOptions): Promise<RegisterViewResult>;
|
|
44
62
|
/** Tear down all engine resources. Called from `ServerHandle.shutdown()`. */
|
|
45
63
|
shutdown(): Promise<void>;
|
|
46
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDataCanvasProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/IDataCanvasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElE,gDAAgD;IAChD,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAExB;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE
|
|
1
|
+
{"version":3,"file":"IDataCanvasProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/IDataCanvasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElE,gDAAgD;IAChD,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAExB;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE;;;;OAIG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhF,wDAAwD;IACxD,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB,+CAA+C;IAC/C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhC;;;;;OAKG;IACH,UAAU,CACR,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEhC;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,mFAAmF;IACnF,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,4EAA4E;IAC5E,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEhC;;;;;OAKG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B,6EAA6E;IAC7E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Engine-level provider interface for the DataCanvas primitive.
|
|
3
|
-
* Implementations own
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Implementations own physical resources per canvas (e.g. one DuckDB instance
|
|
4
|
+
* per canvasId) and expose register/query/export/describe keyed by canvasId.
|
|
5
|
+
* The lifecycle wrapper ({@link CanvasRegistry}) handles TTL, caps, and the
|
|
6
|
+
* tenant authorization check before any provider call.
|
|
7
7
|
* @module src/services/canvas/core/IDataCanvasProvider
|
|
8
8
|
*/
|
|
9
9
|
export {};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Factory for the optional DataCanvas service.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* The factory does NOT eager-load `@duckdb/node-api`; the provider lazy-loads
|
|
8
|
-
* on first use via `lazyImport`. Servers that set `CANVAS_PROVIDER_TYPE=none`
|
|
9
|
-
* (the default) pay zero install cost.
|
|
2
|
+
* @fileoverview Factory for the optional DataCanvas service. Switches on
|
|
3
|
+
* `config.canvas.providerType`, fails closed in serverless for `duckdb`, and
|
|
4
|
+
* returns `undefined` when canvas is disabled. The factory does not eager-load
|
|
5
|
+
* `@duckdb/node-api`; the provider lazy-loads on first use.
|
|
10
6
|
*
|
|
11
7
|
* @module src/services/canvas/core/canvasFactory
|
|
12
8
|
*/
|
|
@@ -14,13 +10,9 @@ import type { AppConfig } from '../../../config/index.js';
|
|
|
14
10
|
import { DataCanvas } from './DataCanvas.js';
|
|
15
11
|
/**
|
|
16
12
|
* Construct the canvas service from configuration. Returns `undefined` when
|
|
17
|
-
* canvas is disabled
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* In serverless environments, an explicit `CANVAS_PROVIDER_TYPE=duckdb`
|
|
21
|
-
* fails closed with a clear ConfigurationError — DuckDB has no V8-isolate
|
|
22
|
-
* build, so canvas is unavailable on Workers. (Refinement #1 in issue #97 is
|
|
23
|
-
* about export-path sandboxing, separate from this Worker fail-closed.)
|
|
13
|
+
* canvas is disabled. Fails closed with `ConfigurationError` in serverless
|
|
14
|
+
* environments when `CANVAS_PROVIDER_TYPE=duckdb` — DuckDB has no V8-isolate
|
|
15
|
+
* build, so canvas is unavailable on Workers.
|
|
24
16
|
*/
|
|
25
17
|
export declare function createCanvasService(config: AppConfig): DataCanvas | undefined;
|
|
26
18
|
//# sourceMappingURL=canvasFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasFactory.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/canvasFactory.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"canvasFactory.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/canvasFactory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAiC7E"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Factory for the optional DataCanvas service.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* The factory does NOT eager-load `@duckdb/node-api`; the provider lazy-loads
|
|
8
|
-
* on first use via `lazyImport`. Servers that set `CANVAS_PROVIDER_TYPE=none`
|
|
9
|
-
* (the default) pay zero install cost.
|
|
2
|
+
* @fileoverview Factory for the optional DataCanvas service. Switches on
|
|
3
|
+
* `config.canvas.providerType`, fails closed in serverless for `duckdb`, and
|
|
4
|
+
* returns `undefined` when canvas is disabled. The factory does not eager-load
|
|
5
|
+
* `@duckdb/node-api`; the provider lazy-loads on first use.
|
|
10
6
|
*
|
|
11
7
|
* @module src/services/canvas/core/canvasFactory
|
|
12
8
|
*/
|
|
@@ -22,13 +18,9 @@ function isServerless() {
|
|
|
22
18
|
}
|
|
23
19
|
/**
|
|
24
20
|
* Construct the canvas service from configuration. Returns `undefined` when
|
|
25
|
-
* canvas is disabled
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* In serverless environments, an explicit `CANVAS_PROVIDER_TYPE=duckdb`
|
|
29
|
-
* fails closed with a clear ConfigurationError — DuckDB has no V8-isolate
|
|
30
|
-
* build, so canvas is unavailable on Workers. (Refinement #1 in issue #97 is
|
|
31
|
-
* about export-path sandboxing, separate from this Worker fail-closed.)
|
|
21
|
+
* canvas is disabled. Fails closed with `ConfigurationError` in serverless
|
|
22
|
+
* environments when `CANVAS_PROVIDER_TYPE=duckdb` — DuckDB has no V8-isolate
|
|
23
|
+
* build, so canvas is unavailable on Workers.
|
|
32
24
|
*/
|
|
33
25
|
export function createCanvasService(config) {
|
|
34
26
|
const providerType = config.canvas.providerType;
|
|
@@ -56,7 +48,6 @@ export function createCanvasService(config) {
|
|
|
56
48
|
});
|
|
57
49
|
return new DataCanvas(provider, registry);
|
|
58
50
|
}
|
|
59
|
-
// Exhaustive check for the providerType union.
|
|
60
51
|
const exhaustive = providerType;
|
|
61
52
|
throw configurationError(`Unhandled canvas provider type: ${String(exhaustive)}`, context);
|
|
62
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasFactory.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/canvasFactory.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"canvasFactory.js","sourceRoot":"","sources":["../../../../src/services/canvas/core/canvasFactory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,kFAAkF;AAClF,SAAS,YAAY;IACnB,OAAO,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM,CAAC;AAChF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;IAChD,IAAI,YAAY,KAAK,MAAM;QAAE,OAAO;IAEpC,MAAM,OAAO,GAAG,qBAAqB,CAAC,oBAAoB,CAAC;QACzD,SAAS,EAAE,qBAAqB;KACjC,CAAC,CAAC;IAEH,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,YAAY,EAAE,EAAE,CAAC;YACnB,MAAM,kBAAkB,CACtB,oHAAoH,EACpH,OAAO,CACR,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC;YAClC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,oBAAoB;YACjD,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc;YAC5C,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe;YAC9C,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe;SAC/C,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE;YAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;YAC1B,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;YAC1C,oBAAoB,EAAE,MAAM,CAAC,MAAM,CAAC,oBAAoB;YACxD,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB;SACnD,CAAC,CAAC;QACH,OAAO,IAAI,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,UAAU,GAAU,YAAY,CAAC;IACvC,MAAM,kBAAkB,CAAC,mCAAmC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC7F,CAAC"}
|
|
@@ -1,61 +1,85 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Read-only SQL gate for the DataCanvas primitive. Engine-agnostic
|
|
3
|
-
* pure validators
|
|
4
|
-
* metadata (statement extraction, prepared-statement type, EXPLAIN plan JSON).
|
|
3
|
+
* pure validators the provider invokes after pulling DuckDB-specific metadata.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Four layers of enforcement, each authoritative:
|
|
7
6
|
*
|
|
8
|
-
* 1. **
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 2. **
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
7
|
+
* 1. **Function deny-list (text scan).** Pre-EXPLAIN regex against the SQL
|
|
8
|
+
* (string literals stripped) for file/HTTP-reading table functions like
|
|
9
|
+
* `read_json`, `read_parquet`. These can lower into generic SEQ_SCAN
|
|
10
|
+
* operators that pass the operator allowlist; catching them by name closes
|
|
11
|
+
* that bypass.
|
|
12
|
+
* 2. **Single-statement check.** Reject anything other than exactly one
|
|
13
|
+
* statement parsed by DuckDB. Comment-hidden second statements, Unicode
|
|
14
|
+
* tricks, and multi-statement smuggling collapse here.
|
|
15
|
+
* 3. **Statement-type check.** Require `SELECT`. DDL, DML, and utility
|
|
16
|
+
* statements (PRAGMA/ATTACH/COPY/INSTALL/LOAD/SET/EXECUTE) fail to type as
|
|
17
|
+
* SELECT.
|
|
18
|
+
* 4. **Plan-walk allowlist + denied-function rescan.** Walk the
|
|
19
|
+
* `EXPLAIN (FORMAT JSON)` tree; reject any operator outside the allowlist
|
|
20
|
+
* or any string field referencing a deny-listed function.
|
|
21
21
|
*
|
|
22
|
-
* Rejection paths throw `ValidationError` with a structured `data.reason
|
|
23
|
-
* suitable for surfacing to the agent.
|
|
22
|
+
* Rejection paths throw `ValidationError` with a structured `data.reason`.
|
|
24
23
|
*
|
|
25
24
|
* @module src/services/canvas/core/sqlGate
|
|
26
25
|
*/
|
|
27
26
|
/**
|
|
28
|
-
* DuckDB statement-type
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `INSTALL`, `SET`, `RESET`, `EXECUTE`, `EXPLAIN`, `TRANSACTION`, `VACUUM`,
|
|
32
|
-
* `CHECKPOINT`, `CALL`, …) are rejected outright. This is a surface — not
|
|
33
|
-
* an enum we own — so the gate matches on the literal string emitted.
|
|
27
|
+
* DuckDB statement-type string. Only `SELECT` is accepted; everything else
|
|
28
|
+
* (DDL, DML, utility) is rejected. Modeled as a string surface rather than an
|
|
29
|
+
* owned enum so the gate matches on whatever DuckDB emits.
|
|
34
30
|
*/
|
|
35
31
|
export type DuckdbStatementType = string;
|
|
36
32
|
/** Subset of statement types the gate permits. */
|
|
37
33
|
export declare const ALLOWED_STATEMENT_TYPES: ReadonlySet<DuckdbStatementType>;
|
|
38
34
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
* Reason codes set on `validationError.data.reason` by gate assertions.
|
|
36
|
+
* Consumers can import the {@link SqlGateReason} union to translate gate
|
|
37
|
+
* denials into typed contract reasons without duplicating the strings.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SQL_GATE_REASONS: {
|
|
40
|
+
readonly multiStatement: "multi_statement";
|
|
41
|
+
readonly nonSelectStatement: "non_select_statement";
|
|
42
|
+
readonly planOperatorNotAllowed: "plan_operator_not_allowed";
|
|
43
|
+
readonly deniedFunction: "denied_function";
|
|
44
|
+
readonly deniedFunctionInPlan: "denied_function_in_plan";
|
|
45
|
+
readonly identifierEmpty: "identifier_empty";
|
|
46
|
+
readonly identifierShape: "identifier_shape";
|
|
47
|
+
readonly identifierReserved: "identifier_reserved";
|
|
48
|
+
};
|
|
49
|
+
/** Union of all gate reason strings — see {@link SQL_GATE_REASONS}. */
|
|
50
|
+
export type SqlGateReason = (typeof SQL_GATE_REASONS)[keyof typeof SQL_GATE_REASONS];
|
|
51
|
+
/**
|
|
52
|
+
* Allowlist of read-only operator names that can appear in an EXPLAIN plan.
|
|
53
|
+
* Anything outside this set causes rejection. Notable exclusions:
|
|
48
54
|
*
|
|
49
55
|
* - `READ_CSV`, `READ_PARQUET`, `READ_JSON` — bypass canvas, read external files.
|
|
50
|
-
* - `INSERT`, `UPDATE`, `DELETE`, `
|
|
51
|
-
* - `COPY_TO_FILE`, `BATCH_COPY_TO_FILE` —
|
|
52
|
-
* - `ATTACH`, `DETACH`, `LOAD`, `
|
|
56
|
+
* - `INSERT`, `UPDATE`, `DELETE`, `MERGE_INTO`, `CREATE_*`, `DROP`, `ALTER` — writes.
|
|
57
|
+
* - `COPY_TO_FILE`, `BATCH_COPY_TO_FILE`, `COPY_DATABASE` — write a SELECT to a file/db.
|
|
58
|
+
* - `ATTACH`, `DETACH`, `LOAD`, `PRAGMA`, `SET`, `SET_VARIABLE`, `RESET`, `TRANSACTION`,
|
|
59
|
+
* `EXECUTE`, `PREPARE`, `VACUUM`, `EXPORT`, `EXPLAIN_ANALYZE`, `CREATE_SECRET` — utility/system.
|
|
60
|
+
* - `INOUT_FUNCTION` — table-valued function lowering (read_json/read_parquet/...);
|
|
61
|
+
* gated by the function deny-list rather than the operator allowlist.
|
|
62
|
+
*
|
|
63
|
+
* Source pinned against `PhysicalOperatorToString` in DuckDB v1.5.2:
|
|
64
|
+
* https://github.com/duckdb/duckdb/blob/v1.5.2/src/common/enums/physical_operator_type.cpp
|
|
53
65
|
*/
|
|
54
66
|
export declare const ALLOWED_PLAN_OPERATORS: ReadonlySet<string>;
|
|
55
67
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
68
|
+
* External-data table functions (files, HTTP, S3, lakehouse formats). These
|
|
69
|
+
* lower into generic scan operators that pass the operator allowlist, so the
|
|
70
|
+
* text-scan and plan-rescan defenses in this module catch them by name
|
|
71
|
+
* regardless of how DuckDB lowers them.
|
|
72
|
+
*/
|
|
73
|
+
export declare const DENIED_TABLE_FUNCTIONS: ReadonlySet<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Layer 1: pre-EXPLAIN function deny-list. Scans the SQL (string literals
|
|
76
|
+
* stripped) for calls to any function in {@link DENIED_TABLE_FUNCTIONS} so a
|
|
77
|
+
* malicious `read_json('/etc/passwd')` is rejected before reaching the planner.
|
|
78
|
+
*/
|
|
79
|
+
export declare function assertNoDeniedFunctions(sql: string): void;
|
|
80
|
+
/**
|
|
81
|
+
* Layers 2-4. Throws on the first violation. Layer 1
|
|
82
|
+
* ({@link assertNoDeniedFunctions}) runs separately before `extractStatements`.
|
|
59
83
|
*/
|
|
60
84
|
export declare function assertReadOnlyQuery(input: {
|
|
61
85
|
/** Number of statements DuckDB extracted from the user-supplied SQL. */
|
|
@@ -66,42 +90,48 @@ export declare function assertReadOnlyQuery(input: {
|
|
|
66
90
|
planJson: unknown;
|
|
67
91
|
}): void;
|
|
68
92
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* here rather than a confusing parser error from EXPLAIN itself.
|
|
93
|
+
* Layers 2-3: validate statement count and type before EXPLAIN. Non-SELECT
|
|
94
|
+
* statements (ATTACH/PRAGMA/COPY/INSTALL/...) fail here with a structured
|
|
95
|
+
* ValidationError rather than a confusing parser error from EXPLAIN itself.
|
|
73
96
|
*/
|
|
74
97
|
export declare function assertSelectOnly(input: {
|
|
75
98
|
statementCount: number;
|
|
76
99
|
statementType: DuckdbStatementType;
|
|
77
100
|
}): void;
|
|
78
101
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* smuggle work into a SELECT envelope.
|
|
102
|
+
* Layer 4: walk the plan tree and reject any operator outside the allowlist
|
|
103
|
+
* or any deny-listed table function smuggled into a generic scan operator.
|
|
82
104
|
*/
|
|
83
105
|
export declare function assertPlanReadOnly(planJson: unknown): void;
|
|
84
106
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* Tolerant of structural variation — DuckDB emits operator identity under
|
|
90
|
-
* either `name` (logical plan) or `operator_type` (physical/profile plan)
|
|
91
|
-
* depending on the EXPLAIN flavor. We honor both. Children traversal
|
|
92
|
-
* supports `children`, `child`, and `inputs` arrays.
|
|
107
|
+
* Returns operator names not in `ALLOWED_PLAN_OPERATORS`. Exported for
|
|
108
|
+
* fixture-driven tests that want to inspect the gate's view without throwing.
|
|
109
|
+
* Use {@link collectPlanViolations} to also surface deny-listed function
|
|
110
|
+
* references in scan-operator metadata.
|
|
93
111
|
*/
|
|
94
112
|
export declare function collectDisallowedOperators(planJson: unknown): Set<string>;
|
|
95
113
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
114
|
+
* Combined plan-walk: disallowed operators and deny-listed table-function
|
|
115
|
+
* references in string-valued fields, returned separately so callers can word
|
|
116
|
+
* errors appropriately.
|
|
117
|
+
*/
|
|
118
|
+
export declare function collectPlanViolations(planJson: unknown): {
|
|
119
|
+
offending: Set<string>;
|
|
120
|
+
deniedFunctions: Set<string>;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Allowed shape for canvas table/column names. SQL identifier convention:
|
|
124
|
+
* letter/underscore start, letters/digits/underscores after, max 63 chars
|
|
125
|
+
* (PostgreSQL/DuckDB cap). Exported so consumers can reuse it in Zod schemas
|
|
126
|
+
* (`z.string().regex(CANVAS_IDENTIFIER_REGEX)`).
|
|
98
127
|
*/
|
|
128
|
+
export declare const CANVAS_IDENTIFIER_REGEX: RegExp;
|
|
129
|
+
/** Validate a canvas table or column name. Throws `ValidationError` on rejection. */
|
|
99
130
|
export declare function assertValidIdentifier(value: string, kind: 'table' | 'column'): void;
|
|
100
131
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* only escapes; it does not validate shape.
|
|
132
|
+
* Double-quote-escape an identifier for SQL embedding. Validate via
|
|
133
|
+
* {@link assertValidIdentifier} first — this helper only escapes, it does not
|
|
134
|
+
* check shape.
|
|
105
135
|
*/
|
|
106
136
|
export declare function quoteIdentifier(value: string): string;
|
|
107
137
|
//# sourceMappingURL=sqlGate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlGate.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlGate.d.ts","sourceRoot":"","sources":["../../../../src/services/canvas/core/sqlGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEzC,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,mBAAmB,CAAuB,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC;AAEX,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAErF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAuErD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CA2CrD,CAAC;AA4CH;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,aAAa,EAAE,mBAAmB,CAAC;IACnC,8CAA8C;IAC9C,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,IAAI,CAGP;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,mBAAmB,CAAC;CACpC,GAAG,IAAI,CAaP;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAoB1D;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG;IACxD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC9B,CAKA;AAmDD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAkC,CAAC;AA6CvE,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAmBnF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD"}
|