@uipath/uipath-typescript 1.4.2 → 1.5.1

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 (52) hide show
  1. package/README.md +7 -1
  2. package/dist/agent-memory/index.d.ts +4 -1
  3. package/dist/agents/index.cjs +341 -6
  4. package/dist/agents/index.d.ts +717 -16
  5. package/dist/agents/index.mjs +342 -7
  6. package/dist/assets/index.cjs +132 -15
  7. package/dist/assets/index.d.ts +12 -1
  8. package/dist/assets/index.mjs +132 -15
  9. package/dist/attachments/index.cjs +120 -12
  10. package/dist/attachments/index.mjs +120 -12
  11. package/dist/buckets/index.cjs +136 -15
  12. package/dist/buckets/index.d.ts +12 -1
  13. package/dist/buckets/index.mjs +136 -15
  14. package/dist/cases/index.cjs +1203 -938
  15. package/dist/cases/index.d.ts +325 -45
  16. package/dist/cases/index.mjs +1203 -938
  17. package/dist/conversational-agent/index.cjs +48 -10
  18. package/dist/conversational-agent/index.d.ts +117 -6
  19. package/dist/conversational-agent/index.mjs +48 -10
  20. package/dist/core/index.cjs +1 -1
  21. package/dist/core/index.mjs +1 -1
  22. package/dist/entities/index.cjs +448 -9
  23. package/dist/entities/index.d.ts +441 -1
  24. package/dist/entities/index.mjs +447 -10
  25. package/dist/feedback/index.cjs +25 -9
  26. package/dist/feedback/index.mjs +25 -9
  27. package/dist/index.cjs +1281 -330
  28. package/dist/index.d.ts +1988 -143
  29. package/dist/index.mjs +1282 -331
  30. package/dist/index.umd.js +1230 -279
  31. package/dist/jobs/index.cjs +141 -19
  32. package/dist/jobs/index.d.ts +22 -6
  33. package/dist/jobs/index.mjs +141 -19
  34. package/dist/maestro-processes/index.cjs +553 -354
  35. package/dist/maestro-processes/index.d.ts +376 -47
  36. package/dist/maestro-processes/index.mjs +553 -354
  37. package/dist/notifications/index.cjs +2012 -0
  38. package/dist/notifications/index.d.ts +615 -0
  39. package/dist/notifications/index.mjs +2010 -0
  40. package/dist/processes/index.cjs +118 -18
  41. package/dist/processes/index.d.ts +18 -2
  42. package/dist/processes/index.mjs +118 -18
  43. package/dist/queues/index.cjs +131 -14
  44. package/dist/queues/index.d.ts +12 -1
  45. package/dist/queues/index.mjs +131 -14
  46. package/dist/tasks/index.cjs +125 -13
  47. package/dist/tasks/index.d.ts +4 -1
  48. package/dist/tasks/index.mjs +125 -13
  49. package/dist/traces/index.cjs +220 -6
  50. package/dist/traces/index.d.ts +360 -25
  51. package/dist/traces/index.mjs +221 -7
  52. package/package.json +14 -4
@@ -956,7 +956,16 @@ const BUCKET_TOKEN_PARAMS = {
956
956
  * Returns the original value if parsing fails.
957
957
  */
958
958
  /**
959
- * Transforms data by mapping fields according to the provided field mapping
959
+ * Transforms data by renaming each key in `data` exactly once, using the
960
+ * mapping (`sourceField → targetField`). Keys not present in the mapping
961
+ * pass through unchanged. The original (pre-rename) key is dropped — the
962
+ * result contains only the renamed key.
963
+ *
964
+ * Each rename is independent. If the mapping happens to contain chained
965
+ * entries (`a → b` and `b → c`), they do NOT compose: a field named `a`
966
+ * in `data` becomes `b` (not `c`), because the renames are applied based
967
+ * on the original data's keys, not the running result.
968
+ *
960
969
  * @param data The source data to transform
961
970
  * @param fieldMapping Object mapping source field names to target field names
962
971
  * @returns Transformed data with mapped field names
@@ -979,21 +988,28 @@ const BUCKET_TOKEN_PARAMS = {
979
988
  * // { userId: '123', name: 'john' },
980
989
  * // { userId: '456', name: 'jane' }
981
990
  * // ]
991
+ *
992
+ * // No chaining — `a → b` does not become `a → c` even if the map has `b → c`.
993
+ * transformData({ a: 1 }, { a: 'b', b: 'c' });
994
+ * // result = { b: 1 }
982
995
  * ```
983
996
  */
984
997
  function transformData(data, fieldMapping) {
998
+ // Pass null/undefined through unchanged — callers (e.g. AttachmentService.getById)
999
+ // may invoke this on optional fields that an OData `select` excluded.
1000
+ if (data == null) {
1001
+ return data;
1002
+ }
985
1003
  // Handle array of objects
986
1004
  if (Array.isArray(data)) {
987
1005
  return data.map(item => transformData(item, fieldMapping));
988
1006
  }
989
- // Handle single object
990
- const result = { ...data };
991
- for (const [sourceField, targetField] of Object.entries(fieldMapping)) {
992
- if (sourceField in result) {
993
- const value = result[sourceField];
994
- delete result[sourceField];
995
- result[targetField] = value;
996
- }
1007
+ // Walk the ORIGINAL data's keys, look up each in the mapping. One rename
1008
+ // per data key — no mutation of an in-progress result, so chains can't form.
1009
+ const result = {};
1010
+ for (const [key, value] of Object.entries(data)) {
1011
+ const renamedKey = fieldMapping[key] ?? key;
1012
+ result[renamedKey] = value;
997
1013
  }
998
1014
  return result;
999
1015
  }
@@ -1103,6 +1119,97 @@ function addPrefixToKeys(obj, prefix, keys) {
1103
1119
  }
1104
1120
  return result;
1105
1121
  }
1122
+ /**
1123
+ * Creates a new map with the keys and values reversed
1124
+ * @param map The original map to reverse
1125
+ * @returns A new map with keys and values swapped
1126
+ *
1127
+ * @example
1128
+ * ```typescript
1129
+ * const original = { key1: 'value1', key2: 'value2' };
1130
+ * const reversed = reverseMap(original);
1131
+ * // reversed = { value1: 'key1', value2: 'key2' }
1132
+ * ```
1133
+ */
1134
+ function reverseMap(map) {
1135
+ return Object.entries(map).reduce((acc, [key, value]) => {
1136
+ acc[value] = key;
1137
+ return acc;
1138
+ }, {});
1139
+ }
1140
+ /**
1141
+ * OData query-string keys whose values may contain field identifiers that
1142
+ * need rewriting from SDK names → API names.
1143
+ */
1144
+ const ODATA_FIELD_PARAM_KEYS = ['filter', 'orderby', 'select', 'expand'];
1145
+ /**
1146
+ * Matches one token at a time in an OData expression:
1147
+ * 1. A single-quoted string literal, allowing the `''` escape sequence —
1148
+ * consumed atomically so identifiers inside the literal can't match.
1149
+ * 2. An OData identifier (`[A-Za-z_][A-Za-z0-9_]*`).
1150
+ * Anything else (whitespace, operators, parens, commas) is left alone by
1151
+ * `String.prototype.replace`, which only substitutes matched substrings.
1152
+ */
1153
+ const ODATA_TOKEN_RE = /'(?:[^']|'')*'|[A-Za-z_][A-Za-z0-9_]*/g;
1154
+ /**
1155
+ * Rewrites SDK field identifiers to API field identifiers inside an OData
1156
+ * expression string (`$filter`, `$orderby`, `$select`, `$expand`).
1157
+ *
1158
+ * Field maps (e.g. `JobMap`) rename API fields → SDK fields on responses, so
1159
+ * SDK consumers see the renamed names. Without this rewrite, the same name
1160
+ * in a `filter` string would be forwarded verbatim and the API (which still
1161
+ * uses the original name) would reject it.
1162
+ *
1163
+ * Quoted string literals (with the OData `''` escape) are preserved exactly:
1164
+ * the token regex consumes them whole, so identifiers inside literals never
1165
+ * match. Identifier tokens are looked up in the reversed field map.
1166
+ *
1167
+ * @example
1168
+ * ```typescript
1169
+ * const requestMap = { processName: 'releaseName' };
1170
+ * rewriteODataIdentifiers("processName eq 'processName'", requestMap);
1171
+ * // "releaseName eq 'processName'" — identifier rewritten, literal preserved
1172
+ * ```
1173
+ */
1174
+ function rewriteODataIdentifiers(expression, requestMap) {
1175
+ if (!expression)
1176
+ return expression;
1177
+ return expression.replace(ODATA_TOKEN_RE, (match) => match.startsWith("'") ? match : (requestMap[match] ?? match));
1178
+ }
1179
+ /**
1180
+ * Symmetric counterpart of {@link transformRequest} for OData query options:
1181
+ * rewrites SDK field identifiers inside the recognized OData string params
1182
+ * (`filter`, `orderby`, `select`, `expand`) to their API names using the
1183
+ * reversed form of a response field map. Returns a shallow copy with the
1184
+ * relevant values rewritten; other keys pass through unchanged.
1185
+ *
1186
+ * Use at the OData edge so SDK consumers can refer to renamed fields by
1187
+ * their SDK name throughout — for reading the response and for filtering /
1188
+ * sorting / projecting / expanding.
1189
+ *
1190
+ * @param options The OData query options as authored with SDK field names
1191
+ * @param responseMap The response field map (API → SDK); reversed internally
1192
+ *
1193
+ * @example
1194
+ * ```typescript
1195
+ * // JobMap renames releaseName → processName on responses.
1196
+ * transformOptions({ filter: "processName eq 'X'" }, JobMap);
1197
+ * // { filter: "releaseName eq 'X'" }
1198
+ * ```
1199
+ */
1200
+ function transformOptions(options, responseMap) {
1201
+ const requestMap = reverseMap(responseMap);
1202
+ if (Object.keys(requestMap).length === 0)
1203
+ return options;
1204
+ const result = { ...options };
1205
+ for (const key of ODATA_FIELD_PARAM_KEYS) {
1206
+ const value = result[key];
1207
+ if (typeof value === 'string') {
1208
+ result[key] = rewriteODataIdentifiers(value, requestMap);
1209
+ }
1210
+ }
1211
+ return result;
1212
+ }
1106
1213
 
1107
1214
  /**
1108
1215
  * Constants used throughout the pagination system
@@ -1866,9 +1973,12 @@ class FolderScopedService extends BaseService {
1866
1973
  * @param name - Resource name to search for
1867
1974
  * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) + OData query options (`expand`, `select`)
1868
1975
  * @param transform - Maps a raw OData item to the typed response (e.g. PascalCase → camelCase via field map)
1976
+ * @param responseFieldMap - Optional response field map (API → SDK), reversed internally by
1977
+ * `transformOptions` to rewrite SDK field names back to API names in user-supplied
1978
+ * `expand` / `select` (symmetric counterpart to `transform`)
1869
1979
  * @throws ValidationError when inputs are malformed; NotFoundError when no match
1870
1980
  */
1871
- async getByNameLookup(resourceType, endpoint, name, options, transform) {
1981
+ async getByNameLookup(resourceType, endpoint, name, options, transform, responseFieldMap) {
1872
1982
  const validatedName = validateName(resourceType, name);
1873
1983
  const { folderId, folderKey, folderPath, ...queryOptions } = options;
1874
1984
  const headers = resolveFolderHeaders({
@@ -1878,8 +1988,11 @@ class FolderScopedService extends BaseService {
1878
1988
  resourceType: `${resourceType}.getByName`,
1879
1989
  fallbackFolderKey: this.config.folderKey,
1880
1990
  });
1991
+ const apiFieldOptions = responseFieldMap
1992
+ ? transformOptions(queryOptions, responseFieldMap)
1993
+ : queryOptions;
1881
1994
  const apiOptions = {
1882
- ...addPrefixToKeys(queryOptions, ODATA_PREFIX, Object.keys(queryOptions)),
1995
+ ...addPrefixToKeys(apiFieldOptions, ODATA_PREFIX, Object.keys(apiFieldOptions)),
1883
1996
  '$filter': `Name eq '${validatedName.replace(SINGLE_QUOTE_RE, "''")}'`,
1884
1997
  '$top': '1',
1885
1998
  };
@@ -2016,6 +2129,10 @@ class QueueService extends FolderScopedService {
2016
2129
  async getAll(options) {
2017
2130
  // Transformation function for queues
2018
2131
  const transformQueueResponse = (queue) => transformData(pascalToCamelCaseKeys(queue), QueueMap);
2132
+ // Rewrite renamed SDK field names → API names inside OData strings
2133
+ // before delegating, mirroring the transformRequest pattern used for
2134
+ // request bodies.
2135
+ const apiOptions = options ? transformOptions(options, QueueMap) : options;
2019
2136
  return PaginationHelpers.getAll({
2020
2137
  serviceAccess: this.createPaginationServiceAccess(),
2021
2138
  getEndpoint: (folderId) => folderId ? QUEUE_ENDPOINTS.GET_BY_FOLDER : QUEUE_ENDPOINTS.GET_ALL,
@@ -2031,7 +2148,7 @@ class QueueService extends FolderScopedService {
2031
2148
  countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
2032
2149
  }
2033
2150
  }
2034
- }, options);
2151
+ }, apiOptions);
2035
2152
  }
2036
2153
  /**
2037
2154
  * Gets a single queue by ID
@@ -2052,8 +2169,8 @@ class QueueService extends FolderScopedService {
2052
2169
  */
2053
2170
  async getById(id, folderId, options = {}) {
2054
2171
  const headers = createHeaders({ [FOLDER_ID]: folderId });
2055
- const keysToPrefix = Object.keys(options);
2056
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
2172
+ const apiFieldOptions = transformOptions(options, QueueMap);
2173
+ const apiOptions = addPrefixToKeys(apiFieldOptions, ODATA_PREFIX, Object.keys(apiFieldOptions));
2057
2174
  const response = await this.get(QUEUE_ENDPOINTS.GET_BY_ID(id), {
2058
2175
  headers,
2059
2176
  params: apiOptions
@@ -326,6 +326,14 @@ interface FolderScopedOptions extends BaseOptions {
326
326
  folderPath?: string;
327
327
  }
328
328
 
329
+ /**
330
+ * Type for field mapping configuration
331
+ * Maps source field names to target field names
332
+ */
333
+ type FieldMapping = {
334
+ [sourceField: string]: string;
335
+ };
336
+
329
337
  /**
330
338
  * Base service for services that need folder-specific functionality.
331
339
  *
@@ -367,9 +375,12 @@ declare class FolderScopedService extends BaseService {
367
375
  * @param name - Resource name to search for
368
376
  * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) + OData query options (`expand`, `select`)
369
377
  * @param transform - Maps a raw OData item to the typed response (e.g. PascalCase → camelCase via field map)
378
+ * @param responseFieldMap - Optional response field map (API → SDK), reversed internally by
379
+ * `transformOptions` to rewrite SDK field names back to API names in user-supplied
380
+ * `expand` / `select` (symmetric counterpart to `transform`)
370
381
  * @throws ValidationError when inputs are malformed; NotFoundError when no match
371
382
  */
372
- protected getByNameLookup<TRaw extends object, T>(resourceType: string, endpoint: string, name: string, options: FolderScopedOptions, transform: (raw: TRaw) => T): Promise<T>;
383
+ protected getByNameLookup<TRaw extends object, T>(resourceType: string, endpoint: string, name: string, options: FolderScopedOptions, transform: (raw: TRaw) => T, responseFieldMap?: FieldMapping): Promise<T>;
373
384
  }
374
385
 
375
386
  /**
@@ -954,7 +954,16 @@ const BUCKET_TOKEN_PARAMS = {
954
954
  * Returns the original value if parsing fails.
955
955
  */
956
956
  /**
957
- * Transforms data by mapping fields according to the provided field mapping
957
+ * Transforms data by renaming each key in `data` exactly once, using the
958
+ * mapping (`sourceField → targetField`). Keys not present in the mapping
959
+ * pass through unchanged. The original (pre-rename) key is dropped — the
960
+ * result contains only the renamed key.
961
+ *
962
+ * Each rename is independent. If the mapping happens to contain chained
963
+ * entries (`a → b` and `b → c`), they do NOT compose: a field named `a`
964
+ * in `data` becomes `b` (not `c`), because the renames are applied based
965
+ * on the original data's keys, not the running result.
966
+ *
958
967
  * @param data The source data to transform
959
968
  * @param fieldMapping Object mapping source field names to target field names
960
969
  * @returns Transformed data with mapped field names
@@ -977,21 +986,28 @@ const BUCKET_TOKEN_PARAMS = {
977
986
  * // { userId: '123', name: 'john' },
978
987
  * // { userId: '456', name: 'jane' }
979
988
  * // ]
989
+ *
990
+ * // No chaining — `a → b` does not become `a → c` even if the map has `b → c`.
991
+ * transformData({ a: 1 }, { a: 'b', b: 'c' });
992
+ * // result = { b: 1 }
980
993
  * ```
981
994
  */
982
995
  function transformData(data, fieldMapping) {
996
+ // Pass null/undefined through unchanged — callers (e.g. AttachmentService.getById)
997
+ // may invoke this on optional fields that an OData `select` excluded.
998
+ if (data == null) {
999
+ return data;
1000
+ }
983
1001
  // Handle array of objects
984
1002
  if (Array.isArray(data)) {
985
1003
  return data.map(item => transformData(item, fieldMapping));
986
1004
  }
987
- // Handle single object
988
- const result = { ...data };
989
- for (const [sourceField, targetField] of Object.entries(fieldMapping)) {
990
- if (sourceField in result) {
991
- const value = result[sourceField];
992
- delete result[sourceField];
993
- result[targetField] = value;
994
- }
1005
+ // Walk the ORIGINAL data's keys, look up each in the mapping. One rename
1006
+ // per data key — no mutation of an in-progress result, so chains can't form.
1007
+ const result = {};
1008
+ for (const [key, value] of Object.entries(data)) {
1009
+ const renamedKey = fieldMapping[key] ?? key;
1010
+ result[renamedKey] = value;
995
1011
  }
996
1012
  return result;
997
1013
  }
@@ -1101,6 +1117,97 @@ function addPrefixToKeys(obj, prefix, keys) {
1101
1117
  }
1102
1118
  return result;
1103
1119
  }
1120
+ /**
1121
+ * Creates a new map with the keys and values reversed
1122
+ * @param map The original map to reverse
1123
+ * @returns A new map with keys and values swapped
1124
+ *
1125
+ * @example
1126
+ * ```typescript
1127
+ * const original = { key1: 'value1', key2: 'value2' };
1128
+ * const reversed = reverseMap(original);
1129
+ * // reversed = { value1: 'key1', value2: 'key2' }
1130
+ * ```
1131
+ */
1132
+ function reverseMap(map) {
1133
+ return Object.entries(map).reduce((acc, [key, value]) => {
1134
+ acc[value] = key;
1135
+ return acc;
1136
+ }, {});
1137
+ }
1138
+ /**
1139
+ * OData query-string keys whose values may contain field identifiers that
1140
+ * need rewriting from SDK names → API names.
1141
+ */
1142
+ const ODATA_FIELD_PARAM_KEYS = ['filter', 'orderby', 'select', 'expand'];
1143
+ /**
1144
+ * Matches one token at a time in an OData expression:
1145
+ * 1. A single-quoted string literal, allowing the `''` escape sequence —
1146
+ * consumed atomically so identifiers inside the literal can't match.
1147
+ * 2. An OData identifier (`[A-Za-z_][A-Za-z0-9_]*`).
1148
+ * Anything else (whitespace, operators, parens, commas) is left alone by
1149
+ * `String.prototype.replace`, which only substitutes matched substrings.
1150
+ */
1151
+ const ODATA_TOKEN_RE = /'(?:[^']|'')*'|[A-Za-z_][A-Za-z0-9_]*/g;
1152
+ /**
1153
+ * Rewrites SDK field identifiers to API field identifiers inside an OData
1154
+ * expression string (`$filter`, `$orderby`, `$select`, `$expand`).
1155
+ *
1156
+ * Field maps (e.g. `JobMap`) rename API fields → SDK fields on responses, so
1157
+ * SDK consumers see the renamed names. Without this rewrite, the same name
1158
+ * in a `filter` string would be forwarded verbatim and the API (which still
1159
+ * uses the original name) would reject it.
1160
+ *
1161
+ * Quoted string literals (with the OData `''` escape) are preserved exactly:
1162
+ * the token regex consumes them whole, so identifiers inside literals never
1163
+ * match. Identifier tokens are looked up in the reversed field map.
1164
+ *
1165
+ * @example
1166
+ * ```typescript
1167
+ * const requestMap = { processName: 'releaseName' };
1168
+ * rewriteODataIdentifiers("processName eq 'processName'", requestMap);
1169
+ * // "releaseName eq 'processName'" — identifier rewritten, literal preserved
1170
+ * ```
1171
+ */
1172
+ function rewriteODataIdentifiers(expression, requestMap) {
1173
+ if (!expression)
1174
+ return expression;
1175
+ return expression.replace(ODATA_TOKEN_RE, (match) => match.startsWith("'") ? match : (requestMap[match] ?? match));
1176
+ }
1177
+ /**
1178
+ * Symmetric counterpart of {@link transformRequest} for OData query options:
1179
+ * rewrites SDK field identifiers inside the recognized OData string params
1180
+ * (`filter`, `orderby`, `select`, `expand`) to their API names using the
1181
+ * reversed form of a response field map. Returns a shallow copy with the
1182
+ * relevant values rewritten; other keys pass through unchanged.
1183
+ *
1184
+ * Use at the OData edge so SDK consumers can refer to renamed fields by
1185
+ * their SDK name throughout — for reading the response and for filtering /
1186
+ * sorting / projecting / expanding.
1187
+ *
1188
+ * @param options The OData query options as authored with SDK field names
1189
+ * @param responseMap The response field map (API → SDK); reversed internally
1190
+ *
1191
+ * @example
1192
+ * ```typescript
1193
+ * // JobMap renames releaseName → processName on responses.
1194
+ * transformOptions({ filter: "processName eq 'X'" }, JobMap);
1195
+ * // { filter: "releaseName eq 'X'" }
1196
+ * ```
1197
+ */
1198
+ function transformOptions(options, responseMap) {
1199
+ const requestMap = reverseMap(responseMap);
1200
+ if (Object.keys(requestMap).length === 0)
1201
+ return options;
1202
+ const result = { ...options };
1203
+ for (const key of ODATA_FIELD_PARAM_KEYS) {
1204
+ const value = result[key];
1205
+ if (typeof value === 'string') {
1206
+ result[key] = rewriteODataIdentifiers(value, requestMap);
1207
+ }
1208
+ }
1209
+ return result;
1210
+ }
1104
1211
 
1105
1212
  /**
1106
1213
  * Constants used throughout the pagination system
@@ -1864,9 +1971,12 @@ class FolderScopedService extends BaseService {
1864
1971
  * @param name - Resource name to search for
1865
1972
  * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) + OData query options (`expand`, `select`)
1866
1973
  * @param transform - Maps a raw OData item to the typed response (e.g. PascalCase → camelCase via field map)
1974
+ * @param responseFieldMap - Optional response field map (API → SDK), reversed internally by
1975
+ * `transformOptions` to rewrite SDK field names back to API names in user-supplied
1976
+ * `expand` / `select` (symmetric counterpart to `transform`)
1867
1977
  * @throws ValidationError when inputs are malformed; NotFoundError when no match
1868
1978
  */
1869
- async getByNameLookup(resourceType, endpoint, name, options, transform) {
1979
+ async getByNameLookup(resourceType, endpoint, name, options, transform, responseFieldMap) {
1870
1980
  const validatedName = validateName(resourceType, name);
1871
1981
  const { folderId, folderKey, folderPath, ...queryOptions } = options;
1872
1982
  const headers = resolveFolderHeaders({
@@ -1876,8 +1986,11 @@ class FolderScopedService extends BaseService {
1876
1986
  resourceType: `${resourceType}.getByName`,
1877
1987
  fallbackFolderKey: this.config.folderKey,
1878
1988
  });
1989
+ const apiFieldOptions = responseFieldMap
1990
+ ? transformOptions(queryOptions, responseFieldMap)
1991
+ : queryOptions;
1879
1992
  const apiOptions = {
1880
- ...addPrefixToKeys(queryOptions, ODATA_PREFIX, Object.keys(queryOptions)),
1993
+ ...addPrefixToKeys(apiFieldOptions, ODATA_PREFIX, Object.keys(apiFieldOptions)),
1881
1994
  '$filter': `Name eq '${validatedName.replace(SINGLE_QUOTE_RE, "''")}'`,
1882
1995
  '$top': '1',
1883
1996
  };
@@ -2014,6 +2127,10 @@ class QueueService extends FolderScopedService {
2014
2127
  async getAll(options) {
2015
2128
  // Transformation function for queues
2016
2129
  const transformQueueResponse = (queue) => transformData(pascalToCamelCaseKeys(queue), QueueMap);
2130
+ // Rewrite renamed SDK field names → API names inside OData strings
2131
+ // before delegating, mirroring the transformRequest pattern used for
2132
+ // request bodies.
2133
+ const apiOptions = options ? transformOptions(options, QueueMap) : options;
2017
2134
  return PaginationHelpers.getAll({
2018
2135
  serviceAccess: this.createPaginationServiceAccess(),
2019
2136
  getEndpoint: (folderId) => folderId ? QUEUE_ENDPOINTS.GET_BY_FOLDER : QUEUE_ENDPOINTS.GET_ALL,
@@ -2029,7 +2146,7 @@ class QueueService extends FolderScopedService {
2029
2146
  countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
2030
2147
  }
2031
2148
  }
2032
- }, options);
2149
+ }, apiOptions);
2033
2150
  }
2034
2151
  /**
2035
2152
  * Gets a single queue by ID
@@ -2050,8 +2167,8 @@ class QueueService extends FolderScopedService {
2050
2167
  */
2051
2168
  async getById(id, folderId, options = {}) {
2052
2169
  const headers = createHeaders({ [FOLDER_ID]: folderId });
2053
- const keysToPrefix = Object.keys(options);
2054
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
2170
+ const apiFieldOptions = transformOptions(options, QueueMap);
2171
+ const apiOptions = addPrefixToKeys(apiFieldOptions, ODATA_PREFIX, Object.keys(apiFieldOptions));
2055
2172
  const response = await this.get(QUEUE_ENDPOINTS.GET_BY_ID(id), {
2056
2173
  headers,
2057
2174
  params: apiOptions
@@ -715,7 +715,16 @@ var PaginationType;
715
715
  * Returns the original value if parsing fails.
716
716
  */
717
717
  /**
718
- * Transforms data by mapping fields according to the provided field mapping
718
+ * Transforms data by renaming each key in `data` exactly once, using the
719
+ * mapping (`sourceField → targetField`). Keys not present in the mapping
720
+ * pass through unchanged. The original (pre-rename) key is dropped — the
721
+ * result contains only the renamed key.
722
+ *
723
+ * Each rename is independent. If the mapping happens to contain chained
724
+ * entries (`a → b` and `b → c`), they do NOT compose: a field named `a`
725
+ * in `data` becomes `b` (not `c`), because the renames are applied based
726
+ * on the original data's keys, not the running result.
727
+ *
719
728
  * @param data The source data to transform
720
729
  * @param fieldMapping Object mapping source field names to target field names
721
730
  * @returns Transformed data with mapped field names
@@ -738,21 +747,28 @@ var PaginationType;
738
747
  * // { userId: '123', name: 'john' },
739
748
  * // { userId: '456', name: 'jane' }
740
749
  * // ]
750
+ *
751
+ * // No chaining — `a → b` does not become `a → c` even if the map has `b → c`.
752
+ * transformData({ a: 1 }, { a: 'b', b: 'c' });
753
+ * // result = { b: 1 }
741
754
  * ```
742
755
  */
743
756
  function transformData(data, fieldMapping) {
757
+ // Pass null/undefined through unchanged — callers (e.g. AttachmentService.getById)
758
+ // may invoke this on optional fields that an OData `select` excluded.
759
+ if (data == null) {
760
+ return data;
761
+ }
744
762
  // Handle array of objects
745
763
  if (Array.isArray(data)) {
746
764
  return data.map(item => transformData(item, fieldMapping));
747
765
  }
748
- // Handle single object
749
- const result = { ...data };
750
- for (const [sourceField, targetField] of Object.entries(fieldMapping)) {
751
- if (sourceField in result) {
752
- const value = result[sourceField];
753
- delete result[sourceField];
754
- result[targetField] = value;
755
- }
766
+ // Walk the ORIGINAL data's keys, look up each in the mapping. One rename
767
+ // per data key — no mutation of an in-progress result, so chains can't form.
768
+ const result = {};
769
+ for (const [key, value] of Object.entries(data)) {
770
+ const renamedKey = fieldMapping[key] ?? key;
771
+ result[renamedKey] = value;
756
772
  }
757
773
  return result;
758
774
  }
@@ -967,6 +983,97 @@ function addPrefixToKeys(obj, prefix, keys) {
967
983
  }
968
984
  return result;
969
985
  }
986
+ /**
987
+ * Creates a new map with the keys and values reversed
988
+ * @param map The original map to reverse
989
+ * @returns A new map with keys and values swapped
990
+ *
991
+ * @example
992
+ * ```typescript
993
+ * const original = { key1: 'value1', key2: 'value2' };
994
+ * const reversed = reverseMap(original);
995
+ * // reversed = { value1: 'key1', value2: 'key2' }
996
+ * ```
997
+ */
998
+ function reverseMap(map) {
999
+ return Object.entries(map).reduce((acc, [key, value]) => {
1000
+ acc[value] = key;
1001
+ return acc;
1002
+ }, {});
1003
+ }
1004
+ /**
1005
+ * OData query-string keys whose values may contain field identifiers that
1006
+ * need rewriting from SDK names → API names.
1007
+ */
1008
+ const ODATA_FIELD_PARAM_KEYS = ['filter', 'orderby', 'select', 'expand'];
1009
+ /**
1010
+ * Matches one token at a time in an OData expression:
1011
+ * 1. A single-quoted string literal, allowing the `''` escape sequence —
1012
+ * consumed atomically so identifiers inside the literal can't match.
1013
+ * 2. An OData identifier (`[A-Za-z_][A-Za-z0-9_]*`).
1014
+ * Anything else (whitespace, operators, parens, commas) is left alone by
1015
+ * `String.prototype.replace`, which only substitutes matched substrings.
1016
+ */
1017
+ const ODATA_TOKEN_RE = /'(?:[^']|'')*'|[A-Za-z_][A-Za-z0-9_]*/g;
1018
+ /**
1019
+ * Rewrites SDK field identifiers to API field identifiers inside an OData
1020
+ * expression string (`$filter`, `$orderby`, `$select`, `$expand`).
1021
+ *
1022
+ * Field maps (e.g. `JobMap`) rename API fields → SDK fields on responses, so
1023
+ * SDK consumers see the renamed names. Without this rewrite, the same name
1024
+ * in a `filter` string would be forwarded verbatim and the API (which still
1025
+ * uses the original name) would reject it.
1026
+ *
1027
+ * Quoted string literals (with the OData `''` escape) are preserved exactly:
1028
+ * the token regex consumes them whole, so identifiers inside literals never
1029
+ * match. Identifier tokens are looked up in the reversed field map.
1030
+ *
1031
+ * @example
1032
+ * ```typescript
1033
+ * const requestMap = { processName: 'releaseName' };
1034
+ * rewriteODataIdentifiers("processName eq 'processName'", requestMap);
1035
+ * // "releaseName eq 'processName'" — identifier rewritten, literal preserved
1036
+ * ```
1037
+ */
1038
+ function rewriteODataIdentifiers(expression, requestMap) {
1039
+ if (!expression)
1040
+ return expression;
1041
+ return expression.replace(ODATA_TOKEN_RE, (match) => match.startsWith("'") ? match : (requestMap[match] ?? match));
1042
+ }
1043
+ /**
1044
+ * Symmetric counterpart of {@link transformRequest} for OData query options:
1045
+ * rewrites SDK field identifiers inside the recognized OData string params
1046
+ * (`filter`, `orderby`, `select`, `expand`) to their API names using the
1047
+ * reversed form of a response field map. Returns a shallow copy with the
1048
+ * relevant values rewritten; other keys pass through unchanged.
1049
+ *
1050
+ * Use at the OData edge so SDK consumers can refer to renamed fields by
1051
+ * their SDK name throughout — for reading the response and for filtering /
1052
+ * sorting / projecting / expanding.
1053
+ *
1054
+ * @param options The OData query options as authored with SDK field names
1055
+ * @param responseMap The response field map (API → SDK); reversed internally
1056
+ *
1057
+ * @example
1058
+ * ```typescript
1059
+ * // JobMap renames releaseName → processName on responses.
1060
+ * transformOptions({ filter: "processName eq 'X'" }, JobMap);
1061
+ * // { filter: "releaseName eq 'X'" }
1062
+ * ```
1063
+ */
1064
+ function transformOptions(options, responseMap) {
1065
+ const requestMap = reverseMap(responseMap);
1066
+ if (Object.keys(requestMap).length === 0)
1067
+ return options;
1068
+ const result = { ...options };
1069
+ for (const key of ODATA_FIELD_PARAM_KEYS) {
1070
+ const value = result[key];
1071
+ if (typeof value === 'string') {
1072
+ result[key] = rewriteODataIdentifiers(value, requestMap);
1073
+ }
1074
+ }
1075
+ return result;
1076
+ }
970
1077
 
971
1078
  /**
972
1079
  * Constants used throughout the pagination system
@@ -2260,6 +2367,10 @@ class TaskService extends BaseService {
2260
2367
  const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskMap);
2261
2368
  return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
2262
2369
  };
2370
+ // Rewrite renamed SDK field names → API names inside OData strings
2371
+ // before delegating, mirroring the transformRequest pattern used for
2372
+ // request bodies.
2373
+ const apiOptions = options ? transformOptions(options, TaskMap) : options;
2263
2374
  return PaginationHelpers.getAll({
2264
2375
  serviceAccess: this.createPaginationServiceAccess(),
2265
2376
  getEndpoint: () => endpoint,
@@ -2276,7 +2387,7 @@ class TaskService extends BaseService {
2276
2387
  countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM // OData OFFSET parameter
2277
2388
  }
2278
2389
  }
2279
- }, options);
2390
+ }, apiOptions);
2280
2391
  }
2281
2392
  /**
2282
2393
  * Gets a task by ID
@@ -2312,9 +2423,10 @@ class TaskService extends BaseService {
2312
2423
  const headers = createHeaders({ [FOLDER_ID]: folderId });
2313
2424
  // Add default expand parameters
2314
2425
  const modifiedOptions = this.addDefaultExpand(restOptions);
2315
- // prefix all keys in options
2316
- const keysToPrefix = Object.keys(modifiedOptions);
2317
- const apiOptions = addPrefixToKeys(modifiedOptions, ODATA_PREFIX, keysToPrefix);
2426
+ // Rewrite renamed SDK field names → API names inside OData strings,
2427
+ // then prefix all keys for OData.
2428
+ const apiFieldOptions = transformOptions(modifiedOptions, TaskMap);
2429
+ const apiOptions = addPrefixToKeys(apiFieldOptions, ODATA_PREFIX, Object.keys(apiFieldOptions));
2318
2430
  const response = await this.get(TASK_ENDPOINTS.GET_BY_ID(id), {
2319
2431
  params: apiOptions,
2320
2432
  headers
@@ -26,7 +26,10 @@ declare enum JobState {
26
26
  Successful = "Successful",
27
27
  Stopped = "Stopped",
28
28
  Suspended = "Suspended",
29
- Resumed = "Resumed"
29
+ Resumed = "Resumed",
30
+ Cancelled = "Cancelled",
31
+ /** Server-side fallback for an unrecognized or missing job state. */
32
+ Unknown = "Unknown"
30
33
  }
31
34
  interface BaseOptions {
32
35
  expand?: string;