From ece12394dcfcdee519ded82a3fd0847620e8401b Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 11:18:52 -0400 Subject: [PATCH 01/41] eng-1837-add-public-status-in-db --- .../20260605142437_public_resource_access.sql | 19 +++++++++++++++++++ .../database/supabase/schemas/account.sql | 5 +++++ .../database/supabase/schemas/concept.sql | 1 + .../database/supabase/schemas/content.sql | 3 +++ 4 files changed, 28 insertions(+) create mode 100644 packages/database/supabase/migrations/20260605142437_public_resource_access.sql diff --git a/packages/database/supabase/migrations/20260605142437_public_resource_access.sql b/packages/database/supabase/migrations/20260605142437_public_resource_access.sql new file mode 100644 index 000000000..b88a5e171 --- /dev/null +++ b/packages/database/supabase/migrations/20260605142437_public_resource_access.sql @@ -0,0 +1,19 @@ +CREATE OR REPLACE FUNCTION public.my_user_accounts() RETURNS SETOF UUID +STABLE SECURITY DEFINER +SET search_path = '' +LANGUAGE sql +AS $$ + SELECT auth.uid() WHERE auth.uid() IS NOT NULL UNION + SELECT '00000000-0000-0000-0000-000000000000'::uuid UNION + SELECT group_id FROM public.group_membership + WHERE member_id = auth.uid(); +$$; + + +GRANT SELECT ON TABLE public."ResourceAccess" TO anon; +GRANT SELECT ON TABLE public."Document" TO anon; +GRANT SELECT ON TABLE public."Content" TO anon; +GRANT SELECT ON TABLE public."Concept" TO anon; + +INSERT INTO auth.users (instance_id, id, aud, role, created_at, updated_at, is_super_admin, is_anonymous) +VALUES ('00000000-0000-0000-0000-000000000000', '00000000-0000-0000-0000-000000000000', 'anon', 'anon', now(), now(), false, true); diff --git a/packages/database/supabase/schemas/account.sql b/packages/database/supabase/schemas/account.sql index 73b59baf4..a10a52947 100644 --- a/packages/database/supabase/schemas/account.sql +++ b/packages/database/supabase/schemas/account.sql @@ -1,3 +1,7 @@ +-- Anonymous pseudo-user +INSERT INTO auth.users (instance_id, id, aud, role, created_at, updated_at, is_super_admin, is_anonymous) +VALUES ('00000000-0000-0000-0000-000000000000', '00000000-0000-0000-0000-000000000000', 'anon', 'anon', now(), now(), false, true); + CREATE TYPE public."AgentType" AS ENUM ( 'person', 'organization', @@ -219,6 +223,7 @@ SET search_path = '' LANGUAGE sql AS $$ SELECT auth.uid() WHERE auth.uid() IS NOT NULL UNION + SELECT '00000000-0000-0000-0000-000000000000'::uuid UNION SELECT group_id FROM public.group_membership WHERE member_id = auth.uid(); $$; diff --git a/packages/database/supabase/schemas/concept.sql b/packages/database/supabase/schemas/concept.sql index ade37cdbf..c0bcd932e 100644 --- a/packages/database/supabase/schemas/concept.sql +++ b/packages/database/supabase/schemas/concept.sql @@ -106,6 +106,7 @@ ADD CONSTRAINT "Concept_space_id_fkey" FOREIGN KEY ( REVOKE ALL ON TABLE public."Concept" FROM anon; +GRANT SELECT ON TABLE public."Concept" TO anon; GRANT ALL ON TABLE public."Concept" TO authenticated; GRANT ALL ON TABLE public."Concept" TO service_role; diff --git a/packages/database/supabase/schemas/content.sql b/packages/database/supabase/schemas/content.sql index 98f18f179..ae75b41c4 100644 --- a/packages/database/supabase/schemas/content.sql +++ b/packages/database/supabase/schemas/content.sql @@ -183,12 +183,15 @@ CREATE INDEX resource_access_content_local_id_idx ON public."ResourceAccess" (so GRANT ALL ON TABLE public."ResourceAccess" TO authenticated; GRANT ALL ON TABLE public."ResourceAccess" TO service_role; REVOKE ALL ON TABLE public."ResourceAccess" FROM anon; +GRANT SELECT ON TABLE public."ResourceAccess" TO anon; REVOKE ALL ON TABLE public."Document" FROM anon; +GRANT SELECT ON TABLE public."Document" TO anon; GRANT ALL ON TABLE public."Document" TO authenticated; GRANT ALL ON TABLE public."Document" TO service_role; REVOKE ALL ON TABLE public."Content" FROM anon; +GRANT SELECT ON TABLE public."Content" TO anon; GRANT ALL ON TABLE public."Content" TO authenticated; GRANT ALL ON TABLE public."Content" TO service_role; From f49e0b6b26304bfcb4a3ed88fa222a1b1b23f028 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sun, 31 May 2026 21:15:02 -0400 Subject: [PATCH 02/41] Routes, with minimalist conversion --- .../content/[space_id]/[resource_id]/route.ts | 175 +++++++++++++++ .../data/[space_id]/[resource_id]/route.ts | 207 ++++++++++++++++++ apps/website/app/api/data/[space_id]/route.ts | 135 ++++++++++++ apps/website/app/utils/conversion/convert.ts | 37 ++++ apps/website/app/utils/conversion/jsonld.ts | 131 +++++++++++ apps/website/package.json | 10 +- pnpm-lock.yaml | 108 ++++----- 7 files changed, 729 insertions(+), 74 deletions(-) create mode 100644 apps/website/app/api/content/[space_id]/[resource_id]/route.ts create mode 100644 apps/website/app/api/data/[space_id]/[resource_id]/route.ts create mode 100644 apps/website/app/api/data/[space_id]/route.ts create mode 100644 apps/website/app/utils/conversion/convert.ts create mode 100644 apps/website/app/utils/conversion/jsonld.ts diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts new file mode 100644 index 000000000..9990900df --- /dev/null +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -0,0 +1,175 @@ +import { NextResponse, NextRequest } from "next/server"; +import { createClient } from "~/utils/supabase/server"; +import { asPostgrestFailure } from "@repo/database/lib/contextFunctions"; +import { + defaultOptionsHandler, + createApiResponse, +} from "~/utils/supabase/apiUtils"; +import { asJsonLD } from "~/utils/conversion/jsonld"; +import { Tables } from "@repo/database/dbTypes"; +import { convert, MIMETYPES, type DocType } from "~/utils/conversion/convert"; + +type Concept = Tables<"Concept">; +type Content = Tables<"Content">; +type Space = Tables<"Space">; +type PlatformAccount = Tables<"PlatformAccount">; + +export type SegmentDataType = { params: Promise> }; + +export const GET = async ( + request: NextRequest, + segmentData: SegmentDataType, +): Promise => { + const { space_id, resource_id } = await segmentData.params; + let targetFormat: DocType = (request.nextUrl.searchParams.get("format") ?? + "html") as DocType; + if (MIMETYPES[targetFormat] === undefined) { + targetFormat = "html"; + } + const targetMimetype = MIMETYPES[targetFormat]; + if (!targetMimetype) { + return createApiResponse( + request, + asPostgrestFailure("Unsupported format", "404", 404), + ); + } + const includeData = + targetFormat === "html" && + request.nextUrl.searchParams.get("data") !== "false"; + const spaceIdN = Number.parseInt(space_id || "NaN"); + if (isNaN(spaceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`${space_id} is not a number`, "type"), + ); + } + const resourceIdN = Number.parseInt(resource_id || "NaN"); + if (isNaN(resourceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`${resource_id} is not a number`, "type"), + ); + } + const supabase = await createClient(); + const spaceResponse = await supabase + .from("Space") + .select() + .eq("id", spaceIdN) + .maybeSingle(); + if (spaceResponse.error) { + return createApiResponse(request, spaceResponse); + } + if (!spaceResponse.data) { + // consideration: We may not see it because we don't have access, + // so it would be worth re-fetching as superuser to see if I should redirect to login. + return createApiResponse( + request, + asPostgrestFailure("Space not found", "401", 401), + ); + } + const space: Space = spaceResponse.data; + const conceptResponse = await supabase + .from("Concept") + .select() + .eq("id", resourceIdN) + .maybeSingle(); + if (conceptResponse.error) { + return createApiResponse(request, conceptResponse); + } + const concept = conceptResponse.data; + if (!concept) { + return createApiResponse( + request, + asPostgrestFailure("Resource not found", "401", 401), + ); + } + const contentResponse = await supabase + .from("Content") + .select() + .eq("source_local_id", concept.source_local_id!); + if (contentResponse.error) { + return createApiResponse(request, conceptResponse); + } + const contents: Content[] = contentResponse.data; + const requestUrlParts = request.url.split("/"); + const baseUrl = requestUrlParts + .slice(0, requestUrlParts.length - 1) + .join("/"); + const fullContentsArray = contents.filter((c) => c.variant === "full"); + const fullContents = fullContentsArray.length + ? fullContentsArray[0] + : undefined; + const titleArray = contents.filter((c) => c.variant === "direct"); + const title = titleArray.length ? titleArray[0] : undefined; + + if (!fullContents) { + return createApiResponse( + request, + asPostgrestFailure("Resource not found", "401", 401), + ); + } + + const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); + // await initRT(rootUrl); + const source: DocType | undefined = + space.platform === "Obsidian" + ? "obsidian" + : space.platform === "Roam" + ? "roam" + : undefined; + let text = + source && source !== targetFormat + ? await convert(fullContents.text, source, targetFormat) + : fullContents.text; + if (includeData) { + const isSchema = concept.is_schema; + let schema: Concept | undefined = undefined; + if (!isSchema && concept.schema_id) { + const schemaResponse = await supabase + .from("Concept") + .select() + .eq("id", concept.schema_id) + .maybeSingle(); + if (schemaResponse.error) { + return createApiResponse(request, schemaResponse); + } + if (!schemaResponse.data) { + return createApiResponse( + request, + asPostgrestFailure("Resource schema not found", "401", 401), + ); + } + schema = schemaResponse.data; + } + + const authorId = concept.author_id ?? (contents ?? [{}])[0]?.author_id; + let author: PlatformAccount | undefined = undefined; + if (authorId) { + const authorResponse = await supabase + .from("PlatformAccount") + .select() + .eq("id", authorId) + .maybeSingle(); + if (authorResponse.data) author = authorResponse.data; + } + + const jsonLdData = await asJsonLD({ + space, + concept, + baseUrl, + title, + schema, + content: undefined, + author, + targetFormat, + wrap: true, + }); + text = `
\n\n${text}\n
`; + } + + return new NextResponse(text, { + headers: { "Content-Type": targetMimetype }, + }); +}; + +export const OPTIONS = defaultOptionsHandler; diff --git a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts new file mode 100644 index 000000000..c80df727a --- /dev/null +++ b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts @@ -0,0 +1,207 @@ +import { NextResponse, NextRequest } from "next/server"; +import { createClient } from "~/utils/supabase/server"; +import { asPostgrestFailure } from "@repo/database/lib/contextFunctions"; +import { + defaultOptionsHandler, + createApiResponse, +} from "~/utils/supabase/apiUtils"; +import { asJsonLD, wrapJsonLd } from "~/utils/conversion/jsonld"; +import { Tables } from "@repo/database/dbTypes"; +import { PostgrestMaybeSingleResponse } from "@supabase/supabase-js"; +import { MIMETYPES, type DocType } from "~/utils/conversion/convert"; + +type Concept = Tables<"Concept">; +type Content = Tables<"Content">; +type Space = Tables<"Space">; +type PlatformAccount = Tables<"PlatformAccount">; + +export type SegmentDataType = { params: Promise> }; + +export const GET = async ( + request: NextRequest, + segmentData: SegmentDataType, +): Promise => { + const { space_id, resource_id } = await segmentData.params; + let targetFormat = (request.nextUrl.searchParams.get("format") ?? "html") as + | DocType + | "none"; + if (targetFormat !== "none" && MIMETYPES[targetFormat] === undefined) { + targetFormat = "html"; + } + const withContext = request.nextUrl.searchParams.get("context"); + const withSchema = request.nextUrl.searchParams.get("schema"); + const spaceIdN = Number.parseInt(space_id || "NaN"); + if (isNaN(spaceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`${space_id} is not a number`, "type"), + ); + } + const resourceIdN = Number.parseInt(resource_id || "NaN"); + if (isNaN(resourceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`${resource_id} is not a number`, "type"), + ); + } + const supabase = await createClient(); + const spaceResponse = await supabase + .from("Space") + .select() + .eq("id", spaceIdN) + .maybeSingle(); + if (spaceResponse.error) { + return createApiResponse(request, spaceResponse); + } + if (!spaceResponse.data) { + // consideration: We may not see it because we don't have access, + // so it would be worth re-fetching as superuser to see if I should redirect to login. + return createApiResponse( + request, + asPostgrestFailure("Space not found", "401", 401), + ); + } + const space: Space = spaceResponse.data; + const conceptResponse = await supabase + .from("Concept") + .select() + .eq("id", resourceIdN) + .maybeSingle(); + if (conceptResponse.error) { + return createApiResponse(request, conceptResponse); + } + const concept = conceptResponse.data; + if (!concept) { + return createApiResponse( + request, + asPostgrestFailure("Resource not found", "401", 401), + ); + } + const contentResponse = await supabase + .from("Content") + .select() + .eq("source_local_id", concept.source_local_id!); + if (contentResponse.error) { + return createApiResponse(request, conceptResponse); + } + const contents: Content[] = contentResponse.data; + const fullContentsArray = contents.filter((c) => c.variant === "full"); + const fullContents = fullContentsArray.length + ? fullContentsArray[0] + : undefined; + const titleArray = contents.filter((c) => c.variant === "direct"); + const title = titleArray.length ? titleArray[0] : undefined; + + const requestUrlParts = request.url.split("/"); + const baseUrl = requestUrlParts + .slice(0, requestUrlParts.length - 1) + .join("/"); + const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); + const pageUrl = `${rootUrl}/api/content/${baseUrl.split("/")[5]}/${concept.id}#`; + let schemas: Record = {}; + let authors: Record = {}; + let relations: Concept[] = []; + let schemaIds = new Set(); + if (withContext) { + const relationsResult = (await supabase + .from("Concept") + .select("relations:concept_in_relations!inner(*)") + .eq("id", concept.id) + .maybeSingle()) as PostgrestMaybeSingleResponse<{ relations: Concept[] }>; + if (relationsResult.data?.relations?.length) { + relations = relationsResult.data.relations; + if (withSchema) + schemaIds = new Set( + relations.map((c) => c.schema_id).filter((id) => id !== null), + ); + } + } + if (concept.schema_id) schemaIds.add(concept.schema_id); + if (schemaIds.size > 0) { + const schemaResponse = await supabase + .from("Concept") + .select() + .in("id", [...schemaIds]); + if (schemaResponse.error) { + return createApiResponse(request, schemaResponse); + } + if (!schemaResponse.data) { + return createApiResponse( + request, + asPostgrestFailure("Resource schema not found", "401", 401), + ); + } + schemas = Object.fromEntries(schemaResponse.data.map((s) => [s.id, s])); + } + const authorIds = new Set([ + ...relations.map((r) => r.author_id).filter((id) => id !== null), + ...Object.values(schemas) + .map((s) => s.author_id) + .filter((id) => id !== null), + ]); + if (concept.author_id) authorIds.add(concept.author_id); + if (authorIds.size > 0) { + const authorsResponse = await supabase + .from("PlatformAccount") + .select() + .in("id", [...authorIds]); + if (authorsResponse.error) { + return createApiResponse(request, authorsResponse); + } + if (!authorsResponse.data) { + return createApiResponse( + request, + asPostgrestFailure("Resource schema not found", "401", 401), + ); + } + authors = Object.fromEntries(authorsResponse.data.map((a) => [a.id, a])); + } + + const relationsJLD = withContext + ? await Promise.all( + relations.map((c) => + asJsonLD({ + space, + concept: c, + baseUrl, + schema: c.schema_id ? schemas[c.schema_id] : undefined, + author: c.author_id ? authors[c.author_id] : undefined, + }), + ), + ) + : []; + const schemasJLD = withSchema + ? await Promise.all( + Object.values(schemas).map((c) => + asJsonLD({ + space, + concept: c, + baseUrl, + author: c.author_id ? authors[c.author_id] : undefined, + }), + ), + ) + : []; + + const baseJLDData = await asJsonLD({ + space, + concept, + baseUrl, + title, + schema: concept.schema_id ? schemas[concept.schema_id] : undefined, + content: targetFormat === "none" ? undefined : fullContents, + author: concept.author_id ? authors[concept.author_id] : undefined, + targetFormat: targetFormat === "none" ? undefined : targetFormat, + }); + + const jsonLdData = + relationsJLD.length > 0 || schemasJLD.length > 0 + ? [baseJLDData, ...relationsJLD, ...schemasJLD] + : baseJLDData; + return NextResponse.json(wrapJsonLd(jsonLdData, baseUrl, pageUrl), { + status: 200, + headers: { "Content-Type": "application/ld+json" }, + }); +}; + +export const OPTIONS = defaultOptionsHandler; diff --git a/apps/website/app/api/data/[space_id]/route.ts b/apps/website/app/api/data/[space_id]/route.ts new file mode 100644 index 000000000..8eae33384 --- /dev/null +++ b/apps/website/app/api/data/[space_id]/route.ts @@ -0,0 +1,135 @@ +import { NextResponse, NextRequest } from "next/server"; +import { createClient } from "~/utils/supabase/server"; +import { asPostgrestFailure } from "@repo/database/lib/contextFunctions"; +import { + defaultOptionsHandler, + createApiResponse, +} from "~/utils/supabase/apiUtils"; +import { Tables } from "@repo/database/dbTypes"; + +type Space = Tables<"Space">; + +export type SegmentDataType = { params: Promise> }; + +export const GET = async ( + request: NextRequest, + segmentData: SegmentDataType, +): Promise => { + const { space_id } = await segmentData.params; + const afterParam = request.nextUrl.searchParams.get("after"); + let after: Date | undefined = undefined; + if (afterParam) + try { + after = new Date(afterParam); + } catch (error) { + return createApiResponse( + request, + asPostgrestFailure(`after is not a date`, "type"), + ); + } + const spaceIdN = Number.parseInt(space_id || "NaN"); + if (isNaN(spaceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`space_id is not a number`, "type"), + ); + } + const supabase = await createClient(); + const spaceResponse = await supabase + .from("Space") + .select() + .eq("id", spaceIdN) + .maybeSingle(); + if (spaceResponse.error) { + return createApiResponse(request, spaceResponse); + } + if (!spaceResponse.data) { + // consideration: We may not see it because we don't have access, + // so it would be worth re-fetching as superuser to see if I should redirect to login. + return createApiResponse( + request, + asPostgrestFailure("Space not found", "401", 401), + ); + } + const space: Space = spaceResponse.data; + let conceptRequest = supabase + .from("my_concepts") + .select("id, last_modified, content_of_concept(last_modified)") + .eq("space_id", space.id); + if (after) { + const afterConceptResponse = await supabase + .from("my_concepts") + .select("source_local_id") + .eq("space_id", space.id) + .gt("last_modified", after.toISOString()); + if (afterConceptResponse.error) { + return createApiResponse(request, afterConceptResponse); + } + const localIds = new Set( + afterConceptResponse.data + .map((c) => c.source_local_id) + .filter((s) => s !== null), + ); + const afterContentResponse = await supabase + .from("my_contents") + .select("source_local_id") + .eq("space_id", space.id) + .gt("last_modified", after.toISOString()); + if (afterContentResponse.error) { + return createApiResponse(request, afterContentResponse); + } + for (const s of afterContentResponse.data) { + if (s.source_local_id !== null) localIds.add(s.source_local_id); + } + conceptRequest = conceptRequest.in("source_local_id", [...localIds]); + } + + const conceptResponse = await conceptRequest; + if (conceptResponse.error) { + return createApiResponse(request, conceptResponse); + } + const concepts = conceptResponse.data; + if (!concepts) { + return createApiResponse( + request, + asPostgrestFailure("Resources not found", "401", 401), + ); + } + const baseUrl = request.url.split("?")[0]!; + const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); + const ctxUrl = rootUrl + "/schema/context.jsonld"; + const localCtx: Record = { + sdata: baseUrl + "/", + }; + const withMaxDate: Record = {}; + // eslint-disable-next-line @typescript-eslint/naming-convention + concepts.map(({ id, last_modified, content_of_concept }) => { + if (id === null || last_modified === null) return; + if ( + content_of_concept && + content_of_concept.last_modified && + content_of_concept.last_modified > last_modified + ) + last_modified = content_of_concept.last_modified; + if (withMaxDate[id] === undefined || withMaxDate[id] < last_modified) + withMaxDate[id] = last_modified; + }); + + const data = { + "@context": [ctxUrl, localCtx], + "@id": baseUrl, + "@type": "Container", + label: space.name, + sameAs: space.url, + container_of: Object.entries(withMaxDate).map(([id, lastModified]) => ({ + "@id": `sdata:${id}`, + modified: lastModified + "Z", + })), + }; + return NextResponse.json(data, { + status: 200, + headers: { "Content-Type": "application/ld+json" }, + }); +}; + +export const OPTIONS = defaultOptionsHandler; diff --git a/apps/website/app/utils/conversion/convert.ts b/apps/website/app/utils/conversion/convert.ts new file mode 100644 index 000000000..a280d0645 --- /dev/null +++ b/apps/website/app/utils/conversion/convert.ts @@ -0,0 +1,37 @@ +import showdown from "showdown"; + +export type DocType = "obsidian" | "roam" | "html" | "markdown"; + +export const MIMETYPES: Record = { + obsidian: "text/x-obsidian", + markdown: "text/markdown", + roam: "application/x-roam+json", + html: "text/html", +}; + +const markdownTypes: Set = new Set(["obsidian", "markdown"]); + +let converter: showdown.Converter | undefined; + +const init = (): showdown.Converter => { + if (converter === undefined) converter = new showdown.Converter(); + return converter; +}; + +export const convert = ( + text: string, + source: DocType, + dest: DocType, +): string => { + if (source === dest) return text; + // punt details + if (markdownTypes.has(source) && markdownTypes.has(dest)) return text; + converter = init(); + if (markdownTypes.has(source) && dest === "html") { + return converter.makeHtml(text); + } + if (markdownTypes.has(dest) && source === "html") { + return converter.makeMarkdown(text); + } + throw new Error("Types not handled"); +}; diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts new file mode 100644 index 000000000..77b320811 --- /dev/null +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -0,0 +1,131 @@ +import { Tables, Json } from "@repo/database/dbTypes"; +import { convert, MIMETYPES, type DocType } from "~/utils/conversion/convert"; + +type Concept = Tables<"Concept">; +type Content = Tables<"Content">; +type Space = Tables<"Space">; +type PlatformAccount = Tables<"PlatformAccount">; + +export const asJsonLD = async ({ + space, + concept, + baseUrl, + title, + schema, + content, + author, + targetFormat, + wrap, +}: { + space: Space; + concept: Concept; + baseUrl: string; + title?: Content; + schema?: Concept; + content?: Content; + author?: PlatformAccount; + targetFormat?: DocType; + wrap?: boolean; +}): Promise> => { + targetFormat ??= "html"; + if (MIMETYPES[targetFormat] === undefined) { + targetFormat = "html"; + } + const schemaUrl = concept.schema_id + ? "sdata:" + concept.schema_id + : concept.arity === 2 + ? "RelationDef" + : "NodeSchema"; + + let extraData: Record = {}; + if ( + schema && + schema.arity && + schema.literal_content !== null && + typeof schema.literal_content === "object" && + !Array.isArray(schema.literal_content) && + concept.reference_content !== null && + typeof concept.reference_content === "object" && + !Array.isArray(concept.reference_content) && + Array.isArray(schema.literal_content.roles) + ) { + for (const role of schema.literal_content.roles) { + if (typeof role !== "string") continue; + const val = concept.reference_content[role]; + if (val && typeof val === "number") extraData[role] = `sdata:${val}`; + } + } + // Explicit punning + if (concept.is_schema && concept.arity === 2) { + extraData["subClassOf"] = [ + "dgb:RelationInstance", + { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:" + concept.id, + }, + ]; + } + const titleText = title?.text ?? concept.name; + if (titleText) { + extraData[concept.is_schema ? "label" : "title"] = titleText; + } + let pageUrl: string | undefined = undefined; + if (content) { + const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); + pageUrl = `${rootUrl}/api/content/${baseUrl.split("/")[5]}/${concept.id}#`; + const source: DocType | undefined = + space.platform === "Obsidian" ? "obsidian" : "markdown"; + // punt roam-json + const contentText = source && convert(content.text, source, targetFormat); + extraData["description"] = { + "@id": "page:content", + format: MIMETYPES[targetFormat], + content: contentText, + }; + } + + if (author) { + extraData.creator = author.name; + // TODO: make into an object? + } + let lastModified = concept.last_modified; + if (content && content.last_modified > lastModified) + lastModified = content.last_modified; + if (title && title.last_modified > lastModified) + lastModified = title.last_modified; + extraData = { + "@id": "sdata:" + concept.id, + "@type": schemaUrl, + modified: lastModified + "Z", + created: concept.created + "Z", + ...extraData, + }; + return wrap ? wrapJsonLd(extraData, baseUrl, pageUrl) : extraData; +}; + +export const wrapJsonLd = ( + json: Json[] | Record, + baseUrl: string, + pageUrl?: string, +): Record => { + const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); + const ctxUrl = rootUrl + "/schema/context.jsonld"; + const localCtx: Record = { + sdata: baseUrl + "/", + }; + if (pageUrl) localCtx["page"] = pageUrl; + if (Array.isArray(json)) { + return { + "@context": [ctxUrl, localCtx], + "@id": baseUrl, + "@graph": json, + }; + } else if (typeof json === "object") { + return { + "@context": [ctxUrl, localCtx], + has_container: baseUrl, + ...json, + }; + } else throw new Error("Wrong input type"); +}; diff --git a/apps/website/package.json b/apps/website/package.json index 38247ae30..e6ed03cf0 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -18,9 +18,9 @@ "dependencies": { "@repo/database": "workspace:*", "@repo/ui": "workspace:*", + "@supabase/auth-js": "catalog:", "@supabase/ssr": "catalog:", "@supabase/supabase-js": "catalog:", - "@supabase/auth-js": "catalog:", "clsx": "^2.1.1", "gray-matter": "^4.0.3", "lucide-react": "^0.540.0", @@ -33,13 +33,12 @@ "react": "catalog:", "react-dom": "catalog:", "resend": "^4.0.1", + "showdown": "^2.1.0", "sonner": "^2.0.7", "zod": "^3.24.1" }, "devDependencies": { "@repo/eslint-config": "workspace:*", - "dotenv": "^16.0.0", - "vitest": "^4.0.0", "@repo/tailwind-config": "workspace:*", "@repo/types": "workspace:*", "@repo/typescript-config": "workspace:*", @@ -47,11 +46,14 @@ "@types/node": "^20", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "@types/showdown": "^2.0.6", "autoprefixer": "^10.4.20", + "dotenv": "^16.0.0", "eslint": "catalog:", "pagefind": "^1.4.0", "postcss": "^8.4.49", "tailwindcss": "^3.4.16", - "typescript": "^5" + "typescript": "^5", + "vitest": "^4.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a9285629..6a11947e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,7 +343,7 @@ importers: version: 3.5.2(react@18.2.0) roamjs-components: specifier: 0.88.1 - version: 0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51) + version: 0.88.1(6fc269b31b2749e4d441ca378d1de710) tldraw: specifier: 2.4.6 version: 2.4.6(patch_hash=56e196052862c9a58a11b43e5e121384cd1d6548416afa0f16e9fbfbf0e4080d)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -395,7 +395,7 @@ importers: version: 0.17.14 tailwindcss: specifier: ^3.4.17 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) tsx: specifier: ^4.19.2 version: 4.20.5 @@ -484,6 +484,9 @@ importers: resend: specifier: ^4.0.1 version: 4.8.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + showdown: + specifier: ^2.1.0 + version: 2.1.0 sonner: specifier: ^2.0.7 version: 2.0.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -515,6 +518,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.1.9(@types/react@19.1.12) + '@types/showdown': + specifier: ^2.0.6 + version: 2.0.6 autoprefixer: specifier: ^10.4.20 version: 10.4.21(postcss@8.5.6) @@ -653,10 +659,10 @@ importers: version: link:../typescript-config tailwindcss: specifier: ^3.4.1 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))) + version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) packages/types: {} @@ -5079,6 +5085,9 @@ packages: '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/showdown@2.0.6': + resolution: {integrity: sha512-pTvD/0CIeqe4x23+YJWlX2gArHa8G0J0Oh6GKaVXV7TAeickpkkZiNOgFcFcmLQ5lB/K0qBJL1FtRYltBfbGCQ==} + '@types/sizzle@2.3.10': resolution: {integrity: sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==} @@ -5822,7 +5831,7 @@ packages: basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.0, please upgrade + deprecated: Security vulnerability fixed in 5.2.1, please upgrade before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} @@ -6197,6 +6206,10 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + compress-commons@4.1.2: resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} engines: {node: '>= 10'} @@ -10376,6 +10389,10 @@ packages: shiki@3.23.0: resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + showdown@2.1.0: + resolution: {integrity: sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==} + hasBin: true + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -15831,22 +15848,22 @@ snapshots: '@rushstack/eslint-patch@1.12.0': {} - '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76)': + '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': dependencies: '@aws-sdk/client-lambda': 3.882.0 '@aws-sdk/client-s3': 3.882.0 - '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) archiver: 5.3.2 axios: 0.27.2(debug@4.4.3) debug: 4.4.3 dotenv: 16.6.1 esbuild: 0.17.14 patch-package: 6.5.1 - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) zod: 3.25.76 - '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))': + '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))': dependencies: '@playwright/test': 1.29.0 '@testing-library/react': 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -15856,7 +15873,7 @@ snapshots: debug: 4.4.3 dotenv: 16.6.1 jsdom: 20.0.3 - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -17044,6 +17061,8 @@ snapshots: '@types/semver@7.7.1': {} + '@types/showdown@2.0.6': {} + '@types/sizzle@2.3.10': {} '@types/statuses@2.0.6': {} @@ -18415,6 +18434,8 @@ snapshots: commander@8.3.0: {} + commander@9.5.0: {} + compress-commons@4.1.2: dependencies: buffer-crc32: 0.2.13 @@ -22540,14 +22561,6 @@ snapshots: postcss: 8.5.6 ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.1 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) - postcss-nested@6.2.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -23497,12 +23510,12 @@ snapshots: dependencies: glob: 7.2.3 - roamjs-components@0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51): + roamjs-components@0.88.1(6fc269b31b2749e4d441ca378d1de710): dependencies: '@blueprintjs/core': 3.50.4(patch_hash=51c5847e0a73a1be0cc263036ff64d8fada46f3b65831ed938dbca5eecf3edc0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/datetime': 3.23.14(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/select': 3.19.1(patch_hash=5b2821b0bf7274e9b64d7824648c596b9e73c61f421d699a6d4c494f12f62355)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76) + '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76) '@types/crypto-js': 4.1.1 '@types/cytoscape': 3.21.9 '@types/file-saver': 2.0.5 @@ -23899,6 +23912,10 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + showdown@2.1.0: + dependencies: + commander: 9.5.0 + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -24298,10 +24315,6 @@ snapshots: dependencies: tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))): - dependencies: - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 @@ -24329,33 +24342,6 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - postcss-nested: 6.2.0(postcss@8.5.6) - postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -24612,24 +24598,6 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.13 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - ts-toolbelt@6.15.5: {} ts-toolbelt@9.6.0: {} From dd874c46ac7c10fec3f1cefa23997a7059eddb18 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Mon, 1 Jun 2026 14:42:59 -0400 Subject: [PATCH 03/41] hackish use of schema --- .../content/[space_id]/[resource_id]/route.ts | 5 +- .../data/[space_id]/[resource_id]/route.ts | 36 ++++++------ apps/website/app/utils/conversion/jsonld.ts | 55 +++++++++++++++---- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts index 9990900df..1e755eaa2 100644 --- a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -109,7 +109,6 @@ export const GET = async ( ); } - const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); // await initRT(rootUrl); const source: DocType | undefined = space.platform === "Obsidian" @@ -119,7 +118,7 @@ export const GET = async ( : undefined; let text = source && source !== targetFormat - ? await convert(fullContents.text, source, targetFormat) + ? convert(fullContents.text, source, targetFormat) : fullContents.text; if (includeData) { const isSchema = concept.is_schema; @@ -153,7 +152,7 @@ export const GET = async ( if (authorResponse.data) author = authorResponse.data; } - const jsonLdData = await asJsonLD({ + const jsonLdData = asJsonLD({ space, concept, baseUrl, diff --git a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts index c80df727a..2215f4801 100644 --- a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts @@ -158,32 +158,28 @@ export const GET = async ( } const relationsJLD = withContext - ? await Promise.all( - relations.map((c) => - asJsonLD({ - space, - concept: c, - baseUrl, - schema: c.schema_id ? schemas[c.schema_id] : undefined, - author: c.author_id ? authors[c.author_id] : undefined, - }), - ), + ? relations.map((c) => + asJsonLD({ + space, + concept: c, + baseUrl, + schema: c.schema_id ? schemas[c.schema_id] : undefined, + author: c.author_id ? authors[c.author_id] : undefined, + }), ) : []; const schemasJLD = withSchema - ? await Promise.all( - Object.values(schemas).map((c) => - asJsonLD({ - space, - concept: c, - baseUrl, - author: c.author_id ? authors[c.author_id] : undefined, - }), - ), + ? Object.values(schemas).map((c) => + asJsonLD({ + space, + concept: c, + baseUrl, + author: c.author_id ? authors[c.author_id] : undefined, + }), ) : []; - const baseJLDData = await asJsonLD({ + const baseJLDData = asJsonLD({ space, concept, baseUrl, diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index 77b320811..2a853863f 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -6,7 +6,26 @@ type Content = Tables<"Content">; type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; -export const asJsonLD = async ({ +// This is a temporary hack +const KnownSchemaEntities: Record = { + Claim: ["dgc"], + Evidence: ["dgc"], + Question: ["dgc"], + SourceDocument: ["dgc"], + describesActivity: ["dgc"], + observationStatement: ["dgc"], + observationOriginActivity: ["dgc"], + observationBase: ["dgc"], + sourceDocument: ["dgc"], + opposes: ["dgc"], + opposedBy: ["dgc"], + supports: ["dgc"], + supportedBy: ["dgc"], + addresses: ["dgc"], + addressedBy: ["dgc"], +}; + +export const asJsonLD = ({ space, concept, baseUrl, @@ -26,12 +45,12 @@ export const asJsonLD = async ({ author?: PlatformAccount; targetFormat?: DocType; wrap?: boolean; -}): Promise> => { +}): Record => { targetFormat ??= "html"; if (MIMETYPES[targetFormat] === undefined) { targetFormat = "html"; } - const schemaUrl = concept.schema_id + let schemaUrl: string | string[] = concept.schema_id ? "sdata:" + concept.schema_id : concept.arity === 2 ? "RelationDef" @@ -55,17 +74,33 @@ export const asJsonLD = async ({ if (val && typeof val === "number") extraData[role] = `sdata:${val}`; } } - // Explicit punning - if (concept.is_schema && concept.arity === 2) { - extraData["subClassOf"] = [ - "dgb:RelationInstance", - { + if (schema !== undefined) { + const knownSchemas = KnownSchemaEntities[schema?.name ?? ""]; + if (knownSchemas !== undefined) { + schemaUrl = [ + schemaUrl, + ...knownSchemas.map((s) => `${s}:${schema.name}`), + ]; + } + } else if (concept.is_schema) { + const subClasses: Array = []; + const knownSchemas = KnownSchemaEntities[concept.name]; + // in that case we can skip the base class + if (knownSchemas !== undefined) { + subClasses.push(...knownSchemas.map((s) => `${s}:${concept.name}`)); + } + if (concept.arity === 2) { + // Explicit punning + subClasses.push("dgb:RelationInstance", { "@type": "owl:Restriction", onProperty: "rdf:predicate", hasValue: "sdata:" + concept.id, - }, - ]; + }); + } + if (subClasses.length > 1) extraData["subClassOf"] = subClasses; + else if (subClasses.length === 1) extraData["subClassOf"] = subClasses[0]!; } + const titleText = title?.text ?? concept.name; if (titleText) { extraData[concept.is_schema ? "label" : "title"] = titleText; From b2f6a98d620a713c75e8dcd31dcc9ea5daa3abb7 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Mon, 1 Jun 2026 14:43:21 -0400 Subject: [PATCH 04/41] add mira to jsonld --- apps/website/app/utils/conversion/jsonld.ts | 13 ++++++++++--- apps/website/public/schema/context.jsonld | 11 ++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index 2a853863f..b86f68762 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -8,9 +8,9 @@ type PlatformAccount = Tables<"PlatformAccount">; // This is a temporary hack const KnownSchemaEntities: Record = { - Claim: ["dgc"], - Evidence: ["dgc"], - Question: ["dgc"], + Claim: ["dgc", "mira"], + Evidence: ["dgc", "mira"], + Question: ["dgc", "mira"], SourceDocument: ["dgc"], describesActivity: ["dgc"], observationStatement: ["dgc"], @@ -23,6 +23,13 @@ const KnownSchemaEntities: Record = { supportedBy: ["dgc"], addresses: ["dgc"], addressedBy: ["dgc"], + Request: ["mira"], + Protocol: ["mira"], + follows: ["mira"], + grounds: ["mira"], + is_grounded_in: ["mira"], + request_for: ["mira"], + request_target: ["mira"], }; export const asJsonLD = ({ diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 497bf5e0f..7ac7183f7 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -8,6 +8,7 @@ "sioc": "http://rdfs.org/sioc/ns#", "dgc": "https://discoursegraphs.com/schema/dg_core#", "dgb": "https://discoursegraphs.com/schema/dg_base#", + "mira": "http://purl.org/mira-science/mira#", "predicate": "rdf:predicate", "subClassOf": "rdfs:subClassOf", "label": "rdfs:label", @@ -60,6 +61,14 @@ "supports": { "@id": "dgc:supports", "@type": "@id" }, "supportedBy": { "@id": "dgc:supportedBy", "@type": "@id" }, "addresses": { "@id": "dgc:addresses", "@type": "@id" }, - "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" } + "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" }, + + "Request": "mira:Request", + "Protocol": "mira:Protocol", + "follows": { "@id": "mira:follows", "@type": "@id" }, + "grounds": { "@id": "mira:grounds", "@type": "@id" }, + "is_grounded_in": { "@id": "mira:is_grounded_in", "@type": "@id" }, + "request_for": { "@id": "mira:request_for", "@type": "@id" }, + "request_target": { "@id": "mira:request_target", "@type": "@id" } } } From 3bafdb0bd35850df143fc7f2ade33247854ffa34 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Wed, 3 Jun 2026 13:02:05 -0400 Subject: [PATCH 05/41] LDO tooling --- apps/website/package.json | 8 + pnpm-lock.yaml | 1651 ++++++++++++++++++++++++++++++++++++- 2 files changed, 1637 insertions(+), 22 deletions(-) diff --git a/apps/website/package.json b/apps/website/package.json index e6ed03cf0..f4fca80f3 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -8,6 +8,7 @@ "dev": "next dev", "build": "next build && node ./scripts/build-docs-search-index.mjs", "build:search": "node ./scripts/build-docs-search-index.mjs", + "build:ldo": "ldo build --input ./app/utils/conversion/shapes --output ./app/utils/conversion/ldo", "start": "next start", "lint": "eslint .", "lint:fix": "eslint . --fix", @@ -16,6 +17,8 @@ "test:integration:nodb": "vitest run --config vitest.integration.config.ts --tags-filter '!database'" }, "dependencies": { + "@ldo/ldo": "1.0.0-alpha.51", + "@ldo/rdf-utils": "1.0.0-alpha.51", "@repo/database": "workspace:*", "@repo/ui": "workspace:*", "@supabase/auth-js": "catalog:", @@ -23,6 +26,7 @@ "@supabase/supabase-js": "catalog:", "clsx": "^2.1.1", "gray-matter": "^4.0.3", + "jsonld": "^9.0.0", "lucide-react": "^0.540.0", "next": "^16.2.0", "nextra": "^4.6.1", @@ -38,14 +42,18 @@ "zod": "^3.24.1" }, "devDependencies": { + "@ldo/cli": "1.0.0-alpha.51", + "@rdfjs/types": "^2.0.1", "@repo/eslint-config": "workspace:*", "@repo/tailwind-config": "workspace:*", "@repo/types": "workspace:*", "@repo/typescript-config": "workspace:*", "@tailwindcss/typography": "^0.5.15", + "@types/jsonld": "^1.5.15", "@types/node": "^20", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "@types/shexj": "^2.1.7", "@types/showdown": "^2.0.6", "autoprefixer": "^10.4.20", "dotenv": "^16.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a11947e5..3c9342f51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -433,6 +433,12 @@ importers: apps/website: dependencies: + '@ldo/ldo': + specifier: 1.0.0-alpha.51 + version: 1.0.0-alpha.51 + '@ldo/rdf-utils': + specifier: 1.0.0-alpha.51 + version: 1.0.0-alpha.51 '@repo/database': specifier: workspace:* version: link:../../packages/database @@ -454,6 +460,9 @@ importers: gray-matter: specifier: ^4.0.3 version: 4.0.3 + jsonld: + specifier: ^9.0.0 + version: 9.0.0 lucide-react: specifier: ^0.540.0 version: 0.540.0(react@19.1.1) @@ -494,6 +503,12 @@ importers: specifier: ^3.24.1 version: 3.25.76 devDependencies: + '@ldo/cli': + specifier: 1.0.0-alpha.51 + version: 1.0.0-alpha.51(web-streams-polyfill@3.3.3) + '@rdfjs/types': + specifier: ^2.0.1 + version: 2.0.1 '@repo/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config @@ -509,6 +524,9 @@ importers: '@tailwindcss/typography': specifier: ^0.5.15 version: 0.5.16(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) + '@types/jsonld': + specifier: ^1.5.15 + version: 1.5.15 '@types/node': specifier: ^20 version: 20.19.13 @@ -518,6 +536,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.1.9(@types/react@19.1.12) + '@types/shexj': + specifier: ^2.1.7 + version: 2.1.7 '@types/showdown': specifier: ^2.0.6 version: 2.0.6 @@ -1070,6 +1091,10 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bergos/jsonparse@1.4.2': + resolution: {integrity: sha512-qUt0QNJjvg4s1zk+AuLM6s/zcsQ8MvGn7+1f0vPuxvpCYa08YtTryuDInngbEyW5fNGGYe2znKt61RMGd5HnXg==} + engines: {'0': node >= 0.2.0} + '@blueprintjs/colors@4.2.1': resolution: {integrity: sha512-Cx7J2YnUuxn+fi+y5XtXnBB7+cFHN4xBrRkaAetp78i3VTCXjUk+d1omrOr8TqbRucUXTdrhbZOUHpzRLFcJpQ==} @@ -1188,6 +1213,103 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@comunica/actor-abstract-mediatyped@4.5.0': + resolution: {integrity: sha512-KbLuhbTcfAQHJeLo3CDDdffCZdfA1qDu15XIdW+7P03UpUp9xMw4p1G0kYtoXwj9KzWguY704TUtpJVBO1GOnw==} + + '@comunica/actor-abstract-parse@4.5.0': + resolution: {integrity: sha512-THNdQsJ58HtkyeW9ghVyLrYEQfSPNfmVAJTDSqOxIujjCdimPbzS2LBXoDdw13GuxWWOATssbm1LwXDlX0xMIQ==} + + '@comunica/actor-dereference-fallback@4.5.0': + resolution: {integrity: sha512-q5D3DEEm5B1+j6FcVZvyRV59ApHys/hBSlO2iCYcVnMg8S04PYlNzjgyERg0+2BjaG5KsbPDSwYlfRUMfJLIug==} + + '@comunica/actor-dereference-file@4.5.0': + resolution: {integrity: sha512-LKETw7dPywGTLF7I1XEKxUYydxucQYxkNa/IStxdNrLlnSFgMSJgb4AEKv57x5RKIY05sL3pVKdJwTj0znlaNw==} + + '@comunica/actor-dereference-http@4.5.0': + resolution: {integrity: sha512-Kn1HMabJL9yjF8R7GEAsVqwiC+DTgODC1ZbYCZF5GoreF5PTLCU+H1ipxnjxK9zv40+wbuO+bj75SOcDvegOdg==} + + '@comunica/actor-dereference-rdf-parse@4.5.0': + resolution: {integrity: sha512-Vs5Cs1GXov1tIWxDzoASA7TWGJOduEKiHqbsvGWAD8CwxRsdi8KSRHoyvKLVNAQUMiHBNe/PTV8G59O1Q53aYQ==} + + '@comunica/actor-http-fetch@4.5.0': + resolution: {integrity: sha512-rhPBWOWe0tGDgwXbRgURwiGcbw1KY58oMByT7MVi5SLMpiK1Tjjb6KoMz5SOkZWsD1z6JY65J/VLxKFSj37ogQ==} + + '@comunica/actor-http-proxy@4.5.0': + resolution: {integrity: sha512-M5UQ+/IqXFNXLu9qSFNeeph/vaP349HQozqZzOY+HTO4TNWSIcB/XO6HgE3SC7r4G+KV+s9WbHwQO/8PxshBPQ==} + + '@comunica/actor-rdf-parse-html-microdata@4.5.0': + resolution: {integrity: sha512-wxoXLS0nxV4ZqJEsx+zdZLjkRxZPFo+bXt+0fVEuDdBwL5WaJ6WPEL3fqbiH3QuaTu08k9klnsg2L1ncCeHhGg==} + + '@comunica/actor-rdf-parse-html-rdfa@4.5.0': + resolution: {integrity: sha512-o39tqHXAvKHnsa82Zm5FIbDRj+CSN46Nxj19TBSpCIsRlv5wJ9NpD6yxd7nGr1ovS5/5Ky7vDSdLcJ0MnJaNSQ==} + + '@comunica/actor-rdf-parse-html-script@4.5.0': + resolution: {integrity: sha512-eobWYbV4w7o/NK+6GMVkcaoGEQbTq2RmDDN63J1I/U0sTSQX0qvtLr0L4buOzGliIUttBbpsYfOc5YtJX6PP0g==} + + '@comunica/actor-rdf-parse-html@4.5.0': + resolution: {integrity: sha512-43PrAVCdHLcbJtPqZOVB9/4Zm5EDwIZrzUJhFPx7y30lzda1LmchL5aPrn5OPyrP3/AxK6U0Y9ISDZOBguOAEw==} + + '@comunica/actor-rdf-parse-jsonld@4.5.0': + resolution: {integrity: sha512-QuYhMRNH7oc2RjpDCUWNoZiEkwgOGgQvT+GnCZz2pd2kHuTcH3iBo5FvDTLornSVO0RVchcpWGItN9zA2dCNoQ==} + + '@comunica/actor-rdf-parse-n3@4.5.0': + resolution: {integrity: sha512-rERwWLr+fiFWuzWJe5Zoh0JvlaZn9DkvFGRl/5DntnDuwI91/U/p/atXBKfz/abpPAUs4hRGj5gkqmfdZg/bBQ==} + + '@comunica/actor-rdf-parse-rdfxml@4.5.0': + resolution: {integrity: sha512-KDmXZ7w++eMO1HXaKwbkx6o5wKTtSMTCdhMGb/ewHinw4XVwesAy9nu/C5CAhi8LpCjdAxa7kf5POejBXUWd3Q==} + + '@comunica/actor-rdf-parse-shaclc@4.5.0': + resolution: {integrity: sha512-YFYn9ml/eCfZhBTYeaYJ0Qk6HerBi0H4acZYppcMKdh/GPJklzW9LOLlEfEzYstrqwPIKZzqgoBg5yvVgbmXpA==} + + '@comunica/actor-rdf-parse-xml-rdfa@4.5.0': + resolution: {integrity: sha512-1uQuq3xsokT0wWf9O6d+SyuNEvGX+bgSSGBCQF9YDjc2RygiZATUdThDmh4VDUYJzUCxHb3YM1XyJ+U2Si6xpA==} + + '@comunica/bus-dereference-rdf@4.5.0': + resolution: {integrity: sha512-z9NQ7zOoNQH7XoiZEHkMl4Y6fYLkinP+KQgGGSTm2ylhAHnId7qf+UVZhbe1+jmX50YhNOPc3ZT1LOm1YdSnzw==} + + '@comunica/bus-dereference@4.5.0': + resolution: {integrity: sha512-aaiPxZMS/KlkLbQErOtGRMtirVGWYVEmQiFtlKkak2w+584rHTS33m0YD21r6iuQ9RIleRIAb8kAsPa6zDgAnA==} + + '@comunica/bus-http@4.5.0': + resolution: {integrity: sha512-wWyPNNOl6shDbtibdBl/pa9OIcoEMemNIo/J4tUViXxYXZ8i1h4FZ6PqaLtAls6O+pV71mR4SKJzKEUuiZiXPg==} + + '@comunica/bus-init@4.5.0': + resolution: {integrity: sha512-9TYFLjirHDt7HPXj3eQW9KX3x5T3mZ1G/EKadL1gQxo0FAqs3y8TdicepCLhk3HY/egidlyv9WQYAPvJ+WAmAg==} + + '@comunica/bus-rdf-parse-html@4.5.0': + resolution: {integrity: sha512-yKsPuCIOLF5TXqoXXo+utZehG2diTCBnNleXrOI8Utr4Qu5rAU4oQ5+FC0UByMu5hr+g/TGm2A+IHSVzFRCUfw==} + + '@comunica/bus-rdf-parse@4.5.0': + resolution: {integrity: sha512-TnTS9F2GSbibuCd0Rep20C9WXU0KH0iWl2S2xycefMFrZK7noA8LeT/AHNshQlMPKejKxWME+jNsvcXgC++8zw==} + + '@comunica/config-query-sparql@4.4.0': + resolution: {integrity: sha512-ZVK6eqpYLNa3MRLOWjRaudgfSdraJH/oZIkc5S2doJI2ZmnHROqQUtjPs13kwkI3hGZ6MVBtLm55oz+tKj2lKA==} + + '@comunica/context-entries@4.5.0': + resolution: {integrity: sha512-mgeSYFBcpMKLq34COpy129LVHigGUgA1uEI66WXmk3mdmlAKRQNe9D/W2Q924w0FZZmIOpeLMo+s358tFsodow==} + + '@comunica/core@4.5.0': + resolution: {integrity: sha512-UFHBboFaY0eESH0H8qJRIRuRfda2QduS886l2sRum/V4qhzJkMpf3zdOoZoBbRDU24PBmliWysi9TEsaPsyRwg==} + engines: {node: '>=14.0'} + + '@comunica/mediator-combine-pipeline@4.5.0': + resolution: {integrity: sha512-Z4uLxugl+Ls8oAwD0dAIQg+i1rkiXbpiFLhgv5h6nksnz9q6Nv14xItm6baivxAJ9p8XVHCOwPxW46YJBtWIoQ==} + + '@comunica/mediator-combine-union@4.5.0': + resolution: {integrity: sha512-aCoO3CiANssR8PEjad2aNuCcfhKdUFZWplTWq77cVUMVc4nsUWNleeEvN6kfOx51qdT8lFpH3b8X+S7bT8CABg==} + + '@comunica/mediator-number@4.5.0': + resolution: {integrity: sha512-fChc4gh+gtwPOS0F5eNeDuU4Kyb2fAuppN28d1/5s+OUr5v+1Wya7yZ1zbPHYxDMWZEpJBR06eX6djcI0gKlkQ==} + + '@comunica/mediator-race@4.5.0': + resolution: {integrity: sha512-eAWjQolFMOxKoKuUMmcQzxwf/ZL9ooT0/OUWv1vbVfHIQb/eqDs/h8wDqwXMgEiK5dIF9ZQYaRL2vEaLq+U3Ew==} + + '@comunica/mediatortype-time@4.5.0': + resolution: {integrity: sha512-HND+om4L0VW3VcQrLHHE4+7Nsg7soC98i7g7UqqzDkJ4fix2FnJs0i9WH4RP+oLcx+bPhBSl5mG1m44A6sV19g==} + + '@comunica/types@4.5.0': + resolution: {integrity: sha512-XhnkspVgYilchErpSAELHRA7B4wRszDdvCkhbd52vjLrThzGUDfDoGx+56y4AeziWkxQLNug8AZbo/Q6J2vCzQ==} + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1256,6 +1378,14 @@ packages: '@cucumber/tag-expressions@9.1.0': resolution: {integrity: sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==} + '@digitalbazaar/http-client@1.2.0': + resolution: {integrity: sha512-W9KQQ5pUJcaR0I4c2HPJC0a7kRbZApIorZgPnEDwMBgj16iQzutGLrCXYaZOmxqVLVNqqlQ4aUJh+HBQZy4W6Q==} + engines: {node: '>=10.0.0'} + + '@digitalbazaar/http-client@4.3.0': + resolution: {integrity: sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==} + engines: {node: '>=18.0'} + '@dnd-kit/accessibility@3.1.1': resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} peerDependencies: @@ -2421,6 +2551,13 @@ packages: '@jcubic/lily@0.3.0': resolution: {integrity: sha512-4z6p4jLGSthc8gQ7wu4nHfGYn/IgCKFr+7hjuf80VdXUs7sm029mZGGDpS8sb29PVZWUBvMMTBCVGFhH2nN4Vw==} + '@jeswr/shacl2shex@1.5.1': + resolution: {integrity: sha512-RBJMu/oOuj4jLAwmPeKEgiFFfwedphOmmvIwJbyfXkF0qTdNtZJ1M14IX77QWfseeI79/9VZrHsunlzFQr7XBQ==} + hasBin: true + + '@jeswr/stream-to-string@2.0.0': + resolution: {integrity: sha512-VmoW6xYRjVzdMr2njBObVSlUc5KCJT+gyuuH+tea9ZLE59XhgfLNc8ufN5Md38STxCyAJUDUVcCBfaOo11BfuA==} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -2440,6 +2577,49 @@ packages: '@juggle/resize-observer@3.4.0': resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + '@ldo/cli@1.0.0-alpha.51': + resolution: {integrity: sha512-+//vjmenLXRJUkYpd+rpPz/jScp21TQf3nl5/HKipnOndrW2ikiWDDVqL3vQzH3qWVnexu+Cc/UcVL9ZnOVXnA==} + hasBin: true + + '@ldo/dataset@0.0.1-alpha.24': + resolution: {integrity: sha512-Jlh6DjvLN4gOOT8SYCKQaHZB8taeHvoriQRbF3s5CtYFf8Ne20job+02cToE1kVcBCinBrjZ/qnZ777wje+Z7A==} + + '@ldo/dataset@1.0.0-alpha.51': + resolution: {integrity: sha512-ZaRCPGxUB9RooLwKYjcQt6XYjAabCWPbtZZrcKJv1yKgOQOXw214cMArmlrYeHJPoEB+Qo7fsq63Vg6CQeZOgg==} + + '@ldo/jsonld-dataset-proxy@0.0.1-alpha.29': + resolution: {integrity: sha512-6r1tn/t82aJ6vjxEGyNSJTzQJgz1Z4Pu875o4EolXXJZCu7TiXBdsW6HyAuloqiIV5b6A2b+M6G0mOuObndooA==} + + '@ldo/jsonld-dataset-proxy@1.0.0-alpha.51': + resolution: {integrity: sha512-ZDBJlyQ/oj9SJ7ufR8HPWFUhmzq9+3aHBt220NbocY5QqrLGPBEVq8SiiPCuxJn+Ye95OAJL4rCTafkXd/E9Sw==} + + '@ldo/ldo@0.0.1-alpha.29': + resolution: {integrity: sha512-eci3e2FlaSoOWN5vzLQaJhrmznuuK89yTr/ZLvmWIK2bvsY8QOArAx8EiGgwvvrzvHpG7ezaoW1ThS/53QFiqQ==} + + '@ldo/ldo@1.0.0-alpha.51': + resolution: {integrity: sha512-a++67keLWExy+CLKyKyBfNomEcKxmuuWnE+6ZMzZxK7Su6NSv8W12uecLd7x1lt+G6mX6VFFMKuqpw6pRnHLtg==} + + '@ldo/rdf-utils@0.0.1-alpha.24': + resolution: {integrity: sha512-L6gV/pS7107ODinnvvD4sUBb9VM/7IuVeFWZnN0Jmyk7XBiviPLVUvReO18UB7mambXweLS7efl+Z0W2NnsH1A==} + + '@ldo/rdf-utils@1.0.0-alpha.51': + resolution: {integrity: sha512-DGkmv1ZeJ8c9TIa6vWXav9n6KIrqHzeRTle6JUcMOEFbzB3AP8qQpUmKcaTpw8HCINQEjQv+bmNeUbfWpCAQ3g==} + + '@ldo/schema-converter-shex@1.0.0-alpha.51': + resolution: {integrity: sha512-YvUBrYS8a5g/nDMYce+1h4K/zZ1KzezxX9V0RiiFk5SeCsNKtbELSS+ZADd1tTjLiwQRN2p1CIUX3P63rMbwqg==} + + '@ldo/subscribable-dataset@0.0.1-alpha.24': + resolution: {integrity: sha512-grQ0/pzdx4euBOTxMHqQqebOYBqrBbNS9Jk8sYFR4u/dEg8e6nIGz0E4beI83dHp/hT8fT18gs/gV4UxZzmphQ==} + + '@ldo/subscribable-dataset@1.0.0-alpha.51': + resolution: {integrity: sha512-WubtsqL9fDtjH8kGaQB3issHf9b2Lxl49EPK9VE3PaT2WJwDWA7wUMbrBsYNJ2wNsIZ8z4qlrjHqsbKACWXp/A==} + + '@ldo/traverser-shexj@1.0.0-alpha.51': + resolution: {integrity: sha512-GXdyYiLL8rWZNXMfKXJfaUfYsEddEaOxDzIgzHklb/QS1+KYcHtWavJGc45X3PIhv7S43rMB1UG6rzDlQrrNNg==} + + '@ldo/type-traverser@1.0.0-alpha.51': + resolution: {integrity: sha512-ONZQ8Wd4qBKdp/QvL926xU96qfYhcl0HFziewZrn7O3OyDwDY+bkZN4o03Ksza8h4IYqVrjsfUCpAQP5K2rwpw==} + '@mapbox/node-pre-gyp@2.0.0': resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} engines: {node: '>=18'} @@ -3939,6 +4119,30 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@rdfjs/data-model@1.3.4': + resolution: {integrity: sha512-iKzNcKvJotgbFDdti7GTQDCYmL7GsGldkYStiP0K8EYtN7deJu5t7U11rKTz+nR7RtesUggT+lriZ7BakFv8QQ==} + hasBin: true + + '@rdfjs/data-model@2.1.1': + resolution: {integrity: sha512-6mcOI4DjIPS6MOZw23H8oAdujHCk5gippVNQ7mKwliYTvTNh+uqRM91B9OLqhoAoNcQ3t49Dx2ooIMRG9/6ooA==} + hasBin: true + + '@rdfjs/dataset@1.1.1': + resolution: {integrity: sha512-BNwCSvG0cz0srsG5esq6CQKJc1m8g/M0DZpLuiEp0MMpfwguXX7VeS8TCg4UUG3DV/DqEvhy83ZKSEjdsYseeA==} + hasBin: true + + '@rdfjs/term-set@1.1.0': + resolution: {integrity: sha512-QQ4yzVe1Rvae/GN9SnOhweHNpaxQtnAjeOVciP/yJ0Gfxtbphy2tM56ZsRLV04Qq5qMcSclZIe6irYyEzx/UwQ==} + + '@rdfjs/to-ntriples@2.0.0': + resolution: {integrity: sha512-nDhpfhx6W6HKsy4HjyLp3H1nbrX1CiUCWhWQwKcYZX1s9GOjcoQTwY7GUUbVec0hzdJDQBR6gnjxtENBDt482Q==} + + '@rdfjs/types@1.1.2': + resolution: {integrity: sha512-wqpOJK1QCbmsGNtyzYnojPU8gRDPid2JO0Q0kMtb4j65xhCK880cnKAfEOwC+dX85VJcCByQx5zOwyyfCjDJsg==} + + '@rdfjs/types@2.0.1': + resolution: {integrity: sha512-uyAzpugX7KekAXAHq26m3JlUIZJOC0uSBhpnefGV5i15bevDyyejoB7I+9MKeUrzXD8OOUI3+4FeV1wwQr5ihA==} + '@react-aria/focus@3.21.5': resolution: {integrity: sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==} peerDependencies: @@ -4207,6 +4411,10 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@rubensworks/saxes@6.0.1': + resolution: {integrity: sha512-UW4OTIsOtJ5KSXo2Tchi4lhZqu+tlHrOAs4nNti7CrtB53kAZl3/hyrTi6HkMihxdbDM6m2Zc3swc/ZewEe1xw==} + engines: {node: '>=v12.22.12'} + '@rushstack/eslint-patch@1.12.0': resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==} @@ -4245,6 +4453,50 @@ packages: '@selderee/plugin-htmlparser2@0.11.0': resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} + '@shexjs/eval-simple-1err@1.0.0-alpha.29': + resolution: {integrity: sha512-qizKDp+FPoOL9140VJglIbf9brgQdoPDrZ0t0vmTEdRQvY5+rF+H20nStAiPPK6XxC/AbIglv6/dImQWAMKuSw==} + engines: {node: '>=0.10.0'} + + '@shexjs/eval-threaded-nerr@1.0.0-alpha.29': + resolution: {integrity: sha512-/RFl7SzEaiofdLd1qNidvpU4Yy4TZuMdO5DMPznHkIICjyJeKgg8Kx166VznZPVIa66Sxr/hG4ngkaWsHxWYwQ==} + engines: {node: '>=0.10.0'} + + '@shexjs/eval-validator-api@1.0.0-alpha.29': + resolution: {integrity: sha512-5QCd6DvgBMOZvWZtixdsH/d4uXPzxYr4yv7C0wzVeBKRkB15KQd7Ccg8Bz9QbsIV1O9asxG1xoxGgYDkhZeBPg==} + engines: {node: '>=0.10.0'} + + '@shexjs/neighborhood-api@1.0.0-alpha.28': + resolution: {integrity: sha512-rkIIt39z3z1gt+8xc3CJAKLBJ/OUE+8sP24Iqs9uZYuRvJitavd+L8oX5XcdpMduwJUqE6s+Rf/YUuN0VYn7Qw==} + engines: {node: '>=0.10.0'} + + '@shexjs/neighborhood-rdfjs@1.0.0-alpha.29': + resolution: {integrity: sha512-6B4LMfTyQA5L42QI3+rlGxQEPywqLe4CFJDUm/bn6V3ldakajh/ZbPHod3DPjSLsJ7tYLZsRi9GPIPTgYgmZUw==} + engines: {node: '>=0.10.0'} + + '@shexjs/parser@1.0.0-alpha.28': + resolution: {integrity: sha512-eeVeHq/2JG9X+3h7y+7EmuBSWWl2EMj/EQBLk5CTRx4W4hWDdjWczsY8RWwKjkIzLwUS1+G0aiAI1u5LHCZ2Rw==} + engines: {node: '>=0.10.0'} + + '@shexjs/term@1.0.0-alpha.27': + resolution: {integrity: sha512-+D7P7pglRPTZC2RkwaQuq+cgBZImx+61JZtcN77uEJVqcGaIscQK5hScsKhAPIo16/I+4jhIUCEFojXqw6otpg==} + engines: {node: '>=0.10.0'} + + '@shexjs/util@1.0.0-alpha.28': + resolution: {integrity: sha512-L8pBokTU/5eNRJPkC8R9SIgPw6/JDh/bHKdV5TZzf8/FkOMNJwKIy6UDHXM1I8FJ+c8u2gOOHp2MA+7b+md+0A==} + engines: {node: '>=0.10.0'} + + '@shexjs/validator@1.0.0-alpha.29': + resolution: {integrity: sha512-KO9Sf9ICpnoFFutiX59vx7o9eRnOPuKngKxfeyOzM3mKmKQXad0SOIbqRxRBaMgV/eXwhnIERhzvCK66EZMrFQ==} + engines: {node: '>=0.10.0'} + + '@shexjs/visitor@1.0.0-alpha.27': + resolution: {integrity: sha512-9s67A+f0ZZNw/SNxqoi1483CqUca8dbnHM6WDWsRH4+eXlQpQqwOZDxA8uKEaWeX4VcDrDwzWpr0WvK6EyDWIQ==} + engines: {node: '>=0.10.0'} + + '@shexjs/writer@1.0.0-alpha.27': + resolution: {integrity: sha512-VK4gIQdIuhlU2vU8HiZAvffj4zPzLrDjLaBS0uKiLS0VTSpee4rejLJs4HiXCfPXFY7xOdW+As9dBH7kKpXWew==} + engines: {node: '>=0.10.0'} + '@shikijs/core@3.23.0': resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} @@ -4798,12 +5050,24 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@ts-jison/common@0.4.1-alpha.1': + resolution: {integrity: sha512-SDbHzq+UMD+V3ciKVBHwCEgVqSeyQPTCjOsd/ZNTGySUVg4x3EauR9ZcEfdVFAsYRR38XWgDI+spq5LDY46KvQ==} + + '@ts-jison/lexer@0.4.1-alpha.1': + resolution: {integrity: sha512-5C1Wr+wixAzn2MOFtgy7KbT6N6j9mhmbjAtyvOqZKsikKtNOQj22MM5HxT+ooRexG2NbtxnDSXYdhHR1Lg58ow==} + + '@ts-jison/parser@0.4.1-alpha.1': + resolution: {integrity: sha512-xNj+qOez/7dju44LlYiTlCjxMzW5oek9EckUAElfln/GBK9vgMSk0swWcnacMr0TYbGjUQuXvL2wEgmDf5WajQ==} + '@ts-morph/common@0.11.1': resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} '@ts-morph/common@0.19.0': resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==} + '@ts-morph/common@0.25.0': + resolution: {integrity: sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==} + '@ts-morph/common@0.28.1': resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==} @@ -4842,6 +5106,9 @@ packages: '@types/codemirror@5.60.8': resolution: {integrity: sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==} + '@types/concat-stream@1.6.1': + resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} @@ -4968,6 +5235,9 @@ packages: '@types/file-saver@2.0.5': resolution: {integrity: sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==} + '@types/form-data@0.0.33': + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} + '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} @@ -4980,6 +5250,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/http-link-header@1.0.7': + resolution: {integrity: sha512-snm5oLckop0K3cTDAiBnZDy6ncx9DJ3mCRDvs42C884MbVYPP74Tiq2hFsSDRTyjK6RyDYDIulPiW23ge+g5Lw==} + '@types/inquirer@6.5.0': resolution: {integrity: sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==} @@ -4998,6 +5271,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonld@1.5.15': + resolution: {integrity: sha512-PlAFPZjL+AuGYmwlqwKEL0IMP8M8RexH0NIPGfCVWSQ041H2rR/8OlyZSD7KsCVoN8vCfWdtWDBxX8yBVP+xow==} + '@types/katex@0.16.8': resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} @@ -5035,6 +5311,9 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/n3@1.26.1': + resolution: {integrity: sha512-TilYHzpU6ecXVJAbV+6o17Z8ZkWLWx6ZJD3IluaU4RiGHxqjU2or9fopxFHS6iXS6qcl5Mg1K3wSx9L8xxJaJQ==} + '@types/nanoid@2.0.0': resolution: {integrity: sha512-NtwPHfAyU3IDXdKAB2OMPpAauHBg9gUjpOYr3FAzI84D70nWdS8k5mryteLvT/s1ACeAFAkGg132/XJVN4qx/w==} @@ -5044,6 +5323,9 @@ packages: '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + '@types/node@18.19.124': resolution: {integrity: sha512-hY4YWZFLs3ku6D2Gqo3RchTd9VRCcrjqp/I0mmohYeUVA5Y8eCXKJEasHxLAJVZRJuQogfd1GiJ9lgogBgKeuQ==} @@ -5053,12 +5335,18 @@ packages: '@types/node@20.19.13': resolution: {integrity: sha512-yCAeZl7a0DxgNVteXFHt9+uyFbqXGy/ShC4BlcHkoE0AfGXYv/BUiplV72DjMYXHDBXFjhvr6DD1NiRVfB4j8g==} + '@types/node@8.10.66': + resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@types/qs@6.15.1': + resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} + '@types/raf@3.4.3': resolution: {integrity: sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==} @@ -5079,18 +5367,30 @@ packages: '@types/react@19.1.12': resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} + '@types/readable-stream@2.3.15': + resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} + + '@types/readable-stream@4.0.23': + resolution: {integrity: sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==} + '@types/scheduler@0.16.8': resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/shexj@2.1.7': + resolution: {integrity: sha512-pu/0vIZxFTMPVjTlo5MJKFkBL/EbAuFhtCXpmBB7ZdUiyNpc6pt8GxfyRPqdf6q2SsWu71a/vbhvGK2IZN2Eug==} + '@types/showdown@2.0.6': resolution: {integrity: sha512-pTvD/0CIeqe4x23+YJWlX2gArHa8G0J0Oh6GKaVXV7TAeickpkkZiNOgFcFcmLQ5lB/K0qBJL1FtRYltBfbGCQ==} '@types/sizzle@2.3.10': resolution: {integrity: sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==} + '@types/sparqljs@3.1.12': + resolution: {integrity: sha512-zg/sdKKtYI0845wKPSuSgunyU1o/+7tRzMw85lHsf4p/0UbA6+65MXAyEtv1nkaqSqrq/bXm7+bqXas+Xo5dpQ==} + '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} @@ -5124,6 +5424,12 @@ packages: '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + '@typescript-eslint/eslint-plugin@7.18.0': resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} engines: {node: ^18.18.0 || >=20.0.0} @@ -5723,6 +6029,9 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + assertion-error-formatter@3.0.0: resolution: {integrity: sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==} @@ -5769,6 +6078,9 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynciterator@3.10.0: + resolution: {integrity: sha512-eDOBoUf2m+4ht0ETVn2SCfuBIZZ6UWyyQbP++LRPKoK7PmrCQq37pJ6vRvyef4o1Pn+CwWnzMlkXxGdh/krVIw==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5939,15 +6251,29 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + camelcase@9.0.0: + resolution: {integrity: sha512-TO9xmyXTZ9HUHI8M1OnvExxYB0eYVS/1e5s7IDMTAoIcwUd+aNcFODs6Xk83mobk0velyHFQgA1yIrvYc6wclw==} + engines: {node: '>=20'} + caniuse-lite@1.0.30001739: resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} + canonicalize@1.0.8: + resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==} + + canonicalize@2.1.0: + resolution: {integrity: sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==} + hasBin: true + canvas-size@1.2.6: resolution: {integrity: sha512-x2iVHOrZ5x9V0Hwx6kBz+Yxf/VCAII+jrD6WLjJbytJLozHq/oDJjEva432Os0eHxWMFR0vYlLJwTr6QxyxQqw==} capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + ccount@1.1.0: resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} @@ -6015,6 +6341,9 @@ packages: chevrotain@11.1.2: resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + child-process-promise@2.2.1: + resolution: {integrity: sha512-Fi4aNdqBsr0mv+jgWxcZ/7rAIC2mgihrptyVI4foh/rrjY/3BNjfP9+oaiFx/fzim+1ZyCNBae0DlyfQhSugog==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -6164,6 +6493,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colors-cli@1.0.33: + resolution: {integrity: sha512-PWGsmoJFdOB0t+BeHgmtuoRZUQucOLl5ii81NBzOOGVxlgE04muFNHlR5j8i8MKbOPELBl3243AI6lGBTj5ICQ==} + hasBin: true + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -6220,6 +6553,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -6315,6 +6652,12 @@ packages: crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-spawn@4.0.2: + resolution: {integrity: sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==} + cross-spawn@6.0.6: resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} engines: {node: '>=4.8'} @@ -6538,6 +6881,10 @@ packages: data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + data-uri-to-buffer@3.0.1: + resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} + engines: {node: '>= 6'} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -6767,6 +7114,9 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dts-dom@3.6.0: + resolution: {integrity: sha512-on5jxTgt+A6r0Zyyz6ZRHXaAO7J1VPnOd6+AmvI1vH440AlAZZNc5rUHzgPuTjGlrVr1rOWQYNl7ZJK6rDohbw==} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -6786,6 +7136,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + electron-to-chromium@1.5.214: resolution: {integrity: sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==} @@ -6816,6 +7171,10 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -7179,6 +7538,9 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + event-emitter-promisify@1.1.0: + resolution: {integrity: sha512-uyHG8gjwYGDlKoo0Txtx/u1HI1ubj0FK0rVqI4O0s1EymQm4iAEMbrS5B+XFlSaS8SZ3xzoKX+YHRZk8Nk/bXg==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -7195,6 +7557,10 @@ packages: events-universal@1.0.1: resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.0.6: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} @@ -7316,6 +7682,15 @@ packages: picomatch: optional: true + fetch-blob@2.1.2: + resolution: {integrity: sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==} + engines: {node: ^10.17.0 || >=12.3.0} + peerDependencies: + domexception: '*' + peerDependenciesMeta: + domexception: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -7337,6 +7712,9 @@ packages: file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -7391,6 +7769,10 @@ packages: form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + form-data@2.5.5: + resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==} + engines: {node: '>= 0.12'} + form-data@4.0.4: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} @@ -7494,6 +7876,10 @@ packages: resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} engines: {node: '>=14.16'} + get-port@3.2.0: + resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} + engines: {node: '>=4'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -7716,6 +8102,9 @@ packages: headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + hierarchy-closure@1.2.2: + resolution: {integrity: sha512-ZqZvsA6HyMqrmm49D3llYA8x8hqdyDDEkaTXcqwyO+fGQlzxoeXws/5ze11M40s4EoTw7GFxdTKIwj5YDOicLQ==} + hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -7750,9 +8139,16 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + http-basic@8.1.3: + resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} + engines: {node: '>=6.0.0'} + http-errors@1.7.3: resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} engines: {node: '>= 0.6'} @@ -7761,6 +8157,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-link-header@1.1.3: + resolution: {integrity: sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==} + engines: {node: '>=6.0.0'} + http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} @@ -7769,6 +8169,9 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -7838,6 +8241,9 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immutable@5.1.6: + resolution: {integrity: sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -8201,6 +8607,11 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true @@ -8287,6 +8698,31 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonld-context-parser@2.4.0: + resolution: {integrity: sha512-ZYOfvh525SdPd9ReYY58dxB3E2RUEU4DJ6ZibO8AitcowPeBH4L5rCAitE2om5G1P+HMEgYEYEr4EZKbVN4tpA==} + hasBin: true + + jsonld-context-parser@3.1.0: + resolution: {integrity: sha512-BfgNJ/t9jjK7Lun9XRCJM6YeNqDk8B6/lg+KS8rzhXAOtS0FvoClSmtLvF24V1M2CDYRy2LcEBt0ilxqSX93WA==} + hasBin: true + + jsonld-streaming-parser@4.0.1: + resolution: {integrity: sha512-6M4y9YGgADk3nXJebbRrxEdMVBJ9bnz+peAvjTXUievopqaE8sg/qml/I6Sp1ln7rpOKffsNZWSre6B7N76szw==} + + jsonld2graphobject@0.0.4: + resolution: {integrity: sha512-7siWYw9/EaD9lWyMbHr2uLMy8kbNVyOtDlsAWJUlUjVfXpcJcwLN6f0qeNt0ySV4fDoAJOjJXNvo7V/McrubAg==} + + jsonld2graphobject@0.0.5: + resolution: {integrity: sha512-5BqfXOq96+OBjjiJNG8gQH66pYt6hW88z2SJxdvFJo4XNoVMvqAcUz+JSm/KEWS5NLRnebApEzFrYP3HUiUmYw==} + + jsonld@5.2.0: + resolution: {integrity: sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw==} + engines: {node: '>=12'} + + jsonld@9.0.0: + resolution: {integrity: sha512-pjMIdkXfC1T2wrX9B9i2uXhGdyCmgec3qgMht+TDj+S0qX3bjWMQUfL7NeqEhuRTi8G5ESzmL9uGlST7nzSEWg==} + engines: {node: '>=18'} + jsonlines@0.1.1: resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} @@ -8328,6 +8764,24 @@ packages: knuth-shuffle-seeded@1.0.6: resolution: {integrity: sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg==} + ky-universal@0.8.2: + resolution: {integrity: sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==} + engines: {node: '>=10.17'} + peerDependencies: + ky: '>=0.17.0' + web-streams-polyfill: '>=2.0.0' + peerDependenciesMeta: + web-streams-polyfill: + optional: true + + ky@0.25.1: + resolution: {integrity: sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==} + engines: {node: '>=10'} + + ky@1.14.3: + resolution: {integrity: sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==} + engines: {node: '>=18'} + langium@4.2.1: resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} @@ -8388,6 +8842,9 @@ packages: resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} engines: {node: '>=20.0.0'} + loading-cli@1.1.2: + resolution: {integrity: sha512-M1ntfXHpdGoQxfaqKBOQPwSrTr9EIoTgj664Q9UVSbSnJvAFdribo+Ij//1jvACgrGHaTvfKoD9PG3NOxGj44g==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -8492,6 +8949,9 @@ packages: resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} engines: {node: 20 || >=22} + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -8651,6 +9111,9 @@ packages: engines: {node: '>= 8.0.0'} hasBin: true + microdata-rdf-streaming-parser@2.0.1: + resolution: {integrity: sha512-oEEYP3OwPGOtoE4eIyJvX1eJXI7VkGR4gKYqpEufaRXc2ele/Tkid/KMU3Los13wGrOq6woSxLEGOYSHzpRvwA==} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -8906,6 +9369,10 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + n3@1.26.0: + resolution: {integrity: sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==} + engines: {node: '>=12.0'} + nanoevents@7.0.1: resolution: {integrity: sha512-o6lpKiCxLeijK4hgsqfR6CNToPyRU3keKyyI6uwuHRvpRTbZ0wXw51WRgyldVugZqoJfkGFrjrIenYH3bfEO3Q==} engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} @@ -9029,6 +9496,10 @@ packages: encoding: optional: true + node-fetch@3.0.0-beta.9: + resolution: {integrity: sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==} + engines: {node: ^10.17 || >=12.3} + node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -9044,6 +9515,10 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-version@1.2.0: + resolution: {integrity: sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==} + engines: {node: '>=6.0.0'} + nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} engines: {node: ^18.17.0 || >=20.5.0} @@ -9288,6 +9763,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + parse-entities@2.0.0: resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} @@ -9626,10 +10104,23 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promise-polyfill@1.1.6: + resolution: {integrity: sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==} + + promise-polyfill@6.1.0: + resolution: {integrity: sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ==} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + promisepipe@3.0.0: resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} @@ -9726,6 +10217,9 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} @@ -9786,6 +10280,51 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true + rdf-canonize@3.4.0: + resolution: {integrity: sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==} + engines: {node: '>=12'} + + rdf-canonize@5.0.0: + resolution: {integrity: sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==} + engines: {node: '>=18'} + + rdf-data-factory@1.1.3: + resolution: {integrity: sha512-ny6CI7m2bq4lfQQmDYvcb2l1F9KtGwz9chipX4oWu2aAtVoXjb7k3d8J1EsgAsEbMXnBipB/iuRen5H2fwRWWQ==} + + rdf-data-factory@2.0.2: + resolution: {integrity: sha512-WzPoYHwQYWvIP9k+7IBLY1b4nIDitzAK4mA37WumAF/Cjvu/KOtYJH9IPZnUTWNSd5K2+pq4vrcE9WZC4sRHhg==} + + rdf-dereference-store@1.4.0: + resolution: {integrity: sha512-VWobImdfxG46vBGzD8V/CJ6+zSC5FPt16Fe0PUyK+jUQG5hYbGDp0+U7fcaeK5Xif8y9kA0mXPUy2k/Qn9PWLg==} + + rdf-dereference@4.0.0: + resolution: {integrity: sha512-hv7uqIHTB9M/OnS69hrSwNVBo/4+CFLwdVCL6Lg7z0+KLDJChZmTK5e6CFQ8v0OL1TJTSETGx2/EORhOwuZfFQ==} + hasBin: true + + rdf-isomorphic@2.0.1: + resolution: {integrity: sha512-8pfA3PeDs1sVrZ2R3dCR4KRM69m3pQGhzviNQq5Az/+Zch4I+fKstjGxCZ5ADAFPsm9zxHk8zMEQ/BFcqlnLKw==} + + rdf-namespaces@1.17.0: + resolution: {integrity: sha512-/Y3TcMZ/doQ/PVyQUy2Mt6I3puVoks9mU0+XifFAlZqnCNl0zMwA3dKOmCcyVMyuMZ4iPKNuzseLcoF5E+pGAg==} + + rdf-parse@4.0.0: + resolution: {integrity: sha512-lNVuUKPVAdX9lJYYrJFhdQHFulYjk95BYvuNsE+eUs/M93sdsovH/Ga8bTAxagmpsoQ4LzMPa2YqeHX8ysltOA==} + + rdf-string@1.6.3: + resolution: {integrity: sha512-HIVwQ2gOqf+ObsCLSUAGFZMIl3rh9uGcRf1KbM85UDhKqP+hy6qj7Vz8FKt3GA54RiThqK3mNcr66dm1LP0+6g==} + + rdf-string@2.0.1: + resolution: {integrity: sha512-SMW4ponnKNrsP9kYpOLyICeM4UJmEXIeS3zri7kPK9gzLFsHD88oiza8LnokNYxd76zW4JoYWD+v4x0g8rJBjw==} + + rdf-terms@2.0.0: + resolution: {integrity: sha512-9O+ifVcvY4ZktOr+uXKswoOV6airAsIKeqCr+C47kFZBB8X+NyPSqDRGgI6X+je8It6z2e9jZhWwjJiEZ8Yn5Q==} + + rdfa-streaming-parser@2.0.1: + resolution: {integrity: sha512-7Yyaj030LO7iQ38Wh/RNLVeYrVFJeyx3dpCK7C1nvX55eIN/gE4HWfbg4BYI9X7Bd+eUIUMVeiKYLmYjV6apow==} + + rdfxml-streaming-parser@2.4.0: + resolution: {integrity: sha512-f+tdI1wxOiPzMbFWRtOwinwPsqac0WIN80668yFKcVdFCSTGOWTM70ucQGUSdDZZo7pce/UvZgV0C3LDj0P7tg==} + react-charts@3.0.0-beta.57: resolution: {integrity: sha512-vqas7IQhsnDGcMxreGaWXvSIL3poEMoUBNltJrslz/+m0pI3QejBCszL1QrLNYQfOWXrbZADfedi/a+yWOQ7Hw==} peerDependencies: @@ -9941,6 +10480,12 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} + readable-from-web@1.0.0: + resolution: {integrity: sha512-tei03fQhxqLEklpIvocFUR9hO42hiyYvdhwoNHAjJztPAQ8QS1NqF2AhLwzGxIGidPBJ4MCqB48wn7OAFCfhsQ==} + + readable-stream-node-to-web@1.0.1: + resolution: {integrity: sha512-OGzi2VKLa8H259kAx7BIwuRrXHGcxeHj4RdASSgEGBP9Q2wowdPvBc65upF4Q9O05qWgKqBw1+9PiLTtObl7uQ==} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -9948,6 +10493,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} @@ -10039,6 +10588,12 @@ packages: rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + relative-to-absolute-iri@1.0.8: + resolution: {integrity: sha512-U1TmhrhCmXKkDL9mI8gBbF5TN6TKcuv28k5+H3gMCAjoz0TyyHAICHlaGDZsTEBSu2Y3HhDKc8e6X9n33qeIqA==} + + relativize-url@0.1.0: + resolution: {integrity: sha512-YXet4a9wQP96Ru9MQSfoRUzsCaeboLPXj+rVG1ulH4t54zqFHiNmW6FPl7V2dTxk9uHlW3yb9+1jWO44AdWisw==} + remark-frontmatter@5.0.0: resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} @@ -10358,6 +10913,9 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + shaclc-parse@1.4.3: + resolution: {integrity: sha512-MQJWVFjfzzMUvieFO0STWjIo49ywy63UkVSsr0e8+8xHUns6X+i3yWYxNKd+GtSEJjBNZxxrUubog+hnd7PvRA==} + shadcn@2.10.0: resolution: {integrity: sha512-/zxjmHGbaYVFtI6bUridFVV7VFStIv3vU/w1h7xenhz7KRzc9pqHsyFvcExZprG7dlA5kW9knRgv8+Cl/H7w9w==} hasBin: true @@ -10507,6 +11065,16 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + sparqlalgebrajs@5.0.2: + resolution: {integrity: sha512-Xz7byRqWqCMkbM+3ogGmKO/wsezQKQQNleoggP03sCTTFfCh/ZlN5CGt+HkrOenDSktZ93jpKFbbaIRjLOYtWw==} + hasBin: true + + sparqljs@3.7.4: + resolution: {integrity: sha512-hb4C84gf7KM7vz+iG595mPwvqxOvBJCm9L3dCxtV2zZDht6ZMmMG0tHeeqFeqwb9875yU9U4lhYe4LYRvWj0BQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + hasBin: true + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -10579,6 +11147,9 @@ packages: stream-to-promise@2.2.0: resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} + stream-to-string@1.2.1: + resolution: {integrity: sha512-WsvTDNF8UYs369Yko3pcdTducQtYpzEZeOV7cTuReyFvOoA9S/DLJ6sYK+xPafSPHhUMpaxiljKYnT6JSFztIA==} + streamx@2.25.0: resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} @@ -10752,6 +11323,13 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + sync-request@6.1.0: + resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} + engines: {node: '>=8.0.0'} + + sync-rpc@1.3.6: + resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + synckit@0.11.11: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -10806,6 +11384,10 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + then-request@6.0.2: + resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} + engines: {node: '>=6.0.0'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -10830,6 +11412,9 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tiny-set-immediate@1.0.2: + resolution: {integrity: sha512-EVbaM4zXFWS4CIqVoPzY7XIioQ5LU1p49AHizwPO1KyFyp/gxy5SA8mDmfDVl/2WLQiHgUL+esO6Ig+KhpUxUw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -10954,6 +11539,9 @@ packages: ts-morph@18.0.0: resolution: {integrity: sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==} + ts-morph@24.0.0: + resolution: {integrity: sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==} + ts-morph@27.0.2: resolution: {integrity: sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==} @@ -11134,6 +11722,9 @@ packages: typed-styles@0.0.7: resolution: {integrity: sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==} + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + typescript-eslint@7.18.0: resolution: {integrity: sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -11329,6 +11920,11 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). @@ -11345,6 +11941,9 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + validate-iri@1.0.1: + resolution: {integrity: sha512-gLXi7351CoyVVQw8XE5sgpYawRKatxE7kj/xmCxXOZS1kMdtcqC0ILIqLuVEVnAUQSL/evOGG3eQ+8VgbdnstA==} + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -11660,6 +12259,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -12488,6 +13090,10 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@bergos/jsonparse@1.4.2': + dependencies: + buffer: 6.0.3 + '@blueprintjs/colors@4.2.1': dependencies: tslib: 2.5.1 @@ -12624,34 +13230,279 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@cspotcode/source-map-support@0.8.1': + '@comunica/actor-abstract-mediatyped@4.5.0': dependencies: - '@jridgewell/trace-mapping': 0.3.9 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 - '@cucumber/ci-environment@13.0.0': {} + '@comunica/actor-abstract-parse@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + readable-stream: 4.7.0 - '@cucumber/cucumber-expressions@19.0.0': + '@comunica/actor-dereference-fallback@4.5.0': dependencies: - regexp-match-indices: 1.0.2 + '@comunica/bus-dereference': 4.5.0 + '@comunica/core': 4.5.0 + transitivePeerDependencies: + - encoding - '@cucumber/cucumber@12.7.0': + '@comunica/actor-dereference-file@4.5.0': dependencies: - '@cucumber/ci-environment': 13.0.0 - '@cucumber/cucumber-expressions': 19.0.0 - '@cucumber/gherkin': 38.0.0 - '@cucumber/gherkin-streams': 6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1) - '@cucumber/gherkin-utils': 11.0.0 - '@cucumber/html-formatter': 23.0.0(@cucumber/messages@32.0.1) - '@cucumber/junit-xml-formatter': 0.9.0(@cucumber/messages@32.0.1) - '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) - '@cucumber/messages': 32.0.1 - '@cucumber/pretty-formatter': 1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1) - '@cucumber/tag-expressions': 9.1.0 - assertion-error-formatter: 3.0.0 - capital-case: 1.0.4 - chalk: 4.1.2 - cli-table3: 0.6.5 - commander: 14.0.0 + '@comunica/bus-dereference': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-dereference-http@4.5.0': + dependencies: + '@comunica/bus-dereference': 4.5.0 + '@comunica/bus-http': 4.5.0 + '@comunica/core': 4.5.0 + '@jeswr/stream-to-string': 2.0.0 + relative-to-absolute-iri: 1.0.8 + transitivePeerDependencies: + - encoding + + '@comunica/actor-dereference-rdf-parse@4.5.0': + dependencies: + '@comunica/bus-dereference': 4.5.0 + '@comunica/bus-dereference-rdf': 4.5.0 + '@comunica/bus-rdf-parse': 4.5.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-http-fetch@4.5.0': + dependencies: + '@comunica/bus-http': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/mediatortype-time': 4.5.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-http-proxy@4.5.0': + dependencies: + '@comunica/bus-http': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/mediatortype-time': 4.5.0 + '@comunica/types': 4.5.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-html-microdata@4.5.0': + dependencies: + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + microdata-rdf-streaming-parser: 2.0.1 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-html-rdfa@4.5.0': + dependencies: + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + rdfa-streaming-parser: 2.0.1 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-html-script@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + '@rdfjs/types': 2.0.1 + readable-stream: 4.7.0 + relative-to-absolute-iri: 1.0.8 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-html@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + '@rdfjs/types': 2.0.1 + htmlparser2: 10.1.0 + readable-stream: 4.7.0 + + '@comunica/actor-rdf-parse-jsonld@4.5.0': + dependencies: + '@comunica/bus-http': 4.5.0 + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + '@jeswr/stream-to-string': 2.0.0 + jsonld-context-parser: 2.4.0 + jsonld-streaming-parser: 4.0.1 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-n3@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/types': 4.5.0 + n3: 1.26.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-rdfxml@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/context-entries': 4.5.0 + rdfxml-streaming-parser: 2.4.0 + transitivePeerDependencies: + - encoding + + '@comunica/actor-rdf-parse-shaclc@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/types': 4.5.0 + '@jeswr/stream-to-string': 2.0.0 + '@rdfjs/types': 2.0.1 + asynciterator: 3.10.0 + readable-stream: 4.7.0 + shaclc-parse: 1.4.3 + + '@comunica/actor-rdf-parse-xml-rdfa@4.5.0': + dependencies: + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/types': 4.5.0 + rdfa-streaming-parser: 2.0.1 + transitivePeerDependencies: + - encoding + + '@comunica/bus-dereference-rdf@4.5.0': + dependencies: + '@comunica/bus-dereference': 4.5.0 + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/core': 4.5.0 + '@rdfjs/types': 2.0.1 + transitivePeerDependencies: + - encoding + + '@comunica/bus-dereference@4.5.0': + dependencies: + '@comunica/actor-abstract-mediatyped': 4.5.0 + '@comunica/actor-abstract-parse': 4.5.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + readable-stream: 4.7.0 + transitivePeerDependencies: + - encoding + + '@comunica/bus-http@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + '@jeswr/stream-to-string': 2.0.0 + is-stream: 2.0.1 + readable-from-web: 1.0.0 + readable-stream-node-to-web: 1.0.1 + + '@comunica/bus-init@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + readable-stream: 4.7.0 + + '@comunica/bus-rdf-parse-html@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + '@rdfjs/types': 2.0.1 + + '@comunica/bus-rdf-parse@4.5.0': + dependencies: + '@comunica/actor-abstract-mediatyped': 4.5.0 + '@comunica/actor-abstract-parse': 4.5.0 + '@comunica/core': 4.5.0 + '@rdfjs/types': 2.0.1 + + '@comunica/config-query-sparql@4.4.0': {} + + '@comunica/context-entries@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + '@rdfjs/types': 2.0.1 + jsonld-context-parser: 2.4.0 + sparqlalgebrajs: 5.0.2 + transitivePeerDependencies: + - encoding + + '@comunica/core@4.5.0': + dependencies: + '@comunica/types': 4.5.0 + immutable: 5.1.6 + + '@comunica/mediator-combine-pipeline@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + '@comunica/types': 4.5.0 + + '@comunica/mediator-combine-union@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + + '@comunica/mediator-number@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + + '@comunica/mediator-race@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + + '@comunica/mediatortype-time@4.5.0': + dependencies: + '@comunica/core': 4.5.0 + + '@comunica/types@4.5.0': + dependencies: + '@rdfjs/types': 2.0.1 + '@types/yargs': 17.0.35 + asynciterator: 3.10.0 + lru-cache: 10.4.3 + sparqlalgebrajs: 5.0.2 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@cucumber/ci-environment@13.0.0': {} + + '@cucumber/cucumber-expressions@19.0.0': + dependencies: + regexp-match-indices: 1.0.2 + + '@cucumber/cucumber@12.7.0': + dependencies: + '@cucumber/ci-environment': 13.0.0 + '@cucumber/cucumber-expressions': 19.0.0 + '@cucumber/gherkin': 38.0.0 + '@cucumber/gherkin-streams': 6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1) + '@cucumber/gherkin-utils': 11.0.0 + '@cucumber/html-formatter': 23.0.0(@cucumber/messages@32.0.1) + '@cucumber/junit-xml-formatter': 0.9.0(@cucumber/messages@32.0.1) + '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) + '@cucumber/messages': 32.0.1 + '@cucumber/pretty-formatter': 1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1) + '@cucumber/tag-expressions': 9.1.0 + assertion-error-formatter: 3.0.0 + capital-case: 1.0.4 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 14.0.0 debug: 4.4.1(supports-color@8.1.1) error-stack-parser: 2.1.4 figures: 3.2.0 @@ -12746,6 +13597,20 @@ snapshots: '@cucumber/tag-expressions@9.1.0': {} + '@digitalbazaar/http-client@1.2.0(web-streams-polyfill@3.3.3)': + dependencies: + esm: 3.2.25 + ky: 0.25.1 + ky-universal: 0.8.2(ky@0.25.1)(web-streams-polyfill@3.3.3) + transitivePeerDependencies: + - domexception + - web-streams-polyfill + + '@digitalbazaar/http-client@4.3.0': + dependencies: + ky: 1.14.3 + undici: 6.25.0 + '@dnd-kit/accessibility@3.1.1(react@18.2.0)': dependencies: react: 18.2.0 @@ -13506,6 +14371,25 @@ snapshots: '@jcubic/lily@0.3.0': {} + '@jeswr/shacl2shex@1.5.1': + dependencies: + '@ldo/ldo': 0.0.1-alpha.29 + '@rdfjs/term-set': 1.1.0 + '@rdfjs/types': 2.0.1 + '@shexjs/neighborhood-rdfjs': 1.0.0-alpha.29 + '@shexjs/validator': 1.0.0-alpha.29 + '@shexjs/writer': 1.0.0-alpha.27 + commander: 14.0.3 + n3: 1.26.0 + rdf-dereference-store: 1.4.0 + rdf-namespaces: 1.17.0 + transitivePeerDependencies: + - encoding + + '@jeswr/stream-to-string@2.0.0': + dependencies: + event-emitter-promisify: 1.1.0 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -13527,6 +14411,133 @@ snapshots: '@juggle/resize-observer@3.4.0': {} + '@ldo/cli@1.0.0-alpha.51(web-streams-polyfill@3.3.3)': + dependencies: + '@jeswr/shacl2shex': 1.5.1 + '@ldo/ldo': 1.0.0-alpha.51 + '@ldo/schema-converter-shex': 1.0.0-alpha.51(web-streams-polyfill@3.3.3) + '@shexjs/parser': 1.0.0-alpha.28 + camelcase: 9.0.0 + child-process-promise: 2.2.1 + commander: 9.5.0 + ejs: 3.1.10 + loading-cli: 1.1.2 + prettier: 3.6.2 + prompts: 2.4.2 + rdf-dereference-store: 1.4.0 + rdf-namespaces: 1.17.0 + ts-morph: 24.0.0 + type-fest: 2.19.0 + transitivePeerDependencies: + - domexception + - encoding + - web-streams-polyfill + + '@ldo/dataset@0.0.1-alpha.24': + dependencies: + '@ldo/rdf-utils': 0.0.1-alpha.24 + '@rdfjs/dataset': 1.1.1 + buffer: 6.0.3 + readable-stream: 4.7.0 + + '@ldo/dataset@1.0.0-alpha.51': + dependencies: + '@ldo/rdf-utils': 1.0.0-alpha.51 + '@rdfjs/dataset': 1.1.1 + '@rdfjs/types': 1.1.2 + buffer: 6.0.3 + readable-stream: 4.7.0 + + '@ldo/jsonld-dataset-proxy@0.0.1-alpha.29': + dependencies: + '@ldo/rdf-utils': 0.0.1-alpha.24 + '@ldo/subscribable-dataset': 0.0.1-alpha.24 + '@rdfjs/data-model': 1.3.4 + '@rdfjs/dataset': 1.1.1 + jsonld2graphobject: 0.0.4 + transitivePeerDependencies: + - encoding + + '@ldo/jsonld-dataset-proxy@1.0.0-alpha.51': + dependencies: + '@ldo/dataset': 1.0.0-alpha.51 + '@ldo/rdf-utils': 1.0.0-alpha.51 + '@ldo/subscribable-dataset': 1.0.0-alpha.51 + '@rdfjs/types': 1.1.2 + jsonld2graphobject: 0.0.4 + transitivePeerDependencies: + - encoding + + '@ldo/ldo@0.0.1-alpha.29': + dependencies: + '@ldo/dataset': 0.0.1-alpha.24 + '@ldo/jsonld-dataset-proxy': 0.0.1-alpha.29 + '@ldo/subscribable-dataset': 0.0.1-alpha.24 + '@rdfjs/data-model': 1.3.4 + buffer: 6.0.3 + readable-stream: 4.7.0 + transitivePeerDependencies: + - encoding + + '@ldo/ldo@1.0.0-alpha.51': + dependencies: + '@ldo/dataset': 1.0.0-alpha.51 + '@ldo/jsonld-dataset-proxy': 1.0.0-alpha.51 + '@ldo/rdf-utils': 1.0.0-alpha.51 + '@ldo/subscribable-dataset': 1.0.0-alpha.51 + '@rdfjs/types': 1.1.2 + buffer: 6.0.3 + readable-stream: 4.7.0 + transitivePeerDependencies: + - encoding + + '@ldo/rdf-utils@0.0.1-alpha.24': + dependencies: + '@rdfjs/data-model': 1.3.4 + n3: 1.26.0 + rdf-string: 1.6.3 + + '@ldo/rdf-utils@1.0.0-alpha.51': + dependencies: + '@rdfjs/data-model': 1.3.4 + '@rdfjs/types': 1.1.2 + n3: 1.26.0 + rdf-string: 1.6.3 + + '@ldo/schema-converter-shex@1.0.0-alpha.51(web-streams-polyfill@3.3.3)': + dependencies: + '@ldo/jsonld-dataset-proxy': 1.0.0-alpha.51 + '@ldo/ldo': 1.0.0-alpha.51 + '@ldo/traverser-shexj': 1.0.0-alpha.51 + '@ldo/type-traverser': 1.0.0-alpha.51 + dts-dom: 3.6.0 + jsonld: 5.2.0(web-streams-polyfill@3.3.3) + jsonld2graphobject: 0.0.5 + transitivePeerDependencies: + - domexception + - encoding + - web-streams-polyfill + + '@ldo/subscribable-dataset@0.0.1-alpha.24': + dependencies: + '@ldo/dataset': 0.0.1-alpha.24 + '@ldo/rdf-utils': 0.0.1-alpha.24 + + '@ldo/subscribable-dataset@1.0.0-alpha.51': + dependencies: + '@ldo/dataset': 1.0.0-alpha.51 + '@ldo/rdf-utils': 1.0.0-alpha.51 + '@rdfjs/types': 1.1.2 + uuid: 11.1.0 + + '@ldo/traverser-shexj@1.0.0-alpha.51': + dependencies: + '@ldo/type-traverser': 1.0.0-alpha.51 + + '@ldo/type-traverser@1.0.0-alpha.51': + dependencies: + uuid: 8.3.2 + '@mapbox/node-pre-gyp@2.0.0': dependencies: consola: 3.4.2 @@ -15657,6 +16668,30 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@rdfjs/data-model@1.3.4': + dependencies: + '@rdfjs/types': 2.0.1 + + '@rdfjs/data-model@2.1.1': {} + + '@rdfjs/dataset@1.1.1': + dependencies: + '@rdfjs/data-model': 1.3.4 + + '@rdfjs/term-set@1.1.0': + dependencies: + '@rdfjs/to-ntriples': 2.0.0 + + '@rdfjs/to-ntriples@2.0.0': {} + + '@rdfjs/types@1.1.2': + dependencies: + '@types/node': 20.19.13 + + '@rdfjs/types@2.0.1': + dependencies: + '@types/node': 20.19.13 + '@react-aria/focus@3.21.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@react-aria/interactions': 3.27.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -15846,6 +16881,10 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@rubensworks/saxes@6.0.1': + dependencies: + xmlchars: 2.2.0 + '@rushstack/eslint-patch@1.12.0': {} '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': @@ -15880,6 +16919,66 @@ snapshots: domhandler: 5.0.3 selderee: 0.11.0 + '@shexjs/eval-simple-1err@1.0.0-alpha.29': + dependencies: + '@shexjs/eval-validator-api': 1.0.0-alpha.29 + '@shexjs/term': 1.0.0-alpha.27 + + '@shexjs/eval-threaded-nerr@1.0.0-alpha.29': + dependencies: + '@shexjs/eval-validator-api': 1.0.0-alpha.29 + '@shexjs/term': 1.0.0-alpha.27 + + '@shexjs/eval-validator-api@1.0.0-alpha.29': + dependencies: + '@shexjs/term': 1.0.0-alpha.27 + + '@shexjs/neighborhood-api@1.0.0-alpha.28': + dependencies: + '@shexjs/term': 1.0.0-alpha.27 + + '@shexjs/neighborhood-rdfjs@1.0.0-alpha.29': + dependencies: + '@shexjs/eval-validator-api': 1.0.0-alpha.29 + '@shexjs/term': 1.0.0-alpha.27 + + '@shexjs/parser@1.0.0-alpha.28': + dependencies: + '@shexjs/util': 1.0.0-alpha.28 + '@ts-jison/parser': 0.4.1-alpha.1 + + '@shexjs/term@1.0.0-alpha.27': + dependencies: + '@types/shexj': 2.1.7 + rdf-data-factory: 1.1.3 + relativize-url: 0.1.0 + + '@shexjs/util@1.0.0-alpha.28': + dependencies: + '@shexjs/term': 1.0.0-alpha.27 + '@shexjs/visitor': 1.0.0-alpha.27 + '@types/shexj': 2.1.7 + hierarchy-closure: 1.2.2 + sync-request: 6.1.0 + + '@shexjs/validator@1.0.0-alpha.29': + dependencies: + '@rdfjs/data-model': 2.1.1 + '@shexjs/eval-simple-1err': 1.0.0-alpha.29 + '@shexjs/eval-threaded-nerr': 1.0.0-alpha.29 + '@shexjs/eval-validator-api': 1.0.0-alpha.29 + '@shexjs/neighborhood-api': 1.0.0-alpha.28 + '@shexjs/term': 1.0.0-alpha.27 + '@shexjs/visitor': 1.0.0-alpha.27 + '@types/shexj': 2.1.7 + hierarchy-closure: 1.2.2 + + '@shexjs/visitor@1.0.0-alpha.27': {} + + '@shexjs/writer@1.0.0-alpha.27': + dependencies: + relativize-url: 0.1.0 + '@shikijs/core@3.23.0': dependencies: '@shikijs/types': 3.23.0 @@ -16704,6 +17803,17 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@ts-jison/common@0.4.1-alpha.1': {} + + '@ts-jison/lexer@0.4.1-alpha.1': + dependencies: + '@ts-jison/common': 0.4.1-alpha.1 + + '@ts-jison/parser@0.4.1-alpha.1': + dependencies: + '@ts-jison/common': 0.4.1-alpha.1 + '@ts-jison/lexer': 0.4.1-alpha.1 + '@ts-morph/common@0.11.1': dependencies: fast-glob: 3.3.3 @@ -16718,6 +17828,12 @@ snapshots: mkdirp: 2.1.6 path-browserify: 1.0.1 + '@ts-morph/common@0.25.0': + dependencies: + minimatch: 9.0.5 + path-browserify: 1.0.1 + tinyglobby: 0.2.16 + '@ts-morph/common@0.28.1': dependencies: minimatch: 10.1.1 @@ -16789,6 +17905,10 @@ snapshots: dependencies: '@types/tern': 0.23.9 + '@types/concat-stream@1.6.1': + dependencies: + '@types/node': 20.19.13 + '@types/cookie@0.6.0': {} '@types/core-js@2.5.8': {} @@ -16935,6 +18055,10 @@ snapshots: '@types/file-saver@2.0.5': {} + '@types/form-data@0.0.33': + dependencies: + '@types/node': 20.19.13 + '@types/geojson@7946.0.16': {} '@types/glob@7.2.0': @@ -16950,6 +18074,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/http-link-header@1.0.7': + dependencies: + '@types/node': 20.19.13 + '@types/inquirer@6.5.0': dependencies: '@types/through': 0.0.33 @@ -16971,6 +18099,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/jsonld@1.5.15': {} + '@types/katex@0.16.8': {} '@types/linkify-it@5.0.0': {} @@ -17004,6 +18134,11 @@ snapshots: '@types/ms@2.1.0': {} + '@types/n3@1.26.1': + dependencies: + '@rdfjs/types': 2.0.1 + '@types/node': 20.19.13 + '@types/nanoid@2.0.0': dependencies: '@types/node': 20.19.13 @@ -17017,6 +18152,8 @@ snapshots: '@types/node': 20.19.13 form-data: 4.0.4 + '@types/node@10.17.60': {} + '@types/node@18.19.124': dependencies: undici-types: 5.26.5 @@ -17029,10 +18166,14 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@8.10.66': {} + '@types/normalize-package-data@2.4.4': {} '@types/prop-types@15.7.15': {} + '@types/qs@6.15.1': {} + '@types/raf@3.4.3': {} '@types/react-dom@18.2.17': @@ -17057,14 +18198,29 @@ snapshots: dependencies: csstype: 3.1.3 + '@types/readable-stream@2.3.15': + dependencies: + '@types/node': 20.19.13 + safe-buffer: 5.1.2 + + '@types/readable-stream@4.0.23': + dependencies: + '@types/node': 20.19.13 + '@types/scheduler@0.16.8': {} '@types/semver@7.7.1': {} + '@types/shexj@2.1.7': {} + '@types/showdown@2.0.6': {} '@types/sizzle@2.3.10': {} + '@types/sparqljs@3.1.12': + dependencies: + '@rdfjs/types': 2.0.1 + '@types/statuses@2.0.6': {} '@types/tern@0.23.9': @@ -17092,6 +18248,12 @@ snapshots: '@types/uuid@9.0.8': {} + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -17955,6 +19117,8 @@ snapshots: dependencies: printable-characters: 1.0.42 + asap@2.0.6: {} + assertion-error-formatter@3.0.0: dependencies: diff: 4.0.2 @@ -17991,6 +19155,10 @@ snapshots: async@3.2.6: {} + asynciterator@3.10.0: + dependencies: + tiny-set-immediate: 1.0.2 + asynckit@0.4.0: {} at-least-node@1.0.0: {} @@ -18180,8 +19348,14 @@ snapshots: camelcase-css@2.0.1: {} + camelcase@9.0.0: {} + caniuse-lite@1.0.30001739: {} + canonicalize@1.0.8: {} + + canonicalize@2.1.0: {} + canvas-size@1.2.6: {} capital-case@1.0.4: @@ -18190,6 +19364,8 @@ snapshots: tslib: 2.5.1 upper-case-first: 2.0.2 + caseless@0.12.0: {} + ccount@1.1.0: {} ccount@2.0.1: {} @@ -18269,6 +19445,12 @@ snapshots: '@chevrotain/utils': 11.1.2 lodash-es: 4.17.23 + child-process-promise@2.2.1: + dependencies: + cross-spawn: 4.0.2 + node-version: 1.2.0 + promise-polyfill: 6.1.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -18410,6 +19592,8 @@ snapshots: colorette@2.0.20: {} + colors-cli@1.0.33: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -18447,6 +19631,13 @@ snapshots: concat-map@0.0.1: {} + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + confbox@0.1.8: {} consola@3.4.2: {} @@ -18527,6 +19718,17 @@ snapshots: crelt@1.0.6: {} + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@4.0.2: + dependencies: + lru-cache: 4.1.5 + which: 1.3.1 + cross-spawn@6.0.6: dependencies: nice-try: 1.0.5 @@ -18781,6 +19983,8 @@ snapshots: data-uri-to-buffer@2.0.2: {} + data-uri-to-buffer@3.0.1: {} + data-uri-to-buffer@4.0.1: {} data-uri-to-buffer@6.0.2: {} @@ -18988,6 +20192,8 @@ snapshots: dotenv@16.6.1: {} + dts-dom@3.6.0: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -19012,6 +20218,10 @@ snapshots: ee-first@1.1.1: {} + ejs@3.1.10: + dependencies: + jake: 10.9.4 + electron-to-chromium@1.5.214: {} emoji-regex@10.6.0: {} @@ -19034,6 +20244,8 @@ snapshots: entities@6.0.1: {} + entities@7.0.1: {} + environment@1.1.0: {} error-ex@1.3.2: @@ -19651,6 +20863,8 @@ snapshots: etag@1.8.1: {} + event-emitter-promisify@1.1.0: {} + event-target-shim@5.0.1: {} eventemitter3@4.0.7: {} @@ -19665,6 +20879,8 @@ snapshots: transitivePeerDependencies: - bare-abort-controller + events@3.3.0: {} + eventsource-parser@3.0.6: {} eventsource@3.0.7: @@ -19872,6 +21088,8 @@ snapshots: optionalDependencies: picomatch: 4.0.4 + fetch-blob@2.1.2: {} + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -19891,6 +21109,10 @@ snapshots: file-uri-to-path@1.0.0: {} + filelist@1.0.6: + dependencies: + minimatch: 5.1.6 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -19950,6 +21172,15 @@ snapshots: form-data-encoder@1.7.2: {} + form-data@2.5.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + safe-buffer: 5.2.1 + form-data@4.0.4: dependencies: asynckit: 0.4.0 @@ -20055,6 +21286,8 @@ snapshots: get-own-enumerable-keys@1.0.0: {} + get-port@3.2.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -20408,6 +21641,8 @@ snapshots: headers-polyfill@4.0.3: {} + hierarchy-closure@1.2.2: {} + hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 @@ -20440,6 +21675,13 @@ snapshots: html-void-elements@3.0.0: {} + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + htmlparser2@8.0.2: dependencies: domelementtype: 2.3.0 @@ -20447,6 +21689,13 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 + http-basic@8.1.3: + dependencies: + caseless: 0.12.0 + concat-stream: 1.6.2 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + http-errors@1.7.3: dependencies: depd: 1.1.2 @@ -20463,6 +21712,8 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-link-header@1.1.3: {} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 @@ -20478,6 +21729,10 @@ snapshots: transitivePeerDependencies: - supports-color + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -20542,6 +21797,8 @@ snapshots: immediate@3.0.6: {} + immutable@5.1.6: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -20892,6 +22149,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + jiti@1.21.7: {} jju@1.4.0: {} @@ -20997,6 +22260,71 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonld-context-parser@2.4.0: + dependencies: + '@types/http-link-header': 1.0.7 + '@types/node': 18.19.124 + cross-fetch: 3.2.0 + http-link-header: 1.1.3 + relative-to-absolute-iri: 1.0.8 + transitivePeerDependencies: + - encoding + + jsonld-context-parser@3.1.0: + dependencies: + '@types/http-link-header': 1.0.7 + '@types/node': 18.19.124 + http-link-header: 1.1.3 + relative-to-absolute-iri: 1.0.8 + + jsonld-streaming-parser@4.0.1: + dependencies: + '@bergos/jsonparse': 1.4.2 + '@rdfjs/types': 2.0.1 + '@types/http-link-header': 1.0.7 + '@types/readable-stream': 4.0.23 + buffer: 6.0.3 + canonicalize: 1.0.8 + http-link-header: 1.1.3 + jsonld-context-parser: 3.1.0 + rdf-data-factory: 1.1.3 + readable-stream: 4.7.0 + + jsonld2graphobject@0.0.4: + dependencies: + '@rdfjs/types': 1.1.2 + '@types/jsonld': 1.5.15 + jsonld-context-parser: 2.4.0 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + + jsonld2graphobject@0.0.5: + dependencies: + '@rdfjs/types': 1.1.2 + '@types/jsonld': 1.5.15 + jsonld-context-parser: 2.4.0 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + + jsonld@5.2.0(web-streams-polyfill@3.3.3): + dependencies: + '@digitalbazaar/http-client': 1.2.0(web-streams-polyfill@3.3.3) + canonicalize: 1.0.8 + lru-cache: 6.0.0 + rdf-canonize: 3.4.0 + transitivePeerDependencies: + - domexception + - web-streams-polyfill + + jsonld@9.0.0: + dependencies: + '@digitalbazaar/http-client': 4.3.0 + canonicalize: 2.1.0 + lru-cache: 6.0.0 + rdf-canonize: 5.0.0 + jsonlines@0.1.1: {} jsx-ast-utils@3.3.5: @@ -21039,6 +22367,20 @@ snapshots: dependencies: seed-random: 2.2.0 + ky-universal@0.8.2(ky@0.25.1)(web-streams-polyfill@3.3.3): + dependencies: + abort-controller: 3.0.0 + ky: 0.25.1 + node-fetch: 3.0.0-beta.9 + optionalDependencies: + web-streams-polyfill: 3.3.3 + transitivePeerDependencies: + - domexception + + ky@0.25.1: {} + + ky@1.14.3: {} + langium@4.2.1: dependencies: chevrotain: 11.1.2 @@ -21104,6 +22446,10 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.2 + loading-cli@1.1.2: + dependencies: + colors-cli: 1.0.33 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -21190,6 +22536,11 @@ snapshots: lru-cache@11.2.1: {} + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -21485,6 +22836,14 @@ snapshots: content-type: 1.0.4 raw-body: 2.4.1 + microdata-rdf-streaming-parser@2.0.1: + dependencies: + '@rdfjs/types': 2.0.1 + htmlparser2: 8.0.2 + rdf-data-factory: 1.1.3 + readable-stream: 4.7.0 + relative-to-absolute-iri: 1.0.8 + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -21906,6 +23265,11 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + n3@1.26.0: + dependencies: + buffer: 6.0.3 + readable-stream: 4.7.0 + nanoevents@7.0.1: {} nanoid@2.0.4: {} @@ -22049,6 +23413,13 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-fetch@3.0.0-beta.9: + dependencies: + data-uri-to-buffer: 3.0.1 + fetch-blob: 2.1.2 + transitivePeerDependencies: + - domexception + node-fetch@3.3.2: dependencies: data-uri-to-buffer: 4.0.1 @@ -22073,6 +23444,8 @@ snapshots: node-releases@2.0.19: {} + node-version@1.2.0: {} + nopt@8.1.0: dependencies: abbrev: 3.0.1 @@ -22378,6 +23751,8 @@ snapshots: dependencies: callsites: 3.1.0 + parse-cache-control@1.0.1: {} + parse-entities@2.0.0: dependencies: character-entities: 1.2.4 @@ -22655,8 +24030,18 @@ snapshots: process-nextick-args@2.0.1: {} + process@0.11.10: {} + progress@2.0.3: {} + promise-polyfill@1.1.6: {} + + promise-polyfill@6.1.0: {} + + promise@8.3.0: + dependencies: + asap: 2.0.6 + promisepipe@3.0.0: {} prompts@2.4.2: @@ -22829,6 +24214,8 @@ snapshots: proxy-from-env@1.1.0: {} + pseudomap@1.0.2: {} + psl@1.15.0: dependencies: punycode: 2.3.1 @@ -22942,6 +24329,144 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 + rdf-canonize@3.4.0: + dependencies: + setimmediate: 1.0.5 + + rdf-canonize@5.0.0: + dependencies: + setimmediate: 1.0.5 + + rdf-data-factory@1.1.3: + dependencies: + '@rdfjs/types': 1.1.2 + + rdf-data-factory@2.0.2: + dependencies: + '@rdfjs/types': 2.0.1 + + rdf-dereference-store@1.4.0: + dependencies: + '@rdfjs/types': 1.1.2 + '@types/n3': 1.26.1 + asynciterator: 3.10.0 + event-emitter-promisify: 1.1.0 + n3: 1.26.0 + rdf-dereference: 4.0.0 + rdf-parse: 4.0.0 + readable-stream: 4.7.0 + transitivePeerDependencies: + - encoding + + rdf-dereference@4.0.0: + dependencies: + '@comunica/actor-dereference-fallback': 4.5.0 + '@comunica/actor-dereference-file': 4.5.0 + '@comunica/actor-dereference-http': 4.5.0 + '@comunica/actor-dereference-rdf-parse': 4.5.0 + '@comunica/actor-http-fetch': 4.5.0 + '@comunica/actor-http-proxy': 4.5.0 + '@comunica/actor-rdf-parse-html': 4.5.0 + '@comunica/actor-rdf-parse-html-microdata': 4.5.0 + '@comunica/actor-rdf-parse-html-rdfa': 4.5.0 + '@comunica/actor-rdf-parse-html-script': 4.5.0 + '@comunica/actor-rdf-parse-jsonld': 4.5.0 + '@comunica/actor-rdf-parse-n3': 4.5.0 + '@comunica/actor-rdf-parse-rdfxml': 4.5.0 + '@comunica/actor-rdf-parse-shaclc': 4.5.0 + '@comunica/actor-rdf-parse-xml-rdfa': 4.5.0 + '@comunica/bus-dereference': 4.5.0 + '@comunica/bus-dereference-rdf': 4.5.0 + '@comunica/bus-http': 4.5.0 + '@comunica/bus-init': 4.5.0 + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/config-query-sparql': 4.4.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/mediator-combine-pipeline': 4.5.0 + '@comunica/mediator-combine-union': 4.5.0 + '@comunica/mediator-number': 4.5.0 + '@comunica/mediator-race': 4.5.0 + '@rdfjs/types': 2.0.1 + rdf-data-factory: 1.1.3 + rdf-string: 1.6.3 + stream-to-string: 1.2.1 + transitivePeerDependencies: + - encoding + + rdf-isomorphic@2.0.1: + dependencies: + imurmurhash: 0.1.4 + rdf-string: 2.0.1 + rdf-terms: 2.0.0 + + rdf-namespaces@1.17.0: {} + + rdf-parse@4.0.0: + dependencies: + '@comunica/actor-http-fetch': 4.5.0 + '@comunica/actor-http-proxy': 4.5.0 + '@comunica/actor-rdf-parse-html': 4.5.0 + '@comunica/actor-rdf-parse-html-microdata': 4.5.0 + '@comunica/actor-rdf-parse-html-rdfa': 4.5.0 + '@comunica/actor-rdf-parse-html-script': 4.5.0 + '@comunica/actor-rdf-parse-jsonld': 4.5.0 + '@comunica/actor-rdf-parse-n3': 4.5.0 + '@comunica/actor-rdf-parse-rdfxml': 4.5.0 + '@comunica/actor-rdf-parse-shaclc': 4.5.0 + '@comunica/actor-rdf-parse-xml-rdfa': 4.5.0 + '@comunica/bus-http': 4.5.0 + '@comunica/bus-init': 4.5.0 + '@comunica/bus-rdf-parse': 4.5.0 + '@comunica/bus-rdf-parse-html': 4.5.0 + '@comunica/config-query-sparql': 4.4.0 + '@comunica/context-entries': 4.5.0 + '@comunica/core': 4.5.0 + '@comunica/mediator-combine-pipeline': 4.5.0 + '@comunica/mediator-combine-union': 4.5.0 + '@comunica/mediator-number': 4.5.0 + '@comunica/mediator-race': 4.5.0 + '@rdfjs/types': 2.0.1 + rdf-data-factory: 1.1.3 + readable-stream: 4.7.0 + stream-to-string: 1.2.1 + transitivePeerDependencies: + - encoding + + rdf-string@1.6.3: + dependencies: + '@rdfjs/types': 2.0.1 + rdf-data-factory: 1.1.3 + + rdf-string@2.0.1: + dependencies: + rdf-data-factory: 2.0.2 + + rdf-terms@2.0.0: + dependencies: + rdf-data-factory: 2.0.2 + rdf-string: 2.0.1 + + rdfa-streaming-parser@2.0.1: + dependencies: + '@rdfjs/types': 2.0.1 + htmlparser2: 8.0.2 + rdf-data-factory: 1.1.3 + readable-stream: 4.7.0 + relative-to-absolute-iri: 1.0.8 + + rdfxml-streaming-parser@2.4.0: + dependencies: + '@rdfjs/types': 2.0.1 + '@rubensworks/saxes': 6.0.1 + '@types/readable-stream': 2.3.15 + buffer: 6.0.3 + rdf-data-factory: 1.1.3 + readable-stream: 4.7.0 + relative-to-absolute-iri: 1.0.8 + validate-iri: 1.0.1 + react-charts@3.0.0-beta.57(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@babel/runtime': 7.28.3 @@ -23179,6 +24704,13 @@ snapshots: parse-json: 5.2.0 type-fest: 0.6.0 + readable-from-web@1.0.0: + dependencies: + '@types/readable-stream': 4.0.23 + readable-stream: 4.7.0 + + readable-stream-node-to-web@1.0.1: {} + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -23195,6 +24727,14 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + readdir-glob@1.1.3: dependencies: minimatch: 5.1.6 @@ -23341,6 +24881,10 @@ snapshots: transitivePeerDependencies: - supports-color + relative-to-absolute-iri@1.0.8: {} + + relativize-url@0.1.0: {} + remark-frontmatter@5.0.0: dependencies: '@types/mdast': 4.0.4 @@ -23798,6 +25342,11 @@ snapshots: setprototypeof@1.2.0: {} + shaclc-parse@1.4.3: + dependencies: + '@rdfjs/types': 2.0.1 + n3: 1.26.0 + shadcn@2.10.0(@types/node@20.19.13)(typescript@5.5.4): dependencies: '@antfu/ni': 23.3.1 @@ -24029,6 +25578,21 @@ snapshots: space-separated-tokens@2.0.2: {} + sparqlalgebrajs@5.0.2: + dependencies: + '@types/sparqljs': 3.1.12 + fast-deep-equal: 3.1.3 + minimist: 1.2.8 + rdf-data-factory: 2.0.2 + rdf-isomorphic: 2.0.1 + rdf-string: 2.0.1 + rdf-terms: 2.0.0 + sparqljs: 3.7.4 + + sparqljs@3.7.4: + dependencies: + rdf-data-factory: 1.1.3 + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -24097,6 +25661,10 @@ snapshots: end-of-stream: 1.1.0 stream-to-array: 2.3.0 + stream-to-string@1.2.1: + dependencies: + promise-polyfill: 1.1.6 + streamx@2.25.0: dependencies: events-universal: 1.0.1 @@ -24299,6 +25867,16 @@ snapshots: symbol-tree@3.2.4: {} + sync-request@6.1.0: + dependencies: + http-response-object: 3.0.2 + sync-rpc: 1.3.6 + then-request: 6.0.2 + + sync-rpc@1.3.6: + dependencies: + get-port: 3.2.0 + synckit@0.11.11: dependencies: '@pkgr/core': 0.2.9 @@ -24389,6 +25967,20 @@ snapshots: text-table@0.2.0: {} + then-request@6.0.2: + dependencies: + '@types/concat-stream': 1.6.1 + '@types/form-data': 0.0.33 + '@types/node': 8.10.66 + '@types/qs': 6.15.1 + caseless: 0.12.0 + concat-stream: 1.6.2 + form-data: 2.5.5 + http-basic: 8.1.3 + http-response-object: 3.0.2 + promise: 8.3.0 + qs: 6.15.1 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -24409,6 +26001,8 @@ snapshots: tiny-invariant@1.3.3: {} + tiny-set-immediate@1.0.2: {} + tinybench@2.9.0: {} tinycolor2@1.6.0: {} @@ -24557,6 +26151,11 @@ snapshots: '@ts-morph/common': 0.19.0 code-block-writer: 12.0.0 + ts-morph@24.0.0: + dependencies: + '@ts-morph/common': 0.25.0 + code-block-writer: 13.0.3 + ts-morph@27.0.2: dependencies: '@ts-morph/common': 0.28.1 @@ -24751,6 +26350,8 @@ snapshots: typed-styles@0.0.7: {} + typedarray@0.0.6: {} + typescript-eslint@7.18.0(eslint@8.57.1)(typescript@5.5.4): dependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4) @@ -25003,6 +26604,8 @@ snapshots: uuid@11.1.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} uuidv7@1.1.0: {} @@ -25015,6 +26618,8 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + validate-iri@1.0.1: {} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -25333,6 +26938,8 @@ snapshots: y18n@5.0.8: {} + yallist@2.1.2: {} + yallist@3.1.1: {} yallist@4.0.0: {} From 516869f1330989d4720daaf92c0138967c9a1a89 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Wed, 3 Jun 2026 13:58:34 -0400 Subject: [PATCH 06/41] LDO shapes, v1 --- .../app/utils/conversion/fromJsonLd.ts | 135 +++++ .../utils/conversion/ldo/dgBase.context.ts | 302 ++++++++++ .../app/utils/conversion/ldo/dgBase.schema.ts | 526 ++++++++++++++++++ .../utils/conversion/ldo/dgBase.shapeTypes.ts | 94 ++++ .../utils/conversion/ldo/dgBase.typings.ts | 148 +++++ .../app/utils/conversion/shapes/dgBase.shex | 88 +++ .../test/integration/parseJsonLd.test.ts | 242 ++++++++ 7 files changed, 1535 insertions(+) create mode 100644 apps/website/app/utils/conversion/fromJsonLd.ts create mode 100644 apps/website/app/utils/conversion/ldo/dgBase.context.ts create mode 100644 apps/website/app/utils/conversion/ldo/dgBase.schema.ts create mode 100644 apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts create mode 100644 apps/website/app/utils/conversion/ldo/dgBase.typings.ts create mode 100644 apps/website/app/utils/conversion/shapes/dgBase.shex create mode 100644 apps/website/test/integration/parseJsonLd.test.ts diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts new file mode 100644 index 000000000..4286d0064 --- /dev/null +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -0,0 +1,135 @@ +import { namedNode } from "@ldo/rdf-utils"; +import { parseRdf } from "@ldo/ldo"; +import { toRDF, type JsonLdDocument } from "jsonld"; +import { + ContainerProfileShapeType, + ContentProfileShapeType, + NodeSchemaProfileShapeType, + NodeInstanceProfileShapeType, + RelationInstanceProfileShapeType, + RelationTripleDefProfileShapeType, + RelationDefProfileShapeType, +} from "./ldo/dgBase.shapeTypes"; +import type { + ContainerProfile, + ContentProfile, + NodeSchemaProfile, + NodeInstanceProfile, + RelationInstanceProfile, + RelationTripleDefProfile, + RelationDefProfile, +} from "./ldo/dgBase.typings"; + +type ParseResult = + | ContainerProfile + | ContentProfile + | NodeSchemaProfile + | NodeInstanceProfile + | RelationInstanceProfile + | RelationTripleDefProfile + | RelationDefProfile; + +const typePredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; +const nodeSchemaType = "https://discoursegraphs.com/schema/dg_base#NodeSchema"; +const relationDefType = + "https://discoursegraphs.com/schema/dg_base#RelationDef"; +const domainPredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#domain"; +const sourcePredicate = "https://discoursegraphs.com/schema/dg_base#source"; +const contentPredicate = "http://rdfs.org/sioc/ns#content"; +const descriptionPredicate = "http://purl.org/dc/elements/1.1/description"; +const containerType = "http://rdfs.org/sioc/ns#Container"; + +export const parseJsonLd = async ( + data: JsonLdDocument, + baseIRI: string, +): Promise => { + const asQuads = (await toRDF(data, { + format: "application/n-quads", + })) as string; + const ldoDataset = await parseRdf(asQuads, { + baseIRI, + }); + const subjects = new Set(ldoDataset.toArray().map((q) => q.subject.value)); + const result: ParseResult[] = []; + const typeMap: Record = {}; + for (const q of ldoDataset.match(null, namedNode(typePredicate)).toArray()) { + const s = q.subject.value; + if (typeMap[s]) typeMap[s].push(q.object.value); + else typeMap[s] = [q.object.value]; + } + for (const subject of subjects) { + const types = new Set(typeMap[subject]); + if (types.has(containerType)) { + result.push( + ldoDataset.usingType(ContainerProfileShapeType).fromSubject(subject), + ); + continue; + } + if (types.has(nodeSchemaType)) { + result.push( + ldoDataset.usingType(NodeSchemaProfileShapeType).fromSubject(subject), + ); + continue; + } + if (types.has(relationDefType)) { + if (ldoDataset.match(namedNode(subject), namedNode(domainPredicate)).size) + result.push( + ldoDataset + .usingType(RelationTripleDefProfileShapeType) + .fromSubject(subject), + ); + else + result.push( + ldoDataset + .usingType(RelationDefProfileShapeType) + .fromSubject(subject), + ); + continue; + } + if ( + ldoDataset.match(namedNode(subject), namedNode(contentPredicate)).size + ) { + result.push( + ldoDataset.usingType(ContentProfileShapeType).fromSubject(subject), + ); + continue; + } + // happy path: The types are there + const typesOfTypes = new Set( + (typeMap[subject] || []).map((t) => typeMap[t] || []).flat(), + ); + if (typesOfTypes.has(relationDefType)) { + result.push( + ldoDataset + .usingType(RelationInstanceProfileShapeType) + .fromSubject(subject), + ); + continue; + } + if (typesOfTypes.has(nodeSchemaType)) { + result.push( + ldoDataset.usingType(NodeInstanceProfileShapeType).fromSubject(subject), + ); + continue; + } + // otherwise use heuristics + if (ldoDataset.match(namedNode(subject), namedNode(sourcePredicate)).size) { + result.push( + ldoDataset + .usingType(RelationInstanceProfileShapeType) + .fromSubject(subject), + ); + continue; + } + if ( + ldoDataset.match(namedNode(subject), namedNode(descriptionPredicate)).size + ) { + result.push( + ldoDataset.usingType(NodeInstanceProfileShapeType).fromSubject(subject), + ); + continue; + } + console.error("Could not interpret ", subject); + } + return result; +}; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts new file mode 100644 index 000000000..8a41a5885 --- /dev/null +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -0,0 +1,302 @@ +import type { LdoJsonldContext } from "@ldo/ldo"; + +/** + * ============================================================================= + * dgBaseContext: JSONLD Context for dgBase + * ============================================================================= + */ +export const dgBaseContext: LdoJsonldContext = { + type: { + "@id": "@type", + "@isCollection": true, + }, + Container: { + "@id": "http://rdfs.org/sioc/ns#Container", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + containerOf: { + "@id": "http://rdfs.org/sioc/ns#container_of", + "@type": "@id", + "@isCollection": true, + }, + }, + }, + containerOf: { + "@id": "http://rdfs.org/sioc/ns#container_of", + "@type": "@id", + "@isCollection": true, + }, + Item: { + "@id": "http://rdfs.org/sioc/ns#Item", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + }, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + NodeSchema: { + "@id": "https://discoursegraphs.com/schema/dg_base#NodeSchema", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + label: { + "@id": "http://www.w3.org/2000/01/rdf-schema#label", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + subClassOf: { + "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@type": "@id", + "@isCollection": true, + }, + }, + }, + label: { + "@id": "http://www.w3.org/2000/01/rdf-schema#label", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + subClassOf: { + "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@type": "@id", + "@isCollection": true, + }, + NodeInstance: { + "@id": "https://discoursegraphs.com/schema/dg_base#NodeInstance", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + title: { + "@id": "http://purl.org/dc/elements/1.1/title", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + description: { + "@id": "http://purl.org/dc/elements/1.1/description", + "@type": "@id", + }, + }, + }, + title: { + "@id": "http://purl.org/dc/elements/1.1/title", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + description: { + "@id": "http://purl.org/dc/elements/1.1/description", + "@type": "@id", + }, + Content: { + "@id": "https://discoursegraphs.com/schema/dg_base#Content", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + format: { + "@id": "http://purl.org/dc/elements/1.1/format", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + content: { + "@id": "http://rdfs.org/sioc/ns#content", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + }, + }, + format: { + "@id": "http://purl.org/dc/elements/1.1/format", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + content: { + "@id": "http://rdfs.org/sioc/ns#content", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + RelationDef: { + "@id": "https://discoursegraphs.com/schema/dg_base#RelationDef", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + subClassOf: { + "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + label: { + "@id": "http://www.w3.org/2000/01/rdf-schema#label", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + }, + }, + ObjectProperty: "http://www.w3.org/2002/07/owl#ObjectProperty", + RelationInstance: { + "@id": "https://discoursegraphs.com/schema/dg_base#RelationInstance", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + source: { + "@id": "https://discoursegraphs.com/schema/dg_base#source", + "@type": "@id", + }, + destination: { + "@id": "https://discoursegraphs.com/schema/dg_base#destination", + "@type": "@id", + }, + }, + }, + RelationTripleDef: { + "@id": "https://discoursegraphs.com/schema/dg_base#RelationTripleDef", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + subClassOf: { + "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@isCollection": true, + }, + hasContainer: { + "@id": "http://rdfs.org/sioc/ns#has_container", + "@type": "@id", + }, + creator: { + "@id": "http://purl.org/dc/elements/1.1/creator", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + date: { + "@id": "http://purl.org/dc/elements/1.1/date", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + modified: { + "@id": "http://purl.org/dc/elements/1.1/modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime", + }, + domain: { + "@id": "http://www.w3.org/2000/01/rdf-schema#domain", + "@type": "@id", + }, + range: { + "@id": "http://www.w3.org/2000/01/rdf-schema#range", + "@type": "@id", + }, + }, + }, + domain: { + "@id": "http://www.w3.org/2000/01/rdf-schema#domain", + "@type": "@id", + }, + range: { + "@id": "http://www.w3.org/2000/01/rdf-schema#range", + "@type": "@id", + }, + source: { + "@id": "https://discoursegraphs.com/schema/dg_base#source", + "@type": "@id", + }, + destination: { + "@id": "https://discoursegraphs.com/schema/dg_base#destination", + "@type": "@id", + }, +}; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts new file mode 100644 index 000000000..62c77621d --- /dev/null +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -0,0 +1,526 @@ +import type { Schema } from "shexj"; + +/** + * ============================================================================= + * dgBaseSchema: ShexJ Schema for dgBase + * ============================================================================= + */ +export const dgBaseSchema: Schema = { + type: "Schema", + shapes: [ + { + id: "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://rdfs.org/sioc/ns#Container"], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#container_of", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ItemProfile", + min: 0, + max: -1, + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#ItemProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://rdfs.org/sioc/ns#Item"], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "https://discoursegraphs.com/schema/dg_base#NodeSchema", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + min: 0, + max: -1, + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#NodeInstanceProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "https://discoursegraphs.com/schema/dg_base#NodeInstance", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/title", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/description", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContentProfile", + min: 0, + max: 1, + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#RelationDefProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "https://discoursegraphs.com/schema/dg_base#RelationDef", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://rdfs.org/sioc/ns#Item", + "http://www.w3.org/2002/07/owl#ObjectProperty", + "https://discoursegraphs.com/schema/dg_base#RelationInstance", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#RelationTripleDefProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "https://discoursegraphs.com/schema/dg_base#RelationTripleDef", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/2002/07/owl#ObjectProperty", + "https://discoursegraphs.com/schema/dg_base#RelationInstance", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#domain", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#range", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#RelationInstanceProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "https://discoursegraphs.com/schema/dg_base#RelationInstance", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#has_container", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/creator", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/date", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/modified", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#dateTime", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "https://discoursegraphs.com/schema/dg_base#source", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#NodeInstanceProfile", + }, + { + type: "TripleConstraint", + predicate: + "https://discoursegraphs.com/schema/dg_base#destination", + valueExpr: + "https://discoursegraphs.com/schema/dg_base#NodeInstanceProfile", + }, + ], + }, + }, + }, + { + id: "https://discoursegraphs.com/schema/dg_base#ContentProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["https://discoursegraphs.com/schema/dg_base#Content"], + }, + }, + { + type: "TripleConstraint", + predicate: "http://purl.org/dc/elements/1.1/format", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#content", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + }, + ], + }, + }, + }, + ], +}; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts new file mode 100644 index 000000000..26aefc0da --- /dev/null +++ b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts @@ -0,0 +1,94 @@ +import type { ShapeType } from "@ldo/ldo"; +import { dgBaseSchema } from "./dgBase.schema"; +import { dgBaseContext } from "./dgBase.context"; +import type { + ContainerProfile, + ItemProfile, + NodeSchemaProfile, + NodeInstanceProfile, + RelationDefProfile, + RelationTripleDefProfile, + RelationInstanceProfile, + ContentProfile, +} from "./dgBase.typings"; + +/** + * ============================================================================= + * LDO ShapeTypes dgBase + * ============================================================================= + */ + +/** + * ContainerProfile ShapeType + */ +export const ContainerProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + context: dgBaseContext, +}; + +/** + * ItemProfile ShapeType + */ +export const ItemProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#ItemProfile", + context: dgBaseContext, +}; + +/** + * NodeSchemaProfile ShapeType + */ +export const NodeSchemaProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + context: dgBaseContext, +}; + +/** + * NodeInstanceProfile ShapeType + */ +export const NodeInstanceProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#NodeInstanceProfile", + context: dgBaseContext, +}; + +/** + * RelationDefProfile ShapeType + */ +export const RelationDefProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#RelationDefProfile", + context: dgBaseContext, +}; + +/** + * RelationTripleDefProfile ShapeType + */ +export const RelationTripleDefProfileShapeType: ShapeType = + { + schema: dgBaseSchema, + shape: + "https://discoursegraphs.com/schema/dg_base#RelationTripleDefProfile", + context: dgBaseContext, + }; + +/** + * RelationInstanceProfile ShapeType + */ +export const RelationInstanceProfileShapeType: ShapeType = + { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#RelationInstanceProfile", + context: dgBaseContext, + }; + +/** + * ContentProfile ShapeType + */ +export const ContentProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#ContentProfile", + context: dgBaseContext, +}; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts new file mode 100644 index 000000000..cd469cbe8 --- /dev/null +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -0,0 +1,148 @@ +import type { LdoJsonldContext, LdSet } from "@ldo/ldo"; + +/** + * ============================================================================= + * Typescript Typings for dgBase + * ============================================================================= + */ + +/** + * ContainerProfile Type + */ +export interface ContainerProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "Container"; + }>; + containerOf?: LdSet; +} + +/** + * ItemProfile Type + */ +export interface ItemProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "Item"; + }>; + hasContainer?: ContainerProfile; + date?: string; + modified?: string; + creator?: string; +} + +/** + * NodeSchemaProfile Type + */ +export interface NodeSchemaProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "NodeSchema"; + }>; + hasContainer?: ContainerProfile; + creator?: string; + date?: string; + modified?: string; + label: string; + subClassOf?: LdSet; +} + +/** + * NodeInstanceProfile Type + */ +export interface NodeInstanceProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "NodeInstance"; + }>; + hasContainer?: ContainerProfile; + creator?: string; + date?: string; + modified?: string; + title?: string; + description?: ContentProfile; +} + +/** + * RelationDefProfile Type + */ +export interface RelationDefProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "RelationDef"; + }>; + subClassOf: + | { + "@id": "Item"; + } + | { + "@id": "ObjectProperty"; + } + | { + "@id": "RelationInstance"; + }; + hasContainer?: ContainerProfile; + creator?: string; + date?: string; + modified?: string; + label: string; +} + +/** + * RelationTripleDefProfile Type + */ +export interface RelationTripleDefProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "RelationTripleDef"; + }>; + subClassOf: + | { + "@id": "ObjectProperty"; + } + | { + "@id": "RelationInstance"; + }; + hasContainer?: ContainerProfile; + creator?: string; + date?: string; + modified?: string; + domain: NodeSchemaProfile; + range: NodeSchemaProfile; +} + +/** + * RelationInstanceProfile Type + */ +export interface RelationInstanceProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "RelationInstance"; + }>; + hasContainer?: ContainerProfile; + creator?: string; + date?: string; + modified?: string; + source: NodeInstanceProfile; + destination: NodeInstanceProfile; +} + +/** + * ContentProfile Type + */ +export interface ContentProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "Content"; + }>; + format?: string; + content: string; +} diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex new file mode 100644 index 000000000..658f7eca3 --- /dev/null +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -0,0 +1,88 @@ +# This shape is provided by default as an example +# You can create your own shape to fit your needs using ShEx (https://shex.io) +# Also check out https://shaperepo.com for examples of more shapes. + +PREFIX dc: +PREFIX dgb: +PREFIX dgshapes: +PREFIX foaf: +PREFIX linkml: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sioc: +PREFIX xsd: + +dgshapes:ContainerProfile { + a [sioc:Container]; + sioc:container_of @dgshapes:ItemProfile *; +} + +dgshapes:ItemProfile { + a [sioc:Item]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + dc:creator xsd:string ? ; +} + +dgshapes:NodeSchemaProfile { + a [dgb:NodeSchema]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:creator xsd:string ? ; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + rdfs:label xsd:string ; + rdfs:subClassOf @dgshapes:NodeSchemaProfile *; +} + +# Note that NodeInstance is not part of the schema, but is useful as a fiction in the code +dgshapes:NodeInstanceProfile { + a [dgshapes:NodeInstance]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:creator xsd:string ? ; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + dc:title xsd:dateTime? ; + dc:description @dgshapes:ContentProfile ? ; +} + +dgshapes:RelationDefProfile { + a [dgb:RelationDef]; + rdfs:subClassOf [sioc:Item owl:ObjectProperty dgb:RelationInstance]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:creator xsd:string ? ; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + rdfs:label xsd:string ; +} + +# Note that RelationTripleDef is not yet part of the schema, but should be +dgshapes:RelationTripleDefProfile { + a [dgshapes:RelationTripleDef]; + rdfs:subClassOf [owl:ObjectProperty dgb:RelationInstance]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:creator xsd:string ? ; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + rdfs:domain @dgshapes:NodeSchemaProfile ; + rdfs:range @dgshapes:NodeSchemaProfile ; +} + + +dgshapes:RelationInstanceProfile { + a [dgb:RelationInstance]; + sioc:has_container @dgshapes:ContainerProfile ?; + dc:creator xsd:string ? ; + dc:date xsd:dateTime ? ; + dc:modified xsd:dateTime ? ; + dgb:source @dgshapes:NodeInstanceProfile ; + dgb:destination @dgshapes:NodeInstanceProfile ; +} + +# Note that Content is not part of the schema, but is useful as a fiction in the code +dgshapes:ContentProfile { + a [dgshapes:Content]; + dc:format xsd:string ?; + sioc:content xsd:string; +} diff --git a/apps/website/test/integration/parseJsonLd.test.ts b/apps/website/test/integration/parseJsonLd.test.ts new file mode 100644 index 000000000..99f74b3f4 --- /dev/null +++ b/apps/website/test/integration/parseJsonLd.test.ts @@ -0,0 +1,242 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import type { + ContainerProfile, + NodeSchemaProfile, + NodeInstanceProfile, + RelationInstanceProfile, + RelationTripleDefProfile, + RelationDefProfile, +} from "../../app/utils/conversion/ldo/dgBase.typings"; +import { parseJsonLd } from "../../app/utils/conversion/fromJsonLd"; + +// example data + +const exNodeSchema = { + "@context": [ + "http://localhost:3000/schema/context.jsonld", + { + sdata: "http://localhost:3000/api/data/131102/", + page: "http://localhost:3000/api/content/131102/131157#", + }, + ], + has_container: "http://localhost:3000/api/data/131102", + "@id": "sdata:131157", + "@type": "NodeSchema", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + subClassOf: ["dgc:Question", "mira:Question"], + label: "Question", + creator: "someone", +}; + +const exNodeInstance = { + "@context": [ + "http://localhost:3000/schema/context.jsonld", + { + sdata: "http://localhost:3000/api/data/131102/", + page: "http://localhost:3000/api/content/131102/254918#", + }, + ], + has_container: "http://localhost:3000/api/data/131102", + "@id": "sdata:254918", + "@type": ["sdata:131157", "dgc:Question", "mira:Question"], + modified: "2026-05-26T00:39:03.077Z", + created: "2025-12-04T15:47:51.694Z", + title: "QUE - How to do interop", + description: { + "@id": "page:content", + format: "text/html", + content: + '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', + }, + creator: "someone", +}; + +const exRelnDef = { + "@context": [ + "http://localhost:3000/schema/context.jsonld", + { + sdata: "http://localhost:3000/api/data/131102/", + page: "http://localhost:3000/api/content/131102/131164#", + }, + ], + has_container: "http://localhost:3000/api/data/131102", + "@id": "sdata:131164", + "@type": "RelationDef", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + subClassOf: [ + "dgb:RelationInstance", + { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:131164", + }, + ], + label: "informs", + creator: "someone", +}; + +const exRelnTripleType = { + "@context": [ + "http://localhost:3000/schema/context.jsonld", + { + sdata: "http://localhost:3000/api/data/131102/", + page: "http://localhost:3000/api/content/131102/131169#", + }, + ], + has_container: "http://localhost:3000/api/data/131102", + "@id": "sdata:131169", + "@type": "RelationDef", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + subClassOf: [ + "dgb:RelationInstance", + { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:131169", + }, + ], + label: "Claim -informs-> Question", + creator: "someone", +}; + +const exRelnInstance = { + "@context": [ + "http://localhost:3000/schema/context.jsonld", + { + sdata: "http://localhost:3000/api/data/131102/", + page: "http://localhost:3000/api/content/131102/261147#", + }, + ], + has_container: "http://localhost:3000/api/data/131102", + "@id": "sdata:261147", + "@type": "sdata:131164", + modified: "2026-06-03T10:13:09.101Z", + created: "2026-06-03T10:13:09.101Z", + source: "sdata:261134", + destination: "sdata:261140", + title: + "[[CLM - New claim for sharing]] -informs-> [[QUE - This is a test question]]", + creator: "someone", +}; + +describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { + beforeAll(() => {}); + + afterAll(() => {}); + + const spaceUrl = "http://localhost:3000/api/data/131102"; + + it("Reads a node schema", async () => { + const data = exNodeSchema; + const id = data["@id"]; + const url = `${spaceUrl}/${id.split(":")[1]}`; + const parsedData = await parseJsonLd(data, url); + const parsedItem = parsedData.filter( + (item) => item["@id"] === url, + )[0] as NodeSchemaProfile; + const types = parsedItem.type.toArray().map((x) => x["@id"]); + expect(types.includes("NodeSchema")); + // TODO: Find a way to verify that it was indeed parsed as NodeSchema + expect(parsedItem); + expect(parsedItem["@id"]); + expect(parsedItem.subClassOf); + expect(parsedItem.date); + expect(parsedItem.modified); + expect(parsedItem.creator); + expect(parsedItem.hasContainer); + // const turtleData = await toTurtle(parsedNodeSchema); + // console.log(turtleData); + }); + + it("Reads a node instance", async () => { + const data = exNodeInstance; + const id = data["@id"]; + const url = `${spaceUrl}/${id.split(":")[1]}`; + const parsedData = await parseJsonLd(data, url); + const parsedItem = parsedData.filter( + (item) => item["@id"] === url, + )[0] as NodeInstanceProfile; + // TODO: Find a way to verify that it was indeed parsed as NodeInstance. + const types = parsedItem.type.toArray().map((x) => x["@id"]); + expect(types.includes("NodeInstance")); + expect(parsedItem); + expect(parsedItem["@id"]); + expect(parsedItem.title); + expect(parsedItem.description); + expect(parsedItem.date); + expect(parsedItem.modified); + expect(parsedItem.creator); + expect(parsedItem.hasContainer); + // const turtleData = await toTurtle(parsedNodeInstance); + // console.log(turtleData); + }); + + it("Reads a relation definition", async () => { + const data = exRelnDef; + const id = data["@id"]; + const url = `${spaceUrl}/${id.split(":")[1]}`; + const parsedData = await parseJsonLd(data, url); + const parsedItem = parsedData.filter( + (item) => item["@id"] === url, + )[0] as RelationDefProfile; + const types = parsedItem.type.toArray().map((x) => x["@id"]); + expect(types.includes("RelationDef")); + + expect(parsedItem); + expect(parsedItem["@id"]); + expect(parsedItem.label); + expect(parsedItem.date); + expect(parsedItem.modified); + expect(parsedItem.creator); + expect(parsedItem.hasContainer); + // const turtleData = await toTurtle(parsedRelnSchema); + // console.log(turtleData); + }); + + it("Reads a relation triple definition", async () => { + const data = exRelnTripleType; + const id = data["@id"]; + const url = `${spaceUrl}/${id.split(":")[1]}`; + const parsedData = await parseJsonLd(data, url); + const parsedItem = parsedData.filter( + (item) => item["@id"] === url, + )[0] as RelationTripleDefProfile; + const types = parsedItem.type.toArray().map((x) => x["@id"]); + expect(types.includes("RelationTripleDef")); + expect(parsedItem); + expect(parsedItem["@id"]); + expect(parsedItem.domain); + expect(parsedItem.range); + expect(parsedItem.date); + expect(parsedItem.modified); + expect(parsedItem.creator); + expect(parsedItem.hasContainer); + // const turtleData = await toTurtle(parsedRelnSchema); + // console.log(turtleData); + }); + + it("Reads a relation instance", async () => { + const data = exRelnInstance; + const id = data["@id"]; + const url = `${spaceUrl}/${id.split(":")[1]}`; + const parsedData = await parseJsonLd(data, url); + const parsedItem = parsedData.filter( + (item) => item["@id"] === url, + )[0] as RelationInstanceProfile; + const types = parsedItem.type.toArray().map((x) => x["@id"]); + expect(types.includes("RelationInstance")); + expect(parsedItem); + expect(parsedItem["@id"]); + expect(parsedItem.source); + expect(parsedItem.destination); + expect(parsedItem.date); + expect(parsedItem.modified); + expect(parsedItem.creator); + expect(parsedItem.hasContainer); + // const turtleData = await toTurtle(parsedRelnInstance); + // console.log(turtleData); + }); +}); From 8ab50d5583ee0e04fdebdb16e3322ef94174d8ef Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Wed, 3 Jun 2026 16:19:21 -0400 Subject: [PATCH 07/41] Correction: Check that the resource is in the right space --- apps/website/app/api/content/[space_id]/[resource_id]/route.ts | 1 + apps/website/app/api/data/[space_id]/[resource_id]/route.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts index 1e755eaa2..326617b60 100644 --- a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -72,6 +72,7 @@ export const GET = async ( .from("Concept") .select() .eq("id", resourceIdN) + .eq("space_id", spaceIdN) .maybeSingle(); if (conceptResponse.error) { return createApiResponse(request, conceptResponse); diff --git a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts index 2215f4801..d8c0794b6 100644 --- a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts @@ -66,6 +66,7 @@ export const GET = async ( .from("Concept") .select() .eq("id", resourceIdN) + .eq("space_id", spaceIdN) .maybeSingle(); if (conceptResponse.error) { return createApiResponse(request, conceptResponse); From 317aad254af81fe30a7a490c0c0fca2a322f1711 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 08:29:56 -0400 Subject: [PATCH 08/41] AbstractRelationDef --- apps/website/app/utils/conversion/jsonld.ts | 102 +++++++++++++------- apps/website/public/schema/context.jsonld | 1 + apps/website/public/schema/dg_base.ttl | 6 +- 3 files changed, 73 insertions(+), 36 deletions(-) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index b86f68762..551bf57a5 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -7,31 +7,56 @@ type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; // This is a temporary hack -const KnownSchemaEntities: Record = { - Claim: ["dgc", "mira"], - Evidence: ["dgc", "mira"], - Question: ["dgc", "mira"], - SourceDocument: ["dgc"], - describesActivity: ["dgc"], - observationStatement: ["dgc"], - observationOriginActivity: ["dgc"], - observationBase: ["dgc"], - sourceDocument: ["dgc"], - opposes: ["dgc"], - opposedBy: ["dgc"], - supports: ["dgc"], - supportedBy: ["dgc"], - addresses: ["dgc"], - addressedBy: ["dgc"], - Request: ["mira"], - Protocol: ["mira"], - follows: ["mira"], - grounds: ["mira"], - is_grounded_in: ["mira"], - request_for: ["mira"], - request_target: ["mira"], +export const KnownSchemaEntities: Record = { + Claim: ["dgc:Claim", "mira:Claim"], + Evidence: ["dgc:Evidence", "mira:Evidence"], + Question: ["dgc:Question", "mira:Question"], + SourceDocument: ["dgc:SourceDocument"], + describesActivity: ["dgc:describesActivity"], + observationStatement: ["dgc:observationStatement"], + observationOriginActivity: ["dgc:observationOriginActivity"], + observationBase: ["dgc:observationBase"], + sourceDocument: ["dgc:sourceDocument"], + opposes: ["dgc:opposes"], + opposedBy: ["dgc:opposedBy"], + supports: ["dgc:supports"], + supportedBy: ["dgc:supportedBy"], + addresses: ["dgc:addresses"], + addressedBy: ["dgc:addressedBy"], + Request: ["mira:Request"], + Protocol: ["mira:Protocol"], + follows: ["mira:follows"], + grounds: ["mira:grounds"], + is_grounded_in: ["mira:is_grounded_in"], + request_for: ["mira:request_for"], + request_target: ["mira:request_target"], }; +const prefixes: Record = { + rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + rdfs: "http://www.w3.org/2000/01/rdf-schema#", + owl: "http://www.w3.org/2002/07/owl#", + dc: "http://purl.org/dc/elements/1.1/", + prov: "http://www.w3.org/ns/prov#", + sioc: "http://rdfs.org/sioc/ns#", + dgb: "https://discoursegraphs.com/schema/dg_base#", + dgc: "https://discoursegraphs.com/schema/dg_core#", + mira: "http://purl.org/mira-science/mira#", +}; + +export const curieToIri = (curie: string): string => { + const [prefix, name]: string[] = curie.split(":", 1); + const iri = prefixes[prefix || ""]; + if (iri === undefined) { + console.error("Unknown prefix", prefix); + return curie; + } + return iri + name; +}; + +export const KnownSchemaCuries = Object.values(KnownSchemaEntities).flat(); +export const KnownSchemaIris = KnownSchemaCuries.map(curieToIri); + export const asJsonLD = ({ space, concept, @@ -60,7 +85,9 @@ export const asJsonLD = ({ let schemaUrl: string | string[] = concept.schema_id ? "sdata:" + concept.schema_id : concept.arity === 2 - ? "RelationDef" + ? (concept.reference_content as Record).source !== undefined + ? "RelationDef" + : "AbstractRelationDef" : "NodeSchema"; let extraData: Record = {}; @@ -84,25 +111,30 @@ export const asJsonLD = ({ if (schema !== undefined) { const knownSchemas = KnownSchemaEntities[schema?.name ?? ""]; if (knownSchemas !== undefined) { - schemaUrl = [ - schemaUrl, - ...knownSchemas.map((s) => `${s}:${schema.name}`), - ]; + schemaUrl = [schemaUrl, ...knownSchemas]; } } else if (concept.is_schema) { const subClasses: Array = []; const knownSchemas = KnownSchemaEntities[concept.name]; // in that case we can skip the base class if (knownSchemas !== undefined) { - subClasses.push(...knownSchemas.map((s) => `${s}:${concept.name}`)); + subClasses.push(...knownSchemas); } if (concept.arity === 2) { - // Explicit punning - subClasses.push("dgb:RelationInstance", { - "@type": "owl:Restriction", - onProperty: "rdf:predicate", - hasValue: "sdata:" + concept.id, - }); + // triple vs abstract def + const abstractRelType = ( + concept.reference_content as Record + ).relation_type; + if (typeof abstractRelType === "number") { + subClasses.push("sdata:" + abstractRelType); + } else { + // Explicit punning + subClasses.push("dgb:RelationInstance", { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:" + concept.id, + }); + } } if (subClasses.length > 1) extraData["subClassOf"] = subClasses; else if (subClasses.length === 1) extraData["subClassOf"] = subClasses[0]!; diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 7ac7183f7..ee6e77dab 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -33,6 +33,7 @@ "container_of": "sioc:container_of", "has_container": { "@id": "sioc:has_container", "@type": "@id" }, "RelationDef": "dgb:RelationDef", + "AbstractRelationDef": "dgb:AbstractRelationDef", "RelationInstance": "dgb:RelationInstance", "RelationSchema": "dgb:RelationSchema", "NodeSchema": "dgb:NodeSchema", diff --git a/apps/website/public/schema/dg_base.ttl b/apps/website/public/schema/dg_base.ttl index eced8e198..45b098e80 100644 --- a/apps/website/public/schema/dg_base.ttl +++ b/apps/website/public/schema/dg_base.ttl @@ -27,9 +27,13 @@ dgb:Role [a owl:Restriction; owl:onProperty rdfs:range ; owl:allValuesFrom dgb:NodeSchema ]; rdfs:comment "A role within a node schema"@en . -dgb:RelationDef rdfs:subClassOf owl:ObjectProperty; + +dgb:AbstractRelationDef rdfs:comment "DiscourseGraph relation definitions"@en. + +dgb:RelationDef rdfs:subClassOf owl:ObjectProperty, dgb:AbstractRelationDef; rdfs:comment "DiscourseGraph relations"@en. + dgb:RelationInstance rdfs:subClassOf rdf:Statement, dgb:NodeSchema, [a owl:Restriction; owl:onProperty rdfs:predicate ; owl:allValuesFrom dgb:RelationDef ]. From 6a3b0170095ffecccb07c314700e9b99b4e38ce9 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 08:30:41 -0400 Subject: [PATCH 09/41] First version of post (untested) --- apps/website/app/api/data/[space_id]/route.ts | 28 ++ apps/website/app/utils/conversion/convert.ts | 4 + .../app/utils/conversion/fromJsonLd.ts | 346 +++++++++++++++++- .../utils/conversion/ldo/dgBase.context.ts | 59 +-- .../app/utils/conversion/ldo/dgBase.schema.ts | 85 +++-- .../utils/conversion/ldo/dgBase.shapeTypes.ts | 24 +- .../utils/conversion/ldo/dgBase.typings.ts | 72 ++-- .../app/utils/conversion/shapes/dgBase.shex | 32 +- .../test/integration/parseJsonLd.test.ts | 55 +-- 9 files changed, 548 insertions(+), 157 deletions(-) diff --git a/apps/website/app/api/data/[space_id]/route.ts b/apps/website/app/api/data/[space_id]/route.ts index 8eae33384..a2d5ee35b 100644 --- a/apps/website/app/api/data/[space_id]/route.ts +++ b/apps/website/app/api/data/[space_id]/route.ts @@ -6,6 +6,8 @@ import { createApiResponse, } from "~/utils/supabase/apiUtils"; import { Tables } from "@repo/database/dbTypes"; +import { populate } from "~/utils/conversion/fromJsonLd"; +import { JsonLdDocument } from "jsonld"; type Space = Tables<"Space">; @@ -133,3 +135,29 @@ export const GET = async ( }; export const OPTIONS = defaultOptionsHandler; + +export const POST = async ( + request: NextRequest, + segmentData: SegmentDataType, +): Promise => { + const { space_id } = await segmentData.params; + const spaceIdN = Number.parseInt(space_id || "NaN"); + if (isNaN(spaceIdN)) { + return createApiResponse( + request, + asPostgrestFailure(`space_id is not a number`, "type"), + ); + } + const supabase = await createClient(); + const input: JsonLdDocument = await request.json(); + try { + const output = await populate(supabase, input, spaceIdN); + return NextResponse.json(output, { + status: 200, + }); + } catch (error) { + return NextResponse.json((error as Error).message || "Error", { + status: 500, + }); + } +}; diff --git a/apps/website/app/utils/conversion/convert.ts b/apps/website/app/utils/conversion/convert.ts index a280d0645..59fcc07f5 100644 --- a/apps/website/app/utils/conversion/convert.ts +++ b/apps/website/app/utils/conversion/convert.ts @@ -9,6 +9,10 @@ export const MIMETYPES: Record = { html: "text/html", }; +export const DOCTYPES: Record = Object.fromEntries( + Object.entries(MIMETYPES).map(([a, b]) => [b, a as DocType]), +); + const markdownTypes: Set = new Set(["obsidian", "markdown"]); let converter: showdown.Converter | undefined; diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 4286d0064..7323de9b2 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -7,39 +7,52 @@ import { NodeSchemaProfileShapeType, NodeInstanceProfileShapeType, RelationInstanceProfileShapeType, - RelationTripleDefProfileShapeType, RelationDefProfileShapeType, + AbstractRelationDefProfileShapeType, } from "./ldo/dgBase.shapeTypes"; +import type { + LocalConceptDataInput, + LocalContentDataInput, +} from "@repo/database/inputTypes"; +import { convert, DOCTYPES } from "~/utils/conversion/convert"; import type { ContainerProfile, ContentProfile, NodeSchemaProfile, NodeInstanceProfile, RelationInstanceProfile, - RelationTripleDefProfile, RelationDefProfile, + AbstractRelationDefProfile, } from "./ldo/dgBase.typings"; +import { KnownSchemaIris, KnownSchemaEntities, curieToIri } from "./jsonld"; +import { DGSupabaseClient } from "@repo/database/lib/client"; +import { Json } from "@repo/database/dbTypes"; + +const apiRoot = process.env.NEXT_API_ROOT; +const nodeOrSpaceIdRegex = RegExp(`^${apiRoot}/data/\d+(/\d+)?$`); -type ParseResult = - | ContainerProfile - | ContentProfile +type NodeParseResult = | NodeSchemaProfile | NodeInstanceProfile | RelationInstanceProfile - | RelationTripleDefProfile - | RelationDefProfile; + | RelationDefProfile + | AbstractRelationDefProfile; + +type ParseResult = NodeParseResult | ContainerProfile | ContentProfile; const typePredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; const nodeSchemaType = "https://discoursegraphs.com/schema/dg_base#NodeSchema"; const relationDefType = "https://discoursegraphs.com/schema/dg_base#RelationDef"; +const abstractRelationDefType = + "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef"; const domainPredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#domain"; const sourcePredicate = "https://discoursegraphs.com/schema/dg_base#source"; const contentPredicate = "http://rdfs.org/sioc/ns#content"; const descriptionPredicate = "http://purl.org/dc/elements/1.1/description"; const containerType = "http://rdfs.org/sioc/ns#Container"; -export const parseJsonLd = async ( +export const parseJsonLdAsLdo = async ( data: JsonLdDocument, baseIRI: string, ): Promise => { @@ -71,17 +84,17 @@ export const parseJsonLd = async ( ); continue; } - if (types.has(relationDefType)) { + if (types.has(abstractRelationDefType) || types.has(relationDefType)) { if (ldoDataset.match(namedNode(subject), namedNode(domainPredicate)).size) result.push( ldoDataset - .usingType(RelationTripleDefProfileShapeType) + .usingType(RelationDefProfileShapeType) .fromSubject(subject), ); else result.push( ldoDataset - .usingType(RelationDefProfileShapeType) + .usingType(AbstractRelationDefProfileShapeType) .fromSubject(subject), ); continue; @@ -98,7 +111,10 @@ export const parseJsonLd = async ( const typesOfTypes = new Set( (typeMap[subject] || []).map((t) => typeMap[t] || []).flat(), ); - if (typesOfTypes.has(relationDefType)) { + if ( + typesOfTypes.has(abstractRelationDefType) || + typesOfTypes.has(relationDefType) + ) { result.push( ldoDataset .usingType(RelationInstanceProfileShapeType) @@ -133,3 +149,309 @@ export const parseJsonLd = async ( } return result; }; + +const interpretId = ( + id: string, + dbVarName: DBN, + localVarName: LVN, + knownClasses?: Record, +): Record | Record => { + if (knownClasses && knownClasses[id] !== undefined) + return { [localVarName]: knownClasses[id] } as Record; + if (nodeOrSpaceIdRegex.test(id)) { + const parts = id.split("/"); + return { [dbVarName]: Number.parseInt(parts[parts.length - 1]!) } as Record< + DBN, + number + >; + } + return { [localVarName]: id } as Record; +}; + +const baseInterpretId = (id: string) => + interpretId(id, "id", "source_local_id"); + +const parseBaseData = (data: NodeParseResult) => { + const spaceInfo = data.hasContainer + ? interpretId(data.hasContainer["@id"], "space_id", "space_local_id") + : {}; + return { + created: data.date, + modified: data.modified, + author_local_id: data.creator, + ...spaceInfo, + }; +}; + +const expectedSchemaIris = new Set(KnownSchemaIris); + +const maybeAddKnownClass = ( + ids: string[], + name: string, + source_local_id: string, + knownClasses: Record, +): void => { + for (const id of ids) { + if (expectedSchemaIris.has(id)) { + if (knownClasses[id] === undefined) { + knownClasses[id] = source_local_id; + return; + } else if (knownClasses[id] !== source_local_id) { + console.error("Conflict on class", id); + return; + } + } + } + // hackish + if (KnownSchemaEntities[name] === undefined) return; + for (const id of KnownSchemaEntities[name]) { + if (knownClasses[id] === undefined) { + knownClasses[id] = source_local_id; + return; + } else if (knownClasses[id] !== source_local_id) { + console.error("Conflict on class", id); + return; + } + } +}; + +const parseNodeSchema = ( + data: NodeSchemaProfile, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (data["@id"] == null) return null; + const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; + maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); + return { + name: data.label, + is_schema: true, + ...baseInterpretId(data["@id"]), + ...parseBaseData(data), + }; +}; + +const parseContent = ( + content: ContentProfile, + data: NodeInstanceProfile, +): LocalContentDataInput | null => { + if (data["@id"] == null) return null; + const sourceFormat = DOCTYPES[content.format || ""] ?? "html"; + const text = convert(content.content, sourceFormat, "obsidian"); + return { + text, + scale: "document", + ...baseInterpretId(data["@id"]), + ...parseBaseData(data), + }; +}; + +const parseNodeInstance = ( + data: NodeInstanceProfile, + content: ContentProfile, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (data["@id"] == null) return null; + const schemaInfo = data.type.map((x) => + interpretId(x["@id"], "schema_id", "schema_local_id", knownClasses), + ); + if (!schemaInfo.length) return null; + // TODO If there's many types, how to choose? + return { + name: data.title, + contents_inline: [parseContent(content, data)].filter((c) => c !== null), + ...schemaInfo[0], + ...baseInterpretId(data["@id"]), + ...parseBaseData(data), + }; +}; +const parseAbstractRelationDef = ( + data: AbstractRelationDefProfile, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (data["@id"] == null) return null; + const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; + maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); + return { + name: data.label, + is_schema: true, + literal_content: { roles: ["source", "destination"] }, + ...baseInterpretId(data["@id"]), + ...parseBaseData(data), + }; +}; +const parseRelationDef = ( + data: RelationDefProfile, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (data["@id"] == null) return null; + if (data.label) { + const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; + maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); + } + const source_ids = knownClasses[data.domain["@id"]]; + const destination_ids = knownClasses[data.range["@id"]]; + const source_id = Array.isArray(source_ids) ? source_ids[0] : source_ids; + const destination_id = Array.isArray(destination_ids) + ? destination_ids[0] + : destination_ids; + if (source_id === undefined || destination_id === undefined) return null; + // TODO: Find the relation_type if appropriate + return { + local_reference_content: { source: source_id, destination: destination_id }, + is_schema: true, + name: data.label, + ...baseInterpretId(data["@id"]), + ...parseBaseData(data), + }; +}; + +const parseRelationInstance = ( + data: RelationInstanceProfile, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (data["@id"] == null) return null; + const schemaInfo = data.type.map((x) => + interpretId(x["@id"], "schema_id", "schema_local_id", knownClasses), + ); + if (!schemaInfo.length) return null; + // TODO If there's many types, how to choose? + return { + ...schemaInfo[0], + ...interpretId(data["@id"], "id", "source_local_id"), + ...parseBaseData(data), + }; +}; + +const parseLdoNode = ( + data: NodeParseResult, + contentById: Record, + knownClasses: Record, +): LocalConceptDataInput | null => { + if (!data["@id"]) { + console.error("No @id: ", data); + return null; + } + const types = new Set(data.type.map((x) => x["@id"])); + if (types.size === 0) return null; + if (types.has("RelationInstance")) + return parseRelationInstance(data as RelationInstanceProfile, knownClasses); + if (types.has("NodeInstance")) { + const nodeInstance = data as NodeInstanceProfile; + if (!nodeInstance.description) return null; + const content = nodeInstance.description.content + ? nodeInstance.description + : contentById[nodeInstance.description["@id"]!]; + if (!content) return null; + return parseNodeInstance(nodeInstance, content, knownClasses); + } + if (types.has("RelationDef")) + return parseRelationDef(data as RelationDefProfile, knownClasses); + if (types.has("AbstractRelationDef")) + return parseAbstractRelationDef( + data as AbstractRelationDefProfile, + knownClasses, + ); + if (types.has("NodeSchema")) + return parseNodeSchema(data as NodeSchemaProfile, knownClasses); + console.error("We should not get here"); + return null; +}; + +const nodeOrder = [ + "NodeSchema", + "AbstractRelationDef", + "RelationDef", + "NodeInstance", + "RelationInstance", +]; + +export const parseJsonLdAsDataInputWithSchemas = async ( + data: JsonLdDocument, + baseIRI: string, + knownClasses: Record, +): Promise => { + const ldoData = await parseJsonLdAsLdo(data, baseIRI); + const contents = ldoData.filter((d) => + d.type + .toArray() + .map((x) => x["@id"]) + .includes("Content"), + ) as ContentProfile[]; + // assume single content for now + const contentById = Object.fromEntries( + contents.map((c) => [c["@id"], c]), + ) as Record; + const nodesWithoutContents = ldoData.filter( + (d) => contentById[d["@id"] || ""] === undefined, + ) as NodeParseResult[]; + // Reorder, put schemas first, relations last. + nodesWithoutContents.sort((n1, n2) => { + const t1os = n1.type + .map((x) => nodeOrder.indexOf(x["@id"])) + .filter((o) => o >= 0); + const t2os = n1.type + .map((x) => nodeOrder.indexOf(x["@id"])) + .filter((o) => o >= 0); + if (t1os.length === 0) return 1; + if (t2os.length === 0) return -1; + if (t2os[0]! < t1os[0]!) return 1; + if (t1os[0]! < t2os[0]!) return -1; + // arbitrary order + if (n1["@id"] === undefined) return 1; + if (n2["@id"] === undefined) return 1; + if (n2["@id"] < n1["@id"]) return 1; + if (n2["@id"] > n1["@id"]) return -1; + return 0; + }); + return nodesWithoutContents + .map((d) => parseLdoNode(d, contentById, knownClasses)) + .filter((x) => !!x); +}; + +export const parseJsonLdAsInput = async ( + supabase: DGSupabaseClient, + jsonLdData: JsonLdDocument, + spaceId: number, +): Promise => { + const baseIri = `${apiRoot}/data/${spaceId}`; + const { error, data } = await supabase + .from("Concept") + .select("name,source_local_id") + .eq("space_id", spaceId) + .eq("is_schema", true); + if (error) throw error; + const knownClasses = Object.fromEntries( + data + .filter(({ name, source_local_id }) => source_local_id !== null) + .map(({ name, source_local_id }) => + (KnownSchemaEntities[name] || []).map((c) => [ + curieToIri(c), + source_local_id!, + ]), + ) + .flat(), + ); + return await parseJsonLdAsDataInputWithSchemas( + jsonLdData, + baseIri, + knownClasses, + ); +}; + +export const populate = async ( + supabase: DGSupabaseClient, + jsonLdData: JsonLdDocument, + spaceId: number, +): Promise => { + const upsertData = await parseJsonLdAsInput(supabase, jsonLdData, spaceId); + if (upsertData.length === 0) return []; + const { data: upsertResult, error: upsertError } = await supabase.rpc( + "upsert_concepts", + { + data: upsertData as Json, + v_space_id: spaceId, + }, + ); + if (upsertError) throw upsertError; + return upsertResult; +}; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index 8a41a5885..56eb45099 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -179,8 +179,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://rdfs.org/sioc/ns#content", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - RelationDef: { - "@id": "https://discoursegraphs.com/schema/dg_base#RelationDef", + AbstractRelationDef: { + "@id": "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef", "@context": { type: { "@id": "@type", @@ -188,6 +188,7 @@ export const dgBaseContext: LdoJsonldContext = { }, subClassOf: { "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@type": "@id", "@isCollection": true, }, hasContainer: { @@ -212,14 +213,18 @@ export const dgBaseContext: LdoJsonldContext = { }, }, }, - ObjectProperty: "http://www.w3.org/2002/07/owl#ObjectProperty", - RelationInstance: { - "@id": "https://discoursegraphs.com/schema/dg_base#RelationInstance", + RelationDef: { + "@id": "https://discoursegraphs.com/schema/dg_base#RelationDef", "@context": { type: { "@id": "@type", "@isCollection": true, }, + subClassOf: { + "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", + "@type": "@id", + "@isCollection": true, + }, hasContainer: { "@id": "http://rdfs.org/sioc/ns#has_container", "@type": "@id", @@ -236,27 +241,35 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/elements/1.1/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, - source: { - "@id": "https://discoursegraphs.com/schema/dg_base#source", + label: { + "@id": "http://www.w3.org/2000/01/rdf-schema#label", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + domain: { + "@id": "http://www.w3.org/2000/01/rdf-schema#domain", "@type": "@id", }, - destination: { - "@id": "https://discoursegraphs.com/schema/dg_base#destination", + range: { + "@id": "http://www.w3.org/2000/01/rdf-schema#range", "@type": "@id", }, }, }, - RelationTripleDef: { - "@id": "https://discoursegraphs.com/schema/dg_base#RelationTripleDef", + domain: { + "@id": "http://www.w3.org/2000/01/rdf-schema#domain", + "@type": "@id", + }, + range: { + "@id": "http://www.w3.org/2000/01/rdf-schema#range", + "@type": "@id", + }, + RelationInstance: { + "@id": "https://discoursegraphs.com/schema/dg_base#RelationInstance", "@context": { type: { "@id": "@type", "@isCollection": true, }, - subClassOf: { - "@id": "http://www.w3.org/2000/01/rdf-schema#subClassOf", - "@isCollection": true, - }, hasContainer: { "@id": "http://rdfs.org/sioc/ns#has_container", "@type": "@id", @@ -273,24 +286,16 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/elements/1.1/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, - domain: { - "@id": "http://www.w3.org/2000/01/rdf-schema#domain", + source: { + "@id": "https://discoursegraphs.com/schema/dg_base#source", "@type": "@id", }, - range: { - "@id": "http://www.w3.org/2000/01/rdf-schema#range", + destination: { + "@id": "https://discoursegraphs.com/schema/dg_base#destination", "@type": "@id", }, }, }, - domain: { - "@id": "http://www.w3.org/2000/01/rdf-schema#domain", - "@type": "@id", - }, - range: { - "@id": "http://www.w3.org/2000/01/rdf-schema#range", - "@type": "@id", - }, source: { "@id": "https://discoursegraphs.com/schema/dg_base#source", "@type": "@id", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index 62c77621d..e612a98e0 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -55,8 +55,10 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, @@ -115,8 +117,10 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, @@ -161,8 +165,10 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: -1, }, @@ -191,8 +197,10 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, @@ -249,7 +257,7 @@ export const dgBaseSchema: Schema = { }, }, { - id: "https://discoursegraphs.com/schema/dg_base#RelationDefProfile", + id: "https://discoursegraphs.com/schema/dg_base#AbstractRelationDefProfile", type: "ShapeDecl", shapeExpr: { type: "Shape", @@ -262,7 +270,7 @@ export const dgBaseSchema: Schema = { valueExpr: { type: "NodeConstraint", values: [ - "https://discoursegraphs.com/schema/dg_base#RelationDef", + "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef", ], }, }, @@ -271,18 +279,18 @@ export const dgBaseSchema: Schema = { predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", valueExpr: { type: "NodeConstraint", - values: [ - "http://rdfs.org/sioc/ns#Item", - "http://www.w3.org/2002/07/owl#ObjectProperty", - "https://discoursegraphs.com/schema/dg_base#RelationInstance", - ], + nodeKind: "iri", }, + min: 0, + max: -1, }, { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, @@ -329,7 +337,7 @@ export const dgBaseSchema: Schema = { }, }, { - id: "https://discoursegraphs.com/schema/dg_base#RelationTripleDefProfile", + id: "https://discoursegraphs.com/schema/dg_base#RelationDefProfile", type: "ShapeDecl", shapeExpr: { type: "Shape", @@ -342,7 +350,7 @@ export const dgBaseSchema: Schema = { valueExpr: { type: "NodeConstraint", values: [ - "https://discoursegraphs.com/schema/dg_base#RelationTripleDef", + "https://discoursegraphs.com/schema/dg_base#RelationDef", ], }, }, @@ -351,17 +359,18 @@ export const dgBaseSchema: Schema = { predicate: "http://www.w3.org/2000/01/rdf-schema#subClassOf", valueExpr: { type: "NodeConstraint", - values: [ - "http://www.w3.org/2002/07/owl#ObjectProperty", - "https://discoursegraphs.com/schema/dg_base#RelationInstance", - ], + nodeKind: "iri", }, + min: 0, + max: -1, }, { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, @@ -395,17 +404,29 @@ export const dgBaseSchema: Schema = { min: 0, max: 1, }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + }, { type: "TripleConstraint", predicate: "http://www.w3.org/2000/01/rdf-schema#domain", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, }, { type: "TripleConstraint", predicate: "http://www.w3.org/2000/01/rdf-schema#range", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#NodeSchemaProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, }, ], }, @@ -432,8 +453,10 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://rdfs.org/sioc/ns#has_container", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContainerProfile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, min: 0, max: 1, }, diff --git a/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts index 26aefc0da..ca450c45f 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts @@ -6,8 +6,8 @@ import type { ItemProfile, NodeSchemaProfile, NodeInstanceProfile, + AbstractRelationDefProfile, RelationDefProfile, - RelationTripleDefProfile, RelationInstanceProfile, ContentProfile, } from "./dgBase.typings"; @@ -54,6 +54,17 @@ export const NodeInstanceProfileShapeType: ShapeType = { context: dgBaseContext, }; +/** + * AbstractRelationDefProfile ShapeType + */ +export const AbstractRelationDefProfileShapeType: ShapeType = + { + schema: dgBaseSchema, + shape: + "https://discoursegraphs.com/schema/dg_base#AbstractRelationDefProfile", + context: dgBaseContext, + }; + /** * RelationDefProfile ShapeType */ @@ -63,17 +74,6 @@ export const RelationDefProfileShapeType: ShapeType = { context: dgBaseContext, }; -/** - * RelationTripleDefProfile ShapeType - */ -export const RelationTripleDefProfileShapeType: ShapeType = - { - schema: dgBaseSchema, - shape: - "https://discoursegraphs.com/schema/dg_base#RelationTripleDefProfile", - context: dgBaseContext, - }; - /** * RelationInstanceProfile ShapeType */ diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index cd469cbe8..30ae242f2 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -27,7 +27,9 @@ export interface ItemProfile { type: LdSet<{ "@id": "Item"; }>; - hasContainer?: ContainerProfile; + hasContainer?: { + "@id": string; + }; date?: string; modified?: string; creator?: string; @@ -42,12 +44,16 @@ export interface NodeSchemaProfile { type: LdSet<{ "@id": "NodeSchema"; }>; - hasContainer?: ContainerProfile; + hasContainer?: { + "@id": string; + }; creator?: string; date?: string; modified?: string; label: string; - subClassOf?: LdSet; + subClassOf?: LdSet<{ + "@id": string; + }>; } /** @@ -59,7 +65,9 @@ export interface NodeInstanceProfile { type: LdSet<{ "@id": "NodeInstance"; }>; - hasContainer?: ContainerProfile; + hasContainer?: { + "@id": string; + }; creator?: string; date?: string; modified?: string; @@ -68,25 +76,20 @@ export interface NodeInstanceProfile { } /** - * RelationDefProfile Type + * AbstractRelationDefProfile Type */ -export interface RelationDefProfile { +export interface AbstractRelationDefProfile { "@id"?: string; "@context"?: LdoJsonldContext; type: LdSet<{ - "@id": "RelationDef"; + "@id": "AbstractRelationDef"; + }>; + subClassOf?: LdSet<{ + "@id": string; }>; - subClassOf: - | { - "@id": "Item"; - } - | { - "@id": "ObjectProperty"; - } - | { - "@id": "RelationInstance"; - }; - hasContainer?: ContainerProfile; + hasContainer?: { + "@id": string; + }; creator?: string; date?: string; modified?: string; @@ -94,27 +97,30 @@ export interface RelationDefProfile { } /** - * RelationTripleDefProfile Type + * RelationDefProfile Type */ -export interface RelationTripleDefProfile { +export interface RelationDefProfile { "@id"?: string; "@context"?: LdoJsonldContext; type: LdSet<{ - "@id": "RelationTripleDef"; + "@id": "RelationDef"; }>; - subClassOf: - | { - "@id": "ObjectProperty"; - } - | { - "@id": "RelationInstance"; - }; - hasContainer?: ContainerProfile; + subClassOf?: LdSet<{ + "@id": string; + }>; + hasContainer?: { + "@id": string; + }; creator?: string; date?: string; modified?: string; - domain: NodeSchemaProfile; - range: NodeSchemaProfile; + label: string; + domain: { + "@id": string; + }; + range: { + "@id": string; + }; } /** @@ -126,7 +132,9 @@ export interface RelationInstanceProfile { type: LdSet<{ "@id": "RelationInstance"; }>; - hasContainer?: ContainerProfile; + hasContainer?: { + "@id": string; + }; creator?: string; date?: string; modified?: string; diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index 658f7eca3..540d6c984 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -20,7 +20,7 @@ dgshapes:ContainerProfile { dgshapes:ItemProfile { a [sioc:Item]; - sioc:has_container @dgshapes:ContainerProfile ?; + sioc:has_container IRI ?; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; dc:creator xsd:string ? ; @@ -28,18 +28,18 @@ dgshapes:ItemProfile { dgshapes:NodeSchemaProfile { a [dgb:NodeSchema]; - sioc:has_container @dgshapes:ContainerProfile ?; + sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; rdfs:label xsd:string ; - rdfs:subClassOf @dgshapes:NodeSchemaProfile *; + rdfs:subClassOf IRI *; } # Note that NodeInstance is not part of the schema, but is useful as a fiction in the code dgshapes:NodeInstanceProfile { a [dgshapes:NodeInstance]; - sioc:has_container @dgshapes:ContainerProfile ?; + sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; @@ -47,32 +47,32 @@ dgshapes:NodeInstanceProfile { dc:description @dgshapes:ContentProfile ? ; } -dgshapes:RelationDefProfile { - a [dgb:RelationDef]; - rdfs:subClassOf [sioc:Item owl:ObjectProperty dgb:RelationInstance]; - sioc:has_container @dgshapes:ContainerProfile ?; +dgshapes:AbstractRelationDefProfile { + a [dgb:AbstractRelationDef]; + rdfs:subClassOf IRI*; + sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; rdfs:label xsd:string ; } -# Note that RelationTripleDef is not yet part of the schema, but should be -dgshapes:RelationTripleDefProfile { - a [dgshapes:RelationTripleDef]; - rdfs:subClassOf [owl:ObjectProperty dgb:RelationInstance]; - sioc:has_container @dgshapes:ContainerProfile ?; +dgshapes:RelationDefProfile { + a [dgshapes:RelationDef]; + rdfs:subClassOf IRI*; + sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; - rdfs:domain @dgshapes:NodeSchemaProfile ; - rdfs:range @dgshapes:NodeSchemaProfile ; + rdfs:label xsd:string ; + rdfs:domain IRI ; + rdfs:range IRI ; } dgshapes:RelationInstanceProfile { a [dgb:RelationInstance]; - sioc:has_container @dgshapes:ContainerProfile ?; + sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; dc:modified xsd:dateTime ? ; diff --git a/apps/website/test/integration/parseJsonLd.test.ts b/apps/website/test/integration/parseJsonLd.test.ts index 99f74b3f4..676c369fc 100644 --- a/apps/website/test/integration/parseJsonLd.test.ts +++ b/apps/website/test/integration/parseJsonLd.test.ts @@ -1,13 +1,12 @@ import { describe, it, expect, beforeAll, afterAll } from "vitest"; import type { - ContainerProfile, NodeSchemaProfile, NodeInstanceProfile, RelationInstanceProfile, - RelationTripleDefProfile, RelationDefProfile, + AbstractRelationDefProfile, } from "../../app/utils/conversion/ldo/dgBase.typings"; -import { parseJsonLd } from "../../app/utils/conversion/fromJsonLd"; +import { parseJsonLdAsLdo } from "../../app/utils/conversion/fromJsonLd"; // example data @@ -24,8 +23,8 @@ const exNodeSchema = { "@type": "NodeSchema", modified: "2026-01-24T15:38:14.553Z", created: "2026-01-24T15:38:14.553Z", - subClassOf: ["dgc:Question", "mira:Question"], - label: "Question", + subClassOf: ["dgc:Claim", "mira:Claim"], + label: "Claim", creator: "someone", }; @@ -39,10 +38,10 @@ const exNodeInstance = { ], has_container: "http://localhost:3000/api/data/131102", "@id": "sdata:254918", - "@type": ["sdata:131157", "dgc:Question", "mira:Question"], + "@type": ["sdata:131157", "dgc:Claim", "mira:Claim"], modified: "2026-05-26T00:39:03.077Z", created: "2025-12-04T15:47:51.694Z", - title: "QUE - How to do interop", + title: "CLM - Some base claim", description: { "@id": "page:content", format: "text/html", @@ -52,7 +51,7 @@ const exNodeInstance = { creator: "someone", }; -const exRelnDef = { +const exAbstractRelnDef = { "@context": [ "http://localhost:3000/schema/context.jsonld", { @@ -62,7 +61,7 @@ const exRelnDef = { ], has_container: "http://localhost:3000/api/data/131102", "@id": "sdata:131164", - "@type": "RelationDef", + "@type": "AbstractRelationDef", modified: "2026-01-24T15:38:14.553Z", created: "2026-01-24T15:38:14.553Z", subClassOf: [ @@ -73,11 +72,11 @@ const exRelnDef = { hasValue: "sdata:131164", }, ], - label: "informs", + label: "supports", creator: "someone", }; -const exRelnTripleType = { +const exRelnType = { "@context": [ "http://localhost:3000/schema/context.jsonld", { @@ -90,6 +89,8 @@ const exRelnTripleType = { "@type": "RelationDef", modified: "2026-01-24T15:38:14.553Z", created: "2026-01-24T15:38:14.553Z", + domain: "sdata:131157", + range: "sdata:131157", subClassOf: [ "dgb:RelationInstance", { @@ -98,7 +99,7 @@ const exRelnTripleType = { hasValue: "sdata:131169", }, ], - label: "Claim -informs-> Question", + label: "supports", creator: "someone", }; @@ -116,9 +117,9 @@ const exRelnInstance = { modified: "2026-06-03T10:13:09.101Z", created: "2026-06-03T10:13:09.101Z", source: "sdata:261134", - destination: "sdata:261140", + destination: "sdata:254918", title: - "[[CLM - New claim for sharing]] -informs-> [[QUE - This is a test question]]", + "[[CLM - Some supporting claim]] -supports-> [[CLM - Some base claim]]", creator: "someone", }; @@ -133,7 +134,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeSchema; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLd(data, url); + const parsedData = await parseJsonLdAsLdo(data, url); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeSchemaProfile; @@ -155,7 +156,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLd(data, url); + const parsedData = await parseJsonLdAsLdo(data, url); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeInstanceProfile; @@ -174,16 +175,16 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { // console.log(turtleData); }); - it("Reads a relation definition", async () => { - const data = exRelnDef; + it("Reads an abstract relation definition", async () => { + const data = exRelnType; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLd(data, url); + const parsedData = await parseJsonLdAsLdo(data, url); const parsedItem = parsedData.filter( (item) => item["@id"] === url, - )[0] as RelationDefProfile; + )[0] as AbstractRelationDefProfile; const types = parsedItem.type.toArray().map((x) => x["@id"]); - expect(types.includes("RelationDef")); + expect(types.includes("AbstractRelationDef")); expect(parsedItem); expect(parsedItem["@id"]); @@ -196,16 +197,16 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { // console.log(turtleData); }); - it("Reads a relation triple definition", async () => { - const data = exRelnTripleType; + it("Reads a relation definition", async () => { + const data = exRelnType; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLd(data, url); + const parsedData = await parseJsonLdAsLdo(data, url); const parsedItem = parsedData.filter( (item) => item["@id"] === url, - )[0] as RelationTripleDefProfile; + )[0] as RelationDefProfile; const types = parsedItem.type.toArray().map((x) => x["@id"]); - expect(types.includes("RelationTripleDef")); + expect(types.includes("RelationDef")); expect(parsedItem); expect(parsedItem["@id"]); expect(parsedItem.domain); @@ -222,7 +223,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exRelnInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLd(data, url); + const parsedData = await parseJsonLdAsLdo(data, url); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as RelationInstanceProfile; From bbbd7290077d4d35fa5f11217e7a32a99d955c23 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 08:56:49 -0400 Subject: [PATCH 10/41] test (failing) --- .../test/integration/upsertJsonLd.test.ts | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 apps/website/test/integration/upsertJsonLd.test.ts diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts new file mode 100644 index 000000000..1a0fd01cc --- /dev/null +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -0,0 +1,156 @@ +import assert from "assert"; +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { + fetchOrCreateSpaceDirect, + spaceAnonUserEmail, +} from "@repo/database/lib/contextFunctions"; +import type { Database, Json } from "@repo/database/dbTypes"; +import type { DGSupabaseClient } from "@repo/database/lib/client"; +import { createClient } from "@supabase/supabase-js"; +import { + populate, + parseJsonLdAsInput, +} from "../../app/utils/conversion/fromJsonLd"; +import { JsonLdDocument } from "jsonld"; + +const SUPABASE_URL = process.env.SUPABASE_URL!; +const ANON_KEY = process.env.SUPABASE_PUBLISHABLE_KEY!; +const SERVICE_KEY = process.env.SUPABASE_SECRET_KEY!; +const PASSWORD = "abcdefgh"; + +const freshClient = (): DGSupabaseClient => + createClient(SUPABASE_URL, ANON_KEY); + +const serviceClient = () => + createClient(SUPABASE_URL, SERVICE_KEY); + +const signedInClient = async (spaceId: number): Promise => { + const client = freshClient(); + const { error } = await client.auth.signInWithPassword({ + email: spaceAnonUserEmail("Roam", spaceId), + password: PASSWORD, + }); + if (error) throw new Error(`Sign-in failed: ${error.message}`); + return client; +}; + +// example data + +const jsonLdData: JsonLdDocument = { + "@context": ["http://localhost:3000/schema/context.jsonld"], + "@graph": [ + { + "@id": "sdata:131157", + "@type": "NodeSchema", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + subClassOf: ["dgc:Claim", "mira:Claim"], + label: "Claim", + creator: "someone", + }, + { + "@id": "sdata:254918", + "@type": ["sdata:131157", "dgc:Claim", "mira:Claim"], + modified: "2026-05-26T00:39:03.077Z", + created: "2025-12-04T15:47:51.694Z", + title: "CLM - Some base claim", + description: { + "@id": "page:content", + format: "text/html", + content: + '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', + }, + creator: "someone", + }, + { + "@id": "sdata:131164", + "@type": "AbstractRelationDef", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + subClassOf: [ + "dgb:RelationInstance", + { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:131164", + }, + ], + label: "supports", + creator: "someone", + }, + { + "@id": "sdata:131169", + "@type": "RelationDef", + modified: "2026-01-24T15:38:14.553Z", + created: "2026-01-24T15:38:14.553Z", + domain: "sdata:131157", + range: "sdata:131157", + subClassOf: [ + "dgb:RelationInstance", + { + "@type": "owl:Restriction", + onProperty: "rdf:predicate", + hasValue: "sdata:131169", + }, + ], + label: "supports", + creator: "someone", + }, + { + "@id": "sdata:261147", + "@type": "sdata:131164", + modified: "2026-06-03T10:13:09.101Z", + created: "2026-06-03T10:13:09.101Z", + source: "sdata:261134", + destination: "sdata:254918", + title: + "[[CLM - Some supporting claim]] -supports-> [[CLM - Some base claim]]", + creator: "someone", + }, + ], +}; + +describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { + let spaceId: number; + let spaceAccountUuid: string; + let client: DGSupabaseClient; + + beforeAll(async () => { + const spaceReq = await fetchOrCreateSpaceDirect({ + name: "vitest-spaceReq", + url: "https://roamresearch.com/#/app/vitest-spaceReq", + platform: "Roam", + password: PASSWORD, + }); + if (!spaceReq.data) + throw new Error(`Failed to create space 1: ${spaceReq.error?.message}`); + spaceId = spaceReq.data.id; + client = await signedInClient(spaceId); + assert(client); + const accountReq = await client + .from("PlatformAccount") + .select("id,dg_account") + .eq( + "account_local_id", + `roam-${spaceId}-anon@database.discoursegraphs.com`, + ) + .maybeSingle(); + assert(!accountReq.error); + assert(accountReq.data); + assert(accountReq.data.dg_account); + spaceAccountUuid = accountReq.data.dg_account; + }); + afterAll(async () => { + if (spaceAccountUuid) + await serviceClient().auth.admin.deleteUser(spaceAccountUuid); + if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); + }); + + it("Upserts the data", async () => { + const client = await signedInClient(spaceId); + const converted = await parseJsonLdAsInput(client, jsonLdData, spaceId); + console.log(converted); + const response = await populate(client, jsonLdData, spaceId); + assert(response.length === (jsonLdData["@graph"] as Array).length); + }); +}); From 79d85f1ff3497fdb7fc650c8a5ba0530f9ce30a6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 10:19:05 -0400 Subject: [PATCH 11/41] wip --- .../app/utils/conversion/fromJsonLd.ts | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 7323de9b2..4a68f18cc 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -51,10 +51,12 @@ const sourcePredicate = "https://discoursegraphs.com/schema/dg_base#source"; const contentPredicate = "http://rdfs.org/sioc/ns#content"; const descriptionPredicate = "http://purl.org/dc/elements/1.1/description"; const containerType = "http://rdfs.org/sioc/ns#Container"; +const restrictionType = "http://www.w3.org/2002/07/owl#Restriction"; export const parseJsonLdAsLdo = async ( data: JsonLdDocument, baseIRI: string, + knownClasses: Record, ): Promise => { const asQuads = (await toRDF(data, { format: "application/n-quads", @@ -72,6 +74,10 @@ export const parseJsonLdAsLdo = async ( } for (const subject of subjects) { const types = new Set(typeMap[subject]); + if (types.has(restrictionType)) continue; + // const isInstance = typeMap[subject] + // .map((t) => knownClasses.has(t)) + // .reduce((a: boolean, b: boolean) => a || b, false); if (types.has(containerType)) { result.push( ldoDataset.usingType(ContainerProfileShapeType).fromSubject(subject), @@ -154,7 +160,7 @@ const interpretId = ( id: string, dbVarName: DBN, localVarName: LVN, - knownClasses?: Record, + knownClasses?: Record, ): Record | Record => { if (knownClasses && knownClasses[id] !== undefined) return { [localVarName]: knownClasses[id] } as Record; @@ -189,7 +195,7 @@ const maybeAddKnownClass = ( ids: string[], name: string, source_local_id: string, - knownClasses: Record, + knownClasses: Record, ): void => { for (const id of ids) { if (expectedSchemaIris.has(id)) { @@ -217,7 +223,7 @@ const maybeAddKnownClass = ( const parseNodeSchema = ( data: NodeSchemaProfile, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; @@ -248,7 +254,7 @@ const parseContent = ( const parseNodeInstance = ( data: NodeInstanceProfile, content: ContentProfile, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const schemaInfo = data.type.map((x) => @@ -266,7 +272,7 @@ const parseNodeInstance = ( }; const parseAbstractRelationDef = ( data: AbstractRelationDefProfile, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; @@ -281,7 +287,7 @@ const parseAbstractRelationDef = ( }; const parseRelationDef = ( data: RelationDefProfile, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; if (data.label) { @@ -307,7 +313,7 @@ const parseRelationDef = ( const parseRelationInstance = ( data: RelationInstanceProfile, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const schemaInfo = data.type.map((x) => @@ -325,7 +331,7 @@ const parseRelationInstance = ( const parseLdoNode = ( data: NodeParseResult, contentById: Record, - knownClasses: Record, + knownClasses: Record, ): LocalConceptDataInput | null => { if (!data["@id"]) { console.error("No @id: ", data); @@ -344,16 +350,20 @@ const parseLdoNode = ( if (!content) return null; return parseNodeInstance(nodeInstance, content, knownClasses); } - if (types.has("RelationDef")) + if ( + types.has("RelationDef") && + (data as RelationDefProfile).domain && + (data as RelationDefProfile).range + ) return parseRelationDef(data as RelationDefProfile, knownClasses); - if (types.has("AbstractRelationDef")) + else if (types.has("AbstractRelationDef") || types.has("RelationDef")) return parseAbstractRelationDef( data as AbstractRelationDefProfile, knownClasses, ); if (types.has("NodeSchema")) return parseNodeSchema(data as NodeSchemaProfile, knownClasses); - console.error("We should not get here"); + console.error("We should not get here", types, data); return null; }; @@ -368,9 +378,9 @@ const nodeOrder = [ export const parseJsonLdAsDataInputWithSchemas = async ( data: JsonLdDocument, baseIRI: string, - knownClasses: Record, + knownClasses: Record, ): Promise => { - const ldoData = await parseJsonLdAsLdo(data, baseIRI); + const ldoData = await parseJsonLdAsLdo(data, baseIRI, knownClasses); const contents = ldoData.filter((d) => d.type .toArray() @@ -430,7 +440,7 @@ export const parseJsonLdAsInput = async ( ]), ) .flat(), - ); + ) as Record; return await parseJsonLdAsDataInputWithSchemas( jsonLdData, baseIri, From 7b6d7fdabbe094cc232fcb1621a24ff1f94d512e Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 22:05:45 -0400 Subject: [PATCH 12/41] wip --- apps/website/app/utils/conversion/convert.ts | 3 +- .../app/utils/conversion/fromJsonLd.ts | 279 ++++++---- apps/website/app/utils/conversion/jsonld.ts | 21 +- .../app/utils/conversion/shapes/dgBase.shex | 8 +- apps/website/package.json | 3 + apps/website/public/schema/context.jsonld | 8 +- .../test/integration/parseJsonLd.test.ts | 12 +- .../test/integration/upsertJsonLd.test.ts | 18 +- pnpm-lock.yaml | 486 ++++++++++-------- 9 files changed, 495 insertions(+), 343 deletions(-) diff --git a/apps/website/app/utils/conversion/convert.ts b/apps/website/app/utils/conversion/convert.ts index 59fcc07f5..04eddbc94 100644 --- a/apps/website/app/utils/conversion/convert.ts +++ b/apps/website/app/utils/conversion/convert.ts @@ -1,4 +1,5 @@ import showdown from "showdown"; +import { JSDOM } from "jsdom"; export type DocType = "obsidian" | "roam" | "html" | "markdown"; @@ -35,7 +36,7 @@ export const convert = ( return converter.makeHtml(text); } if (markdownTypes.has(dest) && source === "html") { - return converter.makeMarkdown(text); + return converter.makeMarkdown(text, new JSDOM().window.document); } throw new Error("Types not handled"); }; diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 4a68f18cc..ca057194a 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -24,9 +24,17 @@ import type { RelationDefProfile, AbstractRelationDefProfile, } from "./ldo/dgBase.typings"; -import { KnownSchemaIris, KnownSchemaEntities, curieToIri } from "./jsonld"; +import { + KnownSchemaIris, + KnownSchemaEntities, + KnownRelationEntities, + curieToIri, + KnownClassIris, + KnownRelationIris, +} from "./jsonld"; import { DGSupabaseClient } from "@repo/database/lib/client"; import { Json } from "@repo/database/dbTypes"; +import { intersection } from "@repo/utils/setOperations"; const apiRoot = process.env.NEXT_API_ROOT; const nodeOrSpaceIdRegex = RegExp(`^${apiRoot}/data/\d+(/\d+)?$`); @@ -46,21 +54,34 @@ const relationDefType = "https://discoursegraphs.com/schema/dg_base#RelationDef"; const abstractRelationDefType = "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef"; -const domainPredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#domain"; + +const domainPredicate = "http://www.w3.org/2000/01/rdf-schema#domain"; const sourcePredicate = "https://discoursegraphs.com/schema/dg_base#source"; const contentPredicate = "http://rdfs.org/sioc/ns#content"; const descriptionPredicate = "http://purl.org/dc/elements/1.1/description"; const containerType = "http://rdfs.org/sioc/ns#Container"; const restrictionType = "http://www.w3.org/2002/07/owl#Restriction"; +export const schemaTypeSet = new Set([ + nodeSchemaType, + relationDefType, + abstractRelationDefType, +]); + +export type SchemaTypes = + | "https://discoursegraphs.com/schema/dg_base#NodeSchema" + | "https://discoursegraphs.com/schema/dg_base#RelationDef" + | "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef"; export const parseJsonLdAsLdo = async ( data: JsonLdDocument, baseIRI: string, - knownClasses: Record, + knownIris: Record, + knownSchemaTypes: Record, ): Promise => { const asQuads = (await toRDF(data, { format: "application/n-quads", })) as string; + // console.log(asQuads); const ldoDataset = await parseRdf(asQuads, { baseIRI, }); @@ -73,11 +94,20 @@ export const parseJsonLdAsLdo = async ( else typeMap[s] = [q.object.value]; } for (const subject of subjects) { - const types = new Set(typeMap[subject]); + const typesA = typeMap[subject]; + if (!typesA) continue; + const types = new Set(typesA); if (types.has(restrictionType)) continue; - // const isInstance = typeMap[subject] - // .map((t) => knownClasses.has(t)) - // .reduce((a: boolean, b: boolean) => a || b, false); + if (intersection(types, schemaTypeSet).size) { + typesA.map((t) => { + if (schemaTypeSet.has(t)) { + knownSchemaTypes[subject] = t as SchemaTypes; + } + if (KnownSchemaIris.has(t) && knownIris[t] === undefined) { + knownIris[t] = subject; + } + }); + } if (types.has(containerType)) { result.push( ldoDataset.usingType(ContainerProfileShapeType).fromSubject(subject), @@ -88,21 +118,27 @@ export const parseJsonLdAsLdo = async ( result.push( ldoDataset.usingType(NodeSchemaProfileShapeType).fromSubject(subject), ); + knownSchemaTypes[subject] = nodeSchemaType; continue; } if (types.has(abstractRelationDefType) || types.has(relationDefType)) { - if (ldoDataset.match(namedNode(subject), namedNode(domainPredicate)).size) + if ( + ldoDataset.match(namedNode(subject), namedNode(domainPredicate)).size + ) { result.push( ldoDataset .usingType(RelationDefProfileShapeType) .fromSubject(subject), ); - else + knownSchemaTypes[subject] = relationDefType; + } else { result.push( ldoDataset .usingType(AbstractRelationDefProfileShapeType) .fromSubject(subject), ); + knownSchemaTypes[subject] = abstractRelationDefType; + } continue; } if ( @@ -113,14 +149,28 @@ export const parseJsonLdAsLdo = async ( ); continue; } - // happy path: The types are there - const typesOfTypes = new Set( - (typeMap[subject] || []).map((t) => typeMap[t] || []).flat(), - ); - if ( - typesOfTypes.has(abstractRelationDefType) || - typesOfTypes.has(relationDefType) - ) { + // New we know it's an instance; try to add the underlying schema type + let schemaType: string | undefined; + typesA.map((t) => { + if (knownSchemaTypes[t]) schemaType = knownSchemaTypes[t]; + const v2 = knownIris[t]; + if (v2 && knownSchemaTypes[v2]) schemaType = knownSchemaTypes[v2]; + }); + if (schemaType === nodeSchemaType) { + result.push( + ldoDataset.usingType(NodeInstanceProfileShapeType).fromSubject(subject), + ); + continue; + } else if (schemaType !== undefined) { + result.push( + ldoDataset + .usingType(RelationInstanceProfileShapeType) + .fromSubject(subject), + ); + continue; + } + // otherwise use heuristics + if (intersection(KnownRelationIris, types).size > 0) { result.push( ldoDataset .usingType(RelationInstanceProfileShapeType) @@ -128,13 +178,12 @@ export const parseJsonLdAsLdo = async ( ); continue; } - if (typesOfTypes.has(nodeSchemaType)) { + if (intersection(KnownClassIris, types).size > 0) { result.push( ldoDataset.usingType(NodeInstanceProfileShapeType).fromSubject(subject), ); continue; } - // otherwise use heuristics if (ldoDataset.match(namedNode(subject), namedNode(sourcePredicate)).size) { result.push( ldoDataset @@ -153,6 +202,8 @@ export const parseJsonLdAsLdo = async ( } console.error("Could not interpret ", subject); } + // console.log("knownSchemaTypes after:", knownSchemaTypes); + // console.log("knownIris after:", knownIris); return result; }; @@ -160,10 +211,10 @@ const interpretId = ( id: string, dbVarName: DBN, localVarName: LVN, - knownClasses?: Record, + knownIris?: Record, ): Record | Record => { - if (knownClasses && knownClasses[id] !== undefined) - return { [localVarName]: knownClasses[id] } as Record; + if (knownIris && knownIris[id] !== undefined) + return { [localVarName]: knownIris[id] } as Record; if (nodeOrSpaceIdRegex.test(id)) { const parts = id.split("/"); return { [dbVarName]: Number.parseInt(parts[parts.length - 1]!) } as Record< @@ -189,33 +240,32 @@ const parseBaseData = (data: NodeParseResult) => { }; }; -const expectedSchemaIris = new Set(KnownSchemaIris); - const maybeAddKnownClass = ( ids: string[], - name: string, + name: string | undefined, source_local_id: string, - knownClasses: Record, + knownIris: Record, ): void => { for (const id of ids) { - if (expectedSchemaIris.has(id)) { - if (knownClasses[id] === undefined) { - knownClasses[id] = source_local_id; + if (KnownSchemaIris.has(id)) { + if (knownIris[id] === undefined) { + knownIris[id] = source_local_id; return; - } else if (knownClasses[id] !== source_local_id) { - console.error("Conflict on class", id); + } else if (knownIris[id] !== source_local_id) { + console.error("Conflict 1 on class", id); return; } } } // hackish - if (KnownSchemaEntities[name] === undefined) return; + if (name === undefined || KnownSchemaEntities[name] === undefined) return; for (const id of KnownSchemaEntities[name]) { - if (knownClasses[id] === undefined) { - knownClasses[id] = source_local_id; + const iri = curieToIri(id); + if (knownIris[iri] === undefined) { + knownIris[iri] = source_local_id; return; - } else if (knownClasses[id] !== source_local_id) { - console.error("Conflict on class", id); + } else if (knownIris[iri] !== source_local_id) { + console.error("Conflict 2 on class", id); return; } } @@ -223,11 +273,11 @@ const maybeAddKnownClass = ( const parseNodeSchema = ( data: NodeSchemaProfile, - knownClasses: Record, + knownIris: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; - maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); + maybeAddKnownClass(ids, data.label, data["@id"], knownIris); return { name: data.label, is_schema: true, @@ -240,13 +290,14 @@ const parseContent = ( content: ContentProfile, data: NodeInstanceProfile, ): LocalContentDataInput | null => { - if (data["@id"] == null) return null; + const id = content["@id"] ?? data["@id"]; // they can share identity + if (!id) return null; const sourceFormat = DOCTYPES[content.format || ""] ?? "html"; const text = convert(content.content, sourceFormat, "obsidian"); return { text, scale: "document", - ...baseInterpretId(data["@id"]), + ...baseInterpretId(id), ...parseBaseData(data), }; }; @@ -254,17 +305,18 @@ const parseContent = ( const parseNodeInstance = ( data: NodeInstanceProfile, content: ContentProfile, - knownClasses: Record, + knownIris: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const schemaInfo = data.type.map((x) => - interpretId(x["@id"], "schema_id", "schema_local_id", knownClasses), + interpretId(x["@id"], "schema_id", "schema_local_id", knownIris), ); if (!schemaInfo.length) return null; // TODO If there's many types, how to choose? + const parsedContent = parseContent(content, data); return { name: data.title, - contents_inline: [parseContent(content, data)].filter((c) => c !== null), + contents_inline: parsedContent ? [parsedContent] : [], ...schemaInfo[0], ...baseInterpretId(data["@id"]), ...parseBaseData(data), @@ -272,40 +324,48 @@ const parseNodeInstance = ( }; const parseAbstractRelationDef = ( data: AbstractRelationDefProfile, - knownClasses: Record, + knownIris: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; - maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); + maybeAddKnownClass(ids, data.label, data["@id"], knownIris); return { name: data.label, is_schema: true, - literal_content: { roles: ["source", "destination"] }, + literal_content: { roles: ["source", "destination"], label: data.label }, ...baseInterpretId(data["@id"]), ...parseBaseData(data), }; }; const parseRelationDef = ( data: RelationDefProfile, - knownClasses: Record, + knownIris: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; - if (data.label) { - const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; - maybeAddKnownClass(ids, data.label, data["@id"], knownClasses); - } - const source_ids = knownClasses[data.domain["@id"]]; - const destination_ids = knownClasses[data.range["@id"]]; - const source_id = Array.isArray(source_ids) ? source_ids[0] : source_ids; - const destination_id = Array.isArray(destination_ids) - ? destination_ids[0] - : destination_ids; - if (source_id === undefined || destination_id === undefined) return null; - // TODO: Find the relation_type if appropriate + let relationType: string | undefined; + const ids = [data["@id"], ...(data.subClassOf || []).map((x) => x["@id"])]; + (KnownRelationEntities[data.label] || []).map((curie) => { + curie = curieToIri(curie); + if (knownIris[curie] !== undefined) relationType = knownIris[curie]; + }); + if (relationType === undefined) + maybeAddKnownClass(ids, data.label, data["@id"], knownIris); + let sourceId = data.domain["@id"]; + let destinationId = data.range["@id"]; + sourceId = knownIris[sourceId] || sourceId; + destinationId = knownIris[destinationId] || destinationId; + if (sourceId === undefined || destinationId === undefined) return null; + // TODO: find the names of source and dest class + const refContent: Record = { + source: sourceId, + destination: destinationId, + }; + if (relationType) refContent["relation_type"] = relationType; return { - local_reference_content: { source: source_id, destination: destination_id }, + literal_content: { roles: ["source", "destination"], label: data.label }, + local_reference_content: refContent, is_schema: true, - name: data.label, + name: `${sourceId} -${data.label}-> ${destinationId}`, ...baseInterpretId(data["@id"]), ...parseBaseData(data), }; @@ -313,16 +373,22 @@ const parseRelationDef = ( const parseRelationInstance = ( data: RelationInstanceProfile, - knownClasses: Record, + knownIris: Record, ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; - const schemaInfo = data.type.map((x) => - interpretId(x["@id"], "schema_id", "schema_local_id", knownClasses), + const schemaInfos = data.type.map((x) => + interpretId(x["@id"], "schema_id", "schema_local_id", knownIris), ); - if (!schemaInfo.length) return null; + const schemaInfo = schemaInfos[0]; + if (!schemaInfo) return null; // TODO If there's many types, how to choose? + const source = data.source["@id"]; + const destination = data.destination["@id"]; + // TODO: find the names of source and dest instances, rel label return { - ...schemaInfo[0], + ...schemaInfo, + name: `${source} -${"schema_local_id" in schemaInfo ? schemaInfo.schema_local_id : schemaInfo.schema_id}-> ${destination}`, + local_reference_content: { source, destination }, ...interpretId(data["@id"], "id", "source_local_id"), ...parseBaseData(data), }; @@ -331,39 +397,50 @@ const parseRelationInstance = ( const parseLdoNode = ( data: NodeParseResult, contentById: Record, - knownClasses: Record, + knownIris: Record, + knownSchemaTypes: Record, ): LocalConceptDataInput | null => { if (!data["@id"]) { console.error("No @id: ", data); return null; } - const types = new Set(data.type.map((x) => x["@id"])); + const typesA = data.type.map((x) => x["@id"]); + const types = new Set(typesA); if (types.size === 0) return null; - if (types.has("RelationInstance")) - return parseRelationInstance(data as RelationInstanceProfile, knownClasses); - if (types.has("NodeInstance")) { - const nodeInstance = data as NodeInstanceProfile; - if (!nodeInstance.description) return null; - const content = nodeInstance.description.content - ? nodeInstance.description - : contentById[nodeInstance.description["@id"]!]; - if (!content) return null; - return parseNodeInstance(nodeInstance, content, knownClasses); - } if ( types.has("RelationDef") && (data as RelationDefProfile).domain && (data as RelationDefProfile).range ) - return parseRelationDef(data as RelationDefProfile, knownClasses); + return parseRelationDef(data as RelationDefProfile, knownIris); else if (types.has("AbstractRelationDef") || types.has("RelationDef")) return parseAbstractRelationDef( data as AbstractRelationDefProfile, - knownClasses, + knownIris, ); if (types.has("NodeSchema")) - return parseNodeSchema(data as NodeSchemaProfile, knownClasses); - console.error("We should not get here", types, data); + return parseNodeSchema(data as NodeSchemaProfile, knownIris); + + // naw instance heuristics + let schemaType: string | undefined; + typesA.map((t) => { + if (knownSchemaTypes[t]) schemaType = knownSchemaTypes[t]; + const v2 = knownIris[t]; + if (v2 && knownSchemaTypes[v2]) schemaType = knownSchemaTypes[v2]; + }); + if (schemaType === nodeSchemaType) { + const nodeInstance = data as NodeInstanceProfile; + if (!nodeInstance.description) return null; + const content = nodeInstance.description.content + ? nodeInstance.description + : contentById[nodeInstance.description["@id"]!]; + if (!content) return null; + return parseNodeInstance(nodeInstance, content, knownIris); + } + if (schemaType === relationDefType || schemaType === abstractRelationDefType) + return parseRelationInstance(data as RelationInstanceProfile, knownIris); + + console.error("We should not get here", [...types], data); return null; }; @@ -378,9 +455,15 @@ const nodeOrder = [ export const parseJsonLdAsDataInputWithSchemas = async ( data: JsonLdDocument, baseIRI: string, - knownClasses: Record, + knownIris: Record, + knownSchemaTypes: Record, ): Promise => { - const ldoData = await parseJsonLdAsLdo(data, baseIRI, knownClasses); + const ldoData = await parseJsonLdAsLdo( + data, + baseIRI, + knownIris, + knownSchemaTypes, + ); const contents = ldoData.filter((d) => d.type .toArray() @@ -414,7 +497,7 @@ export const parseJsonLdAsDataInputWithSchemas = async ( return 0; }); return nodesWithoutContents - .map((d) => parseLdoNode(d, contentById, knownClasses)) + .map((d) => parseLdoNode(d, contentById, knownIris, knownSchemaTypes)) .filter((x) => !!x); }; @@ -426,13 +509,13 @@ export const parseJsonLdAsInput = async ( const baseIri = `${apiRoot}/data/${spaceId}`; const { error, data } = await supabase .from("Concept") - .select("name,source_local_id") + .select("name,source_local_id,arity,reference_content") .eq("space_id", spaceId) .eq("is_schema", true); if (error) throw error; - const knownClasses = Object.fromEntries( + const knownIris = Object.fromEntries( data - .filter(({ name, source_local_id }) => source_local_id !== null) + .filter(({ source_local_id }) => source_local_id !== null) .map(({ name, source_local_id }) => (KnownSchemaEntities[name] || []).map((c) => [ curieToIri(c), @@ -441,10 +524,26 @@ export const parseJsonLdAsInput = async ( ) .flat(), ) as Record; + const knownSchemaTypes = Object.fromEntries( + data + .filter(({ source_local_id }) => source_local_id !== null) + .map(({ source_local_id, arity, reference_content }) => { + if (arity !== 2) return [source_local_id, nodeSchemaType]; + if ( + (reference_content as Record).source && + (reference_content as Record).destination + ) { + return [source_local_id, relationDefType]; + } else { + return [source_local_id, abstractRelationDefType]; + } + }), + ) as Record; return await parseJsonLdAsDataInputWithSchemas( jsonLdData, baseIri, - knownClasses, + knownIris, + knownSchemaTypes, ); }; diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index 551bf57a5..4045e3294 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -7,11 +7,15 @@ type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; // This is a temporary hack -export const KnownSchemaEntities: Record = { +export const KnownClassEntities: Record = { Claim: ["dgc:Claim", "mira:Claim"], Evidence: ["dgc:Evidence", "mira:Evidence"], Question: ["dgc:Question", "mira:Question"], SourceDocument: ["dgc:SourceDocument"], + Request: ["mira:Request"], + Protocol: ["mira:Protocol"], +}; +export const KnownRelationEntities: Record = { describesActivity: ["dgc:describesActivity"], observationStatement: ["dgc:observationStatement"], observationOriginActivity: ["dgc:observationOriginActivity"], @@ -23,8 +27,6 @@ export const KnownSchemaEntities: Record = { supportedBy: ["dgc:supportedBy"], addresses: ["dgc:addresses"], addressedBy: ["dgc:addressedBy"], - Request: ["mira:Request"], - Protocol: ["mira:Protocol"], follows: ["mira:follows"], grounds: ["mira:grounds"], is_grounded_in: ["mira:is_grounded_in"], @@ -32,6 +34,11 @@ export const KnownSchemaEntities: Record = { request_target: ["mira:request_target"], }; +export const KnownSchemaEntities: Record = { + ...KnownClassEntities, + ...KnownRelationEntities, +}; + const prefixes: Record = { rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", rdfs: "http://www.w3.org/2000/01/rdf-schema#", @@ -45,7 +52,7 @@ const prefixes: Record = { }; export const curieToIri = (curie: string): string => { - const [prefix, name]: string[] = curie.split(":", 1); + const [prefix, name]: string[] = curie.split(":", 2); const iri = prefixes[prefix || ""]; if (iri === undefined) { console.error("Unknown prefix", prefix); @@ -54,8 +61,12 @@ export const curieToIri = (curie: string): string => { return iri + name; }; +export const KnownClassCuries = Object.values(KnownClassEntities).flat(); +export const KnownClassIris = new Set(KnownClassCuries.map(curieToIri)); +export const KnownRelationCuries = Object.values(KnownRelationEntities).flat(); +export const KnownRelationIris = new Set(KnownRelationCuries.map(curieToIri)); export const KnownSchemaCuries = Object.values(KnownSchemaEntities).flat(); -export const KnownSchemaIris = KnownSchemaCuries.map(curieToIri); +export const KnownSchemaIris = new Set(KnownSchemaCuries.map(curieToIri)); export const asJsonLD = ({ space, diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index 540d6c984..2911776a7 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -1,7 +1,3 @@ -# This shape is provided by default as an example -# You can create your own shape to fit your needs using ShEx (https://shex.io) -# Also check out https://shaperepo.com for examples of more shapes. - PREFIX dc: PREFIX dgb: PREFIX dgshapes: @@ -49,7 +45,7 @@ dgshapes:NodeInstanceProfile { dgshapes:AbstractRelationDefProfile { a [dgb:AbstractRelationDef]; - rdfs:subClassOf IRI*; + rdfs:subClassOf IRI *; sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; @@ -59,7 +55,7 @@ dgshapes:AbstractRelationDefProfile { dgshapes:RelationDefProfile { a [dgshapes:RelationDef]; - rdfs:subClassOf IRI*; + rdfs:subClassOf IRI *; sioc:has_container IRI ?; dc:creator xsd:string ? ; dc:date xsd:dateTime ? ; diff --git a/apps/website/package.json b/apps/website/package.json index f4fca80f3..d1541b7cc 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -21,11 +21,13 @@ "@ldo/rdf-utils": "1.0.0-alpha.51", "@repo/database": "workspace:*", "@repo/ui": "workspace:*", + "@repo/utils": "workspace:*", "@supabase/auth-js": "catalog:", "@supabase/ssr": "catalog:", "@supabase/supabase-js": "catalog:", "clsx": "^2.1.1", "gray-matter": "^4.0.3", + "jsdom": "^29.1.1", "jsonld": "^9.0.0", "lucide-react": "^0.540.0", "next": "^16.2.0", @@ -49,6 +51,7 @@ "@repo/types": "workspace:*", "@repo/typescript-config": "workspace:*", "@tailwindcss/typography": "^0.5.15", + "@types/jsdom": "^28.0.3", "@types/jsonld": "^1.5.15", "@types/node": "^20", "@types/react": "catalog:", diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index ee6e77dab..19da92eb7 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -9,12 +9,14 @@ "dgc": "https://discoursegraphs.com/schema/dg_core#", "dgb": "https://discoursegraphs.com/schema/dg_base#", "mira": "http://purl.org/mira-science/mira#", - "predicate": "rdf:predicate", - "subClassOf": "rdfs:subClassOf", + "predicate": { "@id": "rdf:predicate", "@type": "@id" }, + "subClassOf": { "@id": "rdfs:subClassOf", "@type": "@id" }, + "domain": { "@id": "rdfs:domain", "@type": "@id" }, + "range": { "@id": "rdfs:range", "@type": "@id" }, "label": "rdfs:label", "inverseOf": "owl:inverseOf", "onProperty": "owl:onProperty", - "sameAs": "owl:sameAs", + "sameAs": { "@id": "owl:sameAs", "@type": "@id" }, "hasValue": "owl:hasValue", "title": "dc:title", "format": "dc:format", diff --git a/apps/website/test/integration/parseJsonLd.test.ts b/apps/website/test/integration/parseJsonLd.test.ts index 676c369fc..d63a812b9 100644 --- a/apps/website/test/integration/parseJsonLd.test.ts +++ b/apps/website/test/integration/parseJsonLd.test.ts @@ -134,7 +134,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeSchema; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url); + const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeSchemaProfile; @@ -156,7 +156,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url); + const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeInstanceProfile; @@ -176,10 +176,10 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { }); it("Reads an abstract relation definition", async () => { - const data = exRelnType; + const data = exAbstractRelnDef; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url); + const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as AbstractRelationDefProfile; @@ -201,7 +201,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exRelnType; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url); + const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as RelationDefProfile; @@ -223,7 +223,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exRelnInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url); + const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as RelationInstanceProfile; diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index 1a0fd01cc..3be71deb0 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -55,7 +55,6 @@ const jsonLdData: JsonLdDocument = { created: "2025-12-04T15:47:51.694Z", title: "CLM - Some base claim", description: { - "@id": "page:content", format: "text/html", content: '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', @@ -85,14 +84,7 @@ const jsonLdData: JsonLdDocument = { created: "2026-01-24T15:38:14.553Z", domain: "sdata:131157", range: "sdata:131157", - subClassOf: [ - "dgb:RelationInstance", - { - "@type": "owl:Restriction", - onProperty: "rdf:predicate", - hasValue: "sdata:131169", - }, - ], + subClassOf: ["sdata:131164"], label: "supports", creator: "someone", }, @@ -141,9 +133,9 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { spaceAccountUuid = accountReq.data.dg_account; }); afterAll(async () => { - if (spaceAccountUuid) - await serviceClient().auth.admin.deleteUser(spaceAccountUuid); - if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); + // if (spaceAccountUuid) + // await serviceClient().auth.admin.deleteUser(spaceAccountUuid); + // if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); }); it("Upserts the data", async () => { @@ -151,6 +143,8 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { const converted = await parseJsonLdAsInput(client, jsonLdData, spaceId); console.log(converted); const response = await populate(client, jsonLdData, spaceId); + console.log(response); assert(response.length === (jsonLdData["@graph"] as Array).length); + assert(Math.min(...response) > 0); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c9342f51..f8903c1cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,7 +343,7 @@ importers: version: 3.5.2(react@18.2.0) roamjs-components: specifier: 0.88.1 - version: 0.88.1(6fc269b31b2749e4d441ca378d1de710) + version: 0.88.1(e143305b3f00d4cb853970aa683101f5) tldraw: specifier: 2.4.6 version: 2.4.6(patch_hash=56e196052862c9a58a11b43e5e121384cd1d6548416afa0f16e9fbfbf0e4080d)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -445,6 +445,9 @@ importers: '@repo/ui': specifier: workspace:* version: link:../../packages/ui + '@repo/utils': + specifier: workspace:* + version: link:../../packages/utils '@supabase/auth-js': specifier: 'catalog:' version: 2.105.4 @@ -460,6 +463,9 @@ importers: gray-matter: specifier: ^4.0.3 version: 4.0.3 + jsdom: + specifier: ^29.1.1 + version: 29.1.1 jsonld: specifier: ^9.0.0 version: 9.0.0 @@ -524,6 +530,9 @@ importers: '@tailwindcss/typography': specifier: ^0.5.15 version: 0.5.16(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) + '@types/jsdom': + specifier: ^28.0.3 + version: 28.0.3 '@types/jsonld': specifier: ^1.5.15 version: 1.5.15 @@ -565,7 +574,7 @@ importers: version: 5.5.4 vitest: specifier: ^4.0.0 - version: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) packages/database: dependencies: @@ -638,7 +647,7 @@ importers: version: 15.0.4 '@vercel/style-guide': specifier: ^6.0.0 - version: 6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) + version: 6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) eslint: specifier: 'catalog:' version: 8.57.1 @@ -807,6 +816,21 @@ packages: resolution: {integrity: sha512-C90iyzm/jLV7Lomv2UzwWUzRv9WZr1oRsFRKsX5HjQL4EXrbi9H/RtBkjCP+NF+ABZXUKpAa4F1dkoTaea4zHg==} hasBin: true + '@asamuzakjp/css-color@5.1.11': + resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/dom-selector@7.1.1': + resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/generational-cache@1.0.1': + resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} engines: {node: '>=16.0.0'} @@ -1133,6 +1157,10 @@ packages: '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + '@bramus/specificity@2.4.2': + resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + hasBin: true + '@bundled-es-modules/cookie@2.0.1': resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} @@ -1314,6 +1342,42 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@csstools/color-helpers@6.0.2': + resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} + engines: {node: '>=20.19.0'} + + '@csstools/css-calc@3.2.1': + resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-color-parser@4.1.1': + resolution: {integrity: sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-parser-algorithms@4.0.0': + resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.5': + resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + + '@csstools/css-tokenizer@4.0.0': + resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + engines: {node: '>=20.19.0'} + '@cucumber/ci-environment@13.0.0': resolution: {integrity: sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==} @@ -2180,6 +2244,15 @@ packages: resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@exodus/bytes@1.15.1': + resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} @@ -5262,8 +5335,8 @@ packages: '@types/jquery@3.5.33': resolution: {integrity: sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==} - '@types/jsdom@20.0.1': - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + '@types/jsdom@28.0.3': + resolution: {integrity: sha512-/HQ2uFoetFTXuye8vzIcHw2z6Fwi7Hi/qcgC+RoS9NCyewiqxhVGqlG+ViGB6lkax481R6dmhf1I7lIGlzJStQ==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -5803,10 +5876,6 @@ packages: resolution: {integrity: sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==} engines: {node: '>=18.12.0'} - abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead - abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -5819,9 +5888,6 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} - acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -5855,10 +5921,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -6153,6 +6215,9 @@ packages: peerDependencies: react: '>=16.8' + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + bin-links@6.0.0: resolution: {integrity: sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==} engines: {node: ^20.17.0 || >=22.9.0} @@ -6669,21 +6734,15 @@ packages: crypto-js@3.1.9-1: resolution: {integrity: sha512-W93aKztssqf29OvUlqfikzGyYbD1rpkXvGP9IQ1JchLY3bxaLXZSWYbwrtib2vk8DobrDzX7PIXcDWHp0B6Ymw==} + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - - cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - - cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} - csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -6893,9 +6952,9 @@ packages: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} - data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} @@ -7085,11 +7144,6 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead - domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} @@ -7175,6 +7229,10 @@ packages: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -8122,9 +8180,9 @@ packages: hotkeys-js@3.13.15: resolution: {integrity: sha512-gHh8a/cPTCpanraePpjRxyIlxDFrIhYqjuh01UHWEwDpglJKCnvLW8kqSx5gQtOuSsJogNZXLhOdbSExpgUiqg==} - html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -8161,10 +8219,6 @@ packages: resolution: {integrity: sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==} engines: {node: '>=6.0.0'} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -8172,10 +8226,6 @@ packages: http-response-object@3.0.2: resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - https-proxy-agent@6.2.1: resolution: {integrity: sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==} engines: {node: '>= 14'} @@ -8647,11 +8697,11 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@20.0.3: - resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} - engines: {node: '>=14'} + jsdom@29.1.1: + resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} peerDependencies: - canvas: ^2.5.0 + canvas: ^3.0.0 peerDependenciesMeta: canvas: optional: true @@ -8949,6 +8999,10 @@ packages: resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} engines: {node: 20 || >=22} + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + engines: {node: 20 || >=22} + lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -9082,6 +9136,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -9562,9 +9619,6 @@ packages: resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - nwsapi@2.2.21: - resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -9793,6 +9847,9 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + parseley@0.12.1: resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} @@ -10220,9 +10277,6 @@ packages: pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} @@ -10245,9 +10299,6 @@ packages: query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -10634,9 +10685,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - resend@4.8.0: resolution: {integrity: sha512-R8eBOFQDO6dzRTDmaMEdpqrkmgSjPpVXt4nGfWsZdYOet0kqra0xgbvTES6HmCriZEXbmGk3e0DiGIaLFTFSHA==} engines: {node: '>=18'} @@ -11495,20 +11543,20 @@ packages: toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - tough-cookie@6.0.0: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} @@ -11774,6 +11822,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.27.1: + resolution: {integrity: sha512-NyfbU7cCMYYxzBT07eOv0/WR3L5j6vmza6sRlF2sDVCkNvsNaCcaFDGu0a4WqzE983tKuSk7YRTY2C+1krumMg==} + undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} @@ -11842,10 +11893,6 @@ packages: universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -11878,9 +11925,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -12073,9 +12117,9 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} @@ -12103,22 +12147,17 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} - whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + whatwg-url@16.0.1: + resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -12237,9 +12276,9 @@ packages: resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} engines: {node: '>= 6.0'} - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} @@ -12397,6 +12436,26 @@ snapshots: '@antfu/ni@23.3.1': {} + '@asamuzakjp/css-color@5.1.11': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@asamuzakjp/dom-selector@7.1.1': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.2.1 + is-potential-custom-element-name: 1.0.1 + + '@asamuzakjp/generational-cache@1.0.1': {} + + '@asamuzakjp/nwsapi@2.3.9': {} + '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 @@ -13162,6 +13221,10 @@ snapshots: '@braintree/sanitize-url@7.1.2': {} + '@bramus/specificity@2.4.2': + dependencies: + css-tree: 3.2.1 + '@bundled-es-modules/cookie@2.0.1': dependencies: cookie: 0.7.2 @@ -13479,6 +13542,30 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@csstools/color-helpers@6.0.2': {} + + '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-color-parser@4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/color-helpers': 6.0.2 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.0': {} + '@cucumber/ci-environment@13.0.0': {} '@cucumber/cucumber-expressions@19.0.0': @@ -14059,6 +14146,8 @@ snapshots: '@eslint/js@9.34.0': {} + '@exodus/bytes@1.15.1': {} + '@fastify/busboy@2.1.1': {} '@floating-ui/core@1.7.3': @@ -16887,11 +16976,11 @@ snapshots: '@rushstack/eslint-patch@1.12.0': {} - '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': + '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': dependencies: '@aws-sdk/client-lambda': 3.882.0 '@aws-sdk/client-s3': 3.882.0 - '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) archiver: 5.3.2 axios: 0.27.2(debug@4.4.3) debug: 4.4.3 @@ -16902,16 +16991,16 @@ snapshots: ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) zod: 3.25.76 - '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))': + '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))': dependencies: '@playwright/test': 1.29.0 '@testing-library/react': 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@types/jsdom': 20.0.1 + '@types/jsdom': 28.0.3 c8: 7.14.0 debug: 4.4.3 dotenv: 16.6.1 - jsdom: 20.0.3 + jsdom: 29.1.1 ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) '@selderee/plugin-htmlparser2@0.11.0': @@ -18089,11 +18178,12 @@ snapshots: dependencies: '@types/sizzle': 2.3.10 - '@types/jsdom@20.0.1': + '@types/jsdom@28.0.3': dependencies: '@types/node': 20.19.13 '@types/tough-cookie': 4.0.5 - parse5: 7.3.0 + parse5: 8.0.1 + undici-types: 7.27.1 '@types/json-schema@7.0.15': {} @@ -18776,7 +18866,7 @@ snapshots: json-schema-to-ts: 1.6.4 ts-morph: 12.0.0 - '@vercel/style-guide@6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)))': + '@vercel/style-guide@6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@babel/core': 7.28.3 '@babel/eslint-parser': 7.28.0(@babel/core@7.28.3)(eslint@8.57.1) @@ -18796,7 +18886,7 @@ snapshots: eslint-plugin-testing-library: 6.5.0(eslint@8.57.1)(typescript@5.5.4) eslint-plugin-tsdoc: 0.2.17 eslint-plugin-unicorn: 51.0.1(eslint@8.57.1) - eslint-plugin-vitest: 0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) + eslint-plugin-vitest: 0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) prettier-plugin-packagejson: 2.5.19(prettier@3.6.2) optionalDependencies: '@next/eslint-plugin-next': 15.0.4 @@ -18861,8 +18951,6 @@ snapshots: js-yaml: 3.14.1 tslib: 2.5.1 - abab@2.0.6: {} - abbrev@3.0.1: {} abort-controller@3.0.0: @@ -18874,11 +18962,6 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn-globals@7.0.1: - dependencies: - acorn: 8.16.0 - acorn-walk: 8.3.4 - acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -18899,12 +18982,6 @@ snapshots: acorn@8.16.0: {} - agent-base@6.0.2: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - agent-base@7.1.4: {} agent-base@9.0.0: {} @@ -19209,6 +19286,10 @@ snapshots: mathjax-full: 3.2.2 react: 19.1.1 + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + bin-links@6.0.0: dependencies: cmd-shim: 8.0.0 @@ -19745,15 +19826,12 @@ snapshots: crypto-js@3.1.9-1: {} - cssesc@3.0.0: {} - - cssom@0.3.8: {} - - cssom@0.5.0: {} - - cssstyle@2.3.0: + css-tree@3.2.1: dependencies: - cssom: 0.3.8 + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -19989,11 +20067,12 @@ snapshots: data-uri-to-buffer@6.0.2: {} - data-urls@3.0.2: + data-urls@7.0.0: dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1 + transitivePeerDependencies: + - '@noble/hashes' data-view-buffer@1.0.2: dependencies: @@ -20162,10 +20241,6 @@ snapshots: domelementtype@2.3.0: {} - domexception@4.0.0: - dependencies: - webidl-conversions: 7.0.0 - domhandler@5.0.3: dependencies: domelementtype: 2.3.0 @@ -20246,6 +20321,8 @@ snapshots: entities@7.0.1: {} + entities@8.0.0: {} + environment@1.1.0: {} error-ex@1.3.2: @@ -20728,13 +20805,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-vitest@0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))): + eslint-plugin-vitest@0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))): dependencies: '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.5.4) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4) - vitest: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + vitest: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - supports-color - typescript @@ -21657,9 +21734,11 @@ snapshots: hotkeys-js@3.13.15: {} - html-encoding-sniffer@3.0.0: + html-encoding-sniffer@6.0.0: dependencies: - whatwg-encoding: 2.0.0 + '@exodus/bytes': 1.15.1 + transitivePeerDependencies: + - '@noble/hashes' html-escaper@2.0.2: {} @@ -21714,14 +21793,6 @@ snapshots: http-link-header@1.1.3: {} - http-proxy-agent@5.0.0: - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -21733,13 +21804,6 @@ snapshots: dependencies: '@types/node': 10.17.60 - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - https-proxy-agent@6.2.1: dependencies: agent-base: 7.1.4 @@ -22194,38 +22258,31 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@20.0.3: + jsdom@29.1.1: dependencies: - abab: 2.0.6 - acorn: 8.16.0 - acorn-globals: 7.0.1 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 + '@asamuzakjp/css-color': 5.1.11 + '@asamuzakjp/dom-selector': 7.1.1 + '@bramus/specificity': 2.4.2 + '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) + '@exodus/bytes': 1.15.1 + css-tree: 3.2.1 + data-urls: 7.0.0 decimal.js: 10.6.0 - domexception: 4.0.0 - escodegen: 2.1.0 - form-data: 4.0.4 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 + html-encoding-sniffer: 6.0.0 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 - parse5: 7.3.0 + lru-cache: 11.5.1 + parse5: 8.0.1 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 4.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - ws: 8.18.3 - xml-name-validator: 4.0.0 + tough-cookie: 6.0.1 + undici: 7.25.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1 + xml-name-validator: 5.0.0 transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + - '@noble/hashes' jsesc@0.5.0: {} @@ -22536,6 +22593,8 @@ snapshots: lru-cache@11.2.1: {} + lru-cache@11.5.1: {} + lru-cache@4.1.5: dependencies: pseudomap: 1.0.2 @@ -22794,6 +22853,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdn-data@2.27.1: {} + mdurl@2.0.0: {} media-typer@1.1.0: {} @@ -23485,8 +23546,6 @@ snapshots: npm-to-yarn@3.0.1: {} - nwsapi@2.2.21: {} - object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -23802,6 +23861,10 @@ snapshots: dependencies: entities: 6.0.1 + parse5@8.0.1: + dependencies: + entities: 8.0.0 + parseley@0.12.1: dependencies: leac: 0.6.0 @@ -24216,10 +24279,6 @@ snapshots: pseudomap@1.0.2: {} - psl@1.15.0: - dependencies: - punycode: 2.3.1 - pump@3.0.3: dependencies: end-of-stream: 1.4.5 @@ -24239,8 +24298,6 @@ snapshots: query-selector-shadow-dom@1.0.1: {} - querystringify@2.2.0: {} - queue-microtask@1.2.3: {} radix-ui@1.4.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): @@ -24964,8 +25021,6 @@ snapshots: require-from-string@2.0.2: {} - requires-port@1.0.0: {} - resend@4.8.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@react-email/render': 1.1.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -25054,16 +25109,16 @@ snapshots: dependencies: glob: 7.2.3 - roamjs-components@0.88.1(6fc269b31b2749e4d441ca378d1de710): + roamjs-components@0.88.1(e143305b3f00d4cb853970aa683101f5): dependencies: '@blueprintjs/core': 3.50.4(patch_hash=51c5847e0a73a1be0cc263036ff64d8fada46f3b65831ed938dbca5eecf3edc0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/datetime': 3.23.14(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/select': 3.19.1(patch_hash=5b2821b0bf7274e9b64d7824648c596b9e73c61f421d699a6d4c494f12f62355)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76) + '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76) '@types/crypto-js': 4.1.1 '@types/cytoscape': 3.21.9 '@types/file-saver': 2.0.5 - '@types/jsdom': 20.0.1 + '@types/jsdom': 28.0.3 '@types/marked': 4.3.2 '@types/nanoid': 2.0.0 '@types/react': 18.2.21 @@ -25080,7 +25135,7 @@ snapshots: hast-util-to-html: 7.1.3 idb: 7.1.1 insect: 5.9.1 - jsdom: 20.0.3 + jsdom: 29.1.1 jszip: 3.10.0 marked: 16.4.2 marked-react: 1.1.2(react@18.2.0) @@ -26110,20 +26165,17 @@ snapshots: toposort@2.0.2: {} - tough-cookie@4.1.4: + tough-cookie@6.0.0: dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 + tldts: 7.0.12 - tough-cookie@6.0.0: + tough-cookie@6.0.1: dependencies: tldts: 7.0.12 tr46@0.0.3: {} - tr46@3.0.0: + tr46@6.0.0: dependencies: punycode: 2.3.1 @@ -26389,6 +26441,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.27.1: {} + undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 @@ -26479,8 +26533,6 @@ snapshots: universal-user-agent@7.0.3: {} - universalify@0.2.0: {} - universalify@2.0.1: {} unpipe@1.0.0: {} @@ -26534,11 +26586,6 @@ snapshots: dependencies: punycode: 2.3.1 - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@18.2.21)(react@18.2.0): dependencies: react: 18.2.0 @@ -26700,7 +26747,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): + vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@vitest/expect': 4.1.6 '@vitest/mocker': 4.1.6(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) @@ -26726,7 +26773,7 @@ snapshots: '@edge-runtime/vm': 3.2.0 '@opentelemetry/api': 1.9.0 '@types/node': 20.19.13 - jsdom: 20.0.3 + jsdom: 29.1.1 transitivePeerDependencies: - msw @@ -26749,9 +26796,9 @@ snapshots: w3c-keyname@2.2.8: {} - w3c-xmlserializer@4.0.0: + w3c-xmlserializer@5.0.0: dependencies: - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 warning@4.0.3: dependencies: @@ -26773,18 +26820,17 @@ snapshots: webidl-conversions@3.0.1: {} - webidl-conversions@7.0.0: {} + webidl-conversions@8.0.1: {} - whatwg-encoding@2.0.0: - dependencies: - iconv-lite: 0.6.3 + whatwg-mimetype@5.0.0: {} - whatwg-mimetype@3.0.0: {} - - whatwg-url@11.0.0: + whatwg-url@16.0.1: dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 + '@exodus/bytes': 1.15.1 + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' whatwg-url@5.0.0: dependencies: @@ -26924,7 +26970,7 @@ snapshots: dependencies: os-paths: 4.4.0 - xml-name-validator@4.0.0: {} + xml-name-validator@5.0.0: {} xmlbuilder@15.1.1: {} From fefc36294944c6e35ec47985e068b71a8b7b5d72 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 4 Jun 2026 22:53:31 -0400 Subject: [PATCH 13/41] wip --- .../app/utils/conversion/fromJsonLd.ts | 39 +++++++++++++------ .../test/integration/upsertJsonLd.test.ts | 39 +++++++++++++++++-- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index ca057194a..e0fc4d07a 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -234,7 +234,7 @@ const parseBaseData = (data: NodeParseResult) => { : {}; return { created: data.date, - modified: data.modified, + last_modified: data.modified, author_local_id: data.creator, ...spaceInfo, }; @@ -296,6 +296,7 @@ const parseContent = ( const text = convert(content.content, sourceFormat, "obsidian"); return { text, + variant: "full", scale: "document", ...baseInterpretId(id), ...parseBaseData(data), @@ -309,7 +310,12 @@ const parseNodeInstance = ( ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const schemaInfo = data.type.map((x) => - interpretId(x["@id"], "schema_id", "schema_local_id", knownIris), + interpretId( + x["@id"], + "schema_id", + "schema_represented_by_local_id", + knownIris, + ), ); if (!schemaInfo.length) return null; // TODO If there's many types, how to choose? @@ -377,7 +383,12 @@ const parseRelationInstance = ( ): LocalConceptDataInput | null => { if (data["@id"] == null) return null; const schemaInfos = data.type.map((x) => - interpretId(x["@id"], "schema_id", "schema_local_id", knownIris), + interpretId( + x["@id"], + "schema_id", + "schema_represented_by_local_id", + knownIris, + ), ); const schemaInfo = schemaInfos[0]; if (!schemaInfo) return null; @@ -387,7 +398,7 @@ const parseRelationInstance = ( // TODO: find the names of source and dest instances, rel label return { ...schemaInfo, - name: `${source} -${"schema_local_id" in schemaInfo ? schemaInfo.schema_local_id : schemaInfo.schema_id}-> ${destination}`, + name: `${source} -${"schema_represented_by_local_id" in schemaInfo ? schemaInfo.schema_represented_by_local_id : schemaInfo.schema_id}-> ${destination}`, local_reference_content: { source, destination }, ...interpretId(data["@id"], "id", "source_local_id"), ...parseBaseData(data), @@ -421,7 +432,7 @@ const parseLdoNode = ( if (types.has("NodeSchema")) return parseNodeSchema(data as NodeSchemaProfile, knownIris); - // naw instance heuristics + // now instance heuristics let schemaType: string | undefined; typesA.map((t) => { if (knownSchemaTypes[t]) schemaType = knownSchemaTypes[t]; @@ -431,9 +442,10 @@ const parseLdoNode = ( if (schemaType === nodeSchemaType) { const nodeInstance = data as NodeInstanceProfile; if (!nodeInstance.description) return null; - const content = nodeInstance.description.content - ? nodeInstance.description - : contentById[nodeInstance.description["@id"]!]; + const content = + nodeInstance.description.content !== undefined + ? nodeInstance.description + : contentById[nodeInstance.description["@id"]!]; if (!content) return null; return parseNodeInstance(nodeInstance, content, knownIris); } @@ -464,11 +476,14 @@ export const parseJsonLdAsDataInputWithSchemas = async ( knownIris, knownSchemaTypes, ); + if (ldoData.length === 0) return []; + const dataset = ldoData[0]!.type.context.dataset; + const contentIds: string[] = dataset + .match(null, namedNode(descriptionPredicate)) + .toArray() + .map((q) => q.object.id); const contents = ldoData.filter((d) => - d.type - .toArray() - .map((x) => x["@id"]) - .includes("Content"), + contentIds.includes(d["@id"]), ) as ContentProfile[]; // assume single content for now const contentById = Object.fromEntries( diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index 3be71deb0..bab25712b 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -61,6 +61,18 @@ const jsonLdData: JsonLdDocument = { }, creator: "someone", }, + { + "@id": "sdata:261134", + "@type": ["sdata:131157", "dgc:Claim", "mira:Claim"], + modified: "2026-05-26T00:39:03.077Z", + created: "2025-12-04T15:47:51.694Z", + title: "CLM - Some supporting claim", + creator: "someone", + description: { + format: "text/html", + content: "", + }, + }, { "@id": "sdata:131164", "@type": "AbstractRelationDef", @@ -106,6 +118,7 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { let spaceId: number; let spaceAccountUuid: string; let client: DGSupabaseClient; + let authorAccountId: number; beforeAll(async () => { const spaceReq = await fetchOrCreateSpaceDirect({ @@ -131,11 +144,31 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { assert(accountReq.data); assert(accountReq.data.dg_account); spaceAccountUuid = accountReq.data.dg_account; + const authorAccountReq = await client.rpc("upsert_accounts_in_space", { + accounts: [ + { + name: "someone", + account_local_id: "someone", + platform: "Roam", + agent_type: "person", + }, + ], + space_id_: spaceId, + }); + console.error(authorAccountReq.error); + assert(!authorAccountReq.error); + assert(authorAccountReq.data); + authorAccountId = authorAccountReq.data[0]!; }); afterAll(async () => { - // if (spaceAccountUuid) - // await serviceClient().auth.admin.deleteUser(spaceAccountUuid); - // if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); + if (spaceAccountUuid) + await serviceClient().auth.admin.deleteUser(spaceAccountUuid); + if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); + if (authorAccountId) + await serviceClient() + .from("PlatformAccount") + .delete() + .eq("id", authorAccountId); }); it("Upserts the data", async () => { From b288ac1c900f0d56b31b072368a7a730e987cf0c Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 04:10:47 -0400 Subject: [PATCH 14/41] wip --- .../app/utils/conversion/fromJsonLd.ts | 31 ++++++++++--------- .../test/integration/parseJsonLd.test.ts | 20 ++++++++---- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index e0fc4d07a..3c254eea2 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -1,5 +1,6 @@ import { namedNode } from "@ldo/rdf-utils"; -import { parseRdf } from "@ldo/ldo"; +import type { NamedNode } from "@rdfjs/types"; +import { parseRdf, type LdoDataset } from "@ldo/ldo"; import { toRDF, type JsonLdDocument } from "jsonld"; import { ContainerProfileShapeType, @@ -72,19 +73,24 @@ export type SchemaTypes = | "https://discoursegraphs.com/schema/dg_base#RelationDef" | "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef"; -export const parseJsonLdAsLdo = async ( +export const parseJsonLdAsLdoDataset = async ( data: JsonLdDocument, baseIRI: string, - knownIris: Record, - knownSchemaTypes: Record, -): Promise => { +): Promise => { const asQuads = (await toRDF(data, { format: "application/n-quads", })) as string; // console.log(asQuads); - const ldoDataset = await parseRdf(asQuads, { + return await parseRdf(asQuads, { baseIRI, }); +}; + +export const extractLdoData = async ( + ldoDataset: LdoDataset, + knownIris: Record, + knownSchemaTypes: Record, +): Promise => { const subjects = new Set(ldoDataset.toArray().map((q) => q.subject.value)); const result: ParseResult[] = []; const typeMap: Record = {}; @@ -470,20 +476,15 @@ export const parseJsonLdAsDataInputWithSchemas = async ( knownIris: Record, knownSchemaTypes: Record, ): Promise => { - const ldoData = await parseJsonLdAsLdo( - data, - baseIRI, - knownIris, - knownSchemaTypes, - ); + const dataset = await parseJsonLdAsLdoDataset(data, baseIRI); + const ldoData = await extractLdoData(dataset, knownIris, knownSchemaTypes); if (ldoData.length === 0) return []; - const dataset = ldoData[0]!.type.context.dataset; const contentIds: string[] = dataset .match(null, namedNode(descriptionPredicate)) .toArray() - .map((q) => q.object.id); + .map((q) => (q.object as NamedNode).value); const contents = ldoData.filter((d) => - contentIds.includes(d["@id"]), + contentIds.includes(d["@id"] || ""), ) as ContentProfile[]; // assume single content for now const contentById = Object.fromEntries( diff --git a/apps/website/test/integration/parseJsonLd.test.ts b/apps/website/test/integration/parseJsonLd.test.ts index d63a812b9..dffd2a5c9 100644 --- a/apps/website/test/integration/parseJsonLd.test.ts +++ b/apps/website/test/integration/parseJsonLd.test.ts @@ -6,7 +6,10 @@ import type { RelationDefProfile, AbstractRelationDefProfile, } from "../../app/utils/conversion/ldo/dgBase.typings"; -import { parseJsonLdAsLdo } from "../../app/utils/conversion/fromJsonLd"; +import { + parseJsonLdAsLdoDataset, + extractLdoData, +} from "../../app/utils/conversion/fromJsonLd"; // example data @@ -134,7 +137,8 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeSchema; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); + const dataset = await parseJsonLdAsLdoDataset(data, url); + const parsedData = await extractLdoData(dataset, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeSchemaProfile; @@ -156,7 +160,8 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exNodeInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); + const dataset = await parseJsonLdAsLdoDataset(data, url); + const parsedData = await extractLdoData(dataset, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as NodeInstanceProfile; @@ -179,7 +184,8 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exAbstractRelnDef; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); + const dataset = await parseJsonLdAsLdoDataset(data, url); + const parsedData = await extractLdoData(dataset, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as AbstractRelationDefProfile; @@ -201,7 +207,8 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exRelnType; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); + const dataset = await parseJsonLdAsLdoDataset(data, url); + const parsedData = await extractLdoData(dataset, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as RelationDefProfile; @@ -223,7 +230,8 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { const data = exRelnInstance; const id = data["@id"]; const url = `${spaceUrl}/${id.split(":")[1]}`; - const parsedData = await parseJsonLdAsLdo(data, url, {}, {}); + const dataset = await parseJsonLdAsLdoDataset(data, url); + const parsedData = await extractLdoData(dataset, {}, {}); const parsedItem = parsedData.filter( (item) => item["@id"] === url, )[0] as RelationInstanceProfile; From e19d6cf91f5ea8969f7539908d4befb7148ce3aa Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 08:26:15 -0400 Subject: [PATCH 15/41] replace dc elements by dcterms --- .../app/utils/conversion/fromJsonLd.ts | 2 +- .../utils/conversion/ldo/dgBase.context.ts | 54 +++++++++---------- .../app/utils/conversion/ldo/dgBase.schema.ts | 42 +++++++-------- .../app/utils/conversion/shapes/dgBase.shex | 44 +++++++-------- apps/website/public/schema/context.jsonld | 14 ++--- apps/website/public/schema/dg_core.ttl | 2 +- 6 files changed, 79 insertions(+), 79 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 3c254eea2..61d0c692e 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -59,7 +59,7 @@ const abstractRelationDefType = const domainPredicate = "http://www.w3.org/2000/01/rdf-schema#domain"; const sourcePredicate = "https://discoursegraphs.com/schema/dg_base#source"; const contentPredicate = "http://rdfs.org/sioc/ns#content"; -const descriptionPredicate = "http://purl.org/dc/elements/1.1/description"; +const descriptionPredicate = "http://purl.org/dc/terms/description"; const containerType = "http://rdfs.org/sioc/ns#Container"; const restrictionType = "http://www.w3.org/2002/07/owl#Restriction"; export const schemaTypeSet = new Set([ diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index 56eb45099..7f7b6809d 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -41,15 +41,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, }, @@ -59,15 +59,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, NodeSchema: { @@ -82,15 +82,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, label: { @@ -125,33 +125,33 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, title: { - "@id": "http://purl.org/dc/elements/1.1/title", + "@id": "http://purl.org/dc/terms/title", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, description: { - "@id": "http://purl.org/dc/elements/1.1/description", + "@id": "http://purl.org/dc/terms/description", "@type": "@id", }, }, }, title: { - "@id": "http://purl.org/dc/elements/1.1/title", + "@id": "http://purl.org/dc/terms/title", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, description: { - "@id": "http://purl.org/dc/elements/1.1/description", + "@id": "http://purl.org/dc/terms/description", "@type": "@id", }, Content: { @@ -162,7 +162,7 @@ export const dgBaseContext: LdoJsonldContext = { "@isCollection": true, }, format: { - "@id": "http://purl.org/dc/elements/1.1/format", + "@id": "http://purl.org/dc/terms/format", "@type": "http://www.w3.org/2001/XMLSchema#string", }, content: { @@ -172,7 +172,7 @@ export const dgBaseContext: LdoJsonldContext = { }, }, format: { - "@id": "http://purl.org/dc/elements/1.1/format", + "@id": "http://purl.org/dc/terms/format", "@type": "http://www.w3.org/2001/XMLSchema#string", }, content: { @@ -196,15 +196,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, label: { @@ -230,15 +230,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, label: { @@ -275,15 +275,15 @@ export const dgBaseContext: LdoJsonldContext = { "@type": "@id", }, creator: { - "@id": "http://purl.org/dc/elements/1.1/creator", + "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, date: { - "@id": "http://purl.org/dc/elements/1.1/date", + "@id": "http://purl.org/dc/terms/date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { - "@id": "http://purl.org/dc/elements/1.1/modified", + "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, source: { diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index e612a98e0..e6496d5e7 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -64,7 +64,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -74,7 +74,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -84,7 +84,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -126,7 +126,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -136,7 +136,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -146,7 +146,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -206,7 +206,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -216,7 +216,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -226,7 +226,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -236,7 +236,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/title", + predicate: "http://purl.org/dc/terms/title", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -246,7 +246,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/description", + predicate: "http://purl.org/dc/terms/description", valueExpr: "https://discoursegraphs.com/schema/dg_base#ContentProfile", min: 0, @@ -296,7 +296,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -306,7 +306,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -316,7 +316,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -376,7 +376,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -386,7 +386,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -396,7 +396,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -462,7 +462,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/creator", + predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", @@ -472,7 +472,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/date", + predicate: "http://purl.org/dc/terms/date", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -482,7 +482,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/modified", + predicate: "http://purl.org/dc/terms/modified", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -525,7 +525,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/elements/1.1/format", + predicate: "http://purl.org/dc/terms/format", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index 2911776a7..203d2c0c6 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -1,4 +1,4 @@ -PREFIX dc: +PREFIX dct: PREFIX dgb: PREFIX dgshapes: PREFIX foaf: @@ -17,17 +17,17 @@ dgshapes:ContainerProfile { dgshapes:ItemProfile { a [sioc:Item]; sioc:has_container IRI ?; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; - dc:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; + dct:creator xsd:string ? ; } dgshapes:NodeSchemaProfile { a [dgb:NodeSchema]; sioc:has_container IRI ?; - dc:creator xsd:string ? ; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; + dct:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:subClassOf IRI *; } @@ -36,20 +36,20 @@ dgshapes:NodeSchemaProfile { dgshapes:NodeInstanceProfile { a [dgshapes:NodeInstance]; sioc:has_container IRI ?; - dc:creator xsd:string ? ; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; - dc:title xsd:dateTime? ; - dc:description @dgshapes:ContentProfile ? ; + dct:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; + dct:title xsd:dateTime? ; + dct:description @dgshapes:ContentProfile ? ; } dgshapes:AbstractRelationDefProfile { a [dgb:AbstractRelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dc:creator xsd:string ? ; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; + dct:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; } @@ -57,9 +57,9 @@ dgshapes:RelationDefProfile { a [dgshapes:RelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dc:creator xsd:string ? ; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; + dct:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:domain IRI ; rdfs:range IRI ; @@ -69,9 +69,9 @@ dgshapes:RelationDefProfile { dgshapes:RelationInstanceProfile { a [dgb:RelationInstance]; sioc:has_container IRI ?; - dc:creator xsd:string ? ; - dc:date xsd:dateTime ? ; - dc:modified xsd:dateTime ? ; + dct:creator xsd:string ? ; + dct:date xsd:dateTime ? ; + dct:modified xsd:dateTime ? ; dgb:source @dgshapes:NodeInstanceProfile ; dgb:destination @dgshapes:NodeInstanceProfile ; } @@ -79,6 +79,6 @@ dgshapes:RelationInstanceProfile { # Note that Content is not part of the schema, but is useful as a fiction in the code dgshapes:ContentProfile { a [dgshapes:Content]; - dc:format xsd:string ?; + dct:format xsd:string ?; sioc:content xsd:string; } diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 19da92eb7..242a896fb 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -3,7 +3,7 @@ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "owl": "http://www.w3.org/2002/07/owl#", - "dc": "http://purl.org/dc/elements/1.1/", + "dct": "http://purl.org/dc/terms/", "prov": "http://www.w3.org/ns/prov#", "sioc": "http://rdfs.org/sioc/ns#", "dgc": "https://discoursegraphs.com/schema/dg_core#", @@ -18,18 +18,18 @@ "onProperty": "owl:onProperty", "sameAs": { "@id": "owl:sameAs", "@type": "@id" }, "hasValue": "owl:hasValue", - "title": "dc:title", - "format": "dc:format", - "description": "dc:description", + "title": "dct:title", + "format": "dct:format", + "description": "dct:description", "modified": { - "@id": "dc:modified", + "@id": "dct:modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "created": { - "@id": "dc:date", + "@id": "dct:date", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, - "creator": "dc:creator", + "creator": "dct:creator", "Container": "sioc:Container", "content": "sioc:content", "container_of": "sioc:container_of", diff --git a/apps/website/public/schema/dg_core.ttl b/apps/website/public/schema/dg_core.ttl index 27c419c58..80a3b0eab 100644 --- a/apps/website/public/schema/dg_core.ttl +++ b/apps/website/public/schema/dg_core.ttl @@ -38,7 +38,7 @@ dg:Evidence a dgb:NodeSchema; dg:describesActivity a dgb:RelationDef; rdfs:label "Describes activity"@en; - rdfs:subPropertyOf dc:subject; + rdfs:subPropertyOf dct:subject; rdfs:domain schema:CreativeWork; rdfs:range prov:Activity. From 7f9514cb5006eb04006374b5f554213789920208 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 12:53:13 -0400 Subject: [PATCH 16/41] jsdom external --- apps/website/next.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/website/next.config.ts b/apps/website/next.config.ts index abefb28de..316d7d157 100644 --- a/apps/website/next.config.ts +++ b/apps/website/next.config.ts @@ -17,6 +17,7 @@ const withNextra = nextra({ const nextConfig: NextConfig = { reactStrictMode: true, + serverExternalPackages: ["jsdom"], async redirects() { return DOCS_REDIRECTS; }, From 62a4449b9ec7adaacbcabbf64f73b56eee7dee35 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 13:23:30 -0400 Subject: [PATCH 17/41] older jsdom --- apps/website/package.json | 4 +- pnpm-lock.yaml | 556 ++++++++++++++++++++------------------ 2 files changed, 290 insertions(+), 270 deletions(-) diff --git a/apps/website/package.json b/apps/website/package.json index d1541b7cc..9cf0bd2c3 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -27,7 +27,7 @@ "@supabase/supabase-js": "catalog:", "clsx": "^2.1.1", "gray-matter": "^4.0.3", - "jsdom": "^29.1.1", + "jsdom": "^20.0.3", "jsonld": "^9.0.0", "lucide-react": "^0.540.0", "next": "^16.2.0", @@ -51,7 +51,7 @@ "@repo/types": "workspace:*", "@repo/typescript-config": "workspace:*", "@tailwindcss/typography": "^0.5.15", - "@types/jsdom": "^28.0.3", + "@types/jsdom": "^20.0.1", "@types/jsonld": "^1.5.15", "@types/node": "^20", "@types/react": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8903c1cf..b8506e3d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,7 +343,7 @@ importers: version: 3.5.2(react@18.2.0) roamjs-components: specifier: 0.88.1 - version: 0.88.1(e143305b3f00d4cb853970aa683101f5) + version: 0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51) tldraw: specifier: 2.4.6 version: 2.4.6(patch_hash=56e196052862c9a58a11b43e5e121384cd1d6548416afa0f16e9fbfbf0e4080d)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -395,7 +395,7 @@ importers: version: 0.17.14 tailwindcss: specifier: ^3.4.17 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) tsx: specifier: ^4.19.2 version: 4.20.5 @@ -464,8 +464,8 @@ importers: specifier: ^4.0.3 version: 4.0.3 jsdom: - specifier: ^29.1.1 - version: 29.1.1 + specifier: ^20.0.3 + version: 20.0.3 jsonld: specifier: ^9.0.0 version: 9.0.0 @@ -531,8 +531,8 @@ importers: specifier: ^0.5.15 version: 0.5.16(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) '@types/jsdom': - specifier: ^28.0.3 - version: 28.0.3 + specifier: ^20.0.1 + version: 20.0.1 '@types/jsonld': specifier: ^1.5.15 version: 1.5.15 @@ -574,7 +574,7 @@ importers: version: 5.5.4 vitest: specifier: ^4.0.0 - version: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) packages/database: dependencies: @@ -647,7 +647,7 @@ importers: version: 15.0.4 '@vercel/style-guide': specifier: ^6.0.0 - version: 6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) + version: 6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) eslint: specifier: 'catalog:' version: 8.57.1 @@ -689,10 +689,10 @@ importers: version: link:../typescript-config tailwindcss: specifier: ^3.4.1 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) + version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))) packages/types: {} @@ -816,21 +816,6 @@ packages: resolution: {integrity: sha512-C90iyzm/jLV7Lomv2UzwWUzRv9WZr1oRsFRKsX5HjQL4EXrbi9H/RtBkjCP+NF+ABZXUKpAa4F1dkoTaea4zHg==} hasBin: true - '@asamuzakjp/css-color@5.1.11': - resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/dom-selector@7.1.1': - resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/generational-cache@1.0.1': - resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/nwsapi@2.3.9': - resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} engines: {node: '>=16.0.0'} @@ -1157,10 +1142,6 @@ packages: '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} - '@bramus/specificity@2.4.2': - resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} - hasBin: true - '@bundled-es-modules/cookie@2.0.1': resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} @@ -1342,42 +1323,6 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@csstools/color-helpers@6.0.2': - resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} - engines: {node: '>=20.19.0'} - - '@csstools/css-calc@3.2.1': - resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 - - '@csstools/css-color-parser@4.1.1': - resolution: {integrity: sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 - - '@csstools/css-parser-algorithms@4.0.0': - resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@csstools/css-tokenizer': ^4.0.0 - - '@csstools/css-syntax-patches-for-csstree@1.1.5': - resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} - peerDependencies: - css-tree: ^3.2.1 - peerDependenciesMeta: - css-tree: - optional: true - - '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} - engines: {node: '>=20.19.0'} - '@cucumber/ci-environment@13.0.0': resolution: {integrity: sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==} @@ -2244,15 +2189,6 @@ packages: resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@exodus/bytes@1.15.1': - resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - peerDependencies: - '@noble/hashes': ^1.8.0 || ^2.0.0 - peerDependenciesMeta: - '@noble/hashes': - optional: true - '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} @@ -5335,8 +5271,8 @@ packages: '@types/jquery@3.5.33': resolution: {integrity: sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==} - '@types/jsdom@28.0.3': - resolution: {integrity: sha512-/HQ2uFoetFTXuye8vzIcHw2z6Fwi7Hi/qcgC+RoS9NCyewiqxhVGqlG+ViGB6lkax481R6dmhf1I7lIGlzJStQ==} + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -5876,6 +5812,10 @@ packages: resolution: {integrity: sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==} engines: {node: '>=18.12.0'} + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -5888,6 +5828,9 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -5921,6 +5864,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -6205,7 +6152,7 @@ packages: basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.1, please upgrade + deprecated: Security vulnerability fixed in 5.2.0, please upgrade before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} @@ -6215,9 +6162,6 @@ packages: peerDependencies: react: '>=16.8' - bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} - bin-links@6.0.0: resolution: {integrity: sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==} engines: {node: ^20.17.0 || >=22.9.0} @@ -6734,15 +6678,21 @@ packages: crypto-js@3.1.9-1: resolution: {integrity: sha512-W93aKztssqf29OvUlqfikzGyYbD1rpkXvGP9IQ1JchLY3bxaLXZSWYbwrtib2vk8DobrDzX7PIXcDWHp0B6Ymw==} - css-tree@3.2.1: - resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -6952,9 +6902,9 @@ packages: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} - data-urls@7.0.0: - resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} @@ -7144,6 +7094,11 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} @@ -7229,10 +7184,6 @@ packages: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} - entities@8.0.0: - resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} - engines: {node: '>=20.19.0'} - environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -8180,9 +8131,9 @@ packages: hotkeys-js@3.13.15: resolution: {integrity: sha512-gHh8a/cPTCpanraePpjRxyIlxDFrIhYqjuh01UHWEwDpglJKCnvLW8kqSx5gQtOuSsJogNZXLhOdbSExpgUiqg==} - html-encoding-sniffer@6.0.0: - resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -8219,6 +8170,10 @@ packages: resolution: {integrity: sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==} engines: {node: '>=6.0.0'} + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -8226,6 +8181,10 @@ packages: http-response-object@3.0.2: resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@6.2.1: resolution: {integrity: sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==} engines: {node: '>= 14'} @@ -8697,11 +8656,11 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@29.1.1: - resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} peerDependencies: - canvas: ^3.0.0 + canvas: ^2.5.0 peerDependenciesMeta: canvas: optional: true @@ -8999,10 +8958,6 @@ packages: resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} engines: {node: 20 || >=22} - lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} - engines: {node: 20 || >=22} - lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -9136,9 +9091,6 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -9619,6 +9571,9 @@ packages: resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -9847,9 +9802,6 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parse5@8.0.1: - resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} - parseley@0.12.1: resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} @@ -10277,6 +10229,9 @@ packages: pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} @@ -10299,6 +10254,9 @@ packages: query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -10685,6 +10643,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resend@4.8.0: resolution: {integrity: sha512-R8eBOFQDO6dzRTDmaMEdpqrkmgSjPpVXt4nGfWsZdYOet0kqra0xgbvTES6HmCriZEXbmGk3e0DiGIaLFTFSHA==} engines: {node: '>=18'} @@ -11543,20 +11504,20 @@ packages: toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + tough-cookie@6.0.0: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@6.0.0: - resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} - engines: {node: '>=20'} + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} @@ -11822,9 +11783,6 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.27.1: - resolution: {integrity: sha512-NyfbU7cCMYYxzBT07eOv0/WR3L5j6vmza6sRlF2sDVCkNvsNaCcaFDGu0a4WqzE983tKuSk7YRTY2C+1krumMg==} - undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} @@ -11893,6 +11851,10 @@ packages: universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -11925,6 +11887,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -12117,9 +12082,9 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} @@ -12147,17 +12112,22 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webidl-conversions@8.0.1: - resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} - engines: {node: '>=20'} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} - whatwg-mimetype@5.0.0: - resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} - engines: {node: '>=20'} + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} - whatwg-url@16.0.1: - resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -12276,9 +12246,9 @@ packages: resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} engines: {node: '>= 6.0'} - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} @@ -12436,26 +12406,6 @@ snapshots: '@antfu/ni@23.3.1': {} - '@asamuzakjp/css-color@5.1.11': - dependencies: - '@asamuzakjp/generational-cache': 1.0.1 - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - - '@asamuzakjp/dom-selector@7.1.1': - dependencies: - '@asamuzakjp/generational-cache': 1.0.1 - '@asamuzakjp/nwsapi': 2.3.9 - bidi-js: 1.0.3 - css-tree: 3.2.1 - is-potential-custom-element-name: 1.0.1 - - '@asamuzakjp/generational-cache@1.0.1': {} - - '@asamuzakjp/nwsapi@2.3.9': {} - '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 @@ -13221,10 +13171,6 @@ snapshots: '@braintree/sanitize-url@7.1.2': {} - '@bramus/specificity@2.4.2': - dependencies: - css-tree: 3.2.1 - '@bundled-es-modules/cookie@2.0.1': dependencies: cookie: 0.7.2 @@ -13542,30 +13488,6 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@csstools/color-helpers@6.0.2': {} - - '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': - dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - - '@csstools/css-color-parser@4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': - dependencies: - '@csstools/color-helpers': 6.0.2 - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': - dependencies: - '@csstools/css-tokenizer': 4.0.0 - - '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': - optionalDependencies: - css-tree: 3.2.1 - - '@csstools/css-tokenizer@4.0.0': {} - '@cucumber/ci-environment@13.0.0': {} '@cucumber/cucumber-expressions@19.0.0': @@ -14146,8 +14068,6 @@ snapshots: '@eslint/js@9.34.0': {} - '@exodus/bytes@1.15.1': {} - '@fastify/busboy@2.1.1': {} '@floating-ui/core@1.7.3': @@ -16976,32 +16896,32 @@ snapshots: '@rushstack/eslint-patch@1.12.0': {} - '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': + '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76)': dependencies: '@aws-sdk/client-lambda': 3.882.0 '@aws-sdk/client-s3': 3.882.0 - '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) archiver: 5.3.2 axios: 0.27.2(debug@4.4.3) debug: 4.4.3 dotenv: 16.6.1 esbuild: 0.17.14 patch-package: 6.5.1 - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) zod: 3.25.76 - '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))': + '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))': dependencies: '@playwright/test': 1.29.0 '@testing-library/react': 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@types/jsdom': 28.0.3 + '@types/jsdom': 20.0.1 c8: 7.14.0 debug: 4.4.3 dotenv: 16.6.1 - jsdom: 29.1.1 - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) + jsdom: 20.0.3 + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -18178,12 +18098,11 @@ snapshots: dependencies: '@types/sizzle': 2.3.10 - '@types/jsdom@28.0.3': + '@types/jsdom@20.0.1': dependencies: '@types/node': 20.19.13 '@types/tough-cookie': 4.0.5 - parse5: 8.0.1 - undici-types: 7.27.1 + parse5: 7.3.0 '@types/json-schema@7.0.15': {} @@ -18866,7 +18785,7 @@ snapshots: json-schema-to-ts: 1.6.4 ts-morph: 12.0.0 - '@vercel/style-guide@6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)))': + '@vercel/style-guide@6.0.0(@next/eslint-plugin-next@15.0.4)(eslint@8.57.1)(prettier@3.6.2)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@babel/core': 7.28.3 '@babel/eslint-parser': 7.28.0(@babel/core@7.28.3)(eslint@8.57.1) @@ -18886,7 +18805,7 @@ snapshots: eslint-plugin-testing-library: 6.5.0(eslint@8.57.1)(typescript@5.5.4) eslint-plugin-tsdoc: 0.2.17 eslint-plugin-unicorn: 51.0.1(eslint@8.57.1) - eslint-plugin-vitest: 0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) + eslint-plugin-vitest: 0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))) prettier-plugin-packagejson: 2.5.19(prettier@3.6.2) optionalDependencies: '@next/eslint-plugin-next': 15.0.4 @@ -18951,6 +18870,8 @@ snapshots: js-yaml: 3.14.1 tslib: 2.5.1 + abab@2.0.6: {} + abbrev@3.0.1: {} abort-controller@3.0.0: @@ -18962,6 +18883,11 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 + acorn-globals@7.0.1: + dependencies: + acorn: 8.16.0 + acorn-walk: 8.3.4 + acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -18982,6 +18908,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} agent-base@9.0.0: {} @@ -19286,10 +19218,6 @@ snapshots: mathjax-full: 3.2.2 react: 19.1.1 - bidi-js@1.0.3: - dependencies: - require-from-string: 2.0.2 - bin-links@6.0.0: dependencies: cmd-shim: 8.0.0 @@ -19826,13 +19754,16 @@ snapshots: crypto-js@3.1.9-1: {} - css-tree@3.2.1: - dependencies: - mdn-data: 2.27.1 - source-map-js: 1.2.1 - cssesc@3.0.0: {} + cssom@0.3.8: {} + + cssom@0.5.0: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + csstype@3.1.3: {} cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): @@ -20067,12 +19998,11 @@ snapshots: data-uri-to-buffer@6.0.2: {} - data-urls@7.0.0: + data-urls@3.0.2: dependencies: - whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 - transitivePeerDependencies: - - '@noble/hashes' + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 data-view-buffer@1.0.2: dependencies: @@ -20241,6 +20171,10 @@ snapshots: domelementtype@2.3.0: {} + domexception@4.0.0: + dependencies: + webidl-conversions: 7.0.0 + domhandler@5.0.3: dependencies: domelementtype: 2.3.0 @@ -20321,8 +20255,6 @@ snapshots: entities@7.0.1: {} - entities@8.0.0: {} - environment@1.1.0: {} error-ex@1.3.2: @@ -20805,13 +20737,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-vitest@0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))): + eslint-plugin-vitest@0.3.26(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)(vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))): dependencies: '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.5.4) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4) - vitest: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + vitest: 4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - supports-color - typescript @@ -21734,11 +21666,9 @@ snapshots: hotkeys-js@3.13.15: {} - html-encoding-sniffer@6.0.0: + html-encoding-sniffer@3.0.0: dependencies: - '@exodus/bytes': 1.15.1 - transitivePeerDependencies: - - '@noble/hashes' + whatwg-encoding: 2.0.0 html-escaper@2.0.2: {} @@ -21793,6 +21723,14 @@ snapshots: http-link-header@1.1.3: {} + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -21804,6 +21742,13 @@ snapshots: dependencies: '@types/node': 10.17.60 + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@6.2.1: dependencies: agent-base: 7.1.4 @@ -22258,31 +22203,38 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@29.1.1: + jsdom@20.0.3: dependencies: - '@asamuzakjp/css-color': 5.1.11 - '@asamuzakjp/dom-selector': 7.1.1 - '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) - '@exodus/bytes': 1.15.1 - css-tree: 3.2.1 - data-urls: 7.0.0 + abab: 2.0.6 + acorn: 8.16.0 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 decimal.js: 10.6.0 - html-encoding-sniffer: 6.0.0 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.4 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.1 - parse5: 8.0.1 + nwsapi: 2.2.21 + parse5: 7.3.0 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 6.0.1 - undici: 7.25.0 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 8.0.1 - whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 - xml-name-validator: 5.0.0 + tough-cookie: 4.1.4 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.18.3 + xml-name-validator: 4.0.0 transitivePeerDependencies: - - '@noble/hashes' + - bufferutil + - supports-color + - utf-8-validate jsesc@0.5.0: {} @@ -22593,8 +22545,6 @@ snapshots: lru-cache@11.2.1: {} - lru-cache@11.5.1: {} - lru-cache@4.1.5: dependencies: pseudomap: 1.0.2 @@ -22853,8 +22803,6 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - mdn-data@2.27.1: {} - mdurl@2.0.0: {} media-typer@1.1.0: {} @@ -23546,6 +23494,8 @@ snapshots: npm-to-yarn@3.0.1: {} + nwsapi@2.2.21: {} + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -23861,10 +23811,6 @@ snapshots: dependencies: entities: 6.0.1 - parse5@8.0.1: - dependencies: - entities: 8.0.0 - parseley@0.12.1: dependencies: leac: 0.6.0 @@ -23999,6 +23945,14 @@ snapshots: postcss: 8.5.6 ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) + postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): + dependencies: + lilconfig: 3.1.3 + yaml: 2.8.1 + optionalDependencies: + postcss: 8.5.6 + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) + postcss-nested@6.2.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -24279,6 +24233,10 @@ snapshots: pseudomap@1.0.2: {} + psl@1.15.0: + dependencies: + punycode: 2.3.1 + pump@3.0.3: dependencies: end-of-stream: 1.4.5 @@ -24298,6 +24256,8 @@ snapshots: query-selector-shadow-dom@1.0.1: {} + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} radix-ui@1.4.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): @@ -25021,6 +24981,8 @@ snapshots: require-from-string@2.0.2: {} + requires-port@1.0.0: {} + resend@4.8.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@react-email/render': 1.1.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -25109,16 +25071,16 @@ snapshots: dependencies: glob: 7.2.3 - roamjs-components@0.88.1(e143305b3f00d4cb853970aa683101f5): + roamjs-components@0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51): dependencies: '@blueprintjs/core': 3.50.4(patch_hash=51c5847e0a73a1be0cc263036ff64d8fada46f3b65831ed938dbca5eecf3edc0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/datetime': 3.23.14(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/select': 3.19.1(patch_hash=5b2821b0bf7274e9b64d7824648c596b9e73c61f421d699a6d4c494f12f62355)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@28.0.3)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@29.1.1)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76) + '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76) '@types/crypto-js': 4.1.1 '@types/cytoscape': 3.21.9 '@types/file-saver': 2.0.5 - '@types/jsdom': 28.0.3 + '@types/jsdom': 20.0.1 '@types/marked': 4.3.2 '@types/nanoid': 2.0.0 '@types/react': 18.2.21 @@ -25135,7 +25097,7 @@ snapshots: hast-util-to-html: 7.1.3 idb: 7.1.1 insect: 5.9.1 - jsdom: 29.1.1 + jsdom: 20.0.3 jszip: 3.10.0 marked: 16.4.2 marked-react: 1.1.2(react@18.2.0) @@ -25948,6 +25910,10 @@ snapshots: dependencies: tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))): + dependencies: + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 @@ -25975,6 +25941,33 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.0.1(postcss@8.5.6) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -26165,17 +26158,20 @@ snapshots: toposort@2.0.2: {} - tough-cookie@6.0.0: + tough-cookie@4.1.4: dependencies: - tldts: 7.0.12 + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 - tough-cookie@6.0.1: + tough-cookie@6.0.0: dependencies: tldts: 7.0.12 tr46@0.0.3: {} - tr46@6.0.0: + tr46@3.0.0: dependencies: punycode: 2.3.1 @@ -26249,6 +26245,24 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.19.13 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + ts-toolbelt@6.15.5: {} ts-toolbelt@9.6.0: {} @@ -26441,8 +26455,6 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.27.1: {} - undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 @@ -26533,6 +26545,8 @@ snapshots: universal-user-agent@7.0.3: {} + universalify@0.2.0: {} + universalify@2.0.1: {} unpipe@1.0.0: {} @@ -26586,6 +26600,11 @@ snapshots: dependencies: punycode: 2.3.1 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + use-callback-ref@1.3.3(@types/react@18.2.21)(react@18.2.0): dependencies: react: 18.2.0 @@ -26747,7 +26766,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@29.1.1)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): + vitest@4.1.6(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jsdom@20.0.3)(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@vitest/expect': 4.1.6 '@vitest/mocker': 4.1.6(msw@2.11.1(@types/node@20.19.13)(typescript@5.5.4))(vite@7.3.3(@types/node@20.19.13)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) @@ -26773,7 +26792,7 @@ snapshots: '@edge-runtime/vm': 3.2.0 '@opentelemetry/api': 1.9.0 '@types/node': 20.19.13 - jsdom: 29.1.1 + jsdom: 20.0.3 transitivePeerDependencies: - msw @@ -26796,9 +26815,9 @@ snapshots: w3c-keyname@2.2.8: {} - w3c-xmlserializer@5.0.0: + w3c-xmlserializer@4.0.0: dependencies: - xml-name-validator: 5.0.0 + xml-name-validator: 4.0.0 warning@4.0.3: dependencies: @@ -26820,17 +26839,18 @@ snapshots: webidl-conversions@3.0.1: {} - webidl-conversions@8.0.1: {} + webidl-conversions@7.0.0: {} + + whatwg-encoding@2.0.0: + dependencies: + iconv-lite: 0.6.3 - whatwg-mimetype@5.0.0: {} + whatwg-mimetype@3.0.0: {} - whatwg-url@16.0.1: + whatwg-url@11.0.0: dependencies: - '@exodus/bytes': 1.15.1 - tr46: 6.0.0 - webidl-conversions: 8.0.1 - transitivePeerDependencies: - - '@noble/hashes' + tr46: 3.0.0 + webidl-conversions: 7.0.0 whatwg-url@5.0.0: dependencies: @@ -26970,7 +26990,7 @@ snapshots: dependencies: os-paths: 4.4.0 - xml-name-validator@5.0.0: {} + xml-name-validator@4.0.0: {} xmlbuilder@15.1.1: {} From 8874a9480be7eb5354e41176283a82d82871e056 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 13:36:48 -0400 Subject: [PATCH 18/41] separate mira and dg contexts. Align dct:date->dct:created --- .../app/utils/conversion/fromJsonLd.ts | 2 +- .../utils/conversion/ldo/dgBase.context.ts | 28 +++---- .../app/utils/conversion/ldo/dgBase.schema.ts | 12 +-- .../utils/conversion/ldo/dgBase.typings.ts | 12 +-- .../app/utils/conversion/shapes/dgBase.shex | 12 +-- apps/website/public/schema/context.jsonld | 13 +--- apps/website/public/schema/mira.jsonld | 77 +++++++++++++++++++ .../test/integration/upsertJsonLd.test.ts | 2 +- 8 files changed, 113 insertions(+), 45 deletions(-) create mode 100644 apps/website/public/schema/mira.jsonld diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 61d0c692e..59f141860 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -239,7 +239,7 @@ const parseBaseData = (data: NodeParseResult) => { ? interpretId(data.hasContainer["@id"], "space_id", "space_local_id") : {}; return { - created: data.date, + created: data.created, last_modified: data.modified, author_local_id: data.creator, ...spaceInfo, diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index 7f7b6809d..a964dac13 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -40,8 +40,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://rdfs.org/sioc/ns#has_container", "@type": "@id", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -58,8 +58,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://rdfs.org/sioc/ns#has_container", "@type": "@id", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -85,8 +85,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -128,8 +128,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -199,8 +199,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -233,8 +233,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { @@ -278,8 +278,8 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, - date: { - "@id": "http://purl.org/dc/terms/date", + created: { + "@id": "http://purl.org/dc/terms/created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime", }, modified: { diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index e6496d5e7..2abd6f94f 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -64,7 +64,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -136,7 +136,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -216,7 +216,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -306,7 +306,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -386,7 +386,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", @@ -472,7 +472,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://purl.org/dc/terms/date", + predicate: "http://purl.org/dc/terms/created", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index 30ae242f2..188e1fb68 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -30,7 +30,7 @@ export interface ItemProfile { hasContainer?: { "@id": string; }; - date?: string; + created?: string; modified?: string; creator?: string; } @@ -48,7 +48,7 @@ export interface NodeSchemaProfile { "@id": string; }; creator?: string; - date?: string; + created?: string; modified?: string; label: string; subClassOf?: LdSet<{ @@ -69,7 +69,7 @@ export interface NodeInstanceProfile { "@id": string; }; creator?: string; - date?: string; + created?: string; modified?: string; title?: string; description?: ContentProfile; @@ -91,7 +91,7 @@ export interface AbstractRelationDefProfile { "@id": string; }; creator?: string; - date?: string; + created?: string; modified?: string; label: string; } @@ -112,7 +112,7 @@ export interface RelationDefProfile { "@id": string; }; creator?: string; - date?: string; + created?: string; modified?: string; label: string; domain: { @@ -136,7 +136,7 @@ export interface RelationInstanceProfile { "@id": string; }; creator?: string; - date?: string; + created?: string; modified?: string; source: NodeInstanceProfile; destination: NodeInstanceProfile; diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index 203d2c0c6..173f5aedd 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -17,7 +17,7 @@ dgshapes:ContainerProfile { dgshapes:ItemProfile { a [sioc:Item]; sioc:has_container IRI ?; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; dct:creator xsd:string ? ; } @@ -26,7 +26,7 @@ dgshapes:NodeSchemaProfile { a [dgb:NodeSchema]; sioc:has_container IRI ?; dct:creator xsd:string ? ; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:subClassOf IRI *; @@ -37,7 +37,7 @@ dgshapes:NodeInstanceProfile { a [dgshapes:NodeInstance]; sioc:has_container IRI ?; dct:creator xsd:string ? ; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; dct:title xsd:dateTime? ; dct:description @dgshapes:ContentProfile ? ; @@ -48,7 +48,7 @@ dgshapes:AbstractRelationDefProfile { rdfs:subClassOf IRI *; sioc:has_container IRI ?; dct:creator xsd:string ? ; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; } @@ -58,7 +58,7 @@ dgshapes:RelationDefProfile { rdfs:subClassOf IRI *; sioc:has_container IRI ?; dct:creator xsd:string ? ; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:domain IRI ; @@ -70,7 +70,7 @@ dgshapes:RelationInstanceProfile { a [dgb:RelationInstance]; sioc:has_container IRI ?; dct:creator xsd:string ? ; - dct:date xsd:dateTime ? ; + dct:created xsd:dateTime ? ; dct:modified xsd:dateTime ? ; dgb:source @dgshapes:NodeInstanceProfile ; dgb:destination @dgshapes:NodeInstanceProfile ; diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 242a896fb..dafbf2ee6 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -8,7 +8,6 @@ "sioc": "http://rdfs.org/sioc/ns#", "dgc": "https://discoursegraphs.com/schema/dg_core#", "dgb": "https://discoursegraphs.com/schema/dg_base#", - "mira": "http://purl.org/mira-science/mira#", "predicate": { "@id": "rdf:predicate", "@type": "@id" }, "subClassOf": { "@id": "rdfs:subClassOf", "@type": "@id" }, "domain": { "@id": "rdfs:domain", "@type": "@id" }, @@ -26,7 +25,7 @@ "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "created": { - "@id": "dct:date", + "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": "dct:creator", @@ -64,14 +63,6 @@ "supports": { "@id": "dgc:supports", "@type": "@id" }, "supportedBy": { "@id": "dgc:supportedBy", "@type": "@id" }, "addresses": { "@id": "dgc:addresses", "@type": "@id" }, - "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" }, - - "Request": "mira:Request", - "Protocol": "mira:Protocol", - "follows": { "@id": "mira:follows", "@type": "@id" }, - "grounds": { "@id": "mira:grounds", "@type": "@id" }, - "is_grounded_in": { "@id": "mira:is_grounded_in", "@type": "@id" }, - "request_for": { "@id": "mira:request_for", "@type": "@id" }, - "request_target": { "@id": "mira:request_target", "@type": "@id" } + "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" } } } diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld new file mode 100644 index 000000000..5b2b942da --- /dev/null +++ b/apps/website/public/schema/mira.jsonld @@ -0,0 +1,77 @@ +{ + "@context": { + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "owl": "http://www.w3.org/2002/07/owl#", + "dct": "http://purl.org/dc/terms/", + "prov": "http://www.w3.org/ns/prov#", + "sioc": "http://rdfs.org/sioc/ns#", + "dgc": "https://discoursegraphs.com/schema/dg_core#", + "dgb": "https://discoursegraphs.com/schema/dg_base#", + "mira": "http://purl.org/mira-science/mira#", + "predicate": { "@id": "rdf:predicate", "@type": "@id" }, + "subClassOf": { "@id": "rdfs:subClassOf", "@type": "@id" }, + "domain": { "@id": "rdfs:domain", "@type": "@id" }, + "range": { "@id": "rdfs:range", "@type": "@id" }, + "label": "rdfs:label", + "inverseOf": "owl:inverseOf", + "onProperty": "owl:onProperty", + "sameAs": { "@id": "owl:sameAs", "@type": "@id" }, + "hasValue": "owl:hasValue", + "title": "dct:title", + "format": "dct:format", + "description": "dct:description", + "modified": { + "@id": "dct:modified", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "created": { + "@id": "dct:created", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "creator": "dct:creator", + "Container": "sioc:Container", + "content": "sioc:content", + "container_of": "sioc:container_of", + "has_container": { "@id": "sioc:has_container", "@type": "@id" }, + "RelationDef": "dgb:RelationDef", + "AbstractRelationDef": "dgb:AbstractRelationDef", + "RelationInstance": "dgb:RelationInstance", + "RelationSchema": "dgb:RelationSchema", + "NodeSchema": "dgb:NodeSchema", + "source": { "@id": "dgb:source", "@type": "@id" }, + "destination": { "@id": "dgb:destination", "@type": "@id" }, + "textRefersToNode": "dgb:textRefersToNode", + + "SourceDocument": "dgc:SourceDocument", + "ClaimOrEvidence": "dgc:ClaimOrEvidence", + "observationStatement": { + "@id": "dgc:observationStatement", + "@type": "@id" + }, + "observationOriginActivity": { + "@id": "dgc:observationOriginActivity", + "@type": "@id" + }, + "observationBase": { "@id": "dgc:observationBase", "@type": "@id" }, + "sourceDocument": { "@id": "dgc:sourceDocument", "@type": "@id" }, + "describesActivity": { "@id": "dgc:describesActivity", "@type": "@id" }, + "opposes": { "@id": "dgc:opposes", "@type": "@id" }, + "opposedBy": { "@id": "dgc:opposedBy", "@type": "@id" }, + "supports": { "@id": "dgc:supports", "@type": "@id" }, + "supportedBy": { "@id": "dgc:supportedBy", "@type": "@id" }, + "addresses": { "@id": "dgc:addresses", "@type": "@id" }, + "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" }, + + "Question": "mira:Question", + "Claim": "mira:Claim", + "Evidence": "mira:Evidence", + "Request": "mira:Request", + "Protocol": "mira:Protocol", + "follows": { "@id": "mira:follows", "@type": "@id" }, + "grounds": { "@id": "mira:grounds", "@type": "@id" }, + "is_grounded_in": { "@id": "mira:is_grounded_in", "@type": "@id" }, + "request_for": { "@id": "mira:request_for", "@type": "@id" }, + "request_target": { "@id": "mira:request_target", "@type": "@id" } + } +} diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index bab25712b..1a23bb47b 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -37,7 +37,7 @@ const signedInClient = async (spaceId: number): Promise => { // example data const jsonLdData: JsonLdDocument = { - "@context": ["http://localhost:3000/schema/context.jsonld"], + "@context": ["http://localhost:3000/schema/mira.jsonld"], "@graph": [ { "@id": "sdata:131157", From 769fbed83d9576f77e5aedfce16013cccb833b34 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 13:46:23 -0400 Subject: [PATCH 19/41] Rename ClaimOrEvidence to Argument, and define as marker class for reusability. --- apps/website/public/schema/context.jsonld | 2 +- apps/website/public/schema/dg_core.ttl | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index dafbf2ee6..65b5addf0 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -46,7 +46,7 @@ "Claim": "dgc:Claim", "Evidence": "dgc:Evidence", "SourceDocument": "dgc:SourceDocument", - "ClaimOrEvidence": "dgc:ClaimOrEvidence", + "Argument": "dgc:Argument", "observationStatement": { "@id": "dgc:observationStatement", "@type": "@id" diff --git a/apps/website/public/schema/dg_core.ttl b/apps/website/public/schema/dg_core.ttl index 80a3b0eab..ca549328e 100644 --- a/apps/website/public/schema/dg_core.ttl +++ b/apps/website/public/schema/dg_core.ttl @@ -21,15 +21,20 @@ bibo:status status:draft; owl:versionInfo "0.1 (tentative)". +dg:Argument a owl:Class; + rdfs:comment "A marker class for nodes that can serve as arguments". + dg:Question a dgb:NodeSchema; rdfs:label "Question"@en; rdfs:comment "Scientific unknowns that we want to make known, and are addressable by the systematic application of research methods"@en. dg:Claim a dgb:NodeSchema; + rdfs:subClassOf dg:Argument; rdfs:label "Claim"@en; rdfs:comment "Atomic, generalized assertions about the world that (propose to) answer research questions"@en. dg:Evidence a dgb:NodeSchema; + rdfs:subClassOf dg:Argument; rdfs:label "Evidence"@en; rdfs:comment "A specific empirical observation from a particular application of a research method"@en; owl:subClassOf [rdf:type owl:Restriction ; owl:onProperty dg:observationStatement ; owl:cardinality 1], @@ -80,30 +85,26 @@ dg:sourceDocument a dgb:RelationDef; rdfs:domain dg:Evidence; rdfs:range dg:SourceDocument. -dg:ClaimOrEvidence owl:equivalentClass [ - owl:unionOf (dg:Evidence dg:Claim) -]. - dg:opposes a dgb:RelationDef; rdfs:label "Opposes"@en; rdfs:range dg:Claim; - rdfs:domain dg:ClaimOrEvidence. + rdfs:domain dg:Argument. dg:opposedBy a dgb:RelationDef; rdfs:label "Opposed by"@en; owl:inverseOf dg:opposes; - rdfs:range dg:ClaimOrEvidence; + rdfs:range dg:Argument; rdfs:domain dg:Claim. dg:supports a dgb:RelationDef; rdfs:label "Supports"@en; rdfs:range dg:Claim; - rdfs:domain dg:ClaimOrEvidence. + rdfs:domain dg:Argument. dg:supportedBy a dgb:RelationDef; rdfs:label "Supported by"@en; owl:inverseOf dg:supports; - rdfs:range dg:ClaimOrEvidence; + rdfs:range dg:Argument; rdfs:domain dg:Claim. dg:addresses a dgb:RelationDef; From 41bb9be2373a4091bb21210ceea8411721625cc5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Fri, 5 Jun 2026 13:50:31 -0400 Subject: [PATCH 20/41] extend to mira --- apps/website/public/schema/mira.jsonld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index 5b2b942da..56aa90db7 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -44,7 +44,7 @@ "textRefersToNode": "dgb:textRefersToNode", "SourceDocument": "dgc:SourceDocument", - "ClaimOrEvidence": "dgc:ClaimOrEvidence", + "Argument": "dgc:Argument", "observationStatement": { "@id": "dgc:observationStatement", "@type": "@id" From 99df6521e6084c30ad481988afd608a0157fc9e4 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 09:09:02 -0400 Subject: [PATCH 21/41] another date->created change --- apps/website/test/integration/parseJsonLd.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/website/test/integration/parseJsonLd.test.ts b/apps/website/test/integration/parseJsonLd.test.ts index dffd2a5c9..22d660ef0 100644 --- a/apps/website/test/integration/parseJsonLd.test.ts +++ b/apps/website/test/integration/parseJsonLd.test.ts @@ -148,7 +148,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { expect(parsedItem); expect(parsedItem["@id"]); expect(parsedItem.subClassOf); - expect(parsedItem.date); + expect(parsedItem.created); expect(parsedItem.modified); expect(parsedItem.creator); expect(parsedItem.hasContainer); @@ -172,7 +172,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { expect(parsedItem["@id"]); expect(parsedItem.title); expect(parsedItem.description); - expect(parsedItem.date); + expect(parsedItem.created); expect(parsedItem.modified); expect(parsedItem.creator); expect(parsedItem.hasContainer); @@ -195,7 +195,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { expect(parsedItem); expect(parsedItem["@id"]); expect(parsedItem.label); - expect(parsedItem.date); + expect(parsedItem.created); expect(parsedItem.modified); expect(parsedItem.creator); expect(parsedItem.hasContainer); @@ -218,7 +218,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { expect(parsedItem["@id"]); expect(parsedItem.domain); expect(parsedItem.range); - expect(parsedItem.date); + expect(parsedItem.created); expect(parsedItem.modified); expect(parsedItem.creator); expect(parsedItem.hasContainer); @@ -241,7 +241,7 @@ describe("LTO parsing of JSON-LD data", { tags: ["database"] }, () => { expect(parsedItem["@id"]); expect(parsedItem.source); expect(parsedItem.destination); - expect(parsedItem.date); + expect(parsedItem.created); expect(parsedItem.modified); expect(parsedItem.creator); expect(parsedItem.hasContainer); From 613b46ecbfa58498987b41420962e5d3e7f9af18 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 09:34:34 -0400 Subject: [PATCH 22/41] Add user account as part of upsert logic --- .../app/utils/conversion/fromJsonLd.ts | 142 +++++++++++++++--- .../utils/conversion/ldo/dgBase.context.ts | 17 +++ .../app/utils/conversion/ldo/dgBase.schema.ts | 28 ++++ .../utils/conversion/ldo/dgBase.shapeTypes.ts | 10 ++ .../utils/conversion/ldo/dgBase.typings.ts | 12 ++ .../app/utils/conversion/shapes/dgBase.shex | 6 + apps/website/public/schema/context.jsonld | 4 + apps/website/public/schema/mira.jsonld | 4 + .../test/integration/upsertJsonLd.test.ts | 42 ++---- 9 files changed, 213 insertions(+), 52 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 59f141860..a508461a2 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -10,8 +10,10 @@ import { RelationInstanceProfileShapeType, RelationDefProfileShapeType, AbstractRelationDefProfileShapeType, + PersonAccountProfileShapeType, } from "./ldo/dgBase.shapeTypes"; import type { + LocalAccountDataInput, LocalConceptDataInput, LocalContentDataInput, } from "@repo/database/inputTypes"; @@ -24,6 +26,7 @@ import type { RelationInstanceProfile, RelationDefProfile, AbstractRelationDefProfile, + PersonAccountProfile, } from "./ldo/dgBase.typings"; import { KnownSchemaIris, @@ -34,11 +37,13 @@ import { KnownRelationIris, } from "./jsonld"; import { DGSupabaseClient } from "@repo/database/lib/client"; -import { Json } from "@repo/database/dbTypes"; +import { Json, Enums, TablesInsert } from "@repo/database/dbTypes"; import { intersection } from "@repo/utils/setOperations"; const apiRoot = process.env.NEXT_API_ROOT; const nodeOrSpaceIdRegex = RegExp(`^${apiRoot}/data/\d+(/\d+)?$`); +type PlatformType = Enums<"Platform">; +type AccountType = TablesInsert<"PlatformAccount">; type NodeParseResult = | NodeSchemaProfile @@ -47,7 +52,11 @@ type NodeParseResult = | RelationDefProfile | AbstractRelationDefProfile; -type ParseResult = NodeParseResult | ContainerProfile | ContentProfile; +type ParseResult = + | NodeParseResult + | ContainerProfile + | ContentProfile + | PersonAccountProfile; const typePredicate = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; const nodeSchemaType = "https://discoursegraphs.com/schema/dg_base#NodeSchema"; @@ -62,6 +71,7 @@ const contentPredicate = "http://rdfs.org/sioc/ns#content"; const descriptionPredicate = "http://purl.org/dc/terms/description"; const containerType = "http://rdfs.org/sioc/ns#Container"; const restrictionType = "http://www.w3.org/2002/07/owl#Restriction"; +const accountType = "http://rdfs.org/sioc/ns#UserAccount"; export const schemaTypeSet = new Set([ nodeSchemaType, relationDefType, @@ -104,6 +114,7 @@ export const extractLdoData = async ( if (!typesA) continue; const types = new Set(typesA); if (types.has(restrictionType)) continue; + console.log(subject, types); if (intersection(types, schemaTypeSet).size) { typesA.map((t) => { if (schemaTypeSet.has(t)) { @@ -114,6 +125,14 @@ export const extractLdoData = async ( } }); } + if (types.has(accountType)) { + result.push( + ldoDataset + .usingType(PersonAccountProfileShapeType) + .fromSubject(subject), + ); + continue; + } if (types.has(containerType)) { result.push( ldoDataset.usingType(ContainerProfileShapeType).fromSubject(subject), @@ -292,6 +311,20 @@ const parseNodeSchema = ( }; }; +const parsePersonDef = ( + person: PersonAccountProfile, + platform: PlatformType, +): AccountType | null => { + const account_local_id = person["@id"]; + if (!account_local_id) return null; + return { + account_local_id, + name: person.name, + platform, + agent_type: "person", + }; +}; + const parseContent = ( content: ContentProfile, data: NodeInstanceProfile, @@ -470,15 +503,37 @@ const nodeOrder = [ "RelationInstance", ]; -export const parseJsonLdAsDataInputWithSchemas = async ( - data: JsonLdDocument, - baseIRI: string, - knownIris: Record, - knownSchemaTypes: Record, -): Promise => { +export const parseJsonLdAsDataInputWithSchemas = async ({ + data, + baseIRI, + knownIris, + knownSchemaTypes, + platform, +}: { + data: JsonLdDocument; + baseIRI: string; + knownIris: Record; + knownSchemaTypes: Record; + platform: PlatformType; +}): Promise<{ + concepts: LocalConceptDataInput[]; + accounts: LocalAccountDataInput[]; +}> => { const dataset = await parseJsonLdAsLdoDataset(data, baseIRI); const ldoData = await extractLdoData(dataset, knownIris, knownSchemaTypes); - if (ldoData.length === 0) return []; + if (ldoData.length === 0) return { concepts: [], accounts: [] }; + const accountIds: string[] = dataset + .match(null, namedNode(typePredicate), namedNode(accountType)) + .toArray() + .map((q) => q.subject.value); + const accountsLdo = ldoData.filter((d) => + accountIds.includes(d["@id"] || ""), + ) as PersonAccountProfile[]; + + const accounts = accountsLdo + .map((p) => parsePersonDef(p, platform)) + .filter((p) => p !== null); + const contentIds: string[] = dataset .match(null, namedNode(descriptionPredicate)) .toArray() @@ -490,11 +545,12 @@ export const parseJsonLdAsDataInputWithSchemas = async ( const contentById = Object.fromEntries( contents.map((c) => [c["@id"], c]), ) as Record; - const nodesWithoutContents = ldoData.filter( - (d) => contentById[d["@id"] || ""] === undefined, + const processed = new Set([...contentIds, ...accountIds]); + const nodes = ldoData.filter( + (d) => !processed.has(d["@id"] || ""), ) as NodeParseResult[]; // Reorder, put schemas first, relations last. - nodesWithoutContents.sort((n1, n2) => { + nodes.sort((n1, n2) => { const t1os = n1.type .map((x) => nodeOrder.indexOf(x["@id"])) .filter((o) => o >= 0); @@ -512,17 +568,34 @@ export const parseJsonLdAsDataInputWithSchemas = async ( if (n2["@id"] > n1["@id"]) return -1; return 0; }); - return nodesWithoutContents - .map((d) => parseLdoNode(d, contentById, knownIris, knownSchemaTypes)) - .filter((x) => !!x); + return { + accounts, + concepts: nodes + .map((d) => parseLdoNode(d, contentById, knownIris, knownSchemaTypes)) + .filter((x) => !!x), + }; }; export const parseJsonLdAsInput = async ( supabase: DGSupabaseClient, jsonLdData: JsonLdDocument, spaceId: number, -): Promise => { - const baseIri = `${apiRoot}/data/${spaceId}`; +): Promise<{ + concepts: LocalConceptDataInput[]; + accounts: LocalAccountDataInput[]; +}> => { + const baseIRI = `${apiRoot}/data/${spaceId}`; + let platform: PlatformType | undefined; + { + const { error, data } = await supabase + .from("Space") + .select("platform") + .eq("id", spaceId) + .single(); + if (error) throw error; + platform = data?.platform; + if (!platform) throw new Error("Cannot determine platform"); + } const { error, data } = await supabase .from("Concept") .select("name,source_local_id,arity,reference_content") @@ -555,12 +628,13 @@ export const parseJsonLdAsInput = async ( } }), ) as Record; - return await parseJsonLdAsDataInputWithSchemas( - jsonLdData, - baseIri, + return await parseJsonLdAsDataInputWithSchemas({ + data: jsonLdData, + baseIRI, knownIris, knownSchemaTypes, - ); + platform, + }); }; export const populate = async ( @@ -568,15 +642,33 @@ export const populate = async ( jsonLdData: JsonLdDocument, spaceId: number, ): Promise => { - const upsertData = await parseJsonLdAsInput(supabase, jsonLdData, spaceId); - if (upsertData.length === 0) return []; + const result: number[] = []; + const { concepts, accounts } = await parseJsonLdAsInput( + supabase, + jsonLdData, + spaceId, + ); + if (accounts.length) { + const { data: upsertResult, error: upsertError } = await supabase.rpc( + "upsert_accounts_in_space", + { + accounts, + space_id_: spaceId, + }, + ); + if (upsertError) throw upsertError; + result.push(...upsertResult); + } + + if (concepts.length === 0) return []; const { data: upsertResult, error: upsertError } = await supabase.rpc( "upsert_concepts", { - data: upsertData as Json, + data: concepts as Json, v_space_id: spaceId, }, ); if (upsertError) throw upsertError; - return upsertResult; + result.push(...upsertResult); + return result; }; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index a964dac13..2cbf419b4 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -70,6 +70,23 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://purl.org/dc/terms/creator", "@type": "http://www.w3.org/2001/XMLSchema#string", }, + UserAccount: { + "@id": "http://rdfs.org/sioc/ns#UserAccount", + "@context": { + type: { + "@id": "@type", + "@isCollection": true, + }, + name: { + "@id": "http://rdfs.org/sioc/ns#name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + }, + }, + name: { + "@id": "http://rdfs.org/sioc/ns#name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, NodeSchema: { "@id": "https://discoursegraphs.com/schema/dg_base#NodeSchema", "@context": { diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index 2abd6f94f..d6c8e3afc 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -36,6 +36,34 @@ export const dgBaseSchema: Schema = { }, }, }, + { + id: "https://discoursegraphs.com/schema/dg_base#PersonAccountProfile", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://rdfs.org/sioc/ns#UserAccount"], + }, + }, + { + type: "TripleConstraint", + predicate: "http://rdfs.org/sioc/ns#name", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + }, + ], + }, + }, + }, { id: "https://discoursegraphs.com/schema/dg_base#ItemProfile", type: "ShapeDecl", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts index ca450c45f..f08dc6c8f 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.shapeTypes.ts @@ -3,6 +3,7 @@ import { dgBaseSchema } from "./dgBase.schema"; import { dgBaseContext } from "./dgBase.context"; import type { ContainerProfile, + PersonAccountProfile, ItemProfile, NodeSchemaProfile, NodeInstanceProfile, @@ -27,6 +28,15 @@ export const ContainerProfileShapeType: ShapeType = { context: dgBaseContext, }; +/** + * PersonAccountProfile ShapeType + */ +export const PersonAccountProfileShapeType: ShapeType = { + schema: dgBaseSchema, + shape: "https://discoursegraphs.com/schema/dg_base#PersonAccountProfile", + context: dgBaseContext, +}; + /** * ItemProfile ShapeType */ diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index 188e1fb68..b30f6a4f4 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -18,6 +18,18 @@ export interface ContainerProfile { containerOf?: LdSet; } +/** + * PersonAccountProfile Type + */ +export interface PersonAccountProfile { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: LdSet<{ + "@id": "UserAccount"; + }>; + name: string; +} + /** * ItemProfile Type */ diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index 173f5aedd..d650694fb 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -1,3 +1,4 @@ +PREFIX foaf: PREFIX dct: PREFIX dgb: PREFIX dgshapes: @@ -14,6 +15,11 @@ dgshapes:ContainerProfile { sioc:container_of @dgshapes:ItemProfile *; } +dgshapes:PersonAccountProfile { + a [sioc:UserAccount]; + sioc:name xsd:string; +} + dgshapes:ItemProfile { a [sioc:Item]; sioc:has_container IRI ?; diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 65b5addf0..1d2848574 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -29,6 +29,10 @@ "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": "dct:creator", + "UserAccount": "sioc:UserAccount", + "name": "sioc:name", + "account_of": "sioc:account_of", + "Person": "foaf:Person", "Container": "sioc:Container", "content": "sioc:content", "container_of": "sioc:container_of", diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index 56aa90db7..b75ab5bb4 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -30,6 +30,10 @@ "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": "dct:creator", + "UserAccount": "sioc:UserAccount", + "name": "sioc:name", + "account_of": "sioc:account_of", + "Person": "foaf:Person", "Container": "sioc:Container", "content": "sioc:content", "container_of": "sioc:container_of", diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index 1a23bb47b..fa8681132 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -39,6 +39,11 @@ const signedInClient = async (spaceId: number): Promise => { const jsonLdData: JsonLdDocument = { "@context": ["http://localhost:3000/schema/mira.jsonld"], "@graph": [ + { + "@id": "some:account", + name: "Some One", + "@type": "UserAccount", + }, { "@id": "sdata:131157", "@type": "NodeSchema", @@ -46,7 +51,7 @@ const jsonLdData: JsonLdDocument = { created: "2026-01-24T15:38:14.553Z", subClassOf: ["dgc:Claim", "mira:Claim"], label: "Claim", - creator: "someone", + creator: "some:account", }, { "@id": "sdata:254918", @@ -59,7 +64,7 @@ const jsonLdData: JsonLdDocument = { content: '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', }, - creator: "someone", + creator: "some:account", }, { "@id": "sdata:261134", @@ -67,7 +72,7 @@ const jsonLdData: JsonLdDocument = { modified: "2026-05-26T00:39:03.077Z", created: "2025-12-04T15:47:51.694Z", title: "CLM - Some supporting claim", - creator: "someone", + creator: "some:account", description: { format: "text/html", content: "", @@ -87,7 +92,7 @@ const jsonLdData: JsonLdDocument = { }, ], label: "supports", - creator: "someone", + creator: "some:account", }, { "@id": "sdata:131169", @@ -98,7 +103,7 @@ const jsonLdData: JsonLdDocument = { range: "sdata:131157", subClassOf: ["sdata:131164"], label: "supports", - creator: "someone", + creator: "some:account", }, { "@id": "sdata:261147", @@ -109,7 +114,7 @@ const jsonLdData: JsonLdDocument = { destination: "sdata:254918", title: "[[CLM - Some supporting claim]] -supports-> [[CLM - Some base claim]]", - creator: "someone", + creator: "some:account", }, ], }; @@ -118,7 +123,6 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { let spaceId: number; let spaceAccountUuid: string; let client: DGSupabaseClient; - let authorAccountId: number; beforeAll(async () => { const spaceReq = await fetchOrCreateSpaceDirect({ @@ -144,31 +148,15 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { assert(accountReq.data); assert(accountReq.data.dg_account); spaceAccountUuid = accountReq.data.dg_account; - const authorAccountReq = await client.rpc("upsert_accounts_in_space", { - accounts: [ - { - name: "someone", - account_local_id: "someone", - platform: "Roam", - agent_type: "person", - }, - ], - space_id_: spaceId, - }); - console.error(authorAccountReq.error); - assert(!authorAccountReq.error); - assert(authorAccountReq.data); - authorAccountId = authorAccountReq.data[0]!; }); afterAll(async () => { if (spaceAccountUuid) await serviceClient().auth.admin.deleteUser(spaceAccountUuid); if (spaceId) await serviceClient().from("Space").delete().eq("id", spaceId); - if (authorAccountId) - await serviceClient() - .from("PlatformAccount") - .delete() - .eq("id", authorAccountId); + await serviceClient() + .from("PlatformAccount") + .delete() + .eq("account_local_id", "someone"); }); it("Upserts the data", async () => { From a7133af174d823153238f5dca52c4d3b50aefdc8 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 09:55:11 -0400 Subject: [PATCH 23/41] output creator correctly --- apps/website/app/utils/conversion/jsonld.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index 4045e3294..e49fb16e2 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -171,8 +171,12 @@ export const asJsonLD = ({ } if (author) { - extraData.creator = author.name; - // TODO: make into an object? + extraData.creator = { + // TODO: ensure it's a URL + "@id": author.account_local_id, + "@type": "UserAccount", + name: author.name, + }; } let lastModified = concept.last_modified; if (content && content.last_modified > lastModified) From 2a9684f9a37b7ebc8c755e5553402537e5452a98 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 10:02:26 -0400 Subject: [PATCH 24/41] Creator as object --- .../app/utils/conversion/fromJsonLd.ts | 2 +- .../utils/conversion/ldo/dgBase.context.ts | 14 ++++---- .../app/utils/conversion/ldo/dgBase.schema.ts | 36 ++++--------------- .../utils/conversion/ldo/dgBase.typings.ts | 36 ++++++++++++------- .../app/utils/conversion/shapes/dgBase.shex | 24 ++++++------- apps/website/public/schema/context.jsonld | 2 +- apps/website/public/schema/mira.jsonld | 2 +- 7 files changed, 52 insertions(+), 64 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index a508461a2..bd7259b49 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -260,7 +260,7 @@ const parseBaseData = (data: NodeParseResult) => { return { created: data.created, last_modified: data.modified, - author_local_id: data.creator, + author_local_id: data.creator["@id"], ...spaceInfo, }; }; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index 2cbf419b4..b48021487 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -50,7 +50,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, }, }, @@ -68,7 +68,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, UserAccount: { "@id": "http://rdfs.org/sioc/ns#UserAccount", @@ -100,7 +100,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, created: { "@id": "http://purl.org/dc/terms/created", @@ -143,7 +143,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, created: { "@id": "http://purl.org/dc/terms/created", @@ -214,7 +214,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, created: { "@id": "http://purl.org/dc/terms/created", @@ -248,7 +248,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, created: { "@id": "http://purl.org/dc/terms/created", @@ -293,7 +293,7 @@ export const dgBaseContext: LdoJsonldContext = { }, creator: { "@id": "http://purl.org/dc/terms/creator", - "@type": "http://www.w3.org/2001/XMLSchema#string", + "@type": "@id", }, created: { "@id": "http://purl.org/dc/terms/created", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index d6c8e3afc..a0556b90c 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -97,8 +97,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -115,10 +113,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, ], }, @@ -157,10 +153,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -169,8 +163,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -237,10 +229,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -249,8 +239,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -327,10 +315,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -339,8 +325,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -407,10 +391,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -419,8 +401,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -493,10 +473,8 @@ export const dgBaseSchema: Schema = { predicate: "http://purl.org/dc/terms/creator", valueExpr: { type: "NodeConstraint", - datatype: "http://www.w3.org/2001/XMLSchema#string", + nodeKind: "iri", }, - min: 0, - max: 1, }, { type: "TripleConstraint", @@ -505,8 +483,6 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#dateTime", }, - min: 0, - max: 1, }, { type: "TripleConstraint", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index b30f6a4f4..983d298a4 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -42,9 +42,11 @@ export interface ItemProfile { hasContainer?: { "@id": string; }; - created?: string; + created: string; modified?: string; - creator?: string; + creator: { + "@id": string; + }; } /** @@ -59,8 +61,10 @@ export interface NodeSchemaProfile { hasContainer?: { "@id": string; }; - creator?: string; - created?: string; + creator: { + "@id": string; + }; + created: string; modified?: string; label: string; subClassOf?: LdSet<{ @@ -80,8 +84,10 @@ export interface NodeInstanceProfile { hasContainer?: { "@id": string; }; - creator?: string; - created?: string; + creator: { + "@id": string; + }; + created: string; modified?: string; title?: string; description?: ContentProfile; @@ -102,8 +108,10 @@ export interface AbstractRelationDefProfile { hasContainer?: { "@id": string; }; - creator?: string; - created?: string; + creator: { + "@id": string; + }; + created: string; modified?: string; label: string; } @@ -123,8 +131,10 @@ export interface RelationDefProfile { hasContainer?: { "@id": string; }; - creator?: string; - created?: string; + creator: { + "@id": string; + }; + created: string; modified?: string; label: string; domain: { @@ -147,8 +157,10 @@ export interface RelationInstanceProfile { hasContainer?: { "@id": string; }; - creator?: string; - created?: string; + creator: { + "@id": string; + }; + created: string; modified?: string; source: NodeInstanceProfile; destination: NodeInstanceProfile; diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index d650694fb..bd5ef9753 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -23,16 +23,16 @@ dgshapes:PersonAccountProfile { dgshapes:ItemProfile { a [sioc:Item]; sioc:has_container IRI ?; - dct:created xsd:dateTime ? ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; - dct:creator xsd:string ? ; + dct:creator IRI ; } dgshapes:NodeSchemaProfile { a [dgb:NodeSchema]; sioc:has_container IRI ?; - dct:creator xsd:string ? ; - dct:created xsd:dateTime ? ; + dct:creator IRI ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:subClassOf IRI *; @@ -42,8 +42,8 @@ dgshapes:NodeSchemaProfile { dgshapes:NodeInstanceProfile { a [dgshapes:NodeInstance]; sioc:has_container IRI ?; - dct:creator xsd:string ? ; - dct:created xsd:dateTime ? ; + dct:creator IRI ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; dct:title xsd:dateTime? ; dct:description @dgshapes:ContentProfile ? ; @@ -53,8 +53,8 @@ dgshapes:AbstractRelationDefProfile { a [dgb:AbstractRelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dct:creator xsd:string ? ; - dct:created xsd:dateTime ? ; + dct:creator IRI ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; } @@ -63,8 +63,8 @@ dgshapes:RelationDefProfile { a [dgshapes:RelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dct:creator xsd:string ? ; - dct:created xsd:dateTime ? ; + dct:creator IRI ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; rdfs:domain IRI ; @@ -75,8 +75,8 @@ dgshapes:RelationDefProfile { dgshapes:RelationInstanceProfile { a [dgb:RelationInstance]; sioc:has_container IRI ?; - dct:creator xsd:string ? ; - dct:created xsd:dateTime ? ; + dct:creator IRI ; + dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; dgb:source @dgshapes:NodeInstanceProfile ; dgb:destination @dgshapes:NodeInstanceProfile ; diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 1d2848574..4a5223aba 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -28,7 +28,7 @@ "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, - "creator": "dct:creator", + "creator": { "@id": "dct:creator", "@type": "@id" }, "UserAccount": "sioc:UserAccount", "name": "sioc:name", "account_of": "sioc:account_of", diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index b75ab5bb4..f4f3c4da3 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -29,7 +29,7 @@ "@id": "dct:created", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, - "creator": "dct:creator", + "creator": { "@id": "dct:creator", "@type": "@id" }, "UserAccount": "sioc:UserAccount", "name": "sioc:name", "account_of": "sioc:account_of", From dd7de08e439a8f3b84cd53806c85ea0ddf14c9cc Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 12:33:29 -0400 Subject: [PATCH 25/41] Expose public content --- .../content/[space_id]/[resource_id]/route.ts | 27 ++++++++++--------- .../data/[space_id]/[resource_id]/route.ts | 27 ++++++++++--------- apps/website/app/utils/conversion/jsonld.ts | 10 +++---- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts index 326617b60..0a83066aa 100644 --- a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -6,13 +6,13 @@ import { createApiResponse, } from "~/utils/supabase/apiUtils"; import { asJsonLD } from "~/utils/conversion/jsonld"; -import { Tables } from "@repo/database/dbTypes"; +import { Tables, Enums } from "@repo/database/dbTypes"; import { convert, MIMETYPES, type DocType } from "~/utils/conversion/convert"; type Concept = Tables<"Concept">; type Content = Tables<"Content">; -type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; +type Platform = Enums<"Platform">; export type SegmentDataType = { params: Promise> }; @@ -59,15 +59,18 @@ export const GET = async ( if (spaceResponse.error) { return createApiResponse(request, spaceResponse); } - if (!spaceResponse.data) { + let platform: Platform = "Obsidian"; + if (spaceResponse.data) { + platform = spaceResponse.data.platform; + } else { // consideration: We may not see it because we don't have access, - // so it would be worth re-fetching as superuser to see if I should redirect to login. - return createApiResponse( - request, - asPostgrestFailure("Space not found", "401", 401), - ); + // We should find a way to check its platform otherwise. + // Let's just keep the Obsidian guess for MIRA demo. + // return createApiResponse( + // request, + // asPostgrestFailure("Space not found", "401", 401), + // ); } - const space: Space = spaceResponse.data; const conceptResponse = await supabase .from("Concept") .select() @@ -112,9 +115,9 @@ export const GET = async ( // await initRT(rootUrl); const source: DocType | undefined = - space.platform === "Obsidian" + platform === "Obsidian" ? "obsidian" - : space.platform === "Roam" + : platform === "Roam" ? "roam" : undefined; let text = @@ -154,7 +157,7 @@ export const GET = async ( } const jsonLdData = asJsonLD({ - space, + platform, concept, baseUrl, title, diff --git a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts index d8c0794b6..727934cca 100644 --- a/apps/website/app/api/data/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/data/[space_id]/[resource_id]/route.ts @@ -6,14 +6,14 @@ import { createApiResponse, } from "~/utils/supabase/apiUtils"; import { asJsonLD, wrapJsonLd } from "~/utils/conversion/jsonld"; -import { Tables } from "@repo/database/dbTypes"; +import type { Tables, Enums } from "@repo/database/dbTypes"; import { PostgrestMaybeSingleResponse } from "@supabase/supabase-js"; import { MIMETYPES, type DocType } from "~/utils/conversion/convert"; type Concept = Tables<"Concept">; type Content = Tables<"Content">; -type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; +type Platform = Enums<"Platform">; export type SegmentDataType = { params: Promise> }; @@ -53,15 +53,18 @@ export const GET = async ( if (spaceResponse.error) { return createApiResponse(request, spaceResponse); } - if (!spaceResponse.data) { + let platform: Platform = "Obsidian"; + if (spaceResponse.data) { + platform = spaceResponse.data.platform; + } else { // consideration: We may not see it because we don't have access, - // so it would be worth re-fetching as superuser to see if I should redirect to login. - return createApiResponse( - request, - asPostgrestFailure("Space not found", "401", 401), - ); + // We should find a way to check its platform otherwise. + // Let's just keep the Obsidian guess for MIRA demo. + // return createApiResponse( + // request, + // asPostgrestFailure("Space not found", "401", 401), + // ); } - const space: Space = spaceResponse.data; const conceptResponse = await supabase .from("Concept") .select() @@ -161,7 +164,7 @@ export const GET = async ( const relationsJLD = withContext ? relations.map((c) => asJsonLD({ - space, + platform, concept: c, baseUrl, schema: c.schema_id ? schemas[c.schema_id] : undefined, @@ -172,7 +175,7 @@ export const GET = async ( const schemasJLD = withSchema ? Object.values(schemas).map((c) => asJsonLD({ - space, + platform, concept: c, baseUrl, author: c.author_id ? authors[c.author_id] : undefined, @@ -181,7 +184,7 @@ export const GET = async ( : []; const baseJLDData = asJsonLD({ - space, + platform, concept, baseUrl, title, diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index e49fb16e2..6750ce1d9 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -1,10 +1,10 @@ -import { Tables, Json } from "@repo/database/dbTypes"; +import type { Tables, Enums, Json } from "@repo/database/dbTypes"; import { convert, MIMETYPES, type DocType } from "~/utils/conversion/convert"; type Concept = Tables<"Concept">; type Content = Tables<"Content">; -type Space = Tables<"Space">; type PlatformAccount = Tables<"PlatformAccount">; +type Platform = Enums<"Platform">; // This is a temporary hack export const KnownClassEntities: Record = { @@ -69,7 +69,7 @@ export const KnownSchemaCuries = Object.values(KnownSchemaEntities).flat(); export const KnownSchemaIris = new Set(KnownSchemaCuries.map(curieToIri)); export const asJsonLD = ({ - space, + platform, concept, baseUrl, title, @@ -79,7 +79,7 @@ export const asJsonLD = ({ targetFormat, wrap, }: { - space: Space; + platform: Platform; concept: Concept; baseUrl: string; title?: Content; @@ -160,7 +160,7 @@ export const asJsonLD = ({ const rootUrl = baseUrl.split("/").slice(0, 3).join("/"); pageUrl = `${rootUrl}/api/content/${baseUrl.split("/")[5]}/${concept.id}#`; const source: DocType | undefined = - space.platform === "Obsidian" ? "obsidian" : "markdown"; + platform === "Obsidian" ? "obsidian" : "markdown"; // punt roam-json const contentText = source && convert(content.text, source, targetFormat); extraData["description"] = { From f34a91a0aa5b95b1226c26e3c13a52218ef834ef Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 16:41:27 -0400 Subject: [PATCH 26/41] OpenGraph data --- .../content/[space_id]/[resource_id]/route.ts | 62 ++++++++++++------- apps/website/app/utils/conversion/jsonld.ts | 23 +++++++ 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts index 0a83066aa..4496209f1 100644 --- a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -5,7 +5,7 @@ import { defaultOptionsHandler, createApiResponse, } from "~/utils/supabase/apiUtils"; -import { asJsonLD } from "~/utils/conversion/jsonld"; +import { asJsonLD, conceptName } from "~/utils/conversion/jsonld"; import { Tables, Enums } from "@repo/database/dbTypes"; import { convert, MIMETYPES, type DocType } from "~/utils/conversion/convert"; @@ -124,27 +124,28 @@ export const GET = async ( source && source !== targetFormat ? convert(fullContents.text, source, targetFormat) : fullContents.text; - if (includeData) { - const isSchema = concept.is_schema; - let schema: Concept | undefined = undefined; - if (!isSchema && concept.schema_id) { - const schemaResponse = await supabase - .from("Concept") - .select() - .eq("id", concept.schema_id) - .maybeSingle(); - if (schemaResponse.error) { - return createApiResponse(request, schemaResponse); - } - if (!schemaResponse.data) { - return createApiResponse( - request, - asPostgrestFailure("Resource schema not found", "401", 401), - ); - } - schema = schemaResponse.data; + const isSchema = concept.is_schema; + let schema: Concept | undefined = undefined; + if (!isSchema && concept.schema_id) { + const schemaResponse = await supabase + .from("Concept") + .select() + .eq("id", concept.schema_id) + .maybeSingle(); + if (schemaResponse.error) { + return createApiResponse(request, schemaResponse); + } + if (!schemaResponse.data) { + return createApiResponse( + request, + asPostgrestFailure("Resource schema not found", "401", 401), + ); } + schema = schemaResponse.data; + } + const schemaName = conceptName(concept, schema); + if (includeData) { const authorId = concept.author_id ?? (contents ?? [{}])[0]?.author_id; let author: PlatformAccount | undefined = undefined; if (authorId) { @@ -169,8 +170,27 @@ export const GET = async ( }); text = `
\n\n${text}\n
`; } + const divideFM = fullContents.text.split("---\n"); + const firstTextFragment = + divideFM.length > 2 && divideFM[0].trim().length == 0 + ? divideFM[2] + : fullContents.text; + + const wrap = ` + ${title ? '' : ""} + + + + + +
+ ${text} +
+ + +`; - return new NextResponse(text, { + return new NextResponse(wrap, { headers: { "Content-Type": targetMimetype }, }); }; diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index 6750ce1d9..e8a7a084e 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -68,6 +68,29 @@ export const KnownRelationIris = new Set(KnownRelationCuries.map(curieToIri)); export const KnownSchemaCuries = Object.values(KnownSchemaEntities).flat(); export const KnownSchemaIris = new Set(KnownSchemaCuries.map(curieToIri)); +export const conceptName = ( + concept: Concept, + schema: Concept | undefined, +): string => { + console.log(concept, schema); + if (concept.is_schema) { + if (concept.arity !== 2) + return "https://discoursegraphs.com/schema/dg_base#NodeSchema"; + const ref = (concept.reference_content || {}) as Record< + string, + number | number[] + >; + if (ref["source"]) + return "https://discoursegraphs.com/schema/dg_base#RelationDefSchema"; + return "https://discoursegraphs.com/schema/dg_base#AbstractRelationDefSchema"; + } + const name = schema?.name; + if (!name) return "document"; // really an error here + const entities = KnownSchemaEntities[name]; + if (!entities) return name; + return entities[0]!; +}; + export const asJsonLD = ({ platform, concept, From 75a3901e22411103c8e603f125af54e61b5d8229 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 16:51:21 -0400 Subject: [PATCH 27/41] ts is really bad at array indices --- .../website/app/api/content/[space_id]/[resource_id]/route.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts index 4496209f1..49f59f18a 100644 --- a/apps/website/app/api/content/[space_id]/[resource_id]/route.ts +++ b/apps/website/app/api/content/[space_id]/[resource_id]/route.ts @@ -172,8 +172,8 @@ export const GET = async ( } const divideFM = fullContents.text.split("---\n"); const firstTextFragment = - divideFM.length > 2 && divideFM[0].trim().length == 0 - ? divideFM[2] + divideFM.length > 2 && divideFM[0]!.trim().length == 0 + ? divideFM[2]! : fullContents.text; const wrap = ` From 34170f5b734e4252256a37b327ee38d7a1de40f0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sat, 6 Jun 2026 18:05:04 -0400 Subject: [PATCH 28/41] forgot a log --- apps/website/app/utils/conversion/jsonld.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index e8a7a084e..d0bf00140 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -72,7 +72,6 @@ export const conceptName = ( concept: Concept, schema: Concept | undefined, ): string => { - console.log(concept, schema); if (concept.is_schema) { if (concept.arity !== 2) return "https://discoursegraphs.com/schema/dg_base#NodeSchema"; From 1544db02489eb5d78229ef9cd69e53fdbdfb5064 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sun, 7 Jun 2026 10:46:13 -0400 Subject: [PATCH 29/41] iriToCurie --- apps/website/app/utils/conversion/jsonld.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index d0bf00140..a83445b1a 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -44,6 +44,7 @@ const prefixes: Record = { rdfs: "http://www.w3.org/2000/01/rdf-schema#", owl: "http://www.w3.org/2002/07/owl#", dc: "http://purl.org/dc/elements/1.1/", + dct: "http://purl.org/dc/terms/", prov: "http://www.w3.org/ns/prov#", sioc: "http://rdfs.org/sioc/ns#", dgb: "https://discoursegraphs.com/schema/dg_base#", @@ -61,6 +62,16 @@ export const curieToIri = (curie: string): string => { return iri + name; }; +export const iriToCurie = (iri: string): string => { + // not efficient, but not so many prefixes, and easier than determining the cut point + for (const [prefix, base] of Object.entries(prefixes)) { + if (iri.startsWith(base)) { + return prefix + ":" + iri.substring(base.length); + } + } + return iri; +}; + export const KnownClassCuries = Object.values(KnownClassEntities).flat(); export const KnownClassIris = new Set(KnownClassCuries.map(curieToIri)); export const KnownRelationCuries = Object.values(KnownRelationEntities).flat(); From 16b5c7c0b63adeca8d841dfdfcb84bcd55942fba Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sun, 7 Jun 2026 23:03:29 +0100 Subject: [PATCH 30/41] Add extra json attributes to literal_content --- .../app/utils/conversion/fromJsonLd.ts | 150 ++++++++++++++++-- apps/website/package.json | 1 + pnpm-lock.yaml | 84 ++-------- 3 files changed, 151 insertions(+), 84 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index bd7259b49..73639b10f 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -1,6 +1,9 @@ import { namedNode } from "@ldo/rdf-utils"; -import type { NamedNode } from "@rdfjs/types"; -import { parseRdf, type LdoDataset } from "@ldo/ldo"; +import type { NamedNode, Quad_Object, Literal } from "@rdfjs/types"; +import { parseRdf } from "@ldo/ldo"; +import type { LdoDataset, ShapeType, LdoBase } from "@ldo/ldo"; +import ShexJTraverser from "@ldo/traverser-shexj"; +import { type ShapeDecl } from "@ldo/traverser-shexj"; import { toRDF, type JsonLdDocument } from "jsonld"; import { ContainerProfileShapeType, @@ -33,6 +36,7 @@ import { KnownSchemaEntities, KnownRelationEntities, curieToIri, + iriToCurie, KnownClassIris, KnownRelationIris, } from "./jsonld"; @@ -114,7 +118,6 @@ export const extractLdoData = async ( if (!typesA) continue; const types = new Set(typesA); if (types.has(restrictionType)) continue; - console.log(subject, types); if (intersection(types, schemaTypeSet).size) { typesA.map((t) => { if (schemaTypeSet.has(t)) { @@ -250,6 +253,94 @@ const interpretId = ( return { [localVarName]: id } as Record; }; +const KnownShapeIris: Record> = {}; + +type PredicateExtractionVisitorContext = { + predicates: Set; +}; + +const predicateExtractionVisitor = + ShexJTraverser.createVisitor({ + TripleConstraint: { + visitor: async (tripleConstraint, instanceNode, context) => { + context.predicates.add(tripleConstraint.predicate); + }, + }, + }); + +const getKnownIris = async ( + shapeDecl: ShapeDecl | undefined, +): Promise> => { + if (shapeDecl === undefined) return new Set(); + if (KnownShapeIris[shapeDecl.id] === undefined) { + const context: PredicateExtractionVisitorContext = { + predicates: new Set(), + }; + await predicateExtractionVisitor.visit(shapeDecl, "ShapeDecl", context); + KnownShapeIris[shapeDecl.id] = context.predicates; + } + return KnownShapeIris[shapeDecl.id] ?? new Set(); +}; + +const identifyExtraData = async ( + dataset: LdoDataset, + id: string, + shape: ShapeType, +): Promise<{ + literals: Record; + references: Record; +}> => { + const shapeDecl = (shape.schema.shapes ?? []).filter( + (s) => s.id === shape.shape, + )[0]; + const knownIris = await getKnownIris(shapeDecl); + const extra: [string, Quad_Object][] = dataset + .match(namedNode(id)) + .toArray() + .filter((q) => !knownIris.has(q.predicate.value)) + .map((q) => [q.predicate.value, q.object]); + const literals: Record = {}; + const references: Record = {}; + for (let [s, o] of extra) { + s = iriToCurie(s); + const results = + o.termType === "Literal" + ? literals + : o.termType === "NamedNode" + ? references + : null; + if (results === null) continue; + const value = o.termType === "NamedNode" ? iriToCurie(o.value) : o.value; + if (results[s] === undefined) results[s] = value; + else if (Array.isArray(results[s])) (results[s] as string[]).push(value); + else results[s] = [results[s] as string, value]; + } + return { literals, references }; +}; + +const addExtraData = async ( + dataset: LdoDataset, + id: string, + shape: ShapeType, + concept: LocalConceptDataInput | null, +): Promise => { + if (concept === null) return null; + const { literals, references } = await identifyExtraData(dataset, id, shape); + if (Object.keys(literals).length > 0) + concept.literal_content = { + extra: literals, + ...((concept.literal_content as Record) || {}), + }; + // TODO check which iris are internal refs + // if (Object.keys(references).length > 0) + // concept.reference_content = { + // extra: references, + // ...((concept.reference_content as Record) || + // {}), + // }; + return concept; +}; + const baseInterpretId = (id: string) => interpretId(id, "id", "source_local_id"); @@ -444,12 +535,13 @@ const parseRelationInstance = ( }; }; -const parseLdoNode = ( +const parseLdoNode = async ( data: NodeParseResult, contentById: Record, knownIris: Record, knownSchemaTypes: Record, -): LocalConceptDataInput | null => { + dataset: LdoDataset, +): Promise => { if (!data["@id"]) { console.error("No @id: ", data); return null; @@ -462,14 +554,26 @@ const parseLdoNode = ( (data as RelationDefProfile).domain && (data as RelationDefProfile).range ) - return parseRelationDef(data as RelationDefProfile, knownIris); + return await addExtraData( + dataset, + data["@id"], + RelationDefProfileShapeType, + parseRelationDef(data as RelationDefProfile, knownIris), + ); else if (types.has("AbstractRelationDef") || types.has("RelationDef")) - return parseAbstractRelationDef( - data as AbstractRelationDefProfile, - knownIris, + return await addExtraData( + dataset, + data["@id"], + AbstractRelationDefProfileShapeType, + parseAbstractRelationDef(data as AbstractRelationDefProfile, knownIris), ); if (types.has("NodeSchema")) - return parseNodeSchema(data as NodeSchemaProfile, knownIris); + return await addExtraData( + dataset, + data["@id"], + NodeSchemaProfileShapeType, + parseNodeSchema(data as NodeSchemaProfile, knownIris), + ); // now instance heuristics let schemaType: string | undefined; @@ -486,10 +590,20 @@ const parseLdoNode = ( ? nodeInstance.description : contentById[nodeInstance.description["@id"]!]; if (!content) return null; - return parseNodeInstance(nodeInstance, content, knownIris); + return await addExtraData( + dataset, + data["@id"], + NodeInstanceProfileShapeType, + parseNodeInstance(nodeInstance, content, knownIris), + ); } if (schemaType === relationDefType || schemaType === abstractRelationDefType) - return parseRelationInstance(data as RelationInstanceProfile, knownIris); + return await addExtraData( + dataset, + data["@id"], + RelationInstanceProfileShapeType, + parseRelationInstance(data as RelationInstanceProfile, knownIris), + ); console.error("We should not get here", [...types], data); return null; @@ -568,11 +682,17 @@ export const parseJsonLdAsDataInputWithSchemas = async ({ if (n2["@id"] > n1["@id"]) return -1; return 0; }); + const concepts = ( + await Promise.all( + nodes.map((d) => + parseLdoNode(d, contentById, knownIris, knownSchemaTypes, dataset), + ), + ) + ).filter((x) => !!x); + return { accounts, - concepts: nodes - .map((d) => parseLdoNode(d, contentById, knownIris, knownSchemaTypes)) - .filter((x) => !!x), + concepts, }; }; diff --git a/apps/website/package.json b/apps/website/package.json index 9cf0bd2c3..c98f0c5cf 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -19,6 +19,7 @@ "dependencies": { "@ldo/ldo": "1.0.0-alpha.51", "@ldo/rdf-utils": "1.0.0-alpha.51", + "@ldo/traverser-shexj": "1.0.0-alpha.51", "@repo/database": "workspace:*", "@repo/ui": "workspace:*", "@repo/utils": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8506e3d7..1475e28c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,7 +343,7 @@ importers: version: 3.5.2(react@18.2.0) roamjs-components: specifier: 0.88.1 - version: 0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51) + version: 0.88.1(6fc269b31b2749e4d441ca378d1de710) tldraw: specifier: 2.4.6 version: 2.4.6(patch_hash=56e196052862c9a58a11b43e5e121384cd1d6548416afa0f16e9fbfbf0e4080d)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -395,7 +395,7 @@ importers: version: 0.17.14 tailwindcss: specifier: ^3.4.17 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) tsx: specifier: ^4.19.2 version: 4.20.5 @@ -439,6 +439,9 @@ importers: '@ldo/rdf-utils': specifier: 1.0.0-alpha.51 version: 1.0.0-alpha.51 + '@ldo/traverser-shexj': + specifier: 1.0.0-alpha.51 + version: 1.0.0-alpha.51 '@repo/database': specifier: workspace:* version: link:../../packages/database @@ -689,10 +692,10 @@ importers: version: link:../typescript-config tailwindcss: specifier: ^3.4.1 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + version: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))) + version: 1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))) packages/types: {} @@ -16896,22 +16899,22 @@ snapshots: '@rushstack/eslint-patch@1.12.0': {} - '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76)': + '@samepage/scripts@0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76)': dependencies: '@aws-sdk/client-lambda': 3.882.0 '@aws-sdk/client-s3': 3.882.0 - '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) + '@samepage/testing': 0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) archiver: 5.3.2 axios: 0.27.2(debug@4.4.3) debug: 4.4.3 dotenv: 16.6.1 esbuild: 0.17.14 patch-package: 6.5.1 - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) zod: 3.25.76 - '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))': + '@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))': dependencies: '@playwright/test': 1.29.0 '@testing-library/react': 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -16921,7 +16924,7 @@ snapshots: debug: 4.4.3 dotenv: 16.6.1 jsdom: 20.0.3 - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -23945,14 +23948,6 @@ snapshots: postcss: 8.5.6 ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.5.4) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.1 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@types/node@20.19.13)(typescript@5.9.3) - postcss-nested@6.2.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -25071,12 +25066,12 @@ snapshots: dependencies: glob: 7.2.3 - roamjs-components@0.88.1(f3dd466ad63c875d7b4d2c35ecf33e51): + roamjs-components@0.88.1(6fc269b31b2749e4d441ca378d1de710): dependencies: '@blueprintjs/core': 3.50.4(patch_hash=51c5847e0a73a1be0cc263036ff64d8fada46f3b65831ed938dbca5eecf3edc0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/datetime': 3.23.14(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@blueprintjs/select': 3.19.1(patch_hash=5b2821b0bf7274e9b64d7824648c596b9e73c61f421d699a6d4c494f12f62355)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))(zod@3.25.76) + '@samepage/scripts': 0.74.5(@aws-sdk/client-lambda@3.882.0)(@aws-sdk/client-s3@3.882.0)(@samepage/testing@0.74.5(@playwright/test@1.29.0)(@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.17)(@types/react@18.2.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1))(@types/jsdom@20.0.1)(c8@7.14.0)(debug@4.4.3)(dotenv@16.6.1)(jsdom@20.0.3)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(archiver@5.3.2)(axios@0.27.2(debug@4.4.3))(debug@4.4.3)(dotenv@16.6.1)(esbuild@0.17.14)(patch-package@6.5.1)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)))(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4))(zod@3.25.76) '@types/crypto-js': 4.1.1 '@types/cytoscape': 3.21.9 '@types/file-saver': 2.0.5 @@ -25910,10 +25905,6 @@ snapshots: dependencies: tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3))): - dependencies: - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 @@ -25941,33 +25932,6 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)): - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3)) - postcss-nested: 6.2.0(postcss@8.5.6) - postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -26245,24 +26209,6 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@20.19.13)(typescript@5.9.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.13 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - ts-toolbelt@6.15.5: {} ts-toolbelt@9.6.0: {} From ceac739f30b875ea53db3137c9f1c4f39d79339d Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Sun, 7 Jun 2026 23:11:21 +0100 Subject: [PATCH 31/41] check-types --- apps/website/app/utils/conversion/jsonld.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/website/app/utils/conversion/jsonld.ts b/apps/website/app/utils/conversion/jsonld.ts index a83445b1a..351c0de53 100644 --- a/apps/website/app/utils/conversion/jsonld.ts +++ b/apps/website/app/utils/conversion/jsonld.ts @@ -211,6 +211,17 @@ export const asJsonLD = ({ name: author.name, }; } + if ( + concept.literal_content !== null && + (concept.literal_content as Record).extra !== undefined + ) + extraData = { + ...extraData, + ...((concept.literal_content as Record).extra as Record< + string, + string | string[] + >), + }; let lastModified = concept.last_modified; if (content && content.last_modified > lastModified) lastModified = content.last_modified; From 89f24a2d10530422b33da07000ae543f83c620d5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 09:12:58 +0100 Subject: [PATCH 32/41] jsonld --- apps/website/public/schema/context.jsonld | 12 ++++++++---- apps/website/public/schema/mira.jsonld | 14 ++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/website/public/schema/context.jsonld b/apps/website/public/schema/context.jsonld index 4a5223aba..aedbda640 100644 --- a/apps/website/public/schema/context.jsonld +++ b/apps/website/public/schema/context.jsonld @@ -5,6 +5,7 @@ "owl": "http://www.w3.org/2002/07/owl#", "dct": "http://purl.org/dc/terms/", "prov": "http://www.w3.org/ns/prov#", + "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "dgc": "https://discoursegraphs.com/schema/dg_core#", "dgb": "https://discoursegraphs.com/schema/dg_base#", @@ -19,7 +20,7 @@ "hasValue": "owl:hasValue", "title": "dct:title", "format": "dct:format", - "description": "dct:description", + "description": { "@id": "dct:description", "@type": "@id" }, "modified": { "@id": "dct:modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" @@ -30,18 +31,21 @@ }, "creator": { "@id": "dct:creator", "@type": "@id" }, "UserAccount": "sioc:UserAccount", - "name": "sioc:name", - "account_of": "sioc:account_of", + "name": "foaf:name", + "accountName": "foaf:accountName", + "account": { "@id": "dct:creator", "@type": "foaf:account" }, + "account_of": { "@id": "dct:creator", "@type": "sioc:account_of" }, "Person": "foaf:Person", "Container": "sioc:Container", "content": "sioc:content", - "container_of": "sioc:container_of", + "container_of": { "@type": "@id", "@id": "sioc:container_of" }, "has_container": { "@id": "sioc:has_container", "@type": "@id" }, "RelationDef": "dgb:RelationDef", "AbstractRelationDef": "dgb:AbstractRelationDef", "RelationInstance": "dgb:RelationInstance", "RelationSchema": "dgb:RelationSchema", "NodeSchema": "dgb:NodeSchema", + "Agent": "dgb:Agent", "source": { "@id": "dgb:source", "@type": "@id" }, "destination": { "@id": "dgb:destination", "@type": "@id" }, "textRefersToNode": "dgb:textRefersToNode", diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index f4f3c4da3..753328e47 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -5,6 +5,7 @@ "owl": "http://www.w3.org/2002/07/owl#", "dct": "http://purl.org/dc/terms/", "prov": "http://www.w3.org/ns/prov#", + "foaf": "http://xmlns.com/foaf/0.1/", "sioc": "http://rdfs.org/sioc/ns#", "dgc": "https://discoursegraphs.com/schema/dg_core#", "dgb": "https://discoursegraphs.com/schema/dg_base#", @@ -20,7 +21,7 @@ "hasValue": "owl:hasValue", "title": "dct:title", "format": "dct:format", - "description": "dct:description", + "description": { "@id": "dct:description", "@type": "@id" }, "modified": { "@id": "dct:modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" @@ -30,15 +31,16 @@ "@type": "http://www.w3.org/2001/XMLSchema#dateTime" }, "creator": { "@id": "dct:creator", "@type": "@id" }, - "UserAccount": "sioc:UserAccount", - "name": "sioc:name", - "account_of": "sioc:account_of", - "Person": "foaf:Person", + "accountName": "foaf:accountName", + "name": "foaf:name", + "account": "foaf:account", "Container": "sioc:Container", + "UserAccount": "sioc:UserAccount", "content": "sioc:content", - "container_of": "sioc:container_of", + "container_of": { "@type": "@id", "@id": "sioc:container_of" }, "has_container": { "@id": "sioc:has_container", "@type": "@id" }, "RelationDef": "dgb:RelationDef", + "Agent": "dgb:Agent", "AbstractRelationDef": "dgb:AbstractRelationDef", "RelationInstance": "dgb:RelationInstance", "RelationSchema": "dgb:RelationSchema", From 91a6eee598c314fc5a13fee98577923d025180b1 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 09:39:06 +0100 Subject: [PATCH 33/41] accountName --- apps/website/app/utils/conversion/fromJsonLd.ts | 2 +- apps/website/app/utils/conversion/ldo/dgBase.context.ts | 8 ++++---- apps/website/app/utils/conversion/ldo/dgBase.schema.ts | 2 +- apps/website/app/utils/conversion/ldo/dgBase.typings.ts | 2 +- apps/website/app/utils/conversion/shapes/dgBase.shex | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 73639b10f..89c15372f 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -410,7 +410,7 @@ const parsePersonDef = ( if (!account_local_id) return null; return { account_local_id, - name: person.name, + name: person.accountName, platform, agent_type: "person", }; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index b48021487..3011856b8 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -77,14 +77,14 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "@type", "@isCollection": true, }, - name: { - "@id": "http://rdfs.org/sioc/ns#name", + accountName: { + "@id": "http://xmlns.com/foaf/0.1/accountName", "@type": "http://www.w3.org/2001/XMLSchema#string", }, }, }, - name: { - "@id": "http://rdfs.org/sioc/ns#name", + accountName: { + "@id": "http://xmlns.com/foaf/0.1/accountName", "@type": "http://www.w3.org/2001/XMLSchema#string", }, NodeSchema: { diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index a0556b90c..3386970e1 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -54,7 +54,7 @@ export const dgBaseSchema: Schema = { }, { type: "TripleConstraint", - predicate: "http://rdfs.org/sioc/ns#name", + predicate: "http://xmlns.com/foaf/0.1/accountName", valueExpr: { type: "NodeConstraint", datatype: "http://www.w3.org/2001/XMLSchema#string", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index 983d298a4..b55ce464d 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -27,7 +27,7 @@ export interface PersonAccountProfile { type: LdSet<{ "@id": "UserAccount"; }>; - name: string; + accountName: string; } /** diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index bd5ef9753..fa65e6747 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -17,7 +17,7 @@ dgshapes:ContainerProfile { dgshapes:PersonAccountProfile { a [sioc:UserAccount]; - sioc:name xsd:string; + foaf:accountName xsd:string; } dgshapes:ItemProfile { From 0f3e37f8875781d59b9abdfde52c71340f742ef5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 12:07:12 +0100 Subject: [PATCH 34/41] multiple creators --- .../app/utils/conversion/fromJsonLd.ts | 4 +++- .../utils/conversion/ldo/dgBase.context.ts | 7 ++++++ .../app/utils/conversion/ldo/dgBase.schema.ts | 12 ++++++++++ .../utils/conversion/ldo/dgBase.typings.ts | 24 +++++++++---------- .../app/utils/conversion/shapes/dgBase.shex | 12 +++++----- .../test/integration/upsertJsonLd.test.ts | 14 +++++------ 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 89c15372f..df1f5f273 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -348,10 +348,12 @@ const parseBaseData = (data: NodeParseResult) => { const spaceInfo = data.hasContainer ? interpretId(data.hasContainer["@id"], "space_id", "space_local_id") : {}; + const creators = [...data.creator]; return { created: data.created, last_modified: data.modified, - author_local_id: data.creator["@id"], + // losing other creators for now... + author_local_id: creators[0]!["@id"], ...spaceInfo, }; }; diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index 3011856b8..b92422cb7 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -51,6 +51,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, }, }, @@ -69,6 +70,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, UserAccount: { "@id": "http://rdfs.org/sioc/ns#UserAccount", @@ -101,6 +103,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, created: { "@id": "http://purl.org/dc/terms/created", @@ -144,6 +147,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, created: { "@id": "http://purl.org/dc/terms/created", @@ -215,6 +219,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, created: { "@id": "http://purl.org/dc/terms/created", @@ -249,6 +254,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, created: { "@id": "http://purl.org/dc/terms/created", @@ -294,6 +300,7 @@ export const dgBaseContext: LdoJsonldContext = { creator: { "@id": "http://purl.org/dc/terms/creator", "@type": "@id", + "@isCollection": true, }, created: { "@id": "http://purl.org/dc/terms/created", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index 3386970e1..f9ed41a70 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -115,6 +115,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, ], }, @@ -155,6 +157,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, { type: "TripleConstraint", @@ -231,6 +235,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, { type: "TripleConstraint", @@ -317,6 +323,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, { type: "TripleConstraint", @@ -393,6 +401,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, { type: "TripleConstraint", @@ -475,6 +485,8 @@ export const dgBaseSchema: Schema = { type: "NodeConstraint", nodeKind: "iri", }, + min: 1, + max: -1, }, { type: "TripleConstraint", diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index b55ce464d..32cd0b938 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -44,9 +44,9 @@ export interface ItemProfile { }; created: string; modified?: string; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; } /** @@ -61,9 +61,9 @@ export interface NodeSchemaProfile { hasContainer?: { "@id": string; }; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; created: string; modified?: string; label: string; @@ -84,9 +84,9 @@ export interface NodeInstanceProfile { hasContainer?: { "@id": string; }; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; created: string; modified?: string; title?: string; @@ -108,9 +108,9 @@ export interface AbstractRelationDefProfile { hasContainer?: { "@id": string; }; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; created: string; modified?: string; label: string; @@ -131,9 +131,9 @@ export interface RelationDefProfile { hasContainer?: { "@id": string; }; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; created: string; modified?: string; label: string; @@ -157,9 +157,9 @@ export interface RelationInstanceProfile { hasContainer?: { "@id": string; }; - creator: { + creator: LdSet<{ "@id": string; - }; + }>; created: string; modified?: string; source: NodeInstanceProfile; diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index fa65e6747..a9ad2eba9 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -25,13 +25,13 @@ dgshapes:ItemProfile { sioc:has_container IRI ?; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; - dct:creator IRI ; + dct:creator IRI +; } dgshapes:NodeSchemaProfile { a [dgb:NodeSchema]; sioc:has_container IRI ?; - dct:creator IRI ; + dct:creator IRI +; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; @@ -42,7 +42,7 @@ dgshapes:NodeSchemaProfile { dgshapes:NodeInstanceProfile { a [dgshapes:NodeInstance]; sioc:has_container IRI ?; - dct:creator IRI ; + dct:creator IRI +; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; dct:title xsd:dateTime? ; @@ -53,7 +53,7 @@ dgshapes:AbstractRelationDefProfile { a [dgb:AbstractRelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dct:creator IRI ; + dct:creator IRI +; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; @@ -63,7 +63,7 @@ dgshapes:RelationDefProfile { a [dgshapes:RelationDef]; rdfs:subClassOf IRI *; sioc:has_container IRI ?; - dct:creator IRI ; + dct:creator IRI +; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; rdfs:label xsd:string ; @@ -75,7 +75,7 @@ dgshapes:RelationDefProfile { dgshapes:RelationInstanceProfile { a [dgb:RelationInstance]; sioc:has_container IRI ?; - dct:creator IRI ; + dct:creator IRI +; dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; dgb:source @dgshapes:NodeInstanceProfile ; diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index fa8681132..ac7fa32c1 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -41,7 +41,7 @@ const jsonLdData: JsonLdDocument = { "@graph": [ { "@id": "some:account", - name: "Some One", + accountName: "Some One", "@type": "UserAccount", }, { @@ -51,7 +51,7 @@ const jsonLdData: JsonLdDocument = { created: "2026-01-24T15:38:14.553Z", subClassOf: ["dgc:Claim", "mira:Claim"], label: "Claim", - creator: "some:account", + creator: ["some:account"], }, { "@id": "sdata:254918", @@ -64,7 +64,7 @@ const jsonLdData: JsonLdDocument = { content: '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', }, - creator: "some:account", + creator: ["some:account"], }, { "@id": "sdata:261134", @@ -72,7 +72,7 @@ const jsonLdData: JsonLdDocument = { modified: "2026-05-26T00:39:03.077Z", created: "2025-12-04T15:47:51.694Z", title: "CLM - Some supporting claim", - creator: "some:account", + creator: ["some:account"], description: { format: "text/html", content: "", @@ -92,7 +92,7 @@ const jsonLdData: JsonLdDocument = { }, ], label: "supports", - creator: "some:account", + creator: ["some:account"], }, { "@id": "sdata:131169", @@ -103,7 +103,7 @@ const jsonLdData: JsonLdDocument = { range: "sdata:131157", subClassOf: ["sdata:131164"], label: "supports", - creator: "some:account", + creator: ["some:account"], }, { "@id": "sdata:261147", @@ -114,7 +114,7 @@ const jsonLdData: JsonLdDocument = { destination: "sdata:254918", title: "[[CLM - Some supporting claim]] -supports-> [[CLM - Some base claim]]", - creator: "some:account", + creator: ["some:account"], }, ], }; From f85503d2b1bcf65ef664f86ece1f4ed11f770b41 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 16:01:14 +0100 Subject: [PATCH 35/41] indirect description; description containment --- .../utils/conversion/ldo/dgBase.context.ts | 8 +++++++ .../app/utils/conversion/ldo/dgBase.schema.ts | 23 +++++++++++++++++-- .../utils/conversion/ldo/dgBase.typings.ts | 9 +++++++- .../app/utils/conversion/shapes/dgBase.shex | 4 +++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/apps/website/app/utils/conversion/ldo/dgBase.context.ts b/apps/website/app/utils/conversion/ldo/dgBase.context.ts index b92422cb7..4ff02cb34 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.context.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.context.ts @@ -190,6 +190,10 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://rdfs.org/sioc/ns#content", "@type": "http://www.w3.org/2001/XMLSchema#string", }, + isContainedBy: { + "@id": "http://www.essepuntato.it/2008/12/pattern#isContainedBy", + "@type": "@id", + }, }, }, format: { @@ -200,6 +204,10 @@ export const dgBaseContext: LdoJsonldContext = { "@id": "http://rdfs.org/sioc/ns#content", "@type": "http://www.w3.org/2001/XMLSchema#string", }, + isContainedBy: { + "@id": "http://www.essepuntato.it/2008/12/pattern#isContainedBy", + "@type": "@id", + }, AbstractRelationDef: { "@id": "https://discoursegraphs.com/schema/dg_base#AbstractRelationDef", "@context": { diff --git a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts index f9ed41a70..5040c694f 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.schema.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.schema.ts @@ -269,8 +269,16 @@ export const dgBaseSchema: Schema = { { type: "TripleConstraint", predicate: "http://purl.org/dc/terms/description", - valueExpr: - "https://discoursegraphs.com/schema/dg_base#ContentProfile", + valueExpr: { + type: "ShapeOr", + shapeExprs: [ + "https://discoursegraphs.com/schema/dg_base#ContentProfile", + { + type: "NodeConstraint", + nodeKind: "iri", + }, + ], + }, min: 0, max: 1, }, @@ -557,6 +565,17 @@ export const dgBaseSchema: Schema = { datatype: "http://www.w3.org/2001/XMLSchema#string", }, }, + { + type: "TripleConstraint", + predicate: + "http://www.essepuntato.it/2008/12/pattern#isContainedBy", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + }, ], }, }, diff --git a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts index 32cd0b938..fab2f6fc3 100644 --- a/apps/website/app/utils/conversion/ldo/dgBase.typings.ts +++ b/apps/website/app/utils/conversion/ldo/dgBase.typings.ts @@ -90,7 +90,11 @@ export interface NodeInstanceProfile { created: string; modified?: string; title?: string; - description?: ContentProfile; + description?: + | ContentProfile + | { + "@id": string; + }; } /** @@ -177,4 +181,7 @@ export interface ContentProfile { }>; format?: string; content: string; + isContainedBy?: { + "@id": string; + }; } diff --git a/apps/website/app/utils/conversion/shapes/dgBase.shex b/apps/website/app/utils/conversion/shapes/dgBase.shex index a9ad2eba9..c0d9f9598 100644 --- a/apps/website/app/utils/conversion/shapes/dgBase.shex +++ b/apps/website/app/utils/conversion/shapes/dgBase.shex @@ -9,6 +9,7 @@ PREFIX rdf: PREFIX rdfs: PREFIX sioc: PREFIX xsd: +PREFIX po: dgshapes:ContainerProfile { a [sioc:Container]; @@ -46,7 +47,7 @@ dgshapes:NodeInstanceProfile { dct:created xsd:dateTime ; dct:modified xsd:dateTime ? ; dct:title xsd:dateTime? ; - dct:description @dgshapes:ContentProfile ? ; + dct:description (@dgshapes:ContentProfile OR IRI)? ; } dgshapes:AbstractRelationDefProfile { @@ -87,4 +88,5 @@ dgshapes:ContentProfile { a [dgshapes:Content]; dct:format xsd:string ?; sioc:content xsd:string; + po:isContainedBy IRI?; } From 7a9d00a9d78d2ae620eb9d55315916c20aba012a Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 16:36:17 +0100 Subject: [PATCH 36/41] partOf info --- apps/website/app/utils/conversion/fromJsonLd.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index df1f5f273..7a34aed82 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -426,10 +426,13 @@ const parseContent = ( if (!id) return null; const sourceFormat = DOCTYPES[content.format || ""] ?? "html"; const text = convert(content.content, sourceFormat, "obsidian"); + const partOf = content.isContainedBy; + const partOfInfo = partOf ? { part_of_local_id: partOf["@id"] } : {}; return { text, variant: "full", - scale: "document", + scale: partOf ? "block" : "document", + ...partOfInfo, ...baseInterpretId(id), ...parseBaseData(data), }; @@ -587,10 +590,11 @@ const parseLdoNode = async ( if (schemaType === nodeSchemaType) { const nodeInstance = data as NodeInstanceProfile; if (!nodeInstance.description) return null; + const contentId = nodeInstance.description["@id"]; const content = - nodeInstance.description.content !== undefined + "content" in nodeInstance.description ? nodeInstance.description - : contentById[nodeInstance.description["@id"]!]; + : contentById[nodeInstance.description["@id"]]; if (!content) return null; return await addExtraData( dataset, From 2cb68005188d5c4764ffa711edb89bdad7531bff Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 9 Jun 2026 17:13:47 +0100 Subject: [PATCH 37/41] Repair content reading --- .../app/utils/conversion/fromJsonLd.ts | 12 ++--- .../test/integration/upsertJsonLd.test.ts | 51 ++++++++++++------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/apps/website/app/utils/conversion/fromJsonLd.ts b/apps/website/app/utils/conversion/fromJsonLd.ts index 7a34aed82..868bb248c 100644 --- a/apps/website/app/utils/conversion/fromJsonLd.ts +++ b/apps/website/app/utils/conversion/fromJsonLd.ts @@ -1,5 +1,5 @@ import { namedNode } from "@ldo/rdf-utils"; -import type { NamedNode, Quad_Object, Literal } from "@rdfjs/types"; +import type { NamedNode, Quad_Object } from "@rdfjs/types"; import { parseRdf } from "@ldo/ldo"; import type { LdoDataset, ShapeType, LdoBase } from "@ldo/ldo"; import ShexJTraverser from "@ldo/traverser-shexj"; @@ -589,12 +589,10 @@ const parseLdoNode = async ( }); if (schemaType === nodeSchemaType) { const nodeInstance = data as NodeInstanceProfile; - if (!nodeInstance.description) return null; - const contentId = nodeInstance.description["@id"]; - const content = - "content" in nodeInstance.description - ? nodeInstance.description - : contentById[nodeInstance.description["@id"]]; + if (nodeInstance.description === undefined) return null; + const content = (nodeInstance.description as ContentProfile).content + ? (nodeInstance.description as ContentProfile) + : contentById[nodeInstance.description["@id"]!]; if (!content) return null; return await addExtraData( dataset, diff --git a/apps/website/test/integration/upsertJsonLd.test.ts b/apps/website/test/integration/upsertJsonLd.test.ts index ac7fa32c1..04c8e9b1c 100644 --- a/apps/website/test/integration/upsertJsonLd.test.ts +++ b/apps/website/test/integration/upsertJsonLd.test.ts @@ -1,4 +1,5 @@ import assert from "assert"; +import { inspect } from "node:util"; import { describe, it, expect, beforeAll, afterAll } from "vitest"; import { fetchOrCreateSpaceDirect, @@ -49,13 +50,13 @@ const jsonLdData: JsonLdDocument = { "@type": "NodeSchema", modified: "2026-01-24T15:38:14.553Z", created: "2026-01-24T15:38:14.553Z", - subClassOf: ["dgc:Claim", "mira:Claim"], + subClassOf: ["mira:Claim"], label: "Claim", - creator: ["some:account"], + creator: "some:account", }, { "@id": "sdata:254918", - "@type": ["sdata:131157", "dgc:Claim", "mira:Claim"], + "@type": ["sdata:131157", "mira:Claim"], modified: "2026-05-26T00:39:03.077Z", created: "2025-12-04T15:47:51.694Z", title: "CLM - Some base claim", @@ -64,19 +65,28 @@ const jsonLdData: JsonLdDocument = { content: '
\n

nodeTypeId: nodeOHkZtsR6jkJIVaNmMYGB\nnodeInstanceId: c1f02ff4-f116-452f-a490-3e0309667145

\n

publishedToGroups:

\n

That file was empty

', }, - creator: ["some:account"], + creator: "some:account", + }, + { + "@id": "https://example.com/some_document.html", + format: "text/html", + "@type": "Item", + }, + { + "@id": "https://example.com/some_document.html#someClaim", + "@type": "Item", + format: "text/plain", + isContainedBy: "https://example.com/some_document.html", + content: "Some claim contained in a broader document", }, { "@id": "sdata:261134", - "@type": ["sdata:131157", "dgc:Claim", "mira:Claim"], + "@type": ["sdata:131157", "mira:Claim"], modified: "2026-05-26T00:39:03.077Z", created: "2025-12-04T15:47:51.694Z", title: "CLM - Some supporting claim", - creator: ["some:account"], - description: { - format: "text/html", - content: "", - }, + creator: "some:account", + description: "https://example.com/some_document.html#someClaim", }, { "@id": "sdata:131164", @@ -85,6 +95,7 @@ const jsonLdData: JsonLdDocument = { created: "2026-01-24T15:38:14.553Z", subClassOf: [ "dgb:RelationInstance", + "mira:supports", { "@type": "owl:Restriction", onProperty: "rdf:predicate", @@ -92,7 +103,7 @@ const jsonLdData: JsonLdDocument = { }, ], label: "supports", - creator: ["some:account"], + creator: "some:account", }, { "@id": "sdata:131169", @@ -103,18 +114,18 @@ const jsonLdData: JsonLdDocument = { range: "sdata:131157", subClassOf: ["sdata:131164"], label: "supports", - creator: ["some:account"], + creator: "some:account", }, { "@id": "sdata:261147", - "@type": "sdata:131164", + "@type": ["sdata:131164", "mira:supports"], modified: "2026-06-03T10:13:09.101Z", created: "2026-06-03T10:13:09.101Z", - source: "sdata:261134", - destination: "sdata:254918", + source: "sdata:254918", + destination: "sdata:261134", title: "[[CLM - Some supporting claim]] -supports-> [[CLM - Some base claim]]", - creator: ["some:account"], + creator: "some:account", }, ], }; @@ -162,10 +173,14 @@ describe("Upsert of JSON-LD data", { tags: ["database"] }, () => { it("Upserts the data", async () => { const client = await signedInClient(spaceId); const converted = await parseJsonLdAsInput(client, jsonLdData, spaceId); - console.log(converted); + console.log(inspect(converted, { depth: null })); const response = await populate(client, jsonLdData, spaceId); console.log(response); - assert(response.length === (jsonLdData["@graph"] as Array).length); + const originalArray = jsonLdData["@graph"] as Array>; + assert( + response.length === + originalArray.filter((c) => c["@type"] !== "Item").length, + ); assert(Math.min(...response) > 0); }); }); From 1718ec99fa674aff02dbc30d859f033b533d5254 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Wed, 10 Jun 2026 16:39:23 +0100 Subject: [PATCH 38/41] update mira jsonld --- .../app/utils/conversion/shacl/mira.shacl | 605 ++++++++++++++++++ .../app/utils/conversion/validation.ts | 1 + apps/website/public/schema/mira.jsonld | 27 +- 3 files changed, 620 insertions(+), 13 deletions(-) create mode 100644 apps/website/app/utils/conversion/shacl/mira.shacl create mode 100644 apps/website/app/utils/conversion/validation.ts diff --git a/apps/website/app/utils/conversion/shacl/mira.shacl b/apps/website/app/utils/conversion/shacl/mira.shacl new file mode 100644 index 000000000..8f94ba10f --- /dev/null +++ b/apps/website/app/utils/conversion/shacl/mira.shacl @@ -0,0 +1,605 @@ +@prefix rdf: . +@prefix wgs: . +@prefix brick: . +@prefix geo: . +@prefix rdfs: . +@prefix skos: . +@prefix xml: . +@prefix mira: . +@prefix qb: . +@prefix xsd: . +@prefix dc: . +@prefix owl: . +@prefix doap: . +@prefix prof: . +@prefix dcmitype: . +@prefix odrl: . +@prefix time: . +@prefix sh: . +@prefix vann: . +@prefix csvw: . +@prefix dcat: . +@prefix foaf: . +@prefix prov: . +@prefix sosa: . +@prefix dcterms: . +@prefix org: . +@prefix ssn: . +@prefix dcam: . +@prefix void: . +@prefix schema: . + a sh:NodeShape ; + rdfs:comment "Some research source document that reports/generates evidence, like a book, conference paper, or journal article" ; + rdfs:label "Source document" ; + sh:closed true ; + sh:ignoredProperties _:c14n92 ; + sh:property _:c14n15 , _:c14n28 , _:c14n33 , _:c14n40 , _:c14n44 , _:c14n63 , _:c14n71 ; + sh:targetClass . +mira:Argument a sh:NodeShape ; + rdfs:comment "A node that can support or oppose another node" ; + sh:closed false ; + sh:ignoredProperties _:c14n27 ; + sh:property _:c14n52 , _:c14n82 ; + sh:targetClass mira:Argument . +mira:Claim a sh:NodeShape ; + rdfs:comment "Atomic, generalized assertions about the world that (propose to) answer research questions" ; + sh:closed true ; + sh:ignoredProperties _:c14n68 ; + sh:property _:c14n103 , _:c14n29 , _:c14n36 , _:c14n51 , _:c14n59 , _:c14n64 , _:c14n74 ; + sh:targetClass mira:Claim . +mira:Evidence a sh:NodeShape ; + rdfs:comment "A specific empirical observation from a particular application of a research method" ; + sh:closed true ; + sh:ignoredProperties _:c14n76 ; + sh:property _:c14n101 , _:c14n106 , _:c14n14 , _:c14n32 , _:c14n39 , _:c14n50 , _:c14n62 ; + sh:targetClass mira:Evidence . +mira:Protocol a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n23 ; + sh:property _:c14n17 , _:c14n60 , _:c14n66 , _:c14n70 , _:c14n84 , _:c14n88 , _:c14n9 ; + sh:targetClass mira:Protocol . +mira:Question a sh:NodeShape ; + rdfs:comment "Scientific unknowns that we want to make known, and are addressable by the systematic application of research methods" ; + sh:closed true ; + sh:ignoredProperties _:c14n20 ; + sh:property _:c14n104 , _:c14n21 , _:c14n24 , _:c14n54 , _:c14n55 , _:c14n57 , _:c14n86 ; + sh:targetClass mira:Question . +mira:Request a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n26 ; + sh:property _:c14n0 , _:c14n19 , _:c14n35 , _:c14n41 , _:c14n80 , _:c14n94 , _:c14n96 ; + sh:targetClass mira:Request . +mira:Study a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n49 ; + sh:property _:c14n12 , _:c14n13 , _:c14n22 , _:c14n7 , _:c14n75 , _:c14n87 , _:c14n98 ; + sh:targetClass mira:Study . + a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n58 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n6 ; + sh:property _:c14n16 , _:c14n42 , _:c14n69 , _:c14n81 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n2 ; + sh:property _:c14n37 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n8 ; + sh:targetClass . +prov:Activity a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n47 ; + sh:targetClass prov:Activity . +prov:Entity a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n73 ; + sh:ignoredProperties _:c14n73 ; + sh:targetClass prov:Entity . +foaf:Agent a sh:NodeShape ; + sh:closed false ; + sh:ignoredProperties _:c14n61 ; + sh:targetClass foaf:Agent . + a sh:NodeShape ; + sh:closed false ; + sh:ignoredProperties _:c14n34 ; + sh:property _:c14n105 , _:c14n25 , _:c14n56 , _:c14n77 , _:c14n89 , _:c14n95 , _:c14n99 ; + sh:targetClass . + a sh:NodeShape ; + rdfs:comment "An agent engaging in an activity, and posting MIRA nodes." ; + sh:closed true ; + sh:ignoredProperties _:c14n100 ; + sh:property _:c14n1 , _:c14n4 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed false ; + sh:ignoredProperties _:c14n91 ; + sh:property _:c14n11 , _:c14n3 , _:c14n31 , _:c14n48 , _:c14n67 , _:c14n79 , _:c14n85 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed false ; + sh:ignoredProperties _:c14n83 ; + sh:property _:c14n10 , _:c14n30 , _:c14n38 , _:c14n43 , _:c14n46 , _:c14n53 , _:c14n65 , _:c14n78 , _:c14n90 ; + sh:targetClass . + a sh:NodeShape ; + sh:closed true ; + sh:ignoredProperties _:c14n45 ; + sh:targetClass . +_:c14n0 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n1 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 1 ; + sh:path foaf:account . +_:c14n10 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 2 ; + sh:path dcterms:created . +_:c14n100 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n101 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n102 rdf:first dcterms:format ; + rdf:rest rdf:nil . +_:c14n103 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n104 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n105 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n106 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n107 rdf:first dcterms:modified ; + rdf:rest _:c14n108 . +_:c14n108 rdf:first dcterms:created ; + rdf:rest _:c14n102 . +_:c14n109 rdf:first dcterms:modified ; + rdf:rest _:c14n110 . +_:c14n11 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n110 rdf:first dcterms:created ; + rdf:rest _:c14n111 . +_:c14n111 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n112 rdf:first "observationBase" ; + rdf:rest rdf:nil . +_:c14n113 rdf:first "RelationDef" ; + rdf:rest _:c14n112 . +_:c14n114 rdf:first "observationBase" ; + rdf:rest rdf:nil . +_:c14n115 rdf:first "RelationDef" ; + rdf:rest _:c14n114 . +_:c14n116 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n12 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n13 sh:datatype xsd:dateTime . +_:c14n13 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n14 sh:class . +_:c14n14 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n15 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n16 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:format . +_:c14n17 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n18 rdf:first ; + rdf:rest _:c14n93 . +_:c14n19 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n2 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n20 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n21 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n22 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n23 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n24 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n25 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n26 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n27 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n28 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n29 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n3 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n30 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 0 ; + sh:path rdfs:domain . +_:c14n31 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n32 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n33 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n34 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n35 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n36 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n37 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path foaf:accountName . +_:c14n38 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 5 ; + sh:path dcterms:description . +_:c14n39 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n4 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path foaf:name . +_:c14n40 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n41 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n42 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:creator . +_:c14n43 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 7 ; + sh:path dcterms:format . +_:c14n44 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n45 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n46 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 3 ; + sh:path dcterms:modified . +_:c14n47 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n48 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n49 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n5 rdf:first dcterms:creator ; + rdf:rest _:c14n107 . +_:c14n50 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n51 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n52 sh:class mira:Claim ; + sh:in _:c14n115 ; + sh:name "Opposes" ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 1 ; + sh:path mira:opposes . +_:c14n53 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 8 ; + sh:path . +_:c14n54 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n55 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n56 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n57 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n58 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n59 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n6 rdf:first dcterms:description ; + rdf:rest _:c14n109 . +_:c14n60 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n61 rdf:first foaf:account ; + rdf:rest _:c14n97 . +_:c14n62 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n63 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n64 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 3 ; + sh:path dcterms:description . +_:c14n65 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 1 ; + sh:path rdfs:range . +_:c14n66 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n67 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n68 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n69 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path . +_:c14n7 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n70 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n71 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n72 rdf:first dcterms:description ; + rdf:rest _:c14n18 . +_:c14n73 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n74 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n75 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n76 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n77 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n78 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 6 ; + sh:order 6 ; + sh:path . +_:c14n79 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n8 rdf:first ; + rdf:rest _:c14n72 . +_:c14n80 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n81 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path . +_:c14n82 sh:class mira:Claim ; + sh:in _:c14n113 ; + sh:name "Supports" ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 0 ; + sh:path mira:supports . +_:c14n83 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n84 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . +_:c14n85 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n86 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n87 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 2 ; + sh:path dcterms:creator . +_:c14n88 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n89 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n9 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 0 ; + sh:path dcterms:created . +_:c14n90 sh:class ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path dcterms:creator . +_:c14n91 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n92 rdf:first rdf:type ; + rdf:rest rdf:nil . +_:c14n93 rdf:first rdf:type ; + rdf:rest _:c14n5 . +_:c14n94 sh:class ; + sh:maxCount 1 ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:order 4 ; + sh:path . +_:c14n95 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n96 sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 1 ; + sh:path dcterms:modified . +_:c14n97 rdf:first foaf:name ; + rdf:rest _:c14n116 . +_:c14n98 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 5 ; + sh:path dcterms:format . +_:c14n99 sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:nodeKind sh:Literal ; + sh:order 6 ; + sh:path . + diff --git a/apps/website/app/utils/conversion/validation.ts b/apps/website/app/utils/conversion/validation.ts new file mode 100644 index 000000000..c2f787d87 --- /dev/null +++ b/apps/website/app/utils/conversion/validation.ts @@ -0,0 +1 @@ +import { Validator } from "shacl-engine"; diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index 753328e47..6251d358e 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -49,31 +49,32 @@ "destination": { "@id": "dgb:destination", "@type": "@id" }, "textRefersToNode": "dgb:textRefersToNode", - "SourceDocument": "dgc:SourceDocument", - "Argument": "dgc:Argument", + "SourceDocument": "mira:SourceDocument", + "Argument": "mira:Argument", "observationStatement": { - "@id": "dgc:observationStatement", + "@id": "mira:observationStatement", "@type": "@id" }, "observationOriginActivity": { - "@id": "dgc:observationOriginActivity", + "@id": "mira:observationOriginActivity", "@type": "@id" }, - "observationBase": { "@id": "dgc:observationBase", "@type": "@id" }, - "sourceDocument": { "@id": "dgc:sourceDocument", "@type": "@id" }, - "describesActivity": { "@id": "dgc:describesActivity", "@type": "@id" }, - "opposes": { "@id": "dgc:opposes", "@type": "@id" }, - "opposedBy": { "@id": "dgc:opposedBy", "@type": "@id" }, - "supports": { "@id": "dgc:supports", "@type": "@id" }, - "supportedBy": { "@id": "dgc:supportedBy", "@type": "@id" }, - "addresses": { "@id": "dgc:addresses", "@type": "@id" }, - "addressedBy": { "@id": "dgc:addressedBy", "@type": "@id" }, + "observationBase": { "@id": "mira:observationBase", "@type": "@id" }, + "sourceDocument": { "@id": "mira:sourceDocument", "@type": "@id" }, + "describesActivity": { "@id": "mira:describesActivity", "@type": "@id" }, + "opposes": { "@id": "mira:opposes", "@type": "@id" }, + "opposedBy": { "@id": "mira:opposedBy", "@type": "@id" }, + "supports": { "@id": "mira:supports", "@type": "@id" }, + "supportedBy": { "@id": "mira:supportedBy", "@type": "@id" }, + "addresses": { "@id": "mira:addresses", "@type": "@id" }, + "addressedBy": { "@id": "mira:addressedBy", "@type": "@id" }, "Question": "mira:Question", "Claim": "mira:Claim", "Evidence": "mira:Evidence", "Request": "mira:Request", "Protocol": "mira:Protocol", + "Item": "sioc:Item", "follows": { "@id": "mira:follows", "@type": "@id" }, "grounds": { "@id": "mira:grounds", "@type": "@id" }, "is_grounded_in": { "@id": "mira:is_grounded_in", "@type": "@id" }, From a9fa48d51e0ca518bd04de543b7fe46a58918e44 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Wed, 10 Jun 2026 16:51:16 +0100 Subject: [PATCH 39/41] commited by mistake --- apps/website/app/utils/conversion/validation.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/website/app/utils/conversion/validation.ts diff --git a/apps/website/app/utils/conversion/validation.ts b/apps/website/app/utils/conversion/validation.ts deleted file mode 100644 index c2f787d87..000000000 --- a/apps/website/app/utils/conversion/validation.ts +++ /dev/null @@ -1 +0,0 @@ -import { Validator } from "shacl-engine"; From de4f8c78e0068eb7e0b1a2cbe730c4b8f125cab7 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 11 Jun 2026 14:10:41 +0100 Subject: [PATCH 40/41] more jsonld adjustments --- apps/website/public/schema/mira.jsonld | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index 6251d358e..25f18e37c 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -15,7 +15,7 @@ "domain": { "@id": "rdfs:domain", "@type": "@id" }, "range": { "@id": "rdfs:range", "@type": "@id" }, "label": "rdfs:label", - "inverseOf": "owl:inverseOf", + "inverseOf": { "@type": "@id", "owl:inverseOf"}, "onProperty": "owl:onProperty", "sameAs": { "@id": "owl:sameAs", "@type": "@id" }, "hasValue": "owl:hasValue", @@ -74,6 +74,8 @@ "Evidence": "mira:Evidence", "Request": "mira:Request", "Protocol": "mira:Protocol", + "Study": "mira:Protocol", + "Item": "sioc:Item", "follows": { "@id": "mira:follows", "@type": "@id" }, "grounds": { "@id": "mira:grounds", "@type": "@id" }, From 02b828e687f9bb76ff5a7fa57b23a3c4b012b9ad Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Thu, 11 Jun 2026 22:24:08 +0100 Subject: [PATCH 41/41] more jsonld adjustments --- apps/website/public/schema/mira.jsonld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/website/public/schema/mira.jsonld b/apps/website/public/schema/mira.jsonld index 25f18e37c..ea01c34d6 100644 --- a/apps/website/public/schema/mira.jsonld +++ b/apps/website/public/schema/mira.jsonld @@ -15,7 +15,7 @@ "domain": { "@id": "rdfs:domain", "@type": "@id" }, "range": { "@id": "rdfs:range", "@type": "@id" }, "label": "rdfs:label", - "inverseOf": { "@type": "@id", "owl:inverseOf"}, + "inverseOf": { "@type": "@id", "@id": "owl:inverseOf"}, "onProperty": "owl:onProperty", "sameAs": { "@id": "owl:sameAs", "@type": "@id" }, "hasValue": "owl:hasValue",