@streamline-pulse/formkrafter-core 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { RecapItem, collectRecapItems } from "./utils/recap.js";
10
10
  export { FieldDescriptor, CollectFieldsOptions, collectFields } from "./utils/fields.js";
11
11
  export { IdentityFormat, IDENTITY_FORMATS, checkIdentity, checkFrNir, checkBjNpi, checkDigits, checkLuhn, checkFrSiren, checkFrSiret, checkBjIfu, checkIban, formatIban } from "./utils/identity.js";
12
12
  export { MrzResult, parseMrz, mrzLines, mrzCheckDigit } from "./utils/mrz.js";
13
+ export { Slot, SlotRules, generateSlots, readSlots, groupSlotsByDay, slotDate } from "./utils/slots.js";
13
14
  export { FieldAnnotation, FieldAnnotations, flaggedKeys } from "./review.js";
14
15
  export { SpecIssue, SpecIssueCode, lintSpec } from "./utils/lint-spec.js";
15
16
  export { ensureBrickUids, stripBrickUids, stripUidsFromPatches } from "./ops/uids.js";
package/dist/index.js CHANGED
@@ -6923,6 +6923,7 @@ var DEFAULT_MESSAGES = {
6923
6923
  custom: "Invalid value",
6924
6924
  identity: "Invalid identifier for this format",
6925
6925
  iban: "Invalid IBAN",
6926
+ dateRange: "The end before the start is not allowed",
6926
6927
  mrz: "Machine-readable zone unreadable or inconsistent"
6927
6928
  },
6928
6929
  fr: {
@@ -6940,6 +6941,7 @@ var DEFAULT_MESSAGES = {
6940
6941
  custom: "Valeur invalide",
6941
6942
  identity: "Identifiant invalide pour ce format",
6942
6943
  iban: "IBAN invalide",
6944
+ dateRange: "La fin ne peut pas précéder le début",
6943
6945
  mrz: "Zone de lecture illisible ou incohérente"
6944
6946
  }
6945
6947
  };
@@ -7045,6 +7047,10 @@ function buildValidationSchema(brickSpecs, locale) {
7045
7047
  property.format = `identity-${brick.configs.idFormat}`;
7046
7048
  messages.format = defaultValidationMessage("identity", locale);
7047
7049
  }
7050
+ if (brick.id === "date-range") {
7051
+ property.dateRange = true;
7052
+ messages.dateRange = defaultValidationMessage("dateRange", locale);
7053
+ }
7048
7054
  if (brick.id === "mrz") {
7049
7055
  property.mrzValid = true;
7050
7056
  messages.mrzValid = defaultValidationMessage("mrz", locale);
@@ -7295,6 +7301,22 @@ var en = {
7295
7301
  "mrz.expiryDate": "Expiry date",
7296
7302
  "category.Identity": "Identity",
7297
7303
  "category.Finance": "Finance",
7304
+ "category.Time": "Time",
7305
+ "slots.loading": "Loading slots…",
7306
+ "slots.unavailable": "Slots unavailable",
7307
+ "slots.empty": "No slot available",
7308
+ "slots.none": "No slot chosen",
7309
+ "slots.picked": "Chosen slot:",
7310
+ "range.from": "From",
7311
+ "range.to": "To",
7312
+ "panel.slotsUrl": "Slots URL (empty = opening rules)",
7313
+ "panel.slotDays": "Open days (1 = Monday … 7 = Sunday)",
7314
+ "panel.slotFrom": "Opens at",
7315
+ "panel.slotTo": "Closes at",
7316
+ "panel.slotDuration": "Slot length (minutes)",
7317
+ "panel.slotHorizon": "Bookable days ahead",
7318
+ "panel.slotNotice": "Notice (hours)",
7319
+ "panel.slotExclude": "Closed dates (YYYY-MM-DD, comma-separated)",
7298
7320
  "money.amount": "Amount",
7299
7321
  "money.currency": "Currency",
7300
7322
  "panel.currencies": "Currencies offered (XOF, EUR, USD)",
@@ -7484,6 +7506,22 @@ var frFkTranslations = {
7484
7506
  "mrz.expiryDate": "Date d’expiration",
7485
7507
  "category.Identity": "Identité",
7486
7508
  "category.Finance": "Finance",
7509
+ "category.Time": "Temps",
7510
+ "slots.loading": "Chargement des créneaux…",
7511
+ "slots.unavailable": "Créneaux indisponibles",
7512
+ "slots.empty": "Aucun créneau disponible",
7513
+ "slots.none": "Aucun créneau choisi",
7514
+ "slots.picked": "Créneau choisi :",
7515
+ "range.from": "Du",
7516
+ "range.to": "Au",
7517
+ "panel.slotsUrl": "URL des créneaux (vide = règles d’ouverture)",
7518
+ "panel.slotDays": "Jours ouverts (1 = lundi … 7 = dimanche)",
7519
+ "panel.slotFrom": "Ouverture",
7520
+ "panel.slotTo": "Fermeture",
7521
+ "panel.slotDuration": "Durée d’un créneau (minutes)",
7522
+ "panel.slotHorizon": "Jours réservables à l’avance",
7523
+ "panel.slotNotice": "Préavis (heures)",
7524
+ "panel.slotExclude": "Dates fermées (AAAA-MM-JJ, séparées par des virgules)",
7487
7525
  "money.amount": "Montant",
7488
7526
  "money.currency": "Devise",
7489
7527
  "panel.currencies": "Devises proposées (XOF, EUR, USD)",
@@ -8483,6 +8521,61 @@ function parseTd1(l1, l2, l3, raw) {
8483
8521
  errors
8484
8522
  };
8485
8523
  }
8524
+ // lib/utils/slots.ts
8525
+ var pad = (n) => String(n).padStart(2, "0");
8526
+ var localIso = (date) => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
8527
+ var slotDate = (iso) => iso.slice(0, 10);
8528
+ var minutes = (hhmm) => {
8529
+ const [h, m] = hhmm.split(":").map(Number);
8530
+ return (h ?? 0) * 60 + (m ?? 0);
8531
+ };
8532
+ var weekday = (date) => (date.getDay() + 6) % 7 + 1;
8533
+ function generateSlots(rules, now = new Date) {
8534
+ const days = rules.days?.length ? rules.days : [1, 2, 3, 4, 5];
8535
+ const open = minutes(rules.from ?? "08:00");
8536
+ const close = minutes(rules.to ?? "17:00");
8537
+ const duration = Math.max(5, rules.duration ?? 30);
8538
+ const horizon = Math.max(1, rules.horizonDays ?? 14);
8539
+ const notice = (rules.noticeHours ?? 0) * 60;
8540
+ const exclude = new Set(rules.exclude ?? []);
8541
+ const earliest = new Date(now.getTime() + notice * 60000);
8542
+ const out = [];
8543
+ for (let offset = 0;offset < horizon; offset++) {
8544
+ const day = new Date(now.getFullYear(), now.getMonth(), now.getDate() + offset);
8545
+ if (!days.includes(weekday(day)) || exclude.has(localIso(day).slice(0, 10)))
8546
+ continue;
8547
+ for (let m = open;m + duration <= close; m += duration) {
8548
+ const start = new Date(day.getFullYear(), day.getMonth(), day.getDate(), Math.floor(m / 60), m % 60);
8549
+ if (start < earliest)
8550
+ continue;
8551
+ const end = new Date(start.getTime() + duration * 60000);
8552
+ const startIso = localIso(start);
8553
+ out.push({ id: startIso, start: startIso, end: localIso(end) });
8554
+ }
8555
+ }
8556
+ return out;
8557
+ }
8558
+ function readSlots(payload) {
8559
+ const list = Array.isArray(payload) ? payload : payload && typeof payload === "object" ? payload.slots ?? payload.data : undefined;
8560
+ if (!Array.isArray(list))
8561
+ return [];
8562
+ return list.filter((item) => !!item && typeof item === "object").map((item) => ({
8563
+ id: String(item.id ?? item.start ?? ""),
8564
+ start: String(item.start ?? ""),
8565
+ end: String(item.end ?? ""),
8566
+ ...typeof item.remaining === "number" ? { remaining: item.remaining } : {}
8567
+ })).filter((slot) => slot.id && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(slot.start));
8568
+ }
8569
+ function groupSlotsByDay(slots) {
8570
+ const byDay = new Map;
8571
+ for (const slot of [...slots].sort((a, b) => a.start.localeCompare(b.start))) {
8572
+ if (slot.remaining !== undefined && slot.remaining <= 0)
8573
+ continue;
8574
+ const day = slotDate(slot.start);
8575
+ byDay.set(day, [...byDay.get(day) ?? [], slot]);
8576
+ }
8577
+ return [...byDay.entries()].map(([day, list]) => ({ day, slots: list }));
8578
+ }
8486
8579
  // lib/review.ts
8487
8580
  var flaggedKeys = (annotations) => Object.entries(annotations ?? {}).filter(([, annotation]) => annotation?.incorrect === true).map(([key]) => key);
8488
8581
  // lib/utils/lint-spec.ts
@@ -8644,6 +8737,12 @@ import_ajv_formats.default(ajv, ["email", "uri"]);
8644
8737
  import_ajv_errors.default(ajv);
8645
8738
  for (const format of ["fr-nir", "bj-npi", "fr-siren", "fr-siret", "bj-ifu", "iban", ...Array.from({ length: 20 }, (_, i) => `digits-${i + 1}`)])
8646
8739
  ajv.addFormat(`identity-${format}`, (value) => checkIdentity(format, value));
8740
+ ajv.addKeyword({
8741
+ keyword: "dateRange",
8742
+ type: "object",
8743
+ schemaType: "boolean",
8744
+ validate: (expected, value) => !expected || !value?.from || !value?.to || value.from <= value.to
8745
+ });
8647
8746
  ajv.addKeyword({
8648
8747
  keyword: "mrzValid",
8649
8748
  type: "object",
@@ -9616,9 +9715,11 @@ export {
9616
9715
  flaggedKeys,
9617
9716
  formatIban,
9618
9717
  frFkTranslations,
9718
+ generateSlots,
9619
9719
  getAffectedProperties,
9620
9720
  getBrickAt,
9621
9721
  getBrickData,
9722
+ groupSlotsByDay,
9622
9723
  hasNestedForms,
9623
9724
  interpolateTemplate,
9624
9725
  isLocalizedObject,
@@ -9632,6 +9733,7 @@ export {
9632
9733
  parseHeaderLines,
9633
9734
  parseMrz,
9634
9735
  pointerFromPath,
9736
+ readSlots,
9635
9737
  registerValidationMessages,
9636
9738
  removeBrick,
9637
9739
  resolveLocalizedRecord,
@@ -9639,6 +9741,7 @@ export {
9639
9741
  runSandboxed,
9640
9742
  services,
9641
9743
  setFkTranslations,
9744
+ slotDate,
9642
9745
  stripBrickUids,
9643
9746
  stripUidsFromPatches,
9644
9747
  updateBrickConfigs,
@@ -9651,5 +9754,5 @@ export {
9651
9754
  wrapBrickData
9652
9755
  };
9653
9756
 
9654
- //# debugId=9E13D1BABBC3D27264756E2164756E21
9757
+ //# debugId=30A49B7E74D3EC6964756E2164756E21
9655
9758
  //# sourceMappingURL=index.js.map