agentlang 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1740,8 +1740,11 @@ async function runPrePostEvents(
1740
1740
  }
1741
1741
  };
1742
1742
  if (trigInfo.async) {
1743
- evaluate(eventInst, callback).catch(catchHandler);
1743
+ const newEnv = new Environment('async.prepost.env');
1744
+ newEnv.bind('this', inst);
1745
+ evaluate(eventInst, callback, newEnv).catch(catchHandler);
1744
1746
  } else {
1747
+ env.bind('this', inst);
1745
1748
  await evaluate(eventInst, callback, env).catch(catchHandler);
1746
1749
  }
1747
1750
  }
@@ -413,7 +413,7 @@ export function addRelationshipFromDef(
413
413
  }
414
414
 
415
415
  export function addWorkflowFromDef(def: WorkflowDefinition, moduleName: string): Workflow {
416
- return addWorkflow(def.name, moduleName, def.statements, def.hints);
416
+ return addWorkflow(def.name || '', moduleName, def.statements, def.header);
417
417
  }
418
418
 
419
419
  const StandaloneStatements = new Map<string, Statement[]>();
@@ -25,8 +25,6 @@ if (isNodeEnv) {
25
25
  maxFiles: '7d',
26
26
  });
27
27
 
28
- const consoleTransport = new winston.transports.Console();
29
-
30
28
  logger = winston.createLogger({
31
29
  format: winston.format.combine(
32
30
  winston.format.timestamp(),
@@ -34,7 +32,7 @@ if (isNodeEnv) {
34
32
  return `[${timestamp}] ${level}: ${message}`;
35
33
  })
36
34
  ),
37
- transports: [fileTransport, consoleTransport],
35
+ transports: [fileTransport],
38
36
  });
39
37
  } else {
40
38
  function mkLogger(tag: string): Function {
@@ -19,7 +19,7 @@ import {
19
19
  RbacSpecEntry,
20
20
  RbacSpecEntries,
21
21
  RbacOpr,
22
- WorkflowHint,
22
+ WorkflowHeader,
23
23
  } from '../language/generated/ast.js';
24
24
  import {
25
25
  Path,
@@ -45,7 +45,7 @@ import {
45
45
  } from './util.js';
46
46
  import { parseStatement } from '../language/parser.js';
47
47
  import { ActiveSessionInfo, AdminSession } from './auth/defs.js';
48
- import { FetchModuleFn, PathAttributeName, SetSubscription } from './defs.js';
48
+ import { FetchModuleFn, PathAttributeName } from './defs.js';
49
49
  import { logger } from './logger.js';
50
50
 
51
51
  export class ModuleEntry {
@@ -1157,10 +1157,17 @@ export class Relationship extends Record {
1157
1157
 
1158
1158
  export class Workflow extends ModuleEntry {
1159
1159
  statements: Statement[];
1160
+ generatedName: boolean;
1160
1161
 
1161
- constructor(name: string, patterns: Statement[], moduleName: string) {
1162
+ constructor(
1163
+ name: string,
1164
+ patterns: Statement[],
1165
+ moduleName: string,
1166
+ generatedName: boolean = false
1167
+ ) {
1162
1168
  super(name, moduleName);
1163
1169
  this.statements = patterns;
1170
+ this.generatedName = generatedName;
1164
1171
  }
1165
1172
 
1166
1173
  async addStatement(stmtCode: string): Promise<Workflow> {
@@ -1278,7 +1285,8 @@ export class Workflow extends ModuleEntry {
1278
1285
  }
1279
1286
 
1280
1287
  override toString() {
1281
- let s: string = `workflow ${normalizeWorkflowName(this.name)} {\n`;
1288
+ const n = this.generatedName ? untangleWorkflowName(this.name) : this.name;
1289
+ let s: string = `workflow ${normalizeWorkflowName(n)} {\n`;
1282
1290
  const ss = this.statementsToStringsHelper(this.statements);
1283
1291
  s = s.concat(joinStatements(ss));
1284
1292
  return s.concat('\n}');
@@ -1883,12 +1891,24 @@ function normalizeWorkflowName(n: string): string {
1883
1891
  return n;
1884
1892
  }
1885
1893
 
1894
+ export type PrePostTag = '@after' | '@before';
1895
+ export type PrePostOpr = 'create' | 'update' | 'delete';
1896
+
1897
+ type ThinWfHeader = {
1898
+ tag: PrePostTag;
1899
+ prefix: PrePostOpr;
1900
+ name: string;
1901
+ };
1902
+
1886
1903
  export function addWorkflow(
1887
1904
  name: string,
1888
1905
  moduleName = activeModule,
1889
1906
  statements?: Statement[],
1890
- hints?: WorkflowHint[]
1907
+ hdr?: WorkflowHeader | ThinWfHeader
1891
1908
  ): Workflow {
1909
+ if (hdr) {
1910
+ name = prePostWorkflowName(hdr.tag, hdr.prefix, hdr.name, moduleName);
1911
+ }
1892
1912
  const module: Module = fetchModule(moduleName);
1893
1913
  if (module.hasEntry(name)) {
1894
1914
  const entry: ModuleEntry = module.getEntry(name);
@@ -1900,39 +1920,111 @@ export function addWorkflow(
1900
1920
  event.addMeta(SystemDefinedEvent, 'true');
1901
1921
  }
1902
1922
  if (!statements) statements = new Array<Statement>();
1903
- if (hints && hints.length > 0) {
1923
+ if (hdr) {
1904
1924
  const eventFqName = makeFqName(moduleName, name);
1905
- hints.forEach((hint: WorkflowHint) => {
1906
- if (hint.subs) {
1907
- SetSubscription(eventFqName, hint.subs.resolverName);
1908
- } else if (hint.trigs) {
1909
- if (hint.trigs.after) {
1910
- hint.trigs.after.triggers.entries.forEach((te: TriggerEntry) => {
1911
- const entityDef = getEntityDefForTrigger(te, moduleName);
1912
- entityDef.addAfterTrigger({
1913
- on: te.on,
1914
- event: eventFqName,
1915
- async: te.async ? true : false,
1916
- });
1917
- });
1918
- } else if (hint.trigs.before) {
1919
- hint.trigs.before.triggers.entries.forEach((te: TriggerEntry) => {
1920
- const entityDef = getEntityDefForTrigger(te, moduleName);
1921
- entityDef.addBeforeTrigger({
1922
- on: te.on,
1923
- event: eventFqName,
1924
- async: te.async ? true : false,
1925
- });
1926
- });
1927
- }
1928
- }
1929
- });
1925
+ const entityDef = getEntityDef(hdr.name, moduleName);
1926
+ if (hdr.tag == '@after') {
1927
+ entityDef?.addAfterTrigger({
1928
+ on: hdr.prefix,
1929
+ event: eventFqName,
1930
+ async: false,
1931
+ });
1932
+ } else {
1933
+ entityDef?.addBeforeTrigger({
1934
+ on: hdr.prefix,
1935
+ event: eventFqName,
1936
+ async: false,
1937
+ });
1938
+ }
1930
1939
  }
1931
- return module.addEntry(new Workflow(asWorkflowName(name), statements, moduleName)) as Workflow;
1940
+ return module.addEntry(
1941
+ new Workflow(asWorkflowName(name), statements, moduleName, hdr ? true : false)
1942
+ ) as Workflow;
1943
+ }
1944
+
1945
+ function addPrePostWorkflow(
1946
+ tag: PrePostTag,
1947
+ opr: PrePostOpr,
1948
+ entityName: string,
1949
+ moduleName = activeModule,
1950
+ statements?: Statement[]
1951
+ ): Workflow {
1952
+ const hdr: ThinWfHeader = {
1953
+ tag: tag,
1954
+ prefix: opr,
1955
+ name: entityName,
1956
+ };
1957
+ return addWorkflow('', moduleName, statements, hdr);
1932
1958
  }
1933
1959
 
1934
- function getEntityDefForTrigger(te: TriggerEntry, moduleName: string): Entity {
1935
- const entityName: string = te.event;
1960
+ export function addAfterCreateWorkflow(
1961
+ entityName: string,
1962
+ moduleName = activeModule,
1963
+ statements?: Statement[]
1964
+ ): Workflow {
1965
+ return addPrePostWorkflow('@after', 'create', entityName, moduleName, statements);
1966
+ }
1967
+
1968
+ export function addAfterUpdateWorkflow(
1969
+ entityName: string,
1970
+ moduleName = activeModule,
1971
+ statements?: Statement[]
1972
+ ): Workflow {
1973
+ return addPrePostWorkflow('@after', 'update', entityName, moduleName, statements);
1974
+ }
1975
+
1976
+ export function addAfterDeleteWorkflow(
1977
+ entityName: string,
1978
+ moduleName = activeModule,
1979
+ statements?: Statement[]
1980
+ ): Workflow {
1981
+ return addPrePostWorkflow('@after', 'delete', entityName, moduleName, statements);
1982
+ }
1983
+
1984
+ export function addBeforeCreateWorkflow(
1985
+ entityName: string,
1986
+ moduleName = activeModule,
1987
+ statements?: Statement[]
1988
+ ): Workflow {
1989
+ return addPrePostWorkflow('@before', 'create', entityName, moduleName, statements);
1990
+ }
1991
+
1992
+ export function addBeforeUpdateWorkflow(
1993
+ entityName: string,
1994
+ moduleName = activeModule,
1995
+ statements?: Statement[]
1996
+ ): Workflow {
1997
+ return addPrePostWorkflow('@before', 'update', entityName, moduleName, statements);
1998
+ }
1999
+
2000
+ export function addBeforeDeleteWorkflow(
2001
+ entityName: string,
2002
+ moduleName = activeModule,
2003
+ statements?: Statement[]
2004
+ ): Workflow {
2005
+ return addPrePostWorkflow('@before', 'delete', entityName, moduleName, statements);
2006
+ }
2007
+
2008
+ function prePostWorkflowName(
2009
+ tag: PrePostTag,
2010
+ opr: PrePostOpr,
2011
+ entityName: string,
2012
+ moduleName?: string
2013
+ ): string {
2014
+ const parts = splitFqName(entityName);
2015
+ const mname = parts.hasModule() ? parts.getModuleName() : moduleName;
2016
+ if (!mname) {
2017
+ throw new Error(`Cannot infer module name for ${entityName}`);
2018
+ }
2019
+ return `${tag.substring(1)}_${opr}_${mname}_${parts.getEntryName()}`;
2020
+ }
2021
+
2022
+ function untangleWorkflowName(name: string): string {
2023
+ const parts = name.split('_');
2024
+ return `@${parts[0]} ${parts[1]}:${parts[2]}/${parts[3]}`;
2025
+ }
2026
+
2027
+ function getEntityDef(entityName: string, moduleName: string): Entity | undefined {
1936
2028
  const parts = splitFqName(entityName);
1937
2029
  const mname = parts.hasModule() ? parts.getModuleName() : moduleName;
1938
2030
  return getEntity(parts.getEntryName(), mname);
@@ -1949,12 +2041,13 @@ export function getWorkflow(eventInstance: Instance): Workflow {
1949
2041
  return EmptyWorkflow;
1950
2042
  }
1951
2043
 
1952
- export function getEntity(name: string, moduleName: string): Entity {
2044
+ export function getEntity(name: string, moduleName: string): Entity | undefined {
1953
2045
  const fr: FetchModuleByEntryNameResult = fetchModuleByEntryName(name, moduleName);
1954
2046
  if (fr.module.isEntity(fr.entryName)) {
1955
2047
  return fr.module.getEntry(fr.entryName) as Entity;
1956
2048
  }
1957
- throw new Error(`Entity ${fr.entryName} not found in module ${fr.moduleName}`);
2049
+ logger.error(`Entity ${fr.entryName} not found in module ${fr.moduleName}`);
2050
+ return undefined;
1958
2051
  }
1959
2052
 
1960
2053
  function isEntryOfType(t: RecordType, fqName: string): boolean {
@@ -2782,7 +2875,7 @@ export function getEntityRbacRules(entityFqName: string): RbacSpecification[] |
2782
2875
  const m = isModule(mn) && fetchModule(mn);
2783
2876
  if (m && m.isEntity(en)) {
2784
2877
  const entity = getEntity(en, mn);
2785
- return entity.getRbacSpecifications()?.filter((spec: RbacSpecification) => {
2878
+ return entity?.getRbacSpecifications()?.filter((spec: RbacSpecification) => {
2786
2879
  return spec.expression != undefined;
2787
2880
  });
2788
2881
  }
@@ -1,7 +1,7 @@
1
1
  // Monarch syntax highlighting for the agentlang language.
2
2
  export default {
3
3
  keywords: [
4
- '@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@subs','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
4
+ '@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
5
5
  ],
6
6
  operators: [
7
7
  '!=','*','+',',','-','.','/',':',';','<','<=','<>','=','>','>=','?','@'