erudit 3.0.0-dev.11 → 3.0.0-dev.12
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/app/components/SiteMain.vue +1 -1
- package/app/components/aside/major/panes/nav/Nav.vue +11 -6
- package/app/components/aside/major/panes/nav/fnav/FNavFlags.vue +1 -1
- package/app/components/aside/minor/Contribute.vue +2 -2
- package/app/components/aside/minor/content/AsideMinorContent.vue +1 -1
- package/app/components/aside/minor/topic/AsideMinorTopic.vue +1 -1
- package/app/components/aside/minor/topic/TopicContributors.vue +2 -2
- package/app/components/aside/minor/topic/TopicToc.vue +1 -6
- package/app/components/aside/minor/topic/TopicTocItem.vue +3 -1
- package/app/components/main/utils/Breadcrumb.vue +1 -1
- package/app/components/preview/PreviewScreen.vue +2 -2
- package/app/components/preview/display/PageLink.vue +1 -1
- package/app/composables/bitranContent.ts +3 -3
- package/app/composables/contentPage.ts +8 -7
- package/app/composables/formatText.ts +21 -8
- package/app/composables/phrases.ts +0 -16
- package/app/plugins/prerender.server.ts +22 -0
- package/app/scripts/preview/build.ts +1 -5
- package/app/scripts/preview/data/pageLink.ts +1 -0
- package/app/styles/normalize.scss +0 -14
- package/globals/content.ts +5 -0
- package/module/imports.ts +1 -0
- package/nuxt.config.ts +1 -5
- package/package.json +8 -8
- package/server/api/aside/minor/path.ts +19 -11
- package/server/api/bitran/content/[...location].ts +4 -2
- package/server/api/bitran/toc/[...location].ts +4 -2
- package/server/api/content/data.ts +5 -2
- package/server/api/prerender.ts +120 -0
- package/server/api/preview/page/[...parts].ts +30 -4
- package/server/api/preview/unique/{[location].ts → [...location].ts} +4 -3
- package/server/plugin/bitran/content.ts +3 -16
- package/server/plugin/bitran/elements/include.ts +13 -16
- package/server/plugin/bitran/location.ts +24 -10
- package/server/plugin/bitran/toc.ts +7 -2
- package/server/plugin/bitran/transpiler.ts +10 -1
- package/server/plugin/build/jobs/content/generic.ts +10 -5
- package/server/plugin/build/jobs/content/type/group.ts +2 -2
- package/server/plugin/build/jobs/content/type/topic.ts +2 -2
- package/server/plugin/build/jobs/nav.ts +8 -11
- package/server/plugin/content/context.ts +4 -1
- package/server/plugin/db/entities/Content.ts +0 -4
- package/server/plugin/db/entities/ContentId.ts +11 -0
- package/server/plugin/db/setup.ts +3 -1
- package/server/plugin/importer.ts +5 -1
- package/server/plugin/nav/utils.ts +4 -4
- package/server/plugin/repository/content.ts +4 -12
- package/server/plugin/repository/contentId.ts +26 -0
- package/server/plugin/repository/frontNav.ts +4 -4
- package/server/plugin/repository/topic.ts +4 -1
- package/shared/aside/minor.ts +2 -2
- package/shared/bitran/contentId.ts +4 -4
- package/shared/content/bookId.ts +11 -0
- package/shared/frontNav.ts +1 -1
|
@@ -46,7 +46,7 @@ export async function getPreviousNextNav(contentId: string) {
|
|
|
46
46
|
let finish = false;
|
|
47
47
|
|
|
48
48
|
await walkNav(async (navNode) => {
|
|
49
|
-
if (navNode.
|
|
49
|
+
if (navNode.fullId === contentId) {
|
|
50
50
|
book = getNavBookOf(navNode);
|
|
51
51
|
finish = true;
|
|
52
52
|
return;
|
|
@@ -94,7 +94,7 @@ export async function getNavNode(
|
|
|
94
94
|
let navNode: NavNode | undefined;
|
|
95
95
|
|
|
96
96
|
await walkNav(async (_navNode) => {
|
|
97
|
-
if (_navNode.
|
|
97
|
+
if (_navNode.fullId === contentId) {
|
|
98
98
|
navNode = _navNode;
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
@@ -112,7 +112,7 @@ export async function getIdsUp(contentId: string): Promise<string[]> {
|
|
|
112
112
|
|
|
113
113
|
let currentNavNode: any = startNavNode;
|
|
114
114
|
while (currentNavNode?.id) {
|
|
115
|
-
ids.push(currentNavNode.
|
|
115
|
+
ids.push(currentNavNode.fullId);
|
|
116
116
|
currentNavNode = currentNavNode.parent;
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -123,7 +123,7 @@ export async function isSkipId(contentId: string) {
|
|
|
123
123
|
let hidden = false;
|
|
124
124
|
|
|
125
125
|
await walkNav(async (navNode) => {
|
|
126
|
-
if (navNode.
|
|
126
|
+
if (navNode.fullId === contentId) {
|
|
127
127
|
hidden = navNode.skip;
|
|
128
128
|
return false;
|
|
129
129
|
}
|
|
@@ -23,11 +23,12 @@ export async function getContentGenericData(
|
|
|
23
23
|
where: { contentId },
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
if (!dbContent)
|
|
26
|
+
if (!dbContent) {
|
|
27
27
|
throw createError({
|
|
28
28
|
statusCode: 404,
|
|
29
29
|
message: `Content item "${contentId}" not found!`,
|
|
30
30
|
});
|
|
31
|
+
}
|
|
31
32
|
|
|
32
33
|
const previousNext = await getPreviousNext(contentId);
|
|
33
34
|
const decoration = await getContentDecoration(contentId);
|
|
@@ -57,12 +58,12 @@ export async function getPreviousNext(contentId: string) {
|
|
|
57
58
|
const { previousNav, nextNav } = await getPreviousNextNav(contentId);
|
|
58
59
|
|
|
59
60
|
async function getItemData(navNode: NavNode): Promise<PreviousNextItem> {
|
|
60
|
-
const title = await getContentTitle(navNode.
|
|
61
|
+
const title = await getContentTitle(navNode.fullId);
|
|
61
62
|
|
|
62
63
|
const link = await (async () => {
|
|
63
64
|
if (navNode.type === 'topic')
|
|
64
65
|
return createTopicPartLink(
|
|
65
|
-
await getTopicPart(navNode.
|
|
66
|
+
await getTopicPart(navNode.fullId),
|
|
66
67
|
navNode.id,
|
|
67
68
|
);
|
|
68
69
|
|
|
@@ -166,15 +167,6 @@ export async function getContentLink(contentId: string) {
|
|
|
166
167
|
return createTopicPartLink(topicPart, contentId);
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
export async function getFullContentId(contentId: string) {
|
|
170
|
-
const dbContent = await ERUDIT_SERVER.DB.manager.findOne(DbContent, {
|
|
171
|
-
select: ['fullId'],
|
|
172
|
-
where: { contentId },
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
return dbContent?.fullId;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
170
|
export async function getContentContributors(contentId: string) {
|
|
179
171
|
const contributorIds = await (async () => {
|
|
180
172
|
const idHash: Record<string, true> = {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DbContentId } from '@server/db/entities/ContentId';
|
|
2
|
+
import { ERUDIT_SERVER } from '@server/global';
|
|
3
|
+
|
|
4
|
+
async function findContentId(contentId: string): Promise<DbContentId> {
|
|
5
|
+
const dbContentId = await ERUDIT_SERVER.DB.manager.findOne(DbContentId, {
|
|
6
|
+
where: [{ shortId: contentId }, { fullId: contentId }],
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
if (!dbContentId) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Can't find both short or full content id: ${contentId}!`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return dbContentId;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function getFullContentId(maybeShortId: string): Promise<string> {
|
|
19
|
+
const dbContentId = await findContentId(maybeShortId);
|
|
20
|
+
return dbContentId.fullId;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function getShortContentId(maybeFullId: string): Promise<string> {
|
|
24
|
+
const dbContentId = await findContentId(maybeFullId);
|
|
25
|
+
return dbContentId.shortId;
|
|
26
|
+
}
|
|
@@ -46,12 +46,12 @@ async function toFrontNavItem(arg: ToFuncArg): Promise<FrontNavItem> {
|
|
|
46
46
|
case 'group':
|
|
47
47
|
const dbGroup = await ERUDIT_SERVER.DB.manager.findOne(DbGroup, {
|
|
48
48
|
select: ['type'],
|
|
49
|
-
where: { contentId: arg.node.
|
|
49
|
+
where: { contentId: arg.node.fullId },
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
if (!dbGroup)
|
|
53
53
|
throw new Error(
|
|
54
|
-
`Missing group content item "${arg.node.
|
|
54
|
+
`Missing group content item "${arg.node.fullId}" when creating front nav!`,
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
if (dbGroup.type === 'folder') return await toFrontNavFolder(arg);
|
|
@@ -107,7 +107,7 @@ async function toFrontNavTopic({
|
|
|
107
107
|
node,
|
|
108
108
|
level,
|
|
109
109
|
}: ToFuncArg): Promise<FrontNavTopic> {
|
|
110
|
-
const topicPart = await getTopicPart(node.
|
|
110
|
+
const topicPart = await getTopicPart(node.fullId);
|
|
111
111
|
return {
|
|
112
112
|
type: 'topic',
|
|
113
113
|
part: topicPart,
|
|
@@ -121,7 +121,7 @@ async function toFrontNavBase({
|
|
|
121
121
|
}: ToFuncArg): Promise<Omit<FrontNavBase, 'type'>> {
|
|
122
122
|
const dbContent = await ERUDIT_SERVER.DB.manager.findOne(DbContent, {
|
|
123
123
|
select: ['title', 'navTitle', 'flags'],
|
|
124
|
-
where: { contentId: node.
|
|
124
|
+
where: { contentId: node.fullId },
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
return {
|
|
@@ -2,6 +2,8 @@ import type { TopicPart } from '@erudit-js/cog/schema';
|
|
|
2
2
|
|
|
3
3
|
import { ERUDIT_SERVER } from '@server/global';
|
|
4
4
|
import { DbTopic } from '@server/db/entities/Topic';
|
|
5
|
+
import { getShortContentId } from '@server/repository/contentId';
|
|
6
|
+
|
|
5
7
|
import type { TopicPartLinks } from '@shared/content/data/type/topic';
|
|
6
8
|
import { createTopicPartLink } from '@shared/link';
|
|
7
9
|
|
|
@@ -23,10 +25,11 @@ export async function getTopicPart(contentId: string): Promise<TopicPart> {
|
|
|
23
25
|
|
|
24
26
|
export async function getTopicPartsLinks(topicId: string) {
|
|
25
27
|
const existingTopicParts = await getTopicParts(topicId);
|
|
28
|
+
const shortTopicId = await getShortContentId(topicId);
|
|
26
29
|
const links: TopicPartLinks = {};
|
|
27
30
|
|
|
28
31
|
for (const topicPart of existingTopicParts)
|
|
29
|
-
links[topicPart] = createTopicPartLink(topicPart,
|
|
32
|
+
links[topicPart] = createTopicPartLink(topicPart, shortTopicId);
|
|
30
33
|
|
|
31
34
|
return links;
|
|
32
35
|
}
|
package/shared/aside/minor.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type AsideMinorType =
|
|
|
17
17
|
|
|
18
18
|
export interface AsideMinorTopic extends AsideMinorBase {
|
|
19
19
|
type: 'topic';
|
|
20
|
-
|
|
20
|
+
topicId: string;
|
|
21
21
|
location: BitranLocation;
|
|
22
22
|
nav: Partial<{
|
|
23
23
|
previous: PreviousNextItem;
|
|
@@ -33,7 +33,7 @@ export interface AsideMinorTopic extends AsideMinorBase {
|
|
|
33
33
|
|
|
34
34
|
export interface AsideMinorContent extends AsideMinorBase {
|
|
35
35
|
type: 'group' | 'book';
|
|
36
|
-
|
|
36
|
+
contentId: string;
|
|
37
37
|
nav: Partial<{
|
|
38
38
|
previous: PreviousNextItem;
|
|
39
39
|
next: PreviousNextItem;
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
stringifyBitranLocation,
|
|
5
5
|
type BitranLocation,
|
|
6
6
|
} from '@erudit-js/cog/schema';
|
|
7
|
+
import { detectContentBookId } from '../content/bookId';
|
|
7
8
|
|
|
8
9
|
export function toAbsoluteLocation<T extends string | BitranLocation>(
|
|
9
10
|
location: T,
|
|
@@ -43,11 +44,10 @@ export function toAbsoluteContentId(
|
|
|
43
44
|
|
|
44
45
|
if (contentId.startsWith('~/')) {
|
|
45
46
|
const restPath = contentId.substring(2);
|
|
47
|
+
const bookId = detectContentBookId(contextId, bookIds ?? []);
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return bookId + '/' + restPath;
|
|
50
|
-
}
|
|
49
|
+
if (bookId) {
|
|
50
|
+
return bookId + '/' + restPath;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Not in any book, convert to absolute path
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function detectContentBookId(contentId: string, bookIds: string[]) {
|
|
2
|
+
let bestMatch: string | undefined = undefined;
|
|
3
|
+
for (const bookId of bookIds) {
|
|
4
|
+
if (contentId.startsWith(bookId)) {
|
|
5
|
+
if (!bestMatch || bookId.length > bestMatch.length) {
|
|
6
|
+
bestMatch = bookId;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return bestMatch;
|
|
11
|
+
}
|
package/shared/frontNav.ts
CHANGED