simple-scaffold 1.3.1 → 1.4.0

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.
Files changed (54) hide show
  1. package/cmd.d.ts +2 -0
  2. package/cmd.js +132 -0
  3. package/cmd.js.map +1 -0
  4. package/index.d.ts +4 -0
  5. package/index.js +24 -0
  6. package/index.js.map +1 -0
  7. package/package.json +1 -1
  8. package/scaffold.d.ts +34 -0
  9. package/scaffold.js +113 -0
  10. package/scaffold.js.map +1 -0
  11. package/types.d.ts +311 -0
  12. package/types.js +32 -0
  13. package/types.js.map +1 -0
  14. package/utils.d.ts +66 -0
  15. package/utils.js +305 -0
  16. package/utils.js.map +1 -0
  17. package/.editorconfig +0 -8
  18. package/.github/FUNDING.yml +0 -13
  19. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
  20. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
  21. package/.github/workflows/docs.yml +0 -20
  22. package/.github/workflows/pull_requests.yml +0 -17
  23. package/.github/workflows/release.yml +0 -22
  24. package/.markdownlint.json +0 -9
  25. package/.prettierrc +0 -15
  26. package/.vscode/launch.json +0 -27
  27. package/.vscode/settings.json +0 -22
  28. package/.vscode/tasks.json +0 -59
  29. package/CHANGELOG.md +0 -120
  30. package/LICENSE +0 -21
  31. package/examples/test-input/Component/.hidden-file +0 -0
  32. package/examples/test-input/Component/button-example.png +0 -0
  33. package/examples/test-input/Component/inner/inner-{{name}}.txt +0 -1
  34. package/examples/test-input/Component/{{Name}}.tsx +0 -17
  35. package/examples/test-input/scaffold.config.js +0 -13
  36. package/jest.config.ts +0 -205
  37. package/media/intro.gif +0 -0
  38. package/pages/README.md +0 -7
  39. package/pages/cli.md +0 -74
  40. package/pages/configuration_files.md +0 -86
  41. package/pages/migration.md +0 -25
  42. package/pages/node.md +0 -53
  43. package/pages/templates.md +0 -224
  44. package/release.config.js +0 -76
  45. package/src/cmd.ts +0 -130
  46. package/src/docs.css +0 -55
  47. package/src/index.ts +0 -4
  48. package/src/scaffold.ts +0 -140
  49. package/src/types.ts +0 -342
  50. package/src/utils.ts +0 -423
  51. package/tests/scaffold.test.ts +0 -502
  52. package/tests/utils.test.ts +0 -124
  53. package/tsconfig.json +0 -16
  54. package/typedoc.config.js +0 -63
package/pages/node.md DELETED
@@ -1,53 +0,0 @@
1
- You can build the scaffold yourself, if you want to create more complex arguments, scaffold groups,
2
- etc - simply pass a config object to the Scaffold function when you are ready to start.
3
-
4
- The config takes similar arguments to the command line. The full type definitions can be found in
5
- [src/types.ts](https://github.com/chenasraf/simple-scaffold/blob/develop/src/types.ts#L13).
6
-
7
- See the full
8
- [documentation](https://chenasraf.github.io/simple-scaffold/interfaces/ScaffoldConfig.html) for the
9
- configuration options and their behavior.
10
-
11
- ```ts
12
- interface ScaffoldConfig {
13
- name: string
14
- templates: string[]
15
- output: FileResponse<string>
16
- createSubFolder?: boolean
17
- data?: Record<string, any>
18
- overwrite?: FileResponse<boolean>
19
- quiet?: boolean
20
- verbose?: LogLevel
21
- dryRun?: boolean
22
- helpers?: Record<string, Helper>
23
- subFolderNameHelper?: DefaultHelpers | string
24
- beforeWrite?(
25
- content: Buffer,
26
- rawContent: Buffer,
27
- outputPath: string,
28
- ): string | Buffer | undefined | Promise<string | Buffer | undefined>
29
- }
30
- ```
31
-
32
- This is an example of loading a complete scaffold via Node.js:
33
-
34
- ```typescript
35
- import Scaffold from "simple-scaffold"
36
-
37
- const config = {
38
- name: "component",
39
- templates: [path.join(__dirname, "scaffolds", "component")],
40
- output: path.join(__dirname, "src", "components"),
41
- createSubFolder: true,
42
- subFolderNameHelper: "upperCase"
43
- data: {
44
- property: "value",
45
- },
46
- helpers: {
47
- twice: (text) => [text, text].join(" ")
48
- },
49
- beforeWrite: (content, rawContent, outputPath) => content.toString().toUpperCase()
50
- }
51
-
52
- const scaffold = Scaffold(config)
53
- ```
@@ -1,224 +0,0 @@
1
- # Preparing template files
2
-
3
- Put your template files anywhere, and fill them with tokens for replacement.
4
-
5
- Each template (not file) in the config array is parsed individually, and copied to the output
6
- directory. If a single template path contains multiple files (e.g. if you use a folder path or a
7
- glob pattern), the first directory up the tree of that template will become the base inside the
8
- defined output path for that template, while copying files recursively and maintaining their
9
- relative structure.
10
-
11
- Examples:
12
-
13
- > In the following examples, the config `name` is `AppName`, and the config `output` is `src`.
14
-
15
- | Input template | Files in template | Output path(s) |
16
- | ----------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
17
- | `./templates/{{ name }}.txt` | `./templates/{{ name }}.txt` | `src/AppName.txt` |
18
- | `./templates/directory` | `outer/{{name}}.txt`,<br />`outer2/inner/{{name}}.txt` | `src/outer/AppName.txt`,<br />`src/outer2/inner/AppName.txt` |
19
- | `./templates/others/**/*.txt` | `outer/{{name}}.jpg`,<br />`outer2/inner/{{name}}.txt` | `src/outer2/inner/AppName.txt` |
20
-
21
- ## Variable/token replacement
22
-
23
- Scaffolding will replace `{{ varName }}` in both the file name and its contents and put the
24
- transformed files in the output directory.
25
-
26
- The data available for the template parser is the data you pass to the `data` config option (or
27
- `--data` argument in CLI).
28
-
29
- For example, using the following command:
30
-
31
- ```bash
32
- npx simple-scaffold@latest \
33
- --templates templates/components/{{name}}.jsx \
34
- --output src/components \
35
- --create-sub-folder true \
36
- MyComponent
37
- ```
38
-
39
- Will output a file with the path:
40
-
41
- ```text
42
- <working_dir>/src/components/MyComponent.jsx
43
- ```
44
-
45
- The contents of the file will be transformed in a similar fashion.
46
-
47
- Your `data` will be pre-populated with the following:
48
-
49
- - `{{Name}}`: PascalCase of the component name
50
- - `{{name}}`: raw name of the component as you entered it
51
-
52
- > Simple-Scaffold uses [Handlebars.js](https://handlebarsjs.com/) for outputting the file contents.
53
- > Any `data` you add in the config will be available for use with their names wrapped in `{{` and
54
- > `}}`. Other Handlebars built-ins such as `each`, `if` and `with` are also supported, see
55
- > [Handlebars.js Language Features](https://handlebarsjs.com/guide/#language-features) for more
56
- > information.
57
-
58
- ## Helpers
59
-
60
- ### Built-in Helpers
61
-
62
- Simple-Scaffold provides some built-in text transformation filters usable by Handlebars.
63
-
64
- For example, you may use `{{ snakeCase name }}` inside a template file or filename, and it will
65
- replace `My Name` with `my_name` when producing the final value.
66
-
67
- #### Capitalization Helpers
68
-
69
- | Helper name | Example code | Example output |
70
- | ------------ | ----------------------- | -------------- |
71
- | [None] | `{{ name }}` | my name |
72
- | `camelCase` | `{{ camelCase name }}` | myName |
73
- | `snakeCase` | `{{ snakeCase name }}` | my_name |
74
- | `startCase` | `{{ startCase name }}` | My Name |
75
- | `kebabCase` | `{{ kebabCase name }}` | my-name |
76
- | `hyphenCase` | `{{ hyphenCase name }}` | my-name |
77
- | `pascalCase` | `{{ pascalCase name }}` | MyName |
78
- | `upperCase` | `{{ upperCase name }}` | MY NAME |
79
- | `lowerCase` | `{{ lowerCase name }}` | my name |
80
-
81
- #### Date helpers
82
-
83
- | Helper name | Description | Example code | Example output |
84
- | -------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------ |
85
- | `now` | Current date with format | `{{ now "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
86
- | `now` (with offset) | Current date with format, and with offset | `{{ now "yyyy-MM-dd HH:mm" -1 "hours" }}` | `2042-01-01 14:00` |
87
- | `date` | Custom date with format | `{{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
88
- | `date` (with offset) | Custom date with format, and with offset | `{{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" -1 "days" }}` | `2041-31-12 15:00` |
89
- | `date` (with date from `--data`) | Custom date with format, with data from the `data` config option | `{{ date myCustomDate "yyyy-MM-dd HH:mm" }}` | `2042-01-01 12:00` |
90
-
91
- Further details:
92
-
93
- - We use [`date-fns`](https://date-fns.org/docs/) for parsing/manipulating the dates. If you want
94
- more information on the date tokens to use, refer to
95
- [their format documentation](https://date-fns.org/docs/format).
96
-
97
- - The date helper format takes the following arguments:
98
-
99
- ```typescript
100
- (
101
- date: string,
102
- format: string,
103
- offsetAmount?: number,
104
- offsetType?: "years" | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds"
105
- )
106
- ```
107
-
108
- - **The now helper** (for current time) takes the same arguments, minus the first one (`date`) as it
109
- is implicitly the current date.
110
-
111
- ### Custom Helpers
112
-
113
- You may also add your own custom helpers using the `helpers` options when using the JS API (rather
114
- than the CLI). The `helpers` option takes an object whose keys are helper names, and values are the
115
- transformation functions. For example, `upperCase` is implemented like so:
116
-
117
- ```typescript
118
- config.helpers = {
119
- upperCase: (text) => text.toUpperCase(),
120
- }
121
- ```
122
-
123
- All of the above helpers (built in and custom) will also be available to you when using
124
- `subFolderNameHelper` (`--sub-folder-name-helper`/`-sh`) as a possible value.
125
-
126
- > To see more information on how helpers work and more features, see
127
- > [Handlebars.js docs](https://handlebarsjs.com/guide/#custom-helpers).
128
-
129
- # Examples
130
-
131
- ## Run
132
-
133
- ### Command Example
134
-
135
- ```bash
136
- simple-scaffold MyComponent \
137
- -t project/scaffold/**/* \
138
- -o src/components \
139
- -d '{"className": "myClassName","author": "Chen Asraf"}'
140
- MyComponent
141
- ```
142
-
143
- ### Equivalent Node Module Example
144
-
145
- ```typescript
146
- import Scaffold from "simple-scaffold"
147
-
148
- async function main() {
149
- await Scaffold({
150
- name: "MyComponent",
151
- templates: ["project/scaffold/**/*"],
152
- output: ["src/components"],
153
- data: {
154
- className: "myClassName",
155
- author: "Chen Asraf",
156
- },
157
- })
158
- console.log("Done.")
159
- }
160
- ```
161
-
162
- ## Files
163
-
164
- ### Input
165
-
166
- - Input file path:
167
-
168
- ```text
169
- project → scaffold → {{Name}}.js → src → components
170
- ```
171
-
172
- - Input file contents:
173
-
174
- ```typescript
175
- /**
176
- * Author: {{ author }}
177
- * Date: {{ now "yyyy-MM-dd" }}
178
- */
179
- import React from 'react'
180
-
181
- export default {{camelCase name}}: React.FC = (props) => {
182
- return (
183
- <div className="{{className}}">{{camelCase name}} Component</div>
184
- )
185
- }
186
- ```
187
-
188
- ### Output
189
-
190
- - Output file path:
191
-
192
- - With `createSubFolder = false` (default):
193
-
194
- ```text
195
- project → src → components → MyComponent.js
196
- ```
197
-
198
- - With `createSubFolder = true`:
199
-
200
- ```text
201
- project → src → components → MyComponent → MyComponent.js
202
- ```
203
-
204
- - With `createSubFolder = true` and `subFolderNameHelper = 'upperCase'`:
205
-
206
- ```text
207
- project → src → components → MYCOMPONENT → MyComponent.js
208
- ```
209
-
210
- - Output file contents:
211
-
212
- ```typescript
213
- /**
214
- * Author: Chen Asraf
215
- * Date: 2077-01-01
216
- */
217
- import React from 'react'
218
-
219
- export default MyComponent: React.FC = (props) => {
220
- return (
221
- <div className="myClassName">MyComponent Component</div>
222
- )
223
- }
224
- ```
package/release.config.js DELETED
@@ -1,76 +0,0 @@
1
- const releaseRules = [
2
- { type: "feat", section: "Features", release: "minor" },
3
- { type: "docs", section: "Misc", release: "patch" },
4
- { type: "fix", section: "Bug Fixes", release: "patch" },
5
- { type: "refactor", section: "Misc", release: "patch" },
6
- { type: "docs", section: "Build", release: "patch" },
7
- { type: "perf", section: "Misc", release: "patch" },
8
- { type: "build", section: "Build", release: "patch" },
9
- { type: "chore", section: "Misc", release: "patch" },
10
- { type: "test", section: "Misc", release: "patch" },
11
- ]
12
-
13
- /** @type {import('semantic-release').Options} */
14
- module.exports = {
15
- branches: [
16
- "+([0-9])?(.{+([0-9]),x}).x",
17
- "master",
18
- "next",
19
- "next-major",
20
- { name: "beta", prerelease: true },
21
- { name: "alpha", prerelease: true },
22
- ],
23
- analyzeCommits: {
24
- path: "semantic-release-conventional-commits",
25
- majorTypes: ["major", "breaking"],
26
- minorTypes: ["minor", "feat", "feature"],
27
- patchTypes: ["patch", "fix", "bugfix", "refactor", "perf", "revert"],
28
- },
29
- plugins: [
30
- [
31
- "@semantic-release/commit-analyzer",
32
- {
33
- preset: "conventionalcommits",
34
- parserOpts: {
35
- noteKeywords: ["breaking:", "breaking-fix:", "breaking-feat:"],
36
- },
37
- releaseRules: releaseRules,
38
- },
39
- ],
40
- [
41
- "@semantic-release/release-notes-generator",
42
- {
43
- preset: "conventionalcommits",
44
- parserOpts: {
45
- noteKeywords: ["breaking"],
46
- types: releaseRules,
47
- },
48
- },
49
- ],
50
- [
51
- "@semantic-release/changelog",
52
- {
53
- changelogFile: "CHANGELOG.md",
54
- changelogTitle: "# Change Log",
55
- },
56
- ],
57
- [
58
- "@semantic-release/npm",
59
- {
60
- packageRoot: "dist",
61
- },
62
- ],
63
- [
64
- "@semantic-release/github",
65
- {
66
- assets: ["package.tgz"],
67
- },
68
- ],
69
- [
70
- "@semantic-release/git",
71
- {
72
- assets: ["CHANGELOG.md", "package.json"],
73
- },
74
- ],
75
- ],
76
- }
package/src/cmd.ts DELETED
@@ -1,130 +0,0 @@
1
- #!/usr/bin/env node
2
- import massarg from "massarg"
3
- import chalk from "chalk"
4
- import { LogLevel, ScaffoldCmdConfig } from "./types"
5
- import { Scaffold } from "./scaffold"
6
- import path from "path"
7
- import fs from "fs/promises"
8
- import { parseAppendData, parseConfig } from "./utils"
9
-
10
- export async function parseCliArgs(args = process.argv.slice(2)) {
11
- const pkg = JSON.parse((await fs.readFile(path.join(__dirname, "package.json"))).toString())
12
- const isConfig = args.includes("--config") || args.includes("-c")
13
-
14
- return (
15
- massarg<ScaffoldCmdConfig>()
16
- .main((config) => {
17
- const _config = parseConfig(config)
18
- return Scaffold(_config)
19
- })
20
- .option({
21
- name: "name",
22
- aliases: ["n"],
23
- description:
24
- "Name to be passed to the generated files. {{name}} and {{Name}} inside contents and file names will be replaced accordingly.",
25
- isDefault: true,
26
- required: true,
27
- })
28
- .option({
29
- name: "config",
30
- aliases: ["c"],
31
- description:
32
- "Filename to load config from instead of passing arguments to CLI or using a Node.js script. You may pass a JSON or JS file, with a relative or absolute path.",
33
- })
34
- .option({
35
- name: "output",
36
- aliases: ["o"],
37
- description: `Path to output to. If --create-sub-folder is enabled, the subfolder will be created inside this path. ${chalk.reset`${chalk.white`(default: current dir)`}`}`,
38
- required: !isConfig,
39
- })
40
- .option({
41
- name: "templates",
42
- aliases: ["t"],
43
- array: true,
44
- description:
45
- "Template files to use as input. You may provide multiple files, each of which can be a relative or absolute path, " +
46
- "or a glob pattern for multiple file matching easily.",
47
- required: !isConfig,
48
- })
49
- .option({
50
- name: "overwrite",
51
- aliases: ["w"],
52
- boolean: true,
53
- defaultValue: false,
54
- description: "Enable to override output files, even if they already exist.",
55
- })
56
- .option({
57
- name: "data",
58
- aliases: ["d"],
59
- description: "Add custom data to the templates. By default, only your app name is included.",
60
- parse: (v) => JSON.parse(v),
61
- })
62
- .option({
63
- name: "append-data",
64
- aliases: ["D"],
65
- description:
66
- "Append additional custom data to the templates, which will overwrite --data, using an alternate syntax, which is easier to use with CLI: -D key1=string -D key2:=raw",
67
- parse: parseAppendData,
68
- })
69
- .option({
70
- name: "create-sub-folder",
71
- aliases: ["s"],
72
- boolean: true,
73
- defaultValue: false,
74
- description: "Create subfolder with the input name",
75
- })
76
- .option({
77
- name: "sub-folder-name-helper",
78
- aliases: ["sh"],
79
- description: "Default helper to apply to subfolder name when using `--create-sub-folder true`.",
80
- })
81
- .option({
82
- name: "quiet",
83
- aliases: ["q"],
84
- boolean: true,
85
- defaultValue: false,
86
- description: "Suppress output logs (Same as --verbose 0)",
87
- })
88
- .option({
89
- name: "verbose",
90
- aliases: ["v"],
91
- defaultValue: LogLevel.Info,
92
- description:
93
- "Determine amount of logs to display. The values are: " +
94
- `${chalk.bold`0 (none) | 1 (debug) | 2 (info) | 3 (warn) | 4 (error)`}. ` +
95
- "The provided level will display messages of the same level or higher.",
96
- parse: Number,
97
- })
98
- .option({
99
- name: "dry-run",
100
- aliases: ["dr"],
101
- boolean: true,
102
- defaultValue: false,
103
- description:
104
- "Don't emit files. This is good for testing your scaffolds and making sure they " +
105
- "don't fail, without having to write actual file contents or create directories.",
106
- })
107
- // .example({
108
- // input: `yarn cmd -t examples/test-input/Component -o examples/test-output -d '{"property":"myProp","value":"10"}'`,
109
- // description: "Usage",
110
- // output: "",
111
- // })
112
- .help({
113
- binName: "simple-scaffold",
114
- useGlobalColumns: true,
115
- usageExample: "[options]",
116
- header: [`Create structured files based on templates.`].join("\n"),
117
- footer: [
118
- `Version: ${pkg.version}`,
119
- `Copyright © Chen Asraf 2017-${new Date().getFullYear()}`,
120
- ``,
121
- `Documentation: ${chalk.underline`https://casraf.dev/simple-scaffold`}`,
122
- `NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
123
- `GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
124
- ].join("\n"),
125
- })
126
- .parse(args)
127
- )
128
- }
129
-
130
- parseCliArgs()
package/src/docs.css DELETED
@@ -1,55 +0,0 @@
1
- .tsd-typography table {
2
- border-collapse: collapse;
3
- width: 100%;
4
- }
5
-
6
- .tsd-typography table td,
7
- .tsd-typography table th {
8
- vertical-align: top;
9
- border: 1px solid var(--color-accent);
10
- padding: 6px;
11
- }
12
- .tsd-typography h1 + pre,
13
- .tsd-typography h2 + pre,
14
- .tsd-typography h3 + pre,
15
- .tsd-typography h4 + pre,
16
- .tsd-typography h5 + pre,
17
- .tsd-typography h6 + pre,
18
- /* */
19
- .tsd-typography h1 + table,
20
- .tsd-typography h2 + table,
21
- .tsd-typography h3 + table,
22
- .tsd-typography h4 + table,
23
- .tsd-typography h5 + table,
24
- .tsd-typography h6 + table {
25
- margin-top: 1em;
26
- }
27
-
28
- .tsd-typography pre + a + h1,
29
- .tsd-typography pre + a + h2,
30
- .tsd-typography pre + a + h3,
31
- .tsd-typography pre + a + h4,
32
- .tsd-typography pre + a + h5,
33
- .tsd-typography pre + a + h6,
34
- /* */
35
- .tsd-typography table + a + h1,
36
- .tsd-typography table + a + h2,
37
- .tsd-typography table + a + h3,
38
- .tsd-typography table + a + h4,
39
- .tsd-typography table + a + h5,
40
- .tsd-typography table + a + h6 {
41
- margin-top: 2em;
42
- }
43
-
44
- .tsd-index-accordion[data-key*="Configuration."] ul.tsd-nested-navigation,
45
- .tsd-index-accordion[data-key*="Configuration."] .tsd-accordion-summary > svg,
46
- .tsd-index-accordion[data-key="Changelog"] ul.tsd-nested-navigation,
47
- .tsd-index-accordion[data-key="Changelog"] .tsd-accordion-summary > svg,
48
- .tsd-index-accordion[data-key="Configuration"] li:nth-child(n + 6) {
49
- display: none;
50
- }
51
-
52
- .tsd-index-accordion[data-key*="Configuration."],
53
- .tsd-index-accordion[data-key="Changelog"] {
54
- margin-left: 0;
55
- }
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./scaffold"
2
- export * from "./types"
3
- import Scaffold from "./scaffold"
4
- export default Scaffold
package/src/scaffold.ts DELETED
@@ -1,140 +0,0 @@
1
- /**
2
- * @module
3
- * Simple Scaffold
4
- *
5
- * See [readme](README.md)
6
- */
7
- import path from "path"
8
-
9
- import {
10
- createDirIfNotExists,
11
- getOptionValueForFile,
12
- handleErr,
13
- log,
14
- pascalCase,
15
- isDir,
16
- removeGlob,
17
- makeRelativePath,
18
- registerHelpers,
19
- getTemplateGlobInfo,
20
- getFileList,
21
- getBasePath,
22
- copyFileTransformed,
23
- getTemplateFileInfo,
24
- logInitStep,
25
- logInputFile,
26
- } from "./utils"
27
- import { LogLevel, ScaffoldConfig } from "./types"
28
-
29
- /**
30
- * Create a scaffold using given `options`.
31
- *
32
- * #### Create files
33
- * To create a file structure to output, use any directory and file structure you would like.
34
- * Inside folder names, file names or file contents, you may place `{{ var }}` where `var` is either
35
- * `name` which is the scaffold name you provided or one of the keys you provided in the `data` option.
36
- *
37
- * The contents and names will be replaced with the transformed values so you can use your original structure as a
38
- * boilerplate for other projects, components, modules, or even single files.
39
- *
40
- * The files will maintain their structure, starting from the directory containing the template (or the template itself
41
- * if it is already a directory), and will output from that directory into the directory defined by `config.output`.
42
- *
43
- * #### Helpers
44
- * Helpers are functions you can use to transform your `{{ var }}` contents into other values without having to
45
- * pre-define the data and use a duplicated key.
46
- *
47
- * Any functions you provide in `helpers` option will also be available to you to make custom formatting as you see fit
48
- * (for example, formatting a date)
49
- *
50
- * For available default values, see {@link DefaultHelpers}.
51
- *
52
- * @param {ScaffoldConfig} config The main configuration object
53
- *
54
- * @see {@link DefaultHelpers}
55
- * @see {@link CaseHelpers}
56
- * @see {@link DateHelpers}
57
- *
58
- * @category Main
59
- */
60
- export async function Scaffold(config: ScaffoldConfig): Promise<void> {
61
- config.output ??= process.cwd()
62
-
63
- registerHelpers(config)
64
- try {
65
- config.data = { name: config.name, Name: pascalCase(config.name), ...config.data }
66
- logInitStep(config)
67
- for (let _template of config.templates) {
68
- try {
69
- const { nonGlobTemplate, origTemplate, isDirOrGlob, isGlob, template } = await getTemplateGlobInfo(
70
- config,
71
- _template,
72
- )
73
- const files = await getFileList(config, template)
74
- for (const inputFilePath of files) {
75
- if (await isDir(inputFilePath)) {
76
- continue
77
- }
78
- const relPath = makeRelativePath(path.dirname(removeGlob(inputFilePath).replace(nonGlobTemplate, "")))
79
- const basePath = getBasePath(relPath)
80
- logInputFile(config, {
81
- origTemplate,
82
- relPath,
83
- template,
84
- inputFilePath,
85
- nonGlobTemplate,
86
- basePath,
87
- isDirOrGlob,
88
- isGlob,
89
- })
90
- await handleTemplateFile(config, {
91
- templatePath: inputFilePath,
92
- basePath,
93
- })
94
- }
95
- } catch (e: any) {
96
- handleErr(e)
97
- }
98
- }
99
- } catch (e: any) {
100
- log(config, LogLevel.Error, e)
101
- throw e
102
- }
103
- }
104
- async function handleTemplateFile(
105
- config: ScaffoldConfig,
106
- { templatePath, basePath }: { templatePath: string; basePath: string },
107
- ): Promise<void> {
108
- return new Promise(async (resolve, reject) => {
109
- try {
110
- const { inputPath, outputPathOpt, outputDir, outputPath, exists } = await getTemplateFileInfo(config, {
111
- templatePath,
112
- basePath,
113
- })
114
- const overwrite = getOptionValueForFile(config, inputPath, config.overwrite ?? false)
115
-
116
- log(
117
- config,
118
- LogLevel.Debug,
119
- `\nParsing ${templatePath}`,
120
- `\nBase path: ${basePath}`,
121
- `\nFull input path: ${inputPath}`,
122
- `\nOutput Path Opt: ${outputPathOpt}`,
123
- `\nFull output dir: ${outputDir}`,
124
- `\nFull output path: ${outputPath}`,
125
- `\n`,
126
- )
127
-
128
- await createDirIfNotExists(path.dirname(outputPath), config)
129
-
130
- log(config, LogLevel.Info, `Writing to ${outputPath}`)
131
- await copyFileTransformed(config, { exists, overwrite, outputPath, inputPath })
132
- resolve()
133
- } catch (e: any) {
134
- handleErr(e)
135
- reject(e)
136
- }
137
- })
138
- }
139
-
140
- export default Scaffold