@uipath/maestro-builder-sdk 6.66.1 → 6.66.3
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/dist/api-index.md +8 -8
- package/dist/api-members.md +44 -43
- package/dist/case/decompile.js +31 -18
- package/dist/case/merge.d.ts +3 -3
- package/dist/case/merge.js +12 -8
- package/dist/case/preserve.d.ts +12 -0
- package/dist/case/preserve.js +21 -0
- package/dist/case/serialize.d.ts +16 -0
- package/dist/case/serialize.js +271 -63
- package/dist/core/process-resource.d.ts +6 -1
- package/dist/core/process-resource.js +7 -6
- package/dist/core/refusals.d.ts +1 -0
- package/dist/core/refusals.js +1 -0
- package/dist/merge.js +31 -0
- package/dist/nodes/hitl/flow/check.js +23 -4
- package/dist/nodes/hitl/flow/node-type.js +44 -3
- package/dist/nodes/hitl/flow/spec.d.ts +33 -4
- package/package.json +2 -2
|
@@ -25,6 +25,7 @@ export const HITL_DIAGNOSTICS = {
|
|
|
25
25
|
HITL_APP_INPUT_UNKNOWN: { severity: 'error', summary: 'an app input the action schema does not declare' },
|
|
26
26
|
HITL_APP_INPUT_REQUIRED: { severity: 'error', summary: 'a required app input left unbound' },
|
|
27
27
|
HITL_APP_OUTCOME_UNKNOWN: { severity: 'error', summary: 'an outcome the app has no button for' },
|
|
28
|
+
HITL_APP_LOCAL_HAS_FOLDER: { severity: 'error', summary: 'an in-solution app with a folderPath' },
|
|
28
29
|
HITL_NO_FIELDS: { severity: 'error', summary: 'no fields array' },
|
|
29
30
|
HITL_FIELD_NO_ID: { severity: 'error', summary: 'a form field with no id' },
|
|
30
31
|
HITL_DUP_FIELD: { severity: 'error', summary: 'a form field id declared twice' },
|
|
@@ -185,11 +186,23 @@ export function checkHitl(inputs, ctx) {
|
|
|
185
186
|
+ `App — but names no app, so nothing tells the platform which form to show.`, `app: { name: 'Expense Review', key: '<guid>', folderPath: 'Shared' }`);
|
|
186
187
|
return;
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
+
// An in-solution app has no folder to author. A published one does: with
|
|
190
|
+
// none it is serialized as an inline app, and on a serializer before
|
|
191
|
+
// flow-v1 #4076 the task loses its folderPath context and fails at run
|
|
192
|
+
// time (170004, "Invalid input for the HITL task").
|
|
193
|
+
const inSolution = app.location === 'in-solution';
|
|
194
|
+
for (const k of inSolution ? ['name', 'key'] : ['name', 'key', 'folderPath']) {
|
|
189
195
|
if (typeof app[k] !== 'string' || !app[k].trim()) {
|
|
190
|
-
at('HITL_APP_INCOMPLETE',
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
at('HITL_APP_INCOMPLETE', inSolution
|
|
197
|
+
? `Human task "${step}" names an in-solution Action App with no ${k}. An in-solution app is `
|
|
198
|
+
+ `resolved by its key (\`resource.key\` in resources/solution_folder/app/codedAction/<App>.json), `
|
|
199
|
+
+ `with the name shown to the reviewer — both are needed for the platform to find it.`
|
|
200
|
+
: `Human task "${step}" names an Action App with no ${k}. An app is resolved by its key plus `
|
|
201
|
+
+ `the folder it is deployed in, with the name shown to the reviewer — all three are needed `
|
|
202
|
+
+ `for the platform to find it. If the app is in the same solution as the flow, set `
|
|
203
|
+
+ `\`location: 'in-solution'\` instead of a folder.`, inSolution
|
|
204
|
+
? `app: { name: 'InvoiceReview', key: '<resource.key>', location: 'in-solution' }`
|
|
205
|
+
: `app: { name: 'Expense Review', key: '<guid>', folderPath: 'Shared' }`);
|
|
193
206
|
return;
|
|
194
207
|
}
|
|
195
208
|
}
|
|
@@ -235,6 +248,12 @@ export function checkHitl(inputs, ctx) {
|
|
|
235
248
|
}
|
|
236
249
|
}
|
|
237
250
|
}
|
|
251
|
+
if (inSolution && app.folderPath !== undefined && app.folderPath !== '') {
|
|
252
|
+
at('HITL_APP_LOCAL_HAS_FOLDER', `Human task "${step}" names an in-solution Action App with folderPath ${JSON.stringify(app.folderPath)}. `
|
|
253
|
+
+ `An in-solution app has no folder — it is emitted with the empty folder the platform's app picker `
|
|
254
|
+
+ `writes for an app inline to the solution — so the value would be dropped. Remove it, or drop `
|
|
255
|
+
+ `\`location: 'in-solution'\` to call an app published to that folder.`, `Delete \`folderPath\`.`);
|
|
256
|
+
}
|
|
238
257
|
// Outcomes still matter for an app task: the flow's own routing and its
|
|
239
258
|
// `Action`/`status` outputs are derived from them, so fall through to the
|
|
240
259
|
// outcome rules below rather than returning here.
|
|
@@ -22,6 +22,7 @@ import { wireExprBody } from '../../../core/wire-expr.js';
|
|
|
22
22
|
import { appAnswerSchemas, appInputSchema, liftActionSchema, normalizeActionSchema } from './action-schema.js';
|
|
23
23
|
import { checkHitl, checkHitlRead } from './check.js';
|
|
24
24
|
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
25
|
+
import { processResourceBindings } from '../../../core/process-resource.js';
|
|
25
26
|
const BASE = 'uipath.human-in-the-loop';
|
|
26
27
|
const QUICK_FORM = 'uipath.human-in-the-loop.quick-form';
|
|
27
28
|
const ACTION_APP = 'uipath.human-in-the-loop.coded-action-app';
|
|
@@ -131,6 +132,14 @@ function hitlInputs(inputs, nodeType, ctx) {
|
|
|
131
132
|
for (const [name, value] of Object.entries(app?.inputs ?? {})) {
|
|
132
133
|
appInputBindings[name] = appBindingExpr(value, ctx);
|
|
133
134
|
}
|
|
135
|
+
const emitsApp = (isApp || (nodeType === DOC_VALIDATION && inputs?.document?.render === 'custom')) && app !== undefined;
|
|
136
|
+
// An in-solution app has no folder: the platform's own picker writes `''`,
|
|
137
|
+
// and its serializer keeps that `''` in the task context (flow-v1 #4076).
|
|
138
|
+
const appFolder = app?.location === 'in-solution' ? '' : (app?.folderPath ?? '');
|
|
139
|
+
if (emitsApp) {
|
|
140
|
+
for (const b of appResourceBindings({ name: app.name, key: app.key, folderPath: appFolder }, ctx.bindings))
|
|
141
|
+
ctx.bind(b);
|
|
142
|
+
}
|
|
134
143
|
// The author's recipient when given; the definition's own default otherwise
|
|
135
144
|
// (unchanged — that default is what 203 of 233 deployed v1 tasks carry).
|
|
136
145
|
// `1.0`: every human-task type's first bundled definition, which is the one
|
|
@@ -189,13 +198,13 @@ function hitlInputs(inputs, nodeType, ctx) {
|
|
|
189
198
|
...(inputs?.labels !== undefined ? { labels: inputs.labels } : {}),
|
|
190
199
|
recipient,
|
|
191
200
|
...docvalInputs,
|
|
192
|
-
...(
|
|
201
|
+
...(emitsApp
|
|
193
202
|
? {
|
|
194
203
|
app: {
|
|
195
204
|
displayName: app.name,
|
|
196
205
|
name: app.name,
|
|
197
206
|
key: app.key,
|
|
198
|
-
folderPath:
|
|
207
|
+
folderPath: appFolder,
|
|
199
208
|
...(app.appSystemName !== undefined ? { appSystemName: app.appSystemName } : {}),
|
|
200
209
|
// What types the task's arguments (see action-schema.ts): lowered
|
|
201
210
|
// from the action schema, or the decompiled node's own, verbatim.
|
|
@@ -230,6 +239,34 @@ function hitlInputs(inputs, nodeType, ctx) {
|
|
|
230
239
|
},
|
|
231
240
|
};
|
|
232
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* The canvas's legacy placeholder folder for an app inline to the solution. The
|
|
244
|
+
* platform's own app picker clears it to `''` (flow-v1 `HITLAppPicker.tsx`
|
|
245
|
+
* `INLINE_APP_FOLDER_TOKEN`, #4076): an inline app has no deploy-time
|
|
246
|
+
* overwrite, so the token would reach the engine literally and be refused
|
|
247
|
+
* (170000). Read back as `location: 'in-solution'`, never emitted.
|
|
248
|
+
*/
|
|
249
|
+
const INLINE_APP_FOLDER_TOKEN = 'solution_folder';
|
|
250
|
+
/**
|
|
251
|
+
* The `app` binding pair for one Action App, through the shared
|
|
252
|
+
* {@link processResourceBindings}: one pair per app, keyed the way flow-v1's app
|
|
253
|
+
* picker creates them — by the app's `key` once it has a folder, by its `name`
|
|
254
|
+
* while it has none (an in-solution app) (`hitl-serialization.ts`,
|
|
255
|
+
* `HITLAppPicker.tsx`, flow-v1 #3910). The serializer resolves the task's
|
|
256
|
+
* `<bindings.name>` / `<bindings.folderPath>` context against them; without a
|
|
257
|
+
* row the placeholder text reaches the engine, and packaging leaves the app out
|
|
258
|
+
* of `bindings_v2.json`. Serializers before #3910 (flow-converter 0.69) key the
|
|
259
|
+
* app by name only and fall back to the FIRST row named `name`/`folderPath` of
|
|
260
|
+
* any resource.
|
|
261
|
+
*/
|
|
262
|
+
function appResourceBindings(spec, existing) {
|
|
263
|
+
return processResourceBindings({
|
|
264
|
+
name: spec.name,
|
|
265
|
+
folderPath: spec.folderPath,
|
|
266
|
+
resource: 'app',
|
|
267
|
+
resourceKey: spec.folderPath ? spec.key : spec.name,
|
|
268
|
+
}, existing).entries;
|
|
269
|
+
}
|
|
233
270
|
/**
|
|
234
271
|
* One `appInputBindings` value: the expression sent to a deployed app's input.
|
|
235
272
|
*
|
|
@@ -416,7 +453,10 @@ function liftHitl(node, typeName, ctx) {
|
|
|
416
453
|
// `displayName` is serialize's echo of `name`; only `name` is authored.
|
|
417
454
|
name: String(app.name ?? ''),
|
|
418
455
|
key: String(app.key ?? ''),
|
|
419
|
-
|
|
456
|
+
// No folder (or the canvas's legacy inline placeholder) is how the platform
|
|
457
|
+
// writes an app inline to the solution.
|
|
458
|
+
...(typeof app.folderPath === 'string' && app.folderPath !== '' && app.folderPath !== INLINE_APP_FOLDER_TOKEN
|
|
459
|
+
? { folderPath: app.folderPath } : { location: 'in-solution' }),
|
|
420
460
|
...(app.appSystemName === null ? { appSystemName: null }
|
|
421
461
|
: typeof app.appSystemName === 'string' ? { appSystemName: app.appSystemName } : {}),
|
|
422
462
|
...(appInputs !== undefined ? { inputs: appInputs } : {}),
|
|
@@ -517,6 +557,7 @@ function printHitl({ inputs }, ctx) {
|
|
|
517
557
|
const app = h.app === undefined ? undefined : obj([
|
|
518
558
|
['name', ctx.string(h.app.name)],
|
|
519
559
|
['key', ctx.string(h.app.key)],
|
|
560
|
+
['location', h.app.location !== undefined ? ctx.string(h.app.location) : undefined],
|
|
520
561
|
['folderPath', h.app.folderPath !== undefined ? ctx.string(h.app.folderPath) : undefined],
|
|
521
562
|
['appSystemName', h.app.appSystemName === null ? 'null'
|
|
522
563
|
: h.app.appSystemName !== undefined ? ctx.string(h.app.appSystemName) : undefined],
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `core/actions.ts`: an agent's quick-form escalation shares them.
|
|
7
7
|
*/
|
|
8
8
|
import type { Expr } from '../../../core/expr.js';
|
|
9
|
-
import type { FormField } from '../../../core/actions.js';
|
|
9
|
+
import type { FormField, ProcessLocation } from '../../../core/actions.js';
|
|
10
10
|
/**
|
|
11
11
|
* Where the task is delivered. The four ids are the platform's own — including
|
|
12
12
|
* the lowercase `'teams'`, which is how every deployed recipient spells
|
|
@@ -164,15 +164,44 @@ export type HitlVariant = 'quick-form' | 'action-app' | 'document-validation';
|
|
|
164
164
|
* },
|
|
165
165
|
* outcomes: ['Approve', 'Reject'],
|
|
166
166
|
* })
|
|
167
|
+
*
|
|
168
|
+
* // A coded action app in the same solution as the flow:
|
|
169
|
+
* hitl({
|
|
170
|
+
* variant: 'action-app',
|
|
171
|
+
* app: { name: 'InvoiceReview', key: '<resource.key>', location: 'in-solution' },
|
|
172
|
+
* outcomes: ['Approve', 'Reject'],
|
|
173
|
+
* })
|
|
167
174
|
* ```
|
|
168
175
|
*/
|
|
169
176
|
export interface AppRef {
|
|
170
177
|
/** The app's display title, e.g. `'Expense Review'`. */
|
|
171
178
|
name: string;
|
|
172
|
-
/**
|
|
179
|
+
/**
|
|
180
|
+
* The app's key (a GUID) — how the platform resolves which app this is.
|
|
181
|
+
*
|
|
182
|
+
* For an in-solution app it is `resource.key` from
|
|
183
|
+
* `resources/solution_folder/app/codedAction/<App>.json`.
|
|
184
|
+
*/
|
|
173
185
|
key: string;
|
|
174
|
-
/**
|
|
175
|
-
|
|
186
|
+
/**
|
|
187
|
+
* Where the app lives. `'published'` (the default) is an app deployed to
|
|
188
|
+
* `folderPath`. `'in-solution'` is a coded action app in the same solution as
|
|
189
|
+
* the flow: it takes no `folderPath` — it is emitted with the empty folder
|
|
190
|
+
* and name-keyed bindings the platform's own app picker writes for an app
|
|
191
|
+
* inline to the solution. Needs a `uip` CLI with flow-converter 0.100.3 or
|
|
192
|
+
* later (or a process engine with MST-15436); older ones fail at run time
|
|
193
|
+
* with 170004.
|
|
194
|
+
*
|
|
195
|
+
* @enforcedBy HITL_APP_LOCAL_HAS_FOLDER An in-solution app takes no folderPath.
|
|
196
|
+
*/
|
|
197
|
+
location?: ProcessLocation;
|
|
198
|
+
/**
|
|
199
|
+
* Fully-qualified folder the app is deployed in, e.g. `'Shared'`. Required
|
|
200
|
+
* for a published app; omit it for an in-solution one.
|
|
201
|
+
*
|
|
202
|
+
* @enforcedBy HITL_APP_INCOMPLETE A published app needs its folder.
|
|
203
|
+
*/
|
|
204
|
+
folderPath?: string;
|
|
176
205
|
/**
|
|
177
206
|
* The app's stable system name. `null` until the app's first deployment
|
|
178
207
|
* assigns one, which is why it is optional and why `null` is a legal value
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.66.
|
|
3
|
+
"version": "6.66.3",
|
|
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",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"@types/node": "^22.7.0",
|
|
101
101
|
"esbuild": "^0.28.1"
|
|
102
102
|
},
|
|
103
|
-
"gitref": "
|
|
103
|
+
"gitref": "e7e32040e5596319cf1bccea2a6caa9124d79bbb"
|
|
104
104
|
}
|