@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.
Files changed (57) hide show
  1. package/CLAUDE.md +2 -1
  2. package/README.md +1 -1
  3. package/changelog/0.8.x/0.8.12.md +31 -0
  4. package/changelog/0.8.x/0.8.13.md +27 -0
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/index.js +6 -1
  7. package/dist/config/index.js.map +1 -1
  8. package/dist/logs/combined.log +4 -4
  9. package/dist/logs/error.log +4 -4
  10. package/dist/services/canvas/core/CanvasInstance.d.ts +16 -5
  11. package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
  12. package/dist/services/canvas/core/CanvasInstance.js +22 -4
  13. package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
  14. package/dist/services/canvas/core/CanvasRegistry.d.ts +5 -11
  15. package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
  16. package/dist/services/canvas/core/CanvasRegistry.js +5 -13
  17. package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
  18. package/dist/services/canvas/core/DataCanvas.d.ts +2 -3
  19. package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
  20. package/dist/services/canvas/core/DataCanvas.js +3 -8
  21. package/dist/services/canvas/core/DataCanvas.js.map +1 -1
  22. package/dist/services/canvas/core/IDataCanvasProvider.d.ts +24 -6
  23. package/dist/services/canvas/core/IDataCanvasProvider.d.ts.map +1 -1
  24. package/dist/services/canvas/core/IDataCanvasProvider.js +4 -4
  25. package/dist/services/canvas/core/canvasFactory.d.ts +7 -15
  26. package/dist/services/canvas/core/canvasFactory.d.ts.map +1 -1
  27. package/dist/services/canvas/core/canvasFactory.js +7 -16
  28. package/dist/services/canvas/core/canvasFactory.js.map +1 -1
  29. package/dist/services/canvas/core/sqlGate.d.ts +90 -60
  30. package/dist/services/canvas/core/sqlGate.d.ts.map +1 -1
  31. package/dist/services/canvas/core/sqlGate.js +231 -84
  32. package/dist/services/canvas/core/sqlGate.js.map +1 -1
  33. package/dist/services/canvas/index.d.ts +2 -2
  34. package/dist/services/canvas/index.d.ts.map +1 -1
  35. package/dist/services/canvas/index.js +1 -1
  36. package/dist/services/canvas/index.js.map +1 -1
  37. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +59 -17
  38. package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
  39. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +364 -222
  40. package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
  41. package/dist/services/canvas/providers/duckdb/exportWriter.d.ts +13 -25
  42. package/dist/services/canvas/providers/duckdb/exportWriter.d.ts.map +1 -1
  43. package/dist/services/canvas/providers/duckdb/exportWriter.js +15 -29
  44. package/dist/services/canvas/providers/duckdb/exportWriter.js.map +1 -1
  45. package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts +19 -26
  46. package/dist/services/canvas/providers/duckdb/schemaSniffer.d.ts.map +1 -1
  47. package/dist/services/canvas/providers/duckdb/schemaSniffer.js +30 -56
  48. package/dist/services/canvas/providers/duckdb/schemaSniffer.js.map +1 -1
  49. package/dist/services/canvas/types.d.ts +33 -6
  50. package/dist/services/canvas/types.d.ts.map +1 -1
  51. package/dist/services/canvas/types.js +1 -2
  52. package/dist/services/canvas/types.js.map +1 -1
  53. package/dist/utils/internal/requestContext.d.ts +9 -4
  54. package/dist/utils/internal/requestContext.d.ts.map +1 -1
  55. package/dist/utils/internal/requestContext.js.map +1 -1
  56. package/package.json +2 -2
  57. 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;;;;;;GAMG;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;AAmBpE;;;;;;;;;;;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
+ {"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
- * caps, and provider-keying. Mirrors the StorageService surface pattern but
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;;;;;;GAMG;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;;;;GAIG;AACH,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
+ {"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 the physical resources backing each canvas (e.g. one
4
- * DuckDB instance per canvasId) and expose register/query/export/describe
5
- * operations keyed by canvasId. The lifecycle wrapper ({@link CanvasRegistry})
6
- * keys these calls by `(tenantId, canvasId)` and enforces TTL/caps.
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
- /** Drop a single canvas table. Returns `true` when found and removed. */
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,yEAAyE;IACzE,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;;;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,6EAA6E;IAC7E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
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 the physical resources backing each canvas (e.g. one
4
- * DuckDB instance per canvasId) and expose register/query/export/describe
5
- * operations keyed by canvasId. The lifecycle wrapper ({@link CanvasRegistry})
6
- * keys these calls by `(tenantId, canvasId)` and enforces TTL/caps.
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. Mirrors the
3
- * pattern in `createStorageProvider` switches on `config.canvas.providerType`,
4
- * fails closed in serverless environments for `duckdb`, and returns
5
- * `undefined` when canvas is disabled (`'none'`).
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 (`CANVAS_PROVIDER_TYPE=none`), keeping `core.canvas`
18
- * `undefined` on `CoreServices` for that case.
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;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAkC7E"}
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. Mirrors the
3
- * pattern in `createStorageProvider` switches on `config.canvas.providerType`,
4
- * fails closed in serverless environments for `duckdb`, and returns
5
- * `undefined` when canvas is disabled (`'none'`).
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 (`CANVAS_PROVIDER_TYPE=none`), keeping `core.canvas`
26
- * `undefined` on `CoreServices` for that case.
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;;;;;;;;;;;GAWG;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;;;;;;;;;GASG;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,+CAA+C;IAC/C,MAAM,UAAU,GAAU,YAAY,CAAC;IACvC,MAAM,kBAAkB,CAAC,mCAAmC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC7F,CAAC"}
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 that the provider invokes after pulling DuckDB-specific
4
- * metadata (statement extraction, prepared-statement type, EXPLAIN plan JSON).
3
+ * pure validators the provider invokes after pulling DuckDB-specific metadata.
5
4
  *
6
- * Three layers of enforcement, each authoritative on its own:
5
+ * Four layers of enforcement, each authoritative:
7
6
  *
8
- * 1. **Single-statement check.** The provider parses the input via DuckDB's
9
- * `extractStatements` and passes the count here. Anything other than 1 is
10
- * rejected comment-hidden second statements, multi-statement smuggling,
11
- * and Unicode tricks all collapse here because DuckDB's parser is the
12
- * arbiter, not a regex.
13
- * 2. **Statement-type check.** The provider prepares the single statement and
14
- * passes the resulting `statementType`. We require `SELECT`. Any DDL, DML,
15
- * or utility (PRAGMA/ATTACH/COPY/INSTALL/LOAD/SET/EXECUTE) fails to type as
16
- * SELECT and is rejected here.
17
- * 3. **Plan-walk allowlist.** The provider runs `EXPLAIN (FORMAT JSON)` and
18
- * passes the plan JSON. We walk every node and reject if any operator
19
- * name is outside the curated allowlist defense-in-depth against future
20
- * DuckDB additions that might smuggle work into a SELECT envelope.
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 strings emitted by the Neo client. Only `SELECT` is
29
- * accepted by the canvas. Other values (`INSERT`, `UPDATE`, `DELETE`,
30
- * `CREATE`, `DROP`, `ALTER`, `COPY`, `PRAGMA`, `ATTACH`, `DETACH`, `LOAD`,
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
- * Curated allowlist of operator names that can appear in an EXPLAIN plan.
40
- * Sourced from DuckDB's logical/physical-plan node families (1.5.x). Not
41
- * every member is reachable from a SELECT but every member is read-only.
42
- *
43
- * Pinned by `tests/canvas/sqlGate.fixtures.test.ts` against live DuckDB
44
- * EXPLAIN output so version bumps that add operators are caught in CI rather
45
- * than silently widening the gate.
46
- *
47
- * Operators **not** in this list cause rejection. Notable exclusions:
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`, `MERGE`, `CREATE_*`, `DROP_*`, `ALTER_*` — writes.
51
- * - `COPY_TO_FILE`, `BATCH_COPY_TO_FILE` — exports a SELECT to a file.
52
- * - `ATTACH`, `DETACH`, `LOAD`, `INSTALL`, `PRAGMA`, `SET`, `RESET` — utility.
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
- * Public entry point validates the trio of `(statementCount, statementType,
57
- * planJson)`. Throws on the first violation, leaving the provider to pass
58
- * results back to the caller untouched on success.
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
- * Pre-EXPLAIN gate: validate statement count and type. Run before the EXPLAIN
70
- * call so non-SELECT statements (which DuckDB's EXPLAIN can't always wrap —
71
- * e.g. ATTACH/PRAGMA/COPY/INSTALL) fail with a structured ValidationError
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
- * Post-EXPLAIN gate: walk the plan tree and reject any operator outside the
80
- * curated allowlist. Defense-in-depth against future DuckDB additions that
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
- * Walks the EXPLAIN plan and returns the set of operator names not in
86
- * `ALLOWED_PLAN_OPERATORS`. Exported for fixture-driven tests that want
87
- * to inspect the gate's view of a plan without throwing.
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
- * Validate an identifier for use as a canvas-local table or column name.
97
- * Throws `ValidationError` on rejection.
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
- * Wrap an identifier in double quotes for safe inclusion in SQL. Internal
102
- * double quotes are doubled per the SQL standard. Callers should still
103
- * validate via {@link assertValidIdentifier} before quoting — this helper
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;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEzC,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,mBAAmB,CAAuB,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAwDrD,CAAC;AAEH;;;;GAIG;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;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,mBAAmB,CAAC;CACpC,GAAG,IAAI,CAaP;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAW1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAIzE;AAsFD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAmBnF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD"}
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"}