itd-api 0.8.0 → 0.9.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.
Files changed (80) hide show
  1. package/README.md +63 -18
  2. package/dist/events/index.cjs +3 -3
  3. package/dist/events/index.d.cts +2 -2
  4. package/dist/events/index.d.ts +2 -2
  5. package/dist/events/index.js +3 -3
  6. package/dist/index.cjs +26 -13
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +9 -6
  9. package/dist/index.d.ts +9 -6
  10. package/dist/index.js +13 -8
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +5 -4
  13. package/dist/node/index.cjs.map +1 -1
  14. package/dist/node/index.d.cts +2 -2
  15. package/dist/node/index.d.ts +2 -2
  16. package/dist/node/index.js +4 -3
  17. package/dist/node/index.js.map +1 -1
  18. package/dist/rest/index.cjs +16 -4
  19. package/dist/rest/index.cjs.map +1 -1
  20. package/dist/rest/index.d.cts +5 -3
  21. package/dist/rest/index.d.ts +5 -3
  22. package/dist/rest/index.js +9 -5
  23. package/dist/rest/index.js.map +1 -1
  24. package/dist/shared/{events-TfhKh26b.js → events-C5wnTXPT.js} +3 -3
  25. package/dist/shared/{events-TfhKh26b.js.map → events-C5wnTXPT.js.map} +1 -1
  26. package/dist/shared/{events-QyhQZrnC.d.ts → events-CqtkP65d.d.ts} +2 -2
  27. package/dist/shared/{events-Br2r7coi.d.cts → events-DGAWlCaI.d.cts} +2 -2
  28. package/dist/shared/{events-iTteVsd_.cjs → events-FZfnEez0.cjs} +3 -3
  29. package/dist/shared/{events-iTteVsd_.cjs.map → events-FZfnEez0.cjs.map} +1 -1
  30. package/dist/shared/{storage-BLmXmzKF.cjs → key-value-store-B5GYVEYZ.cjs} +1 -85
  31. package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +1 -0
  32. package/dist/shared/{storage-CCxn0Kkv.js → key-value-store-Bt2PSMxY.js} +2 -68
  33. package/dist/shared/key-value-store-Bt2PSMxY.js.map +1 -0
  34. package/dist/shared/key-value-store-COZaNHZS.d.cts +69 -0
  35. package/dist/shared/key-value-store-COZaNHZS.d.ts +69 -0
  36. package/dist/shared/{multi-storage-DccjD7Ww.d.ts → multi-storage-BEL7tcKn.d.cts} +3 -2
  37. package/dist/shared/{multi-storage-CCUgkqvI.cjs → multi-storage-CDKLa956.cjs} +8 -7
  38. package/dist/shared/{multi-storage-CCUgkqvI.cjs.map → multi-storage-CDKLa956.cjs.map} +1 -1
  39. package/dist/shared/{multi-storage-CjAPB5Kq.d.cts → multi-storage-LkljOSzA.d.ts} +3 -2
  40. package/dist/shared/{multi-storage-1AEZTczk.js → multi-storage-SoW05uzO.js} +4 -3
  41. package/dist/shared/{multi-storage-1AEZTczk.js.map → multi-storage-SoW05uzO.js.map} +1 -1
  42. package/dist/shared/{options-BUfoHE9G.cjs → options-DOJYtoti.cjs} +2 -2
  43. package/dist/shared/{options-BUfoHE9G.cjs.map → options-DOJYtoti.cjs.map} +1 -1
  44. package/dist/shared/{options-BNP633A5.js → options-DhgGg7Ms.js} +2 -2
  45. package/dist/shared/{options-BNP633A5.js.map → options-DhgGg7Ms.js.map} +1 -1
  46. package/dist/shared/{redact-DB9EMGJx.cjs → redact-BP00URmQ.cjs} +15 -4
  47. package/dist/shared/{redact-DB9EMGJx.cjs.map → redact-BP00URmQ.cjs.map} +1 -1
  48. package/dist/shared/{redact-FNK29Fv-.js → redact-Ba5iSVYZ.js} +15 -4
  49. package/dist/shared/{redact-FNK29Fv-.js.map → redact-Ba5iSVYZ.js.map} +1 -1
  50. package/dist/shared/{render-DVB7T8pm.d.ts → render-B4qis7Sb.d.ts} +348 -3
  51. package/dist/shared/{render-BszcKF7S.d.cts → render-DDwy2Ame.d.cts} +348 -3
  52. package/dist/shared/{render-DNTESBSl.cjs → render-Dqi8Owqk.cjs} +457 -4
  53. package/dist/shared/render-Dqi8Owqk.cjs.map +1 -0
  54. package/dist/shared/{render-CiL1VS0b.js → render-hiWFh2s4.js} +411 -6
  55. package/dist/shared/render-hiWFh2s4.js.map +1 -0
  56. package/dist/shared/storage-BQrtKon9.d.cts +86 -0
  57. package/dist/shared/storage-CTRGT5wF.d.ts +86 -0
  58. package/dist/shared/storage-CfHKzVHf.js +71 -0
  59. package/dist/shared/storage-CfHKzVHf.js.map +1 -0
  60. package/dist/shared/storage-QNVxzpDB.cjs +88 -0
  61. package/dist/shared/storage-QNVxzpDB.cjs.map +1 -0
  62. package/dist/shared/{url-CFN1sT9S.cjs → url-Bsb3xE5U.cjs} +83 -4
  63. package/dist/shared/{url-CFN1sT9S.cjs.map → url-Bsb3xE5U.cjs.map} +1 -1
  64. package/dist/shared/{url-B3ocFlHj.js → url-DP33mp3s.js} +78 -5
  65. package/dist/shared/{url-B3ocFlHj.js.map → url-DP33mp3s.js.map} +1 -1
  66. package/dist/shared/{url-Be9jlWRv.d.ts → url-XBsMdAcv.d.cts} +75 -2
  67. package/dist/shared/{url-Be9jlWRv.d.cts → url-XBsMdAcv.d.ts} +75 -2
  68. package/dist/web/index.cjs +4 -3
  69. package/dist/web/index.cjs.map +1 -1
  70. package/dist/web/index.d.cts +1 -1
  71. package/dist/web/index.d.ts +1 -1
  72. package/dist/web/index.js +2 -1
  73. package/dist/web/index.js.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/shared/render-CiL1VS0b.js.map +0 -1
  76. package/dist/shared/render-DNTESBSl.cjs.map +0 -1
  77. package/dist/shared/storage-BLmXmzKF.cjs.map +0 -1
  78. package/dist/shared/storage-CCxn0Kkv.js.map +0 -1
  79. package/dist/shared/storage-C_eICCep.d.cts +0 -152
  80. package/dist/shared/storage-C_eICCep.d.ts +0 -152
@@ -1,7 +1,8 @@
1
- import { B as isRecord, C as ReportReason, E as SpanType, G as pickString, H as pickBoolean, J as identityResult, K as RetrySafety, M as defineBuiltInOperation, U as pickNumber, V as pickArray, W as pickObject, Y as mergeService, c as normalizeNotification, et as DEFAULT_STATUS_BASE_URL, o as passthroughOperation, q as defineOperation, s as voidOperation, st as createDeadline, tt as STATUS_SERVICE, w as ReportTargetType, y as InteractionType } from "./url-B3ocFlHj.js";
2
- import { _ as ItdStateError, a as ItdConfigError, l as ItdFileError, s as ItdError, t as ItdAbortError, u as ItdFileErrorReason } from "./errors-GI10kZxk.js";
3
- import { a as redactUrl, b as isFile, d as encodePathSegment, r as redactErrorCause, v as createDeviceId, y as isBlob } from "./redact-FNK29Fv-.js";
4
- import { a as fileTooLarge, c as FileTransferMode, i as isReadableByteStream, n as boundedFileStream, o as optionalBytes, r as isBoundedFileStream, s as DEFAULT_URL_FILE_MAX_BYTES, t as resolveFileStreamOptions } from "./options-BNP633A5.js";
1
+ import { B as isRecord, C as ReportReason, E as SpanType, G as pickString, H as pickBoolean, J as identityResult, K as RetrySafety, M as defineBuiltInOperation, U as pickNumber, V as pickArray, W as pickObject, X as mergeService, Y as voidResult, c as normalizeNotification, ct as createDeadline, nt as STATUS_SERVICE, o as passthroughOperation, q as defineOperation, s as voidOperation, tt as DEFAULT_STATUS_BASE_URL, w as ReportTargetType, y as InteractionType } from "./url-DP33mp3s.js";
2
+ import { _ as ItdStateError, a as ItdConfigError, b as isItdApiError, l as ItdFileError, s as ItdError, t as ItdAbortError, u as ItdFileErrorReason } from "./errors-GI10kZxk.js";
3
+ import { a as redactUrl, b as isFile, d as encodePathSegment, r as redactErrorCause, v as createDeviceId, y as isBlob } from "./redact-Ba5iSVYZ.js";
4
+ import { a as fileTooLarge, c as FileTransferMode, i as isReadableByteStream, n as boundedFileStream, o as optionalBytes, r as isBoundedFileStream, s as DEFAULT_URL_FILE_MAX_BYTES, t as resolveFileStreamOptions } from "./options-DhgGg7Ms.js";
5
+ import { r as createKeyValueStore, t as MemoryKeyValueStore } from "./key-value-store-Bt2PSMxY.js";
5
6
  //#region src/core/feature-catalog.ts
6
7
  /**
7
8
  * Изменяемый слой над каталогом конкретного API.
@@ -3531,6 +3532,195 @@ var SearchResource = class extends BaseResource {
3531
3532
  }
3532
3533
  };
3533
3534
  //#endregion
3535
+ //#region src/resources/shop.ts
3536
+ const PRODUCTS_LIST = passthroughOperation("shop.products.list");
3537
+ const PRODUCTS_GET = passthroughOperation("shop.products.get");
3538
+ const DELIVERY_COUNTRIES = passthroughOperation("shop.delivery.countries");
3539
+ const DELIVERY_CITIES = passthroughOperation("shop.delivery.cities");
3540
+ const DELIVERY_POINTS = passthroughOperation("shop.delivery.points");
3541
+ const DELIVERY_CALCULATE = passthroughOperation("shop.delivery.calculate");
3542
+ const ORDERS_CREATE = passthroughOperation("shop.orders.create");
3543
+ const ORDERS_LIST = passthroughOperation("shop.orders.list");
3544
+ const ORDERS_GET = passthroughOperation("shop.orders.get");
3545
+ const ORDERS_PAY = passthroughOperation("shop.orders.pay");
3546
+ const ORDERS_REQUEST_ACCESS_CODE = voidOperation("shop.orders.requestAccessCode");
3547
+ const ORDERS_VERIFY_ACCESS_CODE = passthroughOperation("shop.orders.verifyAccessCode");
3548
+ const CONSENTS_RECORD = voidOperation("shop.consents.record");
3549
+ function orderRequestOptions(options) {
3550
+ const { orderAccessToken, useItdAuth, headers, ...request } = options;
3551
+ return {
3552
+ ...request,
3553
+ ...useItdAuth === false ? { skipAuth: true } : {},
3554
+ headers: {
3555
+ ...headers,
3556
+ ...orderAccessToken ? { "X-Order-Token": orderAccessToken } : {}
3557
+ }
3558
+ };
3559
+ }
3560
+ /** Каталог товаров магазина. */
3561
+ var ShopProductsResource = class extends BaseResource {
3562
+ /** Загружает все товары. */
3563
+ list(options = {}) {
3564
+ return this.http.execute(PRODUCTS_LIST, {
3565
+ path: "/api/v1/shop/products",
3566
+ raw: true,
3567
+ ...options
3568
+ });
3569
+ }
3570
+ /** Загружает товар по идентификатору. */
3571
+ async get(productId, options = {}) {
3572
+ try {
3573
+ return await this.http.execute(PRODUCTS_GET, {
3574
+ path: `/api/v1/shop/products/${encodePathSegment(productId, "идентификатор товара")}`,
3575
+ raw: true,
3576
+ ...options
3577
+ });
3578
+ } catch (error) {
3579
+ if (isItdApiError(error) && error.status === 404) return null;
3580
+ throw error;
3581
+ }
3582
+ }
3583
+ };
3584
+ /** Расчёт и выбор доставки. */
3585
+ var ShopDeliveryResource = class extends BaseResource {
3586
+ /** Загружает страны, в которые доступна доставка. */
3587
+ countries(options = {}) {
3588
+ return this.http.execute(DELIVERY_COUNTRIES, {
3589
+ path: "/api/v1/shop/delivery/countries",
3590
+ raw: true,
3591
+ ...options
3592
+ });
3593
+ }
3594
+ /** Ищет города службы доставки. */
3595
+ cities(query, countryCode, options = {}) {
3596
+ return this.http.execute(DELIVERY_CITIES, {
3597
+ path: "/api/v1/shop/delivery/cities",
3598
+ query: {
3599
+ q: query,
3600
+ country: countryCode
3601
+ },
3602
+ raw: true,
3603
+ ...options
3604
+ });
3605
+ }
3606
+ /** Загружает пункты выдачи в городе. */
3607
+ points(cityCode, options = {}) {
3608
+ return this.http.execute(DELIVERY_POINTS, {
3609
+ path: "/api/v1/shop/delivery/points",
3610
+ query: { cityCode },
3611
+ raw: true,
3612
+ ...options
3613
+ });
3614
+ }
3615
+ /** Рассчитывает стоимость и срок доставки. */
3616
+ calculate(items, destination, options = {}) {
3617
+ return this.http.execute(DELIVERY_CALCULATE, {
3618
+ path: "/api/v1/shop/delivery/calculate",
3619
+ body: {
3620
+ items,
3621
+ to: destination
3622
+ },
3623
+ raw: true,
3624
+ ...options
3625
+ });
3626
+ }
3627
+ };
3628
+ /** Создание, просмотр и оплата заказов. */
3629
+ var ShopOrdersResource = class extends BaseResource {
3630
+ /** Создаёт заказ. */
3631
+ create(input, options = {}) {
3632
+ const { idempotencyKey = createDeviceId(), headers, ...request } = options;
3633
+ return this.http.execute(ORDERS_CREATE, {
3634
+ path: "/api/v1/shop/orders",
3635
+ body: input,
3636
+ headers: {
3637
+ ...headers,
3638
+ "Idempotency-Key": idempotencyKey
3639
+ },
3640
+ raw: true,
3641
+ ...request
3642
+ });
3643
+ }
3644
+ /** Загружает заказы аккаунта ИТД или владельца временного токена. */
3645
+ list(options = {}) {
3646
+ return this.http.execute(ORDERS_LIST, {
3647
+ path: "/api/v1/shop/orders/my",
3648
+ raw: true,
3649
+ ...orderRequestOptions(options)
3650
+ });
3651
+ }
3652
+ /** Загружает заказ по номеру. */
3653
+ get(orderNumber, options = {}) {
3654
+ return this.http.execute(ORDERS_GET, {
3655
+ path: `/api/v1/shop/orders/${encodePathSegment(orderNumber, "номер заказа")}`,
3656
+ raw: true,
3657
+ ...orderRequestOptions(options)
3658
+ });
3659
+ }
3660
+ /** Создаёт ссылку на оплату заказа. */
3661
+ pay(orderNumber, options) {
3662
+ const { returnUrl, ...access } = options;
3663
+ return this.http.execute(ORDERS_PAY, {
3664
+ path: `/api/v1/shop/orders/${encodePathSegment(orderNumber, "номер заказа")}/pay`,
3665
+ body: { returnUrl },
3666
+ raw: true,
3667
+ ...orderRequestOptions(access)
3668
+ });
3669
+ }
3670
+ /** Отправляет на почту код доступа к гостевым заказам. */
3671
+ requestAccessCode(email, options = {}) {
3672
+ return this.http.execute(ORDERS_REQUEST_ACCESS_CODE, {
3673
+ path: "/api/v1/shop/orders/lookup/request",
3674
+ body: { email },
3675
+ raw: true,
3676
+ skipAuth: true,
3677
+ ...options
3678
+ });
3679
+ }
3680
+ /** Проверяет код из письма и возвращает временный токен заказов. */
3681
+ verifyAccessCode(email, code, options = {}) {
3682
+ return this.http.execute(ORDERS_VERIFY_ACCESS_CODE, {
3683
+ path: "/api/v1/shop/orders/lookup/verify",
3684
+ body: {
3685
+ email,
3686
+ code
3687
+ },
3688
+ raw: true,
3689
+ skipAuth: true,
3690
+ ...options
3691
+ });
3692
+ }
3693
+ };
3694
+ /** Запись согласий магазина. */
3695
+ var ShopConsentsResource = class extends BaseResource {
3696
+ /** Записывает согласия покупателя. */
3697
+ record(consents, consentContext, options = {}) {
3698
+ return this.http.execute(CONSENTS_RECORD, {
3699
+ path: "/api/v1/shop/consents",
3700
+ body: {
3701
+ consents,
3702
+ consentContext
3703
+ },
3704
+ raw: true,
3705
+ ...options
3706
+ });
3707
+ }
3708
+ };
3709
+ /** Магазин ИТД. */
3710
+ var ShopResource = class {
3711
+ products;
3712
+ delivery;
3713
+ orders;
3714
+ consents;
3715
+ /** @internal */
3716
+ constructor(http) {
3717
+ this.products = new ShopProductsResource(http);
3718
+ this.delivery = new ShopDeliveryResource(http);
3719
+ this.orders = new ShopOrdersResource(http);
3720
+ this.consents = new ShopConsentsResource(http);
3721
+ }
3722
+ };
3723
+ //#endregion
3534
3724
  //#region src/resources/subscription.ts
3535
3725
  const SUBSCRIPTION_METHODS = defineBuiltInOperation("subscription.methods", (body) => Array.isArray(body) ? body : []);
3536
3726
  const SUBSCRIPTION_STATUS = passthroughOperation("subscription.status");
@@ -4282,6 +4472,7 @@ function createResources(deps) {
4282
4472
  let subscription;
4283
4473
  let platform;
4284
4474
  let telemetry;
4475
+ let shop;
4285
4476
  const bag = {
4286
4477
  get users() {
4287
4478
  users ??= new UsersResource(deps.http, { uploadFile });
@@ -4331,6 +4522,10 @@ function createResources(deps) {
4331
4522
  telemetry ??= new TelemetryResource(deps.http);
4332
4523
  return telemetry;
4333
4524
  },
4525
+ get shop() {
4526
+ shop ??= new ShopResource(deps.http);
4527
+ return shop;
4528
+ },
4334
4529
  closeTelemetry: (forDispose) => forDispose ? closeTelemetryForDispose(telemetry) : telemetry?.close() ?? Promise.resolve(),
4335
4530
  prepareTelemetryClose: () => prepareTelemetryForDispose(telemetry)
4336
4531
  };
@@ -4404,6 +4599,36 @@ function isMyProfile(profile) {
4404
4599
  return "subscription" in profile;
4405
4600
  }
4406
4601
  //#endregion
4602
+ //#region src/models/shop.ts
4603
+ /** Категория товара магазина. */
4604
+ const ShopProductCategory = Object.freeze({
4605
+ Apparel: "apparel",
4606
+ Accessories: "accessories",
4607
+ Print: "print"
4608
+ });
4609
+ /** Состояние товара в каталоге. */
4610
+ const ShopProductStatus = Object.freeze({
4611
+ Available: "available",
4612
+ Preorder: "preorder",
4613
+ SoldOut: "soldout"
4614
+ });
4615
+ /** Вид согласия, которое принимает покупатель. */
4616
+ const ShopConsentKind = Object.freeze({
4617
+ Offer: "offer",
4618
+ PersonalData: "personal_data",
4619
+ Cookie: "cookie"
4620
+ });
4621
+ /** Состояние заказа. */
4622
+ const ShopOrderStatus = Object.freeze({
4623
+ New: "new",
4624
+ Paid: "paid",
4625
+ Shipping: "ship",
4626
+ Done: "done",
4627
+ Cancelled: "cancelled",
4628
+ Refunded: "refunded",
4629
+ Expired: "expired"
4630
+ });
4631
+ //#endregion
4407
4632
  //#region src/models/status-helpers.ts
4408
4633
  const STATUS_WINDOW_DAYS = 90;
4409
4634
  /**
@@ -4425,6 +4650,186 @@ function statusDays(service) {
4425
4650
  return Array.from({ length: STATUS_WINDOW_DAYS }, (_, index) => service.days[String(index)] ?? null);
4426
4651
  }
4427
4652
  //#endregion
4653
+ //#region src/shop/order-access.ts
4654
+ function copySession(session) {
4655
+ return { ...session };
4656
+ }
4657
+ /** Хранилище доступа к заказам в памяти процесса. */
4658
+ var MemoryShopOrderAccessStorage = class {
4659
+ #session;
4660
+ constructor(initial = null) {
4661
+ this.#session = initial ? copySession(initial) : null;
4662
+ }
4663
+ get() {
4664
+ return this.#session ? copySession(this.#session) : null;
4665
+ }
4666
+ set(session) {
4667
+ this.#session = copySession(session);
4668
+ }
4669
+ clear() {
4670
+ this.#session = null;
4671
+ }
4672
+ };
4673
+ /** Создаёт хранилище доступа к заказам поверх `KeyValueStore`. */
4674
+ function createShopOrderAccessStorage(store, options = {}) {
4675
+ const key = options.key ?? "shop-order-access";
4676
+ if (typeof key !== "string" || key.length === 0) throw new ItdConfigError("ключ хранилища доступа к заказам должен быть непустой строкой");
4677
+ const backend = createKeyValueStore(store);
4678
+ return {
4679
+ async get() {
4680
+ const session = await backend.get(key);
4681
+ return session ? copySession(session) : null;
4682
+ },
4683
+ set: (session) => backend.set(key, copySession(session)),
4684
+ clear: () => backend.delete(key)
4685
+ };
4686
+ }
4687
+ /** Создаёт независимое хранилище доступа к заказам в памяти. */
4688
+ function createMemoryShopOrderAccessStorage() {
4689
+ return createShopOrderAccessStorage(new MemoryKeyValueStore());
4690
+ }
4691
+ //#endregion
4692
+ //#region src/shop/feature.ts
4693
+ const Operation = Object.freeze({
4694
+ RequestCode: "request-code",
4695
+ VerifyCode: "verify-code",
4696
+ List: "list",
4697
+ Get: "get",
4698
+ Pay: "pay"
4699
+ });
4700
+ function requireEmail(value) {
4701
+ const email = value.trim();
4702
+ if (!email?.includes("@")) throw new ItdConfigError("укажите адрес почты");
4703
+ return email;
4704
+ }
4705
+ /** Создаёт подключаемый модуль для доступа к заказам по коду из письма. */
4706
+ function createShopFeature(options = {}) {
4707
+ return {
4708
+ name: "shop",
4709
+ buckets: {
4710
+ [Operation.RequestCode]: { limit: 4 },
4711
+ [Operation.VerifyCode]: { limit: 13 },
4712
+ [Operation.List]: { limit: 150 },
4713
+ [Operation.Get]: { limit: 150 },
4714
+ [Operation.Pay]: { limit: 13 }
4715
+ },
4716
+ operations: {
4717
+ [Operation.RequestCode]: {
4718
+ method: "POST",
4719
+ retrySafety: RetrySafety.Unsafe,
4720
+ read: voidResult,
4721
+ bucket: Operation.RequestCode
4722
+ },
4723
+ [Operation.VerifyCode]: {
4724
+ method: "POST",
4725
+ retrySafety: RetrySafety.Unsafe,
4726
+ bucket: Operation.VerifyCode
4727
+ },
4728
+ [Operation.List]: {
4729
+ method: "GET",
4730
+ retrySafety: RetrySafety.Safe,
4731
+ bucket: Operation.List
4732
+ },
4733
+ [Operation.Get]: {
4734
+ method: "GET",
4735
+ retrySafety: RetrySafety.Safe,
4736
+ bucket: Operation.Get
4737
+ },
4738
+ [Operation.Pay]: {
4739
+ method: "POST",
4740
+ retrySafety: RetrySafety.Unsafe,
4741
+ bucket: Operation.Pay
4742
+ }
4743
+ },
4744
+ setup(context) {
4745
+ const storage = options.storage ?? createMemoryShopOrderAccessStorage();
4746
+ let pendingEmail = null;
4747
+ const readSession = async () => {
4748
+ const session = await storage.get();
4749
+ if (!session) return null;
4750
+ if (session.expiresAt > context.clock.now()) return { ...session };
4751
+ await storage.clear();
4752
+ return null;
4753
+ };
4754
+ const requireSession = async () => {
4755
+ const session = await readSession();
4756
+ if (!session) throw new ItdConfigError("доступ к заказам отсутствует или истёк; запросите новый код");
4757
+ return session;
4758
+ };
4759
+ const withAccess = async (run) => {
4760
+ const session = await requireSession();
4761
+ try {
4762
+ return await run(session.token);
4763
+ } catch (error) {
4764
+ if (isItdApiError(error) && error.status === 401) await storage.clear();
4765
+ throw error;
4766
+ }
4767
+ };
4768
+ const request = (operation, token, requestOptions) => context.request(operation, {
4769
+ ...requestOptions,
4770
+ headers: {
4771
+ ...requestOptions.headers,
4772
+ "X-Order-Token": token
4773
+ },
4774
+ skipAuth: true,
4775
+ raw: true
4776
+ });
4777
+ return { api: Object.freeze({
4778
+ async requestCode(email, requestOptions = {}) {
4779
+ const normalized = requireEmail(email);
4780
+ await context.request(Operation.RequestCode, {
4781
+ path: "/api/v1/shop/orders/lookup/request",
4782
+ body: { email: normalized },
4783
+ skipAuth: true,
4784
+ raw: true,
4785
+ ...requestOptions
4786
+ });
4787
+ pendingEmail = normalized;
4788
+ },
4789
+ async verifyCode(code, requestOptions = {}) {
4790
+ if (!pendingEmail) throw new ItdConfigError("сначала запросите код для адреса почты");
4791
+ const verified = await context.request(Operation.VerifyCode, {
4792
+ path: "/api/v1/shop/orders/lookup/verify",
4793
+ body: {
4794
+ email: pendingEmail,
4795
+ code
4796
+ },
4797
+ skipAuth: true,
4798
+ raw: true,
4799
+ ...requestOptions
4800
+ });
4801
+ const session = {
4802
+ email: pendingEmail,
4803
+ token: verified.token,
4804
+ expiresAt: context.clock.now() + verified.expiresInSec * 1e3
4805
+ };
4806
+ await storage.set(session);
4807
+ pendingEmail = null;
4808
+ return { ...session };
4809
+ },
4810
+ session: readSession,
4811
+ async clear() {
4812
+ pendingEmail = null;
4813
+ await storage.clear();
4814
+ },
4815
+ list: (requestOptions = {}) => withAccess((token) => request(Operation.List, token, {
4816
+ path: "/api/v1/shop/orders/my",
4817
+ ...requestOptions
4818
+ })),
4819
+ get: (orderNumber, requestOptions = {}) => withAccess((token) => request(Operation.Get, token, {
4820
+ path: `/api/v1/shop/orders/${encodePathSegment(orderNumber, "номер заказа")}`,
4821
+ ...requestOptions
4822
+ })),
4823
+ pay: (orderNumber, returnUrl, requestOptions = {}) => withAccess((token) => request(Operation.Pay, token, {
4824
+ path: `/api/v1/shop/orders/${encodePathSegment(orderNumber, "номер заказа")}/pay`,
4825
+ body: { returnUrl },
4826
+ ...requestOptions
4827
+ }))
4828
+ }) };
4829
+ }
4830
+ };
4831
+ }
4832
+ //#endregion
4428
4833
  //#region src/spans/render.ts
4429
4834
  /** Формат результата {@link renderSpans}. */
4430
4835
  const SpanRenderFormat = Object.freeze({
@@ -4627,6 +5032,6 @@ function renderSpans(content, spans = [], options = {}) {
4627
5032
  return result;
4628
5033
  }
4629
5034
  //#endregion
4630
- export { ExtensibleOperationCatalog as A, utcStampToIso as C, Paginator as D, PaginationMode as E, mapPage as O, toDate as S, BaseResource as T, IMAGE_MIME_TYPES as _, fromStream as a, isBuilder as b, report as c, autoSpans as d, markup as f, AUDIO_MIME_TYPES as g, ALLOWED_MIME_TYPES as h, isMyProfile as i, createFeatureHost as k, post as l, parseMarkdown as m, renderSpans as n, fromUrl as o, parseHtml as p, statusDays as r, createResources as s, SpanRenderFormat as t, poll as u, VIDEO_MIME_TYPES as v, NotificationsResource as w, createStatusFeature as x, comment as y };
5035
+ export { toDate as A, ALLOWED_MIME_TYPES as C, comment as D, VIDEO_MIME_TYPES as E, Paginator as F, mapPage as I, createFeatureHost as L, NotificationsResource as M, BaseResource as N, isBuilder as O, PaginationMode as P, ExtensibleOperationCatalog as R, parseMarkdown as S, IMAGE_MIME_TYPES as T, post as _, createMemoryShopOrderAccessStorage as a, markup as b, ShopConsentKind as c, ShopProductStatus as d, isMyProfile as f, report as g, createResources as h, MemoryShopOrderAccessStorage as i, utcStampToIso as j, createStatusFeature as k, ShopOrderStatus as l, fromUrl as m, renderSpans as n, createShopOrderAccessStorage as o, fromStream as p, createShopFeature as r, statusDays as s, SpanRenderFormat as t, ShopProductCategory as u, poll as v, AUDIO_MIME_TYPES as w, parseHtml as x, autoSpans as y };
4631
5036
 
4632
- //# sourceMappingURL=render-CiL1VS0b.js.map
5037
+ //# sourceMappingURL=render-hiWFh2s4.js.map