@fnet/cli 0.101.0 → 0.101.1

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 (71) hide show
  1. package/dist/fnet/index.B5XE4ChJ.js +1 -0
  2. package/dist/fnet/index.Bfg4lyu-.js +1 -0
  3. package/dist/fnet/index.Bn6hEUL-.js +1 -0
  4. package/dist/fnet/index.BoO2Mnox.js +1 -0
  5. package/dist/fnet/index.C7saWH6d.js +1 -0
  6. package/dist/fnet/index.CDct_kkF.js +1 -0
  7. package/dist/fnet/index.CMC8mlye.js +1 -0
  8. package/dist/fnet/index.CmMM-Ek9.js +1 -0
  9. package/dist/fnet/index.CzAV0S36.js +1 -0
  10. package/dist/fnet/index.D2N9YZmA.js +1 -0
  11. package/dist/fnet/index.DI3yyTtl.js +1 -0
  12. package/dist/fnet/index.DLGSTm8o.js +1 -0
  13. package/dist/fnet/index.Q-CYRcna.js +1 -0
  14. package/dist/fnet/index.UOds5XLl.js +1 -0
  15. package/dist/fnet/index.W6RYgypK.js +1 -0
  16. package/dist/fnet/index.dpz2QIRu.js +1 -0
  17. package/dist/fnet/index.js +1 -4561
  18. package/dist/fnet/index.xd8c7XMr.js +1 -0
  19. package/dist/fnode/index.B5XE4ChJ.js +1 -0
  20. package/dist/fnode/index.Bfg4lyu-.js +1 -0
  21. package/dist/fnode/index.BoO2Mnox.js +1 -0
  22. package/dist/fnode/index.C7saWH6d.js +1 -0
  23. package/dist/fnode/index.CDct_kkF.js +1 -0
  24. package/dist/fnode/index.CMC8mlye.js +1 -0
  25. package/dist/fnode/index.CmMM-Ek9.js +1 -0
  26. package/dist/fnode/index.CzAV0S36.js +1 -0
  27. package/dist/fnode/index.D2N9YZmA.js +1 -0
  28. package/dist/fnode/index.DI3yyTtl.js +1 -0
  29. package/dist/fnode/index.DLGSTm8o.js +1 -0
  30. package/dist/fnode/index.DhIcnnpM.js +1 -0
  31. package/dist/fnode/index.Q-CYRcna.js +1 -0
  32. package/dist/fnode/index.UOds5XLl.js +1 -0
  33. package/dist/fnode/index.W6RYgypK.js +1 -0
  34. package/dist/fnode/index.dpz2QIRu.js +1 -0
  35. package/dist/fnode/index.js +1 -2783
  36. package/dist/fnode/index.xd8c7XMr.js +1 -0
  37. package/package.json +1 -1
  38. package/dist/fnet/index.B5vpZn1Z.js +0 -53
  39. package/dist/fnet/index.B6WHm9H0.js +0 -106
  40. package/dist/fnet/index.B90Vm9uq.js +0 -114
  41. package/dist/fnet/index.BMsD46br.js +0 -60
  42. package/dist/fnet/index.BUhoGq-h.js +0 -70
  43. package/dist/fnet/index.BjzEMdm1.js +0 -52
  44. package/dist/fnet/index.C9zKEF61.js +0 -106
  45. package/dist/fnet/index.CQNYMi1Z.js +0 -51
  46. package/dist/fnet/index.CX8eMqfH.js +0 -191
  47. package/dist/fnet/index.Ce8sTnt_.js +0 -52
  48. package/dist/fnet/index.D2kFuxXo.js +0 -52
  49. package/dist/fnet/index.D61MduW1.js +0 -106
  50. package/dist/fnet/index.Dd0lngp8.js +0 -41
  51. package/dist/fnet/index.DqwVukIB.js +0 -52
  52. package/dist/fnet/index.MWHLt6g3.js +0 -52
  53. package/dist/fnet/index.f798DPwo.js +0 -93
  54. package/dist/fnet/index.j5JP-zGw.js +0 -52
  55. package/dist/fnode/index.B5vpZn1Z.js +0 -53
  56. package/dist/fnode/index.B6WHm9H0.js +0 -106
  57. package/dist/fnode/index.BMsD46br.js +0 -60
  58. package/dist/fnode/index.BNSTS5o6.js +0 -109
  59. package/dist/fnode/index.BUhoGq-h.js +0 -70
  60. package/dist/fnode/index.BjzEMdm1.js +0 -52
  61. package/dist/fnode/index.C9zKEF61.js +0 -106
  62. package/dist/fnode/index.CQNYMi1Z.js +0 -51
  63. package/dist/fnode/index.CX8eMqfH.js +0 -191
  64. package/dist/fnode/index.Ce8sTnt_.js +0 -52
  65. package/dist/fnode/index.D2kFuxXo.js +0 -52
  66. package/dist/fnode/index.D61MduW1.js +0 -106
  67. package/dist/fnode/index.Dd0lngp8.js +0 -41
  68. package/dist/fnode/index.DqwVukIB.js +0 -52
  69. package/dist/fnode/index.MWHLt6g3.js +0 -52
  70. package/dist/fnode/index.f798DPwo.js +0 -93
  71. package/dist/fnode/index.j5JP-zGw.js +0 -52
@@ -1,4562 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import { spawn } from 'child_process';
3
- import prompt from '@fnet/prompt';
4
- import fs, { existsSync } from 'node:fs';
5
- import path, { delimiter, join } from 'node:path';
6
- import fnetConfig from '@fnet/config';
7
- import { fileURLToPath } from 'node:url';
8
- import { Command, Option } from 'commander';
9
- import fs$1 from 'fs';
10
- import yaml from 'yaml';
11
- import fnetShellJs from '@fnet/shelljs';
12
- import fnetYaml from '@fnet/yaml';
13
- import fnetObjectFromSchema from '@fnet/object-from-schema';
14
- import fnetShellFlow from '@fnet/shell-flow';
15
- import fnetRender from '@flownet/lib-render-templates-dir';
16
- import nunjucks from 'nunjucks';
17
- import cloneDeep from 'lodash.clonedeep';
18
- import isObject from 'isobject';
19
- import redis from 'redis';
20
- import fnetIsRedisOnline from '@flownet/lib-is-redis-online';
21
- import { randomUUID } from 'node:crypto';
22
- import { Api, Atom } from '@flownet/lib-atom-api-js';
23
- import merge from 'lodash.merge';
24
- import fnetParseImports from '@flownet/lib-parse-imports-js';
25
- import fnetListNpmVersions from '@fnet/npm-list-versions';
26
- import fnetPickNpmVersions from '@fnet/npm-pick-versions';
27
- import hash from 'object-hash';
28
- import Ajv from 'ajv/dist/2020.js';
29
- import standaloneCode from 'ajv/dist/standalone/index.js';
30
- import addFormats from 'ajv-formats';
31
- import path$1 from 'path';
32
- import fnetParseNodeUrl from '@flownet/lib-parse-node-url';
33
- import BpmnModdle from 'bpmn-moddle';
34
- import dagre from 'dagre';
35
- import fnetExpression from '@fnet/expression';
36
- import chalk from 'chalk';
37
- import fnetListFiles from '@fnet/list-files';
38
- import fnetKvTransformer from '@fnet/key-value-transformer';
39
- import pick from 'lodash.pick';
40
- import omit from 'lodash.omit';
41
-
42
- var which = (binName) => {
43
- const pathEnv = process.env.PATH || '';
44
- const pathExt = process.platform === 'win32'
45
- ? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';')
46
- : [''];
47
-
48
- const paths = pathEnv.split(delimiter);
49
-
50
- for (const dir of paths) {
51
- for (const ext of pathExt) {
52
- const fullPath = join(dir, process.platform === 'win32' ? binName + ext : binName);
53
- if (existsSync(fullPath)) {
54
- return fullPath;
55
- }
56
- }
57
- }
58
-
59
- return null;
60
- };
61
-
62
- var version = "0.101.0";
63
- var pkg = {
64
- version: version};
65
-
66
- async function createRedisClient() {
67
- const isOnline = await fnetIsRedisOnline({ host: process.env.REDIS_HOST, port: process.env.REDIS_PORT });
68
- if (!isOnline) return;
69
-
70
- const redisClient = redis.createClient({
71
- socket: { host: process.env.REDIS_HOST, port: process.env.REDIS_PORT }
72
- });
73
- await redisClient.connect();
74
-
75
- return redisClient;
76
- }
77
-
78
- class Auth {
79
- init({ config, accessToken }) {
80
- return new Promise((resolve, reject) => {
81
-
82
- Api.set_api_url(config.data.url);
83
-
84
- if (accessToken) {
85
- Api.set_req_token(accessToken);
86
- resolve(accessToken);
87
- return;
88
- }
89
-
90
- fetch(`${config.data.issuer}/protocol/openid-connect/token`, {
91
- method: "POST",
92
- headers: {
93
- "Content-Type": "application/x-www-form-urlencoded"
94
- },
95
- body: new URLSearchParams(config.data.grant.params)
96
- })
97
- .then(async (response) => {
98
- if (!response.ok) throw new Error(await response.text());
99
- return response.json();
100
- })
101
- .then(response => {
102
- Api.set_req_token(response.access_token);
103
- resolve(response.access_token);
104
- })
105
- .catch(error => {
106
- Api.set_req_token();
107
- reject(error);
108
- });
109
- });
110
- }
111
- }
112
-
113
- function featureTemplate({ feature, features, packageDevDependencies }) {
114
-
115
- const { name, packages, options, extraCheck, explicit } = feature;
116
-
117
- const keyEnabled = `${name}_enabled`;
118
-
119
- const rollup_output = features.rollup_output || {};
120
-
121
- const allKeys = Object.keys(rollup_output);
122
-
123
- let initialOptions = options || {};
124
-
125
- const featureOptions = features[name]?.options;
126
-
127
- if (featureOptions) initialOptions = merge(initialOptions, featureOptions);
128
-
129
- const globallyDisabled = !features[name] || features[name]?.enabled === false;
130
-
131
- allKeys.forEach(key => {
132
- const output = features.rollup_output[key];
133
-
134
- if (!output) return;
135
-
136
- // Output has the feature
137
- if (Reflect.has(output, name)) {
138
- if (globallyDisabled || !output[name] || output[name]?.enabled === false) {
139
- delete output[name];
140
- return;
141
- }
142
- if (output[name] === true) {
143
- output[name] = {
144
- enabled: true,
145
- options: initialOptions
146
- };
147
- }
148
- } else {
149
- // Output hasn't the feature
150
- if (!globallyDisabled && !explicit && features[keyEnabled] !== false) {
151
- output[name] = {
152
- enabled: true,
153
- };
154
- }
155
- else return;
156
- }
157
- output[name] = output[name] || {};
158
- output[name].options = {
159
- ...initialOptions,
160
- ...output[name].options
161
- };
162
- });
163
-
164
- let exists = allKeys.some(w => features.rollup_output[w][name]?.enabled === true);
165
-
166
- if (extraCheck) exists = extraCheck() && exists;
167
-
168
- features[keyEnabled] = exists;
169
-
170
- if (exists) {
171
- packages.forEach(p => packageDevDependencies.push({ package: p[0], version: p[1] }));
172
- }
173
- }
174
-
175
- function initWorkboxFeature(apiContext) {
176
-
177
- const { atom, packageDevDependencies } = apiContext;
178
- const features = atom.doc.features;
179
-
180
- featureTemplate({
181
- feature: {
182
- name: "workbox",
183
- packages: [["rollup-plugin-workbox", "^8"]],
184
- options: {
185
- generate: {
186
- swDest: 'dist/app/esm/sw.js',
187
- globDirectory: 'dist/app/esm',
188
- globPatterns: ['**/*.{html,js,css,png,jpg}'],
189
- skipWaiting: true,
190
- clientsClaim: true
191
- }
192
- },
193
- explicit: true
194
- }, features, packageDevDependencies
195
- });
196
- }
197
-
198
- function initGzipFeature(apiContext) {
199
-
200
- const { atom, packageDevDependencies } = apiContext;
201
- const features = atom.doc.features;
202
-
203
- featureTemplate({
204
- feature: {
205
- name: "gzip",
206
- packages: [["rollup-plugin-gzip", "^4"]],
207
- explicit: true
208
- }, features, packageDevDependencies
209
- });
210
- }
211
-
212
- function initNunjucksFeature(apiContext) {
213
-
214
- const { atom, packageDevDependencies } = apiContext;
215
- const features = atom.doc.features;
216
-
217
- featureTemplate({
218
- feature: {
219
- name: "nunjucks",
220
- packages: [["@fnet/rollup-plugin-nunjucks", "0.1.8"]],
221
- }, features, packageDevDependencies
222
- });
223
- }
224
-
225
- function initPolyfillFeature(apiContext) {
226
-
227
- const { atom, packageDevDependencies } = apiContext;
228
- const features = atom.doc.features;
229
-
230
- featureTemplate({
231
- feature: {
232
- name: "polyfill",
233
- packages: [["rollup-plugin-node-polyfills", "^0.2"]],
234
- }, features, packageDevDependencies
235
- });
236
- }
237
-
238
- function initVisualizerFeature(apiContext) {
239
-
240
- const { atom, packageDevDependencies } = apiContext;
241
- const features = atom.doc.features;
242
-
243
- featureTemplate({
244
- feature: {
245
- name: "visualizer",
246
- packages: [["rollup-plugin-visualizer", "^5"]]}, features, packageDevDependencies
247
- });
248
- }
249
-
250
- function initAnalyzerFeature(apiContext) {
251
- const { atom, packageDevDependencies } = apiContext;
252
- const features = atom.doc.features;
253
-
254
- featureTemplate({
255
- feature: {
256
- name: "analyzer",
257
- packages: [["rollup-plugin-analyzer", "^3"]],
258
- options: {
259
- summaryOnly: true,
260
- limit: 12
261
- },
262
- explicit: true
263
- }, features, packageDevDependencies
264
- });
265
- }
266
-
267
- function initStringFeature(apiContext) {
268
-
269
- const { atom, packageDevDependencies } = apiContext;
270
- const features = atom.doc.features;
271
-
272
- featureTemplate({
273
- feature: {
274
- name: "string",
275
- packages: [["rollup-plugin-string", "^3"]],
276
- }, features, packageDevDependencies
277
- });
278
- }
279
-
280
- function initImageFeature(apiContext) {
281
-
282
- const { atom, packageDevDependencies } = apiContext;
283
- const features = atom.doc.features;
284
-
285
- featureTemplate({
286
- feature: {
287
- name: "image",
288
- packages: [["@rollup/plugin-image", "^3"]],
289
- }, features, packageDevDependencies
290
- });
291
- }
292
-
293
- function initJsonFeature(apiContext) {
294
-
295
- const { atom, packageDevDependencies } = apiContext;
296
- const features = atom.doc.features;
297
-
298
- featureTemplate({
299
- feature: {
300
- name: "json",
301
- packages: [["@rollup/plugin-json", "^6"]],
302
- }, features, packageDevDependencies
303
- });
304
- }
305
-
306
- function initTerserFeature(apiContext) {
307
-
308
- const { atom, packageDevDependencies } = apiContext;
309
- const features = atom.doc.features;
310
-
311
- featureTemplate({
312
- feature: {
313
- name: "terser",
314
- packages: [["@rollup/plugin-terser", "^0.4"]],
315
- }, features, packageDevDependencies
316
- });
317
- }
318
-
319
- function initWasmFeature(apiContext) {
320
-
321
- const { atom, packageDevDependencies } = apiContext;
322
- const features = atom.doc.features;
323
-
324
- featureTemplate({
325
- feature: {
326
- name: "wasm",
327
- packages: [["@rollup/plugin-wasm", "^6"]],
328
- }, features, packageDevDependencies
329
- });
330
- }
331
-
332
- function initCopyFeature(apiContext) {
333
-
334
- const { atom, packageDevDependencies } = apiContext;
335
- const features = atom.doc.features;
336
-
337
- const options = {};
338
-
339
- // TODO: remove it later
340
- // app specific
341
- if (features.app?.enabled === true) {
342
- options.targets = options.targets || [];
343
- options.targets.push({ src: "./src/app/index.html", dest: features.app.dir });
344
- if (!Reflect.has(features.app, "copy")) {
345
- if (!Reflect.has(features, "copy")) {
346
- features.copy = true;
347
- }
348
- }
349
- }
350
-
351
- // const extraCheck = () => {
352
- // return features.app_enabled;
353
- // }
354
-
355
- featureTemplate({
356
- feature: {
357
- name: "copy",
358
- packages: [["rollup-plugin-copy", "^3"], ["chokidar", "^3"]],
359
- options
360
- // extraCheck
361
- }, features, packageDevDependencies
362
- });
363
- }
364
-
365
- function initCssFeature(apiContext) {
366
-
367
- const { atom, packageDevDependencies } = apiContext;
368
- const features = atom.doc.features;
369
-
370
- const cssEnabled = features.css && features.css.enabled !== false;
371
-
372
- let packages = [];
373
-
374
- if (cssEnabled) {
375
- packages.push(["rollup-plugin-postcss", "^4"]);
376
- packages.push(["sass", "^1.66"]);
377
- const plugins = features.css?.options?.plugins || [];
378
- plugins.forEach(plugin => {
379
- switch (plugin.name) {
380
- case 'postcss-import':
381
- packages.push(["postcss-import", "^15"]);
382
- break;
383
- case 'postcss-url':
384
- packages.push(["postcss-url", "^10"]);
385
- break;
386
- case 'postcss-preset-env':
387
- packages.push(["postcss-preset-env", "^9"]);
388
- break;
389
- case 'autoprefixer':
390
- packages.push(["autoprefixer", "^10"]);
391
- break;
392
- case 'cssnano':
393
- packages.push(["cssnano", "^6"]);
394
- break;
395
- }
396
- });
397
- }
398
-
399
- featureTemplate({
400
- feature: {
401
- name: "css",
402
- packages: packages,
403
- }, features, packageDevDependencies
404
- });
405
- }
406
-
407
- function findEntryFile({ dir, name = 'index' }) {
408
- let entryFile = path.resolve(dir, `./${name}.tsx`);
409
-
410
- if (!fs.existsSync(entryFile)) entryFile = path.resolve(dir, `./${name}.ts`);
411
- if (!fs.existsSync(entryFile)) entryFile = path.resolve(dir, `./${name}.jsx`);
412
- if (!fs.existsSync(entryFile)) entryFile = path.resolve(dir, `./${name}.js`);
413
- if (!fs.existsSync(entryFile)) return {};
414
-
415
- const file = entryFile;
416
- const ext = path.extname(entryFile);
417
- const ts = ext === '.ts' || ext === '.tsx';
418
-
419
- return { file, ext, ts, name };
420
- }
421
- async function initFeatures(apiContext) {
422
-
423
- const { atom, context, setProgress } = apiContext;
424
-
425
- setProgress('Initializing features...');
426
-
427
- atom.doc.features = atom.doc.features || {};
428
- const features = atom.doc.features;
429
-
430
- // project format
431
- features.project = features.project || {};
432
- features.project.format = features.project.format || features.project_format || "esm";
433
- features.project_format = features.project.format;
434
-
435
- features.dts_enabled = features.dts === true || (typeof features.dts !== 'undefined' && features.dts !== false);
436
-
437
- const projectDir = path.resolve(context.project.projectDir);
438
-
439
- const appEntry = findEntryFile({ dir: path.resolve(projectDir, './app') });
440
- if (appEntry.file) {
441
- setProgress('Parsing app entry imports...');
442
-
443
- let parsed = await fnetParseImports({ file: appEntry.file, recursive: true });
444
- let usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
445
- features.app_uses_jsx = usesJSX;
446
- features.app_has_entry = true;
447
- parsed = await fnetParseImports({ file: appEntry.file });
448
- usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
449
- features.app_entry_uses_jsx = usesJSX;
450
- features.app_entry_is_ts = appEntry.ts;
451
- features.app_entry_ext = appEntry.ext;
452
- }
453
-
454
- const cliEntry = findEntryFile({ dir: path.resolve(projectDir, './cli') });
455
- if (cliEntry.file) {
456
- setProgress('Parsing cli entry imports...');
457
-
458
- let parsed = await fnetParseImports({ file: cliEntry.file, recursive: true });
459
- let usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
460
- features.cli_uses_jsx = usesJSX;
461
- features.cli_has_entry = true;
462
- parsed = await fnetParseImports({ file: cliEntry.file });
463
- usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
464
- features.cli_entry_uses_jsx = usesJSX;
465
- features.cli_entry_is_ts = cliEntry.ts;
466
- features.cli_entry_ext = cliEntry.ext;
467
- }
468
-
469
- if (atom.type === 'workflow.lib') {
470
- const srcEntry = findEntryFile({ dir: path.resolve(projectDir, './src') });
471
-
472
- if (srcEntry.file) {
473
- setProgress('Parsing src entry imports...');
474
-
475
- let parsed = await fnetParseImports({ file: srcEntry.file, recursive: true });
476
- let usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
477
- features.src_uses_jsx = usesJSX;
478
- features.src_has_entry = true;
479
- parsed = await fnetParseImports({ file: srcEntry.file });
480
- usesJSX = parsed.all.some(w => w.usesJSX === true && w.type === 'local');
481
- features.src_entry_uses_jsx = usesJSX;
482
- features.src_entry_is_ts = srcEntry.ts;
483
- features.src_entry_ext = srcEntry.ext;
484
- }
485
- }
486
-
487
- const isAppReact = Reflect.has(features, 'app_entry_uses_jsx') ? features.app_entry_uses_jsx === true : features.src_entry_uses_jsx === true;
488
- const isCliReact = Reflect.has(features, 'cli_entry_uses_jsx') ? features.cli_entry_uses_jsx === true : features.src_entry_uses_jsx === true;
489
-
490
- features.form_enabled = (isAppReact || isCliReact) || features.form === true || features.form?.enabled === true;
491
- features.multiple_enabled = features.multiple_enabled || features.multiple === true || features.multiple?.enabled === true;
492
-
493
- // APP PROPS
494
- if (features.app === false) {
495
- features.app = {
496
- enabled: false,
497
- };
498
- } else if (features.app === true) {
499
- features.app = {
500
- enabled: true,
501
- extend: features.app_has_entry === true,
502
- export: true,
503
- react: isAppReact
504
- };
505
- } else features.app = { enabled: true, extend: features.app_has_entry === true, export: true, react: isAppReact, ...(features.app || {}) };
506
-
507
-
508
- features.app.enabled = features.app.enabled === true && (atom.doc.features.form_enabled === true || features.app.extend === true || features.app.enabled === true);
509
- features.app.format = features.app.format || "esm";
510
- features.app.folder = features.app.folder || features.app.format || "default";
511
-
512
- // CLI PROPS
513
- if (features.cli === false) {
514
- features.cli = {
515
- enabled: false
516
- };
517
- } else if (features.cli === true) {
518
- features.cli = {
519
- enabled: true,
520
- extend: features.cli_has_entry === true,
521
- export: true,
522
- react: isCliReact
523
- };
524
- } else features.cli = {
525
- enabled: true,
526
- extend: features.cli_has_entry === true,
527
- export: true,
528
- react: isCliReact, ...(features.cli || {})
529
- };
530
-
531
- features.cli.enabled = features.cli.enabled === true && (atom.doc.features.form_enabled === false || features.cli.extend === true || features.cli.enabled === true);
532
- features.cli.format = features.cli.format || "esm";
533
- features.cli.folder = features.cli.folder || features.cli.folder || "esm";
534
- features.cli.node_options = features.cli.node?.options || features.cli.node_options || '';
535
- features.json = features.cli.enabled || features.json;
536
-
537
- // rollup output default
538
- const rollup_output_default = {
539
- cjs: {
540
- format: "cjs",
541
- context: features.form_enabled ? "window" : "global",
542
- babel: (features.src_uses_jsx === true) || false,
543
- browser: false,
544
- replace: true,
545
- terser: true,
546
- enabled: features.cjs !== false,
547
- copy: false,
548
- },
549
- esm: {
550
- format: "esm",
551
- context: features.form_enabled ? "window" : "global",
552
- babel: (features.src_uses_jsx === true) || false,
553
- browser: false,
554
- replace: true,
555
- terser: false,
556
- enabled: features.esm !== false,
557
- copy: true,
558
- },
559
- iife: {
560
- format: "iife",
561
- context: features.form_enabled ? "window" : "global",
562
- babel: true,
563
- browser: true,
564
- replace: true,
565
- enabled: features.iife === true,
566
- terser: true,
567
- copy: false,
568
- }
569
- };
570
-
571
- // babel targets default
572
- const babel_default = {
573
- targets: {
574
- browsers: "last 9 versions, not dead",
575
- node: "18"
576
- }
577
- };
578
-
579
- // replace default
580
- const replace_default = {};
581
-
582
- // webos default
583
- if (features.webos === true) {
584
- rollup_output_default.webos = {
585
- format: "iife",
586
- browser: true,
587
- babel: true,
588
- context: "window",
589
- replace: true,
590
- terser: true,
591
- input: "./src/app/index.js",
592
- output_dir: `./dist/app/webos`,
593
- copy: false,
594
- babel_options: {
595
- targets: {
596
- chrome: "79"
597
- }
598
- }
599
- };
600
- }
601
-
602
- // electron default
603
- if (features.electron === true) {
604
- rollup_output_default.electron = {
605
- format: "iife",
606
- browser: true,
607
- babel: true,
608
- context: "window",
609
- replace: true,
610
- terser: true,
611
- copy: false,
612
- input: "./src/app/index.js",
613
- output_dir: `./dist/app/electron`,
614
- };
615
- }
616
-
617
- // nextsj default
618
- if (features.nextjs === true) {
619
- rollup_output_default.nextjs = {
620
- format: "esm",
621
- browser: true,
622
- babel: true,
623
- context: "window",
624
- replace: true,
625
- terser: true,
626
- copy: false,
627
- input: "./src/app/index.js",
628
- output_dir: `./dist/app/nextjs`,
629
- };
630
- }
631
-
632
- // ios default
633
- if (features.ios === true) {
634
- rollup_output_default.ios = {
635
- format: "iife",
636
- browser: true,
637
- babel: true,
638
- context: "window",
639
- replace: true,
640
- terser: true,
641
- copy: false,
642
- input: "./src/app/index.js",
643
- output_dir: `./dist/app/ios`,
644
- };
645
- }
646
-
647
- // macos default
648
- if (features.macos === true) {
649
- rollup_output_default.macos = {
650
- format: "iife",
651
- browser: true,
652
- babel: true,
653
- context: "window",
654
- replace: true,
655
- terser: true,
656
- copy: false,
657
- input: "./src/app/index.js",
658
- output_dir: `./dist/app/macos`,
659
- };
660
- }
661
-
662
- // app default
663
- if (features.app.enabled === true) {
664
- features.app.dir = `./dist/app/${features.app.folder}`;
665
-
666
- rollup_output_default.app = {
667
- format: features.app.format,
668
- browser: true,
669
- babel: true,
670
- context: "window",
671
- replace: true,
672
- input: "./src/app/index.js",
673
- output_dir: features.app.dir,
674
- terser: true,
675
- output_exports: features.app.export === false ? "none" : "auto",
676
- browsersync: true,
677
- };
678
- }
679
-
680
- // cli default
681
- if (features.cli.enabled === true) {
682
- features.cli.dir = `./dist/cli/${features.cli.folder}`;
683
-
684
- rollup_output_default.cli = {
685
- format: features.cli.format,
686
- context: "global",
687
- babel: (features.src_uses_jsx === true || features.cli_uses_jsx === true) || false,
688
- browser: false,
689
- replace: true,
690
- enabled: true,
691
- input: "./src/cli/index.js",
692
- output_dir: features.cli.dir,
693
- banner: "#!/usr/bin/env node",
694
- terser: true,
695
- output_exports: features.cli.export === false ? "none" : "auto",
696
- };
697
- }
698
-
699
- // browsersync default
700
- const browsersync_default = {
701
- server: '.',
702
- startPath: `${path.normalize(features.app.dir || '.')}`,
703
- files: [path.normalize("./dist/**/*")],
704
- cors: true,
705
- open: false,
706
- };
707
-
708
- features.babel_options = merge(babel_default, features.babel_options || features.babel?.options);
709
- features.browsersync_options = merge(browsersync_default, features.browsersync_options || features.browsersync?.options || {});
710
- features.replace_options = merge(replace_default, features.replace_options || features.replace?.options || {});
711
-
712
- if (Reflect.has(features.browsersync_options, 'proxy')) {
713
- delete features.browsersync_options.server;
714
- }
715
-
716
- features.rollup = features.rollup || {};
717
- features.rollup_output = merge(rollup_output_default, features.rollup_output || features.rollup?.output || {});
718
-
719
- features.preact_enabled = features.preact === true || (features.preact && features.preact?.enabled !== false);
720
-
721
- // rollup outputs
722
- let rollup_output_keys = Object.keys(rollup_output_default);
723
- for (const key of rollup_output_keys) {
724
- const output = rollup_output_default[key];
725
-
726
- if (!output) continue;
727
-
728
- if (features.rollup[key] === false) {
729
- delete features.rollup_output[key];
730
- continue;
731
- }
732
- output.babel_options = output.babel_options || features.babel_options;
733
- output.browsersync_options = merge(features.browsersync_options, output.browsersync_options);
734
- output.replace_options = merge(features.replace_options, output.replace_options);
735
-
736
- if (features.preact_enabled) {
737
- output.alias_enabled = true;
738
- output.alias = output.alias || {};
739
- output.alias.entries = output.alias.entries || {};
740
- output.alias.entries['react'] = 'preact/compat';
741
- output.alias.entries['react-dom'] = 'preact/compat';
742
- }
743
-
744
- if (features.form_enabled || features.babel) output.babel = true;
745
- }
746
-
747
- rollup_output_keys = Object.keys(features.rollup_output);
748
-
749
- features.babel_enabled = rollup_output_keys.some(w => features.rollup_output[w].babel === true);
750
- features.browser_enabled = rollup_output_keys.some(w => features.rollup_output[w].babel === true);
751
- features.browsersync_enabled = features.browsersync !== false && rollup_output_keys.some(w => features.rollup_output[w].browsersync === true);
752
- features.browsersync_enabled = features.browsersync_enabled && features.app.enabled;
753
- features.dependency_auto_enabled = features.dependency_auto !== false && features.dependency_auto?.enabled !== false;
754
- features.npm_install_flags = features.npm_install_flags || '';
755
- features.react_version = features.react_version || features.react?.version || 18;
756
-
757
- initCssFeature(apiContext);
758
- initCopyFeature(apiContext);
759
- initWasmFeature(apiContext);
760
- initTerserFeature(apiContext);
761
- initJsonFeature(apiContext);
762
- initStringFeature(apiContext);
763
- initImageFeature(apiContext);
764
- initAnalyzerFeature(apiContext);
765
- initVisualizerFeature(apiContext);
766
- initPolyfillFeature(apiContext);
767
- initNunjucksFeature(apiContext);
768
- initWorkboxFeature(apiContext);
769
- initGzipFeature(apiContext);
770
- }
771
-
772
- async function initDependencies({ atom, packageDependencies, packageDevDependencies, setProgress }) {
773
-
774
- setProgress('Initializing dependencies');
775
-
776
- const userDependencies = atom.doc.dependencies || [];
777
- userDependencies.filter(w => !w.dev).forEach(dep => packageDependencies.push(dep));
778
- userDependencies.filter(w => w.dev).forEach(dep => packageDevDependencies.push(dep));
779
-
780
- if (atom.type === 'workflow') {
781
- packageDependencies.push({ package: "get-value", version: "^3" });
782
- packageDependencies.push({ package: "set-value", version: "^4" });
783
- }
784
-
785
- if (atom.doc.features.form_enabled) {
786
- if (atom.doc.features.dependency_auto_enabled) {
787
- let reactVersion = '^18.2';
788
- setProgress('Fetching React versions');
789
- const versions = await fnetListNpmVersions({ name: "react", groupBy: { major: true } });
790
- const found = versions.find(w => w[0] === atom.doc.features.react_version.toString());
791
- reactVersion = `^${found[0]}`;
792
- packageDependencies.push({ package: "react", version: reactVersion });
793
- packageDependencies.push({ package: "react-dom", version: reactVersion });
794
-
795
- if (atom.type === 'workflow') {
796
- packageDependencies.push({ package: "@fnet/react-app", version: "^0.1" });
797
- packageDependencies.push({ package: "@fnet/react-app-state", version: "^0.1" });
798
- }
799
- }
800
- }
801
-
802
- if (atom.doc.features.preact_enabled) {
803
- packageDependencies.push({ package: "preact", version: "^10" });
804
- }
805
-
806
- if (atom.doc.features.cli.enabled === true) {
807
- packageDependencies.push({ package: "@fnet/args", version: "^0.1" });
808
- packageDevDependencies.push({ package: "ajv", version: "^8" });
809
-
810
- if (atom.doc.features.cli.fargs && atom.doc.features.cli.fargs?.enabled !== false) {
811
- packageDependencies.push({ package: "@fnet/config", version: "0.2.21" });
812
- }
813
- }
814
-
815
- if (atom.doc.features.render && atom.doc.features.render.enabled !== false) {
816
- packageDevDependencies.push({ package: "@flownet/lib-render-templates-dir", version: "0.1.19" });
817
- }
818
-
819
- // DEV DEPENDENCIES
820
- packageDevDependencies.push({ package: "@babel/core", version: "^7" });
821
- packageDevDependencies.push({ package: "@rollup/plugin-commonjs", version: "^28" });
822
- packageDevDependencies.push({ package: "@rollup/plugin-node-resolve", version: "^16" });
823
- packageDevDependencies.push({ package: "@rollup/plugin-replace", version: "^6" });
824
- packageDevDependencies.push({ package: "rollup", version: "^4" });
825
- if (atom.doc.features.dts_enabled) {
826
- packageDevDependencies.push({ package: "rollup-plugin-dts", version: "^6" });
827
- }
828
- packageDevDependencies.push({ package: "rollup-plugin-peer-deps-external", version: "^2" });
829
- packageDevDependencies.push({ package: "@rollup/plugin-alias", version: "^5" });
830
- packageDevDependencies.push({ package: "fs-extra", version: "^11" });
831
-
832
- if (atom.doc.features.babel_enabled) {
833
- packageDevDependencies.push({ package: "@rollup/plugin-babel", version: "^6" });
834
- packageDevDependencies.push({ package: "@babel/preset-env", version: "^7" });
835
- packageDevDependencies.push({ package: "@babel/preset-react", version: "^7" });
836
-
837
- atom.doc.features.babel?.options?.plugins?.forEach(plugin => {
838
- const pluginName = plugin[0];
839
- switch (pluginName) {
840
- case '@babel/plugin-proposal-decorators':
841
- packageDevDependencies.push({ package: "@babel/plugin-proposal-decorators", version: "^7" });
842
- break;
843
- case '@babel/plugin-proposal-class-properties':
844
- packageDevDependencies.push({ package: "@babel/plugin-proposal-class-properties", version: "^7" });
845
- break;
846
- case '@babel/plugin-proposal-private-methods':
847
- packageDevDependencies.push({ package: "@babel/plugin-proposal-private-methods", version: "^7" });
848
- break;
849
- case '@babel/plugin-proposal-private-property-in-object':
850
- packageDevDependencies.push({ package: "@babel/plugin-proposal-private-property-in-object", version: "^7" });
851
- break;
852
- case '@babel/plugin-proposal-optional-chaining':
853
- packageDevDependencies.push({ package: "@babel/plugin-proposal-optional-chaining", version: "^7" });
854
- break;
855
- }
856
- });
857
- }
858
-
859
- packageDevDependencies.push({ package: "@fnet/rollup-plugin-delete", version: "0.1.10" });
860
-
861
- if (atom.doc.features.browsersync_enabled) {
862
- packageDevDependencies.push({ package: "@fnet/rollup-plugin-browsersync", version: "0.1.11" });
863
- }
864
- }
865
-
866
- async function createApp({ atom, setProgress, context, packageDependencies }) {
867
-
868
- if (atom.doc.features.app.enabled !== true) return;
869
-
870
- await setProgress({ message: "Creating app folder" });
871
-
872
- const templateContext = {
873
- atom: atom,
874
- packageDependencies: packageDependencies,
875
- ts: Date.now()
876
- };
877
- const templateDir = context.templateDir;
878
-
879
- const outDir = path.resolve(context.projectDir, `src/app`);
880
- if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
881
-
882
- let pattern = ["index.js.njk"];
883
- if (atom.doc.features.app.html !== false) pattern.push("index.html.njk");
884
- await fnetRender({
885
- pattern: pattern,
886
- dir: path.resolve(templateDir, `src/app`),
887
- outDir,
888
- context: templateContext,
889
- });
890
- }
891
-
892
- async function pickNpmVersions({ projectDir, name, setProgress, count = 1 }) {
893
-
894
- let npmVersions;
895
-
896
- const key = ['npm-pick-versions', name, count];
897
- const cacheKey = hash(key);
898
- const cacheDir = path.join(projectDir, '.cache');
899
- const cacheFile = path.join(cacheDir, cacheKey + '.json');
900
-
901
- if (fs.existsSync(cacheFile)) {
902
- if (setProgress) setProgress(`Picking npm version of ${name} from cache ...`);
903
- npmVersions = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
904
- }
905
- else {
906
- if (setProgress) setProgress(`Picking npm version of ${name} ...`);
907
- npmVersions = await fnetPickNpmVersions({ name: name, count });
908
- fs.mkdirSync(cacheDir, { recursive: true });
909
- fs.writeFileSync(cacheFile, JSON.stringify(npmVersions), 'utf8');
910
- }
911
-
912
- return npmVersions;
913
- }
914
-
915
- async function createPackageJson({ atom, context, packageDependencies, packageDevDependencies, setProgress }) {
916
-
917
- await setProgress({ message: "Creating package.json." });
918
-
919
- // move dev dependencies in packageDependencies to packageDevDependencies
920
- const devPackages = packageDependencies.filter(w => w.dev === true);
921
- devPackages.forEach(w => {
922
- if (!packageDevDependencies.find(x => x.package === w.package)) {
923
- packageDevDependencies.push(w);
924
- }
925
-
926
- const index = packageDependencies.findIndex(x => x.package === w.package);
927
- packageDependencies.splice(index, 1);
928
- });
929
-
930
- // TODO: PEER DEPENDENCIES
931
- // REACT CHECK
932
- const reactDep = packageDependencies.find(w => w.package === "react");
933
- const reactDomDep = packageDependencies.find(w => w.package === "react-dom");
934
-
935
- if (reactDep && !reactDomDep)
936
- packageDependencies.push({ package: "react-dom", version: reactDep.version });
937
- else if (reactDep && reactDomDep)
938
- reactDomDep.version = reactDep.version;
939
-
940
- // EMOTION CHECK
941
- if (reactDep && atom.doc.features.react_version >= 17) {
942
- if (!packageDependencies.find(w => w.package === '@emotion/react'))
943
- packageDependencies.push({ package: "@emotion/react", version: "^11" });
944
- if (!packageDependencies.find(w => w.package === '@emotion/styled'))
945
- packageDependencies.push({ package: "@emotion/styled", version: "^11" });
946
- }
947
-
948
- const checkFiles = [];
949
-
950
- if (atom.doc.features.app.enabled === true) {
951
- checkFiles.push({
952
- file: path.resolve(context.projectDir, `src/app/index.js`),
953
- dev: atom.doc.features.app.dev !== false
954
- });
955
- }
956
-
957
- if (atom.doc.features.cli.enabled === true) {
958
- checkFiles.push({
959
- file: path.resolve(context.projectDir, `src/cli/index.js`),
960
- dev: atom.doc.features.cli.dev !== false
961
- });
962
- }
963
-
964
- for await (const checkFile of checkFiles) {
965
- const srcFilePath = checkFile.file;
966
- if (!fs.existsSync(srcFilePath)) throw new Error(`App file not found: ${srcFilePath}`);
967
-
968
- const parsedImports = await fnetParseImports({ file: srcFilePath, recursive: true });
969
- const targetImports = parsedImports.all;
970
-
971
- for await (const parsedImport of targetImports) {
972
- if (parsedImport.type !== 'npm') continue;
973
-
974
- if (packageDependencies.find(w => w.package === parsedImport.package)) continue;
975
- if (packageDevDependencies.find(w => w.package === parsedImport.package)) continue;
976
-
977
- const npmVersions = await pickNpmVersions({
978
- name: parsedImport.package,
979
- projectDir: context.projectDir,
980
- setProgress
981
- });
982
-
983
- const targetDependencies = checkFile.dev === true ? packageDevDependencies : packageDependencies;
984
- targetDependencies.push({
985
- package: parsedImport.package,
986
- subpath: parsedImport.subpath,
987
- version: npmVersions.minorRange,
988
- type: "npm"
989
- });
990
- }
991
- }
992
-
993
- const templateContext = {
994
- atom: atom,
995
- packageDependencies: packageDependencies,
996
- packageDevDependencies: packageDevDependencies
997
- };
998
-
999
- const templateDir = context.templateCommonDir;
1000
- const template = nunjucks.compile(
1001
- fs.readFileSync(path.resolve(templateDir, `package.json.njk`), "utf8"),
1002
- nunjucks.configure(templateDir)
1003
- );
1004
-
1005
- const templateRender = template.render(templateContext);
1006
-
1007
- const projectDir = context.projectDir;
1008
- const filePath = path.resolve(projectDir, `package.json`);
1009
- fs.writeFileSync(filePath, templateRender, 'utf8');
1010
-
1011
- // copy fnet files to projectDir
1012
- const fnetSrcDir = path.resolve(context.project.projectDir, 'fnet');
1013
- if (fs.existsSync(fnetSrcDir)) {
1014
- const fnetDestDir = path.resolve(context.projectDir, 'fnet');
1015
- if (!fs.existsSync(fnetDestDir)) {
1016
- fs.mkdirSync(fnetDestDir);
1017
- }
1018
-
1019
- const fnetFiles = fs.readdirSync(fnetSrcDir);
1020
- for (const fnetFile of fnetFiles) {
1021
- const fnetFilePath = path.resolve(fnetSrcDir, fnetFile);
1022
- if (!fs.lstatSync(fnetFilePath).isFile()) continue;
1023
- const targetFilePath = path.resolve(fnetDestDir, fnetFile);
1024
- fs.copyFileSync(fnetFilePath, targetFilePath);
1025
- }
1026
- }
1027
- }
1028
-
1029
- async function createCli({ atom, setProgress, context, packageDependencies }) {
1030
-
1031
- if (atom.doc.features.cli.enabled !== true) return;
1032
-
1033
- await setProgress({ message: "Creating cli." });
1034
-
1035
- const templateContext = {
1036
- atom: atom,
1037
- packageDependencies: packageDependencies
1038
- };
1039
-
1040
- const templateDir = context.templateDir;
1041
-
1042
- const outDir = path.resolve(context.projectDir, `src/cli`);
1043
- if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
1044
-
1045
- await fnetRender({
1046
- pattern: ["index.js.njk"],
1047
- dir: path.resolve(templateDir, `src/cli`),
1048
- outDir,
1049
- context: templateContext,
1050
- });
1051
- }
1052
-
1053
- async function createRollup({ atom, setProgress, context, packageDependencies }) {
1054
-
1055
- await setProgress({ message: "Creating rollup file." });
1056
-
1057
- const templateContext = {
1058
- atom,
1059
- packageDependencies
1060
- };
1061
-
1062
- // SCAN ENTRY FILE
1063
- const entryFile = path.resolve(context.projectDir, "src", "default/index.js");
1064
- if (!fs.existsSync(entryFile)) throw new Error(`Entry file not found: ${entryFile}`);
1065
-
1066
- const packages = await fnetParseImports({ file: entryFile, recursive: true });
1067
-
1068
- // ADD NODE BUILTINS
1069
- const nodeBuiltins = packages.all.filter(p => p.type === "node").map(p => p.path);
1070
- const rollup_output = atom.doc.features.rollup_output;
1071
- const keys = Object.keys(rollup_output);
1072
- for (let i = 0; i < keys.length; i++) {
1073
- const key = keys[i];
1074
- const value = rollup_output[key];
1075
- if (value.browser === true) {
1076
- if (nodeBuiltins.length > 0) {
1077
-
1078
- // GLOBALS
1079
- value.globals_enabled = true;
1080
- value.globals = value.globals || [];
1081
- value.globals = value.globals.concat(nodeBuiltins.map(nodeBuiltin => { return { key: nodeBuiltin, value: nodeBuiltin } }));
1082
-
1083
- // ALIAS
1084
- value.alias_enabled = true;
1085
- value.alias = value.alias || {};
1086
- value.alias.entries = value.alias.entries || {};
1087
- for (let j = 0; j < nodeBuiltins.length; j++) {
1088
- const nodeBuiltin = nodeBuiltins[j];
1089
- value.alias.entries[nodeBuiltin] = `node:${nodeBuiltin}`;
1090
- value.alias.entries[`node:${nodeBuiltin}`] = nodeBuiltin;
1091
- }
1092
-
1093
- // EXTERNAL
1094
- value.external_enabled = true;
1095
- value.external = value.external || [];
1096
- value.external = value.external.concat(nodeBuiltins);
1097
- }
1098
- }
1099
- }
1100
-
1101
- // RENDER TEMPLATE rollup.config.js.njk
1102
- const templateDir = context.templateCommonDir;
1103
- let template = nunjucks.compile(
1104
- fs.readFileSync(path.resolve(templateDir, `rollup.config.mjs.njk`), "utf8"),
1105
- nunjucks.configure(templateDir)
1106
- );
1107
-
1108
- let templateRender = template.render(templateContext);
1109
-
1110
- const projectDir = context.projectDir;
1111
- let filePath = path.resolve(projectDir, `rollup.config.mjs`);
1112
- fs.writeFileSync(filePath, templateRender, 'utf8');
1113
-
1114
-
1115
- // // RENDER TEMPLATE rollup.config.mjs.njk
1116
- // // check file if exists
1117
- // if (fs.existsSync(path.resolve(templateDir, `rollup.config.mjs.njk`))) {
1118
- // template = nunjucks.compile(
1119
- // fs.readFileSync(path.resolve(templateDir, `rollup.config.mjs.njk`), "utf8"),
1120
- // nunjucks.configure(templateDir)
1121
- // );
1122
-
1123
- // templateRender = template.render(templateContext);
1124
-
1125
- // filePath = path.resolve(projectDir, `rollup.config.mjs`);
1126
- // fs.writeFileSync(filePath, templateRender, 'utf8');
1127
- // };
1128
- }
1129
-
1130
- async function createToYargs({ atom, setProgress, context, njEnv }) {
1131
-
1132
- if (atom.doc.features.cli.enabled !== true) return;
1133
-
1134
- await setProgress({ message: "Creating yargs." });
1135
-
1136
- let schema = {};
1137
- const imports = [];
1138
-
1139
- const input = atom.doc.input;
1140
- if (input) {
1141
- schema = atom.doc.input;
1142
- }
1143
- else {
1144
- schema = {
1145
- type: "object",
1146
- properties: {},
1147
- required: []
1148
- };
1149
- }
1150
- if (atom.doc.features.cli.fargs && atom.doc.features.cli.fargs?.enabled !== false) {
1151
-
1152
- const fargsOptions = atom.doc.features.cli.fargs;
1153
-
1154
- const fargs = { type: "string", description: "Config name to load args", hidden: false };
1155
- const ftag = { type: "array", description: "Tags to filter the config", hidden: false };
1156
-
1157
- if (Reflect.has(fargsOptions, 'default')) fargs.default = fargsOptions.default;
1158
- // if (Reflect.has(fargsOptions, 'describe') || Reflect.has(fargsOptions, 'description')) fargs.describe = fargsOptions.describe || fargsOptions.description;
1159
- // if (Reflect.has(fargsOptions, 'choices')) fargs.choices = fargsOptions.choices;
1160
-
1161
- if (schema.properties) {
1162
- schema.properties["fargs"] = fargs;
1163
- schema.properties["ftag"] = ftag;
1164
- }
1165
- }
1166
-
1167
- const templateContext = { options: schema, imports, atom: atom };
1168
-
1169
- const templateDir = context.templateDir;
1170
- const template = nunjucks.compile(
1171
- fs.readFileSync(path.resolve(templateDir, `src/default/to.args.js.njk`), "utf8"),
1172
- njEnv
1173
- );
1174
-
1175
- const templateRender = template.render(templateContext);
1176
-
1177
- const projectDir = context.projectDir;
1178
- const filePath = path.resolve(projectDir, `src/default/to.args.js`);
1179
- fs.writeFileSync(filePath, templateRender, 'utf8');
1180
-
1181
- const ajv = new Ajv({
1182
- allErrors: true,
1183
- useDefaults: true,
1184
- formats: { },
1185
- strict: false,
1186
- code: {
1187
- esm: true,
1188
- lines: true,
1189
- optimize: false,
1190
- source: true
1191
- },
1192
- });
1193
-
1194
- addFormats(ajv);
1195
- const validate = ajv.compile(schema);
1196
- const validateCode = standaloneCode(ajv, validate);
1197
-
1198
- fs.writeFileSync(path.resolve(projectDir, `src/default/validate_input.js`), validateCode, 'utf8');
1199
- }
1200
-
1201
- async function createGitIgnore({ atom, setProgress, context, packageDependencies }) {
1202
- await setProgress({ message: "Creating .gitignore" });
1203
-
1204
- const templateContext = {
1205
- atom: atom,
1206
- packageDependencies:
1207
- packageDependencies
1208
- };
1209
-
1210
- const templateDir = context.templateCommonDir;
1211
- const template = nunjucks.compile(
1212
- fs.readFileSync(path.resolve(templateDir, `.gitignore.njk`), "utf8"),
1213
- nunjucks.configure(templateDir)
1214
- );
1215
-
1216
- const templateRender = template.render(templateContext);
1217
-
1218
- const projectDir = context.projectDir;
1219
- const filePath = path.resolve(projectDir, `.gitignore`);
1220
- fs.writeFileSync(filePath, templateRender, 'utf8');
1221
- }
1222
-
1223
- async function createTsConfig({ atom, setProgress, context, packageDependencies }) {
1224
- await setProgress({ message: "Creating tsconfig.json." });
1225
-
1226
- const templateContext = {
1227
- atom: atom,
1228
- packageDependencies:
1229
- packageDependencies
1230
- };
1231
-
1232
- const templateDir = context.templateCommonDir;
1233
- const template = nunjucks.compile(
1234
- fs.readFileSync(path.resolve(templateDir, `tsconfig.json.njk`), "utf8"),
1235
- nunjucks.configure(templateDir)
1236
- );
1237
-
1238
- const templateRender = template.render(templateContext);
1239
-
1240
- const projectDir = context.projectDir;
1241
- const filePath = path.resolve(projectDir, `tsconfig.json`);
1242
- fs.writeFileSync(filePath, templateRender, 'utf8');
1243
- }
1244
-
1245
- async function createProjectReadme({ atom, context, setProgress, Atom }) {
1246
-
1247
- const fileBase = `readme.md`;
1248
- const message = `Creating ${fileBase}`;
1249
-
1250
- await setProgress({ message: message });
1251
-
1252
- if (context.project?.readme) {
1253
-
1254
- const projectDir = context.projectDir;
1255
-
1256
- const templateContext = {
1257
- content: context.project.readme.doc.content
1258
- };
1259
-
1260
- const howtoPath = path.resolve(context.project.projectDir, `fnet/how-to.md`);
1261
- if (fs.existsSync(howtoPath)) {
1262
- const howtoContent = fs.readFileSync(howtoPath, 'utf8');
1263
- templateContext.howto = howtoContent;
1264
- }
1265
-
1266
- const inputSchemaPath = path.resolve(context.project.projectDir, `fnet/input.yaml`);
1267
- if (fs.existsSync(inputSchemaPath)) {
1268
- const yaml = await fnetYaml({ file: inputSchemaPath, tags: context.tags });
1269
- templateContext.input = yaml.content;
1270
- }
1271
-
1272
- const templateDir = context.templateCommonDir;
1273
- const template = nunjucks.compile(
1274
- fs.readFileSync(path.resolve(templateDir, `${fileBase}.njk`), "utf8"),
1275
- nunjucks.configure(templateDir)
1276
- );
1277
-
1278
- const templateRender = template.render(templateContext);
1279
-
1280
- const filePath = path.resolve(projectDir, `${fileBase}`);
1281
- fs.writeFileSync(filePath, templateRender, 'utf8');
1282
- }
1283
- else if (atom.id) {
1284
- const wiki = await Atom.first({ type: "wiki", parent_id: atom.id });
1285
-
1286
- if (!wiki || wiki.doc?.["content-type"] !== 'markdown') return;
1287
-
1288
- const { content: main, ...content } = wiki.doc;
1289
-
1290
- const templateContext = { content: main };
1291
-
1292
- const templateDir = context.templateCommonDir;
1293
- const template = nunjucks.compile(
1294
- fs.readFileSync(path.resolve(templateDir, `${fileBase}.njk`), "utf8"),
1295
- nunjucks.configure(templateDir)
1296
- );
1297
-
1298
- const templateRender = template.render(templateContext);
1299
-
1300
- const projectDir = context.projectDir;
1301
- const filePath = path.resolve(projectDir, `${fileBase}`);
1302
- fs.writeFileSync(filePath, templateRender, 'utf8');
1303
- }
1304
- }
1305
-
1306
- async function formatFiles({ setProgress, context }) {
1307
-
1308
- const projectDir = context.projectDir;
1309
-
1310
- await setProgress({ message: "Prettifiying source files." });
1311
-
1312
- let srcDir = path$1.join("src","**", "*");
1313
-
1314
- await fnetShellFlow({
1315
- commands: {
1316
- steps: [`prettier --write ${srcDir} *.{js,cjs,mjs,json,yaml,html} --no-error-on-unmatched-pattern`],
1317
- wdir: projectDir,
1318
- }
1319
- });
1320
- }
1321
-
1322
- async function createDts({ atom, setProgress, context }) {
1323
-
1324
- if(!atom.doc.features.dts_enabled) return;
1325
-
1326
- const projectDir = context.projectDir;
1327
-
1328
- await setProgress({ message: "Creating .d.ts" });
1329
- const result = await fnetShellJs(`tsc`, { cwd: projectDir });
1330
- if (result.code !== 0) throw new Error('Couldnt create .d.ts files.');
1331
- }
1332
-
1333
- async function installNpmPackages({ setProgress, atom, context }) {
1334
-
1335
- const projectDir = context.projectDir;
1336
-
1337
- await setProgress({ message: "Installing npm packages." });
1338
- const packageManager = which('bun') ? 'bun' : 'npm';
1339
- const result = await fnetShellJs(`${packageManager} install ${atom.doc.features.npm_install_flags}`, { cwd: projectDir });
1340
- if (result.code !== 0) throw new Error('Couldnt install npm packages.');
1341
- }
1342
-
1343
- async function runNpmBuild({ setProgress, context }) {
1344
-
1345
- const projectDir = context.projectDir;
1346
-
1347
- await setProgress({ message: "Building main project." });
1348
- const result = await fnetShellJs(`npm run build`, { cwd: projectDir });
1349
- if (result.code !== 0) throw new Error('Couldnt build project.');
1350
- }
1351
-
1352
- var deployTo = async (apiContext) => {
1353
-
1354
- // Destructure the apiContext to get needed variables
1355
- const {
1356
- atom,
1357
- packageDependencies,
1358
- context,
1359
- deploymentProjectTarget,
1360
- setProgress,
1361
- deploymentProject,
1362
- yamlTarget
1363
- } = apiContext;
1364
-
1365
- // Early exit if the target is not enabled
1366
- if (deploymentProjectTarget.enabled !== true) return;
1367
-
1368
- const type = deploymentProjectTarget.type;
1369
-
1370
- try {
1371
- // Handle the first set of deployment types
1372
- if (type === "lib") {
1373
- await (await import('./index.f798DPwo.js')).default({ ...apiContext });
1374
- } else if (type === "red") {
1375
- await (await import('./index.CX8eMqfH.js')).default({ ...apiContext });
1376
- } else if (type === "npm") {
1377
- await (await import('./index.B90Vm9uq.js')).default({ ...apiContext });
1378
- } else if (type === "gcs") {
1379
- await (await import('./index.BMsD46br.js')).default({ ...apiContext });
1380
- } else if (type === "gitlab") {
1381
- await (await import('./index.Dd0lngp8.js')).default({ ...apiContext });
1382
- } else if (type === "fnet-package") {
1383
- await (await import('./index.C9zKEF61.js')).default({ ...apiContext });
1384
- } else if (type === "fnet-form") {
1385
- await (await import('./index.BUhoGq-h.js')).default({ ...apiContext });
1386
- } else if (type === "fnet-node") {
1387
- await (await import('./index.B6WHm9H0.js')).default({ ...apiContext });
1388
- } else if (type === "fnet-flow") {
1389
- await (await import('./index.D61MduW1.js')).default({ ...apiContext });
1390
- }
1391
- // Handle the second set of deployment types
1392
- else if (type === 'nextjs') {
1393
- await (await import('./index.DqwVukIB.js')).default({
1394
- atom,
1395
- target: deploymentProjectTarget,
1396
- onProgress: setProgress,
1397
- projectDir: context.projectDir,
1398
- dependencies: packageDependencies,
1399
- context,
1400
- yamlTarget
1401
- });
1402
- deploymentProject.isDirty = true;
1403
- } else if (type === 'webos') {
1404
- await (await import('./index.MWHLt6g3.js')).default({
1405
- atom,
1406
- target: deploymentProjectTarget,
1407
- onProgress: setProgress,
1408
- projectDir: context.projectDir,
1409
- dependencies: packageDependencies,
1410
- context,
1411
- yamlTarget
1412
- });
1413
- deploymentProject.isDirty = true;
1414
- } else if (type === 'electron') {
1415
- await (await import('./index.CQNYMi1Z.js')).default({
1416
- atom,
1417
- target: deploymentProjectTarget,
1418
- onProgress: setProgress,
1419
- projectDir: context.projectDir,
1420
- dependencies: packageDependencies,
1421
- context,
1422
- yamlTarget
1423
- });
1424
- deploymentProject.isDirty = true;
1425
- } else if (type === 'docker') {
1426
- await (await import('./index.B5vpZn1Z.js')).default({
1427
- atom,
1428
- target: deploymentProjectTarget,
1429
- onProgress: setProgress,
1430
- projectDir: context.projectDir,
1431
- dependencies: packageDependencies,
1432
- context,
1433
- yamlTarget
1434
- });
1435
- deploymentProject.isDirty = true;
1436
- } else if (type === 'ios') {
1437
- await (await import('./index.D2kFuxXo.js')).default({
1438
- atom,
1439
- target: deploymentProjectTarget,
1440
- onProgress: setProgress,
1441
- projectDir: context.projectDir,
1442
- dependencies: packageDependencies,
1443
- context,
1444
- yamlTarget
1445
- });
1446
- deploymentProject.isDirty = true;
1447
- } else if (type === 'macos') {
1448
- await (await import('./index.Ce8sTnt_.js')).default({
1449
- atom,
1450
- target: deploymentProjectTarget,
1451
- onProgress: setProgress,
1452
- projectDir: context.projectDir,
1453
- dependencies: packageDependencies,
1454
- context,
1455
- yamlTarget
1456
- });
1457
- deploymentProject.isDirty = true;
1458
- } else if (type === 'rust') {
1459
- await (await import('./index.BjzEMdm1.js')).default({
1460
- atom,
1461
- target: deploymentProjectTarget,
1462
- onProgress: setProgress,
1463
- projectDir: context.projectDir,
1464
- dependencies: packageDependencies,
1465
- context,
1466
- yamlTarget
1467
- });
1468
- deploymentProject.isDirty = true;
1469
- } else if (type === 'pypi') {
1470
- await (await import('./index.j5JP-zGw.js')).default({
1471
- atom,
1472
- target: deploymentProjectTarget,
1473
- onProgress: setProgress,
1474
- projectDir: context.projectDir,
1475
- dependencies: packageDependencies,
1476
- context,
1477
- yamlTarget
1478
- });
1479
- deploymentProject.isDirty = true;
1480
- } else {
1481
- console.warn(`No deployer found for type: ${type}`);
1482
- return;
1483
- }
1484
- } catch (error) {
1485
- // Add error handling for require failures or execution errors
1486
- console.error(`Error during deployment for type "${type}":`, error);
1487
- // Re-throw the error or handle it as appropriate for your application
1488
- throw error;
1489
- }
1490
- };
1491
-
1492
- var name = "ATOM";
1493
- var uri = "http://atom.org/bpmn";
1494
- var prefix = "atom";
1495
- var types = [
1496
- {
1497
- name: "AtomExtension",
1498
- "extends": [
1499
- "bpmn:BaseElement"
1500
- ],
1501
- properties: [
1502
- {
1503
- name: "atom",
1504
- type: "atom:Atom",
1505
- isMany: false
1506
- }
1507
- ]
1508
- },
1509
- {
1510
- name: "Atom",
1511
- properties: [
1512
- {
1513
- name: "type",
1514
- type: "String",
1515
- isAttr: true
1516
- }
1517
- ]
1518
- }
1519
- ];
1520
- var atomJson = {
1521
- name: name,
1522
- uri: uri,
1523
- prefix: prefix,
1524
- types: types
1525
- };
1526
-
1527
- function initNodes(context) {
1528
- const { nodes} = context;
1529
-
1530
- nodes.forEach(node => {
1531
-
1532
- const all = [];
1533
- const start = [];
1534
-
1535
- const iterate = (tempNode) => {
1536
-
1537
- if (tempNode.context.next) {
1538
- all.push({
1539
- from: tempNode,
1540
- to: tempNode.context.next,
1541
- type: "bpmn:SequenceFlow",
1542
- });
1543
-
1544
- // TODO: TEMP
1545
- if (tempNode === node) {
1546
- start.push({
1547
- to: tempNode.context.next,
1548
- type: "bpmn:SequenceFlow",
1549
- next: true
1550
- });
1551
- }
1552
- }
1553
- tempNode.childs.forEach(tempNodeChild => {
1554
-
1555
- // TODO: TEMP
1556
- if (tempNode === node) {
1557
- if (node.type === 'switch') {
1558
- start.push({
1559
- to: tempNodeChild,
1560
- type: "bpmn:SequenceFlow",
1561
- });
1562
- }
1563
- }
1564
-
1565
- iterate(tempNodeChild);
1566
- });
1567
- };
1568
-
1569
- iterate(node);
1570
-
1571
- const edges = all
1572
- .filter(w => w.to.parent.indexKey === node.parent.indexKey)
1573
- .map(item => { return { ...item, from: node.indexKey, to: item.to.indexKey } });
1574
-
1575
- const outside = all
1576
- .filter(w => (w.to.parent.indexKey !== node.parent.indexKey) && !w.to.indexKey.startsWith(node.indexKey + '/'))
1577
- .map(item => { return { ...item, from: node.indexKey, to: item.to.indexKey } });
1578
-
1579
- // TODO: TEMP
1580
- const starts = start
1581
- .map(item => { return { ...item, to: item.to.indexKey } });
1582
-
1583
- node.bpmn = node.bpmn || {};
1584
- node.bpmn.edges = removeDuplicates(edges, "to");
1585
- node.bpmn.outside = removeDuplicates(outside, "to");
1586
- node.bpmn.starts = removeDuplicates(starts, "to");
1587
- node.bpmn.type = getBpmnType(node);
1588
- node.bpmn.width = 120;
1589
- node.bpmn.height = 80;
1590
-
1591
- // testing
1592
- if (node.type === 'return') {
1593
- node.bpmn.width = 36;
1594
- node.bpmn.height = 36;
1595
- }
1596
- });
1597
- }
1598
-
1599
- function getBpmnType(node) {
1600
- if (node.type === 'call') return "bpmn:ServiceTask";
1601
- else if (node.type === 'form') return "bpmn:UserTask";
1602
- else if (node.type === 'return') return "bpmn:EndEvent";
1603
- else return "bpmn:Task";
1604
- }
1605
-
1606
- function removeDuplicates(array, criteria) {
1607
- return array.filter((obj, pos, arr) => {
1608
- return arr.map(mapObj => mapObj[criteria]).indexOf(obj[criteria]) === pos;
1609
- });
1610
- }
1611
-
1612
- function createVirtualNodes(context) {
1613
- const { nodes, nodeIndex, root } = context;
1614
-
1615
- const targetNodes = context.targetNodes || root.childs;
1616
-
1617
- targetNodes.forEach(node => {
1618
-
1619
- const isProcess = node.type === 'workflow' || node.type === 'subworkflow';
1620
-
1621
- const isSubProcess = !isProcess
1622
- && node.childs.filter(w => !w.virtual).length > 0
1623
- ;
1624
-
1625
- if (isSubProcess) {
1626
- node.bpmn.type = "bpmn:SubProcess";
1627
- }
1628
-
1629
- if (isProcess || isSubProcess) {
1630
-
1631
- const firstNode = node.childs.filter(w=>w.module!==true)[0];
1632
-
1633
- // Modules intermediate catch event
1634
- const childModules = node.childs.filter(w => w.module === true);
1635
- childModules.forEach(moduleNode => {
1636
- const vNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:IntermediateCatchEvent", type: "inter", definitions: [{ type: "bpmn:SignalEventDefinition" }] });
1637
- vNode.bpmn.edges = [{ from: vNode.indexKey, to: moduleNode.indexKey, type: "bpmn:SequenceFlow" }];
1638
- });
1639
-
1640
- // tryNode
1641
- const tryNode = node.childs.find(w => w.name === "try" && node.type === 'tryexcept');
1642
- const exceptNodes = node.childs.filter(w => w.name === "except" && node.type === 'tryexcept');
1643
- if (tryNode && exceptNodes.length) {
1644
- // Except nodes
1645
- exceptNodes.forEach(exceptNode => {
1646
- const vNode = createVirtualNode({ location: node.childs.indexOf(exceptNode), ...context, parent: node, bpmnType: "bpmn:BoundaryEvent", type: "boundary", attrs: { attachedToRef: tryNode }, definitions: [{ type: "bpmn:ErrorEventDefinition" }] });
1647
- vNode.bpmn.edges = [{ from: vNode.indexKey, to: exceptNode.indexKey, type: "bpmn:SequenceFlow" }];
1648
- });
1649
- }
1650
-
1651
- // raiseNode
1652
- const raiseNode = node.childs.find(w => w.type === "raise");
1653
- if (raiseNode) {
1654
- const vEndNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:EndEvent", type: "end", name: `ERROR`,definitions: [{ type: "bpmn:ErrorEventDefinition" }] });
1655
- raiseNode.bpmn.edges = [{ from: raiseNode.indexKey, to: vEndNode.indexKey, type: "bpmn:SequenceFlow" }];
1656
- }
1657
-
1658
- if (firstNode) {
1659
- if (node.bpmn.starts.length > 1) {
1660
-
1661
- const vStartNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:StartEvent", type: "start" });
1662
- const vSwitchNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:ExclusiveGateway", type: "switch" });
1663
- vStartNode.bpmn.edges = [{ from: vStartNode.indexKey, to: vSwitchNode.indexKey, type: "bpmn:SequenceFlow" }];
1664
- vSwitchNode.bpmn.edges = node.bpmn.starts.map(m => { return { ...m, from: vSwitchNode.indexKey } });
1665
-
1666
- const nextNode = vSwitchNode.bpmn.edges.find(w => w.next === true);
1667
-
1668
- if (nextNode) {
1669
- const vEndNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:EndEvent", type: "end", name: nextNode.to });
1670
- nextNode.to = vEndNode.indexKey;
1671
- }
1672
- }
1673
- else {
1674
- const vStartNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:StartEvent", type: "start" });
1675
- vStartNode.bpmn.edges.push({ from: vStartNode.indexKey, to: firstNode.indexKey, type: "bpmn:SequenceFlow" });
1676
- }
1677
- }
1678
-
1679
- const outsideNodes = node.childs.filter(w =>
1680
- w.virtual !== true &&
1681
- w.bpmn.outside.length &&
1682
- w.bpmn.type !== 'bpmn:EndEvent'
1683
- );
1684
-
1685
- outsideNodes.forEach(noEndNode => {
1686
- noEndNode.bpmn.outside.forEach(out => {
1687
- const location = targetNodes.indexOf(node);
1688
- const vEndNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:EndEvent", type: "end", name: out.to, location: location + 1 });
1689
-
1690
- noEndNode.bpmn.edges.push({ from: noEndNode.indexKey, to: vEndNode.indexKey, type: "bpmn:SequenceFlow" });
1691
- });
1692
- });
1693
-
1694
- const switchRequiredNodes = node.childs.filter(w =>
1695
- w.virtual !== true &&
1696
- w.bpmn.edges.length > 1
1697
- );
1698
-
1699
- // add virtual switch node
1700
- switchRequiredNodes.forEach(switchRequiredNode => {
1701
-
1702
- const location = targetNodes.indexOf(switchRequiredNode);
1703
-
1704
- const vSwitchNode = createVirtualNode({ ...context, parent: node, bpmnType: "bpmn:ExclusiveGateway", type: "switch", location: location + 1 });
1705
-
1706
- vSwitchNode.bpmn.edges = switchRequiredNode.bpmn.edges.map(m => { return { ...m, from: vSwitchNode.indexKey } });
1707
-
1708
- switchRequiredNode.bpmn.edges = [{ from: switchRequiredNode.indexKey, to: vSwitchNode.indexKey, type: "bpmn:SequenceFlow" }];
1709
- switchRequiredNode.bpmn.outside = [];
1710
- });
1711
- }
1712
- createVirtualNodes({ ...context, targetNodes: node.childs });
1713
- });
1714
- }
1715
-
1716
- function createVirtualNode(context) {
1717
- const { parent, nodes, nodeIndex, bpmnType, type, name, outside, location, definitions, attrs } = context;
1718
-
1719
- const index = parent.childs.filter(w => w.type === `v${type}`).length;
1720
-
1721
- const virtualNode = {
1722
- indexKey: `${parent.indexKey}/_${type}${index}`,
1723
- pathKey: `${parent.pathKey}._${type}${index}`,
1724
- type: `v${type}`,
1725
- name: name,
1726
- bpmn: {
1727
- edges: [],
1728
- outside: [],
1729
- type: bpmnType,
1730
- width: 36,
1731
- height: 36,
1732
- fill: "#c8e6c9",
1733
- stroke: "#205022",
1734
- definitions,
1735
- attrs
1736
- },
1737
- virtual: true,
1738
- childs: []
1739
- };
1740
-
1741
- parent.childs.splice(location || 0, 0, virtualNode);
1742
- nodes.push(virtualNode);
1743
- nodeIndex[virtualNode.indexKey] = virtualNode;
1744
-
1745
- return virtualNode;
1746
- }
1747
-
1748
- function create(context) {
1749
-
1750
- const { targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex, diagrams, nodes } = context;
1751
-
1752
- createFlowNodes(context);
1753
-
1754
- createSequenceFlows(context);
1755
-
1756
- createDiagram(context);
1757
-
1758
- createSubprocesses(context);
1759
- }
1760
-
1761
- function createFlowNodes(context) {
1762
- const { targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex, nodes } = context;
1763
- const flowElements = targetFlowElementsContainer.get('flowElements');
1764
- targetFlowElementsContainer.$nodes = targetFlowElementsContainer.$nodes || [];
1765
-
1766
- // create flow nodes
1767
- targetNode.childs.forEach(child => {
1768
-
1769
- const flowElement = moddle.create(child.bpmn.type, { id: `node.${child.pathKey}`, name: child.definition?.title || child.name });
1770
- elementIndex[flowElement.id] = flowElement;
1771
- flowElement.$isNode = true;
1772
- flowElement.$node = child;
1773
- child.$flow = flowElement;
1774
- targetFlowElementsContainer.$nodes.push(flowElement);
1775
- flowElements.push(flowElement);
1776
-
1777
- if (child.bpmn.attrs) {
1778
- const attrKeys = Object.keys(child.bpmn.attrs);
1779
- attrKeys.forEach(attrKey => {
1780
- if (attrKey === 'attachedToRef')
1781
- flowElement.set(attrKey, child.bpmn.attrs[attrKey].$flow);
1782
- });
1783
- }
1784
-
1785
- if (child.bpmn.definitions) {
1786
- const definitons = child.bpmn.definitions.map(m => {
1787
- const temp = moddle.create(m.type);
1788
- const attrKeys = Object.keys(m.attrs || {});
1789
- attrKeys.forEach(attrKey => {
1790
- temp.set(attrKey, m.attrs[attrKey]);
1791
- });
1792
- return temp;
1793
- });
1794
- flowElement.eventDefinitions = definitons;
1795
- }
1796
- });
1797
- }
1798
-
1799
- function createSequenceFlows(context) {
1800
- const { targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex } = context;
1801
- const flowElements = targetFlowElementsContainer.get('flowElements');
1802
- targetFlowElementsContainer.$edges = targetFlowElementsContainer.$edges || [];
1803
-
1804
- // create sequence flows
1805
- targetNode.childs.forEach(child => {
1806
-
1807
- const edges = child.bpmn.edges;
1808
-
1809
- edges.forEach(edge => {
1810
-
1811
- const fromNode = child;
1812
- const toNode = nodeIndex[edge.to];
1813
- const id = `edge.${fromNode.pathKey}_${toNode.pathKey}`;
1814
- if (elementIndex[id]) return;
1815
-
1816
- const sourceRef = elementIndex[`node.${fromNode.pathKey}`];
1817
- const targetRef = elementIndex[`node.${toNode.pathKey}`];
1818
-
1819
- const flowElement = moddle.create(edge.type, { id, sourceRef, targetRef });
1820
- elementIndex[flowElement.id] = flowElement;
1821
- flowElement.$is_edge = true;
1822
-
1823
- sourceRef.get('outgoing').push(flowElement);
1824
- targetRef.get('incoming').push(flowElement);
1825
-
1826
- targetFlowElementsContainer.$edges.push({ from: sourceRef, to: targetRef, flow: flowElement });
1827
- flowElements.push(flowElement);
1828
- });
1829
- });
1830
- }
1831
-
1832
- function createDiagram(context) {
1833
- const { targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex } = context;
1834
-
1835
- // create diagram
1836
- const nodeSep = 120;
1837
- const rankSep = 80;
1838
-
1839
- const xOffset = 160;
1840
- const yOffset = 160;
1841
-
1842
- // layout engine
1843
- const dagreGraph = new dagre.graphlib.Graph();
1844
- dagreGraph.setDefaultEdgeLabel(() => ({}));
1845
-
1846
- // The rankdir option can take one of the following values:
1847
-
1848
- // TB: Top-to-bottom layout. This is the default value.
1849
- // BT: Bottom-to-top layout.
1850
- // LR: Left-to-right layout.
1851
- // RL: Right-to-left layout.
1852
-
1853
- dagreGraph.setGraph({ rankdir: "TB", nodesep: nodeSep, ranksep: rankSep, xranker: "longest-path" });
1854
-
1855
- targetFlowElementsContainer.$nodes.forEach((node) => {
1856
- dagreGraph.setNode(node.id, {
1857
- width: node.$node?.bpmn.width || nodeSep,
1858
- height: node.$node?.bpmn.height || rankSep,
1859
- label: node.id
1860
- });
1861
- });
1862
-
1863
- targetFlowElementsContainer.$edges.forEach((edge) => {
1864
- dagreGraph.setEdge(edge.from.id, edge.to.id);
1865
- });
1866
-
1867
- dagre.layout(dagreGraph);
1868
-
1869
- targetFlowElementsContainer.$nodes.forEach((node) => {
1870
- const layout = dagreGraph.node(node.id);
1871
-
1872
- let width = layout.width;
1873
- let height = layout.height;
1874
-
1875
- const shape = moddle.create("bpmndi:BPMNShape", {
1876
- id: `shape.${node.id}`,
1877
- bpmnElement: node,
1878
- bounds: moddle.create("dc:Bounds", {
1879
- x: xOffset + layout.x - layout.width / 2,
1880
- y: yOffset + layout.y - layout.height / 2,
1881
- width: width,
1882
- height: height
1883
- }),
1884
- label: moddle.create('bpmndi:BPMNLabel')
1885
- });
1886
-
1887
- if (node.$node.bpmn.fill) shape.set('bioc:fill', node.$node.bpmn.fill);
1888
- if (node.$node.bpmn.stroke) shape.set('bioc:stroke', node.$node.bpmn.stroke);
1889
-
1890
- const planeElement = targetPlaneElement.get('planeElement');
1891
- planeElement.push(shape);
1892
- });
1893
-
1894
- targetFlowElementsContainer.$edges.forEach((edge) => {
1895
- const layout = dagreGraph.edge(edge.from.id, edge.to.id);
1896
-
1897
- const shape = moddle.create("bpmndi:BPMNEdge", {
1898
- id: `edge.${edge.from.id}_${edge.to.id}`,
1899
- bpmnElement: edge.flow,
1900
- label: moddle.create('bpmndi:BPMNLabel')
1901
- });
1902
-
1903
- layout.points.forEach(point => {
1904
-
1905
- const waypoint = moddle.create("dc:Point", {
1906
- x: xOffset + point.x,
1907
- y: yOffset + point.y
1908
- });
1909
-
1910
- shape.get('waypoint').push(waypoint);
1911
- });
1912
-
1913
- const planeElement = targetPlaneElement.get('planeElement');
1914
- planeElement.push(shape);
1915
- });
1916
- }
1917
-
1918
- function createSubprocesses(context) {
1919
- const { targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex, diagrams } = context;
1920
-
1921
- const subprocessNodes = targetNode.childs.filter(w => w.bpmn.type === 'bpmn:SubProcess');
1922
-
1923
- subprocessNodes.forEach(subprocessNode => {
1924
-
1925
- const subprocessElement = elementIndex[`node.${subprocessNode.pathKey}`];
1926
- const diagramElement = moddle.create('bpmndi:BPMNDiagram', { id: `diagram_${subprocessNode.pathKey}` });
1927
- elementIndex[diagramElement.id] = diagramElement;
1928
- diagrams.push(diagramElement);
1929
-
1930
- // PLANE
1931
- const planeElement = moddle.create('bpmndi:BPMNPlane', { id: `plane_${subprocessNode.pathKey}` });
1932
- elementIndex[planeElement.id] = planeElement;
1933
-
1934
- diagramElement.plane = planeElement;
1935
- planeElement.bpmnElement = subprocessElement;
1936
-
1937
- create({ ...context, targetNode: subprocessNode, targetFlowElementsContainer: subprocessElement, targetPlaneElement: planeElement });
1938
- });
1939
- }
1940
-
1941
- async function modelA(context) {
1942
-
1943
- const root = context.root;
1944
-
1945
- const nodeIndex = root.context.index;
1946
- const nodes = Object.keys(nodeIndex).map(key => nodeIndex[key]);
1947
-
1948
- initNodes({ nodes});
1949
-
1950
- createVirtualNodes({ nodes, nodeIndex, root });
1951
-
1952
- // const defaultDiagram = await loadBpmnFile('default');
1953
- const defaultDiagram = undefined;
1954
- // const result = await moddle.fromXML(defaultDiagram);
1955
-
1956
- const moddle = new BpmnModdle({
1957
- atom: atomJson
1958
- });
1959
-
1960
- const elementIndex = {};
1961
-
1962
- // BASE
1963
- // Definitions
1964
- const definitions = moddle.create('bpmn:Definitions', { id: "definitions_0" });
1965
- elementIndex[definitions.id] = definitions;
1966
-
1967
- for await (const flow of root.childs) {
1968
-
1969
- const rootElements = definitions.get('rootElements');
1970
- const diagrams = definitions.get('diagrams');
1971
-
1972
- // PROCESS
1973
- const process = moddle.create('bpmn:Process', {
1974
- id: `process_${flow.pathKey}`,
1975
- documentation: [moddle.create('bpmn:Documentation', { text: `Atom Workflow - ${root.context.atom.name}` })],
1976
- // atom: moddle.create('atom:Atom', { type: "Test" })
1977
- // extensionElements: moddle.create('bpmn:ExtensionElements', { values: [custom] })
1978
- });
1979
- elementIndex[process.id] = process;
1980
-
1981
- process.isExecutable = true;
1982
- rootElements.push(process);
1983
-
1984
- // DIAGRAM
1985
- const diagram = moddle.create('bpmndi:BPMNDiagram', { id: `diagram_${flow.pathKey}` });
1986
- elementIndex[diagram.id] = diagram;
1987
- diagrams.push(diagram);
1988
-
1989
- // PLANE
1990
- const plane = moddle.create('bpmndi:BPMNPlane', { id: `plane_${flow.pathKey}` });
1991
- elementIndex[plane.id] = plane;
1992
-
1993
- diagram.plane = plane;
1994
- plane.bpmnElement = process;
1995
-
1996
- // workflow or subworkflow
1997
- const targetNode = flow;
1998
- const targetFlowElementsContainer = process;
1999
- const targetPlaneElement = plane;
2000
-
2001
- create({ targetNode, targetFlowElementsContainer, targetPlaneElement, moddle, elementIndex, nodeIndex, nodes, diagrams });
2002
- }
2003
-
2004
- const moddleResult = await moddle.toXML(definitions, { format: true });
2005
-
2006
- return {
2007
- diagramXML: defaultDiagram || moddleResult.xml
2008
- }
2009
- }
2010
-
2011
- async function generateBpmnModel(context = {}) {
2012
- return await modelA(cloneDeep(context));
2013
- }
2014
-
2015
- async function initModules({ node, initNode }) {
2016
-
2017
- if (Reflect.has(node.definition, 'modules') && !Array.isArray(node.definition.modules)) {
2018
- const modules = node.definition.modules;
2019
-
2020
- node.definition.modules = [];
2021
-
2022
- Object.keys(modules).forEach(key => {
2023
- const transformed = {
2024
- ...modules[key]
2025
- };
2026
-
2027
- if (node.type === 'modules') {
2028
- transformed.export = transformed.export || key;
2029
- }
2030
-
2031
- node.definition.modules.push({
2032
- [key]: transformed
2033
- });
2034
- });
2035
- }
2036
-
2037
- const extraModules = [];
2038
-
2039
- const newOne = await fnetKvTransformer({
2040
- data: node.definition, callback: (key, value, path) => {
2041
- // if (typeof key === 'number') {
2042
- // debugger;
2043
- // }
2044
-
2045
- const exp = fnetExpression({ expression: key });
2046
- if (exp?.processor === 'm') {
2047
- const newPath = path.slice(0, -1);
2048
- newPath.push(exp.statement);
2049
- const name = newPath.join('_');
2050
-
2051
- extraModules.push({
2052
- [name]: value
2053
- });
2054
-
2055
- return [exp.statement, `m::${name}`];
2056
- }
2057
- return [key, value];
2058
- }
2059
- });
2060
-
2061
- if (extraModules.length > 0) {
2062
- node.definition = newOne;
2063
- node.definition.modules = node.definition.modules || [];
2064
- node.definition.modules = node.definition.modules.concat(extraModules);
2065
- }
2066
-
2067
- node.hasModules = node.definition.modules?.length > 0;
2068
-
2069
- for (let i = 0; i < node.definition.modules?.length; i++) {
2070
- const temp = node.definition.modules[i];
2071
- const key = Object.keys(temp)[0];
2072
-
2073
- const childNode = {
2074
- name: key,
2075
- childs: [],
2076
- parent: node,
2077
- definition: temp[key],
2078
- module: true,
2079
- blockAutoJumpToParent: true,
2080
- blockAutoJumpToSibling: false,
2081
- index: node.childs.length,
2082
- context: {}
2083
- };
2084
-
2085
- node.childs.push(childNode);
2086
-
2087
- await initNode({ node: childNode });
2088
- }
2089
- }
2090
-
2091
- async function initCommonResolve({ node, transformExpression }) {
2092
- const transform = node.context.transform;
2093
-
2094
- if (Reflect.has(transform, 'export'))
2095
- transform.export = await transformExpression(transform.export);
2096
-
2097
- if (Reflect.has(transform, 'return')) {
2098
- node.hasReturn = true;
2099
- transform.return = await transformExpression(transform.return);
2100
- }
2101
-
2102
- if (transform.hasOwnProperty('nextArgs')) {
2103
- node.hasNextArgs = true;
2104
- transform.nextArgs = await transformExpression(transform.nextArgs);
2105
- }
2106
- }
2107
-
2108
- async function hits$d({ node }) {
2109
- const hit = node.definition.hasOwnProperty('switch');
2110
- if (!hit) return false;
2111
-
2112
- return true;
2113
- }
2114
-
2115
- async function init$d({ node, initNode }) {
2116
- node.type = "switch";
2117
-
2118
- const switchChilds = node.definition.switch || [];
2119
-
2120
- const check = switchChilds.every(w => w.hasOwnProperty('condition') || w.hasOwnProperty('default'));
2121
- if (!check) throw new Error(`Switch must have condition or default`);
2122
-
2123
- const conditionChilds = switchChilds.filter(w => w.hasOwnProperty('condition'));
2124
- if (conditionChilds.length === 0) throw new Error(`Switch must have at least one condition`);
2125
-
2126
- const defaultChilds = switchChilds.filter(w => w.hasOwnProperty('default'));
2127
- if (defaultChilds.length > 1) throw new Error(`Switch must have only one default`);
2128
-
2129
- if (defaultChilds.length === 1 && !switchChilds[switchChilds.length - 1].hasOwnProperty('default'))
2130
- throw new Error(`Switch default must be the last child`);
2131
-
2132
- node.hasDefaultCondition = defaultChilds.length === 1;
2133
-
2134
- await initModules({ node, initNode });
2135
-
2136
- node.blockAutoJumpToParent = false;
2137
- node.blockAutoJumpToSibling = true;
2138
-
2139
- for (let i = 0; i < node.definition.switch.length; i++) {
2140
- let temp = node.definition.switch[i];
2141
- let key = `${i}`;
2142
-
2143
- if (temp.hasOwnProperty('default')) {
2144
- key = 'default';
2145
- temp = temp.default;
2146
- }
2147
-
2148
- const childNode = {
2149
- name: temp.condition || key,
2150
- childs: [],
2151
- parent: node,
2152
- definition: temp,
2153
- index: node.childs.length,
2154
- context: {},
2155
- };
2156
-
2157
- node.childs.push(childNode);
2158
-
2159
- await initNode({ node: childNode });
2160
- }
2161
-
2162
- node.resolve = resolve$c;
2163
- }
2164
-
2165
- async function resolve$c({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2166
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2167
-
2168
- node.context.transform;
2169
-
2170
- for (const child of node.childs) {
2171
- child.context.transform = child.context.transform || cloneDeep(child.definition);
2172
-
2173
- if (child.definition.hasOwnProperty('condition'))
2174
- child.context.transform.condition = await transformExpression(child.definition.condition);
2175
- }
2176
-
2177
- await initCommonResolve({ node, transformExpression });
2178
-
2179
- await resolveTypeCommon({ node });
2180
-
2181
- resolveNextBlock({ node });
2182
- }
2183
-
2184
- var switchBlock = {
2185
- hits: hits$d,
2186
- init: init$d,
2187
- resolve: resolve$c
2188
- };
2189
-
2190
- async function hits$c({ node }) {
2191
- const keys = Object.keys(node.definition);
2192
- const parsedKeys = keys.map(key => fnetExpression({ expression: key }));
2193
-
2194
- const ifProcessors = parsedKeys.filter(key => key?.processor === 'if');
2195
- if (ifProcessors.length !== 1) return false;
2196
-
2197
- return true;
2198
- }
2199
-
2200
- async function init$c(api) {
2201
- const { node } = api;
2202
-
2203
- const keys = Object.keys(node.definition);
2204
- const parsedKeys = keys.map(key => fnetExpression({ expression: key }));
2205
-
2206
- const blocks = [];
2207
-
2208
- // if
2209
- const ifProcessor = parsedKeys.find(key => key?.processor === 'if');
2210
-
2211
- const ifDefinition = node.definition[ifProcessor.expression];
2212
-
2213
- blocks.push({
2214
- name: `${node.name}_if`,
2215
- definition: ifDefinition,
2216
- processor: ifProcessor,
2217
- });
2218
- delete node.definition[ifProcessor.expression];
2219
-
2220
- // else if
2221
- const elseifProcessors = parsedKeys.filter(key => key?.processor === 'elseif');
2222
- let elseIfIndex = 0;
2223
- for (const elseifProcessor of elseifProcessors) {
2224
- const elseifDefinition = node.definition[elseifProcessor.expression];
2225
-
2226
- blocks.push({
2227
- name: `${node.name}_elseif_${elseIfIndex++}`,
2228
- definition: elseifDefinition,
2229
- processor: elseifProcessor,
2230
- });
2231
- delete node.definition[elseifProcessor.expression];
2232
- }
2233
-
2234
- node.definition.switch = [];
2235
-
2236
- for (const block of blocks) {
2237
- node.definition.switch.push({
2238
- condition: block.processor.statement,
2239
- ...block.definition
2240
- });
2241
- }
2242
-
2243
- // else
2244
- if (node.definition?.else) {
2245
- const elseDefinition = node.definition.else;
2246
-
2247
- node.definition.switch.push({
2248
- default: elseDefinition,
2249
- });
2250
-
2251
- delete node.definition['else'];
2252
- }
2253
-
2254
- await switchBlock.init(api);
2255
- }
2256
-
2257
- var ifBlock = {
2258
- hits: hits$c,
2259
- init: init$c
2260
- };
2261
-
2262
- async function hits$b({ node }) {
2263
- return node.definition.hasOwnProperty('try') && node.definition.hasOwnProperty('except');
2264
- }
2265
-
2266
- async function init$b({ node, initNode }) {
2267
- node.type = "tryexcept";
2268
-
2269
- await initModules({ node, initNode });
2270
-
2271
- node.blockAutoJumpToParent = false;
2272
- node.blockAutoJumpToSibling = true;
2273
-
2274
- // try
2275
- if (node.definition.try) {
2276
- const key = "try";
2277
- const childNode = {
2278
- name: key,
2279
- childs: [],
2280
- parent: node,
2281
- definition: node.definition[key],
2282
- index: node.childs.length,
2283
- context: {}
2284
- };
2285
- node.childs.push(childNode);
2286
- await initNode({ node: childNode });
2287
- }
2288
-
2289
- // except
2290
- if (node.definition.except) {
2291
- const key = "except";
2292
- const childNode = {
2293
- name: key,
2294
- childs: [],
2295
- parent: node,
2296
- definition: node.definition[key],
2297
- index: node.childs.length,
2298
- context: {}
2299
- };
2300
- node.childs.push(childNode);
2301
- await initNode({ node: childNode });
2302
- }
2303
-
2304
- node.resolve = resolve$b;
2305
- }
2306
-
2307
- async function resolve$b({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2308
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2309
- node.context.transform;
2310
-
2311
- node.context.try = node.childs.find(w => w.name === 'try');
2312
- node.context.except = node.childs.find(w => w.name === 'except');
2313
-
2314
- if (node.context.except) {
2315
- const child = node.context.except;
2316
- child.context.transform = child.context.transform || cloneDeep(child.definition);
2317
- if (!child.context.transform.hasOwnProperty('as')) child.context.transform.as = 'error';
2318
- }
2319
-
2320
- await initCommonResolve({ node, transformExpression });
2321
-
2322
- await resolveTypeCommon({ node });
2323
-
2324
- resolveNextBlock({ node });
2325
- }
2326
-
2327
- var tryExceptBlock = {
2328
- hits: hits$b,
2329
- init: init$b,
2330
- resolve: resolve$b
2331
- };
2332
-
2333
- async function hits$a({ node }) {
2334
- return node.definition.hasOwnProperty('assign');
2335
- }
2336
-
2337
- async function init$a({ node, initNode }) {
2338
- node.type = "assign";
2339
-
2340
- await initModules({ node, initNode });
2341
-
2342
- node.resolve = resolve$a;
2343
- }
2344
-
2345
- async function resolve$a({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2346
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2347
- const transform = node.context.transform;
2348
-
2349
- for (let i = 0; i < transform.assign?.length; i++) {
2350
- let assign = transform.assign[i];
2351
- let assignKey = Object.keys(assign)[0];
2352
- let assingValue = assign[assignKey];
2353
-
2354
- let assignTransform = {
2355
- key: await transformExpression(assignKey),
2356
- value: await transformExpression(assingValue)
2357
- };
2358
-
2359
- transform.assign[i] = assignTransform;
2360
- }
2361
-
2362
- await initCommonResolve({ node, transformExpression });
2363
-
2364
- await resolveTypeCommon({ node });
2365
- resolveNextBlock({ node });
2366
- }
2367
-
2368
- var assignBlock = {
2369
- hits: hits$a,
2370
- init: init$a,
2371
- resolve: resolve$a
2372
- };
2373
-
2374
- async function hits$9({ node }) {
2375
- return node.definition.hasOwnProperty('for');
2376
- }
2377
-
2378
- async function init$9({ node, initNode }) {
2379
-
2380
- node.type = "for";
2381
-
2382
- await initModules({ node, initNode });
2383
-
2384
- node.blockAutoJumpToParent = true;
2385
- node.blockAutoJumpToSibling = false;
2386
-
2387
- // No steps property
2388
- if (!node.definition.for.hasOwnProperty('steps')) {
2389
- const reserved = ['value', 'in'];
2390
- const [self, child] = [pick(node.definition.for, reserved), omit(node.definition.for, reserved)];
2391
- node.definition.for = self;
2392
- node.definition.for.steps = [
2393
- {
2394
- [`${node.name}_step`]: child
2395
- }
2396
- ];
2397
- }
2398
-
2399
- if (!Array.isArray(node.definition.for.steps)) {
2400
- node.definition.for.steps = [
2401
- {
2402
- [`${node.name}_step`]: node.definition.for.steps
2403
- }
2404
- ];
2405
- }
2406
-
2407
- for (let i = 0; i < node.definition.for.steps.length; i++) {
2408
-
2409
- const temp = node.definition.for.steps[i];
2410
- const key = Object.keys(temp)[0];
2411
-
2412
- const childNode = {
2413
- name: key,
2414
- childs: [],
2415
- parent: node,
2416
- definition: temp[key],
2417
- index: node.childs.length,
2418
- context: {}
2419
- };
2420
-
2421
- node.childs.push(childNode);
2422
-
2423
- await initNode({ node: childNode });
2424
- }
2425
-
2426
- node.resolve = resolve$9;
2427
- }
2428
-
2429
- async function resolve$9({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2430
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2431
- const transform = node.context.transform;
2432
-
2433
- transform.for.in = await transformExpression(node.definition.for.in);
2434
-
2435
- await initCommonResolve({ node, transformExpression });
2436
-
2437
- await resolveTypeCommon({ node });
2438
- resolveNextBlock({ node });
2439
- }
2440
-
2441
- var forBlock = {
2442
- hits: hits$9,
2443
- init: init$9,
2444
- resolve: resolve$9
2445
- };
2446
-
2447
- async function hits$8({ node }) {
2448
- return false;
2449
- }
2450
-
2451
- async function init$8({ node, initNode }) {
2452
- }
2453
-
2454
- async function resolve$8({ node, resolveTypeCommon, resolveNextBlock, transformExpression, transformValue }) {
2455
- }
2456
-
2457
- var parralelBlock = {
2458
- hits: hits$8,
2459
- init: init$8,
2460
- resolve: resolve$8
2461
- };
2462
-
2463
- async function hits$7({ node }) {
2464
- return node.definition.hasOwnProperty('raise');
2465
- }
2466
-
2467
- async function init$7({ node, initNode }) {
2468
- node.type = "raise";
2469
-
2470
- node.resolve = resolve$7;
2471
- }
2472
-
2473
- async function resolve$7({ node, resolveTypeCommon, transformExpression }) {
2474
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2475
- const transform = node.context.transform;
2476
-
2477
- transform.raise = await transformExpression(transform.raise);
2478
-
2479
- await resolveTypeCommon({ node });
2480
- }
2481
-
2482
- var raiseBlock = {
2483
- hits: hits$7,
2484
- init: init$7,
2485
- resolve: resolve$7
2486
- };
2487
-
2488
- async function hits$6({ node }) {
2489
- return node.definition.hasOwnProperty('return');
2490
- }
2491
-
2492
- async function init$6({ node, initNode }) {
2493
- node.type = "return";
2494
-
2495
- node.resolve = resolve$6;
2496
- }
2497
-
2498
- async function resolve$6({ node, resolveTypeCommon, transformExpression }) {
2499
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2500
- const transform = node.context.transform;
2501
- node.hasReturn = true;
2502
- transform.return = await transformExpression(transform.return);
2503
- await resolveTypeCommon({ node });
2504
- }
2505
-
2506
- var returnBlock = {
2507
- hits: hits$6,
2508
- init: init$6,
2509
- resolve: resolve$6
2510
- };
2511
-
2512
- async function hits$5({ node }) {
2513
- return node.definition.hasOwnProperty('call');
2514
- }
2515
-
2516
- async function init$5({ node, initNode }) {
2517
- node.type = "call";
2518
-
2519
- await initModules({ node, initNode });
2520
-
2521
- node.resolve = resolve$5;
2522
- }
2523
-
2524
- async function resolve$5({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2525
-
2526
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2527
- const transform = node.context.transform;
2528
-
2529
- if (node.target?.atom?.doc?.type === 'function') {
2530
- transform.call = await transformExpression(node.target.atom.name);
2531
- }
2532
-
2533
- if (transform.args)
2534
- transform.args = await transformExpression(transform.args);
2535
-
2536
- if (transform.result) {
2537
- if (typeof transform.result === 'string') {
2538
- transform.result = [{ [transform.result]: "e::result" }];
2539
- }
2540
-
2541
- for (let i = 0; i < transform.result?.length; i++) {
2542
- let assign = transform.result[i];
2543
- let assignKey = Object.keys(assign)[0];
2544
- let assingValue = assign[assignKey];
2545
-
2546
- let assignTransform = {
2547
- key: await transformExpression(assignKey),
2548
- value: await transformExpression(assingValue)
2549
- };
2550
-
2551
- transform.result[i] = assignTransform;
2552
- }
2553
-
2554
- // transform.result = await transformExpression(transform.result);
2555
- }
2556
- const root = node.workflow.parent;
2557
-
2558
- if (transform.import)
2559
- node.context.lib = root.context.libs.find(w => w.name === transform.import);
2560
- else
2561
- node.context.lib = root.context.libs.find(w => w.name === transform.call);
2562
-
2563
- await initCommonResolve({ node, transformExpression });
2564
-
2565
- await resolveTypeCommon({ node });
2566
-
2567
- resolveNextBlock({ node });
2568
- }
2569
-
2570
- var callBlock = {
2571
- hits: hits$5,
2572
- init: init$5,
2573
- resolve: resolve$5
2574
- };
2575
-
2576
- async function hits$4({ node }) {
2577
- return node.definition.hasOwnProperty('steps');
2578
- }
2579
-
2580
- async function init$4({ node, initNode }) {
2581
- if (!node.type) node.type = 'steps';
2582
-
2583
- const steps = node.definition.steps || [];
2584
-
2585
- for await (const step of steps) {
2586
- const key = Object.keys(step)[0];
2587
- const childNode = {
2588
- name: key,
2589
- childs: [],
2590
- parent: node,
2591
- definition: step[key],
2592
- index: node.childs.length,
2593
- context: {
2594
- }
2595
- };
2596
-
2597
- node.childs.push(childNode);
2598
-
2599
- await initNode({ node: childNode });
2600
- }
2601
-
2602
- node.resolve = resolve$4;
2603
- }
2604
-
2605
- async function resolve$4({ node, transformExpression }) {
2606
- node.context.next = node.childs[0];
2607
-
2608
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2609
-
2610
- await initCommonResolve({ node, transformExpression });
2611
-
2612
- }
2613
-
2614
- var stepsBlock = {
2615
- hits: hits$4,
2616
- init: init$4,
2617
- resolve: resolve$4
2618
- };
2619
-
2620
- async function hits$3({ node }) {
2621
- return node.definition.hasOwnProperty('form');
2622
- }
2623
-
2624
- async function init$3({ node, initNode }) {
2625
- node.type = "form";
2626
-
2627
- await initModules({ node, initNode });
2628
-
2629
- node.resolve = resolve$3;
2630
- }
2631
-
2632
- async function resolve$3({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2633
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2634
- const transform = node.context.transform;
2635
-
2636
- if (transform.props)
2637
- transform.props = await transformExpression(transform.props);
2638
-
2639
-
2640
- const root = node.workflow.parent;
2641
-
2642
- node.context.lib = root.context.libs.find(w => w.name === transform.form);
2643
-
2644
- await initCommonResolve({ node, transformExpression });
2645
-
2646
- await resolveTypeCommon({ node });
2647
-
2648
- resolveNextBlock({ node });
2649
- }
2650
-
2651
- var formBlock = {
2652
- hits: hits$3,
2653
- init: init$3,
2654
- resolve: resolve$3
2655
- };
2656
-
2657
- async function hits$2({ node }) {
2658
- return node.definition.hasOwnProperty('operation');
2659
- }
2660
-
2661
- async function init$2({ node, initNode }) {
2662
- node.type = "operation";
2663
-
2664
- node.resolve = resolve$2;
2665
- }
2666
-
2667
- async function resolve$2({ node, resolveTypeCommon, resolveNextBlock, transformExpression, transformValue }) {
2668
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2669
-
2670
- await resolveTypeCommon({ node });
2671
- }
2672
-
2673
- var operationBlock = {
2674
- hits: hits$2,
2675
- init: init$2,
2676
- resolve: resolve$2
2677
- };
2678
-
2679
- async function hits$1({ node }) {
2680
- return node.definition.hasOwnProperty('next');
2681
- }
2682
-
2683
- async function init$1({ node, initNode }) {
2684
- node.type = "jump";
2685
-
2686
- node.resolve = resolve$1;
2687
- }
2688
-
2689
- async function resolve$1({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2690
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2691
- const transform = node.context.transform;
2692
-
2693
- transform.next = await transformExpression(transform.next);
2694
-
2695
- await initCommonResolve({ node, transformExpression });
2696
-
2697
- await resolveTypeCommon({ node });
2698
- resolveNextBlock({ node });
2699
- }
2700
-
2701
- var jumpBlock = {
2702
- hits: hits$1,
2703
- init: init$1,
2704
- resolve: resolve$1
2705
- };
2706
-
2707
- async function hits({ node }) {
2708
- return node.definition.hasOwnProperty('modules');
2709
- }
2710
-
2711
- async function init({ node, initNode }) {
2712
- node.type = "modules";
2713
-
2714
- await initModules({ node, initNode });
2715
-
2716
- node.resolve = resolve;
2717
- }
2718
-
2719
- async function resolve({ node, resolveTypeCommon, resolveNextBlock, transformExpression }) {
2720
-
2721
- node.context.transform = node.context.transform || cloneDeep(node.definition);
2722
- node.context.transform;
2723
-
2724
- await initCommonResolve({ node, transformExpression });
2725
-
2726
- await resolveTypeCommon({ node });
2727
-
2728
- resolveNextBlock({ node });
2729
- }
2730
-
2731
- var modulesBlock = {
2732
- hits,
2733
- init,
2734
- resolve
2735
- };
2736
-
2737
- function resolveNextBlock({ node }) {
2738
- const definition = node.definition;
2739
-
2740
- if(node.hasReturn) return;
2741
-
2742
- if (definition.next === 'end') ;
2743
- else if (definition.next === 'stop') ;
2744
- else if (definition.next === 'none') ;
2745
- else if (definition.next) {
2746
-
2747
- // FIND NEXT BLOCK BY NAME
2748
- // TRY SIBLINGS UNTIL ROOT
2749
- let current = node.parent;
2750
- while (current.parent) {
2751
- const found = current.childs.find(w => w.name === definition.next);
2752
-
2753
- if (found) {
2754
- node.context.next = found;
2755
- break;
2756
- }
2757
-
2758
- current = current.parent;
2759
- }
2760
- }
2761
- else {
2762
-
2763
- // AUTO NEXT BLOCK IS DISABLED FOR MODULE ROOT
2764
- if (node.module === true) {
2765
- return;
2766
- }
2767
-
2768
- // AUTO FINDING NEXT BLOCK
2769
- let parent = node.parent;
2770
- let targetIndex = node.index + 1;
2771
-
2772
- while (parent.parent) {
2773
-
2774
- // NEITHER JUMP TO PARENT NOR SIBLING ENABLED
2775
- if (parent.blockAutoJumpToParent && parent.blockAutoJumpToSibling)
2776
- break;
2777
- else if (!Reflect.has(parent, 'blockAutoJumpToParent') && !Reflect.has(parent, 'blockAutoJumpToSibling')) {
2778
-
2779
- const found = parent.childs.find(w => w.index === targetIndex);
2780
- if (found) {
2781
- // JUMP TO SIBLING
2782
- node.context.next = found;
2783
- break;
2784
- } else {
2785
- // JUMP TO PARENT
2786
- targetIndex = parent.index + 1;
2787
- parent = parent.parent;
2788
- continue;
2789
- }
2790
- }
2791
- else if (parent.blockAutoJumpToParent) {
2792
- // JUMP TO PARENT DISABLED
2793
- // SIBLING ENABLED
2794
- const found = parent.childs.find(w => w.index === targetIndex);
2795
- if (found) node.context.next = found;
2796
- break;
2797
- }
2798
- else if (!parent.blockAutoJumpToParent) {
2799
- // JUMP TO PARENT ENABLED
2800
- // SIBLING DISABLED
2801
- targetIndex = parent.index + 1;
2802
- parent = parent.parent;
2803
- continue;
2804
- }
2805
- }
2806
- }
2807
- }
2808
-
2809
- class NpmWrapper {
2810
- #key;
2811
- #npm;
2812
- #master;
2813
- #extras;
2814
-
2815
- constructor({ key, npm, master, extras }) {
2816
- this.#key = key;
2817
- this.#npm = npm;
2818
- this.#master = master;
2819
- this.#extras = extras;
2820
- }
2821
-
2822
- hits({ node }) {
2823
- return node.definition.hasOwnProperty(this.#key);
2824
- }
2825
-
2826
- async init(api) {
2827
- const { node } = api;
2828
-
2829
- const name = this.#key;
2830
- const definition = node.definition;
2831
- const valueType = typeof definition[name];
2832
-
2833
- definition.call = `npm:${this.#npm}`;
2834
- if (valueType !== 'object') definition.args = { ...definition.args, [`${this.#master}`]: definition[name] };
2835
- else definition.args = definition[name];
2836
- delete definition[name];
2837
-
2838
- if (this.#extras) {
2839
- for (const extra in this.#extras) {
2840
- definition[extra] = this.#extras[extra];
2841
- }
2842
- }
2843
-
2844
- console.log(`[npm-block] ${this.#key} --> ${this.#npm}`);
2845
- await callBlock.init(api);
2846
- }
2847
- }
2848
-
2849
- function createNpmWrapper(args) {
2850
- return new NpmWrapper(args);
2851
- }
2852
-
2853
- class Builder {
2854
-
2855
- #auth;
2856
- #context;
2857
- #atom;
2858
- #workflow;
2859
- #njEnv;
2860
- #packageDependencies;
2861
- #packageDevDependencies;
2862
- #stepTemplateCache;
2863
- #atomAccessToken;
2864
- #root;
2865
- #buildId;
2866
- #buildKey;
2867
- #protocol;
2868
- #atomConfig;
2869
-
2870
- #mode;
2871
- #fileMode;
2872
- #buildMode;
2873
- #deployMode;
2874
- #bpmnMode;
2875
- #apiContext;
2876
- #blockBuilderContext;
2877
- #npmBlocks = []
2878
-
2879
- constructor(context) {
2880
-
2881
- this.#auth = new Auth();
2882
- this.#context = context;
2883
- this.#packageDependencies = [];
2884
- this.#packageDevDependencies = [];
2885
- this.#stepTemplateCache = {};
2886
-
2887
- this._expire_ttl = 3600; // 1-hour
2888
- this._expire_ttl_short = 300; // 5-minutes
2889
-
2890
- this.#npmBlocks.push(createNpmWrapper({ key: 'config', npm: '@fnet/config', master: "name" }));
2891
- this.#npmBlocks.push(createNpmWrapper({ key: 'yaml', npm: '@fnet/yaml', master: "file" }));
2892
- this.#npmBlocks.push(createNpmWrapper({ key: 'prompt', npm: '@fnet/prompt', master: "message" }));
2893
- this.#npmBlocks.push(createNpmWrapper({ key: 'html-link', npm: '@flownet/lib-load-browser-link-url', master: "src" }));
2894
- this.#npmBlocks.push(createNpmWrapper({ key: 'html-script', npm: '@flownet/lib-load-browser-script-url', master: "src" }));
2895
- this.#npmBlocks.push(createNpmWrapper({ key: 'http-server', npm: '@fnet/node-express', master: "server_port" }));
2896
- this.#npmBlocks.push(createNpmWrapper({ key: 'shell', npm: '@fnet/shell-flow', master: "commands" }));
2897
- this.#npmBlocks.push(createNpmWrapper({ key: 'list-files', npm: '@fnet/list-files', master: "pattern" }));
2898
- this.#npmBlocks.push(createNpmWrapper({ key: 'up-list-files', npm: '@fnet/up-list-files', master: "pattern" }));
2899
- this.#npmBlocks.push(createNpmWrapper({ key: 'auto-conda-env', npm: '@fnet/auto-conda-env', master: "envDir" }));
2900
- this.#npmBlocks.push(createNpmWrapper({ key: 'ollama-chat', npm: '@fnet/ollama-chat', master: "model" }));
2901
- this.#npmBlocks.push(createNpmWrapper({ key: 'ai', npm: '@fnet/ai', master: "prompt", extras: { subtype: "flow" } }));
2902
- this.#npmBlocks.push(createNpmWrapper({ key: 'invoke', npm: '@fnet/invoke', master: "method", extras: {} }));
2903
- this.#npmBlocks.push(createNpmWrapper({ key: 'fetch', npm: '@fnet/fetch', master: "url", extras: {} }));
2904
- this.#npmBlocks.push(createNpmWrapper({ key: 'filemap', npm: '@fnet/filemap', master: "target", extras: {} }));
2905
-
2906
- this.#apiContext = {
2907
- packageDependencies: this.#packageDependencies,
2908
- packageDevDependencies: this.#packageDevDependencies,
2909
- setProgress: this.setProgress.bind(this),
2910
- context: this.#context,
2911
- Atom,
2912
- registerToPackageManager: this.registerToPackageManager.bind(this)
2913
- };
2914
-
2915
- this.#blockBuilderContext = {
2916
- initNode: this.initNode.bind(this),
2917
- cloneDeep: cloneDeep,
2918
- resolveTypeCommon: this.resolveTypeCommon.bind(this),
2919
- resolveNextBlock: resolveNextBlock,
2920
- transformExpression: this.transformExpression.bind(this),
2921
- transformValue: this.transformValue.bind(this),
2922
- };
2923
- }
2924
-
2925
- async _cache_set(key, value, expire_ttl) {
2926
- if (!this._redis_client) return;
2927
-
2928
- await this._redis_client.SETEX(
2929
- key,
2930
- expire_ttl || this._expire_ttl,
2931
- JSON.stringify(value),
2932
- ).catch(console.error);
2933
- }
2934
-
2935
- async init() {
2936
-
2937
- this._redis_client = await createRedisClient();
2938
-
2939
- this.#buildId = this.#context.buildId || randomUUID();
2940
- this.#apiContext.buildId = this.#buildId;
2941
-
2942
- this.#mode = this.#context.mode;
2943
- this.#fileMode = ['all', 'deploy', 'build', 'file'].includes(this.#mode);
2944
- this.#buildMode = ['all', 'deploy', 'build'].includes(this.#mode);
2945
- this.#deployMode = ['all', 'deploy'].includes(this.#mode);
2946
- this.#bpmnMode = ['all', 'deploy', 'build', 'file', 'bpmn'].includes(this.#mode);
2947
-
2948
- this.#protocol = this.#context.protocol;
2949
- this.#buildKey = "BUILD:" + this.#buildId;
2950
-
2951
- this.#atomConfig = (await fnetConfig({ optional: true, name: "atom", dir: this.#context.projectDir, tags: this.#context.tags }))?.data;
2952
-
2953
- try {
2954
- await this.setProgress({ message: "Initialization started." });
2955
-
2956
- await this.initAuth();
2957
- await this.initWorkflow();
2958
-
2959
- // await initFeatures(this.#apiContext);
2960
- // await initDependencies(this.#apiContext);
2961
-
2962
- this.transformWorkflow({ workflow: this.#workflow });
2963
-
2964
- const root = await this.initNodeTree({ workflow: this.#workflow });
2965
- await this.initNodeTreeIndex({ root });
2966
-
2967
- await this.initNodeCalls({ root });
2968
- await this.initNodeCallLibs({ root });
2969
-
2970
- await this.initNodeForms({ root });
2971
- await this.initNodeFormLibs({ root });
2972
-
2973
- await this.initEntryFiles({ root, features: this.#atom.doc.features });
2974
- await this.initFeaturesFromNodes({ childs: root.childs, features: this.#atom.doc.features });
2975
-
2976
- await initFeatures(this.#apiContext);
2977
- await initDependencies(this.#apiContext);
2978
-
2979
- await this.initAtomLibsAndDeps({ libs: root.context.libs, packageDependencies: this.#packageDependencies });
2980
-
2981
- await this.resolveNodeTree({ root });
2982
-
2983
- this.#root = root;
2984
- }
2985
- catch (error) {
2986
- await this._cache_set(this.#buildKey, { status: "FAILED", message: error?.message || error });
2987
- throw error;
2988
- }
2989
- }
2990
-
2991
- async initAuth() {
2992
- if (!this.#context.id) return;
2993
- this.#atomAccessToken = await this.#auth.init({ config: this.#atomConfig });
2994
- this.#apiContext.atomAccessToken = this.#atomAccessToken;
2995
- }
2996
-
2997
- async initWorkflow() {
2998
- const workflowId = this.#context.id;
2999
- this.#atom = this.#context.project?.workflowAtom || await Atom.get({ id: workflowId });
3000
- this.#workflow = typeof this.#atom.doc.content === 'string' ? (await fnetYaml({ content: this.#atom.doc.content, tags: this.#context.tags })).parsed : this.#atom.doc.content;
3001
- let bundleName = this.#atom.doc.bundleName;
3002
- bundleName = bundleName || (this.#atom.doc.name || "").toUpperCase().replace(/[^A-Z0-9]/g, "_");
3003
- this.#atom.doc.bundleName = bundleName;
3004
- this.#atom.type = this.#atom.type || "workflow";
3005
-
3006
- this.#apiContext.atom = this.#atom;
3007
-
3008
- this.#atom.doc.features = this.#atom.doc.features || {};
3009
- }
3010
-
3011
- #recursiveDelete(filePath) {
3012
- console.log('filePath', filePath);
3013
- if (fs.statSync(filePath).isDirectory()) {
3014
- fs.readdirSync(filePath).forEach(file => {
3015
- const curPath = path.join(filePath, file);
3016
- this.#recursiveDelete(curPath);
3017
- });
3018
- fs.rmSync(filePath);
3019
- } else {
3020
- fs.unlinkSync(filePath);
3021
- }
3022
- }
3023
- #copyRecursiveSync(src, dest) {
3024
- const exists = fs.existsSync(src);
3025
- const stats = exists && fs.statSync(src);
3026
- const isDirectory = exists && stats.isDirectory();
3027
- if (isDirectory) {
3028
- fs.mkdirSync(dest, { recursive: true });
3029
- fs.readdirSync(src).forEach(childItemName => {
3030
- this.#copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
3031
- });
3032
- } else {
3033
- fs.copyFileSync(src, dest);
3034
- }
3035
- }
3036
- async initWorkflowDir() {
3037
-
3038
- this.setProgress({ message: "Initializing library directory." });
3039
-
3040
- const projectDir = this.#context.projectDir;
3041
- const coreDir = this.#context.coreDir;
3042
-
3043
- this.setProgress({ message: "Cleaning project directory." });
3044
-
3045
- const assets = fnetListFiles({ dir: projectDir, ignore: ['.cache', 'node_modules', '.conda'], absolute: true });
3046
-
3047
- for (const asset of assets) {
3048
- fs.rmSync(asset, { recursive: true, force: true });
3049
- }
3050
-
3051
- this.setProgress({ message: "Creating project directory." });
3052
-
3053
- // Create projectDir if it doesn't exist.
3054
- if (!fs.existsSync(projectDir)) {
3055
- fs.mkdirSync(projectDir, { recursive: true });
3056
- }
3057
-
3058
- // Create src directory.
3059
- const srcDir = path.join(projectDir, 'src');
3060
- if (!fs.existsSync(srcDir)) {
3061
- fs.mkdirSync(srcDir, { recursive: true });
3062
- }
3063
-
3064
- // Copy coreDir to src/core
3065
- const srcCoreDir = path.join(srcDir, 'core');
3066
- this.#copyRecursiveSync(coreDir, srcCoreDir);
3067
-
3068
- // Create src/default/blocks directory.
3069
- const blocksDir = path.join(srcDir, 'default', 'blocks');
3070
- if (!fs.existsSync(blocksDir)) {
3071
- fs.mkdirSync(blocksDir, { recursive: true });
3072
- }
3073
- }
3074
-
3075
- async initNunjucks() {
3076
- this.setProgress({ message: "Initializing nunjucks." });
3077
-
3078
- const templateDir = this.#context.templateDir;
3079
- this.#njEnv = nunjucks.configure(templateDir, { watch: false, dev: true });
3080
- this.#apiContext.njEnv = this.#njEnv;
3081
- }
3082
-
3083
- /**
3084
- * Transforms the given workflow by applying transformation rules on each step.
3085
- * @param {Object} workflow - The workflow to be transformed.
3086
- */
3087
- transformWorkflow({ workflow }) {
3088
- for (const flow of Object.values(workflow)) {
3089
- // Ensure steps exist as an array.
3090
- flow.steps = flow.steps || [];
3091
- flow.steps = flow.steps.filter(w => Object.keys(w).length > 0);
3092
-
3093
- // Transform each step.
3094
- flow.steps = flow.steps.map(step => this.transformStep({ step }));
3095
- }
3096
- }
3097
-
3098
- /**
3099
- * Transforms the given step based on certain rules.
3100
- * For example, replaces 'onerror' with 'try-except' structure.
3101
- * @param {Object} step - The step to be transformed.
3102
- * @returns {Object} The transformed step.
3103
- */
3104
- transformStep({ step }) {
3105
- // Validate input.
3106
- if (Array.isArray(step)) throw new Error('Step must be an object.');
3107
-
3108
- const [stepName, stepDefinition] = Object.entries(step)[0];
3109
-
3110
- // Transform 'onerror' into 'try-except'.
3111
- if (stepDefinition.hasOwnProperty('onerror')) {
3112
- const { onerror, ...rest } = stepDefinition;
3113
- step[stepName] = {
3114
- try: rest,
3115
- except: onerror
3116
- };
3117
- }
3118
-
3119
- // Recursively transform child steps if they exist.
3120
- if (step[stepName].hasOwnProperty('steps')) {
3121
- const childSteps = step[stepName].steps;
3122
- if (!Array.isArray(childSteps)) throw new Error('Steps must be an array.');
3123
- step[stepName].steps = childSteps.map(childStep => this.transformStep({ step: childStep }));
3124
- }
3125
-
3126
- return step;
3127
- }
3128
-
3129
- async initNodeTree({ workflow }) {
3130
-
3131
- const workflowKeys = Object.keys(workflow);
3132
-
3133
- const root = {
3134
- definition: workflow,
3135
- name: undefined,
3136
- type: "root",
3137
- parent: undefined,
3138
- childs: [],
3139
- blockAutoJumpToParent: true,
3140
- blockAutoJumpToSibling: true,
3141
- index: 0,
3142
- depth: 0,
3143
- context: {
3144
- libs: [],
3145
- atom: this.#atom
3146
- }
3147
- };
3148
-
3149
- workflowKeys.forEach(flowName => {
3150
- const node = {
3151
- name: flowName,
3152
- type: flowName === 'main' ? 'workflow' : "subworkflow",
3153
- childs: [],
3154
- parent: root,
3155
- definition: workflow[flowName],
3156
- index: root.childs.length,
3157
- depth: root.depth + 1,
3158
- context: {},
3159
- blockAutoJumpToParent: true,
3160
- blockAutoJumpToSibling: false,
3161
- };
3162
-
3163
- root.childs.push(node);
3164
- });
3165
-
3166
- for await (const node of root.childs) {
3167
- await this.initNode({ node });
3168
- }
3169
-
3170
- return root;
3171
- }
3172
-
3173
- async initNode({ node }) {
3174
-
3175
- const api = { ...this.#blockBuilderContext, node };
3176
-
3177
- node.workflow = node.parent.workflow || node; //?
3178
- node.depth = node.parent.depth + 1;
3179
-
3180
- if (await tryExceptBlock.hits(api)) await tryExceptBlock.init(api);
3181
- else if (await forBlock.hits(api)) await forBlock.init(api);
3182
- else if (await switchBlock.hits(api)) await switchBlock.init(api);
3183
- else if (await ifBlock.hits(api)) await ifBlock.init(api);
3184
- else if (await parralelBlock.hits(api)) await parralelBlock.init(api);
3185
- else if (await assignBlock.hits(api)) await assignBlock.init(api);
3186
- else if (await raiseBlock.hits(api)) await raiseBlock.init(api);
3187
- else if (await callBlock.hits(api)) await callBlock.init(api);
3188
- else if (this.#npmBlocks.find(w => w.hits(api))) await (this.#npmBlocks.find(w => w.hits(api))).init(api);
3189
- else if (await formBlock.hits(api)) await formBlock.init(api);
3190
- else if (await operationBlock.hits(api)) await operationBlock.init(api);
3191
- else if (await stepsBlock.hits(api)) await stepsBlock.init(api);
3192
- else if (await jumpBlock.hits(api)) await jumpBlock.init(api);
3193
- else if (await modulesBlock.hits(api)) await modulesBlock.init(api);
3194
- else if (await returnBlock.hits(api)) await returnBlock.init(api);
3195
- else throw new Error('Undefined step type.');
3196
- }
3197
-
3198
- async initNodeTreeIndex({ root }) {
3199
- const index = {};
3200
-
3201
- root.indexKey = "/";
3202
- for await (const child of root.childs) {
3203
- await this.initNodeIndex({ node: child, index });
3204
- }
3205
-
3206
- root.context.index = index;
3207
-
3208
- return index;
3209
- }
3210
-
3211
- async initNodeIndex({ node, index }) {
3212
-
3213
- const indexKey = path.join(node.parent.indexKey, node.name);
3214
- node.indexKey = indexKey;
3215
- index[indexKey] = node;
3216
-
3217
- const levels = [];
3218
- let current = node;
3219
- while (current?.parent) {
3220
- levels.push(current.index);
3221
- current = current.parent;
3222
- }
3223
- levels.reverse();
3224
-
3225
- node.codeKey = `B_${levels.join('_')}_${node.type}`;
3226
- node.pathKey = `${levels.join('.')}`;
3227
- node.typeId = randomUUID();
3228
-
3229
- for await (const child of node.childs) {
3230
- await this.initNodeIndex({ node: child, index });
3231
- }
3232
- }
3233
-
3234
- async initNodeCalls({ root }) {
3235
-
3236
- const index = root.context.index;
3237
-
3238
- const callNodes = [];
3239
- for await (const indexKey of Object.keys(index)) {
3240
- const node = index[indexKey];
3241
- if (node.type !== 'call') continue;
3242
-
3243
- callNodes.push(node);
3244
- }
3245
-
3246
- root.context.calls = callNodes;
3247
-
3248
- return callNodes;
3249
- }
3250
-
3251
- async initNodeCallLibs({ root }) {
3252
- const libs = [];
3253
- const calls = root.context.calls;
3254
-
3255
- for await (const node of calls) {
3256
- const callName = node.definition.import || node.definition.call;
3257
-
3258
- const targetNode =
3259
- await this.findNodeCallTarget({ refNode: node, curNode: node.parent }) ||
3260
- {
3261
- name: callName,
3262
- type: "atom",
3263
- definition: node.definition,
3264
- };
3265
-
3266
- const foundTargetNode = libs.find(w => w.name === targetNode.name && w.type === targetNode.type);
3267
- if (!foundTargetNode) libs.push(targetNode);
3268
-
3269
- node.target = foundTargetNode || targetNode;
3270
- }
3271
-
3272
- root.context.callLibs = libs;
3273
- root.context.libs = [...root.context.libs, ...libs];
3274
- return libs;
3275
- }
3276
-
3277
- async findNodeCallTarget({ refNode, curNode }) {
3278
- if (!curNode) return;
3279
-
3280
- const callName = refNode.definition.call;
3281
-
3282
- const found = curNode.childs.find(w => w.name === callName && w.type === 'subworkflow');
3283
-
3284
- if (found) return found;
3285
- else return await this.findNodeCallTarget({ refNode, curNode: curNode.parent });
3286
- }
3287
-
3288
- async initNodeForms({ root }) {
3289
-
3290
- const index = root.context.index;
3291
-
3292
- const formNodes = [];
3293
- for await (const indexKey of Object.keys(index)) {
3294
- const node = index[indexKey];
3295
- if (node.type !== 'form') continue;
3296
-
3297
- formNodes.push(node);
3298
- }
3299
-
3300
- root.context.forms = formNodes;
3301
-
3302
- return formNodes;
3303
- }
3304
-
3305
- async initNodeFormLibs({ root }) {
3306
- const libs = [];
3307
-
3308
- const forms = root.context.forms;
3309
-
3310
- for await (const node of forms) {
3311
- const formName = node.definition.import || node.definition.form;
3312
-
3313
- const targetNode =
3314
- await this.findNodeCallTarget({ refNode: node, curNode: node.parent }) ||
3315
- {
3316
- name: formName,
3317
- type: "atom"
3318
- };
3319
-
3320
- const foundTargetNode = libs.find(w => w.name === targetNode.name && w.type === targetNode.type);
3321
- if (!foundTargetNode) libs.push(targetNode);
3322
-
3323
- node.target = foundTargetNode || targetNode;
3324
- }
3325
-
3326
- root.context.formLibs = libs;
3327
- root.context.libs = [...root.context.libs, ...libs];
3328
-
3329
- return libs;
3330
- }
3331
-
3332
- async initFeaturesFromNodes({ childs, features }) {
3333
-
3334
- for await (const child of childs) {
3335
-
3336
- if (child.type === 'form' && !Reflect.has(features, 'form')) features.form = true;
3337
-
3338
- await this.initFeaturesFromNodes({ childs: child.childs, features });
3339
- }
3340
- }
3341
-
3342
- async initEntryFiles({ root, features }) {
3343
-
3344
- for await (const flow of root.childs) {
3345
-
3346
- let fileName;
3347
-
3348
- if (flow.name === 'main') fileName = `index.js`;
3349
- else if (flow.name === 'cli') fileName = `cli.js`;
3350
- else if (flow.name === 'app') fileName = `app.js`;
3351
- else if (flow.name === 'api') fileName = `api.js`;
3352
- else continue;
3353
-
3354
- features[`${flow.name}_default_entry_file`] = fileName;
3355
-
3356
- flow.entryFile = fileName;
3357
- }
3358
- }
3359
-
3360
- async findNodeFormTarget({ refNode, curNode }) {
3361
- if (!curNode) return;
3362
-
3363
- const formName = refNode.definition.form;
3364
-
3365
- const found = curNode.childs.find(w => w.name === formName && w.type === 'subworkflow');
3366
-
3367
- if (found) return found;
3368
- else return await this.findNodeFormTarget({ refNode, curNode: curNode.parent });
3369
- }
3370
-
3371
- async initAtomLibsAndDeps({ libs, packageDependencies }) {
3372
- const atomLibRefs = libs.filter(w => w.type === 'atom');
3373
- for (let i = 0; i < atomLibRefs.length; i++) {
3374
- const atomLibRef = atomLibRefs[i];
3375
-
3376
- const atomLib = await this.findAtomLibrary({ url: atomLibRef.name, libRef: atomLibRef });
3377
- atomLibRef.atom = atomLib;
3378
-
3379
- const packageDeps = atomLib.doc.dependencies?.filter(w => typeof w.repo === 'undefined' || w.repo === 'npm');
3380
- packageDeps?.forEach(npmDep => {
3381
- const found = packageDependencies.find(w => w.package === npmDep.package);
3382
- if (found) {
3383
- if (typeof npmDep.path === 'string') {
3384
- if (!(found.path || []).some(w => w === npmDep.path)) {
3385
- found.path = found.path || [];
3386
- found.path.push(npmDep.path);
3387
- }
3388
- }
3389
- else if (Array.isArray(npmDep.path)) {
3390
- npmDep.path.forEach(item => {
3391
- if (!(found.path || []).some(w => w === item)) {
3392
- found.path = found.path || [];
3393
- found.path.push(item);
3394
- }
3395
- });
3396
- }
3397
- }
3398
- else packageDependencies.push(npmDep);
3399
- });
3400
- }
3401
-
3402
- packageDependencies.sort((a, b) => a.package?.localeCompare(b.package));
3403
- }
3404
-
3405
- async findAtomLibrary({ url, libRef }) {
3406
- const parsedUrl = fnetParseNodeUrl({ url: url });
3407
- if (!parsedUrl) throw new Error(`Invalid package name: ${url}`);
3408
-
3409
- if (!parsedUrl.protocol) parsedUrl.protocol = this.#protocol;
3410
-
3411
- if (parsedUrl.protocol === 'ac:') {
3412
- const parts = parsedUrl.pathname.split('/');
3413
- if (parts.length === 1) {
3414
- return await Atom.first({ where: { name: url, parent_id: this.#atomConfig.env.ATOM_LIBRARIES_ID, type: "workflow.lib" } });
3415
- }
3416
-
3417
- if (parts.length === 2) {
3418
- const folder = await Atom.first({ where: { name: parts[0], parent_id: this.#atomConfig.env.ATOM_LIBRARIES_ID, type: "folder" } });
3419
- return await Atom.first({ where: { name: parts[1], parent_id: folder.id, type: "workflow.lib" } });
3420
- }
3421
- }
3422
- else if (parsedUrl.protocol === 'local:') {
3423
-
3424
- const srcFilePath = path.resolve(this.#context.projectSrcDir, `${parsedUrl.pathname}.js`);
3425
- const dependencies = [];
3426
-
3427
- const parsedImports = await fnetParseImports({ file: srcFilePath, recursive: true });
3428
- const targetImports = parsedImports.all;
3429
-
3430
- for await (const parsedImport of targetImports) {
3431
- if (parsedImport.type !== 'npm') continue;
3432
-
3433
- if (dependencies.find(w => w.package === parsedImport.package)) continue;
3434
-
3435
- const npmVersions = await pickNpmVersions({
3436
- name: parsedImport.package,
3437
- projectDir: this.#context.projectDir,
3438
- setProgress: this.#apiContext.setProgress
3439
- });
3440
-
3441
- dependencies.push({
3442
- package: parsedImport.package,
3443
- subpath: parsedImport.subpath,
3444
- version: npmVersions.minorRange,
3445
- type: "npm"
3446
- });
3447
- }
3448
-
3449
- const atom = {
3450
- name: parsedUrl.pathname,
3451
- doc: {
3452
- type: "workflow.lib",
3453
- "content-type": "javascript",
3454
- language: "js",
3455
- dependencies,
3456
- },
3457
- protocol: parsedUrl.protocol,
3458
- };
3459
- return atom;
3460
- }
3461
- else if (parsedUrl.protocol === 'npm:') {
3462
-
3463
- const npmVersions = await pickNpmVersions({
3464
- name: parsedUrl.pathname,
3465
- projectDir: this.#context.projectDir,
3466
- setProgress: this.#apiContext.setProgress
3467
- });
3468
-
3469
- const atom = {
3470
- name: parsedUrl.pathname,
3471
- doc: {
3472
- type: "workflow.lib",
3473
- subtype: libRef?.definition?.subtype === 'flow' ? "workflow" : null,
3474
- "content-type": "javascript",
3475
- language: "js",
3476
- dependencies: [
3477
- {
3478
- package: parsedUrl.pathname,
3479
- version: npmVersions.minorRange,
3480
- type: "npm"
3481
- }
3482
- ],
3483
- },
3484
- protocol: parsedUrl.protocol,
3485
- };
3486
- return atom;
3487
- }
3488
- else if (parsedUrl.protocol === 'use:') {
3489
- const atom = {
3490
- name: parsedUrl.pathname,
3491
- doc: {
3492
- type: "function",
3493
- dependencies: []
3494
- },
3495
- protocol: parsedUrl.protocol,
3496
- };
3497
- return atom;
3498
- }
3499
- }
3500
-
3501
- async resolveNodeTree({ root }) {
3502
- for await (const node of root.childs) {
3503
- await this.resolveTypeWorkflow({ node });
3504
- }
3505
- }
3506
-
3507
- async resolveTypeWorkflow({ node }) {
3508
- node.context.transform = node.context.transform || cloneDeep(node.definition);
3509
- const transform = node.context.transform;
3510
-
3511
- for (let i = 0; i < transform.params?.length; i++) {
3512
- const param = transform.params[i];
3513
- if (typeof param === 'string') transform.params[i] = { key: param, hasDefault: false };
3514
- else {
3515
- const paramKey = Object.keys(param)[0];
3516
- transform.params[i] = { key: paramKey, hasDefault: true, default: param[paramKey], type: typeof param[paramKey] };
3517
- }
3518
- }
3519
-
3520
- node.context.next = node.childs[0];
3521
-
3522
- for await (const child of node.childs) {
3523
- await this.resolveType({ node: child });
3524
- }
3525
- }
3526
-
3527
- async resolveType({ node }) {
3528
-
3529
- const api = { ...this.#blockBuilderContext, node };
3530
-
3531
- if (typeof node.resolve === 'function') await node.resolve(api);
3532
-
3533
- for await (const child of node.childs) {
3534
- await this.resolveType({ node: child });
3535
- }
3536
- }
3537
-
3538
- async resolveTypeCommon({ node }) {
3539
- const transform = node.context.transform;
3540
-
3541
- if (transform.hasOwnProperty('operation'))
3542
- transform.operation = await this.transformExpression(transform.operation);
3543
-
3544
- if (transform.hasOwnProperty('page'))
3545
- transform.page = await this.transformExpression(transform.page);
3546
-
3547
- if (transform.hasOwnProperty('print'))
3548
- transform.print = await this.transformExpression(transform.print);
3549
-
3550
- if (transform.hasOwnProperty('sleep'))
3551
- transform.sleep = await this.transformExpression(transform.sleep);
3552
-
3553
- if (transform.hasOwnProperty('assert'))
3554
- transform.assert = await this.transformExpression(transform.assert);
3555
- }
3556
-
3557
- // CREATE
3558
- async createAtomLibFiles({ root }) {
3559
- await this.setProgress({ message: "Creating external lib files." });
3560
-
3561
- this.#atom.typesDir = './types';
3562
-
3563
- const libs = root.context.libs;
3564
- const atomLibRefs = libs.filter(w => w.type === 'atom');
3565
- for (let i = 0; i < atomLibRefs.length; i++) {
3566
- const atomLibRef = atomLibRefs[i];
3567
-
3568
- const atomLib = atomLibRef.atom;
3569
- const projectDir = this.#context.projectDir;
3570
- if (atomLib.protocol === 'local:') {
3571
- const srcFilePath = path.resolve(this.#context.projectSrcDir, `${atomLib.fileName || atomLib.name}.js`);
3572
- const relativePath = path.relative(`${this.#context.projectDir}/src/default/blocks`, srcFilePath);
3573
-
3574
- if (!fs.existsSync(srcFilePath)) {
3575
- fs.mkdirSync(path.dirname(srcFilePath), { recursive: true });
3576
- let template = 'export default async (args)=>{\n';
3577
- template += '}';
3578
- fs.writeFileSync(srcFilePath, template, 'utf8');
3579
- }
3580
-
3581
- atomLib.relativePath = relativePath.split(path.sep).join('/');
3582
-
3583
- this.#atom.typesDir = `./types/${path.basename(projectDir)}/src`;
3584
- }
3585
- else if (atomLib.protocol === 'npm:') {
3586
- // nothing
3587
- atomLib.relativePath = atomLib.name;
3588
- }
3589
- else if (atomLib.protocol === 'use:') ;
3590
- else {
3591
- const atomLibPath = `${projectDir}/src/libs/${atomLib.id}.js`;
3592
- const content = atomLib.doc.contents?.find(w => w.format === 'esm') || atomLib.doc;
3593
- fs.writeFileSync(path.normalize(atomLibPath), content.content, 'utf8');
3594
- }
3595
- }
3596
- }
3597
-
3598
- async createEngine({ root }) {
3599
-
3600
- await this.setProgress({ message: "Creating engine file." });
3601
-
3602
- const templateDir = this.#context.templateDir;
3603
- const template = nunjucks.compile(
3604
- fs.readFileSync(path.resolve(templateDir, `src/default/engine.js.njk`), "utf8"),
3605
- this.#njEnv
3606
- );
3607
-
3608
- for (let i = 0; i < root.childs.length; i++) {
3609
- const flow = root.childs[i];
3610
-
3611
- if (!flow.entryFile) continue;
3612
- const templateRender = template.render({ flow, ui: { package: "@fnet/react-app" } });
3613
-
3614
- const projectDir = this.#context.projectDir;
3615
- const filePath = path.resolve(projectDir, `src/default/${flow.entryFile}`);
3616
- fs.writeFileSync(filePath, templateRender, 'utf8');
3617
- }
3618
- }
3619
-
3620
- async createNodeTree({ root }) {
3621
- await this.setProgress({ message: "Creating block files." });
3622
-
3623
- for await (const node of root.childs) {
3624
- await this.createTypeWorkflow({ node });
3625
- }
3626
- }
3627
-
3628
- async createTypeWorkflow({ node }) {
3629
- const templateDir = this.#context.templateDir;
3630
- const template = nunjucks.compile(
3631
- fs.readFileSync(path.resolve(templateDir, `src/default/workflow.js.njk`), "utf8"),
3632
- this.#njEnv
3633
- );
3634
-
3635
- const flowTemplateRender = template.render(node);
3636
-
3637
- const projectDir = this.#context.projectDir;
3638
- const flowFilePath = path.resolve(projectDir, `src/default/${node.codeKey}.js`);
3639
- fs.writeFileSync(flowFilePath, flowTemplateRender, 'utf8');
3640
-
3641
- for await (const child of node.childs) {
3642
- await this.createType({ node: child });
3643
- }
3644
- }
3645
-
3646
- async createType({ node }) {
3647
-
3648
- switch (node.type) {
3649
- case "assign":
3650
- case "steps":
3651
- case "return":
3652
- case "call":
3653
- case "form":
3654
- case "raise":
3655
- case "switch":
3656
- case "jump":
3657
- case "tryexcept":
3658
- case "for":
3659
- case "operation":
3660
- case "modules":
3661
- this.createBlockFromTemplate({ node });
3662
- break;
3663
- }
3664
-
3665
- for await (const child of node.childs) {
3666
- await this.createType({ node: child });
3667
- }
3668
- }
3669
-
3670
- createBlockFromTemplate({ node }) {
3671
- const template = this.getBlockTemplate({ node });
3672
- node.context.render = template.render(node);
3673
- this.createStepFile({ node });
3674
- }
3675
-
3676
- getBlockTemplate({ node }) {
3677
- let template = this.#stepTemplateCache[node.type];
3678
- if (template) return template;
3679
-
3680
- const templateDir = this.#context.templateDir;
3681
-
3682
- template = nunjucks.compile(
3683
- fs.readFileSync(path.resolve(templateDir, `src/default/blocks/${node.type}.js.njk`), "utf8"),
3684
- this.#njEnv
3685
- );
3686
-
3687
- this.#stepTemplateCache[node.type] = template;
3688
-
3689
- return template;
3690
- }
3691
-
3692
- createStepFile({ node }) {
3693
- const projectDir = this.#context.projectDir;
3694
- const stepFileName = `${node.codeKey}.js`;
3695
- const stepFilePath = path.resolve(projectDir, `src/default/blocks/${stepFileName}`);
3696
- fs.writeFileSync(stepFilePath, node.context.render, 'utf8');
3697
- node.context.fileName = stepFileName;
3698
- node.context.filePath = stepFilePath;
3699
- }
3700
-
3701
- async transformExpression(value) {
3702
- let temp = await this.transformValue(value);
3703
- temp = JSON.stringify(temp);
3704
- // temp = this.replaceExpressionLegacy(temp);
3705
- temp = this.replaceSpecialPattern(temp);
3706
- return temp;
3707
- }
3708
-
3709
- async transformValue(value) {
3710
- if (Array.isArray(value)) {
3711
- for (let i = 0; i < value.length; i++) {
3712
- value[i] = await this.transformValue(value[i]);
3713
- }
3714
- }
3715
- else if (isObject(value)) {
3716
- const keys = Object.keys(value);
3717
- for (let i = 0; i < keys.length; i++) {
3718
- const key = keys[i];
3719
- const exp = fnetExpression({ expression: key });
3720
- if (exp) {
3721
- if (exp.processor === 'e') {
3722
- const transformedValue = value[key].replace(/(\r\n|\n|\r)/g, "");
3723
- value[exp.statement] = `$::${transformedValue}::`;
3724
- delete value[key];
3725
- }
3726
- else value[key] = await this.transformValue(value[key]);
3727
- }
3728
- else {
3729
- value[key] = await this.transformValue(value[key]);
3730
- }
3731
- }
3732
- }
3733
- else if (typeof value === 'string') {
3734
- const exp = fnetExpression({ expression: value });
3735
- if (exp) {
3736
- const { processor, statement } = exp;
3737
- switch (processor) {
3738
- // @fnet/yaml reserved processors
3739
- // s:: reserved for yaml setter
3740
- // g:: reserved for yaml getter
3741
- // r:: reserved for yaml replacer
3742
- // b:: reserved for yaml builder/blocks
3743
- case 'v':
3744
- value = `$::v.${statement}::`;
3745
- break;
3746
- case 'e':
3747
- value = `$::${statement}::`;
3748
- break;
3749
- case 'm':
3750
- value = `$::c.module['${statement}']::`;
3751
- break;
3752
- case 'fm':
3753
- value = `$::flow.getModule('${statement}')::`;
3754
- break;
3755
- case 'f':
3756
- value = `$::c.form.${statement}::`;
3757
- break;
3758
- case 'for':
3759
- value = `$::caller.for.${statement}::`;
3760
- break;
3761
- }
3762
- }
3763
- }
3764
-
3765
- return value;
3766
- }
3767
-
3768
- replaceSpecialPattern(text) {
3769
- const pattern1 = /"\$::(.*?)::"/g;
3770
- let temp = text.replace(pattern1, "$1");
3771
- // remove new lines
3772
- // temp = temp.replace(/(\r\n|\n|\r)/g, "");
3773
- return temp;
3774
- }
3775
-
3776
- replaceExpressionLegacy(value) {
3777
- // https://regex101.com/r/ZC9Wxb/1
3778
- const regex = /(?<outer>"\${(?<inner>[^{]*)}")/g;
3779
- return value.replaceAll(regex, "$2");
3780
- }
3781
-
3782
- async createProjectYaml() {
3783
-
3784
- const fileBase = `fnet.yaml`;
3785
- const message = `Creating ${fileBase}`;
3786
-
3787
- await this.setProgress({ message: message });
3788
-
3789
- const { content: main, ...content } = this.#atom.doc;
3790
-
3791
- const templateContext = { content: yaml.stringify(content) };
3792
-
3793
- const templateDir = this.#context.templateDir;
3794
- const template = nunjucks.compile(
3795
- fs.readFileSync(path.resolve(templateDir, `${fileBase}.njk`), "utf8"),
3796
- this.#njEnv
3797
- );
3798
-
3799
- const templateRender = template.render(templateContext);
3800
-
3801
- const projectDir = this.#context.projectDir;
3802
- const filePath = path.resolve(projectDir, `${fileBase}`);
3803
- fs.writeFileSync(filePath, templateRender, 'utf8');
3804
- }
3805
-
3806
- async createProjectMainYaml() {
3807
-
3808
- const fileBase = `flow.main.yaml`;
3809
- const message = `Creating ${fileBase}`;
3810
-
3811
- await this.setProgress({ message: message });
3812
-
3813
- // const { content: main, ...content } = this.#atom.doc;
3814
-
3815
- const templateContext = { content: yaml.stringify(this.#workflow) };
3816
-
3817
- const templateDir = this.#context.templateDir;
3818
- const template = nunjucks.compile(
3819
- fs.readFileSync(path.resolve(templateDir, `${fileBase}.njk`), "utf8"),
3820
- this.#njEnv
3821
- );
3822
-
3823
- const templateRender = template.render(templateContext);
3824
-
3825
- const projectDir = this.#context.projectDir;
3826
- const filePath = path.resolve(projectDir, `${fileBase}`);
3827
- fs.writeFileSync(filePath, templateRender, 'utf8');
3828
- }
3829
-
3830
- async runPrettifier() {
3831
- const projectDir = this.#context.projectDir;
3832
-
3833
- const result = await fnetShellJs(`prettier --write .`, { cwd: path.resolve(projectDir, "src") });
3834
- if (result.code !== 0) throw new Error(result.stderr);
3835
- }
3836
-
3837
- async deploy() {
3838
-
3839
- await this.setProgress({ message: "Deploying." });
3840
-
3841
- if (this.#context.project?.devops) {
3842
- const devopsProjects = [this.#context.project?.devops];
3843
- for (let i = 0; i < devopsProjects.length; i++) {
3844
- let deploymentProject = devopsProjects[i];
3845
- await this.deployProject({ deploymentProject });
3846
-
3847
- if (deploymentProject.isDirty === true) {
3848
- await deploymentProject.save();
3849
- }
3850
- }
3851
-
3852
- } else if (this.#atom.id) {
3853
- const deploymentProjects = await Atom.list({ type: "workflow.deploy", parent_id: this.#atom.id });
3854
- for (let i = 0; i < deploymentProjects.length; i++) {
3855
- let deploymentProject = deploymentProjects[i];
3856
- await this.deployProject({ deploymentProject });
3857
-
3858
- if (deploymentProject.isDirty === true) {
3859
- deploymentProject = await Atom.update(deploymentProject, { id: deploymentProject.id });
3860
- }
3861
- }
3862
- }
3863
- }
3864
-
3865
- async deployProject(context) {
3866
- const { deploymentProject } = context;
3867
- const { yamlDocument } = deploymentProject;
3868
-
3869
- if (deploymentProject.doc.targets && Array.isArray(deploymentProject.doc.targets))
3870
- throw new Error("Deployment project targets are deprecated. Please update targets in the yaml file.");
3871
-
3872
- const targetKeys = Object.keys(deploymentProject.doc || {});
3873
- const yamlTargets = yamlDocument || {};
3874
- for (let i = 0; i < targetKeys.length; i++) {
3875
- const deploymentProjectTarget = deploymentProject.doc[targetKeys[i]];
3876
- deploymentProjectTarget.name = targetKeys[i];
3877
- const yamlTarget = yamlTargets.get(targetKeys[i]);
3878
- await deployTo({ ...this.#apiContext, deploymentProject, deploymentProjectTarget, yamlTarget });
3879
- }
3880
- }
3881
-
3882
- async registerToPackageManager(context) {
3883
- const { target, packageJSON } = context;
3884
-
3885
- if (!this.#context.id) return;
3886
-
3887
- // update
3888
- let packageAtom = await Atom.first({ name: target.params.name, parent_id: this.#atomConfig.env.ATOM_PACKAGES_ID });
3889
-
3890
- if (!packageAtom) {
3891
- // create new
3892
- packageAtom = await Atom.create({
3893
- parent_id: this.#atomConfig.env.ATOM_PACKAGES_ID,
3894
- doc: {
3895
- name: target.params.name,
3896
- type: "pm",
3897
- versions: [{ v: packageJSON.version }]
3898
- }
3899
- });
3900
- }
3901
- else {
3902
- // update existing
3903
- packageAtom.doc.versions.splice(0, 0, { v: packageJSON.version });
3904
-
3905
- await Atom.update(packageAtom, { id: packageAtom.id });
3906
- }
3907
- }
3908
-
3909
- async setProgress(args) {
3910
-
3911
- const message = typeof args === 'string' ? args : args?.message;
3912
-
3913
- console.log(chalk.blue(message));
3914
-
3915
- await this._cache_set(this.#buildKey, { status: "IN_PROGRESS", message });
3916
- }
3917
-
3918
- async build() {
3919
- if (this.#bpmnMode && !this.#fileMode) return await this.createNetwork();
3920
-
3921
- try {
3922
- const network = this.#bpmnMode ? await generateBpmnModel({ root: this.#root }) : undefined;
3923
-
3924
- if (this.#fileMode) {
3925
-
3926
- await this.initWorkflowDir();
3927
- await this.initNunjucks();
3928
-
3929
- if (this.#bpmnMode) {
3930
- let bpmnDir = this.#context.project?.projectDir || this.#context.projectDir;
3931
- bpmnDir = path.resolve(bpmnDir, 'fnet');
3932
- if (fs.existsSync(bpmnDir)) {
3933
- fs.writeFileSync(path.resolve(bpmnDir, 'flow.bpmn'), network.diagramXML, 'utf8');
3934
- }
3935
- }
3936
-
3937
- await this.createAtomLibFiles({ root: this.#root });
3938
- await this.createEngine({ root: this.#root });
3939
- await this.createNodeTree({ root: this.#root });
3940
- await this.createProjectYaml();
3941
- // await this.createProjectMainYaml();
3942
-
3943
- await createProjectReadme(this.#apiContext);
3944
- await createTsConfig(this.#apiContext);
3945
- await createGitIgnore(this.#apiContext);
3946
- await createToYargs(this.#apiContext);
3947
- await createCli(this.#apiContext);
3948
- await createApp(this.#apiContext);
3949
- await createRollup(this.#apiContext);
3950
- await createPackageJson(this.#apiContext);
3951
-
3952
- await formatFiles(this.#apiContext);
3953
-
3954
- await createDts(this.#apiContext);
3955
-
3956
- if (this.#buildMode) {
3957
-
3958
- await installNpmPackages(this.#apiContext);
3959
- await runNpmBuild(this.#apiContext);
3960
-
3961
- if (this.#deployMode)
3962
- await this.deploy();
3963
- }
3964
- }
3965
-
3966
- await this._cache_set(this.#buildKey, { status: "COMPLETED", data: { network } });
3967
- }
3968
- catch (error) {
3969
- await this._cache_set(this.#buildKey, { status: "FAILED", message: error.message || error });
3970
- throw error;
3971
- }
3972
- }
3973
-
3974
- async createNetwork() {
3975
- try {
3976
- const network = await generateBpmnModel({ root: this.#root });
3977
-
3978
- await this._cache_set(this.#buildKey, { status: "COMPLETED", data: { ...network } });
3979
- }
3980
- catch (error) {
3981
- await this._cache_set(this.#buildKey, { status: "FAILED", message: error.message || error });
3982
- throw error;
3983
- }
3984
- }
3985
- }
3986
-
3987
- const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
3988
-
3989
- function findNodeModules({ baseDir }) {
3990
-
3991
- baseDir = baseDir || __dirname$1;
3992
-
3993
- let currentDir = baseDir;
3994
-
3995
- while (currentDir !== path.parse(currentDir).root) {
3996
- const potentialPath = path.join(currentDir, 'node_modules');
3997
-
3998
- if (fs.existsSync(potentialPath)) {
3999
- return potentialPath;
4000
- }
4001
-
4002
- currentDir = path.dirname(currentDir);
4003
- }
4004
-
4005
- return null;
4006
- }
4007
-
4008
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
4009
-
4010
- const cwd = process.cwd();
4011
-
4012
- // fnet env
4013
- fnetConfig({
4014
- name: ["redis"],
4015
- dir: cwd,
4016
- optional: true
4017
- });
4018
- const nodeModulesDir = findNodeModules({ baseDir: __dirname });
4019
- const pathSeparator = process.platform === 'win32' ? ';' : ':';
4020
-
4021
- if (nodeModulesDir)
4022
- process.env.PATH = `${path.join(nodeModulesDir, '/.bin')}${pathSeparator}${process.env.PATH}`;
4023
-
4024
- // --- Commander Setup ---
4025
- const program = new Command();
4026
-
4027
- program
4028
- .name('fnet') // Set the name for help messages (assuming executable is fnet)
4029
- .version(pkg.version) // Use version from package.json
4030
- .description('CLI tool for FlowNet workflow projects');
4031
-
4032
- // --- Create Command ---
4033
- program
4034
- .command('create')
4035
- .description('Initialize flow workflow project') // Description updated
4036
- // Make name required as it's used to create the directory
4037
- .requiredOption('-n, --name <string>', 'Project name')
4038
- .addOption(new Option('-r, --runtime <type>', 'Runtime environment (currently only node)').choices(['node']).default('node'))
4039
- .option('--vscode', 'Open project in VSCode after creation', true)
4040
- .option('--no-vscode', 'Do not open project in VSCode')
4041
- .action(async (options) => { // Handler receives options object
4042
- try {
4043
- // Use the correct template path
4044
- const templateDir = path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/project');
4045
- const outDir = path.resolve(cwd, options.name); // Use options.name
4046
- if (!fs$1.existsSync(outDir)) fs$1.mkdirSync(outDir);
4047
-
4048
- await fnetRender({
4049
- dir: templateDir,
4050
- outDir,
4051
- // Pass commander options object as context
4052
- context: options,
4053
- copyUnmatchedAlso: true
4054
- });
4055
-
4056
- // Use fnet build (assuming fnet is the command)
4057
- let shellResult = await fnetShellJs(`fnet build`, { cwd: outDir });
4058
- if (shellResult.code !== 0) throw new Error('Failed to build project.');
4059
-
4060
- if (which('git')) {
4061
- shellResult = await fnetShellJs(`git init --initial-branch=main`, { cwd: outDir });
4062
- if (shellResult.code !== 0) throw new Error('Failed to initialize git.');
4063
- }
4064
-
4065
- if (options.vscode && which('code')) { // Check options.vscode
4066
- shellResult = await fnetShellJs(`cd ${outDir} && code .`);
4067
- if (shellResult.code !== 0) throw new Error('Failed to open vscode.');
4068
- }
4069
-
4070
- console.log('Creating project succeeded!');
4071
- process.exit(0);
4072
- } catch (error) {
4073
- console.error('Initialization failed!', error.message);
4074
- process.exit(1);
4075
- }
4076
- });
4077
-
4078
- // --- Project Command ---
4079
- program
4080
- .command('project')
4081
- .description('Flow workflow project operations') // Description updated
4082
- .option('-u, --update', 'Update project files from template', false)
4083
- .action(async (options) => {
4084
- try {
4085
- // Use the correct template path
4086
- const templateDir = path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/project');
4087
- const outDir = process.cwd();
4088
-
4089
- // Pass commander options to createContext
4090
- const context = await createContext(options);
4091
-
4092
- if (options.update) { // Check options.update
4093
- await fnetRender({
4094
- dir: templateDir,
4095
- outDir,
4096
- // Use context derived from project file, keep runtime hardcoded as node
4097
- context: {
4098
- name: context.project.projectFileParsed.name,
4099
- runtime: 'node' // Kept hardcoded as per original logic
4100
- },
4101
- copyUnmatchedAlso: true
4102
- });
4103
-
4104
- let shellResult = await fnetShellJs(`fnet build`, { cwd: outDir });
4105
- if (shellResult.code !== 0) throw new Error('Failed to build project.');
4106
-
4107
- console.log('Updating project succeeded!');
4108
- } else {
4109
- console.log("Use 'fnet project --update' to update project files.");
4110
- }
4111
- process.exit(0);
4112
- } catch (error) {
4113
- console.error('Project command failed.', error.message); // Message updated
4114
- process.exit(1);
4115
- }
4116
- });
4117
-
4118
- // --- Build Command ---
4119
- program
4120
- .command('build')
4121
- .description('Build flownet workflow project') // Description updated
4122
- .option('--id <string>', 'Build identifier')
4123
- .option('--buildId <string>', 'Specific build ID') // Removed alias for simplicity
4124
- .addOption(new Option('--mode <mode>', 'Build mode').choices(['all', 'file', 'build', 'deploy', 'bpmn']).default('build'))
4125
- .option('--ftag <tags...>', 'Filter tags (specify multiple times or space-separated)')
4126
- .action(async (options) => {
4127
- try {
4128
- // Pass commander options to createContext
4129
- const context = await createContext(options);
4130
- const builder = new Builder(context); // Uses ./wf-builder
4131
- await builder.init();
4132
- await builder.build();
4133
-
4134
- console.log('Building workflow succeeded!'); // Message updated
4135
-
4136
- process.exit(0);
4137
- } catch (error) {
4138
- console.error('Building workflow failed!', error.message); // Message updated
4139
- process.exit(1);
4140
- }
4141
- });
4142
-
4143
- // --- Deploy Command ---
4144
- program
4145
- .command('deploy')
4146
- .description('Build and deploy flownet workflow project') // Description updated
4147
- .option('--id <string>', 'Build identifier')
4148
- .option('--buildId <string>', 'Specific build ID')
4149
- .option('--ftag <tags...>', 'Filter tags')
4150
- .action(async (options) => {
4151
- try {
4152
- // Pass commander options to createContext, overriding mode
4153
- const context = await createContext({ ...options, mode: "all" });
4154
- const builder = new Builder(context); // Uses ./wf-builder
4155
- await builder.init();
4156
- await builder.build();
4157
- console.log('Building and deploying workflow succeeded!'); // Message updated
4158
- process.exit(0);
4159
- } catch (error) {
4160
- console.error('Building/deploying workflow failed!', error.message); // Message updated
4161
- process.exit(1);
4162
- }
4163
- });
4164
-
4165
- // --- File Command ---
4166
- program
4167
- .command('file')
4168
- .description('Just create files (part of workflow build)') // Description updated
4169
- .option('--id <string>', 'Build identifier')
4170
- .option('--buildId <string>', 'Specific build ID')
4171
- .option('--ftag <tags...>', 'Filter tags')
4172
- .action(async (options) => {
4173
- try {
4174
- // Pass commander options to createContext, overriding mode
4175
- const context = await createContext({ ...options, mode: "file" });
4176
- const builder = new Builder(context); // Uses ./wf-builder
4177
- await builder.init();
4178
- await builder.build();
4179
- console.log('Creating workflow files succeeded!'); // Message updated
4180
- process.exit(0);
4181
- } catch (error) {
4182
- console.error('Creating workflow files failed!', error.message); // Message updated
4183
- process.exit(1);
4184
- }
4185
- });
4186
-
4187
- // --- Input Command ---
4188
- // (Identical structure to the previous script)
4189
- program
4190
- .command('input')
4191
- .description('Create or modify an input config file')
4192
- .argument('[name]', 'Optional input configuration name (e.g., dev, prod)')
4193
- .action(async (name, options) => { // Handler receives positional args first, then options
4194
- try {
4195
- // Pass options and name to createContext
4196
- const context = await createContext({ ...options, name }); // Include name if needed by createContext
4197
- const { project } = context;
4198
- const { projectDir, projectFileParsed } = project;
4199
- const schema = projectFileParsed.input;
4200
- if (!schema) throw new Error('Config schema `input` not found in project file (fnet.yaml).'); // Updated filename in error
4201
-
4202
- let configName = name; // Use the positional argument
4203
- if (!configName) {
4204
- const answers = await prompt({ type: 'input', name: 'inputName', message: 'Input name:', initial: 'dev' });
4205
- configName = answers.inputName;
4206
- if (!configName) { // Exit if user provides no name
4207
- console.error("Input name cannot be empty.");
4208
- process.exit(1);
4209
- }
4210
- }
4211
-
4212
- const dotFnetDir = path.resolve(projectDir, '.fnet');
4213
- if (!fs$1.existsSync(dotFnetDir)) fs$1.mkdirSync(dotFnetDir);
4214
-
4215
- const configFilePath = path.resolve(dotFnetDir, `${configName}.fnet`);
4216
- const exists = fs$1.existsSync(configFilePath);
4217
-
4218
- const result = await fnetObjectFromSchema({ schema, format: "yaml", ref: exists ? configFilePath : undefined });
4219
- fs$1.writeFileSync(configFilePath, result);
4220
- console.log(`Input config '${configName}.fnet' ${exists ? 'updated' : 'created'}.`);
4221
- } catch (error) {
4222
- console.error(error.message);
4223
- process.exit(1);
4224
- }
4225
- });
4226
-
4227
-
4228
- // --- Helper Functions (Copied from previous conversion, no Conda needed) ---
4229
-
4230
- // Helper function for simple pass-through commands
4231
- function bindSimpleContextCommand(prog, { name, bin, preArgs = [] }) {
4232
- const cmdName = name || bin;
4233
- prog
4234
- .command(cmdName, { isDefault: false, hidden: false })
4235
- .description(`Run ${bin} ${preArgs.join(' ')} in project context. Pass arguments directly after command name.`)
4236
- .argument('[command_args...]', `Arguments for ${bin}`)
4237
- .allowUnknownOption()
4238
- .action(async (command_args, options) => {
4239
- try {
4240
- const context = await createContext(options);
4241
- // Use projectDir from context if available, otherwise CWD
4242
- const effectiveCwd = context?.projectDir && fs$1.existsSync(context.projectDir)
4243
- ? context.projectDir
4244
- : (context?.project?.projectDir && fs$1.existsSync(context.project.projectDir)
4245
- ? context.project.projectDir
4246
- : cwd);
4247
-
4248
- const rawArgs = command_args;
4249
-
4250
- const subprocess = spawn(bin, [...preArgs, ...rawArgs], {
4251
- cwd: effectiveCwd,
4252
- stdio: 'inherit',
4253
- shell: true // Keep shell true for convenience like handling 'npm run' etc.
4254
- });
4255
-
4256
- subprocess.on('close', (code) => {
4257
- // Avoid exiting if the process is already closing (e.g., via SIGINT)
4258
- if (process.exitCode === undefined) {
4259
- process.exit(code);
4260
- }
4261
- });
4262
- subprocess.on('error', (err) => {
4263
- console.error(`Failed to start ${bin}:`, err);
4264
- if (process.exitCode === undefined) {
4265
- process.exit(1);
4266
- }
4267
- });
4268
-
4269
- } catch (error) {
4270
- console.error(`Error setting up context for ${cmdName}:`, error.message);
4271
- if (process.exitCode === undefined) {
4272
- process.exit(1);
4273
- }
4274
- }
4275
- });
4276
- }
4277
-
4278
-
4279
- // Helper function for "with" command
4280
- function bindWithContextCommand(prog, { name, preArgs = [] }) {
4281
- prog
4282
- .command(name)
4283
- .description('Run a command with environment variables from a .fnet config file.')
4284
- .argument('<config>', 'Name of the .fnet config file (without extension)')
4285
- .argument('<command>', 'The command to execute')
4286
- .argument('[command_args...]', 'Arguments for the command')
4287
- .option('--ftag <tags...>', 'Filter tags for loading config')
4288
- .allowUnknownOption()
4289
- .action(async (configName, commandName, command_args, options) => {
4290
- try {
4291
- const context = await createContext(options);
4292
- // Determine projectDir robustly for config loading
4293
- const configProjectDir = context?.project?.projectDir && fs$1.existsSync(context.project.projectDir)
4294
- ? context.project.projectDir
4295
- : cwd;
4296
-
4297
- const config = await fnetConfig({
4298
- name: configName,
4299
- dir: configProjectDir,
4300
- transferEnv: false,
4301
- optional: true,
4302
- tags: context?.tags || options.ftag || [] // Get tags from context or options
4303
- });
4304
- const env = config?.data?.env || {};
4305
-
4306
- // Determine effective CWD for the spawned process
4307
- const effectiveCwd = context?.projectDir && fs$1.existsSync(context.projectDir)
4308
- ? context.projectDir
4309
- : configProjectDir; // Fallback to where config was loaded
4310
-
4311
- const rawArgs = command_args;
4312
-
4313
- const subprocess = spawn(commandName, [...preArgs, ...rawArgs], {
4314
- cwd: effectiveCwd,
4315
- stdio: 'inherit',
4316
- shell: true,
4317
- env: {
4318
- ...process.env,
4319
- ...env
4320
- }
4321
- });
4322
-
4323
- subprocess.on('close', (code) => {
4324
- if (process.exitCode === undefined) process.exit(code);
4325
- });
4326
- subprocess.on('error', (err) => {
4327
- if (err.code === 'ENOENT') {
4328
- console.error(`Error: Command not found: '${commandName}'. Is it installed or in your PATH?`);
4329
- } else {
4330
- console.error(`Failed to start command '${commandName}':`, err);
4331
- }
4332
- if (process.exitCode === undefined) process.exit(1);
4333
- });
4334
- } catch (error) {
4335
- console.error(`Error setting up context or running command for '${name}': ${error.message}`);
4336
- if (process.exitCode === undefined) process.exit(1);
4337
- }
4338
- });
4339
- }
4340
-
4341
- // Helper function for "run" command
4342
- function bindRunContextCommand(prog, { name, preArgs = [] }) {
4343
- prog
4344
- .command(name)
4345
- .description('Run a command group defined in fnet.yaml.') // Updated filename
4346
- .argument('<group>', 'Name of the command group in fnet.yaml commands section')
4347
- .option('--ftag <tags...>', 'Filter tags for loading project config')
4348
- .action(async (groupName, options) => {
4349
- try {
4350
- const context = await createContext(options);
4351
- // Ensure project was loaded (might not be if running from outside a project dir without --id)
4352
- if (!context || !context.project || !context.project.projectFileParsed) {
4353
- throw new Error("Could not load project context. Are you in a fnet project directory?");
4354
- }
4355
- const { projectFileParsed } = context.project;
4356
- const commands = projectFileParsed.commands;
4357
- if (!commands) throw new Error('`commands` section not found in project file (fnet.yaml).');
4358
-
4359
- const group = commands[groupName];
4360
- if (!group) throw new Error(`Command group '${groupName}' not found in project file.`);
4361
-
4362
- await fnetShellFlow({ commands: group });
4363
- if (process.exitCode === undefined) process.exit(0);
4364
-
4365
- } catch (error) {
4366
- console.error(`Error running command group '${groupName}':`, error.message);
4367
- if (process.exitCode === undefined) process.exit(1);
4368
- }
4369
- });
4370
- }
4371
-
4372
-
4373
- // --- Bind dynamic/pass-through commands ---
4374
- // Note: Adjusted preArgs for simplicity with commander's argument handling
4375
- bindSimpleContextCommand(program, { bin: 'npm' });
4376
- bindSimpleContextCommand(program, { bin: 'node' });
4377
- bindSimpleContextCommand(program, { bin: 'bun' });
4378
- bindSimpleContextCommand(program, { name: "serve", bin: 'npm', preArgs: ['run', 'serve'] }); // Pass '--' manually if needed
4379
- bindSimpleContextCommand(program, { name: "watch", bin: 'npm', preArgs: ['run', 'watch'] });
4380
- bindSimpleContextCommand(program, { name: "app", bin: 'npm', preArgs: ['run', 'app'] });
4381
- bindSimpleContextCommand(program, { name: "cli", bin: 'npm', preArgs: ['run', 'cli'] });
4382
- bindSimpleContextCommand(program, { bin: 'npx' });
4383
- bindSimpleContextCommand(program, { bin: 'cdk' });
4384
- bindSimpleContextCommand(program, { bin: 'aws' });
4385
- bindWithContextCommand(program, { name: 'with' });
4386
- bindRunContextCommand(program, { name: 'run' });
4387
-
4388
-
4389
- // --- createContext Function (modified for workflow context) ---
4390
- async function createContext(options) { // Accepts commander's options object
4391
- const tags = options.ftag || []; // Ensure tags is always an array
4392
-
4393
- if (options.id) {
4394
- // Context for building based on an ID (likely remote/CI)
4395
- return {
4396
- id: options.id,
4397
- buildId: options.buildId,
4398
- mode: options.mode,
4399
- protocol: options.protocol || "ac:", // options.protocol might not be defined
4400
- projectDir: path.resolve(cwd, `./.output/${options.id}`),
4401
- templateDir: path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/default'),
4402
- templateCommonDir: path.resolve(nodeModulesDir, '@fnet/cli-project-common/dist/template/default'),
4403
- coreDir: path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/core'), // Added coreDir
4404
- tags: tags,
4405
- };
4406
- } else {
4407
- // Context for running commands within a local project directory
4408
- const project = await loadLocalProject({ tags: tags }); // Pass tags down
4409
-
4410
- return {
4411
- buildId: options.buildId,
4412
- mode: options.mode,
4413
- protocol: options.protocol || "local:",
4414
- templateDir: path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/default'),
4415
- templateCommonDir: path.resolve(nodeModulesDir, '@fnet/cli-project-common/dist/template/default'),
4416
- coreDir: path.resolve(nodeModulesDir, '@fnet/cli-project-flow/dist/template/core'), // Added coreDir
4417
- projectDir: path.resolve(project.projectDir, `./.workspace`), // Output/build dir within project
4418
- projectSrcDir: path.resolve(project.projectDir, `./src`), // Source dir within project
4419
- project, // Include the loaded project details (paths, parsed content, etc.)
4420
- tags: tags,
4421
- };
4422
- }
4423
- }
4424
-
4425
- // --- loadLocalProject Function (modified for workflow projects) ---
4426
- async function loadLocalProject({ tags = [] }) { // Default tags to empty array
4427
- const projectFilePath = path.resolve(cwd, 'fnet.yaml'); // Workflow project file
4428
- if (!fs$1.existsSync(projectFilePath)) throw new Error('fnet.yaml file not found in current directory.');
4429
-
4430
- const effectiveTags = Array.isArray(tags) ? tags : (tags ? [tags] : []);
4431
-
4432
- const { raw: projectFileContent, parsed: projectFileParsed } = await fnetYaml({ file: projectFilePath, tags: effectiveTags });
4433
- const projectDir = path.dirname(projectFilePath);
4434
-
4435
- let flowsContent = {}; // Initialize as object
4436
-
4437
- // Check if flows are embedded or in a separate file
4438
- if (typeof projectFileParsed.flows === 'object' && projectFileParsed.flows !== null) {
4439
- // Flows are directly embedded in fnet.yaml
4440
- flowsContent = projectFileParsed.flows;
4441
- } else {
4442
- // Flows are likely in a separate file (or missing)
4443
- let defaultFlowsFile = 'flow.main.yaml'; // Original default
4444
-
4445
- // Check for newer standard location first
4446
- const standardFlowsPath = path.join(projectDir, 'fnet', 'flows.yaml');
4447
- if (fs$1.existsSync(standardFlowsPath)) {
4448
- defaultFlowsFile = path.join('fnet', 'flows.yaml');
4449
- }
4450
-
4451
- // Determine the main flow file name from project file or default
4452
- const mainFileName = projectFileParsed.main || defaultFlowsFile;
4453
- let projectMainFilePath = path.resolve(projectDir, mainFileName);
4454
-
4455
- if (!fs$1.existsSync(projectMainFilePath)) {
4456
- // Only provide minimal structure if file specified in fnet.yaml doesn't exist
4457
- if (projectFileParsed.main) {
4458
- console.warn(`Warning: Main flow file specified in fnet.yaml (${mainFileName}) not found.`);
4459
- }
4460
- // Fallback to empty content if default doesn't exist either
4461
- flowsContent = { main: { steps: [] } }; // Default empty structure
4462
- }
4463
- else {
4464
- // Load from the determined flow file
4465
- try {
4466
- const { parsed: projectMainFileParsed } = await fnetYaml({ file: projectMainFilePath, tags: effectiveTags });
4467
- flowsContent = projectMainFileParsed;
4468
- } catch (yamlError) {
4469
- console.error(`Error parsing flow file: ${projectMainFilePath}`);
4470
- throw yamlError; // Re-throw error after logging context
4471
- }
4472
-
4473
- }
4474
- }
4475
-
4476
-
4477
- // Construct the main result object
4478
- const result = {
4479
- // workflowAtom combines project config and flow content
4480
- workflowAtom: {
4481
- doc: {
4482
- ...projectFileParsed, // Include all keys from fnet.yaml
4483
- content: flowsContent // Add the resolved flow content under 'content'
4484
- }
4485
- },
4486
- projectDir,
4487
- projectFilePath,
4488
- projectFileContent, // Raw content of fnet.yaml
4489
- projectFileParsed, // Parsed content of fnet.yaml (without flows if external)
4490
- };
4491
-
4492
- // Load devops file (targets.yaml, with migration from flow.devops.yaml)
4493
- let devopsFilePath = path.resolve(projectDir, 'fnet/targets.yaml');
4494
- const legacyDevopsPath = path.resolve(projectDir, 'flow.devops.yaml'); // Legacy path
4495
-
4496
- if (!fs$1.existsSync(devopsFilePath) && fs$1.existsSync(legacyDevopsPath)) {
4497
- // Migrate legacy devops file
4498
- console.log(`Migrating legacy devops file: ${legacyDevopsPath}`);
4499
- try {
4500
- const fnetDir = path.resolve(projectDir, 'fnet');
4501
- if (!fs$1.existsSync(fnetDir)) fs$1.mkdirSync(fnetDir);
4502
- fs$1.copyFileSync(legacyDevopsPath, devopsFilePath);
4503
- fs$1.unlinkSync(legacyDevopsPath); // Delete legacy file after copy
4504
- console.log(`Successfully migrated to ${devopsFilePath}`);
4505
- } catch (migrationError) {
4506
- console.error(`Error migrating devops file: ${migrationError.message}`);
4507
- // Continue without devops info if migration fails
4508
- }
4509
- }
4510
-
4511
- // Load the devops file if it exists now
4512
- if (fs$1.existsSync(devopsFilePath)) {
4513
- try {
4514
- const { raw: devopsFileContent, parsed: devopsFileParsed } = await fnetYaml({ file: devopsFilePath, tags: effectiveTags }); // Pass tags
4515
- const yamlDocument = yaml.parseDocument(devopsFileContent); // For preserving comments/structure on save
4516
- result.devops = {
4517
- filePath: devopsFilePath,
4518
- fileContent: devopsFileContent,
4519
- yamlDocument,
4520
- doc: { ...devopsFileParsed },
4521
- type: "workflow.deploy", // Specific type for workflows
4522
- save: async () => {
4523
- // Save using the parsed document to preserve structure
4524
- fs$1.writeFileSync(result.devops.filePath, yamlDocument.toString());
4525
- }
4526
- };
4527
- } catch (devopsError) {
4528
- console.error(`Error loading or parsing devops file: ${devopsFilePath}`);
4529
- // Potentially throw error or just warn and continue without devops
4530
- // throw devopsError; // Uncomment to make devops file parsing critical
4531
- }
4532
-
4533
- }
4534
-
4535
- // Load readme file (same logic as before)
4536
- const readmeFilePath = path.resolve(projectDir, 'readme.md');
4537
- if (fs$1.existsSync(readmeFilePath)) {
4538
- const readmeFileContent = fs$1.readFileSync(readmeFilePath, 'utf8');
4539
- result.readme = {
4540
- filePath: readmeFilePath,
4541
- fileContent: readmeFileContent,
4542
- doc: {
4543
- content: readmeFileContent,
4544
- "content-type": "markdown",
4545
- },
4546
- type: "wiki"
4547
- };
4548
- }
4549
-
4550
- return result;
4551
- }
4552
-
4553
-
4554
- // --- Parse Arguments ---
4555
- program.parse(process.argv);
4556
-
4557
- // Add a fallback for when no command is provided
4558
- if (!process.argv.slice(2).length) {
4559
- program.outputHelp();
4560
- }
4561
-
4562
- export { which as w };
2
+ import{spawn as e}from"child_process";import t from"@fnet/prompt";import o,{existsSync as n}from"node:fs";import i,{delimiter as s,join as r}from"node:path";import a from"@fnet/config";import{fileURLToPath as c}from"node:url";import{Command as p,Option as l}from"commander";import d from"fs";import f from"yaml";import m from"@fnet/shelljs";import u from"@fnet/yaml";import h from"@fnet/object-from-schema";import y from"@fnet/shell-flow";import g from"@flownet/lib-render-templates-dir";import w from"nunjucks";import x from"lodash.clonedeep";import b from"isobject";import k from"redis";import v from"@flownet/lib-is-redis-online";import{randomUUID as j}from"node:crypto";import{Api as D,Atom as _}from"@flownet/lib-atom-api-js";import E from"lodash.merge";import S from"@flownet/lib-parse-imports-js";import P from"@fnet/npm-list-versions";import $ from"@fnet/npm-pick-versions";import C from"object-hash";import T from"ajv/dist/2020.js";import N from"ajv/dist/standalone/index.js";import F from"ajv-formats";import A from"path";import O from"@flownet/lib-parse-node-url";import I from"bpmn-moddle";import B from"dagre";import K from"@fnet/expression";import R from"chalk";import M from"@fnet/list-files";import J from"@fnet/key-value-transformer";import L from"lodash.pick";import z from"lodash.omit";var q=e=>{const t=process.env.PATH||"",o="win32"===process.platform?(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM").split(";"):[""],i=t.split(s);for(const t of i)for(const i of o){const o=r(t,"win32"===process.platform?e+i:e);if(n(o))return o}return null},W="0.101.0";class U{init({config:e,accessToken:t}){return new Promise(((o,n)=>{if(D.set_api_url(e.data.url),t)return D.set_req_token(t),void o(t);fetch(`${e.data.issuer}/protocol/openid-connect/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e.data.grant.params)}).then((async e=>{if(!e.ok)throw new Error(await e.text());return e.json()})).then((e=>{D.set_req_token(e.access_token),o(e.access_token)})).catch((e=>{D.set_req_token(),n(e)}))}))}}function X({feature:e,features:t,packageDevDependencies:o}){const{name:n,packages:i,options:s,extraCheck:r,explicit:a}=e,c=`${n}_enabled`,p=t.rollup_output||{},l=Object.keys(p);let d=s||{};const f=t[n]?.options;f&&(d=E(d,f));const m=!t[n]||!1===t[n]?.enabled;l.forEach((e=>{const o=t.rollup_output[e];if(o){if(Reflect.has(o,n)){if(m||!o[n]||!1===o[n]?.enabled)return void delete o[n];!0===o[n]&&(o[n]={enabled:!0,options:d})}else{if(m||a||!1===t[c])return;o[n]={enabled:!0}}o[n]=o[n]||{},o[n].options={...d,...o[n].options}}}));let u=l.some((e=>!0===t.rollup_output[e][n]?.enabled));r&&(u=r()&&u),t[c]=u,u&&i.forEach((e=>o.push({package:e[0],version:e[1]})))}function V({dir:e,name:t="index"}){let n=i.resolve(e,`./${t}.tsx`);if(o.existsSync(n)||(n=i.resolve(e,`./${t}.ts`)),o.existsSync(n)||(n=i.resolve(e,`./${t}.jsx`)),o.existsSync(n)||(n=i.resolve(e,`./${t}.js`)),!o.existsSync(n))return{};const s=n,r=i.extname(n);return{file:s,ext:r,ts:".ts"===r||".tsx"===r,name:t}}async function H(e){const{atom:t,context:o,setProgress:n}=e;n("Initializing features..."),t.doc.features=t.doc.features||{};const s=t.doc.features;s.project=s.project||{},s.project.format=s.project.format||s.project_format||"esm",s.project_format=s.project.format,s.dts_enabled=!0===s.dts||void 0!==s.dts&&!1!==s.dts;const r=i.resolve(o.project.projectDir),a=V({dir:i.resolve(r,"./app")});if(a.file){n("Parsing app entry imports...");let e=await S({file:a.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));s.app_uses_jsx=t,s.app_has_entry=!0,e=await S({file:a.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),s.app_entry_uses_jsx=t,s.app_entry_is_ts=a.ts,s.app_entry_ext=a.ext}const c=V({dir:i.resolve(r,"./cli")});if(c.file){n("Parsing cli entry imports...");let e=await S({file:c.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));s.cli_uses_jsx=t,s.cli_has_entry=!0,e=await S({file:c.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),s.cli_entry_uses_jsx=t,s.cli_entry_is_ts=c.ts,s.cli_entry_ext=c.ext}if("workflow.lib"===t.type){const e=V({dir:i.resolve(r,"./src")});if(e.file){n("Parsing src entry imports...");let t=await S({file:e.file,recursive:!0}),o=t.all.some((e=>!0===e.usesJSX&&"local"===e.type));s.src_uses_jsx=o,s.src_has_entry=!0,t=await S({file:e.file}),o=t.all.some((e=>!0===e.usesJSX&&"local"===e.type)),s.src_entry_uses_jsx=o,s.src_entry_is_ts=e.ts,s.src_entry_ext=e.ext}}const p=Reflect.has(s,"app_entry_uses_jsx")?!0===s.app_entry_uses_jsx:!0===s.src_entry_uses_jsx,l=Reflect.has(s,"cli_entry_uses_jsx")?!0===s.cli_entry_uses_jsx:!0===s.src_entry_uses_jsx;s.form_enabled=p||l||!0===s.form||!0===s.form?.enabled,s.multiple_enabled=s.multiple_enabled||!0===s.multiple||!0===s.multiple?.enabled,!1===s.app?s.app={enabled:!1}:!0===s.app?s.app={enabled:!0,extend:!0===s.app_has_entry,export:!0,react:p}:s.app={enabled:!0,extend:!0===s.app_has_entry,export:!0,react:p,...s.app||{}},s.app.enabled=!0===s.app.enabled&&(!0===t.doc.features.form_enabled||!0===s.app.extend||!0===s.app.enabled),s.app.format=s.app.format||"esm",s.app.folder=s.app.folder||s.app.format||"default",!1===s.cli?s.cli={enabled:!1}:!0===s.cli?s.cli={enabled:!0,extend:!0===s.cli_has_entry,export:!0,react:l}:s.cli={enabled:!0,extend:!0===s.cli_has_entry,export:!0,react:l,...s.cli||{}},s.cli.enabled=!0===s.cli.enabled&&(!1===t.doc.features.form_enabled||!0===s.cli.extend||!0===s.cli.enabled),s.cli.format=s.cli.format||"esm",s.cli.folder=s.cli.folder||s.cli.folder||"esm",s.cli.node_options=s.cli.node?.options||s.cli.node_options||"",s.json=s.cli.enabled||s.json;const d={cjs:{format:"cjs",context:s.form_enabled?"window":"global",babel:!0===s.src_uses_jsx||!1,browser:!1,replace:!0,terser:!0,enabled:!1!==s.cjs,copy:!1},esm:{format:"esm",context:s.form_enabled?"window":"global",babel:!0===s.src_uses_jsx||!1,browser:!1,replace:!0,terser:!1,enabled:!1!==s.esm,copy:!0},iife:{format:"iife",context:s.form_enabled?"window":"global",babel:!0,browser:!0,replace:!0,enabled:!0===s.iife,terser:!0,copy:!1}};!0===s.webos&&(d.webos={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,input:"./src/app/index.js",output_dir:"./dist/app/webos",copy:!1,babel_options:{targets:{chrome:"79"}}}),!0===s.electron&&(d.electron={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/electron"}),!0===s.nextjs&&(d.nextjs={format:"esm",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/nextjs"}),!0===s.ios&&(d.ios={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/ios"}),!0===s.macos&&(d.macos={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/macos"}),!0===s.app.enabled&&(s.app.dir=`./dist/app/${s.app.folder}`,d.app={format:s.app.format,browser:!0,babel:!0,context:"window",replace:!0,input:"./src/app/index.js",output_dir:s.app.dir,terser:!0,output_exports:!1===s.app.export?"none":"auto",browsersync:!0}),!0===s.cli.enabled&&(s.cli.dir=`./dist/cli/${s.cli.folder}`,d.cli={format:s.cli.format,context:"global",babel:!0===s.src_uses_jsx||!0===s.cli_uses_jsx||!1,browser:!1,replace:!0,enabled:!0,input:"./src/cli/index.js",output_dir:s.cli.dir,banner:"#!/usr/bin/env node",terser:!0,output_exports:!1===s.cli.export?"none":"auto"});const f={server:".",startPath:`${i.normalize(s.app.dir||".")}`,files:[i.normalize("./dist/**/*")],cors:!0,open:!1};s.babel_options=E({targets:{browsers:"last 9 versions, not dead",node:"18"}},s.babel_options||s.babel?.options),s.browsersync_options=E(f,s.browsersync_options||s.browsersync?.options||{}),s.replace_options=E({},s.replace_options||s.replace?.options||{}),Reflect.has(s.browsersync_options,"proxy")&&delete s.browsersync_options.server,s.rollup=s.rollup||{},s.rollup_output=E(d,s.rollup_output||s.rollup?.output||{}),s.preact_enabled=!0===s.preact||s.preact&&!1!==s.preact?.enabled;let m=Object.keys(d);for(const e of m){const t=d[e];t&&(!1!==s.rollup[e]?(t.babel_options=t.babel_options||s.babel_options,t.browsersync_options=E(s.browsersync_options,t.browsersync_options),t.replace_options=E(s.replace_options,t.replace_options),s.preact_enabled&&(t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{},t.alias.entries.react="preact/compat",t.alias.entries["react-dom"]="preact/compat"),(s.form_enabled||s.babel)&&(t.babel=!0)):delete s.rollup_output[e])}m=Object.keys(s.rollup_output),s.babel_enabled=m.some((e=>!0===s.rollup_output[e].babel)),s.browser_enabled=m.some((e=>!0===s.rollup_output[e].babel)),s.browsersync_enabled=!1!==s.browsersync&&m.some((e=>!0===s.rollup_output[e].browsersync)),s.browsersync_enabled=s.browsersync_enabled&&s.app.enabled,s.dependency_auto_enabled=!1!==s.dependency_auto&&!1!==s.dependency_auto?.enabled,s.npm_install_flags=s.npm_install_flags||"",s.react_version=s.react_version||s.react?.version||18,function(e){const{atom:t,packageDevDependencies:o}=e,n=t.doc.features,i=n.css&&!1!==n.css.enabled;let s=[];i&&(s.push(["rollup-plugin-postcss","^4"]),s.push(["sass","^1.66"]),(n.css?.options?.plugins||[]).forEach((e=>{switch(e.name){case"postcss-import":s.push(["postcss-import","^15"]);break;case"postcss-url":s.push(["postcss-url","^10"]);break;case"postcss-preset-env":s.push(["postcss-preset-env","^9"]);break;case"autoprefixer":s.push(["autoprefixer","^10"]);break;case"cssnano":s.push(["cssnano","^6"])}})));X({feature:{name:"css",packages:s},features:n,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e,n=t.doc.features,i={};!0===n.app?.enabled&&(i.targets=i.targets||[],i.targets.push({src:"./src/app/index.html",dest:n.app.dir}),Reflect.has(n.app,"copy")||Reflect.has(n,"copy")||(n.copy=!0)),X({feature:{name:"copy",packages:[["rollup-plugin-copy","^3"],["chokidar","^3"]],options:i},features:n,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"wasm",packages:[["@rollup/plugin-wasm","^6"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"terser",packages:[["@rollup/plugin-terser","^0.4"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"json",packages:[["@rollup/plugin-json","^6"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"string",packages:[["rollup-plugin-string","^3"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"image",packages:[["@rollup/plugin-image","^3"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"analyzer",packages:[["rollup-plugin-analyzer","^3"]],options:{summaryOnly:!0,limit:12},explicit:!0},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"visualizer",packages:[["rollup-plugin-visualizer","^5"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"polyfill",packages:[["rollup-plugin-node-polyfills","^0.2"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"nunjucks",packages:[["@fnet/rollup-plugin-nunjucks","0.1.8"]]},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"workbox",packages:[["rollup-plugin-workbox","^8"]],options:{generate:{swDest:"dist/app/esm/sw.js",globDirectory:"dist/app/esm",globPatterns:["**/*.{html,js,css,png,jpg}"],skipWaiting:!0,clientsClaim:!0}},explicit:!0},features:t.doc.features,packageDevDependencies:o})}(e),function(e){const{atom:t,packageDevDependencies:o}=e;X({feature:{name:"gzip",packages:[["rollup-plugin-gzip","^4"]],explicit:!0},features:t.doc.features,packageDevDependencies:o})}(e)}async function G({projectDir:e,name:t,setProgress:n,count:s=1}){let r;const a=C(["npm-pick-versions",t,s]),c=i.join(e,".cache"),p=i.join(c,a+".json");return o.existsSync(p)?(n&&n(`Picking npm version of ${t} from cache ...`),r=JSON.parse(o.readFileSync(p,"utf8"))):(n&&n(`Picking npm version of ${t} ...`),r=await $({name:t,count:s}),o.mkdirSync(c,{recursive:!0}),o.writeFileSync(p,JSON.stringify(r),"utf8")),r}var Y=async e=>{const{atom:t,packageDependencies:o,context:n,deploymentProjectTarget:i,setProgress:s,deploymentProject:r,yamlTarget:a}=e;if(!0!==i.enabled)return;const c=i.type;try{if("lib"===c)await(await import("./index.DLGSTm8o.js")).default({...e});else if("red"===c)await(await import("./index.CmMM-Ek9.js")).default({...e});else if("npm"===c)await(await import("./index.Bn6hEUL-.js")).default({...e});else if("gcs"===c)await(await import("./index.UOds5XLl.js")).default({...e});else if("gitlab"===c)await(await import("./index.DI3yyTtl.js")).default({...e});else if("fnet-package"===c)await(await import("./index.Bfg4lyu-.js")).default({...e});else if("fnet-form"===c)await(await import("./index.Q-CYRcna.js")).default({...e});else if("fnet-node"===c)await(await import("./index.BoO2Mnox.js")).default({...e});else if("fnet-flow"===c)await(await import("./index.dpz2QIRu.js")).default({...e});else if("nextjs"===c)await(await import("./index.CDct_kkF.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("webos"===c)await(await import("./index.CMC8mlye.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("electron"===c)await(await import("./index.xd8c7XMr.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("docker"===c)await(await import("./index.D2N9YZmA.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("ios"===c)await(await import("./index.B5XE4ChJ.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("macos"===c)await(await import("./index.W6RYgypK.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else if("rust"===c)await(await import("./index.CzAV0S36.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0;else{if("pypi"!==c)return void console.warn(`No deployer found for type: ${c}`);await(await import("./index.C7saWH6d.js")).default({atom:t,target:i,onProgress:s,projectDir:n.projectDir,dependencies:o,context:n,yamlTarget:a}),r.isDirty=!0}}catch(e){throw console.error(`Error during deployment for type "${c}":`,e),e}},Z={name:"ATOM",uri:"http://atom.org/bpmn",prefix:"atom",types:[{name:"AtomExtension",extends:["bpmn:BaseElement"],properties:[{name:"atom",type:"atom:Atom",isMany:!1}]},{name:"Atom",properties:[{name:"type",type:"String",isAttr:!0}]}]};function Q(e,t){return e.filter(((e,o,n)=>n.map((e=>e[t])).indexOf(e[t])===o))}function ee(e){const{nodes:t,nodeIndex:o,root:n}=e,i=e.targetNodes||n.childs;i.forEach((t=>{const o="workflow"===t.type||"subworkflow"===t.type,n=!o&&t.childs.filter((e=>!e.virtual)).length>0;if(n&&(t.bpmn.type="bpmn:SubProcess"),o||n){const o=t.childs.filter((e=>!0!==e.module))[0];t.childs.filter((e=>!0===e.module)).forEach((o=>{const n=te({...e,parent:t,bpmnType:"bpmn:IntermediateCatchEvent",type:"inter",definitions:[{type:"bpmn:SignalEventDefinition"}]});n.bpmn.edges=[{from:n.indexKey,to:o.indexKey,type:"bpmn:SequenceFlow"}]}));const n=t.childs.find((e=>"try"===e.name&&"tryexcept"===t.type)),s=t.childs.filter((e=>"except"===e.name&&"tryexcept"===t.type));n&&s.length&&s.forEach((o=>{const i=te({location:t.childs.indexOf(o),...e,parent:t,bpmnType:"bpmn:BoundaryEvent",type:"boundary",attrs:{attachedToRef:n},definitions:[{type:"bpmn:ErrorEventDefinition"}]});i.bpmn.edges=[{from:i.indexKey,to:o.indexKey,type:"bpmn:SequenceFlow"}]}));const r=t.childs.find((e=>"raise"===e.type));if(r){const o=te({...e,parent:t,bpmnType:"bpmn:EndEvent",type:"end",name:"ERROR",definitions:[{type:"bpmn:ErrorEventDefinition"}]});r.bpmn.edges=[{from:r.indexKey,to:o.indexKey,type:"bpmn:SequenceFlow"}]}if(o)if(t.bpmn.starts.length>1){const o=te({...e,parent:t,bpmnType:"bpmn:StartEvent",type:"start"}),n=te({...e,parent:t,bpmnType:"bpmn:ExclusiveGateway",type:"switch"});o.bpmn.edges=[{from:o.indexKey,to:n.indexKey,type:"bpmn:SequenceFlow"}],n.bpmn.edges=t.bpmn.starts.map((e=>({...e,from:n.indexKey})));const i=n.bpmn.edges.find((e=>!0===e.next));if(i){const o=te({...e,parent:t,bpmnType:"bpmn:EndEvent",type:"end",name:i.to});i.to=o.indexKey}}else{const n=te({...e,parent:t,bpmnType:"bpmn:StartEvent",type:"start"});n.bpmn.edges.push({from:n.indexKey,to:o.indexKey,type:"bpmn:SequenceFlow"})}t.childs.filter((e=>!0!==e.virtual&&e.bpmn.outside.length&&"bpmn:EndEvent"!==e.bpmn.type)).forEach((o=>{o.bpmn.outside.forEach((n=>{const s=i.indexOf(t),r=te({...e,parent:t,bpmnType:"bpmn:EndEvent",type:"end",name:n.to,location:s+1});o.bpmn.edges.push({from:o.indexKey,to:r.indexKey,type:"bpmn:SequenceFlow"})}))}));t.childs.filter((e=>!0!==e.virtual&&e.bpmn.edges.length>1)).forEach((o=>{const n=i.indexOf(o),s=te({...e,parent:t,bpmnType:"bpmn:ExclusiveGateway",type:"switch",location:n+1});s.bpmn.edges=o.bpmn.edges.map((e=>({...e,from:s.indexKey}))),o.bpmn.edges=[{from:o.indexKey,to:s.indexKey,type:"bpmn:SequenceFlow"}],o.bpmn.outside=[]}))}ee({...e,targetNodes:t.childs})}))}function te(e){const{parent:t,nodes:o,nodeIndex:n,bpmnType:i,type:s,name:r,outside:a,location:c,definitions:p,attrs:l}=e,d=t.childs.filter((e=>e.type===`v${s}`)).length,f={indexKey:`${t.indexKey}/_${s}${d}`,pathKey:`${t.pathKey}._${s}${d}`,type:`v${s}`,name:r,bpmn:{edges:[],outside:[],type:i,width:36,height:36,fill:"#c8e6c9",stroke:"#205022",definitions:p,attrs:l},virtual:!0,childs:[]};return t.childs.splice(c||0,0,f),o.push(f),n[f.indexKey]=f,f}function oe(e){const{targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:n,moddle:i,elementIndex:s,nodeIndex:r,diagrams:a,nodes:c}=e;!function(e){const{targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:n,moddle:i,elementIndex:s,nodeIndex:r,nodes:a}=e,c=o.get("flowElements");o.$nodes=o.$nodes||[],t.childs.forEach((e=>{const t=i.create(e.bpmn.type,{id:`node.${e.pathKey}`,name:e.definition?.title||e.name});if(s[t.id]=t,t.$isNode=!0,t.$node=e,e.$flow=t,o.$nodes.push(t),c.push(t),e.bpmn.attrs){Object.keys(e.bpmn.attrs).forEach((o=>{"attachedToRef"===o&&t.set(o,e.bpmn.attrs[o].$flow)}))}if(e.bpmn.definitions){const o=e.bpmn.definitions.map((e=>{const t=i.create(e.type);return Object.keys(e.attrs||{}).forEach((o=>{t.set(o,e.attrs[o])})),t}));t.eventDefinitions=o}}))}(e),function(e){const{targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:n,moddle:i,elementIndex:s,nodeIndex:r}=e,a=o.get("flowElements");o.$edges=o.$edges||[],t.childs.forEach((e=>{e.bpmn.edges.forEach((t=>{const n=e,c=r[t.to],p=`edge.${n.pathKey}_${c.pathKey}`;if(s[p])return;const l=s[`node.${n.pathKey}`],d=s[`node.${c.pathKey}`],f=i.create(t.type,{id:p,sourceRef:l,targetRef:d});s[f.id]=f,f.$is_edge=!0,l.get("outgoing").push(f),d.get("incoming").push(f),o.$edges.push({from:l,to:d,flow:f}),a.push(f)}))}))}(e),function(e){const{targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:n,moddle:i,elementIndex:s,nodeIndex:r}=e,a=120,c=80,p=160,l=160,d=new B.graphlib.Graph;d.setDefaultEdgeLabel((()=>({}))),d.setGraph({rankdir:"TB",nodesep:a,ranksep:c,xranker:"longest-path"}),o.$nodes.forEach((e=>{d.setNode(e.id,{width:e.$node?.bpmn.width||a,height:e.$node?.bpmn.height||c,label:e.id})})),o.$edges.forEach((e=>{d.setEdge(e.from.id,e.to.id)})),B.layout(d),o.$nodes.forEach((e=>{const t=d.node(e.id);let o=t.width,s=t.height;const r=i.create("bpmndi:BPMNShape",{id:`shape.${e.id}`,bpmnElement:e,bounds:i.create("dc:Bounds",{x:p+t.x-t.width/2,y:l+t.y-t.height/2,width:o,height:s}),label:i.create("bpmndi:BPMNLabel")});e.$node.bpmn.fill&&r.set("bioc:fill",e.$node.bpmn.fill),e.$node.bpmn.stroke&&r.set("bioc:stroke",e.$node.bpmn.stroke);n.get("planeElement").push(r)})),o.$edges.forEach((e=>{const t=d.edge(e.from.id,e.to.id),o=i.create("bpmndi:BPMNEdge",{id:`edge.${e.from.id}_${e.to.id}`,bpmnElement:e.flow,label:i.create("bpmndi:BPMNLabel")});t.points.forEach((e=>{const t=i.create("dc:Point",{x:p+e.x,y:l+e.y});o.get("waypoint").push(t)}));n.get("planeElement").push(o)}))}(e),function(e){const{targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:n,moddle:i,elementIndex:s,nodeIndex:r,diagrams:a}=e,c=t.childs.filter((e=>"bpmn:SubProcess"===e.bpmn.type));c.forEach((t=>{const o=s[`node.${t.pathKey}`],n=i.create("bpmndi:BPMNDiagram",{id:`diagram_${t.pathKey}`});s[n.id]=n,a.push(n);const r=i.create("bpmndi:BPMNPlane",{id:`plane_${t.pathKey}`});s[r.id]=r,n.plane=r,r.bpmnElement=o,oe({...e,targetNode:t,targetFlowElementsContainer:o,targetPlaneElement:r})}))}(e)}async function ne(e){const t=e.root,o=t.context.index,n=Object.keys(o).map((e=>o[e]));!function(e){const{nodes:t}=e;t.forEach((e=>{const t=[],o=[],n=i=>{i.context.next&&(t.push({from:i,to:i.context.next,type:"bpmn:SequenceFlow"}),i===e&&o.push({to:i.context.next,type:"bpmn:SequenceFlow",next:!0})),i.childs.forEach((t=>{i===e&&"switch"===e.type&&o.push({to:t,type:"bpmn:SequenceFlow"}),n(t)}))};n(e);const i=t.filter((t=>t.to.parent.indexKey===e.parent.indexKey)).map((t=>({...t,from:e.indexKey,to:t.to.indexKey}))),s=t.filter((t=>t.to.parent.indexKey!==e.parent.indexKey&&!t.to.indexKey.startsWith(e.indexKey+"/"))).map((t=>({...t,from:e.indexKey,to:t.to.indexKey}))),r=o.map((e=>({...e,to:e.to.indexKey})));e.bpmn=e.bpmn||{},e.bpmn.edges=Q(i,"to"),e.bpmn.outside=Q(s,"to"),e.bpmn.starts=Q(r,"to"),e.bpmn.type=function(e){return"call"===e.type?"bpmn:ServiceTask":"form"===e.type?"bpmn:UserTask":"return"===e.type?"bpmn:EndEvent":"bpmn:Task"}(e),e.bpmn.width=120,e.bpmn.height=80,"return"===e.type&&(e.bpmn.width=36,e.bpmn.height=36)}))}({nodes:n}),ee({nodes:n,nodeIndex:o,root:t});const i=new I({atom:Z}),s={},r=i.create("bpmn:Definitions",{id:"definitions_0"});s[r.id]=r;for await(const e of t.childs){const a=r.get("rootElements"),c=r.get("diagrams"),p=i.create("bpmn:Process",{id:`process_${e.pathKey}`,documentation:[i.create("bpmn:Documentation",{text:`Atom Workflow - ${t.context.atom.name}`})]});s[p.id]=p,p.isExecutable=!0,a.push(p);const l=i.create("bpmndi:BPMNDiagram",{id:`diagram_${e.pathKey}`});s[l.id]=l,c.push(l);const d=i.create("bpmndi:BPMNPlane",{id:`plane_${e.pathKey}`});s[d.id]=d,l.plane=d,d.bpmnElement=p;oe({targetNode:e,targetFlowElementsContainer:p,targetPlaneElement:d,moddle:i,elementIndex:s,nodeIndex:o,nodes:n,diagrams:c})}return{diagramXML:(await i.toXML(r,{format:!0})).xml}}async function ie(e={}){return await ne(x(e))}async function se({node:e,initNode:t}){if(Reflect.has(e.definition,"modules")&&!Array.isArray(e.definition.modules)){const t=e.definition.modules;e.definition.modules=[],Object.keys(t).forEach((o=>{const n={...t[o]};"modules"===e.type&&(n.export=n.export||o),e.definition.modules.push({[o]:n})}))}const o=[],n=await J({data:e.definition,callback:(e,t,n)=>{const i=K({expression:e});if("m"===i?.processor){const e=n.slice(0,-1);e.push(i.statement);const s=e.join("_");return o.push({[s]:t}),[i.statement,`m::${s}`]}return[e,t]}});o.length>0&&(e.definition=n,e.definition.modules=e.definition.modules||[],e.definition.modules=e.definition.modules.concat(o)),e.hasModules=e.definition.modules?.length>0;for(let o=0;o<e.definition.modules?.length;o++){const n=e.definition.modules[o],i=Object.keys(n)[0],s={name:i,childs:[],parent:e,definition:n[i],module:!0,blockAutoJumpToParent:!0,blockAutoJumpToSibling:!1,index:e.childs.length,context:{}};e.childs.push(s),await t({node:s})}}async function re({node:e,transformExpression:t}){const o=e.context.transform;Reflect.has(o,"export")&&(o.export=await t(o.export)),Reflect.has(o,"return")&&(e.hasReturn=!0,o.return=await t(o.return)),o.hasOwnProperty("nextArgs")&&(e.hasNextArgs=!0,o.nextArgs=await t(o.nextArgs))}async function ae({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition),e.context.transform;for(const t of e.childs)t.context.transform=t.context.transform||x(t.definition),t.definition.hasOwnProperty("condition")&&(t.context.transform.condition=await n(t.definition.condition));await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var ce={hits:async function({node:e}){return!!e.definition.hasOwnProperty("switch")},init:async function({node:e,initNode:t}){e.type="switch";const o=e.definition.switch||[];if(!o.every((e=>e.hasOwnProperty("condition")||e.hasOwnProperty("default"))))throw new Error("Switch must have condition or default");if(0===o.filter((e=>e.hasOwnProperty("condition"))).length)throw new Error("Switch must have at least one condition");const n=o.filter((e=>e.hasOwnProperty("default")));if(n.length>1)throw new Error("Switch must have only one default");if(1===n.length&&!o[o.length-1].hasOwnProperty("default"))throw new Error("Switch default must be the last child");e.hasDefaultCondition=1===n.length,await se({node:e,initNode:t}),e.blockAutoJumpToParent=!1,e.blockAutoJumpToSibling=!0;for(let o=0;o<e.definition.switch.length;o++){let n=e.definition.switch[o],i=`${o}`;n.hasOwnProperty("default")&&(i="default",n=n.default);const s={name:n.condition||i,childs:[],parent:e,definition:n,index:e.childs.length,context:{}};e.childs.push(s),await t({node:s})}e.resolve=ae},resolve:ae};var pe={hits:async function({node:e}){return 1===Object.keys(e.definition).map((e=>K({expression:e}))).filter((e=>"if"===e?.processor)).length},init:async function(e){const{node:t}=e,o=Object.keys(t.definition).map((e=>K({expression:e}))),n=[],i=o.find((e=>"if"===e?.processor)),s=t.definition[i.expression];n.push({name:`${t.name}_if`,definition:s,processor:i}),delete t.definition[i.expression];const r=o.filter((e=>"elseif"===e?.processor));let a=0;for(const e of r){const o=t.definition[e.expression];n.push({name:`${t.name}_elseif_${a++}`,definition:o,processor:e}),delete t.definition[e.expression]}t.definition.switch=[];for(const e of n)t.definition.switch.push({condition:e.processor.statement,...e.definition});if(t.definition?.else){const e=t.definition.else;t.definition.switch.push({default:e}),delete t.definition.else}await ce.init(e)}};async function le({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){if(e.context.transform=e.context.transform||x(e.definition),e.context.transform,e.context.try=e.childs.find((e=>"try"===e.name)),e.context.except=e.childs.find((e=>"except"===e.name)),e.context.except){const t=e.context.except;t.context.transform=t.context.transform||x(t.definition),t.context.transform.hasOwnProperty("as")||(t.context.transform.as="error")}await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var de={hits:async function({node:e}){return e.definition.hasOwnProperty("try")&&e.definition.hasOwnProperty("except")},init:async function({node:e,initNode:t}){if(e.type="tryexcept",await se({node:e,initNode:t}),e.blockAutoJumpToParent=!1,e.blockAutoJumpToSibling=!0,e.definition.try){const o="try",n={name:o,childs:[],parent:e,definition:e.definition[o],index:e.childs.length,context:{}};e.childs.push(n),await t({node:n})}if(e.definition.except){const o="except",n={name:o,childs:[],parent:e,definition:e.definition[o],index:e.childs.length,context:{}};e.childs.push(n),await t({node:n})}e.resolve=le},resolve:le};async function fe({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition);const i=e.context.transform;for(let e=0;e<i.assign?.length;e++){let t=i.assign[e],o=Object.keys(t)[0],s=t[o],r={key:await n(o),value:await n(s)};i.assign[e]=r}await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var me={hits:async function({node:e}){return e.definition.hasOwnProperty("assign")},init:async function({node:e,initNode:t}){e.type="assign",await se({node:e,initNode:t}),e.resolve=fe},resolve:fe};async function ue({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition);e.context.transform.for.in=await n(e.definition.for.in),await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var he={hits:async function({node:e}){return e.definition.hasOwnProperty("for")},init:async function({node:e,initNode:t}){if(e.type="for",await se({node:e,initNode:t}),e.blockAutoJumpToParent=!0,e.blockAutoJumpToSibling=!1,!e.definition.for.hasOwnProperty("steps")){const t=["value","in"],[o,n]=[L(e.definition.for,t),z(e.definition.for,t)];e.definition.for=o,e.definition.for.steps=[{[`${e.name}_step`]:n}]}Array.isArray(e.definition.for.steps)||(e.definition.for.steps=[{[`${e.name}_step`]:e.definition.for.steps}]);for(let o=0;o<e.definition.for.steps.length;o++){const n=e.definition.for.steps[o],i=Object.keys(n)[0],s={name:i,childs:[],parent:e,definition:n[i],index:e.childs.length,context:{}};e.childs.push(s),await t({node:s})}e.resolve=ue},resolve:ue};var ye={hits:async function({node:e}){return!1},init:async function({node:e,initNode:t}){},resolve:async function({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n,transformValue:i}){}};async function ge({node:e,resolveTypeCommon:t,transformExpression:o}){e.context.transform=e.context.transform||x(e.definition);const n=e.context.transform;n.raise=await o(n.raise),await t({node:e})}var we={hits:async function({node:e}){return e.definition.hasOwnProperty("raise")},init:async function({node:e,initNode:t}){e.type="raise",e.resolve=ge},resolve:ge};async function xe({node:e,resolveTypeCommon:t,transformExpression:o}){e.context.transform=e.context.transform||x(e.definition);const n=e.context.transform;e.hasReturn=!0,n.return=await o(n.return),await t({node:e})}var be={hits:async function({node:e}){return e.definition.hasOwnProperty("return")},init:async function({node:e,initNode:t}){e.type="return",e.resolve=xe},resolve:xe};async function ke({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition);const i=e.context.transform;if("function"===e.target?.atom?.doc?.type&&(i.call=await n(e.target.atom.name)),i.args&&(i.args=await n(i.args)),i.result){"string"==typeof i.result&&(i.result=[{[i.result]:"e::result"}]);for(let e=0;e<i.result?.length;e++){let t=i.result[e],o=Object.keys(t)[0],s=t[o],r={key:await n(o),value:await n(s)};i.result[e]=r}}const s=e.workflow.parent;i.import?e.context.lib=s.context.libs.find((e=>e.name===i.import)):e.context.lib=s.context.libs.find((e=>e.name===i.call)),await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var ve={hits:async function({node:e}){return e.definition.hasOwnProperty("call")},init:async function({node:e,initNode:t}){e.type="call",await se({node:e,initNode:t}),e.resolve=ke},resolve:ke};async function je({node:e,transformExpression:t}){e.context.next=e.childs[0],e.context.transform=e.context.transform||x(e.definition),await re({node:e,transformExpression:t})}var De={hits:async function({node:e}){return e.definition.hasOwnProperty("steps")},init:async function({node:e,initNode:t}){e.type||(e.type="steps");const o=e.definition.steps||[];for await(const n of o){const o=Object.keys(n)[0],i={name:o,childs:[],parent:e,definition:n[o],index:e.childs.length,context:{}};e.childs.push(i),await t({node:i})}e.resolve=je},resolve:je};async function _e({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition);const i=e.context.transform;i.props&&(i.props=await n(i.props));const s=e.workflow.parent;e.context.lib=s.context.libs.find((e=>e.name===i.form)),await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var Ee={hits:async function({node:e}){return e.definition.hasOwnProperty("form")},init:async function({node:e,initNode:t}){e.type="form",await se({node:e,initNode:t}),e.resolve=_e},resolve:_e};async function Se({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n,transformValue:i}){e.context.transform=e.context.transform||x(e.definition),await t({node:e})}var Pe={hits:async function({node:e}){return e.definition.hasOwnProperty("operation")},init:async function({node:e,initNode:t}){e.type="operation",e.resolve=Se},resolve:Se};async function $e({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition);const i=e.context.transform;i.next=await n(i.next),await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var Ce={hits:async function({node:e}){return e.definition.hasOwnProperty("next")},init:async function({node:e,initNode:t}){e.type="jump",e.resolve=$e},resolve:$e};async function Te({node:e,resolveTypeCommon:t,resolveNextBlock:o,transformExpression:n}){e.context.transform=e.context.transform||x(e.definition),e.context.transform,await re({node:e,transformExpression:n}),await t({node:e}),o({node:e})}var Ne={hits:async function({node:e}){return e.definition.hasOwnProperty("modules")},init:async function({node:e,initNode:t}){e.type="modules",await se({node:e,initNode:t}),e.resolve=Te},resolve:Te};function Fe({node:e}){const t=e.definition;if(!e.hasReturn)if("end"===t.next);else if("stop"===t.next);else if("none"===t.next);else if(t.next){let o=e.parent;for(;o.parent;){const n=o.childs.find((e=>e.name===t.next));if(n){e.context.next=n;break}o=o.parent}}else{if(!0===e.module)return;let t=e.parent,o=e.index+1;for(;t.parent&&(!t.blockAutoJumpToParent||!t.blockAutoJumpToSibling);)if(Reflect.has(t,"blockAutoJumpToParent")||Reflect.has(t,"blockAutoJumpToSibling")){if(t.blockAutoJumpToParent){const n=t.childs.find((e=>e.index===o));n&&(e.context.next=n);break}t.blockAutoJumpToParent||(o=t.index+1,t=t.parent)}else{const n=t.childs.find((e=>e.index===o));if(n){e.context.next=n;break}o=t.index+1,t=t.parent}}}class Ae{#e;#t;#o;#n;constructor({key:e,npm:t,master:o,extras:n}){this.#e=e,this.#t=t,this.#o=o,this.#n=n}hits({node:e}){return e.definition.hasOwnProperty(this.#e)}async init(e){const{node:t}=e,o=this.#e,n=t.definition,i=typeof n[o];if(n.call=`npm:${this.#t}`,n.args="object"!==i?{...n.args,[`${this.#o}`]:n[o]}:n[o],delete n[o],this.#n)for(const e in this.#n)n[e]=this.#n[e];console.log(`[npm-block] ${this.#e} --\x3e ${this.#t}`),await ve.init(e)}}function Oe(e){return new Ae(e)}class Ie{#i;#s;#r;#a;#c;#p;#l;#d;#f;#m;#u;#h;#y;#g;#w;#x;#b;#k;#v;#j;#D;#_=[];constructor(e){this.#i=new U,this.#s=e,this.#p=[],this.#l=[],this.#d={},this._expire_ttl=3600,this._expire_ttl_short=300,this.#_.push(Oe({key:"config",npm:"@fnet/config",master:"name"})),this.#_.push(Oe({key:"yaml",npm:"@fnet/yaml",master:"file"})),this.#_.push(Oe({key:"prompt",npm:"@fnet/prompt",master:"message"})),this.#_.push(Oe({key:"html-link",npm:"@flownet/lib-load-browser-link-url",master:"src"})),this.#_.push(Oe({key:"html-script",npm:"@flownet/lib-load-browser-script-url",master:"src"})),this.#_.push(Oe({key:"http-server",npm:"@fnet/node-express",master:"server_port"})),this.#_.push(Oe({key:"shell",npm:"@fnet/shell-flow",master:"commands"})),this.#_.push(Oe({key:"list-files",npm:"@fnet/list-files",master:"pattern"})),this.#_.push(Oe({key:"up-list-files",npm:"@fnet/up-list-files",master:"pattern"})),this.#_.push(Oe({key:"auto-conda-env",npm:"@fnet/auto-conda-env",master:"envDir"})),this.#_.push(Oe({key:"ollama-chat",npm:"@fnet/ollama-chat",master:"model"})),this.#_.push(Oe({key:"ai",npm:"@fnet/ai",master:"prompt",extras:{subtype:"flow"}})),this.#_.push(Oe({key:"invoke",npm:"@fnet/invoke",master:"method",extras:{}})),this.#_.push(Oe({key:"fetch",npm:"@fnet/fetch",master:"url",extras:{}})),this.#_.push(Oe({key:"filemap",npm:"@fnet/filemap",master:"target",extras:{}})),this.#j={packageDependencies:this.#p,packageDevDependencies:this.#l,setProgress:this.setProgress.bind(this),context:this.#s,Atom:_,registerToPackageManager:this.registerToPackageManager.bind(this)},this.#D={initNode:this.initNode.bind(this),cloneDeep:x,resolveTypeCommon:this.resolveTypeCommon.bind(this),resolveNextBlock:Fe,transformExpression:this.transformExpression.bind(this),transformValue:this.transformValue.bind(this)}}async _cache_set(e,t,o){this._redis_client&&await this._redis_client.SETEX(e,o||this._expire_ttl,JSON.stringify(t)).catch(console.error)}async init(){this._redis_client=await async function(){if(!await v({host:process.env.REDIS_HOST,port:process.env.REDIS_PORT}))return;const e=k.createClient({socket:{host:process.env.REDIS_HOST,port:process.env.REDIS_PORT}});return await e.connect(),e}(),this.#u=this.#s.buildId||j(),this.#j.buildId=this.#u,this.#w=this.#s.mode,this.#x=["all","deploy","build","file"].includes(this.#w),this.#b=["all","deploy","build"].includes(this.#w),this.#k=["all","deploy"].includes(this.#w),this.#v=["all","deploy","build","file","bpmn"].includes(this.#w),this.#y=this.#s.protocol,this.#h="BUILD:"+this.#u,this.#g=(await a({optional:!0,name:"atom",dir:this.#s.projectDir,tags:this.#s.tags}))?.data;try{await this.setProgress({message:"Initialization started."}),await this.initAuth(),await this.initWorkflow(),this.transformWorkflow({workflow:this.#a});const e=await this.initNodeTree({workflow:this.#a});await this.initNodeTreeIndex({root:e}),await this.initNodeCalls({root:e}),await this.initNodeCallLibs({root:e}),await this.initNodeForms({root:e}),await this.initNodeFormLibs({root:e}),await this.initEntryFiles({root:e,features:this.#r.doc.features}),await this.initFeaturesFromNodes({childs:e.childs,features:this.#r.doc.features}),await H(this.#j),await async function({atom:e,packageDependencies:t,packageDevDependencies:o,setProgress:n}){n("Initializing dependencies");const i=e.doc.dependencies||[];if(i.filter((e=>!e.dev)).forEach((e=>t.push(e))),i.filter((e=>e.dev)).forEach((e=>o.push(e))),"workflow"===e.type&&(t.push({package:"get-value",version:"^3"}),t.push({package:"set-value",version:"^4"})),e.doc.features.form_enabled&&e.doc.features.dependency_auto_enabled){let o="^18.2";n("Fetching React versions"),o=`^${(await P({name:"react",groupBy:{major:!0}})).find((t=>t[0]===e.doc.features.react_version.toString()))[0]}`,t.push({package:"react",version:o}),t.push({package:"react-dom",version:o}),"workflow"===e.type&&(t.push({package:"@fnet/react-app",version:"^0.1"}),t.push({package:"@fnet/react-app-state",version:"^0.1"}))}e.doc.features.preact_enabled&&t.push({package:"preact",version:"^10"}),!0===e.doc.features.cli.enabled&&(t.push({package:"@fnet/args",version:"^0.1"}),o.push({package:"ajv",version:"^8"}),e.doc.features.cli.fargs&&!1!==e.doc.features.cli.fargs?.enabled&&t.push({package:"@fnet/config",version:"0.2.21"})),e.doc.features.render&&!1!==e.doc.features.render.enabled&&o.push({package:"@flownet/lib-render-templates-dir",version:"0.1.19"}),o.push({package:"@babel/core",version:"^7"}),o.push({package:"@rollup/plugin-commonjs",version:"^28"}),o.push({package:"@rollup/plugin-node-resolve",version:"^16"}),o.push({package:"@rollup/plugin-replace",version:"^6"}),o.push({package:"rollup",version:"^4"}),e.doc.features.dts_enabled&&o.push({package:"rollup-plugin-dts",version:"^6"}),o.push({package:"rollup-plugin-peer-deps-external",version:"^2"}),o.push({package:"@rollup/plugin-alias",version:"^5"}),o.push({package:"fs-extra",version:"^11"}),e.doc.features.babel_enabled&&(o.push({package:"@rollup/plugin-babel",version:"^6"}),o.push({package:"@babel/preset-env",version:"^7"}),o.push({package:"@babel/preset-react",version:"^7"}),e.doc.features.babel?.options?.plugins?.forEach((e=>{switch(e[0]){case"@babel/plugin-proposal-decorators":o.push({package:"@babel/plugin-proposal-decorators",version:"^7"});break;case"@babel/plugin-proposal-class-properties":o.push({package:"@babel/plugin-proposal-class-properties",version:"^7"});break;case"@babel/plugin-proposal-private-methods":o.push({package:"@babel/plugin-proposal-private-methods",version:"^7"});break;case"@babel/plugin-proposal-private-property-in-object":o.push({package:"@babel/plugin-proposal-private-property-in-object",version:"^7"});break;case"@babel/plugin-proposal-optional-chaining":o.push({package:"@babel/plugin-proposal-optional-chaining",version:"^7"})}}))),o.push({package:"@fnet/rollup-plugin-delete",version:"0.1.10"}),e.doc.features.browsersync_enabled&&o.push({package:"@fnet/rollup-plugin-browsersync",version:"0.1.11"})}(this.#j),await this.initAtomLibsAndDeps({libs:e.context.libs,packageDependencies:this.#p}),await this.resolveNodeTree({root:e}),this.#m=e}catch(e){throw await this._cache_set(this.#h,{status:"FAILED",message:e?.message||e}),e}}async initAuth(){this.#s.id&&(this.#f=await this.#i.init({config:this.#g}),this.#j.atomAccessToken=this.#f)}async initWorkflow(){const e=this.#s.id;this.#r=this.#s.project?.workflowAtom||await _.get({id:e}),this.#a="string"==typeof this.#r.doc.content?(await u({content:this.#r.doc.content,tags:this.#s.tags})).parsed:this.#r.doc.content;let t=this.#r.doc.bundleName;t=t||(this.#r.doc.name||"").toUpperCase().replace(/[^A-Z0-9]/g,"_"),this.#r.doc.bundleName=t,this.#r.type=this.#r.type||"workflow",this.#j.atom=this.#r,this.#r.doc.features=this.#r.doc.features||{}}#E(e){console.log("filePath",e),o.statSync(e).isDirectory()?(o.readdirSync(e).forEach((t=>{const o=i.join(e,t);this.#E(o)})),o.rmSync(e)):o.unlinkSync(e)}#S(e,t){const n=o.existsSync(e),s=n&&o.statSync(e);n&&s.isDirectory()?(o.mkdirSync(t,{recursive:!0}),o.readdirSync(e).forEach((o=>{this.#S(i.join(e,o),i.join(t,o))}))):o.copyFileSync(e,t)}async initWorkflowDir(){this.setProgress({message:"Initializing library directory."});const e=this.#s.projectDir,t=this.#s.coreDir;this.setProgress({message:"Cleaning project directory."});const n=M({dir:e,ignore:[".cache","node_modules",".conda"],absolute:!0});for(const e of n)o.rmSync(e,{recursive:!0,force:!0});this.setProgress({message:"Creating project directory."}),o.existsSync(e)||o.mkdirSync(e,{recursive:!0});const s=i.join(e,"src");o.existsSync(s)||o.mkdirSync(s,{recursive:!0});const r=i.join(s,"core");this.#S(t,r);const a=i.join(s,"default","blocks");o.existsSync(a)||o.mkdirSync(a,{recursive:!0})}async initNunjucks(){this.setProgress({message:"Initializing nunjucks."});const e=this.#s.templateDir;this.#c=w.configure(e,{watch:!1,dev:!0}),this.#j.njEnv=this.#c}transformWorkflow({workflow:e}){for(const t of Object.values(e))t.steps=t.steps||[],t.steps=t.steps.filter((e=>Object.keys(e).length>0)),t.steps=t.steps.map((e=>this.transformStep({step:e})))}transformStep({step:e}){if(Array.isArray(e))throw new Error("Step must be an object.");const[t,o]=Object.entries(e)[0];if(o.hasOwnProperty("onerror")){const{onerror:n,...i}=o;e[t]={try:i,except:n}}if(e[t].hasOwnProperty("steps")){const o=e[t].steps;if(!Array.isArray(o))throw new Error("Steps must be an array.");e[t].steps=o.map((e=>this.transformStep({step:e})))}return e}async initNodeTree({workflow:e}){const t=Object.keys(e),o={definition:e,name:void 0,type:"root",parent:void 0,childs:[],blockAutoJumpToParent:!0,blockAutoJumpToSibling:!0,index:0,depth:0,context:{libs:[],atom:this.#r}};t.forEach((t=>{const n={name:t,type:"main"===t?"workflow":"subworkflow",childs:[],parent:o,definition:e[t],index:o.childs.length,depth:o.depth+1,context:{},blockAutoJumpToParent:!0,blockAutoJumpToSibling:!1};o.childs.push(n)}));for await(const e of o.childs)await this.initNode({node:e});return o}async initNode({node:e}){const t={...this.#D,node:e};if(e.workflow=e.parent.workflow||e,e.depth=e.parent.depth+1,await de.hits(t))await de.init(t);else if(await he.hits(t))await he.init(t);else if(await ce.hits(t))await ce.init(t);else if(await pe.hits(t))await pe.init(t);else if(await ye.hits(t))await ye.init(t);else if(await me.hits(t))await me.init(t);else if(await we.hits(t))await we.init(t);else if(await ve.hits(t))await ve.init(t);else if(this.#_.find((e=>e.hits(t))))await this.#_.find((e=>e.hits(t))).init(t);else if(await Ee.hits(t))await Ee.init(t);else if(await Pe.hits(t))await Pe.init(t);else if(await De.hits(t))await De.init(t);else if(await Ce.hits(t))await Ce.init(t);else if(await Ne.hits(t))await Ne.init(t);else{if(!await be.hits(t))throw new Error("Undefined step type.");await be.init(t)}}async initNodeTreeIndex({root:e}){const t={};e.indexKey="/";for await(const o of e.childs)await this.initNodeIndex({node:o,index:t});return e.context.index=t,t}async initNodeIndex({node:e,index:t}){const o=i.join(e.parent.indexKey,e.name);e.indexKey=o,t[o]=e;const n=[];let s=e;for(;s?.parent;)n.push(s.index),s=s.parent;n.reverse(),e.codeKey=`B_${n.join("_")}_${e.type}`,e.pathKey=`${n.join(".")}`,e.typeId=j();for await(const o of e.childs)await this.initNodeIndex({node:o,index:t})}async initNodeCalls({root:e}){const t=e.context.index,o=[];for await(const e of Object.keys(t)){const n=t[e];"call"===n.type&&o.push(n)}return e.context.calls=o,o}async initNodeCallLibs({root:e}){const t=[],o=e.context.calls;for await(const e of o){const o=e.definition.import||e.definition.call,n=await this.findNodeCallTarget({refNode:e,curNode:e.parent})||{name:o,type:"atom",definition:e.definition},i=t.find((e=>e.name===n.name&&e.type===n.type));i||t.push(n),e.target=i||n}return e.context.callLibs=t,e.context.libs=[...e.context.libs,...t],t}async findNodeCallTarget({refNode:e,curNode:t}){if(!t)return;const o=e.definition.call,n=t.childs.find((e=>e.name===o&&"subworkflow"===e.type));return n||await this.findNodeCallTarget({refNode:e,curNode:t.parent})}async initNodeForms({root:e}){const t=e.context.index,o=[];for await(const e of Object.keys(t)){const n=t[e];"form"===n.type&&o.push(n)}return e.context.forms=o,o}async initNodeFormLibs({root:e}){const t=[],o=e.context.forms;for await(const e of o){const o=e.definition.import||e.definition.form,n=await this.findNodeCallTarget({refNode:e,curNode:e.parent})||{name:o,type:"atom"},i=t.find((e=>e.name===n.name&&e.type===n.type));i||t.push(n),e.target=i||n}return e.context.formLibs=t,e.context.libs=[...e.context.libs,...t],t}async initFeaturesFromNodes({childs:e,features:t}){for await(const o of e)"form"!==o.type||Reflect.has(t,"form")||(t.form=!0),await this.initFeaturesFromNodes({childs:o.childs,features:t})}async initEntryFiles({root:e,features:t}){for await(const o of e.childs){let e;if("main"===o.name)e="index.js";else if("cli"===o.name)e="cli.js";else if("app"===o.name)e="app.js";else{if("api"!==o.name)continue;e="api.js"}t[`${o.name}_default_entry_file`]=e,o.entryFile=e}}async findNodeFormTarget({refNode:e,curNode:t}){if(!t)return;const o=e.definition.form,n=t.childs.find((e=>e.name===o&&"subworkflow"===e.type));return n||await this.findNodeFormTarget({refNode:e,curNode:t.parent})}async initAtomLibsAndDeps({libs:e,packageDependencies:t}){const o=e.filter((e=>"atom"===e.type));for(let e=0;e<o.length;e++){const n=o[e],i=await this.findAtomLibrary({url:n.name,libRef:n});n.atom=i;const s=i.doc.dependencies?.filter((e=>void 0===e.repo||"npm"===e.repo));s?.forEach((e=>{const o=t.find((t=>t.package===e.package));o?"string"==typeof e.path?(o.path||[]).some((t=>t===e.path))||(o.path=o.path||[],o.path.push(e.path)):Array.isArray(e.path)&&e.path.forEach((e=>{(o.path||[]).some((t=>t===e))||(o.path=o.path||[],o.path.push(e))})):t.push(e)}))}t.sort(((e,t)=>e.package?.localeCompare(t.package)))}async findAtomLibrary({url:e,libRef:t}){const o=O({url:e});if(!o)throw new Error(`Invalid package name: ${e}`);if(o.protocol||(o.protocol=this.#y),"ac:"===o.protocol){const t=o.pathname.split("/");if(1===t.length)return await _.first({where:{name:e,parent_id:this.#g.env.ATOM_LIBRARIES_ID,type:"workflow.lib"}});if(2===t.length){const e=await _.first({where:{name:t[0],parent_id:this.#g.env.ATOM_LIBRARIES_ID,type:"folder"}});return await _.first({where:{name:t[1],parent_id:e.id,type:"workflow.lib"}})}}else{if("local:"===o.protocol){const e=i.resolve(this.#s.projectSrcDir,`${o.pathname}.js`),t=[],n=(await S({file:e,recursive:!0})).all;for await(const e of n){if("npm"!==e.type)continue;if(t.find((t=>t.package===e.package)))continue;const o=await G({name:e.package,projectDir:this.#s.projectDir,setProgress:this.#j.setProgress});t.push({package:e.package,subpath:e.subpath,version:o.minorRange,type:"npm"})}return{name:o.pathname,doc:{type:"workflow.lib","content-type":"javascript",language:"js",dependencies:t},protocol:o.protocol}}if("npm:"===o.protocol){const e=await G({name:o.pathname,projectDir:this.#s.projectDir,setProgress:this.#j.setProgress});return{name:o.pathname,doc:{type:"workflow.lib",subtype:"flow"===t?.definition?.subtype?"workflow":null,"content-type":"javascript",language:"js",dependencies:[{package:o.pathname,version:e.minorRange,type:"npm"}]},protocol:o.protocol}}if("use:"===o.protocol){return{name:o.pathname,doc:{type:"function",dependencies:[]},protocol:o.protocol}}}}async resolveNodeTree({root:e}){for await(const t of e.childs)await this.resolveTypeWorkflow({node:t})}async resolveTypeWorkflow({node:e}){e.context.transform=e.context.transform||x(e.definition);const t=e.context.transform;for(let e=0;e<t.params?.length;e++){const o=t.params[e];if("string"==typeof o)t.params[e]={key:o,hasDefault:!1};else{const n=Object.keys(o)[0];t.params[e]={key:n,hasDefault:!0,default:o[n],type:typeof o[n]}}}e.context.next=e.childs[0];for await(const t of e.childs)await this.resolveType({node:t})}async resolveType({node:e}){const t={...this.#D,node:e};"function"==typeof e.resolve&&await e.resolve(t);for await(const t of e.childs)await this.resolveType({node:t})}async resolveTypeCommon({node:e}){const t=e.context.transform;t.hasOwnProperty("operation")&&(t.operation=await this.transformExpression(t.operation)),t.hasOwnProperty("page")&&(t.page=await this.transformExpression(t.page)),t.hasOwnProperty("print")&&(t.print=await this.transformExpression(t.print)),t.hasOwnProperty("sleep")&&(t.sleep=await this.transformExpression(t.sleep)),t.hasOwnProperty("assert")&&(t.assert=await this.transformExpression(t.assert))}async createAtomLibFiles({root:e}){await this.setProgress({message:"Creating external lib files."}),this.#r.typesDir="./types";const t=e.context.libs.filter((e=>"atom"===e.type));for(let e=0;e<t.length;e++){const n=t[e].atom,s=this.#s.projectDir;if("local:"===n.protocol){const e=i.resolve(this.#s.projectSrcDir,`${n.fileName||n.name}.js`),t=i.relative(`${this.#s.projectDir}/src/default/blocks`,e);if(!o.existsSync(e)){o.mkdirSync(i.dirname(e),{recursive:!0});let t="export default async (args)=>{\n";t+="}",o.writeFileSync(e,t,"utf8")}n.relativePath=t.split(i.sep).join("/"),this.#r.typesDir=`./types/${i.basename(s)}/src`}else if("npm:"===n.protocol)n.relativePath=n.name;else if("use:"===n.protocol);else{const e=`${s}/src/libs/${n.id}.js`,t=n.doc.contents?.find((e=>"esm"===e.format))||n.doc;o.writeFileSync(i.normalize(e),t.content,"utf8")}}}async createEngine({root:e}){await this.setProgress({message:"Creating engine file."});const t=this.#s.templateDir,n=w.compile(o.readFileSync(i.resolve(t,"src/default/engine.js.njk"),"utf8"),this.#c);for(let t=0;t<e.childs.length;t++){const s=e.childs[t];if(!s.entryFile)continue;const r=n.render({flow:s,ui:{package:"@fnet/react-app"}}),a=this.#s.projectDir,c=i.resolve(a,`src/default/${s.entryFile}`);o.writeFileSync(c,r,"utf8")}}async createNodeTree({root:e}){await this.setProgress({message:"Creating block files."});for await(const t of e.childs)await this.createTypeWorkflow({node:t})}async createTypeWorkflow({node:e}){const t=this.#s.templateDir,n=w.compile(o.readFileSync(i.resolve(t,"src/default/workflow.js.njk"),"utf8"),this.#c).render(e),s=this.#s.projectDir,r=i.resolve(s,`src/default/${e.codeKey}.js`);o.writeFileSync(r,n,"utf8");for await(const t of e.childs)await this.createType({node:t})}async createType({node:e}){switch(e.type){case"assign":case"steps":case"return":case"call":case"form":case"raise":case"switch":case"jump":case"tryexcept":case"for":case"operation":case"modules":this.createBlockFromTemplate({node:e})}for await(const t of e.childs)await this.createType({node:t})}createBlockFromTemplate({node:e}){const t=this.getBlockTemplate({node:e});e.context.render=t.render(e),this.createStepFile({node:e})}getBlockTemplate({node:e}){let t=this.#d[e.type];if(t)return t;const n=this.#s.templateDir;return t=w.compile(o.readFileSync(i.resolve(n,`src/default/blocks/${e.type}.js.njk`),"utf8"),this.#c),this.#d[e.type]=t,t}createStepFile({node:e}){const t=this.#s.projectDir,n=`${e.codeKey}.js`,s=i.resolve(t,`src/default/blocks/${n}`);o.writeFileSync(s,e.context.render,"utf8"),e.context.fileName=n,e.context.filePath=s}async transformExpression(e){let t=await this.transformValue(e);return t=JSON.stringify(t),t=this.replaceSpecialPattern(t),t}async transformValue(e){if(Array.isArray(e))for(let t=0;t<e.length;t++)e[t]=await this.transformValue(e[t]);else if(b(e)){const t=Object.keys(e);for(let o=0;o<t.length;o++){const n=t[o],i=K({expression:n});if(i)if("e"===i.processor){const t=e[n].replace(/(\r\n|\n|\r)/g,"");e[i.statement]=`$::${t}::`,delete e[n]}else e[n]=await this.transformValue(e[n]);else e[n]=await this.transformValue(e[n])}}else if("string"==typeof e){const t=K({expression:e});if(t){const{processor:o,statement:n}=t;switch(o){case"v":e=`$::v.${n}::`;break;case"e":e=`$::${n}::`;break;case"m":e=`$::c.module['${n}']::`;break;case"fm":e=`$::flow.getModule('${n}')::`;break;case"f":e=`$::c.form.${n}::`;break;case"for":e=`$::caller.for.${n}::`}}}return e}replaceSpecialPattern(e){return e.replace(/"\$::(.*?)::"/g,"$1")}replaceExpressionLegacy(e){return e.replaceAll(/(?<outer>"\${(?<inner>[^{]*)}")/g,"$2")}async createProjectYaml(){const e="fnet.yaml",t=`Creating ${e}`;await this.setProgress({message:t});const{content:n,...s}=this.#r.doc,r={content:f.stringify(s)},a=this.#s.templateDir,c=w.compile(o.readFileSync(i.resolve(a,`${e}.njk`),"utf8"),this.#c).render(r),p=this.#s.projectDir,l=i.resolve(p,`${e}`);o.writeFileSync(l,c,"utf8")}async createProjectMainYaml(){const e="flow.main.yaml",t=`Creating ${e}`;await this.setProgress({message:t});const n={content:f.stringify(this.#a)},s=this.#s.templateDir,r=w.compile(o.readFileSync(i.resolve(s,`${e}.njk`),"utf8"),this.#c).render(n),a=this.#s.projectDir,c=i.resolve(a,`${e}`);o.writeFileSync(c,r,"utf8")}async runPrettifier(){const e=this.#s.projectDir,t=await m("prettier --write .",{cwd:i.resolve(e,"src")});if(0!==t.code)throw new Error(t.stderr)}async deploy(){if(await this.setProgress({message:"Deploying."}),this.#s.project?.devops){const e=[this.#s.project?.devops];for(let t=0;t<e.length;t++){let o=e[t];await this.deployProject({deploymentProject:o}),!0===o.isDirty&&await o.save()}}else if(this.#r.id){const e=await _.list({type:"workflow.deploy",parent_id:this.#r.id});for(let t=0;t<e.length;t++){let o=e[t];await this.deployProject({deploymentProject:o}),!0===o.isDirty&&(o=await _.update(o,{id:o.id}))}}}async deployProject(e){const{deploymentProject:t}=e,{yamlDocument:o}=t;if(t.doc.targets&&Array.isArray(t.doc.targets))throw new Error("Deployment project targets are deprecated. Please update targets in the yaml file.");const n=Object.keys(t.doc||{}),i=o||{};for(let e=0;e<n.length;e++){const o=t.doc[n[e]];o.name=n[e];const s=i.get(n[e]);await Y({...this.#j,deploymentProject:t,deploymentProjectTarget:o,yamlTarget:s})}}async registerToPackageManager(e){const{target:t,packageJSON:o}=e;if(!this.#s.id)return;let n=await _.first({name:t.params.name,parent_id:this.#g.env.ATOM_PACKAGES_ID});n?(n.doc.versions.splice(0,0,{v:o.version}),await _.update(n,{id:n.id})):n=await _.create({parent_id:this.#g.env.ATOM_PACKAGES_ID,doc:{name:t.params.name,type:"pm",versions:[{v:o.version}]}})}async setProgress(e){const t="string"==typeof e?e:e?.message;console.log(R.blue(t)),await this._cache_set(this.#h,{status:"IN_PROGRESS",message:t})}async build(){if(this.#v&&!this.#x)return await this.createNetwork();try{const e=this.#v?await ie({root:this.#m}):void 0;if(this.#x){if(await this.initWorkflowDir(),await this.initNunjucks(),this.#v){let t=this.#s.project?.projectDir||this.#s.projectDir;t=i.resolve(t,"fnet"),o.existsSync(t)&&o.writeFileSync(i.resolve(t,"flow.bpmn"),e.diagramXML,"utf8")}await this.createAtomLibFiles({root:this.#m}),await this.createEngine({root:this.#m}),await this.createNodeTree({root:this.#m}),await this.createProjectYaml(),await async function({atom:e,context:t,setProgress:n,Atom:s}){const r="readme.md",a=`Creating ${r}`;if(await n({message:a}),t.project?.readme){const e=t.projectDir,n={content:t.project.readme.doc.content},s=i.resolve(t.project.projectDir,"fnet/how-to.md");if(o.existsSync(s)){const e=o.readFileSync(s,"utf8");n.howto=e}const a=i.resolve(t.project.projectDir,"fnet/input.yaml");if(o.existsSync(a)){const e=await u({file:a,tags:t.tags});n.input=e.content}const c=t.templateCommonDir,p=w.compile(o.readFileSync(i.resolve(c,`${r}.njk`),"utf8"),w.configure(c)).render(n),l=i.resolve(e,`${r}`);o.writeFileSync(l,p,"utf8")}else if(e.id){const n=await s.first({type:"wiki",parent_id:e.id});if(!n||"markdown"!==n.doc?.["content-type"])return;const{content:a,...c}=n.doc,p={content:a},l=t.templateCommonDir,d=w.compile(o.readFileSync(i.resolve(l,`${r}.njk`),"utf8"),w.configure(l)).render(p),f=t.projectDir,m=i.resolve(f,`${r}`);o.writeFileSync(m,d,"utf8")}}(this.#j),await async function({atom:e,setProgress:t,context:n,packageDependencies:s}){await t({message:"Creating tsconfig.json."});const r={atom:e,packageDependencies:s},a=n.templateCommonDir,c=w.compile(o.readFileSync(i.resolve(a,"tsconfig.json.njk"),"utf8"),w.configure(a)).render(r),p=n.projectDir,l=i.resolve(p,"tsconfig.json");o.writeFileSync(l,c,"utf8")}(this.#j),await async function({atom:e,setProgress:t,context:n,packageDependencies:s}){await t({message:"Creating .gitignore"});const r={atom:e,packageDependencies:s},a=n.templateCommonDir,c=w.compile(o.readFileSync(i.resolve(a,".gitignore.njk"),"utf8"),w.configure(a)).render(r),p=n.projectDir,l=i.resolve(p,".gitignore");o.writeFileSync(l,c,"utf8")}(this.#j),await async function({atom:e,setProgress:t,context:n,njEnv:s}){if(!0!==e.doc.features.cli.enabled)return;await t({message:"Creating yargs."});let r={};if(r=e.doc.input?e.doc.input:{type:"object",properties:{},required:[]},e.doc.features.cli.fargs&&!1!==e.doc.features.cli.fargs?.enabled){const t=e.doc.features.cli.fargs,o={type:"string",description:"Config name to load args",hidden:!1},n={type:"array",description:"Tags to filter the config",hidden:!1};Reflect.has(t,"default")&&(o.default=t.default),r.properties&&(r.properties.fargs=o,r.properties.ftag=n)}const a={options:r,imports:[],atom:e},c=n.templateDir,p=w.compile(o.readFileSync(i.resolve(c,"src/default/to.args.js.njk"),"utf8"),s).render(a),l=n.projectDir,d=i.resolve(l,"src/default/to.args.js");o.writeFileSync(d,p,"utf8");const f=new T({allErrors:!0,useDefaults:!0,formats:{},strict:!1,code:{esm:!0,lines:!0,optimize:!1,source:!0}});F(f);const m=f.compile(r),u=N(f,m);o.writeFileSync(i.resolve(l,"src/default/validate_input.js"),u,"utf8")}(this.#j),await async function({atom:e,setProgress:t,context:n,packageDependencies:s}){if(!0!==e.doc.features.cli.enabled)return;await t({message:"Creating cli."});const r={atom:e,packageDependencies:s},a=n.templateDir,c=i.resolve(n.projectDir,"src/cli");o.existsSync(c)||o.mkdirSync(c,{recursive:!0}),await g({pattern:["index.js.njk"],dir:i.resolve(a,"src/cli"),outDir:c,context:r})}(this.#j),await async function({atom:e,setProgress:t,context:n,packageDependencies:s}){if(!0!==e.doc.features.app.enabled)return;await t({message:"Creating app folder"});const r={atom:e,packageDependencies:s,ts:Date.now()},a=n.templateDir,c=i.resolve(n.projectDir,"src/app");o.existsSync(c)||o.mkdirSync(c,{recursive:!0});let p=["index.js.njk"];!1!==e.doc.features.app.html&&p.push("index.html.njk"),await g({pattern:p,dir:i.resolve(a,"src/app"),outDir:c,context:r})}(this.#j),await async function({atom:e,setProgress:t,context:n,packageDependencies:s}){await t({message:"Creating rollup file."});const r={atom:e,packageDependencies:s},a=i.resolve(n.projectDir,"src","default/index.js");if(!o.existsSync(a))throw new Error(`Entry file not found: ${a}`);const c=(await S({file:a,recursive:!0})).all.filter((e=>"node"===e.type)).map((e=>e.path)),p=e.doc.features.rollup_output,l=Object.keys(p);for(let e=0;e<l.length;e++){const t=p[l[e]];if(!0===t.browser&&c.length>0){t.globals_enabled=!0,t.globals=t.globals||[],t.globals=t.globals.concat(c.map((e=>({key:e,value:e})))),t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{};for(let e=0;e<c.length;e++){const o=c[e];t.alias.entries[o]=`node:${o}`,t.alias.entries[`node:${o}`]=o}t.external_enabled=!0,t.external=t.external||[],t.external=t.external.concat(c)}}const d=n.templateCommonDir;let f=w.compile(o.readFileSync(i.resolve(d,"rollup.config.mjs.njk"),"utf8"),w.configure(d)).render(r);const m=n.projectDir;let u=i.resolve(m,"rollup.config.mjs");o.writeFileSync(u,f,"utf8")}(this.#j),await async function({atom:e,context:t,packageDependencies:n,packageDevDependencies:s,setProgress:r}){await r({message:"Creating package.json."}),n.filter((e=>!0===e.dev)).forEach((e=>{s.find((t=>t.package===e.package))||s.push(e);const t=n.findIndex((t=>t.package===e.package));n.splice(t,1)}));const a=n.find((e=>"react"===e.package)),c=n.find((e=>"react-dom"===e.package));a&&!c?n.push({package:"react-dom",version:a.version}):a&&c&&(c.version=a.version),a&&e.doc.features.react_version>=17&&(n.find((e=>"@emotion/react"===e.package))||n.push({package:"@emotion/react",version:"^11"}),n.find((e=>"@emotion/styled"===e.package))||n.push({package:"@emotion/styled",version:"^11"}));const p=[];!0===e.doc.features.app.enabled&&p.push({file:i.resolve(t.projectDir,"src/app/index.js"),dev:!1!==e.doc.features.app.dev}),!0===e.doc.features.cli.enabled&&p.push({file:i.resolve(t.projectDir,"src/cli/index.js"),dev:!1!==e.doc.features.cli.dev});for await(const e of p){const i=e.file;if(!o.existsSync(i))throw new Error(`App file not found: ${i}`);const a=(await S({file:i,recursive:!0})).all;for await(const o of a){if("npm"!==o.type)continue;if(n.find((e=>e.package===o.package)))continue;if(s.find((e=>e.package===o.package)))continue;const i=await G({name:o.package,projectDir:t.projectDir,setProgress:r});(!0===e.dev?s:n).push({package:o.package,subpath:o.subpath,version:i.minorRange,type:"npm"})}}const l={atom:e,packageDependencies:n,packageDevDependencies:s},d=t.templateCommonDir,f=w.compile(o.readFileSync(i.resolve(d,"package.json.njk"),"utf8"),w.configure(d)).render(l),m=t.projectDir,u=i.resolve(m,"package.json");o.writeFileSync(u,f,"utf8");const h=i.resolve(t.project.projectDir,"fnet");if(o.existsSync(h)){const e=i.resolve(t.projectDir,"fnet");o.existsSync(e)||o.mkdirSync(e);const n=o.readdirSync(h);for(const t of n){const n=i.resolve(h,t);if(!o.lstatSync(n).isFile())continue;const s=i.resolve(e,t);o.copyFileSync(n,s)}}}(this.#j),await async function({setProgress:e,context:t}){const o=t.projectDir;await e({message:"Prettifiying source files."});let n=A.join("src","**","*");await y({commands:{steps:[`prettier --write ${n} *.{js,cjs,mjs,json,yaml,html} --no-error-on-unmatched-pattern`],wdir:o}})}(this.#j),await async function({atom:e,setProgress:t,context:o}){if(!e.doc.features.dts_enabled)return;const n=o.projectDir;if(await t({message:"Creating .d.ts"}),0!==(await m("tsc",{cwd:n})).code)throw new Error("Couldnt create .d.ts files.")}(this.#j),this.#b&&(await async function({setProgress:e,atom:t,context:o}){const n=o.projectDir;await e({message:"Installing npm packages."});const i=q("bun")?"bun":"npm";if(0!==(await m(`${i} install ${t.doc.features.npm_install_flags}`,{cwd:n})).code)throw new Error("Couldnt install npm packages.")}(this.#j),await async function({setProgress:e,context:t}){const o=t.projectDir;if(await e({message:"Building main project."}),0!==(await m("npm run build",{cwd:o})).code)throw new Error("Couldnt build project.")}(this.#j),this.#k&&await this.deploy())}await this._cache_set(this.#h,{status:"COMPLETED",data:{network:e}})}catch(e){throw await this._cache_set(this.#h,{status:"FAILED",message:e.message||e}),e}}async createNetwork(){try{const e=await ie({root:this.#m});await this._cache_set(this.#h,{status:"COMPLETED",data:{...e}})}catch(e){throw await this._cache_set(this.#h,{status:"FAILED",message:e.message||e}),e}}}const Be=i.dirname(c(import.meta.url));const Ke=i.dirname(c(import.meta.url)),Re=process.cwd();a({name:["redis"],dir:Re,optional:!0});const Me=function({baseDir:e}){let t=e=e||Be;for(;t!==i.parse(t).root;){const e=i.join(t,"node_modules");if(o.existsSync(e))return e;t=i.dirname(t)}return null}({baseDir:Ke}),Je="win32"===process.platform?";":":";Me&&(process.env.PATH=`${i.join(Me,"/.bin")}${Je}${process.env.PATH}`);const Le=new p;function ze(t,{name:o,bin:n,preArgs:i=[]}){const s=o||n;t.command(s,{isDefault:!1,hidden:!1}).description(`Run ${n} ${i.join(" ")} in project context. Pass arguments directly after command name.`).argument("[command_args...]",`Arguments for ${n}`).allowUnknownOption().action((async(t,o)=>{try{const s=await qe(o),r=s?.projectDir&&d.existsSync(s.projectDir)?s.projectDir:s?.project?.projectDir&&d.existsSync(s.project.projectDir)?s.project.projectDir:Re,a=t,c=e(n,[...i,...a],{cwd:r,stdio:"inherit",shell:!0});c.on("close",(e=>{void 0===process.exitCode&&process.exit(e)})),c.on("error",(e=>{console.error(`Failed to start ${n}:`,e),void 0===process.exitCode&&process.exit(1)}))}catch(e){console.error(`Error setting up context for ${s}:`,e.message),void 0===process.exitCode&&process.exit(1)}}))}async function qe(e){const t=e.ftag||[];if(e.id)return{id:e.id,buildId:e.buildId,mode:e.mode,protocol:e.protocol||"ac:",projectDir:i.resolve(Re,`./.output/${e.id}`),templateDir:i.resolve(Me,"@fnet/cli-project-flow/dist/template/default"),templateCommonDir:i.resolve(Me,"@fnet/cli-project-common/dist/template/default"),coreDir:i.resolve(Me,"@fnet/cli-project-flow/dist/template/core"),tags:t};{const o=await async function({tags:e=[]}){const t=i.resolve(Re,"fnet.yaml");if(!d.existsSync(t))throw new Error("fnet.yaml file not found in current directory.");const o=Array.isArray(e)?e:e?[e]:[],{raw:n,parsed:s}=await u({file:t,tags:o}),r=i.dirname(t);let a={};if("object"==typeof s.flows&&null!==s.flows)a=s.flows;else{let e="flow.main.yaml";const t=i.join(r,"fnet","flows.yaml");d.existsSync(t)&&(e=i.join("fnet","flows.yaml"));const n=s.main||e;let c=i.resolve(r,n);if(d.existsSync(c))try{const{parsed:e}=await u({file:c,tags:o});a=e}catch(e){throw console.error(`Error parsing flow file: ${c}`),e}else s.main&&console.warn(`Warning: Main flow file specified in fnet.yaml (${n}) not found.`),a={main:{steps:[]}}}const c={workflowAtom:{doc:{...s,content:a}},projectDir:r,projectFilePath:t,projectFileContent:n,projectFileParsed:s};let p=i.resolve(r,"fnet/targets.yaml");const l=i.resolve(r,"flow.devops.yaml");if(!d.existsSync(p)&&d.existsSync(l)){console.log(`Migrating legacy devops file: ${l}`);try{const e=i.resolve(r,"fnet");d.existsSync(e)||d.mkdirSync(e),d.copyFileSync(l,p),d.unlinkSync(l),console.log(`Successfully migrated to ${p}`)}catch(e){console.error(`Error migrating devops file: ${e.message}`)}}if(d.existsSync(p))try{const{raw:e,parsed:t}=await u({file:p,tags:o}),n=f.parseDocument(e);c.devops={filePath:p,fileContent:e,yamlDocument:n,doc:{...t},type:"workflow.deploy",save:async()=>{d.writeFileSync(c.devops.filePath,n.toString())}}}catch(e){console.error(`Error loading or parsing devops file: ${p}`)}const m=i.resolve(r,"readme.md");if(d.existsSync(m)){const e=d.readFileSync(m,"utf8");c.readme={filePath:m,fileContent:e,doc:{content:e,"content-type":"markdown"},type:"wiki"}}return c}({tags:t});return{buildId:e.buildId,mode:e.mode,protocol:e.protocol||"local:",templateDir:i.resolve(Me,"@fnet/cli-project-flow/dist/template/default"),templateCommonDir:i.resolve(Me,"@fnet/cli-project-common/dist/template/default"),coreDir:i.resolve(Me,"@fnet/cli-project-flow/dist/template/core"),projectDir:i.resolve(o.projectDir,"./.workspace"),projectSrcDir:i.resolve(o.projectDir,"./src"),project:o,tags:t}}}Le.name("fnet").version(W).description("CLI tool for FlowNet workflow projects"),Le.command("create").description("Initialize flow workflow project").requiredOption("-n, --name <string>","Project name").addOption(new l("-r, --runtime <type>","Runtime environment (currently only node)").choices(["node"]).default("node")).option("--vscode","Open project in VSCode after creation",!0).option("--no-vscode","Do not open project in VSCode").action((async e=>{try{const t=i.resolve(Me,"@fnet/cli-project-flow/dist/template/project"),o=i.resolve(Re,e.name);d.existsSync(o)||d.mkdirSync(o),await g({dir:t,outDir:o,context:e,copyUnmatchedAlso:!0});let n=await m("fnet build",{cwd:o});if(0!==n.code)throw new Error("Failed to build project.");if(q("git")&&(n=await m("git init --initial-branch=main",{cwd:o}),0!==n.code))throw new Error("Failed to initialize git.");if(e.vscode&&q("code")&&(n=await m(`cd ${o} && code .`),0!==n.code))throw new Error("Failed to open vscode.");console.log("Creating project succeeded!"),process.exit(0)}catch(e){console.error("Initialization failed!",e.message),process.exit(1)}})),Le.command("project").description("Flow workflow project operations").option("-u, --update","Update project files from template",!1).action((async e=>{try{const t=i.resolve(Me,"@fnet/cli-project-flow/dist/template/project"),o=process.cwd(),n=await qe(e);if(e.update){if(await g({dir:t,outDir:o,context:{name:n.project.projectFileParsed.name,runtime:"node"},copyUnmatchedAlso:!0}),0!==(await m("fnet build",{cwd:o})).code)throw new Error("Failed to build project.");console.log("Updating project succeeded!")}else console.log("Use 'fnet project --update' to update project files.");process.exit(0)}catch(e){console.error("Project command failed.",e.message),process.exit(1)}})),Le.command("build").description("Build flownet workflow project").option("--id <string>","Build identifier").option("--buildId <string>","Specific build ID").addOption(new l("--mode <mode>","Build mode").choices(["all","file","build","deploy","bpmn"]).default("build")).option("--ftag <tags...>","Filter tags (specify multiple times or space-separated)").action((async e=>{try{const t=await qe(e),o=new Ie(t);await o.init(),await o.build(),console.log("Building workflow succeeded!"),process.exit(0)}catch(e){console.error("Building workflow failed!",e.message),process.exit(1)}})),Le.command("deploy").description("Build and deploy flownet workflow project").option("--id <string>","Build identifier").option("--buildId <string>","Specific build ID").option("--ftag <tags...>","Filter tags").action((async e=>{try{const t=await qe({...e,mode:"all"}),o=new Ie(t);await o.init(),await o.build(),console.log("Building and deploying workflow succeeded!"),process.exit(0)}catch(e){console.error("Building/deploying workflow failed!",e.message),process.exit(1)}})),Le.command("file").description("Just create files (part of workflow build)").option("--id <string>","Build identifier").option("--buildId <string>","Specific build ID").option("--ftag <tags...>","Filter tags").action((async e=>{try{const t=await qe({...e,mode:"file"}),o=new Ie(t);await o.init(),await o.build(),console.log("Creating workflow files succeeded!"),process.exit(0)}catch(e){console.error("Creating workflow files failed!",e.message),process.exit(1)}})),Le.command("input").description("Create or modify an input config file").argument("[name]","Optional input configuration name (e.g., dev, prod)").action((async(e,o)=>{try{const n=await qe({...o,name:e}),{project:s}=n,{projectDir:r,projectFileParsed:a}=s,c=a.input;if(!c)throw new Error("Config schema `input` not found in project file (fnet.yaml).");let p=e;if(!p){p=(await t({type:"input",name:"inputName",message:"Input name:",initial:"dev"})).inputName,p||(console.error("Input name cannot be empty."),process.exit(1))}const l=i.resolve(r,".fnet");d.existsSync(l)||d.mkdirSync(l);const f=i.resolve(l,`${p}.fnet`),m=d.existsSync(f),u=await h({schema:c,format:"yaml",ref:m?f:void 0});d.writeFileSync(f,u),console.log(`Input config '${p}.fnet' ${m?"updated":"created"}.`)}catch(e){console.error(e.message),process.exit(1)}})),ze(Le,{bin:"npm"}),ze(Le,{bin:"node"}),ze(Le,{bin:"bun"}),ze(Le,{name:"serve",bin:"npm",preArgs:["run","serve"]}),ze(Le,{name:"watch",bin:"npm",preArgs:["run","watch"]}),ze(Le,{name:"app",bin:"npm",preArgs:["run","app"]}),ze(Le,{name:"cli",bin:"npm",preArgs:["run","cli"]}),ze(Le,{bin:"npx"}),ze(Le,{bin:"cdk"}),ze(Le,{bin:"aws"}),function(t,{name:o,preArgs:n=[]}){t.command(o).description("Run a command with environment variables from a .fnet config file.").argument("<config>","Name of the .fnet config file (without extension)").argument("<command>","The command to execute").argument("[command_args...]","Arguments for the command").option("--ftag <tags...>","Filter tags for loading config").allowUnknownOption().action((async(t,i,s,r)=>{try{const o=await qe(r),c=o?.project?.projectDir&&d.existsSync(o.project.projectDir)?o.project.projectDir:Re,p=await a({name:t,dir:c,transferEnv:!1,optional:!0,tags:o?.tags||r.ftag||[]}),l=p?.data?.env||{},f=o?.projectDir&&d.existsSync(o.projectDir)?o.projectDir:c,m=e(i,[...n,...s],{cwd:f,stdio:"inherit",shell:!0,env:{...process.env,...l}});m.on("close",(e=>{void 0===process.exitCode&&process.exit(e)})),m.on("error",(e=>{"ENOENT"===e.code?console.error(`Error: Command not found: '${i}'. Is it installed or in your PATH?`):console.error(`Failed to start command '${i}':`,e),void 0===process.exitCode&&process.exit(1)}))}catch(e){console.error(`Error setting up context or running command for '${o}': ${e.message}`),void 0===process.exitCode&&process.exit(1)}}))}(Le,{name:"with"}),function(e,{name:t,preArgs:o=[]}){e.command(t).description("Run a command group defined in fnet.yaml.").argument("<group>","Name of the command group in fnet.yaml commands section").option("--ftag <tags...>","Filter tags for loading project config").action((async(e,t)=>{try{const o=await qe(t);if(!o||!o.project||!o.project.projectFileParsed)throw new Error("Could not load project context. Are you in a fnet project directory?");const{projectFileParsed:n}=o.project,i=n.commands;if(!i)throw new Error("`commands` section not found in project file (fnet.yaml).");const s=i[e];if(!s)throw new Error(`Command group '${e}' not found in project file.`);await y({commands:s}),void 0===process.exitCode&&process.exit(0)}catch(t){console.error(`Error running command group '${e}':`,t.message),void 0===process.exitCode&&process.exit(1)}}))}(Le,{name:"run"}),Le.parse(process.argv),process.argv.slice(2).length||Le.outputHelp();export{q as w};