@streamline-pulse/formkrafter-core 0.28.1 → 0.30.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.
@@ -15,6 +15,8 @@ export interface BrickProps<DataType, Configs extends BrickBaseConfigs, Styles>
15
15
  dataMap?: Record<string, unknown>;
16
16
  rootSpec?: BrickSpec;
17
17
  onDataChange?: (value?: DataType) => void;
18
+ /** Sets several form keys at once (a brick that fills other fields, e.g. from a document). */
19
+ onDataPatch?: (patch: Record<string, unknown>) => void;
18
20
  onMove?: (from: string, to: string) => void;
19
21
  onDuplicate?: (path: string) => void;
20
22
  onDelete?: (path: string) => void;
package/dist/index.d.ts CHANGED
@@ -10,7 +10,10 @@ 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 { MeasureFamily, MeasureUnit, MeasureValue, MEASURE_FAMILIES, measureFamilyOf, measureUnits, unitOf, convertMeasure, measureValue, formatMeasure } from "./utils/units.js";
14
+ export { PLATE_FORMATS, REGISTRY_FORMATS, checkPlate, formatPlate, compactPlate, checkCompanyRegistry, formatCompanyRegistry } from "./utils/registries.js";
13
15
  export { Slot, SlotRules, generateSlots, readSlots, groupSlotsByDay, slotDate } from "./utils/slots.js";
16
+ export { DocumentField, parseDocumentFields, parseDocumentFills, documentFillPatch } from "./utils/documents.js";
14
17
  export { FieldAnnotation, FieldAnnotations, flaggedKeys } from "./review.js";
15
18
  export { SpecIssue, SpecIssueCode, lintSpec } from "./utils/lint-spec.js";
16
19
  export { ensureBrickUids, stripBrickUids, stripUidsFromPatches } from "./ops/uids.js";
@@ -43,4 +46,5 @@ export type { ExpandSpecOptions } from "./utils/expand-spec.js";
43
46
  export { FetchSpecSourceService } from "./services/spec_source_service.js";
44
47
  export type { SpecSourceService, FetchSpecSourceDefaults } from "./services/spec_source_service.js";
45
48
  export { FetchOptionSourceService } from "./services/option_source_service.js";
49
+ export { DocumentReading, DocumentReadOptions, DocumentReaderService, FetchDocumentReaderDefaults, FetchDocumentReaderService, readDocumentReading, } from "./services/document_reader_service.js";
46
50
  export type { OptionSourceService, FetchOptionSourceDefaults } from "./services/option_source_service.js";
package/dist/index.js CHANGED
@@ -6924,7 +6924,9 @@ var DEFAULT_MESSAGES = {
6924
6924
  identity: "Invalid identifier for this format",
6925
6925
  iban: "Invalid IBAN",
6926
6926
  dateRange: "The end before the start is not allowed",
6927
- mrz: "Machine-readable zone unreadable or inconsistent"
6927
+ mrz: "Machine-readable zone unreadable or inconsistent",
6928
+ plate: "Invalid registration plate for this format",
6929
+ registry: "Invalid registration number for this format"
6928
6930
  },
6929
6931
  fr: {
6930
6932
  required: "Ce champ est obligatoire",
@@ -6942,7 +6944,9 @@ var DEFAULT_MESSAGES = {
6942
6944
  identity: "Identifiant invalide pour ce format",
6943
6945
  iban: "IBAN invalide",
6944
6946
  dateRange: "La fin ne peut pas précéder le début",
6945
- mrz: "Zone de lecture illisible ou incohérente"
6947
+ mrz: "Zone de lecture illisible ou incohérente",
6948
+ plate: "Immatriculation invalide pour ce format",
6949
+ registry: "Numéro d’immatriculation invalide pour ce format"
6946
6950
  }
6947
6951
  };
6948
6952
  function registerValidationMessages(locale, messages) {
@@ -7051,6 +7055,16 @@ function buildValidationSchema(brickSpecs, locale) {
7051
7055
  property.dateRange = true;
7052
7056
  messages.dateRange = defaultValidationMessage("dateRange", locale);
7053
7057
  }
7058
+ if (brick.id === "vehicle-plate") {
7059
+ const format = typeof brick.configs?.plateFormat === "string" && brick.configs.plateFormat ? brick.configs.plateFormat : "generic";
7060
+ property.format = `plate-${format}`;
7061
+ messages.format = defaultValidationMessage("plate", locale);
7062
+ }
7063
+ if (brick.id === "company-registry") {
7064
+ const format = typeof brick.configs?.registryFormat === "string" && brick.configs.registryFormat ? brick.configs.registryFormat : "generic";
7065
+ property.format = `registry-${format}`;
7066
+ messages.format = defaultValidationMessage("registry", locale);
7067
+ }
7054
7068
  if (brick.id === "mrz") {
7055
7069
  property.mrzValid = true;
7056
7070
  messages.mrzValid = defaultValidationMessage("mrz", locale);
@@ -7309,6 +7323,38 @@ var en = {
7309
7323
  "slots.picked": "Chosen slot:",
7310
7324
  "range.from": "From",
7311
7325
  "range.to": "To",
7326
+ "category.Documents": "Documents",
7327
+ "brick.document.name": "Document reading",
7328
+ "document.choose": "Choose a document…",
7329
+ "document.capture": "Take a photo",
7330
+ "document.reading": "Reading the document…",
7331
+ "document.read": "Document read",
7332
+ "document.none": "No document",
7333
+ "document.text": "Text read",
7334
+ "document.fields": "Fields read",
7335
+ "document.notFound": "not found",
7336
+ "document.remove": "Remove document",
7337
+ "document.noReader": "No document reader configured",
7338
+ "document.failed": "The document could not be read",
7339
+ "document.filled": "Fields filled from the document:",
7340
+ "panel.readUrl": "Reader URL (empty = host default)",
7341
+ "panel.documentFields": "Fields to read (key|Label per line)",
7342
+ "panel.documentFills": "Fill the form (field=formKey per line)",
7343
+ "panel.documentLanguage": "Document language (fr, en…)",
7344
+ "panel.cfg.capture": "Offer the camera on mobile",
7345
+ "panel.cfg.keepFile": "Keep the file in the answer",
7346
+ "category.Measures": "Measures",
7347
+ "category.Registries": "Vehicles & companies",
7348
+ "brick.measure.name": "Measure",
7349
+ "brick.vehicle-plate.name": "Vehicle plate",
7350
+ "brick.company-registry.name": "Company registration",
7351
+ "measure.value": "Value",
7352
+ "measure.unit": "Unit",
7353
+ "panel.family": "Measure family (length, area, mass, volume, duration)",
7354
+ "panel.units": "Units offered (ids, comma-separated; empty = all)",
7355
+ "panel.unit": "Default unit",
7356
+ "panel.plateFormat": "Plate format (fr, bj, ci, sn, generic)",
7357
+ "panel.registryFormat": "Registration format (ohada-rccm, fr-rcs, generic)",
7312
7358
  "panel.slotsUrl": "Slots URL (empty = opening rules)",
7313
7359
  "panel.slotDays": "Open days (1 = Monday … 7 = Sunday)",
7314
7360
  "panel.slotFrom": "Opens at",
@@ -7514,6 +7560,38 @@ var frFkTranslations = {
7514
7560
  "slots.picked": "Créneau choisi :",
7515
7561
  "range.from": "Du",
7516
7562
  "range.to": "Au",
7563
+ "category.Documents": "Documents",
7564
+ "brick.document.name": "Lecture de document",
7565
+ "document.choose": "Choisir un document…",
7566
+ "document.capture": "Prendre une photo",
7567
+ "document.reading": "Lecture du document…",
7568
+ "document.read": "Document lu",
7569
+ "document.none": "Aucun document",
7570
+ "document.text": "Texte lu",
7571
+ "document.fields": "Champs lus",
7572
+ "document.notFound": "non trouvé",
7573
+ "document.remove": "Retirer le document",
7574
+ "document.noReader": "Aucun lecteur de document configuré",
7575
+ "document.failed": "Le document n’a pas pu être lu",
7576
+ "document.filled": "Champs remplis depuis le document :",
7577
+ "panel.readUrl": "URL du lecteur (vide = celle de l’hôte)",
7578
+ "panel.documentFields": "Champs à lire (clé|Libellé par ligne)",
7579
+ "panel.documentFills": "Remplir le formulaire (champ=cléFormulaire par ligne)",
7580
+ "panel.documentLanguage": "Langue du document (fr, en…)",
7581
+ "panel.cfg.capture": "Proposer l’appareil photo sur mobile",
7582
+ "panel.cfg.keepFile": "Conserver le fichier dans la réponse",
7583
+ "category.Measures": "Mesures",
7584
+ "category.Registries": "Véhicules & entreprises",
7585
+ "brick.measure.name": "Mesure",
7586
+ "brick.vehicle-plate.name": "Immatriculation",
7587
+ "brick.company-registry.name": "Registre d’entreprise",
7588
+ "measure.value": "Valeur",
7589
+ "measure.unit": "Unité",
7590
+ "panel.family": "Famille de mesure (length, area, mass, volume, duration)",
7591
+ "panel.units": "Unités proposées (identifiants séparés par des virgules ; vide = toutes)",
7592
+ "panel.unit": "Unité par défaut",
7593
+ "panel.plateFormat": "Format d’immatriculation (fr, bj, ci, sn, generic)",
7594
+ "panel.registryFormat": "Format du registre (ohada-rccm, fr-rcs, generic)",
7517
7595
  "panel.slotsUrl": "URL des créneaux (vide = règles d’ouverture)",
7518
7596
  "panel.slotDays": "Jours ouverts (1 = lundi … 7 = dimanche)",
7519
7597
  "panel.slotFrom": "Ouverture",
@@ -8127,6 +8205,67 @@ class FetchOptionSourceService {
8127
8205
  }
8128
8206
  }
8129
8207
 
8208
+ // lib/services/document_reader_service.ts
8209
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
8210
+ function readDocumentReading(payload) {
8211
+ const root = asRecord(payload) ?? {};
8212
+ const data = asRecord(root.data) ?? root;
8213
+ const text = typeof data.text === "string" ? data.text : typeof data.md_content === "string" ? data.md_content : typeof data.content === "string" ? data.content : undefined;
8214
+ const reading = {};
8215
+ if (text !== undefined)
8216
+ reading.text = text;
8217
+ const fields = asRecord(data.fields);
8218
+ if (fields)
8219
+ reading.fields = fields;
8220
+ if (typeof data.pages === "number")
8221
+ reading.pages = data.pages;
8222
+ if (typeof data.engine === "string")
8223
+ reading.engine = data.engine;
8224
+ if (typeof data.confidence === "number")
8225
+ reading.confidence = data.confidence;
8226
+ if (Array.isArray(data.warnings))
8227
+ reading.warnings = data.warnings.filter((w) => typeof w === "string");
8228
+ return reading;
8229
+ }
8230
+
8231
+ class FetchDocumentReaderService {
8232
+ defaults;
8233
+ constructor(defaults = {}) {
8234
+ this.defaults = defaults;
8235
+ }
8236
+ async read(file, options = {}) {
8237
+ const url = options.url || this.defaults.url;
8238
+ if (!url)
8239
+ throw new Error("No document reader URL configured");
8240
+ const body = new FormData;
8241
+ const blob = file instanceof Blob ? file : new Blob([await file.arrayBuffer()], { type: file.type });
8242
+ body.append(this.defaults.fieldName ?? "file", blob, file.name);
8243
+ if (options.fields?.length)
8244
+ body.append("fields", options.fields.map((field) => field.key).join(","));
8245
+ if (options.fields?.length)
8246
+ body.append("fieldLabels", JSON.stringify(Object.fromEntries(options.fields.map((f) => [f.key, f.label ?? f.key]))));
8247
+ if (options.language)
8248
+ body.append("language", options.language);
8249
+ const doFetch = this.defaults.fetch ?? globalThis.fetch.bind(globalThis);
8250
+ const response = await doFetch(url, {
8251
+ method: "POST",
8252
+ body,
8253
+ credentials: this.defaults.credentials,
8254
+ headers: { accept: "application/json", ...this.defaults.headers, ...options.headers }
8255
+ });
8256
+ if (!response.ok) {
8257
+ let message = `Document reading failed (${response.status})`;
8258
+ try {
8259
+ const payload = await response.json();
8260
+ if (payload?.message)
8261
+ message = payload.message;
8262
+ } catch {}
8263
+ throw new Error(message);
8264
+ }
8265
+ return readDocumentReading(await response.json());
8266
+ }
8267
+ }
8268
+
8130
8269
  // lib/services/index.ts
8131
8270
  var GLOBAL_KEY2 = Symbol.for("formkrafter.core.services");
8132
8271
  var globalStore2 = globalThis;
@@ -8135,10 +8274,12 @@ var services = globalStore2[GLOBAL_KEY2] ??= {
8135
8274
  dataSourceService: new FetchDataSourceService,
8136
8275
  fileUploadService: new Base64FileUploadService,
8137
8276
  specSourceService: new FetchSpecSourceService,
8138
- optionSourceService: new FetchOptionSourceService
8277
+ optionSourceService: new FetchOptionSourceService,
8278
+ documentReaderService: new FetchDocumentReaderService
8139
8279
  };
8140
8280
  services.specSourceService ??= new FetchSpecSourceService;
8141
8281
  services.optionSourceService ??= new FetchOptionSourceService;
8282
+ services.documentReaderService ??= new FetchDocumentReaderService;
8142
8283
 
8143
8284
  // lib/brick/utils.ts
8144
8285
  var evalBrickCode = (code, data) => {
@@ -8521,6 +8662,150 @@ function parseTd1(l1, l2, l3, raw) {
8521
8662
  errors
8522
8663
  };
8523
8664
  }
8665
+ // lib/utils/units.ts
8666
+ var MEASURE_FAMILIES = {
8667
+ length: {
8668
+ base: "m",
8669
+ units: [
8670
+ { id: "mm", symbol: "mm", factor: 0.001 },
8671
+ { id: "cm", symbol: "cm", factor: 0.01 },
8672
+ { id: "m", symbol: "m", factor: 1 },
8673
+ { id: "km", symbol: "km", factor: 1000 }
8674
+ ]
8675
+ },
8676
+ area: {
8677
+ base: "m2",
8678
+ units: [
8679
+ { id: "m2", symbol: "m²", factor: 1 },
8680
+ { id: "a", symbol: "a", factor: 100 },
8681
+ { id: "ha", symbol: "ha", factor: 1e4 },
8682
+ { id: "km2", symbol: "km²", factor: 1e6 }
8683
+ ]
8684
+ },
8685
+ mass: {
8686
+ base: "kg",
8687
+ units: [
8688
+ { id: "g", symbol: "g", factor: 0.001 },
8689
+ { id: "kg", symbol: "kg", factor: 1 },
8690
+ { id: "t", symbol: "t", factor: 1000 }
8691
+ ]
8692
+ },
8693
+ volume: {
8694
+ base: "l",
8695
+ units: [
8696
+ { id: "ml", symbol: "ml", factor: 0.001 },
8697
+ { id: "l", symbol: "l", factor: 1 },
8698
+ { id: "m3", symbol: "m³", factor: 1000 }
8699
+ ]
8700
+ },
8701
+ duration: {
8702
+ base: "h",
8703
+ units: [
8704
+ { id: "min", symbol: "min", factor: 1 / 60 },
8705
+ { id: "h", symbol: "h", factor: 1 },
8706
+ { id: "d", symbol: "j", factor: 24 }
8707
+ ]
8708
+ }
8709
+ };
8710
+ var measureFamilyOf = (value) => typeof value === "string" && (value in MEASURE_FAMILIES) ? value : "length";
8711
+ function measureUnits(family, allowed) {
8712
+ const all = MEASURE_FAMILIES[family].units;
8713
+ if (typeof allowed !== "string" || !allowed.trim())
8714
+ return all;
8715
+ const wanted = allowed.split(",").map((id) => id.trim().toLowerCase()).filter(Boolean);
8716
+ const picked = all.filter((unit) => wanted.includes(unit.id));
8717
+ return picked.length ? picked : all;
8718
+ }
8719
+ function unitOf(family, id) {
8720
+ return MEASURE_FAMILIES[family].units.find((unit) => unit.id === id);
8721
+ }
8722
+ var round = (n) => Math.round(n * 1e9) / 1e9;
8723
+ function convertMeasure(family, value, from, to) {
8724
+ const source = unitOf(family, from);
8725
+ const target = unitOf(family, to);
8726
+ if (!source || !target)
8727
+ return;
8728
+ return round(value * source.factor / target.factor);
8729
+ }
8730
+ function measureValue(family, value, unit) {
8731
+ const source = unitOf(family, unit);
8732
+ if (!source || !Number.isFinite(value))
8733
+ return;
8734
+ return { value, unit, base: round(value * source.factor) };
8735
+ }
8736
+ function formatMeasure(family, value, locale) {
8737
+ if (!value)
8738
+ return "";
8739
+ const unit = unitOf(family, value.unit);
8740
+ const number = new Intl.NumberFormat(locale, { maximumFractionDigits: 3 }).format(value.value);
8741
+ return `${number} ${unit?.symbol ?? value.unit}`;
8742
+ }
8743
+ // lib/utils/registries.ts
8744
+ var compact2 = (value) => value.replace(/[\s.-]/g, "").toUpperCase();
8745
+ var group = (value, pattern, template) => value.replace(pattern, template);
8746
+ var PLATE_FORMATS = [
8747
+ {
8748
+ id: "fr",
8749
+ label: "France · AA-123-AA",
8750
+ test: (v) => /^[A-HJ-NP-Z]{2}\d{3}[A-HJ-NP-Z]{2}$/.test(v),
8751
+ format: (v) => group(v, /^([A-Z]{2})(\d{3})([A-Z]{2})$/, "$1-$2-$3")
8752
+ },
8753
+ {
8754
+ id: "bj",
8755
+ label: "Bénin · AB 1234 RB",
8756
+ test: (v) => /^[A-Z]{1,2}\d{4}[A-Z]{2}$/.test(v),
8757
+ format: (v) => group(v, /^([A-Z]{1,2})(\d{4})([A-Z]{2})$/, "$1 $2 $3")
8758
+ },
8759
+ {
8760
+ id: "ci",
8761
+ label: "Côte d’Ivoire · 1234 AB 01",
8762
+ test: (v) => /^\d{4}[A-Z]{2}\d{2}$/.test(v),
8763
+ format: (v) => group(v, /^(\d{4})([A-Z]{2})(\d{2})$/, "$1 $2 $3")
8764
+ },
8765
+ {
8766
+ id: "sn",
8767
+ label: "Sénégal · AA 123 AA",
8768
+ test: (v) => /^[A-Z]{2}\d{3,4}[A-Z]{1,2}$/.test(v),
8769
+ format: (v) => group(v, /^([A-Z]{2})(\d{3,4})([A-Z]{1,2})$/, "$1 $2 $3")
8770
+ },
8771
+ { id: "generic", label: "Libre (4 à 10 lettres ou chiffres)", test: (v) => /^[A-Z0-9]{4,10}$/.test(v) }
8772
+ ];
8773
+ var REGISTRY_FORMATS = [
8774
+ {
8775
+ id: "ohada-rccm",
8776
+ label: "OHADA · RCCM (RB/COT/01 B 1234)",
8777
+ test: (v) => /^[A-Z]{2}\/[A-Z]{2,4}\/\d{2,4}[A-Z]\d{3,7}$/.test(v.replace(/[\s]/g, "")),
8778
+ format: (v) => v.replace(/^([A-Z]{2}\/[A-Z]{2,4}\/\d{2,4})([A-Z])(\d{3,7})$/, "$1 $2 $3")
8779
+ },
8780
+ {
8781
+ id: "fr-rcs",
8782
+ label: "France · RCS (SIREN + ville)",
8783
+ test: (v) => /^\d{9}RCS[A-Z]{2,}$/.test(v.replace(/[\s]/g, "")),
8784
+ format: (v) => v.replace(/^(\d{3})(\d{3})(\d{3})RCS(.+)$/, "$1 $2 $3 RCS $4")
8785
+ },
8786
+ { id: "generic", label: "Libre (4 à 20 caractères)", test: (v) => /^[A-Z0-9/-]{4,20}$/.test(v) }
8787
+ ];
8788
+ var find = (list, id) => list.find((format) => format.id === id);
8789
+ var compactPlate = (value) => compact2(value);
8790
+ function checkPlate(format, value) {
8791
+ const rule = find(PLATE_FORMATS, format) ?? find(PLATE_FORMATS, "generic");
8792
+ return rule.test(compact2(value));
8793
+ }
8794
+ function formatPlate(format, value) {
8795
+ const rule = find(PLATE_FORMATS, format);
8796
+ const compacted = compact2(value);
8797
+ return rule?.format && rule.test(compacted) ? rule.format(compacted) : value.trim().toUpperCase();
8798
+ }
8799
+ var compactRegistry = (value) => value.replace(/\s+/g, "").toUpperCase();
8800
+ function checkCompanyRegistry(format, value) {
8801
+ const rule = find(REGISTRY_FORMATS, format) ?? find(REGISTRY_FORMATS, "generic");
8802
+ return rule.test(compactRegistry(value));
8803
+ }
8804
+ function formatCompanyRegistry(format, value) {
8805
+ const rule = find(REGISTRY_FORMATS, format);
8806
+ const compacted = compactRegistry(value);
8807
+ return rule?.format && rule.test(compacted) ? rule.format(compacted) : value.trim().toUpperCase();
8808
+ }
8524
8809
  // lib/utils/slots.ts
8525
8810
  var pad = (n) => String(n).padStart(2, "0");
8526
8811
  var localIso = (date) => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
@@ -8576,6 +8861,58 @@ function groupSlotsByDay(slots) {
8576
8861
  }
8577
8862
  return [...byDay.entries()].map(([day, list]) => ({ day, slots: list }));
8578
8863
  }
8864
+ // lib/utils/documents.ts
8865
+ function parseDocumentFields(source) {
8866
+ if (Array.isArray(source))
8867
+ return source.filter((item) => !!item && typeof item === "object" && typeof item.key === "string").map((item) => ({ key: item.key.trim(), ...item.label ? { label: item.label } : {} })).filter((item) => item.key);
8868
+ if (typeof source !== "string")
8869
+ return [];
8870
+ const out = [];
8871
+ const seen = new Set;
8872
+ for (const raw of source.split(/\r?\n/)) {
8873
+ const line = raw.trim();
8874
+ if (!line || line.startsWith("#"))
8875
+ continue;
8876
+ const [keyPart, ...labelParts] = line.split("|");
8877
+ const key = (keyPart ?? "").trim();
8878
+ if (!key || seen.has(key))
8879
+ continue;
8880
+ seen.add(key);
8881
+ const label = labelParts.join("|").trim();
8882
+ out.push(label ? { key, label } : { key });
8883
+ }
8884
+ return out;
8885
+ }
8886
+ function parseDocumentFills(source) {
8887
+ if (typeof source !== "string")
8888
+ return {};
8889
+ const out = {};
8890
+ for (const raw of source.split(/\r?\n/)) {
8891
+ const line = raw.trim();
8892
+ if (!line || line.startsWith("#"))
8893
+ continue;
8894
+ const index = line.indexOf("=");
8895
+ if (index === -1)
8896
+ continue;
8897
+ const field = line.slice(0, index).trim();
8898
+ const target = line.slice(index + 1).trim();
8899
+ if (field && target)
8900
+ out[field] = target;
8901
+ }
8902
+ return out;
8903
+ }
8904
+ function documentFillPatch(fields, fills) {
8905
+ const patch = {};
8906
+ if (!fields)
8907
+ return patch;
8908
+ for (const [field, target] of Object.entries(fills)) {
8909
+ const value = fields[field];
8910
+ if (value === undefined || value === null || value === "")
8911
+ continue;
8912
+ patch[target] = value;
8913
+ }
8914
+ return patch;
8915
+ }
8579
8916
  // lib/review.ts
8580
8917
  var flaggedKeys = (annotations) => Object.entries(annotations ?? {}).filter(([, annotation]) => annotation?.incorrect === true).map(([key]) => key);
8581
8918
  // lib/utils/lint-spec.ts
@@ -8737,6 +9074,10 @@ import_ajv_formats.default(ajv, ["email", "uri"]);
8737
9074
  import_ajv_errors.default(ajv);
8738
9075
  for (const format of ["fr-nir", "bj-npi", "fr-siren", "fr-siret", "bj-ifu", "iban", ...Array.from({ length: 20 }, (_, i) => `digits-${i + 1}`)])
8739
9076
  ajv.addFormat(`identity-${format}`, (value) => checkIdentity(format, value));
9077
+ for (const { id } of PLATE_FORMATS)
9078
+ ajv.addFormat(`plate-${id}`, (value) => checkPlate(id, value));
9079
+ for (const { id } of REGISTRY_FORMATS)
9080
+ ajv.addFormat(`registry-${id}`, (value) => checkCompanyRegistry(id, value));
8740
9081
  ajv.addKeyword({
8741
9082
  keyword: "dateRange",
8742
9083
  type: "object",
@@ -9682,9 +10023,13 @@ export {
9682
10023
  Base64FileUploadService,
9683
10024
  Brick,
9684
10025
  FetchDataSourceService,
10026
+ FetchDocumentReaderService,
9685
10027
  FetchOptionSourceService,
9686
10028
  FetchSpecSourceService,
9687
10029
  IDENTITY_FORMATS,
10030
+ MEASURE_FAMILIES,
10031
+ PLATE_FORMATS,
10032
+ REGISTRY_FORMATS,
9688
10033
  SandboxJsRunnerService,
9689
10034
  SpecHistory,
9690
10035
  UnsafeEvalJsRunnerService,
@@ -9694,6 +10039,7 @@ export {
9694
10039
  buildValidationSchema,
9695
10040
  checkBjIfu,
9696
10041
  checkBjNpi,
10042
+ checkCompanyRegistry,
9697
10043
  checkDigits,
9698
10044
  checkFrNir,
9699
10045
  checkFrSiren,
@@ -9701,11 +10047,15 @@ export {
9701
10047
  checkIban,
9702
10048
  checkIdentity,
9703
10049
  checkLuhn,
10050
+ checkPlate,
9704
10051
  collectFields,
9705
10052
  collectRecapItems,
10053
+ compactPlate,
9706
10054
  convertFormioForm,
10055
+ convertMeasure,
9707
10056
  defaultFormData,
9708
10057
  defaultValidationMessage,
10058
+ documentFillPatch,
9709
10059
  duplicateBrick,
9710
10060
  ensureBrickUids,
9711
10061
  evalBrickCode,
@@ -9713,7 +10063,10 @@ export {
9713
10063
  fkT,
9714
10064
  fkTOr,
9715
10065
  flaggedKeys,
10066
+ formatCompanyRegistry,
9716
10067
  formatIban,
10068
+ formatMeasure,
10069
+ formatPlate,
9717
10070
  frFkTranslations,
9718
10071
  generateSlots,
9719
10072
  getAffectedProperties,
@@ -9726,13 +10079,19 @@ export {
9726
10079
  iterateBricks,
9727
10080
  iterateSchemaBricks,
9728
10081
  lintSpec,
10082
+ measureFamilyOf,
10083
+ measureUnits,
10084
+ measureValue,
9729
10085
  moveBrick,
9730
10086
  mrzCheckDigit,
9731
10087
  mrzLines,
9732
10088
  normalizeOptions,
10089
+ parseDocumentFields,
10090
+ parseDocumentFills,
9733
10091
  parseHeaderLines,
9734
10092
  parseMrz,
9735
10093
  pointerFromPath,
10094
+ readDocumentReading,
9736
10095
  readSlots,
9737
10096
  registerValidationMessages,
9738
10097
  removeBrick,
@@ -9744,6 +10103,7 @@ export {
9744
10103
  slotDate,
9745
10104
  stripBrickUids,
9746
10105
  stripUidsFromPatches,
10106
+ unitOf,
9747
10107
  updateBrickConfigs,
9748
10108
  updateBrickRules,
9749
10109
  updateBrickStyles,
@@ -9754,5 +10114,5 @@ export {
9754
10114
  wrapBrickData
9755
10115
  };
9756
10116
 
9757
- //# debugId=30A49B7E74D3EC6964756E2164756E21
10117
+ //# debugId=4C355ABE22E4DDEC64756E2164756E21
9758
10118
  //# sourceMappingURL=index.js.map