115 lines
3.0 KiB
JavaScript
Executable File
115 lines
3.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import {
|
|
readFileSync,
|
|
writeFileSync,
|
|
mkdirSync,
|
|
readdirSync,
|
|
copyFileSync,
|
|
existsSync,
|
|
} from 'fs'
|
|
import { join, dirname } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const TEMPLATE_DIR = join(__dirname, '..', 'template')
|
|
|
|
const toKebabCase = (str) => {
|
|
return str
|
|
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
.replace(/[\s_]+/g, '-')
|
|
.toLowerCase()
|
|
}
|
|
|
|
const toPascalCase = (str) => {
|
|
return str
|
|
.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
|
|
.replace(/^./, (s) => s.toUpperCase())
|
|
}
|
|
|
|
const toTitleCase = (str) => {
|
|
return str
|
|
.replace(/[-_\s]+(.)?/g, (_, c) => (c ? ' ' + c.toUpperCase() : ''))
|
|
.replace(/^./, (s) => s.toUpperCase())
|
|
.replace(/\b\w/g, (c) => c.toUpperCase())
|
|
}
|
|
|
|
const replaceValues = (content, values) => {
|
|
return content.replace(/\$\{(.*?)\}/g, (_, key) => {
|
|
return values[key] ?? `\${${key}}`
|
|
})
|
|
}
|
|
|
|
const copyDir = (src, dest, values) => {
|
|
mkdirSync(dest, { recursive: true })
|
|
const entries = readdirSync(src, { withFileTypes: true })
|
|
|
|
for (const entry of entries) {
|
|
const srcPath = join(src, entry.name)
|
|
const destName = replaceValues(entry.name, values)
|
|
const destPath = join(dest, destName)
|
|
|
|
if (entry.isDirectory()) {
|
|
copyDir(srcPath, destPath, values)
|
|
} else {
|
|
copyFileSync(srcPath, destPath)
|
|
const content = readFileSync(destPath, 'utf8')
|
|
writeFileSync(destPath, replaceValues(content, values))
|
|
}
|
|
}
|
|
}
|
|
|
|
const prompt = async (question) => {
|
|
const readline = await import('readline')
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
})
|
|
return new Promise((resolve) => {
|
|
rl.question(question, (answer) => {
|
|
rl.close()
|
|
resolve(answer)
|
|
})
|
|
})
|
|
}
|
|
|
|
const main = async () => {
|
|
const name = await prompt('Plugin name: ')
|
|
const description = await prompt('Plugin description: ')
|
|
|
|
const trimmedName = name?.trim()
|
|
|
|
if (!trimmedName) {
|
|
console.error('Plugin name is required')
|
|
process.exit(1)
|
|
}
|
|
|
|
const kebab = toKebabCase(trimmedName)
|
|
const pascal = toPascalCase(trimmedName)
|
|
const title = toTitleCase(trimmedName)
|
|
|
|
const values = {
|
|
NAME_KEBAB_CASE: kebab,
|
|
NAME_PASCAL_CASE: pascal,
|
|
NAME_TITLE_CASE: title,
|
|
DESCRIPTION: description.trim(),
|
|
}
|
|
|
|
const destDir = join(process.cwd(), `takerofnotes-plugin-${kebab}`)
|
|
|
|
if (existsSync(destDir)) {
|
|
console.error(`Directory already exists: ${destDir}`)
|
|
process.exit(1)
|
|
}
|
|
|
|
copyDir(TEMPLATE_DIR, destDir, values)
|
|
|
|
console.log(`\nPlugin created: takerofnotes-plugin-${kebab}`)
|
|
console.log(`\nNext steps:`)
|
|
console.log(` cd takerofnotes-plugin-${kebab}`)
|
|
console.log(` npm install`)
|
|
console.log(` cat README.md`)
|
|
}
|
|
|
|
main()
|