UNPKG

@backland/schema

Version:

TypeScript schema declaration and validation library with static type inference

235 lines (204 loc) 7.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultTypesDest = exports.BacklandWatchTypesPubSub = void 0; exports.writeTypes = writeTypes; var _path = _interopRequireDefault(require("path")); var _utils = require("@backland/utils"); var _fsExtra = require("fs-extra"); var _CircularDeps = require("../CircularDeps"); var _LiteralField = require("../fields/LiteralField"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const { serialize } = _LiteralField.LiteralField.utils; const BacklandWatchTypesPubSub = (0, _utils.mitt)(); exports.BacklandWatchTypesPubSub = BacklandWatchTypesPubSub; const typesRecord = {}; const resolversRecord = {}; const customTypeRecord = {}; // APLICAR AOS RESOLVERS DA ENTITY, etc BacklandWatchTypesPubSub.on('created', async event => { var _event$graphType; if ((_event$graphType = event.graphType) !== null && _event$graphType !== void 0 && _event$graphType.optionalId) { typesRecord[`${event.graphType.id}`] = event.graphType; } if (event.resolver) { resolversRecord[`${event.resolver.name}`] = event.resolver; } if (event.custom) { customTypeRecord[event.custom.name] = event.custom; } save(); }); const defaultTypesDest = _path.default.resolve(_utils.Process.cwd(), 'src/generated/backland.d.ts'); exports.defaultTypesDest = defaultTypesDest; async function writeTypes(options) { const { dest = defaultTypesDest } = options || {}; (0, _fsExtra.ensureFileSync)(dest); const creators = Object.keys(typesRecord).map(name => { let txt = ''; const fn = [`function createType<Definition extends ObjectFieldInput>(name: "${name}",`, `definition: Definition):`, `GraphTypeRuntime<Definition,`, `RuntimeTypes["${name}"], "${name}">`, '\n'].join(' '); const getTypeFn = [`function getType(name: "${name}"): GraphTypeRuntime<RuntimeDefinitions["${name}"], RuntimeTypes["${name}"], "${name}">`].join(' '); txt += `\n export ${fn};\n`; txt += `\n export ${getTypeFn};\n`; txt += `\n export const Backland = { createType, getType };\n`; return txt; }); const resolvers = Object.keys(resolversRecord).map(name => { let txt = ''; const fn = [`function createResolver<Context, Source>(`, `options: ResolverRuntimeConfig<Context, Source, RuntimeTypes["${name}Payload"], RuntimeTypes["${name}Input"], "${name}">`, `): ResolverRuntime<Context, Source, RuntimeTypes["${name}Payload"], RuntimeTypes["${name}Input"], "${name}">`].join(' '); const getTypeFn = [`function getResolver(name: "${name}"): ResolverRuntime<Context, Source, RuntimeTypes["${name}Payload"], RuntimeTypes["${name}Input"], "${name}">`].join(' '); txt += `\n export ${fn};\n`; txt += `\n export ${getTypeFn};\n`; txt += `\n export const Backland = { createResolver, getResolver };\n`; return txt; }); const head = []; const body = []; const footer = []; Object.values(customTypeRecord).forEach(item => { item.head && head.push(...item.head); item.body && head.push(...item.body); item.footer && head.push(...item.footer); }); const typesInterface = await _CircularDeps.CircularDeps.objectToTypescript('RuntimeTypes', typesRecord); let definitions = Object.entries(typesRecord).reduce((acc, [id, next]) => { acc += `\n"${id}": ${serialize(next.definition)}\n;`; return acc; }, ''); definitions = `export interface RuntimeDefinitions {\n${definitions}\n}`; let content = template({ creators, definitions, extraCustomBody: body, extraCustomFooter: footer, extraCustomHead: head, resolvers, typesInterface }); content = await _CircularDeps.CircularDeps.prettier.format(content, { parser: 'typescript', singleQuote: true }); (0, _fsExtra.writeFileSync)(dest, content); } function template({ typesInterface, creators, resolvers, definitions, extraCustomHead, extraCustomBody, extraCustomFooter }) { return ` /* tslint-disable */ /* tslint:disable */ /* eslint-disable */ declare global { module '@backland/schema' { export * from '@backland/schema'; import { ObjectFieldInput, ValidationCustomMessage, FieldDefinitionConfig } from '@backland/schema'; import { Merge } from '@backland/utils'; import { GraphQLField, GraphQLFieldConfig, GraphQLResolveInfo, } from 'graphql'; ${extraCustomHead.join('\n')} export class GraphTypeRuntime<Definition extends FieldDefinitionConfig, Type, Name> { static __isGraphType: true; readonly __isGraphType: true; static reset(): Promise<void>; readonly definition: Definition; readonly id: Name; clone<Ext, NewName>( name: NewName, extend?: Ext ): GraphTypeRuntime<Definition & Ext, Type, NewName>; constructor(definition: Definition); constructor(name: Name, definition: Definition); parse(input: any, customMessage?: ValidationCustomMessage): Type; graphQLType(...args: unknown[]): typeof import('graphql').GraphQLNamedType; graphQLInputType( ...args: unknown[] ): typeof import('graphql').GraphQLNamedInputType; graphQLInterface( ...args: unknown[] ): typeof import('graphql').GraphQLInterfaceType; addRelation<FieldTypeDef, Name, Context = unknown, ArgsDef>( options: Merge< { type: FieldTypeDef; name: Name }, ResolverConfigRuntime<Context, unknown, FieldTypeDef, ArgsDef> > ): this; print(): string[]; typescriptPrint(options?: unknown): Promise<string>; } export type ResolverKind = 'query' | 'mutation' | 'subscription'; export interface ResolverConfigRuntime<Context, Source, Type, Args, Name> extends Omit<GraphQLFieldConfig<any, any>, 'resolve' | 'args' | 'type'> { name: Name; kind?: ResolverKind; args?: unknown; type: unknown; resolve( root: Source, args: Args, context: Context, info: GraphQLResolveInfo ): Type | Promise<Type>; } export interface ResolverRuntime<Context, Source, Type, Args, Name> extends Omit<GraphQLFieldConfig<any, any>, 'resolve' | 'args' | 'type'> { __isResolver: true; __isRelation: boolean; __graphTypeId: string; __relatedToGraphTypeId: string; resolve( root: Source, args: Args, context: Context, info: GraphQLResolveInfo ): Type | Promise<Type>; name: Name; kind: 'query' | 'subscription' | 'mutation'; typeDef: any; argsDef: any; payloadType: GraphTypeRuntime<any, Type, any>; argsType: GraphTypeRuntime<any, Args, any>; type: any; args: any; asObjectField(name?: string): GraphQLField<any, any>; } ${creators.join('\n')} ${resolvers.join('\n')} ${extraCustomBody.join('\n')} ${definitions} ${typesInterface} ${extraCustomFooter.join('\n')} } } `; } let timeoutRef; let timeoutMS = 2000; function save() { clearTimeout(timeoutRef); if (process.env.backland_emit_interval) { timeoutMS = +process.env.backland_emit_interval > 0 ? +process.env.backland_emit_interval : timeoutMS; timeoutRef = setTimeout(() => { writeTypes().catch(err => { console.error('writeTypes:', err.message); }); }, timeoutMS); } } process.on('unhandledRejection', () => { clearTimeout(timeoutRef); }); //# sourceMappingURL=writeTypes.js.map