Files
gh-vanman2024-cli-builder-p…/skills/gluegun-patterns/scripts/template-helpers.ts
2025-11-30 09:04:14 +08:00

251 lines
5.1 KiB
TypeScript

/**
* Template Helper Functions for Gluegun
* Useful utilities for EJS templates
*/
/**
* String case conversions
*/
export const caseConverters = {
/**
* Convert to PascalCase
* Example: "hello-world" => "HelloWorld"
*/
pascalCase: (str: string): string => {
return str
.replace(/[-_\s](.)/g, (_, char) => char.toUpperCase())
.replace(/^(.)/, (_, char) => char.toUpperCase())
},
/**
* Convert to camelCase
* Example: "hello-world" => "helloWorld"
*/
camelCase: (str: string): string => {
return str
.replace(/[-_\s](.)/g, (_, char) => char.toUpperCase())
.replace(/^(.)/, (_, char) => char.toLowerCase())
},
/**
* Convert to kebab-case
* Example: "HelloWorld" => "hello-world"
*/
kebabCase: (str: string): string => {
return str
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/[\s_]+/g, '-')
.toLowerCase()
},
/**
* Convert to snake_case
* Example: "HelloWorld" => "hello_world"
*/
snakeCase: (str: string): string => {
return str
.replace(/([a-z])([A-Z])/g, '$1_$2')
.replace(/[\s-]+/g, '_')
.toLowerCase()
},
/**
* Convert to Title Case
* Example: "hello world" => "Hello World"
*/
titleCase: (str: string): string => {
return str
.toLowerCase()
.split(/[\s-_]+/)
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')
}
}
/**
* Pluralization helpers
*/
export const pluralize = {
/**
* Simple pluralization
*/
plural: (word: string): string => {
if (word.endsWith('y')) {
return word.slice(0, -1) + 'ies'
}
if (word.endsWith('s') || word.endsWith('x') || word.endsWith('z')) {
return word + 'es'
}
return word + 's'
},
/**
* Simple singularization
*/
singular: (word: string): string => {
if (word.endsWith('ies')) {
return word.slice(0, -3) + 'y'
}
if (word.endsWith('es')) {
return word.slice(0, -2)
}
if (word.endsWith('s')) {
return word.slice(0, -1)
}
return word
}
}
/**
* File path helpers
*/
export const pathHelpers = {
/**
* Convert name to file path
* Example: "UserProfile" => "user-profile.ts"
*/
toFilePath: (name: string, extension: string = 'ts'): string => {
const kebab = caseConverters.kebabCase(name)
return `${kebab}.${extension}`
},
/**
* Convert name to directory path
* Example: "UserProfile" => "user-profile"
*/
toDirPath: (name: string): string => {
return caseConverters.kebabCase(name)
}
}
/**
* Comment generators
*/
export const comments = {
/**
* Generate file header comment
*/
fileHeader: (filename: string, description: string, author?: string): string => {
const lines = [
'/**',
` * ${filename}`,
` * ${description}`,
]
if (author) {
lines.push(` * @author ${author}`)
}
lines.push(` * @generated ${new Date().toISOString()}`)
lines.push(' */')
return lines.join('\n')
},
/**
* Generate JSDoc comment
*/
jsDoc: (description: string, params?: Array<{ name: string; type: string; description: string }>, returns?: string): string => {
const lines = [
'/**',
` * ${description}`
]
if (params && params.length > 0) {
lines.push(' *')
params.forEach(param => {
lines.push(` * @param {${param.type}} ${param.name} - ${param.description}`)
})
}
if (returns) {
lines.push(' *')
lines.push(` * @returns {${returns}}`)
}
lines.push(' */')
return lines.join('\n')
}
}
/**
* Import statement generators
*/
export const imports = {
/**
* Generate TypeScript import
*/
typescript: (items: string[], from: string): string => {
if (items.length === 1) {
return `import { ${items[0]} } from '${from}'`
}
return `import {\n ${items.join(',\n ')}\n} from '${from}'`
},
/**
* Generate CommonJS require
*/
commonjs: (name: string, from: string): string => {
return `const ${name} = require('${from}')`
}
}
/**
* Code formatting helpers
*/
export const formatting = {
/**
* Indent text by specified spaces
*/
indent: (text: string, spaces: number = 2): string => {
const indent = ' '.repeat(spaces)
return text
.split('\n')
.map(line => indent + line)
.join('\n')
},
/**
* Wrap text in quotes
*/
quote: (text: string, style: 'single' | 'double' = 'single'): string => {
const quote = style === 'single' ? "'" : '"'
return `${quote}${text}${quote}`
}
}
/**
* Validation helpers
*/
export const validate = {
/**
* Check if string is valid identifier
*/
isValidIdentifier: (str: string): boolean => {
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str)
},
/**
* Check if string is valid package name
*/
isValidPackageName: (str: string): boolean => {
return /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(str)
}
}
/**
* All helpers combined for easy import
*/
export const helpers = {
...caseConverters,
pluralize,
pathHelpers,
comments,
imports,
formatting,
validate
}
export default helpers