Skip to content

Commit 240a17b

Browse files
committed
Process the schema
1 parent a445331 commit 240a17b

File tree

7 files changed

+192
-11
lines changed

7 files changed

+192
-11
lines changed

dist/vuex-orm-graphql.esm.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,6 +3565,19 @@ var Logger = /** @class */ (function () {
35653565
console.log.apply(console, this.PREFIX.concat(messages));
35663566
}
35673567
};
3568+
/**
3569+
* Wrapper for console.warn.
3570+
* @param {Array<any>} messages
3571+
*/
3572+
Logger.prototype.warn = function () {
3573+
var messages = [];
3574+
for (var _i = 0; _i < arguments.length; _i++) {
3575+
messages[_i] = arguments[_i];
3576+
}
3577+
if (this.enabled) {
3578+
console.warn.apply(console, this.PREFIX.concat(messages));
3579+
}
3580+
};
35683581
/**
35693582
* Logs a graphql query in a readable format and with all information like fetch policy and variables.
35703583
* @param {string | DocumentNode} query
@@ -9832,6 +9845,42 @@ var Apollo = /** @class */ (function () {
98329845
return Apollo;
98339846
}());
98349847

9848+
var Schema = /** @class */ (function () {
9849+
function Schema(schema) {
9850+
var _this = this;
9851+
this.schema = schema;
9852+
this.types = new Map();
9853+
this.mutations = new Map();
9854+
this.queries = new Map();
9855+
this.schema.types.forEach(function (t) { return _this.types.set(t.name, t); });
9856+
this.getType('Query').fields.forEach(function (f) { return _this.queries.set(f.name, f); });
9857+
this.getType('Mutation').fields.forEach(function (f) { return _this.mutations.set(f.name, f); });
9858+
}
9859+
Schema.prototype.getType = function (name) {
9860+
name = upcaseFirstLetter(name);
9861+
var type = this.types.get(name);
9862+
if (!type)
9863+
throw new Error("Couldn't find Type of name " + name + " in the GraphQL Schema.");
9864+
return type;
9865+
};
9866+
Schema.prototype.getMutation = function (name) {
9867+
var mutation = this.mutations.get(name);
9868+
if (!mutation)
9869+
throw new Error("Couldn't find Mutation of name " + name + " in the GraphQL Schema.");
9870+
return mutation;
9871+
};
9872+
Schema.prototype.getQuery = function (name) {
9873+
var query = this.types.get(name);
9874+
if (!query)
9875+
throw new Error("Couldn't find Query of name " + name + " in the GraphQL Schema.");
9876+
return query;
9877+
};
9878+
Schema.prototype.returnsConnection = function (field) {
9879+
return field.type.name.endsWith('TypeConnection');
9880+
};
9881+
return Schema;
9882+
}());
9883+
98359884
var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
98369885
return new (P || (P = Promise))(function (resolve, reject) {
98379886
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -9941,8 +9990,11 @@ var Context = /** @class */ (function () {
99419990
return [4 /*yield*/, this.apollo.simpleQuery(introspectionQuery, {}, true, context)];
99429991
case 1:
99439992
result = _a.sent();
9944-
this.schema = result.data.__schema;
9945-
this.logger.log('GraphQL Schema successful fetched', this.schema);
9993+
this.schema = new Schema(result.data.__schema);
9994+
this.logger.log('GraphQL Schema successful fetched', result);
9995+
this.logger.log('Starting to process the schema ...');
9996+
this.processSchema();
9997+
this.logger.log('Schema procession done ...');
99469998
_a.label = 2;
99479999
case 2: return [2 /*return*/];
994810000
}
@@ -9978,6 +10030,29 @@ var Context = /** @class */ (function () {
997810030
Model.augment(model);
997910031
});
998010032
};
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+
};
998110056
return Context;
998210057
}());
998310058

src/common/context.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { Components } from '@vuex-orm/core/lib/plugins/use';
55
import { downcaseFirstLetter } from '../support/utils';
66
import Apollo from '../graphql/apollo';
77
import Database from '@vuex-orm/core/lib/database/Database';
8-
import { Data, Options, Schema } from '../support/interfaces';
8+
import { Data, Field, GraphQLSchema, GraphQLType, Options } from '../support/interfaces';
9+
import Schema from '../graphql/schema';
910
const inflection = require('inflection');
1011

1112
const introspectionQuery = `
@@ -158,9 +159,12 @@ export default class Context {
158159
};
159160

160161
const result = await this.apollo.simpleQuery(introspectionQuery, {}, true, context);
161-
this.schema = result.data.__schema;
162+
this.schema = new Schema(result.data.__schema);
162163

163-
this.logger.log('GraphQL Schema successful fetched', this.schema);
164+
this.logger.log('GraphQL Schema successful fetched', result);
165+
this.logger.log('Starting to process the schema ...');
166+
this.processSchema();
167+
this.logger.log('Schema procession done ...');
164168
}
165169
}
166170

@@ -192,4 +196,29 @@ export default class Context {
192196
Model.augment(model);
193197
});
194198
}
199+
200+
private processSchema () {
201+
this.models.forEach((model: Model) => {
202+
let type: GraphQLType;
203+
204+
try {
205+
type = this.schema!.getType(model.singularName);
206+
} catch (error) {
207+
this.logger.warn(`Ignoring entity ${model.singularName} because it's not in the schema.`);
208+
return;
209+
}
210+
211+
model.fields.forEach((field: Field, fieldName: string) => {
212+
if (!type.fields!.find(f => f.name === fieldName)) {
213+
this.logger.warn(`Ignoring field ${model.singularName}.${fieldName} because it's not in the schema.`);
214+
215+
// TODO: Move skipFields to the model
216+
model.baseModel.skipFields = model.baseModel.skipFields ? model.baseModel.skipFields : [];
217+
if (!model.baseModel.skipFields.includes(fieldName)) {
218+
model.baseModel.skipFields.push(fieldName);
219+
}
220+
}
221+
});
222+
});
223+
}
195224
}

src/common/logger.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ export default class Logger {
6767
}
6868
}
6969

70+
/**
71+
* Wrapper for console.warn.
72+
* @param {Array<any>} messages
73+
*/
74+
public warn (...messages: Array<any>): void {
75+
if (this.enabled) {
76+
console.warn(...this.PREFIX, ...messages);
77+
}
78+
}
79+
7080
/**
7181
* Logs a graphql query in a readable format and with all information like fetch policy and variables.
7282
* @param {string | DocumentNode} query

src/graphql/schema.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { GraphQLField, GraphQLSchema, GraphQLType } from '../support/interfaces';
2+
import { upcaseFirstLetter } from '../support/utils';
3+
4+
export default class Schema {
5+
private schema: GraphQLSchema;
6+
private types: Map<string, GraphQLType>;
7+
private mutations: Map<string, GraphQLField>;
8+
private queries: Map<string, GraphQLField>;
9+
10+
public constructor (schema: GraphQLSchema) {
11+
this.schema = schema;
12+
this.types = new Map<string, GraphQLType>();
13+
this.mutations = new Map<string, GraphQLField>();
14+
this.queries = new Map<string, GraphQLField>();
15+
16+
this.schema.types.forEach((t: GraphQLType) => this.types.set(t.name, t));
17+
18+
this.getType('Query').fields!.forEach(f => this.queries.set(f.name, f));
19+
this.getType('Mutation').fields!.forEach(f => this.mutations.set(f.name, f));
20+
}
21+
22+
public getType (name: string): GraphQLType {
23+
name = upcaseFirstLetter(name);
24+
const type = this.types.get(name);
25+
26+
if (!type) throw new Error(`Couldn't find Type of name ${name} in the GraphQL Schema.`);
27+
28+
return type;
29+
}
30+
31+
public getMutation (name: string): GraphQLField {
32+
const mutation = this.mutations.get(name);
33+
34+
if (!mutation) throw new Error(`Couldn't find Mutation of name ${name} in the GraphQL Schema.`);
35+
36+
return mutation;
37+
}
38+
39+
public getQuery (name: string): GraphQLType {
40+
const query = this.types.get(name);
41+
42+
if (!query) throw new Error(`Couldn't find Query of name ${name} in the GraphQL Schema.`);
43+
44+
return query;
45+
}
46+
47+
public returnsConnection (field: GraphQLField) {
48+
return field.type.name.endsWith('TypeConnection');
49+
}
50+
}

src/support/interfaces.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,34 @@ export interface Data {
3535
[index: string]: any;
3636
}
3737

38-
export interface Filter extends Object {
38+
export interface Filter {
3939
[index: string]: any;
4040
}
4141

42-
export interface Arguments extends Object {
42+
export interface Arguments {
4343
[index: string]: any;
4444
}
4545

46-
export interface Schema extends Object {
47-
[index: string]: any;
46+
export interface GraphQLType {
47+
description: string;
48+
name: string;
49+
fields?: Array<GraphQLField>;
50+
inputFields?: Array<GraphQLField>;
51+
}
52+
53+
export interface GraphQLField {
54+
description: string;
55+
name: string;
56+
type: GraphQLTypeDefinition;
57+
}
58+
59+
export interface GraphQLTypeDefinition {
60+
kind: string;
61+
name: string;
62+
}
63+
64+
export interface GraphQLSchema {
65+
types: Array<GraphQLType>;
4866
}
4967

5068
export interface Field {

test/integration/VuexORMGraphQL.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('VuexORMGraphQL', () => {
5050

5151
const context = Context.getInstance();
5252
expect(!!context.schema).not.toEqual(false);
53-
expect(context.schema.types[0].name).toEqual('Boolean')
53+
expect(context.schema.getType('Post').name).toEqual('Post')
5454
});
5555

5656
describe('fetch', () => {

test/support/mock-data.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export class User extends ORMModel {
1717
export class Video extends ORMModel {
1818
static entity = 'videos';
1919
static eagerLoad = ['comments'];
20-
static skipFields = ['ignoreMe'];
2120

2221
static fields () {
2322
return {

0 commit comments

Comments
 (0)