Repository navigation
move out into write module #25
Copy link
Copy link
Closed
Description
Task: Pull filesystem I/O out of the generate-template core
Repo: LLazyEmail/generate-template
Goal: Core engine is catalog + render + payload → HTML. Disk is an adapter. run({ templateId, payload }) must not touch fs.
Why
The public contract is already GenerateRequest / GenerateResult. Filesystem leftover from the old in-app script still lives in the engine:
listTemplateFiles()scanstemplatesDirpayload.tsprobesdataDir/{slug}.data.js/require()render/file-adapter.tswrites temp files andspawnSyncs Node- CLI
existsSyncs catalogfileentries - Defaults still assume
src/templatesandsrc/data
Writers already go through markup-generator. Reads should follow the same split.
Out of scope
- Do not add HTTP/Express
- Do not publish to npmjs
- Do not merge
markup-generatorinto this package - Do not keep
file+exportNameon the default path
Target shape
src/
engine/ createGenerator, run, render (no node:fs)
catalog/ find / slug / ids
persist/ Writer → markup-generator only
adapters/
payload-files.ts dataPath json / *.data.js
file-renderer.ts spawn path, opt-in
list-files.ts directory scan for CLI --list
cli.ts uses adapters, not the engine internals
Steps
- Audit every
fs,path.resolve(process.cwd()),createRequire,spawnSync,os.tmpdir()import. Table: file, API, required or adapter. - Engine rule:
TemplateGenerator.render/run/loadPayload(default) use only:- catalog
- injected
render - explicit
payloadorsamplePayloadsorconfig.loadPayload - no
templatesDir/dataDirunless an adapter is registered
- Move payload file loading to
adapters/payload-files.ts. Wire it only whendataPathis set oruseDataFiles: true. Default: missing payload →NO_PAYLOAD, do notexistsSync(dataDir). - Move
listTemplateFilesoff the class public API used by other repos, or keep it aslistTemplateFiles(dir)on the CLI adapter. Engine lists catalog ids, not directories. - Keep file-spawn in
adapters/file-renderer.ts. Still gated byallowFileTemplates. Engine must not importspawnSync. - CLI may import adapters.
--listuseslist-files.--data=uses payload-files. Generate still goes throughrun(). - Defaults: stop inventing
src/templatesandsrc/datawhen config omits them.outDirstays'generated'only for writes. - Tests
- engine test with no temp dirs and no
fsmock required forrun({ templateId, payload }) - payload-files adapter tests isolated
- file-renderer tests stay behind the flag
- sandbox keeps injected
render+run({ write })— that write path ismarkup-generator, allowed
- engine test with no temp dirs and no
- Docs:
MIGRATION.md+ README: “passpayloadorloadPayload; do not rely onsrc/data/*.data.jsunless you opt into the adapter.”
Done when
rg "node:fs|spawnSync|createRequire" srconly hitssrc/adapters/andsrc/cli.tsrun({ templateId, payload })works in a process with no projectsrc/templatesorsrc/data- CI +
npm run sandboxstill produce HTML - Sibling note: if anyone used
{slug}.data.jsauto-load, they passpayloador enable the payload-files adapter
Suggested split
- PR A: stop default
dataDirprobe; require explicit payload / sample / hook - PR B: move
listTemplateFilesto CLI adapter - PR C: isolate file-spawn so
generator.ts/render.tshave nofs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
feat: move directory scan and payload files behind adapters (issue #25)
atherdon commentedon Sep 29, 2026
Issue #25 is: the engine should only catalog + render + payload. Disk belongs in markup-generator (writes already did; reads should too).
Two PRs:
1. markup-generator #275
New public helpers:
pathExists(path)listTemplateFiles(dir, { skipFiles, extensions })— missing dir →[]loadData/readJson/writeGeneratedFilewere already here.2. generate-template #26
src/adapters/list-files.ts→listTemplateFilesfrom markup-generatorsrc/adapters/payload-files.ts→loadData+pathExistsgenerator.tsno longer importsnode:fsdataDirprobe. Missing payload throwsNO_PAYLOADunless you passpayload,dataPath,samplePayloads,loadPayload, oruseDataFiles: trueMerge order: #275 → publish markup-generator → bump the dependency → merge #26.
Still later (issue PR C): move
spawnSyncfile-renderer sorender.tsis also fs-free. Not in these PRs.Merge pull request #26 from LLazyEmail/feat/fs-adapters-issue-25
Merge pull request #29 from LLazyEmail/feat/issue-25-pr-b-c