File Generator
How to setup
# To start in dev mode (builds and runs the script)
pnpm dev
# To build script
pnpm build
# To start from the built file
pnpm start
How it works
To add a template file create a file in the configured templates directory (you can change it from the src/config/index.ts
file it defaults to templates
). subdirectories will be separated with a dash (-) for the template name.
Any file with the name "base" it'll take its parent directory's name. You can change "base" in the config file.
Example
A file tree like this (assuming the template
directory is the root directory for templates)
templates
├─ license
│ ├── MIT
│ └── WTFPL
├─ lit
│ └── base.ts
└─ vue
└── base.vue
The templates names will resolve to
- license-mit
- license-wtfpl
- lit
- vue
After creating a file inside the templates directory that's all you'll need to define a template. But you can add more configs to the src/config/templates.ts
file, more on that here.
Now you can run fg -t <template-name>
from anywhere and it'll create that file in the CWD.
Cli options
-
Template: to select a template you can pass its name to the
--template
or-t
flag. -
Destination: you can change the destination of the generated file by adding
--dest
or-d
followed by the target location.
More Configuration
By default you don't need to add any configuration. But most of the time generating a file isn't enough; you'd need to change the content or the filename itself.
You can do this easily by adding configuration for the template inside src/config/templates.ts
. You can add props
to pass down to the template file, defaultFilename
to add a dynamic or static default filename, and/or defaultDist
to define the relative dist the file should be created in.
Props
GF ejs templating engine, to resolve the passed props.
Props options
-
default
the default value for the property. -
shouldAsk
whether should prompt for this property or just fallback to the default value. If it's not defined it'll default totrue
. -
hint
add a hint to show on prompting to collect the property value. -
type
the needed input type. You can set it toinput
,confirm
,number
, orpassword
. It defaults toinput
. -
validator
a validator function that takes the input value as it's argument and return aboolean
value to validate the input.
None of the property options are required.
Pass props to a template
Assuming you have template/template-name.ext
template file created, and defined as follows
templates/template-name.ext
<%= name %>
<% if (email) { %><%= email %><% } %>
<%= date %>
src/config/template.ts
const templatesConfig: TemplateConfig = {
"template-name": {
props: {
name: {
hint: "in kebab-case",
validator: (v: string) => !!v.match(/^[a-z][a-z1-9-]+$/),
}
email: {
validator: (v) => validateEmail(v)
},
date: { shouldAsk: false, default: new Date().getFullYear() },
},
},
};
Passing Props
After selecting the template
gf -t template-name
You will get prompt to pass the enter the required values.
This will generate the template as follows
foo
bar@baz.com
2022
or what ever the year you're testing this in.
Template Utils
By default there are utility functions that'll be passed to the templates generator. But you can extend them to you're own custom functions.
Provided utility functions
-
CaseConvertor.kebabToPascal
: will convert kebab-case string to PascalCase. -
CaseConvertor.kebabToCamel
: will convert kebab-case string to camelCase. -
CaseConvertor.kebabToLazy
: will convert kebab-case string to lazycase. -
CaseConvertor.kebabToSnake
: will convert kebab-case string to snake_case. -
CaseConvertor.kebabToScreamingSnake
: will convert kebab-case string to SCREAMING_SNAKE_CASE.
Create your own utils
To pass down a utility all you need to do is to export it from src/config/templates-utils.ts
.
How to use them
You just use them as normal functions
<%= CaseConvertor.kebabToPascal(name) %>
If provided name property was "foo-bar" it'll resolve to
FooBar
Default Filename
Syntax
- Any text surrounded by {} will be resolved from the provided props.
- Because most of the provided data will be passed in kebab-case, you can change the case from kebab-case by adding a comma and a one of these values
-
c
for camelCase -
p
for PascalCase -
l
for lazycase -
s
for snake_case -
ss
for SCREAMING_SNAKE_CASE
-
Examples
const templatesConfig: TemplateConfig = {
"template-name": {
props: {
name: {
hint: "in kebab-case",
validator: (v: string) => !!v.match(/^[a-z][a-z1-9-]+$/),
}
},
defaultFilename: "{name,p}",
},
};
/*
Assuming
- the name's value will always be foo-bar.
- ext is the current template extension.
This is how the filename will be resolved
defaultFilename: "{name}"
filename -> foo-bar.ext
defaultFilename: "{name,p}"
filename -> FooBar.ext
defaultFilename: "{name,c}"
filename -> fooBar.ext
defaultFilename: "{name}.controller"
filename -> foo-bar.controller.ext
defaultFilename: "name"
filename -> name.ext
// No defaultFilename provided
filename -> template-name.ext
*/
Default Distention
Instead of having to provide the distention every time you create a file you can provide a default distention to create the file in.
All you have to do is to add defaultDist
to the template options.
const templatesConfig: TemplateConfig = {
"template-name": {
props: {
name: {
hint: "in kebab-case",
validator: (v: string) => !!v.match(/^[a-z][a-z1-9-]+$/),
}
},
defaultFilename: "{name,p}",
// -- here -- //
defaultDist: path.join(process.cwd(), "src", "models"),
},
}
After defining this every time you create a template-name
template it'll be generated to a models
directory inside the src
directory.
Config File
You can override the default dist for files for a project's scope by creating file-generator.yaml
to the project's root.
Schema
The config file schema is provided at schema/config.json
.
# yaml-language-server: $schema=./schema/config.json
default-dist: "./src"
templates:
template-name:
dist: "./src/model"
Options
-
default-dist
where the file will be generated if it's dist wasn't defined. -
templates
where each template option will be overridden. -
template-name
the template you want to override. -
dist
the default dist for that specific template.
Change File Name, Location, or Extension
From src/config/index.ts
you can change settings from configFile
to change the file location and name.
- To change the default file location change
FILE_LOCATION
. - To change the file name to search and retrieve settings from change
FILENAME
. - To use
json
orjsonc
instead ofyaml
you can changeFILE_TYPE
to the extension you want to use.
License
MIT.