@loradb/lora-graphql 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +42 -10
  2. package/dist/analyze/access-lint.d.ts +7 -0
  3. package/dist/analyze/access.d.ts +2 -30
  4. package/dist/analyze/assert-schema.d.ts +19 -0
  5. package/dist/analyze/diff.d.ts +1 -1
  6. package/dist/analyze/plans.d.ts +1 -1
  7. package/dist/analyze/principals.d.ts +25 -0
  8. package/dist/analyze/verdicts.d.ts +45 -0
  9. package/dist/cli.js +2 -2
  10. package/dist/cli.js.map +1 -1
  11. package/dist/compile/cache.d.ts +1 -1
  12. package/dist/compile/read/abstract.d.ts +19 -0
  13. package/dist/compile/read/aggregates.d.ts +34 -0
  14. package/dist/compile/read/by-keys.d.ts +10 -0
  15. package/dist/compile/read/common.d.ts +30 -0
  16. package/dist/compile/read/connection.d.ts +26 -0
  17. package/dist/compile/read/cypher-field.d.ts +21 -0
  18. package/dist/compile/read/match.d.ts +11 -0
  19. package/dist/compile/read/project.d.ts +15 -0
  20. package/dist/compile/read/root.d.ts +5 -0
  21. package/dist/compile/read/search.d.ts +16 -0
  22. package/dist/compile/read/sort.d.ts +42 -0
  23. package/dist/compile/read/types.d.ts +61 -0
  24. package/dist/{diff-B9iDdELF.js → diff-aDivqYqr.js} +2 -2
  25. package/dist/diff-aDivqYqr.js.map +1 -0
  26. package/dist/{driver-C5dSoSD8.js → driver-DSnytFsU.js} +11092 -10674
  27. package/dist/driver-DSnytFsU.js.map +1 -0
  28. package/dist/execute/cypher-mutation.d.ts +1 -1
  29. package/dist/execute/mutate/adjust.d.ts +5 -0
  30. package/dist/execute/mutate/checks.d.ts +21 -0
  31. package/dist/execute/mutate/delete.d.ts +7 -0
  32. package/dist/execute/mutate/env.d.ts +73 -0
  33. package/dist/execute/mutate/errors.d.ts +7 -0
  34. package/dist/execute/mutate/fragments.d.ts +37 -0
  35. package/dist/execute/mutate/plan.d.ts +95 -0
  36. package/dist/execute/mutate/runner.d.ts +129 -0
  37. package/dist/execute/mutate/unique-together.d.ts +18 -0
  38. package/dist/execute/mutate.d.ts +2 -79
  39. package/dist/index.d.ts +10 -6
  40. package/dist/index.js +2 -2
  41. package/dist/lora-graphql.d.ts +12 -326
  42. package/dist/model/build/authorization.d.ts +31 -0
  43. package/dist/model/build/cypher-field.d.ts +11 -0
  44. package/dist/model/build/directive-args.d.ts +16 -0
  45. package/dist/model/build/limits.d.ts +18 -0
  46. package/dist/model/build/relationship-field.d.ts +11 -0
  47. package/dist/model/build/rule-checks.d.ts +23 -0
  48. package/dist/model/build/rule-references.d.ts +28 -0
  49. package/dist/model/build/scalar-field.d.ts +7 -0
  50. package/dist/model/build/search.d.ts +4 -0
  51. package/dist/model/build/shapes.d.ts +18 -0
  52. package/dist/model/build/unique-together.d.ts +5 -0
  53. package/dist/model/build.d.ts +3 -20
  54. package/dist/model/directives.d.ts +1 -1
  55. package/dist/model/types.d.ts +12 -2
  56. package/dist/options.d.ts +255 -0
  57. package/dist/results.d.ts +70 -0
  58. package/dist/runtime/custom-requires.d.ts +7 -0
  59. package/dist/runtime/database-error.d.ts +10 -0
  60. package/dist/runtime/documents.d.ts +35 -0
  61. package/dist/runtime/limits.d.ts +37 -0
  62. package/dist/runtime/request.d.ts +33 -0
  63. package/dist/runtime/timing.d.ts +13 -0
  64. package/dist/schema/aggregates.d.ts +17 -0
  65. package/dist/schema/base.d.ts +17 -0
  66. package/dist/schema/build.d.ts +3 -42
  67. package/dist/schema/filters.d.ts +10 -0
  68. package/dist/schema/hooks.d.ts +42 -0
  69. package/dist/schema/objects.d.ts +36 -0
  70. package/dist/schema/query.d.ts +8 -0
  71. package/dist/schema/resolvers.d.ts +13 -0
  72. package/dist/schema/sorts.d.ts +5 -0
  73. package/dist/schema/subscriptions.d.ts +7 -0
  74. package/dist/subscriptions/change-hub.d.ts +50 -0
  75. package/dist/subscriptions/compiles.d.ts +23 -0
  76. package/dist/subscriptions/events.d.ts +9 -0
  77. package/dist/subscriptions/filter-cost.d.ts +15 -0
  78. package/dist/subscriptions/subscriptions.d.ts +73 -0
  79. package/dist/testing.d.ts +4 -1
  80. package/dist/testing.js +34 -29
  81. package/dist/testing.js.map +1 -1
  82. package/package.json +2 -2
  83. package/dist/compile/read.d.ts +0 -102
  84. package/dist/diff-B9iDdELF.js.map +0 -1
  85. package/dist/driver-C5dSoSD8.js.map +0 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/migrate.ts","../src/cli.ts"],"sourcesContent":["// `lora-graphql migrate neo4j`: rewrite an @neo4j/graphql SDL into this\n// package's vocabulary. What maps is rewritten; what does not is removed\n// and listed as a TODO. With the client's operations, the opt-in surface\n// (@mutation, @filterable, @sortable) follows observed usage; without\n// them, mutations stay on for every type (as in @neo4j/graphql).\n\nimport {\n Kind,\n parse,\n print,\n visit,\n type ArgumentNode,\n type ConstArgumentNode,\n type ConstDirectiveNode,\n type ConstValueNode,\n type DocumentNode,\n type FieldDefinitionNode,\n type ObjectTypeDefinitionNode,\n type SelectionSetNode,\n type ValueNode,\n} from \"graphql\";\nimport { defaultPlural } from \"./model/build.js\";\n\nexport interface MigrationResult {\n /** The rewritten SDL. */\n typeDefs: string;\n /** What has no equivalent or needs a decision, by type and field. */\n todos: string[];\n}\n\nconst ROOT = new Set([\"Query\", \"Mutation\", \"Subscription\"]);\n\n/** Removed with a TODO: no equivalent here. */\nconst UNSUPPORTED: Record<string, string> = {\n coalesce:\n \"@coalesce is not supported: it hides predicates from indexes; store a value instead\",\n subscriptionsAuthorization:\n \"@subscriptionsAuthorization is not supported: SUBSCRIBE rules go in @authorization\",\n shareable: \"federation (@shareable) is not supported\",\n external: \"federation (@external) is not supported\",\n requires: \"federation (@requires) is not supported\",\n provides: \"federation (@provides) is not supported\",\n exclude: \"@exclude: use @query / @mutation to choose operations\",\n vector:\n \"@vector on types (with a provider) is not supported: put @vector(dimensions:, similarity:) on a [Float!] field\",\n};\n\n/** neo4j 5 filter suffixes → @filterable operators. */\nconst SUFFIX_OPS: Array<[string, string]> = [\n [\"_NOT_IN\", \"IN\"],\n [\"_STARTS_WITH\", \"STARTS_WITH\"],\n [\"_ENDS_WITH\", \"ENDS_WITH\"],\n [\"_CONTAINS\", \"CONTAINS\"],\n [\"_INCLUDES\", \"INCLUDES\"],\n [\"_GTE\", \"GTE\"],\n [\"_LTE\", \"LTE\"],\n [\"_GT\", \"GT\"],\n [\"_LT\", \"LT\"],\n [\"_IN\", \"IN\"],\n [\"_EQ\", \"EQ\"],\n];\n\n/** neo4j 6 nested filter operators → @filterable operators. */\nconst NESTED_OPS: Record<string, string> = {\n eq: \"EQ\",\n in: \"IN\",\n lt: \"LT\",\n lte: \"LTE\",\n gt: \"GT\",\n gte: \"GTE\",\n contains: \"CONTAINS\",\n startsWith: \"STARTS_WITH\",\n endsWith: \"ENDS_WITH\",\n includes: \"INCLUDES\",\n caseInsensitive: \"CASE_INSENSITIVE\",\n};\n\ninterface Usage {\n filters: Map<string, Map<string, Set<string>>>;\n sorts: Map<string, Set<string>>;\n mutations: Map<string, Set<string>>;\n}\n\nexport function migrateNeo4j(\n sdl: string,\n operations: DocumentNode[] = [],\n): MigrationResult {\n const doc = parse(sdl, { noLocation: true });\n const todos: string[] = [];\n const nodeTypes = doc.definitions.filter(\n (d): d is ObjectTypeDefinitionNode =>\n d.kind === Kind.OBJECT_TYPE_DEFINITION &&\n !ROOT.has(d.name.value) &&\n !has(d.directives, \"relationshipProperties\") &&\n !has(d.directives, \"jwt\"),\n );\n const nodeNames = new Set(nodeTypes.map((t) => t.name.value));\n const usage =\n operations.length > 0 ? observe(operations, nodeTypes) : undefined;\n\n const out = visit(doc, {\n ObjectTypeDefinition(t) {\n if (!nodeNames.has(t.name.value)) return undefined;\n const type = t.name.value;\n let directives = migrateDirectives(\n t.directives ?? [],\n type,\n undefined,\n todos,\n );\n if (!has(directives, \"node\"))\n directives = [...directives, directive(\"node\")];\n const ops = usage?.mutations.get(type);\n if (!has(directives, \"mutation\")) {\n if (!usage) {\n directives = [...directives, directive(\"mutation\")];\n todos.push(\n `${type}: @mutation added (@neo4j/graphql generates mutations for every type); remove it or narrow its operations`,\n );\n } else if (ops && ops.size > 0) {\n directives = [\n ...directives,\n directive(\"mutation\", {\n operations: enumList([...ops].sort()),\n }),\n ];\n }\n }\n const idFields = (t.fields ?? []).filter((f) => has(f.directives, \"id\"));\n if (idFields.length === 0) {\n todos.push(\n `${type}: no @id field; add a required @key field (the sort tie-breaker and mutation address)`,\n );\n } else if (idFields.length > 1) {\n todos.push(`${type}: several @id fields; keep one as the @key`);\n }\n const fields = (t.fields ?? []).map((f) =>\n migrateField(f, type, usage, todos),\n );\n return { ...t, directives, fields };\n },\n });\n return { typeDefs: print(out), todos };\n}\n\nfunction migrateField(\n f: FieldDefinitionNode,\n type: string,\n usage: Usage | undefined,\n todos: string[],\n): FieldDefinitionNode {\n let directives = migrateDirectives(\n f.directives ?? [],\n type,\n f.name.value,\n todos,\n );\n const id = directives.find((d) => d.name.value === \"id\");\n if (id) {\n directives = directives.filter(\n (d) => d.name.value !== \"id\" && d.name.value !== \"unique\",\n );\n directives.push(directive(\"key\", { generate: bool(true) }));\n }\n const used = usage?.filters.get(type)?.get(f.name.value);\n if (used && used.size > 0 && !has(directives, \"filterable\")) {\n directives.push(\n has(directives, \"relationship\")\n ? directive(\"filterable\")\n : directive(\"filterable\", { byValue: enumList([...used].sort()) }),\n );\n }\n if (\n usage?.sorts.get(type)?.has(f.name.value) &&\n !has(directives, \"sortable\")\n ) {\n directives.push(directive(\"sortable\"));\n }\n return { ...f, directives };\n}\n\nfunction migrateDirectives(\n directives: readonly ConstDirectiveNode[],\n type: string,\n field: string | undefined,\n todos: string[],\n): ConstDirectiveNode[] {\n const at = field ? `${type}.${field}` : type;\n const out: ConstDirectiveNode[] = [];\n for (const d of directives) {\n const name = d.name.value;\n if (name in UNSUPPORTED) {\n todos.push(`${at}: ${UNSUPPORTED[name]}`);\n continue;\n }\n if (name === \"key\" && !field) {\n todos.push(`${at}: federation @key(fields:) is not supported`);\n continue;\n }\n if (name === \"unique\") {\n out.push(directive(\"unique\"));\n continue;\n }\n if (name === \"relationship\") {\n out.push(migrateRelationship(d, at, todos));\n continue;\n }\n if (name === \"fulltext\") {\n out.push(renameInList(d, \"indexes\", \"indexName\", \"name\"));\n continue;\n }\n if (name === \"subscription\") {\n out.push(migrateSubscription(d, at, todos));\n continue;\n }\n if (name === \"authorization\" || name === \"authentication\") {\n todos.push(\n `${at}: check the @${name} rule's filters: operators are written { field: { eq: ... } } here`,\n );\n }\n out.push(d);\n }\n return out;\n}\n\nfunction migrateRelationship(\n d: ConstDirectiveNode,\n at: string,\n todos: string[],\n): ConstDirectiveNode {\n const args: ConstArgumentNode[] = [];\n for (const a of d.arguments ?? []) {\n const name = a.name.value;\n if (name === \"queryDirection\" && a.value.kind === Kind.ENUM) {\n if (a.value.value.includes(\"UNDIRECTED\")) {\n args.push(arg(\"queryDirection\", enumValue(\"UNDIRECTED\")));\n }\n continue;\n }\n if (name === \"nestedOperations\" && a.value.kind === Kind.LIST) {\n const kept = a.value.values.filter(\n (v) => v.kind === Kind.ENUM && v.value !== \"CONNECT_OR_CREATE\",\n );\n if (kept.length < a.value.values.length) {\n todos.push(`${at}: connectOrCreate is not supported; use upsert`);\n }\n args.push(arg(\"nestedOperations\", { kind: Kind.LIST, values: kept }));\n continue;\n }\n args.push(a);\n }\n return { ...d, arguments: args };\n}\n\nfunction migrateSubscription(\n d: ConstDirectiveNode,\n at: string,\n todos: string[],\n): ConstDirectiveNode {\n const events = d.arguments?.find((a) => a.name.value === \"events\")?.value;\n if (!events || events.kind !== Kind.LIST) return d;\n const ops = new Set<string>();\n let relationships = false;\n for (const e of events.values) {\n if (e.kind !== Kind.ENUM) continue;\n if (e.value.startsWith(\"CREATED\") && !e.value.includes(\"RELATIONSHIP\"))\n ops.add(\"CREATE\");\n else if (e.value.startsWith(\"UPDATED\")) ops.add(\"UPDATE\");\n else if (e.value.startsWith(\"DELETED\") && !e.value.includes(\"RELATIONSHIP\"))\n ops.add(\"DELETE\");\n else if (e.value.includes(\"RELATIONSHIP\")) relationships = true;\n }\n todos.push(\n `${at}: subscriptions see writes made through this library (or the engine change feed), not CDC`,\n );\n return directive(\"subscription\", {\n operations: enumList([...ops].sort()),\n ...(relationships ? { relationships: bool(true) } : {}),\n });\n}\n\n/** What the client's operations use: filters, sorts and mutations per type. */\nfunction observe(\n operations: DocumentNode[],\n types: ObjectTypeDefinitionNode[],\n): Usage {\n const usage: Usage = {\n filters: new Map(),\n sorts: new Map(),\n mutations: new Map(),\n };\n // Root fields as either naming would call them: this package's plural\n // and @neo4j/graphql's (which knows irregular plurals, e.g. people).\n const byPlural = new Map<string, ObjectTypeDefinitionNode>();\n for (const t of types) {\n byPlural.set(defaultPlural(t.name.value), t);\n byPlural.set(neo4jPlural(t.name.value), t);\n }\n const byName = new Map(types.map((t) => [t.name.value, t]));\n const note = (type: string, field: string, op: string) => {\n const fields = usage.filters.get(type) ?? new Map<string, Set<string>>();\n const ops = fields.get(field) ?? new Set<string>();\n ops.add(op);\n fields.set(field, ops);\n usage.filters.set(type, fields);\n };\n const where = (type: ObjectTypeDefinitionNode, value: ValueNode) => {\n if (value.kind !== Kind.OBJECT) return;\n for (const f of value.fields) {\n const key = f.name.value;\n if (key === \"AND\" || key === \"OR\") {\n if (f.value.kind === Kind.LIST)\n for (const v of f.value.values) where(type, v);\n continue;\n }\n if (key === \"NOT\") {\n where(type, f.value);\n continue;\n }\n // neo4j 5 relationship quantifiers: `actors_SOME: { name_EQ: ... }`.\n const quantifier = /^(.+)_(SOME|ALL|NONE|SINGLE)$/.exec(key);\n if (quantifier) {\n const rel = type.fields?.find((x) => x.name.value === quantifier[1]);\n const target = rel && byName.get(namedTypeOf(rel));\n if (rel && target) {\n note(type.name.value, quantifier[1]!, \"EQ\");\n where(target, f.value);\n }\n continue;\n }\n const suffix = SUFFIX_OPS.find(([s]) => key.endsWith(s));\n const fieldName = suffix ? key.slice(0, -suffix[0].length) : key;\n const def = type.fields?.find((x) => x.name.value === fieldName);\n if (!def) continue;\n const target = byName.get(namedTypeOf(def));\n if (target) {\n note(type.name.value, fieldName, \"EQ\");\n // `some` / `all` / `none` / `single`, or a nested where.\n if (f.value.kind === Kind.OBJECT) {\n for (const inner of f.value.fields) where(target, inner.value);\n where(target, f.value);\n }\n continue;\n }\n if (suffix) note(type.name.value, fieldName, suffix[1]);\n else if (f.value.kind === Kind.OBJECT) {\n for (const op of f.value.fields) {\n const mapped = NESTED_OPS[op.name.value];\n if (mapped) note(type.name.value, fieldName, mapped);\n }\n } else note(type.name.value, fieldName, \"EQ\");\n }\n };\n const walk = (set: SelectionSetNode | undefined, root: boolean) => {\n for (const sel of set?.selections ?? []) {\n if (sel.kind !== Kind.FIELD) continue;\n const name = sel.name.value;\n if (root) {\n const mutation = /^(create|update|delete|upsert)(.+)$/.exec(name);\n const plural = name.replace(/(Connection|Aggregate)$/, \"\");\n const type =\n byPlural.get(plural) ??\n (mutation ? byPlural.get(lowerFirst(mutation[2]!)) : undefined);\n if (type && mutation) {\n const ops = usage.mutations.get(type.name.value) ?? new Set<string>();\n const op = mutation[1]!.toUpperCase();\n if (op === \"UPSERT\") {\n ops.add(\"CREATE\");\n ops.add(\"UPDATE\");\n } else ops.add(op);\n usage.mutations.set(type.name.value, ops);\n }\n if (type) {\n for (const a of sel.arguments ?? []) argumentUse(type, a);\n }\n }\n walk(sel.selectionSet, false);\n }\n };\n const argumentUse = (type: ObjectTypeDefinitionNode, a: ArgumentNode) => {\n if (a.name.value === \"where\") where(type, a.value);\n if (a.name.value === \"sort\" || a.name.value === \"options\") {\n const sorts = usage.sorts.get(type.name.value) ?? new Set<string>();\n const collect = (v: ValueNode) => {\n if (v.kind === Kind.LIST) v.values.forEach(collect);\n else if (v.kind === Kind.OBJECT) {\n for (const f of v.fields) {\n if (f.name.value === \"sort\") collect(f.value);\n else if (f.value.kind === Kind.ENUM) sorts.add(f.name.value);\n }\n }\n };\n collect(a.value);\n usage.sorts.set(type.name.value, sorts);\n }\n };\n for (const doc of operations) {\n for (const def of doc.definitions) {\n if (def.kind === Kind.OPERATION_DEFINITION) walk(def.selectionSet, true);\n }\n }\n return usage;\n}\n\nfunction namedTypeOf(f: FieldDefinitionNode): string {\n let t = f.type;\n while (t.kind !== Kind.NAMED_TYPE) t = t.type;\n return t.name.value;\n}\n\nfunction has(\n directives: readonly ConstDirectiveNode[] | undefined,\n name: string,\n): boolean {\n return (directives ?? []).some((d) => d.name.value === name);\n}\n\nfunction directive(\n name: string,\n args: Record<string, ConstValueNode> = {},\n): ConstDirectiveNode {\n return {\n kind: Kind.DIRECTIVE,\n name: { kind: Kind.NAME, value: name },\n arguments: Object.entries(args).map(([k, v]) => arg(k, v)),\n };\n}\n\nfunction arg(name: string, value: ConstValueNode): ConstArgumentNode {\n return { kind: Kind.ARGUMENT, name: { kind: Kind.NAME, value: name }, value };\n}\n\nconst enumValue = (value: string): ConstValueNode => ({\n kind: Kind.ENUM,\n value,\n});\nconst bool = (value: boolean): ConstValueNode => ({\n kind: Kind.BOOLEAN,\n value,\n});\nconst enumList = (values: string[]): ConstValueNode => ({\n kind: Kind.LIST,\n values: values.map(enumValue),\n});\n\n/** Rename a key inside each object of a list argument. */\nfunction renameInList(\n d: ConstDirectiveNode,\n argName: string,\n from: string,\n to: string,\n): ConstDirectiveNode {\n return {\n ...d,\n arguments: (d.arguments ?? []).map((a) =>\n a.name.value === argName && a.value.kind === Kind.LIST\n ? arg(argName, {\n kind: Kind.LIST,\n values: a.value.values.map((v) =>\n v.kind === Kind.OBJECT\n ? {\n ...v,\n fields: v.fields.map((f) =>\n f.name.value === from\n ? { ...f, name: { kind: Kind.NAME, value: to } }\n : f,\n ),\n }\n : v,\n ),\n })\n : a,\n ),\n };\n}\n\nconst IRREGULAR: Record<string, string> = {\n person: \"people\",\n man: \"men\",\n woman: \"women\",\n child: \"children\",\n mouse: \"mice\",\n goose: \"geese\",\n foot: \"feet\",\n tooth: \"teeth\",\n};\n\nfunction neo4jPlural(typeName: string): string {\n const base = lowerFirst(typeName);\n const lower = base.toLowerCase();\n for (const [one, many] of Object.entries(IRREGULAR)) {\n if (lower.endsWith(one))\n return base.slice(0, base.length - one.length) + many;\n }\n return defaultPlural(typeName);\n}\n\nfunction lowerFirst(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n","// lora-graphql: the build-time half of the library.\n//\n// lora-graphql print <schema.graphql>\n// lora-graphql directives\n// lora-graphql requirements <schema.graphql> [--ddl]\n// lora-graphql check <schema.graphql> [--operations <file|dir>]... [--variables <file>] [--context <file>]\n// [--baseline <file> [--update-baseline]] [--row-budget <n>]\n// [--database <dir> [--name <db>]] [--json]\n// lora-graphql compile <schema.graphql> --operations <file|dir>... [--out <dir>]\n// lora-graphql analyze <schema.graphql> --database <dir> [--name <db>] [--sample <n>]\n// lora-graphql migrate neo4j <schema.graphql> [--operations <file|dir>]...\n// lora-graphql diff <old.graphql> <new.graphql> [--allow-breaking] [--json]\n// lora-graphql diff --base <git-ref> <file|dir>... [--allow-breaking] [--json]\n\nimport { execFileSync } from \"node:child_process\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n getNamedType,\n isEnumType,\n isInputObjectType,\n isListType,\n isNonNullType,\n Kind,\n parse,\n print as printAst,\n typeFromAST,\n visit,\n type DefinitionNode,\n type FragmentDefinitionNode,\n type GraphQLInputType,\n type GraphQLSchema,\n type OperationDefinitionNode,\n} from \"graphql\";\nimport { diffSchemas } from \"./analyze/diff.js\";\nimport { formatProblem, ModelError } from \"./errors.js\";\nimport { buildModel } from \"./model/build.js\";\nimport { directiveTypeDefs } from \"./model/directives.js\";\nimport {\n describeRequirement,\n inferRequirements,\n requirementDdl,\n} from \"./analyze/indexes.js\";\nimport { LoraGraphQL, type CheckOptions } from \"./lora-graphql.js\";\nimport { loraDriver, type LoraDriver } from \"./driver.js\";\nimport { usedFragments } from \"./codegen.js\";\nimport { migrateNeo4j } from \"./migrate.js\";\n\nconst USAGE = `lora-graphql <command>\n\n print <schema.graphql> the public SDL clients see\n directives the directive definitions, for editors\n access <schema.graphql> [--json] who may do what: each type and guarded field,\n operation and kind of caller\n requirements <schema.graphql> [--ddl] constraints and indexes the API needs\n check <schema.graphql> [--operations <file|dir>]... [--json]\n [--variables <file>] [--context <file>]\n [--baseline <file> [--update-baseline]]\n [--row-budget <n>] [--database <dir> [--name <db>]]\n CI gate: model, lint, @cypher statements and\n the plans of your operations, on an in-memory\n LoraDB (or an existing one with --database)\n compile <schema.graphql> --operations <file|dir>... [--out <dir>]\n persisted-operation manifest.json and\n operations.d.ts types\n analyze <schema.graphql> --database <dir> [--name <db>] [--sample <n>]\n statistics JSON for useStatistics()\n migrate neo4j <schema.graphql> [--operations <file|dir>]...\n rewrite an @neo4j/graphql SDL; TODOs for\n what has no equivalent\n diff <old.graphql> <new.graphql> [--allow-breaking] [--json]\n diff --base <git-ref> <file|dir>... [--allow-breaking] [--json]\n database statements and API changes; exit 1\n on a breaking change or a destructive statement\n (--base: the SDL files at a git ref against the\n working tree, each side concatenated)`;\n\ninterface Io {\n out: (line: string) => void;\n err: (line: string) => void;\n}\n\nexport async function main(\n argv: string[],\n io: Io = defaultIo,\n): Promise<number> {\n const [command, ...rest] = argv;\n const flags = new Set<string>();\n const values = new Map<string, string>();\n const positional: string[] = [];\n const operations: string[] = [];\n for (let i = 0; i < rest.length; i++) {\n const a = rest[i]!;\n if (a === \"--operations\") operations.push(rest[++i] ?? \"\");\n else if (VALUE_FLAGS.has(a)) values.set(a, rest[++i] ?? \"\");\n else if (a.startsWith(\"--\")) flags.add(a);\n else positional.push(a);\n }\n try {\n switch (command) {\n case \"print\":\n return await print(need(positional, 1), io);\n case \"directives\":\n io.out(directiveTypeDefs.trim());\n return 0;\n case \"access\":\n return await access(need(positional, 1), flags.has(\"--json\"), io);\n case \"requirements\":\n return await requirements(need(positional, 1), flags.has(\"--ddl\"), io);\n case \"check\":\n return await check(need(positional, 1), operations, flags, values, io);\n case \"compile\":\n return await compile(need(positional, 1), operations, values, io);\n case \"analyze\":\n return await analyzeCommand(need(positional, 1), values, io);\n case \"migrate\": {\n const [from, file] = need(positional, 2);\n if (from !== \"neo4j\") throw new UsageError(\"migrate supports neo4j\");\n const docs = [];\n for (const path of operations) {\n for (const f of await graphqlFiles(path)) docs.push(parse(f.source));\n }\n const result = migrateNeo4j(await read(file!), docs);\n for (const t of result.todos) io.out(`# TODO(migrate): ${t}`);\n if (result.todos.length > 0) io.out(\"\");\n io.out(result.typeDefs);\n return 0;\n }\n case \"diff\": {\n const base = values.get(\"--base\");\n if (base !== undefined) {\n if (!base) throw new UsageError(\"--base takes a git ref\");\n const paths = need(positional, 1);\n const before = await atGitRef(base, paths);\n if (before === undefined) {\n io.out(\n `${base} has none of ${paths.join(\", \")}; nothing to compare`,\n );\n return 0;\n }\n return diff(before, await sdlFiles(paths), flags, io);\n }\n const [before, after] = need(positional, 2);\n return diff(await read(before!), await read(after!), flags, io);\n }\n default:\n io.err(USAGE);\n return 2;\n }\n } catch (err) {\n if (err instanceof UsageError) {\n io.err(`${err.message}\\n\\n${USAGE}`);\n return 2;\n }\n if (err instanceof ModelError) {\n io.err(err.message);\n return 1;\n }\n io.err(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\nclass UsageError extends Error {}\n\nconst VALUE_FLAGS = new Set([\n \"--base\",\n \"--out\",\n \"--variables\",\n \"--context\",\n \"--baseline\",\n \"--row-budget\",\n \"--database\",\n \"--name\",\n \"--sample\",\n]);\n\nfunction need(positional: string[], n: number): string[] {\n if (positional.length < n)\n throw new UsageError(`expected ${n} file argument(s)`);\n return positional;\n}\n\nconst read = (path: string) => readFile(path, \"utf8\");\n\n/** A LoraGraphQL over a driver that refuses to run anything. */\nfunction offline(typeDefs: string): LoraGraphQL {\n const driver: LoraDriver = {\n run: () => Promise.reject(new Error(\"no database\")),\n };\n return new LoraGraphQL({ typeDefs, driver });\n}\n\nasync function access(\n [file]: string[],\n json: boolean,\n io: Io,\n): Promise<number> {\n const matrix = offline(await read(file!)).accessMatrix();\n if (json) {\n io.out(JSON.stringify(matrix, null, 2));\n return 0;\n }\n const rows = matrix.map((e) => [\n e.field ? `${e.type}.${e.field}` : e.type,\n e.operation,\n e.principal,\n e.verdict,\n e.by.join(\", \"),\n ]);\n const widths = [0, 1, 2, 3].map((i) =>\n Math.max(...rows.map((r) => r[i]!.length), 0),\n );\n for (const r of rows) {\n io.out(\n r\n .map((cell, i) => (i < 4 ? cell.padEnd(widths[i]!) : cell))\n .join(\" \")\n .trimEnd(),\n );\n }\n return 0;\n}\n\nasync function print([file]: string[], io: Io): Promise<number> {\n io.out(offline(await read(file!)).printPublicSchema());\n return 0;\n}\n\nasync function requirements(\n [file]: string[],\n ddl: boolean,\n io: Io,\n): Promise<number> {\n const model = buildModel(await read(file!));\n for (const r of inferRequirements(model)) {\n io.out(\n ddl\n ? `${requirementDdl(r)};`\n : `${describeRequirement(r)}, because ${r.reason}`,\n );\n }\n return 0;\n}\n\n/** The node binding's createDatabase, or a message saying how to get it. */\nasync function nodeBinding(\n io: Io,\n command: string,\n): Promise<\n | ((name?: string, options?: { databaseDir?: string }) => Promise<unknown>)\n | undefined\n> {\n try {\n const { createDatabase } =\n (await import(\"@loradb/lora-node\")) as unknown as {\n createDatabase: (\n name?: string,\n options?: { databaseDir?: string },\n ) => Promise<unknown>;\n };\n return createDatabase;\n } catch {\n io.err(\n `${command} needs @loradb/lora-node: npm install --save-dev @loradb/lora-node`,\n );\n return undefined;\n }\n}\n\nasync function check(\n [file]: string[],\n operationPaths: string[],\n flags: Set<string>,\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n const json = flags.has(\"--json\");\n const typeDefs = await read(file!);\n const createDatabase = await nodeBinding(io, \"check\");\n if (!createDatabase) return 1;\n // An existing database is checked as it is; an in-memory one gets what\n // the API needs, so only the plans are under test.\n const databaseDir = values.get(\"--database\");\n const db = await createDatabase(\n databaseDir ? (values.get(\"--name\") ?? \"app\") : undefined,\n databaseDir ? { databaseDir } : {},\n );\n const lora = new LoraGraphQL({\n typeDefs,\n driver: loraDriver(db as Parameters<typeof loraDriver>[0]),\n });\n if (!databaseDir) await lora.assertSchema({ create: true });\n const schema = lora.getSchema();\n const fixtures = values.has(\"--variables\")\n ? (JSON.parse(await read(values.get(\"--variables\")!)) as Record<\n string,\n Record<string, unknown>\n >)\n : {};\n // GraphQL contexts per operation name, `*` for every other operation.\n const contexts = values.has(\"--context\")\n ? (JSON.parse(await read(values.get(\"--context\")!)) as Record<\n string,\n unknown\n >)\n : {};\n const operations: NonNullable<CheckOptions[\"operations\"]> = [];\n for (const path of operationPaths) {\n for (const f of await graphqlFiles(path)) {\n for (const op of operationsIn(schema, f.path, f.source)) {\n const short = op.name!.split(\"#\")[1] ?? \"\";\n const given = fixtures[op.name!] ?? fixtures[short];\n const context = contexts[op.name!] ?? contexts[short] ?? contexts[\"*\"];\n operations.push({\n ...op,\n ...(given ? { variables: given } : {}),\n ...(context !== undefined ? { context } : {}),\n });\n }\n }\n }\n const rowBudget = values.has(\"--row-budget\")\n ? Number(values.get(\"--row-budget\"))\n : undefined;\n const report = await lora.check({\n operations,\n ...(rowBudget !== undefined ? { rowBudget } : {}),\n });\n\n // Plan baseline: the operators of every statement, so a plan change\n // shows up in review.\n const baselinePath = values.get(\"--baseline\");\n const current: Record<string, string[][]> = {};\n for (const p of report.plans) {\n current[`${p.operation} › ${p.field}`] = p.reports.map((r) => r.operators);\n }\n const changed: string[] = [];\n if (baselinePath) {\n let before: Record<string, string[][]> | undefined;\n try {\n before = JSON.parse(await read(baselinePath)) as Record<\n string,\n string[][]\n >;\n } catch {\n before = undefined;\n }\n if (flags.has(\"--update-baseline\") || !before) {\n await writeFile(baselinePath, JSON.stringify(current, null, 2) + \"\\n\");\n } else {\n for (const key of new Set([\n ...Object.keys(before),\n ...Object.keys(current),\n ])) {\n if (JSON.stringify(before[key]) !== JSON.stringify(current[key])) {\n changed.push(key);\n }\n }\n }\n }\n const ok = report.ok && changed.length === 0;\n\n if (json) {\n io.out(JSON.stringify({ ...report, ok, planChanges: changed }, null, 2));\n return ok ? 0 : 1;\n }\n for (const w of report.warnings) io.out(`warning ${formatProblem(w)}`);\n for (const w of report.lint) io.out(`lint ${formatProblem(w)}`);\n for (const u of report.unused) {\n io.out(\n `unused ${u.type} index ${u.name} on :${u.labels.join(\":\")}(${u.properties.join(\", \")})`,\n );\n }\n for (const s of report.security) io.out(`error ${formatProblem(s)}`);\n for (const m of report.missing)\n io.out(`error missing ${describeRequirement(m)}`);\n for (const c of report.cypher)\n io.out(`error ${c.type}.${c.field}: ${c.message}`);\n for (const e of report.errors)\n io.out(`error ${e.operation}: ${e.message}`);\n for (const p of report.plans) {\n for (const r of p.reports) {\n for (const f of r.findings) {\n io.out(`error ${p.operation} › ${p.field}: ${f.message}`);\n }\n for (const n of r.notes) {\n io.out(`lint ${p.operation} › ${p.field}: ${n.message}`);\n }\n }\n }\n for (const key of changed) {\n io.out(\n `error ${key}: the plan differs from the baseline (--update-baseline to accept)`,\n );\n }\n const checked = report.plans.length;\n io.out(\n ok\n ? `ok ${checked} root field(s) in ${operations.length} operation(s) seek as expected`\n : \"failed\",\n );\n return ok ? 0 : 1;\n}\n\n/** Persisted operations from .graphql files (one per operation) or JSON (id → source). */\nasync function persistedOperations(\n paths: string[],\n): Promise<Record<string, string>> {\n const out: Record<string, string> = {};\n for (const path of paths) {\n const info = await stat(path);\n if (info.isFile() && path.endsWith(\".json\")) {\n Object.assign(\n out,\n JSON.parse(await read(path)) as Record<string, string>,\n );\n continue;\n }\n for (const f of await graphqlFiles(path)) {\n const doc = parse(f.source);\n const fragments = new Map(\n doc.definitions\n .filter(\n (d): d is FragmentDefinitionNode =>\n d.kind === Kind.FRAGMENT_DEFINITION,\n )\n .map((d) => [d.name.value, d]),\n );\n const rel = relative(process.cwd(), f.path);\n doc.definitions\n .filter(\n (d): d is OperationDefinitionNode =>\n d.kind === Kind.OPERATION_DEFINITION,\n )\n .forEach((op, i) => {\n const id = `${rel}#${op.name?.value ?? i + 1}`;\n out[id] = printAst({\n kind: Kind.DOCUMENT,\n definitions: [op, ...usedFragments(op, fragments)],\n });\n });\n }\n }\n return out;\n}\n\nasync function compile(\n [file]: string[],\n operationPaths: string[],\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n if (operationPaths.length === 0) {\n throw new UsageError(\"compile needs --operations <file|dir>\");\n }\n const lora = offline(await read(file!));\n const manifest = lora.buildManifest(\n await persistedOperations(operationPaths),\n );\n const outDir = values.get(\"--out\") ?? \"lora-graphql\";\n await mkdir(outDir, { recursive: true });\n await writeFile(\n join(outDir, \"manifest.json\"),\n JSON.stringify(manifest) + \"\\n\",\n );\n await writeFile(\n join(outDir, \"operations.d.ts\"),\n lora.generateTypes(manifest),\n );\n io.out(\n `wrote ${Object.keys(manifest.operations).length} operation(s) to ${join(outDir, \"manifest.json\")} and ${join(outDir, \"operations.d.ts\")}`,\n );\n return 0;\n}\n\nasync function analyzeCommand(\n [file]: string[],\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n const databaseDir = values.get(\"--database\");\n if (!databaseDir) throw new UsageError(\"analyze needs --database <dir>\");\n const createDatabase = await nodeBinding(io, \"analyze\");\n if (!createDatabase) return 1;\n const db = await createDatabase(values.get(\"--name\") ?? \"app\", {\n databaseDir,\n });\n const lora = new LoraGraphQL({\n typeDefs: await read(file!),\n driver: loraDriver(db as Parameters<typeof loraDriver>[0]),\n });\n const sample = values.has(\"--sample\")\n ? Number(values.get(\"--sample\"))\n : undefined;\n const stats = await lora.analyze(sample !== undefined ? { sample } : {});\n io.out(JSON.stringify(stats, null, 2));\n (db as { dispose?: () => void }).dispose?.();\n return 0;\n}\n\nasync function graphqlFiles(\n path: string,\n): Promise<Array<{ path: string; source: string }>> {\n const info = await stat(path);\n if (info.isFile()) return [{ path, source: await read(path) }];\n const out: Array<{ path: string; source: string }> = [];\n for (const entry of await readdir(path, { withFileTypes: true })) {\n const full = join(path, entry.name);\n if (entry.isDirectory()) out.push(...(await graphqlFiles(full)));\n else if (/\\.(graphql|gql)$/.test(entry.name)) {\n out.push({ path: full, source: await read(full) });\n }\n }\n return out;\n}\n\n/** Each query in a file, with example values for its required variables. */\nfunction operationsIn(\n schema: GraphQLSchema,\n path: string,\n source: string,\n): NonNullable<CheckOptions[\"operations\"]> {\n const doc = parse(source);\n const fragments = new Map(\n doc.definitions\n .filter(\n (d): d is FragmentDefinitionNode => d.kind === Kind.FRAGMENT_DEFINITION,\n )\n .map((f) => [f.name.value, f]),\n );\n // The fragments an operation spreads, transitively.\n const used = (root: DefinitionNode): FragmentDefinitionNode[] => {\n const seen = new Map<string, FragmentDefinitionNode>();\n const walk = (node: DefinitionNode) =>\n visit(node, {\n FragmentSpread(spread) {\n const f = fragments.get(spread.name.value);\n if (f && !seen.has(f.name.value)) {\n seen.set(f.name.value, f);\n walk(f);\n }\n },\n });\n walk(root);\n return [...seen.values()];\n };\n return doc.definitions\n .filter(\n (d): d is OperationDefinitionNode =>\n d.kind === Kind.OPERATION_DEFINITION && d.operation === \"query\",\n )\n .map((op, i) => {\n const variables: Record<string, unknown> = {};\n for (const v of op.variableDefinitions ?? []) {\n if (v.defaultValue || v.type.kind !== Kind.NON_NULL_TYPE) continue;\n const type = typeFromAST(schema, v.type) as\n | GraphQLInputType\n | undefined;\n if (type) variables[v.variable.name.value] = sample(type);\n }\n return {\n name: `${path}${op.name ? `#${op.name.value}` : `#${i + 1}`}`,\n document: { kind: Kind.DOCUMENT, definitions: [op, ...used(op)] },\n variables,\n };\n });\n}\n\nconst SAMPLES: Record<string, unknown> = {\n String: \"x\",\n ID: \"x\",\n Int: 1,\n Float: 1,\n Boolean: true,\n BigInt: \"1\",\n Date: \"2026-01-01\",\n Time: \"12:00:00Z\",\n LocalTime: \"12:00:00\",\n DateTime: \"2026-01-01T12:00:00Z\",\n LocalDateTime: \"2026-01-01T12:00:00\",\n Duration: \"P1D\",\n};\n\nfunction sample(type: GraphQLInputType): unknown {\n const inner = isNonNullType(type) ? type.ofType : type;\n if (isListType(inner)) return [sample(inner.ofType)];\n const named = getNamedType(inner);\n if (isEnumType(named)) return named.getValues()[0]?.value;\n if (isInputObjectType(named)) {\n const out: Record<string, unknown> = {};\n for (const f of Object.values(named.getFields())) {\n if (isNonNullType(f.type) && f.defaultValue === undefined) {\n out[f.name] = sample(f.type);\n }\n }\n return out;\n }\n return SAMPLES[named.name] ?? \"x\";\n}\n\nconst SDL_FILE = /\\.(graphql|gql)$/;\n\n/** The SDL in `paths` (files, or directories searched recursively), joined. */\nasync function sdlFiles(paths: string[]): Promise<string> {\n const parts: string[] = [];\n for (const path of paths) {\n const files = await graphqlFiles(path);\n files.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n parts.push(...files.map((f) => f.source));\n }\n return parts.join(\"\\n\");\n}\n\n/**\n * The SDL in `paths` as of git `ref`, joined in the same order as\n * `sdlFiles`, or undefined when the ref has none of them (a base from\n * before the schema existed). A ref that is not a commit is an error: a\n * gate that silently compared nothing would pass without looking.\n */\nasync function atGitRef(\n ref: string,\n paths: string[],\n): Promise<string | undefined> {\n const git = (cwd: string, ...args: string[]) =>\n execFileSync(\"git\", args, {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n maxBuffer: 64 * 1024 * 1024,\n });\n const parts: string[] = [];\n let found = false;\n for (const path of paths) {\n // Run git next to the path and name it `./…`, so relative and\n // absolute paths both resolve, from any directory of the repository.\n const isDir = await stat(path).then(\n (s) => s.isDirectory(),\n () => !SDL_FILE.test(path),\n );\n const cwd = isDir ? path : dirname(path);\n try {\n git(cwd, \"rev-parse\", \"--verify\", \"--quiet\", `${ref}^{commit}`);\n } catch {\n throw new Error(\n `diff: ${ref} is not a commit (fetch it, or pass another ref)`,\n );\n }\n if (!isDir) {\n try {\n parts.push(git(cwd, \"show\", `${ref}:./${basename(path)}`));\n found = true;\n } catch {\n // Not in the base: a new file.\n }\n continue;\n }\n // Paths come back relative to `cwd`; none when the directory is not\n // in the base.\n const files = git(cwd, \"ls-tree\", \"-r\", \"--name-only\", ref, \"--\", \".\")\n .split(\"\\n\")\n .filter((f) => SDL_FILE.test(f));\n // Same order as sdlFiles: by path.\n files.sort((a, b) => {\n const pa = join(path, a);\n const pb = join(path, b);\n return pa < pb ? -1 : pa > pb ? 1 : 0;\n });\n for (const f of files) {\n parts.push(git(cwd, \"show\", `${ref}:./${f}`));\n found = true;\n }\n }\n return found ? parts.join(\"\\n\") : undefined;\n}\n\nfunction diff(\n before: string,\n after: string,\n flags: Set<string>,\n io: Io,\n): number {\n const result = diffSchemas(before, after);\n const breaking = result.api.breaking.length > 0;\n const destructive = result.database.statements.some((s) => s.destructive);\n const code =\n (breaking || destructive) && !flags.has(\"--allow-breaking\") ? 1 : 0;\n if (flags.has(\"--json\")) {\n io.out(JSON.stringify(result, null, 2));\n return code;\n }\n io.out(\"# Database\");\n if (result.database.statements.length === 0) io.out(\"no changes\");\n for (const s of result.database.statements) {\n io.out(`${s.destructive ? \"// destructive: \" : \"// \"}${s.reason}`);\n io.out(`${s.text};`);\n }\n io.out(\"\\n# API\");\n if (!breaking && result.api.dangerous.length === 0) io.out(\"no changes\");\n for (const c of result.api.breaking) io.out(`breaking ${c.description}`);\n for (const c of result.api.dangerous) io.out(`dangerous ${c.description}`);\n for (const n of result.notes) io.out(`note ${n}`);\n return code;\n}\n\nconst defaultIo: Io = {\n out: (line) => process.stdout.write(line + \"\\n\"),\n err: (line) => process.stderr.write(line + \"\\n\"),\n};\n\nconst invokedDirectly =\n typeof process !== \"undefined\" &&\n process.argv[1] !== undefined &&\n /lora-graphql(\\.js)?$|cli\\.js$/.test(process.argv[1]);\nif (invokedDirectly) {\n main(process.argv.slice(2)).then((code) => process.exit(code));\n}\n"],"names":["ROOT","UNSUPPORTED","SUFFIX_OPS","NESTED_OPS","migrateNeo4j","sdl","operations","doc","parse","todos","nodeTypes","d","Kind","has","nodeNames","t","usage","observe","out","visit","type","directives","migrateDirectives","directive","ops","enumList","idFields","f","fields","migrateField","print","bool","used","field","at","name","migrateRelationship","renameInList","migrateSubscription","args","a","arg","enumValue","kept","v","events","relationships","e","types","byPlural","defaultPlural","neo4jPlural","byName","note","op","where","value","key","quantifier","rel","x","target","namedTypeOf","suffix","s","fieldName","def","inner","mapped","walk","set","root","sel","mutation","plural","lowerFirst","argumentUse","sorts","collect","k","values","argName","from","to","IRREGULAR","typeName","base","lower","one","many","USAGE","main","argv","io","defaultIo","command","rest","flags","positional","i","VALUE_FLAGS","need","directiveTypeDefs","access","requirements","check","compile","analyzeCommand","file","UsageError","docs","path","graphqlFiles","result","read","paths","before","atGitRef","diff","sdlFiles","after","err","ModelError","n","readFile","offline","typeDefs","driver","LoraGraphQL","json","matrix","rows","widths","r","cell","ddl","model","buildModel","inferRequirements","requirementDdl","describeRequirement","nodeBinding","createDatabase","operationPaths","databaseDir","db","lora","loraDriver","schema","fixtures","contexts","operationsIn","short","given","context","rowBudget","report","baselinePath","current","p","changed","writeFile","ok","w","formatProblem","u","m","c","checked","persistedOperations","stat","fragments","relative","id","printAst","usedFragments","manifest","outDir","mkdir","join","sample","stats","entry","readdir","full","source","seen","node","spread","variables","typeFromAST","SAMPLES","isNonNullType","isListType","named","getNamedType","isEnumType","isInputObjectType","SDL_FILE","parts","files","b","ref","git","cwd","execFileSync","found","isDir","dirname","basename","pa","pb","diffSchemas","breaking","destructive","code","line","invokedDirectly"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/migrate.ts","../src/cli.ts"],"sourcesContent":["// `lora-graphql migrate neo4j`: rewrite an @neo4j/graphql SDL into this\n// package's vocabulary. What maps is rewritten; what does not is removed\n// and listed as a TODO. With the client's operations, the opt-in surface\n// (@mutation, @filterable, @sortable) follows observed usage; without\n// them, mutations stay on for every type (as in @neo4j/graphql).\n\nimport {\n Kind,\n parse,\n print,\n visit,\n type ArgumentNode,\n type ConstArgumentNode,\n type ConstDirectiveNode,\n type ConstValueNode,\n type DocumentNode,\n type FieldDefinitionNode,\n type ObjectTypeDefinitionNode,\n type SelectionSetNode,\n type ValueNode,\n} from \"graphql\";\nimport { defaultPlural } from \"./model/build/shapes.js\";\n\nexport interface MigrationResult {\n /** The rewritten SDL. */\n typeDefs: string;\n /** What has no equivalent or needs a decision, by type and field. */\n todos: string[];\n}\n\nconst ROOT = new Set([\"Query\", \"Mutation\", \"Subscription\"]);\n\n/** Removed with a TODO: no equivalent here. */\nconst UNSUPPORTED: Record<string, string> = {\n coalesce:\n \"@coalesce is not supported: it hides predicates from indexes; store a value instead\",\n subscriptionsAuthorization:\n \"@subscriptionsAuthorization is not supported: SUBSCRIBE rules go in @authorization\",\n shareable: \"federation (@shareable) is not supported\",\n external: \"federation (@external) is not supported\",\n requires: \"federation (@requires) is not supported\",\n provides: \"federation (@provides) is not supported\",\n exclude: \"@exclude: use @query / @mutation to choose operations\",\n vector:\n \"@vector on types (with a provider) is not supported: put @vector(dimensions:, similarity:) on a [Float!] field\",\n};\n\n/** neo4j 5 filter suffixes → @filterable operators. */\nconst SUFFIX_OPS: Array<[string, string]> = [\n [\"_NOT_IN\", \"IN\"],\n [\"_STARTS_WITH\", \"STARTS_WITH\"],\n [\"_ENDS_WITH\", \"ENDS_WITH\"],\n [\"_CONTAINS\", \"CONTAINS\"],\n [\"_INCLUDES\", \"INCLUDES\"],\n [\"_GTE\", \"GTE\"],\n [\"_LTE\", \"LTE\"],\n [\"_GT\", \"GT\"],\n [\"_LT\", \"LT\"],\n [\"_IN\", \"IN\"],\n [\"_EQ\", \"EQ\"],\n];\n\n/** neo4j 6 nested filter operators → @filterable operators. */\nconst NESTED_OPS: Record<string, string> = {\n eq: \"EQ\",\n in: \"IN\",\n lt: \"LT\",\n lte: \"LTE\",\n gt: \"GT\",\n gte: \"GTE\",\n contains: \"CONTAINS\",\n startsWith: \"STARTS_WITH\",\n endsWith: \"ENDS_WITH\",\n includes: \"INCLUDES\",\n caseInsensitive: \"CASE_INSENSITIVE\",\n};\n\ninterface Usage {\n filters: Map<string, Map<string, Set<string>>>;\n sorts: Map<string, Set<string>>;\n mutations: Map<string, Set<string>>;\n}\n\nexport function migrateNeo4j(\n sdl: string,\n operations: DocumentNode[] = [],\n): MigrationResult {\n const doc = parse(sdl, { noLocation: true });\n const todos: string[] = [];\n const nodeTypes = doc.definitions.filter(\n (d): d is ObjectTypeDefinitionNode =>\n d.kind === Kind.OBJECT_TYPE_DEFINITION &&\n !ROOT.has(d.name.value) &&\n !has(d.directives, \"relationshipProperties\") &&\n !has(d.directives, \"jwt\"),\n );\n const nodeNames = new Set(nodeTypes.map((t) => t.name.value));\n const usage =\n operations.length > 0 ? observe(operations, nodeTypes) : undefined;\n\n const out = visit(doc, {\n ObjectTypeDefinition(t) {\n if (!nodeNames.has(t.name.value)) return undefined;\n const type = t.name.value;\n let directives = migrateDirectives(\n t.directives ?? [],\n type,\n undefined,\n todos,\n );\n if (!has(directives, \"node\"))\n directives = [...directives, directive(\"node\")];\n const ops = usage?.mutations.get(type);\n if (!has(directives, \"mutation\")) {\n if (!usage) {\n directives = [...directives, directive(\"mutation\")];\n todos.push(\n `${type}: @mutation added (@neo4j/graphql generates mutations for every type); remove it or narrow its operations`,\n );\n } else if (ops && ops.size > 0) {\n directives = [\n ...directives,\n directive(\"mutation\", {\n operations: enumList([...ops].sort()),\n }),\n ];\n }\n }\n const idFields = (t.fields ?? []).filter((f) => has(f.directives, \"id\"));\n if (idFields.length === 0) {\n todos.push(\n `${type}: no @id field; add a required @key field (the sort tie-breaker and mutation address)`,\n );\n } else if (idFields.length > 1) {\n todos.push(`${type}: several @id fields; keep one as the @key`);\n }\n const fields = (t.fields ?? []).map((f) =>\n migrateField(f, type, usage, todos),\n );\n return { ...t, directives, fields };\n },\n });\n return { typeDefs: print(out), todos };\n}\n\nfunction migrateField(\n f: FieldDefinitionNode,\n type: string,\n usage: Usage | undefined,\n todos: string[],\n): FieldDefinitionNode {\n let directives = migrateDirectives(\n f.directives ?? [],\n type,\n f.name.value,\n todos,\n );\n const id = directives.find((d) => d.name.value === \"id\");\n if (id) {\n directives = directives.filter(\n (d) => d.name.value !== \"id\" && d.name.value !== \"unique\",\n );\n directives.push(directive(\"key\", { generate: bool(true) }));\n }\n const used = usage?.filters.get(type)?.get(f.name.value);\n if (used && used.size > 0 && !has(directives, \"filterable\")) {\n directives.push(\n has(directives, \"relationship\")\n ? directive(\"filterable\")\n : directive(\"filterable\", { byValue: enumList([...used].sort()) }),\n );\n }\n if (\n usage?.sorts.get(type)?.has(f.name.value) &&\n !has(directives, \"sortable\")\n ) {\n directives.push(directive(\"sortable\"));\n }\n return { ...f, directives };\n}\n\nfunction migrateDirectives(\n directives: readonly ConstDirectiveNode[],\n type: string,\n field: string | undefined,\n todos: string[],\n): ConstDirectiveNode[] {\n const at = field ? `${type}.${field}` : type;\n const out: ConstDirectiveNode[] = [];\n for (const d of directives) {\n const name = d.name.value;\n if (name in UNSUPPORTED) {\n todos.push(`${at}: ${UNSUPPORTED[name]}`);\n continue;\n }\n if (name === \"key\" && !field) {\n todos.push(`${at}: federation @key(fields:) is not supported`);\n continue;\n }\n if (name === \"unique\") {\n out.push(directive(\"unique\"));\n continue;\n }\n if (name === \"relationship\") {\n out.push(migrateRelationship(d, at, todos));\n continue;\n }\n if (name === \"fulltext\") {\n out.push(renameInList(d, \"indexes\", \"indexName\", \"name\"));\n continue;\n }\n if (name === \"subscription\") {\n out.push(migrateSubscription(d, at, todos));\n continue;\n }\n if (name === \"authorization\" || name === \"authentication\") {\n todos.push(\n `${at}: check the @${name} rule's filters: operators are written { field: { eq: ... } } here`,\n );\n }\n out.push(d);\n }\n return out;\n}\n\nfunction migrateRelationship(\n d: ConstDirectiveNode,\n at: string,\n todos: string[],\n): ConstDirectiveNode {\n const args: ConstArgumentNode[] = [];\n for (const a of d.arguments ?? []) {\n const name = a.name.value;\n if (name === \"queryDirection\" && a.value.kind === Kind.ENUM) {\n if (a.value.value.includes(\"UNDIRECTED\")) {\n args.push(arg(\"queryDirection\", enumValue(\"UNDIRECTED\")));\n }\n continue;\n }\n if (name === \"nestedOperations\" && a.value.kind === Kind.LIST) {\n const kept = a.value.values.filter(\n (v) => v.kind === Kind.ENUM && v.value !== \"CONNECT_OR_CREATE\",\n );\n if (kept.length < a.value.values.length) {\n todos.push(`${at}: connectOrCreate is not supported; use upsert`);\n }\n args.push(arg(\"nestedOperations\", { kind: Kind.LIST, values: kept }));\n continue;\n }\n args.push(a);\n }\n return { ...d, arguments: args };\n}\n\nfunction migrateSubscription(\n d: ConstDirectiveNode,\n at: string,\n todos: string[],\n): ConstDirectiveNode {\n const events = d.arguments?.find((a) => a.name.value === \"events\")?.value;\n if (!events || events.kind !== Kind.LIST) return d;\n const ops = new Set<string>();\n let relationships = false;\n for (const e of events.values) {\n if (e.kind !== Kind.ENUM) continue;\n if (e.value.startsWith(\"CREATED\") && !e.value.includes(\"RELATIONSHIP\"))\n ops.add(\"CREATE\");\n else if (e.value.startsWith(\"UPDATED\")) ops.add(\"UPDATE\");\n else if (e.value.startsWith(\"DELETED\") && !e.value.includes(\"RELATIONSHIP\"))\n ops.add(\"DELETE\");\n else if (e.value.includes(\"RELATIONSHIP\")) relationships = true;\n }\n todos.push(\n `${at}: subscriptions see writes made through this library (or the engine change feed), not CDC`,\n );\n return directive(\"subscription\", {\n operations: enumList([...ops].sort()),\n ...(relationships ? { relationships: bool(true) } : {}),\n });\n}\n\n/** What the client's operations use: filters, sorts and mutations per type. */\nfunction observe(\n operations: DocumentNode[],\n types: ObjectTypeDefinitionNode[],\n): Usage {\n const usage: Usage = {\n filters: new Map(),\n sorts: new Map(),\n mutations: new Map(),\n };\n // Root fields as either naming would call them: this package's plural\n // and @neo4j/graphql's (which knows irregular plurals, e.g. people).\n const byPlural = new Map<string, ObjectTypeDefinitionNode>();\n for (const t of types) {\n byPlural.set(defaultPlural(t.name.value), t);\n byPlural.set(neo4jPlural(t.name.value), t);\n }\n const byName = new Map(types.map((t) => [t.name.value, t]));\n const note = (type: string, field: string, op: string) => {\n const fields = usage.filters.get(type) ?? new Map<string, Set<string>>();\n const ops = fields.get(field) ?? new Set<string>();\n ops.add(op);\n fields.set(field, ops);\n usage.filters.set(type, fields);\n };\n const where = (type: ObjectTypeDefinitionNode, value: ValueNode) => {\n if (value.kind !== Kind.OBJECT) return;\n for (const f of value.fields) {\n const key = f.name.value;\n if (key === \"AND\" || key === \"OR\") {\n if (f.value.kind === Kind.LIST)\n for (const v of f.value.values) where(type, v);\n continue;\n }\n if (key === \"NOT\") {\n where(type, f.value);\n continue;\n }\n // neo4j 5 relationship quantifiers: `actors_SOME: { name_EQ: ... }`.\n const quantifier = /^(.+)_(SOME|ALL|NONE|SINGLE)$/.exec(key);\n if (quantifier) {\n const rel = type.fields?.find((x) => x.name.value === quantifier[1]);\n const target = rel && byName.get(namedTypeOf(rel));\n if (rel && target) {\n note(type.name.value, quantifier[1]!, \"EQ\");\n where(target, f.value);\n }\n continue;\n }\n const suffix = SUFFIX_OPS.find(([s]) => key.endsWith(s));\n const fieldName = suffix ? key.slice(0, -suffix[0].length) : key;\n const def = type.fields?.find((x) => x.name.value === fieldName);\n if (!def) continue;\n const target = byName.get(namedTypeOf(def));\n if (target) {\n note(type.name.value, fieldName, \"EQ\");\n // `some` / `all` / `none` / `single`, or a nested where.\n if (f.value.kind === Kind.OBJECT) {\n for (const inner of f.value.fields) where(target, inner.value);\n where(target, f.value);\n }\n continue;\n }\n if (suffix) note(type.name.value, fieldName, suffix[1]);\n else if (f.value.kind === Kind.OBJECT) {\n for (const op of f.value.fields) {\n const mapped = NESTED_OPS[op.name.value];\n if (mapped) note(type.name.value, fieldName, mapped);\n }\n } else note(type.name.value, fieldName, \"EQ\");\n }\n };\n const walk = (set: SelectionSetNode | undefined, root: boolean) => {\n for (const sel of set?.selections ?? []) {\n if (sel.kind !== Kind.FIELD) continue;\n const name = sel.name.value;\n if (root) {\n const mutation = /^(create|update|delete|upsert)(.+)$/.exec(name);\n const plural = name.replace(/(Connection|Aggregate)$/, \"\");\n const type =\n byPlural.get(plural) ??\n (mutation ? byPlural.get(lowerFirst(mutation[2]!)) : undefined);\n if (type && mutation) {\n const ops = usage.mutations.get(type.name.value) ?? new Set<string>();\n const op = mutation[1]!.toUpperCase();\n if (op === \"UPSERT\") {\n ops.add(\"CREATE\");\n ops.add(\"UPDATE\");\n } else ops.add(op);\n usage.mutations.set(type.name.value, ops);\n }\n if (type) {\n for (const a of sel.arguments ?? []) argumentUse(type, a);\n }\n }\n walk(sel.selectionSet, false);\n }\n };\n const argumentUse = (type: ObjectTypeDefinitionNode, a: ArgumentNode) => {\n if (a.name.value === \"where\") where(type, a.value);\n if (a.name.value === \"sort\" || a.name.value === \"options\") {\n const sorts = usage.sorts.get(type.name.value) ?? new Set<string>();\n const collect = (v: ValueNode) => {\n if (v.kind === Kind.LIST) v.values.forEach(collect);\n else if (v.kind === Kind.OBJECT) {\n for (const f of v.fields) {\n if (f.name.value === \"sort\") collect(f.value);\n else if (f.value.kind === Kind.ENUM) sorts.add(f.name.value);\n }\n }\n };\n collect(a.value);\n usage.sorts.set(type.name.value, sorts);\n }\n };\n for (const doc of operations) {\n for (const def of doc.definitions) {\n if (def.kind === Kind.OPERATION_DEFINITION) walk(def.selectionSet, true);\n }\n }\n return usage;\n}\n\nfunction namedTypeOf(f: FieldDefinitionNode): string {\n let t = f.type;\n while (t.kind !== Kind.NAMED_TYPE) t = t.type;\n return t.name.value;\n}\n\nfunction has(\n directives: readonly ConstDirectiveNode[] | undefined,\n name: string,\n): boolean {\n return (directives ?? []).some((d) => d.name.value === name);\n}\n\nfunction directive(\n name: string,\n args: Record<string, ConstValueNode> = {},\n): ConstDirectiveNode {\n return {\n kind: Kind.DIRECTIVE,\n name: { kind: Kind.NAME, value: name },\n arguments: Object.entries(args).map(([k, v]) => arg(k, v)),\n };\n}\n\nfunction arg(name: string, value: ConstValueNode): ConstArgumentNode {\n return { kind: Kind.ARGUMENT, name: { kind: Kind.NAME, value: name }, value };\n}\n\nconst enumValue = (value: string): ConstValueNode => ({\n kind: Kind.ENUM,\n value,\n});\nconst bool = (value: boolean): ConstValueNode => ({\n kind: Kind.BOOLEAN,\n value,\n});\nconst enumList = (values: string[]): ConstValueNode => ({\n kind: Kind.LIST,\n values: values.map(enumValue),\n});\n\n/** Rename a key inside each object of a list argument. */\nfunction renameInList(\n d: ConstDirectiveNode,\n argName: string,\n from: string,\n to: string,\n): ConstDirectiveNode {\n return {\n ...d,\n arguments: (d.arguments ?? []).map((a) =>\n a.name.value === argName && a.value.kind === Kind.LIST\n ? arg(argName, {\n kind: Kind.LIST,\n values: a.value.values.map((v) =>\n v.kind === Kind.OBJECT\n ? {\n ...v,\n fields: v.fields.map((f) =>\n f.name.value === from\n ? { ...f, name: { kind: Kind.NAME, value: to } }\n : f,\n ),\n }\n : v,\n ),\n })\n : a,\n ),\n };\n}\n\nconst IRREGULAR: Record<string, string> = {\n person: \"people\",\n man: \"men\",\n woman: \"women\",\n child: \"children\",\n mouse: \"mice\",\n goose: \"geese\",\n foot: \"feet\",\n tooth: \"teeth\",\n};\n\nfunction neo4jPlural(typeName: string): string {\n const base = lowerFirst(typeName);\n const lower = base.toLowerCase();\n for (const [one, many] of Object.entries(IRREGULAR)) {\n if (lower.endsWith(one))\n return base.slice(0, base.length - one.length) + many;\n }\n return defaultPlural(typeName);\n}\n\nfunction lowerFirst(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n","// lora-graphql: the build-time half of the library.\n//\n// lora-graphql print <schema.graphql>\n// lora-graphql directives\n// lora-graphql requirements <schema.graphql> [--ddl]\n// lora-graphql check <schema.graphql> [--operations <file|dir>]... [--variables <file>] [--context <file>]\n// [--baseline <file> [--update-baseline]] [--row-budget <n>]\n// [--database <dir> [--name <db>]] [--json]\n// lora-graphql compile <schema.graphql> --operations <file|dir>... [--out <dir>]\n// lora-graphql analyze <schema.graphql> --database <dir> [--name <db>] [--sample <n>]\n// lora-graphql migrate neo4j <schema.graphql> [--operations <file|dir>]...\n// lora-graphql diff <old.graphql> <new.graphql> [--allow-breaking] [--json]\n// lora-graphql diff --base <git-ref> <file|dir>... [--allow-breaking] [--json]\n\nimport { execFileSync } from \"node:child_process\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n getNamedType,\n isEnumType,\n isInputObjectType,\n isListType,\n isNonNullType,\n Kind,\n parse,\n print as printAst,\n typeFromAST,\n visit,\n type DefinitionNode,\n type FragmentDefinitionNode,\n type GraphQLInputType,\n type GraphQLSchema,\n type OperationDefinitionNode,\n} from \"graphql\";\nimport { diffSchemas } from \"./analyze/diff.js\";\nimport { formatProblem, ModelError } from \"./errors.js\";\nimport { buildModel } from \"./model/build.js\";\nimport { directiveTypeDefs } from \"./model/directives.js\";\nimport {\n describeRequirement,\n inferRequirements,\n requirementDdl,\n} from \"./analyze/indexes.js\";\nimport { LoraGraphQL } from \"./lora-graphql.js\";\nimport { type CheckOptions } from \"./options.js\";\nimport { loraDriver, type LoraDriver } from \"./driver.js\";\nimport { usedFragments } from \"./codegen.js\";\nimport { migrateNeo4j } from \"./migrate.js\";\n\nconst USAGE = `lora-graphql <command>\n\n print <schema.graphql> the public SDL clients see\n directives the directive definitions, for editors\n access <schema.graphql> [--json] who may do what: each type and guarded field,\n operation and kind of caller\n requirements <schema.graphql> [--ddl] constraints and indexes the API needs\n check <schema.graphql> [--operations <file|dir>]... [--json]\n [--variables <file>] [--context <file>]\n [--baseline <file> [--update-baseline]]\n [--row-budget <n>] [--database <dir> [--name <db>]]\n CI gate: model, lint, @cypher statements and\n the plans of your operations, on an in-memory\n LoraDB (or an existing one with --database)\n compile <schema.graphql> --operations <file|dir>... [--out <dir>]\n persisted-operation manifest.json and\n operations.d.ts types\n analyze <schema.graphql> --database <dir> [--name <db>] [--sample <n>]\n statistics JSON for useStatistics()\n migrate neo4j <schema.graphql> [--operations <file|dir>]...\n rewrite an @neo4j/graphql SDL; TODOs for\n what has no equivalent\n diff <old.graphql> <new.graphql> [--allow-breaking] [--json]\n diff --base <git-ref> <file|dir>... [--allow-breaking] [--json]\n database statements and API changes; exit 1\n on a breaking change or a destructive statement\n (--base: the SDL files at a git ref against the\n working tree, each side concatenated)`;\n\ninterface Io {\n out: (line: string) => void;\n err: (line: string) => void;\n}\n\nexport async function main(\n argv: string[],\n io: Io = defaultIo,\n): Promise<number> {\n const [command, ...rest] = argv;\n const flags = new Set<string>();\n const values = new Map<string, string>();\n const positional: string[] = [];\n const operations: string[] = [];\n for (let i = 0; i < rest.length; i++) {\n const a = rest[i]!;\n if (a === \"--operations\") operations.push(rest[++i] ?? \"\");\n else if (VALUE_FLAGS.has(a)) values.set(a, rest[++i] ?? \"\");\n else if (a.startsWith(\"--\")) flags.add(a);\n else positional.push(a);\n }\n try {\n switch (command) {\n case \"print\":\n return await print(need(positional, 1), io);\n case \"directives\":\n io.out(directiveTypeDefs.trim());\n return 0;\n case \"access\":\n return await access(need(positional, 1), flags.has(\"--json\"), io);\n case \"requirements\":\n return await requirements(need(positional, 1), flags.has(\"--ddl\"), io);\n case \"check\":\n return await check(need(positional, 1), operations, flags, values, io);\n case \"compile\":\n return await compile(need(positional, 1), operations, values, io);\n case \"analyze\":\n return await analyzeCommand(need(positional, 1), values, io);\n case \"migrate\": {\n const [from, file] = need(positional, 2);\n if (from !== \"neo4j\") throw new UsageError(\"migrate supports neo4j\");\n const docs = [];\n for (const path of operations) {\n for (const f of await graphqlFiles(path)) docs.push(parse(f.source));\n }\n const result = migrateNeo4j(await read(file!), docs);\n for (const t of result.todos) io.out(`# TODO(migrate): ${t}`);\n if (result.todos.length > 0) io.out(\"\");\n io.out(result.typeDefs);\n return 0;\n }\n case \"diff\": {\n const base = values.get(\"--base\");\n if (base !== undefined) {\n if (!base) throw new UsageError(\"--base takes a git ref\");\n const paths = need(positional, 1);\n const before = await atGitRef(base, paths);\n if (before === undefined) {\n io.out(\n `${base} has none of ${paths.join(\", \")}; nothing to compare`,\n );\n return 0;\n }\n return diff(before, await sdlFiles(paths), flags, io);\n }\n const [before, after] = need(positional, 2);\n return diff(await read(before!), await read(after!), flags, io);\n }\n default:\n io.err(USAGE);\n return 2;\n }\n } catch (err) {\n if (err instanceof UsageError) {\n io.err(`${err.message}\\n\\n${USAGE}`);\n return 2;\n }\n if (err instanceof ModelError) {\n io.err(err.message);\n return 1;\n }\n io.err(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\nclass UsageError extends Error {}\n\nconst VALUE_FLAGS = new Set([\n \"--base\",\n \"--out\",\n \"--variables\",\n \"--context\",\n \"--baseline\",\n \"--row-budget\",\n \"--database\",\n \"--name\",\n \"--sample\",\n]);\n\nfunction need(positional: string[], n: number): string[] {\n if (positional.length < n)\n throw new UsageError(`expected ${n} file argument(s)`);\n return positional;\n}\n\nconst read = (path: string) => readFile(path, \"utf8\");\n\n/** A LoraGraphQL over a driver that refuses to run anything. */\nfunction offline(typeDefs: string): LoraGraphQL {\n const driver: LoraDriver = {\n run: () => Promise.reject(new Error(\"no database\")),\n };\n return new LoraGraphQL({ typeDefs, driver });\n}\n\nasync function access(\n [file]: string[],\n json: boolean,\n io: Io,\n): Promise<number> {\n const matrix = offline(await read(file!)).accessMatrix();\n if (json) {\n io.out(JSON.stringify(matrix, null, 2));\n return 0;\n }\n const rows = matrix.map((e) => [\n e.field ? `${e.type}.${e.field}` : e.type,\n e.operation,\n e.principal,\n e.verdict,\n e.by.join(\", \"),\n ]);\n const widths = [0, 1, 2, 3].map((i) =>\n Math.max(...rows.map((r) => r[i]!.length), 0),\n );\n for (const r of rows) {\n io.out(\n r\n .map((cell, i) => (i < 4 ? cell.padEnd(widths[i]!) : cell))\n .join(\" \")\n .trimEnd(),\n );\n }\n return 0;\n}\n\nasync function print([file]: string[], io: Io): Promise<number> {\n io.out(offline(await read(file!)).printPublicSchema());\n return 0;\n}\n\nasync function requirements(\n [file]: string[],\n ddl: boolean,\n io: Io,\n): Promise<number> {\n const model = buildModel(await read(file!));\n for (const r of inferRequirements(model)) {\n io.out(\n ddl\n ? `${requirementDdl(r)};`\n : `${describeRequirement(r)}, because ${r.reason}`,\n );\n }\n return 0;\n}\n\n/** The node binding's createDatabase, or a message saying how to get it. */\nasync function nodeBinding(\n io: Io,\n command: string,\n): Promise<\n | ((name?: string, options?: { databaseDir?: string }) => Promise<unknown>)\n | undefined\n> {\n try {\n const { createDatabase } =\n (await import(\"@loradb/lora-node\")) as unknown as {\n createDatabase: (\n name?: string,\n options?: { databaseDir?: string },\n ) => Promise<unknown>;\n };\n return createDatabase;\n } catch {\n io.err(\n `${command} needs @loradb/lora-node: npm install --save-dev @loradb/lora-node`,\n );\n return undefined;\n }\n}\n\nasync function check(\n [file]: string[],\n operationPaths: string[],\n flags: Set<string>,\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n const json = flags.has(\"--json\");\n const typeDefs = await read(file!);\n const createDatabase = await nodeBinding(io, \"check\");\n if (!createDatabase) return 1;\n // An existing database is checked as it is; an in-memory one gets what\n // the API needs, so only the plans are under test.\n const databaseDir = values.get(\"--database\");\n const db = await createDatabase(\n databaseDir ? (values.get(\"--name\") ?? \"app\") : undefined,\n databaseDir ? { databaseDir } : {},\n );\n const lora = new LoraGraphQL({\n typeDefs,\n driver: loraDriver(db as Parameters<typeof loraDriver>[0]),\n });\n if (!databaseDir) await lora.assertSchema({ create: true });\n const schema = lora.getSchema();\n const fixtures = values.has(\"--variables\")\n ? (JSON.parse(await read(values.get(\"--variables\")!)) as Record<\n string,\n Record<string, unknown>\n >)\n : {};\n // GraphQL contexts per operation name, `*` for every other operation.\n const contexts = values.has(\"--context\")\n ? (JSON.parse(await read(values.get(\"--context\")!)) as Record<\n string,\n unknown\n >)\n : {};\n const operations: NonNullable<CheckOptions[\"operations\"]> = [];\n for (const path of operationPaths) {\n for (const f of await graphqlFiles(path)) {\n for (const op of operationsIn(schema, f.path, f.source)) {\n const short = op.name!.split(\"#\")[1] ?? \"\";\n const given = fixtures[op.name!] ?? fixtures[short];\n const context = contexts[op.name!] ?? contexts[short] ?? contexts[\"*\"];\n operations.push({\n ...op,\n ...(given ? { variables: given } : {}),\n ...(context !== undefined ? { context } : {}),\n });\n }\n }\n }\n const rowBudget = values.has(\"--row-budget\")\n ? Number(values.get(\"--row-budget\"))\n : undefined;\n const report = await lora.check({\n operations,\n ...(rowBudget !== undefined ? { rowBudget } : {}),\n });\n\n // Plan baseline: the operators of every statement, so a plan change\n // shows up in review.\n const baselinePath = values.get(\"--baseline\");\n const current: Record<string, string[][]> = {};\n for (const p of report.plans) {\n current[`${p.operation} › ${p.field}`] = p.reports.map((r) => r.operators);\n }\n const changed: string[] = [];\n if (baselinePath) {\n let before: Record<string, string[][]> | undefined;\n try {\n before = JSON.parse(await read(baselinePath)) as Record<\n string,\n string[][]\n >;\n } catch {\n before = undefined;\n }\n if (flags.has(\"--update-baseline\") || !before) {\n await writeFile(baselinePath, JSON.stringify(current, null, 2) + \"\\n\");\n } else {\n for (const key of new Set([\n ...Object.keys(before),\n ...Object.keys(current),\n ])) {\n if (JSON.stringify(before[key]) !== JSON.stringify(current[key])) {\n changed.push(key);\n }\n }\n }\n }\n const ok = report.ok && changed.length === 0;\n\n if (json) {\n io.out(JSON.stringify({ ...report, ok, planChanges: changed }, null, 2));\n return ok ? 0 : 1;\n }\n for (const w of report.warnings) io.out(`warning ${formatProblem(w)}`);\n for (const w of report.lint) io.out(`lint ${formatProblem(w)}`);\n for (const u of report.unused) {\n io.out(\n `unused ${u.type} index ${u.name} on :${u.labels.join(\":\")}(${u.properties.join(\", \")})`,\n );\n }\n for (const s of report.security) io.out(`error ${formatProblem(s)}`);\n for (const m of report.missing)\n io.out(`error missing ${describeRequirement(m)}`);\n for (const c of report.cypher)\n io.out(`error ${c.type}.${c.field}: ${c.message}`);\n for (const e of report.errors)\n io.out(`error ${e.operation}: ${e.message}`);\n for (const p of report.plans) {\n for (const r of p.reports) {\n for (const f of r.findings) {\n io.out(`error ${p.operation} › ${p.field}: ${f.message}`);\n }\n for (const n of r.notes) {\n io.out(`lint ${p.operation} › ${p.field}: ${n.message}`);\n }\n }\n }\n for (const key of changed) {\n io.out(\n `error ${key}: the plan differs from the baseline (--update-baseline to accept)`,\n );\n }\n const checked = report.plans.length;\n io.out(\n ok\n ? `ok ${checked} root field(s) in ${operations.length} operation(s) seek as expected`\n : \"failed\",\n );\n return ok ? 0 : 1;\n}\n\n/** Persisted operations from .graphql files (one per operation) or JSON (id → source). */\nasync function persistedOperations(\n paths: string[],\n): Promise<Record<string, string>> {\n const out: Record<string, string> = {};\n for (const path of paths) {\n const info = await stat(path);\n if (info.isFile() && path.endsWith(\".json\")) {\n Object.assign(\n out,\n JSON.parse(await read(path)) as Record<string, string>,\n );\n continue;\n }\n for (const f of await graphqlFiles(path)) {\n const doc = parse(f.source);\n const fragments = new Map(\n doc.definitions\n .filter(\n (d): d is FragmentDefinitionNode =>\n d.kind === Kind.FRAGMENT_DEFINITION,\n )\n .map((d) => [d.name.value, d]),\n );\n const rel = relative(process.cwd(), f.path);\n doc.definitions\n .filter(\n (d): d is OperationDefinitionNode =>\n d.kind === Kind.OPERATION_DEFINITION,\n )\n .forEach((op, i) => {\n const id = `${rel}#${op.name?.value ?? i + 1}`;\n out[id] = printAst({\n kind: Kind.DOCUMENT,\n definitions: [op, ...usedFragments(op, fragments)],\n });\n });\n }\n }\n return out;\n}\n\nasync function compile(\n [file]: string[],\n operationPaths: string[],\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n if (operationPaths.length === 0) {\n throw new UsageError(\"compile needs --operations <file|dir>\");\n }\n const lora = offline(await read(file!));\n const manifest = lora.buildManifest(\n await persistedOperations(operationPaths),\n );\n const outDir = values.get(\"--out\") ?? \"lora-graphql\";\n await mkdir(outDir, { recursive: true });\n await writeFile(\n join(outDir, \"manifest.json\"),\n JSON.stringify(manifest) + \"\\n\",\n );\n await writeFile(\n join(outDir, \"operations.d.ts\"),\n lora.generateTypes(manifest),\n );\n io.out(\n `wrote ${Object.keys(manifest.operations).length} operation(s) to ${join(outDir, \"manifest.json\")} and ${join(outDir, \"operations.d.ts\")}`,\n );\n return 0;\n}\n\nasync function analyzeCommand(\n [file]: string[],\n values: Map<string, string>,\n io: Io,\n): Promise<number> {\n const databaseDir = values.get(\"--database\");\n if (!databaseDir) throw new UsageError(\"analyze needs --database <dir>\");\n const createDatabase = await nodeBinding(io, \"analyze\");\n if (!createDatabase) return 1;\n const db = await createDatabase(values.get(\"--name\") ?? \"app\", {\n databaseDir,\n });\n const lora = new LoraGraphQL({\n typeDefs: await read(file!),\n driver: loraDriver(db as Parameters<typeof loraDriver>[0]),\n });\n const sample = values.has(\"--sample\")\n ? Number(values.get(\"--sample\"))\n : undefined;\n const stats = await lora.analyze(sample !== undefined ? { sample } : {});\n io.out(JSON.stringify(stats, null, 2));\n (db as { dispose?: () => void }).dispose?.();\n return 0;\n}\n\nasync function graphqlFiles(\n path: string,\n): Promise<Array<{ path: string; source: string }>> {\n const info = await stat(path);\n if (info.isFile()) return [{ path, source: await read(path) }];\n const out: Array<{ path: string; source: string }> = [];\n for (const entry of await readdir(path, { withFileTypes: true })) {\n const full = join(path, entry.name);\n if (entry.isDirectory()) out.push(...(await graphqlFiles(full)));\n else if (/\\.(graphql|gql)$/.test(entry.name)) {\n out.push({ path: full, source: await read(full) });\n }\n }\n return out;\n}\n\n/** Each query in a file, with example values for its required variables. */\nfunction operationsIn(\n schema: GraphQLSchema,\n path: string,\n source: string,\n): NonNullable<CheckOptions[\"operations\"]> {\n const doc = parse(source);\n const fragments = new Map(\n doc.definitions\n .filter(\n (d): d is FragmentDefinitionNode => d.kind === Kind.FRAGMENT_DEFINITION,\n )\n .map((f) => [f.name.value, f]),\n );\n // The fragments an operation spreads, transitively.\n const used = (root: DefinitionNode): FragmentDefinitionNode[] => {\n const seen = new Map<string, FragmentDefinitionNode>();\n const walk = (node: DefinitionNode) =>\n visit(node, {\n FragmentSpread(spread) {\n const f = fragments.get(spread.name.value);\n if (f && !seen.has(f.name.value)) {\n seen.set(f.name.value, f);\n walk(f);\n }\n },\n });\n walk(root);\n return [...seen.values()];\n };\n return doc.definitions\n .filter(\n (d): d is OperationDefinitionNode =>\n d.kind === Kind.OPERATION_DEFINITION && d.operation === \"query\",\n )\n .map((op, i) => {\n const variables: Record<string, unknown> = {};\n for (const v of op.variableDefinitions ?? []) {\n if (v.defaultValue || v.type.kind !== Kind.NON_NULL_TYPE) continue;\n const type = typeFromAST(schema, v.type) as\n | GraphQLInputType\n | undefined;\n if (type) variables[v.variable.name.value] = sample(type);\n }\n return {\n name: `${path}${op.name ? `#${op.name.value}` : `#${i + 1}`}`,\n document: { kind: Kind.DOCUMENT, definitions: [op, ...used(op)] },\n variables,\n };\n });\n}\n\nconst SAMPLES: Record<string, unknown> = {\n String: \"x\",\n ID: \"x\",\n Int: 1,\n Float: 1,\n Boolean: true,\n BigInt: \"1\",\n Date: \"2026-01-01\",\n Time: \"12:00:00Z\",\n LocalTime: \"12:00:00\",\n DateTime: \"2026-01-01T12:00:00Z\",\n LocalDateTime: \"2026-01-01T12:00:00\",\n Duration: \"P1D\",\n};\n\nfunction sample(type: GraphQLInputType): unknown {\n const inner = isNonNullType(type) ? type.ofType : type;\n if (isListType(inner)) return [sample(inner.ofType)];\n const named = getNamedType(inner);\n if (isEnumType(named)) return named.getValues()[0]?.value;\n if (isInputObjectType(named)) {\n const out: Record<string, unknown> = {};\n for (const f of Object.values(named.getFields())) {\n if (isNonNullType(f.type) && f.defaultValue === undefined) {\n out[f.name] = sample(f.type);\n }\n }\n return out;\n }\n return SAMPLES[named.name] ?? \"x\";\n}\n\nconst SDL_FILE = /\\.(graphql|gql)$/;\n\n/** The SDL in `paths` (files, or directories searched recursively), joined. */\nasync function sdlFiles(paths: string[]): Promise<string> {\n const parts: string[] = [];\n for (const path of paths) {\n const files = await graphqlFiles(path);\n files.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n parts.push(...files.map((f) => f.source));\n }\n return parts.join(\"\\n\");\n}\n\n/**\n * The SDL in `paths` as of git `ref`, joined in the same order as\n * `sdlFiles`, or undefined when the ref has none of them (a base from\n * before the schema existed). A ref that is not a commit is an error: a\n * gate that silently compared nothing would pass without looking.\n */\nasync function atGitRef(\n ref: string,\n paths: string[],\n): Promise<string | undefined> {\n const git = (cwd: string, ...args: string[]) =>\n execFileSync(\"git\", args, {\n cwd,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n maxBuffer: 64 * 1024 * 1024,\n });\n const parts: string[] = [];\n let found = false;\n for (const path of paths) {\n // Run git next to the path and name it `./…`, so relative and\n // absolute paths both resolve, from any directory of the repository.\n const isDir = await stat(path).then(\n (s) => s.isDirectory(),\n () => !SDL_FILE.test(path),\n );\n const cwd = isDir ? path : dirname(path);\n try {\n git(cwd, \"rev-parse\", \"--verify\", \"--quiet\", `${ref}^{commit}`);\n } catch {\n throw new Error(\n `diff: ${ref} is not a commit (fetch it, or pass another ref)`,\n );\n }\n if (!isDir) {\n try {\n parts.push(git(cwd, \"show\", `${ref}:./${basename(path)}`));\n found = true;\n } catch {\n // Not in the base: a new file.\n }\n continue;\n }\n // Paths come back relative to `cwd`; none when the directory is not\n // in the base.\n const files = git(cwd, \"ls-tree\", \"-r\", \"--name-only\", ref, \"--\", \".\")\n .split(\"\\n\")\n .filter((f) => SDL_FILE.test(f));\n // Same order as sdlFiles: by path.\n files.sort((a, b) => {\n const pa = join(path, a);\n const pb = join(path, b);\n return pa < pb ? -1 : pa > pb ? 1 : 0;\n });\n for (const f of files) {\n parts.push(git(cwd, \"show\", `${ref}:./${f}`));\n found = true;\n }\n }\n return found ? parts.join(\"\\n\") : undefined;\n}\n\nfunction diff(\n before: string,\n after: string,\n flags: Set<string>,\n io: Io,\n): number {\n const result = diffSchemas(before, after);\n const breaking = result.api.breaking.length > 0;\n const destructive = result.database.statements.some((s) => s.destructive);\n const code =\n (breaking || destructive) && !flags.has(\"--allow-breaking\") ? 1 : 0;\n if (flags.has(\"--json\")) {\n io.out(JSON.stringify(result, null, 2));\n return code;\n }\n io.out(\"# Database\");\n if (result.database.statements.length === 0) io.out(\"no changes\");\n for (const s of result.database.statements) {\n io.out(`${s.destructive ? \"// destructive: \" : \"// \"}${s.reason}`);\n io.out(`${s.text};`);\n }\n io.out(\"\\n# API\");\n if (!breaking && result.api.dangerous.length === 0) io.out(\"no changes\");\n for (const c of result.api.breaking) io.out(`breaking ${c.description}`);\n for (const c of result.api.dangerous) io.out(`dangerous ${c.description}`);\n for (const n of result.notes) io.out(`note ${n}`);\n return code;\n}\n\nconst defaultIo: Io = {\n out: (line) => process.stdout.write(line + \"\\n\"),\n err: (line) => process.stderr.write(line + \"\\n\"),\n};\n\nconst invokedDirectly =\n typeof process !== \"undefined\" &&\n process.argv[1] !== undefined &&\n /lora-graphql(\\.js)?$|cli\\.js$/.test(process.argv[1]);\nif (invokedDirectly) {\n main(process.argv.slice(2)).then((code) => process.exit(code));\n}\n"],"names":["ROOT","UNSUPPORTED","SUFFIX_OPS","NESTED_OPS","migrateNeo4j","sdl","operations","doc","parse","todos","nodeTypes","d","Kind","has","nodeNames","t","usage","observe","out","visit","type","directives","migrateDirectives","directive","ops","enumList","idFields","f","fields","migrateField","print","bool","used","field","at","name","migrateRelationship","renameInList","migrateSubscription","args","a","arg","enumValue","kept","v","events","relationships","e","types","byPlural","defaultPlural","neo4jPlural","byName","note","op","where","value","key","quantifier","rel","x","target","namedTypeOf","suffix","s","fieldName","def","inner","mapped","walk","set","root","sel","mutation","plural","lowerFirst","argumentUse","sorts","collect","k","values","argName","from","to","IRREGULAR","typeName","base","lower","one","many","USAGE","main","argv","io","defaultIo","command","rest","flags","positional","i","VALUE_FLAGS","need","directiveTypeDefs","access","requirements","check","compile","analyzeCommand","file","UsageError","docs","path","graphqlFiles","result","read","paths","before","atGitRef","diff","sdlFiles","after","err","ModelError","n","readFile","offline","typeDefs","driver","LoraGraphQL","json","matrix","rows","widths","r","cell","ddl","model","buildModel","inferRequirements","requirementDdl","describeRequirement","nodeBinding","createDatabase","operationPaths","databaseDir","db","lora","loraDriver","schema","fixtures","contexts","operationsIn","short","given","context","rowBudget","report","baselinePath","current","p","changed","writeFile","ok","w","formatProblem","u","m","c","checked","persistedOperations","stat","fragments","relative","id","printAst","usedFragments","manifest","outDir","mkdir","join","sample","stats","entry","readdir","full","source","seen","node","spread","variables","typeFromAST","SAMPLES","isNonNullType","isListType","named","getNamedType","isEnumType","isInputObjectType","SDL_FILE","parts","files","b","ref","git","cwd","execFileSync","found","isDir","dirname","basename","pa","pb","diffSchemas","breaking","destructive","code","line","invokedDirectly"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { FieldNode, FragmentDefinitionNode } from 'graphql';
2
- import { CompiledRead } from './read.js';
2
+ import { CompiledRead } from './read/types.js';
3
3
  import { CompileContext } from './context.js';
4
4
  /** Compiled root fields kept per field node, across keys. */
5
5
  export declare const COMPILED_PER_FIELD = 16;
@@ -0,0 +1,19 @@
1
+ import { FieldNode, SelectionSetNode } from 'graphql';
2
+ import { AbstractType, RelationshipField } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { Clause, Expr } from '../cypher.js';
5
+ import { CompiledRead, Args, Projection } from './types.js';
6
+ /** `events(where, sort, limit)` over an interface's implementations or a union's members. */
7
+ export declare function compileAbstractRoot(ctx: CompileContext, abstract: AbstractType, args: Args, fieldNodes: readonly FieldNode[]): CompiledRead;
8
+ /** A relationship field whose target is an interface or union. */
9
+ export declare function projectPolymorphic(ctx: CompileContext, parent: string, rel: RelationshipField, key: string, args: Args, sets: SelectionSetNode[], rows: number): Projection;
10
+ /**
11
+ * A node `variable` of an interface or union, projected as the member its
12
+ * label says, with `__typename`. `where` keeps the nodes of some member
13
+ * the caller may read; others (and non-members) are dropped.
14
+ */
15
+ export declare function projectAbstract(ctx: CompileContext, abstract: AbstractType, variable: string, sets: SelectionSetNode[], rows: number): {
16
+ pre: Clause[];
17
+ where: Expr;
18
+ expr: Expr;
19
+ };
@@ -0,0 +1,34 @@
1
+ import { SelectionSetNode } from 'graphql';
2
+ import { NodeType, ScalarField } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { Clause, Expr } from '../cypher.js';
5
+ import { CompiledRead, Args } from './types.js';
6
+ export declare const AGGREGATES: Set<string>;
7
+ export interface WantedAggregate {
8
+ field: ScalarField;
9
+ agg: string;
10
+ column: string;
11
+ }
12
+ /**
13
+ * The RETURN of an aggregate statement over `variable`: `base` items
14
+ * (already aggregate expressions) and one column per wanted aggregate.
15
+ * Folded aggregates need their values collected first, in a WITH: an
16
+ * aggregate nested in another call is not aggregated (E16).
17
+ */
18
+ export declare function aggregateReturn(ctx: CompileContext, variable: string, base: Array<{
19
+ expr: Expr;
20
+ alias: string;
21
+ }>, wanted: WantedAggregate[], group?: {
22
+ keys: Array<{
23
+ expr: Expr;
24
+ alias: string;
25
+ }>;
26
+ limit: Expr;
27
+ }): Clause[];
28
+ export declare function compileAggregate(ctx: CompileContext, node: NodeType, args: Args, sets: SelectionSetNode[]): CompiledRead;
29
+ /**
30
+ * `<plural>Grouped(by: [...])`: one row per group of values, ordered by
31
+ * them, at most `limit` groups. The values are collected per group and
32
+ * folded (an aggregate nested in another call is not aggregated, E16).
33
+ */
34
+ export declare function compileGrouped(ctx: CompileContext, node: NodeType, args: Args, sets: SelectionSetNode[]): CompiledRead;
@@ -0,0 +1,10 @@
1
+ import { SelectionSetNode } from 'graphql';
2
+ import { NodeType } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { CompiledRead } from './types.js';
5
+ /**
6
+ * Nodes by @key, in one statement, for mutation payloads: the read runs
7
+ * inside the mutation's transaction and sees its writes.
8
+ */
9
+ export declare function compileByKeys(ctx: CompileContext, node: NodeType, keys: unknown[], sets: SelectionSetNode[]): CompiledRead;
10
+ export declare function keyOf(value: unknown): string;
@@ -0,0 +1,30 @@
1
+ import { Statement } from '../../driver.js';
2
+ import { NodeType, ScalarField } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { Clause, Expr } from '../cypher.js';
5
+ import { SeekExpectation, ReadSet, CompiledRead } from './types.js';
6
+ export declare function finish(ctx: CompileContext, clauses: Clause[], columns: string[], shape: CompiledRead["shape"], expectation: Omit<SeekExpectation, "statement"> | undefined, extra?: Statement[], mode?: "read" | "write"): CompiledRead;
7
+ export declare function readSet(ctx: CompileContext): ReadSet;
8
+ /**
9
+ * Sorting or aggregating over a field with row-level READ rules would
10
+ * reveal values of rows the rules hide: refused unless the claims alone
11
+ * already settle the rules.
12
+ */
13
+ export declare function refuseRowRules(ctx: CompileContext, node: NodeType, field: ScalarField, what: string): void;
14
+ /**
15
+ * `sum(CASE WHEN <READ validate rule> THEN 0 ELSE 1 END) AS __denied`:
16
+ * aggregates and counts cover nodes a READ validate rule rejects, so they
17
+ * fail like reading those nodes would.
18
+ */
19
+ export declare function deniedItem(ctx: CompileContext, node: NodeType, variable: string): Array<{
20
+ expr: Expr;
21
+ alias: string;
22
+ }>;
23
+ export declare function assertNoneDenied(row: Record<string, unknown> | undefined): void;
24
+ /**
25
+ * `RETURN head(collect(x)) AS out`, written as two clauses: LoraDB 0.15
26
+ * does not treat an aggregate nested inside another call as aggregating.
27
+ */
28
+ export declare function collectOne(value: Expr, out: string): Clause[];
29
+ /** A rule condition as a WHERE predicate: an unknown result excludes. */
30
+ export declare function coalesceFalse(e: Expr | undefined): Expr | undefined;
@@ -0,0 +1,26 @@
1
+ import { GraphQLObjectType, SelectionSetNode } from 'graphql';
2
+ import { NodeType, RelationshipPropertiesType, RelationshipField, ScalarField } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { Args, Projection } from './types.js';
5
+ export declare function projectRelationshipConnection(ctx: CompileContext, parent: string, rel: RelationshipField, key: string, args: Args, sets: SelectionSetNode[], rows: number): Projection;
6
+ /** Aggregates a connection's `aggregate { … }` asks for. */
7
+ interface AggregateSpec {
8
+ node: Array<{
9
+ field: ScalarField;
10
+ fns: string[];
11
+ }>;
12
+ edge: Array<{
13
+ field: ScalarField;
14
+ fns: string[];
15
+ }>;
16
+ }
17
+ /** What a connection selection asks for, merged across aliases. */
18
+ export declare function connectionSelections(ctx: CompileContext, connType: GraphQLObjectType, edgeType: GraphQLObjectType, sets: SelectionSetNode[], target: NodeType, props: RelationshipPropertiesType | undefined): {
19
+ node: SelectionSetNode[];
20
+ properties: SelectionSetNode[];
21
+ totalCount: boolean;
22
+ /** `edges` or `pageInfo` selected: the page must be read. */
23
+ page: boolean;
24
+ aggregate: AggregateSpec | undefined;
25
+ };
26
+ export {};
@@ -0,0 +1,21 @@
1
+ import { FieldNode, SelectionSetNode } from 'graphql';
2
+ import { CypherField } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { CompiledRead, Args, Projection } from './types.js';
5
+ /**
6
+ * A root `@cypher` field on Query or Mutation: the statement runs in a
7
+ * `CALL { }`, and returned nodes are projected like any other read.
8
+ */
9
+ export declare function compileCypherRoot(ctx: CompileContext, field: CypherField, args: Args, fieldNodes: readonly FieldNode[]): CompiledRead;
10
+ /** The statement text with its parameters renamed to bound `$pN`s. */
11
+ export declare function bindStatement(ctx: CompileContext, field: CypherField, args: Args): string;
12
+ /** Default `maxListArgument`: the most items a @cypher list argument takes. */
13
+ export declare const MAX_LIST_ARGUMENT = 1000;
14
+ /**
15
+ * An object `@cypher` field, run once per parent:
16
+ *
17
+ * CALL { WITH parent WITH parent AS this
18
+ * CALL { WITH this <statement> }
19
+ * RETURN collect(<column>) AS out }
20
+ */
21
+ export declare function projectCypher(ctx: CompileContext, parent: string, field: CypherField, key: string, args: Args, sets: SelectionSetNode[], rows: number): Projection;
@@ -0,0 +1,11 @@
1
+ import { NodeType } from '../../model/types.js';
2
+ import { CompileContext } from '../context.js';
3
+ import { Clause } from '../cypher.js';
4
+ import { SeekExpectation, Where } from './types.js';
5
+ import { SortKey } from './sort.js';
6
+ export declare function rootMatch(ctx: CompileContext, node: NodeType, where: Where | null | undefined, sort: SortKey[], cursor?: unknown[]): {
7
+ clauses: Clause[];
8
+ expectation: Omit<SeekExpectation, "statement"> | undefined;
9
+ /** Computed values the following clauses must carry. */
10
+ carry: string[];
11
+ };
@@ -0,0 +1,15 @@
1
+ import { SelectionSetNode } from 'graphql';
2
+ import { NodeType, RelationshipField } from '../../model/types.js';
3
+ import { fieldReadGuard } from '../auth.js';
4
+ import { CompileContext } from '../context.js';
5
+ import { Expr } from '../cypher.js';
6
+ import { Projection } from './types.js';
7
+ /**
8
+ * Project `variable` (a `node`) with the selection sets. `rows` is how
9
+ * many parents this projection runs for, for the cost estimate.
10
+ */
11
+ export declare function projectNode(ctx: CompileContext, node: NodeType, variable: string, sets: SelectionSetNode[], rows: number): Projection;
12
+ /** `value` where the guard holds, else the marker the resolvers raise. */
13
+ export declare function guardedValue(guard: NonNullable<ReturnType<typeof fieldReadGuard>>, value: Expr): Expr;
14
+ /** Rows a list relationship yields per parent, for the cost estimate. */
15
+ export declare function fanOut(ctx: CompileContext, rel: RelationshipField, limit: number): number;
@@ -0,0 +1,5 @@
1
+ import { FieldNode } from 'graphql';
2
+ import { NodeType } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { RootKind, CompiledRead, Args } from './types.js';
5
+ export declare function compileRoot(ctx: CompileContext, kind: RootKind, node: NodeType, args: Args, fieldNodes: readonly FieldNode[]): CompiledRead;
@@ -0,0 +1,16 @@
1
+ import { FieldNode } from 'graphql';
2
+ import { NodeType, SearchIndex } from '../../model/types.js';
3
+ import { CompileContext } from '../context.js';
4
+ import { CompiledRead, Args } from './types.js';
5
+ /** A search root field's value: nodes with their scores. */
6
+ export interface SearchResult {
7
+ node: unknown;
8
+ score: number;
9
+ }
10
+ /**
11
+ * A search as a connection (`connection: true`): pages forward by keyset
12
+ * on (score DESC, key ASC). A vector index returns its top candidates
13
+ * before any filter, so vector connections page within a fixed pool of
14
+ * `4 × @limit(max:)` candidates.
15
+ */
16
+ export declare function compileSearch(ctx: CompileContext, node: NodeType, index: SearchIndex, args: Args, fieldNodes: readonly FieldNode[], connection?: boolean): CompiledRead;
@@ -0,0 +1,42 @@
1
+ import { NodeType, RelationshipPropertiesType, PageLimit, ScalarField } from '../../model/types.js';
2
+ import { CompileContext } from '../context.js';
3
+ import { Expr, SortItem } from '../cypher.js';
4
+ import { Args } from './types.js';
5
+ export interface SortKey {
6
+ field: ScalarField;
7
+ direction: "ASC" | "DESC";
8
+ /** A relationship property (`sort: [{ edge: { ... } }]`), not a node field. */
9
+ edge?: boolean;
10
+ /** For a computed (`@cypher`) field: the variable holding its value. */
11
+ computed?: string;
12
+ }
13
+ export declare function resolveLimit(value: unknown, limit: PageLimit, argument: string): number;
14
+ /**
15
+ * The sort keys for `value`. Connections (`tieBreak`) always end on a
16
+ * unique field so cursors are stable; plain lists do not, because LoraDB
17
+ * 0.15 streams an index in order only for a single sort key, and a
18
+ * tie-breaker would turn a `LIMIT` into a sort of the whole label.
19
+ */
20
+ export declare function resolveSort(ctx: CompileContext, node: NodeType, value: unknown, tieBreak: boolean, props?: RelationshipPropertiesType): SortKey[];
21
+ /**
22
+ * `first` / `after`, or `last` / `before`. A backward page runs the sort
23
+ * reversed from the cursor and is flipped back by the resolvers; cursors
24
+ * carry the requested sort's signature, so they work in both directions.
25
+ */
26
+ export declare function resolvePage(ctx: CompileContext, node: NodeType, args: Args, limit: PageLimit, props?: RelationshipPropertiesType): {
27
+ first: number;
28
+ sort: SortKey[];
29
+ signature: string;
30
+ cursor: unknown[] | undefined;
31
+ backward: boolean;
32
+ };
33
+ export declare function sortItems(variable: string, sort: SortKey[], edge?: string): SortItem[];
34
+ export declare function cursorValues(variable: string, sort: SortKey[], edge?: string): Expr;
35
+ /** Whether a sort key is guaranteed present, so a `>=` bound loses no rows. */
36
+ export declare function leadBound(k: SortKey): boolean;
37
+ /**
38
+ * Rows strictly after `values` in `sort` order, written out term by term
39
+ * (`[a, b] > $list` silently matches nothing in LoraDB). Null ordering
40
+ * follows Cypher: nulls last ascending, first descending.
41
+ */
42
+ export declare function keysetPredicate(ctx: CompileContext, variable: string, sort: SortKey[], values: unknown[], edge?: string): Expr | undefined;