erudit 3.0.0-dev.13 → 3.0.0-dev.15

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.
@@ -1,12 +1,12 @@
1
1
  <script lang="ts" setup>
2
- import type { AsideMinorData } from '@shared/asideMinor';
2
+ import type { AsideMinorData } from '@shared/aside/minor';
3
+ import { trailingSlash } from '@erudit/utils/slash';
3
4
  import { asideMinorKey } from '@app/scripts/aside/minor/state';
4
5
 
5
6
  import {
6
7
  LazyAsideMinorNews,
7
8
  LazyAsideMinorTopic,
8
9
  LazyAsideMinorContent,
9
- LazyAsideMinorContributor,
10
10
  } from '#components';
11
11
 
12
12
  let setupI = 0;
@@ -19,7 +19,7 @@ const AsideMinorPane = shallowRef<Component>();
19
19
 
20
20
  async function setupAsideMinorData() {
21
21
  const currentSetupI = ++setupI;
22
- const path = route.path;
22
+ const dataKey = trailingSlash(route.path, false);
23
23
  const payloadKey = 'aside-minor';
24
24
  const asideMinorPayload =
25
25
  (nuxtApp.static.data[payloadKey] ||=
@@ -28,8 +28,8 @@ async function setupAsideMinorData() {
28
28
 
29
29
  const data: AsideMinorData = await (async () => {
30
30
  const payloadKeyValue: AsideMinorData | 'news' = (asideMinorPayload[
31
- path
32
- ] ||= await $fetch(`/api/aside/minor/path`, { query: { path } }));
31
+ dataKey
32
+ ] ||= await $fetch(`/api/aside/minor/path`, { query: { path: dataKey } }));
33
33
 
34
34
  if (payloadKeyValue === 'news') {
35
35
  // We do not save news in the payload as it will always have the same content.
@@ -16,7 +16,7 @@ const paneVisible = defineModel<boolean>('pane');
16
16
  const issueLink = computed(() => {
17
17
  const ghRepositorty = eruditConfig.repository;
18
18
  return ghRepositorty
19
- ? `https://github.com/${ghRepositorty.name}/issues/`
19
+ ? `https://github.com/${ghRepositorty.name}/issues/new/choose`
20
20
  : null;
21
21
  });
22
22
 
@@ -1,3 +1,4 @@
1
+ import { trailingSlash } from '@erudit/utils/slash';
1
2
  import type { ContentData } from '@shared/content/data';
2
3
 
3
4
  export function useContentData<T extends ContentData>() {
@@ -21,12 +22,13 @@ export function useContentData<T extends ContentData>() {
21
22
  return;
22
23
  }
23
24
 
24
- const contentId = contentRoute.value.contentId;
25
+ const dataKey = trailingSlash(contentRoute.value.contentId, false);
25
26
 
26
- const payloadValue = (payload[contentId] ||= await $fetch(
27
+ const payloadValue = (payload[dataKey] ||= await $fetch(
27
28
  '/api/content/data',
28
- { query: { contentId } },
29
+ { query: { contentId: dataKey } },
29
30
  ));
31
+
30
32
  data.value = payloadValue as T;
31
33
  return data;
32
34
  })();
package/module/restart.ts CHANGED
@@ -15,9 +15,9 @@ const watchTargets: string[] = [
15
15
  // Erudit Nuxt module non-runtime files
16
16
  ...globSync(eruditPath('module/**/*')),
17
17
  // Erudit config in project root
18
- ...globSync(projectPath('erudit.{js,ts}')),
18
+ ...globSync(projectPath('erudit.config.{js,ts}')),
19
19
  // Erudit Bitran config in project root
20
- ...globSync(projectPath('bitran.{js,ts}')),
20
+ ...globSync(projectPath('bitran.{app,server}.{js,ts}')),
21
21
  ];
22
22
 
23
23
  const ignoreTargets: string[] = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "erudit",
3
- "version": "3.0.0-dev.13",
3
+ "version": "3.0.0-dev.15",
4
4
  "type": "module",
5
5
  "description": "🤓 CMS for perfect educational sites.",
6
6
  "license": "MIT",
@@ -15,9 +15,9 @@
15
15
  "erudit": "bin/erudit.mjs"
16
16
  },
17
17
  "peerDependencies": {
18
- "@erudit-js/cog": "3.0.0-dev.13",
19
- "@erudit-js/cli": "3.0.0-dev.13",
20
- "@erudit-js/bitran-elements": "3.0.0-dev.13"
18
+ "@erudit-js/cog": "3.0.0-dev.15",
19
+ "@erudit-js/cli": "3.0.0-dev.15",
20
+ "@erudit-js/bitran-elements": "3.0.0-dev.15"
21
21
  },
22
22
  "dependencies": {
23
23
  "@bitran-js/core": "1.0.0-dev.13",
@@ -30,8 +30,8 @@
30
30
  "glob": "^11.0.1",
31
31
  "image-size": "^2.0.2",
32
32
  "jiti": "^2.4.2",
33
- "nuxt": "3.17.0",
34
- "nuxt-my-icons": "1.0.2",
33
+ "nuxt": "3.17.2",
34
+ "nuxt-my-icons": "1.1.1",
35
35
  "sass": "^1.86.2",
36
36
  "sqlite3": "^5.1.7",
37
37
  "typeorm": "^0.3.22",
@@ -7,10 +7,7 @@ import {
7
7
  getPreviousNext,
8
8
  } from '@server/repository/content';
9
9
  import { getTopicPartsLinks } from '@server/repository/topic';
10
- import {
11
- getFullContentId,
12
- getShortContentId,
13
- } from '@server/repository/contentId';
10
+ import { getFullContentId } from '@server/repository/contentId';
14
11
 
15
12
  export default defineEventHandler(async (event) => {
16
13
  const query = getQuery<{ path: string }>(event);
@@ -72,7 +69,7 @@ async function createContentData(
72
69
  path: string,
73
70
  ): Promise<AsideMinorContent> {
74
71
  const rawContentId = path.split('/').slice(1).join('/');
75
- const contentId = (await getFullContentId(rawContentId))!;
72
+ const contentId = getFullContentId(rawContentId);
76
73
  const previousNext = await getPreviousNext(contentId);
77
74
  const contributors = await getContentContributors(contentId);
78
75
 
@@ -140,7 +140,12 @@ async function createBitranContent(
140
140
  mergeAliases(context.aliases, node.parseData);
141
141
  break;
142
142
  case node instanceof IncludeNode:
143
- await resolveInclude(node, context);
143
+ const includeNode = await resolveInclude(node, context);
144
+ await walkDown(includeNode, async (child) => {
145
+ if (child instanceof ElementNode) {
146
+ await makePreRender(child);
147
+ }
148
+ });
144
149
  break;
145
150
  case node instanceof BlockErrorNode:
146
151
  case node instanceof InlinerErrorNode:
@@ -149,16 +154,6 @@ async function createBitranContent(
149
154
  }
150
155
 
151
156
  await makePreRender(node);
152
-
153
- if (node instanceof IncludeNode) {
154
- for (const block of node.parseData.blocks?.children || []) {
155
- await walkDown(block, async (child) => {
156
- if (child instanceof ElementNode) {
157
- await makePreRender(child);
158
- }
159
- });
160
- }
161
- }
162
157
  },
163
158
  });
164
159
 
@@ -15,17 +15,18 @@ import {
15
15
  type NavNode,
16
16
  type RootNavNode,
17
17
  } from '@server/nav/node';
18
- import { ERUDIT_SERVER } from '../../global';
18
+ import { ERUDIT_SERVER } from '@server/global';
19
+ import { readFileSync } from 'fs';
19
20
 
20
21
  type Ids = Record<string, string>;
21
22
  let ids: Ids;
22
23
 
23
- const contentTargets = ERUDIT_SERVER.CONFIG?.contentTargets || [];
24
-
25
24
  const nodePathRegexp = new RegExp(
26
25
  `(?<pos>\\d+)(?<sep>-|\\+)(?<id>[\\w-]+)\\/(?<type>${contentTypes.join('|')})\\..*`,
27
26
  );
28
27
 
28
+ const contentFilter = createContentFilter();
29
+
29
30
  export async function buildNav() {
30
31
  debug.start('Building navigation tree...');
31
32
 
@@ -88,8 +89,6 @@ async function scanChildNodes(
88
89
  continue;
89
90
  }
90
91
 
91
- if (!satisfiesContentTargets(nodePath)) continue; // Not a content target
92
-
93
92
  const parentId = isRootNode(parent)
94
93
  ? ''
95
94
  : parent.skip
@@ -129,6 +128,30 @@ async function scanChildNodes(
129
128
  return ids.join('/');
130
129
  })();
131
130
 
131
+ const shouldSkip = (() => {
132
+ const targets = [
133
+ ...contentFilter.cliContentTargets,
134
+ ...(ERUDIT_SERVER.CONFIG?.contentTargets || []),
135
+ ];
136
+
137
+ // If there are no filters, allow all nodes
138
+ if (targets.length === 0) {
139
+ return false;
140
+ }
141
+
142
+ // If the node passes at least one filter, keep it
143
+ for (const target of targets) {
144
+ if (contentFilter.strFilter(fullId, target)) {
145
+ return false;
146
+ }
147
+ }
148
+
149
+ // Node failed all filters, skip it
150
+ return true;
151
+ })();
152
+
153
+ if (shouldSkip) continue;
154
+
132
155
  const skip = pathParts.sep === '+';
133
156
 
134
157
  const childNode: NavNode = {
@@ -177,14 +200,29 @@ async function scanChildNodes(
177
200
  };
178
201
  }
179
202
 
180
- function satisfiesContentTargets(nodePath: string): boolean {
181
- if (contentTargets.length === 0) return true;
203
+ function createContentFilter() {
204
+ const cliContentTargets = (() => {
205
+ try {
206
+ return JSON.parse(
207
+ readFileSync(PROJECT_DIR + '/.erudit/targets.json', 'utf-8'),
208
+ );
209
+ } catch (error) {}
182
210
 
183
- for (const target of contentTargets)
184
- if (nodePath.startsWith(target) || target.search(nodePath) === 0)
211
+ return [];
212
+ })();
213
+
214
+ const strFilter = (fullId: string, filterItem: string) => {
215
+ if (fullId.startsWith(filterItem) || filterItem.search(fullId) === 0) {
185
216
  return true;
217
+ }
186
218
 
187
- return false;
219
+ return false;
220
+ };
221
+
222
+ return {
223
+ cliContentTargets,
224
+ strFilter,
225
+ };
188
226
  }
189
227
 
190
228
  function validNode(node: NavNode): boolean {
@@ -1,3 +1,5 @@
1
+ import { resetDatabase } from '@server/db/reset';
2
+ import { ERUDIT_SERVER } from '@server/global';
1
3
  import { debug, logger } from '@server/logger';
2
4
 
3
5
  import { setup } from './setup';
@@ -5,11 +7,10 @@ import { setupLanguage } from './jobs/language';
5
7
  import { buildContributors } from './jobs/contributors';
6
8
  import { buildNav } from './jobs/nav';
7
9
  import { buildContent } from './jobs/content/generic';
8
- import { resetDatabase } from '../db/reset';
9
10
 
10
11
  let initial = true;
11
12
 
12
- export async function build() {
13
+ async function _build() {
13
14
  debug.start('Building data...');
14
15
 
15
16
  if (initial) {
@@ -25,3 +26,7 @@ export async function build() {
25
26
 
26
27
  logger.success('Build successful!');
27
28
  }
29
+
30
+ export async function build() {
31
+ ERUDIT_SERVER.BUILD_PROMISE = _build();
32
+ }
@@ -3,7 +3,7 @@ import { DataSource } from 'typeorm';
3
3
 
4
4
  import { PROJECT_DIR } from '#erudit/globalPaths';
5
5
  import { ERUDIT_SERVER } from '@server/global';
6
- import { logger } from '../logger';
6
+ import { logger } from '@server/logger';
7
7
 
8
8
  // Database Entities
9
9
  import { DbContributor } from './entities/Contributor';
@@ -1,9 +1,9 @@
1
- import { ERUDIT_SERVER } from './global';
2
- import { build } from './build/process';
3
- import { close } from './build/close';
1
+ import { ERUDIT_SERVER } from '@server/global';
2
+ import { build } from '@server/build/process';
3
+ import { close } from '@server/build/close';
4
4
 
5
5
  export default defineNitroPlugin((_nitro) => {
6
- ERUDIT_SERVER.BUILD_PROMISE = build();
6
+ build();
7
7
  _nitro.hooks.hook('request', async () => await ERUDIT_SERVER.BUILD_PROMISE);
8
8
  _nitro.hooks.hook('close', close);
9
9
  });
package/utils/slash.ts ADDED
@@ -0,0 +1,11 @@
1
+ export function trailingSlash(path: string, add: boolean): string {
2
+ if (path === '/') {
3
+ return '/';
4
+ }
5
+
6
+ if (add) {
7
+ return path.endsWith('/') ? path : `${path}/`;
8
+ }
9
+
10
+ return path.endsWith('/') ? path.slice(0, -1) : path;
11
+ }