@streamline-pulse/formkrafter-core 0.26.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 +3 -0
- package/dist/index.js +404 -5
- package/dist/index.js.map +10 -7
- package/dist/utils/identity.d.ts +30 -0
- package/dist/utils/mrz.d.ts +29 -0
- package/dist/utils/slots.d.ts +38 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ export { getBrickData, wrapBrickData } from "./utils/brick-data.js";
|
|
|
8
8
|
export { SelectOption, normalizeOptions } from "./utils/options.js";
|
|
9
9
|
export { RecapItem, collectRecapItems } from "./utils/recap.js";
|
|
10
10
|
export { FieldDescriptor, CollectFieldsOptions, collectFields } from "./utils/fields.js";
|
|
11
|
+
export { IdentityFormat, IDENTITY_FORMATS, checkIdentity, checkFrNir, checkBjNpi, checkDigits, checkLuhn, checkFrSiren, checkFrSiret, checkBjIfu, checkIban, formatIban } from "./utils/identity.js";
|
|
12
|
+
export { MrzResult, parseMrz, mrzLines, mrzCheckDigit } from "./utils/mrz.js";
|
|
13
|
+
export { Slot, SlotRules, generateSlots, readSlots, groupSlotsByDay, slotDate } from "./utils/slots.js";
|
|
11
14
|
export { FieldAnnotation, FieldAnnotations, flaggedKeys } from "./review.js";
|
|
12
15
|
export { SpecIssue, SpecIssueCode, lintSpec } from "./utils/lint-spec.js";
|
|
13
16
|
export { ensureBrickUids, stripBrickUids, stripUidsFromPatches } from "./ops/uids.js";
|
package/dist/index.js
CHANGED
|
@@ -6920,7 +6920,11 @@ var DEFAULT_MESSAGES = {
|
|
|
6920
6920
|
email: "Invalid email address",
|
|
6921
6921
|
url: "Invalid URL",
|
|
6922
6922
|
type: "Invalid value",
|
|
6923
|
-
custom: "Invalid value"
|
|
6923
|
+
custom: "Invalid value",
|
|
6924
|
+
identity: "Invalid identifier for this format",
|
|
6925
|
+
iban: "Invalid IBAN",
|
|
6926
|
+
dateRange: "The end before the start is not allowed",
|
|
6927
|
+
mrz: "Machine-readable zone unreadable or inconsistent"
|
|
6924
6928
|
},
|
|
6925
6929
|
fr: {
|
|
6926
6930
|
required: "Ce champ est obligatoire",
|
|
@@ -6934,7 +6938,11 @@ var DEFAULT_MESSAGES = {
|
|
|
6934
6938
|
email: "Adresse email invalide",
|
|
6935
6939
|
url: "URL invalide",
|
|
6936
6940
|
type: "Valeur invalide",
|
|
6937
|
-
custom: "Valeur invalide"
|
|
6941
|
+
custom: "Valeur invalide",
|
|
6942
|
+
identity: "Identifiant invalide pour ce format",
|
|
6943
|
+
iban: "IBAN invalide",
|
|
6944
|
+
dateRange: "La fin ne peut pas précéder le début",
|
|
6945
|
+
mrz: "Zone de lecture illisible ou incohérente"
|
|
6938
6946
|
}
|
|
6939
6947
|
};
|
|
6940
6948
|
function registerValidationMessages(locale, messages) {
|
|
@@ -7031,6 +7039,22 @@ function buildValidationSchema(brickSpecs, locale) {
|
|
|
7031
7039
|
messages.format = message;
|
|
7032
7040
|
}
|
|
7033
7041
|
}
|
|
7042
|
+
if (brick.id === "iban") {
|
|
7043
|
+
property.format = "identity-iban";
|
|
7044
|
+
messages.format = defaultValidationMessage("iban", locale);
|
|
7045
|
+
}
|
|
7046
|
+
if ((brick.id === "national-id" || brick.id === "tax-id") && typeof brick.configs?.idFormat === "string" && brick.configs.idFormat) {
|
|
7047
|
+
property.format = `identity-${brick.configs.idFormat}`;
|
|
7048
|
+
messages.format = defaultValidationMessage("identity", locale);
|
|
7049
|
+
}
|
|
7050
|
+
if (brick.id === "date-range") {
|
|
7051
|
+
property.dateRange = true;
|
|
7052
|
+
messages.dateRange = defaultValidationMessage("dateRange", locale);
|
|
7053
|
+
}
|
|
7054
|
+
if (brick.id === "mrz") {
|
|
7055
|
+
property.mrzValid = true;
|
|
7056
|
+
messages.mrzValid = defaultValidationMessage("mrz", locale);
|
|
7057
|
+
}
|
|
7034
7058
|
property.errorMessage = messages;
|
|
7035
7059
|
properties[key] = property;
|
|
7036
7060
|
if (isRequired) {
|
|
@@ -7248,7 +7272,55 @@ var en = {
|
|
|
7248
7272
|
"panel.zoom": "Initial zoom",
|
|
7249
7273
|
"panel.height": "Height (px)",
|
|
7250
7274
|
"panel.tileUrl": "Tile URL",
|
|
7251
|
-
"panel.shape": "Shape (polygon or line)"
|
|
7275
|
+
"panel.shape": "Shape (polygon or line)",
|
|
7276
|
+
"panel.searchUrl": "Geocoding URL ({q} = query)",
|
|
7277
|
+
"panel.countryCodes": "Country codes (bj, tg)",
|
|
7278
|
+
"address.search": "Search an address",
|
|
7279
|
+
"address.searching": "Searching…",
|
|
7280
|
+
"address.located": "Address located",
|
|
7281
|
+
"address.notLocated": "Address not located: pick a match to place it",
|
|
7282
|
+
"address.noResult": "No matching address",
|
|
7283
|
+
"address.unavailable": "Address search unavailable",
|
|
7284
|
+
"layer.pick": "Choose a zone…",
|
|
7285
|
+
"layer.pickMany": "Click the zones on the map",
|
|
7286
|
+
"layer.hint": "Click a zone on the map to select it",
|
|
7287
|
+
"layer.unavailable": "Reference layer unavailable",
|
|
7288
|
+
"panel.layerUrl": "Reference layer URL (GeoJSON)",
|
|
7289
|
+
"panel.codeProperty": "Code property",
|
|
7290
|
+
"panel.nameProperty": "Name property",
|
|
7291
|
+
"panel.idFormat": "Identifier format (fr-nir, bj-npi, digits-10…)",
|
|
7292
|
+
"mrz.placeholder": "Paste or type the two or three lines of the machine-readable zone",
|
|
7293
|
+
"mrz.unreadable": "Zone not recognised: 2 lines of 44 (passport) or 3 lines of 30 (identity card)",
|
|
7294
|
+
"mrz.invalid": "Check digits do not match for:",
|
|
7295
|
+
"mrz.documentNumber": "Document number",
|
|
7296
|
+
"mrz.nationality": "Nationality",
|
|
7297
|
+
"mrz.surname": "Surname",
|
|
7298
|
+
"mrz.givenNames": "Given names",
|
|
7299
|
+
"mrz.birthDate": "Date of birth",
|
|
7300
|
+
"mrz.sex": "Sex",
|
|
7301
|
+
"mrz.expiryDate": "Expiry date",
|
|
7302
|
+
"category.Identity": "Identity",
|
|
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)",
|
|
7320
|
+
"money.amount": "Amount",
|
|
7321
|
+
"money.currency": "Currency",
|
|
7322
|
+
"panel.currencies": "Currencies offered (XOF, EUR, USD)",
|
|
7323
|
+
"panel.currency": "Default currency"
|
|
7252
7324
|
};
|
|
7253
7325
|
var frFkTranslations = {
|
|
7254
7326
|
"palette.search": "Rechercher une brique…",
|
|
@@ -7405,7 +7477,55 @@ var frFkTranslations = {
|
|
|
7405
7477
|
"panel.zoom": "Zoom initial",
|
|
7406
7478
|
"panel.height": "Hauteur (px)",
|
|
7407
7479
|
"panel.tileUrl": "URL des tuiles",
|
|
7408
|
-
"panel.shape": "Forme (polygon ou line)"
|
|
7480
|
+
"panel.shape": "Forme (polygon ou line)",
|
|
7481
|
+
"panel.searchUrl": "URL de géocodage ({q} = recherche)",
|
|
7482
|
+
"panel.countryCodes": "Codes pays (bj, tg)",
|
|
7483
|
+
"address.search": "Rechercher une adresse",
|
|
7484
|
+
"address.searching": "Recherche…",
|
|
7485
|
+
"address.located": "Adresse localisée",
|
|
7486
|
+
"address.notLocated": "Adresse non localisée : choisissez une proposition pour la placer",
|
|
7487
|
+
"address.noResult": "Aucune adresse ne correspond",
|
|
7488
|
+
"address.unavailable": "Recherche d’adresse indisponible",
|
|
7489
|
+
"layer.pick": "Choisir une zone…",
|
|
7490
|
+
"layer.pickMany": "Cliquez les zones sur la carte",
|
|
7491
|
+
"layer.hint": "Cliquez une zone sur la carte pour la choisir",
|
|
7492
|
+
"layer.unavailable": "Couche de référence indisponible",
|
|
7493
|
+
"panel.layerUrl": "URL de la couche de référence (GeoJSON)",
|
|
7494
|
+
"panel.codeProperty": "Propriété du code",
|
|
7495
|
+
"panel.nameProperty": "Propriété du nom",
|
|
7496
|
+
"panel.idFormat": "Format de l’identifiant (fr-nir, bj-npi, digits-10…)",
|
|
7497
|
+
"mrz.placeholder": "Collez ou saisissez les deux ou trois lignes de la zone de lecture",
|
|
7498
|
+
"mrz.unreadable": "Zone non reconnue : 2 lignes de 44 (passeport) ou 3 lignes de 30 (carte d’identité)",
|
|
7499
|
+
"mrz.invalid": "Chiffres de contrôle incohérents pour :",
|
|
7500
|
+
"mrz.documentNumber": "Numéro du document",
|
|
7501
|
+
"mrz.nationality": "Nationalité",
|
|
7502
|
+
"mrz.surname": "Nom",
|
|
7503
|
+
"mrz.givenNames": "Prénoms",
|
|
7504
|
+
"mrz.birthDate": "Date de naissance",
|
|
7505
|
+
"mrz.sex": "Sexe",
|
|
7506
|
+
"mrz.expiryDate": "Date d’expiration",
|
|
7507
|
+
"category.Identity": "Identité",
|
|
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)",
|
|
7525
|
+
"money.amount": "Montant",
|
|
7526
|
+
"money.currency": "Devise",
|
|
7527
|
+
"panel.currencies": "Devises proposées (XOF, EUR, USD)",
|
|
7528
|
+
"panel.currency": "Devise par défaut"
|
|
7409
7529
|
};
|
|
7410
7530
|
var GLOBAL_KEY = Symbol.for("formkrafter.i18n");
|
|
7411
7531
|
var globalStore = globalThis;
|
|
@@ -8209,6 +8329,253 @@ var collectFields = (spec, locale, options = {}) => {
|
|
|
8209
8329
|
walk(spec, "0", out);
|
|
8210
8330
|
return out;
|
|
8211
8331
|
};
|
|
8332
|
+
// lib/utils/identity.ts
|
|
8333
|
+
var compact = (value) => value.replace(/[\s.-]/g, "").toUpperCase();
|
|
8334
|
+
function checkFrNir(value) {
|
|
8335
|
+
const raw = compact(value);
|
|
8336
|
+
if (!/^[12][0-9]{2}(0[1-9]|1[0-2]|[2-9][0-9])(2A|2B|[0-9]{2})[0-9]{6}[0-9]{2}$/.test(raw))
|
|
8337
|
+
return false;
|
|
8338
|
+
const number = raw.slice(0, 13).replace("2A", "19").replace("2B", "18");
|
|
8339
|
+
const key = Number(raw.slice(13));
|
|
8340
|
+
return key === 97 - Number(BigInt(number) % 97n);
|
|
8341
|
+
}
|
|
8342
|
+
function checkBjNpi(value) {
|
|
8343
|
+
return /^[0-9]{10}$/.test(compact(value));
|
|
8344
|
+
}
|
|
8345
|
+
function checkDigits(value, length) {
|
|
8346
|
+
return new RegExp(`^[0-9]{${length}}$`).test(compact(value));
|
|
8347
|
+
}
|
|
8348
|
+
function checkLuhn(digits) {
|
|
8349
|
+
if (!/^[0-9]+$/.test(digits))
|
|
8350
|
+
return false;
|
|
8351
|
+
let sum = 0;
|
|
8352
|
+
for (let i = 0;i < digits.length; i++) {
|
|
8353
|
+
let n = Number(digits[digits.length - 1 - i]);
|
|
8354
|
+
if (i % 2 === 1) {
|
|
8355
|
+
n *= 2;
|
|
8356
|
+
if (n > 9)
|
|
8357
|
+
n -= 9;
|
|
8358
|
+
}
|
|
8359
|
+
sum += n;
|
|
8360
|
+
}
|
|
8361
|
+
return sum % 10 === 0;
|
|
8362
|
+
}
|
|
8363
|
+
function checkFrSiren(value) {
|
|
8364
|
+
const raw = compact(value);
|
|
8365
|
+
return /^[0-9]{9}$/.test(raw) && checkLuhn(raw);
|
|
8366
|
+
}
|
|
8367
|
+
function checkFrSiret(value) {
|
|
8368
|
+
const raw = compact(value);
|
|
8369
|
+
return /^[0-9]{14}$/.test(raw) && checkLuhn(raw);
|
|
8370
|
+
}
|
|
8371
|
+
function checkBjIfu(value) {
|
|
8372
|
+
return /^[0-9]{13}$/.test(compact(value));
|
|
8373
|
+
}
|
|
8374
|
+
function checkIban(value) {
|
|
8375
|
+
const raw = compact(value);
|
|
8376
|
+
if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(raw))
|
|
8377
|
+
return false;
|
|
8378
|
+
const rearranged = raw.slice(4) + raw.slice(0, 4);
|
|
8379
|
+
const numeric = rearranged.replace(/[A-Z]/g, (char) => String(char.charCodeAt(0) - 55));
|
|
8380
|
+
return Number(BigInt(numeric) % 97n) === 1;
|
|
8381
|
+
}
|
|
8382
|
+
function checkIdentity(format, value) {
|
|
8383
|
+
if (format === "fr-nir")
|
|
8384
|
+
return checkFrNir(value);
|
|
8385
|
+
if (format === "bj-npi")
|
|
8386
|
+
return checkBjNpi(value);
|
|
8387
|
+
if (format === "fr-siren")
|
|
8388
|
+
return checkFrSiren(value);
|
|
8389
|
+
if (format === "fr-siret")
|
|
8390
|
+
return checkFrSiret(value);
|
|
8391
|
+
if (format === "bj-ifu")
|
|
8392
|
+
return checkBjIfu(value);
|
|
8393
|
+
if (format === "iban")
|
|
8394
|
+
return checkIban(value);
|
|
8395
|
+
const digits = /^digits-([0-9]{1,3})$/.exec(format);
|
|
8396
|
+
if (digits)
|
|
8397
|
+
return checkDigits(value, Number(digits[1]));
|
|
8398
|
+
return value.trim().length > 0;
|
|
8399
|
+
}
|
|
8400
|
+
var IDENTITY_FORMATS = [
|
|
8401
|
+
{ id: "fr-nir", label: "France · NIR (sécurité sociale)" },
|
|
8402
|
+
{ id: "bj-npi", label: "Bénin · NPI" },
|
|
8403
|
+
{ id: "fr-siren", label: "France · SIREN" },
|
|
8404
|
+
{ id: "fr-siret", label: "France · SIRET" },
|
|
8405
|
+
{ id: "bj-ifu", label: "Bénin · IFU" },
|
|
8406
|
+
{ id: "iban", label: "IBAN" },
|
|
8407
|
+
{ id: "digits-10", label: "10 chiffres" },
|
|
8408
|
+
{ id: "digits-13", label: "13 chiffres" }
|
|
8409
|
+
];
|
|
8410
|
+
var formatIban = (value) => compact(value).replace(/(.{4})(?=.)/g, "$1 ");
|
|
8411
|
+
// lib/utils/mrz.ts
|
|
8412
|
+
var WEIGHTS = [7, 3, 1];
|
|
8413
|
+
var charValue = (char) => {
|
|
8414
|
+
if (char === "<")
|
|
8415
|
+
return 0;
|
|
8416
|
+
if (/[0-9]/.test(char))
|
|
8417
|
+
return Number(char);
|
|
8418
|
+
if (/[A-Z]/.test(char))
|
|
8419
|
+
return char.charCodeAt(0) - 55;
|
|
8420
|
+
return 0;
|
|
8421
|
+
};
|
|
8422
|
+
function mrzCheckDigit(field) {
|
|
8423
|
+
let sum = 0;
|
|
8424
|
+
for (let i = 0;i < field.length; i++)
|
|
8425
|
+
sum += charValue(field[i]) * WEIGHTS[i % 3];
|
|
8426
|
+
return sum % 10;
|
|
8427
|
+
}
|
|
8428
|
+
var checks = (field, digit) => /[0-9]/.test(digit) && mrzCheckDigit(field) === Number(digit);
|
|
8429
|
+
var clean = (field) => field.replace(/</g, " ").trim().replace(/\s+/g, " ");
|
|
8430
|
+
var names = (field) => {
|
|
8431
|
+
const [surname = "", given = ""] = field.split("<<");
|
|
8432
|
+
return { surname: clean(surname), givenNames: clean(given) };
|
|
8433
|
+
};
|
|
8434
|
+
var date = (field, kind) => {
|
|
8435
|
+
if (!/^[0-9]{6}$/.test(field))
|
|
8436
|
+
return null;
|
|
8437
|
+
const yy = Number(field.slice(0, 2));
|
|
8438
|
+
const month = field.slice(2, 4);
|
|
8439
|
+
const day = field.slice(4, 6);
|
|
8440
|
+
const now = new Date().getFullYear();
|
|
8441
|
+
const century = Math.floor(now / 100) * 100;
|
|
8442
|
+
let year = century + yy;
|
|
8443
|
+
if (kind === "birth" && year > now)
|
|
8444
|
+
year -= 100;
|
|
8445
|
+
if (kind === "expiry" && year < now - 20)
|
|
8446
|
+
year += 100;
|
|
8447
|
+
return `${year}-${month}-${day}`;
|
|
8448
|
+
};
|
|
8449
|
+
var sex = (char) => char === "M" ? "M" : char === "F" ? "F" : "X";
|
|
8450
|
+
function mrzLines(text) {
|
|
8451
|
+
return text.split(/\r?\n/).map((line) => line.replace(/\s+/g, "").toUpperCase()).filter((line) => line.length > 0);
|
|
8452
|
+
}
|
|
8453
|
+
function parseMrz(text) {
|
|
8454
|
+
const lines = mrzLines(text);
|
|
8455
|
+
if (lines.length === 2 && lines.every((line) => line.length === 44))
|
|
8456
|
+
return parseTd3(lines[0], lines[1], text);
|
|
8457
|
+
if (lines.length === 3 && lines.every((line) => line.length === 30))
|
|
8458
|
+
return parseTd1(lines[0], lines[1], lines[2], text);
|
|
8459
|
+
return null;
|
|
8460
|
+
}
|
|
8461
|
+
function parseTd3(l1, l2, raw) {
|
|
8462
|
+
const errors = [];
|
|
8463
|
+
const documentNumber = l2.slice(0, 9);
|
|
8464
|
+
if (!checks(documentNumber, l2[9]))
|
|
8465
|
+
errors.push("documentNumber");
|
|
8466
|
+
const birth = l2.slice(13, 19);
|
|
8467
|
+
if (!checks(birth, l2[19]))
|
|
8468
|
+
errors.push("birthDate");
|
|
8469
|
+
const expiry = l2.slice(21, 27);
|
|
8470
|
+
if (!checks(expiry, l2[27]))
|
|
8471
|
+
errors.push("expiryDate");
|
|
8472
|
+
const optional = l2.slice(28, 42);
|
|
8473
|
+
if (optional.replace(/</g, "") && !checks(optional, l2[42]))
|
|
8474
|
+
errors.push("optional");
|
|
8475
|
+
const composite = l2.slice(0, 10) + l2.slice(13, 20) + l2.slice(21, 43);
|
|
8476
|
+
if (!checks(composite, l2[43]))
|
|
8477
|
+
errors.push("composite");
|
|
8478
|
+
return {
|
|
8479
|
+
raw,
|
|
8480
|
+
format: "TD3",
|
|
8481
|
+
documentType: clean(l1.slice(0, 2)),
|
|
8482
|
+
issuingCountry: clean(l1.slice(2, 5)),
|
|
8483
|
+
documentNumber: clean(documentNumber),
|
|
8484
|
+
nationality: clean(l2.slice(10, 13)),
|
|
8485
|
+
...names(l1.slice(5)),
|
|
8486
|
+
birthDate: date(birth, "birth"),
|
|
8487
|
+
sex: sex(l2[20]),
|
|
8488
|
+
expiryDate: date(expiry, "expiry"),
|
|
8489
|
+
optional: clean(optional),
|
|
8490
|
+
valid: errors.length === 0,
|
|
8491
|
+
errors
|
|
8492
|
+
};
|
|
8493
|
+
}
|
|
8494
|
+
function parseTd1(l1, l2, l3, raw) {
|
|
8495
|
+
const errors = [];
|
|
8496
|
+
const documentNumber = l1.slice(5, 14);
|
|
8497
|
+
if (!checks(documentNumber, l1[14]))
|
|
8498
|
+
errors.push("documentNumber");
|
|
8499
|
+
const birth = l2.slice(0, 6);
|
|
8500
|
+
if (!checks(birth, l2[6]))
|
|
8501
|
+
errors.push("birthDate");
|
|
8502
|
+
const expiry = l2.slice(8, 14);
|
|
8503
|
+
if (!checks(expiry, l2[14]))
|
|
8504
|
+
errors.push("expiryDate");
|
|
8505
|
+
const composite = l1.slice(5, 30) + l2.slice(0, 7) + l2.slice(8, 15) + l2.slice(18, 29);
|
|
8506
|
+
if (!checks(composite, l2[29]))
|
|
8507
|
+
errors.push("composite");
|
|
8508
|
+
return {
|
|
8509
|
+
raw,
|
|
8510
|
+
format: "TD1",
|
|
8511
|
+
documentType: clean(l1.slice(0, 2)),
|
|
8512
|
+
issuingCountry: clean(l1.slice(2, 5)),
|
|
8513
|
+
documentNumber: clean(documentNumber),
|
|
8514
|
+
nationality: clean(l2.slice(15, 18)),
|
|
8515
|
+
...names(l3),
|
|
8516
|
+
birthDate: date(birth, "birth"),
|
|
8517
|
+
sex: sex(l2[7]),
|
|
8518
|
+
expiryDate: date(expiry, "expiry"),
|
|
8519
|
+
optional: clean(l1.slice(15, 30) + l2.slice(18, 29)),
|
|
8520
|
+
valid: errors.length === 0,
|
|
8521
|
+
errors
|
|
8522
|
+
};
|
|
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
|
+
}
|
|
8212
8579
|
// lib/review.ts
|
|
8213
8580
|
var flaggedKeys = (annotations) => Object.entries(annotations ?? {}).filter(([, annotation]) => annotation?.incorrect === true).map(([key]) => key);
|
|
8214
8581
|
// lib/utils/lint-spec.ts
|
|
@@ -8368,6 +8735,20 @@ var import_ajv_formats = __toESM(require_dist2(), 1);
|
|
|
8368
8735
|
var ajv = new import_ajv.Ajv({ allErrors: true });
|
|
8369
8736
|
import_ajv_formats.default(ajv, ["email", "uri"]);
|
|
8370
8737
|
import_ajv_errors.default(ajv);
|
|
8738
|
+
for (const format of ["fr-nir", "bj-npi", "fr-siren", "fr-siret", "bj-ifu", "iban", ...Array.from({ length: 20 }, (_, i) => `digits-${i + 1}`)])
|
|
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
|
+
});
|
|
8746
|
+
ajv.addKeyword({
|
|
8747
|
+
keyword: "mrzValid",
|
|
8748
|
+
type: "object",
|
|
8749
|
+
schemaType: "boolean",
|
|
8750
|
+
validate: (expected, value) => !expected || value?.valid === true
|
|
8751
|
+
});
|
|
8371
8752
|
var validatorCache = new WeakMap;
|
|
8372
8753
|
var compileFailures = new WeakMap;
|
|
8373
8754
|
var recordCompileFailure = (brickSpec, error) => {
|
|
@@ -9303,6 +9684,7 @@ export {
|
|
|
9303
9684
|
FetchDataSourceService,
|
|
9304
9685
|
FetchOptionSourceService,
|
|
9305
9686
|
FetchSpecSourceService,
|
|
9687
|
+
IDENTITY_FORMATS,
|
|
9306
9688
|
SandboxJsRunnerService,
|
|
9307
9689
|
SpecHistory,
|
|
9308
9690
|
UnsafeEvalJsRunnerService,
|
|
@@ -9310,6 +9692,15 @@ export {
|
|
|
9310
9692
|
addBrick,
|
|
9311
9693
|
appendSearchParam,
|
|
9312
9694
|
buildValidationSchema,
|
|
9695
|
+
checkBjIfu,
|
|
9696
|
+
checkBjNpi,
|
|
9697
|
+
checkDigits,
|
|
9698
|
+
checkFrNir,
|
|
9699
|
+
checkFrSiren,
|
|
9700
|
+
checkFrSiret,
|
|
9701
|
+
checkIban,
|
|
9702
|
+
checkIdentity,
|
|
9703
|
+
checkLuhn,
|
|
9313
9704
|
collectFields,
|
|
9314
9705
|
collectRecapItems,
|
|
9315
9706
|
convertFormioForm,
|
|
@@ -9322,10 +9713,13 @@ export {
|
|
|
9322
9713
|
fkT,
|
|
9323
9714
|
fkTOr,
|
|
9324
9715
|
flaggedKeys,
|
|
9716
|
+
formatIban,
|
|
9325
9717
|
frFkTranslations,
|
|
9718
|
+
generateSlots,
|
|
9326
9719
|
getAffectedProperties,
|
|
9327
9720
|
getBrickAt,
|
|
9328
9721
|
getBrickData,
|
|
9722
|
+
groupSlotsByDay,
|
|
9329
9723
|
hasNestedForms,
|
|
9330
9724
|
interpolateTemplate,
|
|
9331
9725
|
isLocalizedObject,
|
|
@@ -9333,9 +9727,13 @@ export {
|
|
|
9333
9727
|
iterateSchemaBricks,
|
|
9334
9728
|
lintSpec,
|
|
9335
9729
|
moveBrick,
|
|
9730
|
+
mrzCheckDigit,
|
|
9731
|
+
mrzLines,
|
|
9336
9732
|
normalizeOptions,
|
|
9337
9733
|
parseHeaderLines,
|
|
9734
|
+
parseMrz,
|
|
9338
9735
|
pointerFromPath,
|
|
9736
|
+
readSlots,
|
|
9339
9737
|
registerValidationMessages,
|
|
9340
9738
|
removeBrick,
|
|
9341
9739
|
resolveLocalizedRecord,
|
|
@@ -9343,6 +9741,7 @@ export {
|
|
|
9343
9741
|
runSandboxed,
|
|
9344
9742
|
services,
|
|
9345
9743
|
setFkTranslations,
|
|
9744
|
+
slotDate,
|
|
9346
9745
|
stripBrickUids,
|
|
9347
9746
|
stripUidsFromPatches,
|
|
9348
9747
|
updateBrickConfigs,
|
|
@@ -9355,5 +9754,5 @@ export {
|
|
|
9355
9754
|
wrapBrickData
|
|
9356
9755
|
};
|
|
9357
9756
|
|
|
9358
|
-
//# debugId=
|
|
9757
|
+
//# debugId=30A49B7E74D3EC6964756E2164756E21
|
|
9359
9758
|
//# sourceMappingURL=index.js.map
|