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