Skip to content

Commit 849ec6a

Browse files
committed
eng-2017-add-converters-for-schemas
1 parent d54f0c7 commit 849ec6a

1 file changed

Lines changed: 136 additions & 0 deletions

File tree

packages/database/src/lib/crossAppConverters.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import {
55
InlineCrossAppContent,
66
CrossAppBase,
77
CrossAppNode,
8+
CrossAppNodeSchema,
9+
CrossAppRelationTypeSchema,
10+
CrossAppRelationTripleSchema,
811
} from "../crossAppContracts";
912
import { LocalContentDataInput, LocalConceptDataInput } from "../inputTypes";
1013
import { Enums, CompositeTypes } from "../dbTypes";
@@ -39,6 +42,50 @@ const decodeRef = <DbVarName extends string, LocalVarName extends string>(
3942
return decodeLocalRef(ref, localVarName);
4043
};
4144

45+
const decodeRefOrInline = <
46+
InlineType extends object,
47+
DbType extends object,
48+
DbVarName extends string,
49+
LocalVarName extends string,
50+
InlineVarName extends string,
51+
>({
52+
data,
53+
dbVarName,
54+
localVarName,
55+
inlineVarName,
56+
encoder,
57+
}: {
58+
data: InlineType | Ref | undefined;
59+
dbVarName: DbVarName;
60+
localVarName: LocalVarName;
61+
inlineVarName: InlineVarName;
62+
encoder: (inlineData: InlineType) => DbType;
63+
}):
64+
| Record<DbVarName, number>
65+
| Record<LocalVarName, string>
66+
| Record<InlineVarName, DbType>
67+
| Record<string, never> => {
68+
if (data === undefined) return {};
69+
if (Object.keys(data).length === 0) return {};
70+
const ref = data as Ref;
71+
if ("dbId" in ref) {
72+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
73+
const { dbId, ...extraData } = ref;
74+
if (Object.keys(extraData).length === 0)
75+
return decodeRef(ref, dbVarName, localVarName);
76+
}
77+
if ("localId" in ref) {
78+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
79+
const { localId, ...extraData } = ref;
80+
if (Object.keys(extraData).length === ("space" in ref ? 1 : 0))
81+
return decodeRef(ref, dbVarName, localVarName);
82+
}
83+
// assume not a simple ref
84+
return {
85+
[inlineVarName]: encoder(data as InlineType),
86+
} as Record<InlineVarName, DbType>;
87+
};
88+
4289
const crossAppEmbeddingToDbEmbedding = (
4390
embedding: CrossAppEmbedding | undefined,
4491
): InlineEmbeddingInput | undefined =>
@@ -109,3 +156,92 @@ export const crossAppNodeToDbConcept = (
109156
last_modified: node.modifiedAt?.toISOString(),
110157
});
111158
};
159+
160+
export const crossAppNodeSchemaToDbConcept = (
161+
node: CrossAppNodeSchema,
162+
): LocalConceptDataInput => {
163+
const literalInfo = filterUndefined({
164+
template: node.templateTitle,
165+
templateContent: node.template,
166+
});
167+
return filterUndefined<LocalConceptDataInput>({
168+
...decodeLocalRef(node, "source_local_id"),
169+
name: node.label,
170+
...decodeRef(node.author, "author_id", "author_local_id"),
171+
is_schema: true,
172+
literal_content:
173+
Object.keys(literalInfo).length > 0 ? literalInfo : undefined,
174+
created: node.createdAt?.toISOString(),
175+
last_modified: node.modifiedAt?.toISOString(),
176+
});
177+
};
178+
179+
export const crossAppRelationTypeSchemaToDbConcept = (
180+
node: CrossAppRelationTypeSchema,
181+
): LocalConceptDataInput => {
182+
return filterUndefined<LocalConceptDataInput>({
183+
...decodeLocalRef(node, "source_local_id"),
184+
name: node.label,
185+
...decodeRef(node.author, "author_id", "author_local_id"),
186+
is_schema: true,
187+
literal_content: {
188+
roles: ["source", "destination"],
189+
label: node.label,
190+
complement: node.complement,
191+
},
192+
created: node.createdAt?.toISOString(),
193+
last_modified: node.modifiedAt?.toISOString(),
194+
});
195+
};
196+
197+
export const crossAppRelationTripleSchemaToDbConcept = ({
198+
node,
199+
sourceNodeSchema,
200+
destinationNodeSchema,
201+
relationType,
202+
}: {
203+
node: CrossAppRelationTripleSchema;
204+
sourceNodeSchema: CrossAppNodeSchema;
205+
destinationNodeSchema: CrossAppNodeSchema;
206+
relationType?: CrossAppRelationTypeSchema;
207+
}): LocalConceptDataInput | undefined => {
208+
// relationType must be provided if relation-based triple.
209+
if (!("label" in node) && relationType === undefined) return undefined;
210+
const label = "label" in node ? node.label : relationType!.label;
211+
const complement =
212+
"complement" in node ? node.complement : relationType!.complement;
213+
214+
const relData = {
215+
...decodeRef(
216+
"relation" in node ? node.relation : undefined,
217+
"relation_type",
218+
"relation_type_local_id",
219+
),
220+
...decodeRef(node.sourceType, "source", "source_local_id"),
221+
...decodeRef(node.destinationType, "destination", "destination_local_id"),
222+
};
223+
const refLocalIds = Object.fromEntries(
224+
Object.entries(relData)
225+
.filter(([k]) => k.endsWith("_local_id"))
226+
.map(([k, v]) => [k.substring(0, k.length - 9), v]),
227+
) as Record<string, string>;
228+
const refIds = Object.fromEntries(
229+
Object.entries(relData).filter(([k]) => !k.endsWith("_local_id")),
230+
) as Record<string, number>;
231+
return filterUndefined<LocalConceptDataInput>({
232+
...decodeLocalRef(node, "source_local_id"),
233+
name: `${sourceNodeSchema.label} -${label}-> ${destinationNodeSchema.label}`,
234+
...decodeRef(node.author, "author_id", "author_local_id"),
235+
is_schema: true,
236+
literal_content: filterUndefined({
237+
roles: ["source", "destination"],
238+
label,
239+
complement,
240+
}),
241+
local_reference_content:
242+
Object.keys(refLocalIds).length > 0 ? refLocalIds : undefined,
243+
reference_content: Object.keys(refIds).length > 0 ? refIds : undefined,
244+
created: node.createdAt?.toISOString(),
245+
last_modified: node.modifiedAt?.toISOString(),
246+
});
247+
};

0 commit comments

Comments
 (0)