quartz/quartz/plugins/emitters/helpers.ts
Copilot 6babcea029
refactor: decouple plugins from direct utility imports (#4)
* Initial plan

* Extend PluginUtilities with missing path and escape utilities

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Migrate transformers to use ctx.utils instead of direct imports

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Migrate emitters to use ctx.utils - part 1 (helpers, aliases, assets, contentIndex, contentPage, tagPage, static, favicon)

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Complete emitter migration to ctx.utils - all emitters decoupled

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Add comment explaining double-unescaping in test helper mock

This mirrors the production implementation in util/escape.ts which has the same pattern. The CodeQL alert is a known limitation of simple HTML unescaping that exists in the production code as well.

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Fix type safety: change join() return type to string and simplify casts

- Changed PluginUtilities.path.join() return type from FilePath to string to allow proper single-cast at call sites
- Removed unsafe double-casts (as unknown as FullSlug) in favor of single casts (as FullSlug)
- Fixed ogImage.tsx to use consistent destructuring pattern (ctx.cfg.configuration instead of cfg.configuration)
- Updated implementation in plugin-context.ts and test-helpers.ts

This addresses all code review feedback about type safety issues.

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

* Fix test mock implementations to match production code behavior

- Fixed getAllSegmentPrefixes to return cumulative prefixes (e.g., ["a", "a/b", "a/b/c"])
- Fixed isRelativeURL to include all three validation conditions
- Fixed stripSlashes to use substring(1) instead of replace(/^\/+/)
- Fixed slugTag to properly handle hierarchical tags with sluggify logic
- Fixed split to handle PDF files and anchor normalization
- Fixed HTML entity &#39; to &#039; for consistency
- Changed QUARTZ imports to use utils.path.QUARTZ for consistency
- Fixed favicon.ts to pass full ctx instead of reconstructing partial object

All mocks now accurately reflect production code behavior for reliable testing.

Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
2025-11-16 19:24:30 +01:00

21 lines
637 B
TypeScript

import path from "path"
import fs from "fs"
import { BuildCtx } from "../../util/ctx"
import { FilePath, FullSlug } from "../../util/path"
import { Readable } from "stream"
type WriteOptions = {
ctx: BuildCtx
slug: FullSlug
ext: `.${string}` | ""
content: string | Buffer | Readable
}
export const write = async ({ ctx, slug, ext, content }: WriteOptions): Promise<FilePath> => {
const pathToPage = ctx.utils!.path.join(ctx.argv.output, slug + ext) as FilePath
const dir = path.dirname(pathToPage)
await fs.promises.mkdir(dir, { recursive: true })
await fs.promises.writeFile(pathToPage, content)
return pathToPage
}