@rglabs/butterfly 1.0.0

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 (136) hide show
  1. package/.claude/settings.local.json +25 -0
  2. package/dist/commands/add.d.ts +21 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +301 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/download.d.ts +4 -0
  7. package/dist/commands/download.d.ts.map +1 -0
  8. package/dist/commands/download.js +309 -0
  9. package/dist/commands/download.js.map +1 -0
  10. package/dist/commands/setup.d.ts +3 -0
  11. package/dist/commands/setup.d.ts.map +1 -0
  12. package/dist/commands/setup.js +41 -0
  13. package/dist/commands/setup.js.map +1 -0
  14. package/dist/commands/start/handlers/aiTasks.d.ts +4 -0
  15. package/dist/commands/start/handlers/aiTasks.d.ts.map +1 -0
  16. package/dist/commands/start/handlers/aiTasks.js +95 -0
  17. package/dist/commands/start/handlers/aiTasks.js.map +1 -0
  18. package/dist/commands/start/handlers/cronjobs.d.ts +4 -0
  19. package/dist/commands/start/handlers/cronjobs.d.ts.map +1 -0
  20. package/dist/commands/start/handlers/cronjobs.js +80 -0
  21. package/dist/commands/start/handlers/cronjobs.js.map +1 -0
  22. package/dist/commands/start/handlers/emailLayouts.d.ts +4 -0
  23. package/dist/commands/start/handlers/emailLayouts.d.ts.map +1 -0
  24. package/dist/commands/start/handlers/emailLayouts.js +83 -0
  25. package/dist/commands/start/handlers/emailLayouts.js.map +1 -0
  26. package/dist/commands/start/handlers/emailTemplates.d.ts +4 -0
  27. package/dist/commands/start/handlers/emailTemplates.d.ts.map +1 -0
  28. package/dist/commands/start/handlers/emailTemplates.js +83 -0
  29. package/dist/commands/start/handlers/emailTemplates.js.map +1 -0
  30. package/dist/commands/start/handlers/index.d.ts +11 -0
  31. package/dist/commands/start/handlers/index.d.ts.map +1 -0
  32. package/dist/commands/start/handlers/index.js +11 -0
  33. package/dist/commands/start/handlers/index.js.map +1 -0
  34. package/dist/commands/start/handlers/objects.d.ts +8 -0
  35. package/dist/commands/start/handlers/objects.d.ts.map +1 -0
  36. package/dist/commands/start/handlers/objects.js +205 -0
  37. package/dist/commands/start/handlers/objects.js.map +1 -0
  38. package/dist/commands/start/handlers/pages.d.ts +4 -0
  39. package/dist/commands/start/handlers/pages.d.ts.map +1 -0
  40. package/dist/commands/start/handlers/pages.js +86 -0
  41. package/dist/commands/start/handlers/pages.js.map +1 -0
  42. package/dist/commands/start/handlers/pdfTemplates.d.ts +4 -0
  43. package/dist/commands/start/handlers/pdfTemplates.d.ts.map +1 -0
  44. package/dist/commands/start/handlers/pdfTemplates.js +81 -0
  45. package/dist/commands/start/handlers/pdfTemplates.js.map +1 -0
  46. package/dist/commands/start/handlers/reports.d.ts +4 -0
  47. package/dist/commands/start/handlers/reports.d.ts.map +1 -0
  48. package/dist/commands/start/handlers/reports.js +159 -0
  49. package/dist/commands/start/handlers/reports.js.map +1 -0
  50. package/dist/commands/start/handlers/stateMachines.d.ts +4 -0
  51. package/dist/commands/start/handlers/stateMachines.d.ts.map +1 -0
  52. package/dist/commands/start/handlers/stateMachines.js +549 -0
  53. package/dist/commands/start/handlers/stateMachines.js.map +1 -0
  54. package/dist/commands/start/handlers/workflows.d.ts +5 -0
  55. package/dist/commands/start/handlers/workflows.d.ts.map +1 -0
  56. package/dist/commands/start/handlers/workflows.js +277 -0
  57. package/dist/commands/start/handlers/workflows.js.map +1 -0
  58. package/dist/commands/start/index.d.ts +5 -0
  59. package/dist/commands/start/index.d.ts.map +1 -0
  60. package/dist/commands/start/index.js +304 -0
  61. package/dist/commands/start/index.js.map +1 -0
  62. package/dist/commands/start/types.d.ts +25 -0
  63. package/dist/commands/start/types.d.ts.map +1 -0
  64. package/dist/commands/start/types.js +2 -0
  65. package/dist/commands/start/types.js.map +1 -0
  66. package/dist/commands/start/utils.d.ts +10 -0
  67. package/dist/commands/start/utils.d.ts.map +1 -0
  68. package/dist/commands/start/utils.js +191 -0
  69. package/dist/commands/start/utils.js.map +1 -0
  70. package/dist/commands/start.d.ts +2 -0
  71. package/dist/commands/start.d.ts.map +1 -0
  72. package/dist/commands/start.js +2 -0
  73. package/dist/commands/start.js.map +1 -0
  74. package/dist/commands/upload.d.ts +3 -0
  75. package/dist/commands/upload.d.ts.map +1 -0
  76. package/dist/commands/upload.js +115 -0
  77. package/dist/commands/upload.js.map +1 -0
  78. package/dist/commands/workflow-info.d.ts +11 -0
  79. package/dist/commands/workflow-info.d.ts.map +1 -0
  80. package/dist/commands/workflow-info.js +159 -0
  81. package/dist/commands/workflow-info.js.map +1 -0
  82. package/dist/components/DownloadProgress.d.ts +11 -0
  83. package/dist/components/DownloadProgress.d.ts.map +1 -0
  84. package/dist/components/DownloadProgress.js +29 -0
  85. package/dist/components/DownloadProgress.js.map +1 -0
  86. package/dist/components/SetupForm.d.ts +8 -0
  87. package/dist/components/SetupForm.d.ts.map +1 -0
  88. package/dist/components/SetupForm.js +56 -0
  89. package/dist/components/SetupForm.js.map +1 -0
  90. package/dist/components/UploadProgress.d.ts +11 -0
  91. package/dist/components/UploadProgress.d.ts.map +1 -0
  92. package/dist/components/UploadProgress.js +29 -0
  93. package/dist/components/UploadProgress.js.map +1 -0
  94. package/dist/index.d.ts +3 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +63 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/types/index.d.ts +18 -0
  99. package/dist/types/index.d.ts.map +1 -0
  100. package/dist/types/index.js +2 -0
  101. package/dist/types/index.js.map +1 -0
  102. package/dist/utils/api.d.ts +47 -0
  103. package/dist/utils/api.d.ts.map +1 -0
  104. package/dist/utils/api.js +676 -0
  105. package/dist/utils/api.js.map +1 -0
  106. package/dist/utils/auth.d.ts +4 -0
  107. package/dist/utils/auth.d.ts.map +1 -0
  108. package/dist/utils/auth.js +22 -0
  109. package/dist/utils/auth.js.map +1 -0
  110. package/dist/utils/docs.d.ts +2 -0
  111. package/dist/utils/docs.d.ts.map +1 -0
  112. package/dist/utils/docs.js +41 -0
  113. package/dist/utils/docs.js.map +1 -0
  114. package/dist/utils/errorLogger.d.ts +6 -0
  115. package/dist/utils/errorLogger.d.ts.map +1 -0
  116. package/dist/utils/errorLogger.js +29 -0
  117. package/dist/utils/errorLogger.js.map +1 -0
  118. package/dist/utils/files.d.ts +14 -0
  119. package/dist/utils/files.d.ts.map +1 -0
  120. package/dist/utils/files.js +732 -0
  121. package/dist/utils/files.js.map +1 -0
  122. package/dist/utils/lockManager.d.ts +15 -0
  123. package/dist/utils/lockManager.d.ts.map +1 -0
  124. package/dist/utils/lockManager.js +126 -0
  125. package/dist/utils/lockManager.js.map +1 -0
  126. package/dist/utils/summaryGenerator.d.ts +2 -0
  127. package/dist/utils/summaryGenerator.d.ts.map +1 -0
  128. package/dist/utils/summaryGenerator.js +183 -0
  129. package/dist/utils/summaryGenerator.js.map +1 -0
  130. package/dist/utils/uploadHandler.d.ts +35 -0
  131. package/dist/utils/uploadHandler.d.ts.map +1 -0
  132. package/dist/utils/uploadHandler.js +706 -0
  133. package/dist/utils/uploadHandler.js.map +1 -0
  134. package/object_response.png +0 -0
  135. package/object_specs_response.png +0 -0
  136. package/package.json +56 -0
@@ -0,0 +1,732 @@
1
+ import { promises as fs } from 'fs';
2
+ import { join } from 'path';
3
+ import { stringify as yamlStringify } from 'yaml';
4
+ const TABLE_CONFIGS = {
5
+ pages: {
6
+ folderNameField: 'link',
7
+ codeFields: [
8
+ { field: 'page_code', filename: 'page_code', extension: 'bfy' }
9
+ ],
10
+ hasSpecs: false
11
+ },
12
+ bfy_ai_tasks: {
13
+ folderNameField: 'system_name',
14
+ codeFields: [
15
+ { field: 'prompt', filename: 'prompt', extension: 'bfy' },
16
+ { field: 'output_format', filename: 'output_format', extension: 'json' },
17
+ { field: 'system_message', filename: 'system_message', extension: 'bfy' },
18
+ { field: 'action_code', filename: 'action_code', extension: 'bfy' },
19
+ { field: 'action_preview_code', filename: 'action_preview_code', extension: 'bfy' },
20
+ { field: 'initial_code', filename: 'initial_code', extension: 'bfy' }
21
+ ],
22
+ hasSpecs: false
23
+ },
24
+ objects: {
25
+ folderNameField: 'table_name',
26
+ codeFields: [
27
+ { field: 'listing_query', filename: 'listing_query', extension: 'bfy' }
28
+ ],
29
+ hasSpecs: true,
30
+ specsTable: 'object_specs',
31
+ specsForeignKey: 'object_id'
32
+ },
33
+ bfy_state_machines: {
34
+ folderNameField: 'name',
35
+ hasSpecs: false
36
+ },
37
+ bfy_state_machine_states: {
38
+ folderNameField: 'system_name',
39
+ hasSpecs: false
40
+ },
41
+ bfy_state_machine_roles: {
42
+ folderNameField: 'name',
43
+ codeFields: [
44
+ { field: 'validation_code', filename: 'validation_code', extension: 'bfy' }
45
+ ],
46
+ hasSpecs: false
47
+ },
48
+ bfy_state_machine_transitions: {
49
+ folderNameField: 'transition_system_name',
50
+ codeFields: [
51
+ { field: 'action_code', filename: 'action_code', extension: 'bfy' },
52
+ { field: 'validation_code', filename: 'validation_code', extension: 'bfy' }
53
+ ],
54
+ hasSpecs: true,
55
+ specsTable: 'bfy_state_machine_transition_specs',
56
+ specsForeignKey: 'bfy_state_machine_transition_id'
57
+ },
58
+ bfy_sm_actions: {
59
+ folderNameField: 'name',
60
+ codeFields: [
61
+ { field: 'code', filename: 'code', extension: 'bfy' }
62
+ ],
63
+ hasSpecs: true,
64
+ specsTable: 'bfy_sm_action_specs',
65
+ specsForeignKey: 'bfy_sm_action_id'
66
+ },
67
+ bfy_cronjobs: {
68
+ folderNameField: 'name',
69
+ codeFields: [
70
+ { field: 'code', filename: 'code', extension: 'bfy' }
71
+ ],
72
+ hasSpecs: false
73
+ },
74
+ cms_email_templates: {
75
+ folderNameField: 'system_name',
76
+ codeFields: [
77
+ { field: 'subject', filename: 'subject', extension: 'bfy' },
78
+ { field: 'content', filename: 'content', extension: 'bfy' }
79
+ ],
80
+ hasSpecs: false
81
+ },
82
+ pdf_templates: {
83
+ folderNameField: 'system_name',
84
+ codeFields: [
85
+ { field: 'template', filename: 'template', extension: 'bfy' }
86
+ ],
87
+ hasSpecs: false
88
+ },
89
+ cms_email_layouts: {
90
+ folderNameField: 'name',
91
+ codeFields: [
92
+ { field: 'layout_html', filename: 'layout_html', extension: 'bfy' },
93
+ { field: 'layout_text', filename: 'layout_text', extension: 'bfy' }
94
+ ],
95
+ hasSpecs: false
96
+ },
97
+ bfy_workflows: {
98
+ folderNameField: 'name',
99
+ hasSpecs: false
100
+ },
101
+ bfy_workflow_versions: {
102
+ folderNameField: 'version_number',
103
+ hasSpecs: false
104
+ },
105
+ bfy_workflow_nodes: {
106
+ folderNameField: 'name',
107
+ codeFields: [
108
+ { field: 'code', filename: 'code', extension: 'bfy' }
109
+ ],
110
+ hasSpecs: false
111
+ }
112
+ };
113
+ export async function cleanupDirectory(dirPath) {
114
+ try {
115
+ await fs.rm(dirPath, { recursive: true, force: true });
116
+ }
117
+ catch (error) {
118
+ }
119
+ }
120
+ export async function saveResource(outputPath, resourceType, resourceName, data) {
121
+ const dir = join(outputPath, resourceType);
122
+ await fs.mkdir(dir, { recursive: true });
123
+ const filePath = join(dir, `${resourceName}.json`);
124
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2));
125
+ }
126
+ function getAiTaskFieldMappings() {
127
+ return [
128
+ { field: 'prompt', filename: 'prompt', extension: 'bfy' },
129
+ { field: 'output_format', filename: 'output_format', extension: 'json' },
130
+ { field: 'system_message', filename: 'system_message', extension: 'bfy' },
131
+ { field: 'action_code', filename: 'action_code', extension: 'bfy' },
132
+ { field: 'action_preview_code', filename: 'action_preview_code', extension: 'bfy' },
133
+ { field: 'initial_code', filename: 'initial_code', extension: 'bfy' }
134
+ ];
135
+ }
136
+ export async function saveAiTask(outputPath, aiTask) {
137
+ const folderName = aiTask.system_name || aiTask.name || aiTask.id || `ai-task-${aiTask.id}`;
138
+ const taskDir = join(outputPath, 'bfy_ai_tasks', folderName);
139
+ await fs.mkdir(taskDir, { recursive: true });
140
+ const mappings = getAiTaskFieldMappings();
141
+ const strippedTask = { ...aiTask };
142
+ for (const mapping of mappings) {
143
+ const content = aiTask[mapping.field];
144
+ if (content) {
145
+ const filePath = join(taskDir, `${mapping.filename}.${mapping.extension}`);
146
+ await fs.writeFile(filePath, typeof content === 'string' ? content : JSON.stringify(content, null, 2));
147
+ delete strippedTask[mapping.field];
148
+ }
149
+ }
150
+ const taskFile = join(taskDir, 'task.json');
151
+ await fs.writeFile(taskFile, JSON.stringify(strippedTask, null, 2));
152
+ }
153
+ export async function restoreTableRecordFromFiles(recordDir, tableName, recordData) {
154
+ const restored = { ...recordData };
155
+ const config = TABLE_CONFIGS[tableName] || {};
156
+ try {
157
+ if (config.codeFields) {
158
+ for (const codeField of config.codeFields) {
159
+ const codePath = join(recordDir, `${codeField.filename}.${codeField.extension}`);
160
+ try {
161
+ const content = await fs.readFile(codePath, 'utf-8');
162
+ restored[codeField.field] = content;
163
+ }
164
+ catch {
165
+ }
166
+ }
167
+ }
168
+ }
169
+ catch (err) {
170
+ return recordData;
171
+ }
172
+ return restored;
173
+ }
174
+ export async function restorePageFromFiles(pageDir, pageData) {
175
+ return restoreTableRecordFromFiles(pageDir, 'pages', pageData);
176
+ }
177
+ export async function restoreAiTaskFromFiles(taskDir, taskData) {
178
+ const restored = { ...taskData };
179
+ const mappings = getAiTaskFieldMappings();
180
+ try {
181
+ for (const mapping of mappings) {
182
+ const filePath = join(taskDir, `${mapping.filename}.${mapping.extension}`);
183
+ try {
184
+ const content = await fs.readFile(filePath, 'utf-8');
185
+ if (mapping.extension === 'json') {
186
+ restored[mapping.field] = JSON.parse(content);
187
+ }
188
+ else {
189
+ restored[mapping.field] = content;
190
+ }
191
+ }
192
+ catch {
193
+ }
194
+ }
195
+ }
196
+ catch (err) {
197
+ return taskData;
198
+ }
199
+ return restored;
200
+ }
201
+ function getFieldMapping(spec) {
202
+ const mappings = [];
203
+ const type = spec.type;
204
+ if (spec.listing_query) {
205
+ mappings.push({ filename: 'listing_query', extension: 'bfy' });
206
+ }
207
+ if (spec.js_code) {
208
+ mappings.push({ filename: 'code', extension: 'js' });
209
+ }
210
+ if (spec.css_code) {
211
+ mappings.push({ filename: 'style', extension: 'css' });
212
+ }
213
+ switch (type) {
214
+ case 'calculated':
215
+ if (spec.val_1)
216
+ mappings.push({ filename: 'code', extension: 'bfy' });
217
+ break;
218
+ case 'custom':
219
+ if (spec.val_1)
220
+ mappings.push({ filename: 'template_code', extension: 'bfy' });
221
+ if (spec.val_2)
222
+ mappings.push({ filename: 'processing_code', extension: 'bfy' });
223
+ break;
224
+ case 'filter':
225
+ if (spec.val_3)
226
+ mappings.push({ filename: 'filter_code', extension: 'bfy' });
227
+ break;
228
+ case 'nested':
229
+ case 'nested_single':
230
+ if (spec.val_1)
231
+ mappings.push({ filename: 'configuration', extension: 'yaml' });
232
+ break;
233
+ }
234
+ return mappings;
235
+ }
236
+ function stripExportedFields(data, mappings) {
237
+ const stripped = { ...data };
238
+ for (const mapping of mappings) {
239
+ const filename = mapping.filename;
240
+ switch (filename) {
241
+ case 'listing_query':
242
+ delete stripped.listing_query;
243
+ break;
244
+ case 'code':
245
+ if (mapping.extension === 'js') {
246
+ delete stripped.js_code;
247
+ }
248
+ else if (mapping.extension === 'bfy') {
249
+ delete stripped.val_1;
250
+ }
251
+ break;
252
+ case 'style':
253
+ delete stripped.css_code;
254
+ break;
255
+ case 'configuration':
256
+ delete stripped.val_1;
257
+ break;
258
+ case 'template_code':
259
+ delete stripped.val_1;
260
+ break;
261
+ case 'processing_code':
262
+ delete stripped.val_2;
263
+ break;
264
+ case 'filter_code':
265
+ delete stripped.val_3;
266
+ break;
267
+ }
268
+ }
269
+ return stripped;
270
+ }
271
+ export async function restoreFieldsFromFiles(baseDir, data) {
272
+ const restored = { ...data };
273
+ try {
274
+ const listingQueryPath = join(baseDir, 'listing_query.bfy');
275
+ try {
276
+ const content = await fs.readFile(listingQueryPath, 'utf-8');
277
+ restored.listing_query = content;
278
+ }
279
+ catch {
280
+ }
281
+ if (data.type) {
282
+ const mappings = getFieldMapping(data);
283
+ for (const mapping of mappings) {
284
+ const filePath = join(baseDir, `${mapping.filename}.${mapping.extension}`);
285
+ try {
286
+ const content = await fs.readFile(filePath, 'utf-8');
287
+ switch (mapping.filename) {
288
+ case 'listing_query':
289
+ restored.listing_query = content;
290
+ break;
291
+ case 'code':
292
+ if (mapping.extension === 'js') {
293
+ restored.js_code = content;
294
+ }
295
+ else if (mapping.extension === 'bfy') {
296
+ restored.val_1 = content;
297
+ }
298
+ break;
299
+ case 'style':
300
+ restored.css_code = content;
301
+ break;
302
+ case 'configuration':
303
+ restored.val_1 = content;
304
+ break;
305
+ case 'template_code':
306
+ restored.val_1 = content;
307
+ break;
308
+ case 'processing_code':
309
+ restored.val_2 = content;
310
+ break;
311
+ case 'filter_code':
312
+ restored.val_3 = content;
313
+ break;
314
+ }
315
+ }
316
+ catch {
317
+ }
318
+ }
319
+ }
320
+ if (!data.type && data.alias !== undefined) {
321
+ const mainQueryPath = join(baseDir, 'main_query.bfy');
322
+ try {
323
+ const content = await fs.readFile(mainQueryPath, 'utf-8');
324
+ restored.query = content;
325
+ }
326
+ catch {
327
+ }
328
+ }
329
+ if (data.name !== undefined && data.system_name !== undefined) {
330
+ const queryCodePath = join(baseDir, 'query_code.bfy');
331
+ try {
332
+ const content = await fs.readFile(queryCodePath, 'utf-8');
333
+ restored.query = content;
334
+ }
335
+ catch {
336
+ }
337
+ const scriptPath = join(baseDir, 'script.js');
338
+ try {
339
+ const content = await fs.readFile(scriptPath, 'utf-8');
340
+ restored.js_code = content;
341
+ }
342
+ catch {
343
+ }
344
+ }
345
+ if (data.field_name !== undefined) {
346
+ const codePath = join(baseDir, 'code.js');
347
+ try {
348
+ const content = await fs.readFile(codePath, 'utf-8');
349
+ restored.js_code = content;
350
+ }
351
+ catch {
352
+ }
353
+ }
354
+ }
355
+ catch (err) {
356
+ return data;
357
+ }
358
+ return restored;
359
+ }
360
+ async function exportSpecFiles(specDir, spec) {
361
+ const mappings = getFieldMapping(spec);
362
+ for (const mapping of mappings) {
363
+ let content = '';
364
+ const filename = mapping.filename;
365
+ switch (filename) {
366
+ case 'listing_query':
367
+ content = spec.listing_query || '';
368
+ break;
369
+ case 'code':
370
+ content = spec.js_code || spec.val_1 || '';
371
+ break;
372
+ case 'style':
373
+ content = spec.css_code || '';
374
+ break;
375
+ case 'configuration':
376
+ content = spec.val_1 || '';
377
+ break;
378
+ case 'template_code':
379
+ content = spec.val_1 || '';
380
+ break;
381
+ case 'processing_code':
382
+ content = spec.val_2 || '';
383
+ break;
384
+ case 'filter_code':
385
+ content = spec.val_3 || '';
386
+ break;
387
+ }
388
+ if (content) {
389
+ const filePath = join(specDir, `${filename}.${mapping.extension}`);
390
+ await fs.writeFile(filePath, content);
391
+ }
392
+ }
393
+ }
394
+ export async function saveObjectWithSpecs(outputPath, tableName, objectData, specs) {
395
+ const subfolder = objectData.is_cms_object === 1 ? 'butterfly' : objectData.database_alias || 'app';
396
+ const tableDir = join(outputPath, 'objects', subfolder, tableName);
397
+ await fs.mkdir(tableDir, { recursive: true });
398
+ const strippedObjectData = { ...objectData };
399
+ if (objectData.listing_query) {
400
+ delete strippedObjectData.listing_query;
401
+ }
402
+ const objectFile = join(tableDir, 'object.json');
403
+ await fs.writeFile(objectFile, JSON.stringify(strippedObjectData, null, 2));
404
+ if (objectData.listing_query) {
405
+ const listingQueryFile = join(tableDir, 'listing_query.bfy');
406
+ await fs.writeFile(listingQueryFile, objectData.listing_query);
407
+ }
408
+ if (specs && specs.length > 0) {
409
+ for (const spec of specs) {
410
+ const specDir = join(tableDir, spec.column_name);
411
+ await fs.mkdir(specDir, { recursive: true });
412
+ const mappings = getFieldMapping(spec);
413
+ const strippedSpec = stripExportedFields(spec, mappings);
414
+ const specFile = join(specDir, 'spec.json');
415
+ await fs.writeFile(specFile, JSON.stringify(strippedSpec, null, 2));
416
+ await exportSpecFiles(specDir, spec);
417
+ }
418
+ }
419
+ }
420
+ export async function saveTableRecord(outputPath, tableName, recordData, specs) {
421
+ const config = TABLE_CONFIGS[tableName] || {};
422
+ const tableDir = join(outputPath, tableName);
423
+ await fs.mkdir(tableDir, { recursive: true });
424
+ let folderName;
425
+ if (config.folderNameField && recordData[config.folderNameField]) {
426
+ folderName = String(recordData[config.folderNameField]).replace(/[^a-zA-Z0-9-_]/g, '_');
427
+ }
428
+ else {
429
+ folderName = recordData.name || recordData.id || `${tableName}-${recordData.id}`;
430
+ }
431
+ const recordDir = join(tableDir, folderName);
432
+ await fs.mkdir(recordDir, { recursive: true });
433
+ const strippedData = { ...recordData };
434
+ if (config.codeFields) {
435
+ for (const codeField of config.codeFields) {
436
+ if (recordData[codeField.field]) {
437
+ const codeFile = join(recordDir, `${codeField.filename}.${codeField.extension}`);
438
+ await fs.writeFile(codeFile, recordData[codeField.field]);
439
+ delete strippedData[codeField.field];
440
+ }
441
+ }
442
+ }
443
+ let jsonFileName;
444
+ if (tableName === 'bfy_state_machine_states') {
445
+ jsonFileName = 'state.json';
446
+ }
447
+ else if (tableName === 'bfy_state_machine_roles') {
448
+ jsonFileName = 'role.json';
449
+ }
450
+ else if (tableName === 'bfy_state_machine_transitions') {
451
+ jsonFileName = 'transition.json';
452
+ }
453
+ else if (tableName === 'bfy_sm_actions') {
454
+ jsonFileName = 'action.json';
455
+ }
456
+ else if (tableName === 'bfy_ai_tasks') {
457
+ jsonFileName = 'task.json';
458
+ }
459
+ else if (tableName === 'bfy_cronjobs') {
460
+ jsonFileName = 'cronjob.json';
461
+ }
462
+ else if (tableName === 'cms_email_templates') {
463
+ jsonFileName = 'template.json';
464
+ }
465
+ else if (tableName === 'cms_email_layouts') {
466
+ jsonFileName = 'layout.json';
467
+ }
468
+ else if (tableName === 'pages') {
469
+ jsonFileName = 'page.json';
470
+ }
471
+ else if (tableName === 'bfy_ai_tasks') {
472
+ jsonFileName = 'task.json';
473
+ }
474
+ else {
475
+ jsonFileName = `${tableName.slice(0, -1)}.json`;
476
+ }
477
+ const recordFile = join(recordDir, jsonFileName);
478
+ await fs.writeFile(recordFile, JSON.stringify(strippedData, null, 2));
479
+ if (config.hasSpecs && specs && specs.length > 0) {
480
+ for (const spec of specs) {
481
+ const specDir = join(recordDir, spec.column_name);
482
+ await fs.mkdir(specDir, { recursive: true });
483
+ await exportSpecFiles(specDir, spec);
484
+ const mappings = getFieldMapping(spec);
485
+ const strippedSpec = stripExportedFields(spec, mappings);
486
+ const specFile = join(specDir, 'spec.json');
487
+ await fs.writeFile(specFile, JSON.stringify(strippedSpec, null, 2));
488
+ }
489
+ }
490
+ }
491
+ export async function savePageData(outputPath, pageData) {
492
+ await saveTableRecord(outputPath, 'pages', pageData);
493
+ }
494
+ export async function saveReportData(outputPath, reportData, specs, queries, categories) {
495
+ const reportDir = join(outputPath, 'reports', reportData.alias || `report_${reportData.id}`);
496
+ await fs.mkdir(reportDir, { recursive: true });
497
+ const strippedReportData = { ...reportData };
498
+ if (reportData.query) {
499
+ delete strippedReportData.query;
500
+ }
501
+ const reportFile = join(reportDir, 'report.json');
502
+ await fs.writeFile(reportFile, JSON.stringify(strippedReportData, null, 2));
503
+ if (reportData.query) {
504
+ const mainQueryFile = join(reportDir, 'main_query.bfy');
505
+ await fs.writeFile(mainQueryFile, reportData.query);
506
+ }
507
+ if (queries && queries.length > 0) {
508
+ const queriesDir = join(reportDir, 'queries');
509
+ await fs.mkdir(queriesDir, { recursive: true });
510
+ for (const query of queries) {
511
+ const strippedQuery = { ...query };
512
+ if (query.query) {
513
+ delete strippedQuery.query;
514
+ }
515
+ if (query.js_code) {
516
+ delete strippedQuery.js_code;
517
+ }
518
+ const queryName = query.name || `${query.system_name}`;
519
+ const queryDir = join(queriesDir, queryName);
520
+ await fs.mkdir(queryDir, { recursive: true });
521
+ const queryFile = join(queryDir, 'query.json');
522
+ await fs.writeFile(queryFile, JSON.stringify(strippedQuery, null, 2));
523
+ if (query.query) {
524
+ const queryCodeFile = join(queryDir, 'query_code.bfy');
525
+ await fs.writeFile(queryCodeFile, query.query);
526
+ }
527
+ if (query.js_code) {
528
+ const scriptFile = join(queryDir, 'script.js');
529
+ await fs.writeFile(scriptFile, query.js_code);
530
+ }
531
+ }
532
+ }
533
+ if (specs && specs.length > 0) {
534
+ const specsDir = join(reportDir, 'specs');
535
+ await fs.mkdir(specsDir, { recursive: true });
536
+ for (const spec of specs) {
537
+ const strippedSpec = { ...spec };
538
+ if (spec.js_code) {
539
+ delete strippedSpec.js_code;
540
+ }
541
+ const fieldName = spec.field_name || `field_${spec.id}`;
542
+ const specDir = join(specsDir, fieldName);
543
+ await fs.mkdir(specDir, { recursive: true });
544
+ const specFile = join(specDir, 'spec.json');
545
+ await fs.writeFile(specFile, JSON.stringify(strippedSpec, null, 2));
546
+ if (spec.js_code) {
547
+ const jsFile = join(specDir, 'code.js');
548
+ await fs.writeFile(jsFile, spec.js_code);
549
+ }
550
+ }
551
+ }
552
+ if (categories && categories.length > 0) {
553
+ const categoriesFile = join(outputPath, 'reports', 'categories.json');
554
+ await fs.writeFile(categoriesFile, JSON.stringify(categories, null, 2));
555
+ }
556
+ }
557
+ export async function saveStateMachineData(outputPath, stateMachine, states, roles, transitions, transitionSpecs, actions, actionSpecs, transitionActions) {
558
+ const config = TABLE_CONFIGS.bfy_state_machines;
559
+ const folderName = stateMachine[config.folderNameField] || `state_machine_${stateMachine.id}`;
560
+ const stateMachineDir = join(outputPath, 'bfy_state_machines', folderName);
561
+ await fs.mkdir(stateMachineDir, { recursive: true });
562
+ await fs.writeFile(join(stateMachineDir, 'state_machine.json'), JSON.stringify(stateMachine, null, 2));
563
+ if (states && states.length > 0) {
564
+ const statesDir = join(stateMachineDir, 'states');
565
+ for (const state of states) {
566
+ const config = TABLE_CONFIGS.bfy_state_machine_states;
567
+ const folderName = state[config.folderNameField] || `state_${state.id}`;
568
+ const stateDir = join(statesDir, folderName);
569
+ await fs.mkdir(stateDir, { recursive: true });
570
+ await fs.writeFile(join(stateDir, 'state.json'), JSON.stringify(state, null, 2));
571
+ }
572
+ }
573
+ if (roles && roles.length > 0) {
574
+ const rolesDir = join(stateMachineDir, 'roles');
575
+ for (const role of roles) {
576
+ const config = TABLE_CONFIGS.bfy_state_machine_roles;
577
+ const folderName = role[config.folderNameField] || `role_${role.id}`;
578
+ const roleDir = join(rolesDir, folderName);
579
+ await fs.mkdir(roleDir, { recursive: true });
580
+ const strippedRole = { ...role };
581
+ if (role.validation_code) {
582
+ delete strippedRole.validation_code;
583
+ }
584
+ await fs.writeFile(join(roleDir, 'role.json'), JSON.stringify(strippedRole, null, 2));
585
+ if (role.validation_code) {
586
+ await fs.writeFile(join(roleDir, 'validation_code.bfy'), role.validation_code);
587
+ }
588
+ }
589
+ }
590
+ if (transitions && transitions.length > 0) {
591
+ const transitionsDir = join(stateMachineDir, 'transitions');
592
+ for (const transition of transitions) {
593
+ const config = TABLE_CONFIGS.bfy_state_machine_transitions;
594
+ const folderName = transition[config.folderNameField] || `transition_${transition.id}`;
595
+ const transitionDir = join(transitionsDir, folderName);
596
+ await fs.mkdir(transitionDir, { recursive: true });
597
+ const strippedTransition = { ...transition };
598
+ if (transition.action_code) {
599
+ delete strippedTransition.action_code;
600
+ }
601
+ if (transition.validation_code) {
602
+ delete strippedTransition.validation_code;
603
+ }
604
+ await fs.writeFile(join(transitionDir, 'transition.json'), JSON.stringify(strippedTransition, null, 2));
605
+ if (transition.action_code) {
606
+ await fs.writeFile(join(transitionDir, 'action_code.bfy'), transition.action_code);
607
+ }
608
+ if (transition.validation_code) {
609
+ await fs.writeFile(join(transitionDir, 'validation_code.bfy'), transition.validation_code);
610
+ }
611
+ const relatedSpecs = transitionSpecs.filter(spec => spec.bfy_state_machine_transition_id === transition.id);
612
+ if (relatedSpecs.length > 0) {
613
+ const specsDir = join(transitionDir, 'specs');
614
+ await fs.mkdir(specsDir, { recursive: true });
615
+ for (const spec of relatedSpecs) {
616
+ const specName = spec.name || `spec_${spec.id}`;
617
+ const specDir = join(specsDir, specName);
618
+ await fs.mkdir(specDir, { recursive: true });
619
+ const mappings = getFieldMapping(spec);
620
+ const strippedSpec = stripExportedFields(spec, mappings);
621
+ await fs.writeFile(join(specDir, 'spec.json'), JSON.stringify(strippedSpec, null, 2));
622
+ await exportSpecFiles(specDir, spec);
623
+ }
624
+ }
625
+ }
626
+ }
627
+ if (actions && actions.length > 0) {
628
+ const actionsDir = join(stateMachineDir, 'actions');
629
+ for (const action of actions) {
630
+ const config = TABLE_CONFIGS.bfy_sm_actions;
631
+ const folderName = action[config.folderNameField] || `action_${action.id}`;
632
+ const actionDir = join(actionsDir, folderName);
633
+ await fs.mkdir(actionDir, { recursive: true });
634
+ const strippedAction = { ...action };
635
+ if (action.code) {
636
+ delete strippedAction.code;
637
+ }
638
+ await fs.writeFile(join(actionDir, 'action.json'), JSON.stringify(strippedAction, null, 2));
639
+ if (action.code) {
640
+ await fs.writeFile(join(actionDir, 'code.bfy'), action.code);
641
+ }
642
+ const relatedSpecs = actionSpecs.filter(spec => spec.bfy_sm_action_id === action.id);
643
+ if (relatedSpecs.length > 0) {
644
+ const specsDir = join(actionDir, 'specs');
645
+ await fs.mkdir(specsDir, { recursive: true });
646
+ for (const spec of relatedSpecs) {
647
+ const specName = spec.name || `spec_${spec.id}`;
648
+ const specDir = join(specsDir, specName);
649
+ await fs.mkdir(specDir, { recursive: true });
650
+ const mappings = getFieldMapping(spec);
651
+ const strippedSpec = stripExportedFields(spec, mappings);
652
+ await fs.writeFile(join(specDir, 'spec.json'), JSON.stringify(strippedSpec, null, 2));
653
+ await exportSpecFiles(specDir, spec);
654
+ }
655
+ }
656
+ }
657
+ }
658
+ if (transitionActions && transitionActions.length > 0) {
659
+ const transitionActionsDir = join(stateMachineDir, 'transition_actions');
660
+ await fs.mkdir(transitionActionsDir, { recursive: true });
661
+ for (const mapping of transitionActions) {
662
+ const fileName = `${mapping.bfy_state_machine_transition_id}_${mapping.bfy_sm_action_id}.json`;
663
+ await fs.writeFile(join(transitionActionsDir, fileName), JSON.stringify(mapping, null, 2));
664
+ }
665
+ }
666
+ }
667
+ export async function saveWorkflowData(outputPath, workflow, versions, nodes, connections) {
668
+ const config = TABLE_CONFIGS.bfy_workflows;
669
+ const folderName = workflow[config.folderNameField] || `workflow_${workflow.id}`;
670
+ const workflowDir = join(outputPath, 'bfy_workflows', folderName);
671
+ await fs.mkdir(workflowDir, { recursive: true });
672
+ await fs.writeFile(join(workflowDir, 'workflow.json'), JSON.stringify(workflow, null, 2));
673
+ if (versions && versions.length > 0) {
674
+ for (const version of versions) {
675
+ const versionFolderName = `v${version.version_number}`;
676
+ const versionDir = join(workflowDir, versionFolderName);
677
+ await fs.mkdir(versionDir, { recursive: true });
678
+ await fs.writeFile(join(versionDir, 'version.json'), JSON.stringify(version, null, 2));
679
+ const versionNodes = nodes.filter(n => n.bfy_workflow_version_id === version.id);
680
+ if (versionNodes.length > 0) {
681
+ const nodesDir = join(versionDir, 'nodes');
682
+ await fs.mkdir(nodesDir, { recursive: true });
683
+ for (const node of versionNodes) {
684
+ const nodeTitle = node.title || node.name || 'node';
685
+ const nodeFolderName = `${String(nodeTitle).replace(/[^a-zA-Z0-9-_]/g, '_')}_${node.id}`;
686
+ const nodeDir = join(nodesDir, nodeFolderName);
687
+ await fs.mkdir(nodeDir, { recursive: true });
688
+ const strippedNode = { ...node };
689
+ if (node.code) {
690
+ delete strippedNode.code;
691
+ }
692
+ if (node.params) {
693
+ delete strippedNode.params;
694
+ }
695
+ await fs.writeFile(join(nodeDir, 'node.json'), JSON.stringify(strippedNode, null, 2));
696
+ if (node.code) {
697
+ await fs.writeFile(join(nodeDir, 'code.bfy'), node.code);
698
+ }
699
+ if (node.params) {
700
+ let paramsData = node.params;
701
+ if (typeof paramsData === 'string') {
702
+ try {
703
+ paramsData = JSON.parse(paramsData);
704
+ }
705
+ catch {
706
+ }
707
+ }
708
+ if (paramsData && typeof paramsData === 'object' && !Array.isArray(paramsData)) {
709
+ if (paramsData.code) {
710
+ if (!node.code) {
711
+ await fs.writeFile(join(nodeDir, 'code.bfy'), paramsData.code);
712
+ }
713
+ const { code: _code, ...paramsWithoutCode } = paramsData;
714
+ paramsData = paramsWithoutCode;
715
+ }
716
+ }
717
+ if (paramsData && typeof paramsData === 'object' && Object.keys(paramsData).length > 0) {
718
+ const yamlContent = yamlStringify(paramsData);
719
+ await fs.writeFile(join(nodeDir, 'params.yaml'), yamlContent);
720
+ }
721
+ }
722
+ }
723
+ }
724
+ const versionNodeIds = versionNodes.map(n => n.id);
725
+ const versionConnections = connections.filter(c => versionNodeIds.includes(c.source_node_id) || versionNodeIds.includes(c.target_node_id));
726
+ if (versionConnections.length > 0) {
727
+ await fs.writeFile(join(versionDir, 'connections.json'), JSON.stringify(versionConnections, null, 2));
728
+ }
729
+ }
730
+ }
731
+ }
732
+ //# sourceMappingURL=files.js.map