Compare commits

..

45 Commits

Author SHA1 Message Date
semantic-release-bot
f666c357f4 chore(release): 1.8.0 [skip ci]
## [1.8.0](https://github.com/chenasraf/simple-scaffold/compare/v1.7.2...v1.8.0) (2023-11-29)

### Bug Fixes

* **config:** fn config load ([457c904](457c90470b)), closes [#63](https://github.com/chenasraf/simple-scaffold/issues/63)
2023-11-29 22:16:52 +00:00
f5d55f234a docs: update configuration files docs 2023-11-30 00:12:11 +02:00
semantic-release-bot
746f924a22 chore(release): 1.8.0-pre.1 [skip ci]
## [1.8.0-pre.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.2...v1.8.0-pre.1) (2023-11-27)

### Bug Fixes

* **config:** fn config load ([457c904](457c90470b)), closes [#63](https://github.com/chenasraf/simple-scaffold/issues/63)
2023-11-30 00:12:11 +02:00
807c3e27e2 ci: update release config 2023-11-28 00:49:28 +02:00
b048841dac chore: update dependencies 2023-11-28 00:49:28 +02:00
457c90470b fix(config): fn config load
closes #63
2023-11-28 00:49:28 +02:00
dependabot[bot]
0fa1ad4db7 build(deps-dev): bump @babel/traverse from 7.21.5 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.5 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 00:49:28 +02:00
semantic-release-bot
d62eeeb8e4 chore(release): 1.7.2 [skip ci]
## [1.7.2](https://github.com/chenasraf/simple-scaffold/compare/v1.7.1...v1.7.2) (2023-08-20)

### Bug Fixes

* windows path resolution ([98ee000](98ee00031f))
2023-08-20 10:09:48 +00:00
Chen Asraf
565d1f33aa Merge pull request #61 from chenasraf/pre
v1.7.2
2023-08-20 13:08:25 +03:00
semantic-release-bot
9f58fff2cf chore(release): 1.7.2-pre.1 [skip ci]
## [1.7.2-pre.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.1...v1.7.2-pre.1) (2023-08-15)

### Bug Fixes

* windows path resolution ([98ee000](98ee00031f))
2023-08-15 19:34:02 +00:00
dbba81d053 ci: trigger on pre branch 2023-08-15 22:32:25 +03:00
9f5716e1b9 chore: bump version number 2023-08-15 22:31:38 +03:00
Chen Asraf
4cbb79bb3b Merge pull request #60 from chenasraf/fix/windows
[BUGFIX] Windows path resolution
2023-08-15 22:28:04 +03:00
98ee00031f fix: windows path resolution 2023-08-14 00:19:50 +03:00
8c3369a00d chore: formatting 2023-08-14 00:19:36 +03:00
20ef0cea9b chore: update logs 2023-08-14 00:08:16 +03:00
Chen Asraf
3413151358 test: add tests
chore: use node:* modules for builtins
2023-06-12 23:26:25 +03:00
Chen Asraf
d2a2fda1b1 chore: update dependencies 2023-06-12 23:18:50 +03:00
Chen Asraf
486c07a55b Merge branch 'master' into develop 2023-06-08 08:13:52 +03:00
semantic-release-bot
de05bca546 chore(release): 1.7.1 [skip ci]
## [1.7.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0...v1.7.1) (2023-06-07)

### Bug Fixes

* local config file load error ([2b74239](2b7423993b))
2023-06-07 23:56:29 +00:00
Chen Asraf
72d4cf58c5 Merge pull request #58 from chenasraf/develop
v1.7.1
2023-06-08 02:55:06 +03:00
Chen Asraf
2cf31e827e build: fix tsconfig 2023-06-08 02:52:45 +03:00
Chen Asraf
3714e8b3bd build: update release rules, add tests 2023-06-08 02:50:50 +03:00
semantic-release-bot
77be7c09d5 chore(release): 1.7.1-develop.1 [skip ci]
## [1.7.1-develop.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0...v1.7.1-develop.1) (2023-06-07)

### Bug Fixes

* local config file load error ([2b74239](2b7423993b))
2023-06-07 21:51:53 +00:00
Chen Asraf
1246b51cda Merge branch 'master' into develop
# Conflicts:
#	CHANGELOG.md
#	package.json
2023-06-08 00:50:24 +03:00
semantic-release-bot
fea6c0fb16 chore(release): 1.7.0-develop.7 [skip ci]
## [1.7.0-develop.7](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.6...v1.7.0-develop.7) (2023-06-07)

### Bug Fixes

* local config file load error ([2b74239](2b7423993b))
2023-06-07 20:22:57 +00:00
Chen Asraf
2b7423993b fix: local config file load error 2023-06-07 23:21:12 +03:00
semantic-release-bot
a47ba1186c chore(release): 1.7.0-develop.6 [skip ci]
## [1.7.0-develop.6](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.5...v1.7.0-develop.6) (2023-05-27)
2023-05-27 23:16:21 +00:00
Chen Asraf
06b1552dca docs: update README.md 2023-05-28 02:14:36 +03:00
semantic-release-bot
4868925511 chore(release): 1.7.0 [skip ci]
## [1.7.0](https://github.com/chenasraf/simple-scaffold/compare/v1.6.0...v1.7.0) (2023-05-17)

### Features

* function config file ([02a8ba1](02a8ba16cd))

### Bug Fixes

* use path.normalize ([565090a](565090a951))
2023-05-17 17:30:07 +00:00
Chen Asraf
79cfdbed38 Merge pull request #57 from chenasraf/develop
release
2023-05-17 20:28:02 +03:00
Chen Asraf
4f27b7b934 test: add tests 2023-05-13 02:36:26 +03:00
semantic-release-bot
bee430a40d chore(release): 1.7.0-develop.5 [skip ci]
## [1.7.0-develop.5](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.4...v1.7.0-develop.5) (2023-05-12)
2023-05-12 22:59:55 +00:00
Chen Asraf
3dfc920455 test: fix + add tests 2023-05-13 01:58:21 +03:00
Chen Asraf
68307d1378 refactor: remove lodash dependency 2023-05-13 01:29:59 +03:00
Chen Asraf
33e1d569a3 build: update workflows 2023-05-13 01:29:40 +03:00
semantic-release-bot
c446439b1a chore(release): 1.7.0-develop.4 [skip ci]
## [1.7.0-develop.4](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.3...v1.7.0-develop.4) (2023-05-11)
2023-05-11 21:03:55 +00:00
Chen Asraf
773fd00674 build: update package asset name 2023-05-12 00:02:36 +03:00
semantic-release-bot
22763f655e chore(release): 1.7.0-develop.3 [skip ci]
## [1.7.0-develop.3](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.2...v1.7.0-develop.3) (2023-05-11)
2023-05-11 20:28:22 +00:00
Chen Asraf
a54b1f9fa7 build: update package link 2023-05-11 23:26:59 +03:00
Chen Asraf
dac5527173 build: add packageManager key to package.json 2023-05-11 22:59:36 +03:00
Chen Asraf
339459cad8 build: update workflows 2023-05-11 22:55:52 +03:00
Chen Asraf
62b4a1cd2f build: update workflows 2023-05-11 22:52:36 +03:00
Chen Asraf
5844c080ec build: use pnpm 2023-05-11 22:35:59 +03:00
Chen Asraf
9393c546aa chore: cleanup 2023-05-11 22:35:48 +03:00
29 changed files with 839 additions and 546 deletions

View File

@@ -2,20 +2,28 @@ name: Documentation
on:
push:
branches: [ master, develop ]
branches: [master]
jobs:
docs:
runs-on: ubuntu-latest
# if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip docs]')"
if: "!contains(github.event.head_commit.message, '[skip docs]')"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18.x"
- run: yarn install --frozen-lockfile
- run: yarn build-docs
- uses: peaceiris/actions-gh-pages@v3
- name: Install PNPM
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build Docs
run: pnpm build-docs
- name: Deploy on GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs

View File

@@ -2,16 +2,25 @@ name: Pull Requests
on:
pull_request:
branches: [master, develop]
branches: [master, pre, develop]
jobs:
build:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18.x"
- run: yarn install --frozen-lockfile
- run: yarn build
- run: yarn test
- name: Install PNPM
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run Tests
run: pnpm test
- name: Build Package
run: pnpm build

View File

@@ -2,33 +2,56 @@ name: Test & Build
on:
push:
branches: [ master, develop, feat/*, fix/* ]
branches: [master, pre, develop]
permissions:
contents: read # for checkout
jobs:
test:
name: Test
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: pnpm/action-setup@v2
with:
node-version: "18.x"
- run: yarn install --frozen-lockfile
- run: yarn test
if: "!contains(github.event.head_commit.message, '[skip test]')"
run_install: |
- recursive: true
args: [--frozen-lockfile, --strict-peer-dependencies]
- run: pnpm test
build:
name: Build
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
needs: test
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18.x"
- run: yarn install --frozen-lockfile
- run: yarn build
- run: cd ./dist && yarn pack --filename=../package.tgz
- run: yarn semantic-release
if: "!contains(github.event.head_commit.message, '[skip publish]')"
- name: Install PNPM
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run Tests
run: pnpm test
- name: Build Package
run: pnpm build
- name: Pack
run: cd ./dist && pnpm pack --pack-destination=../
- name: Semantic Release
run: npx semantic-release
env:
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -14,9 +14,6 @@
"variabletoken"
],
"[markdown]": {
"editor.rulers": [
87,
100
],
},
"editor.rulers": [87, 100]
}
}

6
.vscode/tasks.json vendored
View File

@@ -14,7 +14,7 @@
"problemMatcher": []
},
{
"command": "yarn typedoc --watch",
"command": "pnpm typedoc --watch",
"label": "typedoc --watch",
"type": "shell",
"problemMatcher": []
@@ -32,8 +32,8 @@
"problemMatcher": []
},
{
"command": "yarn test --watchAll",
"label": "yarn test --watchAll",
"command": "pnpm test --watchAll",
"label": "pnpm test --watchAll",
"type": "shell",
"problemMatcher": []
},

View File

@@ -1,34 +1,62 @@
# Change Log
## [1.7.0-develop.2](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.1...v1.7.0-develop.2) (2023-05-10)
## [1.8.0](https://github.com/chenasraf/simple-scaffold/compare/v1.7.2...v1.8.0) (2023-11-29)
### Bug Fixes
* **config:** fn config load ([457c904](https://github.com/chenasraf/simple-scaffold/commit/457c90470b0f138862469ff878c7e061c7afd18a)), closes [#63](https://github.com/chenasraf/simple-scaffold/issues/63)
## [1.8.0-pre.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.2...v1.8.0-pre.1) (2023-11-27)
### Bug Fixes
* **config:** fn config load ([457c904](https://github.com/chenasraf/simple-scaffold/commit/457c90470b0f138862469ff878c7e061c7afd18a)), closes [#63](https://github.com/chenasraf/simple-scaffold/issues/63)
## [1.7.2](https://github.com/chenasraf/simple-scaffold/compare/v1.7.1...v1.7.2) (2023-08-20)
### Bug Fixes
* windows path resolution ([98ee000](https://github.com/chenasraf/simple-scaffold/commit/98ee00031fc1ad67a53797a9e28e5c4759bc8bce))
## [1.7.2-pre.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.1...v1.7.2-pre.1) (2023-08-15)
### Bug Fixes
* windows path resolution ([98ee000](https://github.com/chenasraf/simple-scaffold/commit/98ee00031fc1ad67a53797a9e28e5c4759bc8bce))
## [1.7.1](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0...v1.7.1) (2023-06-07)
### Bug Fixes
- local config file load error
([2b74239](https://github.com/chenasraf/simple-scaffold/commit/2b7423993be06b2375631642455c801ae2acf75f))
## [1.7.0](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.5...v1.7.0) (2023-05-17)
## [1.7.0-develop.7](https://github.com/chenasraf/simple-scaffold/compare/v1.7.0-develop.6...v1.7.0-develop.7) (2023-06-07)
### Bug Fixes
- local config file load error
([2b74239](https://github.com/chenasraf/simple-scaffold/commit/2b7423993be06b2375631642455c801ae2acf75f))
## [1.7.0-develop.1](https://github.com/chenasraf/simple-scaffold/compare/v1.6.0...v1.7.0-develop.1) (2023-05-09)
### Features
* function config file ([02a8ba1](https://github.com/chenasraf/simple-scaffold/commit/02a8ba16cd6ee31806532845cb5ddbe0f5abf7de))
- function config file
([02a8ba1](https://github.com/chenasraf/simple-scaffold/commit/02a8ba16cd6ee31806532845cb5ddbe0f5abf7de))
### Bug Fixes
* use path.normalize ([565090a](https://github.com/chenasraf/simple-scaffold/commit/565090a951e13dd222f2f802df717e7cb6ca0a73))
- use path.normalize
([565090a](https://github.com/chenasraf/simple-scaffold/commit/565090a951e13dd222f2f802df717e7cb6ca0a73))
## [1.6.0](https://github.com/chenasraf/simple-scaffold/compare/v1.5.0...v1.6.0) (2023-05-05)
### Features
* node.js function for remote configs ([ce5adbe](https://github.com/chenasraf/simple-scaffold/commit/ce5adbe0f898a86db6046d7f66d83dfcaa519ad2))
### Bug Fixes
* move dependency to dev dependency ([d916d88](https://github.com/chenasraf/simple-scaffold/commit/d916d88384054e6c6b40e6299073f1d1acb4d29d))
## Change Log
# [1.5.0](https://github.com/chenasraf/simple-scaffold/compare/v1.6.0-develop.1...v1.5.0) (2023-05-04)
## [1.6.0](https://github.com/chenasraf/simple-scaffold/compare/v1.6.0-develop.1...v1.6.0) (2023-05-05)
## [1.6.0-develop.1](https://github.com/chenasraf/simple-scaffold/compare/v1.5.0...v1.6.0-develop.1) (2023-05-04)

View File

@@ -66,7 +66,7 @@ $ npx simple-scaffold@latest \
This will immediately create the following file: `src/components/PageWrapper.tsx`
```tsx
// Created: 2077/01/01
// Created: 2077-01-01
import React from 'react'
export default PageWrapper: React.FC = (props) => {

5
examples/.dotdir/README.md Executable file
View File

@@ -0,0 +1,5 @@
# {{ name }} Readme
TO DO:
- [ ] ...

View File

@@ -195,7 +195,7 @@ export default {
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
verbose: true,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],

6
nodemon.json Normal file
View File

@@ -0,0 +1,6 @@
{
"ignore": ["**/*.test.ts", "**/*.spec.ts", ".git", "node_modules"],
"watch": ["src"],
"exec": "node -r tsconfig-paths/register -r ts-node/register ./src/index.ts",
"ext": "ts, js"
}

View File

@@ -1,6 +1,6 @@
{
"name": "simple-scaffold",
"version": "1.7.0-develop.2",
"version": "1.8.0",
"description": "Generate any file structure - from single components to entire app boilerplates, with a single command.",
"homepage": "https://chenasraf.github.io/simple-scaffold",
"repository": "https://github.com/chenasraf/simple-scaffold.git",
@@ -8,6 +8,7 @@
"license": "MIT",
"main": "index.js",
"bin": "cmd.js",
"packageManager": "pnpm@8.6.2",
"keywords": [
"javascript",
"cli",
@@ -21,35 +22,35 @@
],
"scripts": {
"clean": "rimraf dist/",
"build": "yarn clean && tsc && chmod -R +x ./dist && cp ./package.json ./README.md ./dist/",
"build": "pnpm clean && tsc && chmod -R +x ./dist && cp ./package.json ./README.md ./dist/",
"dev": "tsc --watch",
"start": "node dist/scaffold.js",
"test": "jest",
"cmd": "node --trace-warnings dist/cmd.js",
"build-test": "yarn build && yarn test",
"build-cmd": "yarn build && yarn cmd",
"build-test": "pnpm build && pnpm test",
"build-cmd": "pnpm build && pnpm cmd",
"build-docs": "typedoc",
"watch-docs": "yarn typedoc --watch",
"audit-fix": "npm_config_yes=true npx yarn-audit-fix --flow=convert",
"changelog": "conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0"
"watch-docs": "pnpm typedoc --watch",
"audit-fix": "pnpm audit --fix",
"changelog": "conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0; echo \"# Change Log\n\n$(cat CHANGELOG.md)\" > CHANGELOG.md"
},
"dependencies": {
"chalk": "^4.1.2",
"date-fns": "^2.29.3",
"glob": "^9.2.1",
"date-fns": "^2.30.0",
"glob": "^10.3.3",
"handlebars": "^4.7.7",
"lodash": "^4.17.21",
"massarg": "^1.0.7-pre.1"
},
"devDependencies": {
"@knodes/typedoc-plugin-pages": "^0.23.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@semantic-release/release-notes-generator": "^10.0.3",
"@types/jest": "^29.5.1",
"@types/lodash": "^4.14.171",
"@types/mock-fs": "^4.13.1",
"@types/node": "^18.16.0",
"@types/semantic-release": "^20.0.1",
"conventional-changelog": "^3.1.25",
"conventional-changelog-cli": "^2.2.2",
"conventional-changelog-conventionalcommits": "^5.0.0",
@@ -60,7 +61,7 @@
"semantic-release-conventional-commits": "^3.0.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"typedoc": "^0.24.6",
"typedoc": "^0.24.7",
"typescript": "^5.0.4"
}
}

View File

@@ -45,7 +45,7 @@ interface ScaffoldConfig {
If you want to supply functions inside the configurations, you must use a `.js` file as JSON does
not support non-primitives.
A `.js` file is just like a `.json` file, make sure to export the final configuration:
A `.js` file can be just like a `.json` file, make sure to export the final configuration:
```js
/** @type {import('simple-scaffold').ScaffoldConfigFile} */
@@ -57,6 +57,23 @@ module.exports = {
}
```
Another feature of using a JS file is you can export a function which will be loaded with the CMD
config provided to Simple Scaffold. The `extras` key contains any values not consumed by built-in
flags, so you can pre-process your args before outputting a config:
```js
/** @type {import('simple-scaffold').ScaffoldConfigFile} */
module.exports = (config) => {
console.log("Config:", config)
return {
component: {
templates: ["templates/component"],
output: "src/components",
},
}
}
```
## Using a config file
Once your config is created, you can use it by providing the file name to the `--config` (or `-c`

325
pnpm-lock.yaml generated
View File

@@ -1,21 +1,22 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
chalk:
specifier: ^4.1.2
version: 4.1.2
date-fns:
specifier: ^2.29.3
version: 2.29.3
specifier: ^2.30.0
version: 2.30.0
glob:
specifier: ^9.2.1
version: 9.2.1
specifier: ^10.3.3
version: 10.3.3
handlebars:
specifier: ^4.7.7
version: 4.7.7
lodash:
specifier: ^4.17.21
version: 4.17.21
massarg:
specifier: ^1.0.7-pre.1
version: 1.0.7-pre.1
@@ -23,10 +24,13 @@ dependencies:
devDependencies:
'@knodes/typedoc-plugin-pages':
specifier: ^0.23.4
version: 0.23.4(lunr@2.3.9)(typedoc@0.24.6)
version: 0.23.4(lunr@2.3.9)(typedoc@0.24.7)
'@semantic-release/changelog':
specifier: ^6.0.3
version: 6.0.3(semantic-release@21.0.1)
'@semantic-release/exec':
specifier: ^6.0.3
version: 6.0.3(semantic-release@21.0.1)
'@semantic-release/git':
specifier: ^10.0.1
version: 10.0.1(semantic-release@21.0.1)
@@ -36,15 +40,15 @@ devDependencies:
'@types/jest':
specifier: ^29.5.1
version: 29.5.1
'@types/lodash':
specifier: ^4.14.171
version: 4.14.171
'@types/mock-fs':
specifier: ^4.13.1
version: 4.13.1
'@types/node':
specifier: ^18.16.0
version: 18.16.0
'@types/semantic-release':
specifier: ^20.0.1
version: 20.0.1
conventional-changelog:
specifier: ^3.1.25
version: 3.1.25
@@ -76,8 +80,8 @@ devDependencies:
specifier: ^10.9.1
version: 10.9.1(@types/node@18.16.0)(typescript@5.0.4)
typedoc:
specifier: ^0.24.6
version: 0.24.6(typescript@5.0.4)
specifier: ^0.24.7
version: 0.24.7(typescript@5.0.4)
typescript:
specifier: ^5.0.4
version: 5.0.4
@@ -92,11 +96,12 @@ packages:
'@jridgewell/trace-mapping': 0.3.18
dev: true
/@babel/code-frame@7.21.4:
resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==}
/@babel/code-frame@7.22.13:
resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.18.6
'@babel/highlight': 7.22.20
chalk: 2.4.2
dev: true
/@babel/compat-data@7.21.7:
@@ -109,15 +114,15 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.1
'@babel/code-frame': 7.21.4
'@babel/generator': 7.21.5
'@babel/code-frame': 7.22.13
'@babel/generator': 7.23.0
'@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8)
'@babel/helper-module-transforms': 7.21.5
'@babel/helpers': 7.21.5
'@babel/parser': 7.21.8
'@babel/template': 7.20.7
'@babel/traverse': 7.21.5
'@babel/types': 7.21.5
'@babel/parser': 7.23.0
'@babel/template': 7.22.15
'@babel/traverse': 7.23.2
'@babel/types': 7.23.0
convert-source-map: 1.9.0
debug: 4.3.4
gensync: 1.0.0-beta.2
@@ -127,11 +132,11 @@ packages:
- supports-color
dev: true
/@babel/generator@7.21.5:
resolution: {integrity: sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==}
/@babel/generator@7.23.0:
resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.18
jsesc: 2.5.2
@@ -151,45 +156,45 @@ packages:
semver: 6.3.0
dev: true
/@babel/helper-environment-visitor@7.21.5:
resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==}
/@babel/helper-environment-visitor@7.22.20:
resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/helper-function-name@7.21.0:
resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
/@babel/helper-function-name@7.23.0:
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.20.7
'@babel/types': 7.21.5
'@babel/template': 7.22.15
'@babel/types': 7.23.0
dev: true
/@babel/helper-hoist-variables@7.18.6:
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
/@babel/helper-hoist-variables@7.22.5:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@babel/helper-module-imports@7.21.4:
resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@babel/helper-module-transforms@7.21.5:
resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-environment-visitor': 7.21.5
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-module-imports': 7.21.4
'@babel/helper-simple-access': 7.21.5
'@babel/helper-split-export-declaration': 7.18.6
'@babel/helper-validator-identifier': 7.19.1
'@babel/template': 7.20.7
'@babel/traverse': 7.21.5
'@babel/types': 7.21.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/helper-validator-identifier': 7.22.20
'@babel/template': 7.22.15
'@babel/traverse': 7.23.2
'@babel/types': 7.23.0
transitivePeerDependencies:
- supports-color
dev: true
@@ -203,23 +208,23 @@ packages:
resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@babel/helper-split-export-declaration@7.18.6:
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
/@babel/helper-split-export-declaration@7.22.6:
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@babel/helper-string-parser@7.21.5:
resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==}
/@babel/helper-string-parser@7.22.5:
resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/helper-validator-identifier@7.19.1:
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
/@babel/helper-validator-identifier@7.22.20:
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
engines: {node: '>=6.9.0'}
dev: true
@@ -232,28 +237,28 @@ packages:
resolution: {integrity: sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.20.7
'@babel/traverse': 7.21.5
'@babel/types': 7.21.5
'@babel/template': 7.22.15
'@babel/traverse': 7.23.2
'@babel/types': 7.23.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/highlight@7.18.6:
resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
/@babel/highlight@7.22.20:
resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-validator-identifier': 7.19.1
'@babel/helper-validator-identifier': 7.22.20
chalk: 2.4.2
js-tokens: 4.0.0
dev: true
/@babel/parser@7.21.8:
resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==}
/@babel/parser@7.23.0:
resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.8):
@@ -385,39 +390,46 @@ packages:
'@babel/helper-plugin-utils': 7.21.5
dev: true
/@babel/template@7.20.7:
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
/@babel/runtime@7.21.5:
resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.21.4
'@babel/parser': 7.21.8
'@babel/types': 7.21.5
regenerator-runtime: 0.13.11
dev: false
/@babel/template@7.22.15:
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.22.13
'@babel/parser': 7.23.0
'@babel/types': 7.23.0
dev: true
/@babel/traverse@7.21.5:
resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==}
/@babel/traverse@7.23.2:
resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.21.4
'@babel/generator': 7.21.5
'@babel/helper-environment-visitor': 7.21.5
'@babel/helper-function-name': 7.21.0
'@babel/helper-hoist-variables': 7.18.6
'@babel/helper-split-export-declaration': 7.18.6
'@babel/parser': 7.21.8
'@babel/types': 7.21.5
'@babel/code-frame': 7.22.13
'@babel/generator': 7.23.0
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.23.0
'@babel/types': 7.23.0
debug: 4.3.4
globals: 11.12.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/types@7.21.5:
resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==}
/@babel/types@7.23.0:
resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.21.5
'@babel/helper-validator-identifier': 7.19.1
'@babel/helper-string-parser': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
dev: true
@@ -454,7 +466,6 @@ packages:
strip-ansi-cjs: /strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: /wrap-ansi@7.0.0
dev: true
/@istanbuljs/load-nyc-config@1.1.0:
resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
@@ -731,19 +742,19 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/@knodes/typedoc-plugin-pages@0.23.4(lunr@2.3.9)(typedoc@0.24.6):
/@knodes/typedoc-plugin-pages@0.23.4(lunr@2.3.9)(typedoc@0.24.7):
resolution: {integrity: sha512-3LMS2TDV/lH/BKfxNEjCEhAwSCxOuQRF742EoYoP63/AQmIM/EZKDwShn1AYu4CtVAHvJpixuKF0VeFDLjgrbQ==}
peerDependencies:
lunr: ^2.3.0
typedoc: ^0.23.0
dependencies:
'@knodes/typedoc-pluginutils': 0.23.4(typedoc@0.24.6)
'@knodes/typedoc-pluginutils': 0.23.4(typedoc@0.24.7)
lodash: 4.17.21
lunr: 2.3.9
typedoc: 0.24.6(typescript@5.0.4)
typedoc: 0.24.7(typescript@5.0.4)
dev: true
/@knodes/typedoc-pluginutils@0.23.4(typedoc@0.24.6):
/@knodes/typedoc-pluginutils@0.23.4(typedoc@0.24.7):
resolution: {integrity: sha512-uO7t9XxYW1DMjVFTgmRs2p431+AsmvnX4CrrB/zkauo8mZSLS3CppMKHBVE/Lk1cFO73vgfyJReRK98X/8BzUA==}
peerDependencies:
typedoc: ^0.23.0
@@ -752,7 +763,7 @@ packages:
lodash: 4.17.21
pkg-up: 3.1.0
semver: 7.5.0
typedoc: 0.24.6(typescript@5.0.4)
typedoc: 0.24.7(typescript@5.0.4)
dev: true
/@nodelib/fs.scandir@2.1.5:
@@ -896,7 +907,6 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
requiresBuild: true
dev: true
optional: true
/@pnpm/config.env-replace@1.1.0:
@@ -956,6 +966,23 @@ packages:
engines: {node: '>=14.17'}
dev: true
/@semantic-release/exec@6.0.3(semantic-release@21.0.1):
resolution: {integrity: sha512-bxAq8vLOw76aV89vxxICecEa8jfaWwYITw6X74zzlO0mc/Bgieqx9kBRz9z96pHectiTAtsCwsQcUyLYWnp3VQ==}
engines: {node: '>=14.17'}
peerDependencies:
semantic-release: '>=18.0.0'
dependencies:
'@semantic-release/error': 3.0.0
aggregate-error: 3.1.0
debug: 4.3.4
execa: 5.1.1
lodash: 4.17.21
parse-json: 5.2.0
semantic-release: 21.0.1(typescript@5.0.4)
transitivePeerDependencies:
- supports-color
dev: true
/@semantic-release/git@10.0.1(semantic-release@21.0.1):
resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==}
engines: {node: '>=14.17'}
@@ -1088,8 +1115,8 @@ packages:
/@types/babel__core@7.20.0:
resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==}
dependencies:
'@babel/parser': 7.21.8
'@babel/types': 7.21.5
'@babel/parser': 7.23.0
'@babel/types': 7.23.0
'@types/babel__generator': 7.6.4
'@types/babel__template': 7.4.1
'@types/babel__traverse': 7.18.5
@@ -1098,20 +1125,20 @@ packages:
/@types/babel__generator@7.6.4:
resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@types/babel__template@7.4.1:
resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
dependencies:
'@babel/parser': 7.21.8
'@babel/types': 7.21.5
'@babel/parser': 7.23.0
'@babel/types': 7.23.0
dev: true
/@types/babel__traverse@7.18.5:
resolution: {integrity: sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==}
dependencies:
'@babel/types': 7.21.5
'@babel/types': 7.23.0
dev: true
/@types/graceful-fs@4.1.6:
@@ -1143,10 +1170,6 @@ packages:
pretty-format: 29.5.0
dev: true
/@types/lodash@4.14.171:
resolution: {integrity: sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==}
dev: true
/@types/minimist@1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
dev: true
@@ -1173,6 +1196,12 @@ packages:
resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
dev: true
/@types/semantic-release@20.0.1:
resolution: {integrity: sha512-rANSSye4mYTnP6szFSFUPl9GEowqxKjfKKnE06/axdgOLIL3pQNB4u3gXelZ2wiL6J6Clzb8PSyX8Bbv/JOPHw==}
dependencies:
'@types/node': 18.16.0
dev: true
/@types/stack-utils@2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: true
@@ -1252,12 +1281,10 @@ packages:
/ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
dev: true
/ansi-regex@6.0.1:
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
engines: {node: '>=12'}
dev: true
/ansi-sequence-parser@1.1.0:
resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==}
@@ -1284,7 +1311,6 @@ packages:
/ansi-styles@6.2.1:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
dev: true
/ansicolors@0.3.2:
resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==}
@@ -1365,8 +1391,8 @@ packages:
resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/template': 7.20.7
'@babel/types': 7.21.5
'@babel/template': 7.22.15
'@babel/types': 7.23.0
'@types/babel__core': 7.20.0
'@types/babel__traverse': 7.18.5
dev: true
@@ -1815,7 +1841,6 @@ packages:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
dev: true
/crypto-random-string@4.0.0:
resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==}
@@ -1829,9 +1854,11 @@ packages:
engines: {node: '>=8'}
dev: true
/date-fns@2.29.3:
resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==}
/date-fns@2.30.0:
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
engines: {node: '>=0.11'}
dependencies:
'@babel/runtime': 7.21.5
dev: false
/dateformat@3.0.3:
@@ -1918,7 +1945,6 @@ packages:
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
dev: true
/electron-to-chromium@1.4.382:
resolution: {integrity: sha512-czMavlW52VIPgutbVL9JnZIZuFijzsG1ww/1z2Otu1r1q+9Qe2bTsH3My3sZarlvwyqHM6+mnZfEnt2Vr4dsIg==}
@@ -1931,11 +1957,9 @@ packages:
/emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true
/emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
dev: true
/env-ci@9.1.0:
resolution: {integrity: sha512-ZCEas2sDVFR3gpumwwzSU4OJZwWJ46yqJH3TqH3vSxEBzeAlC0uCJLGAnZC0vX1TIXzHzjcwpKmUn2xw5mC/qA==}
@@ -2120,7 +2144,6 @@ packages:
dependencies:
cross-spawn: 7.0.3
signal-exit: 4.0.1
dev: true
/from2@2.3.0:
resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==}
@@ -2140,6 +2163,7 @@ packages:
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
/fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
@@ -2237,17 +2261,16 @@ packages:
is-glob: 4.0.3
dev: true
/glob@10.2.2:
resolution: {integrity: sha512-Xsa0BcxIC6th9UwNjZkhrMtNo/MnyRL8jGCP+uEwhA5oFOCY1f2s1/oNKY47xQ0Bg5nkjsfAEIej1VeH62bDDQ==}
/glob@10.3.3:
resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==}
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
dependencies:
foreground-child: 3.1.1
jackspeak: 2.2.0
minimatch: 9.0.0
minimatch: 9.0.3
minipass: 5.0.0
path-scurry: 1.7.0
dev: true
path-scurry: 1.10.1
/glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
@@ -2260,16 +2283,6 @@ packages:
path-is-absolute: 1.0.1
dev: true
/glob@9.2.1:
resolution: {integrity: sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
fs.realpath: 1.0.0
minimatch: 7.4.6
minipass: 4.2.8
path-scurry: 1.7.0
dev: false
/globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'}
@@ -2469,7 +2482,6 @@ packages:
/is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
dev: true
/is-generator-fn@2.1.0:
resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
@@ -2531,7 +2543,6 @@ packages:
/isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/issue-parser@6.0.0:
resolution: {integrity: sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==}
@@ -2554,7 +2565,7 @@ packages:
engines: {node: '>=8'}
dependencies:
'@babel/core': 7.21.8
'@babel/parser': 7.21.8
'@babel/parser': 7.23.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 6.3.0
@@ -2597,7 +2608,6 @@ packages:
'@isaacs/cliui': 8.0.2
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
dev: true
/java-properties@1.0.2:
resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==}
@@ -2794,7 +2804,7 @@ packages:
resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/code-frame': 7.21.4
'@babel/code-frame': 7.22.13
'@jest/types': 29.5.0
'@types/stack-utils': 2.0.1
chalk: 4.1.2
@@ -2920,11 +2930,11 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.21.8
'@babel/generator': 7.21.5
'@babel/generator': 7.23.0
'@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8)
'@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.8)
'@babel/traverse': 7.21.5
'@babel/types': 7.21.5
'@babel/traverse': 7.23.2
'@babel/types': 7.23.0
'@jest/expect-utils': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
@@ -3178,6 +3188,10 @@ packages:
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
/lru-cache@10.0.1:
resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
engines: {node: 14 || >=16.14}
/lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
dependencies:
@@ -3196,10 +3210,6 @@ packages:
engines: {node: '>=12'}
dev: true
/lru-cache@9.1.1:
resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==}
engines: {node: 14 || >=16.14}
/lunr@2.3.9:
resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==}
dev: true
@@ -3320,13 +3330,6 @@ packages:
brace-expansion: 1.1.11
dev: true
/minimatch@7.4.6:
resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==}
engines: {node: '>=10'}
dependencies:
brace-expansion: 2.0.1
dev: false
/minimatch@9.0.0:
resolution: {integrity: sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -3334,6 +3337,12 @@ packages:
brace-expansion: 2.0.1
dev: true
/minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
/minimist-options@4.1.0:
resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
engines: {node: '>= 6'}
@@ -3346,11 +3355,6 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
/minipass@4.2.8:
resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
engines: {node: '>=8'}
dev: false
/minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
@@ -3677,7 +3681,7 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
dependencies:
'@babel/code-frame': 7.21.4
'@babel/code-frame': 7.22.13
error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
@@ -3687,7 +3691,7 @@ packages:
resolution: {integrity: sha512-kP+TQYAzAiVnzOlWOe0diD6L35s9bJh0SCn95PIbZFKrOYuIRQsQkeWEYxzVDuHTt9V9YqvYCJ2Qo4z9wdfZPw==}
engines: {node: '>=16'}
dependencies:
'@babel/code-frame': 7.21.4
'@babel/code-frame': 7.22.13
error-ex: 1.3.2
json-parse-even-better-errors: 3.0.0
lines-and-columns: 2.0.3
@@ -3719,7 +3723,6 @@ packages:
/path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
dev: true
/path-key@4.0.0:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
@@ -3730,11 +3733,11 @@ packages:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
/path-scurry@1.7.0:
resolution: {integrity: sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==}
/path-scurry@1.10.1:
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
lru-cache: 9.1.1
lru-cache: 10.0.1
minipass: 5.0.0
/path-type@3.0.0:
@@ -3954,6 +3957,10 @@ packages:
esprima: 4.0.1
dev: true
/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
/registry-auth-token@5.0.2:
resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==}
engines: {node: '>=14'}
@@ -4012,7 +4019,7 @@ packages:
engines: {node: '>=14'}
hasBin: true
dependencies:
glob: 10.2.2
glob: 10.3.3
dev: true
/run-parallel@1.2.0:
@@ -4110,12 +4117,10 @@ packages:
engines: {node: '>=8'}
dependencies:
shebang-regex: 3.0.0
dev: true
/shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
dev: true
/shiki@0.14.2:
resolution: {integrity: sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==}
@@ -4133,7 +4138,6 @@ packages:
/signal-exit@4.0.1:
resolution: {integrity: sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw==}
engines: {node: '>=14'}
dev: true
/signale@1.4.0:
resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==}
@@ -4241,7 +4245,6 @@ packages:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
dev: true
/string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
@@ -4250,7 +4253,6 @@ packages:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.0.1
dev: true
/string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
@@ -4269,14 +4271,12 @@ packages:
engines: {node: '>=8'}
dependencies:
ansi-regex: 5.0.1
dev: true
/strip-ansi@7.0.1:
resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==}
engines: {node: '>=12'}
dependencies:
ansi-regex: 6.0.1
dev: true
/strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
@@ -4540,8 +4540,8 @@ packages:
typescript: 5.0.4
dev: true
/typedoc@0.24.6(typescript@5.0.4):
resolution: {integrity: sha512-c3y3h45xJv3qYwKDAwU6Cl+26CjT0ZvblHzfHJ+SjQDM4p1mZxtgHky4lhmG0+nNarRht8kADfZlbspJWdZarQ==}
/typedoc@0.24.7(typescript@5.0.4):
resolution: {integrity: sha512-zzfKDFIZADA+XRIp2rMzLe9xZ6pt12yQOhCr7cD7/PBTjhPmMyMvGrkZ2lPNJitg3Hj1SeiYFNzCsSDrlpxpKw==}
engines: {node: '>= 14.14'}
hasBin: true
peerDependencies:
@@ -4659,7 +4659,6 @@ packages:
hasBin: true
dependencies:
isexe: 2.0.0
dev: true
/wordwrap@1.0.0:
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
@@ -4671,7 +4670,6 @@ packages:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
dev: true
/wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
@@ -4680,7 +4678,6 @@ packages:
ansi-styles: 6.2.1
string-width: 5.1.2
strip-ansi: 7.0.1
dev: true
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}

View File

@@ -1,31 +1,8 @@
const releaseRules = [
{ type: "feat", section: "Features", release: "minor" },
{ type: "revert", section: "Features", release: "minor" },
{ type: "fix", section: "Bug Fixes", release: "patch" },
{ type: "chore", section: "Misc", release: "patch" },
{ type: "refactor", section: "Misc", release: "patch" },
{ type: "perf", section: "Misc", release: "patch" },
{ type: "build", section: "Build", release: "patch" },
{ type: "docs", section: "Build", release: false },
{ type: "test", section: "Tests", release: false },
]
/** @type {import('semantic-release').Options} */
module.exports = {
branches: [
"+([0-9])?(.{+([0-9]),x}).x",
"master",
"next",
"next-major",
{ name: "develop", prerelease: true },
{ name: "beta", prerelease: true },
{ name: "alpha", prerelease: true },
],
branches: ["master", { name: "pre", prerelease: true }],
analyzeCommits: {
path: "semantic-release-conventional-commits",
majorTypes: releaseRules.filter((x) => x.release === "major").map((x) => x.type),
minorTypes: releaseRules.filter((x) => x.release === "minor").map((x) => x.type),
patchTypes: releaseRules.filter((x) => x.release === "patch").map((x) => x.type),
},
plugins: [
[
@@ -35,7 +12,6 @@ module.exports = {
parserOpts: {
noteKeywords: ["breaking:", "breaking-fix:", "breaking-feat:"],
},
releaseRules: releaseRules,
},
],
[
@@ -44,7 +20,6 @@ module.exports = {
preset: "conventionalcommits",
parserOpts: {
noteKeywords: ["breaking", "major"],
types: releaseRules,
},
},
],
@@ -77,7 +52,12 @@ module.exports = {
[
"@semantic-release/github",
{
assets: ["package.tgz"],
assets: [
{
path: "*.tgz",
name: "simple-scaffold.tgz",
},
],
},
],
],

View File

@@ -1,13 +1,16 @@
/** @type {import('simple-scaffold').ScaffoldConfigFile} */
module.exports = {
default: {
templates: ["examples/test-input/Component"],
output: "examples/test-output",
data: { property: "myProp", value: "10" },
},
component: {
templates: ["examples/test-input/Component"],
output: "examples/test-output/component",
data: { property: "myProp", value: "10" },
},
module.exports = (conf) => {
console.log("Config:", conf)
return {
default: {
templates: ["examples/test-input/Component"],
output: "examples/test-output",
data: { property: "myProp", value: "10" },
},
component: {
templates: ["examples/test-input/Component"],
output: "examples/test-output/component",
data: { property: "myProp", value: "10" },
},
}
}

View File

@@ -3,18 +3,20 @@ 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"
import { parseAppendData, parseConfig } from "./config"
import path from "node:path"
import fs from "node:fs/promises"
import { parseAppendData, parseConfigFile } from "./config"
export async function parseCliArgs(args = process.argv.slice(2)) {
const pkg = JSON.parse((await fs.readFile(path.join(__dirname, "package.json"))).toString())
const isConfig = args.includes("--config") || args.includes("-c") || args.includes("--github") || args.includes("-gh")
const pkgFile = await fs.readFile(path.join(__dirname, "package.json"))
const pkg = JSON.parse(pkgFile.toString())
const isConfigProvided =
args.includes("--config") || args.includes("-c") || args.includes("--github") || args.includes("-gh")
return (
massarg<ScaffoldCmdConfig>()
.main(async (config) => {
const _config = await parseConfig(config)
const _config = await parseConfigFile(config)
return Scaffold(_config)
})
.option({
@@ -47,7 +49,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 this path. ${chalk.reset`${chalk.white`(default: current dir)`}`}`,
required: !isConfig,
required: !isConfigProvided,
})
.option({
name: "templates",
@@ -56,7 +58,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
description:
"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.",
required: !isConfig,
required: !isConfigProvided,
})
.option({
name: "overwrite",

View File

@@ -1,23 +1,17 @@
import path from "path"
import path from "node:path"
import {
AsyncResolver,
ConfigLoadConfig,
FileResponse,
FileResponseHandler,
LogConfig,
LogLevel,
Resolver,
ScaffoldCmdConfig,
ScaffoldConfig,
ScaffoldConfigFile,
ScaffoldConfigMap,
} from "./types"
import { OptionsBase } from "massarg/types"
import { spawn } from "node:child_process"
import os from "node:os"
import { handlebarsParse } from "./parser"
import { log } from "./logger"
import { resolve } from "./utils"
import { resolve, wrapNoopResolver } from "./utils"
import { getGitConfig } from "./git"
export function getOptionValueForFile<T>(
config: ScaffoldConfig,
@@ -35,7 +29,7 @@ export function getOptionValueForFile<T>(
)
}
export function parseAppendData(value: string, options: ScaffoldCmdConfig & OptionsBase): unknown {
export function parseAppendData(value: string, options: ScaffoldCmdConfig): unknown {
const data = options.data ?? {}
const [key, val] = value.split(/\:?=/)
// raw
@@ -50,38 +44,35 @@ function isWrappedWithQuotes(string: string): boolean {
}
/** @internal */
export async function parseConfig(config: ScaffoldCmdConfig & OptionsBase): Promise<ScaffoldConfig> {
export async function parseConfigFile(config: ScaffoldCmdConfig): Promise<ScaffoldConfig> {
let c: ScaffoldConfig = config
if (config.github) {
log(config, LogLevel.Info, `Loading config from github ${config.github}`)
const gitUrl = new URL(`https://github.com/${config.github}`)
if (!gitUrl.pathname.endsWith(".git")) {
gitUrl.pathname += ".git"
}
config.config = gitUrl.toString()
config.config = githubPartToUrl(config.github)
}
if (config.config) {
const isUrl = config.config.includes("://")
const hasColonToken = (!isUrl && config.config.includes(":")) || (isUrl && count(config.config, ":") > 1)
const colonIndex = config.config.lastIndexOf(":")
const [configFile, templateKey = "default"] = hasColonToken
? [config.config.substring(0, colonIndex), config.config.substring(colonIndex + 1)]
: [config.config, undefined]
const key = (config.key ?? templateKey) || "default"
const { configFile, key, isRemote } = parseConfigSelection(config.config, config.key)
log(config, LogLevel.Info, `Loading config from ${configFile} with key ${key}`)
const configPromise = await getConfig({ config: configFile, quiet: config.quiet, verbose: config.verbose })
const configImport = await resolve(configPromise, config)
const configPromise = await getConfig({
config: configFile,
isRemote,
quiet: config.quiet,
verbose: config.verbose,
})
let configImport = await resolve(configPromise, config)
if (typeof configImport.default === "function" || configImport.default instanceof Promise) {
configImport = await resolve(configImport.default, config)
}
if (!configImport[key]) {
throw new Error(`Template "${key}" not found in ${configFile}`)
}
const importedKey = configImport[key]
c = {
...config,
...configImport[key],
...importedKey,
data: {
...configImport[key].data,
...(importedKey as any).data,
...config.data,
},
}
@@ -92,77 +83,54 @@ export async function parseConfig(config: ScaffoldCmdConfig & OptionsBase): Prom
return c
}
function wrapNoopResolver<T, R = T>(value: Resolver<T, R>): Resolver<T, R> {
if (typeof value === "function") {
return value
}
export function parseConfigSelection(
config: string,
key?: string,
): { configFile: string; key: string; isRemote: boolean } {
const isUrl = config.includes("://")
return (_) => value
const hasColonToken = (!isUrl && config.includes(":")) || (isUrl && count(config, ":") > 1)
const colonIndex = config.lastIndexOf(":")
const [configFile, templateKey = "default"] = hasColonToken
? [config.substring(0, colonIndex), config.substring(colonIndex + 1)]
: [config, undefined]
const _key = (key ?? templateKey) || "default"
return { configFile, key: _key, isRemote: isUrl }
}
export function githubPartToUrl(part: string): string {
const gitUrl = new URL(`https://github.com/${part}`)
if (!gitUrl.pathname.endsWith(".git")) {
gitUrl.pathname += ".git"
}
return gitUrl.toString()
}
/** @internal */
export async function getConfig(config: ConfigLoadConfig): Promise<ScaffoldConfigFile> {
const { config: configFile, ...logConfig } = config as Required<typeof config>
const url = new URL(configFile)
const { config: configFile, isRemote, ...logConfig } = config as Required<typeof config>
if (url.protocol === "file:") {
if (!isRemote) {
log(logConfig, LogLevel.Info, `Loading config from file ${configFile}`)
const absolutePath = path.resolve(process.cwd(), configFile)
return wrapNoopResolver(import(absolutePath))
}
const url = new URL(configFile)
const isHttp = url.protocol === "http:" || url.protocol === "https:"
const isGit = url.protocol === "git:" || (isHttp && url.pathname.endsWith(".git"))
if (isHttp || isGit) {
if (isGit) {
return getGitConfig(url, logConfig)
}
if (isGit) {
return getGitConfig(url, logConfig)
}
if (!isHttp) {
throw new Error(`Unsupported protocol ${url.protocol}`)
}
return wrapNoopResolver(import(path.resolve(process.cwd(), configFile)))
}
async function getGitConfig(
url: URL,
logConfig: LogConfig,
): Promise<AsyncResolver<ScaffoldCmdConfig, ScaffoldConfigMap>> {
const repoUrl = `${url.protocol}//${url.host}${url.pathname}`
log(logConfig, LogLevel.Info, `Cloning git repo ${repoUrl}`)
const tmpPath = path.resolve(os.tmpdir(), `scaffold-config-${Date.now()}`)
return new Promise((resolve, reject) => {
const clone = spawn("git", ["clone", "--depth", "1", repoUrl, tmpPath])
clone.on("error", reject)
clone.on("close", async (code) => {
if (code === 0) {
log(logConfig, LogLevel.Info, `Loading config from git repo: ${repoUrl}`)
const hashPath = url.hash?.replace("#", "") || "scaffold.config.js"
const absolutePath = path.resolve(tmpPath, hashPath)
const loadedConfig = (await import(absolutePath)).default as ScaffoldConfigMap
log(logConfig, LogLevel.Info, `Loaded config from git`)
log(logConfig, LogLevel.Debug, `Raw config:`, loadedConfig)
const fixedConfig: ScaffoldConfigMap = Object.fromEntries(
Object.entries(loadedConfig).map(([k, v]) => [
k,
// use absolute paths for template as config is necessarily in another directory
{ ...v, templates: v.templates.map((t) => path.resolve(tmpPath, t)) },
]),
)
resolve(wrapNoopResolver(fixedConfig))
} else {
reject(new Error(`Git clone failed with code ${code}`))
}
})
})
}
function count(string: string, substring: string): number {
return string.split(substring).length - 1
}

View File

@@ -1,17 +1,20 @@
import path from "path"
import { F_OK } from "constants"
import path from "node:path"
import { F_OK } from "node:constants"
import { LogLevel, ScaffoldConfig } from "./types"
import { promises as fsPromises } from "fs"
const { stat, access, mkdir } = fsPromises
import fs from "node:fs/promises"
import { glob, hasMagic } from "glob"
import { log } from "./logger"
import { getOptionValueForFile } from "./config"
import { handlebarsParse } from "./parser"
import { handleErr } from "./utils"
const { readFile, writeFile } = fsPromises
const { stat, access, mkdir, readFile, writeFile } = fs
export async function createDirIfNotExists(dir: string, config: ScaffoldConfig): Promise<void> {
if (config.dryRun) {
log(config, LogLevel.Info, `Dry Run. Not creating dir ${dir}`)
return
}
const parentDir = path.dirname(dir)
if (!(await pathExists(parentDir))) {
@@ -50,7 +53,7 @@ export async function isDir(path: string): Promise<boolean> {
}
export function removeGlob(template: string): string {
return template.replace(/\*/g, "").replace(/(\/\/|\\\\)/g, path.sep)
return path.normalize(template.replace(/\*/g, ""))
}
export function makeRelativePath(str: string): string {
@@ -65,6 +68,8 @@ export function getBasePath(relPath: string): string {
}
export async function getFileList(_config: ScaffoldConfig, template: string): Promise<string[]> {
template = template.replaceAll(/[\\]+/g, "/")
log(_config, LogLevel.Debug, `Getting file list for ${template}`)
return (
await glob(template, {
dot: true,
@@ -89,8 +94,8 @@ export async function getTemplateGlobInfo(config: ScaffoldConfig, template: stri
let nonGlobTemplate = isGlob ? removeGlob(template) : template
nonGlobTemplate = path.normalize(nonGlobTemplate)
const isDirOrGlob = isGlob ? true : await isDir(template)
log(config, LogLevel.Debug, "after isDir", isDirOrGlob)
const _shouldAddGlob = !isGlob && isDirOrGlob
log(config, LogLevel.Debug, "after", { isDirOrGlob, _shouldAddGlob })
const origTemplate = template
if (_shouldAddGlob) {
_template = path.join(template, "**", "*")
@@ -148,7 +153,7 @@ export async function copyFileTransformed(
log(config, LogLevel.Info, "Done.")
} else {
log(config, LogLevel.Info, "Dry Run. Output should be:")
log(config, LogLevel.Info, finalOutputContents)
log(config, LogLevel.Info, finalOutputContents.toString())
}
} else if (exists) {
log(config, LogLevel.Info, `File ${outputPath} already exists, skipping`)

48
src/git.ts Normal file
View File

@@ -0,0 +1,48 @@
import path from "node:path"
import os from "node:os"
import { log } from "./logger"
import { AsyncResolver, LogConfig, LogLevel, ScaffoldCmdConfig, ScaffoldConfig, ScaffoldConfigMap } from "./types"
import { spawn } from "node:child_process"
import { resolve, wrapNoopResolver } from "./utils"
export async function getGitConfig(
url: URL,
logConfig: LogConfig,
): Promise<AsyncResolver<ScaffoldCmdConfig, ScaffoldConfigMap>> {
const repoUrl = `${url.protocol}//${url.host}${url.pathname}`
log(logConfig, LogLevel.Info, `Cloning git repo ${repoUrl}`)
const tmpPath = path.resolve(os.tmpdir(), `scaffold-config-${Date.now()}`)
return new Promise((res, reject) => {
const clone = spawn("git", ["clone", "--depth", "1", repoUrl, tmpPath])
clone.on("error", reject)
clone.on("close", async (code) => {
if (code === 0) {
log(logConfig, LogLevel.Info, `Loading config from git repo: ${repoUrl}`)
const hashPath = url.hash?.replace("#", "") || "scaffold.config.js"
const absolutePath = path.resolve(tmpPath, hashPath)
const loadedConfig = await resolve(
async () => (await import(absolutePath)).default as ScaffoldConfigMap,
logConfig,
)
log(logConfig, LogLevel.Info, `Loaded config from git`)
log(logConfig, LogLevel.Debug, `Raw config:`, loadedConfig)
const fixedConfig: ScaffoldConfigMap = {}
for (const [k, v] of Object.entries(loadedConfig)) {
fixedConfig[k] = {
...v,
templates: v.templates.map((t) => path.resolve(tmpPath, t)),
}
}
res(wrapNoopResolver(fixedConfig))
return
}
reject(new Error(`Git clone failed with code ${code}`))
})
})
}

View File

@@ -30,19 +30,10 @@ export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void {
export function logInputFile(
config: ScaffoldConfig,
{
origTemplate,
relPath,
template,
inputFilePath,
nonGlobTemplate,
basePath,
isDirOrGlob,
isGlob,
}: {
origTemplate: string
relPath: string
template: string
data: {
originalTemplate: string
relativePath: string
parsedTemplate: string
inputFilePath: string
nonGlobTemplate: string
basePath: string
@@ -50,20 +41,7 @@ export function logInputFile(
isGlob: boolean
},
): void {
log(
config,
LogLevel.Debug,
`\nprocess.cwd(): ${process.cwd()}`,
`\norigTemplate: ${origTemplate}`,
`\nrelPath: ${relPath}`,
`\ntemplate: ${template}`,
`\ninputFilePath: ${inputFilePath}`,
`\nnonGlobTemplate: ${nonGlobTemplate}`,
`\nbasePath: ${basePath}`,
`\nisDirOrGlob: ${isDirOrGlob}`,
`\nisGlob: ${isGlob}`,
`\n`,
)
log(config, LogLevel.Debug, data)
}
export function logInitStep(config: ScaffoldConfig): void {

View File

@@ -1,9 +1,5 @@
import path from "path"
import path from "node:path"
import { DefaultHelpers, Helper, LogLevel, ScaffoldConfig } from "./types"
import camelCase from "lodash/camelCase"
import snakeCase from "lodash/snakeCase"
import kebabCase from "lodash/kebabCase"
import startCase from "lodash/startCase"
import Handlebars from "handlebars"
import dtAdd from "date-fns/add"
import dtFormat from "date-fns/format"
@@ -29,14 +25,9 @@ export const defaultHelpers: Record<DefaultHelpers, Helper> = {
date: dateHelper,
}
export function _dateHelper(date: Date, formatString: string): string
export function _dateHelper(
date: Date,
formatString: string,
durationDifference: number,
durationType: keyof Duration,
): string
export function _dateHelper(
function _dateHelper(date: Date, formatString: string): string
function _dateHelper(date: Date, formatString: string, durationDifference: number, durationType: keyof Duration): string
function _dateHelper(
date: Date,
formatString: string,
durationDifference?: number,
@@ -61,7 +52,6 @@ export function dateHelper(
durationDifference: number,
durationType: keyof Duration,
): string
export function dateHelper(
date: string,
formatString: string,
@@ -71,7 +61,35 @@ export function dateHelper(
return _dateHelper(dateFns.parseISO(date), formatString, durationDifference!, durationType!)
}
export function pascalCase(s: string): string {
// splits by either non-alpha character or capital letter
function toWordParts(string: string): string[] {
return string.split(/(?=[A-Z])|[^a-zA-Z]/).filter((s) => s.length > 0)
}
function camelCase(s: string): string {
return toWordParts(s).reduce((acc, part, i) => {
if (i === 0) {
return part.toLowerCase()
}
return acc + part[0].toUpperCase() + part.slice(1).toLowerCase()
}, "")
}
function snakeCase(s: string): string {
return toWordParts(s).join("_").toLowerCase()
}
function kebabCase(s: string): string {
return toWordParts(s).join("-").toLowerCase()
}
function startCase(s: string): string {
return toWordParts(s)
.map((part) => part[0].toUpperCase() + part.slice(1).toLowerCase())
.join(" ")
}
function pascalCase(s: string): string {
return startCase(s).replace(/\s+/g, "")
}

View File

@@ -4,25 +4,21 @@
*
* See [readme](README.md)
*/
import path from "path"
import path from "node:path"
import { handleErr, resolve } from "./utils"
import {
createDirIfNotExists,
isDir,
removeGlob,
makeRelativePath,
getTemplateGlobInfo,
getFileList,
getBasePath,
copyFileTransformed,
getTemplateFileInfo,
handleTemplateFile,
} from "./file"
import { LogLevel, MinimalConfig, Resolver, ScaffoldCmdConfig, ScaffoldConfig } from "./types"
import { OptionsBase } from "massarg/types"
import { pascalCase, registerHelpers } from "./parser"
import { defaultHelpers, registerHelpers } from "./parser"
import { log, logInitStep, logInputFile } from "./logger"
import { getOptionValueForFile, parseConfig } from "./config"
import { parseConfigFile } from "./config"
/**
* Create a scaffold using given `options`.
@@ -61,7 +57,7 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
registerHelpers(config)
try {
config.data = { name: config.name, Name: pascalCase(config.name), ...config.data }
config.data = { name: config.name, Name: defaultHelpers.pascalCase(config.name), ...config.data }
logInitStep(config)
for (let _template of config.templates) {
try {
@@ -70,6 +66,7 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
_template,
)
const files = await getFileList(config, template)
log(config, LogLevel.Debug, "Iterating files", { files, template })
for (const inputFilePath of files) {
if (await isDir(inputFilePath)) {
continue
@@ -77,9 +74,9 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
const relPath = makeRelativePath(path.dirname(removeGlob(inputFilePath).replace(nonGlobTemplate, "")))
const basePath = getBasePath(relPath)
logInputFile(config, {
origTemplate,
relPath,
template,
originalTemplate: origTemplate,
relativePath: relPath,
parsedTemplate: template,
inputFilePath,
nonGlobTemplate,
basePath,
@@ -112,7 +109,7 @@ export async function Scaffold(config: ScaffoldConfig): Promise<void> {
* @category Main
* @return {Promise<void>} A promise that resolves when the scaffold is complete
*/
Scaffold.fromConfig = async function (
Scaffold.fromConfig = async function(
/** The path or URL to the config file */
pathOrUrl: string,
/** Information needed before loading the config */
@@ -120,7 +117,7 @@ Scaffold.fromConfig = async function (
/** Any overrides to the loaded config */
overrides?: Resolver<ScaffoldCmdConfig, Partial<Omit<ScaffoldConfig, "name">>>,
): Promise<void> {
const _cmdConfig: ScaffoldCmdConfig & OptionsBase = {
const _cmdConfig: ScaffoldCmdConfig = {
dryRun: false,
output: process.cwd(),
verbose: LogLevel.Info,
@@ -128,13 +125,11 @@ Scaffold.fromConfig = async function (
templates: [],
createSubFolder: false,
quiet: false,
help: false,
extras: [],
config: pathOrUrl,
...config,
}
const _overrides = resolve(overrides, _cmdConfig)
const _config = await parseConfig(_cmdConfig)
const _config = await parseConfigFile(_cmdConfig)
return Scaffold({ ..._config, ..._overrides })
}

View File

@@ -376,7 +376,7 @@ export type AsyncResolver<T, R = T> = Resolver<T, Promise<R> | R>
export type LogConfig = Pick<ScaffoldConfig, "quiet" | "verbose">
/** @internal */
export type ConfigLoadConfig = LogConfig & Pick<ScaffoldCmdConfig, "config">
export type ConfigLoadConfig = LogConfig & Pick<ScaffoldCmdConfig, "config"> & { isRemote: boolean }
/** @internal */
export type MinimalConfig = Pick<ScaffoldCmdConfig, "name" | "key">

View File

@@ -7,3 +7,11 @@ export function handleErr(err: NodeJS.ErrnoException | null): void {
export function resolve<T, R = T>(resolver: Resolver<T, R>, arg: T): R {
return typeof resolver === "function" ? (resolver as (value: T) => R)(arg) : (resolver as R)
}
export function wrapNoopResolver<T, R = T>(value: Resolver<T, R>): Resolver<T, R> {
if (typeof value === "function") {
return value
}
return (_) => value
}

149
tests/config.test.ts Normal file
View File

@@ -0,0 +1,149 @@
import { ScaffoldCmdConfig } from "../src/types"
import * as config from "../src/config"
import { resolve } from "../src/utils"
// @ts-ignore
import * as configFile from "../scaffold.config"
jest.mock("../src/git", () => {
return {
__esModule: true,
...jest.requireActual("../src/git"),
getGitConfig: () => {
return Promise.resolve(blankCliConf)
},
}
})
const { githubPartToUrl, parseAppendData, parseConfigFile, parseConfigSelection } = config
const blankCliConf: ScaffoldCmdConfig = {
verbose: 0,
name: "",
output: "",
templates: [],
data: { name: "test" },
overwrite: false,
createSubFolder: false,
dryRun: false,
quiet: false,
}
describe("config", () => {
describe("parseAppendData", () => {
test('works for "key=value"', () => {
expect(parseAppendData("key=value", blankCliConf)).toEqual({ key: "value", name: "test" })
})
test('works for "key:=value"', () => {
expect(parseAppendData("key:=123", blankCliConf)).toEqual({ key: 123, name: "test" })
})
test("overwrites existing value", () => {
expect(parseAppendData("name:=123", blankCliConf)).toEqual({ name: 123 })
})
test("works with quotes", () => {
expect(parseAppendData('key="value test"', blankCliConf)).toEqual({ key: "value test", name: "test" })
})
})
describe("githubPartToUrl", () => {
test("works", () => {
expect(githubPartToUrl("chenasraf/simple-scaffold")).toEqual("https://github.com/chenasraf/simple-scaffold.git")
expect(githubPartToUrl("chenasraf/simple-scaffold.git")).toEqual(
"https://github.com/chenasraf/simple-scaffold.git",
)
})
})
describe("parseConfigSelection", () => {
test("no key", () => {
expect(parseConfigSelection("scaffold.config.js")).toEqual({
configFile: "scaffold.config.js",
key: "default",
isRemote: false,
})
})
test("separate key", () => {
expect(parseConfigSelection("scaffold.config.js", "component")).toEqual({
configFile: "scaffold.config.js",
key: "component",
isRemote: false,
})
})
test("key override", () => {
expect(parseConfigSelection("scaffold.config.js:component", "main")).toEqual({
configFile: "scaffold.config.js",
key: "main",
isRemote: false,
})
})
test("isRemote: false", () => {
expect(parseConfigSelection("scaffold.config.js", "main")).toEqual({
configFile: "scaffold.config.js",
key: "main",
isRemote: false,
})
})
test("isRemote: true", () => {
expect(
parseConfigSelection("https://github.com/chenasraf/simple-scaffold.git#scaffold.config.js:component", "main"),
).toEqual({
configFile: "https://github.com/chenasraf/simple-scaffold.git#scaffold.config.js",
key: "main",
isRemote: true,
})
})
})
describe("parseConfigFile", () => {
test("normal config does not change", async () => {
expect(
await parseConfigFile({
...blankCliConf,
}),
).toEqual(blankCliConf)
})
describe("appendData", () => {
test("appends", async () => {
const result = await parseConfigFile({
...blankCliConf,
appendData: { key: "value" },
})
expect(result?.data?.key).toEqual("value")
})
test("overwrites existing value", async () => {
const result = await parseConfigFile({
...blankCliConf,
data: { num: "123" },
appendData: { num: "1234" },
})
expect(result?.data?.num).toEqual("1234")
})
})
})
describe("getConfig", () => {
test("gets git config", async () => {
const resultFn = await config.getConfig({
config: "https://github.com/chenasraf/simple-scaffold.git",
isRemote: true,
quiet: true,
verbose: 0,
})
const result = await resolve(resultFn, blankCliConf)
expect(result).toEqual(blankCliConf)
})
test("gets local file config", async () => {
const resultFn = await config.getConfig({
config: "scaffold.config.js",
isRemote: false,
quiet: true,
verbose: 0,
})
const result = await resolve(resultFn, {} as any)
expect(result).toEqual(configFile)
})
})
})

148
tests/parser.test.ts Normal file
View File

@@ -0,0 +1,148 @@
import { ScaffoldCmdConfig, ScaffoldConfig } from "../src/types"
import path from "node:path"
import * as dateFns from "date-fns"
import { OptionsBase } from "massarg/types"
import { dateHelper, defaultHelpers, handlebarsParse, nowHelper } from "../src/parser"
const blankConf: ScaffoldConfig = {
verbose: 0,
name: "",
output: "",
templates: [],
data: { name: "test" },
}
const blankCliConf: ScaffoldCmdConfig & OptionsBase = {
verbose: 0,
name: "",
output: "",
templates: [],
data: { name: "test" },
overwrite: false,
createSubFolder: false,
dryRun: false,
quiet: false,
extras: [],
help: false,
}
describe("parser", () => {
describe("handlebarsParse", () => {
let origSep: any
describe("windows paths", () => {
beforeAll(() => {
origSep = path.sep
Object.defineProperty(path, "sep", { value: "\\" })
})
afterAll(() => {
Object.defineProperty(path, "sep", { value: origSep })
})
test("should work for windows paths", async () => {
expect(handlebarsParse(blankConf, "C:\\exports\\{{name}}.txt", { isPath: true }).toString()).toEqual(
"C:\\exports\\test.txt",
)
})
})
describe("non-windows paths", () => {
beforeAll(() => {
origSep = path.sep
Object.defineProperty(path, "sep", { value: "/" })
})
afterAll(() => {
Object.defineProperty(path, "sep", { value: origSep })
})
test("should work for non-windows paths", async () => {
expect(handlebarsParse(blankConf, "/home/test/{{name}}.txt", { isPath: true })).toEqual(
Buffer.from("/home/test/test.txt"),
)
})
})
test("should not do path escaping on non-path compiles", async () => {
expect(
handlebarsParse(
{ ...blankConf, data: { ...blankConf.data, escaped: "value" } },
"/home/test/{{name}} \\{{escaped}}.txt",
{
isPath: false,
},
),
).toEqual(Buffer.from("/home/test/test {{escaped}}.txt"))
})
})
describe("Helpers", () => {
describe("string helpers", () => {
test("camelCase", () => {
expect(defaultHelpers.camelCase("test string")).toEqual("testString")
expect(defaultHelpers.camelCase("test_string")).toEqual("testString")
expect(defaultHelpers.camelCase("test-string")).toEqual("testString")
expect(defaultHelpers.camelCase("testString")).toEqual("testString")
expect(defaultHelpers.camelCase("TestString")).toEqual("testString")
expect(defaultHelpers.camelCase("Test____String")).toEqual("testString")
})
test("pascalCase", () => {
expect(defaultHelpers.pascalCase("test string")).toEqual("TestString")
expect(defaultHelpers.pascalCase("test_string")).toEqual("TestString")
expect(defaultHelpers.pascalCase("test-string")).toEqual("TestString")
expect(defaultHelpers.pascalCase("testString")).toEqual("TestString")
expect(defaultHelpers.pascalCase("TestString")).toEqual("TestString")
expect(defaultHelpers.pascalCase("Test____String")).toEqual("TestString")
})
test("snakeCase", () => {
expect(defaultHelpers.snakeCase("test string")).toEqual("test_string")
expect(defaultHelpers.snakeCase("test_string")).toEqual("test_string")
expect(defaultHelpers.snakeCase("test-string")).toEqual("test_string")
expect(defaultHelpers.snakeCase("testString")).toEqual("test_string")
expect(defaultHelpers.snakeCase("TestString")).toEqual("test_string")
expect(defaultHelpers.snakeCase("Test____String")).toEqual("test_string")
})
test("kebabCase", () => {
expect(defaultHelpers.kebabCase("test string")).toEqual("test-string")
expect(defaultHelpers.kebabCase("test_string")).toEqual("test-string")
expect(defaultHelpers.kebabCase("test-string")).toEqual("test-string")
expect(defaultHelpers.kebabCase("testString")).toEqual("test-string")
expect(defaultHelpers.kebabCase("TestString")).toEqual("test-string")
expect(defaultHelpers.kebabCase("Test____String")).toEqual("test-string")
})
test("startCase", () => {
expect(defaultHelpers.startCase("test string")).toEqual("Test String")
expect(defaultHelpers.startCase("test_string")).toEqual("Test String")
expect(defaultHelpers.startCase("test-string")).toEqual("Test String")
expect(defaultHelpers.startCase("testString")).toEqual("Test String")
expect(defaultHelpers.startCase("TestString")).toEqual("Test String")
expect(defaultHelpers.startCase("Test____String")).toEqual("Test String")
})
})
describe("date helpers", () => {
describe("now", () => {
test("should work without extra params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(nowHelper(fmt)).toEqual(dateFns.format(now, fmt))
})
})
describe("date", () => {
test("should work with no offset params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(dateHelper(now.toISOString(), fmt)).toEqual(dateFns.format(now, fmt))
})
test("should work with offset params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(dateHelper(now.toISOString(), fmt, -1, "days")).toEqual(
dateFns.format(dateFns.add(now, { days: -1 }), fmt),
)
expect(dateHelper(now.toISOString(), fmt, 1, "months")).toEqual(
dateFns.format(dateFns.add(now, { months: 1 }), fmt),
)
})
})
})
})
})

View File

@@ -1,125 +1,21 @@
import { ScaffoldCmdConfig, ScaffoldConfig } from "../src/types"
import path from "path"
import * as dateFns from "date-fns"
import { OptionsBase } from "massarg/types"
import { dateHelper, handlebarsParse, nowHelper } from "../src/parser"
import { parseAppendData } from "../src/config"
import { handleErr, resolve } from "../src/utils"
const blankConf: ScaffoldConfig = {
verbose: 0,
name: "",
output: "",
templates: [],
data: { name: "test" },
}
const blankCliConf: ScaffoldCmdConfig & OptionsBase = {
verbose: 0,
name: "",
output: "",
templates: [],
data: { name: "test" },
overwrite: false,
createSubFolder: false,
dryRun: false,
quiet: false,
extras: [],
help: false,
}
describe("Utils", () => {
describe("handlebarsParse", () => {
let origSep: any
describe("windows paths", () => {
beforeAll(() => {
origSep = path.sep
Object.defineProperty(path, "sep", { value: "\\" })
})
afterAll(() => {
Object.defineProperty(path, "sep", { value: origSep })
})
test("should work for windows paths", async () => {
expect(handlebarsParse(blankConf, "C:\\exports\\{{name}}.txt", { isPath: true })).toEqual(
Buffer.from("C:\\exports\\test.txt"),
)
})
describe("utils", () => {
describe("resolve", () => {
test("should resolve function", () => {
expect(resolve(() => 1, null)).toBe(1)
expect(resolve((x) => x, 2)).toBe(2)
})
describe("non-windows paths", () => {
beforeAll(() => {
origSep = path.sep
Object.defineProperty(path, "sep", { value: "/" })
})
afterAll(() => {
Object.defineProperty(path, "sep", { value: origSep })
})
test("should work for non-windows paths", async () => {
expect(handlebarsParse(blankConf, "/home/test/{{name}}.txt", { isPath: true })).toEqual(
Buffer.from("/home/test/test.txt"),
)
})
})
test("should not do path escaping on non-path compiles", async () => {
expect(
handlebarsParse(
{ ...blankConf, data: { ...blankConf.data, escaped: "value" } },
"/home/test/{{name}} \\{{escaped}}.txt",
{
isPath: false,
},
),
).toEqual(Buffer.from("/home/test/test {{escaped}}.txt"))
test("should resolve value", () => {
expect(resolve(1, null)).toBe(1)
expect(resolve(2, 1)).toBe(2)
})
})
describe("Helpers", () => {
describe("date helpers", () => {
describe("now", () => {
test("should work without extra params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(nowHelper(fmt)).toEqual(dateFns.format(now, fmt))
})
})
describe("date", () => {
test("should work with no offset params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(dateHelper(now.toISOString(), fmt)).toEqual(dateFns.format(now, fmt))
})
test("should work with offset params", () => {
const now = new Date()
const fmt = "yyyy-MM-dd HH:mm"
expect(dateHelper(now.toISOString(), fmt, -1, "days")).toEqual(
dateFns.format(dateFns.add(now, { days: -1 }), fmt),
)
expect(dateHelper(now.toISOString(), fmt, 1, "months")).toEqual(
dateFns.format(dateFns.add(now, { months: 1 }), fmt),
)
})
})
})
})
describe("parseAppendData", () => {
test('works for "key=value"', () => {
expect(parseAppendData("key=value", blankCliConf)).toEqual({ key: "value", name: "test" })
})
test('works for "key:=value"', () => {
expect(parseAppendData("key:=123", blankCliConf)).toEqual({ key: 123, name: "test" })
})
test("overwrites existing value", () => {
expect(parseAppendData("name:=123", blankCliConf)).toEqual({ name: 123 })
})
test("works with quotes", () => {
expect(parseAppendData('key="value test"', blankCliConf)).toEqual({ key: "value test", name: "test" })
describe("handleErr", () => {
test("should throw error", () => {
expect(() => handleErr({ name: "test", message: "test" })).toThrow()
expect(() => handleErr(null as never)).not.toThrow()
})
})
})

View File

@@ -1,4 +1,5 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
@@ -9,7 +10,10 @@
"outDir": "dist",
"strict": true,
"sourceMap": true,
"removeComments": false
"removeComments": false,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/index.ts", "src/cmd.ts"],
"exclude": ["tests/*"]

View File

@@ -1,4 +1,4 @@
const path = require("path")
const path = require("node:path")
/** @type {import('typedoc').TypeDocOptions} */
module.exports = {