introspectron 0.2.4 → 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/main/process.js DELETED
@@ -1,410 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.introspectionResultsFromRaw = void 0;
9
-
10
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
-
12
- var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
13
-
14
- var _utils = require("./utils");
15
-
16
- var removeQuotes = function removeQuotes(str) {
17
- var trimmed = str.trim();
18
-
19
- if (trimmed[0] === '"') {
20
- if (trimmed[trimmed.length - 1] !== '"') {
21
- throw new Error("We failed to parse a quoted identifier '".concat(str, "'. Please avoid putting quotes or commas in smart comment identifiers (or file a PR to fix the parser)."));
22
- }
23
-
24
- return trimmed.substr(1, trimmed.length - 2);
25
- } else {
26
- // PostgreSQL lower-cases unquoted columns, so we should too.
27
- return trimmed.toLowerCase();
28
- }
29
- };
30
-
31
- var parseSqlColumnArray = function parseSqlColumnArray(str) {
32
- if (!str) {
33
- throw new Error("Cannot parse '".concat(str, "'"));
34
- }
35
-
36
- var parts = str.split(',');
37
- return parts.map(removeQuotes);
38
- };
39
-
40
- var parseSqlColumnString = function parseSqlColumnString(str) {
41
- if (!str) {
42
- throw new Error("Cannot parse '".concat(str, "'"));
43
- }
44
-
45
- return removeQuotes(str);
46
- };
47
-
48
- function parseConstraintSpec(rawSpec) {
49
- var _rawSpec$split = rawSpec.split(/\|/),
50
- _rawSpec$split2 = (0, _toArray2["default"])(_rawSpec$split),
51
- spec = _rawSpec$split2[0],
52
- tagComponents = _rawSpec$split2.slice(1);
53
-
54
- var parsed = (0, _utils.parseTags)(tagComponents.join('\n'));
55
- return {
56
- spec: spec,
57
- tags: parsed.tags,
58
- description: parsed.text
59
- };
60
- }
61
-
62
- function smartCommentConstraints(introspectionResults) {
63
- var attributesByNames = function attributesByNames(tbl, cols, debugStr) {
64
- var attributes = introspectionResults.attribute.filter(function (a) {
65
- return a.classId === tbl.id;
66
- }).sort(function (a, b) {
67
- return a.num - b.num;
68
- });
69
-
70
- if (!cols) {
71
- var pk = introspectionResults.constraint.find(function (c) {
72
- return c.classId == tbl.id && c.type === 'p';
73
- });
74
-
75
- if (pk) {
76
- return pk.keyAttributeNums.map(function (n) {
77
- return attributes.find(function (a) {
78
- return a.num === n;
79
- });
80
- });
81
- } else {
82
- throw new Error("No columns specified for '".concat(tbl.namespaceName, ".").concat(tbl.name, "' (oid: ").concat(tbl.id, ") and no PK found (").concat(debugStr, ")."));
83
- }
84
- }
85
-
86
- return cols.map(function (colName) {
87
- var attr = attributes.find(function (a) {
88
- return a.name === colName;
89
- });
90
-
91
- if (!attr) {
92
- throw new Error("Could not find attribute '".concat(colName, "' in '").concat(tbl.namespaceName, ".").concat(tbl.name, "'"));
93
- }
94
-
95
- return attr;
96
- });
97
- }; // First: primary keys
98
-
99
-
100
- introspectionResults["class"].forEach(function (klass) {
101
- var namespace = introspectionResults.namespace.find(function (n) {
102
- return n.id === klass.namespaceId;
103
- });
104
-
105
- if (!namespace) {
106
- return;
107
- }
108
-
109
- if (klass.tags.primaryKey) {
110
- if (typeof klass.tags.primaryKey !== 'string') {
111
- throw new Error("@primaryKey configuration of '".concat(klass.namespaceName, ".").concat(klass.name, "' is invalid; please specify just once \"@primaryKey col1,col2\""));
112
- }
113
-
114
- var _parseConstraintSpec = parseConstraintSpec(klass.tags.primaryKey),
115
- pkSpec = _parseConstraintSpec.spec,
116
- tags = _parseConstraintSpec.tags,
117
- description = _parseConstraintSpec.description;
118
-
119
- var columns = parseSqlColumnArray(pkSpec);
120
- var attributes = attributesByNames(klass, columns, "@primaryKey ".concat(klass.tags.primaryKey));
121
- attributes.forEach(function (attr) {
122
- attr.tags.notNull = true;
123
- });
124
- var keyAttributeNums = attributes.map(function (a) {
125
- return a.num;
126
- }); // Now we need to fake a constraint for this:
127
-
128
- var fakeConstraint = {
129
- kind: 'constraint',
130
- isFake: true,
131
- isIndexed: true,
132
- // otherwise it gets ignored by ignoreIndexes
133
- id: Math.random(),
134
- name: "FAKE_".concat(klass.namespaceName, "_").concat(klass.name, "_primaryKey"),
135
- type: 'p',
136
- // primary key
137
- classId: klass.id,
138
- foreignClassId: null,
139
- comment: null,
140
- description: description,
141
- keyAttributeNums: keyAttributeNums,
142
- foreignKeyAttributeNums: null,
143
- tags: tags
144
- };
145
- introspectionResults.constraint.push(fakeConstraint);
146
- }
147
- }); // Now primary keys are in place, we can apply foreign keys
148
-
149
- introspectionResults["class"].forEach(function (klass) {
150
- var namespace = introspectionResults.namespace.find(function (n) {
151
- return n.id === klass.namespaceId;
152
- });
153
-
154
- if (!namespace) {
155
- return;
156
- }
157
-
158
- var getType = function getType() {
159
- return introspectionResults.type.find(function (t) {
160
- return t.id === klass.typeId;
161
- });
162
- };
163
-
164
- var foreignKey = klass.tags.foreignKey || getType().tags.foreignKey;
165
-
166
- if (foreignKey) {
167
- var foreignKeys = typeof foreignKey === 'string' ? [foreignKey] : foreignKey;
168
-
169
- if (!Array.isArray(foreignKeys)) {
170
- throw new Error("Invalid foreign key smart comment specified on '".concat(klass.namespaceName, ".").concat(klass.name, "'"));
171
- }
172
-
173
- foreignKeys.forEach(function (fkSpecRaw, index) {
174
- if (typeof fkSpecRaw !== 'string') {
175
- throw new Error("Invalid foreign key spec (".concat(index, ") on '").concat(klass.namespaceName, ".").concat(klass.name, "'"));
176
- }
177
-
178
- var _parseConstraintSpec2 = parseConstraintSpec(fkSpecRaw),
179
- fkSpec = _parseConstraintSpec2.spec,
180
- tags = _parseConstraintSpec2.tags,
181
- description = _parseConstraintSpec2.description;
182
-
183
- var matches = fkSpec.match(/^\(([^()]+)\) references ([^().]+)(?:\.([^().]+))?(?:\s*\(([^()]+)\))?$/i);
184
-
185
- if (!matches) {
186
- throw new Error("Invalid foreignKey syntax for '".concat(klass.namespaceName, ".").concat(klass.name, "'; expected something like \"(col1,col2) references schema.table (c1, c2)\", you passed '").concat(fkSpecRaw, "'"));
187
- }
188
-
189
- var _matches = (0, _slicedToArray2["default"])(matches, 5),
190
- rawColumns = _matches[1],
191
- rawSchemaOrTable = _matches[2],
192
- rawTableOnly = _matches[3],
193
- rawForeignColumns = _matches[4];
194
-
195
- var rawSchema = rawTableOnly ? rawSchemaOrTable : "\"".concat(klass.namespaceName, "\"");
196
- var rawTable = rawTableOnly || rawSchemaOrTable;
197
- var columns = parseSqlColumnArray(rawColumns);
198
- var foreignSchema = parseSqlColumnString(rawSchema);
199
- var foreignTable = parseSqlColumnString(rawTable);
200
- var foreignColumns = rawForeignColumns ? parseSqlColumnArray(rawForeignColumns) : null;
201
- var foreignKlass = introspectionResults["class"].find(function (k) {
202
- return k.name === foreignTable && k.namespaceName === foreignSchema;
203
- });
204
-
205
- if (!foreignKlass) {
206
- throw new Error("@foreignKey smart comment referenced non-existant table/view '".concat(foreignSchema, "'.'").concat(foreignTable, "'. Note that this reference must use *database names* (i.e. it does not respect @name). (").concat(fkSpecRaw, ")"));
207
- }
208
-
209
- var foreignNamespace = introspectionResults.namespace.find(function (n) {
210
- return n.id === foreignKlass.namespaceId;
211
- });
212
-
213
- if (!foreignNamespace) {
214
- return;
215
- }
216
-
217
- var keyAttributeNums = attributesByNames(klass, columns, "@foreignKey ".concat(fkSpecRaw)).map(function (a) {
218
- return a.num;
219
- });
220
- var foreignKeyAttributeNums = attributesByNames(foreignKlass, foreignColumns, "@foreignKey ".concat(fkSpecRaw)).map(function (a) {
221
- return a.num;
222
- }); // Now we need to fake a constraint for this:
223
-
224
- var fakeConstraint = {
225
- kind: 'constraint',
226
- isFake: true,
227
- isIndexed: true,
228
- // otherwise it gets ignored by ignoreIndexes
229
- id: Math.random(),
230
- name: "FAKE_".concat(klass.namespaceName, "_").concat(klass.name, "_foreignKey_").concat(index),
231
- type: 'f',
232
- // foreign key
233
- classId: klass.id,
234
- foreignClassId: foreignKlass.id,
235
- comment: null,
236
- description: description,
237
- keyAttributeNums: keyAttributeNums,
238
- foreignKeyAttributeNums: foreignKeyAttributeNums,
239
- tags: tags
240
- };
241
- introspectionResults.constraint.push(fakeConstraint);
242
- });
243
- }
244
- });
245
- }
246
-
247
- var introspectionResultsFromRaw = function introspectionResultsFromRaw(rawResults, pgAugmentIntrospectionResults) {
248
- var introspectionResultsByKind = (0, _utils.deepClone)(rawResults);
249
-
250
- var xByY = function xByY(arrayOfX, attrKey) {
251
- return arrayOfX.reduce(function (memo, x) {
252
- memo[x[attrKey]] = x;
253
- return memo;
254
- }, {});
255
- };
256
-
257
- var xByYAndZ = function xByYAndZ(arrayOfX, attrKey, attrKey2) {
258
- return arrayOfX.reduce(function (memo, x) {
259
- if (!memo[x[attrKey]]) memo[x[attrKey]] = {};
260
- memo[x[attrKey]][x[attrKey2]] = x;
261
- return memo;
262
- }, {});
263
- };
264
-
265
- introspectionResultsByKind.namespaceById = xByY(introspectionResultsByKind.namespace, 'id');
266
- introspectionResultsByKind.classById = xByY(introspectionResultsByKind["class"], 'id');
267
- introspectionResultsByKind.typeById = xByY(introspectionResultsByKind.type, 'id');
268
- introspectionResultsByKind.attributeByClassIdAndNum = xByYAndZ(introspectionResultsByKind.attribute, 'classId', 'num');
269
- introspectionResultsByKind.extensionById = xByY(introspectionResultsByKind.extension, 'id');
270
-
271
- var relate = function relate(array, newAttr, lookupAttr, lookup) {
272
- var missingOk = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
273
- array.forEach(function (entry) {
274
- var key = entry[lookupAttr];
275
-
276
- if (Array.isArray(key)) {
277
- entry[newAttr] = key.map(function (innerKey) {
278
- var result = lookup[innerKey];
279
-
280
- if (innerKey && !result) {
281
- if (missingOk) {
282
- return;
283
- }
284
-
285
- throw new Error("Could not look up '".concat(newAttr, "' by '").concat(lookupAttr, "' ('").concat(innerKey, "') on '").concat(JSON.stringify(entry), "'"));
286
- }
287
-
288
- return result;
289
- }).filter(function (_) {
290
- return _;
291
- });
292
- } else {
293
- var result = lookup[key];
294
-
295
- if (key && !result) {
296
- if (missingOk) {
297
- return;
298
- }
299
-
300
- throw new Error("Could not look up '".concat(newAttr, "' by '").concat(lookupAttr, "' on '").concat(JSON.stringify(entry), "'"));
301
- }
302
-
303
- entry[newAttr] = result;
304
- }
305
- });
306
- };
307
-
308
- var augment = function augment(introspectionResults) {
309
- [pgAugmentIntrospectionResults, smartCommentConstraints].forEach(function (fn) {
310
- return fn ? fn(introspectionResults) : null;
311
- });
312
- };
313
-
314
- augment(introspectionResultsByKind);
315
- relate(introspectionResultsByKind["class"], 'namespace', 'namespaceId', introspectionResultsByKind.namespaceById, true // Because it could be a type defined in a different namespace - which is fine so long as we don't allow querying it directly
316
- );
317
- relate(introspectionResultsByKind["class"], 'type', 'typeId', introspectionResultsByKind.typeById);
318
- relate(introspectionResultsByKind.attribute, 'class', 'classId', introspectionResultsByKind.classById);
319
- relate(introspectionResultsByKind.attribute, 'type', 'typeId', introspectionResultsByKind.typeById);
320
- relate(introspectionResultsByKind.procedure, 'namespace', 'namespaceId', introspectionResultsByKind.namespaceById);
321
- relate(introspectionResultsByKind.type, 'class', 'classId', introspectionResultsByKind.classById, true);
322
- relate(introspectionResultsByKind.type, 'domainBaseType', 'domainBaseTypeId', introspectionResultsByKind.typeById, true // Because not all types are domains
323
- );
324
- relate(introspectionResultsByKind.type, 'arrayItemType', 'arrayItemTypeId', introspectionResultsByKind.typeById, true // Because not all types are arrays
325
- );
326
- relate(introspectionResultsByKind.constraint, 'class', 'classId', introspectionResultsByKind.classById);
327
- relate(introspectionResultsByKind.constraint, 'foreignClass', 'foreignClassId', introspectionResultsByKind.classById, true // Because many constraints don't apply to foreign classes
328
- );
329
- relate(introspectionResultsByKind.extension, 'namespace', 'namespaceId', introspectionResultsByKind.namespaceById, true // Because the extension could be a defined in a different namespace
330
- );
331
- relate(introspectionResultsByKind.extension, 'configurationClasses', 'configurationClassIds', introspectionResultsByKind.classById, true // Because the configuration table could be a defined in a different namespace
332
- );
333
- relate(introspectionResultsByKind.index, 'class', 'classId', introspectionResultsByKind.classById); // Reverse arrayItemType -> arrayType
334
-
335
- introspectionResultsByKind.type.forEach(function (type) {
336
- if (type.arrayItemType) {
337
- type.arrayItemType.arrayType = type;
338
- }
339
- }); // Table/type columns / constraints
340
-
341
- introspectionResultsByKind["class"].forEach(function (klass) {
342
- klass.attributes = introspectionResultsByKind.attribute.filter(function (attr) {
343
- return attr.classId === klass.id;
344
- });
345
- klass.canUseAsterisk = !klass.attributes.some(function (attr) {
346
- return attr.columnLevelSelectGrant;
347
- });
348
- klass.constraints = introspectionResultsByKind.constraint.filter(function (constraint) {
349
- return constraint.classId === klass.id;
350
- });
351
- klass.foreignConstraints = introspectionResultsByKind.constraint.filter(function (constraint) {
352
- return constraint.foreignClassId === klass.id;
353
- });
354
- klass.primaryKeyConstraint = klass.constraints.find(function (constraint) {
355
- return constraint.type === 'p';
356
- });
357
- }); // Constraint attributes
358
-
359
- introspectionResultsByKind.constraint.forEach(function (constraint) {
360
- if (constraint.keyAttributeNums && constraint["class"]) {
361
- constraint.keyAttributes = constraint.keyAttributeNums.map(function (nr) {
362
- return constraint["class"].attributes.find(function (attr) {
363
- return attr.num === nr;
364
- });
365
- });
366
- } else {
367
- constraint.keyAttributes = [];
368
- }
369
-
370
- if (constraint.foreignKeyAttributeNums && constraint.foreignClass) {
371
- constraint.foreignKeyAttributes = constraint.foreignKeyAttributeNums.map(function (nr) {
372
- return constraint.foreignClass.attributes.find(function (attr) {
373
- return attr.num === nr;
374
- });
375
- });
376
- } else {
377
- constraint.foreignKeyAttributes = [];
378
- }
379
- }); // Detect which columns and constraints are indexed
380
-
381
- introspectionResultsByKind.index.forEach(function (index) {
382
- var columns = index.attributeNums.map(function (nr) {
383
- return index["class"].attributes.find(function (attr) {
384
- return attr.num === nr;
385
- });
386
- }); // Indexed column (for orderBy / filter):
387
-
388
- if (columns[0]) {
389
- columns[0].isIndexed = true;
390
- }
391
-
392
- if (columns[0] && columns.length === 1 && index.isUnique) {
393
- columns[0].isUnique = true;
394
- } // Indexed constraints (for reverse relations):
395
-
396
-
397
- index["class"].constraints.filter(function (constraint) {
398
- return constraint.type === 'f';
399
- }).forEach(function (constraint) {
400
- if (constraint.keyAttributeNums.every(function (nr, idx) {
401
- return index.attributeNums[idx] === nr;
402
- })) {
403
- constraint.isIndexed = true;
404
- }
405
- });
406
- });
407
- return introspectionResultsByKind;
408
- };
409
-
410
- exports.introspectionResultsFromRaw = introspectionResultsFromRaw;
package/main/query.js DELETED
@@ -1,26 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.makeIntrospectionQuery = void 0;
7
-
8
- /*
9
- * IMPORTANT: when editing this file, ensure all operators (e.g. `@>`) are
10
- * specified in the correct namespace (e.g. `operator(pg_catalog.@>)`). It looks
11
- * weird, but it prevents clashes with extensions or user code that may
12
- * overload operators, e.g. extension `intarray` overloads `@>`.
13
- *
14
- * NOTE: I'm not doing this with `=` because that way lies madness.
15
- */
16
- var makeIntrospectionQuery = function makeIntrospectionQuery(serverVersionNum) {
17
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18
- var _options$pgLegacyFunc = options.pgLegacyFunctionsOnly,
19
- pgLegacyFunctionsOnly = _options$pgLegacyFunc === void 0 ? false : _options$pgLegacyFunc,
20
- _options$pgIgnoreRBAC = options.pgIgnoreRBAC,
21
- pgIgnoreRBAC = _options$pgIgnoreRBAC === void 0 ? true : _options$pgIgnoreRBAC;
22
- var unionRBAC = "\n union all\n select pg_roles.oid _oid, pg_roles.*\n from pg_roles, accessible_roles, pg_auth_members\n where pg_auth_members.roleid = pg_roles.oid\n and pg_auth_members.member = accessible_roles._oid \n ";
23
- return " -- @see https://www.postgresql.org/docs/9.5/static/catalogs.html\n -- @see https://github.com/graphile/graphile-engine/blob/master/packages/graphile-build-pg/src/plugins/introspectionQuery.js\n --\n -- ## Parameters\n -- - `$1`: An array of strings that represent the namespaces we are introspecting.\n -- - `$2`: set true to include functions/tables/etc that come from extensions\n with\n ".concat(!pgIgnoreRBAC ? 'recursive' : '', " accessible_roles(_oid) as (\n select oid _oid, pg_roles.*\n from pg_roles\n where rolname = current_user\n ").concat(!pgIgnoreRBAC ? unionRBAC : '', "\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-namespace.html\n namespace as (\n select\n 'namespace' as \"kind\",\n nsp.oid as \"id\",\n nsp.nspname as \"name\",\n dsc.description as \"description\"\n from\n pg_catalog.pg_namespace as nsp\n left join pg_catalog.pg_description as dsc on dsc.objoid = nsp.oid and dsc.classoid = 'pg_catalog.pg_namespace'::regclass\n where\n nsp.nspname = any ($1)\n order by\n nsp.nspname\n ),\n -- Select all of the remote procedures we can use in this schema. This comes\n -- first so that we can select types and classes using the information we get\n -- from it.\n --\n -- @see https://www.postgresql.org/docs/9.6/static/catalog-pg-proc.html\n procedure as (\n select\n 'procedure' as \"kind\",\n pro.oid as \"id\",\n pro.proname as \"name\",\n dsc.description as \"description\",\n pro.pronamespace as \"namespaceId\",\n nsp.nspname as \"namespaceName\",\n pro.proisstrict as \"isStrict\",\n pro.proretset as \"returnsSet\",\n case\n when pro.provolatile = 'i' then true\n when pro.provolatile = 's' then true\n else false\n end as \"isStable\",\n pro.prorettype as \"returnTypeId\",\n coalesce(pro.proallargtypes, pro.proargtypes) as \"argTypeIds\",\n coalesce(pro.proargmodes, array[]::text[]) as \"argModes\",\n coalesce(pro.proargnames, array[]::text[]) as \"argNames\",\n pro.pronargs as \"inputArgsCount\",\n pro.pronargdefaults as \"argDefaultsNum\",\n pro.procost as \"cost\",\n exists(select 1 from accessible_roles where has_function_privilege(accessible_roles.oid, pro.oid, 'EXECUTE')) as \"aclExecutable\",\n (select lanname from pg_catalog.pg_language where pg_language.oid = pro.prolang) as \"language\"\n from\n pg_catalog.pg_proc as pro\n left join pg_catalog.pg_description as dsc on dsc.objoid = pro.oid and dsc.classoid = 'pg_catalog.pg_proc'::regclass\n left join pg_catalog.pg_namespace as nsp on nsp.oid = pro.pronamespace\n where\n pro.pronamespace in (select \"id\" from namespace) and\n -- Currently we don\u2019t support functions with variadic arguments. In the\n -- future we may, but for now let\u2019s just ignore functions with variadic\n -- arguments.\n -- TODO: Variadic arguments.\n pro.provariadic = 0 and\n -- Filter our aggregate functions and window functions.\n ").concat(serverVersionNum >= 110000 ? "pro.prokind = 'f'" : 'pro.proisagg = false and pro.proiswindow = false', " and\n ").concat(pgLegacyFunctionsOnly ? " -- We want to make sure the argument mode for all of our arguments is\n -- `IN` which means `proargmodes` will be null.\n pro.proargmodes is null and\n -- Do not select procedures that return `RECORD` (oid 2249).\n pro.prorettype operator(pg_catalog.<>) 2249 and" : " -- We want to make sure the argument modes for all of our arguments are\n -- `IN`, `OUT`, `INOUT`, or `TABLE` (not `VARIADIC`).\n (pro.proargmodes is null or pro.proargmodes operator(pg_catalog.<@) array['i','o','b','t']::\"char\"[]) and\n -- Do not select procedures that return `RECORD` (oid 2249) unless they\n -- have `OUT`, `INOUT`, or `TABLE` arguments to define the return type.\n (pro.prorettype operator(pg_catalog.<>) 2249 or pro.proargmodes && array['o','b','t']::\"char\"[]) and\n -- Do not select procedures that have `RECORD` arguments.\n (pro.proallargtypes is null or not (pro.proallargtypes operator(pg_catalog.@>) array[2249::oid])) and", "\n -- Do not select procedures that create range types. These are utility\n -- functions that really don\u2019t need to be exposed in an API.\n pro.proname not in (\n select typ.typname\n from pg_catalog.pg_type as typ\n where typ.typtype = 'r'\n and typ.typnamespace = pro.pronamespace\n ) and\n -- Do not expose trigger functions (type trigger has oid 2279)\n pro.prorettype operator(pg_catalog.<>) 2279 and\n -- We don't want functions that will clash with GraphQL (treat them as private)\n pro.proname not like E'\\\\_\\\\_%' and\n -- We also don\u2019t want procedures that have been defined in our namespace\n -- twice. This leads to duplicate fields in the API which throws an\n -- error. In the future we may support this case. For now though, it is\n -- too complex.\n (\n select count(pro2.*)\n from pg_catalog.pg_proc as pro2\n where pro2.pronamespace = pro.pronamespace\n and pro2.proname = pro.proname\n ) = 1 and\n ($2 is true or not exists(\n select 1\n from pg_catalog.pg_depend\n where pg_depend.refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n and pg_depend.deptype = 'e'\n and pg_depend.classid = 'pg_catalog.pg_proc'::pg_catalog.regclass\n and pg_depend.objid = pro.oid\n ))\n order by\n pro.pronamespace, pro.proname\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-class.html\n class as (\n select\n 'class' as \"kind\",\n rel.oid as \"id\",\n rel.relname as \"name\",\n rel.relkind as \"classKind\",\n dsc.description as \"description\",\n rel.relnamespace as \"namespaceId\",\n nsp.nspname as \"namespaceName\",\n rel.reltype as \"typeId\",\n -- Here we determine whether or not we can use this class in a\n -- `SELECT`\u2019s `FROM` clause. In order to determine this we look at them\n -- `relkind` column, if it is `i` (index) or `c` (composite), we cannot\n -- select this class. Otherwise we can.\n rel.relkind not in ('i', 'c') as \"isSelectable\",\n -- Here we are determining whether we can insert/update/delete a class.\n -- This is helpful as it lets us detect non-updatable views and then\n -- exclude them from being inserted/updated/deleted into. For more info\n -- on how `pg_catalog.pg_relation_is_updatable` works:\n --\n -- - https://www.postgresql.org/message-id/CAEZATCV2_qN9P3zbvADwME_TkYf2gR_X2cLQR4R+pqkwxGxqJg@mail.gmail.com\n -- - https://github.com/postgres/postgres/blob/2410a2543e77983dab1f63f48b2adcd23dba994e/src/backend/utils/adt/misc.c#L684\n -- - https://github.com/postgres/postgres/blob/3aff33aa687e47d52f453892498b30ac98a296af/src/backend/rewrite/rewriteHandler.c#L2351\n (pg_catalog.pg_relation_is_updatable(rel.oid, true)::bit(8) operator(pg_catalog.&) B'00010000') = B'00010000' as \"isDeletable\",\n (pg_catalog.pg_relation_is_updatable(rel.oid, true)::bit(8) operator(pg_catalog.&) B'00001000') = B'00001000' as \"isInsertable\",\n (pg_catalog.pg_relation_is_updatable(rel.oid, true)::bit(8) operator(pg_catalog.&) B'00000100') = B'00000100' as \"isUpdatable\",\n exists(select 1 from accessible_roles where has_table_privilege(accessible_roles.oid, rel.oid, 'SELECT')) as \"aclSelectable\",\n exists(select 1 from accessible_roles where has_table_privilege(accessible_roles.oid, rel.oid, 'INSERT')) as \"aclInsertable\",\n exists(select 1 from accessible_roles where has_table_privilege(accessible_roles.oid, rel.oid, 'UPDATE')) as \"aclUpdatable\",\n exists(select 1 from accessible_roles where has_table_privilege(accessible_roles.oid, rel.oid, 'DELETE')) as \"aclDeletable\"\n from\n pg_catalog.pg_class as rel\n left join pg_catalog.pg_description as dsc on dsc.objoid = rel.oid and dsc.objsubid = 0 and dsc.classoid = 'pg_catalog.pg_class'::regclass\n left join pg_catalog.pg_namespace as nsp on nsp.oid = rel.relnamespace\n where\n rel.relpersistence in ('p') and\n -- We don't want classes that will clash with GraphQL (treat them as private)\n rel.relname not like E'\\\\_\\\\_%' and\n rel.relkind in ('r', 'v', 'm', 'c', 'f') and\n ($2 is true or not exists(\n select 1\n from pg_catalog.pg_depend\n where pg_depend.refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n and pg_depend.deptype = 'e'\n and pg_depend.classid = 'pg_catalog.pg_class'::pg_catalog.regclass\n and pg_depend.objid = rel.oid\n ))\n order by\n rel.relnamespace, rel.relname\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-attribute.html\n attribute as (\n select\n 'attribute' as \"kind\",\n att.attrelid as \"classId\",\n att.attnum as \"num\",\n att.attname as \"name\",\n dsc.description as \"description\",\n att.atttypid as \"typeId\",\n nullif(att.atttypmod, -1) as \"typeModifier\",\n att.attnotnull as \"isNotNull\",\n att.atthasdef as \"hasDefault\",\n ").concat(serverVersionNum >= 100000 ? 'att.attidentity' : "''", " as \"identity\",\n exists(select 1 from accessible_roles where has_column_privilege(accessible_roles.oid, att.attrelid, att.attname, 'SELECT')) as \"aclSelectable\",\n exists(select 1 from accessible_roles where has_column_privilege(accessible_roles.oid, att.attrelid, att.attname, 'INSERT')) as \"aclInsertable\",\n exists(select 1 from accessible_roles where has_column_privilege(accessible_roles.oid, att.attrelid, att.attname, 'UPDATE')) as \"aclUpdatable\",\n -- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c62dd80cdf149e2792b13c13777a539f5abb0370\n att.attacl is not null and exists(select 1 from aclexplode(att.attacl) aclitem where aclitem.privilege_type = 'SELECT' and grantee in (select oid from accessible_roles)) as \"columnLevelSelectGrant\"\n from\n pg_catalog.pg_attribute as att\n left join pg_catalog.pg_description as dsc on dsc.objoid = att.attrelid and dsc.objsubid = att.attnum and dsc.classoid = 'pg_catalog.pg_class'::regclass\n where\n att.attrelid in (select \"id\" from class) and\n att.attnum > 0 and\n -- We don't want attributes that will clash with GraphQL (treat them as private)\n att.attname not like E'\\\\_\\\\_%' and\n not att.attisdropped\n order by\n att.attrelid, att.attnum\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-type.html\n type as (\n -- Use another `WITH` statement here, because our `WHERE` clause will need\n -- to use it.\n with type_all as (\n select\n 'type' as \"kind\",\n typ.oid as \"id\",\n typ.typname as \"name\",\n dsc.description as \"description\",\n typ.typnamespace as \"namespaceId\",\n -- We include the namespace name in types only because we select so\n -- many types that are outside of our core set of namespaces. Having\n -- the namespace name is super helpful when generating SQL, so\n -- conditionally having namespace names for types is a pain.\n nsp.nspname as \"namespaceName\",\n typ.typtype as \"type\",\n typ.typcategory as \"category\",\n typ.typnotnull as \"domainIsNotNull\",\n nullif(typ.typelem, 0) as \"arrayItemTypeId\",\n typ.typlen as \"typeLength\",\n (typ.typelem <> 0 and typ.typlen = -1) as \"isPgArray\",\n nullif(typ.typrelid, 0) as \"classId\",\n nullif(typ.typbasetype, 0) as \"domainBaseTypeId\",\n nullif(typ.typtypmod, -1) as \"domainTypeModifier\",\n typ.typdefaultbin is not null as \"domainHasDefault\",\n -- If this type is an enum type, let\u2019s select all of its enum variants.\n --\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-enum.html\n case\n when typ.typtype = 'e' then array(\n select enm.enumlabel\n from pg_catalog.pg_enum as enm\n where enm.enumtypid = typ.oid\n order by enm.enumsortorder\n )\n else null\n end as \"enumVariants\",\n -- If this type is a range type, we want to select the sub type of the\n -- range.\n --\n -- @see https://www.postgresql.org/docs/9.6/static/catalog-pg-range.html\n case\n when typ.typtype = 'r' then (\n select rng.rngsubtype\n from pg_catalog.pg_range as rng\n where rng.rngtypid = typ.oid\n limit 1\n )\n else null\n end as \"rangeSubTypeId\"\n from\n pg_catalog.pg_type as typ\n left join pg_catalog.pg_description as dsc on dsc.objoid = typ.oid and dsc.classoid = 'pg_catalog.pg_type'::regclass\n left join pg_catalog.pg_namespace as nsp on nsp.oid = typ.typnamespace\n )\n select\n *\n from\n type_all as typ\n where\n typ.id in (\n select \"typeId\" from class\n union all\n select \"typeId\" from attribute\n union all\n select \"returnTypeId\" from procedure\n union all\n select unnest(\"argTypeIds\") from procedure\n union all\n -- If this type is a base type for *any* domain type, we will include it\n -- in our selection. This may mean we fetch more types than we need, but\n -- the alternative is to do some funky SQL recursion which would be hard\n -- code to read. So we prefer code readability over selecting like 3 or\n -- 4 less type rows.\n --\n -- We also do this for range sub types and array item types.\n select \"domainBaseTypeId\" from type_all\n union all\n select \"rangeSubTypeId\" from type_all\n union all\n select \"arrayItemTypeId\" from type_all\n )\n order by\n \"namespaceId\", \"name\"\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-constraint.html\n \"constraint\" as (\n select distinct on (con.conrelid, con.conkey, con.confrelid, con.confkey)\n 'constraint' as \"kind\",\n con.oid as \"id\",\n con.conname as \"name\",\n con.contype as \"type\",\n con.conrelid as \"classId\",\n nullif(con.confrelid, 0) as \"foreignClassId\",\n dsc.description as \"description\",\n con.conkey as \"keyAttributeNums\",\n con.confkey as \"foreignKeyAttributeNums\"\n from\n pg_catalog.pg_constraint as con\n inner join class on (con.conrelid = class.id)\n left join pg_catalog.pg_description as dsc on dsc.objoid = con.oid and dsc.classoid = 'pg_catalog.pg_constraint'::regclass\n where\n -- Only get constraints for classes we have selected.\n con.conrelid in (select \"id\" from class where \"namespaceId\" in (select \"id\" from namespace)) and\n case\n -- If this is a foreign key constraint, we want to ensure that the\n -- foreign class is also in the list of classes we have already\n -- selected.\n when con.contype = 'f' then con.confrelid in (select \"id\" from class where \"namespaceId\" in (select \"id\" from namespace))\n -- Otherwise, this should be true.\n else true\n end and\n -- We only want foreign key, primary key, and unique constraints. We\n -- made add support for more constraints in the future.\n con.contype in ('f', 'p', 'u')\n order by\n con.conrelid, con.conkey, con.confrelid, con.confkey, con.conname\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-extension.html\n \"extension\" as (\n select\n 'extension' as \"kind\",\n ext.oid as \"id\",\n ext.extname as \"name\",\n ext.extnamespace as \"namespaceId\",\n nsp.nspname as \"namespaceName\",\n ext.extrelocatable as \"relocatable\",\n ext.extversion as \"version\",\n ext.extconfig as \"configurationClassIds\",\n dsc.description as \"description\"\n from\n pg_catalog.pg_extension as ext\n left join pg_catalog.pg_description as dsc on dsc.objoid = ext.oid and dsc.classoid = 'pg_catalog.pg_extension'::regclass\n left join pg_catalog.pg_namespace as nsp on nsp.oid = ext.extnamespace\n order by\n ext.extname, ext.oid\n ),\n -- @see https://www.postgresql.org/docs/9.5/static/catalog-pg-index.html\n \"indexes\" as (\n select\n 'index' as \"kind\",\n idx.indexrelid as \"id\",\n idx_more.relname as \"name\",\n nsp.nspname as \"namespaceName\",\n idx.indrelid as \"classId\",\n idx.indnatts as \"numberOfAttributes\",\n idx.indisunique as \"isUnique\",\n idx.indisprimary as \"isPrimary\",\n idx.indimmediate as \"isImmediate\", -- enforce uniqueness immediately on insert\n idx.indisreplident as \"isReplicaIdentity\",\n idx.indisvalid as \"isValid\", -- if false, don't use for queries\n idx.indpred is not null as \"isPartial\", -- if true, index is not on on rows.\n idx.indkey as \"attributeNums\",\n am.amname as \"indexType\",\n ").concat(serverVersionNum >= 90600 ? " (\n select array_agg(pg_index_column_has_property(idx.indexrelid,n::int2,'asc'))\n from unnest(idx.indkey) with ordinality as ord(key,n)\n ) as \"attributePropertiesAsc\",\n (\n select array_agg(pg_index_column_has_property(idx.indexrelid,n::int2,'nulls_first'))\n from unnest(idx.indkey) with ordinality as ord(key,n)\n ) as \"attributePropertiesNullsFirst\"," : '', "\n dsc.description as \"description\"\n from\n pg_catalog.pg_index as idx\n inner join pg_catalog.pg_class idx_more on (idx.indexrelid = idx_more.oid)\n inner join class on (idx.indrelid = class.id)\n inner join pg_catalog.pg_namespace as nsp on (nsp.oid = idx_more.relnamespace)\n inner join pg_catalog.pg_am as am on (am.oid = idx_more.relam)\n left join pg_catalog.pg_description as dsc on dsc.objoid = idx.indexrelid and dsc.objsubid = 0 and dsc.classoid = 'pg_catalog.pg_class'::regclass\n where\n idx.indislive is not false and\n idx.indisexclusion is not true and -- exclusion index\n idx.indcheckxmin is not true and -- always valid?\n idx.indpred is null -- no partial index predicate\n order by\n idx.indrelid, idx.indexrelid\n )\n select row_to_json(x) as object from namespace as x\n union all\n select row_to_json(x) as object from class as x\n union all\n select row_to_json(x) as object from attribute as x\n union all\n select row_to_json(x) as object from type as x\n union all\n select row_to_json(x) as object from \"constraint\" as x\n union all\n select row_to_json(x) as object from procedure as x\n union all\n select row_to_json(x) as object from extension as x\n union all\n select row_to_json(x) as object from indexes as x\n ;\n ");
24
- };
25
-
26
- exports.makeIntrospectionQuery = makeIntrospectionQuery;
package/main/utils.js DELETED
@@ -1,64 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.deepClone = exports.parseTags = void 0;
9
-
10
- var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
-
12
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
-
14
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
-
16
- 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; }
17
-
18
- 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) { (0, _defineProperty2["default"])(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; }
19
-
20
- var parseTags = function parseTags(str) {
21
- return str.split(/\r?\n/).reduce(function (prev, curr) {
22
- if (prev.text !== '') {
23
- return _objectSpread(_objectSpread({}, prev), {}, {
24
- text: "".concat(prev.text, "\n").concat(curr)
25
- });
26
- }
27
-
28
- var match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\s)/);
29
-
30
- if (!match) {
31
- return _objectSpread(_objectSpread({}, prev), {}, {
32
- text: curr
33
- });
34
- }
35
-
36
- var key = match[0].substr(1).trim();
37
- var value = match[0] === curr ? true : curr.replace(match[0], '');
38
- return _objectSpread(_objectSpread({}, prev), {}, {
39
- tags: _objectSpread(_objectSpread({}, prev.tags), {}, (0, _defineProperty2["default"])({}, key, !Object.prototype.hasOwnProperty.call(prev.tags, key) ? value : Array.isArray(prev.tags[key]) ? [].concat((0, _toConsumableArray2["default"])(prev.tags[key]), [value]) : [prev.tags[key], value]))
40
- });
41
- }, {
42
- tags: {},
43
- text: ''
44
- });
45
- };
46
-
47
- exports.parseTags = parseTags;
48
-
49
- var deepClone = function deepClone(value) {
50
- if (Array.isArray(value)) {
51
- return value.map(function (val) {
52
- return deepClone(val);
53
- });
54
- } else if ((0, _typeof2["default"])(value) === 'object' && value) {
55
- return Object.keys(value).reduce(function (memo, k) {
56
- memo[k] = deepClone(value[k]);
57
- return memo;
58
- }, {});
59
- } else {
60
- return value;
61
- }
62
- };
63
-
64
- exports.deepClone = deepClone;