@uipath/maestro-builder-sdk 6.6.1 → 6.8.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.
@@ -1401,7 +1401,7 @@ export interface InlineAgentInputs {
1401
1401
  * argument after the reference PATH, `__`-joined. For a flow input the two
1402
1402
  * coincide (`$vars.notes` → `notes`); for a step output they do not, and a sidecar
1403
1403
  * still saying `{{input.claim}}` templates against a key that is not there — the
1404
- * literal text reaches the model. See `skill/references/inline-agent.md`
1404
+ * literal text reaches the model. See the inline-agent node reference (`website/reference/inline-agent.md`)
1405
1405
  * §"The three prompt DIALECTS".
1406
1406
  *
1407
1407
  * If the agent has to answer in a shape the flow then reads, say so here. The
@@ -2016,46 +2016,215 @@ export interface QueueItemInputs {
2016
2016
  */
2017
2017
  returns?: Record<string, ReturnFieldType>;
2018
2018
  }
2019
- /** One filter row on a Data Fabric read — rows AND together unless `or` is set. */
2019
+ /**
2020
+ * The comparison operators the Data Fabric query serializer can emit, spelled
2021
+ * exactly as the file carries them.
2022
+ *
2023
+ * @remarks
2024
+ * There is deliberately no `not in`, `not contains`, or null check — the
2025
+ * serializer cannot emit them, and a filter it cannot emit takes the WHOLE
2026
+ * query down rather than dropping one row. `is any of` is the legacy spelling
2027
+ * of `in` and is still read, but author `in`.
2028
+ */
2029
+ export type DataFabricOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'contains' | 'starts with' | 'ends with' | 'in';
2030
+ /** One filter row on a Data Fabric query — rows AND together unless `or` is set. */
2020
2031
  export interface DataFabricFilter {
2021
- /** The entity column to filter on. */
2032
+ /**
2033
+ * The entity column to filter on. A dotted related path (`customer.Name`) is
2034
+ * capped at 3 segments and needs the canvas's `_entityFields` snapshot, which
2035
+ * the SDK does not author — keep from-scratch filters on the entity's own
2036
+ * columns.
2037
+ */
2022
2038
  field: string;
2023
- /** Comparison operator the designer offers — `=` (the default), `!=`, `>`, `>=`, `<`, `<=`, `contains`, … */
2024
- operator?: string;
2025
- /** The comparison value. An `Expr` re-evaluates at activation time. */
2039
+ /** Comparison operator; `=` when omitted. */
2040
+ operator?: DataFabricOperator;
2041
+ /**
2042
+ * The comparison value. An `Expr` re-evaluates at activation time.
2043
+ *
2044
+ * A choice-set column compares against the choice's numeric `numberId`, never
2045
+ * its label — a label matches nothing.
2046
+ */
2026
2047
  value: string | Expr;
2027
- /** Join this row to the PREVIOUS one with OR instead of AND. */
2048
+ /**
2049
+ * Start a new OR alternative at this row.
2050
+ *
2051
+ * @remarks
2052
+ * The query model is disjunctive — `alt1 OR alt2 OR …`, each alternative an
2053
+ * AND of its own rows — so `or` SPLITS the list rather than joining one row
2054
+ * to the one before it. `[A, B(or), C]` is therefore `A OR (B AND C)`, not
2055
+ * `(A OR B) AND C`; to get the latter, write it out as
2056
+ * `(A AND C) OR (B AND C)`.
2057
+ *
2058
+ * Ignored on the first row, which has no earlier alternative to split from.
2059
+ */
2028
2060
  or?: boolean;
2029
2061
  }
2062
+ /** How a multi-record query orders its rows before the limit is applied. */
2063
+ export interface DataFabricSort {
2064
+ /** The column to order by — a real one; a sort on a missing column is not caught by `validate`. */
2065
+ field: string;
2066
+ /** `'asc'` when omitted. */
2067
+ direction?: 'asc' | 'desc';
2068
+ }
2069
+ /**
2070
+ * Which record a Data Fabric write targets — exactly ONE of the two forms.
2071
+ *
2072
+ * @remarks
2073
+ * `{ byId }` names a record id, literal or expression. `{ fromRead }` names an
2074
+ * earlier {@link dataFabricRead} STEP and reuses the record that step found, so
2075
+ * the id never has to be carried by hand; `check` rejects a name no read step
2076
+ * has. Shared by {@link dataFabricUpdate} and {@link dataFabricDelete} — the
2077
+ * platform gives them the same `recordSource` shape.
2078
+ */
2079
+ export type DataFabricRecordRef = {
2080
+ byId: string | Expr;
2081
+ fromRead?: never;
2082
+ } | {
2083
+ fromRead: string;
2084
+ byId?: never;
2085
+ };
2030
2086
  export interface DataFabricReadInputs {
2031
2087
  /** The Data Fabric entity's name, e.g. `'Invoices'`. */
2032
2088
  entity: string;
2033
- /** Filter rows selecting the record to read. Omit to read the first record. */
2089
+ /** Filter rows selecting the record(s) to query. Omit to take everything the entity holds. */
2034
2090
  filters?: DataFabricFilter[];
2035
- /** Folder key (GUID) for folder-scoped entities. */
2091
+ /**
2092
+ * `'single'` publishes ONE record as the step's `output`; `'multiple'`
2093
+ * publishes the matching records under `output.results`.
2094
+ *
2095
+ * Setting either selects the node's **1.4** definition, which is where
2096
+ * `resultMode` exists at all — the SDK's pinned default is 1.0, the
2097
+ * read-one-record node this family started as. Omit it and nothing changes:
2098
+ * the step stays on 1.0 and reads one record, as it always did.
2099
+ *
2100
+ * A `'single'` read faults only on an OVER-match; zero matches completes
2101
+ * normally and leaves the step's output unresolved, so treat "not found" as a
2102
+ * branch rather than an error.
2103
+ */
2104
+ resultMode?: 'single' | 'multiple';
2105
+ /**
2106
+ * Row cap for a `'multiple'` query. The emitted query ALWAYS carries a limit:
2107
+ * omitting this resolves to 100, and 1000 is a hard ceiling — a larger value
2108
+ * truncates silently, so page with `skip` instead.
2109
+ */
2110
+ limit?: number;
2111
+ /** Rows to skip before the limit — the paging half of `limit`. */
2112
+ skip?: number;
2113
+ /** Order rows before the limit applies. Without it a limited slice is arbitrary. */
2114
+ sort?: DataFabricSort;
2115
+ /** Only these columns. Omit for every column the entity has. */
2116
+ fields?: string[];
2117
+ /**
2118
+ * Folder key (GUID) for a folder-scoped entity — its `folderId` from
2119
+ * `uip df entities list --include-folders`.
2120
+ *
2121
+ * Requires `resourceKey`: `folderKey` alone serializes the folder as a
2122
+ * source-org LITERAL, which looks portable and breaks on cross-org deploy, so
2123
+ * `check` refuses the pair being half-authored.
2124
+ */
2036
2125
  folderKey?: string;
2126
+ /**
2127
+ * The key the entity's reference is registered under in the solution, from
2128
+ * `uip solution resources list --kind Entity`.
2129
+ *
2130
+ * @remarks
2131
+ * Only meaningful with `folderKey`. Supplying both emits the two
2132
+ * `resource: 'Entity'` binding rows (`propertyAttribute` `name` and
2133
+ * `folderKey`) that let the flow deploy to another org. Nothing mints this
2134
+ * key for a hand-authored flow — if you cannot resolve one, keep the entity
2135
+ * tenant-scoped and omit both.
2136
+ */
2137
+ resourceKey?: string;
2037
2138
  }
2038
- export interface DataFabricUpdateInputs {
2139
+ export interface DataFabricCreateInputs {
2039
2140
  /** The Data Fabric entity's name, e.g. `'Invoices'`. */
2040
2141
  entity: string;
2041
2142
  /**
2042
- * Which record to update: `{ byId: <record id> }`, or `{ fromRead: '<step>' }`
2043
- * naming an earlier `dataFabricRead` step whose record this write targets.
2143
+ * The columns the new record starts with, by field name. At least one is
2144
+ * required — the node's schema rejects an empty field list rather than
2145
+ * inserting a blank row.
2044
2146
  */
2045
- record: {
2046
- byId: string | Expr;
2047
- fromRead?: never;
2048
- } | {
2049
- fromRead: string;
2050
- byId?: never;
2051
- };
2147
+ values: Record<string, string | Expr>;
2148
+ /**
2149
+ * Folder key (GUID) for a folder-scoped entity — its `folderId` from
2150
+ * `uip df entities list --include-folders`.
2151
+ *
2152
+ * Requires `resourceKey`: `folderKey` alone serializes the folder as a
2153
+ * source-org LITERAL, which looks portable and breaks on cross-org deploy, so
2154
+ * `check` refuses the pair being half-authored.
2155
+ */
2156
+ folderKey?: string;
2157
+ /**
2158
+ * The key the entity's reference is registered under in the solution, from
2159
+ * `uip solution resources list --kind Entity`.
2160
+ *
2161
+ * @remarks
2162
+ * Only meaningful with `folderKey`. Supplying both emits the two
2163
+ * `resource: 'Entity'` binding rows (`propertyAttribute` `name` and
2164
+ * `folderKey`) that let the flow deploy to another org. Nothing mints this
2165
+ * key for a hand-authored flow — if you cannot resolve one, keep the entity
2166
+ * tenant-scoped and omit both.
2167
+ */
2168
+ resourceKey?: string;
2169
+ }
2170
+ export interface DataFabricUpdateInputs {
2171
+ /** The Data Fabric entity's name, e.g. `'Invoices'`. */
2172
+ entity: string;
2173
+ /** Which record to update — see {@link DataFabricRecordRef}. */
2174
+ record: DataFabricRecordRef;
2052
2175
  /**
2053
2176
  * The columns to write, by field name. An empty string is a real write — it
2054
2177
  * clears the column.
2055
2178
  */
2056
2179
  set: Record<string, string | Expr>;
2057
- /** Folder key (GUID) for folder-scoped entities. */
2180
+ /**
2181
+ * Folder key (GUID) for a folder-scoped entity — its `folderId` from
2182
+ * `uip df entities list --include-folders`.
2183
+ *
2184
+ * Requires `resourceKey`: `folderKey` alone serializes the folder as a
2185
+ * source-org LITERAL, which looks portable and breaks on cross-org deploy, so
2186
+ * `check` refuses the pair being half-authored.
2187
+ */
2188
+ folderKey?: string;
2189
+ /**
2190
+ * The key the entity's reference is registered under in the solution, from
2191
+ * `uip solution resources list --kind Entity`.
2192
+ *
2193
+ * @remarks
2194
+ * Only meaningful with `folderKey`. Supplying both emits the two
2195
+ * `resource: 'Entity'` binding rows (`propertyAttribute` `name` and
2196
+ * `folderKey`) that let the flow deploy to another org. Nothing mints this
2197
+ * key for a hand-authored flow — if you cannot resolve one, keep the entity
2198
+ * tenant-scoped and omit both.
2199
+ */
2200
+ resourceKey?: string;
2201
+ }
2202
+ export interface DataFabricDeleteInputs {
2203
+ /** The Data Fabric entity's name, e.g. `'Invoices'`. */
2204
+ entity: string;
2205
+ /** Which record to delete — see {@link DataFabricRecordRef}. */
2206
+ record: DataFabricRecordRef;
2207
+ /**
2208
+ * Folder key (GUID) for a folder-scoped entity — its `folderId` from
2209
+ * `uip df entities list --include-folders`.
2210
+ *
2211
+ * Requires `resourceKey`: `folderKey` alone serializes the folder as a
2212
+ * source-org LITERAL, which looks portable and breaks on cross-org deploy, so
2213
+ * `check` refuses the pair being half-authored.
2214
+ */
2058
2215
  folderKey?: string;
2216
+ /**
2217
+ * The key the entity's reference is registered under in the solution, from
2218
+ * `uip solution resources list --kind Entity`.
2219
+ *
2220
+ * @remarks
2221
+ * Only meaningful with `folderKey`. Supplying both emits the two
2222
+ * `resource: 'Entity'` binding rows (`propertyAttribute` `name` and
2223
+ * `folderKey`) that let the flow deploy to another org. Nothing mints this
2224
+ * key for a hand-authored flow — if you cannot resolve one, keep the entity
2225
+ * tenant-scoped and omit both.
2226
+ */
2227
+ resourceKey?: string;
2059
2228
  }
2060
2229
  export interface DocumentClassifyInputs {
2061
2230
  /** The document to classify — a file reference (`input('file')`, `out('fetch', 'fileRef')`, …). */
@@ -2191,9 +2360,15 @@ export type ActionSpec = {
2191
2360
  } | {
2192
2361
  kind: 'dataFabricRead';
2193
2362
  inputs: DataFabricReadInputs;
2363
+ } | {
2364
+ kind: 'dataFabricCreate';
2365
+ inputs: DataFabricCreateInputs;
2194
2366
  } | {
2195
2367
  kind: 'dataFabricUpdate';
2196
2368
  inputs: DataFabricUpdateInputs;
2369
+ } | {
2370
+ kind: 'dataFabricDelete';
2371
+ inputs: DataFabricDeleteInputs;
2197
2372
  } | {
2198
2373
  kind: 'waitEvent';
2199
2374
  subscription: EventSubscription;
@@ -2436,7 +2611,7 @@ export declare function batchTransform(inputs: BatchTransformInputs): ActionSpec
2436
2611
  * with zero envelopes among them. The RUNTIME
2437
2612
  * accepts both, so only `uip maestro flow validate` sees a wrong one; the
2438
2613
  * emitter's exemption lives in `migrate.ts` (`UNWRAPPED_INPUTS`).
2439
- * See `skill/references/ixp.md` §3.
2614
+ * See the IxP node reference (`website/reference/ixp.md`) §3.
2440
2615
  *
2441
2616
  * @example
2442
2617
  * **Extract an invoice total and read it out of the nested result**
@@ -2929,63 +3104,97 @@ export declare function documentClassify(inputs: DocumentClassifyInputs): Action
2929
3104
  */
2930
3105
  export declare function dynamicExtract(inputs: DynamicExtractInputs): ActionSpec;
2931
3106
  /**
2932
- * Read ONE entity record from Data Fabric (`core.datafabric.read`). The record
3107
+ * Query entity records from Data Fabric (`core.datafabric.read`). The result
2933
3108
  * publishes to the step's `output`; downstream references re-fetch fresh data
2934
3109
  * at activation time (the engine re-runs the query rather than caching).
2935
3110
  *
2936
3111
  * @remarks
2937
- * **Prefer the connector for Data Fabric work during the transition.**
2938
- * `core.datafabric.*` has exactly two verbs — this one and
2939
- * {@link dataFabricUpdate} — and neither declares an output schema. Create,
2940
- * delete, get-by-id, a multi-record query with a row limit, file record fields
2941
- * and entity events are NOT in this family: they are operations on the SAME
2942
- * product reached through its Integration Service connector,
3112
+ * This node is **read-one AND query-many**, on its 1.4 definition: `resultMode:
3113
+ * 'multiple'` publishes the matching records under `output.results`, and the
3114
+ * platform renames the node "Query entity records" to say so. The SDK still
3115
+ * pins 1.0 — read-one — as the no-`{ version }` default, so passing
3116
+ * `resultMode` is what selects 1.4; see {@link DataFabricReadInputs.resultMode}.
3117
+ *
3118
+ * The native family covers all four CRUD verbs: this one,
3119
+ * {@link dataFabricCreate}, {@link dataFabricUpdate} and
3120
+ * {@link dataFabricDelete}. What it does NOT cover is get-by-id, a query row
3121
+ * limit, file record fields, and entity events — those are operations on the
3122
+ * SAME product reached through its Integration Service connector,
2943
3123
  * `uipath-uipath-dataservice` (the tenant displays it as **UiPath Data
2944
- * Fabric**), which covers every verb including the two here.
2945
- *
2946
- * Taking this node for the one verb that has a native form leaves the rest of
2947
- * the same entity on the connector — two connection bindings and two payload
2948
- * shapes in one flow. So route entity work through the connector unless the
2949
- * scenario names these nodes; native forms for the remaining verbs are the
2950
- * direction of travel, and this guidance changes when they land. `check` does
2951
- * not reject a native node — this is a routing default, not a rule:
3124
+ * Fabric**). So a flow that needs one of those still straddles two surfaces,
3125
+ * and the connector remains the one surface that covers everything:
2952
3126
  *
2953
3127
  * ```ts
2954
- * .step('create', connector('uipath-uipath-dataservice', 'create-entity-record',
2955
- * { entityName: 'Contracts', contractTitle: 'Q3 renewal' }, { connection: 'df' }))
3128
+ * .step('byId', connector('uipath-uipath-dataservice', 'get-entity-record-by-id',
3129
+ * { entityName: 'Contracts', recordId: input('id') }, { connection: 'df' }))
2956
3130
  * ```
2957
3131
  *
2958
- * That operation's body fields come from the entity, so the library cannot
2959
- * carry them: run `npx flow-sdk registry prepare uipath-uipath-dataservice
2960
- * create-entity-record -f entityName=<Entity>` first (`uip maestro registry
2961
- * prepare …` is the same command when you are driving through the UiPath CLI). The routing table is in
2962
- * the `data-fabric.md` reference and the parent-field loop in
2963
- * `connector-params.md` — cited by name rather than linked, because this
3132
+ * A connector operation's body fields come from the entity, so the library
3133
+ * cannot carry them: run `uip maestro registry prepare uipath-uipath-dataservice
3134
+ * get-entity-record-by-id -f entityName=<Entity>` first (`npx flow-sdk registry
3135
+ * prepare …` is the same command when invoking the package's own bin directly).
3136
+ * The routing table is in the `data-fabric.md` reference and the parent-field
3137
+ * loop in `connector-params.md` — cited by name rather than linked, because this
2964
3138
  * comment renders both into the flat corpus, where those files sit alongside
2965
3139
  * it, and onto the site, where each symbol is its own page and a relative
2966
3140
  * `./data-fabric` resolves to nothing.
2967
3141
  *
2968
- * @param inputs - The entity, optional filter rows, and folder scope.
3142
+ * @param inputs - The entity, optional filter rows, result mode, and folder scope.
2969
3143
  * @returns An action spec to pass to `.step(name, …)`.
2970
3144
  */
2971
3145
  export declare function dataFabricRead(inputs: DataFabricReadInputs): ActionSpec;
3146
+ /**
3147
+ * Create an entity record in Data Fabric (`core.datafabric.create`). The new
3148
+ * record publishes to the step's `output`, so a following
3149
+ * {@link dataFabricUpdate} or {@link dataFabricDelete} can read its id.
3150
+ *
3151
+ * @remarks
3152
+ * `values` must name at least one column — the node's schema rejects an empty
3153
+ * field list rather than inserting a blank row, and `check` says so before the
3154
+ * platform does. Field names are the ENTITY's, so copy them from the scenario
3155
+ * or the tenant; nothing offline can tell a real column from a typo.
3156
+ *
3157
+ * See {@link dataFabricRead} for what the native family still does not cover
3158
+ * and which connector operation covers it.
3159
+ *
3160
+ * @param inputs - The entity, the columns the record starts with, and folder scope.
3161
+ * @returns An action spec to pass to `.step(name, …)`.
3162
+ */
3163
+ export declare function dataFabricCreate(inputs: DataFabricCreateInputs): ActionSpec;
2972
3164
  /**
2973
3165
  * Update an entity record in Data Fabric (`core.datafabric.update`). Target the
2974
3166
  * record by id or through an earlier {@link dataFabricRead} step; downstream
2975
3167
  * reads of this step observe the record AFTER the write.
2976
3168
  *
2977
3169
  * @remarks
2978
- * The second and last verb of the native family — see {@link dataFabricRead}
2979
- * for what the family does NOT cover, which connector operation covers it
2980
- * instead, and why entity work routes through the connector during the
2981
- * transition. For an update whose flow also creates, gets or deletes on the
2982
- * same entity, use `connector(…, 'update-entity-record', …)` so the flow keeps
2983
- * one surface.
3170
+ * `set` must write at least one column: an empty `set` is a no-op the platform
3171
+ * reports as success, so `check` rejects it.
3172
+ *
3173
+ * See {@link dataFabricRead} for what the native family still does not cover
3174
+ * and which connector operation covers it.
2984
3175
  *
2985
3176
  * @param inputs - The entity, the record selector, and the columns to write.
2986
3177
  * @returns An action spec to pass to `.step(name, …)`.
2987
3178
  */
2988
3179
  export declare function dataFabricUpdate(inputs: DataFabricUpdateInputs): ActionSpec;
3180
+ /**
3181
+ * Delete an entity record from Data Fabric (`core.datafabric.delete`). Target
3182
+ * the record by id or through an earlier {@link dataFabricRead} step, exactly
3183
+ * as {@link dataFabricUpdate} does.
3184
+ *
3185
+ * @remarks
3186
+ * A delete **publishes nothing** — its definition declares no output — so
3187
+ * `$vars.<step>.output` is undefined at run time and `check` rejects a read of
3188
+ * it. Take what you need off the read step that found the record, before the
3189
+ * delete.
3190
+ *
3191
+ * See {@link dataFabricRead} for what the native family still does not cover
3192
+ * and which connector operation covers it.
3193
+ *
3194
+ * @param inputs - The entity, the record selector, and folder scope.
3195
+ * @returns An action spec to pass to `.step(name, …)`.
3196
+ */
3197
+ export declare function dataFabricDelete(inputs: DataFabricDeleteInputs): ActionSpec;
2989
3198
  /**
2990
3199
  * Declare an Orchestrator QUEUE ITEM step.
2991
3200
  *
@@ -345,7 +345,7 @@ export function batchTransform(inputs) {
345
345
  * with zero envelopes among them. The RUNTIME
346
346
  * accepts both, so only `uip maestro flow validate` sees a wrong one; the
347
347
  * emitter's exemption lives in `migrate.ts` (`UNWRAPPED_INPUTS`).
348
- * See `skill/references/ixp.md` §3.
348
+ * See the IxP node reference (`website/reference/ixp.md`) §3.
349
349
  *
350
350
  * @example
351
351
  * **Extract an invoice total and read it out of the nested result**
@@ -891,71 +891,118 @@ export function dynamicExtract(inputs) {
891
891
  return builtinActionSpec({ kind: 'dynamicExtract', inputs });
892
892
  }
893
893
  /**
894
- * Read ONE entity record from Data Fabric (`core.datafabric.read`). The record
894
+ * Query entity records from Data Fabric (`core.datafabric.read`). The result
895
895
  * publishes to the step's `output`; downstream references re-fetch fresh data
896
896
  * at activation time (the engine re-runs the query rather than caching).
897
897
  *
898
898
  * @remarks
899
- * **Prefer the connector for Data Fabric work during the transition.**
900
- * `core.datafabric.*` has exactly two verbs — this one and
901
- * {@link dataFabricUpdate} — and neither declares an output schema. Create,
902
- * delete, get-by-id, a multi-record query with a row limit, file record fields
903
- * and entity events are NOT in this family: they are operations on the SAME
904
- * product reached through its Integration Service connector,
899
+ * This node is **read-one AND query-many**, on its 1.4 definition: `resultMode:
900
+ * 'multiple'` publishes the matching records under `output.results`, and the
901
+ * platform renames the node "Query entity records" to say so. The SDK still
902
+ * pins 1.0 — read-one — as the no-`{ version }` default, so passing
903
+ * `resultMode` is what selects 1.4; see {@link DataFabricReadInputs.resultMode}.
904
+ *
905
+ * The native family covers all four CRUD verbs: this one,
906
+ * {@link dataFabricCreate}, {@link dataFabricUpdate} and
907
+ * {@link dataFabricDelete}. What it does NOT cover is get-by-id, a query row
908
+ * limit, file record fields, and entity events — those are operations on the
909
+ * SAME product reached through its Integration Service connector,
905
910
  * `uipath-uipath-dataservice` (the tenant displays it as **UiPath Data
906
- * Fabric**), which covers every verb including the two here.
907
- *
908
- * Taking this node for the one verb that has a native form leaves the rest of
909
- * the same entity on the connector — two connection bindings and two payload
910
- * shapes in one flow. So route entity work through the connector unless the
911
- * scenario names these nodes; native forms for the remaining verbs are the
912
- * direction of travel, and this guidance changes when they land. `check` does
913
- * not reject a native node — this is a routing default, not a rule:
911
+ * Fabric**). So a flow that needs one of those still straddles two surfaces,
912
+ * and the connector remains the one surface that covers everything:
914
913
  *
915
914
  * ```ts
916
- * .step('create', connector('uipath-uipath-dataservice', 'create-entity-record',
917
- * { entityName: 'Contracts', contractTitle: 'Q3 renewal' }, { connection: 'df' }))
915
+ * .step('byId', connector('uipath-uipath-dataservice', 'get-entity-record-by-id',
916
+ * { entityName: 'Contracts', recordId: input('id') }, { connection: 'df' }))
918
917
  * ```
919
918
  *
920
- * That operation's body fields come from the entity, so the library cannot
921
- * carry them: run `npx flow-sdk registry prepare uipath-uipath-dataservice
922
- * create-entity-record -f entityName=<Entity>` first (`uip maestro registry
923
- * prepare …` is the same command when you are driving through the UiPath CLI). The routing table is in
924
- * the `data-fabric.md` reference and the parent-field loop in
925
- * `connector-params.md` — cited by name rather than linked, because this
919
+ * A connector operation's body fields come from the entity, so the library
920
+ * cannot carry them: run `uip maestro registry prepare uipath-uipath-dataservice
921
+ * get-entity-record-by-id -f entityName=<Entity>` first (`npx flow-sdk registry
922
+ * prepare …` is the same command when invoking the package's own bin directly).
923
+ * The routing table is in the `data-fabric.md` reference and the parent-field
924
+ * loop in `connector-params.md` — cited by name rather than linked, because this
926
925
  * comment renders both into the flat corpus, where those files sit alongside
927
926
  * it, and onto the site, where each symbol is its own page and a relative
928
927
  * `./data-fabric` resolves to nothing.
929
928
  *
930
- * @param inputs - The entity, optional filter rows, and folder scope.
929
+ * @param inputs - The entity, optional filter rows, result mode, and folder scope.
931
930
  * @returns An action spec to pass to `.step(name, …)`.
932
931
  */
933
932
  export function dataFabricRead(inputs) {
934
933
  return builtinActionSpec({ kind: 'dataFabricRead', inputs });
935
934
  }
935
+ /**
936
+ * Create an entity record in Data Fabric (`core.datafabric.create`). The new
937
+ * record publishes to the step's `output`, so a following
938
+ * {@link dataFabricUpdate} or {@link dataFabricDelete} can read its id.
939
+ *
940
+ * @remarks
941
+ * `values` must name at least one column — the node's schema rejects an empty
942
+ * field list rather than inserting a blank row, and `check` says so before the
943
+ * platform does. Field names are the ENTITY's, so copy them from the scenario
944
+ * or the tenant; nothing offline can tell a real column from a typo.
945
+ *
946
+ * See {@link dataFabricRead} for what the native family still does not cover
947
+ * and which connector operation covers it.
948
+ *
949
+ * @param inputs - The entity, the columns the record starts with, and folder scope.
950
+ * @returns An action spec to pass to `.step(name, …)`.
951
+ */
952
+ export function dataFabricCreate(inputs) {
953
+ return builtinActionSpec({ kind: 'dataFabricCreate', inputs });
954
+ }
936
955
  /**
937
956
  * Update an entity record in Data Fabric (`core.datafabric.update`). Target the
938
957
  * record by id or through an earlier {@link dataFabricRead} step; downstream
939
958
  * reads of this step observe the record AFTER the write.
940
959
  *
941
960
  * @remarks
942
- * The second and last verb of the native family — see {@link dataFabricRead}
943
- * for what the family does NOT cover, which connector operation covers it
944
- * instead, and why entity work routes through the connector during the
945
- * transition. For an update whose flow also creates, gets or deletes on the
946
- * same entity, use `connector(…, 'update-entity-record', …)` so the flow keeps
947
- * one surface.
961
+ * `set` must write at least one column: an empty `set` is a no-op the platform
962
+ * reports as success, so `check` rejects it.
963
+ *
964
+ * See {@link dataFabricRead} for what the native family still does not cover
965
+ * and which connector operation covers it.
948
966
  *
949
967
  * @param inputs - The entity, the record selector, and the columns to write.
950
968
  * @returns An action spec to pass to `.step(name, …)`.
951
969
  */
952
970
  export function dataFabricUpdate(inputs) {
953
- const byId = inputs.record?.byId !== undefined;
954
- const fromRead = typeof inputs.record?.fromRead === 'string';
971
+ assertOneRecordRef(inputs.record, 'dataFabricUpdate');
972
+ return builtinActionSpec({ kind: 'dataFabricUpdate', inputs });
973
+ }
974
+ /**
975
+ * Delete an entity record from Data Fabric (`core.datafabric.delete`). Target
976
+ * the record by id or through an earlier {@link dataFabricRead} step, exactly
977
+ * as {@link dataFabricUpdate} does.
978
+ *
979
+ * @remarks
980
+ * A delete **publishes nothing** — its definition declares no output — so
981
+ * `$vars.<step>.output` is undefined at run time and `check` rejects a read of
982
+ * it. Take what you need off the read step that found the record, before the
983
+ * delete.
984
+ *
985
+ * See {@link dataFabricRead} for what the native family still does not cover
986
+ * and which connector operation covers it.
987
+ *
988
+ * @param inputs - The entity, the record selector, and folder scope.
989
+ * @returns An action spec to pass to `.step(name, …)`.
990
+ */
991
+ export function dataFabricDelete(inputs) {
992
+ assertOneRecordRef(inputs.record, 'dataFabricDelete');
993
+ return builtinActionSpec({ kind: 'dataFabricDelete', inputs });
994
+ }
995
+ /**
996
+ * `record` names exactly ONE of `{ byId }` / `{ fromRead }`. Both forms are
997
+ * optional properties on the same object type, so TypeScript alone cannot
998
+ * refuse `{}` — and an empty selector compiles into a write with no target.
999
+ */
1000
+ function assertOneRecordRef(record, factory) {
1001
+ const byId = record?.byId !== undefined;
1002
+ const fromRead = typeof record?.fromRead === 'string';
955
1003
  if (byId === fromRead) {
956
- throw new Error("dataFabricUpdate() targets exactly ONE of record: { byId } or record: { fromRead: '<step>' }.");
1004
+ throw new Error(`${factory}() targets exactly ONE of record: { byId } or record: { fromRead: '<step>' }.`);
957
1005
  }
958
- return builtinActionSpec({ kind: 'dataFabricUpdate', inputs });
959
1006
  }
960
1007
  /**
961
1008
  * Declare an Orchestrator QUEUE ITEM step.