@nuxtjs/mdc 0.9.2 → 0.9.3

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/README.md CHANGED
@@ -19,6 +19,7 @@ MDC supercharges regular Markdown to write documents interacting deeply with any
19
19
  - Unwrap any generated content (ex: `<p>` added by each Markdown paragraph)
20
20
  - Use Vue components with named slots
21
21
  - Support inline components
22
+ - Support asynchronous rendering of nested components
22
23
  - Add attributes and classes to inline HTML tags
23
24
 
24
25
  Learn more about the MDC syntax on https://content.nuxtjs.org/guide/writing/mdc
@@ -260,6 +261,59 @@ export default defineNuxtConfig({
260
261
 
261
262
  Checkout [`ModuleOptions` types↗︎](https://github.com/nuxt-modules/mdc/blob/main/src/types.ts).
262
263
 
264
+ ---
265
+
266
+ ## Render nested async components
267
+
268
+ The `MDCRenderer` also supports rendering _nested_ async components by waiting for any child component in its tree to resolve its top-level `async setup()`.
269
+
270
+ This behavior allows for rendering asynchronous [MDC block components](https://content.nuxt.com/usage/markdown#block-components) (e.g. via `defineAsyncComponent`) as well as introducing components that themselves internally utilize the `MDCRenderer` to render markdown before allowing the parent component to resolve.
271
+
272
+ In order for the parent `MDCRenderer` component to properly wait for the child async component(s) to resolve:
273
+
274
+ 1. All functionality in the child component **must** be executed within an async setup function with top-level `await` (if no async/await behavior is needed in the child, e.g. no data fetching, then the component will resolve normally).
275
+ 2. The child component's `template` content **should** be wrapped with the built-in [`Suspense` component](https://vuejs.org/guide/built-ins/suspense.html#suspense) with the [`suspensible` prop](https://vuejs.org/guide/built-ins/suspense.html#nested-suspense) set to `true`.
276
+
277
+ ```vue
278
+ <template>
279
+ <Suspense suspensible>
280
+ <pre>{{ data }}</pre>
281
+ </Suspense>
282
+ </template>
283
+
284
+ <script setup>
285
+ const { data } = await useAsyncData(..., {
286
+ immediate: true, // This is the default, but is required for this functionality
287
+ })
288
+ </script>
289
+ ```
290
+
291
+ In a Nuxt application, this means that setting `immediate: false` on any `useAsyncData` or `useFetch` calls would _prevent_ the parent `MDCRenderer` from waiting and the parent would potentially resolve before the child components have finished rendering, causing hydration errors or missing content.
292
+
293
+ ### Simple Example: Async Component
294
+
295
+ Your nested MDC block components can utilize top-level `async setup()` as part of their lifecycle, such as awaiting data fetching before allowing the parent component to resolve.
296
+
297
+ See the code in the playground [`AsyncComponent` component](/playground/components/global/AsyncComponent.vue) as an example, and to see the behavior in action, check out the playground by running `pnpm dev` and navigating to the `/async-components` route.
298
+
299
+ ### Advanced Example: MDC "snippets"
300
+
301
+ To demonstrate how powerful these nested async block components can be, you could allow users to define a subset of markdown documents in your project that will be utilized as reusable "snippets" in a parent document.
302
+
303
+ You would create a custom block component in your project that handles fetching the snippet markdown content from the API, use `parseMarkdown` to get the `ast` nodes, and render it in its own `MDC` or `MDCRenderer` component.
304
+
305
+ See the code in the playground [`PageSnippet` component](/playground/components/global/PageSnippet.vue) as an example, and to see the behavior in action, check out the playground by running `pnpm dev` and navigating to the `/async-components/advanced` route.
306
+
307
+ #### Handling recursion
308
+
309
+ If your project implements a "reusable snippet" type of approach, you will likely want to prevent the use of recursive snippets, whereby a nested `MDCRenderer` attempts to then load another child somewhere in its component tree with the same content (meaning, importing itself) and your application would be thrown into an infinite loop.
310
+
311
+ One way to get around this is to utilize Vue's [`provide/inject`](https://vuejs.org/guide/components/provide-inject.html#provide-inject) to pass down the history of rendered "snippets" so that a child can properly determine if it is being called recursively, and stop the chain. This can be used in combination with parsing the `ast` document nodes after calling the `parseMarkdown` function to strip out recursive node trees from the `ast` before rendering the content in the DOM.
312
+
313
+ For an example on how to prevent infinite loops and recursion with this pattern, please see the code in the playground's [`PageSnippet` component](/playground/components/global/PageSnippet.vue).
314
+
315
+ ---
316
+
263
317
  ## Rendering in your Vue project
264
318
 
265
319
  The `<MDCRenderer>` component in combination with a few exported package utilities may also be utilized inside a normal (non-Nuxt) Vue project.
@@ -399,6 +453,8 @@ onBeforeMount(async () => {
399
453
  </template>
400
454
  ```
401
455
 
456
+ ---
457
+
402
458
  ## Contributing
403
459
 
404
460
  You can dive into this module online using StackBlitz:
package/dist/module.d.mts CHANGED
@@ -88,11 +88,11 @@ interface ModuleOptions {
88
88
  /**
89
89
  * A map of remark plugins to be used for processing markdown.
90
90
  */
91
- remarkPlugins?: Record<string, UnistPlugin>;
91
+ remarkPlugins?: Record<string, UnistPlugin | false>;
92
92
  /**
93
93
  * A map of remark plugins to be used for processing markdown.
94
94
  */
95
- rehypePlugins?: Record<string, UnistPlugin>;
95
+ rehypePlugins?: Record<string, UnistPlugin | false>;
96
96
  highlight?: {
97
97
  /**
98
98
  * The highlighter to be used for highlighting code blocks.
package/dist/module.d.ts CHANGED
@@ -88,11 +88,11 @@ interface ModuleOptions {
88
88
  /**
89
89
  * A map of remark plugins to be used for processing markdown.
90
90
  */
91
- remarkPlugins?: Record<string, UnistPlugin>;
91
+ remarkPlugins?: Record<string, UnistPlugin | false>;
92
92
  /**
93
93
  * A map of remark plugins to be used for processing markdown.
94
94
  */
95
- rehypePlugins?: Record<string, UnistPlugin>;
95
+ rehypePlugins?: Record<string, UnistPlugin | false>;
96
96
  highlight?: {
97
97
  /**
98
98
  * The highlighter to be used for highlighting code blocks.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nuxtjs/mdc",
3
3
  "configKey": "mdc",
4
- "version": "0.9.2",
4
+ "version": "0.9.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -164,11 +164,15 @@ function processUnistPlugins(plugins) {
164
164
  const definitions = [];
165
165
  Object.entries(plugins).forEach(([name, plugin]) => {
166
166
  const instanceName = `_${pascalCase(name).replace(/\W/g, "")}`;
167
- imports.push(`import ${instanceName} from '${plugin.src || name}'`);
168
- if (Object.keys(plugin).length) {
169
- definitions.push(` '${name}': { instance: ${instanceName}, options: ${JSON.stringify(plugin.options || plugin)} },`);
167
+ if (plugin) {
168
+ imports.push(`import ${instanceName} from '${plugin.src || name}'`);
169
+ if (Object.keys(plugin).length) {
170
+ definitions.push(` '${name}': { instance: ${instanceName}, options: ${JSON.stringify(plugin.options || plugin)} },`);
171
+ } else {
172
+ definitions.push(` '${name}': { instance: ${instanceName} },`);
173
+ }
170
174
  } else {
171
- definitions.push(` '${name}': { instance: ${instanceName} },`);
175
+ definitions.push(` '${name}': false,`);
172
176
  }
173
177
  });
174
178
  return { imports, definitions };
@@ -222,7 +226,9 @@ const module = defineNuxtModule({
222
226
  },
223
227
  // Default configuration options of the Nuxt module
224
228
  defaults: {
225
- remarkPlugins: {},
229
+ remarkPlugins: {
230
+ "remark-emoji": {}
231
+ },
226
232
  rehypePlugins: {},
227
233
  highlight: false,
228
234
  headings: {
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { h, resolveComponent, Text, Comment, defineComponent, toRaw, computed, getCurrentInstance } from "vue";
2
+ import { h, resolveComponent, reactive, watch, Text, Comment, defineAsyncComponent, defineComponent, toRaw, computed, getCurrentInstance } from "vue";
3
3
  import destr from "destr";
4
4
  import { kebabCase, pascalCase } from "scule";
5
5
  import { find, html } from "property-information";
@@ -79,15 +79,31 @@ export default defineComponent({
79
79
  const components = (props.body?.children || []).map((n) => n.tag || n.type).filter((t) => !htmlTags.includes(t));
80
80
  return Array.from(new Set(components)).sort().join(".");
81
81
  });
82
+ const runtimeData = reactive({
83
+ ...props.data
84
+ });
85
+ watch(() => props.data, (newData) => {
86
+ Object.assign(runtimeData, newData);
87
+ });
82
88
  await resolveContentComponents(props.body, { tags });
83
- return { tags, contentKey, route };
89
+ function updateRuntimeData(code, value) {
90
+ const lastIndex = code.split(".").length - 1;
91
+ return code.split(".").reduce((o, k, i) => {
92
+ if (i == lastIndex && o) {
93
+ o[k] = value;
94
+ return o[k];
95
+ }
96
+ return typeof o === "object" ? o[k] : void 0;
97
+ }, runtimeData);
98
+ }
99
+ return { tags, contentKey, route, runtimeData, updateRuntimeData };
84
100
  },
85
101
  render(ctx) {
86
- const { tags, tag, body, data, contentKey, route, unwrap } = ctx;
102
+ const { tags, tag, body, data, contentKey, route, unwrap, runtimeData, updateRuntimeData } = ctx;
87
103
  if (!body) {
88
104
  return null;
89
105
  }
90
- const meta = { ...data, tags, $route: route };
106
+ const meta = { ...data, tags, $route: route, runtimeData, updateRuntimeData };
91
107
  const component = tag !== false ? resolveVueComponent(tag || meta.component?.name || meta.component || "div") : void 0;
92
108
  return component ? h(component, { ...meta.component?.props, class: ctx.class, ...this.$attrs, key: contentKey }, { default: defaultSlotRenderer }) : defaultSlotRenderer?.();
93
109
  function defaultSlotRenderer() {
@@ -126,6 +142,7 @@ function renderNode(node, h2, documentMeta, parentScope = {}) {
126
142
  }
127
143
  function renderBinding(node, h2, documentMeta, parentScope = {}) {
128
144
  const data = {
145
+ ...documentMeta.runtimeData,
129
146
  ...parentScope,
130
147
  $document: documentMeta,
131
148
  $doc: documentMeta
@@ -180,8 +197,8 @@ function propsToData(node, documentMeta) {
180
197
  return data;
181
198
  }
182
199
  const value = props[key];
183
- if (rxModel.test(key) && !nativeInputs.includes(tag)) {
184
- return propsToDataRxModel(key, value, data, documentMeta);
200
+ if (rxModel.test(key)) {
201
+ return propsToDataRxModel(key, value, data, documentMeta, { native: nativeInputs.includes(tag) });
185
202
  }
186
203
  if (key === "v-bind") {
187
204
  return propsToDataVBind(key, value, data, documentMeta);
@@ -201,20 +218,14 @@ function propsToData(node, documentMeta) {
201
218
  return data;
202
219
  }, {});
203
220
  }
204
- function propsToDataRxModel(key, value, data, documentMeta) {
205
- const number = (d) => +d;
206
- const trim = (d) => d.trim();
207
- const noop = (d) => d;
208
- const mods = key.replace(rxModel, "").split(".").filter((d) => d).reduce((d, k) => {
209
- d[k] = true;
210
- return d;
211
- }, {});
212
- const field = "value";
213
- const event = mods.lazy ? "change" : "input";
214
- const processor = mods.number ? number : mods.trim ? trim : noop;
215
- data[field] = evalInContext(value, documentMeta);
216
- data.on = data.on || {};
217
- data.on[event] = (e) => documentMeta[value] = processor(e);
221
+ function propsToDataRxModel(key, value, data, documentMeta, { native }) {
222
+ const propName = key.match(/^v-model:([^=]+)/)?.[1] || "modelValue";
223
+ const field = native ? "value" : propName;
224
+ const event = native ? "onInput" : `onUpdate:${propName}`;
225
+ data[field] = evalInContext(value, documentMeta.runtimeData);
226
+ data[event] = (e) => {
227
+ documentMeta.updateRuntimeData(value, native ? e.target?.value : e);
228
+ };
218
229
  return data;
219
230
  }
220
231
  function propsToDataVBind(_key, value, data, documentMeta) {
@@ -235,7 +246,17 @@ function propsToDataRxBind(key, value, data, documentMeta) {
235
246
  }
236
247
  const resolveVueComponent = (component) => {
237
248
  if (typeof component === "string") {
238
- return htmlTags.includes(component) ? component : resolveComponent(pascalCase(component), false);
249
+ if (htmlTags.includes(component)) {
250
+ return component;
251
+ }
252
+ const _component = resolveComponent(pascalCase(component), false);
253
+ if (!component || _component?.name === "AsyncComponentWrapper") {
254
+ return _component;
255
+ }
256
+ if ("setup" in _component) {
257
+ return defineAsyncComponent(() => new Promise((resolve) => resolve(_component)));
258
+ }
259
+ return _component;
239
260
  }
240
261
  return component;
241
262
  };
@@ -55,6 +55,12 @@ declare const _default: DefineComponent<import("vue").ExtractPropTypes<{
55
55
  tags: any;
56
56
  contentKey: import("vue").ComputedRef<string>;
57
57
  route: any;
58
+ runtimeData: {
59
+ [x: string]: any;
60
+ };
61
+ updateRuntimeData: (code: string, value: any) => {
62
+ [x: string]: any;
63
+ };
58
64
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
59
65
  /**
60
66
  * Content to render
@@ -345,6 +351,10 @@ declare global {
345
351
  type __VLS_PrettifyGlobal<T> = {
346
352
  [K in keyof T]: T[K];
347
353
  } & {};
354
+ type __VLS_PickFunctionalComponentCtx<T, K> = NonNullable<__VLS_PickNotAny<'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends {
355
+ __ctx?: infer Ctx;
356
+ } ? Ctx : never : any, T extends (props: any, ctx: infer Ctx) => any ? Ctx : any>>;
357
+ type __VLS_UseTemplateRef<T> = Readonly<import('vue').ShallowRef<T | null>>;
348
358
  function __VLS_getVForSourceType(source: number): [number, number, number][];
349
359
  function __VLS_getVForSourceType(source: string): [string, number, number][];
350
360
  function __VLS_getVForSourceType<T extends any[]>(source: T): [
@@ -377,7 +387,7 @@ declare global {
377
387
  ][];
378
388
  function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>;
379
389
  function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0];
380
- function __VLS_directiveAsFunction<T extends import('vue').Directive>(dir: T): T extends (...args: any) => any ? T | __VLS_unknownDirective : NonNullable<(T & Record<string, __VLS_unknownDirective>)['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>;
390
+ function __VLS_asFunctionalDirective<T>(dir: T): T extends import('vue').ObjectDirective ? NonNullable<T['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']> : T extends (...args: any) => any ? T : __VLS_unknownDirective;
381
391
  function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
382
392
  function __VLS_makeOptional<T>(t: T): {
383
393
  [K in keyof T]?: T[K];
@@ -411,9 +421,6 @@ declare global {
411
421
  };
412
422
  function __VLS_elementAsFunction<T>(tag: T, endTag?: T): (_: T & Record<string, unknown>) => void;
413
423
  function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : [];
414
- function __VLS_pickFunctionalComponentCtx<T, K>(comp: T, compInstance: K): NonNullable<__VLS_PickNotAny<'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends {
415
- __ctx?: infer Ctx;
416
- } ? Ctx : never : any, T extends (props: any, ctx: infer Ctx) => any ? Ctx : any>>;
417
424
  function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
418
425
  function __VLS_tryAsConstant<const T>(t: T): T;
419
426
  }
@@ -1,6 +1,11 @@
1
+ import type { Options as VFileOptions } from 'vfile';
1
2
  import type { MDCParseOptions, MDCParserResult, MDCRoot } from '@nuxtjs/mdc';
2
- export declare const createMarkdownParser: (inlineOptions?: MDCParseOptions) => Promise<(md: string) => Promise<MDCParserResult>>;
3
- export declare const parseMarkdown: (md: string, inlineOptions?: MDCParseOptions) => Promise<MDCParserResult>;
3
+ export declare const createMarkdownParser: (inlineOptions?: MDCParseOptions) => Promise<(md: string, { fileOptions }?: {
4
+ fileOptions?: VFileOptions;
5
+ }) => Promise<MDCParserResult>>;
6
+ export declare const parseMarkdown: (md: string, markdownParserOptions?: MDCParseOptions, parseOptions?: {
7
+ fileOptions?: VFileOptions;
8
+ }) => Promise<MDCParserResult>;
4
9
  export declare function contentHeading(body: MDCRoot): {
5
10
  title: string;
6
11
  description: string;
@@ -67,9 +67,9 @@ export const createMarkdownParser = async (inlineOptions = {}) => {
67
67
  for (const config of mdcConfigs) {
68
68
  processor = await config.unified?.post?.(processor) || processor;
69
69
  }
70
- return async (md) => {
70
+ return async function parse(md, { fileOptions } = {}) {
71
71
  const { content, data: frontmatter } = await parseFrontMatter(md);
72
- const processedFile = await processor.process({ value: content, data: frontmatter });
72
+ const processedFile = await processor.process({ ...fileOptions, value: content, data: frontmatter });
73
73
  const result = processedFile.result;
74
74
  const data = Object.assign(
75
75
  contentHeading(result.body),
@@ -89,9 +89,9 @@ export const createMarkdownParser = async (inlineOptions = {}) => {
89
89
  };
90
90
  };
91
91
  };
92
- export const parseMarkdown = async (md, inlineOptions = {}) => {
93
- const parser = await createMarkdownParser(inlineOptions);
94
- return parser(md);
92
+ export const parseMarkdown = async (md, markdownParserOptions = {}, parseOptions = {}) => {
93
+ const parser = await createMarkdownParser(markdownParserOptions);
94
+ return parser(md, parseOptions);
95
95
  };
96
96
  export function contentHeading(body) {
97
97
  let title = "";
@@ -1,4 +1,3 @@
1
- import remarkEmoji from "remark-emoji";
2
1
  import remarkGFM from "remark-gfm";
3
2
  import remarkMDC from "remark-mdc";
4
3
  import rehypeExternalLinks from "rehype-external-links";
@@ -12,9 +11,6 @@ export const defaults = {
12
11
  "remark-mdc": {
13
12
  instance: remarkMDC
14
13
  },
15
- "remark-emoji": {
16
- instance: remarkEmoji
17
- },
18
14
  "remark-gfm": {
19
15
  instance: remarkGFM
20
16
  }
@@ -61,7 +61,7 @@ function _flatUnwrap(vnodes, tags = []) {
61
61
  }
62
62
  export function flatUnwrap(vnodes, tags = []) {
63
63
  if (typeof tags === "string") {
64
- tags = tags.split(",").map((tag) => tag.trim()).filter(Boolean);
64
+ tags = tags.split(/[,\s]/).map((tag) => tag.trim()).filter(Boolean);
65
65
  }
66
66
  if (!tags.length) {
67
67
  return vnodes;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxtjs/mdc",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Nuxt MDC module",
5
5
  "repository": "nuxt-modules/mdc",
6
6
  "license": "MIT",
@@ -71,11 +71,11 @@
71
71
  "test:watch": "vitest watch"
72
72
  },
73
73
  "dependencies": {
74
- "@nuxt/kit": "^3.13.2",
75
- "@shikijs/transformers": "^1.22.0",
74
+ "@nuxt/kit": "^3.14.159",
75
+ "@shikijs/transformers": "^1.23.1",
76
76
  "@types/hast": "^3.0.4",
77
77
  "@types/mdast": "^4.0.4",
78
- "@vue/compiler-core": "^3.5.12",
78
+ "@vue/compiler-core": "^3.5.13",
79
79
  "consola": "^3.2.3",
80
80
  "debug": "^4.3.7",
81
81
  "defu": "^6.1.4",
@@ -84,9 +84,9 @@
84
84
  "github-slugger": "^2.0.0",
85
85
  "hast-util-to-string": "^3.0.1",
86
86
  "mdast-util-to-hast": "^13.2.0",
87
- "micromark-util-sanitize-uri": "^2.0.0",
87
+ "micromark-util-sanitize-uri": "^2.0.1",
88
88
  "ohash": "^1.1.4",
89
- "parse5": "^7.2.0",
89
+ "parse5": "^7.2.1",
90
90
  "pathe": "^1.1.2",
91
91
  "property-information": "^6.5.0",
92
92
  "rehype-external-links": "^3.0.0",
@@ -96,36 +96,40 @@
96
96
  "rehype-sort-attributes": "^5.0.1",
97
97
  "remark-emoji": "^5.0.1",
98
98
  "remark-gfm": "^4.0.0",
99
- "remark-mdc": "^3.2.1",
99
+ "remark-mdc": "^3.3.0",
100
100
  "remark-parse": "^11.0.0",
101
101
  "remark-rehype": "^11.1.1",
102
102
  "scule": "^1.3.0",
103
- "shiki": "^1.22.0",
103
+ "shiki": "^1.23.1",
104
104
  "ufo": "^1.5.4",
105
105
  "unified": "^11.0.5",
106
106
  "unist-builder": "^4.0.0",
107
107
  "unist-util-visit": "^5.0.0",
108
- "unwasm": "^0.3.9"
108
+ "unwasm": "^0.3.9",
109
+ "vfile": "^6.0.3"
109
110
  },
110
111
  "devDependencies": {
111
112
  "@nuxt/devtools": "latest",
112
- "@nuxt/eslint-config": "^0.6.0",
113
+ "@nuxt/eslint-config": "^0.7.1",
113
114
  "@nuxt/module-builder": "^0.8.4",
114
- "@nuxt/schema": "^3.13.2",
115
- "@nuxt/test-utils": "^3.14.3",
116
- "@nuxt/ui": "^2.18.7",
115
+ "@nuxt/schema": "^3.14.159",
116
+ "@nuxt/test-utils": "^3.14.4",
117
+ "@nuxt/ui": "^2.19.2",
117
118
  "@nuxtjs/mdc": "link:.",
118
- "@types/node": "^22.7.5",
119
+ "@types/node": "^22.9.0",
119
120
  "changelogen": "^0.5.7",
120
- "eslint": "^9.12.0",
121
- "nuxt": "^3.13.2",
121
+ "eslint": "^9.15.0",
122
+ "nuxt": "^3.14.159",
122
123
  "rehype": "^13.0.2",
123
- "release-it": "^17.9.0",
124
+ "release-it": "^17.10.0",
124
125
  "typescript": "^5.6.3",
125
- "vitest": "^2.1.3",
126
- "vue-tsc": "^2.1.6"
126
+ "vitest": "^2.1.5",
127
+ "vue-tsc": "^2.1.10"
127
128
  },
128
- "packageManager": "pnpm@9.12.1",
129
+ "resolutions": {
130
+ "@nuxtjs/mdc": "workspace:*"
131
+ },
132
+ "packageManager": "pnpm@9.13.2",
129
133
  "release-it": {
130
134
  "git": {
131
135
  "commitMessage": "chore(release): release v${version}"