simple-scaffold 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -120
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -28,196 +28,292 @@ of files you're generating.
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
> **Full documentation is available at
|
|
32
|
+
> [chenasraf.github.io/simple-scaffold](https://chenasraf.github.io/simple-scaffold)** — including
|
|
33
|
+
> detailed guides on [CLI usage](https://chenasraf.github.io/simple-scaffold/docs/usage/cli),
|
|
34
|
+
> [Node.js API](https://chenasraf.github.io/simple-scaffold/docs/usage/node),
|
|
35
|
+
> [templates](https://chenasraf.github.io/simple-scaffold/docs/usage/templates),
|
|
36
|
+
> [configuration files](https://chenasraf.github.io/simple-scaffold/docs/usage/configuration_files),
|
|
37
|
+
> [examples](https://chenasraf.github.io/simple-scaffold/docs/usage/examples), and
|
|
38
|
+
> [migration from v1/v2](https://chenasraf.github.io/simple-scaffold/docs/usage/migration).
|
|
39
|
+
|
|
40
|
+
## Table of Contents
|
|
41
|
+
|
|
42
|
+
- [Getting Started](#getting-started)
|
|
43
|
+
- [Configuration Files](#configuration-files)
|
|
44
|
+
- [Templates](#templates)
|
|
45
|
+
- [Interactive Mode & Inputs](#interactive-mode--inputs)
|
|
46
|
+
- [Remote Templates](#remote-templates)
|
|
47
|
+
- [CLI Reference](#cli-reference)
|
|
48
|
+
- [Node.js API](#nodejs-api)
|
|
49
|
+
- [Built-in Helpers](#built-in-helpers)
|
|
50
|
+
- [Contributing](#contributing)
|
|
32
51
|
|
|
33
|
-
|
|
52
|
+
## Getting Started
|
|
34
53
|
|
|
35
|
-
|
|
36
|
-
- [Node.js usage](https://chenasraf.github.io/simple-scaffold/docs/usage/node)
|
|
37
|
-
- [Templates](https://chenasraf.github.io/simple-scaffold/docs/usage/templates)
|
|
38
|
-
- [Configuration Files](https://chenasraf.github.io/simple-scaffold/docs/usage/configuration_files)
|
|
39
|
-
- [Migration](https://chenasraf.github.io/simple-scaffold/docs/usage/migration)
|
|
54
|
+
### Install
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
```sh
|
|
57
|
+
npm install -D simple-scaffold
|
|
58
|
+
# or use directly with npx
|
|
59
|
+
npx simple-scaffold
|
|
60
|
+
```
|
|
42
61
|
|
|
43
|
-
###
|
|
62
|
+
### Initialize a Project
|
|
44
63
|
|
|
45
|
-
|
|
64
|
+
Run `init` to create a config file and an example template:
|
|
46
65
|
|
|
47
66
|
```sh
|
|
48
67
|
npx simple-scaffold init
|
|
49
68
|
```
|
|
50
69
|
|
|
51
|
-
This creates
|
|
52
|
-
files with:
|
|
70
|
+
This creates `scaffold.config.js` and `templates/default/{{name}}.md`. Now generate files:
|
|
53
71
|
|
|
54
72
|
```sh
|
|
55
73
|
npx simple-scaffold MyProject
|
|
56
74
|
```
|
|
57
75
|
|
|
58
|
-
###
|
|
76
|
+
### One-off Usage (No Config)
|
|
59
77
|
|
|
60
|
-
|
|
78
|
+
Generate files from a template directory without a config file:
|
|
61
79
|
|
|
62
|
-
|
|
80
|
+
```sh
|
|
81
|
+
npx simple-scaffold -t templates/component -o src/components MyComponent
|
|
82
|
+
```
|
|
63
83
|
|
|
64
|
-
|
|
65
|
-
npx simple-scaffold -g username/repository -c scaffold.js -k component NewComponentName
|
|
66
|
-
```
|
|
84
|
+
## Configuration Files
|
|
67
85
|
|
|
68
|
-
|
|
86
|
+
Config files let you define reusable scaffold definitions. Simple Scaffold **auto-detects** config
|
|
87
|
+
files in the current directory — no `--config` flag needed.
|
|
69
88
|
|
|
70
|
-
|
|
71
|
-
npx simple-scaffold -c scaffold.js -k component NewComponentName
|
|
72
|
-
```
|
|
89
|
+
It searches for these files in order:
|
|
73
90
|
|
|
74
|
-
|
|
91
|
+
`scaffold.config.{mjs,cjs,js,json}`, `scaffold.{mjs,cjs,js,json}`, `.scaffold.{mjs,cjs,js,json}`
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
npx simple-scaffold -t templates/component -o src/components NewComponentName
|
|
78
|
-
```
|
|
93
|
+
### Example
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
```js
|
|
96
|
+
// scaffold.config.js
|
|
97
|
+
module.exports = {
|
|
98
|
+
component: {
|
|
99
|
+
templates: ["templates/component"],
|
|
100
|
+
output: "src/components",
|
|
101
|
+
},
|
|
102
|
+
page: {
|
|
103
|
+
templates: ["templates/page"],
|
|
104
|
+
output: "src/pages",
|
|
105
|
+
subdir: true,
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
```
|
|
81
109
|
|
|
82
|
-
|
|
83
|
-
repository.
|
|
110
|
+
Then run:
|
|
84
111
|
|
|
85
|
-
|
|
112
|
+
```sh
|
|
113
|
+
npx simple-scaffold -k component MyComponent
|
|
114
|
+
npx simple-scaffold -k page Dashboard
|
|
115
|
+
```
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
- For other Git platforms like GitLab, use `-g https://example.com/user/repository_name.git`
|
|
117
|
+
Use the key `default` to skip the `-k` flag entirely.
|
|
89
118
|
|
|
90
|
-
|
|
91
|
-
`--key` or `-k` argument:
|
|
119
|
+
### Listing Available Templates
|
|
92
120
|
|
|
93
121
|
```sh
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-k component \
|
|
97
|
-
PageWrapper
|
|
98
|
-
|
|
99
|
-
# equivalent to:
|
|
100
|
-
$ npx simple-scaffold \
|
|
101
|
-
-g https://github.com/chenasraf/simple-scaffold.git \
|
|
102
|
-
-c scaffold.config.js \
|
|
103
|
-
-k component \
|
|
104
|
-
PageWrapper
|
|
122
|
+
npx simple-scaffold list
|
|
123
|
+
npx simple-scaffold list -c path/to/config.js
|
|
105
124
|
```
|
|
106
125
|
|
|
107
|
-
|
|
126
|
+
## Templates
|
|
108
127
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
about how configuration files work, [see below](#configuration-files).
|
|
128
|
+
Templates are regular files in a directory. Both **file names** and **file contents** support
|
|
129
|
+
Handlebars syntax. Simple Scaffold preserves the directory structure of your template folder.
|
|
112
130
|
|
|
113
|
-
###
|
|
131
|
+
### Example Template
|
|
114
132
|
|
|
115
|
-
|
|
116
|
-
values — name, output directory, template paths, and template key (if multiple are available).
|
|
133
|
+
`templates/component/{{pascalCase name}}.tsx`
|
|
117
134
|
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
```tsx
|
|
136
|
+
// Created: {{ now 'yyyy-MM-dd' }}
|
|
137
|
+
import React from "react"
|
|
120
138
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
output: "src/components",
|
|
126
|
-
inputs: {
|
|
127
|
-
author: { message: "Author name", required: true },
|
|
128
|
-
license: { message: "License", default: "MIT" },
|
|
129
|
-
},
|
|
130
|
-
},
|
|
139
|
+
export default {{ pascalCase name }}: React.FC = (props) => {
|
|
140
|
+
return (
|
|
141
|
+
<div className="{{ camelCase name }}">{{ pascalCase name }} Component</div>
|
|
142
|
+
)
|
|
131
143
|
}
|
|
132
144
|
```
|
|
133
145
|
|
|
134
|
-
|
|
146
|
+
Running `npx simple-scaffold -t templates/component -o src/components PageWrapper` produces
|
|
147
|
+
`src/components/PageWrapper.tsx` with all tokens replaced.
|
|
135
148
|
|
|
136
|
-
|
|
137
|
-
|
|
149
|
+
### Glob Patterns & Exclusions
|
|
150
|
+
|
|
151
|
+
Template paths support globs and negation:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
{
|
|
155
|
+
templates: ["templates/component/**", "!templates/component/README.md"]
|
|
156
|
+
}
|
|
138
157
|
```
|
|
139
158
|
|
|
140
|
-
###
|
|
159
|
+
### .scaffoldignore
|
|
141
160
|
|
|
142
|
-
|
|
143
|
-
|
|
161
|
+
Place a `.scaffoldignore` file in your template directory to exclude files. It works like
|
|
162
|
+
`.gitignore` — one pattern per line, `#` for comments.
|
|
144
163
|
|
|
145
|
-
|
|
146
|
-
`scaffold.{mjs,cjs,js,json}`, `.scaffold.{mjs,cjs,js,json}`.
|
|
164
|
+
## Interactive Mode & Inputs
|
|
147
165
|
|
|
148
|
-
|
|
166
|
+
When running in a terminal, Simple Scaffold prompts for any missing required values (name, output,
|
|
167
|
+
template key). Config files can also define **inputs** — custom fields that are prompted
|
|
168
|
+
interactively:
|
|
149
169
|
|
|
150
170
|
```js
|
|
151
171
|
module.exports = {
|
|
152
|
-
// use "default" to avoid needing to specify key
|
|
153
|
-
// in this case the key is "component"
|
|
154
172
|
component: {
|
|
155
173
|
templates: ["templates/component"],
|
|
156
174
|
output: "src/components",
|
|
157
|
-
|
|
158
|
-
|
|
175
|
+
inputs: {
|
|
176
|
+
author: { type: "text", message: "Author name", required: true },
|
|
177
|
+
license: { type: "select", message: "License", options: ["MIT", "Apache-2.0", "GPL-3.0"] },
|
|
178
|
+
isPublic: { type: "confirm", message: "Public package?" },
|
|
179
|
+
priority: { type: "number", message: "Priority level", default: 1 },
|
|
159
180
|
},
|
|
160
181
|
},
|
|
161
182
|
}
|
|
162
183
|
```
|
|
163
184
|
|
|
164
|
-
|
|
185
|
+
**Input types:** `text` (default), `select`, `confirm`, `number`
|
|
186
|
+
|
|
187
|
+
Pre-fill inputs from the command line to skip prompts:
|
|
165
188
|
|
|
166
189
|
```sh
|
|
167
|
-
|
|
168
|
-
# or explicitly: npx simple-scaffold -c scaffold.config.js PageWrapper
|
|
190
|
+
npx simple-scaffold -k component -D author=John -D license=MIT MyComponent
|
|
169
191
|
```
|
|
170
192
|
|
|
171
|
-
|
|
172
|
-
one-liner in `package.json` which can get pretty long and messy, and harder to maintain.
|
|
173
|
-
|
|
174
|
-
Also, this allows you to define more complex scaffolds with logic without having to use the Node.js
|
|
175
|
-
API directly. (Of course you always have the option to still do so if you wish)
|
|
176
|
-
|
|
177
|
-
More information can be found at the
|
|
178
|
-
[Configuration Files documentation](https://chenasraf.github.io/simple-scaffold/docs/usage/configuration_files).
|
|
193
|
+
## Remote Templates
|
|
179
194
|
|
|
180
|
-
|
|
195
|
+
Use templates from any Git repository:
|
|
181
196
|
|
|
182
|
-
|
|
197
|
+
```sh
|
|
198
|
+
# GitHub shorthand
|
|
199
|
+
npx simple-scaffold -g username/repo -k component MyComponent
|
|
183
200
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
201
|
+
# Full Git URL (GitLab, Bitbucket, etc.)
|
|
202
|
+
npx simple-scaffold -g https://gitlab.com/user/repo.git -k component MyComponent
|
|
203
|
+
```
|
|
187
204
|
|
|
188
|
-
|
|
205
|
+
The repository is cloned to a temporary directory, used, and cleaned up automatically.
|
|
206
|
+
|
|
207
|
+
## CLI Reference
|
|
208
|
+
|
|
209
|
+
### Commands
|
|
210
|
+
|
|
211
|
+
| Command | Description |
|
|
212
|
+
| ------------- | ---------------------------------------- |
|
|
213
|
+
| `[name]` | Generate files from a template (default) |
|
|
214
|
+
| `init` | Create config file and example template |
|
|
215
|
+
| `list` / `ls` | List available template keys in a config |
|
|
216
|
+
|
|
217
|
+
### Options
|
|
218
|
+
|
|
219
|
+
| Flag | Short | Description | Default |
|
|
220
|
+
| ------------------------------ | --------- | ---------------------------------------------------- | ----------- |
|
|
221
|
+
| `--config` | `-c` | Path to config file or directory | auto-detect |
|
|
222
|
+
| `--git` | `-g` | Git URL or GitHub shorthand | |
|
|
223
|
+
| `--key` | `-k` | Template key from config | `default` |
|
|
224
|
+
| `--output` | `-o` | Output directory | |
|
|
225
|
+
| `--templates` | `-t` | Template file paths or globs | |
|
|
226
|
+
| `--data` | `-d` | Custom JSON data | |
|
|
227
|
+
| `--append-data` | `-D` | Key-value data (`key=string`, `key:=raw`) | |
|
|
228
|
+
| `--subdir`/`--no-subdir` | `-s`/`-S` | Create parent directory with input name | `false` |
|
|
229
|
+
| `--subdir-helper` | `-H` | Helper to transform subdir name | |
|
|
230
|
+
| `--overwrite`/`--no-overwrite` | `-w`/`-W` | Overwrite existing files | `false` |
|
|
231
|
+
| `--dry-run` | `-dr` | Preview output without writing files | `false` |
|
|
232
|
+
| `--before-write` | `-B` | Script to run before each file is written | |
|
|
233
|
+
| `--after-scaffold` | `-A` | Shell command to run after scaffolding | |
|
|
234
|
+
| `--quiet` | `-q` | Suppress output | |
|
|
235
|
+
| `--log-level` | `-l` | Log level (`none`, `debug`, `info`, `warn`, `error`) | `info` |
|
|
236
|
+
| `--version` | `-v` | Show version | |
|
|
237
|
+
| `--help` | `-h` | Show help | |
|
|
238
|
+
|
|
239
|
+
## Node.js API
|
|
189
240
|
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
241
|
+
```js
|
|
242
|
+
import Scaffold from "simple-scaffold"
|
|
243
|
+
|
|
244
|
+
// Basic usage
|
|
245
|
+
const scaffold = new Scaffold({
|
|
246
|
+
name: "MyComponent",
|
|
247
|
+
templates: ["templates/component"],
|
|
248
|
+
output: "src/components",
|
|
249
|
+
})
|
|
250
|
+
await scaffold.run()
|
|
251
|
+
|
|
252
|
+
// Load from config file
|
|
253
|
+
const scaffold = await Scaffold.fromConfig("scaffold.config.js", {
|
|
254
|
+
key: "component",
|
|
255
|
+
name: "MyComponent",
|
|
256
|
+
})
|
|
257
|
+
await scaffold.run()
|
|
199
258
|
```
|
|
200
259
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
260
|
+
### Config Options
|
|
261
|
+
|
|
262
|
+
| Option | Type | Description |
|
|
263
|
+
| --------------- | -------------------------- | ------------------------------------- |
|
|
264
|
+
| `name` | `string` | Name for generated files (required) |
|
|
265
|
+
| `templates` | `string[]` | Template paths or globs (required) |
|
|
266
|
+
| `output` | `string \| Function` | Output directory or per-file function |
|
|
267
|
+
| `data` | `Record<string, unknown>` | Custom template data |
|
|
268
|
+
| `inputs` | `Record<string, Input>` | Interactive input definitions |
|
|
269
|
+
| `helpers` | `Record<string, Function>` | Custom Handlebars helpers |
|
|
270
|
+
| `subdir` | `boolean` | Create parent directory with name |
|
|
271
|
+
| `subdirHelper` | `string` | Helper for subdir name transformation |
|
|
272
|
+
| `overwrite` | `boolean \| Function` | Overwrite existing files |
|
|
273
|
+
| `dryRun` | `boolean` | Preview without writing |
|
|
274
|
+
| `logLevel` | `string` | Log verbosity |
|
|
275
|
+
| `beforeWrite` | `Function` | Async hook before each file write |
|
|
276
|
+
| `afterScaffold` | `Function \| string` | Hook after all files are written |
|
|
277
|
+
|
|
278
|
+
## Built-in Helpers
|
|
279
|
+
|
|
280
|
+
All helpers work in both file names and file contents.
|
|
281
|
+
|
|
282
|
+
### Case Helpers
|
|
283
|
+
|
|
284
|
+
| Helper | Example Input | Output |
|
|
285
|
+
| ------------ | ------------- | --------- |
|
|
286
|
+
| `camelCase` | `my name` | `myName` |
|
|
287
|
+
| `pascalCase` | `my name` | `MyName` |
|
|
288
|
+
| `snakeCase` | `my name` | `my_name` |
|
|
289
|
+
| `kebabCase` | `my name` | `my-name` |
|
|
290
|
+
| `hyphenCase` | `my name` | `my-name` |
|
|
291
|
+
| `startCase` | `my name` | `My Name` |
|
|
292
|
+
| `upperCase` | `my name` | `MY NAME` |
|
|
293
|
+
| `lowerCase` | `My Name` | `my name` |
|
|
294
|
+
|
|
295
|
+
### Date Helpers
|
|
296
|
+
|
|
297
|
+
```handlebars
|
|
298
|
+
{{now "yyyy-MM-dd"}}
|
|
299
|
+
{{now "yyyy-MM-dd HH:mm" -1 "hours"}}
|
|
300
|
+
{{date myDateVar "yyyy-MM-dd"}}
|
|
301
|
+
{{date "2077-01-01T00:00:00Z" "yyyy-MM-dd" 7 "days"}}
|
|
209
302
|
```
|
|
210
303
|
|
|
211
|
-
|
|
304
|
+
### Custom Helpers
|
|
212
305
|
|
|
213
|
-
|
|
214
|
-
// Created: 2077-01-01
|
|
215
|
-
import React from 'react'
|
|
306
|
+
Add your own via config:
|
|
216
307
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
308
|
+
```js
|
|
309
|
+
module.exports = {
|
|
310
|
+
component: {
|
|
311
|
+
templates: ["templates/component"],
|
|
312
|
+
output: "src/components",
|
|
313
|
+
helpers: {
|
|
314
|
+
shout: (str) => str.toUpperCase() + "!!!",
|
|
315
|
+
},
|
|
316
|
+
},
|
|
221
317
|
}
|
|
222
318
|
```
|
|
223
319
|
|
|
@@ -231,7 +327,7 @@ just a small amount to help sustain this project, I would be very very thankful!
|
|
|
231
327
|
<img
|
|
232
328
|
height='36'
|
|
233
329
|
src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3'
|
|
234
|
-
alt='Buy Me a Coffee at ko-fi.com'
|
|
330
|
+
alt='Buy Me a Coffee at ko-fi.com'
|
|
235
331
|
/>
|
|
236
332
|
</a>
|
|
237
333
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simple-scaffold",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Generate any file structure - from single components to entire app boilerplates, with a single command.",
|
|
5
5
|
"homepage": "https://chenasraf.github.io/simple-scaffold",
|
|
6
6
|
"repository": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@inquirer/select": "^5.1.2",
|
|
60
60
|
"date-fns": "^4.1.0",
|
|
61
61
|
"glob": "^13.0.6",
|
|
62
|
-
"handlebars": "^4.7.
|
|
62
|
+
"handlebars": "^4.7.9",
|
|
63
63
|
"massarg": "2.1.1",
|
|
64
64
|
"minimatch": "^10.2.4",
|
|
65
65
|
"zod": "^4.3.6"
|
|
@@ -67,16 +67,16 @@
|
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@eslint/js": "^10.0.1",
|
|
69
69
|
"@types/node": "^25.5.0",
|
|
70
|
-
"@vitest/coverage-v8": "^4.1.
|
|
70
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
71
71
|
"husky": "^9.1.7",
|
|
72
72
|
"lint-staged": "^16.4.0",
|
|
73
73
|
"mock-fs": "^5.5.0",
|
|
74
74
|
"prettier": "^3.8.1",
|
|
75
75
|
"rimraf": "^6.1.3",
|
|
76
|
-
"typescript": "^
|
|
77
|
-
"typescript-eslint": "^8.57.
|
|
78
|
-
"vite": "^8.0.
|
|
76
|
+
"typescript": "^6.0.2",
|
|
77
|
+
"typescript-eslint": "^8.57.2",
|
|
78
|
+
"vite": "^8.0.3",
|
|
79
79
|
"vite-node": "^6.0.0",
|
|
80
|
-
"vitest": "^4.1.
|
|
80
|
+
"vitest": "^4.1.2"
|
|
81
81
|
}
|
|
82
82
|
}
|