create-specment 0.2.9 → 0.3.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/bin/commands/create.d.ts +0 -1
- package/bin/constants/languages.d.ts +0 -1
- package/bin/core/interactive-setup.d.ts +0 -1
- package/bin/core/interactive-setup.js +17 -10
- package/bin/core/interactive-setup.js.map +1 -1
- package/bin/core/interactive-setup.test.d.ts +0 -1
- package/bin/core/interactive-setup.test.js +7 -7
- package/bin/core/interactive-setup.test.js.map +1 -1
- package/bin/core/project-generator.d.ts +0 -1
- package/bin/core/project-generator.js +5 -8
- package/bin/core/project-generator.js.map +1 -1
- package/bin/features/index.d.ts +0 -1
- package/bin/features/index.js +15 -13
- package/bin/features/index.js.map +1 -1
- package/bin/generators/docusaurus-config.d.ts +0 -1
- package/bin/generators/docusaurus-config.js +211 -264
- package/bin/generators/docusaurus-config.js.map +1 -1
- package/bin/generators/package-json.d.ts +0 -1
- package/bin/generators/package-json.js +45 -91
- package/bin/generators/package-json.js.map +1 -1
- package/bin/generators/template-files.d.ts +0 -1
- package/bin/generators/template-files.js +563 -168
- package/bin/generators/template-files.js.map +1 -1
- package/bin/index.d.ts +0 -1
- package/bin/index.js.map +1 -1
- package/bin/templates/index.d.ts +0 -1
- package/bin/templates/index.js +36 -24
- package/bin/templates/index.js.map +1 -1
- package/bin/tests/integration.test.d.ts +0 -1
- package/bin/tests/integration.test.js +34 -34
- package/bin/tests/integration.test.js.map +1 -1
- package/bin/types/index.d.ts +1 -21
- package/bin/utils/config-merger.d.ts +0 -1
- package/bin/utils/config-merger.js +0 -1
- package/bin/utils/config-merger.js.map +1 -1
- package/bin/utils/errors.d.ts +0 -1
- package/bin/utils/install.d.ts +0 -1
- package/bin/utils/install.js +3 -3
- package/bin/utils/install.js.map +1 -1
- package/bin/utils/message-formatter.d.ts +0 -1
- package/bin/utils/template-processor.d.ts +0 -1
- package/bin/utils/template-processor.js +2 -3
- package/bin/utils/template-processor.js.map +1 -1
- package/bin/utils/template-processor.test.d.ts +0 -1
- package/bin/utils/template-processor.test.js +22 -22
- package/bin/utils/template-processor.test.js.map +1 -1
- package/bin/utils/version.d.ts +0 -1
- package/bin/utils/version.js +3 -3
- package/bin/utils/version.js.map +1 -1
- package/package.json +2 -7
- package/templates/docs/01-overview/_requirements-specification.mdx +1 -5
- package/templates/docs/01-overview/as-is.mdx +1 -1
- package/templates/docs/01-overview/glossary.mdx +6 -6
- package/templates/docs/01-overview/odsc.mdx +1 -1
- package/templates/docs/01-overview/to-be.mdx +6 -6
- package/templates/docs/02-requirements/functional/_req-template.mdx +0 -3
- package/templates/docs/02-requirements/functional/req-001.mdx +0 -4
- package/templates/docs/02-requirements/non-functional/_nfr-template.mdx +0 -3
- package/templates/docs/02-requirements/non-functional/nfr-001.mdx +0 -3
- package/templates/docs/02-requirements/non-functional/nfr-002.mdx +0 -3
- package/templates/docs/03-external/business-model.mdx +1 -1
- package/templates/docs/03-external/index.mdx +1 -1
- package/templates/docs/04-internal/batches/import-products.mdx +2 -6
- package/templates/docs/04-internal/policies/github.mdx +1 -1
- package/templates/docs/04-internal/rules/database.mdx +1 -1
- package/templates/docs/04-internal/screens/dashboard.mdx +1 -1
- package/templates/docs/04-internal/screens/index.mdx +1 -1
- package/templates/docs/04-internal/screens/login.mdx +1 -1
- package/templates/docs/04-internal/screens/menu.mdx +1 -1
- package/templates/docs/index.module.css +96 -0
- package/templates/docs/index.tsx +48 -0
- package/templates/docs/introduction/index.mdx +1 -1
- package/templates/docs/introduction/operational-policies/sharepoint.mdx +1 -1
- package/templates/package.json.template +46 -0
- package/templates/src/components/Highlight/index.tsx +68 -0
- package/templates/src/components/PriorityMatrix/index.tsx +97 -0
- package/templates/src/components/TBD/index.tsx +16 -0
- package/templates/src/css/custom.css +81 -0
- package/templates/src/types/requirements.ts +19 -0
- package/templates/static/img/business-model.drawio.svg +4 -0
- package/templates/static/img/gantt.drawio.svg +1152 -0
- package/templates/static/img/logo.svg +21 -0
- package/bin/commands/create.d.ts.map +0 -1
- package/bin/constants/languages.d.ts.map +0 -1
- package/bin/core/interactive-setup.d.ts.map +0 -1
- package/bin/core/interactive-setup.test.d.ts.map +0 -1
- package/bin/core/project-generator.d.ts.map +0 -1
- package/bin/features/index.d.ts.map +0 -1
- package/bin/generators/docusaurus-config.d.ts.map +0 -1
- package/bin/generators/package-json.d.ts.map +0 -1
- package/bin/generators/template-files.d.ts.map +0 -1
- package/bin/index.d.ts.map +0 -1
- package/bin/plugins/i18n-integration.d.ts +0 -25
- package/bin/plugins/i18n-integration.d.ts.map +0 -1
- package/bin/plugins/i18n-integration.js +0 -310
- package/bin/plugins/i18n-integration.js.map +0 -1
- package/bin/plugins/plantuml-integration.d.ts +0 -17
- package/bin/plugins/plantuml-integration.d.ts.map +0 -1
- package/bin/plugins/plantuml-integration.js +0 -112
- package/bin/plugins/plantuml-integration.js.map +0 -1
- package/bin/plugins/redoc-integration.d.ts +0 -25
- package/bin/plugins/redoc-integration.d.ts.map +0 -1
- package/bin/plugins/redoc-integration.js +0 -373
- package/bin/plugins/redoc-integration.js.map +0 -1
- package/bin/plugins/search-integration.d.ts +0 -20
- package/bin/plugins/search-integration.d.ts.map +0 -1
- package/bin/plugins/search-integration.js +0 -169
- package/bin/plugins/search-integration.js.map +0 -1
- package/bin/templates/index.d.ts.map +0 -1
- package/bin/templates/template-definitions.d.ts +0 -10
- package/bin/templates/template-definitions.d.ts.map +0 -1
- package/bin/templates/template-definitions.js +0 -517
- package/bin/templates/template-definitions.js.map +0 -1
- package/bin/tests/integration.test.d.ts.map +0 -1
- package/bin/types/index.d.ts.map +0 -1
- package/bin/utils/config-merger.d.ts.map +0 -1
- package/bin/utils/errors.d.ts.map +0 -1
- package/bin/utils/install.d.ts.map +0 -1
- package/bin/utils/message-formatter.d.ts.map +0 -1
- package/bin/utils/template-processor.d.ts.map +0 -1
- package/bin/utils/template-processor.test.d.ts.map +0 -1
- package/bin/utils/version.d.ts.map +0 -1
- package/templates/classic-spec/docusaurus.config.js.template +0 -106
- package/templates/classic-spec/package.json.template +0 -36
- package/templates/docs/example.drawio.svg +0 -57
- package/templates/external-design/docusaurus.config.js.template +0 -123
- package/templates/external-design/package.json.template +0 -36
- package/templates/internal-design/docusaurus.config.js.template +0 -123
- package/templates/internal-design/package.json.template +0 -36
- package/templates/project-analysis/docusaurus.config.js.template +0 -113
- package/templates/project-analysis/package.json.template +0 -36
- package/templates/requirements/docusaurus.config.js.template +0 -119
- package/templates/requirements/package.json.template +0 -36
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { mkdir, writeFile, access, cp } from '
|
|
2
|
-
import { join, resolve, dirname } from '
|
|
3
|
-
import { existsSync, constants } from '
|
|
4
|
-
import { fileURLToPath } from '
|
|
1
|
+
import { mkdir, writeFile, access, cp } from 'fs/promises';
|
|
2
|
+
import { join, resolve, dirname } from 'path';
|
|
3
|
+
import { existsSync, constants } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
5
|
import { createTemplateProcessor } from '../utils/template-processor.js';
|
|
6
|
-
import { getTemplateDefinition } from '../templates/template-definitions.js';
|
|
7
6
|
// プロジェクト内のテンプレートディレクトリのパス
|
|
8
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
8
|
const __dirname = dirname(__filename);
|
|
@@ -18,24 +17,19 @@ export async function copyTemplateFiles(selections, projectPath) {
|
|
|
18
17
|
templateName: primaryTemplate.name,
|
|
19
18
|
templateDisplayName: primaryTemplate.displayName,
|
|
20
19
|
});
|
|
21
|
-
// 全テンプレートのディレクトリ構造を統合
|
|
22
|
-
const combinedStructure = combineTemplateStructures(templates);
|
|
23
20
|
// ディレクトリ構造を作成
|
|
24
|
-
await createDirectoryStructure(projectPath
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
console.warn(`Template definition not found for: ${template.name}`);
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
// サンプルコンテンツを生成
|
|
33
|
-
await generateSampleContent(projectPath, templateDef.sampleContent, processor);
|
|
21
|
+
await createDirectoryStructure(projectPath);
|
|
22
|
+
// API機能が有効な場合はOpenAPIファイルとディレクトリを生成
|
|
23
|
+
const hasApiFeature = selections.features.some(f => f.enabled && f.name === 'redoc');
|
|
24
|
+
if (hasApiFeature) {
|
|
25
|
+
await generateOpenAPIFiles(projectPath);
|
|
34
26
|
}
|
|
35
|
-
//
|
|
36
|
-
await generateSidebarsConfig(projectPath,
|
|
27
|
+
// 基本ファイルを生成(選択されたテンプレート配列を渡す)
|
|
28
|
+
await generateSidebarsConfig(projectPath, templates, processor);
|
|
37
29
|
// 参考リポジトリから基本ファイルをコピー
|
|
38
30
|
await copyFromReferenceRepo(projectPath, ['introduction']);
|
|
31
|
+
// ルートページファイルをコピー
|
|
32
|
+
await copyRootPageFiles(projectPath);
|
|
39
33
|
// intro.mdもコピー
|
|
40
34
|
const introSourcePath = join(TEMPLATE_DOCS_PATH, 'intro.md');
|
|
41
35
|
const introTargetPath = join(projectPath, 'docs', 'intro.md');
|
|
@@ -54,38 +48,13 @@ export async function copyTemplateFiles(selections, projectPath) {
|
|
|
54
48
|
}
|
|
55
49
|
await generateCustomCSS(projectPath);
|
|
56
50
|
await generateStaticFiles(projectPath, processor);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
for (const template of templates) {
|
|
65
|
-
const templateDef = getTemplateDefinition(template.name);
|
|
66
|
-
if (templateDef?.directoryStructure) {
|
|
67
|
-
if (templateDef.directoryStructure.docs) {
|
|
68
|
-
for (const dir of templateDef.directoryStructure.docs) {
|
|
69
|
-
combined.docs.add(dir);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (templateDef.directoryStructure.static) {
|
|
73
|
-
for (const dir of templateDef.directoryStructure.static) {
|
|
74
|
-
combined.static.add(dir);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (templateDef.directoryStructure.src) {
|
|
78
|
-
for (const dir of templateDef.directoryStructure.src) {
|
|
79
|
-
combined.src.add(dir);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
51
|
+
await copyStaticAssets(projectPath);
|
|
52
|
+
await generateTBDComponent(projectPath);
|
|
53
|
+
// 要件定義テンプレートが選択されている場合はPriorityMatrixコンポーネントをコピー
|
|
54
|
+
const hasRequirementsTemplate = templates.some(template => template.name === 'requirements');
|
|
55
|
+
if (hasRequirementsTemplate) {
|
|
56
|
+
await generatePriorityMatrixComponent(projectPath);
|
|
83
57
|
}
|
|
84
|
-
return {
|
|
85
|
-
docs: Array.from(combined.docs),
|
|
86
|
-
static: Array.from(combined.static),
|
|
87
|
-
src: Array.from(combined.src),
|
|
88
|
-
};
|
|
89
58
|
}
|
|
90
59
|
async function validateProjectPath(projectPath) {
|
|
91
60
|
const resolvedPath = resolve(projectPath);
|
|
@@ -101,128 +70,47 @@ async function validateProjectPath(projectPath) {
|
|
|
101
70
|
throw new Error(`No write permission for directory: ${resolvedPath}`);
|
|
102
71
|
}
|
|
103
72
|
}
|
|
104
|
-
async function createDirectoryStructure(projectPath
|
|
73
|
+
async function createDirectoryStructure(projectPath) {
|
|
105
74
|
// 基本ディレクトリを作成
|
|
106
75
|
const baseDirectories = ['docs', 'src/css', 'src/components', 'static/img'];
|
|
107
76
|
for (const dir of baseDirectories) {
|
|
108
77
|
const dirPath = join(projectPath, dir);
|
|
109
78
|
await mkdir(dirPath, { recursive: true });
|
|
110
79
|
}
|
|
111
|
-
// テンプレート固有のディレクトリを作成
|
|
112
|
-
if (structure.docs) {
|
|
113
|
-
for (const docDir of structure.docs) {
|
|
114
|
-
const dirPath = join(projectPath, 'docs', docDir);
|
|
115
|
-
await mkdir(dirPath, { recursive: true });
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (structure.static) {
|
|
119
|
-
for (const staticDir of structure.static) {
|
|
120
|
-
const dirPath = join(projectPath, 'static', staticDir);
|
|
121
|
-
await mkdir(dirPath, { recursive: true });
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (structure.src) {
|
|
125
|
-
for (const srcDir of structure.src) {
|
|
126
|
-
const dirPath = join(projectPath, 'src', srcDir);
|
|
127
|
-
await mkdir(dirPath, { recursive: true });
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
80
|
}
|
|
131
|
-
async function
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
await mkdir(dirPath, { recursive: true });
|
|
154
|
-
// 既存のディレクトリと同名のファイルを作成しようとしている場合はエラー
|
|
155
|
-
if (existsSync(filePath)) {
|
|
156
|
-
const { stat } = await import('node:fs/promises');
|
|
157
|
-
const stats = await stat(filePath);
|
|
158
|
-
if (stats.isDirectory()) {
|
|
159
|
-
throw new Error(`Cannot create file '${filePath}': A directory with the same name already exists`);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (content.template) {
|
|
163
|
-
// テンプレート変数を置換
|
|
164
|
-
const processedContent = processor.processTemplate(content.content);
|
|
165
|
-
await writeFile(filePath, processedContent, 'utf8');
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
// そのまま書き込み
|
|
169
|
-
await writeFile(filePath, content.content, 'utf8');
|
|
81
|
+
async function generateSidebarsConfig(projectPath, selectedTemplates, processor) {
|
|
82
|
+
const sidebarSections = [];
|
|
83
|
+
// 常に含まれるセクション
|
|
84
|
+
sidebarSections.push('introduction: [{ type: \'autogenerated\', dirName: \'introduction\' }]');
|
|
85
|
+
// 選択されたテンプレートに応じてセクションを追加
|
|
86
|
+
for (const template of selectedTemplates) {
|
|
87
|
+
switch (template.name) {
|
|
88
|
+
case 'project-analysis':
|
|
89
|
+
sidebarSections.push('overview: [{ type: \'autogenerated\', dirName: \'overview\' }]');
|
|
90
|
+
break;
|
|
91
|
+
case 'requirements':
|
|
92
|
+
sidebarSections.push('requirements: [{ type: \'autogenerated\', dirName: \'requirements\' }]');
|
|
93
|
+
break;
|
|
94
|
+
case 'external-design':
|
|
95
|
+
sidebarSections.push('external: [{ type: \'autogenerated\', dirName: \'external\' }]');
|
|
96
|
+
break;
|
|
97
|
+
case 'internal-design':
|
|
98
|
+
sidebarSections.push('internal: [{ type: \'autogenerated\', dirName: \'internal\' }]');
|
|
99
|
+
break;
|
|
100
|
+
case 'api-spec':
|
|
101
|
+
// APIテンプレートの場合は特別なセクションは追加しない(Redocで表示)
|
|
102
|
+
break;
|
|
170
103
|
}
|
|
171
104
|
}
|
|
172
|
-
}
|
|
173
|
-
async function generateSidebarsConfig(projectPath, templateName, processor) {
|
|
174
|
-
const sidebarConfigs = {
|
|
175
|
-
'classic-spec': `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
105
|
+
const sidebarContent = `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
176
106
|
|
|
177
107
|
// https://docusaurus.io/docs/sidebar
|
|
178
108
|
|
|
179
109
|
const sidebars: SidebarsConfig = {
|
|
180
|
-
|
|
110
|
+
${sidebarSections.join(',\n ')},
|
|
181
111
|
};
|
|
182
112
|
|
|
183
|
-
export default sidebars
|
|
184
|
-
'project-analysis': `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
185
|
-
|
|
186
|
-
// https://docusaurus.io/docs/sidebar
|
|
187
|
-
|
|
188
|
-
const sidebars: SidebarsConfig = {
|
|
189
|
-
introduction: [{ type: 'autogenerated', dirName: 'introduction' }],
|
|
190
|
-
businessAnalysis: [{ type: 'autogenerated', dirName: '01-overview' }],
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
export default sidebars;`,
|
|
194
|
-
requirements: `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
195
|
-
|
|
196
|
-
// https://docusaurus.io/docs/sidebar
|
|
197
|
-
|
|
198
|
-
const sidebars: SidebarsConfig = {
|
|
199
|
-
introduction: [{ type: 'autogenerated', dirName: 'introduction' }],
|
|
200
|
-
requirements: [{ type: 'autogenerated', dirName: '02-requirements' }],
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export default sidebars;`,
|
|
204
|
-
'external-design': `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
205
|
-
|
|
206
|
-
// https://docusaurus.io/docs/sidebar
|
|
207
|
-
|
|
208
|
-
const sidebars: SidebarsConfig = {
|
|
209
|
-
introduction: [{ type: 'autogenerated', dirName: 'introduction' }],
|
|
210
|
-
external: [{ type: 'autogenerated', dirName: '03-external' }],
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
export default sidebars;`,
|
|
214
|
-
'internal-design': `import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
|
215
|
-
|
|
216
|
-
// https://docusaurus.io/docs/sidebar
|
|
217
|
-
|
|
218
|
-
const sidebars: SidebarsConfig = {
|
|
219
|
-
introduction: [{ type: 'autogenerated', dirName: 'introduction' }],
|
|
220
|
-
internal: [{ type: 'autogenerated', dirName: '04-internal' }],
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
export default sidebars;`,
|
|
224
|
-
};
|
|
225
|
-
const sidebarContent = sidebarConfigs[templateName] || sidebarConfigs['classic-spec'];
|
|
113
|
+
export default sidebars;`;
|
|
226
114
|
const processedContent = processor.processTemplate(sidebarContent);
|
|
227
115
|
await writeFile(join(projectPath, 'sidebars.ts'), processedContent);
|
|
228
116
|
}
|
|
@@ -322,6 +210,35 @@ yarn-error.log*
|
|
|
322
210
|
`;
|
|
323
211
|
await writeFile(join(projectPath, '.gitignore'), gitignoreContent, 'utf8');
|
|
324
212
|
}
|
|
213
|
+
// ルートページファイルをコピー
|
|
214
|
+
async function copyRootPageFiles(projectPath) {
|
|
215
|
+
const srcPagesDir = join(projectPath, 'src', 'pages');
|
|
216
|
+
await mkdir(srcPagesDir, { recursive: true });
|
|
217
|
+
// index.tsxファイルをコピー(ユーザーが編集済み)
|
|
218
|
+
const indexSourcePath = join(TEMPLATE_DOCS_PATH, 'index.tsx');
|
|
219
|
+
const indexTargetPath = join(srcPagesDir, 'index.tsx');
|
|
220
|
+
if (existsSync(indexSourcePath)) {
|
|
221
|
+
try {
|
|
222
|
+
await cp(indexSourcePath, indexTargetPath);
|
|
223
|
+
console.log('Copied index.tsx to src/pages');
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
console.warn(`Failed to copy index.tsx: ${error}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// index.module.cssファイルをコピー(参考リポジトリからコピー済み)
|
|
230
|
+
const cssSourcePath = join(TEMPLATE_DOCS_PATH, 'index.module.css');
|
|
231
|
+
const cssTargetPath = join(srcPagesDir, 'index.module.css');
|
|
232
|
+
if (existsSync(cssSourcePath)) {
|
|
233
|
+
try {
|
|
234
|
+
await cp(cssSourcePath, cssTargetPath);
|
|
235
|
+
console.log('Copied index.module.css to src/pages');
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.warn(`Failed to copy index.module.css: ${error}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
325
242
|
// プロジェクト内のテンプレートから基本ディレクトリをコピー
|
|
326
243
|
async function copyFromReferenceRepo(projectPath, directories) {
|
|
327
244
|
const docsPath = join(projectPath, 'docs');
|
|
@@ -345,30 +262,508 @@ async function copyFromReferenceRepo(projectPath, directories) {
|
|
|
345
262
|
// テンプレートに対応するディレクトリをコピー
|
|
346
263
|
async function copyTemplateDirectory(projectPath, templateName) {
|
|
347
264
|
const templateDirMap = {
|
|
348
|
-
'classic-spec': 'introduction',
|
|
349
|
-
'project-analysis': '01-overview',
|
|
350
|
-
'requirements': '02-requirements',
|
|
351
|
-
'external-design': '03-external',
|
|
352
|
-
'internal-design': '04-internal',
|
|
265
|
+
'classic-spec': { source: 'introduction', target: 'introduction' },
|
|
266
|
+
'project-analysis': { source: '01-overview', target: 'overview' },
|
|
267
|
+
'requirements': { source: '02-requirements', target: 'requirements' },
|
|
268
|
+
'external-design': { source: '03-external', target: 'external' },
|
|
269
|
+
'internal-design': { source: '04-internal', target: 'internal' },
|
|
270
|
+
'technical-spec': { source: '04-internal', target: 'internal' }, // 技術仕様書は内部設計と同じディレクトリを使用
|
|
353
271
|
};
|
|
354
|
-
const
|
|
355
|
-
if (!
|
|
272
|
+
const dirMapping = templateDirMap[templateName];
|
|
273
|
+
if (!dirMapping) {
|
|
356
274
|
console.warn(`No directory mapping found for template: ${templateName}`);
|
|
357
275
|
return;
|
|
358
276
|
}
|
|
359
|
-
const sourcePath = join(TEMPLATE_DOCS_PATH,
|
|
360
|
-
const targetPath = join(projectPath, 'docs',
|
|
277
|
+
const sourcePath = join(TEMPLATE_DOCS_PATH, dirMapping.source);
|
|
278
|
+
const targetPath = join(projectPath, 'docs', dirMapping.target);
|
|
361
279
|
if (existsSync(sourcePath)) {
|
|
362
280
|
try {
|
|
363
281
|
await cp(sourcePath, targetPath, { recursive: true });
|
|
364
|
-
console.log(`Copied ${
|
|
282
|
+
console.log(`Copied ${dirMapping.source} directory for template: ${templateName}`);
|
|
365
283
|
}
|
|
366
284
|
catch (error) {
|
|
367
|
-
console.warn(`Failed to copy ${
|
|
285
|
+
console.warn(`Failed to copy ${dirMapping.source}: ${error}`);
|
|
368
286
|
}
|
|
369
287
|
}
|
|
370
288
|
else {
|
|
371
289
|
console.warn(`Template directory not found: ${sourcePath}`);
|
|
372
290
|
}
|
|
373
291
|
}
|
|
292
|
+
// OpenAPIファイルとディレクトリを生成
|
|
293
|
+
async function generateOpenAPIFiles(projectPath) {
|
|
294
|
+
// openapiディレクトリを作成
|
|
295
|
+
const openapiDir = join(projectPath, 'openapi');
|
|
296
|
+
await mkdir(openapiDir, { recursive: true });
|
|
297
|
+
// 参考リポジトリのOpenAPIファイルをコピー
|
|
298
|
+
const referenceOpenAPIPath = '/home/ohbayashi/projects/specment/openapi/openapi-single.yaml';
|
|
299
|
+
const targetOpenAPIPath = join(openapiDir, 'openapi-single.yaml');
|
|
300
|
+
if (existsSync(referenceOpenAPIPath)) {
|
|
301
|
+
try {
|
|
302
|
+
await cp(referenceOpenAPIPath, targetOpenAPIPath);
|
|
303
|
+
console.log('Copied OpenAPI specification from reference repository');
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
console.warn(`Failed to copy OpenAPI file: ${error}`);
|
|
307
|
+
// フォールバック: サンプルOpenAPIファイルを生成
|
|
308
|
+
await generateSampleOpenAPIFile(targetOpenAPIPath);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
// 参考ファイルが見つからない場合はサンプルを生成
|
|
313
|
+
await generateSampleOpenAPIFile(targetOpenAPIPath);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// サンプルOpenAPIファイルを生成
|
|
317
|
+
async function generateSampleOpenAPIFile(filePath) {
|
|
318
|
+
const sampleOpenAPI = `openapi: 3.0.3
|
|
319
|
+
servers:
|
|
320
|
+
- url: //api.example.com/v1
|
|
321
|
+
description: プロダクションサーバー
|
|
322
|
+
- url: //staging-api.example.com/v1
|
|
323
|
+
description: ステージングサーバー
|
|
324
|
+
info:
|
|
325
|
+
description: |
|
|
326
|
+
これはサンプルAPIの仕様書です。
|
|
327
|
+
|
|
328
|
+
# はじめに
|
|
329
|
+
このAPIは **OpenAPI形式** でドキュメント化されており、RESTful APIの設計原則に従っています。
|
|
330
|
+
|
|
331
|
+
# 認証
|
|
332
|
+
このAPIはJWT(JSON Web Token)を使用したBearer認証を採用しています。
|
|
333
|
+
|
|
334
|
+
# レスポンス形式
|
|
335
|
+
すべてのAPIレスポンスはJSON形式で返されます。
|
|
336
|
+
|
|
337
|
+
version: 1.0.0
|
|
338
|
+
title: Sample API
|
|
339
|
+
contact:
|
|
340
|
+
name: APIサポート
|
|
341
|
+
email: support@example.com
|
|
342
|
+
license:
|
|
343
|
+
name: MIT
|
|
344
|
+
url: 'https://opensource.org/licenses/MIT'
|
|
345
|
+
tags:
|
|
346
|
+
- name: users
|
|
347
|
+
description: ユーザー管理
|
|
348
|
+
- name: auth
|
|
349
|
+
description: 認証・認可
|
|
350
|
+
paths:
|
|
351
|
+
/users:
|
|
352
|
+
get:
|
|
353
|
+
tags:
|
|
354
|
+
- users
|
|
355
|
+
summary: ユーザー一覧を取得
|
|
356
|
+
description: システムに登録されているユーザーの一覧を取得します
|
|
357
|
+
parameters:
|
|
358
|
+
- name: limit
|
|
359
|
+
in: query
|
|
360
|
+
description: 取得する件数の上限
|
|
361
|
+
required: false
|
|
362
|
+
schema:
|
|
363
|
+
type: integer
|
|
364
|
+
minimum: 1
|
|
365
|
+
maximum: 100
|
|
366
|
+
default: 20
|
|
367
|
+
- name: offset
|
|
368
|
+
in: query
|
|
369
|
+
description: 取得開始位置
|
|
370
|
+
required: false
|
|
371
|
+
schema:
|
|
372
|
+
type: integer
|
|
373
|
+
minimum: 0
|
|
374
|
+
default: 0
|
|
375
|
+
responses:
|
|
376
|
+
'200':
|
|
377
|
+
description: ユーザー一覧の取得に成功
|
|
378
|
+
content:
|
|
379
|
+
application/json:
|
|
380
|
+
schema:
|
|
381
|
+
type: object
|
|
382
|
+
properties:
|
|
383
|
+
users:
|
|
384
|
+
type: array
|
|
385
|
+
items:
|
|
386
|
+
$ref: '#/components/schemas/User'
|
|
387
|
+
total:
|
|
388
|
+
type: integer
|
|
389
|
+
description: 総件数
|
|
390
|
+
limit:
|
|
391
|
+
type: integer
|
|
392
|
+
description: 取得件数の上限
|
|
393
|
+
offset:
|
|
394
|
+
type: integer
|
|
395
|
+
description: 取得開始位置
|
|
396
|
+
'400':
|
|
397
|
+
description: リクエストパラメータが不正
|
|
398
|
+
content:
|
|
399
|
+
application/json:
|
|
400
|
+
schema:
|
|
401
|
+
$ref: '#/components/schemas/Error'
|
|
402
|
+
'500':
|
|
403
|
+
description: サーバーエラー
|
|
404
|
+
content:
|
|
405
|
+
application/json:
|
|
406
|
+
schema:
|
|
407
|
+
$ref: '#/components/schemas/Error'
|
|
408
|
+
security:
|
|
409
|
+
- BearerAuth: []
|
|
410
|
+
post:
|
|
411
|
+
tags:
|
|
412
|
+
- users
|
|
413
|
+
summary: 新しいユーザーを作成
|
|
414
|
+
description: 新しいユーザーをシステムに登録します
|
|
415
|
+
requestBody:
|
|
416
|
+
required: true
|
|
417
|
+
content:
|
|
418
|
+
application/json:
|
|
419
|
+
schema:
|
|
420
|
+
$ref: '#/components/schemas/CreateUserRequest'
|
|
421
|
+
responses:
|
|
422
|
+
'201':
|
|
423
|
+
description: ユーザーの作成に成功
|
|
424
|
+
content:
|
|
425
|
+
application/json:
|
|
426
|
+
schema:
|
|
427
|
+
$ref: '#/components/schemas/User'
|
|
428
|
+
'400':
|
|
429
|
+
description: リクエストボディが不正
|
|
430
|
+
content:
|
|
431
|
+
application/json:
|
|
432
|
+
schema:
|
|
433
|
+
$ref: '#/components/schemas/Error'
|
|
434
|
+
'409':
|
|
435
|
+
description: ユーザーが既に存在
|
|
436
|
+
content:
|
|
437
|
+
application/json:
|
|
438
|
+
schema:
|
|
439
|
+
$ref: '#/components/schemas/Error'
|
|
440
|
+
'500':
|
|
441
|
+
description: サーバーエラー
|
|
442
|
+
content:
|
|
443
|
+
application/json:
|
|
444
|
+
schema:
|
|
445
|
+
$ref: '#/components/schemas/Error'
|
|
446
|
+
security:
|
|
447
|
+
- BearerAuth: []
|
|
448
|
+
|
|
449
|
+
/users/{userId}:
|
|
450
|
+
get:
|
|
451
|
+
tags:
|
|
452
|
+
- users
|
|
453
|
+
summary: ユーザー詳細を取得
|
|
454
|
+
description: 指定されたIDのユーザー詳細情報を取得します
|
|
455
|
+
parameters:
|
|
456
|
+
- name: userId
|
|
457
|
+
in: path
|
|
458
|
+
required: true
|
|
459
|
+
description: ユーザーID
|
|
460
|
+
schema:
|
|
461
|
+
type: string
|
|
462
|
+
format: uuid
|
|
463
|
+
responses:
|
|
464
|
+
'200':
|
|
465
|
+
description: ユーザー詳細の取得に成功
|
|
466
|
+
content:
|
|
467
|
+
application/json:
|
|
468
|
+
schema:
|
|
469
|
+
$ref: '#/components/schemas/User'
|
|
470
|
+
'404':
|
|
471
|
+
description: ユーザーが見つからない
|
|
472
|
+
content:
|
|
473
|
+
application/json:
|
|
474
|
+
schema:
|
|
475
|
+
$ref: '#/components/schemas/Error'
|
|
476
|
+
'500':
|
|
477
|
+
description: サーバーエラー
|
|
478
|
+
content:
|
|
479
|
+
application/json:
|
|
480
|
+
schema:
|
|
481
|
+
$ref: '#/components/schemas/Error'
|
|
482
|
+
security:
|
|
483
|
+
- BearerAuth: []
|
|
484
|
+
|
|
485
|
+
/auth/login:
|
|
486
|
+
post:
|
|
487
|
+
tags:
|
|
488
|
+
- auth
|
|
489
|
+
summary: ユーザーログイン
|
|
490
|
+
description: ユーザー認証を行い、JWTトークンを発行します
|
|
491
|
+
requestBody:
|
|
492
|
+
required: true
|
|
493
|
+
content:
|
|
494
|
+
application/json:
|
|
495
|
+
schema:
|
|
496
|
+
type: object
|
|
497
|
+
required:
|
|
498
|
+
- email
|
|
499
|
+
- password
|
|
500
|
+
properties:
|
|
501
|
+
email:
|
|
502
|
+
type: string
|
|
503
|
+
format: email
|
|
504
|
+
description: メールアドレス
|
|
505
|
+
example: "user@example.com"
|
|
506
|
+
password:
|
|
507
|
+
type: string
|
|
508
|
+
description: パスワード
|
|
509
|
+
example: "password123"
|
|
510
|
+
responses:
|
|
511
|
+
'200':
|
|
512
|
+
description: ログイン成功
|
|
513
|
+
content:
|
|
514
|
+
application/json:
|
|
515
|
+
schema:
|
|
516
|
+
type: object
|
|
517
|
+
properties:
|
|
518
|
+
token:
|
|
519
|
+
type: string
|
|
520
|
+
description: JWTトークン
|
|
521
|
+
user:
|
|
522
|
+
$ref: '#/components/schemas/User'
|
|
523
|
+
'401':
|
|
524
|
+
description: 認証失敗
|
|
525
|
+
content:
|
|
526
|
+
application/json:
|
|
527
|
+
schema:
|
|
528
|
+
$ref: '#/components/schemas/Error'
|
|
529
|
+
'500':
|
|
530
|
+
description: サーバーエラー
|
|
531
|
+
content:
|
|
532
|
+
application/json:
|
|
533
|
+
schema:
|
|
534
|
+
$ref: '#/components/schemas/Error'
|
|
535
|
+
|
|
536
|
+
components:
|
|
537
|
+
schemas:
|
|
538
|
+
User:
|
|
539
|
+
type: object
|
|
540
|
+
required:
|
|
541
|
+
- id
|
|
542
|
+
- name
|
|
543
|
+
- email
|
|
544
|
+
- createdAt
|
|
545
|
+
properties:
|
|
546
|
+
id:
|
|
547
|
+
type: string
|
|
548
|
+
format: uuid
|
|
549
|
+
description: ユーザーID
|
|
550
|
+
example: "123e4567-e89b-12d3-a456-426614174000"
|
|
551
|
+
name:
|
|
552
|
+
type: string
|
|
553
|
+
description: ユーザー名
|
|
554
|
+
minLength: 1
|
|
555
|
+
maxLength: 100
|
|
556
|
+
example: "田中太郎"
|
|
557
|
+
email:
|
|
558
|
+
type: string
|
|
559
|
+
format: email
|
|
560
|
+
description: メールアドレス
|
|
561
|
+
example: "tanaka@example.com"
|
|
562
|
+
age:
|
|
563
|
+
type: integer
|
|
564
|
+
description: 年齢
|
|
565
|
+
minimum: 0
|
|
566
|
+
maximum: 150
|
|
567
|
+
example: 30
|
|
568
|
+
createdAt:
|
|
569
|
+
type: string
|
|
570
|
+
format: date-time
|
|
571
|
+
description: 作成日時
|
|
572
|
+
example: "2023-01-01T00:00:00Z"
|
|
573
|
+
updatedAt:
|
|
574
|
+
type: string
|
|
575
|
+
format: date-time
|
|
576
|
+
description: 更新日時
|
|
577
|
+
example: "2023-01-01T00:00:00Z"
|
|
578
|
+
|
|
579
|
+
CreateUserRequest:
|
|
580
|
+
type: object
|
|
581
|
+
required:
|
|
582
|
+
- name
|
|
583
|
+
- email
|
|
584
|
+
- password
|
|
585
|
+
properties:
|
|
586
|
+
name:
|
|
587
|
+
type: string
|
|
588
|
+
description: ユーザー名
|
|
589
|
+
minLength: 1
|
|
590
|
+
maxLength: 100
|
|
591
|
+
example: "田中太郎"
|
|
592
|
+
email:
|
|
593
|
+
type: string
|
|
594
|
+
format: email
|
|
595
|
+
description: メールアドレス
|
|
596
|
+
example: "tanaka@example.com"
|
|
597
|
+
age:
|
|
598
|
+
type: integer
|
|
599
|
+
description: 年齢
|
|
600
|
+
minimum: 0
|
|
601
|
+
maximum: 150
|
|
602
|
+
example: 30
|
|
603
|
+
password:
|
|
604
|
+
type: string
|
|
605
|
+
description: パスワード
|
|
606
|
+
minLength: 8
|
|
607
|
+
example: "password123"
|
|
608
|
+
|
|
609
|
+
Error:
|
|
610
|
+
type: object
|
|
611
|
+
required:
|
|
612
|
+
- code
|
|
613
|
+
- message
|
|
614
|
+
properties:
|
|
615
|
+
code:
|
|
616
|
+
type: string
|
|
617
|
+
description: エラーコード
|
|
618
|
+
example: "INVALID_REQUEST"
|
|
619
|
+
message:
|
|
620
|
+
type: string
|
|
621
|
+
description: エラーメッセージ
|
|
622
|
+
example: "リクエストパラメータが不正です"
|
|
623
|
+
details:
|
|
624
|
+
type: object
|
|
625
|
+
description: エラーの詳細情報
|
|
626
|
+
additionalProperties: true
|
|
627
|
+
|
|
628
|
+
securitySchemes:
|
|
629
|
+
BearerAuth:
|
|
630
|
+
type: http
|
|
631
|
+
scheme: bearer
|
|
632
|
+
bearerFormat: JWT
|
|
633
|
+
|
|
634
|
+
security:
|
|
635
|
+
- BearerAuth: []
|
|
636
|
+
`;
|
|
637
|
+
await writeFile(filePath, sampleOpenAPI, 'utf8');
|
|
638
|
+
console.log('Generated sample OpenAPI specification');
|
|
639
|
+
}
|
|
640
|
+
// 静的アセット(画像など)をコピー
|
|
641
|
+
async function copyStaticAssets(projectPath) {
|
|
642
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
643
|
+
const __dirname = dirname(__filename);
|
|
644
|
+
const TEMPLATE_STATIC_PATH = resolve(__dirname, '../../templates/static');
|
|
645
|
+
const staticTargetPath = join(projectPath, 'static');
|
|
646
|
+
if (existsSync(TEMPLATE_STATIC_PATH)) {
|
|
647
|
+
try {
|
|
648
|
+
await cp(TEMPLATE_STATIC_PATH, staticTargetPath, { recursive: true });
|
|
649
|
+
console.log('Copied static assets from templates/static');
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
console.warn(`Failed to copy static assets: ${error}`);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
console.warn(`Template static directory not found: ${TEMPLATE_STATIC_PATH}`);
|
|
657
|
+
// フォールバック: 個別にファイルをコピー
|
|
658
|
+
const staticImgDir = join(projectPath, 'static', 'img');
|
|
659
|
+
await mkdir(staticImgDir, { recursive: true });
|
|
660
|
+
// logo.svgファイルをコピー
|
|
661
|
+
const logoSourcePath = join(TEMPLATE_DOCS_PATH, 'logo.svg');
|
|
662
|
+
const logoTargetPath = join(staticImgDir, 'logo.svg');
|
|
663
|
+
if (existsSync(logoSourcePath)) {
|
|
664
|
+
try {
|
|
665
|
+
await cp(logoSourcePath, logoTargetPath);
|
|
666
|
+
console.log('Copied logo.svg to static/img');
|
|
667
|
+
}
|
|
668
|
+
catch (error) {
|
|
669
|
+
console.warn(`Failed to copy logo.svg: ${error}`);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
// PriorityMatrixコンポーネントをコピー(要件定義テンプレート用)
|
|
675
|
+
async function generatePriorityMatrixComponent(projectPath) {
|
|
676
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
677
|
+
const __dirname = dirname(__filename);
|
|
678
|
+
const TEMPLATE_SRC_PATH = resolve(__dirname, '../../templates/src');
|
|
679
|
+
// PriorityMatrixコンポーネントをコピー
|
|
680
|
+
const priorityMatrixSourcePath = join(TEMPLATE_SRC_PATH, 'components', 'PriorityMatrix');
|
|
681
|
+
const priorityMatrixTargetPath = join(projectPath, 'src', 'components', 'PriorityMatrix');
|
|
682
|
+
if (existsSync(priorityMatrixSourcePath)) {
|
|
683
|
+
try {
|
|
684
|
+
await cp(priorityMatrixSourcePath, priorityMatrixTargetPath, { recursive: true });
|
|
685
|
+
console.log('Generated PriorityMatrix component');
|
|
686
|
+
}
|
|
687
|
+
catch (error) {
|
|
688
|
+
console.warn(`Failed to copy PriorityMatrix component: ${error}`);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
else {
|
|
692
|
+
console.warn(`PriorityMatrix component template not found: ${priorityMatrixSourcePath}`);
|
|
693
|
+
}
|
|
694
|
+
// 型定義ファイルをコピー(存在する場合)
|
|
695
|
+
const typesSourcePath = join(TEMPLATE_SRC_PATH, 'types');
|
|
696
|
+
const typesTargetPath = join(projectPath, 'src', 'types');
|
|
697
|
+
if (existsSync(typesSourcePath)) {
|
|
698
|
+
try {
|
|
699
|
+
await cp(typesSourcePath, typesTargetPath, { recursive: true });
|
|
700
|
+
console.log('Generated types directory');
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
console.warn(`Failed to copy types directory: ${error}`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
// 型定義ファイルが存在しない場合は作成
|
|
708
|
+
await mkdir(typesTargetPath, { recursive: true });
|
|
709
|
+
const requirementsTypeContent = `/**
|
|
710
|
+
* Requirements related type definitions
|
|
711
|
+
*/
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Priority scale from 1 to 9
|
|
715
|
+
* 1-3: Low priority
|
|
716
|
+
* 4-6: Medium priority
|
|
717
|
+
* 7-9: High priority
|
|
718
|
+
*/
|
|
719
|
+
export type PriorityScale = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Requirement priority matrix
|
|
723
|
+
*/
|
|
724
|
+
export interface RequirementPriority {
|
|
725
|
+
importance: PriorityScale;
|
|
726
|
+
urgency: PriorityScale;
|
|
727
|
+
}
|
|
728
|
+
`;
|
|
729
|
+
await writeFile(join(typesTargetPath, 'requirements.ts'), requirementsTypeContent, 'utf8');
|
|
730
|
+
console.log('Generated requirements.ts type definitions');
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
// TBDコンポーネントとその依存関係をコピー
|
|
734
|
+
async function generateTBDComponent(projectPath) {
|
|
735
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
736
|
+
const __dirname = dirname(__filename);
|
|
737
|
+
const TEMPLATE_SRC_PATH = resolve(__dirname, '../../templates/src');
|
|
738
|
+
// TBDコンポーネントをコピー
|
|
739
|
+
const tbdSourcePath = join(TEMPLATE_SRC_PATH, 'components', 'TBD');
|
|
740
|
+
const tbdTargetPath = join(projectPath, 'src', 'components', 'TBD');
|
|
741
|
+
if (existsSync(tbdSourcePath)) {
|
|
742
|
+
try {
|
|
743
|
+
await cp(tbdSourcePath, tbdTargetPath, { recursive: true });
|
|
744
|
+
console.log('Generated TBD component');
|
|
745
|
+
}
|
|
746
|
+
catch (error) {
|
|
747
|
+
console.warn(`Failed to copy TBD component: ${error}`);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
console.warn(`TBD component template not found: ${tbdSourcePath}`);
|
|
752
|
+
}
|
|
753
|
+
// Highlightコンポーネントもコピー(TBDが依存しているため)
|
|
754
|
+
const highlightSourcePath = join(TEMPLATE_SRC_PATH, 'components', 'Highlight');
|
|
755
|
+
const highlightTargetPath = join(projectPath, 'src', 'components', 'Highlight');
|
|
756
|
+
if (existsSync(highlightSourcePath)) {
|
|
757
|
+
try {
|
|
758
|
+
await cp(highlightSourcePath, highlightTargetPath, { recursive: true });
|
|
759
|
+
console.log('Generated Highlight component');
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
console.warn(`Failed to copy Highlight component: ${error}`);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
console.warn(`Highlight component template not found: ${highlightSourcePath}`);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
374
769
|
//# sourceMappingURL=template-files.js.map
|