mirror of
https://github.com/chenasraf/simple-scaffold.git
synced 2026-05-18 01:29:09 +00:00
feat!: rename createSubFolder and subFolderNameHelper
This commit is contained in:
@@ -31,14 +31,17 @@ interface ScaffoldConfig {
|
||||
name: string
|
||||
templates: string[]
|
||||
output: FileResponse<string>
|
||||
createSubFolder?: boolean
|
||||
subdir?: boolean
|
||||
git?: string
|
||||
config?: string
|
||||
key?: string
|
||||
data?: Record<string, any>
|
||||
overwrite?: FileResponse<boolean>
|
||||
quiet?: boolean
|
||||
verbose?: LogLevel
|
||||
dryRun?: boolean
|
||||
helpers?: Record<string, Helper>
|
||||
subFolderNameHelper?: DefaultHelpers | string
|
||||
subdirHelper?: DefaultHelpers | string
|
||||
beforeWrite?(
|
||||
content: Buffer,
|
||||
rawContent: Buffer,
|
||||
|
||||
@@ -32,19 +32,19 @@ title: Examples
|
||||
|
||||
- Output file path:
|
||||
|
||||
- With `createSubFolder = false` (default):
|
||||
- With `subdir = false` (default):
|
||||
|
||||
```text
|
||||
project → src → components → MyComponent.js
|
||||
```
|
||||
|
||||
- With `createSubFolder = true`:
|
||||
- With `subdir = true`:
|
||||
|
||||
```text
|
||||
project → src → components → MyComponent → MyComponent.js
|
||||
```
|
||||
|
||||
- With `createSubFolder = true` and `subFolderNameHelper = 'upperCase'`:
|
||||
- With `subdir = true` and `subdirHelper = 'upperCase'`:
|
||||
|
||||
```text
|
||||
project → src → components → MYCOMPONENT → MyComponent.js
|
||||
|
||||
@@ -6,9 +6,9 @@ title: Migration
|
||||
|
||||
### CLI option changes
|
||||
|
||||
- The `:template_key` syntax has been removed. You can still use `-k template_key` to achieve the
|
||||
same result.
|
||||
- Several changes to how remote configs are loaded via CLI:
|
||||
- The `:template_key` syntax has been removed. You can still use `-k template_key` to achieve the
|
||||
same result.
|
||||
- The `--github` (`-gh`) flag has been replaced by a generic `--git` (`-g`) one, which handles any
|
||||
git URL. Providing a partial GitHub path will default to trying to find the project on GitHub,
|
||||
e.g. `-g username/project`
|
||||
@@ -17,6 +17,10 @@ title: Migration
|
||||
which can find the file for you if it is in one of the supported filenames.
|
||||
- `verbose` can now take the names `debug`, `info`, `warn`, `error` or `none` (case insensitive) or
|
||||
as usual by using the numbering from before.
|
||||
- `--create-sub-folder` (`-s`) has been renamed to `--subdir` (`-s`) in the CLI. The Node.js names
|
||||
have been changed as well.
|
||||
- `--sub-folder-name-helper` (`-sh`) has been renamed to `--subdir-helper` (`-sh`). The Node.js
|
||||
names have been changed as well.
|
||||
- All boolean flags no longer take a value. `-q` instead of `-q 1` or `-q true`, `-s` instead of
|
||||
`-s 1`, `-w` instead of `-w 1`, etc.
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ config.helpers = {
|
||||
```
|
||||
|
||||
All of the above helpers (built in and custom) will also be available to you when using
|
||||
`subFolderNameHelper` (`--sub-folder-name-helper`/`-sh`) as a possible value.
|
||||
`subdirHelper` (`--sub-dir-helper`/`-H`) as a possible value.
|
||||
|
||||
> To see more information on how helpers work and more features, see
|
||||
> [Handlebars.js docs](https://handlebarsjs.com/guide/#custom-helpers).
|
||||
|
||||
@@ -24,11 +24,9 @@
|
||||
"clean": "rm -rf dist/",
|
||||
"build": "pnpm clean && tsc && chmod -R +x ./dist && cp ./package.json ./README.md ./dist/",
|
||||
"dev": "tsc --watch",
|
||||
"start": "node dist/scaffold.js",
|
||||
"start": "ts-node src/scaffold.ts",
|
||||
"test": "jest",
|
||||
"cmd": "node --trace-warnings dist/cmd.js",
|
||||
"build-test": "pnpm build && pnpm test",
|
||||
"build-cmd": "pnpm build && pnpm cmd",
|
||||
"cmd": "ts-node src/cmd.ts",
|
||||
"docs:build": "cd docs && pnpm build",
|
||||
"docs:watch": "cd docs && pnpm start",
|
||||
"audit-fix": "pnpm audit --fix",
|
||||
@@ -39,7 +37,7 @@
|
||||
"date-fns": "^3.3.1",
|
||||
"glob": "^10.3.10",
|
||||
"handlebars": "^4.7.8",
|
||||
"massarg": "2.0.0-pre.11"
|
||||
"massarg": "2.0.0-pre.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -18,8 +18,8 @@ dependencies:
|
||||
specifier: ^4.7.8
|
||||
version: 4.7.8
|
||||
massarg:
|
||||
specifier: 2.0.0-pre.11
|
||||
version: 2.0.0-pre.11
|
||||
specifier: 2.0.0-pre.12
|
||||
version: 2.0.0-pre.12
|
||||
|
||||
devDependencies:
|
||||
'@semantic-release/changelog':
|
||||
@@ -3164,8 +3164,8 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/massarg@2.0.0-pre.11:
|
||||
resolution: {integrity: sha512-MrN5ZllZyGI8DPSA8o164WgeEhfpDYnFvtA0xRoWrGJ2eCDUeyyCItUk3EB55tV3kwysqi6AAOei49xUQ5BG4w==}
|
||||
/massarg@2.0.0-pre.12:
|
||||
resolution: {integrity: sha512-ncD9mXRQh4y8IIi5qcNEzh0qsqXyVq0FH0/v2vdMy/+WJCdAIuKG3TqlWML1SWMH4QdqZ/XJnbDfp8u2i91NNg==}
|
||||
dependencies:
|
||||
zod: 3.22.4
|
||||
dev: false
|
||||
|
||||
31
src/cmd.ts
31
src/cmd.ts
@@ -8,7 +8,8 @@ import fs from "node:fs/promises"
|
||||
import { parseAppendData, parseConfigFile } from "./config"
|
||||
|
||||
export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
const pkgFile = await fs.readFile(path.join(__dirname, "package.json"))
|
||||
const isProjectRoot = Boolean(await fs.stat(path.join(__dirname, "package.json")).catch(() => false))
|
||||
const pkgFile = await fs.readFile(path.resolve(__dirname, isProjectRoot ? "." : "..", "package.json"))
|
||||
const pkg = JSON.parse(pkgFile.toString())
|
||||
const isConfigProvided =
|
||||
args.includes("--config") || args.includes("-c") || args.includes("--git") || args.includes("-g")
|
||||
@@ -56,7 +57,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
name: "output",
|
||||
aliases: ["o"],
|
||||
description:
|
||||
"Path to output to. If `--create-sub-folder` is enabled, the subfolder will be created inside " +
|
||||
"Path to output to. If `--subdir` is enabled, the subfolder will be created inside " +
|
||||
"this path. Default is current working directory.",
|
||||
required: !isConfigProvided,
|
||||
})
|
||||
@@ -75,6 +76,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
aliases: ["w"],
|
||||
defaultValue: false,
|
||||
description: "Enable to override output files, even if they already exist.",
|
||||
negatable: true,
|
||||
})
|
||||
.option({
|
||||
name: "data",
|
||||
@@ -91,15 +93,17 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
parse: parseAppendData,
|
||||
})
|
||||
.flag({
|
||||
name: "create-sub-folder",
|
||||
name: "subdir",
|
||||
aliases: ["s"],
|
||||
defaultValue: false,
|
||||
description: "Create subfolder with the input name",
|
||||
description: "Create a parent directory with the input name (and possibly `--subdir-helper`",
|
||||
negatable: true,
|
||||
negationName: "no-subdir",
|
||||
})
|
||||
.option({
|
||||
name: "sub-folder-name-helper",
|
||||
aliases: ["sh"],
|
||||
description: "Default helper to apply to subfolder name when using `--create-sub-folder true`.",
|
||||
name: "subdir-helper",
|
||||
aliases: ["H"],
|
||||
description: "Default helper to apply to subfolder name when using `--subdir`.",
|
||||
})
|
||||
.flag({
|
||||
name: "quiet",
|
||||
@@ -150,16 +154,17 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
bindOption: true,
|
||||
lineLength: 100,
|
||||
useGlobalTableColumns: true,
|
||||
// optionOptions: {
|
||||
// displayNegations: true,
|
||||
// },
|
||||
usageText: [chalk.yellow`simple-scaffold`, chalk.gray`[options]`, chalk.cyan`<name>`].join(" "),
|
||||
optionOptions: {
|
||||
displayNegations: true,
|
||||
},
|
||||
footerText: [
|
||||
`Version: ${pkg.version}`,
|
||||
`Copyright © Chen Asraf 2017-${new Date().getFullYear()}`,
|
||||
``,
|
||||
`Documentation:\n ${chalk.underline`https://chenasraf.github.io/simple-scaffold`}`,
|
||||
`NPM:\n ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
|
||||
`GitHub:\n ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
|
||||
`Documentation: ${chalk.underline`https://chenasraf.github.io/simple-scaffold`}`,
|
||||
`NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
|
||||
`GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
|
||||
].join("\n"),
|
||||
})
|
||||
.parse(args)
|
||||
|
||||
@@ -165,9 +165,9 @@ export function getOutputDir(config: ScaffoldConfig, outputPathOpt: string, base
|
||||
...([
|
||||
outputPathOpt,
|
||||
basePath,
|
||||
config.createSubFolder
|
||||
? config.subFolderNameHelper
|
||||
? handlebarsParse(config, `{{ ${config.subFolderNameHelper} name }}`).toString()
|
||||
config.subdir
|
||||
? config.subdirHelper
|
||||
? handlebarsParse(config, `{{ ${config.subdirHelper} name }}`).toString()
|
||||
: config.name
|
||||
: undefined,
|
||||
].filter(Boolean) as string[]),
|
||||
|
||||
@@ -2,7 +2,15 @@ import { LogConfig, LogLevel, ScaffoldConfig } from "./types"
|
||||
import chalk from "chalk"
|
||||
|
||||
export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void {
|
||||
if (config.logLevel === LogLevel.none || level < (config.logLevel ?? LogLevel.info)) {
|
||||
const priority: Record<LogLevel, number> = {
|
||||
[LogLevel.none]: 0,
|
||||
[LogLevel.debug]: 1,
|
||||
[LogLevel.info]: 2,
|
||||
[LogLevel.warning]: 3,
|
||||
[LogLevel.error]: 4,
|
||||
}
|
||||
|
||||
if (config.logLevel === LogLevel.none || priority[level] < priority[config.logLevel ?? LogLevel.info]) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,10 +57,10 @@ export function logInitStep(config: ScaffoldConfig): void {
|
||||
name: config.name,
|
||||
templates: config.templates,
|
||||
output: config.output,
|
||||
createSubFolder: config.createSubFolder,
|
||||
subdir: config.subdir,
|
||||
data: config.data,
|
||||
overwrite: config.overwrite,
|
||||
subFolderNameHelper: config.subFolderNameHelper,
|
||||
subdirHelper: config.subdirHelper,
|
||||
helpers: Object.keys(config.helpers ?? {}),
|
||||
logLevel: config.logLevel,
|
||||
dryRun: config.dryRun,
|
||||
|
||||
@@ -123,7 +123,7 @@ Scaffold.fromConfig = async function (
|
||||
logLevel: LogLevel.info,
|
||||
overwrite: false,
|
||||
templates: [],
|
||||
createSubFolder: false,
|
||||
subdir: false,
|
||||
quiet: false,
|
||||
config: pathOrUrl,
|
||||
...config,
|
||||
|
||||
40
src/types.ts
40
src/types.ts
@@ -27,7 +27,7 @@ export interface ScaffoldConfig {
|
||||
templates: string[]
|
||||
|
||||
/**
|
||||
* Path to output to. If `createSubFolder` is `true`, the subfolder will be created inside this path.
|
||||
* Path to output to. If `subdir` is `true`, the subfolder will be created inside this path.
|
||||
*
|
||||
* May also be a {@link FileResponseHandler} which returns a new output path to override the default one.
|
||||
*
|
||||
@@ -39,12 +39,12 @@ export interface ScaffoldConfig {
|
||||
/**
|
||||
* Whether to create subfolder with the input name.
|
||||
*
|
||||
* When `true`, you may also use {@link subFolderNameHelper} to determine a pre-process helper on
|
||||
* When `true`, you may also use {@link subdirHelper} to determine a pre-process helper on
|
||||
* the directory name.
|
||||
*
|
||||
* @default `false`
|
||||
*/
|
||||
createSubFolder?: boolean
|
||||
subdir?: boolean
|
||||
|
||||
/**
|
||||
* Add custom data to the templates. By default, only your app name is included as `{{name}}` and `{{Name}}`.
|
||||
@@ -131,15 +131,15 @@ export interface ScaffoldConfig {
|
||||
helpers?: Record<string, Helper>
|
||||
|
||||
/**
|
||||
* Default transformer to apply to subfolder name when using `createSubFolder: true`. Can be one of the default
|
||||
* Default transformer to apply to subfolder name when using `subdir: true`. Can be one of the default
|
||||
* capitalization helpers, or a custom one you provide to `helpers`. Defaults to `undefined`, which means no
|
||||
* transformation is done.
|
||||
*
|
||||
* @see {@link createSubFolder}
|
||||
* @see {@link subdir}
|
||||
* @see {@link CaseHelpers}
|
||||
* @see {@link DefaultHelpers}
|
||||
*/
|
||||
subFolderNameHelper?: DefaultHelpers | string
|
||||
subdirHelper?: DefaultHelpers | string
|
||||
|
||||
/**
|
||||
* This callback runs right before content is being written to the disk. If you supply this function, you may return
|
||||
@@ -182,7 +182,7 @@ export interface ScaffoldConfig {
|
||||
* @see {@link DefaultHelpers}
|
||||
* @see {@link DateHelpers}
|
||||
* @see {@link ScaffoldConfig}
|
||||
* @see {@link ScaffoldConfig.subFolderNameHelper}
|
||||
* @see {@link ScaffoldConfig.subdirHelper}
|
||||
*
|
||||
* @category Helpers
|
||||
*/
|
||||
@@ -320,20 +320,42 @@ export type FileResponseHandler<T> = (fullPath: string, basedir: string, basenam
|
||||
* */
|
||||
export type FileResponse<T> = T | FileResponseHandler<T>
|
||||
|
||||
/** @internal */
|
||||
/**
|
||||
* The Scaffold config for CLI
|
||||
* Contains less and more specific options than {@link ScaffoldConfig}
|
||||
*/
|
||||
export interface ScaffoldCmdConfig {
|
||||
/** The name of the scaffold template to use. */
|
||||
name: string
|
||||
/** The templates to use for generation */
|
||||
templates: string[]
|
||||
/** The output path to write to */
|
||||
output: string
|
||||
createSubFolder: boolean
|
||||
/** Whether to create subfolder with the input name */
|
||||
subdir: boolean
|
||||
/** Default transformer to apply to subfolder name when using `subdir: true` */
|
||||
subdirHelper?: string
|
||||
/** Add custom data to the templates */
|
||||
data?: Record<string, string>
|
||||
/** Add custom data to the template in a CLI-friendly syntax (and not JSON) */
|
||||
appendData?: Record<string, string>
|
||||
/** Enable to override output files, even if they already exist */
|
||||
overwrite: boolean
|
||||
/** Silence logs, same as `logLevel: "none"` */
|
||||
quiet: boolean
|
||||
/**
|
||||
* Determine amount of logs to display.
|
||||
*
|
||||
* @see {@link LogLevel}
|
||||
*/
|
||||
logLevel: LogLevel
|
||||
/** Don't emit files. This is good for testing your scaffolds and making sure they don't fail, without having to write actual file contents or create directories. */
|
||||
dryRun: boolean
|
||||
/** Config file path to use */
|
||||
config?: string
|
||||
/** The key of the template to use */
|
||||
key?: string
|
||||
/** The git repository to use to fetch the config file */
|
||||
git?: string
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ describe("Scaffold", () => {
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["input"],
|
||||
createSubFolder: true,
|
||||
subdir: true,
|
||||
logLevel: "none",
|
||||
})
|
||||
|
||||
@@ -402,7 +402,7 @@ describe("Scaffold", () => {
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["input"],
|
||||
createSubFolder: true,
|
||||
subdir: true,
|
||||
logLevel: "none",
|
||||
})
|
||||
|
||||
@@ -415,9 +415,9 @@ describe("Scaffold", () => {
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["input"],
|
||||
createSubFolder: true,
|
||||
subdir: true,
|
||||
logLevel: "none",
|
||||
subFolderNameHelper: "upperCase",
|
||||
subdirHelper: "upperCase",
|
||||
})
|
||||
|
||||
const data = readFileSync(join(process.cwd(), "output", "APP_NAME", "app_name.txt"))
|
||||
@@ -429,9 +429,9 @@ describe("Scaffold", () => {
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["input"],
|
||||
createSubFolder: true,
|
||||
subdir: true,
|
||||
logLevel: "none",
|
||||
subFolderNameHelper: "test",
|
||||
subdirHelper: "test",
|
||||
helpers: {
|
||||
test: () => "REPLACED",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user