@objectql/types 4.1.0 → 4.2.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/dist/action.d.ts CHANGED
@@ -6,7 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  import { UI } from '@objectstack/spec';
9
- type Action = UI.Action;
9
+ import { z } from 'zod';
10
+ type Action = z.infer<typeof UI.ActionSchema>;
10
11
  import { FieldConfig } from "./field";
11
12
  import { HookAPI } from "./hook";
12
13
  /**
@@ -35,7 +36,7 @@ export type ActionInputDefinition = Record<string, FieldConfig>;
35
36
  *
36
37
  * RUNTIME TYPE: Used during action execution.
37
38
  */
38
- export interface ActionContext<BaseT = any, InputT = any> {
39
+ export interface ActionContext<_BaseT = Record<string, unknown>, InputT = Record<string, unknown>> {
39
40
  /** The object this action belongs to. */
40
41
  objectName: string;
41
42
  /** The name of the action being executed. */
@@ -58,7 +59,7 @@ export interface ActionContext<BaseT = any, InputT = any> {
58
59
  */
59
60
  user?: {
60
61
  id: string | number;
61
- [key: string]: any;
62
+ [key: string]: unknown;
62
63
  };
63
64
  }
64
65
  /**
@@ -100,10 +101,10 @@ export interface ActionConfig {
100
101
  *
101
102
  * RUNTIME TYPE: Includes the handler function for execution.
102
103
  */
103
- export interface ActionDefinition<BaseT = any, InputT = any, ReturnT = any> extends ActionConfig {
104
+ export interface ActionDefinition<BaseT = Record<string, unknown>, InputT = Record<string, unknown>, ReturnT = unknown> extends ActionConfig {
104
105
  /**
105
106
  * The business logic implementation.
106
107
  */
107
108
  handler: (ctx: ActionContext<BaseT, InputT>) => Promise<ReturnT>;
108
109
  }
109
- export type ActionHandler<BaseT = any, InputT = any, ReturnT = any> = (ctx: ActionContext<BaseT, InputT>) => Promise<ReturnT>;
110
+ export type ActionHandler<BaseT = Record<string, unknown>, InputT = Record<string, unknown>, ReturnT = unknown> = (ctx: ActionContext<BaseT, InputT>) => Promise<ReturnT>;
package/dist/ai.d.ts ADDED
@@ -0,0 +1,118 @@
1
+ /**
2
+ * ObjectQL - AI Namespace Types
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * RUNTIME EXTENSIONS: Not part of the wire protocol.
9
+ * These types define stable integration points for AI features.
10
+ */
11
+ /** AI model task types */
12
+ export type AiModelType = 'chat' | 'embedding' | 'rerank' | 'completion' | 'tool';
13
+ /** Model capability flags */
14
+ export interface AiModelCapabilities {
15
+ readonly chat?: boolean;
16
+ readonly embedding?: boolean;
17
+ readonly rerank?: boolean;
18
+ readonly toolCalling?: boolean;
19
+ readonly vision?: boolean;
20
+ }
21
+ /** AI model definition for registry */
22
+ export interface AiModelDefinition {
23
+ /** Unique identifier for registry lookup */
24
+ readonly id: string;
25
+ /** Provider name (e.g., openai, anthropic, local) */
26
+ readonly provider: string;
27
+ /** Provider model name */
28
+ readonly model: string;
29
+ /** Task type */
30
+ readonly type: AiModelType;
31
+ /** Optional display name */
32
+ readonly displayName?: string;
33
+ /** Max output tokens for generation */
34
+ readonly maxTokens?: number;
35
+ /** Context window size */
36
+ readonly contextWindow?: number;
37
+ /** Embedding dimensions (if embedding model) */
38
+ readonly embeddingDimensions?: number;
39
+ /** Capability flags */
40
+ readonly capabilities?: AiModelCapabilities;
41
+ /** Arbitrary metadata */
42
+ readonly metadata?: Record<string, unknown>;
43
+ }
44
+ /** Registry for AI models */
45
+ export interface ModelRegistry {
46
+ register(model: AiModelDefinition): void;
47
+ get(id: string): AiModelDefinition | undefined;
48
+ list(): readonly AiModelDefinition[];
49
+ remove(id: string): void;
50
+ }
51
+ /** Prompt template definition */
52
+ export interface PromptTemplate {
53
+ /** Stable prompt identifier */
54
+ readonly id: string;
55
+ /** Optional semantic version tag */
56
+ readonly version?: string;
57
+ /** Optional display name */
58
+ readonly name?: string;
59
+ /** Prompt template string */
60
+ readonly template: string;
61
+ /** Declared variables for the template */
62
+ readonly variables?: readonly string[];
63
+ /** Optional description */
64
+ readonly description?: string;
65
+ /** Arbitrary metadata */
66
+ readonly metadata?: Record<string, unknown>;
67
+ }
68
+ /** Registry for prompt templates */
69
+ export interface PromptRegistry {
70
+ register(template: PromptTemplate): void;
71
+ get(id: string, version?: string): PromptTemplate | undefined;
72
+ list(id?: string): readonly PromptTemplate[];
73
+ remove(id: string, version?: string): void;
74
+ }
75
+ /** Document for RAG indexing */
76
+ export interface RagDocument {
77
+ readonly id: string;
78
+ readonly content: string;
79
+ readonly metadata?: Record<string, unknown>;
80
+ }
81
+ /** RAG search options */
82
+ export interface RagSearchOptions {
83
+ readonly topK?: number;
84
+ readonly filter?: Record<string, unknown>;
85
+ readonly minScore?: number;
86
+ readonly namespace?: string;
87
+ }
88
+ /** RAG search result */
89
+ export interface RagSearchResult {
90
+ readonly document: RagDocument;
91
+ readonly score: number;
92
+ }
93
+ /** Embedding provider interface */
94
+ export interface EmbeddingProvider {
95
+ embed(texts: readonly string[], modelId: string, options?: {
96
+ readonly dimensions?: number;
97
+ }): Promise<number[][]>;
98
+ }
99
+ /** Vector store interface for RAG */
100
+ export interface VectorStore {
101
+ upsert(documents: readonly RagDocument[], embeddings?: number[][], options?: {
102
+ readonly namespace?: string;
103
+ }): Promise<void>;
104
+ query(embedding: number[], options?: RagSearchOptions): Promise<RagSearchResult[]>;
105
+ delete(ids: readonly string[], options?: {
106
+ readonly namespace?: string;
107
+ }): Promise<void>;
108
+ clear(options?: {
109
+ readonly namespace?: string;
110
+ }): Promise<void>;
111
+ }
112
+ /** AI registry surface for runtime */
113
+ export interface AiRegistry {
114
+ readonly models: ModelRegistry;
115
+ readonly prompts: PromptRegistry;
116
+ readonly embeddings?: EmbeddingProvider;
117
+ readonly vectorStore?: VectorStore;
118
+ }
package/dist/ai.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL - AI Namespace Types
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * RUNTIME EXTENSIONS: Not part of the wire protocol.
10
+ * These types define stable integration points for AI features.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ //# sourceMappingURL=ai.js.map
package/dist/ai.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
package/dist/api.d.ts CHANGED
@@ -27,7 +27,23 @@ export declare enum ApiErrorCode {
27
27
  CONFLICT = "CONFLICT",
28
28
  INTERNAL_ERROR = "INTERNAL_ERROR",
29
29
  DATABASE_ERROR = "DATABASE_ERROR",
30
- RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED"
30
+ RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED",
31
+ DRIVER_ERROR = "DRIVER_ERROR",
32
+ DRIVER_CONNECTION_FAILED = "DRIVER_CONNECTION_FAILED",
33
+ DRIVER_QUERY_FAILED = "DRIVER_QUERY_FAILED",
34
+ DRIVER_TRANSACTION_FAILED = "DRIVER_TRANSACTION_FAILED",
35
+ DRIVER_UNSUPPORTED_OPERATION = "DRIVER_UNSUPPORTED_OPERATION",
36
+ PROTOCOL_ERROR = "PROTOCOL_ERROR",
37
+ PROTOCOL_INVALID_REQUEST = "PROTOCOL_INVALID_REQUEST",
38
+ PROTOCOL_METHOD_NOT_FOUND = "PROTOCOL_METHOD_NOT_FOUND",
39
+ PROTOCOL_BATCH_ERROR = "PROTOCOL_BATCH_ERROR",
40
+ TENANT_ISOLATION_VIOLATION = "TENANT_ISOLATION_VIOLATION",
41
+ TENANT_NOT_FOUND = "TENANT_NOT_FOUND",
42
+ WORKFLOW_TRANSITION_DENIED = "WORKFLOW_TRANSITION_DENIED",
43
+ FORMULA_EVALUATION_ERROR = "FORMULA_EVALUATION_ERROR",
44
+ CONFIG_ERROR = "CONFIG_ERROR",
45
+ SCAFFOLD_ERROR = "SCAFFOLD_ERROR",
46
+ MIGRATION_ERROR = "MIGRATION_ERROR"
31
47
  }
32
48
  /**
33
49
  * Error details structure with optional field-specific information
@@ -79,7 +95,7 @@ export interface PaginationMeta {
79
95
  /**
80
96
  * Base response structure for Data API operations
81
97
  */
82
- export interface DataApiResponse<T = unknown> {
98
+ export interface DataApiResponse<_T = unknown> {
83
99
  /** Error information if the operation failed */
84
100
  error?: ApiError;
85
101
  /** Additional response fields for successful operations */
@@ -185,7 +201,7 @@ export interface DataApiDeleteResponse extends DataApiResponse {
185
201
  /**
186
202
  * Base response structure for Metadata API operations
187
203
  */
188
- export interface MetadataApiResponse<T = unknown> {
204
+ export interface MetadataApiResponse<_T = unknown> {
189
205
  /** Error information if the operation failed */
190
206
  error?: ApiError;
191
207
  /** Additional response fields */
package/dist/api.js CHANGED
@@ -26,6 +26,26 @@ var ApiErrorCode;
26
26
  ApiErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
27
27
  ApiErrorCode["DATABASE_ERROR"] = "DATABASE_ERROR";
28
28
  ApiErrorCode["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED";
29
+ // Driver error codes
30
+ ApiErrorCode["DRIVER_ERROR"] = "DRIVER_ERROR";
31
+ ApiErrorCode["DRIVER_CONNECTION_FAILED"] = "DRIVER_CONNECTION_FAILED";
32
+ ApiErrorCode["DRIVER_QUERY_FAILED"] = "DRIVER_QUERY_FAILED";
33
+ ApiErrorCode["DRIVER_TRANSACTION_FAILED"] = "DRIVER_TRANSACTION_FAILED";
34
+ ApiErrorCode["DRIVER_UNSUPPORTED_OPERATION"] = "DRIVER_UNSUPPORTED_OPERATION";
35
+ // Protocol error codes
36
+ ApiErrorCode["PROTOCOL_ERROR"] = "PROTOCOL_ERROR";
37
+ ApiErrorCode["PROTOCOL_INVALID_REQUEST"] = "PROTOCOL_INVALID_REQUEST";
38
+ ApiErrorCode["PROTOCOL_METHOD_NOT_FOUND"] = "PROTOCOL_METHOD_NOT_FOUND";
39
+ ApiErrorCode["PROTOCOL_BATCH_ERROR"] = "PROTOCOL_BATCH_ERROR";
40
+ // Plugin error codes
41
+ ApiErrorCode["TENANT_ISOLATION_VIOLATION"] = "TENANT_ISOLATION_VIOLATION";
42
+ ApiErrorCode["TENANT_NOT_FOUND"] = "TENANT_NOT_FOUND";
43
+ ApiErrorCode["WORKFLOW_TRANSITION_DENIED"] = "WORKFLOW_TRANSITION_DENIED";
44
+ ApiErrorCode["FORMULA_EVALUATION_ERROR"] = "FORMULA_EVALUATION_ERROR";
45
+ // CLI/Tool error codes
46
+ ApiErrorCode["CONFIG_ERROR"] = "CONFIG_ERROR";
47
+ ApiErrorCode["SCAFFOLD_ERROR"] = "SCAFFOLD_ERROR";
48
+ ApiErrorCode["MIGRATION_ERROR"] = "MIGRATION_ERROR";
29
49
  })(ApiErrorCode || (exports.ApiErrorCode = ApiErrorCode = {}));
30
50
  /**
31
51
  * ObjectQL Error class for throwing structured errors
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AA6jBH,4CASC;AAxjBD,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;GAEG;AACH,IAAY,YAUX;AAVD,WAAY,YAAY;IACpB,mDAAmC,CAAA;IACnC,qDAAqC,CAAA;IACrC,6CAA6B,CAAA;IAC7B,uCAAuB,CAAA;IACvB,uCAAuB,CAAA;IACvB,qCAAqB,CAAA;IACrB,iDAAiC,CAAA;IACjC,iDAAiC,CAAA;IACjC,2DAA2C,CAAA;AAC/C,CAAC,EAVW,YAAY,4BAAZ,YAAY,QAUvB;AAwBD;;GAEG;AACH,MAAa,aAAc,SAAQ,KAAK;IAIpC,YAAY,KAAkF;QAC1F,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,uDAAuD;QACvD,MAAM,gBAAgB,GAAG,KAA2F,CAAC;QACrH,IAAI,OAAO,gBAAgB,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC3D,gBAAgB,CAAC,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;CACJ;AAhBD,sCAgBC;AAqeD;;GAEG;AACU,QAAA,kBAAkB,GAA2B;IACtD,GAAG,EAAE,eAAe;IACpB,IAAI,EAAE,WAAW;IACjB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,YAAY;CACtB,CAAC;AAEF;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,MAAuB;;IACpD,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAEzF,OAAO;QACH,GAAG,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,mCAAI,0BAAkB,CAAC,GAAG,CAAC;QACzD,IAAI,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,mCAAI,0BAAkB,CAAC,IAAI,CAAC;QAC5D,QAAQ,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,mCAAI,0BAAkB,CAAC,QAAQ,CAAC;QACxE,KAAK,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,mCAAI,0BAAkB,CAAC,KAAK,CAAC;KAClE,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAqlBH,4CASC;AAhlBD,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;GAEG;AACH,IAAY,YAkCX;AAlCD,WAAY,YAAY;IACpB,mDAAmC,CAAA;IACnC,qDAAqC,CAAA;IACrC,6CAA6B,CAAA;IAC7B,uCAAuB,CAAA;IACvB,uCAAuB,CAAA;IACvB,qCAAqB,CAAA;IACrB,iDAAiC,CAAA;IACjC,iDAAiC,CAAA;IACjC,2DAA2C,CAAA;IAE3C,qBAAqB;IACrB,6CAA6B,CAAA;IAC7B,qEAAqD,CAAA;IACrD,2DAA2C,CAAA;IAC3C,uEAAuD,CAAA;IACvD,6EAA6D,CAAA;IAE7D,uBAAuB;IACvB,iDAAiC,CAAA;IACjC,qEAAqD,CAAA;IACrD,uEAAuD,CAAA;IACvD,6DAA6C,CAAA;IAE7C,qBAAqB;IACrB,yEAAyD,CAAA;IACzD,qDAAqC,CAAA;IACrC,yEAAyD,CAAA;IACzD,qEAAqD,CAAA;IAErD,uBAAuB;IACvB,6CAA6B,CAAA;IAC7B,iDAAiC,CAAA;IACjC,mDAAmC,CAAA;AACvC,CAAC,EAlCW,YAAY,4BAAZ,YAAY,QAkCvB;AAwBD;;GAEG;AACH,MAAa,aAAc,SAAQ,KAAK;IAIpC,YAAY,KAAkF;QAC1F,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,uDAAuD;QACvD,MAAM,gBAAgB,GAAG,KAA8G,CAAC;QACxI,IAAI,OAAO,gBAAgB,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC3D,gBAAgB,CAAC,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;CACJ;AAhBD,sCAgBC;AAqeD;;GAEG;AACU,QAAA,kBAAkB,GAA2B;IACtD,GAAG,EAAE,eAAe;IACpB,IAAI,EAAE,WAAW;IACjB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,YAAY;CACtB,CAAC;AAEF;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,MAAuB;;IACpD,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAEzF,OAAO;QACH,GAAG,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,mCAAI,0BAAkB,CAAC,GAAG,CAAC;QACzD,IAAI,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,mCAAI,0BAAkB,CAAC,IAAI,CAAC;QAC5D,QAAQ,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,mCAAI,0BAAkB,CAAC,QAAQ,CAAC;QACxE,KAAK,EAAE,aAAa,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,mCAAI,0BAAkB,CAAC,KAAK,CAAC;KAClE,CAAC;AACN,CAAC"}
package/dist/app.d.ts CHANGED
@@ -22,10 +22,10 @@ export interface IObjectQL {
22
22
  on(event: HookName, objectName: string, handler: HookHandler): void;
23
23
  triggerHook(event: HookName, objectName: string, ctx: HookContext): Promise<void>;
24
24
  registerAction(objectName: string, actionName: string, handler: ActionHandler): void;
25
- executeAction(objectName: string, actionName: string, ctx: ActionContext): Promise<any>;
25
+ executeAction(objectName: string, actionName: string, ctx: ActionContext): Promise<unknown>;
26
26
  /**
27
27
  * Get the underlying ObjectKernel instance
28
28
  * @returns The ObjectKernel instance
29
29
  */
30
- getKernel(): any;
30
+ getKernel(): unknown;
31
31
  }
@@ -41,5 +41,5 @@ export interface AppConfig {
41
41
  /**
42
42
  * Custom metadata/settings
43
43
  */
44
- [key: string]: any;
44
+ [key: string]: unknown;
45
45
  }
package/dist/config.d.ts CHANGED
@@ -9,6 +9,7 @@ import { MetadataRegistry } from "./registry";
9
9
  import { Driver } from "./driver";
10
10
  import { ObjectConfig } from "./object";
11
11
  import type { RuntimePlugin } from "./plugin";
12
+ import type { Logger } from "./logger";
12
13
  export interface ObjectQLConfig {
13
14
  registry?: MetadataRegistry;
14
15
  datasources?: Record<string, Driver>;
@@ -46,4 +47,9 @@ export interface ObjectQLConfig {
46
47
  * e.g. ["http://user-service:3000", "http://order-service:3000"]
47
48
  */
48
49
  remotes?: string[];
50
+ /**
51
+ * Optional structured logger instance.
52
+ * If not provided, a ConsoleLogger with level 'info' is used.
53
+ */
54
+ logger?: Logger;
49
55
  }
package/dist/context.d.ts CHANGED
@@ -23,7 +23,7 @@ export interface ObjectQLContext {
23
23
  * Execute a function within a transaction.
24
24
  * The callback receives a new context 'trxCtx' which inherits userId, spaceId from this context.
25
25
  */
26
- transaction(callback: (trxCtx: ObjectQLContext) => Promise<any>): Promise<any>;
26
+ transaction(callback: (trxCtx: ObjectQLContext) => Promise<unknown>): Promise<unknown>;
27
27
  /**
28
28
  * Returns a new context with system privileges (isSystem: true).
29
29
  * It shares the same transaction scope as the current context.
@@ -32,7 +32,7 @@ export interface ObjectQLContext {
32
32
  /**
33
33
  * Internal: Driver-specific transaction handle.
34
34
  */
35
- transactionHandle?: any;
35
+ transactionHandle?: unknown;
36
36
  }
37
37
  export interface ObjectQLContextOptions {
38
38
  userId?: string;
package/dist/driver.d.ts CHANGED
@@ -16,7 +16,7 @@ export interface IntrospectedColumn {
16
16
  /** Whether the column is nullable */
17
17
  nullable: boolean;
18
18
  /** Default value if any */
19
- defaultValue?: any;
19
+ defaultValue?: unknown;
20
20
  /** Whether this is a primary key */
21
21
  isPrimary?: boolean;
22
22
  /** Whether this column has a unique constraint */
@@ -57,88 +57,214 @@ export interface IntrospectedSchema {
57
57
  /** Map of table name to table metadata */
58
58
  tables: Record<string, IntrospectedTable>;
59
59
  }
60
+ /**
61
+ * Transaction isolation levels supported by the driver.
62
+ *
63
+ * Aligned with @objectstack/spec DriverCapabilitiesSchema — uses snake_case per protocol convention.
64
+ */
65
+ export type IsolationLevel = 'read_uncommitted' | 'read_committed' | 'repeatable_read' | 'serializable' | 'snapshot';
66
+ /**
67
+ * Driver Capabilities
68
+ *
69
+ * Declares what features a driver supports. Aligned with the canonical
70
+ * DriverCapabilitiesSchema from @objectstack/spec.
71
+ *
72
+ * All boolean fields default to `false`. Drivers only set `true` for supported features.
73
+ */
74
+ export interface DriverCapabilities {
75
+ readonly create?: boolean;
76
+ readonly read?: boolean;
77
+ readonly update?: boolean;
78
+ readonly delete?: boolean;
79
+ readonly bulkCreate?: boolean;
80
+ readonly bulkUpdate?: boolean;
81
+ readonly bulkDelete?: boolean;
82
+ readonly transactions?: boolean;
83
+ readonly savepoints?: boolean;
84
+ readonly isolationLevels?: readonly IsolationLevel[];
85
+ readonly queryFilters?: boolean;
86
+ readonly queryAggregations?: boolean;
87
+ readonly querySorting?: boolean;
88
+ readonly queryPagination?: boolean;
89
+ readonly queryWindowFunctions?: boolean;
90
+ readonly querySubqueries?: boolean;
91
+ readonly queryCTE?: boolean;
92
+ readonly joins?: boolean;
93
+ readonly fullTextSearch?: boolean;
94
+ readonly jsonQuery?: boolean;
95
+ readonly geospatialQuery?: boolean;
96
+ readonly streaming?: boolean;
97
+ readonly jsonFields?: boolean;
98
+ readonly arrayFields?: boolean;
99
+ readonly vectorSearch?: boolean;
100
+ /** @deprecated Use `geospatialQuery` instead */
101
+ readonly geoSpatial?: boolean;
102
+ readonly schemaSync?: boolean;
103
+ readonly migrations?: boolean;
104
+ readonly indexes?: boolean;
105
+ readonly connectionPooling?: boolean;
106
+ readonly preparedStatements?: boolean;
107
+ readonly queryCache?: boolean;
108
+ }
109
+ /**
110
+ * Runtime Driver Capabilities (extends spec with sync-specific properties)
111
+ *
112
+ * These properties are NOT part of the @objectstack/spec DriverCapabilitiesSchema
113
+ * (which sets additionalProperties: false). They are runtime-only extensions
114
+ * used by the Offline-First Sync Protocol (Q3).
115
+ *
116
+ * Use this interface for drivers that need sync capabilities.
117
+ */
118
+ export interface RuntimeDriverCapabilities extends DriverCapabilities {
119
+ /** Driver can record mutations to an append-only log for offline sync */
120
+ readonly mutationLog?: boolean;
121
+ /** Driver supports checkpoint-based change tracking */
122
+ readonly changeTracking?: boolean;
123
+ }
124
+ /**
125
+ * Driver type discriminator — aligned with @objectstack/spec DriverConfigSchema.
126
+ */
127
+ export type DriverType = 'sql' | 'nosql' | 'cache' | 'search' | 'graph' | 'timeseries';
128
+ /**
129
+ * Base driver configuration common to all drivers.
130
+ * Individual drivers extend this with driver-specific fields.
131
+ */
132
+ export interface BaseDriverConfig {
133
+ /** Driver type discriminator */
134
+ readonly type?: DriverType;
135
+ }
136
+ /**
137
+ * Database driver interface. All storage backends implement this contract.
138
+ *
139
+ * Type strategy:
140
+ * - `Record<string, unknown>` for data payloads (plain field-value maps)
141
+ * - `object` for query/filter/command parameters that may receive named interfaces
142
+ * (e.g., UnifiedQuery, Filter) which lack implicit index signatures
143
+ * - `unknown` for opaque values (transaction handles, heterogeneous returns)
144
+ */
60
145
  export interface Driver {
61
- name?: string;
62
- version?: string;
63
- supports?: {
64
- transactions?: boolean;
65
- joins?: boolean;
66
- fullTextSearch?: boolean;
67
- jsonFields?: boolean;
68
- arrayFields?: boolean;
69
- queryFilters?: boolean;
70
- queryAggregations?: boolean;
71
- querySorting?: boolean;
72
- queryPagination?: boolean;
73
- queryWindowFunctions?: boolean;
74
- querySubqueries?: boolean;
75
- };
76
- find(objectName: string, query: any, options?: any): Promise<any[]>;
77
- findOne(objectName: string, id: string | number, query?: any, options?: any): Promise<any>;
78
- create(objectName: string, data: any, options?: any): Promise<any>;
79
- update(objectName: string, id: string | number, data: any, options?: any): Promise<any>;
80
- delete(objectName: string, id: string | number, options?: any): Promise<any>;
81
- count(objectName: string, filters: any, options?: any): Promise<number>;
146
+ /** Driver identifier (e.g., 'memory', 'sql', 'mongo') */
147
+ readonly name?: string;
148
+ /** Driver version (semver) */
149
+ readonly version?: string;
150
+ /** Capabilities declaration — what this driver supports */
151
+ readonly supports?: DriverCapabilities;
152
+ find(objectName: string, query: object, options?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
153
+ findOne(objectName: string, id: string | number, query?: object, options?: Record<string, unknown>): Promise<Record<string, unknown> | null>;
154
+ create(objectName: string, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<Record<string, unknown>>;
155
+ update(objectName: string, id: string | number, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<Record<string, unknown>>;
156
+ delete(objectName: string, id: string | number, options?: Record<string, unknown>): Promise<unknown>;
157
+ count(objectName: string, filters: object, options?: Record<string, unknown>): Promise<number>;
82
158
  connect?(): Promise<void>;
83
159
  disconnect?(): Promise<void>;
84
160
  checkHealth?(): Promise<boolean>;
85
- execute?(command: any, parameters?: any[], options?: any): Promise<any>;
86
- bulkCreate?(objectName: string, data: any[], options?: any): Promise<any>;
161
+ execute?(command: object, parameters?: unknown[], options?: Record<string, unknown>): Promise<unknown>;
162
+ bulkCreate?(objectName: string, data: Record<string, unknown>[], options?: Record<string, unknown>): Promise<unknown>;
87
163
  bulkUpdate?(objectName: string, updates: Array<{
88
164
  id: string | number;
89
- data: any;
90
- }>, options?: any): Promise<any>;
91
- bulkDelete?(objectName: string, ids: Array<string | number>, options?: any): Promise<any>;
92
- distinct?(objectName: string, field: string, filters?: any, options?: any): Promise<any[]>;
93
- aggregate?(objectName: string, aggregations: any[], filters?: any, options?: any): Promise<any[]>;
94
- beginTransaction?(): Promise<any>;
95
- commitTransaction?(transaction: any): Promise<void>;
96
- rollbackTransaction?(transaction: any): Promise<void>;
97
- init?(objects: any[]): Promise<void>;
165
+ data: Record<string, unknown>;
166
+ }>, options?: Record<string, unknown>): Promise<unknown>;
167
+ bulkDelete?(objectName: string, ids: Array<string | number>, options?: Record<string, unknown>): Promise<unknown>;
168
+ distinct?(objectName: string, field: string, filters?: object, options?: Record<string, unknown>): Promise<unknown[]>;
169
+ aggregate?(objectName: string, query: object, options?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
170
+ beginTransaction?(): Promise<unknown>;
171
+ /** @deprecated Use `commit` — aligned with @objectstack/spec DriverInterfaceSchema. Will be removed in v5.0. */
172
+ commitTransaction?(transaction: unknown): Promise<void>;
173
+ /** @deprecated Use `rollback` — aligned with @objectstack/spec DriverInterfaceSchema. Will be removed in v5.0. */
174
+ rollbackTransaction?(transaction: unknown): Promise<void>;
175
+ /** Commit a transaction (spec-aligned name) */
176
+ commit?(transaction: unknown): Promise<void>;
177
+ /** Rollback a transaction (spec-aligned name) */
178
+ rollback?(transaction: unknown): Promise<void>;
179
+ init?(objects: object[]): Promise<void>;
98
180
  /**
99
181
  * Introspect the database schema to discover existing tables, columns, and relationships.
100
- * This allows connecting to an existing database without defining metadata.
101
182
  * @returns Complete schema information including tables, columns, and foreign keys
102
183
  */
103
184
  introspectSchema?(): Promise<IntrospectedSchema>;
104
- aggregate?(objectName: string, query: any, options?: any): Promise<any>;
105
- distinct?(objectName: string, field: string, filters?: any, options?: any): Promise<any[]>;
106
- createMany?(objectName: string, data: any[], options?: any): Promise<any>;
107
- updateMany?(objectName: string, filters: any, data: any, options?: any): Promise<any>;
108
- deleteMany?(objectName: string, filters: any, options?: any): Promise<any>;
109
- findOneAndUpdate?(objectName: string, filters: any, update: any, options?: any): Promise<any>;
110
- beginTransaction?(): Promise<any>;
111
- commitTransaction?(trx: any): Promise<void>;
112
- rollbackTransaction?(trx: any): Promise<void>;
113
- disconnect?(): Promise<void>;
185
+ createMany?(objectName: string, data: Record<string, unknown>[], options?: Record<string, unknown>): Promise<unknown>;
186
+ updateMany?(objectName: string, filters: object, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<unknown>;
187
+ deleteMany?(objectName: string, filters: object, options?: Record<string, unknown>): Promise<unknown>;
188
+ findOneAndUpdate?(objectName: string, filters: object, update: Record<string, unknown>, options?: Record<string, unknown>): Promise<Record<string, unknown> | null>;
114
189
  /**
115
190
  * Execute a query using QueryAST format (DriverInterface v4.0)
116
- * @param ast - The QueryAST to execute
117
- * @param options - Driver-specific options
118
- * @returns Query result with value and optional count
119
191
  */
120
- executeQuery?(ast: any, options?: any): Promise<{
121
- value: any[];
192
+ executeQuery?(ast: object, options?: Record<string, unknown>): Promise<{
193
+ value: Record<string, unknown>[];
122
194
  count?: number;
123
195
  }>;
124
196
  /**
125
197
  * Execute a command using Command format (DriverInterface v4.0)
126
- * @param command - The command to execute (create/update/delete/bulk operations)
127
- * @param options - Driver-specific options
128
- * @returns Command result with success status and affected count
129
198
  */
130
- executeCommand?(command: any, options?: any): Promise<{
199
+ executeCommand?(command: object, options?: Record<string, unknown>): Promise<{
131
200
  success: boolean;
132
- data?: any;
201
+ data?: unknown;
133
202
  affected: number;
134
203
  }>;
135
204
  /**
136
- * Alternative method names for findOne (some drivers use 'get')
205
+ * Alternative method name for findOne (some drivers use 'get')
206
+ */
207
+ get?(objectName: string, id: string, options?: Record<string, unknown>): Promise<Record<string, unknown> | null>;
208
+ /**
209
+ * Direct query execution (legacy)
210
+ */
211
+ directQuery?(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
212
+ query?(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
213
+ /**
214
+ * Upsert (create or update) a record.
215
+ * If the record exists (matched by ID or unique key), update it; otherwise, create it.
216
+ *
217
+ * @param objectName - The object name.
218
+ * @param data - Key-value map of field data (must include ID or unique key).
219
+ * @param options - Driver options.
220
+ * @returns The upserted record.
221
+ */
222
+ upsert?(objectName: string, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<Record<string, unknown>>;
223
+ /**
224
+ * Stream records matching the structured query.
225
+ * Optimized for large datasets to avoid memory overflow.
226
+ *
227
+ * @param objectName - The name of the object.
228
+ * @param query - The structured QueryAST.
229
+ * @param options - Driver options.
230
+ * @returns AsyncIterable/ReadableStream of records.
231
+ */
232
+ findStream?(objectName: string, query: object, options?: Record<string, unknown>): AsyncIterable<Record<string, unknown>> | unknown;
233
+ /**
234
+ * Get connection pool statistics.
235
+ * Useful for monitoring database load.
236
+ *
237
+ * @returns Pool stats object, or undefined if pooling is not supported by the driver.
238
+ */
239
+ getPoolStats?(): {
240
+ total: number;
241
+ idle: number;
242
+ active: number;
243
+ waiting: number;
244
+ } | undefined;
245
+ /**
246
+ * Synchronize the schema for one or more objects.
247
+ * Creates or alters tables/collections to match the object definitions.
248
+ *
249
+ * @param objects - Object definitions to synchronize.
250
+ * @param options - Driver options.
251
+ */
252
+ syncSchema?(objects: object[], options?: Record<string, unknown>): Promise<void>;
253
+ /**
254
+ * Drop a table/collection by name.
255
+ *
256
+ * @param objectName - The name of the object/table to drop.
257
+ * @param options - Driver options.
137
258
  */
138
- get?(objectName: string, id: string, options?: any): Promise<any>;
259
+ dropTable?(objectName: string, options?: Record<string, unknown>): Promise<void>;
139
260
  /**
140
- * Direct query execution (legacy, some drivers)
261
+ * Explain the execution plan for a query.
262
+ * Useful for debugging and performance optimization.
263
+ *
264
+ * @param objectName - The name of the object.
265
+ * @param query - The structured QueryAST.
266
+ * @param options - Driver options.
267
+ * @returns Execution plan details.
141
268
  */
142
- directQuery?(sql: string, params?: any[]): Promise<any[]>;
143
- query?(sql: string, params?: any[]): Promise<any[]>;
269
+ explain?(objectName: string, query: object, options?: Record<string, unknown>): Promise<unknown>;
144
270
  }