@uipath/maestro-builder-sdk 6.32.4 → 6.32.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.
@@ -204,6 +204,8 @@ export interface BuiltTrigger {
204
204
  eventOutputs?: TaskOutputBinding[];
205
205
  /** Event only: a library-resolved Integration Service subscription. */
206
206
  eventSubscription?: EventSubscription;
207
+ /** Event placeholder only: the source object the event watches (see {@link EventTriggerOpts.object}). */
208
+ eventObject?: string;
207
209
  }
208
210
  export interface ManualTriggerOpts {
209
211
  name?: string;
@@ -241,10 +243,25 @@ export interface EventTriggerOpts {
241
243
  description?: string;
242
244
  /**
243
245
  * Stringly resolved subscription. Prefer the descriptor overload when a
244
- * prepared connector module is available. Omit this for the legacy
245
- * `serviceType`-only placeholder.
246
+ * prepared connector module is available. Omit this for a **placeholder**
247
+ * trigger, whose bag carries `serviceType` (plus `context[objectName]` when
248
+ * `object` is set).
246
249
  */
247
250
  subscription?: EventSubscription;
251
+ /**
252
+ * The source OBJECT the event watches — a Data Fabric entity, a Salesforce or
253
+ * ServiceNow object, a database table — for a **placeholder** trigger whose
254
+ * connector and connection are not resolved yet. It is emitted as the
255
+ * trigger's `context[objectName]` row, the same row `uip maestro case sdd
256
+ * convert` writes for an SDD's `| T02 | Intsvc.EventTrigger | <object> | … |`
257
+ * Case Triggers row, so the requested source survives in the plan as data,
258
+ * not only in a label. For example
259
+ * `eventTrigger({ name: 'Invoice created', object: 'aged_invoice_cases' })`.
260
+ *
261
+ * A resolved subscription names its object in `subscription.object` instead;
262
+ * passing both is refused.
263
+ */
264
+ object?: string;
248
265
  /**
249
266
  * Optional event-payload extractions. Each key is a case-variable name read
250
267
  * downstream as `=vars.<name>`; each value is the payload field expression
@@ -253,7 +270,8 @@ export interface EventTriggerOpts {
253
270
  *
254
271
  * @remarks
255
272
  * With **no** outputs the event trigger is a **placeholder** (`data.inputs`
256
- * carries only `serviceType`) — the offline shape for an event on a connector
273
+ * carries `serviceType`, plus `context[objectName]` when `object` is set) —
274
+ * the offline shape for an event on a connector
257
275
  * not yet registered; attach the real connection after registering it.
258
276
  */
259
277
  outputs?: Record<string, string | {
@@ -112,11 +112,21 @@ export function eventTrigger(descriptorOrOpts = {}, descriptorOpts = {}) {
112
112
  const type = (typeof v === 'string' ? 'string' : (v.type ?? 'string'));
113
113
  eventOutputs.push({ var: name, source, type });
114
114
  }
115
+ const object = descriptor ? undefined : opts.object;
116
+ if (object !== undefined) {
117
+ if (opts.subscription)
118
+ throw new Error('eventTrigger: pass the watched object as `subscription.object` on a resolved subscription, not as `object`.');
119
+ // Refuse padding rather than trim it: the value must match the SDD's
120
+ // source object exactly, and a silent trim would hide the typo.
121
+ if (typeof object !== 'string' || !object.trim() || object !== object.trim())
122
+ throw new Error('eventTrigger: `object` must be a non-empty string with no surrounding whitespace.');
123
+ }
115
124
  return {
116
125
  kind: 'event',
117
126
  name: opts.name,
118
127
  description: opts.description,
119
128
  eventOutputs: eventOutputs.length ? eventOutputs : undefined,
129
+ eventObject: object,
120
130
  eventSubscription: descriptor
121
131
  ? subscriptionFrom(descriptor, descriptorOpts)
122
132
  : opts.subscription,
@@ -814,7 +814,9 @@ function triggerSource(node, index, plan, refs) {
814
814
  }
815
815
  if (bag.serviceType === 'Intsvc.EventTrigger') {
816
816
  const bridges = bridgeRows(plan, node.id ?? '', bag);
817
- const resolved = bag.context !== undefined || bag.inputs !== undefined || bag.bindings !== undefined;
817
+ const object = placeholderEventObject(bag);
818
+ const resolved = object === undefined
819
+ && (bag.context !== undefined || bag.inputs !== undefined || bag.bindings !== undefined);
818
820
  const outputs = (bag.outputs ?? []).filter((row) => !bridges.has(row) && !isResolvedConnectorOutput(row, node.id ?? '', resolved));
819
821
  const subscription = resolved
820
822
  ? resolvedSubscriptionSource(bag, `event trigger "${label ?? node.id ?? index}"`, 'trigger', refs)
@@ -832,11 +834,28 @@ function triggerSource(node, index, plan, refs) {
832
834
  ['name', name],
833
835
  ['description', description ? tsLiteral(description) : undefined],
834
836
  ['subscription', subscription],
837
+ ['object', object !== undefined ? tsLiteral(object) : undefined],
835
838
  ['outputs', outputShape],
836
839
  ])})`;
837
840
  }
838
841
  throw new Error(`trigger "${label ?? node.id ?? index}" has unsupported serviceType "${bag.serviceType}".`);
839
842
  }
843
+ /**
844
+ * The source object of an unresolved event trigger, when its bag is the
845
+ * placeholder plus one `context[objectName]` row — the shape `eventTrigger({
846
+ * object })` compiles to and `uip maestro case sdd convert` writes. Anything
847
+ * richer (connector key, inputs, bindings) is a resolved subscription.
848
+ */
849
+ function placeholderEventObject(bag) {
850
+ const context = bag.context;
851
+ if (!Array.isArray(context) || context.length !== 1)
852
+ return undefined;
853
+ const row = context[0];
854
+ if (row?.name !== 'objectName' || typeof row.value !== 'string' || !row.value.trim())
855
+ return undefined;
856
+ const empty = (value) => value === undefined || (Array.isArray(value) && value.length === 0);
857
+ return empty(bag.inputs) && empty(bag.bindings) ? row.value : undefined;
858
+ }
840
859
  function caseAppSource(config) {
841
860
  if (typeof config.caseSummary !== 'string')
842
861
  throw new Error('caseAppConfig.caseSummary must be a string.');
@@ -700,7 +700,12 @@ function emitTriggers(triggers, ids, resolver) {
700
700
  // machinery as connector tasks and wait-for-connector bags.
701
701
  const bag = t.eventSubscription
702
702
  ? resolvedSubscriptionBag('trigger', t.eventSubscription, resolver, triggerId, `Event trigger "${label}"`)
703
- : { serviceType: CASE_FORMAT_PROFILE.eventServiceType };
703
+ : {
704
+ serviceType: CASE_FORMAT_PROFILE.eventServiceType,
705
+ // A placeholder that names its source object carries it the way
706
+ // `case sdd convert` does: one `context[objectName]` row.
707
+ ...(t.eventObject ? { context: [io('objectName', 'string', { value: t.eventObject })] } : {}),
708
+ };
704
709
  if (t.eventOutputs?.length) {
705
710
  const outputs = t.eventOutputs.map((o) => {
706
711
  const field = o.source.replace(/^=/, '').split('.').pop() || o.source;
@@ -80,8 +80,9 @@ export declare function canonicalFormFieldType(type: unknown): CanonicalFormFiel
80
80
  /**
81
81
  * The spelling decompile writes into source for a wire field type: a canonical
82
82
  * type or an SDK alias stays as written, so a canvas form (`"integer"`,
83
- * `"date"`) and a classic-CLI form (`"text"`) both compile back to the bytes
84
- * they came from; a product alias the SDK does not accept in source
83
+ * `"date"`) compiles back to the bytes it came from and a classic-CLI form's
84
+ * `"text"` stays a type `check` accepts (compile writes it as `"string"`);
85
+ * a product alias the SDK does not accept in source
85
86
  * (`"System.Int32"`, `"string[]"`) becomes its canonical type; anything else
86
87
  * stays verbatim for `check` to report.
87
88
  *
@@ -158,3 +159,17 @@ export declare function formFieldOptionsProblem(type: unknown, options: unknown)
158
159
  * that starts "… the field "<id>" …".
159
160
  */
160
161
  export declare function formFieldOptionsWhy(problem: 'malformed' | 'missing' | 'ignored', type: unknown): string;
162
+ /**
163
+ * The spelling a form field's type is written in on the wire: the product's
164
+ * canonical one for the SDK's legacy spellings (`text` is written `string`,
165
+ * `date-time` is written `datetime`). `@uipath/hitl-schema-types` resolves
166
+ * those two only as legacy aliases, and the designer saves the canonical value,
167
+ * so an SDK-authored form says what a canvas-built one says (#1185). Every
168
+ * other type passes through unchanged.
169
+ *
170
+ * @example
171
+ * wireFormFieldType('text') // 'string'
172
+ * wireFormFieldType('date-time') // 'datetime'
173
+ * wireFormFieldType('number') // 'number'
174
+ */
175
+ export declare function wireFormFieldType(type: unknown): unknown;
@@ -22,9 +22,10 @@ const CANONICAL_JSON_SCHEMA = {
22
22
  /** The product's 11 canonical quick-form field types, in its own order. */
23
23
  export const CANONICAL_FORM_FIELD_TYPES = Object.keys(CANONICAL_JSON_SCHEMA);
24
24
  /**
25
- * The SDK's own legacy spellings, accepted in source: `text` (what the SDK,
26
- * flow-v1's serializer and `uip maestro flow hitl add` have always written) and
27
- * `date-time`. The product resolves both.
25
+ * The SDK's own legacy spellings, accepted in source: `text` (what flow-v1's
26
+ * serializer and `uip maestro flow hitl add` write) and `date-time`. The
27
+ * product resolves both. The SDK writes their canonical value on the wire
28
+ * (`wireFormFieldType`).
28
29
  */
29
30
  const SDK_ALIASES = {
30
31
  text: 'string',
@@ -172,8 +173,9 @@ export function canonicalFormFieldType(type) {
172
173
  /**
173
174
  * The spelling decompile writes into source for a wire field type: a canonical
174
175
  * type or an SDK alias stays as written, so a canvas form (`"integer"`,
175
- * `"date"`) and a classic-CLI form (`"text"`) both compile back to the bytes
176
- * they came from; a product alias the SDK does not accept in source
176
+ * `"date"`) compiles back to the bytes it came from and a classic-CLI form's
177
+ * `"text"` stays a type `check` accepts (compile writes it as `"string"`);
178
+ * a product alias the SDK does not accept in source
177
179
  * (`"System.Int32"`, `"string[]"`) becomes its canonical type; anything else
178
180
  * stays verbatim for `check` to report.
179
181
  *
@@ -299,3 +301,21 @@ export function formFieldOptionsWhy(problem, type) {
299
301
  + `plain input and never shows them. Use 'singleSelect' or 'enum' (a dropdown) or 'multiSelect'`;
300
302
  }
301
303
  }
304
+ /**
305
+ * The spelling a form field's type is written in on the wire: the product's
306
+ * canonical one for the SDK's legacy spellings (`text` is written `string`,
307
+ * `date-time` is written `datetime`). `@uipath/hitl-schema-types` resolves
308
+ * those two only as legacy aliases, and the designer saves the canonical value,
309
+ * so an SDK-authored form says what a canvas-built one says (#1185). Every
310
+ * other type passes through unchanged.
311
+ *
312
+ * @example
313
+ * wireFormFieldType('text') // 'string'
314
+ * wireFormFieldType('date-time') // 'datetime'
315
+ * wireFormFieldType('number') // 'number'
316
+ */
317
+ export function wireFormFieldType(type) {
318
+ return typeof type === 'string' && Object.hasOwn(SDK_ALIASES, type)
319
+ ? SDK_ALIASES[type]
320
+ : type;
321
+ }
@@ -13,7 +13,7 @@
13
13
  * every edge out of an outcome-handle node to.
14
14
  */
15
15
  import { Expr, toExpr } from '../../../core/expr.js';
16
- import { formFieldJsonSchema, formFieldOptionsWire, liftFormFieldOptions, sourceFormFieldType } from '../../../core/form-field-type.js';
16
+ import { formFieldJsonSchema, formFieldOptionsWire, liftFormFieldOptions, sourceFormFieldType, wireFormFieldType } from '../../../core/form-field-type.js';
17
17
  import { isAnswerField } from '../../../core/hitl-answers.js';
18
18
  import { OUTCOME_HANDLE_NODE_TYPES, hitlExitModel, outcomeIdOf, outcomeSlug } from '../../../core/hitl-routing.js';
19
19
  import { jsonClone } from '../../../core/json-clone.js';
@@ -61,7 +61,7 @@ function hitlInputs(inputs, nodeType, ctx) {
61
61
  const base = {
62
62
  id: f.id,
63
63
  label: f.label ?? f.id,
64
- type: f.type,
64
+ type: wireFormFieldType(f.type),
65
65
  direction: f.direction,
66
66
  };
67
67
  if (f.direction === 'input') {
package/dist/serialize.js CHANGED
@@ -20,7 +20,7 @@ import { FLOW_NODE_TYPES } from './flow-node-registry.js';
20
20
  import { stepExits } from './flow-step-exits.js';
21
21
  import { resolveVersionCarried } from './core/nodes/versioned.js';
22
22
  import { indexCarriedDefinitions } from './core/carried-definitions.js';
23
- import { formFieldJsonSchema, formFieldOptionsWire } from './core/form-field-type.js';
23
+ import { formFieldJsonSchema, formFieldOptionsWire, wireFormFieldType } from './core/form-field-type.js';
24
24
  import { ConnectorResolveError } from './core/connector-resolve-error.js';
25
25
  import { connectionConnectors } from './bindings-v2.js';
26
26
  import { BindingRefusal, GUID_RE, bindingLabelRefusal, bindingMissingMessage, missingBindingLabels } from './core/binding-messages.js';
@@ -5720,7 +5720,7 @@ export function serialize(built, opts = {}) {
5720
5720
  return {
5721
5721
  id: f.id,
5722
5722
  label: f.label ?? f.id,
5723
- type: f.type,
5723
+ type: wireFormFieldType(f.type),
5724
5724
  direction: f.direction,
5725
5725
  // A picker's choices, as the human task's rows carry them (#1235).
5726
5726
  ...(options !== undefined ? { options } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.32.4",
3
+ "version": "6.32.6",
4
4
  "description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.uipath.com/maestro",
@@ -93,5 +93,5 @@
93
93
  "@types/node": "^22.7.0",
94
94
  "esbuild": "^0.28.1"
95
95
  },
96
- "gitref": "9a7e5f98ca054b05f74ac655b8725bf4e3b50e89"
96
+ "gitref": "0b27856ab8b25ffc834013f559a14946f61cb89a"
97
97
  }