@manta-eu/client 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/graphql.d.ts +109 -1
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +66 -0
- package/dist/generated/graphql.js.map +1 -1
- package/dist/shared/action-document.d.ts +13 -4
- package/dist/shared/action-document.d.ts.map +1 -1
- package/dist/shared/action-document.js +55 -24
- package/dist/shared/action-document.js.map +1 -1
- package/dist/shared/email.d.ts.map +1 -1
- package/dist/shared/email.js +19 -17
- package/dist/shared/email.js.map +1 -1
- package/package.json +5 -7
- package/src/generated/graphql.ts +235 -4
- package/src/shared/action-document.ts +88 -35
- package/src/shared/email.ts +23 -17
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { isPresent } from "@manta-eu/lib/present";
|
|
2
|
+
import { owlNothingIri } from "@manta-eu/rdf-lib/namespaces";
|
|
3
|
+
import { encodeEntity, type Identity, type Lens, type Property, type Schema, type SchemaInterface } from "ldkit";
|
|
4
|
+
import { rdf, xsd } from "ldkit/namespaces";
|
|
5
|
+
import { groupBy, uniq, uniqBy } from "ramda";
|
|
6
|
+
import type { GQLExecuteActionUpdateInput } from "../generated/graphql";
|
|
4
7
|
|
|
5
8
|
export type DocumentTerm = { value: string; termType: string };
|
|
6
9
|
|
|
@@ -10,47 +13,97 @@ export type DocumentQuad = {
|
|
|
10
13
|
object: DocumentTerm & { datatype?: { value: string }; language?: string };
|
|
11
14
|
};
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
type InsertEntity<S extends Schema> = Parameters<Lens<S>["insert"]>[number];
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
export type ActionSchema = Schema & { "@type": string };
|
|
19
|
+
|
|
20
|
+
export type Writable<T> = T extends readonly (infer E)[]
|
|
21
|
+
? Writable<E>[]
|
|
22
|
+
: T extends Record<string, unknown>
|
|
23
|
+
? { [K in keyof T]?: Writable<T[K]> }
|
|
24
|
+
: T;
|
|
25
|
+
|
|
26
|
+
export type ActionEntity<S extends Schema> = Identity &
|
|
27
|
+
(string extends keyof S ? Record<string, unknown> : Writable<Omit<SchemaInterface<S>, "$id">>);
|
|
28
|
+
|
|
29
|
+
export type ActionInput = GQLExecuteActionUpdateInput;
|
|
30
|
+
|
|
31
|
+
const termKey = (term: DocumentTerm): string => (term.termType === "BlankNode" ? `_:${term.value}` : term.value);
|
|
32
|
+
|
|
33
|
+
const objectKey = ({ object }: DocumentQuad): string =>
|
|
34
|
+
`${termKey(object)} ${object.datatype?.value ?? ""} ${object.language ?? ""}`;
|
|
35
|
+
|
|
36
|
+
const oneOrMany = (values: readonly unknown[]): unknown => (values.length === 1 ? values[0] : values);
|
|
37
|
+
|
|
38
|
+
function literal(object: DocumentQuad["object"]): unknown {
|
|
39
|
+
const datatype = object.datatype?.value ?? xsd.string;
|
|
40
|
+
|
|
41
|
+
if (isPresent(object.language)) return { "@value": object.value, "@language": object.language };
|
|
42
|
+
if (datatype === xsd.string) return object.value;
|
|
43
|
+
return { "@value": object.value, "@type": datatype };
|
|
18
44
|
}
|
|
19
45
|
|
|
20
|
-
function
|
|
21
|
-
const { subject
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
value: object.value,
|
|
31
|
-
language: object.language,
|
|
32
|
-
datatype: { value: object.datatype?.value ?? xsd.string },
|
|
33
|
-
}
|
|
34
|
-
: jsonldTerm(object),
|
|
35
|
-
graph: { termType: "DefaultGraph", value: "" },
|
|
46
|
+
export function documentFromQuads(quads: readonly DocumentQuad[], subjectIri: string): Record<string, unknown> {
|
|
47
|
+
const described = quads.filter(({ subject }) => subject.value === subjectIri || subject.termType === "BlankNode");
|
|
48
|
+
const bySubject = groupBy((quad: DocumentQuad) => termKey(quad.subject), described);
|
|
49
|
+
const blankObjects = described.flatMap(({ object }) => (object.termType === "BlankNode" ? [termKey(object)] : []));
|
|
50
|
+
const shared = new Set(blankObjects.filter((key, index) => blankObjects.indexOf(key) !== index));
|
|
51
|
+
const labels = new Map<string, string>();
|
|
52
|
+
|
|
53
|
+
const label = (key: string): string => {
|
|
54
|
+
if (!labels.has(key)) labels.set(key, `_:b${labels.size}`);
|
|
55
|
+
return labels.get(key) ?? key;
|
|
36
56
|
};
|
|
57
|
+
|
|
58
|
+
const value = (object: DocumentQuad["object"], path: readonly string[]): unknown => {
|
|
59
|
+
const key = termKey(object);
|
|
60
|
+
|
|
61
|
+
if (object.termType === "Literal") return literal(object);
|
|
62
|
+
if (object.termType !== "BlankNode") return { "@id": key };
|
|
63
|
+
if (path.includes(key)) return { "@id": label(key) };
|
|
64
|
+
return node(key, [...path, key]);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const node = (key: string, path: readonly string[]): Record<string, unknown> => {
|
|
68
|
+
const own = bySubject[key] ?? [];
|
|
69
|
+
const types = own.filter(({ predicate }) => predicate.value === rdf.type).map(({ object }) => termKey(object));
|
|
70
|
+
const others = own.filter(({ predicate }) => predicate.value !== rdf.type);
|
|
71
|
+
const byPredicate = groupBy((quad: DocumentQuad) => quad.predicate.value, others);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
...(shared.has(key) && { "@id": label(key) }),
|
|
75
|
+
...(isPresent(types) && { "@type": oneOrMany(uniq(types)) }),
|
|
76
|
+
...Object.fromEntries(
|
|
77
|
+
Object.entries(byPredicate).map(([predicate, values = []]) => [
|
|
78
|
+
predicate,
|
|
79
|
+
oneOrMany(uniqBy(objectKey, values).map(({ object }) => value(object, path))),
|
|
80
|
+
]),
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return { "@id": subjectIri, ...node(subjectIri, [subjectIri]) };
|
|
37
86
|
}
|
|
38
87
|
|
|
39
|
-
export
|
|
40
|
-
quads
|
|
41
|
-
|
|
42
|
-
)
|
|
43
|
-
const described = quads.filter(({ subject }) => subject.value === subjectIri || subject.termType === "BlankNode");
|
|
44
|
-
const flattened = await jsonld.fromRDF(described.map(jsonldQuad));
|
|
88
|
+
export function entityActionDocument<S extends Schema>(schema: S, entity: ActionEntity<S>): Record<string, unknown> {
|
|
89
|
+
const quads = encodeEntity(schema, entity as unknown as InsertEntity<S>).filter(
|
|
90
|
+
(quad) => quad.object.termType !== "Variable",
|
|
91
|
+
);
|
|
45
92
|
|
|
46
|
-
return
|
|
93
|
+
return documentFromQuads(quads, entity.$id);
|
|
47
94
|
}
|
|
48
95
|
|
|
49
|
-
|
|
96
|
+
const propertyIri = (definition: Property | string | readonly string[] | undefined): string =>
|
|
97
|
+
typeof definition === "object" && "@id" in definition ? definition["@id"] : String(definition);
|
|
98
|
+
|
|
99
|
+
export function entityActionInput<S extends ActionSchema>(
|
|
50
100
|
schema: S,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
101
|
+
actionShape: string,
|
|
102
|
+
entity: ActionEntity<S>,
|
|
103
|
+
cleared: readonly (Exclude<keyof S, "@type"> & string)[] = [],
|
|
104
|
+
): ActionInput {
|
|
105
|
+
const document = entityActionDocument(schema, entity);
|
|
106
|
+
const nothing = Object.fromEntries(cleared.map((key) => [propertyIri(schema[key]), { "@id": owlNothingIri }]));
|
|
54
107
|
|
|
55
|
-
return
|
|
108
|
+
return { subjectIri: entity.$id, rdfType: schema["@type"], actionShape, properties: { ...document, ...nothing } };
|
|
56
109
|
}
|
package/src/shared/email.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NcoEmailAddressSchema } from "@manta-eu/ldo/schemas/nco";
|
|
2
|
+
import { NmoEmailSchema } from "@manta-eu/ldo/schemas/nmo";
|
|
2
3
|
import { isPresent } from "@manta-eu/lib/present";
|
|
4
|
+
import type { Schema } from "ldkit";
|
|
3
5
|
import { ExecuteAgentActionAdditionDocument, type GQLExecuteAgentActionAdditionMutation } from "../generated/graphql";
|
|
6
|
+
import { entityActionInput } from "./action-document";
|
|
4
7
|
|
|
5
8
|
export type EmailGraphql = (document: string, variables: Record<string, unknown>) => Promise<unknown>;
|
|
6
9
|
|
|
@@ -16,22 +19,25 @@ export type RenderedEmail = {
|
|
|
16
19
|
|
|
17
20
|
export type EmailStart = { ok: true; plan: string } | { ok: false; error: string };
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
const renderedEmailSchema = (terms: RealmEmailTerms) =>
|
|
23
|
+
({
|
|
24
|
+
"@type": NmoEmailSchema["@type"],
|
|
25
|
+
from: { "@id": NmoEmailSchema.messageFrom["@id"], "@schema": NcoEmailAddressSchema },
|
|
26
|
+
to: { "@id": NmoEmailSchema.emailTo["@id"], "@schema": NcoEmailAddressSchema },
|
|
27
|
+
subject: NmoEmailSchema.messageSubject,
|
|
28
|
+
contentMimeType: NmoEmailSchema.contentMimeType,
|
|
29
|
+
renderedFrom: { ...NmoEmailSchema.renderedFrom, "@id": terms.renderedFrom },
|
|
30
|
+
}) as const satisfies Schema;
|
|
31
|
+
|
|
32
|
+
const renderedEmailAddition = (terms: RealmEmailTerms, email: RenderedEmail) =>
|
|
33
|
+
entityActionInput(renderedEmailSchema(terms), terms.emailMessageShape, {
|
|
34
|
+
$id: email.subjectIri,
|
|
35
|
+
from: { emailAddress: email.from },
|
|
36
|
+
to: { emailAddress: email.to },
|
|
37
|
+
subject: email.subject,
|
|
38
|
+
contentMimeType: "text/html",
|
|
39
|
+
renderedFrom: email.renderedFrom,
|
|
40
|
+
});
|
|
35
41
|
|
|
36
42
|
export async function startRenderedEmail(
|
|
37
43
|
graphql: EmailGraphql,
|