@elqnt/kg 2.1.1 → 3.0.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/README.md +357 -39
- package/dist/api/index.d.mts +250 -3
- package/dist/api/index.d.ts +250 -3
- package/dist/api/index.js +2 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +1 -1
- package/dist/api/server.d.mts +219 -0
- package/dist/api/server.d.ts +219 -0
- package/dist/api/server.js +442 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/server.mjs +442 -0
- package/dist/api/server.mjs.map +1 -0
- package/dist/{chunk-4XIW5GLO.js → chunk-2TJCYLTP.js} +63 -68
- package/dist/chunk-2TJCYLTP.js.map +1 -0
- package/dist/chunk-67SUELDR.js.map +1 -1
- package/dist/chunk-7RW5MHP5.js +497 -0
- package/dist/chunk-7RW5MHP5.js.map +1 -0
- package/dist/chunk-ADIKUMMI.js +238 -0
- package/dist/chunk-ADIKUMMI.js.map +1 -0
- package/dist/chunk-CAXPQTKI.mjs +238 -0
- package/dist/chunk-CAXPQTKI.mjs.map +1 -0
- package/dist/{chunk-3AS6C7FW.mjs → chunk-HCDFJCQL.mjs} +62 -67
- package/dist/chunk-HCDFJCQL.mjs.map +1 -0
- package/dist/chunk-JZ7UXVRW.mjs +497 -0
- package/dist/chunk-JZ7UXVRW.mjs.map +1 -0
- package/dist/chunk-UCKE66GB.js.map +1 -1
- package/dist/chunk-W4XVBGE7.js.map +1 -1
- package/dist/hooks/index.d.mts +109 -4
- package/dist/hooks/index.d.ts +109 -4
- package/dist/hooks/index.js +9 -3
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +10 -4
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -4
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/kg-designer.js.map +1 -1
- package/dist/models/kg.js.map +1 -1
- package/dist/utils/index.d.mts +277 -0
- package/dist/utils/index.d.ts +277 -0
- package/dist/utils/index.js +44 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +44 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +24 -16
- package/dist/chunk-3AS6C7FW.mjs.map +0 -1
- package/dist/chunk-4XIW5GLO.js.map +0 -1
- package/dist/chunk-7HNJUCVW.js +0 -577
- package/dist/chunk-7HNJUCVW.js.map +0 -1
- package/dist/chunk-EW3NQGUZ.mjs +0 -577
- package/dist/chunk-EW3NQGUZ.mjs.map +0 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;"use client";
|
|
2
|
+
|
|
3
|
+
// utils/query-builder.ts
|
|
4
|
+
var KGQueryBuilder = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this); }
|
|
5
|
+
__init() {this._label = ""}
|
|
6
|
+
__init2() {this._fields = []}
|
|
7
|
+
__init3() {this._edges = []}
|
|
8
|
+
__init4() {this._limit = 100}
|
|
9
|
+
__init5() {this._depth = 1}
|
|
10
|
+
__init6() {this._offset = 0}
|
|
11
|
+
__init7() {this._sortBy = ""}
|
|
12
|
+
__init8() {this._sortOrder = ""}
|
|
13
|
+
|
|
14
|
+
__init9() {this._skipEmbedding = false}
|
|
15
|
+
__init10() {this._summaryOnly = false}
|
|
16
|
+
/**
|
|
17
|
+
* Set the node label to query
|
|
18
|
+
*
|
|
19
|
+
* @param label - The node label (e.g., "Person", "Product")
|
|
20
|
+
*/
|
|
21
|
+
label(label) {
|
|
22
|
+
this._label = label;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Add a field filter to the query
|
|
27
|
+
*
|
|
28
|
+
* @param name - Field name
|
|
29
|
+
* @param operator - Comparison operator (eq, neq, gt, lt, gte, lte, like, similar, in, arrayContains)
|
|
30
|
+
* @param value - Value to compare against
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* builder.field("age", "gt", 21);
|
|
35
|
+
* builder.field("status", "in", ["active", "pending"]);
|
|
36
|
+
* builder.field("name", "like", "John%");
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
field(name, operator, value) {
|
|
40
|
+
this._fields.push({ name, operator, value });
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Add an equality field filter (shorthand for field(name, "eq", value))
|
|
45
|
+
*
|
|
46
|
+
* @param name - Field name
|
|
47
|
+
* @param value - Value to match
|
|
48
|
+
*/
|
|
49
|
+
where(name, value) {
|
|
50
|
+
return this.field(name, "eq", value);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Add multiple equality filters at once
|
|
54
|
+
*
|
|
55
|
+
* @param fields - Object with field names as keys and values to match
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* builder.whereAll({ status: "active", type: "premium" });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
whereAll(fields) {
|
|
63
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
64
|
+
this.where(name, value);
|
|
65
|
+
}
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Add an edge traversal to the query
|
|
70
|
+
*
|
|
71
|
+
* @param label - Edge label (e.g., "WORKS_AT", "REPORTS_TO")
|
|
72
|
+
* @param direction - Traversal direction ("incoming" or "outgoing")
|
|
73
|
+
* @param toLabel - Target node label (optional)
|
|
74
|
+
* @param options - Additional edge query options
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* builder.edge("WORKS_AT", "outgoing", "Company");
|
|
79
|
+
* builder.edge("REPORTS_TO", "incoming", "Person", {
|
|
80
|
+
* toFieldKey: "id",
|
|
81
|
+
* toFieldValue: "manager-123"
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
edge(label, direction, toLabel = "", options = {}) {
|
|
86
|
+
this._edges.push({
|
|
87
|
+
label,
|
|
88
|
+
direction,
|
|
89
|
+
toLabel,
|
|
90
|
+
toFieldKey: options.toFieldKey || "",
|
|
91
|
+
toFieldValue: options.toFieldValue,
|
|
92
|
+
fields: options.fields
|
|
93
|
+
});
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add an outgoing edge traversal
|
|
98
|
+
*
|
|
99
|
+
* @param label - Edge label
|
|
100
|
+
* @param toLabel - Target node label
|
|
101
|
+
*/
|
|
102
|
+
outgoing(label, toLabel = "") {
|
|
103
|
+
return this.edge(label, "outgoing", toLabel);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Add an incoming edge traversal
|
|
107
|
+
*
|
|
108
|
+
* @param label - Edge label
|
|
109
|
+
* @param toLabel - Source node label
|
|
110
|
+
*/
|
|
111
|
+
incoming(label, toLabel = "") {
|
|
112
|
+
return this.edge(label, "incoming", toLabel);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set the maximum number of results
|
|
116
|
+
*
|
|
117
|
+
* @param n - Maximum number of results (default: 100)
|
|
118
|
+
*/
|
|
119
|
+
limit(n) {
|
|
120
|
+
this._limit = n;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Set the traversal depth
|
|
125
|
+
*
|
|
126
|
+
* @param n - Depth of edge traversal (default: 1)
|
|
127
|
+
*/
|
|
128
|
+
depth(n) {
|
|
129
|
+
this._depth = n;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Set the result offset for pagination
|
|
134
|
+
*
|
|
135
|
+
* @param n - Number of results to skip
|
|
136
|
+
*/
|
|
137
|
+
offset(n) {
|
|
138
|
+
this._offset = n;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Set the sort field and order
|
|
143
|
+
*
|
|
144
|
+
* @param field - Field name to sort by
|
|
145
|
+
* @param order - Sort order ("asc" or "desc")
|
|
146
|
+
*/
|
|
147
|
+
sortBy(field, order = "asc") {
|
|
148
|
+
this._sortBy = field;
|
|
149
|
+
this._sortOrder = order;
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set the embeddings source for similarity search
|
|
154
|
+
*
|
|
155
|
+
* @param source - Embeddings source identifier
|
|
156
|
+
*/
|
|
157
|
+
embeddingsSource(source) {
|
|
158
|
+
this._embeddingsSource = source;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Skip embedding generation for this query
|
|
163
|
+
*/
|
|
164
|
+
skipEmbedding() {
|
|
165
|
+
this._skipEmbedding = true;
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Return only summary fields (excludes heavy fields like text, embeddings)
|
|
170
|
+
*/
|
|
171
|
+
summaryOnly() {
|
|
172
|
+
this._summaryOnly = true;
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Build the final KGQuery object
|
|
177
|
+
*
|
|
178
|
+
* @returns The constructed KGQuery
|
|
179
|
+
* @throws Error if no label is set
|
|
180
|
+
*/
|
|
181
|
+
build() {
|
|
182
|
+
if (!this._label) {
|
|
183
|
+
throw new Error("KGQueryBuilder: label is required");
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
label: this._label,
|
|
187
|
+
fields: this._fields,
|
|
188
|
+
edges: this._edges.length > 0 ? this._edges : void 0,
|
|
189
|
+
limit: this._limit,
|
|
190
|
+
depth: this._depth,
|
|
191
|
+
sortBy: this._sortBy,
|
|
192
|
+
sortOrder: this._sortOrder,
|
|
193
|
+
embeddingsSource: this._embeddingsSource,
|
|
194
|
+
skipEmbedding: this._skipEmbedding || void 0,
|
|
195
|
+
summaryOnly: this._summaryOnly || void 0
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}, _class);
|
|
199
|
+
function createNodeQuery(label, fields, options) {
|
|
200
|
+
const builder = new KGQueryBuilder().label(label);
|
|
201
|
+
if (fields) {
|
|
202
|
+
builder.whereAll(fields);
|
|
203
|
+
}
|
|
204
|
+
if (_optionalChain([options, 'optionalAccess', _ => _.limit]) !== void 0) builder.limit(options.limit);
|
|
205
|
+
if (_optionalChain([options, 'optionalAccess', _2 => _2.depth]) !== void 0) builder.depth(options.depth);
|
|
206
|
+
if (_optionalChain([options, 'optionalAccess', _3 => _3.sortBy])) builder.sortBy(options.sortBy, options.sortOrder);
|
|
207
|
+
if (_optionalChain([options, 'optionalAccess', _4 => _4.summaryOnly])) builder.summaryOnly();
|
|
208
|
+
return builder.build();
|
|
209
|
+
}
|
|
210
|
+
function createEdgeQuery(label, direction = "outgoing", options) {
|
|
211
|
+
return {
|
|
212
|
+
label,
|
|
213
|
+
direction,
|
|
214
|
+
toLabel: _optionalChain([options, 'optionalAccess', _5 => _5.toLabel]) || "",
|
|
215
|
+
toFieldKey: _optionalChain([options, 'optionalAccess', _6 => _6.toFieldKey]) || "",
|
|
216
|
+
toFieldValue: _optionalChain([options, 'optionalAccess', _7 => _7.toFieldValue]),
|
|
217
|
+
fields: _optionalChain([options, 'optionalAccess', _8 => _8.fields])
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function createFieldQuery(name, operator, value) {
|
|
221
|
+
return { name, operator, value };
|
|
222
|
+
}
|
|
223
|
+
function createSimilarityQuery(label, searchText, options) {
|
|
224
|
+
const builder = new KGQueryBuilder().label(label).field("_search", "similar", searchText);
|
|
225
|
+
if (_optionalChain([options, 'optionalAccess', _9 => _9.embeddingsSource])) builder.embeddingsSource(options.embeddingsSource);
|
|
226
|
+
if (_optionalChain([options, 'optionalAccess', _10 => _10.limit]) !== void 0) builder.limit(options.limit);
|
|
227
|
+
if (_optionalChain([options, 'optionalAccess', _11 => _11.summaryOnly])) builder.summaryOnly();
|
|
228
|
+
return builder.build();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
exports.KGQueryBuilder = KGQueryBuilder; exports.createNodeQuery = createNodeQuery; exports.createEdgeQuery = createEdgeQuery; exports.createFieldQuery = createFieldQuery; exports.createSimilarityQuery = createSimilarityQuery;
|
|
238
|
+
//# sourceMappingURL=chunk-ADIKUMMI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eloquent-packages/eloquent-packages/packages/kg/dist/chunk-ADIKUMMI.js","../utils/query-builder.ts"],"names":[],"mappings":"AAAA,qmBAAY;AACZ;AACA;ACoEO,IAAM,eAAA,YAAN,MAAqB;AAAA,iBAClB,OAAA,EAAiB,GAAA;AAAA,kBACjB,QAAA,EAA0B,CAAC,EAAA;AAAA,kBAC3B,OAAA,EAAwB,CAAC,EAAA;AAAA,kBACzB,OAAA,EAAiB,IAAA;AAAA,kBACjB,OAAA,EAAiB,EAAA;AAAA,kBACjB,QAAA,EAAkB,EAAA;AAAA,kBAClB,QAAA,EAAkB,GAAA;AAAA,kBAClB,WAAA,EAAqB,GAAA;AAAA,EACrB;AAAA,kBACA,eAAA,EAA0B,MAAA;AAAA,mBAC1B,aAAA,EAAwB,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhC,KAAA,CAAM,KAAA,EAAqB;AACzB,IAAA,IAAA,CAAK,OAAA,EAAS,KAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,KAAA,CAAM,IAAA,EAAc,QAAA,EAAgC,KAAA,EAAsB;AACxE,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,CAAC,CAAA;AAC3C,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAA,CAAM,IAAA,EAAc,KAAA,EAAsB;AACxC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,QAAA,CAAS,MAAA,EAAuC;AAC9C,IAAA,IAAA,CAAA,MAAW,CAAC,IAAA,EAAM,KAAK,EAAA,GAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,MAAA,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,KAAK,CAAA;AAAA,IACxB;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,IAAA,CACE,KAAA,EACA,SAAA,EACA,QAAA,EAAkB,EAAA,EAClB,QAAA,EAII,CAAC,CAAA,EACC;AACN,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK;AAAA,MACf,KAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA,EAAY,OAAA,CAAQ,WAAA,GAAc,EAAA;AAAA,MAClC,YAAA,EAAc,OAAA,CAAQ,YAAA;AAAA,MACtB,MAAA,EAAQ,OAAA,CAAQ;AAAA,IAClB,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAA,CAAS,KAAA,EAAe,QAAA,EAAkB,EAAA,EAAU;AAClD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO,UAAA,EAAY,OAAO,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAA,CAAS,KAAA,EAAe,QAAA,EAAkB,EAAA,EAAU;AAClD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO,UAAA,EAAY,OAAO,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAA,CAAM,CAAA,EAAiB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAS,CAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAA,CAAM,CAAA,EAAiB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAS,CAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAA,CAAO,CAAA,EAAiB;AACtB,IAAA,IAAA,CAAK,QAAA,EAAU,CAAA;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAA,CAAO,KAAA,EAAe,MAAA,EAAwB,KAAA,EAAa;AACzD,IAAA,IAAA,CAAK,QAAA,EAAU,KAAA;AACf,IAAA,IAAA,CAAK,WAAA,EAAa,KAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAA,CAAiB,MAAA,EAAsB;AACrC,IAAA,IAAA,CAAK,kBAAA,EAAoB,MAAA;AACzB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CAAA,EAAsB;AACpB,IAAA,IAAA,CAAK,eAAA,EAAiB,IAAA;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,CAAA,EAAoB;AAClB,IAAA,IAAA,CAAK,aAAA,EAAe,IAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAA,CAAA,EAAiB;AACf,IAAA,GAAA,CAAI,CAAC,IAAA,CAAK,MAAA,EAAQ;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,mCAAmC,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA,CAAK,MAAA;AAAA,MACZ,MAAA,EAAQ,IAAA,CAAK,OAAA;AAAA,MACb,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,EAAA,EAAI,IAAA,CAAK,OAAA,EAAS,KAAA,CAAA;AAAA,MAC9C,KAAA,EAAO,IAAA,CAAK,MAAA;AAAA,MACZ,KAAA,EAAO,IAAA,CAAK,MAAA;AAAA,MACZ,MAAA,EAAQ,IAAA,CAAK,OAAA;AAAA,MACb,SAAA,EAAW,IAAA,CAAK,UAAA;AAAA,MAChB,gBAAA,EAAkB,IAAA,CAAK,iBAAA;AAAA,MACvB,aAAA,EAAe,IAAA,CAAK,eAAA,GAAkB,KAAA,CAAA;AAAA,MACtC,WAAA,EAAa,IAAA,CAAK,aAAA,GAAgB,KAAA;AAAA,IACpC,CAAA;AAAA,EACF;AACF,UAAA;AA8BO,SAAS,eAAA,CACd,KAAA,EACA,MAAA,EACA,OAAA,EAOS;AACT,EAAA,MAAM,QAAA,EAAU,IAAI,cAAA,CAAe,CAAA,CAAE,KAAA,CAAM,KAAK,CAAA;AAEhD,EAAA,GAAA,CAAI,MAAA,EAAQ;AACV,IAAA,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA;AAAA,EACzB;AAEA,EAAA,GAAA,iBAAI,OAAA,2BAAS,QAAA,IAAU,KAAA,CAAA,EAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAC7D,EAAA,GAAA,iBAAI,OAAA,6BAAS,QAAA,IAAU,KAAA,CAAA,EAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAC7D,EAAA,GAAA,iBAAI,OAAA,6BAAS,QAAA,EAAQ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,SAAS,CAAA;AACrE,EAAA,GAAA,iBAAI,OAAA,6BAAS,aAAA,EAAa,OAAA,CAAQ,WAAA,CAAY,CAAA;AAE9C,EAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA;AACvB;AAmBO,SAAS,eAAA,CACd,KAAA,EACA,UAAA,EAAqC,UAAA,EACrC,OAAA,EAMa;AACb,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA,kBAAS,OAAA,6BAAS,UAAA,GAAW,EAAA;AAAA,IAC7B,UAAA,kBAAY,OAAA,6BAAS,aAAA,GAAc,EAAA;AAAA,IACnC,YAAA,kBAAc,OAAA,6BAAS,cAAA;AAAA,IACvB,MAAA,kBAAQ,OAAA,6BAAS;AAAA,EACnB,CAAA;AACF;AAgBO,SAAS,gBAAA,CACd,IAAA,EACA,QAAA,EACA,KAAA,EACc;AACd,EAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AACjC;AAmBO,SAAS,qBAAA,CACd,KAAA,EACA,UAAA,EACA,OAAA,EAKS;AACT,EAAA,MAAM,QAAA,EAAU,IAAI,cAAA,CAAe,CAAA,CAChC,KAAA,CAAM,KAAK,CAAA,CACX,KAAA,CAAM,SAAA,EAAW,SAAA,EAAW,UAAU,CAAA;AAEzC,EAAA,GAAA,iBAAI,OAAA,6BAAS,kBAAA,EAAkB,OAAA,CAAQ,gBAAA,CAAiB,OAAA,CAAQ,gBAAgB,CAAA;AAChF,EAAA,GAAA,iBAAI,OAAA,+BAAS,QAAA,IAAU,KAAA,CAAA,EAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAC7D,EAAA,GAAA,iBAAI,OAAA,+BAAS,aAAA,EAAa,OAAA,CAAQ,WAAA,CAAY,CAAA;AAE9C,EAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA;AACvB;ADjNA;AACA;AACE;AACA;AACA;AACA;AACA;AACF,kOAAC","file":"/home/runner/work/eloquent-packages/eloquent-packages/packages/kg/dist/chunk-ADIKUMMI.js","sourcesContent":[null,"/**\n * Knowledge Graph Query Builder\n *\n * Fluent API for building KGQuery objects programmatically.\n *\n * @example\n * ```ts\n * import { KGQueryBuilder, createNodeQuery } from \"@elqnt/kg/utils\";\n *\n * // Using the builder\n * const query = new KGQueryBuilder()\n * .label(\"Person\")\n * .field(\"age\", \"gt\", 21)\n * .field(\"status\", \"eq\", \"active\")\n * .edge(\"WORKS_AT\", \"outgoing\", \"Company\")\n * .limit(50)\n * .sortBy(\"name\", \"asc\")\n * .build();\n *\n * // Using helper functions\n * const simpleQuery = createNodeQuery(\"Product\", { category: \"electronics\" });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type {\n KGQuery,\n KGFieldQuery,\n KGFieldQueryOperator,\n KGEdgeQuery,\n KGRelationshipDirection,\n} from \"../models\";\n\n// Re-export operator and direction constants for convenience\nexport {\n KGFieldQueryOperatorEqual,\n KGFieldQueryOperatorNotEqual,\n KGFieldQueryOperatorGreater,\n KGFieldQueryOperatorLess,\n KGFieldQueryOperatorGreaterOrEqual,\n KGFieldQueryOperatorLessOrEqual,\n KGFieldQueryOperatorLike,\n KGFieldQueryOperatorSimilar,\n KGFieldQueryOperatorIn,\n KGFieldQueryOperatorArrayContains,\n KGRelationshipDirectionIncoming,\n KGRelationshipDirectionOutgoing,\n} from \"../models\";\n\n/**\n * Fluent builder for KGQuery objects\n *\n * Provides a chainable API for constructing knowledge graph queries.\n * All methods return `this` to allow chaining.\n *\n * @example\n * ```ts\n * const query = new KGQueryBuilder()\n * .label(\"Person\")\n * .field(\"age\", \"gt\", 21)\n * .field(\"department\", \"eq\", \"Engineering\")\n * .edge(\"REPORTS_TO\", \"outgoing\", \"Person\")\n * .limit(100)\n * .offset(0)\n * .sortBy(\"name\", \"asc\")\n * .summaryOnly()\n * .build();\n * ```\n */\nexport class KGQueryBuilder {\n private _label: string = \"\";\n private _fields: KGFieldQuery[] = [];\n private _edges: KGEdgeQuery[] = [];\n private _limit: number = 100;\n private _depth: number = 1;\n private _offset: number = 0;\n private _sortBy: string = \"\";\n private _sortOrder: string = \"\";\n private _embeddingsSource?: string;\n private _skipEmbedding: boolean = false;\n private _summaryOnly: boolean = false;\n\n /**\n * Set the node label to query\n *\n * @param label - The node label (e.g., \"Person\", \"Product\")\n */\n label(label: string): this {\n this._label = label;\n return this;\n }\n\n /**\n * Add a field filter to the query\n *\n * @param name - Field name\n * @param operator - Comparison operator (eq, neq, gt, lt, gte, lte, like, similar, in, arrayContains)\n * @param value - Value to compare against\n *\n * @example\n * ```ts\n * builder.field(\"age\", \"gt\", 21);\n * builder.field(\"status\", \"in\", [\"active\", \"pending\"]);\n * builder.field(\"name\", \"like\", \"John%\");\n * ```\n */\n field(name: string, operator: KGFieldQueryOperator, value: unknown): this {\n this._fields.push({ name, operator, value });\n return this;\n }\n\n /**\n * Add an equality field filter (shorthand for field(name, \"eq\", value))\n *\n * @param name - Field name\n * @param value - Value to match\n */\n where(name: string, value: unknown): this {\n return this.field(name, \"eq\", value);\n }\n\n /**\n * Add multiple equality filters at once\n *\n * @param fields - Object with field names as keys and values to match\n *\n * @example\n * ```ts\n * builder.whereAll({ status: \"active\", type: \"premium\" });\n * ```\n */\n whereAll(fields: Record<string, unknown>): this {\n for (const [name, value] of Object.entries(fields)) {\n this.where(name, value);\n }\n return this;\n }\n\n /**\n * Add an edge traversal to the query\n *\n * @param label - Edge label (e.g., \"WORKS_AT\", \"REPORTS_TO\")\n * @param direction - Traversal direction (\"incoming\" or \"outgoing\")\n * @param toLabel - Target node label (optional)\n * @param options - Additional edge query options\n *\n * @example\n * ```ts\n * builder.edge(\"WORKS_AT\", \"outgoing\", \"Company\");\n * builder.edge(\"REPORTS_TO\", \"incoming\", \"Person\", {\n * toFieldKey: \"id\",\n * toFieldValue: \"manager-123\"\n * });\n * ```\n */\n edge(\n label: string,\n direction: \"incoming\" | \"outgoing\",\n toLabel: string = \"\",\n options: {\n toFieldKey?: string;\n toFieldValue?: unknown;\n fields?: Record<string, unknown>;\n } = {}\n ): this {\n this._edges.push({\n label,\n direction,\n toLabel,\n toFieldKey: options.toFieldKey || \"\",\n toFieldValue: options.toFieldValue,\n fields: options.fields,\n });\n return this;\n }\n\n /**\n * Add an outgoing edge traversal\n *\n * @param label - Edge label\n * @param toLabel - Target node label\n */\n outgoing(label: string, toLabel: string = \"\"): this {\n return this.edge(label, \"outgoing\", toLabel);\n }\n\n /**\n * Add an incoming edge traversal\n *\n * @param label - Edge label\n * @param toLabel - Source node label\n */\n incoming(label: string, toLabel: string = \"\"): this {\n return this.edge(label, \"incoming\", toLabel);\n }\n\n /**\n * Set the maximum number of results\n *\n * @param n - Maximum number of results (default: 100)\n */\n limit(n: number): this {\n this._limit = n;\n return this;\n }\n\n /**\n * Set the traversal depth\n *\n * @param n - Depth of edge traversal (default: 1)\n */\n depth(n: number): this {\n this._depth = n;\n return this;\n }\n\n /**\n * Set the result offset for pagination\n *\n * @param n - Number of results to skip\n */\n offset(n: number): this {\n this._offset = n;\n return this;\n }\n\n /**\n * Set the sort field and order\n *\n * @param field - Field name to sort by\n * @param order - Sort order (\"asc\" or \"desc\")\n */\n sortBy(field: string, order: \"asc\" | \"desc\" = \"asc\"): this {\n this._sortBy = field;\n this._sortOrder = order;\n return this;\n }\n\n /**\n * Set the embeddings source for similarity search\n *\n * @param source - Embeddings source identifier\n */\n embeddingsSource(source: string): this {\n this._embeddingsSource = source;\n return this;\n }\n\n /**\n * Skip embedding generation for this query\n */\n skipEmbedding(): this {\n this._skipEmbedding = true;\n return this;\n }\n\n /**\n * Return only summary fields (excludes heavy fields like text, embeddings)\n */\n summaryOnly(): this {\n this._summaryOnly = true;\n return this;\n }\n\n /**\n * Build the final KGQuery object\n *\n * @returns The constructed KGQuery\n * @throws Error if no label is set\n */\n build(): KGQuery {\n if (!this._label) {\n throw new Error(\"KGQueryBuilder: label is required\");\n }\n\n return {\n label: this._label,\n fields: this._fields,\n edges: this._edges.length > 0 ? this._edges : undefined,\n limit: this._limit,\n depth: this._depth,\n sortBy: this._sortBy,\n sortOrder: this._sortOrder,\n embeddingsSource: this._embeddingsSource,\n skipEmbedding: this._skipEmbedding || undefined,\n summaryOnly: this._summaryOnly || undefined,\n };\n }\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Create a simple node query with equality filters\n *\n * @param label - Node label to query\n * @param fields - Optional field equality filters\n * @param options - Additional query options\n * @returns KGQuery object\n *\n * @example\n * ```ts\n * // Query all Person nodes\n * const allPeople = createNodeQuery(\"Person\");\n *\n * // Query with filters\n * const activeUsers = createNodeQuery(\"User\", { status: \"active\", role: \"admin\" });\n *\n * // With options\n * const recentProducts = createNodeQuery(\n * \"Product\",\n * { inStock: true },\n * { limit: 10, sortBy: \"createdAt\", sortOrder: \"desc\" }\n * );\n * ```\n */\nexport function createNodeQuery(\n label: string,\n fields?: Record<string, unknown>,\n options?: {\n limit?: number;\n depth?: number;\n sortBy?: string;\n sortOrder?: \"asc\" | \"desc\";\n summaryOnly?: boolean;\n }\n): KGQuery {\n const builder = new KGQueryBuilder().label(label);\n\n if (fields) {\n builder.whereAll(fields);\n }\n\n if (options?.limit !== undefined) builder.limit(options.limit);\n if (options?.depth !== undefined) builder.depth(options.depth);\n if (options?.sortBy) builder.sortBy(options.sortBy, options.sortOrder);\n if (options?.summaryOnly) builder.summaryOnly();\n\n return builder.build();\n}\n\n/**\n * Create an edge query object\n *\n * @param label - Edge label\n * @param direction - Traversal direction\n * @param options - Additional edge options\n * @returns KGEdgeQuery object\n *\n * @example\n * ```ts\n * const worksAtEdge = createEdgeQuery(\"WORKS_AT\", \"outgoing\", {\n * toLabel: \"Company\",\n * toFieldKey: \"name\",\n * toFieldValue: \"Acme Corp\"\n * });\n * ```\n */\nexport function createEdgeQuery(\n label: string,\n direction: \"incoming\" | \"outgoing\" = \"outgoing\",\n options?: {\n toLabel?: string;\n toFieldKey?: string;\n toFieldValue?: unknown;\n fields?: Record<string, unknown>;\n }\n): KGEdgeQuery {\n return {\n label,\n direction,\n toLabel: options?.toLabel || \"\",\n toFieldKey: options?.toFieldKey || \"\",\n toFieldValue: options?.toFieldValue,\n fields: options?.fields,\n };\n}\n\n/**\n * Create a field query object\n *\n * @param name - Field name\n * @param operator - Comparison operator\n * @param value - Value to compare against\n * @returns KGFieldQuery object\n *\n * @example\n * ```ts\n * const ageFilter = createFieldQuery(\"age\", \"gt\", 21);\n * const statusFilter = createFieldQuery(\"status\", \"in\", [\"active\", \"pending\"]);\n * ```\n */\nexport function createFieldQuery(\n name: string,\n operator: KGFieldQueryOperator,\n value: unknown\n): KGFieldQuery {\n return { name, operator, value };\n}\n\n/**\n * Create a similarity search query\n *\n * @param label - Node label to search\n * @param searchText - Text to find similar nodes for\n * @param options - Additional query options\n * @returns KGQuery object configured for similarity search\n *\n * @example\n * ```ts\n * const similarDocs = createSimilarityQuery(\n * \"Document\",\n * \"machine learning algorithms\",\n * { limit: 10, embeddingsSource: \"openai\" }\n * );\n * ```\n */\nexport function createSimilarityQuery(\n label: string,\n searchText: string,\n options?: {\n embeddingsSource?: string;\n limit?: number;\n summaryOnly?: boolean;\n }\n): KGQuery {\n const builder = new KGQueryBuilder()\n .label(label)\n .field(\"_search\", \"similar\", searchText);\n\n if (options?.embeddingsSource) builder.embeddingsSource(options.embeddingsSource);\n if (options?.limit !== undefined) builder.limit(options.limit);\n if (options?.summaryOnly) builder.summaryOnly();\n\n return builder.build();\n}\n"]}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// utils/query-builder.ts
|
|
4
|
+
var KGQueryBuilder = class {
|
|
5
|
+
_label = "";
|
|
6
|
+
_fields = [];
|
|
7
|
+
_edges = [];
|
|
8
|
+
_limit = 100;
|
|
9
|
+
_depth = 1;
|
|
10
|
+
_offset = 0;
|
|
11
|
+
_sortBy = "";
|
|
12
|
+
_sortOrder = "";
|
|
13
|
+
_embeddingsSource;
|
|
14
|
+
_skipEmbedding = false;
|
|
15
|
+
_summaryOnly = false;
|
|
16
|
+
/**
|
|
17
|
+
* Set the node label to query
|
|
18
|
+
*
|
|
19
|
+
* @param label - The node label (e.g., "Person", "Product")
|
|
20
|
+
*/
|
|
21
|
+
label(label) {
|
|
22
|
+
this._label = label;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Add a field filter to the query
|
|
27
|
+
*
|
|
28
|
+
* @param name - Field name
|
|
29
|
+
* @param operator - Comparison operator (eq, neq, gt, lt, gte, lte, like, similar, in, arrayContains)
|
|
30
|
+
* @param value - Value to compare against
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* builder.field("age", "gt", 21);
|
|
35
|
+
* builder.field("status", "in", ["active", "pending"]);
|
|
36
|
+
* builder.field("name", "like", "John%");
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
field(name, operator, value) {
|
|
40
|
+
this._fields.push({ name, operator, value });
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Add an equality field filter (shorthand for field(name, "eq", value))
|
|
45
|
+
*
|
|
46
|
+
* @param name - Field name
|
|
47
|
+
* @param value - Value to match
|
|
48
|
+
*/
|
|
49
|
+
where(name, value) {
|
|
50
|
+
return this.field(name, "eq", value);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Add multiple equality filters at once
|
|
54
|
+
*
|
|
55
|
+
* @param fields - Object with field names as keys and values to match
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* builder.whereAll({ status: "active", type: "premium" });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
whereAll(fields) {
|
|
63
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
64
|
+
this.where(name, value);
|
|
65
|
+
}
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Add an edge traversal to the query
|
|
70
|
+
*
|
|
71
|
+
* @param label - Edge label (e.g., "WORKS_AT", "REPORTS_TO")
|
|
72
|
+
* @param direction - Traversal direction ("incoming" or "outgoing")
|
|
73
|
+
* @param toLabel - Target node label (optional)
|
|
74
|
+
* @param options - Additional edge query options
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* builder.edge("WORKS_AT", "outgoing", "Company");
|
|
79
|
+
* builder.edge("REPORTS_TO", "incoming", "Person", {
|
|
80
|
+
* toFieldKey: "id",
|
|
81
|
+
* toFieldValue: "manager-123"
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
edge(label, direction, toLabel = "", options = {}) {
|
|
86
|
+
this._edges.push({
|
|
87
|
+
label,
|
|
88
|
+
direction,
|
|
89
|
+
toLabel,
|
|
90
|
+
toFieldKey: options.toFieldKey || "",
|
|
91
|
+
toFieldValue: options.toFieldValue,
|
|
92
|
+
fields: options.fields
|
|
93
|
+
});
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add an outgoing edge traversal
|
|
98
|
+
*
|
|
99
|
+
* @param label - Edge label
|
|
100
|
+
* @param toLabel - Target node label
|
|
101
|
+
*/
|
|
102
|
+
outgoing(label, toLabel = "") {
|
|
103
|
+
return this.edge(label, "outgoing", toLabel);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Add an incoming edge traversal
|
|
107
|
+
*
|
|
108
|
+
* @param label - Edge label
|
|
109
|
+
* @param toLabel - Source node label
|
|
110
|
+
*/
|
|
111
|
+
incoming(label, toLabel = "") {
|
|
112
|
+
return this.edge(label, "incoming", toLabel);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set the maximum number of results
|
|
116
|
+
*
|
|
117
|
+
* @param n - Maximum number of results (default: 100)
|
|
118
|
+
*/
|
|
119
|
+
limit(n) {
|
|
120
|
+
this._limit = n;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Set the traversal depth
|
|
125
|
+
*
|
|
126
|
+
* @param n - Depth of edge traversal (default: 1)
|
|
127
|
+
*/
|
|
128
|
+
depth(n) {
|
|
129
|
+
this._depth = n;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Set the result offset for pagination
|
|
134
|
+
*
|
|
135
|
+
* @param n - Number of results to skip
|
|
136
|
+
*/
|
|
137
|
+
offset(n) {
|
|
138
|
+
this._offset = n;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Set the sort field and order
|
|
143
|
+
*
|
|
144
|
+
* @param field - Field name to sort by
|
|
145
|
+
* @param order - Sort order ("asc" or "desc")
|
|
146
|
+
*/
|
|
147
|
+
sortBy(field, order = "asc") {
|
|
148
|
+
this._sortBy = field;
|
|
149
|
+
this._sortOrder = order;
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set the embeddings source for similarity search
|
|
154
|
+
*
|
|
155
|
+
* @param source - Embeddings source identifier
|
|
156
|
+
*/
|
|
157
|
+
embeddingsSource(source) {
|
|
158
|
+
this._embeddingsSource = source;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Skip embedding generation for this query
|
|
163
|
+
*/
|
|
164
|
+
skipEmbedding() {
|
|
165
|
+
this._skipEmbedding = true;
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Return only summary fields (excludes heavy fields like text, embeddings)
|
|
170
|
+
*/
|
|
171
|
+
summaryOnly() {
|
|
172
|
+
this._summaryOnly = true;
|
|
173
|
+
return this;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Build the final KGQuery object
|
|
177
|
+
*
|
|
178
|
+
* @returns The constructed KGQuery
|
|
179
|
+
* @throws Error if no label is set
|
|
180
|
+
*/
|
|
181
|
+
build() {
|
|
182
|
+
if (!this._label) {
|
|
183
|
+
throw new Error("KGQueryBuilder: label is required");
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
label: this._label,
|
|
187
|
+
fields: this._fields,
|
|
188
|
+
edges: this._edges.length > 0 ? this._edges : void 0,
|
|
189
|
+
limit: this._limit,
|
|
190
|
+
depth: this._depth,
|
|
191
|
+
sortBy: this._sortBy,
|
|
192
|
+
sortOrder: this._sortOrder,
|
|
193
|
+
embeddingsSource: this._embeddingsSource,
|
|
194
|
+
skipEmbedding: this._skipEmbedding || void 0,
|
|
195
|
+
summaryOnly: this._summaryOnly || void 0
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
function createNodeQuery(label, fields, options) {
|
|
200
|
+
const builder = new KGQueryBuilder().label(label);
|
|
201
|
+
if (fields) {
|
|
202
|
+
builder.whereAll(fields);
|
|
203
|
+
}
|
|
204
|
+
if (options?.limit !== void 0) builder.limit(options.limit);
|
|
205
|
+
if (options?.depth !== void 0) builder.depth(options.depth);
|
|
206
|
+
if (options?.sortBy) builder.sortBy(options.sortBy, options.sortOrder);
|
|
207
|
+
if (options?.summaryOnly) builder.summaryOnly();
|
|
208
|
+
return builder.build();
|
|
209
|
+
}
|
|
210
|
+
function createEdgeQuery(label, direction = "outgoing", options) {
|
|
211
|
+
return {
|
|
212
|
+
label,
|
|
213
|
+
direction,
|
|
214
|
+
toLabel: options?.toLabel || "",
|
|
215
|
+
toFieldKey: options?.toFieldKey || "",
|
|
216
|
+
toFieldValue: options?.toFieldValue,
|
|
217
|
+
fields: options?.fields
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function createFieldQuery(name, operator, value) {
|
|
221
|
+
return { name, operator, value };
|
|
222
|
+
}
|
|
223
|
+
function createSimilarityQuery(label, searchText, options) {
|
|
224
|
+
const builder = new KGQueryBuilder().label(label).field("_search", "similar", searchText);
|
|
225
|
+
if (options?.embeddingsSource) builder.embeddingsSource(options.embeddingsSource);
|
|
226
|
+
if (options?.limit !== void 0) builder.limit(options.limit);
|
|
227
|
+
if (options?.summaryOnly) builder.summaryOnly();
|
|
228
|
+
return builder.build();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export {
|
|
232
|
+
KGQueryBuilder,
|
|
233
|
+
createNodeQuery,
|
|
234
|
+
createEdgeQuery,
|
|
235
|
+
createFieldQuery,
|
|
236
|
+
createSimilarityQuery
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=chunk-CAXPQTKI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../utils/query-builder.ts"],"sourcesContent":["/**\n * Knowledge Graph Query Builder\n *\n * Fluent API for building KGQuery objects programmatically.\n *\n * @example\n * ```ts\n * import { KGQueryBuilder, createNodeQuery } from \"@elqnt/kg/utils\";\n *\n * // Using the builder\n * const query = new KGQueryBuilder()\n * .label(\"Person\")\n * .field(\"age\", \"gt\", 21)\n * .field(\"status\", \"eq\", \"active\")\n * .edge(\"WORKS_AT\", \"outgoing\", \"Company\")\n * .limit(50)\n * .sortBy(\"name\", \"asc\")\n * .build();\n *\n * // Using helper functions\n * const simpleQuery = createNodeQuery(\"Product\", { category: \"electronics\" });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type {\n KGQuery,\n KGFieldQuery,\n KGFieldQueryOperator,\n KGEdgeQuery,\n KGRelationshipDirection,\n} from \"../models\";\n\n// Re-export operator and direction constants for convenience\nexport {\n KGFieldQueryOperatorEqual,\n KGFieldQueryOperatorNotEqual,\n KGFieldQueryOperatorGreater,\n KGFieldQueryOperatorLess,\n KGFieldQueryOperatorGreaterOrEqual,\n KGFieldQueryOperatorLessOrEqual,\n KGFieldQueryOperatorLike,\n KGFieldQueryOperatorSimilar,\n KGFieldQueryOperatorIn,\n KGFieldQueryOperatorArrayContains,\n KGRelationshipDirectionIncoming,\n KGRelationshipDirectionOutgoing,\n} from \"../models\";\n\n/**\n * Fluent builder for KGQuery objects\n *\n * Provides a chainable API for constructing knowledge graph queries.\n * All methods return `this` to allow chaining.\n *\n * @example\n * ```ts\n * const query = new KGQueryBuilder()\n * .label(\"Person\")\n * .field(\"age\", \"gt\", 21)\n * .field(\"department\", \"eq\", \"Engineering\")\n * .edge(\"REPORTS_TO\", \"outgoing\", \"Person\")\n * .limit(100)\n * .offset(0)\n * .sortBy(\"name\", \"asc\")\n * .summaryOnly()\n * .build();\n * ```\n */\nexport class KGQueryBuilder {\n private _label: string = \"\";\n private _fields: KGFieldQuery[] = [];\n private _edges: KGEdgeQuery[] = [];\n private _limit: number = 100;\n private _depth: number = 1;\n private _offset: number = 0;\n private _sortBy: string = \"\";\n private _sortOrder: string = \"\";\n private _embeddingsSource?: string;\n private _skipEmbedding: boolean = false;\n private _summaryOnly: boolean = false;\n\n /**\n * Set the node label to query\n *\n * @param label - The node label (e.g., \"Person\", \"Product\")\n */\n label(label: string): this {\n this._label = label;\n return this;\n }\n\n /**\n * Add a field filter to the query\n *\n * @param name - Field name\n * @param operator - Comparison operator (eq, neq, gt, lt, gte, lte, like, similar, in, arrayContains)\n * @param value - Value to compare against\n *\n * @example\n * ```ts\n * builder.field(\"age\", \"gt\", 21);\n * builder.field(\"status\", \"in\", [\"active\", \"pending\"]);\n * builder.field(\"name\", \"like\", \"John%\");\n * ```\n */\n field(name: string, operator: KGFieldQueryOperator, value: unknown): this {\n this._fields.push({ name, operator, value });\n return this;\n }\n\n /**\n * Add an equality field filter (shorthand for field(name, \"eq\", value))\n *\n * @param name - Field name\n * @param value - Value to match\n */\n where(name: string, value: unknown): this {\n return this.field(name, \"eq\", value);\n }\n\n /**\n * Add multiple equality filters at once\n *\n * @param fields - Object with field names as keys and values to match\n *\n * @example\n * ```ts\n * builder.whereAll({ status: \"active\", type: \"premium\" });\n * ```\n */\n whereAll(fields: Record<string, unknown>): this {\n for (const [name, value] of Object.entries(fields)) {\n this.where(name, value);\n }\n return this;\n }\n\n /**\n * Add an edge traversal to the query\n *\n * @param label - Edge label (e.g., \"WORKS_AT\", \"REPORTS_TO\")\n * @param direction - Traversal direction (\"incoming\" or \"outgoing\")\n * @param toLabel - Target node label (optional)\n * @param options - Additional edge query options\n *\n * @example\n * ```ts\n * builder.edge(\"WORKS_AT\", \"outgoing\", \"Company\");\n * builder.edge(\"REPORTS_TO\", \"incoming\", \"Person\", {\n * toFieldKey: \"id\",\n * toFieldValue: \"manager-123\"\n * });\n * ```\n */\n edge(\n label: string,\n direction: \"incoming\" | \"outgoing\",\n toLabel: string = \"\",\n options: {\n toFieldKey?: string;\n toFieldValue?: unknown;\n fields?: Record<string, unknown>;\n } = {}\n ): this {\n this._edges.push({\n label,\n direction,\n toLabel,\n toFieldKey: options.toFieldKey || \"\",\n toFieldValue: options.toFieldValue,\n fields: options.fields,\n });\n return this;\n }\n\n /**\n * Add an outgoing edge traversal\n *\n * @param label - Edge label\n * @param toLabel - Target node label\n */\n outgoing(label: string, toLabel: string = \"\"): this {\n return this.edge(label, \"outgoing\", toLabel);\n }\n\n /**\n * Add an incoming edge traversal\n *\n * @param label - Edge label\n * @param toLabel - Source node label\n */\n incoming(label: string, toLabel: string = \"\"): this {\n return this.edge(label, \"incoming\", toLabel);\n }\n\n /**\n * Set the maximum number of results\n *\n * @param n - Maximum number of results (default: 100)\n */\n limit(n: number): this {\n this._limit = n;\n return this;\n }\n\n /**\n * Set the traversal depth\n *\n * @param n - Depth of edge traversal (default: 1)\n */\n depth(n: number): this {\n this._depth = n;\n return this;\n }\n\n /**\n * Set the result offset for pagination\n *\n * @param n - Number of results to skip\n */\n offset(n: number): this {\n this._offset = n;\n return this;\n }\n\n /**\n * Set the sort field and order\n *\n * @param field - Field name to sort by\n * @param order - Sort order (\"asc\" or \"desc\")\n */\n sortBy(field: string, order: \"asc\" | \"desc\" = \"asc\"): this {\n this._sortBy = field;\n this._sortOrder = order;\n return this;\n }\n\n /**\n * Set the embeddings source for similarity search\n *\n * @param source - Embeddings source identifier\n */\n embeddingsSource(source: string): this {\n this._embeddingsSource = source;\n return this;\n }\n\n /**\n * Skip embedding generation for this query\n */\n skipEmbedding(): this {\n this._skipEmbedding = true;\n return this;\n }\n\n /**\n * Return only summary fields (excludes heavy fields like text, embeddings)\n */\n summaryOnly(): this {\n this._summaryOnly = true;\n return this;\n }\n\n /**\n * Build the final KGQuery object\n *\n * @returns The constructed KGQuery\n * @throws Error if no label is set\n */\n build(): KGQuery {\n if (!this._label) {\n throw new Error(\"KGQueryBuilder: label is required\");\n }\n\n return {\n label: this._label,\n fields: this._fields,\n edges: this._edges.length > 0 ? this._edges : undefined,\n limit: this._limit,\n depth: this._depth,\n sortBy: this._sortBy,\n sortOrder: this._sortOrder,\n embeddingsSource: this._embeddingsSource,\n skipEmbedding: this._skipEmbedding || undefined,\n summaryOnly: this._summaryOnly || undefined,\n };\n }\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Create a simple node query with equality filters\n *\n * @param label - Node label to query\n * @param fields - Optional field equality filters\n * @param options - Additional query options\n * @returns KGQuery object\n *\n * @example\n * ```ts\n * // Query all Person nodes\n * const allPeople = createNodeQuery(\"Person\");\n *\n * // Query with filters\n * const activeUsers = createNodeQuery(\"User\", { status: \"active\", role: \"admin\" });\n *\n * // With options\n * const recentProducts = createNodeQuery(\n * \"Product\",\n * { inStock: true },\n * { limit: 10, sortBy: \"createdAt\", sortOrder: \"desc\" }\n * );\n * ```\n */\nexport function createNodeQuery(\n label: string,\n fields?: Record<string, unknown>,\n options?: {\n limit?: number;\n depth?: number;\n sortBy?: string;\n sortOrder?: \"asc\" | \"desc\";\n summaryOnly?: boolean;\n }\n): KGQuery {\n const builder = new KGQueryBuilder().label(label);\n\n if (fields) {\n builder.whereAll(fields);\n }\n\n if (options?.limit !== undefined) builder.limit(options.limit);\n if (options?.depth !== undefined) builder.depth(options.depth);\n if (options?.sortBy) builder.sortBy(options.sortBy, options.sortOrder);\n if (options?.summaryOnly) builder.summaryOnly();\n\n return builder.build();\n}\n\n/**\n * Create an edge query object\n *\n * @param label - Edge label\n * @param direction - Traversal direction\n * @param options - Additional edge options\n * @returns KGEdgeQuery object\n *\n * @example\n * ```ts\n * const worksAtEdge = createEdgeQuery(\"WORKS_AT\", \"outgoing\", {\n * toLabel: \"Company\",\n * toFieldKey: \"name\",\n * toFieldValue: \"Acme Corp\"\n * });\n * ```\n */\nexport function createEdgeQuery(\n label: string,\n direction: \"incoming\" | \"outgoing\" = \"outgoing\",\n options?: {\n toLabel?: string;\n toFieldKey?: string;\n toFieldValue?: unknown;\n fields?: Record<string, unknown>;\n }\n): KGEdgeQuery {\n return {\n label,\n direction,\n toLabel: options?.toLabel || \"\",\n toFieldKey: options?.toFieldKey || \"\",\n toFieldValue: options?.toFieldValue,\n fields: options?.fields,\n };\n}\n\n/**\n * Create a field query object\n *\n * @param name - Field name\n * @param operator - Comparison operator\n * @param value - Value to compare against\n * @returns KGFieldQuery object\n *\n * @example\n * ```ts\n * const ageFilter = createFieldQuery(\"age\", \"gt\", 21);\n * const statusFilter = createFieldQuery(\"status\", \"in\", [\"active\", \"pending\"]);\n * ```\n */\nexport function createFieldQuery(\n name: string,\n operator: KGFieldQueryOperator,\n value: unknown\n): KGFieldQuery {\n return { name, operator, value };\n}\n\n/**\n * Create a similarity search query\n *\n * @param label - Node label to search\n * @param searchText - Text to find similar nodes for\n * @param options - Additional query options\n * @returns KGQuery object configured for similarity search\n *\n * @example\n * ```ts\n * const similarDocs = createSimilarityQuery(\n * \"Document\",\n * \"machine learning algorithms\",\n * { limit: 10, embeddingsSource: \"openai\" }\n * );\n * ```\n */\nexport function createSimilarityQuery(\n label: string,\n searchText: string,\n options?: {\n embeddingsSource?: string;\n limit?: number;\n summaryOnly?: boolean;\n }\n): KGQuery {\n const builder = new KGQueryBuilder()\n .label(label)\n .field(\"_search\", \"similar\", searchText);\n\n if (options?.embeddingsSource) builder.embeddingsSource(options.embeddingsSource);\n if (options?.limit !== undefined) builder.limit(options.limit);\n if (options?.summaryOnly) builder.summaryOnly();\n\n return builder.build();\n}\n"],"mappings":"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","names":[]}
|