@constructive-io/graphql-codegen 4.6.1 → 4.7.0
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/client/error.d.ts +2 -93
- package/client/error.js +9 -273
- package/client/execute.d.ts +2 -55
- package/client/execute.js +5 -120
- package/client/typed-document.d.ts +2 -29
- package/client/typed-document.js +3 -39
- package/core/ast.d.ts +8 -10
- package/core/ast.js +17 -592
- package/core/custom-ast.d.ts +5 -33
- package/core/custom-ast.js +16 -203
- package/core/introspect/infer-tables.d.ts +2 -40
- package/core/introspect/infer-tables.js +4 -696
- package/core/introspect/schema-query.d.ts +3 -18
- package/core/introspect/schema-query.js +3 -118
- package/core/introspect/transform-schema.d.ts +2 -84
- package/core/introspect/transform-schema.js +14 -279
- package/core/introspect/transform.d.ts +2 -18
- package/core/introspect/transform.js +6 -39
- package/core/meta-object/convert.d.ts +2 -63
- package/core/meta-object/convert.js +4 -59
- package/core/meta-object/validate.d.ts +2 -7
- package/core/meta-object/validate.js +4 -30
- package/core/query-builder.d.ts +7 -46
- package/core/query-builder.js +8 -408
- package/core/types.d.ts +9 -139
- package/core/types.js +12 -26
- package/esm/client/error.d.ts +2 -93
- package/esm/client/error.js +2 -269
- package/esm/client/execute.d.ts +2 -55
- package/esm/client/execute.js +2 -118
- package/esm/client/typed-document.d.ts +2 -29
- package/esm/client/typed-document.js +2 -38
- package/esm/core/ast.d.ts +8 -10
- package/esm/core/ast.js +8 -550
- package/esm/core/custom-ast.d.ts +5 -33
- package/esm/core/custom-ast.js +5 -160
- package/esm/core/introspect/infer-tables.d.ts +2 -40
- package/esm/core/introspect/infer-tables.js +2 -695
- package/esm/core/introspect/schema-query.d.ts +3 -18
- package/esm/core/introspect/schema-query.js +2 -118
- package/esm/core/introspect/transform-schema.d.ts +2 -84
- package/esm/core/introspect/transform-schema.js +2 -269
- package/esm/core/introspect/transform.d.ts +2 -18
- package/esm/core/introspect/transform.js +2 -36
- package/esm/core/meta-object/convert.d.ts +2 -63
- package/esm/core/meta-object/convert.js +2 -58
- package/esm/core/meta-object/validate.d.ts +2 -7
- package/esm/core/meta-object/validate.js +2 -26
- package/esm/core/query-builder.d.ts +7 -46
- package/esm/core/query-builder.js +5 -373
- package/esm/core/types.d.ts +9 -139
- package/esm/core/types.js +9 -24
- package/esm/generators/field-selector.d.ts +5 -28
- package/esm/generators/field-selector.js +5 -379
- package/esm/generators/mutations.d.ts +5 -28
- package/esm/generators/mutations.js +5 -198
- package/esm/generators/naming-helpers.d.ts +3 -45
- package/esm/generators/naming-helpers.js +3 -151
- package/esm/generators/select.d.ts +6 -37
- package/esm/generators/select.js +6 -659
- package/generators/field-selector.d.ts +5 -28
- package/generators/field-selector.js +12 -385
- package/generators/mutations.d.ts +5 -28
- package/generators/mutations.js +9 -234
- package/generators/naming-helpers.d.ts +3 -45
- package/generators/naming-helpers.js +15 -164
- package/generators/select.d.ts +6 -37
- package/generators/select.js +17 -703
- package/package.json +7 -6
- package/core/meta-object/format.json +0 -93
- package/esm/core/meta-object/format.json +0 -93
|
@@ -1,60 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Re-export meta-object conversion from @constructive-io/graphql-query.
|
|
3
3
|
*/
|
|
4
|
-
export
|
|
5
|
-
const { _meta: { tables }, } = metaSchema;
|
|
6
|
-
const result = {
|
|
7
|
-
tables: [],
|
|
8
|
-
};
|
|
9
|
-
for (const table of tables) {
|
|
10
|
-
result.tables.push({
|
|
11
|
-
name: table.name,
|
|
12
|
-
fields: table.fields.map((f) => pickField(f)),
|
|
13
|
-
primaryConstraints: pickArrayConstraint(table.primaryKeyConstraints),
|
|
14
|
-
uniqueConstraints: pickArrayConstraint(table.uniqueConstraints),
|
|
15
|
-
foreignConstraints: pickForeignConstraint(table.foreignKeyConstraints, table.relations),
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
function pickArrayConstraint(constraints) {
|
|
21
|
-
if (constraints.length === 0)
|
|
22
|
-
return [];
|
|
23
|
-
const c = constraints[0];
|
|
24
|
-
return c.fields.map((field) => pickConstraintField(field));
|
|
25
|
-
}
|
|
26
|
-
function pickForeignConstraint(constraints, relations) {
|
|
27
|
-
if (constraints.length === 0)
|
|
28
|
-
return [];
|
|
29
|
-
const { belongsTo } = relations;
|
|
30
|
-
return constraints.map((c) => {
|
|
31
|
-
const { fields, refFields, refTable } = c;
|
|
32
|
-
const fromKey = pickField(fields[0]);
|
|
33
|
-
const toKey = pickField(refFields[0]);
|
|
34
|
-
const matchingBelongsTo = belongsTo.find((belongsToItem) => {
|
|
35
|
-
const field = pickField(belongsToItem.keys[0]);
|
|
36
|
-
return field.name === fromKey.name;
|
|
37
|
-
});
|
|
38
|
-
// Ex: 'ownerId' will have an alias of 'owner', which has further selection of 'User' type
|
|
39
|
-
if (matchingBelongsTo) {
|
|
40
|
-
fromKey.alias = matchingBelongsTo.fieldName;
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
refTable: refTable.name,
|
|
44
|
-
fromKey,
|
|
45
|
-
toKey,
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function pickField(field) {
|
|
50
|
-
return {
|
|
51
|
-
name: field.name,
|
|
52
|
-
type: field.type,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function pickConstraintField(field) {
|
|
56
|
-
return {
|
|
57
|
-
name: field.name,
|
|
58
|
-
type: field.type,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
4
|
+
export { convertFromMetaSchema } from '@constructive-io/graphql-query';
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
export interface ValidationResult {
|
|
2
|
-
errors: unknown[] | null | undefined;
|
|
3
|
-
message: string;
|
|
4
|
-
}
|
|
5
1
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @returns true if valid, or an object with errors and message if invalid
|
|
2
|
+
* Re-export meta-object validation from @constructive-io/graphql-query.
|
|
8
3
|
*/
|
|
9
|
-
export
|
|
4
|
+
export { validateMetaObject, type ValidationResult, } from '@constructive-io/graphql-query';
|
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
import Ajv from 'ajv';
|
|
2
|
-
import format from './format.json';
|
|
3
|
-
let cachedAjv = null;
|
|
4
|
-
let cachedValidator = null;
|
|
5
|
-
function getValidator() {
|
|
6
|
-
if (!cachedAjv) {
|
|
7
|
-
cachedAjv = new Ajv({ allErrors: true });
|
|
8
|
-
cachedValidator = cachedAjv.compile(format);
|
|
9
|
-
}
|
|
10
|
-
return {
|
|
11
|
-
ajv: cachedAjv,
|
|
12
|
-
validator: cachedValidator,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
1
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @returns true if valid, or an object with errors and message if invalid
|
|
2
|
+
* Re-export meta-object validation from @constructive-io/graphql-query.
|
|
18
3
|
*/
|
|
19
|
-
export
|
|
20
|
-
const { ajv, validator } = getValidator();
|
|
21
|
-
const valid = validator(obj);
|
|
22
|
-
if (valid)
|
|
23
|
-
return true;
|
|
24
|
-
return {
|
|
25
|
-
errors: validator.errors,
|
|
26
|
-
message: ajv.errorsText(validator.errors, { separator: '\n' }),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
4
|
+
export { validateMetaObject, } from '@constructive-io/graphql-query';
|
|
@@ -1,46 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
private _key;
|
|
9
|
-
private _queryName;
|
|
10
|
-
private _ast;
|
|
11
|
-
_edges: boolean;
|
|
12
|
-
private _op;
|
|
13
|
-
private _mutation;
|
|
14
|
-
private _select;
|
|
15
|
-
constructor({ meta, introspection }: QueryBuilderOptions);
|
|
16
|
-
initModelMap(): void;
|
|
17
|
-
clear(): void;
|
|
18
|
-
query(model: string): QueryBuilder;
|
|
19
|
-
_findQuery(): string;
|
|
20
|
-
_findMutation(): string;
|
|
21
|
-
select(selection?: QuerySelectionOptions | null): QueryBuilder;
|
|
22
|
-
edges(useEdges: boolean): QueryBuilder;
|
|
23
|
-
getMany({ select }?: {
|
|
24
|
-
select?: QuerySelectionOptions;
|
|
25
|
-
}): QueryBuilder;
|
|
26
|
-
all({ select }?: {
|
|
27
|
-
select?: QuerySelectionOptions;
|
|
28
|
-
}): QueryBuilder;
|
|
29
|
-
count(): QueryBuilder;
|
|
30
|
-
getOne({ select }?: {
|
|
31
|
-
select?: QuerySelectionOptions;
|
|
32
|
-
}): QueryBuilder;
|
|
33
|
-
create({ select }?: {
|
|
34
|
-
select?: QuerySelectionOptions;
|
|
35
|
-
}): QueryBuilder;
|
|
36
|
-
delete({ select }?: {
|
|
37
|
-
select?: QuerySelectionOptions;
|
|
38
|
-
}): QueryBuilder;
|
|
39
|
-
update({ select }?: {
|
|
40
|
-
select?: QuerySelectionOptions;
|
|
41
|
-
}): QueryBuilder;
|
|
42
|
-
queryName(name: string): QueryBuilder;
|
|
43
|
-
print(): QueryBuilderResult;
|
|
44
|
-
pickScalarFields: (selection: QuerySelectionOptions | null, defn: QueryDefinition) => QueryFieldSelection[];
|
|
45
|
-
pickAllFields: (selection: QuerySelectionOptions, defn: QueryDefinition) => QueryFieldSelection[];
|
|
46
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Re-export QueryBuilder from @constructive-io/graphql-query.
|
|
3
|
+
*
|
|
4
|
+
* The QueryBuilder class and MetaObject namespace now live in graphql-query.
|
|
5
|
+
* Re-exported here for backward compatibility.
|
|
6
|
+
*/
|
|
7
|
+
export { QueryBuilder, MetaObject } from '@constructive-io/graphql-query';
|
|
@@ -1,375 +1,7 @@
|
|
|
1
|
-
import { print as gqlPrint } from 'graphql';
|
|
2
|
-
import { camelize, pluralize, underscore } from 'inflekt';
|
|
3
|
-
import { createOne, deleteOne, getAll, getCount, getMany, getOne, patchOne, } from './ast';
|
|
4
|
-
import { validateMetaObject } from './meta-object';
|
|
5
|
-
export * as MetaObject from './meta-object';
|
|
6
|
-
const isObject = (val) => val !== null && typeof val === 'object';
|
|
7
|
-
export class QueryBuilder {
|
|
8
|
-
_introspection;
|
|
9
|
-
_meta;
|
|
10
|
-
_models;
|
|
11
|
-
_model;
|
|
12
|
-
_key;
|
|
13
|
-
_queryName;
|
|
14
|
-
_ast;
|
|
15
|
-
_edges;
|
|
16
|
-
_op;
|
|
17
|
-
_mutation;
|
|
18
|
-
_select;
|
|
19
|
-
constructor({ meta = {}, introspection }) {
|
|
20
|
-
this._introspection = introspection;
|
|
21
|
-
this._meta = meta;
|
|
22
|
-
this.clear();
|
|
23
|
-
this.initModelMap();
|
|
24
|
-
this.pickScalarFields = pickScalarFields.bind(this);
|
|
25
|
-
this.pickAllFields = pickAllFields.bind(this);
|
|
26
|
-
const result = validateMetaObject(this._meta);
|
|
27
|
-
if (typeof result === 'object' && result.errors) {
|
|
28
|
-
throw new Error(`QueryBuilder: meta object is invalid:\n${result.message}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/*
|
|
32
|
-
* Save all gql queries and mutations by model name for quicker lookup
|
|
33
|
-
*/
|
|
34
|
-
initModelMap() {
|
|
35
|
-
this._models = {};
|
|
36
|
-
for (const [key, defn] of Object.entries(this._introspection)) {
|
|
37
|
-
if (!this._models[defn.model]) {
|
|
38
|
-
this._models[defn.model] = {};
|
|
39
|
-
}
|
|
40
|
-
this._models[defn.model][key] = defn;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
clear() {
|
|
44
|
-
this._model = '';
|
|
45
|
-
this._key = null;
|
|
46
|
-
this._queryName = '';
|
|
47
|
-
this._ast = null;
|
|
48
|
-
this._edges = false;
|
|
49
|
-
this._op = '';
|
|
50
|
-
this._mutation = '';
|
|
51
|
-
this._select = [];
|
|
52
|
-
}
|
|
53
|
-
query(model) {
|
|
54
|
-
this.clear();
|
|
55
|
-
this._model = model;
|
|
56
|
-
return this;
|
|
57
|
-
}
|
|
58
|
-
_findQuery() {
|
|
59
|
-
// based on the op, finds the relevant GQL query
|
|
60
|
-
const queries = this._models[this._model];
|
|
61
|
-
if (!queries) {
|
|
62
|
-
throw new Error('No queries found for ' + this._model);
|
|
63
|
-
}
|
|
64
|
-
const matchQuery = Object.entries(queries).find(([_, defn]) => defn.qtype === this._op);
|
|
65
|
-
if (!matchQuery) {
|
|
66
|
-
throw new Error('No query found for ' + this._model + ':' + this._op);
|
|
67
|
-
}
|
|
68
|
-
const queryKey = matchQuery[0];
|
|
69
|
-
return queryKey;
|
|
70
|
-
}
|
|
71
|
-
_findMutation() {
|
|
72
|
-
// For mutation, there can be many defns that match the operation being requested
|
|
73
|
-
// .ie: deleteAction, deleteActionBySlug, deleteActionByName
|
|
74
|
-
const matchingDefns = Object.keys(this._introspection).reduce((arr, mutationKey) => {
|
|
75
|
-
const defn = this._introspection[mutationKey];
|
|
76
|
-
if (defn.model === this._model &&
|
|
77
|
-
defn.qtype === this._op &&
|
|
78
|
-
defn.qtype === 'mutation' &&
|
|
79
|
-
defn.mutationType === this._mutation) {
|
|
80
|
-
arr = [...arr, { defn, mutationKey }];
|
|
81
|
-
}
|
|
82
|
-
return arr;
|
|
83
|
-
}, []);
|
|
84
|
-
if (matchingDefns.length === 0) {
|
|
85
|
-
throw new Error('no mutation found for ' + this._model + ':' + this._mutation);
|
|
86
|
-
}
|
|
87
|
-
// We only need deleteAction from all of [deleteAction, deleteActionBySlug, deleteActionByName]
|
|
88
|
-
const getInputName = (mutationType) => {
|
|
89
|
-
switch (mutationType) {
|
|
90
|
-
case 'delete': {
|
|
91
|
-
return `Delete${camelize(this._model)}Input`;
|
|
92
|
-
}
|
|
93
|
-
case 'create': {
|
|
94
|
-
return `Create${camelize(this._model)}Input`;
|
|
95
|
-
}
|
|
96
|
-
case 'patch': {
|
|
97
|
-
return `Update${camelize(this._model)}Input`;
|
|
98
|
-
}
|
|
99
|
-
default:
|
|
100
|
-
throw new Error('Unhandled mutation type' + mutationType);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
const matchDefn = matchingDefns.find(({ defn }) => defn.properties.input.type === getInputName(this._mutation));
|
|
104
|
-
if (!matchDefn) {
|
|
105
|
-
throw new Error('no mutation found for ' + this._model + ':' + this._mutation);
|
|
106
|
-
}
|
|
107
|
-
return matchDefn.mutationKey;
|
|
108
|
-
}
|
|
109
|
-
select(selection) {
|
|
110
|
-
const defn = this._introspection[this._key];
|
|
111
|
-
// If selection not given, pick only scalar fields
|
|
112
|
-
if (selection == null) {
|
|
113
|
-
this._select = this.pickScalarFields(null, defn);
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
this._select = this.pickAllFields(selection, defn);
|
|
117
|
-
return this;
|
|
118
|
-
}
|
|
119
|
-
edges(useEdges) {
|
|
120
|
-
this._edges = useEdges;
|
|
121
|
-
return this;
|
|
122
|
-
}
|
|
123
|
-
getMany({ select } = {}) {
|
|
124
|
-
this._op = 'getMany';
|
|
125
|
-
this._key = this._findQuery();
|
|
126
|
-
this.queryName(camelize(['get', underscore(this._key), 'query'].join('_'), true));
|
|
127
|
-
const defn = this._introspection[this._key];
|
|
128
|
-
this.select(select);
|
|
129
|
-
this._ast = getMany({
|
|
130
|
-
builder: this,
|
|
131
|
-
queryName: this._queryName,
|
|
132
|
-
operationName: this._key,
|
|
133
|
-
query: defn,
|
|
134
|
-
selection: this._select,
|
|
135
|
-
});
|
|
136
|
-
return this;
|
|
137
|
-
}
|
|
138
|
-
all({ select } = {}) {
|
|
139
|
-
this._op = 'getMany';
|
|
140
|
-
this._key = this._findQuery();
|
|
141
|
-
this.queryName(camelize(['get', underscore(this._key), 'query', 'all'].join('_'), true));
|
|
142
|
-
const defn = this._introspection[this._key];
|
|
143
|
-
this.select(select);
|
|
144
|
-
this._ast = getAll({
|
|
145
|
-
queryName: this._queryName,
|
|
146
|
-
operationName: this._key,
|
|
147
|
-
query: defn,
|
|
148
|
-
selection: this._select,
|
|
149
|
-
});
|
|
150
|
-
return this;
|
|
151
|
-
}
|
|
152
|
-
count() {
|
|
153
|
-
this._op = 'getMany';
|
|
154
|
-
this._key = this._findQuery();
|
|
155
|
-
this.queryName(camelize(['get', underscore(this._key), 'count', 'query'].join('_'), true));
|
|
156
|
-
const defn = this._introspection[this._key];
|
|
157
|
-
this._ast = getCount({
|
|
158
|
-
queryName: this._queryName,
|
|
159
|
-
operationName: this._key,
|
|
160
|
-
query: defn,
|
|
161
|
-
});
|
|
162
|
-
return this;
|
|
163
|
-
}
|
|
164
|
-
getOne({ select } = {}) {
|
|
165
|
-
this._op = 'getOne';
|
|
166
|
-
this._key = this._findQuery();
|
|
167
|
-
this.queryName(camelize(['get', underscore(this._key), 'query'].join('_'), true));
|
|
168
|
-
const defn = this._introspection[this._key];
|
|
169
|
-
this.select(select);
|
|
170
|
-
this._ast = getOne({
|
|
171
|
-
builder: this,
|
|
172
|
-
queryName: this._queryName,
|
|
173
|
-
operationName: this._key,
|
|
174
|
-
query: defn,
|
|
175
|
-
selection: this._select,
|
|
176
|
-
});
|
|
177
|
-
return this;
|
|
178
|
-
}
|
|
179
|
-
create({ select } = {}) {
|
|
180
|
-
this._op = 'mutation';
|
|
181
|
-
this._mutation = 'create';
|
|
182
|
-
this._key = this._findMutation();
|
|
183
|
-
this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
|
|
184
|
-
const defn = this._introspection[this._key];
|
|
185
|
-
this.select(select);
|
|
186
|
-
this._ast = createOne({
|
|
187
|
-
operationName: this._key,
|
|
188
|
-
mutationName: this._queryName,
|
|
189
|
-
mutation: defn,
|
|
190
|
-
selection: this._select,
|
|
191
|
-
});
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
delete({ select } = {}) {
|
|
195
|
-
this._op = 'mutation';
|
|
196
|
-
this._mutation = 'delete';
|
|
197
|
-
this._key = this._findMutation();
|
|
198
|
-
this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
|
|
199
|
-
const defn = this._introspection[this._key];
|
|
200
|
-
this.select(select);
|
|
201
|
-
this._ast = deleteOne({
|
|
202
|
-
operationName: this._key,
|
|
203
|
-
mutationName: this._queryName,
|
|
204
|
-
mutation: defn,
|
|
205
|
-
});
|
|
206
|
-
return this;
|
|
207
|
-
}
|
|
208
|
-
update({ select } = {}) {
|
|
209
|
-
this._op = 'mutation';
|
|
210
|
-
this._mutation = 'patch';
|
|
211
|
-
this._key = this._findMutation();
|
|
212
|
-
this.queryName(camelize([underscore(this._key), 'mutation'].join('_'), true));
|
|
213
|
-
const defn = this._introspection[this._key];
|
|
214
|
-
this.select(select);
|
|
215
|
-
this._ast = patchOne({
|
|
216
|
-
operationName: this._key,
|
|
217
|
-
mutationName: this._queryName,
|
|
218
|
-
mutation: defn,
|
|
219
|
-
selection: this._select,
|
|
220
|
-
});
|
|
221
|
-
return this;
|
|
222
|
-
}
|
|
223
|
-
queryName(name) {
|
|
224
|
-
this._queryName = name;
|
|
225
|
-
return this;
|
|
226
|
-
}
|
|
227
|
-
print() {
|
|
228
|
-
if (!this._ast) {
|
|
229
|
-
throw new Error('No AST generated. Please call a query method first.');
|
|
230
|
-
}
|
|
231
|
-
const _hash = gqlPrint(this._ast);
|
|
232
|
-
return {
|
|
233
|
-
_hash,
|
|
234
|
-
_queryName: this._queryName,
|
|
235
|
-
_ast: this._ast,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
// Bind methods that will be called with different this context
|
|
239
|
-
pickScalarFields;
|
|
240
|
-
pickAllFields;
|
|
241
|
-
}
|
|
242
1
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
2
|
+
* Re-export QueryBuilder from @constructive-io/graphql-query.
|
|
3
|
+
*
|
|
4
|
+
* The QueryBuilder class and MetaObject namespace now live in graphql-query.
|
|
5
|
+
* Re-exported here for backward compatibility.
|
|
247
6
|
*/
|
|
248
|
-
|
|
249
|
-
const model = defn.model;
|
|
250
|
-
const modelMeta = this._meta.tables.find((t) => t.name === model);
|
|
251
|
-
if (!modelMeta) {
|
|
252
|
-
throw new Error(`Model meta not found for ${model}`);
|
|
253
|
-
}
|
|
254
|
-
const isInTableSchema = (fieldName) => !!modelMeta.fields.find((field) => field.name === fieldName);
|
|
255
|
-
const pickFrom = (modelSelection) => modelSelection
|
|
256
|
-
.filter((fieldName) => {
|
|
257
|
-
// If not specified or not a valid selection list, allow all
|
|
258
|
-
if (selection == null || !Array.isArray(selection))
|
|
259
|
-
return true;
|
|
260
|
-
return Object.keys(selection).includes(fieldName);
|
|
261
|
-
})
|
|
262
|
-
.filter((fieldName) => !isRelationalField(fieldName, modelMeta) &&
|
|
263
|
-
isInTableSchema(fieldName))
|
|
264
|
-
.map((fieldName) => ({
|
|
265
|
-
name: fieldName,
|
|
266
|
-
isObject: false,
|
|
267
|
-
fieldDefn: modelMeta.fields.find((f) => f.name === fieldName),
|
|
268
|
-
}));
|
|
269
|
-
// This is for inferring the sub-selection of a mutation query
|
|
270
|
-
// from a definition model .eg UserSetting, find its related queries in the introspection object, and pick its selection fields
|
|
271
|
-
if (defn.qtype === 'mutation') {
|
|
272
|
-
const relatedQuery = this._introspection[`${modelNameToGetMany(defn.model)}`];
|
|
273
|
-
return pickFrom(relatedQuery.selection);
|
|
274
|
-
}
|
|
275
|
-
return pickFrom(defn.selection);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Pick scalar fields and sub-selection fields of a query definition
|
|
279
|
-
* @param {Object} selection Selection clause object
|
|
280
|
-
* @param {Object} defn Query definition
|
|
281
|
-
* @param {Object} meta Meta object containing info about table relations
|
|
282
|
-
* @returns {Array}
|
|
283
|
-
*/
|
|
284
|
-
function pickAllFields(selection, defn) {
|
|
285
|
-
const model = defn.model;
|
|
286
|
-
const modelMeta = this._meta.tables.find((t) => t.name === model);
|
|
287
|
-
if (!modelMeta) {
|
|
288
|
-
throw new Error(`Model meta not found for ${model}`);
|
|
289
|
-
}
|
|
290
|
-
const selectionEntries = Object.entries(selection);
|
|
291
|
-
let fields = [];
|
|
292
|
-
const isWhiteListed = (selectValue) => {
|
|
293
|
-
return typeof selectValue === 'boolean' && selectValue;
|
|
294
|
-
};
|
|
295
|
-
for (const entry of selectionEntries) {
|
|
296
|
-
const [fieldName, fieldOptions] = entry;
|
|
297
|
-
// Case
|
|
298
|
-
// {
|
|
299
|
-
// goalResults: // fieldName
|
|
300
|
-
// { select: { id: true }, variables: { first: 100 } } // fieldOptions
|
|
301
|
-
// }
|
|
302
|
-
if (isObject(fieldOptions)) {
|
|
303
|
-
if (!isFieldInDefinition(fieldName, defn, modelMeta)) {
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
const referencedForeignConstraint = modelMeta.foreignConstraints.find((constraint) => constraint.fromKey.name === fieldName ||
|
|
307
|
-
constraint.fromKey.alias === fieldName);
|
|
308
|
-
const selectOptions = fieldOptions;
|
|
309
|
-
const subFields = Object.keys(selectOptions.select).filter((subField) => {
|
|
310
|
-
return (!isRelationalField(subField, modelMeta) &&
|
|
311
|
-
isWhiteListed(selectOptions.select[subField]));
|
|
312
|
-
});
|
|
313
|
-
const isBelongTo = !!referencedForeignConstraint;
|
|
314
|
-
const fieldSelection = {
|
|
315
|
-
name: fieldName,
|
|
316
|
-
isObject: true,
|
|
317
|
-
isBelongTo,
|
|
318
|
-
selection: subFields.map((name) => ({ name, isObject: false })),
|
|
319
|
-
variables: selectOptions.variables,
|
|
320
|
-
};
|
|
321
|
-
// Need to further expand selection of object fields,
|
|
322
|
-
// but only non-graphql-builtin, non-relation fields
|
|
323
|
-
// .ie action { id location }
|
|
324
|
-
// location is non-scalar and non-relational, thus need to further expand into { x y ... }
|
|
325
|
-
if (isBelongTo) {
|
|
326
|
-
const getManyName = modelNameToGetMany(referencedForeignConstraint.refTable);
|
|
327
|
-
const refDefn = this._introspection[getManyName];
|
|
328
|
-
fieldSelection.selection = pickScalarFields.call(this, { [fieldName]: true }, refDefn);
|
|
329
|
-
}
|
|
330
|
-
fields = [...fields, fieldSelection];
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
// Case
|
|
334
|
-
// {
|
|
335
|
-
// userId: true // [fieldName, fieldOptions]
|
|
336
|
-
// }
|
|
337
|
-
if (isWhiteListed(fieldOptions)) {
|
|
338
|
-
fields = [
|
|
339
|
-
...fields,
|
|
340
|
-
{
|
|
341
|
-
name: fieldName,
|
|
342
|
-
isObject: false,
|
|
343
|
-
fieldDefn: modelMeta.fields.find((f) => f.name === fieldName),
|
|
344
|
-
},
|
|
345
|
-
];
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
return fields;
|
|
350
|
-
}
|
|
351
|
-
function isFieldInDefinition(fieldName, defn, modelMeta) {
|
|
352
|
-
const isReferenced = !!modelMeta.foreignConstraints.find((constraint) => constraint.fromKey.name === fieldName ||
|
|
353
|
-
constraint.fromKey.alias === fieldName);
|
|
354
|
-
return (isReferenced ||
|
|
355
|
-
defn.selection.some((selectionItem) => {
|
|
356
|
-
if (typeof selectionItem === 'string') {
|
|
357
|
-
return fieldName === selectionItem;
|
|
358
|
-
}
|
|
359
|
-
if (isObject(selectionItem)) {
|
|
360
|
-
return selectionItem.name === fieldName;
|
|
361
|
-
}
|
|
362
|
-
return false;
|
|
363
|
-
}));
|
|
364
|
-
}
|
|
365
|
-
// TODO: see if there is a possibility of supertyping table (a key is both a foreign and primary key)
|
|
366
|
-
// A relational field is a foreign key but not a primary key
|
|
367
|
-
function isRelationalField(fieldName, modelMeta) {
|
|
368
|
-
return (!modelMeta.primaryConstraints.find((field) => field.name === fieldName) &&
|
|
369
|
-
!!modelMeta.foreignConstraints.find((constraint) => constraint.fromKey.name === fieldName));
|
|
370
|
-
}
|
|
371
|
-
// Get getMany op name from model
|
|
372
|
-
// ie. UserSetting => userSettings
|
|
373
|
-
function modelNameToGetMany(model) {
|
|
374
|
-
return camelize(pluralize(underscore(model)), true);
|
|
375
|
-
}
|
|
7
|
+
export { QueryBuilder, MetaObject } from '@constructive-io/graphql-query';
|
package/esm/core/types.d.ts
CHANGED
|
@@ -1,139 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
isNotNull: boolean;
|
|
11
|
-
isArray: boolean;
|
|
12
|
-
isArrayNotNull: boolean;
|
|
13
|
-
properties?: NestedProperties;
|
|
14
|
-
}
|
|
15
|
-
export interface QueryDefinition {
|
|
16
|
-
model: string;
|
|
17
|
-
qtype: 'getMany' | 'getOne' | 'mutation';
|
|
18
|
-
mutationType?: 'create' | 'patch' | 'delete';
|
|
19
|
-
selection: string[];
|
|
20
|
-
properties: Record<string, QueryProperty>;
|
|
21
|
-
}
|
|
22
|
-
export interface MutationDefinition extends QueryDefinition {
|
|
23
|
-
qtype: 'mutation';
|
|
24
|
-
mutationType: 'create' | 'patch' | 'delete';
|
|
25
|
-
}
|
|
26
|
-
export interface IntrospectionSchema {
|
|
27
|
-
[key: string]: QueryDefinition | MutationDefinition;
|
|
28
|
-
}
|
|
29
|
-
export interface MetaFieldType {
|
|
30
|
-
gqlType: string;
|
|
31
|
-
isArray: boolean;
|
|
32
|
-
modifier?: string | number | null;
|
|
33
|
-
pgAlias?: string | null;
|
|
34
|
-
pgType?: string | null;
|
|
35
|
-
subtype?: string | null;
|
|
36
|
-
typmod?: number | null;
|
|
37
|
-
}
|
|
38
|
-
export interface MetaField {
|
|
39
|
-
name: string;
|
|
40
|
-
type: MetaFieldType;
|
|
41
|
-
}
|
|
42
|
-
export interface MetaConstraint {
|
|
43
|
-
name: string;
|
|
44
|
-
type: MetaFieldType;
|
|
45
|
-
alias?: string;
|
|
46
|
-
}
|
|
47
|
-
export interface MetaForeignConstraint {
|
|
48
|
-
fromKey: MetaConstraint;
|
|
49
|
-
refTable: string;
|
|
50
|
-
toKey: MetaConstraint;
|
|
51
|
-
}
|
|
52
|
-
export interface MetaTable {
|
|
53
|
-
name: string;
|
|
54
|
-
fields: MetaField[];
|
|
55
|
-
primaryConstraints: MetaConstraint[];
|
|
56
|
-
uniqueConstraints: MetaConstraint[];
|
|
57
|
-
foreignConstraints: MetaForeignConstraint[];
|
|
58
|
-
}
|
|
59
|
-
export interface MetaObject {
|
|
60
|
-
tables: MetaTable[];
|
|
61
|
-
}
|
|
62
|
-
export type GraphQLVariableValue = string | number | boolean | null;
|
|
63
|
-
export interface GraphQLVariables {
|
|
64
|
-
[key: string]: GraphQLVariableValue | GraphQLVariableValue[] | GraphQLVariables | GraphQLVariables[];
|
|
65
|
-
}
|
|
66
|
-
export interface QueryFieldSelection {
|
|
67
|
-
name: string;
|
|
68
|
-
isObject: boolean;
|
|
69
|
-
fieldDefn?: MetaField | CleanField;
|
|
70
|
-
selection?: QueryFieldSelection[];
|
|
71
|
-
variables?: GraphQLVariables;
|
|
72
|
-
isBelongTo?: boolean;
|
|
73
|
-
}
|
|
74
|
-
export interface QuerySelectionOptions {
|
|
75
|
-
[fieldName: string]: boolean | {
|
|
76
|
-
select: Record<string, boolean>;
|
|
77
|
-
variables?: GraphQLVariables;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
export interface QueryBuilderInstance {
|
|
81
|
-
_introspection: IntrospectionSchema;
|
|
82
|
-
_meta: MetaObject;
|
|
83
|
-
_edges?: boolean;
|
|
84
|
-
}
|
|
85
|
-
export interface ASTFunctionParams {
|
|
86
|
-
queryName: string;
|
|
87
|
-
operationName: string;
|
|
88
|
-
query: QueryDefinition;
|
|
89
|
-
selection: QueryFieldSelection[];
|
|
90
|
-
builder?: QueryBuilderInstance;
|
|
91
|
-
}
|
|
92
|
-
export interface MutationASTParams {
|
|
93
|
-
mutationName: string;
|
|
94
|
-
operationName: string;
|
|
95
|
-
mutation: MutationDefinition;
|
|
96
|
-
selection?: QueryFieldSelection[];
|
|
97
|
-
}
|
|
98
|
-
export interface QueryBuilderOptions {
|
|
99
|
-
meta: MetaObject;
|
|
100
|
-
introspection: IntrospectionSchema;
|
|
101
|
-
}
|
|
102
|
-
export interface QueryBuilderResult {
|
|
103
|
-
_hash: string;
|
|
104
|
-
_queryName: string;
|
|
105
|
-
_ast: DocumentNode;
|
|
106
|
-
}
|
|
107
|
-
export interface IQueryBuilder {
|
|
108
|
-
query(model: string): IQueryBuilder;
|
|
109
|
-
getMany(options?: {
|
|
110
|
-
select?: QuerySelectionOptions;
|
|
111
|
-
}): IQueryBuilder;
|
|
112
|
-
getOne(options?: {
|
|
113
|
-
select?: QuerySelectionOptions;
|
|
114
|
-
}): IQueryBuilder;
|
|
115
|
-
all(options?: {
|
|
116
|
-
select?: QuerySelectionOptions;
|
|
117
|
-
}): IQueryBuilder;
|
|
118
|
-
count(): IQueryBuilder;
|
|
119
|
-
create(options?: {
|
|
120
|
-
select?: QuerySelectionOptions;
|
|
121
|
-
}): IQueryBuilder;
|
|
122
|
-
update(options?: {
|
|
123
|
-
select?: QuerySelectionOptions;
|
|
124
|
-
}): IQueryBuilder;
|
|
125
|
-
delete(options?: {
|
|
126
|
-
select?: QuerySelectionOptions;
|
|
127
|
-
}): IQueryBuilder;
|
|
128
|
-
edges(useEdges: boolean): IQueryBuilder;
|
|
129
|
-
print(): QueryBuilderResult;
|
|
130
|
-
}
|
|
131
|
-
export interface ObjectArrayItem extends QueryProperty {
|
|
132
|
-
name: string;
|
|
133
|
-
key?: string;
|
|
134
|
-
}
|
|
135
|
-
export declare function isGraphQLVariableValue(value: unknown): value is GraphQLVariableValue;
|
|
136
|
-
export declare function isGraphQLVariables(obj: unknown): obj is GraphQLVariables;
|
|
137
|
-
export type StrictRecord<K extends PropertyKey, V> = Record<K, V> & {
|
|
138
|
-
[P in PropertyKey]: P extends K ? V : never;
|
|
139
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Re-export core types from @constructive-io/graphql-query.
|
|
3
|
+
*
|
|
4
|
+
* This file used to contain the canonical type definitions. They now live in
|
|
5
|
+
* the `graphql-query` package and are re-exported here for backward
|
|
6
|
+
* compatibility so existing codegen consumers continue to work unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export { type ASTNode, type NestedProperties, type QueryProperty, type QueryDefinition, type MutationDefinition, type MetaFieldType, type MetaField, type MetaConstraint, type MetaForeignConstraint, type MetaTable, type MetaObject, type GraphQLVariableValue, type GraphQLVariables, type QueryFieldSelection, type QuerySelectionOptions, type QueryBuilderInstance, type ASTFunctionParams, type MutationASTParams, type QueryBuilderOptions, type QueryBuilderResult, type IQueryBuilder, type ObjectArrayItem, isGraphQLVariableValue, isGraphQLVariables, type StrictRecord, } from '@constructive-io/graphql-query';
|
|
9
|
+
export { type QueryIntrospectionSchema as IntrospectionSchema } from '@constructive-io/graphql-query';
|