@eightyfourthousand/client-graphql 2026.3.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/codegen.ts +34 -0
- package/package.json +25 -0
- package/project.json +21 -0
- package/src/index.ts +79 -0
- package/src/lib/client-ssr.ts +44 -0
- package/src/lib/client.ts +58 -0
- package/src/lib/config.ts +21 -0
- package/src/lib/functions/get-bibliography-entry.ts +40 -0
- package/src/lib/functions/get-glossary-entry.ts +136 -0
- package/src/lib/functions/get-glossary-instance.ts +48 -0
- package/src/lib/functions/get-glossary-terms.ts +44 -0
- package/src/lib/functions/get-passage.ts +78 -0
- package/src/lib/functions/get-term-passages.ts +53 -0
- package/src/lib/functions/get-translation-blocks-around.ts +131 -0
- package/src/lib/functions/get-translation-blocks.ts +160 -0
- package/src/lib/functions/get-translation-imprint.ts +114 -0
- package/src/lib/functions/get-translation-metadata.ts +99 -0
- package/src/lib/functions/get-translation-passages-around.ts +153 -0
- package/src/lib/functions/get-translation-passages.ts +168 -0
- package/src/lib/functions/get-translation-titles.ts +55 -0
- package/src/lib/functions/get-translation-toc.ts +115 -0
- package/src/lib/functions/get-translation-uuids.ts +63 -0
- package/src/lib/functions/get-translations-metadata.ts +81 -0
- package/src/lib/functions/get-work-bibliography.ts +47 -0
- package/src/lib/functions/get-work-folios.ts +52 -0
- package/src/lib/functions/get-work-glossary-terms-around.ts +126 -0
- package/src/lib/functions/get-work-glossary-terms.ts +150 -0
- package/src/lib/functions/get-work-glossary.ts +54 -0
- package/src/lib/functions/get-works.ts +111 -0
- package/src/lib/functions/has-permission.ts +38 -0
- package/src/lib/functions/index.ts +33 -0
- package/src/lib/functions/save-passages.ts +76 -0
- package/src/lib/generated/graphql.ts +1318 -0
- package/src/lib/graphql/fragments/alignment.graphql +7 -0
- package/src/lib/graphql/fragments/annotation.graphql +7 -0
- package/src/lib/graphql/fragments/imprint.graphql +34 -0
- package/src/lib/graphql/fragments/passage.graphql +29 -0
- package/src/lib/graphql/fragments/title.graphql +6 -0
- package/src/lib/graphql/fragments/toc.graphql +40 -0
- package/src/lib/graphql/fragments/work.graphql +10 -0
- package/src/lib/graphql/queries/passages.graphql +116 -0
- package/src/lib/graphql/queries/work.graphql +38 -0
- package/src/lib/graphql/queries/works.graphql +23 -0
- package/src/lib/mappers/alignment.ts +34 -0
- package/src/lib/mappers/annotation.ts +204 -0
- package/src/lib/mappers/imprint.ts +79 -0
- package/src/lib/mappers/index.ts +7 -0
- package/src/lib/mappers/passage.ts +80 -0
- package/src/lib/mappers/title.ts +35 -0
- package/src/lib/mappers/toc.ts +49 -0
- package/src/lib/mappers/work.ts +38 -0
- package/src/ssr.ts +73 -0
- package/tsconfig.json +17 -0
- package/tsconfig.lib.json +14 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
fragment LicenseFields on License {
|
|
2
|
+
name
|
|
3
|
+
link
|
|
4
|
+
description
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
fragment TitlesByLanguageFields on TitlesByLanguage {
|
|
8
|
+
tibetan
|
|
9
|
+
english
|
|
10
|
+
wylie
|
|
11
|
+
sanskrit
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fragment ImprintFields on Imprint {
|
|
15
|
+
toh
|
|
16
|
+
section
|
|
17
|
+
version
|
|
18
|
+
restriction
|
|
19
|
+
publishYear
|
|
20
|
+
tibetanAuthors
|
|
21
|
+
isAuthorContested
|
|
22
|
+
sourceDescription
|
|
23
|
+
publisherStatement
|
|
24
|
+
tibetanTranslators
|
|
25
|
+
license {
|
|
26
|
+
...LicenseFields
|
|
27
|
+
}
|
|
28
|
+
mainTitles {
|
|
29
|
+
...TitlesByLanguageFields
|
|
30
|
+
}
|
|
31
|
+
longTitles {
|
|
32
|
+
...TitlesByLanguageFields
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
fragment PassageFields on Passage {
|
|
2
|
+
uuid
|
|
3
|
+
workUuid
|
|
4
|
+
content
|
|
5
|
+
label
|
|
6
|
+
sort
|
|
7
|
+
type
|
|
8
|
+
xmlId
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
fragment PassageWithAnnotations on Passage {
|
|
12
|
+
...PassageFields
|
|
13
|
+
annotations {
|
|
14
|
+
...AnnotationFields
|
|
15
|
+
}
|
|
16
|
+
alignments {
|
|
17
|
+
...AlignmentFields
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fragment PassageWithJson on Passage {
|
|
22
|
+
uuid
|
|
23
|
+
workUuid
|
|
24
|
+
label
|
|
25
|
+
sort
|
|
26
|
+
type
|
|
27
|
+
xmlId
|
|
28
|
+
json
|
|
29
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
fragment TocEntryFields on TocEntry {
|
|
2
|
+
uuid
|
|
3
|
+
content
|
|
4
|
+
label
|
|
5
|
+
sort
|
|
6
|
+
level
|
|
7
|
+
section
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
# Recursive fragment for TOC entries up to 6 levels deep
|
|
11
|
+
fragment TocEntryNested on TocEntry {
|
|
12
|
+
...TocEntryFields
|
|
13
|
+
children {
|
|
14
|
+
...TocEntryFields
|
|
15
|
+
children {
|
|
16
|
+
...TocEntryFields
|
|
17
|
+
children {
|
|
18
|
+
...TocEntryFields
|
|
19
|
+
children {
|
|
20
|
+
...TocEntryFields
|
|
21
|
+
children {
|
|
22
|
+
...TocEntryFields
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fragment TocFields on Toc {
|
|
31
|
+
frontMatter {
|
|
32
|
+
...TocEntryNested
|
|
33
|
+
}
|
|
34
|
+
body {
|
|
35
|
+
...TocEntryNested
|
|
36
|
+
}
|
|
37
|
+
backMatter {
|
|
38
|
+
...TocEntryNested
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
query GetPassages(
|
|
2
|
+
$uuid: ID!
|
|
3
|
+
$cursor: String
|
|
4
|
+
$limit: Int
|
|
5
|
+
$direction: PaginationDirection
|
|
6
|
+
$filter: PassageFilter
|
|
7
|
+
) {
|
|
8
|
+
work(uuid: $uuid) {
|
|
9
|
+
uuid
|
|
10
|
+
passages(
|
|
11
|
+
cursor: $cursor
|
|
12
|
+
limit: $limit
|
|
13
|
+
direction: $direction
|
|
14
|
+
filter: $filter
|
|
15
|
+
) {
|
|
16
|
+
nodes {
|
|
17
|
+
...PassageWithAnnotations
|
|
18
|
+
}
|
|
19
|
+
pageInfo {
|
|
20
|
+
nextCursor
|
|
21
|
+
prevCursor
|
|
22
|
+
hasMoreAfter
|
|
23
|
+
hasMoreBefore
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
query GetPassagesBasic(
|
|
30
|
+
$uuid: ID!
|
|
31
|
+
$cursor: String
|
|
32
|
+
$limit: Int
|
|
33
|
+
$direction: PaginationDirection
|
|
34
|
+
$filter: PassageFilter
|
|
35
|
+
) {
|
|
36
|
+
work(uuid: $uuid) {
|
|
37
|
+
uuid
|
|
38
|
+
passages(
|
|
39
|
+
cursor: $cursor
|
|
40
|
+
limit: $limit
|
|
41
|
+
direction: $direction
|
|
42
|
+
filter: $filter
|
|
43
|
+
) {
|
|
44
|
+
nodes {
|
|
45
|
+
...PassageFields
|
|
46
|
+
}
|
|
47
|
+
pageInfo {
|
|
48
|
+
nextCursor
|
|
49
|
+
prevCursor
|
|
50
|
+
hasMoreAfter
|
|
51
|
+
hasMoreBefore
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
query GetPassagesWithJson(
|
|
58
|
+
$uuid: ID!
|
|
59
|
+
$cursor: String
|
|
60
|
+
$limit: Int
|
|
61
|
+
$direction: PaginationDirection
|
|
62
|
+
$filter: PassageFilter
|
|
63
|
+
) {
|
|
64
|
+
work(uuid: $uuid) {
|
|
65
|
+
uuid
|
|
66
|
+
passages(
|
|
67
|
+
cursor: $cursor
|
|
68
|
+
limit: $limit
|
|
69
|
+
direction: $direction
|
|
70
|
+
filter: $filter
|
|
71
|
+
) {
|
|
72
|
+
nodes {
|
|
73
|
+
...PassageWithJson
|
|
74
|
+
}
|
|
75
|
+
pageInfo {
|
|
76
|
+
nextCursor
|
|
77
|
+
prevCursor
|
|
78
|
+
hasMoreAfter
|
|
79
|
+
hasMoreBefore
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
query GetPassagesAroundWithJson(
|
|
86
|
+
$uuid: ID!
|
|
87
|
+
$cursor: String!
|
|
88
|
+
$limit: Int
|
|
89
|
+
$filter: PassageFilter
|
|
90
|
+
) {
|
|
91
|
+
work(uuid: $uuid) {
|
|
92
|
+
uuid
|
|
93
|
+
passages(
|
|
94
|
+
cursor: $cursor
|
|
95
|
+
limit: $limit
|
|
96
|
+
direction: AROUND
|
|
97
|
+
filter: $filter
|
|
98
|
+
) {
|
|
99
|
+
nodes {
|
|
100
|
+
...PassageWithJson
|
|
101
|
+
}
|
|
102
|
+
pageInfo {
|
|
103
|
+
nextCursor
|
|
104
|
+
prevCursor
|
|
105
|
+
hasMoreAfter
|
|
106
|
+
hasMoreBefore
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
query GetPassage($uuid: ID!) {
|
|
113
|
+
passage(uuid: $uuid) {
|
|
114
|
+
...PassageWithAnnotations
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
query GetWorkByUuid($uuid: ID!) {
|
|
2
|
+
work(uuid: $uuid) {
|
|
3
|
+
...WorkFields
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
query GetWorkByToh($toh: String!) {
|
|
8
|
+
work(toh: $toh) {
|
|
9
|
+
...WorkFields
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
query GetWorkWithTitles($uuid: ID!) {
|
|
14
|
+
work(uuid: $uuid) {
|
|
15
|
+
...WorkFields
|
|
16
|
+
titles {
|
|
17
|
+
...TitleFields
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
query GetWorkWithImprint($uuid: ID!, $toh: String) {
|
|
23
|
+
work(uuid: $uuid, toh: $toh) {
|
|
24
|
+
...WorkFields
|
|
25
|
+
imprint {
|
|
26
|
+
...ImprintFields
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
query GetWorkWithToc($uuid: ID!) {
|
|
32
|
+
work(uuid: $uuid) {
|
|
33
|
+
...WorkFields
|
|
34
|
+
toc {
|
|
35
|
+
...TocFields
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
query GetAllWorks($cursor: String, $limit: Int) {
|
|
2
|
+
works(cursor: $cursor, limit: $limit) {
|
|
3
|
+
items {
|
|
4
|
+
...WorkFields
|
|
5
|
+
}
|
|
6
|
+
pageInfo {
|
|
7
|
+
nextCursor
|
|
8
|
+
hasMoreAfter
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
query GetWorkUuids($cursor: String, $limit: Int) {
|
|
14
|
+
works(cursor: $cursor, limit: $limit) {
|
|
15
|
+
items {
|
|
16
|
+
uuid
|
|
17
|
+
}
|
|
18
|
+
pageInfo {
|
|
19
|
+
nextCursor
|
|
20
|
+
hasMoreAfter
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Alignment, TohokuCatalogEntry } from '@eightyfourthousand/data-access';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GraphQL Alignment type from generated code
|
|
5
|
+
*/
|
|
6
|
+
export type GraphQLAlignment = {
|
|
7
|
+
folioUuid: string;
|
|
8
|
+
toh: string;
|
|
9
|
+
tibetan: string;
|
|
10
|
+
folioNumber: number;
|
|
11
|
+
volumeNumber: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert a GraphQL alignment to the internal Alignment type
|
|
16
|
+
*/
|
|
17
|
+
export function alignmentFromGraphQL(gqlAlignment: GraphQLAlignment): Alignment {
|
|
18
|
+
return {
|
|
19
|
+
folioUuid: gqlAlignment.folioUuid,
|
|
20
|
+
toh: gqlAlignment.toh as TohokuCatalogEntry,
|
|
21
|
+
tibetan: gqlAlignment.tibetan,
|
|
22
|
+
folioNumber: gqlAlignment.folioNumber,
|
|
23
|
+
volumeNumber: gqlAlignment.volumeNumber,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Convert an array of GraphQL alignments to internal Alignment types
|
|
29
|
+
*/
|
|
30
|
+
export function alignmentsFromGraphQL(
|
|
31
|
+
gqlAlignments: GraphQLAlignment[],
|
|
32
|
+
): Alignment[] {
|
|
33
|
+
return gqlAlignments.map(alignmentFromGraphQL);
|
|
34
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Annotation,
|
|
3
|
+
type Annotations,
|
|
4
|
+
type AnnotationType,
|
|
5
|
+
type HeadingClass,
|
|
6
|
+
type ExtendedTranslationLanguage,
|
|
7
|
+
ANNOTATION_TYPE_DTO_TO_TYPE,
|
|
8
|
+
} from '@eightyfourthousand/data-access';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* GraphQL Annotation type from generated code
|
|
12
|
+
*/
|
|
13
|
+
export type GraphQLAnnotation = {
|
|
14
|
+
uuid: string;
|
|
15
|
+
type: string;
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
metadata?: Record<string, unknown> | null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Map from DTO-style type names (kebab-case) to internal type names (camelCase)
|
|
23
|
+
*/
|
|
24
|
+
const typeMap: Record<string, AnnotationType> = {
|
|
25
|
+
...ANNOTATION_TYPE_DTO_TO_TYPE,
|
|
26
|
+
// Also handle camelCase types (from GraphQL)
|
|
27
|
+
endNoteLink: 'endNoteLink',
|
|
28
|
+
glossaryInstance: 'glossaryInstance',
|
|
29
|
+
hasAbbreviation: 'hasAbbreviation',
|
|
30
|
+
inlineTitle: 'inlineTitle',
|
|
31
|
+
internalLink: 'internalLink',
|
|
32
|
+
leadingSpace: 'leadingSpace',
|
|
33
|
+
lineGroup: 'lineGroup',
|
|
34
|
+
listItem: 'listItem',
|
|
35
|
+
tableBodyData: 'tableBodyData',
|
|
36
|
+
tableBodyHeader: 'tableBodyHeader',
|
|
37
|
+
tableBodyRow: 'tableBodyRow',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Convert a GraphQL annotation to the internal Annotation type
|
|
42
|
+
*/
|
|
43
|
+
export function annotationFromGraphQL(
|
|
44
|
+
gqlAnnotation: GraphQLAnnotation,
|
|
45
|
+
passageUuid: string,
|
|
46
|
+
): Annotation {
|
|
47
|
+
const type = typeMap[gqlAnnotation.type] || 'unknown';
|
|
48
|
+
const metadata = gqlAnnotation.metadata || {};
|
|
49
|
+
|
|
50
|
+
const base = {
|
|
51
|
+
uuid: gqlAnnotation.uuid,
|
|
52
|
+
type,
|
|
53
|
+
start: gqlAnnotation.start,
|
|
54
|
+
end: gqlAnnotation.end,
|
|
55
|
+
passageUuid,
|
|
56
|
+
validated: true,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Extract type-specific fields from metadata
|
|
60
|
+
switch (type) {
|
|
61
|
+
case 'heading':
|
|
62
|
+
return {
|
|
63
|
+
...base,
|
|
64
|
+
type: 'heading',
|
|
65
|
+
level: (metadata.level as number) ?? 1,
|
|
66
|
+
class: metadata.class as HeadingClass | undefined,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
case 'link':
|
|
70
|
+
return {
|
|
71
|
+
...base,
|
|
72
|
+
type: 'link',
|
|
73
|
+
href: (metadata.href as string) ?? '',
|
|
74
|
+
text: (metadata.text as string) ?? '',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
case 'internalLink':
|
|
78
|
+
return {
|
|
79
|
+
...base,
|
|
80
|
+
type: 'internalLink',
|
|
81
|
+
linkType: (metadata.linkType as string) ?? '',
|
|
82
|
+
href: metadata.href as string | undefined,
|
|
83
|
+
label: metadata.label as string | undefined,
|
|
84
|
+
entity: metadata.entity as string | undefined,
|
|
85
|
+
isPending: metadata.isPending as boolean | undefined,
|
|
86
|
+
isSameWork: metadata.isSameWork as boolean | undefined,
|
|
87
|
+
subtype: metadata.subtype as string | undefined,
|
|
88
|
+
linkToh: metadata.linkToh as string | undefined,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
case 'span':
|
|
92
|
+
return {
|
|
93
|
+
...base,
|
|
94
|
+
type: 'span',
|
|
95
|
+
textStyle: metadata.textStyle as string | undefined,
|
|
96
|
+
lang: metadata.lang as ExtendedTranslationLanguage | undefined,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
case 'mantra':
|
|
100
|
+
return {
|
|
101
|
+
...base,
|
|
102
|
+
type: 'mantra',
|
|
103
|
+
lang: (metadata.lang as ExtendedTranslationLanguage) ?? 'Sa-Ltn',
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
case 'inlineTitle':
|
|
107
|
+
return {
|
|
108
|
+
...base,
|
|
109
|
+
type: 'inlineTitle',
|
|
110
|
+
lang: (metadata.lang as ExtendedTranslationLanguage) ?? 'Sa-Ltn',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
case 'audio':
|
|
114
|
+
return {
|
|
115
|
+
...base,
|
|
116
|
+
type: 'audio',
|
|
117
|
+
src: (metadata.src as string) ?? '',
|
|
118
|
+
mediaType: (metadata.mediaType as string) ?? '',
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
case 'image':
|
|
122
|
+
return {
|
|
123
|
+
...base,
|
|
124
|
+
type: 'image',
|
|
125
|
+
src: (metadata.src as string) ?? '',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
case 'list':
|
|
129
|
+
return {
|
|
130
|
+
...base,
|
|
131
|
+
type: 'list',
|
|
132
|
+
spacing: metadata.spacing as string | undefined,
|
|
133
|
+
nesting: metadata.nesting as number | undefined,
|
|
134
|
+
itemStyle: metadata.itemStyle as string | undefined,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
case 'glossaryInstance':
|
|
138
|
+
return {
|
|
139
|
+
...base,
|
|
140
|
+
type: 'glossaryInstance',
|
|
141
|
+
authority: (metadata.authority as string) ?? '',
|
|
142
|
+
glossary: (metadata.glossary as string) ?? '',
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
case 'endNoteLink':
|
|
146
|
+
return {
|
|
147
|
+
...base,
|
|
148
|
+
type: 'endNoteLink',
|
|
149
|
+
endNote: (metadata.endNote as string) ?? '',
|
|
150
|
+
label: metadata.label as string | undefined,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
case 'abbreviation':
|
|
154
|
+
return {
|
|
155
|
+
...base,
|
|
156
|
+
type: 'abbreviation',
|
|
157
|
+
abbreviation: (metadata.abbreviation as string) ?? '',
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
case 'hasAbbreviation':
|
|
161
|
+
return {
|
|
162
|
+
...base,
|
|
163
|
+
type: 'hasAbbreviation',
|
|
164
|
+
abbreviation: (metadata.abbreviation as string) ?? '',
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
case 'quote':
|
|
168
|
+
return {
|
|
169
|
+
...base,
|
|
170
|
+
type: 'quote',
|
|
171
|
+
quote: metadata.quote as string | undefined,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
case 'quoted':
|
|
175
|
+
return {
|
|
176
|
+
...base,
|
|
177
|
+
type: 'quoted',
|
|
178
|
+
quote: metadata.quote as string | undefined,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
default:
|
|
182
|
+
// For types with no additional fields
|
|
183
|
+
return base as Annotation;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Convert an array of GraphQL annotations to internal Annotation types
|
|
189
|
+
*/
|
|
190
|
+
export function annotationsFromGraphQL(
|
|
191
|
+
gqlAnnotations: GraphQLAnnotation[],
|
|
192
|
+
passageUuid: string,
|
|
193
|
+
): Annotations {
|
|
194
|
+
// Filter out ignored annotation types
|
|
195
|
+
const ignoredTypes = [
|
|
196
|
+
'deprecated-internal-link',
|
|
197
|
+
'quoted',
|
|
198
|
+
'reference',
|
|
199
|
+
'unknown',
|
|
200
|
+
];
|
|
201
|
+
const filtered = gqlAnnotations.filter((a) => !ignoredTypes.includes(a.type));
|
|
202
|
+
|
|
203
|
+
return filtered.map((a) => annotationFromGraphQL(a, passageUuid));
|
|
204
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Imprint, SemVer, TranslationLanguage } from '@eightyfourthousand/data-access';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GraphQL TitlesByLanguage type
|
|
5
|
+
*/
|
|
6
|
+
type GraphQLTitlesByLanguage = {
|
|
7
|
+
tibetan?: string | null;
|
|
8
|
+
english?: string | null;
|
|
9
|
+
wylie?: string | null;
|
|
10
|
+
sanskrit?: string | null;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* GraphQL Imprint type
|
|
15
|
+
*/
|
|
16
|
+
export type GraphQLImprint = {
|
|
17
|
+
toh: string;
|
|
18
|
+
section?: string | null;
|
|
19
|
+
version?: string | null;
|
|
20
|
+
restriction?: boolean | null;
|
|
21
|
+
publishYear?: string | null;
|
|
22
|
+
tibetanAuthors?: string[] | null;
|
|
23
|
+
isAuthorContested: boolean;
|
|
24
|
+
sourceDescription?: string | null;
|
|
25
|
+
publisherStatement?: string | null;
|
|
26
|
+
tibetanTranslators?: string | null;
|
|
27
|
+
license: {
|
|
28
|
+
name?: string | null;
|
|
29
|
+
link?: string | null;
|
|
30
|
+
description?: string | null;
|
|
31
|
+
} | null;
|
|
32
|
+
mainTitles?: GraphQLTitlesByLanguage | null;
|
|
33
|
+
longTitles?: GraphQLTitlesByLanguage | null;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Map GraphQL TitlesByLanguage to internal TranslationLanguage keyed record
|
|
38
|
+
*/
|
|
39
|
+
function titlesFromGraphQL(
|
|
40
|
+
gqlTitles?: GraphQLTitlesByLanguage | null,
|
|
41
|
+
): Partial<{ [key in TranslationLanguage]: string }> | undefined {
|
|
42
|
+
if (!gqlTitles) return undefined;
|
|
43
|
+
|
|
44
|
+
const result: Partial<{ [key in TranslationLanguage]: string }> = {};
|
|
45
|
+
if (gqlTitles.tibetan) result['bo'] = gqlTitles.tibetan;
|
|
46
|
+
if (gqlTitles.english) result['en'] = gqlTitles.english;
|
|
47
|
+
if (gqlTitles.wylie) result['Bo-Ltn'] = gqlTitles.wylie;
|
|
48
|
+
if (gqlTitles.sanskrit) result['Sa-Ltn'] = gqlTitles.sanskrit;
|
|
49
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Convert a GraphQL Imprint to the internal Imprint type
|
|
54
|
+
*/
|
|
55
|
+
export function imprintFromGraphQL(
|
|
56
|
+
gqlImprint: GraphQLImprint,
|
|
57
|
+
workUuid: string,
|
|
58
|
+
): Imprint {
|
|
59
|
+
return {
|
|
60
|
+
uuid: workUuid,
|
|
61
|
+
toh: gqlImprint.toh,
|
|
62
|
+
section: gqlImprint.section || undefined,
|
|
63
|
+
version: (gqlImprint.version as SemVer) || undefined,
|
|
64
|
+
restriction: gqlImprint.restriction || undefined,
|
|
65
|
+
publishYear: gqlImprint.publishYear || undefined,
|
|
66
|
+
tibetanAuthors: gqlImprint.tibetanAuthors || undefined,
|
|
67
|
+
isAuthorContested: gqlImprint.isAuthorContested,
|
|
68
|
+
sourceDescription: gqlImprint.sourceDescription || undefined,
|
|
69
|
+
publisherStatement: gqlImprint.publisherStatement || undefined,
|
|
70
|
+
tibetanTranslators: gqlImprint.tibetanTranslators || undefined,
|
|
71
|
+
license: {
|
|
72
|
+
link: gqlImprint.license?.link || undefined,
|
|
73
|
+
name: gqlImprint.license?.name || undefined,
|
|
74
|
+
description: gqlImprint.license?.description || undefined,
|
|
75
|
+
},
|
|
76
|
+
mainTitles: titlesFromGraphQL(gqlImprint.mainTitles),
|
|
77
|
+
longTitles: titlesFromGraphQL(gqlImprint.longTitles),
|
|
78
|
+
};
|
|
79
|
+
}
|