orga-build 0.5.4 → 0.6.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
@@ -78,6 +78,10 @@ export default {
78
78
  // CSS class(es) to wrap rendered org content
79
79
  containerClass: ['prose', 'prose-lg'],
80
80
 
81
+ // Global stylesheet URLs (explicit, no magic files)
82
+ // These are injected in dev SSR <head> and imported by the client entry.
83
+ styles: ['/style.css'],
84
+
81
85
  // Additional Vite plugins
82
86
  vitePlugins: []
83
87
  }
@@ -90,6 +94,7 @@ export default {
90
94
  | =root= | =string= | ='pages'= | Directory containing content files |
91
95
  | =outDir= | =string= | ='out'= | Output directory for production build |
92
96
  | =containerClass= | =string \vert string[]= | =[]= | CSS class(es) for content wrapper |
97
+ | =styles= | =string[]= | =[]= | Global stylesheet URLs injected/imported explicitly |
93
98
  | =vitePlugins= | =PluginOption[]= | =[]= | Additional Vite plugins |
94
99
 
95
100
  * TypeScript Setup
package/lib/build.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @param {import('./config.js').Config} config
3
3
  */
4
- export function build({ outDir, root, containerClass, vitePlugins }: import("./config.js").Config): Promise<void>;
4
+ export function build({ outDir, root, containerClass, styles, vitePlugins }: import("./config.js").Config): Promise<void>;
5
5
  export { alias };
6
6
  import { alias } from './plugin.js';
7
7
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["build.js"],"names":[],"mappings":"AAcA;;GAEG;AACH,qEAFW,OAAO,aAAa,EAAE,MAAM,iBAmJtC;;sBA7J4C,aAAa"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["build.js"],"names":[],"mappings":"AAeA;;GAEG;AACH,6EAFW,OAAO,aAAa,EAAE,MAAM,iBAqJtC;;sBAhK4C,aAAa"}
package/lib/build.js CHANGED
@@ -4,6 +4,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
4
4
  import { emptyDir, ensureDir, exists } from './fs.js'
5
5
  import fs from 'fs/promises'
6
6
  import { createOrgaBuildConfig, alias } from './plugin.js'
7
+ import { escapeHtml } from './util.js'
7
8
 
8
9
  // Re-export alias for backwards compatibility
9
10
  export { alias }
@@ -19,6 +20,7 @@ export async function build({
19
20
  outDir,
20
21
  root,
21
22
  containerClass,
23
+ styles = [],
22
24
  vitePlugins = []
23
25
  }) {
24
26
  await emptyDir(outDir)
@@ -29,6 +31,7 @@ export async function build({
29
31
  root,
30
32
  outDir,
31
33
  containerClass,
34
+ styles,
32
35
  vitePlugins
33
36
  })
34
37
 
@@ -150,12 +153,12 @@ export async function build({
150
153
 
151
154
  html = html.replace('</head>', `${css}</head>`)
152
155
 
153
- const page = pages[pagePath]
154
- if (page && page.title) {
155
- html = html.replace(
156
- /<title>(.*?)<\/title>/,
157
- `<title>${page.title}</title>`
158
- )
156
+ const page = pages[pagePath]
157
+ if (page) {
158
+ html = html.replace(/%orga\.(\w+)%/g, (_, key) => {
159
+ const value = page[key] ?? ''
160
+ return escapeHtml(String(value))
161
+ })
159
162
  }
160
163
 
161
164
  return html
package/lib/config.d.ts CHANGED
@@ -13,5 +13,9 @@ export type Config = {
13
13
  */
14
14
  vitePlugins: import("vite").PluginOption[];
15
15
  containerClass: string[] | string;
16
+ /**
17
+ * - Global stylesheet URLs injected in dev SSR and imported by client entry
18
+ */
19
+ styles?: string[];
16
20
  };
17
21
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.js"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,qCAHW,MAAM,EAAE,GACN,OAAO,CAAC,MAAM,CAAC,CAsC3B;;YA1Da,MAAM;UACN,MAAM;cACN,MAAM,EAAE;eACR,MAAM,EAAE;;;;iBACR,OAAO,MAAM,EAAE,YAAY,EAAE;oBAC7B,MAAM,EAAE,GAAC,MAAM"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.js"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,qCAHW,MAAM,EAAE,GACN,OAAO,CAAC,MAAM,CAAC,CAwC3B;;YA9Da,MAAM;UACN,MAAM;cACN,MAAM,EAAE;eACR,MAAM,EAAE;;;;iBACR,OAAO,MAAM,EAAE,YAAY,EAAE;oBAC7B,MAAM,EAAE,GAAC,MAAM;;;;aACf,MAAM,EAAE"}
package/lib/config.js CHANGED
@@ -9,6 +9,7 @@ import path from 'node:path'
9
9
  * @property {string[]} postBuild
10
10
  * @property {import('vite').PluginOption[]} vitePlugins - Array of Vite plugins
11
11
  * @property {string[]|string} containerClass
12
+ * @property {string[]} [styles] - Global stylesheet URLs injected in dev SSR and imported by client entry
12
13
  */
13
14
 
14
15
  /** @type {Config} */
@@ -18,7 +19,8 @@ const defaultConfig = {
18
19
  preBuild: [],
19
20
  postBuild: [],
20
21
  vitePlugins: [],
21
- containerClass: []
22
+ containerClass: [],
23
+ styles: []
22
24
  }
23
25
 
24
26
  /**
@@ -60,5 +62,7 @@ export async function loadConfig(...files) {
60
62
 
61
63
  result.root = resolveConfigPath(result.root)
62
64
  result.outDir = resolveConfigPath(result.outDir)
65
+ const styles = result.styles
66
+ result.styles = Array.isArray(styles) ? styles.filter((v) => typeof v === 'string') : []
63
67
  return result
64
68
  }
package/lib/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8"/>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
- <title>📘Orga Pages</title>
6
+ <title>%orga.title%</title>
7
7
  </head>
8
8
  <body>
9
9
  <div id="root"></div>
package/lib/plugin.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * @property {string} root - Root directory for content files
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
+ * @property {string[]} [styles] - Global stylesheet URLs to import/inject
6
7
  */
7
8
  /**
8
9
  * Creates the canonical orga-build plugin preset.
@@ -11,7 +12,7 @@
11
12
  * @param {OrgaBuildPluginOptions} options
12
13
  * @returns {import('vite').PluginOption[]}
13
14
  */
14
- export function orgaBuildPlugin({ root, outDir, containerClass }: OrgaBuildPluginOptions): import("vite").PluginOption[];
15
+ export function orgaBuildPlugin({ root, outDir, containerClass, styles }: OrgaBuildPluginOptions): import("vite").PluginOption[];
15
16
  /**
16
17
  * Creates the full Vite config options for orga-build.
17
18
  * Includes plugins, resolve aliases, and other shared config.
@@ -19,7 +20,7 @@ export function orgaBuildPlugin({ root, outDir, containerClass }: OrgaBuildPlugi
19
20
  * @param {OrgaBuildPluginOptions & { outDir?: string, vitePlugins?: import('vite').PluginOption[], includeFallbackHtml?: boolean, projectRoot?: string }} options
20
21
  * @returns {{ plugins: import('vite').PluginOption[], resolve: { alias: typeof alias } }}
21
22
  */
22
- export function createOrgaBuildConfig({ root, outDir, containerClass, vitePlugins, includeFallbackHtml, projectRoot }: OrgaBuildPluginOptions & {
23
+ export function createOrgaBuildConfig({ root, outDir, containerClass, styles, vitePlugins, includeFallbackHtml, projectRoot }: OrgaBuildPluginOptions & {
23
24
  outDir?: string;
24
25
  vitePlugins?: import("vite").PluginOption[];
25
26
  includeFallbackHtml?: boolean;
@@ -33,17 +34,18 @@ export function createOrgaBuildConfig({ root, outDir, containerClass, vitePlugin
33
34
  /**
34
35
  * Creates an HTML serving plugin that handles index.html for dev mode.
35
36
  *
36
- * This plugin:
37
- * - Serves user's index.html from project root if present, otherwise uses the default template
37
+ * This plugin performs per-request SSR in dev mode (matching Astro/SvelteKit behaviour):
38
+ * - SSR-renders each page on every request using Vite's server module runner
39
+ * - Injects rendered content and page metadata (%orga.*% placeholders) into the template
40
+ * - Falls back to the shell HTML for unknown routes (client-side router handles 404)
38
41
  * - Only handles GET/HEAD requests that accept HTML
39
- * - Runs late (post middleware) so other plugins get first chance
40
- * - Passes HTML through transformIndexHtml for ecosystem compatibility
41
42
  * - Does not intercept asset requests
42
43
  *
43
44
  * @param {string} projectRoot - Project root directory (where orga.config.js lives)
45
+ * @param {string[]} [styles]
44
46
  * @returns {import('vite').Plugin}
45
47
  */
46
- export function htmlFallbackPlugin(projectRoot: string): import("vite").Plugin;
48
+ export function htmlFallbackPlugin(projectRoot: string, styles?: string[]): import("vite").Plugin;
47
49
  /**
48
50
  * Alias map for React and wouter to ensure consistent resolution
49
51
  */
@@ -65,5 +67,9 @@ export type OrgaBuildPluginOptions = {
65
67
  * - CSS class(es) to wrap rendered content
66
68
  */
67
69
  containerClass?: string | string[];
70
+ /**
71
+ * - Global stylesheet URLs to import/inject
72
+ */
73
+ styles?: string[];
68
74
  };
69
75
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["plugin.js"],"names":[],"mappings":"AAoBA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,kEAHW,sBAAsB,GACpB,OAAO,MAAM,EAAE,YAAY,EAAE,CAQzC;AAED;;;;;;GAMG;AACH,uHAHW,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,CAoBxF;AAiBD;;;;;;;;;;;;GAYG;AACH,gDAHW,MAAM,GACJ,OAAO,MAAM,EAAE,MAAM,CA8CjC;AAlID;;GAEG;AACH;;;;EAIC;;;;;UAIa,MAAM;;;;aACN,MAAM,GAAG,SAAS;;;;qBAClB,MAAM,GAAC,MAAM,EAAE"}
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"}
package/lib/plugin.js CHANGED
@@ -2,13 +2,16 @@ import path from 'node:path'
2
2
  import fs from 'node:fs/promises'
3
3
  import { createRequire } from 'node:module'
4
4
  import { fileURLToPath } from 'node:url'
5
+ import { createServerModuleRunner } from 'vite'
5
6
  import react from '@vitejs/plugin-react'
6
7
  import { setupOrga } from './orga.js'
7
8
  import { pluginFactory } from './vite.js'
9
+ import { escapeHtml } from './util.js'
10
+
11
+ const ssrEntry = fileURLToPath(new URL('./ssr.jsx', import.meta.url))
8
12
 
9
13
  const require = createRequire(import.meta.url)
10
14
  const defaultIndexHtml = fileURLToPath(new URL('./index.html', import.meta.url))
11
-
12
15
  /**
13
16
  * Alias map for React and wouter to ensure consistent resolution
14
17
  */
@@ -23,6 +26,7 @@ export const alias = {
23
26
  * @property {string} root - Root directory for content files
24
27
  * @property {string | undefined} [outDir] - Output directory (excluded from file discovery)
25
28
  * @property {string|string[]} [containerClass] - CSS class(es) to wrap rendered content
29
+ * @property {string[]} [styles] - Global stylesheet URLs to import/inject
26
30
  */
27
31
 
28
32
  /**
@@ -32,11 +36,16 @@ export const alias = {
32
36
  * @param {OrgaBuildPluginOptions} options
33
37
  * @returns {import('vite').PluginOption[]}
34
38
  */
35
- export function orgaBuildPlugin({ root, outDir, containerClass = [] }) {
39
+ export function orgaBuildPlugin({
40
+ root,
41
+ outDir,
42
+ containerClass = [],
43
+ styles = []
44
+ }) {
36
45
  return [
37
46
  setupOrga({ containerClass, root }),
38
47
  react(),
39
- pluginFactory({ dir: root, outDir })
48
+ pluginFactory({ dir: root, outDir, styles })
40
49
  ]
41
50
  }
42
51
 
@@ -51,15 +60,19 @@ export function createOrgaBuildConfig({
51
60
  root,
52
61
  outDir,
53
62
  containerClass = [],
63
+ styles = [],
54
64
  vitePlugins = [],
55
65
  includeFallbackHtml = false,
56
66
  projectRoot = process.cwd()
57
67
  }) {
58
- const plugins = [...vitePlugins, ...orgaBuildPlugin({ root, outDir, containerClass })]
68
+ const plugins = [
69
+ ...vitePlugins,
70
+ ...orgaBuildPlugin({ root, outDir, containerClass, styles })
71
+ ]
59
72
  if (includeFallbackHtml) {
60
73
  // HTML fallback must be first so it can handle HTML navigation requests
61
74
  // before runtime plugins (e.g. Cloudflare) potentially return 404.
62
- plugins.unshift(htmlFallbackPlugin(projectRoot))
75
+ plugins.unshift(htmlFallbackPlugin(projectRoot, styles))
63
76
  }
64
77
  return {
65
78
  plugins,
@@ -85,17 +98,18 @@ async function hasUserIndexHtml(root) {
85
98
  /**
86
99
  * Creates an HTML serving plugin that handles index.html for dev mode.
87
100
  *
88
- * This plugin:
89
- * - Serves user's index.html from project root if present, otherwise uses the default template
101
+ * This plugin performs per-request SSR in dev mode (matching Astro/SvelteKit behaviour):
102
+ * - SSR-renders each page on every request using Vite's server module runner
103
+ * - Injects rendered content and page metadata (%orga.*% placeholders) into the template
104
+ * - Falls back to the shell HTML for unknown routes (client-side router handles 404)
90
105
  * - Only handles GET/HEAD requests that accept HTML
91
- * - Runs late (post middleware) so other plugins get first chance
92
- * - Passes HTML through transformIndexHtml for ecosystem compatibility
93
106
  * - Does not intercept asset requests
94
107
  *
95
108
  * @param {string} projectRoot - Project root directory (where orga.config.js lives)
109
+ * @param {string[]} [styles]
96
110
  * @returns {import('vite').Plugin}
97
111
  */
98
- export function htmlFallbackPlugin(projectRoot) {
112
+ export function htmlFallbackPlugin(projectRoot, styles = []) {
99
113
  return {
100
114
  name: 'orga-build:html-fallback',
101
115
 
@@ -106,7 +120,11 @@ export function htmlFallbackPlugin(projectRoot) {
106
120
  const userHasIndex = await hasUserIndexHtml(projectRoot)
107
121
  const indexHtmlPath = userHasIndex ? userIndexPath : defaultIndexHtml
108
122
 
109
- // Add middleware to serve HTML early in the chain.
123
+ // CJS compatibility here depends on Vite externalizing bare-specifier deps
124
+ // (e.g. react/*) to native Node import(). If aliases rewrite specifiers
125
+ // to absolute paths, modules can be inlined and evaluated without CJS globals.
126
+ const runner = createServerModuleRunner(server.environments.ssr)
127
+
110
128
  server.middlewares.use(async (req, res, next) => {
111
129
  // Only handle GET/HEAD requests
112
130
  if (req.method !== 'GET' && req.method !== 'HEAD') {
@@ -128,8 +146,41 @@ export function htmlFallbackPlugin(projectRoot) {
128
146
  }
129
147
 
130
148
  try {
149
+ // Import via the runner on each request — the module graph handles
150
+ // HMR invalidation so stale modules are never served.
151
+ const { render, pages } = await runner.import(ssrEntry)
152
+ const content = render(pathname)
153
+
131
154
  let html = await fs.readFile(indexHtmlPath, 'utf-8')
132
155
  html = await server.transformIndexHtml(url, html)
156
+
157
+ const uniqueCssUrls = [...new Set(styles)]
158
+ if (uniqueCssUrls.length > 0) {
159
+ const cssLinks = uniqueCssUrls
160
+ .map((u) => `<link rel="stylesheet" href="${escapeHtml(u)}">`)
161
+ .join('')
162
+ html = html.replace('</head>', `${cssLinks}</head>`)
163
+ }
164
+
165
+ if (content) {
166
+ const ssr = { routePath: pathname }
167
+ html = html.replace(
168
+ '<div id="root"></div>',
169
+ `<script>window._ssr=${JSON.stringify(ssr)};</script><div id="root">${content}</div>`
170
+ )
171
+ }
172
+
173
+ // Replace %orga.*% placeholders with page metadata
174
+ const page = pages[pathname]
175
+ if (page) {
176
+ html = html.replace(/%orga\.(\w+)%/g, (_, key) => {
177
+ const value = page[key] ?? ''
178
+ return escapeHtml(String(value))
179
+ })
180
+ }
181
+ // Strip any remaining unresolved placeholders (unknown route)
182
+ html = html.replace(/%orga\.\w+%/g, '')
183
+
133
184
  res.statusCode = 200
134
185
  res.setHeader('Content-Type', 'text/html')
135
186
  res.end(html)
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["serve.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,8BAHW,OAAO,aAAa,EAAE,MAAM,SAC5B,MAAM,iBA2BhB"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["serve.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,8BAHW,OAAO,aAAa,EAAE,MAAM,SAC5B,MAAM,iBAsChB"}
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 } from './plugin.js'
3
+ import { createOrgaBuildConfig, alias } from './plugin.js'
4
4
 
5
5
  /**
6
6
  * Start the development server using native Vite.
@@ -9,19 +9,30 @@ import { createOrgaBuildConfig } from './plugin.js'
9
9
  * @param {number} [port]
10
10
  */
11
11
  export async function serve(config, port = 3000) {
12
- const { plugins, resolve } = createOrgaBuildConfig({
12
+ const { plugins } = createOrgaBuildConfig({
13
13
  root: config.root,
14
14
  outDir: config.outDir,
15
15
  containerClass: config.containerClass,
16
+ styles: config.styles ?? [],
16
17
  vitePlugins: config.vitePlugins,
17
- includeFallbackHtml: true
18
+ includeFallbackHtml: true,
19
+ projectRoot: config.root
18
20
  })
19
21
 
20
22
  const server = await createServer({
21
23
  root: config.root,
22
24
  plugins,
23
- resolve,
24
25
  appType: 'custom',
26
+ // Aliases are scoped to the client environment only.
27
+ // The SSR environment must NOT have these aliases: they convert bare specifiers
28
+ // (e.g. 'react') into absolute paths, which bypasses Vite's fetchModule
29
+ // externalization branch and causes CJS packages to be evaluated inline by
30
+ // ESModulesEvaluator (which has no 'module'/'require' globals).
31
+ environments: {
32
+ client: {
33
+ resolve: /** @type {any} */ ({ alias })
34
+ }
35
+ },
25
36
  server: {
26
37
  port,
27
38
  strictPort: false,
package/lib/util.d.ts CHANGED
@@ -16,6 +16,11 @@ export function DefaultLayout({ title, children }: {
16
16
  title: string | undefined;
17
17
  children: import("react").ReactNode;
18
18
  }): React.JSX.Element;
19
+ /**
20
+ * @param {string} str
21
+ * @returns {string}
22
+ */
23
+ export function escapeHtml(str: string): string;
19
24
  /**
20
25
  * @param {string} cmd
21
26
  */
package/lib/util.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["util.js"],"names":[],"mappings":"AAGA,iCAA6B;AAE7B;;;;GAIG;AACH,4BAJW,MAAM,eACN,CAAG,MAAM,GAAC,MAAM,GAAA,GACd,OAAO,CASnB;AAED;;;;;;GAMG;AACH,mDAJG;IAAgC,KAAK,EAA7B,MAAM,GAAC,SAAS;IACiB,QAAQ,EAAzC,OAAO,OAAO,EAAE,SAAS;CACjC,GAAU,KAAK,CAAC,GAAG,CAAC,OAAO,CAkB7B;AAED;;GAEG;AACH,uBAFW,MAAM,gBAehB"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["util.js"],"names":[],"mappings":"AAGA,iCAA6B;AAE7B;;;;GAIG;AACH,4BAJW,MAAM,eACN,CAAG,MAAM,GAAC,MAAM,GAAA,GACd,OAAO,CASnB;AAED;;;;;;GAMG;AACH,mDAJG;IAAgC,KAAK,EAA7B,MAAM,GAAC,SAAS;IACiB,QAAQ,EAAzC,OAAO,OAAO,EAAE,SAAS;CACjC,GAAU,KAAK,CAAC,GAAG,CAAC,OAAO,CAkB7B;AAED;;;GAGG;AACH,gCAHW,MAAM,GACJ,MAAM,CAQlB;AAED;;GAEG;AACH,uBAFW,MAAM,gBAehB"}
package/lib/util.js CHANGED
@@ -42,6 +42,18 @@ export function DefaultLayout({ title, children }) {
42
42
  )
43
43
  }
44
44
 
45
+ /**
46
+ * @param {string} str
47
+ * @returns {string}
48
+ */
49
+ export function escapeHtml(str) {
50
+ return String(str)
51
+ .replace(/&/g, '&amp;')
52
+ .replace(/"/g, '&quot;')
53
+ .replace(/</g, '&lt;')
54
+ .replace(/>/g, '&gt;')
55
+ }
56
+
45
57
  /**
46
58
  * @param {string} cmd
47
59
  */
package/lib/vite.d.ts CHANGED
@@ -2,10 +2,12 @@
2
2
  * @param {Object} options
3
3
  * @param {string} options.dir
4
4
  * @param {string} [options.outDir]
5
+ * @param {string[]} [options.styles]
5
6
  * @returns {import('vite').Plugin}
6
7
  */
7
- export function pluginFactory({ dir, outDir }: {
8
+ export function pluginFactory({ dir, outDir, styles }: {
8
9
  dir: string;
9
10
  outDir?: string | undefined;
11
+ styles?: string[] | undefined;
10
12
  }): import("vite").Plugin;
11
13
  //# sourceMappingURL=vite.d.ts.map
package/lib/vite.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["vite.js"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,+CAJG;IAAwB,GAAG,EAAnB,MAAM;IACW,MAAM;CAC/B,GAAU,OAAO,MAAM,EAAE,MAAM,CA2JjC"}
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"}
package/lib/vite.js CHANGED
@@ -11,9 +11,10 @@ const contentModuleIdResolved = '\0' + contentModuleId
11
11
  * @param {Object} options
12
12
  * @param {string} options.dir
13
13
  * @param {string} [options.outDir]
14
+ * @param {string[]} [options.styles]
14
15
  * @returns {import('vite').Plugin}
15
16
  */
16
- export function pluginFactory({ dir, outDir }) {
17
+ export function pluginFactory({ dir, outDir, styles = [] }) {
17
18
  const files = setup(dir, { outDir })
18
19
 
19
20
  return {
@@ -62,7 +63,10 @@ export function pluginFactory({ dir, outDir }) {
62
63
  },
63
64
  async load(id) {
64
65
  if (id === appEntryId) {
65
- return `import "orga-build/csr";`
66
+ const styleImports = styles
67
+ .map((styleUrl) => `import ${JSON.stringify(styleUrl)};`)
68
+ .join('\n')
69
+ return `${styleImports}\nimport "orga-build/csr";`
66
70
  }
67
71
  if (id === contentModuleIdResolved) {
68
72
  return await renderContentModule()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orga-build",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "description": "A simple tool that builds org-mode files into a website",
5
5
  "type": "module",
6
6
  "engines": {