@vigilkids/cms-nuxt 0.0.2 → 0.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/dist/module.json +1 -1
- package/dist/module.mjs +4 -0
- package/dist/runtime/composables/useArticle.js +5 -3
- package/dist/runtime/composables/useArticleList.js +1 -1
- package/dist/runtime/composables/useAuthor.js +8 -6
- package/dist/runtime/composables/useBlogSeo.js +1 -1
- package/dist/runtime/composables/useCategories.js +6 -7
- package/dist/runtime/composables/useCmsClient.js +1 -1
- package/dist/runtime/composables/useCmsPreview.js +19 -6
- package/dist/runtime/server/api/_revalidate.post.js +6 -4
- package/dist/runtime/server/api/preview.get.js +3 -3
- package/dist/runtime/server/middleware/preview-context.d.ts +0 -0
- package/dist/runtime/server/middleware/preview-context.js +10 -0
- package/dist/runtime/server/middleware/redirects.js +3 -2
- package/dist/runtime/server/utils/cms-client.js +1 -1
- package/package.json +9 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -49,6 +49,10 @@ const module = defineNuxtModule({
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
if (options.preview?.enabled !== false) {
|
|
52
|
+
addServerHandler({
|
|
53
|
+
middleware: true,
|
|
54
|
+
handler: resolve("./runtime/server/middleware/preview-context")
|
|
55
|
+
});
|
|
52
56
|
addServerHandler({
|
|
53
57
|
route: "/api/preview",
|
|
54
58
|
method: "get",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { toRef } from "vue";
|
|
2
1
|
import { useAsyncData, useHead, useRuntimeConfig, useSeoMeta } from "#imports";
|
|
2
|
+
import { toRef } from "vue";
|
|
3
3
|
import { useCmsClient } from "./useCmsClient.js";
|
|
4
4
|
export function useArticle(slug) {
|
|
5
5
|
const resolvedSlug = toRef(slug);
|
|
@@ -29,14 +29,16 @@ export function useArticle(slug) {
|
|
|
29
29
|
});
|
|
30
30
|
useHead({
|
|
31
31
|
script: () => {
|
|
32
|
-
if (!article.value?.json_ld || Object.keys(article.value.json_ld).length === 0)
|
|
32
|
+
if (!article.value?.json_ld || Object.keys(article.value.json_ld).length === 0)
|
|
33
|
+
return [];
|
|
33
34
|
return [{ type: "application/ld+json", innerHTML: JSON.stringify(article.value.json_ld) }];
|
|
34
35
|
}
|
|
35
36
|
});
|
|
36
37
|
useHead({
|
|
37
38
|
link: () => {
|
|
38
39
|
const a = article.value;
|
|
39
|
-
if (!a?.available_locales || a.available_locales.length <= 1)
|
|
40
|
+
if (!a?.available_locales || a.available_locales.length <= 1)
|
|
41
|
+
return [];
|
|
40
42
|
const publicConfig = useRuntimeConfig().public;
|
|
41
43
|
const siteUrl = publicConfig.siteUrl ?? "";
|
|
42
44
|
const links = a.available_locales.map((locale) => ({
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { toRef } from "vue";
|
|
2
1
|
import { useAsyncData } from "#imports";
|
|
2
|
+
import { toRef } from "vue";
|
|
3
3
|
import { useCmsClient } from "./useCmsClient.js";
|
|
4
4
|
export function useAuthor(slug) {
|
|
5
5
|
const resolvedSlug = toRef(slug);
|
|
6
6
|
const client = useCmsClient();
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
7
|
+
const {
|
|
8
|
+
data: author,
|
|
9
|
+
status,
|
|
10
|
+
error
|
|
11
|
+
} = useAsyncData(`cms-author-${resolvedSlug.value}`, () => client.getAuthor(resolvedSlug.value), {
|
|
12
|
+
watch: [resolvedSlug]
|
|
13
|
+
});
|
|
12
14
|
const { data: articles } = useAsyncData(
|
|
13
15
|
`cms-author-articles-${resolvedSlug.value}`,
|
|
14
16
|
() => client.getAuthorArticles(resolvedSlug.value),
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { computed } from "vue";
|
|
2
1
|
import { useAsyncData } from "#imports";
|
|
2
|
+
import { computed } from "vue";
|
|
3
3
|
import { useCmsClient } from "./useCmsClient.js";
|
|
4
4
|
export function useCategories() {
|
|
5
5
|
const client = useCmsClient();
|
|
6
|
-
const { data, status, error } = useAsyncData(
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
{ dedupe: "defer" }
|
|
10
|
-
);
|
|
6
|
+
const { data, status, error } = useAsyncData("cms-categories", () => client.getCategories(), {
|
|
7
|
+
dedupe: "defer"
|
|
8
|
+
});
|
|
11
9
|
const categories = computed(() => data.value ?? []);
|
|
12
10
|
const flatCategories = computed(() => {
|
|
13
11
|
const result = [];
|
|
14
12
|
function flatten(nodes) {
|
|
15
13
|
for (const node of nodes) {
|
|
16
14
|
result.push(node);
|
|
17
|
-
if (node.children?.length)
|
|
15
|
+
if (node.children?.length)
|
|
16
|
+
flatten(node.children);
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
19
|
flatten(categories.value);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CmsClient } from "@vigilkids/cms-client";
|
|
2
1
|
import { useRuntimeConfig, useState } from "#imports";
|
|
2
|
+
import { CmsClient } from "@vigilkids/cms-client";
|
|
3
3
|
export function useCmsClient() {
|
|
4
4
|
const config = useRuntimeConfig();
|
|
5
5
|
const previewToken = useState("cmsPreviewToken", () => null);
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useCookie, useRequestEvent, useRoute, useRuntimeConfig } from "#imports";
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
export function useCmsPreviewToken() {
|
|
4
|
+
const config = useRuntimeConfig();
|
|
5
|
+
const cookieName = config.public.cms.preview?.cookieName ?? "__preview_token";
|
|
6
|
+
if (import.meta.server) {
|
|
7
|
+
const event = useRequestEvent();
|
|
8
|
+
const token = event?.context?.__cms_preview_token ?? null;
|
|
9
|
+
return ref(token);
|
|
10
|
+
}
|
|
11
|
+
const cookie = useCookie(cookieName);
|
|
12
|
+
return computed(
|
|
13
|
+
() => cookie.value ? decodeURIComponent(cookie.value) : null
|
|
14
|
+
);
|
|
15
|
+
}
|
|
3
16
|
export function useCmsPreview() {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
17
|
+
const token = useCmsPreviewToken();
|
|
18
|
+
const route = useRoute();
|
|
19
|
+
const isPreview = computed(() => !!token.value || route.query._preview === "1");
|
|
6
20
|
function exitPreview() {
|
|
7
|
-
previewToken.value = null;
|
|
8
21
|
if (import.meta.client) {
|
|
9
22
|
const config = useRuntimeConfig();
|
|
10
23
|
const cookieName = config.public.cms.preview?.cookieName ?? "__preview_token";
|
|
@@ -12,5 +25,5 @@ export function useCmsPreview() {
|
|
|
12
25
|
window.location.reload();
|
|
13
26
|
}
|
|
14
27
|
}
|
|
15
|
-
return { isPreview, previewToken, exitPreview };
|
|
28
|
+
return { isPreview, previewToken: token, exitPreview };
|
|
16
29
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createError, defineEventHandler, getHeader, readRawBody } from "h3";
|
|
2
1
|
import { useRuntimeConfig, useStorage } from "#imports";
|
|
3
2
|
import { verifyWebhookSignature } from "@vigilkids/cms-client/webhook";
|
|
3
|
+
import { createError, defineEventHandler, getHeader, readRawBody } from "h3";
|
|
4
4
|
export default defineEventHandler(async (event) => {
|
|
5
5
|
const config = useRuntimeConfig();
|
|
6
6
|
const secret = config.cms.webhookSecret;
|
|
@@ -29,11 +29,13 @@ export default defineEventHandler(async (event) => {
|
|
|
29
29
|
paths.push(`${localePrefix}/blog/${payload.slug}`);
|
|
30
30
|
paths.push(`${localePrefix}/blog`);
|
|
31
31
|
const storage = useStorage("cache:nitro:routes");
|
|
32
|
+
const allKeys = await storage.getKeys("_:");
|
|
32
33
|
let cleared = 0;
|
|
33
34
|
for (const path of paths) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const escapedPrefix = path.replace(/\W/g, "").slice(0, 16);
|
|
36
|
+
const matchingKeys = allKeys.filter((k) => k.startsWith(`_:${escapedPrefix}.`));
|
|
37
|
+
for (const key of matchingKeys) {
|
|
38
|
+
await storage.removeItem(key);
|
|
37
39
|
cleared++;
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createError, defineEventHandler, getQuery, sendRedirect, setCookie } from "h3";
|
|
2
1
|
import { useRuntimeConfig } from "#imports";
|
|
2
|
+
import { createError, defineEventHandler, getQuery, sendRedirect, setCookie } from "h3";
|
|
3
3
|
export default defineEventHandler(async (event) => {
|
|
4
4
|
const query = getQuery(event);
|
|
5
5
|
const token = query.token;
|
|
@@ -23,9 +23,9 @@ export default defineEventHandler(async (event) => {
|
|
|
23
23
|
let prefix = "";
|
|
24
24
|
if (locale && locale !== defaultLocale) {
|
|
25
25
|
const prefixes = cmsConfig.localePrefixes ?? {};
|
|
26
|
-
prefix =
|
|
26
|
+
prefix = `/${prefixes[locale] ?? locale.toLowerCase()}`;
|
|
27
27
|
}
|
|
28
28
|
const articlePath = cmsConfig.preview?.articlePath ?? "/blog/{slug}";
|
|
29
29
|
const path = articlePath.replace("{slug}", slug);
|
|
30
|
-
return sendRedirect(event, `${prefix}${path}`, 302);
|
|
30
|
+
return sendRedirect(event, `${prefix}${path}?_preview=1`, 302);
|
|
31
31
|
});
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "#imports";
|
|
2
|
+
import { defineEventHandler, getCookie } from "h3";
|
|
3
|
+
export default defineEventHandler((event) => {
|
|
4
|
+
const config = useRuntimeConfig();
|
|
5
|
+
const cookieName = config.public.cms.preview?.cookieName ?? "__preview_token";
|
|
6
|
+
const raw = getCookie(event, cookieName);
|
|
7
|
+
if (raw) {
|
|
8
|
+
event.context.__cms_preview_token = decodeURIComponent(raw);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { defineEventHandler, getRequestURL, sendRedirect } from "h3";
|
|
2
1
|
import { useRuntimeConfig } from "#imports";
|
|
2
|
+
import { defineEventHandler, getRequestURL, sendRedirect } from "h3";
|
|
3
3
|
let cachedRules = null;
|
|
4
4
|
let cacheExpiry = 0;
|
|
5
5
|
async function loadRules() {
|
|
6
6
|
const now = Date.now();
|
|
7
|
-
if (cachedRules && now < cacheExpiry)
|
|
7
|
+
if (cachedRules && now < cacheExpiry)
|
|
8
|
+
return cachedRules;
|
|
8
9
|
const config = useRuntimeConfig();
|
|
9
10
|
const cacheTtl = config.cms.redirects?.cacheTtl ?? 3e5;
|
|
10
11
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vigilkids/cms-nuxt",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Nuxt 3 module for OnEx CMS — composables, server routes, middleware, sitemap",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/module.mjs",
|
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
"sideEffects": false,
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "nuxt-module-build build",
|
|
20
|
-
"prepack": "nuxt-module-build build"
|
|
20
|
+
"prepack": "nuxt-module-build build",
|
|
21
|
+
"lint": "eslint .",
|
|
22
|
+
"lint:fix": "eslint . --fix",
|
|
23
|
+
"format": "prettier --write src/"
|
|
21
24
|
},
|
|
22
25
|
"publishConfig": {
|
|
23
26
|
"access": "public"
|
|
@@ -28,11 +31,15 @@
|
|
|
28
31
|
"directory": "packages/cms-nuxt"
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|
|
34
|
+
"@antfu/eslint-config": "^4.13.2",
|
|
31
35
|
"@nuxt/kit": "^3.15.0",
|
|
32
36
|
"@nuxt/module-builder": "^0.8.0",
|
|
33
37
|
"@nuxt/schema": "^3.15.0",
|
|
34
38
|
"@types/node": "^22.0.0",
|
|
39
|
+
"eslint": "^9.22.0",
|
|
40
|
+
"eslint-config-prettier": "^10.1.1",
|
|
35
41
|
"h3": "^1.12.0",
|
|
42
|
+
"prettier": "^3.5.3",
|
|
36
43
|
"vue": "^3.4.0"
|
|
37
44
|
},
|
|
38
45
|
"peerDependencies": {
|