UNPKG

genezio

Version:

Command line utility to interact with Genezio infrastructure.

278 lines (277 loc) 12.1 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _AstGenerator_instances, _AstGenerator_parseList, _AstGenerator_parseMap, _AstGenerator_parsePromise, _AstGenerator_mapTypesToParamType, _AstGenerator_compileGenezioDartAstExtractor; import path from "path"; import fs from "fs"; import { AstNodeType, MethodKindEnum, SourceType, } from "../../models/genezioModels.js"; import { checkIfDartIsInstalled, getDartAstGeneratorPath, getDartSdkVersion, } from "../../utils/dart.js"; import { createTemporaryFolder, deleteFolder, fileExists } from "../../utils/file.js"; import { runNewProcess } from "../../utils/process.js"; import { GENEZIO_NO_SUPPORT_FOR_BUILT_IN_TYPE, GENEZIO_NO_SUPPORT_FOR_OPTIONAL_DART, UserError, } from "../../errors.js"; import { $ } from "execa"; import { log } from "../../utils/logging.js"; // These are dart:core build-in errors that are not currently supported by the Genezio AST const dartNotSupportedBuiltInErrors = [ "AbstractClassInstantiationError", "ConcurrentModificationError", "CyclicInitializationError", "Error", "FallThroughError", "IntegerDivisionByZeroException", "NoSuchMethodError", "NullThrownError", "OutOfMemoryError", "RangeError", "StateError", "StackOverflowError", "TypeError", "UnimplementedError", "UnsupportedError", ]; // These are dart:core build-in types that are not currently supported by the Genezio AST const dartNotSupportedBuiltInTypes = [ "BidirectionalIterator", "Comparable", "Duration", "Exception", "Expando", "FormatException", "Function", "Invocation", "Iterable", "Iterator", "Match", "Null", "Pattern", "RegExp", "RuneIterator", "Runes", "Set", "StackTrace", "Stopwatch", "StringBuffer", "StringSink", "Symbol", "Type", "Uri", "num", ]; export class AstGenerator { constructor() { _AstGenerator_instances.add(this); } async generateAst(input) { // Check if dart is installed. await checkIfDartIsInstalled(); // Get the dart sdk version. const dartSdkVersion = getDartSdkVersion()?.toString(); if (!dartSdkVersion) { throw new UserError("Unable to get the dart sdk version."); } // Get the path of the dart ast extractor. const { directory: genezioAstExtractorDir, path: genezioAstExtractorPath } = getDartAstGeneratorPath(dartSdkVersion); // Check if the dart ast extractor is compiled and installed in home. const compiled = await fileExists(genezioAstExtractorPath); if (!compiled) { // Check if the folder exists, if not, create it. if (!fs.existsSync(genezioAstExtractorDir)) { fs.mkdirSync(genezioAstExtractorDir); } await __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_compileGenezioDartAstExtractor).call(this, genezioAstExtractorPath); } const classAbsolutePath = path.resolve(input.class.path); const modelsAbsolutePath = path.join(process.cwd(), "lib", "models"); const result = await $ `dartaotruntime ${genezioAstExtractorPath} ${classAbsolutePath} ${modelsAbsolutePath}`.catch((error) => { log.error(error.stderr); throw new UserError("Error: Failed to generate AST for class " + input.class.path); }); const ast = JSON.parse(result.stdout); const mainClasses = ast.classes.filter((c) => c.name === input.class.name); if (mainClasses.length == 0) { throw new UserError(`No class named ${input.class.name} found. Check in the 'genezio.yaml' file and make sure the path is correct.`); } const classToDeploy = mainClasses[0]; const genezioClass = { type: AstNodeType.ClassDefinition, path: classToDeploy.library.replace(/package:.*?\//, "./lib/"), name: classToDeploy.name, methods: classToDeploy.methods.map((m) => { return { type: AstNodeType.MethodDefinition, name: m.name, params: m.parameters.map((p) => { return { type: AstNodeType.ParameterDefinition, path: p.library.replace(/package:.*?\//, "./lib/"), name: p.name, paramType: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, p.type), rawType: p.type, }; }), returnType: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, m.returnType), static: false, kind: MethodKindEnum.method, }; }), }; const body = [genezioClass]; const otherClasses = ast.classes.filter((c) => c.name !== input.class.name); otherClasses.forEach((c) => { const genezioClass = { type: AstNodeType.StructLiteral, path: c.library.replace(/package:.*?\//, "./lib/"), name: c.name, typeLiteral: { type: AstNodeType.TypeLiteral, properties: c.fields.map((p) => { return { name: p.name, type: { ...__classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, p.type), path: p.library.replace(/package:.*?\//, "./lib/"), }, rawType: p.type, }; }), }, }; body.push(genezioClass); }); return { program: { body: body, originalLanguage: "dart", sourceType: SourceType.module, }, }; } } _AstGenerator_instances = new WeakSet(), _AstGenerator_parseList = function _AstGenerator_parseList(type) { const listToken = "List<"; if (type.startsWith(listToken)) { const lastIndex = type.length - 1; // If the List is optional, we need to remove the last character if (type[type.length - 1] === "?") { throw new UserError(GENEZIO_NO_SUPPORT_FOR_OPTIONAL_DART); } // Check for not supported built-in types if (dartNotSupportedBuiltInTypes.includes(type) || dartNotSupportedBuiltInErrors.includes(type)) { throw new UserError(`${type} not supported.\n` + GENEZIO_NO_SUPPORT_FOR_BUILT_IN_TYPE); } const extractedString = type.substring(listToken.length, lastIndex); return { type: AstNodeType.ArrayType, generic: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, extractedString), }; } else { return undefined; } }, _AstGenerator_parseMap = function _AstGenerator_parseMap(type) { const mapToken = "Map<"; if (type.startsWith(mapToken)) { const cleanedType = type.replace(" ", ""); const lastIndex = cleanedType.length - 1; // If the Map is optional, we need to remove the last character if (cleanedType[cleanedType.length - 1] === "?") { throw new UserError(GENEZIO_NO_SUPPORT_FOR_OPTIONAL_DART); } // Check for not supported built-in types if (dartNotSupportedBuiltInTypes.includes(type) || dartNotSupportedBuiltInErrors.includes(type)) { throw new UserError(`${type} not supported.\n` + GENEZIO_NO_SUPPORT_FOR_BUILT_IN_TYPE); } const extractedString = cleanedType.substring(mapToken.length, lastIndex); const components = extractedString.split(","); const key = components[0]; const value = components.slice(1).join(","); return { type: AstNodeType.MapType, genericKey: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, key), genericValue: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, value), }; } }, _AstGenerator_parsePromise = function _AstGenerator_parsePromise(type) { const promiseToken = "Future<"; if (type.startsWith(promiseToken)) { const extractedString = type.substring(promiseToken.length, type.length - 1); return { type: AstNodeType.PromiseType, generic: __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_mapTypesToParamType).call(this, extractedString), }; } }, _AstGenerator_mapTypesToParamType = function _AstGenerator_mapTypesToParamType(type) { const list = __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_parseList).call(this, type); if (list) { return list; } const map = __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_parseMap).call(this, type); if (map) { return map; } const promise = __classPrivateFieldGet(this, _AstGenerator_instances, "m", _AstGenerator_parsePromise).call(this, type); if (promise) { return promise; } // Remove the Optional property for now, we don't support it. if (type[type.length - 1] === "?") { throw new UserError(GENEZIO_NO_SUPPORT_FOR_OPTIONAL_DART); } // Check for not supported built-in types if (dartNotSupportedBuiltInTypes.includes(type) || dartNotSupportedBuiltInErrors.includes(type)) { throw new UserError(`${type} not supported.\n` + GENEZIO_NO_SUPPORT_FOR_BUILT_IN_TYPE); } switch (type) { case "String": return { type: AstNodeType.StringLiteral, }; case "int": return { type: AstNodeType.IntegerLiteral, }; case "double": return { type: AstNodeType.DoubleLiteral, }; case "bool": return { type: AstNodeType.BooleanLiteral, }; case "void": { return { type: AstNodeType.VoidLiteral, }; } case "DateTime": return { type: AstNodeType.DateType, }; case "Object": return { type: AstNodeType.AnyLiteral, }; default: return { type: AstNodeType.CustomNodeLiteral, rawValue: type, }; } }, _AstGenerator_compileGenezioDartAstExtractor = async function _AstGenerator_compileGenezioDartAstExtractor(genezioAstExtractorPath) { const folder = await createTemporaryFolder(); // Clone the dart ast generator. await runNewProcess("git clone https://github.com/Genez-io/dart-ast.git .", folder); await runNewProcess("git checkout tags/v0.1 -b releases", folder); await runNewProcess("dart pub get", folder); // Compile the dart ast generator. await runNewProcess(`dart compile aot-snapshot main.dart -o ${genezioAstExtractorPath}`, folder); // Remove the temporary folder. await deleteFolder(folder); }; const supportedExtensions = ["dart"]; export default { supportedExtensions, AstGenerator };