@ztl-uwu/nuxt-content 2.13.5

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 (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/dist/module.d.mts +1176 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +696 -0
  6. package/dist/runtime/app.vue +3 -0
  7. package/dist/runtime/app.vue.d.ts +2 -0
  8. package/dist/runtime/components/ContentDoc.vue +108 -0
  9. package/dist/runtime/components/ContentDoc.vue.d.ts +118 -0
  10. package/dist/runtime/components/ContentList.vue +59 -0
  11. package/dist/runtime/components/ContentList.vue.d.ts +59 -0
  12. package/dist/runtime/components/ContentNavigation.vue +61 -0
  13. package/dist/runtime/components/ContentNavigation.vue.d.ts +35 -0
  14. package/dist/runtime/components/ContentQuery.vue +212 -0
  15. package/dist/runtime/components/ContentQuery.vue.d.ts +0 -0
  16. package/dist/runtime/components/ContentRenderer.vue +78 -0
  17. package/dist/runtime/components/ContentRenderer.vue.d.ts +56 -0
  18. package/dist/runtime/components/ContentRendererMarkdown.vue +69 -0
  19. package/dist/runtime/components/ContentRendererMarkdown.vue.d.ts +73 -0
  20. package/dist/runtime/components/ContentSlot.vue +25 -0
  21. package/dist/runtime/components/ContentSlot.vue.d.ts +37 -0
  22. package/dist/runtime/components/DocumentDrivenEmpty.vue +18 -0
  23. package/dist/runtime/components/DocumentDrivenEmpty.vue.d.ts +17 -0
  24. package/dist/runtime/components/DocumentDrivenNotFound.vue +9 -0
  25. package/dist/runtime/components/DocumentDrivenNotFound.vue.d.ts +5 -0
  26. package/dist/runtime/components/Markdown.vue +29 -0
  27. package/dist/runtime/components/Markdown.vue.d.ts +31 -0
  28. package/dist/runtime/components/Prose/ProseCode.vue +32 -0
  29. package/dist/runtime/components/Prose/ProseCode.vue.d.ts +110 -0
  30. package/dist/runtime/components/Prose/ProseCodeInline.vue +3 -0
  31. package/dist/runtime/components/Prose/ProseCodeInline.vue.d.ts +14 -0
  32. package/dist/runtime/components/Prose/ProsePre.vue +42 -0
  33. package/dist/runtime/components/Prose/ProsePre.vue.d.ts +146 -0
  34. package/dist/runtime/composables/client-db.d.ts +14 -0
  35. package/dist/runtime/composables/client-db.js +105 -0
  36. package/dist/runtime/composables/content.d.ts +19 -0
  37. package/dist/runtime/composables/content.js +41 -0
  38. package/dist/runtime/composables/head.d.ts +4 -0
  39. package/dist/runtime/composables/head.js +94 -0
  40. package/dist/runtime/composables/helpers.d.ts +7 -0
  41. package/dist/runtime/composables/helpers.js +66 -0
  42. package/dist/runtime/composables/navigation.d.ts +2 -0
  43. package/dist/runtime/composables/navigation.js +34 -0
  44. package/dist/runtime/composables/preview.d.ts +5 -0
  45. package/dist/runtime/composables/preview.js +41 -0
  46. package/dist/runtime/composables/query.d.ts +10 -0
  47. package/dist/runtime/composables/query.js +64 -0
  48. package/dist/runtime/composables/search.d.ts +130 -0
  49. package/dist/runtime/composables/search.js +59 -0
  50. package/dist/runtime/composables/useUnwrap.d.ts +5 -0
  51. package/dist/runtime/composables/useUnwrap.js +5 -0
  52. package/dist/runtime/composables/utils.d.ts +6 -0
  53. package/dist/runtime/composables/utils.js +36 -0
  54. package/dist/runtime/composables/web-socket.d.ts +3 -0
  55. package/dist/runtime/composables/web-socket.js +65 -0
  56. package/dist/runtime/legacy/composables/client-db.d.ts +12 -0
  57. package/dist/runtime/legacy/composables/client-db.js +105 -0
  58. package/dist/runtime/legacy/composables/navigation.d.ts +2 -0
  59. package/dist/runtime/legacy/composables/navigation.js +34 -0
  60. package/dist/runtime/legacy/composables/query.d.ts +10 -0
  61. package/dist/runtime/legacy/composables/query.js +61 -0
  62. package/dist/runtime/legacy/plugins/documentDriven.d.ts +2 -0
  63. package/dist/runtime/legacy/plugins/documentDriven.js +231 -0
  64. package/dist/runtime/legacy/server.d.ts +3 -0
  65. package/dist/runtime/legacy/server.js +3 -0
  66. package/dist/runtime/legacy/types.d.ts +5 -0
  67. package/dist/runtime/pages/document-driven.vue +27 -0
  68. package/dist/runtime/pages/document-driven.vue.d.ts +2 -0
  69. package/dist/runtime/plugins/documentDriven.d.ts +2 -0
  70. package/dist/runtime/plugins/documentDriven.js +222 -0
  71. package/dist/runtime/plugins/ws.d.ts +2 -0
  72. package/dist/runtime/plugins/ws.js +7 -0
  73. package/dist/runtime/query/match/index.d.ts +6 -0
  74. package/dist/runtime/query/match/index.js +123 -0
  75. package/dist/runtime/query/match/pipeline-legacy.d.ts +2 -0
  76. package/dist/runtime/query/match/pipeline-legacy.js +22 -0
  77. package/dist/runtime/query/match/pipeline.d.ts +2 -0
  78. package/dist/runtime/query/match/pipeline.js +104 -0
  79. package/dist/runtime/query/match/utils.d.ts +35 -0
  80. package/dist/runtime/query/match/utils.js +65 -0
  81. package/dist/runtime/query/query.d.ts +12 -0
  82. package/dist/runtime/query/query.js +61 -0
  83. package/dist/runtime/server/api/cache.d.ts +7 -0
  84. package/dist/runtime/server/api/cache.js +18 -0
  85. package/dist/runtime/server/api/navigation-qid-params.d.ts +1 -0
  86. package/dist/runtime/server/api/navigation-qid-params.js +1 -0
  87. package/dist/runtime/server/api/navigation-qid.d.ts +1 -0
  88. package/dist/runtime/server/api/navigation-qid.js +1 -0
  89. package/dist/runtime/server/api/navigation.d.ts +2 -0
  90. package/dist/runtime/server/api/navigation.js +42 -0
  91. package/dist/runtime/server/api/query-qid-params.d.ts +1 -0
  92. package/dist/runtime/server/api/query-qid-params.js +1 -0
  93. package/dist/runtime/server/api/query-qid.d.ts +1 -0
  94. package/dist/runtime/server/api/query-qid.js +1 -0
  95. package/dist/runtime/server/api/query.d.ts +2 -0
  96. package/dist/runtime/server/api/query.js +32 -0
  97. package/dist/runtime/server/api/search.d.ts +8 -0
  98. package/dist/runtime/server/api/search.js +16 -0
  99. package/dist/runtime/server/content-index.d.ts +4 -0
  100. package/dist/runtime/server/content-index.js +37 -0
  101. package/dist/runtime/server/index.d.ts +1 -0
  102. package/dist/runtime/server/index.js +1 -0
  103. package/dist/runtime/server/navigation.d.ts +5 -0
  104. package/dist/runtime/server/navigation.js +96 -0
  105. package/dist/runtime/server/plugins/refresh-cache.d.ts +2 -0
  106. package/dist/runtime/server/plugins/refresh-cache.js +15 -0
  107. package/dist/runtime/server/preview.d.ts +5 -0
  108. package/dist/runtime/server/preview.js +9 -0
  109. package/dist/runtime/server/search.d.ts +14 -0
  110. package/dist/runtime/server/search.js +70 -0
  111. package/dist/runtime/server/storage.d.ts +35 -0
  112. package/dist/runtime/server/storage.js +238 -0
  113. package/dist/runtime/transformers/component-resolver.d.ts +2 -0
  114. package/dist/runtime/transformers/component-resolver.js +44 -0
  115. package/dist/runtime/transformers/csv/create-tokenizer.d.ts +39 -0
  116. package/dist/runtime/transformers/csv/create-tokenizer.js +307 -0
  117. package/dist/runtime/transformers/csv/from-csv.d.ts +13 -0
  118. package/dist/runtime/transformers/csv/from-csv.js +203 -0
  119. package/dist/runtime/transformers/csv/index.d.ts +2 -0
  120. package/dist/runtime/transformers/csv/index.js +50 -0
  121. package/dist/runtime/transformers/csv/parser.d.ts +24 -0
  122. package/dist/runtime/transformers/csv/parser.js +154 -0
  123. package/dist/runtime/transformers/index.d.ts +7 -0
  124. package/dist/runtime/transformers/index.js +50 -0
  125. package/dist/runtime/transformers/json.d.ts +2 -0
  126. package/dist/runtime/transformers/json.js +29 -0
  127. package/dist/runtime/transformers/markdown.d.ts +2 -0
  128. package/dist/runtime/transformers/markdown.js +88 -0
  129. package/dist/runtime/transformers/path-meta.d.ts +27 -0
  130. package/dist/runtime/transformers/path-meta.js +59 -0
  131. package/dist/runtime/transformers/utils.d.ts +3 -0
  132. package/dist/runtime/transformers/utils.js +12 -0
  133. package/dist/runtime/transformers/yaml.d.ts +2 -0
  134. package/dist/runtime/transformers/yaml.js +21 -0
  135. package/dist/runtime/utils/config.d.ts +4 -0
  136. package/dist/runtime/utils/config.js +7 -0
  137. package/dist/runtime/utils/html-tags.d.ts +2 -0
  138. package/dist/runtime/utils/html-tags.js +119 -0
  139. package/dist/runtime/utils/json.d.ts +10 -0
  140. package/dist/runtime/utils/json.js +20 -0
  141. package/dist/runtime/utils/query.d.ts +5 -0
  142. package/dist/runtime/utils/query.js +77 -0
  143. package/dist/runtime/virtual/transformers.d.ts +2 -0
  144. package/dist/types.d.mts +9 -0
  145. package/dist/web-types.json +572 -0
  146. package/package.json +111 -0
@@ -0,0 +1,104 @@
1
+ import { joinURL } from "ufo";
2
+ import { apply, ensureArray, sortList, withoutKeys, withKeys, omit } from "./utils.js";
3
+ import { createMatch } from "./index.js";
4
+ export function createPipelineFetcher(getContentsList) {
5
+ const match = createMatch();
6
+ const surround = (data, { query, before, after }) => {
7
+ const matchQuery = typeof query === "string" ? { _path: query } : query;
8
+ const index = data.findIndex((item) => match(item, matchQuery));
9
+ before = before ?? 1;
10
+ after = after ?? 1;
11
+ const slice = new Array(before + after).fill(null, 0);
12
+ return index === -1 ? slice : slice.map((_, i) => data[index - before + i + Number(i >= before)] || null);
13
+ };
14
+ const matchingPipelines = [
15
+ // Conditions
16
+ (state, params) => {
17
+ const filtered = state.result.filter((item) => ensureArray(params.where).every((matchQuery) => match(item, matchQuery)));
18
+ return {
19
+ ...state,
20
+ result: filtered,
21
+ total: filtered.length
22
+ };
23
+ },
24
+ // Sort data
25
+ (state, params) => ensureArray(params.sort).forEach((options) => sortList(state.result, options)),
26
+ function fetchSurround(state, params, db) {
27
+ if (params.surround) {
28
+ let _surround = surround(state.result?.length === 1 ? db : state.result, params.surround);
29
+ _surround = apply(withoutKeys(params.without))(_surround);
30
+ _surround = apply(withKeys(params.only))(_surround);
31
+ state.surround = _surround;
32
+ }
33
+ return state;
34
+ }
35
+ ];
36
+ const transformingPiples = [
37
+ // Skip first items
38
+ (state, params) => {
39
+ if (params.skip) {
40
+ return {
41
+ ...state,
42
+ result: state.result.slice(params.skip),
43
+ skip: params.skip
44
+ };
45
+ }
46
+ },
47
+ // Pick first items
48
+ (state, params) => {
49
+ if (params.limit) {
50
+ return {
51
+ ...state,
52
+ result: state.result.slice(0, params.limit),
53
+ limit: params.limit
54
+ };
55
+ }
56
+ },
57
+ function fetchDirConfig(state, params, db) {
58
+ if (params.dirConfig) {
59
+ const path = state.result[0]?._path || params.where?.find((w) => w._path)?._path;
60
+ if (typeof path === "string") {
61
+ const dirConfig = db.find((item) => item._path === joinURL(path, "_dir"));
62
+ if (dirConfig) {
63
+ state.dirConfig = { _path: dirConfig._path, ...withoutKeys(["_"])(dirConfig) };
64
+ }
65
+ }
66
+ }
67
+ return state;
68
+ },
69
+ // Remove unwanted fields
70
+ (state, params) => ({
71
+ ...state,
72
+ result: apply(withoutKeys(params.without))(state.result)
73
+ }),
74
+ // Select only wanted fields
75
+ (state, params) => ({
76
+ ...state,
77
+ result: apply(withKeys(params.only))(state.result)
78
+ })
79
+ ];
80
+ return async (query) => {
81
+ const db = await getContentsList();
82
+ const params = query.params();
83
+ const result1 = {
84
+ result: db,
85
+ limit: 0,
86
+ skip: 0,
87
+ total: db.length
88
+ };
89
+ const matchedData = matchingPipelines.reduce(($data, pipe) => pipe($data, params, db) || $data, result1);
90
+ if (params.count) {
91
+ return {
92
+ result: matchedData.result.length
93
+ };
94
+ }
95
+ const result = transformingPiples.reduce(($data, pipe) => pipe($data, params, db) || $data, matchedData);
96
+ if (params.first) {
97
+ return {
98
+ ...omit(["skip", "limit", "total"])(result),
99
+ result: result.result[0]
100
+ };
101
+ }
102
+ return result;
103
+ };
104
+ }
@@ -0,0 +1,35 @@
1
+ import type { SortOptions } from '@nuxt/content';
2
+ /**
3
+ * Retrive nested value from object by path
4
+ */
5
+ export declare const get: (obj: any, path: string) => any;
6
+ /**
7
+ * Returns a new object with the specified keys
8
+ **/
9
+ export declare const pick: (keys?: string[]) => (obj: any) => any;
10
+ /**
11
+ * Returns a new object with all the keys of the original object execept the ones specified.
12
+ **/
13
+ export declare const omit: (keys?: string[]) => (obj: any) => any;
14
+ /**
15
+ * Apply a function to each element of an array
16
+ */
17
+ export declare const apply: (fn: (d: any) => any) => (data: any) => any;
18
+ export declare const detectProperties: (keys: string[]) => {
19
+ prefixes: string[];
20
+ properties: string[];
21
+ };
22
+ export declare const withoutKeys: (keys?: string[]) => (obj: any) => any;
23
+ export declare const withKeys: (keys?: string[]) => (obj: any) => any;
24
+ /**
25
+ * Sort list of items by givin options
26
+ */
27
+ export declare const sortList: (data: any[], params: SortOptions) => any[];
28
+ /**
29
+ * Raise TypeError if value is not an array
30
+ */
31
+ export declare const assertArray: (value: any, message?: string) => void;
32
+ /**
33
+ * Ensure result is an array
34
+ */
35
+ export declare const ensureArray: <T>(value: T) => T extends Array<any> ? T : T[];
@@ -0,0 +1,65 @@
1
+ export const get = (obj, path) => path.split(".").reduce((acc, part) => acc && acc[part], obj);
2
+ const _pick = (obj, condition) => Object.keys(obj).filter(condition).reduce((newObj, key) => Object.assign(newObj, { [key]: obj[key] }), {});
3
+ export const pick = (keys) => (obj) => keys && keys.length ? _pick(obj, (key) => keys.includes(key)) : obj;
4
+ export const omit = (keys) => (obj) => keys && keys.length ? _pick(obj, (key) => !keys.includes(key)) : obj;
5
+ export const apply = (fn) => (data) => Array.isArray(data) ? data.map((item) => fn(item)) : fn(data);
6
+ export const detectProperties = (keys) => {
7
+ const prefixes = [];
8
+ const properties = [];
9
+ for (const key of keys) {
10
+ if (["$", "_"].includes(key)) {
11
+ prefixes.push(key);
12
+ } else {
13
+ properties.push(key);
14
+ }
15
+ }
16
+ return { prefixes, properties };
17
+ };
18
+ export const withoutKeys = (keys = []) => (obj) => {
19
+ if (keys.length === 0 || !obj) {
20
+ return obj;
21
+ }
22
+ const { prefixes, properties } = detectProperties(keys);
23
+ return _pick(obj, (key) => !properties.includes(key) && !prefixes.includes(key[0]));
24
+ };
25
+ export const withKeys = (keys = []) => (obj) => {
26
+ if (keys.length === 0 || !obj) {
27
+ return obj;
28
+ }
29
+ const { prefixes, properties } = detectProperties(keys);
30
+ return _pick(obj, (key) => properties.includes(key) || prefixes.includes(key[0]));
31
+ };
32
+ export const sortList = (data, params) => {
33
+ const comperable = new Intl.Collator(params.$locale, {
34
+ numeric: params.$numeric,
35
+ caseFirst: params.$caseFirst,
36
+ sensitivity: params.$sensitivity
37
+ });
38
+ const keys = Object.keys(params).filter((key) => !key.startsWith("$"));
39
+ for (const key of keys) {
40
+ data = data.sort((a, b) => {
41
+ const values = [get(a, key), get(b, key)].map((value) => {
42
+ if (value === null) {
43
+ return void 0;
44
+ }
45
+ if (value instanceof Date) {
46
+ return value.toISOString();
47
+ }
48
+ return value;
49
+ });
50
+ if (params[key] === -1) {
51
+ values.reverse();
52
+ }
53
+ return comperable.compare(values[0], values[1]);
54
+ });
55
+ }
56
+ return data;
57
+ };
58
+ export const assertArray = (value, message = "Expected an array") => {
59
+ if (!Array.isArray(value)) {
60
+ throw new TypeError(message);
61
+ }
62
+ };
63
+ export const ensureArray = (value) => {
64
+ return Array.isArray(value) ? value : [void 0, null].includes(value) ? [] : [value];
65
+ };
@@ -0,0 +1,12 @@
1
+ import type { QueryBuilder, ParsedContent, ContentQueryBuilder, ContentQueryBuilderParams, ContentQueryFetcher } from '@nuxt/content';
2
+ interface QueryOptions {
3
+ initialParams?: ContentQueryBuilderParams;
4
+ legacy?: boolean;
5
+ }
6
+ export declare function createQuery<T = ParsedContent>(fetcher: ContentQueryFetcher<T>, opts: QueryOptions & {
7
+ legacy: true;
8
+ }): QueryBuilder<T>;
9
+ export declare function createQuery<T = ParsedContent>(fetcher: ContentQueryFetcher<T>, opts: QueryOptions & {
10
+ legacy: false;
11
+ }): ContentQueryBuilder<T>;
12
+ export {};
@@ -0,0 +1,61 @@
1
+ import { ensureArray } from "./match/utils.js";
2
+ const arrayParams = ["sort", "where", "only", "without"];
3
+ export function createQuery(fetcher, opts = {}) {
4
+ const queryParams = {};
5
+ for (const key of Object.keys(opts.initialParams || {})) {
6
+ queryParams[key] = arrayParams.includes(key) ? ensureArray(opts.initialParams[key]) : opts.initialParams[key];
7
+ }
8
+ const $set = (key, fn = (v) => v) => {
9
+ return (...values) => {
10
+ queryParams[key] = fn(...values);
11
+ return query;
12
+ };
13
+ };
14
+ const resolveResult = (result) => {
15
+ if (opts.legacy) {
16
+ if (result?.surround) {
17
+ return result.surround;
18
+ }
19
+ if (!result) {
20
+ return result;
21
+ }
22
+ if (result?.dirConfig) {
23
+ result.result = {
24
+ _path: result.dirConfig?._path,
25
+ ...result.result,
26
+ _dir: result.dirConfig
27
+ };
28
+ }
29
+ return result?._path || Array.isArray(result) || !Object.prototype.hasOwnProperty.call(result, "result") ? result : result?.result;
30
+ }
31
+ return result;
32
+ };
33
+ const query = {
34
+ params: () => ({
35
+ ...queryParams,
36
+ ...queryParams.where ? { where: [...ensureArray(queryParams.where)] } : {},
37
+ ...queryParams.sort ? { sort: [...ensureArray(queryParams.sort)] } : {}
38
+ }),
39
+ only: $set("only", ensureArray),
40
+ without: $set("without", ensureArray),
41
+ where: $set("where", (q) => [...ensureArray(queryParams.where), ...ensureArray(q)]),
42
+ sort: $set("sort", (sort) => [...ensureArray(queryParams.sort), ...ensureArray(sort)]),
43
+ limit: $set("limit", (v) => parseInt(String(v), 10)),
44
+ skip: $set("skip", (v) => parseInt(String(v), 10)),
45
+ // find
46
+ find: () => fetcher(query).then(resolveResult),
47
+ findOne: () => fetcher($set("first")(true)).then(resolveResult),
48
+ count: () => fetcher($set("count")(true)).then(resolveResult),
49
+ // locale
50
+ locale: (_locale) => query.where({ _locale }),
51
+ withSurround: $set("surround", (surroundQuery, options) => ({ query: surroundQuery, ...options })),
52
+ withDirConfig: () => $set("dirConfig")(true)
53
+ };
54
+ if (opts.legacy) {
55
+ query.findSurround = (surroundQuery, options) => {
56
+ return query.withSurround(surroundQuery, options).find().then(resolveResult);
57
+ };
58
+ return query;
59
+ }
60
+ return query;
61
+ }
@@ -0,0 +1,7 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ generatedAt: number;
3
+ generateTime: number;
4
+ contents: any;
5
+ navigation: NavItem[];
6
+ }>>;
7
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const { getContentIndex } = await import("../content-index.js");
5
+ const { cacheStorage, serverQueryContent } = await import("../storage.js");
6
+ const { content } = useRuntimeConfig();
7
+ const now = Date.now();
8
+ const contents = await serverQueryContent(event).find();
9
+ await getContentIndex(event);
10
+ const navigation = await $fetch(`${content.api.baseURL}/navigation`);
11
+ await cacheStorage().setItem("content-navigation.json", navigation);
12
+ return {
13
+ generatedAt: now,
14
+ generateTime: Date.now() - now,
15
+ contents: content.experimental.cacheContents ? contents : [],
16
+ navigation
17
+ };
18
+ });
@@ -0,0 +1 @@
1
+ export { default as default } from './navigation';
@@ -0,0 +1 @@
1
+ export { default } from "./navigation.js";
@@ -0,0 +1 @@
1
+ export { default as default } from './navigation';
@@ -0,0 +1 @@
1
+ export { default } from "./navigation.js";
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<string | number | true | object>>;
2
+ export default _default;
@@ -0,0 +1,42 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { isPreview } from "../preview.js";
3
+ export default defineEventHandler(async (event) => {
4
+ const { getContentQuery } = await import("../../utils/query.js");
5
+ const { cacheStorage, serverQueryContent } = await import("../storage.js");
6
+ const { createNav } = await import("../navigation.js");
7
+ const query = getContentQuery(event);
8
+ if (!isPreview(event) && Object.keys(query).length === 0) {
9
+ const cache = await cacheStorage().getItem("content-navigation.json");
10
+ if (cache) {
11
+ return cache;
12
+ }
13
+ }
14
+ const contents = await serverQueryContent(event, query).where({
15
+ /**
16
+ * Partial contents are not included in the navigation
17
+ * A partial content is a content that has `_` prefix in its path
18
+ */
19
+ _partial: false,
20
+ /**
21
+ * Exclude any pages which have opted out of navigation via frontmatter.
22
+ */
23
+ navigation: {
24
+ $ne: false
25
+ }
26
+ }).find();
27
+ const _locale = (query?.where || []).find((w) => w._locale)?._locale;
28
+ const dirConfigs = await serverQueryContent(event, _locale ? { where: [{ _locale }] } : void 0).where({ _path: /\/_dir$/i, _partial: true }).find();
29
+ const configs = (dirConfigs?.result || dirConfigs).reduce((configs2, conf) => {
30
+ if (conf.title?.toLowerCase() === "dir") {
31
+ conf.title = void 0;
32
+ }
33
+ const key = conf._path.split("/").slice(0, -1).join("/") || "/";
34
+ configs2[key] = {
35
+ ...conf,
36
+ // Extract meta from body. (non MD files)
37
+ ...conf.body
38
+ };
39
+ return configs2;
40
+ }, {});
41
+ return createNav(contents?.result || contents, configs);
42
+ });
@@ -0,0 +1 @@
1
+ export { default as default } from './query';
@@ -0,0 +1 @@
1
+ export { default } from "./query.js";
@@ -0,0 +1 @@
1
+ export { default as default } from './query';
@@ -0,0 +1 @@
1
+ export { default } from "./query.js";
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
2
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import { createError, defineEventHandler } from "h3";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const { getContentQuery } = await import("../../utils/query.js");
5
+ const { serverQueryContent } = await import("../storage.js");
6
+ const query = getContentQuery(event);
7
+ const { advanceQuery } = useRuntimeConfig().public.content.experimental;
8
+ if (query.first) {
9
+ let contentQuery = serverQueryContent(event, query);
10
+ if (!advanceQuery) {
11
+ contentQuery = contentQuery.withDirConfig();
12
+ }
13
+ const content = await contentQuery.findOne();
14
+ const _result = advanceQuery ? content?.result : content;
15
+ const missing = !_result && !content?.dirConfig?.navigation?.redirect && !content?._dir?.navigation?.redirect;
16
+ if (missing) {
17
+ throw createError({
18
+ statusMessage: "Document not found!",
19
+ statusCode: 404,
20
+ data: {
21
+ description: "Could not find document for the given query.",
22
+ query
23
+ }
24
+ });
25
+ }
26
+ return content;
27
+ }
28
+ if (query.count) {
29
+ return serverQueryContent(event, query).count();
30
+ }
31
+ return serverQueryContent(event, query).find();
32
+ });
@@ -0,0 +1,8 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<string | {
2
+ id: string;
3
+ title: string;
4
+ titles: string[];
5
+ level: number;
6
+ content: string;
7
+ }[]>>;
8
+ export default _default;
@@ -0,0 +1,16 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const { serverSearchContent, splitPageIntoSections } = await import("../search.js");
5
+ const MiniSearch = await import("minisearch").then((m) => m.default);
6
+ const runtimeConfig = useRuntimeConfig();
7
+ const { ignoredTags = [], filterQuery, indexed, options } = runtimeConfig.public.content.search;
8
+ const files = await serverSearchContent(event, filterQuery);
9
+ const sections = files.map((page) => splitPageIntoSections(page, { ignoredTags })).flat();
10
+ if (indexed) {
11
+ const miniSearch = new MiniSearch(options);
12
+ miniSearch.addAll(sections);
13
+ return JSON.stringify(miniSearch);
14
+ }
15
+ return sections;
16
+ });
@@ -0,0 +1,4 @@
1
+ import type { H3Event } from 'h3';
2
+ import type { ParsedContent, ContentQueryBuilder } from '@nuxt/content';
3
+ export declare function getContentIndex(event: H3Event): Promise<Record<string, string[]>>;
4
+ export declare function getIndexedContentsList<T = ParsedContent>(event: H3Event, query: ContentQueryBuilder<T>): Promise<T[]>;
@@ -0,0 +1,37 @@
1
+ import { isPreview } from "./preview.js";
2
+ import { cacheStorage, chunksFromArray, getContent, getContentsList } from "./storage.js";
3
+ import { useRuntimeConfig } from "#imports";
4
+ export async function getContentIndex(event) {
5
+ const defaultLocale = useRuntimeConfig().content.defaultLocale;
6
+ let contentIndex = await cacheStorage().getItem("content-index.json");
7
+ if (!contentIndex) {
8
+ const data = await getContentsList(event);
9
+ contentIndex = data.reduce((acc, item) => {
10
+ acc[item._path] = acc[item._path] || [];
11
+ if (item._locale === defaultLocale) {
12
+ acc[item._path].unshift(item._id);
13
+ } else {
14
+ acc[item._path].push(item._id);
15
+ }
16
+ return acc;
17
+ }, {});
18
+ await cacheStorage().setItem("content-index.json", contentIndex);
19
+ }
20
+ return contentIndex;
21
+ }
22
+ export async function getIndexedContentsList(event, query) {
23
+ const params = query.params();
24
+ const path = params?.where?.find((wh) => wh._path)?._path;
25
+ if (!isPreview(event) && !params.surround && !params.dirConfig && (typeof path === "string" || path instanceof RegExp)) {
26
+ const index = await getContentIndex(event);
27
+ const keys = Object.keys(index).filter((key) => path.test ? path.test(key) : key === String(path)).flatMap((key) => index[key]);
28
+ const keyChunks = [...chunksFromArray(keys, 10)];
29
+ const contents = [];
30
+ for await (const chunk of keyChunks) {
31
+ const result = await Promise.all(chunk.map((key) => getContent(event, key)));
32
+ contents.push(...result);
33
+ }
34
+ return contents;
35
+ }
36
+ return getContentsList(event);
37
+ }
@@ -0,0 +1 @@
1
+ export { serverQueryContent, parseContent } from './storage';
@@ -0,0 +1 @@
1
+ export { serverQueryContent, parseContent } from "./storage.js";
@@ -0,0 +1,5 @@
1
+ import type { ParsedContentMeta } from '@nuxt/content';
2
+ /**
3
+ * Create NavItem array to be consumed from runtime plugin.
4
+ */
5
+ export declare function createNav(contents: ParsedContentMeta[], configs: Record<string, ParsedContentMeta>): any[];
@@ -0,0 +1,96 @@
1
+ import { generateTitle } from "../transformers/path-meta.js";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export function createNav(contents, configs) {
4
+ const { navigation } = useRuntimeConfig().public.content;
5
+ if (navigation === false) {
6
+ return [];
7
+ }
8
+ const pickNavigationFields = (content) => ({
9
+ ...pick(["title", ...navigation.fields])(content),
10
+ ...isObject(content?.navigation) ? content.navigation : {}
11
+ });
12
+ const nav = contents.sort((a, b) => a._path.localeCompare(b._path)).reduce((nav2, content) => {
13
+ const parts = content._path.substring(1).split("/");
14
+ const idParts = content._id.split(":").slice(1);
15
+ const isIndex = !!idParts[idParts.length - 1]?.match(/([1-9][0-9]*\.)?index.md/g);
16
+ const getNavItem = (content2) => ({
17
+ title: content2.title,
18
+ _path: content2._path,
19
+ _file: content2._file,
20
+ children: [],
21
+ ...pickNavigationFields(content2),
22
+ ...content2._draft ? { _draft: true } : {}
23
+ });
24
+ const navItem = getNavItem(content);
25
+ if (isIndex) {
26
+ const dirConfig = configs[navItem._path];
27
+ if (typeof dirConfig?.navigation !== "undefined" && !dirConfig?.navigation) {
28
+ return nav2;
29
+ }
30
+ if (content._path !== "/") {
31
+ const indexItem = getNavItem(content);
32
+ navItem.children.push(indexItem);
33
+ }
34
+ if (dirConfig) {
35
+ Object.assign(
36
+ navItem,
37
+ pickNavigationFields(dirConfig)
38
+ );
39
+ }
40
+ }
41
+ if (parts.length === 1) {
42
+ nav2.push(navItem);
43
+ return nav2;
44
+ }
45
+ const siblings = parts.slice(0, -1).reduce((nodes, part, i) => {
46
+ const currentPathPart = "/" + parts.slice(0, i + 1).join("/");
47
+ const conf = configs[currentPathPart];
48
+ if (typeof conf?.navigation !== "undefined" && !conf.navigation) {
49
+ return [];
50
+ }
51
+ let parent = nodes.find((n) => n._path === currentPathPart);
52
+ if (!parent) {
53
+ parent = {
54
+ title: generateTitle(part),
55
+ _path: currentPathPart,
56
+ _file: content._file,
57
+ children: [],
58
+ ...conf && pickNavigationFields(conf)
59
+ };
60
+ nodes.push(parent);
61
+ }
62
+ return parent.children;
63
+ }, nav2);
64
+ siblings.push(navItem);
65
+ return nav2;
66
+ }, []);
67
+ return sortAndClear(nav);
68
+ }
69
+ const collator = new Intl.Collator(void 0, { numeric: true, sensitivity: "base" });
70
+ function sortAndClear(nav) {
71
+ nav.forEach((item) => {
72
+ item._file = item._file.split(".").slice(0, -1).join(".");
73
+ });
74
+ const sorted = nav.sort((a, b) => collator.compare(a._file, b._file));
75
+ for (const item of sorted) {
76
+ if (item.children?.length) {
77
+ sortAndClear(item.children);
78
+ } else {
79
+ delete item.children;
80
+ }
81
+ delete item._file;
82
+ }
83
+ return nav;
84
+ }
85
+ function pick(keys) {
86
+ return (obj) => {
87
+ obj = obj || {};
88
+ if (keys && keys.length) {
89
+ return keys.filter((key) => typeof obj[key] !== "undefined").reduce((newObj, key) => Object.assign(newObj, { [key]: obj[key] }), {});
90
+ }
91
+ return obj;
92
+ };
93
+ }
94
+ function isObject(obj) {
95
+ return Object.prototype.toString.call(obj) === "[object Object]";
96
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { useStorage, defineNitroPlugin } from "#imports";
2
+ export default defineNitroPlugin(async (nitro) => {
3
+ const { cleanCachedContents } = await import("../storage.js");
4
+ const storage = useStorage();
5
+ const unwatch = await storage.watch(async (event, key) => {
6
+ if (key.startsWith("content:source")) {
7
+ cleanCachedContents();
8
+ }
9
+ });
10
+ nitro.hooks.hook("close", async () => {
11
+ if (typeof unwatch === "function") {
12
+ await unwatch();
13
+ }
14
+ });
15
+ });
@@ -0,0 +1,5 @@
1
+ import type { H3Event } from 'h3';
2
+ export declare const isPreview: (event: H3Event) => boolean;
3
+ export declare const getPreview: (event: H3Event) => {
4
+ key: string | undefined;
5
+ };
@@ -0,0 +1,9 @@
1
+ import { getQuery, getCookie } from "h3";
2
+ export const isPreview = (event) => {
3
+ const previewToken = getQuery(event).previewToken || getCookie(event, "previewToken");
4
+ return !!previewToken;
5
+ };
6
+ export const getPreview = (event) => {
7
+ const key = getQuery(event).previewToken || getCookie(event, "previewToken");
8
+ return { key };
9
+ };
@@ -0,0 +1,14 @@
1
+ import type { H3Event } from 'h3';
2
+ import type { ParsedContent, QueryBuilderWhere } from '@nuxt/content';
3
+ export declare function serverSearchContent(event: H3Event, filterQuery?: QueryBuilderWhere): Promise<ParsedContent[]>;
4
+ type Section = {
5
+ id: string;
6
+ title: string;
7
+ titles: string[];
8
+ level: number;
9
+ content: string;
10
+ };
11
+ export declare function splitPageIntoSections(page: ParsedContent, { ignoredTags }: {
12
+ ignoredTags: string[];
13
+ }): Section[];
14
+ export {};