@loradb/lora-graphql 0.16.2 → 0.18.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 +106 -26
- package/dist/analyze/plans.d.ts +6 -0
- package/dist/cli.js +271 -262
- package/dist/cli.js.map +1 -1
- package/dist/compile/auth.d.ts +32 -0
- package/dist/compile/selection.d.ts +13 -0
- package/dist/{diff-BVP1Jzh3.js → diff-fpWH5KUa.js} +2 -2
- package/dist/{diff-BVP1Jzh3.js.map → diff-fpWH5KUa.js.map} +1 -1
- package/dist/{driver-C8vA5fV-.js → driver-CQj9gkvl.js} +3628 -3175
- package/dist/driver-CQj9gkvl.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/lora-graphql.d.ts +27 -9
- package/dist/model/cypher-lexer.d.ts +6 -0
- package/dist/model/inputs.d.ts +12 -0
- package/dist/model/types.d.ts +12 -0
- package/dist/schema/mutations.d.ts +2 -4
- package/dist/testing.js +1 -1
- package/package.json +4 -2
- package/dist/driver-C8vA5fV-.js.map +0 -1
package/dist/errors.d.ts
CHANGED
|
@@ -15,6 +15,6 @@ export declare class ModelError extends Error {
|
|
|
15
15
|
constructor(problems: ModelProblem[]);
|
|
16
16
|
}
|
|
17
17
|
export declare function formatProblem(p: ModelProblem): string;
|
|
18
|
-
export type LoraGraphQLErrorCode = "BAD_USER_INPUT" | "INVALID_CURSOR" | "LIMIT_EXCEEDED" | "COST_EXCEEDED" | "UNAUTHENTICATED" | "FORBIDDEN" | "NOT_FOUND" | "CONSTRAINT_VIOLATION" | "DATABASE_ERROR";
|
|
18
|
+
export type LoraGraphQLErrorCode = "BAD_USER_INPUT" | "INVALID_CURSOR" | "LIMIT_EXCEEDED" | "COST_EXCEEDED" | "UNAUTHENTICATED" | "FORBIDDEN" | "NOT_FOUND" | "CONSTRAINT_VIOLATION" | "DATABASE_ERROR" | "PERSISTED_QUERY_ONLY";
|
|
19
19
|
/** A request-time error with a stable `extensions.code`. */
|
|
20
20
|
export declare function requestError(code: LoraGraphQLErrorCode, message: string, cause?: unknown, extensions?: Record<string, unknown>): GraphQLError;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as e, L as r, a as o, M as l, b as i, c as d, d as n, e as t, f, g as m, i as p, l as c, p as h, r as D, s as b, h as u, t as v, v as L } from "./driver-
|
|
2
|
-
import { d as x } from "./diff-
|
|
1
|
+
import { D as e, L as r, a as o, M as l, b as i, c as d, d as n, e as t, f, g as m, i as p, l as c, p as h, r as D, s as b, h as u, t as v, v as L } from "./driver-CQj9gkvl.js";
|
|
2
|
+
import { d as x } from "./diff-fpWH5KUa.js";
|
|
3
3
|
export {
|
|
4
4
|
e as DEFAULT_GUARDS,
|
|
5
5
|
r as LoraGraphQL,
|
package/dist/lora-graphql.d.ts
CHANGED
|
@@ -59,9 +59,10 @@ export interface LoraGraphQLOptions extends ModelOptions, ObservabilityOptions {
|
|
|
59
59
|
scalars?: Record<string, GraphQLScalarType>;
|
|
60
60
|
/**
|
|
61
61
|
* Feed subscriptions and `changes()` from the engine's committed change
|
|
62
|
-
* feed (lora-node `db.changes()`):
|
|
63
|
-
* in commit order. `onWrite`
|
|
64
|
-
* and `previousState` needs
|
|
62
|
+
* feed (lora-node `db.changes()`): every write to the database, from
|
|
63
|
+
* any path in the process that owns it, in commit order. `onWrite`
|
|
64
|
+
* still reports this instance's mutations, and `previousState` needs
|
|
65
|
+
* them. Default false.
|
|
65
66
|
*/
|
|
66
67
|
changeFeed?: boolean;
|
|
67
68
|
/**
|
|
@@ -80,14 +81,15 @@ export interface LoraGraphQLOptions extends ModelOptions, ObservabilityOptions {
|
|
|
80
81
|
/** Called with every database error, masked or not. */
|
|
81
82
|
onError?: (event: DatabaseErrorEvent) => void;
|
|
82
83
|
/**
|
|
83
|
-
* Limits on the documents `execute()` and `persist()`
|
|
84
|
+
* Limits on the documents `execute()`, `subscribe()` and `persist()`
|
|
85
|
+
* accept: depth,
|
|
84
86
|
* aliases, root fields, tokens, introspection. `false` turns them off.
|
|
85
87
|
* For other servers use `validationRules()` or `envelopPlugin()`.
|
|
86
88
|
*/
|
|
87
89
|
guards?: DocumentGuards | false;
|
|
88
90
|
/**
|
|
89
|
-
* Make `execute()` refuse `source` and run only
|
|
90
|
-
* by `id`. Default false.
|
|
91
|
+
* Make `execute()` and `subscribe()` refuse `source` and run only
|
|
92
|
+
* persisted operations by `id`. Default false.
|
|
91
93
|
*/
|
|
92
94
|
persistedOnly?: boolean;
|
|
93
95
|
}
|
|
@@ -143,11 +145,17 @@ export interface CheckOptions {
|
|
|
143
145
|
* that stops an index-ordered scan early.
|
|
144
146
|
*/
|
|
145
147
|
rowBudget?: number;
|
|
146
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Operations to compile and plan-check (S2), with example variables and
|
|
150
|
+
* the GraphQL context to compile them under (e.g. `{ jwt }`, so rules
|
|
151
|
+
* compile as they do for a signed-in caller). Without one, an operation
|
|
152
|
+
* compiles as an anonymous request would.
|
|
153
|
+
*/
|
|
147
154
|
operations?: Array<{
|
|
148
155
|
name?: string;
|
|
149
156
|
document: string | DocumentNode;
|
|
150
157
|
variables?: Record<string, unknown>;
|
|
158
|
+
context?: unknown;
|
|
151
159
|
}>;
|
|
152
160
|
}
|
|
153
161
|
export interface CheckReport {
|
|
@@ -263,10 +271,20 @@ export declare class LoraGraphQL {
|
|
|
263
271
|
*/
|
|
264
272
|
loadManifest(manifest: OperationManifest): void;
|
|
265
273
|
/**
|
|
266
|
-
* Execute
|
|
267
|
-
* documents are cached by source text; persisted ones by id.
|
|
274
|
+
* Execute a query or mutation against the schema. Parsed and validated
|
|
275
|
+
* documents are cached by source text; persisted ones by id. A
|
|
276
|
+
* subscription runs with {@link LoraGraphQL.subscribe}.
|
|
268
277
|
*/
|
|
269
278
|
execute(args: ExecuteArgs): Promise<ExecutionResult>;
|
|
279
|
+
/**
|
|
280
|
+
* Run a subscription: an async iterable of results, one per event, or a
|
|
281
|
+
* single result with the errors when it cannot start (an unknown id, a
|
|
282
|
+
* validation error, a denied subscribe). Takes the same arguments as
|
|
283
|
+
* {@link LoraGraphQL.execute}, a persisted id included, with the same
|
|
284
|
+
* document cache and guards. End it with `return()` on the iterator, or
|
|
285
|
+
* with an `AbortSignal` passed as `context.signal`.
|
|
286
|
+
*/
|
|
287
|
+
subscribe(args: ExecuteArgs): Promise<AsyncIterableIterator<ExecutionResult> | ExecutionResult>;
|
|
270
288
|
/** Called after every committed mutation with its exact write-set. */
|
|
271
289
|
onWrite(listener: (change: WriteChange) => void): () => void;
|
|
272
290
|
/**
|
|
@@ -8,3 +8,9 @@ export declare function scanParams(text: string): ParamRef[];
|
|
|
8
8
|
export declare function renameParams(text: string, rename: (name: string) => string): string;
|
|
9
9
|
/** Code outside strings and comments, uppercased, for construct checks. */
|
|
10
10
|
export declare function codeOnly(text: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* `text` with the same length and offsets, strings and comments blanked
|
|
13
|
+
* and the insides of backtick-quoted names replaced by `_`, so structure
|
|
14
|
+
* (brackets, commas, keywords) can be read without being fooled by them.
|
|
15
|
+
*/
|
|
16
|
+
export declare function maskLiterals(text: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GraphModel, NodeType, RelationshipField, RelationshipPropertiesType, ScalarField } from './types.js';
|
|
2
|
+
/** Whether clients may set a field on `op` (`@settable`, `@readonly`, …). */
|
|
3
|
+
export declare function settable(f: ScalarField | RelationshipField, op: "CREATE" | "UPDATE"): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Whether an update input for `node` has any field: a scalar settable on
|
|
6
|
+
* update, or a relationship offering a nested operation.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isUpdatable(model: GraphModel, node: NodeType, seen?: Set<string>): boolean;
|
|
9
|
+
/** Whether the create or update input of `rel` offers any operation. */
|
|
10
|
+
export declare function offersNested(model: GraphModel, rel: RelationshipField, update: boolean, seen?: Set<string>): boolean;
|
|
11
|
+
/** Whether any property of a @relationshipProperties type is settable on `op`. */
|
|
12
|
+
export declare function hasSettable(props: RelationshipPropertiesType, op: "CREATE" | "UPDATE"): boolean;
|
package/dist/model/types.d.ts
CHANGED
|
@@ -103,6 +103,14 @@ export interface RelationshipField extends FieldBase {
|
|
|
103
103
|
onDelete: "DETACH" | "CASCADE" | "RESTRICT";
|
|
104
104
|
/** Nested writes mutation inputs offer for the field. */
|
|
105
105
|
nestedOperations: ReadonlySet<NestedOperation>;
|
|
106
|
+
/**
|
|
107
|
+
* `@settable` / `@readonly`: whether create and update inputs offer the
|
|
108
|
+
* field at all (an upsert of an existing node keeps its relationship).
|
|
109
|
+
*/
|
|
110
|
+
settableOn: {
|
|
111
|
+
create: boolean;
|
|
112
|
+
update: boolean;
|
|
113
|
+
};
|
|
106
114
|
/** Whether the field's connection and filters offer aggregates. */
|
|
107
115
|
aggregate: boolean;
|
|
108
116
|
cardinality: number | undefined;
|
|
@@ -162,6 +170,8 @@ export interface CustomField extends FieldBase {
|
|
|
162
170
|
description: string | undefined;
|
|
163
171
|
}
|
|
164
172
|
export type Field = ScalarField | RelationshipField | CypherField | CustomField;
|
|
173
|
+
/** A `${jwt.path}` / `${context.path}` placeholder inside a rule string. */
|
|
174
|
+
export declare const PLACEHOLDER: RegExp;
|
|
165
175
|
/** `{ node, jwt, AND, OR, NOT }`, as written in `@authorization`. */
|
|
166
176
|
export type AuthorizationWhere = Record<string, unknown>;
|
|
167
177
|
export interface AuthorizationFilterRule {
|
|
@@ -291,6 +301,8 @@ export interface GraphModel {
|
|
|
291
301
|
warnings: readonly ModelWarning[];
|
|
292
302
|
/** Custom scalars (`@storedAs`), by name: their storage type. */
|
|
293
303
|
scalars: ReadonlyMap<string, ScalarType>;
|
|
304
|
+
/** Custom scalars' SDL descriptions, by name, when they have one. */
|
|
305
|
+
scalarDescriptions: ReadonlyMap<string, string>;
|
|
294
306
|
/** Object types without @node that @cypher fields return. */
|
|
295
307
|
objects: ReadonlyMap<string, PlainObjectType>;
|
|
296
308
|
/** The `@jwt` claims shape, when declared: claim name → token path. */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { GraphQLObjectType, GraphQLFieldConfigMap, GraphQLInputType, GraphQLResolveInfo } from 'graphql';
|
|
2
2
|
import { GraphModel, MutationOperation, NodeType, ScalarField } from '../model/types.js';
|
|
3
|
+
import { isUpdatable, settable } from '../model/inputs.js';
|
|
4
|
+
export { isUpdatable, settable };
|
|
3
5
|
/** A generated mutation: the single-node ones, and the bulk ones by where. */
|
|
4
6
|
export type MutationKind = MutationOperation | "UPSERT" | "UPDATE_MANY" | "DELETE_MANY";
|
|
5
7
|
export type MutationResolver = (operation: MutationKind, node: NodeType, info: GraphQLResolveInfo, context: unknown) => Promise<unknown>;
|
|
@@ -33,12 +35,8 @@ export interface MutationSchemaContext {
|
|
|
33
35
|
inputType: (f: ScalarField) => GraphQLInputType;
|
|
34
36
|
where: (typeName: string) => GraphQLInputType;
|
|
35
37
|
}
|
|
36
|
-
/** Whether clients may set a field on `op` (`@settable`, `@readonly`, …). */
|
|
37
|
-
export declare function settable(f: ScalarField, op: "CREATE" | "UPDATE"): boolean;
|
|
38
38
|
/** Whether the create input must carry the field. */
|
|
39
39
|
export declare function requiredOnCreate(f: ScalarField): boolean;
|
|
40
|
-
/** A type with nothing settable after create has no update. */
|
|
41
|
-
export declare function isUpdatable(node: NodeType): boolean;
|
|
42
40
|
/** Numeric and list fields take operators in `adjust`. */
|
|
43
41
|
export declare function adjustable(f: ScalarField): boolean;
|
|
44
42
|
export declare function buildMutations(ctx: MutationSchemaContext, resolve: MutationResolver): GraphQLFieldConfigMap<unknown, unknown>;
|
package/dist/testing.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loradb/lora-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.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",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"build": "vite build",
|
|
56
56
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
57
|
"test": "vitest run",
|
|
58
|
+
"test:graphql17": "LORA_GRAPHQL_VERSION=17 vitest run",
|
|
58
59
|
"test:watch": "vitest",
|
|
59
60
|
"lint": "eslint src test bench",
|
|
60
61
|
"lint:fix": "eslint src test bench --fix",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"bench": "vitest bench --run"
|
|
64
65
|
},
|
|
65
66
|
"peerDependencies": {
|
|
66
|
-
"@loradb/lora-node": "^0.
|
|
67
|
+
"@loradb/lora-node": "^0.18.0",
|
|
67
68
|
"graphql": "^16.8.0 || ^17.0.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
"eslint": "^9.15.0",
|
|
73
74
|
"fast-check": "^4.10.2",
|
|
74
75
|
"graphql": "^16.9.0",
|
|
76
|
+
"graphql17": "npm:graphql@17.0.2",
|
|
75
77
|
"typescript": "^5.6.0",
|
|
76
78
|
"vite": "^5.4.0",
|
|
77
79
|
"vite-plugin-dts": "^4.2.0",
|