{"version":3,"sources":["parser/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAc5B,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqDpM","file":"compile.d.ts","sourcesContent":["import ts from 'typescript';\n// import {readFileSync} from 'fs';\nimport { join, dirname, relative } from 'path';\nimport { parse as ParseModelFrom } from './parser';\nimport { PACKAGE_NAME } from '@src/config';\n// import { printTree } from '@src/utils/console-print';\nimport { format } from '@src/formatter/formatter';\nimport { info } from '@src/utils/log';\nimport { toGraphQL } from '@src/graphql/compiler';\nimport { _errorFile } from '@src/utils/error';\nimport { getFilesFromPattern } from '..';\nimport { printTree } from '@src/utils/console-print';\n\n// import { compileGraphQL } from \"@src/graphql/compiler\";\n\n/** Compile each file */\nexport function generateModel(\n\tfilePath: string,\n\tfileContent: string,\n\tcompilerOptions: ts.CompilerOptions,\n\tonModelFile: ((filePath: string) => void) | undefined,\n\tpretty: boolean\n): string | undefined {\n\tconst f = ts.factory;\n\t//* Load source file\n\tvar srcFile = ts.createSourceFile(\n\t\tfilePath,\n\t\tfileContent,\n\t\tcompilerOptions.target ?? ts.ScriptTarget.Latest,\n\t\ttrue\n\t);\n\t//* check for files with \"Model.from('glob-path')\"\n\tconst mappedFiles = mapFilesWithModel(srcFile);\n\n\tif (!mappedFiles.patterns.size) return;\n\n\t//* Resolve Model for each pattern\n\tconst relativeDirname = relative(process.cwd(), dirname(filePath));\n\tconst mapGqlPatternToNode: Map<string, ts.CallExpression> = new Map();\n\tconst mapFromPatternToNode: Map<string, ts.CallExpression> = new Map();\n\tconst listImports: ts.Statement[] = [];\n\tinfo(`Compile File>> ${filePath}`);\n\tconst srcFileDir = dirname(filePath);\n\tmappedFiles.patterns.forEach(function (p) {\n\t\tinfo('COMPILE PATTERN>>', p);\n\t\tconst filePaths = getFilesFromPattern(p, relativeDirname, onModelFile);\n\t\t//* Create compiler host\n\t\tinfo('>> Create program...');\n\t\tconst pHost = ts.createCompilerHost(compilerOptions, true);\n\t\t//* Create program\n\t\tconst program = ts.createProgram(filePaths, compilerOptions, pHost);\n\n\t\tvar root = ParseModelFrom(filePaths, program);\n\t\t// console.log('===ROOT===\\n', printTree(root, '\\t'));\n\t\t// Create graphql object\n\t\tinfo('>> FORMAT DATA');\n\t\tvar formatted = format(root, program);\n\t\t// console.log('===FORMATTED ROOT===\\n', printTree(formatted, '  '));\n\t\tif (mappedFiles.toGraphqlPatterns.has(p)) {\n\t\t\tinfo('>> Compile to GraphQL');\n\t\t\tvar { imports, node } = toGraphQL(formatted, f, pretty, srcFileDir);\n\t\t\t// Map data\n\t\t\tmapGqlPatternToNode.set(p, node);\n\t\t\tlistImports.push(...imports);\n\t\t}\n\t\tif (mappedFiles.fromPatterns.has(p)) {\n\t\t\tthrow new Error('Model.from not yet implemented!');\n\t\t}\n\t});\n\t//* Inject imports\n\tif (listImports.length) {\n\t\tsrcFile = f.updateSourceFile(\n\t\t\tsrcFile,\n\t\t\tlistImports.concat(srcFile.statements),\n\t\t\tfalse,\n\t\t\tsrcFile.referencedFiles,\n\t\t\tsrcFile.typeReferenceDirectives,\n\t\t\tsrcFile.hasNoDefaultLib,\n\t\t\tsrcFile.libReferenceDirectives\n\t\t);\n\t}\n\t//* Replace patterns\n\tsrcFile = ts.transform(\n\t\tsrcFile,\n\t\t[\n\t\t\tfunction (ctx: ts.TransformationContext): ts.Transformer<ts.Node> {\n\t\t\t\treturn _createModelInjectTransformer(\n\t\t\t\t\tctx,\n\t\t\t\t\tsrcFile,\n\t\t\t\t\tmappedFiles.ModelVarName,\n\t\t\t\t\tmapGqlPatternToNode,\n\t\t\t\t\tmapFromPatternToNode\n\t\t\t\t);\n\t\t\t}\n\t\t],\n\t\tcompilerOptions\n\t).transformed[0] as ts.SourceFile;\n\t//* Return content\n\tinfo('>> Print file');\n\treturn ts.createPrinter().printFile(srcFile);\n}\n\n/** filterFilesWithModel response */\ninterface FilterFilesWithModelResp {\n\t/** Absolute Glob pattern inside: \"Model.from(pattern)\" */\n\tpatterns: Set<string>;\n\tfromPatterns: Set<string>;\n\ttoGraphqlPatterns: Set<string>;\n\t/** Selected files (has \"model.from\") */\n\tfile: ts.SourceFile;\n\tModelVarName: Set<string>;\n}\n/** Filter files to get those with \"Model.from('glob-path')\" */\nfunction mapFilesWithModel(srcFile: ts.SourceFile): FilterFilesWithModelResp {\n\tconst fromPatterns: Set<string> = new Set();\n\tconst toGraphqlPatterns: Set<string> = new Set();\n\tconst foundGlobPatterns: Set<string> = new Set();\n\tconst ModelVarName: Set<string> = new Set();\n\t//* Parse each file\n\tconst fileName = srcFile.fileName;\n\tconst queue: ts.Node[] = [srcFile];\n\tvar node,\n\t\tj = 0;\n\twhile (j < queue.length) {\n\t\tnode = queue[j++];\n\t\tif (\n\t\t\tts.isImportDeclaration(node) &&\n\t\t\tnode.moduleSpecifier.getText() === PACKAGE_NAME\n\t\t) {\n\t\t\t// Load names used for \"Model\"\n\t\t\tnode.importClause?.namedBindings?.forEachChild(function (n) {\n\t\t\t\tif (\n\t\t\t\t\tts.isImportSpecifier(n) &&\n\t\t\t\t\t(n.propertyName ?? n.name).getText() === 'Model'\n\t\t\t\t) {\n\t\t\t\t\tModelVarName.add(n.name.getText());\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (\n\t\t\tts.isCallExpression(node) &&\n\t\t\tts.isPropertyAccessExpression(node.expression) &&\n\t\t\tModelVarName.has(node.expression.getFirstToken()!.getText())\n\t\t) {\n\t\t\tlet arg;\n\t\t\tif (\n\t\t\t\tnode.arguments.length === 1 &&\n\t\t\t\t(arg = node.arguments[0]) &&\n\t\t\t\tts.isStringLiteral(arg)\n\t\t\t) {\n\t\t\t\tlet t = arg.getText();\n\t\t\t\tswitch (node.expression.name.getText()) {\n\t\t\t\t\tcase 'from':\n\t\t\t\t\t\tfoundGlobPatterns.add(t);\n\t\t\t\t\t\tfromPatterns.add(t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'toGraphQL':\n\t\t\t\t\t\tfoundGlobPatterns.add(t);\n\t\t\t\t\t\ttoGraphqlPatterns.add(t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (node.getChildCount()) {\n\t\t\tqueue.push(...node.getChildren());\n\t\t}\n\t}\n\t// found\n\treturn {\n\t\tpatterns: foundGlobPatterns,\n\t\tfromPatterns,\n\t\ttoGraphqlPatterns,\n\t\tfile: srcFile,\n\t\tModelVarName: ModelVarName\n\t};\n}\n\nfunction _createModelInjectTransformer(\n\tctx: ts.TransformationContext,\n\tsrcFile: ts.SourceFile,\n\tModelVarName: Set<string>,\n\tmapGqlPatternToNode: Map<string, ts.CallExpression>,\n\tmapFromPatternToNode: Map<string, ts.CallExpression>\n): ts.Transformer<ts.Node> {\n\tconst f = ctx.factory;\n\treturn _visitor;\n\t// Visitor\n\tfunction _visitor(node: ts.Node): ts.Node {\n\t\tif (\n\t\t\tts.isCallExpression(node) &&\n\t\t\tts.isPropertyAccessExpression(node.expression) &&\n\t\t\tModelVarName.has(node.expression.getFirstToken()!.getText()) &&\n\t\t\tnode.arguments.length === 1\n\t\t) {\n\t\t\tlet arg = node.arguments[0].getText();\n\t\t\tswitch (node.expression.name.getText()) {\n\t\t\t\tcase 'from':\n\t\t\t\t\tthrow new Error(`Model.from not yet implemented!`);\n\t\t\t\t// \tnode= factory.createNewExpression(\n\t\t\t\t// \t\tfactory.createIdentifier(node.expression.getFirstToken()!.getText()),\n\t\t\t\t// \t\tundefined,\n\t\t\t\t// \t\t[ModelMap.get(arg)!]\n\t\t\t\t// \t);\n\t\t\t\t// \tbreak;\n\t\t\t\tcase 'toGraphQL':\n\t\t\t\t\t//ModelRoots\n\t\t\t\t\tlet n = mapGqlPatternToNode.get(arg)!;\n\t\t\t\t\tif (n == null)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Unexpected empty result for pattern: ${arg} at ${_errorFile(\n\t\t\t\t\t\t\t\tsrcFile,\n\t\t\t\t\t\t\t\tnode\n\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t);\n\t\t\t\t\tnode = n;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tnode = ts.visitEachChild(node, _visitor, ctx);\n\t\t}\n\t\treturn node;\n\t}\n}\n"]}