agentlang 0.7.8 → 0.7.11
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.
- package/out/api/http.d.ts.map +1 -1
- package/out/api/http.js +8 -1
- package/out/api/http.js.map +1 -1
- package/out/cli/main.d.ts.map +1 -1
- package/out/cli/main.js +33 -2
- package/out/cli/main.js.map +1 -1
- package/out/extension/main.cjs +250 -250
- package/out/extension/main.cjs.map +2 -2
- package/out/language/agentlang-validator.d.ts +1 -2
- package/out/language/agentlang-validator.d.ts.map +1 -1
- package/out/language/agentlang-validator.js +0 -39
- package/out/language/agentlang-validator.js.map +1 -1
- package/out/language/generated/ast.d.ts +62 -11
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +75 -3
- package/out/language/generated/ast.js.map +1 -1
- package/out/language/generated/grammar.d.ts.map +1 -1
- package/out/language/generated/grammar.js +758 -239
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +1370 -824
- package/out/language/main.cjs.map +4 -4
- package/out/language/parser.d.ts +1 -0
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +44 -7
- package/out/language/parser.js.map +1 -1
- package/out/language/syntax.d.ts +1 -1
- package/out/language/syntax.d.ts.map +1 -1
- package/out/language/syntax.js +22 -13
- package/out/language/syntax.js.map +1 -1
- package/out/runtime/api.d.ts +4 -0
- package/out/runtime/api.d.ts.map +1 -1
- package/out/runtime/api.js +9 -0
- package/out/runtime/api.js.map +1 -1
- package/out/runtime/auth/cognito.d.ts.map +1 -1
- package/out/runtime/auth/cognito.js +4 -4
- package/out/runtime/auth/cognito.js.map +1 -1
- package/out/runtime/auth/defs.d.ts +9 -1
- package/out/runtime/auth/defs.d.ts.map +1 -1
- package/out/runtime/auth/defs.js +23 -2
- package/out/runtime/auth/defs.js.map +1 -1
- package/out/runtime/defs.d.ts +5 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +16 -0
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/exec-graph.js +1 -1
- package/out/runtime/exec-graph.js.map +1 -1
- package/out/runtime/interpreter.d.ts +6 -1
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +144 -112
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +74 -27
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/module.d.ts +41 -11
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +238 -50
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +13 -6
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/auth.d.ts +2 -1
- package/out/runtime/modules/auth.d.ts.map +1 -1
- package/out/runtime/modules/auth.js +93 -3
- package/out/runtime/modules/auth.js.map +1 -1
- package/out/runtime/modules/core.d.ts +7 -5
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +93 -16
- package/out/runtime/modules/core.js.map +1 -1
- package/out/runtime/monitor.d.ts.map +1 -1
- package/out/runtime/monitor.js +1 -0
- package/out/runtime/monitor.js.map +1 -1
- package/out/runtime/resolvers/interface.d.ts +6 -1
- package/out/runtime/resolvers/interface.d.ts.map +1 -1
- package/out/runtime/resolvers/interface.js +2 -2
- package/out/runtime/resolvers/interface.js.map +1 -1
- package/out/runtime/resolvers/sqldb/database.d.ts +19 -2
- package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/database.js +107 -21
- package/out/runtime/resolvers/sqldb/database.js.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.d.ts +1 -0
- package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.js +25 -3
- package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts +3 -2
- package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.js +80 -6
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
- package/out/runtime/state.d.ts +58 -0
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +12 -0
- package/out/runtime/state.js.map +1 -1
- package/out/runtime/util.d.ts +1 -1
- package/out/runtime/util.d.ts.map +1 -1
- package/out/runtime/util.js +27 -13
- package/out/runtime/util.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +1 -1
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/out/utils/fs-utils.d.ts +10 -0
- package/out/utils/fs-utils.d.ts.map +1 -1
- package/out/utils/fs-utils.js +14 -0
- package/out/utils/fs-utils.js.map +1 -1
- package/package.json +2 -1
- package/src/api/http.ts +8 -0
- package/src/cli/main.ts +38 -2
- package/src/language/agentlang-validator.ts +1 -51
- package/src/language/agentlang.langium +17 -4
- package/src/language/generated/ast.ts +147 -13
- package/src/language/generated/grammar.ts +758 -239
- package/src/language/parser.ts +43 -8
- package/src/language/syntax.ts +25 -12
- package/src/runtime/api.ts +16 -0
- package/src/runtime/auth/defs.ts +25 -2
- package/src/runtime/defs.ts +8 -0
- package/src/runtime/interpreter.ts +104 -76
- package/src/runtime/loader.ts +75 -25
- package/src/runtime/module.ts +194 -32
- package/src/runtime/modules/ai.ts +10 -4
- package/src/runtime/modules/auth.ts +1 -0
- package/src/runtime/modules/core.ts +99 -23
- package/src/runtime/monitor.ts +1 -0
- package/src/runtime/resolvers/interface.ts +9 -2
- package/src/runtime/resolvers/sqldb/database.ts +68 -17
- package/src/runtime/resolvers/sqldb/dbutil.ts +28 -6
- package/src/runtime/resolvers/sqldb/impl.ts +86 -14
- package/src/runtime/state.ts +14 -0
- package/src/runtime/util.ts +25 -12
- package/src/syntaxes/agentlang.monarch.ts +1 -1
- package/src/utils/fs-utils.ts +16 -0
package/src/runtime/loader.ts
CHANGED
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
addAgent,
|
|
70
70
|
fetchModule,
|
|
71
71
|
Retry,
|
|
72
|
+
addGlobalRetry,
|
|
72
73
|
} from './module.js';
|
|
73
74
|
import {
|
|
74
75
|
asStringLiteralsMap,
|
|
@@ -81,6 +82,7 @@ import {
|
|
|
81
82
|
preprocessRawConfig,
|
|
82
83
|
registerInitFunction,
|
|
83
84
|
rootRef,
|
|
85
|
+
ScratchModuleName,
|
|
84
86
|
} from './util.js';
|
|
85
87
|
import { getFileSystem, toFsPath, readFile, readdir, exists } from '../utils/fs-utils.js';
|
|
86
88
|
import { URI } from 'vscode-uri';
|
|
@@ -348,10 +350,14 @@ async function evaluateConfigPatterns(cfgPats: string): Promise<any> {
|
|
|
348
350
|
const wf = await parseWorkflow(cfgWf);
|
|
349
351
|
const cfgStmts = new Array<Statement>();
|
|
350
352
|
const initInsts = new Array<Statement>();
|
|
353
|
+
const deleted = new Set<string>();
|
|
351
354
|
for (let i = 0; i < wf.statements.length; ++i) {
|
|
352
355
|
const stmt: Statement = wf.statements[i];
|
|
353
356
|
if (stmt.pattern.crudMap) {
|
|
354
|
-
|
|
357
|
+
if (!deleted.has(stmt.pattern.crudMap?.name)) {
|
|
358
|
+
initInsts.push(await makeDeleteAllConfigStatement(stmt.pattern.crudMap));
|
|
359
|
+
deleted.add(stmt.pattern.crudMap.name);
|
|
360
|
+
}
|
|
355
361
|
initInsts.push(stmt);
|
|
356
362
|
} else {
|
|
357
363
|
cfgStmts.push(stmt);
|
|
@@ -377,20 +383,37 @@ async function evaluateConfigPatterns(cfgPats: string): Promise<any> {
|
|
|
377
383
|
return undefined;
|
|
378
384
|
}
|
|
379
385
|
|
|
380
|
-
|
|
386
|
+
function isStringContent(content: string): boolean {
|
|
387
|
+
return content.includes('{');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export async function loadAppConfig(configDirOrContent: string): Promise<Config> {
|
|
391
|
+
const stringContent = isStringContent(configDirOrContent);
|
|
392
|
+
|
|
381
393
|
let cfgObj: any = undefined;
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const
|
|
386
|
-
if (
|
|
387
|
-
|
|
394
|
+
|
|
395
|
+
if (!stringContent) {
|
|
396
|
+
const fs = await getFileSystem();
|
|
397
|
+
const alCfgFile = `${configDirOrContent}${path.sep}config.al`;
|
|
398
|
+
if (await fs.exists(alCfgFile)) {
|
|
399
|
+
configDirOrContent = await fs.readFile(alCfgFile);
|
|
388
400
|
}
|
|
389
401
|
}
|
|
402
|
+
|
|
403
|
+
if (canParse(configDirOrContent)) {
|
|
404
|
+
cfgObj = await evaluateConfigPatterns(configDirOrContent);
|
|
405
|
+
}
|
|
406
|
+
|
|
390
407
|
try {
|
|
391
|
-
|
|
408
|
+
let cfg = cfgObj
|
|
392
409
|
? await configFromObject(cfgObj)
|
|
393
|
-
: await loadRawConfig(`${
|
|
410
|
+
: await loadRawConfig(`${configDirOrContent}${path.sep}app.config.json`);
|
|
411
|
+
|
|
412
|
+
const envAppConfig = typeof process !== 'undefined' ? process.env.APP_CONFIG : undefined;
|
|
413
|
+
if (envAppConfig) {
|
|
414
|
+
const envConfig = JSON.parse(envAppConfig);
|
|
415
|
+
cfg = { ...cfg, ...envConfig };
|
|
416
|
+
}
|
|
394
417
|
return setAppConfig(cfg);
|
|
395
418
|
} catch (err: any) {
|
|
396
419
|
if (err instanceof z.ZodError) {
|
|
@@ -891,7 +914,7 @@ function addFlowDefinition(def: FlowDefinition, moduleName: string) {
|
|
|
891
914
|
f = sdef;
|
|
892
915
|
}
|
|
893
916
|
}
|
|
894
|
-
m.addFlow(def.name,
|
|
917
|
+
m.addFlow(def.name, def);
|
|
895
918
|
registerFlow(`${moduleName}/${def.name}`, f);
|
|
896
919
|
}
|
|
897
920
|
|
|
@@ -1161,6 +1184,7 @@ export async function internModule(
|
|
|
1161
1184
|
// Process imports sequentially to ensure all JS modules are loaded before definitions
|
|
1162
1185
|
for (const imp of module.imports as Import[]) {
|
|
1163
1186
|
await importModule(imp.path, imp.name, moduleFileName);
|
|
1187
|
+
r.addImport({ name: imp.name, path: imp.path });
|
|
1164
1188
|
}
|
|
1165
1189
|
for (let i = 0; i < module.defs.length; ++i) {
|
|
1166
1190
|
const def = module.defs[i];
|
|
@@ -1186,31 +1210,57 @@ export async function loadRawConfig(
|
|
|
1186
1210
|
}
|
|
1187
1211
|
}
|
|
1188
1212
|
|
|
1189
|
-
function filterConfigEntityInstances(rawConfig: any): [any,
|
|
1190
|
-
|
|
1191
|
-
const insts = new
|
|
1192
|
-
Object.
|
|
1193
|
-
|
|
1194
|
-
insts.set(key, value);
|
|
1195
|
-
} else {
|
|
1196
|
-
cfg.set(key, value);
|
|
1197
|
-
}
|
|
1213
|
+
function filterConfigEntityInstances(rawConfig: any): [any, Array<any>] {
|
|
1214
|
+
let cfg: any = undefined;
|
|
1215
|
+
const insts = new Array<any>();
|
|
1216
|
+
const oldFormat = Object.keys(rawConfig).some((k: string) => {
|
|
1217
|
+
return k === 'store' || k === 'service';
|
|
1198
1218
|
});
|
|
1199
|
-
|
|
1219
|
+
const newFormat = !oldFormat;
|
|
1220
|
+
if (newFormat) {
|
|
1221
|
+
Object.entries(rawConfig).forEach(([key, value]: [string, any]) => {
|
|
1222
|
+
if (key === 'agentlang') {
|
|
1223
|
+
cfg = value;
|
|
1224
|
+
} else {
|
|
1225
|
+
if (value instanceof Array) {
|
|
1226
|
+
value.forEach((v: any) => {
|
|
1227
|
+
insts.push(v);
|
|
1228
|
+
});
|
|
1229
|
+
} else {
|
|
1230
|
+
insts.push(value);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
if (cfg === undefined) cfg = {};
|
|
1235
|
+
return [cfg, insts];
|
|
1236
|
+
} else {
|
|
1237
|
+
return [rawConfig, insts];
|
|
1238
|
+
}
|
|
1200
1239
|
}
|
|
1201
1240
|
|
|
1202
1241
|
async function configFromObject(cfgObj: any, validate: boolean = true): Promise<any> {
|
|
1203
1242
|
const rawConfig = preprocessRawConfig(cfgObj);
|
|
1204
|
-
if (validate) {
|
|
1243
|
+
if (validate && rawConfig) {
|
|
1205
1244
|
const [cfg, insts] = filterConfigEntityInstances(rawConfig);
|
|
1206
1245
|
const pats = new Array<string>();
|
|
1207
|
-
insts.forEach((v: any
|
|
1208
|
-
|
|
1246
|
+
insts.forEach((v: any) => {
|
|
1247
|
+
const n = Object.keys(v)[0];
|
|
1248
|
+
const attrs = v[n];
|
|
1249
|
+
pats.push(`{${n} ${objectAsString(attrs)}}`);
|
|
1209
1250
|
});
|
|
1210
1251
|
if (pats.length > 0) {
|
|
1211
1252
|
await evaluateConfigPatterns(pats.join('\n'));
|
|
1212
1253
|
}
|
|
1213
|
-
|
|
1254
|
+
const result = ConfigSchema.parse(cfg);
|
|
1255
|
+
cfg.retry?.forEach((r: any) => {
|
|
1256
|
+
const retry: Retry = new Retry(r.name, ScratchModuleName, r.attempts)
|
|
1257
|
+
.setBackoffDelay(r.backoff.delay)
|
|
1258
|
+
.setBackoffFactor(r.backoff.factor)
|
|
1259
|
+
.setBackoffStrategy(r.backoff.strategy[0])
|
|
1260
|
+
.setBackoffMagnitude(r.backoff.magnitude);
|
|
1261
|
+
addGlobalRetry(retry);
|
|
1262
|
+
});
|
|
1263
|
+
return result;
|
|
1214
1264
|
}
|
|
1215
1265
|
return rawConfig;
|
|
1216
1266
|
}
|
package/src/runtime/module.ts
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
RbacSpecEntries,
|
|
21
21
|
RbacOpr,
|
|
22
22
|
WorkflowHeader,
|
|
23
|
+
FlowDefinition,
|
|
24
|
+
FlowEntry,
|
|
23
25
|
} from '../language/generated/ast.js';
|
|
24
26
|
import {
|
|
25
27
|
Path,
|
|
@@ -75,7 +77,7 @@ import {
|
|
|
75
77
|
removeAgentResponseSchema,
|
|
76
78
|
removeAgentScenarios,
|
|
77
79
|
} from './agents/common.js';
|
|
78
|
-
import { Environment } from './interpreter.js';
|
|
80
|
+
import { AggregateFunctionCall, Environment } from './interpreter.js';
|
|
79
81
|
import { isNode } from '../utils/fs-utils.js';
|
|
80
82
|
|
|
81
83
|
export class ModuleEntry {
|
|
@@ -208,7 +210,7 @@ function attributePropertyValueToString(
|
|
|
208
210
|
});
|
|
209
211
|
return ss.join(',');
|
|
210
212
|
} else if (propName == 'default') {
|
|
211
|
-
if (isTextualType(attrType) &&
|
|
213
|
+
if (isTextualType(attrType) && !defaultValueIsFunctionCall(propValue)) {
|
|
212
214
|
return `"${propValue}"`;
|
|
213
215
|
}
|
|
214
216
|
} else if (propName == 'comment') {
|
|
@@ -433,6 +435,37 @@ export class Record extends ModuleEntry {
|
|
|
433
435
|
return this;
|
|
434
436
|
}
|
|
435
437
|
|
|
438
|
+
public getSecretAttributes(): Array<string> {
|
|
439
|
+
const result = new Array<string>();
|
|
440
|
+
this.schema.forEach((spec: AttributeSpec, n: string) => {
|
|
441
|
+
if (spec.properties?.get('secret') === true) {
|
|
442
|
+
result.push(n);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
private static WriteOnlyAttributes = new Map<string, Array<string>>();
|
|
449
|
+
|
|
450
|
+
public getWriteOnlyAttributes(): Array<string> | undefined {
|
|
451
|
+
const fqn = this.getFqName();
|
|
452
|
+
const cachedResult = Record.WriteOnlyAttributes.get(fqn);
|
|
453
|
+
if (cachedResult !== undefined) {
|
|
454
|
+
if (cachedResult.length === 0) return undefined;
|
|
455
|
+
return cachedResult;
|
|
456
|
+
} else {
|
|
457
|
+
const result = new Array<string>();
|
|
458
|
+
this.schema.forEach((spec: AttributeSpec, n: string) => {
|
|
459
|
+
if (spec.properties?.get('writeonly') === true) {
|
|
460
|
+
result.push(n);
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
const finalResult = result.concat(this.getSecretAttributes());
|
|
464
|
+
Record.WriteOnlyAttributes.set(fqn, finalResult);
|
|
465
|
+
return finalResult;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
436
469
|
getCompositeUniqueAttributes(): Array<string> | undefined {
|
|
437
470
|
return this.compositeUqAttributes;
|
|
438
471
|
}
|
|
@@ -641,18 +674,27 @@ export class Record extends ModuleEntry {
|
|
|
641
674
|
return s.concat('\n{', scms, '\n}\n');
|
|
642
675
|
}
|
|
643
676
|
|
|
677
|
+
private userAttrsSchema: RecordSchema | undefined;
|
|
678
|
+
|
|
644
679
|
getUserAttributes(): RecordSchema {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
680
|
+
if (this.userAttrsSchema === undefined) {
|
|
681
|
+
this.userAttrsSchema = newRecordSchema();
|
|
682
|
+
this.schema.forEach((attrSpec: AttributeSpec, n: string) => {
|
|
683
|
+
if (!isSystemAttribute(attrSpec)) {
|
|
684
|
+
this.userAttrsSchema?.set(n, attrSpec);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
return this.userAttrsSchema;
|
|
652
689
|
}
|
|
653
690
|
|
|
654
|
-
|
|
655
|
-
|
|
691
|
+
private userAttrNames: Set<string> | undefined;
|
|
692
|
+
|
|
693
|
+
getUserAttributeNames(): Set<string> {
|
|
694
|
+
if (this.userAttrNames === undefined) {
|
|
695
|
+
this.userAttrNames = new Set([...this.getUserAttributes().keys()]);
|
|
696
|
+
}
|
|
697
|
+
return this.userAttrNames;
|
|
656
698
|
}
|
|
657
699
|
}
|
|
658
700
|
|
|
@@ -1592,18 +1634,21 @@ export type FlowGraphNode = {
|
|
|
1592
1634
|
next: string[];
|
|
1593
1635
|
};
|
|
1594
1636
|
|
|
1637
|
+
function splitFlowSteps(flow: FlowDefinition): string[] {
|
|
1638
|
+
const steps = new Array<string>();
|
|
1639
|
+
flow.body?.entries.forEach((fe: FlowEntry) => {
|
|
1640
|
+
steps.push(fe.$cstNode?.text || '');
|
|
1641
|
+
});
|
|
1642
|
+
return steps;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1595
1645
|
export class Flow extends ModuleEntry {
|
|
1596
1646
|
flowSteps: string[];
|
|
1597
1647
|
|
|
1598
|
-
constructor(name: string, moduleName: string, flow?:
|
|
1648
|
+
constructor(name: string, moduleName: string, flow?: FlowDefinition) {
|
|
1599
1649
|
super(name, moduleName);
|
|
1600
|
-
this.flowSteps =
|
|
1601
|
-
|
|
1602
|
-
const s = step.trim();
|
|
1603
|
-
if (s.length > 0) {
|
|
1604
|
-
this.flowSteps.push(s);
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1650
|
+
if (flow) this.flowSteps = splitFlowSteps(flow);
|
|
1651
|
+
else this.flowSteps = new Array<string>();
|
|
1607
1652
|
}
|
|
1608
1653
|
|
|
1609
1654
|
getFlow(): string {
|
|
@@ -1629,10 +1674,11 @@ export class Flow extends ModuleEntry {
|
|
|
1629
1674
|
return this.flowSteps.length;
|
|
1630
1675
|
}
|
|
1631
1676
|
|
|
1632
|
-
toGraph(): FlowGraphNode[] {
|
|
1677
|
+
async toGraph(): Promise<FlowGraphNode[]> {
|
|
1633
1678
|
const result = new Array<FlowGraphNode>();
|
|
1634
|
-
this.flowSteps.
|
|
1635
|
-
const
|
|
1679
|
+
for (let i = 0; i < this.flowSteps.length; ++i) {
|
|
1680
|
+
const s = this.flowSteps[i];
|
|
1681
|
+
const fp = await FlowStepPattern.Parse(s);
|
|
1636
1682
|
if (fp.condition) {
|
|
1637
1683
|
const orig = result.find((v: FlowGraphNode) => {
|
|
1638
1684
|
return v.label == fp.first;
|
|
@@ -1657,7 +1703,7 @@ export class Flow extends ModuleEntry {
|
|
|
1657
1703
|
next: [fp.next],
|
|
1658
1704
|
});
|
|
1659
1705
|
}
|
|
1660
|
-
}
|
|
1706
|
+
}
|
|
1661
1707
|
return result;
|
|
1662
1708
|
}
|
|
1663
1709
|
|
|
@@ -1801,6 +1847,11 @@ export class Retry extends ModuleEntry {
|
|
|
1801
1847
|
};
|
|
1802
1848
|
}
|
|
1803
1849
|
|
|
1850
|
+
setBackoffStrategy(s: BackoffStrategy): Retry {
|
|
1851
|
+
this.backoff.strategy = s;
|
|
1852
|
+
return this;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1804
1855
|
setExponentialBackoff(): Retry {
|
|
1805
1856
|
this.backoff.strategy = 'e';
|
|
1806
1857
|
return this;
|
|
@@ -1835,6 +1886,17 @@ export class Retry extends ModuleEntry {
|
|
|
1835
1886
|
return this;
|
|
1836
1887
|
}
|
|
1837
1888
|
|
|
1889
|
+
setBackoffMagnitude(m: string): Retry {
|
|
1890
|
+
if (m[0] === 's') {
|
|
1891
|
+
this.backoff.magnitude = 's';
|
|
1892
|
+
} else if (m.startsWith('milli')) {
|
|
1893
|
+
this.backoff.magnitude = 'ms';
|
|
1894
|
+
} else {
|
|
1895
|
+
this.backoff.magnitude = 'm';
|
|
1896
|
+
}
|
|
1897
|
+
return this;
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1838
1900
|
setBackoffMagnitudeAsMilliseconds(): Retry {
|
|
1839
1901
|
this.backoff.magnitude = 'ms';
|
|
1840
1902
|
return this;
|
|
@@ -1995,9 +2057,15 @@ export function isEmptyWorkflow(wf: Workflow): boolean {
|
|
|
1995
2057
|
return wf == EmptyWorkflow;
|
|
1996
2058
|
}
|
|
1997
2059
|
|
|
2060
|
+
export type ModuleImportEntry = {
|
|
2061
|
+
path: string;
|
|
2062
|
+
name: string;
|
|
2063
|
+
};
|
|
2064
|
+
|
|
1998
2065
|
export class Module {
|
|
1999
2066
|
name: string;
|
|
2000
2067
|
entries: ModuleEntry[];
|
|
2068
|
+
imports: ModuleImportEntry[] | undefined;
|
|
2001
2069
|
|
|
2002
2070
|
constructor(name: string) {
|
|
2003
2071
|
this.name = name;
|
|
@@ -2009,6 +2077,21 @@ export class Module {
|
|
|
2009
2077
|
return entry;
|
|
2010
2078
|
}
|
|
2011
2079
|
|
|
2080
|
+
addImport(entry: ModuleImportEntry): Module {
|
|
2081
|
+
if (this.imports === undefined) {
|
|
2082
|
+
this.imports = new Array<ModuleImportEntry>();
|
|
2083
|
+
}
|
|
2084
|
+
this.imports?.push(entry);
|
|
2085
|
+
return this;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
removeImportAt(index: number): Module {
|
|
2089
|
+
if (index >= 0) {
|
|
2090
|
+
this.imports?.splice(index, 1);
|
|
2091
|
+
}
|
|
2092
|
+
return this;
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2012
2095
|
getConfigEntity(): Entity | undefined {
|
|
2013
2096
|
return this.getEntityEntries().find((e: Entity) => {
|
|
2014
2097
|
return e.isConfigEntity();
|
|
@@ -2031,8 +2114,8 @@ export class Module {
|
|
|
2031
2114
|
return this.removeEntry(Agent.EscapeName(agentName));
|
|
2032
2115
|
}
|
|
2033
2116
|
|
|
2034
|
-
addFlow(name: string,
|
|
2035
|
-
const flow: Flow = new Flow(Flow.asFlowName(name), this.name,
|
|
2117
|
+
addFlow(name: string, flowDef?: FlowDefinition): Flow {
|
|
2118
|
+
const flow: Flow = new Flow(Flow.asFlowName(name), this.name, flowDef);
|
|
2036
2119
|
this.addEntry(flow);
|
|
2037
2120
|
return flow;
|
|
2038
2121
|
}
|
|
@@ -2434,6 +2517,14 @@ export class Module {
|
|
|
2434
2517
|
return names;
|
|
2435
2518
|
}
|
|
2436
2519
|
|
|
2520
|
+
getBetweenRelationshipNames(): string[] {
|
|
2521
|
+
const names: string[] = [];
|
|
2522
|
+
this.getRelationshipEntries().forEach((re: Relationship) => {
|
|
2523
|
+
if (re.isBetween()) names.push(re.name);
|
|
2524
|
+
});
|
|
2525
|
+
return names;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2437
2528
|
isContainsRelationship(entryName: string): boolean {
|
|
2438
2529
|
if (this.hasEntry(entryName)) {
|
|
2439
2530
|
const entry: ModuleEntry = this.getEntry(entryName);
|
|
@@ -2450,6 +2541,17 @@ export class Module {
|
|
|
2450
2541
|
return false;
|
|
2451
2542
|
}
|
|
2452
2543
|
|
|
2544
|
+
private importsAsString(): string {
|
|
2545
|
+
if (this.imports !== undefined) {
|
|
2546
|
+
const ss = new Array<string>();
|
|
2547
|
+
this.imports.forEach((me: ModuleImportEntry) => {
|
|
2548
|
+
ss.push(`import "${me.path}" @as ${me.name}`);
|
|
2549
|
+
});
|
|
2550
|
+
return `\n${ss.join('\n')}\n`;
|
|
2551
|
+
}
|
|
2552
|
+
return '';
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2453
2555
|
toString(): string {
|
|
2454
2556
|
const ss: Array<string> = [];
|
|
2455
2557
|
this.entries.forEach((me: ModuleEntry) => {
|
|
@@ -2458,8 +2560,27 @@ export class Module {
|
|
|
2458
2560
|
}
|
|
2459
2561
|
ss.push(me.toString());
|
|
2460
2562
|
});
|
|
2461
|
-
return `module ${this.name}\n\n${ss.join('\n')}`;
|
|
2563
|
+
return `module ${this.name}\n${this.importsAsString()}\n${ss.join('\n')}`;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
let GlobalRetries: Array<Retry> | undefined = undefined;
|
|
2568
|
+
|
|
2569
|
+
export function addGlobalRetry(r: Retry): Retry {
|
|
2570
|
+
if (GlobalRetries === undefined) {
|
|
2571
|
+
GlobalRetries = new Array<Retry>();
|
|
2572
|
+
}
|
|
2573
|
+
GlobalRetries?.push(r);
|
|
2574
|
+
return r;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
export function getGlobalRetry(name: string): Retry | undefined {
|
|
2578
|
+
if (GlobalRetries !== undefined) {
|
|
2579
|
+
return GlobalRetries.find((r: Retry) => {
|
|
2580
|
+
return r.name === name;
|
|
2581
|
+
});
|
|
2462
2582
|
}
|
|
2583
|
+
return undefined;
|
|
2463
2584
|
}
|
|
2464
2585
|
|
|
2465
2586
|
declare global {
|
|
@@ -2587,6 +2708,8 @@ export const propertyNames = new Set([
|
|
|
2587
2708
|
'@fk',
|
|
2588
2709
|
'@ref',
|
|
2589
2710
|
'@readonly',
|
|
2711
|
+
'@writeonly',
|
|
2712
|
+
'@secret',
|
|
2590
2713
|
'@enum',
|
|
2591
2714
|
'@oneof',
|
|
2592
2715
|
'@comment',
|
|
@@ -2655,7 +2778,7 @@ export function defaultAttributes(schema: RecordSchema): Map<string, any> {
|
|
|
2655
2778
|
export function passwordAttributes(schema: RecordSchema): Set<string> | undefined {
|
|
2656
2779
|
let result: Set<string> | undefined = undefined;
|
|
2657
2780
|
schema.forEach((v: AttributeSpec, k: string) => {
|
|
2658
|
-
if (v.type == 'Password') {
|
|
2781
|
+
if (v.type == 'Password' || v.properties?.get('secret') === true) {
|
|
2659
2782
|
if (result === undefined) {
|
|
2660
2783
|
result = new Set<string>();
|
|
2661
2784
|
}
|
|
@@ -3336,6 +3459,10 @@ export class Instance {
|
|
|
3336
3459
|
queryAttributes: InstanceAttributes | undefined;
|
|
3337
3460
|
queryAttributeValues: InstanceAttributes | undefined;
|
|
3338
3461
|
relatedInstances: Map<string, Instance[]> | undefined;
|
|
3462
|
+
aggregates: Map<string, AggregateFunctionCall> | undefined;
|
|
3463
|
+
groupBy: string[] | undefined;
|
|
3464
|
+
orderBy: string[] | undefined;
|
|
3465
|
+
orderByDesc: boolean = false;
|
|
3339
3466
|
private contextData: Map<string, any> | undefined;
|
|
3340
3467
|
private ___id: string;
|
|
3341
3468
|
|
|
@@ -3432,6 +3559,22 @@ export class Instance {
|
|
|
3432
3559
|
return this.lookup(PathAttributeName);
|
|
3433
3560
|
}
|
|
3434
3561
|
|
|
3562
|
+
setAggregates(aggregates: Map<string, AggregateFunctionCall>): Instance {
|
|
3563
|
+
this.aggregates = aggregates;
|
|
3564
|
+
return this;
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3567
|
+
setGroupBy(n: string[]): Instance {
|
|
3568
|
+
this.groupBy = n;
|
|
3569
|
+
return this;
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
setOrderBy(n: string[], desc: boolean = false): Instance {
|
|
3573
|
+
this.orderBy = n;
|
|
3574
|
+
this.orderByDesc = desc;
|
|
3575
|
+
return this;
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3435
3578
|
asSerializableObject(): object {
|
|
3436
3579
|
const obj: any = {
|
|
3437
3580
|
AL_INSTANCE: true,
|
|
@@ -3519,6 +3662,15 @@ export class Instance {
|
|
|
3519
3662
|
return Object.fromEntries(attrs);
|
|
3520
3663
|
}
|
|
3521
3664
|
|
|
3665
|
+
userAttributesAsObject(forSerialization: boolean = false): object {
|
|
3666
|
+
const attrs = newInstanceAttributes();
|
|
3667
|
+
const userAttrNames = this.getAllUserAttributeNames();
|
|
3668
|
+
this.attributes.forEach((v: any, k: string) => {
|
|
3669
|
+
if (userAttrNames.has(k)) attrs.set(k, Instance.asSerializableValue(v, forSerialization));
|
|
3670
|
+
});
|
|
3671
|
+
return Object.fromEntries(attrs);
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3522
3674
|
static stringifyObjects(attributes: InstanceAttributes): object {
|
|
3523
3675
|
const attrs = newInstanceAttributes();
|
|
3524
3676
|
attributes.forEach((v: any, k: string) => {
|
|
@@ -3549,6 +3701,10 @@ export class Instance {
|
|
|
3549
3701
|
return {};
|
|
3550
3702
|
}
|
|
3551
3703
|
|
|
3704
|
+
getQueryValue(k: string): any {
|
|
3705
|
+
return this.queryAttributeValues?.get(k);
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3552
3708
|
addQuery(attrName: string, op: string = '=', attrVal: any = undefined) {
|
|
3553
3709
|
if (this.queryAttributes === undefined) this.queryAttributes = newInstanceAttributes();
|
|
3554
3710
|
this.queryAttributes.set(attrName, op);
|
|
@@ -3610,7 +3766,7 @@ export class Instance {
|
|
|
3610
3766
|
return undefined;
|
|
3611
3767
|
}
|
|
3612
3768
|
|
|
3613
|
-
getAllUserAttributeNames(): string
|
|
3769
|
+
getAllUserAttributeNames(): Set<string> {
|
|
3614
3770
|
return this.record.getUserAttributeNames();
|
|
3615
3771
|
}
|
|
3616
3772
|
|
|
@@ -3743,6 +3899,10 @@ export function findIdAttribute(inst: Instance): AttributeEntry | undefined {
|
|
|
3743
3899
|
return undefined;
|
|
3744
3900
|
}
|
|
3745
3901
|
|
|
3902
|
+
function defaultValueIsFunctionCall(dv: string): boolean {
|
|
3903
|
+
return dv.endsWith('()');
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3746
3906
|
function maybeSetDefaultAttributeValues(
|
|
3747
3907
|
schema: RecordSchema,
|
|
3748
3908
|
attributes: InstanceAttributes
|
|
@@ -3752,10 +3912,12 @@ function maybeSetDefaultAttributeValues(
|
|
|
3752
3912
|
const cv = attributes.get(k);
|
|
3753
3913
|
if (cv === undefined || cv === null) {
|
|
3754
3914
|
if (isString(v)) {
|
|
3755
|
-
if (v
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3915
|
+
if (defaultValueIsFunctionCall(v)) {
|
|
3916
|
+
try {
|
|
3917
|
+
v = eval(v);
|
|
3918
|
+
} catch {
|
|
3919
|
+
v = (0, eval)(`globalThis.${v}`);
|
|
3920
|
+
}
|
|
3759
3921
|
}
|
|
3760
3922
|
}
|
|
3761
3923
|
attributes.set(k, v);
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
Decision,
|
|
21
21
|
fetchModule,
|
|
22
22
|
getDecision,
|
|
23
|
+
getGlobalRetry,
|
|
23
24
|
Instance,
|
|
24
25
|
instanceToObject,
|
|
25
26
|
isAgent,
|
|
@@ -198,11 +199,16 @@ export class AgentInstance {
|
|
|
198
199
|
if (agent.retry) {
|
|
199
200
|
let n = agent.retry;
|
|
200
201
|
if (!isFqName(n)) {
|
|
201
|
-
|
|
202
|
+
agent.retryObj = getGlobalRetry(n);
|
|
203
|
+
if (agent.retryObj === undefined) {
|
|
204
|
+
n = `${agent.moduleName}/${n}`;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (agent.retryObj === undefined) {
|
|
208
|
+
const parts = splitFqName(n);
|
|
209
|
+
const m = fetchModule(parts[0]);
|
|
210
|
+
agent.retryObj = m.getRetry(parts[1]);
|
|
202
211
|
}
|
|
203
|
-
const parts = splitFqName(n);
|
|
204
|
-
const m = fetchModule(parts[0]);
|
|
205
|
-
agent.retryObj = m.getRetry(parts[1]);
|
|
206
212
|
}
|
|
207
213
|
return agent;
|
|
208
214
|
}
|
|
@@ -36,6 +36,7 @@ entity User {
|
|
|
36
36
|
email Email @unique @indexed,
|
|
37
37
|
firstName String,
|
|
38
38
|
lastName String,
|
|
39
|
+
profilePicture String @optional,
|
|
39
40
|
lastLoginTime DateTime @default(now()),
|
|
40
41
|
status @enum("Active", "Invited", "Inactive") @default("Active"),
|
|
41
42
|
@rbac [(allow: [read, delete, update, create], where: auth.user = this.id)],
|