@d-zero/create-frontend 5.0.0 → 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,18 @@
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
+
6
18
  # [5.0.0](https://github.com/d-zero-dev/frontend-env/compare/v5.0.0-beta.19...v5.0.0) (2026-01-05)
7
19
 
8
20
  **Note:** Version bump only for package @d-zero/create-frontend
package/index.spec.js CHANGED
@@ -4,6 +4,7 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
 
6
6
  import { execa } from 'execa';
7
+ import nodePlop from 'node-plop';
7
8
  import { describe, test, expect, beforeEach } from 'vitest';
8
9
 
9
10
  /**
@@ -14,6 +15,115 @@ function getName(task) {
14
15
  return createHash('sha256').update(`${task.suite.name}_${task.name}`).digest('hex');
15
16
  }
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
+ ];
125
+ }
126
+
17
127
  beforeEach((ctx) => {
18
128
  ctx.tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
19
129
  });
@@ -50,13 +160,49 @@ describe('CLI', () => {
50
160
  .filter((line) => line.trim() !== '');
51
161
  }
52
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
+ });
190
+ }
191
+
53
192
  test('npx', async ({ tmpDir, task }) => {
54
193
  const dir = path.join(tmpDir, getName(task));
55
194
  const actual = await cliTest(dir);
56
195
  expect(actual).toStrictEqual([
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`,
57
202
  `✔ ++ ${dir}/.editorconfig`,
58
203
  `✔ ++ ${dir}/.gitignore`,
59
204
  `✔ ++ ${dir}/.husky/pre-commit`,
205
+ `✔ ++ ${dir}/.mcp.json`,
60
206
  `✔ ++ ${dir}/.npmignore`,
61
207
  `✔ ++ ${dir}/.postcssrc.js`,
62
208
  `✔ ++ ${dir}/.prettierrc.mjs`,
@@ -68,6 +214,7 @@ describe('CLI', () => {
68
214
  `✔ ++ ${dir}/.vscode/settings.json`,
69
215
  `✔ ++ ${dir}/.yarnrc.yml`,
70
216
  `✔ ++ ${dir}/CHANGELOG.md`,
217
+ `✔ ++ ${dir}/CLAUDE.md`,
71
218
  `✔ ++ ${dir}/README.md`,
72
219
  `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
73
220
  `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
@@ -112,6 +259,7 @@ describe('CLI', () => {
112
259
  `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
113
260
  `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
114
261
  `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
262
+ `✔ ++ ${dir}/__assets/htdocs/index.json`,
115
263
  `✔ ++ ${dir}/__assets/htdocs/index.pug`,
116
264
  `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
117
265
  `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
@@ -134,110 +282,23 @@ describe('CLI', () => {
134
282
  test('npx --type basercms4', async ({ tmpDir, task }) => {
135
283
  const dir = path.join(tmpDir, getName(task));
136
284
  const actual = await cliTest(dir, 'basercms4');
137
- expect(actual).toStrictEqual([
138
- `✔ ++ ${dir}/.editorconfig`,
139
- `✔ ++ ${dir}/.gitignore`,
140
- `✔ ++ ${dir}/.husky/pre-commit`,
141
- `✔ ++ ${dir}/.npmignore`,
142
- `✔ ++ ${dir}/.postcssrc.js`,
143
- `✔ ++ ${dir}/.prettierrc.mjs`,
144
- `✔ ++ ${dir}/.pug-lintrc`,
145
- `✔ ++ ${dir}/.stylelintrc`,
146
- `✔ ++ ${dir}/.textlintignore`,
147
- `✔ ++ ${dir}/.textlintrc.js`,
148
- `✔ ++ ${dir}/.vscode/extensions.json`,
149
- `✔ ++ ${dir}/.vscode/settings.json`,
150
- `✔ ++ ${dir}/.yarnrc.yml`,
151
- `✔ ++ ${dir}/CHANGELOG.md`,
152
- `✔ ++ ${dir}/README.md`,
153
- `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
154
- `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
155
- `✔ ++ ${dir}/__assets/_libs/component/c-card.css`,
156
- `✔ ++ ${dir}/__assets/_libs/component/c-card.pug`,
157
- `✔ ++ ${dir}/__assets/_libs/component/c-content-index.css`,
158
- `✔ ++ ${dir}/__assets/_libs/component/c-content-main.css`,
159
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.css`,
160
- `✔ ++ ${dir}/__assets/_libs/component/c-footer.pug`,
161
- `✔ ++ ${dir}/__assets/_libs/component/c-header.css`,
162
- `✔ ++ ${dir}/__assets/_libs/component/c-header.pug`,
163
- `✔ ++ ${dir}/__assets/_libs/component/c-media-list.css`,
164
- `✔ ++ ${dir}/__assets/_libs/component/c-media.css`,
165
- `✔ ++ ${dir}/__assets/_libs/component/c-media.pug`,
166
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.css`,
167
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-breadcrumb.pug`,
168
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.css`,
169
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-global.pug`,
170
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.css`,
171
- `✔ ++ ${dir}/__assets/_libs/component/c-nav-sitemap.pug`,
172
- `✔ ++ ${dir}/__assets/_libs/component/c-page-home.css`,
173
- `✔ ++ ${dir}/__assets/_libs/component/c-page-sub.css`,
174
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.css`,
175
- `✔ ++ ${dir}/__assets/_libs/component/c-pagination.pug`,
176
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.css`,
177
- `✔ ++ ${dir}/__assets/_libs/component/c-title-page.pug`,
178
- `✔ ++ ${dir}/__assets/_libs/data/.markuplintrc`,
179
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks-v2.html`,
180
- `✔ ++ ${dir}/__assets/_libs/data/bge-blocks.html`,
181
- `✔ ++ ${dir}/__assets/_libs/data/blocks.js`,
182
- `✔ ++ ${dir}/__assets/_libs/data/data.yml`,
183
- `✔ ++ ${dir}/__assets/_libs/img/bg-arrow.svg`,
184
- `✔ ++ ${dir}/__assets/_libs/img/bg-repeat-01.gif`,
185
- `✔ ++ ${dir}/__assets/_libs/layouts/home.pug`,
186
- `✔ ++ ${dir}/__assets/_libs/layouts/sub.pug`,
187
- `✔ ++ ${dir}/__assets/_libs/mixin/meta-basercms.pug`,
188
- `✔ ++ ${dir}/__assets/_libs/mixin/meta.pug`,
189
- `✔ ++ ${dir}/__assets/_libs/script/index.ts`,
190
- `✔ ++ ${dir}/__assets/_libs/style/base/root.css`,
191
- `✔ ++ ${dir}/__assets/_libs/style/general/all.css`,
192
- `✔ ++ ${dir}/__assets/_libs/style/general/body.css`,
193
- `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
194
- `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
195
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/.markuplintrc`,
196
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.json`,
197
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/000_home.pug`,
198
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.json`,
199
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/100_sub.pug`,
200
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.json`,
201
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/200_blog_index.pug`,
202
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.json`,
203
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/210_blog_index.pug`,
204
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.json`,
205
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/300_form_input.pug`,
206
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.json`,
207
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/301_form_confirm.pug`,
208
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.json`,
209
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/302_form_complete.pug`,
210
- `✔ ++ ${dir}/__assets/htdocs/__tmpl/index.pug`,
211
- `✔ ++ ${dir}/__assets/htdocs/css/bge_style.css`,
212
- `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
213
- `✔ ++ ${dir}/__assets/htdocs/index.pug`,
214
- `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
215
- `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
216
- `✔ ++ ${dir}/__info/print.txt`,
217
- `✔ ++ ${dir}/burgereditor.config.js`,
218
- `✔ ++ ${dir}/cspell.json`,
219
- `✔ ++ ${dir}/eslint.config.js`,
220
- `✔ ++ ${dir}/htdocs/__tmpl/__burger_editor/img/bg-sample.png`,
221
- `✔ ++ ${dir}/htdocs/__tmpl/__burger_editor/js/bge_modules/bge_functions.min.js`,
222
- `✔ ++ ${dir}/htdocs/files/images/sample.png`,
223
- `✔ ++ ${dir}/kamado.config.ts`,
224
- `✔ ++ ${dir}/lint-staged.config.mjs`,
225
- `✔ ++ ${dir}/markuplint.config.js`,
226
- `✔ ++ ${dir}/package.json`,
227
- `✔ ++ ${dir}/prh.yaml`,
228
- `✔ ++ ${dir}/tsconfig.json`,
229
- '✔ Install dependencies skipped',
230
- '✔ Finalize finalized',
231
- ]);
285
+ expect(actual).toStrictEqual(expectedBasercms4(dir));
232
286
  });
233
287
 
234
288
  test('npx --type static', async ({ tmpDir, task }) => {
235
289
  const dir = path.join(tmpDir, getName(task));
236
290
  const actual = await cliTest(dir, 'static');
237
291
  expect(actual).toStrictEqual([
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`,
238
298
  `✔ ++ ${dir}/.editorconfig`,
239
299
  `✔ ++ ${dir}/.gitignore`,
240
300
  `✔ ++ ${dir}/.husky/pre-commit`,
301
+ `✔ ++ ${dir}/.mcp.json`,
241
302
  `✔ ++ ${dir}/.npmignore`,
242
303
  `✔ ++ ${dir}/.postcssrc.js`,
243
304
  `✔ ++ ${dir}/.prettierrc.mjs`,
@@ -249,6 +310,7 @@ describe('CLI', () => {
249
310
  `✔ ++ ${dir}/.vscode/settings.json`,
250
311
  `✔ ++ ${dir}/.yarnrc.yml`,
251
312
  `✔ ++ ${dir}/CHANGELOG.md`,
313
+ `✔ ++ ${dir}/CLAUDE.md`,
252
314
  `✔ ++ ${dir}/README.md`,
253
315
  `✔ ++ ${dir}/__assets/_libs/.markuplintrc`,
254
316
  `✔ ++ ${dir}/__assets/_libs/component/c-card-list.css`,
@@ -293,6 +355,7 @@ describe('CLI', () => {
293
355
  `✔ ++ ${dir}/__assets/_libs/style/general/button.css`,
294
356
  `✔ ++ ${dir}/__assets/_libs/style/general/img.css`,
295
357
  `✔ ++ ${dir}/__assets/htdocs/css/style.css`,
358
+ `✔ ++ ${dir}/__assets/htdocs/index.json`,
296
359
  `✔ ++ ${dir}/__assets/htdocs/index.pug`,
297
360
  `✔ ++ ${dir}/__assets/htdocs/js/script.ts`,
298
361
  `✔ ++ ${dir}/__assets/htdocs/sample/index.html`,
@@ -311,4 +374,22 @@ describe('CLI', () => {
311
374
  '✔ Finalize finalized',
312
375
  ]);
313
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
+ });
314
395
  });
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@d-zero/create-frontend",
3
- "version": "5.0.0",
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,15 +17,19 @@
13
17
  "create-dzero-frontend": "./index.js"
14
18
  },
15
19
  "dependencies": {
16
- "@d-zero/scaffold": "5.0.0",
17
- "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",
18
23
  "ignore": "7.0.5",
19
- "meow": "14.0.0",
20
- "plop": "4.0.4"
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"
21
29
  },
22
30
  "devDependencies": {
23
- "@types/node": "25.0.3",
31
+ "@types/node": "25.3.3",
24
32
  "execa": "9.6.1"
25
33
  },
26
- "gitHead": "d5be73bc1f2fbfb85eea684d6b4807323a8999ff"
34
+ "gitHead": "24532c43d0a5e542e0ce8cb6a16653583ac40a5d"
27
35
  }
package/plopfile.js CHANGED
@@ -3,8 +3,12 @@ import fsp from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { argv } from 'node:process';
5
5
 
6
+ import prettierConfig from '@d-zero/prettier-config/base';
6
7
  import ignore from 'ignore';
8
+ import { generateCode, parseModule } from 'magicast';
7
9
  import meow from 'meow';
10
+ import { minimatch } from 'minimatch';
11
+ import { format as prettierFormat } from 'prettier';
8
12
 
9
13
  import { command } from './command.js';
10
14
  import { copyLibraries } from './libraries.js';
@@ -104,15 +108,7 @@ export default async function (plop) {
104
108
  '**/*.test/**/*',
105
109
  // Test Files
106
110
  '*.test.*',
107
- ])
108
- .add(
109
- // BurgerEditor for baserCMS
110
- cli.flags.type.startsWith('basercms') ? [] : ['**/bge_style.css'],
111
- )
112
- .add(
113
- // static
114
- cli.flags.type === 'static' ? ['**/__tmpl/**/*'] : [],
115
- );
111
+ ]);
116
112
 
117
113
  const scaffoldFiles = ig.filter(await getAllFiles(scaffoldDir, scaffoldDir)).toSorted();
118
114
 
@@ -181,8 +177,25 @@ export default async function (plop) {
181
177
  console.log(config);
182
178
  }
183
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
+
184
197
  return [
185
- ...scaffoldFiles.map(
198
+ ...filteredFiles.map(
186
199
  /**
187
200
  * @see https://plopjs.com/documentation/#add
188
201
  * @type {import('plop').AddActionConfig}
@@ -192,7 +205,7 @@ export default async function (plop) {
192
205
  type: 'add',
193
206
  path: path.resolve(config.dest, originFile),
194
207
  templateFile: path.resolve(scaffoldDir, originFile),
195
- transform(content) {
208
+ async transform(content) {
196
209
  const nameCandidate = path.basename(path.resolve(config.dest));
197
210
 
198
211
  switch (originFile) {
@@ -230,15 +243,29 @@ export default async function (plop) {
230
243
  }
231
244
  break;
232
245
  }
233
- case '__assets/htdocs/index.pug': {
234
- if (config.type === 'static') {
235
- content = fs.readFileSync(
236
- path.resolve(scaffoldDir, '__assets/htdocs/__tmpl/000_home.pug'),
237
- 'utf8',
238
- );
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;
239
251
  }
252
+ break;
240
253
  }
241
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
+
242
269
  return content;
243
270
  },
244
271
  };