11import { FolderScopedService } from '../../folder-scoped' ;
2- import { AssetGetResponse , AssetGetAllOptions , AssetGetByIdOptions , AssetGetByNameOptions } from '../../../models/orchestrator/assets.types' ;
2+ import { AssetGetResponse , AssetGetAllOptions , AssetGetByIdOptions , AssetGetByNameOptions , AssetNewValue , AssetValueType } from '../../../models/orchestrator/assets.types' ;
33import { AssetServiceModel } from '../../../models/orchestrator/assets.models' ;
44import { addPrefixToKeys , pascalToCamelCaseKeys , transformData } from '../../../utils/transform' ;
55import { createHeaders } from '../../../utils/http/headers' ;
@@ -12,6 +12,7 @@ import { PaginatedResponse, NonPaginatedResponse, HasPaginationOptions } from '.
1212import { PaginationHelpers } from '../../../utils/pagination/helpers' ;
1313import { PaginationType } from '../../../utils/pagination/internal-types' ;
1414import { track } from '../../../core/telemetry' ;
15+ import { ValidationError } from '../../../core/errors' ;
1516
1617/**
1718 * Service for interacting with UiPath Orchestrator Assets API
@@ -155,4 +156,116 @@ export class AssetService extends FolderScopedService implements AssetServiceMod
155156 ( raw ) => transformData ( pascalToCamelCaseKeys ( raw ) , AssetMap ) ,
156157 ) ;
157158 }
159+
160+ /**
161+ * Updates the value of an existing asset by ID.
162+ *
163+ * Fetches the asset internally to determine its type, then updates only the value while
164+ * preserving the asset's name, scope, and description.
165+ *
166+ * **Supported value types:** `Text`, `Integer`, and `Bool` only. Other types
167+ * (`Credential`, `Secret`) throw a `ValidationError`.
168+ *
169+ * The `newValue` runtime type must match the asset's `valueType`:
170+ * - `Text` → `string`
171+ * - `Integer` → `number` (integer)
172+ * - `Bool` → `boolean`
173+ *
174+ * A `ValidationError` is thrown when the `newValue` type does not match.
175+ *
176+ * Returns void; the API does not return the updated asset, so call
177+ * {@link AssetService.getById} or {@link AssetService.getByName} if you need
178+ * the refreshed value.
179+ *
180+ * @param id - Asset ID
181+ * @param folderId - Required folder ID the asset belongs to
182+ * @param newValue - New value to apply (string for `Text`, number for `Integer`, boolean for `Bool`)
183+ * @returns Promise resolving when the asset has been updated
184+ *
185+ * @example
186+ * ```typescript
187+ * import { Assets } from '@uipath/uipath-typescript/assets';
188+ *
189+ * const assets = new Assets(sdk);
190+ *
191+ * // Update a Text asset
192+ * await assets.updateValueById(<assetId>, <folderId>, 'new-value');
193+ *
194+ * // Update an Integer asset
195+ * await assets.updateValueById(<assetId>, <folderId>, 42);
196+ *
197+ * // Update a Bool asset
198+ * await assets.updateValueById(<assetId>, <folderId>, true);
199+ * ```
200+ */
201+ @track ( 'Assets.UpdateValueById' )
202+ async updateValueById ( id : number , folderId : number , newValue : AssetNewValue ) : Promise < void > {
203+ if ( ! id ) {
204+ throw new ValidationError ( { message : 'id is required for updateValueById' } ) ;
205+ }
206+ if ( ! folderId ) {
207+ throw new ValidationError ( { message : 'folderId is required for updateValueById' } ) ;
208+ }
209+ if ( newValue === null || newValue === undefined ) {
210+ throw new ValidationError ( { message : 'newValue is required for updateValueById' } ) ;
211+ }
212+
213+ const existing = await this . getById ( id , folderId ) ;
214+
215+ const valueField = resolveValueField ( id , existing . valueType , newValue ) ;
216+
217+ const headers = createHeaders ( { [ FOLDER_ID ] : folderId } ) ;
218+ const body : Record < string , unknown > = {
219+ Id : id ,
220+ Name : existing . name ,
221+ ValueScope : existing . valueScope ,
222+ ValueType : existing . valueType ,
223+ Description : existing . description ,
224+ [ valueField ] : newValue ,
225+ } ;
226+
227+ await this . put (
228+ ASSET_ENDPOINTS . GET_BY_ID ( id ) ,
229+ body ,
230+ { headers } ,
231+ ) ;
232+ }
233+ }
234+
235+ /**
236+ * Maps the asset's `valueType` to the PUT body field carrying the new value, validating
237+ * that the new value's runtime type matches the asset type.
238+ */
239+ function resolveValueField (
240+ id : number ,
241+ valueType : AssetValueType ,
242+ newValue : AssetNewValue ,
243+ ) : 'StringValue' | 'IntValue' | 'BoolValue' {
244+ switch ( valueType ) {
245+ case AssetValueType . Text :
246+ if ( typeof newValue !== 'string' ) {
247+ throw new ValidationError ( {
248+ message : `Asset ${ id } has valueType Text; newValue must be a string, got ${ typeof newValue } ` ,
249+ } ) ;
250+ }
251+ return 'StringValue' ;
252+ case AssetValueType . Integer :
253+ if ( typeof newValue !== 'number' || ! Number . isInteger ( newValue ) ) {
254+ throw new ValidationError ( {
255+ message : `Asset ${ id } has valueType Integer; newValue must be an integer number, got ${ typeof newValue } ` ,
256+ } ) ;
257+ }
258+ return 'IntValue' ;
259+ case AssetValueType . Bool :
260+ if ( typeof newValue !== 'boolean' ) {
261+ throw new ValidationError ( {
262+ message : `Asset ${ id } has valueType Bool; newValue must be a boolean, got ${ typeof newValue } ` ,
263+ } ) ;
264+ }
265+ return 'BoolValue' ;
266+ default :
267+ throw new ValidationError ( {
268+ message : `updateValueById only supports Text, Integer, or Bool assets; asset ${ id } has valueType ${ valueType } ` ,
269+ } ) ;
270+ }
158271}
0 commit comments