grafeo-ogm 1.2.0 → 1.3.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 (77) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +156 -1
  3. package/dist/cjs/compilers/vector.compiler.d.ts +56 -0
  4. package/dist/cjs/compilers/vector.compiler.d.ts.map +1 -0
  5. package/dist/cjs/compilers/vector.compiler.js +129 -0
  6. package/dist/cjs/compilers/vector.compiler.js.map +1 -0
  7. package/dist/cjs/generator/generate-types.d.ts.map +1 -1
  8. package/dist/cjs/generator/generate-types.js +2 -0
  9. package/dist/cjs/generator/generate-types.js.map +1 -1
  10. package/dist/cjs/generator/type-emitters/fulltext-emitter.d.ts +16 -4
  11. package/dist/cjs/generator/type-emitters/fulltext-emitter.d.ts.map +1 -1
  12. package/dist/cjs/generator/type-emitters/fulltext-emitter.js +122 -9
  13. package/dist/cjs/generator/type-emitters/fulltext-emitter.js.map +1 -1
  14. package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts +6 -0
  15. package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
  16. package/dist/cjs/generator/type-emitters/model-map-emitter.js +76 -5
  17. package/dist/cjs/generator/type-emitters/model-map-emitter.js.map +1 -1
  18. package/dist/cjs/generator/type-emitters/utility-types.js +1 -1
  19. package/dist/cjs/generator/type-emitters/utility-types.js.map +1 -1
  20. package/dist/cjs/generator/type-emitters/vector-emitter.d.ts +14 -0
  21. package/dist/cjs/generator/type-emitters/vector-emitter.d.ts.map +1 -0
  22. package/dist/cjs/generator/type-emitters/vector-emitter.js +81 -0
  23. package/dist/cjs/generator/type-emitters/vector-emitter.js.map +1 -0
  24. package/dist/cjs/index.d.ts +3 -1
  25. package/dist/cjs/index.d.ts.map +1 -1
  26. package/dist/cjs/index.js +3 -1
  27. package/dist/cjs/index.js.map +1 -1
  28. package/dist/cjs/model.d.ts +127 -1
  29. package/dist/cjs/model.d.ts.map +1 -1
  30. package/dist/cjs/model.js +166 -58
  31. package/dist/cjs/model.js.map +1 -1
  32. package/dist/cjs/ogm.d.ts.map +1 -1
  33. package/dist/cjs/ogm.js +3 -0
  34. package/dist/cjs/ogm.js.map +1 -1
  35. package/dist/cjs/schema/parser.d.ts.map +1 -1
  36. package/dist/cjs/schema/parser.js +48 -0
  37. package/dist/cjs/schema/parser.js.map +1 -1
  38. package/dist/cjs/schema/types.d.ts +7 -0
  39. package/dist/cjs/schema/types.d.ts.map +1 -1
  40. package/dist/esm/compilers/vector.compiler.d.ts +56 -0
  41. package/dist/esm/compilers/vector.compiler.d.ts.map +1 -0
  42. package/dist/esm/compilers/vector.compiler.js +125 -0
  43. package/dist/esm/compilers/vector.compiler.js.map +1 -0
  44. package/dist/esm/generator/generate-types.d.ts.map +1 -1
  45. package/dist/esm/generator/generate-types.js +2 -0
  46. package/dist/esm/generator/generate-types.js.map +1 -1
  47. package/dist/esm/generator/type-emitters/fulltext-emitter.d.ts +16 -4
  48. package/dist/esm/generator/type-emitters/fulltext-emitter.d.ts.map +1 -1
  49. package/dist/esm/generator/type-emitters/fulltext-emitter.js +121 -9
  50. package/dist/esm/generator/type-emitters/fulltext-emitter.js.map +1 -1
  51. package/dist/esm/generator/type-emitters/model-map-emitter.d.ts +6 -0
  52. package/dist/esm/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
  53. package/dist/esm/generator/type-emitters/model-map-emitter.js +76 -5
  54. package/dist/esm/generator/type-emitters/model-map-emitter.js.map +1 -1
  55. package/dist/esm/generator/type-emitters/utility-types.js +1 -1
  56. package/dist/esm/generator/type-emitters/utility-types.js.map +1 -1
  57. package/dist/esm/generator/type-emitters/vector-emitter.d.ts +14 -0
  58. package/dist/esm/generator/type-emitters/vector-emitter.d.ts.map +1 -0
  59. package/dist/esm/generator/type-emitters/vector-emitter.js +78 -0
  60. package/dist/esm/generator/type-emitters/vector-emitter.js.map +1 -0
  61. package/dist/esm/index.d.ts +3 -1
  62. package/dist/esm/index.d.ts.map +1 -1
  63. package/dist/esm/index.js +1 -0
  64. package/dist/esm/index.js.map +1 -1
  65. package/dist/esm/model.d.ts +127 -1
  66. package/dist/esm/model.d.ts.map +1 -1
  67. package/dist/esm/model.js +166 -58
  68. package/dist/esm/model.js.map +1 -1
  69. package/dist/esm/ogm.d.ts.map +1 -1
  70. package/dist/esm/ogm.js +3 -0
  71. package/dist/esm/ogm.js.map +1 -1
  72. package/dist/esm/schema/parser.d.ts.map +1 -1
  73. package/dist/esm/schema/parser.js +48 -0
  74. package/dist/esm/schema/parser.js.map +1 -1
  75. package/dist/esm/schema/types.d.ts +7 -0
  76. package/dist/esm/schema/types.d.ts.map +1 -1
  77. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.1 (2026-04-21)
4
+
5
+ ### Bug Fixes
6
+
7
+ - **`$param0` collision in mutations with projected relationships** — `create()`, `update()`, and `upsert()` compiled the RETURN-clause projection with a fresh `paramCounter` starting at `0`. If the projection contained a relationship-`where` or a connection-`where` on a scalar filter, the selection compiler would allocate `$param0` and silently clobber the outer WHERE's `$param0` (already present in the mutation params). Symptom: `MATCH (n:Label) WHERE n.id = $param0` would run against the selection's value instead of the caller's — the match returned zero rows and the mutation appeared to succeed against nothing. The fix threads a single `paramCounter` through `applySelect*To*` / `applySelectionSet*To*` helpers so outer WHERE params and inner selection params share one namespace. No API change; behavior is purely additive for callers that were unaffected.
8
+
9
+ ### Features
10
+
11
+ - **`@vector` directive** — spec-compatible vector index support on `@node` types. Mirrors the official `@neo4j/graphql` shape: `@vector(indexes: [{ indexName, queryName, embeddingProperty, provider? }])`. The directive is parsed into a `VectorIndex[]` on each `NodeDefinition` and powers two new typed query methods.
12
+ - **`Model.searchByVector()`** — top-k vector similarity search against a Neo4j vector index. Accepts a pre-computed `number[]` embedding, a user-supplied `where` filter, and any selection mode (`select` or `selectionSet`). Compiles to `CALL db.index.vector.queryNodes(...)` with `k` clamped to `[1, 1000]` and returns `Array<{ node, score }>`.
13
+ - **`Model.searchByPhrase()`** — phrase-based vector search via the Neo4j GenAI plugin. The matching `@vector` index must have `provider` set. Accepts a `phrase` plus a runtime `providerConfig` (e.g. `{ token: process.env.OPENAI_API_KEY }`) so API credentials stay out of the schema. Compiles to `CALL genai.vector.encode(...)` chained into `db.index.vector.queryNodes(...)`.
14
+ - **Typed vector result / input types** — the code generator emits `<Node>VectorResult`, `<Node>VectorSearchByVectorInput`, and (when at least one index has `provider` set) `<Node>VectorSearchByPhraseInput`. Index names become a literal-string union for autocomplete and typo-checking. The generated `<Node>Model` exposes typed `searchByVector` / `searchByPhrase` signatures.
15
+
16
+ ### Improvements
17
+
18
+ - **F1 — typed `<Node>FulltextInput` per node** — the fulltext emitter now emits per-node `<Node>FulltextLeaf` and `<Node>FulltextInput` types with literal-keyed index names. Typos in index names surface as TypeScript errors and IDEs autocomplete valid indexes. The generated `<Node>Model.find()` signature threads the per-node fulltext type via an `Omit<..., 'find' | ...> & { ...typed find }` wrapper. Fully backward compatible — the global `FulltextInput`, `FulltextLeaf`, and `FulltextIndexEntry` exports are unchanged for users who write generic helpers across models.
19
+
20
+ ### Internal
21
+
22
+ - `ModelCompilers` extended with an optional `vector?: VectorCompiler` field. `OGM` instantiates `VectorCompiler` alongside the other compilers and injects it into every `Model`.
23
+ - Exported `VectorCompiler`, `VectorResult`, and `VectorIndex` from the package root for advanced use cases (custom query composition, testing).
24
+ - New emitter `src/generator/type-emitters/vector-emitter.ts` wired into `generateTypes`.
25
+
26
+ ### Requirements
27
+
28
+ - `@vector` requires **Neo4j 5.11+** (native vector index support).
29
+ - `Model.searchByPhrase()` additionally requires the **Neo4j GenAI plugin** installed on the database. Without it, phrase search will fail at query time.
30
+ - Users must create the vector index themselves via Cypher migration (grafeo-ogm does not create vector indexes automatically in this release):
31
+ ```cypher
32
+ CREATE VECTOR INDEX article_content_idx FOR (n:Article) ON n.embedding
33
+ OPTIONS { indexConfig: { 'vector.dimensions': 1536, 'vector.similarity_function': 'cosine' } }
34
+ ```
35
+
36
+ ### Notes & Limits
37
+
38
+ - **`k` is silently clamped to `[1, 1000]`** in `searchByVector` and `searchByPhrase` to prevent unbounded result sets. Requests for `k > 1000` return at most 1000 results with no runtime warning. If your workload needs a larger top-k (bulk re-ranking, recommendation retrieval), track [a future release](https://github.com/neomodular/grafeo-ogm/issues) where this will be configurable.
39
+
3
40
  ## 1.2.0 (2026-04-16)
4
41
 
5
42
  ### Features
package/README.md CHANGED
@@ -26,6 +26,7 @@ Define your graph model once in `.graphql` and get fully typed CRUD operations,
26
26
  - [Query API](#query-api)
27
27
  - [Mutation API](#mutation-api)
28
28
  - [Advanced Features](#advanced-features)
29
+ - [Vector Search](#vector-search)
29
30
  - [Type Generation](#type-generation)
30
31
  - [Testing Utilities](#testing-utilities)
31
32
  - [Security](#security)
@@ -221,7 +222,8 @@ await ogm.$transaction(async (ctx) => {
221
222
  | **Full TypeScript type safety** | Code generation produces typed models, where inputs, create/update inputs, select fields, and connection types |
222
223
  | **Pattern comprehensions** | Relationship traversal without Cartesian products -- O(1) rows per node |
223
224
  | **Typed `select` API** | `select: { id: true, author: { select: { name: true } } }` with compile-time type checking |
224
- | **Fulltext search** | Node and relationship indexes with phrase matching, score thresholds, and logical operators (`AND`, `OR`, `NOT`) |
225
+ | **Fulltext search** | Node and relationship indexes with phrase matching, score thresholds, and logical operators (`AND`, `OR`, `NOT`). Per-node typed inputs with literal-string autocomplete for index names |
226
+ | **Vector search** | `@vector` directive with `searchByVector` (top-k similarity) and `searchByPhrase` (via the Neo4j GenAI plugin). Typed results as `{ node, score }[]` |
225
227
  | **Subgraph operations** | Clone and delete entire subgraphs via APOC with reference relationship re-attachment |
226
228
  | **Runtime multi-label** | Add/remove/filter by labels at query time: `labels: ['Active']`, `setLabels()` |
227
229
  | **Interface models** | Polymorphic read queries across all types implementing a shared interface, with `__typename` discrimination |
@@ -251,6 +253,7 @@ grafeo-ogm uses standard GraphQL SDL with Neo4j directives to define your graph
251
253
  | `@cypher` | Field | Computed field resolved via a custom Cypher statement |
252
254
  | `@default` | Field | Sets a default value on create |
253
255
  | `@fulltext` | Type | Defines fulltext search indexes with `name` and `fields` |
256
+ | `@vector` | Type | Registers one or more Neo4j vector indexes on a node (see [Vector Search](#vector-search)) |
254
257
 
255
258
  ### Supported Scalar Types
256
259
 
@@ -766,6 +769,18 @@ const results = await Book.find({
766
769
  });
767
770
  ```
768
771
 
772
+ **Typed index names (v1.3.0+).** The generated `<Node>FulltextInput` type now carries the list of valid index names as literal-keyed optional fields. Typos surface as TypeScript errors and IDEs autocomplete the available indexes.
773
+
774
+ ```typescript
775
+ // Before v1.3.0 — any string key compiled, typos only failed at runtime
776
+ await Book.find({ fulltext: { BokSearch: { phrase: 'graph' } } }); // silently accepted at type-check
777
+
778
+ // v1.3.0+ — `BokSearch` is a compile-time error; `BookSearch` autocompletes
779
+ await Book.find({ fulltext: { BookSearch: { phrase: 'graph' } } });
780
+ ```
781
+
782
+ The runtime compiler is unchanged; this is a purely ergonomic type-level improvement. The global `FulltextInput`, `FulltextLeaf`, and `FulltextIndexEntry` exports remain for writing generic helpers across models.
783
+
769
784
  ### Subgraph Operations
770
785
 
771
786
  Clone or delete entire subgraphs using APOC procedures. Requires the APOC plugin installed in Neo4j.
@@ -883,6 +898,146 @@ const publishedStats = await Book.aggregate({
883
898
 
884
899
  ---
885
900
 
901
+ ## Vector Search
902
+
903
+ grafeo-ogm supports Neo4j's native vector indexes via the `@vector` directive. The directive lives on `@node` types, mirrors the official `@neo4j/graphql` spec shape, and enables two typed query methods on the generated model: `searchByVector` (pass a pre-computed embedding) and `searchByPhrase` (encode text server-side via the Neo4j GenAI plugin). Results are returned as `Array<{ node, score }>`.
904
+
905
+ ### Schema
906
+
907
+ Declare one or more vector indexes on a node type. Set `provider` only on indexes that should support phrase search; plain vector search is always available.
908
+
909
+ ```graphql
910
+ type Article @node @vector(indexes: [
911
+ {
912
+ indexName: "article_content_idx"
913
+ queryName: "similarArticles"
914
+ embeddingProperty: "embedding"
915
+ provider: "OpenAI"
916
+ },
917
+ {
918
+ indexName: "article_title_idx"
919
+ queryName: "similarTitles"
920
+ embeddingProperty: "titleEmbedding"
921
+ # no provider — only searchByVector is available for this index
922
+ }
923
+ ]) {
924
+ id: ID! @id
925
+ title: String!
926
+ content: String!
927
+ embedding: [Float!]!
928
+ titleEmbedding: [Float!]!
929
+ published: Boolean!
930
+ }
931
+ ```
932
+
933
+ ### Creating the index in Neo4j
934
+
935
+ grafeo-ogm does **not** create vector indexes for you in this release. Run the `CREATE VECTOR INDEX` Cypher yourself as part of your migration:
936
+
937
+ ```cypher
938
+ CREATE VECTOR INDEX article_content_idx FOR (n:Article) ON n.embedding
939
+ OPTIONS { indexConfig: { 'vector.dimensions': 1536, 'vector.similarity_function': 'cosine' } }
940
+ ```
941
+
942
+ ### `searchByVector` — top-k similarity with a pre-computed embedding
943
+
944
+ Use this when you already have an embedding vector (for example, computed via an external SDK in your application code). `k` is clamped to the range `[1, 1000]`.
945
+
946
+ ```typescript
947
+ const Article = ogm.model('Article');
948
+
949
+ const vector = await myEmbedder.embed('distributed consensus algorithms');
950
+
951
+ const results = await Article.searchByVector({
952
+ indexName: 'article_content_idx',
953
+ vector,
954
+ k: 10,
955
+ where: { published: true },
956
+ select: { id: true, title: true },
957
+ });
958
+ // results: Array<{ node: { id: string, title: string }, score: number }>
959
+ ```
960
+
961
+ Compiles to:
962
+
963
+ ```cypher
964
+ CALL db.index.vector.queryNodes($v_name, $v_k, $v_vector) YIELD node AS n, score
965
+ WHERE n.published = $param0
966
+ RETURN n { .id, .title } AS n, score
967
+ ```
968
+
969
+ ### `searchByPhrase` — server-side encoding via Neo4j GenAI
970
+
971
+ Use this when you want Neo4j to encode the phrase for you. This requires two things:
972
+
973
+ 1. The index's `@vector` entry has a `provider` set (e.g. `"OpenAI"`, `"AzureOpenAI"`, `"VertexAI"` — whatever the GenAI plugin accepts).
974
+ 2. The **Neo4j GenAI plugin** is installed on the database.
975
+
976
+ API credentials never appear in the schema. Pass them at query time via `providerConfig`:
977
+
978
+ ```typescript
979
+ const results = await Article.searchByPhrase({
980
+ indexName: 'article_content_idx',
981
+ phrase: 'distributed consensus algorithms',
982
+ k: 10,
983
+ providerConfig: { token: process.env.OPENAI_API_KEY },
984
+ where: { published: true },
985
+ select: { id: true, title: true },
986
+ });
987
+ // results: Array<{ node: { id: string, title: string }, score: number }>
988
+ ```
989
+
990
+ Compiles to:
991
+
992
+ ```cypher
993
+ CALL genai.vector.encode($v_phrase, $v_provider, $v_providerConfig) YIELD vector AS __v_encoded
994
+ CALL db.index.vector.queryNodes($v_name, $v_k, __v_encoded) YIELD node AS n, score
995
+ WHERE n.published = $param0
996
+ RETURN n { .id, .title } AS n, score
997
+ ```
998
+
999
+ Calling `searchByPhrase` on an index that does not have `provider` set throws at compile time with a descriptive error.
1000
+
1001
+ ### Generated types
1002
+
1003
+ For the `Article` schema above, `generateTypes` emits typed helpers with literal-string index names:
1004
+
1005
+ ```typescript
1006
+ export type ArticleVectorResult = { node: Article; score: number };
1007
+
1008
+ export type ArticleVectorSearchByVectorInput = {
1009
+ indexName: 'article_content_idx' | 'article_title_idx';
1010
+ vector: number[];
1011
+ k: number;
1012
+ where?: ArticleWhere;
1013
+ selectionSet?: string;
1014
+ labels?: string[];
1015
+ };
1016
+
1017
+ export type ArticleVectorSearchByPhraseInput = {
1018
+ indexName: 'article_content_idx'; // only indexes with provider set
1019
+ phrase: string;
1020
+ k: number;
1021
+ providerConfig?: Record<string, unknown>;
1022
+ where?: ArticleWhere;
1023
+ selectionSet?: string;
1024
+ labels?: string[];
1025
+ };
1026
+ ```
1027
+
1028
+ `ArticleVectorSearchByPhraseInput` is only emitted when at least one `@vector` index declares `provider`. Index-name typos surface as TypeScript errors.
1029
+
1030
+ ### Not supported (deferred)
1031
+
1032
+ The following were intentionally left out of this release:
1033
+
1034
+ - **`@embedded(from:, using:)` auto-write directive** — automatic embedding on create / update. Requires a pluggable embedder port and peer-dependency adapters.
1035
+ - **Third-party embedder SDKs** (`grafeo-ogm/embedders/openai`, etc.) — tracked for a future release with optional peer dependencies.
1036
+ - **Relationship-level `@vector` indexes** — the current Neo4j / official spec only supports node vector indexes.
1037
+ - **Automatic index creation via `assertIndexesAndConstraints`** — you must run `CREATE VECTOR INDEX` yourself.
1038
+
1039
+ ---
1040
+
886
1041
  ## Type Generation
887
1042
 
888
1043
  Generate TypeScript types from your schema for compile-time safety. **No Neo4j driver connection needed at build time.**
@@ -0,0 +1,56 @@
1
+ import { NodeDefinition } from '../schema/types';
2
+ export interface VectorResult {
3
+ cypher: string;
4
+ params: Record<string, unknown>;
5
+ }
6
+ /**
7
+ * Compiles vector-index search input into Cypher CALL clauses using
8
+ * `db.index.vector.queryNodes` and (optionally) `genai.vector.encode`.
9
+ *
10
+ * Emits only the CALL prelude — the caller (Model) composes any
11
+ * subsequent WHERE / RETURN / ORDER BY around it.
12
+ *
13
+ * Two entry points:
14
+ * - `compileByVector` — user supplies a pre-computed embedding.
15
+ * - `compileByPhrase` — user supplies a text phrase; the server-side GenAI
16
+ * plugin encodes it using the `provider` configured on the index.
17
+ */
18
+ export declare class VectorCompiler {
19
+ constructor();
20
+ /**
21
+ * Build the CALL clause for a vector similarity search against a pre-computed
22
+ * embedding. Returns a Cypher fragment that yields `n` and `score`.
23
+ */
24
+ compileByVector(input: {
25
+ indexName: string;
26
+ vector: number[];
27
+ k: number;
28
+ nodeDef: NodeDefinition;
29
+ paramCounter?: {
30
+ count: number;
31
+ };
32
+ }): VectorResult;
33
+ /**
34
+ * Build the two-step CALL for a vector similarity search keyed on a text
35
+ * phrase. Requires the matching index to declare a `provider`.
36
+ */
37
+ compileByPhrase(input: {
38
+ indexName: string;
39
+ phrase: string;
40
+ k: number;
41
+ providerConfig?: Record<string, unknown>;
42
+ nodeDef: NodeDefinition;
43
+ paramCounter?: {
44
+ count: number;
45
+ };
46
+ }): VectorResult;
47
+ /**
48
+ * Resolve and validate that `indexName` is declared on `nodeDef`. Throws a
49
+ * descriptive `OGMError` listing the available indexes on miss. The index
50
+ * name is also run through `assertSafeIdentifier` as defense in depth —
51
+ * even though it travels through a parameter, validating it here guards
52
+ * against accidental injection if the shape ever changes.
53
+ */
54
+ private assertIndexExists;
55
+ }
56
+ //# sourceMappingURL=vector.compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector.compiler.d.ts","sourceRoot":"","sources":["../../../src/compilers/vector.compiler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAe,MAAM,iBAAiB,CAAC;AAM9D,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,cAAc;;IAOzB;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,CAAC,EAAE,MAAM,CAAC;QACV,OAAO,EAAE,cAAc,CAAC;QACxB,YAAY,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAClC,GAAG,YAAY;IAwBhB;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,EAAE,MAAM,CAAC;QACV,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,cAAc,CAAC;QACxB,YAAY,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAClC,GAAG,YAAY;IAyChB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;CAgB1B"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VectorCompiler = void 0;
4
+ const errors_1 = require("../errors");
5
+ const validation_1 = require("../utils/validation");
6
+ /** Upper bound for k to prevent resource exhaustion on top-k queries. */
7
+ const MAX_K = 1000;
8
+ /**
9
+ * Compiles vector-index search input into Cypher CALL clauses using
10
+ * `db.index.vector.queryNodes` and (optionally) `genai.vector.encode`.
11
+ *
12
+ * Emits only the CALL prelude — the caller (Model) composes any
13
+ * subsequent WHERE / RETURN / ORDER BY around it.
14
+ *
15
+ * Two entry points:
16
+ * - `compileByVector` — user supplies a pre-computed embedding.
17
+ * - `compileByPhrase` — user supplies a text phrase; the server-side GenAI
18
+ * plugin encodes it using the `provider` configured on the index.
19
+ */
20
+ class VectorCompiler {
21
+ // No schema dependency: all metadata is resolved from the caller-supplied
22
+ // `nodeDef` on each `compileBy*` call. Keeping the constructor parameter-free
23
+ // makes the coupling honest — add a schema dependency only when the compiler
24
+ // genuinely needs cross-index metadata (e.g. resolving nodeDef from indexName).
25
+ constructor() { }
26
+ /**
27
+ * Build the CALL clause for a vector similarity search against a pre-computed
28
+ * embedding. Returns a Cypher fragment that yields `n` and `score`.
29
+ */
30
+ compileByVector(input) {
31
+ const { indexName, vector, k, nodeDef } = input;
32
+ const counter = input.paramCounter ?? { count: 0 };
33
+ this.assertIndexExists(indexName, nodeDef);
34
+ const safeK = assertValidK(k);
35
+ assertValidVector(vector);
36
+ const suffix = counter.count++;
37
+ const nameParam = `v_name_${suffix}`;
38
+ const kParam = `v_k_${suffix}`;
39
+ const vectorParam = `v_vector_${suffix}`;
40
+ const cypher = `CALL db.index.vector.queryNodes($${nameParam}, $${kParam}, $${vectorParam}) YIELD node AS n, score`;
41
+ const params = {
42
+ [nameParam]: indexName,
43
+ [kParam]: safeK,
44
+ [vectorParam]: vector,
45
+ };
46
+ return { cypher, params };
47
+ }
48
+ /**
49
+ * Build the two-step CALL for a vector similarity search keyed on a text
50
+ * phrase. Requires the matching index to declare a `provider`.
51
+ */
52
+ compileByPhrase(input) {
53
+ const { indexName, phrase, k, providerConfig, nodeDef } = input;
54
+ const counter = input.paramCounter ?? { count: 0 };
55
+ const index = this.assertIndexExists(indexName, nodeDef);
56
+ const safeK = assertValidK(k);
57
+ assertValidPhrase(phrase);
58
+ if (!index.provider || index.provider.trim().length === 0)
59
+ throw new errors_1.OGMError(`Vector index "${indexName}" is not configured for phrase search. Set "provider" on the @vector directive to enable searchByPhrase.`);
60
+ const suffix = counter.count++;
61
+ const nameParam = `v_name_${suffix}`;
62
+ const kParam = `v_k_${suffix}`;
63
+ const phraseParam = `v_phrase_${suffix}`;
64
+ const providerParam = `v_provider_${suffix}`;
65
+ const providerCfgParam = `v_providerConfig_${suffix}`;
66
+ const encodedVar = `__v_encoded_${suffix}`;
67
+ const cypher = [
68
+ `CALL genai.vector.encode($${phraseParam}, $${providerParam}, $${providerCfgParam}) YIELD vector AS ${encodedVar}`,
69
+ `CALL db.index.vector.queryNodes($${nameParam}, $${kParam}, ${encodedVar}) YIELD node AS n, score`,
70
+ ].join('\n');
71
+ const params = {
72
+ [nameParam]: indexName,
73
+ [kParam]: safeK,
74
+ [phraseParam]: phrase,
75
+ [providerParam]: index.provider,
76
+ [providerCfgParam]: providerConfig ?? {},
77
+ };
78
+ return { cypher, params };
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Private helpers
82
+ // ---------------------------------------------------------------------------
83
+ /**
84
+ * Resolve and validate that `indexName` is declared on `nodeDef`. Throws a
85
+ * descriptive `OGMError` listing the available indexes on miss. The index
86
+ * name is also run through `assertSafeIdentifier` as defense in depth —
87
+ * even though it travels through a parameter, validating it here guards
88
+ * against accidental injection if the shape ever changes.
89
+ */
90
+ assertIndexExists(indexName, nodeDef) {
91
+ (0, validation_1.assertSafeIdentifier)(indexName, 'vector index name');
92
+ const indexes = nodeDef.vectorIndexes ?? [];
93
+ const match = indexes.find((idx) => idx.indexName === indexName);
94
+ if (!match) {
95
+ const available = indexes.map((idx) => idx.indexName);
96
+ throw new errors_1.OGMError(`Invalid vector index: "${indexName}" is not defined on ${nodeDef.typeName}. Available: [${available.join(', ')}]`);
97
+ }
98
+ return match;
99
+ }
100
+ }
101
+ exports.VectorCompiler = VectorCompiler;
102
+ /** Validate `k` is a positive integer; clamp to `MAX_K`. */
103
+ function assertValidK(k) {
104
+ if (typeof k !== 'number' || !Number.isFinite(k))
105
+ throw new errors_1.OGMError(`Vector search "k" must be a finite number, got ${k}`);
106
+ if (!Number.isInteger(k))
107
+ throw new errors_1.OGMError(`Vector search "k" must be an integer, got ${k}`);
108
+ if (k < 1)
109
+ throw new errors_1.OGMError(`Vector search "k" must be >= 1, got ${k}`);
110
+ return k > MAX_K ? MAX_K : k;
111
+ }
112
+ /** Validate `vector` is a non-empty array of finite numbers. */
113
+ function assertValidVector(vector) {
114
+ if (!Array.isArray(vector))
115
+ throw new errors_1.OGMError('Vector search "vector" must be a number[]');
116
+ if (vector.length === 0)
117
+ throw new errors_1.OGMError('Vector search "vector" must not be empty');
118
+ for (let i = 0; i < vector.length; i++) {
119
+ const v = vector[i];
120
+ if (typeof v !== 'number' || !Number.isFinite(v))
121
+ throw new errors_1.OGMError(`Vector search "vector" contains a non-finite value at index ${i}`);
122
+ }
123
+ }
124
+ /** Validate `phrase` is a non-empty, non-whitespace string. */
125
+ function assertValidPhrase(phrase) {
126
+ if (typeof phrase !== 'string' || phrase.trim().length === 0)
127
+ throw new errors_1.OGMError('Vector search "phrase" must be a non-empty string');
128
+ }
129
+ //# sourceMappingURL=vector.compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector.compiler.js","sourceRoot":"","sources":["../../../src/compilers/vector.compiler.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../../src/generator/generate-types.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAMD,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAoBD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAgG9B"}
1
+ {"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../../src/generator/generate-types.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAMD,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAoBD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAiG9B"}
@@ -49,6 +49,7 @@ const sort_options_emitter_1 = require("./type-emitters/sort-options-emitter");
49
49
  const aggregation_emitter_1 = require("./type-emitters/aggregation-emitter");
50
50
  const mutation_response_emitter_1 = require("./type-emitters/mutation-response-emitter");
51
51
  const fulltext_emitter_1 = require("./type-emitters/fulltext-emitter");
52
+ const vector_emitter_1 = require("./type-emitters/vector-emitter");
52
53
  const select_fields_emitter_1 = require("./type-emitters/select-fields-emitter");
53
54
  const select_result_emitter_1 = require("./type-emitters/select-result-emitter");
54
55
  const model_map_emitter_1 = require("./type-emitters/model-map-emitter");
@@ -139,6 +140,7 @@ async function generateTypes(options) {
139
140
  (0, aggregation_emitter_1.emitAggregationTypes)(metadata),
140
141
  (0, mutation_response_emitter_1.emitMutationResponseTypes)(metadata),
141
142
  (0, fulltext_emitter_1.emitFulltextTypes)(metadata),
143
+ (0, vector_emitter_1.emitVectorTypes)(metadata),
142
144
  (0, select_fields_emitter_1.emitSelectFieldTypes)(metadata),
143
145
  (0, select_result_emitter_1.emitSelectResultType)(),
144
146
  (0, model_map_emitter_1.emitModelDeclarations)(metadata),
@@ -1 +1 @@
1
- {"version":3,"file":"generate-types.js","sourceRoot":"","sources":["../../../src/generator/generate-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate-types.js","sourceRoot":"","sources":["../../../src/generator/generate-types.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,27 @@
1
- import type { SchemaMetadata } from '../../schema/types';
1
+ import type { SchemaMetadata, NodeDefinition } from '../../schema/types';
2
2
  /**
3
3
  * Emits fulltext-related types for every node that declares at least one
4
- * `@fulltext` index:
4
+ * `@fulltext` index (either directly on the node or on a relationship whose
5
+ * `@relationshipProperties` type has fulltext indexes):
5
6
  *
6
7
  * - `<Node>FulltextResult` — score + the matched node
7
8
  * - `<Node>FulltextWhere` — filtering by score and node-level where
8
9
  * - `<Node>FulltextSort` — sorting by score and node-level sort
10
+ * - `<Node>FulltextLeaf` — per-node leaf with literal index-name keys
11
+ * - `<Node>FulltextInput` — leaf | OR/AND/NOT composition
9
12
  *
10
- * Also emits the shared `FloatWhere` type used for score filtering.
13
+ * Also emits the shared `FloatWhere` and `FulltextIndexEntry` types used by
14
+ * the typed inputs.
11
15
  *
12
- * Returns an empty string when no nodes have fulltext indexes.
16
+ * Returns an empty string when no nodes have fulltext indexes (direct or via
17
+ * a relationship-properties type).
13
18
  */
14
19
  export declare function emitFulltextTypes(schema: SchemaMetadata): string;
20
+ /**
21
+ * Returns true when the node has a node-level fulltext index OR a
22
+ * relationship whose `@relationshipProperties` type has fulltext indexes.
23
+ * Exposed so the model-map emitter can decide whether to override the
24
+ * `fulltext` parameter type on the generated `<Node>Model`.
25
+ */
26
+ export declare function nodeHasAnyFulltext(node: NodeDefinition, schema: SchemaMetadata): boolean;
15
27
  //# sourceMappingURL=fulltext-emitter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fulltext-emitter.d.ts","sourceRoot":"","sources":["../../../../src/generator/type-emitters/fulltext-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,oBAAoB,CAAC;AAMzE;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAchE"}
1
+ {"version":3,"file":"fulltext-emitter.d.ts","sourceRoot":"","sources":["../../../../src/generator/type-emitters/fulltext-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAGf,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA0BhE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAGT"}