ultravisor 1.0.28 → 1.0.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultravisor",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "Cyclic process execution with ai integration.",
5
5
  "main": "source/Ultravisor.cjs",
6
6
  "bin": {
@@ -1234,21 +1234,22 @@ class UltravisorExecutionEngine extends libPictService
1234
1234
  {
1235
1235
  let tmpKey = tmpSettingsKeys[i];
1236
1236
  let tmpVal = tmpSettings[tmpKey];
1237
-
1238
- // Skip template resolution for Object and Array typed settings.
1239
- // These carry opaque configuration (e.g. mapping rules) whose
1240
- // template expressions belong to the consuming service, not the engine.
1241
1237
  let tmpDeclaredType = tmpSettingsTypeMap[tmpKey];
1242
- if (tmpDeclaredType === 'Object' || tmpDeclaredType === 'Array')
1243
- {
1244
- continue;
1245
- }
1246
1238
 
1239
+ // First, handle the single-whole-reference case regardless of
1240
+ // declared type. When a string-typed graph value is exactly one
1241
+ // `{~D:Record.X~}` expression, the author's intent is "pass the
1242
+ // referenced value through verbatim." For Array / Object typed
1243
+ // settings, that's the ONLY way to populate them via the graph
1244
+ // (graph values are JSON, so a literal array reference is encoded
1245
+ // as a string template). Resolving here preserves the non-scalar
1246
+ // type. Without this branch, an Array setting that points at an
1247
+ // upstream task's output (e.g. BulkInsertViaBeacon's `Records`
1248
+ // reading parse-task `Records`) gets the unresolved template
1249
+ // string passed to the handler, which then iterates over the
1250
+ // string's characters and POSTs garbage.
1247
1251
  if (typeof(tmpVal) === 'string' && tmpVal.indexOf('{~') >= 0)
1248
1252
  {
1249
- // When the entire value is a single {~D:Record.X~} expression,
1250
- // resolve via StateManager to preserve non-scalar types
1251
- // (arrays, objects). parseTemplate always returns strings.
1252
1253
  let tmpDataMatch = tmpVal.match(/^\{~D:Record\.(.+?)~\}$/);
1253
1254
  if (tmpDataMatch)
1254
1255
  {
@@ -1260,6 +1261,22 @@ class UltravisorExecutionEngine extends libPictService
1260
1261
  continue;
1261
1262
  }
1262
1263
  }
1264
+ }
1265
+
1266
+ // For Object / Array typed settings whose value is NOT a single
1267
+ // reference, skip template resolution. These carry opaque
1268
+ // configuration (e.g. mapping rules) whose `{~D:~}` expressions
1269
+ // belong to the consuming service (TabularTransform etc.), not
1270
+ // the execution engine.
1271
+ if (tmpDeclaredType === 'Object' || tmpDeclaredType === 'Array')
1272
+ {
1273
+ continue;
1274
+ }
1275
+
1276
+ if (typeof(tmpVal) === 'string' && tmpVal.indexOf('{~') >= 0)
1277
+ {
1278
+ // Mixed/inline template — parseTemplate always returns a string,
1279
+ // which is fine for scalar (String) settings.
1263
1280
  tmpSettings[tmpKey] = this._resolveTemplate(tmpVal, tmpTemplateContext);
1264
1281
  }
1265
1282
  }