@loradb/lora-graphql 0.18.0 → 0.20.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 +324 -77
- package/dist/analyze/access.d.ts +32 -0
- package/dist/analyze/lint.d.ts +9 -0
- package/dist/cli.js +310 -286
- package/dist/cli.js.map +1 -1
- package/dist/compile/auth.d.ts +64 -2
- package/dist/compile/cache.d.ts +37 -0
- package/dist/compile/context.d.ts +12 -0
- package/dist/compile/cypher.d.ts +5 -0
- package/dist/compile/read.d.ts +6 -0
- package/dist/{diff-fpWH5KUa.js → diff-DUOLUgrI.js} +2 -2
- package/dist/{diff-fpWH5KUa.js.map → diff-DUOLUgrI.js.map} +1 -1
- package/dist/driver-C7a5NkfH.js +11521 -0
- package/dist/driver-C7a5NkfH.js.map +1 -0
- package/dist/driver.d.ts +17 -8
- package/dist/errors.d.ts +1 -1
- package/dist/execute/feed.d.ts +1 -1
- package/dist/guards.d.ts +13 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/lora-graphql.d.ts +37 -5
- package/dist/model/desugar.d.ts +34 -0
- package/dist/model/directives.d.ts +1 -1
- package/dist/model/positions.d.ts +22 -0
- package/dist/model/types.d.ts +38 -1
- package/dist/testing.d.ts +27 -0
- package/dist/testing.js +145 -28
- package/dist/testing.js.map +1 -1
- package/package.json +4 -3
- package/dist/driver-CQj9gkvl.js +0 -9580
- package/dist/driver-CQj9gkvl.js.map +0 -1
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sources":["../src/testing.ts"],"sourcesContent":["// Test helpers: an in-memory LoraDB with the schema asserted, and a plan\n// assertion. Import from `@loradb/lora-graphql/testing`; needs\n// `@loradb/lora-node`. Framework-agnostic: failures throw plain errors.\n\nimport {\n graphql,\n type DocumentNode,\n type ExecutionResult,\n type GraphQLSchema,\n} from \"graphql\";\nimport { loraDriver, type LoraDatabaseLike } from \"./driver.js\";\nimport {\n LoraGraphQL,\n type LoraGraphQLOptions,\n type StatementEvent,\n} from \"./lora-graphql.js\";\n\n/** The node binding's database, as far as tests use it. */\nexport type TestDatabase = LoraDatabaseLike & {\n execute(query: string, params?: never): Promise<unknown>;\n dispose?(): void;\n};\n\nexport interface TestLoraGraphQLOptions extends Omit<\n LoraGraphQLOptions,\n \"driver\"\n> {\n /** Cypher to run after the schema is asserted, or a function given the database. */\n seed?: string | string[] | ((db: TestDatabase) => Promise<void>);\n}\n\nexport interface TestLoraGraphQL {\n lora: LoraGraphQL;\n db: TestDatabase;\n schema: GraphQLSchema;\n /** Every statement run so far (clear with `statements.length = 0`). */\n statements: StatementEvent[];\n /** Execute a document; errors stay in the result. */\n run: (\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => Promise<ExecutionResult>;\n /** Execute a document and return its data; throws on the first error. */\n data: <T = Record<string, unknown>>(\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => Promise<T>;\n /** Release the database. */\n close: () => void;\n}\n\n/** A LoraGraphQL over a fresh in-memory database, schema asserted and seeded. */\nexport async function createTestLoraGraphQL(\n options: TestLoraGraphQLOptions,\n): Promise<TestLoraGraphQL> {\n let createDatabase: () => Promise<TestDatabase>;\n try {\n ({ createDatabase } = (await import(\"@loradb/lora-node\")) as unknown as {\n createDatabase: typeof createDatabase;\n });\n } catch {\n throw new Error(\n \"createTestLoraGraphQL needs @loradb/lora-node: npm install --save-dev @loradb/lora-node\",\n );\n }\n const db = await createDatabase();\n const statements: StatementEvent[] = [];\n const { seed, onStatement, ...rest } = options;\n const lora = new LoraGraphQL({\n ...rest,\n driver: loraDriver(db),\n onStatement: (event) => {\n statements.push(event);\n onStatement?.(event);\n },\n });\n await lora.assertSchema({ create: true });\n if (typeof seed === \"function\") await seed(db);\n else {\n for (const text of typeof seed === \"string\" ? [seed] : (seed ?? [])) {\n await db.execute(text);\n }\n }\n const schema = lora.getSchema();\n const run = (\n source: string,\n variables: Record<string, unknown> = {},\n contextValue: Record<string, unknown> = {},\n ) => graphql({ schema, source, variableValues: variables, contextValue });\n return {\n lora,\n db,\n schema,\n statements,\n run,\n data: async <T>(\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => {\n const r = await run(source, variables, context);\n if (r.errors) throw r.errors[0];\n return r.data as T;\n },\n close: () => db.dispose?.(),\n };\n}\n\n/**\n * Assert that every statement of a query's root fields uses the index\n * access it was compiled for (no label scans where a seek was expected,\n * no mutating plans, no row-budget excess). Throws listing each finding.\n */\nexport async function expectSeeks(\n lora: LoraGraphQL,\n document: string | DocumentNode,\n variables: Record<string, unknown> = {},\n options: { rowBudget?: number; context?: unknown } = {},\n): Promise<void> {\n const fields = await lora.explain(document, variables, options);\n const findings = fields.flatMap((f) =>\n f.reports.flatMap((r) =>\n r.findings.map((x) => `${f.field}: ${x.message}\\n ${x.statement}`),\n ),\n );\n if (findings.length > 0) {\n throw new Error(\n `expected every root field to seek:\\n${findings.join(\"\\n\")}`,\n );\n }\n}\n"],"names":["createTestLoraGraphQL","options","createDatabase","db","statements","seed","onStatement","rest","lora","LoraGraphQL","loraDriver","event","text","schema","run","source","variables","contextValue","graphql","context","r","expectSeeks","document","findings","f","x"],"mappings":";;AAsDA,eAAsBA,EACpBC,GAC0B;AAC1B,MAAIC;AACJ,MAAI;AACF,KAAC,EAAE,gBAAAA,EAAA,IAAoB,MAAM,OAAO,mBAAmB;AAAA,EAGzD,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,QAAMC,IAAK,MAAMD,EAAA,GACXE,IAA+B,CAAA,GAC/B,EAAE,MAAAC,GAAM,aAAAC,GAAa,GAAGC,MAASN,GACjCO,IAAO,IAAIC,EAAY;AAAA,IAC3B,GAAGF;AAAA,IACH,QAAQG,EAAWP,CAAE;AAAA,IACrB,aAAa,CAACQ,MAAU;AACtB,MAAAP,EAAW,KAAKO,CAAK,GACrBL,IAAcK,CAAK;AAAA,IACrB;AAAA,EAAA,CACD;AAED,MADA,MAAMH,EAAK,aAAa,EAAE,QAAQ,IAAM,GACpC,OAAOH,KAAS,WAAY,OAAMA,EAAKF,CAAE;AAAA;AAE3C,eAAWS,KAAQ,OAAOP,KAAS,WAAW,CAACA,CAAI,IAAKA,KAAQ;AAC9D,YAAMF,EAAG,QAAQS,CAAI;AAGzB,QAAMC,IAASL,EAAK,UAAA,GACdM,IAAM,CACVC,GACAC,IAAqC,CAAA,GACrCC,IAAwC,CAAA,MACrCC,EAAQ,EAAE,QAAAL,GAAQ,QAAAE,GAAQ,gBAAgBC,GAAW,cAAAC,GAAc;AACxE,SAAO;AAAA,IACL,MAAAT;AAAA,IACA,IAAAL;AAAA,IACA,QAAAU;AAAA,IACA,YAAAT;AAAA,IACA,KAAAU;AAAA,IACA,MAAM,OACJC,GACAC,GACAG,MACG;AACH,YAAMC,IAAI,MAAMN,EAAIC,GAAQC,GAAWG,CAAO;AAC9C,UAAIC,EAAE,OAAQ,OAAMA,EAAE,OAAO,CAAC;AAC9B,aAAOA,EAAE;AAAA,IACX;AAAA,IACA,OAAO,MAAMjB,EAAG,UAAA;AAAA,EAAU;AAE9B;AAOA,eAAsBkB,EACpBb,GACAc,GACAN,IAAqC,CAAA,GACrCf,IAAqD,IACtC;AAEf,QAAMsB,KADS,MAAMf,EAAK,QAAQc,GAAUN,GAAWf,CAAO,GACtC;AAAA,IAAQ,CAACuB,MAC/BA,EAAE,QAAQ;AAAA,MAAQ,CAAC,MACjB,EAAE,SAAS,IAAI,CAACC,MAAM,GAAGD,EAAE,KAAK,KAAKC,EAAE,OAAO;AAAA,IAAOA,EAAE,SAAS,EAAE;AAAA,IAAA;AAAA,EACpE;AAEF,MAAIF,EAAS,SAAS;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,EAAuCA,EAAS,KAAK;AAAA,CAAI,CAAC;AAAA,IAAA;AAGhE;"}
|
|
1
|
+
{"version":3,"file":"testing.js","sources":["../src/testing.ts"],"sourcesContent":["// Test helpers: an in-memory LoraDB with the schema asserted, and a plan\n// assertion. Import from `@loradb/lora-graphql/testing`; needs\n// `@loradb/lora-node`. Framework-agnostic: failures throw plain errors.\n\nimport {\n graphql,\n type DocumentNode,\n type ExecutionResult,\n type GraphQLSchema,\n} from \"graphql\";\nimport { loraDriver, type LoraDatabaseLike } from \"./driver.js\";\nimport {\n LoraGraphQL,\n type LoraGraphQLOptions,\n type StatementEvent,\n} from \"./lora-graphql.js\";\n\n/** The node binding's database, as far as tests use it. */\nexport type TestDatabase = LoraDatabaseLike & {\n execute(query: string, params?: never): Promise<unknown>;\n dispose?(): void;\n};\n\nexport interface TestLoraGraphQLOptions extends Omit<\n LoraGraphQLOptions,\n \"driver\"\n> {\n /** Cypher to run after the schema is asserted, or a function given the database. */\n seed?: string | string[] | ((db: TestDatabase) => Promise<void>);\n}\n\nexport interface TestLoraGraphQL {\n lora: LoraGraphQL;\n db: TestDatabase;\n schema: GraphQLSchema;\n /** Every statement run so far (clear with `statements.length = 0`). */\n statements: StatementEvent[];\n /** Execute a document; errors stay in the result. */\n run: (\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => Promise<ExecutionResult>;\n /** Execute a document and return its data; throws on the first error. */\n data: <T = Record<string, unknown>>(\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => Promise<T>;\n /** Release the database. */\n close: () => void;\n}\n\n/** A LoraGraphQL over a fresh in-memory database, schema asserted and seeded. */\nexport async function createTestLoraGraphQL(\n options: TestLoraGraphQLOptions,\n): Promise<TestLoraGraphQL> {\n let createDatabase: () => Promise<TestDatabase>;\n try {\n ({ createDatabase } = (await import(\"@loradb/lora-node\")) as unknown as {\n createDatabase: typeof createDatabase;\n });\n } catch {\n throw new Error(\n \"createTestLoraGraphQL needs @loradb/lora-node: npm install --save-dev @loradb/lora-node\",\n );\n }\n const db = await createDatabase();\n const statements: StatementEvent[] = [];\n const { seed, onStatement, ...rest } = options;\n const lora = new LoraGraphQL({\n ...rest,\n driver: loraDriver(db),\n onStatement: (event) => {\n statements.push(event);\n onStatement?.(event);\n },\n });\n await lora.assertSchema({ create: true });\n if (typeof seed === \"function\") await seed(db);\n else {\n for (const text of typeof seed === \"string\" ? [seed] : (seed ?? [])) {\n await db.execute(text);\n }\n }\n const schema = lora.getSchema();\n const run = (\n source: string,\n variables: Record<string, unknown> = {},\n contextValue: Record<string, unknown> = {},\n ) => graphql({ schema, source, variableValues: variables, contextValue });\n return {\n lora,\n db,\n schema,\n statements,\n run,\n data: async <T>(\n source: string,\n variables?: Record<string, unknown>,\n context?: Record<string, unknown>,\n ) => {\n const r = await run(source, variables, context);\n if (r.errors) throw r.errors[0];\n return r.data as T;\n },\n close: () => db.dispose?.(),\n };\n}\n\n/**\n * Assert that every statement of a query's root fields uses the index\n * access it was compiled for (no label scans where a seek was expected,\n * no mutating plans, no row-budget excess). Throws listing each finding.\n */\nexport async function expectSeeks(\n lora: LoraGraphQL,\n document: string | DocumentNode,\n variables: Record<string, unknown> = {},\n options: { rowBudget?: number; context?: unknown } = {},\n): Promise<void> {\n const fields = await lora.explain(document, variables, options);\n const findings = fields.flatMap((f) =>\n f.reports.flatMap((r) =>\n r.findings.map((x) => `${f.field}: ${x.message}\\n ${x.statement}`),\n ),\n );\n if (findings.length > 0) {\n throw new Error(\n `expected every root field to seek:\\n${findings.join(\"\\n\")}`,\n );\n }\n}\n\n/** The access `expectAccess` expects: entries allowed, and entries denied. */\nexport interface AccessExpectations {\n /** The claims to act as; undefined acts anonymously. */\n as: Record<string, unknown> | undefined;\n /** Other GraphQL context values the rules read (`$context.*`). */\n context?: Record<string, unknown>;\n allowed?: readonly string[];\n denied?: readonly string[];\n}\n\n/**\n * Assert who may do what, against the database: each entry runs as the\n * caller in a transaction that is always rolled back, and every mismatch\n * is reported at once. Entries:\n *\n * - `read Trip lou:tomorrowland` (denied: not visible, or refused)\n * - `create Trip lou:x {\"name\": \"X\"}` (other input fields as JSON)\n * - `update Trip lou:x {\"name\": \"Y\"}` and `delete Trip lou:x`\n * - `connect Trip.members lou:tomorrowland → f1` (also `->`)\n * - `disconnect Trip.members lou:tomorrowland → f1`\n * - `update-edge Trip.members lou:tomorrowland → f1 {\"rsvp\": \"GOING\"}`\n *\n * Denied means `FORBIDDEN`, `UNAUTHENTICATED` or `NOT_FOUND` (a node the\n * caller cannot see); any other error is reported as a mismatch either way.\n */\nexport async function expectAccess(\n target: LoraGraphQL | { lora: LoraGraphQL },\n expectations: AccessExpectations,\n): Promise<void> {\n const lora = target instanceof LoraGraphQL ? target : target.lora;\n const problems: string[] = [];\n const check = async (entry: string, allowed: boolean) => {\n let outcome: AccessOutcome;\n try {\n outcome = await tryAccess(lora, entry, expectations);\n } catch (err) {\n problems.push(\n `${entry}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return;\n }\n if (outcome.kind === \"error\") {\n problems.push(`${entry}: failed with ${outcome.message}`);\n } else if (allowed && outcome.kind === \"denied\") {\n problems.push(\n `expected allowed, was denied: ${entry} (${outcome.message})`,\n );\n } else if (!allowed && outcome.kind === \"allowed\") {\n problems.push(`expected denied, was allowed: ${entry}`);\n }\n };\n for (const entry of expectations.allowed ?? []) await check(entry, true);\n for (const entry of expectations.denied ?? []) await check(entry, false);\n if (problems.length > 0) {\n const who = expectations.as ? JSON.stringify(expectations.as) : \"anonymous\";\n throw new Error(\n `access as ${who} differs in ${problems.length} ${problems.length === 1 ? \"entry\" : \"entries\"}:\\n ${problems.join(\"\\n \")}`,\n );\n }\n}\n\ntype AccessOutcome =\n | { kind: \"allowed\" }\n | { kind: \"denied\"; message: string }\n | { kind: \"error\"; message: string };\n\nconst DENIED = new Set([\"FORBIDDEN\", \"UNAUTHENTICATED\", \"NOT_FOUND\"]);\n\nasync function tryAccess(\n lora: LoraGraphQL,\n entry: string,\n expectations: AccessExpectations,\n): Promise<AccessOutcome> {\n const { source, variables, isRead, root } = accessOperation(lora, entry);\n const tx = await lora.begin();\n try {\n const result = await lora.execute({\n source,\n variables,\n context: {\n ...expectations.context,\n ...(expectations.as ? { jwt: expectations.as } : {}),\n transaction: tx,\n },\n });\n const error = result.errors?.[0];\n if (error) {\n const code = (error.extensions as Record<string, unknown> | undefined)?.[\n \"code\"\n ];\n return typeof code === \"string\" && DENIED.has(code)\n ? { kind: \"denied\", message: `${code}: ${error.message}` }\n : {\n kind: \"error\",\n message: `${String(code ?? \"error\")}: ${error.message}`,\n };\n }\n if (isRead) {\n const value = (result.data as Record<string, unknown> | null)?.[root];\n if (value == null) return { kind: \"denied\", message: \"not visible\" };\n }\n return { kind: \"allowed\" };\n } finally {\n await tx.rollback();\n }\n}\n\nfunction accessOperation(\n lora: LoraGraphQL,\n entry: string,\n): {\n operation: string;\n source: string;\n variables: Record<string, unknown>;\n isRead: boolean;\n root: string;\n} {\n const m =\n /^\\s*(read|create|update|delete|connect|disconnect|update-edge)\\s+([A-Za-z_][\\w]*)(?:\\.([A-Za-z_]\\w*))?\\s+(\\S+)(?:\\s*(?:→|->)\\s*(\\S+))?\\s*(\\{.*\\})?\\s*$/s.exec(\n entry,\n );\n if (!m) {\n throw new Error(\n \"expected `<read|create|update|delete> Type key [json]` or `<connect|disconnect|update-edge> Type.field key → key [json]`\",\n );\n }\n const [, operation, typeName, fieldName, key, other, json] = m as unknown as [\n string,\n string,\n string,\n string | undefined,\n string,\n string | undefined,\n string | undefined,\n ];\n const node = lora.model.nodes.get(typeName);\n if (!node) throw new Error(`${typeName} is not a @node type`);\n const input = json ? (JSON.parse(json) as Record<string, unknown>) : {};\n const keyType = `${node.key.customScalar ?? node.key.type}!`;\n const lower = typeName.charAt(0).toLowerCase() + typeName.slice(1);\n const upperPlural =\n node.plural.charAt(0).toUpperCase() + node.plural.slice(1);\n const relational = [\"connect\", \"disconnect\", \"update-edge\"].includes(\n operation,\n );\n if (relational !== (fieldName !== undefined && other !== undefined)) {\n throw new Error(\n relational\n ? `${operation} takes Type.field key → key`\n : `${operation} takes Type key`,\n );\n }\n switch (operation) {\n case \"read\":\n return {\n operation,\n source: `query($key: ${keyType}) { ${lower}(${node.key.name}: $key) { ${node.key.name} } }`,\n variables: { key },\n isRead: true,\n root: lower,\n };\n case \"create\":\n return {\n operation,\n source: `mutation($input: [${typeName}CreateInput!]!) { create${upperPlural}(input: $input) { __typename } }`,\n variables: { input: [{ ...input, [node.key.name]: key }] },\n isRead: false,\n root: `create${upperPlural}`,\n };\n case \"update\":\n return {\n operation,\n source: `mutation($key: ${keyType}, $update: ${typeName}UpdateInput!) { update${typeName}(${node.key.name}: $key, update: $update) { __typename } }`,\n variables: { key, update: input },\n isRead: false,\n root: `update${typeName}`,\n };\n case \"delete\":\n return {\n operation,\n source: `mutation($key: ${keyType}) { delete${typeName}(${node.key.name}: $key) { __typename } }`,\n variables: { key },\n isRead: false,\n root: `delete${typeName}`,\n };\n }\n const field = node.fields.get(fieldName!);\n if (field?.kind !== \"relationship\") {\n throw new Error(`${typeName}.${fieldName} is not a relationship field`);\n }\n const targetKey = lora.model.nodes.get(field.target)?.key.name ?? \"key\";\n const change =\n operation === \"connect\"\n ? {\n connect: field.list\n ? [{ [targetKey]: other, ...(json ? { edge: input } : {}) }]\n : { [targetKey]: other, ...(json ? { edge: input } : {}) },\n }\n : operation === \"disconnect\"\n ? { disconnect: field.list ? [other] : true }\n : { update: [{ [targetKey]: other, edge: input }] };\n return {\n operation,\n source: `mutation($key: ${keyType}, $update: ${typeName}UpdateInput!) { update${typeName}(${node.key.name}: $key, update: $update) { __typename } }`,\n variables: { key, update: { [fieldName!]: change } },\n isRead: false,\n root: `update${typeName}`,\n };\n}\n"],"names":["createTestLoraGraphQL","options","createDatabase","db","statements","seed","onStatement","rest","lora","LoraGraphQL","loraDriver","event","text","schema","run","source","variables","contextValue","graphql","context","r","expectSeeks","document","findings","f","x","expectAccess","target","expectations","problems","check","entry","allowed","outcome","tryAccess","err","who","DENIED","isRead","root","accessOperation","tx","result","error","code","m","operation","typeName","fieldName","key","other","json","node","input","keyType","lower","upperPlural","relational","field","targetKey","change"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loradb/lora-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Schema-first GraphQL for LoraDB: one annotated SDL becomes an executable, index-aware GraphQL API that compiles every operation to a single Cypher statement.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"packageManager": "yarn@4.5.1",
|
|
@@ -61,10 +61,11 @@
|
|
|
61
61
|
"lint:fix": "eslint src test bench --fix",
|
|
62
62
|
"format": "prettier --write src test",
|
|
63
63
|
"format:check": "prettier --check src test",
|
|
64
|
-
"bench": "vitest bench --run"
|
|
64
|
+
"bench": "vitest bench --run",
|
|
65
|
+
"bench:load": "node bench/load/main.mjs"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
|
-
"@loradb/lora-node": "^0.
|
|
68
|
+
"@loradb/lora-node": "^0.20.0",
|
|
68
69
|
"graphql": "^16.8.0 || ^17.0.0"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|