@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,696 @@
1
+ import fs from 'fs';
2
+ import { defineNuxtModule, createResolver, addImports, addComponentsDir, addTemplate, addServerPlugin, addPlugin, installModule, extendViteConfig, addVitePlugin } from '@nuxt/kit';
3
+ import { defu } from 'defu';
4
+ import { genSafeVariableName, genImport, genDynamicImport } from 'knitwork';
5
+ import { listen } from 'listhen';
6
+ import { hash } from 'ohash';
7
+ import { resolve, join, relative } from 'pathe';
8
+ import { withLeadingSlash, joinURL, withTrailingSlash } from 'ufo';
9
+ import { createStorage } from 'unstorage';
10
+ import { makeIgnored } from '../dist/runtime/utils/config.js';
11
+ import fsDriver from 'unstorage/drivers/fs';
12
+ import httpDriver from 'unstorage/drivers/http';
13
+ import githubDriver from 'unstorage/drivers/github';
14
+ import { WebSocketServer } from 'ws';
15
+ import { consola } from 'consola';
16
+
17
+ const name = "@ztl-uwu/nuxt-content";
18
+ const version = "2.13.5";
19
+
20
+ const logger = consola.withTag("@nuxt/content");
21
+ const CACHE_VERSION = 2;
22
+ const MOUNT_PREFIX = "content:source:";
23
+ const PROSE_TAGS = [
24
+ "p",
25
+ "a",
26
+ "blockquote",
27
+ "code-inline",
28
+ "code",
29
+ "em",
30
+ "h1",
31
+ "h2",
32
+ "h3",
33
+ "h4",
34
+ "h5",
35
+ "h6",
36
+ "hr",
37
+ "img",
38
+ "ul",
39
+ "ol",
40
+ "li",
41
+ "strong",
42
+ "table",
43
+ "thead",
44
+ "tbody",
45
+ "td",
46
+ "th",
47
+ "tr"
48
+ ];
49
+ const unstorageDrivers = {
50
+ fs: fsDriver,
51
+ http: httpDriver,
52
+ github: githubDriver
53
+ };
54
+ async function getMountDriver(mount) {
55
+ const dirverName = mount.driver;
56
+ if (unstorageDrivers[dirverName]) {
57
+ return unstorageDrivers[dirverName](mount);
58
+ }
59
+ try {
60
+ return (await import(mount.driver)).default(mount);
61
+ } catch {
62
+ console.error("Couldn't load driver", mount.driver);
63
+ }
64
+ }
65
+ function useContentMounts(nuxt, storages) {
66
+ const key = (path, prefix = "") => `${MOUNT_PREFIX}${path.replace(/[/:]/g, "_")}${prefix.replace(/\//g, ":")}`;
67
+ const baseDir = nuxt.options.future?.compatibilityVersion === 4 ? nuxt.options.rootDir : nuxt.options.srcDir;
68
+ const storageKeys = Object.keys(storages);
69
+ if (Array.isArray(storages) || // Detect object representation of array `{ '0': 'source1' }`. Nuxt converts this array to object when using `nuxt.config.ts`
70
+ storageKeys.length > 0 && storageKeys.every((i) => i === String(+i))) {
71
+ storages = Object.values(storages);
72
+ logger.warn("Using array syntax to define sources is deprecated. Consider using object syntax.");
73
+ storages = storages.reduce((mounts, storage) => {
74
+ if (typeof storage === "string") {
75
+ mounts[key(storage)] = {
76
+ name: storage,
77
+ driver: "fs",
78
+ prefix: "",
79
+ base: resolve(baseDir, storage)
80
+ };
81
+ }
82
+ if (typeof storage === "object") {
83
+ mounts[key(storage.name, storage.prefix)] = storage;
84
+ }
85
+ return mounts;
86
+ }, {});
87
+ } else {
88
+ storages = Object.entries(storages).reduce((mounts, [name, storage]) => {
89
+ mounts[key(storage.name || name, storage.prefix)] = storage;
90
+ return mounts;
91
+ }, {});
92
+ }
93
+ const defaultStorage = key("content");
94
+ if (!storages[defaultStorage]) {
95
+ storages[defaultStorage] = {
96
+ name: defaultStorage,
97
+ driver: "fs",
98
+ base: resolve(baseDir, "content")
99
+ };
100
+ }
101
+ return storages;
102
+ }
103
+ function createWebSocket() {
104
+ const wss = new WebSocketServer({ noServer: true });
105
+ const serve = (req, socket = req.socket, head = "") => wss.handleUpgrade(req, socket, head, (client) => wss.emit("connection", client, req));
106
+ const broadcast = (data) => {
107
+ data = JSON.stringify(data);
108
+ for (const client of wss.clients) {
109
+ try {
110
+ client.send(data);
111
+ } catch {
112
+ }
113
+ }
114
+ };
115
+ return {
116
+ serve,
117
+ broadcast,
118
+ close: () => {
119
+ wss.clients.forEach((client) => client.close());
120
+ return new Promise((resolve2) => wss.close(resolve2));
121
+ }
122
+ };
123
+ }
124
+ function processMarkdownOptions(options) {
125
+ const anchorLinks = typeof options.anchorLinks === "boolean" ? { depth: options.anchorLinks ? 6 : 0, exclude: [] } : { depth: 4, exclude: [1], ...options.anchorLinks };
126
+ return {
127
+ ...options,
128
+ anchorLinks,
129
+ remarkPlugins: resolveMarkdownPlugins(options.remarkPlugins),
130
+ rehypePlugins: resolveMarkdownPlugins(options.rehypePlugins)
131
+ };
132
+ }
133
+ function resolveMarkdownPlugins(plugins) {
134
+ if (Array.isArray(plugins)) {
135
+ return Object.values(plugins).reduce((plugins2, plugin) => {
136
+ const [name, pluginOptions] = Array.isArray(plugin) ? plugin : [plugin, {}];
137
+ plugins2[name] = pluginOptions;
138
+ return plugins2;
139
+ }, {});
140
+ }
141
+ return plugins || {};
142
+ }
143
+
144
+ const module = defineNuxtModule({
145
+ meta: {
146
+ name,
147
+ version,
148
+ configKey: "content",
149
+ compatibility: {
150
+ nuxt: ">=3.0.0-rc.3"
151
+ }
152
+ },
153
+ defaults: {
154
+ // @deprecated
155
+ base: "",
156
+ api: {
157
+ baseURL: "/api/_content"
158
+ },
159
+ watch: {
160
+ ws: {
161
+ port: {
162
+ port: 4e3,
163
+ portRange: [4e3, 4040]
164
+ },
165
+ hostname: "localhost",
166
+ showURL: false
167
+ }
168
+ },
169
+ sources: {},
170
+ ignores: [],
171
+ locales: [],
172
+ defaultLocale: void 0,
173
+ highlight: false,
174
+ markdown: {
175
+ tags: {
176
+ ...Object.fromEntries(PROSE_TAGS.map((t) => [t, `prose-${t}`])),
177
+ code: "ProseCodeInline"
178
+ },
179
+ anchorLinks: {
180
+ depth: 4,
181
+ exclude: [1]
182
+ }
183
+ },
184
+ yaml: {},
185
+ csv: {
186
+ delimeter: ",",
187
+ json: true
188
+ },
189
+ navigation: {
190
+ fields: []
191
+ },
192
+ contentHead: true,
193
+ documentDriven: false,
194
+ respectPathCase: false,
195
+ experimental: {
196
+ clientDB: false,
197
+ cacheContents: true,
198
+ stripQueryParameters: false,
199
+ advanceQuery: false,
200
+ search: void 0
201
+ }
202
+ },
203
+ async setup(options, nuxt) {
204
+ const { resolve, resolvePath } = createResolver(import.meta.url);
205
+ const resolveRuntimeModule = (path) => resolve("./runtime", path);
206
+ options.locales = Array.from(new Set([options.defaultLocale, ...options.locales].filter(Boolean)));
207
+ const buildIntegrity = nuxt.options.dev ? void 0 : Date.now();
208
+ if (options.base) {
209
+ logger.warn("content.base is deprecated. Use content.api.baseURL instead.");
210
+ options.api.baseURL = withLeadingSlash(joinURL("api", options.base));
211
+ }
212
+ const contentContext = {
213
+ transformers: [],
214
+ ...options
215
+ };
216
+ nuxt.hook("nitro:config", (nitroConfig) => {
217
+ nitroConfig.prerender = nitroConfig.prerender || {};
218
+ nitroConfig.prerender.routes = nitroConfig.prerender.routes || [];
219
+ nitroConfig.handlers = nitroConfig.handlers || [];
220
+ nitroConfig.handlers.push(
221
+ {
222
+ method: "get",
223
+ route: `${options.api.baseURL}/query/:qid/**:params`,
224
+ handler: resolveRuntimeModule("./server/api/query-qid-params")
225
+ },
226
+ {
227
+ method: "get",
228
+ route: `${options.api.baseURL}/query/:qid`,
229
+ handler: resolveRuntimeModule("./server/api/query-qid")
230
+ },
231
+ {
232
+ method: "get",
233
+ route: `${options.api.baseURL}/query`,
234
+ handler: resolveRuntimeModule("./server/api/query")
235
+ },
236
+ {
237
+ method: "get",
238
+ route: nuxt.options.dev ? `${options.api.baseURL}/cache.json` : `${options.api.baseURL}/cache.${buildIntegrity}.json`,
239
+ handler: resolveRuntimeModule("./server/api/cache")
240
+ }
241
+ );
242
+ if (options.experimental?.search) {
243
+ const route = nuxt.options.dev ? `${options.api.baseURL}/search` : `${options.api.baseURL}/search-${buildIntegrity}`;
244
+ nitroConfig.handlers.push({
245
+ method: "get",
246
+ route,
247
+ handler: resolveRuntimeModule("./server/api/search")
248
+ });
249
+ nitroConfig.routeRules = nitroConfig.routeRules || {};
250
+ nitroConfig.routeRules[route] = {
251
+ prerender: true,
252
+ // Use text/plain to avoid Nitro render an index.html
253
+ headers: options.experimental.search.indexed ? { "Content-Type": "text/plain; charset=utf-8" } : { "Content-Type": "application/json" }
254
+ };
255
+ }
256
+ if (!nuxt.options.dev) {
257
+ nitroConfig.prerender.routes.unshift(`${options.api.baseURL}/cache.${buildIntegrity}.json`);
258
+ }
259
+ const sources = useContentMounts(nuxt, contentContext.sources);
260
+ nitroConfig.devStorage = Object.assign(nitroConfig.devStorage || {}, sources);
261
+ nitroConfig.devStorage["cache:content"] = {
262
+ driver: "fs",
263
+ base: resolve(nuxt.options.buildDir, "content-cache")
264
+ };
265
+ for (const source of Object.values(sources)) {
266
+ if (source.driver === "fs" && source.base.includes(nuxt.options.srcDir)) {
267
+ const wildcard = join(source.base, "**/*").replace(withTrailingSlash(nuxt.options.srcDir), "");
268
+ nuxt.options.ignore.push(
269
+ // Remove `srcDir` from the path
270
+ wildcard,
271
+ `!${wildcard}.vue`
272
+ );
273
+ }
274
+ }
275
+ nitroConfig.bundledStorage = nitroConfig.bundledStorage || [];
276
+ nitroConfig.bundledStorage.push("/cache/content");
277
+ nitroConfig.externals = defu(typeof nitroConfig.externals === "object" ? nitroConfig.externals : {}, {
278
+ inline: [
279
+ // Inline module runtime in Nitro bundle
280
+ resolve("./runtime")
281
+ ]
282
+ });
283
+ nitroConfig.alias = nitroConfig.alias || {};
284
+ nitroConfig.alias["#content/server"] = resolveRuntimeModule(options.experimental.advanceQuery ? "./server" : "./legacy/server");
285
+ const transformers = contentContext.transformers.map((t) => {
286
+ const name2 = genSafeVariableName(relative(nuxt.options.rootDir, t)).replace(/_(45|46|47)/g, "_") + "_" + hash(t);
287
+ return { name: name2, import: genImport(t, name2) };
288
+ });
289
+ nitroConfig.virtual = nitroConfig.virtual || {};
290
+ nitroConfig.virtual["#content/virtual/transformers"] = [
291
+ ...transformers.map((t) => t.import),
292
+ `export const transformers = [${transformers.map((t) => t.name).join(", ")}]`,
293
+ 'export const getParser = (ext) => transformers.find(p => ext.match(new RegExp(p.extensions.join("|"), "i")) && p.parse)',
294
+ 'export const getTransformers = (ext) => transformers.filter(p => ext.match(new RegExp(p.extensions.join("|"), "i")) && p.transform)',
295
+ "export default () => {}"
296
+ ].join("\n");
297
+ });
298
+ addImports([
299
+ { name: "queryContent", as: "queryContent", from: resolveRuntimeModule(`./${options.experimental.advanceQuery ? "" : "legacy/"}composables/query`) },
300
+ { name: "useContentHelpers", as: "useContentHelpers", from: resolveRuntimeModule("./composables/helpers") },
301
+ { name: "useContentHead", as: "useContentHead", from: resolveRuntimeModule("./composables/head") },
302
+ { name: "useContentPreview", as: "useContentPreview", from: resolveRuntimeModule("./composables/preview") },
303
+ { name: "withContentBase", as: "withContentBase", from: resolveRuntimeModule("./composables/utils") },
304
+ { name: "useUnwrap", as: "useUnwrap", from: resolveRuntimeModule("./composables/useUnwrap") }
305
+ ]);
306
+ if (options.experimental?.search) {
307
+ const defaultSearchOptions = {
308
+ indexed: true,
309
+ ignoredTags: ["script", "style", "pre"],
310
+ filterQuery: { _draft: false, _partial: false },
311
+ options: {
312
+ fields: ["title", "content", "titles"],
313
+ storeFields: ["title", "content", "titles"],
314
+ searchOptions: {
315
+ prefix: true,
316
+ fuzzy: 0.2,
317
+ boost: {
318
+ title: 4,
319
+ content: 2,
320
+ titles: 1
321
+ }
322
+ }
323
+ }
324
+ };
325
+ options.experimental.search = {
326
+ ...defaultSearchOptions,
327
+ ...options.experimental.search
328
+ };
329
+ nuxt.options.modules.push("@vueuse/nuxt");
330
+ addImports([
331
+ {
332
+ name: "defineMiniSearchOptions",
333
+ as: "defineMiniSearchOptions",
334
+ from: resolveRuntimeModule("./composables/search")
335
+ },
336
+ {
337
+ name: "searchContent",
338
+ as: "searchContent",
339
+ from: resolveRuntimeModule("./composables/search")
340
+ }
341
+ ]);
342
+ }
343
+ addComponentsDir({
344
+ path: resolve("./runtime/components"),
345
+ pathPrefix: false,
346
+ prefix: "",
347
+ global: true
348
+ });
349
+ const componentsContext = { components: [] };
350
+ nuxt.hook("components:extend", (newComponents) => {
351
+ componentsContext.components = newComponents.filter((c) => {
352
+ if (c.pascalName.startsWith("Prose") || c.pascalName === "NuxtLink") {
353
+ return true;
354
+ }
355
+ if (c.filePath.includes("@nuxt/content/dist") || c.filePath.includes("@nuxtjs/mdc/dist") || c.filePath.includes("nuxt/dist/app") || c.filePath.includes("NuxtWelcome")) {
356
+ return false;
357
+ }
358
+ return true;
359
+ });
360
+ });
361
+ addTemplate({
362
+ filename: "content-components.mjs",
363
+ getContents({ options: options2 }) {
364
+ const components = options2.getComponents().filter((c) => !c.island).flatMap((c) => {
365
+ const exp = c.export === "default" ? "c.default || c" : `c['${c.export}']`;
366
+ const isClient = c.mode === "client";
367
+ const definitions = [];
368
+ definitions.push(`export const ${c.pascalName} = ${genDynamicImport(c.filePath)}.then(c => ${isClient ? `createClientOnly(${exp})` : exp})`);
369
+ return definitions;
370
+ });
371
+ return components.join("\n");
372
+ },
373
+ options: { getComponents: () => componentsContext.components }
374
+ });
375
+ const typesPath = addTemplate({
376
+ filename: "types/content.d.ts",
377
+ getContents: () => [
378
+ "declare module '#content/server' {",
379
+ ` const serverQueryContent: typeof import('${resolve(options.experimental.advanceQuery ? "./runtime/server" : "./runtime/legacy/types")}').serverQueryContent`,
380
+ ` const parseContent: typeof import('${resolve("./runtime/server")}').parseContent`,
381
+ "}"
382
+ ].join("\n")
383
+ }).dst;
384
+ nuxt.hook("prepare:types", (options2) => {
385
+ options2.references.push({ path: typesPath });
386
+ });
387
+ const _layers = [...nuxt.options._layers].reverse();
388
+ for (const layer of _layers) {
389
+ const srcDir = layer.config.srcDir;
390
+ const globalComponents = resolve(srcDir, "components/content");
391
+ const dirStat = await fs.promises.stat(globalComponents).catch(() => null);
392
+ if (dirStat && dirStat.isDirectory()) {
393
+ nuxt.hook("components:dirs", (dirs) => {
394
+ dirs.unshift({
395
+ path: globalComponents,
396
+ global: true,
397
+ pathPrefix: false,
398
+ prefix: ""
399
+ });
400
+ });
401
+ }
402
+ }
403
+ if (options.navigation) {
404
+ addImports({ name: "fetchContentNavigation", as: "fetchContentNavigation", from: resolveRuntimeModule(`./${options.experimental.advanceQuery ? "" : "legacy/"}composables/navigation`) });
405
+ nuxt.hook("nitro:config", (nitroConfig) => {
406
+ nitroConfig.handlers = nitroConfig.handlers || [];
407
+ nitroConfig.handlers.push(
408
+ {
409
+ method: "get",
410
+ route: `${options.api.baseURL}/navigation/:qid/**:params`,
411
+ handler: resolveRuntimeModule("./server/api/navigation-qid-params")
412
+ },
413
+ {
414
+ method: "get",
415
+ route: `${options.api.baseURL}/navigation/:qid`,
416
+ handler: resolveRuntimeModule("./server/api/navigation-qid")
417
+ },
418
+ {
419
+ method: "get",
420
+ route: `${options.api.baseURL}/navigation`,
421
+ handler: resolveRuntimeModule("./server/api/navigation")
422
+ }
423
+ );
424
+ });
425
+ } else {
426
+ addImports({ name: "navigationDisabled", as: "fetchContentNavigation", from: resolveRuntimeModule("./composables/utils") });
427
+ }
428
+ if (nuxt.options.dev) {
429
+ addServerPlugin(resolveRuntimeModule("./server/plugins/refresh-cache"));
430
+ }
431
+ if (options.documentDriven) {
432
+ const defaultDocumentDrivenConfig = {
433
+ page: true,
434
+ navigation: true,
435
+ surround: true,
436
+ globals: {},
437
+ layoutFallbacks: ["theme"],
438
+ injectPage: true
439
+ };
440
+ if (options.documentDriven === true) {
441
+ options.documentDriven = defaultDocumentDrivenConfig;
442
+ } else {
443
+ options.documentDriven = {
444
+ ...defaultDocumentDrivenConfig,
445
+ ...options.documentDriven
446
+ };
447
+ }
448
+ if (options.navigation) {
449
+ options.navigation.fields.push("layout");
450
+ }
451
+ addImports([
452
+ { name: "useContentState", as: "useContentState", from: resolveRuntimeModule("./composables/content") },
453
+ { name: "useContent", as: "useContent", from: resolveRuntimeModule("./composables/content") }
454
+ ]);
455
+ addPlugin(resolveRuntimeModule(
456
+ options.experimental.advanceQuery ? "./plugins/documentDriven" : "./legacy/plugins/documentDriven"
457
+ ));
458
+ if (options.documentDriven.injectPage) {
459
+ nuxt.options.pages = true;
460
+ nuxt.hook("pages:extend", (pages) => {
461
+ if (!pages.find((page) => page.path === "/:slug(.*)*")) {
462
+ pages.unshift({
463
+ name: "slug",
464
+ path: "/:slug(.*)*",
465
+ file: resolveRuntimeModule("./pages/document-driven.vue"),
466
+ children: []
467
+ });
468
+ }
469
+ });
470
+ nuxt.hook("app:resolve", async (app) => {
471
+ if (app.mainComponent?.includes("@nuxt/ui-templates")) {
472
+ app.mainComponent = resolveRuntimeModule("./app.vue");
473
+ } else {
474
+ const appContent = await fs.promises.readFile(app.mainComponent, { encoding: "utf-8" });
475
+ if (appContent.includes("<NuxtLayout") || appContent.includes("<nuxt-layout")) {
476
+ logger.warn([
477
+ "Using `<NuxtLayout>` inside `app.vue` will cause unwanted layout shifting in your application.",
478
+ "Consider removing `<NuxtLayout>` from `app.vue` and using it in your pages."
479
+ ].join(" "));
480
+ }
481
+ }
482
+ });
483
+ }
484
+ } else {
485
+ addImports([
486
+ { name: "useContentDisabled", as: "useContentState", from: resolveRuntimeModule("./composables/utils") },
487
+ { name: "useContentDisabled", as: "useContent", from: resolveRuntimeModule("./composables/utils") }
488
+ ]);
489
+ }
490
+ await nuxt.callHook("content:context", contentContext);
491
+ contentContext.defaultLocale = contentContext.defaultLocale || contentContext.locales[0];
492
+ const cacheIntegrity = hash({
493
+ locales: options.locales,
494
+ options: options.defaultLocale,
495
+ markdown: options.markdown,
496
+ hightlight: options.highlight
497
+ });
498
+ contentContext.markdown = processMarkdownOptions(contentContext.markdown);
499
+ if (options.markdown?.mdc === false) {
500
+ contentContext.markdown.remarkPlugins["remark-mdc"] = void 0;
501
+ }
502
+ const nuxtMDCOptions = {
503
+ remarkPlugins: contentContext.markdown.remarkPlugins,
504
+ rehypePlugins: contentContext.markdown.rehypePlugins,
505
+ highlight: contentContext.highlight,
506
+ components: {
507
+ prose: true,
508
+ map: contentContext.markdown.tags
509
+ },
510
+ headings: {
511
+ anchorLinks: {
512
+ // Reset defaults
513
+ h2: false,
514
+ h3: false,
515
+ h4: false
516
+ }
517
+ }
518
+ };
519
+ if (contentContext.markdown.anchorLinks) {
520
+ for (let i = 0; i < contentContext.markdown.anchorLinks.depth; i++) {
521
+ nuxtMDCOptions.headings.anchorLinks[`h${i + 1}`] = !contentContext.markdown.anchorLinks.exclude.includes(i + 1);
522
+ }
523
+ }
524
+ await installModule("@nuxtjs/mdc", nuxtMDCOptions);
525
+ extendViteConfig((config) => {
526
+ config.optimizeDeps ||= {};
527
+ config.optimizeDeps.include ||= [];
528
+ config.optimizeDeps.include.push("@nuxt/content > slugify");
529
+ config.optimizeDeps.include = config.optimizeDeps.include.map((id) => id.replace(/^@nuxtjs\/mdc > /, "@nuxt/content > @nuxtjs/mdc > "));
530
+ config.plugins?.push({
531
+ name: "content-slot",
532
+ enforce: "pre",
533
+ transform(code) {
534
+ if (code.includes("ContentSlot")) {
535
+ code = code.replace(/<ContentSlot(\s)+([^/>]*)(:use=['"](\$slots.)?([a-zA-Z0-9_-]*)['"])/g, '<MDCSlot$1$2name="$5"');
536
+ code = code.replace(/<\/ContentSlot>/g, "</MDCSlot>");
537
+ code = code.replace(/<ContentSlot/g, "<MDCSlot");
538
+ code = code.replace(/(['"])ContentSlot['"]/g, "$1MDCSlot$1");
539
+ code = code.replace(/ContentSlot\(([^(]*)(:use=['"](\$slots.)?([a-zA-Z0-9_-]*)['"]|use=['"]([a-zA-Z0-9_-]*)['"])([^)]*)/g, 'MDCSlot($1name="$4"$6');
540
+ return {
541
+ code,
542
+ map: { mappings: "" }
543
+ };
544
+ }
545
+ if (code.includes("content-slot")) {
546
+ code = code.replace(/<content-slot(\s)+([^/>]*)(:use=['"](\$slots.)?([a-zA-Z0-9_-]*)['"])/g, '<MDCSlot$1$2name="$5"');
547
+ code = code.replace(/<\/content-slot>/g, "</MDCSlot>");
548
+ code = code.replace(/<content-slot/g, "<MDCSlot");
549
+ code = code.replace(/(['"])content-slot['"]/g, "$1MDCSlot$1");
550
+ code = code.replace(/content-slot\(([^(]*)(:use=['"](\$slots.)?([a-zA-Z0-9_-]*)['"]|use=['"]([a-zA-Z0-9_-]*)['"])([^)]*)/g, 'MDCSlot($1name="$4"$6');
551
+ return {
552
+ code,
553
+ map: { mappings: "" }
554
+ };
555
+ }
556
+ }
557
+ });
558
+ });
559
+ const contentRuntime = defu(nuxt.options.runtimeConfig.public.content, {
560
+ locales: options.locales,
561
+ defaultLocale: contentContext.defaultLocale || void 0,
562
+ integrity: buildIntegrity,
563
+ experimental: {
564
+ stripQueryParameters: options.experimental.stripQueryParameters,
565
+ advanceQuery: options.experimental.advanceQuery === true,
566
+ clientDB: options.experimental.clientDB && nuxt.options.ssr === false
567
+ },
568
+ respectPathCase: options.respectPathCase ?? false,
569
+ api: {
570
+ baseURL: options.api.baseURL
571
+ },
572
+ navigation: contentContext.navigation,
573
+ // Tags will use in markdown renderer for component replacement
574
+ // @deprecated
575
+ tags: contentContext.markdown.tags,
576
+ // @deprecated
577
+ highlight: options.highlight,
578
+ wsUrl: "",
579
+ // Document-driven configuration
580
+ documentDriven: options.documentDriven,
581
+ host: typeof options.documentDriven !== "boolean" ? options.documentDriven?.host ?? "" : "",
582
+ trailingSlash: typeof options.documentDriven !== "boolean" ? options.documentDriven?.trailingSlash ?? false : false,
583
+ search: options.experimental.search,
584
+ contentHead: options.contentHead ?? true,
585
+ // Anchor link generation config
586
+ // @deprecated
587
+ anchorLinks: options.markdown.anchorLinks
588
+ });
589
+ nuxt.options.runtimeConfig.public.content = contentRuntime;
590
+ nuxt.options.runtimeConfig.content = defu(nuxt.options.runtimeConfig.content, {
591
+ cacheVersion: CACHE_VERSION,
592
+ cacheIntegrity,
593
+ ...contentContext
594
+ });
595
+ nuxt.hook("tailwindcss:config", async (tailwindConfig) => {
596
+ const contentPath = resolve(nuxt.options.buildDir, "content-cache", "parsed/**/*.{md,yml,yaml,json}");
597
+ tailwindConfig.content = tailwindConfig.content ?? [];
598
+ if (Array.isArray(tailwindConfig.content)) {
599
+ tailwindConfig.content.push(contentPath);
600
+ } else {
601
+ tailwindConfig.content.files = tailwindConfig.content.files ?? [];
602
+ tailwindConfig.content.files.push(contentPath);
603
+ }
604
+ const [tailwindCssPath] = Array.isArray(nuxt.options.tailwindcss?.cssPath) ? nuxt.options.tailwindcss.cssPath : [nuxt.options.tailwindcss?.cssPath];
605
+ let cssPath = tailwindCssPath ? await resolvePath(tailwindCssPath, { extensions: [".css", ".sass", ".scss", ".less", ".styl"] }) : join(nuxt.options.dir.assets, "css/tailwind.css");
606
+ if (!fs.existsSync(cssPath)) {
607
+ cssPath = await resolvePath("tailwindcss/tailwind.css");
608
+ }
609
+ const contentSources = Object.values(useContentMounts(nuxt, contentContext.sources)).map((mount) => mount.driver === "fs" ? mount.base : void 0).filter(Boolean);
610
+ addVitePlugin({
611
+ enforce: "post",
612
+ name: "nuxt:content:tailwindcss",
613
+ handleHotUpdate(ctx) {
614
+ if (!contentSources.some((cs) => ctx.file.startsWith(cs))) {
615
+ return;
616
+ }
617
+ const extraModules = ctx.server.moduleGraph.getModulesByFile(cssPath) || /* @__PURE__ */ new Set();
618
+ const timestamp = +Date.now();
619
+ for (const mod of extraModules) {
620
+ ctx.server.moduleGraph.invalidateModule(mod, void 0, timestamp);
621
+ }
622
+ setTimeout(() => {
623
+ ctx.server.ws.send({
624
+ type: "update",
625
+ updates: Array.from(extraModules).map((mod) => {
626
+ return {
627
+ type: mod.type === "js" ? "js-update" : "css-update",
628
+ path: mod.url,
629
+ acceptedPath: mod.url,
630
+ timestamp
631
+ };
632
+ })
633
+ });
634
+ }, 100);
635
+ }
636
+ });
637
+ });
638
+ const isIgnored = makeIgnored(contentContext.ignores);
639
+ if (!nuxt.options.dev) {
640
+ nuxt.hook("build:before", async () => {
641
+ const storage = createStorage();
642
+ const sources = useContentMounts(nuxt, contentContext.sources);
643
+ sources["cache:content"] = {
644
+ driver: "fs",
645
+ base: resolve(nuxt.options.buildDir, "content-cache")
646
+ };
647
+ for (const [key, source] of Object.entries(sources)) {
648
+ storage.mount(key, await getMountDriver(source));
649
+ }
650
+ let keys = await storage.getKeys("content:source");
651
+ const invalidKeyCharacters = `'"?#/`.split("");
652
+ keys = keys.filter((key) => {
653
+ if (key.startsWith("preview:") || isIgnored(key)) {
654
+ return false;
655
+ }
656
+ if (invalidKeyCharacters.some((ik) => key.includes(ik))) {
657
+ return false;
658
+ }
659
+ return true;
660
+ });
661
+ await Promise.all(
662
+ keys.map(async (key) => await storage.setItem(
663
+ `cache:content:parsed:${key.substring(15)}`,
664
+ await storage.getItem(key)
665
+ ))
666
+ );
667
+ });
668
+ return;
669
+ }
670
+ addPlugin(resolveRuntimeModule("./plugins/ws"));
671
+ nuxt.hook("nitro:init", async (nitro) => {
672
+ if (!options.watch || !options.watch.ws) {
673
+ return;
674
+ }
675
+ const ws = createWebSocket();
676
+ const { server, url } = await listen(() => "Nuxt Content", options.watch.ws);
677
+ nitro.hooks.hook("close", async () => {
678
+ await ws.close();
679
+ await server.close();
680
+ });
681
+ server.on("upgrade", ws.serve);
682
+ nitro.options.runtimeConfig.public.content.wsUrl = url.replace("http", "ws");
683
+ await nitro.storage.removeItem("cache:content:content-index.json");
684
+ await nitro.storage.watch(async (event, key) => {
685
+ if (!key.startsWith(MOUNT_PREFIX) || isIgnored(key)) {
686
+ return;
687
+ }
688
+ key = key.substring(MOUNT_PREFIX.length);
689
+ await nitro.storage.removeItem("cache:content:content-index.json");
690
+ ws.broadcast({ event, key });
691
+ });
692
+ });
693
+ }
694
+ });
695
+
696
+ export { module as default };
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <NuxtPage />
3
+ </template>