@torrow/sdk-client 0.23.0 → 0.25.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 +31 -0
- package/dist/index.d.ts +270 -7
- package/dist/index.js +895 -60
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -126,6 +126,10 @@ var ItemPatchEffectStep = /* @__PURE__ */ ((ItemPatchEffectStep2) => {
|
|
|
126
126
|
ItemPatchEffectStep2["Write"] = "Write";
|
|
127
127
|
return ItemPatchEffectStep2;
|
|
128
128
|
})(ItemPatchEffectStep || {});
|
|
129
|
+
var PlacementEffectStep = /* @__PURE__ */ ((PlacementEffectStep2) => {
|
|
130
|
+
PlacementEffectStep2["Write"] = "Write";
|
|
131
|
+
return PlacementEffectStep2;
|
|
132
|
+
})(PlacementEffectStep || {});
|
|
129
133
|
var AuthSessionEffectStep = /* @__PURE__ */ ((AuthSessionEffectStep2) => {
|
|
130
134
|
AuthSessionEffectStep2["CreateAuthSession"] = "CreateAuthSession";
|
|
131
135
|
AuthSessionEffectStep2["CloseSession"] = "CloseSession";
|
|
@@ -9988,10 +9992,10 @@ function validateOperationNoteTypes(body, method, path) {
|
|
|
9988
9992
|
if (Array.isArray(current) && node.items !== void 0) {
|
|
9989
9993
|
current.forEach((entry, i) => merge(invalidPaths(entry, node.items, `${path2}/${i}`, /* @__PURE__ */ new Set())));
|
|
9990
9994
|
} else if (typeof current === "object" && !Array.isArray(current)) {
|
|
9991
|
-
const
|
|
9995
|
+
const record9 = current;
|
|
9992
9996
|
for (const [key, child] of Object.entries(node.properties ?? {})) {
|
|
9993
|
-
if (Object.hasOwn(
|
|
9994
|
-
merge(invalidPaths(
|
|
9997
|
+
if (Object.hasOwn(record9, key)) {
|
|
9998
|
+
merge(invalidPaths(record9[key], child, `${path2}/${key}`, /* @__PURE__ */ new Set()));
|
|
9995
9999
|
}
|
|
9996
10000
|
}
|
|
9997
10001
|
}
|
|
@@ -11885,7 +11889,7 @@ function copyValue(value, active = /* @__PURE__ */ new Set(), path = [], ridPath
|
|
|
11885
11889
|
if (Array.isArray(value)) {
|
|
11886
11890
|
result = Array.from(value, (child, index) => copyValue(child, active, [...path, index], ridPaths));
|
|
11887
11891
|
} else {
|
|
11888
|
-
const
|
|
11892
|
+
const record9 = {};
|
|
11889
11893
|
for (const key of Reflect.ownKeys(value)) {
|
|
11890
11894
|
if (typeof key !== "string") {
|
|
11891
11895
|
throw itemPatchError("InvalidInput" /* InvalidInput */);
|
|
@@ -11898,14 +11902,14 @@ function copyValue(value, active = /* @__PURE__ */ new Set(), path = [], ridPath
|
|
|
11898
11902
|
if (descriptor.value === void 0 && isPatchRidPath(childPath, ridPaths)) {
|
|
11899
11903
|
continue;
|
|
11900
11904
|
}
|
|
11901
|
-
Object.defineProperty(
|
|
11905
|
+
Object.defineProperty(record9, key, {
|
|
11902
11906
|
value: copyValue(descriptor.value, active, childPath, ridPaths),
|
|
11903
11907
|
enumerable: true,
|
|
11904
11908
|
writable: true,
|
|
11905
11909
|
configurable: true
|
|
11906
11910
|
});
|
|
11907
11911
|
}
|
|
11908
|
-
result =
|
|
11912
|
+
result = record9;
|
|
11909
11913
|
}
|
|
11910
11914
|
active.delete(value);
|
|
11911
11915
|
return result;
|
|
@@ -12322,7 +12326,11 @@ var CalendarsFacade = class extends TorrowItemFacade {
|
|
|
12322
12326
|
signal
|
|
12323
12327
|
}).then((items) => projectReadList(items, (dto) => projectCalendarItem(dto)));
|
|
12324
12328
|
}
|
|
12325
|
-
/**
|
|
12329
|
+
/**
|
|
12330
|
+
* Исходное расписание кейсов календаря — `PUT /api/v1/calendars/{id}/timetable`.
|
|
12331
|
+
* После чтения нужных серверных страниц повторы явно разворачивает `expandRecurringTimetableCases`;
|
|
12332
|
+
* права на исходные строки проверяет сервер.
|
|
12333
|
+
*/
|
|
12326
12334
|
getTimetable(calendarId, body, options) {
|
|
12327
12335
|
const { signal, ...queryOpts } = options ?? {};
|
|
12328
12336
|
return this.http.requestJson({
|
|
@@ -12533,6 +12541,24 @@ function normalizeCaseActionRidsForWrite(body, path) {
|
|
|
12533
12541
|
}
|
|
12534
12542
|
|
|
12535
12543
|
// ../../src/resources/cases/types.ts
|
|
12544
|
+
var AvailabilityTimeValues = /* @__PURE__ */ ((AvailabilityTimeValues2) => {
|
|
12545
|
+
AvailabilityTimeValues2["Unknown"] = "UnknownSystemAvailabilityTime";
|
|
12546
|
+
AvailabilityTimeValues2["Free"] = "Free";
|
|
12547
|
+
AvailabilityTimeValues2["Busy"] = "Busy";
|
|
12548
|
+
return AvailabilityTimeValues2;
|
|
12549
|
+
})(AvailabilityTimeValues || {});
|
|
12550
|
+
var CaseParticipantTypeValues = /* @__PURE__ */ ((CaseParticipantTypeValues2) => {
|
|
12551
|
+
CaseParticipantTypeValues2["Unknown"] = "UnknownCaseParticipantType";
|
|
12552
|
+
CaseParticipantTypeValues2["Consumer"] = "Consumer";
|
|
12553
|
+
CaseParticipantTypeValues2["Executor"] = "Executor";
|
|
12554
|
+
CaseParticipantTypeValues2["Escort"] = "Escort";
|
|
12555
|
+
return CaseParticipantTypeValues2;
|
|
12556
|
+
})(CaseParticipantTypeValues || {});
|
|
12557
|
+
var ShowCaseInTimetableTypeValues = /* @__PURE__ */ ((ShowCaseInTimetableTypeValues2) => {
|
|
12558
|
+
ShowCaseInTimetableTypeValues2["All"] = "All";
|
|
12559
|
+
ShowCaseInTimetableTypeValues2["ExcludeUser"] = "ExcludeUser";
|
|
12560
|
+
return ShowCaseInTimetableTypeValues2;
|
|
12561
|
+
})(ShowCaseInTimetableTypeValues || {});
|
|
12536
12562
|
var CaseStateValues = {
|
|
12537
12563
|
Unknown: "UnknownCaseState",
|
|
12538
12564
|
Verifying: "Verifying",
|
|
@@ -13492,7 +13518,11 @@ var ContactsFacade = class extends TorrowItemFacade {
|
|
|
13492
13518
|
signal
|
|
13493
13519
|
}).then((items) => projectReadList(items, (dto) => projectContactItem(dto)));
|
|
13494
13520
|
}
|
|
13495
|
-
/**
|
|
13521
|
+
/**
|
|
13522
|
+
* Исходное расписание по контакту (профиль/исполнитель) — `PUT /api/v1/contacts/{id}/timetable`.
|
|
13523
|
+
* После чтения нужных серверных страниц повторы явно разворачивает `expandRecurringTimetableCases`;
|
|
13524
|
+
* права на исходные строки проверяет сервер.
|
|
13525
|
+
*/
|
|
13496
13526
|
getTimetable(contactId, body, options) {
|
|
13497
13527
|
const { signal, ...queryOpts } = options ?? {};
|
|
13498
13528
|
return this.http.requestJson({
|
|
@@ -13892,12 +13922,228 @@ var NotesFacade = class extends TorrowItemFacade {
|
|
|
13892
13922
|
}
|
|
13893
13923
|
};
|
|
13894
13924
|
|
|
13925
|
+
// ../../src/resources/views/view-domain-resolver.ts
|
|
13926
|
+
function getCreateViewDomain(childIds) {
|
|
13927
|
+
return getTorrowItemDomainFromTorrowIds(childIds);
|
|
13928
|
+
}
|
|
13929
|
+
function getUpdateViewOrderDomain(orderedViews) {
|
|
13930
|
+
const childIds = orderedViews.flatMap(({ childId }) => childId ? [childId] : []);
|
|
13931
|
+
return getTorrowItemDomainFromTorrowIds(childIds);
|
|
13932
|
+
}
|
|
13933
|
+
|
|
13934
|
+
// ../../src/resources/views/view-paths.ts
|
|
13935
|
+
function viewDomainPath(domain) {
|
|
13936
|
+
return `/api/v1/${domain}`;
|
|
13937
|
+
}
|
|
13938
|
+
function viewParentPath(domain, parentId) {
|
|
13939
|
+
return `${viewDomainPath(domain)}/${encodePathSegment(parentId)}`;
|
|
13940
|
+
}
|
|
13941
|
+
function viewChildPath(domain, parentId, kind, childId) {
|
|
13942
|
+
return `${viewParentPath(domain, parentId)}/views/${kind}/${encodePathSegment(childId)}`;
|
|
13943
|
+
}
|
|
13944
|
+
|
|
13945
|
+
// ../../src/resources/relations/placement-types.ts
|
|
13946
|
+
var PlacementKindValues = /* @__PURE__ */ ((PlacementKindValues2) => {
|
|
13947
|
+
PlacementKindValues2["User"] = "User";
|
|
13948
|
+
PlacementKindValues2["Pinned"] = "Pinned";
|
|
13949
|
+
return PlacementKindValues2;
|
|
13950
|
+
})(PlacementKindValues || {});
|
|
13951
|
+
var PlacementWriteStatusValues = /* @__PURE__ */ ((PlacementWriteStatusValues2) => {
|
|
13952
|
+
PlacementWriteStatusValues2["Applied"] = "Applied";
|
|
13953
|
+
PlacementWriteStatusValues2["NoOp"] = "NoOp";
|
|
13954
|
+
PlacementWriteStatusValues2["Unknown"] = "Unknown";
|
|
13955
|
+
return PlacementWriteStatusValues2;
|
|
13956
|
+
})(PlacementWriteStatusValues || {});
|
|
13957
|
+
|
|
13958
|
+
// ../../src/resources/relations/PlacementFacade.ts
|
|
13959
|
+
function record5(value) {
|
|
13960
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
13961
|
+
}
|
|
13962
|
+
function matchesKey(key, parentId, childId) {
|
|
13963
|
+
return key?.parentId === parentId && key.itemId === childId;
|
|
13964
|
+
}
|
|
13965
|
+
function invalidResponse(body) {
|
|
13966
|
+
return new TorrowSdkError({ category: "InvalidResponse" /* InvalidResponse */, sensitive: { body } });
|
|
13967
|
+
}
|
|
13968
|
+
function writeError(cause, dispatched, operation) {
|
|
13969
|
+
const error = cause instanceof TorrowSdkError ? cause : new TorrowSdkError({ category: "Unknown" /* Unknown */, sensitive: { cause } });
|
|
13970
|
+
return error.withContext({
|
|
13971
|
+
operation,
|
|
13972
|
+
request: dispatched ? "Started" /* Started */ : "NotStarted" /* NotStarted */,
|
|
13973
|
+
effects: [
|
|
13974
|
+
{
|
|
13975
|
+
area: "Remote" /* Remote */,
|
|
13976
|
+
step: "Write" /* Write */,
|
|
13977
|
+
state: dispatched ? "Unknown" /* Unknown */ : "NotApplied" /* NotApplied */
|
|
13978
|
+
}
|
|
13979
|
+
]
|
|
13980
|
+
});
|
|
13981
|
+
}
|
|
13982
|
+
var PlacementFacade = class {
|
|
13983
|
+
constructor(http) {
|
|
13984
|
+
this.http = http;
|
|
13985
|
+
}
|
|
13986
|
+
http;
|
|
13987
|
+
/** Читает ровно одну пару; HTTP-отказ, включая 404, не доказывает отсутствие связи. */
|
|
13988
|
+
async get(parentId, childId, kind, options) {
|
|
13989
|
+
const domain = getTorrowItemDomainFromTorrowId(childId);
|
|
13990
|
+
const path = viewChildPath(domain, parentId, kind === "User" /* User */ ? "user" : "pinned", childId);
|
|
13991
|
+
const view = await this.http.requestJson({ method: "GET", path, signal: options?.signal });
|
|
13992
|
+
const link = record5(view?.itemLink);
|
|
13993
|
+
if (!link || link.parentId !== parentId || link.itemId !== childId || link.linkType !== kind) {
|
|
13994
|
+
throw invalidResponse(view);
|
|
13995
|
+
}
|
|
13996
|
+
const order = link.order;
|
|
13997
|
+
if (order !== void 0 && order !== null && (!Number.isInteger(order) || typeof order !== "number")) {
|
|
13998
|
+
throw invalidResponse(view);
|
|
13999
|
+
}
|
|
14000
|
+
const base = {
|
|
14001
|
+
parentId,
|
|
14002
|
+
childId,
|
|
14003
|
+
...order !== void 0 ? { order } : {}
|
|
14004
|
+
};
|
|
14005
|
+
if (kind === "User" /* User */) {
|
|
14006
|
+
return { ...base, kind };
|
|
14007
|
+
}
|
|
14008
|
+
const alias = link.alias;
|
|
14009
|
+
const tags = link.tags;
|
|
14010
|
+
if (alias !== void 0 && alias !== null && typeof alias !== "string" || tags !== void 0 && tags !== null && (!Array.isArray(tags) || tags.some((tag) => typeof tag !== "string"))) {
|
|
14011
|
+
throw invalidResponse(view);
|
|
14012
|
+
}
|
|
14013
|
+
return {
|
|
14014
|
+
...base,
|
|
14015
|
+
kind,
|
|
14016
|
+
...alias !== void 0 ? { alias } : {},
|
|
14017
|
+
...tags !== void 0 ? { tags } : {}
|
|
14018
|
+
};
|
|
14019
|
+
}
|
|
14020
|
+
/** Создаёт одну пару. Backend может сначала снять противоположный вид без общей транзакции. */
|
|
14021
|
+
async attach(input, options) {
|
|
14022
|
+
const domain = getTorrowItemDomainFromTorrowId(input.parentId);
|
|
14023
|
+
let dispatched = false;
|
|
14024
|
+
try {
|
|
14025
|
+
const itemProperties = {
|
|
14026
|
+
itemId: input.childId,
|
|
14027
|
+
...input.order !== void 0 ? { order: input.order } : {},
|
|
14028
|
+
...input.kind === "Pinned" /* Pinned */ && input.alias !== void 0 ? { alias: input.alias } : {},
|
|
14029
|
+
...input.kind === "Pinned" /* Pinned */ && input.tags !== void 0 ? { tags: input.tags } : {}
|
|
14030
|
+
};
|
|
14031
|
+
const resp = await this.http.requestJson(
|
|
14032
|
+
{
|
|
14033
|
+
method: "PUT",
|
|
14034
|
+
path: `/api/v1/${domain}/${encodePathSegment(input.parentId)}/include/${input.kind === "User" /* User */ ? "foruser" : "items"}`,
|
|
14035
|
+
body: { itemPropertiesList: [itemProperties] },
|
|
14036
|
+
signal: options?.signal
|
|
14037
|
+
},
|
|
14038
|
+
() => {
|
|
14039
|
+
dispatched = true;
|
|
14040
|
+
}
|
|
14041
|
+
);
|
|
14042
|
+
const included = resp?.includeResp;
|
|
14043
|
+
const excluded = resp?.excludeResp;
|
|
14044
|
+
if (included?.success !== true || !Array.isArray(included.linkMetaList)) {
|
|
14045
|
+
throw invalidResponse(resp);
|
|
14046
|
+
}
|
|
14047
|
+
if (included.linkMetaList.some(
|
|
14048
|
+
(entry) => !matchesKey(entry.key, input.parentId, input.childId) || record5(entry.info) === null
|
|
14049
|
+
)) {
|
|
14050
|
+
throw invalidResponse(resp);
|
|
14051
|
+
}
|
|
14052
|
+
const status = included.linkMetaList.length > 0 ? "Applied" /* Applied */ : "NoOp" /* NoOp */;
|
|
14053
|
+
let oppositeStatus = "Unknown" /* Unknown */;
|
|
14054
|
+
if (excluded?.success === true && Array.isArray(excluded.linkMetaList)) {
|
|
14055
|
+
if (excluded.linkMetaList.some(
|
|
14056
|
+
(entry) => !matchesKey(entry.key, input.parentId, input.childId) || !Number.isInteger(entry.count) || (entry.count ?? 0) <= 0
|
|
14057
|
+
)) {
|
|
14058
|
+
throw invalidResponse(resp);
|
|
14059
|
+
}
|
|
14060
|
+
oppositeStatus = excluded.linkMetaList.length > 0 ? "Applied" /* Applied */ : "NoOp" /* NoOp */;
|
|
14061
|
+
}
|
|
14062
|
+
return { parentId: input.parentId, childId: input.childId, kind: input.kind, status, oppositeStatus };
|
|
14063
|
+
} catch (cause) {
|
|
14064
|
+
throw writeError(cause, dispatched, "Placement.attach");
|
|
14065
|
+
}
|
|
14066
|
+
}
|
|
14067
|
+
/** Снимает только запрошенную пару и вид, без readback или повтора. */
|
|
14068
|
+
async detach(parentId, childId, kind, options) {
|
|
14069
|
+
const domain = getTorrowItemDomainFromTorrowId(parentId);
|
|
14070
|
+
let dispatched = false;
|
|
14071
|
+
try {
|
|
14072
|
+
const resp = await this.http.requestJson(
|
|
14073
|
+
{
|
|
14074
|
+
method: "PUT",
|
|
14075
|
+
path: `/api/v1/${domain}/${encodePathSegment(parentId)}/exclude/${kind === "User" /* User */ ? "fromuser" : "items"}`,
|
|
14076
|
+
body: { itemIds: [childId] },
|
|
14077
|
+
signal: options?.signal
|
|
14078
|
+
},
|
|
14079
|
+
() => {
|
|
14080
|
+
dispatched = true;
|
|
14081
|
+
}
|
|
14082
|
+
);
|
|
14083
|
+
if (resp?.success !== true || !Array.isArray(resp.linkMetaList)) {
|
|
14084
|
+
throw invalidResponse(resp);
|
|
14085
|
+
}
|
|
14086
|
+
if (resp.linkMetaList.some((entry) => !matchesKey(entry.key, parentId, childId))) {
|
|
14087
|
+
throw invalidResponse(resp);
|
|
14088
|
+
}
|
|
14089
|
+
const count = resp.linkMetaList.reduce((total, entry) => total + (entry.count ?? 0), 0);
|
|
14090
|
+
if (!Number.isInteger(count) || resp.linkMetaList.some((entry) => !Number.isInteger(entry.count) || (entry.count ?? 0) <= 0)) {
|
|
14091
|
+
throw invalidResponse(resp);
|
|
14092
|
+
}
|
|
14093
|
+
return {
|
|
14094
|
+
parentId,
|
|
14095
|
+
childId,
|
|
14096
|
+
kind,
|
|
14097
|
+
status: count > 0 ? "Applied" /* Applied */ : "NoOp" /* NoOp */
|
|
14098
|
+
};
|
|
14099
|
+
} catch (cause) {
|
|
14100
|
+
throw writeError(cause, dispatched, "Placement.detach");
|
|
14101
|
+
}
|
|
14102
|
+
}
|
|
14103
|
+
/** Изменяет явные веса одним серверным вызовом; результат каждого ребёнка проверяется отдельно. */
|
|
14104
|
+
async reorder(parentId, kind, items, options) {
|
|
14105
|
+
const domain = getUpdateViewOrderDomain(items);
|
|
14106
|
+
let dispatched = false;
|
|
14107
|
+
try {
|
|
14108
|
+
const resp = await this.http.requestJson(
|
|
14109
|
+
{
|
|
14110
|
+
method: "POST",
|
|
14111
|
+
path: `${viewParentPath(domain, parentId)}/views/${kind === "User" /* User */ ? "user" : "pinned"}/updateorder`,
|
|
14112
|
+
body: { orderedViewList: items },
|
|
14113
|
+
signal: options?.signal
|
|
14114
|
+
},
|
|
14115
|
+
() => {
|
|
14116
|
+
dispatched = true;
|
|
14117
|
+
}
|
|
14118
|
+
);
|
|
14119
|
+
if (!Array.isArray(resp?.updatedViewInfoList)) {
|
|
14120
|
+
throw invalidResponse(resp);
|
|
14121
|
+
}
|
|
14122
|
+
return items.map((item) => {
|
|
14123
|
+
const matches = resp.updatedViewInfoList?.filter((entry) => matchesKey(entry.itemLinkKey, parentId, item.childId)) ?? [];
|
|
14124
|
+
const applied = matches.length === 1 && !matches[0].torrowError && record5(matches[0].itemLinkInfo) !== null;
|
|
14125
|
+
return {
|
|
14126
|
+
parentId,
|
|
14127
|
+
childId: item.childId,
|
|
14128
|
+
kind,
|
|
14129
|
+
status: applied ? "Applied" /* Applied */ : "Unknown" /* Unknown */
|
|
14130
|
+
};
|
|
14131
|
+
});
|
|
14132
|
+
} catch (cause) {
|
|
14133
|
+
throw writeError(cause, dispatched, "Placement.reorder");
|
|
14134
|
+
}
|
|
14135
|
+
}
|
|
14136
|
+
};
|
|
14137
|
+
|
|
13895
14138
|
// ../../src/resources/relations/RelationsFacade.ts
|
|
13896
14139
|
var RelationsFacade = class {
|
|
13897
14140
|
constructor(http) {
|
|
13898
14141
|
this.http = http;
|
|
14142
|
+
this.placements = new PlacementFacade(http);
|
|
13899
14143
|
}
|
|
13900
14144
|
http;
|
|
14145
|
+
/** Точные User/Pinned связи с проверенным ACK отдельного вызова. */
|
|
14146
|
+
placements;
|
|
13901
14147
|
base(domain) {
|
|
13902
14148
|
return `/api/v1/${domain}`;
|
|
13903
14149
|
}
|
|
@@ -13920,7 +14166,8 @@ var RelationsFacade = class {
|
|
|
13920
14166
|
* в личную структуру пользователя под указанным родителем (`LinkType.User`).
|
|
13921
14167
|
* Это batch-операция: `parentId` задаётся в path, а дочерние item'ы передаются
|
|
13922
14168
|
* первым аргументом как `itemPropertiesList` (`itemId`, опционально `order`).
|
|
13923
|
-
* Канон torrow-apps для сохранения одного item — {@link saveToMindMap}
|
|
14169
|
+
* Канон torrow-apps для участия и сохранения одного item — {@link saveToMindMap}.
|
|
14170
|
+
* Для placement-only одной существующей пары используйте {@link placements}.
|
|
13924
14171
|
*/
|
|
13925
14172
|
includeForUser(parentId, itemPropertiesList, options) {
|
|
13926
14173
|
const domain = getTorrowItemDomainFromTorrowId(parentId);
|
|
@@ -14472,11 +14719,11 @@ var providers = {
|
|
|
14472
14719
|
strings: ["redirectBaseUrl"]
|
|
14473
14720
|
}
|
|
14474
14721
|
};
|
|
14475
|
-
function
|
|
14722
|
+
function record6(value) {
|
|
14476
14723
|
return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
14477
14724
|
}
|
|
14478
14725
|
function isResourcePaymentPatch(value) {
|
|
14479
|
-
if (!
|
|
14726
|
+
if (!record6(value) || Object.keys(value).some(
|
|
14480
14727
|
(key) => !["paymentProviderType", "parameters", "numeratorId", "waitForConfirmation"].includes(key)
|
|
14481
14728
|
)) {
|
|
14482
14729
|
return false;
|
|
@@ -14496,7 +14743,7 @@ function isResourcePaymentPatch(value) {
|
|
|
14496
14743
|
if (value.parameters == null) {
|
|
14497
14744
|
return guarded;
|
|
14498
14745
|
}
|
|
14499
|
-
if (!
|
|
14746
|
+
if (!record6(value.parameters)) {
|
|
14500
14747
|
return false;
|
|
14501
14748
|
}
|
|
14502
14749
|
const parameters = value.parameters;
|
|
@@ -14525,7 +14772,7 @@ function isResourcePaymentPatch(value) {
|
|
|
14525
14772
|
});
|
|
14526
14773
|
}
|
|
14527
14774
|
function paymentPatchToWire(value) {
|
|
14528
|
-
if (!
|
|
14775
|
+
if (!record6(value) || !record6(value.parameters)) {
|
|
14529
14776
|
return value;
|
|
14530
14777
|
}
|
|
14531
14778
|
const shape2 = providers[value.paymentProviderType];
|
|
@@ -14542,7 +14789,7 @@ function equalResourcePaymentPatchField(key, before, after) {
|
|
|
14542
14789
|
return void 0;
|
|
14543
14790
|
}
|
|
14544
14791
|
const expected = paymentPatchToWire(after);
|
|
14545
|
-
if (
|
|
14792
|
+
if (record6(before) && record6(expected) && before.paymentProviderType === "MockPaymentProvider" /* Mock */ && expected.paymentProviderType === "MockPaymentProvider" /* Mock */ && record6(before.parameters) && record6(expected.parameters) && expected.parameters.createAfter instanceof Date && typeof before.parameters.createAfter === "string") {
|
|
14546
14793
|
const date2 = new Date(before.parameters.createAfter);
|
|
14547
14794
|
if (!Number.isFinite(date2.getTime())) {
|
|
14548
14795
|
return false;
|
|
@@ -14661,7 +14908,7 @@ function invalidInput() {
|
|
|
14661
14908
|
function insufficientData() {
|
|
14662
14909
|
throw itemPatchError("InsufficientData" /* InsufficientData */);
|
|
14663
14910
|
}
|
|
14664
|
-
function
|
|
14911
|
+
function invalidResponse2() {
|
|
14665
14912
|
throw itemPatchError("InvalidResponse" /* InvalidResponse */);
|
|
14666
14913
|
}
|
|
14667
14914
|
function validateSelector(selector) {
|
|
@@ -14707,26 +14954,26 @@ function checkedDescriptions(dto) {
|
|
|
14707
14954
|
insufficientData();
|
|
14708
14955
|
}
|
|
14709
14956
|
if (!Array.isArray(list)) {
|
|
14710
|
-
|
|
14957
|
+
invalidResponse2();
|
|
14711
14958
|
}
|
|
14712
14959
|
const seen = /* @__PURE__ */ new Set();
|
|
14713
14960
|
for (const binding of list) {
|
|
14714
14961
|
if (binding === null || typeof binding !== "object" || Array.isArray(binding) || typeof binding.id !== "string" || typeof binding.resourceGroupId !== "string" || binding.resourceGroupId.length === 0) {
|
|
14715
|
-
|
|
14962
|
+
invalidResponse2();
|
|
14716
14963
|
}
|
|
14717
14964
|
try {
|
|
14718
14965
|
if (getTorrowObjectTypeFromTorrowId(binding.id) !== "Service") {
|
|
14719
|
-
|
|
14966
|
+
invalidResponse2();
|
|
14720
14967
|
}
|
|
14721
14968
|
} catch {
|
|
14722
|
-
|
|
14969
|
+
invalidResponse2();
|
|
14723
14970
|
}
|
|
14724
14971
|
if (binding.serviceName != null && typeof binding.serviceName !== "string" || binding.resourceGroupName != null && typeof binding.resourceGroupName !== "string" || binding.laterBinding != null && typeof binding.laterBinding !== "boolean" || binding.usageAmount != null && (typeof binding.usageAmount !== "number" || !Number.isFinite(binding.usageAmount)) || binding.sortIndex != null && (typeof binding.sortIndex !== "number" || !Number.isInteger(binding.sortIndex) || binding.sortIndex < -2147483648 || binding.sortIndex > 2147483647)) {
|
|
14725
|
-
|
|
14972
|
+
invalidResponse2();
|
|
14726
14973
|
}
|
|
14727
14974
|
const pair = `${binding.id.length}:${binding.id}${binding.resourceGroupId}`;
|
|
14728
14975
|
if (seen.has(pair)) {
|
|
14729
|
-
|
|
14976
|
+
invalidResponse2();
|
|
14730
14977
|
}
|
|
14731
14978
|
seen.add(pair);
|
|
14732
14979
|
}
|
|
@@ -14768,7 +15015,7 @@ async function changeResourceServiceLink(http, project, resourceId, selector, op
|
|
|
14768
15015
|
signal
|
|
14769
15016
|
});
|
|
14770
15017
|
if (service === null || typeof service !== "object" || Array.isArray(service) || service.id !== selected.serviceId) {
|
|
14771
|
-
|
|
15018
|
+
invalidResponse2();
|
|
14772
15019
|
}
|
|
14773
15020
|
const groups = service.resourceGroupList;
|
|
14774
15021
|
if (!Array.isArray(groups)) {
|
|
@@ -14776,14 +15023,14 @@ async function changeResourceServiceLink(http, project, resourceId, selector, op
|
|
|
14776
15023
|
}
|
|
14777
15024
|
const matchingGroups = groups.filter((item) => item?.groupId === selected.resourceGroupId);
|
|
14778
15025
|
if (matchingGroups.length > 1) {
|
|
14779
|
-
|
|
15026
|
+
invalidResponse2();
|
|
14780
15027
|
}
|
|
14781
15028
|
const group = matchingGroups[0];
|
|
14782
15029
|
if (!group || typeof group.usageType !== "string" || group.usageType.length === 0 || typeof group.groupName !== "string" || typeof service.name !== "string") {
|
|
14783
15030
|
insufficientData();
|
|
14784
15031
|
}
|
|
14785
15032
|
if (group.usageType === UsageTypeValues.Unknown || !Object.values(UsageTypeValues).some((value) => value === group.usageType)) {
|
|
14786
|
-
|
|
15033
|
+
invalidResponse2();
|
|
14787
15034
|
}
|
|
14788
15035
|
if (dto.usageType !== group.usageType) {
|
|
14789
15036
|
invalidInput();
|
|
@@ -14806,13 +15053,13 @@ async function changeResourceServiceLink(http, project, resourceId, selector, op
|
|
|
14806
15053
|
},
|
|
14807
15054
|
assertAck(ack, written) {
|
|
14808
15055
|
if (!before || !expected || !Array.isArray(ack.serviceDescriptions) || !equalItemPatchValue(ack.serviceDescriptions, expected) || !Number.isInteger(ack.meta?.version) || (ack.meta?.version ?? 0) <= 0) {
|
|
14809
|
-
|
|
15056
|
+
invalidResponse2();
|
|
14810
15057
|
}
|
|
14811
15058
|
const rawAck = ack;
|
|
14812
15059
|
const rawWritten = written;
|
|
14813
15060
|
for (const key of preservedRootFields) {
|
|
14814
15061
|
if (Object.hasOwn(before, key) && !equalItemPatchValue(rawAck[key], rawWritten[key])) {
|
|
14815
|
-
|
|
15062
|
+
invalidResponse2();
|
|
14816
15063
|
}
|
|
14817
15064
|
}
|
|
14818
15065
|
acknowledged = ack.serviceDescriptions;
|
|
@@ -15095,6 +15342,8 @@ var ResourcesFacade = class extends TorrowItemFacade {
|
|
|
15095
15342
|
}
|
|
15096
15343
|
/**
|
|
15097
15344
|
* Расписание заказов, привязанных к **ресурсу** — `PUT /api/v1/resources/{id}/timetable`.
|
|
15345
|
+
* Возвращает исходные строки сервера. Повторы разворачивает отдельный
|
|
15346
|
+
* `expandRecurringTimetableCases` после загрузки нужных страниц; права проверяет сервер.
|
|
15098
15347
|
*/
|
|
15099
15348
|
getTimetable(resourceId, body, options) {
|
|
15100
15349
|
const { signal, ...queryOpts } = options ?? {};
|
|
@@ -15336,18 +15585,18 @@ var configs = Object.values(SERVICE_IMPLICIT_TAG_REGISTRY);
|
|
|
15336
15585
|
function isBehaviorVersion(value) {
|
|
15337
15586
|
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 2147483647;
|
|
15338
15587
|
}
|
|
15339
|
-
function
|
|
15588
|
+
function record7(value) {
|
|
15340
15589
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15341
15590
|
}
|
|
15342
15591
|
function validateBehaviorResponse(value, serviceId) {
|
|
15343
|
-
if (!
|
|
15592
|
+
if (!record7(value) || value.id !== serviceId) {
|
|
15344
15593
|
throw behaviorSettingsError("InvalidResponse" /* InvalidResponse */);
|
|
15345
15594
|
}
|
|
15346
15595
|
const personal = value.personalInfo;
|
|
15347
|
-
if (
|
|
15596
|
+
if (record7(personal) && (personal.itemContentType === "NoRights" /* NoRights */ || personal.itemContentType === "SubscriptionIsNotValid" /* SubscriptionIsNotValid */)) {
|
|
15348
15597
|
throw behaviorSettingsError("AccessDenied" /* AccessDenied */);
|
|
15349
15598
|
}
|
|
15350
|
-
if (!
|
|
15599
|
+
if (!record7(personal) || personal.itemContentType !== "Full" /* Full */ || value.tags == null || !record7(value.meta) || !isBehaviorVersion(value.meta.version)) {
|
|
15351
15600
|
throw behaviorSettingsError("InsufficientData" /* InsufficientData */);
|
|
15352
15601
|
}
|
|
15353
15602
|
if (!Array.isArray(value.tags) || !value.tags.every((tag) => typeof tag === "string")) {
|
|
@@ -15476,7 +15725,7 @@ function normalizeBehaviorInput(input) {
|
|
|
15476
15725
|
function fail() {
|
|
15477
15726
|
throw behaviorSettingsError("InvalidInput" /* InvalidInput */);
|
|
15478
15727
|
}
|
|
15479
|
-
if (!
|
|
15728
|
+
if (!record7(input) || Object.keys(input).some((key) => !Object.hasOwn(SERVICE_IMPLICIT_TAG_REGISTRY, key))) {
|
|
15480
15729
|
fail();
|
|
15481
15730
|
}
|
|
15482
15731
|
const output = {};
|
|
@@ -15506,7 +15755,7 @@ function normalizeBehaviorInput(input) {
|
|
|
15506
15755
|
}
|
|
15507
15756
|
const seen = /* @__PURE__ */ new Set();
|
|
15508
15757
|
output[config.field] = value.map((entry) => {
|
|
15509
|
-
if (!
|
|
15758
|
+
if (!record7(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)) {
|
|
15510
15759
|
fail();
|
|
15511
15760
|
}
|
|
15512
15761
|
seen.add(entry.index);
|
|
@@ -15801,6 +16050,8 @@ var ServicesFacade = class extends TorrowItemFacade {
|
|
|
15801
16050
|
/**
|
|
15802
16051
|
* События/заказы и занятость услуги — `PUT /api/v1/services/{serviceId}/timetable`.
|
|
15803
16052
|
* Не вычисляет свободные слоты записи: для них используй `getCheckInSchedule` с `type: "FreeTimeSlots"`.
|
|
16053
|
+
* Возвращает исходные `TimetableCase[]`; серверный `take/skip` не считает виртуальные появления.
|
|
16054
|
+
* После чтения нужных страниц вызови `expandRecurringTimetableCases` явно; доступ проверяет сервер.
|
|
15804
16055
|
*/
|
|
15805
16056
|
getTimetable(serviceId, body, options) {
|
|
15806
16057
|
const { signal, ...queryOpts } = options ?? {};
|
|
@@ -16241,26 +16492,6 @@ var ProfilesFacade = class {
|
|
|
16241
16492
|
}
|
|
16242
16493
|
};
|
|
16243
16494
|
|
|
16244
|
-
// ../../src/resources/views/view-domain-resolver.ts
|
|
16245
|
-
function getCreateViewDomain(childIds) {
|
|
16246
|
-
return getTorrowItemDomainFromTorrowIds(childIds);
|
|
16247
|
-
}
|
|
16248
|
-
function getUpdateViewOrderDomain(orderedViews) {
|
|
16249
|
-
const childIds = orderedViews.flatMap(({ childId }) => childId ? [childId] : []);
|
|
16250
|
-
return getTorrowItemDomainFromTorrowIds(childIds);
|
|
16251
|
-
}
|
|
16252
|
-
|
|
16253
|
-
// ../../src/resources/views/view-paths.ts
|
|
16254
|
-
function viewDomainPath(domain) {
|
|
16255
|
-
return `/api/v1/${domain}`;
|
|
16256
|
-
}
|
|
16257
|
-
function viewParentPath(domain, parentId) {
|
|
16258
|
-
return `${viewDomainPath(domain)}/${encodePathSegment(parentId)}`;
|
|
16259
|
-
}
|
|
16260
|
-
function viewChildPath(domain, parentId, kind, childId) {
|
|
16261
|
-
return `${viewParentPath(domain, parentId)}/views/${kind}/${encodePathSegment(childId)}`;
|
|
16262
|
-
}
|
|
16263
|
-
|
|
16264
16495
|
// ../../src/resources/views/PinnedViewsFacade.ts
|
|
16265
16496
|
var PinnedViewsFacade = class {
|
|
16266
16497
|
constructor(http) {
|
|
@@ -16453,7 +16684,9 @@ var ViewsFacade = class {
|
|
|
16453
16684
|
pinned;
|
|
16454
16685
|
/**
|
|
16455
16686
|
* `POST /api/v1/{domain}/{parentId}/views/user/{childId}/pin` — переход **User → Pinned**.
|
|
16456
|
-
*
|
|
16687
|
+
* Внутри backend сначала снимается User-связь, затем создаётся Pinned; общей транзакции нет.
|
|
16688
|
+
* Query `alias` принимается маршрутом, но текущий ViewLayer его не применяет.
|
|
16689
|
+
* Создание исходной User view: `client.views.user.create` или `client.relations.placements.attach`.
|
|
16457
16690
|
*/
|
|
16458
16691
|
pin(parentId, childId, options) {
|
|
16459
16692
|
const { signal, alias } = options ?? {};
|
|
@@ -16467,6 +16700,8 @@ var ViewsFacade = class {
|
|
|
16467
16700
|
}
|
|
16468
16701
|
/**
|
|
16469
16702
|
* Переход **Pinned → User**. Для `contacts` API использует сегмент `pinned`, для остальных доменов — `user`.
|
|
16703
|
+
* Внутри backend сначала снимается Pinned-связь, затем создаётся User; общей транзакции нет.
|
|
16704
|
+
* Query `alias` принимается маршрутом, но текущий ViewLayer его не применяет.
|
|
16470
16705
|
*/
|
|
16471
16706
|
unpin(parentId, childId, options) {
|
|
16472
16707
|
const { signal, alias } = options ?? {};
|
|
@@ -17397,6 +17632,8 @@ var LoyaltyCardsFacade = class extends TorrowItemCoreFacade {
|
|
|
17397
17632
|
/**
|
|
17398
17633
|
* Расписание по карте — `PUT /api/v1/loyaltycards/{torrowId}/timetable`.
|
|
17399
17634
|
* В torrow-apps: `LoyaltyCardClient.getTimetable`.
|
|
17635
|
+
* Возвращает исходные строки сервера; после чтения нужных страниц повторы явно
|
|
17636
|
+
* разворачивает `expandRecurringTimetableCases`. Права на исходные строки проверяет сервер.
|
|
17400
17637
|
*/
|
|
17401
17638
|
getTimetable(torrowId, body, options) {
|
|
17402
17639
|
const { signal, ...queryOpts } = options ?? {};
|
|
@@ -17474,6 +17711,38 @@ var UserSettingsFacade = class {
|
|
|
17474
17711
|
});
|
|
17475
17712
|
return { settings: parseOpaqueJsonSettings(dto.settings) };
|
|
17476
17713
|
}
|
|
17714
|
+
/**
|
|
17715
|
+
* Читает проверенную IANA-зону текущего пользователя из `settings.place.timeZone`.
|
|
17716
|
+
* Отсутствующая, повреждённая или не поддержанная средой зона даёт `null`.
|
|
17717
|
+
* Ошибки GET и отмена запроса сохраняются; зона процесса не используется.
|
|
17718
|
+
*/
|
|
17719
|
+
async getTimeZone(options) {
|
|
17720
|
+
const { settings } = await this.get(options);
|
|
17721
|
+
if (settings === null || settings === void 0 || typeof settings !== "object" || Array.isArray(settings)) {
|
|
17722
|
+
return null;
|
|
17723
|
+
}
|
|
17724
|
+
const place = settings.place;
|
|
17725
|
+
if (place === null || typeof place !== "object" || Array.isArray(place)) {
|
|
17726
|
+
return null;
|
|
17727
|
+
}
|
|
17728
|
+
const rawTimeZone = place.timeZone;
|
|
17729
|
+
if (typeof rawTimeZone !== "string") {
|
|
17730
|
+
return null;
|
|
17731
|
+
}
|
|
17732
|
+
const timeZone = rawTimeZone.trim();
|
|
17733
|
+
if (timeZone === "" || /^[+-]/.test(timeZone)) {
|
|
17734
|
+
return null;
|
|
17735
|
+
}
|
|
17736
|
+
try {
|
|
17737
|
+
new Intl.DateTimeFormat("en-US", { timeZone });
|
|
17738
|
+
return timeZone;
|
|
17739
|
+
} catch (error) {
|
|
17740
|
+
if (error instanceof RangeError) {
|
|
17741
|
+
return null;
|
|
17742
|
+
}
|
|
17743
|
+
throw error;
|
|
17744
|
+
}
|
|
17745
|
+
}
|
|
17477
17746
|
/**
|
|
17478
17747
|
* `PUT /api/v1/user/settings/update` — принимает JSON в `settings`, на wire уходит string.
|
|
17479
17748
|
* `null`/`undefined` → `settings: null` в теле.
|
|
@@ -17712,7 +17981,11 @@ var UserFacade = class {
|
|
|
17712
17981
|
signal: options?.signal
|
|
17713
17982
|
});
|
|
17714
17983
|
}
|
|
17715
|
-
/**
|
|
17984
|
+
/**
|
|
17985
|
+
* Исходные события текущего пользователя — `PUT /api/v1/user/timetable`.
|
|
17986
|
+
* `take/skip` делят серверные строки; повторы явно разворачивает `expandRecurringTimetableCases`
|
|
17987
|
+
* после чтения нужных страниц. Права на строки определяет сервер.
|
|
17988
|
+
*/
|
|
17716
17989
|
getTimetable(body, query, options) {
|
|
17717
17990
|
return this.http.requestJson({
|
|
17718
17991
|
method: "PUT",
|
|
@@ -17941,12 +18214,12 @@ var IntegrationEventTypeValues = /* @__PURE__ */ ((IntegrationEventTypeValues2)
|
|
|
17941
18214
|
IntegrationEventTypeValues2["UpdateOrder"] = "UpdateOrder";
|
|
17942
18215
|
return IntegrationEventTypeValues2;
|
|
17943
18216
|
})(IntegrationEventTypeValues || {});
|
|
17944
|
-
function
|
|
18217
|
+
function record8(value) {
|
|
17945
18218
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17946
18219
|
}
|
|
17947
18220
|
function hasReadEnvelope(value, type, discriminator) {
|
|
17948
|
-
return
|
|
17949
|
-
(event) =>
|
|
18221
|
+
return record8(value) && typeof value.name === "string" && value.integrationType === type && value.discriminator === discriminator && record8(value.integrationParameters) && Array.isArray(value.integrationEvents) && Array.from(value.integrationEvents).every(
|
|
18222
|
+
(event) => record8(event) && typeof event.rid === "string" && typeof event.eventType === "string" && Object.values(IntegrationEventTypeValues).some((known) => known === event.eventType)
|
|
17950
18223
|
);
|
|
17951
18224
|
}
|
|
17952
18225
|
function isExternalCalendarIntegration(value) {
|
|
@@ -17954,8 +18227,8 @@ function isExternalCalendarIntegration(value) {
|
|
|
17954
18227
|
return false;
|
|
17955
18228
|
}
|
|
17956
18229
|
const parameters = value.integrationParameters;
|
|
17957
|
-
return
|
|
17958
|
-
(calendar) =>
|
|
18230
|
+
return record8(parameters) && Array.isArray(parameters.externalCalendars) && Array.from(parameters.externalCalendars).every(
|
|
18231
|
+
(calendar) => record8(calendar) && typeof calendar.externalAuthId === "string"
|
|
17959
18232
|
);
|
|
17960
18233
|
}
|
|
17961
18234
|
function isVideoTelephonyIntegration(value) {
|
|
@@ -17963,7 +18236,7 @@ function isVideoTelephonyIntegration(value) {
|
|
|
17963
18236
|
return false;
|
|
17964
18237
|
}
|
|
17965
18238
|
const parameters = value.integrationParameters;
|
|
17966
|
-
return
|
|
18239
|
+
return record8(parameters) && record8(parameters.videoTelephony) && typeof parameters.videoTelephony.externalAuthId === "string";
|
|
17967
18240
|
}
|
|
17968
18241
|
function isWebHookIntegration(integration) {
|
|
17969
18242
|
return typeof integration === "object" && integration !== null && "name" in integration && typeof integration.name === "string" && "integrationType" in integration && integration.integrationType === "WebHook" /* WebHook */ && "discriminator" in integration && integration.discriminator === "WebHookIntegration" /* WebHookIntegration */ && "integrationParameters" in integration && typeof integration.integrationParameters === "object" && integration.integrationParameters !== null && "url" in integration.integrationParameters && typeof integration.integrationParameters.url === "string" && "integrationEvents" in integration && Array.isArray(integration.integrationEvents) && Array.from(integration.integrationEvents).every(
|
|
@@ -18544,6 +18817,558 @@ var TimetableViewTypeValues = {
|
|
|
18544
18817
|
Schedule: 5
|
|
18545
18818
|
};
|
|
18546
18819
|
|
|
18820
|
+
// ../../src/resources/common/timetable-cron.ts
|
|
18821
|
+
import Cron from "cron-converter";
|
|
18822
|
+
var TimetableCronError = class extends Error {
|
|
18823
|
+
/** Машинно читаемая причина локального отказа. */
|
|
18824
|
+
failure;
|
|
18825
|
+
constructor(failure) {
|
|
18826
|
+
super(`Timetable cron: ${failure}`);
|
|
18827
|
+
this.name = "TimetableCronError";
|
|
18828
|
+
this.failure = failure;
|
|
18829
|
+
}
|
|
18830
|
+
};
|
|
18831
|
+
var MONTH_NAME = /\b(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\b/gi;
|
|
18832
|
+
var WEEKDAY_NAME = /\b(?:SUN|MON|TUE|WED|THU|FRI|SAT)\b/gi;
|
|
18833
|
+
var NUMERIC_FIELD = new RegExp("^[-0-9*,/]+$");
|
|
18834
|
+
function createTimetableCronSeeker(expression, earliestStartMs) {
|
|
18835
|
+
const fields = expression.trim().split(/\s+/);
|
|
18836
|
+
if (fields.length !== 5) {
|
|
18837
|
+
throw new TimetableCronError("UnsupportedSyntax" /* UnsupportedSyntax */);
|
|
18838
|
+
}
|
|
18839
|
+
const normalized = fields.map((field, index) => {
|
|
18840
|
+
if (index === 3) {
|
|
18841
|
+
return field.replace(MONTH_NAME, "1");
|
|
18842
|
+
}
|
|
18843
|
+
if (index === 4) {
|
|
18844
|
+
return field.replace(WEEKDAY_NAME, "1");
|
|
18845
|
+
}
|
|
18846
|
+
return field;
|
|
18847
|
+
});
|
|
18848
|
+
if (normalized.some((field) => !NUMERIC_FIELD.test(field))) {
|
|
18849
|
+
throw new TimetableCronError("UnsupportedSyntax" /* UnsupportedSyntax */);
|
|
18850
|
+
}
|
|
18851
|
+
if (!Number.isFinite(earliestStartMs)) {
|
|
18852
|
+
throw new TimetableCronError("InvalidSchedule" /* InvalidSchedule */);
|
|
18853
|
+
}
|
|
18854
|
+
const floorMs = Math.floor(earliestStartMs / 6e4) * 6e4;
|
|
18855
|
+
const floorDate = new Date(floorMs);
|
|
18856
|
+
if (!Number.isFinite(floorDate.getTime())) {
|
|
18857
|
+
throw new TimetableCronError("InvalidSchedule" /* InvalidSchedule */);
|
|
18858
|
+
}
|
|
18859
|
+
let seeker;
|
|
18860
|
+
try {
|
|
18861
|
+
seeker = new Cron().fromString(expression).schedule(floorDate);
|
|
18862
|
+
} catch {
|
|
18863
|
+
throw new TimetableCronError("InvalidSchedule" /* InvalidSchedule */);
|
|
18864
|
+
}
|
|
18865
|
+
let previousMs = floorMs - 6e4;
|
|
18866
|
+
return {
|
|
18867
|
+
next() {
|
|
18868
|
+
let date2;
|
|
18869
|
+
try {
|
|
18870
|
+
date2 = seeker.next().toJSDate();
|
|
18871
|
+
} catch {
|
|
18872
|
+
throw new TimetableCronError("InvalidSchedule" /* InvalidSchedule */);
|
|
18873
|
+
}
|
|
18874
|
+
if (!(date2 instanceof Date) || !Number.isFinite(date2.getTime()) || date2.getTime() <= previousMs) {
|
|
18875
|
+
throw new TimetableCronError("InvalidSchedule" /* InvalidSchedule */);
|
|
18876
|
+
}
|
|
18877
|
+
previousMs = date2.getTime();
|
|
18878
|
+
return date2;
|
|
18879
|
+
}
|
|
18880
|
+
};
|
|
18881
|
+
}
|
|
18882
|
+
|
|
18883
|
+
// ../../src/resources/common/timetable-weekly.ts
|
|
18884
|
+
var DAY_MS = 864e5;
|
|
18885
|
+
function civilOrdinal(year, month, day) {
|
|
18886
|
+
const date2 = /* @__PURE__ */ new Date(0);
|
|
18887
|
+
date2.setUTCFullYear(year, month - 1, day);
|
|
18888
|
+
date2.setUTCHours(0, 0, 0, 0);
|
|
18889
|
+
return date2.getTime();
|
|
18890
|
+
}
|
|
18891
|
+
function zonedCivilOrdinal(formatter, instant) {
|
|
18892
|
+
const parts = formatter.formatToParts(instant);
|
|
18893
|
+
const year = Number(parts.find((part) => part.type === "year")?.value);
|
|
18894
|
+
const month = Number(parts.find((part) => part.type === "month")?.value);
|
|
18895
|
+
const day = Number(parts.find((part) => part.type === "day")?.value);
|
|
18896
|
+
if (!Number.isSafeInteger(year) || !Number.isSafeInteger(month) || !Number.isSafeInteger(day)) {
|
|
18897
|
+
throw new Error("Invalid calendar date");
|
|
18898
|
+
}
|
|
18899
|
+
return civilOrdinal(year, month, day);
|
|
18900
|
+
}
|
|
18901
|
+
function isoWeekNumber(ordinal) {
|
|
18902
|
+
const dayOfWeek = (new Date(ordinal).getUTCDay() + 6) % 7;
|
|
18903
|
+
const thursday = ordinal + (3 - dayOfWeek) * DAY_MS;
|
|
18904
|
+
const weekYear = new Date(thursday).getUTCFullYear();
|
|
18905
|
+
const januaryFourth = civilOrdinal(weekYear, 1, 4);
|
|
18906
|
+
const firstWeekMonday = januaryFourth - (new Date(januaryFourth).getUTCDay() + 6) % 7 * DAY_MS;
|
|
18907
|
+
return Math.floor((ordinal - firstWeekMonday) / (7 * DAY_MS)) + 1;
|
|
18908
|
+
}
|
|
18909
|
+
function safeInteger(value) {
|
|
18910
|
+
const parsed = Number(value);
|
|
18911
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
18912
|
+
}
|
|
18913
|
+
function parseWeeklyPredicate(expression) {
|
|
18914
|
+
if (expression === "*") {
|
|
18915
|
+
return () => true;
|
|
18916
|
+
}
|
|
18917
|
+
const wildcardStep = /^\*\/(\d+)$/.exec(expression);
|
|
18918
|
+
if (wildcardStep) {
|
|
18919
|
+
const step = safeInteger(wildcardStep[1]);
|
|
18920
|
+
return step ? (week) => week % step === 0 : null;
|
|
18921
|
+
}
|
|
18922
|
+
const predicates = [];
|
|
18923
|
+
for (const part of expression.split(",")) {
|
|
18924
|
+
const single = /^(\d+)$/.exec(part);
|
|
18925
|
+
if (single) {
|
|
18926
|
+
const number = safeInteger(single[1]);
|
|
18927
|
+
if (number === null) {
|
|
18928
|
+
return null;
|
|
18929
|
+
}
|
|
18930
|
+
predicates.push((week) => week === number);
|
|
18931
|
+
continue;
|
|
18932
|
+
}
|
|
18933
|
+
const range = /^(\d+)-(\d+)(?:\/(\d+))?$/.exec(part);
|
|
18934
|
+
if (range) {
|
|
18935
|
+
const first = safeInteger(range[1]);
|
|
18936
|
+
const last = safeInteger(range[2]);
|
|
18937
|
+
const step = range[3] === void 0 ? null : safeInteger(range[3]);
|
|
18938
|
+
if (first === null || last === null || first > last || range[3] !== void 0 && (!step || step <= 0)) {
|
|
18939
|
+
return null;
|
|
18940
|
+
}
|
|
18941
|
+
predicates.push((week) => week >= first && week <= last && (step === null || week % step === 0));
|
|
18942
|
+
continue;
|
|
18943
|
+
}
|
|
18944
|
+
const fromStep = /^(\d+)\/(\d+)$/.exec(part);
|
|
18945
|
+
if (fromStep) {
|
|
18946
|
+
const first = safeInteger(fromStep[1]);
|
|
18947
|
+
const step = safeInteger(fromStep[2]);
|
|
18948
|
+
if (first === null || !step) {
|
|
18949
|
+
return null;
|
|
18950
|
+
}
|
|
18951
|
+
predicates.push((week) => week >= first && (week - first) % step === 0);
|
|
18952
|
+
continue;
|
|
18953
|
+
}
|
|
18954
|
+
return null;
|
|
18955
|
+
}
|
|
18956
|
+
return (week) => predicates.some((predicate) => predicate(week));
|
|
18957
|
+
}
|
|
18958
|
+
function createTimetableWeeklyChecker(weeklyCron, firstWeekDate, timeZone) {
|
|
18959
|
+
const predicate = parseWeeklyPredicate(weeklyCron);
|
|
18960
|
+
if (predicate === null || firstWeekDate != null && (!(firstWeekDate instanceof Date) || !Number.isFinite(firstWeekDate.getTime()))) {
|
|
18961
|
+
return null;
|
|
18962
|
+
}
|
|
18963
|
+
const formatter = new Intl.DateTimeFormat("en-US-u-ca-gregory-nu-latn", {
|
|
18964
|
+
timeZone,
|
|
18965
|
+
year: "numeric",
|
|
18966
|
+
month: "2-digit",
|
|
18967
|
+
day: "2-digit"
|
|
18968
|
+
});
|
|
18969
|
+
const anchorOrdinal = firstWeekDate == null ? null : zonedCivilOrdinal(formatter, firstWeekDate);
|
|
18970
|
+
return (candidateMs) => {
|
|
18971
|
+
const ordinal = zonedCivilOrdinal(formatter, new Date(candidateMs));
|
|
18972
|
+
if (anchorOrdinal !== null) {
|
|
18973
|
+
const daysBetween = Math.abs((ordinal - anchorOrdinal) / DAY_MS);
|
|
18974
|
+
const anchorDay = new Date(anchorOrdinal).getUTCDay();
|
|
18975
|
+
const candidateDay = new Date(ordinal).getUTCDay();
|
|
18976
|
+
const week = Math.floor((daysBetween + anchorDay - candidateDay) / 7) + 1;
|
|
18977
|
+
return predicate(week);
|
|
18978
|
+
}
|
|
18979
|
+
return predicate(isoWeekNumber(ordinal));
|
|
18980
|
+
};
|
|
18981
|
+
}
|
|
18982
|
+
|
|
18983
|
+
// ../../src/resources/common/timetable-recurring.ts
|
|
18984
|
+
var TimetableExpansionKind = /* @__PURE__ */ ((TimetableExpansionKind2) => {
|
|
18985
|
+
TimetableExpansionKind2["StoredCase"] = "stored_case";
|
|
18986
|
+
TimetableExpansionKind2["VirtualOccurrence"] = "virtual_occurrence";
|
|
18987
|
+
TimetableExpansionKind2["UnexpandedSeries"] = "unexpanded_series";
|
|
18988
|
+
return TimetableExpansionKind2;
|
|
18989
|
+
})(TimetableExpansionKind || {});
|
|
18990
|
+
var TimetableUnexpandedReason = /* @__PURE__ */ ((TimetableUnexpandedReason2) => {
|
|
18991
|
+
TimetableUnexpandedReason2["MissingScheduleRanges"] = "MissingScheduleRanges";
|
|
18992
|
+
TimetableUnexpandedReason2["MissingSeriesId"] = "MissingSeriesId";
|
|
18993
|
+
TimetableUnexpandedReason2["MissingWeeklyTimeZone"] = "MissingWeeklyTimeZone";
|
|
18994
|
+
TimetableUnexpandedReason2["InvalidSeriesDates"] = "InvalidSeriesDates";
|
|
18995
|
+
TimetableUnexpandedReason2["InvalidSchedule"] = "InvalidSchedule";
|
|
18996
|
+
TimetableUnexpandedReason2["UnsupportedCronSyntax"] = "UnsupportedCronSyntax";
|
|
18997
|
+
TimetableUnexpandedReason2["UnsupportedRecurrenceRule"] = "UnsupportedRecurrenceRule";
|
|
18998
|
+
return TimetableUnexpandedReason2;
|
|
18999
|
+
})(TimetableUnexpandedReason || {});
|
|
19000
|
+
var DEFAULT_MAX_CANDIDATES = 1e4;
|
|
19001
|
+
var DEFAULT_MAX_ITERATIONS = 1e5;
|
|
19002
|
+
var DEFAULT_MAX_RESULTS = 1e4;
|
|
19003
|
+
function sdkError(category) {
|
|
19004
|
+
return new TorrowSdkError({ category, operation: "expandRecurringTimetableCases" });
|
|
19005
|
+
}
|
|
19006
|
+
function validDate(value) {
|
|
19007
|
+
return value instanceof Date && Number.isFinite(value.getTime());
|
|
19008
|
+
}
|
|
19009
|
+
function validZone(value) {
|
|
19010
|
+
if (/^[+-]\d{1,2}(?::?\d{2})?$/.test(value)) {
|
|
19011
|
+
return false;
|
|
19012
|
+
}
|
|
19013
|
+
try {
|
|
19014
|
+
new Intl.DateTimeFormat("en", { timeZone: value });
|
|
19015
|
+
return true;
|
|
19016
|
+
} catch {
|
|
19017
|
+
return false;
|
|
19018
|
+
}
|
|
19019
|
+
}
|
|
19020
|
+
function budget(value, fallback) {
|
|
19021
|
+
if (value === void 0) {
|
|
19022
|
+
return fallback;
|
|
19023
|
+
}
|
|
19024
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
19025
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19026
|
+
}
|
|
19027
|
+
return value;
|
|
19028
|
+
}
|
|
19029
|
+
function dateKey(source, identity, beginning, ending) {
|
|
19030
|
+
return JSON.stringify([
|
|
19031
|
+
source.timetableId ?? null,
|
|
19032
|
+
identity,
|
|
19033
|
+
beginning?.getTime() ?? null,
|
|
19034
|
+
ending?.getTime() ?? null
|
|
19035
|
+
]);
|
|
19036
|
+
}
|
|
19037
|
+
function overlaps(beginning, ending, from, to, strict) {
|
|
19038
|
+
return strict ? beginning >= from && ending <= to : beginning < to && ending > from;
|
|
19039
|
+
}
|
|
19040
|
+
function expandRecurringTimetableCases(cases, options) {
|
|
19041
|
+
if (!Array.isArray(cases) || !options || !validDate(options.from) || !validDate(options.to)) {
|
|
19042
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19043
|
+
}
|
|
19044
|
+
const from = options.from.getTime();
|
|
19045
|
+
const to = options.to.getTime();
|
|
19046
|
+
if (from >= to || options.userTimeZone != null && (typeof options.userTimeZone !== "string" || !validZone(options.userTimeZone))) {
|
|
19047
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19048
|
+
}
|
|
19049
|
+
if (options.resolveRecurrenceContext !== void 0 && typeof options.resolveRecurrenceContext !== "function") {
|
|
19050
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19051
|
+
}
|
|
19052
|
+
if (options.strictlyInTimeRange !== void 0 && typeof options.strictlyInTimeRange !== "boolean") {
|
|
19053
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19054
|
+
}
|
|
19055
|
+
const maxCandidates = budget(options.maxCandidates, DEFAULT_MAX_CANDIDATES);
|
|
19056
|
+
const maxIterations = budget(options.maxIterations, DEFAULT_MAX_ITERATIONS);
|
|
19057
|
+
const maxResults = budget(options.maxResults, DEFAULT_MAX_RESULTS);
|
|
19058
|
+
const entries = [];
|
|
19059
|
+
let candidateCount = 0;
|
|
19060
|
+
let iterationCount = 0;
|
|
19061
|
+
function append(entry) {
|
|
19062
|
+
entries.push(entry);
|
|
19063
|
+
}
|
|
19064
|
+
function unexpanded(source, index, reason) {
|
|
19065
|
+
const identity = source.itemObject?.id || `row:${index}`;
|
|
19066
|
+
append({
|
|
19067
|
+
kind: "unexpanded_series" /* UnexpandedSeries */,
|
|
19068
|
+
source,
|
|
19069
|
+
reason,
|
|
19070
|
+
key: `${dateKey(source, identity, validDate(source.beginDate) ? source.beginDate : null, validDate(source.endDate) ? source.endDate : null)}:${reason}`
|
|
19071
|
+
});
|
|
19072
|
+
}
|
|
19073
|
+
for (const [index, source] of cases.entries()) {
|
|
19074
|
+
let resolveWeeklyZone2 = function() {
|
|
19075
|
+
if (!recurrenceContextResolved) {
|
|
19076
|
+
let context;
|
|
19077
|
+
try {
|
|
19078
|
+
context = options.resolveRecurrenceContext?.(source);
|
|
19079
|
+
} catch {
|
|
19080
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19081
|
+
}
|
|
19082
|
+
if (context != null && (typeof context !== "object" || Array.isArray(context))) {
|
|
19083
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19084
|
+
}
|
|
19085
|
+
if (context != null && "then" in context && typeof context.then === "function") {
|
|
19086
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19087
|
+
}
|
|
19088
|
+
const explicitZone = context?.weeklyTimeZone;
|
|
19089
|
+
if (explicitZone != null && (typeof explicitZone !== "string" || !validZone(explicitZone))) {
|
|
19090
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19091
|
+
}
|
|
19092
|
+
seriesWeeklyZone = explicitZone ?? options.userTimeZone ?? null;
|
|
19093
|
+
recurrenceContextResolved = true;
|
|
19094
|
+
}
|
|
19095
|
+
return seriesWeeklyZone;
|
|
19096
|
+
};
|
|
19097
|
+
var resolveWeeklyZone = resolveWeeklyZone2;
|
|
19098
|
+
if (!source || typeof source !== "object") {
|
|
19099
|
+
throw sdkError("InvalidInput" /* InvalidInput */);
|
|
19100
|
+
}
|
|
19101
|
+
const beginDate = validDate(source.beginDate) ? source.beginDate : null;
|
|
19102
|
+
const endDate = validDate(source.endDate) ? source.endDate : null;
|
|
19103
|
+
const sourceId = typeof source.itemObject?.id === "string" && source.itemObject.id.length > 0 ? source.itemObject.id : null;
|
|
19104
|
+
if (!source.schedule || source.groupId) {
|
|
19105
|
+
if (beginDate && endDate && !overlaps(beginDate.getTime(), endDate.getTime(), from, to, !!options.strictlyInTimeRange)) {
|
|
19106
|
+
continue;
|
|
19107
|
+
}
|
|
19108
|
+
append({
|
|
19109
|
+
kind: "stored_case" /* StoredCase */,
|
|
19110
|
+
source,
|
|
19111
|
+
caseId: sourceId,
|
|
19112
|
+
beginDate,
|
|
19113
|
+
endDate,
|
|
19114
|
+
key: dateKey(source, sourceId ?? `row:${index}`, beginDate, endDate)
|
|
19115
|
+
});
|
|
19116
|
+
continue;
|
|
19117
|
+
}
|
|
19118
|
+
if (!sourceId) {
|
|
19119
|
+
unexpanded(source, index, "MissingSeriesId" /* MissingSeriesId */);
|
|
19120
|
+
continue;
|
|
19121
|
+
}
|
|
19122
|
+
if (!beginDate || !endDate || endDate.getTime() <= beginDate.getTime()) {
|
|
19123
|
+
unexpanded(source, index, "InvalidSeriesDates" /* InvalidSeriesDates */);
|
|
19124
|
+
continue;
|
|
19125
|
+
}
|
|
19126
|
+
const ranges = source.schedule.scheduleRanges;
|
|
19127
|
+
if (ranges == null || Array.isArray(ranges) && ranges.length === 0) {
|
|
19128
|
+
unexpanded(source, index, "MissingScheduleRanges" /* MissingScheduleRanges */);
|
|
19129
|
+
continue;
|
|
19130
|
+
}
|
|
19131
|
+
if (!Array.isArray(ranges)) {
|
|
19132
|
+
unexpanded(source, index, "InvalidSchedule" /* InvalidSchedule */);
|
|
19133
|
+
continue;
|
|
19134
|
+
}
|
|
19135
|
+
const exceptions = source.schedule.scheduleRangeExceptions;
|
|
19136
|
+
if (exceptions != null && (typeof exceptions !== "object" || Array.isArray(exceptions))) {
|
|
19137
|
+
unexpanded(source, index, "InvalidSchedule" /* InvalidSchedule */);
|
|
19138
|
+
continue;
|
|
19139
|
+
}
|
|
19140
|
+
const rawExcluded = exceptions?.excludedTimeRanges;
|
|
19141
|
+
const rawReplaced = exceptions?.replacedTimeRanges;
|
|
19142
|
+
if (rawExcluded != null && !Array.isArray(rawExcluded) || rawReplaced != null && !Array.isArray(rawReplaced)) {
|
|
19143
|
+
unexpanded(source, index, "InvalidSchedule" /* InvalidSchedule */);
|
|
19144
|
+
continue;
|
|
19145
|
+
}
|
|
19146
|
+
const excludedRanges = [];
|
|
19147
|
+
const replacedRanges = [];
|
|
19148
|
+
let invalidException = false;
|
|
19149
|
+
for (const excluded of rawExcluded ?? []) {
|
|
19150
|
+
if (!excluded || !validDate(excluded.begin) || !validDate(excluded.end)) {
|
|
19151
|
+
invalidException = true;
|
|
19152
|
+
break;
|
|
19153
|
+
}
|
|
19154
|
+
const excludeBegin = excluded.begin.getTime();
|
|
19155
|
+
const excludeEnd = excluded.end.getTime();
|
|
19156
|
+
if (excludeEnd < excludeBegin) {
|
|
19157
|
+
invalidException = true;
|
|
19158
|
+
break;
|
|
19159
|
+
}
|
|
19160
|
+
excludedRanges.push({ begin: excludeBegin, end: excludeEnd });
|
|
19161
|
+
}
|
|
19162
|
+
for (const replaced of rawReplaced ?? []) {
|
|
19163
|
+
if (!replaced || !validDate(replaced.begin) || !validDate(replaced.end)) {
|
|
19164
|
+
invalidException = true;
|
|
19165
|
+
break;
|
|
19166
|
+
}
|
|
19167
|
+
replacedRanges.push({ begin: replaced.begin.getTime(), end: replaced.end.getTime() });
|
|
19168
|
+
}
|
|
19169
|
+
if (invalidException) {
|
|
19170
|
+
unexpanded(source, index, "InvalidSchedule" /* InvalidSchedule */);
|
|
19171
|
+
continue;
|
|
19172
|
+
}
|
|
19173
|
+
const replacementStarts = /* @__PURE__ */ new Map();
|
|
19174
|
+
for (let replacementIndex = replacedRanges.length - 1; replacementIndex >= 0; replacementIndex -= 1) {
|
|
19175
|
+
const replacement = replacedRanges[replacementIndex];
|
|
19176
|
+
replacementStarts.set(replacement.begin, replacementStarts.get(replacement.end) ?? replacement.end);
|
|
19177
|
+
}
|
|
19178
|
+
const seriesEntries = [];
|
|
19179
|
+
let seriesReason = null;
|
|
19180
|
+
let seriesWeeklyZone = null;
|
|
19181
|
+
let recurrenceContextResolved = false;
|
|
19182
|
+
for (const range of ranges) {
|
|
19183
|
+
if (!range || typeof range !== "object") {
|
|
19184
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19185
|
+
break;
|
|
19186
|
+
}
|
|
19187
|
+
const beginning = validDate(range.beginning) ? range.beginning.getTime() : Number.NaN;
|
|
19188
|
+
const ending = validDate(range.ending) ? range.ending.getTime() : Number.NaN;
|
|
19189
|
+
const duration = ending - beginning;
|
|
19190
|
+
if (!Number.isFinite(duration) || duration <= 0) {
|
|
19191
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19192
|
+
break;
|
|
19193
|
+
}
|
|
19194
|
+
const recurrence = range.recurringConditions;
|
|
19195
|
+
const cronExpression = recurrence?.cron;
|
|
19196
|
+
const hasCron = cronExpression != null;
|
|
19197
|
+
if (hasCron && (typeof cronExpression !== "string" || cronExpression.trim().length === 0)) {
|
|
19198
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19199
|
+
break;
|
|
19200
|
+
}
|
|
19201
|
+
const lower = recurrence?.beginDate == null ? beginning : validDate(recurrence.beginDate) ? recurrence.beginDate.getTime() : Number.NaN;
|
|
19202
|
+
const upper = recurrence?.endDate == null ? Number.POSITIVE_INFINITY : validDate(recurrence.endDate) ? recurrence.endDate.getTime() : Number.NaN;
|
|
19203
|
+
if (!Number.isFinite(lower) || Number.isNaN(upper) || lower > upper) {
|
|
19204
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19205
|
+
break;
|
|
19206
|
+
}
|
|
19207
|
+
const repeatSeconds = recurrence?.repeatInterval;
|
|
19208
|
+
const repeating = hasCron || repeatSeconds != null;
|
|
19209
|
+
const step = !hasCron && repeatSeconds != null ? repeatSeconds * 1e3 : 0;
|
|
19210
|
+
if (!hasCron && repeating && (!Number.isSafeInteger(repeatSeconds) || repeatSeconds <= 0 || !Number.isSafeInteger(step))) {
|
|
19211
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19212
|
+
break;
|
|
19213
|
+
}
|
|
19214
|
+
if (recurrence?.remainingCount != null && (!Number.isSafeInteger(recurrence.remainingCount) || recurrence.remainingCount < -1)) {
|
|
19215
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19216
|
+
break;
|
|
19217
|
+
}
|
|
19218
|
+
const earliestOverlap = options.strictlyInTimeRange ? from : from - duration + 1;
|
|
19219
|
+
let searchFrom = earliestOverlap;
|
|
19220
|
+
let searchUntil = to;
|
|
19221
|
+
for (const [originalStart, finalStart] of replacementStarts) {
|
|
19222
|
+
if (overlaps(finalStart, finalStart + duration, from, to, !!options.strictlyInTimeRange)) {
|
|
19223
|
+
searchFrom = Math.min(searchFrom, originalStart);
|
|
19224
|
+
searchUntil = Math.max(searchUntil, originalStart + 1);
|
|
19225
|
+
}
|
|
19226
|
+
}
|
|
19227
|
+
const firstAllowed = hasCron ? Math.max(lower, searchFrom) : Math.max(beginning, lower, searchFrom);
|
|
19228
|
+
const firstIndex = !hasCron && repeating ? Math.max(0, Math.ceil((firstAllowed - beginning) / step)) : 0;
|
|
19229
|
+
let cronSeeker = null;
|
|
19230
|
+
if (hasCron) {
|
|
19231
|
+
try {
|
|
19232
|
+
cronSeeker = createTimetableCronSeeker(cronExpression, firstAllowed);
|
|
19233
|
+
} catch (error) {
|
|
19234
|
+
seriesReason = error instanceof TimetableCronError && error.failure === "UnsupportedSyntax" /* UnsupportedSyntax */ ? "UnsupportedCronSyntax" /* UnsupportedCronSyntax */ : "InvalidSchedule" /* InvalidSchedule */;
|
|
19235
|
+
break;
|
|
19236
|
+
}
|
|
19237
|
+
}
|
|
19238
|
+
let weeklyChecker = null;
|
|
19239
|
+
if (recurrence?.weeklyCron != null) {
|
|
19240
|
+
if (typeof recurrence.weeklyCron !== "string") {
|
|
19241
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19242
|
+
break;
|
|
19243
|
+
}
|
|
19244
|
+
const weeklyZone = resolveWeeklyZone2();
|
|
19245
|
+
if (weeklyZone === null) {
|
|
19246
|
+
seriesReason = "MissingWeeklyTimeZone" /* MissingWeeklyTimeZone */;
|
|
19247
|
+
break;
|
|
19248
|
+
}
|
|
19249
|
+
weeklyChecker = createTimetableWeeklyChecker(recurrence.weeklyCron, recurrence.firstWeekDate, weeklyZone);
|
|
19250
|
+
if (weeklyChecker === null) {
|
|
19251
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19252
|
+
break;
|
|
19253
|
+
}
|
|
19254
|
+
}
|
|
19255
|
+
if (recurrence?.remainingCount === 0) {
|
|
19256
|
+
continue;
|
|
19257
|
+
}
|
|
19258
|
+
let visibleCount = 0;
|
|
19259
|
+
for (let occurrenceIndex = firstIndex; !repeating || occurrenceIndex <= Number.MAX_SAFE_INTEGER; occurrenceIndex += 1) {
|
|
19260
|
+
let start;
|
|
19261
|
+
if (cronSeeker) {
|
|
19262
|
+
try {
|
|
19263
|
+
start = cronSeeker.next().getTime();
|
|
19264
|
+
} catch {
|
|
19265
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19266
|
+
break;
|
|
19267
|
+
}
|
|
19268
|
+
} else {
|
|
19269
|
+
start = repeating ? beginning + occurrenceIndex * step : beginning;
|
|
19270
|
+
}
|
|
19271
|
+
if (!Number.isFinite(start) || start > upper || start >= searchUntil) {
|
|
19272
|
+
break;
|
|
19273
|
+
}
|
|
19274
|
+
iterationCount += 1;
|
|
19275
|
+
if (iterationCount > maxIterations) {
|
|
19276
|
+
throw sdkError("UnsupportedOperation" /* UnsupportedOperation */);
|
|
19277
|
+
}
|
|
19278
|
+
candidateCount += 1;
|
|
19279
|
+
if (candidateCount > maxCandidates) {
|
|
19280
|
+
throw sdkError("UnsupportedOperation" /* UnsupportedOperation */);
|
|
19281
|
+
}
|
|
19282
|
+
const finish = start + duration;
|
|
19283
|
+
if (!validDate(new Date(finish))) {
|
|
19284
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19285
|
+
break;
|
|
19286
|
+
}
|
|
19287
|
+
let matchesWeekly = true;
|
|
19288
|
+
if (weeklyChecker) {
|
|
19289
|
+
try {
|
|
19290
|
+
matchesWeekly = weeklyChecker(start);
|
|
19291
|
+
} catch {
|
|
19292
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19293
|
+
break;
|
|
19294
|
+
}
|
|
19295
|
+
}
|
|
19296
|
+
const isExcluded = excludedRanges.some((excluded) => excluded.begin <= start && excluded.end >= finish);
|
|
19297
|
+
const finalStart = replacementStarts.get(start) ?? start;
|
|
19298
|
+
const finalFinish = finalStart + duration;
|
|
19299
|
+
if (!validDate(new Date(finalFinish))) {
|
|
19300
|
+
seriesReason = "InvalidSchedule" /* InvalidSchedule */;
|
|
19301
|
+
break;
|
|
19302
|
+
}
|
|
19303
|
+
if (start >= lower && matchesWeekly && !isExcluded && overlaps(finalStart, finalFinish, from, to, !!options.strictlyInTimeRange)) {
|
|
19304
|
+
seriesEntries.push({
|
|
19305
|
+
kind: "virtual_occurrence" /* VirtualOccurrence */,
|
|
19306
|
+
source,
|
|
19307
|
+
seriesId: sourceId,
|
|
19308
|
+
beginDate: new Date(finalStart),
|
|
19309
|
+
endDate: new Date(finalFinish),
|
|
19310
|
+
key: dateKey(source, sourceId, new Date(finalStart), new Date(finalFinish))
|
|
19311
|
+
});
|
|
19312
|
+
visibleCount += 1;
|
|
19313
|
+
if (recurrence?.remainingCount != null && recurrence.remainingCount >= 0 && visibleCount >= recurrence.remainingCount) {
|
|
19314
|
+
break;
|
|
19315
|
+
}
|
|
19316
|
+
}
|
|
19317
|
+
if (!repeating) {
|
|
19318
|
+
break;
|
|
19319
|
+
}
|
|
19320
|
+
}
|
|
19321
|
+
if (seriesReason) {
|
|
19322
|
+
break;
|
|
19323
|
+
}
|
|
19324
|
+
}
|
|
19325
|
+
if (seriesReason) {
|
|
19326
|
+
unexpanded(source, index, seriesReason);
|
|
19327
|
+
continue;
|
|
19328
|
+
}
|
|
19329
|
+
for (const entry of seriesEntries) {
|
|
19330
|
+
append(entry);
|
|
19331
|
+
}
|
|
19332
|
+
}
|
|
19333
|
+
const storedDescendants = /* @__PURE__ */ new Set();
|
|
19334
|
+
for (const entry of entries) {
|
|
19335
|
+
if (entry.kind === "stored_case" /* StoredCase */ && typeof entry.source.groupId === "string" && entry.source.groupId.length > 0 && entry.beginDate && entry.endDate) {
|
|
19336
|
+
storedDescendants.add(JSON.stringify([entry.source.groupId, entry.beginDate.getTime(), entry.endDate.getTime()]));
|
|
19337
|
+
}
|
|
19338
|
+
}
|
|
19339
|
+
const seenOccurrences = /* @__PURE__ */ new Set();
|
|
19340
|
+
const result = entries.filter((entry) => {
|
|
19341
|
+
if (entry.kind === "virtual_occurrence" /* VirtualOccurrence */) {
|
|
19342
|
+
const replacementKey = JSON.stringify([entry.seriesId, entry.beginDate.getTime(), entry.endDate.getTime()]);
|
|
19343
|
+
if (storedDescendants.has(replacementKey)) {
|
|
19344
|
+
return false;
|
|
19345
|
+
}
|
|
19346
|
+
}
|
|
19347
|
+
if (entry.kind === "unexpanded_series" /* UnexpandedSeries */ || entry.kind === "stored_case" /* StoredCase */ && !entry.caseId) {
|
|
19348
|
+
return true;
|
|
19349
|
+
}
|
|
19350
|
+
const occurrenceKey = `${entry.kind}:${entry.key}`;
|
|
19351
|
+
if (seenOccurrences.has(occurrenceKey)) {
|
|
19352
|
+
return false;
|
|
19353
|
+
}
|
|
19354
|
+
seenOccurrences.add(occurrenceKey);
|
|
19355
|
+
return true;
|
|
19356
|
+
});
|
|
19357
|
+
if (result.length > maxResults) {
|
|
19358
|
+
throw sdkError("UnsupportedOperation" /* UnsupportedOperation */);
|
|
19359
|
+
}
|
|
19360
|
+
result.sort((left, right) => {
|
|
19361
|
+
const leftStart = left.kind === "unexpanded_series" /* UnexpandedSeries */ ? left.source.beginDate : left.beginDate;
|
|
19362
|
+
const rightStart = right.kind === "unexpanded_series" /* UnexpandedSeries */ ? right.source.beginDate : right.beginDate;
|
|
19363
|
+
const timeDifference = (validDate(leftStart) ? leftStart.getTime() : Number.POSITIVE_INFINITY) - (validDate(rightStart) ? rightStart.getTime() : Number.POSITIVE_INFINITY);
|
|
19364
|
+
if (timeDifference) {
|
|
19365
|
+
return timeDifference;
|
|
19366
|
+
}
|
|
19367
|
+
return left.key < right.key ? -1 : left.key > right.key ? 1 : 0;
|
|
19368
|
+
});
|
|
19369
|
+
return result;
|
|
19370
|
+
}
|
|
19371
|
+
|
|
18547
19372
|
// ../../src/resources/contexts/context-icon-preset-paths.ts
|
|
18548
19373
|
var CONTEXT_ICON_PRESET_PATHS = {
|
|
18549
19374
|
anchor: "M35.4783 29.6467C30.6084 24.7768 26.629 15.4085 26.586 15.307C26.585 15.3045 26.5825 15.3015 26.5825 15.3015C26.5594 15.2485 26.527 15.2036 26.4889 15.1626C26.4775 15.1501 26.4645 15.1401 26.4515 15.129C26.4195 15.1006 26.3845 15.0771 26.3465 15.058C26.331 15.0505 26.317 15.042 26.301 15.0361C26.2465 15.0155 26.19 15.0011 26.13 15.0005H26.1265H26.125L26.1215 15.001C25.9914 14.9915 25.8714 15.0495 25.78 15.141C25.776 15.145 25.772 15.148 25.768 15.152C25.7279 15.195 25.6924 15.2425 25.668 15.2975L25.6644 15.3055C25.561 15.536 21.6095 24.3088 16.7716 29.1467C16.6441 29.2742 16.5951 29.4602 16.6431 29.6337C16.6911 29.8072 16.8291 29.9417 17.0037 29.9852C20.5716 30.8772 20.6245 37.3121 20.6251 37.5006C20.6256 37.7765 20.8495 37.9995 21.125 37.9995C21.401 37.999 21.6251 37.7761 21.6251 37.5C21.6251 37.4495 21.5811 30.7692 18.0356 29.2767C21.4051 25.6693 24.22 20.5154 25.6249 17.707V27.0508C24.4854 27.2833 23.625 28.2928 23.625 29.5002C23.625 30.8787 24.7465 32.0002 26.125 32.0002C27.5035 32.0002 28.6249 30.8787 28.6249 29.5002C28.6249 28.2928 27.7644 27.2833 26.625 27.0508V17.8115C28.0315 20.7629 30.8454 26.1428 34.2113 29.7717C30.6684 31.2087 30.6249 37.4546 30.6249 37.5C30.6249 37.776 30.8483 37.999 31.1238 37.9995C31.3998 37.9995 31.6239 37.7765 31.6249 37.501C31.6253 37.3331 31.6814 31.3761 35.2463 30.4852C35.4208 30.4417 35.5588 30.3072 35.6068 30.1337C35.6547 29.9602 35.6058 29.7742 35.4783 29.6467ZM27.6249 29.5002C27.6249 30.3272 26.9519 31.0002 26.125 31.0002C25.298 31.0002 24.625 30.3272 24.625 29.5002C24.625 28.6733 25.298 28.0003 26.125 28.0003C26.9519 28.0003 27.6249 28.6733 27.6249 29.5002ZM32.1248 37.0001H20.1251C19.8491 37.0001 19.6251 37.2241 19.6251 37.5V38.5C19.6251 38.776 19.8491 39 20.1251 39C20.4011 39 20.6251 38.776 20.6251 38.5V38.0001H31.6248V38.5C31.6248 38.776 31.8488 39 32.1248 39C32.4007 39 32.6247 38.776 32.6247 38.5V37.5C32.6248 37.2241 32.4008 37.0001 32.1248 37.0001Z",
|
|
@@ -19711,11 +20536,13 @@ export {
|
|
|
19711
20536
|
AuthScopeValues,
|
|
19712
20537
|
AuthSessionEffectStep,
|
|
19713
20538
|
AuthSessionErrorReason,
|
|
20539
|
+
AvailabilityTimeValues,
|
|
19714
20540
|
AvailableResourcesValues,
|
|
19715
20541
|
BehaviorSettingsEffectStep,
|
|
19716
20542
|
BlockReasonsFacade,
|
|
19717
20543
|
CalendarViewTypeValues,
|
|
19718
20544
|
CalendarsFacade,
|
|
20545
|
+
CaseParticipantTypeValues,
|
|
19719
20546
|
CaseStateValues,
|
|
19720
20547
|
CaseTypeValues,
|
|
19721
20548
|
CasesFacade,
|
|
@@ -19763,6 +20590,10 @@ export {
|
|
|
19763
20590
|
ParticipationFieldTypeValues,
|
|
19764
20591
|
PaymentProviderTypeValues,
|
|
19765
20592
|
PinnedViewsFacade,
|
|
20593
|
+
PlacementEffectStep,
|
|
20594
|
+
PlacementFacade,
|
|
20595
|
+
PlacementKindValues,
|
|
20596
|
+
PlacementWriteStatusValues,
|
|
19766
20597
|
ProfileEffectStep,
|
|
19767
20598
|
ProfileErrorReason,
|
|
19768
20599
|
ProfileFailureAt,
|
|
@@ -19793,11 +20624,14 @@ export {
|
|
|
19793
20624
|
SessionDurationTypeValues,
|
|
19794
20625
|
SessionPrecisionTypeValues,
|
|
19795
20626
|
ShortUrlFacade,
|
|
20627
|
+
ShowCaseInTimetableTypeValues,
|
|
19796
20628
|
StateManagementTypeValues,
|
|
19797
20629
|
ThesaurusFacade,
|
|
19798
20630
|
TimeSelectionTypeValues,
|
|
19799
20631
|
TimeSplitTypeValues,
|
|
19800
20632
|
TimeStepUiModeValues,
|
|
20633
|
+
TimetableExpansionKind,
|
|
20634
|
+
TimetableUnexpandedReason,
|
|
19801
20635
|
TimetableViewTypeValues,
|
|
19802
20636
|
TokenStatusValueList,
|
|
19803
20637
|
TokenStatusValues,
|
|
@@ -19828,6 +20662,7 @@ export {
|
|
|
19828
20662
|
createOrder,
|
|
19829
20663
|
createServiceSessionDurationProperties,
|
|
19830
20664
|
expandBookingWizardSteps,
|
|
20665
|
+
expandRecurringTimetableCases,
|
|
19831
20666
|
generateRid,
|
|
19832
20667
|
generateServiceResourceGroupId,
|
|
19833
20668
|
generateTorrowId,
|