@rglabs/butterfly 2.0.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 (117) hide show
  1. package/CLAUDE.md +201 -0
  2. package/README.md +371 -0
  3. package/dist/commands/add.d.ts +23 -0
  4. package/dist/commands/add.js +303 -0
  5. package/dist/commands/code.d.ts +11 -0
  6. package/dist/commands/code.js +72 -0
  7. package/dist/commands/create-object.d.ts +6 -0
  8. package/dist/commands/create-object.js +293 -0
  9. package/dist/commands/create-report.d.ts +6 -0
  10. package/dist/commands/create-report.js +154 -0
  11. package/dist/commands/diff.d.ts +4 -0
  12. package/dist/commands/diff.js +238 -0
  13. package/dist/commands/download.d.ts +4 -0
  14. package/dist/commands/download.js +374 -0
  15. package/dist/commands/layout.d.ts +12 -0
  16. package/dist/commands/layout.js +83 -0
  17. package/dist/commands/record.d.ts +21 -0
  18. package/dist/commands/record.js +483 -0
  19. package/dist/commands/run-poc.d.ts +3 -0
  20. package/dist/commands/run-poc.js +18 -0
  21. package/dist/commands/setup.d.ts +3 -0
  22. package/dist/commands/setup.js +66 -0
  23. package/dist/commands/start-poc.d.ts +3 -0
  24. package/dist/commands/start-poc.js +55 -0
  25. package/dist/commands/sync-docs.d.ts +3 -0
  26. package/dist/commands/sync-docs.js +27 -0
  27. package/dist/commands/translate.d.ts +13 -0
  28. package/dist/commands/translate.js +401 -0
  29. package/dist/commands/upload.d.ts +3 -0
  30. package/dist/commands/upload.js +150 -0
  31. package/dist/commands/workflow-info.d.ts +13 -0
  32. package/dist/commands/workflow-info.js +161 -0
  33. package/dist/components/ConflictResolver.d.ts +12 -0
  34. package/dist/components/ConflictResolver.js +77 -0
  35. package/dist/components/DiffView.d.ts +11 -0
  36. package/dist/components/DiffView.js +101 -0
  37. package/dist/components/DownloadProgress.d.ts +11 -0
  38. package/dist/components/DownloadProgress.js +29 -0
  39. package/dist/components/RecordPreview.d.ts +11 -0
  40. package/dist/components/RecordPreview.js +91 -0
  41. package/dist/components/SetupForm.d.ts +8 -0
  42. package/dist/components/SetupForm.js +56 -0
  43. package/dist/components/UploadProgress.d.ts +13 -0
  44. package/dist/components/UploadProgress.js +42 -0
  45. package/dist/diff/adapters/index.d.ts +8 -0
  46. package/dist/diff/adapters/index.js +18 -0
  47. package/dist/diff/adapters/objectsAdapter.d.ts +13 -0
  48. package/dist/diff/adapters/objectsAdapter.js +177 -0
  49. package/dist/diff/adapters/reportsAdapter.d.ts +14 -0
  50. package/dist/diff/adapters/reportsAdapter.js +212 -0
  51. package/dist/diff/adapters/types.d.ts +19 -0
  52. package/dist/diff/adapters/types.js +2 -0
  53. package/dist/diff/engine.d.ts +19 -0
  54. package/dist/diff/engine.js +57 -0
  55. package/dist/diff/types.d.ts +34 -0
  56. package/dist/diff/types.js +110 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.js +117 -0
  59. package/dist/types/index.d.ts +18 -0
  60. package/dist/types/index.js +2 -0
  61. package/dist/utils/api.d.ts +85 -0
  62. package/dist/utils/api.js +1031 -0
  63. package/dist/utils/auth.d.ts +4 -0
  64. package/dist/utils/auth.js +22 -0
  65. package/dist/utils/bfySplitter.d.ts +12 -0
  66. package/dist/utils/bfySplitter.js +151 -0
  67. package/dist/utils/docs.d.ts +16 -0
  68. package/dist/utils/docs.js +186 -0
  69. package/dist/utils/errorLogger.d.ts +6 -0
  70. package/dist/utils/errorLogger.js +29 -0
  71. package/dist/utils/files.d.ts +14 -0
  72. package/dist/utils/files.js +772 -0
  73. package/dist/utils/lockManager.d.ts +15 -0
  74. package/dist/utils/lockManager.js +126 -0
  75. package/dist/utils/resourceHandlers.d.ts +50 -0
  76. package/dist/utils/resourceHandlers.js +684 -0
  77. package/dist/utils/resourceMapping.d.ts +32 -0
  78. package/dist/utils/resourceMapping.js +210 -0
  79. package/dist/utils/singleResourceDownload.d.ts +14 -0
  80. package/dist/utils/singleResourceDownload.js +261 -0
  81. package/dist/utils/summaryGenerator.d.ts +2 -0
  82. package/dist/utils/summaryGenerator.js +183 -0
  83. package/dist/utils/uploadHandler.d.ts +31 -0
  84. package/dist/utils/uploadHandler.js +263 -0
  85. package/docs/AI_API.md +93 -0
  86. package/docs/CLAUDE.md +216 -0
  87. package/docs/PROJECT_SPECIFIC.md +1 -0
  88. package/docs/RECORD_COMMAND.md +262 -0
  89. package/docs/WORKFLOW_API.md +480 -0
  90. package/docs/bfy-splitting.md +126 -0
  91. package/docs/cli-commands.md +333 -0
  92. package/docs/examples/README.md +95 -0
  93. package/docs/examples/order-system.md +147 -0
  94. package/docs/examples/product-catalog.md +195 -0
  95. package/docs/examples/reports.md +187 -0
  96. package/docs/excel-export.md +216 -0
  97. package/docs/field-types/README.md +29 -0
  98. package/docs/field-types/calculated.md +147 -0
  99. package/docs/field-types/code-mappings.md +84 -0
  100. package/docs/field-types/custom.md +340 -0
  101. package/docs/object-specs/README.md +136 -0
  102. package/docs/object-specs/code-parameters.md +151 -0
  103. package/docs/object-specs/creating.md +203 -0
  104. package/docs/object-specs/js-code-examples.md +208 -0
  105. package/docs/object-specs/js-field-updates.md +168 -0
  106. package/docs/objects/README.md +89 -0
  107. package/docs/objects/creating.md +127 -0
  108. package/docs/page-layout.md +361 -0
  109. package/docs/permissions.md +260 -0
  110. package/docs/reports.md +197 -0
  111. package/docs/state-machines.md +544 -0
  112. package/docs/tasks/create-object.md +81 -0
  113. package/docs/translations.md +346 -0
  114. package/docs/twig-helpers.md +283 -0
  115. package/docs/webservices.md +159 -0
  116. package/docs/workspaces.md +176 -0
  117. package/package.json +59 -0
@@ -0,0 +1,480 @@
1
+ # Workflow API Reference
2
+
3
+ This document describes workflow management, node connections, and synchronization features in the CLI.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [File Structure](#file-structure)
10
+ - [Downloading Workflows](#downloading-workflows)
11
+ - [Watch Mode (Real-time Sync)](#watch-mode-real-time-sync)
12
+ - [Node Connections](#node-connections)
13
+ - [Version Management](#version-management)
14
+ - [Discovering Node Groups and Types](#discovering-node-groups-and-types)
15
+ - [Creating Workflows and Nodes](#creating-workflows-and-nodes)
16
+ - [API Methods Reference](#api-methods-reference)
17
+
18
+ ---
19
+
20
+ ## File Structure
21
+
22
+ When downloading workflows, the CLI creates the following structure:
23
+
24
+ ```
25
+ bfy_workflows/
26
+ └── [workflow_name]/ # Folder named by workflow name
27
+ ├── workflow.json # Main workflow metadata
28
+ └── v[version_number]/ # Version folder (v1, v2, etc.)
29
+ ├── version.json # Version data with status
30
+ ├── connections.json # Node connections for this version
31
+ └── nodes/
32
+ └── [node_title]_[id]/ # Node folder (e.g., "Process_Data_123")
33
+ ├── node.json # Node metadata (position, title, etc.)
34
+ ├── code.bfy # Node code (if exists)
35
+ └── params.yaml # Node parameters (if exists)
36
+ ```
37
+
38
+ ### File Descriptions
39
+
40
+ | File | Description |
41
+ |------|-------------|
42
+ | `workflow.json` | Main workflow definition (name, description, settings) |
43
+ | `version.json` | Version metadata including status (1=Draft, 2=Published, 3=Archived) |
44
+ | `connections.json` | Array of connections between nodes |
45
+ | `node.json` | Node configuration (position_x, position_y, title, node_group, etc.) |
46
+ | `code.bfy` | Node's executable code (extracted from `params.code` or `node.code`) |
47
+ | `params.yaml` | Node parameters in YAML format (excluding code) |
48
+
49
+ ---
50
+
51
+ ## Downloading Workflows
52
+
53
+ ### Download All Workflows
54
+
55
+ ```bash
56
+ butterfly-cli download -t bfy_workflows
57
+ ```
58
+
59
+ ### Download with Cleanup
60
+
61
+ ```bash
62
+ butterfly-cli download -t bfy_workflows --cleanup
63
+ ```
64
+
65
+ ### Download All Resources (includes workflows)
66
+
67
+ ```bash
68
+ butterfly-cli download
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Watch Mode (Real-time Sync)
74
+
75
+ Upload changes back to the platform:
76
+
77
+ ```bash
78
+ butterfly-cli upload <path>
79
+ ```
80
+
81
+ ### Watched Files
82
+
83
+ | File | Sync Behavior |
84
+ |------|---------------|
85
+ | `workflow.json` | Updates workflow metadata |
86
+ | `version.json` | Updates version status and metadata |
87
+ | `node.json` | Updates node position, title, and configuration |
88
+ | `code.bfy` | Updates node code (merged into `params.code` or `node.code`) |
89
+ | `params.yaml` | Updates node parameters (merged with code if both exist) |
90
+ | `connections.json` | **Full sync**: creates, updates, and deletes connections |
91
+
92
+ ### Connection Sync Behavior
93
+
94
+ When you edit `connections.json`, the CLI:
95
+
96
+ 1. **Detects new connections** (entries without `id`) - Creates them on the server and writes back the assigned ID
97
+ 2. **Detects modified connections** - Updates changed fields on the server
98
+ 3. **Detects deleted connections** - Removes them from the server
99
+
100
+ The connection cache is initialized at startup to accurately track changes.
101
+
102
+ ---
103
+
104
+ ## Node Connections
105
+
106
+ ### Connection Structure
107
+
108
+ Each connection in `connections.json` has the following fields:
109
+
110
+ ```json
111
+ {
112
+ "id": 123,
113
+ "source_node_id": 1,
114
+ "target_node_id": 2,
115
+ "source_output_key": "output",
116
+ "target_input_key": "input",
117
+ "connection_type": "data"
118
+ }
119
+ ```
120
+
121
+ | Field | Description |
122
+ |-------|-------------|
123
+ | `id` | Connection ID (assigned by server for new connections) |
124
+ | `source_node_id` | ID of the source node |
125
+ | `target_node_id` | ID of the target node |
126
+ | `source_output_key` | Output connector key on source node |
127
+ | `target_input_key` | Input connector key on target node |
128
+ | `connection_type` | Type of connection (e.g., "data", "control") |
129
+
130
+ ### Creating a New Connection
131
+
132
+ Add a new entry to `connections.json` **without an `id`**:
133
+
134
+ ```json
135
+ [
136
+ {
137
+ "source_node_id": 1,
138
+ "target_node_id": 2,
139
+ "source_output_key": "output",
140
+ "target_input_key": "input"
141
+ }
142
+ ]
143
+ ```
144
+
145
+ Save the file, and watch mode will:
146
+ 1. Create the connection on the server
147
+ 2. Write back the assigned `id` to the file
148
+
149
+ ### Deleting a Connection
150
+
151
+ Remove the connection entry from `connections.json` and save. Watch mode will delete it from the server.
152
+
153
+ ### Node Connectors
154
+
155
+ Nodes have three types of connectors:
156
+
157
+ | Connector Type | Color | Purpose |
158
+ |----------------|-------|---------|
159
+ | **Input** | Blue | Receive data from other nodes |
160
+ | **Output** | Green | Send data to other nodes |
161
+ | **Preference** | Purple | Configuration values |
162
+
163
+ ---
164
+
165
+ ## Version Management
166
+
167
+ ### Version Statuses
168
+
169
+ | Status | Value | Description |
170
+ |--------|-------|-------------|
171
+ | Draft | 1 | Editable version |
172
+ | Published | 2 | Read-only, active version |
173
+ | Archived | 3 | Read-only, historical version |
174
+
175
+ ### Changing Version Status
176
+
177
+ Edit `version.json` and change the `status` field:
178
+
179
+ ```json
180
+ {
181
+ "id": 1,
182
+ "bfy_workflow_id": 1,
183
+ "version_number": 1,
184
+ "status": 2
185
+ }
186
+ ```
187
+
188
+ Save the file, and watch mode will update the status on the server.
189
+
190
+ ### Version Folder Naming
191
+
192
+ Versions are stored in folders named `v[version_number]`:
193
+ - `v1/` - Version 1
194
+ - `v2/` - Version 2
195
+ - etc.
196
+
197
+ ---
198
+
199
+ ## Discovering Node Groups and Types
200
+
201
+ Use the `workflow-info` command to dynamically discover available node groups and types from the API.
202
+
203
+ ### List All Node Groups
204
+
205
+ ```bash
206
+ butterfly-cli workflow-info --groups
207
+ ```
208
+
209
+ ### List Nodes in a Group
210
+
211
+ ```bash
212
+ butterfly-cli workflow-info --nodes <group>
213
+
214
+ # Examples:
215
+ butterfly-cli workflow-info --nodes Database
216
+ butterfly-cli workflow-info --nodes Control
217
+ butterfly-cli workflow-info --nodes Notification
218
+ butterfly-cli workflow-info --nodes Trigger
219
+ butterfly-cli workflow-info --nodes Code
220
+ ```
221
+
222
+ ### Get Node Details
223
+
224
+ ```bash
225
+ butterfly-cli workflow-info --details <node> --group <group>
226
+
227
+ # Examples:
228
+ butterfly-cli workflow-info --details MySQL --group Database
229
+ butterfly-cli workflow-info --details Alarm --group Control
230
+ butterfly-cli workflow-info --details Mailer --group Notification
231
+ butterfly-cli workflow-info --details CustomScript --group Code
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Creating Workflows and Nodes
237
+
238
+ ### Create a New Workflow
239
+
240
+ ```bash
241
+ butterfly-cli add -t workflow --title "My Workflow"
242
+ ```
243
+
244
+ ### Add Nodes to a Workflow
245
+
246
+ Use the `--node-group` and `--node-type` values from `workflow-info` output:
247
+
248
+ ```bash
249
+ butterfly-cli add -t workflow-node -w "<workflow-name>" --title "<node-title>" --node-group <group> --node-type <type>
250
+ ```
251
+
252
+ ### Node Creation Options
253
+
254
+ | Option | Description |
255
+ |--------|-------------|
256
+ | `-w, --workflow <name>` | Workflow name or ID (required) |
257
+ | `--title <title>` | Node title |
258
+ | `--node-group <group>` | Node group from `workflow-info --groups` |
259
+ | `--node-type <type>` | Node type from `workflow-info --nodes <group>` |
260
+ | `--system-name <name>` | System name for the node |
261
+ | `-v, --version <number>` | Version number (defaults to latest) |
262
+ | `--connect-from <spec>` | Connect FROM existing node TO new node |
263
+ | `--connect-to <spec>` | Connect FROM new node TO existing node |
264
+
265
+ ---
266
+
267
+ ## Creating Connections Between Existing Nodes
268
+
269
+ Use the `workflow-connection` type to create connections between existing nodes:
270
+
271
+ ```bash
272
+ butterfly-cli add -t workflow-connection -w "<workflow-name>" --from <source_id> --to <target_id>
273
+ ```
274
+
275
+ ### Connection Creation Options
276
+
277
+ | Option | Description |
278
+ |--------|-------------|
279
+ | `-w, --workflow <name>` | Workflow name or ID (required) |
280
+ | `--from <id>` | Source node ID (required) |
281
+ | `--from-output <key>` | Source node output key (default: `output`) |
282
+ | `--to <id>` | Target node ID (required) |
283
+ | `--to-input <key>` | Target node input key (default: `input`) |
284
+ | `-v, --version <number>` | Version number (defaults to latest) |
285
+
286
+ ### Connection Examples
287
+
288
+ ```bash
289
+ # Create a basic connection between two nodes
290
+ butterfly-cli add -t workflow-connection -w "Order Processing" --from 123 --to 456
291
+
292
+ # Specify custom output key on source node
293
+ butterfly-cli add -t workflow-connection -w "Order Processing" --from 123 --from-output result --to 456
294
+
295
+ # Specify custom input key on target node
296
+ butterfly-cli add -t workflow-connection -w "Order Processing" --from 123 --to 456 --to-input data
297
+
298
+ # Specify both custom keys
299
+ butterfly-cli add -t workflow-connection -w "Order Processing" --from 123 --from-output result --to 456 --to-input data
300
+
301
+ # Create connection in a specific version
302
+ butterfly-cli add -t workflow-connection -w "Order Processing" -v 2 --from 123 --to 456
303
+ ```
304
+
305
+ ### Connection Specification Format
306
+
307
+ **`--connect-from <node_id>[:<output_key>]`**
308
+ - Connects FROM an existing node's output TO the new node's input
309
+ - `output_key` specifies the source node's output connector (default: `output`)
310
+ - The new node's input connector is always `input`
311
+
312
+ **`--connect-to <node_id>[:<input_key>]`**
313
+ - Connects FROM the new node's output TO an existing node's input
314
+ - `input_key` specifies the target node's input connector (default: `input`)
315
+ - The new node's output connector is always `output`
316
+
317
+ **Examples:**
318
+ - `--connect-from 123` - Connect from node 123's "output" to new node's "input"
319
+ - `--connect-from 123:result` - Connect from node 123's "result" output to new node's "input"
320
+ - `--connect-to 456` - Connect from new node's "output" to node 456's "input"
321
+ - `--connect-to 456:data` - Connect from new node's "output" to node 456's "data" input
322
+
323
+ ### Examples
324
+
325
+ ```bash
326
+ # Create a new workflow
327
+ butterfly-cli add -t workflow --title "Order Processing"
328
+
329
+ # Add a CustomScript node
330
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Process Data" --node-group Code --node-type CustomScript
331
+
332
+ # Add a REST API connector
333
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "API Call" --node-group Connector --node-type RESTAPI
334
+
335
+ # Add a webhook trigger
336
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Webhook Trigger" --node-group Trigger --node-type WebHook
337
+
338
+ # Add node to specific version
339
+ butterfly-cli add -t workflow-node -w "Order Processing" -v 1 --title "New Node"
340
+
341
+ # Add a node and connect FROM an existing node (node 123) TO the new node
342
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Next Step" --connect-from 123
343
+
344
+ # Add a node and connect FROM the new node TO an existing node (node 456)
345
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Pre-Process" --connect-to 456
346
+
347
+ # Add a node with custom output key from source node
348
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Transform" --connect-from 123:result
349
+
350
+ # Add a node with custom input key to target node
351
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Finalize" --connect-to 456:data
352
+
353
+ # Add a node with both incoming and outgoing connections
354
+ butterfly-cli add -t workflow-node -w "Order Processing" --title "Middle Node" --connect-from 123 --connect-to 456
355
+ ```
356
+
357
+ ---
358
+
359
+ ## API Methods Reference
360
+
361
+ The following API methods are available in `ButterflyAPI` class for workflow management:
362
+
363
+ ### Connection Methods
364
+
365
+ | Method | Description |
366
+ |--------|-------------|
367
+ | `createWorkflowConnection(data)` | Create a new connection between nodes |
368
+ | `updateWorkflowConnection(id, data)` | Update an existing connection |
369
+ | `deleteWorkflowConnection(id)` | Delete a connection |
370
+
371
+ ### Node Methods
372
+
373
+ | Method | Description |
374
+ |--------|-------------|
375
+ | `createWorkflowNode(data)` | Create a new node in a workflow version |
376
+ | `updateWorkflowNode(id, data)` | Update node properties (position, title, code, params) |
377
+ | `deleteWorkflowNode(id)` | Delete a node from a workflow |
378
+
379
+ ### Version Methods
380
+
381
+ | Method | Description |
382
+ |--------|-------------|
383
+ | `createWorkflowVersion(data)` | Create a new version of a workflow |
384
+ | `updateWorkflowVersion(id, data)` | Update version metadata |
385
+ | `publishWorkflowVersion(id)` | Set version status to Published (2) |
386
+ | `archiveWorkflowVersion(id)` | Set version status to Archived (3) |
387
+
388
+ ### API Endpoints
389
+
390
+ All workflow operations use the standard CMS object operation endpoint:
391
+
392
+ ```
393
+ POST /admin/ajax/cms_object/operation?do={table}__{action}
394
+ ```
395
+
396
+ | Table | Actions |
397
+ |-------|---------|
398
+ | `bfy_workflows` | `add`, `edit`, `delete` |
399
+ | `bfy_workflow_versions` | `add`, `edit`, `delete` |
400
+ | `bfy_workflow_nodes` | `add`, `edit`, `delete` |
401
+ | `bfy_workflow_connections` | `add`, `edit`, `delete` |
402
+
403
+ ---
404
+
405
+ ## Node Code and Parameters
406
+
407
+ ### Code Extraction
408
+
409
+ When downloading, node code is extracted to separate files:
410
+
411
+ 1. If `node.code` exists → `code.bfy`
412
+ 2. If `params.code` exists → `code.bfy` (and removed from params.yaml)
413
+ 3. Other params → `params.yaml`
414
+
415
+ ### Code Sync (Watch Mode)
416
+
417
+ When syncing back:
418
+
419
+ 1. If `params.yaml` exists:
420
+ - Code from `code.bfy` is merged into `params.code`
421
+ - Combined params JSON is sent to server
422
+ 2. If only `code.bfy` exists:
423
+ - Code is sent directly as `node.code`
424
+
425
+ ### Example Node Files
426
+
427
+ **node.json:**
428
+ ```json
429
+ {
430
+ "id": 123,
431
+ "bfy_workflow_version_id": 1,
432
+ "title": "Process Order",
433
+ "node_group_class_name": "Code",
434
+ "node_identifier_key": "CustomScript",
435
+ "position_x": 250,
436
+ "position_y": 150
437
+ }
438
+ ```
439
+
440
+ **code.bfy:**
441
+ ```twig
442
+ {% set order = input.order %}
443
+ {% set total = order.items|reduce((carry, item) => carry + item.price, 0) %}
444
+
445
+ {{ output('result', { 'total': total }) }}
446
+ ```
447
+
448
+ **params.yaml:**
449
+ ```yaml
450
+ timeout: 30
451
+ retry_count: 3
452
+ error_handling: continue
453
+ ```
454
+
455
+ ---
456
+
457
+ ## Troubleshooting
458
+
459
+ ### Connection Sync Issues
460
+
461
+ If connections aren't syncing properly:
462
+
463
+ 1. Check `.butterfly/error_log.txt` for errors
464
+ 2. Ensure the workflow version status is Draft (1)
465
+ 3. Verify node IDs in connections match existing nodes
466
+
467
+ ### Node Code Not Updating
468
+
469
+ If node code changes aren't reflected:
470
+
471
+ 1. Check if `params.yaml` exists - code goes into `params.code`
472
+ 2. Without `params.yaml`, code goes directly to `node.code`
473
+ 3. Both files are merged when syncing
474
+
475
+ ### Version Status Locked
476
+
477
+ Published (2) and Archived (3) versions are read-only on the server. To edit:
478
+
479
+ 1. Create a new Draft version
480
+ 2. Or change status back to Draft (1) via `version.json`
@@ -0,0 +1,126 @@
1
+ # BFY File Splitting
2
+
3
+ Butterfly CLI supports splitting large `.bfy` files into smaller, manageable parts. This is useful when a single file (like `processing_code.bfy`) becomes too large to manage.
4
+
5
+ ## Marker Syntax
6
+
7
+ Use these markers to define parts within a `.bfy` file:
8
+
9
+ ```twig
10
+ {# --- part: part_name --- #}
11
+ ... part content ...
12
+ {# --- endpart --- #}
13
+ ```
14
+
15
+ **Rules:**
16
+ - Part names must be alphanumeric with underscores or hyphens (`[a-zA-Z0-9_-]+`)
17
+ - Each `part` marker must have a matching `endpart` marker
18
+ - Part names must be unique within the file
19
+
20
+ ## How It Works
21
+
22
+ ### Splitting (Download)
23
+
24
+ When you download resources, the CLI automatically detects `.bfy` files with part markers and splits them:
25
+
26
+ **Before splitting:**
27
+ ```
28
+ processing_code.bfy
29
+ ```
30
+
31
+ **After splitting:**
32
+ ```
33
+ processing_code.bfy # Container file (with include markers)
34
+ processing_code/ # Parts folder
35
+ ├── validation.bfy
36
+ └── calculation.bfy
37
+ ```
38
+
39
+ The container file will have `{# --- include: part_name --- #}` markers where the parts were extracted.
40
+
41
+ ### Merging (Upload)
42
+
43
+ When you upload or read a split file, the CLI automatically merges the parts back:
44
+ - Detects `{# --- include: name --- #}` markers in container file
45
+ - Looks for corresponding `.bfy` files in the parts folder
46
+ - Replaces include markers with full part content (wrapped in `part`/`endpart` markers)
47
+
48
+ ## Example
49
+
50
+ ### Original File (before download)
51
+
52
+ ```twig
53
+ {% set data = getValue('items') %}
54
+
55
+ {# --- part: validation --- #}
56
+ {% if data|length == 0 %}
57
+ {{ errorMessage('No items found') }}
58
+ {% endif %}
59
+
60
+ {% for item in data %}
61
+ {% if item.quantity <= 0 %}
62
+ {{ errorMessage('Invalid quantity for ' ~ item.name) }}
63
+ {% endif %}
64
+ {% endfor %}
65
+ {# --- endpart --- #}
66
+
67
+ {# --- part: calculation --- #}
68
+ {% set total = 0 %}
69
+ {% for item in data %}
70
+ {% set total = total + (item.price * item.quantity) %}
71
+ {% endfor %}
72
+ {{ setValue('total', total) }}
73
+ {# --- endpart --- #}
74
+ ```
75
+
76
+ ### After Download (split)
77
+
78
+ **processing_code.bfy** (container):
79
+ ```twig
80
+ {% set data = getValue('items') %}
81
+
82
+ {# --- include: validation --- #}
83
+
84
+ {# --- include: calculation --- #}
85
+ ```
86
+
87
+ **processing_code/validation.bfy**:
88
+ ```twig
89
+ {% if data|length == 0 %}
90
+ {{ errorMessage('No items found') }}
91
+ {% endif %}
92
+
93
+ {% for item in data %}
94
+ {% if item.quantity <= 0 %}
95
+ {{ errorMessage('Invalid quantity for ' ~ item.name) }}
96
+ {% endif %}
97
+ {% endfor %}
98
+ ```
99
+
100
+ **processing_code/calculation.bfy**:
101
+ ```twig
102
+ {% set total = 0 %}
103
+ {% for item in data %}
104
+ {% set total = total + (item.price * item.quantity) %}
105
+ {% endfor %}
106
+ {{ setValue('total', total) }}
107
+ ```
108
+
109
+ ## When to Use
110
+
111
+ Use file splitting when:
112
+ - A `.bfy` file has multiple distinct logical sections
113
+ - The file is too large to navigate easily
114
+ - You want to organize code by functionality (validation, calculation, rendering, etc.)
115
+
116
+ ## Technical Details
117
+
118
+ | Function | Description |
119
+ |----------|-------------|
120
+ | `splitBfyFile()` | Splits a file with part markers into container + parts folder |
121
+ | `mergeBfyFile()` | Merges parts back into single content for upload |
122
+ | `smartReadBfyContent()` | Automatically merges split files when reading |
123
+ | `hasSplitMarkers()` | Checks if content has `{# --- part: ... --- #}` markers |
124
+ | `hasIncludeMarkers()` | Checks if content has `{# --- include: ... --- #}` markers |
125
+
126
+ > **Note:** The splitting/merging is handled automatically by the CLI. You only need to add the part markers to your code.