Add API & UI for ID & VERSIONS.
This commit is contained in:
parent
6842108f49
commit
ced57a197f
11 changed files with 454 additions and 10 deletions
|
@ -31,6 +31,11 @@ export interface Contexte {
|
||||||
|
|
||||||
export type Etat = "MODIFIE" | "VIGUEUR"
|
export type Etat = "MODIFIE" | "VIGUEUR"
|
||||||
|
|
||||||
|
export interface IdWrapper {
|
||||||
|
eli: string
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface Jo {
|
export interface Jo {
|
||||||
META: {
|
META: {
|
||||||
META_SPEC: {
|
META_SPEC: {
|
||||||
|
@ -46,11 +51,12 @@ export interface Jo {
|
||||||
|
|
||||||
export type LegalObject =
|
export type LegalObject =
|
||||||
| Article
|
| Article
|
||||||
|
| IdWrapper
|
||||||
| Jo
|
| Jo
|
||||||
| SectionTa
|
| SectionTa
|
||||||
| Textelr
|
| Textelr
|
||||||
| TexteVersion
|
| TexteVersion
|
||||||
| Versions
|
| VersionsWrapper
|
||||||
|
|
||||||
export type LegalObjectType =
|
export type LegalObjectType =
|
||||||
| "article"
|
| "article"
|
||||||
|
@ -116,6 +122,11 @@ export interface Versions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VersionsWrapper {
|
||||||
|
eli: string
|
||||||
|
versions: Versions
|
||||||
|
}
|
||||||
|
|
||||||
export interface XmlHeader {
|
export interface XmlHeader {
|
||||||
"@encoding": "UTF-8"
|
"@encoding": "UTF-8"
|
||||||
"@version": "1.0"
|
"@version": "1.0"
|
||||||
|
@ -149,17 +160,17 @@ export function pathnameFromLegalObject(
|
||||||
case "article":
|
case "article":
|
||||||
return `/article/${(object as Article).META.META_COMMUN.ID}`
|
return `/article/${(object as Article).META.META_COMMUN.ID}`
|
||||||
case "id":
|
case "id":
|
||||||
return `/eli/ids/TODO`
|
return `/id/${(object as IdWrapper).eli}`
|
||||||
case "jo":
|
case "jo":
|
||||||
return `/jo/${(object as Jo).META.META_COMMUN.ID}`
|
return `/jo/${(object as Jo).META.META_COMMUN.ID}`
|
||||||
case "section_ta":
|
case "section_ta":
|
||||||
return `/section_ta/${(object as unknown as SectionTa).ID}`
|
return `/section_ta/${(object as SectionTa).ID}`
|
||||||
case "texte_version":
|
case "texte_version":
|
||||||
return `/texte_version/${(object as TexteVersion).META.META_COMMUN.ID}`
|
return `/texte_version/${(object as TexteVersion).META.META_COMMUN.ID}`
|
||||||
case "textelr":
|
case "textelr":
|
||||||
return `/textelr/${(object as Textelr).META.META_COMMUN.ID}`
|
return `/textelr/${(object as Textelr).META.META_COMMUN.ID}`
|
||||||
case "versions":
|
case "versions":
|
||||||
return `/eli/versions/TODO`
|
return `/versions/${(object as VersionsWrapper).eli}`
|
||||||
default:
|
default:
|
||||||
assertNeverLegalObjectType(type)
|
assertNeverLegalObjectType(type)
|
||||||
}
|
}
|
||||||
|
@ -173,7 +184,8 @@ export function pathnameFromLegalObjectId(
|
||||||
case "article":
|
case "article":
|
||||||
return `/article/${id}`
|
return `/article/${id}`
|
||||||
case "id":
|
case "id":
|
||||||
return `/eli/ids/TODO`
|
// Here, id is an ELI.
|
||||||
|
return `/id/{id}`
|
||||||
case "jo":
|
case "jo":
|
||||||
return `/jo/${id}`
|
return `/jo/${id}`
|
||||||
case "section_ta":
|
case "section_ta":
|
||||||
|
@ -183,7 +195,8 @@ export function pathnameFromLegalObjectId(
|
||||||
case "textelr":
|
case "textelr":
|
||||||
return `/textelr/${id}`
|
return `/textelr/${id}`
|
||||||
case "versions":
|
case "versions":
|
||||||
return `/eli/versions/TODO`
|
// Here, id is an ELI.
|
||||||
|
return `/versions/${id}`
|
||||||
default:
|
default:
|
||||||
assertNeverLegalObjectType(type)
|
assertNeverLegalObjectType(type)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
type Article,
|
type Article,
|
||||||
assertNeverLegalObjectType,
|
assertNeverLegalObjectType,
|
||||||
bestItemForDate,
|
bestItemForDate,
|
||||||
|
type IdWrapper,
|
||||||
type Jo,
|
type Jo,
|
||||||
type LegalObject,
|
type LegalObject,
|
||||||
type LegalObjectType,
|
type LegalObjectType,
|
||||||
|
@ -14,6 +15,7 @@ import {
|
||||||
type Textelr,
|
type Textelr,
|
||||||
type TexteVersion,
|
type TexteVersion,
|
||||||
type LienArt,
|
type LienArt,
|
||||||
|
type VersionsWrapper,
|
||||||
} from "$lib/data"
|
} from "$lib/data"
|
||||||
|
|
||||||
export const summarizeArticleProperties: Summarizer = (access, value) => {
|
export const summarizeArticleProperties: Summarizer = (access, value) => {
|
||||||
|
@ -78,6 +80,17 @@ export const summarizeArticleProperties: Summarizer = (access, value) => {
|
||||||
return undefined
|
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) => {
|
export const summarizeJoProperties: Summarizer = (access, value) => {
|
||||||
if (access?.key === "jo" && typeof value !== "number") {
|
if (access?.key === "jo" && typeof value !== "number") {
|
||||||
return summarizeLegalObject(access, "jo", value)
|
return summarizeLegalObject(access, "jo", value)
|
||||||
|
@ -136,7 +149,8 @@ export function summarizeLegalObject(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "id":
|
case "id":
|
||||||
return `/eli/ids/TODO`
|
const idWrapper = value as IdWrapper | undefined
|
||||||
|
return idWrapper?.eli
|
||||||
case "jo": {
|
case "jo": {
|
||||||
const jo = value as Jo | undefined
|
const jo = value as Jo | undefined
|
||||||
return jo?.META.META_SPEC.META_CONTENEUR.TITRE
|
return jo?.META.META_SPEC.META_CONTENEUR.TITRE
|
||||||
|
@ -160,7 +174,8 @@ export function summarizeLegalObject(
|
||||||
return textelr?.META.META_COMMUN.ID
|
return textelr?.META.META_COMMUN.ID
|
||||||
}
|
}
|
||||||
case "versions":
|
case "versions":
|
||||||
return `/eli/versions/TODO`
|
const versionsWrapper = value as VersionsWrapper | undefined
|
||||||
|
return versionsWrapper?.eli
|
||||||
default:
|
default:
|
||||||
assertNeverLegalObjectType(type)
|
assertNeverLegalObjectType(type)
|
||||||
}
|
}
|
||||||
|
@ -260,3 +275,17 @@ export const summarizeTexteVersionProperties: Summarizer = (access, value) => {
|
||||||
|
|
||||||
return undefined
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -30,12 +30,12 @@
|
||||||
{
|
{
|
||||||
items: [
|
items: [
|
||||||
{ href: "/article", label: "ARTICLE" },
|
{ href: "/article", label: "ARTICLE" },
|
||||||
// { href: "/eli/ids", label: "ID" },
|
{ href: "/id", label: "ID" },
|
||||||
{ href: "/jo", label: "JO" },
|
{ href: "/jo", label: "JO" },
|
||||||
{ href: "/section_ta", label: "SECTION_TA" },
|
{ href: "/section_ta", label: "SECTION_TA" },
|
||||||
{ href: "/texte_version", label: "TEXTE_VERSION" },
|
{ href: "/texte_version", label: "TEXTE_VERSION" },
|
||||||
{ href: "/textelr", label: "TEXTELR" },
|
{ href: "/textelr", label: "TEXTELR" },
|
||||||
// { href: "/eli/versions", label: "VERSIONS" },
|
{ href: "/versions", label: "VERSIONS" },
|
||||||
],
|
],
|
||||||
label: "Données",
|
label: "Données",
|
||||||
},
|
},
|
||||||
|
|
39
src/routes/id/[...eli].svelte
Normal file
39
src/routes/id/[...eli].svelte
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { TreeView, SummaryView } from "augmented-data-viewer"
|
||||||
|
|
||||||
|
import ErrorAlert from "$lib/components/errors/ErrorAlert.svelte"
|
||||||
|
import type { IdWrapper } from "$lib/data"
|
||||||
|
import {
|
||||||
|
summarizeIdWrapperProperties,
|
||||||
|
summarizeLegalObject,
|
||||||
|
} from "$lib/summaries"
|
||||||
|
|
||||||
|
export let error: unknown
|
||||||
|
let idWrapper: IdWrapper
|
||||||
|
export { idWrapper as id }
|
||||||
|
|
||||||
|
const summary = summarizeLegalObject({ key: "id" }, "id", idWrapper)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="prose my-6 max-w-full">
|
||||||
|
<h2>ID</h2>
|
||||||
|
{#if summary !== undefined}
|
||||||
|
<h1>
|
||||||
|
<SummaryView {summary} />
|
||||||
|
</h1>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{#if error != null}
|
||||||
|
<ErrorAlert {error} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if error == null}
|
||||||
|
<TreeView
|
||||||
|
access={{ key: "article" }}
|
||||||
|
frame={false}
|
||||||
|
open
|
||||||
|
summarize={summarizeIdWrapperProperties}
|
||||||
|
value={idWrapper}
|
||||||
|
/>
|
||||||
|
{/if}
|
22
src/routes/id/[...eli].ts
Normal file
22
src/routes/id/[...eli].ts
Normal file
|
@ -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 },
|
||||||
|
}
|
||||||
|
}
|
68
src/routes/id/index.svelte
Normal file
68
src/routes/id/index.svelte
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<script lang="ts">
|
||||||
|
// import Icon from "@iconify/svelte"
|
||||||
|
// import searchIcon from "@iconify-icons/codicon/search"
|
||||||
|
import { TreeView } from "augmented-data-viewer"
|
||||||
|
|
||||||
|
// import { page } from "$app/stores"
|
||||||
|
import ErrorAlert from "$lib/components/errors/ErrorAlert.svelte"
|
||||||
|
import Pagination from "$lib/components/Pagination.svelte"
|
||||||
|
import type { IdWrapper } from "$lib/data"
|
||||||
|
import { summarizeIdWrapperProperties } from "$lib/summaries"
|
||||||
|
|
||||||
|
let idsWrapper: IdWrapper[]
|
||||||
|
export { idsWrapper as id }
|
||||||
|
export let error: unknown
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="prose my-6 max-w-full">
|
||||||
|
<h1>ID</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- <form action={$page.url.pathname} class="mx-auto max-w-sm" method="get">
|
||||||
|
<div class="form-control">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
name="q"
|
||||||
|
type="search"
|
||||||
|
bind:value={q}
|
||||||
|
/>
|
||||||
|
<button class="btn btn-square" type="submit">
|
||||||
|
<Icon icon={searchIcon} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label">
|
||||||
|
<span class="label-text">Législature</span>
|
||||||
|
<select
|
||||||
|
class="select select-bordered"
|
||||||
|
name="legislature"
|
||||||
|
bind:value={legislature}
|
||||||
|
>
|
||||||
|
<option value="">Toutes</option>
|
||||||
|
{#each Object.entries(Legislature) as [key, value]}
|
||||||
|
{#if value !== "*"}
|
||||||
|
<option {value}>{key}</option>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form> -->
|
||||||
|
|
||||||
|
{#if error != null}
|
||||||
|
<ErrorAlert {error} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if error == null}
|
||||||
|
<TreeView
|
||||||
|
access={{ key: "id" }}
|
||||||
|
frame={false}
|
||||||
|
open
|
||||||
|
summarize={summarizeIdWrapperProperties}
|
||||||
|
value={idsWrapper}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Pagination currentPageCount={idsWrapper.length ?? 0} />
|
||||||
|
{/if}
|
70
src/routes/id/index.ts
Normal file
70
src/routes/id/index.ts
Normal file
|
@ -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<IdWrapper[]>`
|
||||||
|
SELECT eli, id FROM id
|
||||||
|
OFFSET ${offset}
|
||||||
|
LIMIT ${limit}
|
||||||
|
`
|
||||||
|
return {
|
||||||
|
headers: { "Access-Control-Allow-Origin": "*" },
|
||||||
|
body: { id: idsWrapper as unknown as JSONObject[] },
|
||||||
|
}
|
||||||
|
}
|
43
src/routes/versions/[...eli].svelte
Normal file
43
src/routes/versions/[...eli].svelte
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { TreeView, SummaryView } from "augmented-data-viewer"
|
||||||
|
|
||||||
|
import ErrorAlert from "$lib/components/errors/ErrorAlert.svelte"
|
||||||
|
import type { VersionsWrapper } from "$lib/data"
|
||||||
|
import {
|
||||||
|
summarizeVersionsWrapperProperties,
|
||||||
|
summarizeLegalObject,
|
||||||
|
} from "$lib/summaries"
|
||||||
|
|
||||||
|
export let error: unknown
|
||||||
|
let versionsWrapper: VersionsWrapper
|
||||||
|
export { versionsWrapper as versions }
|
||||||
|
|
||||||
|
const summary = summarizeLegalObject(
|
||||||
|
{ key: "versions" },
|
||||||
|
"versions",
|
||||||
|
versionsWrapper,
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="prose my-6 max-w-full">
|
||||||
|
<h2>VERSIONS</h2>
|
||||||
|
{#if summary !== undefined}
|
||||||
|
<h1>
|
||||||
|
<SummaryView {summary} />
|
||||||
|
</h1>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{#if error != null}
|
||||||
|
<ErrorAlert {error} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if error == null}
|
||||||
|
<TreeView
|
||||||
|
access={{ key: "article" }}
|
||||||
|
frame={false}
|
||||||
|
open
|
||||||
|
summarize={summarizeVersionsWrapperProperties}
|
||||||
|
value={versionsWrapper}
|
||||||
|
/>
|
||||||
|
{/if}
|
22
src/routes/versions/[...eli].ts
Normal file
22
src/routes/versions/[...eli].ts
Normal file
|
@ -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 },
|
||||||
|
}
|
||||||
|
}
|
68
src/routes/versions/index.svelte
Normal file
68
src/routes/versions/index.svelte
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<script lang="ts">
|
||||||
|
// import Icon from "@iconify/svelte"
|
||||||
|
// import searchIcon from "@iconify-icons/codicon/search"
|
||||||
|
import { TreeView } from "augmented-data-viewer"
|
||||||
|
|
||||||
|
// import { page } from "$app/stores"
|
||||||
|
import ErrorAlert from "$lib/components/errors/ErrorAlert.svelte"
|
||||||
|
import Pagination from "$lib/components/Pagination.svelte"
|
||||||
|
import type { VersionsWrapper } from "$lib/data"
|
||||||
|
import { summarizeVersionsWrapperProperties } from "$lib/summaries"
|
||||||
|
|
||||||
|
let versionsWrapper: VersionsWrapper[]
|
||||||
|
export { versionsWrapper as versions }
|
||||||
|
export let error: unknown
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class="prose my-6 max-w-full">
|
||||||
|
<h1>VERSIONS</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- <form action={$page.url.pathname} class="mx-auto max-w-sm" method="get">
|
||||||
|
<div class="form-control">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
name="q"
|
||||||
|
type="search"
|
||||||
|
bind:value={q}
|
||||||
|
/>
|
||||||
|
<button class="btn btn-square" type="submit">
|
||||||
|
<Icon icon={searchIcon} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label">
|
||||||
|
<span class="label-text">Législature</span>
|
||||||
|
<select
|
||||||
|
class="select select-bordered"
|
||||||
|
name="legislature"
|
||||||
|
bind:value={legislature}
|
||||||
|
>
|
||||||
|
<option value="">Toutes</option>
|
||||||
|
{#each Object.entries(Legislature) as [key, value]}
|
||||||
|
{#if value !== "*"}
|
||||||
|
<option {value}>{key}</option>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form> -->
|
||||||
|
|
||||||
|
{#if error != null}
|
||||||
|
<ErrorAlert {error} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if error == null}
|
||||||
|
<TreeView
|
||||||
|
access={{ key: "versions" }}
|
||||||
|
frame={false}
|
||||||
|
open
|
||||||
|
summarize={summarizeVersionsWrapperProperties}
|
||||||
|
value={versionsWrapper}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Pagination currentPageCount={versionsWrapper.length ?? 0} />
|
||||||
|
{/if}
|
70
src/routes/versions/index.ts
Normal file
70
src/routes/versions/index.ts
Normal file
|
@ -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<VersionsWrapper[]>`
|
||||||
|
SELECT eli, id, data FROM versions
|
||||||
|
OFFSET ${offset}
|
||||||
|
LIMIT ${limit}
|
||||||
|
`
|
||||||
|
return {
|
||||||
|
headers: { "Access-Control-Allow-Origin": "*" },
|
||||||
|
body: { versions: versionsWrapper as unknown as JSONObject[] },
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue