@outbuild-company/schedule-core 1.31.0 → 1.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2657,6 +2657,8 @@ interface BackendCalendarExceptionInput {
2657
2657
  to_date: string;
2658
2658
  workable: boolean;
2659
2659
  shifts?: BackendShiftInput[];
2660
+ /** Recurrence step: `DAILY`, `WEEKLY`, `MONTHLY` or `YEARLY`. Empty or unknown means a plain range. */
2661
+ every_type?: string | null;
2660
2662
  }
2661
2663
  /** Calendar payload accepted at the backend normalization boundary. */
2662
2664
  interface BackendCalendarInput {
package/dist/index.d.ts CHANGED
@@ -2657,6 +2657,8 @@ interface BackendCalendarExceptionInput {
2657
2657
  to_date: string;
2658
2658
  workable: boolean;
2659
2659
  shifts?: BackendShiftInput[];
2660
+ /** Recurrence step: `DAILY`, `WEEKLY`, `MONTHLY` or `YEARLY`. Empty or unknown means a plain range. */
2661
+ every_type?: string | null;
2660
2662
  }
2661
2663
  /** Calendar payload accepted at the backend normalization boundary. */
2662
2664
  interface BackendCalendarInput {
package/dist/index.js CHANGED
@@ -14907,11 +14907,14 @@ var PASTE_PLACEMENT = {
14907
14907
  };
14908
14908
 
14909
14909
  // src/activity-copy-paste/paste.ts
14910
+ function childIdsInCorrelativeOrder(parentId, adapter) {
14911
+ return collectChildrenSnapshots(parentId, adapter).sort(compareActivitiesInVisualOrder).map((activity) => activity.id);
14912
+ }
14910
14913
  function resolveEndDestination(adapter) {
14911
- const rootIds = adapter.getRootIds();
14914
+ const rootIds = childIdsInCorrelativeOrder(ROOT_PARENT_ID, adapter);
14912
14915
  const [soleRootId] = rootIds;
14913
14916
  if (rootIds.length === 1 && soleRootId !== void 0) {
14914
- const lastChildId = adapter.getChildren(soleRootId).at(-1);
14917
+ const lastChildId = childIdsInCorrelativeOrder(soleRootId, adapter).at(-1);
14915
14918
  return lastChildId === void 0 ? { ok: true, parentId: soleRootId } : { ok: true, parentId: soleRootId, afterSiblingId: lastChildId };
14916
14919
  }
14917
14920
  const lastRootId = rootIds.at(-1);
@@ -14930,14 +14933,14 @@ function resolvePasteDestination(destination, adapter) {
14930
14933
  return adapter.getRootIds().length === 1 ? {
14931
14934
  ok: true,
14932
14935
  parentId: sibling.id,
14933
- beforeSiblingId: adapter.getChildren(sibling.id)[0]
14936
+ beforeSiblingId: childIdsInCorrelativeOrder(sibling.id, adapter)[0]
14934
14937
  } : { ok: true, parentId: ROOT_PARENT_ID, afterSiblingId };
14935
14938
  }
14936
14939
  if (adapter.hasChildren(sibling.id)) {
14937
14940
  return {
14938
14941
  ok: true,
14939
14942
  parentId: sibling.id,
14940
- beforeSiblingId: adapter.getChildren(sibling.id)[0]
14943
+ beforeSiblingId: childIdsInCorrelativeOrder(sibling.id, adapter)[0]
14941
14944
  };
14942
14945
  }
14943
14946
  return {
@@ -24246,6 +24249,13 @@ function computeProjectWorkHours(calendars) {
24246
24249
  var DAY_MS = 24 * 60 * 60 * 1e3;
24247
24250
  var EXCEPTION_DATE_FORMAT_REGEX = /^(\d{4})[/-](\d{1,2})[/-](\d{1,2})/;
24248
24251
  var WEEKDAYS_PER_WEEK = 7;
24252
+ var EXCEPTION_EVERY_TYPE = {
24253
+ DAILY: "DAILY",
24254
+ WEEKLY: "WEEKLY",
24255
+ MONTHLY: "MONTHLY",
24256
+ YEARLY: "YEARLY"
24257
+ };
24258
+ var MONTHS_PER_YEAR = 12;
24249
24259
  var CALENDAR_FALLBACK_WORKING_DAYS = [false, true, true, true, true, true, false];
24250
24260
  var WORKING_DAY_TRUE_VALUES = /* @__PURE__ */ new Set([
24251
24261
  "1",
@@ -24342,7 +24352,8 @@ function parseExceptionDays(exceptions, range) {
24342
24352
  const rangeKeys = expandRangeToUtcKeys(
24343
24353
  exception.from_date,
24344
24354
  exception.to_date,
24345
- range
24355
+ range,
24356
+ exception.every_type
24346
24357
  );
24347
24358
  if (rangeKeys.length === 0) continue;
24348
24359
  const value = exceptionToDateValue(exception);
@@ -24351,19 +24362,59 @@ function parseExceptionDays(exceptions, range) {
24351
24362
  }
24352
24363
  return Object.keys(map).length > 0 ? map : null;
24353
24364
  }
24354
- function expandRangeToUtcKeys(from, to, range) {
24365
+ function expandRangeToUtcKeys(from, to, range, everyType) {
24355
24366
  const fromTs = parseExceptionDate(from);
24356
24367
  const toTs = parseExceptionDate(to);
24357
24368
  if (fromTs === null || toTs === null) return [];
24358
24369
  if (range && (toTs < range.start || fromTs > range.end)) return [];
24359
- const keys = [];
24360
- let cursor = range ? Math.max(fromTs, range.start) : fromTs;
24370
+ const first = range ? Math.max(fromTs, range.start) : fromTs;
24361
24371
  const last = range ? Math.min(toTs, range.end) : toTs;
24362
- while (cursor <= last) {
24363
- keys.push(String(cursor));
24364
- cursor += DAY_MS;
24372
+ const timestamps = steppedTimestamps(fromTs, first, last, everyType);
24373
+ return timestamps.map(String);
24374
+ }
24375
+ function steppedTimestamps(anchor, first, last, everyType) {
24376
+ switch (everyType) {
24377
+ case EXCEPTION_EVERY_TYPE.DAILY:
24378
+ return everyNthDay(anchor, first, last, 1);
24379
+ case EXCEPTION_EVERY_TYPE.WEEKLY:
24380
+ return everyNthDay(anchor, first, last, WEEKDAYS_PER_WEEK);
24381
+ case EXCEPTION_EVERY_TYPE.MONTHLY:
24382
+ return monthlyOccurrences(anchor, first, last, 1);
24383
+ case EXCEPTION_EVERY_TYPE.YEARLY:
24384
+ return monthlyOccurrences(anchor, first, last, MONTHS_PER_YEAR);
24385
+ default:
24386
+ return everyNthDay(anchor, first, last, 1);
24387
+ }
24388
+ }
24389
+ function everyNthDay(anchor, first, last, stepDays) {
24390
+ const stepMs = stepDays * DAY_MS;
24391
+ const skipped = Math.max(0, Math.ceil((first - anchor) / stepMs));
24392
+ const timestamps = [];
24393
+ for (let cursor = anchor + skipped * stepMs; cursor <= last; cursor += stepMs) {
24394
+ timestamps.push(cursor);
24395
+ }
24396
+ return timestamps;
24397
+ }
24398
+ function monthlyOccurrences(anchor, first, last, stepMonths) {
24399
+ const anchorDate = new Date(anchor);
24400
+ const anchorMonthIndex = anchorDate.getUTCFullYear() * MONTHS_PER_YEAR + anchorDate.getUTCMonth();
24401
+ const firstDate = new Date(first);
24402
+ const firstMonthIndex = firstDate.getUTCFullYear() * MONTHS_PER_YEAR + firstDate.getUTCMonth();
24403
+ const anchorDay = anchorDate.getUTCDate();
24404
+ const skipped = Math.max(
24405
+ 0,
24406
+ Math.floor((firstMonthIndex - anchorMonthIndex) / stepMonths)
24407
+ );
24408
+ const timestamps = [];
24409
+ for (let step = skipped; ; step += 1) {
24410
+ const monthIndex = anchorMonthIndex + step * stepMonths;
24411
+ const year = Math.floor(monthIndex / MONTHS_PER_YEAR);
24412
+ const month = monthIndex % MONTHS_PER_YEAR;
24413
+ const timestamp = Date.UTC(year, month, anchorDay);
24414
+ if (timestamp > last) return timestamps;
24415
+ const dayExists = new Date(timestamp).getUTCMonth() === month;
24416
+ if (dayExists && timestamp >= first) timestamps.push(timestamp);
24365
24417
  }
24366
- return keys;
24367
24418
  }
24368
24419
  function parseExceptionDate(raw) {
24369
24420
  if (typeof raw !== "string") return null;