@ossido-labs/ossido-mdx 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/esm/index.d.ts +18 -0
- package/dist/esm/index.js +0 -0
- package/dist/esm/vite.d.ts +25 -0
- package/dist/esm/vite.js +79 -0
- package/dist/esm/vite.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chris Schofield
|
|
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,64 @@
|
|
|
1
|
+
# ossido-mdx
|
|
2
|
+
|
|
3
|
+
MDX support for [ossido](https://ossido.dev), with a Next.js-style
|
|
4
|
+
`src/mdx-components.tsx` convention for styling Markdown globally — no
|
|
5
|
+
`<MDXProvider>` boilerplate.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Install:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @ossido-labs/ossido-mdx
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add the plugin to your ossido config:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// ossido.config.ts
|
|
19
|
+
import type { OssidoConfig } from '@ossido-labs/ossido/config';
|
|
20
|
+
import { ossidoMdx } from '@ossido-labs/ossido-mdx/vite';
|
|
21
|
+
|
|
22
|
+
const config: OssidoConfig = {
|
|
23
|
+
vite: { plugins: [ossidoMdx()] },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default config;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
That's it — `.mdx` files under `src/routes` now compile and render.
|
|
30
|
+
|
|
31
|
+
## Global components
|
|
32
|
+
|
|
33
|
+
Create `src/mdx-components.tsx` and export a `useMDXComponents` function. Every
|
|
34
|
+
`.mdx` file uses it automatically (it's wired through MDX's `providerImportSource`,
|
|
35
|
+
so there's no provider to render):
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// src/mdx-components.tsx
|
|
39
|
+
import type { MDXComponents } from '@ossido-labs/ossido-mdx';
|
|
40
|
+
import { Link } from '@ossido-labs/ossido';
|
|
41
|
+
|
|
42
|
+
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
|
43
|
+
return {
|
|
44
|
+
h1: (props) => <h1 className="text-3xl font-bold" {...props} />,
|
|
45
|
+
a: ({ href = '', ...props }) => <Link href={href} {...props} />,
|
|
46
|
+
// per-file components (passed to a rendered <MDXContent components={...} />)
|
|
47
|
+
// still win:
|
|
48
|
+
...components,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The file is optional: until it exists, MDX renders with plain HTML elements.
|
|
54
|
+
|
|
55
|
+
## Options
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
ossidoMdx({
|
|
59
|
+
// forwarded to @mdx-js/rollup (remark/rehype plugins, etc.)
|
|
60
|
+
mdxOptions: { remarkPlugins: [], rehypePlugins: [] },
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`providerImportSource` is managed by the plugin and can't be overridden.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The map of components MDX renders HTML/JSX elements with. Return this from the
|
|
3
|
+
* `useMDXComponents` export of your `src/mdx-components.tsx` to style Markdown
|
|
4
|
+
* globally (see {@link ./vite | `ossido-mdx/vite`}).
|
|
5
|
+
*
|
|
6
|
+
* @example src/mdx-components.tsx
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import type { MDXComponents } from '@ossido-labs/ossido-mdx'
|
|
9
|
+
*
|
|
10
|
+
* export function useMDXComponents(components: MDXComponents): MDXComponents {
|
|
11
|
+
* return {
|
|
12
|
+
* h1: (props) => <h1 className="text-3xl font-bold" {...props} />,
|
|
13
|
+
* ...components,
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type { MDXComponents } from 'mdx/types';
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
export interface OssidoMdxOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Extra options forwarded to `@mdx-js/rollup` (remark/rehype plugins, etc.).
|
|
5
|
+
* `providerImportSource` is managed by this plugin and can't be overridden.
|
|
6
|
+
*/
|
|
7
|
+
mdxOptions?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* MDX support for ossido with a Next.js-style global components convention.
|
|
11
|
+
*
|
|
12
|
+
* Add it to your ossido config's `vite.plugins`:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // ossido.config.ts
|
|
16
|
+
* import { ossidoMdx } from '@ossido-labs/ossido-mdx/vite'
|
|
17
|
+
*
|
|
18
|
+
* export default { vite: { plugins: [ossidoMdx()] } }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Then style Markdown globally by exporting `useMDXComponents` from
|
|
22
|
+
* `src/mdx-components.tsx` — every `.mdx` file picks it up, no `<MDXProvider>`
|
|
23
|
+
* needed. Until that file exists, MDX renders with plain HTML elements.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ossidoMdx(options?: OssidoMdxOptions): Array<Plugin>;
|
package/dist/esm/vite.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import mdx from "@mdx-js/rollup";
|
|
4
|
+
|
|
5
|
+
//#region src/vite.ts
|
|
6
|
+
/**
|
|
7
|
+
* The module the MDX compiler imports `useMDXComponents` from (via
|
|
8
|
+
* `providerImportSource`). It is virtual: the `ossido-mdx:components` plugin
|
|
9
|
+
* resolves it to the project's `src/mdx-components` file, or a passthrough
|
|
10
|
+
* default when that file doesn't exist yet.
|
|
11
|
+
*/
|
|
12
|
+
const VIRTUAL_ID = "virtual:ossido-mdx/components";
|
|
13
|
+
const RESOLVED_VIRTUAL_ID = "\0virtual:ossido-mdx/components";
|
|
14
|
+
const COMPONENTS_BASENAME = "mdx-components";
|
|
15
|
+
const EXTENSIONS = [
|
|
16
|
+
"tsx",
|
|
17
|
+
"jsx",
|
|
18
|
+
"ts",
|
|
19
|
+
"js"
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Locate the project's `src/mdx-components.{tsx,jsx,ts,js}`.
|
|
23
|
+
*
|
|
24
|
+
* ossido runs vite with `root: '.ossido'`, so the project lives one directory
|
|
25
|
+
* up; we look there first (the real location) and fall back to the vite root so
|
|
26
|
+
* this also works for a non-ossido vite project.
|
|
27
|
+
*/
|
|
28
|
+
function findComponentsFile(viteRoot) {
|
|
29
|
+
const projectRoots = [path.dirname(viteRoot), viteRoot];
|
|
30
|
+
for (const base of projectRoots) for (const ext of EXTENSIONS) {
|
|
31
|
+
const candidate = path.join(base, "src", `${COMPONENTS_BASENAME}.${ext}`);
|
|
32
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* MDX support for ossido with a Next.js-style global components convention.
|
|
37
|
+
*
|
|
38
|
+
* Add it to your ossido config's `vite.plugins`:
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* // ossido.config.ts
|
|
42
|
+
* import { ossidoMdx } from '@ossido-labs/ossido-mdx/vite'
|
|
43
|
+
*
|
|
44
|
+
* export default { vite: { plugins: [ossidoMdx()] } }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* Then style Markdown globally by exporting `useMDXComponents` from
|
|
48
|
+
* `src/mdx-components.tsx` — every `.mdx` file picks it up, no `<MDXProvider>`
|
|
49
|
+
* needed. Until that file exists, MDX renders with plain HTML elements.
|
|
50
|
+
*/
|
|
51
|
+
function ossidoMdx(options = {}) {
|
|
52
|
+
let viteRoot = process.cwd();
|
|
53
|
+
return [{
|
|
54
|
+
name: "ossido-mdx:components",
|
|
55
|
+
enforce: "pre",
|
|
56
|
+
configResolved(config) {
|
|
57
|
+
viteRoot = config.root;
|
|
58
|
+
},
|
|
59
|
+
resolveId(id) {
|
|
60
|
+
if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
|
|
61
|
+
},
|
|
62
|
+
load(id) {
|
|
63
|
+
if (id !== RESOLVED_VIRTUAL_ID) return void 0;
|
|
64
|
+
const file = findComponentsFile(viteRoot);
|
|
65
|
+
if (file) return `export { useMDXComponents } from ${JSON.stringify(file)}`;
|
|
66
|
+
return `export function useMDXComponents(components) {\n return components ?? {}\n}`;
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
enforce: "pre",
|
|
70
|
+
...mdx({
|
|
71
|
+
...options.mdxOptions,
|
|
72
|
+
providerImportSource: VIRTUAL_ID
|
|
73
|
+
})
|
|
74
|
+
}];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { ossidoMdx };
|
|
79
|
+
//# sourceMappingURL=vite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","names":[],"sources":["../../src/vite.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport mdx from '@mdx-js/rollup';\nimport type { Plugin } from 'vite';\n\n/**\n * The module the MDX compiler imports `useMDXComponents` from (via\n * `providerImportSource`). It is virtual: the `ossido-mdx:components` plugin\n * resolves it to the project's `src/mdx-components` file, or a passthrough\n * default when that file doesn't exist yet.\n */\nconst VIRTUAL_ID = 'virtual:ossido-mdx/components';\nconst RESOLVED_VIRTUAL_ID = '\\0' + VIRTUAL_ID;\n\nconst COMPONENTS_BASENAME = 'mdx-components';\nconst EXTENSIONS = ['tsx', 'jsx', 'ts', 'js'] as const;\n\n/**\n * Locate the project's `src/mdx-components.{tsx,jsx,ts,js}`.\n *\n * ossido runs vite with `root: '.ossido'`, so the project lives one directory\n * up; we look there first (the real location) and fall back to the vite root so\n * this also works for a non-ossido vite project.\n */\nfunction findComponentsFile(viteRoot: string): string | undefined {\n const projectRoots = [path.dirname(viteRoot), viteRoot];\n for (const base of projectRoots) {\n for (const ext of EXTENSIONS) {\n const candidate = path.join(base, 'src', `${COMPONENTS_BASENAME}.${ext}`);\n if (fs.existsSync(candidate)) return candidate;\n }\n }\n return undefined;\n}\n\nexport interface OssidoMdxOptions {\n /**\n * Extra options forwarded to `@mdx-js/rollup` (remark/rehype plugins, etc.).\n * `providerImportSource` is managed by this plugin and can't be overridden.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mdxOptions?: Record<string, any>;\n}\n\n/**\n * MDX support for ossido with a Next.js-style global components convention.\n *\n * Add it to your ossido config's `vite.plugins`:\n *\n * ```ts\n * // ossido.config.ts\n * import { ossidoMdx } from '@ossido-labs/ossido-mdx/vite'\n *\n * export default { vite: { plugins: [ossidoMdx()] } }\n * ```\n *\n * Then style Markdown globally by exporting `useMDXComponents` from\n * `src/mdx-components.tsx` — every `.mdx` file picks it up, no `<MDXProvider>`\n * needed. Until that file exists, MDX renders with plain HTML elements.\n */\nexport function ossidoMdx(options: OssidoMdxOptions = {}): Array<Plugin> {\n let viteRoot = process.cwd();\n\n const componentsPlugin: Plugin = {\n name: 'ossido-mdx:components',\n enforce: 'pre',\n configResolved(config): void {\n viteRoot = config.root;\n },\n resolveId(id): string | undefined {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n return undefined;\n },\n load(id): string | undefined {\n if (id !== RESOLVED_VIRTUAL_ID) return undefined;\n\n const file = findComponentsFile(viteRoot);\n if (file) {\n // Re-export the user's hook; the dependency on `file` also gives HMR.\n return `export { useMDXComponents } from ${JSON.stringify(file)}`;\n }\n // Passthrough default: MDX works before a mdx-components file is created.\n return `export function useMDXComponents(components) {\\n return components ?? {}\\n}`;\n },\n };\n\n const mdxPlugin: Plugin = {\n enforce: 'pre',\n ...(mdx({\n ...options.mdxOptions,\n providerImportSource: VIRTUAL_ID,\n }) as Plugin),\n };\n\n return [componentsPlugin, mdxPlugin];\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,aAAa;AACnB,MAAM,sBAAsB;AAE5B,MAAM,sBAAsB;AAC5B,MAAM,aAAa;CAAC;CAAO;CAAO;CAAM;AAAI;;;;;;;;AAS5C,SAAS,mBAAmB,UAAsC;CAChE,MAAM,eAAe,CAAC,KAAK,QAAQ,QAAQ,GAAG,QAAQ;CACtD,KAAK,MAAM,QAAQ,cACjB,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,YAAY,KAAK,KAAK,MAAM,OAAO,GAAG,oBAAoB,GAAG,KAAK;EACxE,IAAI,GAAG,WAAW,SAAS,GAAG,OAAO;CACvC;AAGJ;;;;;;;;;;;;;;;;;AA2BA,SAAgB,UAAU,UAA4B,CAAC,GAAkB;CACvE,IAAI,WAAW,QAAQ,IAAI;CAiC3B,OAAO,CAAC;EA9BN,MAAM;EACN,SAAS;EACT,eAAe,QAAc;GAC3B,WAAW,OAAO;EACpB;EACA,UAAU,IAAwB;GAChC,IAAI,OAAO,YAAY,OAAO;EAEhC;EACA,KAAK,IAAwB;GAC3B,IAAI,OAAO,qBAAqB,OAAO;GAEvC,MAAM,OAAO,mBAAmB,QAAQ;GACxC,IAAI,MAEF,OAAO,oCAAoC,KAAK,UAAU,IAAI;GAGhE,OAAO;EACT;CAWqB,GAAG;EAPxB,SAAS;EACT,GAAI,IAAI;GACN,GAAG,QAAQ;GACX,sBAAsB;EACxB,CAAC;CAG+B,CAAC;AACrC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ossido-labs/ossido-mdx",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "MDX support for ossido with a Next.js-style src/mdx-components.tsx convention for global MDX components. Ossido is the react/rust fullstack framework",
|
|
8
|
+
"homepage": "https://ossido.dev",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "tsdown --watch",
|
|
11
|
+
"build": "tsdown && tsc -p tsconfig.build.json",
|
|
12
|
+
"prepack": "bun run build",
|
|
13
|
+
"lint": "oxlint",
|
|
14
|
+
"format": "oxfmt --check .",
|
|
15
|
+
"format:fix": "oxfmt .",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"test": "vitest run"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/ossido-labs/ossido.git",
|
|
23
|
+
"directory": "packages/ossido-mdx"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [],
|
|
26
|
+
"author": "Chris Schofield <chris@childishforces.com>",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"types": "dist/esm/index.d.ts",
|
|
30
|
+
"main": "dist/esm/index.js",
|
|
31
|
+
"module": "dist/esm/index.js",
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/esm/index.d.ts",
|
|
39
|
+
"default": "./dist/esm/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./vite": {
|
|
42
|
+
"types": "./dist/esm/vite.d.ts",
|
|
43
|
+
"default": "./dist/esm/vite.js"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@mdx-js/rollup": "^3.1.0",
|
|
49
|
+
"@types/mdx": "^2.0.13"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"vite": "^8.1.5"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"vite": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"tsdown": "0.22.14",
|
|
61
|
+
"vite": "^8.2.0",
|
|
62
|
+
"vite-config": "1.0.0",
|
|
63
|
+
"vitest": "4.1.10"
|
|
64
|
+
}
|
|
65
|
+
}
|