nexus-prisma
Advanced tools
Comparing version 0.5.0-next.1 to 0.5.0-next.2
@@ -13,5 +13,7 @@ import * as Nexus from 'nexus'; | ||
} | ||
declare type FieldPublisher = (opts?: FieldPublisherConfig) => PublisherMethods; | ||
declare type PublisherMethods = Record<string, FieldPublisher>; | ||
export interface Options { | ||
types: any; | ||
photon?: (ctx: any) => any; | ||
photon?: (ctx: Nexus.core.GetGen<'context'>) => any; | ||
shouldGenerateArtifacts?: boolean; | ||
@@ -88,4 +90,5 @@ inputs?: { | ||
protected buildModel(): DynamicOutputPropertyDef<"model">; | ||
protected buildArgsFromField(prismaModelName: string, graphQLTypeName: string, operationName: keyof DMMF.Data.Mapping | null, field: DMMF.Data.SchemaField, opts: FieldPublisherConfig): Nexus.core.ArgsRecord; | ||
protected argsFromQueryOrModelField(prismaModelName: string, graphQLTypeName: string, dmmfField: DMMF.Data.SchemaField, opts: FieldPublisherConfig): CustomInputArg[]; | ||
protected internalBuildModel(typeName: string, t: Nexus.core.OutputDefinitionBlock<any>): Record<string, FieldPublisher>; | ||
protected buildArgsFromField(typeName: string, operationName: keyof DMMF.Data.Mapping | null, field: DMMF.Data.SchemaField, resolvedConfig: FieldPublisherConfig): Nexus.core.ArgsRecord; | ||
protected argsFromQueryOrModelField(typeName: string, dmmfField: DMMF.Data.SchemaField, resolvedConfig: FieldPublisherConfig): CustomInputArg[]; | ||
/** | ||
@@ -111,8 +114,4 @@ * This handles "tailored field feature publishing". | ||
protected handleInputObjectCustomization(fieldWhitelist: Record<string, boolean> | boolean, inputTypeName: string, fieldName: string, graphQLTypeName: string): DMMF.Data.InputType; | ||
/** | ||
* Build the properties on a .model for a given prisma model. | ||
*/ | ||
protected buildModelDo(prismaModelName: string, graphQLTypeName: string, t: Nexus.core.OutputDefinitionBlock<any>): Record<string, (opts?: FieldPublisherConfig | undefined) => any>; | ||
} | ||
export {}; | ||
//# sourceMappingURL=builder.d.ts.map |
@@ -14,5 +14,5 @@ "use strict"; | ||
const GraphQL = __importStar(require("./graphql")); | ||
const mapping_1 = require("./mapping"); | ||
const naming_strategies_1 = require("./naming-strategies"); | ||
const publisher_1 = require("./publisher"); | ||
const supported_ops_1 = require("./supported-ops"); | ||
const Typegen = __importStar(require("./typegen")); | ||
@@ -103,56 +103,29 @@ const utils_1 = require("./utils"); | ||
// Nexus should improve the type of typeName to be AllOutputTypes | ||
factory: ({ typeDef: t, typeName: gqlTypeName }) => { | ||
if (gqlTypeName === GraphQL.rootNames.Subscription) { | ||
factory: ({ typeDef: t, typeName }) => { | ||
if (typeName === GraphQL.rootNames.Subscription) { | ||
// TODO Lets put a GitHub issue link in this error message | ||
throw new Error(`t.crud is not yet supported on the 'Subscription' type.`); | ||
} | ||
if (gqlTypeName !== GraphQL.rootNames.Query && | ||
gqlTypeName !== GraphQL.rootNames.Mutation) { | ||
throw new Error(`t.crud can only be used on GraphQL root types 'Query' & 'Mutation' but was used on '${gqlTypeName}'. Please use 't.model' instead`); | ||
if (typeName !== GraphQL.rootNames.Query && | ||
typeName !== GraphQL.rootNames.Mutation) { | ||
throw new Error(`t.crud can only be used on GraphQL root types 'Query' & 'Mutation' but was used on '${typeName}'. Please use 't.model' instead`); | ||
} | ||
const mappedFields = gqlTypeName === 'Query' | ||
? this.dmmf.mappings.map(mapping => { | ||
const queriesNames = supported_ops_1.getSupportedQueries(mapping); | ||
return { | ||
fields: this.dmmf.queryObject.fields.filter(query => queriesNames.includes(query.name)), | ||
mapping, | ||
}; | ||
}) | ||
: gqlTypeName === 'Mutation' | ||
? this.dmmf.mappings.map(mapping => { | ||
const mutationsNames = supported_ops_1.getSupportedMutations(mapping); | ||
return { | ||
fields: this.dmmf.mutationObject.fields.filter(mutation => mutationsNames.includes(mutation.name)), | ||
mapping, | ||
}; | ||
}) | ||
: undefined; | ||
return mappedFields.reduce((crud, mappedField) => { | ||
const prismaModelName = mappedField.mapping.model; | ||
mappedField.fields.forEach(field => { | ||
const mappedFieldName = utils_1.getCRUDFieldName(prismaModelName, field.name, mappedField.mapping, this.fieldNamingStrategy); | ||
const fieldPublisher = givenConfig => { | ||
const resolvedConfig = Object.assign({ pagination: true, type: field.outputType.type }, givenConfig); | ||
const gqlFieldName = resolvedConfig.alias | ||
? resolvedConfig.alias | ||
: mappedFieldName; | ||
const operationName = Object.keys(mappedField.mapping).find(key => mappedField.mapping[key] === field.name); | ||
if (!operationName) { | ||
throw new Error(`Could not find operation name for field ${field.name}`); | ||
} | ||
t.field(gqlFieldName, { | ||
type: this.publisher.outputType(resolvedConfig.type, field), | ||
list: field.outputType.isList || undefined, | ||
nullable: !field.outputType.isRequired, | ||
args: this.buildArgsFromField(prismaModelName, gqlTypeName, operationName, field, resolvedConfig), | ||
resolve: (_parent, args, ctx) => { | ||
const photon = this.getPhoton(ctx); | ||
utils_1.assertPhotonInContext(photon); | ||
return photon[mappedField.mapping.plural][operationName](args); | ||
}, | ||
}); | ||
return crud; | ||
}; | ||
crud[mappedFieldName] = fieldPublisher; | ||
}); | ||
return mapping_1.getCrudMappedFields(typeName, this.dmmf).reduce((crud, mappedField) => { | ||
const fieldPublisher = givenConfig => { | ||
const resolvedConfig = Object.assign({ pagination: true, type: mappedField.field.outputType.type }, givenConfig); | ||
const gqlFieldName = resolvedConfig.alias || mappedField.field.name; | ||
t.field(gqlFieldName, { | ||
type: this.publisher.outputType(resolvedConfig.type, mappedField.field), | ||
list: mappedField.field.outputType.isList || undefined, | ||
nullable: !mappedField.field.outputType.isRequired, | ||
args: this.buildArgsFromField(typeName, mappedField.operation, mappedField.field, resolvedConfig), | ||
resolve: (_parent, args, ctx) => { | ||
const photon = this.getPhoton(ctx); | ||
utils_1.assertPhotonInContext(photon); | ||
return photon[mappedField.photonAccessor][mappedField.operation](args); | ||
}, | ||
}); | ||
return crud; | ||
}; | ||
crud[mappedField.field.name] = fieldPublisher; | ||
return crud; | ||
@@ -215,9 +188,40 @@ }, {}); | ||
factory: ({ typeDef, typeName }) => this.dmmf.hasModel(typeName) | ||
? this.buildModelDo(typeName, typeName, typeDef) | ||
: (modelName) => this.buildModelDo(modelName, modelName, typeDef), | ||
? this.internalBuildModel(typeName, typeDef) | ||
: (modelName) => this.internalBuildModel(modelName, typeDef), | ||
}); | ||
} | ||
buildArgsFromField(prismaModelName, graphQLTypeName, operationName, field, opts) { | ||
internalBuildModel(typeName, t) { | ||
const model = this.dmmf.getModelOrThrow(typeName); | ||
const outputType = this.dmmf.getOutputType(model.name); | ||
const publishers = outputType.fields.reduce((acc, field) => { | ||
const fieldPublisher = givenConfig => { | ||
const resolvedConfig = Object.assign({ pagination: true, type: field.outputType.type }, givenConfig); | ||
const fieldName = resolvedConfig.alias || field.name; | ||
const type = resolvedConfig.type || field.outputType.type; | ||
const fieldOpts = { | ||
type: this.publisher.outputType(type, field), | ||
list: field.outputType.isList || undefined, | ||
nullable: !field.outputType.isRequired, | ||
args: this.buildArgsFromField(typeName, null, field, resolvedConfig), | ||
}; | ||
// Rely on default resolvers for scalars and enums | ||
if (field.outputType.kind === 'object') { | ||
const mapping = this.dmmf.getMapping(typeName); | ||
fieldOpts.resolve = (root, args, ctx) => { | ||
const photon = this.getPhoton(ctx); | ||
utils_1.assertPhotonInContext(photon); | ||
return photon[mapping.plural]['findOne']({ where: { id: root.id } })[field.name](args); | ||
}; | ||
} | ||
t.field(fieldName, fieldOpts); | ||
return publishers; | ||
}; | ||
acc[field.name] = fieldPublisher; | ||
return acc; | ||
}, {}); | ||
return publishers; | ||
} | ||
buildArgsFromField(typeName, operationName, field, resolvedConfig) { | ||
let args = []; | ||
if (graphQLTypeName === 'Mutation' || operationName === 'findOne') { | ||
if (typeName === 'Mutation' || operationName === 'findOne') { | ||
args = field.args.map(arg => ({ | ||
@@ -229,3 +233,3 @@ arg, | ||
else { | ||
args = this.argsFromQueryOrModelField(prismaModelName, graphQLTypeName, field, opts); | ||
args = this.argsFromQueryOrModelField(typeName, field, resolvedConfig); | ||
} | ||
@@ -237,31 +241,31 @@ return args.reduce((acc, customArg) => { | ||
} | ||
argsFromQueryOrModelField(prismaModelName, graphQLTypeName, dmmfField, opts) { | ||
argsFromQueryOrModelField(typeName, dmmfField, resolvedConfig) { | ||
let args = []; | ||
if (opts.filtering) { | ||
if (resolvedConfig.filtering) { | ||
const inputObjectTypeDefName = `${dmmfField.outputType.type}WhereInput`; | ||
const whereArg = dmmfField.args.find(arg => arg.inputType.type === inputObjectTypeDefName && arg.name === 'where'); | ||
if (!whereArg) { | ||
throw new Error(`Could not find filtering argument for ${prismaModelName}.${dmmfField.name}`); | ||
throw new Error(`Could not find filtering argument for ${typeName}.${dmmfField.name}`); | ||
} | ||
args.push({ | ||
arg: whereArg, | ||
type: this.handleInputObjectCustomization(opts.filtering, inputObjectTypeDefName, dmmfField.name, graphQLTypeName), | ||
type: this.handleInputObjectCustomization(resolvedConfig.filtering, inputObjectTypeDefName, dmmfField.name, typeName), | ||
}); | ||
} | ||
if (opts.ordering) { | ||
if (resolvedConfig.ordering) { | ||
const orderByTypeName = `${dmmfField.outputType.type}OrderByInput`; | ||
const orderByArg = dmmfField.args.find(arg => arg.inputType.type === orderByTypeName && arg.name === 'orderBy'); | ||
if (!orderByArg) { | ||
throw new Error(`Could not find ordering argument for ${prismaModelName}.${dmmfField.name}`); | ||
throw new Error(`Could not find ordering argument for ${typeName}.${dmmfField.name}`); | ||
} | ||
args.push({ | ||
arg: orderByArg, | ||
type: this.handleInputObjectCustomization(opts.ordering, orderByTypeName, dmmfField.name, graphQLTypeName), | ||
type: this.handleInputObjectCustomization(resolvedConfig.ordering, orderByTypeName, dmmfField.name, typeName), | ||
}); | ||
} | ||
if (opts.pagination) { | ||
if (resolvedConfig.pagination) { | ||
const paginationKeys = ['first', 'last', 'before', 'after', 'skip']; | ||
const paginationsArgs = opts.pagination === true | ||
const paginationsArgs = resolvedConfig.pagination === true | ||
? dmmfField.args.filter(a => paginationKeys.includes(a.name)) | ||
: dmmfField.args.filter(arg => opts.pagination[arg.name] === true); | ||
: dmmfField.args.filter(arg => resolvedConfig.pagination[arg.name] === true); | ||
args.push(...paginationsArgs.map(a => ({ | ||
@@ -310,38 +314,4 @@ arg: a, | ||
} | ||
/** | ||
* Build the properties on a .model for a given prisma model. | ||
*/ | ||
buildModelDo(prismaModelName, graphQLTypeName, t) { | ||
const model = this.dmmf.getModelOrThrow(prismaModelName); | ||
const outputType = this.dmmf.getOutputType(model.name); | ||
const seed = {}; | ||
const result = outputType.fields.reduce((acc, graphqlField) => { | ||
acc[graphqlField.name] = opts => { | ||
if (!opts) { | ||
opts = {}; | ||
} | ||
if (opts.pagination === undefined) { | ||
opts.pagination = true; | ||
} | ||
const fieldName = opts.alias ? opts.alias : graphqlField.name; | ||
const type = opts.type ? opts.type : graphqlField.outputType.type; | ||
const fieldOpts = Object.assign(Object.assign({}, utils_1.nexusFieldOpts(Object.assign(Object.assign({}, graphqlField.outputType), { type: this.publisher.outputType(type, graphqlField) }))), { args: this.buildArgsFromField(prismaModelName, graphQLTypeName, null, graphqlField, opts) }); | ||
// Rely on default resolvers for scalars and enums | ||
if (graphqlField.outputType.kind === 'object') { | ||
const mapping = this.dmmf.getMapping(prismaModelName); | ||
fieldOpts.resolve = (root, args, ctx) => { | ||
const photon = this.getPhoton(ctx); | ||
utils_1.assertPhotonInContext(photon); | ||
return photon[mapping.plural]['findOne']({ where: { id: root.id } })[graphqlField.name](args); | ||
}; | ||
} | ||
t.field(fieldName, fieldOpts); | ||
return result; | ||
}; | ||
return acc; | ||
}, seed); | ||
return result; | ||
} | ||
} | ||
exports.SchemaBuilder = SchemaBuilder; | ||
//# sourceMappingURL=builder.js.map |
@@ -7,6 +7,7 @@ import { ExternalDMMF as DMMF } from './transformer'; | ||
mappings: DMMF.Mapping[]; | ||
queryObject: DMMF.OutputType; | ||
mutationObject: DMMF.OutputType; | ||
queryObject: OutputType; | ||
mutationObject: OutputType; | ||
outputTypesIndex: Index<DMMF.OutputType>; | ||
inputTypesIndex: Index<DMMF.InputType>; | ||
mappingsIndex: Index<DMMF.Mapping>; | ||
enumsIndex: Index<DMMF.Enum>; | ||
@@ -16,3 +17,3 @@ modelsIndex: Index<DMMF.Model>; | ||
getInputType(inputTypeName: string): DMMF.InputType; | ||
getOutputType(outputTypeName: string): DMMF.OutputType; | ||
getOutputType(outputTypeName: string): OutputType; | ||
hasOutputType(outputTypeName: string): boolean; | ||
@@ -25,2 +26,10 @@ getEnumType(enumTypeName: string): DMMF.Enum; | ||
} | ||
export declare class OutputType { | ||
protected outputType: DMMF.OutputType; | ||
name: string; | ||
fields: DMMF.SchemaField[]; | ||
isEmbedded?: boolean; | ||
constructor(outputType: DMMF.OutputType); | ||
getField(fieldName: string): DMMF.SchemaField; | ||
} | ||
//# sourceMappingURL=DMMFClass.d.ts.map |
@@ -11,5 +11,2 @@ "use strict"; | ||
this.mappings = mappings; | ||
// Entrypoints | ||
this.queryObject = schema.outputTypes.find(t => t.name === 'Query'); | ||
this.mutationObject = schema.outputTypes.find(t => t.name === 'Mutation'); | ||
// Indices | ||
@@ -20,2 +17,6 @@ this.modelsIndex = utils_1.indexBy('name', datamodel.models); | ||
this.outputTypesIndex = utils_1.indexBy('name', schema.outputTypes); | ||
this.mappingsIndex = utils_1.indexBy('model', mappings); | ||
// Entrypoints | ||
this.queryObject = this.getOutputType('Query'); | ||
this.mutationObject = this.getOutputType('Mutation'); | ||
} | ||
@@ -34,3 +35,3 @@ getInputType(inputTypeName) { | ||
} | ||
return outputType; | ||
return new OutputType(outputType); | ||
} | ||
@@ -73,3 +74,3 @@ hasOutputType(outputTypeName) { | ||
getMapping(modelName) { | ||
const mapping = this.mappings.find(m => m.model === modelName); | ||
const mapping = this.mappingsIndex[modelName]; | ||
if (!mapping) { | ||
@@ -82,2 +83,18 @@ throw new Error('Could not find mapping for model: ' + modelName); | ||
exports.DMMFClass = DMMFClass; | ||
class OutputType { | ||
constructor(outputType) { | ||
this.outputType = outputType; | ||
this.name = outputType.name; | ||
this.fields = outputType.fields; | ||
this.isEmbedded = outputType.isEmbedded; | ||
} | ||
getField(fieldName) { | ||
const field = this.outputType.fields.find(f => f.name === fieldName); | ||
if (!field) { | ||
throw new Error(`Could not find field field '${fieldName}' on type ${this.outputType.name}`); | ||
} | ||
return field; | ||
} | ||
} | ||
exports.OutputType = OutputType; | ||
//# sourceMappingURL=DMMFClass.js.map |
@@ -87,11 +87,11 @@ import * as Nexus from 'nexus'; | ||
model: string; | ||
plural?: string; | ||
findOne?: string; | ||
findMany?: string; | ||
create?: string; | ||
update?: string; | ||
updateMany?: string; | ||
upsert?: string; | ||
delete?: string; | ||
deleteMany?: string; | ||
plural: string; | ||
findOne: string; | ||
findMany: string; | ||
create: string; | ||
update: string; | ||
updateMany: string; | ||
upsert: string; | ||
delete: string; | ||
deleteMany: string; | ||
} | ||
@@ -98,0 +98,0 @@ enum ModelAction { |
@@ -10,6 +10,9 @@ import * as Nexus from 'nexus'; | ||
outputType(outputTypeName: string, field: DMMF.Data.SchemaField): any; | ||
protected publishObject(name: string): Nexus.core.NexusObjectTypeDef<string>; | ||
protected publishScalar(typeName: string): string | Nexus.core.NexusScalarTypeDef<string>; | ||
protected publishEnum(typeName: string): Nexus.core.NexusEnumTypeDef<string>; | ||
protected publishInputObjectType(inputType: DMMF.Data.InputType): Nexus.core.NexusInputObjectTypeDef<string>; | ||
protected getTypeFromArg(arg: DMMF.Data.SchemaArg): DMMF.Data.Enum | DMMF.Data.InputType | DMMF.Data.OutputType; | ||
protected getTypeFromArg(arg: DMMF.Data.SchemaArg): { | ||
name: string; | ||
}; | ||
protected isPublished(typeName: string): boolean; | ||
@@ -16,0 +19,0 @@ protected markTypeAsPublished(typeName: string): void; |
@@ -22,3 +22,3 @@ "use strict"; | ||
if (this.isPublished(typeName)) { | ||
return Nexus.arg(utils_1.nexusFieldOpts(Object.assign(Object.assign({}, customArg.arg.inputType), { type: customArg.type.name }))); | ||
return Nexus.arg(utils_1.dmmfFieldToNexusFieldConfig(Object.assign(Object.assign({}, customArg.arg.inputType), { type: customArg.type.name }))); | ||
} | ||
@@ -42,3 +42,3 @@ if (customArg.arg.inputType.kind === 'scalar') { | ||
if (field.outputType.kind === 'object') { | ||
return outputTypeName; | ||
return this.publishObject(outputTypeName); | ||
} | ||
@@ -53,2 +53,14 @@ if (this.dmmf.hasEnumType(outputTypeName)) { | ||
} | ||
publishObject(name) { | ||
this.markTypeAsPublished(name); | ||
const dmmfObject = this.dmmf.getOutputType(name); | ||
return Nexus.objectType({ | ||
name, | ||
definition: t => { | ||
for (const field of dmmfObject.fields) { | ||
t.field(field.name, utils_1.dmmfFieldToNexusFieldConfig(field.outputType)); | ||
} | ||
}, | ||
}); | ||
} | ||
publishScalar(typeName) { | ||
@@ -67,7 +79,7 @@ if (graphql_1.scalarsNameValues.includes(typeName)) { | ||
publishEnum(typeName) { | ||
const eType = this.dmmf.getEnumType(typeName); | ||
const dmmfEnum = this.dmmf.getEnumType(typeName); | ||
this.markTypeAsPublished(typeName); | ||
return Nexus.enumType({ | ||
name: typeName, | ||
members: eType.values, | ||
members: dmmfEnum.values, | ||
}); | ||
@@ -89,3 +101,3 @@ } | ||
[...scalarFields, ...remappedObjectFields].forEach(field => { | ||
t.field(field.name, utils_1.nexusFieldOpts(field.inputType)); | ||
t.field(field.name, utils_1.dmmfFieldToNexusFieldConfig(field.inputType)); | ||
}); | ||
@@ -97,3 +109,5 @@ }, | ||
const kindToType = { | ||
scalar: (typeName) => this.dmmf.getOutputType(typeName), | ||
scalar: (typeName) => ({ | ||
name: this.dmmf.getOutputType(typeName).name, | ||
}), | ||
enum: (typeName) => this.dmmf.getEnumType(typeName), | ||
@@ -100,0 +114,0 @@ object: (typeName) => this.dmmf.getInputType(typeName), |
@@ -10,8 +10,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const supported_ops_1 = require("./supported-ops"); | ||
const utils_1 = require("./utils"); | ||
const naming_strategies_1 = require("./naming-strategies"); | ||
const fs = __importStar(require("fs-extra")); | ||
const path = __importStar(require("path")); | ||
const DMMF = __importStar(require("./dmmf")); | ||
const mapping_1 = require("./mapping"); | ||
const naming_strategies_1 = require("./naming-strategies"); | ||
function generateSync(options) { | ||
@@ -69,24 +68,10 @@ doGenerate(true, options); | ||
function renderNexusPrismaTypes(dmmf) { | ||
const queryFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const queriesNames = supported_ops_1.getSupportedQueries(mapping); | ||
return { | ||
fields: dmmf.queryObject.fields.filter(query => queriesNames.includes(query.name)), | ||
mapping, | ||
}; | ||
}); | ||
const queriesByType = utils_1.flatMap(queryFieldsWithMapping, ({ fields, mapping }) => fields.map(field => ({ | ||
fieldName: utils_1.getCRUDFieldName(mapping.model, field.name, mapping, naming_strategies_1.defaultFieldNamingStrategy), | ||
returnType: field.outputType.type, | ||
}))); | ||
const mutationsFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const mutationsNames = supported_ops_1.getSupportedMutations(mapping); | ||
return { | ||
fields: dmmf.mutationObject.fields.filter(mutation => mutationsNames.includes(mutation.name)), | ||
mapping, | ||
}; | ||
}); | ||
const mutationsByType = utils_1.flatMap(mutationsFieldsWithMapping, ({ fields, mapping }) => fields.map(field => ({ | ||
fieldName: utils_1.getCRUDFieldName(mapping.model, field.name, mapping, naming_strategies_1.defaultFieldNamingStrategy), | ||
returnType: field.outputType.type, | ||
}))); | ||
const queriesByType = mapping_1.getCrudMappedFields('Query', dmmf).map(mappedfield => ({ | ||
fieldName: mappedfield.field.name, | ||
returnType: mappedfield.field.outputType.type, | ||
})); | ||
const mutationsByType = mapping_1.getCrudMappedFields('Mutation', dmmf).map(mappedField => ({ | ||
fieldName: mappedField.field.name, | ||
returnType: mappedField.field.outputType.type, | ||
})); | ||
const fieldsByType = dmmf.datamodel.models.reduce((acc, m) => { | ||
@@ -118,24 +103,18 @@ acc[m.name] = m.fields.map(f => ({ | ||
function renderNexusPrismaInputs(dmmf) { | ||
const queryFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const queriesNames = supported_ops_1.getSupportedQueries(mapping); | ||
return { | ||
fields: dmmf.queryObject.fields | ||
.filter(query => queriesNames.includes(query.name)) | ||
.filter(q => q.outputType.isList && q.outputType.kind === 'object'), | ||
mapping, | ||
}; | ||
}); | ||
const queriesFields = utils_1.flatMap(queryFieldsWithMapping, ({ fields, mapping }) => fields.map(field => { | ||
const whereArg = field.args.find(a => a.name === 'where'); | ||
const orderByArg = field.args.find(a => a.name === 'orderBy'); | ||
const queriesFields = mapping_1.getCrudMappedFields('Query', dmmf) | ||
.filter(mappedField => mappedField.field.outputType.isList && | ||
mappedField.field.outputType.kind === 'object') | ||
.map(mappedField => { | ||
const whereArg = mappedField.field.args.find(a => a.name === 'where'); | ||
const orderByArg = mappedField.field.args.find(a => a.name === 'orderBy'); | ||
const whereInput = dmmf.schema.inputTypes.find(i => i.name === whereArg.inputType.type); | ||
const orderByInput = dmmf.schema.inputTypes.find(i => i.name === orderByArg.inputType.type); | ||
return { | ||
fieldName: utils_1.getCRUDFieldName(mapping.model, field.name, mapping, naming_strategies_1.defaultFieldNamingStrategy), | ||
fieldName: naming_strategies_1.defaultFieldNamingStrategy[mappedField.operation](mappedField.field.name, mappedField.model), | ||
filtering: whereInput, | ||
ordering: orderByInput, | ||
}; | ||
})); | ||
}); | ||
const fieldsByType = dmmf.datamodel.models | ||
.map(m => dmmf.schema.outputTypes.find(o => o.name === m.name)) | ||
.map(m => dmmf.getOutputType(m.name)) | ||
.reduce((acc, type) => { | ||
@@ -190,3 +169,3 @@ acc[type.name] = type.fields | ||
return `\ | ||
type ModelNameExistsInGraphQLType< | ||
type IsModelNameExistsInGraphQLTypes< | ||
ReturnType extends any | ||
@@ -212,2 +191,5 @@ > = ReturnType extends core.GetGen<'objectNames'> ? true : false; | ||
/** | ||
* Determine if \`B\` is a subset (or equivalent to) of \`A\`. | ||
*/ | ||
type IsSubset<A, B> = keyof A extends never | ||
@@ -241,3 +223,3 @@ ? false | ||
type DynamicRequiredType<ReturnType extends any> = ModelNameExistsInGraphQLType< | ||
type DynamicRequiredType<ReturnType extends any> = IsModelNameExistsInGraphQLTypes< | ||
ReturnType | ||
@@ -313,3 +295,3 @@ > extends true | ||
? (opts?: NexusPrismaScalarOpts) => NexusPrismaFields<ModelName> // Return optional scalar opts | ||
: ModelNameExistsInGraphQLType<ReturnType> extends true // If model name has a mapped graphql types | ||
: IsModelNameExistsInGraphQLTypes<ReturnType> extends true // If model name has a mapped graphql types | ||
? ( | ||
@@ -316,0 +298,0 @@ opts?: NexusPrismaRelationOpts<ModelName, MethodName, ReturnType> |
@@ -1,3 +0,1 @@ | ||
import * as DMMF from './dmmf'; | ||
import { FieldNamingStrategy } from './naming-strategies'; | ||
/** | ||
@@ -10,3 +8,3 @@ * TODO | ||
export declare function flatMap<T, U>(array: T[], callbackfn: (value: T, index: number, array: T[]) => U[]): U[]; | ||
export declare function nexusFieldOpts(param: { | ||
export declare function dmmfFieldToNexusFieldConfig(param: { | ||
type: string | object; | ||
@@ -23,3 +21,2 @@ isList: boolean; | ||
export declare function getImportPathRelativeToOutput(from: string, to: string): string; | ||
export declare function getCRUDFieldName(modelName: string, fieldName: string, mapping: DMMF.Data.Mapping, namingStrategy: FieldNamingStrategy): string; | ||
/** | ||
@@ -26,0 +23,0 @@ * Unwrap nexus user-defined types and convert them to a map<TypeName, boolean> |
@@ -46,3 +46,3 @@ "use strict"; | ||
exports.flatMap = flatMap; | ||
function nexusFieldOpts(param) { | ||
function dmmfFieldToNexusFieldConfig(param) { | ||
return { | ||
@@ -54,3 +54,3 @@ type: param.type, | ||
} | ||
exports.nexusFieldOpts = nexusFieldOpts; | ||
exports.dmmfFieldToNexusFieldConfig = dmmfFieldToNexusFieldConfig; | ||
function assertPhotonInContext(photon) { | ||
@@ -86,10 +86,2 @@ if (!photon) { | ||
exports.getImportPathRelativeToOutput = getImportPathRelativeToOutput; | ||
function getCRUDFieldName(modelName, fieldName, mapping, namingStrategy) { | ||
const operationName = Object.keys(mapping).find(key => mapping[key] === fieldName); | ||
if (!operationName || !namingStrategy[operationName]) { | ||
throw new Error(`Could not find mapping for field ${fieldName}`); | ||
} | ||
return namingStrategy[operationName](fieldName, modelName); | ||
} | ||
exports.getCRUDFieldName = getCRUDFieldName; | ||
/** | ||
@@ -96,0 +88,0 @@ * Unwrap nexus user-defined types and convert them to a map<TypeName, boolean> |
{ | ||
"name": "nexus-prisma", | ||
"version": "0.5.0-next.1", | ||
"version": "0.5.0-next.2", | ||
"main": "dist/index.js", | ||
@@ -17,3 +17,3 @@ "types": "dist/index.d.ts", | ||
"prepublishOnly": "yarn -s build", | ||
"style": "prettier --write src/**/*.ts test/**/*.ts example/**/*.ts", | ||
"style": "prettier --write 'src/**/*.ts' 'test/**/*.ts' 'example/**/*.ts'", | ||
"test": "jest" | ||
@@ -20,0 +20,0 @@ }, |
@@ -6,17 +6,12 @@ import * as Nexus from 'nexus' | ||
import * as GraphQL from './graphql' | ||
import { getCrudMappedFields } from './mapping' | ||
import { | ||
ArgsNamingStrategy, | ||
defaultArgsNamingStrategy, | ||
defaultFieldNamingStrategy, | ||
ArgsNamingStrategy, | ||
FieldNamingStrategy, | ||
} from './naming-strategies' | ||
import { Publisher } from './publisher' | ||
import { getSupportedMutations, getSupportedQueries } from './supported-ops' | ||
import * as Typegen from './typegen' | ||
import { | ||
assertPhotonInContext, | ||
getCRUDFieldName, | ||
nexusFieldOpts, | ||
unwrapTypes, | ||
} from './utils' | ||
import { assertPhotonInContext, unwrapTypes } from './utils' | ||
@@ -31,5 +26,8 @@ interface FieldPublisherConfig { | ||
type FieldPublisher = (opts?: FieldPublisherConfig) => PublisherMethods // Fluent API | ||
type PublisherMethods = Record<string, FieldPublisher> | ||
export interface Options { | ||
types: any | ||
photon?: (ctx: any) => any | ||
photon?: (ctx: Nexus.core.GetGen<'context'>) => any | ||
shouldGenerateArtifacts?: boolean | ||
@@ -155,4 +153,4 @@ inputs?: { | ||
// Nexus should improve the type of typeName to be AllOutputTypes | ||
factory: ({ typeDef: t, typeName: gqlTypeName }) => { | ||
if (gqlTypeName === GraphQL.rootNames.Subscription) { | ||
factory: ({ typeDef: t, typeName }) => { | ||
if (typeName === GraphQL.rootNames.Subscription) { | ||
// TODO Lets put a GitHub issue link in this error message | ||
@@ -165,90 +163,47 @@ throw new Error( | ||
if ( | ||
gqlTypeName !== GraphQL.rootNames.Query && | ||
gqlTypeName !== GraphQL.rootNames.Mutation | ||
typeName !== GraphQL.rootNames.Query && | ||
typeName !== GraphQL.rootNames.Mutation | ||
) { | ||
throw new Error( | ||
`t.crud can only be used on GraphQL root types 'Query' & 'Mutation' but was used on '${gqlTypeName}'. Please use 't.model' instead`, | ||
`t.crud can only be used on GraphQL root types 'Query' & 'Mutation' but was used on '${typeName}'. Please use 't.model' instead`, | ||
) | ||
} | ||
return getCrudMappedFields(typeName, this.dmmf).reduce< | ||
PublisherMethods | ||
>((crud, mappedField) => { | ||
const fieldPublisher: FieldPublisher = givenConfig => { | ||
const resolvedConfig: FieldPublisherConfig = { | ||
pagination: true, | ||
type: mappedField.field.outputType.type, | ||
...givenConfig, | ||
} | ||
const gqlFieldName = resolvedConfig.alias || mappedField.field.name | ||
const mappedFields = | ||
gqlTypeName === 'Query' | ||
? this.dmmf.mappings.map(mapping => { | ||
const queriesNames = getSupportedQueries(mapping) | ||
return { | ||
fields: this.dmmf.queryObject.fields.filter(query => | ||
queriesNames.includes(query.name), | ||
), | ||
mapping, | ||
} | ||
}) | ||
: gqlTypeName === 'Mutation' | ||
? this.dmmf.mappings.map(mapping => { | ||
const mutationsNames = getSupportedMutations(mapping) | ||
return { | ||
fields: this.dmmf.mutationObject.fields.filter(mutation => | ||
mutationsNames.includes(mutation.name), | ||
), | ||
mapping, | ||
} | ||
}) | ||
: (undefined as never) | ||
t.field(gqlFieldName, { | ||
type: this.publisher.outputType( | ||
resolvedConfig.type!, | ||
mappedField.field, | ||
), | ||
list: mappedField.field.outputType.isList || undefined, | ||
nullable: !mappedField.field.outputType.isRequired, | ||
args: this.buildArgsFromField( | ||
typeName, | ||
mappedField.operation, | ||
mappedField.field, | ||
resolvedConfig, | ||
), | ||
resolve: (_parent, args, ctx) => { | ||
const photon = this.getPhoton(ctx) | ||
assertPhotonInContext(photon) | ||
return photon[mappedField.photonAccessor][ | ||
mappedField.operation | ||
](args) | ||
}, | ||
}) | ||
type FieldPublisher = (opts?: FieldPublisherConfig) => CRUDMethods // Fluent API | ||
type CRUDMethods = Record<string, FieldPublisher> | ||
return crud | ||
} | ||
return mappedFields.reduce<CRUDMethods>((crud, mappedField) => { | ||
const prismaModelName = mappedField.mapping.model | ||
crud[mappedField.field.name] = fieldPublisher | ||
mappedField.fields.forEach(field => { | ||
const mappedFieldName = getCRUDFieldName( | ||
prismaModelName, | ||
field.name, | ||
mappedField.mapping, | ||
this.fieldNamingStrategy, | ||
) | ||
const fieldPublisher: FieldPublisher = givenConfig => { | ||
const resolvedConfig: FieldPublisherConfig = { | ||
pagination: true, | ||
type: field.outputType.type, | ||
...givenConfig, | ||
} | ||
const gqlFieldName = resolvedConfig.alias | ||
? resolvedConfig.alias | ||
: mappedFieldName | ||
const operationName = Object.keys(mappedField.mapping).find( | ||
key => (mappedField.mapping as any)[key] === field.name, | ||
) as keyof DMMF.Data.Mapping | undefined | ||
if (!operationName) { | ||
throw new Error( | ||
`Could not find operation name for field ${field.name}`, | ||
) | ||
} | ||
t.field(gqlFieldName, { | ||
type: this.publisher.outputType(resolvedConfig.type!, field), | ||
list: field.outputType.isList || undefined, | ||
nullable: !field.outputType.isRequired, | ||
args: this.buildArgsFromField( | ||
prismaModelName, | ||
gqlTypeName, | ||
operationName, | ||
field, | ||
resolvedConfig, | ||
), | ||
resolve: (_parent, args, ctx) => { | ||
const photon = this.getPhoton(ctx) | ||
assertPhotonInContext(photon) | ||
return photon[mappedField.mapping.plural!][operationName]( | ||
args, | ||
) | ||
}, | ||
}) | ||
return crud | ||
} | ||
crud[mappedFieldName] = fieldPublisher | ||
}) | ||
return crud | ||
@@ -313,18 +268,73 @@ }, {}) | ||
this.dmmf.hasModel(typeName) | ||
? this.buildModelDo(typeName, typeName, typeDef) | ||
: (modelName: string) => | ||
this.buildModelDo(modelName, modelName, typeDef), | ||
? this.internalBuildModel(typeName, typeDef) | ||
: (modelName: string) => this.internalBuildModel(modelName, typeDef), | ||
}) | ||
} | ||
protected internalBuildModel( | ||
typeName: string, | ||
t: Nexus.core.OutputDefinitionBlock<any>, | ||
) { | ||
const model = this.dmmf.getModelOrThrow(typeName) | ||
const outputType = this.dmmf.getOutputType(model.name) | ||
const publishers = outputType.fields.reduce<PublisherMethods>( | ||
(acc, field) => { | ||
const fieldPublisher: FieldPublisher = givenConfig => { | ||
const resolvedConfig: FieldPublisherConfig = { | ||
pagination: true, | ||
type: field.outputType.type, | ||
...givenConfig, | ||
} | ||
const fieldName = resolvedConfig.alias || field.name | ||
const type = resolvedConfig.type || field.outputType.type | ||
const fieldOpts: Nexus.core.NexusOutputFieldConfig<any, string> = { | ||
type: this.publisher.outputType(type, field), | ||
list: field.outputType.isList || undefined, | ||
nullable: !field.outputType.isRequired, | ||
args: this.buildArgsFromField( | ||
typeName, | ||
null, | ||
field, | ||
resolvedConfig, | ||
), | ||
} | ||
// Rely on default resolvers for scalars and enums | ||
if (field.outputType.kind === 'object') { | ||
const mapping = this.dmmf.getMapping(typeName) | ||
fieldOpts.resolve = (root, args, ctx) => { | ||
const photon = this.getPhoton(ctx) | ||
assertPhotonInContext(photon) | ||
return photon[mapping.plural!] | ||
['findOne']({ where: { id: root.id } }) | ||
[field.name](args) | ||
} | ||
} | ||
t.field(fieldName, fieldOpts) | ||
return publishers | ||
} | ||
acc[field.name] = fieldPublisher | ||
return acc | ||
}, | ||
{}, | ||
) | ||
return publishers | ||
} | ||
protected buildArgsFromField( | ||
prismaModelName: string, | ||
graphQLTypeName: string, | ||
typeName: string, | ||
operationName: keyof DMMF.Data.Mapping | null, | ||
field: DMMF.Data.SchemaField, | ||
opts: FieldPublisherConfig, | ||
resolvedConfig: FieldPublisherConfig, | ||
): Nexus.core.ArgsRecord { | ||
let args: CustomInputArg[] = [] | ||
if (graphQLTypeName === 'Mutation' || operationName === 'findOne') { | ||
if (typeName === 'Mutation' || operationName === 'findOne') { | ||
args = field.args.map(arg => ({ | ||
@@ -335,8 +345,3 @@ arg, | ||
} else { | ||
args = this.argsFromQueryOrModelField( | ||
prismaModelName, | ||
graphQLTypeName, | ||
field, | ||
opts, | ||
) | ||
args = this.argsFromQueryOrModelField(typeName, field, resolvedConfig) | ||
} | ||
@@ -346,2 +351,3 @@ | ||
acc[customArg.arg.name] = this.publisher.inputType(customArg) as any //FIXME | ||
return acc | ||
@@ -352,10 +358,9 @@ }, {}) | ||
protected argsFromQueryOrModelField( | ||
prismaModelName: string, | ||
graphQLTypeName: string, | ||
typeName: string, | ||
dmmfField: DMMF.Data.SchemaField, | ||
opts: FieldPublisherConfig, | ||
resolvedConfig: FieldPublisherConfig, | ||
) { | ||
let args: CustomInputArg[] = [] | ||
if (opts.filtering) { | ||
if (resolvedConfig.filtering) { | ||
const inputObjectTypeDefName = `${dmmfField.outputType.type}WhereInput` | ||
@@ -369,3 +374,3 @@ const whereArg = dmmfField.args.find( | ||
throw new Error( | ||
`Could not find filtering argument for ${prismaModelName}.${dmmfField.name}`, | ||
`Could not find filtering argument for ${typeName}.${dmmfField.name}`, | ||
) | ||
@@ -377,6 +382,6 @@ } | ||
type: this.handleInputObjectCustomization( | ||
opts.filtering, | ||
resolvedConfig.filtering, | ||
inputObjectTypeDefName, | ||
dmmfField.name, | ||
graphQLTypeName, | ||
typeName, | ||
), | ||
@@ -386,3 +391,3 @@ }) | ||
if (opts.ordering) { | ||
if (resolvedConfig.ordering) { | ||
const orderByTypeName = `${dmmfField.outputType.type}OrderByInput` | ||
@@ -395,3 +400,3 @@ const orderByArg = dmmfField.args.find( | ||
throw new Error( | ||
`Could not find ordering argument for ${prismaModelName}.${dmmfField.name}`, | ||
`Could not find ordering argument for ${typeName}.${dmmfField.name}`, | ||
) | ||
@@ -403,6 +408,6 @@ } | ||
type: this.handleInputObjectCustomization( | ||
opts.ordering, | ||
resolvedConfig.ordering, | ||
orderByTypeName, | ||
dmmfField.name, | ||
graphQLTypeName, | ||
typeName, | ||
), | ||
@@ -412,9 +417,9 @@ }) | ||
if (opts.pagination) { | ||
if (resolvedConfig.pagination) { | ||
const paginationKeys = ['first', 'last', 'before', 'after', 'skip'] | ||
const paginationsArgs = | ||
opts.pagination === true | ||
resolvedConfig.pagination === true | ||
? dmmfField.args.filter(a => paginationKeys.includes(a.name)) | ||
: dmmfField.args.filter( | ||
arg => (opts.pagination as any)[arg.name] === true, | ||
arg => (resolvedConfig.pagination as any)[arg.name] === true, | ||
) | ||
@@ -484,62 +489,2 @@ | ||
} | ||
/** | ||
* Build the properties on a .model for a given prisma model. | ||
*/ | ||
protected buildModelDo( | ||
prismaModelName: string, | ||
graphQLTypeName: string, | ||
t: Nexus.core.OutputDefinitionBlock<any>, | ||
) { | ||
const model = this.dmmf.getModelOrThrow(prismaModelName) | ||
const outputType = this.dmmf.getOutputType(model.name) | ||
const seed: Record<string, (opts?: FieldPublisherConfig) => any> = {} | ||
const result = outputType.fields.reduce((acc, graphqlField) => { | ||
acc[graphqlField.name] = opts => { | ||
if (!opts) { | ||
opts = {} | ||
} | ||
if (opts.pagination === undefined) { | ||
opts.pagination = true | ||
} | ||
const fieldName = opts.alias ? opts.alias : graphqlField.name | ||
const type = opts.type ? opts.type : graphqlField.outputType.type | ||
const fieldOpts: Nexus.core.NexusOutputFieldConfig<any, string> = { | ||
...nexusFieldOpts({ | ||
...graphqlField.outputType, | ||
type: this.publisher.outputType(type, graphqlField), | ||
}), | ||
args: this.buildArgsFromField( | ||
prismaModelName, | ||
graphQLTypeName, | ||
null, | ||
graphqlField, | ||
opts, | ||
), | ||
} | ||
// Rely on default resolvers for scalars and enums | ||
if (graphqlField.outputType.kind === 'object') { | ||
const mapping = this.dmmf.getMapping(prismaModelName) | ||
fieldOpts.resolve = (root, args, ctx) => { | ||
const photon = this.getPhoton(ctx) | ||
assertPhotonInContext(photon) | ||
return photon[mapping.plural!] | ||
['findOne']({ where: { id: root.id } }) | ||
[graphqlField.name](args) | ||
} | ||
} | ||
t.field(fieldName, fieldOpts) | ||
return result | ||
} | ||
return acc | ||
}, seed) | ||
return result | ||
} | ||
} |
@@ -8,6 +8,7 @@ import { ExternalDMMF as DMMF } from './transformer' | ||
public mappings: DMMF.Mapping[] | ||
public queryObject: DMMF.OutputType | ||
public mutationObject: DMMF.OutputType | ||
public queryObject: OutputType | ||
public mutationObject: OutputType | ||
public outputTypesIndex: Index<DMMF.OutputType> = {} | ||
public inputTypesIndex: Index<DMMF.InputType> | ||
public mappingsIndex: Index<DMMF.Mapping> | ||
public enumsIndex: Index<DMMF.Enum> | ||
@@ -22,6 +23,2 @@ public modelsIndex: Index<DMMF.Model> | ||
// Entrypoints | ||
this.queryObject = schema.outputTypes.find(t => t.name === 'Query')! | ||
this.mutationObject = schema.outputTypes.find(t => t.name === 'Mutation')! | ||
// Indices | ||
@@ -32,2 +29,7 @@ this.modelsIndex = indexBy('name', datamodel.models) | ||
this.outputTypesIndex = indexBy('name', schema.outputTypes) | ||
this.mappingsIndex = indexBy('model', mappings) | ||
// Entrypoints | ||
this.queryObject = this.getOutputType('Query') | ||
this.mutationObject = this.getOutputType('Mutation') | ||
} | ||
@@ -52,3 +54,3 @@ | ||
return outputType | ||
return new OutputType(outputType) | ||
} | ||
@@ -107,3 +109,3 @@ | ||
getMapping(modelName: string) { | ||
const mapping = this.mappings.find(m => m.model === modelName) | ||
const mapping = this.mappingsIndex[modelName] | ||
@@ -117,1 +119,25 @@ if (!mapping) { | ||
} | ||
export class OutputType { | ||
public name: string | ||
public fields: DMMF.SchemaField[] | ||
public isEmbedded?: boolean | ||
constructor(protected outputType: DMMF.OutputType) { | ||
this.name = outputType.name | ||
this.fields = outputType.fields | ||
this.isEmbedded = outputType.isEmbedded | ||
} | ||
getField(fieldName: string) { | ||
const field = this.outputType.fields.find(f => f.name === fieldName) | ||
if (!field) { | ||
throw new Error( | ||
`Could not find field field '${fieldName}' on type ${this.outputType.name}`, | ||
) | ||
} | ||
return field | ||
} | ||
} |
@@ -179,11 +179,11 @@ import * as Nexus from 'nexus' | ||
model: string | ||
plural?: string | ||
findOne?: string | ||
findMany?: string | ||
create?: string | ||
update?: string | ||
updateMany?: string | ||
upsert?: string | ||
delete?: string | ||
deleteMany?: string | ||
plural: string | ||
findOne: string | ||
findMany: string | ||
create: string | ||
update: string | ||
updateMany: string | ||
upsert: string | ||
delete: string | ||
deleteMany: string | ||
} | ||
@@ -190,0 +190,0 @@ enum ModelAction { |
import * as Nexus from 'nexus' | ||
import * as DMMF from './dmmf' | ||
import { nexusFieldOpts, partition } from './utils' | ||
import { dmmfFieldToNexusFieldConfig, partition } from './utils' | ||
import { CustomInputArg } from './builder' | ||
@@ -26,3 +26,3 @@ import { scalarsNameValues } from './graphql' | ||
return Nexus.arg( | ||
nexusFieldOpts({ | ||
dmmfFieldToNexusFieldConfig({ | ||
...customArg.arg.inputType, | ||
@@ -56,3 +56,3 @@ type: customArg.type.name, | ||
if (field.outputType.kind === 'object') { | ||
return outputTypeName | ||
return this.publishObject(outputTypeName) | ||
} | ||
@@ -71,2 +71,15 @@ | ||
protected publishObject(name: string) { | ||
this.markTypeAsPublished(name) | ||
const dmmfObject = this.dmmf.getOutputType(name) | ||
return Nexus.objectType({ | ||
name, | ||
definition: t => { | ||
for (const field of dmmfObject.fields) { | ||
t.field(field.name, dmmfFieldToNexusFieldConfig(field.outputType)) | ||
} | ||
}, | ||
}) | ||
} | ||
protected publishScalar(typeName: string) { | ||
@@ -88,3 +101,3 @@ if (scalarsNameValues.includes(typeName as any)) { | ||
protected publishEnum(typeName: string) { | ||
const eType = this.dmmf.getEnumType(typeName) | ||
const dmmfEnum = this.dmmf.getEnumType(typeName) | ||
@@ -95,3 +108,3 @@ this.markTypeAsPublished(typeName) | ||
name: typeName, | ||
members: eType.values, | ||
members: dmmfEnum.values, | ||
}) | ||
@@ -125,3 +138,3 @@ } | ||
;[...scalarFields, ...remappedObjectFields].forEach(field => { | ||
t.field(field.name, nexusFieldOpts(field.inputType)) | ||
t.field(field.name, dmmfFieldToNexusFieldConfig(field.inputType)) | ||
}) | ||
@@ -134,3 +147,5 @@ }, | ||
const kindToType = { | ||
scalar: (typeName: string) => this.dmmf.getOutputType(typeName), | ||
scalar: (typeName: string) => ({ | ||
name: this.dmmf.getOutputType(typeName).name, | ||
}), | ||
enum: (typeName: string) => this.dmmf.getEnumType(typeName), | ||
@@ -137,0 +152,0 @@ object: (typeName: string) => this.dmmf.getInputType(typeName), |
@@ -1,7 +0,6 @@ | ||
import { getSupportedQueries, getSupportedMutations } from './supported-ops' | ||
import { flatMap, getCRUDFieldName } from './utils' | ||
import { defaultFieldNamingStrategy } from './naming-strategies' | ||
import * as fs from 'fs-extra' | ||
import * as path from 'path' | ||
import * as DMMF from './dmmf' | ||
import { getCrudMappedFields } from './mapping' | ||
import { defaultFieldNamingStrategy } from './naming-strategies' | ||
@@ -70,45 +69,12 @@ type Options = { | ||
function renderNexusPrismaTypes(dmmf: DMMF.DMMF) { | ||
const queryFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const queriesNames = getSupportedQueries(mapping) | ||
return { | ||
fields: dmmf.queryObject.fields.filter(query => | ||
queriesNames.includes(query.name), | ||
), | ||
mapping, | ||
} | ||
}) | ||
const queriesByType = flatMap(queryFieldsWithMapping, ({ fields, mapping }) => | ||
fields.map(field => ({ | ||
fieldName: getCRUDFieldName( | ||
mapping.model, | ||
field.name, | ||
mapping, | ||
defaultFieldNamingStrategy, | ||
), | ||
returnType: field.outputType.type, | ||
})), | ||
const queriesByType = getCrudMappedFields('Query', dmmf).map(mappedfield => ({ | ||
fieldName: mappedfield.field.name, | ||
returnType: mappedfield.field.outputType.type, | ||
})) | ||
const mutationsByType = getCrudMappedFields('Mutation', dmmf).map( | ||
mappedField => ({ | ||
fieldName: mappedField.field.name, | ||
returnType: mappedField.field.outputType.type, | ||
}), | ||
) | ||
const mutationsFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const mutationsNames = getSupportedMutations(mapping) | ||
return { | ||
fields: dmmf.mutationObject.fields.filter(mutation => | ||
mutationsNames.includes(mutation.name), | ||
), | ||
mapping, | ||
} | ||
}) | ||
const mutationsByType = flatMap( | ||
mutationsFieldsWithMapping, | ||
({ fields, mapping }) => | ||
fields.map(field => ({ | ||
fieldName: getCRUDFieldName( | ||
mapping.model, | ||
field.name, | ||
mapping, | ||
defaultFieldNamingStrategy, | ||
), | ||
returnType: field.outputType.type, | ||
})), | ||
) | ||
const fieldsByType = dmmf.datamodel.models.reduce< | ||
@@ -153,15 +119,11 @@ Record<string, { fieldName: string; returnType: string }[]> | ||
function renderNexusPrismaInputs(dmmf: DMMF.DMMF) { | ||
const queryFieldsWithMapping = dmmf.mappings.map(mapping => { | ||
const queriesNames = getSupportedQueries(mapping) | ||
return { | ||
fields: dmmf.queryObject.fields | ||
.filter(query => queriesNames.includes(query.name)) | ||
.filter(q => q.outputType.isList && q.outputType.kind === 'object'), | ||
mapping, | ||
} | ||
}) | ||
const queriesFields = flatMap(queryFieldsWithMapping, ({ fields, mapping }) => | ||
fields.map(field => { | ||
const whereArg = field.args.find(a => a.name === 'where')! | ||
const orderByArg = field.args.find(a => a.name === 'orderBy')! | ||
const queriesFields = getCrudMappedFields('Query', dmmf) | ||
.filter( | ||
mappedField => | ||
mappedField.field.outputType.isList && | ||
mappedField.field.outputType.kind === 'object', | ||
) | ||
.map(mappedField => { | ||
const whereArg = mappedField.field.args.find(a => a.name === 'where')! | ||
const orderByArg = mappedField.field.args.find(a => a.name === 'orderBy')! | ||
const whereInput = dmmf.schema.inputTypes.find( | ||
@@ -175,7 +137,5 @@ i => i.name === whereArg.inputType.type, | ||
return { | ||
fieldName: getCRUDFieldName( | ||
mapping.model, | ||
field.name, | ||
mapping, | ||
defaultFieldNamingStrategy, | ||
fieldName: defaultFieldNamingStrategy[mappedField.operation]( | ||
mappedField.field.name, | ||
mappedField.model, | ||
), | ||
@@ -185,7 +145,6 @@ filtering: whereInput, | ||
} | ||
}), | ||
) | ||
}) | ||
const fieldsByType = dmmf.datamodel.models | ||
.map(m => dmmf.schema.outputTypes.find(o => o.name === m.name)!) | ||
.map(m => dmmf.getOutputType(m.name)) | ||
.reduce< | ||
@@ -270,3 +229,3 @@ Record< | ||
return `\ | ||
type ModelNameExistsInGraphQLType< | ||
type IsModelNameExistsInGraphQLTypes< | ||
ReturnType extends any | ||
@@ -292,2 +251,5 @@ > = ReturnType extends core.GetGen<'objectNames'> ? true : false; | ||
/** | ||
* Determine if \`B\` is a subset (or equivalent to) of \`A\`. | ||
*/ | ||
type IsSubset<A, B> = keyof A extends never | ||
@@ -321,3 +283,3 @@ ? false | ||
type DynamicRequiredType<ReturnType extends any> = ModelNameExistsInGraphQLType< | ||
type DynamicRequiredType<ReturnType extends any> = IsModelNameExistsInGraphQLTypes< | ||
ReturnType | ||
@@ -393,3 +355,3 @@ > extends true | ||
? (opts?: NexusPrismaScalarOpts) => NexusPrismaFields<ModelName> // Return optional scalar opts | ||
: ModelNameExistsInGraphQLType<ReturnType> extends true // If model name has a mapped graphql types | ||
: IsModelNameExistsInGraphQLTypes<ReturnType> extends true // If model name has a mapped graphql types | ||
? ( | ||
@@ -396,0 +358,0 @@ opts?: NexusPrismaRelationOpts<ModelName, MethodName, ReturnType> |
import { isNamedType } from 'graphql' | ||
import { core } from 'nexus' | ||
import { relative } from 'path' | ||
import * as DMMF from './dmmf' | ||
import { OperationName, FieldNamingStrategy } from './naming-strategies' | ||
@@ -60,3 +58,3 @@ // TODO `any` should be `unknown` but there is a bug (?) | ||
export function nexusFieldOpts(param: { | ||
export function dmmfFieldToNexusFieldConfig(param: { | ||
type: string | object | ||
@@ -119,19 +117,2 @@ isList: boolean | ||
export function getCRUDFieldName( | ||
modelName: string, | ||
fieldName: string, | ||
mapping: DMMF.Data.Mapping, | ||
namingStrategy: FieldNamingStrategy, | ||
) { | ||
const operationName = Object.keys(mapping).find( | ||
key => (mapping as any)[key] === fieldName, | ||
) as OperationName | undefined | ||
if (!operationName || !namingStrategy[operationName]) { | ||
throw new Error(`Could not find mapping for field ${fieldName}`) | ||
} | ||
return namingStrategy[operationName](fieldName, modelName) | ||
} | ||
/** | ||
@@ -138,0 +119,0 @@ * Unwrap nexus user-defined types and convert them to a map<TypeName, boolean> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
146682
2925