erudit 2.0.0-dev.8 → 3.0.0-dev.1
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/.nuxtrc +1 -1
- package/app/components/SiteMain.vue +2 -2
- package/app/components/aside/major/panes/Search.vue +10 -2
- package/app/components/aside/minor/AsideMinorContributor.vue +1 -1
- package/app/components/aside/minor/AsideMinorPane.vue +2 -3
- package/app/components/aside/minor/topic/TopicToc.vue +2 -1
- package/app/components/aside/minor/topic/TopicTocItem.vue +3 -3
- package/app/components/bitran/BitranContent.vue +20 -21
- package/app/components/bitran/RenderWrapper.vue +2 -4
- package/app/components/main/topic/MainTopic.vue +1 -1
- package/app/components/main/utils/ContentDescription.vue +3 -4
- package/app/components/main/utils/ContentFlag.vue +3 -4
- package/app/components/main/utils/ContentReferences.vue +16 -22
- package/app/components/main/utils/ContentSection.vue +21 -18
- package/app/components/main/utils/ContentTitle.vue +12 -10
- package/app/components/main/utils/reference/ReferenceGroup.vue +5 -8
- package/app/components/main/utils/reference/ReferenceItem.vue +25 -21
- package/app/components/main/utils/reference/ReferenceSource.vue +42 -36
- package/app/components/preview/PreviewLoading.vue +2 -3
- package/app/components/preview/display/Unique.vue +2 -2
- package/app/components/transition/Fade.vue +4 -7
- package/app/components/tree/TreeContainer.vue +2 -3
- package/app/composables/bitran.ts +127 -132
- package/app/composables/bitranContent.ts +37 -36
- package/app/composables/bitranLocation.ts +7 -7
- package/app/composables/contentData.ts +36 -36
- package/app/composables/contentPage.ts +156 -156
- package/app/composables/contentRoute.ts +45 -45
- package/app/composables/darkMagic.ts +24 -24
- package/app/composables/externalApi.ts +63 -63
- package/app/composables/favicon.ts +8 -8
- package/app/composables/formatText.ts +86 -86
- package/app/composables/majorPane.ts +60 -60
- package/app/composables/theme.ts +29 -29
- package/app/composables/url.ts +33 -33
- package/app/pages/article/[...articleId].vue +1 -1
- package/app/pages/group/[...groupId].vue +2 -1
- package/app/pages/members.vue +2 -3
- package/app/pages/practice/[...practice].vue +1 -1
- package/app/pages/summary/[...summaryId].vue +1 -1
- package/app/public/favicon/article.svg +9 -9
- package/app/public/favicon/default.svg +9 -9
- package/app/public/favicon/practice.svg +9 -9
- package/app/public/favicon/summary.svg +9 -9
- package/app/public/logotype.svg +16 -16
- package/app/public/user.svg +9 -9
- package/app/scripts/_immediate.js +7 -2
- package/app/scripts/aside/index.ts +59 -59
- package/app/scripts/aside/major/nav.ts +26 -26
- package/app/scripts/aside/minor/state.ts +37 -37
- package/app/scripts/aside/minor/topic.ts +3 -3
- package/app/scripts/preview/build.ts +73 -84
- package/app/scripts/preview/data/alert.ts +19 -19
- package/app/scripts/preview/data/custom.ts +8 -8
- package/app/scripts/preview/data/genericLink.ts +24 -24
- package/app/scripts/preview/data/pageLink.ts +20 -20
- package/app/scripts/preview/data/unique.ts +70 -70
- package/app/scripts/preview/data.ts +24 -26
- package/app/scripts/preview/display.ts +37 -39
- package/app/scripts/preview/footer.ts +9 -9
- package/app/scripts/preview/request.ts +51 -51
- package/app/scripts/preview/state.ts +63 -63
- package/app/styles/_immediate.css +6 -2
- package/app/styles/_util.scss +13 -20
- package/app/styles/app.scss +91 -91
- package/app/styles/def/_bp.scss +27 -24
- package/app/styles/def/_size.scss +7 -7
- package/app/styles/def/_z.scss +5 -5
- package/app/styles/default.scss +33 -35
- package/app/styles/normalize.scss +63 -63
- package/app/styles/partials/_darkMagic.scss +3 -5
- package/app/styles/partials/_fnav.scss +4 -7
- package/app/styles/partials/_preview.scss +3 -5
- package/globals/bitran.ts +47 -39
- package/globals/content.ts +22 -22
- package/globals/contributor.ts +5 -5
- package/module/bitran.ts +34 -34
- package/module/index.ts +12 -0
- package/module/paths.ts +22 -22
- package/nuxt.config.ts +20 -5
- package/package.json +9 -6
- package/server/api/contributor/count.ts +6 -6
- package/server/api/fake/content.ts +6 -6
- package/server/api/preview/page/[...parts].ts +1 -1
- package/server/plugin/bitran/content.ts +187 -176
- package/server/plugin/bitran/location.ts +25 -25
- package/server/plugin/bitran/products/include.ts +230 -229
- package/server/plugin/bitran/products/link.ts +116 -114
- package/server/plugin/bitran/setup.ts +9 -10
- package/server/plugin/bitran/toc.ts +83 -82
- package/server/plugin/bitran/transpiler.ts +46 -0
- package/server/plugin/build/jobs/content/builderArgs.ts +8 -8
- package/server/plugin/build/jobs/content/generic.ts +176 -176
- package/server/plugin/build/jobs/content/parse.ts +100 -90
- package/server/plugin/build/jobs/content/path.ts +6 -6
- package/server/plugin/build/jobs/content/type/book.ts +9 -9
- package/server/plugin/build/jobs/content/type/group.ts +37 -37
- package/server/plugin/build/jobs/content/type/topic.ts +36 -36
- package/server/plugin/build/jobs/contributors.ts +66 -66
- package/server/plugin/build/jobs/nav.ts +209 -209
- package/server/plugin/content/absoluteId.ts +94 -94
- package/server/plugin/content/context.ts +112 -112
- package/server/plugin/db/entities/Book.ts +7 -7
- package/server/plugin/db/entities/Content.ts +49 -49
- package/server/plugin/db/entities/Contribution.ts +10 -10
- package/server/plugin/db/entities/Contributor.ts +16 -16
- package/server/plugin/db/entities/Group.ts +14 -14
- package/server/plugin/db/entities/Hash.ts +15 -15
- package/server/plugin/db/entities/Topic.ts +20 -20
- package/server/plugin/db/entities/Unique.ts +21 -21
- package/server/plugin/db/setup.ts +34 -34
- package/server/plugin/nav/node.ts +26 -26
- package/server/plugin/nav/utils.ts +129 -129
- package/server/plugin/repository/book.ts +21 -21
- package/server/plugin/repository/content.ts +238 -238
- package/server/plugin/repository/contributor.ts +8 -8
- package/server/plugin/repository/frontNav.ts +148 -148
- package/server/plugin/repository/topic.ts +32 -32
- package/shared/aside/minor.ts +50 -50
- package/shared/asset.ts +15 -15
- package/shared/bitran/context.ts +8 -7
- package/shared/bitran/default.ts +46 -0
- package/shared/bitran/{products/link/render → link}/Link.vue +167 -174
- package/shared/bitran/link/factory.ts +24 -0
- package/shared/bitran/link/languages/en.ts +7 -0
- package/shared/bitran/link/languages/ru.ts +7 -0
- package/shared/bitran/link/renderer.ts +21 -0
- package/shared/bitran/link/shared.ts +17 -0
- package/shared/bitran/{products/link → link}/target.ts +134 -134
- package/shared/bitran/link/transpiler.ts +10 -0
- package/shared/bitran/location.ts +166 -166
- package/shared/bitran/toc.ts +8 -8
- package/shared/contributor.ts +5 -5
- package/shared/frontNav.ts +41 -41
- package/shared/icons.ts +38 -38
- package/shared/image.ts +5 -5
- package/shared/utils/objectsEqual.ts +4 -4
- package/shared/utils/stringColor.ts +9 -9
- package/test/bitran/{products/link → link}/target.test.ts +141 -138
- package/test/bitran/location.test.ts +143 -143
- package/server/plugin/bitran/core.ts +0 -51
- package/shared/bitran/alias.ts +0 -17
- package/shared/bitran/products/alias/core/factory.ts +0 -46
- package/shared/bitran/products/alias/core/index.ts +0 -13
- package/shared/bitran/products/alias/render/Alias.vue +0 -10
- package/shared/bitran/products/alias/render/icon.svg +0 -3
- package/shared/bitran/products/alias/render/index.ts +0 -17
- package/shared/bitran/products/alias/render/languages/en.ts +0 -5
- package/shared/bitran/products/alias/render/languages/ru.ts +0 -5
- package/shared/bitran/products/alias/shared.ts +0 -11
- package/shared/bitran/products/heading/core/factory.ts +0 -53
- package/shared/bitran/products/heading/core/index.ts +0 -19
- package/shared/bitran/products/heading/render/Heading.vue +0 -47
- package/shared/bitran/products/heading/render/icon.svg +0 -3
- package/shared/bitran/products/heading/render/index.ts +0 -17
- package/shared/bitran/products/heading/render/languages/en.ts +0 -5
- package/shared/bitran/products/heading/render/languages/ru.ts +0 -5
- package/shared/bitran/products/heading/shared.ts +0 -13
- package/shared/bitran/products/include/core/factory.ts +0 -61
- package/shared/bitran/products/include/core/index.ts +0 -13
- package/shared/bitran/products/include/render/Include.vue +0 -13
- package/shared/bitran/products/include/render/icon.svg +0 -3
- package/shared/bitran/products/include/render/index.ts +0 -18
- package/shared/bitran/products/include/render/languages/en.ts +0 -5
- package/shared/bitran/products/include/render/languages/ru.ts +0 -5
- package/shared/bitran/products/include/shared.ts +0 -15
- package/shared/bitran/products/link/core/factory.ts +0 -20
- package/shared/bitran/products/link/core/index.ts +0 -17
- package/shared/bitran/products/link/render/index.ts +0 -17
- package/shared/bitran/products/link/render/languages/en.ts +0 -5
- package/shared/bitran/products/link/render/languages/ru.ts +0 -5
- package/shared/bitran/products/link/shared.ts +0 -15
- package/test/bitran/alias.test.ts +0 -44
- package/test/bitran/products/alias.test.ts +0 -83
- package/test/bitran/products/heading.test.ts +0 -119
- package/test/bitran/products/include.test.ts +0 -77
- package/test/bitran/products/link/factory.test.ts +0 -30
- /package/shared/bitran/{products/link/render → link}/icon.svg +0 -0
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import { isTopicPart } from 'erudit-cog/schema';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
parseBitranLocation,
|
|
5
|
-
stringifyBitranLocation,
|
|
6
|
-
type BitranLocation,
|
|
7
|
-
} from '@shared/bitran/location';
|
|
8
|
-
import { getNavBookOf } from '../nav/utils';
|
|
9
|
-
|
|
10
|
-
export function toAbsoluteContentLocation<T extends string | BitranLocation>(
|
|
11
|
-
location: T,
|
|
12
|
-
contextContentId: string,
|
|
13
|
-
): T {
|
|
14
|
-
const isLocationStr = typeof location === 'string';
|
|
15
|
-
const parsedLocation = isLocationStr
|
|
16
|
-
? parseBitranLocation(location)
|
|
17
|
-
: (location as BitranLocation);
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
isTopicPart(parsedLocation.type) ||
|
|
21
|
-
['book', 'group', 'topic'].includes(parsedLocation.type)
|
|
22
|
-
) {
|
|
23
|
-
parsedLocation.path = toAbsoluteContentId(
|
|
24
|
-
parsedLocation.path!,
|
|
25
|
-
contextContentId,
|
|
26
|
-
);
|
|
27
|
-
return (
|
|
28
|
-
isLocationStr
|
|
29
|
-
? stringifyBitranLocation(parsedLocation)
|
|
30
|
-
: parsedLocation
|
|
31
|
-
) as T;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return location;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function toAbsoluteContentId(
|
|
38
|
-
path: string,
|
|
39
|
-
contextContentId: string = '',
|
|
40
|
-
) {
|
|
41
|
-
const fullPath = (() => {
|
|
42
|
-
if (path.startsWith('..'))
|
|
43
|
-
return (contextContentId ? contextContentId + '/' : '') + path;
|
|
44
|
-
|
|
45
|
-
if (path.startsWith('.'))
|
|
46
|
-
return trimEdgeSlashes(contextContentId + path.substring(1));
|
|
47
|
-
|
|
48
|
-
if (path.startsWith('~'))
|
|
49
|
-
return trimEdgeSlashes(
|
|
50
|
-
tryGetParentBook(contextContentId) + path.substring(1),
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
return path;
|
|
54
|
-
})();
|
|
55
|
-
|
|
56
|
-
const reversePathParts = fullPath.split('/').reverse();
|
|
57
|
-
const finalParts: string[] = [];
|
|
58
|
-
|
|
59
|
-
let skipCounter = 0;
|
|
60
|
-
|
|
61
|
-
for (let i = 0; i < reversePathParts.length; i++) {
|
|
62
|
-
const part = reversePathParts[i];
|
|
63
|
-
|
|
64
|
-
if (part === '..') {
|
|
65
|
-
skipCounter++;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (skipCounter) {
|
|
70
|
-
skipCounter--;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
finalParts.unshift(part!);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return finalParts.join('/');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function trimEdgeSlashes(path: string) {
|
|
81
|
-
if (path.startsWith('/')) path = path.substring(1);
|
|
82
|
-
|
|
83
|
-
if (path.endsWith('/')) path = path.substring(0, path.length - 1);
|
|
84
|
-
|
|
85
|
-
return path;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function tryGetParentBook(contentId: string): string {
|
|
89
|
-
const navBook = getNavBookOf(contentId);
|
|
90
|
-
|
|
91
|
-
if (!navBook) return '';
|
|
92
|
-
|
|
93
|
-
return navBook.id;
|
|
94
|
-
}
|
|
1
|
+
import { isTopicPart } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
parseBitranLocation,
|
|
5
|
+
stringifyBitranLocation,
|
|
6
|
+
type BitranLocation,
|
|
7
|
+
} from '@shared/bitran/location';
|
|
8
|
+
import { getNavBookOf } from '../nav/utils';
|
|
9
|
+
|
|
10
|
+
export function toAbsoluteContentLocation<T extends string | BitranLocation>(
|
|
11
|
+
location: T,
|
|
12
|
+
contextContentId: string,
|
|
13
|
+
): T {
|
|
14
|
+
const isLocationStr = typeof location === 'string';
|
|
15
|
+
const parsedLocation = isLocationStr
|
|
16
|
+
? parseBitranLocation(location)
|
|
17
|
+
: (location as BitranLocation);
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
isTopicPart(parsedLocation.type) ||
|
|
21
|
+
['book', 'group', 'topic'].includes(parsedLocation.type)
|
|
22
|
+
) {
|
|
23
|
+
parsedLocation.path = toAbsoluteContentId(
|
|
24
|
+
parsedLocation.path!,
|
|
25
|
+
contextContentId,
|
|
26
|
+
);
|
|
27
|
+
return (
|
|
28
|
+
isLocationStr
|
|
29
|
+
? stringifyBitranLocation(parsedLocation)
|
|
30
|
+
: parsedLocation
|
|
31
|
+
) as T;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return location;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function toAbsoluteContentId(
|
|
38
|
+
path: string,
|
|
39
|
+
contextContentId: string = '',
|
|
40
|
+
) {
|
|
41
|
+
const fullPath = (() => {
|
|
42
|
+
if (path.startsWith('..'))
|
|
43
|
+
return (contextContentId ? contextContentId + '/' : '') + path;
|
|
44
|
+
|
|
45
|
+
if (path.startsWith('.'))
|
|
46
|
+
return trimEdgeSlashes(contextContentId + path.substring(1));
|
|
47
|
+
|
|
48
|
+
if (path.startsWith('~'))
|
|
49
|
+
return trimEdgeSlashes(
|
|
50
|
+
tryGetParentBook(contextContentId) + path.substring(1),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return path;
|
|
54
|
+
})();
|
|
55
|
+
|
|
56
|
+
const reversePathParts = fullPath.split('/').reverse();
|
|
57
|
+
const finalParts: string[] = [];
|
|
58
|
+
|
|
59
|
+
let skipCounter = 0;
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < reversePathParts.length; i++) {
|
|
62
|
+
const part = reversePathParts[i];
|
|
63
|
+
|
|
64
|
+
if (part === '..') {
|
|
65
|
+
skipCounter++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (skipCounter) {
|
|
70
|
+
skipCounter--;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
finalParts.unshift(part!);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return finalParts.join('/');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function trimEdgeSlashes(path: string) {
|
|
81
|
+
if (path.startsWith('/')) path = path.substring(1);
|
|
82
|
+
|
|
83
|
+
if (path.endsWith('/')) path = path.substring(0, path.length - 1);
|
|
84
|
+
|
|
85
|
+
return path;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function tryGetParentBook(contentId: string): string {
|
|
89
|
+
const navBook = getNavBookOf(contentId);
|
|
90
|
+
|
|
91
|
+
if (!navBook) return '';
|
|
92
|
+
|
|
93
|
+
return navBook.id;
|
|
94
|
+
}
|
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
import { isContentType, isTopicPart, type TopicPart } from 'erudit-cog/schema';
|
|
2
|
-
|
|
3
|
-
import { ERUDIT_SERVER } from '@server/global';
|
|
4
|
-
import { getIdsUp, isSkipId } from '@server/nav/utils';
|
|
5
|
-
import { DbContent } from '@server/db/entities/Content';
|
|
6
|
-
import { DbContributor } from '@server/db/entities/Contributor';
|
|
7
|
-
|
|
8
|
-
import type { Context } from '@shared/content/context';
|
|
9
|
-
import {
|
|
10
|
-
createContentLink,
|
|
11
|
-
createContributorLink,
|
|
12
|
-
createTopicPartLink,
|
|
13
|
-
} from '@shared/link';
|
|
14
|
-
import { CONTENT_TYPE_ICON, ICON, TOPIC_PART_ICON } from '@erudit/shared/icons';
|
|
15
|
-
import type { BitranLocation } from '@erudit/shared/bitran/location';
|
|
16
|
-
|
|
17
|
-
export async function getContentContext(contentId: string): Promise<Context> {
|
|
18
|
-
const context: Context = [];
|
|
19
|
-
|
|
20
|
-
for (const _contentId of (await getIdsUp(contentId)).reverse()) {
|
|
21
|
-
const dbContent = await getDbContent(_contentId);
|
|
22
|
-
|
|
23
|
-
context.push({
|
|
24
|
-
type: ERUDIT_SERVER.LANGUAGE.phrases[dbContent.type],
|
|
25
|
-
icon: isTopicPart(dbContent.type)
|
|
26
|
-
? TOPIC_PART_ICON[dbContent.type]
|
|
27
|
-
: isContentType(dbContent.type)
|
|
28
|
-
? CONTENT_TYPE_ICON[dbContent.type]
|
|
29
|
-
: '',
|
|
30
|
-
title: dbContent.title || dbContent.contentId,
|
|
31
|
-
href: createContentLink(dbContent.type, dbContent.contentId),
|
|
32
|
-
hidden: await isSkipId(dbContent.contentId),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return context;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function getTopicPartContext(
|
|
40
|
-
topicPart: TopicPart,
|
|
41
|
-
contentId: string,
|
|
42
|
-
): Promise<Context> {
|
|
43
|
-
const context = await getContentContext(contentId);
|
|
44
|
-
const topicItem = context.pop()!;
|
|
45
|
-
|
|
46
|
-
topicItem.type = ERUDIT_SERVER.LANGUAGE.phrases[topicPart];
|
|
47
|
-
topicItem.icon = TOPIC_PART_ICON[topicPart];
|
|
48
|
-
topicItem.href = createTopicPartLink(topicPart, contentId);
|
|
49
|
-
|
|
50
|
-
return context.concat([topicItem]);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export async function getContributorContext(
|
|
54
|
-
contributorId: string,
|
|
55
|
-
): Promise<Context> {
|
|
56
|
-
const dbContributor = await ERUDIT_SERVER.DB.manager.findOne(
|
|
57
|
-
DbContributor,
|
|
58
|
-
{
|
|
59
|
-
select: ['displayName'],
|
|
60
|
-
where: { contributorId },
|
|
61
|
-
},
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
if (!dbContributor)
|
|
65
|
-
throw new Error(`Contributor "${contributorId}" not found!`);
|
|
66
|
-
|
|
67
|
-
return [
|
|
68
|
-
{
|
|
69
|
-
type: ERUDIT_SERVER.LANGUAGE.phrases.contributor,
|
|
70
|
-
icon: ICON.contributor,
|
|
71
|
-
title: dbContributor.displayName || contributorId,
|
|
72
|
-
href: createContributorLink(contributorId),
|
|
73
|
-
hidden: false,
|
|
74
|
-
},
|
|
75
|
-
];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export async function getLocationContext(
|
|
79
|
-
location: BitranLocation,
|
|
80
|
-
): Promise<Context> {
|
|
81
|
-
const contentId = location.path!;
|
|
82
|
-
|
|
83
|
-
switch (location.type) {
|
|
84
|
-
case 'article':
|
|
85
|
-
case 'summary':
|
|
86
|
-
case 'practice':
|
|
87
|
-
return await getTopicPartContext(location.type, contentId);
|
|
88
|
-
case 'group':
|
|
89
|
-
return await getContentContext(contentId);
|
|
90
|
-
case 'contributor':
|
|
91
|
-
return await getContributorContext(contentId);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
throw new Error(
|
|
95
|
-
`Cant' build context for location unknown type "${location.type}"!`,
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
async function getDbContent(contentId: string): Promise<DbContent> {
|
|
104
|
-
const dbContent = await ERUDIT_SERVER.DB.manager.findOne(DbContent, {
|
|
105
|
-
select: ['type', 'title', 'fullId', 'contentId'],
|
|
106
|
-
where: { contentId },
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if (!dbContent) throw new Error(`Content "${contentId}" not found!`);
|
|
110
|
-
|
|
111
|
-
return dbContent;
|
|
112
|
-
}
|
|
1
|
+
import { isContentType, isTopicPart, type TopicPart } from 'erudit-cog/schema';
|
|
2
|
+
|
|
3
|
+
import { ERUDIT_SERVER } from '@server/global';
|
|
4
|
+
import { getIdsUp, isSkipId } from '@server/nav/utils';
|
|
5
|
+
import { DbContent } from '@server/db/entities/Content';
|
|
6
|
+
import { DbContributor } from '@server/db/entities/Contributor';
|
|
7
|
+
|
|
8
|
+
import type { Context } from '@shared/content/context';
|
|
9
|
+
import {
|
|
10
|
+
createContentLink,
|
|
11
|
+
createContributorLink,
|
|
12
|
+
createTopicPartLink,
|
|
13
|
+
} from '@shared/link';
|
|
14
|
+
import { CONTENT_TYPE_ICON, ICON, TOPIC_PART_ICON } from '@erudit/shared/icons';
|
|
15
|
+
import type { BitranLocation } from '@erudit/shared/bitran/location';
|
|
16
|
+
|
|
17
|
+
export async function getContentContext(contentId: string): Promise<Context> {
|
|
18
|
+
const context: Context = [];
|
|
19
|
+
|
|
20
|
+
for (const _contentId of (await getIdsUp(contentId)).reverse()) {
|
|
21
|
+
const dbContent = await getDbContent(_contentId);
|
|
22
|
+
|
|
23
|
+
context.push({
|
|
24
|
+
type: ERUDIT_SERVER.LANGUAGE.phrases[dbContent.type],
|
|
25
|
+
icon: isTopicPart(dbContent.type)
|
|
26
|
+
? TOPIC_PART_ICON[dbContent.type]
|
|
27
|
+
: isContentType(dbContent.type)
|
|
28
|
+
? CONTENT_TYPE_ICON[dbContent.type]
|
|
29
|
+
: '',
|
|
30
|
+
title: dbContent.title || dbContent.contentId,
|
|
31
|
+
href: createContentLink(dbContent.type, dbContent.contentId),
|
|
32
|
+
hidden: await isSkipId(dbContent.contentId),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return context;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function getTopicPartContext(
|
|
40
|
+
topicPart: TopicPart,
|
|
41
|
+
contentId: string,
|
|
42
|
+
): Promise<Context> {
|
|
43
|
+
const context = await getContentContext(contentId);
|
|
44
|
+
const topicItem = context.pop()!;
|
|
45
|
+
|
|
46
|
+
topicItem.type = ERUDIT_SERVER.LANGUAGE.phrases[topicPart];
|
|
47
|
+
topicItem.icon = TOPIC_PART_ICON[topicPart];
|
|
48
|
+
topicItem.href = createTopicPartLink(topicPart, contentId);
|
|
49
|
+
|
|
50
|
+
return context.concat([topicItem]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function getContributorContext(
|
|
54
|
+
contributorId: string,
|
|
55
|
+
): Promise<Context> {
|
|
56
|
+
const dbContributor = await ERUDIT_SERVER.DB.manager.findOne(
|
|
57
|
+
DbContributor,
|
|
58
|
+
{
|
|
59
|
+
select: ['displayName'],
|
|
60
|
+
where: { contributorId },
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (!dbContributor)
|
|
65
|
+
throw new Error(`Contributor "${contributorId}" not found!`);
|
|
66
|
+
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
type: ERUDIT_SERVER.LANGUAGE.phrases.contributor,
|
|
70
|
+
icon: ICON.contributor,
|
|
71
|
+
title: dbContributor.displayName || contributorId,
|
|
72
|
+
href: createContributorLink(contributorId),
|
|
73
|
+
hidden: false,
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function getLocationContext(
|
|
79
|
+
location: BitranLocation,
|
|
80
|
+
): Promise<Context> {
|
|
81
|
+
const contentId = location.path!;
|
|
82
|
+
|
|
83
|
+
switch (location.type) {
|
|
84
|
+
case 'article':
|
|
85
|
+
case 'summary':
|
|
86
|
+
case 'practice':
|
|
87
|
+
return await getTopicPartContext(location.type, contentId);
|
|
88
|
+
case 'group':
|
|
89
|
+
return await getContentContext(contentId);
|
|
90
|
+
case 'contributor':
|
|
91
|
+
return await getContributorContext(contentId);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Cant' build context for location unknown type "${location.type}"!`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//
|
|
100
|
+
//
|
|
101
|
+
//
|
|
102
|
+
|
|
103
|
+
async function getDbContent(contentId: string): Promise<DbContent> {
|
|
104
|
+
const dbContent = await ERUDIT_SERVER.DB.manager.findOne(DbContent, {
|
|
105
|
+
select: ['type', 'title', 'fullId', 'contentId'],
|
|
106
|
+
where: { contentId },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (!dbContent) throw new Error(`Content "${contentId}" not found!`);
|
|
110
|
+
|
|
111
|
+
return dbContent;
|
|
112
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
@Entity('book')
|
|
4
|
-
export class DbBook {
|
|
5
|
-
@PrimaryColumn('varchar')
|
|
6
|
-
contentId!: string;
|
|
7
|
-
}
|
|
1
|
+
import { Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
@Entity('book')
|
|
4
|
+
export class DbBook {
|
|
5
|
+
@PrimaryColumn('varchar')
|
|
6
|
+
contentId!: string;
|
|
7
|
+
}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
|
2
|
-
import type {
|
|
3
|
-
ContentFlag,
|
|
4
|
-
ContentReferences,
|
|
5
|
-
ContentSeo,
|
|
6
|
-
ContentType,
|
|
7
|
-
} from 'erudit-cog/schema';
|
|
8
|
-
|
|
9
|
-
import type { ImageData } from '@erudit/shared/image';
|
|
10
|
-
|
|
11
|
-
@Entity('content')
|
|
12
|
-
export class DbContent {
|
|
13
|
-
@PrimaryColumn('varchar')
|
|
14
|
-
contentId!: string;
|
|
15
|
-
|
|
16
|
-
@Column('varchar')
|
|
17
|
-
@Index({ unique: true })
|
|
18
|
-
fullId!: string;
|
|
19
|
-
|
|
20
|
-
@Column('varchar')
|
|
21
|
-
type!: ContentType;
|
|
22
|
-
|
|
23
|
-
@Column('varchar', { nullable: true })
|
|
24
|
-
title?: string;
|
|
25
|
-
|
|
26
|
-
@Column('varchar', { nullable: true })
|
|
27
|
-
navTitle?: string;
|
|
28
|
-
|
|
29
|
-
@Column('text', { nullable: true })
|
|
30
|
-
description?: string;
|
|
31
|
-
|
|
32
|
-
@Column('simple-json', { nullable: true })
|
|
33
|
-
flags?: Record<ContentFlag, boolean>;
|
|
34
|
-
|
|
35
|
-
@Column('varchar', { nullable: true })
|
|
36
|
-
decoration?: string;
|
|
37
|
-
|
|
38
|
-
@Column('simple-json', { nullable: true })
|
|
39
|
-
seo?: Partial<ContentSeo>;
|
|
40
|
-
|
|
41
|
-
@Column('simple-json', { nullable: true })
|
|
42
|
-
ogImage?: ImageData;
|
|
43
|
-
|
|
44
|
-
@Column('simple-array', { nullable: true })
|
|
45
|
-
dependencies?: string[];
|
|
46
|
-
|
|
47
|
-
@Column('simple-json', { nullable: true })
|
|
48
|
-
references?: ContentReferences;
|
|
49
|
-
}
|
|
1
|
+
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
|
2
|
+
import type {
|
|
3
|
+
ContentFlag,
|
|
4
|
+
ContentReferences,
|
|
5
|
+
ContentSeo,
|
|
6
|
+
ContentType,
|
|
7
|
+
} from 'erudit-cog/schema';
|
|
8
|
+
|
|
9
|
+
import type { ImageData } from '@erudit/shared/image';
|
|
10
|
+
|
|
11
|
+
@Entity('content')
|
|
12
|
+
export class DbContent {
|
|
13
|
+
@PrimaryColumn('varchar')
|
|
14
|
+
contentId!: string;
|
|
15
|
+
|
|
16
|
+
@Column('varchar')
|
|
17
|
+
@Index({ unique: true })
|
|
18
|
+
fullId!: string;
|
|
19
|
+
|
|
20
|
+
@Column('varchar')
|
|
21
|
+
type!: ContentType;
|
|
22
|
+
|
|
23
|
+
@Column('varchar', { nullable: true })
|
|
24
|
+
title?: string;
|
|
25
|
+
|
|
26
|
+
@Column('varchar', { nullable: true })
|
|
27
|
+
navTitle?: string;
|
|
28
|
+
|
|
29
|
+
@Column('text', { nullable: true })
|
|
30
|
+
description?: string;
|
|
31
|
+
|
|
32
|
+
@Column('simple-json', { nullable: true })
|
|
33
|
+
flags?: Record<ContentFlag, boolean>;
|
|
34
|
+
|
|
35
|
+
@Column('varchar', { nullable: true })
|
|
36
|
+
decoration?: string;
|
|
37
|
+
|
|
38
|
+
@Column('simple-json', { nullable: true })
|
|
39
|
+
seo?: Partial<ContentSeo>;
|
|
40
|
+
|
|
41
|
+
@Column('simple-json', { nullable: true })
|
|
42
|
+
ogImage?: ImageData;
|
|
43
|
+
|
|
44
|
+
@Column('simple-array', { nullable: true })
|
|
45
|
+
dependencies?: string[];
|
|
46
|
+
|
|
47
|
+
@Column('simple-json', { nullable: true })
|
|
48
|
+
references?: ContentReferences;
|
|
49
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
@Entity('contribution')
|
|
4
|
-
export class DbContribution {
|
|
5
|
-
@PrimaryColumn('varchar')
|
|
6
|
-
contentId!: string;
|
|
7
|
-
|
|
8
|
-
@PrimaryColumn('varchar')
|
|
9
|
-
contributorId!: string;
|
|
10
|
-
}
|
|
1
|
+
import { Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
@Entity('contribution')
|
|
4
|
+
export class DbContribution {
|
|
5
|
+
@PrimaryColumn('varchar')
|
|
6
|
+
contentId!: string;
|
|
7
|
+
|
|
8
|
+
@PrimaryColumn('varchar')
|
|
9
|
+
contributorId!: string;
|
|
10
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
@Entity('contributor')
|
|
4
|
-
export class DbContributor {
|
|
5
|
-
@PrimaryColumn('varchar')
|
|
6
|
-
contributorId!: string;
|
|
7
|
-
|
|
8
|
-
@Column('varchar', { nullable: true })
|
|
9
|
-
displayName?: string;
|
|
10
|
-
|
|
11
|
-
@Column('text', { nullable: true })
|
|
12
|
-
description?: string;
|
|
13
|
-
|
|
14
|
-
@Column('varchar', { nullable: true })
|
|
15
|
-
avatar?: string;
|
|
16
|
-
}
|
|
1
|
+
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
@Entity('contributor')
|
|
4
|
+
export class DbContributor {
|
|
5
|
+
@PrimaryColumn('varchar')
|
|
6
|
+
contributorId!: string;
|
|
7
|
+
|
|
8
|
+
@Column('varchar', { nullable: true })
|
|
9
|
+
displayName?: string;
|
|
10
|
+
|
|
11
|
+
@Column('text', { nullable: true })
|
|
12
|
+
description?: string;
|
|
13
|
+
|
|
14
|
+
@Column('varchar', { nullable: true })
|
|
15
|
+
avatar?: string;
|
|
16
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
-
import type { GroupType } from 'erudit-cog/schema';
|
|
3
|
-
|
|
4
|
-
@Entity('group')
|
|
5
|
-
export class DbGroup {
|
|
6
|
-
@PrimaryColumn('varchar')
|
|
7
|
-
contentId!: string;
|
|
8
|
-
|
|
9
|
-
@Column('varchar')
|
|
10
|
-
type!: GroupType;
|
|
11
|
-
|
|
12
|
-
@Column('text', { nullable: true })
|
|
13
|
-
content?: string;
|
|
14
|
-
}
|
|
1
|
+
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
+
import type { GroupType } from 'erudit-cog/schema';
|
|
3
|
+
|
|
4
|
+
@Entity('group')
|
|
5
|
+
export class DbGroup {
|
|
6
|
+
@PrimaryColumn('varchar')
|
|
7
|
+
contentId!: string;
|
|
8
|
+
|
|
9
|
+
@Column('varchar')
|
|
10
|
+
type!: GroupType;
|
|
11
|
+
|
|
12
|
+
@Column('text', { nullable: true })
|
|
13
|
+
content?: string;
|
|
14
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* TODO:
|
|
5
|
-
* Create hash of Bitran content of content items and use it to distinguish between content item version.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
@Entity('hash')
|
|
9
|
-
export class DbHash {
|
|
10
|
-
@PrimaryColumn('varchar')
|
|
11
|
-
id!: string;
|
|
12
|
-
|
|
13
|
-
@Column('varchar')
|
|
14
|
-
hash!: string;
|
|
15
|
-
}
|
|
1
|
+
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TODO:
|
|
5
|
+
* Create hash of Bitran content of content items and use it to distinguish between content item version.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
@Entity('hash')
|
|
9
|
+
export class DbHash {
|
|
10
|
+
@PrimaryColumn('varchar')
|
|
11
|
+
id!: string;
|
|
12
|
+
|
|
13
|
+
@Column('varchar')
|
|
14
|
+
hash!: string;
|
|
15
|
+
}
|