@dirwell/cli 0.0.1 → 0.0.2
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.md +3 -3
- package/dist/bin.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-DapzDTGv.mjs → src-BadHyOPx.mjs} +18 -1
- package/dist/src-BadHyOPx.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/src-DapzDTGv.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@ The CLI supports short theme names and automatic `dirwell.config.mjs` discovery.
|
|
|
11
11
|
## Open or publish a folder
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
npx @dirwell/cli@0.0.
|
|
15
|
-
npx @dirwell/cli@0.0.
|
|
14
|
+
npx @dirwell/cli@0.0.2 server ./files
|
|
15
|
+
npx @dirwell/cli@0.0.2 build ./files --out ./generated
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
No project, configuration file or global installation is required. Open the URL
|
|
@@ -42,7 +42,7 @@ Builds replace missing, empty or Dirwell-marked output directories. A nonempty u
|
|
|
42
42
|
For repeated project use, install the CLI and the theme you want:
|
|
43
43
|
|
|
44
44
|
```sh
|
|
45
|
-
npm install --save-dev @dirwell/cli@0.0.
|
|
45
|
+
npm install --save-dev @dirwell/cli@0.0.2 @dirwell/theme-ledger@0.0.2
|
|
46
46
|
npx dirwell server ./files --theme ledger
|
|
47
47
|
```
|
|
48
48
|
|
package/dist/bin.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as defineConfig, t as runCli } from "./src-
|
|
1
|
+
import { n as defineConfig, t as runCli } from "./src-BadHyOPx.mjs";
|
|
2
2
|
export { defineConfig, runCli };
|
|
@@ -100,6 +100,7 @@ const serverKeys = {
|
|
|
100
100
|
entryData: true,
|
|
101
101
|
ignoreFiles: true,
|
|
102
102
|
live: true,
|
|
103
|
+
search: true,
|
|
103
104
|
blockSize: true,
|
|
104
105
|
mountPath: true,
|
|
105
106
|
files: true,
|
|
@@ -183,6 +184,22 @@ function validateCliConfig(value) {
|
|
|
183
184
|
keys(live, ["intervalMs", "maxClients"], "server.live");
|
|
184
185
|
for (const key of ["intervalMs", "maxClients"]) scalar(live[key], "number", `server.live.${key}`);
|
|
185
186
|
}
|
|
187
|
+
if (options.search !== void 0 && options.search !== false) {
|
|
188
|
+
const search = object(options.search, "server.search");
|
|
189
|
+
keys(search, [
|
|
190
|
+
"maxEntries",
|
|
191
|
+
"maxDirectories",
|
|
192
|
+
"maxConcurrent",
|
|
193
|
+
"maxResults",
|
|
194
|
+
"timeoutMs",
|
|
195
|
+
"refreshIntervalMs"
|
|
196
|
+
], "server.search");
|
|
197
|
+
if (typeof search.maxResults === "number" && search.maxResults > 1e4) throw new TypeError("server.search.maxResults must not exceed 10000");
|
|
198
|
+
for (const key of Object.keys(search)) {
|
|
199
|
+
scalar(search[key], "number", `server.search.${key}`);
|
|
200
|
+
if (!Number.isSafeInteger(search[key]) || Number(search[key]) < (key === "refreshIntervalMs" ? 1e3 : 1)) throw new TypeError(`server.search.${key} must be a positive safe integer`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
186
203
|
}
|
|
187
204
|
}
|
|
188
205
|
}
|
|
@@ -408,4 +425,4 @@ async function runCli(args, cwd = process.cwd(), log = console.log) {
|
|
|
408
425
|
//#endregion
|
|
409
426
|
export { defineConfig as n, runCli as t };
|
|
410
427
|
|
|
411
|
-
//# sourceMappingURL=src-
|
|
428
|
+
//# sourceMappingURL=src-BadHyOPx.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-BadHyOPx.mjs","names":["resolveModule"],"sources":["../src/config.ts","../src/index.ts"],"sourcesContent":["import type { CliConfig } from \"./index.ts\";\nimport { resolveIgnoreFiles } from \"@dirwell/core\";\n\ntype RecordValue = Record<string, unknown>;\nfunction object(value: unknown, name: string): RecordValue {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`${name} must be an object`);\n return value as RecordValue;\n}\nfunction distance(left: string, right: string): number {\n let previous = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++)\n current[j] = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n );\n previous = current;\n }\n return previous[right.length]!;\n}\nfunction keys(value: RecordValue, allowed: readonly string[], name: string): void {\n for (const key of Object.keys(value)) {\n if (allowed.includes(key)) continue;\n const suggestion = allowed\n .map((candidate) => ({ candidate, distance: distance(key, candidate) }))\n .sort((left, right) => left.distance - right.distance)\n .find((item) => item.distance <= 2)?.candidate;\n throw new TypeError(\n `Unsupported config key \"${name}.${key}\".${suggestion ? ` Did you mean \"${name}.${suggestion}\"?` : ` Supported keys: ${allowed.join(\", \")}.`}`,\n );\n }\n}\nfunction scalar(value: unknown, type: \"string\" | \"boolean\" | \"number\" | \"function\", name: string) {\n if (\n value !== undefined &&\n (typeof value !== type || (type === \"number\" && !Number.isFinite(value)))\n )\n throw new TypeError(`${name} must be a ${type}`);\n}\nfunction patterns(value: unknown, name: string): void {\n if (\n value !== undefined &&\n typeof value !== \"string\" &&\n (!Array.isArray(value) || value.some((item) => typeof item !== \"string\"))\n )\n throw new TypeError(`${name} must be a string or an array of strings`);\n}\nfunction sort(value: unknown, name: string): void {\n if (value === undefined) return;\n const options = object(value, name);\n keys(options, [\"direction\", \"directoriesFirst\", \"field\", \"nameMode\"], name);\n scalar(options.directoriesFirst, \"boolean\", `${name}.directoriesFirst`);\n for (const [key, allowed] of Object.entries({\n direction: [\"asc\", \"desc\"],\n field: [\"name\", \"size\", \"modified\"],\n nameMode: [\"natural\", \"unicode\", \"locale\"],\n }))\n if (options[key] !== undefined && !allowed.includes(String(options[key])))\n throw new TypeError(`${name}.${key} must be one of ${allowed.join(\", \")}`);\n}\nfunction listing(value: unknown, name: string): void {\n if (value === undefined || typeof value === \"function\") return;\n const plan = object(value, name);\n keys(plan, [\"html\", \"data\"], name);\n for (const [key, sizedStrategy, sizeKey] of [\n [\"html\", \"paged\", \"pageSize\"],\n [\"data\", \"blocks\", \"blockSize\"],\n ] as const) {\n const strategy = object(plan[key], `${name}.${key}`);\n keys(\n strategy,\n strategy.strategy === sizedStrategy ? [\"strategy\", sizeKey] : [\"strategy\"],\n `${name}.${key}`,\n );\n if (strategy.strategy !== \"all\" && strategy.strategy !== sizedStrategy)\n throw new TypeError(`${name}.${key}.strategy must be all or ${sizedStrategy}`);\n if (\n strategy.strategy === sizedStrategy &&\n (!Number.isSafeInteger(strategy[sizeKey]) || Number(strategy[sizeKey]) < 1)\n )\n throw new TypeError(`${name}.${key}.${sizeKey} must be a positive integer`);\n }\n}\nconst buildKeys = {\n fileHref: true,\n entryData: true,\n dryRun: true,\n outputPolicy: true,\n ignoreFiles: true,\n metadata: true,\n base: true,\n include: true,\n exclude: true,\n mode: true,\n mirror: true,\n outputName: true,\n urlStrategy: true,\n symlinks: true,\n sort: true,\n} satisfies Record<keyof NonNullable<CliConfig[\"build\"]>, true>;\nconst serverKeys = {\n entryData: true,\n ignoreFiles: true,\n live: true,\n search: true,\n blockSize: true,\n mountPath: true,\n files: true,\n pageSize: true,\n maxPageSize: true,\n fileHref: true,\n headers: true,\n authorize: true,\n include: true,\n exclude: true,\n sort: true,\n host: true,\n port: true,\n} satisfies Record<keyof NonNullable<CliConfig[\"server\"]>, true>;\n\n/** Validate both modes before filesystem publication or server startup. */\nexport function validateCliConfig(value: unknown): asserts value is CliConfig {\n const config = object(value, \"Config\");\n // Preserve the top-level diagnostic used by CLI consumers.\n for (const key of Object.keys(config))\n if (![\"theme\", \"listing\", \"build\", \"server\", \"ignoreFiles\"].includes(key))\n throw new TypeError(\n `Unsupported config key \"${key}\". Use { theme, listing, build, server }; selection rules belong in build/server.`,\n );\n listing(config.listing, \"listing\");\n resolveIgnoreFiles(config.ignoreFiles as CliConfig[\"ignoreFiles\"]);\n for (const mode of [\"build\", \"server\"] as const) {\n if (config[mode] === undefined) continue;\n const options = object(config[mode], mode);\n keys(options, Object.keys(mode === \"build\" ? buildKeys : serverKeys), mode);\n patterns(options.include, `${mode}.include`);\n patterns(options.exclude, `${mode}.exclude`);\n resolveIgnoreFiles(options.ignoreFiles as CliConfig[\"ignoreFiles\"]);\n sort(options.sort, `${mode}.sort`);\n scalar(options.entryData, \"function\", `${mode}.entryData`);\n if (mode === \"build\") {\n scalar(options.fileHref, \"function\", \"build.fileHref\");\n for (const key of [\"base\", \"mode\", \"urlStrategy\"])\n scalar(options[key], \"string\", `${mode}.${key}`);\n scalar(options.mirror, \"boolean\", \"build.mirror\");\n scalar(options.dryRun, \"boolean\", \"build.dryRun\");\n if (\n options.outputPolicy !== undefined &&\n options.outputPolicy !== \"owned\" &&\n options.outputPolicy !== \"replace\"\n )\n throw new TypeError(\"build.outputPolicy must be owned or replace\");\n scalar(options.metadata, \"function\", \"build.metadata\");\n if (\n options.outputName !== undefined &&\n typeof options.outputName !== \"string\" &&\n typeof options.outputName !== \"function\"\n )\n throw new TypeError(\"build.outputName must be a string or function\");\n if (options.symlinks !== undefined) {\n const links = object(options.symlinks, \"build.symlinks\");\n keys(links, [\"follow\", \"boundary\", \"onCycle\"], \"build.symlinks\");\n scalar(links.follow, \"boolean\", \"build.symlinks.follow\");\n for (const [key, allowed] of Object.entries({\n boundary: [\"root\", \"anywhere\"],\n onCycle: [\"error\", \"skip\"],\n }))\n if (links[key] !== undefined && !allowed.includes(String(links[key])))\n throw new TypeError(`build.symlinks.${key} must be one of ${allowed.join(\", \")}`);\n }\n } else {\n for (const key of [\"host\", \"mountPath\"]) scalar(options[key], \"string\", `server.${key}`);\n for (const key of [\"port\", \"pageSize\", \"maxPageSize\", \"blockSize\"])\n scalar(options[key], \"number\", `server.${key}`);\n for (const key of [\"fileHref\", \"headers\", \"authorize\"])\n scalar(options[key], \"function\", `server.${key}`);\n if (\n options.files !== undefined &&\n options.files !== false &&\n ![\"media\", \"attachment\", \"inline\"].includes(String(options.files))\n )\n throw new TypeError(\"server.files must be false, media, attachment or inline\");\n if (options.live !== undefined && options.live !== false) {\n const live = object(options.live, \"server.live\");\n keys(live, [\"intervalMs\", \"maxClients\"], \"server.live\");\n for (const key of [\"intervalMs\", \"maxClients\"])\n scalar(live[key], \"number\", `server.live.${key}`);\n }\n if (options.search !== undefined && options.search !== false) {\n const search = object(options.search, \"server.search\");\n keys(\n search,\n [\n \"maxEntries\",\n \"maxDirectories\",\n \"maxConcurrent\",\n \"maxResults\",\n \"timeoutMs\",\n \"refreshIntervalMs\",\n ],\n \"server.search\",\n );\n if (typeof search.maxResults === \"number\" && search.maxResults > 10000)\n throw new TypeError(\"server.search.maxResults must not exceed 10000\");\n for (const key of Object.keys(search)) {\n scalar(search[key], \"number\", `server.search.${key}`);\n if (\n !Number.isSafeInteger(search[key]) ||\n Number(search[key]) < (key === \"refreshIntervalMs\" ? 1000 : 1)\n )\n throw new TypeError(`server.search.${key} must be a positive safe integer`);\n }\n }\n }\n }\n}\n\n/** Preserve literal types and validate JavaScript configuration at definition time. */\nexport function defineConfig<const T extends CliConfig>(config: T): T {\n validateCliConfig(config);\n return config;\n}\n","import path from \"node:path\";\nimport { access, stat } from \"node:fs/promises\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve as resolveModule } from \"import-meta-resolve\";\nimport { parseArgs } from \"node:util\";\nimport { generateExplorer, resolveIgnoreFiles } from \"@dirwell/core\";\nimport type { ExplorerTheme, ListingPolicy, GenerateOptions } from \"@dirwell/core\";\nimport { createPlainTheme } from \"@dirwell/theme-plain\";\nimport { startExplorerServer } from \"@dirwell/server/node\";\nimport { validateCliConfig } from \"./config.ts\";\nexport { defineConfig } from \"./config.ts\";\n\nexport interface CliConfig {\n readonly ignoreFiles?: GenerateOptions[\"ignoreFiles\"];\n readonly build?: Omit<GenerateOptions, \"sourceDir\" | \"outputDir\" | \"theme\" | \"listing\">;\n readonly theme?: ExplorerTheme;\n readonly listing?: ListingPolicy;\n readonly server?: Omit<Parameters<typeof startExplorerServer>[0], \"root\" | \"theme\" | \"listing\">;\n}\nconst help = `Usage:\n dirwell build <source> --out <output>\n dirwell server <source> [--port 3000]\n\nPlain is included and selected by default. Install other themes separately.\nOfficial themes: --theme plain|ledger|crosswave\nCustom themes: --theme <module>#<factory>, or a module's default export.\nReads dirwell.config.mjs in the working folder; --config <file.mjs> selects another file.\nConfig exports theme, listing, build options, and server hooks.\nBuild options: --mode ssg|mpa, --urls relative|base|html-base, --base <path>\nBuild safety: --dry-run, --force (-f) replaces an unowned nonempty output.\nSelection: --ignore-file <path> (repeatable), --no-ignore disables ignore files.\nServer options: --host <host>, --port <port>, --mount <path>, --live\nBoth modes: --page-size <n>, --block-size <n>\nLive server reads on request. It does not build an output tree or require watch mode.\n`;\nconst positive = (value: string | undefined, name: string): number | undefined => {\n if (value === undefined) return undefined;\n const number = Number(value);\n if (!Number.isSafeInteger(number) || number < 1)\n throw new TypeError(`${name} must be a positive integer`);\n return number;\n};\nfunction assertTheme(candidate: unknown): asserts candidate is ExplorerTheme {\n if (\n typeof candidate !== \"object\" ||\n candidate === null ||\n !(\"name\" in candidate) ||\n typeof candidate.name !== \"string\" ||\n !(\"render\" in candidate) ||\n typeof candidate.render !== \"function\"\n )\n throw new TypeError(\"Theme must be an object with name and render(context)\");\n}\nasync function loadTheme(specifier: string, cwd: string): Promise<ExplorerTheme> {\n const official: Record<string, string> = {\n plain: \"@dirwell/theme-plain#createPlainTheme\",\n ledger: \"@dirwell/theme-ledger#createLedgerTheme\",\n crosswave: \"@dirwell/theme-crosswave#createCrosswaveTheme\",\n };\n if (Object.hasOwn(official, specifier)) specifier = official[specifier]!;\n const delimiter = specifier.lastIndexOf(\"#\"),\n name = delimiter < 0 ? specifier : specifier.slice(0, delimiter),\n exported = delimiter < 0 ? \"default\" : specifier.slice(delimiter + 1);\n if (!name || !exported) throw new TypeError(\"Theme needs a module and export name\");\n let moduleUrl: string;\n if (name.startsWith(\".\") || path.isAbsolute(name)) {\n moduleUrl = pathToFileURL(path.resolve(cwd, name)).href;\n } else {\n try {\n moduleUrl = resolveModule(name, pathToFileURL(path.join(cwd, \"package.json\")).href);\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ERR_MODULE_NOT_FOUND\"))\n throw error;\n // npm exec installs explicit --package entries beside the CLI, outside the user's folder.\n try {\n moduleUrl = resolveModule(name, import.meta.url);\n } catch (fallbackError) {\n if (\n fallbackError instanceof Error &&\n \"code\" in fallbackError &&\n fallbackError.code === \"ERR_MODULE_NOT_FOUND\"\n )\n throw new TypeError(\n `Theme package \"${name}\" was not found. Install it in your project or include it with npm exec --package=${name}.`,\n );\n throw fallbackError;\n }\n }\n }\n const module: Record<string, unknown> = await import(moduleUrl);\n const candidate =\n typeof module[exported] === \"function\" ? await module[exported]() : module[exported];\n assertTheme(candidate);\n return candidate;\n}\n/** Parse explicit commands; return server ownership to the caller for graceful shutdown. */\nexport async function runCli(\n args: readonly string[],\n cwd = process.cwd(),\n log: (value: string) => void = console.log,\n) {\n const parsed = parseArgs({\n args: [...args],\n allowPositionals: true,\n options: {\n help: { type: \"boolean\", short: \"h\" },\n force: { type: \"boolean\", short: \"f\" },\n \"dry-run\": { type: \"boolean\" },\n \"ignore-file\": { type: \"string\", multiple: true },\n \"no-ignore\": { type: \"boolean\" },\n live: { type: \"boolean\" },\n theme: { type: \"string\" },\n config: { type: \"string\" },\n out: { type: \"string\" },\n mode: { type: \"string\" },\n urls: { type: \"string\" },\n base: { type: \"string\" },\n host: { type: \"string\" },\n port: { type: \"string\" },\n mount: { type: \"string\" },\n \"page-size\": { type: \"string\" },\n \"block-size\": { type: \"string\" },\n },\n });\n if (parsed.values.help) {\n log(help);\n return null;\n }\n const [command, source] = parsed.positionals;\n if (\n ![\"build\", \"server\"].includes(command ?? \"\") ||\n source === undefined ||\n source === \"\" ||\n parsed.positionals.length !== 2\n )\n throw new TypeError(help);\n const otherModeOptions =\n command === \"build\"\n ? [\"host\", \"port\", \"mount\", \"live\"]\n : [\"out\", \"mode\", \"urls\", \"base\", \"force\", \"dry-run\"];\n for (const option of otherModeOptions)\n if (Object.hasOwn(parsed.values, option))\n throw new TypeError(`--${option} is not supported in ${command} mode`);\n let config: CliConfig = {};\n const configPath = path.resolve(cwd, parsed.values.config ?? \"dirwell.config.mjs\");\n let hasConfig = parsed.values.config !== undefined;\n if (!hasConfig) {\n try {\n await access(configPath);\n hasConfig = true;\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n }\n if (!hasConfig) {\n for (const filename of [\n \"dirwell.config.ts\",\n \"dirwell.config.js\",\n \"dirwell.config.mts\",\n \"dirwell.config.cjs\",\n ]) {\n try {\n await access(path.resolve(cwd, filename));\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") continue;\n throw error;\n }\n throw new TypeError(\n `Found ${filename}. This CLI discovers dirwell.config.mjs only. Migrate the config or select a native JavaScript module with --config; existing rules will not be silently ignored.`,\n );\n }\n }\n if (hasConfig) {\n const module = await import(pathToFileURL(configPath).href);\n if (\n typeof module.default !== \"object\" ||\n module.default === null ||\n Array.isArray(module.default)\n )\n throw new TypeError(\"Config must export an object\");\n for (const key of Object.keys(module.default))\n if (![\"theme\", \"listing\", \"build\", \"server\", \"ignoreFiles\"].includes(key))\n throw new TypeError(\n `Unsupported config key \"${key}\". Use { theme, listing, build, server }; selection rules belong in build/server.`,\n );\n if (typeof module.default.then === \"function\")\n throw new TypeError(\n \"Config must export a resolved object; use top-level await for async setup\",\n );\n validateCliConfig(module.default);\n config = module.default;\n }\n const theme =\n parsed.values.theme !== undefined\n ? await loadTheme(parsed.values.theme, cwd)\n : config.theme === undefined\n ? createPlainTheme()\n : config.theme;\n assertTheme(theme);\n const pageSize = positive(parsed.values[\"page-size\"], \"page-size\"),\n blockSize = positive(parsed.values[\"block-size\"], \"block-size\");\n const listing: ListingPolicy | undefined =\n pageSize !== undefined || blockSize !== undefined\n ? {\n html: pageSize === undefined ? { strategy: \"all\" } : { strategy: \"paged\", pageSize },\n data: blockSize === undefined ? { strategy: \"all\" } : { strategy: \"blocks\", blockSize },\n }\n : config.listing;\n const root = path.resolve(cwd, source);\n if (!(await stat(root)).isDirectory())\n throw new TypeError(\"Source must be an existing directory\");\n if (parsed.values[\"no-ignore\"] && parsed.values[\"ignore-file\"])\n throw new TypeError(\"--no-ignore cannot be combined with --ignore-file\");\n const modeOptions = command === \"build\" ? config.build : config.server;\n const ignoreFiles = resolveIgnoreFiles(\n parsed.values[\"no-ignore\"]\n ? []\n : (parsed.values[\"ignore-file\"] ??\n modeOptions?.ignoreFiles ??\n config.ignoreFiles ?? [{ path: \".gitignore\", optional: true }]),\n cwd,\n );\n if (command === \"build\") {\n if (parsed.values.out === undefined)\n throw new TypeError(\"Build requires --out pointing to a dedicated generated output tree\");\n const mode = parsed.values.mode ?? config.build?.mode ?? \"ssg\",\n urlStrategy = parsed.values.urls ?? config.build?.urlStrategy ?? \"relative\";\n if (mode !== \"ssg\" && mode !== \"mpa\") throw new TypeError(\"mode must be ssg or mpa\");\n if (![\"relative\", \"base\", \"html-base\"].includes(urlStrategy))\n throw new TypeError(\"Unknown URL strategy\");\n const report = await generateExplorer({\n ...config.build,\n sourceDir: root,\n outputDir: path.resolve(cwd, parsed.values.out),\n theme,\n ignoreFiles,\n ...(parsed.values.force ? { outputPolicy: \"replace\" } : {}),\n ...(parsed.values[\"dry-run\"] ? { dryRun: true } : {}),\n mode,\n urlStrategy: urlStrategy as \"relative\" | \"base\" | \"html-base\",\n ...(parsed.values.base === undefined ? {} : { base: parsed.values.base }),\n ...(listing === undefined ? {} : { listing }),\n });\n if (report.dryRun) log(JSON.stringify(report, null, 2));\n else {\n log(`Built ${parsed.values.out}`);\n log(\n `${report.selectedPaths.length} selected paths; ${report.pages.filter((page) => page.outputName !== null).length} directory pages; ${report.pages.filter((page) => page.outputName === null).length} skipped pages.`,\n );\n for (const page of report.pages)\n if (page.directory === \"\" || page.outputName === null)\n log(\n page.outputName === null\n ? `Skipped explorer page: ${page.directory || \"/\"}`\n : `Explorer entry: ${path.join(report.outputDir, page.outputName)}`,\n );\n }\n return null;\n }\n const port = Number(parsed.values.port ?? process.env.PORT ?? config.server?.port ?? 0);\n if (!Number.isSafeInteger(port) || port < 0 || port > 65535)\n throw new TypeError(\"port must be between 0 and 65535\");\n const server = await startExplorerServer({\n ...config.server,\n ...(parsed.values.live ? { live: config.server?.live || {} } : {}),\n root,\n theme,\n ignoreFiles,\n port,\n ...(listing === undefined ? {} : { listing }),\n ...(pageSize === undefined ? {} : { pageSize }),\n ...(blockSize === undefined ? {} : { blockSize }),\n ...(parsed.values.host === undefined ? {} : { host: parsed.values.host }),\n ...(parsed.values.mount === undefined ? {} : { mountPath: parsed.values.mount }),\n });\n log(\n `Dirwell server: ${server.url}${parsed.values.mount ?? config.server?.mountPath ?? \"\"}/browse/`,\n );\n return server;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dirwell/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Minimal file explorer build and live-server commands with Plain included.",
|
|
5
5
|
"homepage": "https://vp-tw.github.io/dirwell/getting-started/",
|
|
6
6
|
"bugs": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"tag": "latest"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@dirwell/core": "0.0.
|
|
37
|
-
"@dirwell/server": "0.0.
|
|
38
|
-
"@dirwell/theme-plain": "0.0.
|
|
36
|
+
"@dirwell/core": "0.0.2",
|
|
37
|
+
"@dirwell/server": "0.0.2",
|
|
38
|
+
"@dirwell/theme-plain": "0.0.2",
|
|
39
39
|
"import-meta-resolve": "4.2.0"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-DapzDTGv.mjs","names":["resolveModule"],"sources":["../src/config.ts","../src/index.ts"],"sourcesContent":["import type { CliConfig } from \"./index.ts\";\nimport { resolveIgnoreFiles } from \"@dirwell/core\";\n\ntype RecordValue = Record<string, unknown>;\nfunction object(value: unknown, name: string): RecordValue {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n throw new TypeError(`${name} must be an object`);\n return value as RecordValue;\n}\nfunction distance(left: string, right: string): number {\n let previous = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++)\n current[j] = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n );\n previous = current;\n }\n return previous[right.length]!;\n}\nfunction keys(value: RecordValue, allowed: readonly string[], name: string): void {\n for (const key of Object.keys(value)) {\n if (allowed.includes(key)) continue;\n const suggestion = allowed\n .map((candidate) => ({ candidate, distance: distance(key, candidate) }))\n .sort((left, right) => left.distance - right.distance)\n .find((item) => item.distance <= 2)?.candidate;\n throw new TypeError(\n `Unsupported config key \"${name}.${key}\".${suggestion ? ` Did you mean \"${name}.${suggestion}\"?` : ` Supported keys: ${allowed.join(\", \")}.`}`,\n );\n }\n}\nfunction scalar(value: unknown, type: \"string\" | \"boolean\" | \"number\" | \"function\", name: string) {\n if (\n value !== undefined &&\n (typeof value !== type || (type === \"number\" && !Number.isFinite(value)))\n )\n throw new TypeError(`${name} must be a ${type}`);\n}\nfunction patterns(value: unknown, name: string): void {\n if (\n value !== undefined &&\n typeof value !== \"string\" &&\n (!Array.isArray(value) || value.some((item) => typeof item !== \"string\"))\n )\n throw new TypeError(`${name} must be a string or an array of strings`);\n}\nfunction sort(value: unknown, name: string): void {\n if (value === undefined) return;\n const options = object(value, name);\n keys(options, [\"direction\", \"directoriesFirst\", \"field\", \"nameMode\"], name);\n scalar(options.directoriesFirst, \"boolean\", `${name}.directoriesFirst`);\n for (const [key, allowed] of Object.entries({\n direction: [\"asc\", \"desc\"],\n field: [\"name\", \"size\", \"modified\"],\n nameMode: [\"natural\", \"unicode\", \"locale\"],\n }))\n if (options[key] !== undefined && !allowed.includes(String(options[key])))\n throw new TypeError(`${name}.${key} must be one of ${allowed.join(\", \")}`);\n}\nfunction listing(value: unknown, name: string): void {\n if (value === undefined || typeof value === \"function\") return;\n const plan = object(value, name);\n keys(plan, [\"html\", \"data\"], name);\n for (const [key, sizedStrategy, sizeKey] of [\n [\"html\", \"paged\", \"pageSize\"],\n [\"data\", \"blocks\", \"blockSize\"],\n ] as const) {\n const strategy = object(plan[key], `${name}.${key}`);\n keys(\n strategy,\n strategy.strategy === sizedStrategy ? [\"strategy\", sizeKey] : [\"strategy\"],\n `${name}.${key}`,\n );\n if (strategy.strategy !== \"all\" && strategy.strategy !== sizedStrategy)\n throw new TypeError(`${name}.${key}.strategy must be all or ${sizedStrategy}`);\n if (\n strategy.strategy === sizedStrategy &&\n (!Number.isSafeInteger(strategy[sizeKey]) || Number(strategy[sizeKey]) < 1)\n )\n throw new TypeError(`${name}.${key}.${sizeKey} must be a positive integer`);\n }\n}\nconst buildKeys = {\n fileHref: true,\n entryData: true,\n dryRun: true,\n outputPolicy: true,\n ignoreFiles: true,\n metadata: true,\n base: true,\n include: true,\n exclude: true,\n mode: true,\n mirror: true,\n outputName: true,\n urlStrategy: true,\n symlinks: true,\n sort: true,\n} satisfies Record<keyof NonNullable<CliConfig[\"build\"]>, true>;\nconst serverKeys = {\n entryData: true,\n ignoreFiles: true,\n live: true,\n blockSize: true,\n mountPath: true,\n files: true,\n pageSize: true,\n maxPageSize: true,\n fileHref: true,\n headers: true,\n authorize: true,\n include: true,\n exclude: true,\n sort: true,\n host: true,\n port: true,\n} satisfies Record<keyof NonNullable<CliConfig[\"server\"]>, true>;\n\n/** Validate both modes before filesystem publication or server startup. */\nexport function validateCliConfig(value: unknown): asserts value is CliConfig {\n const config = object(value, \"Config\");\n // Preserve the top-level diagnostic used by CLI consumers.\n for (const key of Object.keys(config))\n if (![\"theme\", \"listing\", \"build\", \"server\", \"ignoreFiles\"].includes(key))\n throw new TypeError(\n `Unsupported config key \"${key}\". Use { theme, listing, build, server }; selection rules belong in build/server.`,\n );\n listing(config.listing, \"listing\");\n resolveIgnoreFiles(config.ignoreFiles as CliConfig[\"ignoreFiles\"]);\n for (const mode of [\"build\", \"server\"] as const) {\n if (config[mode] === undefined) continue;\n const options = object(config[mode], mode);\n keys(options, Object.keys(mode === \"build\" ? buildKeys : serverKeys), mode);\n patterns(options.include, `${mode}.include`);\n patterns(options.exclude, `${mode}.exclude`);\n resolveIgnoreFiles(options.ignoreFiles as CliConfig[\"ignoreFiles\"]);\n sort(options.sort, `${mode}.sort`);\n scalar(options.entryData, \"function\", `${mode}.entryData`);\n if (mode === \"build\") {\n scalar(options.fileHref, \"function\", \"build.fileHref\");\n for (const key of [\"base\", \"mode\", \"urlStrategy\"])\n scalar(options[key], \"string\", `${mode}.${key}`);\n scalar(options.mirror, \"boolean\", \"build.mirror\");\n scalar(options.dryRun, \"boolean\", \"build.dryRun\");\n if (\n options.outputPolicy !== undefined &&\n options.outputPolicy !== \"owned\" &&\n options.outputPolicy !== \"replace\"\n )\n throw new TypeError(\"build.outputPolicy must be owned or replace\");\n scalar(options.metadata, \"function\", \"build.metadata\");\n if (\n options.outputName !== undefined &&\n typeof options.outputName !== \"string\" &&\n typeof options.outputName !== \"function\"\n )\n throw new TypeError(\"build.outputName must be a string or function\");\n if (options.symlinks !== undefined) {\n const links = object(options.symlinks, \"build.symlinks\");\n keys(links, [\"follow\", \"boundary\", \"onCycle\"], \"build.symlinks\");\n scalar(links.follow, \"boolean\", \"build.symlinks.follow\");\n for (const [key, allowed] of Object.entries({\n boundary: [\"root\", \"anywhere\"],\n onCycle: [\"error\", \"skip\"],\n }))\n if (links[key] !== undefined && !allowed.includes(String(links[key])))\n throw new TypeError(`build.symlinks.${key} must be one of ${allowed.join(\", \")}`);\n }\n } else {\n for (const key of [\"host\", \"mountPath\"]) scalar(options[key], \"string\", `server.${key}`);\n for (const key of [\"port\", \"pageSize\", \"maxPageSize\", \"blockSize\"])\n scalar(options[key], \"number\", `server.${key}`);\n for (const key of [\"fileHref\", \"headers\", \"authorize\"])\n scalar(options[key], \"function\", `server.${key}`);\n if (\n options.files !== undefined &&\n options.files !== false &&\n ![\"media\", \"attachment\", \"inline\"].includes(String(options.files))\n )\n throw new TypeError(\"server.files must be false, media, attachment or inline\");\n if (options.live !== undefined && options.live !== false) {\n const live = object(options.live, \"server.live\");\n keys(live, [\"intervalMs\", \"maxClients\"], \"server.live\");\n for (const key of [\"intervalMs\", \"maxClients\"])\n scalar(live[key], \"number\", `server.live.${key}`);\n }\n }\n }\n}\n\n/** Preserve literal types and validate JavaScript configuration at definition time. */\nexport function defineConfig<const T extends CliConfig>(config: T): T {\n validateCliConfig(config);\n return config;\n}\n","import path from \"node:path\";\nimport { access, stat } from \"node:fs/promises\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve as resolveModule } from \"import-meta-resolve\";\nimport { parseArgs } from \"node:util\";\nimport { generateExplorer, resolveIgnoreFiles } from \"@dirwell/core\";\nimport type { ExplorerTheme, ListingPolicy, GenerateOptions } from \"@dirwell/core\";\nimport { createPlainTheme } from \"@dirwell/theme-plain\";\nimport { startExplorerServer } from \"@dirwell/server/node\";\nimport { validateCliConfig } from \"./config.ts\";\nexport { defineConfig } from \"./config.ts\";\n\nexport interface CliConfig {\n readonly ignoreFiles?: GenerateOptions[\"ignoreFiles\"];\n readonly build?: Omit<GenerateOptions, \"sourceDir\" | \"outputDir\" | \"theme\" | \"listing\">;\n readonly theme?: ExplorerTheme;\n readonly listing?: ListingPolicy;\n readonly server?: Omit<Parameters<typeof startExplorerServer>[0], \"root\" | \"theme\" | \"listing\">;\n}\nconst help = `Usage:\n dirwell build <source> --out <output>\n dirwell server <source> [--port 3000]\n\nPlain is included and selected by default. Install other themes separately.\nOfficial themes: --theme plain|ledger|crosswave\nCustom themes: --theme <module>#<factory>, or a module's default export.\nReads dirwell.config.mjs in the working folder; --config <file.mjs> selects another file.\nConfig exports theme, listing, build options, and server hooks.\nBuild options: --mode ssg|mpa, --urls relative|base|html-base, --base <path>\nBuild safety: --dry-run, --force (-f) replaces an unowned nonempty output.\nSelection: --ignore-file <path> (repeatable), --no-ignore disables ignore files.\nServer options: --host <host>, --port <port>, --mount <path>, --live\nBoth modes: --page-size <n>, --block-size <n>\nLive server reads on request. It does not build an output tree or require watch mode.\n`;\nconst positive = (value: string | undefined, name: string): number | undefined => {\n if (value === undefined) return undefined;\n const number = Number(value);\n if (!Number.isSafeInteger(number) || number < 1)\n throw new TypeError(`${name} must be a positive integer`);\n return number;\n};\nfunction assertTheme(candidate: unknown): asserts candidate is ExplorerTheme {\n if (\n typeof candidate !== \"object\" ||\n candidate === null ||\n !(\"name\" in candidate) ||\n typeof candidate.name !== \"string\" ||\n !(\"render\" in candidate) ||\n typeof candidate.render !== \"function\"\n )\n throw new TypeError(\"Theme must be an object with name and render(context)\");\n}\nasync function loadTheme(specifier: string, cwd: string): Promise<ExplorerTheme> {\n const official: Record<string, string> = {\n plain: \"@dirwell/theme-plain#createPlainTheme\",\n ledger: \"@dirwell/theme-ledger#createLedgerTheme\",\n crosswave: \"@dirwell/theme-crosswave#createCrosswaveTheme\",\n };\n if (Object.hasOwn(official, specifier)) specifier = official[specifier]!;\n const delimiter = specifier.lastIndexOf(\"#\"),\n name = delimiter < 0 ? specifier : specifier.slice(0, delimiter),\n exported = delimiter < 0 ? \"default\" : specifier.slice(delimiter + 1);\n if (!name || !exported) throw new TypeError(\"Theme needs a module and export name\");\n let moduleUrl: string;\n if (name.startsWith(\".\") || path.isAbsolute(name)) {\n moduleUrl = pathToFileURL(path.resolve(cwd, name)).href;\n } else {\n try {\n moduleUrl = resolveModule(name, pathToFileURL(path.join(cwd, \"package.json\")).href);\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ERR_MODULE_NOT_FOUND\"))\n throw error;\n // npm exec installs explicit --package entries beside the CLI, outside the user's folder.\n try {\n moduleUrl = resolveModule(name, import.meta.url);\n } catch (fallbackError) {\n if (\n fallbackError instanceof Error &&\n \"code\" in fallbackError &&\n fallbackError.code === \"ERR_MODULE_NOT_FOUND\"\n )\n throw new TypeError(\n `Theme package \"${name}\" was not found. Install it in your project or include it with npm exec --package=${name}.`,\n );\n throw fallbackError;\n }\n }\n }\n const module: Record<string, unknown> = await import(moduleUrl);\n const candidate =\n typeof module[exported] === \"function\" ? await module[exported]() : module[exported];\n assertTheme(candidate);\n return candidate;\n}\n/** Parse explicit commands; return server ownership to the caller for graceful shutdown. */\nexport async function runCli(\n args: readonly string[],\n cwd = process.cwd(),\n log: (value: string) => void = console.log,\n) {\n const parsed = parseArgs({\n args: [...args],\n allowPositionals: true,\n options: {\n help: { type: \"boolean\", short: \"h\" },\n force: { type: \"boolean\", short: \"f\" },\n \"dry-run\": { type: \"boolean\" },\n \"ignore-file\": { type: \"string\", multiple: true },\n \"no-ignore\": { type: \"boolean\" },\n live: { type: \"boolean\" },\n theme: { type: \"string\" },\n config: { type: \"string\" },\n out: { type: \"string\" },\n mode: { type: \"string\" },\n urls: { type: \"string\" },\n base: { type: \"string\" },\n host: { type: \"string\" },\n port: { type: \"string\" },\n mount: { type: \"string\" },\n \"page-size\": { type: \"string\" },\n \"block-size\": { type: \"string\" },\n },\n });\n if (parsed.values.help) {\n log(help);\n return null;\n }\n const [command, source] = parsed.positionals;\n if (\n ![\"build\", \"server\"].includes(command ?? \"\") ||\n source === undefined ||\n source === \"\" ||\n parsed.positionals.length !== 2\n )\n throw new TypeError(help);\n const otherModeOptions =\n command === \"build\"\n ? [\"host\", \"port\", \"mount\", \"live\"]\n : [\"out\", \"mode\", \"urls\", \"base\", \"force\", \"dry-run\"];\n for (const option of otherModeOptions)\n if (Object.hasOwn(parsed.values, option))\n throw new TypeError(`--${option} is not supported in ${command} mode`);\n let config: CliConfig = {};\n const configPath = path.resolve(cwd, parsed.values.config ?? \"dirwell.config.mjs\");\n let hasConfig = parsed.values.config !== undefined;\n if (!hasConfig) {\n try {\n await access(configPath);\n hasConfig = true;\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n }\n if (!hasConfig) {\n for (const filename of [\n \"dirwell.config.ts\",\n \"dirwell.config.js\",\n \"dirwell.config.mts\",\n \"dirwell.config.cjs\",\n ]) {\n try {\n await access(path.resolve(cwd, filename));\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") continue;\n throw error;\n }\n throw new TypeError(\n `Found ${filename}. This CLI discovers dirwell.config.mjs only. Migrate the config or select a native JavaScript module with --config; existing rules will not be silently ignored.`,\n );\n }\n }\n if (hasConfig) {\n const module = await import(pathToFileURL(configPath).href);\n if (\n typeof module.default !== \"object\" ||\n module.default === null ||\n Array.isArray(module.default)\n )\n throw new TypeError(\"Config must export an object\");\n for (const key of Object.keys(module.default))\n if (![\"theme\", \"listing\", \"build\", \"server\", \"ignoreFiles\"].includes(key))\n throw new TypeError(\n `Unsupported config key \"${key}\". Use { theme, listing, build, server }; selection rules belong in build/server.`,\n );\n if (typeof module.default.then === \"function\")\n throw new TypeError(\n \"Config must export a resolved object; use top-level await for async setup\",\n );\n validateCliConfig(module.default);\n config = module.default;\n }\n const theme =\n parsed.values.theme !== undefined\n ? await loadTheme(parsed.values.theme, cwd)\n : config.theme === undefined\n ? createPlainTheme()\n : config.theme;\n assertTheme(theme);\n const pageSize = positive(parsed.values[\"page-size\"], \"page-size\"),\n blockSize = positive(parsed.values[\"block-size\"], \"block-size\");\n const listing: ListingPolicy | undefined =\n pageSize !== undefined || blockSize !== undefined\n ? {\n html: pageSize === undefined ? { strategy: \"all\" } : { strategy: \"paged\", pageSize },\n data: blockSize === undefined ? { strategy: \"all\" } : { strategy: \"blocks\", blockSize },\n }\n : config.listing;\n const root = path.resolve(cwd, source);\n if (!(await stat(root)).isDirectory())\n throw new TypeError(\"Source must be an existing directory\");\n if (parsed.values[\"no-ignore\"] && parsed.values[\"ignore-file\"])\n throw new TypeError(\"--no-ignore cannot be combined with --ignore-file\");\n const modeOptions = command === \"build\" ? config.build : config.server;\n const ignoreFiles = resolveIgnoreFiles(\n parsed.values[\"no-ignore\"]\n ? []\n : (parsed.values[\"ignore-file\"] ??\n modeOptions?.ignoreFiles ??\n config.ignoreFiles ?? [{ path: \".gitignore\", optional: true }]),\n cwd,\n );\n if (command === \"build\") {\n if (parsed.values.out === undefined)\n throw new TypeError(\"Build requires --out pointing to a dedicated generated output tree\");\n const mode = parsed.values.mode ?? config.build?.mode ?? \"ssg\",\n urlStrategy = parsed.values.urls ?? config.build?.urlStrategy ?? \"relative\";\n if (mode !== \"ssg\" && mode !== \"mpa\") throw new TypeError(\"mode must be ssg or mpa\");\n if (![\"relative\", \"base\", \"html-base\"].includes(urlStrategy))\n throw new TypeError(\"Unknown URL strategy\");\n const report = await generateExplorer({\n ...config.build,\n sourceDir: root,\n outputDir: path.resolve(cwd, parsed.values.out),\n theme,\n ignoreFiles,\n ...(parsed.values.force ? { outputPolicy: \"replace\" } : {}),\n ...(parsed.values[\"dry-run\"] ? { dryRun: true } : {}),\n mode,\n urlStrategy: urlStrategy as \"relative\" | \"base\" | \"html-base\",\n ...(parsed.values.base === undefined ? {} : { base: parsed.values.base }),\n ...(listing === undefined ? {} : { listing }),\n });\n if (report.dryRun) log(JSON.stringify(report, null, 2));\n else {\n log(`Built ${parsed.values.out}`);\n log(\n `${report.selectedPaths.length} selected paths; ${report.pages.filter((page) => page.outputName !== null).length} directory pages; ${report.pages.filter((page) => page.outputName === null).length} skipped pages.`,\n );\n for (const page of report.pages)\n if (page.directory === \"\" || page.outputName === null)\n log(\n page.outputName === null\n ? `Skipped explorer page: ${page.directory || \"/\"}`\n : `Explorer entry: ${path.join(report.outputDir, page.outputName)}`,\n );\n }\n return null;\n }\n const port = Number(parsed.values.port ?? process.env.PORT ?? config.server?.port ?? 0);\n if (!Number.isSafeInteger(port) || port < 0 || port > 65535)\n throw new TypeError(\"port must be between 0 and 65535\");\n const server = await startExplorerServer({\n ...config.server,\n ...(parsed.values.live ? { live: config.server?.live || {} } : {}),\n root,\n theme,\n ignoreFiles,\n port,\n ...(listing === undefined ? {} : { listing }),\n ...(pageSize === undefined ? {} : { pageSize }),\n ...(blockSize === undefined ? {} : { blockSize }),\n ...(parsed.values.host === undefined ? {} : { host: parsed.values.host }),\n ...(parsed.values.mount === undefined ? {} : { mountPath: parsed.values.mount }),\n });\n log(\n `Dirwell server: ${server.url}${parsed.values.mount ?? config.server?.mountPath ?? \"\"}/browse/`,\n );\n return server;\n}\n"],"mappings":"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"}
|