@skspwork/config-doc 2.0.2 → 2.0.4
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/package.json +3 -2
- package/packages/web/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/packages/web/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/packages/web/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/packages/web/.next/standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/packages/web/.next/standalone/.next/server/app/index.html +1 -1
- package/packages/web/.next/standalone/.next/server/app/index.rsc +3 -3
- package/packages/web/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/packages/web/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/packages/web/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/packages/web/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/packages/web/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/packages/web/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_d09de205.js +84 -24
- package/packages/web/.next/standalone/.next/server/chunks/ssr/app_page_tsx_55b2e5ee._.js +1 -1
- package/packages/web/.next/standalone/.next/server/pages/404.html +1 -1
- package/packages/web/.next/standalone/.next/static/chunks/9726c2cde77e0916.js +1 -0
- package/packages/web/.next/standalone/.next/static/chunks/cd878566fda12635.css +3 -0
- package/packages/web/.next/standalone/hooks/useConfigManager.ts +72 -52
- package/packages/web/.next/standalone/lib/configManagerUtils.ts +84 -0
- package/packages/web/.next/standalone/lib/configParser.ts +44 -0
- package/packages/web/.next/standalone/lib/htmlGenerator.ts +73 -8
- package/packages/web/.next/standalone/lib/markdownGenerator.ts +58 -13
- package/packages/web/.next/standalone/lib/markdownTableGenerator.ts +31 -28
- package/packages/web/.next/standalone/lib/utils.ts +19 -2
- package/packages/web/.next/standalone/package-lock.json +239 -0
- package/packages/web/.next/standalone/package.json +2 -0
- package/packages/web/.next/standalone/playwright-report/index.html +1 -1
- package/packages/web/.next/static/chunks/9726c2cde77e0916.js +1 -0
- package/packages/web/.next/static/chunks/cd878566fda12635.css +3 -0
- package/packages/web/package.json +2 -0
- package/packages/web/.next/standalone/.next/static/chunks/1747faf69b71cf6d.js +0 -1
- package/packages/web/.next/standalone/.next/static/chunks/4bbca8cd642026de.css +0 -3
- package/packages/web/.next/static/chunks/1747faf69b71cf6d.js +0 -1
- package/packages/web/.next/static/chunks/4bbca8cd642026de.css +0 -3
|
@@ -2,6 +2,7 @@ import { FileSystemService } from './fileSystem';
|
|
|
2
2
|
import { StorageService } from './storage';
|
|
3
3
|
import { escapeHtml } from './utils';
|
|
4
4
|
import { ProjectConfigFiles, ConfigDocs } from '@/types';
|
|
5
|
+
import { sortTagsByOrder } from './configManagerUtils';
|
|
5
6
|
|
|
6
7
|
interface ConfigWithDocs {
|
|
7
8
|
filePath: string;
|
|
@@ -26,6 +27,12 @@ export class HtmlGenerator {
|
|
|
26
27
|
return this.generateEmptyHtml();
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
// フィールドの順序を取得
|
|
31
|
+
const fieldKeys = settings.fields ? Object.keys(settings.fields) : [];
|
|
32
|
+
|
|
33
|
+
// タグの順序を取得
|
|
34
|
+
const availableTags = settings.availableTags || [];
|
|
35
|
+
|
|
29
36
|
// 各設定ファイルとそのドキュメントを読み込む
|
|
30
37
|
const configs: ConfigWithDocs[] = [];
|
|
31
38
|
for (const filePath of settings.configFiles) {
|
|
@@ -59,7 +66,7 @@ export class HtmlGenerator {
|
|
|
59
66
|
configFiles: []
|
|
60
67
|
};
|
|
61
68
|
|
|
62
|
-
return this.generateFullHtml(metadata, configs);
|
|
69
|
+
return this.generateFullHtml(metadata, configs, fieldKeys, availableTags);
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
private generateEmptyHtml(): string {
|
|
@@ -85,8 +92,10 @@ export class HtmlGenerator {
|
|
|
85
92
|
</html>`;
|
|
86
93
|
}
|
|
87
94
|
|
|
88
|
-
private generateFullHtml(metadata: ProjectConfigFiles, configs: ConfigWithDocs[]): string {
|
|
95
|
+
private generateFullHtml(metadata: ProjectConfigFiles, configs: ConfigWithDocs[], fieldKeys: string[], availableTags: string[]): string {
|
|
89
96
|
const configsJson = JSON.stringify(configs, null, 2);
|
|
97
|
+
const fieldKeysJson = JSON.stringify(fieldKeys);
|
|
98
|
+
const availableTagsJson = JSON.stringify(availableTags);
|
|
90
99
|
|
|
91
100
|
return `<!DOCTYPE html>
|
|
92
101
|
<html lang="ja">
|
|
@@ -123,10 +132,25 @@ export class HtmlGenerator {
|
|
|
123
132
|
|
|
124
133
|
<script>
|
|
125
134
|
const configs = ${configsJson};
|
|
135
|
+
const fieldKeys = ${fieldKeysJson};
|
|
136
|
+
const availableTags = ${availableTagsJson};
|
|
126
137
|
let activeConfigIndex = 0;
|
|
127
138
|
let selectedPath = '';
|
|
128
139
|
let currentSearchQuery = '';
|
|
129
140
|
|
|
141
|
+
// タグをavailableTagsの順序でソート
|
|
142
|
+
function sortTagsByOrder(tags) {
|
|
143
|
+
if (!tags || tags.length === 0) return [];
|
|
144
|
+
return [...tags].sort((a, b) => {
|
|
145
|
+
const indexA = availableTags.indexOf(a);
|
|
146
|
+
const indexB = availableTags.indexOf(b);
|
|
147
|
+
if (indexA !== -1 && indexB !== -1) return indexA - indexB;
|
|
148
|
+
if (indexA === -1) return 1;
|
|
149
|
+
if (indexB === -1) return -1;
|
|
150
|
+
return 0;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
130
154
|
${this.getScripts()}
|
|
131
155
|
</script>
|
|
132
156
|
</body>
|
|
@@ -223,13 +247,15 @@ export class HtmlGenerator {
|
|
|
223
247
|
}
|
|
224
248
|
|
|
225
249
|
.config-tab {
|
|
226
|
-
|
|
250
|
+
display: flex;
|
|
251
|
+
flex-direction: column;
|
|
252
|
+
gap: 2px;
|
|
253
|
+
padding: 10px 12px;
|
|
227
254
|
background: #f9fafb;
|
|
228
255
|
border: 1px solid #e5e7eb;
|
|
229
256
|
border-radius: 4px;
|
|
230
257
|
cursor: pointer;
|
|
231
258
|
transition: all 0.2s;
|
|
232
|
-
font-size: 0.9rem;
|
|
233
259
|
}
|
|
234
260
|
|
|
235
261
|
.config-tab:hover {
|
|
@@ -242,10 +268,28 @@ export class HtmlGenerator {
|
|
|
242
268
|
border-color: #2563eb;
|
|
243
269
|
}
|
|
244
270
|
|
|
271
|
+
.config-tab.active .config-tab-path {
|
|
272
|
+
color: rgba(255, 255, 255, 0.8);
|
|
273
|
+
}
|
|
274
|
+
|
|
245
275
|
.config-tab.hidden {
|
|
246
276
|
display: none;
|
|
247
277
|
}
|
|
248
278
|
|
|
279
|
+
.config-tab-filename {
|
|
280
|
+
font-weight: 500;
|
|
281
|
+
font-size: 0.9rem;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.config-tab-path {
|
|
285
|
+
font-size: 0.75rem;
|
|
286
|
+
color: #9ca3af;
|
|
287
|
+
overflow: hidden;
|
|
288
|
+
text-overflow: ellipsis;
|
|
289
|
+
white-space: nowrap;
|
|
290
|
+
max-width: 100%;
|
|
291
|
+
}
|
|
292
|
+
|
|
249
293
|
.tree-container {
|
|
250
294
|
padding: 10px;
|
|
251
295
|
max-height: 600px;
|
|
@@ -363,6 +407,20 @@ export class HtmlGenerator {
|
|
|
363
407
|
border-bottom: 2px solid #e5e7eb;
|
|
364
408
|
}
|
|
365
409
|
|
|
410
|
+
.property-file {
|
|
411
|
+
font-size: 0.85rem;
|
|
412
|
+
color: #6b7280;
|
|
413
|
+
background: #f9fafb;
|
|
414
|
+
padding: 6px 10px;
|
|
415
|
+
border-radius: 4px;
|
|
416
|
+
margin-bottom: 12px;
|
|
417
|
+
font-family: 'Courier New', monospace;
|
|
418
|
+
overflow: hidden;
|
|
419
|
+
text-overflow: ellipsis;
|
|
420
|
+
white-space: nowrap;
|
|
421
|
+
cursor: help;
|
|
422
|
+
}
|
|
423
|
+
|
|
366
424
|
.property-path {
|
|
367
425
|
background: #f3f4f6;
|
|
368
426
|
padding: 10px 15px;
|
|
@@ -585,23 +643,26 @@ export class HtmlGenerator {
|
|
|
585
643
|
const doc = config.docs.properties && config.docs.properties[node.path];
|
|
586
644
|
|
|
587
645
|
let html = \`<h2>\${escapeHtml(node.key)}</h2>\`;
|
|
646
|
+
html += \`<div class="property-file" title="\${escapeHtml(config.filePath)}">ファイル: \${escapeHtml(config.filePath)}</div>\`;
|
|
588
647
|
html += \`<div class="property-path">パス: \${escapeHtml(node.path)}</div>\`;
|
|
589
648
|
html += \`<div class="property-value">値: \${escapeHtml(JSON.stringify(node.value, null, 2))}</div>\`;
|
|
590
649
|
|
|
591
650
|
if (doc) {
|
|
592
651
|
if (doc.tags && doc.tags.length > 0) {
|
|
652
|
+
const sortedTags = sortTagsByOrder(doc.tags);
|
|
593
653
|
html += \`<div class="doc-section">
|
|
594
654
|
<h3>タグ</h3>
|
|
595
655
|
<div class="tag-list">\`;
|
|
596
|
-
|
|
656
|
+
sortedTags.forEach(tag => {
|
|
597
657
|
html += \`<span class="tag">\${escapeHtml(tag)}</span>\`;
|
|
598
658
|
});
|
|
599
659
|
html += \`</div>
|
|
600
660
|
</div>\`;
|
|
601
661
|
}
|
|
602
662
|
|
|
603
|
-
//
|
|
604
|
-
|
|
663
|
+
// フィールドをprojectFieldsの順序で表示
|
|
664
|
+
fieldKeys.forEach(label => {
|
|
665
|
+
const value = doc.fields[label];
|
|
605
666
|
if (value) {
|
|
606
667
|
html += \`<div class="doc-section">
|
|
607
668
|
<h3>\${escapeHtml(label)}</h3>
|
|
@@ -645,7 +706,10 @@ export class HtmlGenerator {
|
|
|
645
706
|
}
|
|
646
707
|
|
|
647
708
|
tab.className = className;
|
|
648
|
-
tab.
|
|
709
|
+
tab.innerHTML = \`
|
|
710
|
+
<div class="config-tab-filename">\${escapeHtml(config.fileName)}</div>
|
|
711
|
+
<div class="config-tab-path" title="\${escapeHtml(config.filePath)}">\${escapeHtml(config.filePath)}</div>
|
|
712
|
+
\`;
|
|
649
713
|
tab.addEventListener('click', () => {
|
|
650
714
|
activeConfigIndex = index;
|
|
651
715
|
renderConfigTabs(matchedConfigIndexes);
|
|
@@ -657,6 +721,7 @@ export class HtmlGenerator {
|
|
|
657
721
|
});
|
|
658
722
|
tabsEl.appendChild(tab);
|
|
659
723
|
});
|
|
724
|
+
|
|
660
725
|
}
|
|
661
726
|
|
|
662
727
|
// 現在の設定を描画
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FileSystemService } from './fileSystem';
|
|
2
2
|
import { StorageService } from './storage';
|
|
3
|
-
import
|
|
3
|
+
import { ConfigParser } from './configParser';
|
|
4
|
+
import { sortTagsByOrder } from './configManagerUtils';
|
|
5
|
+
import { getPropertyByPath } from './utils';
|
|
4
6
|
|
|
5
7
|
export class MarkdownGenerator {
|
|
6
8
|
private rootPath: string;
|
|
@@ -19,6 +21,12 @@ export class MarkdownGenerator {
|
|
|
19
21
|
return '# 設定ファイルドキュメント\n\nドキュメント化された設定ファイルがありません。\n';
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
// フィールドの順序を取得
|
|
25
|
+
const fieldKeys = settings.fields ? Object.keys(settings.fields) : [];
|
|
26
|
+
|
|
27
|
+
// タグの順序を取得
|
|
28
|
+
const availableTags = settings.availableTags || [];
|
|
29
|
+
|
|
22
30
|
let markdown = '# 設定ファイルドキュメント\n\n';
|
|
23
31
|
markdown += `プロジェクト: **${settings.projectName}**\n\n`;
|
|
24
32
|
markdown += `最終更新: ${new Date().toLocaleString('ja-JP')}\n\n`;
|
|
@@ -28,37 +36,74 @@ export class MarkdownGenerator {
|
|
|
28
36
|
for (const filePath of settings.configFiles) {
|
|
29
37
|
const fileName = filePath.split(/[/\\]/).pop() || 'config.json';
|
|
30
38
|
const docs = await storageService.loadAllDocs(filePath);
|
|
39
|
+
const configData = await fsService.loadConfigFile(filePath);
|
|
31
40
|
|
|
32
41
|
markdown += `## ${fileName}\n\n`;
|
|
33
42
|
markdown += `**ファイルパス:** \`${filePath}\`\n\n`;
|
|
34
43
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
// 設定ファイルから全プロパティを取得(オブジェクト型も含む)
|
|
45
|
+
// ツリー構造の順序を保持するためソートしない
|
|
46
|
+
const allPropertyPaths = ConfigParser.getAllPropertyPaths(configData);
|
|
47
|
+
|
|
48
|
+
if (allPropertyPaths.length === 0) {
|
|
49
|
+
markdown += '*プロパティがありません。*\n\n';
|
|
38
50
|
continue;
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
markdown += '### プロパティ一覧\n\n';
|
|
42
54
|
|
|
43
|
-
for (const
|
|
55
|
+
for (const propertyPath of allPropertyPaths) {
|
|
56
|
+
const doc = docs.properties[propertyPath];
|
|
57
|
+
const value = getPropertyByPath(configData, propertyPath);
|
|
58
|
+
|
|
44
59
|
markdown += `#### \`${propertyPath}\`\n\n`;
|
|
45
60
|
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
// 値を表示(プリミティブ値とプリミティブ配列)
|
|
62
|
+
if (value !== undefined && value !== null) {
|
|
63
|
+
const valueType = typeof value;
|
|
64
|
+
const isArray = Array.isArray(value);
|
|
65
|
+
const isObject = valueType === 'object' && !isArray;
|
|
66
|
+
|
|
67
|
+
if (isArray) {
|
|
68
|
+
// 配列の場合:要素がプリミティブならば表示
|
|
69
|
+
const hasPrimitiveElements = value.length > 0 && value.every((item: any) =>
|
|
70
|
+
typeof item !== 'object' || item === null
|
|
71
|
+
);
|
|
72
|
+
if (hasPrimitiveElements) {
|
|
73
|
+
markdown += `**値:** \`${JSON.stringify(value)}\`\n\n`;
|
|
74
|
+
}
|
|
75
|
+
} else if (!isObject) {
|
|
76
|
+
// プリミティブ値を表示
|
|
77
|
+
markdown += `**値:** \`${String(value)}\`\n\n`;
|
|
78
|
+
}
|
|
48
79
|
}
|
|
49
80
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
|
|
81
|
+
// ドキュメントがある場合
|
|
82
|
+
if (doc) {
|
|
83
|
+
if (doc.tags && doc.tags.length > 0) {
|
|
84
|
+
const sortedTags = sortTagsByOrder(doc.tags, availableTags);
|
|
85
|
+
markdown += `**タグ:** ${sortedTags.map(tag => `\`${tag}\``).join(', ')}\n\n`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// フィールドをprojectFieldsの順序で表示
|
|
89
|
+
if (doc.fields) {
|
|
90
|
+
for (const fieldKey of fieldKeys) {
|
|
91
|
+
const fieldValue = doc.fields[fieldKey];
|
|
92
|
+
if (fieldValue) {
|
|
93
|
+
markdown += `**${fieldKey}:**\n\n${fieldValue}\n\n`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
54
96
|
}
|
|
55
|
-
}
|
|
97
|
+
} else {
|
|
98
|
+
// ドキュメントがない場合
|
|
99
|
+
markdown += '*ドキュメントなし*\n\n';
|
|
100
|
+
}
|
|
56
101
|
|
|
57
102
|
markdown += '---\n\n';
|
|
58
103
|
}
|
|
59
104
|
}
|
|
60
105
|
|
|
61
|
-
markdown += `\n*このドキュメントは
|
|
106
|
+
markdown += `\n*このドキュメントは ConfigDoc により自動生成されました。*\n`;
|
|
62
107
|
|
|
63
108
|
return markdown;
|
|
64
109
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FileSystemService } from './fileSystem';
|
|
2
2
|
import { StorageService } from './storage';
|
|
3
3
|
import { escapeTableCell, getPropertyByPath, formatValue } from './utils';
|
|
4
|
+
import { ConfigParser } from './configParser';
|
|
5
|
+
import { sortTagsByOrder } from './configManagerUtils';
|
|
4
6
|
|
|
5
7
|
export class MarkdownTableGenerator {
|
|
6
8
|
private rootPath: string;
|
|
@@ -19,6 +21,12 @@ export class MarkdownTableGenerator {
|
|
|
19
21
|
return '# 設定ファイルドキュメント\n\nドキュメント化された設定ファイルがありません。\n';
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
// フィールドの順序を取得(すべてのフィールドをテーブルの列として使用)
|
|
25
|
+
const fieldKeys = settings.fields ? Object.keys(settings.fields) : [];
|
|
26
|
+
|
|
27
|
+
// タグの順序を取得
|
|
28
|
+
const availableTags = settings.availableTags || [];
|
|
29
|
+
|
|
22
30
|
let markdown = '# 設定ファイルドキュメント\n\n';
|
|
23
31
|
markdown += `プロジェクト: **${settings.projectName}**\n\n`;
|
|
24
32
|
markdown += `最終更新: ${new Date().toLocaleString('ja-JP')}\n\n`;
|
|
@@ -33,52 +41,47 @@ export class MarkdownTableGenerator {
|
|
|
33
41
|
markdown += `## ${fileName}\n\n`;
|
|
34
42
|
markdown += `**ファイルパス:** \`${filePath}\`\n\n`;
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
// 設定ファイルから全プロパティを取得(オブジェクト型も含む)
|
|
45
|
+
// ツリー構造の順序を保持するためソートしない
|
|
46
|
+
const allPropertyPaths = ConfigParser.getAllPropertyPaths(configData);
|
|
47
|
+
|
|
48
|
+
if (allPropertyPaths.length === 0) {
|
|
49
|
+
markdown += '*プロパティがありません。*\n\n';
|
|
39
50
|
continue;
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Object.keys(doc.fields).forEach(label => {
|
|
46
|
-
if (label !== '説明') {
|
|
47
|
-
fieldLabels.add(label);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
const sortedLabels = Array.from(fieldLabels).sort();
|
|
52
|
-
|
|
53
|
-
// テーブルヘッダー
|
|
54
|
-
markdown += '| プロパティ名 | タグ | 説明 | 値 |';
|
|
55
|
-
sortedLabels.forEach(label => {
|
|
53
|
+
// テーブルヘッダー(projectFieldsの順序で表示)
|
|
54
|
+
markdown += '| プロパティ名 | タグ | 値 |';
|
|
55
|
+
fieldKeys.forEach(label => {
|
|
56
56
|
markdown += ` ${label} |`;
|
|
57
57
|
});
|
|
58
58
|
markdown += '\n';
|
|
59
59
|
|
|
60
|
-
markdown += '
|
|
61
|
-
|
|
60
|
+
markdown += '|-------------|------|-----|';
|
|
61
|
+
fieldKeys.forEach(() => {
|
|
62
62
|
markdown += '------|';
|
|
63
63
|
});
|
|
64
64
|
markdown += '\n';
|
|
65
65
|
|
|
66
66
|
// 各プロパティの行を追加
|
|
67
|
-
for (const
|
|
67
|
+
for (const propertyPath of allPropertyPaths) {
|
|
68
|
+
const doc = docs.properties[propertyPath];
|
|
68
69
|
const propertyName = escapeTableCell(propertyPath);
|
|
69
|
-
const
|
|
70
|
-
?
|
|
70
|
+
const sortedTags = doc && doc.tags && doc.tags.length > 0
|
|
71
|
+
? sortTagsByOrder(doc.tags, availableTags)
|
|
72
|
+
: [];
|
|
73
|
+
const tags = sortedTags.length > 0
|
|
74
|
+
? escapeTableCell(sortedTags.map(tag => `\`${tag}\``).join(', '))
|
|
71
75
|
: '-';
|
|
72
76
|
|
|
73
|
-
const description = escapeTableCell(doc.fields['説明'] || '-');
|
|
74
77
|
const value = this.getPropertyValue(configData, propertyPath);
|
|
75
78
|
const valueStr = escapeTableCell(value);
|
|
76
79
|
|
|
77
|
-
markdown += `| ${propertyName} | ${tags} | ${
|
|
80
|
+
markdown += `| ${propertyName} | ${tags} | ${valueStr} |`;
|
|
78
81
|
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
const fieldValue = doc.fields[label] || '-';
|
|
82
|
+
// フィールドの値をprojectFieldsの順序で追加
|
|
83
|
+
fieldKeys.forEach(label => {
|
|
84
|
+
const fieldValue = (doc && doc.fields && doc.fields[label]) || '-';
|
|
82
85
|
markdown += ` ${escapeTableCell(fieldValue)} |`;
|
|
83
86
|
});
|
|
84
87
|
|
|
@@ -88,7 +91,7 @@ export class MarkdownTableGenerator {
|
|
|
88
91
|
markdown += '\n';
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
markdown += `\n*このドキュメントは
|
|
94
|
+
markdown += `\n*このドキュメントは ConfigDoc により自動生成されました。*\n`;
|
|
92
95
|
|
|
93
96
|
return markdown;
|
|
94
97
|
}
|
|
@@ -58,15 +58,32 @@ export function getPropertyByPath(obj: unknown, propertyPath: string): unknown {
|
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* 値を表示用の文字列に変換
|
|
61
|
+
* プリミティブ値とプリミティブ配列のみ表示し、オブジェクトとオブジェクト配列は'-'を返す
|
|
61
62
|
*/
|
|
62
63
|
export function formatValue(value: unknown): string {
|
|
63
64
|
if (value === null || value === undefined) {
|
|
64
65
|
return '-';
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
const valueType = typeof value;
|
|
69
|
+
const isArray = Array.isArray(value);
|
|
70
|
+
const isObject = valueType === 'object' && !isArray;
|
|
71
|
+
|
|
72
|
+
if (isArray) {
|
|
73
|
+
// 配列の場合:要素がプリミティブならば表示
|
|
74
|
+
const hasPrimitiveElements = value.length > 0 && value.every((item: any) =>
|
|
75
|
+
typeof item !== 'object' || item === null
|
|
76
|
+
);
|
|
77
|
+
if (hasPrimitiveElements) {
|
|
78
|
+
return JSON.stringify(value);
|
|
79
|
+
}
|
|
80
|
+
// オブジェクト配列の場合は表示しない
|
|
81
|
+
return '-';
|
|
82
|
+
} else if (isObject) {
|
|
83
|
+
// オブジェクトの場合は表示しない
|
|
84
|
+
return '-';
|
|
69
85
|
}
|
|
70
86
|
|
|
87
|
+
// プリミティブ値を表示
|
|
71
88
|
return String(value);
|
|
72
89
|
}
|