genezio
Version:
Command line utility to interact with Genezio infrastructure.
125 lines (124 loc) • 6.13 kB
JavaScript
import path from "path";
import { getAllFilesFromPath } from "./file.js";
import { debugLogger, log } from "./logging.js";
import { TriggerType } from "../projectConfiguration/yaml/models.js";
import { GENEZIO_DECORATOR_YAML_OVERLAP, UserError } from "../errors.js";
import { DecoratorExtractorFactory } from "./decorators/decoratorFactory.js";
async function tryToReadClassInformationFromDecorators(yamlBackend) {
const cwd = yamlBackend.path || process.cwd();
const decoratorExtractor = DecoratorExtractorFactory.createExtractor(yamlBackend.language.name);
const allFilesPaths = (await getAllFilesFromPath(cwd)).filter(decoratorExtractor.fileFilter(cwd));
return await Promise.all(allFilesPaths.map((file) => {
const filePath = path.join(cwd, file.path);
return decoratorExtractor.getDecoratorsFromFile(filePath, cwd);
}));
}
export async function scanClassesForDecorators(yamlBackend) {
const result = await tryToReadClassInformationFromDecorators(yamlBackend).catch((error) => {
if (error instanceof UserError && error.message.includes("Language not supported")) {
debugLogger.debug("Language decorators not supported, skipping scan for decorators.");
}
else if (error instanceof UserError) {
throw error;
}
return [];
});
const classes = yamlBackend.classes || [];
const overlappingYamlClasses = [];
result.forEach((classInfo) => {
if (classInfo.length < 1) {
return;
}
if (Object.keys(classInfo[0]).length > 0) {
const r = classes.find((c) => path.resolve(path.join(yamlBackend.path, c.path)) ===
path.resolve(classInfo[0].path));
const deployDecoratorFound = classInfo[0].decorators.find((d) => d.name === "GenezioDeploy");
if (!r && deployDecoratorFound) {
let type = TriggerType.jsonrpc;
let timeout;
let storageSize;
let instanceSize;
let vcpuCount;
let memoryMb;
let maxConcurrentRequestsPerInstance;
let maxConcurrentInstances;
let cooldownTime;
let persistent;
const methods = classInfo[0].methods
.map((m) => {
const genezioMethodDecorator = m.decorators.find((d) => d.name === "GenezioMethod");
if (!genezioMethodDecorator || !genezioMethodDecorator.arguments) {
return undefined;
}
const methodType = genezioMethodDecorator.arguments["type"]
? getTriggerTypeFromString(genezioMethodDecorator.arguments["type"])
: undefined;
const cronString = genezioMethodDecorator.arguments["cronString"];
if (methodType === TriggerType.cron && !cronString) {
throw new UserError(`Method ${m.name} in class ${classInfo[0].name} has type cron but no cronString specified`);
}
const usesAuth = m.decorators.find((d) => d.name === "GenezioAuth") !== undefined;
return {
name: m.name,
type: methodType,
cronString: cronString,
auth: usesAuth,
};
})
.filter((m) => m !== undefined);
if (deployDecoratorFound.arguments) {
const classType = deployDecoratorFound.arguments["type"];
if (classType) {
type = getTriggerTypeFromString(classType);
}
let persistentDecorator = false;
if (deployDecoratorFound.arguments["persistent"] === "true") {
persistentDecorator = true;
}
timeout = deployDecoratorFound.arguments["timeout"];
storageSize = deployDecoratorFound.arguments["storageSize"];
instanceSize = deployDecoratorFound.arguments["instanceSize"];
vcpuCount = deployDecoratorFound.arguments["vcpuCount"];
memoryMb = deployDecoratorFound.arguments["memoryMb"];
maxConcurrentRequestsPerInstance = deployDecoratorFound.arguments["maxConcurrentRequestsPerInstance"];
maxConcurrentInstances = deployDecoratorFound.arguments["maxConcurrentInstances"];
cooldownTime = deployDecoratorFound.arguments["cooldownTime"];
persistent = persistentDecorator;
}
classes.push({
name: classInfo[0].name,
path: path.relative(yamlBackend.path, classInfo[0].path),
type: type,
timeout: timeout,
storageSize: storageSize,
instanceSize: instanceSize,
vcpuCount: vcpuCount,
memoryMb: memoryMb,
maxConcurrentRequestsPerInstance: maxConcurrentRequestsPerInstance,
maxConcurrentInstances: maxConcurrentInstances,
cooldownTime: cooldownTime,
persistent: persistent,
methods: methods,
});
}
else if (r && deployDecoratorFound) {
overlappingYamlClasses.push(r?.name || "");
}
}
});
if (overlappingYamlClasses.length > 0) {
log.warn(GENEZIO_DECORATOR_YAML_OVERLAP(overlappingYamlClasses));
}
return classes;
}
export function getTriggerTypeFromString(string) {
if (string && !TriggerType[string]) {
const triggerTypes = Object.keys(TriggerType).join(", ");
throw new UserError("Specified class type for " +
string +
" is incorrect. Accepted values: " +
triggerTypes +
".");
}
return TriggerType[string];
}