@cxtms/cx-schema 1.7.4 → 1.7.6

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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: cx-core
3
3
  description: >
4
- Provides shared CargoXplorer entity field reference — domain entities, field names, enums, and customValues patterns.
4
+ Provides shared CXTMS entity field reference — domain entities, field names, enums, and customValues patterns.
5
5
  Use when the user asks about CX entity fields, enums, customValues, entity relationships, or needs domain reference for Orders, Contacts, Commodities, Jobs, etc.
6
6
  argument-hint: <entity name or question about fields>
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: cx-module
3
3
  description: >
4
- Generates schema-valid CargoXplorer app module YAML files (UI screens, forms, grids, routes).
4
+ Works with CXTMS app module YAML files — creates, modifies, fixes, validates, and deploys UI screens, forms, grids, and routes.
5
5
  Use when the user asks to create, modify, or fix a module YAML file, references *-module.yaml files, or asks about UI components/forms/grids/routes in a CX project.
6
6
  Not for workflow YAML files, TypeScript code, or non-YAML tasks.
7
7
  argument-hint: <description of what to build>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: cx-workflow
3
3
  description: >
4
- Generates schema-valid CargoXplorer workflow YAML files (standard process and Flow state machine workflows).
4
+ Works with CXTMS workflow YAML files — creates, modifies, fixes, validates, and deploys standard process and Flow state machine workflows.
5
5
  Use when the user asks to create, modify, or fix a workflow YAML file, references workflow/*.yaml files, or asks about workflow tasks/triggers/activities in a CX project.
6
6
  Not for module YAML files, TypeScript code, or non-YAML tasks.
7
7
  argument-hint: <description of what to build>
@@ -191,7 +191,8 @@ events: # Workflow-level event handlers
191
191
 
192
192
  ## Variable References (quick summary)
193
193
 
194
- For full reference: `!cat .claude/skills/cx-workflow/ref-expressions.md`
194
+ For template expressions and value directives: see [ref-expressions-template.md](.claude/skills/cx-workflow/ref-expressions-template.md)
195
+ For NCalc conditions and functions: see [ref-expressions-ncalc.md](.claude/skills/cx-workflow/ref-expressions-ncalc.md)
195
196
 
196
197
  **`{{ path }}`** — in step inputs. Single `{{ }}` returns raw object. Multiple returns string interpolation.
197
198
  **`[variable]`** — in conditions and `expression:` directives. NCalc syntax.
@@ -294,7 +295,8 @@ Implicit variable: `iteration` (zero-based).
294
295
 
295
296
  | Reference | Load |
296
297
  |-----------|------|
297
- | Expressions & Functions | `!cat .claude/skills/cx-workflow/ref-expressions.md` |
298
+ | Template Expressions & Value Directives | `!cat .claude/skills/cx-workflow/ref-expressions-template.md` |
299
+ | NCalc Expressions & Functions | `!cat .claude/skills/cx-workflow/ref-expressions-ncalc.md` |
298
300
  | Flow Workflows (state machines) | `!cat .claude/skills/cx-workflow/ref-flow.md` |
299
301
 
300
302
  ## Dynamic Schema Access (load on demand)
@@ -1,131 +1,16 @@
1
- # Variable References & Expressions
1
+ # NCalc Expressions & Functions
2
2
 
3
3
  ## Contents
4
- - Template Expressions: `{{ path }}` (in step inputs)
5
- - NCalc Expressions: `[variable]` (in conditions and expression directives)
6
- - Property Path Syntax (in collection, mapping, variable paths)
4
+ - NCalc expression syntax `[variable]` (in conditions and expression directives)
5
+ - Operators (comparison, logical, arithmetic, ternary, membership)
6
+ - Iterator variables (`[each.*]` and `[item.*]`)
7
+ - Collection functions (any, all, count, sum, first, last, distinct, groupBy, join, etc.)
8
+ - String functions (isNullOrEmpty, length, lower, upper, replace, format, base64, etc.)
9
+ - Date functions (now, parseDate, addDays, formatDate, dateFromUnix, etc.)
10
+ - Math functions (Abs, Ceiling, Floor, Round, Min, Max, etc.)
11
+ - Domain functions (convertWeight, convertDimension)
7
12
 
8
- There are **two distinct syntaxes** for referencing variables, used in different contexts.
9
-
10
- ## Template Expressions: `{{ path }}` (in step inputs)
11
-
12
- Used in step `inputs` values. Resolves variable paths from scoped variables.
13
-
14
- ```yaml
15
- inputs:
16
- orderId: "{{ inputs.orderId }}" # Simple reference
17
- url: "{{ chopinConfig.baseUrl }}/api/v1" # String interpolation
18
- order: "{{ Data.GetOrder.order }}" # Raw object (single {{ }})
19
- name: "Order {{ Data.GetOrder.order.orderNumber }}" # String interpolation (multiple)
20
- ```
21
-
22
- **Key behavior**: A single `{{ path }}` returns the **raw object** (preserving type). Multiple `{{ }}` in a string returns string interpolation (each resolved value is `.ToString()`).
23
-
24
- ### Type Converters (prefix in {{ }})
25
-
26
- ```yaml
27
- organizationId: "{{ int organizationId }}"
28
- amount: "{{ decimal totalAmount }}"
29
- isActive: "{{ bool isActive }}"
30
- flag: "{{ boolOrFalse someFlag }}" # null -> false
31
- flagOn: "{{ boolOrTrue someFlag }}" # null -> true
32
- notes: "{{ emptyIfNull notes }}" # null -> ""
33
- notes: "{{ nullIfEmpty notes }}" # "" or whitespace -> null
34
- config: "{{ fromJson configJsonString }}" # JSON string -> dict/array
35
- payload: "{{ toJson someObject }}" # object -> JSON string
36
- name: "{{ trim value }}"
37
- search: "{{ luceneString query }}" # escape & quote for Lucene
38
- ```
39
-
40
- | Converter | Returns | Null handling |
41
- |-----------|---------|---------------|
42
- | `string` | `string` | null. Reads `Stream` to string if value is Stream |
43
- | `int` | `int` | Throws on null |
44
- | `decimal` | `decimal` | Throws on null |
45
- | `bool` | `bool` | Throws on null |
46
- | `boolOrFalse` | `bool` | `false` if null |
47
- | `boolOrTrue` | `bool` | `true` if null |
48
- | `datetime` | `DateTime` | Throws on null |
49
- | `emptyIfNull` | same type | `""` if null, `0` for int?, `0m` for decimal? |
50
- | `nullIfEmpty` | same type | `null` if empty/whitespace string or empty collection |
51
- | `luceneString` | `string` | null |
52
- | `transliterate` | `string` | null (Unicode -> ASCII via Unidecode) |
53
- | `transliterateUa` | `string` | null (Ukrainian-specific rules) |
54
- | `fromJson` | `dict` or `array` | null. Empty string -> empty dict |
55
- | `toJson` | `string` | `""` if null |
56
- | `trim` | `string` | null |
57
-
58
- ### Value Directives (in YAML input mappings)
59
-
60
- **`expression`** -- Evaluate NCalc expression as a value:
61
- ```yaml
62
- amount:
63
- expression: "[price] * [quantity]"
64
- ```
65
-
66
- **`coalesce`** -- First non-null value from a list:
67
- ```yaml
68
- displayName:
69
- coalesce:
70
- - "{{ customer.name? }}"
71
- - "{{ customer.email? }}"
72
- - "Unknown"
73
- ```
74
-
75
- **`foreach`** (value context) -- Transform collections inline:
76
- ```yaml
77
- commodities:
78
- foreach: "sourceCommodities"
79
- item: "item" # default: "item"
80
- conditions: "[item.isActive] = true" # optional NCalc filter per item
81
- continueOnError: false # optional, skip errors
82
- mapping: # dict -> List<dict>, string -> List<object>
83
- name: "{{ item.name }}"
84
- quantity: "{{ item.qty }}"
85
- ```
86
-
87
- **`switch`** (value context) -- Value-based switch (case-insensitive match):
88
- ```yaml
89
- perLb:
90
- switch: "{{ contact.commissionTier }}"
91
- cases:
92
- "tier1": "{{ rate.customValues.commission_per_lb_tier1 }}"
93
- "tier2": "{{ rate.customValues.commission_per_lb_tier2 }}"
94
- default: "0"
95
- ```
96
-
97
- **`extends`** -- Extend/merge an existing object or array:
98
- ```yaml
99
- orderData:
100
- extends: "{{ existingOrder }}" # base object or array
101
- defaultIfNull: {} # fallback if extends is null
102
- mapping: # dict: merge overrides. array: append items
103
- status: "Updated"
104
- notes: "{{ newNotes }}"
105
- ```
106
-
107
- **`$raw`** -- Prevent template parsing (pass as-is):
108
- ```yaml
109
- template:
110
- $raw: "This {{ won't }} be parsed"
111
- ```
112
-
113
- **`$eval`** -- Parse JSON string then evaluate as template:
114
- ```yaml
115
- dynamicConfig:
116
- $eval: "{{ configJsonString }}"
117
- ```
118
-
119
- **`decrypt`** / **`encrypt`** -- AES-CBC encryption (optional key/IV, has defaults):
120
- ```yaml
121
- apiKey:
122
- decrypt:
123
- encryptedValue: "{{ encryptedApiKey }}"
124
- key: "{{ encryptionKey }}" # optional Base64 AES key
125
- initializationVector: "{{ iv }}" # optional Base64 IV
126
- ```
127
-
128
- ---
13
+ For template expressions `{{ path }}` used in step inputs, see [ref-expressions-template.md](ref-expressions-template.md).
129
14
 
130
15
  ## NCalc Expressions: `[variable]` (in conditions and expression directives)
131
16
 
@@ -224,24 +109,3 @@ Custom: `ceiling([value])` -- same as `Ceiling` but handles type conversion to d
224
109
  |----------|-------------|
225
110
  | `convertWeight([weight], 'Kg', 'Lb')` | Weight unit conversion. Returns `decimal` rounded to 5 places |
226
111
  | `convertDimension([length], 'Cm', 'In')` | Dimension unit conversion. Returns `decimal` rounded to 3 places |
227
-
228
- ---
229
-
230
- ## Property Path Syntax (in collection, mapping, variable paths)
231
-
232
- Used in `collection:` (foreach), `mapping:` (outputs), and variable resolution.
233
-
234
- | Pattern | Description | Example |
235
- |---------|-------------|---------|
236
- | `a.b.c` | Dot-separated nested path | `order.customer.name` |
237
- | `prop?` | Optional access (null if missing) | `order.customer?.name?` |
238
- | `list[0]` | Array index | `items[0]` |
239
- | `list[^1]` | Index from end (last item) | `items[^1]` |
240
- | `list[*]` | Flatten/wildcard (all items) | `containers[*].commodities` |
241
- | `list[**]` | Recursive flatten (all depths) | `containerCommodities[**]` |
242
- | `list[-1]` | Depth filter (leaves only) | `tree[**][-1]` |
243
- | `list[condition]` | Filter by condition | `items[status=Active]` |
244
- | `dict['key']` | Dictionary key access | `customValues['myField']` |
245
- | `list[*].{f1 f2}` | Field selector (projection) | `items[*].{name description}` |
246
- | `list[*].{alias:source}` | Field selector with alias | `items[*].{id:commodityId}` |
247
- | `list[*].{alias:_.parent}` | Field selector referencing parent | `items[*].{parentId:_.orderId}` |
@@ -0,0 +1,148 @@
1
+ # Template Expressions & Value Directives
2
+
3
+ ## Contents
4
+ - Template expression syntax `{{ path }}` (in step inputs)
5
+ - Type converters (int, decimal, bool, fromJson, toJson, etc.)
6
+ - Value directives (expression, coalesce, foreach, switch, extends, $raw, $eval, encrypt/decrypt)
7
+ - Property path syntax (dot paths, array indexing, wildcards, filters, projections)
8
+
9
+ There are **two distinct syntaxes** for referencing variables, used in different contexts. This file covers **template expressions** used in step inputs. For NCalc conditions and functions, see [ref-expressions-ncalc.md](ref-expressions-ncalc.md).
10
+
11
+ ## Template Expressions: `{{ path }}` (in step inputs)
12
+
13
+ Used in step `inputs` values. Resolves variable paths from scoped variables.
14
+
15
+ ```yaml
16
+ inputs:
17
+ orderId: "{{ inputs.orderId }}" # Simple reference
18
+ url: "{{ chopinConfig.baseUrl }}/api/v1" # String interpolation
19
+ order: "{{ Data.GetOrder.order }}" # Raw object (single {{ }})
20
+ name: "Order {{ Data.GetOrder.order.orderNumber }}" # String interpolation (multiple)
21
+ ```
22
+
23
+ **Key behavior**: A single `{{ path }}` returns the **raw object** (preserving type). Multiple `{{ }}` in a string returns string interpolation (each resolved value is `.ToString()`).
24
+
25
+ ### Type Converters (prefix in {{ }})
26
+
27
+ ```yaml
28
+ organizationId: "{{ int organizationId }}"
29
+ amount: "{{ decimal totalAmount }}"
30
+ isActive: "{{ bool isActive }}"
31
+ flag: "{{ boolOrFalse someFlag }}" # null -> false
32
+ flagOn: "{{ boolOrTrue someFlag }}" # null -> true
33
+ notes: "{{ emptyIfNull notes }}" # null -> ""
34
+ notes: "{{ nullIfEmpty notes }}" # "" or whitespace -> null
35
+ config: "{{ fromJson configJsonString }}" # JSON string -> dict/array
36
+ payload: "{{ toJson someObject }}" # object -> JSON string
37
+ name: "{{ trim value }}"
38
+ search: "{{ luceneString query }}" # escape & quote for Lucene
39
+ ```
40
+
41
+ | Converter | Returns | Null handling |
42
+ |-----------|---------|---------------|
43
+ | `string` | `string` | null. Reads `Stream` to string if value is Stream |
44
+ | `int` | `int` | Throws on null |
45
+ | `decimal` | `decimal` | Throws on null |
46
+ | `bool` | `bool` | Throws on null |
47
+ | `boolOrFalse` | `bool` | `false` if null |
48
+ | `boolOrTrue` | `bool` | `true` if null |
49
+ | `datetime` | `DateTime` | Throws on null |
50
+ | `emptyIfNull` | same type | `""` if null, `0` for int?, `0m` for decimal? |
51
+ | `nullIfEmpty` | same type | `null` if empty/whitespace string or empty collection |
52
+ | `luceneString` | `string` | null |
53
+ | `transliterate` | `string` | null (Unicode -> ASCII via Unidecode) |
54
+ | `transliterateUa` | `string` | null (Ukrainian-specific rules) |
55
+ | `fromJson` | `dict` or `array` | null. Empty string -> empty dict |
56
+ | `toJson` | `string` | `""` if null |
57
+ | `trim` | `string` | null |
58
+
59
+ ### Value Directives (in YAML input mappings)
60
+
61
+ **`expression`** -- Evaluate NCalc expression as a value:
62
+ ```yaml
63
+ amount:
64
+ expression: "[price] * [quantity]"
65
+ ```
66
+
67
+ **`coalesce`** -- First non-null value from a list:
68
+ ```yaml
69
+ displayName:
70
+ coalesce:
71
+ - "{{ customer.name? }}"
72
+ - "{{ customer.email? }}"
73
+ - "Unknown"
74
+ ```
75
+
76
+ **`foreach`** (value context) -- Transform collections inline:
77
+ ```yaml
78
+ commodities:
79
+ foreach: "sourceCommodities"
80
+ item: "item" # default: "item"
81
+ conditions: "[item.isActive] = true" # optional NCalc filter per item
82
+ continueOnError: false # optional, skip errors
83
+ mapping: # dict -> List<dict>, string -> List<object>
84
+ name: "{{ item.name }}"
85
+ quantity: "{{ item.qty }}"
86
+ ```
87
+
88
+ **`switch`** (value context) -- Value-based switch (case-insensitive match):
89
+ ```yaml
90
+ perLb:
91
+ switch: "{{ contact.commissionTier }}"
92
+ cases:
93
+ "tier1": "{{ rate.customValues.commission_per_lb_tier1 }}"
94
+ "tier2": "{{ rate.customValues.commission_per_lb_tier2 }}"
95
+ default: "0"
96
+ ```
97
+
98
+ **`extends`** -- Extend/merge an existing object or array:
99
+ ```yaml
100
+ orderData:
101
+ extends: "{{ existingOrder }}" # base object or array
102
+ defaultIfNull: {} # fallback if extends is null
103
+ mapping: # dict: merge overrides. array: append items
104
+ status: "Updated"
105
+ notes: "{{ newNotes }}"
106
+ ```
107
+
108
+ **`$raw`** -- Prevent template parsing (pass as-is):
109
+ ```yaml
110
+ template:
111
+ $raw: "This {{ won't }} be parsed"
112
+ ```
113
+
114
+ **`$eval`** -- Parse JSON string then evaluate as template:
115
+ ```yaml
116
+ dynamicConfig:
117
+ $eval: "{{ configJsonString }}"
118
+ ```
119
+
120
+ **`decrypt`** / **`encrypt`** -- AES-CBC encryption (optional key/IV, has defaults):
121
+ ```yaml
122
+ apiKey:
123
+ decrypt:
124
+ encryptedValue: "{{ encryptedApiKey }}"
125
+ key: "{{ encryptionKey }}" # optional Base64 AES key
126
+ initializationVector: "{{ iv }}" # optional Base64 IV
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Property Path Syntax (in collection, mapping, variable paths)
132
+
133
+ Used in `collection:` (foreach), `mapping:` (outputs), and variable resolution.
134
+
135
+ | Pattern | Description | Example |
136
+ |---------|-------------|---------|
137
+ | `a.b.c` | Dot-separated nested path | `order.customer.name` |
138
+ | `prop?` | Optional access (null if missing) | `order.customer?.name?` |
139
+ | `list[0]` | Array index | `items[0]` |
140
+ | `list[^1]` | Index from end (last item) | `items[^1]` |
141
+ | `list[*]` | Flatten/wildcard (all items) | `containers[*].commodities` |
142
+ | `list[**]` | Recursive flatten (all depths) | `containerCommodities[**]` |
143
+ | `list[-1]` | Depth filter (leaves only) | `tree[**][-1]` |
144
+ | `list[condition]` | Filter by condition | `items[status=Active]` |
145
+ | `dict['key']` | Dictionary key access | `customValues['myField']` |
146
+ | `list[*].{f1 f2}` | Field selector (projection) | `items[*].{name description}` |
147
+ | `list[*].{alias:source}` | Field selector with alias | `items[*].{id:commodityId}` |
148
+ | `list[*].{alias:_.parent}` | Field selector referencing parent | `items[*].{parentId:_.orderId}` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cxtms/cx-schema",
3
- "version": "1.7.4",
3
+ "version": "1.7.6",
4
4
  "description": "Schema validation package for CargoXplorer YAML modules",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",