agentlang
Version:
The easiest way to build the most reliable AI agents - enterprise-grade teams of AI agents that collaborate with each other and humans
533 lines • 14.6 kB
JavaScript
import { isNodeEnv } from '../utils/runtime.js';
import { isLiteral, } from '../language/generated/ast.js';
import { readFile } from '../utils/fs-utils.js';
import bcrypt from 'bcryptjs';
import path from 'node:path';
export const QuerySuffix = '?';
// Conditionally import Node.js specific modules
let exec = undefined;
let promisify = undefined;
if (isNodeEnv) {
// Dynamic import for node:child_process to avoid browser compatibility issues
const childProcess = await import('node:child_process');
exec = childProcess.exec;
const nu = await import('node:util');
promisify = nu.promisify;
}
export function isNumber(x) {
return typeof x === 'number';
}
export function isMinusZero(value) {
return 1 / value === -Infinity;
}
export function isBoolean(x) {
return typeof x === 'boolean';
}
export function isStringNumeric(str) {
return !isNaN(Number(str)) && !isNaN(parseFloat(str));
}
export function isString(s) {
return s !== undefined && typeof s === 'string';
}
function asString(s) {
if (s === undefined)
return '';
else
return s;
}
const QuoteCharacter = '"';
export function restoreSpecialChars(s) {
return s.replaceAll(QuoteCharacter, '"');
}
export function escapeSpecialChars(s) {
return s.replaceAll('"', QuoteCharacter);
}
export class Path {
constructor(moduleName, entryName) {
this.moduleName = moduleName;
this.entryName = entryName;
}
hasModule() {
return isString(this.moduleName);
}
hasEntry() {
return isString(this.entryName);
}
setModuleName(n) {
this.moduleName = n;
return this;
}
getModuleName() {
return asString(this.moduleName);
}
setEntryname(n) {
this.entryName = n;
return this;
}
getEntryName() {
return asString(this.entryName);
}
asFqName() {
return makeFqName(this.moduleName || '?', this.entryName || '?');
}
equals(p) {
return this.moduleName == p.moduleName && this.entryName == p.entryName;
}
}
export function newPath() {
return new Path(undefined, undefined);
}
export function makeFqName(moduleName, entryName) {
return moduleName + '/' + entryName;
}
export function forceAsFqName(entryName, moduleName) {
if (entryName.indexOf('$') > 0) {
return restoreFqName(entryName);
}
if (isFqName(entryName)) {
return entryName;
}
return makeFqName(moduleName, entryName);
}
export function forceAsEscapedName(entryName, moduleName) {
if (entryName.indexOf('$') > 0) {
return entryName;
}
if (isFqName(entryName)) {
return escapeFqName(entryName);
}
return `${moduleName}$${entryName}`;
}
export function isFqName(s) {
return s.indexOf('/') > 0;
}
export function nameToPath(s) {
if (s.indexOf('/') > 0) {
const parts = s.split('/');
return new Path(parts[0], parts[1]);
}
return new Path(undefined, s);
}
export function splitFqName(s) {
return s.split('/');
}
export function splitRefs(s) {
if (s.indexOf('.') > 0) {
return s.split('.');
}
else {
return [s];
}
}
export function rootRef(s) {
return splitRefs(s)[0];
}
export function runShellCommand(cmd, options, continuation) {
if (!isNodeEnv) {
console.warn('Shell commands cannot be executed in non-Node.js environments');
// Call continuation to allow the program flow to continue
if (continuation)
continuation();
return;
}
if (!exec) {
console.error('Node.js child_process not available');
if (continuation)
continuation();
return;
}
exec(cmd, options, (err, stdout, stderr) => {
if (err) {
throw new Error(`Failed to execute ${cmd} - ${err.message}`);
}
if (stdout.length > 0) {
console.log(stdout);
if (continuation)
continuation();
}
if (stderr.length > 0)
console.log(stderr);
});
}
export function escapeFqName(n, moduleName) {
if (moduleName) {
if (n.indexOf('/') < 0) {
return `${moduleName}$${n}`;
}
}
return n.replace('/', '$');
}
export function restoreFqName(n) {
return n.replace('$', '/');
}
export function arrayEquals(a, b) {
if (a.length !== b.length)
return false;
else {
// Comparing each element of your array
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
}
export const DefaultModuleName = 'agentlang';
export const DefaultModules = new Set();
export const DefaultFileHandlingDirectory = 'fs';
export function makeCoreModuleName(n) {
return DefaultModuleName + '.' + n;
}
export function isCoreModule(n) {
return n === DefaultModuleName || n.startsWith(`${DefaultModuleName}.`);
}
export function isCoreDefinition(n) {
if (isFqName(n)) {
const parts = splitFqName(n);
return isCoreModule(parts[0]);
}
return false;
}
const InitFunctions = [];
export function registerInitFunction(f) {
InitFunctions.push(f);
}
export async function runInitFunctions() {
for (let i = 0; i < InitFunctions.length; ++i) {
await InitFunctions[i]();
}
InitFunctions.splice(0, InitFunctions.length);
}
export function maybeExtends(ext) {
return ext ? ext.parentName : undefined;
}
export function escapeQueryName(s) {
if (s.endsWith('?')) {
return s.substring(0, s.length - 1);
}
else {
return s;
}
}
export function joinStatements(stmts) {
return stmts
.filter((s) => {
return s.trim().length > 0;
})
.join(';\n');
}
export const sleepMilliseconds = isNodeEnv
? promisify(setTimeout)
: (m) => new Promise(r => setTimeout(r, m));
export function now() {
return new Date().toISOString();
}
export async function slurpJsonFile(fileName) {
const s = await readFile(fileName);
return JSON.parse(s);
}
function findExtraSchema(type, scm) {
if (scm && scm.extras) {
return scm.extras.find((ex) => {
switch (type) {
case 0 /* ExtraType.META */:
return ex.meta ? true : false;
case 1 /* ExtraType.RBAC */:
return ex.rbacSpec ? true : false;
case 2 /* ExtraType.PRE_POST_TRIGGER */:
return ex.prePost ? true : false;
}
});
}
else {
return undefined;
}
}
export function findMetaSchema(scm) {
const ex = findExtraSchema(0 /* ExtraType.META */, scm);
if (ex) {
return ex.meta;
}
return undefined;
}
export function findRbacSchema(scm) {
const ex = findExtraSchema(1 /* ExtraType.RBAC */, scm);
if (ex) {
return ex.rbacSpec;
}
return undefined;
}
export function findUqCompositeAttributes(scm) {
if (scm && scm.extras) {
const uqs = scm.extras.filter((ex) => {
return ex.uq ? true : false;
});
if (uqs && uqs.length > 0) {
if (uqs.length == 1 && uqs[0].uq) {
return uqs[0].uq.attrs;
}
else {
let attrs = new Array();
uqs.forEach((uq) => {
if (uq.uq) {
attrs = attrs.concat(uq.uq.attrs);
}
});
return attrs;
}
}
}
return undefined;
}
export function findAllPrePostTriggerSchema(scm) {
if (scm && scm.extras) {
let result;
for (let i = 0; i < scm.extras.length; ++i) {
const rex = scm.extras[i];
if (rex.prePost) {
if (result === undefined) {
result = new Array();
}
result.push(rex.prePost);
}
}
return result;
}
return undefined;
}
export var CrudType;
(function (CrudType) {
CrudType[CrudType["CREATE"] = 0] = "CREATE";
CrudType[CrudType["UPDATE"] = 1] = "UPDATE";
CrudType[CrudType["DELETE"] = 2] = "DELETE";
CrudType[CrudType["READ"] = 3] = "READ";
CrudType[CrudType["UPSERT"] = 4] = "UPSERT";
})(CrudType || (CrudType = {}));
export function asCrudType(s) {
const r = CrudType[s.toUpperCase()];
if (r === undefined) {
throw new Error(`${s} does not represent a valid CrudType`);
}
return r;
}
export function isPath(obj, ref) {
if (isString(obj)) {
const s = obj;
const r = s.indexOf('/') > 0;
if (r && ref) {
return s.indexOf(ref) >= 0;
}
return r;
}
else {
return false;
}
}
export function fqNameFromPath(path) {
const parts = path.split('/');
const len = parts.length;
if (len > 1) {
const n = restoreFqName(parts[len - 2]);
if (n.indexOf('/') > 0) {
return n;
}
}
return undefined;
}
export function firstAliasSpec(stmt) {
if (stmt.hints) {
for (let i = 0; i < stmt.hints.length; ++i) {
const rh = stmt.hints[i];
if (rh.aliasSpec) {
return rh.aliasSpec;
}
}
}
return undefined;
}
export function firstCatchSpec(stmt) {
if (stmt.hints) {
for (let i = 0; i < stmt.hints.length; ++i) {
const rh = stmt.hints[i];
if (rh.catchSpec) {
return rh.catchSpec;
}
}
}
return undefined;
}
function maybeExtractEntryName(n) {
const i = n.indexOf('$');
if (i > 0) {
return n.substring(i + 1);
}
return n;
}
function maybeExtractModuleName(n, moduleName) {
const i = n.indexOf('$');
if (i > 0) {
return n.substring(0, i);
}
if (moduleName === undefined) {
throw new Error(`Failed to extract module-name from ${n}`);
}
return moduleName;
}
export function walkDownInstancePath(path) {
const parts = path.split('/').filter((n) => {
return n.length > 0;
});
const nameParts = parts[0].split('$');
const hasParts = nameParts.length == 2;
let moduleName = hasParts ? nameParts[0] : parts[0];
let entryName = hasParts ? nameParts[1] : parts[1];
if (!hasParts && parts.length == 2) {
return [moduleName, entryName, undefined, parts];
}
if (parts.length > 1) {
let id = parts[1];
if (parts.length > 2) {
for (let i = 2; i < parts.length; ++i) {
const relName = parts[i];
moduleName = maybeExtractModuleName(relName, moduleName);
entryName = parts[++i];
moduleName = maybeExtractModuleName(entryName, moduleName);
entryName = maybeExtractEntryName(entryName);
if (i < parts.length) {
id = parts[++i];
}
else {
id = undefined;
}
}
}
return [moduleName, entryName, id, parts];
}
return [moduleName, entryName, undefined, parts];
}
export function areSetsEqual(set1, set2) {
if (set1.size !== set2.size) {
return false;
}
for (const item of set1) {
if (!set2.has(item)) {
return false;
}
}
return true;
}
const ReservedNames = new Set([
'if',
'else',
'for',
'or',
'and',
'entity',
'record',
'event',
'workflow',
'create',
'delete',
'update',
'upsert',
'agent',
'resolver',
]);
export function isReservedName(s) {
return ReservedNames.has(s);
}
export function encryptPassword(s) {
return bcrypt.hashSync(s, 10);
}
export function comparePassword(s, hash) {
return bcrypt.compareSync(s, hash);
}
export function fileExtension(fileName) {
if (isNodeEnv) {
return path.extname(fileName);
}
else {
const idx = fileName.lastIndexOf('.');
if (idx >= 0) {
return fileName.substring(idx);
}
}
return '';
}
export function trimQuotes(s) {
let ss = s.trim();
if (ss[0] == '"') {
ss = ss.substring(1);
}
if (ss[ss.length - 1] == '"') {
return ss.substring(0, ss.length - 1);
}
return ss;
}
export function asStringLiteralsMap(mapLit) {
const result = new Map();
mapLit.entries.forEach((me) => {
const k = me.key.str;
if (k && isLiteral(me.value)) {
const v = me.value.str || me.value.id || me.value.ref;
if (v)
result.set(k, v);
}
});
return result;
}
const IdSepEscape = '__';
export function escapeSepInPath(path) {
return path.replace(IdSepEscape, '/');
}
export function validateIdFormat(idAttrName, idAttrValue) {
if (isString(idAttrValue)) {
if (idAttrValue.indexOf(IdSepEscape) >= 0) {
throw new Error(`${IdSepEscape} not allowed in @id ${idAttrName} - '${idAttrValue}'`);
}
}
}
export function nameContainsSepEscape(n) {
return n.indexOf(IdSepEscape) >= 0;
}
export function generateUrlSafePassword(length = 8) {
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const lower = 'abcdefghijklmnopqrstuvwxyz';
const digits = '0123456789';
const special = '-_.~';
const chars = [
upper[Math.floor(Math.random() * upper.length)],
lower[Math.floor(Math.random() * lower.length)],
digits[Math.floor(Math.random() * digits.length)],
special[Math.floor(Math.random() * special.length)],
];
const all = upper + lower + digits + special;
for (let i = chars.length; i < length; ++i) {
chars.push(all[Math.floor(Math.random() * all.length)]);
}
for (let i = chars.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[chars[i], chars[j]] = [chars[j], chars[i]];
}
return chars.join('');
}
const JS_PREFIX = '#js';
export function preprocessRawConfig(rawConfig) {
const keys = Object.keys(rawConfig);
keys.forEach((k) => {
const v = rawConfig[k];
if (isString(v) && v.startsWith(JS_PREFIX)) {
const s = v.substring(3).trim();
rawConfig[k] = eval(s);
}
else if (typeof v == 'object') {
preprocessRawConfig(v);
}
});
return rawConfig;
}
export function setScecretReader(f) {
globalThis.readSecret = f;
}
//# sourceMappingURL=util.js.map