@torrow/sdk-client 0.17.1 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9959,10 +9959,10 @@ function validateOperationNoteTypes(body, method, path) {
9959
9959
  if (Array.isArray(current) && node.items !== void 0) {
9960
9960
  current.forEach((entry, i) => merge(invalidPaths(entry, node.items, `${path2}/${i}`, /* @__PURE__ */ new Set())));
9961
9961
  } else if (typeof current === "object" && !Array.isArray(current)) {
9962
- const record6 = current;
9962
+ const record7 = current;
9963
9963
  for (const [key, child] of Object.entries(node.properties ?? {})) {
9964
- if (Object.hasOwn(record6, key)) {
9965
- merge(invalidPaths(record6[key], child, `${path2}/${key}`, /* @__PURE__ */ new Set()));
9964
+ if (Object.hasOwn(record7, key)) {
9965
+ merge(invalidPaths(record7[key], child, `${path2}/${key}`, /* @__PURE__ */ new Set()));
9966
9966
  }
9967
9967
  }
9968
9968
  }
@@ -10893,6 +10893,18 @@ async function readOptionalFileMetadata(options) {
10893
10893
  }
10894
10894
  }
10895
10895
 
10896
+ // ../../src/resources/common/nested-rid.ts
10897
+ function ensureNestedRidForWrite(item, path) {
10898
+ const { rid: rid2 } = item;
10899
+ if (rid2 === null || rid2 === void 0 || typeof rid2 === "string" && rid2.trim() === "") {
10900
+ item.rid = generateRid();
10901
+ return;
10902
+ }
10903
+ if (!isValidRid(rid2)) {
10904
+ throw new Error(`Invalid rid for ${path}: expected ${TORROW_OBJECT_ID_HEX_LENGTH} hexadecimal characters`);
10905
+ }
10906
+ }
10907
+
10896
10908
  // ../../src/resources/common/item-social-facet-base.ts
10897
10909
  var TorrowItemCoreFacade = class {
10898
10910
  constructor(http, basePath, socialOpts = {}) {
@@ -11639,8 +11651,13 @@ var TorrowItemFacade = class extends TorrowItemCoreFacade {
11639
11651
  signal: options?.signal
11640
11652
  });
11641
11653
  }
11642
- /** `PUT /api/v1/{domain}/{itemId}/reminders` */
11654
+ /**
11655
+ * `PUT /api/v1/{domain}/{itemId}/reminders`.
11656
+ * Отсутствующий/null/пустой `rid` создаётся на независимой копии; валидный 24-hex сохраняется.
11657
+ */
11643
11658
  updateReminders(itemId, reminders, options) {
11659
+ const payload = structuredClone(reminders);
11660
+ payload.forEach((reminder, index) => ensureNestedRidForWrite(reminder, `reminder[${index}]`));
11644
11661
  return this.http.requestJson({
11645
11662
  method: "PUT",
11646
11663
  path: `${this.basePath}/${encodePathSegment(itemId)}/reminders`,
@@ -11648,7 +11665,7 @@ var TorrowItemFacade = class extends TorrowItemCoreFacade {
11648
11665
  versionToCheck: options?.versionToCheck,
11649
11666
  isNeedAnnouncement: options?.isNeedAnnouncement
11650
11667
  },
11651
- body: reminders,
11668
+ body: payload,
11652
11669
  signal: options?.signal
11653
11670
  });
11654
11671
  }
@@ -11710,6 +11727,29 @@ function buildTimetableQuery(options) {
11710
11727
  };
11711
11728
  }
11712
11729
 
11730
+ // ../../src/resources/common/patch-rid-paths.ts
11731
+ var contactPatchRidPaths = [
11732
+ ["addresses", "*", "rid"],
11733
+ ["communications", "*", "rid"],
11734
+ ["dates", "*", "rid"]
11735
+ ];
11736
+ var calendarPatchRidPaths = [
11737
+ ["scheduleRangeExceptions", "replacedTimeRanges", "*", "rid"],
11738
+ ["scheduleRangeExceptions", "excludedTimeRanges", "*", "rid"]
11739
+ ];
11740
+ var itemSchedulePatchRidPaths = [
11741
+ ["schedule", "scheduleRanges", "*", "rid"],
11742
+ ...calendarPatchRidPaths.map((path) => ["schedule", ...path]),
11743
+ ["priceInfo", "settings", "*", "schedule", "scheduleRanges", "*", "rid"],
11744
+ ...calendarPatchRidPaths.map((path) => ["priceInfo", "settings", "*", "schedule", ...path])
11745
+ ];
11746
+ var caseActionPatchRidPaths = [["caseActionList", "*", "rid"]];
11747
+ function isPatchRidPath(path, allowed) {
11748
+ return allowed.some(
11749
+ (pattern) => pattern.length === path.length && pattern.every((part, index) => part === "*" ? typeof path[index] === "number" : part === path[index])
11750
+ );
11751
+ }
11752
+
11713
11753
  // ../../src/resources/common/item-patch.ts
11714
11754
  var commonItemPatchFields = {
11715
11755
  name: { kind: "String" /* String */, nonEmpty: true },
@@ -11742,7 +11782,7 @@ function projectItem(dto, project) {
11742
11782
  });
11743
11783
  }
11744
11784
  }
11745
- function copyValue(value, active = /* @__PURE__ */ new Set()) {
11785
+ function copyValue(value, active = /* @__PURE__ */ new Set(), path = [], ridPaths = []) {
11746
11786
  if (value === null || typeof value === "string" || typeof value === "boolean") {
11747
11787
  return value;
11748
11788
  }
@@ -11758,9 +11798,9 @@ function copyValue(value, active = /* @__PURE__ */ new Set()) {
11758
11798
  active.add(value);
11759
11799
  let result;
11760
11800
  if (Array.isArray(value)) {
11761
- result = Array.from(value, (child) => copyValue(child, active));
11801
+ result = Array.from(value, (child, index) => copyValue(child, active, [...path, index], ridPaths));
11762
11802
  } else {
11763
- const record6 = {};
11803
+ const record7 = {};
11764
11804
  for (const key of Reflect.ownKeys(value)) {
11765
11805
  if (typeof key !== "string") {
11766
11806
  throw itemPatchError("InvalidInput" /* InvalidInput */);
@@ -11769,14 +11809,18 @@ function copyValue(value, active = /* @__PURE__ */ new Set()) {
11769
11809
  if (!descriptor || !Object.hasOwn(descriptor, "value")) {
11770
11810
  throw itemPatchError("InvalidInput" /* InvalidInput */);
11771
11811
  }
11772
- Object.defineProperty(record6, key, {
11773
- value: copyValue(descriptor.value, active),
11812
+ const childPath = [...path, key];
11813
+ if (descriptor.value === void 0 && isPatchRidPath(childPath, ridPaths)) {
11814
+ continue;
11815
+ }
11816
+ Object.defineProperty(record7, key, {
11817
+ value: copyValue(descriptor.value, active, childPath, ridPaths),
11774
11818
  enumerable: true,
11775
11819
  writable: true,
11776
11820
  configurable: true
11777
11821
  });
11778
11822
  }
11779
- result = record6;
11823
+ result = record7;
11780
11824
  }
11781
11825
  active.delete(value);
11782
11826
  return result;
@@ -11887,7 +11931,7 @@ async function patchItem(http, itemId, fields, options, adapter) {
11887
11931
  if (expectedVersion !== void 0 && !isVersion(expectedVersion) || Object.hasOwn(opts, "versionToCheck") && expectedVersion === void 0 || signal !== void 0 && !isAbortSignal(signal)) {
11888
11932
  throw localError("InvalidInput" /* InvalidInput */);
11889
11933
  }
11890
- const selected = copyValue(fields);
11934
+ const selected = copyValue(fields, /* @__PURE__ */ new Set(), [], adapter.ridPaths);
11891
11935
  if (!isRecord(selected) || Object.keys(selected).length === 0) {
11892
11936
  throw localError("InvalidInput" /* InvalidInput */);
11893
11937
  }
@@ -12025,6 +12069,44 @@ async function patchItem(http, itemId, fields, options, adapter) {
12025
12069
  }
12026
12070
  }
12027
12071
 
12072
+ // ../../src/resources/common/schedule-rids.ts
12073
+ function record3(value) {
12074
+ return value !== null && typeof value === "object" && !Array.isArray(value);
12075
+ }
12076
+ function normalizeRangeList(value, path) {
12077
+ if (!Array.isArray(value)) {
12078
+ return;
12079
+ }
12080
+ value.forEach((range, index) => {
12081
+ if (record3(range)) {
12082
+ ensureNestedRidForWrite(range, `${path}[${index}]`);
12083
+ }
12084
+ });
12085
+ }
12086
+ function normalizeScheduleRidsForWrite(value, path) {
12087
+ if (!record3(value)) {
12088
+ return;
12089
+ }
12090
+ normalizeRangeList(value.scheduleRanges, `${path}.scheduleRanges`);
12091
+ const exceptions = value.scheduleRangeExceptions;
12092
+ if (record3(exceptions)) {
12093
+ normalizeRangeList(exceptions.replacedTimeRanges, `${path}.scheduleRangeExceptions.replacedTimeRanges`);
12094
+ normalizeRangeList(exceptions.excludedTimeRanges, `${path}.scheduleRangeExceptions.excludedTimeRanges`);
12095
+ }
12096
+ }
12097
+ function normalizeItemScheduleRidsForWrite(body, path) {
12098
+ normalizeScheduleRidsForWrite(body.schedule, `${path}.schedule`);
12099
+ const priceInfo = body.priceInfo;
12100
+ if (!record3(priceInfo) || !Array.isArray(priceInfo.settings)) {
12101
+ return;
12102
+ }
12103
+ priceInfo.settings.forEach((setting, index) => {
12104
+ if (record3(setting)) {
12105
+ normalizeScheduleRidsForWrite(setting.schedule, `${path}.priceInfo.settings[${index}].schedule`);
12106
+ }
12107
+ });
12108
+ }
12109
+
12028
12110
  // ../../src/resources/calendars/calendar-patch.ts
12029
12111
  function isRecord2(value) {
12030
12112
  return value !== null && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
@@ -12032,11 +12114,19 @@ function isRecord2(value) {
12032
12114
  function isCalendarPatchViewIndex(value) {
12033
12115
  return typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;
12034
12116
  }
12035
- function isTimeRange(value) {
12036
- return isRecord2(value) && Object.keys(value).every((key) => ["rid", "begin", "end", "name"].includes(key)) && isValidRid(value.rid) && value.begin instanceof Date && Number.isFinite(value.begin.getTime()) && value.end instanceof Date && Number.isFinite(value.end.getTime()) && (value.name == null || typeof value.name === "string");
12117
+ function isTimeRange(value, allowMissingRid = false) {
12118
+ const rid2 = isRecord2(value) ? value.rid : void 0;
12119
+ return isRecord2(value) && Object.keys(value).every((key) => ["rid", "begin", "end", "name"].includes(key)) && (isValidRid(rid2) || allowMissingRid && (rid2 == null || typeof rid2 === "string" && rid2.trim() === "")) && value.begin instanceof Date && Number.isFinite(value.begin.getTime()) && value.end instanceof Date && Number.isFinite(value.end.getTime()) && (value.name == null || typeof value.name === "string");
12037
12120
  }
12038
12121
  function isCalendarPatchExceptions(value) {
12039
- return isRecord2(value) && Object.keys(value).every((key) => ["replacedTimeRanges", "excludedTimeRanges"].includes(key)) && Object.values(value).every((ranges) => ranges == null || Array.isArray(ranges) && ranges.every(isTimeRange));
12122
+ return isRecord2(value) && Object.keys(value).every((key) => ["replacedTimeRanges", "excludedTimeRanges"].includes(key)) && Object.values(value).every(
12123
+ (ranges) => ranges == null || Array.isArray(ranges) && ranges.every((range) => isTimeRange(range))
12124
+ );
12125
+ }
12126
+ function isCalendarPatchInputExceptions(value) {
12127
+ return isRecord2(value) && Object.keys(value).every((key) => ["replacedTimeRanges", "excludedTimeRanges"].includes(key)) && Object.values(value).every(
12128
+ (ranges) => ranges == null || Array.isArray(ranges) && ranges.every((range) => isTimeRange(range, true))
12129
+ );
12040
12130
  }
12041
12131
  function projectCalendarPatchItem(item) {
12042
12132
  if (item.description != null && typeof item.description !== "string" || item.name != null && typeof item.name !== "string" || item.calendarViewIndex != null && !isCalendarPatchViewIndex(item.calendarViewIndex) || item.scheduleRangeExceptions != null && !isCalendarPatchExceptions(item.scheduleRangeExceptions)) {
@@ -12056,6 +12146,7 @@ function assertCalendarPatchSnapshot(item) {
12056
12146
  function createCalendarPatchAdapter() {
12057
12147
  return {
12058
12148
  operation: "CalendarsFacade.patch",
12149
+ ridPaths: calendarPatchRidPaths,
12059
12150
  basePath: "/api/v1/calendars",
12060
12151
  objectType: TorrowObjectTypeCode.Calendar,
12061
12152
  discriminator: "CalendarItem" /* CalendarItem */,
@@ -12066,7 +12157,14 @@ function createCalendarPatchAdapter() {
12066
12157
  scheduleRangeExceptions: {
12067
12158
  kind: "Object" /* Object */,
12068
12159
  nullable: true,
12069
- validate: isCalendarPatchExceptions
12160
+ validate: isCalendarPatchInputExceptions
12161
+ }
12162
+ },
12163
+ validateFields: (fields) => {
12164
+ try {
12165
+ normalizeScheduleRidsForWrite(fields, "calendar");
12166
+ } catch {
12167
+ throw itemPatchError("InvalidInput" /* InvalidInput */);
12070
12168
  }
12071
12169
  },
12072
12170
  assertSnapshot: assertCalendarPatchSnapshot,
@@ -12096,7 +12194,8 @@ var CalendarsFacade = class extends TorrowItemFacade {
12096
12194
  }
12097
12195
  /** `POST /api/v1/calendars` */
12098
12196
  create(body, options) {
12099
- const payload = applyItemCreateDefaults(body, "CalendarItem" /* CalendarItem */, options?.publicityType);
12197
+ const payload = applyItemCreateDefaults(structuredClone(body), "CalendarItem" /* CalendarItem */, options?.publicityType);
12198
+ normalizeScheduleRidsForWrite(payload, "calendar");
12100
12199
  return this.http.requestJson({
12101
12200
  method: "POST",
12102
12201
  path: BASE,
@@ -12111,6 +12210,8 @@ var CalendarsFacade = class extends TorrowItemFacade {
12111
12210
  /** `PUT /api/v1/calendars/{body.id}` */
12112
12211
  update(body, options) {
12113
12212
  const itemId = requireItemUpdateId(body, "Calendar");
12213
+ const payload = structuredClone(body);
12214
+ normalizeScheduleRidsForWrite(payload, "calendar");
12114
12215
  return this.http.requestJson({
12115
12216
  method: "PUT",
12116
12217
  path: `${BASE}/${encodePathSegment(itemId)}`,
@@ -12119,7 +12220,7 @@ var CalendarsFacade = class extends TorrowItemFacade {
12119
12220
  isNeedAnnouncement: options?.isNeedAnnouncement,
12120
12221
  securityToken: options?.securityToken
12121
12222
  },
12122
- body,
12223
+ body: payload,
12123
12224
  signal: options?.signal
12124
12225
  }).then((dto) => projectCalendarItem(dto));
12125
12226
  }
@@ -12278,7 +12379,8 @@ function validRecurring(value) {
12278
12379
  ) && ["cron", "weeklyCron"].every((key) => value[key] == null || typeof value[key] === "string");
12279
12380
  }
12280
12381
  function validRange(value, begin, end) {
12281
- return objectValue(value) && optionalDate(value[begin]) && optionalDate(value[end]) && (value.rid == null || typeof value.rid === "string") && (value.name == null || typeof value.name === "string") && validRecurring(value.recurringConditions);
12382
+ const rid2 = objectValue(value) ? value.rid : void 0;
12383
+ return objectValue(value) && optionalDate(value[begin]) && optionalDate(value[end]) && (rid2 == null || typeof rid2 === "string" && (rid2.trim() === "" || isValidRid(rid2))) && (value.name == null || typeof value.name === "string") && validRecurring(value.recurringConditions);
12282
12384
  }
12283
12385
  function isItemPatchSchedule(value) {
12284
12386
  if (!objectValue(value)) {
@@ -12347,6 +12449,18 @@ function isItemPatchObjectArray(value) {
12347
12449
  return Array.isArray(value) && value.every(isItemPatchDtoObject);
12348
12450
  }
12349
12451
 
12452
+ // ../../src/resources/common/case-action-rids.ts
12453
+ function normalizeCaseActionRidsForWrite(body, path) {
12454
+ if (!Array.isArray(body.caseActionList)) {
12455
+ return;
12456
+ }
12457
+ body.caseActionList.forEach((action, index) => {
12458
+ if (action !== null && typeof action === "object" && !Array.isArray(action)) {
12459
+ ensureNestedRidForWrite(action, `${path}.caseActionList[${index}]`);
12460
+ }
12461
+ });
12462
+ }
12463
+
12350
12464
  // ../../src/resources/cases/case-patch.ts
12351
12465
  function optionalDate2(value) {
12352
12466
  return value == null || value instanceof Date && Number.isFinite(value.getTime());
@@ -12375,6 +12489,7 @@ function checkinPermission(value) {
12375
12489
  function createCasePatchAdapter() {
12376
12490
  return {
12377
12491
  operation: "CasesFacade.patch",
12492
+ ridPaths: [...itemSchedulePatchRidPaths, ...caseActionPatchRidPaths],
12378
12493
  basePath: "/api/v1/cases",
12379
12494
  objectType: TorrowObjectTypeCode.Case,
12380
12495
  discriminator: "CaseItem" /* CaseItem */,
@@ -12414,7 +12529,15 @@ function createCasePatchAdapter() {
12414
12529
  loyaltyTransactionPropertiesList: { kind: "Array" /* Array */, nullable: true, validate: isItemPatchObjectArray },
12415
12530
  priceInfo: { kind: "Object" /* Object */, nullable: true }
12416
12531
  },
12417
- validateFields: validateItemPricePatch,
12532
+ validateFields: (fields) => {
12533
+ validateItemPricePatch(fields);
12534
+ try {
12535
+ normalizeItemScheduleRidsForWrite(fields, "case");
12536
+ normalizeCaseActionRidsForWrite(fields, "case");
12537
+ } catch {
12538
+ throw itemPatchError("InvalidInput" /* InvalidInput */);
12539
+ }
12540
+ },
12418
12541
  project: (item) => projectCaseItem(item),
12419
12542
  casRefusal: isItemPatchCasRefusal
12420
12543
  };
@@ -12512,6 +12635,9 @@ var CasesFacade = class extends TorrowItemFacade {
12512
12635
  /** `PUT /api/v1/cases/{body.id}` */
12513
12636
  update(body, options) {
12514
12637
  const itemId = requireItemUpdateId(body, "Case");
12638
+ const payload = structuredClone(body);
12639
+ normalizeItemScheduleRidsForWrite(payload, "case");
12640
+ normalizeCaseActionRidsForWrite(payload, "case");
12515
12641
  return this.http.requestJson({
12516
12642
  method: "PUT",
12517
12643
  path: `${BASE3}/${encodePathSegment(itemId)}`,
@@ -12521,13 +12647,13 @@ var CasesFacade = class extends TorrowItemFacade {
12521
12647
  isNeedAnnouncement: options?.isNeedAnnouncement,
12522
12648
  securityToken: options?.securityToken
12523
12649
  },
12524
- body,
12650
+ body: payload,
12525
12651
  signal: options?.signal
12526
12652
  }).then((dto) => projectCaseItem(dto));
12527
12653
  }
12528
12654
  withCreateDefaults(body, publicityType) {
12529
- const payload = applyItemCreateDefaults(body, "CaseItem" /* CaseItem */, publicityType);
12530
- return {
12655
+ const payload = applyItemCreateDefaults(structuredClone(body), "CaseItem" /* CaseItem */, publicityType);
12656
+ const prepared = {
12531
12657
  ...payload,
12532
12658
  caseState: payload.caseState ?? CaseStateValues.Verifying,
12533
12659
  caseType: payload.caseType ?? CaseTypeValues.Time,
@@ -12540,6 +12666,9 @@ var CasesFacade = class extends TorrowItemFacade {
12540
12666
  ]
12541
12667
  }
12542
12668
  };
12669
+ normalizeItemScheduleRidsForWrite(prepared, "case");
12670
+ normalizeCaseActionRidsForWrite(prepared, "case");
12671
+ return prepared;
12543
12672
  }
12544
12673
  /** `DELETE /api/v1/cases/{torrowId}` */
12545
12674
  async delete(torrowId, options) {
@@ -12819,12 +12948,6 @@ var CasesFacade = class extends TorrowItemFacade {
12819
12948
 
12820
12949
  // ../../src/resources/contacts/contact-structured-array-rids.ts
12821
12950
  var CONTACT_STRUCTURED_ARRAY_KEYS = ["addresses", "communications", "dates"];
12822
- function isMissingRid(rid2) {
12823
- if (rid2 === null || rid2 === void 0) {
12824
- return true;
12825
- }
12826
- return typeof rid2 === "string" && rid2.trim() === "";
12827
- }
12828
12951
  function ensureRidsOnArray(items, arrayKey) {
12829
12952
  if (!Array.isArray(items)) {
12830
12953
  return;
@@ -12834,16 +12957,7 @@ function ensureRidsOnArray(items, arrayKey) {
12834
12957
  if (item === null || item === void 0 || typeof item !== "object") {
12835
12958
  continue;
12836
12959
  }
12837
- const rid2 = item.rid;
12838
- if (isMissingRid(rid2)) {
12839
- item.rid = generateRid();
12840
- continue;
12841
- }
12842
- if (!isValidRid(rid2)) {
12843
- throw new Error(
12844
- `Invalid rid for contact.${arrayKey}[${i}]: expected ${TORROW_OBJECT_ID_HEX_LENGTH} hexadecimal characters`
12845
- );
12846
- }
12960
+ ensureNestedRidForWrite(item, `contact.${arrayKey}[${i}]`);
12847
12961
  }
12848
12962
  }
12849
12963
  function normalizeContactStructuredArrayRidsForWrite(body) {
@@ -12970,7 +13084,7 @@ var ContactPatchCommunicationState = /* @__PURE__ */ ((ContactPatchCommunication
12970
13084
  ContactPatchCommunicationState2["Checked"] = "Checked";
12971
13085
  return ContactPatchCommunicationState2;
12972
13086
  })(ContactPatchCommunicationState || {});
12973
- function record3(value) {
13087
+ function record4(value) {
12974
13088
  return value !== null && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
12975
13089
  }
12976
13090
  var text = (value) => typeof value === "string";
@@ -12979,7 +13093,7 @@ var date = (value) => value instanceof Date && Number.isFinite(value.getTime());
12979
13093
  var nullable = (validate) => (value) => value === null || validate(value);
12980
13094
  var rid = (value) => value === null || typeof value === "string" && (value.trim() === "" || isValidRid(value));
12981
13095
  function shape(value, fields) {
12982
- return record3(value) && Object.entries(value).every(([key, child]) => Object.hasOwn(fields, key) && fields[key](child));
13096
+ return record4(value) && Object.entries(value).every(([key, child]) => Object.hasOwn(fields, key) && fields[key](child));
12983
13097
  }
12984
13098
  var addressShape = {
12985
13099
  rid,
@@ -13012,7 +13126,7 @@ var memorableDateShape = {
13012
13126
  needsReminder: (value) => typeof value === "boolean",
13013
13127
  order: integer
13014
13128
  };
13015
- var file = (value) => shape(value, { id: (value2) => typeof value2 === "string" && value2.length > 0 }) && record3(value) && Object.hasOwn(value, "id");
13129
+ var file = (value) => shape(value, { id: (value2) => typeof value2 === "string" && value2.length > 0 }) && record4(value) && Object.hasOwn(value, "id");
13016
13130
  var visitCard2 = (value) => shape(value, {
13017
13131
  fields: nullable(
13018
13132
  (value2) => Array.isArray(value2) && value2.every((child) => shape(child, { number: integer, value: nullable(text), expression: nullable(text) }))
@@ -13026,7 +13140,7 @@ function comparable(value) {
13026
13140
  if (Array.isArray(value)) {
13027
13141
  return `[${value.map(comparable).join(",")}]`;
13028
13142
  }
13029
- if (record3(value)) {
13143
+ if (record4(value)) {
13030
13144
  return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${comparable(value[key])}`).join(",")}}`;
13031
13145
  }
13032
13146
  return JSON.stringify(value) ?? "undefined";
@@ -13057,6 +13171,7 @@ function createContactPatchAdapter() {
13057
13171
  }
13058
13172
  return {
13059
13173
  operation: "ContactsFacade.patch",
13174
+ ridPaths: contactPatchRidPaths,
13060
13175
  basePath: "/api/v1/contacts",
13061
13176
  objectType: TorrowObjectTypeCode.Contact,
13062
13177
  discriminator: "ContactItem" /* ContactItem */,
@@ -13108,7 +13223,7 @@ function createContactPatchAdapter() {
13108
13223
  return void 0;
13109
13224
  }
13110
13225
  if (key === "photos") {
13111
- const previousIds = Array.isArray(before) ? before.map((photo) => record3(photo) ? { id: photo.id } : photo) : before;
13226
+ const previousIds = Array.isArray(before) ? before.map((photo) => record4(photo) ? { id: photo.id } : photo) : before;
13112
13227
  return comparable(previousIds) === comparable(selected.photos);
13113
13228
  }
13114
13229
  if (key !== "addresses" && key !== "communications" && key !== "dates" && key !== "visitCard") {
@@ -13166,7 +13281,7 @@ var ContactsFacade = class extends TorrowItemFacade {
13166
13281
  }
13167
13282
  withCreateDefaults(body, publicityType) {
13168
13283
  const payload = applyItemCreateDefaults(
13169
- body,
13284
+ structuredClone(body),
13170
13285
  "ContactItem" /* ContactItem */,
13171
13286
  publicityType
13172
13287
  );
@@ -13178,7 +13293,7 @@ var ContactsFacade = class extends TorrowItemFacade {
13178
13293
  /** `PUT /api/v1/contacts/{body.id}` */
13179
13294
  update(body, options) {
13180
13295
  const itemId = requireItemUpdateId(body, "Contact");
13181
- const payload = { ...body };
13296
+ const payload = structuredClone(body);
13182
13297
  normalizeContactStructuredArrayRidsForWrite(payload);
13183
13298
  normalizeContactCommunicationsForWrite(payload);
13184
13299
  normalizeContactVisitCardFieldsForWrite(payload);
@@ -14216,11 +14331,11 @@ var providers = {
14216
14331
  strings: ["redirectBaseUrl"]
14217
14332
  }
14218
14333
  };
14219
- function record4(value) {
14334
+ function record5(value) {
14220
14335
  return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
14221
14336
  }
14222
14337
  function isResourcePaymentPatch(value) {
14223
- if (!record4(value) || Object.keys(value).some(
14338
+ if (!record5(value) || Object.keys(value).some(
14224
14339
  (key) => !["paymentProviderType", "parameters", "numeratorId", "waitForConfirmation"].includes(key)
14225
14340
  )) {
14226
14341
  return false;
@@ -14240,7 +14355,7 @@ function isResourcePaymentPatch(value) {
14240
14355
  if (value.parameters == null) {
14241
14356
  return guarded;
14242
14357
  }
14243
- if (!record4(value.parameters)) {
14358
+ if (!record5(value.parameters)) {
14244
14359
  return false;
14245
14360
  }
14246
14361
  const parameters = value.parameters;
@@ -14269,7 +14384,7 @@ function isResourcePaymentPatch(value) {
14269
14384
  });
14270
14385
  }
14271
14386
  function paymentPatchToWire(value) {
14272
- if (!record4(value) || !record4(value.parameters)) {
14387
+ if (!record5(value) || !record5(value.parameters)) {
14273
14388
  return value;
14274
14389
  }
14275
14390
  const shape2 = providers[value.paymentProviderType];
@@ -14286,7 +14401,7 @@ function equalResourcePaymentPatchField(key, before, after) {
14286
14401
  return void 0;
14287
14402
  }
14288
14403
  const expected = paymentPatchToWire(after);
14289
- if (record4(before) && record4(expected) && before.paymentProviderType === "MockPaymentProvider" /* Mock */ && expected.paymentProviderType === "MockPaymentProvider" /* Mock */ && record4(before.parameters) && record4(expected.parameters) && expected.parameters.createAfter instanceof Date && typeof before.parameters.createAfter === "string") {
14404
+ if (record5(before) && record5(expected) && before.paymentProviderType === "MockPaymentProvider" /* Mock */ && expected.paymentProviderType === "MockPaymentProvider" /* Mock */ && record5(before.parameters) && record5(expected.parameters) && expected.parameters.createAfter instanceof Date && typeof before.parameters.createAfter === "string") {
14290
14405
  const date2 = new Date(before.parameters.createAfter);
14291
14406
  if (!Number.isFinite(date2.getTime())) {
14292
14407
  return false;
@@ -14341,6 +14456,7 @@ var resourceItemPatchFields = {
14341
14456
  function createResourcePatchAdapter(project) {
14342
14457
  return {
14343
14458
  operation: "ResourcesFacade.patch",
14459
+ ridPaths: itemSchedulePatchRidPaths,
14344
14460
  basePath: "/api/v1/resources",
14345
14461
  objectType: TorrowObjectTypeCode.Resource,
14346
14462
  discriminator: "ResourceItem" /* ResourceItem */,
@@ -14349,7 +14465,14 @@ function createResourcePatchAdapter(project) {
14349
14465
  ...resourceItemPatchFields,
14350
14466
  priceInfo: { kind: "Object" /* Object */, nullable: true }
14351
14467
  },
14352
- validateFields: validateItemPricePatch,
14468
+ validateFields: (fields) => {
14469
+ validateItemPricePatch(fields);
14470
+ try {
14471
+ normalizeItemScheduleRidsForWrite(fields, "resource");
14472
+ } catch {
14473
+ throw itemPatchError("InvalidInput" /* InvalidInput */);
14474
+ }
14475
+ },
14353
14476
  prepare: prepareResourcePaymentPatch,
14354
14477
  equalField: equalResourcePaymentPatchField,
14355
14478
  assertSnapshot: assertResourcePatchSnapshot,
@@ -14403,7 +14526,9 @@ var ResourcesFacade = class extends TorrowItemFacade {
14403
14526
  };
14404
14527
  }
14405
14528
  toApiResourceItem(item) {
14406
- const { behaviorSettings, ...rest } = item;
14529
+ const copy = structuredClone(item);
14530
+ normalizeItemScheduleRidsForWrite(copy, "resource");
14531
+ const { behaviorSettings, ...rest } = copy;
14407
14532
  const apiBase = rest;
14408
14533
  const nextTags = behaviorSettings ? mergeResourceBehaviorTags(apiBase.tags, behaviorSettings) : apiBase.tags;
14409
14534
  return {
@@ -14737,6 +14862,7 @@ function checkinPermission2(value) {
14737
14862
  function createServicePatchAdapter() {
14738
14863
  return {
14739
14864
  operation: "ServicesFacade.patch",
14865
+ ridPaths: [...itemSchedulePatchRidPaths, ...caseActionPatchRidPaths],
14740
14866
  basePath: "/api/v1/services",
14741
14867
  objectType: TorrowObjectTypeCode.Service,
14742
14868
  discriminator: "ServiceItem" /* ServiceItem */,
@@ -14774,10 +14900,33 @@ function createServicePatchAdapter() {
14774
14900
  loyaltyTransactionPropertiesList: { kind: "Array" /* Array */, validate: isItemPatchObjectArray },
14775
14901
  priceInfo: { kind: "Object" /* Object */, nullable: true }
14776
14902
  },
14777
- validateFields: validateItemPricePatch,
14903
+ validateFields: (fields) => {
14904
+ validateItemPricePatch(fields);
14905
+ if (isItemPatchDtoObject(fields.priceInfo) && Array.isArray(fields.priceInfo.settings) && fields.priceInfo.settings.length === 0) {
14906
+ Object.assign(fields, { priceInfo: null });
14907
+ }
14908
+ try {
14909
+ normalizeItemScheduleRidsForWrite(fields, "service");
14910
+ normalizeCaseActionRidsForWrite(fields, "service");
14911
+ } catch {
14912
+ throw itemPatchError("InvalidInput" /* InvalidInput */);
14913
+ }
14914
+ },
14778
14915
  project: toSdkServiceItem,
14779
- prepare: (body) => {
14916
+ equalField: (key, before, after, snapshot) => {
14917
+ if (key !== "priceInfo" || after !== null) {
14918
+ return void 0;
14919
+ }
14920
+ if (snapshot.priceProperties != null) {
14921
+ return false;
14922
+ }
14923
+ return before == null || isItemPatchDtoObject(before) && Array.isArray(before.settings) && before.settings.length === 0;
14924
+ },
14925
+ prepare: (body, fields) => {
14780
14926
  const clean = omitUnusedServiceFields(body);
14927
+ if (Object.hasOwn(fields, "priceInfo")) {
14928
+ Reflect.deleteProperty(clean, "priceProperties");
14929
+ }
14781
14930
  Reflect.deleteProperty(clean, "numeratorInfo");
14782
14931
  return clean;
14783
14932
  },
@@ -14795,18 +14944,18 @@ var configs = Object.values(SERVICE_IMPLICIT_TAG_REGISTRY);
14795
14944
  function isBehaviorVersion(value) {
14796
14945
  return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 2147483647;
14797
14946
  }
14798
- function record5(value) {
14947
+ function record6(value) {
14799
14948
  return value !== null && typeof value === "object" && !Array.isArray(value);
14800
14949
  }
14801
14950
  function validateBehaviorResponse(value, serviceId) {
14802
- if (!record5(value) || value.id !== serviceId) {
14951
+ if (!record6(value) || value.id !== serviceId) {
14803
14952
  throw behaviorSettingsError("InvalidResponse" /* InvalidResponse */);
14804
14953
  }
14805
14954
  const personal = value.personalInfo;
14806
- if (record5(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
14955
+ if (record6(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
14807
14956
  throw behaviorSettingsError("AccessDenied" /* AccessDenied */);
14808
14957
  }
14809
- if (!record5(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record5(value.meta) || !isBehaviorVersion(value.meta.version)) {
14958
+ if (!record6(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record6(value.meta) || !isBehaviorVersion(value.meta.version)) {
14810
14959
  throw behaviorSettingsError("InsufficientData" /* InsufficientData */);
14811
14960
  }
14812
14961
  if (!Array.isArray(value.tags) || !value.tags.every((tag) => typeof tag === "string")) {
@@ -14935,7 +15084,7 @@ function normalizeBehaviorInput(input) {
14935
15084
  function fail() {
14936
15085
  throw behaviorSettingsError("InvalidInput" /* InvalidInput */);
14937
15086
  }
14938
- if (!record5(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) {
15087
+ if (!record6(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) {
14939
15088
  fail();
14940
15089
  }
14941
15090
  const output = {};
@@ -14965,7 +15114,7 @@ function normalizeBehaviorInput(input) {
14965
15114
  }
14966
15115
  const seen = /* @__PURE__ */ new Set();
14967
15116
  output[config.field] = value.map((entry) => {
14968
- if (!record5(entry) || Object.keys(entry).some((key) => !["index", "text", "link"].includes(key)) || typeof entry.index !== "number" || !Number.isSafeInteger(entry.index) || entry.index <= 0 || seen.has(entry.index)) {
15117
+ if (!record6(entry) || Object.keys(entry).some((key) => !["index", "text", "link"].includes(key)) || typeof entry.index !== "number" || !Number.isSafeInteger(entry.index) || entry.index <= 0 || seen.has(entry.index)) {
14969
15118
  fail();
14970
15119
  }
14971
15120
  seen.add(entry.index);
@@ -15033,7 +15182,10 @@ var ServicesFacade = class extends TorrowItemFacade {
15033
15182
  return this.generateItemId(ownerTorrowId);
15034
15183
  }
15035
15184
  toApiServiceItem(service) {
15036
- const { behaviorSettings, ...rest } = omitUnusedServiceFields(service);
15185
+ const copy = structuredClone(service);
15186
+ normalizeItemScheduleRidsForWrite(copy, "service");
15187
+ normalizeCaseActionRidsForWrite(copy, "service");
15188
+ const { behaviorSettings, ...rest } = omitUnusedServiceFields(copy);
15037
15189
  const apiBase = rest;
15038
15190
  const nextTags = behaviorSettings ? mergeServiceImplicitTags(apiBase.tags, behaviorSettings) : apiBase.tags;
15039
15191
  return {
@@ -15079,7 +15231,12 @@ var ServicesFacade = class extends TorrowItemFacade {
15079
15231
  signal: options?.signal
15080
15232
  }).then((item) => toSdkServiceItem(item));
15081
15233
  }
15082
- /** GET → максимум один полный CAS PUT; пропущенные поля сохраняются, версии персональной связи не подменяют meta.version. Retry/readback не выполняются. */
15234
+ /**
15235
+ * GET → максимум один полный CAS PUT; пропущенные поля сохраняются, версии персональной связи не подменяют meta.version.
15236
+ * priceInfo:null и priceInfo:{settings:[]} полностью очищают цену; SDK исключает старый root alias из ценового PUT.
15237
+ * Пропуск priceInfo сохраняет цены. Результат содержит ACK; независимый readback при необходимости выполняет приложение.
15238
+ * Retry/readback не выполняются SDK. Пример: examples/node/item-services/services-patch-price.ts.
15239
+ */
15083
15240
  patch(itemId, fields, options) {
15084
15241
  return patchItem(this.http, itemId, fields, options, createServicePatchAdapter());
15085
15242
  }
@@ -15484,7 +15641,7 @@ function ensureContactNameForProfileWrite(body) {
15484
15641
  }
15485
15642
  function prepareUserProfileItemForAdd(body) {
15486
15643
  const payload = applyItemCreateDefaults(
15487
- body,
15644
+ structuredClone(body),
15488
15645
  "ContactItem" /* ContactItem */,
15489
15646
  void 0
15490
15647
  );
@@ -18775,6 +18932,7 @@ export {
18775
18932
  createOrder,
18776
18933
  createServiceSessionDurationProperties,
18777
18934
  expandBookingWizardSteps,
18935
+ generateRid,
18778
18936
  generateServiceResourceGroupId,
18779
18937
  generateTorrowId,
18780
18938
  generateTorrowIdForOwner,