grafeo-ogm 1.8.7 → 1.9.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 (115) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +131 -26
  3. package/dist/cjs/cli/commands/db-push.d.ts +3 -0
  4. package/dist/cjs/cli/commands/db-push.d.ts.map +1 -0
  5. package/dist/cjs/cli/commands/db-push.js +197 -0
  6. package/dist/cjs/cli/commands/db-push.js.map +1 -0
  7. package/dist/cjs/cli/commands/db-seed.d.ts +3 -0
  8. package/dist/cjs/cli/commands/db-seed.d.ts.map +1 -0
  9. package/dist/cjs/cli/commands/db-seed.js +153 -0
  10. package/dist/cjs/cli/commands/db-seed.js.map +1 -0
  11. package/dist/cjs/cli/commands/generate.d.ts +3 -0
  12. package/dist/cjs/cli/commands/generate.d.ts.map +1 -0
  13. package/dist/cjs/cli/commands/generate.js +218 -0
  14. package/dist/cjs/cli/commands/generate.js.map +1 -0
  15. package/dist/cjs/cli/config.d.ts +38 -0
  16. package/dist/cjs/cli/config.d.ts.map +1 -0
  17. package/dist/cjs/cli/config.js +173 -0
  18. package/dist/cjs/cli/config.js.map +1 -0
  19. package/dist/cjs/cli/driver.d.ts +12 -0
  20. package/dist/cjs/cli/driver.d.ts.map +1 -0
  21. package/dist/cjs/cli/driver.js +21 -0
  22. package/dist/cjs/cli/driver.js.map +1 -0
  23. package/dist/cjs/cli/errors.d.ts +16 -0
  24. package/dist/cjs/cli/errors.d.ts.map +1 -0
  25. package/dist/cjs/cli/errors.js +66 -0
  26. package/dist/cjs/cli/errors.js.map +1 -0
  27. package/dist/cjs/cli/index.d.ts +8 -0
  28. package/dist/cjs/cli/index.d.ts.map +1 -0
  29. package/dist/cjs/cli/index.js +187 -0
  30. package/dist/cjs/cli/index.js.map +1 -0
  31. package/dist/cjs/cli/introspect.d.ts +8 -0
  32. package/dist/cjs/cli/introspect.d.ts.map +1 -0
  33. package/dist/cjs/cli/introspect.js +52 -0
  34. package/dist/cjs/cli/introspect.js.map +1 -0
  35. package/dist/cjs/cli/push-planner.d.ts +52 -0
  36. package/dist/cjs/cli/push-planner.d.ts.map +1 -0
  37. package/dist/cjs/cli/push-planner.js +114 -0
  38. package/dist/cjs/cli/push-planner.js.map +1 -0
  39. package/dist/cjs/cli/types.d.ts +71 -0
  40. package/dist/cjs/cli/types.d.ts.map +1 -0
  41. package/dist/cjs/cli/types.js +8 -0
  42. package/dist/cjs/cli/types.js.map +1 -0
  43. package/dist/cjs/generator/generate-types.d.ts +1 -1
  44. package/dist/cjs/generator/generate-types.d.ts.map +1 -1
  45. package/dist/cjs/generator/generate-types.js +16 -3
  46. package/dist/cjs/generator/generate-types.js.map +1 -1
  47. package/dist/cjs/index.d.ts +2 -0
  48. package/dist/cjs/index.d.ts.map +1 -1
  49. package/dist/cjs/index.js +6 -1
  50. package/dist/cjs/index.js.map +1 -1
  51. package/dist/cjs/ogm.d.ts +0 -3
  52. package/dist/cjs/ogm.d.ts.map +1 -1
  53. package/dist/cjs/ogm.js +13 -50
  54. package/dist/cjs/ogm.js.map +1 -1
  55. package/dist/cjs/schema/index-statements.d.ts +50 -0
  56. package/dist/cjs/schema/index-statements.d.ts.map +1 -0
  57. package/dist/cjs/schema/index-statements.js +117 -0
  58. package/dist/cjs/schema/index-statements.js.map +1 -0
  59. package/dist/esm/cli/commands/db-push.d.ts +3 -0
  60. package/dist/esm/cli/commands/db-push.d.ts.map +1 -0
  61. package/dist/esm/cli/commands/db-push.js +161 -0
  62. package/dist/esm/cli/commands/db-push.js.map +1 -0
  63. package/dist/esm/cli/commands/db-seed.d.ts +3 -0
  64. package/dist/esm/cli/commands/db-seed.d.ts.map +1 -0
  65. package/dist/esm/cli/commands/db-seed.js +117 -0
  66. package/dist/esm/cli/commands/db-seed.js.map +1 -0
  67. package/dist/esm/cli/commands/generate.d.ts +3 -0
  68. package/dist/esm/cli/commands/generate.d.ts.map +1 -0
  69. package/dist/esm/cli/commands/generate.js +182 -0
  70. package/dist/esm/cli/commands/generate.js.map +1 -0
  71. package/dist/esm/cli/config.d.ts +38 -0
  72. package/dist/esm/cli/config.d.ts.map +1 -0
  73. package/dist/esm/cli/config.js +134 -0
  74. package/dist/esm/cli/config.js.map +1 -0
  75. package/dist/esm/cli/driver.d.ts +12 -0
  76. package/dist/esm/cli/driver.d.ts.map +1 -0
  77. package/dist/esm/cli/driver.js +15 -0
  78. package/dist/esm/cli/driver.js.map +1 -0
  79. package/dist/esm/cli/errors.d.ts +16 -0
  80. package/dist/esm/cli/errors.d.ts.map +1 -0
  81. package/dist/esm/cli/errors.js +61 -0
  82. package/dist/esm/cli/errors.js.map +1 -0
  83. package/dist/esm/cli/index.d.ts +8 -0
  84. package/dist/esm/cli/index.d.ts.map +1 -0
  85. package/dist/esm/cli/index.js +151 -0
  86. package/dist/esm/cli/index.js.map +1 -0
  87. package/dist/esm/cli/introspect.d.ts +8 -0
  88. package/dist/esm/cli/introspect.d.ts.map +1 -0
  89. package/dist/esm/cli/introspect.js +49 -0
  90. package/dist/esm/cli/introspect.js.map +1 -0
  91. package/dist/esm/cli/push-planner.d.ts +52 -0
  92. package/dist/esm/cli/push-planner.d.ts.map +1 -0
  93. package/dist/esm/cli/push-planner.js +111 -0
  94. package/dist/esm/cli/push-planner.js.map +1 -0
  95. package/dist/esm/cli/types.d.ts +71 -0
  96. package/dist/esm/cli/types.d.ts.map +1 -0
  97. package/dist/esm/cli/types.js +5 -0
  98. package/dist/esm/cli/types.js.map +1 -0
  99. package/dist/esm/generator/generate-types.d.ts +1 -1
  100. package/dist/esm/generator/generate-types.d.ts.map +1 -1
  101. package/dist/esm/generator/generate-types.js +16 -3
  102. package/dist/esm/generator/generate-types.js.map +1 -1
  103. package/dist/esm/index.d.ts +2 -0
  104. package/dist/esm/index.d.ts.map +1 -1
  105. package/dist/esm/index.js +4 -0
  106. package/dist/esm/index.js.map +1 -1
  107. package/dist/esm/ogm.d.ts +0 -3
  108. package/dist/esm/ogm.d.ts.map +1 -1
  109. package/dist/esm/ogm.js +13 -50
  110. package/dist/esm/ogm.js.map +1 -1
  111. package/dist/esm/schema/index-statements.d.ts +50 -0
  112. package/dist/esm/schema/index-statements.d.ts.map +1 -0
  113. package/dist/esm/schema/index-statements.js +109 -0
  114. package/dist/esm/schema/index-statements.js.map +1 -0
  115. package/package.json +13 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,80 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.1 (2026-06-13) — 🩹 `grafeo generate` formatting DX
4
+
5
+ > **A first-run papercut from the 1.9.0 CLI.** Prettier is a *dev* dependency (kept out of the runtime footprint on purpose), so a consumer who runs `grafeo generate` without prettier installed got a terse `Prettier formatting failed; output written without formatting.` — accurate, but unhelpful. The output was always valid TypeScript; only the message was poor. `1.9.1` makes that path friendly and honest.
6
+
7
+ ### 🩹 Actionable "formatting skipped" warning
8
+
9
+ When prettier isn't available, the generator now detects the missing-module case specifically and emits: *"prettier is not installed — generated types were written unformatted. Run `npm i -D prettier` for formatted output, or set `generate.formatOutput: false` to silence this warning."* A genuine prettier *error* (as opposed to a missing install) now reports its actual detail instead of a generic string. The warning carries a dedicated `FORMATTING_SKIPPED` code (previously mislabeled `UNSUPPORTED_TYPE`).
10
+
11
+ ### 🔧 prettier declared as an optional peer dependency
12
+
13
+ `prettier` is now listed under `peerDependencies` with `peerDependenciesMeta.prettier.optional = true`. This documents the relationship for tooling and package managers without auto-installing it — the runtime footprint is unchanged (still just `jiti`), and consumers who want formatted codegen opt in by installing prettier.
14
+
15
+ ### Tests
16
+
17
+ Added coverage that forces the prettier-missing path and asserts the actionable `FORMATTING_SKIPPED` warning. Full suite green; lint, format, and type-check clean.
18
+
19
+ ---
20
+
21
+ ## 1.9.0 (2026-06-13) — 🚀 the `grafeo` CLI
22
+
23
+ > **The first developer-facing command-line tool.** Until now grafeo-ogm was a library you imported; the schema-to-types step, the constraint/index provisioning, and seeding were all things you wired up by hand. `1.9.0` ships `grafeo` — a thin, lazy-loaded CLI over machinery the library already had. Three commands: `grafeo generate` (codegen, including a CI staleness gate), `grafeo db push` (declarative constraint/index sync against a live database), and `grafeo db seed` (idempotent project seeding). Config lives in a typed `grafeo.config.ts`. **The CLI adds exactly one runtime dependency (`jiti`), and importing the library doesn't pull it in.** No library API surface changed; existing consumers upgrade transparently.
24
+
25
+ ### ✨ `grafeo generate` — codegen with a CI staleness gate
26
+
27
+ Wraps the existing `generateTypes()` so the type-emit step is no longer bespoke per project. Three modes:
28
+
29
+ - **One-shot** (default) — read schema, emit the TypeScript file, exit.
30
+ - **`--watch`** — re-emit on schema change via a debounced `fs.watch`, with a `--poll <ms>` fallback for filesystems where native watch events are unreliable (network mounts, some container bind-mounts).
31
+ - **`--verify`** — emit into memory and byte-compare against the on-disk file. Writes **nothing**; exits `1` on drift. This is the CI gate: a build fails if a committed types file has fallen behind its schema, the same way a `git diff --exit-code` after codegen would, but without a working-tree mutation.
32
+
33
+ ### ✨ `grafeo db push` — declarative constraint & index sync
34
+
35
+ Diffs the constraints and indexes **declared in your SDL** against what's actually live in the database, then reconciles them. Declarations are derived from directives: `@id`/`@unique` → unique constraints, `@fulltext` → fulltext indexes, `@vector` → vector indexes. The live state is read via `SHOW CONSTRAINTS` / `SHOW INDEXES`.
36
+
37
+ The planner sorts everything into four buckets and prints them before touching anything:
38
+
39
+ - **create** — declared in SDL, missing in the DB.
40
+ - **in-sync** — declared and already present.
41
+ - **orphans** — managed-looking artifacts present in the DB but no longer declared in SDL (candidates for removal).
42
+ - **unmanaged** — DB artifacts outside grafeo's naming convention, left strictly untouched (hand-rolled DBA constraints, other tools' indexes).
43
+
44
+ `push` is **additive-by-default and idempotent** — re-running it is a no-op once in sync, and it never drops anything on the happy path. Destructive orphan drops are gated behind `--force-drop` **and** `--yes` (or an interactive confirmation); `--dry-run` prints the plan and exits without executing. Orphan detection is scoped by naming convention, so DBA-created constraints never even enter the orphan bucket — they land in *unmanaged* and are left alone.
45
+
46
+ ### ✨ `grafeo db seed` — idempotent project seeding
47
+
48
+ Runs your project's seed script — resolved as config `seed` → `./seed.ts` → `./seed.js` — handing it a fully constructed, **already-connected** OGM so the script doesn't re-derive connection details. The driver is **always closed**, including when the seed script throws, so a failed seed never leaks a live connection. The docs promote `upsert` for seed data specifically because it's idempotent: re-seeding a populated database converges instead of duplicating.
49
+
50
+ ### ✨ Config: `grafeo.config.ts` and connection precedence
51
+
52
+ Configuration loads from `grafeo.config.ts` / `.js` / `.json`, transpiled on the fly via `jiti` (the single new runtime dependency). A `defineConfig` export gives you full type inference on the config object. Connection settings resolve by precedence: **explicit flag > config file > `NEO4J_*` environment variables**.
53
+
54
+ One deliberate omission: **the password is never accepted as a CLI flag.** A password passed on the command line leaks into process listings (`ps`), shell history, and CI logs — so it must come from config or the environment. This is a security constraint, not an oversight.
55
+
56
+ ### Lazy loading — `generate` doesn't touch the driver
57
+
58
+ Commands are loaded lazily so the cheap path stays cheap. `grafeo generate` does pure codegen and **never loads `neo4j-driver`** — only `db push` / `db seed` pull in the driver, and only when invoked. Symmetrically, importing the library from application code does **not** pull in `jiti`; the config loader lives behind the CLI entry point. No bloat leaks in either direction.
59
+
60
+ ### Internal — single source of truth for constraint/index Cypher (no behavior change)
61
+
62
+ The Cypher that creates constraints and indexes was previously emitted inside `OGM.assertIndexesAndConstraints()`. `db push`'s planner needs the *same* statements to diff against the live DB, so that generation was extracted into one module — `src/schema/index-statements.ts` — now shared by both `assertIndexesAndConstraints()` and the planner. The emitted statement text and ordering are **byte-identical** to 1.8.7; this is a pure refactor with no behavioral effect on existing OGM users.
63
+
64
+ ### SECURITY — orphan `DROP CONSTRAINT` re-validates the introspected name
65
+
66
+ The orphan-drop path takes a constraint *name read back from the live database* and puts it into a `DROP CONSTRAINT` statement. Constraint names are normally grafeo-generated and safe, but a live database can carry a name with unsafe characters (created by another tool, or maliciously). Before any introspected name enters Cypher, it is now re-validated through `assertSafeIdentifier`. A name that fails validation is **demoted to *unmanaged*** — it is never dropped, and the destructive path never runs against an untrusted identifier. Defense in depth: the drop path treats DB-sourced names with the same suspicion as user input.
67
+
68
+ ### Minor — NLS audit metadata version bump
69
+
70
+ NLS audit metadata now emits `ogmPolicySetVersion: "1.7.0"`, dropping the stale `-beta.0` pre-release suffix it had been carrying. The policy format reached GA in 1.7.0 and is unchanged — this only corrects the reported version string. If you assert on the exact audit-metadata value, update your expectation from `1.7.0-beta.0` to `1.7.0`.
71
+
72
+ ### Tests
73
+
74
+ New CLI coverage for all three commands and the config loader: `generate` one-shot/`--watch`/`--verify`-drift, the four-bucket `db push` planner with additive/idempotent/`--dry-run`/`--force-drop` paths and the unsafe-name demotion, `db seed` driver-always-closed-on-failure, and connection precedence. The `index-statements.ts` extraction is pinned by byte-identical statement assertions against the prior `assertIndexesAndConstraints()` output. Full suite green; lint, format, and type-check clean.
75
+
76
+ ---
77
+
3
78
  ## 1.8.7 (2026-06-12) — 🚨 SECURITY + correctness
4
79
 
5
80
  > **Three HIGH correctness bugs, two subgraph guards, and three security hardenings** from the post-1.8.6 comprehensive audit. Two of the three HIGH bugs are "fixed one site, missed the sibling" regressions of earlier fixes (v1.8.1 and v1.8.3) — sibling-site sweeps are now part of the fix checklist. Upgrade if you use `withContext`, nested relationship updates, union relationship filters, write restrictives, or subgraph operations.
package/README.md CHANGED
@@ -21,6 +21,7 @@ Define your graph model once in `.graphql` and get fully typed CRUD operations,
21
21
  - [Why grafeo-ogm?](#why-grafeo-ogm)
22
22
  - [Common Use Cases](#common-use-cases)
23
23
  - [Quick Start](#quick-start)
24
+ - [CLI](#cli)
24
25
  - [Features Overview](#features-overview)
25
26
  - [Schema Definition](#schema-definition)
26
27
  - [Query API](#query-api)
@@ -151,7 +152,15 @@ type Category @node {
151
152
  }
152
153
  ```
153
154
 
154
- ### 2. Initialize the OGM
155
+ ### 2. Generate types (recommended)
156
+
157
+ ```bash
158
+ npx grafeo generate
159
+ ```
160
+
161
+ This wraps `generateTypes()` to emit typed models from your SDL — wire them in with `new OGM<ModelMap>(...)` for full inference. See the [CLI](#cli) and [Type Generation](#type-generation) sections. You can skip this and run the OGM untyped, but you forfeit compile-time safety.
162
+
163
+ ### 3. Initialize the OGM
155
164
 
156
165
  ```typescript
157
166
  import { OGM } from 'grafeo-ogm';
@@ -167,7 +176,7 @@ const typeDefs = fs.readFileSync('./schema.graphql', 'utf-8');
167
176
  const ogm = new OGM({ typeDefs, driver });
168
177
  ```
169
178
 
170
- ### 3. Basic CRUD
179
+ ### 4. Basic CRUD
171
180
 
172
181
  ```typescript
173
182
  const Book = ogm.model('Book');
@@ -201,7 +210,7 @@ await Book.update({
201
210
  await Book.delete({ where: { isbn: '978-1491930892' } });
202
211
  ```
203
212
 
204
- ### 4. Transactions
213
+ ### 5. Transactions
205
214
 
206
215
  ```typescript
207
216
  await ogm.$transaction(async (ctx) => {
@@ -213,21 +222,118 @@ await ogm.$transaction(async (ctx) => {
213
222
 
214
223
  ---
215
224
 
216
- ## Beta features
225
+ ## CLI
226
+
227
+ grafeo-ogm ships a `grafeo` binary (installed with the package — no global install needed). Run it with `npx grafeo <command>`. The CLI is plumbing over the same library machinery you can call programmatically: `generate` wraps `generateTypes()`, and `db push` reuses the constraint/index logic behind `assertIndexesAndConstraints()`.
228
+
229
+ | Command | Purpose |
230
+ |---|---|
231
+ | `grafeo generate` | Generate TypeScript types from your SDL — one-shot, `--watch`, or `--verify` CI gate |
232
+ | `grafeo db push` | Diff SDL-declared constraints/indexes against the live database and apply them |
233
+ | `grafeo db seed` | Run your seed script with a constructed, connected OGM |
234
+
235
+ ### Configuration
236
+
237
+ All commands read `grafeo.config.ts` (or `.js` / `.json`) from the working directory — first found wins. Command-line flags override config values. `defineConfig` gives full type inference:
238
+
239
+ ```typescript
240
+ // grafeo.config.ts
241
+ import { defineConfig } from 'grafeo-ogm';
242
+
243
+ export default defineConfig({
244
+ schema: './schema.graphql', // default: ./schema.graphql
245
+ out: './src/generated/ogm-types.ts', // default: ./grafeo.generated.ts
246
+ // generate: forwarded to generateTypes(). Set packageName ONLY if you
247
+ // installed grafeo-ogm under an npm alias, e.g. { packageName: '@myorg/ogm' }
248
+ database: {
249
+ uri: process.env.NEO4J_URI,
250
+ username: process.env.NEO4J_USERNAME,
251
+ // password: from config or NEO4J_PASSWORD — never a CLI flag (see below)
252
+ },
253
+ seed: './scripts/seed.ts',
254
+ vectorIndexes: {
255
+ // @vector SDL carries no dimensions; db push reads them here, keyed by index name
256
+ BookEmbedding: { dimensions: 1536, similarity: 'cosine' },
257
+ },
258
+ });
259
+ ```
260
+
261
+ **Database connection** resolves per setting in precedence order: CLI flag (`--uri`, `--username`, `--database`) > config `database` block > environment (`NEO4J_URI`, `NEO4J_USERNAME`, `NEO4J_PASSWORD`, `NEO4J_DATABASE`). The **password is never accepted as a CLI flag** — argv leaks through process listings and shell history, so it must come from `NEO4J_PASSWORD` or the config file.
262
+
263
+ > **Config and seed files run as trusted code.** `grafeo.config.ts` and your seed script are executed in-process (via [jiti](https://github.com/unjs/jiti)) with your database credentials — the same trust model as Prisma/Drizzle. Only run `grafeo` in a directory whose config and seed files you control.
264
+
265
+ ### `grafeo generate`
266
+
267
+ Compiles your SDL to TypeScript types (wraps `generateTypes()` — see [Type Generation](#type-generation) for the programmatic API and the full option list).
268
+
269
+ ```bash
270
+ npx grafeo generate # one-shot
271
+ npx grafeo generate --watch # regenerate on schema change
272
+ npx grafeo generate --verify # CI gate: exit 1 if the file on disk is stale
273
+ ```
274
+
275
+ | Flag | Description |
276
+ |---|---|
277
+ | `--schema <path>` | SDL path (overrides config; default `./schema.graphql`) |
278
+ | `--out <path>` | Output path (default `./grafeo.generated.ts`) |
279
+ | `--watch` | Debounced regeneration on change; a failed parse prints the error and keeps watching |
280
+ | `--verify` | Generate in memory, byte-compare against the file on disk, write nothing, exit 1 on drift |
281
+ | `--poll <ms>` | Use polling instead of `fs.watch` (fallback where native watching misfires) |
282
+
283
+ `--verify` is the CI staleness gate: commit your generated types, then run `grafeo generate --verify` in CI to fail the build if the schema changed without a regeneration.
284
+
285
+ ### `grafeo db push`
286
+
287
+ Synchronizes the **constraints and indexes** your SDL declares (`@id`/`@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.)
288
+
289
+ ```bash
290
+ npx grafeo db push --dry-run # preview the plan — DO THIS FIRST
291
+ npx grafeo db push # apply (additive: creates only what's missing)
292
+ npx grafeo db push --force-drop --yes # also drop orphaned grafeo-managed items
293
+ ```
294
+
295
+ `db push` introspects `SHOW CONSTRAINTS` / `SHOW INDEXES`, diffs against your SDL, and prints a plan in four buckets:
217
296
 
218
- The current beta release exposes one new feature behind opt-in config:
297
+ - **create** — declared in SDL, missing in the database
298
+ - **in sync** — already present
299
+ - **orphans** — grafeo-named (`{Label}_{prop}_unique`) constraints no longer in your SDL; **reported and kept** unless you pass `--force-drop`
300
+ - **unmanaged** — constraints/indexes that don't follow grafeo's naming convention (hand-created DBA indexes, etc.); **never touched, never counted as drift**
219
301
 
220
- - **Node-Level Security (NLS)** — a Postgres-RLS-style filter layer that compiles into the existing WHERE pipeline. See **[Advanced Features → Node-Level Security (Beta)](#node-level-security-beta)**.
302
+ It is **additive by default** and **idempotent** — a second run with no schema change is a no-op. Dropping orphans 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.
221
303
 
222
- The beta is purely additive: an OGM constructed without the new `policies` option emits **byte-identical Cypher** to v1.6.0. Install with:
304
+ | Flag | Description |
305
+ |---|---|
306
+ | `--dry-run` | Print the full plan (including the exact Cypher, drops included) and exit without writing |
307
+ | `--force-drop` | Permit dropping orphaned grafeo-managed constraints/indexes |
308
+ | `--yes` | Confirm destructive drops non-interactively (required with `--force-drop` in CI) |
309
+ | `--schema <path>`, `--uri`, `--username`, `--database` | Schema path and connection overrides |
310
+
311
+ > **Vector indexes** declare no dimensions in the SDL (the `@vector` directive only names the index and its embedding property), but Neo4j requires them at creation time. Supply them in `vectorIndexes` (keyed by index name) in your config. A `@vector` index without configured dimensions is reported and skipped — never silently created or dropped.
312
+
313
+ ### `grafeo db seed`
314
+
315
+ Runs your seed script with a constructed, connected `OGM`. It resolves the entry point from config `seed`, then `./seed.ts`, then `./seed.js`. The module's default export receives the OGM; the CLI awaits it and **always closes the driver**, even if the seed throws.
316
+
317
+ ```typescript
318
+ // seed.ts
319
+ import type { OGM } from 'grafeo-ogm';
320
+
321
+ export default async function seed(ogm: OGM) {
322
+ const Book = ogm.model('Book');
323
+ // Prefer upsert over create so repeated seeds converge instead of duplicating data.
324
+ await Book.upsert({
325
+ where: { id: '1' },
326
+ create: { id: '1', title: 'Dune' },
327
+ update: { title: 'Dune' },
328
+ });
329
+ }
330
+ ```
223
331
 
224
332
  ```bash
225
- npm install grafeo-ogm@beta
226
- # or
227
- pnpm add grafeo-ogm@beta
333
+ npx grafeo db seed
228
334
  ```
229
335
 
230
- The shape of the public API is settled, but the beta window is for collecting integration feedback. Minor adjustments may land before `1.7.0` final.
336
+ grafeo does not enforce idempotency — use `upsert` so re-running the seed is safe. Connection and schema resolve exactly as for `db push`.
231
337
 
232
338
  ---
233
339
 
@@ -834,7 +940,7 @@ const deleteResult = await deleteSubgraph(
834
940
 
835
941
  ### Computed Fields with @cypher
836
942
 
837
- The `@cypher` directive declares a field whose value is produced by a custom Cypher statement at query time. As of v1.6.0, scalar `@cypher` fields are resolved in three scopes — `select` / `selectionSet`, `where`, and `options.sort` — so you can project, filter, and order by them just like stored properties. Pre-1.6.0, references in `select` and `where` silently returned `NULL`.
943
+ The `@cypher` directive declares a field whose value is produced by a custom Cypher statement at query time. Scalar `@cypher` fields are resolved in three scopes — `select` / `selectionSet`, `where`, and `options.sort` — so you can project, filter, and order by them just like stored properties.
838
944
 
839
945
  #### Declaration
840
946
 
@@ -938,11 +1044,9 @@ These are not OGM bugs — they are Cypher-language constraints. Pattern compreh
938
1044
 
939
1045
  Each scope (`where`, `select`, sort) emits its own `CALL { WITH n; WITH n AS this; <statement> }` block per `@cypher` field reference. A query that references the same `@cypher` field in all three scopes emits three `CALL` blocks. This is functionally correct and parameter-isolated, but worth knowing if your statement is expensive (multi-hop traversals, aggregations over large fan-outs). For frequently-accessed computed values, consider materializing as a stored property updated on write instead.
940
1046
 
941
- ### Node-Level Security (Beta)
942
-
943
- > **Beta — install with `npm install grafeo-ogm@beta`.**
1047
+ ### Node-Level Security
944
1048
 
945
- Node-Level Security (NLS) is a per-request filter layer that compiles into the existing WHERE pipeline. Policies return `<Node>Where` partials, so every operator, quantifier, connection filter, and nested traversal already supported by `WhereCompiler` is automatically available inside policies — no new DSL.
1049
+ Node-Level Security (NLS) is a per-request filter layer that compiles into the existing WHERE pipeline. It is opt-in: an OGM constructed without the `policies` option emits byte-identical Cypher to a no-policy OGM. Policies return `<Node>Where` partials, so every operator, quantifier, connection filter, and nested traversal already supported by `WhereCompiler` is automatically available inside policies — no new DSL.
946
1050
 
947
1051
  #### Declaration
948
1052
 
@@ -1083,7 +1187,7 @@ When `policies` is configured, every OGM-emitted query attaches transaction meta
1083
1187
 
1084
1188
  ```typescript
1085
1189
  {
1086
- ogmPolicySetVersion: '1.7.0-beta.0',
1190
+ ogmPolicySetVersion: '1.7.0',
1087
1191
  ctxFingerprint: '<sha256 of sorted ctx KEYS — never values>',
1088
1192
  modelType: 'Book',
1089
1193
  operation: 'read',
@@ -1094,14 +1198,13 @@ When `policies` is configured, every OGM-emitted query attaches transaction meta
1094
1198
 
1095
1199
  Disable via `policyDefaults: { auditMetadata: false }`. The fingerprint is intentionally key-only — no ctx values are leaked.
1096
1200
 
1097
- #### Beta limits
1201
+ #### Limitations
1098
1202
 
1099
1203
  - **`@cypher` scalar fields inside a policy `where`-partial throw when the policy is injected into nested-selection enforcement.** Refactor the policy to use stored properties or a relationship traversal.
1100
- - **`upsert`** evaluates create- and update-side policies at the application layer (MERGE has no WHERE). Documented limit; full MERGE-aware enforcement is deferred to v1.7.1.
1101
- - **Restrictives are split into read-side and write-side flavors.** A restrictive's `operations` array determines which `when` signature applies. Read-side ops (`read|delete|aggregate|count`) → `when(ctx)` returns a where-partial or boolean. Write-side ops (`create|update`) → `when(ctx, input)` returns a boolean only. Mixed arrays (e.g. `['read', 'create']`) are rejected at construction time — split into two restrictives. Each flavor is invoked exactly once per query (read-side at compile, write-side at the application layer); the dual-invocation contract bug from earlier beta iterations is fixed. Use `isReadRestrictive` / `isWriteRestrictive` if you need to inspect a policy at runtime.
1204
+ - **`upsert`** evaluates create- and update-side policies at the application layer (MERGE has no WHERE). Documented limit; full MERGE-aware enforcement is not yet implemented.
1205
+ - **Restrictives are split into read-side and write-side flavors.** A restrictive's `operations` array determines which `when` signature applies. Read-side ops (`read|delete|aggregate|count`) → `when(ctx)` returns a where-partial or boolean. Write-side ops (`create|update`) → `when(ctx, input)` returns a boolean only. Mixed arrays (e.g. `['read', 'create']`) are rejected at construction time — split into two restrictives. Each flavor is invoked exactly once per query (read-side at compile, write-side at the application layer). Use `isReadRestrictive` / `isWriteRestrictive` if you need to inspect a policy at runtime.
1102
1206
  - **InterfaceModel CASE-per-label fallback.** Implementers without a registered policy fall back to interface-level enforcement on their branch. The OGM emits a `logger.warn` at construction time when an interface has policies and one of its implementers does not — silence the warning by registering an explicit policy on each implementer.
1103
- - **AsyncLocalStorage** opt-in is deferred to v1.7.1. Beta is explicit `withContext()` only — create one wrapper per request, discard after.
1104
- - **Live Neo4j integration tests are not part of the beta.** Mock-driver coverage is extensive but a real-DB suite is a `1.7.0` final blocker.
1207
+ - **No AsyncLocalStorage integration.** Context is supplied via explicit `withContext()` only — create one wrapper per request, discard after.
1105
1208
 
1106
1209
  ### Raw Cypher
1107
1210
 
@@ -1221,7 +1324,9 @@ type Article @node @vector(indexes: [
1221
1324
 
1222
1325
  ### Creating the index in Neo4j
1223
1326
 
1224
- grafeo-ogm does **not** create vector indexes for you in this release. Run the `CREATE VECTOR INDEX` Cypher yourself as part of your migration:
1327
+ The `grafeo db push` CLI creates `@vector` indexes for you — the directive carries no dimensions, so supply them in your config's `vectorIndexes` map (keyed by index name) and `db push` issues the `CREATE VECTOR INDEX`. See the [CLI → `grafeo db push`](#grafeo-db-push) section. The runtime `assertIndexesAndConstraints()` does **not** create vector indexes (only fulltext indexes and unique constraints).
1328
+
1329
+ You can also run the Cypher yourself as part of a migration:
1225
1330
 
1226
1331
  ```cypher
1227
1332
  CREATE VECTOR INDEX article_content_idx FOR (n:Article) ON n.embedding
@@ -1323,7 +1428,7 @@ The following were intentionally left out of this release:
1323
1428
  - **`@embedded(from:, using:)` auto-write directive** — automatic embedding on create / update. Requires a pluggable embedder port and peer-dependency adapters.
1324
1429
  - **Third-party embedder SDKs** (`grafeo-ogm/embedders/openai`, etc.) — tracked for a future release with optional peer dependencies.
1325
1430
  - **Relationship-level `@vector` indexes** — the current Neo4j / official spec only supports node vector indexes.
1326
- - **Automatic index creation via `assertIndexesAndConstraints`** — you must run `CREATE VECTOR INDEX` yourself.
1431
+ - **Vector index creation via the runtime `assertIndexesAndConstraints`** — that method covers fulltext indexes and unique constraints only. Create vector indexes with the `grafeo db push` CLI (see [CLI](#cli)) or run `CREATE VECTOR INDEX` yourself.
1327
1432
 
1328
1433
  ---
1329
1434
 
@@ -1588,7 +1693,7 @@ Pure query builders (e.g. `cypher-query-builder`) help you compose Cypher fragme
1588
1693
 
1589
1694
  ### Is grafeo-ogm production-ready?
1590
1695
 
1591
- Yes. The library has 1,093 unit tests covering compilers, mutations, fulltext, transactions, security, scalar type mapping, and edge cases. It targets Neo4j 5.x and follows semver — see [CHANGELOG.md](CHANGELOG.md).
1696
+ Yes. The library has over 1,400 unit tests covering compilers, mutations, fulltext, transactions, security, scalar type mapping, the CLI, and edge cases. It targets Neo4j 5.x and follows semver — see [CHANGELOG.md](CHANGELOG.md).
1592
1697
 
1593
1698
  ### Does grafeo-ogm work with Neo4j Aura?
1594
1699
 
@@ -1620,7 +1725,7 @@ Negligible. grafeo-ogm compiles each query once per shape (selection sets are ca
1620
1725
 
1621
1726
  ### Is there a CLI / migration tool / studio?
1622
1727
 
1623
- Not yet. The library focuses on the runtime API and type generation. Schema migrations are intentionally out of scope — Neo4j's labels and properties are flexible enough that you typically migrate via Cypher scripts (`MATCH (n:OldLabel) SET n:NewLabel REMOVE n:OldLabel`) which you can run via `ogm.$executeRaw(...)`.
1728
+ There is a CLI — the `grafeo` binary ships with the package (`grafeo generate`, `grafeo db push`, `grafeo db seed`). See the [CLI](#cli) section. There is no studio. Data migrations are intentionally out of scope: `db push` syncs SDL-declared constraints and indexes only, never data. Neo4j's labels and properties are flexible enough that you typically migrate data via Cypher scripts (`MATCH (n:OldLabel) SET n:NewLabel REMOVE n:OldLabel`) which you can run via `ogm.$executeRaw(...)`.
1624
1729
 
1625
1730
  ### How do I report a bug or request a feature?
1626
1731
 
@@ -0,0 +1,3 @@
1
+ import type { CliIO } from '../types';
2
+ export declare function runDbPush(argv: string[], io: CliIO): Promise<number>;
3
+ //# sourceMappingURL=db-push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-push.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AA+ItC,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAgE1E"}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runDbPush = runDbPush;
37
+ const fs = __importStar(require("node:fs"));
38
+ const node_util_1 = require("node:util");
39
+ const parser_1 = require("../../schema/parser");
40
+ const config_1 = require("../config");
41
+ const driver_1 = require("../driver");
42
+ const errors_1 = require("../errors");
43
+ const introspect_1 = require("../introspect");
44
+ const push_planner_1 = require("../push-planner");
45
+ function parseDbPushFlags(argv) {
46
+ try {
47
+ const { values } = (0, node_util_1.parseArgs)({
48
+ args: argv,
49
+ options: {
50
+ schema: { type: 'string' },
51
+ uri: { type: 'string' },
52
+ username: { type: 'string' },
53
+ database: { type: 'string' },
54
+ 'dry-run': { type: 'boolean' },
55
+ 'force-drop': { type: 'boolean' },
56
+ yes: { type: 'boolean' },
57
+ debug: { type: 'boolean' },
58
+ },
59
+ strict: true,
60
+ allowPositionals: false,
61
+ });
62
+ return values;
63
+ }
64
+ catch (error) {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ throw new errors_1.CliError(`db push: ${message}`);
67
+ }
68
+ }
69
+ /**
70
+ * Print the FULL diff — including the destructive part. Under `--force-drop`
71
+ * the orphan section shows the exact drop Cypher; otherwise it reports the
72
+ * orphans as kept. Rendering the drops here (not in the confirmation step) is
73
+ * what makes `--dry-run --force-drop` preview the drops instead of hiding
74
+ * them — dry-run is exactly when you need to see what would be removed.
75
+ */
76
+ function renderPlan(plan, io, willDrop) {
77
+ if (plan.create.length === 0)
78
+ if (plan.orphans.length === 0)
79
+ // Only claim a clean "in sync" when there is genuinely nothing to do —
80
+ // outstanding orphans mean the schema is not in sync.
81
+ io.out('✓ No changes — constraints and indexes are in sync');
82
+ else
83
+ io.out('No constraints or indexes to create.');
84
+ else {
85
+ io.out(`Plan — ${plan.create.length} to create, ${plan.inSync.length} in sync:`);
86
+ for (const statement of plan.create) {
87
+ io.out(` + ${statement.name}`);
88
+ io.out(` ${statement.cypher}`);
89
+ }
90
+ }
91
+ if (plan.orphans.length > 0)
92
+ if (willDrop) {
93
+ // "eligible to drop" — this is the plan; consent is resolved afterward.
94
+ io.out(`Orphans — ${plan.orphans.length} eligible to drop (--force-drop):`);
95
+ for (const orphan of plan.orphans)
96
+ io.out(` - ${orphan.dropCypher}`);
97
+ }
98
+ else {
99
+ io.out(`Orphans — ${plan.orphans.length} kept (use --force-drop to remove):`);
100
+ for (const orphan of plan.orphans)
101
+ io.out(` - ${orphan.name}`);
102
+ }
103
+ if (plan.unmanaged.length > 0)
104
+ io.out(`Unmanaged — ${plan.unmanaged.length} ignored: ${plan.unmanaged.join(', ')}`);
105
+ }
106
+ async function resolveDropConsent(plan, io, yes) {
107
+ if (yes)
108
+ return 'granted';
109
+ if (io.interactive && io.confirm)
110
+ // Strict `=== true`: only an explicit boolean true consents, so a
111
+ // misbehaving embedder returning a truthy non-boolean can't authorize a drop.
112
+ return (await io.confirm(`Drop the ${plan.orphans.length} item(s) listed above?`)) === true
113
+ ? 'granted'
114
+ : 'declined';
115
+ return 'blocked';
116
+ }
117
+ async function applyCreates(driver, database, plan, io) {
118
+ if (plan.create.length === 0)
119
+ return;
120
+ const session = driver.session(database ? { database } : undefined);
121
+ try {
122
+ for (const statement of plan.create) {
123
+ await session.run(statement.cypher);
124
+ io.out(`✓ created ${statement.name}`);
125
+ }
126
+ }
127
+ finally {
128
+ await session.close();
129
+ }
130
+ }
131
+ async function applyDrops(driver, database, plan, io) {
132
+ if (plan.orphans.length === 0)
133
+ return;
134
+ const session = driver.session(database ? { database } : undefined);
135
+ try {
136
+ for (const orphan of plan.orphans) {
137
+ await session.run(orphan.dropCypher);
138
+ io.out(`✓ dropped ${orphan.name}`);
139
+ }
140
+ }
141
+ finally {
142
+ await session.close();
143
+ }
144
+ }
145
+ async function runDbPush(argv, io) {
146
+ const flags = parseDbPushFlags(argv);
147
+ const { config } = await (0, config_1.loadConfigFile)(io.cwd);
148
+ const schemaPath = (0, config_1.resolveSchemaPath)(flags, config, io.cwd);
149
+ const typeDefs = fs.readFileSync(schemaPath, 'utf-8');
150
+ const schema = (0, parser_1.parseSchema)(typeDefs);
151
+ const connection = (0, config_1.resolveConnection)(flags, config, io.env);
152
+ // GrafeoVectorIndexConfig is structurally a VectorIndexCreationConfig.
153
+ const vectorConfig = config.vectorIndexes;
154
+ const dryRun = flags['dry-run'] === true;
155
+ const forceDrop = flags['force-drop'] === true;
156
+ const driver = (0, driver_1.createDriver)(io, connection);
157
+ try {
158
+ const live = await (0, introspect_1.fetchLiveSchema)(driver, connection.database);
159
+ const plan = (0, push_planner_1.planSchemaSync)(schema, live, vectorConfig);
160
+ const willDrop = forceDrop && plan.orphans.length > 0;
161
+ renderPlan(plan, io, willDrop);
162
+ // `@vector` indexes without dimensions are reported, never silently
163
+ // skipped, and never block the rest of the plan.
164
+ for (const needs of plan.needsConfig)
165
+ io.err(`warning: vector index "${needs.indexName}" ` +
166
+ `(${needs.typeName}.${needs.embeddingProperty}) skipped — set ` +
167
+ `vectorIndexes['${needs.indexName}'].dimensions in grafeo.config.ts to create it`);
168
+ // Nothing to create and nothing to drop → no writes (idempotent re-run).
169
+ if (plan.create.length === 0 && !willDrop)
170
+ return 0;
171
+ if (dryRun) {
172
+ io.out('');
173
+ io.out('Dry run — no changes applied.');
174
+ return 0;
175
+ }
176
+ // Resolve drop consent FIRST, so a hard block (non-interactive, no --yes)
177
+ // aborts cleanly without having applied anything. An interactive decline,
178
+ // by contrast, still lets the additive creates proceed.
179
+ let consent;
180
+ if (willDrop) {
181
+ consent = await resolveDropConsent(plan, io, flags.yes === true);
182
+ if (consent === 'blocked')
183
+ throw new errors_1.CliError('Destructive changes (--force-drop) require --yes in a non-interactive session.');
184
+ }
185
+ // Additive creates are never gated.
186
+ await applyCreates(driver, connection.database, plan, io);
187
+ if (consent === 'granted')
188
+ await applyDrops(driver, connection.database, plan, io);
189
+ else if (consent === 'declined')
190
+ io.out('Drop declined — orphans kept.');
191
+ return 0;
192
+ }
193
+ finally {
194
+ await driver.close();
195
+ }
196
+ }
197
+ //# sourceMappingURL=db-push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-push.js","sourceRoot":"","sources":["../../../../src/cli/commands/db-push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliIO } from '../types';
2
+ export declare function runDbSeed(argv: string[], io: CliIO): Promise<number>;
3
+ //# sourceMappingURL=db-seed.d.ts.map
@@ -0,0 +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,CA+B1E"}