graphile-meta-schema 0.2.5 → 0.2.7

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/esm/index.js ADDED
@@ -0,0 +1,503 @@
1
+ import { gql, makeExtendSchemaPlugin } from 'graphile-utils';
2
+ import { getNamedType } from 'graphql';
3
+ import belongsTo from './belongs-to';
4
+ import has from './has';
5
+ import manyToMany from './many-to-many';
6
+ const GIS_TYPES = [
7
+ 'Geometry',
8
+ 'Point',
9
+ 'LineString',
10
+ 'Polygon',
11
+ 'MultiPoint',
12
+ 'MultiLineString',
13
+ 'MultiPolygon',
14
+ 'GeometryCollection'
15
+ ];
16
+ const TYPE_ALIASES = {
17
+ int8: 'bigint',
18
+ bool: 'boolean',
19
+ bpchar: 'char',
20
+ float8: 'float',
21
+ float4: 'real',
22
+ int4: 'int',
23
+ int2: 'smallint'
24
+ };
25
+ const aliasTypes = (typeName) => TYPE_ALIASES[typeName] ?? typeName;
26
+ const getTypeName = (graphQLType) => getNamedType(graphQLType).name;
27
+ const PgMetaschemaPlugin = makeExtendSchemaPlugin((build, schemaOptions) => {
28
+ const pgBuild = build;
29
+ const pgSchemaOptions = schemaOptions;
30
+ const introspection = pgBuild.pgIntrospectionResultsByKind;
31
+ const inflection = pgBuild.inflection;
32
+ const schemas = pgSchemaOptions.pgSchemas ?? [];
33
+ const pgGetGqlTypeByTypeIdAndModifier = pgBuild.pgGetGqlTypeByTypeIdAndModifier;
34
+ return {
35
+ typeDefs: gql `
36
+ type MetaschemaType {
37
+ pgAlias: String!
38
+ pgType: String!
39
+ gqlType: String!
40
+ subtype: String
41
+ modifier: Int
42
+ typmod: JSON
43
+ isArray: Boolean!
44
+ }
45
+ type MetaschemaField {
46
+ name: String!
47
+ type: MetaschemaType!
48
+ }
49
+ type MetaschemaTableInflection {
50
+ # https://github.com/graphile/graphile-engine/blob/v4/packages/graphile-build-pg/src/plugins/PgBasicsPlugin.js
51
+ allRows: String!
52
+ allRowsSimple: String!
53
+ tableFieldName: String!
54
+ tableType: String!
55
+ createPayloadType: String!
56
+ orderByType: String!
57
+ filterType: String
58
+ inputType: String!
59
+ patchType: String
60
+ conditionType: String!
61
+ patchField: String!
62
+ edge: String!
63
+ edgeField: String!
64
+ connection: String!
65
+ typeName: String!
66
+ enumType: String!
67
+
68
+ updatePayloadType: String
69
+ deletePayloadType: String!
70
+ deleteByPrimaryKey: String
71
+ updateByPrimaryKey: String
72
+
73
+ createField: String!
74
+ createInputType: String!
75
+ }
76
+ type MetaschemaTableQuery {
77
+ all: String!
78
+ one: String!
79
+ create: String!
80
+ update: String
81
+ delete: String
82
+ }
83
+ type MetaschemaTableManyToManyRelation {
84
+ fieldName: String
85
+ type: String
86
+ leftKeyAttributes: [MetaschemaField]!
87
+ rightKeyAttributes: [MetaschemaField]!
88
+ junctionLeftKeyAttributes: [MetaschemaField]!
89
+ junctionRightKeyAttributes: [MetaschemaField]!
90
+ junctionTable: MetaschemaTable!
91
+ rightTable: MetaschemaTable!
92
+ junctionLeftConstraint: MetaschemaForeignKeyConstraint!
93
+ junctionRightConstraint: MetaschemaForeignKeyConstraint!
94
+ }
95
+ type MetaschemaTableHasRelation {
96
+ fieldName: String
97
+ type: String
98
+ referencedBy: MetaschemaTable!
99
+ isUnique: Boolean!
100
+ keys: [MetaschemaField]
101
+ }
102
+ type MetaschemaTableBelongsToRelation {
103
+ fieldName: String
104
+ type: String
105
+ references: MetaschemaTable!
106
+ isUnique: Boolean!
107
+ keys: [MetaschemaField]
108
+ }
109
+ type MetaschemaTableRelation {
110
+ hasOne: [MetaschemaTableHasRelation]
111
+ hasMany: [MetaschemaTableHasRelation]
112
+ has: [MetaschemaTableHasRelation]
113
+ belongsTo: [MetaschemaTableBelongsToRelation]
114
+ manyToMany: [MetaschemaTableManyToManyRelation]
115
+ }
116
+
117
+ type MetaschemaTable {
118
+ name: String!
119
+ query: MetaschemaTableQuery!
120
+ inflection: MetaschemaTableInflection!
121
+ relations: MetaschemaTableRelation
122
+ fields: [MetaschemaField]
123
+ constraints: [MetaschemaConstraint]
124
+ foreignKeyConstraints: [MetaschemaForeignKeyConstraint]
125
+ primaryKeyConstraints: [MetaschemaPrimaryKeyConstraint]
126
+ uniqueConstraints: [MetaschemaUniqueConstraint]
127
+ checkConstraints: [MetaschemaCheckConstraint]
128
+ exclusionConstraints: [MetaschemaExclusionConstraint]
129
+ }
130
+ union MetaschemaConstraint =
131
+ MetaschemaForeignKeyConstraint
132
+ | MetaschemaUniqueConstraint
133
+ | MetaschemaPrimaryKeyConstraint
134
+ | MetaschemaCheckConstraint
135
+ | MetaschemaExclusionConstraint
136
+ type MetaschemaForeignKeyConstraint {
137
+ name: String!
138
+ fields: [MetaschemaField]
139
+ refTable: MetaschemaTable
140
+ refFields: [MetaschemaField]
141
+ }
142
+ type MetaschemaUniqueConstraint {
143
+ name: String!
144
+ fields: [MetaschemaField]
145
+ }
146
+ type MetaschemaPrimaryKeyConstraint {
147
+ name: String!
148
+ fields: [MetaschemaField]
149
+ }
150
+ type MetaschemaCheckConstraint {
151
+ name: String!
152
+ fields: [MetaschemaField]
153
+ }
154
+ type MetaschemaExclusionConstraint {
155
+ name: String!
156
+ fields: [MetaschemaField]
157
+ }
158
+ type Metaschema {
159
+ tables: [MetaschemaTable]
160
+ }
161
+ extend type Query {
162
+ _meta: Metaschema
163
+ }
164
+ `,
165
+ resolvers: {
166
+ MetaschemaCheckConstraint: {
167
+ fields(constraint) {
168
+ return constraint.keyAttributes;
169
+ }
170
+ },
171
+ MetaschemaExclusionConstraint: {
172
+ fields(constraint) {
173
+ return constraint.keyAttributes;
174
+ }
175
+ },
176
+ MetaschemaUniqueConstraint: {
177
+ fields(constraint) {
178
+ return constraint.keyAttributes;
179
+ }
180
+ },
181
+ MetaschemaPrimaryKeyConstraint: {
182
+ fields(constraint) {
183
+ return constraint.keyAttributes;
184
+ }
185
+ },
186
+ MetaschemaForeignKeyConstraint: {
187
+ fields(constraint) {
188
+ return constraint.keyAttributes;
189
+ },
190
+ refTable(constraint) {
191
+ return constraint.foreignClass;
192
+ },
193
+ refFields(constraint) {
194
+ return constraint.foreignKeyAttributes;
195
+ }
196
+ },
197
+ MetaschemaType: {
198
+ pgType(type) {
199
+ if (type.isPgArray && type.arrayItemType?.name) {
200
+ return type.arrayItemType.name;
201
+ }
202
+ return type.name;
203
+ },
204
+ pgAlias(type) {
205
+ if (type.isPgArray && type.arrayItemType?.name) {
206
+ return aliasTypes(type.arrayItemType.name);
207
+ }
208
+ return aliasTypes(type.name);
209
+ },
210
+ gqlType(type) {
211
+ const gqlType = pgGetGqlTypeByTypeIdAndModifier(type.id, type.attrTypeModifier ?? null);
212
+ const typeName = getTypeName(gqlType);
213
+ switch (typeName) {
214
+ case 'GeometryInterface':
215
+ case 'GeometryPoint':
216
+ case 'GeometryPolygon':
217
+ return 'GeoJSON';
218
+ default:
219
+ return typeName;
220
+ }
221
+ },
222
+ subtype(type) {
223
+ const gqlType = pgGetGqlTypeByTypeIdAndModifier(type.id, type.attrTypeModifier ?? null);
224
+ const typeName = getTypeName(gqlType);
225
+ switch (typeName) {
226
+ case 'GeometryInterface':
227
+ case 'GeometryPoint':
228
+ case 'GeometryPolygon':
229
+ return typeName;
230
+ default:
231
+ return null;
232
+ }
233
+ },
234
+ typmod(type) {
235
+ const modifier = type.attrTypeModifier;
236
+ if (!modifier)
237
+ return null;
238
+ if (type.name === 'geography' || type.name === 'geometry') {
239
+ const srid = ((modifier & 0x0fffff00) - (modifier & 0x10000000)) >> 8;
240
+ const subtype = (modifier & 0x000000fc) >> 2;
241
+ const hasZ = ((modifier & 0x00000002) >> 1) === 1;
242
+ const hasM = (modifier & 0x00000001) === 1;
243
+ if (subtype < GIS_TYPES.length) {
244
+ return {
245
+ srid,
246
+ subtype,
247
+ hasZ,
248
+ hasM,
249
+ gisType: GIS_TYPES[subtype]
250
+ };
251
+ }
252
+ }
253
+ return { modifier };
254
+ },
255
+ modifier(type) {
256
+ return type.attrTypeModifier;
257
+ },
258
+ isArray(type) {
259
+ return type.isPgArray;
260
+ }
261
+ },
262
+ MetaschemaField: {
263
+ name(attr) {
264
+ return inflection.column(attr);
265
+ },
266
+ type(attr) {
267
+ if (attr.typeModifier > 0) {
268
+ return {
269
+ ...attr.type,
270
+ attrTypeModifier: attr.typeModifier
271
+ };
272
+ }
273
+ return attr.type;
274
+ }
275
+ },
276
+ MetaschemaTableInflection: {
277
+ deleteByPrimaryKey(table) {
278
+ if (!table.primaryKeyConstraint?.keyAttributes?.length)
279
+ return null;
280
+ return inflection.deleteByKeys(table.primaryKeyConstraint.keyAttributes, table, table.primaryKeyConstraint);
281
+ },
282
+ updateByPrimaryKey(table) {
283
+ if (!table.primaryKeyConstraint?.keyAttributes?.length)
284
+ return null;
285
+ return inflection.updateByKeys(table.primaryKeyConstraint.keyAttributes, table, table.primaryKeyConstraint);
286
+ },
287
+ createField(table) {
288
+ return inflection.createField(table);
289
+ },
290
+ createInputType(table) {
291
+ return inflection.createInputType(table);
292
+ },
293
+ allRows(table) {
294
+ return inflection.allRows(table);
295
+ },
296
+ allRowsSimple(table) {
297
+ return inflection.allRowsSimple(table);
298
+ },
299
+ tableFieldName(table) {
300
+ return inflection.tableFieldName(table);
301
+ },
302
+ tableType(table) {
303
+ return inflection.tableType(table);
304
+ },
305
+ orderByType(table) {
306
+ return inflection.orderByType(inflection.tableType(table));
307
+ },
308
+ filterType(table) {
309
+ if (typeof inflection.filterType === 'function') {
310
+ return inflection.filterType(inflection.tableType(table)) ?? null;
311
+ }
312
+ return null;
313
+ },
314
+ inputType(table) {
315
+ return inflection.inputType(inflection.tableType(table));
316
+ },
317
+ patchType(table) {
318
+ return inflection.patchType(inflection.tableType(table));
319
+ },
320
+ conditionType(table) {
321
+ return inflection.conditionType(inflection.tableType(table));
322
+ },
323
+ patchField(table) {
324
+ return inflection.patchField(inflection.tableType(table));
325
+ },
326
+ edge(table) {
327
+ return inflection.edge(inflection.tableType(table));
328
+ },
329
+ edgeField(table) {
330
+ return inflection.edgeField(table);
331
+ },
332
+ connection(table) {
333
+ return inflection.connection(inflection.tableType(table));
334
+ },
335
+ typeName(table) {
336
+ return inflection._typeName(table);
337
+ },
338
+ enumType(table) {
339
+ return inflection.enumType(table);
340
+ },
341
+ createPayloadType(table) {
342
+ return inflection.createPayloadType(table);
343
+ },
344
+ updatePayloadType(table) {
345
+ return inflection.updatePayloadType(table);
346
+ },
347
+ deletePayloadType(table) {
348
+ return inflection.deletePayloadType(table);
349
+ }
350
+ },
351
+ MetaschemaTableQuery: {
352
+ delete(table) {
353
+ if (!table.primaryKeyConstraint?.keyAttributes?.length)
354
+ return null;
355
+ return inflection.deleteByKeys(table.primaryKeyConstraint.keyAttributes, table, table.primaryKeyConstraint);
356
+ },
357
+ update(table) {
358
+ if (!table.primaryKeyConstraint?.keyAttributes?.length)
359
+ return null;
360
+ return inflection.updateByKeys(table.primaryKeyConstraint.keyAttributes, table, table.primaryKeyConstraint);
361
+ },
362
+ create(table) {
363
+ return inflection.createField(table);
364
+ },
365
+ all(table) {
366
+ return inflection.allRows(table);
367
+ },
368
+ one(table) {
369
+ return inflection.tableFieldName(table);
370
+ }
371
+ },
372
+ MetaschemaTableRelation: {
373
+ hasOne(table) {
374
+ return has(table, pgBuild).filter((relation) => relation.type === 'hasOne');
375
+ },
376
+ hasMany(table) {
377
+ return has(table, pgBuild).filter((relation) => relation.type === 'hasMany');
378
+ },
379
+ belongsTo(table) {
380
+ return belongsTo(table, pgBuild);
381
+ },
382
+ has(table) {
383
+ return has(table, pgBuild);
384
+ },
385
+ manyToMany(table) {
386
+ return manyToMany(table, pgBuild);
387
+ }
388
+ },
389
+ MetaschemaTableBelongsToRelation: {
390
+ type() {
391
+ return 'BelongsTo';
392
+ }
393
+ },
394
+ MetaschemaTableManyToManyRelation: {
395
+ type() {
396
+ return 'ManyToMany';
397
+ },
398
+ leftKeyAttributes(relation) {
399
+ return relation.leftKeyAttributes;
400
+ },
401
+ junctionLeftKeyAttributes(relation) {
402
+ return relation.junctionLeftKeyAttributes;
403
+ },
404
+ junctionRightKeyAttributes(relation) {
405
+ return relation.junctionRightKeyAttributes;
406
+ },
407
+ rightKeyAttributes(relation) {
408
+ return relation.rightKeyAttributes;
409
+ },
410
+ junctionTable(relation) {
411
+ return relation.junctionTable;
412
+ },
413
+ rightTable(relation) {
414
+ return relation.rightTable;
415
+ },
416
+ junctionLeftConstraint(relation) {
417
+ return relation.junctionLeftConstraint;
418
+ },
419
+ junctionRightConstraint(relation) {
420
+ return relation.junctionRightConstraint;
421
+ },
422
+ fieldName(relation) {
423
+ if (!inflection.manyToManyRelationByKeys) {
424
+ return null;
425
+ }
426
+ const { leftKeyAttributes, junctionLeftKeyAttributes, junctionRightKeyAttributes, rightKeyAttributes, junctionTable, rightTable, junctionLeftConstraint, junctionRightConstraint } = relation;
427
+ return inflection.manyToManyRelationByKeys(leftKeyAttributes, junctionLeftKeyAttributes, junctionRightKeyAttributes, rightKeyAttributes, junctionTable, rightTable, junctionLeftConstraint, junctionRightConstraint);
428
+ }
429
+ },
430
+ MetaschemaTable: {
431
+ relations(table) {
432
+ return table;
433
+ },
434
+ name(table) {
435
+ return inflection.tableType(table);
436
+ },
437
+ fields(table) {
438
+ return table.attributes.filter((attr) => attr.num >= 1);
439
+ },
440
+ inflection(table) {
441
+ return table;
442
+ },
443
+ query(table) {
444
+ return table;
445
+ },
446
+ constraints(table) {
447
+ return table.constraints;
448
+ },
449
+ foreignKeyConstraints(table) {
450
+ return table.constraints.filter((constraint) => constraint.type === 'f');
451
+ },
452
+ primaryKeyConstraints(table) {
453
+ return table.constraints.filter((constraint) => constraint.type === 'p');
454
+ },
455
+ uniqueConstraints(table) {
456
+ return table.constraints.filter((constraint) => constraint.type === 'u');
457
+ },
458
+ checkConstraints(table) {
459
+ return table.constraints.filter((constraint) => constraint.type === 'c');
460
+ },
461
+ exclusionConstraints(table) {
462
+ return table.constraints.filter((constraint) => constraint.type === 'x');
463
+ }
464
+ },
465
+ MetaschemaConstraint: {
466
+ __resolveType(obj) {
467
+ switch (obj.type) {
468
+ case 'p':
469
+ return 'MetaschemaPrimaryKeyConstraint';
470
+ case 'f':
471
+ return 'MetaschemaForeignKeyConstraint';
472
+ case 'c':
473
+ return 'MetaschemaCheckConstraint';
474
+ case 'u':
475
+ return 'MetaschemaUniqueConstraint';
476
+ case 'x':
477
+ return 'MetaschemaExclusionConstraint';
478
+ default:
479
+ return null;
480
+ }
481
+ }
482
+ },
483
+ Metaschema: {
484
+ tables() {
485
+ return introspection.class.filter((table) => {
486
+ if (!schemas.includes(table.namespaceName))
487
+ return false;
488
+ if (table.classKind !== 'r')
489
+ return false;
490
+ return true;
491
+ });
492
+ }
493
+ },
494
+ Query: {
495
+ _meta() {
496
+ return {};
497
+ }
498
+ }
499
+ }
500
+ };
501
+ });
502
+ export { PgMetaschemaPlugin };
503
+ export default PgMetaschemaPlugin;
@@ -0,0 +1,81 @@
1
+ const arraysAreEqual = (array1, array2) => array1.length === array2.length && array1.every((value, index) => array2[index] === value);
2
+ const getManyToManyRelations = (leftTable, build) => {
3
+ const { pgIntrospectionResultsByKind: introspectionResultsByKind, pgOmit: omit } = build;
4
+ return leftTable.foreignConstraints
5
+ .filter((constraint) => constraint.type === 'f')
6
+ .reduce((memoLeft, junctionLeftConstraint) => {
7
+ if (omit(junctionLeftConstraint, 'read') ||
8
+ omit(junctionLeftConstraint, 'manyToMany')) {
9
+ return memoLeft;
10
+ }
11
+ const junctionTable = introspectionResultsByKind.classById[String(junctionLeftConstraint.classId)] ??
12
+ junctionLeftConstraint.foreignClass;
13
+ if (!junctionTable) {
14
+ throw new Error(`Could not find the table that referenced us (constraint: ${junctionLeftConstraint.name})`);
15
+ }
16
+ if (omit(junctionTable, 'read') || omit(junctionTable, 'manyToMany')) {
17
+ return memoLeft;
18
+ }
19
+ const memoRight = junctionTable.constraints
20
+ .filter((constraint) => constraint.id !== junctionLeftConstraint.id &&
21
+ constraint.type === 'f' &&
22
+ !omit(constraint, 'read') &&
23
+ !omit(constraint, 'manyToMany'))
24
+ .reduce((memoRightInner, junctionRightConstraint) => {
25
+ const rightTable = junctionRightConstraint.foreignClass ??
26
+ (junctionRightConstraint.foreignClassId !== undefined
27
+ ? introspectionResultsByKind.classById[String(junctionRightConstraint.foreignClassId)]
28
+ : undefined);
29
+ if (!rightTable || omit(rightTable, 'read') || omit(rightTable, 'manyToMany')) {
30
+ return memoRightInner;
31
+ }
32
+ const leftKeyAttributes = junctionLeftConstraint.foreignKeyAttributes;
33
+ const junctionLeftKeyAttributes = junctionLeftConstraint.keyAttributes;
34
+ const junctionRightKeyAttributes = junctionRightConstraint.keyAttributes;
35
+ const rightKeyAttributes = junctionRightConstraint.foreignKeyAttributes;
36
+ if (!leftKeyAttributes.every(Boolean) ||
37
+ !junctionLeftKeyAttributes.every(Boolean) ||
38
+ !junctionRightKeyAttributes.every(Boolean) ||
39
+ !rightKeyAttributes.every(Boolean)) {
40
+ throw new Error('Could not find key columns!');
41
+ }
42
+ if (leftKeyAttributes.some((attr) => omit(attr, 'read')) ||
43
+ junctionLeftKeyAttributes.some((attr) => omit(attr, 'read')) ||
44
+ junctionRightKeyAttributes.some((attr) => omit(attr, 'read')) ||
45
+ rightKeyAttributes.some((attr) => omit(attr, 'read'))) {
46
+ return memoRightInner;
47
+ }
48
+ if (leftKeyAttributes.length > 1 || rightKeyAttributes.length > 1) {
49
+ return memoRightInner;
50
+ }
51
+ const junctionLeftConstraintIsUnique = junctionTable.constraints.some((constraint) => ['p', 'u'].includes(constraint.type) &&
52
+ arraysAreEqual(constraint.keyAttributeNums, junctionLeftKeyAttributes.map((attr) => attr.num)));
53
+ const junctionRightConstraintIsUnique = junctionTable.constraints.some((constraint) => ['p', 'u'].includes(constraint.type) &&
54
+ arraysAreEqual(constraint.keyAttributeNums, junctionRightKeyAttributes.map((attr) => attr.num)));
55
+ if (junctionLeftConstraintIsUnique || junctionRightConstraintIsUnique) {
56
+ return memoRightInner;
57
+ }
58
+ const allowsMultipleEdgesToNode = !junctionTable.constraints.find((constraint) => ['p', 'u'].includes(constraint.type) &&
59
+ arraysAreEqual(constraint.keyAttributeNums.concat().sort(), [
60
+ ...junctionLeftKeyAttributes.map((attr) => attr.num),
61
+ ...junctionRightKeyAttributes.map((attr) => attr.num)
62
+ ].sort()));
63
+ return [
64
+ ...memoRightInner,
65
+ {
66
+ leftKeyAttributes,
67
+ junctionLeftKeyAttributes,
68
+ junctionRightKeyAttributes,
69
+ rightKeyAttributes,
70
+ junctionTable,
71
+ rightTable,
72
+ junctionLeftConstraint,
73
+ junctionRightConstraint,
74
+ allowsMultipleEdgesToNode
75
+ }
76
+ ];
77
+ }, []);
78
+ return [...memoLeft, ...memoRight];
79
+ }, []);
80
+ };
81
+ export default getManyToManyRelations;
package/esm/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/has.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { HasRelation, PgBuild, PgClass } from './types';
2
+ declare const getHasRelations: (foreignTable: PgClass, build: PgBuild) => HasRelation[];
3
+ export default getHasRelations;
package/has.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const getHasRelations = (foreignTable, build) => {
4
+ const { pgIntrospectionResultsByKind: introspectionResultsByKind, inflection, pgOmit: omit } = build;
5
+ return foreignTable.foreignConstraints
6
+ .filter((constraint) => constraint.type === 'f')
7
+ .reduce((memo, constraint) => {
8
+ if (omit(constraint, 'read')) {
9
+ return memo;
10
+ }
11
+ const table = introspectionResultsByKind.classById[String(constraint.classId)] ?? constraint.foreignClass;
12
+ if (!table || omit(table, 'read')) {
13
+ return memo;
14
+ }
15
+ const keys = constraint.keyAttributes;
16
+ const foreignKeys = constraint.foreignKeyAttributes;
17
+ if (keys.some((key) => omit(key, 'read')) || foreignKeys.some((key) => omit(key, 'read'))) {
18
+ return memo;
19
+ }
20
+ const isUnique = table.constraints.some((c) => (c.type === 'p' || c.type === 'u') &&
21
+ c.keyAttributeNums.length === keys.length &&
22
+ c.keyAttributeNums.every((n, i) => keys[i].num === n));
23
+ const fieldName = isUnique
24
+ ? inflection.singleRelationByKeysBackwards(keys, table, foreignTable, constraint)
25
+ : inflection.manyRelationByKeys(keys, table, foreignTable, constraint);
26
+ return [
27
+ ...memo,
28
+ {
29
+ referencedBy: table,
30
+ isUnique,
31
+ fieldName,
32
+ type: isUnique ? 'hasOne' : 'hasMany',
33
+ keys
34
+ }
35
+ ];
36
+ }, []);
37
+ };
38
+ exports.default = getHasRelations;
package/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from 'graphile-build';
2
+ declare const PgMetaschemaPlugin: Plugin;
3
+ export { PgMetaschemaPlugin };
4
+ export default PgMetaschemaPlugin;