@uipath/maestro-builder-sdk 6.37.0 → 6.38.0

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.
@@ -244,7 +244,225 @@ function localName(type) {
244
244
  const local = type.split(':')[1] ?? type;
245
245
  return local.charAt(0).toLowerCase() + local.slice(1);
246
246
  }
247
+ // The connector lift's state for one `decompile()` call. Planned in a pre-pass so the
248
+ // variable block, which is written before any element, already knows which tasks come
249
+ // back as `.connector()` — their declarations derive differently (`derivedVariableIds`).
250
+ // The lift's per-decompile state. Module-level `let`s, reset at the top of `decompile()`
251
+ // and read while it emits: nothing awaits between the reset and the last emit, and the
252
+ // module is not re-entered, which is the invariant this relies on. A per-call context
253
+ // object is the right shape if that ever changes.
254
+ let runLibrary;
255
+ let runLiftPlans = new Map();
256
+ let runLiftSkipped = [];
257
+ let runLiftCalls = new Map();
247
258
  /** The `uipath:*` payload element on an element, if it has one. */
259
+ /** Context rows a connector task carries that `.connector()` writes itself, or that the lift reads. */
260
+ const CONNECTOR_CONTEXT_ROWS = new Set([
261
+ 'connectorKey', 'operation', 'objectName', 'method', 'path', 'connection', 'folderKey', 'resourceKey',
262
+ 'metadata', 'activityConfigurationVersion', 'activity',
263
+ ]);
264
+ /** Row targets `.connector()` can address — the library's parameter locations plus the body. */
265
+ const CONNECTOR_ROW_TARGETS = new Set(['path', 'query', 'body', 'multipart', 'file']);
266
+ /**
267
+ * Plan every connector task's lift in `container` (sub-processes included): the id →
268
+ * plan for the ones `.connector()` can express, and a reason for each one it cannot.
269
+ */
270
+ function planConnectorLifts(container, skip) {
271
+ for (const el of container.flowElements ?? []) {
272
+ if (el.$type === 'bpmn:SubProcess')
273
+ planConnectorLifts(el, skip);
274
+ const payload = payloadOf(el);
275
+ if (!payload || extensionTypeOf(payload) !== 'Intsvc.ActivityExecution')
276
+ continue;
277
+ if (skip.has(el.id)) {
278
+ runLiftSkipped.push({ id: el.id, reason: 'the lift did not verify' });
279
+ continue;
280
+ }
281
+ const outcome = planConnectorLift(el, payload);
282
+ if (typeof outcome === 'string')
283
+ runLiftSkipped.push({ id: el.id, reason: outcome });
284
+ else
285
+ runLiftPlans.set(el.id, outcome);
286
+ }
287
+ }
288
+ /** The `=bindings.<id>` a context value references, or `undefined` for anything else. */
289
+ function bindingIdOf(value) {
290
+ const m = typeof value === 'string' ? /^=bindings\.([A-Za-z0-9_]+)$/.exec(value) : null;
291
+ return m ? m[1] : undefined;
292
+ }
293
+ /**
294
+ * A row's value as `.connector()` takes it: an `=`-expression as the string it is;
295
+ * otherwise the literal, coerced to the type the library declares for the parameter,
296
+ * because the file writes every scalar row as `type="string"` (`value="false"`,
297
+ * `value="0"`) and the shared validator refuses a string where it declares a boolean
298
+ * or an integer.
299
+ */
300
+ function liftedInputValue(raw, dataType) {
301
+ if (raw.startsWith('='))
302
+ return raw;
303
+ switch ((dataType ?? 'string').toLowerCase()) {
304
+ case 'boolean':
305
+ return raw === 'true' ? true : raw === 'false' ? false : raw;
306
+ case 'integer':
307
+ case 'number':
308
+ return raw.trim() !== '' && Number.isFinite(Number(raw)) ? Number(raw) : raw;
309
+ default:
310
+ return raw;
311
+ }
312
+ }
313
+ /**
314
+ * The `.connector()` call for one task, or why there is none. Everything here is a
315
+ * fact the lift needs and the generic form carries; what the SDK regenerates on
316
+ * compile is deliberately not read (see `BpmnDecompileOptions.connectors`).
317
+ */
318
+ function planConnectorLift(el, payload) {
319
+ const library = runLibrary;
320
+ if (!library)
321
+ return 'no connector library';
322
+ const ctx = contextOf(payload);
323
+ const rows = payload.context?.input ?? [];
324
+ const unknownCtx = rows.map((r) => r.name).filter((n) => !CONNECTOR_CONTEXT_ROWS.has(n));
325
+ if (unknownCtx.length)
326
+ return `context row(s) .connector() does not write: ${unknownCtx.join(', ')}`;
327
+ if (rows.some((r) => r.required !== undefined || r.target !== undefined))
328
+ return 'a context row carries attributes the record form cannot';
329
+ const ctxString = (k) => (typeof ctx[k] === 'string' ? ctx[k] : undefined);
330
+ const connectorKey = ctxString('connectorKey');
331
+ if (!connectorKey)
332
+ return 'no connectorKey';
333
+ let identity;
334
+ try {
335
+ identity = library.identifyAction({
336
+ connectorKey,
337
+ httpMethod: ctxString('method'),
338
+ endpoint: ctxString('path'),
339
+ objectName: ctxString('objectName'),
340
+ });
341
+ }
342
+ catch (e) {
343
+ return `not in the library: ${e.message}`;
344
+ }
345
+ const connection = bindingIdOf(ctx.connection);
346
+ if (!connection)
347
+ return `connection is ${ctx.connection === undefined ? 'absent' : JSON.stringify(ctx.connection)}, not a =bindings.<id> reference`;
348
+ const folder = ctx.folderKey === undefined ? undefined : bindingIdOf(ctx.folderKey);
349
+ if (ctx.folderKey !== undefined && folder === undefined)
350
+ return `folderKey is ${JSON.stringify(ctx.folderKey)}, not a =bindings.<id> reference`;
351
+ let params;
352
+ let declared;
353
+ try {
354
+ const resolved = library.resolve(identity.key, identity.action, identity.version, identity.object);
355
+ params = new Map((resolved.entry.operation?.parameters ?? []).map((p) => [p.name, p.dataType]));
356
+ declared = new Set([...params.keys(), ...resolved.fields.map((f) => f.name)]);
357
+ }
358
+ catch (e) {
359
+ return `the library cannot resolve ${identity.key}/${identity.action}: ${e.message}`;
360
+ }
361
+ const inputs = {};
362
+ for (const row of payload.input ?? []) {
363
+ const target = row.target;
364
+ if (target === undefined || !CONNECTOR_ROW_TARGETS.has(target)) {
365
+ return `payload row "${row.name}" has ${target === undefined ? 'no target' : `target "${target}"`}`;
366
+ }
367
+ if (target === 'body') {
368
+ if (row.name !== 'body')
369
+ return `body row is named "${row.name}"`;
370
+ const body = safeJson(row.body ?? '{}');
371
+ if (!body || typeof body !== 'object' || Array.isArray(body))
372
+ return 'the body row is not a JSON object';
373
+ for (const [k, v] of Object.entries(body)) {
374
+ if (k in inputs)
375
+ return `"${k}" appears both as a parameter row and in the body`;
376
+ // `.connector()` validates every input against the library, and a field the
377
+ // static library does not declare — an entity's own columns on a Data Fabric
378
+ // update, a form's fields — is refused until `registry prepare` loads it.
379
+ if (!declared.has(k) && !declared.has(k.split('.')[0])) {
380
+ return `body field "${k}" is not in the library for ${identity.key}/${identity.action} (connection-specific; \`registry prepare\` loads it)`;
381
+ }
382
+ inputs[k] = v;
383
+ }
384
+ continue;
385
+ }
386
+ if (row.value === undefined)
387
+ return `payload row "${row.name}" carries no value attribute`;
388
+ if (row.name in inputs)
389
+ return `payload row "${row.name}" appears twice`;
390
+ inputs[row.name] = liftedInputValue(String(row.value), params.get(row.name));
391
+ }
392
+ let outputVar;
393
+ let errorVar;
394
+ const outputs = {};
395
+ for (const row of payload.output ?? []) {
396
+ const standard = (row.name === 'response' && row.source === '=response' && outputVar === undefined) ||
397
+ (row.name === 'Error' && row.source === '=Error' && errorVar === undefined);
398
+ // The two standard rows may carry a schema body — the SDK writes the library's
399
+ // response schema there, and regenerates it. Any other row's body, or a target or
400
+ // description on any row, is something `.connector()` cannot say.
401
+ if (row.target !== undefined || row.description !== undefined || (row.body !== undefined && !standard)) {
402
+ return `output row "${row.name}" carries attributes .connector() does not write`;
403
+ }
404
+ if (standard && row.name === 'response')
405
+ outputVar = row.var;
406
+ else if (standard)
407
+ errorVar = row.var;
408
+ else {
409
+ // An extra mapped row: `outputs` keys it by its variable, so one without a
410
+ // variable or a source, or a second row on the same variable, cannot be said.
411
+ if (typeof row.var !== 'string' || typeof row.source !== 'string')
412
+ return `output row "${row.name}" has no variable or no source`;
413
+ if (row.var in outputs)
414
+ return `two output rows write "${row.var}"`;
415
+ const plain = row.name === row.var && (row.type ?? 'string') === 'string' && !row.custom;
416
+ outputs[row.var] = plain
417
+ ? row.source
418
+ : { source: row.source, ...(row.name !== row.var ? { name: row.name } : {}), ...((row.type ?? 'string') !== 'string' ? { type: row.type } : {}), ...(row.custom ? { custom: true } : {}) };
419
+ }
420
+ }
421
+ return {
422
+ key: identity.key,
423
+ action: identity.action,
424
+ version: identity.version === '1.0.0' ? undefined : identity.version,
425
+ object: identity.object,
426
+ inputs,
427
+ connection,
428
+ folder,
429
+ outputVar: outputVar !== undefined && outputVar !== `${el.id}_response` ? outputVar : undefined,
430
+ errorVar: errorVar !== undefined && errorVar !== `${el.id}_Error` ? errorVar : undefined,
431
+ outputs: Object.keys(outputs).length ? outputs : undefined,
432
+ };
433
+ }
434
+ /** The `outputs` option of a lifted connector as source. */
435
+ function connectorOutputsSource(outputs) {
436
+ return `{ ${Object.entries(outputs)
437
+ .map(([v, spec]) => `${key(v)}: ${typeof spec === 'string' ? tsText(spec) : opts([
438
+ ['source', tsText(spec.source)],
439
+ ['name', spec.name !== undefined ? tsText(spec.name) : undefined],
440
+ ['type', spec.type !== undefined ? tsText(spec.type) : undefined],
441
+ ['custom', spec.custom ? 'true' : undefined],
442
+ ])}`)
443
+ .join(', ')} }`;
444
+ }
445
+ /** A planned connector task as its `.connector()` call. */
446
+ function emitConnectorLift(chain, el, payload, plan) {
447
+ const options = opts([
448
+ ['name', el.name !== undefined ? tsText(el.name) : undefined],
449
+ ['connection', tsText(plan.connection)],
450
+ ['folder', plan.folder !== undefined ? tsText(plan.folder) : undefined],
451
+ ['version', plan.version !== undefined ? tsText(plan.version) : undefined],
452
+ ['object', plan.object !== undefined ? tsText(plan.object) : undefined],
453
+ ['outputVar', plan.outputVar !== undefined ? tsText(plan.outputVar) : undefined],
454
+ ['errorVar', plan.errorVar !== undefined ? tsText(plan.errorVar) : undefined],
455
+ ['outputs', plan.outputs ? connectorOutputsSource(plan.outputs) : undefined],
456
+ ['skipCondition', payload.skipCondition !== undefined ? tsText(payload.skipCondition) : undefined],
457
+ ['tags', tagsOf(el)],
458
+ ['retry', emitRetry(retryOf(el))],
459
+ ['errorMapping', emitErrorMapping(errorMappingOf(el))],
460
+ ['loop', emitLoop(el)],
461
+ ]);
462
+ const call = `.connector(${tsText(el.id)}, ${tsText(plan.key)}, ${tsText(plan.action)}, ${record(plan.inputs) ?? '{}'}${optionalArg(options)})`;
463
+ runLiftCalls.set(el.id, call);
464
+ chain.add(call);
465
+ }
248
466
  function payloadOf(el) {
249
467
  for (const ext of el.extensionElements?.values ?? []) {
250
468
  if (ext.$type === 'uipath:Activity' || ext.$type === 'uipath:Event' || ext.$type === 'uipath:Mapping')
@@ -1584,6 +1802,11 @@ function emitElement(chain, el, depth, indent) {
1584
1802
  if (kind === 'startEvent' && startEventDefinitionCarriesConfig(el)) {
1585
1803
  return emitTriggerStartEvent(chain, el, payload, type);
1586
1804
  }
1805
+ // A connector task the library can name, planned in the pre-pass — see
1806
+ // `BpmnDecompileOptions.connectors` for what the lift gives up and how it is checked.
1807
+ const plan = runLiftPlans.get(el.id);
1808
+ if (plan)
1809
+ return emitConnectorLift(chain, el, payload, plan);
1587
1810
  return emitTypedNode(chain, el, payload, type);
1588
1811
  }
1589
1812
  switch (kind) {
@@ -1930,7 +2153,16 @@ export async function decompile(xml, options = {}) {
1930
2153
  // found none, so NOTHING was recognised as derived and every declaration was echoed
1931
2154
  // by hand. That was invisible — an echoed declaration takes the id before
1932
2155
  // `implicitNodeVars` can claim it, so the output was correct, just 112 lines of it.
1933
- const { ids: derived, folds } = derivedVariableIds(process, varsExt, host.rehome);
2156
+ // The connector lift, planned first: the variable block below needs to know which
2157
+ // tasks come back as `.connector()`, whose declarations derive as a connector's.
2158
+ runLibrary = options.library;
2159
+ runLiftPlans = new Map();
2160
+ runLiftSkipped = [];
2161
+ runLiftCalls = new Map();
2162
+ if (options.library && (options.connectors ?? 'lift') === 'lift') {
2163
+ planConnectorLifts(process, options.verbatimConnectors ?? new Set());
2164
+ }
2165
+ const { ids: derived, folds } = derivedVariableIds(process, varsExt, host.rehome, new Set(runLiftPlans.keys()));
1934
2166
  const schemaPlan = planSchemas([
1935
2167
  ...(varsExt?.input ?? []),
1936
2168
  ...(varsExt?.inputOutput ?? []),
@@ -1951,12 +2183,14 @@ export async function decompile(xml, options = {}) {
1951
2183
  // hand-editing". Only when something was actually folded: a document of explicit
1952
2184
  // `.var()` calls already states its order by their position, and the extra line would
1953
2185
  // be noise.
2186
+ let preambleLines = 0;
1954
2187
  if (derived.size) {
1955
2188
  const ids = [...(varsExt?.input ?? []), ...(varsExt?.inputOutput ?? []), ...(varsExt?.output ?? [])].map((v) => v.id);
1956
2189
  chain.add(`.preserve({ variableOrder: [${ids.map(tsText).join(', ')}] })`);
1957
2190
  }
1958
2191
  try {
1959
2192
  emitVariablesInto(chain, host.container, host.rehome?.to ?? host.container.id, derived, host.rehome, schemaPlan, publicDeclarationScopeOf(process, host.rehome?.to ?? host.container.id));
2193
+ preambleLines = chain.all.length;
1960
2194
  if (options.style === 'nested') {
1961
2195
  const sequence = options.sequenceMode ?? true;
1962
2196
  const summary = { handlers: 0, branches: 0, nets: 0, leftFlat: [], renamedFlows: [], sequence };
@@ -1975,11 +2209,18 @@ export async function decompile(xml, options = {}) {
1975
2209
  }
1976
2210
  finally {
1977
2211
  foldedVarSchemas = undefined;
2212
+ runLibrary = undefined;
1978
2213
  }
1979
2214
  const importFrom = options.importSpecifier ?? './bpmn-sdk.js';
1980
2215
  const imported = ['bpmn', ...[...schemaPlan.imports].sort()].join(', ');
1981
2216
  const head = `import { ${imported} } from ${tsText(importFrom)};\n\nexport default bpmn(${tsText(process.id)})`;
1982
2217
  const name = process.name !== undefined ? `\n${indent}.name(${tsText(process.name)})` : '';
2218
+ options.onConnectorLift?.({
2219
+ lifted: [...runLiftPlans.keys()],
2220
+ verbatim: runLiftSkipped,
2221
+ preamble: `${host.note}${head}${name}\n${chain.all.slice(0, preambleLines).join('\n')}`,
2222
+ calls: runLiftCalls,
2223
+ });
1983
2224
  return `${host.note}${head}${name}\n${chain.all.join('\n')}\n${indent}.build();\n`;
1984
2225
  }
1985
2226
  /**
@@ -2010,7 +2251,9 @@ export async function decompile(xml, options = {}) {
2010
2251
  */
2011
2252
  function derivedVariableIds(process, varsExt,
2012
2253
  /** The collaboration→process re-parenting, so `elementId` is compared post-move. */
2013
- rehome) {
2254
+ rehome,
2255
+ /** Connector tasks the lift writes as `.connector()`, whose declarations `implicitNodeVars` derives as a connector's. */
2256
+ lifted = new Set()) {
2014
2257
  // var id -> the declaration `implicitNodeVars` would derive for it
2015
2258
  const candidates = new Map();
2016
2259
  const walk = (container) => {
@@ -2042,6 +2285,20 @@ rehome) {
2042
2285
  for (const row of payload.output ?? []) {
2043
2286
  if (!row.var)
2044
2287
  continue;
2288
+ // A lifted connector's two variables are claimed the way `.connector()` claims
2289
+ // them — `json`, named after the id, no schema — so a file's own `jsonSchema`
2290
+ // declaration with a body stays an explicit `.var()` rather than being folded
2291
+ // onto a row the lifted call no longer has.
2292
+ if (lifted.has(el.id)) {
2293
+ // A `.connector()` call has no row to fold a declaration's schema onto, so
2294
+ // a declaration that carries one stays explicit whatever its wire type —
2295
+ // `noFold` below — rather than vanishing into `foldedVarSchemas`, which the
2296
+ // lift never reads.
2297
+ // The wire type the row implies: `json` for the response and Error rows, the
2298
+ // row's own for an extra mapped row (`integer`), as `implicitNodeVars` declares.
2299
+ candidates.set(row.var, { owner: el.id, wire: rowDeclaration({ name: row.name, type: row.type }).wire, noFold: true });
2300
+ continue;
2301
+ }
2045
2302
  // A script task's rows come back as `outputs` when that form reproduces
2046
2303
  // them, and `implicitNodeVars` then derives their declarations from the
2047
2304
  // keys: id as the name, that arm's own wire type. Rows that need spelling
@@ -2092,7 +2349,7 @@ rehome) {
2092
2349
  // against 28 rows, so without the fold almost every structured output stays an
2093
2350
  // explicit `.var()`.
2094
2351
  if (String(v.body ?? '') !== String(c.schema ?? '')) {
2095
- if (c.schema !== undefined || v.body === undefined)
2352
+ if (c.schema !== undefined || v.body === undefined || c.noFold)
2096
2353
  continue;
2097
2354
  folds.set(v.id, v.body);
2098
2355
  }
@@ -85,6 +85,7 @@ export async function serialize(built, opts = {}) {
85
85
  schemas: built.schemas,
86
86
  variableOrder: built.preservation?.variableOrder,
87
87
  bindingSink: new Map(),
88
+ declaredBindings: new Map(built.bindings.map((b) => [b.id, { name: b.name, default: b.default, resourceKey: b.resourceKey }])),
88
89
  varTypeOf: (varId) => authoredVarType.get(varId),
89
90
  };
90
91
  // `.name()` was accepted by the builder, stored on the built graph, and never
@@ -664,6 +665,14 @@ export function implicitNodeVars(nodes, declared) {
664
665
  const { response, error } = connectorOutputVars(n);
665
666
  claim(response, n.id);
666
667
  claim(error, n.id);
668
+ // An extra mapped row declares its variable as the row is typed (`string` when the
669
+ // row says nothing), not as `object`: `{ poCount: { source, type: 'integer' } }`
670
+ // writes an `integer` row and must declare an integer.
671
+ for (const [varId, spec] of Object.entries(n.outputs ?? {})) {
672
+ const row = typeof spec === 'string' ? { source: spec } : spec;
673
+ const d = rowDeclaration({ name: row.name ?? varId, type: row.type ?? 'string' });
674
+ claim(varId, n.id, d.type, d);
675
+ }
667
676
  }
668
677
  else if (n.kind === 'typed') {
669
678
  // Shared with the expression checker rather than repeated here. Repeating it is
@@ -180,6 +180,15 @@
180
180
  "activityType": "Curated",
181
181
  "objectName": "QueryEntityRecordsCurated",
182
182
  "path": "uipath-uipath-dataservice/query-entity-records@1.0.0.json"
183
+ },
184
+ {
185
+ "nodeType": "uipath.connector.uipath-uipath-dataservice.update-entity-record",
186
+ "version": "1.0.0",
187
+ "connectorKey": "uipath-uipath-dataservice",
188
+ "label": "Update Entity Record",
189
+ "activityType": "Curated",
190
+ "objectName": "UpdateEntityRecordV2",
191
+ "path": "uipath-uipath-dataservice/update-entity-record@1.0.0.json"
183
192
  }
184
193
  ]
185
194
  }
@@ -0,0 +1,132 @@
1
+ {
2
+ "schemaVersion": "1",
3
+ "nodeType": "uipath.connector.uipath-uipath-dataservice.update-entity-record",
4
+ "version": "1.0.0",
5
+ "category": "connector.196550",
6
+ "tags": [
7
+ "connector",
8
+ "activity"
9
+ ],
10
+ "connector": {
11
+ "key": "uipath-uipath-dataservice",
12
+ "name": "UiPath Data Fabric",
13
+ "tier": "1",
14
+ "discovery": {
15
+ "type": "dynamic",
16
+ "hasObjectDiscovery": true,
17
+ "hasFieldDiscovery": true,
18
+ "hasCustomObjectDiscovery": true,
19
+ "hasCustomFieldDiscovery": true
20
+ }
21
+ },
22
+ "operation": {
23
+ "name": "Replace",
24
+ "objectName": "UpdateEntityRecordV2",
25
+ "objectDisplayName": "Update Entity Record",
26
+ "httpMethod": "PUT",
27
+ "path": "/v2/{entityName}/UpdateEntityRecord",
28
+ "subType": "standard",
29
+ "supportsStreaming": false,
30
+ "activityType": "Curated",
31
+ "schemaAction": {
32
+ "name": "GenerateSchema",
33
+ "parents": [
34
+ "entityName"
35
+ ],
36
+ "replaces": "both"
37
+ },
38
+ "pathTemplate": "/v2/{entityName}/UpdateEntityRecord",
39
+ "parameters": [
40
+ {
41
+ "name": "entityName",
42
+ "type": "path",
43
+ "dataType": "string",
44
+ "required": true,
45
+ "displayName": "Entity",
46
+ "description": "Enter entity name",
47
+ "reference": {
48
+ "objectName": "system",
49
+ "lookupNames": [
50
+ "name"
51
+ ],
52
+ "lookupValue": "name",
53
+ "path": "/standard-objects-hybrid"
54
+ }
55
+ },
56
+ {
57
+ "name": "recordId",
58
+ "type": "query",
59
+ "dataType": "string",
60
+ "required": true,
61
+ "displayName": "Record ID",
62
+ "description": "Enter Record ID to update the corresponding record"
63
+ },
64
+ {
65
+ "name": "expansionLevel",
66
+ "type": "query",
67
+ "dataType": "integer",
68
+ "required": false,
69
+ "displayName": "Record level depth",
70
+ "description": "Specify the depth of related records to be retrieved from the service. This property supports values from 1 to 3.",
71
+ "defaultValue": 3
72
+ }
73
+ ]
74
+ },
75
+ "display": {
76
+ "label": "Update Entity Record",
77
+ "description": "Updates an existing record in a Data Fabric entity",
78
+ "icon": "https://alpha.uipath.com/311c6049-4966-4ef2-a6f3-8ceccaf38d54/studio_/typecache/icons/98381fa079bbcf73264f551006d6ef7580fb53992f3d9f94361eb5d9e06040cb.svg",
79
+ "iconBackground": "",
80
+ "iconBackgroundDark": "",
81
+ "operationLabel": "Update Entity Record"
82
+ },
83
+ "runtime": {
84
+ "bpmnType": "bpmn:SendTask",
85
+ "serviceType": "Intsvc.ActivityExecution",
86
+ "activityConfigurationVersion": "v1",
87
+ "requiresConnection": true,
88
+ "requiresFolderKey": true,
89
+ "requiresConnectionForSchema": true
90
+ },
91
+ "inputSchema": {
92
+ "fields": [
93
+ {
94
+ "name": "entityName",
95
+ "type": "string",
96
+ "required": true,
97
+ "description": "Enter entity name",
98
+ "displayName": "Entity",
99
+ "reference": {
100
+ "objectName": "system",
101
+ "lookupNames": [
102
+ "name"
103
+ ],
104
+ "lookupValue": "name",
105
+ "path": "/standard-objects-hybrid"
106
+ }
107
+ },
108
+ {
109
+ "name": "recordId",
110
+ "type": "string",
111
+ "required": true,
112
+ "description": "Enter Record ID to update the corresponding record",
113
+ "displayName": "Record ID"
114
+ },
115
+ {
116
+ "name": "expansionLevel",
117
+ "type": "integer",
118
+ "required": false,
119
+ "description": "Specify the depth of related records to be retrieved from the service. This property supports values from 1 to 3.",
120
+ "displayName": "Record level depth",
121
+ "enum": [
122
+ 1,
123
+ 2,
124
+ 3
125
+ ]
126
+ }
127
+ ]
128
+ },
129
+ "outputSchema": {
130
+ "fields": []
131
+ }
132
+ }