@loradb/lora-graphql 0.23.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +68 -13
  2. package/dist/analyze/access-lint.d.ts +7 -0
  3. package/dist/analyze/access.d.ts +13 -33
  4. package/dist/analyze/assert-schema.d.ts +19 -0
  5. package/dist/analyze/diff.d.ts +1 -1
  6. package/dist/analyze/plans.d.ts +1 -1
  7. package/dist/analyze/principals.d.ts +25 -0
  8. package/dist/analyze/verdicts.d.ts +51 -0
  9. package/dist/cli.js +2 -2
  10. package/dist/cli.js.map +1 -1
  11. package/dist/compile/cache.d.ts +1 -1
  12. package/dist/compile/read/abstract.d.ts +19 -0
  13. package/dist/compile/read/aggregates.d.ts +34 -0
  14. package/dist/compile/read/by-keys.d.ts +10 -0
  15. package/dist/compile/read/common.d.ts +30 -0
  16. package/dist/compile/read/connection.d.ts +26 -0
  17. package/dist/compile/read/cypher-field.d.ts +21 -0
  18. package/dist/compile/read/match.d.ts +11 -0
  19. package/dist/compile/read/project.d.ts +15 -0
  20. package/dist/compile/read/root.d.ts +5 -0
  21. package/dist/compile/read/search.d.ts +16 -0
  22. package/dist/compile/read/sort.d.ts +42 -0
  23. package/dist/compile/read/types.d.ts +61 -0
  24. package/dist/{diff-B9iDdELF.js → diff-K8-GSeKH.js} +2 -2
  25. package/dist/diff-K8-GSeKH.js.map +1 -0
  26. package/dist/{driver-C5dSoSD8.js → driver-CXKPLfkz.js} +10796 -10254
  27. package/dist/driver-CXKPLfkz.js.map +1 -0
  28. package/dist/execute/cypher-mutation.d.ts +1 -1
  29. package/dist/execute/mutate/adjust.d.ts +5 -0
  30. package/dist/execute/mutate/checks.d.ts +21 -0
  31. package/dist/execute/mutate/delete.d.ts +7 -0
  32. package/dist/execute/mutate/env.d.ts +73 -0
  33. package/dist/execute/mutate/errors.d.ts +7 -0
  34. package/dist/execute/mutate/fragments.d.ts +37 -0
  35. package/dist/execute/mutate/plan.d.ts +95 -0
  36. package/dist/execute/mutate/runner.d.ts +129 -0
  37. package/dist/execute/mutate/unique-together.d.ts +18 -0
  38. package/dist/execute/mutate.d.ts +2 -79
  39. package/dist/index.d.ts +10 -6
  40. package/dist/index.js +2 -2
  41. package/dist/lora-graphql.d.ts +18 -328
  42. package/dist/model/build/authorization.d.ts +31 -0
  43. package/dist/model/build/cypher-field.d.ts +11 -0
  44. package/dist/model/build/directive-args.d.ts +16 -0
  45. package/dist/model/build/limits.d.ts +18 -0
  46. package/dist/model/build/relationship-field.d.ts +11 -0
  47. package/dist/model/build/rule-checks.d.ts +23 -0
  48. package/dist/model/build/rule-references.d.ts +28 -0
  49. package/dist/model/build/scalar-field.d.ts +7 -0
  50. package/dist/model/build/search.d.ts +4 -0
  51. package/dist/model/build/shapes.d.ts +18 -0
  52. package/dist/model/build/unique-together.d.ts +5 -0
  53. package/dist/model/build.d.ts +3 -20
  54. package/dist/model/directives.d.ts +1 -1
  55. package/dist/model/types.d.ts +12 -2
  56. package/dist/options.d.ts +255 -0
  57. package/dist/results.d.ts +70 -0
  58. package/dist/runtime/custom-requires.d.ts +7 -0
  59. package/dist/runtime/database-error.d.ts +10 -0
  60. package/dist/runtime/documents.d.ts +35 -0
  61. package/dist/runtime/limits.d.ts +37 -0
  62. package/dist/runtime/request.d.ts +33 -0
  63. package/dist/runtime/timing.d.ts +13 -0
  64. package/dist/schema/aggregates.d.ts +17 -0
  65. package/dist/schema/base.d.ts +17 -0
  66. package/dist/schema/build.d.ts +3 -42
  67. package/dist/schema/filters.d.ts +10 -0
  68. package/dist/schema/hooks.d.ts +42 -0
  69. package/dist/schema/objects.d.ts +36 -0
  70. package/dist/schema/query.d.ts +8 -0
  71. package/dist/schema/resolvers.d.ts +13 -0
  72. package/dist/schema/sorts.d.ts +5 -0
  73. package/dist/schema/subscriptions.d.ts +7 -0
  74. package/dist/subscriptions/change-hub.d.ts +50 -0
  75. package/dist/subscriptions/compiles.d.ts +23 -0
  76. package/dist/subscriptions/events.d.ts +9 -0
  77. package/dist/subscriptions/filter-cost.d.ts +15 -0
  78. package/dist/subscriptions/subscriptions.d.ts +73 -0
  79. package/dist/testing.d.ts +4 -1
  80. package/dist/testing.js +34 -29
  81. package/dist/testing.js.map +1 -1
  82. package/package.json +2 -2
  83. package/dist/compile/read.d.ts +0 -102
  84. package/dist/diff-B9iDdELF.js.map +0 -1
  85. package/dist/driver-C5dSoSD8.js.map +0 -1
package/README.md CHANGED
@@ -746,18 +746,24 @@ type Claims @jwt {
746
746
  roles: [String!] @jwtClaim(path: "app_metadata.roles")
747
747
  }
748
748
 
749
+ extend schema @authorizationDefaults(requireAuthentication: false)
750
+
749
751
  type Post
750
752
  @node
751
753
  @mutation
752
754
  @authentication(operations: [CREATE, UPDATE, DELETE])
753
755
  @authorization(
754
756
  filter: [
757
+ { where: { node: { published: { eq: true } } } }
758
+ { where: { node: { author: { key: { eq: "$jwt.sub" } } } } }
755
759
  {
756
- where: { node: { published: { eq: true } } }
757
- requireAuthentication: false
760
+ where: {
761
+ AND: [
762
+ { jwt: { sub: { exists: true } } }
763
+ { node: { tenant: { eq: "$context.tenant" } } }
764
+ ]
765
+ }
758
766
  }
759
- { where: { node: { author: { key: { eq: "$jwt.sub" } } } } }
760
- { where: { node: { tenant: { eq: "$context.tenant" } } } }
761
767
  { where: { jwt: { roles: { includes: "admin" } } } }
762
768
  ]
763
769
  validate: [
@@ -791,19 +797,39 @@ type Post
791
797
  }
792
798
  ```
793
799
 
800
+ - A rule takes `operations`, `when` (validate rules) and `where`; any
801
+ other field is a model error, so a misspelt `operations` cannot fall
802
+ back to the default unnoticed.
794
803
  - A rule is `{ node, jwt, AND, OR, NOT }`. `node` is a filter over the type
795
804
  (relationship properties included, through `<field>Connection: { some:
796
805
  { node, edge } }`), where `"$jwt.path"` strings become the caller's claims and
797
806
  `"$context.path"` strings values from the GraphQL context. `jwt` tests
798
807
  claims (`eq`, `in`, `includes`, `contains`, `startsWith`, `endsWith`,
799
808
  `lt`, `lte`, `gt`, `gte`, `exists`).
809
+ - **Anonymous callers.** Without a token every rule denies, unless the
810
+ schema says `@authorizationDefaults(requireAuthentication: false)`. Then
811
+ a rule with a branch that reads no claims decides that branch for
812
+ anonymous callers too (the published posts above). A rule that needs
813
+ claims still denies them, and how depends on the kind of rule: a
814
+ validate rule asks for a token (`UNAUTHENTICATED`, not `FORBIDDEN`),
815
+ while a READ filter admits no row, so a signed-out caller reads an
816
+ empty list and the access matrix calls it `denied`.
817
+ It is one setting for the schema; a rule has no such field, and it
818
+ reaches every rule: a CREATE, UPDATE, DELETE or CONNECT rule that
819
+ reads no claims decides for signed-out callers as well. `check` names
820
+ each such write rule that no `@authentication` covers. To keep a
821
+ claim-free rule or branch for signed-in callers, test a claim beside it
822
+ (`{ jwt: { sub: { exists: true } } }`, as the tenant rule above does),
823
+ or put `@authentication` on the type or the relationship field.
800
824
  - **The caller's own node.** Mark the claim that identifies the caller
801
825
  with `@viewer(type: "Person", field: "subject")` (the field is `@key` or
802
826
  `@unique`), so the key can stay a slug while the subject is an identity
803
827
  provider's opaque id. Rules then say `{ node: { isViewer: true } }` on
804
828
  the viewer type, or `{ node: { author: { isViewer: true } } }` through a
805
829
  relationship; this expands to `{ subject: { eq: "$jwt.sub" } }` at
806
- startup and compiles to exactly the same statement. `viewer: { verified:
830
+ startup and compiles to exactly the same statement. With `@viewer`
831
+ declared, writing that expansion out by hand is a model error: the
832
+ mapping lives in one place. `viewer: { verified:
807
833
  { eq: true } }` tests the caller's own node: one seek by the claim. Both
808
834
  are unknown without the claim, so `NOT { isViewer: true }` never grants a
809
835
  signed-out caller. `isViewer` takes `true` only; use `NOT` for the
@@ -1019,6 +1045,8 @@ deleted: Org.docs has onDelete: RESTRICT`. Replacing a single
1019
1045
  covers an operation, it replaces the default for that operation, never
1020
1046
  merges with it. `check()` fails on a `@mutation` type whose
1021
1047
  writes nothing guards, unless it says `@authorization(public: [...])`.
1048
+ `requireAuthentication` (see "Anonymous callers" above) is the third
1049
+ setting here.
1022
1050
 
1023
1051
  Relationship and `@cypher` fields take field-level `@authorization`
1024
1052
  with READ validate rules: a row failing the rule reads the field as
@@ -1105,7 +1133,10 @@ type Trip @node @mutation {
1105
1133
  - The rules hold whichever side the write comes from: a connect through
1106
1134
  `Person.trips` (the same relationship type, the other direction)
1107
1135
  answers to `Trip.members`' rules, with source and target as declared on
1108
- `Trip.members`. If both fields carry rules, both apply.
1136
+ `Trip.members`. Declare each operation's rules on one of the two
1137
+ fields: the same operation ruled on both is a model error (combine
1138
+ with `AND` where both must pass); different operations may sit on
1139
+ different sides.
1109
1140
  - A relationship failing `READ_EDGE` reads its properties as `FORBIDDEN`.
1110
1141
  Unless the claims alone settle the rule, nothing may filter, sort or
1111
1142
  aggregate by that relationship's properties.
@@ -1417,17 +1448,32 @@ relationship property (READ, CREATE, UPDATE) and root `@cypher` field,
1417
1448
  each operation as each kind of caller (anonymous, authenticated, and each role
1418
1449
  the rules test, such as `roles:admin`), with the verdict (`allowed`,
1419
1450
  `filtered`, `validated`, `masked`, `denied`, `unauthenticated`) and the
1420
- rules that decide it. A `@key(scope: VIEWER)` type's CREATE reads
1451
+ rules that decide it. When rules name the caller's node (`isViewer`),
1452
+ `viewer` is the caller on nodes that are theirs: every rule part that
1453
+ only names them passes, so it shows the most a related caller gets,
1454
+ where `authenticated` shows what any signed-in caller gets. A part under
1455
+ `NOT` stays as written and is decided per row, so `viewer` never reads
1456
+ below `authenticated`. A relationship field has a CONNECT row when a
1457
+ rule or `@authentication(operations: [CREATE_RELATIONSHIP])` guards it,
1458
+ and a DISCONNECT row for a rule or `DELETE_RELATIONSHIP`. A
1459
+ `@key(scope: VIEWER)` type's CREATE reads
1421
1460
  `unauthenticated` for anonymous callers and `validated` by `key scope`
1422
1461
  for the rest.
1423
1462
 
1424
- `lora.operationAccess(document | persistedId, operationName?)` answers
1425
- the same question for one operation: each root field (fragments
1463
+ `lora.operationAccess(document | persistedId, operationName?, variables?)`
1464
+ answers the same question for one operation: each root field (fragments
1426
1465
  followed) with its type, the operations it needs (an upsert needs
1427
1466
  `CREATE` and `UPDATE`) and the verdict per caller, plus the most
1428
1467
  restrictive verdict per caller over all root fields. A field over
1429
1468
  several types (`node`, a union) reports the most restrictive member.
1430
- Root fields only: nested selections answer to their own types' rules.
1469
+ A mutation's inputs are read for what they write through relationship
1470
+ fields: a nested connect or create counts as that field's CONNECT (and
1471
+ the target's CREATE), a disconnect or nested delete as its DISCONNECT, an
1472
+ `update: { edge }` as UPDATE_EDGE, each named in `by`
1473
+ (`Room.chan CONNECT: @authentication`). Pass `variables` for inputs the
1474
+ document takes as variables; a variable without a value is not read and
1475
+ is listed in the field's `unresolved`. Selections below a root field
1476
+ answer to their own types' READ rules.
1431
1477
  To keep admin-only operations out of client bundles:
1432
1478
 
1433
1479
  ````ts
@@ -1441,10 +1487,19 @@ order is stable, so a snapshot in CI turns access changes into diffs.
1441
1487
  `check` lints authorization too:
1442
1488
 
1443
1489
  - a filter rule every signed-in caller passes;
1444
- - a rule whose default `requireAuthentication` refuses anonymous callers
1445
- a branch that needs no claims;
1490
+ - a rule that needs no claims, as a whole or in one `OR` branch, on a
1491
+ type or a field, in a schema that leaves
1492
+ `@authorizationDefaults(requireAuthentication:)` unset: anonymous
1493
+ callers are refused it by default, so say which was meant;
1494
+ - once that setting is `false`, each write rule (CREATE, UPDATE, DELETE,
1495
+ CONNECT, DISCONNECT, UPDATE_EDGE) a signed-out caller can pass and no
1496
+ `@authentication` covers. READ rules and operations the type lists in
1497
+ `public` are left alone: those are what the setting and the list are
1498
+ for;
1446
1499
  - field rules the schema's bypass skips, on a type that says neither
1447
- `@authorization(bypass: false)` nor `bypass: true`;
1500
+ `@authorization(bypass: false)` nor `bypass: true`, and one line naming
1501
+ every type with rules the bypass reaches that way (plus relationship
1502
+ property types, whose rules cannot opt out);
1448
1503
  - an UPDATE rule testing a single relationship the update input can
1449
1504
  re-point (`connect`, `disconnect`, `create`): the rule sees the node
1450
1505
  before (and, validated `AFTER`, after) the write, so a caller passing it
@@ -0,0 +1,7 @@
1
+ import { GraphQLSchema } from 'graphql';
2
+ import { GraphModel, ModelWarning } from '../model/types.js';
3
+ /**
4
+ * Authorization lints for `check`: valid rules that are probably not what
5
+ * was meant.
6
+ */
7
+ export declare function accessLints(model: GraphModel, schema: GraphQLSchema): ModelWarning[];
@@ -1,29 +1,6 @@
1
1
  import { FragmentDefinitionNode, GraphQLSchema, OperationDefinitionNode } from 'graphql';
2
- import { AuthOperation, GraphModel, ModelWarning } from '../model/types.js';
3
- export type AccessVerdict =
4
- /** Every row, for this caller. */
5
- "allowed"
6
- /** Only rows a filter rule admits; others are invisible. */
7
- | "filtered"
8
- /** Checked per row; a failing row is FORBIDDEN. */
9
- | "validated"
10
- /** Rows failing a mask read a substitute value. */
11
- | "masked"
12
- /** Never, for this caller. */
13
- | "denied"
14
- /** Needs a token this caller does not have. */
15
- | "unauthenticated";
16
- export interface AccessEntry {
17
- type: string;
18
- /** The field, for field-level and relationship rules. */
19
- field?: string;
20
- /** `EXECUTE`: running a Mutation @cypher field. */
21
- operation: AuthOperation | "EXECUTE";
22
- principal: string;
23
- verdict: AccessVerdict;
24
- /** What decides it: `filter[0]`, `validate[1]`, `@authentication`, `bypass`, … */
25
- by: string[];
26
- }
2
+ import { AuthOperation, GraphModel } from '../model/types.js';
3
+ import { AccessEntry, AccessVerdict } from './verdicts.js';
27
4
  /** One root field of an operation, as each kind of caller. */
28
5
  export interface RootFieldAccess {
29
6
  /** The root field. */
@@ -46,6 +23,11 @@ export interface RootFieldAccess {
46
23
  verdict: AccessVerdict;
47
24
  by: string[];
48
25
  }>;
26
+ /**
27
+ * Variables in the field's arguments that were given no value: what
28
+ * they would write through relationship fields is not in `access`.
29
+ */
30
+ unresolved?: string[];
49
31
  }
50
32
  export interface OperationAccess {
51
33
  operation: "query" | "mutation" | "subscription";
@@ -62,14 +44,12 @@ export interface OperationAccess {
62
44
  }
63
45
  /**
64
46
  * Who may run `operation`: each root field's verdict per principal, read
65
- * off the same rules as `accessMatrix`. Root fields only: nested
66
- * selections answer to their own types' READ rules (see the matrix).
47
+ * off the same rules as `accessMatrix`. A mutation's inputs are read for
48
+ * the relationship writes they make, each a part of its root field's
49
+ * verdict; an input given as a variable is read when `variables` has its
50
+ * value and listed in `unresolved` when it does not. Selections below a
51
+ * root field answer to their own types' READ rules (see the matrix).
67
52
  */
68
- export declare function operationAccess(model: GraphModel, schema: GraphQLSchema, operation: OperationDefinitionNode, fragments: ReadonlyMap<string, FragmentDefinitionNode>): OperationAccess;
53
+ export declare function operationAccess(model: GraphModel, schema: GraphQLSchema, operation: OperationDefinitionNode, fragments: ReadonlyMap<string, FragmentDefinitionNode>, variables?: Readonly<Record<string, unknown>>): OperationAccess;
69
54
  /** The access matrix of `model`, in a stable order. */
70
55
  export declare function accessMatrix(model: GraphModel, schema: GraphQLSchema): AccessEntry[];
71
- /**
72
- * Authorization lints for `check`: valid rules that are probably not what
73
- * was meant.
74
- */
75
- export declare function accessLints(model: GraphModel, schema: GraphQLSchema): ModelWarning[];
@@ -0,0 +1,19 @@
1
+ import { LoraDriver } from '../driver.js';
2
+ import { AssertSchemaOptions } from '../options.js';
3
+ import { CheckReport, SchemaAssertion } from '../results.js';
4
+ import { SchemaRequirement } from './indexes.js';
5
+ export interface SchemaEnv {
6
+ driver: LoraDriver;
7
+ /** Timeout for every statement, in milliseconds. */
8
+ timeoutMs: number;
9
+ /** Constraints and indexes the API needs. */
10
+ requirements(): SchemaRequirement[];
11
+ }
12
+ /**
13
+ * Verify the database has every constraint and index the API needs;
14
+ * with `create`, add what is missing. Idempotent. Runs one DDL
15
+ * statement at a time: LoraDB rejects schema commands in transactions.
16
+ */
17
+ export declare function assertSchema(env: SchemaEnv, options: AssertSchemaOptions): Promise<SchemaAssertion>;
18
+ /** Indexes in the database that no requirement of the API matches. */
19
+ export declare function unusedIndexes(env: SchemaEnv): Promise<CheckReport["unused"]>;
@@ -1,5 +1,5 @@
1
1
  import { DocumentNode } from 'graphql';
2
- import { ModelOptions } from '../model/build.js';
2
+ import { ModelOptions } from '../model/build/limits.js';
3
3
  import { SchemaRequirement } from './indexes.js';
4
4
  export interface ApiChange {
5
5
  /** graphql-js change type, e.g. `FIELD_REMOVED`. */
@@ -1,5 +1,5 @@
1
1
  import { LoraDriver, QueryPlan, Statement } from '../driver.js';
2
- import { CompiledRead } from '../compile/read.js';
2
+ import { CompiledRead } from '../compile/read/types.js';
3
3
  export interface PlanFinding {
4
4
  rule: "full-scan" | "mutating-read" | "result-columns" | "scan-expand" | "row-budget";
5
5
  message: string;
@@ -0,0 +1,25 @@
1
+ import { Field, GraphModel, NodeType, RelationshipPropertiesType } from '../model/types.js';
2
+ export interface Principal {
3
+ name: string;
4
+ jwt: Record<string, unknown> | undefined;
5
+ /** The model this principal's verdicts are read off, when not the schema's. */
6
+ model?: GraphModel;
7
+ }
8
+ /** `node` (or its field, or a property type's field) as `p` sees the model. */
9
+ export declare const nodeAs: (p: Principal, node: NodeType) => NodeType;
10
+ export declare const fieldAs: <F extends Field>(p: Principal, node: NodeType, f: F) => F;
11
+ export declare const propertyAs: <F extends {
12
+ name: string;
13
+ }>(p: Principal, props: RelationshipPropertiesType, f: F) => F;
14
+ /**
15
+ * Anonymous, authenticated (a token with no roles), `viewer` when rules
16
+ * name the caller's node, and one principal per claim value the rules
17
+ * test with `includes`, `eq` or `in` (`roles:admin`).
18
+ */
19
+ export declare function principalsOf(model: GraphModel): Principal[];
20
+ /**
21
+ * A token carrying `claims` where the `@jwt` type says they live
22
+ * (`@jwtClaim(path: "app_metadata.roles")`).
23
+ */
24
+ export declare function token(model: GraphModel, claims: Record<string, unknown>): Record<string, unknown>;
25
+ export declare const isRecord: (x: unknown) => x is Record<string, unknown>;
@@ -0,0 +1,51 @@
1
+ import { fieldReadGuard, propertyAccess, relationshipRules } from '../compile/auth.js';
2
+ import { CompileContext } from '../compile/context.js';
3
+ import { AuthOperation, CypherField, Field, NodeType, RelationshipOperation } from '../model/types.js';
4
+ export type AccessVerdict =
5
+ /** Every row, for this caller. */
6
+ "allowed"
7
+ /** Only rows a filter rule admits; others are invisible. */
8
+ | "filtered"
9
+ /** Checked per row; a failing row is FORBIDDEN. */
10
+ | "validated"
11
+ /** Rows failing a mask read a substitute value. */
12
+ | "masked"
13
+ /** Never, for this caller. */
14
+ | "denied"
15
+ /** Needs a token this caller does not have. */
16
+ | "unauthenticated";
17
+ export interface AccessEntry {
18
+ type: string;
19
+ /** The field, for field-level and relationship rules. */
20
+ field?: string;
21
+ /** `EXECUTE`: running a Mutation @cypher field. */
22
+ operation: AuthOperation | "EXECUTE";
23
+ principal: string;
24
+ verdict: AccessVerdict;
25
+ /** What decides it: `filter[0]`, `validate[1]`, `@authentication`, `bypass`, … */
26
+ by: string[];
27
+ }
28
+ export declare function rootFieldVerdict(ctx: CompileContext, field: CypherField): Pick<AccessEntry, "verdict" | "by">;
29
+ export declare const PROPERTY_OPS: readonly ["READ", "CREATE", "UPDATE"];
30
+ /** `field` has rules (or `@authentication`) for `op`. */
31
+ export declare function fieldWriteGuarded(field: {
32
+ authentication?: ReadonlySet<AuthOperation> | undefined;
33
+ authorization?: NodeType["authorization"];
34
+ }, op: AuthOperation): boolean;
35
+ export declare function fieldWriteVerdict(ctx: CompileContext, node: NodeType, field: Field & {
36
+ kind: "scalar";
37
+ }, op: "CREATE" | "UPDATE"): Pick<AccessEntry, "verdict" | "by">;
38
+ export declare function propertyVerdict(ctx: CompileContext, field: Parameters<typeof propertyAccess>[1], op: AuthOperation): Pick<AccessEntry, "verdict" | "by">;
39
+ export declare function typeVerdict(ctx: CompileContext, node: NodeType, op: AuthOperation): Pick<AccessEntry, "verdict" | "by">;
40
+ export declare function fieldVerdict(ctx: CompileContext, node: NodeType, field: Parameters<typeof fieldReadGuard>[2] & {
41
+ name: string;
42
+ kind: string;
43
+ authorization?: NodeType["authorization"];
44
+ }): Pick<AccessEntry, "verdict" | "by">;
45
+ /**
46
+ * The `@authentication` operation a relationship operation answers to: a
47
+ * connect is checked as CREATE_RELATIONSHIP on the field, a disconnect as
48
+ * DELETE_RELATIONSHIP. Edge reads and updates have none of their own.
49
+ */
50
+ export declare function relationshipAuthentication(op: RelationshipOperation): AuthOperation | undefined;
51
+ export declare function relationshipVerdict(ctx: CompileContext, node: NodeType, field: Parameters<typeof relationshipRules>[1], op: RelationshipOperation): Pick<AccessEntry, "verdict" | "by">;
package/dist/cli.js CHANGED
@@ -3,8 +3,8 @@ import { execFileSync as re } from "node:child_process";
3
3
  import { stat as M, readFile as ce, readdir as ue, mkdir as le, writeFile as _ } from "node:fs/promises";
4
4
  import { dirname as fe, basename as de, join as O, relative as pe } from "node:path";
5
5
  import { parse as j, Kind as p, visit as Y, print as Z, typeFromAST as me, isNonNullType as G, isListType as he, getNamedType as ge, isEnumType as ve, isInputObjectType as we } from "graphql";
6
- import { d as Ee } from "./diff-B9iDdELF.js";
7
- import { q as K, e as be, M as Te, a as R, l as X, g as x, u as ee, c as Ne, i as ye, r as Se, w as Ie } from "./driver-C5dSoSD8.js";
6
+ import { d as Ee } from "./diff-K8-GSeKH.js";
7
+ import { q as K, e as be, M as Te, a as R, l as X, g as x, u as ee, c as Ne, i as ye, r as Se, w as Ie } from "./driver-CXKPLfkz.js";
8
8
  const $e = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]), W = {
9
9
  coalesce: "@coalesce is not supported: it hides predicates from indexes; store a value instead",
10
10
  subscriptionsAuthorization: "@subscriptionsAuthorization is not supported: SUBSCRIBE rules go in @authorization",