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.
Files changed (54) hide show
  1. package/app/components/SiteMain.vue +1 -1
  2. package/app/components/aside/major/panes/nav/Nav.vue +11 -6
  3. package/app/components/aside/major/panes/nav/fnav/FNavFlags.vue +1 -1
  4. package/app/components/aside/minor/Contribute.vue +2 -2
  5. package/app/components/aside/minor/content/AsideMinorContent.vue +1 -1
  6. package/app/components/aside/minor/topic/AsideMinorTopic.vue +1 -1
  7. package/app/components/aside/minor/topic/TopicContributors.vue +2 -2
  8. package/app/components/aside/minor/topic/TopicToc.vue +1 -6
  9. package/app/components/aside/minor/topic/TopicTocItem.vue +3 -1
  10. package/app/components/main/utils/Breadcrumb.vue +1 -1
  11. package/app/components/preview/PreviewScreen.vue +2 -2
  12. package/app/components/preview/display/PageLink.vue +1 -1
  13. package/app/composables/bitranContent.ts +3 -3
  14. package/app/composables/contentPage.ts +8 -7
  15. package/app/composables/formatText.ts +21 -8
  16. package/app/composables/phrases.ts +0 -16
  17. package/app/plugins/prerender.server.ts +22 -0
  18. package/app/scripts/preview/build.ts +1 -5
  19. package/app/scripts/preview/data/pageLink.ts +1 -0
  20. package/app/styles/normalize.scss +0 -14
  21. package/globals/content.ts +5 -0
  22. package/module/imports.ts +1 -0
  23. package/nuxt.config.ts +1 -5
  24. package/package.json +8 -8
  25. package/server/api/aside/minor/path.ts +19 -11
  26. package/server/api/bitran/content/[...location].ts +4 -2
  27. package/server/api/bitran/toc/[...location].ts +4 -2
  28. package/server/api/content/data.ts +5 -2
  29. package/server/api/prerender.ts +120 -0
  30. package/server/api/preview/page/[...parts].ts +30 -4
  31. package/server/api/preview/unique/{[location].ts → [...location].ts} +4 -3
  32. package/server/plugin/bitran/content.ts +3 -16
  33. package/server/plugin/bitran/elements/include.ts +13 -16
  34. package/server/plugin/bitran/location.ts +24 -10
  35. package/server/plugin/bitran/toc.ts +7 -2
  36. package/server/plugin/bitran/transpiler.ts +10 -1
  37. package/server/plugin/build/jobs/content/generic.ts +10 -5
  38. package/server/plugin/build/jobs/content/type/group.ts +2 -2
  39. package/server/plugin/build/jobs/content/type/topic.ts +2 -2
  40. package/server/plugin/build/jobs/nav.ts +8 -11
  41. package/server/plugin/content/context.ts +4 -1
  42. package/server/plugin/db/entities/Content.ts +0 -4
  43. package/server/plugin/db/entities/ContentId.ts +11 -0
  44. package/server/plugin/db/setup.ts +3 -1
  45. package/server/plugin/importer.ts +5 -1
  46. package/server/plugin/nav/utils.ts +4 -4
  47. package/server/plugin/repository/content.ts +4 -12
  48. package/server/plugin/repository/contentId.ts +26 -0
  49. package/server/plugin/repository/frontNav.ts +4 -4
  50. package/server/plugin/repository/topic.ts +4 -1
  51. package/shared/aside/minor.ts +2 -2
  52. package/shared/bitran/contentId.ts +4 -4
  53. package/shared/content/bookId.ts +11 -0
  54. 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.id === contentId) {
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.id === contentId) {
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.id);
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.id === contentId) {
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.id);
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.id),
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.id },
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.id}" when creating front nav!`,
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.id);
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.id },
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, topicId);
32
+ links[topicPart] = createTopicPartLink(topicPart, shortTopicId);
30
33
 
31
34
  return links;
32
35
  }
@@ -17,7 +17,7 @@ export type AsideMinorType =
17
17
 
18
18
  export interface AsideMinorTopic extends AsideMinorBase {
19
19
  type: 'topic';
20
- fullContentId: string;
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
- fullContentId: string;
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
- for (const bookId of bookIds ?? []) {
48
- if (contextId.startsWith(bookId)) {
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
+ }
@@ -8,7 +8,7 @@ export interface FrontNavBase {
8
8
  fullId: string;
9
9
  label: string;
10
10
  level: number;
11
- flags?: Record<ContentFlag, boolean>;
11
+ flags?: Partial<Record<ContentFlag, boolean>>;
12
12
  }
13
13
 
14
14
  export interface FrontNavTopic extends FrontNavBase {