agentlang 0.10.1 → 0.10.3
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/README.md +7 -14
- package/out/api/http.d.ts +4 -0
- package/out/api/http.d.ts.map +1 -1
- package/out/api/http.js +307 -26
- package/out/api/http.js.map +1 -1
- package/out/cli/main.d.ts.map +1 -1
- package/out/cli/main.js +3 -0
- 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.map +1 -1
- package/out/language/agentlang-validator.js +4 -0
- package/out/language/agentlang-validator.js.map +1 -1
- package/out/language/error-reporter.d.ts +53 -0
- package/out/language/error-reporter.d.ts.map +1 -0
- package/out/language/error-reporter.js +879 -0
- package/out/language/error-reporter.js.map +1 -0
- package/out/language/generated/ast.d.ts +77 -2
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +60 -0
- 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 +342 -206
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +901 -710
- package/out/language/main.cjs.map +3 -3
- package/out/language/parser.d.ts +4 -2
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +58 -99
- package/out/language/parser.js.map +1 -1
- package/out/language/syntax.d.ts +16 -0
- package/out/language/syntax.d.ts.map +1 -1
- package/out/language/syntax.js +66 -27
- package/out/language/syntax.js.map +1 -1
- package/out/runtime/api.d.ts +2 -0
- package/out/runtime/api.d.ts.map +1 -1
- package/out/runtime/api.js +25 -0
- package/out/runtime/api.js.map +1 -1
- package/out/runtime/datefns.d.ts +34 -0
- package/out/runtime/datefns.d.ts.map +1 -0
- package/out/runtime/datefns.js +82 -0
- package/out/runtime/datefns.js.map +1 -0
- package/out/runtime/defs.d.ts +1 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +2 -1
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/document-retriever.d.ts +24 -0
- package/out/runtime/document-retriever.d.ts.map +1 -0
- package/out/runtime/document-retriever.js +258 -0
- package/out/runtime/document-retriever.js.map +1 -0
- package/out/runtime/embeddings/chunker.d.ts +18 -0
- package/out/runtime/embeddings/chunker.d.ts.map +1 -1
- package/out/runtime/embeddings/chunker.js +47 -15
- package/out/runtime/embeddings/chunker.js.map +1 -1
- package/out/runtime/embeddings/openai.d.ts.map +1 -1
- package/out/runtime/embeddings/openai.js +22 -9
- package/out/runtime/embeddings/openai.js.map +1 -1
- package/out/runtime/embeddings/provider.d.ts +1 -0
- package/out/runtime/embeddings/provider.d.ts.map +1 -1
- package/out/runtime/embeddings/provider.js +20 -1
- package/out/runtime/embeddings/provider.js.map +1 -1
- package/out/runtime/exec-graph.d.ts.map +1 -1
- package/out/runtime/exec-graph.js +22 -3
- package/out/runtime/exec-graph.js.map +1 -1
- package/out/runtime/integration-client.d.ts +21 -0
- package/out/runtime/integration-client.d.ts.map +1 -0
- package/out/runtime/integration-client.js +112 -0
- package/out/runtime/integration-client.js.map +1 -0
- package/out/runtime/integrations.d.ts.map +1 -1
- package/out/runtime/integrations.js +20 -9
- package/out/runtime/integrations.js.map +1 -1
- package/out/runtime/interpreter.d.ts +10 -0
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +221 -22
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +70 -7
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/logger.d.ts.map +1 -1
- package/out/runtime/logger.js +8 -1
- package/out/runtime/logger.js.map +1 -1
- package/out/runtime/module.d.ts +18 -0
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +91 -3
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +16 -5
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +286 -88
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +5 -1
- package/out/runtime/modules/core.js.map +1 -1
- package/out/runtime/monitor.d.ts +6 -0
- package/out/runtime/monitor.d.ts.map +1 -1
- package/out/runtime/monitor.js +21 -1
- package/out/runtime/monitor.js.map +1 -1
- package/out/runtime/relgraph.d.ts.map +1 -1
- package/out/runtime/relgraph.js +7 -3
- package/out/runtime/relgraph.js.map +1 -1
- package/out/runtime/resolvers/interface.d.ts +7 -2
- package/out/runtime/resolvers/interface.d.ts.map +1 -1
- package/out/runtime/resolvers/interface.js +17 -3
- package/out/runtime/resolvers/interface.js.map +1 -1
- package/out/runtime/resolvers/sqldb/database.d.ts +2 -0
- package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/database.js +142 -126
- package/out/runtime/resolvers/sqldb/database.js.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/dbutil.js +25 -4
- package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts +2 -1
- package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
- package/out/runtime/resolvers/sqldb/impl.js +24 -7
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
- package/out/runtime/resolvers/vector/lancedb-store.d.ts +16 -0
- package/out/runtime/resolvers/vector/lancedb-store.d.ts.map +1 -0
- package/out/runtime/resolvers/vector/lancedb-store.js +159 -0
- package/out/runtime/resolvers/vector/lancedb-store.js.map +1 -0
- package/out/runtime/resolvers/vector/types.d.ts +32 -0
- package/out/runtime/resolvers/vector/types.d.ts.map +1 -0
- package/out/runtime/resolvers/vector/types.js +2 -0
- package/out/runtime/resolvers/vector/types.js.map +1 -0
- package/out/runtime/services/documentFetcher.d.ts.map +1 -1
- package/out/runtime/services/documentFetcher.js +21 -6
- package/out/runtime/services/documentFetcher.js.map +1 -1
- package/out/runtime/state.d.ts +19 -1
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +36 -1
- package/out/runtime/state.js.map +1 -1
- package/out/runtime/util.d.ts +3 -2
- package/out/runtime/util.d.ts.map +1 -1
- package/out/runtime/util.js +13 -2
- 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/test-harness.d.ts +36 -0
- package/out/test-harness.d.ts.map +1 -0
- package/out/test-harness.js +341 -0
- package/out/test-harness.js.map +1 -0
- package/package.json +22 -19
- package/src/api/http.ts +336 -38
- package/src/cli/main.ts +3 -0
- package/src/language/agentlang-validator.ts +3 -0
- package/src/language/agentlang.langium +6 -2
- package/src/language/error-reporter.ts +1028 -0
- package/src/language/generated/ast.ts +94 -1
- package/src/language/generated/grammar.ts +342 -206
- package/src/language/parser.ts +64 -101
- package/src/language/syntax.ts +79 -24
- package/src/runtime/api.ts +36 -0
- package/src/runtime/datefns.ts +112 -0
- package/src/runtime/defs.ts +2 -1
- package/src/runtime/document-retriever.ts +311 -0
- package/src/runtime/embeddings/chunker.ts +52 -14
- package/src/runtime/embeddings/openai.ts +27 -9
- package/src/runtime/embeddings/provider.ts +22 -1
- package/src/runtime/exec-graph.ts +23 -2
- package/src/runtime/integration-client.ts +158 -0
- package/src/runtime/integrations.ts +20 -11
- package/src/runtime/interpreter.ts +221 -15
- package/src/runtime/loader.ts +83 -5
- package/src/runtime/logger.ts +12 -1
- package/src/runtime/module.ts +104 -3
- package/src/runtime/modules/ai.ts +341 -107
- package/src/runtime/modules/core.ts +5 -1
- package/src/runtime/monitor.ts +27 -1
- package/src/runtime/relgraph.ts +7 -3
- package/src/runtime/resolvers/interface.ts +23 -3
- package/src/runtime/resolvers/sqldb/database.ts +158 -130
- package/src/runtime/resolvers/sqldb/dbutil.ts +28 -6
- package/src/runtime/resolvers/sqldb/impl.ts +25 -7
- package/src/runtime/resolvers/vector/lancedb-store.ts +187 -0
- package/src/runtime/resolvers/vector/types.ts +39 -0
- package/src/runtime/services/documentFetcher.ts +21 -6
- package/src/runtime/state.ts +40 -1
- package/src/runtime/util.ts +19 -2
- package/src/syntaxes/agentlang.monarch.ts +1 -1
- package/src/test-harness.ts +423 -0
package/src/runtime/loader.ts
CHANGED
|
@@ -72,6 +72,9 @@ import {
|
|
|
72
72
|
Retry,
|
|
73
73
|
addGlobalRetry,
|
|
74
74
|
AgentEvaluator,
|
|
75
|
+
getAllBetweenRelationshipsForEntity,
|
|
76
|
+
getAttributeExpr,
|
|
77
|
+
AttributeSpec,
|
|
75
78
|
} from './module.js';
|
|
76
79
|
import {
|
|
77
80
|
asStringLiteralsMap,
|
|
@@ -85,6 +88,7 @@ import {
|
|
|
85
88
|
registerInitFunction,
|
|
86
89
|
rootRef,
|
|
87
90
|
ScratchModuleName,
|
|
91
|
+
splitRefs,
|
|
88
92
|
} from './util.js';
|
|
89
93
|
import { getFileSystem, toFsPath, readFile, readdir, exists } from '../utils/fs-utils.js';
|
|
90
94
|
import { URI } from 'vscode-uri';
|
|
@@ -102,7 +106,12 @@ import {
|
|
|
102
106
|
parseWorkflow,
|
|
103
107
|
} from '../language/parser.js';
|
|
104
108
|
import { logger } from './logger.js';
|
|
105
|
-
import {
|
|
109
|
+
import {
|
|
110
|
+
Environment,
|
|
111
|
+
evaluateStatements,
|
|
112
|
+
extractRefsFromExpr,
|
|
113
|
+
GlobalEnvironment,
|
|
114
|
+
} from './interpreter.js';
|
|
106
115
|
import { createPermission, createRole } from './modules/auth.js';
|
|
107
116
|
import {
|
|
108
117
|
AgentEntityName,
|
|
@@ -114,7 +123,7 @@ import {
|
|
|
114
123
|
import { getDefaultLLMService } from './agents/registry.js';
|
|
115
124
|
import { GenericResolver, GenericResolverMethods } from './resolvers/interface.js';
|
|
116
125
|
import { registerResolver, setResolver } from './resolvers/registry.js';
|
|
117
|
-
import { Config, ConfigSchema, setAppConfig } from './state.js';
|
|
126
|
+
import { AppConfig, Config, ConfigSchema, setAppConfig } from './state.js';
|
|
118
127
|
import { getModuleFn, importModule } from './jsmodules.js';
|
|
119
128
|
import { SetSubscription } from './defs.js';
|
|
120
129
|
import { ExtendedFileSystem } from '../utils/fs/interfaces.js';
|
|
@@ -178,12 +187,14 @@ export async function extractDocument(
|
|
|
178
187
|
validation: true,
|
|
179
188
|
});
|
|
180
189
|
|
|
190
|
+
// Handle parser/lexer errors (with human-friendly messages)
|
|
191
|
+
maybeRaiseParserErrors(document);
|
|
192
|
+
|
|
181
193
|
// Handle validation errors
|
|
182
194
|
const errs = maybeGetValidationErrors(document);
|
|
183
195
|
|
|
184
196
|
if (errs) {
|
|
185
|
-
|
|
186
|
-
throw new Error(errorMsg);
|
|
197
|
+
throw new Error('\n' + errs);
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
return document;
|
|
@@ -423,7 +434,9 @@ export async function loadAppConfig(configDirOrContent: string): Promise<Config>
|
|
|
423
434
|
const envConfig = JSON.parse(envAppConfig);
|
|
424
435
|
cfg = { ...cfg, ...envConfig };
|
|
425
436
|
}
|
|
426
|
-
|
|
437
|
+
const result = setAppConfig(cfg);
|
|
438
|
+
|
|
439
|
+
return result;
|
|
427
440
|
} catch (err: any) {
|
|
428
441
|
if (err instanceof z.ZodError) {
|
|
429
442
|
console.log(chalk.red('Config validation failed:'));
|
|
@@ -1152,6 +1165,16 @@ function addResolverDefinition(def: ResolverDefinition, moduleName: string) {
|
|
|
1152
1165
|
});
|
|
1153
1166
|
const methodsObj = Object.fromEntries(methods.entries()) as GenericResolverMethods;
|
|
1154
1167
|
const resolver = new GenericResolver(resolverName, methodsObj);
|
|
1168
|
+
const connections = AppConfig?.integrations?.connections;
|
|
1169
|
+
if (connections) {
|
|
1170
|
+
for (const [integName, conn] of Object.entries(connections)) {
|
|
1171
|
+
const resolvers = typeof conn === 'string' ? [] : conn.resolvers;
|
|
1172
|
+
if (resolvers.includes(resolverName)) {
|
|
1173
|
+
resolver.setIntegrationName(integName);
|
|
1174
|
+
break;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1155
1178
|
registerResolver(resolverName, () => {
|
|
1156
1179
|
return resolver;
|
|
1157
1180
|
});
|
|
@@ -1215,6 +1238,60 @@ export async function refreshModuleDefinition(moduleName: string, moduleDefiniti
|
|
|
1215
1238
|
await internModule(r.parseResult.value);
|
|
1216
1239
|
}
|
|
1217
1240
|
|
|
1241
|
+
function validateExprRelationshipRefs(moduleName: string, mod: Module) {
|
|
1242
|
+
const entities = mod.getEntityEntries();
|
|
1243
|
+
for (const entity of entities) {
|
|
1244
|
+
const schema = entity.schema;
|
|
1245
|
+
schema.forEach((attrSpec: AttributeSpec, attrName: string) => {
|
|
1246
|
+
const expr = getAttributeExpr(attrSpec);
|
|
1247
|
+
if (!expr) return;
|
|
1248
|
+
const refs = extractRefsFromExpr(expr);
|
|
1249
|
+
const entityFqName = makeFqName(moduleName, entity.name);
|
|
1250
|
+
const rels = getAllBetweenRelationshipsForEntity(moduleName, entity.name);
|
|
1251
|
+
if (rels.length === 0) return;
|
|
1252
|
+
for (const ref of refs) {
|
|
1253
|
+
const parts = splitRefs(ref);
|
|
1254
|
+
if (parts.length < 3) continue;
|
|
1255
|
+
const relName = parts[0];
|
|
1256
|
+
const targetEntityAlias = parts[1];
|
|
1257
|
+
const rel = rels.find((r: Relationship) => r.name === relName);
|
|
1258
|
+
if (!rel) continue;
|
|
1259
|
+
// Matched a relationship name - validate
|
|
1260
|
+
if (targetEntityAlias !== rel.node1.alias && targetEntityAlias !== rel.node2.alias) {
|
|
1261
|
+
throw new Error(
|
|
1262
|
+
`Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
|
|
1263
|
+
`"${targetEntityAlias}" does not match any entity alias in relationship ${relName} ` +
|
|
1264
|
+
`(expected "${rel.node1.alias}" or "${rel.node2.alias}")`
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
// The target entity must be on the OTHER side from the current entity
|
|
1268
|
+
const isFirstNode = rel.isFirstNodeName(entityFqName);
|
|
1269
|
+
const targetIsFirst = targetEntityAlias === rel.node1.alias;
|
|
1270
|
+
if ((isFirstNode && targetIsFirst) || (!isFirstNode && !targetIsFirst)) {
|
|
1271
|
+
throw new Error(
|
|
1272
|
+
`Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
|
|
1273
|
+
`the referenced entity "${targetEntityAlias}" must be on the other side of relationship ${relName}`
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
// Cardinality check
|
|
1277
|
+
if (rel.isManyToMany()) {
|
|
1278
|
+
throw new Error(
|
|
1279
|
+
`Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
|
|
1280
|
+
`cannot reference through many-to-many relationship ${relName}`
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
if (rel.isOneToMany() && isFirstNode) {
|
|
1284
|
+
throw new Error(
|
|
1285
|
+
`Invalid @expr reference "${ref}" on ${entityFqName}.${attrName}: ` +
|
|
1286
|
+
`cannot reference from the "one" side of one-to-many relationship ${relName} ` +
|
|
1287
|
+
`(would resolve to multiple entities)`
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1218
1295
|
export async function internModule(
|
|
1219
1296
|
module: ModuleDefinition,
|
|
1220
1297
|
moduleFileName?: string
|
|
@@ -1230,6 +1307,7 @@ export async function internModule(
|
|
|
1230
1307
|
const def = module.defs[i];
|
|
1231
1308
|
await addFromDef(def, mn);
|
|
1232
1309
|
}
|
|
1310
|
+
validateExprRelationshipRefs(mn, r);
|
|
1233
1311
|
return r;
|
|
1234
1312
|
}
|
|
1235
1313
|
|
package/src/runtime/logger.ts
CHANGED
|
@@ -36,6 +36,17 @@ export function initializeLogger() {
|
|
|
36
36
|
maxFiles: '7d',
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
+
// Add console transport for visibility
|
|
40
|
+
const consoleTransport = new winston.transports.Console({
|
|
41
|
+
level: logLevel,
|
|
42
|
+
format: winston.format.combine(
|
|
43
|
+
winston.format.colorize(),
|
|
44
|
+
winston.format.printf(({ level, message }: any) => {
|
|
45
|
+
return `${level}: ${message}`;
|
|
46
|
+
})
|
|
47
|
+
),
|
|
48
|
+
});
|
|
49
|
+
|
|
39
50
|
logger = winston.createLogger({
|
|
40
51
|
level: logLevel,
|
|
41
52
|
format: winston.format.combine(
|
|
@@ -44,7 +55,7 @@ export function initializeLogger() {
|
|
|
44
55
|
return `[${timestamp}] ${level}: ${message}`;
|
|
45
56
|
})
|
|
46
57
|
),
|
|
47
|
-
transports: [fileTransport],
|
|
58
|
+
transports: [fileTransport, consoleTransport],
|
|
48
59
|
});
|
|
49
60
|
} else {
|
|
50
61
|
function mkLogger(tag: string): Function {
|
package/src/runtime/module.ts
CHANGED
|
@@ -1409,6 +1409,10 @@ export class Relationship extends Record {
|
|
|
1409
1409
|
return this.relType == RelType.BETWEEN;
|
|
1410
1410
|
}
|
|
1411
1411
|
|
|
1412
|
+
isSelfReferencing(): boolean {
|
|
1413
|
+
return this.node1.path.asFqName() === this.node2.path.asFqName();
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1412
1416
|
parentNode(): RelationshipNode {
|
|
1413
1417
|
return this.node1;
|
|
1414
1418
|
}
|
|
@@ -1502,6 +1506,28 @@ export class Relationship extends Record {
|
|
|
1502
1506
|
}
|
|
1503
1507
|
}
|
|
1504
1508
|
|
|
1509
|
+
/**
|
|
1510
|
+
* For self-referencing relationships, resolve the alias for the connected instance
|
|
1511
|
+
* based on an explicit connectedAlias. Falls back to fqName-based lookup for
|
|
1512
|
+
* non-self-referencing relationships.
|
|
1513
|
+
*/
|
|
1514
|
+
getAliasForConnected(inst: Instance, connectedAlias?: string): string {
|
|
1515
|
+
if (connectedAlias && this.isSelfReferencing()) {
|
|
1516
|
+
return connectedAlias;
|
|
1517
|
+
}
|
|
1518
|
+
return this.getAliasFor(inst);
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
getInverseAliasForConnected(inst: Instance, connectedAlias?: string): string {
|
|
1522
|
+
if (connectedAlias && this.isSelfReferencing()) {
|
|
1523
|
+
if (connectedAlias === this.node1.alias) {
|
|
1524
|
+
return this.node2.alias;
|
|
1525
|
+
}
|
|
1526
|
+
return this.node1.alias;
|
|
1527
|
+
}
|
|
1528
|
+
return this.getInverseAliasFor(inst);
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1505
1531
|
isParent(inst: Instance): boolean {
|
|
1506
1532
|
return inst.getFqName() == this.node1.path.asFqName();
|
|
1507
1533
|
}
|
|
@@ -2004,7 +2030,7 @@ export class Retry extends ModuleEntry {
|
|
|
2004
2030
|
|
|
2005
2031
|
constructor(name: string, moduleName: string, attempts: number) {
|
|
2006
2032
|
super(name, moduleName);
|
|
2007
|
-
this.attempts = attempts
|
|
2033
|
+
this.attempts = attempts;
|
|
2008
2034
|
this.backoff = {
|
|
2009
2035
|
strategy: undefined,
|
|
2010
2036
|
delay: undefined,
|
|
@@ -2096,7 +2122,7 @@ export class Retry extends ModuleEntry {
|
|
|
2096
2122
|
}
|
|
2097
2123
|
|
|
2098
2124
|
getNextDelayMs(attempt: number): number {
|
|
2099
|
-
if (attempt >= this.attempts) {
|
|
2125
|
+
if (this.attempts >= 0 && attempt >= this.attempts) {
|
|
2100
2126
|
return 0;
|
|
2101
2127
|
}
|
|
2102
2128
|
const delay = this.backoff.delay === undefined ? 2 : this.backoff.delay;
|
|
@@ -2833,6 +2859,46 @@ export function resolveDocumentAliases(names: string[]): string[] {
|
|
|
2833
2859
|
return names.map((name: string) => DocumentAliasMap.get(name) ?? name);
|
|
2834
2860
|
}
|
|
2835
2861
|
|
|
2862
|
+
// TopicRegistry: maps topic name → list of document titles belonging to that topic
|
|
2863
|
+
const TopicRegistry: Map<string, string[]> = new Map();
|
|
2864
|
+
|
|
2865
|
+
export function registerTopic(name: string, documents?: string): void {
|
|
2866
|
+
if (!name) return;
|
|
2867
|
+
const docs = documents
|
|
2868
|
+
? documents
|
|
2869
|
+
.split(',')
|
|
2870
|
+
.map(d => d.trim())
|
|
2871
|
+
.filter(Boolean)
|
|
2872
|
+
: [];
|
|
2873
|
+
TopicRegistry.set(name, docs);
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
export function getTopicDocuments(topicName: string): string[] {
|
|
2877
|
+
return TopicRegistry.get(topicName) ?? [];
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
export function resolveTopicNames(topicsCsv: string): string[] {
|
|
2881
|
+
return topicsCsv
|
|
2882
|
+
.split(',')
|
|
2883
|
+
.map(t => t.trim())
|
|
2884
|
+
.filter(Boolean);
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
export function getTopicContainerTags(topicNames: string[]): string[] {
|
|
2888
|
+
return topicNames.filter(name => TopicRegistry.has(name));
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
export function getAllDocumentsForTopics(topicNames: string[]): string[] {
|
|
2892
|
+
const docs: string[] = [];
|
|
2893
|
+
for (const name of topicNames) {
|
|
2894
|
+
const topicDocs = TopicRegistry.get(name);
|
|
2895
|
+
if (topicDocs) {
|
|
2896
|
+
docs.push(...topicDocs);
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
return [...new Set(docs)];
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2836
2902
|
export function addGlobalRetry(r: Retry): Retry {
|
|
2837
2903
|
if (GlobalRetries === undefined) {
|
|
2838
2904
|
GlobalRetries = new Array<Retry>();
|
|
@@ -2929,6 +2995,19 @@ export function fetchModuleEntry(entryName: string, moduleName: string): ModuleE
|
|
|
2929
2995
|
const module: Module = fetchModule(moduleName);
|
|
2930
2996
|
return module.getEntry(entryName);
|
|
2931
2997
|
}
|
|
2998
|
+
// UUID regex pattern
|
|
2999
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
3000
|
+
|
|
3001
|
+
// containerTag format: alphanumeric with dashes/underscores, no spaces
|
|
3002
|
+
const CONTAINER_TAG_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
3003
|
+
|
|
3004
|
+
export function isTopicReference(value: any): boolean {
|
|
3005
|
+
if (!isString(value)) {
|
|
3006
|
+
return false;
|
|
3007
|
+
}
|
|
3008
|
+
// Topic can be a UUID or a containerTag format
|
|
3009
|
+
return UUID_REGEX.test(value) || CONTAINER_TAG_REGEX.test(value);
|
|
3010
|
+
}
|
|
2932
3011
|
|
|
2933
3012
|
const builtInChecks = new Map([
|
|
2934
3013
|
['String', isString],
|
|
@@ -2957,6 +3036,7 @@ const builtInChecks = new Map([
|
|
|
2957
3036
|
return true;
|
|
2958
3037
|
},
|
|
2959
3038
|
],
|
|
3039
|
+
['Topic', isTopicReference],
|
|
2960
3040
|
]);
|
|
2961
3041
|
|
|
2962
3042
|
export const builtInTypes = new Set(Array.from(builtInChecks.keys()));
|
|
@@ -2980,7 +3060,16 @@ export const propertyNames = new Set([
|
|
|
2980
3060
|
'@comment',
|
|
2981
3061
|
]);
|
|
2982
3062
|
|
|
2983
|
-
const TextualTypes = new Set([
|
|
3063
|
+
const TextualTypes = new Set([
|
|
3064
|
+
'String',
|
|
3065
|
+
'Email',
|
|
3066
|
+
'UUID',
|
|
3067
|
+
'DateTime',
|
|
3068
|
+
'Date',
|
|
3069
|
+
'Time',
|
|
3070
|
+
'Path',
|
|
3071
|
+
'Topic',
|
|
3072
|
+
]);
|
|
2984
3073
|
|
|
2985
3074
|
function isTextualType(type: string): boolean {
|
|
2986
3075
|
return TextualTypes.has(type);
|
|
@@ -3749,6 +3838,8 @@ export class Instance {
|
|
|
3749
3838
|
groupBy: string[] | undefined;
|
|
3750
3839
|
orderBy: string[] | undefined;
|
|
3751
3840
|
orderByDesc: boolean = false;
|
|
3841
|
+
limit: number | undefined;
|
|
3842
|
+
offset: number | undefined;
|
|
3752
3843
|
private contextData: Map<string, any> | undefined;
|
|
3753
3844
|
private ___id: string;
|
|
3754
3845
|
|
|
@@ -3861,6 +3952,16 @@ export class Instance {
|
|
|
3861
3952
|
return this;
|
|
3862
3953
|
}
|
|
3863
3954
|
|
|
3955
|
+
setLimit(n: number): Instance {
|
|
3956
|
+
this.limit = n;
|
|
3957
|
+
return this;
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
setOffset(n: number): Instance {
|
|
3961
|
+
this.offset = n;
|
|
3962
|
+
return this;
|
|
3963
|
+
}
|
|
3964
|
+
|
|
3864
3965
|
asSerializableObject(): object {
|
|
3865
3966
|
const obj: any = {
|
|
3866
3967
|
AL_INSTANCE: true,
|