@d-zero/create-frontend 5.0.0-beta.9 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,81 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.1.0](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0...v5.1.0) (2026-04-08)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **create-frontend:** correct minimatch import ([c6e5eb1](https://github.com/d-zero-dev/frontend-env/commit/c6e5eb1c078d0805015a9e619d0289d8a9ba700c))
11
+ - **create-frontend:** correct scaffold file filtering in interactive mode ([ffa3476](https://github.com/d-zero-dev/frontend-env/commit/ffa34761a72204667605581d6ac32c2b1936babf)), closes [#804](https://github.com/d-zero-dev/frontend-env/issues/804)
12
+ - **create-frontend:** exclude dotfiles from ignored patterns ([a4da0d0](https://github.com/d-zero-dev/frontend-env/commit/a4da0d03d36b95bb60a5990ffc916095909cfd77))
13
+
14
+ ### Features
15
+
16
+ - **create-frontend:** exclude index files for CMS types and format generated files ([cdd2a25](https://github.com/d-zero-dev/frontend-env/commit/cdd2a25874e7ec21a055abb74a206fe681345518))
17
+
18
+ # [5.0.0](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.19...v5.0.0) (2026-01-05)
19
+
20
+ **Note:** Version bump only for package @d-zero/create-frontend
21
+
22
+ # [5.0.0-beta.19](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.18...v5.0.0-beta.19) (2025-12-22)
23
+
24
+ **Note:** Version bump only for package @d-zero/create-frontend
25
+
26
+ # [5.0.0-beta.18](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.17...v5.0.0-beta.18) (2025-11-25)
27
+
28
+ **Note:** Version bump only for package @d-zero/create-frontend
29
+
30
+ # [5.0.0-beta.17](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.16...v5.0.0-beta.17) (2025-10-23)
31
+
32
+ **Note:** Version bump only for package @d-zero/create-frontend
33
+
34
+ # [5.0.0-beta.16](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.15...v5.0.0-beta.16) (2025-10-23)
35
+
36
+ ### Features
37
+
38
+ - **create-frontend:** remove burger editor scripts and add css dependency for basercms ([609d11c](https://github.com/d-zero-dev/frontend-env/commit/609d11cba279068aac411ec240f7c5d4bec24370))
39
+
40
+ # [5.0.0-beta.15](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.14...v5.0.0-beta.15) (2025-10-20)
41
+
42
+ **Note:** Version bump only for package @d-zero/create-frontend
43
+
44
+ # [5.0.0-beta.14](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.13...v5.0.0-beta.14) (2025-10-20)
45
+
46
+ ### Bug Fixes
47
+
48
+ - **create-frontend:** prevent gitignore file copy from being skipped ([6b80db7](https://github.com/d-zero-dev/frontend-env/commit/6b80db70238b3e3cb403a18a4b1f03f047ef144c))
49
+
50
+ # [5.0.0-beta.13](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.12...v5.0.0-beta.13) (2025-10-20)
51
+
52
+ ### Bug Fixes
53
+
54
+ - **create-frontend:** correct typo in volta-install-node command ([a18fda9](https://github.com/d-zero-dev/frontend-env/commit/a18fda9bbfbbeab1ae5233d4eb5655936b1ed458))
55
+
56
+ # [5.0.0-beta.12](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.11...v5.0.0-beta.12) (2025-10-20)
57
+
58
+ ### Features
59
+
60
+ - **create-frontend:** add volta and node installation support ([29e4fff](https://github.com/d-zero-dev/frontend-env/commit/29e4fff6af41be56397ba25f699e946a1f16c10a))
61
+
62
+ # [5.0.0-beta.11](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.10...v5.0.0-beta.11) (2025-10-20)
63
+
64
+ ### Features
65
+
66
+ - **create-frontend:** improve command execution and add volta setup ([e54a526](https://github.com/d-zero-dev/frontend-env/commit/e54a526da7629a9b86fb6d5a53f0aaba72118d9b))
67
+
68
+ # [5.0.0-beta.10](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.9...v5.0.0-beta.10) (2025-10-20)
69
+
70
+ ### Bug Fixes
71
+
72
+ - **create-frontend:** correct file extension from .cjs to .js in blocks data path ([b425f76](https://github.com/d-zero-dev/frontend-env/commit/b425f76b9fb51302a0b26f0149407787679f33ac))
73
+
74
+ ### Features
75
+
76
+ - **create-frontend:** add gitignore rewrite functionality ([e2a6e75](https://github.com/d-zero-dev/frontend-env/commit/e2a6e75ad6d58416cee8b35642ccdc542532ab73))
77
+ - **create-frontend:** add library copying functionality for baserCMS projects ([8e73300](https://github.com/d-zero-dev/frontend-env/commit/8e73300a730aa7dcdcc2f19bb57b99eb5f4d561c))
78
+ - **create-frontend:** update project type options and remove unused blocks.html ([b003628](https://github.com/d-zero-dev/frontend-env/commit/b00362847c11493ab14f8c87c01f9577563f2e07))
79
+ - **scaffold:** add baserCMS-specific meta template and conditional inclusion ([885fe35](https://github.com/d-zero-dev/frontend-env/commit/885fe352ecb692cd1ccf3ca4ee1d82749193a60d))
80
+
6
81
  # [5.0.0-beta.9](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.8...v5.0.0-beta.9) (2025-10-05)
7
82
 
8
83
  **Note:** Version bump only for package @d-zero/create-frontend
package/README.md CHANGED
@@ -7,11 +7,61 @@
7
7
  空のリポジトリで次のパッケージを実行します。
8
8
 
9
9
  ```shell
10
+ yarn create @d-zero/frontend
11
+
12
+ # 非推奨: `.gitignore`が生成ができない
10
13
  npx @d-zero/create-frontend
14
+ ```
11
15
 
12
- # もしくは
16
+ ### オプション
13
17
 
14
- yarn create @d-zero/frontend
18
+ | オプション | 短縮形 | 説明 | デフォルト値 |
19
+ | ----------- | ------ | ------------------------------------------------------------------------------ | ------------------------- |
20
+ | `--type` | `-t` | プロジェクトのタイプを指定します。指定した場合、対話モードはスキップされます。 | `static` |
21
+ | `--dir` | `-d` | 出力先ディレクトリを指定します。 | `.`(現在のディレクトリ) |
22
+ | `--install` | - | スキャフォールディング後にyarnで依存関係をインストールします。 | `true` |
23
+
24
+ #### プロジェクトタイプ
25
+
26
+ ##### `static` - 静的サイト
27
+
28
+ - **用途**: 静的なWebサイトの開発
29
+ - **特徴**:
30
+ - [BurgerEditor Local App](https://github.com/d-zero-dev/BurgerEditor) v4 が組み込まれており、ローカル環境でのビジュアル編集が可能
31
+ - [kamado](https://github.com/kamado-io/kamado) による静的サイトジェネレーター
32
+ - **開発コマンド**:
33
+ - `yarn dev`: 開発サーバー起動(http://localhost:8000/)
34
+ - `yarn bge`: BurgerEditor Local App 起動(http://localhost:8100/)
35
+ - `yarn build`: 本番用ビルド
36
+
37
+ ##### `basercms4` - baserCMS v4
38
+
39
+ - **用途**: [baserCMS](https://basercms.net/) v4 のテーマ開発
40
+ - **特徴**:
41
+ - BurgerEditor v2 対応のテーマファイル
42
+ - baserCMS 固有のテンプレート構造
43
+ - jQuery および関連ライブラリが自動で依存関係に追加
44
+ - baserCMS のテンプレート変数やヘルパー関数に対応
45
+ - BurgerEditor のブロック定義ファイル(`bge-blocks-v2.html`)を使用
46
+ - **追加される依存関係**:
47
+ - `jquery`: 最新版
48
+ - `jquery-colorbox`: v1.5
49
+
50
+ ### 使用例
51
+
52
+ ```shell
53
+ # 対話モードで実行
54
+ npx @d-zero/create-frontend
55
+
56
+ # 静的サイトプロジェクトを指定ディレクトリに作成し、依存関係をインストール
57
+ npx @d-zero/create-frontend --type static --dir ./my-project --install
58
+
59
+ # baserCMS v4プロジェクトを作成(依存関係のインストールはスキップ)
60
+ yarn create @d-zero/frontend --type basercms4 --dir ./my-cms --no-install
15
61
  ```
16
62
 
63
+ ### 注意事項
64
+
65
+ オプションを指定せずにコマンドを実行すると、対話モードが開始され、プロジェクトを段階的に設定できます。
66
+
17
67
  インストールで展開されるファイルは[`@d-zero/scaffold`](https://github.com/d-zero-dev/frontend-env/blob/main/packages/%40d-zero/scaffold/)に格納されています。
package/command.js ADDED
@@ -0,0 +1,48 @@
1
+ import { spawn } from 'node:child_process';
2
+
3
+ /**
4
+ *
5
+ * @param {string} commandName
6
+ * @param {string[]} args
7
+ * @param {import("node:child_process").SpawnOptionsWithoutStdio} options
8
+ * @returns {Promise<string>}
9
+ */
10
+ export async function command(commandName, args, options) {
11
+ return new Promise((resolve, reject) => {
12
+ const child = spawn(commandName, args, options);
13
+
14
+ child.on('error', (error) => {
15
+ reject(error);
16
+ });
17
+
18
+ process.on('SIGINT', () => {
19
+ child.kill('SIGINT');
20
+ });
21
+
22
+ if (child.stdout) {
23
+ let returnValue = '';
24
+
25
+ child.stdout.on('data', (data) => {
26
+ returnValue += data.toString();
27
+ });
28
+
29
+ child.stdout.on('end', () => {
30
+ resolve(returnValue.trim());
31
+ });
32
+
33
+ return;
34
+ }
35
+
36
+ child.on('exit', (code) => {
37
+ if (code !== 0) {
38
+ reject(
39
+ new Error(
40
+ `Command "${commandName} ${args.join(' ')}" exited with code ${code}`,
41
+ ),
42
+ );
43
+ return;
44
+ }
45
+ resolve('');
46
+ });
47
+ });
48
+ }
package/index.spec.js CHANGED
@@ -1,8 +1,10 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import fs from 'node:fs';
2
3
  import os from 'node:os';
3
4
  import path from 'node:path';
4
5
 
5
6
  import { execa } from 'execa';
7
+ import nodePlop from 'node-plop';
6
8
  import { describe, test, expect, beforeEach } from 'vitest';
7
9
 
8
10
  /**
@@ -10,7 +12,116 @@ import { describe, test, expect, beforeEach } from 'vitest';
10
12
  * @param task
11
13
  */
12
14
  function getName(task) {
13
- return encodeURIComponent(`${task.suite.name}_${task.name}`.toLowerCase());
15
+ return createHash('sha256').update(`${task.suite.name}_${task.name}`).digest('hex');
16
+ }
17
+
18
+ /**
19
+ * basercms4の場合期待されるファイル一覧
20
+ * @param {string} dir
21
+ */
22
+ function expectedBasercms4(dir) {
23
+ return [
24
+ `✔ ++ ${dir}/.claude/commands/debug-diff.md`,
25
+ `✔ ++ ${dir}/.claude/commands/fix-component.md`,
26
+ `✔ ++ ${dir}/.claude/commands/git.md`,
27
+ `✔ ++ ${dir}/.claude/commands/release.md`,
28
+ `✔ ++ ${dir}/.claude/settings.json`,
29
+ `✔ ++ ${dir}/.cursor/mcp.json`,
30
+ `✔ ++ ${dir}/.editorconfig`,
31
+ `✔ ++ ${dir}/.gitignore`,
32
+ `✔ ++ ${dir}/.husky/pre-commit`,
33
+ `✔ ++ ${dir}/.mcp.json`,
34
+ `✔ ++ ${dir}/.npmignore`,
35
+ `✔ ++ ${dir}/.postcssrc.js`,
36
+ `✔ ++ ${dir}/.prettierrc.mjs`,
37
+ `✔ ++ ${dir}/.pug-lintrc`,
38
+ `✔ ++ ${dir}/.stylelintrc`,
39
+ `✔ ++ ${dir}/.textlintignore`,
40
+ `✔ ++ ${dir}/.textlintrc.js`,
41
+ `✔ ++ ${dir}/.vscode/extensions.json`,
42
+ `✔ ++ ${dir}/.vscode/settings.json`,
43
+ `✔ ++ ${dir}/.yarnrc.yml`,
44
+ `✔ ++ ${dir}/CHANGELOG.md`,
45
+ `✔ ++ ${dir}/CLAUDE.md`,
46
+ `✔ ++ ${dir}/README.md`,
47
+ `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
48
+ `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
49
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
50
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
51
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
52
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
53
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
54
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
55
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
56
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
57
+ `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
58
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
59
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
60
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
61
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
62
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
63
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
64
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
65
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
66
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
67
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
68
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
69
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
70
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
71
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
72
+ `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
73
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
74
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
75
+ `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
76
+ `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
77
+ `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
78
+ `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
79
+ `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
80
+ `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
81
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta-basercms.pug`,
82
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
83
+ `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
84
+ `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
85
+ `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
86
+ `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
87
+ `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
88
+ `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
89
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/.markuplintrc`,
90
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.json`,
91
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.pug`,
92
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.json`,
93
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.pug`,
94
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.json`,
95
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.pug`,
96
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.json`,
97
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.pug`,
98
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.json`,
99
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.pug`,
100
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.json`,
101
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.pug`,
102
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.json`,
103
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.pug`,
104
+ `✔ ++ ${dir}/__assets/htdocs/__tmpl/index.pug`,
105
+ `✔ ++ ${dir}/__assets/htdocs/css/bge_style.css`,
106
+ `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
107
+ `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
108
+ `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
109
+ `✔ ++ ${dir}/__info/print.txt`,
110
+ `✔ ++ ${dir}/burgereditor.config.js`,
111
+ `✔ ++ ${dir}/cspell.json`,
112
+ `✔ ++ ${dir}/eslint.config.js`,
113
+ `✔ ++ ${dir}/htdocs/__tmpl/__burger_editor/img/bg-sample.png`,
114
+ `✔ ++ ${dir}/htdocs/__tmpl/__burger_editor/js/bge_modules/bge_functions.min.js`,
115
+ `✔ ++ ${dir}/htdocs/files/images/sample.png`,
116
+ `✔ ++ ${dir}/kamado.config.ts`,
117
+ `✔ ++ ${dir}/lint-staged.config.mjs`,
118
+ `✔ ++ ${dir}/markuplint.config.js`,
119
+ `✔ ++ ${dir}/package.json`,
120
+ `✔ ++ ${dir}/prh.yaml`,
121
+ `✔ ++ ${dir}/tsconfig.json`,
122
+ '✔ Install dependencies skipped',
123
+ '✔ Finalize finalized',
124
+ ];
14
125
  }
15
126
 
16
127
  beforeEach((ctx) => {
@@ -38,302 +149,247 @@ describe('CLI', () => {
38
149
  failed: true,
39
150
  env: {
40
151
  NODE_NO_WARNINGS: '1',
152
+ NO_COLOR: '1',
153
+ FORCE_COLOR: '0',
41
154
  },
42
155
  },
43
156
  );
44
- return stdout.replaceAll(path.sep, '/').split('\n');
157
+ return stdout
158
+ .replaceAll(path.sep, '/')
159
+ .split('\n')
160
+ .filter((line) => line.trim() !== '');
161
+ }
162
+
163
+ /**
164
+ * node-plop APIを使い、CLIを経由せずジェネレーターを直接実行する。
165
+ * 対話モードでのプロンプト回答をシミュレートしてアクション結果を検証する。
166
+ * @param dir
167
+ * @param type
168
+ */
169
+ async function interactiveTest(dir, type) {
170
+ const plopfilePath = path.resolve(import.meta.dirname, 'plopfile.js');
171
+ const plop = await nodePlop(plopfilePath);
172
+ const generator = plop.getGenerator('basic');
173
+
174
+ const { changes, failures } = await generator.runActions({
175
+ '__d-zero_project_type__': type,
176
+ '__d-zero_scaffold_dest__': dir,
177
+ '__d-zero_scaffold_yarn_install__': false,
178
+ });
179
+
180
+ if (failures.length > 0) {
181
+ throw new Error(`Actions failed: ${JSON.stringify(failures)}`);
182
+ }
183
+
184
+ return changes.map((c) => {
185
+ if (c.type === 'add') {
186
+ return `✔ ++ ${c.path.replaceAll(path.sep, '/')}`;
187
+ }
188
+ return `✔ ${c.type} ${c.path}`;
189
+ });
45
190
  }
46
191
 
47
192
  test('npx', async ({ tmpDir, task }) => {
48
193
  const dir = path.join(tmpDir, getName(task));
49
194
  const actual = await cliTest(dir);
50
195
  expect(actual).toStrictEqual([
51
- `✔ ++ ${dir}/tsconfig.json`,
52
- `✔ ++ ${dir}/prh.yaml`,
53
- `✔ ++ ${dir}/package.json`,
54
- `✔ ++ ${dir}/markuplint.config.js`,
55
- `✔ ++ ${dir}/lint-staged.config.mjs`,
56
- `✔ ++ ${dir}/eslint.config.js`,
57
- `✔ ++ ${dir}/eleventy.config.mjs`,
58
- `✔ ++ ${dir}/cspell.json`,
59
- `✔ ++ ${dir}/burgereditor.config.js`,
60
- `✔ ++ ${dir}/README.md`,
61
- `✔ ++ ${dir}/CHANGELOG.md`,
62
- `✔ ++ ${dir}/.yarnrc.yml`,
63
- `✔ ++ ${dir}/.textlintrc.js`,
64
- `✔ ++ ${dir}/.textlintignore`,
65
- `✔ ++ ${dir}/.stylelintrc`,
66
- `✔ ++ ${dir}/.pug-lintrc`,
67
- `✔ ++ ${dir}/.prettierrc.mjs`,
68
- `✔ ++ ${dir}/.postcssrc.js`,
69
- `✔ ++ ${dir}/.npmignore`,
70
- `✔ ++ ${dir}/.gitignore`,
196
+ `✔ ++ ${dir}/.claude/commands/debug-diff.md`,
197
+ `✔ ++ ${dir}/.claude/commands/fix-component.md`,
198
+ `✔ ++ ${dir}/.claude/commands/git.md`,
199
+ `✔ ++ ${dir}/.claude/commands/release.md`,
200
+ `✔ ++ ${dir}/.claude/settings.json`,
201
+ `✔ ++ ${dir}/.cursor/mcp.json`,
71
202
  `✔ ++ ${dir}/.editorconfig`,
72
- `✔ ++ ${dir}/.clinerules`,
73
- `✔ ++ ${dir}/.clineignore`,
74
- `✔ ++ ${dir}/htdocs/files/images/sample.png`,
75
- `✔ ++ ${dir}/ai-tasks/page-to-burger.md`,
76
- `✔ ++ ${dir}/ai-tasks/create-page.md`,
77
- `✔ ++ ${dir}/ai-tasks/create-component.md`,
78
- `✔ ++ ${dir}/__info/print.txt`,
79
- `✔ ++ ${dir}/__assets/htdocs/index.pug`,
80
- `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
81
- `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
82
- `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
83
- `✔ ++ ${dir}/__assets/htdocs/css/bge_style.css`,
84
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/index.pug`,
85
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.pug`,
86
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.json`,
87
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.pug`,
88
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.json`,
89
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.pug`,
90
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.json`,
91
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.pug`,
92
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.json`,
93
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.pug`,
94
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.json`,
95
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.pug`,
96
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.json`,
97
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.pug`,
98
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.json`,
99
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/.markuplintrc`,
203
+ `✔ ++ ${dir}/.gitignore`,
204
+ `✔ ++ ${dir}/.husky/pre-commit`,
205
+ `✔ ++ ${dir}/.mcp.json`,
206
+ `✔ ++ ${dir}/.npmignore`,
207
+ `✔ ++ ${dir}/.postcssrc.js`,
208
+ `✔ ++ ${dir}/.prettierrc.mjs`,
209
+ `✔ ++ ${dir}/.pug-lintrc`,
210
+ `✔ ++ ${dir}/.stylelintrc`,
211
+ `✔ ++ ${dir}/.textlintignore`,
212
+ `✔ ++ ${dir}/.textlintrc.js`,
213
+ `✔ ++ ${dir}/.vscode/extensions.json`,
214
+ `✔ ++ ${dir}/.vscode/settings.json`,
215
+ `✔ ++ ${dir}/.yarnrc.yml`,
216
+ `✔ ++ ${dir}/CHANGELOG.md`,
217
+ `✔ ++ ${dir}/CLAUDE.md`,
218
+ `✔ ++ ${dir}/README.md`,
100
219
  `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
101
- `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
102
- `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
103
- `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
104
- `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
105
- `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
106
- `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
107
- `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
108
- `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
109
- `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
110
- `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
111
- `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
112
- `✔ ++ ${dir}/__assets/_libs/data/titlelist.js`,
113
- `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
114
- `✔ ++ ${dir}/__assets/_libs/data/breadcrumbs.js`,
115
- `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
116
- `✔ ++ ${dir}/__assets/_libs/data/blocks.html`,
117
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
118
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
119
- `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
120
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
121
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
122
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
123
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
124
- `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
125
- `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
126
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
127
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
128
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
129
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
130
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
131
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
132
- `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
133
- `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
134
- `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
135
- `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
136
- `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
137
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
138
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
139
- `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
140
- `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
141
- `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
142
- `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
143
220
  `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
144
- `✔ ++ ${dir}/.vscode/settings.json`,
145
- `✔ ++ ${dir}/.vscode/extensions.json`,
146
- `✔ ++ ${dir}/.husky/pre-commit`,
147
- '✔ Install dependencies : skipped',
221
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
222
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
223
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
224
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
225
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
226
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
227
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
228
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
229
+ `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
230
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
231
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
232
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
233
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
234
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
235
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
236
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
237
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
238
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
239
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
240
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
241
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
242
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
243
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
244
+ `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
245
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
246
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
247
+ `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
248
+ `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
249
+ `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
250
+ `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
251
+ `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
252
+ `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
253
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta-basercms.pug`,
254
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
255
+ `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
256
+ `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
257
+ `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
258
+ `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
259
+ `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
260
+ `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
261
+ `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
262
+ `✔ ++ ${dir}/__assets/htdocs/index.json`,
263
+ `✔ ++ ${dir}/__assets/htdocs/index.pug`,
264
+ `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
265
+ `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
266
+ `✔ ++ ${dir}/__info/print.txt`,
267
+ `✔ ++ ${dir}/burgereditor.config.js`,
268
+ `✔ ++ ${dir}/cspell.json`,
269
+ `✔ ++ ${dir}/eslint.config.js`,
270
+ `✔ ++ ${dir}/htdocs/files/images/sample.png`,
271
+ `✔ ++ ${dir}/kamado.config.ts`,
272
+ `✔ ++ ${dir}/lint-staged.config.mjs`,
273
+ `✔ ++ ${dir}/markuplint.config.js`,
274
+ `✔ ++ ${dir}/package.json`,
275
+ `✔ ++ ${dir}/prh.yaml`,
276
+ `✔ ++ ${dir}/tsconfig.json`,
277
+ '✔ Install dependencies skipped',
278
+ '✔ Finalize finalized',
148
279
  ]);
149
280
  });
150
281
 
151
- test('npx --type burger', async ({ tmpDir, task }) => {
282
+ test('npx --type basercms4', async ({ tmpDir, task }) => {
152
283
  const dir = path.join(tmpDir, getName(task));
153
- const actual = await cliTest(dir, 'burger');
154
- expect(actual).toStrictEqual([
155
- `✔ ++ ${dir}/tsconfig.json`,
156
- `✔ ++ ${dir}/prh.yaml`,
157
- `✔ ++ ${dir}/package.json`,
158
- `✔ ++ ${dir}/markuplint.config.js`,
159
- `✔ ++ ${dir}/lint-staged.config.mjs`,
160
- `✔ ++ ${dir}/eslint.config.js`,
161
- `✔ ++ ${dir}/eleventy.config.mjs`,
162
- `✔ ++ ${dir}/cspell.json`,
163
- `✔ ++ ${dir}/burgereditor.config.js`,
164
- `✔ ++ ${dir}/README.md`,
165
- `✔ ++ ${dir}/CHANGELOG.md`,
166
- `✔ ++ ${dir}/.yarnrc.yml`,
167
- `✔ ++ ${dir}/.textlintrc.js`,
168
- `✔ ++ ${dir}/.textlintignore`,
169
- `✔ ++ ${dir}/.stylelintrc`,
170
- `✔ ++ ${dir}/.pug-lintrc`,
171
- `✔ ++ ${dir}/.prettierrc.mjs`,
172
- `✔ ++ ${dir}/.postcssrc.js`,
173
- `✔ ++ ${dir}/.npmignore`,
174
- `✔ ++ ${dir}/.gitignore`,
175
- `✔ ++ ${dir}/.editorconfig`,
176
- `✔ ++ ${dir}/.clinerules`,
177
- `✔ ++ ${dir}/.clineignore`,
178
- `✔ ++ ${dir}/htdocs/files/images/sample.png`,
179
- `✔ ++ ${dir}/ai-tasks/page-to-burger.md`,
180
- `✔ ++ ${dir}/ai-tasks/create-page.md`,
181
- `✔ ++ ${dir}/ai-tasks/create-component.md`,
182
- `✔ ++ ${dir}/__info/print.txt`,
183
- `✔ ++ ${dir}/__assets/htdocs/index.pug`,
184
- `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
185
- `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
186
- `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
187
- `✔ ++ ${dir}/__assets/htdocs/css/bge_style.css`,
188
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/index.pug`,
189
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.pug`,
190
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.json`,
191
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.pug`,
192
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.json`,
193
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.pug`,
194
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.json`,
195
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.pug`,
196
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.json`,
197
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.pug`,
198
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.json`,
199
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.pug`,
200
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.json`,
201
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.pug`,
202
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.json`,
203
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/.markuplintrc`,
204
- `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
205
- `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
206
- `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
207
- `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
208
- `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
209
- `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
210
- `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
211
- `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
212
- `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
213
- `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
214
- `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
215
- `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
216
- `✔ ++ ${dir}/__assets/_libs/data/titlelist.js`,
217
- `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
218
- `✔ ++ ${dir}/__assets/_libs/data/breadcrumbs.js`,
219
- `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
220
- `✔ ++ ${dir}/__assets/_libs/data/blocks.html`,
221
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
222
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
223
- `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
224
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
225
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
226
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
227
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
228
- `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
229
- `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
230
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
231
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
232
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
233
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
234
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
235
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
236
- `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
237
- `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
238
- `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
239
- `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
240
- `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
241
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
242
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
243
- `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
244
- `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
245
- `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
246
- `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
247
- `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
248
- `✔ ++ ${dir}/.vscode/settings.json`,
249
- `✔ ++ ${dir}/.vscode/extensions.json`,
250
- `✔ ++ ${dir}/.husky/pre-commit`,
251
- '✔ Install dependencies : skipped',
252
- ]);
284
+ const actual = await cliTest(dir, 'basercms4');
285
+ expect(actual).toStrictEqual(expectedBasercms4(dir));
253
286
  });
254
287
 
255
288
  test('npx --type static', async ({ tmpDir, task }) => {
256
289
  const dir = path.join(tmpDir, getName(task));
257
290
  const actual = await cliTest(dir, 'static');
258
291
  expect(actual).toStrictEqual([
259
- `✔ ++ ${dir}/tsconfig.json`,
260
- `✔ ++ ${dir}/prh.yaml`,
261
- `✔ ++ ${dir}/package.json`,
262
- `✔ ++ ${dir}/markuplint.config.js`,
263
- `✔ ++ ${dir}/lint-staged.config.mjs`,
264
- `✔ ++ ${dir}/eslint.config.js`,
265
- `✔ ++ ${dir}/eleventy.config.mjs`,
266
- `✔ ++ ${dir}/cspell.json`,
267
- `✔ ++ ${dir}/burgereditor.config.js`,
268
- `✔ ++ ${dir}/README.md`,
269
- `✔ ++ ${dir}/CHANGELOG.md`,
270
- `✔ ++ ${dir}/.yarnrc.yml`,
271
- `✔ ++ ${dir}/.textlintrc.js`,
272
- `✔ ++ ${dir}/.textlintignore`,
273
- `✔ ++ ${dir}/.stylelintrc`,
274
- `✔ ++ ${dir}/.pug-lintrc`,
275
- `✔ ++ ${dir}/.prettierrc.mjs`,
276
- `✔ ++ ${dir}/.postcssrc.js`,
277
- `✔ ++ ${dir}/.npmignore`,
278
- `✔ ++ ${dir}/.gitignore`,
292
+ `✔ ++ ${dir}/.claude/commands/debug-diff.md`,
293
+ `✔ ++ ${dir}/.claude/commands/fix-component.md`,
294
+ `✔ ++ ${dir}/.claude/commands/git.md`,
295
+ `✔ ++ ${dir}/.claude/commands/release.md`,
296
+ `✔ ++ ${dir}/.claude/settings.json`,
297
+ `✔ ++ ${dir}/.cursor/mcp.json`,
279
298
  `✔ ++ ${dir}/.editorconfig`,
280
- `✔ ++ ${dir}/.clinerules`,
281
- `✔ ++ ${dir}/.clineignore`,
282
- `✔ ++ ${dir}/htdocs/files/images/sample.png`,
283
- `✔ ++ ${dir}/ai-tasks/page-to-burger.md`,
284
- `✔ ++ ${dir}/ai-tasks/create-page.md`,
285
- `✔ ++ ${dir}/ai-tasks/create-component.md`,
286
- `✔ ++ ${dir}/__info/print.txt`,
287
- `✔ ++ ${dir}/__assets/htdocs/index.pug`,
288
- `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
289
- `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
290
- `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
299
+ `✔ ++ ${dir}/.gitignore`,
300
+ `✔ ++ ${dir}/.husky/pre-commit`,
301
+ `✔ ++ ${dir}/.mcp.json`,
302
+ `✔ ++ ${dir}/.npmignore`,
303
+ `✔ ++ ${dir}/.postcssrc.js`,
304
+ `✔ ++ ${dir}/.prettierrc.mjs`,
305
+ `✔ ++ ${dir}/.pug-lintrc`,
306
+ `✔ ++ ${dir}/.stylelintrc`,
307
+ `✔ ++ ${dir}/.textlintignore`,
308
+ `✔ ++ ${dir}/.textlintrc.js`,
309
+ `✔ ++ ${dir}/.vscode/extensions.json`,
310
+ `✔ ++ ${dir}/.vscode/settings.json`,
311
+ `✔ ++ ${dir}/.yarnrc.yml`,
312
+ `✔ ++ ${dir}/CHANGELOG.md`,
313
+ `✔ ++ ${dir}/CLAUDE.md`,
314
+ `✔ ++ ${dir}/README.md`,
291
315
  `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
292
- `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
293
- `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
294
- `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
295
- `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
296
- `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
297
- `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
298
- `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
299
- `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
300
- `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
301
- `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
302
- `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
303
- `✔ ++ ${dir}/__assets/_libs/data/titlelist.js`,
304
- `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
305
- `✔ ++ ${dir}/__assets/_libs/data/breadcrumbs.js`,
306
- `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
307
- `✔ ++ ${dir}/__assets/_libs/data/blocks.html`,
308
- `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
309
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
310
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
311
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
312
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
313
- `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
314
- `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
315
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
316
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
317
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
318
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
319
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
320
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
321
- `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
322
- `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
323
- `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
324
- `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
325
- `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
326
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
327
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
328
- `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
329
- `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
330
- `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
331
- `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
332
316
  `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
333
- `✔ ++ ${dir}/.vscode/settings.json`,
334
- `✔ ++ ${dir}/.vscode/extensions.json`,
335
- `✔ ++ ${dir}/.husky/pre-commit`,
336
- '✔ Install dependencies : skipped',
317
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
318
+ `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
319
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
320
+ `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
321
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
322
+ `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
323
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
324
+ `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
325
+ `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
326
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
327
+ `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
328
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
329
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
330
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
331
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
332
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
333
+ `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
334
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
335
+ `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
336
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
337
+ `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
338
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
339
+ `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
340
+ `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
341
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
342
+ `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
343
+ `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
344
+ `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
345
+ `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
346
+ `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
347
+ `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
348
+ `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
349
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta-basercms.pug`,
350
+ `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
351
+ `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
352
+ `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
353
+ `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
354
+ `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
355
+ `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
356
+ `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
357
+ `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
358
+ `✔ ++ ${dir}/__assets/htdocs/index.json`,
359
+ `✔ ++ ${dir}/__assets/htdocs/index.pug`,
360
+ `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
361
+ `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
362
+ `✔ ++ ${dir}/__info/print.txt`,
363
+ `✔ ++ ${dir}/burgereditor.config.js`,
364
+ `✔ ++ ${dir}/cspell.json`,
365
+ `✔ ++ ${dir}/eslint.config.js`,
366
+ `✔ ++ ${dir}/htdocs/files/images/sample.png`,
367
+ `✔ ++ ${dir}/kamado.config.ts`,
368
+ `✔ ++ ${dir}/lint-staged.config.mjs`,
369
+ `✔ ++ ${dir}/markuplint.config.js`,
370
+ `✔ ++ ${dir}/package.json`,
371
+ `✔ ++ ${dir}/prh.yaml`,
372
+ `✔ ++ ${dir}/tsconfig.json`,
373
+ '✔ Install dependencies skipped',
374
+ '✔ Finalize finalized',
337
375
  ]);
338
376
  });
377
+
378
+ test('interactive basercms4', async ({ tmpDir, task }) => {
379
+ const dir = path.join(tmpDir, getName(task));
380
+ const actual = await interactiveTest(dir, 'basercms4');
381
+ expect(actual).toStrictEqual(expectedBasercms4(dir));
382
+ });
383
+
384
+ describe('kamado.config.ts', () => {
385
+ test('basercms4: startPath が "__tmpl/" に設定されている', async ({
386
+ tmpDir,
387
+ task,
388
+ }) => {
389
+ const dir = path.join(tmpDir, getName(task));
390
+ await interactiveTest(dir, 'basercms4');
391
+ const content = fs.readFileSync(path.join(dir, 'kamado.config.ts'), 'utf8');
392
+ expect(content).toContain("startPath: '__tmpl/'");
393
+ });
394
+ });
339
395
  });
package/libraries.js ADDED
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ const basercms4Libraries = [
5
+ {
6
+ from: 'node_modules/jquery/dist/jquery.min.js',
7
+ to: 'htdocs/js/jquery.min.js',
8
+ },
9
+ {
10
+ from: 'node_modules/jquery-colorbox/example3/colorbox.css',
11
+ to: 'htdocs/__tmpl/__burger_editor/css/colorbox.css',
12
+ },
13
+ {
14
+ from: 'node_modules/jquery-colorbox/example3/images/loading.gif',
15
+ to: 'htdocs/__tmpl/__burger_editor/css/images/loading.gif',
16
+ },
17
+ {
18
+ from: 'node_modules/jquery-colorbox/example3/images/controls.png',
19
+ to: 'htdocs/__tmpl/__burger_editor/css/images/controls.png',
20
+ },
21
+ {
22
+ from: 'node_modules/jquery-colorbox/jquery.colorbox-min.js',
23
+ to: 'htdocs/__tmpl/__burger_editor/js/bge_modules/jquery.colorbox-min.js',
24
+ },
25
+ ];
26
+
27
+ /**
28
+ *
29
+ * @param type
30
+ * @param dest
31
+ */
32
+ export async function copyLibraries(type, dest) {
33
+ dest = path.isAbsolute(dest) ? dest : path.resolve(process.cwd(), dest);
34
+ let libraries = [];
35
+ switch (type) {
36
+ case 'basercms4': {
37
+ libraries = basercms4Libraries;
38
+ break;
39
+ }
40
+ }
41
+
42
+ for (const library of libraries) {
43
+ const from = path.join(dest, library.from);
44
+ const dist = path.join(dest, library.to);
45
+ const dir = path.dirname(dist);
46
+ const stats = await fs.stat(from).catch(() => null);
47
+ if (!stats?.isFile()) {
48
+ continue;
49
+ }
50
+ await fs.mkdir(dir, { recursive: true });
51
+ await fs.copyFile(from, dist);
52
+ }
53
+ }
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@d-zero/create-frontend",
3
- "version": "5.0.0-beta.9",
3
+ "version": "5.1.0",
4
4
  "description": "Create a new frontend project from a scaffolding template",
5
- "repository": "https://github.com/d-zero-dev/frontend-env.git",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/d-zero-dev/frontend-env.git",
8
+ "directory": "packages/@d-zero/create-frontend"
9
+ },
6
10
  "author": "D-ZERO Co., Ltd.",
7
11
  "license": "MIT",
8
12
  "publishConfig": {
@@ -13,16 +17,19 @@
13
17
  "create-dzero-frontend": "./index.js"
14
18
  },
15
19
  "dependencies": {
16
- "@d-zero/scaffold": "5.0.0-beta.9",
17
- "glob": "11.0.3",
18
- "i18n-js": "4.5.1",
20
+ "@d-zero/prettier-config": "5.0.0",
21
+ "@d-zero/scaffold": "5.1.0",
22
+ "i18n-js": "4.5.2",
19
23
  "ignore": "7.0.5",
20
- "meow": "14.0.0",
21
- "plop": "4.0.2"
24
+ "magicast": "0.5.2",
25
+ "meow": "14.1.0",
26
+ "minimatch": "10.2.4",
27
+ "plop": "4.0.4",
28
+ "prettier": "3.8.1"
22
29
  },
23
30
  "devDependencies": {
24
- "@types/glob": "9.0.0",
25
- "execa": "9.6.0"
31
+ "@types/node": "25.3.3",
32
+ "execa": "9.6.1"
26
33
  },
27
- "gitHead": "ba74910999437f13873b324db632798851997e58"
34
+ "gitHead": "24532c43d0a5e542e0ce8cb6a16653583ac40a5d"
28
35
  }
package/plopfile.js CHANGED
@@ -1,14 +1,20 @@
1
- import { spawn } from 'node:child_process';
2
1
  import fs from 'node:fs';
2
+ import fsp from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { argv } from 'node:process';
5
5
 
6
- import { globSync } from 'glob';
6
+ import prettierConfig from '@d-zero/prettier-config/base';
7
7
  import ignore from 'ignore';
8
+ import { generateCode, parseModule } from 'magicast';
8
9
  import meow from 'meow';
10
+ import { minimatch } from 'minimatch';
11
+ import { format as prettierFormat } from 'prettier';
9
12
 
13
+ import { command } from './command.js';
14
+ import { copyLibraries } from './libraries.js';
10
15
  import { t } from './locale.js';
11
16
  import { readFileSafe } from './read-file-safe.js';
17
+ import { voltaInstallNode } from './volta-install-node.js';
12
18
 
13
19
  const cli = meow(
14
20
  `
@@ -35,7 +41,7 @@ const cli = meow(
35
41
  type: {
36
42
  type: 'string',
37
43
  shortFlag: 't',
38
- default: 'burger',
44
+ default: 'static',
39
45
  },
40
46
  dir: {
41
47
  type: 'string',
@@ -54,16 +60,42 @@ const cli = meow(
54
60
  },
55
61
  );
56
62
 
63
+ /**
64
+ * Recursively get all files in a directory
65
+ * @param {string} dir - Directory to search
66
+ * @param {string} rootDir - Root directory for relative paths
67
+ * @returns {Promise<string[]>} Array of relative file paths
68
+ */
69
+ async function getAllFiles(dir, rootDir) {
70
+ const files = [];
71
+ const entries = await fsp.readdir(dir, { withFileTypes: true });
72
+
73
+ for (const entry of entries) {
74
+ const fullPath = path.join(dir, entry.name);
75
+ const relativePath = path.relative(rootDir, fullPath);
76
+
77
+ if (entry.isDirectory()) {
78
+ const subFiles = await getAllFiles(fullPath, rootDir);
79
+ files.push(...subFiles);
80
+ } else {
81
+ files.push(relativePath);
82
+ }
83
+ }
84
+
85
+ return files;
86
+ }
87
+
57
88
  /**
58
89
  * @param {import('plop').NodePlopAPI} plop
59
90
  */
60
- export default function (plop) {
91
+ export default async function (plop) {
61
92
  const scaffoldDir = path.normalize(
62
93
  path.dirname(import.meta.resolve('@d-zero/scaffold').replace('file:', '')),
63
94
  );
64
95
 
65
- const gitignore = readFileSafe(path.resolve(scaffoldDir, '.gitignore'));
66
- const ignoreFiles = gitignore?.split('\n').filter(Boolean) ?? [];
96
+ const gitignoreOriginContent =
97
+ readFileSafe(path.resolve(scaffoldDir, '.gitignore')) ?? '';
98
+ const ignoreFiles = gitignoreOriginContent?.split('\n').filter(Boolean) ?? [];
67
99
  const hasArgs = argv.length > 2;
68
100
  const interactive = !hasArgs;
69
101
 
@@ -76,51 +108,29 @@ export default function (plop) {
76
108
  '**/*.test/**/*',
77
109
  // Test Files
78
110
  '*.test.*',
79
- ])
80
- .add(
81
- // BurgerEditor
82
- cli.flags.type === 'burger' ? [] : ['**/bge-*', '**/bge_*'],
83
- )
84
- .add(
85
- // static
86
- cli.flags.type === 'static' ? ['**/__tmpl/**/*'] : [],
87
- );
88
-
89
- const scaffoldFiles = ig.filter(
90
- globSync('**/*', {
91
- cwd: scaffoldDir,
92
- nodir: true,
93
- dot: true,
94
- }),
95
- );
111
+ ]);
96
112
 
97
- plop.setActionType('Install dependencies', (answers) => {
98
- const { dest, doInstall } = answerToConfig(answers);
113
+ const scaffoldFiles = ig.filter(await getAllFiles(scaffoldDir, scaffoldDir)).toSorted();
99
114
 
100
- const { promise, resolve, reject } = Promise.withResolvers();
115
+ plop.setActionType('Install dependencies', async (answers) => {
116
+ const { dest, doInstall } = answerToConfig(answers);
117
+ if (doInstall) {
118
+ await installDependencies(dest);
119
+ return 'success';
120
+ }
121
+ return 'skipped';
122
+ });
101
123
 
124
+ plop.setActionType('Finalize', async (answers) => {
125
+ const { dest, type, doInstall } = answerToConfig(answers);
102
126
  if (doInstall) {
103
- const child = spawn('yarn', ['install'], {
104
- cwd: path.resolve(process.cwd(), dest),
105
- stdio: 'inherit',
106
- });
107
-
108
- child.on('exit', (code) => {
109
- if (code === 0) {
110
- resolve(': success');
111
- } else {
112
- reject(new Error('Failed to install dependencies'));
113
- }
114
- });
115
-
116
- process.on('SIGINT', () => {
117
- child.kill('SIGINT');
118
- });
119
- } else {
120
- resolve(': skipped');
127
+ rewriteDotGitignore(dest, gitignoreOriginContent);
121
128
  }
122
129
 
123
- return promise;
130
+ if (type.startsWith('basercms')) {
131
+ await copyLibraries(type, dest);
132
+ }
133
+ return 'finalized';
124
134
  });
125
135
 
126
136
  plop.setGenerator('basic', {
@@ -132,13 +142,12 @@ export default function (plop) {
132
142
  message: t`What's the type of project?`,
133
143
  choices: [
134
144
  {
135
- name: 'Static',
145
+ name: 'Static Site (with BurgerEditor Local App)',
136
146
  value: 'static',
137
147
  },
138
- 'CMS (WordPress etc.)',
139
148
  {
140
- name: 'CMS (baserCMS with BurgerEditor)',
141
- value: 'burger',
149
+ name: 'baserCMS v4 (with BurgerEditor v2)',
150
+ value: 'basercms4',
142
151
  },
143
152
  ],
144
153
  default: cli.flags.type,
@@ -168,8 +177,25 @@ export default function (plop) {
168
177
  console.log(config);
169
178
  }
170
179
 
180
+ const ignoredFiles = [];
181
+
182
+ if (!config.type.startsWith('basercms')) {
183
+ ignoredFiles.push('**/bge_style.css');
184
+ }
185
+
186
+ if (config.type === 'static') {
187
+ ignoredFiles.push('**/__tmpl/**/*');
188
+ } else {
189
+ ignoredFiles.push('__assets/htdocs/index.pug', '__assets/htdocs/index.json');
190
+ }
191
+
192
+ const filteredFiles = scaffoldFiles.filter(
193
+ (file) =>
194
+ !ignoredFiles.some((pattern) => minimatch(file, pattern, { dot: true })),
195
+ );
196
+
171
197
  return [
172
- ...scaffoldFiles.map(
198
+ ...filteredFiles.map(
173
199
  /**
174
200
  * @see https://plopjs.com/documentation/#add
175
201
  * @type {import('plop').AddActionConfig}
@@ -179,7 +205,7 @@ export default function (plop) {
179
205
  type: 'add',
180
206
  path: path.resolve(config.dest, originFile),
181
207
  templateFile: path.resolve(scaffoldDir, originFile),
182
- transform(content) {
208
+ async transform(content) {
183
209
  const nameCandidate = path.basename(path.resolve(config.dest));
184
210
 
185
211
  switch (originFile) {
@@ -195,24 +221,51 @@ export default function (plop) {
195
221
  delete pkg.license;
196
222
  delete pkg.publishConfig;
197
223
  delete pkg.files;
224
+ if (config.type.startsWith('basercms')) {
225
+ delete pkg.scripts.bge;
226
+ delete pkg.devDependencies['@burger-editor/local'];
227
+ pkg.dependencies['@burger-editor/css'] = '2';
228
+ pkg.dependencies['jquery'] = 'latest';
229
+ pkg.dependencies['jquery-colorbox'] = '1.5';
230
+ }
198
231
  content = JSON.stringify(pkg, null, '\t');
199
232
  break;
200
233
  }
201
- case '__assets/_libs/data/blocks.cjs': {
202
- if (config.type === 'burger') {
203
- content = content.replace("blocks.html'", "bge-blocks.html'");
234
+ case '__assets/_libs/data/blocks.js': {
235
+ if (config.type === 'basercms4') {
236
+ content = content.replace('bge-blocks.html', 'bge-blocks-v2.html');
237
+ }
238
+ break;
239
+ }
240
+ case '__assets/_libs/mixin/meta.pug': {
241
+ if (!config.type.startsWith('basercms')) {
242
+ content = content.replace('\ninclude meta-basercms.pug', '');
204
243
  }
205
244
  break;
206
245
  }
207
- case '__assets/htdocs/index.pug': {
208
- if (config.type === 'static') {
209
- content = fs.readFileSync(
210
- path.resolve(scaffoldDir, '__assets/htdocs/__tmpl/000_home.pug'),
211
- 'utf8',
212
- );
246
+ case 'kamado.config.ts': {
247
+ if (config.type.startsWith('basercms')) {
248
+ const mod = parseModule(content);
249
+ mod.exports.default.devServer.startPath = '__tmpl/';
250
+ content = generateCode(mod).code;
213
251
  }
252
+ break;
214
253
  }
215
254
  }
255
+
256
+ const ext = path.extname(originFile);
257
+ const parserMap = {
258
+ '.ts': 'typescript',
259
+ '.js': 'babel',
260
+ '.mjs': 'babel',
261
+ '.cjs': 'babel',
262
+ '.json': 'json',
263
+ };
264
+ const parser = parserMap[ext];
265
+ if (parser) {
266
+ content = await prettierFormat(content, { ...prettierConfig, parser });
267
+ }
268
+
216
269
  return content;
217
270
  },
218
271
  };
@@ -221,6 +274,9 @@ export default function (plop) {
221
274
  {
222
275
  type: 'Install dependencies',
223
276
  },
277
+ {
278
+ type: 'Finalize',
279
+ },
224
280
  ];
225
281
  },
226
282
  });
@@ -237,3 +293,34 @@ function answerToConfig(answers) {
237
293
 
238
294
  return { type, dest, doInstall };
239
295
  }
296
+
297
+ /**
298
+ *
299
+ * @param dest
300
+ */
301
+ async function installDependencies(dest) {
302
+ await voltaInstallNode();
303
+ await command('yarn', ['install'], {
304
+ cwd: path.resolve(process.cwd(), dest),
305
+ stdio: 'inherit',
306
+ }).catch(() => {
307
+ throw new Error('Failed to install dependencies');
308
+ });
309
+ }
310
+
311
+ /**
312
+ *
313
+ * @param {string} dest
314
+ * @param {string} gitignoreOriginContent
315
+ */
316
+ function rewriteDotGitignore(dest, gitignoreOriginContent) {
317
+ let gitignore = gitignoreOriginContent;
318
+
319
+ // Remove after `# Document Root` section
320
+ const documentRootSection = gitignore.indexOf('\n# Document Root\n');
321
+ if (documentRootSection !== -1) {
322
+ gitignore = gitignore.slice(0, documentRootSection);
323
+ }
324
+
325
+ return fs.writeFileSync(path.resolve(dest, '.gitignore'), gitignore);
326
+ }
@@ -0,0 +1,24 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ import { command } from './command.js';
5
+
6
+ /**
7
+ *
8
+ */
9
+ export async function voltaInstallNode() {
10
+ const node = await command('node', ['-v']).catch(() => null);
11
+ if (node) {
12
+ return;
13
+ }
14
+ const pkg = await readFile(path.join(import.meta.dirname, 'package.json'), 'utf8');
15
+ const pkgJson = JSON.parse(pkg);
16
+ const nodeVersion = pkgJson.devDependencies['@types/node'].split('.')[0];
17
+ const volta = await command('volta', ['-v']).catch(() => null);
18
+ if (volta) {
19
+ await command('volta', ['setup'], { stdio: 'inherit' });
20
+ await command('volta', ['install', `node@${nodeVersion}`], { stdio: 'inherit' });
21
+ return;
22
+ }
23
+ throw new Error('command not found: "node" or "volta"');
24
+ }