@loradb/lora-graphql 0.24.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -31
- package/dist/analyze/input-schemas.d.ts +11 -0
- package/dist/analyze/plans.d.ts +8 -0
- package/dist/analyze/stored.d.ts +29 -0
- package/dist/cli.js +263 -244
- package/dist/cli.js.map +1 -1
- package/dist/compile/cache.d.ts +9 -1
- package/dist/compile/context.d.ts +3 -0
- package/dist/compile/read/common.d.ts +2 -0
- package/dist/compile/read/root.d.ts +7 -0
- package/dist/compile/selection.d.ts +5 -0
- package/dist/diff-CdZZG-N1.js +134 -0
- package/dist/diff-CdZZG-N1.js.map +1 -0
- package/dist/driver.d.ts +36 -1
- package/dist/errors.d.ts +21 -1
- package/dist/events/outbox.d.ts +14 -0
- package/dist/events/worker.d.ts +67 -0
- package/dist/execute/mutate/checks.d.ts +16 -0
- package/dist/execute/mutate/env.d.ts +50 -0
- package/dist/execute/mutate/errors.d.ts +6 -0
- package/dist/execute/mutate/links.d.ts +38 -0
- package/dist/execute/mutate/plan.d.ts +5 -0
- package/dist/execute/mutate/runner.d.ts +101 -25
- package/dist/execute/mutate/single-call.d.ts +92 -0
- package/dist/execute/mutate/triggers.d.ts +21 -0
- package/dist/execute/mutate/unique-together.d.ts +5 -1
- package/dist/execute/mutate/validate.d.ts +11 -0
- package/dist/execute/transaction.d.ts +13 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +16 -15
- package/dist/lora-graphql-D11QFUkf.js +17222 -0
- package/dist/lora-graphql-D11QFUkf.js.map +1 -0
- package/dist/lora-graphql.d.ts +30 -1
- package/dist/model/build/authorization.d.ts +11 -1
- package/dist/model/build/constraints.d.ts +22 -0
- package/dist/model/build/rule-checks.d.ts +6 -1
- package/dist/model/build/trigger.d.ts +9 -0
- package/dist/model/constraints.d.ts +112 -0
- package/dist/model/desugar.d.ts +7 -0
- package/dist/model/directives.d.ts +1 -1
- package/dist/model/types.d.ts +34 -0
- package/dist/options.d.ts +76 -3
- package/dist/results.d.ts +12 -1
- package/dist/schema/scalars.d.ts +8 -1
- package/dist/standard-schema.d.ts +37 -0
- package/dist/testing.js +1 -1
- package/package.json +2 -2
- package/dist/diff-K8-GSeKH.js +0 -100
- package/dist/diff-K8-GSeKH.js.map +0 -1
- package/dist/driver-CXKPLfkz.js +0 -14447
- package/dist/driver-CXKPLfkz.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/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
|
+
{"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 { inputSchemas } from \"./analyze/input-schemas.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 json-schema <schema.graphql> the validation rules of every create and\n update input, as JSON Schema, for clients\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 \"json-schema\": {\n const [file] = need(positional, 1);\n io.out(\n JSON.stringify(inputSchemas(buildModel(await read(file!))), null, 2),\n );\n return 0;\n }\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 { mutation, ...op } of operationsIn(\n schema,\n f.path,\n f.source,\n )) {\n const short = op.name!.split(\"#\")[1] ?? \"\";\n const given = fixtures[op.name!] ?? fixtures[short];\n // A mutation is run (and rolled back), so it needs variables that\n // succeed against this database: checked only when --variables\n // names it.\n if (mutation && !given) continue;\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 v of report.stored) {\n io.out(\n `stored ${v.type} ${JSON.stringify(v.key)}.${v.field} ${v.message}`,\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/**\n * Each query and mutation in a file, with example values for its required\n * variables.\n */\nfunction operationsIn(\n schema: GraphQLSchema,\n path: string,\n source: string,\n): Array<\n NonNullable<CheckOptions[\"operations\"]>[number] & { mutation: boolean }\n> {\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 !== \"subscription\",\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 mutation: op.operation === \"mutation\",\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","file","inputSchemas","buildModel","read","check","compile","analyzeCommand","UsageError","docs","path","graphqlFiles","result","paths","before","atGitRef","diff","sdlFiles","after","err","ModelError","n","readFile","offline","typeDefs","driver","LoraGraphQL","json","matrix","rows","widths","r","cell","ddl","model","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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"}
|
package/dist/compile/cache.d.ts
CHANGED
|
@@ -13,7 +13,9 @@ export declare const COMPILE_CACHE_BYTES: number;
|
|
|
13
13
|
* and would hold its statement's parameters for nothing.
|
|
14
14
|
*/
|
|
15
15
|
export declare const MAX_CACHED_VARIABLES: number;
|
|
16
|
-
type Compile = (jwt: Record<string, unknown> | undefined
|
|
16
|
+
type Compile = (jwt: Record<string, unknown> | undefined,
|
|
17
|
+
/** Values to compile with in place of the request's variables. */
|
|
18
|
+
variables?: Record<string, unknown>) => {
|
|
17
19
|
ctx: CompileContext;
|
|
18
20
|
compiled: CompiledRead;
|
|
19
21
|
};
|
|
@@ -25,6 +27,12 @@ export interface CacheRequest {
|
|
|
25
27
|
jwt: Record<string, unknown> | undefined;
|
|
26
28
|
context: unknown;
|
|
27
29
|
statistics: number;
|
|
30
|
+
/**
|
|
31
|
+
* Variables whose value only ever lands in the statement as a whole
|
|
32
|
+
* parameter: the variable given as the key of a lookup by @key. One
|
|
33
|
+
* compile then serves every value of them.
|
|
34
|
+
*/
|
|
35
|
+
rebindable?: readonly string[] | undefined;
|
|
28
36
|
}
|
|
29
37
|
export declare class CompileCache {
|
|
30
38
|
#private;
|
|
@@ -30,6 +30,8 @@ export interface CompileContext extends SelectionContext {
|
|
|
30
30
|
maxListFilter?: number | undefined;
|
|
31
31
|
/** Characters a string filter operand may hold (`maxStringFilter`). */
|
|
32
32
|
maxStringFilter?: number | undefined;
|
|
33
|
+
/** Most matches a root connection's `totalCount` counts (`maxTotalCount`). */
|
|
34
|
+
maxTotalCount?: number | undefined;
|
|
33
35
|
/** Relationship levels of the `where` being compiled, so far. */
|
|
34
36
|
filterDepth?: number | undefined;
|
|
35
37
|
/** The GraphQL context, for `"$context.path"` values in rules. */
|
|
@@ -66,6 +68,7 @@ export declare function newContext(base: SelectionContext, model: GraphModel, op
|
|
|
66
68
|
maxFilterDepth?: number | undefined;
|
|
67
69
|
maxListFilter?: number | undefined;
|
|
68
70
|
maxStringFilter?: number | undefined;
|
|
71
|
+
maxTotalCount?: number | undefined;
|
|
69
72
|
}): CompileContext;
|
|
70
73
|
/** Record that the compile read the claim at `path` (see `claimReads`). */
|
|
71
74
|
export declare function noteClaim(ctx: CompileContext, path: string, value: unknown, bound: boolean): void;
|
|
@@ -28,3 +28,5 @@ export declare function assertNoneDenied(row: Record<string, unknown> | undefine
|
|
|
28
28
|
export declare function collectOne(value: Expr, out: string): Clause[];
|
|
29
29
|
/** A rule condition as a WHERE predicate: an unknown result excludes. */
|
|
30
30
|
export declare function coalesceFalse(e: Expr | undefined): Expr | undefined;
|
|
31
|
+
/** Stop a count at `cap` matches (`maxTotalCount`): the scan ends there. */
|
|
32
|
+
export declare function countCap(ctx: CompileContext, cap: number | undefined): Clause[];
|
|
@@ -3,3 +3,10 @@ import { NodeType } from '../../model/types.js';
|
|
|
3
3
|
import { CompileContext } from '../context.js';
|
|
4
4
|
import { RootKind, CompiledRead, Args } from './types.js';
|
|
5
5
|
export declare function compileRoot(ctx: CompileContext, kind: RootKind, node: NodeType, args: Args, fieldNodes: readonly FieldNode[]): CompiledRead;
|
|
6
|
+
/**
|
|
7
|
+
* The variables of a root field whose value only ever becomes a
|
|
8
|
+
* parameter, so one compile can be shared across their values: the
|
|
9
|
+
* variable given as the key of a lookup by @key (`festival(key: $key)`),
|
|
10
|
+
* when it is one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function rebindableVariables(kind: RootKind, node: NodeType, fieldNodes: readonly FieldNode[]): readonly string[] | undefined;
|
|
@@ -9,6 +9,11 @@ export interface SelectionContext {
|
|
|
9
9
|
*/
|
|
10
10
|
variables: Record<string, unknown>;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* `ctx` with `values` in place of the coerced variables they name, on
|
|
14
|
+
* graphql 16 and 17 alike.
|
|
15
|
+
*/
|
|
16
|
+
export declare function withVariables(ctx: SelectionContext, values: Record<string, unknown>): SelectionContext;
|
|
12
17
|
/** The coerced variable values, on graphql 16 and 17 alike. */
|
|
13
18
|
export declare function coercedVariables(variables: unknown): Record<string, unknown> | undefined;
|
|
14
19
|
/**
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as b from "graphql";
|
|
2
|
+
import { c as $, i as w, r as E, n as C, o as h, q as N, u as k } from "./lora-graphql-D11QFUkf.js";
|
|
3
|
+
function q(i, n, o = {}) {
|
|
4
|
+
const c = $(i, o), t = $(n, o), f = C, d = new Map(w(c).map((e) => [f(e), e])), s = new Map(w(t).map((e) => [f(e), e])), r = [...s].filter(([e]) => !d.has(e)).map(([, e]) => e), l = [...d].filter(([e]) => !s.has(e)).map(([, e]) => e), a = [], u = [];
|
|
5
|
+
R(c, t, a, u);
|
|
6
|
+
for (const e of l)
|
|
7
|
+
a.push({
|
|
8
|
+
text: `DROP ${e.kind === "constraint" ? "CONSTRAINT" : "INDEX"} \`${e.name.replace(/`/g, "``")}\` IF EXISTS`,
|
|
9
|
+
destructive: !0,
|
|
10
|
+
reason: `no longer needed: ${e.reason}`
|
|
11
|
+
});
|
|
12
|
+
for (const e of r)
|
|
13
|
+
a.push({
|
|
14
|
+
text: E(e),
|
|
15
|
+
destructive: !1,
|
|
16
|
+
reason: e.reason
|
|
17
|
+
});
|
|
18
|
+
const p = S(y(c), y(t));
|
|
19
|
+
return M(c, t, p, u), { database: { create: r, drop: l, statements: a }, api: p, notes: u };
|
|
20
|
+
}
|
|
21
|
+
function R(i, n, o, c) {
|
|
22
|
+
for (const [t, f] of i.nodes) {
|
|
23
|
+
const d = n.nodes.get(t);
|
|
24
|
+
if (!d) {
|
|
25
|
+
c.push(
|
|
26
|
+
`${t} was removed; its :${f.labels[0]} nodes stay in the database`
|
|
27
|
+
);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const s = f.labels[0], r = d.labels[0];
|
|
31
|
+
s !== r && o.push({
|
|
32
|
+
text: `MATCH (n:${h(s)}) SET n:${h(r)} REMOVE n:${h(s)}`,
|
|
33
|
+
destructive: !0,
|
|
34
|
+
reason: `${t}'s label changed from ${s} to ${r}`
|
|
35
|
+
});
|
|
36
|
+
const l = v(f.fields), a = v(d.fields);
|
|
37
|
+
for (const [u, p] of l) {
|
|
38
|
+
const e = a.get(u);
|
|
39
|
+
if (e && e.property !== p.property && o.push({
|
|
40
|
+
text: `MATCH (n:${h(r)}) WHERE n.${h(p.property)} IS NOT NULL SET n.${h(e.property)} = n.${h(p.property)} REMOVE n.${h(p.property)}`,
|
|
41
|
+
destructive: !0,
|
|
42
|
+
reason: `${t}.${u} now stores \`${e.property}\` instead of \`${p.property}\``
|
|
43
|
+
}), !e) {
|
|
44
|
+
const m = [...a.values()].find(
|
|
45
|
+
(g) => g.property === p.property && !l.has(g.name)
|
|
46
|
+
);
|
|
47
|
+
m && c.push(
|
|
48
|
+
`${t}.${u} is now ${t}.${m.name} over the same property \`${p.property}\`: an API break with no data migration`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function M(i, n, o, c) {
|
|
55
|
+
const t = (s) => new Map([
|
|
56
|
+
...[...s.nodes].map(([r, l]) => [r, l.fields]),
|
|
57
|
+
...[...s.relationshipProperties].map(
|
|
58
|
+
([r, l]) => [r, l.fields]
|
|
59
|
+
)
|
|
60
|
+
]), f = t(i);
|
|
61
|
+
let d = 0;
|
|
62
|
+
for (const [s, r] of t(n)) {
|
|
63
|
+
const l = f.get(s);
|
|
64
|
+
if (l)
|
|
65
|
+
for (const a of r.values()) {
|
|
66
|
+
const u = l.get(a.name);
|
|
67
|
+
if (a.kind !== "scalar" || u?.kind !== "scalar") continue;
|
|
68
|
+
const { tightened: p, changed: e } = k(
|
|
69
|
+
u.constraints,
|
|
70
|
+
a.constraints
|
|
71
|
+
);
|
|
72
|
+
for (const m of p)
|
|
73
|
+
d++, o.breaking.push({
|
|
74
|
+
type: "RULE_TIGHTENED",
|
|
75
|
+
description: `${s}.${a.name}: ${m}. Input the old rule accepted is now refused.`
|
|
76
|
+
});
|
|
77
|
+
for (const m of e)
|
|
78
|
+
d++, o.dangerous.push({
|
|
79
|
+
type: "RULE_CHANGED",
|
|
80
|
+
description: `${s}.${a.name}: ${m}.`
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
d > 0 && c.push(
|
|
85
|
+
`${d === 1 ? "A validation rule was" : `${d} validation rules were`} added, tightened or changed: values already stored are not revisited. \`lora-graphql check --database\` lists the ones that no longer pass.`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function v(i) {
|
|
89
|
+
const n = /* @__PURE__ */ new Map();
|
|
90
|
+
for (const o of i.values()) o.kind === "scalar" && n.set(o.name, o);
|
|
91
|
+
return n;
|
|
92
|
+
}
|
|
93
|
+
function y(i) {
|
|
94
|
+
const n = () => Promise.reject(new Error("not connected"));
|
|
95
|
+
return N(i, {
|
|
96
|
+
customResolver: () => () => null,
|
|
97
|
+
resolveSearch: n,
|
|
98
|
+
resolveAbstract: n,
|
|
99
|
+
subscribe: () => {
|
|
100
|
+
throw new Error("not connected");
|
|
101
|
+
},
|
|
102
|
+
resolveChangedNode: n,
|
|
103
|
+
previousValue: () => null,
|
|
104
|
+
resolveRoot: n,
|
|
105
|
+
resolveNode: n,
|
|
106
|
+
resolveCypher: n,
|
|
107
|
+
resolveMutation: n
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function S(i, n) {
|
|
111
|
+
const o = b;
|
|
112
|
+
if (!o.findBreakingChanges || !o.findDangerousChanges)
|
|
113
|
+
return {
|
|
114
|
+
breaking: [
|
|
115
|
+
{
|
|
116
|
+
type: "UNSUPPORTED",
|
|
117
|
+
description: "this graphql version has no findBreakingChanges; compare printPublicSchema() output with @graphql-inspector/core"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
dangerous: []
|
|
121
|
+
};
|
|
122
|
+
const c = (t) => ({
|
|
123
|
+
type: t.type,
|
|
124
|
+
description: t.description
|
|
125
|
+
});
|
|
126
|
+
return {
|
|
127
|
+
breaking: o.findBreakingChanges(i, n).map(c),
|
|
128
|
+
dangerous: o.findDangerousChanges(i, n).map(c)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
q as d
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=diff-CdZZG-N1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-CdZZG-N1.js","sources":["../src/analyze/diff.ts"],"sourcesContent":["// S7: one SDL, two diffs. A change to the annotated SDL changes both the\n// database (constraints, indexes, labels, property names) and the public\n// API; `diffSchemas` reports both from the same two documents.\n\nimport * as graphql from \"graphql\";\nimport type { DocumentNode, GraphQLSchema } from \"graphql\";\nimport { name } from \"../compile/cypher.js\";\nimport { compareConstraints } from \"../model/constraints.js\";\nimport { buildModel } from \"../model/build.js\";\nimport { type ModelOptions } from \"../model/build/limits.js\";\nimport type { Field, GraphModel, ScalarField } from \"../model/types.js\";\nimport { buildSchema } from \"../schema/build.js\";\nimport {\n inferRequirements,\n requirementDdl,\n requirementId,\n type SchemaRequirement,\n} from \"./indexes.js\";\n\nexport interface ApiChange {\n /** graphql-js change type, e.g. `FIELD_REMOVED`. */\n type: string;\n description: string;\n}\n\nexport interface SchemaDiff {\n database: {\n create: SchemaRequirement[];\n drop: SchemaRequirement[];\n /**\n * Statements in the order to run them. Drops and data migrations are\n * destructive: review them before running.\n */\n statements: Array<{ text: string; destructive: boolean; reason: string }>;\n };\n api: {\n /** Changes that break existing clients. */\n breaking: ApiChange[];\n /** Changes that may change behaviour for existing clients. */\n dangerous: ApiChange[];\n };\n /** Consequences worth a human look, e.g. a rename kept by @alias. */\n notes: string[];\n}\n\nexport function diffSchemas(\n before: string | DocumentNode,\n after: string | DocumentNode,\n options: ModelOptions = {},\n): SchemaDiff {\n const oldModel = buildModel(before, options);\n const newModel = buildModel(after, options);\n\n const id = requirementId;\n const oldReqs = new Map(inferRequirements(oldModel).map((r) => [id(r), r]));\n const newReqs = new Map(inferRequirements(newModel).map((r) => [id(r), r]));\n const create = [...newReqs]\n .filter(([k]) => !oldReqs.has(k))\n .map(([, r]) => r);\n const drop = [...oldReqs].filter(([k]) => !newReqs.has(k)).map(([, r]) => r);\n\n const statements: SchemaDiff[\"database\"][\"statements\"] = [];\n const notes: string[] = [];\n migrations(oldModel, newModel, statements, notes);\n for (const r of drop) {\n statements.push({\n text: `DROP ${r.kind === \"constraint\" ? \"CONSTRAINT\" : \"INDEX\"} \\`${r.name.replace(/`/g, \"``\")}\\` IF EXISTS`,\n destructive: true,\n reason: `no longer needed: ${r.reason}`,\n });\n }\n for (const r of create) {\n statements.push({\n text: requirementDdl(r),\n destructive: false,\n reason: r.reason,\n });\n }\n\n const api = apiChanges(publicSchema(oldModel), publicSchema(newModel));\n ruleChanges(oldModel, newModel, api, notes);\n return { database: { create, drop, statements }, api, notes };\n}\n\n/** Relabelled types and renamed properties need their data moved. */\nfunction migrations(\n before: GraphModel,\n after: GraphModel,\n statements: SchemaDiff[\"database\"][\"statements\"],\n notes: string[],\n) {\n for (const [typeName, oldNode] of before.nodes) {\n const newNode = after.nodes.get(typeName);\n if (!newNode) {\n notes.push(\n `${typeName} was removed; its :${oldNode.labels[0]} nodes stay in the database`,\n );\n continue;\n }\n const oldLabel = oldNode.labels[0]!;\n const newLabel = newNode.labels[0]!;\n if (oldLabel !== newLabel) {\n statements.push({\n text: `MATCH (n:${name(oldLabel)}) SET n:${name(newLabel)} REMOVE n:${name(oldLabel)}`,\n destructive: true,\n reason: `${typeName}'s label changed from ${oldLabel} to ${newLabel}`,\n });\n }\n const oldFields = scalars(oldNode.fields);\n const newFields = scalars(newNode.fields);\n for (const [fieldName, oldField] of oldFields) {\n const newField = newFields.get(fieldName);\n if (newField && newField.property !== oldField.property) {\n statements.push({\n text: `MATCH (n:${name(newLabel)}) WHERE n.${name(oldField.property)} IS NOT NULL SET n.${name(newField.property)} = n.${name(oldField.property)} REMOVE n.${name(oldField.property)}`,\n destructive: true,\n reason: `${typeName}.${fieldName} now stores \\`${newField.property}\\` instead of \\`${oldField.property}\\``,\n });\n }\n if (!newField) {\n const renamed = [...newFields.values()].find(\n (f) => f.property === oldField.property && !oldFields.has(f.name),\n );\n if (renamed) {\n notes.push(\n `${typeName}.${fieldName} is now ${typeName}.${renamed.name} over the same property \\`${oldField.property}\\`: an API break with no data migration`,\n );\n }\n }\n }\n }\n}\n\n/**\n * Validation rules are not part of the GraphQL type system, so graphql-js\n * sees no change when one is tightened: a `String` is still a `String`.\n * Compared here, on the model: a rule that now refuses input it accepted\n * breaks clients that send it.\n */\nfunction ruleChanges(\n before: GraphModel,\n after: GraphModel,\n api: SchemaDiff[\"api\"],\n notes: string[],\n) {\n const owners = (model: GraphModel) =>\n new Map<string, ReadonlyMap<string, Field | ScalarField>>([\n ...[...model.nodes].map(([n, t]) => [n, t.fields] as const),\n ...[...model.relationshipProperties].map(\n ([n, t]) => [n, t.fields] as const,\n ),\n ]);\n const old = owners(before);\n let stricter = 0;\n for (const [owner, fields] of owners(after)) {\n const oldFields = old.get(owner);\n if (!oldFields) continue;\n for (const f of fields.values()) {\n const was = oldFields.get(f.name);\n if (f.kind !== \"scalar\" || was?.kind !== \"scalar\") continue;\n const { tightened, changed } = compareConstraints(\n was.constraints,\n f.constraints,\n );\n for (const what of tightened) {\n stricter++;\n api.breaking.push({\n type: \"RULE_TIGHTENED\",\n description: `${owner}.${f.name}: ${what}. Input the old rule accepted is now refused.`,\n });\n }\n for (const what of changed) {\n stricter++;\n api.dangerous.push({\n type: \"RULE_CHANGED\",\n description: `${owner}.${f.name}: ${what}.`,\n });\n }\n }\n }\n if (stricter > 0) {\n notes.push(\n `${stricter === 1 ? \"A validation rule was\" : `${stricter} validation rules were`} added, tightened or changed: values already stored are not revisited. \\`lora-graphql check --database\\` lists the ones that no longer pass.`,\n );\n }\n}\n\nfunction scalars(fields: ReadonlyMap<string, Field>): Map<string, ScalarField> {\n const out = new Map<string, ScalarField>();\n for (const f of fields.values()) if (f.kind === \"scalar\") out.set(f.name, f);\n return out;\n}\n\nfunction publicSchema(model: GraphModel): GraphQLSchema {\n const never = () => Promise.reject(new Error(\"not connected\"));\n return buildSchema(model, {\n customResolver: () => () => null,\n resolveSearch: never,\n resolveAbstract: never,\n subscribe: () => {\n throw new Error(\"not connected\");\n },\n resolveChangedNode: never,\n previousValue: () => null,\n resolveRoot: never,\n resolveNode: never,\n resolveCypher: never,\n resolveMutation: never,\n });\n}\n\ntype ChangeFinder = (\n a: GraphQLSchema,\n b: GraphQLSchema,\n) => Array<{ type: string; description: string }>;\n\nfunction apiChanges(\n before: GraphQLSchema,\n after: GraphQLSchema,\n): SchemaDiff[\"api\"] {\n // graphql-js 16 ships these; 17 removed them.\n const lib = graphql as unknown as {\n findBreakingChanges?: ChangeFinder;\n findDangerousChanges?: ChangeFinder;\n };\n if (!lib.findBreakingChanges || !lib.findDangerousChanges) {\n return {\n breaking: [\n {\n type: \"UNSUPPORTED\",\n description:\n \"this graphql version has no findBreakingChanges; compare printPublicSchema() output with @graphql-inspector/core\",\n },\n ],\n dangerous: [],\n };\n }\n const pick = (c: { type: string; description: string }) => ({\n type: c.type,\n description: c.description,\n });\n return {\n breaking: lib.findBreakingChanges(before, after).map(pick),\n dangerous: lib.findDangerousChanges(before, after).map(pick),\n };\n}\n"],"names":["diffSchemas","before","after","options","oldModel","buildModel","newModel","id","requirementId","oldReqs","inferRequirements","r","newReqs","create","k","drop","statements","notes","migrations","requirementDdl","api","apiChanges","publicSchema","ruleChanges","typeName","oldNode","newNode","oldLabel","newLabel","name","oldFields","scalars","newFields","fieldName","oldField","newField","renamed","f","owners","model","n","t","old","stricter","owner","fields","was","tightened","changed","compareConstraints","what","out","never","buildSchema","lib","graphql","pick","c"],"mappings":"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"}
|