@uipath/maestro-builder-sdk 6.36.1 → 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.
Files changed (41) hide show
  1. package/dist/api-index.md +85 -83
  2. package/dist/api-members.md +339 -335
  3. package/dist/bpmn/bpmn-sdk.d.ts +33 -0
  4. package/dist/bpmn/bpmn-sdk.js +4 -0
  5. package/dist/bpmn/check.js +79 -0
  6. package/dist/bpmn/connector-lift-verify.d.ts +32 -0
  7. package/dist/bpmn/connector-lift-verify.js +220 -0
  8. package/dist/bpmn/connector.d.ts +12 -0
  9. package/dist/bpmn/connector.js +19 -1
  10. package/dist/bpmn/declared-vars.js +10 -3
  11. package/dist/bpmn/decompile-cli.js +68 -6
  12. package/dist/bpmn/decompile.d.ts +43 -0
  13. package/dist/bpmn/decompile.js +274 -9
  14. package/dist/bpmn/intsvc.d.ts +9 -10
  15. package/dist/bpmn/intsvc.js +31 -18
  16. package/dist/bpmn/serialize.js +31 -24
  17. package/dist/cli-library.js +3 -1
  18. package/dist/core/cli-library.d.ts +8 -2
  19. package/dist/core/cli-library.js +6 -4
  20. package/dist/core/connector-resolve-error.d.ts +7 -1
  21. package/dist/core/event-checks.js +2 -2
  22. package/dist/core/lookups.d.ts +22 -0
  23. package/dist/core/lookups.js +34 -1
  24. package/dist/core/synthesized-definition.d.ts +15 -0
  25. package/dist/core/synthesized-definition.js +22 -0
  26. package/dist/registry/library-build/context.d.ts +16 -0
  27. package/dist/registry/library-build/context.js +32 -5
  28. package/dist/registry/prepare/actions.d.ts +15 -0
  29. package/dist/registry/prepare/actions.js +12 -1
  30. package/dist/registry/prepare/integration-service.d.ts +105 -0
  31. package/dist/registry/prepare/integration-service.js +218 -0
  32. package/dist/registry/prepare/messages.d.ts +41 -1
  33. package/dist/registry/prepare/messages.js +82 -1
  34. package/dist/registry/prepare/pipeline.js +73 -15
  35. package/dist/registry/uip/commands.d.ts +8 -0
  36. package/dist/registry/uip/commands.js +12 -0
  37. package/dist/serialize.js +11 -0
  38. package/lib/library-json.samples/index.json +9 -0
  39. package/lib/library-json.samples/uipath-uipath-dataservice/update-entity-record@1.0.0.json +132 -0
  40. package/lib/library-json.samples/uipath-uipath-dataservice/update-entity-record@1.0.0.v1def.json +254 -0
  41. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { Library, type ResolvedConnector } from './library.js';
1
+ import { ConnectorResolveError, Library, type ResolvedConnector } from './library.js';
2
2
  import type { BindingsView } from './binding-messages.js';
3
3
  import { type ConnectorCheckOpts } from './connector-checks.js';
4
4
  import type { LookupResolutions, LookupSpec } from './lookups.js';
@@ -32,9 +32,15 @@ export declare function openCliLibrary(argv: readonly string[]): Library | undef
32
32
  * recorded by `registry prepare --resolve` would be reported as still owed,
33
33
  * telling the author to re-run a prepare they already ran.
34
34
  */
35
- export declare function connectorCheckOpts(library: Library | undefined, bindings?: BindingsView, inputErrors?: ConnectorInputValidator): ConnectorCheckOpts & EventCheckOpts;
35
+ export declare function connectorCheckOpts(library: Library | undefined, bindings?: BindingsView, inputErrors?: ConnectorInputValidator, refuse?: ConnectorRefusal): ConnectorCheckOpts & EventCheckOpts;
36
36
  /** A family's field-contract validator: `compile`'s refusal for these inputs, or `undefined`. */
37
37
  export type ConnectorInputValidator = (rc: ResolvedConnector, inputs: Record<string, unknown>, resolutions: LookupResolutions, lookups: Readonly<Record<string, LookupSpec>>) => string | undefined;
38
+ /**
39
+ * A family's own refusal of an operation the library DID resolve — Flow's
40
+ * `synthesizedDefinitionRefusal` — applied after `library.resolve`, so check
41
+ * and compile refuse the same entry with the same code and text.
42
+ */
43
+ export type ConnectorRefusal = (rc: ResolvedConnector) => ConnectorResolveError | undefined;
38
44
  /**
39
45
  * `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
40
46
  * for a subscription, or `undefined` when it resolves.
@@ -57,12 +57,12 @@ export function openCliLibrary(argv) {
57
57
  * recorded by `registry prepare --resolve` would be reported as still owed,
58
58
  * telling the author to re-run a prepare they already ran.
59
59
  */
60
- export function connectorCheckOpts(library, bindings, inputErrors = (rc, inputs, resolutions, lookups) => connectorInputErrors(rc, inputs, resolutions, lookups, { dialect: EQUALS_EXPR_DIALECT })) {
60
+ export function connectorCheckOpts(library, bindings, inputErrors = (rc, inputs, resolutions, lookups) => connectorInputErrors(rc, inputs, resolutions, lookups, { dialect: EQUALS_EXPR_DIALECT }), refuse) {
61
61
  if (!library)
62
62
  return bindings ? { bindings } : {};
63
63
  // One memoized resolve per connector step, shared by `connectorResolveError`
64
64
  // and `connectorInputs`, so the second hook does not resolve again.
65
- const resolve = connectorResolver(library);
65
+ const resolve = connectorResolver(library, refuse);
66
66
  return {
67
67
  eventResolveError: eventResolveErrorFor(library),
68
68
  ...byoaCheckOpts(library),
@@ -129,14 +129,16 @@ const CONNECTOR_RESOLVE_FAILED = 'CONNECTOR_RESOLVE_FAILED';
129
129
  * "unknown" used to let `check` pass a step `compile` then died on (#1015); the
130
130
  * event twin, `eventResolveErrorFor`, already reported every throw.
131
131
  */
132
- function connectorResolver(library) {
132
+ function connectorResolver(library, refuse) {
133
133
  const memo = new Map();
134
134
  return (spec) => {
135
135
  const id = JSON.stringify([spec.key, spec.action, spec.version ?? null, spec.object ?? null]);
136
136
  let r = memo.get(id);
137
137
  if (!r) {
138
138
  try {
139
- r = { rc: library.resolve(spec.key, spec.action, spec.version, spec.object) };
139
+ const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
140
+ const refused = refuse?.(rc);
141
+ r = refused ? { error: { code: refused.code, message: refused.message } } : { rc };
140
142
  }
141
143
  catch (error) {
142
144
  r = error instanceof ConnectorResolveError
@@ -15,7 +15,13 @@ export type ConnectorResolveCode =
15
15
  * The index lists the operation, but its entry file or `.v1def.json` sidecar is
16
16
  * missing or not valid JSON: the library on disk is incomplete (#1015).
17
17
  */
18
- | 'CONNECTOR_LIBRARY_ENTRY_UNREADABLE';
18
+ | 'CONNECTOR_LIBRARY_ENTRY_UNREADABLE'
19
+ /**
20
+ * Flow only: the sidecar was synthesized from Integration Service by `registry
21
+ * prepare` (no registry node exists), and a Flow node needs the registry's
22
+ * definition. BPMN compiles the same entry (`core/synthesized-definition.ts`).
23
+ */
24
+ | 'CONNECTOR_NO_FLOW_DEFINITION';
19
25
  /**
20
26
  * The refusal `Library.resolve` throws, with a `code` for each reason.
21
27
  *
@@ -18,7 +18,7 @@
18
18
  * `skill-bpmn-outlook-waitfor-email` in `flow-v2-run-8` failed on exactly that last
19
19
  * question, and in run 12 on having nowhere to put a payload condition.
20
20
  */
21
- import { isLookupToken, resolvedValue, unresolvedLookupMessage, } from './lookups.js';
21
+ import { isLookupToken, resolvedEventValue, unresolvedLookupMessage, } from './lookups.js';
22
22
  import { prepareCommand } from './cli-spelling.js';
23
23
  import { EVENT_FILTER_OPERATORS, readEventFilter, eventFilterProblem, jmesStringProblem } from './event-filters.js';
24
24
  import { EVENT_BYOA_UNVERIFIED, byoaUnverified } from './byoa.js';
@@ -129,7 +129,7 @@ export function checkEventResolution(subscription, where, kind, opts, error, war
129
129
  for (const [key, value] of scope) {
130
130
  if (!isLookupToken(value))
131
131
  continue;
132
- if (resolvedValue(value, resolutions) !== undefined)
132
+ if (resolvedEventValue(value, resolutions) !== undefined)
133
133
  continue;
134
134
  warn('LOOKUP_UNRESOLVED', `${where}: \`where.${key}\` ` + unresolvedLookupMessage(value)
135
135
  + `\nCompile will fail until this is recorded.`);
@@ -114,6 +114,11 @@ export declare function lookup<D extends LookupBearing, F extends keyof NonNulla
114
114
  * and there are no typed aliases, so only the generic `.by(name, value)` is
115
115
  * available. A consistent trade rather than a new one.
116
116
  *
117
+ * On a connector EVENT's `where` (`.waitForEvent()` / `.eventTrigger()` /
118
+ * `onEvent()`), `action` is the event id and the token is matched against the
119
+ * resolution `prepare` recorded for the event as well, so this form and
120
+ * `lookup({ connector, event }, field)` resolve alike.
121
+ *
117
122
  * @param key - The connector library key, e.g. `'uipath-salesforce-slack'`.
118
123
  * @param action - The operation id, e.g. `'send-message-to-user'`.
119
124
  * @param field - The lookup field, e.g. `'channel'`.
@@ -177,6 +182,23 @@ export type LookupResolutions = Readonly<Record<string, LookupResolution>>;
177
182
  * @returns The connector-facing id, when this exact `(nodeType, field, by, value)` was resolved.
178
183
  */
179
184
  export declare function resolvedValue(token: LookupToken, resolutions: LookupResolutions): string | undefined;
185
+ /**
186
+ * {@link resolvedValue} for a token on an event's `where`.
187
+ *
188
+ * `prepare` records an event's resolutions under the EVENT form of the node type,
189
+ * which the descriptor form `lookup({ connector, event }, field)` keys a token
190
+ * under too. The string form `lookup(key, action, field)` cannot know it is being
191
+ * used on an event and keys the token under the activity form, so a recorded
192
+ * resolution was never found for it: on the 2026-10-16 run an author whose
193
+ * `prepare --resolve parentFolderId:displayName=Inbox` had succeeded still saw
194
+ * `LOOKUP_UNRESOLVED` from `check` and a refusal from `compile`, and pasted the
195
+ * id in by hand. The token's own key is tried first; the event form second.
196
+ *
197
+ * @param token - The unresolved lookup, from either `lookup()` form.
198
+ * @param resolutions - Everything `prepare --resolve` has recorded.
199
+ * @returns The connector-facing id, when either key was resolved.
200
+ */
201
+ export declare function resolvedEventValue(token: LookupToken, resolutions: LookupResolutions): string | undefined;
180
202
  /**
181
203
  * The message for a lookup nothing has resolved — the command that fixes it.
182
204
  *
@@ -166,6 +166,39 @@ export function resolvedValue(token, resolutions) {
166
166
  const { nodeType, field, by, value } = token.__lookup;
167
167
  return resolutions[lookupKey(nodeType, field, by, value)]?.value;
168
168
  }
169
+ /**
170
+ * The event form of a node type — `uipath.connector.event.<key>.<op>` — for one
171
+ * written without a role segment, else `undefined`. A role-less type is what the
172
+ * string form `lookup(key, action, field)` keys a token under.
173
+ */
174
+ function eventFormOf(nodeType) {
175
+ const m = /^uipath\.connector\.(?!event\.|trigger\.)(.+)$/.exec(nodeType);
176
+ return m ? `uipath.connector.event.${m[1]}` : undefined;
177
+ }
178
+ /**
179
+ * {@link resolvedValue} for a token on an event's `where`.
180
+ *
181
+ * `prepare` records an event's resolutions under the EVENT form of the node type,
182
+ * which the descriptor form `lookup({ connector, event }, field)` keys a token
183
+ * under too. The string form `lookup(key, action, field)` cannot know it is being
184
+ * used on an event and keys the token under the activity form, so a recorded
185
+ * resolution was never found for it: on the 2026-10-16 run an author whose
186
+ * `prepare --resolve parentFolderId:displayName=Inbox` had succeeded still saw
187
+ * `LOOKUP_UNRESOLVED` from `check` and a refusal from `compile`, and pasted the
188
+ * id in by hand. The token's own key is tried first; the event form second.
189
+ *
190
+ * @param token - The unresolved lookup, from either `lookup()` form.
191
+ * @param resolutions - Everything `prepare --resolve` has recorded.
192
+ * @returns The connector-facing id, when either key was resolved.
193
+ */
194
+ export function resolvedEventValue(token, resolutions) {
195
+ const own = resolvedValue(token, resolutions);
196
+ if (own !== undefined)
197
+ return own;
198
+ const { nodeType, field, by, value } = token.__lookup;
199
+ const eventForm = eventFormOf(nodeType);
200
+ return eventForm === undefined ? undefined : resolutions[lookupKey(eventForm, field, by, value)]?.value;
201
+ }
169
202
  /**
170
203
  * The message for a lookup nothing has resolved — the command that fixes it.
171
204
  *
@@ -282,7 +315,7 @@ export function resolveEventWhere(where, resolutions, site) {
282
315
  out[key] = value;
283
316
  continue;
284
317
  }
285
- const resolved = resolvedValue(value, resolutions);
318
+ const resolved = resolvedEventValue(value, resolutions);
286
319
  if (resolved === undefined)
287
320
  throw new Error(`${site}: \`where.${key}\` ` + unresolvedLookupMessage(value));
288
321
  out[key] = resolved;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The one refusal Flow adds on top of `Library.resolve`: an operation whose
3
+ * sidecar `registry prepare` synthesized from Integration Service
4
+ * (`prepare/integration-service.ts`) has no registry node behind it. A BPMN
5
+ * `sendTask` carries its own identity and rows, so BPMN compiles it; a Flow
6
+ * node embeds the registry's whole definition — form, handles, model — which
7
+ * no describe supplies, so Flow refuses it here, in `check` and `compile`
8
+ * alike, instead of emitting a node the designer cannot open.
9
+ */
10
+ import { ConnectorResolveError } from './connector-resolve-error.js';
11
+ import type { ResolvedConnector } from './library.js';
12
+ /** The marker `prepare` writes on a sidecar it built from Integration Service. */
13
+ export declare const SYNTHESIZED_FROM_INTEGRATION_SERVICE = "integration-service";
14
+ /** Flow's refusal for a resolved operation with no registry definition, or `undefined` when it has one. */
15
+ export declare function synthesizedDefinitionRefusal(rc: Pick<ResolvedConnector, 'v1def' | 'connectorKey' | 'nodeType'>): ConnectorResolveError | undefined;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The one refusal Flow adds on top of `Library.resolve`: an operation whose
3
+ * sidecar `registry prepare` synthesized from Integration Service
4
+ * (`prepare/integration-service.ts`) has no registry node behind it. A BPMN
5
+ * `sendTask` carries its own identity and rows, so BPMN compiles it; a Flow
6
+ * node embeds the registry's whole definition — form, handles, model — which
7
+ * no describe supplies, so Flow refuses it here, in `check` and `compile`
8
+ * alike, instead of emitting a node the designer cannot open.
9
+ */
10
+ import { ConnectorResolveError } from './connector-resolve-error.js';
11
+ /** The marker `prepare` writes on a sidecar it built from Integration Service. */
12
+ export const SYNTHESIZED_FROM_INTEGRATION_SERVICE = 'integration-service';
13
+ /** Flow's refusal for a resolved operation with no registry definition, or `undefined` when it has one. */
14
+ export function synthesizedDefinitionRefusal(rc) {
15
+ const origin = rc.v1def?.synthesizedFrom;
16
+ if (origin !== SYNTHESIZED_FROM_INTEGRATION_SERVICE)
17
+ return undefined;
18
+ const action = String(rc.nodeType).replace(/^uipath\.connector\.[^.]+\./, '');
19
+ return new ConnectorResolveError('CONNECTOR_NO_FLOW_DEFINITION', `connector ${rc.connectorKey} ${action} was prepared from Integration Service because the Flow node catalog serves no node for ${rc.connectorKey}; `
20
+ + 'a Flow step or inline agent tool needs that node (its form, handles and model), so this operation compiles in BPMN only. '
21
+ + `Author it as a BPMN .connector(), or check \`uip maestro flow registry search ${rc.connectorKey}\` after \`registry pull --force\` in case the catalog has since gained it.`);
22
+ }
@@ -130,4 +130,20 @@ export declare function isResourcesList(ctx: BuildContext, connectorKey: string,
130
130
  * files are deliberately not reused: that output omitted the discovery
131
131
  * capabilities and would silently mark every connector static.
132
132
  */
133
+ /** `uip is activities list`'s answer: its rows, or why it could not be read. */
134
+ export type IsActivitiesCatalog = {
135
+ rows: unknown[];
136
+ } | {
137
+ failure: string;
138
+ };
139
+ /**
140
+ * Cached `uip is activities list <key>`: the connector's activity catalog
141
+ * (every row, curated or not — the caller filters on `IsCurated`), or the
142
+ * failure in the CLI's own words ({@link failureReason}): a refusal, output
143
+ * that is not JSON, or a `Result: Failure` envelope (an expired token, a 5xx,
144
+ * a connector the tenant has not enabled). Cached beside the `is resources`
145
+ * payloads — it is the same catalog service, read without a connection — and
146
+ * a cached failure keeps its reason.
147
+ */
148
+ export declare function isActivitiesCatalog(ctx: BuildContext, connectorKey: string): Promise<IsActivitiesCatalog>;
133
149
  export declare function isConnectorGet(ctx: BuildContext, connectorKey: string): Promise<unknown>;
@@ -16,7 +16,7 @@
16
16
  import { createHash } from "node:crypto";
17
17
  import { pyJsonStringify } from "../codecs/pyjson.js";
18
18
  import { sortedByKeys } from "../compat/compare.js";
19
- import { isConnectorsMetadata, isResourcesDescribeObject, isResourcesDescribeOperation, isResourcesList as isResourcesListArgv, registryGet as registryGetArgv, } from "../uip/commands.js";
19
+ import { isActivitiesList as isActivitiesListArgv, 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
21
  import { failureReason, isNodeNotFound } from "../uip/envelope.js";
22
22
  import { get, isPyDict, pyOr, pyTruthy } from "./py.js";
@@ -251,11 +251,38 @@ export async function isResourcesList(ctx, connectorKey, options = {}) {
251
251
  return Array.isArray(payload.Data) ? payload.Data : undefined;
252
252
  }
253
253
  /**
254
- * `is_connector_get`: cached `uip is connectors metadata <key>`, answering the
255
- * first element of `Data` or `undefined`. The legacy `connectors get` cache
256
- * files are deliberately not reused: that output omitted the discovery
257
- * capabilities and would silently mark every connector static.
254
+ * Cached `uip is activities list <key>`: the connector's activity catalog
255
+ * (every row, curated or not — the caller filters on `IsCurated`), or the
256
+ * failure in the CLI's own words ({@link failureReason}): a refusal, output
257
+ * that is not JSON, or a `Result: Failure` envelope (an expired token, a 5xx,
258
+ * a connector the tenant has not enabled). Cached beside the `is resources`
259
+ * payloads — it is the same catalog service, read without a connection — and
260
+ * a cached failure keeps its reason.
258
261
  */
262
+ export async function isActivitiesCatalog(ctx, connectorKey) {
263
+ const name = `${safeCacheName(connectorKey, "_activities_list")}.json`;
264
+ if (ctx.caches.is.has(name)) {
265
+ const cached = ctx.caches.is.read(name);
266
+ const data = get(cached, "Data");
267
+ if (Array.isArray(data))
268
+ return { rows: data };
269
+ return { failure: String(pyOr(get(cached, "Message"), "the cached answer carries no rows")) };
270
+ }
271
+ const result = await runUip(ctx, isActivitiesListArgv(connectorKey));
272
+ if (refused(result))
273
+ return { failure: failureReason(result) };
274
+ const parsed = parseStdout(result.stdout);
275
+ if (parsed === undefined)
276
+ return { failure: failureReason(result) };
277
+ const payload = envelope(parsed);
278
+ if (get(payload, "Result") !== "Success") {
279
+ const failure = failureReason(result);
280
+ writeCache(ctx.caches.is, name, { Result: "Failure", Message: failure, [CACHED_FAILURE]: true });
281
+ return { failure };
282
+ }
283
+ writeCache(ctx.caches.is, name, payload);
284
+ return Array.isArray(payload.Data) ? { rows: payload.Data } : { failure: "the answer carries no Data rows" };
285
+ }
259
286
  export async function isConnectorGet(ctx, connectorKey) {
260
287
  const name = `${safeCacheName(connectorKey, "_connector_metadata")}.json`;
261
288
  const firstRow = (payload) => {
@@ -56,6 +56,21 @@ export interface RegistryCatalog {
56
56
  */
57
57
  failure?: string;
58
58
  }
59
+ /** Whether `registry pull --force` refreshed the local catalog copy, or why not. */
60
+ export type RegistryRefresh = {
61
+ ok: true;
62
+ } | {
63
+ ok: false;
64
+ reason: string;
65
+ };
66
+ /**
67
+ * `uip maestro flow registry pull --force`: refresh the local catalog copy the
68
+ * probes and the search answer from. It never refreshes itself, so before
69
+ * `prepare` concludes that the catalog serves nothing for a connector it pulls
70
+ * once and looks again; a stale copy would otherwise send a connector the
71
+ * catalog does serve down the BPMN-only path, and state it as fact.
72
+ */
73
+ export declare function refreshRegistryCatalog(client: UipClient, timeoutMs?: number): Promise<RegistryRefresh>;
59
74
  /**
60
75
  * `registry search <key>`, read for both catalogs. This runs only on the
61
76
  * failure path, to tell the author what the catalog does serve.
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { compareCodePoints, sortedStrings } from "../compat/compare.js";
20
20
  import { editDistance } from "../../core/edit-distance.js";
21
- import { registrySearch } from "../uip/commands.js";
21
+ import { registryPull, registrySearch } from "../uip/commands.js";
22
22
  import { failureReason, findJsonDocument, tail } from "../uip/envelope.js";
23
23
  import { isPlainObject, pyOr } from "./support.js";
24
24
  /**
@@ -141,6 +141,17 @@ export function registryEventIds(payload, connectorKey) {
141
141
  forms: ["trigger", "event"].filter((form) => forms.get(id).has(form)),
142
142
  }));
143
143
  }
144
+ /**
145
+ * `uip maestro flow registry pull --force`: refresh the local catalog copy the
146
+ * probes and the search answer from. It never refreshes itself, so before
147
+ * `prepare` concludes that the catalog serves nothing for a connector it pulls
148
+ * once and looks again; a stale copy would otherwise send a connector the
149
+ * catalog does serve down the BPMN-only path, and state it as fact.
150
+ */
151
+ export async function refreshRegistryCatalog(client, timeoutMs) {
152
+ const result = await client.run(registryPull(), timeoutMs === undefined ? undefined : { timeoutMs });
153
+ return result.code === 0 ? { ok: true } : { ok: false, reason: failureReason(result) };
154
+ }
144
155
  /**
145
156
  * `registry search <key>`, read for both catalogs. This runs only on the
146
157
  * failure path, to tell the author what the catalog does serve.
@@ -0,0 +1,105 @@
1
+ import { SYNTHESIZED_FROM_INTEGRATION_SERVICE } from "../../core/synthesized-definition.js";
2
+ import { type BuildContext } from "../library-build/context.js";
3
+ import type { LibraryEntry } from "../model/library.js";
4
+ /** The marker a synthesized sidecar carries; Flow refuses a definition that has it. One owner, `core/`, so the writer and the refuser cannot drift. */
5
+ export { SYNTHESIZED_FROM_INTEGRATION_SERVICE };
6
+ /** One row of `uip is activities list`, the fields this module reads. */
7
+ export interface IsActivity {
8
+ /** The activity's own name, PascalCase: `CreateTestSet`. */
9
+ name: string;
10
+ displayName: string;
11
+ description: string;
12
+ /** The IS object the activity addresses: `TestSet`. */
13
+ objectName: string;
14
+ /** The HTTP verb as the catalog spells it: `POST`, `GETBYID`, `PATCH`, … */
15
+ method: string;
16
+ }
17
+ /** Why the Integration Service path could not prepare the action. */
18
+ export type IntegrationServiceMiss =
19
+ /** The catalog could not be listed (`reason`: the CLI's own words), or lists no curated activity (no `reason`). */
20
+ {
21
+ kind: "no-catalog";
22
+ reason?: string;
23
+ }
24
+ /** The catalog lists curated activities, none of which is the action; their ids, for the refusal. */
25
+ | {
26
+ kind: "no-such-activity";
27
+ activities: string[];
28
+ }
29
+ /** The activity's HTTP method maps to no `is resources` verb, so there is no describe to read. */
30
+ | {
31
+ kind: "no-operation";
32
+ activity: IsActivity;
33
+ }
34
+ /** The activity exists but `is resources describe` returned no schema for it. */
35
+ | {
36
+ kind: "no-schema";
37
+ activity: IsActivity;
38
+ operation: string;
39
+ };
40
+ export interface IntegrationServicePrepared {
41
+ entry: LibraryEntry;
42
+ /**
43
+ * The action id the entry goes by: the activity's own name in kebab case,
44
+ * whatever spelling the author gave (`--action "Create Test Set"` prepares
45
+ * `create-test-set`). The overlay path and the handoff use it.
46
+ */
47
+ action: string;
48
+ /** The registry-shaped node `planLibrary` builds the sidecar from. */
49
+ node: Record<string, unknown>;
50
+ activity: IsActivity;
51
+ /** The `is resources` verb the describe was read under (`Create`, `Retrieve`, …). */
52
+ operation: string;
53
+ }
54
+ /**
55
+ * The action id an activity goes by: its PascalCase name in kebab case —
56
+ * `CreateTestSet` → `create-test-set`, `AssignTestCasesToReq` →
57
+ * `assign-test-cases-to-req`, `CreateV2Attachment` → `create-v2-attachment`.
58
+ * A run of capitals stays one word (`GetPDFReport` → `get-pdf-report`).
59
+ */
60
+ export declare function activityActionId(name: string): string;
61
+ /** The curated rows of an activities listing, in the catalog's order. */
62
+ export declare function curatedActivities(rows: readonly unknown[]): IsActivity[];
63
+ /**
64
+ * The curated activity an author's action names: by action id first
65
+ * (`create-test-set`), then by the activity's own name or display name,
66
+ * case-insensitively — `CreateTestSet`, `"Create Test Set"` and `create test set`
67
+ * all reach it. The spellings are compared both as given and in kebab case, so a
68
+ * display name with spaces matches whether or not the author kebab-cased it.
69
+ */
70
+ export declare function matchActivity(activities: readonly IsActivity[], action: string): IsActivity | undefined;
71
+ /** The `is resources` verb an activity's HTTP method reads under; `undefined` for a verb the catalog has no describe for. */
72
+ export declare function describeOperationFor(method: string): string | undefined;
73
+ /**
74
+ * Prepare one action from Integration Service: the entry and the node the
75
+ * sidecar is built from, or why not.
76
+ */
77
+ export declare function integrationServiceEntry(ctx: BuildContext, input: {
78
+ connectorKey: string;
79
+ action: string;
80
+ }): Promise<IntegrationServicePrepared | {
81
+ miss: IntegrationServiceMiss;
82
+ }>;
83
+ /**
84
+ * The library entry for one described activity — the shape `extractCanonical`
85
+ * writes from a registry node, filled from the describe instead: the IS
86
+ * object and verb, the path and its parameters, the request fields as the
87
+ * input schema. `httpMethod` keeps the catalog's spelling (`GETBYID` for a
88
+ * get-by-id, as registry entries do); the wire maps it. The entry goes by the
89
+ * activity's own action id, never the author's spelling: a display name would
90
+ * put spaces (or a `/`) in the overlay path and a second entry next to the id.
91
+ */
92
+ export declare function synthesizeEntry(input: {
93
+ connectorKey: string;
94
+ activity: IsActivity;
95
+ operation: string;
96
+ described: Record<string, unknown>;
97
+ connector: unknown;
98
+ }): LibraryEntry;
99
+ /**
100
+ * The node `planLibrary` turns into the `.v1def.json` sidecar — the little a
101
+ * BPMN compile reads of one (`inputDefinition.fields` for the body, the model's
102
+ * type and service type) and the marker Flow refuses on. `buildV1Definition`
103
+ * keeps every key here.
104
+ */
105
+ export declare function synthesizeNode(entry: LibraryEntry, described: Record<string, unknown>): Record<string, unknown>;