Skip to content

Commit e63a00f

Browse files
committed
Determine field type via schema
1 parent 6c41c34 commit e63a00f

File tree

8 files changed

+136
-100
lines changed

8 files changed

+136
-100
lines changed

dist/vuex-orm-graphql.esm.js

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10001,6 +10001,29 @@ var Context = /** @class */ (function () {
1000110001
});
1000210002
});
1000310003
};
10004+
Context.prototype.processSchema = function () {
10005+
var _this = this;
10006+
this.models.forEach(function (model) {
10007+
var type;
10008+
try {
10009+
type = _this.schema.getType(model.singularName);
10010+
}
10011+
catch (error) {
10012+
_this.logger.warn("Ignoring entity " + model.singularName + " because it's not in the schema.");
10013+
return;
10014+
}
10015+
model.fields.forEach(function (field, fieldName) {
10016+
if (!type.fields.find(function (f) { return f.name === fieldName; })) {
10017+
_this.logger.warn("Ignoring field " + model.singularName + "." + fieldName + " because it's not in the schema.");
10018+
// TODO: Move skipFields to the model
10019+
model.baseModel.skipFields = model.baseModel.skipFields ? model.baseModel.skipFields : [];
10020+
if (!model.baseModel.skipFields.includes(fieldName)) {
10021+
model.baseModel.skipFields.push(fieldName);
10022+
}
10023+
}
10024+
});
10025+
});
10026+
};
1000410027
/**
1000510028
* Returns a model from the model collection by it's name
1000610029
*
@@ -10030,29 +10053,6 @@ var Context = /** @class */ (function () {
1003010053
Model.augment(model);
1003110054
});
1003210055
};
10033-
Context.prototype.processSchema = function () {
10034-
var _this = this;
10035-
this.models.forEach(function (model) {
10036-
var type;
10037-
try {
10038-
type = _this.schema.getType(model.singularName);
10039-
}
10040-
catch (error) {
10041-
_this.logger.warn("Ignoring entity " + model.singularName + " because it's not in the schema.");
10042-
return;
10043-
}
10044-
model.fields.forEach(function (field, fieldName) {
10045-
if (!type.fields.find(function (f) { return f.name === fieldName; })) {
10046-
_this.logger.warn("Ignoring field " + model.singularName + "." + fieldName + " because it's not in the schema.");
10047-
// TODO: Move skipFields to the model
10048-
model.baseModel.skipFields = model.baseModel.skipFields ? model.baseModel.skipFields : [];
10049-
if (!model.baseModel.skipFields.includes(fieldName)) {
10050-
model.baseModel.skipFields.push(fieldName);
10051-
}
10052-
}
10053-
});
10054-
});
10055-
};
1005610056
return Context;
1005710057
}());
1005810058

@@ -10211,26 +10211,32 @@ var QueryBuilder = /** @class */ (function () {
1021110211
* @returns {string}
1021210212
*/
1021310213
QueryBuilder.determineAttributeType = function (model, key, value) {
10214-
var field = model.fields.get(key);
1021510214
var context = Context.getInstance();
10216-
if (field && field instanceof context.components.String) {
10217-
return 'String';
10218-
}
10219-
else if (field && field instanceof context.components.Number) {
10220-
return 'Int';
10221-
}
10222-
else if (field && field instanceof context.components.Boolean) {
10223-
return 'Boolean';
10215+
var field = model.fields.get(key);
10216+
var schemaField = context.schema.getType(model.singularName).fields.find(function (f) { return f.name === key; });
10217+
if (schemaField) {
10218+
return schemaField.type.name;
1022410219
}
1022510220
else {
10226-
if (typeof value === 'number')
10227-
return 'Int';
10228-
if (typeof value === 'string')
10221+
if (field instanceof context.components.String) {
1022910222
return 'String';
10230-
if (typeof value === 'boolean')
10223+
}
10224+
else if (field && field instanceof context.components.Number) {
10225+
return 'Int';
10226+
}
10227+
else if (field && field instanceof context.components.Boolean) {
1023110228
return 'Boolean';
10229+
}
10230+
else {
10231+
if (typeof value === 'number')
10232+
return 'Int';
10233+
if (typeof value === 'string')
10234+
return 'String';
10235+
if (typeof value === 'boolean')
10236+
return 'Boolean';
10237+
throw new Error("Can't find suitable graphql type for field '" + model.singularName + "." + key + "'.");
10238+
}
1023210239
}
10233-
throw new Error("Can't find suitable graphql type for variable " + key + " for model " + model.singularName);
1023410240
};
1023510241
/**
1023610242
* Generates the fields for all related models.

src/common/context.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,31 @@ export default class Context {
170170
return this.schema;
171171
}
172172

173+
public processSchema () {
174+
this.models.forEach((model: Model) => {
175+
let type: GraphQLType;
176+
177+
try {
178+
type = this.schema!.getType(model.singularName);
179+
} catch (error) {
180+
this.logger.warn(`Ignoring entity ${model.singularName} because it's not in the schema.`);
181+
return;
182+
}
183+
184+
model.fields.forEach((field: Field, fieldName: string) => {
185+
if (!type.fields!.find(f => f.name === fieldName)) {
186+
this.logger.warn(`Ignoring field ${model.singularName}.${fieldName} because it's not in the schema.`);
187+
188+
// TODO: Move skipFields to the model
189+
model.baseModel.skipFields = model.baseModel.skipFields ? model.baseModel.skipFields : [];
190+
if (!model.baseModel.skipFields.includes(fieldName)) {
191+
model.baseModel.skipFields.push(fieldName);
192+
}
193+
}
194+
});
195+
});
196+
}
197+
173198
/**
174199
* Returns a model from the model collection by it's name
175200
*
@@ -198,29 +223,4 @@ export default class Context {
198223
Model.augment(model);
199224
});
200225
}
201-
202-
private processSchema () {
203-
this.models.forEach((model: Model) => {
204-
let type: GraphQLType;
205-
206-
try {
207-
type = this.schema!.getType(model.singularName);
208-
} catch (error) {
209-
this.logger.warn(`Ignoring entity ${model.singularName} because it's not in the schema.`);
210-
return;
211-
}
212-
213-
model.fields.forEach((field: Field, fieldName: string) => {
214-
if (!type.fields!.find(f => f.name === fieldName)) {
215-
this.logger.warn(`Ignoring field ${model.singularName}.${fieldName} because it's not in the schema.`);
216-
217-
// TODO: Move skipFields to the model
218-
model.baseModel.skipFields = model.baseModel.skipFields ? model.baseModel.skipFields : [];
219-
if (!model.baseModel.skipFields.includes(fieldName)) {
220-
model.baseModel.skipFields.push(fieldName);
221-
}
222-
}
223-
});
224-
});
225-
}
226226
}

src/graphql/query-builder.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,22 +185,28 @@ export default class QueryBuilder {
185185
* @returns {string}
186186
*/
187187
private static determineAttributeType (model: Model, key: string, value: any): string {
188+
const context: Context = Context.getInstance();
188189
const field: undefined | Field = model.fields.get(key);
189-
const context = Context.getInstance();
190190

191-
if (field && field instanceof context.components.String) {
192-
return 'String';
193-
} else if (field && field instanceof context.components.Number) {
194-
return 'Int';
195-
} else if (field && field instanceof context.components.Boolean) {
196-
return 'Boolean';
191+
const schemaField = context.schema!.getType(model.singularName).fields!.find(f => f.name === key);
192+
193+
if (schemaField) {
194+
return schemaField.type.name;
197195
} else {
198-
if (typeof value === 'number') return 'Int';
199-
if (typeof value === 'string') return 'String';
200-
if (typeof value === 'boolean') return 'Boolean';
201-
}
196+
if (field instanceof context.components.String) {
197+
return 'String';
198+
} else if (field && field instanceof context.components.Number) {
199+
return 'Int';
200+
} else if (field && field instanceof context.components.Boolean) {
201+
return 'Boolean';
202+
} else {
203+
if (typeof value === 'number') return 'Int';
204+
if (typeof value === 'string') return 'String';
205+
if (typeof value === 'boolean') return 'Boolean';
202206

203-
throw new Error(`Can't find suitable graphql type for variable ${key} for model ${model.singularName}`);
207+
throw new Error(`Can't find suitable graphql type for field '${model.singularName}.${key}'.`);
208+
}
209+
}
204210
}
205211

206212
/**

test/unit/Context.spec.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ let store;
66
let vuexOrmGraphQL;
77
let context;
88

9-
beforeEach(async () => {
10-
[store, vuexOrmGraphQL] = await setupMockData();
11-
context = Context.getInstance();
12-
});
139

1410
describe('Context', () => {
11+
beforeEach(async () => {
12+
[store, vuexOrmGraphQL] = await setupMockData();
13+
context = Context.getInstance();
14+
});
15+
1516
describe('.debugMode', () => {
1617
it('to be false', () => {
1718
expect(context.debugMode).toEqual(false)

test/unit/Model.spec.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import Model from 'app/orm/model';
22
import { setupMockData, User, Video, Post, Comment, TariffTariffOption, Tariff, TariffOption } from 'test/support/mock-data';
33
import Context from "app/common/context";
4+
import Schema from "app/graphql/schema";
5+
import {introspectionResult} from "../support/mock-data";
46

57
let model;
68
let store;
79
let vuexOrmGraphQL;
810
let context;
911

10-
beforeEach(async () => {
11-
[store, vuexOrmGraphQL] = await setupMockData();
12-
context = Context.getInstance();
13-
model = context.getModel('user');
14-
});
15-
1612
describe('Model', () => {
13+
beforeEach(async () => {
14+
[store, vuexOrmGraphQL] = await setupMockData();
15+
context = Context.getInstance();
16+
model = context.getModel('user');
17+
18+
// Make sure schema is filled
19+
context.schema = new Schema(introspectionResult.data.__schema);
20+
context.processSchema();
21+
});
22+
1723
describe('.singularName', () => {
1824
it('returns the singular name of the entity', () => {
1925
expect(model.singularName).toEqual('user');

test/unit/NameGenerator.spec.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@ import NameGenerator from "app/graphql/name-generator";
22
import Model from 'app/orm/model';
33
import { setupMockData, User, Video, Post, Comment, TariffTariffOption, Tariff, TariffOption } from 'test/support/mock-data';
44
import Context from "app/common/context";
5+
import Schema from "app/graphql/schema";
6+
import {introspectionResult} from "../support/mock-data";
57

68
let model;
79
let store;
810
let vuexOrmGraphQL;
911
let context;
1012

11-
beforeEach(async () => {
12-
[store, vuexOrmGraphQL] = await setupMockData();
13-
context = Context.getInstance();
14-
model = context.getModel('post');
15-
});
1613

1714
describe('NameGenerator', () => {
15+
beforeEach(async () => {
16+
[store, vuexOrmGraphQL] = await setupMockData();
17+
context = Context.getInstance();
18+
model = context.getModel('post');
19+
20+
// Make sure schema is filled
21+
context.schema = new Schema(introspectionResult.data.__schema);
22+
context.processSchema();
23+
});
24+
1825
describe('.getNameForPersist', () => {
1926
it('returns a correct create mutation name', () => {
2027
expect(NameGenerator.getNameForPersist(model)).toEqual('createPost');

test/unit/QueryBuilder.spec.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@ import QueryBuilder from 'app/graphql/query-builder';
22
import { setupMockData, User, Video, Post, Comment, TariffTariffOption, Tariff, TariffOption } from 'test/support/mock-data'
33
import {prettify} from "app/support/utils";
44
import Context from "app/common/context";
5+
import Schema from "app/graphql/schema";
6+
import {introspectionResult} from "../support/mock-data";
57

68
let context;
79
let store;
810
let vuexOrmGraphQL;
911

1012

11-
beforeEach(async () => {
12-
[store, vuexOrmGraphQL] = await setupMockData();
13-
context = Context.getInstance();
14-
});
13+
describe('QueryBuilder', () => {
14+
beforeEach(async () => {
15+
[store, vuexOrmGraphQL] = await setupMockData();
16+
context = Context.getInstance();
1517

18+
// Make sure schema is filled
19+
context.schema = new Schema(introspectionResult.data.__schema);
20+
context.processSchema();
21+
});
1622

17-
describe('QueryBuilder', () => {
1823
describe('.buildArguments', () => {
1924
it('can generate signatures', () => {
2025
const model = context.getModel('post');
@@ -240,7 +245,7 @@ mutation DeleteUser($id: ID!) {
240245
it('throws a exception when the input is something unknown', () => {
241246
const model = context.getModel('post');
242247
expect(() => QueryBuilder.determineAttributeType(model, 'asdfsfa', undefined))
243-
.toThrowError("Can't find suitable graphql type for variable asdfsfa for model post");
248+
.toThrowError("Can't find suitable graphql type for field 'post.asdfsfa'");
244249
});
245250

246251
it('returns String for string typed fields', () => {

test/unit/Transformer.spec.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import Transformer from "app/graphql/transformer";
22
import { setupMockData, User, Video, Post, Comment, TariffTariffOption, Tariff, TariffOption } from 'test/support/mock-data'
33
import Context from "app/common/context";
4+
import Schema from "app/graphql/schema";
5+
import {introspectionResult} from "../support/mock-data";
46

57
let store;
68
let vuexOrmGraphQL;
79
let context;
810

911

10-
beforeEach(async () => {
11-
[store, vuexOrmGraphQL] = await setupMockData();
12-
context = Context.getInstance();
13-
});
12+
describe('Transformer', () => {
13+
beforeEach(async () => {
14+
[store, vuexOrmGraphQL] = await setupMockData();
15+
context = Context.getInstance();
1416

17+
// Make sure schema is filled
18+
context.schema = new Schema(introspectionResult.data.__schema);
19+
context.processSchema();
20+
});
1521

16-
describe('Transformer', () => {
1722
describe('.transformOutgoingData', () => {
1823
it('transforms models to a useful data hashmap', () => {
1924
const user = User.query().first();

0 commit comments

Comments
 (0)