Add validation of articles

This commit is contained in:
Emmanuel 2023-02-11 15:15:23 +01:00
parent 04cdaac718
commit 126aebd7b1
14 changed files with 2335 additions and 111 deletions

View file

@ -473,9 +473,8 @@ function auditLigne(audit: Audit, dataUnknown: unknown): [unknown, unknown] {
remainingKeys,
auditSwitch(
[auditNumber, auditInteger, auditFunction((numero) => numero.toString())],
auditTrimString,
[auditTrimString, auditEmptyToNull],
),
auditEmptyToNull,
)
return audit.reduceRemaining(data, errors, remainingKeys)

View file

@ -0,0 +1,773 @@
import {
type Audit,
auditRequire,
auditDateIso8601String,
auditTrimString,
auditInteger,
auditFunction,
auditEmptyToNull,
auditNullish,
auditSwitch,
auditNumber,
auditCleanArray,
auditOptions,
auditHttpUrl,
} from "@auditors/core"
import {
allJorfArticleEtatsMutable,
allJorfArticleLienArticleOriginesMutable,
allJorfArticleNaturesMutable,
allJorfArticleOriginesMutable,
allJorfArticleTexteNaturesMutable,
allJorfArticleTypesMutable,
} from "$lib/legal"
function auditBlocTextuel(
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,
"CONTENU",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
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)
}
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 auditJorfArticle(
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,
"BLOC_TEXTUEL",
true,
errors,
remainingKeys,
auditBlocTextuel,
auditEmptyToNull,
)
audit.attribute(
data,
"CONTEXTE",
true,
errors,
remainingKeys,
auditContexte,
auditRequire,
)
audit.attribute(
data,
"LIENS",
true,
errors,
remainingKeys,
auditSwitch(auditTrimString, auditLiens),
auditEmptyToNull,
auditNullish,
)
audit.attribute(
data,
"META",
true,
errors,
remainingKeys,
auditMeta,
auditRequire,
)
audit.attribute(
data,
"SM",
true,
errors,
remainingKeys,
auditSm,
auditEmptyToNull,
auditNullish,
)
audit.attribute(
data,
"VERSIONS",
true,
errors,
remainingKeys,
auditVersions,
auditRequire,
)
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,
auditOptions(allJorfArticleEtatsMutable),
)
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,
auditOptions(allJorfArticleLienArticleOriginesMutable),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditLiens(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))
return audit.reduceRemaining(data, errors, remainingKeys)
}
/// Mots-clés articles
function auditMcsArt(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,
"MC",
true,
errors,
remainingKeys,
auditFunction((lien) => (Array.isArray(lien) ? lien : [lien])),
auditCleanArray(
auditSwitch(
[auditNumber, auditInteger, auditFunction((num) => num.toString())],
[auditTrimString, auditEmptyToNull],
),
),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMeta(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,
"META_COMMUN",
true,
errors,
remainingKeys,
auditMetaCommun,
auditRequire,
)
audit.attribute(
data,
"META_SPEC",
true,
errors,
remainingKeys,
auditMetaSpec,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaArticle(
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 ["DATE_DEBUT", "DATE_FIN"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditDateIso8601String,
auditRequire,
)
}
audit.attribute(
data,
"MCS_ART",
true,
errors,
remainingKeys,
auditSwitch([auditTrimString, auditEmptyToNull, auditNullish], auditMcsArt),
)
audit.attribute(
data,
"NUM",
true,
errors,
remainingKeys,
auditSwitch(
[auditNumber, auditFunction((num) => num.toString())],
[auditTrimString, auditEmptyToNull],
),
)
audit.attribute(
data,
"TYPE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allJorfArticleTypesMutable),
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaCommun(
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,
"ANCIEN_ID",
true,
errors,
remainingKeys,
auditSwitch(
[auditNumber, auditInteger, auditFunction((id) => id.toString())],
[auditTrimString, auditEmptyToNull],
),
)
audit.attribute(data, "ELI_ALIAS", true, errors, remainingKeys, auditEliAlias)
for (const key of ["ID", "URL"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditRequire,
)
}
audit.attribute(
data,
"ID_ELI",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditHttpUrl,
)
audit.attribute(
data,
"NATURE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allJorfArticleNaturesMutable),
)
audit.attribute(
data,
"ORIGINE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allJorfArticleOriginesMutable),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaSpec(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,
"META_ARTICLE",
true,
errors,
remainingKeys,
auditMetaArticle,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditSm(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,
"CONTENU",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditNullish,
)
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))
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,
auditOptions(allJorfArticleTexteNaturesMutable),
)
for (const key of ["@nor", "@num", "@num_parution_jo"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
}
audit.attribute(
data,
"TITRE_TXT",
true,
errors,
remainingKeys,
auditFunction((titreTxt) =>
Array.isArray(titreTxt) ? titreTxt : [titreTxt],
),
auditCleanArray(auditTitreTxt),
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))
audit.attribute(
data,
"#text",
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,
)
}
audit.attribute(
data,
"@id_txt",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
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)
}
function auditVersion(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,
"@etat",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allJorfArticleEtatsMutable),
)
audit.attribute(
data,
"LIEN_ART",
true,
errors,
remainingKeys,
auditLienArt,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditVersions(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,
"VERSION",
true,
errors,
remainingKeys,
auditFunction((version) => (Array.isArray(version) ? version : [version])),
auditCleanArray(auditVersion),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}

View file

@ -0,0 +1 @@
export { auditJorfArticle } from "./articles"

View file

@ -0,0 +1,912 @@
import {
type Audit,
auditRequire,
auditDateIso8601String,
auditTrimString,
auditInteger,
auditFunction,
auditEmptyToNull,
auditSwitch,
auditNumber,
auditCleanArray,
auditOptions,
auditHttpUrl,
} from "@auditors/core"
import {
allLegiArticleEtatsMutable,
allLegiArticleLienArticleOriginesMutable,
allLegiArticleLienNaturesMutable,
allLegiArticleLienSensMutable,
allLegiArticleLienTypesMutable,
allLegiArticleNaturesMutable,
allLegiArticleOriginesMutable,
allLegiArticleTexteNaturesMutable,
allLegiArticleTypesMutable,
} from "$lib/legal"
export const legiArticleStats: {
countByEtat: { [etat: string]: number }
countByLienArtEtat: { [etat: string]: number }
countByLienNature: { [nature: string]: number }
countByLienType: { [type: string]: number }
countByTexteNature: { [nature: string]: number }
countByVersionEtat: { [etat: string]: number }
} = {
countByEtat: {},
countByLienArtEtat: {},
countByLienNature: {},
countByLienType: {},
countByTexteNature: {},
countByVersionEtat: {},
}
function auditBlocTextuel(
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,
"CONTENU",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
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)
}
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,
): [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,
"BLOC_TEXTUEL",
true,
errors,
remainingKeys,
auditBlocTextuel,
auditEmptyToNull,
)
audit.attribute(
data,
"CONTEXTE",
true,
errors,
remainingKeys,
auditContexte,
auditRequire,
)
audit.attribute(
data,
"LIENS",
true,
errors,
remainingKeys,
auditSwitch(auditTrimString, auditLiens),
auditEmptyToNull,
)
audit.attribute(
data,
"META",
true,
errors,
remainingKeys,
auditMeta,
auditRequire,
)
audit.attribute(
data,
"NOTA",
true,
errors,
remainingKeys,
auditNota,
auditEmptyToNull,
)
audit.attribute(
data,
"VERSIONS",
true,
errors,
remainingKeys,
auditVersions,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditLien(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,
auditSwitch(
[auditNumber, auditInteger, auditFunction((num) => num.toString())],
[auditTrimString, auditEmptyToNull],
),
)
for (const key of ["@cidtexte", "@id", "@nortexte"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
}
for (const key of ["@datesignatexte"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditDateIso8601String,
)
}
audit.attribute(
data,
"@naturetexte",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
// auditFunction((nature) => {
// legiArticleStats.countByLienNature[nature] =
// (legiArticleStats.countByLienNature[nature] ?? 0) + 1
// return nature
// }),
auditOptions(allLegiArticleLienNaturesMutable),
)
audit.attribute(
data,
"@num",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
audit.attribute(
data,
"@numtexte",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
audit.attribute(
data,
"@sens",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allLegiArticleLienSensMutable),
auditRequire,
)
audit.attribute(
data,
"@typelien",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
// auditFunction((type) => {
// legiArticleStats.countByLienType[type] =
// (legiArticleStats.countByLienType[type] ?? 0) + 1
// return type
// }),
auditOptions(allLegiArticleLienTypesMutable),
auditRequire,
)
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) => {
// legiArticleStats.countByLienArtEtat[etat] =
// (legiArticleStats.countByLienArtEtat[etat] ?? 0) + 1
// return etat
// }),
auditOptions(allLegiArticleEtatsMutable),
)
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,
auditOptions(allLegiArticleLienArticleOriginesMutable),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditLiens(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",
true,
errors,
remainingKeys,
auditFunction((lien) => (Array.isArray(lien) ? lien : [lien])),
auditCleanArray(auditLien),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMeta(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,
"META_COMMUN",
true,
errors,
remainingKeys,
auditMetaCommun,
auditRequire,
)
audit.attribute(
data,
"META_SPEC",
true,
errors,
remainingKeys,
auditMetaSpec,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaArticle(
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 ["DATE_DEBUT", "DATE_FIN"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditDateIso8601String,
auditRequire,
)
}
audit.attribute(
data,
"ETAT",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
// auditFunction((etat) => {
// legiArticleStats.countByEtat[etat] =
// (legiArticleStats.countByEtat[etat] ?? 0) + 1
// return etat
// }),
auditOptions(allLegiArticleEtatsMutable),
)
audit.attribute(
data,
"NUM",
true,
errors,
remainingKeys,
auditSwitch(
[auditNumber, auditFunction((num) => num.toString())],
[auditTrimString, auditEmptyToNull],
),
)
audit.attribute(
data,
"TYPE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allLegiArticleTypesMutable),
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaCommun(
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,
"ANCIEN_ID",
true,
errors,
remainingKeys,
auditSwitch(
[auditNumber, auditInteger, auditFunction((id) => id.toString())],
[auditTrimString, auditEmptyToNull],
),
)
for (const key of ["ID", "URL"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditRequire,
)
}
audit.attribute(
data,
"NATURE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allLegiArticleNaturesMutable),
auditRequire,
)
audit.attribute(
data,
"ORIGINE",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
auditOptions(allLegiArticleOriginesMutable),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditMetaSpec(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,
"META_ARTICLE",
true,
errors,
remainingKeys,
auditMetaArticle,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditNota(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,
"CONTENU",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
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))
audit.attribute(
data,
"@autorite",
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,
"@ministere",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
)
audit.attribute(
data,
"@nature",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
// auditFunction((nature) => {
// legiArticleStats.countByTexteNature[nature] =
// (legiArticleStats.countByTexteNature[nature] ?? 0) + 1
// return nature
// }),
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",
true,
errors,
remainingKeys,
auditFunction((titreTxt) =>
Array.isArray(titreTxt) ? titreTxt : [titreTxt],
),
auditCleanArray(auditTitreTxt),
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,
auditSwitch(
[auditNumber, auditInteger, auditFunction((num) => num.toString())],
[auditTrimString, auditEmptyToNull],
),
auditRequire,
)
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))
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 ["@debut", "@fin"]) {
audit.attribute(
data,
key,
true,
errors,
remainingKeys,
auditDateIso8601String,
auditRequire,
)
}
audit.attribute(
data,
"@id_txt",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
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,
auditFunction((titreTm) => (Array.isArray(titreTm) ? titreTm : [titreTm])),
auditCleanArray(auditTitreTm),
auditRequire,
)
audit.attribute(data, "TM", true, errors, remainingKeys, auditTm)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditVersion(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,
"@etat",
true,
errors,
remainingKeys,
auditTrimString,
auditEmptyToNull,
// auditFunction((etat) => {
// legiArticleStats.countByVersionEtat[etat] =
// (legiArticleStats.countByVersionEtat[etat] ?? 0) + 1
// return etat
// }),
auditOptions(allLegiArticleEtatsMutable),
)
audit.attribute(
data,
"LIEN_ART",
true,
errors,
remainingKeys,
auditLienArt,
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}
function auditVersions(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,
"VERSION",
true,
errors,
remainingKeys,
auditFunction((version) => (Array.isArray(version) ? version : [version])),
auditCleanArray(auditVersion),
auditRequire,
)
return audit.reduceRemaining(data, errors, remainingKeys)
}

View file

@ -0,0 +1 @@
export { auditLegiArticle, legiArticleStats } from "./articles"

View file

@ -7,24 +7,71 @@ export {
type GetRechercheResult,
type GetTexteResult,
type ListTextesResult,
} from "$lib/aggregates"
} from "./aggregates"
export { default as ArticleView } from "$lib/components/ArticleView.svelte"
export { default as ArticleView } from "./components/ArticleView.svelte"
export { default as LienView } from "$lib/components/LienView.svelte"
export { default as LienView } from "./components/LienView.svelte"
export { default as SectionTaView } from "$lib/components/SectionTaView.svelte"
export { default as SectionTaView } from "./components/SectionTaView.svelte"
export { default as TextelrView } from "$lib/components/TextelrView.svelte"
export { default as TextelrView } from "./components/TextelrView.svelte"
export { default as TexteVersionView } from "$lib/components/TexteVersionView.svelte"
export { default as TexteVersionView } from "./components/TexteVersionView.svelte"
export {
allJorfArticleEtats,
allJorfArticleEtatsMutable,
allJorfArticleLienArticleOrigines,
allJorfArticleLienArticleOriginesMutable,
allJorfArticleNatures,
allJorfArticleNaturesMutable,
allJorfArticleOrigines,
allJorfArticleOriginesMutable,
allJorfArticleTexteNatures,
allJorfArticleTexteNaturesMutable,
allJorfArticleTypes,
allJorfArticleTypesMutable,
allLegiArticleEtats,
allLegiArticleEtatsMutable,
allLegiArticleLienArticleOrigines,
allLegiArticleLienArticleOriginesMutable,
allLegiArticleLienNatures,
allLegiArticleLienNaturesMutable,
allLegiArticleLienSens,
allLegiArticleLienSensMutable,
allLegiArticleNatures,
allLegiArticleNaturesMutable,
allLegiArticleOrigines,
allLegiArticleOriginesMutable,
allLegiArticleTexteNatures,
allLegiArticleTexteNaturesMutable,
allLegiArticleTypes,
allLegiArticleTypesMutable,
type DossierLegislatif,
type JorfArticle,
type JorfArticleEtat,
type JorfArticleLienArticleOrigine,
type JorfArticleNature,
type JorfArticleOrigine,
type JorfArticleTexteNature,
type JorfArticleType,
type LegiArticle,
type LegiArticleEtat,
type LegiArticleLienArticleOrigine,
type LegiArticleLienNature,
type LegiArticleLienSens,
type LegiArticleNature,
type LegiArticleOrigine,
type LegiArticleTexteNature,
type LegiArticleType,
} from "./legal"
export {
type Article,
type ArticleVersion,
bestItemForDate,
type Contexte,
type DossierLegislatif,
type Etat,
type Idcc,
type Jo,
@ -50,4 +97,4 @@ export {
type Tm,
type TmLienTxt,
type Versions,
} from "$lib/legal"
} from "./legal"

82
src/lib/legal/dole.ts Normal file
View file

@ -0,0 +1,82 @@
export interface ArborescenceLien {
"#text"?: string
"@id": string
"@libelle"?: string
"@lien"?: string
}
export interface ArborescenceNiveau {
"@id": string
"@libelle": string
LIEN?: ArborescenceLien[]
NIVEAU?: ArborescenceNiveau
}
export interface DossierLegislatif {
CONTENU: {
ARBORESCENCE: {
LIEN?: ArborescenceLien[]
NIVEAU?: ArborescenceNiveau
}
CONTENU_DOSSIER_1?: string
CONTENU_DOSSIER_2?: string
CONTENU_DOSSIER_3?: string
CONTENU_DOSSIER_4?: string
CONTENU_DOSSIER_5?: string
ECHEANCIER?: {
"@derniere_maj"?: string
LIGNE: Ligne[]
}
EXPOSE_MOTIF?: string
LIBELLE_TEXTE_1?: string
LIBELLE_TEXTE_2?: string
LIBELLE_TEXTE_3?: string
LIBELLE_TEXTE_4?: string
LIBELLE_TEXTE_5?: string
}
META: {
META_COMMUN: {
// MetaCommun
ANCIEN_ID?: string
ID: string
URL: string
// NATURE?: Nature // Never used
ORIGINE: "JORF" // Origine
}
META_DOSSIER_LEGISLATIF: {
DATE_CREATION: string
DATE_DERNIERE_MODIFICATION: string
ID_TEXTE_1?: string
ID_TEXTE_2?: string
ID_TEXTE_3?: string
ID_TEXTE_4?: string
ID_TEXTE_5?: string
LEGISLATURE: {
DATE_DEBUT: string
DATE_FIN: string
LIBELLE: string
NUMERO: number
}
TITRE: string
TYPE?:
| "LOI_PUBLIEE"
| "PROJET_LOI"
| "PROPOSITION_LOI"
| "ORDONNANCE_PUBLIEE"
}
}
}
export interface Ligne {
ARTICLE?: string
BASE_LEGALE?: string
CID_LOI_CIBLE?: string // Always a JORFTEXT ID
DATE_PREVUE?: string
DECRET?: string
LIEN_ARTICLE?: Array<{
"@id": string // Always a JORFARTI ID
"#text": string
}>
NUMERO_ORDRE?: string
OBJET?: string
}

View file

@ -1,18 +1,59 @@
import type { MenuItem } from "@tricoteuses/explorer-tools"
export interface ArborescenceLien {
"#text"?: string
"@id": string
"@libelle"?: string
"@lien"?: string
}
import type { DossierLegislatif } from "./dole"
export interface ArborescenceNiveau {
"@id": string
"@libelle": string
LIEN?: ArborescenceLien[]
NIVEAU?: ArborescenceNiveau
}
export type { DossierLegislatif } from "./dole"
export {
allJorfArticleEtats,
allJorfArticleEtatsMutable,
allJorfArticleLienArticleOrigines,
allJorfArticleLienArticleOriginesMutable,
allJorfArticleNatures,
allJorfArticleNaturesMutable,
allJorfArticleOrigines,
allJorfArticleOriginesMutable,
allJorfArticleTexteNatures,
allJorfArticleTexteNaturesMutable,
allJorfArticleTypes,
allJorfArticleTypesMutable,
type JorfArticle,
type JorfArticleEtat,
type JorfArticleLienArticleOrigine,
type JorfArticleNature,
type JorfArticleOrigine,
type JorfArticleTexteNature,
type JorfArticleType,
} from "./jorf"
export {
allLegiArticleEtats,
allLegiArticleEtatsMutable,
allLegiArticleLienArticleOrigines,
allLegiArticleLienArticleOriginesMutable,
allLegiArticleLienNatures,
allLegiArticleLienNaturesMutable,
allLegiArticleLienSens,
allLegiArticleLienSensMutable,
allLegiArticleLienTypes,
allLegiArticleLienTypesMutable,
allLegiArticleNatures,
allLegiArticleNaturesMutable,
allLegiArticleOrigines,
allLegiArticleOriginesMutable,
allLegiArticleTexteNatures,
allLegiArticleTexteNaturesMutable,
allLegiArticleTypes,
allLegiArticleTypesMutable,
type LegiArticle,
type LegiArticleEtat,
type LegiArticleLienArticleOrigine,
type LegiArticleLienNature,
type LegiArticleLienSens,
type LegiArticleLienType,
type LegiArticleNature,
type LegiArticleOrigine,
type LegiArticleTexteNature,
type LegiArticleType,
} from "./legi"
export interface Article {
META: {
@ -62,61 +103,6 @@ export interface Contexte {
}
}
export interface DossierLegislatif {
META: {
META_COMMUN: {
// MetaCommun
ANCIEN_ID?: string
ID: string
URL: string
// NATURE?: Nature // Never used
ORIGINE: "JORF" // Origine
}
META_DOSSIER_LEGISLATIF: {
DATE_CREATION: string
DATE_DERNIERE_MODIFICATION: string
ID_TEXTE_1?: string
ID_TEXTE_2?: string
ID_TEXTE_3?: string
ID_TEXTE_4?: string
ID_TEXTE_5?: string
LEGISLATURE: {
DATE_DEBUT: string
DATE_FIN: string
LIBELLE: string
NUMERO: number
}
TITRE: string
TYPE?:
| "LOI_PUBLIEE"
| "PROJET_LOI"
| "PROPOSITION_LOI"
| "ORDONNANCE_PUBLIEE"
}
}
CONTENU: {
ARBORESCENCE: {
LIEN?: ArborescenceLien[]
NIVEAU?: ArborescenceNiveau
}
CONTENU_DOSSIER_1?: string
CONTENU_DOSSIER_2?: string
CONTENU_DOSSIER_3?: string
CONTENU_DOSSIER_4?: string
CONTENU_DOSSIER_5?: string
ECHEANCIER?: {
"@derniere_maj"?: string
LIGNE: Ligne[]
}
EXPOSE_MOTIF?: string
LIBELLE_TEXTE_1?: string
LIBELLE_TEXTE_2?: string
LIBELLE_TEXTE_3?: string
LIBELLE_TEXTE_4?: string
LIBELLE_TEXTE_5?: string
}
}
export type Etat =
| ""
| "ABROGE_DIFF"
@ -260,20 +246,6 @@ export interface LienSectionTa {
"#text": string
}
export interface Ligne {
ARTICLE?: string
BASE_LEGALE?: string
CID_LOI_CIBLE?: string // Always a JORFTEXT ID
DATE_PREVUE?: string
DECRET?: string
LIEN_ARTICLE?: Array<{
"@id": string // Always a JORFARTI ID
"#text": string
}>
NUMERO_ORDRE?: string
OBJET?: string
}
export interface MetaCommun {
ID: string
URL: string
@ -463,18 +435,18 @@ export interface TexteVersion {
}
export interface TitreTm {
"@id": string
"@fin": string
"#text": string
"@debut": string
"@fin": string
"@id": string
}
export interface TitreTxt {
"@fin": string
"@debut": string
"@id_txt": string
"@c_titre_court": string
"#text": string
"@c_titre_court": string
"@debut": string
"@fin": string
"@id_txt": string
}
/// Table des matières (TM)

190
src/lib/legal/jorf.ts Normal file
View file

@ -0,0 +1,190 @@
export interface JorfArticle {
BLOC_TEXTUEL?: {
CONTENU: string // HTML
}
CONTEXTE: {
TEXTE: {
"@cid": string
"@date_publi": string
"@date_signature": string
"@nature"?: JorfArticleTexteNature
"@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?: JorfArticleTm
}
}
META: {
META_COMMUN: {
ANCIEN_ID?: string
ELI_ALIAS?: {
ID_ELI_ALIAS: string
}
ID: string
ID_ELI?: string
NATURE?: JorfArticleNature
URL: string
ORIGINE: JorfArticleOrigine
}
META_SPEC: {
META_ARTICLE: {
DATE_FIN: string
DATE_DEBUT: string
/// Mots-clés
MCS_ART?: { MC: string[] }
NUM?: string
TYPE?: JorfArticleType
}
}
}
VERSIONS: {
VERSION: Array<{
"@etat"?: JorfArticleEtat
LIEN_ART: {
"@debut": string
"@etat"?: JorfArticleEtat
"@fin": string
"@id": string
"@num"?: string
"@origine": JorfArticleLienArticleOrigine
}
}>
}
}
export type JorfArticleEtat = (typeof allJorfArticleEtats)[number]
export type JorfArticleLienArticleOrigine =
(typeof allJorfArticleLienArticleOrigines)[number]
export type JorfArticleNature = (typeof allJorfArticleNatures)[number]
export type JorfArticleOrigine = (typeof allJorfArticleOrigines)[number]
export type JorfArticleTexteNature = (typeof allJorfArticleTexteNatures)[number]
export type JorfArticleType = (typeof allJorfArticleTypes)[number]
/// Table des matières (TM)
export interface JorfArticleTm {
TITRE_TM: {
"#text"?: string
"@debut": string
"@fin": string
"@id": string
}
TM?: JorfArticleTm
}
export const allJorfArticleEtats = [
"ABROGE",
"ABROGE_DIFF",
"ANNULE",
"MODIFIE",
"MODIFIE_MORT_NE",
"PERIME",
"TRANSFERE",
"VIGUEUR",
"VIGUEUR_DIFF",
] as const
export const allJorfArticleEtatsMutable = [...allJorfArticleEtats]
export const allJorfArticleLienArticleOrigines = ["JORF", "LEGI"] as const
export const allJorfArticleLienArticleOriginesMutable = [
...allJorfArticleLienArticleOrigines,
]
export const allJorfArticleNatures = ["Article"] as const
export const allJorfArticleNaturesMutable = [...allJorfArticleNatures]
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", //
] as const
export const allJorfArticleTexteNaturesMutable = [...allJorfArticleTexteNatures]
export const allJorfArticleTypes = [
"AUTONOME",
"ENTIEREMENT_MODIF",
"PARTIELLEMENT_MODIF",
] as const
export const allJorfArticleTypesMutable = [...allJorfArticleTypes]

215
src/lib/legal/legi.ts Normal file
View file

@ -0,0 +1,215 @@
export interface LegiArticle {
BLOC_TEXTUEL?: {
CONTENU: string // HTML
}
CONTEXTE: {
TEXTE: {
"@cid": string
"@date_publi": string
"@date_signature": string
"@nature"?: LegiArticleTexteNature
"@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?: LegiArticleTm
}
}
META: {
META_COMMUN: {
ANCIEN_ID?: string
ELI_ALIAS?: {
ID_ELI_ALIAS: string
}
ID: string
ID_ELI?: string
NATURE?: LegiArticleNature
URL: string
ORIGINE: LegiArticleOrigine
}
META_SPEC: {
META_ARTICLE: {
DATE_FIN: string
DATE_DEBUT: string
/// Mots-clés
MCS_ART?: { MC: string[] }
NUM?: string
TYPE?: LegiArticleType
}
}
}
VERSIONS: {
VERSION: Array<{
"@etat"?: LegiArticleEtat
LIEN_ART: {
"@debut": string
"@etat"?: LegiArticleEtat
"@fin": string
"@id": string
"@num"?: string
"@origine": LegiArticleLienArticleOrigine
}
}>
}
}
export type LegiArticleEtat = (typeof allLegiArticleEtats)[number]
export type LegiArticleLienArticleOrigine =
(typeof allLegiArticleLienArticleOrigines)[number]
export type LegiArticleLienNature = (typeof allLegiArticleLienNatures)[number]
export type LegiArticleLienSens = (typeof allLegiArticleLienSens)[number]
export type LegiArticleLienType = (typeof allLegiArticleLienTypes)[number]
export type LegiArticleNature = (typeof allLegiArticleNatures)[number]
export type LegiArticleOrigine = (typeof allLegiArticleOrigines)[number]
export type LegiArticleTexteNature = (typeof allLegiArticleTexteNatures)[number]
export type LegiArticleType = (typeof allLegiArticleTypes)[number]
/// Table des matières (TM)
export interface LegiArticleTm {
TITRE_TM: {
"#text"?: string
"@debut": string
"@fin": string
"@id": string
}
TM?: LegiArticleTm
}
export const allLegiArticleEtats = [
"ABROGE_DIFF", // 16233
"ABROGE", // 341353
"ANNULE", // 1955
"DISJOINT", // 87
"MODIFIE_MORT_NE", // 6929
"MODIFIE", // 429664
"PERIME", // 19628
"TRANSFERE", // 14757
"VIGUEUR_DIFF", // 14629
"VIGUEUR", // 619477
] as const
export const allLegiArticleEtatsMutable = [...allLegiArticleEtats]
export const allLegiArticleLienArticleOrigines = ["JORF", "LEGI"] as const
export const allLegiArticleLienArticleOriginesMutable = [
...allLegiArticleLienArticleOrigines,
]
export const allLegiArticleLienNatures = [
"Accord de branche", // 10
"ACCORD_FONCTION_PUBLIQUE", // 68
"Accord", // 9
"ARRETE", // 878512
"Avenant", // 24
"AVENANT", // 7
"AVIS", // 139
"CIRCULAIRE", // 73
"CODE", // 3276729
"CONSTITUTION", // 1086
"Convention collective nationale", // 7
"Convention collective", // 1
"CONVENTION", // 3
"DECISION_EURO", // 1
"DECISION", // 1735
"DECRET_LOI", // 1184
"DECRET", // 2037090
"DELIBERATION", // 4172
"DIRECTIVE_EURO", // 180
"DIRECTIVE", // 64
"INSTRUCTION", // 4
"LOI_CONSTIT", // 111
"LOI_ORGANIQUE", // 5681
"LOI_PROGRAMME", // 335
"LOI", // 645965
"ORDONNANCE", // 225464
"RAPPORT", // 15802
"RECOMMANDATION", // 6
"REGLEMENTEUROPEEN", // 3
] as const
export const allLegiArticleLienNaturesMutable = [...allLegiArticleLienNatures]
export const allLegiArticleLienSens = ["cible", "source"] as const
export const allLegiArticleLienSensMutable = [...allLegiArticleLienSens]
export const allLegiArticleLienTypes = [
"ABROGATION", // 237556
"ABROGE", // 480524
"ANNULATION", // 1801
"ANNULE", // 13
"APPLICATION", // 398
"CITATION", // 4028139
"CODIFICATION", // 380434
"CODIFIE", // 29
"CONCORDANCE", // 315976
"CONCORDE", // 192980
"CREATION", // 174907
"CREE", // 265183
"DEPLACE", // 12605
"DEPLACEMENT", // 307
"DISJOINT", // 46
"DISJONCTION", // 77
"ETEND", // 43
"HISTO", // 14499
"MODIFICATION", // 390927
"MODIFIE", // 570147
"PEREMPTION", // 7001
"PERIME", // 1024
"PILOTE_SUIVEUR", // 4734
"RATIFICATION", // 259
"RATIFIE", // 56
"RECTIFICATION", // 1439
"SPEC_APPLI", // 87345
"TRANSFERE", // 16828
"TRANSFERT", // 10641
"TXT_ASSOCIE", // 47348
"TXT_SOURCE", // 263557
] as const
export const allLegiArticleLienTypesMutable = [...allLegiArticleLienTypes]
export const allLegiArticleNatures = ["Article"] as const
export const allLegiArticleNaturesMutable = [...allLegiArticleNatures]
export const allLegiArticleOrigines = ["LEGI"] as const
export const allLegiArticleOriginesMutable = [...allLegiArticleOrigines]
export const allLegiArticleTexteNatures = [
"ACCORD_FONCTION_PUBLIQUE", // 9,
"ARRETE", // 566126,
"AVIS", // 12,
"CIRCULAIRE", // 8,
"CODE", // 475255,
"CONSTITUTION", // 255,
"CONVENTION", // 1,
"DECISION", // 44,
"DECRET_LOI", // 905,
"DECRET", // 513465,
"DELIBERATION", // 1467,
"DIRECTIVE", // 57,
"LOI_CONSTIT", // 103,
"LOI_ORGANIQUE", // 1468,
"LOI_PROGRAMME", // 65,
"LOI", // 94775,
"ORDONNANCE", // 26800,
"RAPPORT", // 22,
] as const
export const allLegiArticleTexteNaturesMutable = [...allLegiArticleTexteNatures]
export const allLegiArticleTypes = [
"AUTONOME",
"ENTIEREMENT_MODIF",
"PARTIELLEMENT_MODIF",
] as const
export const allLegiArticleTypesMutable = [...allLegiArticleTypes]

View file

@ -7,7 +7,7 @@ import path from "path"
import type { JSONValue } from "postgres"
import sade from "sade"
import { auditDossierLegislatif } from "$lib/auditors/dossiers_legislatifs"
import { auditDossierLegislatif } from "$lib/auditors/dole"
import type { DossierLegislatif, XmlHeader } from "$lib/legal"
import { db } from "$lib/server/database"
import { walkDir } from "$lib/server/file_systems"

View file

@ -8,9 +8,10 @@ import type { JSONValue } from "postgres"
import sade from "sade"
import { auditId, auditVersions } from "$lib/auditors/legal"
import { auditJorfArticle } from "$lib/auditors/jorf"
import type {
Article,
Jo,
JorfArticle,
SectionTa,
Textelr,
TexteVersion,
@ -107,7 +108,7 @@ async function importJorf(
).map(({ eli }) => eli),
)
const dataDir = path.join(dilaDir, "dole")
const dataDir = path.join(dilaDir, "jorf")
assert(await fs.pathExists(dataDir))
iterXmlFiles: for (const relativeSplitPath of walkDir(dataDir)) {
const relativePath = path.join(...relativeSplitPath)
@ -134,7 +135,7 @@ async function importJorf(
for (const [key, element] of Object.entries(xmlData) as [
string,
(
| Article
| JorfArticle
| Jo
| SectionTa
| Textelr
@ -151,7 +152,19 @@ async function importJorf(
break
}
case "ARTICLE": {
const article = element as Article
const [article, error] = auditChain(auditJorfArticle, auditRequire)(
strictAudit,
element,
) as [JorfArticle, unknown]
assert.strictEqual(
error,
null,
`Unexpected format for ARTICLE:\n${JSON.stringify(
article,
null,
2,
)}\nError:\n${JSON.stringify(error, null, 2)}`,
)
await db`
INSERT INTO article (
id,
@ -184,7 +197,6 @@ async function importJorf(
2,
)}\nError:\n${JSON.stringify(idError, null, 2)}`,
)
assert
await db`
INSERT INTO id (
eli,
@ -249,7 +261,7 @@ async function importJorf(
) VALUES (
${texteVersion.META.META_COMMUN.ID},
${db.json(texteVersion as unknown as JSONValue)},
${texteVersion.META.META_COMMUN.NATURE}
${texteVersion.META.META_COMMUN.NATURE},
setweight(to_tsvector('french', ${textAFragments.join(
" ",
)}), 'A')

View file

@ -97,7 +97,7 @@ async function importKali(
).map(({ id }) => id),
)
const dataDir = path.join(dilaDir, "dole")
const dataDir = path.join(dilaDir, "kali")
assert(await fs.pathExists(dataDir))
iterXmlFiles: for (const relativeSplitPath of walkDir(dataDir)) {
const relativePath = path.join(...relativeSplitPath)
@ -206,7 +206,7 @@ async function importKali(
) VALUES (
${texteVersion.META.META_COMMUN.ID},
${db.json(texteVersion as unknown as JSONValue)},
${texteVersion.META.META_COMMUN.NATURE}
${texteVersion.META.META_COMMUN.NATURE},
setweight(to_tsvector('french', ${textAFragments.join(
" ",
)}), 'A')

View file

@ -8,8 +8,12 @@ import type { JSONValue } from "postgres"
import sade from "sade"
import { auditId, auditVersions } from "$lib/auditors/legal"
import {
auditLegiArticle,
// legiArticleStats
} from "$lib/auditors/legi"
import type {
Article,
LegiArticle,
SectionTa,
Textelr,
TexteVersion,
@ -98,7 +102,7 @@ async function importLegi(
).map(({ eli }) => eli),
)
const dataDir = path.join(dilaDir, "dole")
const dataDir = path.join(dilaDir, "legi")
assert(await fs.pathExists(dataDir))
iterXmlFiles: for (const relativeSplitPath of walkDir(dataDir)) {
const relativePath = path.join(...relativeSplitPath)
@ -124,7 +128,7 @@ async function importLegi(
const xmlData = xmlParser.parse(xmlString)
for (const [key, element] of Object.entries(xmlData) as [
string,
Article | SectionTa | Textelr | TexteVersion | Versions | XmlHeader,
LegiArticle | SectionTa | Textelr | TexteVersion | Versions | XmlHeader,
][]) {
switch (key) {
case "?xml": {
@ -134,7 +138,19 @@ async function importLegi(
break
}
case "ARTICLE": {
const article = element as Article
const [article, error] = auditChain(auditLegiArticle, auditRequire)(
strictAudit,
element,
) as [LegiArticle, unknown]
assert.strictEqual(
error,
null,
`Unexpected format for ARTICLE:\n${JSON.stringify(
article,
null,
2,
)}\nError:\n${JSON.stringify(error, null, 2)}`,
)
await db`
INSERT INTO article (
id,
@ -215,7 +231,7 @@ async function importLegi(
) VALUES (
${texteVersion.META.META_COMMUN.ID},
${db.json(texteVersion as unknown as JSONValue)},
${texteVersion.META.META_COMMUN.NATURE}
${texteVersion.META.META_COMMUN.NATURE},
setweight(to_tsvector('french', ${textAFragments.join(
" ",
)}), 'A')
@ -342,6 +358,10 @@ async function importLegi(
`
}
}
// console.log(
// "LEGI articles stats =",
// JSON.stringify(legiArticleStats, null, 2),
// )
}
sade("import_legi <dilaDir>", true)