graphql-composer
Version:
Create your GraphQL API using composition!
250 lines • 7.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Field = void 0;
const __1 = require("../..");
const GQLField_1 = require("./GQLField");
class Field extends GQLField_1.GQLField {
constructor(name, type) {
super(name, type);
this._args = [];
this._doParseArgs = true;
this._middlewares = [];
}
get args() {
return this._args;
}
get flatArgs() {
return this._args.flatMap((a) => a.args);
}
get doParseArgs() {
return this._doParseArgs;
}
get resolver() {
return this._resolver;
}
get subscription() {
return this._subscription;
}
get middlewares() {
return this._middlewares;
}
get definitionNode() {
const t = __1.TypeParser.parse(this.type);
return {
kind: "FieldDefinition",
type: {
kind: "NamedType",
name: {
kind: "Name",
value: t === null || t === void 0 ? void 0 : t.toString(),
},
},
name: {
kind: "Name",
value: this.name,
},
directives: this.directives.map((d) => d.definitionNode),
};
}
static create(nameOrField, type) {
if (typeof nameOrField === "string") {
return new Field(nameOrField, type);
}
else if (nameOrField instanceof GQLField_1.GQLField) {
const field = Field.create(nameOrField.name, nameOrField.type)
.setDescription(nameOrField.description)
.setExtensions(nameOrField.extensions)
.setDirectives(...nameOrField.directives)
.setDeprecationReason(nameOrField.deprecationReason);
if (nameOrField instanceof Field) {
field
.setMiddlewares(...nameOrField._middlewares)
.setResolver(nameOrField._resolver, ...nameOrField.args);
}
return field;
}
}
build() {
if (this.resolver) {
this.addMiddlewares(this.resolver);
}
const args = this.flatArgs.map((arg) => arg.build());
const field = {
name: this._name,
type: __1.TypeParser.parse(this._type, __1.Schema.config.requiredByDefault, __1.Schema.config.arrayRequired),
resolve: this.resolver ? this.resolveField.bind(this) : undefined,
subscribe: this.subscription ? this.subscribe.bind(this) : undefined,
deprecationReason: this._deprecationReason || null,
isDeprecated: !!this._deprecationReason,
args,
description: this._description,
extensions: this.extensions,
astNode: this.definitionNode,
};
this._built = field;
return { ...this._built };
}
/**
* Set the middlewares to your field
* A middleware is executed before your main function
* @param middlewares The middlewares list
*/
setMiddlewares(...middlewares) {
this._middlewares = middlewares;
return this;
}
/**
* Add some middlewares to your field
* A middleware is executed before your main function
* @param middlewares The middlewares list
*/
addMiddlewares(...middlewares) {
return this.setMiddlewares(...this._middlewares, ...middlewares);
}
/**
* Remove some middlewares from your field
* @param middlewares The middlewares list
*/
removeMiddlewares(...middlewares) {
middlewares.map((mw) => {
this._middlewares.splice(this._middlewares.indexOf(mw), 1);
});
return this;
}
/**
* If you don't want to parse your aguments objects into the specified class (enabled by default)
*/
disableArgsParsing() {
this._doParseArgs = false;
return this;
}
/**
* If you want to parse your aguments objects into the specified class (enabled by default)
*/
enableArgsParsing() {
this._doParseArgs = true;
return this;
}
/**
* Set the arguments of your field
* @param args The aguments
*/
setArgs(...args) {
this._args = args;
return this;
}
/**
* Add arguments to your field
* @param args The aguments
*/
addArgs(...args) {
return this.setArgs(...this.args, ...args);
}
/**
* Set the resolver function to your field
* @param args The aguments
*/
setResolver(resolver, ...args) {
if (resolver) {
this._resolver = resolver;
this.addArgs(...args);
}
return this;
}
/**
* Set the resolver function to your field
* @param args The aguments
*/
setSubscription(subscription) {
this._subscription = subscription;
return this;
}
/**
* Copy the field and return a new one
*/
copy() {
return Field.create(this);
}
convert(to) {
return to.create(this);
}
parseArgs(args, values) {
if (!values) {
return;
}
if (!this.doParseArgs) {
return args;
}
return args.reduce((prev, arg) => {
const instance = arg.classType ? new arg.classType() : {};
let descriptions = [];
if (arg instanceof __1.Args) {
descriptions = arg.args.map((a) => [a.name, a.type]);
}
else if (arg instanceof __1.InputType) {
descriptions = arg.fields.map((a) => [a.name, a.type]);
}
descriptions.map((description) => {
const value = values[description[0]];
let parsedValue = value;
if (description[1] instanceof __1.InputType) {
parsedValue = this.parseArgs([description[1]], value);
}
instance[description[0]] = parsedValue;
});
if (arg instanceof __1.Args) {
if (arg.classType) {
if (args.length > 1) {
prev[arg.classType.name] = instance;
}
else {
return instance;
}
}
else {
prev = {
...prev,
...instance,
};
}
}
else {
return instance;
}
return prev;
}, {});
}
async resolveField(source, args, context, infos) {
const parsedArgs = this.parseArgs(this._args, args);
return await this.next(parsedArgs, {
body: undefined,
source,
context,
infos,
rawArgs: args,
field: this,
}, 0);
}
async subscribe(source, args, context, infos) {
const parsedArgs = this.parseArgs(this.args, args);
return await this.subscription(parsedArgs, {
body: undefined,
source,
context,
infos,
rawArgs: args,
field: this,
});
}
async next(args, ctx, index) {
const nextFn = async () => await this.next(args, ctx, index + 1);
const guardToExecute = this._middlewares[index];
const res = await guardToExecute(args, ctx, nextFn);
if (res !== undefined) {
ctx.body = res;
}
return ctx.body;
}
}
exports.Field = Field;
//# sourceMappingURL=Field.js.map