Compare commits
No commits in common. "732b9944d66f40b9276ecc30cb0426f86212743a" and "6dc7ad86083cb5153b27b28764404ddc05742e66" have entirely different histories.
732b9944d6
...
6dc7ad8608
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -5,9 +5,6 @@ node_modules
|
||||||
pub/client/index.js
|
pub/client/index.js
|
||||||
toes/
|
toes/
|
||||||
|
|
||||||
# generated
|
|
||||||
src/lib/templates.data.ts
|
|
||||||
|
|
||||||
# output
|
# output
|
||||||
out
|
out
|
||||||
dist
|
dist
|
||||||
|
|
|
||||||
|
|
@ -555,10 +555,6 @@ app.on('GET', ['/:repo{.+\\.git}/info/refs', '/:repo/info/refs'], async c => {
|
||||||
return c.text('Invalid service', 400)
|
return c.text('Invalid service', 400)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service === 'git-receive-pack' && c.req.header('x-sneaker')) {
|
|
||||||
return c.text('Push access denied over sneaker', 403)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (service === 'git-receive-pack') {
|
if (service === 'git-receive-pack') {
|
||||||
await ensureBareRepo(repoParam)
|
await ensureBareRepo(repoParam)
|
||||||
}
|
}
|
||||||
|
|
@ -590,10 +586,6 @@ app.on('POST', ['/:repo{.+\\.git}/git-upload-pack', '/:repo/git-upload-pack'], a
|
||||||
|
|
||||||
// POST /:repo[.git]/git-receive-pack
|
// POST /:repo[.git]/git-receive-pack
|
||||||
app.on('POST', ['/:repo{.+\\.git}/git-receive-pack', '/:repo/git-receive-pack'], async c => {
|
app.on('POST', ['/:repo{.+\\.git}/git-receive-pack', '/:repo/git-receive-pack'], async c => {
|
||||||
if (c.req.header('x-sneaker')) {
|
|
||||||
return c.text('Push access denied over sneaker', 403)
|
|
||||||
}
|
|
||||||
|
|
||||||
const repoParam = c.req.param('repo').replace(/\.git$/, '')
|
const repoParam = c.req.param('repo').replace(/\.git$/, '')
|
||||||
|
|
||||||
if (!validRepoName(repoParam)) {
|
if (!validRepoName(repoParam)) {
|
||||||
|
|
|
||||||
8
bun.lock
8
bun.lock
|
|
@ -7,7 +7,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@because/forge": "^0.0.1",
|
"@because/forge": "^0.0.1",
|
||||||
"@because/hype": "^0.0.2",
|
"@because/hype": "^0.0.2",
|
||||||
"@because/sneaker": "^0.0.4",
|
"@because/sneaker": "^0.0.3",
|
||||||
"commander": "14.0.3",
|
"commander": "14.0.3",
|
||||||
"diff": "^8.0.3",
|
"diff": "^8.0.3",
|
||||||
"kleur": "^4.1.5",
|
"kleur": "^4.1.5",
|
||||||
|
|
@ -26,15 +26,15 @@
|
||||||
|
|
||||||
"@because/hype": ["@because/hype@0.0.2", "https://npm.nose.space/@because/hype/-/hype-0.0.2.tgz", { "dependencies": { "hono": "^4.10.4", "kleur": "^4.1.5" }, "peerDependencies": { "typescript": "^5" } }, "sha512-fdKeII6USGC1loVVj+tPz086cKz+Bm+XozNee3NOnK4VP+q4yNPP2Fq1Yujw5xeDYE+ZvJn40gKwlngRvmX2hA=="],
|
"@because/hype": ["@because/hype@0.0.2", "https://npm.nose.space/@because/hype/-/hype-0.0.2.tgz", { "dependencies": { "hono": "^4.10.4", "kleur": "^4.1.5" }, "peerDependencies": { "typescript": "^5" } }, "sha512-fdKeII6USGC1loVVj+tPz086cKz+Bm+XozNee3NOnK4VP+q4yNPP2Fq1Yujw5xeDYE+ZvJn40gKwlngRvmX2hA=="],
|
||||||
|
|
||||||
"@because/sneaker": ["@because/sneaker@0.0.4", "https://npm.nose.space/@because/sneaker/-/sneaker-0.0.4.tgz", { "dependencies": { "hono": "^4.9.8", "unique-names-generator": "^4.7.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-juklirqLPOzCQTlY3Vf6elXO7bPTEfc1QB4ephdWONZwllovtAEF4H0O6CoOcoV5g5P0i8qUu+ffNVqtkC3SBw=="],
|
"@because/sneaker": ["@because/sneaker@0.0.3", "https://npm.nose.space/@because/sneaker/-/sneaker-0.0.3.tgz", { "dependencies": { "hono": "^4.9.8", "unique-names-generator": "^4.7.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-4cG8w/tYPGbDtLw89k1PiASJKfWUdd1NXv+GKad2d7Ckw3FpZ+dnN2+gR2ihs81dqAkNaZomo+9RznBju2WaOw=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.3.10", "https://npm.nose.space/@types/bun/-/bun-1.3.10.tgz", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
"@types/bun": ["@types/bun@1.3.9", "https://npm.nose.space/@types/bun/-/bun-1.3.9.tgz", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
|
||||||
|
|
||||||
"@types/diff": ["@types/diff@8.0.0", "https://npm.nose.space/@types/diff/-/diff-8.0.0.tgz", { "dependencies": { "diff": "*" } }, "sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw=="],
|
"@types/diff": ["@types/diff@8.0.0", "https://npm.nose.space/@types/diff/-/diff-8.0.0.tgz", { "dependencies": { "diff": "*" } }, "sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@25.2.3", "https://npm.nose.space/@types/node/-/node-25.2.3.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="],
|
"@types/node": ["@types/node@25.2.3", "https://npm.nose.space/@types/node/-/node-25.2.3.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.10", "https://npm.nose.space/bun-types/-/bun-types-1.3.10.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
|
"bun-types": ["bun-types@1.3.9", "https://npm.nose.space/bun-types/-/bun-types-1.3.9.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
||||||
|
|
||||||
"commander": ["commander@14.0.3", "https://npm.nose.space/commander/-/commander-14.0.3.tgz", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
|
"commander": ["commander@14.0.3", "https://npm.nose.space/commander/-/commander-14.0.3.tgz", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
"toes": "src/cli/index.ts"
|
"toes": "src/cli/index.ts"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "bun run templates && bunx tsc --noEmit",
|
"check": "bunx tsc --noEmit",
|
||||||
"build": "./scripts/build.sh",
|
"build": "./scripts/build.sh",
|
||||||
"cli:build": "bun run scripts/build.ts",
|
"cli:build": "bun run scripts/build.ts",
|
||||||
"cli:build:all": "bun run scripts/build.ts --all",
|
"cli:build:all": "bun run scripts/build.ts --all",
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
"cli:uninstall": "sudo rm /usr/local/bin",
|
"cli:uninstall": "sudo rm /usr/local/bin",
|
||||||
"deploy": "./scripts/deploy.sh",
|
"deploy": "./scripts/deploy.sh",
|
||||||
"debug": "DEBUG=1 bun run dev",
|
"debug": "DEBUG=1 bun run dev",
|
||||||
"dev": "bun run templates && rm -f pub/client/index.js && bun run --hot src/server/index.tsx",
|
"dev": "rm -f pub/client/index.js && bun run --hot src/server/index.tsx",
|
||||||
"remote:deploy": "./scripts/deploy.sh",
|
"remote:deploy": "./scripts/deploy.sh",
|
||||||
"remote:migrate": "bun run scripts/migrate.ts",
|
"remote:migrate": "bun run scripts/migrate.ts",
|
||||||
"remote:install": "./scripts/remote-install.sh",
|
"remote:install": "./scripts/remote-install.sh",
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
"remote:start": "./scripts/remote-start.sh",
|
"remote:start": "./scripts/remote-start.sh",
|
||||||
"remote:stop": "./scripts/remote-stop.sh",
|
"remote:stop": "./scripts/remote-stop.sh",
|
||||||
"start": "bun run src/server/index.tsx",
|
"start": "bun run src/server/index.tsx",
|
||||||
"templates": "bun run scripts/embed-templates.ts",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -46,7 +45,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@because/forge": "^0.0.1",
|
"@because/forge": "^0.0.1",
|
||||||
"@because/hype": "^0.0.2",
|
"@because/hype": "^0.0.2",
|
||||||
"@because/sneaker": "^0.0.4",
|
"@because/sneaker": "^0.0.3",
|
||||||
"commander": "14.0.3",
|
"commander": "14.0.3",
|
||||||
"diff": "^8.0.3",
|
"diff": "^8.0.3",
|
||||||
"kleur": "^4.1.5"
|
"kleur": "^4.1.5"
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,47 @@ const TARGETS: BuildTarget[] = [
|
||||||
{ os: 'linux', arch: 'x64', name: 'toes-linux-x64' },
|
{ os: 'linux', arch: 'x64', name: 'toes-linux-x64' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Ensure dist directory exists
|
||||||
|
if (!existsSync(DIST_DIR)) {
|
||||||
|
mkdirSync(DIST_DIR, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse command line args
|
||||||
|
const args = process.argv.slice(2)
|
||||||
|
const buildAll = args.includes('--all')
|
||||||
|
const targetArg = args.find(arg => arg.startsWith('--target='))?.split('=')[1]
|
||||||
|
|
||||||
|
async function buildTarget(target: BuildTarget) {
|
||||||
|
console.log(`Building ${target.name}...`)
|
||||||
|
|
||||||
|
const output = join(DIST_DIR, target.name)
|
||||||
|
|
||||||
|
const proc = Bun.spawn([
|
||||||
|
'bun',
|
||||||
|
'build',
|
||||||
|
ENTRY_POINT,
|
||||||
|
'--compile',
|
||||||
|
'--target',
|
||||||
|
`bun-${target.os}-${target.arch}`,
|
||||||
|
'--minify',
|
||||||
|
'--sourcemap=external',
|
||||||
|
'--outfile',
|
||||||
|
output,
|
||||||
|
], {
|
||||||
|
stdout: 'inherit',
|
||||||
|
stderr: 'inherit',
|
||||||
|
})
|
||||||
|
|
||||||
|
const exitCode = await proc.exited
|
||||||
|
|
||||||
|
if (exitCode === 0) {
|
||||||
|
console.log(`✓ Built ${target.name}`)
|
||||||
|
} else {
|
||||||
|
console.error(`✗ Failed to build ${target.name}`)
|
||||||
|
process.exit(exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function buildCurrent() {
|
async function buildCurrent() {
|
||||||
const platform = process.platform
|
const platform = process.platform
|
||||||
const arch = process.arch
|
const arch = process.arch
|
||||||
|
|
@ -59,57 +100,6 @@ async function buildCurrent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildTarget(target: BuildTarget) {
|
|
||||||
console.log(`Building ${target.name}...`)
|
|
||||||
|
|
||||||
const output = join(DIST_DIR, target.name)
|
|
||||||
|
|
||||||
const proc = Bun.spawn([
|
|
||||||
'bun',
|
|
||||||
'build',
|
|
||||||
ENTRY_POINT,
|
|
||||||
'--compile',
|
|
||||||
'--target',
|
|
||||||
`bun-${target.os}-${target.arch}`,
|
|
||||||
'--minify',
|
|
||||||
'--sourcemap=external',
|
|
||||||
'--outfile',
|
|
||||||
output,
|
|
||||||
], {
|
|
||||||
stdout: 'inherit',
|
|
||||||
stderr: 'inherit',
|
|
||||||
})
|
|
||||||
|
|
||||||
const exitCode = await proc.exited
|
|
||||||
|
|
||||||
if (exitCode === 0) {
|
|
||||||
console.log(`✓ Built ${target.name}`)
|
|
||||||
} else {
|
|
||||||
console.error(`✗ Failed to build ${target.name}`)
|
|
||||||
process.exit(exitCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Embed template files before compiling
|
|
||||||
const embedProc = Bun.spawn(['bun', 'run', join(import.meta.dir, 'embed-templates.ts')], {
|
|
||||||
stdout: 'inherit',
|
|
||||||
stderr: 'inherit',
|
|
||||||
})
|
|
||||||
if (await embedProc.exited !== 0) {
|
|
||||||
console.error('✗ Failed to embed templates')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure dist directory exists
|
|
||||||
if (!existsSync(DIST_DIR)) {
|
|
||||||
mkdirSync(DIST_DIR, { recursive: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse command line args
|
|
||||||
const args = process.argv.slice(2)
|
|
||||||
const buildAll = args.includes('--all')
|
|
||||||
const targetArg = args.find(arg => arg.startsWith('--target='))?.split('=')[1]
|
|
||||||
|
|
||||||
// Main build logic
|
// Main build logic
|
||||||
if (buildAll) {
|
if (buildAll) {
|
||||||
console.log('Building for all targets...\n')
|
console.log('Building for all targets...\n')
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
#!/usr/bin/env bun
|
|
||||||
// Generates src/lib/templates.data.ts with embedded template file contents.
|
|
||||||
// Run: bun run templates
|
|
||||||
import { readdirSync, readFileSync, statSync } from 'fs'
|
|
||||||
import { extname, join, relative } from 'path'
|
|
||||||
|
|
||||||
const BINARY_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot', '.svg'])
|
|
||||||
const TEMPLATES_DIR = join(import.meta.dir, '..', 'templates')
|
|
||||||
|
|
||||||
const binary: Record<string, Record<string, string>> = {}
|
|
||||||
const shared: Record<string, string> = {}
|
|
||||||
const templates: Record<string, Record<string, string>> = {}
|
|
||||||
|
|
||||||
const isBinary = (path: string) =>
|
|
||||||
BINARY_EXTENSIONS.has(extname(path))
|
|
||||||
|
|
||||||
function readDir(dir: string): string[] {
|
|
||||||
const files: string[] = []
|
|
||||||
for (const entry of readdirSync(dir)) {
|
|
||||||
const path = join(dir, entry)
|
|
||||||
if (statSync(path).isDirectory()) {
|
|
||||||
files.push(...readDir(path))
|
|
||||||
} else {
|
|
||||||
files.push(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return files.sort()
|
|
||||||
}
|
|
||||||
|
|
||||||
// First pass: collect shared files (root level)
|
|
||||||
for (const entry of readdirSync(TEMPLATES_DIR).sort()) {
|
|
||||||
const path = join(TEMPLATES_DIR, entry)
|
|
||||||
if (!statSync(path).isDirectory()) {
|
|
||||||
shared[entry] = readFileSync(path, 'utf-8')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second pass: build template maps with shared files folded in
|
|
||||||
for (const entry of readdirSync(TEMPLATES_DIR).sort()) {
|
|
||||||
const path = join(TEMPLATES_DIR, entry)
|
|
||||||
if (statSync(path).isDirectory()) {
|
|
||||||
templates[entry] = { ...shared }
|
|
||||||
binary[entry] = {}
|
|
||||||
for (const filePath of readDir(path)) {
|
|
||||||
const filename = relative(path, filePath)
|
|
||||||
if (isBinary(filePath)) {
|
|
||||||
binary[entry]![filename] = readFileSync(filePath).toString('base64')
|
|
||||||
} else {
|
|
||||||
templates[entry]![filename] = readFileSync(filePath, 'utf-8')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Object.keys(binary[entry]!).length === 0) {
|
|
||||||
delete binary[entry]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate TypeScript module
|
|
||||||
const lines: string[] = [
|
|
||||||
'// Auto-generated by scripts/embed-templates.ts',
|
|
||||||
'// Run `bun run templates` to regenerate',
|
|
||||||
'',
|
|
||||||
`export const TEMPLATES: Record<string, Record<string, string>> = ${JSON.stringify(templates, null, 2)}`,
|
|
||||||
'',
|
|
||||||
`export const BINARY: Record<string, Record<string, string>> = ${JSON.stringify(binary, null, 2)}`,
|
|
||||||
'',
|
|
||||||
]
|
|
||||||
|
|
||||||
const outPath = join(import.meta.dir, '..', 'src', 'lib', 'templates.data.ts')
|
|
||||||
await Bun.write(outPath, lines.join('\n'))
|
|
||||||
console.log(`✓ Embedded templates → ${relative(join(import.meta.dir, '..'), outPath)}`)
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { DEFAULT_EMOJI } from '@types'
|
import { DEFAULT_EMOJI } from '@types'
|
||||||
|
import { readdirSync, readFileSync, statSync } from 'fs'
|
||||||
import { BINARY, TEMPLATES } from './templates.data'
|
import { join, relative } from 'path'
|
||||||
|
|
||||||
export type TemplateType = 'ssr' | 'bare' | 'spa'
|
export type TemplateType = 'ssr' | 'bare' | 'spa'
|
||||||
|
|
||||||
export type AppTemplates = Record<string, string | Uint8Array>
|
export type AppTemplates = Record<string, string>
|
||||||
|
|
||||||
interface TemplateOptions {
|
interface TemplateOptions {
|
||||||
tool?: boolean
|
tool?: boolean
|
||||||
|
|
@ -15,6 +15,28 @@ interface TemplateVars {
|
||||||
APP_NAME: string
|
APP_NAME: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHARED_FILES = ['CLAUDE.md', '.gitignore', '.npmrc', 'package.json', 'tsconfig.json']
|
||||||
|
const TEMPLATES_DIR = join(import.meta.dir, '../../templates')
|
||||||
|
|
||||||
|
function readDir(dir: string): string[] {
|
||||||
|
const files: string[] = []
|
||||||
|
for (const entry of readdirSync(dir)) {
|
||||||
|
const path = join(dir, entry)
|
||||||
|
if (statSync(path).isDirectory()) {
|
||||||
|
files.push(...readDir(path))
|
||||||
|
} else {
|
||||||
|
files.push(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceVars(content: string, vars: TemplateVars): string {
|
||||||
|
return content
|
||||||
|
.replace(/\$\$APP_NAME\$\$/g, vars.APP_NAME)
|
||||||
|
.replace(/\$\$APP_EMOJI\$\$/g, vars.APP_EMOJI)
|
||||||
|
}
|
||||||
|
|
||||||
export function generateTemplates(appName: string, template: TemplateType = 'ssr', options: TemplateOptions = {}): AppTemplates {
|
export function generateTemplates(appName: string, template: TemplateType = 'ssr', options: TemplateOptions = {}): AppTemplates {
|
||||||
const vars: TemplateVars = {
|
const vars: TemplateVars = {
|
||||||
APP_EMOJI: DEFAULT_EMOJI,
|
APP_EMOJI: DEFAULT_EMOJI,
|
||||||
|
|
@ -23,29 +45,29 @@ export function generateTemplates(appName: string, template: TemplateType = 'ssr
|
||||||
|
|
||||||
const result: AppTemplates = {}
|
const result: AppTemplates = {}
|
||||||
|
|
||||||
// Text files (shared + template-specific, merged at embed time)
|
// Read shared files from templates/
|
||||||
for (const [filename, content] of Object.entries(TEMPLATES[template] ?? {})) {
|
for (const filename of SHARED_FILES) {
|
||||||
let processed = replaceVars(content, vars)
|
const path = join(TEMPLATES_DIR, filename)
|
||||||
|
let content = readFileSync(path, 'utf-8')
|
||||||
|
content = replaceVars(content, vars)
|
||||||
|
|
||||||
|
// Add tool option to package.json if specified
|
||||||
if (filename === 'package.json' && options.tool) {
|
if (filename === 'package.json' && options.tool) {
|
||||||
const pkg = JSON.parse(processed)
|
const pkg = JSON.parse(content)
|
||||||
pkg.toes.tool = true
|
pkg.toes.tool = true
|
||||||
processed = JSON.stringify(pkg, null, 2) + '\n'
|
content = JSON.stringify(pkg, null, 2) + '\n'
|
||||||
}
|
}
|
||||||
|
|
||||||
result[filename] = processed
|
result[filename] = content
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary files (base64 encoded)
|
// Read template-specific files
|
||||||
for (const [filename, base64] of Object.entries(BINARY[template] ?? {})) {
|
const templateDir = join(TEMPLATES_DIR, template)
|
||||||
result[filename] = Buffer.from(base64, 'base64')
|
for (const path of readDir(templateDir)) {
|
||||||
|
const filename = relative(templateDir, path)
|
||||||
|
const content = readFileSync(path, 'utf-8')
|
||||||
|
result[filename] = replaceVars(content, vars)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceVars(content: string, vars: TemplateVars): string {
|
|
||||||
return content
|
|
||||||
.replace(/\$\$APP_NAME\$\$/g, vars.APP_NAME)
|
|
||||||
.replace(/\$\$APP_EMOJI\$\$/g, vars.APP_EMOJI)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user