@zauso-ai/capstan-db 0.2.0 → 0.3.0
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/client.d.ts +3 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +206 -27
- package/dist/client.js.map +1 -1
- package/dist/crud.d.ts +14 -0
- package/dist/crud.d.ts.map +1 -1
- package/dist/crud.js +49 -39
- package/dist/crud.js.map +1 -1
- package/dist/dialect.d.ts +25 -0
- package/dist/dialect.d.ts.map +1 -0
- package/dist/dialect.js +208 -0
- package/dist/dialect.js.map +1 -0
- package/dist/embedding.d.ts +63 -0
- package/dist/embedding.d.ts.map +1 -0
- package/dist/embedding.js +61 -0
- package/dist/embedding.js.map +1 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/migrate.d.ts +44 -23
- package/dist/migrate.d.ts.map +1 -1
- package/dist/migrate.js +308 -125
- package/dist/migrate.js.map +1 -1
- package/dist/model.d.ts +9 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +13 -0
- package/dist/model.js.map +1 -1
- package/dist/naming.d.ts +37 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +196 -0
- package/dist/naming.js.map +1 -0
- package/dist/runtime.d.ts +51 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +490 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schema.d.ts +2 -27
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +181 -197
- package/dist/schema.js.map +1 -1
- package/dist/search.d.ts +52 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +110 -0
- package/dist/search.js.map +1 -0
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-store-memory.d.ts +31 -0
- package/dist/vector-store-memory.d.ts.map +1 -0
- package/dist/vector-store-memory.js +125 -0
- package/dist/vector-store-memory.js.map +1 -0
- package/dist/vector-store-pgvector.d.ts +46 -0
- package/dist/vector-store-pgvector.d.ts.map +1 -0
- package/dist/vector-store-pgvector.js +215 -0
- package/dist/vector-store-pgvector.js.map +1 -0
- package/dist/vector-store-sqlite.d.ts +51 -0
- package/dist/vector-store-sqlite.d.ts.map +1 -0
- package/dist/vector-store-sqlite.js +203 -0
- package/dist/vector-store-sqlite.js.map +1 -0
- package/dist/vector-store.d.ts +79 -0
- package/dist/vector-store.d.ts.map +1 -0
- package/dist/vector-store.js +5 -0
- package/dist/vector-store.js.map +1 -0
- package/dist/write.d.ts +15 -0
- package/dist/write.d.ts.map +1 -0
- package/dist/write.js +156 -0
- package/dist/write.js.map +1 -0
- package/package.json +9 -4
package/dist/schema.js
CHANGED
|
@@ -1,228 +1,149 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
/**
|
|
5
|
-
* Convert a camelCase name to snake_case for column names.
|
|
6
|
-
*/
|
|
7
|
-
function toSnakeCase(str) {
|
|
8
|
-
return str.replace(/[A-Z]/g, (ch) => `_${ch.toLowerCase()}`);
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Pluralise a model name for the table name (very simple heuristic).
|
|
12
|
-
* "Ticket" -> "tickets", "Category" -> "categories", "Status" -> "statuses"
|
|
13
|
-
*/
|
|
14
|
-
function pluralise(name) {
|
|
15
|
-
const lower = name.charAt(0).toLowerCase() + name.slice(1);
|
|
16
|
-
if (lower.endsWith("y") && !/[aeiou]y$/i.test(lower)) {
|
|
17
|
-
return lower.slice(0, -1) + "ies";
|
|
18
|
-
}
|
|
19
|
-
if (lower.endsWith("s") || lower.endsWith("x") || lower.endsWith("sh") || lower.endsWith("ch")) {
|
|
20
|
-
return lower + "es";
|
|
21
|
-
}
|
|
22
|
-
return lower + "s";
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Escape a JavaScript string value for embedding in generated code.
|
|
26
|
-
*/
|
|
1
|
+
import { autoIdSchemaExpr, columnMapping, columnMappingForReference, providerMeta } from "./dialect.js";
|
|
2
|
+
import { findPrimaryKeyField, inferRelationForeignKey, resolveManyToManyRelation, resolveReferenceField, resolveTargetRelationForeignKey, tableNameForModel, tableVarForModel, toSnakeCase } from "./naming.js";
|
|
27
3
|
function jsString(val) {
|
|
28
4
|
if (typeof val === "string") {
|
|
29
5
|
return `"${val.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
30
6
|
}
|
|
31
7
|
return String(val);
|
|
32
8
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
case "text":
|
|
37
|
-
case "date":
|
|
38
|
-
case "datetime":
|
|
39
|
-
return { builder: "text", import: "text" };
|
|
40
|
-
case "integer":
|
|
41
|
-
return { builder: "integer", import: "integer" };
|
|
42
|
-
case "number":
|
|
43
|
-
return { builder: "real", import: "real" };
|
|
44
|
-
case "boolean":
|
|
45
|
-
return { builder: "integer", import: "integer", config: '{ mode: "boolean" }' };
|
|
46
|
-
case "json":
|
|
47
|
-
return { builder: "text", import: "text", config: '{ mode: "json" }' };
|
|
9
|
+
function runtimeTimestampExpr(field, provider) {
|
|
10
|
+
if (field.type === "date") {
|
|
11
|
+
return `new Date().toISOString().slice(0, 10)`;
|
|
48
12
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
switch (fieldType) {
|
|
52
|
-
case "string":
|
|
53
|
-
return { builder: "varchar", import: "varchar", config: "{ length: 255 }" };
|
|
54
|
-
case "text":
|
|
55
|
-
return { builder: "text", import: "text" };
|
|
56
|
-
case "date":
|
|
57
|
-
return { builder: "date", import: "date" };
|
|
58
|
-
case "datetime":
|
|
59
|
-
return { builder: "timestamp", import: "timestamp" };
|
|
60
|
-
case "integer":
|
|
61
|
-
return { builder: "integer", import: "integer" };
|
|
62
|
-
case "number":
|
|
63
|
-
return { builder: "doublePrecision", import: "doublePrecision" };
|
|
64
|
-
case "boolean":
|
|
65
|
-
return { builder: "boolean", import: "boolean" };
|
|
66
|
-
case "json":
|
|
67
|
-
return { builder: "jsonb", import: "jsonb" };
|
|
13
|
+
if (provider === "sqlite" || provider === "libsql") {
|
|
14
|
+
return `new Date().toISOString()`;
|
|
68
15
|
}
|
|
16
|
+
return `new Date()`;
|
|
69
17
|
}
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
case "string":
|
|
73
|
-
return { builder: "varchar", import: "varchar", config: "{ length: 255 }" };
|
|
74
|
-
case "text":
|
|
75
|
-
return { builder: "text", import: "text" };
|
|
76
|
-
case "date":
|
|
77
|
-
return { builder: "varchar", import: "varchar", config: "{ length: 255 }" };
|
|
78
|
-
case "datetime":
|
|
79
|
-
return { builder: "datetime", import: "datetime" };
|
|
80
|
-
case "integer":
|
|
81
|
-
return { builder: "int", import: "int" };
|
|
82
|
-
case "number":
|
|
83
|
-
return { builder: "double", import: "double" };
|
|
84
|
-
case "boolean":
|
|
85
|
-
return { builder: "boolean", import: "boolean" };
|
|
86
|
-
case "json":
|
|
87
|
-
return { builder: "json", import: "json" };
|
|
88
|
-
}
|
|
18
|
+
function indexName(tableName, fields) {
|
|
19
|
+
return `idx_${tableName}_${fields.map(toSnakeCase).join("_")}`;
|
|
89
20
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
21
|
+
function buildIndexExpr(tableName, idx, provider) {
|
|
22
|
+
const builder = idx.unique ? "uniqueIndex" : "index";
|
|
23
|
+
const columns = idx.fields.map((fieldName) => {
|
|
24
|
+
if (provider === "postgres" && idx.order) {
|
|
25
|
+
return `table.${fieldName}.${idx.order}()`;
|
|
26
|
+
}
|
|
27
|
+
return `table.${fieldName}`;
|
|
28
|
+
});
|
|
29
|
+
return `${builder}("${indexName(tableName, idx.fields)}").on(${columns.join(", ")})`;
|
|
99
30
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
31
|
+
function buildRelationExpr(sourceModel, sourceVar, relationName, relation, modelMap) {
|
|
32
|
+
const targetModel = modelMap.get(relation.model);
|
|
33
|
+
if (!targetModel)
|
|
34
|
+
return null;
|
|
35
|
+
const targetVar = tableVarForModel(targetModel);
|
|
36
|
+
switch (relation.kind) {
|
|
37
|
+
case "belongsTo": {
|
|
38
|
+
const foreignKey = inferRelationForeignKey(relation);
|
|
39
|
+
if (!(foreignKey in sourceModel.fields)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const targetField = sourceModel.fields[foreignKey]?.references
|
|
43
|
+
? resolveReferenceField(sourceModel.fields[foreignKey].references, modelMap).fieldName
|
|
44
|
+
: (findPrimaryKeyField(targetModel) ?? "id");
|
|
45
|
+
return `${relationName}: one(${targetVar}, { fields: [${sourceVar}.${foreignKey}], references: [${targetVar}.${targetField}] })`;
|
|
46
|
+
}
|
|
47
|
+
case "hasMany":
|
|
48
|
+
return `${relationName}: many(${targetVar})`;
|
|
49
|
+
case "hasOne":
|
|
50
|
+
return `${relationName}: one(${targetVar})`;
|
|
51
|
+
case "manyToMany":
|
|
52
|
+
return null;
|
|
120
53
|
}
|
|
121
54
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
case "
|
|
137
|
-
return {
|
|
138
|
-
case "
|
|
139
|
-
return {
|
|
55
|
+
function buildRelationMetadataExpr(sourceModel, relationName, relation, modelMap) {
|
|
56
|
+
const targetModel = modelMap.get(relation.model);
|
|
57
|
+
if (!targetModel && relation.kind !== "manyToMany") {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
switch (relation.kind) {
|
|
61
|
+
case "belongsTo":
|
|
62
|
+
{
|
|
63
|
+
const foreignKey = inferRelationForeignKey(relation);
|
|
64
|
+
const targetField = sourceModel.fields[foreignKey]?.references
|
|
65
|
+
? resolveReferenceField(sourceModel.fields[foreignKey].references, modelMap).fieldName
|
|
66
|
+
: (findPrimaryKeyField(targetModel) ?? "id");
|
|
67
|
+
return `${relationName}: { kind: "belongsTo", model: "${relation.model}", foreignKey: "${foreignKey}", targetKey: "${targetField}" }`;
|
|
68
|
+
}
|
|
69
|
+
case "hasMany":
|
|
70
|
+
return `${relationName}: { kind: "hasMany", model: "${relation.model}", foreignKey: "${resolveTargetRelationForeignKey(sourceModel, relation, modelMap)}", sourceKey: "${findPrimaryKeyField(sourceModel) ?? "id"}" }`;
|
|
71
|
+
case "hasOne":
|
|
72
|
+
return `${relationName}: { kind: "hasOne", model: "${relation.model}", foreignKey: "${resolveTargetRelationForeignKey(sourceModel, relation, modelMap)}", sourceKey: "${findPrimaryKeyField(sourceModel) ?? "id"}" }`;
|
|
73
|
+
case "manyToMany": {
|
|
74
|
+
const resolved = resolveManyToManyRelation(sourceModel, relation, modelMap);
|
|
75
|
+
if (!resolved) {
|
|
76
|
+
return `${relationName}: { kind: "manyToMany", model: "${relation.model}", through: ${relation.through ? `"${relation.through}"` : "null"}, resolved: false }`;
|
|
77
|
+
}
|
|
78
|
+
return `${relationName}: { kind: "manyToMany", model: "${relation.model}", through: "${resolved.throughModel.name}", throughTable: "${tableNameForModel(resolved.throughModel)}", sourceForeignKey: "${resolved.sourceForeignKey}", targetForeignKey: "${resolved.targetForeignKey}", sourceKey: "${resolved.sourcePrimaryKey}", targetKey: "${resolved.targetPrimaryKey}", resolved: true }`;
|
|
79
|
+
}
|
|
140
80
|
}
|
|
141
81
|
}
|
|
142
|
-
|
|
143
|
-
// Column expression builder
|
|
144
|
-
// ---------------------------------------------------------------------------
|
|
145
|
-
function buildColumnExpr(fieldName, def, provider) {
|
|
82
|
+
function buildColumnExpr(fieldName, def, provider, modelMap) {
|
|
146
83
|
const colName = toSnakeCase(fieldName);
|
|
147
|
-
// Auto-id fields get special treatment per provider
|
|
148
84
|
if (def.autoId) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
85
|
+
return autoIdSchemaExpr(colName, provider);
|
|
86
|
+
}
|
|
87
|
+
const referencedField = def.references
|
|
88
|
+
? (() => {
|
|
89
|
+
const target = resolveReferenceField(def.references, modelMap);
|
|
90
|
+
return modelMap.get(target.modelName)?.fields[target.fieldName];
|
|
91
|
+
})()
|
|
92
|
+
: undefined;
|
|
93
|
+
const mapping = referencedField
|
|
94
|
+
? columnMappingForReference(referencedField, provider)
|
|
95
|
+
: columnMapping(def.type, provider, def.dimensions);
|
|
96
|
+
let expr = mapping.config
|
|
97
|
+
? `${mapping.builder}("${colName}", ${mapping.config})`
|
|
98
|
+
: `${mapping.builder}("${colName}")`;
|
|
99
|
+
if (def.required || def.updatedAt) {
|
|
162
100
|
expr += ".notNull()";
|
|
163
101
|
}
|
|
164
|
-
// Unique constraint
|
|
165
102
|
if (def.unique) {
|
|
166
103
|
expr += ".unique()";
|
|
167
104
|
}
|
|
168
|
-
|
|
105
|
+
if (def.references) {
|
|
106
|
+
const target = resolveReferenceField(def.references, modelMap);
|
|
107
|
+
const targetVar = tableVarForModel(target.modelName);
|
|
108
|
+
expr += `.references(() => ${targetVar}.${target.fieldName})`;
|
|
109
|
+
}
|
|
169
110
|
let needsSql = false;
|
|
170
111
|
if (def.default !== undefined) {
|
|
171
112
|
if (def.default === "now") {
|
|
172
|
-
|
|
173
|
-
expr += `.default(sql\`${meta.nowDefault}\`)`;
|
|
113
|
+
expr += `.default(sql\`${providerMeta(provider).nowDefaultSql}\`)`;
|
|
174
114
|
needsSql = true;
|
|
175
115
|
}
|
|
176
116
|
else if (typeof def.default === "string") {
|
|
177
117
|
expr += `.default(${jsString(def.default)})`;
|
|
178
118
|
}
|
|
179
|
-
else if (typeof def.default === "boolean") {
|
|
180
|
-
expr += `.default(${def.default})`;
|
|
119
|
+
else if (typeof def.default === "boolean" || typeof def.default === "number") {
|
|
120
|
+
expr += `.default(${String(def.default)})`;
|
|
181
121
|
}
|
|
182
|
-
else if (typeof def.default === "
|
|
183
|
-
expr += `.default(${def.default})`;
|
|
122
|
+
else if (typeof def.default === "object") {
|
|
123
|
+
expr += `.default(${jsString(JSON.stringify(def.default))})`;
|
|
184
124
|
}
|
|
185
125
|
else {
|
|
186
126
|
expr += `.default(${jsString(def.default)})`;
|
|
187
127
|
}
|
|
188
128
|
}
|
|
129
|
+
if (def.updatedAt) {
|
|
130
|
+
if (def.default === undefined) {
|
|
131
|
+
expr += `.$defaultFn(() => ${runtimeTimestampExpr(def, provider)})`;
|
|
132
|
+
}
|
|
133
|
+
expr += `.$onUpdateFn(() => ${runtimeTimestampExpr(def, provider)})`;
|
|
134
|
+
}
|
|
189
135
|
return { expr, imports: [mapping.import], needsSql };
|
|
190
136
|
}
|
|
191
|
-
// ---------------------------------------------------------------------------
|
|
192
|
-
// Public API
|
|
193
|
-
// ---------------------------------------------------------------------------
|
|
194
|
-
/**
|
|
195
|
-
* Generate a Drizzle ORM schema file (as a TypeScript string) from an array
|
|
196
|
-
* of model definitions.
|
|
197
|
-
*
|
|
198
|
-
* The generated code targets the specified provider's drizzle package:
|
|
199
|
-
* - `"sqlite"` -> `drizzle-orm/sqlite-core`
|
|
200
|
-
* - `"postgres"` -> `drizzle-orm/pg-core`
|
|
201
|
-
* - `"mysql"` -> `drizzle-orm/mysql-core`
|
|
202
|
-
*
|
|
203
|
-
* @param models - Array of model definitions to generate schema for.
|
|
204
|
-
* @param provider - The database provider. Defaults to `"sqlite"` for
|
|
205
|
-
* backwards compatibility.
|
|
206
|
-
*
|
|
207
|
-
* @example
|
|
208
|
-
* const src = generateDrizzleSchema([ticketModel, userModel]);
|
|
209
|
-
* fs.writeFileSync("schema.ts", src);
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* const src = generateDrizzleSchema([ticketModel], "postgres");
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* const src = generateDrizzleSchema([ticketModel], "mysql");
|
|
216
|
-
*/
|
|
217
137
|
export function generateDrizzleSchema(models, provider = "sqlite") {
|
|
218
138
|
const meta = providerMeta(provider);
|
|
219
|
-
|
|
139
|
+
const modelMap = new Map(models.map((model) => [model.name, model]));
|
|
220
140
|
const neededImports = new Set([meta.tableBuilder]);
|
|
221
141
|
let needsSql = false;
|
|
222
|
-
|
|
142
|
+
let needsRelations = false;
|
|
143
|
+
let hasRelationComments = false;
|
|
223
144
|
for (const model of models) {
|
|
224
145
|
for (const [fieldName, def] of Object.entries(model.fields)) {
|
|
225
|
-
const result = buildColumnExpr(fieldName, def, provider);
|
|
146
|
+
const result = buildColumnExpr(fieldName, def, provider, modelMap);
|
|
226
147
|
for (const imp of result.imports) {
|
|
227
148
|
neededImports.add(imp);
|
|
228
149
|
}
|
|
@@ -230,28 +151,91 @@ export function generateDrizzleSchema(models, provider = "sqlite") {
|
|
|
230
151
|
needsSql = true;
|
|
231
152
|
}
|
|
232
153
|
}
|
|
154
|
+
if (model.indexes.length > 0) {
|
|
155
|
+
neededImports.add("index");
|
|
156
|
+
neededImports.add("uniqueIndex");
|
|
157
|
+
}
|
|
158
|
+
for (const relation of Object.values(model.relations)) {
|
|
159
|
+
if (relation.kind === "manyToMany") {
|
|
160
|
+
hasRelationComments = true;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
needsRelations = true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
233
166
|
}
|
|
234
|
-
// Build import line
|
|
235
|
-
const importNames = [...neededImports].sort();
|
|
236
167
|
const lines = [];
|
|
237
|
-
lines.push(`import { ${
|
|
238
|
-
if (needsSql) {
|
|
239
|
-
lines.push(`import { sql } from "drizzle-orm";`);
|
|
168
|
+
lines.push(`import { ${[...neededImports].sort().join(", ")} } from "${meta.importModule}";`);
|
|
169
|
+
if (needsSql || models.some((model) => Object.values(model.fields).some((field) => field.autoId))) {
|
|
170
|
+
lines.push(`import { sql${needsRelations ? ", relations" : ""} } from "drizzle-orm";`);
|
|
171
|
+
}
|
|
172
|
+
else if (needsRelations) {
|
|
173
|
+
lines.push(`import { relations } from "drizzle-orm";`);
|
|
240
174
|
}
|
|
241
|
-
// Generate each table
|
|
242
175
|
for (const model of models) {
|
|
243
|
-
const tableName =
|
|
244
|
-
const varName =
|
|
176
|
+
const tableName = tableNameForModel(model);
|
|
177
|
+
const varName = tableVarForModel(model);
|
|
245
178
|
lines.push("");
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
179
|
+
const fields = Object.entries(model.fields);
|
|
180
|
+
if (model.indexes.length > 0) {
|
|
181
|
+
lines.push(`export const ${varName} = ${meta.tableBuilder}("${tableName}", {`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
lines.push(`export const ${varName} = ${meta.tableBuilder}("${tableName}", {`);
|
|
185
|
+
}
|
|
186
|
+
for (const [fieldName, def] of fields) {
|
|
187
|
+
const result = buildColumnExpr(fieldName, def, provider, modelMap);
|
|
188
|
+
lines.push(` ${fieldName}: ${result.expr},`);
|
|
189
|
+
}
|
|
190
|
+
if (model.indexes.length === 0) {
|
|
191
|
+
lines.push("});");
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
lines.push("}, (table) => [");
|
|
195
|
+
for (const idx of model.indexes) {
|
|
196
|
+
lines.push(` ${buildIndexExpr(tableName, idx, provider)},`);
|
|
197
|
+
}
|
|
198
|
+
lines.push("]);");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (needsRelations || hasRelationComments) {
|
|
202
|
+
for (const model of models) {
|
|
203
|
+
const varName = tableVarForModel(model);
|
|
204
|
+
const relationLines = [];
|
|
205
|
+
const relationMetadataLines = [];
|
|
206
|
+
let skippedManyToMany = false;
|
|
207
|
+
for (const [relationName, relation] of Object.entries(model.relations)) {
|
|
208
|
+
const line = buildRelationExpr(model, varName, relationName, relation, modelMap);
|
|
209
|
+
if (line) {
|
|
210
|
+
relationLines.push(` ${line},`);
|
|
211
|
+
}
|
|
212
|
+
else if (relation.kind === "manyToMany") {
|
|
213
|
+
skippedManyToMany = true;
|
|
214
|
+
}
|
|
215
|
+
const metadataLine = buildRelationMetadataExpr(model, relationName, relation, modelMap);
|
|
216
|
+
if (metadataLine) {
|
|
217
|
+
relationMetadataLines.push(` ${metadataLine},`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (relationLines.length === 0 && !skippedManyToMany && relationMetadataLines.length === 0) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
lines.push("");
|
|
224
|
+
if (skippedManyToMany) {
|
|
225
|
+
lines.push(`// ${model.name}: many-to-many relations require an explicit join model and are not generated automatically.`);
|
|
226
|
+
}
|
|
227
|
+
if (relationMetadataLines.length > 0) {
|
|
228
|
+
lines.push(`export const ${varName}RelationMetadata = {`);
|
|
229
|
+
lines.push(...relationMetadataLines);
|
|
230
|
+
lines.push("} as const;");
|
|
231
|
+
lines.push("");
|
|
232
|
+
}
|
|
233
|
+
if (relationLines.length > 0) {
|
|
234
|
+
lines.push(`export const ${varName}Relations = relations(${varName}, ({ one, many }) => ({`);
|
|
235
|
+
lines.push(...relationLines);
|
|
236
|
+
lines.push("}));");
|
|
237
|
+
}
|
|
253
238
|
}
|
|
254
|
-
lines.push("});");
|
|
255
239
|
}
|
|
256
240
|
return lines.join("\n") + "\n";
|
|
257
241
|
}
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the cosine distance between two vectors.
|
|
3
|
+
*
|
|
4
|
+
* Returns a value in [0, 2] where 0 means identical direction and 2 means
|
|
5
|
+
* opposite direction. Cosine *similarity* = 1 - cosineDistance.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cosineDistance(a: number[], b: number[]): number;
|
|
8
|
+
export interface VectorItem {
|
|
9
|
+
id: string;
|
|
10
|
+
vector: number[];
|
|
11
|
+
}
|
|
12
|
+
export interface ScoredResult {
|
|
13
|
+
id: string;
|
|
14
|
+
score: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find the top-K nearest neighbours from an array of vectors using cosine
|
|
18
|
+
* similarity (higher score = more similar).
|
|
19
|
+
*
|
|
20
|
+
* This is a brute-force scan suitable for small-to-medium datasets that fit
|
|
21
|
+
* in memory. For larger workloads, use a dedicated vector index (pgvector,
|
|
22
|
+
* Qdrant, etc.).
|
|
23
|
+
*
|
|
24
|
+
* @returns Items sorted by descending similarity score.
|
|
25
|
+
*/
|
|
26
|
+
export declare function findNearest(query: number[], items: VectorItem[], k: number): ScoredResult[];
|
|
27
|
+
export interface HybridItem {
|
|
28
|
+
id: string;
|
|
29
|
+
text: string;
|
|
30
|
+
vector: number[];
|
|
31
|
+
}
|
|
32
|
+
export interface HybridSearchOptions {
|
|
33
|
+
/** Number of results to return. @default 10 */
|
|
34
|
+
k?: number;
|
|
35
|
+
/** Weight for the keyword component (0-1). @default 0.3 */
|
|
36
|
+
keywordWeight?: number;
|
|
37
|
+
/** Weight for the vector component (0-1). @default 0.7 */
|
|
38
|
+
vectorWeight?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Hybrid search combining BM25-style keyword matching with vector cosine
|
|
42
|
+
* similarity.
|
|
43
|
+
*
|
|
44
|
+
* The keyword score is a simple normalised term-frequency overlap (not a
|
|
45
|
+
* full BM25 implementation) which is sufficient for re-ranking a
|
|
46
|
+
* pre-filtered candidate set. For production-grade keyword search, pair
|
|
47
|
+
* with a proper full-text index.
|
|
48
|
+
*
|
|
49
|
+
* @returns Items sorted by descending combined score.
|
|
50
|
+
*/
|
|
51
|
+
export declare function hybridSearch(query: string, queryVector: number[], items: HybridItem[], opts?: HybridSearchOptions): ScoredResult[];
|
|
52
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAwB/D;AAMD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,UAAU,EAAE,EACnB,CAAC,EAAE,MAAM,GACR,YAAY,EAAE,CAQhB;AAMD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EAAE,EACrB,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,CAAC,EAAE,mBAAmB,GACzB,YAAY,EAAE,CA6BhB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Vector similarity search utilities
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Compute the cosine distance between two vectors.
|
|
6
|
+
*
|
|
7
|
+
* Returns a value in [0, 2] where 0 means identical direction and 2 means
|
|
8
|
+
* opposite direction. Cosine *similarity* = 1 - cosineDistance.
|
|
9
|
+
*/
|
|
10
|
+
export function cosineDistance(a, b) {
|
|
11
|
+
if (a.length !== b.length) {
|
|
12
|
+
throw new Error(`Vector length mismatch: ${a.length} vs ${b.length}`);
|
|
13
|
+
}
|
|
14
|
+
let dot = 0;
|
|
15
|
+
let normA = 0;
|
|
16
|
+
let normB = 0;
|
|
17
|
+
for (let i = 0; i < a.length; i++) {
|
|
18
|
+
const ai = a[i];
|
|
19
|
+
const bi = b[i];
|
|
20
|
+
dot += ai * bi;
|
|
21
|
+
normA += ai * ai;
|
|
22
|
+
normB += bi * bi;
|
|
23
|
+
}
|
|
24
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
25
|
+
if (denom === 0)
|
|
26
|
+
return 1; // zero-vector edge case
|
|
27
|
+
const similarity = dot / denom;
|
|
28
|
+
return 1 - similarity;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Find the top-K nearest neighbours from an array of vectors using cosine
|
|
32
|
+
* similarity (higher score = more similar).
|
|
33
|
+
*
|
|
34
|
+
* This is a brute-force scan suitable for small-to-medium datasets that fit
|
|
35
|
+
* in memory. For larger workloads, use a dedicated vector index (pgvector,
|
|
36
|
+
* Qdrant, etc.).
|
|
37
|
+
*
|
|
38
|
+
* @returns Items sorted by descending similarity score.
|
|
39
|
+
*/
|
|
40
|
+
export function findNearest(query, items, k) {
|
|
41
|
+
const scored = items.map((item) => ({
|
|
42
|
+
id: item.id,
|
|
43
|
+
score: 1 - cosineDistance(query, item.vector),
|
|
44
|
+
}));
|
|
45
|
+
scored.sort((a, b) => b.score - a.score);
|
|
46
|
+
return scored.slice(0, k);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Hybrid search combining BM25-style keyword matching with vector cosine
|
|
50
|
+
* similarity.
|
|
51
|
+
*
|
|
52
|
+
* The keyword score is a simple normalised term-frequency overlap (not a
|
|
53
|
+
* full BM25 implementation) which is sufficient for re-ranking a
|
|
54
|
+
* pre-filtered candidate set. For production-grade keyword search, pair
|
|
55
|
+
* with a proper full-text index.
|
|
56
|
+
*
|
|
57
|
+
* @returns Items sorted by descending combined score.
|
|
58
|
+
*/
|
|
59
|
+
export function hybridSearch(query, queryVector, items, opts) {
|
|
60
|
+
const k = opts?.k ?? 10;
|
|
61
|
+
const keywordWeight = opts?.keywordWeight ?? 0.3;
|
|
62
|
+
const vectorWeight = opts?.vectorWeight ?? 0.7;
|
|
63
|
+
// Tokenise the query into lower-case terms.
|
|
64
|
+
const queryTerms = tokenize(query);
|
|
65
|
+
if (queryTerms.length === 0 && queryVector.length === 0) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
// Score each item.
|
|
69
|
+
const scored = items.map((item) => {
|
|
70
|
+
const vectorScore = queryVector.length > 0
|
|
71
|
+
? 1 - cosineDistance(queryVector, item.vector)
|
|
72
|
+
: 0;
|
|
73
|
+
const keywordScore = queryTerms.length > 0 ? keywordOverlap(queryTerms, item.text) : 0;
|
|
74
|
+
return {
|
|
75
|
+
id: item.id,
|
|
76
|
+
score: vectorWeight * vectorScore + keywordWeight * keywordScore,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
scored.sort((a, b) => b.score - a.score);
|
|
80
|
+
return scored.slice(0, k);
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Internal helpers
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
/** Simple whitespace tokeniser with lower-casing and deduplication. */
|
|
86
|
+
function tokenize(text) {
|
|
87
|
+
return [
|
|
88
|
+
...new Set(text
|
|
89
|
+
.toLowerCase()
|
|
90
|
+
.split(/\W+/)
|
|
91
|
+
.filter((t) => t.length > 0)),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Normalised keyword overlap score in [0, 1].
|
|
96
|
+
*
|
|
97
|
+
* Counts how many query terms appear in the document text, divided by the
|
|
98
|
+
* number of query terms.
|
|
99
|
+
*/
|
|
100
|
+
function keywordOverlap(queryTerms, text) {
|
|
101
|
+
const docTokens = new Set(tokenize(text));
|
|
102
|
+
let hits = 0;
|
|
103
|
+
for (const term of queryTerms) {
|
|
104
|
+
if (docTokens.has(term)) {
|
|
105
|
+
hits++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return hits / queryTerms.length;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=search.js.map
|