@studiocms/markdoc 0.1.0-beta.13

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 StudioCMS - Adam Matthiesen, Jacob Jenkins, Paul Valladares
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # @StudioCMS/MarkDoc Plugin
2
+
3
+ Add MarkDoc support to StudioCMS
4
+
5
+ ## Usage
6
+
7
+ Add this plugin in your StudioCMS config. (`studiocms.config.mjs`)
8
+
9
+ ```ts
10
+ import { defineStudioCMSConfig } from 'studiocms/config';
11
+ import markdocPlugin from '@studiocms/markdoc';
12
+
13
+ export default defineStudioCMSConfig({
14
+ // other options here
15
+ plugins: [markdocPlugin()]
16
+ });
17
+ ```
18
+
19
+ ## Options
20
+
21
+ ### type
22
+ **Type:** `'html'` | `'react-static'` | [`MarkDocRenderer`](#markdocrenderer)
23
+ **Default:** `'html'`
24
+
25
+ Set the type of MarkDoc rendering that you would like to do.
26
+
27
+ ### argParse
28
+ **Type:** `ParserArgs` | `undefined`
29
+
30
+ Optional Parser args for MarkDoc
31
+
32
+ ### transformConfig
33
+ **Type:** `ConfigType` | `undefined`
34
+
35
+ Optional Transform config for MarkDoc
36
+
37
+ #### MarkDocRenderer
38
+ **Type:** `{ name: string; render: (content: import('@markdoc/markdoc').RenderableTreeNode) => Promise<string>; }`
39
+
40
+ Example Renderer
41
+ ```ts
42
+ import type { RenderableTreeNode } from '@markdoc/markdoc';
43
+ import type { MarkDocRenderer } from '@studiocms/markdoc/types';
44
+
45
+ export const renderHTML: MarkDocRenderer = {
46
+ name: 'html',
47
+ render: async (content: RenderableTreeNode) => {
48
+ return Markdoc.renderers.html(content);
49
+ },
50
+ };
51
+ ```
52
+
53
+ ## License
54
+
55
+ [MIT Licensed](./LICENSE).
@@ -0,0 +1,15 @@
1
+ ---
2
+ import renderMarkDoc from 'studiocms:markdoc/renderer';
3
+ import type { PluginPageTypeRendererProps } from 'studiocms/types';
4
+
5
+ interface Props extends PluginPageTypeRendererProps {}
6
+
7
+ // Get default content
8
+ const { defaultContent } = Astro.props.data;
9
+
10
+ // Get content to render
11
+ const contentToRender = defaultContent?.content || '# Error: No content found';
12
+
13
+ const renderedContent = await renderMarkDoc(contentToRender);
14
+ ---
15
+ <Fragment set:html={renderedContent} />
@@ -0,0 +1,10 @@
1
+ /**
2
+ * These triple-slash directives defines dependencies to various declaration files that will be
3
+ * loaded when a user imports the StudioCMS plugin in their Astro configuration file. These
4
+ * directives must be first at the top of the file and can only be preceded by this comment.
5
+ */
6
+ /// <reference types="./virtual.d.ts" preserve="true" />
7
+ import { type StudioCMSPlugin } from 'studiocms/plugins';
8
+ import type { MarkDocPluginOptions } from './types.js';
9
+ export declare function studiocmsMarkDoc(options?: MarkDocPluginOptions): StudioCMSPlugin;
10
+ export default studiocmsMarkDoc;
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ import { addVirtualImports, createResolver } from "astro-integration-kit";
2
+ import { definePlugin } from "studiocms/plugins";
3
+ import { shared } from "./lib/shared.js";
4
+ function studiocmsMarkDoc(options) {
5
+ const { resolve } = createResolver(import.meta.url);
6
+ const packageIdentifier = "@studiocms/markdoc";
7
+ const renderer = resolve("./components/MarkDocRenderer.astro");
8
+ const internalRenderer = resolve("./lib/render.js");
9
+ const resolvedOptions = {
10
+ type: options?.type || "html",
11
+ argParse: options?.argParse,
12
+ transformConfig: options?.transformConfig
13
+ };
14
+ return definePlugin({
15
+ identifier: packageIdentifier,
16
+ name: "StudioCMS MarkDoc",
17
+ studiocmsMinimumVersion: "0.1.0-beta.12",
18
+ pageTypes: [
19
+ // Define the MarkDoc page type
20
+ {
21
+ identifier: "studiocms/markdoc",
22
+ label: "MarkDoc",
23
+ pageContentComponent: "studiocms/markdown",
24
+ // Fallback to the default content editor for now, might build a custom MarkDoc editor in the future
25
+ rendererComponent: renderer
26
+ }
27
+ ],
28
+ integration: {
29
+ name: packageIdentifier,
30
+ hooks: {
31
+ "astro:config:setup": (params) => {
32
+ addVirtualImports(params, {
33
+ name: packageIdentifier,
34
+ imports: {
35
+ "studiocms:markdoc/renderer": `
36
+ import { renderMarkDoc as _render } from '${internalRenderer}';
37
+ export const renderMarkDoc = _render;
38
+ export default renderMarkDoc;
39
+ `
40
+ }
41
+ });
42
+ },
43
+ "astro:config:done": () => {
44
+ shared.markDocConfig = resolvedOptions;
45
+ }
46
+ }
47
+ }
48
+ });
49
+ }
50
+ var index_default = studiocmsMarkDoc;
51
+ export {
52
+ index_default as default,
53
+ studiocmsMarkDoc
54
+ };
@@ -0,0 +1,2 @@
1
+ export declare function renderMarkDoc(content: string): Promise<string>;
2
+ export default renderMarkDoc;
@@ -0,0 +1,45 @@
1
+ import Markdoc from "@markdoc/markdoc";
2
+ import { shared } from "./shared.js";
3
+ const { argParse, transformConfig, type } = shared.markDocConfig;
4
+ const renderHTML = {
5
+ name: "html",
6
+ render: async (content) => {
7
+ return Markdoc.renderers.html(content);
8
+ }
9
+ };
10
+ const renderReactStatic = {
11
+ name: "react-static",
12
+ render: async (content) => {
13
+ return Markdoc.renderers.reactStatic(content);
14
+ }
15
+ };
16
+ async function renderMarkDoc(content) {
17
+ const ast = Markdoc.parse(content, argParse);
18
+ const MarkDocContent = Markdoc.transform(ast, transformConfig);
19
+ switch (type) {
20
+ case "html": {
21
+ const data = await renderHTML.render(MarkDocContent);
22
+ return data;
23
+ }
24
+ case "react-static": {
25
+ const data = await renderReactStatic.render(MarkDocContent);
26
+ return data;
27
+ }
28
+ default: {
29
+ if (!type) {
30
+ throw new Error("Error in MarkDoc config, renderer not found.");
31
+ }
32
+ try {
33
+ const data = await type.render(MarkDocContent);
34
+ return data;
35
+ } catch {
36
+ throw new Error(`Error in MarkDoc renderer, Unable to render with ${type.name}`);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ var render_default = renderMarkDoc;
42
+ export {
43
+ render_default as default,
44
+ renderMarkDoc
45
+ };
@@ -0,0 +1,14 @@
1
+ import type { MarkDocPluginOptions } from '../types.js';
2
+ export declare const symbol: symbol;
3
+ /**
4
+ * A shared object that is either retrieved from the global scope using a symbol or
5
+ * initialized as a new object with a `markDocConfig` property.
6
+ *
7
+ * @remarks
8
+ * The `@ts-ignore` comments are used to suppress TypeScript errors related to the use of
9
+ * the global scope and assignment within expressions. The `biome-ignore` comment is used
10
+ * to suppress linting errors for the same reason.
11
+ */
12
+ export declare const shared: {
13
+ markDocConfig: MarkDocPluginOptions;
14
+ };
@@ -0,0 +1,13 @@
1
+ const symbol = Symbol.for("@studiocms/markdoc");
2
+ const shared = (
3
+ // @ts-ignore
4
+ globalThis[symbol] || // @ts-ignore
5
+ // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
6
+ (globalThis[symbol] = {
7
+ markDocConfig: {}
8
+ })
9
+ );
10
+ export {
11
+ shared,
12
+ symbol
13
+ };
@@ -0,0 +1,8 @@
1
+ import type React from 'react';
2
+ /**
3
+ * React component for rendering generated MarkDoc React content within StudioCMS using the Astro Container API
4
+ */
5
+ export declare function MarkDocReactRenderer({ children }: {
6
+ children: React.ReactNode;
7
+ }): React.JSX.Element;
8
+ export default MarkDocReactRenderer;
@@ -0,0 +1,10 @@
1
+ import type React from 'react';
2
+
3
+ /**
4
+ * React component for rendering generated MarkDoc React content within StudioCMS using the Astro Container API
5
+ */
6
+ export function MarkDocReactRenderer({ children }: { children: React.ReactNode }) {
7
+ return <>{children}</>;
8
+ }
9
+
10
+ export default MarkDocReactRenderer;
@@ -0,0 +1,13 @@
1
+ ---
2
+ import React from 'react';
3
+ import { MarkDocReactRenderer } from './MarkDocReactRenderer.jsx';
4
+
5
+ interface Props {
6
+ content: React.ReactNode;
7
+ }
8
+
9
+ const { content } = Astro.props;
10
+ ---
11
+ <MarkDocReactRenderer client:load>
12
+ {content}
13
+ </MarkDocReactRenderer>
@@ -0,0 +1,10 @@
1
+ import type { MarkDocRenderer } from '../types.js';
2
+ /**
3
+ * MarkDoc React Components
4
+ *
5
+ * The React components to use for rendering the content
6
+ *
7
+ * @type {Object} - The React components to use for rendering the content
8
+ */
9
+ export type markdocReactComponents = {} | undefined;
10
+ export declare const renderReact: (components?: markdocReactComponents) => MarkDocRenderer;
@@ -0,0 +1,30 @@
1
+ import reactRenderer from "@astrojs/react/server.js";
2
+ import Markdoc from "@markdoc/markdoc";
3
+ import { experimental_AstroContainer } from "astro/container";
4
+ import * as React from "react";
5
+ import ReactWrapper from "./ReactWrapper.astro";
6
+ const renderReact = (components) => ({
7
+ name: "react",
8
+ render: async (content) => {
9
+ const container = await experimental_AstroContainer.create();
10
+ container.addServerRenderer({
11
+ name: "@astrojs/react",
12
+ renderer: reactRenderer
13
+ });
14
+ container.addClientRenderer({
15
+ name: "@astrojs/react",
16
+ entrypoint: "@astrojs/react/client.js"
17
+ });
18
+ const renderedContent = await container.renderToString(ReactWrapper, {
19
+ props: {
20
+ content: Markdoc.renderers.react(content, React, {
21
+ components
22
+ })
23
+ }
24
+ });
25
+ return renderedContent;
26
+ }
27
+ });
28
+ export {
29
+ renderReact
30
+ };
@@ -0,0 +1,10 @@
1
+ import type { ConfigType, ParserArgs, RenderableTreeNode } from '@markdoc/markdoc';
2
+ export interface MarkDocRenderer {
3
+ name: string;
4
+ render: (content: RenderableTreeNode) => Promise<string>;
5
+ }
6
+ export interface MarkDocPluginOptions {
7
+ type?: 'html' | 'react-static' | MarkDocRenderer;
8
+ argParse?: ParserArgs | undefined;
9
+ transformConfig?: ConfigType | undefined;
10
+ }
package/dist/types.js ADDED
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ declare module 'studiocms:markdoc/renderer' {
2
+ export const renderMarkDoc: typeof import('./lib/render').renderMarkDoc;
3
+ export default renderMarkDoc;
4
+ }
5
+
6
+ declare module 'virtual:studiocms/plugins/renderers' {
7
+ export const studiocms_markdoc: typeof import('./components/MarkDocRenderer.astro').default;
8
+ }
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@studiocms/markdoc",
3
+ "version": "0.1.0-beta.13",
4
+ "description": "Add MarkDoc Support to your StudioCMS project with ease!",
5
+ "author": {
6
+ "name": "Adam Matthiesen | Jacob Jenkins | Paul Valladares",
7
+ "url": "https://studiocms.dev"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/withstudiocms/studiocms.git",
12
+ "directory": "packages/studiocms_markdoc"
13
+ },
14
+ "contributors": [
15
+ "Adammatthiesen",
16
+ "jdtjenkins",
17
+ "dreyfus92",
18
+ "code.spirit"
19
+ ],
20
+ "license": "MIT",
21
+ "keywords": [
22
+ "astro",
23
+ "astrocms",
24
+ "astrodb",
25
+ "astrostudio",
26
+ "astro-integration",
27
+ "astro-studio",
28
+ "astro-studiocms",
29
+ "cms",
30
+ "studiocms",
31
+ "withastro",
32
+ "plugin",
33
+ "studiocms-plugin"
34
+ ],
35
+ "homepage": "https://studiocms.dev",
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "provenance": true
39
+ },
40
+ "sideEffects": false,
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "exports": {
45
+ ".": {
46
+ "types": "./dist/index.d.ts",
47
+ "default": "./dist/index.js"
48
+ },
49
+ "./types": {
50
+ "types": "./dist/types.d.ts",
51
+ "default": "./dist/types.js"
52
+ },
53
+ "./v/types": {
54
+ "types": "./dist/virtual.d.ts",
55
+ "default": "./dist/virtual.d.js"
56
+ },
57
+ "./react": {
58
+ "types": "./dist/react-renderer/renderReact.d.ts",
59
+ "default": "./dist/react-renderer/renderReact.js"
60
+ }
61
+ },
62
+ "type": "module",
63
+ "dependencies": {
64
+ "@markdoc/markdoc": "^0.5.1",
65
+ "astro-integration-kit": "^0.18",
66
+ "react": "^19.0.0",
67
+ "react-dom": "^19.0.0"
68
+ },
69
+ "devDependencies": {
70
+ "@types/node": "^22.0.0",
71
+ "@types/react": "^19.0.12",
72
+ "@types/react-dom": "^19.0.4"
73
+ },
74
+ "peerDependencies": {
75
+ "@astrojs/react": "^4.2.1",
76
+ "astro": "^5.5.0",
77
+ "vite": "^6.2.0",
78
+ "studiocms": "0.1.0-beta.13"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "@astrojs/react": {
82
+ "optional": true
83
+ }
84
+ },
85
+ "scripts": {
86
+ "build": "build-scripts build 'src/**/*.ts'",
87
+ "dev": "build-scripts dev 'src/**/*.ts'"
88
+ }
89
+ }