@uipath/maestro-builder-sdk 6.8.4 → 6.8.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.
- package/dist/api-index.md +1 -1
- package/dist/check-cli.js +13 -16
- package/dist/check.d.ts +20 -0
- package/dist/check.js +46 -12
- package/dist/cli/commands/flow.js +2 -0
- package/dist/cli-library.d.ts +21 -0
- package/dist/cli-library.js +56 -0
- package/dist/compile-cli.js +12 -11
- package/dist/core/cli-spelling.d.ts +10 -0
- package/dist/core/cli-spelling.js +24 -0
- package/dist/core/library.d.ts +20 -0
- package/dist/core/library.js +97 -20
- package/dist/core/lookups.js +4 -2
- package/dist/core/node-classes.d.ts +8 -0
- package/dist/core/node-classes.js +27 -3
- package/dist/core/typed-raw-node.d.ts +97 -0
- package/dist/core/typed-raw-node.js +199 -0
- package/dist/registry/generators/markdown/sections/lookups.js +20 -5
- package/dist/registry/library-build/build.js +2 -1
- package/dist/registry/library-build/context.d.ts +26 -0
- package/dist/registry/library-build/context.js +25 -12
- package/dist/registry/library-build/events.js +3 -2
- package/dist/registry/prepare/actions.d.ts +42 -5
- package/dist/registry/prepare/actions.js +90 -16
- package/dist/registry/prepare/connections.js +2 -3
- package/dist/registry/prepare/event.d.ts +15 -6
- package/dist/registry/prepare/event.js +19 -11
- package/dist/registry/prepare/ledger.d.ts +3 -1
- package/dist/registry/prepare/ledger.js +55 -5
- package/dist/registry/prepare/messages.d.ts +40 -4
- package/dist/registry/prepare/messages.js +97 -15
- package/dist/registry/prepare/pipeline.js +19 -10
- package/dist/registry/prepare/resolve.d.ts +27 -2
- package/dist/registry/prepare/resolve.js +71 -8
- package/dist/registry/uip/envelope.d.ts +44 -9
- package/dist/registry/uip/envelope.js +80 -0
- package/dist/serialize.js +82 -9
- package/lib/library-json.samples/index.json +18 -0
- package/lib/library-json.samples/uipath-getresponse-getresponse/send-newsletter@1.0.0.json +159 -0
- package/lib/library-json.samples/uipath-getresponse-getresponse/send-newsletter@1.0.0.v1def.json +323 -0
- package/lib/library-json.samples/uipath-salesforce-slack/create-group-direct-message@1.0.0.json +149 -0
- package/lib/library-json.samples/uipath-salesforce-slack/create-group-direct-message@1.0.0.v1def.json +237 -0
- package/package.json +2 -2
package/dist/core/lookups.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* degenerate classes the generator excludes and why generating for them would
|
|
28
28
|
* make the surface worse rather than more complete.
|
|
29
29
|
*/
|
|
30
|
-
import { prepareCommand } from './cli-spelling.js';
|
|
30
|
+
import { prepareCommand, resolveFlagArg } from './cli-spelling.js';
|
|
31
31
|
/** True when `v` is an unresolved {@link LookupToken}. */
|
|
32
32
|
export function isLookupToken(v) {
|
|
33
33
|
return (typeof v === 'object' && v !== null &&
|
|
@@ -192,7 +192,9 @@ export function unresolvedLookupMessage(token) {
|
|
|
192
192
|
return (`input "${field}" is an unresolved lookup (${by}=${JSON.stringify(value)}). ` +
|
|
193
193
|
`Compile does not make network calls, so the value has to be resolved first:\n` +
|
|
194
194
|
` ${prepareCommand(key, action)} \\\n` +
|
|
195
|
-
|
|
195
|
+
// Quoted only when the shell would mangle it: a multiselect's `users[*]`
|
|
196
|
+
// is a glob and a real name has spaces, and the last line is meant to paste.
|
|
197
|
+
` --resolve ${resolveFlagArg(field, by, String(value))}`);
|
|
196
198
|
}
|
|
197
199
|
// ─── Classification, mirroring `_lookups.py` ─────────────────────────────────
|
|
198
200
|
//
|
|
@@ -217,6 +217,14 @@ export declare abstract class FlowResource extends FlowNode<never> {
|
|
|
217
217
|
* compile reports an input the static library does not carry; use
|
|
218
218
|
* {@link onEvent} for a connector event trigger.
|
|
219
219
|
*
|
|
220
|
+
* **Prefer the typed factory** for a node type that has one: `check` warns
|
|
221
|
+
* (`RAW_NODE_TYPED_FAMILY`), because `validate` cannot see an input the
|
|
222
|
+
* registry definition does not declare. For a `core.datafabric.*` type, a key
|
|
223
|
+
* the product never reads (an invented `_sortOptions` in place of `_sort`) is
|
|
224
|
+
* an error at a version the SDK bundles (`RAW_NODE_UNKNOWN_INPUT`); the
|
|
225
|
+
* canvas's snapshots, such as the `_entityFields` a related-path filter
|
|
226
|
+
* needs, stay legal.
|
|
227
|
+
*
|
|
220
228
|
* @param spec - The definition to compile against, plus the node's inputs.
|
|
221
229
|
* @returns A node to pass to `.step(...)`.
|
|
222
230
|
*/
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* built-in rules with the same severities.
|
|
25
25
|
*/
|
|
26
26
|
import { connectorRawNodeRefusal } from './connector-raw-node.js';
|
|
27
|
+
import { typedFamilyRawNodeWarning, dataFabricUnknownInputs } from './typed-raw-node.js';
|
|
27
28
|
/**
|
|
28
29
|
* The abstract root of every definition-backed node the builder can place.
|
|
29
30
|
*
|
|
@@ -113,6 +114,14 @@ export class FlowResource extends FlowNode {
|
|
|
113
114
|
* compile reports an input the static library does not carry; use
|
|
114
115
|
* {@link onEvent} for a connector event trigger.
|
|
115
116
|
*
|
|
117
|
+
* **Prefer the typed factory** for a node type that has one: `check` warns
|
|
118
|
+
* (`RAW_NODE_TYPED_FAMILY`), because `validate` cannot see an input the
|
|
119
|
+
* registry definition does not declare. For a `core.datafabric.*` type, a key
|
|
120
|
+
* the product never reads (an invented `_sortOptions` in place of `_sort`) is
|
|
121
|
+
* an error at a version the SDK bundles (`RAW_NODE_UNKNOWN_INPUT`); the
|
|
122
|
+
* canvas's snapshots, such as the `_entityFields` a related-path filter
|
|
123
|
+
* needs, stay legal.
|
|
124
|
+
*
|
|
116
125
|
* @param spec - The definition to compile against, plus the node's inputs.
|
|
117
126
|
* @returns A node to pass to `.step(...)`.
|
|
118
127
|
*/
|
|
@@ -126,14 +135,29 @@ class RawNode extends FlowAction {
|
|
|
126
135
|
super();
|
|
127
136
|
this.spec = spec;
|
|
128
137
|
}
|
|
129
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* `check` surfaces the connector refusal as an error, a typed family as a
|
|
140
|
+
* warning, and a Data Fabric key the product never reads as an error at a
|
|
141
|
+
* bundled version (a warning at any other); `compile` throws the errors
|
|
142
|
+
* (see {@link contribute}).
|
|
143
|
+
*/
|
|
130
144
|
diagnostics() {
|
|
131
145
|
const refusal = connectorRawNodeRefusal(this.spec.nodeType);
|
|
132
|
-
|
|
146
|
+
if (refusal)
|
|
147
|
+
return [{ code: 'RAW_NODE_CONNECTOR', severity: 'error', message: refusal }];
|
|
148
|
+
const out = [];
|
|
149
|
+
const unknown = dataFabricUnknownInputs(this.spec.nodeType, this.spec.version, this.spec.inputs);
|
|
150
|
+
if (unknown)
|
|
151
|
+
out.push({ code: 'RAW_NODE_UNKNOWN_INPUT', ...unknown });
|
|
152
|
+
const typed = typedFamilyRawNodeWarning(this.spec.nodeType);
|
|
153
|
+
if (typed)
|
|
154
|
+
out.push({ code: 'RAW_NODE_TYPED_FAMILY', severity: 'warning', message: typed });
|
|
155
|
+
return out;
|
|
133
156
|
}
|
|
134
157
|
contribute(context) {
|
|
135
158
|
// compile does not run diagnostics(); refuse here too so the escape hatch
|
|
136
|
-
// cannot emit an unconfigured connector node.
|
|
159
|
+
// cannot emit an unconfigured connector node. (A Data Fabric key the
|
|
160
|
+
// product never reads is refused by the serializer, for every contribution.)
|
|
137
161
|
const refusal = connectorRawNodeRefusal(this.spec.nodeType);
|
|
138
162
|
if (refusal)
|
|
139
163
|
throw new Error(refusal);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal: what `check` and `compile` say about a `rawNode` for a node type
|
|
3
|
+
* the SDK has a typed factory for, and the Data Fabric input keys it may carry.
|
|
4
|
+
* Not re-exported from the package entry point.
|
|
5
|
+
*/
|
|
6
|
+
/** The factory to use for one node type, and the versions of it the SDK bundles. */
|
|
7
|
+
export interface TypedFactory {
|
|
8
|
+
/** The typed spelling, as the refusal names it. */
|
|
9
|
+
factory: string;
|
|
10
|
+
/**
|
|
11
|
+
* Every `<version>` with a `<nodeType>@<version>` entry in `core-definitions.json`.
|
|
12
|
+
* Listed here rather than read from the file because this module sits under
|
|
13
|
+
* `node-classes.ts`, which must not import `node:*`; `raw-node-typed-family.test.ts`
|
|
14
|
+
* pins the two equal.
|
|
15
|
+
*/
|
|
16
|
+
bundled: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Every node type the SDK authors as a STEP through a typed factory, with the
|
|
20
|
+
* factory to use. `raw-node-typed-family.test.ts` pins the key set to the
|
|
21
|
+
* `flow-coverage.json` rows with `support: 'typed'` and a `bundledKey`, so a
|
|
22
|
+
* family that gains a factory gains its row here too.
|
|
23
|
+
*
|
|
24
|
+
* Two groups of typed rows are left out, because neither is ever a step:
|
|
25
|
+
* triggers (`core.trigger.*`, placed by `.trigger()`) and agent resources
|
|
26
|
+
* (`uipath.agent.resource.*`, attached to an agent). `decompile` keeps an
|
|
27
|
+
* orphaned one as a `rawNode`, and a warning on that round trip would be noise.
|
|
28
|
+
*
|
|
29
|
+
* The Data Fabric verbs name their options, because the query and write keys
|
|
30
|
+
* an author reaches for by hand (`_filters`, `_sort`, `fieldValues`, …) each
|
|
31
|
+
* have a typed spelling.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TYPED_FACTORIES: Readonly<Record<string, TypedFactory>>;
|
|
34
|
+
/**
|
|
35
|
+
* Every `entityConfig` key the product reads or persists on a Data Fabric node,
|
|
36
|
+
* across the four verbs. flow-workbench develop `eed682f19`:
|
|
37
|
+
*
|
|
38
|
+
* - services `serialization/entity-vdo.ts` `interface EntityConfig` (:229-272):
|
|
39
|
+
* `entityName`, `resultMode`, `_recordLimit`, `_skip`, `_sort`,
|
|
40
|
+
* `_selectedFieldNames`, `_filters`, `_entityFields`, `_relatedFields`,
|
|
41
|
+
* `_folderKey`, `_entityKey`, `_resourceKey`, `_outputSchema`;
|
|
42
|
+
* `CreateEntityConfig` (:719) adds `fieldValues`; `UpdateEntityConfig` (:744)
|
|
43
|
+
* adds `recordSource`, `readEntityNodeId`, `recordId`, `fieldUpdates`.
|
|
44
|
+
* - canvas `properties-panel/EntityConfigField.tsx` `EntityConfigInputs`
|
|
45
|
+
* (:85-110) and `entity/useEntityPanelState.ts` `EntitySelectionPatch`
|
|
46
|
+
* (:248-270), which the panels persist on an entity pick:
|
|
47
|
+
* `_entityDisplayName`, `_choiceSets`, `_folderPath`, `_entitySubType`.
|
|
48
|
+
* - Create/Update/DeleteEntityConfigField.tsx declare nothing beyond these.
|
|
49
|
+
*
|
|
50
|
+
* One union rather than one set per verb: a key another verb reads is at worst
|
|
51
|
+
* ignored, and a per-verb split would refuse a canvas-written key on a verb
|
|
52
|
+
* whose panel happens not to declare it. The test pins every key the typed
|
|
53
|
+
* factories write to this set.
|
|
54
|
+
*/
|
|
55
|
+
export declare const DATAFABRIC_ENTITY_CONFIG_KEYS: ReadonlySet<string>;
|
|
56
|
+
/**
|
|
57
|
+
* A reminder, as a `warning`, that a `rawNode` stands in for a typed factory,
|
|
58
|
+
* or `undefined` for a type with no factory.
|
|
59
|
+
*
|
|
60
|
+
* A warning and never an error: a factory does not always write every input its
|
|
61
|
+
* node reads (the Data Fabric verbs do not write `_entityFields`, which a
|
|
62
|
+
* related-path filter needs), and nothing checks factory coverage family by
|
|
63
|
+
* family. So the raw node keeps compiling at every version. The one failure
|
|
64
|
+
* the eval archive measured, an invented key the node never reads, is refused
|
|
65
|
+
* by {@link dataFabricUnknownInputs} instead.
|
|
66
|
+
*
|
|
67
|
+
* @param nodeType - The definition's `nodeType`, as passed to `rawNode`.
|
|
68
|
+
* @returns The warning, or `undefined` for a type with no typed factory.
|
|
69
|
+
*/
|
|
70
|
+
export declare function typedFamilyRawNodeWarning(nodeType: string): string | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Why a `core.datafabric.*` node's inputs carry a key the product never reads,
|
|
73
|
+
* or `undefined` when they do not.
|
|
74
|
+
*
|
|
75
|
+
* This is where the eval failure became possible. A raw node renders its inputs
|
|
76
|
+
* verbatim, and `core.datafabric.read@1.4`'s registry definition declares only
|
|
77
|
+
* `entityName` and `resultMode`, so `validate` cannot see any other key. Measured
|
|
78
|
+
* on the eval archive (2026-09-23, skill-flow-datafabric-native-contract-intake-pipeline):
|
|
79
|
+
* the agent wrote `_sortOptions: [{ fieldName, isDescending }]` in place of
|
|
80
|
+
* `_sort`, `check` printed "no issues", `validate` said Valid, and the query
|
|
81
|
+
* would have run unsorted. The allowed set is what the product reads
|
|
82
|
+
* ({@link DATAFABRIC_ENTITY_CONFIG_KEYS}), so `_entityFields` and the other
|
|
83
|
+
* canvas snapshots stay legal.
|
|
84
|
+
*
|
|
85
|
+
* Severity follows the version: at a bundled `<nodeType>@<version>` the key set
|
|
86
|
+
* is known, so the key is refused (`error`); at a version this SDK has not
|
|
87
|
+
* synced, a newer node could read a new key, so it is reported (`warning`).
|
|
88
|
+
*
|
|
89
|
+
* @param nodeType - The node's type.
|
|
90
|
+
* @param version - The version the node is emitted at.
|
|
91
|
+
* @param inputs - The node's inputs, before rendering.
|
|
92
|
+
* @returns The diagnostic, or `undefined` for a clean node or a non-Data-Fabric type.
|
|
93
|
+
*/
|
|
94
|
+
export declare function dataFabricUnknownInputs(nodeType: string, version: string, inputs: unknown): {
|
|
95
|
+
severity: 'error' | 'warning';
|
|
96
|
+
message: string;
|
|
97
|
+
} | undefined;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal: what `check` and `compile` say about a `rawNode` for a node type
|
|
3
|
+
* the SDK has a typed factory for, and the Data Fabric input keys it may carry.
|
|
4
|
+
* Not re-exported from the package entry point.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Every node type the SDK authors as a STEP through a typed factory, with the
|
|
8
|
+
* factory to use. `raw-node-typed-family.test.ts` pins the key set to the
|
|
9
|
+
* `flow-coverage.json` rows with `support: 'typed'` and a `bundledKey`, so a
|
|
10
|
+
* family that gains a factory gains its row here too.
|
|
11
|
+
*
|
|
12
|
+
* Two groups of typed rows are left out, because neither is ever a step:
|
|
13
|
+
* triggers (`core.trigger.*`, placed by `.trigger()`) and agent resources
|
|
14
|
+
* (`uipath.agent.resource.*`, attached to an agent). `decompile` keeps an
|
|
15
|
+
* orphaned one as a `rawNode`, and a warning on that round trip would be noise.
|
|
16
|
+
*
|
|
17
|
+
* The Data Fabric verbs name their options, because the query and write keys
|
|
18
|
+
* an author reaches for by hand (`_filters`, `_sort`, `fieldValues`, …) each
|
|
19
|
+
* have a typed spelling.
|
|
20
|
+
*/
|
|
21
|
+
export const TYPED_FACTORIES = {
|
|
22
|
+
'core.action.http': { factory: 'http({ managed: false })', bundled: ['1.0.0'] },
|
|
23
|
+
'core.action.http.v2': { factory: 'http({ managed: true })', bundled: ['2.3'] },
|
|
24
|
+
'core.action.queue.create': { factory: 'queueItem()', bundled: ['1.2'] },
|
|
25
|
+
'core.action.queue.create-and-wait': { factory: 'queueItem({ wait: true })', bundled: ['1.2'] },
|
|
26
|
+
'core.action.script': { factory: 'script()', bundled: ['1.0.0', '1.1'] },
|
|
27
|
+
'core.action.transform': { factory: 'transform()', bundled: ['1.0.0', '1.1'] },
|
|
28
|
+
'core.action.transform.filter': { factory: "transform({ variant: 'filter' })", bundled: ['1.0.0', '1.1'] },
|
|
29
|
+
'core.action.transform.group-by': { factory: "transform({ variant: 'group-by' })", bundled: ['1.0.0', '1.1'] },
|
|
30
|
+
'core.action.transform.map': { factory: "transform({ variant: 'map' })", bundled: ['1.0.0', '1.1'] },
|
|
31
|
+
'core.control.end': { factory: '.return()', bundled: ['1.0.0', '1.0'] },
|
|
32
|
+
'core.datafabric.read': {
|
|
33
|
+
factory: "dataFabricRead({ entity, resultMode: 'single' | 'multiple', filters: [{ field, operator, value, or }], "
|
|
34
|
+
+ 'sort: { field, direction }, limit, skip, fields, folderKey })',
|
|
35
|
+
bundled: ['1.0', '1.4'],
|
|
36
|
+
},
|
|
37
|
+
'core.datafabric.create': {
|
|
38
|
+
factory: 'dataFabricCreate({ entity, values: { <field>: <value> }, folderKey })',
|
|
39
|
+
bundled: ['1.3'],
|
|
40
|
+
},
|
|
41
|
+
'core.datafabric.update': {
|
|
42
|
+
factory: 'dataFabricUpdate({ entity, record: { byId } | { fromRead }, set: { <field>: <value> }, folderKey })',
|
|
43
|
+
bundled: ['1.0', '1.3'],
|
|
44
|
+
},
|
|
45
|
+
'core.datafabric.delete': {
|
|
46
|
+
factory: 'dataFabricDelete({ entity, record: { byId } | { fromRead }, folderKey })',
|
|
47
|
+
bundled: ['1.3'],
|
|
48
|
+
},
|
|
49
|
+
'core.logic.decision': { factory: '.branch()', bundled: ['1.0.0', '1.3'] },
|
|
50
|
+
'core.logic.delay': { factory: 'delay({ duration })', bundled: ['1.0.0', '1.0'] },
|
|
51
|
+
'core.logic.dowhile': { factory: '.doWhile(name, condition, body, { limit, breakEnabled })', bundled: ['1.0'] },
|
|
52
|
+
'core.logic.loop': { factory: '.loop()', bundled: ['1.0.0', '2.4'] },
|
|
53
|
+
'core.logic.merge': { factory: '.parallel() rejoin', bundled: ['1.0.0', '1.0'] },
|
|
54
|
+
'core.logic.mock': { factory: 'mock()', bundled: ['1.0.0', '1.0'] },
|
|
55
|
+
'core.logic.switch': { factory: '.switch()', bundled: ['1.0.0', '1.1'] },
|
|
56
|
+
'core.logic.terminate': { factory: '.terminate()', bundled: ['1.0.0', '1.0'] },
|
|
57
|
+
'core.subflow': { factory: 'subflow(child, inputs)', bundled: ['1.0.0', '1.0'] },
|
|
58
|
+
'uipath.agent.conversational': { factory: 'conversationalAgent()', bundled: ['1.6', '1.7'] },
|
|
59
|
+
'uipath.agent.voice': { factory: 'voiceAgent()', bundled: ['1.0', '1.1'] },
|
|
60
|
+
'uipath.conversational.get-conversation-context': { factory: 'conversationContext()', bundled: ['1.0'] },
|
|
61
|
+
'uipath.conversational.send-message': { factory: 'sendMessage()', bundled: ['1.0', '1.1'] },
|
|
62
|
+
'uipath.conversational.voice.create-outgoing-call': { factory: 'createOutgoingCall()', bundled: ['1.0'] },
|
|
63
|
+
'uipath.conversational.voice.end-call': { factory: 'endCall()', bundled: ['1.0'] },
|
|
64
|
+
'uipath.conversational.wait-for-message': { factory: 'waitForMessage()', bundled: ['1.0', '1.1'] },
|
|
65
|
+
'uipath.document.classify': { factory: 'documentClassify()', bundled: ['1.0'] },
|
|
66
|
+
'uipath.human-in-the-loop': { factory: 'hitl()', bundled: ['1.0', '1.1', '1.2'] },
|
|
67
|
+
'uipath.human-in-the-loop.coded-action-app': {
|
|
68
|
+
factory: "hitl({ variant: 'action-app' })",
|
|
69
|
+
bundled: ['1.0', '1.1'],
|
|
70
|
+
},
|
|
71
|
+
'uipath.human-in-the-loop.document-validation': {
|
|
72
|
+
factory: "hitl({ variant: 'document-validation' })",
|
|
73
|
+
bundled: ['1.0'],
|
|
74
|
+
},
|
|
75
|
+
'uipath.human-in-the-loop.quick-form': { factory: "hitl({ variant: 'quick-form' })", bundled: ['1.0', '1.1'] },
|
|
76
|
+
'uipath.pattern.batch-transform': { factory: 'batchTransform()', bundled: ['1.0'] },
|
|
77
|
+
'uipath.pattern.deep-rag': { factory: 'summarize()', bundled: ['1.0'] },
|
|
78
|
+
'uipath.ixp.extract-document-builder': { factory: 'dynamicExtract()', bundled: ['1.0.0'] },
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Every `entityConfig` key the product reads or persists on a Data Fabric node,
|
|
82
|
+
* across the four verbs. flow-workbench develop `eed682f19`:
|
|
83
|
+
*
|
|
84
|
+
* - services `serialization/entity-vdo.ts` `interface EntityConfig` (:229-272):
|
|
85
|
+
* `entityName`, `resultMode`, `_recordLimit`, `_skip`, `_sort`,
|
|
86
|
+
* `_selectedFieldNames`, `_filters`, `_entityFields`, `_relatedFields`,
|
|
87
|
+
* `_folderKey`, `_entityKey`, `_resourceKey`, `_outputSchema`;
|
|
88
|
+
* `CreateEntityConfig` (:719) adds `fieldValues`; `UpdateEntityConfig` (:744)
|
|
89
|
+
* adds `recordSource`, `readEntityNodeId`, `recordId`, `fieldUpdates`.
|
|
90
|
+
* - canvas `properties-panel/EntityConfigField.tsx` `EntityConfigInputs`
|
|
91
|
+
* (:85-110) and `entity/useEntityPanelState.ts` `EntitySelectionPatch`
|
|
92
|
+
* (:248-270), which the panels persist on an entity pick:
|
|
93
|
+
* `_entityDisplayName`, `_choiceSets`, `_folderPath`, `_entitySubType`.
|
|
94
|
+
* - Create/Update/DeleteEntityConfigField.tsx declare nothing beyond these.
|
|
95
|
+
*
|
|
96
|
+
* One union rather than one set per verb: a key another verb reads is at worst
|
|
97
|
+
* ignored, and a per-verb split would refuse a canvas-written key on a verb
|
|
98
|
+
* whose panel happens not to declare it. The test pins every key the typed
|
|
99
|
+
* factories write to this set.
|
|
100
|
+
*/
|
|
101
|
+
export const DATAFABRIC_ENTITY_CONFIG_KEYS = new Set([
|
|
102
|
+
'entityName', 'resultMode',
|
|
103
|
+
'_recordLimit', '_skip', '_sort', '_selectedFieldNames', '_filters',
|
|
104
|
+
'_entityFields', '_relatedFields', '_choiceSets', '_outputSchema',
|
|
105
|
+
'_folderKey', '_folderPath', '_entityKey', '_resourceKey', '_entityDisplayName', '_entitySubType',
|
|
106
|
+
'fieldValues', 'fieldUpdates', 'recordSource', 'readEntityNodeId', 'recordId',
|
|
107
|
+
]);
|
|
108
|
+
/**
|
|
109
|
+
* What the Data Fabric factories write, and what they do not, as the typed-family
|
|
110
|
+
* warning states it. The factories do not author the canvas's column snapshots,
|
|
111
|
+
* so a related-path filter (`customer.Name`) still needs a raw node carrying
|
|
112
|
+
* `_entityFields` (core/actions.ts `DataFabricFilter.field`).
|
|
113
|
+
*/
|
|
114
|
+
const DATAFABRIC_HINT = ' The factory writes the query and write keys: `filters` becomes `_filters` (flat rows; `or: true` '
|
|
115
|
+
+ 'starts each OR alternative), `sort` is `_sort`, `limit`/`skip`/`fields` are '
|
|
116
|
+
+ '`_recordLimit`/`_skip`/`_selectedFieldNames`, `values`/`set` are `fieldValues`/`fieldUpdates`, '
|
|
117
|
+
+ 'and `record` is `recordSource`. It does not write the column snapshots `_entityFields`, '
|
|
118
|
+
+ '`_relatedFields`, `_choiceSets` or `_outputSchema`; a related-path filter such as '
|
|
119
|
+
+ '`customer.Name` needs `_entityFields`, so for that a raw node is still the way.';
|
|
120
|
+
/**
|
|
121
|
+
* A reminder, as a `warning`, that a `rawNode` stands in for a typed factory,
|
|
122
|
+
* or `undefined` for a type with no factory.
|
|
123
|
+
*
|
|
124
|
+
* A warning and never an error: a factory does not always write every input its
|
|
125
|
+
* node reads (the Data Fabric verbs do not write `_entityFields`, which a
|
|
126
|
+
* related-path filter needs), and nothing checks factory coverage family by
|
|
127
|
+
* family. So the raw node keeps compiling at every version. The one failure
|
|
128
|
+
* the eval archive measured, an invented key the node never reads, is refused
|
|
129
|
+
* by {@link dataFabricUnknownInputs} instead.
|
|
130
|
+
*
|
|
131
|
+
* @param nodeType - The definition's `nodeType`, as passed to `rawNode`.
|
|
132
|
+
* @returns The warning, or `undefined` for a type with no typed factory.
|
|
133
|
+
*/
|
|
134
|
+
export function typedFamilyRawNodeWarning(nodeType) {
|
|
135
|
+
if (typeof nodeType !== 'string')
|
|
136
|
+
return undefined;
|
|
137
|
+
const entry = TYPED_FACTORIES[nodeType];
|
|
138
|
+
if (entry === undefined)
|
|
139
|
+
return undefined;
|
|
140
|
+
const hint = nodeType.startsWith('core.datafabric.') ? DATAFABRIC_HINT : '';
|
|
141
|
+
return `rawNode("${nodeType}"): this SDK has a typed factory, ${entry.factory}. A raw node keeps its `
|
|
142
|
+
+ `inputs verbatim, and \`validate\` cannot see a key the registry definition does not declare, so a `
|
|
143
|
+
+ `misspelled input compiles and is ignored at run time. Prefer the factory unless you need an input it `
|
|
144
|
+
+ `does not write.${hint}`;
|
|
145
|
+
}
|
|
146
|
+
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && Object.getPrototypeOf(v) === Object.prototype;
|
|
147
|
+
/**
|
|
148
|
+
* Why a `core.datafabric.*` node's inputs carry a key the product never reads,
|
|
149
|
+
* or `undefined` when they do not.
|
|
150
|
+
*
|
|
151
|
+
* This is where the eval failure became possible. A raw node renders its inputs
|
|
152
|
+
* verbatim, and `core.datafabric.read@1.4`'s registry definition declares only
|
|
153
|
+
* `entityName` and `resultMode`, so `validate` cannot see any other key. Measured
|
|
154
|
+
* on the eval archive (2026-09-23, skill-flow-datafabric-native-contract-intake-pipeline):
|
|
155
|
+
* the agent wrote `_sortOptions: [{ fieldName, isDescending }]` in place of
|
|
156
|
+
* `_sort`, `check` printed "no issues", `validate` said Valid, and the query
|
|
157
|
+
* would have run unsorted. The allowed set is what the product reads
|
|
158
|
+
* ({@link DATAFABRIC_ENTITY_CONFIG_KEYS}), so `_entityFields` and the other
|
|
159
|
+
* canvas snapshots stay legal.
|
|
160
|
+
*
|
|
161
|
+
* Severity follows the version: at a bundled `<nodeType>@<version>` the key set
|
|
162
|
+
* is known, so the key is refused (`error`); at a version this SDK has not
|
|
163
|
+
* synced, a newer node could read a new key, so it is reported (`warning`).
|
|
164
|
+
*
|
|
165
|
+
* @param nodeType - The node's type.
|
|
166
|
+
* @param version - The version the node is emitted at.
|
|
167
|
+
* @param inputs - The node's inputs, before rendering.
|
|
168
|
+
* @returns The diagnostic, or `undefined` for a clean node or a non-Data-Fabric type.
|
|
169
|
+
*/
|
|
170
|
+
export function dataFabricUnknownInputs(nodeType, version, inputs) {
|
|
171
|
+
if (typeof nodeType !== 'string' || !nodeType.startsWith('core.datafabric.'))
|
|
172
|
+
return undefined;
|
|
173
|
+
if (!isPlainObject(inputs))
|
|
174
|
+
return undefined;
|
|
175
|
+
const unknown = Object.keys(inputs).filter((k) => k !== 'entityConfig');
|
|
176
|
+
const cfg = inputs.entityConfig;
|
|
177
|
+
if (isPlainObject(cfg)) {
|
|
178
|
+
for (const k of Object.keys(cfg))
|
|
179
|
+
if (!DATAFABRIC_ENTITY_CONFIG_KEYS.has(k))
|
|
180
|
+
unknown.push(`entityConfig.${k}`);
|
|
181
|
+
}
|
|
182
|
+
if (unknown.length === 0)
|
|
183
|
+
return undefined;
|
|
184
|
+
const bundled = TYPED_FACTORIES[nodeType]?.bundled.includes(version) ?? false;
|
|
185
|
+
const named = unknown.map((k) => `\`${k}\``).join(', ');
|
|
186
|
+
const factory = TYPED_FACTORIES[nodeType]?.factory;
|
|
187
|
+
const base = `${nodeType}@${version} carries ${named}, which the platform never reads: Data Fabric `
|
|
188
|
+
+ `nodes read only \`inputs.entityConfig\`, with the keys ${[...DATAFABRIC_ENTITY_CONFIG_KEYS].join(', ')} `
|
|
189
|
+
+ `(flow-workbench entity-vdo.ts \`EntityConfig\` and the entity panels). \`validate\` cannot see `
|
|
190
|
+
+ `the key, so it compiles and is ignored at run time; for example a sort is \`_sort: { field, direction }\`, `
|
|
191
|
+
+ `not \`_sortOptions\`.${factory ? ` The typed factory, ${factory}, writes only keys the node reads.` : ''}`;
|
|
192
|
+
if (bundled)
|
|
193
|
+
return { severity: 'error', message: base };
|
|
194
|
+
return {
|
|
195
|
+
severity: 'warning',
|
|
196
|
+
message: `${base} This SDK does not bundle ${nodeType}@${version}, so a newer node may read the key; `
|
|
197
|
+
+ 'it compiles as written.',
|
|
198
|
+
};
|
|
199
|
+
}
|
|
@@ -11,6 +11,7 @@ import { sortedStrings } from "../../../compat/compare.js";
|
|
|
11
11
|
import { pyStr, splitOnce } from "../../../compat/pystr.js";
|
|
12
12
|
import { classify, referenceOf } from "../../../lookup-specs.js";
|
|
13
13
|
import { byAliases } from "../../../naming.js";
|
|
14
|
+
import { resolveFlagArg } from "../../../../core/cli-spelling.js";
|
|
14
15
|
import { authoringField, referenceCollection, referenceQuery } from "../common.js";
|
|
15
16
|
import { firstValue, IDENT, pyOr, pyTruthy, strList } from "../pyvalue.js";
|
|
16
17
|
/** The `resources run list` call that shows what an identity-lookup field accepts. */
|
|
@@ -85,9 +86,21 @@ export function lookupLines(connectorKey, action, fields, symbol, invariant) {
|
|
|
85
86
|
"different connection. Resolve it late:");
|
|
86
87
|
out.push("");
|
|
87
88
|
out.push("```ts");
|
|
88
|
-
// A
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
// A plain multiselect (`users[*]`) is authored as an array of lookups under
|
|
90
|
+
// its authoring name, the same form `## Example` prints and the one that
|
|
91
|
+
// compiles to one id per element. Any other wire name is written as a key —
|
|
92
|
+
// a dotted one is a legal object key only when quoted — and one ending in
|
|
93
|
+
// `[*]` (`recipients.listIds[*]`) still names ONE list, so its value is an
|
|
94
|
+
// array too: the flat key compiles to the same list the nested
|
|
95
|
+
// `recipients: { listIds: [...] }` of `## Example` does.
|
|
96
|
+
const [authoringName, , multiselectWire] = authoringField(firstField);
|
|
97
|
+
if (multiselectWire) {
|
|
98
|
+
out.push(`${authoringName}: [${call}${sample}]`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const key = IDENT.test(firstName) ? firstName : pyJsonString(firstName);
|
|
102
|
+
out.push(firstName.endsWith("[*]") ? `${key}: [${call}${sample}]` : `${key}: ${call}${sample}`);
|
|
103
|
+
}
|
|
91
104
|
out.push("```");
|
|
92
105
|
out.push("");
|
|
93
106
|
out.push("| field | helpers | matches on | sends |");
|
|
@@ -116,10 +129,12 @@ export function lookupLines(connectorKey, action, fields, symbol, invariant) {
|
|
|
116
129
|
// ONE command carrying every --resolve, and no `--connection-id`.
|
|
117
130
|
out.push("```bash");
|
|
118
131
|
out.push(`npx flow-sdk registry prepare ${connectorKey} ${action} \\`);
|
|
132
|
+
// The WIRE name (`users[*]`), which is what prepare's lookup table is keyed
|
|
133
|
+
// on — the authoring name (`users`) is refused as RESOLVE_UNKNOWN_FIELD.
|
|
119
134
|
const resolves = resolvable.map(([f, reference]) => {
|
|
120
|
-
const
|
|
135
|
+
const wire = pyStr(pyOr(f.name, authoringField(f)[0]));
|
|
121
136
|
const names = pyOr(strList(reference.lookupNames), ["id"]);
|
|
122
|
-
return ` --resolve ${
|
|
137
|
+
return ` --resolve ${resolveFlagArg(wire, names[0], "<value>")}`;
|
|
123
138
|
});
|
|
124
139
|
for (const line of resolves.slice(0, -1))
|
|
125
140
|
out.push(`${line} \\`);
|
|
@@ -15,6 +15,7 @@ import { pyStr } from "../compat/pystr.js";
|
|
|
15
15
|
import { mapConcurrent } from "../concurrency.js";
|
|
16
16
|
import { Refusal, messageOf } from "../errors.js";
|
|
17
17
|
import { registrySearchConnectors } from "../uip/commands.js";
|
|
18
|
+
import { failureReason } from "../uip/envelope.js";
|
|
18
19
|
import { applyCuratedOverrides, extractCanonical, filterNodeTypesByTier, mergeConnectorRecord, nodeOf, scopedConnectorKey, selectPublishedConnectors, } from "./canonical.js";
|
|
19
20
|
import { SEARCH_RESULTS_NAME, createBuildContext, isConnectorGet, registryCacheName, registryGet, } from "./context.js";
|
|
20
21
|
import { enrichAll } from "./enrich.js";
|
|
@@ -53,7 +54,7 @@ export async function registrySearch(ctx) {
|
|
|
53
54
|
ctx.reporter.info("Running registry search...");
|
|
54
55
|
const result = await ctx.client.run(registrySearchConnectors(), ctx.timeoutMs === undefined ? undefined : { timeoutMs: ctx.timeoutMs });
|
|
55
56
|
if (result.code !== 0)
|
|
56
|
-
throw new Refusal(`Registry search failed: ${result
|
|
57
|
+
throw new Refusal(`Registry search failed: ${failureReason(result)}`, "REGISTRY_SEARCH_FAILED");
|
|
57
58
|
ctx.caches.registry.write(SEARCH_RESULTS_NAME, undefined, result.stdout);
|
|
58
59
|
}
|
|
59
60
|
const data = ctx.caches.registry.read(SEARCH_RESULTS_NAME);
|
|
@@ -60,6 +60,32 @@ export declare function registryCacheName(nodeType: string): string;
|
|
|
60
60
|
export declare const SEARCH_RESULTS_NAME = "_search_results.json";
|
|
61
61
|
/** `json.dump(payload, f)`: cache bytes shaped as Python wrote them. */
|
|
62
62
|
export declare function writeCache(cache: ResponseCache, name: string, payload: unknown): void;
|
|
63
|
+
/** A `registry get` that did not answer with the node, and why. */
|
|
64
|
+
export interface RegistryMiss {
|
|
65
|
+
nodeType: string;
|
|
66
|
+
/** The CLI's own reason ({@link failureReason}); never empty. */
|
|
67
|
+
reason: string;
|
|
68
|
+
/**
|
|
69
|
+
* True only for the CLI's "Node not found" answer — the node is absent. False
|
|
70
|
+
* for every failure of the LOOKUP (an error, a refusal, a timeout), which says
|
|
71
|
+
* nothing about whether the node exists.
|
|
72
|
+
*/
|
|
73
|
+
notFound: boolean;
|
|
74
|
+
}
|
|
75
|
+
/** {@link registryProbe}'s answer: the cache name of the reply, or the miss. */
|
|
76
|
+
export type RegistryProbe = {
|
|
77
|
+
name: string;
|
|
78
|
+
} | {
|
|
79
|
+
miss: RegistryMiss;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Cached `uip maestro flow registry get <nodeType>`, reporting nothing.
|
|
83
|
+
*
|
|
84
|
+
* The caller gets the miss with its reason and decides what to say — a caller
|
|
85
|
+
* probing which namespace an operation lives in puts every probe's reason into
|
|
86
|
+
* one refusal instead of a WARN per probe.
|
|
87
|
+
*/
|
|
88
|
+
export declare function registryProbe(ctx: BuildContext, nodeType: string): Promise<RegistryProbe>;
|
|
63
89
|
/**
|
|
64
90
|
* `registry_get`: cached `uip maestro flow registry get <nodeType>`.
|
|
65
91
|
*
|
|
@@ -18,7 +18,7 @@ import { pyJsonStringify } from "../codecs/pyjson.js";
|
|
|
18
18
|
import { sortedByKeys } from "../compat/compare.js";
|
|
19
19
|
import { isConnectorsMetadata, isResourcesDescribeObject, isResourcesDescribeOperation, isResourcesList as isResourcesListArgv, registryGet as registryGetArgv, } from "../uip/commands.js";
|
|
20
20
|
import { CACHED_FAILURE, isCachedFailure, safeCacheName } from "../uip/response-cache.js";
|
|
21
|
-
import {
|
|
21
|
+
import { failureReason, isNodeNotFound } from "../uip/envelope.js";
|
|
22
22
|
import { get, isRecord, pyOr, truthy } from "./py.js";
|
|
23
23
|
export function createBuildContext(ports, scope = {}) {
|
|
24
24
|
const parentFields = scope.parentFields instanceof Map
|
|
@@ -116,25 +116,38 @@ function envelope(payload) {
|
|
|
116
116
|
return payload;
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
119
|
+
* Cached `uip maestro flow registry get <nodeType>`, reporting nothing.
|
|
120
120
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* expected answer rather than a problem to report.
|
|
121
|
+
* The caller gets the miss with its reason and decides what to say — a caller
|
|
122
|
+
* probing which namespace an operation lives in puts every probe's reason into
|
|
123
|
+
* one refusal instead of a WARN per probe.
|
|
125
124
|
*/
|
|
126
|
-
export async function
|
|
125
|
+
export async function registryProbe(ctx, nodeType) {
|
|
127
126
|
const name = registryCacheName(nodeType);
|
|
128
127
|
if (ctx.caches.registry.has(name))
|
|
129
|
-
return name;
|
|
128
|
+
return { name };
|
|
130
129
|
const result = await runUip(ctx, registryGetArgv(nodeType, ctx.connectionId));
|
|
131
130
|
if (result.code !== 0) {
|
|
132
|
-
|
|
133
|
-
ctx.reporter.warn(` WARN: registry get failed for ${nodeType}: ${pyStrip(result.stderr)}`);
|
|
134
|
-
return undefined;
|
|
131
|
+
return { miss: { nodeType, reason: failureReason(result), notFound: isNodeNotFound(result) } };
|
|
135
132
|
}
|
|
136
133
|
ctx.caches.registry.write(name, undefined, result.stdout);
|
|
137
|
-
return name;
|
|
134
|
+
return { name };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* `registry_get`: cached `uip maestro flow registry get <nodeType>`.
|
|
138
|
+
*
|
|
139
|
+
* Returns the cache name the raw stdout lives under, or `undefined` when the
|
|
140
|
+
* call failed. `quiet` suppresses the failure WARN — for a caller probing which
|
|
141
|
+
* of several node-type namespaces an action lives in, where a miss is an
|
|
142
|
+
* expected answer rather than a problem to report.
|
|
143
|
+
*/
|
|
144
|
+
export async function registryGet(ctx, nodeType, quiet = false) {
|
|
145
|
+
const probe = await registryProbe(ctx, nodeType);
|
|
146
|
+
if ("name" in probe)
|
|
147
|
+
return probe.name;
|
|
148
|
+
if (!quiet)
|
|
149
|
+
ctx.reporter.warn(` WARN: registry get failed for ${nodeType}: ${probe.miss.reason}`);
|
|
150
|
+
return undefined;
|
|
138
151
|
}
|
|
139
152
|
function noteFailedFieldDescribe(ctx, connectorKey, objectName, operation, message) {
|
|
140
153
|
if (ctx.parentFields.size > 0) {
|
|
@@ -18,6 +18,7 @@ import { lowerFirst, pyStr, pyStrip, startsWithUpper } from "../compat/pystr.js"
|
|
|
18
18
|
import { mapConcurrent } from "../concurrency.js";
|
|
19
19
|
import { Refusal } from "../errors.js";
|
|
20
20
|
import { isTriggersDescribe, isTriggersObjects } from "../uip/commands.js";
|
|
21
|
+
import { failureReason } from "../uip/envelope.js";
|
|
21
22
|
import { safeCacheName } from "../uip/response-cache.js";
|
|
22
23
|
import { schemaCacheScope, writeCache } from "./context.js";
|
|
23
24
|
import { objectsComeFromTheConnection } from "./generic-expand.js";
|
|
@@ -66,8 +67,8 @@ async function runJson(client, argv, timeoutMs) {
|
|
|
66
67
|
payload = JSON.parse(result.stdout);
|
|
67
68
|
}
|
|
68
69
|
catch {
|
|
69
|
-
const text = codePointSlice(
|
|
70
|
-
throw new EventDiscoveryError(`${head} did not answer JSON: ${text
|
|
70
|
+
const text = codePointSlice(failureReason(result), 0, 300);
|
|
71
|
+
throw new EventDiscoveryError(`${head} did not answer JSON: ${text}`, result.refused === true);
|
|
71
72
|
}
|
|
72
73
|
if (get(payload, "Result") !== "Success") {
|
|
73
74
|
// `refused` is carried here too, although the refusing client in this tree
|
|
@@ -5,7 +5,8 @@ import type { UipClient } from "../uip/client.js";
|
|
|
5
5
|
* Exact prefix only: the same search returns
|
|
6
6
|
* `uipath.agent.resource.tool.connector.<key>.<action>` and
|
|
7
7
|
* `uipath.connector.trigger.<key>.<event>`, which are not actions of this node
|
|
8
|
-
* and would read as alternatives an author could pass.
|
|
8
|
+
* and would read as alternatives an author could pass as an action. The events
|
|
9
|
+
* are listed separately, by {@link registryEventIds}.
|
|
9
10
|
*/
|
|
10
11
|
export declare function registryActionIds(payload: unknown, connectorKey: string): string[];
|
|
11
12
|
/**
|
|
@@ -19,8 +20,44 @@ export declare function registryActionIds(payload: unknown, connectorKey: string
|
|
|
19
20
|
*/
|
|
20
21
|
export declare function closestActions(action: string, candidates: readonly string[]): string[];
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* {@link closestActions}, kept only where the candidate is plausibly what was
|
|
24
|
+
* meant: it shares MOST of the wanted id's words (`list-all-records` →
|
|
25
|
+
* `list-records`), or it is a near spelling (`record-creatd` → `record-created`,
|
|
26
|
+
* `send-mail` → `send-email`). One shared word is not enough: `record-created`
|
|
27
|
+
* shares "record" with every Data Fabric action, and offering
|
|
28
|
+
* `update-entity-record` as the closest match to an EVENT name points the
|
|
29
|
+
* author at the wrong namespace.
|
|
25
30
|
*/
|
|
26
|
-
export declare function
|
|
31
|
+
export declare function plausibleMatches(wanted: string, candidates: readonly string[]): string[];
|
|
32
|
+
/** The two node-type forms a connector event is served in. */
|
|
33
|
+
export type EventForm = "trigger" | "event";
|
|
34
|
+
/** One event id in a `registry search` reply, with the forms it was served in. */
|
|
35
|
+
export interface RegistryEvent {
|
|
36
|
+
id: string;
|
|
37
|
+
/** `trigger` = `uipath.connector.trigger.<key>.<id>` (starts a flow), `event` = `…event…` (waits mid-flow). */
|
|
38
|
+
forms: EventForm[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The event ids in a `registry search <key>` reply, sorted, each with its forms.
|
|
42
|
+
*
|
|
43
|
+
* The form is kept because the two can come and go separately: on 2026-09-16
|
|
44
|
+
* the Data Fabric `.event.` pair was still served after its `.trigger.` pair
|
|
45
|
+
* was gone, and `prepare` probes the `.trigger.` form.
|
|
46
|
+
*/
|
|
47
|
+
export declare function registryEventIds(payload: unknown, connectorKey: string): RegistryEvent[];
|
|
48
|
+
/** What `registry search <key>` served, or why it could not say. */
|
|
49
|
+
export interface RegistryCatalog {
|
|
50
|
+
actions: string[];
|
|
51
|
+
events: RegistryEvent[];
|
|
52
|
+
/**
|
|
53
|
+
* Set when the search itself failed or did not answer JSON. The lists are
|
|
54
|
+
* then empty because nothing was read, NOT because the catalog is empty, and
|
|
55
|
+
* a message must not say "returned nothing".
|
|
56
|
+
*/
|
|
57
|
+
failure?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* `registry search <key>`, read for both catalogs. This runs only on the
|
|
61
|
+
* failure path, to tell the author what the catalog does serve.
|
|
62
|
+
*/
|
|
63
|
+
export declare function registryCatalog(client: UipClient, connectorKey: string, timeoutMs?: number): Promise<RegistryCatalog>;
|