1
#!/usr/bin/env node
2
/**
3
- * Sync the /developer docs from the smbcloud-cli repository.
3
+ * Generate the /developer docs from the sibling `docs/` tree.
4
*
5
- * The CLI / tooling documentation lives in `docs/` of smbcloud-cli and is the
6
- * source of truth. This script pulls those files into content/developer/ so the
7
- * docs site tracks the tool. Synced files are committed (vendored) so the site
8
- * builds on CI without network access — re-run this script to refresh them.
5
+ * The CLI / tooling documentation lives in `docs/` at the smbcloud-cli repo root
6
+ * (this site is `website/` in the same repo), so it is read in place — no clone,
7
+ * no network. This runs automatically on `predev`/`prebuild`; the generated
8
+ * pages are gitignored, leaving `docs/` as the single source of truth.
9
*
10
- * pnpm sync:developer
10
+ * pnpm docs:generate
11
*
12
* Hand-written index pages (content/developer/**\/index.mdx) are NOT touched.
13
* Only the files listed in MANIFEST and the generated _meta.js are written.
14
*/
15
-import { execSync } from 'node:child_process'
16
-import { mkdtempSync, rmSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs'
17
-import { tmpdir } from 'node:os'
15
+import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
16
import { join, dirname } from 'node:path'
17
import { fileURLToPath } from 'node:url'
18
21
-const REPO = 'https://github.com/smbcloudXYZ/smbcloud-cli.git'
19
const BRANCH = 'main'
20
const SRC_DIR = 'docs'
21
22
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
23
+// `docs/` sits next to `website/` at the smbcloud-cli repo root.
24
+const SRC = join(ROOT, '..', SRC_DIR)
25
const DEST = join(ROOT, 'content', 'developer')
26
27
// Source file -> where it lands and how it's labelled in the sidebar.
50
const blobUrl = src =>
51
`https://github.com/smbcloudXYZ/smbcloud-cli/blob/${BRANCH}/${SRC_DIR}/${src}`
52
54
-/** Wrap synced markdown: header note + a source callout after the first H1. */
53
+/** Wrap generated markdown: header note + a source callout after the first H1. */
54
function decorate(markdown, src) {
56
- const note = `{/* AUTO-GENERATED — do not edit. Synced by scripts/sync-developer-docs.mjs from ${SRC_DIR}/${src} (smbcloud-cli, ${BRANCH}). */}`
55
+ const note = `{/* AUTO-GENERATED — do not edit. Generated by scripts/generate-developer-docs.mjs from ../${SRC_DIR}/${src}. */}`
56
const callout = [
57
"import { Callout } from 'nextra/components'",
58
'',
59
'<Callout type="info">',
61
- ` Synced from [\`${SRC_DIR}/${src}\`](${blobUrl(src)}) on the \`${BRANCH}\` branch of`,
60
+ ` Generated from [\`${SRC_DIR}/${src}\`](${blobUrl(src)}) in`,
61
' [smbcloud-cli](https://github.com/smbcloudXYZ/smbcloud-cli). Edit it there.',
62
'</Callout>'
63
].join('\n')
80
}
81
82
function main() {
84
- const tmp = mkdtempSync(join(tmpdir(), 'smb-cli-docs-'))
85
- try {
86
- console.log(`Cloning ${REPO} (${BRANCH}, sparse: ${SRC_DIR})…`)
87
- execSync(
88
- `git clone --depth 1 --branch ${BRANCH} --filter=blob:none --sparse ${REPO} "${tmp}"`,
89
- { stdio: 'inherit' }
90
- )
91
- execSync(`git -C "${tmp}" sparse-checkout set ${SRC_DIR}`, { stdio: 'inherit' })
92
-
93
- let count = 0
94
- for (const [section, { title, pages }] of Object.entries(MANIFEST)) {
95
- const dir = join(DEST, section)
96
- mkdirSync(dir, { recursive: true })
97
- for (const page of pages) {
98
- const raw = readFileSync(join(tmp, SRC_DIR, page.src), 'utf8')
99
- writeFileSync(join(dir, `${page.slug}.mdx`), decorate(raw, page.src))
100
- count++
101
- }
102
- writeFileSync(join(dir, '_meta.js'), metaFile(pages))
103
- console.log(` ${section}: ${pages.length} pages (${title})`)
104
- }
105
-
106
- // Top-level developer nav: each section (the overview is asIndexPage).
107
- const top = []
108
- for (const [section, { title }] of Object.entries(MANIFEST)) {
109
- top.push(` ${section}: ${JSON.stringify(title)},`)
83
+ let count = 0
84
+ for (const [section, { title, pages }] of Object.entries(MANIFEST)) {
85
+ const dir = join(DEST, section)
86
+ mkdirSync(dir, { recursive: true })
87
+ for (const page of pages) {
88
+ const raw = readFileSync(join(SRC, page.src), 'utf8')
89
+ writeFileSync(join(dir, `${page.slug}.mdx`), decorate(raw, page.src))
90
+ count++
91
}
111
- writeFileSync(join(DEST, '_meta.js'), `export default {\n${top.join('\n')}\n}\n`)
92
+ writeFileSync(join(dir, '_meta.js'), metaFile(pages))
93
+ console.log(` ${section}: ${pages.length} pages (${title})`)
94
+ }
95
113
- console.log(`\nSynced ${count} pages into content/developer/.`)
114
- } finally {
115
- rmSync(tmp, { recursive: true, force: true })
96
+ // Top-level developer nav: each section (the overview is asIndexPage).
97
+ const top = []
98
+ for (const [section, { title }] of Object.entries(MANIFEST)) {
99
+ top.push(` ${section}: ${JSON.stringify(title)},`)
100
}
101
+ writeFileSync(join(DEST, '_meta.js'), `export default {\n${top.join('\n')}\n}\n`)
102
+
103
+ console.log(`\nGenerated ${count} pages into content/developer/ from ${SRC}.`)
104
}
105
106
main()