@eightyfourthousand/data-access 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/.babelrc +12 -0
- package/.eslintrc.json +18 -0
- package/README.md +7 -0
- package/jest.config.ts +10 -0
- package/package.json +30 -0
- package/project.json +21 -0
- package/src/index.ts +18 -0
- package/src/lib/auth.ts +203 -0
- package/src/lib/bibliography.ts +57 -0
- package/src/lib/canon.ts +111 -0
- package/src/lib/client-browser.ts +12 -0
- package/src/lib/client-server.ts +30 -0
- package/src/lib/client-ssr.ts +24 -0
- package/src/lib/client-token.ts +24 -0
- package/src/lib/feedback.ts +71 -0
- package/src/lib/folio.ts +43 -0
- package/src/lib/glossary.ts +147 -0
- package/src/lib/imprint.ts +42 -0
- package/src/lib/library.ts +209 -0
- package/src/lib/local-storage.ts +33 -0
- package/src/lib/lookup-entity.ts +122 -0
- package/src/lib/panel-url.ts +43 -0
- package/src/lib/passage.ts +122 -0
- package/src/lib/projects.ts +107 -0
- package/src/lib/proxy.ts +68 -0
- package/src/lib/publications.ts +213 -0
- package/src/lib/storage.ts +23 -0
- package/src/lib/types/alignment.ts +32 -0
- package/src/lib/types/annotation/abbreviation.ts +30 -0
- package/src/lib/types/annotation/annotation-type.ts +219 -0
- package/src/lib/types/annotation/annotation.ts +244 -0
- package/src/lib/types/annotation/audio.ts +33 -0
- package/src/lib/types/annotation/blockquote.ts +18 -0
- package/src/lib/types/annotation/code.ts +16 -0
- package/src/lib/types/annotation/deprecated.ts +18 -0
- package/src/lib/types/annotation/end-note-link.ts +35 -0
- package/src/lib/types/annotation/export.ts +69 -0
- package/src/lib/types/annotation/glossary-instance.ts +34 -0
- package/src/lib/types/annotation/has-abbreviation.ts +30 -0
- package/src/lib/types/annotation/heading.ts +37 -0
- package/src/lib/types/annotation/image.ts +29 -0
- package/src/lib/types/annotation/indent.ts +16 -0
- package/src/lib/types/annotation/index.ts +4 -0
- package/src/lib/types/annotation/inline-title.ts +34 -0
- package/src/lib/types/annotation/internal-link.ts +86 -0
- package/src/lib/types/annotation/leading-space.ts +18 -0
- package/src/lib/types/annotation/line-group.ts +18 -0
- package/src/lib/types/annotation/line.ts +16 -0
- package/src/lib/types/annotation/link.ts +38 -0
- package/src/lib/types/annotation/list-item.ts +16 -0
- package/src/lib/types/annotation/list.ts +43 -0
- package/src/lib/types/annotation/mantra.ts +31 -0
- package/src/lib/types/annotation/mention.ts +64 -0
- package/src/lib/types/annotation/paragraph.ts +18 -0
- package/src/lib/types/annotation/quote.ts +30 -0
- package/src/lib/types/annotation/quoted.ts +30 -0
- package/src/lib/types/annotation/reference.ts +18 -0
- package/src/lib/types/annotation/span.ts +39 -0
- package/src/lib/types/annotation/table-body-data.ts +18 -0
- package/src/lib/types/annotation/table-body-header.ts +18 -0
- package/src/lib/types/annotation/table-body-row.ts +18 -0
- package/src/lib/types/annotation/table.ts +16 -0
- package/src/lib/types/annotation/trailer.ts +16 -0
- package/src/lib/types/annotation/transform.ts +140 -0
- package/src/lib/types/annotation/unknown.ts +16 -0
- package/src/lib/types/bibliography.ts +86 -0
- package/src/lib/types/canon.ts +148 -0
- package/src/lib/types/client.ts +3 -0
- package/src/lib/types/contributor.ts +84 -0
- package/src/lib/types/editor-content.ts +21 -0
- package/src/lib/types/folio.ts +28 -0
- package/src/lib/types/glossary-page.ts +204 -0
- package/src/lib/types/glossary.ts +114 -0
- package/src/lib/types/imprint.ts +159 -0
- package/src/lib/types/index.ts +22 -0
- package/src/lib/types/language.ts +64 -0
- package/src/lib/types/layout.ts +37 -0
- package/src/lib/types/library.ts +29 -0
- package/src/lib/types/passage.ts +220 -0
- package/src/lib/types/project.ts +200 -0
- package/src/lib/types/semver.ts +1 -0
- package/src/lib/types/title.ts +47 -0
- package/src/lib/types/toh.ts +1 -0
- package/src/lib/types/translation.ts +15 -0
- package/src/lib/types/user.ts +15 -0
- package/src/lib/types/work.ts +38 -0
- package/src/lib/use-bookmark.ts +45 -0
- package/src/ssr.ts +5 -0
- package/tsconfig.json +20 -0
- package/tsconfig.lib.json +26 -0
- package/tsconfig.spec.json +22 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { Alignment, AlignmentDTO, alignmentsFromDTO } from './alignment';
|
|
2
|
+
import {
|
|
3
|
+
Annotations,
|
|
4
|
+
AnnotationsDTO,
|
|
5
|
+
annotationsFromDTO,
|
|
6
|
+
annotationsToDTO,
|
|
7
|
+
} from './annotation';
|
|
8
|
+
import { TohokuCatalogEntry } from './toh';
|
|
9
|
+
|
|
10
|
+
export const BODY_ITEM_TYPES = [
|
|
11
|
+
'abbreviations',
|
|
12
|
+
'abbreviationsHeader',
|
|
13
|
+
'acknowledgment',
|
|
14
|
+
'acknowledgmentHeader',
|
|
15
|
+
'appendix',
|
|
16
|
+
'appendixHeader',
|
|
17
|
+
'colophon',
|
|
18
|
+
'colophonHeader',
|
|
19
|
+
'endnotes',
|
|
20
|
+
'endnotesHeader',
|
|
21
|
+
'homage',
|
|
22
|
+
'homageHeader',
|
|
23
|
+
'introduction',
|
|
24
|
+
'introductionHeader',
|
|
25
|
+
'prelude',
|
|
26
|
+
'preludeHeader',
|
|
27
|
+
'prologue',
|
|
28
|
+
'prologueHeader',
|
|
29
|
+
'summary',
|
|
30
|
+
'summaryHeader',
|
|
31
|
+
'translation',
|
|
32
|
+
'translationHeader',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export type BodyItemType = (typeof BODY_ITEM_TYPES)[number] | 'unknown';
|
|
36
|
+
|
|
37
|
+
export const FRONT_MATTER: BodyItemType[] = [
|
|
38
|
+
'acknowledgment',
|
|
39
|
+
'summary',
|
|
40
|
+
'introduction',
|
|
41
|
+
];
|
|
42
|
+
export const FRONT_MATTER_FILTER = `(${FRONT_MATTER.join('|')})`;
|
|
43
|
+
export const BODY_MATTER: BodyItemType[] = [
|
|
44
|
+
'prelude',
|
|
45
|
+
'prologue',
|
|
46
|
+
'translation',
|
|
47
|
+
'appendix',
|
|
48
|
+
'colophon',
|
|
49
|
+
'homage',
|
|
50
|
+
];
|
|
51
|
+
export const BODY_MATTER_FILTER = `(${BODY_MATTER.join('|')})`;
|
|
52
|
+
export const BACK_MATTER: BodyItemType[] = ['abbreviations', 'endnotes'];
|
|
53
|
+
export const BACK_MATTER_FILTER = `(${BACK_MATTER.join('|')})`;
|
|
54
|
+
export const COMPARE_MODE = BODY_MATTER;
|
|
55
|
+
export const COMPARE_MODE_FILTER = `(${COMPARE_MODE.join('|')})`;
|
|
56
|
+
|
|
57
|
+
export const PANEL_FILTERS = [
|
|
58
|
+
FRONT_MATTER_FILTER,
|
|
59
|
+
BODY_MATTER_FILTER,
|
|
60
|
+
BACK_MATTER_FILTER,
|
|
61
|
+
COMPARE_MODE_FILTER,
|
|
62
|
+
] as const;
|
|
63
|
+
|
|
64
|
+
export type PanelFilter = (typeof PANEL_FILTERS)[number];
|
|
65
|
+
|
|
66
|
+
export type Passage = {
|
|
67
|
+
alignments?: Alignment[];
|
|
68
|
+
annotations: Annotations;
|
|
69
|
+
content: string;
|
|
70
|
+
label: string;
|
|
71
|
+
sort: number;
|
|
72
|
+
type: BodyItemType;
|
|
73
|
+
uuid: string;
|
|
74
|
+
workUuid: string;
|
|
75
|
+
xmlId?: string;
|
|
76
|
+
parent?: string;
|
|
77
|
+
toh?: TohokuCatalogEntry;
|
|
78
|
+
references?: Passages;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type Passages = Passage[];
|
|
82
|
+
|
|
83
|
+
export type PassageRowDTO = {
|
|
84
|
+
content: string;
|
|
85
|
+
label: string;
|
|
86
|
+
sort: number;
|
|
87
|
+
type: BodyItemType;
|
|
88
|
+
uuid: string;
|
|
89
|
+
work_uuid: string;
|
|
90
|
+
xmlId?: string;
|
|
91
|
+
parent?: string;
|
|
92
|
+
toh?: TohokuCatalogEntry;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type PassageDTO = PassageRowDTO & {
|
|
96
|
+
alignments?: AlignmentDTO[];
|
|
97
|
+
annotations?: AnnotationsDTO | null;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type PaginationDirection = 'forward' | 'backward';
|
|
101
|
+
|
|
102
|
+
export type PassagesPageDTO = {
|
|
103
|
+
passages: PassageDTO[];
|
|
104
|
+
nextCursor?: string;
|
|
105
|
+
hasMore: boolean;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export type PassagesPageAroundDTO = {
|
|
109
|
+
passages: PassageDTO[];
|
|
110
|
+
prevCursor?: string;
|
|
111
|
+
nextCursor?: string;
|
|
112
|
+
hasMoreBefore: boolean;
|
|
113
|
+
hasMoreAfter: boolean;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type PassagesPage = {
|
|
117
|
+
passages: Passage[];
|
|
118
|
+
prevCursor?: string;
|
|
119
|
+
nextCursor?: string;
|
|
120
|
+
hasMoreAfter: boolean;
|
|
121
|
+
hasMoreBefore: boolean;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const passageFromDTO = (
|
|
125
|
+
dto: PassageDTO,
|
|
126
|
+
annotations: Annotations = [],
|
|
127
|
+
alignments: Alignment[] = [],
|
|
128
|
+
): Passage => {
|
|
129
|
+
return {
|
|
130
|
+
content: dto.content,
|
|
131
|
+
label: dto.label,
|
|
132
|
+
sort: dto.sort,
|
|
133
|
+
type: dto.type,
|
|
134
|
+
uuid: dto.uuid,
|
|
135
|
+
workUuid: dto.work_uuid,
|
|
136
|
+
xmlId: dto.xmlId,
|
|
137
|
+
parent: dto.parent,
|
|
138
|
+
toh: dto.toh,
|
|
139
|
+
alignments,
|
|
140
|
+
annotations,
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const passagesFromDTO = (dto: PassageDTO[]): Passage[] => {
|
|
145
|
+
return dto.map((p) =>
|
|
146
|
+
passageFromDTO(
|
|
147
|
+
p,
|
|
148
|
+
annotationsFromDTO(p.annotations || [], p.content.length),
|
|
149
|
+
alignmentsFromDTO(p.alignments || []),
|
|
150
|
+
),
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const passageToRowDTO = (passage: Passage): PassageRowDTO => {
|
|
155
|
+
const dto: PassageRowDTO = {
|
|
156
|
+
content: passage.content,
|
|
157
|
+
label: passage.label,
|
|
158
|
+
sort: passage.sort,
|
|
159
|
+
type: passage.type,
|
|
160
|
+
uuid: passage.uuid,
|
|
161
|
+
work_uuid: passage.workUuid,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// NOTE: only include xmlId and parent if they exist, otherwise an upsert
|
|
165
|
+
// will set them to null in the database.
|
|
166
|
+
if (passage.xmlId) {
|
|
167
|
+
dto.xmlId = passage.xmlId;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (passage.parent) {
|
|
171
|
+
dto.parent = passage.parent;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (passage.toh) {
|
|
175
|
+
dto.toh = passage.toh;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return dto;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const passageToDTO = (passage: Passage): PassageDTO => {
|
|
182
|
+
// NOTE: ignore alignments
|
|
183
|
+
return {
|
|
184
|
+
...passageToRowDTO(passage),
|
|
185
|
+
annotations: annotationsToDTO(passage.annotations) || [],
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const passagesToDTO = (passages: Passage[]): PassageDTO[] => {
|
|
190
|
+
return passages.map(passageToDTO);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export const passagesToRowDTO = (passages: Passage[]): PassageRowDTO[] => {
|
|
194
|
+
return passages.map(passageToRowDTO);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const passagesPageFromDTO = (
|
|
198
|
+
direction: PaginationDirection,
|
|
199
|
+
dto: PassagesPageDTO,
|
|
200
|
+
): PassagesPage => {
|
|
201
|
+
return {
|
|
202
|
+
passages: passagesFromDTO(dto.passages),
|
|
203
|
+
nextCursor: direction === 'forward' ? dto.nextCursor : undefined,
|
|
204
|
+
prevCursor: direction === 'backward' ? dto.nextCursor : undefined,
|
|
205
|
+
hasMoreAfter: direction === 'forward' && dto.hasMore,
|
|
206
|
+
hasMoreBefore: direction === 'backward' && dto.hasMore,
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export const passagesPageAroundFromDTO = (
|
|
211
|
+
dto: PassagesPageAroundDTO,
|
|
212
|
+
): PassagesPage => {
|
|
213
|
+
return {
|
|
214
|
+
passages: passagesFromDTO(dto.passages),
|
|
215
|
+
nextCursor: dto.nextCursor,
|
|
216
|
+
prevCursor: dto.prevCursor,
|
|
217
|
+
hasMoreAfter: dto.hasMoreAfter,
|
|
218
|
+
hasMoreBefore: dto.hasMoreBefore,
|
|
219
|
+
};
|
|
220
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { SemVer } from './semver';
|
|
2
|
+
|
|
3
|
+
export const PROJECT_STAGE_LABELS = [
|
|
4
|
+
'1',
|
|
5
|
+
'1.a',
|
|
6
|
+
'2',
|
|
7
|
+
'2.a',
|
|
8
|
+
'2.b',
|
|
9
|
+
'2.c',
|
|
10
|
+
'2.d',
|
|
11
|
+
'2.e',
|
|
12
|
+
'2.f',
|
|
13
|
+
'2.g',
|
|
14
|
+
'2.h',
|
|
15
|
+
'3',
|
|
16
|
+
'4',
|
|
17
|
+
'0',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
export const STAGE_DESCRIPTIONS: Record<ProjectStageLabel, string> = {
|
|
21
|
+
'1': 'Published and in app',
|
|
22
|
+
'1.a': 'Published',
|
|
23
|
+
'2': 'Marked up and awaiting final proofing',
|
|
24
|
+
'2.a': 'Markup in progress',
|
|
25
|
+
'2.b': 'Awaiting markup',
|
|
26
|
+
'2.c': "Awaiting editor's OK form markup",
|
|
27
|
+
'2.d': 'Copy editing complete',
|
|
28
|
+
'2.e': 'Copy editing in progress',
|
|
29
|
+
'2.f': 'Review complete',
|
|
30
|
+
'2.g': 'In editorial review',
|
|
31
|
+
'2.h': 'Awaiting editorial review',
|
|
32
|
+
'3': 'In translation',
|
|
33
|
+
'4': 'Application pending',
|
|
34
|
+
'0': 'Not started',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const STAGE_COLORS: Record<ProjectStageLabel, string> = {
|
|
38
|
+
'1': 'emerald',
|
|
39
|
+
'1.a': 'emerald',
|
|
40
|
+
'2': 'ochre',
|
|
41
|
+
'2.a': 'ochre',
|
|
42
|
+
'2.b': 'ochre',
|
|
43
|
+
'2.c': 'ochre',
|
|
44
|
+
'2.d': 'ochre',
|
|
45
|
+
'2.e': 'ochre',
|
|
46
|
+
'2.f': 'ochre',
|
|
47
|
+
'2.g': 'ochre',
|
|
48
|
+
'2.h': 'ochre',
|
|
49
|
+
'3': 'navy',
|
|
50
|
+
'4': 'brick',
|
|
51
|
+
'0': 'muted text-muted-foreground',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const CANON_TYPES = ['kangyur', 'tengyur'];
|
|
55
|
+
|
|
56
|
+
export type ProjectStageLabel = (typeof PROJECT_STAGE_LABELS)[number];
|
|
57
|
+
|
|
58
|
+
export type CanonType = (typeof CANON_TYPES)[number];
|
|
59
|
+
|
|
60
|
+
export type ProjectStage = {
|
|
61
|
+
label: ProjectStageLabel;
|
|
62
|
+
description: string;
|
|
63
|
+
date: Date;
|
|
64
|
+
targetDate?: Date;
|
|
65
|
+
color: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type ProjectViewDTO = {
|
|
69
|
+
uuid: string;
|
|
70
|
+
toh: string;
|
|
71
|
+
title: string;
|
|
72
|
+
translator: string;
|
|
73
|
+
stage: ProjectStageLabel;
|
|
74
|
+
stage_date: string;
|
|
75
|
+
pages: number;
|
|
76
|
+
type?: string;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type ProjectTableDTO = {
|
|
80
|
+
uuid: string;
|
|
81
|
+
notes: string;
|
|
82
|
+
contractDate: string;
|
|
83
|
+
contractId: string;
|
|
84
|
+
workUuid: string;
|
|
85
|
+
pages: number;
|
|
86
|
+
publicationDate: string;
|
|
87
|
+
version: string;
|
|
88
|
+
stage: ProjectStageLabel;
|
|
89
|
+
restriction: boolean;
|
|
90
|
+
title: string;
|
|
91
|
+
toh: string;
|
|
92
|
+
mainTranslator: string;
|
|
93
|
+
translationGroup: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type Project = {
|
|
97
|
+
uuid: string;
|
|
98
|
+
toh: string;
|
|
99
|
+
title: string;
|
|
100
|
+
translator?: string;
|
|
101
|
+
translationGroup?: string;
|
|
102
|
+
stage: ProjectStage;
|
|
103
|
+
pages: number;
|
|
104
|
+
notes?: string;
|
|
105
|
+
contractDate?: Date;
|
|
106
|
+
contractId?: string;
|
|
107
|
+
workUuid?: string;
|
|
108
|
+
version?: SemVer;
|
|
109
|
+
canons?: string;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export type ProjectStageDetailsDTO = {
|
|
113
|
+
uuid: string;
|
|
114
|
+
stage: ProjectStageLabel;
|
|
115
|
+
stageDate: string;
|
|
116
|
+
targetDate?: string;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type ProjectStageDetail = {
|
|
120
|
+
uuid: string;
|
|
121
|
+
stage: ProjectStage;
|
|
122
|
+
targetDate?: Date;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export type ProjectStageDetails = ProjectStageDetail[];
|
|
126
|
+
|
|
127
|
+
export type ProjectAssetDTO = {
|
|
128
|
+
uuid: string;
|
|
129
|
+
projectUuid: string;
|
|
130
|
+
stageUuid?: string;
|
|
131
|
+
filename: string;
|
|
132
|
+
url: string;
|
|
133
|
+
note?: string;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type ProjectAsset = ProjectAssetDTO;
|
|
137
|
+
|
|
138
|
+
export function projectStageDetailFromDTO(
|
|
139
|
+
dto: ProjectStageDetailsDTO,
|
|
140
|
+
): ProjectStageDetail {
|
|
141
|
+
return {
|
|
142
|
+
uuid: dto.uuid,
|
|
143
|
+
stage: {
|
|
144
|
+
label: dto.stage,
|
|
145
|
+
description: STAGE_DESCRIPTIONS[dto.stage] || '',
|
|
146
|
+
date: new Date(dto.stageDate),
|
|
147
|
+
targetDate: dto.targetDate ? new Date(dto.targetDate) : undefined,
|
|
148
|
+
color: STAGE_COLORS[dto.stage] || 'grey',
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function projectStageDetailsFromDTO(
|
|
154
|
+
dto?: ProjectStageDetailsDTO[],
|
|
155
|
+
): ProjectStageDetails {
|
|
156
|
+
return dto?.map(projectStageDetailFromDTO) || [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function projectFromViewDTO(dto: ProjectViewDTO): Project {
|
|
160
|
+
return {
|
|
161
|
+
uuid: dto.uuid,
|
|
162
|
+
toh: dto.toh,
|
|
163
|
+
title: dto.title,
|
|
164
|
+
translator: dto.translator,
|
|
165
|
+
stage: {
|
|
166
|
+
label: dto.stage,
|
|
167
|
+
description: STAGE_DESCRIPTIONS[dto.stage] || '',
|
|
168
|
+
date: new Date(dto.stage_date),
|
|
169
|
+
color: STAGE_COLORS[dto.stage] || 'grey',
|
|
170
|
+
},
|
|
171
|
+
pages: dto.pages,
|
|
172
|
+
canons: dto.type,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function projectFromTableDTO(dto: ProjectTableDTO): Project {
|
|
177
|
+
const stage = dto.stage;
|
|
178
|
+
const contractDate = dto.contractDate
|
|
179
|
+
? new Date(dto.contractDate)
|
|
180
|
+
: undefined;
|
|
181
|
+
return {
|
|
182
|
+
uuid: dto.uuid,
|
|
183
|
+
toh: dto.toh,
|
|
184
|
+
title: dto.title,
|
|
185
|
+
stage: {
|
|
186
|
+
label: stage,
|
|
187
|
+
description: STAGE_DESCRIPTIONS[stage] || '',
|
|
188
|
+
date: new Date(dto.publicationDate),
|
|
189
|
+
color: STAGE_COLORS[stage] || 'grey',
|
|
190
|
+
},
|
|
191
|
+
pages: dto.pages,
|
|
192
|
+
notes: dto.notes,
|
|
193
|
+
contractId: dto.contractId,
|
|
194
|
+
contractDate,
|
|
195
|
+
workUuid: dto.workUuid,
|
|
196
|
+
version: dto.version as SemVer,
|
|
197
|
+
translator: dto.mainTranslator,
|
|
198
|
+
translationGroup: dto.translationGroup,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type SemVer = `${number}.${number}.${number}`;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ExtendedTranslationLanguage } from './language';
|
|
2
|
+
|
|
3
|
+
export const TITLE_TYPES = [
|
|
4
|
+
'toh',
|
|
5
|
+
'mainTitle',
|
|
6
|
+
'mainTitleOutsideCatalogueSection',
|
|
7
|
+
'longTitle',
|
|
8
|
+
'otherTitle',
|
|
9
|
+
'shortcode',
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
export const BO_TITLE_PREFIX = '༄༅།\u00a0\u00a0།' as const;
|
|
13
|
+
|
|
14
|
+
export type TitleType = (typeof TITLE_TYPES)[number];
|
|
15
|
+
|
|
16
|
+
export type TitleTypeDTO = `eft:${TitleType}`;
|
|
17
|
+
|
|
18
|
+
export type Title = {
|
|
19
|
+
uuid: string;
|
|
20
|
+
title: string;
|
|
21
|
+
language: ExtendedTranslationLanguage;
|
|
22
|
+
type: TitleType;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type Titles = Title[];
|
|
26
|
+
|
|
27
|
+
export type TitleDTO = {
|
|
28
|
+
uuid: string;
|
|
29
|
+
title: string;
|
|
30
|
+
language: ExtendedTranslationLanguage;
|
|
31
|
+
type: TitleTypeDTO;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type TitlesDTO = TitleDTO[];
|
|
35
|
+
|
|
36
|
+
export const titleFromDTO = (dto: TitleDTO): Title => {
|
|
37
|
+
return {
|
|
38
|
+
uuid: dto.uuid,
|
|
39
|
+
title: dto.title,
|
|
40
|
+
language: dto.language,
|
|
41
|
+
type: (dto.type?.replace('eft:', '') as TitleType) || 'mainTitle',
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const titlesFromDTO = (dto?: TitlesDTO): Titles => {
|
|
46
|
+
return dto?.map(titleFromDTO) || [];
|
|
47
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TohokuCatalogEntry = `toh${number}`;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BibliographyEntries } from './bibliography';
|
|
2
|
+
import { GlossaryTermInstances } from './glossary';
|
|
3
|
+
import { BodyItemType, Passages } from './passage';
|
|
4
|
+
import { Titles } from './title';
|
|
5
|
+
import { Work } from './work';
|
|
6
|
+
|
|
7
|
+
export type TranslationNodeClass = 'translation' | 'annotation';
|
|
8
|
+
|
|
9
|
+
export type Translation = {
|
|
10
|
+
metadata: Work;
|
|
11
|
+
titles: Titles;
|
|
12
|
+
passages: Partial<Record<BodyItemType, Passages>>;
|
|
13
|
+
glossary: GlossaryTermInstances;
|
|
14
|
+
bibliography: BibliographyEntries;
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type UserRole = 'reader' | 'scholar' | 'translator' | 'editor' | 'admin';
|
|
2
|
+
export type UserClaims = {
|
|
3
|
+
role: UserRole;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const USER_PERMISIONS = [
|
|
7
|
+
'projects.read',
|
|
8
|
+
'projects.edit',
|
|
9
|
+
'projects.admin',
|
|
10
|
+
'editor.read',
|
|
11
|
+
'editor.edit',
|
|
12
|
+
'editor.admin',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
export type UserPermission = (typeof USER_PERMISIONS)[number];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TohokuCatalogEntry } from './toh';
|
|
2
|
+
import { SemVer } from './semver';
|
|
3
|
+
|
|
4
|
+
export type Work = {
|
|
5
|
+
uuid: string;
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
toh: TohokuCatalogEntry[];
|
|
9
|
+
publicationDate?: Date;
|
|
10
|
+
publicationVersion: SemVer;
|
|
11
|
+
pages: number;
|
|
12
|
+
restriction: boolean;
|
|
13
|
+
section: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type WorkDTO = {
|
|
17
|
+
uuid: string;
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
tohs: { toh: TohokuCatalogEntry }[];
|
|
21
|
+
publicationDate: string;
|
|
22
|
+
publicationVersion: string;
|
|
23
|
+
pages: number;
|
|
24
|
+
restriction: boolean;
|
|
25
|
+
breadcrumb?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const workFromDTO = (dto: WorkDTO) => ({
|
|
29
|
+
uuid: dto.uuid,
|
|
30
|
+
title: dto.title || '<Untitled>',
|
|
31
|
+
description: dto.description || '',
|
|
32
|
+
toh: dto.tohs.map((t) => t.toh) as TohokuCatalogEntry[],
|
|
33
|
+
publicationDate: dto.publicationDate ? new Date(dto.publicationDate) : undefined,
|
|
34
|
+
publicationVersion: (dto.publicationVersion || '0.0.0') as SemVer,
|
|
35
|
+
pages: dto.pages || 0,
|
|
36
|
+
restriction: dto.restriction,
|
|
37
|
+
section: dto.breadcrumb?.split('>').at(-2)?.trim() || '',
|
|
38
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
4
|
+
import { addBookmark, isBookmarked, removeBookmark } from './local-storage';
|
|
5
|
+
|
|
6
|
+
type BookmarkOptions = {
|
|
7
|
+
type: string;
|
|
8
|
+
subType?: string;
|
|
9
|
+
tab: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const listeners = new Set<() => void>();
|
|
13
|
+
|
|
14
|
+
function subscribe(callback: () => void) {
|
|
15
|
+
listeners.add(callback);
|
|
16
|
+
return () => listeners.delete(callback);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function emitChange() {
|
|
20
|
+
listeners.forEach((l) => l());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function useBookmark(uuid: string, options?: BookmarkOptions) {
|
|
24
|
+
const bookmarked = useSyncExternalStore(
|
|
25
|
+
subscribe,
|
|
26
|
+
() => isBookmarked(uuid),
|
|
27
|
+
() => false,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const toggle = useCallback(() => {
|
|
31
|
+
if (isBookmarked(uuid)) {
|
|
32
|
+
removeBookmark(uuid);
|
|
33
|
+
} else {
|
|
34
|
+
addBookmark({
|
|
35
|
+
uuid,
|
|
36
|
+
type: options?.type ?? '',
|
|
37
|
+
subType: options?.subType,
|
|
38
|
+
tab: options?.tab ?? '',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
emitChange();
|
|
42
|
+
}, [uuid, options?.type, options?.subType, options?.tab]);
|
|
43
|
+
|
|
44
|
+
return { isBookmarked: bookmarked, toggle };
|
|
45
|
+
}
|
package/src/ssr.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"allowJs": false,
|
|
5
|
+
"esModuleInterop": false,
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"strict": true
|
|
8
|
+
},
|
|
9
|
+
"files": [],
|
|
10
|
+
"include": [],
|
|
11
|
+
"references": [
|
|
12
|
+
{
|
|
13
|
+
"path": "./tsconfig.lib.json"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "./tsconfig.spec.json"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"extends": "../../tsconfig.base.json"
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"types": [
|
|
7
|
+
"node",
|
|
8
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
9
|
+
"@nx/react/typings/image.d.ts",
|
|
10
|
+
"next",
|
|
11
|
+
"@nx/next/typings/image.d.ts"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"exclude": [
|
|
15
|
+
"jest.config.ts",
|
|
16
|
+
"src/**/*.spec.ts",
|
|
17
|
+
"src/**/*.test.ts",
|
|
18
|
+
"src/**/*.spec.tsx",
|
|
19
|
+
"src/**/*.test.tsx",
|
|
20
|
+
"src/**/*.spec.js",
|
|
21
|
+
"src/**/*.test.js",
|
|
22
|
+
"src/**/*.spec.jsx",
|
|
23
|
+
"src/**/*.test.jsx"
|
|
24
|
+
],
|
|
25
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"moduleResolution": "node10",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"types": ["jest", "node"]
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"jest.config.ts",
|
|
12
|
+
"src/**/*.test.ts",
|
|
13
|
+
"src/**/*.spec.ts",
|
|
14
|
+
"src/**/*.test.tsx",
|
|
15
|
+
"src/**/*.spec.tsx",
|
|
16
|
+
"src/**/*.test.js",
|
|
17
|
+
"src/**/*.spec.js",
|
|
18
|
+
"src/**/*.test.jsx",
|
|
19
|
+
"src/**/*.spec.jsx",
|
|
20
|
+
"src/**/*.d.ts"
|
|
21
|
+
]
|
|
22
|
+
}
|