mirror of
https://github.com/chenasraf/simple-scaffold.git
synced 2026-05-18 01:29:09 +00:00
Compare commits
22 Commits
v1.1.2
...
v1.1.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0742fc8771 | ||
|
|
0ecf07de18 | ||
|
|
51081cf2ee | ||
|
|
5a39c08a9f | ||
|
|
83e5724152 | ||
|
|
7455ac1ead | ||
|
|
f315373d18 | ||
|
|
38d557d450 | ||
|
|
a27389e262 | ||
|
|
ce9fededf0 | ||
|
|
4653428bda | ||
|
|
19b2203f30 | ||
|
|
3f103cd4c2 | ||
|
|
ec5503bc3e | ||
|
|
19ad60c3cb | ||
|
|
f04dd7e487 | ||
|
|
4c9a838ebe | ||
|
|
6700708e1d | ||
|
|
2727bd526c | ||
|
|
834a805794 | ||
|
|
ba9434f504 | ||
|
|
59353f4121 |
@@ -3,6 +3,3 @@ tab_width = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
10
.github/workflows/develop.yml
vendored
10
.github/workflows/develop.yml
vendored
@@ -16,21 +16,21 @@ jobs:
|
||||
- run: yarn test
|
||||
- run: yarn build
|
||||
- run: cd ./dist && yarn pack --filename=../package.tgz
|
||||
if: "contains(github.event.head_commit.message, '[publish]')"
|
||||
if: "!contains(github.event.head_commit.message, '[skip publish]')"
|
||||
- uses: Klemensas/action-autotag@stable
|
||||
if: "contains(github.event.head_commit.message, '[publish]')"
|
||||
if: "!contains(github.event.head_commit.message, '[skip publish]')"
|
||||
id: update_tag
|
||||
with:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
tag_prefix: "v"
|
||||
- name: Publish on NPM
|
||||
uses: JS-DevTools/npm-publish@v1
|
||||
if: "contains(github.event.head_commit.message, '[publish]')"
|
||||
if: "!contains(github.event.head_commit.message, '[skip publish]')"
|
||||
with:
|
||||
package: ./dist/package.json
|
||||
token: "${{ secrets.NPM_TOKEN }}"
|
||||
- name: Create Release
|
||||
if: steps.update_tag.outputs.tagname && contains(github.event.head_commit.message, '[publish]')
|
||||
if: steps.update_tag.outputs.tagname && !contains(github.event.head_commit.message, '[skip publish]')
|
||||
uses: actions/create-release@v1
|
||||
id: create_release
|
||||
env:
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
tag_name: ${{ steps.update_tag.outputs.tagname }}
|
||||
release_name: Release ${{ steps.update_tag.outputs.tagname }}
|
||||
- name: Upload Release Asset
|
||||
if: steps.update_tag.outputs.tagname && contains(github.event.head_commit.message, '[publish]')
|
||||
if: steps.update_tag.outputs.tagname && !contains(github.event.head_commit.message, '[skip publish]')
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
|
||||
21
.github/workflows/docs.yml
vendored
21
.github/workflows/docs.yml
vendored
@@ -1,21 +0,0 @@
|
||||
name: Build Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip docs]')"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: "12.x"
|
||||
- run: cd doc-theme && yarn install && yarn build && rm -rf node_modules && cd ..
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn typedoc
|
||||
- uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./docs
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -61,4 +61,3 @@ examples/test-output/**/*
|
||||
dist/
|
||||
.DS_Store
|
||||
tmp/
|
||||
docs/
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
{
|
||||
"line-length": {
|
||||
"MD013": {
|
||||
"line_length": 100,
|
||||
"tables": false,
|
||||
"code_blocks": false
|
||||
},
|
||||
"no-inline-html": false,
|
||||
"first-line-h1": false
|
||||
}
|
||||
"MD033": false
|
||||
}
|
||||
|
||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -10,11 +10,5 @@
|
||||
"noext",
|
||||
"nonegate",
|
||||
"subdir"
|
||||
],
|
||||
"[markdown]": {
|
||||
"editor.rulers": [
|
||||
87,
|
||||
100
|
||||
],
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
8
.vscode/tasks.json
vendored
8
.vscode/tasks.json
vendored
@@ -13,12 +13,6 @@
|
||||
"type": "npm",
|
||||
"problemMatcher": [],
|
||||
},
|
||||
{
|
||||
"command": "yarn typedoc --watch",
|
||||
"label": "typedoc --watch",
|
||||
"type": "shell",
|
||||
"problemMatcher": [],
|
||||
},
|
||||
{
|
||||
"script": "start",
|
||||
"label": "start",
|
||||
@@ -56,4 +50,4 @@
|
||||
"problemMatcher": [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
238
README.md
238
README.md
@@ -1,13 +1,4 @@
|
||||
<h1 align="center">Simple Scaffold</h1>
|
||||
|
||||
<h2 align="center">
|
||||
|
||||
[GitHub](https://github.com/chenasraf/simple-scaffold) |
|
||||
[Documentation](https://casraf.blog/simple-scaffold) |
|
||||
[NPM](https://npmjs.com/package/simple-scaffold) |
|
||||
[casraf.blog](https://casraf.blog)
|
||||
|
||||
</h2>
|
||||
# Simple Scaffold
|
||||
|
||||
Simple Scaffold allows you to generate any set of files in the easiest way possible with simple commands.
|
||||
|
||||
@@ -23,27 +14,28 @@ other custom data) inside the paths or contents of the files using Handlebars.js
|
||||
<details>
|
||||
<summary>Table of contents</summary>
|
||||
|
||||
- [Install](#install)
|
||||
- [Command Line Interface (CLI)](#command-line-interface-cli)
|
||||
- [Available flags](#available-flags)
|
||||
- [Node module](#node-module)
|
||||
- [Node-specific options](#node-specific-options)
|
||||
- [Preparing files](#preparing-files)
|
||||
- [Template files](#template-files)
|
||||
- [Variable/token replacement](#variabletoken-replacement)
|
||||
- [Helpers](#helpers)
|
||||
- [Simple Scaffold](#simple-scaffold)
|
||||
- [Install](#install)
|
||||
- [Use as a command line tool](#use-as-a-command-line-tool)
|
||||
- [Command Line Options](#command-line-options)
|
||||
- [Use in Node.js](#use-in-nodejs)
|
||||
- [Node-specific options](#node-specific-options)
|
||||
- [Preparing files](#preparing-files)
|
||||
- [Template files](#template-files)
|
||||
- [Variable/token replacement](#variabletoken-replacement)
|
||||
- [Built-in Helpers](#built-in-helpers)
|
||||
- [Capitalization Helpers](#capitalization-helpers)
|
||||
- [Date helpers](#date-helpers)
|
||||
- [Custom Helpers](#custom-helpers)
|
||||
- [Examples](#examples)
|
||||
- [Run](#run)
|
||||
- [Examples](#examples)
|
||||
- [Command Example](#command-example)
|
||||
- [Node Module Example](#node-module-example)
|
||||
- [Files](#files)
|
||||
- [Input](#input)
|
||||
- [Output](#output)
|
||||
- [Contributing](#contributing)
|
||||
- [Example Scaffold Input](#example-scaffold-input)
|
||||
- [Input Directory structure](#input-directory-structure)
|
||||
- [Contents of `project/scaffold/{{Name}}.jsx`](#contents-of-projectscaffoldnamejsx)
|
||||
- [Example Scaffold Output](#example-scaffold-output)
|
||||
- [Output directory structure](#output-directory-structure)
|
||||
- [Contents of `project/scaffold/MyComponent/MyComponent.jsx`](#contents-of-projectscaffoldmycomponentmycomponentjsx)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
</details>
|
||||
|
||||
@@ -62,15 +54,11 @@ yarn [global] add simple-scaffold
|
||||
npx simple-scaffold@latest <...args>
|
||||
```
|
||||
|
||||
## Command Line Interface (CLI)
|
||||
## Use as a command line tool
|
||||
|
||||
### Available flags
|
||||
### Command Line Options
|
||||
|
||||
The following is the help text from the `simple-scaffold` binary. To see this and more
|
||||
information anytime, add the `-h` or `--help` flag to your call, e.g.
|
||||
`npx simple-scaffold@latest -h`.
|
||||
|
||||
```text
|
||||
```plaintext
|
||||
Usage: simple-scaffold [options]
|
||||
|
||||
Create structured files based on templates.
|
||||
@@ -79,26 +67,26 @@ Options:
|
||||
|
||||
--help|-h Display help information
|
||||
|
||||
--name|-n Name to be passed to the generated files. {{name}}
|
||||
and {{Name}} inside contents and file names will be
|
||||
replaced accordingly.
|
||||
--name|-n Name to be passed to the generated files. {{name}} and
|
||||
{{Name}} inside contents and file names will be replaced
|
||||
accordingly.
|
||||
|
||||
--output|-o Path to output to. If --create-sub-folder is enabled,
|
||||
the subfolder will be created inside this path.
|
||||
(default: current dir)
|
||||
|
||||
--templates|-t Template files to use as input. You may provide
|
||||
multiple files, each of which can be a relative or
|
||||
absolute path, or a glob pattern for multiple file
|
||||
matching easily.
|
||||
--templates|-t Template files to use as input. You may provide multiple
|
||||
files, each of which can be a relative or absolute path, or a
|
||||
glob pattern for multiple file matching easily.
|
||||
|
||||
--overwrite|-w Enable to override output files, even if they already
|
||||
exist. (default: false)
|
||||
|
||||
--data|-d Add custom data to the templates. By default, only
|
||||
your app name is included.
|
||||
--data|-d Add custom data to the templates. By default, only your
|
||||
app name is included.
|
||||
|
||||
--create-sub-folder|-s Create subfolder with the input name (default: false)
|
||||
--create-sub-folder|-s Create subfolder with the input name
|
||||
(default: false)
|
||||
|
||||
--sub-folder-name-helper|-sh Default helper to apply to subfolder name when using
|
||||
`--create-sub-folder true`.
|
||||
@@ -113,9 +101,9 @@ Options:
|
||||
2)
|
||||
|
||||
--dry-run|-dr 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. (default: false)
|
||||
scaffolds and making sure they don't fail, without having to
|
||||
write actual file contents or create directories.
|
||||
(default: false)
|
||||
```
|
||||
|
||||
You can also add this as a script in your `package.json`:
|
||||
@@ -128,11 +116,10 @@ You can also add this as a script in your `package.json`:
|
||||
}
|
||||
```
|
||||
|
||||
## Node module
|
||||
|
||||
You can also build the scaffold yourself, if you want to create more complex arguments or scaffold
|
||||
groups - simply pass a config object to the Scaffold function when you are ready to start.
|
||||
## Use in Node.js
|
||||
|
||||
You can also build the scaffold yourself, if you want to create more complex arguments or scaffold groups.
|
||||
Simply pass a config object to the Scaffold function when you are ready to start.
|
||||
The config takes similar arguments to the command line:
|
||||
|
||||
```typescript
|
||||
@@ -161,11 +148,11 @@ const scaffold = Scaffold(config)
|
||||
In addition to all the options available in the command line, there are some Node/JS-specific
|
||||
options available:
|
||||
|
||||
| Option | Type | Description |
|
||||
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `output` | | In addition to being passed the same as CLI, it may also be passed a function for each input file to output into a dynamic path: `{ output: (fullPath, baseDir, baseName) => path.resolve(baseDir, baseName) }` |
|
||||
| `helpers` | `Record<string, (string) => string>` | Helpers are simple functions that transform your `data` variables into other values. See [Helpers](#helpers) for the list of default helpers, or add your own to be loaded into the template parser. |
|
||||
| `beforeWrite` | `(content: Buffer, rawContent: Buffer, outputPath: string) => Promise<String \| Buffer \| undefined> \| String \| Buffer \| undefined` | Supply this function to override the final output contents of each of your files, allowing you to add more pre-processing to your generator pipeline. The return value of this function will replace the output content of the respective file, which you may discriminate (if needed) using the `outputPath` argument. |
|
||||
| Option | Type | Description |
|
||||
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `output` | | In addition to being passed the same as CLI, it may also be passed a function for each input file to output into a dynamic path: `{ output: (fullPath, baseDir, baseName) => path.resolve(baseDir, baseName) }` |
|
||||
| `helpers` | `Record<string, (string) => string>` | Helpers are simple functions that transform your `data` variables into other values. See [Helpers](#helpers) for the list of default helpers, or add your own to be loaded into the template parser. |
|
||||
| `beforeWrite` | `(content: Buffer, rawContent: Buffer, outputPath: string) => Promise<String \| Buffer \| undefined> \| String \| Buffer \| undefined` | Supply this function to override the final output contents of each of your files. The return value of this function will replace the output content of the respective file, which you may discriminate (if needed) using the `outputPath` argument. |
|
||||
|
||||
## Preparing files
|
||||
|
||||
@@ -183,11 +170,11 @@ Examples:
|
||||
|
||||
> In the following examples, the config `name` is `AppName`, and the config `output` is `src`.
|
||||
|
||||
| Input template | Files in template | Output path(s) |
|
||||
| ----------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| `./templates/{{ name }}.txt` | `./templates/{{ name }}.txt` | `src/AppName.txt` |
|
||||
| `./templates/directory` | `outer/{{name}}.txt`,<br />`outer2/inner/{{name}}.txt` | `src/outer/AppName.txt`,<br />`src/outer2/inner/AppName.txt` |
|
||||
| `./templates/others/**/*.txt` | `outer/{{name}}.jpg`,<br />`outer2/inner/{{name}}.txt` | `src/outer2/inner/AppName.txt` |
|
||||
| Input template | Output path(s) |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| `./templates/{{ name }}.txt` | `src/AppName.txt` |
|
||||
| `./templates/directory` <br /><br /> Directory contents:<br /> <ol><li>`outer/{{name}}.txt`</li></li><li>`outer2/inner/{{name.txt}}`</li></ol> | `src/outer/AppName.txt`,<br />`src/outer2/inner/AppName.txt` |
|
||||
| `./templates/others/**/*.txt` <br /><br /> Directory contents:<br /> <ol><li>`outer/{{name}}.jpg`</li></li><li>`outer2/inner/{{name.txt}}`</li></ol> | `src/outer2/inner/AppName.txt` |
|
||||
|
||||
### Variable/token replacement
|
||||
|
||||
@@ -203,13 +190,13 @@ For example, using the following command:
|
||||
npx simple-scaffold@latest \
|
||||
--templates templates/components/{{name}}.jsx \
|
||||
--output src/components \
|
||||
--create-sub-folder true \
|
||||
-create-sub-folder true \
|
||||
MyComponent
|
||||
```
|
||||
|
||||
Will output a file with the path:
|
||||
|
||||
```text
|
||||
```plaintext
|
||||
<working_dir>/src/components/MyComponent.jsx
|
||||
```
|
||||
|
||||
@@ -226,16 +213,14 @@ Your `data` will be pre-populated with the following:
|
||||
> [Handlebars.js Language Features](https://handlebarsjs.com/guide/#language-features) for more
|
||||
> information.
|
||||
|
||||
### Helpers
|
||||
### Built-in Helpers
|
||||
|
||||
#### Built-in Helpers
|
||||
|
||||
Simple-Scaffold provides some built-in text transformation filters usable by Handlebars.
|
||||
Simple-Scaffold provides some built-in text transformation filters usable by handleBars.
|
||||
|
||||
For example, you may use `{{ snakeCase name }}` inside a template file or filename, and it will
|
||||
replace `My Name` with `my_name` when producing the final value.
|
||||
|
||||
##### Capitalization Helpers
|
||||
#### Capitalization Helpers
|
||||
|
||||
| Helper name | Example code | Example output |
|
||||
| ------------ | ----------------------- | -------------- |
|
||||
@@ -249,15 +234,15 @@ replace `My Name` with `my_name` when producing the final value.
|
||||
| `upperCase` | `{{ upperCase name }}` | MY NAME |
|
||||
| `lowerCase` | `{{ lowerCase name }}` | my name |
|
||||
|
||||
##### Date helpers
|
||||
#### Date helpers
|
||||
|
||||
| Helper name | Description | Example code | Example output |
|
||||
| -------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------ |
|
||||
| `now` | Current date with format | `{{ now "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
|
||||
| `now` (with offset) | Current date with format, and with offset | `{{ now "yyyy-MM-dd HH:mm" -1 "hours" }}` | `2042-01-01 14:00` |
|
||||
| `date` | Custom date with format | `{{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
|
||||
| `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` |
|
||||
| `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` |
|
||||
| Helper name | Description | Example code | Example output |
|
||||
| -------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------- |
|
||||
| `now` | Current date with format | `{{ now "yyyy-MM-dd HH:mm" }}` | 2042-01-01 15:00 |
|
||||
| `now` (with offset) | Current date with format, and with offset | `{{ now "yyyy-MM-dd HH:mm" -1 "hours" }}` | 2042-01-01 14:00 |
|
||||
| `date` | Custom date with format | `{{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" }}` | 2042-01-01 15:00 |
|
||||
| `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 |
|
||||
| `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 |
|
||||
|
||||
Further details:
|
||||
|
||||
@@ -267,19 +252,19 @@ Further details:
|
||||
|
||||
- The date helper format takes the following arguments:
|
||||
|
||||
```typescript
|
||||
(
|
||||
date: string,
|
||||
format: string,
|
||||
offsetAmount?: number,
|
||||
offsetType?: "years" | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds"
|
||||
)
|
||||
```
|
||||
```typescript
|
||||
(
|
||||
date: string,
|
||||
format: string,
|
||||
offsetAmount?: number,
|
||||
offsetType?: "years" | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds"
|
||||
)
|
||||
```
|
||||
|
||||
- **The now helper** (for current time) takes the same arguments, minus the first one (`date`) as
|
||||
it is implicitly the current date.
|
||||
|
||||
#### Custom Helpers
|
||||
### Custom Helpers
|
||||
|
||||
You may also add your own custom helpers using the `helpers` options when using the JS API (rather
|
||||
than the CLI). The `helpers` option takes an object whose keys are helper names, and values are
|
||||
@@ -294,14 +279,9 @@ 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.
|
||||
|
||||
> To see more information on how helpers work and more features, see
|
||||
> [Handlebars.js docs](https://handlebarsjs.com/guide/#custom-helpers).
|
||||
|
||||
## Examples
|
||||
|
||||
### Run
|
||||
|
||||
#### Command Example
|
||||
### Command Example
|
||||
|
||||
```bash
|
||||
simple-scaffold MyComponent \
|
||||
@@ -311,71 +291,57 @@ simple-scaffold MyComponent \
|
||||
MyComponent
|
||||
```
|
||||
|
||||
#### Node Module Example
|
||||
### Example Scaffold Input
|
||||
|
||||
```typescript
|
||||
import Scaffold from "simple-scaffold"
|
||||
#### Input Directory structure
|
||||
|
||||
async function main() {
|
||||
await Scaffold({
|
||||
name: "MyComponent",
|
||||
templates: ["project/scaffold/**/*"],
|
||||
output: ["src/components"],
|
||||
data: {
|
||||
className: "myClassName",
|
||||
},
|
||||
})
|
||||
console.log("Done.")
|
||||
}
|
||||
```plaintext
|
||||
- project
|
||||
- scaffold
|
||||
- {{Name}}.js
|
||||
- src
|
||||
- components
|
||||
- ...
|
||||
```
|
||||
|
||||
### Files
|
||||
#### Contents of `project/scaffold/{{Name}}.jsx`
|
||||
|
||||
#### Input
|
||||
|
||||
Input file path:
|
||||
|
||||
```text
|
||||
project → scaffold → {{Name}}.js → src → components
|
||||
```
|
||||
|
||||
Input file contents:
|
||||
|
||||
```typescript
|
||||
```typescriptreact
|
||||
import React from 'react'
|
||||
|
||||
export default {{camelCase name}}: React.FC = (props) => {
|
||||
export default {{camelCase ame}}: React.FC = (props) => {
|
||||
return (
|
||||
<div className="{{className}}">{{camelCase name}} Component</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### Output
|
||||
### Example Scaffold Output
|
||||
|
||||
Output file path:
|
||||
### Output directory structure
|
||||
|
||||
- With `createSubFolder = false` (default):
|
||||
```plaintext
|
||||
- project
|
||||
- src
|
||||
- components
|
||||
- MyComponent
|
||||
- MyComponent.js
|
||||
- ...
|
||||
```
|
||||
|
||||
```text
|
||||
project → src → components → MyComponent.js
|
||||
```
|
||||
With `createSubFolder = false`:
|
||||
|
||||
- With `createSubFolder = true`:
|
||||
```plaintext
|
||||
- project
|
||||
- src
|
||||
- components
|
||||
- MyComponent.js
|
||||
- ...
|
||||
```
|
||||
|
||||
```text
|
||||
project → src → components → MyComponent → MyComponent.js
|
||||
```
|
||||
#### Contents of `project/scaffold/MyComponent/MyComponent.jsx`
|
||||
|
||||
- With `createSubFolder = true` and `subFolderNameHelper = 'upperCase'`:
|
||||
|
||||
```text
|
||||
project → src → components → MYCOMPONENT → MyComponent.js
|
||||
```
|
||||
|
||||
Output file contents:
|
||||
|
||||
```typescript
|
||||
```typescriptreact
|
||||
import React from 'react'
|
||||
|
||||
export default MyComponent: React.FC = (props) => {
|
||||
|
||||
2
doc-theme/.gitignore
vendored
2
doc-theme/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
node_modules/
|
||||
build/
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "doc-theme",
|
||||
"version": "1.0.0",
|
||||
"keywords": [
|
||||
"typedocplugin"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"main": "build/index.js",
|
||||
"devDependencies": {
|
||||
"typedoc": "^0.22.15",
|
||||
"typescript": "^4.6.3"
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { Application, DefaultTheme, PageEvent, JSX, DefaultThemeRenderContext } from "typedoc"
|
||||
|
||||
class MyThemeContext extends DefaultThemeRenderContext {
|
||||
// Important: If you use `this`, this function MUST be bound! Template functions are free
|
||||
// to destructure the context object to only grab what they care about.
|
||||
override analytics = () => {
|
||||
// Reusing existing option rather than declaring our own for brevity
|
||||
if (!this.options.isSet("gaID")) return
|
||||
|
||||
const gaID = this.options.getValue("gaID")
|
||||
|
||||
const scr = `
|
||||
(function (w, d, s, l, i) {
|
||||
w[l] = w[l] || [];
|
||||
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
|
||||
var f = d.getElementsByTagName(s)[0],
|
||||
j = d.createElement(s),
|
||||
dl = l != "dataLayer" ? "&l=" + l : "";
|
||||
j.async = true;
|
||||
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
|
||||
f.parentNode.insertBefore(j, f);
|
||||
})(window, document, "script", "dataLayer", "${gaID}");
|
||||
`
|
||||
|
||||
return (
|
||||
<script>
|
||||
<JSX.Raw html={scr} />
|
||||
</script>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MyTheme extends DefaultTheme {
|
||||
private _contextCache?: MyThemeContext
|
||||
override getRenderContext(): DefaultThemeRenderContext {
|
||||
return (this._contextCache ||= new MyThemeContext(this, this.application.options))
|
||||
}
|
||||
}
|
||||
|
||||
export function load(app: Application) {
|
||||
app.renderer.defineTheme("doc-theme", MyTheme)
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
/* Projects */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react", // /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
"jsxFactory": "JSX.createElement", // /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||
"jsxFragmentFactory": "JSX.Fragment", // /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files */
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./build", // /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
glob@^7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
jsonc-parser@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
|
||||
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
|
||||
|
||||
lunr@^2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
|
||||
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
||||
|
||||
marked@^4.0.12:
|
||||
version "4.0.14"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.14.tgz#7a3a5fa5c80580bac78c1ed2e3b84d7bd6fc3870"
|
||||
integrity sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
|
||||
integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
shiki@^0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14"
|
||||
integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==
|
||||
dependencies:
|
||||
jsonc-parser "^3.0.0"
|
||||
vscode-oniguruma "^1.6.1"
|
||||
vscode-textmate "5.2.0"
|
||||
|
||||
typedoc@^0.22.15:
|
||||
version "0.22.15"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.15.tgz#c6ad7ed9d017dc2c3a06c9189cb392bd8e2d8c3f"
|
||||
integrity sha512-CMd1lrqQbFvbx6S9G6fL4HKp3GoIuhujJReWqlIvSb2T26vGai+8Os3Mde7Pn832pXYemd9BMuuYWhFpL5st0Q==
|
||||
dependencies:
|
||||
glob "^7.2.0"
|
||||
lunr "^2.3.9"
|
||||
marked "^4.0.12"
|
||||
minimatch "^5.0.1"
|
||||
shiki "^0.10.1"
|
||||
|
||||
typescript@^4.6.3:
|
||||
version "4.6.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c"
|
||||
integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==
|
||||
|
||||
vscode-oniguruma@^1.6.1:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607"
|
||||
integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==
|
||||
|
||||
vscode-textmate@5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e"
|
||||
integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB |
12
package.json
12
package.json
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "simple-scaffold",
|
||||
"version": "1.1.2",
|
||||
"description": "A simple command to generate any file structure, from single components to entire app boilerplates.",
|
||||
"homepage": "https://casraf.blog/simple-scaffold",
|
||||
"version": "1.1.0-alpha.4",
|
||||
"description": "Create files based on templates",
|
||||
"repository": "https://github.com/chenasraf/simple-scaffold.git",
|
||||
"author": "Chen Asraf <inbox@casraf.com>",
|
||||
"license": "MIT",
|
||||
@@ -27,8 +26,7 @@
|
||||
"test": "jest --verbose",
|
||||
"cmd": "node --trace-warnings dist/cmd.js",
|
||||
"build-test": "yarn build && yarn test",
|
||||
"build-cmd": "yarn build && yarn cmd",
|
||||
"audit-fix": "npm_config_yes=true npx yarn-audit-fix --flow=convert"
|
||||
"build-cmd": "yarn build && yarn cmd"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
@@ -45,13 +43,11 @@
|
||||
"@types/lodash": "^4.14.171",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^14.14.22",
|
||||
"doc-theme": "file:./doc-theme",
|
||||
"jest": "^27.0.6",
|
||||
"mock-fs": "^5.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-node": "^10.1.0",
|
||||
"typedoc": "^0.22.15",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/cmd.ts
13
src/cmd.ts
@@ -3,12 +3,8 @@ import massarg from "massarg"
|
||||
import chalk from "chalk"
|
||||
import { LogLevel, ScaffoldCmdConfig } from "./types"
|
||||
import { Scaffold } from "./scaffold"
|
||||
import path from "path"
|
||||
import fs from "fs/promises"
|
||||
|
||||
export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
const pkg = JSON.parse((await fs.readFile(path.join(__dirname, "package.json"))).toString())
|
||||
|
||||
export function parseCliArgs(args = process.argv.slice(2)) {
|
||||
return (
|
||||
massarg<ScaffoldCmdConfig & { help: boolean; extras: string[] }>()
|
||||
.main(Scaffold)
|
||||
@@ -92,12 +88,9 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
|
||||
binName: "simple-scaffold",
|
||||
useGlobalColumns: true,
|
||||
usageExample: "[options]",
|
||||
header: [`Create structured files based on templates.`].join("\n"),
|
||||
header: "Create structured files based on templates.",
|
||||
footer: [
|
||||
`Version: ${pkg.version}`,
|
||||
`Copyright © Chen Asraf 2017-${new Date().getFullYear()}`,
|
||||
``,
|
||||
`Documentation: ${chalk.underline`https://casraf.blog/simple-scaffold`}`,
|
||||
`Copyright © Chen Asraf 2021`,
|
||||
`NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
|
||||
`GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
|
||||
].join("\n"),
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* @module
|
||||
* Simple Scaffold
|
||||
*
|
||||
* See [readme](README.md)
|
||||
*/
|
||||
import path from "path"
|
||||
|
||||
import {
|
||||
@@ -17,6 +11,7 @@ import {
|
||||
makeRelativePath,
|
||||
registerHelpers,
|
||||
getTemplateGlobInfo,
|
||||
ensureFileExists,
|
||||
getFileList,
|
||||
getBasePath,
|
||||
copyFileTransformed,
|
||||
@@ -37,45 +32,47 @@ import { LogLevel, ScaffoldConfig } from "./types"
|
||||
* The contents and names will be replaced with the transformed values so you can use your original structure as a
|
||||
* boilerplate for other projects, components, modules, or even single files.
|
||||
*
|
||||
* The files will maintain their structure, starting from the directory containing the template (or the template itself
|
||||
* if it is already a directory), and will output from that directory into the directory defined by `config.output`.
|
||||
*
|
||||
* #### Helpers
|
||||
* Helpers are functions you can use to transform your `{{ var }}` contents into other values without having to
|
||||
* pre-define the data and use a duplicated key.
|
||||
* pre-define the data and use a duplicated key. Common cases are transforming name-case format
|
||||
* (e.g. `MyName` → `my_name`), so these have been provided as defaults:
|
||||
*
|
||||
* | Helper name | Example code | Example output |
|
||||
* | ----------- | ----------------------- | -------------- |
|
||||
* | camelCase | `{{ camelCase name }}` | myName |
|
||||
* | snakeCase | `{{ snakeCase name }}` | my_name |
|
||||
* | startCase | `{{ startCase name }}` | My Name |
|
||||
* | kebabCase | `{{ kebabCase name }}` | my-name |
|
||||
* | hyphenCase | `{{ hyphenCase name }}` | my-name |
|
||||
* | pascalCase | `{{ pascalCase name }}` | MyName |
|
||||
* | upperCase | `{{ upperCase name }}` | MYNAME |
|
||||
* | lowerCase | `{{ lowerCase name }}` | myname |
|
||||
*
|
||||
* Any functions you provide in `helpers` option will also be available to you to make custom formatting as you see fit
|
||||
* (for example, formatting a date)
|
||||
*
|
||||
* For available default values, see {@link DefaultHelperKeys}.
|
||||
*
|
||||
* @param {ScaffoldConfig} config The main configuration object
|
||||
*
|
||||
* @see {@link DefaultHelperKeys}
|
||||
*
|
||||
* @category Main
|
||||
*/
|
||||
export async function Scaffold(config: ScaffoldConfig): Promise<void> {
|
||||
config.output ??= process.cwd()
|
||||
export async function Scaffold({ ...options }: ScaffoldConfig): Promise<void> {
|
||||
options.output ??= process.cwd()
|
||||
|
||||
registerHelpers(config)
|
||||
registerHelpers(options)
|
||||
try {
|
||||
config.data = { name: config.name, Name: pascalCase(config.name), ...config.data }
|
||||
logInitStep(config)
|
||||
for (let _template of config.templates) {
|
||||
options.data = { name: options.name, Name: pascalCase(options.name), ...options.data }
|
||||
logInitStep(options)
|
||||
for (let _template of options.templates) {
|
||||
try {
|
||||
const { nonGlobTemplate, origTemplate, isDirOrGlob, isGlob, template } = await getTemplateGlobInfo(
|
||||
config,
|
||||
options,
|
||||
_template
|
||||
)
|
||||
const files = await getFileList(config, template)
|
||||
await ensureFileExists(template, isDirOrGlob)
|
||||
const files = await getFileList(options, template)
|
||||
for (const inputFilePath of files) {
|
||||
if (await isDir(inputFilePath)) {
|
||||
continue
|
||||
}
|
||||
const relPath = makeRelativePath(path.dirname(removeGlob(inputFilePath).replace(nonGlobTemplate, "")))
|
||||
const basePath = getBasePath(relPath)
|
||||
logInputFile(config, {
|
||||
logInputFile(options, {
|
||||
origTemplate,
|
||||
relPath,
|
||||
template,
|
||||
@@ -85,7 +82,7 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
|
||||
isDirOrGlob,
|
||||
isGlob,
|
||||
})
|
||||
await handleTemplateFile(config, {
|
||||
await handleTemplateFile(options, options.data, {
|
||||
templatePath: inputFilePath,
|
||||
basePath,
|
||||
})
|
||||
@@ -95,24 +92,25 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
log(config, LogLevel.Error, e)
|
||||
log(options, LogLevel.Error, e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
async function handleTemplateFile(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
data: Record<string, string>,
|
||||
{ templatePath, basePath }: { templatePath: string; basePath: string }
|
||||
): Promise<void> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const { inputPath, outputPathOpt, outputDir, outputPath, exists } = await getTemplateFileInfo(config, {
|
||||
const { inputPath, outputPathOpt, outputDir, outputPath, exists } = await getTemplateFileInfo(options, data, {
|
||||
templatePath,
|
||||
basePath,
|
||||
})
|
||||
const overwrite = getOptionValueForFile(config, inputPath, config.overwrite ?? false)
|
||||
const overwrite = getOptionValueForFile(options, inputPath, options.overwrite ?? false)
|
||||
|
||||
log(
|
||||
config,
|
||||
options,
|
||||
LogLevel.Debug,
|
||||
`\nParsing ${templatePath}`,
|
||||
`\nBase path: ${basePath}`,
|
||||
@@ -123,10 +121,10 @@ async function handleTemplateFile(
|
||||
`\n`
|
||||
)
|
||||
|
||||
await createDirIfNotExists(path.dirname(outputPath), config)
|
||||
await createDirIfNotExists(path.dirname(outputPath), options)
|
||||
|
||||
log(config, LogLevel.Info, `Writing to ${outputPath}`)
|
||||
await copyFileTransformed(config, { exists, overwrite, outputPath, inputPath })
|
||||
log(options, LogLevel.Info, `Writing to ${outputPath}`)
|
||||
await copyFileTransformed(options, { exists, overwrite, outputPath, inputPath })
|
||||
resolve()
|
||||
} catch (e: any) {
|
||||
handleErr(e)
|
||||
|
||||
241
src/types.ts
241
src/types.ts
@@ -1,13 +1,31 @@
|
||||
import { HelperDelegate } from "handlebars/runtime"
|
||||
export enum LogLevel {
|
||||
None = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Warning = 3,
|
||||
Error = 4,
|
||||
}
|
||||
|
||||
export type FileResponseFn<T> = (fullPath: string, basedir: string, basename: string) => T
|
||||
|
||||
export type FileResponse<T> = T | FileResponseFn<T>
|
||||
|
||||
export type DefaultHelperKeys =
|
||||
| "camelCase"
|
||||
| "date"
|
||||
| "hyphenCase"
|
||||
| "kebabCase"
|
||||
| "lowerCase"
|
||||
| "now"
|
||||
| "pascalCase"
|
||||
| "snakeCase"
|
||||
| "startCase"
|
||||
| "upperCase"
|
||||
|
||||
export type HelperKeys<T> = DefaultHelperKeys | T
|
||||
|
||||
export type Helper = Handlebars.HelperDelegate
|
||||
|
||||
/**
|
||||
* The config object for defining a scaffolding group.
|
||||
*
|
||||
* @see https://github.com/chenasraf/simple-scaffold#readme
|
||||
* @see {@link DefaultHelperKeys}
|
||||
*
|
||||
* @category Config
|
||||
*/
|
||||
export interface ScaffoldConfig {
|
||||
/**
|
||||
* Name to be passed to the generated files. `{{name}}` and `{{Name}}` inside contents and file names will be replaced
|
||||
@@ -17,77 +35,46 @@ export interface ScaffoldConfig {
|
||||
|
||||
/**
|
||||
* Template files to use as input. You may provide multiple files, each of which can be a relative or absolute path,
|
||||
* or a glob pattern for multiple file matching easily.
|
||||
*
|
||||
* @default Current working directory
|
||||
* or a glob pattern for multiple file matching easily. (default: current working directory)
|
||||
*/
|
||||
templates: string[]
|
||||
|
||||
/**
|
||||
* Path to output to. If `createSubFolder` 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.
|
||||
*
|
||||
* @see {@link FileResponse}
|
||||
* @see {@link FileResponseHandler}
|
||||
*/
|
||||
/** Path to output to. If `createSubFolder` is `true`, the subfolder will be created inside this path. */
|
||||
output: FileResponse<string>
|
||||
|
||||
/**
|
||||
* Whether to create subfolder with the input name.
|
||||
*
|
||||
* When `true`, you may also use {@link subFolderNameHelper} to determine a pre-process helper on
|
||||
* the directory name.
|
||||
*
|
||||
* @default `false`
|
||||
* Create subfolder with the input name (default: `false`)
|
||||
*/
|
||||
createSubFolder?: boolean
|
||||
|
||||
/**
|
||||
* Add custom data to the templates. By default, only your app name is included as `{{name}}` and `{{Name}}`.
|
||||
*
|
||||
* This can be any object that will be usable by Handlebars.
|
||||
*/
|
||||
data?: Record<string, any>
|
||||
data?: Record<string, string>
|
||||
|
||||
/**
|
||||
* Enable to override output files, even if they already exist.
|
||||
* Enable to override output files, even if they already exist. (default: `false`)
|
||||
*
|
||||
* You may supply a function to this option, which can take the arguments `(fullPath, baseDir, baseName)` and returns
|
||||
* a string, to return a dynamic path for each file.
|
||||
*
|
||||
* May also be a {@link FileResponseHandler} which returns a boolean value per file.
|
||||
*
|
||||
* @see {@link FileResponse}
|
||||
* @see {@link FileResponseHandler}
|
||||
*
|
||||
* @default `false`
|
||||
*/
|
||||
overwrite?: FileResponse<boolean>
|
||||
|
||||
/**
|
||||
* Suppress output logs (Same as `verbose: 0` or `verbose: LogLevel.None`)
|
||||
* @see {@link verbose}
|
||||
*/
|
||||
/** Suppress output logs (Same as `verbose: 0` or `verbose: LogLevel.None`) */
|
||||
quiet?: boolean
|
||||
|
||||
/**
|
||||
* Determine amount of logs to display.
|
||||
*
|
||||
* The values are: `0 (none) | 1 (debug) | 2 (info) | 3 (warn) | 4 (error)`. The provided level will display messages
|
||||
* of the same level or higher.
|
||||
*
|
||||
* @see {@link LogLevel}
|
||||
*
|
||||
* @default `2 (info)`
|
||||
* of the same level or higher. (default: `2 (info)`)
|
||||
* @see LogLevel
|
||||
*/
|
||||
verbose?: 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.
|
||||
*
|
||||
* @default `false`
|
||||
* actual file contents or create directories. (default: `false`)
|
||||
*/
|
||||
dryRun?: boolean
|
||||
|
||||
@@ -109,20 +96,23 @@ export interface ScaffoldConfig {
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* See {@link DefaultHelperKeys} for a list of all the built-in available helpers.
|
||||
*
|
||||
* @see https://github.com/chenasraf/simple-scaffold#helpers
|
||||
* @see https://github.com/chenasraf/simple-scaffold#built-in-helpers
|
||||
* Here are the built-in helpers available for use:
|
||||
* | Helper name | Example code | Example output |
|
||||
* | ----------- | ----------------------- | -------------- |
|
||||
* | camelCase | `{{ camelCase name }}` | myName |
|
||||
* | snakeCase | `{{ snakeCase name }}` | my_name |
|
||||
* | startCase | `{{ startCase name }}` | My Name |
|
||||
* | kebabCase | `{{ kebabCase name }}` | my-name |
|
||||
* | hyphenCase | `{{ hyphenCase name }}` | my-name |
|
||||
* | pascalCase | `{{ pascalCase name }}` | MyName |
|
||||
* | upperCase | `{{ upperCase name }}` | MYNAME |
|
||||
* | lowerCase | `{{ lowerCase name }}` | myname |
|
||||
*/
|
||||
helpers?: Record<string, Helper>
|
||||
|
||||
/**
|
||||
* Default transformer to apply to subfolder name when using `createSubFolder: 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 CapitalizationHelperKeys}
|
||||
* @see {@link DefaultHelperKeys}
|
||||
* helpers, or a custom one you provide to `helpers`. Defaults to `undefined`, which means no transformation is done.
|
||||
*/
|
||||
subFolderNameHelper?: DefaultHelperKeys | string
|
||||
|
||||
@@ -137,7 +127,7 @@ export interface ScaffoldConfig {
|
||||
* @param rawContent The original template before token replacement
|
||||
* @param outputPath The final output path of the processed file
|
||||
*
|
||||
* @returns {Promise<String | Buffer | undefined> | String | Buffer | undefined} The final output of the file contents-only, after further modifications -
|
||||
* @returns `String | Buffer | undefined` The final output of the file contents-only, after further modifications -
|
||||
* or `undefined` to use the original content (i.e. `content.toString()`)
|
||||
*/
|
||||
beforeWrite?(
|
||||
@@ -146,139 +136,6 @@ export interface ScaffoldConfig {
|
||||
outputPath: string
|
||||
): string | Buffer | undefined | Promise<string | Buffer | undefined>
|
||||
}
|
||||
|
||||
/**
|
||||
* The names of the available helper functions that relate to text capitalization.
|
||||
*
|
||||
* These are available for `subfolderNameHelper`.
|
||||
*
|
||||
* | Helper name | Example code | Example output |
|
||||
* | ------------ | ----------------------- | -------------- |
|
||||
* | [None] | `{{ name }}` | my name |
|
||||
* | `camelCase` | `{{ camelCase name }}` | myName |
|
||||
* | `snakeCase` | `{{ snakeCase name }}` | my_name |
|
||||
* | `startCase` | `{{ startCase name }}` | My Name |
|
||||
* | `kebabCase` | `{{ kebabCase name }}` | my-name |
|
||||
* | `hyphenCase` | `{{ hyphenCase name }}` | my-name |
|
||||
* | `pascalCase` | `{{ pascalCase name }}` | MyName |
|
||||
* | `upperCase` | `{{ upperCase name }}` | MY NAME |
|
||||
* | `lowerCase` | `{{ lowerCase name }}` | my name |
|
||||
*
|
||||
* @see {@link ScaffoldConfig}
|
||||
* @see {@link subFolderNameHelper}
|
||||
* @see {@link DefaultHelperKeys}
|
||||
*
|
||||
* @category Helpers
|
||||
*/
|
||||
export type CapitalizationHelperKeys =
|
||||
| "camelCase"
|
||||
| "hyphenCase"
|
||||
| "kebabCase"
|
||||
| "lowerCase"
|
||||
| "pascalCase"
|
||||
| "snakeCase"
|
||||
| "startCase"
|
||||
| "upperCase"
|
||||
|
||||
/**
|
||||
* The names of the available helper functions that relate to dates.
|
||||
*
|
||||
* | Helper name | Description | Example code | Example output |
|
||||
* | -------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------ |
|
||||
* | `now` | Current date with format | `{{ now "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
|
||||
* | `now` (with offset) | Current date with format, and with offset | `{{ now "yyyy-MM-dd HH:mm" -1 "hours" }}` | `2042-01-01 14:00` |
|
||||
* | `date` | Custom date with format | `{{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" }}` | `2042-01-01 15:00` |
|
||||
* | `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` |
|
||||
* | `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` |
|
||||
*
|
||||
* @see {@link DefaultHelperKeys}
|
||||
*
|
||||
* @category Helpers
|
||||
*/
|
||||
export type DateHelperKeys = "date" | "now"
|
||||
|
||||
/**
|
||||
* The names of all the available helper functions in templates.
|
||||
* Simple-Scaffold provides some built-in text transformation filters usable by handleBars.
|
||||
*
|
||||
* For example, you may use `{{ snakeCase name }}` inside a template file or filename, and it will
|
||||
* replace `My Name` with `my_name` when producing the final value.
|
||||
*
|
||||
* @see {@link CapitalizationHelperKeys}
|
||||
* @see {@link DateHelperKeys}
|
||||
*
|
||||
* @category Helpers
|
||||
*/
|
||||
export type DefaultHelperKeys = CapitalizationHelperKeys | DateHelperKeys
|
||||
|
||||
/**
|
||||
* Helper function, see https://handlebarsjs.com/guide/#custom-helpers
|
||||
*
|
||||
* @category Helpers
|
||||
*/
|
||||
export type Helper = HelperDelegate
|
||||
|
||||
/**
|
||||
* The amount of information to log when generating scaffold.
|
||||
* When not `None`, the selected level will be the lowest level included.
|
||||
*
|
||||
* For example, level `Info` (2) will include `Info`, `Warning` and `Error`, but not `Debug`; and `Warning` will only
|
||||
* show `Warning` and `Error`.
|
||||
*
|
||||
* @default `2 (info)`
|
||||
*
|
||||
* @category Logging
|
||||
*/
|
||||
export enum LogLevel {
|
||||
/** Silent output */
|
||||
None = 0,
|
||||
/** Debugging information. Very verbose and only recommended for troubleshooting. */
|
||||
Debug = 1,
|
||||
/**
|
||||
* The regular level of logging. Major actions are logged to show the scaffold progress.
|
||||
*
|
||||
* @default
|
||||
*/
|
||||
Info = 2,
|
||||
/** Warnings such as when file fails to replace token values properly in template. */
|
||||
Warning = 3,
|
||||
/** Errors, such as missing files, bad replacement token syntax, or un-writable directories. */
|
||||
Error = 4,
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that takes path information about file, and returns a value of type `T`
|
||||
*
|
||||
* @template T The return type for the function
|
||||
* @param {string} fullPath The full path of the current file
|
||||
* @param {string} basedir The directory containing the current file
|
||||
* @param {string} basename The name of the file
|
||||
*
|
||||
* @returns {T} A return value
|
||||
*
|
||||
* @category Config
|
||||
*/
|
||||
export type FileResponseHandler<T> = (fullPath: string, basedir: string, basename: string) => T
|
||||
|
||||
/**
|
||||
* Represents a response for file path information.
|
||||
* Can either be:
|
||||
*
|
||||
* 1. `T` - static value
|
||||
* 2. A function with the following signature which returns `T`:
|
||||
* ```typescript
|
||||
* (fullPath: string, basedir: string, basename: string) => T
|
||||
* ```
|
||||
*
|
||||
* @typedef T The return type
|
||||
*
|
||||
* @see {@link FileResponseHandler}
|
||||
*
|
||||
* @category Config
|
||||
* */
|
||||
export type FileResponse<T> = T | FileResponseHandler<T>
|
||||
|
||||
/** @internal */
|
||||
export interface ScaffoldCmdConfig {
|
||||
name: string
|
||||
templates: string[]
|
||||
|
||||
126
src/utils.ts
126
src/utils.ts
@@ -1,6 +1,6 @@
|
||||
import path from "path"
|
||||
import { F_OK } from "constants"
|
||||
import { DefaultHelperKeys, FileResponse, FileResponseHandler, Helper, LogLevel, ScaffoldConfig } from "./types"
|
||||
import { DefaultHelperKeys, FileResponse, FileResponseFn, Helper, LogLevel, ScaffoldConfig } from "./types"
|
||||
import camelCase from "lodash/camelCase"
|
||||
import snakeCase from "lodash/snakeCase"
|
||||
import kebabCase from "lodash/kebabCase"
|
||||
@@ -78,10 +78,10 @@ export function dateHelper(
|
||||
return _dateHelper(dateFns.parseISO(date), formatString, durationDifference!, durationType!)
|
||||
}
|
||||
|
||||
export function registerHelpers(config: ScaffoldConfig): void {
|
||||
const _helpers = { ...defaultHelpers, ...config.helpers }
|
||||
export function registerHelpers(options: ScaffoldConfig): void {
|
||||
const _helpers = { ...defaultHelpers, ...options.helpers }
|
||||
for (const helperName in _helpers) {
|
||||
log(config, LogLevel.Debug, `Registering helper: ${helperName}`)
|
||||
log(options, LogLevel.Debug, `Registering helper: ${helperName}`)
|
||||
Handlebars.registerHelper(helperName, _helpers[helperName as keyof typeof _helpers])
|
||||
}
|
||||
}
|
||||
@@ -90,8 +90,8 @@ export function handleErr(err: NodeJS.ErrnoException | null): void {
|
||||
if (err) throw err
|
||||
}
|
||||
|
||||
export function log(config: ScaffoldConfig, level: LogLevel, ...obj: any[]): void {
|
||||
if (config.quiet || config.verbose === LogLevel.None || level < (config.verbose ?? LogLevel.Info)) {
|
||||
export function log(options: ScaffoldConfig, level: LogLevel, ...obj: any[]): void {
|
||||
if (options.quiet || options.verbose === LogLevel.None || level < (options.verbose ?? LogLevel.Info)) {
|
||||
return
|
||||
}
|
||||
const levelColor: Record<LogLevel, keyof typeof chalk> = {
|
||||
@@ -115,16 +115,16 @@ export function log(config: ScaffoldConfig, level: LogLevel, ...obj: any[]): voi
|
||||
)
|
||||
}
|
||||
|
||||
export async function createDirIfNotExists(dir: string, config: ScaffoldConfig): Promise<void> {
|
||||
export async function createDirIfNotExists(dir: string, options: ScaffoldConfig): Promise<void> {
|
||||
const parentDir = path.dirname(dir)
|
||||
|
||||
if (!(await pathExists(parentDir))) {
|
||||
await createDirIfNotExists(parentDir, config)
|
||||
await createDirIfNotExists(parentDir, options)
|
||||
}
|
||||
|
||||
if (!(await pathExists(dir))) {
|
||||
try {
|
||||
log(config, LogLevel.Debug, `Creating dir ${dir}`)
|
||||
log(options, LogLevel.Debug, `Creating dir ${dir}`)
|
||||
await mkdir(dir)
|
||||
return
|
||||
} catch (e: any) {
|
||||
@@ -137,7 +137,7 @@ export async function createDirIfNotExists(dir: string, config: ScaffoldConfig):
|
||||
}
|
||||
|
||||
export function getOptionValueForFile<T>(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
filePath: string,
|
||||
fn: FileResponse<T>,
|
||||
defaultValue?: T
|
||||
@@ -145,19 +145,19 @@ export function getOptionValueForFile<T>(
|
||||
if (typeof fn !== "function") {
|
||||
return defaultValue ?? (fn as T)
|
||||
}
|
||||
return (fn as FileResponseHandler<T>)(
|
||||
return (fn as FileResponseFn<T>)(
|
||||
filePath,
|
||||
path.dirname(handlebarsParse(config, filePath, { isPath: true }).toString()),
|
||||
path.basename(handlebarsParse(config, filePath, { isPath: true }).toString())
|
||||
path.dirname(handlebarsParse(options, filePath, { isPath: true }).toString()),
|
||||
path.basename(handlebarsParse(options, filePath, { isPath: true }).toString())
|
||||
)
|
||||
}
|
||||
|
||||
export function handlebarsParse(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
templateBuffer: Buffer | string,
|
||||
{ isPath = false }: { isPath?: boolean } = {}
|
||||
): Buffer {
|
||||
const { data } = config
|
||||
const { data } = options
|
||||
try {
|
||||
let str = templateBuffer.toString()
|
||||
if (isPath) {
|
||||
@@ -170,8 +170,8 @@ export function handlebarsParse(
|
||||
}
|
||||
return Buffer.from(outputContents)
|
||||
} catch (e) {
|
||||
log(config, LogLevel.Debug, e)
|
||||
log(config, LogLevel.Warning, "Couldn't parse file with handlebars, returning original content")
|
||||
log(options, LogLevel.Debug, e)
|
||||
log(options, LogLevel.Warning, "Couldn't parse file with handlebars, returning original content")
|
||||
return Buffer.from(templateBuffer)
|
||||
}
|
||||
}
|
||||
@@ -212,11 +212,11 @@ export function getBasePath(relPath: string): string {
|
||||
.replace(process.cwd(), "")
|
||||
}
|
||||
|
||||
export async function getFileList(config: ScaffoldConfig, template: string): Promise<string[]> {
|
||||
export async function getFileList(options: ScaffoldConfig, template: string): Promise<string[]> {
|
||||
return (
|
||||
await promisify(glob)(template, {
|
||||
dot: true,
|
||||
debug: config.verbose === LogLevel.Debug,
|
||||
debug: options.verbose === LogLevel.Debug,
|
||||
nodir: true,
|
||||
})
|
||||
).map((f) => f.replace(/\//g, path.sep))
|
||||
@@ -230,13 +230,13 @@ export interface GlobInfo {
|
||||
template: string
|
||||
}
|
||||
|
||||
export async function getTemplateGlobInfo(config: ScaffoldConfig, template: string): Promise<GlobInfo> {
|
||||
export async function getTemplateGlobInfo(options: ScaffoldConfig, template: string): Promise<GlobInfo> {
|
||||
const isGlob = glob.hasMagic(template)
|
||||
log(config, LogLevel.Debug, "before isDir", "isGlob:", isGlob, template)
|
||||
log(options, LogLevel.Debug, "before isDir", "isGlob:", isGlob, template)
|
||||
let _template = template
|
||||
const nonGlobTemplate = isGlob ? removeGlob(template) : template
|
||||
const isDirOrGlob = isGlob ? true : await isDir(template)
|
||||
log(config, LogLevel.Debug, "after isDir", isDirOrGlob)
|
||||
log(options, LogLevel.Debug, "after isDir", isDirOrGlob)
|
||||
const _shouldAddGlob = !isGlob && isDirOrGlob
|
||||
const origTemplate = template
|
||||
if (_shouldAddGlob) {
|
||||
@@ -245,6 +245,16 @@ export async function getTemplateGlobInfo(config: ScaffoldConfig, template: stri
|
||||
return { nonGlobTemplate, origTemplate, isDirOrGlob, isGlob, template: _template }
|
||||
}
|
||||
|
||||
export async function ensureFileExists(template: string, isGlob: boolean): Promise<void> {
|
||||
if (!isGlob && !(await pathExists(template))) {
|
||||
const err: NodeJS.ErrnoException = new Error(`ENOENT, no such file or directory ${template}`)
|
||||
err.code = "ENOENT"
|
||||
err.path = template
|
||||
err.errno = -2
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export interface OutputFileInfo {
|
||||
inputPath: string
|
||||
outputPathOpt: string
|
||||
@@ -254,13 +264,14 @@ export interface OutputFileInfo {
|
||||
}
|
||||
|
||||
export async function getTemplateFileInfo(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
data: Record<string, string>,
|
||||
{ templatePath, basePath }: { templatePath: string; basePath: string }
|
||||
): Promise<OutputFileInfo> {
|
||||
const inputPath = path.resolve(process.cwd(), templatePath)
|
||||
const outputPathOpt = getOptionValueForFile(config, inputPath, config.output)
|
||||
const outputDir = getOutputDir(config, outputPathOpt, basePath)
|
||||
const outputPath = handlebarsParse(config, path.join(outputDir, path.basename(inputPath)), {
|
||||
const outputPathOpt = getOptionValueForFile(options, inputPath, options.output)
|
||||
const outputDir = getOutputDir(options, outputPathOpt, basePath)
|
||||
const outputPath = handlebarsParse(options, path.join(outputDir, path.basename(inputPath)), {
|
||||
isPath: true,
|
||||
}).toString()
|
||||
const exists = await pathExists(outputPath)
|
||||
@@ -268,7 +279,7 @@ export async function getTemplateFileInfo(
|
||||
}
|
||||
|
||||
export async function copyFileTransformed(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
{
|
||||
exists,
|
||||
overwrite,
|
||||
@@ -283,42 +294,43 @@ export async function copyFileTransformed(
|
||||
): Promise<void> {
|
||||
if (!exists || overwrite) {
|
||||
if (exists && overwrite) {
|
||||
log(config, LogLevel.Info, `File ${outputPath} exists, overwriting`)
|
||||
log(options, LogLevel.Info, `File ${outputPath} exists, overwriting`)
|
||||
}
|
||||
const templateBuffer = await readFile(inputPath)
|
||||
const unprocessedOutputContents = handlebarsParse(config, templateBuffer)
|
||||
const finalOutputContents =
|
||||
(await config.beforeWrite?.(unprocessedOutputContents, templateBuffer, outputPath)) ?? unprocessedOutputContents
|
||||
const unprocessedOutputContents = handlebarsParse(options, templateBuffer)
|
||||
const finalOutputContents = (
|
||||
(await options.beforeWrite?.(unprocessedOutputContents, templateBuffer, outputPath)) ?? unprocessedOutputContents
|
||||
).toString()
|
||||
|
||||
if (!config.dryRun) {
|
||||
if (!options.dryRun) {
|
||||
await writeFile(outputPath, finalOutputContents)
|
||||
log(config, LogLevel.Info, "Done.")
|
||||
log(options, LogLevel.Info, "Done.")
|
||||
} else {
|
||||
log(config, LogLevel.Info, "Content output:")
|
||||
log(config, LogLevel.Info, finalOutputContents)
|
||||
log(options, LogLevel.Info, "Content output:")
|
||||
log(options, LogLevel.Info, finalOutputContents)
|
||||
}
|
||||
} else if (exists) {
|
||||
log(config, LogLevel.Info, `File ${outputPath} already exists, skipping`)
|
||||
log(options, LogLevel.Info, `File ${outputPath} already exists, skipping`)
|
||||
}
|
||||
}
|
||||
|
||||
export function getOutputDir(config: ScaffoldConfig, outputPathOpt: string, basePath: string): string {
|
||||
export function getOutputDir(options: ScaffoldConfig, outputPathOpt: string, basePath: string): string {
|
||||
return path.resolve(
|
||||
process.cwd(),
|
||||
...([
|
||||
outputPathOpt,
|
||||
basePath,
|
||||
config.createSubFolder
|
||||
? config.subFolderNameHelper
|
||||
? handlebarsParse(config, `{{ ${config.subFolderNameHelper} name }}`).toString()
|
||||
: config.name
|
||||
options.createSubFolder
|
||||
? options.subFolderNameHelper
|
||||
? handlebarsParse(options, `{{ ${options.subFolderNameHelper} name }}`).toString()
|
||||
: options.name
|
||||
: undefined,
|
||||
].filter(Boolean) as string[])
|
||||
)
|
||||
}
|
||||
|
||||
export function logInputFile(
|
||||
config: ScaffoldConfig,
|
||||
options: ScaffoldConfig,
|
||||
{
|
||||
origTemplate,
|
||||
relPath,
|
||||
@@ -340,7 +352,7 @@ export function logInputFile(
|
||||
}
|
||||
): void {
|
||||
log(
|
||||
config,
|
||||
options,
|
||||
LogLevel.Debug,
|
||||
`\nprocess.cwd(): ${process.cwd()}`,
|
||||
`\norigTemplate: ${origTemplate}`,
|
||||
@@ -355,20 +367,20 @@ export function logInputFile(
|
||||
)
|
||||
}
|
||||
|
||||
export function logInitStep(config: ScaffoldConfig): void {
|
||||
log(config, LogLevel.Debug, "Full config:", {
|
||||
name: config.name,
|
||||
templates: config.templates,
|
||||
output: config.output,
|
||||
createSubfolder: config.createSubFolder,
|
||||
data: config.data,
|
||||
overwrite: config.overwrite,
|
||||
quiet: config.quiet,
|
||||
subFolderTransformHelper: config.subFolderNameHelper,
|
||||
helpers: Object.keys(config.helpers ?? {}),
|
||||
verbose: `${config.verbose} (${Object.keys(LogLevel).find(
|
||||
(k) => (LogLevel[k as any] as unknown as number) === config.verbose!
|
||||
export function logInitStep(options: ScaffoldConfig): void {
|
||||
log(options, LogLevel.Debug, "Full config:", {
|
||||
name: options.name,
|
||||
templates: options.templates,
|
||||
output: options.output,
|
||||
createSubfolder: options.createSubFolder,
|
||||
data: options.data,
|
||||
overwrite: options.overwrite,
|
||||
quiet: options.quiet,
|
||||
subFolderTransformHelper: options.subFolderNameHelper,
|
||||
helpers: Object.keys(options.helpers ?? {}),
|
||||
verbose: `${options.verbose} (${Object.keys(LogLevel).find(
|
||||
(k) => (LogLevel[k as any] as unknown as number) === options.verbose!
|
||||
)})`,
|
||||
})
|
||||
log(config, LogLevel.Info, "Data:", config.data)
|
||||
log(options, LogLevel.Info, "Data:", options.data)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Console } from "console"
|
||||
import { defaultHelpers } from "../src/utils"
|
||||
import { join } from "path"
|
||||
import * as dateFns from "date-fns"
|
||||
import crypto from "crypto"
|
||||
|
||||
const fileStructNormal = {
|
||||
input: {
|
||||
@@ -14,13 +13,6 @@ const fileStructNormal = {
|
||||
},
|
||||
output: {},
|
||||
}
|
||||
const fileStructWithBinary = {
|
||||
input: {
|
||||
"{{name}}.txt": "Hello, my app is {{name}}",
|
||||
"{{name}}.bin": crypto.randomBytes(10000),
|
||||
},
|
||||
output: {},
|
||||
}
|
||||
|
||||
const fileStructWithData = {
|
||||
input: {
|
||||
@@ -120,24 +112,6 @@ describe("Scaffold", () => {
|
||||
})
|
||||
)
|
||||
|
||||
describe(
|
||||
"binary files",
|
||||
withMock(fileStructWithBinary, () => {
|
||||
test("should copy as-is", async () => {
|
||||
await Scaffold({
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["input"],
|
||||
verbose: 0,
|
||||
})
|
||||
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
||||
expect(data.toString()).toEqual("Hello, my app is app_name")
|
||||
const dataBin = readFileSync(join(process.cwd(), "output", "app_name.bin"))
|
||||
expect(dataBin).toEqual(fileStructWithBinary.input["{{name}}.bin"])
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
describe(
|
||||
"overwrite",
|
||||
withMock(fileStructWithData, () => {
|
||||
@@ -209,16 +183,6 @@ describe("Scaffold", () => {
|
||||
})
|
||||
).rejects.toThrow()
|
||||
|
||||
await expect(
|
||||
Scaffold({
|
||||
name: "app_name",
|
||||
output: "output",
|
||||
templates: ["non-existing-input/non-existing-file.txt"],
|
||||
data: { value: "1" },
|
||||
verbose: 0,
|
||||
})
|
||||
).rejects.toThrow()
|
||||
|
||||
expect(() => readFileSync(join(process.cwd(), "output", "app_name.txt"))).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
26
typedoc.json
26
typedoc.json
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "Simple Scaffold",
|
||||
"entryPoints": [
|
||||
"src/index.ts"
|
||||
],
|
||||
"includeVersion": true,
|
||||
"categorizeByGroup": false,
|
||||
"sort": [
|
||||
"visibility"
|
||||
],
|
||||
"categoryOrder": [
|
||||
"Main",
|
||||
"*"
|
||||
],
|
||||
"theme": "doc-theme",
|
||||
"githubPages": true,
|
||||
"entryPointStrategy": "expand",
|
||||
"out": "docs",
|
||||
"excludePrivate": true,
|
||||
"excludeProtected": true,
|
||||
"excludeInternal": true,
|
||||
"gaID": "GTM-KHQS9TQ",
|
||||
"validation": {
|
||||
"invalidLink": true
|
||||
}
|
||||
}
|
||||
80
yarn.lock
80
yarn.lock
@@ -833,13 +833,6 @@ brace-expansion@^1.1.7:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
braces@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
@@ -1121,9 +1114,6 @@ diff@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
"doc-theme@file:./doc-theme":
|
||||
version "1.0.0"
|
||||
|
||||
domexception@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
||||
@@ -1355,18 +1345,6 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
@@ -2107,11 +2085,6 @@ json5@2.x, json5@^2.1.2:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
jsonc-parser@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
|
||||
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
|
||||
|
||||
kleur@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||
@@ -2149,11 +2122,6 @@ lru-cache@^6.0.0:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lunr@^2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
|
||||
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
||||
|
||||
make-dir@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
|
||||
@@ -2173,11 +2141,6 @@ makeerror@1.0.x:
|
||||
dependencies:
|
||||
tmpl "1.0.x"
|
||||
|
||||
marked@^4.0.12:
|
||||
version "4.0.14"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.14.tgz#7a3a5fa5c80580bac78c1ed2e3b84d7bd6fc3870"
|
||||
integrity sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==
|
||||
|
||||
massarg@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/massarg/-/massarg-1.0.5.tgz#3dfd49bb63bfca4b0371a2f0ffc7580a9a6cc7a0"
|
||||
@@ -2223,13 +2186,6 @@ minimatch@^3.0.4:
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
|
||||
integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
@@ -2536,15 +2492,6 @@ shebang-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
shiki@^0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14"
|
||||
integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==
|
||||
dependencies:
|
||||
jsonc-parser "^3.0.0"
|
||||
vscode-oniguruma "^1.6.1"
|
||||
vscode-textmate "5.2.0"
|
||||
|
||||
signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
@@ -2702,9 +2649,9 @@ throat@^6.0.1:
|
||||
integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
|
||||
|
||||
tmpl@1.0.x:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
|
||||
integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
|
||||
integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -2790,17 +2737,6 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typedoc@^0.22.15:
|
||||
version "0.22.15"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.15.tgz#c6ad7ed9d017dc2c3a06c9189cb392bd8e2d8c3f"
|
||||
integrity sha512-CMd1lrqQbFvbx6S9G6fL4HKp3GoIuhujJReWqlIvSb2T26vGai+8Os3Mde7Pn832pXYemd9BMuuYWhFpL5st0Q==
|
||||
dependencies:
|
||||
glob "^7.2.0"
|
||||
lunr "^2.3.9"
|
||||
marked "^4.0.12"
|
||||
minimatch "^5.0.1"
|
||||
shiki "^0.10.1"
|
||||
|
||||
typescript@^4.3.5:
|
||||
version "4.3.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
|
||||
@@ -2846,16 +2782,6 @@ v8-to-istanbul@^8.0.0:
|
||||
convert-source-map "^1.6.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
vscode-oniguruma@^1.6.1:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607"
|
||||
integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==
|
||||
|
||||
vscode-textmate@5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e"
|
||||
integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==
|
||||
|
||||
w3c-hr-time@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||
|
||||
Reference in New Issue
Block a user