UNPKG

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
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 = '&quot;'; 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