grafeo-ogm 2.4.6 → 2.4.8
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/CHANGELOG.md +83 -0
- package/README.md +77 -31
- package/dist/cjs/cli/commands/db-push.d.ts.map +1 -1
- package/dist/cjs/cli/commands/db-push.js +74 -8
- package/dist/cjs/cli/commands/db-push.js.map +1 -1
- package/dist/cjs/cli/commands/db-seed.d.ts.map +1 -1
- package/dist/cjs/cli/commands/db-seed.js +10 -1
- package/dist/cjs/cli/commands/db-seed.js.map +1 -1
- package/dist/cjs/cli/introspect.d.ts +2 -2
- package/dist/cjs/cli/introspect.d.ts.map +1 -1
- package/dist/cjs/cli/introspect.js +70 -3
- package/dist/cjs/cli/introspect.js.map +1 -1
- package/dist/cjs/cli/push-planner.d.ts +61 -2
- package/dist/cjs/cli/push-planner.d.ts.map +1 -1
- package/dist/cjs/cli/push-planner.js +182 -17
- package/dist/cjs/cli/push-planner.js.map +1 -1
- package/dist/cjs/compilers/fulltext.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/fulltext.compiler.js +5 -1
- package/dist/cjs/compilers/fulltext.compiler.js.map +1 -1
- package/dist/cjs/compilers/mutation.compiler.d.ts +107 -1
- package/dist/cjs/compilers/mutation.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/mutation.compiler.js +647 -380
- package/dist/cjs/compilers/mutation.compiler.js.map +1 -1
- package/dist/cjs/compilers/select-normalizer.d.ts.map +1 -1
- package/dist/cjs/compilers/select-normalizer.js +12 -1
- package/dist/cjs/compilers/select-normalizer.js.map +1 -1
- package/dist/cjs/compilers/selection.compiler.d.ts +40 -0
- package/dist/cjs/compilers/selection.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/selection.compiler.js +123 -21
- package/dist/cjs/compilers/selection.compiler.js.map +1 -1
- package/dist/cjs/compilers/where.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/where.compiler.js +36 -15
- package/dist/cjs/compilers/where.compiler.js.map +1 -1
- package/dist/cjs/execution/executor.d.ts +34 -9
- package/dist/cjs/execution/executor.d.ts.map +1 -1
- package/dist/cjs/execution/executor.js +42 -5
- package/dist/cjs/execution/executor.js.map +1 -1
- package/dist/cjs/execution/result-mapper.d.ts.map +1 -1
- package/dist/cjs/execution/result-mapper.js +4 -2
- package/dist/cjs/execution/result-mapper.js.map +1 -1
- package/dist/cjs/generator/generate-types.d.ts.map +1 -1
- package/dist/cjs/generator/generate-types.js +76 -0
- package/dist/cjs/generator/generate-types.js.map +1 -1
- package/dist/cjs/generator/type-emitters/aggregation-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/aggregation-emitter.js +19 -7
- package/dist/cjs/generator/type-emitters/aggregation-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/input-emitter.js +13 -4
- package/dist/cjs/generator/type-emitters/input-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts +1 -0
- package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/model-map-emitter.js +5 -20
- package/dist/cjs/generator/type-emitters/model-map-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/node-type-emitter.d.ts +3 -0
- package/dist/cjs/generator/type-emitters/node-type-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/node-type-emitter.js +6 -11
- package/dist/cjs/generator/type-emitters/node-type-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/select-fields-emitter.js +21 -2
- package/dist/cjs/generator/type-emitters/select-fields-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/where-emitter.js +3 -3
- package/dist/cjs/generator/type-emitters/where-emitter.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/interface-model.d.ts.map +1 -1
- package/dist/cjs/interface-model.js +6 -0
- package/dist/cjs/interface-model.js.map +1 -1
- package/dist/cjs/model.d.ts.map +1 -1
- package/dist/cjs/model.js +6 -0
- package/dist/cjs/model.js.map +1 -1
- package/dist/cjs/ogm.d.ts +22 -2
- package/dist/cjs/ogm.d.ts.map +1 -1
- package/dist/cjs/ogm.js +42 -5
- package/dist/cjs/ogm.js.map +1 -1
- package/dist/cjs/policy/nested-writes.d.ts.map +1 -1
- package/dist/cjs/policy/nested-writes.js +40 -20
- package/dist/cjs/policy/nested-writes.js.map +1 -1
- package/dist/cjs/schema/parser.d.ts.map +1 -1
- package/dist/cjs/schema/parser.js +94 -16
- package/dist/cjs/schema/parser.js.map +1 -1
- package/dist/cjs/schema/types.d.ts +1 -1
- package/dist/cjs/schema/types.d.ts.map +1 -1
- package/dist/cjs/testing/cypher-assert.d.ts.map +1 -1
- package/dist/cjs/testing/cypher-assert.js +25 -2
- package/dist/cjs/testing/cypher-assert.js.map +1 -1
- package/dist/cjs/testing/neo4j-record-factory.d.ts +25 -2
- package/dist/cjs/testing/neo4j-record-factory.d.ts.map +1 -1
- package/dist/cjs/testing/neo4j-record-factory.js +82 -3
- package/dist/cjs/testing/neo4j-record-factory.js.map +1 -1
- package/dist/cjs/utils/cypher-field-projection.d.ts +31 -3
- package/dist/cjs/utils/cypher-field-projection.d.ts.map +1 -1
- package/dist/cjs/utils/cypher-field-projection.js +59 -7
- package/dist/cjs/utils/cypher-field-projection.js.map +1 -1
- package/dist/cjs/utils/write-coercion.d.ts +18 -0
- package/dist/cjs/utils/write-coercion.d.ts.map +1 -1
- package/dist/cjs/utils/write-coercion.js +74 -1
- package/dist/cjs/utils/write-coercion.js.map +1 -1
- package/dist/esm/cli/commands/db-push.d.ts.map +1 -1
- package/dist/esm/cli/commands/db-push.js +74 -8
- package/dist/esm/cli/commands/db-push.js.map +1 -1
- package/dist/esm/cli/commands/db-seed.d.ts.map +1 -1
- package/dist/esm/cli/commands/db-seed.js +10 -1
- package/dist/esm/cli/commands/db-seed.js.map +1 -1
- package/dist/esm/cli/introspect.d.ts +2 -2
- package/dist/esm/cli/introspect.d.ts.map +1 -1
- package/dist/esm/cli/introspect.js +70 -3
- package/dist/esm/cli/introspect.js.map +1 -1
- package/dist/esm/cli/push-planner.d.ts +61 -2
- package/dist/esm/cli/push-planner.d.ts.map +1 -1
- package/dist/esm/cli/push-planner.js +183 -18
- package/dist/esm/cli/push-planner.js.map +1 -1
- package/dist/esm/compilers/fulltext.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/fulltext.compiler.js +5 -1
- package/dist/esm/compilers/fulltext.compiler.js.map +1 -1
- package/dist/esm/compilers/mutation.compiler.d.ts +107 -1
- package/dist/esm/compilers/mutation.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/mutation.compiler.js +644 -380
- package/dist/esm/compilers/mutation.compiler.js.map +1 -1
- package/dist/esm/compilers/select-normalizer.d.ts.map +1 -1
- package/dist/esm/compilers/select-normalizer.js +12 -1
- package/dist/esm/compilers/select-normalizer.js.map +1 -1
- package/dist/esm/compilers/selection.compiler.d.ts +40 -0
- package/dist/esm/compilers/selection.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/selection.compiler.js +123 -21
- package/dist/esm/compilers/selection.compiler.js.map +1 -1
- package/dist/esm/compilers/where.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/where.compiler.js +37 -16
- package/dist/esm/compilers/where.compiler.js.map +1 -1
- package/dist/esm/execution/executor.d.ts +34 -9
- package/dist/esm/execution/executor.d.ts.map +1 -1
- package/dist/esm/execution/executor.js +41 -5
- package/dist/esm/execution/executor.js.map +1 -1
- package/dist/esm/execution/result-mapper.d.ts.map +1 -1
- package/dist/esm/execution/result-mapper.js +4 -2
- package/dist/esm/execution/result-mapper.js.map +1 -1
- package/dist/esm/generator/generate-types.d.ts.map +1 -1
- package/dist/esm/generator/generate-types.js +76 -0
- package/dist/esm/generator/generate-types.js.map +1 -1
- package/dist/esm/generator/type-emitters/aggregation-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/aggregation-emitter.js +19 -7
- package/dist/esm/generator/type-emitters/aggregation-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/input-emitter.js +13 -4
- package/dist/esm/generator/type-emitters/input-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/model-map-emitter.d.ts +1 -0
- package/dist/esm/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/model-map-emitter.js +5 -20
- package/dist/esm/generator/type-emitters/model-map-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/node-type-emitter.d.ts +3 -0
- package/dist/esm/generator/type-emitters/node-type-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/node-type-emitter.js +6 -11
- package/dist/esm/generator/type-emitters/node-type-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/select-fields-emitter.js +21 -2
- package/dist/esm/generator/type-emitters/select-fields-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/where-emitter.js +3 -3
- package/dist/esm/generator/type-emitters/where-emitter.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/interface-model.d.ts.map +1 -1
- package/dist/esm/interface-model.js +6 -0
- package/dist/esm/interface-model.js.map +1 -1
- package/dist/esm/model.d.ts.map +1 -1
- package/dist/esm/model.js +6 -0
- package/dist/esm/model.js.map +1 -1
- package/dist/esm/ogm.d.ts +22 -2
- package/dist/esm/ogm.d.ts.map +1 -1
- package/dist/esm/ogm.js +43 -6
- package/dist/esm/ogm.js.map +1 -1
- package/dist/esm/policy/nested-writes.d.ts.map +1 -1
- package/dist/esm/policy/nested-writes.js +40 -20
- package/dist/esm/policy/nested-writes.js.map +1 -1
- package/dist/esm/schema/parser.d.ts.map +1 -1
- package/dist/esm/schema/parser.js +94 -16
- package/dist/esm/schema/parser.js.map +1 -1
- package/dist/esm/schema/types.d.ts +1 -1
- package/dist/esm/schema/types.d.ts.map +1 -1
- package/dist/esm/testing/cypher-assert.d.ts.map +1 -1
- package/dist/esm/testing/cypher-assert.js +25 -2
- package/dist/esm/testing/cypher-assert.js.map +1 -1
- package/dist/esm/testing/neo4j-record-factory.d.ts +25 -2
- package/dist/esm/testing/neo4j-record-factory.d.ts.map +1 -1
- package/dist/esm/testing/neo4j-record-factory.js +82 -3
- package/dist/esm/testing/neo4j-record-factory.js.map +1 -1
- package/dist/esm/utils/cypher-field-projection.d.ts +31 -3
- package/dist/esm/utils/cypher-field-projection.d.ts.map +1 -1
- package/dist/esm/utils/cypher-field-projection.js +58 -7
- package/dist/esm/utils/cypher-field-projection.js.map +1 -1
- package/dist/esm/utils/write-coercion.d.ts +18 -0
- package/dist/esm/utils/write-coercion.d.ts.map +1 -1
- package/dist/esm/utils/write-coercion.js +73 -1
- package/dist/esm/utils/write-coercion.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.4.8 (2026-10-18) — bug-scan fixes across reads, writes, codegen, CLI and testing helpers
|
|
4
|
+
|
|
5
|
+
> **A large patch release. Upgrading is safe, with no breaking changes.** Most of these bugs were found by a third, multi-area bug scan. Each fix was reproduced on Neo4j 5.26 before it was fixed, and is pinned by a regression test, live wherever behaviour depends on the server. The breaking fixes from the same scan ship separately in **2.5.0**. Cypher for queries the fixes don't touch is unchanged; the policy byte-identical suite pins this.
|
|
6
|
+
|
|
7
|
+
### Reads
|
|
8
|
+
|
|
9
|
+
- **`_SINGLE` and `Connection_SINGLE` filters work.** Every `_SINGLE` form failed on Neo4j with `Invalid input 'WHERE'`, because of an extra parenthesis around the pattern comprehension. That covered relationship, interface, union and connection filters. They now compile to `size([pattern WHERE … | x]) = 1`. The target type's `read` policy stays inside the comprehension, so `_SINGLE` counts only nodes the caller can see.
|
|
10
|
+
- **Relationship-index fulltext returns each node once.** A search on a relationship index returned a node once per matching relationship, which inflated `count` and made `limit` pages come up short. Results are now grouped per node with the best score. This also works inside `AND`, `OR` and `NOT`.
|
|
11
|
+
- **Connection `totalCount` is returned.** It was declared on connection types but always came back `undefined`. It is now the size of the same filtered comprehension `edges` uses, so it honours the connection `where` and the target `read` policy. Selecting only `totalCount` returns `{ totalCount }`, and the generated connection `SelectFields` now offer it.
|
|
12
|
+
- **Implementer `@cypher` fields resolve in inline fragments.** `InterfaceModel.find({ selectionSet: '{ id ... on Doc { dcount } }' })` used to return `dcount: null`. Fragment fields now project per type: `CASE WHEN n:Doc THEN … END`.
|
|
13
|
+
- **Typed `select` keeps scalars whose names end in `Connection`.** A scalar such as `internetConnection: String` was silently dropped. A `*Connection` key is now treated as a connection only when its base name is a relationship.
|
|
14
|
+
- **BigInt, DateTime and list where filters match.** These used to silently match nothing:
|
|
15
|
+
- a BigInt filter given a string (its generated input type) or a `bigint`
|
|
16
|
+
- a DateTime filter given a JS `Date`
|
|
17
|
+
- equality, `_NOT` or `_IN` on a temporal **list** field
|
|
18
|
+
|
|
19
|
+
Values are now bound in the stored representation. Case-insensitive mode on a list field used to emit `toLower(list)`, a Cypher type error. It now lowercases element-wise for equality and `_NOT`, and leaves `_IN` case-sensitive.
|
|
20
|
+
- **Nested relationship `orderBy` sorts.** `select: { friends: { select: { id: true }, orderBy: { rank: 'DESC' } } }` sorted maps that didn't contain the sort key. It now sorts on injected keys, as connection `orderBy` does. This needs APOC and is verified by the emitted Cypher's shape.
|
|
21
|
+
- **Point `srid` is a number** on the driver's default lossless integers. It used to come back as `{ low, high }`.
|
|
22
|
+
- **Clear errors instead of wrong results:**
|
|
23
|
+
- Selecting an **aggregating** `@cypher` field (e.g. `RETURN count(p)`) **through a relationship** now throws an `OGMError` naming the field. Neo4j 5 rejects aggregation inside a projection, and no rewrite parses. Top-level selection still works.
|
|
24
|
+
- `aggregate` on a `@cypher` field now throws instead of returning null min/max/average and a sum of 0.
|
|
25
|
+
|
|
26
|
+
### Writes
|
|
27
|
+
|
|
28
|
+
- **Nested writes on interface relationships run.** A nested `connect`, `create`, `update`, `disconnect` or `delete` on an interface-typed relationship was skipped without an error. It now runs, keyed by implementer (`pets: { Dog: { create: [...] } }`) or flat. A flat nested create names its implementer: `node: { Dog: {...} }`. Each implementer's policies apply. Inputs that can't be resolved now throw `OGMError` instead of being ignored.
|
|
29
|
+
- **Top-level `connect` and `disconnect` work on interface and union relationships.** They matched the abstract type's label, which no node carries, so nothing changed. Per-member union input was also never unwrapped. Both now match the members' own labels and apply each member's `read` policy. A blanket disconnect keyed by one union member now unlinks only that member, not every member.
|
|
30
|
+
- **Array `connect` with a bare-property `where` links.** `connect: { posts: [{ where: { title: 'a' } }] }`, with no `node:` wrapper, used to link nothing.
|
|
31
|
+
- **A connect nested in a connect item, and a disconnect nested in a disconnect item, run.** They used to be dropped, at the top level, inside `create` and inside nested `update`. Every level applies its target type's `read` policy. Nesting is capped at 5 levels.
|
|
32
|
+
- **`upsert` rejects relationship fields** in `create` / `update` with an `OGMError`. They used to be ignored, so their nested ops never ran.
|
|
33
|
+
|
|
34
|
+
### Schema and generated types
|
|
35
|
+
|
|
36
|
+
- **`@relationship(direction:)` is validated.** A direction other than exactly `IN` or `OUT`, such as `"out"`, was accepted. Reads treated it as OUT and writes as IN, so edges were written reversed and couldn't be read back. It's now a schema error that names the field.
|
|
37
|
+
- **List `@default` values work.** `@default(value: [RED, GREEN])` used to be ignored. They're now stored with native element types. A list default on a non-list field is a schema error.
|
|
38
|
+
- **`@declareRelationship` interface relationships work.** They parsed with an empty relationship type, so every operator on them threw `Invalid identifier ""`. The type, direction and properties now come from the implementors, and implementors that disagree are a schema error.
|
|
39
|
+
- **Generated types match the runtime:**
|
|
40
|
+
- scalar `@cypher` fields are selectable in `<T>SelectFields`
|
|
41
|
+
- required fields with `@default` are optional in `CreateInput`
|
|
42
|
+
- `IdAggregateSelection` and `StringAggregateSelection` are `{ min, max }`, not `{ shortest, longest }`
|
|
43
|
+
- interfaces are no longer in `ModelMap`, where `ogm.model('<Interface>')` type-checked but always threw
|
|
44
|
+
- unsupported `<rel>Aggregate` fields and where keys are no longer generated; the old aggregation types remain, deprecated
|
|
45
|
+
- **Colliding generated type names fail at generation time.** For example, `User.postComments` and `UserPost.comments` both produce `UserPostCommentsConnectionWhere`, which used to make the generated file fail to compile. Generation now fails with an error that lists each duplicate and its sources.
|
|
46
|
+
|
|
47
|
+
### CLI and execution
|
|
48
|
+
|
|
49
|
+
- **`grafeo db push` reports changed index definitions.** Changing a fulltext index's fields, or a vector index's dimensions or similarity, used to print "No changes". Push now reports a **changed** bucket saying the schema is NOT in sync. It recreates those indexes only under `--force-drop`, with the usual consent rules.
|
|
50
|
+
- **`grafeo db push` output is accurate:**
|
|
51
|
+
- It no longer claims "created X" when an equivalent constraint already exists under another name; that one is reported as `X covered by <name>`.
|
|
52
|
+
- A conflicting RANGE index is reported instead of crashing the push.
|
|
53
|
+
- In-sync constraints are no longer listed as "Unmanaged".
|
|
54
|
+
- **`grafeo db seed` honours `--database`, `database.database` and `NEO4J_DATABASE`.** It used to seed the default database regardless. The new optional **`OGMConfig.database`** sends every session the OGM opens to that database. Without it, nothing changes.
|
|
55
|
+
- **Transaction audit metadata is no longer dropped silently.** Driver 5.x transactions have no `setMetaData`, so policy audit metadata for calls inside a transaction, including `unsafe.bypassPolicies` audits, never reached the server. Per-call metadata still can't be attached to an open transaction, but each such call now logs a `warn`. The new `ogm.$transaction(fn, { metadata })` attaches metadata when the transaction begins, and its `TransactionOptions` type is exported.
|
|
56
|
+
- **`Executor.debug = true` no longer breaks queries with `bigint` params.** This includes `$queryRaw` and `$executeRaw`.
|
|
57
|
+
|
|
58
|
+
### Testing helpers
|
|
59
|
+
|
|
60
|
+
- **`Neo4jRecordFactory.dateTime` keeps the offset, nanoseconds and zone id.** It converted values to UTC and cut the fraction to milliseconds. It now matches what the real driver returns.
|
|
61
|
+
- **`CypherAssert.assertParams` ignores key order and compares bigints.** A bigint param used to throw.
|
|
62
|
+
- **`Neo4jRecordFactory.node` takes `{ identity?, elementId? }`**, so mock nodes can have distinct ids.
|
|
63
|
+
|
|
64
|
+
### Docs
|
|
65
|
+
|
|
66
|
+
- `@id` does **not** create a unique constraint; only `@unique` does. Use `@id @unique` to have the database enforce uniqueness.
|
|
67
|
+
- The README Interfaces example is now valid GraphQL (directives go after `implements`).
|
|
68
|
+
- The Testing Utilities section documents the real API.
|
|
69
|
+
- The directive table covers `@declareRelationship`, the `IN`/`OUT` rule and list defaults.
|
|
70
|
+
|
|
71
|
+
## 2.4.7 (2026-10-18) — `db push --force-drop` only drops constraints grafeo created
|
|
72
|
+
|
|
73
|
+
### 🐛 `--force-drop` could drop constraints on labels grafeo doesn't manage
|
|
74
|
+
|
|
75
|
+
`db push` decided whether a live constraint was grafeo's from its **name alone**: any name that started with a known label and ended in `_unique` qualified. With `type Book` in the SDL, a DBA's `Book_Archive_code_unique` constraint on the **unrelated** label `Book_Archive` looked like "label `Book`, property `Archive_code`". `db push --force-drop --yes` then dropped it. A NODE KEY or existence constraint that happened to share the naming shape qualified too.
|
|
76
|
+
|
|
77
|
+
A constraint is now treated as a droppable orphan only when its **definition** proves grafeo would have created it:
|
|
78
|
+
|
|
79
|
+
- the type is `UNIQUENESS`
|
|
80
|
+
- it covers exactly one label, and that label is in the schema
|
|
81
|
+
- it covers exactly one property
|
|
82
|
+
- its name is exactly `{Label}_{prop}_unique` for that label and property
|
|
83
|
+
|
|
84
|
+
`db push` now reads `labelsOrTypes` and `properties` from `SHOW CONSTRAINTS` to check this. If a server doesn't report those columns, nothing is treated as droppable: a missed orphan only means "kept", while a wrong drop can lose a constraint. The set of constraints `--force-drop` can drop only ever shrinks.
|
|
85
|
+
|
|
3
86
|
## 2.4.6 (2026-10-18) — `createMany` writes every item's fields
|
|
4
87
|
|
|
5
88
|
### 🐛 `createMany` took its columns from the first item only
|
package/README.md
CHANGED
|
@@ -309,7 +309,7 @@ npx grafeo generate --verify # CI gate: exit 1 if the file on disk is stale
|
|
|
309
309
|
|
|
310
310
|
### `grafeo db push`
|
|
311
311
|
|
|
312
|
-
Synchronizes the **constraints and indexes** your SDL declares (`@
|
|
312
|
+
Synchronizes the **constraints and indexes** your SDL declares (`@unique` → unique constraints, `@fulltext` → fulltext indexes, `@vector` → vector indexes) with the live database. Constraints and indexes only — **not data**. (`db push` is deliberately scoped; use a dedicated migration tool for data.) `@id` alone creates **no** constraint: it only generates a UUID on create. Add `@unique` (`id: ID! @id @unique`) to have the database enforce uniqueness.
|
|
313
313
|
|
|
314
314
|
```bash
|
|
315
315
|
npx grafeo db push --dry-run # preview the plan — DO THIS FIRST
|
|
@@ -317,19 +317,22 @@ npx grafeo db push # apply (additive: creates only what's mis
|
|
|
317
317
|
npx grafeo db push --force-drop --yes # also drop orphaned grafeo-managed items
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
-
`db push` introspects `SHOW CONSTRAINTS` / `SHOW INDEXES`, diffs against your SDL, and prints a plan in
|
|
320
|
+
`db push` introspects `SHOW CONSTRAINTS` / `SHOW INDEXES`, diffs against your SDL, and prints a plan in five buckets:
|
|
321
321
|
|
|
322
322
|
- **create** — declared in SDL, missing in the database
|
|
323
|
-
- **in sync** — already present
|
|
323
|
+
- **in sync** — already present with the declared definition. A unique constraint is also in sync when an equivalent constraint (same label and property) exists under another name, such as one a DBA created; push prints `X covered by <name>` instead of creating it. Before v2.4.8 push printed "created X" on every run while Neo4j created nothing.
|
|
324
|
+
- **changed** — an index present under the SDL name whose definition differs (fulltext fields or label, vector dimensions or similarity, index type). The output says the schema is **NOT in sync**; the index is **kept as-is** unless you pass `--force-drop`, which drops and recreates it under the same consent rules as orphans. Before v2.4.8 indexes were matched by name only, so a changed definition was reported as in sync and never applied.
|
|
324
325
|
- **orphans** — grafeo-named (`{Label}_{prop}_unique`) constraints no longer in your SDL; **reported and kept** unless you pass `--force-drop`
|
|
325
326
|
- **unmanaged** — constraints/indexes that don't follow grafeo's naming convention (hand-created DBA indexes, etc.); **never touched, never counted as drift**
|
|
326
327
|
|
|
327
|
-
|
|
328
|
+
If a plain RANGE index already covers a property you mark `@unique`, Neo4j refuses the constraint until that index is dropped. Push reports this as a warning (the index isn't grafeo's, so it is never dropped) and applies the rest of the plan; before v2.4.8 the push crashed with exit 1. "created X" is printed only when Neo4j reports that something was added.
|
|
329
|
+
|
|
330
|
+
It is **additive by default** and **idempotent** — a second run with no schema change is a no-op. Dropping orphans and recreating changed indexes is destructive and gated: `--force-drop` lists the exact drops (shown in `--dry-run` too) and requires interactive confirmation, or `--yes` in non-interactive sessions like CI.
|
|
328
331
|
|
|
329
332
|
| Flag | Description |
|
|
330
333
|
|---|---|
|
|
331
334
|
| `--dry-run` | Print the full plan (including the exact Cypher, drops included) and exit without writing |
|
|
332
|
-
| `--force-drop` | Permit dropping orphaned grafeo-managed constraints/indexes |
|
|
335
|
+
| `--force-drop` | Permit dropping orphaned grafeo-managed constraints/indexes, and dropping + recreating indexes whose definition changed |
|
|
333
336
|
| `--yes` | Confirm destructive drops non-interactively (required with `--force-drop` in CI) |
|
|
334
337
|
| `--schema <path>`, `--uri`, `--username`, `--database` | Schema path and connection overrides |
|
|
335
338
|
|
|
@@ -358,7 +361,7 @@ export default async function seed(ogm: OGM) {
|
|
|
358
361
|
npx grafeo db seed
|
|
359
362
|
```
|
|
360
363
|
|
|
361
|
-
grafeo does not enforce idempotency — use `upsert` so re-running the seed is safe. Connection and schema resolve exactly as for `db push
|
|
364
|
+
grafeo does not enforce idempotency — use `upsert` so re-running the seed is safe. Connection and schema resolve exactly as for `db push`, including the database (`--database` > `database.database` > `NEO4J_DATABASE`). Before v2.4.8 `db seed` ignored the database setting and always seeded the server's default database.
|
|
362
365
|
|
|
363
366
|
---
|
|
364
367
|
|
|
@@ -394,13 +397,14 @@ grafeo-ogm uses standard GraphQL SDL with Neo4j directives to define your graph
|
|
|
394
397
|
|
|
395
398
|
| Directive | Target | Description |
|
|
396
399
|
|---|---|---|
|
|
397
|
-
| `@node` | Type | Marks a type as a Neo4j node. Optional `labels` argument for multi-label nodes |
|
|
398
|
-
| `@relationship` | Field | Defines a relationship with `type`, `direction` (`IN
|
|
400
|
+
| `@node` | Type | Marks a type as a Neo4j node. Optional `labels` argument for multi-label nodes (implementors of an interface must include the interface name, see [Interfaces](#interfaces)) |
|
|
401
|
+
| `@relationship` | Field | Defines a relationship with `type`, `direction` (exactly `IN` or `OUT`; anything else is a schema error), and optional `properties` |
|
|
402
|
+
| `@declareRelationship` | Interface field | Declares a relationship on an interface. Its `type`, `direction` and `properties` come from the implementors' `@relationship`, which must all agree |
|
|
399
403
|
| `@relationshipProperties` | Type | Marks a type as relationship properties (edge data) |
|
|
400
|
-
| `@id` | Field | Auto-generates a UUID on create |
|
|
404
|
+
| `@id` | Field | Auto-generates a UUID on create (creates no constraint — add `@unique` for one) |
|
|
401
405
|
| `@unique` | Field | Creates a uniqueness constraint in Neo4j |
|
|
402
406
|
| `@cypher` | Field | Computed field resolved via a custom Cypher statement. Scalar return types are resolved at runtime in `select` / `selectionSet`, `where`, and `options.sort` (see [Computed Fields with @cypher](#computed-fields-with-cypher)); node/interface return types remain projection-only |
|
|
403
|
-
| `@default` | Field | Sets a default value on create |
|
|
407
|
+
| `@default` | Field | Sets a default `value` on create (scalar, enum, or a list of them for list fields). A required field with a default is optional in the generated `CreateInput` |
|
|
404
408
|
| `@fulltext` | Type | Defines fulltext search indexes with `name` and `fields` |
|
|
405
409
|
| `@vector` | Type | Registers one or more Neo4j vector indexes on a node (see [Vector Search](#vector-search)) |
|
|
406
410
|
|
|
@@ -450,26 +454,38 @@ type HasReview @relationshipProperties {
|
|
|
450
454
|
### Interfaces
|
|
451
455
|
|
|
452
456
|
```graphql
|
|
453
|
-
interface Entity
|
|
454
|
-
id: ID!
|
|
457
|
+
interface Entity {
|
|
458
|
+
id: ID!
|
|
455
459
|
name: String!
|
|
460
|
+
resources: [Resource!]! @declareRelationship
|
|
456
461
|
}
|
|
457
462
|
|
|
458
|
-
type User @node implements Entity
|
|
463
|
+
# Directives go after `implements` — `type User @node implements Entity` is
|
|
464
|
+
# not valid GraphQL.
|
|
465
|
+
type User implements Entity @node(labels: ["User", "Entity"]) {
|
|
459
466
|
id: ID! @id
|
|
460
467
|
name: String!
|
|
461
468
|
email: String!
|
|
469
|
+
resources: [Resource!]! @relationship(type: "OWNS", direction: OUT)
|
|
462
470
|
}
|
|
463
471
|
|
|
464
|
-
type Organization @node
|
|
472
|
+
type Organization implements Entity @node(labels: ["Organization", "Entity"]) {
|
|
465
473
|
id: ID! @id
|
|
466
474
|
name: String!
|
|
467
475
|
website: String
|
|
476
|
+
resources: [Resource!]! @relationship(type: "OWNS", direction: OUT)
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
type Resource @node {
|
|
480
|
+
id: ID! @id
|
|
468
481
|
}
|
|
469
482
|
```
|
|
470
483
|
|
|
471
484
|
Interface types can be queried polymorphically via `ogm.interfaceModel('Entity')`. Results include `__typename` to discriminate concrete types.
|
|
472
485
|
|
|
486
|
+
- The interface model matches nodes by the **interface label** (`MATCH (n:Entity)`), so every implementor must carry it: list the interface name in `@node(labels: [...])`. An implementor declared with a bare `@node` is stored with only its own label and never appears in interface queries.
|
|
487
|
+
- A `@declareRelationship` field takes its relationship `type`, `direction` and `properties` from the implementors. They must all declare the same ones; if they disagree, or an implementor has no `@relationship` on that field, `parseSchema` throws.
|
|
488
|
+
|
|
473
489
|
### Enums
|
|
474
490
|
|
|
475
491
|
```graphql
|
|
@@ -1355,6 +1371,8 @@ When `policies` is configured, every OGM-emitted query attaches transaction meta
|
|
|
1355
1371
|
|
|
1356
1372
|
Disable via `policyDefaults: { auditMetadata: false }`. The fingerprint is intentionally key-only — no ctx values are leaked.
|
|
1357
1373
|
|
|
1374
|
+
> **Inside a transaction the per-call audit metadata does not reach the server.** neo4j-driver accepts transaction metadata only when a transaction begins, so it is attached on the OGM's own auto-commit sessions and on a caller-supplied `session`, but not to a call that runs in an already-open transaction (`$transaction`, an explicit `beginTransaction()` tx, or an `executeRead`/`executeWrite` managed tx). Since v2.4.8 each such call logs a `warn` instead of dropping the metadata silently; before v2.4.8 the docs claimed it was forwarded. To tag the transaction itself, pass metadata when it opens: `ogm.$transaction(fn, { metadata })`, `session.beginTransaction({ metadata })`, or `session.executeWrite(fn, { metadata })`.
|
|
1375
|
+
|
|
1358
1376
|
`policiesEvaluated` lists only the policies that **applied** to the query. A restrictive whose `appliesWhen(ctx)` returned `false` is omitted (before v2.2.0 it was listed even though it contributed nothing). `explainPolicies` calls add `explain: true` and are always recorded, even with `auditMetadata: false`.
|
|
1359
1377
|
|
|
1360
1378
|
#### Explaining policy decisions
|
|
@@ -1446,8 +1464,19 @@ const [books, authors] = await ogm.$transaction([
|
|
|
1446
1464
|
(ctx) => Book.find({ select: { id: true } }, { context: ctx }),
|
|
1447
1465
|
(ctx) => Author.find({ select: { id: true } }, { context: ctx }),
|
|
1448
1466
|
]);
|
|
1467
|
+
|
|
1468
|
+
// Transaction metadata (v2.4.8) — sent to the server when the tx begins,
|
|
1469
|
+
// visible in SHOW TRANSACTIONS and the query log
|
|
1470
|
+
await ogm.$transaction(
|
|
1471
|
+
async (ctx) => {
|
|
1472
|
+
/* ... */
|
|
1473
|
+
},
|
|
1474
|
+
{ metadata: { job: 'nightly-import' } },
|
|
1475
|
+
);
|
|
1449
1476
|
```
|
|
1450
1477
|
|
|
1478
|
+
Per-call policy audit metadata cannot be attached once a transaction is open; see [Audit metadata](#audit-metadata).
|
|
1479
|
+
|
|
1451
1480
|
### Interface Models
|
|
1452
1481
|
|
|
1453
1482
|
Query across all types implementing a shared interface:
|
|
@@ -1731,25 +1760,42 @@ import {
|
|
|
1731
1760
|
|
|
1732
1761
|
### CypherAssert
|
|
1733
1762
|
|
|
1734
|
-
Assert Cypher
|
|
1763
|
+
Assert on compiled Cypher and its parameters:
|
|
1735
1764
|
|
|
1736
1765
|
```typescript
|
|
1737
|
-
//
|
|
1738
|
-
CypherAssert.
|
|
1766
|
+
// Equal after collapsing whitespace and renaming params to $p0, $p1, …
|
|
1767
|
+
CypherAssert.assertStructurallyEqual(cypher, 'MATCH (n:`Book`) RETURN n');
|
|
1768
|
+
|
|
1769
|
+
// A clause is present and contains a fragment
|
|
1770
|
+
CypherAssert.assertContainsClause(cypher, 'WHERE', 'n.price');
|
|
1739
1771
|
|
|
1740
|
-
//
|
|
1772
|
+
// A fragment is absent
|
|
1773
|
+
CypherAssert.assertNotContainsClause(cypher, 'DELETE');
|
|
1774
|
+
|
|
1775
|
+
// Only the listed keys are checked. Object key order doesn't matter;
|
|
1776
|
+
// bigints compare by value, and a neo4j Integer never equals a plain number.
|
|
1741
1777
|
CypherAssert.assertParams(params, { param0: 'Graph Databases' });
|
|
1742
1778
|
```
|
|
1743
1779
|
|
|
1744
1780
|
### Neo4jRecordFactory
|
|
1745
1781
|
|
|
1746
|
-
Build mock Neo4j
|
|
1782
|
+
Build mock Neo4j values for unit tests without a running database:
|
|
1747
1783
|
|
|
1748
1784
|
```typescript
|
|
1749
|
-
const
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1785
|
+
const record = Neo4jRecordFactory.create({ title: 'Test Book', count: 2 });
|
|
1786
|
+
const count = Neo4jRecordFactory.integer(42);
|
|
1787
|
+
|
|
1788
|
+
// Same fields and toString() as the driver's datetime($iso): the offset,
|
|
1789
|
+
// all nine fractional digits and an [Area/City] zone id are kept (v2.4.8).
|
|
1790
|
+
const dt = Neo4jRecordFactory.dateTime('2024-01-01T10:00:00.123456789+02:00');
|
|
1791
|
+
|
|
1792
|
+
// Properties are stored as given; use integer() where the driver would
|
|
1793
|
+
// return an Integer. The third argument (v2.4.8) sets identity / elementId.
|
|
1794
|
+
const node = Neo4jRecordFactory.node(
|
|
1795
|
+
['Book'],
|
|
1796
|
+
{ title: 'Mock', pages: Neo4jRecordFactory.integer(300) },
|
|
1797
|
+
{ identity: 1, elementId: '4:test:1' },
|
|
1798
|
+
);
|
|
1753
1799
|
```
|
|
1754
1800
|
|
|
1755
1801
|
### SelectionSetFactory
|
|
@@ -1757,11 +1803,11 @@ const records = Neo4jRecordFactory.create([
|
|
|
1757
1803
|
Build selection sets programmatically:
|
|
1758
1804
|
|
|
1759
1805
|
```typescript
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
}
|
|
1806
|
+
SelectionSetFactory.gql(['id', 'title', { author: ['name'] }]);
|
|
1807
|
+
// => '{ id title author { name } }'
|
|
1808
|
+
|
|
1809
|
+
SelectionSetFactory.select(['id', 'title', { author: ['name'] }]);
|
|
1810
|
+
// => { id: true, title: true, author: { select: { name: true } } }
|
|
1765
1811
|
```
|
|
1766
1812
|
|
|
1767
1813
|
---
|
|
@@ -1932,7 +1978,7 @@ Yes — `ogm.$transaction(async (ctx) => { ... })` runs multiple operations atom
|
|
|
1932
1978
|
|
|
1933
1979
|
### Does it support multi-database / multi-tenant Neo4j setups?
|
|
1934
1980
|
|
|
1935
|
-
Yes —
|
|
1981
|
+
Yes — instantiate one OGM per database with `new OGM({ typeDefs, driver, database: 'tenant-a' })` (v2.4.8); every session the OGM opens then targets that database. Alternatively, open the session or transaction yourself (`driver.session({ database })`) and pass it via `{ context: { session } }` / `{ context: { transaction } }`. (Before v2.4.8 this answer claimed a per-query `database` option on `ExecutionContext`; there is none.) Multi-label nodes (`@node(labels: [...])`) handle a different multi-tenant pattern where tenants share a graph but have isolated label sets.
|
|
1936
1982
|
|
|
1937
1983
|
### What's the performance overhead vs. raw Cypher?
|
|
1938
1984
|
|
|
@@ -1954,12 +2000,12 @@ Open an issue on [GitHub](https://github.com/neomodular/grafeo-ogm/issues). For
|
|
|
1954
2000
|
|
|
1955
2001
|
| Method | Description |
|
|
1956
2002
|
|---|---|
|
|
1957
|
-
| `new OGM(config)` | Create an OGM instance with `{ typeDefs, driver, logger?, features? }` |
|
|
2003
|
+
| `new OGM(config)` | Create an OGM instance with `{ typeDefs, driver, database?, logger?, features? }` |
|
|
1958
2004
|
| `model(name)` | Get a typed Model for a node type |
|
|
1959
2005
|
| `interfaceModel(name)` | Get a typed InterfaceModel for an interface type |
|
|
1960
2006
|
| `$queryRaw(cypher, params?)` | Execute a read query and return mapped results |
|
|
1961
2007
|
| `$executeRaw(cypher, params?)` | Execute a write operation and return affected counts |
|
|
1962
|
-
| `$transaction(fn)` | Execute operations in an atomic transaction |
|
|
2008
|
+
| `$transaction(fn, options?)` | Execute operations in an atomic transaction; `options.metadata` is attached when it begins |
|
|
1963
2009
|
| `assertIndexesAndConstraints(options?)` | Create fulltext indexes and uniqueness constraints |
|
|
1964
2010
|
| `close()` | Clear caches and release references |
|
|
1965
2011
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-push.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"db-push.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAyNtC,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAkF1E"}
|
|
@@ -76,9 +76,11 @@ function parseDbPushFlags(argv) {
|
|
|
76
76
|
*/
|
|
77
77
|
function renderPlan(plan, io, willDrop) {
|
|
78
78
|
if (plan.create.length === 0)
|
|
79
|
-
if (plan.orphans.length === 0
|
|
79
|
+
if (plan.orphans.length === 0 &&
|
|
80
|
+
plan.changed.length === 0 &&
|
|
81
|
+
plan.blocked.length === 0)
|
|
80
82
|
// Only claim a clean "in sync" when there is genuinely nothing to do —
|
|
81
|
-
// outstanding orphans mean
|
|
83
|
+
// outstanding orphans or changed definitions mean it is not in sync.
|
|
82
84
|
io.out('✓ No changes — constraints and indexes are in sync');
|
|
83
85
|
else
|
|
84
86
|
io.out('No constraints or indexes to create.');
|
|
@@ -89,6 +91,28 @@ function renderPlan(plan, io, willDrop) {
|
|
|
89
91
|
io.out(` ${statement.cypher}`);
|
|
90
92
|
}
|
|
91
93
|
}
|
|
94
|
+
// v2.4.8 — an equivalent constraint under another name satisfies the SDL;
|
|
95
|
+
// say which one, instead of "creating" it on every run.
|
|
96
|
+
for (const cover of plan.covered)
|
|
97
|
+
io.out(` = ${cover.statement.name} covered by ${(0, display_1.safeDisplay)(cover.by)} (equivalent constraint)`);
|
|
98
|
+
// v2.4.8 — a changed definition used to be reported "in sync". Under
|
|
99
|
+
// --force-drop it is dropped and recreated; otherwise it is left alone
|
|
100
|
+
// and the output says plainly that the schema is NOT in sync.
|
|
101
|
+
if (plan.changed.length > 0) {
|
|
102
|
+
if (willDrop)
|
|
103
|
+
io.out(`Changed — ${plan.changed.length} index definition(s) differ from the SDL; eligible to recreate (--force-drop):`);
|
|
104
|
+
else
|
|
105
|
+
io.out(`Changed — ${plan.changed.length} index definition(s) differ from the SDL — schema is NOT in sync (kept as-is; use --force-drop to recreate):`);
|
|
106
|
+
for (const change of plan.changed) {
|
|
107
|
+
io.out(` ~ ${change.statement.name}`);
|
|
108
|
+
for (const diff of change.differences)
|
|
109
|
+
io.out(` ${diff}`);
|
|
110
|
+
if (willDrop) {
|
|
111
|
+
io.out(` ${change.dropCypher}`);
|
|
112
|
+
io.out(` ${change.statement.cypher}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
92
116
|
if (plan.orphans.length > 0)
|
|
93
117
|
if (willDrop) {
|
|
94
118
|
// "eligible to drop" — this is the plan; consent is resolved afterward.
|
|
@@ -112,7 +136,7 @@ async function resolveDropConsent(plan, io, yes) {
|
|
|
112
136
|
if (io.interactive && io.confirm)
|
|
113
137
|
// Strict `=== true`: only an explicit boolean true consents, so a
|
|
114
138
|
// misbehaving embedder returning a truthy non-boolean can't authorize a drop.
|
|
115
|
-
return (await io.confirm(`Drop the ${plan.orphans.length} item(s) listed above?`)) === true
|
|
139
|
+
return (await io.confirm(`Drop the ${plan.orphans.length + plan.changed.length} item(s) listed above?`)) === true
|
|
116
140
|
? 'granted'
|
|
117
141
|
: 'declined';
|
|
118
142
|
return 'blocked';
|
|
@@ -123,19 +147,51 @@ async function applyCreates(driver, database, plan, io) {
|
|
|
123
147
|
const session = driver.session(database ? { database } : undefined);
|
|
124
148
|
try {
|
|
125
149
|
for (const statement of plan.create) {
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
let result;
|
|
151
|
+
try {
|
|
152
|
+
result = await session.run(statement.cypher);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
// v2.4.8 — an existing schema rule the plan could not see (a race,
|
|
156
|
+
// or a server that hides definition columns) used to crash the
|
|
157
|
+
// whole push with exit 1. Report it and carry on with the rest.
|
|
158
|
+
if (!isSchemaAlreadyExists(error))
|
|
159
|
+
throw error;
|
|
160
|
+
io.err(`warning: ${statement.name} not created — ${(0, display_1.safeDisplay)(error.message)}`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// v2.4.8 — `IF NOT EXISTS` is a silent no-op when an equivalent rule
|
|
164
|
+
// exists; only claim "created" when Neo4j says something was added.
|
|
165
|
+
const updates = result?.summary?.counters?.updates?.();
|
|
166
|
+
if (updates &&
|
|
167
|
+
(updates.constraintsAdded ?? 0) + (updates.indexesAdded ?? 0) === 0)
|
|
168
|
+
io.out(`= ${statement.name} not created — Neo4j reports an equivalent constraint or index already exists`);
|
|
169
|
+
else
|
|
170
|
+
io.out(`✓ created ${statement.name}`);
|
|
128
171
|
}
|
|
129
172
|
}
|
|
130
173
|
finally {
|
|
131
174
|
await session.close();
|
|
132
175
|
}
|
|
133
176
|
}
|
|
177
|
+
/** `Neo.ClientError.Schema.*AlreadyExists` (index / constraint / equivalent rule). */
|
|
178
|
+
function isSchemaAlreadyExists(error) {
|
|
179
|
+
const code = error?.code;
|
|
180
|
+
return (typeof code === 'string' &&
|
|
181
|
+
/^Neo\.ClientError\.Schema\.\w*AlreadyExists$/.test(code));
|
|
182
|
+
}
|
|
134
183
|
async function applyDrops(driver, database, plan, io) {
|
|
135
|
-
if (plan.orphans.length === 0)
|
|
184
|
+
if (plan.orphans.length === 0 && plan.changed.length === 0)
|
|
136
185
|
return;
|
|
137
186
|
const session = driver.session(database ? { database } : undefined);
|
|
138
187
|
try {
|
|
188
|
+
// Drop + create, in that order: `CREATE … IF NOT EXISTS` would be a
|
|
189
|
+
// no-op while the old definition still holds the name.
|
|
190
|
+
for (const change of plan.changed) {
|
|
191
|
+
await session.run(change.dropCypher);
|
|
192
|
+
await session.run(change.statement.cypher);
|
|
193
|
+
io.out(`✓ recreated ${change.statement.name}`);
|
|
194
|
+
}
|
|
139
195
|
for (const orphan of plan.orphans) {
|
|
140
196
|
await session.run(orphan.dropCypher);
|
|
141
197
|
io.out(`✓ dropped ${(0, display_1.safeDisplay)(orphan.name)}`);
|
|
@@ -160,14 +216,24 @@ async function runDbPush(argv, io) {
|
|
|
160
216
|
try {
|
|
161
217
|
const live = await (0, introspect_1.fetchLiveSchema)(driver, connection.database);
|
|
162
218
|
const plan = (0, push_planner_1.planSchemaSync)(schema, live, vectorConfig);
|
|
163
|
-
const willDrop = forceDrop && plan.orphans.length > 0;
|
|
219
|
+
const willDrop = forceDrop && (plan.orphans.length > 0 || plan.changed.length > 0);
|
|
164
220
|
renderPlan(plan, io, willDrop);
|
|
165
221
|
// `@vector` indexes without dimensions are reported, never silently
|
|
166
222
|
// skipped, and never block the rest of the plan.
|
|
223
|
+
// v2.4.8 — Neo4j refuses a unique constraint over a property a plain
|
|
224
|
+
// RANGE index already covers. Report it (the index is not grafeo's to
|
|
225
|
+
// drop) instead of letting the CREATE crash the whole push.
|
|
226
|
+
for (const block of plan.blocked)
|
|
227
|
+
io.err(`warning: ${block.statement.name} not created — index "${(0, display_1.safeDisplay)(block.by)}" ` +
|
|
228
|
+
`already covers the same label and property, and Neo4j will not add a ` +
|
|
229
|
+
`unique constraint until that index is dropped. Schema is NOT in sync.`);
|
|
167
230
|
for (const needs of plan.needsConfig)
|
|
168
231
|
io.err(`warning: vector index "${needs.indexName}" ` +
|
|
169
232
|
`(${needs.typeName}.${needs.embeddingProperty}) skipped — set ` +
|
|
170
233
|
`vectorIndexes['${needs.indexName}'].dimensions in grafeo.config.ts to create it`);
|
|
234
|
+
if (plan.changed.length > 0 && !forceDrop)
|
|
235
|
+
io.err(`warning: ${plan.changed.length} index definition(s) differ from the SDL and were NOT applied ` +
|
|
236
|
+
`(${plan.changed.map((c) => c.statement.name).join(', ')}) — re-run with --force-drop to drop and recreate them`);
|
|
171
237
|
// Nothing to create and nothing to drop → no writes (idempotent re-run).
|
|
172
238
|
if (plan.create.length === 0 && !willDrop)
|
|
173
239
|
return 0;
|
|
@@ -190,7 +256,7 @@ async function runDbPush(argv, io) {
|
|
|
190
256
|
if (consent === 'granted')
|
|
191
257
|
await applyDrops(driver, connection.database, plan, io);
|
|
192
258
|
else if (consent === 'declined')
|
|
193
|
-
io.out('Drop declined — orphans kept.');
|
|
259
|
+
io.out('Drop declined — orphans and changed definitions kept.');
|
|
194
260
|
return 0;
|
|
195
261
|
}
|
|
196
262
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-push.js","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"db-push.js","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-seed.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/db-seed.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAgB,MAAM,UAAU,CAAC;AAwGpD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"db-seed.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/db-seed.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAgB,MAAM,UAAU,CAAC;AAwGpD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAwC1E"}
|
|
@@ -134,7 +134,16 @@ async function runDbSeed(argv, io) {
|
|
|
134
134
|
// The OGM constructor parses the SDL synchronously and throws on an
|
|
135
135
|
// invalid schema — it lives inside this try so the driver created above
|
|
136
136
|
// is still closed in that case (cli-db-seed spec: close on any failure).
|
|
137
|
-
|
|
137
|
+
//
|
|
138
|
+
// v2.4.8 — target the resolved database (`--database` >
|
|
139
|
+
// `database.database` > NEO4J_DATABASE), as `db push` does. Pre-2.4.8
|
|
140
|
+
// the OGM had no database option and the seed always ran against the
|
|
141
|
+
// server's default database.
|
|
142
|
+
const ogm = new ogm_1.OGM({
|
|
143
|
+
typeDefs,
|
|
144
|
+
driver,
|
|
145
|
+
...(connection.database ? { database: connection.database } : {}),
|
|
146
|
+
});
|
|
138
147
|
await ogm.init();
|
|
139
148
|
io.out(`running seed ${seedPath}`);
|
|
140
149
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-seed.js","sourceRoot":"","sources":["../../../../src/cli/commands/db-seed.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,
|
|
1
|
+
{"version":3,"file":"db-seed.js","sourceRoot":"","sources":["../../../../src/cli/commands/db-seed.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,8BAwCC;AA3JD,4CAA8B;AAC9B,gDAAkC;AAClC,yCAAsC;AACtC,mCAAgC;AAChC,sCAImB;AACnB,sCAAyC;AACzC,sCAAqC;AAarC,0EAA0E;AAC1E,MAAM,YAAY,GAAG;;;;;;;;;;;EAWnB,CAAC;AAEH,SAAS,gBAAgB,CAAC,IAAc;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,qBAAS,EAAC;YAC3B,IAAI,EAAE,IAAI;YACV,OAAO,EAAE;gBACP,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACvB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;aAC3B;YACD,MAAM,EAAE,IAAI;YACZ,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAC;QACH,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,iBAAQ,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,MAAoB,EAAE,GAAW;IACxD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC1B,MAAM,IAAI,iBAAQ,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,IAAI,iBAAQ,CAChB,qCAAqC;QACnC,kCAAkC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM;QACtC,0DAA0D,YAAY,EAAE,CAC3E,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,MAAM,EAAE,UAAU,EAAE,GAAG,wDAAa,MAAM,GAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAEpC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,iBAAQ,CAChB,uBAAuB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,OAAO,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GACN,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM;QACzD,CAAC,CAAE,MAA+B,CAAC,OAAO;QAC1C,CAAC,CAAC,MAAM,CAAC;IAEb,IAAI,OAAO,EAAE,KAAK,UAAU;QAC1B,MAAM,IAAI,iBAAQ,CAChB,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,wCAAwC;YACrE,yBAAyB,YAAY,EAAE,CAC1C,CAAC;IAEJ,OAAO,EAAY,CAAC;AACtB,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,IAAc,EAAE,EAAS;IACvD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAA,uBAAc,EAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,IAAA,0BAAiB,EAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,IAAA,0BAAiB,EAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAE5D,yEAAyE;IACzE,oDAAoD;IACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,oEAAoE;QACpE,wEAAwE;QACxE,yEAAyE;QACzE,EAAE;QACF,wDAAwD;QACxD,sEAAsE;QACtE,qEAAqE;QACrE,6BAA6B;QAC7B,MAAM,GAAG,GAAG,IAAI,SAAG,CAAC;YAClB,QAAQ;YACR,MAAM;YACN,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClE,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAEjB,EAAE,CAAC,GAAG,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,CAAC;QACD,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Driver } from 'neo4j-driver';
|
|
2
2
|
import type { LiveSchema } from './push-planner';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch the live constraint/index state for the push planner. Read-only —
|
|
5
|
-
* runs exactly `SHOW CONSTRAINTS` and `SHOW INDEXES
|
|
5
|
+
* runs exactly `SHOW CONSTRAINTS` and `SHOW INDEXES YIELD *`.
|
|
6
6
|
*/
|
|
7
7
|
export declare function fetchLiveSchema(driver: Driver, database?: string): Promise<LiveSchema>;
|
|
8
8
|
//# sourceMappingURL=introspect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../../src/cli/introspect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../../src/cli/introspect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAC;AAgGjE;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,CAAC,CAkBrB"}
|