diff --git a/src/lib/data.ts b/src/lib/data.ts
index fae6c82..10006cf 100644
--- a/src/lib/data.ts
+++ b/src/lib/data.ts
@@ -31,6 +31,11 @@ export interface Contexte {
export type Etat = "MODIFIE" | "VIGUEUR"
+export interface IdWrapper {
+ eli: string
+ id: string
+}
+
export interface Jo {
META: {
META_SPEC: {
@@ -46,11 +51,12 @@ export interface Jo {
export type LegalObject =
| Article
+ | IdWrapper
| Jo
| SectionTa
| Textelr
| TexteVersion
- | Versions
+ | VersionsWrapper
export type LegalObjectType =
| "article"
@@ -116,6 +122,11 @@ export interface Versions {
}
}
+export interface VersionsWrapper {
+ eli: string
+ versions: Versions
+}
+
export interface XmlHeader {
"@encoding": "UTF-8"
"@version": "1.0"
@@ -149,17 +160,17 @@ export function pathnameFromLegalObject(
case "article":
return `/article/${(object as Article).META.META_COMMUN.ID}`
case "id":
- return `/eli/ids/TODO`
+ return `/id/${(object as IdWrapper).eli}`
case "jo":
return `/jo/${(object as Jo).META.META_COMMUN.ID}`
case "section_ta":
- return `/section_ta/${(object as unknown as SectionTa).ID}`
+ return `/section_ta/${(object as SectionTa).ID}`
case "texte_version":
return `/texte_version/${(object as TexteVersion).META.META_COMMUN.ID}`
case "textelr":
return `/textelr/${(object as Textelr).META.META_COMMUN.ID}`
case "versions":
- return `/eli/versions/TODO`
+ return `/versions/${(object as VersionsWrapper).eli}`
default:
assertNeverLegalObjectType(type)
}
@@ -173,7 +184,8 @@ export function pathnameFromLegalObjectId(
case "article":
return `/article/${id}`
case "id":
- return `/eli/ids/TODO`
+ // Here, id is an ELI.
+ return `/id/{id}`
case "jo":
return `/jo/${id}`
case "section_ta":
@@ -183,7 +195,8 @@ export function pathnameFromLegalObjectId(
case "textelr":
return `/textelr/${id}`
case "versions":
- return `/eli/versions/TODO`
+ // Here, id is an ELI.
+ return `/versions/${id}`
default:
assertNeverLegalObjectType(type)
}
diff --git a/src/lib/summaries.ts b/src/lib/summaries.ts
index eb3eb0e..fd763a1 100644
--- a/src/lib/summaries.ts
+++ b/src/lib/summaries.ts
@@ -5,6 +5,7 @@ import {
type Article,
assertNeverLegalObjectType,
bestItemForDate,
+ type IdWrapper,
type Jo,
type LegalObject,
type LegalObjectType,
@@ -14,6 +15,7 @@ import {
type Textelr,
type TexteVersion,
type LienArt,
+ type VersionsWrapper,
} from "$lib/data"
export const summarizeArticleProperties: Summarizer = (access, value) => {
@@ -78,6 +80,17 @@ export const summarizeArticleProperties: Summarizer = (access, value) => {
return undefined
}
+export const summarizeIdWrapperProperties: Summarizer = (access, value) => {
+ if (access?.key === "id" && typeof value !== "number") {
+ return summarizeLegalObject(access, "id", value)
+ }
+ if (typeof access?.key === "number" && access?.access?.key === "id") {
+ return summarizeLegalObjectToLink(access, "id", value)
+ }
+
+ return undefined
+}
+
export const summarizeJoProperties: Summarizer = (access, value) => {
if (access?.key === "jo" && typeof value !== "number") {
return summarizeLegalObject(access, "jo", value)
@@ -136,7 +149,8 @@ export function summarizeLegalObject(
}
}
case "id":
- return `/eli/ids/TODO`
+ const idWrapper = value as IdWrapper | undefined
+ return idWrapper?.eli
case "jo": {
const jo = value as Jo | undefined
return jo?.META.META_SPEC.META_CONTENEUR.TITRE
@@ -160,7 +174,8 @@ export function summarizeLegalObject(
return textelr?.META.META_COMMUN.ID
}
case "versions":
- return `/eli/versions/TODO`
+ const versionsWrapper = value as VersionsWrapper | undefined
+ return versionsWrapper?.eli
default:
assertNeverLegalObjectType(type)
}
@@ -260,3 +275,17 @@ export const summarizeTexteVersionProperties: Summarizer = (access, value) => {
return undefined
}
+
+export const summarizeVersionsWrapperProperties: Summarizer = (
+ access,
+ value,
+) => {
+ if (access?.key === "versions" && typeof value !== "number") {
+ return summarizeLegalObject(access, "versions", value)
+ }
+ if (typeof access?.key === "number" && access?.access?.key === "versions") {
+ return summarizeLegalObjectToLink(access, "versions", value)
+ }
+
+ return undefined
+}
diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte
index 13ab40c..6b07f41 100644
--- a/src/routes/__layout.svelte
+++ b/src/routes/__layout.svelte
@@ -30,12 +30,12 @@
{
items: [
{ href: "/article", label: "ARTICLE" },
- // { href: "/eli/ids", label: "ID" },
+ { href: "/id", label: "ID" },
{ href: "/jo", label: "JO" },
{ href: "/section_ta", label: "SECTION_TA" },
{ href: "/texte_version", label: "TEXTE_VERSION" },
{ href: "/textelr", label: "TEXTELR" },
- // { href: "/eli/versions", label: "VERSIONS" },
+ { href: "/versions", label: "VERSIONS" },
],
label: "Données",
},
diff --git a/src/routes/id/[...eli].svelte b/src/routes/id/[...eli].svelte
new file mode 100644
index 0000000..d4d760f
--- /dev/null
+++ b/src/routes/id/[...eli].svelte
@@ -0,0 +1,39 @@
+
+
+
+ ID
+ {#if summary !== undefined}
+
+
+
+ {/if}
+
+
+{#if error != null}
+
+{/if}
+
+{#if error == null}
+
+{/if}
diff --git a/src/routes/id/[...eli].ts b/src/routes/id/[...eli].ts
new file mode 100644
index 0000000..356955f
--- /dev/null
+++ b/src/routes/id/[...eli].ts
@@ -0,0 +1,22 @@
+import type { RequestHandler } from "@sveltejs/kit"
+import type { JSONObject } from "@sveltejs/kit/types/private"
+
+import type { IdWrapper } from "$lib/data"
+import { db } from "$lib/server/database"
+
+export const GET: RequestHandler = async ({ params }) => {
+ const idWrapper = (
+ await db<{ data: IdWrapper }[]>`
+ SELECT eli, id FROM id
+ WHERE eli = ${params.eli}
+ `
+ )[0]
+
+ if (idWrapper === undefined) {
+ return { headers: { "Access-Control-Allow-Origin": "*" }, status: 404 }
+ }
+ return {
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: { id: idWrapper as unknown as JSONObject },
+ }
+}
diff --git a/src/routes/id/index.svelte b/src/routes/id/index.svelte
new file mode 100644
index 0000000..cb9f5b6
--- /dev/null
+++ b/src/routes/id/index.svelte
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+{#if error != null}
+
+{/if}
+
+{#if error == null}
+
+
+
+{/if}
diff --git a/src/routes/id/index.ts b/src/routes/id/index.ts
new file mode 100644
index 0000000..c2c25f9
--- /dev/null
+++ b/src/routes/id/index.ts
@@ -0,0 +1,70 @@
+import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core"
+import type { RequestHandler } from "@sveltejs/kit"
+import type { JSONObject } from "@sveltejs/kit/types/private"
+
+import { auditSearchQueryContent } from "$lib/auditors/queries"
+import type { IdWrapper } from "$lib/data"
+import { db } from "$lib/server/database"
+
+export function auditQuery(
+ audit: Audit,
+ query: URLSearchParams,
+): [unknown, unknown] {
+ if (query == null) {
+ return [query, null]
+ }
+ if (!(query instanceof URLSearchParams)) {
+ return audit.unexpectedType(query, "URLSearchParams")
+ }
+
+ const data: { [key: string]: unknown } = {}
+ for (const [key, value] of query.entries()) {
+ let values = data[key] as string[] | undefined
+ if (values === undefined) {
+ values = data[key] = []
+ }
+ values.push(value)
+ }
+ const errors: { [key: string]: unknown } = {}
+ const remainingKeys = new Set(Object.keys(data))
+
+ auditSearchQueryContent(audit, data, errors, remainingKeys)
+
+ return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({}))
+}
+
+export const GET: RequestHandler = async ({ url }) => {
+ const [query, queryError] = auditQuery(cleanAudit, url.searchParams) as [
+ { limit: number; offset: number; q?: string },
+ unknown,
+ ]
+ if (queryError !== null) {
+ console.error(
+ `Error in ${url.pathname} query:\n${JSON.stringify(
+ query,
+ null,
+ 2,
+ )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`,
+ )
+ return {
+ // status: 400,
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: {
+ error: {
+ query: queryError as unknown as JSONObject,
+ },
+ },
+ }
+ }
+ const { limit, offset } = query
+
+ const idsWrapper = await db`
+ SELECT eli, id FROM id
+ OFFSET ${offset}
+ LIMIT ${limit}
+ `
+ return {
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: { id: idsWrapper as unknown as JSONObject[] },
+ }
+}
diff --git a/src/routes/versions/[...eli].svelte b/src/routes/versions/[...eli].svelte
new file mode 100644
index 0000000..c519f58
--- /dev/null
+++ b/src/routes/versions/[...eli].svelte
@@ -0,0 +1,43 @@
+
+
+
+ VERSIONS
+ {#if summary !== undefined}
+
+
+
+ {/if}
+
+
+{#if error != null}
+
+{/if}
+
+{#if error == null}
+
+{/if}
diff --git a/src/routes/versions/[...eli].ts b/src/routes/versions/[...eli].ts
new file mode 100644
index 0000000..32107f1
--- /dev/null
+++ b/src/routes/versions/[...eli].ts
@@ -0,0 +1,22 @@
+import type { RequestHandler } from "@sveltejs/kit"
+import type { JSONObject } from "@sveltejs/kit/types/private"
+
+import type { VersionsWrapper } from "$lib/data"
+import { db } from "$lib/server/database"
+
+export const GET: RequestHandler = async ({ params }) => {
+ const versionsWrapper = (
+ await db<{ data: VersionsWrapper }[]>`
+ SELECT eli, id, data FROM versions
+ WHERE eli = ${params.eli}
+ `
+ )[0]
+
+ if (versionsWrapper === undefined) {
+ return { headers: { "Access-Control-Allow-Origin": "*" }, status: 404 }
+ }
+ return {
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: { versions: versionsWrapper as unknown as JSONObject },
+ }
+}
diff --git a/src/routes/versions/index.svelte b/src/routes/versions/index.svelte
new file mode 100644
index 0000000..4773e66
--- /dev/null
+++ b/src/routes/versions/index.svelte
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+{#if error != null}
+
+{/if}
+
+{#if error == null}
+
+
+
+{/if}
diff --git a/src/routes/versions/index.ts b/src/routes/versions/index.ts
new file mode 100644
index 0000000..dfc81ff
--- /dev/null
+++ b/src/routes/versions/index.ts
@@ -0,0 +1,70 @@
+import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core"
+import type { RequestHandler } from "@sveltejs/kit"
+import type { JSONObject } from "@sveltejs/kit/types/private"
+
+import { auditSearchQueryContent } from "$lib/auditors/queries"
+import type { VersionsWrapper } from "$lib/data"
+import { db } from "$lib/server/database"
+
+export function auditQuery(
+ audit: Audit,
+ query: URLSearchParams,
+): [unknown, unknown] {
+ if (query == null) {
+ return [query, null]
+ }
+ if (!(query instanceof URLSearchParams)) {
+ return audit.unexpectedType(query, "URLSearchParams")
+ }
+
+ const data: { [key: string]: unknown } = {}
+ for (const [key, value] of query.entries()) {
+ let values = data[key] as string[] | undefined
+ if (values === undefined) {
+ values = data[key] = []
+ }
+ values.push(value)
+ }
+ const errors: { [key: string]: unknown } = {}
+ const remainingKeys = new Set(Object.keys(data))
+
+ auditSearchQueryContent(audit, data, errors, remainingKeys)
+
+ return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({}))
+}
+
+export const GET: RequestHandler = async ({ url }) => {
+ const [query, queryError] = auditQuery(cleanAudit, url.searchParams) as [
+ { limit: number; offset: number; q?: string },
+ unknown,
+ ]
+ if (queryError !== null) {
+ console.error(
+ `Error in ${url.pathname} query:\n${JSON.stringify(
+ query,
+ null,
+ 2,
+ )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`,
+ )
+ return {
+ // status: 400,
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: {
+ error: {
+ query: queryError as unknown as JSONObject,
+ },
+ },
+ }
+ }
+ const { limit, offset } = query
+
+ const versionsWrapper = await db`
+ SELECT eli, id, data FROM versions
+ OFFSET ${offset}
+ LIMIT ${limit}
+ `
+ return {
+ headers: { "Access-Control-Allow-Origin": "*" },
+ body: { versions: versionsWrapper as unknown as JSONObject[] },
+ }
+}