@aigne/afs-sqlite 1.11.0-beta → 1.11.0-beta.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.
Files changed (95) hide show
  1. package/LICENSE.md +17 -84
  2. package/README.md +0 -3
  3. package/dist/actions/built-in.cjs +142 -0
  4. package/dist/actions/built-in.d.cts +10 -0
  5. package/dist/actions/built-in.d.cts.map +1 -0
  6. package/dist/actions/built-in.d.mts +10 -0
  7. package/dist/actions/built-in.d.mts.map +1 -0
  8. package/dist/actions/built-in.mjs +143 -0
  9. package/dist/actions/built-in.mjs.map +1 -0
  10. package/dist/actions/registry.cjs +91 -0
  11. package/dist/actions/registry.d.cts +54 -0
  12. package/dist/actions/registry.d.cts.map +1 -0
  13. package/dist/actions/registry.d.mts +54 -0
  14. package/dist/actions/registry.d.mts.map +1 -0
  15. package/dist/actions/registry.mjs +91 -0
  16. package/dist/actions/registry.mjs.map +1 -0
  17. package/dist/actions/types.d.cts +56 -0
  18. package/dist/actions/types.d.cts.map +1 -0
  19. package/dist/actions/types.d.mts +56 -0
  20. package/dist/actions/types.d.mts.map +1 -0
  21. package/dist/config.cjs +27 -0
  22. package/dist/config.d.cts +81 -0
  23. package/dist/config.d.cts.map +1 -0
  24. package/dist/config.d.mts +81 -0
  25. package/dist/config.d.mts.map +1 -0
  26. package/dist/config.mjs +28 -0
  27. package/dist/config.mjs.map +1 -0
  28. package/dist/index.cjs +38 -1324
  29. package/dist/index.d.cts +14 -758
  30. package/dist/index.d.mts +14 -758
  31. package/dist/index.mjs +12 -1299
  32. package/dist/node/builder.cjs +179 -0
  33. package/dist/node/builder.d.cts +48 -0
  34. package/dist/node/builder.d.cts.map +1 -0
  35. package/dist/node/builder.d.mts +48 -0
  36. package/dist/node/builder.d.mts.map +1 -0
  37. package/dist/node/builder.mjs +172 -0
  38. package/dist/node/builder.mjs.map +1 -0
  39. package/dist/operations/crud.cjs +176 -0
  40. package/dist/operations/crud.d.cts +69 -0
  41. package/dist/operations/crud.d.cts.map +1 -0
  42. package/dist/operations/crud.d.mts +69 -0
  43. package/dist/operations/crud.d.mts.map +1 -0
  44. package/dist/operations/crud.mjs +177 -0
  45. package/dist/operations/crud.mjs.map +1 -0
  46. package/dist/operations/query-builder.cjs +77 -0
  47. package/dist/operations/query-builder.d.cts +34 -0
  48. package/dist/operations/query-builder.d.cts.map +1 -0
  49. package/dist/operations/query-builder.d.mts +34 -0
  50. package/dist/operations/query-builder.d.mts.map +1 -0
  51. package/dist/operations/query-builder.mjs +72 -0
  52. package/dist/operations/query-builder.mjs.map +1 -0
  53. package/dist/operations/search.cjs +141 -0
  54. package/dist/operations/search.d.cts +79 -0
  55. package/dist/operations/search.d.cts.map +1 -0
  56. package/dist/operations/search.d.mts +79 -0
  57. package/dist/operations/search.d.mts.map +1 -0
  58. package/dist/operations/search.mjs +141 -0
  59. package/dist/operations/search.mjs.map +1 -0
  60. package/dist/router/path-router.cjs +79 -0
  61. package/dist/router/path-router.d.cts +42 -0
  62. package/dist/router/path-router.d.cts.map +1 -0
  63. package/dist/router/path-router.d.mts +42 -0
  64. package/dist/router/path-router.d.mts.map +1 -0
  65. package/dist/router/path-router.mjs +76 -0
  66. package/dist/router/path-router.mjs.map +1 -0
  67. package/dist/router/types.d.cts +34 -0
  68. package/dist/router/types.d.cts.map +1 -0
  69. package/dist/router/types.d.mts +34 -0
  70. package/dist/router/types.d.mts.map +1 -0
  71. package/dist/schema/introspector.cjs +160 -0
  72. package/dist/schema/introspector.d.cts +49 -0
  73. package/dist/schema/introspector.d.cts.map +1 -0
  74. package/dist/schema/introspector.d.mts +49 -0
  75. package/dist/schema/introspector.d.mts.map +1 -0
  76. package/dist/schema/introspector.mjs +161 -0
  77. package/dist/schema/introspector.mjs.map +1 -0
  78. package/dist/schema/types.cjs +15 -0
  79. package/dist/schema/types.d.cts +104 -0
  80. package/dist/schema/types.d.cts.map +1 -0
  81. package/dist/schema/types.d.mts +104 -0
  82. package/dist/schema/types.d.mts.map +1 -0
  83. package/dist/schema/types.mjs +15 -0
  84. package/dist/schema/types.mjs.map +1 -0
  85. package/dist/sqlite-afs.cjs +264 -0
  86. package/dist/sqlite-afs.d.cts +152 -0
  87. package/dist/sqlite-afs.d.cts.map +1 -0
  88. package/dist/sqlite-afs.d.mts +152 -0
  89. package/dist/sqlite-afs.d.mts.map +1 -0
  90. package/dist/sqlite-afs.mjs +265 -0
  91. package/dist/sqlite-afs.mjs.map +1 -0
  92. package/package.json +3 -3
  93. package/dist/index.d.cts.map +0 -1
  94. package/dist/index.d.mts.map +0 -1
  95. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,179 @@
1
+
2
+ //#region src/node/builder.ts
3
+ /**
4
+ * Builds an AFSEntry from a database row
5
+ */
6
+ function buildRowEntry(table, schema, row, options) {
7
+ const pkColumn = schema.primaryKey[0] ?? "rowid";
8
+ const pk = String(row[pkColumn] ?? row.rowid);
9
+ const basePath = options?.basePath ?? "";
10
+ return {
11
+ id: `${table}:${pk}`,
12
+ path: `${basePath}/${table}/${pk}`,
13
+ content: row,
14
+ metadata: {
15
+ table,
16
+ primaryKey: pkColumn,
17
+ primaryKeyValue: pk
18
+ },
19
+ createdAt: parseDate(row.created_at ?? row.createdAt),
20
+ updatedAt: parseDate(row.updated_at ?? row.updatedAt)
21
+ };
22
+ }
23
+ /**
24
+ * Builds an AFSEntry for a table listing
25
+ */
26
+ function buildTableEntry(table, schema, options) {
27
+ return {
28
+ id: table,
29
+ path: `${options?.basePath ?? ""}/${table}`,
30
+ description: `Table: ${table} (${schema.columns.length} columns)`,
31
+ metadata: {
32
+ table,
33
+ columnCount: schema.columns.length,
34
+ primaryKey: schema.primaryKey,
35
+ childrenCount: options?.rowCount
36
+ }
37
+ };
38
+ }
39
+ /**
40
+ * Builds an AFSEntry for table schema
41
+ */
42
+ function buildSchemaEntry(table, schema, options) {
43
+ const basePath = options?.basePath ?? "";
44
+ return {
45
+ id: `${table}:@schema`,
46
+ path: `${basePath}/${table}/@schema`,
47
+ description: `Schema for table: ${table}`,
48
+ content: {
49
+ name: schema.name,
50
+ columns: schema.columns.map((col) => ({
51
+ name: col.name,
52
+ type: col.type,
53
+ nullable: !col.notnull,
54
+ primaryKey: col.pk > 0,
55
+ defaultValue: col.dfltValue
56
+ })),
57
+ primaryKey: schema.primaryKey,
58
+ foreignKeys: schema.foreignKeys.map((fk) => ({
59
+ column: fk.from,
60
+ references: {
61
+ table: fk.table,
62
+ column: fk.to
63
+ },
64
+ onUpdate: fk.onUpdate,
65
+ onDelete: fk.onDelete
66
+ })),
67
+ indexes: schema.indexes.map((idx) => ({
68
+ name: idx.name,
69
+ unique: idx.unique,
70
+ origin: idx.origin
71
+ }))
72
+ },
73
+ metadata: {
74
+ table,
75
+ type: "schema"
76
+ }
77
+ };
78
+ }
79
+ /**
80
+ * Builds an AFSEntry for an attribute (single column value)
81
+ */
82
+ function buildAttributeEntry(table, pk, column, value, options) {
83
+ const basePath = options?.basePath ?? "";
84
+ return {
85
+ id: `${table}:${pk}:@attr:${column}`,
86
+ path: `${basePath}/${table}/${pk}/@attr/${column}`,
87
+ content: value,
88
+ metadata: {
89
+ table,
90
+ primaryKeyValue: pk,
91
+ column,
92
+ type: "attribute"
93
+ }
94
+ };
95
+ }
96
+ /**
97
+ * Builds an AFSEntry listing all attributes for a row
98
+ */
99
+ function buildAttributeListEntry(table, schema, pk, row, options) {
100
+ const basePath = options?.basePath ?? "";
101
+ return schema.columns.map((col) => ({
102
+ id: `${table}:${pk}:@attr:${col.name}`,
103
+ path: `${basePath}/${table}/${pk}/@attr/${col.name}`,
104
+ summary: col.name,
105
+ description: `${col.type}${col.notnull ? " NOT NULL" : ""}`,
106
+ content: row[col.name],
107
+ metadata: {
108
+ column: col.name,
109
+ type: col.type
110
+ }
111
+ }));
112
+ }
113
+ /**
114
+ * Builds an AFSEntry for row metadata
115
+ */
116
+ function buildMetaEntry(table, schema, pk, row, options) {
117
+ const basePath = options?.basePath ?? "";
118
+ return {
119
+ id: `${table}:${pk}:@meta`,
120
+ path: `${basePath}/${table}/${pk}/@meta`,
121
+ content: {
122
+ table,
123
+ primaryKey: schema.primaryKey[0] ?? "rowid",
124
+ primaryKeyValue: pk,
125
+ schema: {
126
+ columns: schema.columns.map((c) => c.name),
127
+ types: Object.fromEntries(schema.columns.map((c) => [c.name, c.type]))
128
+ },
129
+ foreignKeys: schema.foreignKeys.filter((fk) => Object.keys(row).includes(fk.from)),
130
+ rowid: row.rowid
131
+ },
132
+ metadata: {
133
+ table,
134
+ type: "meta"
135
+ }
136
+ };
137
+ }
138
+ /**
139
+ * Builds AFSEntry for actions list
140
+ */
141
+ function buildActionsListEntry(table, pk, actions, options) {
142
+ const basePath = options?.basePath ?? "";
143
+ return actions.map((action) => ({
144
+ id: `${table}:${pk}:@actions:${action}`,
145
+ path: `${basePath}/${table}/${pk}/@actions/${action}`,
146
+ summary: action,
147
+ metadata: { execute: {
148
+ name: action,
149
+ description: `Execute ${action} action on ${table}:${pk}`
150
+ } }
151
+ }));
152
+ }
153
+ /**
154
+ * Builds a search result entry with highlights
155
+ */
156
+ function buildSearchEntry(table, schema, row, snippet, options) {
157
+ const entry = buildRowEntry(table, schema, row, options);
158
+ if (snippet) entry.summary = snippet;
159
+ return entry;
160
+ }
161
+ /**
162
+ * Parses a date from various formats
163
+ */
164
+ function parseDate(value) {
165
+ if (!value) return void 0;
166
+ if (value instanceof Date) return value;
167
+ if (typeof value === "string") return new Date(value);
168
+ if (typeof value === "number") return new Date(value);
169
+ }
170
+
171
+ //#endregion
172
+ exports.buildActionsListEntry = buildActionsListEntry;
173
+ exports.buildAttributeEntry = buildAttributeEntry;
174
+ exports.buildAttributeListEntry = buildAttributeListEntry;
175
+ exports.buildMetaEntry = buildMetaEntry;
176
+ exports.buildRowEntry = buildRowEntry;
177
+ exports.buildSchemaEntry = buildSchemaEntry;
178
+ exports.buildSearchEntry = buildSearchEntry;
179
+ exports.buildTableEntry = buildTableEntry;
@@ -0,0 +1,48 @@
1
+ import { TableSchema } from "../schema/types.cjs";
2
+ import { AFSEntry } from "@aigne/afs";
3
+
4
+ //#region src/node/builder.d.ts
5
+ /**
6
+ * Options for building an AFSEntry
7
+ */
8
+ interface BuildEntryOptions {
9
+ /** Base path prefix (e.g., empty string or module mount path) */
10
+ basePath?: string;
11
+ }
12
+ /**
13
+ * Builds an AFSEntry from a database row
14
+ */
15
+ declare function buildRowEntry(table: string, schema: TableSchema, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
16
+ /**
17
+ * Builds an AFSEntry for a table listing
18
+ */
19
+ declare function buildTableEntry(table: string, schema: TableSchema, options?: BuildEntryOptions & {
20
+ rowCount?: number;
21
+ }): AFSEntry;
22
+ /**
23
+ * Builds an AFSEntry for table schema
24
+ */
25
+ declare function buildSchemaEntry(table: string, schema: TableSchema, options?: BuildEntryOptions): AFSEntry;
26
+ /**
27
+ * Builds an AFSEntry for an attribute (single column value)
28
+ */
29
+ declare function buildAttributeEntry(table: string, pk: string, column: string, value: unknown, options?: BuildEntryOptions): AFSEntry;
30
+ /**
31
+ * Builds an AFSEntry listing all attributes for a row
32
+ */
33
+ declare function buildAttributeListEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry[];
34
+ /**
35
+ * Builds an AFSEntry for row metadata
36
+ */
37
+ declare function buildMetaEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
38
+ /**
39
+ * Builds AFSEntry for actions list
40
+ */
41
+ declare function buildActionsListEntry(table: string, pk: string, actions: string[], options?: BuildEntryOptions): AFSEntry[];
42
+ /**
43
+ * Builds a search result entry with highlights
44
+ */
45
+ declare function buildSearchEntry(table: string, schema: TableSchema, row: Record<string, unknown>, snippet?: string, options?: BuildEntryOptions): AFSEntry;
46
+ //#endregion
47
+ export { BuildEntryOptions, buildActionsListEntry, buildAttributeEntry, buildAttributeListEntry, buildMetaEntry, buildRowEntry, buildSchemaEntry, buildSearchEntry, buildTableEntry };
48
+ //# sourceMappingURL=builder.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.cts","names":[],"sources":["../../src/node/builder.ts"],"mappings":";;;;;AAMA;AAQA;UARiB,iBAAA;EAAA;EAAA,QAAA;AAAA;AAAA;AAQjB;;AARiB,iBAQD,aAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,GAAA,EACH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AAsBH;AAtBG,iBAsBa,eAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,OAAA,GACE,iBAAA;EAAA,QAAA;AAAA,IACT,QAAA;AAAA;;AAmBH;AAnBG,iBAmBa,gBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,OAAA,GACE,iBAAA,GACT,QAAA;AAAA;;AA0CH;AA1CG,iBA0Ca,mBAAA,CAAA,KAAA,UAAA,EAAA,UAAA,MAAA,UAAA,KAAA,WAAA,OAAA,GAKJ,iBAAA,GACT,QAAA;AAAA;AAmBH;;AAnBG,iBAmBa,uBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,EAAA,UAAA,GAAA,EAEH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AAmBH;AAnBG,iBAmBa,cAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,EAAA,UAAA,GAAA,EAEH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AA2BH;AA3BG,iBA2Ba,qBAAA,CAAA,KAAA,UAAA,EAAA,UAAA,OAAA,YAAA,OAAA,GAIJ,iBAAA,GACT,QAAA;AAAA;AAmBH;;AAnBG,iBAmBa,gBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,GAAA,EACH,MAAA,mBAAA,OAAA,WAAA,OAAA,GAEK,iBAAA,GACT,QAAA"}
@@ -0,0 +1,48 @@
1
+ import { TableSchema } from "../schema/types.mjs";
2
+ import { AFSEntry } from "@aigne/afs";
3
+
4
+ //#region src/node/builder.d.ts
5
+ /**
6
+ * Options for building an AFSEntry
7
+ */
8
+ interface BuildEntryOptions {
9
+ /** Base path prefix (e.g., empty string or module mount path) */
10
+ basePath?: string;
11
+ }
12
+ /**
13
+ * Builds an AFSEntry from a database row
14
+ */
15
+ declare function buildRowEntry(table: string, schema: TableSchema, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
16
+ /**
17
+ * Builds an AFSEntry for a table listing
18
+ */
19
+ declare function buildTableEntry(table: string, schema: TableSchema, options?: BuildEntryOptions & {
20
+ rowCount?: number;
21
+ }): AFSEntry;
22
+ /**
23
+ * Builds an AFSEntry for table schema
24
+ */
25
+ declare function buildSchemaEntry(table: string, schema: TableSchema, options?: BuildEntryOptions): AFSEntry;
26
+ /**
27
+ * Builds an AFSEntry for an attribute (single column value)
28
+ */
29
+ declare function buildAttributeEntry(table: string, pk: string, column: string, value: unknown, options?: BuildEntryOptions): AFSEntry;
30
+ /**
31
+ * Builds an AFSEntry listing all attributes for a row
32
+ */
33
+ declare function buildAttributeListEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry[];
34
+ /**
35
+ * Builds an AFSEntry for row metadata
36
+ */
37
+ declare function buildMetaEntry(table: string, schema: TableSchema, pk: string, row: Record<string, unknown>, options?: BuildEntryOptions): AFSEntry;
38
+ /**
39
+ * Builds AFSEntry for actions list
40
+ */
41
+ declare function buildActionsListEntry(table: string, pk: string, actions: string[], options?: BuildEntryOptions): AFSEntry[];
42
+ /**
43
+ * Builds a search result entry with highlights
44
+ */
45
+ declare function buildSearchEntry(table: string, schema: TableSchema, row: Record<string, unknown>, snippet?: string, options?: BuildEntryOptions): AFSEntry;
46
+ //#endregion
47
+ export { BuildEntryOptions, buildActionsListEntry, buildAttributeEntry, buildAttributeListEntry, buildMetaEntry, buildRowEntry, buildSchemaEntry, buildSearchEntry, buildTableEntry };
48
+ //# sourceMappingURL=builder.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.mts","names":[],"sources":["../../src/node/builder.ts"],"mappings":";;;;;AAMA;AAQA;UARiB,iBAAA;EAAA;EAAA,QAAA;AAAA;AAAA;AAQjB;;AARiB,iBAQD,aAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,GAAA,EACH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AAsBH;AAtBG,iBAsBa,eAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,OAAA,GACE,iBAAA;EAAA,QAAA;AAAA,IACT,QAAA;AAAA;;AAmBH;AAnBG,iBAmBa,gBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,OAAA,GACE,iBAAA,GACT,QAAA;AAAA;;AA0CH;AA1CG,iBA0Ca,mBAAA,CAAA,KAAA,UAAA,EAAA,UAAA,MAAA,UAAA,KAAA,WAAA,OAAA,GAKJ,iBAAA,GACT,QAAA;AAAA;AAmBH;;AAnBG,iBAmBa,uBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,EAAA,UAAA,GAAA,EAEH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AAmBH;AAnBG,iBAmBa,cAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,EAAA,UAAA,GAAA,EAEH,MAAA,mBAAA,OAAA,GACK,iBAAA,GACT,QAAA;AAAA;;AA2BH;AA3BG,iBA2Ba,qBAAA,CAAA,KAAA,UAAA,EAAA,UAAA,OAAA,YAAA,OAAA,GAIJ,iBAAA,GACT,QAAA;AAAA;AAmBH;;AAnBG,iBAmBa,gBAAA,CAAA,KAAA,UAAA,MAAA,EAEN,WAAA,EAAA,GAAA,EACH,MAAA,mBAAA,OAAA,WAAA,OAAA,GAEK,iBAAA,GACT,QAAA"}
@@ -0,0 +1,172 @@
1
+ //#region src/node/builder.ts
2
+ /**
3
+ * Builds an AFSEntry from a database row
4
+ */
5
+ function buildRowEntry(table, schema, row, options) {
6
+ const pkColumn = schema.primaryKey[0] ?? "rowid";
7
+ const pk = String(row[pkColumn] ?? row.rowid);
8
+ const basePath = options?.basePath ?? "";
9
+ return {
10
+ id: `${table}:${pk}`,
11
+ path: `${basePath}/${table}/${pk}`,
12
+ content: row,
13
+ metadata: {
14
+ table,
15
+ primaryKey: pkColumn,
16
+ primaryKeyValue: pk
17
+ },
18
+ createdAt: parseDate(row.created_at ?? row.createdAt),
19
+ updatedAt: parseDate(row.updated_at ?? row.updatedAt)
20
+ };
21
+ }
22
+ /**
23
+ * Builds an AFSEntry for a table listing
24
+ */
25
+ function buildTableEntry(table, schema, options) {
26
+ return {
27
+ id: table,
28
+ path: `${options?.basePath ?? ""}/${table}`,
29
+ description: `Table: ${table} (${schema.columns.length} columns)`,
30
+ metadata: {
31
+ table,
32
+ columnCount: schema.columns.length,
33
+ primaryKey: schema.primaryKey,
34
+ childrenCount: options?.rowCount
35
+ }
36
+ };
37
+ }
38
+ /**
39
+ * Builds an AFSEntry for table schema
40
+ */
41
+ function buildSchemaEntry(table, schema, options) {
42
+ const basePath = options?.basePath ?? "";
43
+ return {
44
+ id: `${table}:@schema`,
45
+ path: `${basePath}/${table}/@schema`,
46
+ description: `Schema for table: ${table}`,
47
+ content: {
48
+ name: schema.name,
49
+ columns: schema.columns.map((col) => ({
50
+ name: col.name,
51
+ type: col.type,
52
+ nullable: !col.notnull,
53
+ primaryKey: col.pk > 0,
54
+ defaultValue: col.dfltValue
55
+ })),
56
+ primaryKey: schema.primaryKey,
57
+ foreignKeys: schema.foreignKeys.map((fk) => ({
58
+ column: fk.from,
59
+ references: {
60
+ table: fk.table,
61
+ column: fk.to
62
+ },
63
+ onUpdate: fk.onUpdate,
64
+ onDelete: fk.onDelete
65
+ })),
66
+ indexes: schema.indexes.map((idx) => ({
67
+ name: idx.name,
68
+ unique: idx.unique,
69
+ origin: idx.origin
70
+ }))
71
+ },
72
+ metadata: {
73
+ table,
74
+ type: "schema"
75
+ }
76
+ };
77
+ }
78
+ /**
79
+ * Builds an AFSEntry for an attribute (single column value)
80
+ */
81
+ function buildAttributeEntry(table, pk, column, value, options) {
82
+ const basePath = options?.basePath ?? "";
83
+ return {
84
+ id: `${table}:${pk}:@attr:${column}`,
85
+ path: `${basePath}/${table}/${pk}/@attr/${column}`,
86
+ content: value,
87
+ metadata: {
88
+ table,
89
+ primaryKeyValue: pk,
90
+ column,
91
+ type: "attribute"
92
+ }
93
+ };
94
+ }
95
+ /**
96
+ * Builds an AFSEntry listing all attributes for a row
97
+ */
98
+ function buildAttributeListEntry(table, schema, pk, row, options) {
99
+ const basePath = options?.basePath ?? "";
100
+ return schema.columns.map((col) => ({
101
+ id: `${table}:${pk}:@attr:${col.name}`,
102
+ path: `${basePath}/${table}/${pk}/@attr/${col.name}`,
103
+ summary: col.name,
104
+ description: `${col.type}${col.notnull ? " NOT NULL" : ""}`,
105
+ content: row[col.name],
106
+ metadata: {
107
+ column: col.name,
108
+ type: col.type
109
+ }
110
+ }));
111
+ }
112
+ /**
113
+ * Builds an AFSEntry for row metadata
114
+ */
115
+ function buildMetaEntry(table, schema, pk, row, options) {
116
+ const basePath = options?.basePath ?? "";
117
+ return {
118
+ id: `${table}:${pk}:@meta`,
119
+ path: `${basePath}/${table}/${pk}/@meta`,
120
+ content: {
121
+ table,
122
+ primaryKey: schema.primaryKey[0] ?? "rowid",
123
+ primaryKeyValue: pk,
124
+ schema: {
125
+ columns: schema.columns.map((c) => c.name),
126
+ types: Object.fromEntries(schema.columns.map((c) => [c.name, c.type]))
127
+ },
128
+ foreignKeys: schema.foreignKeys.filter((fk) => Object.keys(row).includes(fk.from)),
129
+ rowid: row.rowid
130
+ },
131
+ metadata: {
132
+ table,
133
+ type: "meta"
134
+ }
135
+ };
136
+ }
137
+ /**
138
+ * Builds AFSEntry for actions list
139
+ */
140
+ function buildActionsListEntry(table, pk, actions, options) {
141
+ const basePath = options?.basePath ?? "";
142
+ return actions.map((action) => ({
143
+ id: `${table}:${pk}:@actions:${action}`,
144
+ path: `${basePath}/${table}/${pk}/@actions/${action}`,
145
+ summary: action,
146
+ metadata: { execute: {
147
+ name: action,
148
+ description: `Execute ${action} action on ${table}:${pk}`
149
+ } }
150
+ }));
151
+ }
152
+ /**
153
+ * Builds a search result entry with highlights
154
+ */
155
+ function buildSearchEntry(table, schema, row, snippet, options) {
156
+ const entry = buildRowEntry(table, schema, row, options);
157
+ if (snippet) entry.summary = snippet;
158
+ return entry;
159
+ }
160
+ /**
161
+ * Parses a date from various formats
162
+ */
163
+ function parseDate(value) {
164
+ if (!value) return void 0;
165
+ if (value instanceof Date) return value;
166
+ if (typeof value === "string") return new Date(value);
167
+ if (typeof value === "number") return new Date(value);
168
+ }
169
+
170
+ //#endregion
171
+ export { buildActionsListEntry, buildAttributeEntry, buildAttributeListEntry, buildMetaEntry, buildRowEntry, buildSchemaEntry, buildSearchEntry, buildTableEntry };
172
+ //# sourceMappingURL=builder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.mjs","names":[],"sources":["../../src/node/builder.ts"],"sourcesContent":["import type { AFSEntry } from \"@aigne/afs\";\nimport type { TableSchema } from \"../schema/types.js\";\n\n/**\n * Options for building an AFSEntry\n */\nexport interface BuildEntryOptions {\n /** Base path prefix (e.g., empty string or module mount path) */\n basePath?: string;\n}\n\n/**\n * Builds an AFSEntry from a database row\n */\nexport function buildRowEntry(\n table: string,\n schema: TableSchema,\n row: Record<string, unknown>,\n options?: BuildEntryOptions,\n): AFSEntry {\n const pkColumn = schema.primaryKey[0] ?? \"rowid\";\n const pk = String(row[pkColumn] ?? row.rowid);\n const basePath = options?.basePath ?? \"\";\n\n return {\n id: `${table}:${pk}`,\n path: `${basePath}/${table}/${pk}`,\n content: row,\n metadata: {\n table,\n primaryKey: pkColumn,\n primaryKeyValue: pk,\n },\n createdAt: parseDate(row.created_at ?? row.createdAt),\n updatedAt: parseDate(row.updated_at ?? row.updatedAt),\n };\n}\n\n/**\n * Builds an AFSEntry for a table listing\n */\nexport function buildTableEntry(\n table: string,\n schema: TableSchema,\n options?: BuildEntryOptions & { rowCount?: number },\n): AFSEntry {\n const basePath = options?.basePath ?? \"\";\n\n return {\n id: table,\n path: `${basePath}/${table}`,\n description: `Table: ${table} (${schema.columns.length} columns)`,\n metadata: {\n table,\n columnCount: schema.columns.length,\n primaryKey: schema.primaryKey,\n childrenCount: options?.rowCount,\n },\n };\n}\n\n/**\n * Builds an AFSEntry for table schema\n */\nexport function buildSchemaEntry(\n table: string,\n schema: TableSchema,\n options?: BuildEntryOptions,\n): AFSEntry {\n const basePath = options?.basePath ?? \"\";\n\n return {\n id: `${table}:@schema`,\n path: `${basePath}/${table}/@schema`,\n description: `Schema for table: ${table}`,\n content: {\n name: schema.name,\n columns: schema.columns.map((col) => ({\n name: col.name,\n type: col.type,\n nullable: !col.notnull,\n primaryKey: col.pk > 0,\n defaultValue: col.dfltValue,\n })),\n primaryKey: schema.primaryKey,\n foreignKeys: schema.foreignKeys.map((fk) => ({\n column: fk.from,\n references: {\n table: fk.table,\n column: fk.to,\n },\n onUpdate: fk.onUpdate,\n onDelete: fk.onDelete,\n })),\n indexes: schema.indexes.map((idx) => ({\n name: idx.name,\n unique: idx.unique,\n origin: idx.origin,\n })),\n },\n metadata: {\n table,\n type: \"schema\",\n },\n };\n}\n\n/**\n * Builds an AFSEntry for an attribute (single column value)\n */\nexport function buildAttributeEntry(\n table: string,\n pk: string,\n column: string,\n value: unknown,\n options?: BuildEntryOptions,\n): AFSEntry {\n const basePath = options?.basePath ?? \"\";\n\n return {\n id: `${table}:${pk}:@attr:${column}`,\n path: `${basePath}/${table}/${pk}/@attr/${column}`,\n content: value,\n metadata: {\n table,\n primaryKeyValue: pk,\n column,\n type: \"attribute\",\n },\n };\n}\n\n/**\n * Builds an AFSEntry listing all attributes for a row\n */\nexport function buildAttributeListEntry(\n table: string,\n schema: TableSchema,\n pk: string,\n row: Record<string, unknown>,\n options?: BuildEntryOptions,\n): AFSEntry[] {\n const basePath = options?.basePath ?? \"\";\n\n return schema.columns.map((col) => ({\n id: `${table}:${pk}:@attr:${col.name}`,\n path: `${basePath}/${table}/${pk}/@attr/${col.name}`,\n summary: col.name,\n description: `${col.type}${col.notnull ? \" NOT NULL\" : \"\"}`,\n content: row[col.name],\n metadata: {\n column: col.name,\n type: col.type,\n },\n }));\n}\n\n/**\n * Builds an AFSEntry for row metadata\n */\nexport function buildMetaEntry(\n table: string,\n schema: TableSchema,\n pk: string,\n row: Record<string, unknown>,\n options?: BuildEntryOptions,\n): AFSEntry {\n const basePath = options?.basePath ?? \"\";\n\n return {\n id: `${table}:${pk}:@meta`,\n path: `${basePath}/${table}/${pk}/@meta`,\n content: {\n table,\n primaryKey: schema.primaryKey[0] ?? \"rowid\",\n primaryKeyValue: pk,\n schema: {\n columns: schema.columns.map((c) => c.name),\n types: Object.fromEntries(schema.columns.map((c) => [c.name, c.type])),\n },\n foreignKeys: schema.foreignKeys.filter((fk) => Object.keys(row).includes(fk.from)),\n rowid: row.rowid,\n },\n metadata: {\n table,\n type: \"meta\",\n },\n };\n}\n\n/**\n * Builds AFSEntry for actions list\n */\nexport function buildActionsListEntry(\n table: string,\n pk: string,\n actions: string[],\n options?: BuildEntryOptions,\n): AFSEntry[] {\n const basePath = options?.basePath ?? \"\";\n\n return actions.map((action) => ({\n id: `${table}:${pk}:@actions:${action}`,\n path: `${basePath}/${table}/${pk}/@actions/${action}`,\n summary: action,\n metadata: {\n execute: {\n name: action,\n description: `Execute ${action} action on ${table}:${pk}`,\n },\n },\n }));\n}\n\n/**\n * Builds a search result entry with highlights\n */\nexport function buildSearchEntry(\n table: string,\n schema: TableSchema,\n row: Record<string, unknown>,\n snippet?: string,\n options?: BuildEntryOptions,\n): AFSEntry {\n const entry = buildRowEntry(table, schema, row, options);\n\n if (snippet) {\n entry.summary = snippet;\n }\n\n return entry;\n}\n\n/**\n * Parses a date from various formats\n */\nfunction parseDate(value: unknown): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return value;\n if (typeof value === \"string\") return new Date(value);\n if (typeof value === \"number\") return new Date(value);\n return undefined;\n}\n"],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ const require_builder = require('../node/builder.cjs');
2
+ const require_query_builder = require('./query-builder.cjs');
3
+ let _aigne_sqlite = require("@aigne/sqlite");
4
+
5
+ //#region src/operations/crud.ts
6
+ /**
7
+ * Executes a raw SQL query and returns all rows
8
+ */
9
+ async function execAll(db, query) {
10
+ return db.all(_aigne_sqlite.sql.raw(query)).execute();
11
+ }
12
+ /**
13
+ * Executes a raw SQL query (for INSERT, UPDATE, DELETE)
14
+ */
15
+ async function execRun(db, query) {
16
+ await db.run(_aigne_sqlite.sql.raw(query)).execute();
17
+ }
18
+ /**
19
+ * CRUD operations for SQLite AFS
20
+ */
21
+ var CRUDOperations = class {
22
+ constructor(db, schemas, basePath = "") {
23
+ this.db = db;
24
+ this.schemas = schemas;
25
+ this.basePath = basePath;
26
+ }
27
+ /**
28
+ * Lists all tables
29
+ */
30
+ async listTables() {
31
+ const entries = [];
32
+ const buildOptions = { basePath: this.basePath };
33
+ for (const [name, schema] of this.schemas) {
34
+ const rowCount = (await execAll(this.db, `SELECT COUNT(*) as count FROM "${name}"`))[0]?.count ?? 0;
35
+ entries.push(require_builder.buildTableEntry(name, schema, {
36
+ ...buildOptions,
37
+ rowCount
38
+ }));
39
+ }
40
+ return { data: entries };
41
+ }
42
+ /**
43
+ * Lists rows in a table
44
+ */
45
+ async listTable(table, options) {
46
+ const schema = this.schemas.get(table);
47
+ if (!schema) return {
48
+ data: [],
49
+ message: `Table '${table}' not found`
50
+ };
51
+ const buildOptions = { basePath: this.basePath };
52
+ const queryStr = require_query_builder.buildSelectAll(table, {
53
+ limit: options?.limit ?? 100,
54
+ orderBy: options?.orderBy
55
+ });
56
+ return { data: (await execAll(this.db, queryStr)).map((row) => require_builder.buildRowEntry(table, schema, row, buildOptions)) };
57
+ }
58
+ /**
59
+ * Reads a single row by primary key
60
+ */
61
+ async readRow(table, pk) {
62
+ const schema = this.schemas.get(table);
63
+ if (!schema) return { message: `Table '${table}' not found` };
64
+ const buildOptions = { basePath: this.basePath };
65
+ const row = (await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk)))[0];
66
+ if (!row) return { message: `Row with pk '${pk}' not found in table '${table}'` };
67
+ return { data: require_builder.buildRowEntry(table, schema, row, buildOptions) };
68
+ }
69
+ /**
70
+ * Gets table schema
71
+ */
72
+ getSchema(table) {
73
+ const schema = this.schemas.get(table);
74
+ if (!schema) return { message: `Table '${table}' not found` };
75
+ return { data: require_builder.buildSchemaEntry(table, schema, { basePath: this.basePath }) };
76
+ }
77
+ /**
78
+ * Lists attributes (columns) for a row
79
+ */
80
+ async listAttributes(table, pk) {
81
+ const schema = this.schemas.get(table);
82
+ if (!schema) return {
83
+ data: [],
84
+ message: `Table '${table}' not found`
85
+ };
86
+ const buildOptions = { basePath: this.basePath };
87
+ const row = (await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk)))[0];
88
+ if (!row) return {
89
+ data: [],
90
+ message: `Row with pk '${pk}' not found`
91
+ };
92
+ return { data: require_builder.buildAttributeListEntry(table, schema, pk, row, buildOptions) };
93
+ }
94
+ /**
95
+ * Gets a single attribute (column value) for a row
96
+ */
97
+ async getAttribute(table, pk, column) {
98
+ const schema = this.schemas.get(table);
99
+ if (!schema) return { message: `Table '${table}' not found` };
100
+ if (!schema.columns.find((c) => c.name === column)) return { message: `Column '${column}' not found in table '${table}'` };
101
+ const buildOptions = { basePath: this.basePath };
102
+ const rows = await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk));
103
+ if (rows.length === 0) return { message: `Row with pk '${pk}' not found` };
104
+ return { data: require_builder.buildAttributeEntry(table, pk, column, rows[0]?.[column], buildOptions) };
105
+ }
106
+ /**
107
+ * Gets row metadata
108
+ */
109
+ async getMeta(table, pk) {
110
+ const schema = this.schemas.get(table);
111
+ if (!schema) return { message: `Table '${table}' not found` };
112
+ const buildOptions = { basePath: this.basePath };
113
+ const row = (await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk)))[0];
114
+ if (!row) return { message: `Row with pk '${pk}' not found` };
115
+ return { data: require_builder.buildMetaEntry(table, schema, pk, row, buildOptions) };
116
+ }
117
+ /**
118
+ * Creates a new row in a table
119
+ */
120
+ async createRow(table, content) {
121
+ const schema = this.schemas.get(table);
122
+ if (!schema) throw new Error(`Table '${table}' not found`);
123
+ const buildOptions = { basePath: this.basePath };
124
+ await execRun(this.db, require_query_builder.buildInsert(table, schema, content));
125
+ const lastId = (await execAll(this.db, require_query_builder.buildGetLastRowId()))[0]?.id;
126
+ if (lastId === void 0) throw new Error("Failed to get last inserted row ID");
127
+ const pkColumn = schema.primaryKey[0] ?? "rowid";
128
+ const pk = content[pkColumn] !== void 0 ? String(content[pkColumn]) : String(lastId);
129
+ const row = (await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk)))[0];
130
+ if (!row) throw new Error("Failed to fetch inserted row");
131
+ return { data: require_builder.buildRowEntry(table, schema, row, buildOptions) };
132
+ }
133
+ /**
134
+ * Updates an existing row
135
+ */
136
+ async updateRow(table, pk, content) {
137
+ const schema = this.schemas.get(table);
138
+ if (!schema) throw new Error(`Table '${table}' not found`);
139
+ const buildOptions = { basePath: this.basePath };
140
+ await execRun(this.db, require_query_builder.buildUpdate(table, schema, pk, content));
141
+ const row = (await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk)))[0];
142
+ if (!row) throw new Error(`Row with pk '${pk}' not found after update`);
143
+ return { data: require_builder.buildRowEntry(table, schema, row, buildOptions) };
144
+ }
145
+ /**
146
+ * Deletes a row by primary key
147
+ */
148
+ async deleteRow(table, pk) {
149
+ const schema = this.schemas.get(table);
150
+ if (!schema) throw new Error(`Table '${table}' not found`);
151
+ if ((await execAll(this.db, require_query_builder.buildSelectByPK(table, schema, pk))).length === 0) return { message: `Row with pk '${pk}' not found in table '${table}'` };
152
+ await execRun(this.db, require_query_builder.buildDelete(table, schema, pk));
153
+ return { message: `Deleted row '${pk}' from table '${table}'` };
154
+ }
155
+ /**
156
+ * Checks if a table exists
157
+ */
158
+ hasTable(table) {
159
+ return this.schemas.has(table);
160
+ }
161
+ /**
162
+ * Gets the schema for a table
163
+ */
164
+ getTableSchema(table) {
165
+ return this.schemas.get(table);
166
+ }
167
+ /**
168
+ * Updates the schemas map (after refresh)
169
+ */
170
+ setSchemas(schemas) {
171
+ this.schemas = schemas;
172
+ }
173
+ };
174
+
175
+ //#endregion
176
+ exports.CRUDOperations = CRUDOperations;