@aigne/afs-sqlite 1.0.1-beta

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 (76) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE.md +93 -0
  3. package/README.md +277 -0
  4. package/lib/cjs/actions/built-in.d.ts +5 -0
  5. package/lib/cjs/actions/built-in.js +165 -0
  6. package/lib/cjs/actions/registry.d.ts +49 -0
  7. package/lib/cjs/actions/registry.js +102 -0
  8. package/lib/cjs/actions/types.d.ts +51 -0
  9. package/lib/cjs/actions/types.js +2 -0
  10. package/lib/cjs/config.d.ts +89 -0
  11. package/lib/cjs/config.js +33 -0
  12. package/lib/cjs/index.d.ts +13 -0
  13. package/lib/cjs/index.js +47 -0
  14. package/lib/cjs/node/builder.d.ts +43 -0
  15. package/lib/cjs/node/builder.js +187 -0
  16. package/lib/cjs/operations/crud.d.ts +64 -0
  17. package/lib/cjs/operations/crud.js +225 -0
  18. package/lib/cjs/operations/query-builder.d.ts +37 -0
  19. package/lib/cjs/operations/query-builder.js +102 -0
  20. package/lib/cjs/operations/search.d.ts +75 -0
  21. package/lib/cjs/operations/search.js +172 -0
  22. package/lib/cjs/package.json +3 -0
  23. package/lib/cjs/router/path-router.d.ts +38 -0
  24. package/lib/cjs/router/path-router.js +90 -0
  25. package/lib/cjs/router/types.d.ts +30 -0
  26. package/lib/cjs/router/types.js +2 -0
  27. package/lib/cjs/schema/introspector.d.ts +48 -0
  28. package/lib/cjs/schema/introspector.js +186 -0
  29. package/lib/cjs/schema/types.d.ts +104 -0
  30. package/lib/cjs/schema/types.js +13 -0
  31. package/lib/cjs/sqlite-afs.d.ts +144 -0
  32. package/lib/cjs/sqlite-afs.js +337 -0
  33. package/lib/dts/actions/built-in.d.ts +5 -0
  34. package/lib/dts/actions/registry.d.ts +49 -0
  35. package/lib/dts/actions/types.d.ts +51 -0
  36. package/lib/dts/config.d.ts +89 -0
  37. package/lib/dts/index.d.ts +13 -0
  38. package/lib/dts/node/builder.d.ts +43 -0
  39. package/lib/dts/operations/crud.d.ts +64 -0
  40. package/lib/dts/operations/query-builder.d.ts +37 -0
  41. package/lib/dts/operations/search.d.ts +75 -0
  42. package/lib/dts/router/path-router.d.ts +38 -0
  43. package/lib/dts/router/types.d.ts +30 -0
  44. package/lib/dts/schema/introspector.d.ts +48 -0
  45. package/lib/dts/schema/types.d.ts +104 -0
  46. package/lib/dts/sqlite-afs.d.ts +144 -0
  47. package/lib/esm/actions/built-in.d.ts +5 -0
  48. package/lib/esm/actions/built-in.js +162 -0
  49. package/lib/esm/actions/registry.d.ts +49 -0
  50. package/lib/esm/actions/registry.js +98 -0
  51. package/lib/esm/actions/types.d.ts +51 -0
  52. package/lib/esm/actions/types.js +1 -0
  53. package/lib/esm/config.d.ts +89 -0
  54. package/lib/esm/config.js +30 -0
  55. package/lib/esm/index.d.ts +13 -0
  56. package/lib/esm/index.js +17 -0
  57. package/lib/esm/node/builder.d.ts +43 -0
  58. package/lib/esm/node/builder.js +177 -0
  59. package/lib/esm/operations/crud.d.ts +64 -0
  60. package/lib/esm/operations/crud.js +221 -0
  61. package/lib/esm/operations/query-builder.d.ts +37 -0
  62. package/lib/esm/operations/query-builder.js +92 -0
  63. package/lib/esm/operations/search.d.ts +75 -0
  64. package/lib/esm/operations/search.js +167 -0
  65. package/lib/esm/package.json +3 -0
  66. package/lib/esm/router/path-router.d.ts +38 -0
  67. package/lib/esm/router/path-router.js +83 -0
  68. package/lib/esm/router/types.d.ts +30 -0
  69. package/lib/esm/router/types.js +1 -0
  70. package/lib/esm/schema/introspector.d.ts +48 -0
  71. package/lib/esm/schema/introspector.js +182 -0
  72. package/lib/esm/schema/types.d.ts +104 -0
  73. package/lib/esm/schema/types.js +10 -0
  74. package/lib/esm/sqlite-afs.d.ts +144 -0
  75. package/lib/esm/sqlite-afs.js +333 -0
  76. package/package.json +71 -0
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLiteAFS = void 0;
4
+ const sqlite_1 = require("@aigne/sqlite");
5
+ const built_in_js_1 = require("./actions/built-in.js");
6
+ const registry_js_1 = require("./actions/registry.js");
7
+ const config_js_1 = require("./config.js");
8
+ const builder_js_1 = require("./node/builder.js");
9
+ const crud_js_1 = require("./operations/crud.js");
10
+ const search_js_1 = require("./operations/search.js");
11
+ const path_router_js_1 = require("./router/path-router.js");
12
+ const introspector_js_1 = require("./schema/introspector.js");
13
+ /**
14
+ * SQLite AFS Module
15
+ *
16
+ * Exposes SQLite databases as AFS nodes with full CRUD support,
17
+ * schema introspection, FTS5 search, and virtual paths (@attr, @meta, @actions).
18
+ */
19
+ class SQLiteAFS {
20
+ options;
21
+ name;
22
+ description;
23
+ accessMode;
24
+ db;
25
+ schemas = new Map();
26
+ router;
27
+ crud;
28
+ ftsSearch;
29
+ actions;
30
+ ftsConfig;
31
+ initialized = false;
32
+ constructor(options) {
33
+ this.options = options;
34
+ this.name = options.name ?? "sqlite-afs";
35
+ this.description = options.description ?? `SQLite database: ${options.url}`;
36
+ this.accessMode = options.accessMode ?? "readwrite";
37
+ this.ftsConfig = (0, search_js_1.createFTSConfig)(options.fts);
38
+ this.actions = new registry_js_1.ActionsRegistry();
39
+ (0, built_in_js_1.registerBuiltInActions)(this.actions);
40
+ }
41
+ /**
42
+ * Returns the Zod schema for configuration validation
43
+ */
44
+ static schema() {
45
+ return config_js_1.sqliteAFSConfigSchema;
46
+ }
47
+ /**
48
+ * Loads a module instance from configuration
49
+ */
50
+ static async load({ parsed }) {
51
+ const validated = config_js_1.sqliteAFSConfigSchema.parse(parsed);
52
+ return new SQLiteAFS(validated);
53
+ }
54
+ /**
55
+ * Called when the module is mounted to AFS
56
+ */
57
+ async onMount(_afs) {
58
+ await this.initialize();
59
+ }
60
+ /**
61
+ * Initializes the database connection and introspects schema
62
+ */
63
+ async initialize() {
64
+ if (this.initialized)
65
+ return;
66
+ // Initialize database connection
67
+ this.db = await (0, sqlite_1.initDatabase)({
68
+ url: this.options.url,
69
+ wal: this.options.wal ?? true,
70
+ });
71
+ // Cast db to LibSQLDatabase for operations
72
+ const db = this.db;
73
+ // Introspect database schema
74
+ const introspector = new introspector_js_1.SchemaIntrospector();
75
+ this.schemas = await introspector.introspect(db, {
76
+ tables: this.options.tables,
77
+ excludeTables: this.options.excludeTables,
78
+ });
79
+ // Initialize components
80
+ this.router = (0, path_router_js_1.createPathRouter)();
81
+ this.crud = new crud_js_1.CRUDOperations(db, this.schemas, "");
82
+ this.ftsSearch = new search_js_1.FTSSearch(db, this.schemas, this.ftsConfig, "");
83
+ this.initialized = true;
84
+ }
85
+ /**
86
+ * Ensures the module is initialized
87
+ */
88
+ async ensureInitialized() {
89
+ if (!this.initialized) {
90
+ await this.initialize();
91
+ }
92
+ }
93
+ /**
94
+ * Lists entries at a path
95
+ */
96
+ async list(path, options) {
97
+ await this.ensureInitialized();
98
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
99
+ if (!match) {
100
+ return { data: [] };
101
+ }
102
+ switch (match.action) {
103
+ case "listTables":
104
+ return this.crud.listTables();
105
+ case "listTable":
106
+ if (!match.params.table)
107
+ return { data: [] };
108
+ return this.crud.listTable(match.params.table, options);
109
+ case "listAttributes":
110
+ if (!match.params.table || !match.params.pk)
111
+ return { data: [] };
112
+ return this.crud.listAttributes(match.params.table, match.params.pk);
113
+ case "listActions":
114
+ if (!match.params.table || !match.params.pk)
115
+ return { data: [] };
116
+ return this.listActions(match.params.table, match.params.pk);
117
+ default:
118
+ return { data: [] };
119
+ }
120
+ }
121
+ /**
122
+ * Reads an entry at a path
123
+ */
124
+ async read(path, _options) {
125
+ await this.ensureInitialized();
126
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
127
+ if (!match) {
128
+ return {};
129
+ }
130
+ switch (match.action) {
131
+ case "readRow":
132
+ if (!match.params.table || !match.params.pk)
133
+ return {};
134
+ return this.crud.readRow(match.params.table, match.params.pk);
135
+ case "getSchema":
136
+ if (!match.params.table)
137
+ return {};
138
+ return this.crud.getSchema(match.params.table);
139
+ case "getAttribute":
140
+ if (!match.params.table || !match.params.pk || !match.params.column)
141
+ return {};
142
+ return this.crud.getAttribute(match.params.table, match.params.pk, match.params.column);
143
+ case "getMeta":
144
+ if (!match.params.table || !match.params.pk)
145
+ return {};
146
+ return this.crud.getMeta(match.params.table, match.params.pk);
147
+ default:
148
+ return {};
149
+ }
150
+ }
151
+ /**
152
+ * Writes an entry at a path
153
+ */
154
+ async write(path, content, _options) {
155
+ await this.ensureInitialized();
156
+ if (this.accessMode === "readonly") {
157
+ throw new Error("Module is in readonly mode");
158
+ }
159
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
160
+ if (!match) {
161
+ throw new Error(`Invalid path: ${path}`);
162
+ }
163
+ switch (match.action) {
164
+ case "createRow":
165
+ if (!match.params.table) {
166
+ throw new Error("Table name required for create");
167
+ }
168
+ return this.crud.createRow(match.params.table, content.content ?? content);
169
+ case "readRow":
170
+ if (!match.params.table || !match.params.pk) {
171
+ throw new Error("Table and primary key required for update");
172
+ }
173
+ return this.crud.updateRow(match.params.table, match.params.pk, content.content ?? content);
174
+ case "executeAction":
175
+ if (!match.params.table || !match.params.action) {
176
+ throw new Error("Table and action name required");
177
+ }
178
+ return this.executeAction(match.params.table, match.params.pk, match.params.action, content.content ?? content);
179
+ default:
180
+ throw new Error(`Write not supported for path: ${path}`);
181
+ }
182
+ }
183
+ /**
184
+ * Deletes an entry at a path
185
+ */
186
+ async delete(path, _options) {
187
+ await this.ensureInitialized();
188
+ if (this.accessMode === "readonly") {
189
+ throw new Error("Module is in readonly mode");
190
+ }
191
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
192
+ if (!match || match.action !== "readRow") {
193
+ throw new Error(`Delete not supported for path: ${path}`);
194
+ }
195
+ if (!match.params.table || !match.params.pk) {
196
+ throw new Error("Table and primary key required for delete");
197
+ }
198
+ return this.crud.deleteRow(match.params.table, match.params.pk);
199
+ }
200
+ /**
201
+ * Searches for entries matching a query
202
+ */
203
+ async search(path, query, options) {
204
+ await this.ensureInitialized();
205
+ // If path specifies a table, search only that table
206
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
207
+ if (match?.params.table) {
208
+ return this.ftsSearch.searchTable(match.params.table, query, options);
209
+ }
210
+ // Otherwise search all FTS-enabled tables
211
+ return this.ftsSearch.search(query, options);
212
+ }
213
+ /**
214
+ * Executes a module operation
215
+ */
216
+ async exec(path, args, _options) {
217
+ await this.ensureInitialized();
218
+ const match = (0, path_router_js_1.matchPath)(this.router, path);
219
+ if (match?.action === "executeAction" && match.params.table && match.params.action) {
220
+ const result = await this.executeAction(match.params.table, match.params.pk, match.params.action, args);
221
+ return { data: result.data };
222
+ }
223
+ throw new Error(`Exec not supported for path: ${path}`);
224
+ }
225
+ /**
226
+ * Lists available actions for a row
227
+ */
228
+ listActions(table, pk) {
229
+ const actionNames = this.actions.listNames({ rowLevel: true });
230
+ return {
231
+ data: (0, builder_js_1.buildActionsListEntry)(table, pk, actionNames, { basePath: "" }),
232
+ };
233
+ }
234
+ /**
235
+ * Executes an action
236
+ */
237
+ async executeAction(table, pk, actionName, params) {
238
+ const schema = this.schemas.get(table);
239
+ if (!schema) {
240
+ throw new Error(`Table '${table}' not found`);
241
+ }
242
+ // Get row data if pk is provided
243
+ let row;
244
+ if (pk) {
245
+ const readResult = await this.crud.readRow(table, pk);
246
+ row = readResult.data?.content;
247
+ }
248
+ const ctx = {
249
+ db: this.db,
250
+ schemas: this.schemas,
251
+ table,
252
+ pk,
253
+ row,
254
+ module: {
255
+ refreshSchema: () => this.refreshSchema(),
256
+ exportTable: (t, f) => this.exportTable(t, f),
257
+ },
258
+ };
259
+ const result = await this.actions.execute(actionName, ctx, params);
260
+ if (!result.success) {
261
+ throw new Error(result.message ?? "Action failed");
262
+ }
263
+ return {
264
+ data: {
265
+ id: `${table}:${pk ?? ""}:@actions:${actionName}`,
266
+ path: pk ? `/${table}/${pk}/@actions/${actionName}` : `/${table}/@actions/${actionName}`,
267
+ content: result.data,
268
+ },
269
+ };
270
+ }
271
+ /**
272
+ * Refreshes the schema cache
273
+ */
274
+ async refreshSchema() {
275
+ const db = this.db;
276
+ const introspector = new introspector_js_1.SchemaIntrospector();
277
+ this.schemas = await introspector.introspect(db, {
278
+ tables: this.options.tables,
279
+ excludeTables: this.options.excludeTables,
280
+ });
281
+ this.crud.setSchemas(this.schemas);
282
+ this.ftsSearch.setSchemas(this.schemas);
283
+ }
284
+ /**
285
+ * Exports table data in specified format
286
+ */
287
+ async exportTable(table, format) {
288
+ const listResult = await this.crud.listTable(table, { limit: 10000 });
289
+ if (format === "csv") {
290
+ const schema = this.schemas.get(table);
291
+ if (!schema)
292
+ throw new Error(`Table '${table}' not found`);
293
+ const headers = schema.columns.map((c) => c.name).join(",");
294
+ const rows = listResult.data.map((entry) => {
295
+ const content = entry.content;
296
+ return schema.columns
297
+ .map((c) => {
298
+ const val = content[c.name];
299
+ if (val === null || val === undefined)
300
+ return "";
301
+ if (typeof val === "string" && (val.includes(",") || val.includes('"'))) {
302
+ return `"${val.replace(/"/g, '""')}"`;
303
+ }
304
+ return String(val);
305
+ })
306
+ .join(",");
307
+ });
308
+ return `${headers}\n${rows.join("\n")}`;
309
+ }
310
+ // Default: JSON
311
+ return listResult.data.map((entry) => entry.content);
312
+ }
313
+ /**
314
+ * Registers a custom action
315
+ */
316
+ registerAction(name, handler, options) {
317
+ this.actions.registerSimple(name, async (ctx, params) => ({
318
+ success: true,
319
+ data: await handler(ctx, params),
320
+ }), options);
321
+ }
322
+ /**
323
+ * Gets table schemas (for external access)
324
+ */
325
+ getSchemas() {
326
+ return this.schemas;
327
+ }
328
+ /**
329
+ * Gets the database instance (for advanced operations)
330
+ */
331
+ getDatabase() {
332
+ return this.db;
333
+ }
334
+ }
335
+ exports.SQLiteAFS = SQLiteAFS;
336
+ // Type check to ensure SQLiteAFS implements AFSModuleClass
337
+ const _typeCheck = SQLiteAFS;
@@ -0,0 +1,5 @@
1
+ import type { ActionsRegistry } from "./registry.js";
2
+ /**
3
+ * Registers built-in actions to the registry
4
+ */
5
+ export declare function registerBuiltInActions(registry: ActionsRegistry): void;
@@ -0,0 +1,49 @@
1
+ import type { ActionContext, ActionDefinition, ActionHandler, ActionResult } from "./types.js";
2
+ /**
3
+ * Registry for managing action handlers
4
+ */
5
+ export declare class ActionsRegistry {
6
+ private handlers;
7
+ /**
8
+ * Registers an action handler
9
+ */
10
+ register(definition: ActionDefinition): void;
11
+ /**
12
+ * Registers a simple action with just name and handler
13
+ */
14
+ registerSimple(name: string, handler: ActionHandler, options?: {
15
+ description?: string;
16
+ tableLevel?: boolean;
17
+ rowLevel?: boolean;
18
+ }): void;
19
+ /**
20
+ * Unregisters an action
21
+ */
22
+ unregister(name: string): boolean;
23
+ /**
24
+ * Checks if an action is registered
25
+ */
26
+ has(name: string): boolean;
27
+ /**
28
+ * Gets an action definition
29
+ */
30
+ get(name: string): ActionDefinition | undefined;
31
+ /**
32
+ * Lists all registered actions
33
+ */
34
+ list(options?: {
35
+ tableLevel?: boolean;
36
+ rowLevel?: boolean;
37
+ }): ActionDefinition[];
38
+ /**
39
+ * Lists action names
40
+ */
41
+ listNames(options?: {
42
+ tableLevel?: boolean;
43
+ rowLevel?: boolean;
44
+ }): string[];
45
+ /**
46
+ * Executes an action
47
+ */
48
+ execute(name: string, ctx: ActionContext, params?: Record<string, unknown>): Promise<ActionResult>;
49
+ }
@@ -0,0 +1,51 @@
1
+ import type { LibSQLDatabase } from "drizzle-orm/libsql";
2
+ import type { TableSchema } from "../schema/types.js";
3
+ /**
4
+ * Context provided to action handlers
5
+ */
6
+ export interface ActionContext {
7
+ /** Database instance */
8
+ db: LibSQLDatabase;
9
+ /** All table schemas */
10
+ schemas: Map<string, TableSchema>;
11
+ /** Table this action is being executed on */
12
+ table: string;
13
+ /** Primary key of the row (if row-level action) */
14
+ pk?: string;
15
+ /** The row data (if available) */
16
+ row?: Record<string, unknown>;
17
+ /** Reference to the parent module for advanced operations */
18
+ module: {
19
+ refreshSchema(): Promise<void>;
20
+ exportTable(table: string, format: string): Promise<unknown>;
21
+ };
22
+ }
23
+ /**
24
+ * Action handler function signature
25
+ */
26
+ export type ActionHandler = (ctx: ActionContext, params: Record<string, unknown>) => Promise<ActionResult>;
27
+ /**
28
+ * Result from an action execution
29
+ */
30
+ export interface ActionResult {
31
+ success: boolean;
32
+ data?: unknown;
33
+ message?: string;
34
+ }
35
+ /**
36
+ * Action definition with metadata
37
+ */
38
+ export interface ActionDefinition {
39
+ /** Action name */
40
+ name: string;
41
+ /** Description of what the action does */
42
+ description?: string;
43
+ /** Whether this action is available at table level (vs row level) */
44
+ tableLevel?: boolean;
45
+ /** Whether this action is available at row level */
46
+ rowLevel?: boolean;
47
+ /** Input schema for the action parameters */
48
+ inputSchema?: Record<string, unknown>;
49
+ /** The handler function */
50
+ handler: ActionHandler;
51
+ }
@@ -0,0 +1,89 @@
1
+ import { type AFSAccessMode } from "@aigne/afs";
2
+ import { z } from "zod";
3
+ /**
4
+ * FTS (Full-Text Search) configuration schema
5
+ */
6
+ export declare const ftsConfigSchema: z.ZodOptional<z.ZodObject<{
7
+ enabled: z.ZodDefault<z.ZodBoolean>;
8
+ tables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ enabled: boolean;
11
+ tables?: Record<string, string[]> | undefined;
12
+ }, {
13
+ enabled?: boolean | undefined;
14
+ tables?: Record<string, string[]> | undefined;
15
+ }>>;
16
+ /**
17
+ * SQLite AFS module configuration schema
18
+ */
19
+ export declare const sqliteAFSConfigSchema: z.ZodObject<{
20
+ url: z.ZodString;
21
+ name: z.ZodOptional<z.ZodString>;
22
+ description: z.ZodOptional<z.ZodString>;
23
+ accessMode: z.ZodOptional<z.ZodEnum<["readonly", "readwrite"]>>;
24
+ tables: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ excludeTables: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
26
+ fts: z.ZodOptional<z.ZodObject<{
27
+ enabled: z.ZodDefault<z.ZodBoolean>;
28
+ tables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ enabled: boolean;
31
+ tables?: Record<string, string[]> | undefined;
32
+ }, {
33
+ enabled?: boolean | undefined;
34
+ tables?: Record<string, string[]> | undefined;
35
+ }>>;
36
+ wal: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
37
+ }, "strip", z.ZodTypeAny, {
38
+ url: string;
39
+ wal: boolean;
40
+ tables?: string[] | undefined;
41
+ name?: string | undefined;
42
+ description?: string | undefined;
43
+ accessMode?: "readonly" | "readwrite" | undefined;
44
+ excludeTables?: string[] | undefined;
45
+ fts?: {
46
+ enabled: boolean;
47
+ tables?: Record<string, string[]> | undefined;
48
+ } | undefined;
49
+ }, {
50
+ url: string;
51
+ tables?: string[] | undefined;
52
+ name?: string | undefined;
53
+ description?: string | undefined;
54
+ accessMode?: "readonly" | "readwrite" | undefined;
55
+ excludeTables?: string[] | undefined;
56
+ fts?: {
57
+ enabled?: boolean | undefined;
58
+ tables?: Record<string, string[]> | undefined;
59
+ } | undefined;
60
+ wal?: boolean | undefined;
61
+ }>;
62
+ /**
63
+ * SQLite AFS module configuration type
64
+ */
65
+ export type SQLiteAFSConfig = z.infer<typeof sqliteAFSConfigSchema>;
66
+ /**
67
+ * SQLite AFS module options (after parsing)
68
+ */
69
+ export interface SQLiteAFSOptions {
70
+ /** SQLite database URL */
71
+ url: string;
72
+ /** Module name */
73
+ name?: string;
74
+ /** Module description */
75
+ description?: string;
76
+ /** Access mode */
77
+ accessMode?: AFSAccessMode;
78
+ /** Tables to expose */
79
+ tables?: string[];
80
+ /** Tables to exclude */
81
+ excludeTables?: string[];
82
+ /** FTS configuration */
83
+ fts?: {
84
+ enabled?: boolean;
85
+ tables?: Record<string, string[]>;
86
+ };
87
+ /** Enable WAL mode */
88
+ wal?: boolean;
89
+ }
@@ -0,0 +1,13 @@
1
+ export { registerBuiltInActions } from "./actions/built-in.js";
2
+ export { ActionsRegistry } from "./actions/registry.js";
3
+ export type { ActionContext, ActionDefinition, ActionHandler, ActionResult, } from "./actions/types.js";
4
+ export { type SQLiteAFSConfig, type SQLiteAFSOptions, sqliteAFSConfigSchema } from "./config.js";
5
+ export { type BuildEntryOptions, buildActionsListEntry, buildAttributeEntry, buildAttributeListEntry, buildMetaEntry, buildRowEntry, buildSchemaEntry, buildSearchEntry, buildTableEntry, } from "./node/builder.js";
6
+ export { CRUDOperations } from "./operations/crud.js";
7
+ export { buildDelete, buildGetLastRowId, buildInsert, buildSelectAll, buildSelectByPK, buildUpdate, } from "./operations/query-builder.js";
8
+ export { createFTSConfig, type FTSConfig, FTSSearch, type FTSTableConfig, } from "./operations/search.js";
9
+ export { buildPath, createPathRouter, getVirtualPathType, isVirtualPath, matchPath, } from "./router/path-router.js";
10
+ export type { RouteAction, RouteData, RouteMatch, RouteParams } from "./router/types.js";
11
+ export { SchemaIntrospector } from "./schema/introspector.js";
12
+ export type { ColumnInfo, ForeignKeyInfo, IndexInfo, PragmaForeignKeyRow, PragmaIndexListRow, PragmaTableInfoRow, TableSchema, } from "./schema/types.js";
13
+ export { SQLiteAFS } from "./sqlite-afs.js";
@@ -0,0 +1,43 @@
1
+ import type { AFSEntry } from "@aigne/afs";
2
+ import type { TableSchema } from "../schema/types.js";
3
+ /**
4
+ * Options for building an AFSEntry
5
+ */
6
+ export interface BuildEntryOptions {
7
+ /** Base path prefix (e.g., empty string or module mount path) */
8
+ basePath?: string;
9
+ }
10
+ /**
11
+ * Builds an AFSEntry from a database row
12
+ */
13
+ export declare function buildRowEntry(table: string, schema: TableSchema, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
14
+ /**
15
+ * Builds an AFSEntry for a table listing
16
+ */
17
+ export declare function buildTableEntry(table: string, schema: TableSchema, options?: BuildEntryOptions & {
18
+ rowCount?: number;
19
+ }): AFSEntry;
20
+ /**
21
+ * Builds an AFSEntry for table schema
22
+ */
23
+ export declare function buildSchemaEntry(table: string, schema: TableSchema, options?: BuildEntryOptions): AFSEntry;
24
+ /**
25
+ * Builds an AFSEntry for an attribute (single column value)
26
+ */
27
+ export declare function buildAttributeEntry(table: string, pk: string, column: string, value: unknown, options?: BuildEntryOptions): AFSEntry;
28
+ /**
29
+ * Builds an AFSEntry listing all attributes for a row
30
+ */
31
+ export declare function buildAttributeListEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry[];
32
+ /**
33
+ * Builds an AFSEntry for row metadata
34
+ */
35
+ export declare function buildMetaEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
36
+ /**
37
+ * Builds AFSEntry for actions list
38
+ */
39
+ export declare function buildActionsListEntry(table: string, pk: string, actions: string[], options?: BuildEntryOptions): AFSEntry[];
40
+ /**
41
+ * Builds a search result entry with highlights
42
+ */
43
+ export declare function buildSearchEntry(table: string, schema: TableSchema, row: Record<string, unknown>, snippet?: string, options?: BuildEntryOptions): AFSEntry;
@@ -0,0 +1,64 @@
1
+ import type { AFSDeleteResult, AFSListOptions, AFSListResult, AFSReadResult, AFSWriteResult } from "@aigne/afs";
2
+ import type { LibSQLDatabase } from "drizzle-orm/libsql";
3
+ import type { TableSchema } from "../schema/types.js";
4
+ /**
5
+ * CRUD operations for SQLite AFS
6
+ */
7
+ export declare class CRUDOperations {
8
+ private db;
9
+ private schemas;
10
+ private basePath;
11
+ constructor(db: LibSQLDatabase, schemas: Map<string, TableSchema>, basePath?: string);
12
+ /**
13
+ * Lists all tables
14
+ */
15
+ listTables(): Promise<AFSListResult>;
16
+ /**
17
+ * Lists rows in a table
18
+ */
19
+ listTable(table: string, options?: AFSListOptions): Promise<AFSListResult>;
20
+ /**
21
+ * Reads a single row by primary key
22
+ */
23
+ readRow(table: string, pk: string): Promise<AFSReadResult>;
24
+ /**
25
+ * Gets table schema
26
+ */
27
+ getSchema(table: string): AFSReadResult;
28
+ /**
29
+ * Lists attributes (columns) for a row
30
+ */
31
+ listAttributes(table: string, pk: string): Promise<AFSListResult>;
32
+ /**
33
+ * Gets a single attribute (column value) for a row
34
+ */
35
+ getAttribute(table: string, pk: string, column: string): Promise<AFSReadResult>;
36
+ /**
37
+ * Gets row metadata
38
+ */
39
+ getMeta(table: string, pk: string): Promise<AFSReadResult>;
40
+ /**
41
+ * Creates a new row in a table
42
+ */
43
+ createRow(table: string, content: Record<string, unknown>): Promise<AFSWriteResult>;
44
+ /**
45
+ * Updates an existing row
46
+ */
47
+ updateRow(table: string, pk: string, content: Record<string, unknown>): Promise<AFSWriteResult>;
48
+ /**
49
+ * Deletes a row by primary key
50
+ */
51
+ deleteRow(table: string, pk: string): Promise<AFSDeleteResult>;
52
+ /**
53
+ * Checks if a table exists
54
+ */
55
+ hasTable(table: string): boolean;
56
+ /**
57
+ * Gets the schema for a table
58
+ */
59
+ getTableSchema(table: string): TableSchema | undefined;
60
+ /**
61
+ * Updates the schemas map (after refresh)
62
+ */
63
+ setSchemas(schemas: Map<string, TableSchema>): void;
64
+ }
@@ -0,0 +1,37 @@
1
+ import type { TableSchema } from "../schema/types.js";
2
+ /**
3
+ * Builds a SELECT query string for a single row by primary key
4
+ */
5
+ export declare function buildSelectByPK(tableName: string, schema: TableSchema, pk: string): string;
6
+ /**
7
+ * Builds a SELECT query string for listing rows with optional limit and offset
8
+ */
9
+ export declare function buildSelectAll(tableName: string, options?: {
10
+ limit?: number;
11
+ offset?: number;
12
+ orderBy?: [string, "asc" | "desc"][];
13
+ }): string;
14
+ /**
15
+ * Builds an INSERT query string from content object
16
+ */
17
+ export declare function buildInsert(tableName: string, schema: TableSchema, content: Record<string, unknown>): string;
18
+ /**
19
+ * Builds an UPDATE query string from content object
20
+ */
21
+ export declare function buildUpdate(tableName: string, schema: TableSchema, pk: string, content: Record<string, unknown>): string;
22
+ /**
23
+ * Builds a DELETE query string by primary key
24
+ */
25
+ export declare function buildDelete(tableName: string, schema: TableSchema, pk: string): string;
26
+ /**
27
+ * Formats a value for SQL insertion
28
+ */
29
+ export declare function formatValue(value: unknown): string;
30
+ /**
31
+ * Escapes a string for safe SQL insertion
32
+ */
33
+ export declare function escapeSQLString(str: string): string;
34
+ /**
35
+ * Gets the last inserted rowid query string
36
+ */
37
+ export declare function buildGetLastRowId(): string;