erudit 4.1.1 → 4.2.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/app/assets/icons/update.svg +3 -0
- package/app/components/Prose.vue +7 -7
- package/app/components/SmartMedia.vue +4 -4
- package/app/components/aside/major/contentNav/PaneBookNav.vue +1 -4
- package/app/components/aside/minor/content/Toc.vue +24 -1
- package/app/components/aside/minor/content/TocItem.vue +2 -1
- package/app/components/aside/minor/news/AsideMinorNews.vue +2 -4
- package/app/components/aside/minor/news/NewsItem.vue +3 -4
- package/app/components/aside/minor/news/RenderNewsElement.vue +4 -11
- package/app/components/aside/minor/news/elements/Mix.vue +2 -3
- package/app/components/aside/minor/news/elements/P.vue +3 -3
- package/app/components/aside/minor/news/elements/Ref.vue +3 -3
- package/app/components/aside/minor/news/elements/Text.vue +2 -2
- package/app/components/main/MainContentChild.vue +3 -3
- package/app/components/main/{MainQuickLink.vue → MainKeyLink.vue} +11 -11
- package/app/components/main/{MainQuickLinks.vue → MainKeyLinks.vue} +7 -7
- package/app/components/main/MainQuoteLoader.vue +2 -4
- package/app/components/main/MainStickyHeader.vue +1 -1
- package/app/components/main/MainStickyHeaderPreamble.vue +6 -2
- package/app/components/main/MainTopicPartPage.vue +8 -3
- package/app/components/main/connections/DepUnique.vue +45 -0
- package/app/components/main/connections/Deps.vue +14 -2
- package/app/components/main/connections/Externals.vue +1 -1
- package/app/components/main/connections/MainConnections.vue +1 -0
- package/app/components/main/contentStats/ItemLastChanged.vue +68 -0
- package/app/components/main/contentStats/MainContentStats.vue +36 -28
- package/app/components/preview/PreviewScreen.vue +2 -2
- package/app/components/preview/screen/ContentPage.vue +1 -4
- package/app/components/preview/screen/Unique.vue +3 -5
- package/app/composables/appElements.ts +2 -4
- package/app/composables/asideMajorPane.ts +3 -3
- package/app/composables/fetchJson.ts +4 -0
- package/app/composables/lastChanged.ts +28 -0
- package/app/composables/mainContent.ts +1 -4
- package/app/composables/og.ts +43 -35
- package/app/composables/phrases.ts +2 -3
- package/app/composables/scrollUp.ts +1 -1
- package/app/pages/book/[...bookId].vue +5 -1
- package/app/pages/contributor/[contributorId].vue +3 -5
- package/app/pages/contributors.vue +1 -1
- package/app/pages/group/[...groupId].vue +5 -1
- package/app/pages/index.vue +1 -1
- package/app/pages/page/[...pageId].vue +8 -3
- package/app/pages/sponsors.vue +1 -1
- package/app/plugins/appSetup/index.ts +0 -5
- package/app/plugins/fetchJson.ts +11 -0
- package/app/plugins/prerender.server.ts +1 -1
- package/app/router.options.ts +1 -1
- package/modules/erudit/globals/prose.ts +3 -4
- package/modules/erudit/setup/elements/appTemplate.ts +6 -7
- package/modules/erudit/setup/elements/{globalTypes.ts → elementGlobalTypes.ts} +21 -21
- package/modules/erudit/setup/elements/globalTemplate.ts +29 -23
- package/modules/erudit/setup/elements/setup.ts +18 -16
- package/modules/erudit/setup/elements/shared.ts +2 -2
- package/modules/erudit/setup/elements/tagsTable.ts +1 -1
- package/modules/erudit/setup/runtimeConfig.ts +2 -0
- package/nuxt.config.ts +2 -2
- package/package.json +14 -13
- package/server/api/main/content/[...contentTypePath].ts +5 -4
- package/server/api/prerender/content.ts +1 -3
- package/server/api/preview/contentPage/[...contentTypePath].ts +1 -2
- package/server/api/preview/contentUnique/[...contentTypePathUnique].ts +16 -31
- package/server/api/problemScript/[...problemScriptPath].ts +81 -4
- package/server/erudit/content/global/build.ts +64 -10
- package/server/erudit/content/nav/build.ts +4 -4
- package/server/erudit/content/repository/children.ts +3 -3
- package/server/erudit/content/repository/deps.ts +110 -13
- package/server/erudit/content/repository/elementSnippets.ts +16 -16
- package/server/erudit/content/repository/stats.ts +30 -22
- package/server/erudit/content/repository/topicParts.ts +1 -1
- package/server/erudit/content/repository/unique.ts +14 -15
- package/server/erudit/content/resolve/page.ts +15 -35
- package/server/erudit/content/resolve/topic.ts +33 -164
- package/server/erudit/content/resolve/utils/insertContentResolved.ts +59 -31
- package/server/erudit/content/search.ts +5 -22
- package/server/erudit/contributors/build.ts +7 -8
- package/server/erudit/db/repository/pushFile.ts +10 -3
- package/server/erudit/db/repository/pushProblemScript.ts +14 -3
- package/server/erudit/db/schema/contentDeps.ts +3 -0
- package/server/erudit/db/schema/contentSnippets.ts +3 -3
- package/server/erudit/db/schema/contentUniques.ts +2 -2
- package/server/erudit/db/schema/contributors.ts +2 -2
- package/server/erudit/db/schema/news.ts +2 -2
- package/server/erudit/db/schema/pages.ts +2 -2
- package/server/erudit/db/schema/topics.ts +4 -4
- package/server/erudit/global.ts +4 -0
- package/server/erudit/importer.ts +16 -8
- package/server/erudit/index.ts +0 -3
- package/server/erudit/language/list/en.ts +1 -0
- package/server/erudit/language/list/ru.ts +1 -0
- package/server/erudit/news/build.ts +6 -6
- package/server/erudit/news/repository/batch.ts +2 -2
- package/server/erudit/prose/repository/finalize.ts +22 -25
- package/server/erudit/prose/repository/get.ts +3 -5
- package/server/erudit/prose/repository/rawToProse.ts +31 -0
- package/server/erudit/prose/storage/callout.ts +9 -7
- package/server/erudit/prose/storage/image.ts +8 -11
- package/server/erudit/prose/storage/link.ts +24 -32
- package/server/erudit/prose/storage/problemScript.ts +8 -14
- package/server/erudit/prose/storage/video.ts +9 -7
- package/server/erudit/repository.ts +4 -4
- package/server/routes/file/[...path].ts +1 -1
- package/shared/types/contentChildren.ts +5 -2
- package/shared/types/contentConnections.ts +9 -0
- package/shared/types/elementSnippet.ts +1 -1
- package/shared/types/indexPage.ts +3 -0
- package/shared/types/language.ts +1 -83
- package/shared/types/mainContent.ts +11 -5
- package/shared/types/news.ts +2 -2
- package/shared/types/preview.ts +3 -2
- package/shared/types/runtimeConfig.ts +1 -0
- package/shared/types/search.ts +2 -0
- package/shared/utils/pages.ts +4 -2
- package/shared/utils/stringColor.ts +16 -6
- package/server/erudit/prose/repository/resolve.ts +0 -17
- package/server/erudit/prose/transform/bundleProblemScript.ts +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
2
|
import type { ContentProseType } from '@erudit-js/core/content/prose';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Snippet } from '@erudit-js/prose';
|
|
4
4
|
|
|
5
5
|
export const contentSnippets = sqliteTable('contentSnippets', {
|
|
6
6
|
snippetId: integer().primaryKey({ autoIncrement: true }),
|
|
@@ -8,8 +8,8 @@ export const contentSnippets = sqliteTable('contentSnippets', {
|
|
|
8
8
|
contentProseType: text().notNull().$type<ContentProseType>(),
|
|
9
9
|
schemaName: text().notNull(),
|
|
10
10
|
elementId: text().notNull(),
|
|
11
|
-
snippetData: text({ mode: 'json' }).$type<
|
|
11
|
+
snippetData: text({ mode: 'json' }).$type<Snippet>().notNull(),
|
|
12
12
|
search: integer({ mode: 'boolean' }).notNull(),
|
|
13
|
-
|
|
13
|
+
key: integer({ mode: 'boolean' }).notNull(),
|
|
14
14
|
seo: integer({ mode: 'boolean' }).notNull(),
|
|
15
15
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProseElement } from 'tsprose';
|
|
3
3
|
import type { ContentProseType } from '@erudit-js/core/content/prose';
|
|
4
4
|
|
|
5
5
|
export const contentUniques = sqliteTable(
|
|
@@ -9,7 +9,7 @@ export const contentUniques = sqliteTable(
|
|
|
9
9
|
contentProseType: text().notNull().$type<ContentProseType>(),
|
|
10
10
|
uniqueName: text().notNull(),
|
|
11
11
|
title: text(),
|
|
12
|
-
prose: text({ mode: 'json' }).$type<ProseElement
|
|
12
|
+
prose: text({ mode: 'json' }).$type<ProseElement>().notNull(),
|
|
13
13
|
},
|
|
14
14
|
(table) => [
|
|
15
15
|
primaryKey({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProseElement } from 'tsprose';
|
|
3
3
|
|
|
4
4
|
export const contributors = sqliteTable('contributors', {
|
|
5
5
|
contributorId: text().primaryKey(),
|
|
@@ -8,5 +8,5 @@ export const contributors = sqliteTable('contributors', {
|
|
|
8
8
|
avatarExtension: text(),
|
|
9
9
|
editor: integer({ mode: 'boolean' }),
|
|
10
10
|
links: text({ mode: 'json' }).$type<Record<string, string>>(),
|
|
11
|
-
description: text({ mode: 'json' }).$type<ProseElement
|
|
11
|
+
description: text({ mode: 'json' }).$type<ProseElement>(),
|
|
12
12
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProseElement } from 'tsprose';
|
|
3
3
|
|
|
4
4
|
export const news = sqliteTable('news', {
|
|
5
5
|
date: text().primaryKey(),
|
|
6
|
-
prose: text({ mode: 'json' }).$type<ProseElement
|
|
6
|
+
prose: text({ mode: 'json' }).$type<ProseElement>().notNull(),
|
|
7
7
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProseElement } from 'tsprose';
|
|
3
3
|
|
|
4
4
|
export const pages = sqliteTable('pages', {
|
|
5
5
|
fullId: text().primaryKey(),
|
|
6
|
-
prose: text({ mode: 'json' }).$type<ProseElement
|
|
6
|
+
prose: text({ mode: 'json' }).$type<ProseElement>().notNull(),
|
|
7
7
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProseElement } from 'tsprose';
|
|
3
3
|
|
|
4
4
|
export const topics = sqliteTable('topics', {
|
|
5
5
|
fullId: text().primaryKey(),
|
|
6
|
-
article: text({ mode: 'json' }).$type<ProseElement
|
|
7
|
-
summary: text({ mode: 'json' }).$type<ProseElement
|
|
8
|
-
practice: text({ mode: 'json' }).$type<ProseElement
|
|
6
|
+
article: text({ mode: 'json' }).$type<ProseElement>(),
|
|
7
|
+
summary: text({ mode: 'json' }).$type<ProseElement>(),
|
|
8
|
+
practice: text({ mode: 'json' }).$type<ProseElement>(),
|
|
9
9
|
});
|
package/server/erudit/global.ts
CHANGED
|
@@ -10,6 +10,8 @@ import type { EruditServerLogger } from './logger';
|
|
|
10
10
|
import type { EruditServerPaths } from './path';
|
|
11
11
|
import type { EruditServerRepository } from './repository';
|
|
12
12
|
|
|
13
|
+
import { registerProseGlobals } from '#erudit/prose/global';
|
|
14
|
+
|
|
13
15
|
export const ERUDIT: {
|
|
14
16
|
buildError: EruditServerBuildError;
|
|
15
17
|
buildPromise: Promise<void>;
|
|
@@ -36,3 +38,5 @@ Object.assign(globalThis, {
|
|
|
36
38
|
defineProse,
|
|
37
39
|
Include,
|
|
38
40
|
});
|
|
41
|
+
|
|
42
|
+
registerProseGlobals();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createJiti, type Jiti, type JitiOptions } from 'jiti';
|
|
2
|
-
import { insertDocumentId } from '@jsprose/core';
|
|
3
2
|
import { sn } from 'unslash';
|
|
3
|
+
import { injectDocumentId } from 'tsprose';
|
|
4
4
|
import {
|
|
5
5
|
pathToDocumentId,
|
|
6
6
|
stringifyDocumentId,
|
|
@@ -45,18 +45,18 @@ export async function setupServerImporter() {
|
|
|
45
45
|
const documentId = pathToDocumentId(filename, ERUDIT.paths.project());
|
|
46
46
|
|
|
47
47
|
if (documentId) {
|
|
48
|
-
code =
|
|
48
|
+
code = injectDocumentId(
|
|
49
|
+
stringifyDocumentId(documentId),
|
|
49
50
|
code,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
});
|
|
51
|
+
'defineProse',
|
|
52
|
+
);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
//
|
|
56
56
|
// Problem Scripts
|
|
57
57
|
//
|
|
58
58
|
|
|
59
|
-
code = insertProblemScriptId(filename, code);
|
|
59
|
+
code = insertProblemScriptId(toRelPath(filename), code);
|
|
60
60
|
|
|
61
61
|
return { code };
|
|
62
62
|
},
|
|
@@ -77,18 +77,26 @@ function createBaseJitiOptions(): JitiOptions {
|
|
|
77
77
|
},
|
|
78
78
|
jsx: {
|
|
79
79
|
runtime: 'automatic',
|
|
80
|
-
importSource: '
|
|
80
|
+
importSource: 'tsprose',
|
|
81
81
|
},
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
function toRelPath(filename: string): string {
|
|
86
|
+
const projectPath = ERUDIT.paths.project();
|
|
87
|
+
if (filename.startsWith(projectPath + '/')) {
|
|
88
|
+
return filename.slice(projectPath.length + 1);
|
|
89
|
+
}
|
|
90
|
+
return filename;
|
|
91
|
+
}
|
|
92
|
+
|
|
85
93
|
function tryStaticAssetModule(filename: unknown) {
|
|
86
94
|
if (
|
|
87
95
|
typeof filename === 'string' &&
|
|
88
96
|
STATIC_ASSET_EXTENSIONS.some((ext) => filename.endsWith('.' + ext))
|
|
89
97
|
) {
|
|
90
98
|
return {
|
|
91
|
-
code: `exports.default = "${filename}";`,
|
|
99
|
+
code: `exports.default = "${toRelPath(filename)}";`,
|
|
92
100
|
};
|
|
93
101
|
}
|
|
94
102
|
}
|
package/server/erudit/index.ts
CHANGED
|
@@ -61,9 +61,6 @@ ${escapeHtml(ERUDIT.buildError.stack || '')}
|
|
|
61
61
|
|
|
62
62
|
async function setupServer() {
|
|
63
63
|
try {
|
|
64
|
-
const { registerProseGlobals } = await import('#erudit/prose/global');
|
|
65
|
-
registerProseGlobals();
|
|
66
|
-
|
|
67
64
|
const runtimeConfig = useRuntimeConfig();
|
|
68
65
|
|
|
69
66
|
ERUDIT.mode = runtimeConfig.public.eruditMode as EruditMode;
|
|
@@ -80,6 +80,7 @@ export const phrases: LanguagePhrases = {
|
|
|
80
80
|
no_contribution: 'No contributions yet.',
|
|
81
81
|
editor: 'Editor',
|
|
82
82
|
materials: 'Materials',
|
|
83
|
+
updated: 'Updated',
|
|
83
84
|
x_sponsors: (count: number) => m(count, 'Sponsor', 'Sponsors'),
|
|
84
85
|
x_contributors: (count: number) => m(count, 'Contributor', 'Contributors'),
|
|
85
86
|
news: 'News',
|
|
@@ -81,6 +81,7 @@ export const phrases: LanguagePhrases = {
|
|
|
81
81
|
no_contribution: 'Пока что вклада нет.',
|
|
82
82
|
editor: 'Редактор',
|
|
83
83
|
materials: 'Материалы',
|
|
84
|
+
updated: 'Обновлено',
|
|
84
85
|
x_sponsors: (count: number) => m(count, 'Спонсор', 'Спонсора', 'Спонсоров'),
|
|
85
86
|
x_contributors: (count: number) => m(count, 'Автор', 'Автора', 'Авторов'),
|
|
86
87
|
news: 'Новости',
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { inArray } from 'drizzle-orm';
|
|
3
3
|
import { globSync } from 'glob';
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
import { resolveEruditProse } from '../prose/repository/resolve';
|
|
4
|
+
import type { RawElement } from 'tsprose';
|
|
7
5
|
|
|
8
6
|
let initialBuild = true;
|
|
9
7
|
|
|
@@ -88,7 +86,7 @@ async function buildNewsItem(filename: string) {
|
|
|
88
86
|
`Building news item ${ERUDIT.log.stress(filename)}...`,
|
|
89
87
|
);
|
|
90
88
|
|
|
91
|
-
let newsModule: { default: RawElement
|
|
89
|
+
let newsModule: { default: RawElement } | undefined;
|
|
92
90
|
|
|
93
91
|
try {
|
|
94
92
|
newsModule = await ERUDIT.import(`${newsRoot()}/${filename}`);
|
|
@@ -103,10 +101,12 @@ async function buildNewsItem(filename: string) {
|
|
|
103
101
|
return;
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
const resolvedProse = await
|
|
104
|
+
const resolvedProse = await ERUDIT.repository.prose.fromRaw({
|
|
105
|
+
rawProse: newsModule.default,
|
|
106
|
+
});
|
|
107
107
|
|
|
108
108
|
await ERUDIT.db.insert(ERUDIT.db.schema.news).values({
|
|
109
109
|
date: filename.replace('.tsx', ''),
|
|
110
|
-
prose: resolvedProse.
|
|
110
|
+
prose: resolvedProse.prose,
|
|
111
111
|
});
|
|
112
112
|
}
|
|
@@ -6,7 +6,7 @@ export async function countNewsBatches(): Promise<number> {
|
|
|
6
6
|
const newsTotal = await ERUDIT.db
|
|
7
7
|
.select({ count: count() })
|
|
8
8
|
.from(ERUDIT.db.schema.news)
|
|
9
|
-
.then((result) => result[0]
|
|
9
|
+
.then((result) => result[0]!.count);
|
|
10
10
|
|
|
11
11
|
return Math.ceil(newsTotal / newsNumberPerBatch);
|
|
12
12
|
}
|
|
@@ -15,7 +15,7 @@ export async function getNewsNextBatch(index: number): Promise<NewsBatch> {
|
|
|
15
15
|
const newsTotal = await ERUDIT.db
|
|
16
16
|
.select({ count: count() })
|
|
17
17
|
.from(ERUDIT.db.schema.news)
|
|
18
|
-
.then((result) => result[0]
|
|
18
|
+
.then((result) => result[0]!.count);
|
|
19
19
|
|
|
20
20
|
const dbNews = await ERUDIT.db.query.news.findMany({
|
|
21
21
|
columns: {
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
fillProseStorage,
|
|
3
3
|
isProseElement,
|
|
4
|
-
PROSE_REGISTRY,
|
|
5
|
-
type AnySchema,
|
|
6
|
-
type FinalizedProse,
|
|
7
|
-
type GenericStorage,
|
|
8
4
|
type ProseElement,
|
|
9
|
-
|
|
5
|
+
type ProseWithStorage,
|
|
6
|
+
} from 'tsprose';
|
|
10
7
|
import { imageSchema } from '@erudit-js/prose/elements/image/core';
|
|
11
8
|
import { videoSchema } from '@erudit-js/prose/elements/video/core';
|
|
12
9
|
import { calloutSchema } from '@erudit-js/prose/elements/callout/core';
|
|
@@ -27,42 +24,42 @@ import { createCalloutStorage } from '../storage/callout';
|
|
|
27
24
|
import { createLinkStorage } from '../storage/link';
|
|
28
25
|
import { createProblemScriptStorage } from '../storage/problemScript';
|
|
29
26
|
|
|
27
|
+
import { coreElements } from '#erudit/prose/global';
|
|
28
|
+
|
|
30
29
|
export async function finalizeProse(
|
|
31
|
-
|
|
32
|
-
): Promise<
|
|
33
|
-
const
|
|
30
|
+
prose: ProseElement,
|
|
31
|
+
): Promise<ProseWithStorage> {
|
|
32
|
+
const storageCreators = Object.fromEntries(
|
|
33
|
+
Object.entries(coreElements)
|
|
34
|
+
.map(([key, coreElement]) => [key, coreElement.createStorage])
|
|
35
|
+
.filter(([, createStorage]) => Boolean(createStorage)),
|
|
36
|
+
);
|
|
34
37
|
|
|
35
|
-
await
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
step: async (element) => {
|
|
38
|
+
const storage = await fillProseStorage({
|
|
39
|
+
prose,
|
|
40
|
+
storageCreators,
|
|
41
|
+
alterValue: async ({ element, storageKey }) => {
|
|
40
42
|
switch (true) {
|
|
41
43
|
case isProseElement(element, imageSchema):
|
|
42
|
-
await createImageStorage(element
|
|
43
|
-
break;
|
|
44
|
+
return await createImageStorage(element);
|
|
44
45
|
case isProseElement(element, videoSchema):
|
|
45
|
-
|
|
46
|
-
break;
|
|
46
|
+
return createVideoStorage(element);
|
|
47
47
|
case isProseElement(element, calloutSchema):
|
|
48
|
-
|
|
49
|
-
break;
|
|
48
|
+
return createCalloutStorage(element);
|
|
50
49
|
case isProseElement(element, refSchema):
|
|
51
50
|
case isProseElement(element, referenceSchema):
|
|
52
51
|
case isProseElement(element, depSchema):
|
|
53
52
|
case isProseElement(element, dependencySchema):
|
|
54
|
-
await createLinkStorage(element,
|
|
55
|
-
break;
|
|
53
|
+
return await createLinkStorage(element, storageKey);
|
|
56
54
|
case isProseElement(element, problemSchema):
|
|
57
55
|
case isProseElement(element, subProblemSchema):
|
|
58
|
-
|
|
59
|
-
break;
|
|
56
|
+
return createProblemScriptStorage(element, storageKey);
|
|
60
57
|
}
|
|
61
58
|
},
|
|
62
59
|
});
|
|
63
60
|
|
|
64
61
|
return {
|
|
65
|
-
|
|
62
|
+
prose,
|
|
66
63
|
storage,
|
|
67
64
|
};
|
|
68
65
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { eq } from 'drizzle-orm';
|
|
2
|
-
import
|
|
2
|
+
import { type ProseElement } from 'tsprose';
|
|
3
3
|
import type { ContentProseType } from '@erudit-js/core/content/prose';
|
|
4
4
|
import { isTopicPart } from '@erudit-js/core/content/topic';
|
|
5
5
|
|
|
6
6
|
export async function getContentProse(
|
|
7
7
|
contentType: ContentProseType,
|
|
8
8
|
contentId: string,
|
|
9
|
-
): Promise<ProseElement
|
|
9
|
+
): Promise<ProseElement> {
|
|
10
10
|
const navNode = ERUDIT.contentNav.getNodeOrThrow(contentId);
|
|
11
11
|
const fullContentId = navNode.fullId;
|
|
12
12
|
|
|
@@ -40,7 +40,7 @@ export async function getContentProse(
|
|
|
40
40
|
|
|
41
41
|
export async function getContributorProse(
|
|
42
42
|
contributorId: string,
|
|
43
|
-
): Promise<ProseElement
|
|
43
|
+
): Promise<ProseElement | undefined> {
|
|
44
44
|
const dbContributor = await ERUDIT.db.query.contributors.findFirst({
|
|
45
45
|
columns: {
|
|
46
46
|
description: true,
|
|
@@ -50,5 +50,3 @@ export async function getContributorProse(
|
|
|
50
50
|
|
|
51
51
|
return dbContributor?.description || undefined;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
// @TODO: Get news item prose
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
eruditRawToProse,
|
|
3
|
+
type EruditRawToProseTask,
|
|
4
|
+
type RawToProseSchemaHooks,
|
|
5
|
+
} from '@erudit-js/prose';
|
|
6
|
+
import { coreElements } from '#erudit/prose/global';
|
|
7
|
+
|
|
8
|
+
function buildSchemaHooks(): RawToProseSchemaHooks {
|
|
9
|
+
const hooks: RawToProseSchemaHooks = new Map();
|
|
10
|
+
for (const coreElement of Object.values(coreElements)) {
|
|
11
|
+
if (coreElement.rawToProseHook) {
|
|
12
|
+
hooks.set(coreElement.schema, coreElement.rawToProseHook);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return hooks;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function serverRawToProse(task: EruditRawToProseTask) {
|
|
19
|
+
const elementSchemaHooks = buildSchemaHooks();
|
|
20
|
+
|
|
21
|
+
// Merge caller-provided schemaHooks on top of the element hooks
|
|
22
|
+
const mergedSchemaHooks: RawToProseSchemaHooks = task.schemaHooks
|
|
23
|
+
? new Map([...elementSchemaHooks, ...task.schemaHooks])
|
|
24
|
+
: elementSchemaHooks;
|
|
25
|
+
|
|
26
|
+
return eruditRawToProse({
|
|
27
|
+
...task,
|
|
28
|
+
language: ERUDIT.config.public.language.current,
|
|
29
|
+
schemaHooks: mergedSchemaHooks,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ToProseElement } from 'tsprose';
|
|
2
|
+
import type {
|
|
3
|
+
CalloutSchema,
|
|
4
|
+
CalloutStorage,
|
|
5
|
+
} from '@erudit-js/prose/elements/callout/core';
|
|
3
6
|
import { createCalloutStorage as _createCalloutStorage } from '@erudit-js/prose/elements/callout/storage';
|
|
4
7
|
|
|
5
|
-
export
|
|
6
|
-
element:
|
|
7
|
-
|
|
8
|
-
) {
|
|
8
|
+
export function createCalloutStorage(
|
|
9
|
+
element: ToProseElement<CalloutSchema>,
|
|
10
|
+
): CalloutStorage {
|
|
9
11
|
const runtimeConfig = useRuntimeConfig();
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
return _createCalloutStorage(
|
|
12
14
|
ERUDIT.paths.project(),
|
|
13
15
|
runtimeConfig.app.baseURL,
|
|
14
16
|
element.data.iconSrc,
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToProseElement } from 'tsprose';
|
|
2
2
|
import type {
|
|
3
|
-
|
|
3
|
+
ImageSchema,
|
|
4
4
|
ImageStorage,
|
|
5
5
|
} from '@erudit-js/prose/elements/image/core';
|
|
6
6
|
import { createImageStorage as _createImageStorage } from '@erudit-js/prose/elements/image/storage';
|
|
7
7
|
|
|
8
8
|
export async function createImageStorage(
|
|
9
|
-
element:
|
|
10
|
-
|
|
11
|
-
) {
|
|
9
|
+
element: ToProseElement<ImageSchema>,
|
|
10
|
+
): Promise<ImageStorage> {
|
|
12
11
|
const runtimeConfig = useRuntimeConfig();
|
|
13
12
|
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
const imageRelSrc = element.data.src;
|
|
14
|
+
return (await _createImageStorage(
|
|
16
15
|
ERUDIT.paths.project(),
|
|
17
16
|
runtimeConfig.app.baseURL,
|
|
18
|
-
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
storage[element.storageKey!] = imageStorage satisfies ImageStorage;
|
|
17
|
+
imageRelSrc,
|
|
18
|
+
)) satisfies ImageStorage;
|
|
22
19
|
}
|
|
@@ -1,34 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ProseError,
|
|
3
|
-
uniqueName2Id,
|
|
4
|
-
type GenericStorage,
|
|
5
|
-
type ProseElement,
|
|
6
|
-
} from '@jsprose/core';
|
|
7
|
-
|
|
1
|
+
import type { ToProseElement } from 'tsprose';
|
|
8
2
|
import { isTopicPart } from '@erudit-js/core/content/topic';
|
|
9
3
|
import type { ContentPointer } from '@erudit-js/core/content/pointer';
|
|
10
4
|
import type {
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
ReferenceSchema,
|
|
6
|
+
RefSchema,
|
|
13
7
|
} from '@erudit-js/prose/elements/link/reference/core';
|
|
14
8
|
import type {
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
DependencySchema,
|
|
10
|
+
DepSchema,
|
|
17
11
|
} from '@erudit-js/prose/elements/link/dependency/core';
|
|
18
12
|
import type { LinkStorage } from '@erudit-js/prose/elements/link/storage';
|
|
19
13
|
|
|
20
14
|
export async function createLinkStorage(
|
|
21
15
|
element:
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
27
|
-
) {
|
|
16
|
+
| ToProseElement<RefSchema>
|
|
17
|
+
| ToProseElement<ReferenceSchema>
|
|
18
|
+
| ToProseElement<DepSchema>
|
|
19
|
+
| ToProseElement<DependencySchema>,
|
|
20
|
+
storageKey: string,
|
|
21
|
+
): Promise<LinkStorage> {
|
|
28
22
|
try {
|
|
29
23
|
let linkStorage: LinkStorage | undefined;
|
|
30
24
|
|
|
31
|
-
const storageKeyParts =
|
|
25
|
+
const storageKeyParts = storageKey.split('/');
|
|
32
26
|
const linkType = storageKeyParts[0];
|
|
33
27
|
const strProseLink = storageKeyParts.slice(1).join('/');
|
|
34
28
|
|
|
@@ -72,7 +66,7 @@ export async function createLinkStorage(
|
|
|
72
66
|
if (contentPointer.type === 'topic') {
|
|
73
67
|
linkStorage = {
|
|
74
68
|
type: 'unique',
|
|
75
|
-
schemaName: unique.prose.
|
|
69
|
+
schemaName: unique.prose.schema.name,
|
|
76
70
|
elementTitle: unique.title || undefined,
|
|
77
71
|
content: {
|
|
78
72
|
contentType: 'topic',
|
|
@@ -82,7 +76,7 @@ export async function createLinkStorage(
|
|
|
82
76
|
resolvedHref: PAGES.topic(
|
|
83
77
|
contentPointer.part,
|
|
84
78
|
shortId,
|
|
85
|
-
|
|
79
|
+
unique.prose.id,
|
|
86
80
|
),
|
|
87
81
|
previewRequest: {
|
|
88
82
|
type: 'unique',
|
|
@@ -95,13 +89,13 @@ export async function createLinkStorage(
|
|
|
95
89
|
} else {
|
|
96
90
|
linkStorage = {
|
|
97
91
|
type: 'unique',
|
|
98
|
-
schemaName: unique.prose.
|
|
92
|
+
schemaName: unique.prose.schema.name,
|
|
99
93
|
elementTitle: unique.title || undefined,
|
|
100
94
|
content: {
|
|
101
95
|
contentType: contentPointer.type,
|
|
102
96
|
contentTitle,
|
|
103
97
|
},
|
|
104
|
-
resolvedHref: PAGES.page(shortId,
|
|
98
|
+
resolvedHref: PAGES.page(shortId, unique.prose.id),
|
|
105
99
|
previewRequest: {
|
|
106
100
|
type: 'unique',
|
|
107
101
|
contentFullId: contentPointer.id,
|
|
@@ -160,14 +154,14 @@ export async function createLinkStorage(
|
|
|
160
154
|
}
|
|
161
155
|
|
|
162
156
|
if (!linkStorage) {
|
|
163
|
-
throw new
|
|
164
|
-
`Unable to create prose link storage for link: ${
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Unable to create prose link storage for link: ${storageKey}`,
|
|
165
159
|
);
|
|
166
160
|
}
|
|
167
161
|
|
|
168
|
-
|
|
162
|
+
return linkStorage;
|
|
169
163
|
} catch (error) {
|
|
170
|
-
|
|
164
|
+
return {
|
|
171
165
|
type: 'error',
|
|
172
166
|
error: error instanceof Error ? error.message : String(error),
|
|
173
167
|
};
|
|
@@ -178,7 +172,7 @@ async function getContentPointerFor(
|
|
|
178
172
|
contentId: string,
|
|
179
173
|
): Promise<ContentPointer> {
|
|
180
174
|
if (!contentId) {
|
|
181
|
-
throw new
|
|
175
|
+
throw new Error(`Invalid content ID: "${contentId}"!`);
|
|
182
176
|
}
|
|
183
177
|
|
|
184
178
|
const contentNavNode = ERUDIT.contentNav.getNode(contentId);
|
|
@@ -188,7 +182,7 @@ async function getContentPointerFor(
|
|
|
188
182
|
contentNavNode.fullId,
|
|
189
183
|
);
|
|
190
184
|
if (hidden) {
|
|
191
|
-
throw new
|
|
185
|
+
throw new Error(`Target content is hidden!`);
|
|
192
186
|
}
|
|
193
187
|
|
|
194
188
|
if (contentNavNode.type === 'topic') {
|
|
@@ -213,7 +207,7 @@ async function getContentPointerFor(
|
|
|
213
207
|
const maybeTopicPart = contentIdParts.pop()!;
|
|
214
208
|
|
|
215
209
|
if (!isTopicPart(maybeTopicPart)) {
|
|
216
|
-
throw new
|
|
210
|
+
throw new Error(
|
|
217
211
|
`Prose link part "${contentId}" must be a valid topic part!`,
|
|
218
212
|
);
|
|
219
213
|
}
|
|
@@ -230,7 +224,5 @@ async function getContentPointerFor(
|
|
|
230
224
|
};
|
|
231
225
|
}
|
|
232
226
|
|
|
233
|
-
throw new
|
|
234
|
-
`Unable to find content for prose link: "${contentId}"!`,
|
|
235
|
-
);
|
|
227
|
+
throw new Error(`Unable to find content for prose link: "${contentId}"!`);
|
|
236
228
|
}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { ToProseElement } from 'tsprose';
|
|
2
|
+
import type { ProblemSchema } from '@erudit-js/prose/elements/problem/problem';
|
|
3
|
+
import type { SubProblemSchema } from '@erudit-js/prose/elements/problem/problems';
|
|
4
4
|
import { createProblemScriptStorage as _createProblemScriptStorage } from '@erudit-js/prose/elements/problem/storage';
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
element:
|
|
8
|
-
|
|
9
|
-
| ProseElement<typeof subProblemSchema>,
|
|
10
|
-
storage: GenericStorage,
|
|
6
|
+
export function createProblemScriptStorage(
|
|
7
|
+
element: ToProseElement<ProblemSchema> | ToProseElement<SubProblemSchema>,
|
|
8
|
+
storageKey: string,
|
|
11
9
|
) {
|
|
12
|
-
if (!element.storageKey) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
10
|
const runtimeConfig = useRuntimeConfig();
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
return _createProblemScriptStorage(
|
|
19
13
|
ERUDIT.paths.project(),
|
|
20
14
|
runtimeConfig.app.baseURL,
|
|
21
|
-
|
|
15
|
+
storageKey.replace('problemScript:', ''),
|
|
22
16
|
);
|
|
23
17
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ToProseElement } from 'tsprose';
|
|
2
|
+
import type {
|
|
3
|
+
VideoSchema,
|
|
4
|
+
VideoStorage,
|
|
5
|
+
} from '@erudit-js/prose/elements/video/core';
|
|
3
6
|
import { createVideoStorage as _createVideoStorage } from '@erudit-js/prose/elements/video/storage';
|
|
4
7
|
|
|
5
|
-
export
|
|
6
|
-
element:
|
|
7
|
-
|
|
8
|
-
) {
|
|
8
|
+
export function createVideoStorage(
|
|
9
|
+
element: ToProseElement<VideoSchema>,
|
|
10
|
+
): VideoStorage {
|
|
9
11
|
const runtimeConfig = useRuntimeConfig();
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
return _createVideoStorage(
|
|
12
14
|
ERUDIT.paths.project(),
|
|
13
15
|
runtimeConfig.app.baseURL,
|
|
14
16
|
element.data.src,
|