venom-generator
Version:
In the way of code generation, complete the storage model->computation model (business API) transformation to achieve the goal of design and implementation
343 lines (342 loc) • 14.3 kB
JavaScript
;
//指令解析实现模块
Object.defineProperty(exports, "__esModule", { value: true });
const util = require("./util");
// @Query@Mutation指令生成业务代码
function publicMethods(category, typeName) {
const name = util.initialCase(typeName);
if (category === 'Query') {
return `'${name}s',`;
}
else {
return `'${typeName}',`;
}
}
exports.publicMethods = publicMethods;
// @Query@Mutation指令生成业务代码且需检查权限
function publicMethod(category, server, typeName, directive, authorization) {
// api备注说明
let description = directive.arguments.description;
description = description !== undefined ? description : '';
// 参数解析
const argumentsArgs = directive.arguments.args;
const args = argumentsArgs !== undefined && argumentsArgs !== '' ? argumentsArgs.split(',') : [];
const arg = argsResolver(category, args);
if (category === 'Query') {
const name = util.initialCase(typeName);
return ` t.list.field('${name}s', {
type: '${typeName}',
description: '${description}',
nullable: true,
args: {
${util.trim(util.trim(arg, '\n', 'right'), ',', 'right')}
},
resolve: async (_parent, args, ctx: Context) => {
${authorization}
return await ctx.p${server}.${name}s(args as any)
},
})\n`;
}
else {
return ` t.field('create${typeName}', {
type: '${typeName}',
description: '${directive.arguments.description}',
nullable: true,
args: {
data: arg({ type: '${typeName}CreateInput', nullable: false })
},
resolve: async (_parent, args, ctx: Context) => {
${authorization}
return await ctx.p${server}.create${typeName}(args.data as any)
},
})\n`;
}
}
exports.publicMethod = publicMethod;
// @QueryUnique指令生成业务代码
function privateMethod(server, typeName, directive, authorization, aud) {
// api备注说明
let description = directive.arguments.description;
description = description !== undefined ? description : '';
const name = util.initialCase(typeName);
// 参数解析
const argumentsArgs = directive.arguments.args;
const args = argumentsArgs !== undefined && argumentsArgs !== '' ? argumentsArgs.split(',') : [];
let arg = argsResolver('QueryUnique', args);
arg = arg !== '' ? arg : `id: arg({ type: 'String', nullable: false })`;
// const param = args.length === 1 && /where/.test(args[0]) ? 'args.where as any' : 'args as any'
// 拥有者权限解析
const audAuth = util.authAud(aud, args[0]);
const param = audAuth.external ? `s(${audAuth.param}).then(data => data[0])` : `(${audAuth.param})`;
// console.log('args--->', args, '\n', 'args--->', args.length === 1 && /where/.test(args[0]))
return ` t.field('${name}', {
type: '${typeName}',
description: '${description}',
nullable: true,
args: {
// id: stringArg({nullable: false})
// id: arg({ type: 'String', nullable: false }),
${util.trim(util.trim(arg, '\n', 'right'), ',', 'right')}
},
resolve: async (_parent, args, ctx: Context) => {
${authorization}
return await ctx.p${server}.${name}${param}
}
})\n`;
}
exports.privateMethod = privateMethod;
// @QueryResolve@MutationResolve指令生成业务代码
function customMethod(category, typeName, directive, authorization) {
const name = util.initialCase(typeName);
// api备注说明
let description = directive.arguments.description;
description = description !== undefined ? description : '';
// 自定义方法返回的参数类型
let argumentsType = directive.arguments.type;
argumentsType = argumentsType !== undefined && argumentsType !== '' ? argumentsType : typeName;
// 参数解析
const argumentsArgs = directive.arguments.args;
const args = argumentsArgs !== undefined && argumentsArgs !== '' ? argumentsArgs.split(',') : [];
const arg = argsResolver(category, args);
const list = directive.arguments.list;
return list === true
? ` t.list.field('${name}s', {
type: '${directive.arguments.type}',
description: '${description}',
nullable: true,
args: {
${util.trim(util.trim(arg, '\n', 'right'), ',', 'right')}
},
resolve: async (parent, args, ctx: Context) => {
${authorization}
return await ${name}Resolve(parent, args, ctx)
}
})\n`
: ` t.field('${name}', {
type: '${directive.arguments.type}',
description: '${description}',
nullable: true,
args: {
${util.trim(util.trim(arg, '\n', 'right'), ',', 'right')}
},
resolve: async (parent, args, ctx: Context) => {
${authorization}
return await ${name}Resolve(parent, args, ctx)
}
})\n`;
}
exports.customMethod = customMethod;
// @Filter指令生成业务代码
function filter(category, type) {
// 过滤掉无需处理的属性
const fields = type.fields.filter(type => type.directives.length !== 0);
let filter = '';
// 字段过滤
fields.forEach(field => {
field.directives.forEach(directive => {
let qisFilter = false;
let misFilter = false;
// 需要过滤时处理
if (directive.name === 'Filter') {
const q = directive.arguments.Query;
const m = directive.arguments.Mutation;
// console.log('mq--->', q, m)
qisFilter = q !== undefined && q === true;
misFilter = m !== undefined && m === true;
// 根据类型过滤
if (category === 'Query') {
if (qisFilter)
filter += `'${field.name}',`;
}
else {
if (misFilter)
filter += `'${field.name}',`;
}
}
});
});
// console.log('category--->', category, '\nfilter--->', filter)
// 根据类型生成过滤代码
if (category === 'Query' && filter !== '') {
return `export const ${type.name} = prismaObjectType({
name: '${type.name}',
definition(t) {
t.prismaFields({ filter: [${util.trim(filter, ',', 'right')}] })
}
})\n`;
}
else if (category === 'Mutation' && filter !== '') {
const filterInput = util.trim(filter, ',', 'right');
return `export const ${type.name}CreateInput = prismaInputObjectType({
name: '${type.name}CreateInput',
definition(t) {
t.prismaFields({ filter: [${filterInput}] })
}
})
export const ${type.name}UpdateInput = prismaInputObjectType({
name: '${type.name}UpdateInput',
definition(t) {
t.prismaFields({ filter: [${filterInput}] })
}
})\n`;
}
else {
return '';
}
}
exports.filter = filter;
// @Delete指令生成业务代码
function deleteMethod(server, typeName, directive, authorization) {
// api备注说明
let description = directive.arguments.description;
description = description !== undefined ? description : '';
// 参数解析
const argumentsArgs = directive.arguments.args;
const args = argumentsArgs !== undefined && argumentsArgs !== '' ? argumentsArgs.split(',') : [];
if (args.length === 0) {
console.log(`忽略@Mutation(delete)指令:${typeName},未获取到必要的参数\n`);
return '';
}
const arg = argsResolver('QueryUnique', args);
const param = args.length === 1 && /where/.test(args[0]) && !util.basicDataType(args[0].split(':')[1]) ? 'args.where as any' : 'args as any';
return ` t.field('delete${typeName}', {
type: '${typeName}',
description: '${description}',
nullable: true,
args: {
${util.trim(util.trim(arg, '\n', 'right'), ',', 'right')}
},
resolve: async (_parent, args, ctx: Context) => {
${authorization}
return await ctx.p${server}.delete${typeName}(${param})
}
})\n`;
}
exports.deleteMethod = deleteMethod;
// @Update指令生成业务代码
function updateMethod(server, typeName, directive, authorization) {
// api备注说明
let description = directive.arguments.description;
description = description !== undefined ? description : '';
return ` t.field('update${typeName}', {
type: '${typeName}',
description: '${description}',
nullable: true,
args: {
data: arg({ type: '${typeName}UpdateInput', nullable: false }),
where: arg({ type: '${typeName}WhereUniqueInput', nullable: false })
},
resolve: async (_parent, args, ctx: Context) => {
${authorization}
return await ctx.p${server}.update${typeName}(args as any)
}
})\n`;
}
exports.updateMethod = updateMethod;
// @QueryLink指令生成业务代码
function queryLinkMethod(typeName, queryLink) {
const to = queryLink.arguments.to;
const toArgs = queryLink.arguments.toArgs;
const result = queryLink.arguments.result;
const list = queryLink.arguments.list !== undefined ? queryLink.arguments.list : false;
const dataType = list ? `[${util.initialUpperCase(result)}]` : `${util.initialUpperCase(result)}`;
const importServer = `import { gSchema as ${queryLink.arguments.include}gSchema } from './common/${queryLink.arguments.include}/schema'\n`;
// 内嵌服务拼接
const serversgSchema = `${queryLink.arguments.include}gSchema,`;
// 内嵌服务类型拼接
const typeDefs = `extend type ${typeName} {
${to}: ${dataType}
}\n`;
// 内嵌服务代码生成
const resolvers = ` {
${typeName}: {
'${to}': {
fragment: \`fragment ${typeName}Fragment on ${typeName} { ${toArgs} }\`,
async resolve(parent, _args, context, info) {
const tenantId = parent.${toArgs}
return info.mergeInfo.delegate('query', '${to}', { ${toArgs} }, context, info)
}
}
}
},\n`;
return { importServer, serversgSchema, resolvers, typeDefs };
}
exports.queryLinkMethod = queryLinkMethod;
// 业务API文件数据生成
function operationApiCode(category, importCalcAuthorization, imports, prismaFields, fields, filters, argNexus) {
if (prismaFields === 't.prismaFields([])' && fields === '' && category === 'Mutation')
return '';
const imporNexus = argNexus !== '' ? `import { ${util.delRepetitionArr(argNexus.split(',').filter(a => a !== ''))} } from 'nexus'\n` : '';
const imporContext = fields !== '' ? `import { Context } from '../context'\n` : '';
const importNexusPrisma = filters !== '' && category === 'Mutation' ? `import { prismaObjectType, prismaInputObjectType } from 'nexus-prisma'\n` : `import { prismaObjectType } from 'nexus-prisma'\n`;
return `${importNexusPrisma}${imporNexus}${imporContext}${importCalcAuthorization}${imports}
export const ${category} = prismaObjectType({
name: '${category}',
definition(t) {
/**
* - use \`t.prismaFields(['*'])\` to expose all the underlying object type fields
* - use \`t.primaFields(['fieldName', ...])\` to pick and/or customize specific fields
* - use \`t.prismaFields({ filter: ['fieldName', ...] })\` to filter and/or customize specific fields
*/
// An empty array removes all fields from the underlying object type
${prismaFields}\n${fields}
}
})\n
${filters}
`;
}
exports.operationApiCode = operationApiCode;
// 参数处理
function argsResolver(category, args) {
let arg = '';
// 参数解析
args.forEach(a => {
const argArr = a.split(':');
if (argArr.length == 2) {
let paramName = util.underlineToCamel(argArr[0]);
let nullable = true;
// 是否必传,此处dataType必须这样写,不可替换成''
let dataType = util.trim(argArr[1], '!', '');
if (/!/.test(argArr[1]))
nullable = false;
const databaseType = util.basicDataType(dataType);
// 类型参数解析
switch (category) {
case 'Query':
dataType = databaseType == false ? `${dataType}${util.initialUpperCase(paramName)}Input` : dataType;
break;
case 'Mutation':
dataType = databaseType == false ? `${dataType}CreateInput` : dataType;
break;
case 'QueryUnique':
dataType = databaseType == false ? `${dataType}WhereUniqueInput` : dataType;
break;
case 'QueryResolve':
// 参数条件是否为唯一
if (paramName === 'where') {
dataType = databaseType == false ? `${dataType}WhereUniqueInput` : dataType;
}
else {
paramName = paramName === 'wheres' ? 'where' : paramName;
dataType = databaseType == false ? `${dataType}${util.initialUpperCase(paramName)}Input` : dataType;
}
break;
case 'MutationResolve':
if (paramName === 'where') {
dataType = databaseType == false ? `${dataType}WhereUniqueInput` : dataType;
}
else if (paramName === 'wheres') {
paramName = databaseType == false ? 'where' : paramName;
dataType = databaseType == false ? `${dataType}WhereInput` : dataType;
}
else if (paramName === 'data') {
dataType = databaseType == false ? `${util.initialUpperCase(dataType)}Input` : dataType;
}
break;
}
arg += databaseType === false ? ` ${paramName}: arg({ type: '${dataType}', nullable: ${nullable} }),\n` : ` ${paramName}: ${util.initialCase(dataType)}Arg({ nullable: ${nullable} }),\n`;
}
});
return arg;
}
//# sourceMappingURL=operation.js.map