introspectron 0.2.12 → 2.0.2
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/LICENSE +1 -1
- package/README.md +12 -0
- package/esm/gql.js +297 -0
- package/esm/index.js +6 -0
- package/esm/introspect.js +85 -0
- package/{module → esm}/introspectGql.js +2 -2
- package/esm/process.js +278 -0
- package/{module → esm}/query.js +16 -12
- package/esm/utils.js +42 -0
- package/gql.d.ts +4 -0
- package/gql.js +301 -0
- package/{module/index.js → index.d.ts} +1 -1
- package/index.js +22 -0
- package/introspect.d.ts +16 -0
- package/introspect.js +89 -0
- package/introspectGql.d.ts +1 -0
- package/introspectGql.js +105 -0
- package/package.json +19 -54
- package/process.d.ts +1 -0
- package/process.js +282 -0
- package/query.d.ts +1 -0
- package/query.js +425 -0
- package/utils.d.ts +2 -0
- package/utils.js +47 -0
- package/CHANGELOG.md +0 -167
- package/main/gql.js +0 -388
- package/main/index.js +0 -70
- package/main/introspect.js +0 -162
- package/main/introspectGql.js +0 -17
- package/main/process.js +0 -410
- package/main/query.js +0 -26
- package/main/utils.js +0 -64
- package/module/gql.js +0 -342
- package/module/introspect.js +0 -75
- package/module/process.js +0 -321
- package/module/utils.js +0 -46
package/module/gql.js
DELETED
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
-
|
|
3
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
4
|
-
|
|
5
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
6
|
-
|
|
7
|
-
export const parseGraphQuery = introQuery => {
|
|
8
|
-
const types = introQuery.__schema.types;
|
|
9
|
-
const HASH = types.reduce((m, v) => {
|
|
10
|
-
m[v.name] = v;
|
|
11
|
-
return m;
|
|
12
|
-
}, {});
|
|
13
|
-
const queriesRoot = types.find(t => t.name === 'Query');
|
|
14
|
-
const mutationsRoot = types.find(t => t.name === 'Mutation');
|
|
15
|
-
|
|
16
|
-
const getInputForQueries = (input, context = {}) => {
|
|
17
|
-
if (input.kind === 'NON_NULL') {
|
|
18
|
-
context.isNotNull = true;
|
|
19
|
-
return getInputForQueries(input.ofType, context);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (input.kind === 'LIST') {
|
|
23
|
-
context.isArray = true;
|
|
24
|
-
|
|
25
|
-
if (context.isNotNull) {
|
|
26
|
-
context.isArrayNotNull = true;
|
|
27
|
-
delete context.isNotNull;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return getInputForQueries(input.ofType, context);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (input.kind === 'INPUT_OBJECT') {
|
|
34
|
-
if (input.name && HASH.hasOwnProperty(input.name)) {
|
|
35
|
-
const schema = HASH[input.name];
|
|
36
|
-
context.properties = schema.inputFields.map(field => {
|
|
37
|
-
return {
|
|
38
|
-
name: field.name,
|
|
39
|
-
type: field.type
|
|
40
|
-
};
|
|
41
|
-
}).reduce((m3, v) => {
|
|
42
|
-
m3[v.name] = v;
|
|
43
|
-
return m3;
|
|
44
|
-
}, {});
|
|
45
|
-
}
|
|
46
|
-
} else if (input.kind === 'OBJECT') {
|
|
47
|
-
if (input.name && HASH.hasOwnProperty(input.name)) {
|
|
48
|
-
const schema = HASH[input.name];
|
|
49
|
-
context.properties = schema.fields.map(field => {
|
|
50
|
-
return {
|
|
51
|
-
name: field.name,
|
|
52
|
-
type: field.type
|
|
53
|
-
};
|
|
54
|
-
}).reduce((m3, v) => {
|
|
55
|
-
m3[v.name] = v;
|
|
56
|
-
return m3;
|
|
57
|
-
}, {});
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
context.type = input.name;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return context;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const getInputForMutations = (input, context = {}) => {
|
|
67
|
-
if (input.kind === 'NON_NULL') {
|
|
68
|
-
context.isNotNull = true;
|
|
69
|
-
return getInputForMutations(input.ofType, context);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (input.kind === 'LIST') {
|
|
73
|
-
context.isArray = true;
|
|
74
|
-
|
|
75
|
-
if (context.isNotNull) {
|
|
76
|
-
context.isArrayNotNull = true;
|
|
77
|
-
delete context.isNotNull;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return getInputForMutations(input.ofType, context);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (input.kind === 'INPUT_OBJECT') {
|
|
84
|
-
if (input.name && HASH.hasOwnProperty(input.name)) {
|
|
85
|
-
const schema = HASH[input.name];
|
|
86
|
-
context.properties = schema.inputFields.map(field => {
|
|
87
|
-
return getInputForMutations(field.type, {
|
|
88
|
-
name: field.name
|
|
89
|
-
});
|
|
90
|
-
}).reduce((m3, v) => {
|
|
91
|
-
m3[v.name] = v;
|
|
92
|
-
return m3;
|
|
93
|
-
}, {});
|
|
94
|
-
}
|
|
95
|
-
} else if (input.kind === 'OBJECT') {
|
|
96
|
-
if (input.name && HASH.hasOwnProperty(input.name)) {
|
|
97
|
-
const schema = HASH[input.name];
|
|
98
|
-
context.properties = schema.fields.map(field => {
|
|
99
|
-
return {
|
|
100
|
-
name: field.name,
|
|
101
|
-
type: field.type
|
|
102
|
-
};
|
|
103
|
-
}).reduce((m3, v) => {
|
|
104
|
-
m3[v.name] = v;
|
|
105
|
-
return m3;
|
|
106
|
-
}, {});
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
context.type = input.name;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return context;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const mutations = mutationsRoot.fields.reduce((m, mutation) => {
|
|
116
|
-
let mutationType = 'other';
|
|
117
|
-
|
|
118
|
-
if (/^Create/.test(mutation.type.name)) {
|
|
119
|
-
mutationType = 'create';
|
|
120
|
-
} else if (/^Update/.test(mutation.type.name)) {
|
|
121
|
-
mutationType = 'patch';
|
|
122
|
-
} else if (/^Delete/.test(mutation.type.name)) {
|
|
123
|
-
mutationType = 'delete';
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const props = mutation.args.reduce((m2, arg) => {
|
|
127
|
-
const type = arg.type?.ofType?.name;
|
|
128
|
-
const isNotNull = arg.type?.kind === 'NON_NULL';
|
|
129
|
-
|
|
130
|
-
if (type && HASH.hasOwnProperty(type)) {
|
|
131
|
-
const schema = HASH[type];
|
|
132
|
-
const fields = schema.inputFields.filter(a => a.name !== 'clientMutationId');
|
|
133
|
-
const properties = fields.map(a => getInputForMutations(a.type, {
|
|
134
|
-
name: a.name
|
|
135
|
-
})).reduce((m3, v) => {
|
|
136
|
-
m3[v.name] = v;
|
|
137
|
-
return m3;
|
|
138
|
-
}, {});
|
|
139
|
-
m2[arg.name] = {
|
|
140
|
-
isNotNull,
|
|
141
|
-
type,
|
|
142
|
-
properties
|
|
143
|
-
};
|
|
144
|
-
} else {
|
|
145
|
-
console.warn('whats wrong with ' + arg);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return m2;
|
|
149
|
-
}, {});
|
|
150
|
-
|
|
151
|
-
const getModelTypes = type => {
|
|
152
|
-
return type.fields.filter(t => t.type.kind === 'OBJECT').filter(t => t.type.name !== 'Query').map(f => ({
|
|
153
|
-
name: f.name,
|
|
154
|
-
type: f.type
|
|
155
|
-
}));
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const models = getModelTypes(HASH[mutation.type.name]);
|
|
159
|
-
|
|
160
|
-
if (models.length > 0) {
|
|
161
|
-
// TODO this is probably brittle
|
|
162
|
-
const model = models[0].type.name;
|
|
163
|
-
m[mutation.name] = {
|
|
164
|
-
qtype: 'mutation',
|
|
165
|
-
mutationType,
|
|
166
|
-
model,
|
|
167
|
-
properties: props,
|
|
168
|
-
output: mutation.type
|
|
169
|
-
};
|
|
170
|
-
} else {
|
|
171
|
-
// no return args, probably void functions
|
|
172
|
-
let t;
|
|
173
|
-
let outputFields = [];
|
|
174
|
-
|
|
175
|
-
if (mutation.type.kind === 'OBJECT') {
|
|
176
|
-
t = HASH[mutation.type.name];
|
|
177
|
-
outputFields = t.fields.map(f => ({
|
|
178
|
-
name: f.name,
|
|
179
|
-
type: f.type
|
|
180
|
-
})).filter(f => f.name !== 'clientMutationId').filter(f => f.type.name !== 'Query');
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
m[mutation.name] = {
|
|
184
|
-
qtype: 'mutation',
|
|
185
|
-
mutationType,
|
|
186
|
-
properties: props,
|
|
187
|
-
output: mutation.type,
|
|
188
|
-
outputs: outputFields
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return m;
|
|
193
|
-
}, {}); // expect(mts).toMatchSnapshot();
|
|
194
|
-
|
|
195
|
-
const parseConnectionQuery = (query, nesting) => {
|
|
196
|
-
const objectType = getObjectType(query.type);
|
|
197
|
-
const Connection = HASH[objectType];
|
|
198
|
-
const nodes = Connection.fields.find(f => f.name === 'nodes');
|
|
199
|
-
const edges = Connection.fields.find(f => f.name === 'edges');
|
|
200
|
-
const model = getObjectType(nodes.type);
|
|
201
|
-
const context = {
|
|
202
|
-
HASH,
|
|
203
|
-
parseConnectionQuery,
|
|
204
|
-
parseSingleQuery
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
if (nesting === 0) {
|
|
208
|
-
return {
|
|
209
|
-
qtype: 'getMany',
|
|
210
|
-
model,
|
|
211
|
-
selection: parseSelectionScalar(context, model)
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
qtype: 'getMany',
|
|
217
|
-
model,
|
|
218
|
-
selection: parseSelectionObject(context, model, 1)
|
|
219
|
-
};
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const parseSingleQuery = (query, nesting) => {
|
|
223
|
-
const model = getObjectType(query.type);
|
|
224
|
-
const context = {
|
|
225
|
-
HASH,
|
|
226
|
-
parseConnectionQuery,
|
|
227
|
-
parseSingleQuery
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
if (nesting === 0) {
|
|
231
|
-
return {
|
|
232
|
-
qtype: 'getOne',
|
|
233
|
-
model,
|
|
234
|
-
properties: query.args.reduce((m2, v) => {
|
|
235
|
-
m2[v.name] = getInputForQueries(v.type);
|
|
236
|
-
return m2;
|
|
237
|
-
}, {}),
|
|
238
|
-
selection: parseSelectionScalar(context, model)
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
model,
|
|
244
|
-
qtype: 'getOne',
|
|
245
|
-
properties: query.args.reduce((m2, v) => {
|
|
246
|
-
m2[v.name] = getInputForQueries(v.type);
|
|
247
|
-
return m2;
|
|
248
|
-
}, {}),
|
|
249
|
-
selection: parseSelectionObject(context, model, 1)
|
|
250
|
-
};
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const queries = queriesRoot.fields.reduce((m, query) => {
|
|
254
|
-
// m[query.name] = getInputForQueries(query.type);
|
|
255
|
-
if (query.type.kind === 'OBJECT') {
|
|
256
|
-
if (isConnectionQuery(query)) {
|
|
257
|
-
m[query.name] = parseConnectionQuery(query, 1);
|
|
258
|
-
} else {
|
|
259
|
-
m[query.name] = parseSingleQuery(query, 1);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return m;
|
|
264
|
-
}, {});
|
|
265
|
-
return {
|
|
266
|
-
queries,
|
|
267
|
-
mutations
|
|
268
|
-
};
|
|
269
|
-
}; // Parse selections for both scalar and object fields
|
|
270
|
-
|
|
271
|
-
function parseSelectionObject(context, model, nesting) {
|
|
272
|
-
const {
|
|
273
|
-
HASH,
|
|
274
|
-
parseConnectionQuery,
|
|
275
|
-
parseSingleQuery
|
|
276
|
-
} = context;
|
|
277
|
-
throwIfInvalidContext(context);
|
|
278
|
-
const selectionFields = HASH[model].fields.filter(f => !isPureObjectType(f.type));
|
|
279
|
-
const selection = selectionFields.map(f => {
|
|
280
|
-
if (f.type.ofType?.kind === 'OBJECT') {
|
|
281
|
-
if (isConnectionQuery(f)) {
|
|
282
|
-
return _objectSpread({
|
|
283
|
-
name: f.name
|
|
284
|
-
}, parseConnectionQuery(f, nesting - 1));
|
|
285
|
-
} else {
|
|
286
|
-
return _objectSpread({
|
|
287
|
-
name: f.name
|
|
288
|
-
}, parseSingleQuery(f, nesting - 1));
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return f.name;
|
|
293
|
-
});
|
|
294
|
-
return selection;
|
|
295
|
-
} // Parse selections for scalar types only, ignore all field selections
|
|
296
|
-
// that have more nesting selection level
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
function parseSelectionScalar(context, model) {
|
|
300
|
-
const {
|
|
301
|
-
HASH
|
|
302
|
-
} = context;
|
|
303
|
-
throwIfInvalidContext(context);
|
|
304
|
-
const selectionFields = HASH[model].fields.filter(f => !isPureObjectType(f.type) && !isConnectionQuery(f));
|
|
305
|
-
const selection = selectionFields.map(f => f.name);
|
|
306
|
-
return selection;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function isConnectionQuery(query) {
|
|
310
|
-
const objectType = getObjectType(query.type);
|
|
311
|
-
const fields = query.args.map(a => a.name);
|
|
312
|
-
return /Connection$/.test(objectType) && fields.includes('condition') && fields.includes('filter');
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Check is a type is pure object type
|
|
316
|
-
* pure object type is different from custom types in the sense that
|
|
317
|
-
* it does not inherit from any type, custom types inherit from a parent type
|
|
318
|
-
* @param {Object} typeObj
|
|
319
|
-
* @returns {boolean}
|
|
320
|
-
*/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
function isPureObjectType(typeObj) {
|
|
324
|
-
return typeObj.kind === 'OBJECT' && typeObj.name == null;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function getObjectType(type) {
|
|
328
|
-
if (type.kind === 'OBJECT') return type.name;
|
|
329
|
-
if (type.ofType) return getObjectType(type.ofType);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function throwIfInvalidContext(context) {
|
|
333
|
-
const {
|
|
334
|
-
HASH,
|
|
335
|
-
parseConnectionQuery,
|
|
336
|
-
parseSingleQuery
|
|
337
|
-
} = context;
|
|
338
|
-
|
|
339
|
-
if (!HASH || !parseConnectionQuery || !parseSingleQuery) {
|
|
340
|
-
throw new Error('parseSelection: context missing');
|
|
341
|
-
}
|
|
342
|
-
}
|
package/module/introspect.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { makeIntrospectionQuery } from './query';
|
|
2
|
-
import { parseTags } from './utils';
|
|
3
|
-
import flatMap from 'lodash/flatMap';
|
|
4
|
-
export const introspect = async (pgClient, {
|
|
5
|
-
schemas,
|
|
6
|
-
includeExtensions = false,
|
|
7
|
-
pgEnableTags = true,
|
|
8
|
-
pgThrowOnMissingSchema = true
|
|
9
|
-
} = {}) => {
|
|
10
|
-
const versionResult = await pgClient.query('show server_version_num;');
|
|
11
|
-
const serverVersionNum = parseInt(versionResult.rows[0].server_version_num, 10);
|
|
12
|
-
const introspectionQuery = makeIntrospectionQuery(serverVersionNum, {
|
|
13
|
-
pgLegacyFunctionsOnly: false,
|
|
14
|
-
pgIgnoreRBAC: true
|
|
15
|
-
});
|
|
16
|
-
const {
|
|
17
|
-
rows
|
|
18
|
-
} = await pgClient.query(introspectionQuery, [schemas, includeExtensions]);
|
|
19
|
-
const result = {
|
|
20
|
-
__pgVersion: serverVersionNum,
|
|
21
|
-
namespace: [],
|
|
22
|
-
class: [],
|
|
23
|
-
attribute: [],
|
|
24
|
-
type: [],
|
|
25
|
-
constraint: [],
|
|
26
|
-
procedure: [],
|
|
27
|
-
extension: [],
|
|
28
|
-
index: []
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
for (const {
|
|
32
|
-
object
|
|
33
|
-
} of rows) {
|
|
34
|
-
result[object.kind].push(object);
|
|
35
|
-
} // Parse tags from comments
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
['namespace', 'class', 'attribute', 'type', 'constraint', 'procedure', 'extension', 'index'].forEach(kind => {
|
|
39
|
-
result[kind].forEach(object => {
|
|
40
|
-
// Keep a copy of the raw comment
|
|
41
|
-
object.comment = object.description;
|
|
42
|
-
|
|
43
|
-
if (pgEnableTags && object.description) {
|
|
44
|
-
const parsed = parseTags(object.description);
|
|
45
|
-
object.tags = parsed.tags;
|
|
46
|
-
object.description = parsed.text;
|
|
47
|
-
} else {
|
|
48
|
-
object.tags = {};
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
const extensionConfigurationClassIds = flatMap(result.extension, e => e.configurationClassIds);
|
|
53
|
-
result.class.forEach(klass => {
|
|
54
|
-
klass.isExtensionConfigurationTable = extensionConfigurationClassIds.indexOf(klass.id) >= 0;
|
|
55
|
-
});
|
|
56
|
-
['namespace', 'class', 'attribute', 'type', 'constraint', 'procedure', 'extension', 'index'].forEach(k => {
|
|
57
|
-
result[k].forEach(Object.freeze);
|
|
58
|
-
});
|
|
59
|
-
const knownSchemas = result.namespace.map(n => n.name);
|
|
60
|
-
const missingSchemas = schemas.filter(s => knownSchemas.indexOf(s) < 0);
|
|
61
|
-
|
|
62
|
-
if (missingSchemas.length) {
|
|
63
|
-
const errorMessage = `You requested to use schema '${schemas.join("', '")}'; however we couldn't find some of those! Missing schemas are: '${missingSchemas.join("', '")}'`;
|
|
64
|
-
|
|
65
|
-
if (pgThrowOnMissingSchema) {
|
|
66
|
-
throw new Error(errorMessage);
|
|
67
|
-
} else {
|
|
68
|
-
console.warn('⚠️ WARNING⚠️ ' + errorMessage); // eslint-disable-line no-console
|
|
69
|
-
}
|
|
70
|
-
} // return result;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return Object.freeze(result);
|
|
74
|
-
}; // export const processIntrospection = async (pgClient, introspectionResultsByKind) => {
|
|
75
|
-
// }
|