orga-build 0.6.1 → 0.6.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/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
 
@@ -27,8 +27,15 @@ Here's [[file:./docs/index.org][index page]].
27
27
  Here's [[file:more.org][another page]].
28
28
  `
29
29
  )
30
- await fs.writeFile(path.join(fixtureDir, 'docs', 'index.org'), 'Docs index page.')
30
+ await fs.writeFile(
31
+ path.join(fixtureDir, 'docs', 'index.org'),
32
+ 'Docs index page.'
33
+ )
31
34
  await fs.writeFile(path.join(fixtureDir, 'more.org'), 'Another page.')
35
+ await fs.writeFile(
36
+ path.join(fixtureDir, 'style.css'),
37
+ '.global-style-marker { color: rgb(1, 2, 3); }'
38
+ )
32
39
  })
33
40
 
34
41
  after(async () => {
@@ -58,7 +65,10 @@ Here's [[file:more.org][another page]].
58
65
  const html = await fs.readFile(indexPath, 'utf-8')
59
66
  assert.ok(html.includes('<title>Test Page</title>'), 'should have title')
60
67
  assert.ok(html.includes('Hello World'), 'should have heading content')
61
- assert.ok(html.includes('href="/docs"'), 'should rewrite docs/index.org to /docs')
68
+ assert.ok(
69
+ html.includes('href="/docs"'),
70
+ 'should rewrite docs/index.org to /docs'
71
+ )
62
72
  assert.ok(html.includes('href="/more"'), 'should rewrite more.org to /more')
63
73
  })
64
74
 
@@ -70,4 +80,35 @@ Here's [[file:more.org][another page]].
70
80
  .catch(() => false)
71
81
  assert.ok(assetsExists, 'assets directory should exist')
72
82
  })
83
+
84
+ test('processes configured global styles through vite and injects built css', async () => {
85
+ await build({
86
+ root: fixtureDir,
87
+ outDir: outDir,
88
+ containerClass: [],
89
+ styles: ['/style.css'],
90
+ vitePlugins: [],
91
+ preBuild: [],
92
+ postBuild: []
93
+ })
94
+
95
+ const html = await fs.readFile(path.join(outDir, 'index.html'), 'utf-8')
96
+ assert.ok(
97
+ !html.includes('href="/style.css"'),
98
+ 'should not link raw source css path'
99
+ )
100
+
101
+ const cssHrefMatch = html.match(/href="\/(assets\/[^"]+\.css)"/)
102
+ assert.ok(
103
+ cssHrefMatch,
104
+ 'should link built css asset from assets with hashed name'
105
+ )
106
+
107
+ const builtCssPath = cssHrefMatch[1]
108
+ const builtCss = await fs.readFile(path.join(outDir, builtCssPath), 'utf-8')
109
+ assert.ok(
110
+ builtCss.includes('.global-style-marker'),
111
+ 'built css should include configured global style content'
112
+ )
113
+ })
73
114
  })
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 = (
@@ -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,6EAHW,OAAO,aAAa,EAAE,MAAM,gBAC5B,MAAM,iBAsJhB;;sBAlK4C,aAAa"}
package/lib/build.js CHANGED
@@ -1,29 +1,26 @@
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
+ import { appEntryId } from './vite.js'
8
9
 
9
10
  // Re-export alias for backwards compatibility
10
11
  export { alias }
11
12
 
12
13
  const ssrEntry = fileURLToPath(new URL('./ssr.jsx', import.meta.url))
13
- const clientEntry = fileURLToPath(new URL('./client.jsx', import.meta.url))
14
14
  const defaultIndexHtml = fileURLToPath(new URL('./index.html', import.meta.url))
15
15
 
16
16
  /**
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
+ { outDir, root, containerClass, styles = [], vitePlugins = [] },
22
+ projectRoot = process.cwd()
23
+ ) {
27
24
  await emptyDir(outDir)
28
25
  const ssrOutDir = path.join(outDir, '.ssr')
29
26
  const clientOutDir = outDir
@@ -66,7 +63,7 @@ export async function build({
66
63
  emptyOutDir: false,
67
64
  assetsDir: 'assets',
68
65
  rollupOptions: {
69
- input: clientEntry,
66
+ input: appEntryId,
70
67
  preserveEntrySignatures: 'allow-extension'
71
68
  }
72
69
  }
@@ -105,7 +102,9 @@ export async function build({
105
102
  /* --- get html template, inject entry js and css --- */
106
103
  // Check for user's index.html in project root, otherwise use default
107
104
  const userIndexPath = path.join(projectRoot, 'index.html')
108
- const indexHtmlPath = (await exists(userIndexPath)) ? userIndexPath : defaultIndexHtml
105
+ const indexHtmlPath = (await exists(userIndexPath))
106
+ ? userIndexPath
107
+ : defaultIndexHtml
109
108
  const template = await fs.readFile(indexHtmlPath, { encoding: 'utf-8' })
110
109
  /* --- for each page path, render html using render function from ssr bundle, and inject the right css --- */
111
110
  const pagePaths = Object.keys(pages)
@@ -144,7 +143,10 @@ export async function build({
144
143
  `
145
144
  )
146
145
  const css = cssChunks
147
- .map((/** @type {any} */ c) => `<link rel="stylesheet" href="/${c.fileName}">`)
146
+ .map(
147
+ (/** @type {any} */ c) =>
148
+ `<link rel="stylesheet" href="/${c.fileName}">`
149
+ )
148
150
  .join('\n')
149
151
  html = html.replace(
150
152
  '<script type="module" src="/@orga-build/main.js"></script>',
@@ -153,7 +155,7 @@ export async function build({
153
155
 
154
156
  html = html.replace('</head>', `${css}</head>`)
155
157
 
156
- const page = pages[pagePath]
158
+ const page = pages[pagePath]
157
159
  if (page) {
158
160
  html = html.replace(/%orga\.(\w+)%/g, (_, key) => {
159
161
  const value = page[key] ?? ''
@@ -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":"AAyBA;;;GAGG;AACH,qCAHW,MAAM,EAAE,GACN,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA+C5D;;YArEa,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
@@ -65,7 +65,9 @@ export async function loadConfig(...files) {
65
65
  result.root = resolveConfigPath(result.root)
66
66
  result.outDir = resolveConfigPath(result.outDir)
67
67
  const styles = result.styles
68
- result.styles = Array.isArray(styles) ? styles.filter((v) => typeof v === 'string') : []
68
+ result.styles = Array.isArray(styles)
69
+ ? styles.filter((v) => typeof v === 'string')
70
+ : []
69
71
  return {
70
72
  config: result,
71
73
  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.js CHANGED
@@ -39,7 +39,8 @@ function mediaAssets() {
39
39
  if (typeof src !== 'string') return
40
40
  if (src.startsWith('http')) return
41
41
  const tagName = node.tagName
42
- const name = (imports[src] ??= `asset_${genId()}`)
42
+ if (!imports[src]) imports[src] = `asset_${genId()}`
43
+ const name = imports[src]
43
44
  const attrs = Object.entries(rest)
44
45
  .filter(([, v]) => v !== undefined && v !== false)
45
46
  .map(([k, v]) => (v === true ? k : `${k}='${v}'`))
@@ -80,7 +81,7 @@ function rehypeWrap({ className = [] }) {
80
81
  properties: {
81
82
  className
82
83
  },
83
- // @ts-ignore
84
+ // @ts-expect-error
84
85
  children: tree.children
85
86
  }
86
87
  ]
@@ -131,7 +132,10 @@ function resolveOrgHrefToContentSlug({ root, filePath, href }) {
131
132
  : path.resolve(path.dirname(filePath), decodedHrefPath)
132
133
 
133
134
  const relativeTargetPath = path.relative(root, absoluteTargetPath)
134
- if (relativeTargetPath.startsWith('..') || path.isAbsolute(relativeTargetPath)) {
135
+ if (
136
+ relativeTargetPath.startsWith('..') ||
137
+ path.isAbsolute(relativeTargetPath)
138
+ ) {
135
139
  return null
136
140
  }
137
141
 
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
 
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.
@@ -38,7 +38,7 @@ export async function serve(config, port = 3000, projectRoot = process.cwd()) {
38
38
  port,
39
39
  strictPort: false,
40
40
  watch: {
41
- ignored: [path.resolve(config.outDir) + '/**']
41
+ ignored: [`${path.resolve(config.outDir)}/**`]
42
42
  }
43
43
  }
44
44
  })
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 CHANGED
@@ -10,4 +10,5 @@ export function pluginFactory({ dir, outDir, styles }: {
10
10
  outDir?: string | undefined;
11
11
  styles?: string[] | undefined;
12
12
  }): import("vite").Plugin;
13
+ export const appEntryId: "/@orga-build/main.js";
13
14
  //# 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;;;;;;GAMG;AACH,uDALG;IAAwB,GAAG,EAAnB,MAAM;IACW,MAAM;IACJ,MAAM;CACjC,GAAU,OAAO,MAAM,EAAE,MAAM,CA8JjC"}
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"}
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'
6
- const appEntryId = `${magicModulePrefix}main.js`
5
+ const pagesModuleId = `${magicModulePrefix}pages`
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,7 +20,7 @@ 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',
@@ -50,7 +50,7 @@ export function pluginFactory({ dir, outDir, styles = [] }) {
50
50
  }
51
51
  },
52
52
 
53
- async resolveId(id, importer) {
53
+ async resolveId(id, _importer) {
54
54
  if (id === appEntryId) {
55
55
  return appEntryId
56
56
  }
@@ -75,7 +75,7 @@ export function pluginFactory({ dir, outDir, styles = [] }) {
75
75
  return await renderPageList()
76
76
  }
77
77
  if (id.startsWith(pagesModuleId)) {
78
- let pageId = id.replace(pagesModuleId, '')
78
+ const pageId = id.replace(pagesModuleId, '')
79
79
  const page = await files.page(pageId)
80
80
  if (page) {
81
81
  return `
@@ -111,7 +111,7 @@ export default layouts;
111
111
  const pages = await files.pages()
112
112
  /** @type {string[]} */ const _imports = []
113
113
  /** @type {string[]} */ const _pages = []
114
- Object.entries(pages).forEach(([pageId, value], i) => {
114
+ Object.entries(pages).forEach(([pageId, _value], i) => {
115
115
  const dataModulePath = path.join(magicModulePrefix, 'pages', pageId)
116
116
  _imports.push(`import * as page${i} from '${dataModulePath}'`)
117
117
  _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.1",
3
+ "version": "0.6.3",
4
4
  "description": "A simple tool that builds org-mode files into a website",
5
5
  "type": "module",
6
6
  "engines": {
@@ -51,14 +51,14 @@
51
51
  "unist-util-visit-parents": "^6.0.1",
52
52
  "vite": "^7.3.1",
53
53
  "wouter": "^3.7.0",
54
- "@orgajs/rollup": "1.3.3"
54
+ "@orgajs/rollup": "1.3.4"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/hast": "^3.0.4",
58
58
  "@types/node": "^22.13.1",
59
59
  "@types/react": "^19.0.8",
60
60
  "@types/react-dom": "^19.0.3",
61
- "orga": "4.6.0"
61
+ "orga": "4.7.1"
62
62
  },
63
63
  "scripts": {
64
64
  "clean": "fd . -e d.ts -e d.ts.map -I -x rm {}",
package/lib/client.jsx DELETED
@@ -1,12 +0,0 @@
1
- import { hydrateRoot } from 'react-dom/client'
2
- import { Router } from 'wouter'
3
- import { App } from './app.jsx'
4
-
5
- const ssr = window._ssr
6
-
7
- hydrateRoot(
8
- document.getElementById('root'),
9
- <Router>
10
- <App />
11
- </Router>
12
- )