cxtms 1.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +384 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4784 -0
- package/dist/cli.js.map +1 -0
- package/dist/extractUtils.d.ts +11 -0
- package/dist/extractUtils.d.ts.map +1 -0
- package/dist/extractUtils.js +19 -0
- package/dist/extractUtils.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/schemaLoader.d.ts +17 -0
- package/dist/utils/schemaLoader.d.ts.map +1 -0
- package/dist/utils/schemaLoader.js +134 -0
- package/dist/utils/schemaLoader.js.map +1 -0
- package/dist/validator.d.ts +72 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +432 -0
- package/dist/validator.js.map +1 -0
- package/dist/workflowValidator.d.ts +103 -0
- package/dist/workflowValidator.d.ts.map +1 -0
- package/dist/workflowValidator.js +753 -0
- package/dist/workflowValidator.js.map +1 -0
- package/package.json +51 -0
- package/schemas/actions/all.json +27 -0
- package/schemas/actions/clipboard.json +46 -0
- package/schemas/actions/confirm.json +21 -0
- package/schemas/actions/consoleLog.json +16 -0
- package/schemas/actions/dialog.json +25 -0
- package/schemas/actions/fileDownload.json +16 -0
- package/schemas/actions/forEach.json +31 -0
- package/schemas/actions/if.json +12 -0
- package/schemas/actions/mutation.json +25 -0
- package/schemas/actions/navigate.json +18 -0
- package/schemas/actions/navigateBack.json +22 -0
- package/schemas/actions/navigateBackOrClose.json +21 -0
- package/schemas/actions/notification.json +19 -0
- package/schemas/actions/openBarcodeScanner.json +104 -0
- package/schemas/actions/query.json +32 -0
- package/schemas/actions/refresh.json +13 -0
- package/schemas/actions/resetDirtyState.json +22 -0
- package/schemas/actions/setFields.json +21 -0
- package/schemas/actions/setStore.json +13 -0
- package/schemas/actions/validateForm.json +15 -0
- package/schemas/actions/workflow.json +24 -0
- package/schemas/components/README.md +147 -0
- package/schemas/components/appComponent.json +58 -0
- package/schemas/components/barcodeScanner.json +69 -0
- package/schemas/components/button.json +123 -0
- package/schemas/components/calendar.json +489 -0
- package/schemas/components/card.json +176 -0
- package/schemas/components/collection.json +54 -0
- package/schemas/components/dataGrid.json +119 -0
- package/schemas/components/datasource.json +151 -0
- package/schemas/components/dropdown.json +57 -0
- package/schemas/components/field-collection.json +618 -0
- package/schemas/components/field.json +265 -0
- package/schemas/components/form.json +234 -0
- package/schemas/components/index.json +71 -0
- package/schemas/components/layout.json +69 -0
- package/schemas/components/module.json +167 -0
- package/schemas/components/navDropdown.json +36 -0
- package/schemas/components/navbar.json +78 -0
- package/schemas/components/navbarItem.json +28 -0
- package/schemas/components/navbarLink.json +36 -0
- package/schemas/components/row.json +31 -0
- package/schemas/components/slot.json +30 -0
- package/schemas/components/tab.json +34 -0
- package/schemas/components/tabs.json +35 -0
- package/schemas/components/timeline.json +172 -0
- package/schemas/components/timelineGrid.json +328 -0
- package/schemas/fields/README.md +66 -0
- package/schemas/fields/attachment.json +156 -0
- package/schemas/fields/autocomplete-googleplaces.json +130 -0
- package/schemas/fields/checkbox.json +82 -0
- package/schemas/fields/date.json +88 -0
- package/schemas/fields/datetime.json +75 -0
- package/schemas/fields/email.json +75 -0
- package/schemas/fields/index.json +53 -0
- package/schemas/fields/number.json +91 -0
- package/schemas/fields/password.json +70 -0
- package/schemas/fields/radio.json +94 -0
- package/schemas/fields/rangedatetime.json +56 -0
- package/schemas/fields/select-async.json +334 -0
- package/schemas/fields/select.json +115 -0
- package/schemas/fields/tel.json +79 -0
- package/schemas/fields/text.json +86 -0
- package/schemas/fields/textarea.json +95 -0
- package/schemas/fields/time.json +91 -0
- package/schemas/fields/url.json +74 -0
- package/schemas/schema.graphql +12248 -0
- package/schemas/schemas.json +610 -0
- package/schemas/workflows/activity.json +96 -0
- package/schemas/workflows/common/condition.json +48 -0
- package/schemas/workflows/common/expression.json +76 -0
- package/schemas/workflows/common/mapping.json +173 -0
- package/schemas/workflows/common/step.json +38 -0
- package/schemas/workflows/flow/aggregation.json +44 -0
- package/schemas/workflows/flow/entity.json +129 -0
- package/schemas/workflows/flow/state.json +105 -0
- package/schemas/workflows/flow/transition.json +143 -0
- package/schemas/workflows/input.json +122 -0
- package/schemas/workflows/output.json +61 -0
- package/schemas/workflows/schedule.json +26 -0
- package/schemas/workflows/tasks/accounting-transaction.json +95 -0
- package/schemas/workflows/tasks/action-event.json +65 -0
- package/schemas/workflows/tasks/all.json +152 -0
- package/schemas/workflows/tasks/appmodule.json +56 -0
- package/schemas/workflows/tasks/attachment.json +97 -0
- package/schemas/workflows/tasks/authentication.json +86 -0
- package/schemas/workflows/tasks/caching.json +68 -0
- package/schemas/workflows/tasks/charge.json +92 -0
- package/schemas/workflows/tasks/commodity.json +92 -0
- package/schemas/workflows/tasks/contact-address.json +72 -0
- package/schemas/workflows/tasks/contact-payment-method.json +72 -0
- package/schemas/workflows/tasks/contact.json +82 -0
- package/schemas/workflows/tasks/csv.json +81 -0
- package/schemas/workflows/tasks/document-render.json +105 -0
- package/schemas/workflows/tasks/document-send.json +84 -0
- package/schemas/workflows/tasks/edi.json +157 -0
- package/schemas/workflows/tasks/email-send.json +110 -0
- package/schemas/workflows/tasks/error.json +72 -0
- package/schemas/workflows/tasks/export.json +90 -0
- package/schemas/workflows/tasks/filetransfer.json +102 -0
- package/schemas/workflows/tasks/flow-transition.json +68 -0
- package/schemas/workflows/tasks/foreach.json +69 -0
- package/schemas/workflows/tasks/generic.json +47 -0
- package/schemas/workflows/tasks/graphql.json +78 -0
- package/schemas/workflows/tasks/httpRequest.json +161 -0
- package/schemas/workflows/tasks/import.json +64 -0
- package/schemas/workflows/tasks/inventory.json +67 -0
- package/schemas/workflows/tasks/job.json +88 -0
- package/schemas/workflows/tasks/log.json +73 -0
- package/schemas/workflows/tasks/map.json +58 -0
- package/schemas/workflows/tasks/movement.json +54 -0
- package/schemas/workflows/tasks/note.json +59 -0
- package/schemas/workflows/tasks/number.json +65 -0
- package/schemas/workflows/tasks/order-tracking-event.json +109 -0
- package/schemas/workflows/tasks/order.json +139 -0
- package/schemas/workflows/tasks/payment.json +85 -0
- package/schemas/workflows/tasks/pdf-document.json +60 -0
- package/schemas/workflows/tasks/postal-codes.json +92 -0
- package/schemas/workflows/tasks/resolve-timezone.json +65 -0
- package/schemas/workflows/tasks/setVariable.json +76 -0
- package/schemas/workflows/tasks/switch.json +75 -0
- package/schemas/workflows/tasks/template.json +73 -0
- package/schemas/workflows/tasks/tracking-event.json +137 -0
- package/schemas/workflows/tasks/transmission.json +185 -0
- package/schemas/workflows/tasks/unzip-file.json +68 -0
- package/schemas/workflows/tasks/user.json +70 -0
- package/schemas/workflows/tasks/validation.json +99 -0
- package/schemas/workflows/tasks/while.json +53 -0
- package/schemas/workflows/tasks/workflow-execute.json +82 -0
- package/schemas/workflows/trigger.json +90 -0
- package/schemas/workflows/variable.json +46 -0
- package/schemas/workflows/workflow.json +335 -0
- package/scripts/postinstall.js +291 -0
- package/scripts/setup-vscode.js +80 -0
- package/skills/cxtms-developer/SKILL.md +118 -0
- package/skills/cxtms-developer/ref-cli-auth.md +120 -0
- package/skills/cxtms-developer/ref-entity-accounting.md +180 -0
- package/skills/cxtms-developer/ref-entity-commodity.md +239 -0
- package/skills/cxtms-developer/ref-entity-contact.md +163 -0
- package/skills/cxtms-developer/ref-entity-geography.md +154 -0
- package/skills/cxtms-developer/ref-entity-job.md +77 -0
- package/skills/cxtms-developer/ref-entity-notification.md +85 -0
- package/skills/cxtms-developer/ref-entity-order-sub.md +160 -0
- package/skills/cxtms-developer/ref-entity-order.md +183 -0
- package/skills/cxtms-developer/ref-entity-organization.md +41 -0
- package/skills/cxtms-developer/ref-entity-rate.md +182 -0
- package/skills/cxtms-developer/ref-entity-shared.md +176 -0
- package/skills/cxtms-developer/ref-entity-warehouse.md +115 -0
- package/skills/cxtms-developer/ref-graphql-query.md +309 -0
- package/skills/cxtms-module-builder/SKILL.md +477 -0
- package/skills/cxtms-module-builder/ref-components-data.md +293 -0
- package/skills/cxtms-module-builder/ref-components-display.md +411 -0
- package/skills/cxtms-module-builder/ref-components-forms.md +369 -0
- package/skills/cxtms-module-builder/ref-components-interactive.md +317 -0
- package/skills/cxtms-module-builder/ref-components-layout.md +390 -0
- package/skills/cxtms-module-builder/ref-components-specialized.md +477 -0
- package/skills/cxtms-workflow-builder/SKILL.md +438 -0
- package/skills/cxtms-workflow-builder/ref-accounting.md +66 -0
- package/skills/cxtms-workflow-builder/ref-communication.md +169 -0
- package/skills/cxtms-workflow-builder/ref-entity.md +342 -0
- package/skills/cxtms-workflow-builder/ref-expressions-ncalc.md +128 -0
- package/skills/cxtms-workflow-builder/ref-expressions-template.md +161 -0
- package/skills/cxtms-workflow-builder/ref-filetransfer.md +80 -0
- package/skills/cxtms-workflow-builder/ref-flow.md +210 -0
- package/skills/cxtms-workflow-builder/ref-other.md +157 -0
- package/skills/cxtms-workflow-builder/ref-query.md +105 -0
- package/skills/cxtms-workflow-builder/ref-utilities.md +417 -0
- package/templates/module-configuration.yaml +44 -0
- package/templates/module-form.yaml +152 -0
- package/templates/module-grid.yaml +229 -0
- package/templates/module-select.yaml +139 -0
- package/templates/module.yaml +84 -0
- package/templates/workflow-api-tracking.yaml +189 -0
- package/templates/workflow-basic.yaml +76 -0
- package/templates/workflow-document.yaml +155 -0
- package/templates/workflow-entity-trigger.yaml +90 -0
- package/templates/workflow-ftp-edi.yaml +158 -0
- package/templates/workflow-ftp-tracking.yaml +161 -0
- package/templates/workflow-mcp-tool.yaml +112 -0
- package/templates/workflow-public-api.yaml +135 -0
- package/templates/workflow-scheduled-execute.yaml +75 -0
- package/templates/workflow-scheduled.yaml +125 -0
- package/templates/workflow-utility.yaml +96 -0
- package/templates/workflow-webhook.yaml +128 -0
- package/templates/workflow.yaml +140 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# Utilities Tasks Reference
|
|
2
|
+
|
|
3
|
+
## Available Tasks
|
|
4
|
+
|
|
5
|
+
| Task | Description |
|
|
6
|
+
|------|-------------|
|
|
7
|
+
| `Utilities/SetVariable@1` | Set variables in workflow scope (activity + global) |
|
|
8
|
+
| `Utilities/Log@1` | Log all task variables to workflow logger |
|
|
9
|
+
| `Utilities/Error@1` | Throw a workflow error with message |
|
|
10
|
+
| `Utilities/HttpRequest@1` | HTTP request (GET/POST/PUT/PATCH/DELETE) |
|
|
11
|
+
| `Utilities/Map@1` | Map/extract variables from inputs |
|
|
12
|
+
| `Utilities/Template@1` | Handlebars template rendering |
|
|
13
|
+
| `Utilities/Import@1` | Import data |
|
|
14
|
+
| `Utilities/Export@1` | Export data |
|
|
15
|
+
| `Utilities/CsvParse@1` | Parse CSV content (supports columns, distinct) |
|
|
16
|
+
| `Utilities/GroupBy@1` | Group collection by fields |
|
|
17
|
+
| `Utilities/MoveFile@1` | Move file |
|
|
18
|
+
| `Utilities/ValidateReCaptcha` | Validate reCAPTCHA |
|
|
19
|
+
| `Utilities/ValidateHMAC` | Validate HMAC signatures |
|
|
20
|
+
| `Utilities/UnzipFile@1` | Extract files from ZIP archive (local path or URL) |
|
|
21
|
+
| `Utilities/ResolveTimezone@1` | Resolve IANA timezone and UTC offset from lat/lng coordinates |
|
|
22
|
+
|
|
23
|
+
## UnzipFile@1
|
|
24
|
+
|
|
25
|
+
Extracts files from a ZIP archive. Accepts a local file path (from `saveToFile` or previous step) or a URL (`file://`, `http://`, `https://`). Files are extracted to a workflow-scoped temp directory with auto-cleanup.
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
- task: "Utilities/UnzipFile@1"
|
|
29
|
+
name: ExtractArchive
|
|
30
|
+
inputs:
|
|
31
|
+
filePath: "{{ Main?.DownloadArchive?.result?.FilePath? }}"
|
|
32
|
+
filePattern: "*.csv"
|
|
33
|
+
outputs:
|
|
34
|
+
- name: files
|
|
35
|
+
mapping: "Files?"
|
|
36
|
+
- name: count
|
|
37
|
+
mapping: "Count?"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Inputs:** `filePath` (string, local path) OR `fileUrl` (string, URL — `file://`, `http://`, `https://`). Optional: `filePattern` (glob pattern, e.g. `*.csv`, `data_*.json`).
|
|
41
|
+
**Outputs:** `Files` (string[] — full paths to extracted files), `Count` (int — number of matched files).
|
|
42
|
+
Provide one of `filePath` or `fileUrl`. Common pattern: HttpRequest with `saveToFile: true` → UnzipFile with `filePath`.
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
# Download + unzip + import pipeline
|
|
46
|
+
- task: "Utilities/HttpRequest@1"
|
|
47
|
+
name: Download
|
|
48
|
+
inputs:
|
|
49
|
+
url: "{{ downloadUrl }}"
|
|
50
|
+
method: GET
|
|
51
|
+
saveToFile: true
|
|
52
|
+
outputs:
|
|
53
|
+
- name: result
|
|
54
|
+
mapping: "response?"
|
|
55
|
+
|
|
56
|
+
- task: "Utilities/UnzipFile@1"
|
|
57
|
+
name: Unzip
|
|
58
|
+
inputs:
|
|
59
|
+
filePath: "{{ Main?.Download?.result?.FilePath? }}"
|
|
60
|
+
filePattern: "*.csv"
|
|
61
|
+
outputs:
|
|
62
|
+
- name: files
|
|
63
|
+
mapping: "Files?"
|
|
64
|
+
|
|
65
|
+
- task: foreach
|
|
66
|
+
name: ProcessFiles
|
|
67
|
+
collection: "Main?.Unzip?.files?"
|
|
68
|
+
steps:
|
|
69
|
+
- task: "Utilities/Import@1"
|
|
70
|
+
name: ImportFile
|
|
71
|
+
inputs:
|
|
72
|
+
fileUrl: "file://{{ item }}"
|
|
73
|
+
format: "csv"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## ResolveTimezone@1
|
|
79
|
+
|
|
80
|
+
Resolves IANA timezone ID and current UTC offset from geographic coordinates using offline boundary lookup (GeoTimeZone).
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
- task: "Utilities/ResolveTimezone@1"
|
|
84
|
+
name: ResolveTimezone
|
|
85
|
+
inputs:
|
|
86
|
+
latitude: "{{ postalCode.location.y }}"
|
|
87
|
+
longitude: "{{ postalCode.location.x }}"
|
|
88
|
+
outputs:
|
|
89
|
+
- name: tz
|
|
90
|
+
mapping: "timezoneId?"
|
|
91
|
+
- name: offset
|
|
92
|
+
mapping: "utcOffset?"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Inputs:** `latitude` (double/string, required), `longitude` (double/string, required)
|
|
96
|
+
**Outputs:** `timezoneId` (string, e.g. `America/Chicago`), `utcOffset` (double, e.g. `-5`)
|
|
97
|
+
Throws `WorkflowRuntimeException` if lat/lng missing or unparseable.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## SetVariable@1
|
|
102
|
+
|
|
103
|
+
Sets variables directly into both activity and global scope. No outputs — the side effect IS the variable setting.
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
- task: "Utilities/SetVariable@1"
|
|
107
|
+
name: SetResult
|
|
108
|
+
inputs:
|
|
109
|
+
variables:
|
|
110
|
+
- name: processResult
|
|
111
|
+
value:
|
|
112
|
+
success: true
|
|
113
|
+
orderId: "{{ inputs.orderId }}"
|
|
114
|
+
- name: hasMore
|
|
115
|
+
value:
|
|
116
|
+
expression: "[offset] < [Data?.FetchPage?.result?.totalCount?]"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Each variable entry has `name` (string) and `value` (any type, supports expression directives).
|
|
120
|
+
|
|
121
|
+
## Log@1
|
|
122
|
+
|
|
123
|
+
Logs all task variables (everything in the step's scoped variables) to the workflow file logger.
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
- task: "Utilities/Log@1"
|
|
127
|
+
name: LogInfo
|
|
128
|
+
inputs:
|
|
129
|
+
message: "Processing order: {{ Data?.GetOrder?.order?.orderNumber? }}"
|
|
130
|
+
level: Information
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Levels: `Debug`, `Information`, `Warning`, `Error`.
|
|
134
|
+
|
|
135
|
+
## Error@1
|
|
136
|
+
|
|
137
|
+
Throws a workflow error that halts execution (unless `continueOnError: true` on a parent step).
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
- task: "Utilities/Error@1"
|
|
141
|
+
name: ThrowValidationError
|
|
142
|
+
conditions:
|
|
143
|
+
- expression: "isNullOrEmpty([Data?.GetOrder?.order?]) = true"
|
|
144
|
+
inputs:
|
|
145
|
+
message: "Order not found: {{ inputs.orderId }}"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## HttpRequest@1
|
|
149
|
+
|
|
150
|
+
Performs HTTP requests to external APIs.
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
- task: "Utilities/HttpRequest@1"
|
|
154
|
+
name: CallApi
|
|
155
|
+
inputs:
|
|
156
|
+
url: "{{ apiBaseUrl }}/api/v1/orders"
|
|
157
|
+
method: POST
|
|
158
|
+
contentType: "application/json"
|
|
159
|
+
headers:
|
|
160
|
+
- name: "Authorization"
|
|
161
|
+
value: "Bearer {{ apiToken }}"
|
|
162
|
+
body:
|
|
163
|
+
orderId: "{{ inputs.orderId }}"
|
|
164
|
+
outputs:
|
|
165
|
+
- name: result
|
|
166
|
+
mapping: "response?.body?"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Response structure**: The task returns a `Dictionary<string, object>` (case-insensitive) with key `response`. The response contains `StatusCode`, `Headers`, and `Body` (PascalCase in C#, but access is case-insensitive). Use `response?.body?` to get the parsed body. You can drill deeper: `response?.body?.output?`, `response?.body?.items?[0]?`.
|
|
170
|
+
|
|
171
|
+
**Case sensitivity**: Variable paths go through `Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)` — so `body` and `Body` both work. Convention: use lowercase `body`.
|
|
172
|
+
|
|
173
|
+
Response available at `ActivityName?.CallApi?.result?`.
|
|
174
|
+
|
|
175
|
+
**`saveToFile` mode**: When `saveToFile: true`, the response body is saved to a temp file instead of being returned in memory. The response object changes to `{ StatusCode, Headers, FilePath }`. Use this for large file downloads, then pass `FilePath` to downstream tasks like `UnzipFile` or `Import`.
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
- task: "Utilities/HttpRequest@1"
|
|
179
|
+
name: DownloadArchive
|
|
180
|
+
inputs:
|
|
181
|
+
url: "{{ downloadUrl }}"
|
|
182
|
+
method: GET
|
|
183
|
+
saveToFile: true
|
|
184
|
+
outputs:
|
|
185
|
+
- name: result
|
|
186
|
+
mapping: "response?"
|
|
187
|
+
# result.FilePath contains the temp file path
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Action events**: When an HTTP request operates on a specific entity (e.g., sending parcel info for an order), enable `actionEvents` in the inputs so the system can track and notify about the request. Include `eventDataExt` with the entity ID to link the event to the entity.
|
|
191
|
+
|
|
192
|
+
```yaml
|
|
193
|
+
- task: "Utilities/HttpRequest@1"
|
|
194
|
+
name: CallCarrierApi
|
|
195
|
+
inputs:
|
|
196
|
+
actionEvents:
|
|
197
|
+
enabled: true
|
|
198
|
+
eventName: "carrier.sendParcelInfo"
|
|
199
|
+
eventDataExt:
|
|
200
|
+
orderId: "{{ inputs.orderId }}"
|
|
201
|
+
url: "{{ carrierConfig?.baseUrl? }}/api/shipments"
|
|
202
|
+
method: POST
|
|
203
|
+
contentType: "application/json"
|
|
204
|
+
body:
|
|
205
|
+
trackingNumber: "{{ Data?.GetOrder?.order?.trackingNumber? }}"
|
|
206
|
+
outputs:
|
|
207
|
+
- name: result
|
|
208
|
+
mapping: "response?.body?"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Map@1
|
|
212
|
+
|
|
213
|
+
Extracts/reshapes data from variables into new variables.
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
- task: "Utilities/Map@1"
|
|
217
|
+
name: MapData
|
|
218
|
+
inputs:
|
|
219
|
+
variables:
|
|
220
|
+
- name: orderNumber
|
|
221
|
+
value: "{{ Data?.GetOrder?.order?.orderNumber? }}"
|
|
222
|
+
- name: customerName
|
|
223
|
+
value: "{{ Data?.GetOrder?.order?.customer?.name? }}"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Template@1
|
|
227
|
+
|
|
228
|
+
Renders a Handlebars template string with data.
|
|
229
|
+
|
|
230
|
+
```yaml
|
|
231
|
+
- task: "Utilities/Template@1"
|
|
232
|
+
name: RenderMessage
|
|
233
|
+
inputs:
|
|
234
|
+
template: "Hello {{name}}, your order {{orderNumber}} is {{status}}."
|
|
235
|
+
data:
|
|
236
|
+
name: "{{ Data?.GetOrder?.order?.customer?.name? }}"
|
|
237
|
+
orderNumber: "{{ Data?.GetOrder?.order?.orderNumber? }}"
|
|
238
|
+
status: "{{ Data?.GetOrder?.order?.status? }}"
|
|
239
|
+
outputs:
|
|
240
|
+
- name: message
|
|
241
|
+
mapping: "result?"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## CsvParse@1
|
|
245
|
+
|
|
246
|
+
Parses CSV/TSV data from a URL (file://, http://, https://). Headers are trimmed of whitespace, BOM, and special characters and converted to camelCase. Blank rows are skipped.
|
|
247
|
+
|
|
248
|
+
**Inputs:**
|
|
249
|
+
|
|
250
|
+
| Input | Type | Required | Description |
|
|
251
|
+
|-------|------|----------|-------------|
|
|
252
|
+
| `url` | string | yes | URL to CSV file |
|
|
253
|
+
| `hasHeader` | bool | no | `true` (default). Whether first row has headers |
|
|
254
|
+
| `delimiter` | string | no | `,` (default). Field delimiter. Use `\t` for tab |
|
|
255
|
+
| `columns` | string[] | no | Explicit column names; overrides file header |
|
|
256
|
+
| `distinct` | string[] | no | Deduplicate by these fields; output projected to only these fields |
|
|
257
|
+
|
|
258
|
+
**Outputs:** `records` (array of dicts), `count` (int), `hasRecords` (boolean).
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
- task: "Utilities/CsvParse@1"
|
|
262
|
+
name: ParseCsv
|
|
263
|
+
inputs:
|
|
264
|
+
url: "{{ Data?.DownloadFile?.filePath? }}"
|
|
265
|
+
hasHeader: true
|
|
266
|
+
outputs:
|
|
267
|
+
- name: rows
|
|
268
|
+
mapping: "records?"
|
|
269
|
+
|
|
270
|
+
- task: "Utilities/CsvParse@1"
|
|
271
|
+
name: ParsePostalCodes
|
|
272
|
+
inputs:
|
|
273
|
+
url: "{{ Data?.UnzipFiles?.filePath? }}"
|
|
274
|
+
delimiter: "\t"
|
|
275
|
+
columns: ["CountryCode", "Code", "PlaceName", "StateName", "StateCode"]
|
|
276
|
+
outputs:
|
|
277
|
+
- name: postalCodes
|
|
278
|
+
mapping: "records?"
|
|
279
|
+
|
|
280
|
+
- task: "Utilities/CsvParse@1"
|
|
281
|
+
name: ExtractDistinctStates
|
|
282
|
+
inputs:
|
|
283
|
+
url: "{{ fileUrl }}"
|
|
284
|
+
distinct: ["stateCode", "stateName", "countryCode"]
|
|
285
|
+
outputs:
|
|
286
|
+
- name: states
|
|
287
|
+
mapping: "records?"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Export@1
|
|
291
|
+
|
|
292
|
+
Exports data to file format.
|
|
293
|
+
|
|
294
|
+
```yaml
|
|
295
|
+
- task: "Utilities/Export@1"
|
|
296
|
+
name: ExportData
|
|
297
|
+
inputs:
|
|
298
|
+
data: "{{ Data?.GetOrders?.result?.items? }}"
|
|
299
|
+
format: "csv"
|
|
300
|
+
outputs:
|
|
301
|
+
- name: file
|
|
302
|
+
mapping: "file?"
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Import@1
|
|
306
|
+
|
|
307
|
+
Imports data from file content or URL. Supports `file://` URLs for local files (e.g. from UnzipFile output).
|
|
308
|
+
|
|
309
|
+
```yaml
|
|
310
|
+
- task: "Utilities/Import@1"
|
|
311
|
+
name: ImportData
|
|
312
|
+
inputs:
|
|
313
|
+
content: "{{ fileContent }}"
|
|
314
|
+
format: "csv"
|
|
315
|
+
outputs:
|
|
316
|
+
- name: data
|
|
317
|
+
mapping: "data?"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```yaml
|
|
321
|
+
# Import from local file (e.g. extracted from ZIP)
|
|
322
|
+
- task: "Utilities/Import@1"
|
|
323
|
+
name: ImportLocalFile
|
|
324
|
+
inputs:
|
|
325
|
+
fileUrl: "file://{{ localFilePath }}"
|
|
326
|
+
format: "csv"
|
|
327
|
+
outputs:
|
|
328
|
+
- name: data
|
|
329
|
+
mapping: "data?"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**`file://` URL support**: Import, Order/Import, PostalCodes/Import, and Notes/Import all accept `file://` URLs via UrlStreamHelper. This enables pipeline patterns: HttpRequest (saveToFile) → UnzipFile → Import (file://).
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## GroupBy@1
|
|
337
|
+
|
|
338
|
+
Groups a collection of dictionaries by one or more fields. Produces `{ key, values }` groups for batch processing.
|
|
339
|
+
|
|
340
|
+
**Inputs:**
|
|
341
|
+
|
|
342
|
+
| Input | Type | Required | Description |
|
|
343
|
+
|-------|------|----------|-------------|
|
|
344
|
+
| `collection` | List<Dictionary> | yes | Records to group |
|
|
345
|
+
| `by` | string[] | yes | Field names to group by (case-insensitive) |
|
|
346
|
+
|
|
347
|
+
**Outputs:** `items` (array of `{ key: {field: value, ...}, values: [...] }`), `count` (int).
|
|
348
|
+
|
|
349
|
+
```yaml
|
|
350
|
+
- task: "Utilities/GroupBy@1"
|
|
351
|
+
name: GroupByCustomer
|
|
352
|
+
inputs:
|
|
353
|
+
collection: "{{ Data?.ParseCsv?.records? }}"
|
|
354
|
+
by: ["customerId"]
|
|
355
|
+
outputs:
|
|
356
|
+
- name: groups
|
|
357
|
+
mapping: "items?"
|
|
358
|
+
- name: groupCount
|
|
359
|
+
mapping: "count?"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Import Tasks
|
|
365
|
+
|
|
366
|
+
Import tasks handle bulk data ingestion. All support `file://` URLs for chaining with UnzipFile.
|
|
367
|
+
|
|
368
|
+
### Order/Import@1
|
|
369
|
+
|
|
370
|
+
Imports orders from CSV, JSON, or XLSX. Inputs: `organizationId` (auto-injected), `fileUrl`/`stream`/`orders` (one required), `fileType` (auto-detected), `options` (match-by, update behavior).
|
|
371
|
+
|
|
372
|
+
### States/Import@1
|
|
373
|
+
|
|
374
|
+
Imports US states/provinces. Inputs: `organizationId`, `fileUrl`/`stream`/`states`, `matchByFields`, `updateIfExists`. Deduplicates by match key.
|
|
375
|
+
|
|
376
|
+
### PostalCodes/Import@1
|
|
377
|
+
|
|
378
|
+
Imports postal/ZIP codes. Inputs: `organizationId`, `fileUrl`/`stream`/`postalCodes`, `matchByFields`. Match-key fields protected from overwrite.
|
|
379
|
+
|
|
380
|
+
### TrackingEvent/Import@1
|
|
381
|
+
|
|
382
|
+
Imports tracking events for an order. Inputs: `orderId`, `events`, `matchByFields` (default: `["eventDefinitionName", "eventDate"]`), `skipIfExists`, `createEventDefinitions`. Auto-links commodities via `CommodityId`.
|
|
383
|
+
|
|
384
|
+
```yaml
|
|
385
|
+
# Full ZIP-to-import pipeline
|
|
386
|
+
- task: "Utilities/HttpRequest@1"
|
|
387
|
+
name: Download
|
|
388
|
+
inputs:
|
|
389
|
+
url: "{{ downloadUrl }}"
|
|
390
|
+
method: GET
|
|
391
|
+
saveToFile: true
|
|
392
|
+
|
|
393
|
+
- task: "Utilities/UnzipFile@1"
|
|
394
|
+
name: Unzip
|
|
395
|
+
inputs:
|
|
396
|
+
filePath: "{{ Main?.Download?.result?.FilePath? }}"
|
|
397
|
+
filePattern: "*.csv"
|
|
398
|
+
|
|
399
|
+
- task: "Utilities/CsvParse@1"
|
|
400
|
+
name: Parse
|
|
401
|
+
inputs:
|
|
402
|
+
url: "file://{{ Main?.Unzip?.files?[0] }}"
|
|
403
|
+
distinct: ["stateCode", "stateName", "countryCode"]
|
|
404
|
+
|
|
405
|
+
- task: "States/Import@1"
|
|
406
|
+
name: ImportStates
|
|
407
|
+
inputs:
|
|
408
|
+
organizationId: "{{ organizationId }}"
|
|
409
|
+
states: "{{ Main?.Parse?.records? }}"
|
|
410
|
+
|
|
411
|
+
- task: "PostalCodes/Import@1"
|
|
412
|
+
name: ImportPostalCodes
|
|
413
|
+
inputs:
|
|
414
|
+
organizationId: "{{ organizationId }}"
|
|
415
|
+
fileUrl: "file://{{ Main?.Unzip?.files?[0] }}"
|
|
416
|
+
fileType: "csv"
|
|
417
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# {{displayName}} Configuration Module
|
|
2
|
+
# Generated by cxtms create module --template configuration
|
|
3
|
+
|
|
4
|
+
module:
|
|
5
|
+
name: "{{displayNameNoSpaces}}"
|
|
6
|
+
appModuleId: "{{uuid}}"
|
|
7
|
+
displayName:
|
|
8
|
+
en-US: "{{displayName}}"
|
|
9
|
+
description:
|
|
10
|
+
en-US: "{{displayName}} configuration module"
|
|
11
|
+
application: System
|
|
12
|
+
|
|
13
|
+
components:
|
|
14
|
+
- name: Configurations/{{displayNameNoSpaces}}
|
|
15
|
+
displayName:
|
|
16
|
+
en-US: "{{displayName}} Config"
|
|
17
|
+
platforms:
|
|
18
|
+
- web
|
|
19
|
+
layout:
|
|
20
|
+
component: layout
|
|
21
|
+
name: {{displayNameNoSpaces}}ConfigLayout
|
|
22
|
+
props:
|
|
23
|
+
cols: 1
|
|
24
|
+
title:
|
|
25
|
+
en-US: "{{displayName}} Configuration"
|
|
26
|
+
icon: Create
|
|
27
|
+
permission: System/OrganizationConfigs/Update
|
|
28
|
+
children:
|
|
29
|
+
- component: field
|
|
30
|
+
name: customValues.enabled
|
|
31
|
+
props:
|
|
32
|
+
type: checkbox
|
|
33
|
+
label:
|
|
34
|
+
en-US: "Enable {{displayName}}"
|
|
35
|
+
|
|
36
|
+
configurations:
|
|
37
|
+
- configName: "apps.{{name}}"
|
|
38
|
+
displayName:
|
|
39
|
+
en-US: "{{displayName}}"
|
|
40
|
+
description:
|
|
41
|
+
en-US: "{{displayName}} configuration"
|
|
42
|
+
component: "Configurations/{{displayNameNoSpaces}}"
|
|
43
|
+
defaultValue:
|
|
44
|
+
enabled: false
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# {{displayName}} Form Module
|
|
2
|
+
# Generated by cxtms create module --template form
|
|
3
|
+
|
|
4
|
+
module:
|
|
5
|
+
name: "{{displayNameNoSpaces}}"
|
|
6
|
+
appModuleId: "{{uuid}}"
|
|
7
|
+
displayName:
|
|
8
|
+
en-US: "{{displayName}}"
|
|
9
|
+
description:
|
|
10
|
+
en-US: "{{displayName}} module"
|
|
11
|
+
application: System
|
|
12
|
+
filePath: "{{fileName}}"
|
|
13
|
+
|
|
14
|
+
components:
|
|
15
|
+
- name: {{displayNameNoSpaces}}/Detail
|
|
16
|
+
displayName:
|
|
17
|
+
en-US: "{{displayName}} Detail"
|
|
18
|
+
platforms:
|
|
19
|
+
- web
|
|
20
|
+
layout:
|
|
21
|
+
component: form
|
|
22
|
+
name: {{name}}Form
|
|
23
|
+
props:
|
|
24
|
+
title:
|
|
25
|
+
en-US: "{{displayName}}"
|
|
26
|
+
toolbar:
|
|
27
|
+
- component: button
|
|
28
|
+
name: saveBtn
|
|
29
|
+
props:
|
|
30
|
+
label:
|
|
31
|
+
en-US: "Save"
|
|
32
|
+
icon: check
|
|
33
|
+
options:
|
|
34
|
+
type: submit
|
|
35
|
+
variant: primary
|
|
36
|
+
- component: button
|
|
37
|
+
name: cancelBtn
|
|
38
|
+
props:
|
|
39
|
+
label:
|
|
40
|
+
en-US: "Cancel"
|
|
41
|
+
icon: x
|
|
42
|
+
options:
|
|
43
|
+
variant: secondary
|
|
44
|
+
onClick:
|
|
45
|
+
- navigateBack:
|
|
46
|
+
fallback: "/{{name}}"
|
|
47
|
+
dirtyGuard:
|
|
48
|
+
enabled: true
|
|
49
|
+
title:
|
|
50
|
+
en-US: "Unsaved Changes"
|
|
51
|
+
message:
|
|
52
|
+
en-US: "You have unsaved changes. Are you sure you want to leave?"
|
|
53
|
+
confirmLabel:
|
|
54
|
+
en-US: "Leave"
|
|
55
|
+
cancelLabel:
|
|
56
|
+
en-US: "Stay"
|
|
57
|
+
queries:
|
|
58
|
+
- name: get{{displayNameNoSpaces}}
|
|
59
|
+
query:
|
|
60
|
+
command: |
|
|
61
|
+
query Get{{displayNameNoSpaces}}($organizationId: Int!, $id: Int!) {
|
|
62
|
+
{{name}}(organizationId: $organizationId, id: $id) {
|
|
63
|
+
id
|
|
64
|
+
name
|
|
65
|
+
description
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
variables:
|
|
69
|
+
organizationId: '\{{number organizationId}}'
|
|
70
|
+
id: '\{{number id}}'
|
|
71
|
+
initialValues:
|
|
72
|
+
fromQuery:
|
|
73
|
+
name: get{{displayNameNoSpaces}}
|
|
74
|
+
path: {{name}}
|
|
75
|
+
validationSchema:
|
|
76
|
+
name:
|
|
77
|
+
type: string
|
|
78
|
+
required: true
|
|
79
|
+
description:
|
|
80
|
+
type: string
|
|
81
|
+
onSubmit:
|
|
82
|
+
- mutation:
|
|
83
|
+
command: |
|
|
84
|
+
mutation Save{{displayNameNoSpaces}}($organizationId: Int!, $input: {{displayNameNoSpaces}}Input!) {
|
|
85
|
+
save{{displayNameNoSpaces}}(organizationId: $organizationId, input: $input) {
|
|
86
|
+
id
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
variables:
|
|
90
|
+
organizationId: '\{{number organizationId}}'
|
|
91
|
+
input: '\{{form}}'
|
|
92
|
+
onSuccess:
|
|
93
|
+
- notification:
|
|
94
|
+
message:
|
|
95
|
+
en-US: "{{displayName}} saved successfully"
|
|
96
|
+
type: success
|
|
97
|
+
- navigateBack:
|
|
98
|
+
fallback: "/{{name}}"
|
|
99
|
+
onError:
|
|
100
|
+
- notification:
|
|
101
|
+
message:
|
|
102
|
+
en-US: "Failed to save {{displayName}}"
|
|
103
|
+
type: error
|
|
104
|
+
children:
|
|
105
|
+
- component: field
|
|
106
|
+
name: name
|
|
107
|
+
props:
|
|
108
|
+
label:
|
|
109
|
+
en-US: "Name"
|
|
110
|
+
type: text
|
|
111
|
+
required: true
|
|
112
|
+
- component: field
|
|
113
|
+
name: description
|
|
114
|
+
props:
|
|
115
|
+
label:
|
|
116
|
+
en-US: "Description"
|
|
117
|
+
type: textarea
|
|
118
|
+
|
|
119
|
+
routes:
|
|
120
|
+
- name: detail
|
|
121
|
+
path: /{{name}}/:id
|
|
122
|
+
component: {{displayNameNoSpaces}}/Detail
|
|
123
|
+
props:
|
|
124
|
+
title:
|
|
125
|
+
en-US: "{{displayName}}"
|
|
126
|
+
|
|
127
|
+
entities:
|
|
128
|
+
- name: {{displayNameNoSpaces}}
|
|
129
|
+
entityKind: Other
|
|
130
|
+
displayName:
|
|
131
|
+
en-US: "{{displayName}}"
|
|
132
|
+
fields:
|
|
133
|
+
- name: name
|
|
134
|
+
displayName:
|
|
135
|
+
en-US: "Name"
|
|
136
|
+
fieldType: text
|
|
137
|
+
- name: description
|
|
138
|
+
displayName:
|
|
139
|
+
en-US: "Description"
|
|
140
|
+
fieldType: text
|
|
141
|
+
|
|
142
|
+
permissions:
|
|
143
|
+
- name: "{{displayNameNoSpaces}}/Read"
|
|
144
|
+
displayName:
|
|
145
|
+
en-US: "Read {{displayName}}"
|
|
146
|
+
roles:
|
|
147
|
+
- Admin
|
|
148
|
+
- name: "{{displayNameNoSpaces}}/Update"
|
|
149
|
+
displayName:
|
|
150
|
+
en-US: "Update {{displayName}}"
|
|
151
|
+
roles:
|
|
152
|
+
- Admin
|