erudit 4.1.0 → 4.1.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/app/components/main/connections/Deps.vue +1 -3
- package/app/components/main/connections/Externals.vue +3 -3
- package/package.json +4 -4
- package/server/erudit/content/repository/deps.ts +35 -35
- package/server/erudit/content/resolve/index.ts +6 -1
- package/server/erudit/content/resolve/utils/insertContentItem.ts +2 -2
- package/server/erudit/content/resolve/utils/insertContentResolved.ts +9 -1
|
@@ -5,9 +5,7 @@ defineProps<{ deps: ContentDep[] }>();
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<template>
|
|
8
|
-
<ScrollPane
|
|
9
|
-
class="py-normal gap-main-half flex max-h-[min(500px,30dvh)] flex-col"
|
|
10
|
-
>
|
|
8
|
+
<ScrollPane class="py-normal gap-main-half max-h-[50dvh)] flex flex-col">
|
|
11
9
|
<div v-for="dep of deps" class="gap-small flex">
|
|
12
10
|
<MyIcon :name="ICONS[dep.contentType]" class="relative top-1 shrink-0" />
|
|
13
11
|
<div class="flex flex-col gap-0.5">
|
|
@@ -8,12 +8,12 @@ const phrase = await usePhrases('externals_own', 'externals_from');
|
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<template>
|
|
11
|
-
<ScrollPane class="max-h-[
|
|
11
|
+
<ScrollPane class="max-h-[50dvh]">
|
|
12
12
|
<div v-for="group of externals">
|
|
13
13
|
<div
|
|
14
14
|
:class="[
|
|
15
|
-
`border-border gap-small pl-small py-small
|
|
16
|
-
|
|
15
|
+
`border-border gap-small pl-small py-small sticky top-0 z-10 flex
|
|
16
|
+
w-full items-center border-b border-dashed backdrop-blur-sm`,
|
|
17
17
|
group.type === 'own'
|
|
18
18
|
? 'font-semibold text-amber-600 dark:text-amber-400'
|
|
19
19
|
: 'text-text-muted',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "erudit",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "🤓 CMS for perfect educational sites.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@erudit-js/cli": "4.1.
|
|
28
|
-
"@erudit-js/core": "4.1.
|
|
29
|
-
"@erudit-js/prose": "4.1.
|
|
27
|
+
"@erudit-js/cli": "4.1.1",
|
|
28
|
+
"@erudit-js/core": "4.1.1",
|
|
29
|
+
"@erudit-js/prose": "4.1.1",
|
|
30
30
|
"unslash": "^2.0.0",
|
|
31
31
|
"@floating-ui/vue": "^1.1.10",
|
|
32
32
|
"@jsprose/core": "^1.0.0",
|
|
@@ -4,11 +4,11 @@ export async function getContentDependencies(fullId: string) {
|
|
|
4
4
|
const hardDependencies: ContentHardDep[] = [];
|
|
5
5
|
|
|
6
6
|
const dbHardDependencies = await ERUDIT.db.query.contentDeps.findMany({
|
|
7
|
-
columns: {
|
|
7
|
+
columns: { toFullId: true, hard: true, reason: true },
|
|
8
8
|
where: and(
|
|
9
9
|
or(
|
|
10
|
-
eq(ERUDIT.db.schema.contentDeps.
|
|
11
|
-
like(ERUDIT.db.schema.contentDeps.
|
|
10
|
+
eq(ERUDIT.db.schema.contentDeps.fromFullId, fullId),
|
|
11
|
+
like(ERUDIT.db.schema.contentDeps.fromFullId, `${fullId}/%`),
|
|
12
12
|
),
|
|
13
13
|
eq(ERUDIT.db.schema.contentDeps.hard, true),
|
|
14
14
|
),
|
|
@@ -16,18 +16,18 @@ export async function getContentDependencies(fullId: string) {
|
|
|
16
16
|
|
|
17
17
|
const fullId2Reason = dbHardDependencies.reduce((map, dbDependency) => {
|
|
18
18
|
if (dbDependency.reason) {
|
|
19
|
-
map.set(dbDependency.
|
|
19
|
+
map.set(dbDependency.toFullId, dbDependency.reason);
|
|
20
20
|
}
|
|
21
21
|
return map;
|
|
22
22
|
}, new Map<string, string>());
|
|
23
23
|
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const hardToFullIds = ERUDIT.contentNav.orderIds(
|
|
25
|
+
externalToFullIds(dbHardDependencies),
|
|
26
26
|
);
|
|
27
27
|
|
|
28
|
-
for (const
|
|
29
|
-
const reason = fullId2Reason.get(
|
|
30
|
-
const hardDep = await createContentDep('hard',
|
|
28
|
+
for (const toFullId of hardToFullIds) {
|
|
29
|
+
const reason = fullId2Reason.get(toFullId)!;
|
|
30
|
+
const hardDep = await createContentDep('hard', toFullId, reason);
|
|
31
31
|
if (hardDep) {
|
|
32
32
|
hardDependencies.push(hardDep);
|
|
33
33
|
}
|
|
@@ -40,23 +40,23 @@ export async function getContentDependencies(fullId: string) {
|
|
|
40
40
|
const autoDependencies: ContentAutoDep[] = [];
|
|
41
41
|
|
|
42
42
|
const dbAutoDependencies = await ERUDIT.db.query.contentDeps.findMany({
|
|
43
|
-
columns: {
|
|
43
|
+
columns: { toFullId: true, hard: true },
|
|
44
44
|
where: and(
|
|
45
45
|
or(
|
|
46
|
-
eq(ERUDIT.db.schema.contentDeps.
|
|
47
|
-
like(ERUDIT.db.schema.contentDeps.
|
|
46
|
+
eq(ERUDIT.db.schema.contentDeps.fromFullId, fullId),
|
|
47
|
+
like(ERUDIT.db.schema.contentDeps.fromFullId, `${fullId}/%`),
|
|
48
48
|
),
|
|
49
49
|
eq(ERUDIT.db.schema.contentDeps.hard, false),
|
|
50
50
|
),
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
// Skip auto-dependency if a hard dependency from the same source exists
|
|
54
|
-
const
|
|
55
|
-
.orderIds(
|
|
56
|
-
.filter((
|
|
54
|
+
const autoToFullIds = ERUDIT.contentNav
|
|
55
|
+
.orderIds(externalToFullIds(dbAutoDependencies))
|
|
56
|
+
.filter((toFullId) => !fullId2Reason.has(toFullId));
|
|
57
57
|
|
|
58
|
-
for (const
|
|
59
|
-
const autoDep = await createContentDep('auto',
|
|
58
|
+
for (const toFullId of autoToFullIds) {
|
|
59
|
+
const autoDep = await createContentDep('auto', toFullId);
|
|
60
60
|
if (autoDep) {
|
|
61
61
|
autoDependencies.push(autoDep);
|
|
62
62
|
}
|
|
@@ -72,17 +72,17 @@ export async function getContentDependencies(fullId: string) {
|
|
|
72
72
|
//
|
|
73
73
|
|
|
74
74
|
// Skip dependency if it originates from current content item or its child
|
|
75
|
-
function
|
|
75
|
+
function externalToFullIds(dbDeps: { toFullId: string }[]) {
|
|
76
76
|
return dbDeps.reduce((ids, dbDep) => {
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
const
|
|
77
|
+
const toFullId = dbDep.toFullId;
|
|
78
|
+
const isToSelf = toFullId === fullId;
|
|
79
|
+
const isToChild = toFullId.startsWith(`${fullId}/`);
|
|
80
80
|
|
|
81
|
-
if (
|
|
81
|
+
if (isToSelf || isToChild) {
|
|
82
82
|
return ids;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
ids.push(
|
|
85
|
+
ids.push(toFullId);
|
|
86
86
|
return ids;
|
|
87
87
|
}, [] as string[]);
|
|
88
88
|
}
|
|
@@ -94,30 +94,30 @@ export async function getContentDependents(
|
|
|
94
94
|
const dbDependents = await ERUDIT.db.query.contentDeps.findMany({
|
|
95
95
|
columns: { fromFullId: true, toFullId: true },
|
|
96
96
|
where: or(
|
|
97
|
-
eq(ERUDIT.db.schema.contentDeps.
|
|
98
|
-
like(ERUDIT.db.schema.contentDeps.
|
|
97
|
+
eq(ERUDIT.db.schema.contentDeps.toFullId, fullId),
|
|
98
|
+
like(ERUDIT.db.schema.contentDeps.toFullId, `${fullId}/%`),
|
|
99
99
|
),
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
// Skip dependent if it
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
102
|
+
// Skip dependent if it originates from current content item or its child
|
|
103
|
+
const externalFromFullIds = dbDependents.reduce((ids, dbDependent) => {
|
|
104
|
+
const fromFullId = dbDependent.fromFullId;
|
|
105
|
+
const isFromSelf = fromFullId === fullId;
|
|
106
|
+
const isFromChild = fromFullId.startsWith(`${fullId}/`);
|
|
107
107
|
|
|
108
|
-
if (
|
|
108
|
+
if (isFromSelf || isFromChild) {
|
|
109
109
|
return ids;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
ids.push(
|
|
112
|
+
ids.push(fromFullId);
|
|
113
113
|
return ids;
|
|
114
114
|
}, [] as string[]);
|
|
115
115
|
|
|
116
|
-
// Order
|
|
117
|
-
const
|
|
116
|
+
// Order sources according to nav structure
|
|
117
|
+
const fromFullIds = ERUDIT.contentNav.orderIds(externalFromFullIds);
|
|
118
118
|
|
|
119
119
|
const dependents = await Promise.all(
|
|
120
|
-
|
|
120
|
+
fromFullIds.map((fromFullId) => createContentDep('auto', fromFullId)),
|
|
121
121
|
);
|
|
122
122
|
|
|
123
123
|
return dependents.filter((dep): dep is ContentAutoDep => dep !== undefined);
|
|
@@ -232,7 +232,12 @@ export async function clearOldContentData(contentIds: string[]) {
|
|
|
232
232
|
|
|
233
233
|
await ERUDIT.db
|
|
234
234
|
.delete(ERUDIT.db.schema.contentDeps)
|
|
235
|
-
.where(
|
|
235
|
+
.where(
|
|
236
|
+
or(
|
|
237
|
+
inArray(ERUDIT.db.schema.contentDeps.toFullId, contentIds),
|
|
238
|
+
inArray(ERUDIT.db.schema.contentDeps.fromFullId, contentIds),
|
|
239
|
+
),
|
|
240
|
+
);
|
|
236
241
|
|
|
237
242
|
await ERUDIT.db
|
|
238
243
|
.delete(ERUDIT.db.schema.contentElementStats)
|
|
@@ -78,10 +78,10 @@ async function resolveHardDependencies(
|
|
|
78
78
|
if (contentItem.dependencies) {
|
|
79
79
|
for (const dependency of contentItem.dependencies) {
|
|
80
80
|
await ERUDIT.db.insert(ERUDIT.db.schema.contentDeps).values({
|
|
81
|
-
fromFullId:
|
|
81
|
+
fromFullId: fullId,
|
|
82
|
+
toFullId: getGlobalContentPath(
|
|
82
83
|
dependency.dependency as any as GlobalContentItem,
|
|
83
84
|
),
|
|
84
|
-
toFullId: fullId,
|
|
85
85
|
hard: true,
|
|
86
86
|
reason: dependency.reason,
|
|
87
87
|
});
|
|
@@ -103,7 +103,15 @@ function filterTargetFullIds(
|
|
|
103
103
|
} else if (storageKey.startsWith('<link:global>')) {
|
|
104
104
|
try {
|
|
105
105
|
const globalContentId = storageKey.replace('<link:global>/', '');
|
|
106
|
-
|
|
106
|
+
const targetFullId = globalContentToNavNode(globalContentId).fullId;
|
|
107
|
+
|
|
108
|
+
if (
|
|
109
|
+
metas.some(
|
|
110
|
+
(meta) => meta.type === 'Dep' || meta.type === 'Dependency',
|
|
111
|
+
)
|
|
112
|
+
) {
|
|
113
|
+
targetFullIds.add(targetFullId);
|
|
114
|
+
}
|
|
107
115
|
} catch {
|
|
108
116
|
ERUDIT.log.warn(
|
|
109
117
|
brokenLinkMessage(
|