agentlang 0.0.2
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/LICENSE +83 -0
- package/README.md +120 -0
- package/bin/cli.js +4 -0
- package/out/api/http.d.ts +3 -0
- package/out/api/http.d.ts.map +1 -0
- package/out/api/http.js +290 -0
- package/out/api/http.js.map +1 -0
- package/out/cli/cli-util.d.ts +7 -0
- package/out/cli/cli-util.d.ts.map +1 -0
- package/out/cli/cli-util.js +9 -0
- package/out/cli/cli-util.js.map +1 -0
- package/out/cli/docs.d.ts +2 -0
- package/out/cli/docs.d.ts.map +1 -0
- package/out/cli/docs.js +236 -0
- package/out/cli/docs.js.map +1 -0
- package/out/cli/main.d.ts +288 -0
- package/out/cli/main.d.ts.map +1 -0
- package/out/cli/main.js +119 -0
- package/out/cli/main.js.map +1 -0
- package/out/cli/openapi-docs.yml +695 -0
- package/out/extension/main.cjs +18093 -0
- package/out/extension/main.cjs.map +7 -0
- package/out/extension/main.d.ts +4 -0
- package/out/extension/main.d.ts.map +1 -0
- package/out/extension/main.js +42 -0
- package/out/extension/main.js.map +1 -0
- package/out/language/agentlang-module.d.ts +42 -0
- package/out/language/agentlang-module.d.ts.map +1 -0
- package/out/language/agentlang-module.js +42 -0
- package/out/language/agentlang-module.js.map +1 -0
- package/out/language/agentlang-validator.d.ts +15 -0
- package/out/language/agentlang-validator.d.ts.map +1 -0
- package/out/language/agentlang-validator.js +50 -0
- package/out/language/agentlang-validator.js.map +1 -0
- package/out/language/generated/ast.d.ts +491 -0
- package/out/language/generated/ast.d.ts.map +1 -0
- package/out/language/generated/ast.js +934 -0
- package/out/language/generated/ast.js.map +1 -0
- package/out/language/generated/grammar.d.ts +7 -0
- package/out/language/generated/grammar.d.ts.map +1 -0
- package/out/language/generated/grammar.js +4475 -0
- package/out/language/generated/grammar.js.map +1 -0
- package/out/language/generated/module.d.ts +14 -0
- package/out/language/generated/module.d.ts.map +1 -0
- package/out/language/generated/module.js +21 -0
- package/out/language/generated/module.js.map +1 -0
- package/out/language/main-browser.d.ts +2 -0
- package/out/language/main-browser.d.ts.map +1 -0
- package/out/language/main-browser.js +10 -0
- package/out/language/main-browser.js.map +1 -0
- package/out/language/main.cjs +36229 -0
- package/out/language/main.cjs.map +7 -0
- package/out/language/main.d.ts +2 -0
- package/out/language/main.d.ts.map +1 -0
- package/out/language/main.js +11 -0
- package/out/language/main.js.map +1 -0
- package/out/language/parser.d.ts +9 -0
- package/out/language/parser.d.ts.map +1 -0
- package/out/language/parser.js +273 -0
- package/out/language/parser.js.map +1 -0
- package/out/language/syntax.d.ts +155 -0
- package/out/language/syntax.d.ts.map +1 -0
- package/out/language/syntax.js +527 -0
- package/out/language/syntax.js.map +1 -0
- package/out/runtime/agents/common.d.ts +2 -0
- package/out/runtime/agents/common.d.ts.map +1 -0
- package/out/runtime/agents/common.js +178 -0
- package/out/runtime/agents/common.js.map +1 -0
- package/out/runtime/agents/impl/openai.d.ts +8 -0
- package/out/runtime/agents/impl/openai.d.ts.map +1 -0
- package/out/runtime/agents/impl/openai.js +15 -0
- package/out/runtime/agents/impl/openai.js.map +1 -0
- package/out/runtime/agents/provider.d.ts +21 -0
- package/out/runtime/agents/provider.d.ts.map +1 -0
- package/out/runtime/agents/provider.js +32 -0
- package/out/runtime/agents/provider.js.map +1 -0
- package/out/runtime/agents/registry.d.ts +2 -0
- package/out/runtime/agents/registry.d.ts.map +1 -0
- package/out/runtime/agents/registry.js +10 -0
- package/out/runtime/agents/registry.js.map +1 -0
- package/out/runtime/auth/cognito.d.ts +16 -0
- package/out/runtime/auth/cognito.d.ts.map +1 -0
- package/out/runtime/auth/cognito.js +186 -0
- package/out/runtime/auth/cognito.js.map +1 -0
- package/out/runtime/auth/defs.d.ts +11 -0
- package/out/runtime/auth/defs.d.ts.map +1 -0
- package/out/runtime/auth/defs.js +24 -0
- package/out/runtime/auth/defs.js.map +1 -0
- package/out/runtime/auth/interface.d.ts +22 -0
- package/out/runtime/auth/interface.d.ts.map +1 -0
- package/out/runtime/auth/interface.js +2 -0
- package/out/runtime/auth/interface.js.map +1 -0
- package/out/runtime/defs.js +24 -0
- package/out/runtime/defs.js.map +1 -0
- package/out/runtime/interpreter.d.ts +69 -0
- package/out/runtime/interpreter.d.ts.map +1 -0
- package/out/runtime/interpreter.js +1163 -0
- package/out/runtime/interpreter.js.map +1 -0
- package/out/runtime/loader.d.ts +25 -0
- package/out/runtime/loader.d.ts.map +1 -0
- package/out/runtime/loader.js +346 -0
- package/out/runtime/loader.js.map +1 -0
- package/out/runtime/logger.d.ts +2 -0
- package/out/runtime/logger.d.ts.map +1 -0
- package/out/runtime/logger.js +44 -0
- package/out/runtime/logger.js.map +1 -0
- package/out/runtime/module.d.ts +273 -0
- package/out/runtime/module.d.ts.map +1 -0
- package/out/runtime/module.js +1786 -0
- package/out/runtime/module.js.map +1 -0
- package/out/runtime/modules/ai.d.ts +26 -0
- package/out/runtime/modules/ai.d.ts.map +1 -0
- package/out/runtime/modules/ai.js +211 -0
- package/out/runtime/modules/ai.js.map +1 -0
- package/out/runtime/modules/auth.d.ts +39 -0
- package/out/runtime/modules/auth.d.ts.map +1 -0
- package/out/runtime/modules/auth.js +359 -0
- package/out/runtime/modules/auth.js.map +1 -0
- package/out/runtime/modules/core.d.ts +2 -0
- package/out/runtime/modules/core.d.ts.map +1 -0
- package/out/runtime/modules/core.js +67 -0
- package/out/runtime/modules/core.js.map +1 -0
- package/out/runtime/relgraph.d.ts +21 -0
- package/out/runtime/relgraph.d.ts.map +1 -0
- package/out/runtime/relgraph.js +156 -0
- package/out/runtime/relgraph.js.map +1 -0
- package/out/runtime/resolvers/interface.d.ts +59 -0
- package/out/runtime/resolvers/interface.d.ts.map +1 -0
- package/out/runtime/resolvers/interface.js +111 -0
- package/out/runtime/resolvers/interface.js.map +1 -0
- package/out/runtime/resolvers/registry.d.ts +8 -0
- package/out/runtime/resolvers/registry.d.ts.map +1 -0
- package/out/runtime/resolvers/registry.js +26 -0
- package/out/runtime/resolvers/registry.js.map +1 -0
- package/out/runtime/resolvers/sqldb/database.d.ts +50 -0
- package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -0
- package/out/runtime/resolvers/sqldb/database.js +618 -0
- package/out/runtime/resolvers/sqldb/database.js.map +1 -0
- package/out/runtime/resolvers/sqldb/dbutil.d.ts +18 -0
- package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -0
- package/out/runtime/resolvers/sqldb/dbutil.js +221 -0
- package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -0
- package/out/runtime/resolvers/sqldb/impl.d.ts +26 -0
- package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -0
- package/out/runtime/resolvers/sqldb/impl.js +300 -0
- package/out/runtime/resolvers/sqldb/impl.js.map +1 -0
- package/out/runtime/state.js +83 -0
- package/out/runtime/state.js.map +1 -0
- package/out/runtime/util.d.ts +43 -0
- package/out/runtime/util.d.ts.map +1 -0
- package/out/runtime/util.js +447 -0
- package/out/runtime/util.js.map +1 -0
- package/out/setupClassic.d.ts +98 -0
- package/out/setupClassic.d.ts.map +1 -0
- package/out/setupClassic.js +38 -0
- package/out/setupClassic.js.map +1 -0
- package/out/setupCommon.d.ts +2 -0
- package/out/setupCommon.d.ts.map +1 -0
- package/out/setupCommon.js +33 -0
- package/out/setupCommon.js.map +1 -0
- package/out/setupExtended.d.ts +40 -0
- package/out/setupExtended.d.ts.map +1 -0
- package/out/setupExtended.js +67 -0
- package/out/setupExtended.js.map +1 -0
- package/out/syntaxes/agentlang.monarch.d.ts +77 -0
- package/out/syntaxes/agentlang.monarch.d.ts.map +1 -0
- package/out/syntaxes/agentlang.monarch.js +31 -0
- package/out/syntaxes/agentlang.monarch.js.map +1 -0
- package/out/utils/fs/index.d.ts +14 -0
- package/out/utils/fs/index.d.ts.map +1 -0
- package/out/utils/fs/index.js +26 -0
- package/out/utils/fs/index.js.map +1 -0
- package/out/utils/fs/interfaces.d.ts +105 -0
- package/out/utils/fs/interfaces.d.ts.map +1 -0
- package/out/utils/fs/interfaces.js +5 -0
- package/out/utils/fs/interfaces.js.map +1 -0
- package/out/utils/fs/lightning-fs.d.ts +116 -0
- package/out/utils/fs/lightning-fs.d.ts.map +1 -0
- package/out/utils/fs/lightning-fs.js +243 -0
- package/out/utils/fs/lightning-fs.js.map +1 -0
- package/out/utils/fs/node-fs.d.ts +93 -0
- package/out/utils/fs/node-fs.d.ts.map +1 -0
- package/out/utils/fs/node-fs.js +169 -0
- package/out/utils/fs/node-fs.js.map +1 -0
- package/out/utils/fs-utils.d.ts +153 -0
- package/out/utils/fs-utils.d.ts.map +1 -0
- package/out/utils/fs-utils.js +271 -0
- package/out/utils/fs-utils.js.map +1 -0
- package/out/utils/runtime.d.ts +36 -0
- package/out/utils/runtime.d.ts.map +1 -0
- package/out/utils/runtime.js +39 -0
- package/out/utils/runtime.js.map +1 -0
- package/package.json +155 -0
- package/src/api/http.ts +361 -0
- package/src/cli/cli-util.ts +18 -0
- package/src/cli/main.ts +146 -0
- package/src/extension/main.ts +51 -0
- package/src/language/agentlang-module.ts +75 -0
- package/src/language/agentlang-validator.ts +60 -0
- package/src/language/agentlang.langium +178 -0
- package/src/language/generated/ast.ts +1698 -0
- package/src/language/generated/grammar.ts +4477 -0
- package/src/language/generated/module.ts +25 -0
- package/src/language/main-browser.ts +19 -0
- package/src/language/main.ts +13 -0
- package/src/language/parser.ts +329 -0
- package/src/language/syntax.ts +646 -0
- package/src/runtime/agents/common.ts +177 -0
- package/src/runtime/agents/impl/openai.ts +19 -0
- package/src/runtime/agents/provider.ts +58 -0
- package/src/runtime/agents/registry.ts +9 -0
- package/src/runtime/auth/cognito.ts +225 -0
- package/src/runtime/auth/defs.ts +33 -0
- package/src/runtime/auth/interface.ts +31 -0
- package/src/runtime/defs.ts +33 -0
- package/src/runtime/interpreter.ts +1352 -0
- package/src/runtime/loader.ts +450 -0
- package/src/runtime/logger.ts +51 -0
- package/src/runtime/module.ts +2188 -0
- package/src/runtime/modules/ai.ts +257 -0
- package/src/runtime/modules/auth.ts +489 -0
- package/src/runtime/modules/core.ts +95 -0
- package/src/runtime/relgraph.ts +195 -0
- package/src/runtime/resolvers/interface.ts +160 -0
- package/src/runtime/resolvers/registry.ts +30 -0
- package/src/runtime/resolvers/sqldb/database.ts +823 -0
- package/src/runtime/resolvers/sqldb/dbutil.ts +257 -0
- package/src/runtime/resolvers/sqldb/impl.ts +471 -0
- package/src/runtime/state.ts +87 -0
- package/src/runtime/util.ts +513 -0
- package/src/setupClassic.ts +43 -0
- package/src/setupCommon.ts +33 -0
- package/src/setupExtended.ts +79 -0
- package/src/syntaxes/agentlang.monarch.ts +31 -0
- package/src/utils/fs/index.ts +28 -0
- package/src/utils/fs/interfaces.ts +118 -0
- package/src/utils/fs/lightning-fs.ts +284 -0
- package/src/utils/fs/node-fs.ts +185 -0
- package/src/utils/fs-utils.ts +304 -0
- package/src/utils/runtime.ts +43 -0
|
@@ -0,0 +1,1786 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { isRelNodes, isLiteral, } from '../language/generated/ast.js';
|
|
3
|
+
import { Path, splitFqName, isString, isNumber, isBoolean, isFqName, makeFqName, DefaultModuleName, joinStatements, isMinusZero, now, findMetaSchema, findAllPrePostTriggerSchema, asCrudType, isPath, findUqCompositeAttributes, escapeFqName, } from './util.js';
|
|
4
|
+
import { parseStatement } from '../language/parser.js';
|
|
5
|
+
import { AdminSession } from './auth/defs.js';
|
|
6
|
+
import { DefaultIdAttributeName, PathAttributeName } from './defs.js';
|
|
7
|
+
export class ModuleEntry {
|
|
8
|
+
constructor(name, moduleName) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.moduleName = moduleName;
|
|
11
|
+
}
|
|
12
|
+
getFqName() {
|
|
13
|
+
return makeFqName(this.moduleName, this.name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function normalizePropertyNames(props) {
|
|
17
|
+
// Convert iterator to array for compatibility with different Node.js versions
|
|
18
|
+
const normKs = Array.from(props.keys()).filter((k) => {
|
|
19
|
+
return k.charAt(0) === '@';
|
|
20
|
+
});
|
|
21
|
+
normKs.forEach((k) => {
|
|
22
|
+
const v = props.get(k);
|
|
23
|
+
props.delete(k);
|
|
24
|
+
props.set(k.substring(1), v);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const SystemAttributeProperty = 'system-attribute';
|
|
28
|
+
const SystemDefinedEvent = 'system-event';
|
|
29
|
+
function setAsSystemAttribute(attrSpec) {
|
|
30
|
+
const props = attrSpec.properties ? attrSpec.properties : new Map();
|
|
31
|
+
props.set(SystemAttributeProperty, true);
|
|
32
|
+
attrSpec.properties = props;
|
|
33
|
+
}
|
|
34
|
+
function isSystemAttribute(attrSpec) {
|
|
35
|
+
if (attrSpec.properties) {
|
|
36
|
+
return attrSpec.properties.get(SystemAttributeProperty) == true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function recordSchemaToString(scm) {
|
|
41
|
+
const ss = [];
|
|
42
|
+
scm.forEach((attrSpec, n) => {
|
|
43
|
+
if (!isSystemAttribute(attrSpec)) {
|
|
44
|
+
ss.push(` ${n} ${attributeSpecToString(attrSpec)}`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return `{ \n${ss.join(',\n')} \n}`;
|
|
48
|
+
}
|
|
49
|
+
function attributeSpecToString(attrSpec) {
|
|
50
|
+
let s = `${attrSpec.type}`;
|
|
51
|
+
if (attrSpec.properties) {
|
|
52
|
+
const ps = [];
|
|
53
|
+
attrSpec.properties.forEach((v, k) => {
|
|
54
|
+
if (v == true)
|
|
55
|
+
ps.push(`@${k}`);
|
|
56
|
+
else
|
|
57
|
+
ps.push(`@${k}${v}`);
|
|
58
|
+
});
|
|
59
|
+
s = s.concat(ps.join(' '));
|
|
60
|
+
}
|
|
61
|
+
return s;
|
|
62
|
+
}
|
|
63
|
+
export function newRecordSchema() {
|
|
64
|
+
return new Map();
|
|
65
|
+
}
|
|
66
|
+
export function newMeta() {
|
|
67
|
+
return new Map();
|
|
68
|
+
}
|
|
69
|
+
export var RecordType;
|
|
70
|
+
(function (RecordType) {
|
|
71
|
+
RecordType[RecordType["RECORD"] = 0] = "RECORD";
|
|
72
|
+
RecordType[RecordType["ENTITY"] = 1] = "ENTITY";
|
|
73
|
+
RecordType[RecordType["EVENT"] = 2] = "EVENT";
|
|
74
|
+
RecordType[RecordType["RELATIONSHIP"] = 3] = "RELATIONSHIP";
|
|
75
|
+
})(RecordType || (RecordType = {}));
|
|
76
|
+
function normalizeMetaValue(metaValue) {
|
|
77
|
+
if (!isLiteral(metaValue)) {
|
|
78
|
+
throw new Error(`Invalid entry ${metaValue} in meta specification - expected a literal`);
|
|
79
|
+
}
|
|
80
|
+
const v = metaValue;
|
|
81
|
+
if (v.array) {
|
|
82
|
+
return v.array.vals.map((value) => {
|
|
83
|
+
return normalizeMetaValue(value.pattern.literal);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else if (v.bool != undefined) {
|
|
87
|
+
return v.bool;
|
|
88
|
+
}
|
|
89
|
+
else if (v.id) {
|
|
90
|
+
return v.id;
|
|
91
|
+
}
|
|
92
|
+
else if (v.map) {
|
|
93
|
+
const result = new Map();
|
|
94
|
+
v.map.entries.forEach((value) => {
|
|
95
|
+
result.set(value.key, normalizeMetaValue(value.value));
|
|
96
|
+
});
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
else if (v.ref) {
|
|
100
|
+
return v.ref;
|
|
101
|
+
}
|
|
102
|
+
else if (v.num) {
|
|
103
|
+
return v.num;
|
|
104
|
+
}
|
|
105
|
+
else if (v.str) {
|
|
106
|
+
return v.str;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw new Error(`Invalid value ${metaValue} passed to meta specification`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function asTriggerInfo(te) {
|
|
113
|
+
return {
|
|
114
|
+
eventName: te.event,
|
|
115
|
+
async: te.async ? true : false,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export class Record extends ModuleEntry {
|
|
119
|
+
constructor(name, moduleName, scm, parentEntryName) {
|
|
120
|
+
super(name, moduleName);
|
|
121
|
+
this.type = RecordType.RECORD;
|
|
122
|
+
this.parentEntryName = parentEntryName;
|
|
123
|
+
this.schema = parentEntryName
|
|
124
|
+
? cloneParentSchema(parentEntryName, moduleName)
|
|
125
|
+
: newRecordSchema();
|
|
126
|
+
const attributes = scm ? scm.attributes : undefined;
|
|
127
|
+
if (attributes != undefined) {
|
|
128
|
+
attributes.forEach((a) => {
|
|
129
|
+
var _a, _b;
|
|
130
|
+
verifyAttribute(a);
|
|
131
|
+
let props = asPropertiesMap(a.properties);
|
|
132
|
+
const isArrayType = a.arrayType ? true : false;
|
|
133
|
+
let t = isArrayType ? a.arrayType : a.type;
|
|
134
|
+
if (a.refSpec) {
|
|
135
|
+
let fp = a.refSpec.ref;
|
|
136
|
+
const rp = splitFqName(fp);
|
|
137
|
+
if (!rp.hasModule()) {
|
|
138
|
+
rp.setModuleName(this.moduleName);
|
|
139
|
+
fp = rp.asFqName();
|
|
140
|
+
}
|
|
141
|
+
if (props == undefined) {
|
|
142
|
+
props = new Map();
|
|
143
|
+
}
|
|
144
|
+
props.set('ref', escapeFqName(fp));
|
|
145
|
+
t = 'Path';
|
|
146
|
+
}
|
|
147
|
+
const enumValues = (_a = a.enumSpec) === null || _a === void 0 ? void 0 : _a.values;
|
|
148
|
+
const oneOfRef = (_b = a.oneOfSpec) === null || _b === void 0 ? void 0 : _b.ref;
|
|
149
|
+
if (!t) {
|
|
150
|
+
if (enumValues || oneOfRef) {
|
|
151
|
+
t = 'String';
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
throw new Error(`Attribute ${a.name} requires a type`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (a.expr) {
|
|
158
|
+
if (props == undefined) {
|
|
159
|
+
props = new Map();
|
|
160
|
+
}
|
|
161
|
+
props.set('expr', a.expr).set('optional', true);
|
|
162
|
+
}
|
|
163
|
+
const isObjectType = t == 'Map' || !isBuiltInType(t);
|
|
164
|
+
if (isArrayType || isObjectType || enumValues || oneOfRef) {
|
|
165
|
+
if (props == undefined) {
|
|
166
|
+
props = new Map();
|
|
167
|
+
}
|
|
168
|
+
if (isArrayType)
|
|
169
|
+
props.set('array', true);
|
|
170
|
+
if (isObjectType)
|
|
171
|
+
props.set('object', true);
|
|
172
|
+
if (enumValues)
|
|
173
|
+
props.set('one-of', new Set(enumValues));
|
|
174
|
+
if (oneOfRef) {
|
|
175
|
+
props.set('one-of-ref', oneOfRef);
|
|
176
|
+
this.addOneOfRefAttribute(a.name);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
this.schema.set(a.name, { type: t, properties: props });
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const meta = findMetaSchema(scm);
|
|
183
|
+
if (meta) {
|
|
184
|
+
meta.spec.entries.forEach((entry) => {
|
|
185
|
+
if (entry.key.str)
|
|
186
|
+
this.addMeta(entry.key.str, normalizeMetaValue(entry.value));
|
|
187
|
+
else
|
|
188
|
+
throw new Error(`Key must be a string for meta-definition in ${this.moduleName}/${this.name}`);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
const prepostTrigs = findAllPrePostTriggerSchema(scm);
|
|
192
|
+
if (prepostTrigs) {
|
|
193
|
+
prepostTrigs.forEach((ppt) => {
|
|
194
|
+
if (ppt.after) {
|
|
195
|
+
if (this.afterTriggers == undefined) {
|
|
196
|
+
this.afterTriggers = new Map();
|
|
197
|
+
}
|
|
198
|
+
ppt.after.triggers.entries.forEach((te) => {
|
|
199
|
+
if (this.afterTriggers)
|
|
200
|
+
this.afterTriggers.set(asCrudType(te.on), asTriggerInfo(te));
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else if (ppt.before) {
|
|
204
|
+
if (this.beforeTriggers == undefined) {
|
|
205
|
+
this.beforeTriggers = new Map();
|
|
206
|
+
}
|
|
207
|
+
ppt.before.triggers.entries.forEach((te) => {
|
|
208
|
+
if (this.beforeTriggers)
|
|
209
|
+
this.beforeTriggers.set(asCrudType(te.on), asTriggerInfo(te));
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
this.compositeUqAttributes = findUqCompositeAttributes(scm);
|
|
215
|
+
}
|
|
216
|
+
addOneOfRefAttribute(s) {
|
|
217
|
+
if (this.oneOfRefAttributes == undefined) {
|
|
218
|
+
this.oneOfRefAttributes = [];
|
|
219
|
+
}
|
|
220
|
+
this.oneOfRefAttributes.push(s);
|
|
221
|
+
return this;
|
|
222
|
+
}
|
|
223
|
+
getCompositeUniqueAttributes() {
|
|
224
|
+
return this.compositeUqAttributes;
|
|
225
|
+
}
|
|
226
|
+
getPreTriggerInfo(crudType) {
|
|
227
|
+
if (this.beforeTriggers) {
|
|
228
|
+
return this.beforeTriggers.get(crudType);
|
|
229
|
+
}
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
getPostTriggerInfo(crudType) {
|
|
233
|
+
if (this.afterTriggers) {
|
|
234
|
+
return this.afterTriggers.get(crudType);
|
|
235
|
+
}
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
addMeta(k, v) {
|
|
239
|
+
if (!this.meta) {
|
|
240
|
+
this.meta = newMeta();
|
|
241
|
+
}
|
|
242
|
+
this.meta.set(k, v);
|
|
243
|
+
}
|
|
244
|
+
getMeta(k) {
|
|
245
|
+
if (this.meta) {
|
|
246
|
+
return this.meta.get(k);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
getFullTextSearchAttributes() {
|
|
253
|
+
const fts = this.getMeta('fullTextSearch');
|
|
254
|
+
if (fts) {
|
|
255
|
+
if (fts instanceof Array) {
|
|
256
|
+
return fts;
|
|
257
|
+
}
|
|
258
|
+
else if (fts == '*') {
|
|
259
|
+
return [...this.schema.keys()];
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
addAttribute(n, attrSpec) {
|
|
270
|
+
if (this.schema.has(n)) {
|
|
271
|
+
throw new Error(`Attribute named ${n} already exists in ${this.moduleName}.${this.name}`);
|
|
272
|
+
}
|
|
273
|
+
if (attrSpec.properties != undefined) {
|
|
274
|
+
normalizePropertyNames(attrSpec.properties);
|
|
275
|
+
}
|
|
276
|
+
this.schema.set(n, attrSpec);
|
|
277
|
+
return this;
|
|
278
|
+
}
|
|
279
|
+
removeAttribute(n) {
|
|
280
|
+
this.schema.delete(n);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
reorderAttributes(desiredOrder) {
|
|
284
|
+
this.schema = new Map([...this.schema].sort((a, b) => {
|
|
285
|
+
return desiredOrder.indexOf(a[0]) - desiredOrder.indexOf(b[0]);
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
addSystemAttribute(n, attrSpec) {
|
|
289
|
+
setAsSystemAttribute(attrSpec);
|
|
290
|
+
this.addAttribute(n, attrSpec);
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
findAttribute(predic) {
|
|
294
|
+
for (const k of this.schema.keys()) {
|
|
295
|
+
const attrSpec = this.schema.get(k);
|
|
296
|
+
if (attrSpec != undefined) {
|
|
297
|
+
if (predic(attrSpec))
|
|
298
|
+
return {
|
|
299
|
+
name: k,
|
|
300
|
+
spec: attrSpec,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
hasRefTo(modName, entryName) {
|
|
307
|
+
if (this.findAttribute((attrSpec) => {
|
|
308
|
+
if (attrSpec.properties != undefined) {
|
|
309
|
+
const ref = attrSpec.properties.get('ref');
|
|
310
|
+
if (ref != undefined) {
|
|
311
|
+
if (ref.getModuleName() == modName && ref.getEntryName() == entryName) {
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
}))
|
|
318
|
+
return true;
|
|
319
|
+
else
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
getIdAttributeName() {
|
|
323
|
+
const e = this.findAttribute((attrSpec) => {
|
|
324
|
+
return isIdAttribute(attrSpec);
|
|
325
|
+
});
|
|
326
|
+
if (e != undefined) {
|
|
327
|
+
return e.name;
|
|
328
|
+
}
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
toString() {
|
|
332
|
+
if (this.type == RecordType.EVENT && this.meta && this.meta.get(SystemDefinedEvent)) {
|
|
333
|
+
return '';
|
|
334
|
+
}
|
|
335
|
+
let s = `${RecordType[this.type].toLowerCase()} ${this.name}`;
|
|
336
|
+
if (this.parentEntryName) {
|
|
337
|
+
s = s.concat(` extends ${this.parentEntryName}`);
|
|
338
|
+
}
|
|
339
|
+
const scms = recordSchemaToString(this.schema);
|
|
340
|
+
return s.concat('\n', scms, '\n');
|
|
341
|
+
}
|
|
342
|
+
getUserAttributes() {
|
|
343
|
+
const recSchema = newRecordSchema();
|
|
344
|
+
this.schema.forEach((attrSpec, n) => {
|
|
345
|
+
if (!isSystemAttribute(attrSpec)) {
|
|
346
|
+
recSchema.set(n, attrSpec);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return recSchema;
|
|
350
|
+
}
|
|
351
|
+
getUserAttributeNames() {
|
|
352
|
+
return [...this.getUserAttributes().keys()];
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function fetchModuleByEntryName(entryName, suspectModuleName) {
|
|
356
|
+
if (isFqName(entryName)) {
|
|
357
|
+
const path = splitFqName(entryName);
|
|
358
|
+
entryName = path.getEntryName();
|
|
359
|
+
suspectModuleName = path.getModuleName();
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
module: fetchModule(suspectModuleName),
|
|
363
|
+
entryName: entryName,
|
|
364
|
+
moduleName: suspectModuleName,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function cloneParentSchema(parentName, currentModuleName) {
|
|
368
|
+
const fr = fetchModuleByEntryName(parentName, currentModuleName);
|
|
369
|
+
parentName = fr.entryName;
|
|
370
|
+
currentModuleName = fr.moduleName;
|
|
371
|
+
const mod = fr.module;
|
|
372
|
+
const entry = mod.getEntry(parentName);
|
|
373
|
+
const result = newRecordSchema();
|
|
374
|
+
entry.schema.forEach((attrSpec, attrName) => {
|
|
375
|
+
result.set(attrName, attrSpec);
|
|
376
|
+
});
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
function asPropertiesMap(props) {
|
|
380
|
+
if (props != undefined && props.length > 0) {
|
|
381
|
+
const result = new Map();
|
|
382
|
+
props.forEach((p) => {
|
|
383
|
+
const n = p.name.substring(1);
|
|
384
|
+
if (p.value != undefined && p.value.pairs != undefined && p.value.pairs.length > 0) {
|
|
385
|
+
if (p.value.pairs.length == 1) {
|
|
386
|
+
const kvp = p.value.pairs[0];
|
|
387
|
+
if (kvp.key == undefined) {
|
|
388
|
+
result.set(n, normalizeKvPairValue(kvp));
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
const v = new Map();
|
|
392
|
+
v.set(kvp.key, normalizeKvPairValue(kvp));
|
|
393
|
+
result.set(n, v);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
const v = new Map();
|
|
398
|
+
p.value.pairs.forEach((kvp) => {
|
|
399
|
+
let k = 'null';
|
|
400
|
+
if (kvp.key != undefined)
|
|
401
|
+
k = kvp.key;
|
|
402
|
+
v.set(k, normalizeKvPairValue(kvp));
|
|
403
|
+
});
|
|
404
|
+
result.set(n, v);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
result.set(n, true);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
return maybeProcessRefProperty(result);
|
|
412
|
+
}
|
|
413
|
+
return undefined;
|
|
414
|
+
}
|
|
415
|
+
function maybeProcessRefProperty(props) {
|
|
416
|
+
const v = props.get('ref');
|
|
417
|
+
if (v != undefined) {
|
|
418
|
+
const parts = splitFqName(v);
|
|
419
|
+
if (!parts.hasModule()) {
|
|
420
|
+
parts.setModuleName(activeModule);
|
|
421
|
+
}
|
|
422
|
+
props.set('ref', parts);
|
|
423
|
+
}
|
|
424
|
+
return props;
|
|
425
|
+
}
|
|
426
|
+
function normalizeKvPairValue(kvp) {
|
|
427
|
+
const v = kvp.value;
|
|
428
|
+
if (v == undefined)
|
|
429
|
+
return true;
|
|
430
|
+
if (v.str != undefined) {
|
|
431
|
+
return v.str;
|
|
432
|
+
}
|
|
433
|
+
else if (v.num != undefined) {
|
|
434
|
+
return v.num;
|
|
435
|
+
}
|
|
436
|
+
else if (v.bool != undefined) {
|
|
437
|
+
return v.bool;
|
|
438
|
+
}
|
|
439
|
+
else if (v.id != undefined) {
|
|
440
|
+
return v.id;
|
|
441
|
+
}
|
|
442
|
+
else if (v.ref != undefined) {
|
|
443
|
+
return v.ref;
|
|
444
|
+
}
|
|
445
|
+
else if (v.fnCall != undefined) {
|
|
446
|
+
const fncall = v.fnCall;
|
|
447
|
+
if (fncall.args.length > 0) {
|
|
448
|
+
throw new Error('Cannot allow arguments in properties function-call');
|
|
449
|
+
}
|
|
450
|
+
return fncall.name + '()';
|
|
451
|
+
}
|
|
452
|
+
else if (v.array != undefined) {
|
|
453
|
+
return v.array;
|
|
454
|
+
}
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
export const PlaceholderRecordEntry = new Record('--', DefaultModuleName);
|
|
458
|
+
export var RbacPermissionFlag;
|
|
459
|
+
(function (RbacPermissionFlag) {
|
|
460
|
+
RbacPermissionFlag[RbacPermissionFlag["CREATE"] = 0] = "CREATE";
|
|
461
|
+
RbacPermissionFlag[RbacPermissionFlag["READ"] = 1] = "READ";
|
|
462
|
+
RbacPermissionFlag[RbacPermissionFlag["UPDATE"] = 2] = "UPDATE";
|
|
463
|
+
RbacPermissionFlag[RbacPermissionFlag["DELETE"] = 3] = "DELETE";
|
|
464
|
+
})(RbacPermissionFlag || (RbacPermissionFlag = {}));
|
|
465
|
+
export class RbacSpecification {
|
|
466
|
+
constructor() {
|
|
467
|
+
this.resource = '';
|
|
468
|
+
this.roles = RbacSpecification.EmptyRoles;
|
|
469
|
+
this.permissions = new Set();
|
|
470
|
+
}
|
|
471
|
+
setResource(s) {
|
|
472
|
+
this.resource = s;
|
|
473
|
+
return this;
|
|
474
|
+
}
|
|
475
|
+
hasResource() {
|
|
476
|
+
return this.resource.length > 0;
|
|
477
|
+
}
|
|
478
|
+
setPermissions(perms) {
|
|
479
|
+
perms.forEach((v) => {
|
|
480
|
+
const idx = v.toUpperCase();
|
|
481
|
+
const a = RbacPermissionFlag[idx];
|
|
482
|
+
if (a == undefined) {
|
|
483
|
+
throw new Error(`Not a valid RBAC permission - ${v}`);
|
|
484
|
+
}
|
|
485
|
+
this.permissions.add(a);
|
|
486
|
+
});
|
|
487
|
+
return this;
|
|
488
|
+
}
|
|
489
|
+
hasPermissions() {
|
|
490
|
+
return this.permissions.size > 0;
|
|
491
|
+
}
|
|
492
|
+
hasCreatePermission() {
|
|
493
|
+
return this.permissions.has(RbacPermissionFlag.CREATE);
|
|
494
|
+
}
|
|
495
|
+
hasReadPermission() {
|
|
496
|
+
return this.permissions.has(RbacPermissionFlag.READ);
|
|
497
|
+
}
|
|
498
|
+
hasUpdatePermission() {
|
|
499
|
+
return this.permissions.has(RbacPermissionFlag.UPDATE);
|
|
500
|
+
}
|
|
501
|
+
hasDeletePermission() {
|
|
502
|
+
return this.permissions.has(RbacPermissionFlag.DELETE);
|
|
503
|
+
}
|
|
504
|
+
setRoles(roles) {
|
|
505
|
+
if (this.expression) {
|
|
506
|
+
throw new Error('Cannot set roles while `where` expression is set');
|
|
507
|
+
}
|
|
508
|
+
this.roles = new Set();
|
|
509
|
+
roles.forEach((r) => {
|
|
510
|
+
this.roles.add(r);
|
|
511
|
+
});
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
setExpression(lhs, rhs) {
|
|
515
|
+
if (this.roles != RbacSpecification.EmptyRoles) {
|
|
516
|
+
throw new Error('Cannot set `where` expression along with roles');
|
|
517
|
+
}
|
|
518
|
+
this.expression = {
|
|
519
|
+
lhs: lhs,
|
|
520
|
+
rhs: rhs,
|
|
521
|
+
};
|
|
522
|
+
return this;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
RbacSpecification.EmptyRoles = new Set();
|
|
526
|
+
export class Entity extends Record {
|
|
527
|
+
constructor(name, moduleName, scm, parentEntryName) {
|
|
528
|
+
super(name, moduleName, scm, parentEntryName);
|
|
529
|
+
this.type = RecordType.ENTITY;
|
|
530
|
+
const idattr = this.getIdAttributeName();
|
|
531
|
+
if (idattr == undefined) {
|
|
532
|
+
const attrSpec = {
|
|
533
|
+
type: 'UUID',
|
|
534
|
+
properties: new Map().set('default', 'uuid()').set('id', true),
|
|
535
|
+
};
|
|
536
|
+
this.schema.set(DefaultIdAttributeName, attrSpec);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
setRbacSpecifications(rbac) {
|
|
540
|
+
this.rbac = rbac;
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
export class Event extends Record {
|
|
545
|
+
constructor() {
|
|
546
|
+
super(...arguments);
|
|
547
|
+
this.type = RecordType.EVENT;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
var RelType;
|
|
551
|
+
(function (RelType) {
|
|
552
|
+
RelType[RelType["CONTAINS"] = 0] = "CONTAINS";
|
|
553
|
+
RelType[RelType["BETWEEN"] = 1] = "BETWEEN";
|
|
554
|
+
})(RelType || (RelType = {}));
|
|
555
|
+
export function newRelNodeEntry(nodeFqName, alias) {
|
|
556
|
+
const p = splitFqName(nodeFqName);
|
|
557
|
+
return {
|
|
558
|
+
path: p,
|
|
559
|
+
alias: alias ? alias : p.getEntryName(),
|
|
560
|
+
origName: nodeFqName,
|
|
561
|
+
origAlias: alias,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function relNodeEntryToString(node) {
|
|
565
|
+
let n = `${node.origName}`;
|
|
566
|
+
if (node.origAlias) {
|
|
567
|
+
n = n.concat(` as ${node.origAlias}`);
|
|
568
|
+
}
|
|
569
|
+
return n;
|
|
570
|
+
}
|
|
571
|
+
function asRelNodeEntry(n) {
|
|
572
|
+
const path = splitFqName(n.name);
|
|
573
|
+
let modName = activeModule;
|
|
574
|
+
const entryName = path.getEntryName();
|
|
575
|
+
if (path.hasModule()) {
|
|
576
|
+
modName = path.getModuleName();
|
|
577
|
+
}
|
|
578
|
+
let alias = entryName;
|
|
579
|
+
if (n.alias != undefined) {
|
|
580
|
+
alias = n.alias;
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
path: new Path(modName, entryName),
|
|
584
|
+
alias: alias,
|
|
585
|
+
origName: n.name,
|
|
586
|
+
origAlias: n.alias,
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
export class Relationship extends Record {
|
|
590
|
+
constructor(name, typ, node1, node2, moduleName, scm, props) {
|
|
591
|
+
super(name, moduleName, scm);
|
|
592
|
+
this.type = RecordType.RELATIONSHIP;
|
|
593
|
+
this.relType = RelType.CONTAINS;
|
|
594
|
+
if (typ == 'between')
|
|
595
|
+
this.relType = RelType.BETWEEN;
|
|
596
|
+
this.node1 = node1;
|
|
597
|
+
this.node2 = node2;
|
|
598
|
+
this.properties = props;
|
|
599
|
+
this.updateSchemaWithNodeAttributes();
|
|
600
|
+
}
|
|
601
|
+
updateSchemaWithNodeAttributes() {
|
|
602
|
+
const attrSpec1 = {
|
|
603
|
+
type: 'string',
|
|
604
|
+
};
|
|
605
|
+
this.addSystemAttribute(this.node1.alias, attrSpec1);
|
|
606
|
+
const attrSpec2 = {
|
|
607
|
+
type: 'string',
|
|
608
|
+
};
|
|
609
|
+
this.addSystemAttribute(this.node2.alias, attrSpec2);
|
|
610
|
+
if (this.relType == RelType.BETWEEN && this.isOneToMany()) {
|
|
611
|
+
const attrSpec3 = {
|
|
612
|
+
type: 'string',
|
|
613
|
+
properties: new Map().set('unique', true),
|
|
614
|
+
};
|
|
615
|
+
this.addSystemAttribute(this.joinNodesAttributeName(), attrSpec3);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
joinNodesAttributeName() {
|
|
619
|
+
return this.node1.alias + '_' + this.node2.alias;
|
|
620
|
+
}
|
|
621
|
+
setBetweenRef(inst, refPath, isQuery = false) {
|
|
622
|
+
const refAttrName = `__${this.node1.alias.toLowerCase()}`;
|
|
623
|
+
if (isQuery) {
|
|
624
|
+
inst.addQuery(refAttrName, '=', refPath);
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
inst.attributes.set(refAttrName, refPath);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
isContains() {
|
|
631
|
+
return this.relType == RelType.CONTAINS;
|
|
632
|
+
}
|
|
633
|
+
isBetween() {
|
|
634
|
+
return this.relType == RelType.BETWEEN;
|
|
635
|
+
}
|
|
636
|
+
parentNode() {
|
|
637
|
+
return this.node1;
|
|
638
|
+
}
|
|
639
|
+
childNode() {
|
|
640
|
+
return this.node2;
|
|
641
|
+
}
|
|
642
|
+
hasBooleanFlagSet(flag) {
|
|
643
|
+
if (this.properties != undefined) {
|
|
644
|
+
return this.properties.get(flag) == true;
|
|
645
|
+
}
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
isOneToOne() {
|
|
649
|
+
return this.isBetween() && this.hasBooleanFlagSet('one_one');
|
|
650
|
+
}
|
|
651
|
+
isOneToMany() {
|
|
652
|
+
return this.isBetween() && this.hasBooleanFlagSet('one_many');
|
|
653
|
+
}
|
|
654
|
+
isManyToMany() {
|
|
655
|
+
if (this.isBetween()) {
|
|
656
|
+
return (this.hasBooleanFlagSet('many_many') ||
|
|
657
|
+
(!this.hasBooleanFlagSet('one_one') && !this.hasBooleanFlagSet('one_many')));
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
isFirstNode(inst) {
|
|
664
|
+
return this.isFirstNodeName(inst.getFqName());
|
|
665
|
+
}
|
|
666
|
+
getAliasFor(inst) {
|
|
667
|
+
return this.getAliasForName(inst.getFqName());
|
|
668
|
+
}
|
|
669
|
+
getInverseAliasFor(inst) {
|
|
670
|
+
return this.getInverseAliasForName(inst.getFqName());
|
|
671
|
+
}
|
|
672
|
+
isFirstNodeName(fqName) {
|
|
673
|
+
return fqName == this.node1.path.asFqName();
|
|
674
|
+
}
|
|
675
|
+
getAliasForName(fqName) {
|
|
676
|
+
if (this.isFirstNodeName(fqName)) {
|
|
677
|
+
return this.node1.alias;
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
return this.node2.alias;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
getInverseAliasForName(fqName) {
|
|
684
|
+
if (this.isFirstNodeName(fqName)) {
|
|
685
|
+
return this.node2.alias;
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
return this.node1.alias;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
isParent(inst) {
|
|
692
|
+
return inst.getFqName() == this.node1.path.asFqName();
|
|
693
|
+
}
|
|
694
|
+
getParentFqName() {
|
|
695
|
+
return this.node1.path.asFqName();
|
|
696
|
+
}
|
|
697
|
+
getChildFqName() {
|
|
698
|
+
return this.node2.path.asFqName();
|
|
699
|
+
}
|
|
700
|
+
toString() {
|
|
701
|
+
const n1 = relNodeEntryToString(this.node1);
|
|
702
|
+
const n2 = relNodeEntryToString(this.node2);
|
|
703
|
+
let s = `relationship ${this.name} ${RelType[this.relType].toLowerCase()} (${n1}, ${n2})`;
|
|
704
|
+
if (this.getUserAttributes().size > 0) {
|
|
705
|
+
const attrs = [];
|
|
706
|
+
this.getUserAttributes().forEach((attrSpec, n) => {
|
|
707
|
+
attrs.push(`${n} ${attributeSpecToString(attrSpec)}`);
|
|
708
|
+
});
|
|
709
|
+
s = s.concat(`{\n ${attrs.join(',\n')} }`);
|
|
710
|
+
}
|
|
711
|
+
return s.concat('\n');
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
export class Workflow extends ModuleEntry {
|
|
715
|
+
constructor(name, patterns, moduleName) {
|
|
716
|
+
super(name, moduleName);
|
|
717
|
+
this.statements = patterns;
|
|
718
|
+
}
|
|
719
|
+
async addStatement(stmtCode) {
|
|
720
|
+
const result = await parseStatement(stmtCode);
|
|
721
|
+
this.statements.push(result);
|
|
722
|
+
return this;
|
|
723
|
+
}
|
|
724
|
+
setStatementAtHelper(statements, newStmt, index) {
|
|
725
|
+
let stmt = statements[index[0]];
|
|
726
|
+
const isFe = stmt.pattern.forEach;
|
|
727
|
+
const isIf = stmt.pattern.if;
|
|
728
|
+
if (isFe || isIf) {
|
|
729
|
+
for (let i = 1; i < index.length; ++i) {
|
|
730
|
+
const found = i == index.length - 1;
|
|
731
|
+
let idx = index[i];
|
|
732
|
+
if (stmt.pattern.forEach) {
|
|
733
|
+
if (found) {
|
|
734
|
+
if (!newStmt) {
|
|
735
|
+
stmt.pattern.forEach.statements.splice(idx, 1);
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
stmt.pattern.forEach.statements[idx] = newStmt;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
else
|
|
742
|
+
stmt = stmt.pattern.forEach.statements[idx];
|
|
743
|
+
}
|
|
744
|
+
else if (stmt.pattern.if) {
|
|
745
|
+
if (idx < 0 || isMinusZero(idx)) {
|
|
746
|
+
if (stmt.pattern.if.else) {
|
|
747
|
+
idx *= -1;
|
|
748
|
+
if (found) {
|
|
749
|
+
if (!newStmt) {
|
|
750
|
+
stmt.pattern.if.else.statements.splice(idx, 1);
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
stmt.pattern.if.else.statements[idx] = newStmt;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
else
|
|
757
|
+
stmt = stmt.pattern.if.else.statements[idx];
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
throw new Error('No else part in if');
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
if (found) {
|
|
765
|
+
if (!newStmt) {
|
|
766
|
+
stmt.pattern.if.statements.splice(idx, 1);
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
stmt.pattern.if.statements[idx] = newStmt;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
else
|
|
773
|
+
stmt = stmt.pattern.if.statements[idx];
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
throw new Error('Cannot dig further into statements');
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return this;
|
|
782
|
+
}
|
|
783
|
+
async setStatementAt(stmtCode, index) {
|
|
784
|
+
const result = await parseStatement(stmtCode);
|
|
785
|
+
if (index instanceof Array) {
|
|
786
|
+
if (index.length == 1) {
|
|
787
|
+
this.statements[index[0]] = result;
|
|
788
|
+
return this;
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
return this.setStatementAtHelper(this.statements, result, index);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
this.statements[index] = result;
|
|
796
|
+
}
|
|
797
|
+
return this;
|
|
798
|
+
}
|
|
799
|
+
removeStatementAt(index) {
|
|
800
|
+
if (index instanceof Array) {
|
|
801
|
+
if (index.length == 1) {
|
|
802
|
+
this.statements.splice(index[0], 1);
|
|
803
|
+
return this;
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
return this.setStatementAtHelper(this.statements, undefined, index);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
810
|
+
this.statements.splice(index, 1);
|
|
811
|
+
}
|
|
812
|
+
return this;
|
|
813
|
+
}
|
|
814
|
+
statementsToStringsHelper(statements) {
|
|
815
|
+
const ss = [];
|
|
816
|
+
statements.forEach((stmt) => {
|
|
817
|
+
var _a, _b;
|
|
818
|
+
if (stmt.pattern.forEach) {
|
|
819
|
+
ss.push(` for ${stmt.pattern.forEach.var} in ${(_a = stmt.pattern.forEach.src.$cstNode) === null || _a === void 0 ? void 0 : _a.text} {
|
|
820
|
+
${joinStatements(this.statementsToStringsHelper(stmt.pattern.forEach.statements))}
|
|
821
|
+
}`);
|
|
822
|
+
}
|
|
823
|
+
else if (stmt.pattern.if) {
|
|
824
|
+
let s = ` if (${(_b = stmt.pattern.if.cond.$cstNode) === null || _b === void 0 ? void 0 : _b.text}) {
|
|
825
|
+
${joinStatements(this.statementsToStringsHelper(stmt.pattern.if.statements))}
|
|
826
|
+
}`;
|
|
827
|
+
if (stmt.pattern.if.else) {
|
|
828
|
+
s = s.concat(` else {
|
|
829
|
+
${joinStatements(this.statementsToStringsHelper(stmt.pattern.if.else.statements))}
|
|
830
|
+
}`);
|
|
831
|
+
}
|
|
832
|
+
ss.push(s);
|
|
833
|
+
}
|
|
834
|
+
else if (stmt.$cstNode) {
|
|
835
|
+
ss.push(` ${stmt.$cstNode.text.trimStart()}`);
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
return ss;
|
|
839
|
+
}
|
|
840
|
+
statementsToStrings() {
|
|
841
|
+
return this.statementsToStringsHelper(this.statements);
|
|
842
|
+
}
|
|
843
|
+
toString() {
|
|
844
|
+
let s = `workflow ${normalizeWorkflowName(this.name)} {\n`;
|
|
845
|
+
const ss = this.statementsToStringsHelper(this.statements);
|
|
846
|
+
s = s.concat(joinStatements(ss));
|
|
847
|
+
return s.concat('\n}');
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
const EmptyWorkflow = new Workflow('', [], DefaultModuleName);
|
|
851
|
+
export function isEmptyWorkflow(wf) {
|
|
852
|
+
return wf == EmptyWorkflow;
|
|
853
|
+
}
|
|
854
|
+
export class Module {
|
|
855
|
+
constructor(name) {
|
|
856
|
+
this.name = name;
|
|
857
|
+
this.entries = new Array();
|
|
858
|
+
this.entriesByTypeCache = null;
|
|
859
|
+
}
|
|
860
|
+
addEntry(entry) {
|
|
861
|
+
this.entries.push(entry);
|
|
862
|
+
if (this.entriesByTypeCache != null)
|
|
863
|
+
this.entriesByTypeCache = null;
|
|
864
|
+
return entry;
|
|
865
|
+
}
|
|
866
|
+
getEntryIndex(entryName) {
|
|
867
|
+
return this.entries.findIndex((v) => {
|
|
868
|
+
return v.name == entryName;
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
hasEntry(entryName) {
|
|
872
|
+
return this.getEntryIndex(entryName) >= 0;
|
|
873
|
+
}
|
|
874
|
+
getEntry(entryName) {
|
|
875
|
+
const idx = this.getEntryIndex(entryName);
|
|
876
|
+
if (idx < 0)
|
|
877
|
+
throw new Error(`Entry ${entryName} not found in module ${this.name}`);
|
|
878
|
+
return this.entries[idx];
|
|
879
|
+
}
|
|
880
|
+
getRecord(recordName) {
|
|
881
|
+
const e = this.getEntry(recordName);
|
|
882
|
+
if (e instanceof Record) {
|
|
883
|
+
return e;
|
|
884
|
+
}
|
|
885
|
+
throw new Error(`${recordName} is not a record in module ${this.name}`);
|
|
886
|
+
}
|
|
887
|
+
removeEntry(entryName) {
|
|
888
|
+
const idx = this.getEntryIndex(entryName);
|
|
889
|
+
if (idx >= 0) {
|
|
890
|
+
this.entries.splice(idx, 1);
|
|
891
|
+
if (this.entriesByTypeCache != null)
|
|
892
|
+
this.entriesByTypeCache = null;
|
|
893
|
+
return true;
|
|
894
|
+
}
|
|
895
|
+
return false;
|
|
896
|
+
}
|
|
897
|
+
getEntriesOfType(t) {
|
|
898
|
+
var _a;
|
|
899
|
+
if (this.entriesByTypeCache != null && this.entriesByTypeCache.has(t)) {
|
|
900
|
+
const result = this.entriesByTypeCache.get(t);
|
|
901
|
+
if (result == undefined)
|
|
902
|
+
return new Array();
|
|
903
|
+
return result;
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
const result = this.entries.filter((v) => {
|
|
907
|
+
const r = v;
|
|
908
|
+
return r.type == t;
|
|
909
|
+
});
|
|
910
|
+
if (this.entriesByTypeCache != null)
|
|
911
|
+
this.entriesByTypeCache = new Map();
|
|
912
|
+
(_a = this.entriesByTypeCache) === null || _a === void 0 ? void 0 : _a.set(t, result);
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
getEntityEntries() {
|
|
917
|
+
return this.getEntriesOfType(RecordType.ENTITY);
|
|
918
|
+
}
|
|
919
|
+
getEventEntries() {
|
|
920
|
+
return this.getEntriesOfType(RecordType.EVENT);
|
|
921
|
+
}
|
|
922
|
+
getRecordEntries() {
|
|
923
|
+
return this.getEntriesOfType(RecordType.RECORD);
|
|
924
|
+
}
|
|
925
|
+
getRelationshipEntries() {
|
|
926
|
+
return this.getEntriesOfType(RecordType.RELATIONSHIP);
|
|
927
|
+
}
|
|
928
|
+
getRelationshipEntriesOfType(t) {
|
|
929
|
+
const rels = this.getRelationshipEntries();
|
|
930
|
+
return rels.filter((e) => {
|
|
931
|
+
return e.relType == t;
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
getBetweenRelationshipEntries() {
|
|
935
|
+
return this.getRelationshipEntriesOfType(RelType.BETWEEN);
|
|
936
|
+
}
|
|
937
|
+
getContainsRelationshipEntries() {
|
|
938
|
+
return this.getRelationshipEntriesOfType(RelType.CONTAINS);
|
|
939
|
+
}
|
|
940
|
+
getBetweenRelationshipEntriesThatNeedStore() {
|
|
941
|
+
return this.getBetweenRelationshipEntries().filter((re) => {
|
|
942
|
+
return re.isManyToMany() || re.isOneToMany();
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
getWorkflowForEvent(eventName) {
|
|
946
|
+
return this.getEntry(asWorkflowName(eventName));
|
|
947
|
+
}
|
|
948
|
+
isEntryOfType(t, name) {
|
|
949
|
+
const entry = this.getEntriesOfType(t).find((v) => {
|
|
950
|
+
const r = v;
|
|
951
|
+
return r.name == name;
|
|
952
|
+
});
|
|
953
|
+
return entry != undefined;
|
|
954
|
+
}
|
|
955
|
+
isEntity(name) {
|
|
956
|
+
return this.isEntryOfType(RecordType.ENTITY, name);
|
|
957
|
+
}
|
|
958
|
+
isEvent(name) {
|
|
959
|
+
return this.isEntryOfType(RecordType.EVENT, name);
|
|
960
|
+
}
|
|
961
|
+
isRecord(name) {
|
|
962
|
+
return this.isEntryOfType(RecordType.RECORD, name);
|
|
963
|
+
}
|
|
964
|
+
isRelationship(name) {
|
|
965
|
+
return this.isEntryOfType(RecordType.RELATIONSHIP, name);
|
|
966
|
+
}
|
|
967
|
+
getEntityNames() {
|
|
968
|
+
const names = [];
|
|
969
|
+
this.getEntityEntries().forEach((me) => {
|
|
970
|
+
names.push(me.name);
|
|
971
|
+
});
|
|
972
|
+
return names;
|
|
973
|
+
}
|
|
974
|
+
getEventNames() {
|
|
975
|
+
const names = [];
|
|
976
|
+
this.getEventEntries().forEach((me) => {
|
|
977
|
+
names.push(me.name);
|
|
978
|
+
});
|
|
979
|
+
return names;
|
|
980
|
+
}
|
|
981
|
+
getRecordNames() {
|
|
982
|
+
const names = [];
|
|
983
|
+
this.getRecordEntries().forEach((me) => {
|
|
984
|
+
names.push(me.name);
|
|
985
|
+
});
|
|
986
|
+
return names;
|
|
987
|
+
}
|
|
988
|
+
getRelationshipNames() {
|
|
989
|
+
const names = [];
|
|
990
|
+
this.getRelationshipEntries().forEach((me) => {
|
|
991
|
+
names.push(me.name);
|
|
992
|
+
});
|
|
993
|
+
return names;
|
|
994
|
+
}
|
|
995
|
+
isContainsRelationship(entryName) {
|
|
996
|
+
if (this.hasEntry(entryName)) {
|
|
997
|
+
const entry = this.getEntry(entryName);
|
|
998
|
+
if (entry instanceof Relationship)
|
|
999
|
+
return entry.isContains();
|
|
1000
|
+
}
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
isBetweenRelationship(entryName) {
|
|
1004
|
+
if (this.hasEntry(entryName)) {
|
|
1005
|
+
const entry = this.getEntry(entryName);
|
|
1006
|
+
if (entry instanceof Relationship)
|
|
1007
|
+
return entry.isBetween();
|
|
1008
|
+
}
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
toString() {
|
|
1012
|
+
const ss = [];
|
|
1013
|
+
this.entries.forEach((me) => {
|
|
1014
|
+
ss.push(me.toString());
|
|
1015
|
+
});
|
|
1016
|
+
return `module ${this.name}\n\n${ss.join('\n')}`;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
const moduleDb = new Map();
|
|
1020
|
+
let activeModule = '';
|
|
1021
|
+
export function getActiveModuleName() {
|
|
1022
|
+
return activeModule;
|
|
1023
|
+
}
|
|
1024
|
+
export function addModule(name) {
|
|
1025
|
+
const mod = new Module(name);
|
|
1026
|
+
moduleDb.set(name, mod);
|
|
1027
|
+
activeModule = name;
|
|
1028
|
+
return mod;
|
|
1029
|
+
}
|
|
1030
|
+
export function removeModule(name) {
|
|
1031
|
+
if (moduleDb.has(name)) {
|
|
1032
|
+
moduleDb.delete(name);
|
|
1033
|
+
return true;
|
|
1034
|
+
}
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
addModule(DefaultModuleName);
|
|
1038
|
+
addRecord('env', DefaultModuleName);
|
|
1039
|
+
export function getModuleNames() {
|
|
1040
|
+
const ks = moduleDb.keys();
|
|
1041
|
+
return Array.from(ks);
|
|
1042
|
+
}
|
|
1043
|
+
export function getUserModuleNames() {
|
|
1044
|
+
const result = new Array();
|
|
1045
|
+
Array.from(moduleDb.keys()).forEach((n) => {
|
|
1046
|
+
if (n != DefaultModuleName) {
|
|
1047
|
+
result.push(n);
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
return result;
|
|
1051
|
+
}
|
|
1052
|
+
export function isModule(name) {
|
|
1053
|
+
return moduleDb.has(name);
|
|
1054
|
+
}
|
|
1055
|
+
export function fetchModule(moduleName) {
|
|
1056
|
+
const module = moduleDb.get(moduleName);
|
|
1057
|
+
if (module == undefined) {
|
|
1058
|
+
throw new Error(`Module not found - ${moduleName}`);
|
|
1059
|
+
}
|
|
1060
|
+
return module;
|
|
1061
|
+
}
|
|
1062
|
+
export function allModuleNames() {
|
|
1063
|
+
return [...moduleDb.keys()];
|
|
1064
|
+
}
|
|
1065
|
+
export function fetchModuleEntry(entryName, moduleName) {
|
|
1066
|
+
const module = fetchModule(moduleName);
|
|
1067
|
+
return module.getEntry(entryName);
|
|
1068
|
+
}
|
|
1069
|
+
const builtInChecks = new Map([
|
|
1070
|
+
['String', isString],
|
|
1071
|
+
['Int', Number.isSafeInteger],
|
|
1072
|
+
['Number', isNumber],
|
|
1073
|
+
['Email', isString],
|
|
1074
|
+
['Date', isString],
|
|
1075
|
+
['Time', isString],
|
|
1076
|
+
['DateTime', isString],
|
|
1077
|
+
['Boolean', isBoolean],
|
|
1078
|
+
['UUID', isString],
|
|
1079
|
+
['URL', isString],
|
|
1080
|
+
['Path', isPath],
|
|
1081
|
+
[
|
|
1082
|
+
'Map',
|
|
1083
|
+
(obj) => {
|
|
1084
|
+
return obj instanceof Object || obj instanceof Map;
|
|
1085
|
+
},
|
|
1086
|
+
],
|
|
1087
|
+
[
|
|
1088
|
+
'Any',
|
|
1089
|
+
(_) => {
|
|
1090
|
+
return true;
|
|
1091
|
+
},
|
|
1092
|
+
],
|
|
1093
|
+
]);
|
|
1094
|
+
export const builtInTypes = new Set(Array.from(builtInChecks.keys()));
|
|
1095
|
+
export const propertyNames = new Set([
|
|
1096
|
+
'@id',
|
|
1097
|
+
'@indexed',
|
|
1098
|
+
'@default',
|
|
1099
|
+
'@optional',
|
|
1100
|
+
'@unique',
|
|
1101
|
+
'@autoincrement',
|
|
1102
|
+
'@array',
|
|
1103
|
+
'@object',
|
|
1104
|
+
'@fk',
|
|
1105
|
+
'@ref',
|
|
1106
|
+
'@readonly',
|
|
1107
|
+
]);
|
|
1108
|
+
export function isBuiltInType(type) {
|
|
1109
|
+
return builtInTypes.has(type);
|
|
1110
|
+
}
|
|
1111
|
+
export function isValidType(type) {
|
|
1112
|
+
if (isBuiltInType(type))
|
|
1113
|
+
return true;
|
|
1114
|
+
const path = splitFqName(type);
|
|
1115
|
+
let modName = '';
|
|
1116
|
+
if (path.hasModule())
|
|
1117
|
+
modName = path.getModuleName();
|
|
1118
|
+
else
|
|
1119
|
+
modName = activeModule;
|
|
1120
|
+
return isModule(modName) && fetchModule(modName).hasEntry(path.getEntryName());
|
|
1121
|
+
}
|
|
1122
|
+
function checkType(type) {
|
|
1123
|
+
if (type == undefined)
|
|
1124
|
+
throw new Error('Attribute type is required');
|
|
1125
|
+
if (!isValidType(type)) {
|
|
1126
|
+
console.log(chalk.red(`WARN: type not found - ${type}`));
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
function validateProperties(props) {
|
|
1130
|
+
if (props != undefined) {
|
|
1131
|
+
props.forEach((p) => {
|
|
1132
|
+
if (!propertyNames.has(p.name))
|
|
1133
|
+
throw new Error(`Invalid property ${p.name}`);
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function verifyAttribute(attr) {
|
|
1138
|
+
if (attr.expr)
|
|
1139
|
+
return;
|
|
1140
|
+
if (!attr.enumSpec && !attr.oneOfSpec && !attr.refSpec)
|
|
1141
|
+
checkType(attr.type || attr.arrayType);
|
|
1142
|
+
validateProperties(attr.properties);
|
|
1143
|
+
}
|
|
1144
|
+
export function defaultAttributes(schema) {
|
|
1145
|
+
const result = new Map();
|
|
1146
|
+
schema.forEach((v, k) => {
|
|
1147
|
+
const props = v.properties;
|
|
1148
|
+
if (props != undefined) {
|
|
1149
|
+
const d = props.get('default');
|
|
1150
|
+
if (d != undefined) {
|
|
1151
|
+
result.set(k, d);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
return result;
|
|
1156
|
+
}
|
|
1157
|
+
export function objectAttributes(schema) {
|
|
1158
|
+
let result;
|
|
1159
|
+
schema.forEach((v, k) => {
|
|
1160
|
+
if (isObjectAttribute(v)) {
|
|
1161
|
+
if (result == undefined)
|
|
1162
|
+
result = new Array();
|
|
1163
|
+
result.push(k);
|
|
1164
|
+
}
|
|
1165
|
+
});
|
|
1166
|
+
return result;
|
|
1167
|
+
}
|
|
1168
|
+
function getBooleanProperty(propName, attrSpec) {
|
|
1169
|
+
if (attrSpec.properties != undefined) {
|
|
1170
|
+
return attrSpec.properties.get(propName) == true;
|
|
1171
|
+
}
|
|
1172
|
+
return false;
|
|
1173
|
+
}
|
|
1174
|
+
function getAnyProperty(propName, attrSpec) {
|
|
1175
|
+
if (attrSpec.properties != undefined) {
|
|
1176
|
+
return attrSpec.properties.get(propName);
|
|
1177
|
+
}
|
|
1178
|
+
return undefined;
|
|
1179
|
+
}
|
|
1180
|
+
export function isIdAttribute(attrSpec) {
|
|
1181
|
+
return getBooleanProperty('id', attrSpec);
|
|
1182
|
+
}
|
|
1183
|
+
export function isUniqueAttribute(attrSpec) {
|
|
1184
|
+
return getBooleanProperty('unique', attrSpec);
|
|
1185
|
+
}
|
|
1186
|
+
export function isIndexedAttribute(attrSpec) {
|
|
1187
|
+
return getBooleanProperty('indexed', attrSpec);
|
|
1188
|
+
}
|
|
1189
|
+
export function isOptionalAttribute(attrSpec) {
|
|
1190
|
+
return getBooleanProperty('optional', attrSpec);
|
|
1191
|
+
}
|
|
1192
|
+
export function isArrayAttribute(attrSpec) {
|
|
1193
|
+
return getBooleanProperty('array', attrSpec);
|
|
1194
|
+
}
|
|
1195
|
+
export function isObjectAttribute(attrSpec) {
|
|
1196
|
+
return getBooleanProperty('object', attrSpec);
|
|
1197
|
+
}
|
|
1198
|
+
export function getAttributeExpr(attrSpec) {
|
|
1199
|
+
return getAnyProperty('expr', attrSpec);
|
|
1200
|
+
}
|
|
1201
|
+
export function getOneOfValues(attrSpec) {
|
|
1202
|
+
return getAnyProperty('one-of', attrSpec);
|
|
1203
|
+
}
|
|
1204
|
+
export function getOneOfRef(attrSpec) {
|
|
1205
|
+
return getAnyProperty('one-of-ref', attrSpec);
|
|
1206
|
+
}
|
|
1207
|
+
export function getAttributeDefaultValue(attrSpec) {
|
|
1208
|
+
return getAnyProperty('default', attrSpec);
|
|
1209
|
+
}
|
|
1210
|
+
export function getAttributeLength(attrSpec) {
|
|
1211
|
+
return getAnyProperty('length', attrSpec);
|
|
1212
|
+
}
|
|
1213
|
+
export function getFkSpec(attrSpec) {
|
|
1214
|
+
return getAnyProperty('fk', attrSpec);
|
|
1215
|
+
}
|
|
1216
|
+
export function getRefSpec(attrSpec) {
|
|
1217
|
+
return getAnyProperty('ref', attrSpec);
|
|
1218
|
+
}
|
|
1219
|
+
export function addEntity(name, moduleName = activeModule, scm, ext) {
|
|
1220
|
+
const module = fetchModule(moduleName);
|
|
1221
|
+
return module.addEntry(new Entity(name, moduleName, scm, ext));
|
|
1222
|
+
}
|
|
1223
|
+
export function addEvent(name, moduleName = activeModule, scm, ext) {
|
|
1224
|
+
const module = fetchModule(moduleName);
|
|
1225
|
+
return module.addEntry(new Event(name, moduleName, scm, ext));
|
|
1226
|
+
}
|
|
1227
|
+
export function addRecord(name, moduleName = activeModule, scm, ext) {
|
|
1228
|
+
const module = fetchModule(moduleName);
|
|
1229
|
+
return module.addEntry(new Record(name, moduleName, scm, ext));
|
|
1230
|
+
}
|
|
1231
|
+
export function addRelationship(name, type, nodes, moduleName = activeModule, scm, props) {
|
|
1232
|
+
const module = fetchModule(moduleName);
|
|
1233
|
+
let n1;
|
|
1234
|
+
let n2;
|
|
1235
|
+
if (isRelNodes(nodes)) {
|
|
1236
|
+
n1 = asRelNodeEntry(nodes.node1);
|
|
1237
|
+
n2 = asRelNodeEntry(nodes.node2);
|
|
1238
|
+
}
|
|
1239
|
+
else {
|
|
1240
|
+
n1 = nodes[0];
|
|
1241
|
+
n2 = nodes[1];
|
|
1242
|
+
}
|
|
1243
|
+
let propsMap;
|
|
1244
|
+
if (props != undefined)
|
|
1245
|
+
propsMap = asPropertiesMap(props);
|
|
1246
|
+
return module.addEntry(new Relationship(name, type, n1, n2, moduleName, scm, propsMap));
|
|
1247
|
+
}
|
|
1248
|
+
export function addBetweenRelationship(name, moduleName, nodes) {
|
|
1249
|
+
return addRelationship(name, 'between', nodes, moduleName);
|
|
1250
|
+
}
|
|
1251
|
+
export function addContainsRelationship(name, moduleName, nodes) {
|
|
1252
|
+
return addRelationship(name, 'contains', nodes, moduleName);
|
|
1253
|
+
}
|
|
1254
|
+
function asWorkflowName(n) {
|
|
1255
|
+
return n + '--workflow';
|
|
1256
|
+
}
|
|
1257
|
+
function normalizeWorkflowName(n) {
|
|
1258
|
+
const i = n.indexOf('--workflow');
|
|
1259
|
+
if (i > 0) {
|
|
1260
|
+
return n.substring(0, i);
|
|
1261
|
+
}
|
|
1262
|
+
return n;
|
|
1263
|
+
}
|
|
1264
|
+
export function addWorkflow(name, moduleName = activeModule, statements) {
|
|
1265
|
+
const module = fetchModule(moduleName);
|
|
1266
|
+
if (module.hasEntry(name)) {
|
|
1267
|
+
const entry = module.getEntry(name);
|
|
1268
|
+
if (!(entry instanceof Event))
|
|
1269
|
+
throw new Error(`Not an event, cannot attach workflow to ${entry.name}`);
|
|
1270
|
+
}
|
|
1271
|
+
else {
|
|
1272
|
+
addEvent(name, moduleName);
|
|
1273
|
+
const event = module.getEntry(name);
|
|
1274
|
+
event.addMeta(SystemDefinedEvent, 'true');
|
|
1275
|
+
}
|
|
1276
|
+
if (!statements)
|
|
1277
|
+
statements = new Array();
|
|
1278
|
+
return module.addEntry(new Workflow(asWorkflowName(name), statements, moduleName));
|
|
1279
|
+
}
|
|
1280
|
+
export function getWorkflow(eventInstance) {
|
|
1281
|
+
const eventName = eventInstance.name;
|
|
1282
|
+
const moduleName = eventInstance.moduleName;
|
|
1283
|
+
const wfName = asWorkflowName(eventName);
|
|
1284
|
+
const module = fetchModule(moduleName);
|
|
1285
|
+
if (module.hasEntry(wfName)) {
|
|
1286
|
+
return module.getEntry(wfName);
|
|
1287
|
+
}
|
|
1288
|
+
return EmptyWorkflow;
|
|
1289
|
+
}
|
|
1290
|
+
export function getEntity(name, moduleName) {
|
|
1291
|
+
const fr = fetchModuleByEntryName(name, moduleName);
|
|
1292
|
+
if (fr.module.isEntity(fr.entryName)) {
|
|
1293
|
+
return fr.module.getEntry(fr.entryName);
|
|
1294
|
+
}
|
|
1295
|
+
throw new Error(`Entity ${fr.entryName} not found in module ${fr.moduleName}`);
|
|
1296
|
+
}
|
|
1297
|
+
export function getEvent(name, moduleName) {
|
|
1298
|
+
const fr = fetchModuleByEntryName(name, moduleName);
|
|
1299
|
+
if (fr.module.isEvent(fr.entryName)) {
|
|
1300
|
+
return fr.module.getEntry(fr.entryName);
|
|
1301
|
+
}
|
|
1302
|
+
throw new Error(`Event ${fr.entryName} not found in module ${fr.moduleName}`);
|
|
1303
|
+
}
|
|
1304
|
+
export function getRecord(name, moduleName) {
|
|
1305
|
+
const fr = fetchModuleByEntryName(name, moduleName);
|
|
1306
|
+
if (fr.module.isRecord(fr.entryName)) {
|
|
1307
|
+
return fr.module.getEntry(fr.entryName);
|
|
1308
|
+
}
|
|
1309
|
+
throw new Error(`Record ${fr.entryName} not found in module ${fr.moduleName}`);
|
|
1310
|
+
}
|
|
1311
|
+
export function getRelationship(name, moduleName) {
|
|
1312
|
+
const fr = fetchModuleByEntryName(name, moduleName);
|
|
1313
|
+
if (fr.module.isRelationship(fr.entryName)) {
|
|
1314
|
+
return fr.module.getEntry(fr.entryName);
|
|
1315
|
+
}
|
|
1316
|
+
throw new Error(`Relationship ${fr.entryName} not found in module ${fr.moduleName}`);
|
|
1317
|
+
}
|
|
1318
|
+
export function getAllBetweenRelationships() {
|
|
1319
|
+
let result = [];
|
|
1320
|
+
allModuleNames().forEach((moduleName) => {
|
|
1321
|
+
const mod = fetchModule(moduleName);
|
|
1322
|
+
result = result.concat(mod.getBetweenRelationshipEntries());
|
|
1323
|
+
});
|
|
1324
|
+
return result;
|
|
1325
|
+
}
|
|
1326
|
+
export function getAllChildRelationships(parentFqName) {
|
|
1327
|
+
let result = new Array();
|
|
1328
|
+
allModuleNames().forEach((moduleName) => {
|
|
1329
|
+
const mod = fetchModule(moduleName);
|
|
1330
|
+
result = result.concat(mod.getContainsRelationshipEntries().filter((rel) => {
|
|
1331
|
+
return rel.getParentFqName() == parentFqName;
|
|
1332
|
+
}));
|
|
1333
|
+
});
|
|
1334
|
+
return result;
|
|
1335
|
+
}
|
|
1336
|
+
function filterBetweenRelationshipsForEntity(moduleName, entityName, predic, allBetweenRels) {
|
|
1337
|
+
if (allBetweenRels == undefined) {
|
|
1338
|
+
allBetweenRels = getAllBetweenRelationships();
|
|
1339
|
+
}
|
|
1340
|
+
const p = new Path(moduleName, entityName);
|
|
1341
|
+
return allBetweenRels.filter((re) => {
|
|
1342
|
+
return predic(re, p);
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
export function getAllOneToOneRelationshipsForEntity(moduleName, entityName, allBetweenRels) {
|
|
1346
|
+
return filterBetweenRelationshipsForEntity(moduleName, entityName, (re, p) => {
|
|
1347
|
+
return re.isOneToOne() && (re.node1.path.equals(p) || re.node2.path.equals(p));
|
|
1348
|
+
}, allBetweenRels);
|
|
1349
|
+
}
|
|
1350
|
+
export function getAllOneToManyRelationshipsForEntity(moduleName, entityName, allBetweenRels) {
|
|
1351
|
+
return filterBetweenRelationshipsForEntity(moduleName, entityName, (re, p) => {
|
|
1352
|
+
return re.isOneToMany() && re.node1.path.equals(p);
|
|
1353
|
+
}, allBetweenRels);
|
|
1354
|
+
}
|
|
1355
|
+
export function getAllManyToOneRelationshipsForEntity(moduleName, entityName, allBetweenRels) {
|
|
1356
|
+
return filterBetweenRelationshipsForEntity(moduleName, entityName, (re, p) => {
|
|
1357
|
+
return re.isOneToMany() && re.node2.path.equals(p);
|
|
1358
|
+
}, allBetweenRels);
|
|
1359
|
+
}
|
|
1360
|
+
export function getAllManyToManyRelationshipsForEntity(moduleName, entityName, allBetweenRels) {
|
|
1361
|
+
return filterBetweenRelationshipsForEntity(moduleName, entityName, (re, p) => {
|
|
1362
|
+
return re.isManyToMany() && re.node1.path.equals(p);
|
|
1363
|
+
}, allBetweenRels);
|
|
1364
|
+
}
|
|
1365
|
+
export function getEntrySchema(name, moduleName) {
|
|
1366
|
+
const m = fetchModule(moduleName);
|
|
1367
|
+
const r = m.getEntry(name);
|
|
1368
|
+
return r.schema;
|
|
1369
|
+
}
|
|
1370
|
+
export function removeEntity(name, moduleName = activeModule) {
|
|
1371
|
+
const module = fetchModule(moduleName);
|
|
1372
|
+
if (module.isEntity(name)) {
|
|
1373
|
+
return module.removeEntry(name);
|
|
1374
|
+
}
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
export function removeRecord(name, moduleName = activeModule) {
|
|
1378
|
+
const module = fetchModule(moduleName);
|
|
1379
|
+
if (module.isRecord(name)) {
|
|
1380
|
+
return module.removeEntry(name);
|
|
1381
|
+
}
|
|
1382
|
+
return false;
|
|
1383
|
+
}
|
|
1384
|
+
export function removeRelationship(name, moduleName = activeModule) {
|
|
1385
|
+
const module = fetchModule(moduleName);
|
|
1386
|
+
if (module.isRelationship(name)) {
|
|
1387
|
+
return module.removeEntry(name);
|
|
1388
|
+
}
|
|
1389
|
+
return false;
|
|
1390
|
+
}
|
|
1391
|
+
export function removeWorkflow(name, moduleName = activeModule) {
|
|
1392
|
+
const module = fetchModule(moduleName);
|
|
1393
|
+
return module.removeEntry(asWorkflowName(name));
|
|
1394
|
+
}
|
|
1395
|
+
export function removeEvent(name, moduleName = activeModule) {
|
|
1396
|
+
const module = fetchModule(moduleName);
|
|
1397
|
+
if (module.isEvent(name)) {
|
|
1398
|
+
const r = module.removeEntry(name);
|
|
1399
|
+
if (r) {
|
|
1400
|
+
module.removeEntry(asWorkflowName(name));
|
|
1401
|
+
return r;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
function getAttributeSpec(attrsSpec, attrName) {
|
|
1407
|
+
const spec = attrsSpec.get(attrName);
|
|
1408
|
+
if (spec == undefined) {
|
|
1409
|
+
throw new Error(`Failed to find spec for attribute ${attrName}`);
|
|
1410
|
+
}
|
|
1411
|
+
return spec;
|
|
1412
|
+
}
|
|
1413
|
+
function checkOneOfValue(attrSpec, attrName, attrValue) {
|
|
1414
|
+
if (getOneOfRef(attrSpec)) {
|
|
1415
|
+
return true;
|
|
1416
|
+
}
|
|
1417
|
+
const vals = getOneOfValues(attrSpec);
|
|
1418
|
+
if (vals) {
|
|
1419
|
+
if (!vals.has(attrValue)) {
|
|
1420
|
+
throw new Error(`Value of ${attrName} must be one-of ${vals}`);
|
|
1421
|
+
}
|
|
1422
|
+
return true;
|
|
1423
|
+
}
|
|
1424
|
+
return false;
|
|
1425
|
+
}
|
|
1426
|
+
function validateType(attrName, attrValue, attrSpec) {
|
|
1427
|
+
if (attrSpec.type == 'Path') {
|
|
1428
|
+
if (!isPath(attrValue, getRefSpec(attrSpec))) {
|
|
1429
|
+
throw new Error(`Failed to validate Path ${attrValue} passed to ${attrName}`);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const predic = builtInChecks.get(attrSpec.type);
|
|
1433
|
+
if (predic != undefined) {
|
|
1434
|
+
if (isArrayAttribute(attrSpec)) {
|
|
1435
|
+
if (!(attrValue instanceof Array)) {
|
|
1436
|
+
throw new Error(`${attrName} expects an array of values`);
|
|
1437
|
+
}
|
|
1438
|
+
else {
|
|
1439
|
+
if (!attrValue.every(predic)) {
|
|
1440
|
+
throw new Error(`Invalid value in the array passed to ${attrName}`);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
else {
|
|
1445
|
+
if (!checkOneOfValue(attrSpec, attrName, attrValue)) {
|
|
1446
|
+
if (!predic(attrValue)) {
|
|
1447
|
+
throw new Error(`Invalid value ${attrValue} specified for ${attrName}`);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
else {
|
|
1453
|
+
checkOneOfValue(attrSpec, attrName, attrValue);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
export function newInstanceAttributes() {
|
|
1457
|
+
return new Map();
|
|
1458
|
+
}
|
|
1459
|
+
const EmptyInstanceAttributes = newInstanceAttributes();
|
|
1460
|
+
export class Instance {
|
|
1461
|
+
constructor(record, moduleName, name, attributes, queryAttributes, queryAttributeValues) {
|
|
1462
|
+
this.record = record;
|
|
1463
|
+
this.name = name;
|
|
1464
|
+
this.moduleName = moduleName;
|
|
1465
|
+
this.attributes = attributes;
|
|
1466
|
+
this.queryAttributes = queryAttributes;
|
|
1467
|
+
this.queryAttributeValues = queryAttributeValues;
|
|
1468
|
+
}
|
|
1469
|
+
static EmptyInstance(name, moduleName) {
|
|
1470
|
+
const module = fetchModule(moduleName);
|
|
1471
|
+
return new Instance(module.getEntry(name), moduleName, name, EmptyInstanceAttributes);
|
|
1472
|
+
}
|
|
1473
|
+
static newWithAttributes(inst, newAttrs) {
|
|
1474
|
+
return new Instance(inst.record, inst.moduleName, inst.name, inst.normalizeAttributes(newAttrs));
|
|
1475
|
+
}
|
|
1476
|
+
normalizeAttributes(attrs) {
|
|
1477
|
+
attrs.forEach((v, k) => {
|
|
1478
|
+
const attrSpec = this.record.schema.get(k);
|
|
1479
|
+
if (attrSpec) {
|
|
1480
|
+
if ((isArrayAttribute(attrSpec) || isObjectAttribute(attrSpec)) && isString(v)) {
|
|
1481
|
+
const obj = JSON.parse(v);
|
|
1482
|
+
attrs.set(k, obj);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
return attrs;
|
|
1487
|
+
}
|
|
1488
|
+
requireAudit() {
|
|
1489
|
+
return this.record.getMeta('audit');
|
|
1490
|
+
}
|
|
1491
|
+
lookup(k) {
|
|
1492
|
+
return this.attributes.get(k);
|
|
1493
|
+
}
|
|
1494
|
+
getPath() {
|
|
1495
|
+
return this.lookup(PathAttributeName);
|
|
1496
|
+
}
|
|
1497
|
+
asObject() {
|
|
1498
|
+
const result = new Map();
|
|
1499
|
+
result.set(this.name, Object.fromEntries(this.attributes));
|
|
1500
|
+
return Object.fromEntries(result);
|
|
1501
|
+
}
|
|
1502
|
+
attributesAsObject(stringifyObjects = true) {
|
|
1503
|
+
if (stringifyObjects) {
|
|
1504
|
+
this.attributes.forEach((v, k) => {
|
|
1505
|
+
if (v instanceof Object) {
|
|
1506
|
+
this.attributes.set(k, JSON.stringify(v instanceof Map ? Object.fromEntries(v) : v));
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
return Object.fromEntries(this.attributes);
|
|
1511
|
+
}
|
|
1512
|
+
queryAttributesAsObject() {
|
|
1513
|
+
if (this.queryAttributes != undefined) {
|
|
1514
|
+
return Object.fromEntries(this.queryAttributes);
|
|
1515
|
+
}
|
|
1516
|
+
return {};
|
|
1517
|
+
}
|
|
1518
|
+
queryAttributeValuesAsObject() {
|
|
1519
|
+
if (this.queryAttributeValues != undefined) {
|
|
1520
|
+
return Object.fromEntries(this.queryAttributeValues);
|
|
1521
|
+
}
|
|
1522
|
+
return {};
|
|
1523
|
+
}
|
|
1524
|
+
addQuery(attrName, op = '=', attrVal = undefined) {
|
|
1525
|
+
if (this.queryAttributes == undefined)
|
|
1526
|
+
this.queryAttributes = newInstanceAttributes();
|
|
1527
|
+
this.queryAttributes.set(attrName, op);
|
|
1528
|
+
if (attrVal != undefined) {
|
|
1529
|
+
if (this.queryAttributeValues == undefined)
|
|
1530
|
+
this.queryAttributeValues = newInstanceAttributes();
|
|
1531
|
+
this.queryAttributeValues.set(attrName, attrVal);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
mergeAttributes(newAttrs) {
|
|
1535
|
+
newAttrs.forEach((v, k) => {
|
|
1536
|
+
this.attributes.set(k, v);
|
|
1537
|
+
});
|
|
1538
|
+
return this;
|
|
1539
|
+
}
|
|
1540
|
+
attachRelatedInstances(relName, insts) {
|
|
1541
|
+
if (this.relatedInstances == undefined) {
|
|
1542
|
+
this.relatedInstances = new Map();
|
|
1543
|
+
}
|
|
1544
|
+
let relInsts = this.relatedInstances.get(relName);
|
|
1545
|
+
if (relInsts == undefined) {
|
|
1546
|
+
relInsts = new Array();
|
|
1547
|
+
}
|
|
1548
|
+
if (insts instanceof Instance) {
|
|
1549
|
+
relInsts.push(insts);
|
|
1550
|
+
}
|
|
1551
|
+
else {
|
|
1552
|
+
insts.forEach((inst) => {
|
|
1553
|
+
relInsts.push(inst);
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
this.relatedInstances.set(relName, relInsts);
|
|
1557
|
+
this.attributes.set('->', this.relatedInstances);
|
|
1558
|
+
}
|
|
1559
|
+
detachAllRelatedInstance() {
|
|
1560
|
+
var _a;
|
|
1561
|
+
if (this.relatedInstances != undefined) {
|
|
1562
|
+
(_a = this.relatedInstances) === null || _a === void 0 ? void 0 : _a.clear();
|
|
1563
|
+
this.relatedInstances = undefined;
|
|
1564
|
+
this.attributes.delete('->');
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
mergeRelatedInstances() {
|
|
1568
|
+
if (this.relatedInstances != undefined) {
|
|
1569
|
+
this.relatedInstances.forEach((v, k) => {
|
|
1570
|
+
this.attributes.set(k, v);
|
|
1571
|
+
});
|
|
1572
|
+
this.detachAllRelatedInstance();
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
getRelatedInstances(relName) {
|
|
1576
|
+
if (this.relatedInstances) {
|
|
1577
|
+
const insts = this.relatedInstances.get(relName);
|
|
1578
|
+
return insts ? insts : undefined;
|
|
1579
|
+
}
|
|
1580
|
+
return undefined;
|
|
1581
|
+
}
|
|
1582
|
+
getAllUserAttributeNames() {
|
|
1583
|
+
return this.record.getUserAttributeNames();
|
|
1584
|
+
}
|
|
1585
|
+
getFqName() {
|
|
1586
|
+
return makeFqName(this.moduleName, this.name);
|
|
1587
|
+
}
|
|
1588
|
+
addContextData(k, v) {
|
|
1589
|
+
if (this.contextData == undefined) {
|
|
1590
|
+
this.contextData = new Map();
|
|
1591
|
+
}
|
|
1592
|
+
this.contextData.set(k, v);
|
|
1593
|
+
return this;
|
|
1594
|
+
}
|
|
1595
|
+
getContextData(k, notFoundValue) {
|
|
1596
|
+
if (this.contextData) {
|
|
1597
|
+
const v = this.contextData.get(k);
|
|
1598
|
+
if (v == undefined)
|
|
1599
|
+
return notFoundValue;
|
|
1600
|
+
return v;
|
|
1601
|
+
}
|
|
1602
|
+
return notFoundValue;
|
|
1603
|
+
}
|
|
1604
|
+
setAuthContext(sesssionInfo) {
|
|
1605
|
+
return this.addContextData('sessionInfo', sesssionInfo);
|
|
1606
|
+
}
|
|
1607
|
+
getAuthContext() {
|
|
1608
|
+
return this.getContextData('sessionInfo', undefined);
|
|
1609
|
+
}
|
|
1610
|
+
getAuthContextUserId() {
|
|
1611
|
+
const sessInfo = this.getContextData('sessionInfo', AdminSession);
|
|
1612
|
+
return sessInfo.userId;
|
|
1613
|
+
}
|
|
1614
|
+
getExprAttributes() {
|
|
1615
|
+
let result;
|
|
1616
|
+
this.record.schema.forEach((attrSpec, n) => {
|
|
1617
|
+
const expr = getAttributeExpr(attrSpec);
|
|
1618
|
+
if (expr) {
|
|
1619
|
+
if (result == undefined) {
|
|
1620
|
+
result = new Map();
|
|
1621
|
+
}
|
|
1622
|
+
result.set(n, expr);
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
return result;
|
|
1626
|
+
}
|
|
1627
|
+
cast() {
|
|
1628
|
+
return Object.fromEntries(this.attributes);
|
|
1629
|
+
}
|
|
1630
|
+
get(k) {
|
|
1631
|
+
return this.attributes.get(k);
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
export function objectAsInstanceAttributes(obj) {
|
|
1635
|
+
const attrs = newInstanceAttributes();
|
|
1636
|
+
Object.entries(obj).forEach((v) => {
|
|
1637
|
+
const obj = v[1];
|
|
1638
|
+
attrs.set(v[0], obj);
|
|
1639
|
+
});
|
|
1640
|
+
return attrs;
|
|
1641
|
+
}
|
|
1642
|
+
export function findIdAttribute(inst) {
|
|
1643
|
+
const schema = inst.record.schema;
|
|
1644
|
+
for (const [key, value] of schema) {
|
|
1645
|
+
const attrSpec = value;
|
|
1646
|
+
if (isIdAttribute(attrSpec)) {
|
|
1647
|
+
return {
|
|
1648
|
+
name: key,
|
|
1649
|
+
spec: attrSpec,
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
return undefined;
|
|
1654
|
+
}
|
|
1655
|
+
function maybeSetDefaultAttributeValues(schema, attributes) {
|
|
1656
|
+
const defAttrs = defaultAttributes(schema);
|
|
1657
|
+
defAttrs.forEach((v, k) => {
|
|
1658
|
+
if (!attributes.has(k)) {
|
|
1659
|
+
if (isString(v)) {
|
|
1660
|
+
if (v == 'uuid()') {
|
|
1661
|
+
v = crypto.randomUUID();
|
|
1662
|
+
}
|
|
1663
|
+
else if (v == 'now()') {
|
|
1664
|
+
v = now();
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
attributes.set(k, v);
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
return attributes;
|
|
1671
|
+
}
|
|
1672
|
+
export function makeInstance(moduleName, entryName, attributes, queryAttributes, queryAttributeValues, queryAll = false) {
|
|
1673
|
+
const module = fetchModule(moduleName);
|
|
1674
|
+
const record = module.getRecord(entryName);
|
|
1675
|
+
const schema = record.schema;
|
|
1676
|
+
if (schema.size > 0) {
|
|
1677
|
+
attributes.forEach((value, key) => {
|
|
1678
|
+
if (!schema.has(key)) {
|
|
1679
|
+
throw new Error(`Invalid attribute ${key} specified for ${moduleName}/${entryName}`);
|
|
1680
|
+
}
|
|
1681
|
+
const spec = getAttributeSpec(schema, key);
|
|
1682
|
+
validateType(key, value, spec);
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
if (!queryAttributes && !queryAll) {
|
|
1686
|
+
attributes = maybeSetDefaultAttributeValues(schema, attributes);
|
|
1687
|
+
}
|
|
1688
|
+
return new Instance(record, moduleName, entryName, attributes, queryAttributes, queryAttributeValues);
|
|
1689
|
+
}
|
|
1690
|
+
export function isEventInstance(inst) {
|
|
1691
|
+
return inst.record.type == RecordType.EVENT;
|
|
1692
|
+
}
|
|
1693
|
+
export function isEntityInstance(inst) {
|
|
1694
|
+
return inst.record.type == RecordType.ENTITY;
|
|
1695
|
+
}
|
|
1696
|
+
export function isRecordInstance(inst) {
|
|
1697
|
+
return inst.record.type == RecordType.RECORD;
|
|
1698
|
+
}
|
|
1699
|
+
export function getAllModuleEntries(f) {
|
|
1700
|
+
const result = new Map();
|
|
1701
|
+
moduleDb.forEach((module, k) => {
|
|
1702
|
+
result.set(k, f(module).map((me) => {
|
|
1703
|
+
return me.name;
|
|
1704
|
+
}));
|
|
1705
|
+
});
|
|
1706
|
+
return result;
|
|
1707
|
+
}
|
|
1708
|
+
export function getAllEventNames() {
|
|
1709
|
+
return getAllModuleEntries((module) => {
|
|
1710
|
+
return module.getEventEntries();
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
export function getAllEntityNames() {
|
|
1714
|
+
return getAllModuleEntries((module) => {
|
|
1715
|
+
return module.getEntityEntries();
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
export function isBetweenRelationship(relName, moduleName) {
|
|
1719
|
+
const fr = fetchModuleByEntryName(relName, moduleName);
|
|
1720
|
+
const mod = fr.module;
|
|
1721
|
+
return mod.isBetweenRelationship(fr.entryName);
|
|
1722
|
+
}
|
|
1723
|
+
export function isContainsRelationship(relName, moduleName) {
|
|
1724
|
+
const fr = fetchModuleByEntryName(relName, moduleName);
|
|
1725
|
+
const mod = fr.module;
|
|
1726
|
+
return mod.isContainsRelationship(fr.entryName);
|
|
1727
|
+
}
|
|
1728
|
+
export function getBetweenInstanceNodeValues(inst) {
|
|
1729
|
+
const re = fetchModuleEntry(inst.name, inst.moduleName);
|
|
1730
|
+
return {
|
|
1731
|
+
node1: inst.attributes.get(re.node1.alias),
|
|
1732
|
+
node2: inst.attributes.get(re.node2.alias),
|
|
1733
|
+
entry: re,
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
export function isInstance(obj) {
|
|
1737
|
+
if (obj) {
|
|
1738
|
+
return obj instanceof Instance;
|
|
1739
|
+
}
|
|
1740
|
+
return false;
|
|
1741
|
+
}
|
|
1742
|
+
export function isInstanceOfType(obj, fqName) {
|
|
1743
|
+
if (obj) {
|
|
1744
|
+
return isInstance(obj) && fqName == obj.getFqName();
|
|
1745
|
+
}
|
|
1746
|
+
return false;
|
|
1747
|
+
}
|
|
1748
|
+
export function assertInstance(obj) {
|
|
1749
|
+
if (obj instanceof Array) {
|
|
1750
|
+
if (obj.length == 0) {
|
|
1751
|
+
throw new Error(`Empty instances`);
|
|
1752
|
+
}
|
|
1753
|
+
obj.forEach(assertInstance);
|
|
1754
|
+
}
|
|
1755
|
+
else if (!(obj instanceof Instance)) {
|
|
1756
|
+
throw new Error(`${obj} is not an Instance`);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
const IsAgentEventMeta = 'is-agent-event';
|
|
1760
|
+
const EventAgentName = 'event-agent-name';
|
|
1761
|
+
export function defineAgentEvent(moduleName, agentName) {
|
|
1762
|
+
const module = fetchModule(moduleName);
|
|
1763
|
+
const event = new Event(agentName, moduleName);
|
|
1764
|
+
event.addAttribute('message', { type: 'String' });
|
|
1765
|
+
event.addAttribute('chatId', { type: 'String' });
|
|
1766
|
+
event.addMeta(IsAgentEventMeta, 'y');
|
|
1767
|
+
event.addMeta(EventAgentName, agentName);
|
|
1768
|
+
module.addEntry(event);
|
|
1769
|
+
}
|
|
1770
|
+
export function isTimer(eventInst) {
|
|
1771
|
+
return eventInst.getFqName() == 'agentlang/timer';
|
|
1772
|
+
}
|
|
1773
|
+
export function isAgentEvent(eventInst) {
|
|
1774
|
+
const flag = eventInst.record.getMeta(IsAgentEventMeta);
|
|
1775
|
+
return flag != undefined && flag == 'y';
|
|
1776
|
+
}
|
|
1777
|
+
export function eventAgentName(eventInst) {
|
|
1778
|
+
return eventInst.record.getMeta(EventAgentName);
|
|
1779
|
+
}
|
|
1780
|
+
export function instanceToObject(inst, obj) {
|
|
1781
|
+
inst.attributes.forEach((v, k) => {
|
|
1782
|
+
obj[k] = v;
|
|
1783
|
+
});
|
|
1784
|
+
return obj;
|
|
1785
|
+
}
|
|
1786
|
+
//# sourceMappingURL=module.js.map
|