Skip to content

Commit

Permalink
feat(string casing): add ablility to utilitze different string casing…
Browse files Browse the repository at this point in the history
… in files
  • Loading branch information
pnarielwala committed Nov 8, 2021
1 parent 9f33314 commit 6b03cbe
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 29 deletions.
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ $ npx template-files-generator

## Configuration

`tfgconfig.json`

```json
// tfgconfig.json
{
"templates": {
"custom-component": {
"name": "My Custom Component",
"directory": "./templates/custom-component",
"variables": {
"componentName": {
"displayName": "Component name?"
"prompt": "Component name?"
}
}
},
Expand All @@ -44,18 +45,15 @@ $ npx template-files-generator
"directory": "./internal/templates/custom-component",
"variables": {
"componentName": {
"displayName": "Component name?"
"prompt": "Component name?",
"defaultCase": "camel"
}
}
}
}
}
```

### TODO
## Inspriation

- [x] allow for config path
- [x] package for npm module
- [x] be able to install globally in development
- [ ] clean up readme
- [x] publish package
Partially inspired by the [generate-template-files](https://www.npmjs.com/package/generate-template-files) tool, but was looking for a simpler approach without having to write much configuration in javascript. But check out [generate-template-files](https://www.npmjs.com/package/generate-template-files) for a more robust and configurable template file generator!
101 changes: 81 additions & 20 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,33 @@ import copy from 'copy-template-dir';
import path from 'path';
import inquirer from 'inquirer';
import fs from 'fs';
import _ from 'lodash';
import _, {
camelCase,
startCase,
snakeCase,
kebabCase,
lowerCase,
upperCase,
upperFirst,
} from 'lodash';
import os from 'os';
import prettier from 'prettier';
import fse from 'fs-extra';

import Validator from 'validatorjs';
import { Config, StringCase, Template } from 'types';

const STRING_CASES: Array<StringCase> = [
'snake',
'pascal',
'camel',
'lower',
'dot',
'kebab',
'sentence',
'title',
'path',
];

const fetchConfigPath = () => {
/**
Expand Down Expand Up @@ -76,6 +97,7 @@ const validateConfig = (config: Config): boolean => {

const variableRules = {
prompt: 'required|string',
defaultCase: `in:${STRING_CASES.join(',')}`,
};

const configValidator = new Validator(config, configRules);
Expand Down Expand Up @@ -211,24 +233,6 @@ const initializeTemplateDir = () => {
return templateDir;
};

type Variable = {
prompt: string;
};

type Template = {
name: string;
directory: string;
variables: {
[variable: string]: Variable;
};
};

type Config = {
templates: {
[key: string]: Template;
};
};

const fetchTemplateOptions = (config: Config): Array<[string, string]> => {
/**
* use config object to return template options
Expand All @@ -240,6 +244,29 @@ const fetchTemplateOptions = (config: Config): Array<[string, string]> => {
});
};

const transformCase = (value: string, caseing: StringCase) => {
switch (caseing) {
case 'camel':
return camelCase(value);
case 'snake':
return snakeCase(value);
case 'pascal':
return startCase(camelCase(value)).replace(/ /g, '');
case 'kebab':
return kebabCase(value);
case 'dot':
return lowerCase(value).replace(/ /g, '.');
case 'path':
return lowerCase(value).replace(/ /g, '/');
case 'title':
return startCase(camelCase(value));
case 'sentence':
return upperFirst(lowerCase(value));
case 'lower':
return lowerCase(value).replace(/ /g, '');
}
};

const recordTemplateValues = async (template: Template) => {
/**
* prompt and record values for specific template
Expand All @@ -249,10 +276,37 @@ const recordTemplateValues = async (template: Template) => {
type: 'input',
name: variable,
message: prompt,
validate: (input) => {
if (input === undefined || input === '') {
return false;
} else {
return true;
}
},
})),
);

return variables;
const sideCarVariables = Object.entries(variables).reduce(
(acc, [variable, value]) => {
const defaultCase = template.variables[variable].defaultCase;
return {
...acc,
[variable]: transformCase(String(value), defaultCase ?? 'pascal'),
[`${variable}_pascal`]: transformCase(String(value), 'pascal'),
[`${variable}_camel`]: transformCase(String(value), 'camel'),
[`${variable}_snake`]: transformCase(String(value), 'snake'),
[`${variable}_kebab`]: transformCase(String(value), 'kebab'),
[`${variable}_lower`]: transformCase(String(value), 'lower'),
[`${variable}_sentence`]: transformCase(String(value), 'sentence'),
[`${variable}_title`]: transformCase(String(value), 'title'),
[`${variable}_path`]: transformCase(String(value), 'path'),
[`${variable}_dot`]: transformCase(String(value), 'dot'),
};
},
{},
);

return sideCarVariables;
};

const generateTemplateFiles = () => {
Expand Down Expand Up @@ -347,6 +401,13 @@ export const runCmd = async () => {
name: 'location',
message: 'Where do you want to generate it? (e.g. src/components)',
filter: (input) => _.trim(input, '/'), // trim leading/trailing whitespace and slashes
validate: (input) => {
if (input === undefined || input === '') {
return false;
} else {
return true;
}
},
});

const variables = await recordTemplateValues(
Expand Down
29 changes: 29 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export type StringCase =
| 'snake'
| 'pascal'
| 'camel'
| 'lower'
| 'dot'
| 'kebab'
| 'sentence'
| 'title'
| 'path';

export type Variable = {
prompt: string;
defaultCase?: StringCase;
};

export type Template = {
name: string;
directory: string;
variables: {
[variable: string]: Variable;
};
};

export type Config = {
templates: {
[key: string]: Template;
};
};

0 comments on commit 6b03cbe

Please sign in to comment.