From 920d52bcc0c13939ede4c16cf1c56c4c8c9138e4 Mon Sep 17 00:00:00 2001 From: Emmanuel Raviart Date: Sun, 12 Feb 2023 13:39:07 +0100 Subject: [PATCH] Add validation of JORF SECTION_TA and improve other validations --- src/lib/auditors/dole.ts | 24 +- src/lib/auditors/jorf/articles.ts | 26 +- src/lib/auditors/jorf/index.ts | 1 + src/lib/auditors/jorf/jo.ts | 24 +- src/lib/auditors/jorf/section_ta.ts | 516 ++++++++++++++++++++++++++++ src/lib/auditors/legi/articles.ts | 214 ++++-------- src/lib/legal/index.ts | 30 +- src/lib/legal/jorf.ts | 309 ++++++++++++----- src/lib/legal/legi.ts | 37 +- src/scripts/import_jorf.ts | 15 +- 10 files changed, 904 insertions(+), 292 deletions(-) create mode 100644 src/lib/auditors/jorf/section_ta.ts diff --git a/src/lib/auditors/dole.ts b/src/lib/auditors/dole.ts index 57014af..07b7327 100644 --- a/src/lib/auditors/dole.ts +++ b/src/lib/auditors/dole.ts @@ -1,18 +1,18 @@ import { - type Audit, - auditRequire, - auditDateIso8601String, - auditTrimString, - auditInteger, - auditFunction, - auditEmptyToNull, - auditNullish, - auditSwitch, - auditString, - auditTest, - auditNumber, auditCleanArray, + auditDateIso8601String, + auditEmptyToNull, + auditFunction, + auditInteger, + auditNullish, + auditNumber, auditOptions, + auditRequire, + auditString, + auditSwitch, + auditTest, + auditTrimString, + type Audit, } from "@auditors/core" function auditArborescence( diff --git a/src/lib/auditors/jorf/articles.ts b/src/lib/auditors/jorf/articles.ts index e619489..970c865 100644 --- a/src/lib/auditors/jorf/articles.ts +++ b/src/lib/auditors/jorf/articles.ts @@ -1,17 +1,17 @@ import { - type Audit, - auditRequire, - auditDateIso8601String, - auditTrimString, - auditInteger, - auditFunction, - auditEmptyToNull, - auditNullish, - auditSwitch, - auditNumber, auditCleanArray, - auditOptions, + auditDateIso8601String, + auditEmptyToNull, + auditFunction, auditHttpUrl, + auditInteger, + auditNullish, + auditNumber, + auditOptions, + auditRequire, + auditSwitch, + auditTrimString, + type Audit, } from "@auditors/core" import { @@ -590,7 +590,7 @@ function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditFunction((titreTxt) => Array.isArray(titreTxt) ? titreTxt : [titreTxt], ), - auditCleanArray(auditTitreTxt), + auditCleanArray(auditTitreTxt, auditRequire), auditRequire, ) audit.attribute(data, "TM", true, errors, remainingKeys, auditTm) @@ -781,7 +781,7 @@ function auditVersions(audit: Audit, dataUnknown: unknown): [unknown, unknown] { errors, remainingKeys, auditFunction((version) => (Array.isArray(version) ? version : [version])), - auditCleanArray(auditVersion), + auditCleanArray(auditVersion, auditRequire), auditRequire, ) diff --git a/src/lib/auditors/jorf/index.ts b/src/lib/auditors/jorf/index.ts index dfda818..bd35cdc 100644 --- a/src/lib/auditors/jorf/index.ts +++ b/src/lib/auditors/jorf/index.ts @@ -1,2 +1,3 @@ export { auditJo, joStats } from "./jo" export { auditJorfArticle, jorfArticleStats } from "./articles" +export { auditJorfSectionTa, jorfSectionTaStats } from "./section_ta" diff --git a/src/lib/auditors/jorf/jo.ts b/src/lib/auditors/jorf/jo.ts index c16f184..efb4c84 100644 --- a/src/lib/auditors/jorf/jo.ts +++ b/src/lib/auditors/jorf/jo.ts @@ -1,18 +1,18 @@ import { - type Audit, - auditRequire, - auditDateIso8601String, - auditTrimString, - auditInteger, - auditFunction, - auditEmptyToNull, - auditNullish, - auditSwitch, - auditNumber, auditCleanArray, - auditOptions, + auditDateIso8601String, + auditEmptyToNull, + auditFunction, auditHttpUrl, + auditInteger, + auditNullish, + auditNumber, + auditOptions, + auditRequire, auditStringToNumber, + auditSwitch, + auditTrimString, + type Audit, } from "@auditors/core" import { allJoNaturesMutable, allJoOriginesMutable } from "$lib/legal" @@ -340,7 +340,7 @@ function auditTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { errors, remainingKeys, auditStringToNumber, - auditNumber, + auditInteger, auditRequire, ) audit.attribute( diff --git a/src/lib/auditors/jorf/section_ta.ts b/src/lib/auditors/jorf/section_ta.ts new file mode 100644 index 0000000..efb9f92 --- /dev/null +++ b/src/lib/auditors/jorf/section_ta.ts @@ -0,0 +1,516 @@ +import { + auditCleanArray, + auditDateIso8601String, + auditEmptyToNull, + auditFunction, + auditInteger, + auditNullish, + auditOptions, + auditRequire, + auditStringToNumber, + auditSwitch, + auditTrimString, + type Audit, +} from "@auditors/core" + +import { + allJorfSectionTaLienArtEtatsMutable, + allJorfSectionTaLienArtOriginesMutable, + // allJorfSectionTaLienSectionTaEtatsMutable, + allJorfSectionTaTexteNaturesMutable, +} from "$lib/legal" + +export const jorfSectionTaStats: { + countByLienArtEtat: { [etat: string]: number } + countByLienArtOrigine: { [origine: string]: number } + countByLienSectionTaEtat: { [etat: string]: number } + countByTexteNature: { [nature: string]: number } +} = { + countByLienArtEtat: {}, + countByLienArtOrigine: {}, + countByLienSectionTaEtat: {}, + countByTexteNature: {}, +} + +function auditContexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + audit.attribute( + data, + "TEXTE", + true, + errors, + remainingKeys, + auditTexte, + auditRequire, + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +export function auditJorfSectionTa( + audit: Audit, + dataUnknown: unknown, +): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + for (const key of ["COMMENTAIRE", "TITRE_TA"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + } + audit.attribute( + data, + "CONTEXTE", + true, + errors, + remainingKeys, + auditContexte, + auditRequire, + ) + audit.attribute( + data, + "ID", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + audit.attribute( + data, + "STRUCTURE_TA", + true, + errors, + remainingKeys, + auditSwitch( + [auditTrimString, auditEmptyToNull, auditNullish], + auditStructureTa, + ), + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditLienArt(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + for (const key of ["@debut", "@fin"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditDateIso8601String, + auditRequire, + ) + } + audit.attribute( + data, + "@etat", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + // auditFunction((etat) => { + // jorfSectionTaStats.countByLienArtEtat[etat] = + // (jorfSectionTaStats.countByLienArtEtat[etat] ?? 0) + 1 + // return etat + // }), + auditOptions(allJorfSectionTaLienArtEtatsMutable), + ) + audit.attribute( + data, + "@id", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + audit.attribute( + data, + "@num", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + audit.attribute( + data, + "@origine", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + // auditFunction((origine) => { + // jorfSectionTaStats.countByLienArtOrigine[origine] = + // (jorfSectionTaStats.countByLienArtOrigine[origine] ?? 0) + 1 + // return origine + // }), + auditOptions(allJorfSectionTaLienArtOriginesMutable), + auditRequire, + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditLienSectionTa( + audit: Audit, + dataUnknown: unknown, +): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + for (const key of ["#text"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + } + for (const key of ["@cid", "@id", "@url"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + } + for (const key of ["@debut", "@fin"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditDateIso8601String, + auditRequire, + ) + } + audit.attribute( + data, + "@etat", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditNullish, + // auditFunction((etat) => { + // jorfSectionTaStats.countByLienSectionTaEtat[etat] = + // (jorfSectionTaStats.countByLienSectionTaEtat[etat] ?? 0) + 1 + // return etat + // }), + // auditOptions(allJorfSectionTaLienSectionTaEtatsMutable), + auditNullish, + ) + audit.attribute( + data, + "@niv", + true, + errors, + remainingKeys, + auditStringToNumber, + auditInteger, + auditRequire, + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditStructureTa( + audit: Audit, + dataUnknown: unknown, +): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + audit.attribute( + data, + "LIEN_ART", + true, + errors, + remainingKeys, + auditFunction((lien) => (Array.isArray(lien) ? lien : [lien])), + auditCleanArray(auditLienArt, auditRequire), + ) + audit.attribute( + data, + "LIEN_SECTION_TA", + true, + errors, + remainingKeys, + auditFunction((lien) => (Array.isArray(lien) ? lien : [lien])), + auditCleanArray(auditLienSectionTa, auditRequire), + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + for (const key of [ + "@autorite", + "@ministere", + "@nor", + "@num", + "@num_parution_jo", + ]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + } + audit.attribute( + data, + "@cid", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + for (const key of ["@date_publi", "@date_signature"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + // auditFunction((date) => date.replace(/^11992-12-27$/, "1992-12-27")), + auditDateIso8601String, + auditRequire, + ) + } + audit.attribute( + data, + "@nature", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + // auditFunction((nature) => { + // jorfSectionTaStats.countByTexteNature[nature] = + // (jorfSectionTaStats.countByTexteNature[nature] ?? 0) + 1 + // return nature + // }), + auditOptions(allJorfSectionTaTexteNaturesMutable), + ) + audit.attribute( + data, + "TITRE_TXT", + true, + errors, + remainingKeys, + auditFunction((titreTxt) => + Array.isArray(titreTxt) ? titreTxt : [titreTxt], + ), + auditCleanArray(auditTitreTxt, auditRequire), + auditRequire, + ) + audit.attribute(data, "TM", true, errors, remainingKeys, auditTm) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditTitreTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + audit.attribute( + data, + "#text", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + for (const key of ["@debut", "@fin"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditDateIso8601String, + auditRequire, + ) + } + audit.attribute( + data, + "@id", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +function auditTitreTxt(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + for (const key of ["#text", "@id_txt"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + } + audit.attribute( + data, + "@c_titre_court", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + for (const key of ["@debut", "@fin"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditDateIso8601String, + auditRequire, + ) + } + + return audit.reduceRemaining(data, errors, remainingKeys) +} + +/// Table des matières +function auditTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { + if (dataUnknown == null) { + return [dataUnknown, null] + } + if (typeof dataUnknown !== "object") { + return audit.unexpectedType(dataUnknown, "object") + } + + const data = { ...dataUnknown } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + audit.attribute( + data, + "TITRE_TM", + true, + errors, + remainingKeys, + auditTitreTm, + auditRequire, + ) + audit.attribute(data, "TM", true, errors, remainingKeys, auditTm) + + return audit.reduceRemaining(data, errors, remainingKeys) +} diff --git a/src/lib/auditors/legi/articles.ts b/src/lib/auditors/legi/articles.ts index 6c556d1..ea2cee5 100644 --- a/src/lib/auditors/legi/articles.ts +++ b/src/lib/auditors/legi/articles.ts @@ -1,21 +1,20 @@ import { - type Audit, - auditRequire, - auditDateIso8601String, - auditTrimString, - auditInteger, - auditFunction, - auditEmptyToNull, - auditSwitch, - auditNumber, auditCleanArray, - auditOptions, + auditDateIso8601String, + auditEmptyToNull, + auditFunction, auditHttpUrl, + auditInteger, + auditNumber, + auditOptions, + auditRequire, + auditSwitch, + auditTrimString, + type Audit, } from "@auditors/core" import { allLegiArticleEtatsMutable, - allLegiArticleLienArticleOriginesMutable, allLegiArticleLienNaturesMutable, allLegiArticleLienSensMutable, allLegiArticleLienTypesMutable, @@ -94,33 +93,6 @@ function auditContexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { return audit.reduceRemaining(data, errors, remainingKeys) } -function auditEliAlias(audit: Audit, dataUnknown: unknown): [unknown, unknown] { - if (dataUnknown == null) { - return [dataUnknown, null] - } - if (typeof dataUnknown !== "object") { - return audit.unexpectedType(dataUnknown, "object") - } - - const data = { ...dataUnknown } - const errors: { [key: string]: unknown } = {} - const remainingKeys = new Set(Object.keys(data)) - - audit.attribute( - data, - "ID_ELI_ALIAS", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditHttpUrl, - auditRequire, - ) - - return audit.reduceRemaining(data, errors, remainingKeys) -} - export function auditLegiArticle( audit: Audit, dataUnknown: unknown, @@ -217,7 +189,7 @@ function auditLien(audit: Audit, dataUnknown: unknown): [unknown, unknown] { [auditTrimString, auditEmptyToNull], ), ) - for (const key of ["@cidtexte", "@id", "@nortexte"]) { + for (const key of ["@cidtexte", "@id", "@nortexte", "@num"]) { audit.attribute( data, key, @@ -228,18 +200,16 @@ function auditLien(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditEmptyToNull, ) } - for (const key of ["@datesignatexte"]) { - audit.attribute( - data, - key, - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditDateIso8601String, - ) - } + audit.attribute( + data, + "@datesignatexte", + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditDateIso8601String, + ) audit.attribute( data, "@naturetexte", @@ -255,15 +225,6 @@ function auditLien(audit: Audit, dataUnknown: unknown): [unknown, unknown] { // }), auditOptions(allLegiArticleLienNaturesMutable), ) - audit.attribute( - data, - "@num", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - ) audit.attribute( data, "@numtexte", @@ -369,7 +330,7 @@ function auditLienArt(audit: Audit, dataUnknown: unknown): [unknown, unknown] { remainingKeys, auditTrimString, auditEmptyToNull, - auditOptions(allLegiArticleLienArticleOriginesMutable), + auditOptions(allLegiArticleOriginesMutable), auditRequire, ) @@ -395,7 +356,7 @@ function auditLiens(audit: Audit, dataUnknown: unknown): [unknown, unknown] { errors, remainingKeys, auditFunction((lien) => (Array.isArray(lien) ? lien : [lien])), - auditCleanArray(auditLien), + auditCleanArray(auditLien, auditRequire), auditRequire, ) @@ -627,16 +588,23 @@ function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { const data = { ...dataUnknown } const errors: { [key: string]: unknown } = {} const remainingKeys = new Set(Object.keys(data)) - - audit.attribute( - data, + for (const key of [ "@autorite", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - ) + "@ministere", + "@nor", + "@num", + "@num_parution_jo", + ]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + ) + } audit.attribute( data, "@cid", @@ -659,15 +627,6 @@ function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditRequire, ) } - audit.attribute( - data, - "@ministere", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - ) audit.attribute( data, "@nature", @@ -683,17 +642,6 @@ function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { // }), auditOptions(allLegiArticleTexteNaturesMutable), ) - for (const key of ["@nor", "@num", "@num_parution_jo"]) { - audit.attribute( - data, - key, - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - ) - } audit.attribute( data, "TITRE_TXT", @@ -703,7 +651,7 @@ function auditTexte(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditFunction((titreTxt) => Array.isArray(titreTxt) ? titreTxt : [titreTxt], ), - auditCleanArray(auditTitreTxt), + auditCleanArray(auditTitreTxt, auditRequire), auditRequire, ) audit.attribute(data, "TM", true, errors, remainingKeys, auditTm) @@ -723,18 +671,20 @@ function auditTitreTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { const errors: { [key: string]: unknown } = {} const remainingKeys = new Set(Object.keys(data)) - audit.attribute( - data, - "#text", - true, - errors, - remainingKeys, - auditSwitch( - [auditNumber, auditInteger, auditFunction((num) => num.toString())], - [auditTrimString, auditEmptyToNull], - ), - auditRequire, - ) + for (const key of ["#text", "@id"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditSwitch( + [auditNumber, auditInteger, auditFunction((num) => num.toString())], + [auditTrimString, auditEmptyToNull], + ), + auditRequire, + ) + } for (const key of ["@debut", "@fin"]) { audit.attribute( data, @@ -746,16 +696,6 @@ function auditTitreTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditRequire, ) } - audit.attribute( - data, - "@id", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditRequire, - ) return audit.reduceRemaining(data, errors, remainingKeys) } @@ -772,26 +712,18 @@ function auditTitreTxt(audit: Audit, dataUnknown: unknown): [unknown, unknown] { const errors: { [key: string]: unknown } = {} const remainingKeys = new Set(Object.keys(data)) - audit.attribute( - data, - "#text", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditRequire, - ) - audit.attribute( - data, - "@c_titre_court", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditRequire, - ) + for (const key of ["#text", "@c_titre_court", "@id_txt"]) { + audit.attribute( + data, + key, + true, + errors, + remainingKeys, + auditTrimString, + auditEmptyToNull, + auditRequire, + ) + } for (const key of ["@debut", "@fin"]) { audit.attribute( data, @@ -803,16 +735,6 @@ function auditTitreTxt(audit: Audit, dataUnknown: unknown): [unknown, unknown] { auditRequire, ) } - audit.attribute( - data, - "@id_txt", - true, - errors, - remainingKeys, - auditTrimString, - auditEmptyToNull, - auditRequire, - ) return audit.reduceRemaining(data, errors, remainingKeys) } @@ -837,7 +759,7 @@ function auditTm(audit: Audit, dataUnknown: unknown): [unknown, unknown] { errors, remainingKeys, auditFunction((titreTm) => (Array.isArray(titreTm) ? titreTm : [titreTm])), - auditCleanArray(auditTitreTm), + auditCleanArray(auditTitreTm, auditRequire), auditRequire, ) audit.attribute(data, "TM", true, errors, remainingKeys, auditTm) @@ -904,7 +826,7 @@ function auditVersions(audit: Audit, dataUnknown: unknown): [unknown, unknown] { errors, remainingKeys, auditFunction((version) => (Array.isArray(version) ? version : [version])), - auditCleanArray(auditVersion), + auditCleanArray(auditVersion, auditRequire), auditRequire, ) diff --git a/src/lib/legal/index.ts b/src/lib/legal/index.ts index 4c9846d..c833c1e 100644 --- a/src/lib/legal/index.ts +++ b/src/lib/legal/index.ts @@ -2,6 +2,8 @@ import type { MenuItem } from "@tricoteuses/explorer-tools" import type { DossierLegislatif } from "./dole" +import type { Jo } from "./jorf" + export type { DossierLegislatif } from "./dole" export { allJoNatures, @@ -20,6 +22,15 @@ export { allJorfArticleTexteNaturesMutable, allJorfArticleTypes, allJorfArticleTypesMutable, + allJorfSectionTaLienArtEtats, + allJorfSectionTaLienArtEtatsMutable, + allJorfSectionTaLienArtOrigines, + allJorfSectionTaLienArtOriginesMutable, + allJorfSectionTaLienSectionTaEtats, + allJorfSectionTaLienSectionTaEtatsMutable, + allJorfSectionTaTexteNatures, + allJorfSectionTaTexteNaturesMutable, + type Jo, type JoNature, type JoOrigine, type JorfArticle, @@ -29,6 +40,9 @@ export { type JorfArticleOrigine, type JorfArticleTexteNature, type JorfArticleType, + type JorfSectionTa, + type JorfSectionTaLienArtEtat, + type JorfSectionTaTexteNature, } from "./jorf" export { allLegiArticleEtats, @@ -145,22 +159,6 @@ export interface IdWrapper { id: string } -export interface Jo { - META: { - META_SPEC: { - META_CONTENEUR: { - NUM: string - TITRE: string - DATE_PUBLI: string - } - } - META_COMMUN: MetaCommun - } - STRUCTURE_TXT: { - TM: Tm - } -} - export type LegalObject = | Article | DossierLegislatif diff --git a/src/lib/legal/jorf.ts b/src/lib/legal/jorf.ts index d4a13c6..afe53cb 100644 --- a/src/lib/legal/jorf.ts +++ b/src/lib/legal/jorf.ts @@ -1,3 +1,35 @@ +export interface Jo { + META: { + META_COMMUN: { + ID: string + ID_ELI?: string + NATURE: JoNature + ORIGINE: JoOrigine + URL: string + } + META_SPEC: { + META_CONTENEUR: { + DATE_PUBLI: string + NUM?: string + TITRE: string + } + } + } + STRUCTURE_TXT?: { + LIEN_TXT?: JoLienTxt[] + TM?: JoTm[] + } +} + +export interface JoLienTxt { + "@idtxt": string + "@titretxt": string +} + +export type JoNature = (typeof allJoNatures)[number] + +export type JoOrigine = (typeof allJoOrigines)[number] + export interface JorfArticle { BLOC_TEXTUEL?: { CONTENU: string // HTML @@ -30,13 +62,13 @@ export interface JorfArticle { ID: string ID_ELI?: string NATURE?: JorfArticleNature - URL: string ORIGINE: JorfArticleOrigine + URL: string } META_SPEC: { META_ARTICLE: { - DATE_FIN: string DATE_DEBUT: string + DATE_FIN: string /// Mots-clés MCS_ART?: { MC: string[] } NUM?: string @@ -59,10 +91,6 @@ export interface JorfArticle { } } -export type JoNature = (typeof allJoNatures)[number] - -export type JoOrigine = (typeof allJoOrigines)[number] - export type JorfArticleEtat = (typeof allJorfArticleEtats)[number] export type JorfArticleLienArticleOrigine = @@ -74,9 +102,7 @@ export type JorfArticleOrigine = (typeof allJorfArticleOrigines)[number] export type JorfArticleTexteNature = (typeof allJorfArticleTexteNatures)[number] -export type JorfArticleType = (typeof allJorfArticleTypes)[number] - -/// Table des matières (TM) +/// Table des matières (TM) d'un article de Journal officiel export interface JorfArticleTm { TITRE_TM: { "#text"?: string @@ -87,6 +113,85 @@ export interface JorfArticleTm { TM?: JorfArticleTm } +export type JorfArticleType = (typeof allJorfArticleTypes)[number] + +export interface JorfSectionTa { + COMMENTAIRE?: string + CONTEXTE: { + ID: string + TEXTE: { + "@autorite"?: string + "@cid": string + "@date_publi": string + "@date_signature": string + "@ministere"?: string + "@nature"?: JorfSectionTaTexteNature + "@nor"?: string + "@num"?: string + "@num_parution_jo"?: string + TITRE_TXT: Array<{ + "#text": string + "@c_titre_court"?: string + "@debut": string + "@fin": string + "@id_txt": string + }> + TM?: JorfSectionTaTm[] + } + } + TITRE_TA?: string + STRUCTURE_TA?: Array<{ + LIEN_ART?: Array<{ + "@debut": string + "@etat"?: JorfSectionTaLienArtEtat + "@fin": string + "@id": string + "@num"?: string + "@origine"?: JorfSectionTaLienArtOrigine + }> + LIEN_SECTION_TA?: Array<{ + "#text"?: string + "@cid": string + "@debut": string + // "@etat"?: JorfSectionTaLienSectionTaEtat + "@fin": string + "@id": string + "@niv": number + "@url": string + }> + }> +} + +export type JorfSectionTaLienArtEtat = + (typeof allJorfSectionTaLienArtEtats)[number] + +export type JorfSectionTaLienArtOrigine = + (typeof allJorfSectionTaLienArtOrigines)[number] + +export type JorfSectionTaLienSectionTaEtat = + (typeof allJorfSectionTaLienSectionTaEtats)[number] + +export type JorfSectionTaTexteNature = + (typeof allJorfSectionTaTexteNatures)[number] + +interface JorfSectionTaTm { + TITRE_TM: { + "#text"?: string + "@debut": string + "@fin": string + "@id": string + } + TM?: JorfSectionTaTm +} + +/// Table des matières (TM) d'un Journal officiel +export interface JoTm { + "@niv": number + LIEN_TXT?: JoLienTxt[] + TITRE_TM: string + TM?: JoTm[] +} + export const allJoNatures = ["JO"] as const export const allJoNaturesMutable = [...allJoNatures] @@ -118,77 +223,77 @@ export const allJorfArticleOrigines = ["JORF"] as const export const allJorfArticleOriginesMutable = [...allJorfArticleOrigines] export const allJorfArticleTexteNatures = [ - "DECRET", // 555543 - "LOI", // 64957 - "ARRETE", // 1228598 - "DECISION", // 244100 - "LISTE", // 24279 - "AVIS", // 101688 - "CODE", // 14737 - "RESULTATS", // 14954 - "MODIFICATION", // 724 - "RAPPORT", // 2491 - "REGLEMENT", // 1930 - "LOI_ORGANIQUE", // 1144 - "CIRCULAIRE", // 3933 - "LOI_PROGRAMME", // 10 - "CITATION", // 423 - "ORDONNANCE", // 33582 - "DELIBERATION", // 11012 - "INSTRUCTION", // 1207 - "AVENANT", // 533 - "DECLARATION", // 77 - "OBSERVATION", // 623 - "INFORMATION", // 143 - "RECOMMANDATION", // 204 - "SAISINE", // 1075 - "EXEQUATUR", // 173 - "TABLEAU", // 1063 - "REMISE", // 119 - "ACCORD", // 153 - "MEMOIRE", // 72 - "DECISION_CC", // 51 - "LOI_CONSTIT", // 76 - "LETTRE", // 10 - "ELECTIONDUPRESIDENTDELAREPUBLIQU", // 16 - "CONVENTION", // 972 - "ARRET", // 23 - "CONTRAT", // 32 - "COMPOSITION", // 19 - "ADDITIF", // 139 - "VOCABULAIRE", // 170 - "DATE", // 1 - "PROTOCOLE", // 25 - "PROPOSITION", // 11 - "DECRET_LOI", // 85 - "COMMUNIQUE", // 3 - "PROCLAMATION", // 17 - "CONSTITUTION", // 41 - "DIRECTIVE", // 11 - "DECISION_EURO", // 15 "ABROGATION", // 10 - "PREMIER", // 1 - "PUBLICATION", // 2 - "RECTIFICATIF", // 3 - "DEUXIEME", // 5 - "DELEGATION", // 1 - "ANNEXE", // 2 - "RELEVE", // 2 - "COMPLEMENT", // 2 - "ARRANGEMENT", // 1 - "TROISIEME", // 2 - "ELECTION", // 1 - "SUSPENSION", // 2 - "ATTESTATION", // 1 - "CANDIDAT", // 2 - "CHARTE", // 1 - "PROJET", // 6 - "INFORMATIONS_DIVERSES", // 524 - "INFORMATIONS_PARLEMENTAIRES", // 6335 - "INFORMATIONS_CESE", // 285 - "ANNONCES", // 755 "Accord multilatéral", // 3 "ACCORD_FONCTION_PUBLIQUE", // + "ACCORD", // 153 + "ADDITIF", // 139 + "ANNEXE", // 2 + "ANNONCES", // 755 + "ARRANGEMENT", // 1 + "ARRET", // 23 + "ARRETE", // 1228598 + "ATTESTATION", // 1 + "AVENANT", // 533 + "AVIS", // 101688 + "CANDIDAT", // 2 + "CHARTE", // 1 + "CIRCULAIRE", // 3933 + "CITATION", // 423 + "CODE", // 14737 + "COMMUNIQUE", // 3 + "COMPLEMENT", // 2 + "COMPOSITION", // 19 + "CONSTITUTION", // 41 + "CONTRAT", // 32 + "CONVENTION", // 972 + "DATE", // 1 + "DECISION_CC", // 51 + "DECISION_EURO", // 15 + "DECISION", // 244100 + "DECLARATION", // 77 + "DECRET_LOI", // 85 + "DECRET", // 555543 + "DELEGATION", // 1 + "DELIBERATION", // 11012 + "DEUXIEME", // 5 + "DIRECTIVE", // 11 + "ELECTION", // 1 + "ELECTIONDUPRESIDENTDELAREPUBLIQU", // 16 + "EXEQUATUR", // 173 + "INFORMATION", // 143 + "INFORMATIONS_CESE", // 285 + "INFORMATIONS_DIVERSES", // 524 + "INFORMATIONS_PARLEMENTAIRES", // 6335 + "INSTRUCTION", // 1207 + "LETTRE", // 10 + "LISTE", // 24279 + "LOI_CONSTIT", // 76 + "LOI_ORGANIQUE", // 1144 + "LOI_PROGRAMME", // 10 + "LOI", // 64957 + "MEMOIRE", // 72 + "MODIFICATION", // 724 + "OBSERVATION", // 623 + "ORDONNANCE", // 33582 + "PREMIER", // 1 + "PROCLAMATION", // 17 + "PROJET", // 6 + "PROPOSITION", // 11 + "PROTOCOLE", // 25 + "PUBLICATION", // 2 + "RAPPORT", // 2491 + "RECOMMANDATION", // 204 + "RECTIFICATIF", // 3 + "REGLEMENT", // 1930 + "RELEVE", // 2 + "REMISE", // 119 + "RESULTATS", // 14954 + "SAISINE", // 1075 + "SUSPENSION", // 2 + "TABLEAU", // 1063 + "TROISIEME", // 2 + "VOCABULAIRE", // 170 ] as const export const allJorfArticleTexteNaturesMutable = [...allJorfArticleTexteNatures] @@ -198,3 +303,53 @@ export const allJorfArticleTypes = [ "PARTIELLEMENT_MODIF", ] as const export const allJorfArticleTypesMutable = [...allJorfArticleTypes] + +export const allJorfSectionTaLienArtEtats = ["VIGUEUR"] as const +export const allJorfSectionTaLienArtEtatsMutable = [ + ...allJorfSectionTaLienArtEtats, +] + +export const allJorfSectionTaLienArtOrigines = ["JORF"] as const +export const allJorfSectionTaLienArtOriginesMutable = [ + ...allJorfSectionTaLienArtOrigines, +] + +export const allJorfSectionTaLienSectionTaEtats = [] as const +export const allJorfSectionTaLienSectionTaEtatsMutable = [ + ...allJorfSectionTaLienSectionTaEtats, +] + +export const allJorfSectionTaTexteNatures = [ + "Accord multilatéral", // 2 + "ACCORD_FONCTION_PUBLIQUE", // 2 + "ACCORD", // 3 + "ADDITIF", // 3 + "ARRETE", // 53716 + "AVENANT", // 89 + "AVIS", // 3212 + "CIRCULAIRE", // 168 + "CONVENTION", // 38 + "DECISION", // 16923 + "DECLARATION", // 4 + "DECRET", // 44405 + "DELIBERATION", // 2476 + "DIRECTIVE", // 2 + "INFORMATIONS_PARLEMENTAIRES", // 28 + "INSTRUCTION", // 39 + "LISTE", // 394 + "LOI_ORGANIQUE", // 71 + "LOI", // 5161 + "MODIFICATION", // 6 + "ORDONNANCE", // 9566 + "PROPOSITION", // 3 + "PROTOCOLE", // 1 + "RAPPORT", // 390 + "RECOMMANDATION", // 5 + "REGLEMENT", // 40 + "RESULTATS", // 324 + "SAISINE", // 3 + "TABLEAU", // 100 +] as const +export const allJorfSectionTaTexteNaturesMutable = [ + ...allJorfSectionTaTexteNatures, +] diff --git a/src/lib/legal/legi.ts b/src/lib/legal/legi.ts index 08cdca6..64c42a4 100644 --- a/src/lib/legal/legi.ts +++ b/src/lib/legal/legi.ts @@ -4,16 +4,18 @@ export interface LegiArticle { } CONTEXTE: { TEXTE: { + "@autorite"?: string "@cid": string "@date_publi": string "@date_signature": string + "@ministere"?: string "@nature"?: LegiArticleTexteNature "@nor"?: string "@num"?: string "@num_parution_jo"?: string TITRE_TXT: Array<{ "#text": string - "@c_titre_court"?: string + "@c_titre_court": string "@debut": string "@fin": string "@id_txt": string @@ -21,29 +23,40 @@ export interface LegiArticle { TM?: LegiArticleTm } } + LIENS?: { + LIEN: Array<{ + "#text"?: string + "@cidtexte"?: string + "@datesignatexte"?: string + "@id"?: string + "@naturetexte"?: LegiArticleLienNature + "@nortexte"?: string + "@num"?: string + "@sens": LegiArticleLienSens + "@typelien": LegiArticleLienType + }> + } META: { META_COMMUN: { ANCIEN_ID?: string - ELI_ALIAS?: { - ID_ELI_ALIAS: string - } ID: string - ID_ELI?: string - NATURE?: LegiArticleNature - URL: string + NATURE: LegiArticleNature ORIGINE: LegiArticleOrigine + URL: string } META_SPEC: { META_ARTICLE: { - DATE_FIN: string DATE_DEBUT: string - /// Mots-clés - MCS_ART?: { MC: string[] } + DATE_FIN: string + ETAT?: LegiArticleEtat NUM?: string TYPE?: LegiArticleType } } } + NOTA?: { + CONTENU: string // HTML + } VERSIONS: { VERSION: Array<{ "@etat"?: LegiArticleEtat @@ -53,7 +66,7 @@ export interface LegiArticle { "@fin": string "@id": string "@num"?: string - "@origine": LegiArticleLienArticleOrigine + "@origine": LegiArticleOrigine } }> } @@ -81,7 +94,7 @@ export type LegiArticleType = (typeof allLegiArticleTypes)[number] /// Table des matières (TM) export interface LegiArticleTm { TITRE_TM: { - "#text"?: string + "#text": string "@debut": string "@fin": string "@id": string diff --git a/src/scripts/import_jorf.ts b/src/scripts/import_jorf.ts index 7c7d86b..ff1542e 100644 --- a/src/scripts/import_jorf.ts +++ b/src/scripts/import_jorf.ts @@ -16,12 +16,15 @@ import { auditId, auditVersions } from "$lib/auditors/legal" import { auditJo, auditJorfArticle, - joStats, + auditJorfSectionTa, + // jorfArticleStats, + jorfSectionTaStats, + // joStats, } from "$lib/auditors/jorf" import type { Jo, JorfArticle, - SectionTa, + JorfSectionTa, Textelr, TexteVersion, Versions, @@ -483,10 +486,14 @@ async function importJorf( } // console.log( - // "JORF articles stats =", + // "JORF ARTICLE stats =", // JSON.stringify(jorfArticleStats, null, 2), // ) - console.log("JO stats =", JSON.stringify(joStats, null, 2)) + // console.log("JO stats =", JSON.stringify(joStats, null, 2)) + console.log( + "JORF SECTION_TA stats =", + JSON.stringify(jorfSectionTaStats, null, 2), + ) } sade("import_jorf ", true)