| | |
| | | import { randomUUID } from "crypto" |
| | | import { Mutex } from "async-mutex" |
| | | import { CreateArgv } from "./args.js" |
| | | import { globby } from "globby" |
| | | import { |
| | | exitIfCancel, |
| | | escapePath, |
| | |
| | | } from "./constants.js" |
| | | |
| | | /** |
| | | * Resolve content directory path |
| | | * @param contentPath path to resolve |
| | | */ |
| | | function resolveContentPath(contentPath) { |
| | | if (path.isAbsolute(contentPath)) return path.relative(cwd, contentPath) |
| | | return path.join(cwd, contentPath) |
| | | } |
| | | |
| | | /** |
| | | * Handles `npx quartz create` |
| | | * @param {*} argv arguments for `create` |
| | | */ |
| | | export async function handleCreate(argv) { |
| | | console.log() |
| | | intro(chalk.bgGreen.black(` Quartz v${version} `)) |
| | | const contentFolder = path.join(cwd, argv.directory) |
| | | const contentFolder = resolveContentPath(argv.directory) |
| | | let setupStrategy = argv.strategy?.toLowerCase() |
| | | let linkResolutionStrategy = argv.links?.toLowerCase() |
| | | const sourceDirectory = argv.source |
| | |
| | | * @param {*} argv arguments for `build` |
| | | */ |
| | | export async function handleBuild(argv) { |
| | | if (argv.serve) { |
| | | argv.watch = true |
| | | } |
| | | |
| | | console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`)) |
| | | const ctx = await esbuild.context({ |
| | | entryPoints: [fp], |
| | |
| | | } |
| | | |
| | | if (cleanupBuild) { |
| | | await cleanupBuild() |
| | | console.log(chalk.yellow("Detected a source code change, doing a hard rebuild...")) |
| | | await cleanupBuild() |
| | | } |
| | | |
| | | const result = await ctx.rebuild().catch((err) => { |
| | |
| | | clientRefresh() |
| | | } |
| | | |
| | | let clientRefresh = () => {} |
| | | if (argv.serve) { |
| | | const connections = [] |
| | | const clientRefresh = () => connections.forEach((conn) => conn.send("rebuild")) |
| | | clientRefresh = () => connections.forEach((conn) => conn.send("rebuild")) |
| | | |
| | | if (argv.baseDir !== "" && !argv.baseDir.startsWith("/")) { |
| | | argv.baseDir = "/" + argv.baseDir |
| | |
| | | source: "**/*.*", |
| | | headers: [{ key: "Content-Disposition", value: "inline" }], |
| | | }, |
| | | { |
| | | source: "**/*.webp", |
| | | headers: [{ key: "Content-Type", value: "image/webp" }], |
| | | }, |
| | | // fixes bug where avif images are displayed as text instead of images (future proof) |
| | | { |
| | | source: "**/*.avif", |
| | | headers: [{ key: "Content-Type", value: "image/avif" }], |
| | | }, |
| | | ], |
| | | }) |
| | | const status = res.statusCode |
| | |
| | | |
| | | return serve() |
| | | }) |
| | | |
| | | server.listen(argv.port) |
| | | const wss = new WebSocketServer({ port: argv.wsPort }) |
| | | wss.on("connection", (ws) => connections.push(ws)) |
| | |
| | | `Started a Quartz server listening at http://localhost:${argv.port}${argv.baseDir}`, |
| | | ), |
| | | ) |
| | | console.log("hint: exit with ctrl+c") |
| | | chokidar |
| | | .watch(["**/*.ts", "**/*.tsx", "**/*.scss", "package.json"], { |
| | | ignoreInitial: true, |
| | | }) |
| | | .on("all", async () => { |
| | | build(clientRefresh) |
| | | }) |
| | | } else { |
| | | await build(() => {}) |
| | | await build(clientRefresh) |
| | | ctx.dispose() |
| | | } |
| | | |
| | | if (argv.watch) { |
| | | const paths = await globby([ |
| | | "**/*.ts", |
| | | "quartz/cli/*.js", |
| | | "quartz/static/**/*", |
| | | "**/*.tsx", |
| | | "**/*.scss", |
| | | "package.json", |
| | | ]) |
| | | chokidar |
| | | .watch(paths, { ignoreInitial: true }) |
| | | .on("add", () => build(clientRefresh)) |
| | | .on("change", () => build(clientRefresh)) |
| | | .on("unlink", () => build(clientRefresh)) |
| | | |
| | | console.log(chalk.grey("hint: exit with ctrl+c")) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param {*} argv arguments for `update` |
| | | */ |
| | | export async function handleUpdate(argv) { |
| | | const contentFolder = path.join(cwd, argv.directory) |
| | | const contentFolder = resolveContentPath(argv.directory) |
| | | console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`)) |
| | | console.log("Backing up your content") |
| | | execSync( |
| | |
| | | * @param {*} argv arguments for `restore` |
| | | */ |
| | | export async function handleRestore(argv) { |
| | | const contentFolder = path.join(cwd, argv.directory) |
| | | const contentFolder = resolveContentPath(argv.directory) |
| | | await popContentFolder(contentFolder) |
| | | } |
| | | |
| | |
| | | * @param {*} argv arguments for `sync` |
| | | */ |
| | | export async function handleSync(argv) { |
| | | const contentFolder = path.join(cwd, argv.directory) |
| | | const contentFolder = resolveContentPath(argv.directory) |
| | | console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`)) |
| | | console.log("Backing up your content") |
| | | |