graphile-meta-schema 0.2.4 → 0.2.6
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 +3 -1
- package/README.md +101 -4
- package/belongs-to.d.ts +3 -0
- package/belongs-to.js +37 -0
- package/esm/belongs-to.js +35 -0
- package/esm/has.js +36 -0
- package/esm/index.js +503 -0
- package/esm/many-to-many.js +81 -0
- package/esm/types.js +1 -0
- package/has.d.ts +3 -0
- package/has.js +38 -0
- package/index.d.ts +4 -0
- package/index.js +509 -0
- package/many-to-many.d.ts +3 -0
- package/many-to-many.js +83 -0
- package/package.json +28 -43
- package/types.d.ts +105 -0
- package/types.js +2 -0
- package/main/index.js +0 -496
- package/main/many-to-many.js +0 -124
- package/module/index.js +0 -629
- package/module/many-to-many.js +0 -79
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
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