@torrow/sdk-client 0.6.0 → 0.8.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/README.md +10 -0
- package/dist/index.d.ts +146 -51
- package/dist/index.js +310 -94
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -679,7 +679,7 @@ var HttpClient = class {
|
|
|
679
679
|
this.config = config;
|
|
680
680
|
}
|
|
681
681
|
config;
|
|
682
|
-
async requestJson(init) {
|
|
682
|
+
async requestJson(init, onDispatch) {
|
|
683
683
|
const { fetch: fetchFn = globalThis.fetch } = this.config;
|
|
684
684
|
const url = this.buildUrl(init.path, init.query);
|
|
685
685
|
const authHeaders = await buildAuthHeaders(this.config);
|
|
@@ -696,12 +696,15 @@ var HttpClient = class {
|
|
|
696
696
|
if (needsBody) {
|
|
697
697
|
headers["Content-Type"] = JSON_MIME;
|
|
698
698
|
}
|
|
699
|
-
const
|
|
699
|
+
const requestInit = {
|
|
700
700
|
method: init.method,
|
|
701
701
|
headers,
|
|
702
702
|
body: needsBody ? stringifyJsonBody(init.body) : void 0,
|
|
703
703
|
signal: init.signal
|
|
704
|
-
}
|
|
704
|
+
};
|
|
705
|
+
if (onDispatch) init.signal?.throwIfAborted();
|
|
706
|
+
onDispatch?.();
|
|
707
|
+
const res = await fetchFn(url, requestInit);
|
|
705
708
|
const requestId = res.headers.get("x-request-id") ?? void 0;
|
|
706
709
|
const traceIdentifier = res.headers.get("trace-identifier") ?? void 0;
|
|
707
710
|
const text = await res.text();
|
|
@@ -1210,7 +1213,8 @@ var TorrowItemCoreFacade = class {
|
|
|
1210
1213
|
}
|
|
1211
1214
|
/**
|
|
1212
1215
|
* `PUT /api/v1/{domain}/{torrowId}/participation/requestaccess` — запрос доступа (не-владелец).
|
|
1213
|
-
* Body: **`profileId`**.
|
|
1216
|
+
* Body: **`profileId`**. Новый участник → **`Requested`**; некоторые существующие состояния → **`Accepted`**.
|
|
1217
|
+
* Проверять возвращённый participantState; после Accepted заново прочитать элемент и проверить полноту содержимого.
|
|
1214
1218
|
* Владелец своего item вызвать не может. Дальше: {@link grantAccess} / {@link declineAccess} / {@link revokeAccessRequest}.
|
|
1215
1219
|
*/
|
|
1216
1220
|
requestAccess(torrowId, profileId, options) {
|
|
@@ -3092,7 +3096,6 @@ var SERVICE_IMPLICIT_TAG_SUFFIX = {
|
|
|
3092
3096
|
autoStartTelegramNotificationBot: "AutoStartTelegramNotificationBot",
|
|
3093
3097
|
autoStartTelegramNotificationBotTypo: "AutoStartTelegramNotifcationBot",
|
|
3094
3098
|
autoStartConnectNotifications: "AutoStartConnectNotifications",
|
|
3095
|
-
hideMessengerConnectUiLegacy: "HideTelegramNotificationBot",
|
|
3096
3099
|
hideMessengerConnectUi: "HideMessengerNotifications",
|
|
3097
3100
|
/**
|
|
3098
3101
|
* Резерв под серверную договоренность. Формат в `tags`: `NNN:payment_redirect_timeout_sec`.
|
|
@@ -3100,6 +3103,7 @@ var SERVICE_IMPLICIT_TAG_SUFFIX = {
|
|
|
3100
3103
|
*/
|
|
3101
3104
|
paymentRedirectTimeoutSec: ":payment_redirect_timeout_sec"
|
|
3102
3105
|
};
|
|
3106
|
+
var OBSOLETE_MESSENGER_CONNECT_UI_TAG = "HideTelegramNotificationBot";
|
|
3103
3107
|
var SERVICE_IMPLICIT_TAG_REGISTRY = {
|
|
3104
3108
|
orderName: {
|
|
3105
3109
|
field: "orderName",
|
|
@@ -3145,13 +3149,8 @@ var SERVICE_IMPLICIT_TAG_REGISTRY = {
|
|
|
3145
3149
|
},
|
|
3146
3150
|
hideMessengerConnectUi: {
|
|
3147
3151
|
field: "hideMessengerConnectUi",
|
|
3148
|
-
kind: "
|
|
3149
|
-
tokens: [SERVICE_IMPLICIT_TAG_SUFFIX.hideMessengerConnectUi
|
|
3150
|
-
},
|
|
3151
|
-
hideTelegramNotificationBot: {
|
|
3152
|
-
field: "hideTelegramNotificationBot",
|
|
3153
|
-
kind: "containsFlag",
|
|
3154
|
-
tokens: [SERVICE_IMPLICIT_TAG_SUFFIX.hideMessengerConnectUiLegacy]
|
|
3152
|
+
kind: "exactFlag",
|
|
3153
|
+
tokens: [SERVICE_IMPLICIT_TAG_SUFFIX.hideMessengerConnectUi]
|
|
3155
3154
|
},
|
|
3156
3155
|
autoStartNotificationDelaySeconds: {
|
|
3157
3156
|
field: "autoStartNotificationDelaySeconds",
|
|
@@ -3184,8 +3183,8 @@ function splitBySuffix(tag, suffix, caseInsensitive = false) {
|
|
|
3184
3183
|
}
|
|
3185
3184
|
function firstPrefixBySuffix(tags, suffix, options) {
|
|
3186
3185
|
for (const tag of tags) {
|
|
3187
|
-
const
|
|
3188
|
-
if (
|
|
3186
|
+
const prefix2 = splitBySuffix(tag, suffix, options?.caseInsensitive ?? false);
|
|
3187
|
+
if (prefix2 !== void 0) return prefix2;
|
|
3189
3188
|
}
|
|
3190
3189
|
return void 0;
|
|
3191
3190
|
}
|
|
@@ -3239,8 +3238,8 @@ function parseServiceImplicitTagParams(tags) {
|
|
|
3239
3238
|
if (value !== void 0) mutable[config.field] = value;
|
|
3240
3239
|
}
|
|
3241
3240
|
}
|
|
3242
|
-
if (config.kind === "
|
|
3243
|
-
const hasAny = safeTags.some((tag) => config.tokens.some((token) => tag
|
|
3241
|
+
if (config.kind === "exactFlag") {
|
|
3242
|
+
const hasAny = safeTags.some((tag) => config.tokens.some((token) => tag === token));
|
|
3244
3243
|
if (hasAny) mutable[config.field] = true;
|
|
3245
3244
|
}
|
|
3246
3245
|
}
|
|
@@ -3315,9 +3314,6 @@ function buildServiceImplicitTags(params, options) {
|
|
|
3315
3314
|
if (params.hideMessengerConnectUi) {
|
|
3316
3315
|
tags.push(SERVICE_IMPLICIT_TAG_REGISTRY.hideMessengerConnectUi.tokens[0]);
|
|
3317
3316
|
}
|
|
3318
|
-
if (params.hideTelegramNotificationBot) {
|
|
3319
|
-
tags.push(SERVICE_IMPLICIT_TAG_REGISTRY.hideTelegramNotificationBot.tokens[0]);
|
|
3320
|
-
}
|
|
3321
3317
|
return tags;
|
|
3322
3318
|
}
|
|
3323
3319
|
function isImplicitServiceTag(tag) {
|
|
@@ -3328,8 +3324,8 @@ function isImplicitServiceTag(tag) {
|
|
|
3328
3324
|
);
|
|
3329
3325
|
if (matched) return true;
|
|
3330
3326
|
}
|
|
3331
|
-
if (config.kind === "
|
|
3332
|
-
if (config.tokens.some((token) => tag
|
|
3327
|
+
if (config.kind === "exactFlag") {
|
|
3328
|
+
if (config.tokens.some((token) => tag === token)) return true;
|
|
3333
3329
|
}
|
|
3334
3330
|
if (config.kind === "autoStart") {
|
|
3335
3331
|
const isAutoStart = config.suffixes.some((suffix) => tag.match(new RegExp(`^\\d+:${suffix}$`)) !== null);
|
|
@@ -3345,15 +3341,17 @@ function isImplicitServiceTag(tag) {
|
|
|
3345
3341
|
}
|
|
3346
3342
|
function mergeServiceImplicitTags(baseTags, params, options) {
|
|
3347
3343
|
const safeBase = baseTags ?? [];
|
|
3348
|
-
const preservedNonImplicit = safeBase.filter(
|
|
3344
|
+
const preservedNonImplicit = safeBase.filter(
|
|
3345
|
+
(tag) => tag !== OBSOLETE_MESSENGER_CONNECT_UI_TAG && !isImplicitServiceTag(tag)
|
|
3346
|
+
);
|
|
3349
3347
|
const nextImplicit = buildServiceImplicitTags(params, options);
|
|
3350
3348
|
return [...preservedNonImplicit, ...nextImplicit];
|
|
3351
3349
|
}
|
|
3352
3350
|
function parseResourceBehaviorSettings(tags) {
|
|
3353
|
-
const
|
|
3351
|
+
const marginTimeSec = toPositiveInt(firstPrefixBySuffix(tags ?? [], SERVICE_IMPLICIT_TAG_SUFFIX.marginTime));
|
|
3354
3352
|
const lockId = toPositiveInt(firstPrefixBySuffix(tags ?? [], SERVICE_IMPLICIT_TAG_SUFFIX.lockId));
|
|
3355
3353
|
const result = {};
|
|
3356
|
-
if (
|
|
3354
|
+
if (marginTimeSec !== void 0) result.marginTimeSec = marginTimeSec;
|
|
3357
3355
|
if (lockId !== void 0) result.lockId = lockId;
|
|
3358
3356
|
return result;
|
|
3359
3357
|
}
|
|
@@ -3591,6 +3589,195 @@ var ResourcesFacade = class extends TorrowItemFacade {
|
|
|
3591
3589
|
}
|
|
3592
3590
|
};
|
|
3593
3591
|
|
|
3592
|
+
// ../../src/resources/services/behavior-settings.ts
|
|
3593
|
+
var ServiceBehaviorSettingsErrorCategory = /* @__PURE__ */ ((ServiceBehaviorSettingsErrorCategory2) => {
|
|
3594
|
+
ServiceBehaviorSettingsErrorCategory2["InvalidInput"] = "InvalidInput";
|
|
3595
|
+
ServiceBehaviorSettingsErrorCategory2["AccessDenied"] = "AccessDenied";
|
|
3596
|
+
ServiceBehaviorSettingsErrorCategory2["InsufficientData"] = "InsufficientData";
|
|
3597
|
+
ServiceBehaviorSettingsErrorCategory2["InvalidResponse"] = "InvalidResponse";
|
|
3598
|
+
ServiceBehaviorSettingsErrorCategory2["VersionConflict"] = "VersionConflict";
|
|
3599
|
+
ServiceBehaviorSettingsErrorCategory2["WriteOutcomeUnknown"] = "WriteOutcomeUnknown";
|
|
3600
|
+
ServiceBehaviorSettingsErrorCategory2["RequestNotSent"] = "RequestNotSent";
|
|
3601
|
+
return ServiceBehaviorSettingsErrorCategory2;
|
|
3602
|
+
})(ServiceBehaviorSettingsErrorCategory || {});
|
|
3603
|
+
var ServiceBehaviorSettingsIssueReason = /* @__PURE__ */ ((ServiceBehaviorSettingsIssueReason2) => {
|
|
3604
|
+
ServiceBehaviorSettingsIssueReason2["InvalidValue"] = "InvalidValue";
|
|
3605
|
+
ServiceBehaviorSettingsIssueReason2["AmbiguousValue"] = "AmbiguousValue";
|
|
3606
|
+
return ServiceBehaviorSettingsIssueReason2;
|
|
3607
|
+
})(ServiceBehaviorSettingsIssueReason || {});
|
|
3608
|
+
var ServiceBehaviorSettingsError = class extends Error {
|
|
3609
|
+
/** Предметная категория; не зависит от кодов MCP. */
|
|
3610
|
+
category;
|
|
3611
|
+
/** Исходная ошибка транспорта или сервера, если она существует. */
|
|
3612
|
+
cause;
|
|
3613
|
+
constructor(category, cause) {
|
|
3614
|
+
super(`Service BehaviorSettings: ${category}`);
|
|
3615
|
+
this.name = "ServiceBehaviorSettingsError";
|
|
3616
|
+
this.category = category;
|
|
3617
|
+
this.cause = cause;
|
|
3618
|
+
}
|
|
3619
|
+
};
|
|
3620
|
+
var configs = Object.values(SERVICE_IMPLICIT_TAG_REGISTRY);
|
|
3621
|
+
function isBehaviorVersion(value) {
|
|
3622
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 2147483647;
|
|
3623
|
+
}
|
|
3624
|
+
function record(value) {
|
|
3625
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3626
|
+
}
|
|
3627
|
+
function validateBehaviorResponse(value, serviceId) {
|
|
3628
|
+
if (!record(value) || value.id !== serviceId) throw new ServiceBehaviorSettingsError("InvalidResponse" /* InvalidResponse */);
|
|
3629
|
+
const personal = value.personalInfo;
|
|
3630
|
+
if (record(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
|
|
3631
|
+
throw new ServiceBehaviorSettingsError("AccessDenied" /* AccessDenied */);
|
|
3632
|
+
}
|
|
3633
|
+
if (!record(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record(value.meta) || !isBehaviorVersion(value.meta.version)) {
|
|
3634
|
+
throw new ServiceBehaviorSettingsError("InsufficientData" /* InsufficientData */);
|
|
3635
|
+
}
|
|
3636
|
+
if (!Array.isArray(value.tags) || !value.tags.every((tag) => typeof tag === "string")) {
|
|
3637
|
+
throw new ServiceBehaviorSettingsError("InvalidResponse" /* InvalidResponse */);
|
|
3638
|
+
}
|
|
3639
|
+
const operations = personal.operationList;
|
|
3640
|
+
if (operations != null && (!Array.isArray(operations) || !operations.every((operation) => typeof operation === "string" || typeof operation === "number" && Number.isSafeInteger(operation)))) {
|
|
3641
|
+
throw new ServiceBehaviorSettingsError("InvalidResponse" /* InvalidResponse */);
|
|
3642
|
+
}
|
|
3643
|
+
return { tags: [...new Set(value.tags)], version: value.meta.version, operations };
|
|
3644
|
+
}
|
|
3645
|
+
function assertBehaviorPermission(operations) {
|
|
3646
|
+
if (!Array.isArray(operations)) throw new ServiceBehaviorSettingsError("InsufficientData" /* InsufficientData */);
|
|
3647
|
+
if (!operations.includes("SetItemTags" /* SetItemTags */)) throw new ServiceBehaviorSettingsError("AccessDenied" /* AccessDenied */);
|
|
3648
|
+
}
|
|
3649
|
+
function suffixPrefix(tag, suffix, ignoreCase = false) {
|
|
3650
|
+
const matches = ignoreCase ? tag.toLowerCase().endsWith(suffix.toLowerCase()) : tag.endsWith(suffix);
|
|
3651
|
+
return matches ? tag.slice(0, -suffix.length) : void 0;
|
|
3652
|
+
}
|
|
3653
|
+
function positive(raw) {
|
|
3654
|
+
const value = Number(raw);
|
|
3655
|
+
return /^\d+$/.test(raw) && Number.isSafeInteger(value) && value > 0 ? value : void 0;
|
|
3656
|
+
}
|
|
3657
|
+
function prefix(tag, config) {
|
|
3658
|
+
if (config.kind === "string" /* String */ || config.kind === "positiveInt" /* PositiveInt */) {
|
|
3659
|
+
for (const suffix of config.suffixes) {
|
|
3660
|
+
const value = suffixPrefix(tag, suffix, config.caseInsensitive);
|
|
3661
|
+
if (value !== void 0) return value;
|
|
3662
|
+
}
|
|
3663
|
+
} else if (config.kind === "exactFlag" /* ExactFlag */) {
|
|
3664
|
+
if (config.tokens.includes(tag) || tag === "HideTelegramNotificationBot" /* LegacyHide */) return "true";
|
|
3665
|
+
} else if (config.kind === "autoStart" /* AutoStart */) {
|
|
3666
|
+
for (const suffix of config.suffixes) {
|
|
3667
|
+
const value = suffixPrefix(tag, `:${suffix}`);
|
|
3668
|
+
if (value !== void 0) return value;
|
|
3669
|
+
}
|
|
3670
|
+
} else if (config.kind === "agreement" /* Agreement */) {
|
|
3671
|
+
for (const suffix of [config.textSuffix, config.linkSuffix]) {
|
|
3672
|
+
const position = tag.lastIndexOf(suffix);
|
|
3673
|
+
if (position >= 0 && /^\d+$/.test(tag.slice(position + suffix.length))) return tag;
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
return void 0;
|
|
3677
|
+
}
|
|
3678
|
+
function readBehaviorSettings(tags) {
|
|
3679
|
+
const settings = { hideMessengerConnectUi: false };
|
|
3680
|
+
const issues = [];
|
|
3681
|
+
const target = settings;
|
|
3682
|
+
for (const config of configs) {
|
|
3683
|
+
const matching = [...new Set(tags)].filter((tag) => prefix(tag, config) !== void 0);
|
|
3684
|
+
if (!matching.length) continue;
|
|
3685
|
+
let invalid = false;
|
|
3686
|
+
let ambiguous = false;
|
|
3687
|
+
let result;
|
|
3688
|
+
if (config.kind === "agreement" /* Agreement */) {
|
|
3689
|
+
const entries = /* @__PURE__ */ new Map();
|
|
3690
|
+
for (const tag of matching) {
|
|
3691
|
+
for (const [attribute, suffix] of [["text", config.textSuffix], ["link", config.linkSuffix]]) {
|
|
3692
|
+
const position = tag.lastIndexOf(suffix);
|
|
3693
|
+
if (position < 0 || !/^\d+$/.test(tag.slice(position + suffix.length))) continue;
|
|
3694
|
+
const index = positive(tag.slice(position + suffix.length));
|
|
3695
|
+
let value = tag.slice(0, position).trim();
|
|
3696
|
+
if (attribute === "link") value = value.replace(/^(https?)\/\//, "$1://");
|
|
3697
|
+
if (!index || !value) {
|
|
3698
|
+
invalid = true;
|
|
3699
|
+
continue;
|
|
3700
|
+
}
|
|
3701
|
+
const entry = entries.get(index) ?? { index };
|
|
3702
|
+
if (entry[attribute] !== void 0 && entry[attribute] !== value) ambiguous = true;
|
|
3703
|
+
entry[attribute] = value;
|
|
3704
|
+
entries.set(index, entry);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
result = [...entries.values()].sort((a, b) => a.index - b.index);
|
|
3708
|
+
} else {
|
|
3709
|
+
const values = /* @__PURE__ */ new Set();
|
|
3710
|
+
for (const tag of matching) {
|
|
3711
|
+
const raw = prefix(tag, config);
|
|
3712
|
+
const value = config.kind === "exactFlag" /* ExactFlag */ ? true : config.kind === "string" /* String */ ? raw.trim() || void 0 : positive(raw);
|
|
3713
|
+
if (value === void 0) invalid = true;
|
|
3714
|
+
else values.add(value);
|
|
3715
|
+
}
|
|
3716
|
+
ambiguous = values.size > 1;
|
|
3717
|
+
result = [...values][0];
|
|
3718
|
+
}
|
|
3719
|
+
if (invalid || ambiguous) {
|
|
3720
|
+
issues.push({ field: config.field, reason: invalid ? "InvalidValue" /* InvalidValue */ : "AmbiguousValue" /* AmbiguousValue */ });
|
|
3721
|
+
} else target[config.field] = result;
|
|
3722
|
+
}
|
|
3723
|
+
return { settings, issues };
|
|
3724
|
+
}
|
|
3725
|
+
function normalizeBehaviorInput(input) {
|
|
3726
|
+
function fail() {
|
|
3727
|
+
throw new ServiceBehaviorSettingsError("InvalidInput" /* InvalidInput */);
|
|
3728
|
+
}
|
|
3729
|
+
if (!record(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) fail();
|
|
3730
|
+
const output = {};
|
|
3731
|
+
for (const config of configs) {
|
|
3732
|
+
if (!Object.hasOwn(input, config.field)) continue;
|
|
3733
|
+
const value = input[config.field];
|
|
3734
|
+
if (config.kind === "string" /* String */) {
|
|
3735
|
+
if (typeof value !== "string" || !value.trim()) fail();
|
|
3736
|
+
output[config.field] = value.trim();
|
|
3737
|
+
} else if (config.kind === "positiveInt" /* PositiveInt */ || config.kind === "autoStart" /* AutoStart */) {
|
|
3738
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) fail();
|
|
3739
|
+
output[config.field] = value;
|
|
3740
|
+
} else if (config.kind === "exactFlag" /* ExactFlag */) {
|
|
3741
|
+
if (typeof value !== "boolean") fail();
|
|
3742
|
+
output[config.field] = value;
|
|
3743
|
+
} else {
|
|
3744
|
+
if (!Array.isArray(value)) fail();
|
|
3745
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3746
|
+
output[config.field] = value.map((entry) => {
|
|
3747
|
+
if (!record(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)) fail();
|
|
3748
|
+
seen.add(entry.index);
|
|
3749
|
+
const normalized = { index: entry.index };
|
|
3750
|
+
for (const attribute of ["text", "link"]) {
|
|
3751
|
+
if (Object.hasOwn(entry, attribute)) {
|
|
3752
|
+
if (typeof entry[attribute] !== "string" || !entry[attribute].trim()) fail();
|
|
3753
|
+
normalized[attribute] = entry[attribute].trim();
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
if (!normalized.text && !normalized.link) fail();
|
|
3757
|
+
return normalized;
|
|
3758
|
+
}).sort((a, b) => a.index - b.index);
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
return output;
|
|
3762
|
+
}
|
|
3763
|
+
function mergeBehaviorSettings(tags, settings, mergeParameters) {
|
|
3764
|
+
const selected = configs.filter((config) => !mergeParameters || Object.hasOwn(settings, config.field));
|
|
3765
|
+
const output = tags.filter((tag) => !selected.some((config) => prefix(tag, config) !== void 0));
|
|
3766
|
+
for (const config of selected) {
|
|
3767
|
+
const value = settings[config.field];
|
|
3768
|
+
if (value === void 0) continue;
|
|
3769
|
+
if (config.kind === "string" /* String */ || config.kind === "positiveInt" /* PositiveInt */) output.push(`${value}${config.suffixes[0]}`);
|
|
3770
|
+
else if (config.kind === "exactFlag" /* ExactFlag */) {
|
|
3771
|
+
if (value) output.push(config.tokens[0]);
|
|
3772
|
+
} else if (config.kind === "autoStart" /* AutoStart */) output.push(`${value}:${config.suffixes[0]}`);
|
|
3773
|
+
else if (config.kind === "agreement" /* Agreement */) for (const entry of settings.agreementItems ?? []) {
|
|
3774
|
+
if (entry.text) output.push(`${entry.text}${config.textSuffix}${entry.index}`);
|
|
3775
|
+
if (entry.link) output.push(`${entry.link.replace(/^(https?):\/\//, "$1//")}${config.linkSuffix}${entry.index}`);
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
return [...new Set(output)];
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3594
3781
|
// ../../src/resources/services/service-requests.ts
|
|
3595
3782
|
var BASE8 = "/api/v1/services";
|
|
3596
3783
|
function toSdkServiceItem(service) {
|
|
@@ -3707,56 +3894,80 @@ var ServicesFacade = class extends TorrowItemFacade {
|
|
|
3707
3894
|
getById(torrowId, options) {
|
|
3708
3895
|
return getService(this.http, torrowId, options);
|
|
3709
3896
|
}
|
|
3710
|
-
/**
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3897
|
+
/** Читает сырой OpenAPI DTO до проекции, чтобы malformed tags не маскировались парсером. */
|
|
3898
|
+
async readBehaviorState(serviceId, options) {
|
|
3899
|
+
if (typeof serviceId !== "string" || !serviceId.trim()) {
|
|
3900
|
+
throw new ServiceBehaviorSettingsError("InvalidInput" /* InvalidInput */);
|
|
3901
|
+
}
|
|
3902
|
+
const value = await this.http.requestJson({
|
|
3903
|
+
method: "GET",
|
|
3904
|
+
path: `${BASE9}/${encodePathSegment(serviceId)}`,
|
|
3905
|
+
query: {
|
|
3906
|
+
profileId: options?.profileId,
|
|
3907
|
+
versionToCheck: options?.versionToCheck,
|
|
3908
|
+
includeDeleted: options?.includeDeleted,
|
|
3909
|
+
includeChildTypes: options?.includeChildTypes,
|
|
3910
|
+
securityToken: options?.securityToken
|
|
3911
|
+
},
|
|
3912
|
+
signal: options?.signal
|
|
3913
|
+
});
|
|
3914
|
+
return validateBehaviorResponse(value, serviceId);
|
|
3714
3915
|
}
|
|
3715
|
-
/**
|
|
3916
|
+
/** Один GET: версия всей услуги, предметные настройки и диагностика неполного снимка. */
|
|
3716
3917
|
async getBehaviorSettings(serviceId, options) {
|
|
3717
|
-
const
|
|
3718
|
-
return
|
|
3918
|
+
const state = await this.readBehaviorState(serviceId, options);
|
|
3919
|
+
return { serviceId, version: state.version, ...readBehaviorSettings(state.tags) };
|
|
3719
3920
|
}
|
|
3720
3921
|
/**
|
|
3721
|
-
*
|
|
3722
|
-
*
|
|
3723
|
-
*
|
|
3724
|
-
* Персист только через **`PUT .../services/{id}/tags`**: поле `tags` в теле `PUT /services/{id}`
|
|
3725
|
-
* сервер игнорирует (`tags` в `TorrowItemKeysExcludedFromItemWriteBody`).
|
|
3922
|
+
* GET → локальный patch → PUT /tags с необязательной проверкой версии; автоматического readback нет.
|
|
3923
|
+
* mergeParameters=true сохраняет пропущенные поля, false заменяет все настройки.
|
|
3924
|
+
* Порядок и одинаковые дубли сервер не сохраняет; no-op определяется множеством строк.
|
|
3726
3925
|
*/
|
|
3727
|
-
async updateBehaviorSettings(serviceId, settingsPatch, options) {
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
...this.getBehaviorSettingsFromService(service),
|
|
3738
|
-
...settingsPatch
|
|
3739
|
-
} : { ...settingsPatch };
|
|
3740
|
-
const nextTags = mergeServiceImplicitTags(service.tags, nextSettings);
|
|
3741
|
-
await this.updateTags(serviceId, nextTags, {
|
|
3742
|
-
versionToCheck: options?.checkVersion ? service.meta?.version ?? void 0 : void 0,
|
|
3743
|
-
isNeedAnnouncement: options?.isNeedAnnouncement,
|
|
3744
|
-
signal: options?.signal
|
|
3745
|
-
});
|
|
3746
|
-
return this.getById(serviceId, {
|
|
3747
|
-
profileId: options?.profileId,
|
|
3748
|
-
includeDeleted: options?.includeDeleted,
|
|
3749
|
-
includeChildTypes: options?.includeChildTypes,
|
|
3750
|
-
securityToken: options?.securityToken,
|
|
3751
|
-
signal: options?.signal
|
|
3926
|
+
async updateBehaviorSettings(serviceId, settingsPatch, options = {}) {
|
|
3927
|
+
if (!options || options.versionToCheck !== void 0 && !isBehaviorVersion(options.versionToCheck) || Object.hasOwn(options, "checkVersion") && options.checkVersion !== true || Object.hasOwn(options, "mergeParameters") && typeof options.mergeParameters !== "boolean" || options.isNeedAnnouncement != null && typeof options.isNeedAnnouncement !== "boolean" || Object.keys(options).some((key) => !["versionToCheck", "checkVersion", "mergeParameters", "profileId", "securityToken", "isNeedAnnouncement", "signal"].includes(key))) {
|
|
3928
|
+
throw new ServiceBehaviorSettingsError("InvalidInput" /* InvalidInput */);
|
|
3929
|
+
}
|
|
3930
|
+
const normalized = normalizeBehaviorInput(settingsPatch);
|
|
3931
|
+
options = { ...options };
|
|
3932
|
+
const state = await this.readBehaviorState(serviceId, {
|
|
3933
|
+
profileId: options.profileId,
|
|
3934
|
+
securityToken: options.securityToken,
|
|
3935
|
+
signal: options.signal
|
|
3752
3936
|
});
|
|
3937
|
+
assertBehaviorPermission(state.operations);
|
|
3938
|
+
if (options.versionToCheck !== void 0 && state.version !== options.versionToCheck) {
|
|
3939
|
+
throw new ServiceBehaviorSettingsError("VersionConflict" /* VersionConflict */);
|
|
3940
|
+
}
|
|
3941
|
+
const tags = mergeBehaviorSettings(state.tags, normalized, options.mergeParameters ?? true);
|
|
3942
|
+
const projected = readBehaviorSettings(tags);
|
|
3943
|
+
const unchanged = tags.length === state.tags.length && tags.every((tag) => state.tags.includes(tag));
|
|
3944
|
+
if (unchanged) return { serviceId, version: state.version, ...projected, changed: false };
|
|
3945
|
+
let dispatched = false;
|
|
3946
|
+
let result;
|
|
3947
|
+
try {
|
|
3948
|
+
result = await this.http.requestJson({
|
|
3949
|
+
method: "PUT",
|
|
3950
|
+
path: `${BASE9}/${encodePathSegment(serviceId)}/tags`,
|
|
3951
|
+
query: { versionToCheck: options.versionToCheck ?? (options.checkVersion ? state.version : void 0), isNeedAnnouncement: options.isNeedAnnouncement ?? false },
|
|
3952
|
+
body: tags,
|
|
3953
|
+
signal: options.signal
|
|
3954
|
+
}, () => {
|
|
3955
|
+
dispatched = true;
|
|
3956
|
+
});
|
|
3957
|
+
} catch (cause) {
|
|
3958
|
+
if (dispatched && cause instanceof TorrowHttpError && cause.status === 500 && cause.body !== null && typeof cause.body === "object" && "name" in cause.body && cause.body.name === "OBJECT_HAS_WRONG_VERSION" /* VersionConflict */ && "code" in cause.body && (cause.body.code === 208213 /* VersionConflict */ || cause.body.code === String(208213 /* VersionConflict */))) {
|
|
3959
|
+
throw new ServiceBehaviorSettingsError("VersionConflict" /* VersionConflict */, cause);
|
|
3960
|
+
}
|
|
3961
|
+
throw new ServiceBehaviorSettingsError(dispatched ? "WriteOutcomeUnknown" /* WriteOutcomeUnknown */ : "RequestNotSent" /* RequestNotSent */, cause);
|
|
3962
|
+
}
|
|
3963
|
+
if (!result || result.id !== serviceId || !isBehaviorVersion(result.meta?.version)) {
|
|
3964
|
+
throw new ServiceBehaviorSettingsError("WriteOutcomeUnknown" /* WriteOutcomeUnknown */);
|
|
3965
|
+
}
|
|
3966
|
+
return { serviceId, version: result.meta.version, ...projected, changed: true };
|
|
3753
3967
|
}
|
|
3754
|
-
/** Полная
|
|
3755
|
-
setBehaviorSettings(serviceId, settings, options) {
|
|
3756
|
-
return this.updateBehaviorSettings(serviceId, settings, {
|
|
3757
|
-
...options,
|
|
3758
|
-
mergeParameters: false
|
|
3759
|
-
});
|
|
3968
|
+
/** Полная замена: пропущенные поля очищаются, посторонние данные сохраняются. */
|
|
3969
|
+
setBehaviorSettings(serviceId, settings, options = {}) {
|
|
3970
|
+
return this.updateBehaviorSettings(serviceId, settings, { ...options, mergeParameters: false });
|
|
3760
3971
|
}
|
|
3761
3972
|
/**
|
|
3762
3973
|
* Запись на услугу — `POST /api/v1/services/{serviceId}/order`.
|
|
@@ -3941,7 +4152,13 @@ var AuthFacade = class {
|
|
|
3941
4152
|
signal: options?.signal
|
|
3942
4153
|
});
|
|
3943
4154
|
}
|
|
3944
|
-
/**
|
|
4155
|
+
/**
|
|
4156
|
+
* `POST /api/v1/auth/token` — обмен `sessionId` / `code` на `TokenResp` (смотри `status`).
|
|
4157
|
+
* `body.splitTokens: false` — полные токены в JSON (Node, MCP, интеграционные ключи).
|
|
4158
|
+
* `true` — сервер возвращает части токенов в JSON и HttpOnly cookies;
|
|
4159
|
+
* приложение обеспечивает передачу cookies, SDK не управляет ими и не восстанавливает токены.
|
|
4160
|
+
* Подробности и выбор режима — в README `@torrow/sdk-auth`, раздел «Когда использовать splitTokens».
|
|
4161
|
+
*/
|
|
3945
4162
|
requestToken(body, options) {
|
|
3946
4163
|
return this.anonHttp.requestJson({
|
|
3947
4164
|
method: "POST",
|
|
@@ -5767,39 +5984,35 @@ function parseSendCodeAccountType(raw) {
|
|
|
5767
5984
|
if (!t) return void 0;
|
|
5768
5985
|
return SendCodeAccountTypeValueList.find((x) => x.toLowerCase() === t.toLowerCase());
|
|
5769
5986
|
}
|
|
5770
|
-
var VerificationMethodValues = {
|
|
5771
|
-
UnknownMethod
|
|
5772
|
-
Sms
|
|
5773
|
-
TelegramGateway
|
|
5774
|
-
FlashCall
|
|
5775
|
-
MtsMobileId
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
VerificationMethodValues.Sms,
|
|
5780
|
-
VerificationMethodValues.TelegramGateway,
|
|
5781
|
-
VerificationMethodValues.FlashCall,
|
|
5782
|
-
VerificationMethodValues.MtsMobileId
|
|
5783
|
-
];
|
|
5987
|
+
var VerificationMethodValues = /* @__PURE__ */ ((VerificationMethodValues2) => {
|
|
5988
|
+
VerificationMethodValues2["UnknownMethod"] = "UnknownMethod";
|
|
5989
|
+
VerificationMethodValues2["Sms"] = "Sms";
|
|
5990
|
+
VerificationMethodValues2["TelegramGateway"] = "TelegramGateway";
|
|
5991
|
+
VerificationMethodValues2["FlashCall"] = "FlashCall";
|
|
5992
|
+
VerificationMethodValues2["MtsMobileId"] = "MtsMobileId";
|
|
5993
|
+
return VerificationMethodValues2;
|
|
5994
|
+
})(VerificationMethodValues || {});
|
|
5995
|
+
var VerificationMethodValueList = Object.values(VerificationMethodValues);
|
|
5784
5996
|
function isVerificationMethod(value) {
|
|
5785
|
-
return VerificationMethodValueList.
|
|
5997
|
+
return VerificationMethodValueList.some((method) => method === value);
|
|
5786
5998
|
}
|
|
5787
5999
|
function parseVerificationMethod(raw) {
|
|
5788
6000
|
const t = raw?.trim();
|
|
5789
6001
|
if (!t) return void 0;
|
|
5790
6002
|
return VerificationMethodValueList.find((x) => x.toLowerCase() === t.toLowerCase());
|
|
5791
6003
|
}
|
|
5792
|
-
var TokenStatusValues = {
|
|
5793
|
-
TokenReady
|
|
5794
|
-
Pending
|
|
5795
|
-
AwaitingSmsCode
|
|
5796
|
-
Failed
|
|
5797
|
-
|
|
6004
|
+
var TokenStatusValues = /* @__PURE__ */ ((TokenStatusValues2) => {
|
|
6005
|
+
TokenStatusValues2["TokenReady"] = "TokenReady";
|
|
6006
|
+
TokenStatusValues2["Pending"] = "Pending";
|
|
6007
|
+
TokenStatusValues2["AwaitingSmsCode"] = "AwaitingSmsCode";
|
|
6008
|
+
TokenStatusValues2["Failed"] = "Failed";
|
|
6009
|
+
return TokenStatusValues2;
|
|
6010
|
+
})(TokenStatusValues || {});
|
|
5798
6011
|
var TokenStatusValueList = [
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
6012
|
+
"TokenReady" /* TokenReady */,
|
|
6013
|
+
"Pending" /* Pending */,
|
|
6014
|
+
"AwaitingSmsCode" /* AwaitingSmsCode */,
|
|
6015
|
+
"Failed" /* Failed */
|
|
5803
6016
|
];
|
|
5804
6017
|
function isTokenStatus(value) {
|
|
5805
6018
|
return TokenStatusValueList.includes(value);
|
|
@@ -5810,7 +6023,7 @@ function parseTokenStatus(raw) {
|
|
|
5810
6023
|
return TokenStatusValueList.find((x) => x.toLowerCase() === t.toLowerCase());
|
|
5811
6024
|
}
|
|
5812
6025
|
function isTokenRespReadyStatus(status) {
|
|
5813
|
-
return status == null || status ===
|
|
6026
|
+
return status == null || status === "TokenReady" /* TokenReady */;
|
|
5814
6027
|
}
|
|
5815
6028
|
var AuthCaptchaTypeValues = {
|
|
5816
6029
|
YandexSmartCaptcha: "YandexSmartCaptcha",
|
|
@@ -7006,6 +7219,9 @@ export {
|
|
|
7006
7219
|
SearchFacade,
|
|
7007
7220
|
SendCodeAccountTypeValueList,
|
|
7008
7221
|
SendCodeAccountTypeValues,
|
|
7222
|
+
ServiceBehaviorSettingsError,
|
|
7223
|
+
ServiceBehaviorSettingsErrorCategory,
|
|
7224
|
+
ServiceBehaviorSettingsIssueReason,
|
|
7009
7225
|
ServiceBuilder,
|
|
7010
7226
|
ServiceCheckInWizardStepParameterName,
|
|
7011
7227
|
ServiceCheckInWizardStepType,
|