@torrow/sdk-client 0.11.1 → 0.12.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.
package/dist/index.js CHANGED
@@ -47,12 +47,36 @@ var TorrowSdkEffectState = /* @__PURE__ */ ((TorrowSdkEffectState2) => {
47
47
  return TorrowSdkEffectState2;
48
48
  })(TorrowSdkEffectState || {});
49
49
  var TorrowSdkErrorDomain = /* @__PURE__ */ ((TorrowSdkErrorDomain2) => {
50
+ TorrowSdkErrorDomain2["FileMetadata"] = "FileMetadata";
50
51
  TorrowSdkErrorDomain2["ItemPatch"] = "ItemPatch";
51
52
  TorrowSdkErrorDomain2["BehaviorSettings"] = "BehaviorSettings";
52
53
  TorrowSdkErrorDomain2["Otp"] = "Otp";
53
54
  TorrowSdkErrorDomain2["AuthSession"] = "AuthSession";
54
55
  return TorrowSdkErrorDomain2;
55
56
  })(TorrowSdkErrorDomain || {});
57
+ var FileMetadataErrorReason = /* @__PURE__ */ ((FileMetadataErrorReason2) => {
58
+ FileMetadataErrorReason2["ContentTypeUnavailable"] = "ContentTypeUnavailable";
59
+ FileMetadataErrorReason2["SubscriptionIsNotValid"] = "SubscriptionIsNotValid";
60
+ FileMetadataErrorReason2["FileIdUnavailable"] = "FileIdUnavailable";
61
+ FileMetadataErrorReason2["SubscriptionIdUnavailable"] = "SubscriptionIdUnavailable";
62
+ return FileMetadataErrorReason2;
63
+ })(FileMetadataErrorReason || {});
64
+ var FileMetadataOperation = /* @__PURE__ */ ((FileMetadataOperation2) => {
65
+ FileMetadataOperation2["GetInitialSubscriptionImageInfo"] = "getInitialSubscriptionImageInfo";
66
+ FileMetadataOperation2["GetImageInfo"] = "getImageInfo";
67
+ FileMetadataOperation2["GetFileInfo"] = "getFileInfo";
68
+ FileMetadataOperation2["GetPhotoInfo"] = "getPhotoInfo";
69
+ FileMetadataOperation2["GetSubscriptionImageInfo"] = "getSubscriptionImageInfo";
70
+ return FileMetadataOperation2;
71
+ })(FileMetadataOperation || {});
72
+ var FileMetadataFailureAt = /* @__PURE__ */ ((FileMetadataFailureAt2) => {
73
+ FileMetadataFailureAt2["ValidateInput"] = "ValidateInput";
74
+ FileMetadataFailureAt2["ReadItem"] = "ReadItem";
75
+ FileMetadataFailureAt2["ValidateItem"] = "ValidateItem";
76
+ FileMetadataFailureAt2["ReadMetadata"] = "ReadMetadata";
77
+ FileMetadataFailureAt2["ValidateMetadata"] = "ValidateMetadata";
78
+ return FileMetadataFailureAt2;
79
+ })(FileMetadataFailureAt || {});
56
80
  var OtpErrorReason = /* @__PURE__ */ ((OtpErrorReason2) => {
57
81
  OtpErrorReason2["InvalidChallenge"] = "InvalidChallenge";
58
82
  OtpErrorReason2["UnsupportedMethod"] = "UnsupportedMethod";
@@ -9353,6 +9377,104 @@ function applyItemCreateDefaults(body, discriminator) {
9353
9377
  return payload;
9354
9378
  }
9355
9379
 
9380
+ // ../../src/resources/common/file-metadata.ts
9381
+ function fileMetadataError(category, reason) {
9382
+ return new TorrowSdkError({ category, detail: { domain: "FileMetadata" /* FileMetadata */, reason } });
9383
+ }
9384
+ function validateFileMetadataId(value) {
9385
+ if (typeof value !== "string" || !value.trim()) {
9386
+ throw fileMetadataError("InvalidInput" /* InvalidInput */);
9387
+ }
9388
+ }
9389
+ function record2(value) {
9390
+ return value !== null && typeof value === "object" && !Array.isArray(value);
9391
+ }
9392
+ function validateFileReference(value) {
9393
+ if (!record2(value)) {
9394
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9395
+ }
9396
+ if (value.id == null) {
9397
+ throw fileMetadataError("InsufficientData" /* InsufficientData */, "FileIdUnavailable" /* FileIdUnavailable */);
9398
+ }
9399
+ if (typeof value.id !== "string" || !value.id.trim()) {
9400
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9401
+ }
9402
+ }
9403
+ function validateFullItem(value, itemId) {
9404
+ if (!record2(value) || value.id !== itemId) {
9405
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9406
+ }
9407
+ const personal = value.personalInfo;
9408
+ if (personal != null && !record2(personal)) {
9409
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9410
+ }
9411
+ const content = personal?.itemContentType;
9412
+ if (content != null && typeof content !== "string") {
9413
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9414
+ }
9415
+ if (content === "NoRights" /* NoRights */) {
9416
+ throw fileMetadataError("AccessDenied" /* AccessDenied */);
9417
+ }
9418
+ if (content !== "Full" /* Full */) {
9419
+ throw fileMetadataError(
9420
+ "InsufficientData" /* InsufficientData */,
9421
+ content === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */ ? "SubscriptionIsNotValid" /* SubscriptionIsNotValid */ : "ContentTypeUnavailable" /* ContentTypeUnavailable */
9422
+ );
9423
+ }
9424
+ }
9425
+ async function readSelectedFileMetadata(options) {
9426
+ let failureAt = "ValidateInput" /* ValidateInput */;
9427
+ try {
9428
+ validateFileMetadataId(options.itemId);
9429
+ options.validateInput?.();
9430
+ failureAt = "ReadItem" /* ReadItem */;
9431
+ const item = await options.readItem(options.itemId, options.signal);
9432
+ failureAt = "ValidateItem" /* ValidateItem */;
9433
+ validateFullItem(item, options.itemId);
9434
+ const file2 = options.selectFile(item);
9435
+ if (file2 == null) {
9436
+ return null;
9437
+ }
9438
+ validateFileReference(file2);
9439
+ return file2;
9440
+ } catch (cause) {
9441
+ const error = cause instanceof TorrowSdkError ? cause : new TorrowSdkError({ category: "Unknown" /* Unknown */, sensitive: { cause } });
9442
+ throw error.withContext({ operation: options.operation, failureAt });
9443
+ }
9444
+ }
9445
+ async function readOptionalFileMetadata(options) {
9446
+ let failureAt = "ValidateInput" /* ValidateInput */;
9447
+ try {
9448
+ validateFileMetadataId(options.itemId);
9449
+ failureAt = "ReadItem" /* ReadItem */;
9450
+ const item = await options.readItem(options.itemId, options.signal);
9451
+ failureAt = "ValidateItem" /* ValidateItem */;
9452
+ validateFullItem(item, options.itemId);
9453
+ if (!options.hasFile(item)) {
9454
+ return null;
9455
+ }
9456
+ failureAt = "ReadMetadata" /* ReadMetadata */;
9457
+ if (options.signal?.aborted) {
9458
+ throw new TorrowSdkError({
9459
+ category: "Cancelled" /* Cancelled */,
9460
+ request: "NotStarted" /* NotStarted */
9461
+ });
9462
+ }
9463
+ const metadata = await options.readMetadata();
9464
+ failureAt = "ValidateMetadata" /* ValidateMetadata */;
9465
+ if (!record2(metadata)) {
9466
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9467
+ }
9468
+ if (metadata.id != null && (typeof metadata.id !== "string" || !metadata.id.trim() || options.expectedFileId !== void 0 && metadata.id !== options.expectedFileId)) {
9469
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
9470
+ }
9471
+ return metadata;
9472
+ } catch (cause) {
9473
+ const error = cause instanceof TorrowSdkError ? cause : new TorrowSdkError({ category: "Unknown" /* Unknown */, sensitive: { cause } });
9474
+ throw error.withContext({ operation: options.operation, failureAt });
9475
+ }
9476
+ }
9477
+
9356
9478
  // ../../src/util/torrow-id.ts
9357
9479
  var TORROW_OBJECT_ID_HEX_LENGTH = 24;
9358
9480
  var OBJECT_ID_HEX_LENGTH = TORROW_OBJECT_ID_HEX_LENGTH;
@@ -9934,12 +10056,26 @@ var TorrowItemCoreFacade = class {
9934
10056
  signal: options?.signal
9935
10057
  });
9936
10058
  }
9937
- /** `GET /api/v1/{domain}/{torrowId}/image/info` */
10059
+ /** Полная карточка без аватара → null (1 GET); иначе FileInfo из image/info (2 GET). Требуется доступ к Full. */
9938
10060
  getImageInfo(torrowId, options) {
9939
- return this.http.requestJson({
9940
- method: "GET",
9941
- path: `${this.basePath}/${encodePathSegment(torrowId)}/image/info`,
9942
- signal: options?.signal
10061
+ const signal = options?.signal;
10062
+ return readOptionalFileMetadata({
10063
+ itemId: torrowId,
10064
+ operation: "getImageInfo" /* GetImageInfo */,
10065
+ signal,
10066
+ readItem: (id, readSignal) => this.readFileMetadataItem(id, readSignal),
10067
+ hasFile: (item) => {
10068
+ if (item.image == null) {
10069
+ return false;
10070
+ }
10071
+ validateFileReference(item.image);
10072
+ return true;
10073
+ },
10074
+ readMetadata: () => this.http.requestJson({
10075
+ method: "GET",
10076
+ path: `${this.basePath}/${encodePathSegment(torrowId)}/image/info`,
10077
+ signal
10078
+ })
9943
10079
  });
9944
10080
  }
9945
10081
  /** `GET /api/v1/{domain}/{torrowId}/image/puturl` */
@@ -10001,16 +10137,48 @@ var TorrowItemCoreFacade = class {
10001
10137
  signal: options?.signal
10002
10138
  });
10003
10139
  }
10004
- /** `GET /api/v1/{domain}/{torrowId}/photo/info` — только при {@link TorrowItemFacadeOptions.withPhotoEndpoints}. */
10005
- getPhotoInfo(torrowId, options) {
10006
- if (!this.socialOpts.withPhotoEndpoints) {
10007
- throw new Error("getPhotoInfo is only supported when withPhotoEndpoints is true (contacts)");
10140
+ /** Читает выбранную фотографию Contact: Full-карточка и, при наличии связи, metadata GET. Отсутствие связи — null. */
10141
+ async getPhotoInfo(torrowId, options) {
10142
+ const photoId = options?.photoId;
10143
+ const signal = options?.signal;
10144
+ try {
10145
+ if (!this.socialOpts.withPhotoEndpoints) {
10146
+ throw fileMetadataError("UnsupportedOperation" /* UnsupportedOperation */);
10147
+ }
10148
+ validateFileMetadataId(photoId);
10149
+ } catch (cause) {
10150
+ if (cause instanceof TorrowSdkError) {
10151
+ throw cause.withContext({
10152
+ operation: "getPhotoInfo" /* GetPhotoInfo */,
10153
+ failureAt: "ValidateInput" /* ValidateInput */
10154
+ });
10155
+ }
10156
+ throw cause;
10008
10157
  }
10009
- return this.http.requestJson({
10010
- method: "GET",
10011
- path: `${this.basePath}/${encodePathSegment(torrowId)}/photo/info`,
10012
- query: { photoId: options?.photoId },
10013
- signal: options?.signal
10158
+ return readOptionalFileMetadata({
10159
+ itemId: torrowId,
10160
+ operation: "getPhotoInfo" /* GetPhotoInfo */,
10161
+ signal,
10162
+ readItem: (id, itemSignal) => this.readFileMetadataItem(id, itemSignal),
10163
+ hasFile: (item) => {
10164
+ if (item.photos == null) {
10165
+ return false;
10166
+ }
10167
+ if (!Array.isArray(item.photos)) {
10168
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
10169
+ }
10170
+ for (const photo of item.photos) {
10171
+ validateFileReference(photo);
10172
+ }
10173
+ return item.photos.some((photo) => photo.id === photoId);
10174
+ },
10175
+ expectedFileId: photoId,
10176
+ readMetadata: () => this.http.requestJson({
10177
+ method: "GET",
10178
+ path: `${this.basePath}/${encodePathSegment(torrowId)}/photo/info`,
10179
+ query: { photoId },
10180
+ signal
10181
+ })
10014
10182
  });
10015
10183
  }
10016
10184
  /** `GET /api/v1/{domain}/{torrowId}/photo/puturl` — только при {@link TorrowItemFacadeOptions.withPhotoEndpoints}. */
@@ -10263,7 +10431,7 @@ function copyValue(value, active = /* @__PURE__ */ new Set()) {
10263
10431
  if (Array.isArray(value)) {
10264
10432
  result = Array.from(value, (child) => copyValue(child, active));
10265
10433
  } else {
10266
- const record5 = {};
10434
+ const record6 = {};
10267
10435
  for (const key of Reflect.ownKeys(value)) {
10268
10436
  if (typeof key !== "string") {
10269
10437
  throw itemPatchError("InvalidInput" /* InvalidInput */);
@@ -10272,14 +10440,14 @@ function copyValue(value, active = /* @__PURE__ */ new Set()) {
10272
10440
  if (!descriptor || !Object.hasOwn(descriptor, "value")) {
10273
10441
  throw itemPatchError("InvalidInput" /* InvalidInput */);
10274
10442
  }
10275
- Object.defineProperty(record5, key, {
10443
+ Object.defineProperty(record6, key, {
10276
10444
  value: copyValue(descriptor.value, active),
10277
10445
  enumerable: true,
10278
10446
  writable: true,
10279
10447
  configurable: true
10280
10448
  });
10281
10449
  }
10282
- result = record5;
10450
+ result = record6;
10283
10451
  }
10284
10452
  active.delete(value);
10285
10453
  return result;
@@ -10582,6 +10750,10 @@ function createCalendarPatchAdapter() {
10582
10750
  var BASE = "/api/v1/calendars";
10583
10751
  var CalendarsFacade = class extends TorrowItemFacade {
10584
10752
  itemObjectTypeCode = TorrowObjectTypeCode.Calendar;
10753
+ /** Чтение полной карточки для метаданных без дочерних данных. */
10754
+ readFileMetadataItem(id, signal) {
10755
+ return this.getById(id, { includeChildItems: false, signal });
10756
+ }
10585
10757
  constructor(http) {
10586
10758
  super(http, BASE, { imagePutUrlSecurityToken: false, withPhotoEndpoints: false });
10587
10759
  }
@@ -10950,6 +11122,10 @@ function cancelCaseParticipation(http, torrowId, body, options) {
10950
11122
  var BASE3 = "/api/v1/cases";
10951
11123
  var CasesFacade = class extends TorrowItemFacade {
10952
11124
  itemObjectTypeCode = TorrowObjectTypeCode.Case;
11125
+ /** Чтение полной карточки для метаданных без дочерних данных. */
11126
+ readFileMetadataItem(id, signal) {
11127
+ return this.getById(id, { includeChildTypes: false, signal });
11128
+ }
10953
11129
  constructor(http) {
10954
11130
  super(http, BASE3);
10955
11131
  }
@@ -11465,7 +11641,7 @@ var ContactPatchCommunicationState = /* @__PURE__ */ ((ContactPatchCommunication
11465
11641
  ContactPatchCommunicationState2["Checked"] = "Checked";
11466
11642
  return ContactPatchCommunicationState2;
11467
11643
  })(ContactPatchCommunicationState || {});
11468
- function record2(value) {
11644
+ function record3(value) {
11469
11645
  return value !== null && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
11470
11646
  }
11471
11647
  var text = (value) => typeof value === "string";
@@ -11474,7 +11650,7 @@ var date = (value) => value instanceof Date && Number.isFinite(value.getTime());
11474
11650
  var nullable = (validate) => (value) => value === null || validate(value);
11475
11651
  var rid = (value) => value === null || typeof value === "string" && (value.trim() === "" || isValidRid(value));
11476
11652
  function shape(value, fields) {
11477
- return record2(value) && Object.entries(value).every(([key, child]) => Object.hasOwn(fields, key) && fields[key](child));
11653
+ return record3(value) && Object.entries(value).every(([key, child]) => Object.hasOwn(fields, key) && fields[key](child));
11478
11654
  }
11479
11655
  var addressShape = {
11480
11656
  rid,
@@ -11507,7 +11683,7 @@ var memorableDateShape = {
11507
11683
  needsReminder: (value) => typeof value === "boolean",
11508
11684
  order: integer
11509
11685
  };
11510
- var file = (value) => shape(value, { id: (value2) => typeof value2 === "string" && value2.length > 0 }) && record2(value) && Object.hasOwn(value, "id");
11686
+ var file = (value) => shape(value, { id: (value2) => typeof value2 === "string" && value2.length > 0 }) && record3(value) && Object.hasOwn(value, "id");
11511
11687
  var visitCard2 = (value) => shape(value, {
11512
11688
  fields: nullable(
11513
11689
  (value2) => Array.isArray(value2) && value2.every((child) => shape(child, { number: integer, value: nullable(text), expression: nullable(text) }))
@@ -11521,7 +11697,7 @@ function comparable(value) {
11521
11697
  if (Array.isArray(value)) {
11522
11698
  return `[${value.map(comparable).join(",")}]`;
11523
11699
  }
11524
- if (record2(value)) {
11700
+ if (record3(value)) {
11525
11701
  return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${comparable(value[key])}`).join(",")}}`;
11526
11702
  }
11527
11703
  return JSON.stringify(value) ?? "undefined";
@@ -11603,7 +11779,7 @@ function createContactPatchAdapter() {
11603
11779
  return void 0;
11604
11780
  }
11605
11781
  if (key === "photos") {
11606
- const previousIds = Array.isArray(before) ? before.map((photo) => record2(photo) ? { id: photo.id } : photo) : before;
11782
+ const previousIds = Array.isArray(before) ? before.map((photo) => record3(photo) ? { id: photo.id } : photo) : before;
11607
11783
  return comparable(previousIds) === comparable(selected.photos);
11608
11784
  }
11609
11785
  if (key !== "addresses" && key !== "communications" && key !== "dates" && key !== "visitCard") {
@@ -11627,6 +11803,10 @@ var CONTACT_SOCIAL_OPTS = {
11627
11803
  };
11628
11804
  var ContactsFacade = class extends TorrowItemFacade {
11629
11805
  itemObjectTypeCode = TorrowObjectTypeCode.Contact;
11806
+ /** Чтение полной карточки для метаданных без дочерних данных. */
11807
+ readFileMetadataItem(id, signal) {
11808
+ return this.getById(id, { includeChildTypes: false, signal });
11809
+ }
11630
11810
  constructor(http) {
11631
11811
  super(http, BASE4, CONTACT_SOCIAL_OPTS);
11632
11812
  }
@@ -11818,6 +11998,10 @@ function createContextPatchAdapter() {
11818
11998
  var BASE5 = "/api/v1/contexts";
11819
11999
  var ContextsFacade = class extends TorrowItemFacade {
11820
12000
  itemObjectTypeCode = TorrowObjectTypeCode.Context;
12001
+ /** Чтение полной карточки для метаданных без дочерних данных. */
12002
+ readFileMetadataItem(id, signal) {
12003
+ return this.getById(id, { includeChildTypes: false, signal });
12004
+ }
11821
12005
  constructor(http) {
11822
12006
  super(http, BASE5, { imagePutUrlSecurityToken: false, withPhotoEndpoints: false });
11823
12007
  }
@@ -11976,6 +12160,10 @@ var BASE6 = "/api/v1/notes";
11976
12160
  var DEFAULT_NOTE_NAME = "Untitled note";
11977
12161
  var NotesFacade = class extends TorrowItemFacade {
11978
12162
  itemObjectTypeCode = TorrowObjectTypeCode.Note;
12163
+ /** Чтение полной карточки для метаданных без дочерних данных. */
12164
+ readFileMetadataItem(id, signal) {
12165
+ return this.getById(id, { includeChildTypes: false, signal });
12166
+ }
11979
12167
  constructor(http) {
11980
12168
  super(http, BASE6, { imagePutUrlSecurityToken: false, withPhotoEndpoints: false });
11981
12169
  }
@@ -12058,13 +12246,50 @@ var NotesFacade = class extends TorrowItemFacade {
12058
12246
  signal
12059
12247
  });
12060
12248
  }
12061
- /** `GET /api/v1/notes/{torrowId}/file/info` */
12062
- getFileInfo(torrowId, fileId, options) {
12063
- return this.http.requestJson({
12064
- method: "GET",
12065
- path: `${BASE6}/${encodePathSegment(torrowId)}/file/info`,
12066
- query: { fileId },
12067
- signal: options?.signal
12249
+ /**
12250
+ * Читает полную заметку и метаданные выбранного вложения: один GET при отсутствии связи, два при наличии.
12251
+ * @param torrowId ID заметки без преобразований; доступная карточка Full обязательна.
12252
+ * @param fileId Обязательный ID вложения из files; аватар и фотографии не участвуют в выборе.
12253
+ * @param options.signal Общая отмена чтения карточки и метаданных.
12254
+ * @returns Метаданные либо null, если выбранное вложение отсутствует в полной карточке.
12255
+ */
12256
+ async getFileInfo(torrowId, fileId, options) {
12257
+ const signal = options?.signal;
12258
+ try {
12259
+ validateFileMetadataId(fileId);
12260
+ } catch (error) {
12261
+ if (error instanceof TorrowSdkError) {
12262
+ throw error.withContext({
12263
+ operation: "getFileInfo" /* GetFileInfo */,
12264
+ failureAt: "ValidateInput" /* ValidateInput */
12265
+ });
12266
+ }
12267
+ throw error;
12268
+ }
12269
+ return readOptionalFileMetadata({
12270
+ itemId: torrowId,
12271
+ operation: "getFileInfo" /* GetFileInfo */,
12272
+ signal,
12273
+ readItem: (id, readSignal) => this.readFileMetadataItem(id, readSignal),
12274
+ hasFile: (item) => {
12275
+ if (item.files == null) {
12276
+ return false;
12277
+ }
12278
+ if (!Array.isArray(item.files)) {
12279
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
12280
+ }
12281
+ for (const file2 of item.files) {
12282
+ validateFileReference(file2);
12283
+ }
12284
+ return item.files.some((file2) => file2.id === fileId);
12285
+ },
12286
+ readMetadata: () => this.http.requestJson({
12287
+ method: "GET",
12288
+ path: `${BASE6}/${encodePathSegment(torrowId)}/file/info`,
12289
+ query: { fileId },
12290
+ signal
12291
+ }),
12292
+ expectedFileId: fileId
12068
12293
  });
12069
12294
  }
12070
12295
  /** `GET /api/v1/notes/{torrowId}/file/puturl` — URL для загрузки файла (presigned). */
@@ -12746,11 +12971,11 @@ var providers = {
12746
12971
  strings: ["redirectBaseUrl"]
12747
12972
  }
12748
12973
  };
12749
- function record3(value) {
12974
+ function record4(value) {
12750
12975
  return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
12751
12976
  }
12752
12977
  function isResourcePaymentPatch(value) {
12753
- if (!record3(value) || Object.keys(value).some(
12978
+ if (!record4(value) || Object.keys(value).some(
12754
12979
  (key) => !["paymentProviderType", "parameters", "numeratorId", "waitForConfirmation"].includes(key)
12755
12980
  )) {
12756
12981
  return false;
@@ -12770,7 +12995,7 @@ function isResourcePaymentPatch(value) {
12770
12995
  if (value.parameters == null) {
12771
12996
  return guarded;
12772
12997
  }
12773
- if (!record3(value.parameters)) {
12998
+ if (!record4(value.parameters)) {
12774
12999
  return false;
12775
13000
  }
12776
13001
  const parameters = value.parameters;
@@ -12799,7 +13024,7 @@ function isResourcePaymentPatch(value) {
12799
13024
  });
12800
13025
  }
12801
13026
  function paymentPatchToWire(value) {
12802
- if (!record3(value) || !record3(value.parameters)) {
13027
+ if (!record4(value) || !record4(value.parameters)) {
12803
13028
  return value;
12804
13029
  }
12805
13030
  const shape2 = providers[value.paymentProviderType];
@@ -12816,7 +13041,7 @@ function equalResourcePaymentPatchField(key, before, after) {
12816
13041
  return void 0;
12817
13042
  }
12818
13043
  const expected = paymentPatchToWire(after);
12819
- if (record3(before) && record3(expected) && before.paymentProviderType === "MockPaymentProvider" /* Mock */ && expected.paymentProviderType === "MockPaymentProvider" /* Mock */ && record3(before.parameters) && record3(expected.parameters) && expected.parameters.createAfter instanceof Date && typeof before.parameters.createAfter === "string") {
13044
+ 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") {
12820
13045
  const date2 = new Date(before.parameters.createAfter);
12821
13046
  if (!Number.isFinite(date2.getTime())) {
12822
13047
  return false;
@@ -12893,6 +13118,10 @@ function createResourcePatchAdapter(project) {
12893
13118
  var BASE7 = "/api/v1/resources";
12894
13119
  var ResourcesFacade = class extends TorrowItemFacade {
12895
13120
  itemObjectTypeCode = TorrowObjectTypeCode.Resource;
13121
+ /** Чтение полной карточки для метаданных без дочерних данных. */
13122
+ readFileMetadataItem(id, signal) {
13123
+ return this.getById(id, { includeChildTypes: false, isNeedItem: true, isNeedParentResource: false, signal });
13124
+ }
12896
13125
  constructor(http) {
12897
13126
  super(http, BASE7, { imagePutUrlSecurityToken: false, withPhotoEndpoints: false });
12898
13127
  }
@@ -12915,6 +13144,9 @@ var ResourcesFacade = class extends TorrowItemFacade {
12915
13144
  return super.getByUniqueName(uniqueName, options).then((item) => this.toSdkResourceItem(item));
12916
13145
  }
12917
13146
  toSdkResourceItem(item) {
13147
+ if (item === null || typeof item !== "object" || Array.isArray(item)) {
13148
+ throw new TorrowSdkError({ category: "InvalidResponse" /* InvalidResponse */ });
13149
+ }
12918
13150
  return {
12919
13151
  ...item,
12920
13152
  behaviorSettings: parseResourceBehaviorSettings(item.tags)
@@ -13179,6 +13411,9 @@ function projectItemViews(domain, views) {
13179
13411
  // ../../src/resources/services/service-requests.ts
13180
13412
  var BASE8 = "/api/v1/services";
13181
13413
  function toSdkServiceItem(service) {
13414
+ if (service === null || typeof service !== "object" || Array.isArray(service)) {
13415
+ throw new TorrowSdkError({ category: "InvalidResponse" /* InvalidResponse */ });
13416
+ }
13182
13417
  return {
13183
13418
  ...omitUnusedServiceFields(service),
13184
13419
  behaviorSettings: parseServiceImplicitTagParams(service.tags)
@@ -13289,18 +13524,18 @@ var configs = Object.values(SERVICE_IMPLICIT_TAG_REGISTRY);
13289
13524
  function isBehaviorVersion(value) {
13290
13525
  return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 2147483647;
13291
13526
  }
13292
- function record4(value) {
13527
+ function record5(value) {
13293
13528
  return value !== null && typeof value === "object" && !Array.isArray(value);
13294
13529
  }
13295
13530
  function validateBehaviorResponse(value, serviceId) {
13296
- if (!record4(value) || value.id !== serviceId) {
13531
+ if (!record5(value) || value.id !== serviceId) {
13297
13532
  throw behaviorSettingsError("InvalidResponse" /* InvalidResponse */);
13298
13533
  }
13299
13534
  const personal = value.personalInfo;
13300
- if (record4(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
13535
+ if (record5(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
13301
13536
  throw behaviorSettingsError("AccessDenied" /* AccessDenied */);
13302
13537
  }
13303
- if (!record4(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record4(value.meta) || !isBehaviorVersion(value.meta.version)) {
13538
+ if (!record5(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record5(value.meta) || !isBehaviorVersion(value.meta.version)) {
13304
13539
  throw behaviorSettingsError("InsufficientData" /* InsufficientData */);
13305
13540
  }
13306
13541
  if (!Array.isArray(value.tags) || !value.tags.every((tag) => typeof tag === "string")) {
@@ -13429,7 +13664,7 @@ function normalizeBehaviorInput(input) {
13429
13664
  function fail() {
13430
13665
  throw behaviorSettingsError("InvalidInput" /* InvalidInput */);
13431
13666
  }
13432
- if (!record4(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) {
13667
+ if (!record5(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) {
13433
13668
  fail();
13434
13669
  }
13435
13670
  const output = {};
@@ -13459,7 +13694,7 @@ function normalizeBehaviorInput(input) {
13459
13694
  }
13460
13695
  const seen = /* @__PURE__ */ new Set();
13461
13696
  output[config.field] = value.map((entry) => {
13462
- if (!record4(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)) {
13697
+ 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)) {
13463
13698
  fail();
13464
13699
  }
13465
13700
  seen.add(entry.index);
@@ -13515,6 +13750,10 @@ function mergeBehaviorSettings(tags, settings, mergeParameters) {
13515
13750
  var BASE9 = "/api/v1/services";
13516
13751
  var ServicesFacade = class extends TorrowItemFacade {
13517
13752
  itemObjectTypeCode = TorrowObjectTypeCode.Service;
13753
+ /** Чтение полной карточки для метаданных без дочерних данных. */
13754
+ readFileMetadataItem(id, signal) {
13755
+ return this.getById(id, { includeChildTypes: false, signal });
13756
+ }
13518
13757
  constructor(http) {
13519
13758
  super(http, BASE9, { imagePutUrlSecurityToken: false, withPhotoEndpoints: false });
13520
13759
  }
@@ -14744,9 +14983,36 @@ function createLoyaltySystemPatchAdapter() {
14744
14983
  var BASE17 = "/api/v1/loyaltysystems";
14745
14984
  var LoyaltySystemsFacade = class extends TorrowItemCoreFacade {
14746
14985
  itemObjectTypeCode = TorrowObjectTypeCode.LoyaltySystem;
14986
+ /** Чтение полной карточки для метаданных без дочерних данных. */
14987
+ readFileMetadataItem(id, signal) {
14988
+ return this.getById(id, { includeChildItems: false, signal });
14989
+ }
14747
14990
  constructor(http) {
14748
14991
  super(http, BASE17);
14749
14992
  }
14993
+ /**
14994
+ * Изображение начальной подписки из одного GET Full-программы; null означает отсутствие.
14995
+ * Основной аватар не участвует в выборе; url/refreshUrl не вызываются и не исправляются.
14996
+ */
14997
+ getInitialSubscriptionImageInfo(torrowId, options) {
14998
+ const signal = options?.signal;
14999
+ return readSelectedFileMetadata({
15000
+ itemId: torrowId,
15001
+ operation: "getInitialSubscriptionImageInfo" /* GetInitialSubscriptionImageInfo */,
15002
+ signal,
15003
+ readItem: (id, originalSignal) => this.getById(id, { includeChildItems: false, signal: originalSignal }),
15004
+ selectFile: (item) => {
15005
+ const initial = item.initialSubscription;
15006
+ if (initial == null) {
15007
+ return null;
15008
+ }
15009
+ if (typeof initial !== "object" || Array.isArray(initial)) {
15010
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
15011
+ }
15012
+ return initial.image;
15013
+ }
15014
+ });
15015
+ }
14750
15016
  /** Изменяет выбранные настройки через полный GET и один CAS PUT; пропуск сохраняет поля. */
14751
15017
  patch(itemId, fields, options) {
14752
15018
  return patchItem(
@@ -14886,9 +15152,72 @@ var BASE18 = "/api/v1/loyaltycards";
14886
15152
  var LOYALTY_CARD_SOCIAL_OPTS = { withGroupListEndpoint: false };
14887
15153
  var LoyaltyCardsFacade = class extends TorrowItemCoreFacade {
14888
15154
  itemObjectTypeCode = TorrowObjectTypeCode.LoyaltyCard;
15155
+ /** Чтение полной карточки для метаданных без дочерних данных. */
15156
+ readFileMetadataItem(id, signal) {
15157
+ return this.getById(id, { includeChildItems: false, includeBalance: false, signal });
15158
+ }
14889
15159
  constructor(http) {
14890
15160
  super(http, BASE18, LOYALTY_CARD_SOCIAL_OPTS);
14891
15161
  }
15162
+ /**
15163
+ * Отображаемый аватар из свежей Full-карточки за один GET; отсутствие → null.
15164
+ * Сервер уже применил наследование изображения программы. image/info читает собственный файл карты,
15165
+ * поэтому не используется. Для обновления URL повторить getter; refreshUrl не вызывается.
15166
+ */
15167
+ getImageInfo(torrowId, options) {
15168
+ const signal = options?.signal;
15169
+ return readSelectedFileMetadata({
15170
+ itemId: torrowId,
15171
+ operation: "getImageInfo" /* GetImageInfo */,
15172
+ signal,
15173
+ readItem: (id, readSignal) => this.readFileMetadataItem(id, readSignal),
15174
+ selectFile: (item) => item.image
15175
+ });
15176
+ }
15177
+ /**
15178
+ * Изображение выбранной подписки из одного GET Full-карты; отсутствие → null.
15179
+ * @param torrowId ID карты без преобразований.
15180
+ * @param subscriptionId Обязательный ID подписки, не ID файла и не аватара карты.
15181
+ * @param options Отмена чтения; URL и refreshUrl не запрашиваются автоматически.
15182
+ * @returns FileInfo из свежего снимка либо null; доступность байтов отдельно не проверяется.
15183
+ */
15184
+ getSubscriptionImageInfo(torrowId, subscriptionId, options) {
15185
+ const signal = options?.signal;
15186
+ return readSelectedFileMetadata({
15187
+ itemId: torrowId,
15188
+ operation: "getSubscriptionImageInfo" /* GetSubscriptionImageInfo */,
15189
+ signal,
15190
+ validateInput: () => validateFileMetadataId(subscriptionId),
15191
+ readItem: (id, readSignal) => this.readFileMetadataItem(id, readSignal),
15192
+ selectFile: (item) => {
15193
+ const subscriptions = item.subscriptions;
15194
+ if (subscriptions == null) {
15195
+ return null;
15196
+ }
15197
+ if (!Array.isArray(subscriptions)) {
15198
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
15199
+ }
15200
+ const ids = /* @__PURE__ */ new Set();
15201
+ for (const subscription of subscriptions) {
15202
+ if (subscription === null || typeof subscription !== "object" || Array.isArray(subscription)) {
15203
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
15204
+ }
15205
+ const id = subscription.subscriptionId;
15206
+ if (id == null) {
15207
+ throw fileMetadataError(
15208
+ "InsufficientData" /* InsufficientData */,
15209
+ "SubscriptionIdUnavailable" /* SubscriptionIdUnavailable */
15210
+ );
15211
+ }
15212
+ if (typeof id !== "string" || !id.trim() || ids.has(id)) {
15213
+ throw fileMetadataError("InvalidResponse" /* InvalidResponse */);
15214
+ }
15215
+ ids.add(id);
15216
+ }
15217
+ return subscriptions.find((subscription) => subscription.subscriptionId === subscriptionId)?.image;
15218
+ }
15219
+ });
15220
+ }
14892
15221
  /** Id карты лояльности до `create` / presigned upload. */
14893
15222
  generateLoyaltyCardId(ownerTorrowId) {
14894
15223
  return this.generateItemId(ownerTorrowId);
@@ -17077,6 +17406,9 @@ export {
17077
17406
  Discriminator,
17078
17407
  ExportImportFacade,
17079
17408
  ExternalAuthsFacade,
17409
+ FileMetadataErrorReason,
17410
+ FileMetadataFailureAt,
17411
+ FileMetadataOperation,
17080
17412
  GenderValues,
17081
17413
  HttpClient,
17082
17414
  IdGeneratorFacade,