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.
Files changed (240) hide show
  1. package/LICENSE +83 -0
  2. package/README.md +120 -0
  3. package/bin/cli.js +4 -0
  4. package/out/api/http.d.ts +3 -0
  5. package/out/api/http.d.ts.map +1 -0
  6. package/out/api/http.js +290 -0
  7. package/out/api/http.js.map +1 -0
  8. package/out/cli/cli-util.d.ts +7 -0
  9. package/out/cli/cli-util.d.ts.map +1 -0
  10. package/out/cli/cli-util.js +9 -0
  11. package/out/cli/cli-util.js.map +1 -0
  12. package/out/cli/docs.d.ts +2 -0
  13. package/out/cli/docs.d.ts.map +1 -0
  14. package/out/cli/docs.js +236 -0
  15. package/out/cli/docs.js.map +1 -0
  16. package/out/cli/main.d.ts +288 -0
  17. package/out/cli/main.d.ts.map +1 -0
  18. package/out/cli/main.js +119 -0
  19. package/out/cli/main.js.map +1 -0
  20. package/out/cli/openapi-docs.yml +695 -0
  21. package/out/extension/main.cjs +18093 -0
  22. package/out/extension/main.cjs.map +7 -0
  23. package/out/extension/main.d.ts +4 -0
  24. package/out/extension/main.d.ts.map +1 -0
  25. package/out/extension/main.js +42 -0
  26. package/out/extension/main.js.map +1 -0
  27. package/out/language/agentlang-module.d.ts +42 -0
  28. package/out/language/agentlang-module.d.ts.map +1 -0
  29. package/out/language/agentlang-module.js +42 -0
  30. package/out/language/agentlang-module.js.map +1 -0
  31. package/out/language/agentlang-validator.d.ts +15 -0
  32. package/out/language/agentlang-validator.d.ts.map +1 -0
  33. package/out/language/agentlang-validator.js +50 -0
  34. package/out/language/agentlang-validator.js.map +1 -0
  35. package/out/language/generated/ast.d.ts +491 -0
  36. package/out/language/generated/ast.d.ts.map +1 -0
  37. package/out/language/generated/ast.js +934 -0
  38. package/out/language/generated/ast.js.map +1 -0
  39. package/out/language/generated/grammar.d.ts +7 -0
  40. package/out/language/generated/grammar.d.ts.map +1 -0
  41. package/out/language/generated/grammar.js +4475 -0
  42. package/out/language/generated/grammar.js.map +1 -0
  43. package/out/language/generated/module.d.ts +14 -0
  44. package/out/language/generated/module.d.ts.map +1 -0
  45. package/out/language/generated/module.js +21 -0
  46. package/out/language/generated/module.js.map +1 -0
  47. package/out/language/main-browser.d.ts +2 -0
  48. package/out/language/main-browser.d.ts.map +1 -0
  49. package/out/language/main-browser.js +10 -0
  50. package/out/language/main-browser.js.map +1 -0
  51. package/out/language/main.cjs +36229 -0
  52. package/out/language/main.cjs.map +7 -0
  53. package/out/language/main.d.ts +2 -0
  54. package/out/language/main.d.ts.map +1 -0
  55. package/out/language/main.js +11 -0
  56. package/out/language/main.js.map +1 -0
  57. package/out/language/parser.d.ts +9 -0
  58. package/out/language/parser.d.ts.map +1 -0
  59. package/out/language/parser.js +273 -0
  60. package/out/language/parser.js.map +1 -0
  61. package/out/language/syntax.d.ts +155 -0
  62. package/out/language/syntax.d.ts.map +1 -0
  63. package/out/language/syntax.js +527 -0
  64. package/out/language/syntax.js.map +1 -0
  65. package/out/runtime/agents/common.d.ts +2 -0
  66. package/out/runtime/agents/common.d.ts.map +1 -0
  67. package/out/runtime/agents/common.js +178 -0
  68. package/out/runtime/agents/common.js.map +1 -0
  69. package/out/runtime/agents/impl/openai.d.ts +8 -0
  70. package/out/runtime/agents/impl/openai.d.ts.map +1 -0
  71. package/out/runtime/agents/impl/openai.js +15 -0
  72. package/out/runtime/agents/impl/openai.js.map +1 -0
  73. package/out/runtime/agents/provider.d.ts +21 -0
  74. package/out/runtime/agents/provider.d.ts.map +1 -0
  75. package/out/runtime/agents/provider.js +32 -0
  76. package/out/runtime/agents/provider.js.map +1 -0
  77. package/out/runtime/agents/registry.d.ts +2 -0
  78. package/out/runtime/agents/registry.d.ts.map +1 -0
  79. package/out/runtime/agents/registry.js +10 -0
  80. package/out/runtime/agents/registry.js.map +1 -0
  81. package/out/runtime/auth/cognito.d.ts +16 -0
  82. package/out/runtime/auth/cognito.d.ts.map +1 -0
  83. package/out/runtime/auth/cognito.js +186 -0
  84. package/out/runtime/auth/cognito.js.map +1 -0
  85. package/out/runtime/auth/defs.d.ts +11 -0
  86. package/out/runtime/auth/defs.d.ts.map +1 -0
  87. package/out/runtime/auth/defs.js +24 -0
  88. package/out/runtime/auth/defs.js.map +1 -0
  89. package/out/runtime/auth/interface.d.ts +22 -0
  90. package/out/runtime/auth/interface.d.ts.map +1 -0
  91. package/out/runtime/auth/interface.js +2 -0
  92. package/out/runtime/auth/interface.js.map +1 -0
  93. package/out/runtime/defs.js +24 -0
  94. package/out/runtime/defs.js.map +1 -0
  95. package/out/runtime/interpreter.d.ts +69 -0
  96. package/out/runtime/interpreter.d.ts.map +1 -0
  97. package/out/runtime/interpreter.js +1163 -0
  98. package/out/runtime/interpreter.js.map +1 -0
  99. package/out/runtime/loader.d.ts +25 -0
  100. package/out/runtime/loader.d.ts.map +1 -0
  101. package/out/runtime/loader.js +346 -0
  102. package/out/runtime/loader.js.map +1 -0
  103. package/out/runtime/logger.d.ts +2 -0
  104. package/out/runtime/logger.d.ts.map +1 -0
  105. package/out/runtime/logger.js +44 -0
  106. package/out/runtime/logger.js.map +1 -0
  107. package/out/runtime/module.d.ts +273 -0
  108. package/out/runtime/module.d.ts.map +1 -0
  109. package/out/runtime/module.js +1786 -0
  110. package/out/runtime/module.js.map +1 -0
  111. package/out/runtime/modules/ai.d.ts +26 -0
  112. package/out/runtime/modules/ai.d.ts.map +1 -0
  113. package/out/runtime/modules/ai.js +211 -0
  114. package/out/runtime/modules/ai.js.map +1 -0
  115. package/out/runtime/modules/auth.d.ts +39 -0
  116. package/out/runtime/modules/auth.d.ts.map +1 -0
  117. package/out/runtime/modules/auth.js +359 -0
  118. package/out/runtime/modules/auth.js.map +1 -0
  119. package/out/runtime/modules/core.d.ts +2 -0
  120. package/out/runtime/modules/core.d.ts.map +1 -0
  121. package/out/runtime/modules/core.js +67 -0
  122. package/out/runtime/modules/core.js.map +1 -0
  123. package/out/runtime/relgraph.d.ts +21 -0
  124. package/out/runtime/relgraph.d.ts.map +1 -0
  125. package/out/runtime/relgraph.js +156 -0
  126. package/out/runtime/relgraph.js.map +1 -0
  127. package/out/runtime/resolvers/interface.d.ts +59 -0
  128. package/out/runtime/resolvers/interface.d.ts.map +1 -0
  129. package/out/runtime/resolvers/interface.js +111 -0
  130. package/out/runtime/resolvers/interface.js.map +1 -0
  131. package/out/runtime/resolvers/registry.d.ts +8 -0
  132. package/out/runtime/resolvers/registry.d.ts.map +1 -0
  133. package/out/runtime/resolvers/registry.js +26 -0
  134. package/out/runtime/resolvers/registry.js.map +1 -0
  135. package/out/runtime/resolvers/sqldb/database.d.ts +50 -0
  136. package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -0
  137. package/out/runtime/resolvers/sqldb/database.js +618 -0
  138. package/out/runtime/resolvers/sqldb/database.js.map +1 -0
  139. package/out/runtime/resolvers/sqldb/dbutil.d.ts +18 -0
  140. package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -0
  141. package/out/runtime/resolvers/sqldb/dbutil.js +221 -0
  142. package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -0
  143. package/out/runtime/resolvers/sqldb/impl.d.ts +26 -0
  144. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -0
  145. package/out/runtime/resolvers/sqldb/impl.js +300 -0
  146. package/out/runtime/resolvers/sqldb/impl.js.map +1 -0
  147. package/out/runtime/state.js +83 -0
  148. package/out/runtime/state.js.map +1 -0
  149. package/out/runtime/util.d.ts +43 -0
  150. package/out/runtime/util.d.ts.map +1 -0
  151. package/out/runtime/util.js +447 -0
  152. package/out/runtime/util.js.map +1 -0
  153. package/out/setupClassic.d.ts +98 -0
  154. package/out/setupClassic.d.ts.map +1 -0
  155. package/out/setupClassic.js +38 -0
  156. package/out/setupClassic.js.map +1 -0
  157. package/out/setupCommon.d.ts +2 -0
  158. package/out/setupCommon.d.ts.map +1 -0
  159. package/out/setupCommon.js +33 -0
  160. package/out/setupCommon.js.map +1 -0
  161. package/out/setupExtended.d.ts +40 -0
  162. package/out/setupExtended.d.ts.map +1 -0
  163. package/out/setupExtended.js +67 -0
  164. package/out/setupExtended.js.map +1 -0
  165. package/out/syntaxes/agentlang.monarch.d.ts +77 -0
  166. package/out/syntaxes/agentlang.monarch.d.ts.map +1 -0
  167. package/out/syntaxes/agentlang.monarch.js +31 -0
  168. package/out/syntaxes/agentlang.monarch.js.map +1 -0
  169. package/out/utils/fs/index.d.ts +14 -0
  170. package/out/utils/fs/index.d.ts.map +1 -0
  171. package/out/utils/fs/index.js +26 -0
  172. package/out/utils/fs/index.js.map +1 -0
  173. package/out/utils/fs/interfaces.d.ts +105 -0
  174. package/out/utils/fs/interfaces.d.ts.map +1 -0
  175. package/out/utils/fs/interfaces.js +5 -0
  176. package/out/utils/fs/interfaces.js.map +1 -0
  177. package/out/utils/fs/lightning-fs.d.ts +116 -0
  178. package/out/utils/fs/lightning-fs.d.ts.map +1 -0
  179. package/out/utils/fs/lightning-fs.js +243 -0
  180. package/out/utils/fs/lightning-fs.js.map +1 -0
  181. package/out/utils/fs/node-fs.d.ts +93 -0
  182. package/out/utils/fs/node-fs.d.ts.map +1 -0
  183. package/out/utils/fs/node-fs.js +169 -0
  184. package/out/utils/fs/node-fs.js.map +1 -0
  185. package/out/utils/fs-utils.d.ts +153 -0
  186. package/out/utils/fs-utils.d.ts.map +1 -0
  187. package/out/utils/fs-utils.js +271 -0
  188. package/out/utils/fs-utils.js.map +1 -0
  189. package/out/utils/runtime.d.ts +36 -0
  190. package/out/utils/runtime.d.ts.map +1 -0
  191. package/out/utils/runtime.js +39 -0
  192. package/out/utils/runtime.js.map +1 -0
  193. package/package.json +155 -0
  194. package/src/api/http.ts +361 -0
  195. package/src/cli/cli-util.ts +18 -0
  196. package/src/cli/main.ts +146 -0
  197. package/src/extension/main.ts +51 -0
  198. package/src/language/agentlang-module.ts +75 -0
  199. package/src/language/agentlang-validator.ts +60 -0
  200. package/src/language/agentlang.langium +178 -0
  201. package/src/language/generated/ast.ts +1698 -0
  202. package/src/language/generated/grammar.ts +4477 -0
  203. package/src/language/generated/module.ts +25 -0
  204. package/src/language/main-browser.ts +19 -0
  205. package/src/language/main.ts +13 -0
  206. package/src/language/parser.ts +329 -0
  207. package/src/language/syntax.ts +646 -0
  208. package/src/runtime/agents/common.ts +177 -0
  209. package/src/runtime/agents/impl/openai.ts +19 -0
  210. package/src/runtime/agents/provider.ts +58 -0
  211. package/src/runtime/agents/registry.ts +9 -0
  212. package/src/runtime/auth/cognito.ts +225 -0
  213. package/src/runtime/auth/defs.ts +33 -0
  214. package/src/runtime/auth/interface.ts +31 -0
  215. package/src/runtime/defs.ts +33 -0
  216. package/src/runtime/interpreter.ts +1352 -0
  217. package/src/runtime/loader.ts +450 -0
  218. package/src/runtime/logger.ts +51 -0
  219. package/src/runtime/module.ts +2188 -0
  220. package/src/runtime/modules/ai.ts +257 -0
  221. package/src/runtime/modules/auth.ts +489 -0
  222. package/src/runtime/modules/core.ts +95 -0
  223. package/src/runtime/relgraph.ts +195 -0
  224. package/src/runtime/resolvers/interface.ts +160 -0
  225. package/src/runtime/resolvers/registry.ts +30 -0
  226. package/src/runtime/resolvers/sqldb/database.ts +823 -0
  227. package/src/runtime/resolvers/sqldb/dbutil.ts +257 -0
  228. package/src/runtime/resolvers/sqldb/impl.ts +471 -0
  229. package/src/runtime/state.ts +87 -0
  230. package/src/runtime/util.ts +513 -0
  231. package/src/setupClassic.ts +43 -0
  232. package/src/setupCommon.ts +33 -0
  233. package/src/setupExtended.ts +79 -0
  234. package/src/syntaxes/agentlang.monarch.ts +31 -0
  235. package/src/utils/fs/index.ts +28 -0
  236. package/src/utils/fs/interfaces.ts +118 -0
  237. package/src/utils/fs/lightning-fs.ts +284 -0
  238. package/src/utils/fs/node-fs.ts +185 -0
  239. package/src/utils/fs-utils.ts +304 -0
  240. package/src/utils/runtime.ts +43 -0
@@ -0,0 +1,450 @@
1
+ import chalk from 'chalk';
2
+ import { createAgentlangServices } from '../language/agentlang-module.js';
3
+ import {
4
+ Import,
5
+ RbacSpecEntries,
6
+ RbacSpecEntry,
7
+ RbacOpr,
8
+ ModuleDefinition,
9
+ Definition,
10
+ isEntityDefinition,
11
+ isEventDefinition,
12
+ isRecordDefinition,
13
+ isRelationshipDefinition,
14
+ isWorkflowDefinition,
15
+ EntityDefinition,
16
+ RelationshipDefinition,
17
+ WorkflowDefinition,
18
+ RbacSpecDefinition,
19
+ Statement,
20
+ isStandaloneStatement,
21
+ SchemaDefinition,
22
+ } from '../language/generated/ast.js';
23
+ import {
24
+ addEntity,
25
+ addEvent,
26
+ addModule,
27
+ addRecord,
28
+ addRelationship,
29
+ addWorkflow,
30
+ Entity,
31
+ RbacSpecification,
32
+ Record,
33
+ Relationship,
34
+ Module,
35
+ Workflow,
36
+ isModule,
37
+ getUserModuleNames,
38
+ removeModule,
39
+ } from './module.js';
40
+ import {
41
+ findRbacSchema,
42
+ importModule,
43
+ makeFqName,
44
+ maybeExtends,
45
+ registerInitFunction,
46
+ runShellCommand,
47
+ //runShellCommand,
48
+ } from './util.js';
49
+ import { getFileSystem, toFsPath, readFile, readdir, exists } from '../utils/fs-utils.js';
50
+ import { URI } from 'vscode-uri';
51
+ import { AstNode, LangiumCoreServices, LangiumDocument } from 'langium';
52
+ import { isNodeEnv, path } from '../utils/runtime.js';
53
+ import { CoreModules, registerCoreModules } from './modules/core.js';
54
+ import { parse, parseModule } from '../language/parser.js';
55
+ import { logger } from './logger.js';
56
+ import { Environment, evaluateStatements, GlobalEnvironment } from './interpreter.js';
57
+ import { createPermission, createRole } from './modules/auth.js';
58
+
59
+ export async function extractDocument(
60
+ fileName: string,
61
+ services: LangiumCoreServices
62
+ ): Promise<LangiumDocument> {
63
+ const extensions = services.LanguageMetaData.fileExtensions;
64
+
65
+ if (isNodeEnv && typeof fileName === 'string') {
66
+ if (!extensions.includes(path.extname(fileName))) {
67
+ console.error(
68
+ chalk.yellow(`Please choose a file with one of these extensions: ${extensions}.`)
69
+ );
70
+ process.exit(1);
71
+ }
72
+
73
+ const fullFilePath = path.resolve(fileName);
74
+
75
+ const fileExists = await exists(fullFilePath);
76
+
77
+ if (!fileExists) {
78
+ const errorMsg = `File ${fileName} does not exist.`;
79
+ if (chalk) {
80
+ console.error(chalk.red(errorMsg));
81
+ } else {
82
+ console.error(errorMsg);
83
+ }
84
+ throw new Error(errorMsg);
85
+ }
86
+ } else if (!isNodeEnv && typeof fileName === 'string') {
87
+ const fullFilePath = path.resolve(fileName);
88
+
89
+ const fileExists = await exists(fullFilePath);
90
+
91
+ if (!fileExists) {
92
+ console.error(`File ${fileName} does not exist.`);
93
+ }
94
+ } else {
95
+ throw new Error('Invalid input: expected file path (Node.js) or File object/content (browser)');
96
+ }
97
+
98
+ const document = await services.shared.workspace.LangiumDocuments.getOrCreateDocument(
99
+ URI.file(path.resolve(fileName))
100
+ );
101
+
102
+ // Build document
103
+ await services.shared.workspace.DocumentBuilder.build([document], {
104
+ validation: true,
105
+ });
106
+
107
+ // Handle validation errors
108
+ const validationErrors = (document.diagnostics ?? []).filter(e => e.severity === 1);
109
+
110
+ if (validationErrors.length > 0) {
111
+ console.error(
112
+ isNodeEnv && chalk
113
+ ? chalk.red('There are validation errors:')
114
+ : 'There are validation errors:'
115
+ );
116
+
117
+ for (const validationError of validationErrors) {
118
+ const errorMsg = `line ${validationError.range.start.line + 1}: ${
119
+ validationError.message
120
+ } [${document.textDocument.getText(validationError.range)}]`;
121
+ if (isNodeEnv && chalk) {
122
+ console.error(chalk.red(errorMsg));
123
+ } else {
124
+ console.error(errorMsg);
125
+ }
126
+ }
127
+
128
+ throw new Error('Validation errors found');
129
+ }
130
+
131
+ return document;
132
+ }
133
+
134
+ export async function extractAstNode<T extends AstNode>(
135
+ fileName: string,
136
+ services: LangiumCoreServices
137
+ ): Promise<T> {
138
+ return (await extractDocument(fileName, services)).parseResult?.value as T;
139
+ }
140
+
141
+ export type ApplicationSpec = any;
142
+
143
+ export const DefaultAppSpec: ApplicationSpec = {
144
+ name: 'agentlang-app',
145
+ version: '0.0.1',
146
+ };
147
+
148
+ async function loadApp(appDir: string, fsOptions?: any, callback?: Function): Promise<string> {
149
+ // Initialize filesystem if not already done
150
+ const fs = await getFileSystem(fsOptions);
151
+
152
+ const appJsonFile = `${appDir}${path.sep}package.json`;
153
+ const s: string = await fs.readFile(appJsonFile);
154
+ const appSpec: ApplicationSpec = JSON.parse(s);
155
+ const alFiles: Array<string> = new Array<string>();
156
+ const directoryContents = await fs.readdir(appDir);
157
+ let lastModuleLoaded: string = '';
158
+ async function cont2() {
159
+ if (!directoryContents) {
160
+ console.error(chalk.red(`Directory ${appDir} does not exist or is empty.`));
161
+ return;
162
+ }
163
+ directoryContents.forEach(file => {
164
+ if (path.extname(file) == '.al') {
165
+ alFiles.push(appDir + path.sep + file);
166
+ }
167
+ });
168
+ for (let i = 0; i < alFiles.length; ++i) {
169
+ lastModuleLoaded = (await loadModule(alFiles[i], fsOptions)).name;
170
+ }
171
+ if (callback) await callback(appSpec);
172
+ }
173
+ if (appSpec.dependencies != undefined) {
174
+ if (isNodeEnv) {
175
+ // Only run shell commands in Node.js environment
176
+ for (const [depName, depVer] of Object.entries(appSpec.dependencies)) {
177
+ runShellCommand(`npm install ${depName}@${depVer}`, undefined, cont2);
178
+ }
179
+ } else {
180
+ // In non-Node environments, log a warning and continue
181
+ console.warn('Dependencies cannot be installed in non-Node.js environments');
182
+ await cont2();
183
+ }
184
+ } else {
185
+ await cont2();
186
+ }
187
+ return appSpec.name || lastModuleLoaded;
188
+ }
189
+
190
+ /**
191
+ * Load a module from a file
192
+ * @param fileName Path to the file containing the module
193
+ * @param fsOptions Optional configuration for the filesystem
194
+ * @param callback Function to be called after loading the module
195
+ * @returns Promise that resolves when the module is loaded
196
+ */
197
+ export async function load(
198
+ fileName: string,
199
+ fsOptions?: any,
200
+ callback?: Function
201
+ ): Promise<ApplicationSpec> {
202
+ let result: string = '';
203
+ if (path.basename(fileName).endsWith('.al')) {
204
+ result = (await loadModule(fileName, fsOptions, callback)).name;
205
+ } else {
206
+ result = await loadApp(fileName, fsOptions, callback);
207
+ }
208
+ return { name: result, version: '0.0.1' };
209
+ }
210
+
211
+ /**
212
+ * Removes all existing user-modules and loads the specified module-file.
213
+ * @param fileName Path to the file containing the module
214
+ * @param fsOptions Optional configuration for the filesystem
215
+ * @param callback Function to be called after loading the module
216
+ * @returns Promise that resolves when the module is loaded
217
+ */
218
+ export async function flushAllAndLoad(
219
+ fileName: string,
220
+ fsOptions?: any,
221
+ callback?: Function
222
+ ): Promise<ApplicationSpec> {
223
+ getUserModuleNames().forEach((n: string) => {
224
+ removeModule(n);
225
+ });
226
+ return await load(fileName, fsOptions, callback);
227
+ }
228
+
229
+ export async function loadCoreModules() {
230
+ if (CoreModules.length == 0) {
231
+ registerCoreModules();
232
+ }
233
+ for (let i = 0; i < CoreModules.length; ++i) {
234
+ internModule(await parseModule(CoreModules[i]));
235
+ }
236
+ }
237
+
238
+ async function loadModule(fileName: string, fsOptions?: any, callback?: Function): Promise<Module> {
239
+ // Initialize filesystem if not already done
240
+ const fs = await getFileSystem(fsOptions);
241
+
242
+ const fsAdapter = getFsAdapter(fs);
243
+
244
+ // Create services with our custom filesystem adapter
245
+ const services = createAgentlangServices({
246
+ fileSystemProvider: _services => fsAdapter,
247
+ }).Agentlang;
248
+
249
+ // Extract the AST node
250
+ const module = await extractAstNode<ModuleDefinition>(fileName, services);
251
+ const result: Module = internModule(module);
252
+ console.log(chalk.green(`Module ${chalk.bold(result.name)} loaded`));
253
+ logger.info(`Module ${result.name} loaded`);
254
+ if (callback) {
255
+ await callback();
256
+ }
257
+ return result;
258
+ }
259
+
260
+ let cachedFsAdapter: any = null;
261
+
262
+ function getFsAdapter(fs: any) {
263
+ if (cachedFsAdapter == null) {
264
+ // Create an adapter to make our filesystem compatible with Langium
265
+ cachedFsAdapter = {
266
+ // Read file contents as text
267
+ readFile: async (uri: URI) => {
268
+ return await readFile(uri);
269
+ },
270
+
271
+ // List directory contents with proper metadata
272
+ readDirectory: async (uri: URI) => {
273
+ const result = await readdir(uri);
274
+ const dirPath = toFsPath(uri);
275
+
276
+ // Convert string[] to FileSystemNode[] as required by Langium
277
+ return Promise.all(
278
+ result.map(async name => {
279
+ const filePath = dirPath.endsWith('/') ? `${dirPath}${name}` : `${dirPath}/${name}`;
280
+ const stats = await fs
281
+ .stat(filePath)
282
+ .catch(() => ({ isFile: () => true, isDirectory: () => false }));
283
+
284
+ return {
285
+ uri: URI.file(filePath),
286
+ isFile: stats.isFile?.() ?? true,
287
+ isDirectory: stats.isDirectory?.() ?? false,
288
+ };
289
+ })
290
+ );
291
+ },
292
+ };
293
+ }
294
+ return cachedFsAdapter;
295
+ }
296
+
297
+ function setRbacForEntity(entity: Entity, rbacSpec: RbacSpecDefinition) {
298
+ const rbac: RbacSpecification[] = new Array<RbacSpecification>();
299
+ rbacSpec.specEntries.forEach((specEntries: RbacSpecEntries) => {
300
+ const rs: RbacSpecification = new RbacSpecification().setResource(
301
+ makeFqName(entity.moduleName, entity.name)
302
+ );
303
+ specEntries.entries.forEach((spec: RbacSpecEntry) => {
304
+ if (spec.allow) {
305
+ rs.setPermissions(
306
+ spec.allow.oprs.map((v: RbacOpr) => {
307
+ return v.value;
308
+ })
309
+ );
310
+ } else if (spec.role) {
311
+ rs.setRoles(spec.role.roles);
312
+ } else if (spec.expr) {
313
+ rs.setExpression(spec.expr.lhs, spec.expr.rhs);
314
+ }
315
+ });
316
+ rbac.push(rs);
317
+ });
318
+ if (rbac.length > 0) {
319
+ const f = async () => {
320
+ for (let i = 0; i < rbac.length; ++i) {
321
+ await createRolesAndPermissions(rbac[i]);
322
+ }
323
+ };
324
+ registerInitFunction(f);
325
+ entity.setRbacSpecifications(rbac);
326
+ }
327
+ }
328
+
329
+ async function createRolesAndPermissions(rbacSpec: RbacSpecification) {
330
+ const roles: Array<string> = [...rbacSpec.roles];
331
+ const env: Environment = new Environment();
332
+ async function f() {
333
+ for (let i = 0; i < roles.length; ++i) {
334
+ const r = roles[i];
335
+ await createRole(r, env);
336
+ if (rbacSpec.hasPermissions() && rbacSpec.hasResource()) {
337
+ await createPermission(
338
+ `${r}_permission_${rbacSpec.resource}`,
339
+ r,
340
+ rbacSpec.resource,
341
+ rbacSpec.hasCreatePermission(),
342
+ rbacSpec.hasReadPermission(),
343
+ rbacSpec.hasUpdatePermission(),
344
+ rbacSpec.hasDeletePermission(),
345
+ env
346
+ );
347
+ }
348
+ }
349
+ }
350
+ await env.callInTransaction(f);
351
+ }
352
+
353
+ function addEntityFromDef(def: EntityDefinition, moduleName: string): Entity {
354
+ const entity = addEntity(def.name, moduleName, def.schema, maybeExtends(def.extends));
355
+ const rbacSpec = findRbacSchema(def.schema);
356
+ if (rbacSpec) {
357
+ setRbacForEntity(entity, rbacSpec);
358
+ }
359
+ return entity;
360
+ }
361
+
362
+ export function addSchemaFromDef(def: SchemaDefinition, moduleName: string): Record {
363
+ let result: Record | undefined;
364
+ if (isEntityDefinition(def)) {
365
+ result = addEntityFromDef(def, moduleName);
366
+ } else if (isEventDefinition(def)) {
367
+ result = addEvent(def.name, moduleName, def.schema, maybeExtends(def.extends));
368
+ } else {
369
+ result = addRecord(def.name, moduleName, def.schema, maybeExtends(def.extends));
370
+ }
371
+ return result;
372
+ }
373
+
374
+ export function addRelationshipFromDef(
375
+ def: RelationshipDefinition,
376
+ moduleName: string
377
+ ): Relationship {
378
+ return addRelationship(def.name, def.type, def.nodes, moduleName, def.schema, def.properties);
379
+ }
380
+
381
+ export function addWorkflowFromDef(def: WorkflowDefinition, moduleName: string): Workflow {
382
+ return addWorkflow(def.name, moduleName, def.statements);
383
+ }
384
+
385
+ const StandaloneStatements = new Map<string, Statement[]>();
386
+
387
+ function addStandaloneStatement(stmt: Statement, moduleName: string) {
388
+ let stmts: Array<Statement> | undefined = StandaloneStatements.get(moduleName);
389
+ if (stmts == undefined) {
390
+ stmts = new Array<Statement>();
391
+ }
392
+ stmts.push(stmt);
393
+ if (!StandaloneStatements.has(moduleName)) {
394
+ StandaloneStatements.set(moduleName, stmts);
395
+ }
396
+ }
397
+
398
+ export async function runStandaloneStatements() {
399
+ if (StandaloneStatements.size > 0) {
400
+ await GlobalEnvironment.callInTransaction(async () => {
401
+ const ks = [...StandaloneStatements.keys()];
402
+ for (let i = 0; i < ks.length; ++i) {
403
+ const moduleName = ks[i];
404
+ const stmts: Statement[] | undefined = StandaloneStatements.get(moduleName);
405
+ if (stmts) {
406
+ const oldModule = GlobalEnvironment.switchActiveModuleName(moduleName);
407
+ await evaluateStatements(stmts, GlobalEnvironment);
408
+ GlobalEnvironment.switchActiveModuleName(oldModule);
409
+ }
410
+ }
411
+ logger.info(`Init eval result: ${GlobalEnvironment.getLastResult().toString()}`);
412
+ });
413
+ StandaloneStatements.clear();
414
+ }
415
+ }
416
+
417
+ export function addFromDef(def: Definition, moduleName: string) {
418
+ if (isEntityDefinition(def)) addSchemaFromDef(def, moduleName);
419
+ else if (isEventDefinition(def)) addSchemaFromDef(def, moduleName);
420
+ else if (isRecordDefinition(def)) addSchemaFromDef(def, moduleName);
421
+ else if (isRelationshipDefinition(def)) addRelationshipFromDef(def, moduleName);
422
+ else if (isWorkflowDefinition(def)) addWorkflowFromDef(def, moduleName);
423
+ else if (isStandaloneStatement(def)) addStandaloneStatement(def.stmt, moduleName);
424
+ }
425
+
426
+ export async function parseAndIntern(code: string, moduleName?: string) {
427
+ if (moduleName && !isModule(moduleName)) {
428
+ throw new Error(`Module not found - ${moduleName}`);
429
+ }
430
+ const r = await parse(moduleName ? `module ${moduleName} ${code}` : code);
431
+ if (r.parseResult.lexerErrors.length > 0) {
432
+ throw new Error(`Lexer errors: ${r.parseResult.lexerErrors.join('\n')}`);
433
+ }
434
+ if (r.parseResult.parserErrors.length > 0) {
435
+ throw new Error(`Parser errors: ${r.parseResult.parserErrors.join('\n')}`);
436
+ }
437
+ internModule(r.parseResult.value);
438
+ }
439
+
440
+ export function internModule(module: ModuleDefinition): Module {
441
+ const mn = module.name;
442
+ const r = addModule(mn);
443
+ module.imports.forEach(async (imp: Import) => {
444
+ await importModule(imp.path, imp.name);
445
+ });
446
+ module.defs.forEach((def: Definition) => {
447
+ addFromDef(def, mn);
448
+ });
449
+ return r;
450
+ }
@@ -0,0 +1,51 @@
1
+ import { isNodeEnv } from '../utils/runtime.js';
2
+
3
+ let DailyRotateFile: any;
4
+ let winston: any;
5
+
6
+ if (isNodeEnv) {
7
+ // Only import Node.js modules in Node environment
8
+ // Using dynamic imports to avoid breaking browser bundling
9
+ await import('winston-daily-rotate-file').then(module => {
10
+ DailyRotateFile = module.default;
11
+ });
12
+ await import('winston').then(module => {
13
+ winston = module.default;
14
+ });
15
+ }
16
+
17
+ export let logger: any;
18
+
19
+ if (isNodeEnv) {
20
+ const fileTransport = new DailyRotateFile({
21
+ level: 'debug',
22
+ filename: 'logs/app-%DATE%.log',
23
+ datePattern: 'YYYY-MM-DD',
24
+ maxSize: '20m',
25
+ maxFiles: '7d',
26
+ });
27
+
28
+ const consoleTransport = new winston.transports.Console();
29
+
30
+ logger = winston.createLogger({
31
+ format: winston.format.combine(
32
+ winston.format.timestamp(),
33
+ winston.format.printf(({ timestamp, level, message }: any) => {
34
+ return `[${timestamp}] ${level}: ${message}`;
35
+ })
36
+ ),
37
+ transports: [fileTransport, consoleTransport],
38
+ });
39
+ } else {
40
+ function mkLogger(tag: string): Function {
41
+ return (msg: string) => {
42
+ console.log(`${tag}: ${msg}`);
43
+ };
44
+ }
45
+ logger = {
46
+ debug: mkLogger('DEBUG'),
47
+ info: mkLogger('INFO'),
48
+ warn: mkLogger('WARN'),
49
+ error: mkLogger('ERROR'),
50
+ };
51
+ }