← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
scripts/embed-starter.mjs
63 lines · 2.3 KB · JavaScript#!/usr/bin/env node
/**
* Embed starter-remix/ text files into src/starter-templates.ts for create-package-app.
* Excludes STARTER.md and binary assets (PWA icons served via kit iconPngResponse).
* Includes `.kody/icon.svg` (list/identity mark; packageSave is text-only — PNG via git lane).
*/
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const here = path.dirname(fileURLToPath(import.meta.url))
const pkg = path.resolve(here, '..')
const root = path.join(pkg, 'starter-remix')
const skipNames = new Set(['STARTER.md'])
const binaryExt = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.ico', '.woff', '.woff2'])
/** @type {Record<string, string>} */
const files = {}
function walk(dir, rel = '') {
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
// Include `.kody/` list-mark metadata; skip other dotfiles/dirs.
if (ent.name.startsWith('.') && ent.name !== '.kody') continue
const abs = path.join(dir, ent.name)
const r = rel ? `${rel}/${ent.name}` : ent.name
if (ent.isDirectory()) {
walk(abs, r)
continue
}
if (skipNames.has(ent.name)) continue
const ext = path.extname(ent.name).toLowerCase()
if (binaryExt.has(ext)) continue
files[r] = fs.readFileSync(abs, 'utf8')
}
}
walk(root)
const renames = {
'package.template.json': 'package.json',
'README.template.md': 'README.md',
'AGENTS.template.md': 'AGENTS.md',
}
const header = `/**
* Embedded copy of \`starter-remix/\` (excluding STARTER.md and binary icons) for the Worker scaffolder.
* Source of truth is the \`starter-remix/\` directory — regenerate via \`node scripts/embed-starter.mjs\` when it changes.
* Icons: scaffolded apps use kit \`iconPngResponse\` (no binary copy required).
*/
`
const body = Object.keys(files)
.sort()
.map((k) => `\t${JSON.stringify(k)}: ${JSON.stringify(files[k])},`)
.join('\n')
const renameBody = Object.entries(renames)
.map(([k, v]) => `\t${JSON.stringify(k)}: ${JSON.stringify(v)},`)
.join('\n')
const out = `${header}export const STARTER_FILES: Record<string, string> = {\n${body}\n}\n\nexport const STARTER_TEMPLATE_RENAMES: Record<string, string> = {\n${renameBody}\n}\n`
fs.writeFileSync(path.join(pkg, 'src/starter-templates.ts'), out)
console.log(`Embedded ${Object.keys(files).length} files from starter-remix/ → src/starter-templates.ts`)