Skip to content

Implement @singleton-sd/post-kit-compiler package #20

Description

@patoperpetua

Parent: #3
Depends on: #17
Blocks: #18 (post-kit-publisher)

Goal

Create packages/post-kit-compiler — a TypeScript library that validates and compiles EmailBuilder.js template source files into runtime-ready HTML artifacts. The compiler is used by CI (via post-kit-publisher) and by the editor (via preview rendering). It must be deterministic and independent of any Azure service.

Scope

Package setup

  • Path: packages/post-kit-compiler
  • npm name: @singleton-sd/post-kit-compiler
  • TypeScript ESM, node --test, src/**/*.spec.ts convention
  • Peer/runtime dependencies: @singleton-sd/post-kit-types, @usewaypoint/email-builder renderer, Handlebars (or LiquidJS — choose one, document why, do not use both)
  • Public npm publication under Singleton SD scope

Compilation pipeline

validate source directory
  -> parse and validate template.json (EmailBuilder.js document schema)
  -> parse and validate metadata.json (TemplateSourceMetadata schema)
  -> parse and validate preview.json (TemplatePreviewData schema)
  -> check all metadata.variables are present in preview.json
  -> render EmailBuilder.js JSON -> HTML (using @usewaypoint/email-builder)
  -> render preview using preview.json values (variable substitution)
  -> compute contentHash (SHA-256 of compiled HTML)
  -> build TemplateManifest
  -> return CompiledTemplate

Variable rendering

Use Handlebars (or LiquidJS if preferred) for {{variable}} substitution in both the subject and the HTML body. Document the choice and version in the package README. Do not use custom regex interpolation.

Exported API

compile(source: TemplateSource): Promise<CompiledTemplate>
// where TemplateSource = { templateJson: unknown; metadata: TemplateSourceMetadata; previewData: TemplatePreviewData }

compileFromDirectory(dir: string): Promise<CompiledTemplate>
// reads template.json, metadata.json, preview.json from dir

validateSource(source: TemplateSource): ValidationResult
// dry-run: returns errors without producing output

Error types

  • CompilerError with a code field (INVALID_TEMPLATE_JSON, INVALID_METADATA, MISSING_PREVIEW_VARIABLE, RENDER_FAILURE)

Constraints

  • No Azure dependencies. The compiler must run in any Node.js 20+ environment.
  • compile() must be deterministic: same input → same output (no timestamps in content hash input).
  • Do not reach into apps/api internals.
  • ContentHash must be computed from the compiled HTML only — not from source files.
  • Manifest compiledAt is a timestamp (ISO 8601); sourceCommit is injected by the caller (defaults to empty string if not provided).

Test fixtures

Include at minimum:

  • marketing.contact-us — subject with {{name}}, body with name, email, message
  • A fixture with a missing preview variable (expect MISSING_PREVIEW_VARIABLE error)
  • A fixture with malformed metadata.json (expect INVALID_METADATA error)

Acceptance criteria

  • compile() produces a CompiledTemplate matching the types in @singleton-sd/post-kit-types.
  • compileFromDirectory() reads the three source files from a directory and delegates to compile().
  • Missing preview variables fail with MISSING_PREVIEW_VARIABLE.
  • Malformed source files fail with the appropriate error code.
  • compile() is deterministic (same input → identical HTML and contentHash).
  • Variable engine choice is documented in README with the version pinned.
  • pnpm -r --if-present run test passes including this package.
  • Package is configured for public npm publication.

Agent implementation notes

Check whether @usewaypoint/email-builder is already in the monorepo (look in packages/post-kit-email/package.json and root package.json). Read the packages/post-kit-email package structure before scaffolding — follow its tsconfig and package.json conventions. Branch: feat/N-post-kit-compiler (use actual issue number).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyMeets every criterion in docs/github-source-of-truth.md, section 4 — safe for an agent to claimenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions