@tricoteuses/senat 2.22.4 → 2.22.6

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.
@@ -70,7 +70,16 @@ export function extractMetadata(xmlDoc) {
70
70
  return metadata;
71
71
  }
72
72
  export async function convertSenatXmlToHtml(texteXml, outputFilePath) {
73
- const { document: xmlDoc } = new JSDOM(texteXml, { contentType: "text/xml" }).window;
73
+ let xmlDoc;
74
+ try {
75
+ xmlDoc = new JSDOM(texteXml, { contentType: "text/xml" }).window.document;
76
+ }
77
+ catch (err) {
78
+ if (await fs.pathExists(outputFilePath)) {
79
+ await fs.remove(outputFilePath);
80
+ }
81
+ throw err;
82
+ }
74
83
  const metadata = extractMetadata(xmlDoc);
75
84
  const xmlBody = xmlDoc.querySelector("body");
76
85
  const style = `
@@ -9,5 +9,5 @@ export type { CompteRendu } from "./types/compte_rendu";
9
9
  export type { Debat, LecAssDeb } from "./types/debats";
10
10
  export type { Ass, Aud, Auteur, DateSeance, DecCoc, DenRap, DocAtt, Ecr, EtaLoi, LecAss, LecAssRap, Lecture, Loi, Org, OriTxt, Qua, Rap, RapOrg, Scr, Texte, TypAtt, TypLec, TypLoi, TypTxt, TypUrl, } from "./types/dosleg";
11
11
  export type { Photo, Sen } from "./types/sens";
12
- export { UNDEFINED_SESSION, type Session, getSessionsFromStart } from "./types/sessions";
12
+ export { sessionOptions, sessionOptionsOrAll, UNDEFINED_SESSION, type Session, type SessionOrAll, getSessionsFromStart, } from "./types/sessions";
13
13
  export type { Alinea, Article, Division, DivisionTag, FlatTexte } from "./types/texte";
package/lib/src/index.js CHANGED
@@ -1 +1 @@
1
- export { UNDEFINED_SESSION, getSessionsFromStart } from "./types/sessions";
1
+ export { sessionOptions, sessionOptionsOrAll, UNDEFINED_SESSION, getSessionsFromStart, } from "./types/sessions";
@@ -14,6 +14,7 @@ export declare const AGENDA_FOLDER = "agenda";
14
14
  export declare const COMPTES_RENDUS_FOLDER = "seances";
15
15
  export declare const COMMISSION_FOLDER = "commissions";
16
16
  export declare const DOSLEG_DOSSIERS_FOLDER = "dossiers";
17
+ export declare const ENRICHED_TEXTE_FOLDER = "leg_enrichi";
17
18
  export declare const SCRUTINS_FOLDER = "scrutins";
18
19
  export declare const SENS_CIRCONSCRIPTIONS_FOLDER = "circonscriptions";
19
20
  export declare const SENS_ORGANISMES_FOLDER = "organismes";
@@ -9,6 +9,7 @@ export const AGENDA_FOLDER = "agenda";
9
9
  export const COMPTES_RENDUS_FOLDER = "seances";
10
10
  export const COMMISSION_FOLDER = "commissions";
11
11
  export const DOSLEG_DOSSIERS_FOLDER = "dossiers";
12
+ export const ENRICHED_TEXTE_FOLDER = "leg_enrichi";
12
13
  export const SCRUTINS_FOLDER = "scrutins";
13
14
  export const SENS_CIRCONSCRIPTIONS_FOLDER = "circonscriptions";
14
15
  export const SENS_ORGANISMES_FOLDER = "organismes";
@@ -11,6 +11,8 @@ declare const findAllAmendementsQuery: import("kysely").SelectQueryBuilder<{
11
11
  etat: string;
12
12
  sort: any;
13
13
  url: string;
14
+ au_nom_de_commission: string;
15
+ code_commission: string;
14
16
  auteur_est_gouvernement: boolean;
15
17
  scrutin_num: any;
16
18
  auteurs: {
@@ -33,6 +35,8 @@ export declare function findAllAmendements(fromSession?: number): AsyncIterableI
33
35
  etat: string;
34
36
  sort: any;
35
37
  url: string;
38
+ au_nom_de_commission: string;
39
+ code_commission: string;
36
40
  auteur_est_gouvernement: boolean;
37
41
  scrutin_num: any;
38
42
  auteurs: {
@@ -1,7 +1,7 @@
1
1
  import { sql } from "kysely";
2
2
  import { jsonArrayFrom } from "kysely/helpers/postgres";
3
3
  import { dbSenat } from "../databases";
4
- import { concat, toDateString } from "./util";
4
+ import { concat, rtrim, toDateString } from "./util";
5
5
  function auteurs(amendementId) {
6
6
  return jsonArrayFrom(dbSenat
7
7
  .selectFrom("ameli.amdsen")
@@ -134,8 +134,8 @@ const findAllAmendementsQuery = dbSenat
134
134
  .else(val("https://www.senat.fr/amendements/"))
135
135
  .end(), ref("ameli.ses.ann"), val("-"), sql `(ameli.ses.ann + 1)`, val("/"), ref("ameli.txt_ameli.numabs"), val("/Amdt_"), ref("ameli.amd.num"), val(".html")).as("url"),
136
136
  "ameli.grppol_ameli.lilcou as au_nom_de_groupe_politique",
137
- "ameli.com_ameli.lil as au_nom_de_commission",
138
- "ameli.com_ameli.cod as code_commission",
137
+ rtrim(ref("ameli.com_ameli.lil")).as("au_nom_de_commission"),
138
+ rtrim(ref("ameli.com_ameli.cod")).as("code_commission"),
139
139
  eb.case().when("ameli.cab.entid", "is not", null).then(true).else(false).end().as("auteur_est_gouvernement"),
140
140
  scrutin(ref("ameli.amd.num"), ref("ameli.ses.ann"), ref("dosleg.texte.lecassidt")),
141
141
  auteurs(ref("ameli.amd.id")).as("auteurs"),
@@ -62,7 +62,7 @@ function buildEmptyArticle(index) {
62
62
  alineas: [],
63
63
  };
64
64
  }
65
- function flattenTexte(texteContentRoot) {
65
+ function splitTexte(texteContentRoot) {
66
66
  const divisions = [];
67
67
  let divisionIndex = 0;
68
68
  const iter = (node) => {
@@ -129,7 +129,7 @@ export function transformTexte(document) {
129
129
  date_depot: dateDepot ? new Date(dateDepot) : null,
130
130
  date_publication_xml: datePublicationXml ? new Date(datePublicationXml) : null,
131
131
  version: identificationParts?.["version"] ? identificationParts["version"] : null,
132
- divisions: bodyElement ? flattenTexte(bodyElement) : [],
132
+ divisions: bodyElement ? splitTexte(bodyElement) : [],
133
133
  };
134
134
  }
135
135
  export function transformExposeDesMotifs(document) {
@@ -5,7 +5,7 @@ import path from "path";
5
5
  import pLimit from "p-limit";
6
6
  import * as git from "../git";
7
7
  import { datasets, EnabledDatasets, getEnabledDatasets } from "../datasets";
8
- import { DATA_ORIGINAL_FOLDER, DATA_TRANSFORMED_FOLDER, DOCUMENT_METADATA_FILE, DOSLEG_DOSSIERS_FOLDER, SCRUTINS_FOLDER, RAPPORT_FOLDER, SENS_CIRCONSCRIPTIONS_FOLDER, SENS_ORGANISMES_FOLDER, SENS_SENATEURS_FOLDER, TEXTE_FOLDER, } from "../loaders";
8
+ import { DATA_ORIGINAL_FOLDER, DATA_TRANSFORMED_FOLDER, DOCUMENT_METADATA_FILE, DOSLEG_DOSSIERS_FOLDER, SCRUTINS_FOLDER, RAPPORT_FOLDER, SENS_CIRCONSCRIPTIONS_FOLDER, SENS_ORGANISMES_FOLDER, SENS_SENATEURS_FOLDER, TEXTE_FOLDER, ENRICHED_TEXTE_FOLDER, } from "../loaders";
9
9
  import { findAllAmendements, findAllCirconscriptions, findAllDebats, findAllDossiers, findAllScrutins, findAllOrganismes, findAllQuestions, findAllSens, findAllTextes, findAllRapports, } from "../model";
10
10
  import { processRapport, processTexte } from "./retrieve_documents";
11
11
  import { buildActesLegislatifs } from "../model/dosleg";
@@ -40,7 +40,7 @@ async function convertData() {
40
40
  commitAndPushGit(ameliDir, options);
41
41
  }
42
42
  catch (error) {
43
- console.error(`Error converting Ameli dataset:`, error);
43
+ console.error("Error converting Ameli dataset:", error);
44
44
  }
45
45
  }
46
46
  if (enabledDatasets & EnabledDatasets.Debats) {
@@ -50,7 +50,7 @@ async function convertData() {
50
50
  commitAndPushGit(debatsDir, options);
51
51
  }
52
52
  catch (error) {
53
- console.error(`Error converting Debats dataset:`, error);
53
+ console.error("Error converting Debats dataset:", error);
54
54
  }
55
55
  }
56
56
  if (enabledDatasets & EnabledDatasets.DosLeg) {
@@ -60,7 +60,7 @@ async function convertData() {
60
60
  commitAndPushGit(doslegDir, options);
61
61
  }
62
62
  catch (error) {
63
- console.error(`Error converting DosLeg dataset:`, error);
63
+ console.error("Error converting DosLeg dataset:", error);
64
64
  }
65
65
  try {
66
66
  await convertDatasetScrutins(dataDir, options);
@@ -68,7 +68,7 @@ async function convertData() {
68
68
  commitAndPushGit(scrutinsDir, options);
69
69
  }
70
70
  catch (error) {
71
- console.error(`Error converting Scrutins dataset:`, error);
71
+ console.error("Error converting Scrutins dataset:", error);
72
72
  }
73
73
  }
74
74
  if (enabledDatasets & EnabledDatasets.Questions) {
@@ -78,7 +78,7 @@ async function convertData() {
78
78
  commitAndPushGit(questionsDir, options);
79
79
  }
80
80
  catch (error) {
81
- console.error(`Error converting Questions dataset:`, error);
81
+ console.error("Error converting Questions dataset:", error);
82
82
  }
83
83
  }
84
84
  if (enabledDatasets & EnabledDatasets.Sens) {
@@ -88,7 +88,7 @@ async function convertData() {
88
88
  commitAndPushGit(sensDir, options);
89
89
  }
90
90
  catch (error) {
91
- console.error(`Error converting Sens dataset:`, error);
91
+ console.error("Error converting Sens dataset:", error);
92
92
  }
93
93
  }
94
94
  if (!options["silent"]) {
@@ -220,8 +220,9 @@ async function convertDatasetQuestions(dataDir, options) {
220
220
  async function convertTextes(dataDir, options) {
221
221
  const originalTextesDir = path.join(dataDir, TEXTE_FOLDER, DATA_ORIGINAL_FOLDER);
222
222
  const transformedTextesDir = path.join(dataDir, TEXTE_FOLDER, DATA_TRANSFORMED_FOLDER);
223
+ const enrichedTextesDir = path.join(dataDir, ENRICHED_TEXTE_FOLDER);
223
224
  if (!options["silent"]) {
224
- console.log(`Converting database textes data into files…`);
225
+ console.log("Converting database textes data into files…");
225
226
  }
226
227
  for await (const texte of findAllTextes()) {
227
228
  const session = texte["session"] ?? UNDEFINED_SESSION;
@@ -253,14 +254,14 @@ async function convertTextes(dataDir, options) {
253
254
  spaces: 2,
254
255
  });
255
256
  if (options.fetchDocuments) {
256
- await processTexte(metadata, originalTextesDir, transformedTextesDir, options);
257
+ await processTexte(metadata, originalTextesDir, transformedTextesDir, enrichedTextesDir, options);
257
258
  }
258
259
  }
259
260
  }
260
261
  async function convertRapports(dataDir, options) {
261
262
  const originalRapportsDir = path.join(dataDir, RAPPORT_FOLDER, DATA_ORIGINAL_FOLDER);
262
263
  if (!options["silent"]) {
263
- console.log(`Converting database rapports data into files…`);
264
+ console.log("Converting database rapports data into files…");
264
265
  }
265
266
  for await (const rapport of findAllRapports()) {
266
267
  const session = rapport["session"] ?? UNDEFINED_SESSION;
@@ -1,3 +1,3 @@
1
1
  import { DocumentMetadata } from "../types/texte";
2
- export declare function processTexte(texteMetadata: DocumentMetadata, originalTextesDir: string, transformedTextesDir: string, options: any): Promise<void>;
2
+ export declare function processTexte(texteMetadata: DocumentMetadata, originalTextesDir: string, transformedTextesDir: string, enrichedTextesDir: string, options: any): Promise<void>;
3
3
  export declare function processRapport(rapportMetadata: any, originalRapportsDir: string, options: any): Promise<void>;
@@ -3,8 +3,9 @@ import commandLineArgs from "command-line-args";
3
3
  import fs from "fs-extra";
4
4
  import { DateTime } from "luxon";
5
5
  import path from "path";
6
+ import { convertSenatXmlToHtml } from "../conversion_textes";
6
7
  import * as git from "../git";
7
- import { DATA_ORIGINAL_FOLDER, DATA_TRANSFORMED_FOLDER, iterLoadSenatRapportUrls, iterLoadSenatTexteUrls, RAPPORT_FOLDER, TEXTE_FOLDER, } from "../loaders";
8
+ import { DATA_ORIGINAL_FOLDER, DATA_TRANSFORMED_FOLDER, ENRICHED_TEXTE_FOLDER, iterLoadSenatRapportUrls, iterLoadSenatTexteUrls, RAPPORT_FOLDER, TEXTE_FOLDER, } from "../loaders";
8
9
  import { parseExposeDesMotifs, parseTexte, parseTexteFromFile } from "../parsers/texte";
9
10
  import { getSessionsFromStart, UNDEFINED_SESSION } from "../types/sessions";
10
11
  import { commonOptions } from "./shared/cli_helpers";
@@ -98,7 +99,7 @@ async function processDocument(url, destPath, docDate, options) {
98
99
  await fs.outputFile(destPath, buffer);
99
100
  return { success: true, skipped: false, buffer };
100
101
  }
101
- export async function processTexte(texteMetadata, originalTextesDir, transformedTextesDir, options) {
102
+ export async function processTexte(texteMetadata, originalTextesDir, transformedTextesDir, enrichedTextesDir, options) {
102
103
  const texteDir = path.join(originalTextesDir, `${texteMetadata.session ?? UNDEFINED_SESSION}`, texteMetadata.name);
103
104
  let exposeDesMotifsContent = null;
104
105
  if (texteMetadata.url_expose_des_motifs) {
@@ -121,19 +122,30 @@ export async function processTexte(texteMetadata, originalTextesDir, transformed
121
122
  for (const format of formats) {
122
123
  if (!isOptionEmptyOrHasValue(options.formats, format.type))
123
124
  continue;
124
- if (!format.url)
125
+ if (format.url === undefined || format.url.toString().includes("#"))
125
126
  continue;
126
127
  const destPath = path.join(texteDir, `${texteMetadata.name}.${format.type}`);
127
128
  const result = await processDocument(format.url.toString(), destPath, texteMetadata.date, options);
128
129
  // Specific logic: Parsing (Only applies to XML)
129
130
  if (format.isParseTarget && options.parseDocuments) {
130
- if (!result.buffer && !(await fs.pathExists(destPath))) {
131
- if (options.verbose) {
132
- console.warn(`Skipping parse for missing XML file: ${destPath}`);
131
+ if (result.buffer !== null || (await fs.pathExists(destPath))) {
132
+ await parseDocument(texteMetadata.session, transformedTextesDir, destPath, texteMetadata.name, result.buffer, exposeDesMotifsContent, options);
133
+ }
134
+ let texteXmlContent = null;
135
+ if (result.buffer === null && (await fs.pathExists(destPath))) {
136
+ texteXmlContent = await fs.readFile(destPath, "utf-8");
137
+ }
138
+ else if (result.buffer !== null) {
139
+ texteXmlContent = textDecoder.decode(result.buffer);
140
+ }
141
+ if (texteXmlContent !== null) {
142
+ try {
143
+ await convertSenatXmlToHtml(texteXmlContent, path.join(enrichedTextesDir, `${texteMetadata.session ?? UNDEFINED_SESSION}`, texteMetadata.name, `${texteMetadata.name}.html`));
144
+ }
145
+ catch (error) {
146
+ console.error(`Error converting ${texteMetadata.name} to HTML: ${error.message}`);
133
147
  }
134
- continue;
135
148
  }
136
- await parseDocument(texteMetadata.session, transformedTextesDir, destPath, texteMetadata.name, result.buffer, exposeDesMotifsContent, options);
137
149
  }
138
150
  }
139
151
  }
@@ -154,8 +166,10 @@ async function processTextes(dataDir, sessions) {
154
166
  const textesDir = path.join(dataDir, TEXTE_FOLDER);
155
167
  const originalTextesDir = path.join(textesDir, DATA_ORIGINAL_FOLDER);
156
168
  const transformedTextesDir = path.join(textesDir, DATA_TRANSFORMED_FOLDER);
157
- if (options["parseDocuments"]) {
169
+ const enrichedTextesDir = path.join(dataDir, ENRICHED_TEXTE_FOLDER);
170
+ if (options["parseDocuments"] && options["only-recent"] === undefined) {
158
171
  ensureAndClearDir(transformedTextesDir);
172
+ ensureAndClearDir(enrichedTextesDir);
159
173
  }
160
174
  const dlOptions = {
161
175
  force: options["force"],
@@ -167,10 +181,11 @@ async function processTextes(dataDir, sessions) {
167
181
  };
168
182
  for (const session of sessions) {
169
183
  for (const { item: texteMetadata } of iterLoadSenatTexteUrls(dataDir, session)) {
170
- await processTexte(texteMetadata, originalTextesDir, transformedTextesDir, dlOptions);
184
+ await processTexte(texteMetadata, originalTextesDir, transformedTextesDir, enrichedTextesDir, dlOptions);
171
185
  }
172
186
  }
173
187
  commitAndPushGit(textesDir);
188
+ commitAndPushGit(enrichedTextesDir);
174
189
  }
175
190
  async function processRapports(dataDir, sessions) {
176
191
  const rapportsDir = path.join(dataDir, RAPPORT_FOLDER);
@@ -297,7 +297,7 @@ async function retrieveOpenData() {
297
297
  if (options["schema"]) {
298
298
  const dbConnectionString = `postgres://${process.env["PGUSER"]}:${process.env["PGPASSWORD"]}@${process.env["PGHOST"]}:${process.env["PGPORT"]}/senat`;
299
299
  const definitionsDir = path.resolve("src", "raw_types");
300
- const definitionFilePath = path.join(definitionsDir, `senat.ts`);
300
+ const definitionFilePath = path.join(definitionsDir, "senat.ts");
301
301
  execSync(`npx kysely-codegen --url '${dbConnectionString}' --out-file ${definitionFilePath}`, {
302
302
  env: process.env,
303
303
  encoding: "utf-8",
@@ -1,5 +1,6 @@
1
1
  export declare const UNDEFINED_SESSION = 0;
2
- declare const sessions: readonly [0, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026];
3
- export type Session = (typeof sessions)[number];
4
- export declare function getSessionsFromStart(startSession: Session): (0 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026)[];
5
- export {};
2
+ export declare const sessionOptions: readonly [1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026];
3
+ export declare const sessionOptionsOrAll: readonly [0, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026];
4
+ export type Session = (typeof sessionOptions)[number];
5
+ export type SessionOrAll = (typeof sessionOptionsOrAll)[number];
6
+ export declare function getSessionsFromStart(startSession: SessionOrAll): (1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026)[];
@@ -1,84 +1,19 @@
1
1
  export const UNDEFINED_SESSION = 0;
2
- const sessions = [
3
- UNDEFINED_SESSION,
4
- 1958,
5
- 1959,
6
- 1960,
7
- 1961,
8
- 1962,
9
- 1963,
10
- 1964,
11
- 1965,
12
- 1966,
13
- 1967,
14
- 1968,
15
- 1969,
16
- 1970,
17
- 1971,
18
- 1972,
19
- 1973,
20
- 1974,
21
- 1975,
22
- 1976,
23
- 1977,
24
- 1978,
25
- 1979,
26
- 1980,
27
- 1981,
28
- 1982,
29
- 1983,
30
- 1984,
31
- 1985,
32
- 1986,
33
- 1987,
34
- 1988,
35
- 1989,
36
- 1990,
37
- 1991,
38
- 1992,
39
- 1993,
40
- 1994,
41
- 1995,
42
- 1996,
43
- 1997,
44
- 1998,
45
- 1999,
46
- 2000,
47
- 2001,
48
- 2002,
49
- 2003,
50
- 2004,
51
- 2005,
52
- 2006,
53
- 2007,
54
- 2008,
55
- 2009,
56
- 2010,
57
- 2011,
58
- 2012,
59
- 2013,
60
- 2014,
61
- 2015,
62
- 2016,
63
- 2017,
64
- 2018,
65
- 2019,
66
- 2020,
67
- 2021,
68
- 2022,
69
- 2023,
70
- 2024,
71
- 2025,
72
- 2026,
2
+ export const sessionOptions = [
3
+ 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
4
+ 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
5
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
6
+ 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026,
73
7
  // TO COMPLETE EVERY YEAR :)
74
8
  ];
9
+ export const sessionOptionsOrAll = [UNDEFINED_SESSION, ...sessionOptions];
75
10
  export function getSessionsFromStart(startSession) {
76
- if (startSession === 0) {
77
- return Array.from(sessions);
11
+ if (startSession === UNDEFINED_SESSION) {
12
+ return Array.from(sessionOptions);
78
13
  }
79
- const sessionIndex = sessions.findIndex((session) => startSession === session);
14
+ const sessionIndex = sessionOptions.findIndex((session) => startSession === session);
80
15
  if (sessionIndex >= 0) {
81
- return sessions.slice(sessionIndex);
16
+ return sessionOptions.slice(sessionIndex);
82
17
  }
83
18
  return [];
84
19
  }
@@ -63,6 +63,8 @@ export interface Alinea extends DivisionContent {
63
63
  eId: string;
64
64
  heading: DivisionContent;
65
65
  pastille: string | null;
66
+ text_avec_liens?: string | null;
67
+ html_avec_liens?: string | null;
66
68
  }
67
69
  export interface ExposeDesMotifs {
68
70
  text: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tricoteuses/senat",
3
- "version": "2.22.4",
3
+ "version": "2.22.6",
4
4
  "description": "Handle French Sénat's open data",
5
5
  "keywords": [
6
6
  "France",
@@ -83,9 +83,8 @@
83
83
  "pg-cursor": "^2.12.1",
84
84
  "slug": "^11.0.0",
85
85
  "tsx": "^4.21.0",
86
- "zod": "^4.3.5",
87
- "vitest": "^4.0.18",
88
- "windows-1252": "^3.0.4"
86
+ "windows-1252": "^3.0.4",
87
+ "zod": "^4.3.5"
89
88
  },
90
89
  "devDependencies": {
91
90
  "@typed-code/schemats": "^5.0.1",
@@ -106,6 +105,7 @@
106
105
  "kysely-codegen": "^0.19.0",
107
106
  "prettier": "^3.5.3",
108
107
  "tslib": "^2.1.0",
109
- "typescript": "^5.9.3"
108
+ "typescript": "^5.9.3",
109
+ "vitest": "^4.0.18"
110
110
  }
111
111
  }