@loradb/lora-graphql 0.16.2 → 0.17.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 +86 -20
- 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-8nsBSSNP.js} +2 -2
- package/dist/{diff-BVP1Jzh3.js.map → diff-8nsBSSNP.js.map} +1 -1
- package/dist/{driver-C8vA5fV-.js → driver-BmnRtkpd.js} +3487 -3125
- package/dist/driver-BmnRtkpd.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/lora-graphql.d.ts +11 -4
- 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/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { stat as
|
|
3
|
-
import { join as
|
|
4
|
-
import { parse as
|
|
5
|
-
import { d as
|
|
6
|
-
import { m as
|
|
7
|
-
const
|
|
2
|
+
import { stat as z, readdir as oe, readFile as ie, mkdir as re, writeFile as _ } from "node:fs/promises";
|
|
3
|
+
import { join as $, relative as ce } from "node:path";
|
|
4
|
+
import { parse as q, Kind as p, visit as H, print as Q, typeFromAST as ue, isNonNullType as F, isListType as le, getNamedType as fe, isEnumType as de, isInputObjectType as pe } from "graphql";
|
|
5
|
+
import { d as me } from "./diff-8nsBSSNP.js";
|
|
6
|
+
import { m as V, d as he, M as ge, L as M, l as Y, f as J, o as Z, b as ve, i as we, r as Te, u as Ee } from "./driver-BmnRtkpd.js";
|
|
7
|
+
const be = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]), W = {
|
|
8
8
|
coalesce: "@coalesce is not supported: it hides predicates from indexes; store a value instead",
|
|
9
9
|
subscriptionsAuthorization: "@subscriptionsAuthorization is not supported: SUBSCRIBE rules go in @authorization",
|
|
10
10
|
shareable: "federation (@shareable) is not supported",
|
|
@@ -13,7 +13,7 @@ const we = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]), x = {
|
|
|
13
13
|
provides: "federation (@provides) is not supported",
|
|
14
14
|
exclude: "@exclude: use @query / @mutation to choose operations",
|
|
15
15
|
vector: "@vector on types (with a provider) is not supported: put @vector(dimensions:, similarity:) on a [Float!] field"
|
|
16
|
-
},
|
|
16
|
+
}, Ne = [
|
|
17
17
|
["_NOT_IN", "IN"],
|
|
18
18
|
["_STARTS_WITH", "STARTS_WITH"],
|
|
19
19
|
["_ENDS_WITH", "ENDS_WITH"],
|
|
@@ -25,7 +25,7 @@ const we = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]), x = {
|
|
|
25
25
|
["_LT", "LT"],
|
|
26
26
|
["_IN", "IN"],
|
|
27
27
|
["_EQ", "EQ"]
|
|
28
|
-
],
|
|
28
|
+
], Se = {
|
|
29
29
|
eq: "EQ",
|
|
30
30
|
in: "IN",
|
|
31
31
|
lt: "LT",
|
|
@@ -38,249 +38,249 @@ const we = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]), x = {
|
|
|
38
38
|
includes: "INCLUDES",
|
|
39
39
|
caseInsensitive: "CASE_INSENSITIVE"
|
|
40
40
|
};
|
|
41
|
-
function
|
|
42
|
-
const o =
|
|
43
|
-
(i) => i.kind === p.OBJECT_TYPE_DEFINITION && !
|
|
44
|
-
),
|
|
41
|
+
function Ie(t, n = []) {
|
|
42
|
+
const o = q(t, { noLocation: !0 }), s = [], e = o.definitions.filter(
|
|
43
|
+
(i) => i.kind === p.OBJECT_TYPE_DEFINITION && !be.has(i.name.value) && !O(i.directives, "relationshipProperties") && !O(i.directives, "jwt")
|
|
44
|
+
), u = new Set(e.map((i) => i.name.value)), a = n.length > 0 ? De(n, e) : void 0, c = H(o, {
|
|
45
45
|
ObjectTypeDefinition(i) {
|
|
46
|
-
if (!
|
|
46
|
+
if (!u.has(i.name.value)) return;
|
|
47
47
|
const r = i.name.value;
|
|
48
|
-
let l =
|
|
48
|
+
let l = K(
|
|
49
49
|
i.directives ?? [],
|
|
50
50
|
r,
|
|
51
51
|
void 0,
|
|
52
52
|
s
|
|
53
53
|
);
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
54
|
+
O(l, "node") || (l = [...l, I("node")]);
|
|
55
|
+
const d = a?.mutations.get(r);
|
|
56
|
+
O(l, "mutation") || (a ? d && d.size > 0 && (l = [
|
|
57
57
|
...l,
|
|
58
58
|
I("mutation", {
|
|
59
|
-
operations: R([...
|
|
59
|
+
operations: R([...d].sort())
|
|
60
60
|
})
|
|
61
61
|
]) : (l = [...l, I("mutation")], s.push(
|
|
62
62
|
`${r}: @mutation added (@neo4j/graphql generates mutations for every type); remove it or narrow its operations`
|
|
63
63
|
)));
|
|
64
|
-
const m = (i.fields ?? []).filter((v) =>
|
|
64
|
+
const m = (i.fields ?? []).filter((v) => O(v.directives, "id"));
|
|
65
65
|
m.length === 0 ? s.push(
|
|
66
66
|
`${r}: no @id field; add a required @key field (the sort tie-breaker and mutation address)`
|
|
67
67
|
) : m.length > 1 && s.push(`${r}: several @id fields; keep one as the @key`);
|
|
68
68
|
const h = (i.fields ?? []).map(
|
|
69
|
-
(v) =>
|
|
69
|
+
(v) => ye(v, r, a, s)
|
|
70
70
|
);
|
|
71
71
|
return { ...i, directives: l, fields: h };
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
|
-
return { typeDefs:
|
|
74
|
+
return { typeDefs: Q(c), todos: s };
|
|
75
75
|
}
|
|
76
|
-
function
|
|
77
|
-
let e =
|
|
76
|
+
function ye(t, n, o, s) {
|
|
77
|
+
let e = K(
|
|
78
78
|
t.directives ?? [],
|
|
79
79
|
n,
|
|
80
80
|
t.name.value,
|
|
81
81
|
s
|
|
82
82
|
);
|
|
83
|
-
e.find((
|
|
84
|
-
(
|
|
85
|
-
), e.push(I("key", { generate:
|
|
83
|
+
e.find((c) => c.name.value === "id") && (e = e.filter(
|
|
84
|
+
(c) => c.name.value !== "id" && c.name.value !== "unique"
|
|
85
|
+
), e.push(I("key", { generate: ee(!0) })));
|
|
86
86
|
const a = o?.filters.get(n)?.get(t.name.value);
|
|
87
|
-
return a && a.size > 0 && !
|
|
88
|
-
|
|
89
|
-
), o?.sorts.get(n)?.has(t.name.value) && !
|
|
87
|
+
return a && a.size > 0 && !O(e, "filterable") && e.push(
|
|
88
|
+
O(e, "relationship") ? I("filterable") : I("filterable", { byValue: R([...a].sort()) })
|
|
89
|
+
), o?.sorts.get(n)?.has(t.name.value) && !O(e, "sortable") && e.push(I("sortable")), { ...t, directives: e };
|
|
90
90
|
}
|
|
91
|
-
function
|
|
92
|
-
const e = o ? `${n}.${o}` : n,
|
|
91
|
+
function K(t, n, o, s) {
|
|
92
|
+
const e = o ? `${n}.${o}` : n, u = [];
|
|
93
93
|
for (const a of t) {
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
s.push(`${e}: ${
|
|
94
|
+
const c = a.name.value;
|
|
95
|
+
if (c in W) {
|
|
96
|
+
s.push(`${e}: ${W[c]}`);
|
|
97
97
|
continue;
|
|
98
98
|
}
|
|
99
|
-
if (
|
|
99
|
+
if (c === "key" && !o) {
|
|
100
100
|
s.push(`${e}: federation @key(fields:) is not supported`);
|
|
101
101
|
continue;
|
|
102
102
|
}
|
|
103
|
-
if (
|
|
104
|
-
|
|
103
|
+
if (c === "unique") {
|
|
104
|
+
u.push(I("unique"));
|
|
105
105
|
continue;
|
|
106
106
|
}
|
|
107
|
-
if (
|
|
108
|
-
|
|
107
|
+
if (c === "relationship") {
|
|
108
|
+
u.push(Oe(a, e, s));
|
|
109
109
|
continue;
|
|
110
110
|
}
|
|
111
|
-
if (
|
|
112
|
-
|
|
111
|
+
if (c === "fulltext") {
|
|
112
|
+
u.push($e(a, "indexes", "indexName", "name"));
|
|
113
113
|
continue;
|
|
114
114
|
}
|
|
115
|
-
if (
|
|
116
|
-
|
|
115
|
+
if (c === "subscription") {
|
|
116
|
+
u.push(ke(a, e, s));
|
|
117
117
|
continue;
|
|
118
118
|
}
|
|
119
|
-
(
|
|
120
|
-
`${e}: check the @${
|
|
121
|
-
),
|
|
119
|
+
(c === "authorization" || c === "authentication") && s.push(
|
|
120
|
+
`${e}: check the @${c} rule's filters: operators are written { field: { eq: ... } } here`
|
|
121
|
+
), u.push(a);
|
|
122
122
|
}
|
|
123
|
-
return
|
|
123
|
+
return u;
|
|
124
124
|
}
|
|
125
|
-
function
|
|
125
|
+
function Oe(t, n, o) {
|
|
126
126
|
const s = [];
|
|
127
127
|
for (const e of t.arguments ?? []) {
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
130
|
-
e.value.value.includes("UNDIRECTED") && s.push(
|
|
128
|
+
const u = e.name.value;
|
|
129
|
+
if (u === "queryDirection" && e.value.kind === p.ENUM) {
|
|
130
|
+
e.value.value.includes("UNDIRECTED") && s.push(A("queryDirection", X("UNDIRECTED")));
|
|
131
131
|
continue;
|
|
132
132
|
}
|
|
133
|
-
if (
|
|
133
|
+
if (u === "nestedOperations" && e.value.kind === p.LIST) {
|
|
134
134
|
const a = e.value.values.filter(
|
|
135
|
-
(
|
|
135
|
+
(c) => c.kind === p.ENUM && c.value !== "CONNECT_OR_CREATE"
|
|
136
136
|
);
|
|
137
|
-
a.length < e.value.values.length && o.push(`${n}: connectOrCreate is not supported; use upsert`), s.push(
|
|
137
|
+
a.length < e.value.values.length && o.push(`${n}: connectOrCreate is not supported; use upsert`), s.push(A("nestedOperations", { kind: p.LIST, values: a }));
|
|
138
138
|
continue;
|
|
139
139
|
}
|
|
140
140
|
s.push(e);
|
|
141
141
|
}
|
|
142
142
|
return { ...t, arguments: s };
|
|
143
143
|
}
|
|
144
|
-
function
|
|
144
|
+
function ke(t, n, o) {
|
|
145
145
|
const s = t.arguments?.find((a) => a.name.value === "events")?.value;
|
|
146
146
|
if (!s || s.kind !== p.LIST) return t;
|
|
147
147
|
const e = /* @__PURE__ */ new Set();
|
|
148
|
-
let
|
|
148
|
+
let u = !1;
|
|
149
149
|
for (const a of s.values)
|
|
150
|
-
a.kind === p.ENUM && (a.value.startsWith("CREATED") && !a.value.includes("RELATIONSHIP") ? e.add("CREATE") : a.value.startsWith("UPDATED") ? e.add("UPDATE") : a.value.startsWith("DELETED") && !a.value.includes("RELATIONSHIP") ? e.add("DELETE") : a.value.includes("RELATIONSHIP") && (
|
|
150
|
+
a.kind === p.ENUM && (a.value.startsWith("CREATED") && !a.value.includes("RELATIONSHIP") ? e.add("CREATE") : a.value.startsWith("UPDATED") ? e.add("UPDATE") : a.value.startsWith("DELETED") && !a.value.includes("RELATIONSHIP") ? e.add("DELETE") : a.value.includes("RELATIONSHIP") && (u = !0));
|
|
151
151
|
return o.push(
|
|
152
152
|
`${n}: subscriptions see writes made through this library (or the engine change feed), not CDC`
|
|
153
153
|
), I("subscription", {
|
|
154
154
|
operations: R([...e].sort()),
|
|
155
|
-
...
|
|
155
|
+
...u ? { relationships: ee(!0) } : {}
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
|
-
function
|
|
158
|
+
function De(t, n) {
|
|
159
159
|
const o = {
|
|
160
160
|
filters: /* @__PURE__ */ new Map(),
|
|
161
161
|
sorts: /* @__PURE__ */ new Map(),
|
|
162
162
|
mutations: /* @__PURE__ */ new Map()
|
|
163
163
|
}, s = /* @__PURE__ */ new Map();
|
|
164
164
|
for (const r of n)
|
|
165
|
-
s.set(
|
|
166
|
-
const e = new Map(n.map((r) => [r.name.value, r])),
|
|
165
|
+
s.set(V(r.name.value), r), s.set(Ae(r.name.value), r);
|
|
166
|
+
const e = new Map(n.map((r) => [r.name.value, r])), u = (r, l, d) => {
|
|
167
167
|
const m = o.filters.get(r) ?? /* @__PURE__ */ new Map(), h = m.get(l) ?? /* @__PURE__ */ new Set();
|
|
168
|
-
h.add(
|
|
168
|
+
h.add(d), m.set(l, h), o.filters.set(r, m);
|
|
169
169
|
}, a = (r, l) => {
|
|
170
170
|
if (l.kind === p.OBJECT)
|
|
171
|
-
for (const
|
|
172
|
-
const m =
|
|
171
|
+
for (const d of l.fields) {
|
|
172
|
+
const m = d.name.value;
|
|
173
173
|
if (m === "AND" || m === "OR") {
|
|
174
|
-
if (
|
|
175
|
-
for (const w of
|
|
174
|
+
if (d.value.kind === p.LIST)
|
|
175
|
+
for (const w of d.value.values) a(r, w);
|
|
176
176
|
continue;
|
|
177
177
|
}
|
|
178
178
|
if (m === "NOT") {
|
|
179
|
-
a(r,
|
|
179
|
+
a(r, d.value);
|
|
180
180
|
continue;
|
|
181
181
|
}
|
|
182
182
|
const h = /^(.+)_(SOME|ALL|NONE|SINGLE)$/.exec(m);
|
|
183
183
|
if (h) {
|
|
184
|
-
const w = r.fields?.find((
|
|
185
|
-
w &&
|
|
184
|
+
const w = r.fields?.find((D) => D.name.value === h[1]), S = w && e.get(B(w));
|
|
185
|
+
w && S && (u(r.name.value, h[1], "EQ"), a(S, d.value));
|
|
186
186
|
continue;
|
|
187
187
|
}
|
|
188
|
-
const v =
|
|
189
|
-
if (!
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
if (
|
|
193
|
-
for (const w of
|
|
194
|
-
a(
|
|
188
|
+
const v = Ne.find(([w]) => m.endsWith(w)), T = v ? m.slice(0, -v[0].length) : m, g = r.fields?.find((w) => w.name.value === T);
|
|
189
|
+
if (!g) continue;
|
|
190
|
+
const N = e.get(B(g));
|
|
191
|
+
if (N) {
|
|
192
|
+
if (u(r.name.value, T, "EQ"), d.value.kind === p.OBJECT) {
|
|
193
|
+
for (const w of d.value.fields) a(N, w.value);
|
|
194
|
+
a(N, d.value);
|
|
195
195
|
}
|
|
196
196
|
continue;
|
|
197
197
|
}
|
|
198
|
-
if (v)
|
|
199
|
-
else if (
|
|
200
|
-
for (const w of
|
|
201
|
-
const
|
|
202
|
-
|
|
198
|
+
if (v) u(r.name.value, T, v[1]);
|
|
199
|
+
else if (d.value.kind === p.OBJECT)
|
|
200
|
+
for (const w of d.value.fields) {
|
|
201
|
+
const S = Se[w.name.value];
|
|
202
|
+
S && u(r.name.value, T, S);
|
|
203
203
|
}
|
|
204
|
-
else
|
|
204
|
+
else u(r.name.value, T, "EQ");
|
|
205
205
|
}
|
|
206
|
-
},
|
|
207
|
-
for (const
|
|
208
|
-
if (
|
|
209
|
-
const m =
|
|
206
|
+
}, c = (r, l) => {
|
|
207
|
+
for (const d of r?.selections ?? []) {
|
|
208
|
+
if (d.kind !== p.FIELD) continue;
|
|
209
|
+
const m = d.name.value;
|
|
210
210
|
if (l) {
|
|
211
|
-
const h = /^(create|update|delete|upsert)(.+)$/.exec(m), v = m.replace(/(Connection|Aggregate)$/, ""),
|
|
212
|
-
if (
|
|
213
|
-
const
|
|
214
|
-
|
|
211
|
+
const h = /^(create|update|delete|upsert)(.+)$/.exec(m), v = m.replace(/(Connection|Aggregate)$/, ""), T = s.get(v) ?? (h ? s.get(te(h[2])) : void 0);
|
|
212
|
+
if (T && h) {
|
|
213
|
+
const g = o.mutations.get(T.name.value) ?? /* @__PURE__ */ new Set(), N = h[1].toUpperCase();
|
|
214
|
+
N === "UPSERT" ? (g.add("CREATE"), g.add("UPDATE")) : g.add(N), o.mutations.set(T.name.value, g);
|
|
215
215
|
}
|
|
216
|
-
if (
|
|
217
|
-
for (const
|
|
216
|
+
if (T)
|
|
217
|
+
for (const g of d.arguments ?? []) i(T, g);
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
c(d.selectionSet, !1);
|
|
220
220
|
}
|
|
221
221
|
}, i = (r, l) => {
|
|
222
222
|
if (l.name.value === "where" && a(r, l.value), l.name.value === "sort" || l.name.value === "options") {
|
|
223
|
-
const
|
|
223
|
+
const d = o.sorts.get(r.name.value) ?? /* @__PURE__ */ new Set(), m = (h) => {
|
|
224
224
|
if (h.kind === p.LIST) h.values.forEach(m);
|
|
225
225
|
else if (h.kind === p.OBJECT)
|
|
226
226
|
for (const v of h.fields)
|
|
227
|
-
v.name.value === "sort" ? m(v.value) : v.value.kind === p.ENUM &&
|
|
227
|
+
v.name.value === "sort" ? m(v.value) : v.value.kind === p.ENUM && d.add(v.name.value);
|
|
228
228
|
};
|
|
229
|
-
m(l.value), o.sorts.set(r.name.value,
|
|
229
|
+
m(l.value), o.sorts.set(r.name.value, d);
|
|
230
230
|
}
|
|
231
231
|
};
|
|
232
232
|
for (const r of t)
|
|
233
233
|
for (const l of r.definitions)
|
|
234
|
-
l.kind === p.OPERATION_DEFINITION &&
|
|
234
|
+
l.kind === p.OPERATION_DEFINITION && c(l.selectionSet, !0);
|
|
235
235
|
return o;
|
|
236
236
|
}
|
|
237
|
-
function
|
|
237
|
+
function B(t) {
|
|
238
238
|
let n = t.type;
|
|
239
239
|
for (; n.kind !== p.NAMED_TYPE; ) n = n.type;
|
|
240
240
|
return n.name.value;
|
|
241
241
|
}
|
|
242
|
-
function
|
|
242
|
+
function O(t, n) {
|
|
243
243
|
return (t ?? []).some((o) => o.name.value === n);
|
|
244
244
|
}
|
|
245
245
|
function I(t, n = {}) {
|
|
246
246
|
return {
|
|
247
247
|
kind: p.DIRECTIVE,
|
|
248
248
|
name: { kind: p.NAME, value: t },
|
|
249
|
-
arguments: Object.entries(n).map(([o, s]) =>
|
|
249
|
+
arguments: Object.entries(n).map(([o, s]) => A(o, s))
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
function
|
|
252
|
+
function A(t, n) {
|
|
253
253
|
return { kind: p.ARGUMENT, name: { kind: p.NAME, value: t }, value: n };
|
|
254
254
|
}
|
|
255
|
-
const
|
|
255
|
+
const X = (t) => ({
|
|
256
256
|
kind: p.ENUM,
|
|
257
257
|
value: t
|
|
258
|
-
}),
|
|
258
|
+
}), ee = (t) => ({
|
|
259
259
|
kind: p.BOOLEAN,
|
|
260
260
|
value: t
|
|
261
261
|
}), R = (t) => ({
|
|
262
262
|
kind: p.LIST,
|
|
263
|
-
values: t.map(
|
|
263
|
+
values: t.map(X)
|
|
264
264
|
});
|
|
265
|
-
function
|
|
265
|
+
function $e(t, n, o, s) {
|
|
266
266
|
return {
|
|
267
267
|
...t,
|
|
268
268
|
arguments: (t.arguments ?? []).map(
|
|
269
|
-
(e) => e.name.value === n && e.value.kind === p.LIST ?
|
|
269
|
+
(e) => e.name.value === n && e.value.kind === p.LIST ? A(n, {
|
|
270
270
|
kind: p.LIST,
|
|
271
271
|
values: e.value.values.map(
|
|
272
|
-
(
|
|
273
|
-
...
|
|
274
|
-
fields:
|
|
272
|
+
(u) => u.kind === p.OBJECT ? {
|
|
273
|
+
...u,
|
|
274
|
+
fields: u.fields.map(
|
|
275
275
|
(a) => a.name.value === o ? { ...a, name: { kind: p.NAME, value: s } } : a
|
|
276
276
|
)
|
|
277
|
-
} :
|
|
277
|
+
} : u
|
|
278
278
|
)
|
|
279
279
|
}) : e
|
|
280
280
|
)
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
|
-
const
|
|
283
|
+
const Le = {
|
|
284
284
|
person: "people",
|
|
285
285
|
man: "men",
|
|
286
286
|
woman: "women",
|
|
@@ -290,23 +290,24 @@ const Oe = {
|
|
|
290
290
|
foot: "feet",
|
|
291
291
|
tooth: "teeth"
|
|
292
292
|
};
|
|
293
|
-
function
|
|
294
|
-
const n =
|
|
295
|
-
for (const [s, e] of Object.entries(
|
|
293
|
+
function Ae(t) {
|
|
294
|
+
const n = te(t), o = n.toLowerCase();
|
|
295
|
+
for (const [s, e] of Object.entries(Le))
|
|
296
296
|
if (o.endsWith(s))
|
|
297
297
|
return n.slice(0, n.length - s.length) + e;
|
|
298
|
-
return
|
|
298
|
+
return V(t);
|
|
299
299
|
}
|
|
300
|
-
function
|
|
300
|
+
function te(t) {
|
|
301
301
|
return t.charAt(0).toLowerCase() + t.slice(1);
|
|
302
302
|
}
|
|
303
|
-
const
|
|
303
|
+
const G = `lora-graphql <command>
|
|
304
304
|
|
|
305
305
|
print <schema.graphql> the public SDL clients see
|
|
306
306
|
directives the directive definitions, for editors
|
|
307
307
|
requirements <schema.graphql> [--ddl] constraints and indexes the API needs
|
|
308
308
|
check <schema.graphql> [--operations <file|dir>]... [--json]
|
|
309
|
-
[--variables <file>] [--
|
|
309
|
+
[--variables <file>] [--context <file>]
|
|
310
|
+
[--baseline <file> [--update-baseline]]
|
|
310
311
|
[--row-budget <n>] [--database <dir> [--name <db>]]
|
|
311
312
|
CI gate: model, lint, @cypher statements and
|
|
312
313
|
the plans of your operations, on an in-memory
|
|
@@ -321,54 +322,55 @@ const W = `lora-graphql <command>
|
|
|
321
322
|
what has no equivalent
|
|
322
323
|
diff <old.graphql> <new.graphql> [--allow-breaking] [--json]
|
|
323
324
|
database statements and API changes`;
|
|
324
|
-
async function
|
|
325
|
-
const [o, ...s] = t, e = /* @__PURE__ */ new Set(),
|
|
325
|
+
async function qe(t, n = We) {
|
|
326
|
+
const [o, ...s] = t, e = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Map(), a = [], c = [];
|
|
326
327
|
for (let i = 0; i < s.length; i++) {
|
|
327
328
|
const r = s[i];
|
|
328
|
-
r === "--operations" ?
|
|
329
|
+
r === "--operations" ? c.push(s[++i] ?? "") : Ce.has(r) ? u.set(r, s[++i] ?? "") : r.startsWith("--") ? e.add(r) : a.push(r);
|
|
329
330
|
}
|
|
330
331
|
try {
|
|
331
332
|
switch (o) {
|
|
332
333
|
case "print":
|
|
333
|
-
return await
|
|
334
|
+
return await _e(k(a, 1), n);
|
|
334
335
|
case "directives":
|
|
335
|
-
return n.out(
|
|
336
|
+
return n.out(he.trim()), 0;
|
|
336
337
|
case "requirements":
|
|
337
|
-
return await
|
|
338
|
+
return await je(k(a, 1), e.has("--ddl"), n);
|
|
338
339
|
case "check":
|
|
339
|
-
return await
|
|
340
|
+
return await Me(k(a, 1), c, e, u, n);
|
|
340
341
|
case "compile":
|
|
341
|
-
return await
|
|
342
|
+
return await xe(k(a, 1), c, u, n);
|
|
342
343
|
case "analyze":
|
|
343
|
-
return await
|
|
344
|
+
return await Pe(k(a, 1), u, n);
|
|
344
345
|
case "migrate": {
|
|
345
346
|
const [i, r] = k(a, 2);
|
|
346
|
-
if (i !== "neo4j") throw new
|
|
347
|
+
if (i !== "neo4j") throw new L("migrate supports neo4j");
|
|
347
348
|
const l = [];
|
|
348
|
-
for (const m of
|
|
349
|
-
for (const h of await
|
|
350
|
-
const
|
|
351
|
-
for (const m of
|
|
352
|
-
return
|
|
349
|
+
for (const m of c)
|
|
350
|
+
for (const h of await C(m)) l.push(q(h.source));
|
|
351
|
+
const d = Ie(await E(r), l);
|
|
352
|
+
for (const m of d.todos) n.out(`# TODO(migrate): ${m}`);
|
|
353
|
+
return d.todos.length > 0 && n.out(""), n.out(d.typeDefs), 0;
|
|
353
354
|
}
|
|
354
355
|
case "diff": {
|
|
355
356
|
const [i, r] = k(a, 2);
|
|
356
|
-
return await
|
|
357
|
+
return await Je(i, r, e, n);
|
|
357
358
|
}
|
|
358
359
|
default:
|
|
359
|
-
return n.err(
|
|
360
|
+
return n.err(G), 2;
|
|
360
361
|
}
|
|
361
362
|
} catch (i) {
|
|
362
|
-
return i instanceof
|
|
363
|
+
return i instanceof L ? (n.err(`${i.message}
|
|
363
364
|
|
|
364
|
-
${
|
|
365
|
+
${G}`), 2) : i instanceof ge ? (n.err(i.message), 1) : (n.err(i instanceof Error ? i.message : String(i)), 1);
|
|
365
366
|
}
|
|
366
367
|
}
|
|
367
|
-
class
|
|
368
|
+
class L extends Error {
|
|
368
369
|
}
|
|
369
|
-
const
|
|
370
|
+
const Ce = /* @__PURE__ */ new Set([
|
|
370
371
|
"--out",
|
|
371
372
|
"--variables",
|
|
373
|
+
"--context",
|
|
372
374
|
"--baseline",
|
|
373
375
|
"--row-budget",
|
|
374
376
|
"--database",
|
|
@@ -377,28 +379,28 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
377
379
|
]);
|
|
378
380
|
function k(t, n) {
|
|
379
381
|
if (t.length < n)
|
|
380
|
-
throw new
|
|
382
|
+
throw new L(`expected ${n} file argument(s)`);
|
|
381
383
|
return t;
|
|
382
384
|
}
|
|
383
|
-
const E = (t) =>
|
|
384
|
-
function
|
|
385
|
+
const E = (t) => ie(t, "utf8");
|
|
386
|
+
function ne(t) {
|
|
385
387
|
const n = {
|
|
386
388
|
run: () => Promise.reject(new Error("no database"))
|
|
387
389
|
};
|
|
388
390
|
return new M({ typeDefs: t, driver: n });
|
|
389
391
|
}
|
|
390
|
-
async function
|
|
391
|
-
return n.out(
|
|
392
|
+
async function _e([t], n) {
|
|
393
|
+
return n.out(ne(await E(t)).printPublicSchema()), 0;
|
|
392
394
|
}
|
|
393
|
-
async function
|
|
394
|
-
const s =
|
|
395
|
-
for (const e of
|
|
395
|
+
async function je([t], n, o) {
|
|
396
|
+
const s = ve(await E(t));
|
|
397
|
+
for (const e of we(s))
|
|
396
398
|
o.out(
|
|
397
|
-
n ? `${
|
|
399
|
+
n ? `${Te(e)};` : `${Z(e)}, because ${e.reason}`
|
|
398
400
|
);
|
|
399
401
|
return 0;
|
|
400
402
|
}
|
|
401
|
-
async function
|
|
403
|
+
async function se(t, n) {
|
|
402
404
|
try {
|
|
403
405
|
const { createDatabase: o } = await import("@loradb/lora-node");
|
|
404
406
|
return o;
|
|
@@ -409,175 +411,182 @@ async function te(t, n) {
|
|
|
409
411
|
return;
|
|
410
412
|
}
|
|
411
413
|
}
|
|
412
|
-
async function
|
|
413
|
-
const
|
|
414
|
-
if (!
|
|
415
|
-
const i = s.get("--database"), r = await
|
|
414
|
+
async function Me([t], n, o, s, e) {
|
|
415
|
+
const u = o.has("--json"), a = await E(t), c = await se(e, "check");
|
|
416
|
+
if (!c) return 1;
|
|
417
|
+
const i = s.get("--database"), r = await c(
|
|
416
418
|
i ? s.get("--name") ?? "app" : void 0,
|
|
417
419
|
i ? { databaseDir: i } : {}
|
|
418
420
|
), l = new M({
|
|
419
421
|
typeDefs: a,
|
|
420
|
-
driver:
|
|
422
|
+
driver: Y(r)
|
|
421
423
|
});
|
|
422
424
|
i || await l.assertSchema({ create: !0 });
|
|
423
|
-
const
|
|
424
|
-
for (const
|
|
425
|
-
for (const
|
|
426
|
-
for (const
|
|
427
|
-
const P = m[
|
|
428
|
-
|
|
425
|
+
const d = l.getSchema(), m = s.has("--variables") ? JSON.parse(await E(s.get("--variables"))) : {}, h = s.has("--context") ? JSON.parse(await E(s.get("--context"))) : {}, v = [];
|
|
426
|
+
for (const f of n)
|
|
427
|
+
for (const b of await C(f))
|
|
428
|
+
for (const y of Ue(d, b.path, b.source)) {
|
|
429
|
+
const x = y.name.split("#")[1] ?? "", P = m[y.name] ?? m[x], U = h[y.name] ?? h[x] ?? h["*"];
|
|
430
|
+
v.push({
|
|
431
|
+
...y,
|
|
432
|
+
...P ? { variables: P } : {},
|
|
433
|
+
...U !== void 0 ? { context: U } : {}
|
|
434
|
+
});
|
|
429
435
|
}
|
|
430
|
-
const
|
|
431
|
-
operations:
|
|
432
|
-
...
|
|
433
|
-
}),
|
|
434
|
-
for (const
|
|
435
|
-
|
|
436
|
-
const
|
|
437
|
-
if (
|
|
438
|
-
let
|
|
436
|
+
const T = s.has("--row-budget") ? Number(s.get("--row-budget")) : void 0, g = await l.check({
|
|
437
|
+
operations: v,
|
|
438
|
+
...T !== void 0 ? { rowBudget: T } : {}
|
|
439
|
+
}), N = s.get("--baseline"), w = {};
|
|
440
|
+
for (const f of g.plans)
|
|
441
|
+
w[`${f.operation} › ${f.field}`] = f.reports.map((b) => b.operators);
|
|
442
|
+
const S = [];
|
|
443
|
+
if (N) {
|
|
444
|
+
let f;
|
|
439
445
|
try {
|
|
440
|
-
|
|
446
|
+
f = JSON.parse(await E(N));
|
|
441
447
|
} catch {
|
|
442
|
-
|
|
448
|
+
f = void 0;
|
|
443
449
|
}
|
|
444
|
-
if (o.has("--update-baseline") || !
|
|
445
|
-
await _(
|
|
450
|
+
if (o.has("--update-baseline") || !f)
|
|
451
|
+
await _(N, JSON.stringify(w, null, 2) + `
|
|
446
452
|
`);
|
|
447
453
|
else
|
|
448
|
-
for (const
|
|
449
|
-
...Object.keys(
|
|
450
|
-
...Object.keys(
|
|
454
|
+
for (const b of /* @__PURE__ */ new Set([
|
|
455
|
+
...Object.keys(f),
|
|
456
|
+
...Object.keys(w)
|
|
451
457
|
]))
|
|
452
|
-
JSON.stringify(
|
|
458
|
+
JSON.stringify(f[b]) !== JSON.stringify(w[b]) && S.push(b);
|
|
453
459
|
}
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
456
|
-
return e.out(JSON.stringify({ ...g, ok:
|
|
457
|
-
for (const
|
|
458
|
-
for (const
|
|
459
|
-
for (const
|
|
460
|
+
const D = g.ok && S.length === 0;
|
|
461
|
+
if (u)
|
|
462
|
+
return e.out(JSON.stringify({ ...g, ok: D, planChanges: S }, null, 2)), D ? 0 : 1;
|
|
463
|
+
for (const f of g.warnings) e.out(`warning ${J(f)}`);
|
|
464
|
+
for (const f of g.lint) e.out(`lint ${J(f)}`);
|
|
465
|
+
for (const f of g.unused)
|
|
460
466
|
e.out(
|
|
461
|
-
`unused ${
|
|
467
|
+
`unused ${f.type} index ${f.name} on :${f.labels.join(":")}(${f.properties.join(", ")})`
|
|
462
468
|
);
|
|
463
|
-
for (const
|
|
464
|
-
e.out(`error missing ${
|
|
465
|
-
for (const
|
|
466
|
-
e.out(`error ${
|
|
467
|
-
for (const
|
|
468
|
-
e.out(`error ${
|
|
469
|
-
for (const
|
|
470
|
-
for (const
|
|
471
|
-
for (const
|
|
472
|
-
e.out(`error ${
|
|
473
|
-
|
|
469
|
+
for (const f of g.missing)
|
|
470
|
+
e.out(`error missing ${Z(f)}`);
|
|
471
|
+
for (const f of g.cypher)
|
|
472
|
+
e.out(`error ${f.type}.${f.field}: ${f.message}`);
|
|
473
|
+
for (const f of g.errors)
|
|
474
|
+
e.out(`error ${f.operation}: ${f.message}`);
|
|
475
|
+
for (const f of g.plans)
|
|
476
|
+
for (const b of f.reports) {
|
|
477
|
+
for (const y of b.findings)
|
|
478
|
+
e.out(`error ${f.operation} › ${f.field}: ${y.message}`);
|
|
479
|
+
for (const y of b.notes)
|
|
480
|
+
e.out(`lint ${f.operation} › ${f.field}: ${y.message}`);
|
|
481
|
+
}
|
|
482
|
+
for (const f of S)
|
|
474
483
|
e.out(
|
|
475
|
-
`error ${
|
|
484
|
+
`error ${f}: the plan differs from the baseline (--update-baseline to accept)`
|
|
476
485
|
);
|
|
477
|
-
const
|
|
486
|
+
const ae = g.plans.length;
|
|
478
487
|
return e.out(
|
|
479
|
-
|
|
480
|
-
),
|
|
488
|
+
D ? `ok ${ae} root field(s) in ${v.length} operation(s) seek as expected` : "failed"
|
|
489
|
+
), D ? 0 : 1;
|
|
481
490
|
}
|
|
482
|
-
async function
|
|
491
|
+
async function Re(t) {
|
|
483
492
|
const n = {};
|
|
484
493
|
for (const o of t) {
|
|
485
|
-
if ((await
|
|
494
|
+
if ((await z(o)).isFile() && o.endsWith(".json")) {
|
|
486
495
|
Object.assign(
|
|
487
496
|
n,
|
|
488
497
|
JSON.parse(await E(o))
|
|
489
498
|
);
|
|
490
499
|
continue;
|
|
491
500
|
}
|
|
492
|
-
for (const e of await
|
|
493
|
-
const
|
|
494
|
-
|
|
501
|
+
for (const e of await C(o)) {
|
|
502
|
+
const u = q(e.source), a = new Map(
|
|
503
|
+
u.definitions.filter(
|
|
495
504
|
(i) => i.kind === p.FRAGMENT_DEFINITION
|
|
496
505
|
).map((i) => [i.name.value, i])
|
|
497
|
-
),
|
|
498
|
-
|
|
506
|
+
), c = ce(process.cwd(), e.path);
|
|
507
|
+
u.definitions.filter(
|
|
499
508
|
(i) => i.kind === p.OPERATION_DEFINITION
|
|
500
509
|
).forEach((i, r) => {
|
|
501
|
-
const l = `${
|
|
502
|
-
n[l] =
|
|
510
|
+
const l = `${c}#${i.name?.value ?? r + 1}`;
|
|
511
|
+
n[l] = Q({
|
|
503
512
|
kind: p.DOCUMENT,
|
|
504
|
-
definitions: [i, ...
|
|
513
|
+
definitions: [i, ...Ee(i, a)]
|
|
505
514
|
});
|
|
506
515
|
});
|
|
507
516
|
}
|
|
508
517
|
}
|
|
509
518
|
return n;
|
|
510
519
|
}
|
|
511
|
-
async function
|
|
520
|
+
async function xe([t], n, o, s) {
|
|
512
521
|
if (n.length === 0)
|
|
513
|
-
throw new
|
|
514
|
-
const e =
|
|
515
|
-
await
|
|
522
|
+
throw new L("compile needs --operations <file|dir>");
|
|
523
|
+
const e = ne(await E(t)), u = e.buildManifest(
|
|
524
|
+
await Re(n)
|
|
516
525
|
), a = o.get("--out") ?? "lora-graphql";
|
|
517
|
-
return await
|
|
518
|
-
|
|
519
|
-
JSON.stringify(
|
|
526
|
+
return await re(a, { recursive: !0 }), await _(
|
|
527
|
+
$(a, "manifest.json"),
|
|
528
|
+
JSON.stringify(u) + `
|
|
520
529
|
`
|
|
521
530
|
), await _(
|
|
522
|
-
|
|
523
|
-
e.generateTypes(
|
|
531
|
+
$(a, "operations.d.ts"),
|
|
532
|
+
e.generateTypes(u)
|
|
524
533
|
), s.out(
|
|
525
|
-
`wrote ${Object.keys(
|
|
534
|
+
`wrote ${Object.keys(u.operations).length} operation(s) to ${$(a, "manifest.json")} and ${$(a, "operations.d.ts")}`
|
|
526
535
|
), 0;
|
|
527
536
|
}
|
|
528
|
-
async function
|
|
537
|
+
async function Pe([t], n, o) {
|
|
529
538
|
const s = n.get("--database");
|
|
530
|
-
if (!s) throw new
|
|
531
|
-
const e = await
|
|
539
|
+
if (!s) throw new L("analyze needs --database <dir>");
|
|
540
|
+
const e = await se(o, "analyze");
|
|
532
541
|
if (!e) return 1;
|
|
533
|
-
const
|
|
542
|
+
const u = await e(n.get("--name") ?? "app", {
|
|
534
543
|
databaseDir: s
|
|
535
544
|
}), a = new M({
|
|
536
545
|
typeDefs: await E(t),
|
|
537
|
-
driver:
|
|
538
|
-
}),
|
|
539
|
-
return o.out(JSON.stringify(i, null, 2)),
|
|
546
|
+
driver: Y(u)
|
|
547
|
+
}), c = n.has("--sample") ? Number(n.get("--sample")) : void 0, i = await a.analyze(c !== void 0 ? { sample: c } : {});
|
|
548
|
+
return o.out(JSON.stringify(i, null, 2)), u.dispose?.(), 0;
|
|
540
549
|
}
|
|
541
|
-
async function
|
|
542
|
-
if ((await
|
|
550
|
+
async function C(t) {
|
|
551
|
+
if ((await z(t)).isFile()) return [{ path: t, source: await E(t) }];
|
|
543
552
|
const o = [];
|
|
544
|
-
for (const s of await
|
|
545
|
-
const e =
|
|
546
|
-
s.isDirectory() ? o.push(...await
|
|
553
|
+
for (const s of await oe(t, { withFileTypes: !0 })) {
|
|
554
|
+
const e = $(t, s.name);
|
|
555
|
+
s.isDirectory() ? o.push(...await C(e)) : /\.(graphql|gql)$/.test(s.name) && o.push({ path: e, source: await E(e) });
|
|
547
556
|
}
|
|
548
557
|
return o;
|
|
549
558
|
}
|
|
550
|
-
function
|
|
551
|
-
const s =
|
|
559
|
+
function Ue(t, n, o) {
|
|
560
|
+
const s = q(o), e = new Map(
|
|
552
561
|
s.definitions.filter(
|
|
553
562
|
(a) => a.kind === p.FRAGMENT_DEFINITION
|
|
554
563
|
).map((a) => [a.name.value, a])
|
|
555
|
-
),
|
|
556
|
-
const
|
|
564
|
+
), u = (a) => {
|
|
565
|
+
const c = /* @__PURE__ */ new Map(), i = (r) => H(r, {
|
|
557
566
|
FragmentSpread(l) {
|
|
558
|
-
const
|
|
559
|
-
|
|
567
|
+
const d = e.get(l.name.value);
|
|
568
|
+
d && !c.has(d.name.value) && (c.set(d.name.value, d), i(d));
|
|
560
569
|
}
|
|
561
570
|
});
|
|
562
|
-
return i(a), [...
|
|
571
|
+
return i(a), [...c.values()];
|
|
563
572
|
};
|
|
564
573
|
return s.definitions.filter(
|
|
565
574
|
(a) => a.kind === p.OPERATION_DEFINITION && a.operation === "query"
|
|
566
|
-
).map((a,
|
|
575
|
+
).map((a, c) => {
|
|
567
576
|
const i = {};
|
|
568
577
|
for (const r of a.variableDefinitions ?? []) {
|
|
569
578
|
if (r.defaultValue || r.type.kind !== p.NON_NULL_TYPE) continue;
|
|
570
|
-
const l =
|
|
579
|
+
const l = ue(t, r.type);
|
|
571
580
|
l && (i[r.variable.name.value] = j(l));
|
|
572
581
|
}
|
|
573
582
|
return {
|
|
574
|
-
name: `${n}${a.name ? `#${a.name.value}` : `#${
|
|
575
|
-
document: { kind: p.DOCUMENT, definitions: [a, ...
|
|
583
|
+
name: `${n}${a.name ? `#${a.name.value}` : `#${c + 1}`}`,
|
|
584
|
+
document: { kind: p.DOCUMENT, definitions: [a, ...u(a)] },
|
|
576
585
|
variables: i
|
|
577
586
|
};
|
|
578
587
|
});
|
|
579
588
|
}
|
|
580
|
-
const
|
|
589
|
+
const Fe = {
|
|
581
590
|
String: "x",
|
|
582
591
|
ID: "x",
|
|
583
592
|
Int: 1,
|
|
@@ -592,40 +601,40 @@ const Pe = {
|
|
|
592
601
|
Duration: "P1D"
|
|
593
602
|
};
|
|
594
603
|
function j(t) {
|
|
595
|
-
const n =
|
|
596
|
-
if (
|
|
597
|
-
const o =
|
|
598
|
-
if (
|
|
599
|
-
if (
|
|
604
|
+
const n = F(t) ? t.ofType : t;
|
|
605
|
+
if (le(n)) return [j(n.ofType)];
|
|
606
|
+
const o = fe(n);
|
|
607
|
+
if (de(o)) return o.getValues()[0]?.value;
|
|
608
|
+
if (pe(o)) {
|
|
600
609
|
const s = {};
|
|
601
610
|
for (const e of Object.values(o.getFields()))
|
|
602
|
-
|
|
611
|
+
F(e.type) && e.defaultValue === void 0 && (s[e.name] = j(e.type));
|
|
603
612
|
return s;
|
|
604
613
|
}
|
|
605
|
-
return
|
|
614
|
+
return Fe[o.name] ?? "x";
|
|
606
615
|
}
|
|
607
|
-
async function
|
|
608
|
-
const e =
|
|
616
|
+
async function Je(t, n, o, s) {
|
|
617
|
+
const e = me(await E(t), await E(n)), u = e.api.breaking.length > 0, a = u && !o.has("--allow-breaking") ? 1 : 0;
|
|
609
618
|
if (o.has("--json"))
|
|
610
619
|
return s.out(JSON.stringify(e, null, 2)), a;
|
|
611
620
|
s.out("# Database"), e.database.statements.length === 0 && s.out("no changes");
|
|
612
|
-
for (const
|
|
613
|
-
s.out(`${
|
|
621
|
+
for (const c of e.database.statements)
|
|
622
|
+
s.out(`${c.destructive ? "// destructive: " : "// "}${c.reason}`), s.out(`${c.text};`);
|
|
614
623
|
s.out(`
|
|
615
|
-
# API`), !
|
|
616
|
-
for (const
|
|
617
|
-
for (const
|
|
618
|
-
for (const
|
|
624
|
+
# API`), !u && e.api.dangerous.length === 0 && s.out("no changes");
|
|
625
|
+
for (const c of e.api.breaking) s.out(`breaking ${c.description}`);
|
|
626
|
+
for (const c of e.api.dangerous) s.out(`dangerous ${c.description}`);
|
|
627
|
+
for (const c of e.notes) s.out(`note ${c}`);
|
|
619
628
|
return a;
|
|
620
629
|
}
|
|
621
|
-
const
|
|
630
|
+
const We = {
|
|
622
631
|
out: (t) => process.stdout.write(t + `
|
|
623
632
|
`),
|
|
624
633
|
err: (t) => process.stderr.write(t + `
|
|
625
634
|
`)
|
|
626
|
-
},
|
|
627
|
-
|
|
635
|
+
}, Be = typeof process < "u" && process.argv[1] !== void 0 && /lora-graphql(\.js)?$|cli\.js$/.test(process.argv[1]);
|
|
636
|
+
Be && qe(process.argv.slice(2)).then((t) => process.exit(t));
|
|
628
637
|
export {
|
|
629
|
-
|
|
638
|
+
qe as main
|
|
630
639
|
};
|
|
631
640
|
//# sourceMappingURL=cli.js.map
|