orga-build 0.6.2 → 0.7.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/README.org CHANGED
@@ -82,6 +82,10 @@ export default {
82
82
  // These are injected in dev SSR <head> and imported by the client entry.
83
83
  styles: ['/style.css'],
84
84
 
85
+ // Extra rehype plugins appended to orga-build defaults
86
+ // Useful for syntax highlighting (e.g. rehype-pretty-code).
87
+ rehypePlugins: [],
88
+
85
89
  // Additional Vite plugins
86
90
  vitePlugins: []
87
91
  }
@@ -95,8 +99,19 @@ export default {
95
99
  | =outDir= | =string= | ='out'= | Output directory for production build |
96
100
  | =containerClass= | =string \vert string[]= | =[]= | CSS class(es) for content wrapper |
97
101
  | =styles= | =string[]= | =[]= | Global stylesheet URLs injected/imported explicitly |
102
+ | =rehypePlugins= | =PluggableList= | =[]= | Extra rehype plugins appended to orga-build defaults |
98
103
  | =vitePlugins= | =PluginOption[]= | =[]= | Additional Vite plugins |
99
104
 
105
+ ** Syntax Highlighting Example
106
+
107
+ #+begin_src javascript
108
+ import rehypePrettyCode from 'rehype-pretty-code'
109
+
110
+ export default {
111
+ rehypePlugins: [[rehypePrettyCode, { theme: 'github-dark' }]]
112
+ }
113
+ #+end_src
114
+
100
115
  * TypeScript Setup
101
116
 
102
117
  If you're using TypeScript and want type support for the =orga-build:content= virtual module, you need to add a reference to the type definitions.
package/cli.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  import { argv } from 'node:process'
4
4
  import { parseArgs } from 'node:util'
5
- import { loadConfig } from './lib/config.js'
6
5
  import { build } from './lib/build.js'
6
+ import { loadConfig } from './lib/config.js'
7
7
  import { serve } from './lib/serve.js'
8
8
 
9
9
  const { positionals } = parseArgs({
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { build } from "./lib/build.js";
2
- export { orgaBuildPlugin, createOrgaBuildConfig, alias } from "./lib/plugin.js";
2
+ export { alias, createOrgaBuildConfig, orgaBuildPlugin } from "./lib/plugin.js";
3
3
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export { build } from './lib/build.js'
2
- export { orgaBuildPlugin, createOrgaBuildConfig, alias } from './lib/plugin.js'
2
+ export { alias, createOrgaBuildConfig, orgaBuildPlugin } from './lib/plugin.js'
@@ -1,7 +1,7 @@
1
- import { test, describe, before, after } from 'node:test'
2
1
  import assert from 'node:assert'
3
2
  import fs from 'node:fs/promises'
4
3
  import path from 'node:path'
4
+ import { after, before, describe, test } from 'node:test'
5
5
  import { fileURLToPath } from 'node:url'
6
6
  import { build } from '../build.js'
7
7
 
@@ -9,6 +9,21 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
9
  const fixtureDir = path.join(__dirname, 'fixtures')
10
10
  const outDir = path.join(__dirname, '.test-output')
11
11
 
12
+ function markCodeBlocks() {
13
+ /**
14
+ * @param {any} tree
15
+ */
16
+ return (tree) => {
17
+ tree.children ||= []
18
+ tree.children.unshift({
19
+ type: 'element',
20
+ tagName: 'div',
21
+ properties: { id: 'rehype-plugin-ran' },
22
+ children: []
23
+ })
24
+ }
25
+ }
26
+
12
27
  describe('orga-build', () => {
13
28
  before(async () => {
14
29
  await fs.mkdir(fixtureDir, { recursive: true })
@@ -27,7 +42,10 @@ Here's [[file:./docs/index.org][index page]].
27
42
  Here's [[file:more.org][another page]].
28
43
  `
29
44
  )
30
- await fs.writeFile(path.join(fixtureDir, 'docs', 'index.org'), 'Docs index page.')
45
+ await fs.writeFile(
46
+ path.join(fixtureDir, 'docs', 'index.org'),
47
+ 'Docs index page.'
48
+ )
31
49
  await fs.writeFile(path.join(fixtureDir, 'more.org'), 'Another page.')
32
50
  await fs.writeFile(
33
51
  path.join(fixtureDir, 'style.css'),
@@ -62,7 +80,10 @@ Here's [[file:more.org][another page]].
62
80
  const html = await fs.readFile(indexPath, 'utf-8')
63
81
  assert.ok(html.includes('<title>Test Page</title>'), 'should have title')
64
82
  assert.ok(html.includes('Hello World'), 'should have heading content')
65
- assert.ok(html.includes('href="/docs"'), 'should rewrite docs/index.org to /docs')
83
+ assert.ok(
84
+ html.includes('href="/docs"'),
85
+ 'should rewrite docs/index.org to /docs'
86
+ )
66
87
  assert.ok(html.includes('href="/more"'), 'should rewrite more.org to /more')
67
88
  })
68
89
 
@@ -87,10 +108,16 @@ Here's [[file:more.org][another page]].
87
108
  })
88
109
 
89
110
  const html = await fs.readFile(path.join(outDir, 'index.html'), 'utf-8')
90
- assert.ok(!html.includes('href="/style.css"'), 'should not link raw source css path')
111
+ assert.ok(
112
+ !html.includes('href="/style.css"'),
113
+ 'should not link raw source css path'
114
+ )
91
115
 
92
116
  const cssHrefMatch = html.match(/href="\/(assets\/[^"]+\.css)"/)
93
- assert.ok(cssHrefMatch, 'should link built css asset from assets with hashed name')
117
+ assert.ok(
118
+ cssHrefMatch,
119
+ 'should link built css asset from assets with hashed name'
120
+ )
94
121
 
95
122
  const builtCssPath = cssHrefMatch[1]
96
123
  const builtCss = await fs.readFile(path.join(outDir, builtCssPath), 'utf-8')
@@ -99,4 +126,41 @@ Here's [[file:more.org][another page]].
99
126
  'built css should include configured global style content'
100
127
  )
101
128
  })
129
+
130
+ test('applies custom rehype plugins from config', async () => {
131
+ const fixtureDirRehype = path.join(__dirname, 'fixtures-rehype')
132
+ const outDirRehype = path.join(__dirname, '.test-output-rehype')
133
+
134
+ try {
135
+ await fs.mkdir(fixtureDirRehype, { recursive: true })
136
+ await fs.writeFile(
137
+ path.join(fixtureDirRehype, 'index.org'),
138
+ `#+title: Rehype Test
139
+
140
+ This page verifies custom rehype plugins.`
141
+ )
142
+
143
+ await build({
144
+ root: fixtureDirRehype,
145
+ outDir: outDirRehype,
146
+ containerClass: [],
147
+ rehypePlugins: [markCodeBlocks],
148
+ vitePlugins: [],
149
+ preBuild: [],
150
+ postBuild: []
151
+ })
152
+
153
+ const html = await fs.readFile(
154
+ path.join(outDirRehype, 'index.html'),
155
+ 'utf-8'
156
+ )
157
+ assert.ok(
158
+ html.includes('rehype-plugin-ran'),
159
+ 'should apply user-provided rehype plugins to rendered HTML'
160
+ )
161
+ } finally {
162
+ await fs.rm(outDirRehype, { recursive: true, force: true })
163
+ await fs.rm(fixtureDirRehype, { recursive: true, force: true })
164
+ }
165
+ })
102
166
  })
package/lib/app.jsx CHANGED
@@ -1,7 +1,7 @@
1
- import pages from '/@orga-build/pages'
2
- import layouts from '/@orga-build/layouts'
1
+ import { Link, Route, Switch } from 'wouter'
3
2
  import * as components from '/@orga-build/components'
4
- import { Route, Switch, Link } from 'wouter'
3
+ import layouts from '/@orga-build/layouts'
4
+ import pages from '/@orga-build/pages'
5
5
 
6
6
  export function App() {
7
7
  const _pages = Object.entries(pages).map(([path, page]) => {
@@ -15,7 +15,9 @@ export function App() {
15
15
  const layoutIds = Object.keys(layouts)
16
16
  .filter((key) => path.startsWith(key))
17
17
  .sort((a, b) => -a.localeCompare(b))
18
- let element = <page.default components={{ ...components, Link, a: Link }} />
18
+ let element = (
19
+ <page.default key={path} components={{ ...components, Link, a: Link }} />
20
+ )
19
21
  for (const layoutId of layoutIds) {
20
22
  const Layout = layouts[layoutId]
21
23
  element = (
package/lib/build.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * @param {import('./config.js').Config} config
3
3
  * @param {string} [projectRoot]
4
4
  */
5
- export function build({ outDir, root, containerClass, styles, vitePlugins }: import("./config.js").Config, projectRoot?: string): Promise<void>;
5
+ export function build({ outDir, root, containerClass, styles, rehypePlugins, vitePlugins }: import("./config.js").Config, projectRoot?: string): Promise<void>;
6
6
  export { alias };
7
7
  import { alias } from './plugin.js';
8
8
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["build.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH,6EAHW,OAAO,aAAa,EAAE,MAAM,gBAC5B,MAAM,iBAoJhB;;sBAhK4C,aAAa"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["build.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH,4FAHW,OAAO,aAAa,EAAE,MAAM,gBAC5B,MAAM,iBA8JhB;;sBA1K4C,aAAa"}
package/lib/build.js CHANGED
@@ -1,9 +1,9 @@
1
+ import fs from 'node:fs/promises'
1
2
  import path from 'node:path'
2
- import { createBuilder } from 'vite'
3
3
  import { fileURLToPath, pathToFileURL } from 'node:url'
4
+ import { createBuilder } from 'vite'
4
5
  import { emptyDir, ensureDir, exists } from './fs.js'
5
- import fs from 'fs/promises'
6
- import { createOrgaBuildConfig, alias } from './plugin.js'
6
+ import { alias, createOrgaBuildConfig } from './plugin.js'
7
7
  import { escapeHtml } from './util.js'
8
8
  import { appEntryId } from './vite.js'
9
9
 
@@ -17,13 +17,17 @@ const defaultIndexHtml = fileURLToPath(new URL('./index.html', import.meta.url))
17
17
  * @param {import('./config.js').Config} config
18
18
  * @param {string} [projectRoot]
19
19
  */
20
- export async function build({
21
- outDir,
22
- root,
23
- containerClass,
24
- styles = [],
25
- vitePlugins = []
26
- }, projectRoot = process.cwd()) {
20
+ export async function build(
21
+ {
22
+ outDir,
23
+ root,
24
+ containerClass,
25
+ styles = [],
26
+ rehypePlugins = [],
27
+ vitePlugins = []
28
+ },
29
+ projectRoot = process.cwd()
30
+ ) {
27
31
  await emptyDir(outDir)
28
32
  const ssrOutDir = path.join(outDir, '.ssr')
29
33
  const clientOutDir = outDir
@@ -33,6 +37,7 @@ export async function build({
33
37
  outDir,
34
38
  containerClass,
35
39
  styles,
40
+ rehypePlugins,
36
41
  vitePlugins
37
42
  })
38
43
 
@@ -105,7 +110,9 @@ export async function build({
105
110
  /* --- get html template, inject entry js and css --- */
106
111
  // Check for user's index.html in project root, otherwise use default
107
112
  const userIndexPath = path.join(projectRoot, 'index.html')
108
- const indexHtmlPath = (await exists(userIndexPath)) ? userIndexPath : defaultIndexHtml
113
+ const indexHtmlPath = (await exists(userIndexPath))
114
+ ? userIndexPath
115
+ : defaultIndexHtml
109
116
  const template = await fs.readFile(indexHtmlPath, { encoding: 'utf-8' })
110
117
  /* --- for each page path, render html using render function from ssr bundle, and inject the right css --- */
111
118
  const pagePaths = Object.keys(pages)
@@ -144,7 +151,10 @@ export async function build({
144
151
  `
145
152
  )
146
153
  const css = cssChunks
147
- .map((/** @type {any} */ c) => `<link rel="stylesheet" href="/${c.fileName}">`)
154
+ .map(
155
+ (/** @type {any} */ c) =>
156
+ `<link rel="stylesheet" href="/${c.fileName}">`
157
+ )
148
158
  .join('\n')
149
159
  html = html.replace(
150
160
  '<script type="module" src="/@orga-build/main.js"></script>',
@@ -153,7 +163,7 @@ export async function build({
153
163
 
154
164
  html = html.replace('</head>', `${css}</head>`)
155
165
 
156
- const page = pages[pagePath]
166
+ const page = pages[pagePath]
157
167
  if (page) {
158
168
  html = html.replace(/%orga\.(\w+)%/g, (_, key) => {
159
169
  const value = page[key] ?? ''
package/lib/config.d.ts CHANGED
@@ -20,5 +20,9 @@ export type Config = {
20
20
  * - Global stylesheet URLs injected in dev SSR and imported by client entry
21
21
  */
22
22
  styles?: string[];
23
+ /**
24
+ * - Extra rehype plugins appended to orga-build defaults
25
+ */
26
+ rehypePlugins?: import("unified").PluggableList;
23
27
  };
24
28
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.js"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,qCAHW,MAAM,EAAE,GACN,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA6C5D;;YAnEa,MAAM;UACN,MAAM;cACN,MAAM,EAAE;eACR,MAAM,EAAE;;;;iBACR,OAAO,MAAM,EAAE,YAAY,EAAE;oBAC7B,MAAM,EAAE,GAAC,MAAM;;;;aACf,MAAM,EAAE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.js"],"names":[],"mappings":"AA2BA;;;GAGG;AACH,qCAHW,MAAM,EAAE,GACN,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA+C5D;;YAvEa,MAAM;UACN,MAAM;cACN,MAAM,EAAE;eACR,MAAM,EAAE;;;;iBACR,OAAO,MAAM,EAAE,YAAY,EAAE;oBAC7B,MAAM,EAAE,GAAC,MAAM;;;;aACf,MAAM,EAAE;;;;oBACR,OAAO,SAAS,EAAE,aAAa"}
package/lib/config.js CHANGED
@@ -10,6 +10,7 @@ import path from 'node:path'
10
10
  * @property {import('vite').PluginOption[]} vitePlugins - Array of Vite plugins
11
11
  * @property {string[]|string} containerClass
12
12
  * @property {string[]} [styles] - Global stylesheet URLs injected in dev SSR and imported by client entry
13
+ * @property {import('unified').PluggableList} [rehypePlugins] - Extra rehype plugins appended to orga-build defaults
13
14
  */
14
15
 
15
16
  /** @type {Config} */
@@ -20,7 +21,8 @@ const defaultConfig = {
20
21
  postBuild: [],
21
22
  vitePlugins: [],
22
23
  containerClass: [],
23
- styles: []
24
+ styles: [],
25
+ rehypePlugins: []
24
26
  }
25
27
 
26
28
  /**
@@ -65,7 +67,9 @@ export async function loadConfig(...files) {
65
67
  result.root = resolveConfigPath(result.root)
66
68
  result.outDir = resolveConfigPath(result.outDir)
67
69
  const styles = result.styles
68
- result.styles = Array.isArray(styles) ? styles.filter((v) => typeof v === 'string') : []
70
+ result.styles = Array.isArray(styles)
71
+ ? styles.filter((v) => typeof v === 'string')
72
+ : []
69
73
  return {
70
74
  config: result,
71
75
  projectRoot: configPath ? path.dirname(configPath) : cwd
package/lib/csr.jsx CHANGED
@@ -1,7 +1,6 @@
1
- import React from 'react'
2
1
  import { createRoot } from 'react-dom/client'
3
- import { App } from './app.jsx'
4
2
  import { Router } from 'wouter'
3
+ import { App } from './app.jsx'
5
4
 
6
5
  const container = document.getElementById('root')
7
6
  const root = createRoot(container)
package/lib/files.js CHANGED
@@ -1,6 +1,6 @@
1
- import { globby } from 'globby'
2
- import path from 'node:path'
3
1
  import { readFile } from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import { globby } from 'globby'
4
4
  import { getSettings } from 'orga'
5
5
 
6
6
  /**
@@ -64,7 +64,7 @@ function getContentPath(slug) {
64
64
  */
65
65
  function getContentId(slug) {
66
66
  // Remove leading and trailing slashes
67
- let normalized = slug.replace(/^\/+/, '').replace(/\/+$/, '')
67
+ const normalized = slug.replace(/^\/+/, '').replace(/\/+$/, '')
68
68
 
69
69
  // If root page, return 'index'
70
70
  if (!normalized) {
package/lib/fs.js CHANGED
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises'
1
+ import fs from 'node:fs/promises'
2
2
  import path from 'node:path'
3
3
 
4
4
  /**
package/lib/orga.d.ts CHANGED
@@ -2,9 +2,11 @@
2
2
  * @param {Object} options
3
3
  * @param {string|string[]} options.containerClass - CSS class name(s) to wrap the rendered content
4
4
  * @param {string} options.root - Root directory for content files
5
+ * @param {import('unified').PluggableList} [options.rehypePlugins] - Extra rehype plugins appended to defaults
5
6
  */
6
- export function setupOrga({ containerClass, root }: {
7
+ export function setupOrga({ containerClass, root, rehypePlugins }: {
7
8
  containerClass: string | string[];
8
9
  root: string;
10
+ rehypePlugins?: import("unified").PluggableList | undefined;
9
11
  }): import("@orgajs/rollup").Plugin;
10
12
  //# sourceMappingURL=orga.d.ts.map
package/lib/orga.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"orga.d.ts","sourceRoot":"","sources":["orga.js"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,oDAHG;IAAiC,cAAc,EAAvC,MAAM,GAAC,MAAM,EAAE;IACC,IAAI,EAApB,MAAM;CAChB,mCAYA"}
1
+ {"version":3,"file":"orga.d.ts","sourceRoot":"","sources":["orga.js"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,mEAJG;IAAiC,cAAc,EAAvC,MAAM,GAAC,MAAM,EAAE;IACC,IAAI,EAApB,MAAM;IACoC,aAAa;CACjE,mCAaA"}
package/lib/orga.js CHANGED
@@ -10,13 +10,15 @@ import { getSlugFromContentFilePath } from './files.js'
10
10
  * @param {Object} options
11
11
  * @param {string|string[]} options.containerClass - CSS class name(s) to wrap the rendered content
12
12
  * @param {string} options.root - Root directory for content files
13
+ * @param {import('unified').PluggableList} [options.rehypePlugins] - Extra rehype plugins appended to defaults
13
14
  */
14
- export function setupOrga({ containerClass, root }) {
15
+ export function setupOrga({ containerClass, root, rehypePlugins = [] }) {
15
16
  return _orga({
16
17
  rehypePlugins: [
17
18
  [rehypeWrap, { className: containerClass }],
18
19
  [rewriteOrgFileLinks, { root }],
19
- mediaAssets
20
+ mediaAssets,
21
+ ...rehypePlugins
20
22
  ],
21
23
  reorgRehypeOptions: {
22
24
  linkHref: (link) => link.path.value
@@ -39,7 +41,8 @@ function mediaAssets() {
39
41
  if (typeof src !== 'string') return
40
42
  if (src.startsWith('http')) return
41
43
  const tagName = node.tagName
42
- const name = (imports[src] ??= `asset_${genId()}`)
44
+ if (!imports[src]) imports[src] = `asset_${genId()}`
45
+ const name = imports[src]
43
46
  const attrs = Object.entries(rest)
44
47
  .filter(([, v]) => v !== undefined && v !== false)
45
48
  .map(([k, v]) => (v === true ? k : `${k}='${v}'`))
@@ -80,7 +83,7 @@ function rehypeWrap({ className = [] }) {
80
83
  properties: {
81
84
  className
82
85
  },
83
- // @ts-ignore
86
+ // @ts-expect-error
84
87
  children: tree.children
85
88
  }
86
89
  ]
@@ -131,7 +134,10 @@ function resolveOrgHrefToContentSlug({ root, filePath, href }) {
131
134
  : path.resolve(path.dirname(filePath), decodedHrefPath)
132
135
 
133
136
  const relativeTargetPath = path.relative(root, absoluteTargetPath)
134
- if (relativeTargetPath.startsWith('..') || path.isAbsolute(relativeTargetPath)) {
137
+ if (
138
+ relativeTargetPath.startsWith('..') ||
139
+ path.isAbsolute(relativeTargetPath)
140
+ ) {
135
141
  return null
136
142
  }
137
143
 
package/lib/plugin.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * @property {string | undefined} [outDir] - Output directory (excluded from file discovery)
5
5
  * @property {string|string[]} [containerClass] - CSS class(es) to wrap rendered content
6
6
  * @property {string[]} [styles] - Global stylesheet URLs to import/inject
7
+ * @property {import('unified').PluggableList} [rehypePlugins] - Extra rehype plugins appended to orga-build defaults
7
8
  */
8
9
  /**
9
10
  * Creates the canonical orga-build plugin preset.
@@ -12,7 +13,7 @@
12
13
  * @param {OrgaBuildPluginOptions} options
13
14
  * @returns {import('vite').PluginOption[]}
14
15
  */
15
- export function orgaBuildPlugin({ root, outDir, containerClass, styles }: OrgaBuildPluginOptions): import("vite").PluginOption[];
16
+ export function orgaBuildPlugin({ root, outDir, containerClass, styles, rehypePlugins }: OrgaBuildPluginOptions): import("vite").PluginOption[];
16
17
  /**
17
18
  * Creates the full Vite config options for orga-build.
18
19
  * Includes plugins, resolve aliases, and other shared config.
@@ -20,7 +21,7 @@ export function orgaBuildPlugin({ root, outDir, containerClass, styles }: OrgaBu
20
21
  * @param {OrgaBuildPluginOptions & { outDir?: string, vitePlugins?: import('vite').PluginOption[], includeFallbackHtml?: boolean, projectRoot?: string }} options
21
22
  * @returns {{ plugins: import('vite').PluginOption[], resolve: { alias: typeof alias } }}
22
23
  */
23
- export function createOrgaBuildConfig({ root, outDir, containerClass, styles, vitePlugins, includeFallbackHtml, projectRoot }: OrgaBuildPluginOptions & {
24
+ export function createOrgaBuildConfig({ root, outDir, containerClass, styles, rehypePlugins, vitePlugins, includeFallbackHtml, projectRoot }: OrgaBuildPluginOptions & {
24
25
  outDir?: string;
25
26
  vitePlugins?: import("vite").PluginOption[];
26
27
  includeFallbackHtml?: boolean;
@@ -71,5 +72,9 @@ export type OrgaBuildPluginOptions = {
71
72
  * - Global stylesheet URLs to import/inject
72
73
  */
73
74
  styles?: string[];
75
+ /**
76
+ * - Extra rehype plugins appended to orga-build defaults
77
+ */
78
+ rehypePlugins?: import("unified").PluggableList;
74
79
  };
75
80
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["plugin.js"],"names":[],"mappings":"AAuBA;;;;;;GAMG;AAEH;;;;;;GAMG;AACH,0EAHW,sBAAsB,GACpB,OAAO,MAAM,EAAE,YAAY,EAAE,CAazC;AAED;;;;;;GAMG;AACH,+HAHW,sBAAsB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5I;IAAE,OAAO,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,KAAK,CAAA;KAAE,CAAA;CAAE,CAwBxF;AAiBD;;;;;;;;;;;;;GAaG;AACH,gDAJW,MAAM,WACN,MAAM,EAAE,GACN,OAAO,MAAM,EAAE,MAAM,CAmFjC;AAlLD;;GAEG;AACH;;;;EAIC;;;;;UAIa,MAAM;;;;aACN,MAAM,GAAG,SAAS;;;;qBAClB,MAAM,GAAC,MAAM,EAAE;;;;aACf,MAAM,EAAE"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["plugin.js"],"names":[],"mappings":"AAuBA;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,yFAHW,sBAAsB,GACpB,OAAO,MAAM,EAAE,YAAY,EAAE,CAczC;AAED;;;;;;GAMG;AACH,8IAHW,sBAAsB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5I;IAAE,OAAO,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,KAAK,CAAA;KAAE,CAAA;CAAE,CAyBxF;AAiBD;;;;;;;;;;;;;GAaG;AACH,gDAJW,MAAM,WACN,MAAM,EAAE,GACN,OAAO,MAAM,EAAE,MAAM,CAmFjC;AArLD;;GAEG;AACH;;;;EAIC;;;;;UAIa,MAAM;;;;aACN,MAAM,GAAG,SAAS;;;;qBAClB,MAAM,GAAC,MAAM,EAAE;;;;aACf,MAAM,EAAE;;;;oBACR,OAAO,SAAS,EAAE,aAAa"}
package/lib/plugin.js CHANGED
@@ -1,12 +1,12 @@
1
- import path from 'node:path'
2
1
  import fs from 'node:fs/promises'
3
2
  import { createRequire } from 'node:module'
3
+ import path from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
- import { createServerModuleRunner } from 'vite'
6
5
  import react from '@vitejs/plugin-react'
6
+ import { createServerModuleRunner } from 'vite'
7
7
  import { setupOrga } from './orga.js'
8
- import { pluginFactory } from './vite.js'
9
8
  import { escapeHtml } from './util.js'
9
+ import { pluginFactory } from './vite.js'
10
10
 
11
11
  const ssrEntry = fileURLToPath(new URL('./ssr.jsx', import.meta.url))
12
12
 
@@ -27,6 +27,7 @@ export const alias = {
27
27
  * @property {string | undefined} [outDir] - Output directory (excluded from file discovery)
28
28
  * @property {string|string[]} [containerClass] - CSS class(es) to wrap rendered content
29
29
  * @property {string[]} [styles] - Global stylesheet URLs to import/inject
30
+ * @property {import('unified').PluggableList} [rehypePlugins] - Extra rehype plugins appended to orga-build defaults
30
31
  */
31
32
 
32
33
  /**
@@ -40,10 +41,11 @@ export function orgaBuildPlugin({
40
41
  root,
41
42
  outDir,
42
43
  containerClass = [],
43
- styles = []
44
+ styles = [],
45
+ rehypePlugins = []
44
46
  }) {
45
47
  return [
46
- setupOrga({ containerClass, root }),
48
+ setupOrga({ containerClass, root, rehypePlugins }),
47
49
  react(),
48
50
  pluginFactory({ dir: root, outDir, styles })
49
51
  ]
@@ -61,13 +63,14 @@ export function createOrgaBuildConfig({
61
63
  outDir,
62
64
  containerClass = [],
63
65
  styles = [],
66
+ rehypePlugins = [],
64
67
  vitePlugins = [],
65
68
  includeFallbackHtml = false,
66
69
  projectRoot = process.cwd()
67
70
  }) {
68
71
  const plugins = [
69
72
  ...vitePlugins,
70
- ...orgaBuildPlugin({ root, outDir, containerClass, styles })
73
+ ...orgaBuildPlugin({ root, outDir, containerClass, styles, rehypePlugins })
71
74
  ]
72
75
  if (includeFallbackHtml) {
73
76
  // HTML fallback must be first so it can handle HTML navigation requests
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["serve.js"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,8BAJW,OAAO,aAAa,EAAE,MAAM,SAC5B,MAAM,gBACN,MAAM,iBAsChB"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["serve.js"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,8BAJW,OAAO,aAAa,EAAE,MAAM,SAC5B,MAAM,gBACN,MAAM,iBAuChB"}
package/lib/serve.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path'
2
2
  import { createServer } from 'vite'
3
- import { createOrgaBuildConfig, alias } from './plugin.js'
3
+ import { alias, createOrgaBuildConfig } from './plugin.js'
4
4
 
5
5
  /**
6
6
  * Start the development server using native Vite.
@@ -15,6 +15,7 @@ export async function serve(config, port = 3000, projectRoot = process.cwd()) {
15
15
  outDir: config.outDir,
16
16
  containerClass: config.containerClass,
17
17
  styles: config.styles ?? [],
18
+ rehypePlugins: config.rehypePlugins ?? [],
18
19
  vitePlugins: config.vitePlugins,
19
20
  includeFallbackHtml: true,
20
21
  projectRoot
@@ -38,7 +39,7 @@ export async function serve(config, port = 3000, projectRoot = process.cwd()) {
38
39
  port,
39
40
  strictPort: false,
40
41
  watch: {
41
- ignored: [path.resolve(config.outDir) + '/**']
42
+ ignored: [`${path.resolve(config.outDir)}/**`]
42
43
  }
43
44
  }
44
45
  })
package/lib/ssr.jsx CHANGED
@@ -1,7 +1,7 @@
1
- import pages from '/@orga-build/pages'
2
1
  import { renderToString } from 'react-dom/server'
3
- import { App } from './app.jsx'
4
2
  import { Router } from 'wouter'
3
+ import pages from '/@orga-build/pages'
4
+ import { App } from './app.jsx'
5
5
 
6
6
  export { pages }
7
7
 
package/lib/vite.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["vite.js"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,uDALG;IAAwB,GAAG,EAAnB,MAAM;IACW,MAAM;IACJ,MAAM;CACjC,GAAU,OAAO,MAAM,EAAE,MAAM,CA8JjC;AAvKD,gDAAuD"}
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["vite.js"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,uDALG;IAAwB,GAAG,EAAnB,MAAM;IACW,MAAM;IACJ,MAAM;CACjC,GAAU,OAAO,MAAM,EAAE,MAAM,CAoJjC;AA7JD,gDAAuD"}
package/lib/vite.js CHANGED
@@ -1,11 +1,11 @@
1
- import { setup } from './files.js'
2
1
  import path from 'node:path'
2
+ import { setup } from './files.js'
3
3
 
4
4
  const magicModulePrefix = '/@orga-build/'
5
- const pagesModuleId = magicModulePrefix + 'pages'
5
+ const pagesModuleId = `${magicModulePrefix}pages`
6
6
  export const appEntryId = `${magicModulePrefix}main.js`
7
7
  const contentModuleId = 'orga-build:content'
8
- const contentModuleIdResolved = '\0' + contentModuleId
8
+ const contentModuleIdResolved = `\0${contentModuleId}`
9
9
 
10
10
  /**
11
11
  * @param {Object} options
@@ -20,21 +20,11 @@ export function pluginFactory({ dir, outDir, styles = [] }) {
20
20
  return {
21
21
  name: 'vite-plugin-orga-pages',
22
22
  enforce: 'pre',
23
- config: (config, env) => ({
23
+ config: (_config, _env) => ({
24
24
  future: {
25
25
  removePluginHookSsrArgument: 'warn',
26
26
  removePluginHookHandleHotUpdate: 'warn',
27
27
  removeSsrLoadModule: 'warn'
28
- },
29
- optimizeDeps: {
30
- include: [
31
- 'react',
32
- 'react/jsx-runtime',
33
- 'react-dom',
34
- 'react-dom/client',
35
- 'wouter'
36
- ],
37
- exclude: ['orga-build']
38
28
  }
39
29
  }),
40
30
 
@@ -50,7 +40,7 @@ export function pluginFactory({ dir, outDir, styles = [] }) {
50
40
  }
51
41
  },
52
42
 
53
- async resolveId(id, importer) {
43
+ async resolveId(id, _importer) {
54
44
  if (id === appEntryId) {
55
45
  return appEntryId
56
46
  }
@@ -75,7 +65,7 @@ export function pluginFactory({ dir, outDir, styles = [] }) {
75
65
  return await renderPageList()
76
66
  }
77
67
  if (id.startsWith(pagesModuleId)) {
78
- let pageId = id.replace(pagesModuleId, '')
68
+ const pageId = id.replace(pagesModuleId, '')
79
69
  const page = await files.page(pageId)
80
70
  if (page) {
81
71
  return `
@@ -111,7 +101,7 @@ export default layouts;
111
101
  const pages = await files.pages()
112
102
  /** @type {string[]} */ const _imports = []
113
103
  /** @type {string[]} */ const _pages = []
114
- Object.entries(pages).forEach(([pageId, value], i) => {
104
+ Object.entries(pages).forEach(([pageId, _value], i) => {
115
105
  const dataModulePath = path.join(magicModulePrefix, 'pages', pageId)
116
106
  _imports.push(`import * as page${i} from '${dataModulePath}'`)
117
107
  _pages.push(`pages['${pageId}'] = page${i}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orga-build",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "A simple tool that builds org-mode files into a website",
5
5
  "type": "module",
6
6
  "engines": {
@@ -48,17 +48,18 @@
48
48
  "react": "^19.0.0",
49
49
  "react-dom": "^19.0.0",
50
50
  "rehype-katex": "^7.0.1",
51
+ "unified": "^11.0.5",
51
52
  "unist-util-visit-parents": "^6.0.1",
52
53
  "vite": "^7.3.1",
53
54
  "wouter": "^3.7.0",
54
- "@orgajs/rollup": "1.3.3"
55
+ "@orgajs/rollup": "1.3.4"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@types/hast": "^3.0.4",
58
- "@types/node": "^22.13.1",
59
+ "@types/node": "^25.3.2",
59
60
  "@types/react": "^19.0.8",
60
61
  "@types/react-dom": "^19.0.3",
61
- "orga": "4.6.0"
62
+ "orga": "4.7.1"
62
63
  },
63
64
  "scripts": {
64
65
  "clean": "fd . -e d.ts -e d.ts.map -I -x rm {}",