genezio
Version:
Command line utility to interact with Genezio infrastructure.
278 lines (277 loc) • 12.1 kB
JavaScript
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 };