@skspwork/config-doc 0.2.0 → 0.4.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/package.json +2 -2
- package/packages/web/app/api/config/metadata/route.ts +54 -33
- package/packages/web/app/api/export/settings/route.ts +29 -25
- package/packages/web/lib/fileSystem.ts +32 -1
- package/packages/web/lib/htmlGenerator.ts +24 -10
- package/packages/web/lib/markdownGenerator.ts +10 -9
- package/packages/web/lib/markdownTableGenerator.ts +11 -10
- package/packages/web/lib/storage.ts +38 -16
- package/packages/web/types/index.ts +10 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skspwork/config-doc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Interactive documentation tool for JSON configuration files (appsettings.json)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"config",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"packages/cli/bin",
|
|
32
32
|
"packages/cli/package.json",
|
|
33
33
|
"packages/web/app",
|
|
34
|
-
"packages/web/components",
|
|
34
|
+
"packages/web/components",
|
|
35
35
|
"packages/web/lib",
|
|
36
36
|
"packages/web/types",
|
|
37
37
|
"packages/web/public",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { FileSystemService } from '@/lib/fileSystem';
|
|
4
|
+
import { StorageService } from '@/lib/storage';
|
|
4
5
|
import { ProjectConfigFiles } from '@/types';
|
|
5
6
|
import { getRootPath } from '@/lib/getRootPath';
|
|
6
7
|
|
|
@@ -8,8 +9,32 @@ export async function GET() {
|
|
|
8
9
|
try {
|
|
9
10
|
const rootPath = getRootPath();
|
|
10
11
|
const fsService = new FileSystemService(rootPath);
|
|
12
|
+
const storageService = new StorageService(fsService);
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
// project_settings.jsonを読み込み
|
|
15
|
+
const settings = await fsService.loadProjectSettings();
|
|
16
|
+
|
|
17
|
+
if (!settings) {
|
|
18
|
+
return NextResponse.json({
|
|
19
|
+
success: true,
|
|
20
|
+
data: null
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// UI用にConfigFileInfo形式に変換(互換性のため)
|
|
25
|
+
const configFiles = settings.configFiles.map((filePath, index) => ({
|
|
26
|
+
id: `config-${index + 1}`,
|
|
27
|
+
fileName: filePath.split(/[/\\]/).pop() || 'config.json',
|
|
28
|
+
filePath,
|
|
29
|
+
docsFileName: storageService.getDocsFileName(filePath)
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const metadata: ProjectConfigFiles = {
|
|
33
|
+
projectName: settings.projectName,
|
|
34
|
+
createdAt: '', // 不要になったが互換性のため
|
|
35
|
+
lastModified: new Date().toISOString(),
|
|
36
|
+
configFiles
|
|
37
|
+
};
|
|
13
38
|
|
|
14
39
|
return NextResponse.json({
|
|
15
40
|
success: true,
|
|
@@ -41,50 +66,46 @@ export async function POST(request: NextRequest) {
|
|
|
41
66
|
|
|
42
67
|
const rootPath = getRootPath();
|
|
43
68
|
const fsService = new FileSystemService(rootPath);
|
|
69
|
+
const storageService = new StorageService(fsService);
|
|
44
70
|
|
|
45
|
-
//
|
|
46
|
-
const
|
|
71
|
+
// 既存の設定を読み込み
|
|
72
|
+
const existingSettings = await fsService.loadProjectSettings();
|
|
47
73
|
|
|
48
|
-
//
|
|
74
|
+
// 削除されたファイルのdocsを削除
|
|
49
75
|
const deletedDocsFileNames: string[] = [];
|
|
50
|
-
if (
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
76
|
+
if (existingSettings && existingSettings.configFiles) {
|
|
77
|
+
const newPaths = new Set(
|
|
78
|
+
configFilePaths.map((p: string) =>
|
|
79
|
+
path.isAbsolute(p) ? path.relative(rootPath, p) : p
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
for (const oldPath of existingSettings.configFiles) {
|
|
84
|
+
if (!newPaths.has(oldPath)) {
|
|
85
|
+
const docsFileName = storageService.getDocsFileName(oldPath);
|
|
86
|
+
deletedDocsFileNames.push(docsFileName);
|
|
87
|
+
await fsService.deleteConfigDocs(docsFileName);
|
|
57
88
|
}
|
|
58
89
|
}
|
|
59
90
|
}
|
|
60
91
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
? path.relative(rootPath, filePath)
|
|
72
|
-
: filePath;
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
id: `config-${index + 1}`,
|
|
76
|
-
fileName,
|
|
77
|
-
filePath: relativePath,
|
|
78
|
-
docsFileName
|
|
79
|
-
};
|
|
80
|
-
})
|
|
92
|
+
// 絶対パスを相対パスに変換
|
|
93
|
+
const relativePaths = configFilePaths.map((p: string) =>
|
|
94
|
+
path.isAbsolute(p) ? path.relative(rootPath, p) : p
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// 新しい設定を保存
|
|
98
|
+
const newSettings = {
|
|
99
|
+
projectName: existingSettings?.projectName || path.basename(rootPath),
|
|
100
|
+
configFiles: relativePaths,
|
|
101
|
+
export: existingSettings?.export || {}
|
|
81
102
|
};
|
|
82
103
|
|
|
83
|
-
await fsService.
|
|
104
|
+
await fsService.saveProjectSettings(newSettings);
|
|
84
105
|
|
|
85
106
|
return NextResponse.json({
|
|
86
107
|
success: true,
|
|
87
|
-
message: '
|
|
108
|
+
message: 'プロジェクト設定を保存しました',
|
|
88
109
|
deletedDocsFiles: deletedDocsFileNames
|
|
89
110
|
});
|
|
90
111
|
} catch (error) {
|
|
@@ -3,17 +3,17 @@ import { getRootPath } from '@/lib/getRootPath';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs/promises';
|
|
5
5
|
import { ExportSettings, UserSettings, ProjectSettings } from '@/types';
|
|
6
|
+
import { FileSystemService } from '@/lib/fileSystem';
|
|
6
7
|
|
|
7
|
-
const USER_SETTINGS_FILE = '.
|
|
8
|
-
const PROJECT_SETTINGS_FILE = 'settings.json';
|
|
8
|
+
const USER_SETTINGS_FILE = '.user_settings.json';
|
|
9
9
|
const CONFIG_DOC_DIR = '.config_doc';
|
|
10
10
|
|
|
11
11
|
// GET: エクスポート設定を読み込み
|
|
12
12
|
export async function GET() {
|
|
13
13
|
try {
|
|
14
14
|
const rootPath = getRootPath();
|
|
15
|
+
const fsService = new FileSystemService(rootPath);
|
|
15
16
|
const userSettingsPath = path.join(rootPath, CONFIG_DOC_DIR, USER_SETTINGS_FILE);
|
|
16
|
-
const projectSettingsPath = path.join(rootPath, CONFIG_DOC_DIR, PROJECT_SETTINGS_FILE);
|
|
17
17
|
|
|
18
18
|
// ユーザ設定を読み込み
|
|
19
19
|
let userSettings: UserSettings;
|
|
@@ -28,22 +28,14 @@ export async function GET() {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const content = await fs.readFile(projectSettingsPath, 'utf-8');
|
|
35
|
-
projectSettings = JSON.parse(content);
|
|
36
|
-
} catch {
|
|
37
|
-
// デフォルトのプロジェクト設定
|
|
38
|
-
projectSettings = {
|
|
39
|
-
fileName: 'config-doc'
|
|
40
|
-
};
|
|
41
|
-
}
|
|
31
|
+
// プロジェクト設定から export.fileName を取得
|
|
32
|
+
const projectSettings = await fsService.loadProjectSettings();
|
|
33
|
+
const fileName = projectSettings?.export?.fileName || 'config-doc';
|
|
42
34
|
|
|
43
35
|
// 統合された設定を返す
|
|
44
36
|
const settings: ExportSettings = {
|
|
45
37
|
...userSettings,
|
|
46
|
-
|
|
38
|
+
fileName
|
|
47
39
|
};
|
|
48
40
|
|
|
49
41
|
return NextResponse.json({
|
|
@@ -76,6 +68,7 @@ export async function POST(request: NextRequest) {
|
|
|
76
68
|
}
|
|
77
69
|
|
|
78
70
|
const rootPath = getRootPath();
|
|
71
|
+
const fsService = new FileSystemService(rootPath);
|
|
79
72
|
const configDocDir = path.join(rootPath, CONFIG_DOC_DIR);
|
|
80
73
|
|
|
81
74
|
// .config_doc ディレクトリを確保
|
|
@@ -94,17 +87,28 @@ export async function POST(request: NextRequest) {
|
|
|
94
87
|
'utf-8'
|
|
95
88
|
);
|
|
96
89
|
|
|
97
|
-
//
|
|
90
|
+
// プロジェクト設定の export.fileName を更新
|
|
98
91
|
if (settings.fileName !== undefined) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
const existingProjectSettings = await fsService.loadProjectSettings();
|
|
93
|
+
|
|
94
|
+
if (existingProjectSettings) {
|
|
95
|
+
// 既存の設定を更新
|
|
96
|
+
existingProjectSettings.export = {
|
|
97
|
+
...existingProjectSettings.export,
|
|
98
|
+
fileName: settings.fileName
|
|
99
|
+
};
|
|
100
|
+
await fsService.saveProjectSettings(existingProjectSettings);
|
|
101
|
+
} else {
|
|
102
|
+
// 新規作成
|
|
103
|
+
const newProjectSettings: ProjectSettings = {
|
|
104
|
+
projectName: path.basename(rootPath),
|
|
105
|
+
configFiles: [],
|
|
106
|
+
export: {
|
|
107
|
+
fileName: settings.fileName
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
await fsService.saveProjectSettings(newProjectSettings);
|
|
111
|
+
}
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
return NextResponse.json({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { ProjectConfigFiles, ConfigDocs, FileSystemItem } from '@/types';
|
|
3
|
+
import { ProjectConfigFiles, ConfigDocs, FileSystemItem, ProjectSettings } from '@/types';
|
|
4
4
|
|
|
5
5
|
export class FileSystemService {
|
|
6
6
|
private configDocDir = '.config_doc';
|
|
@@ -25,6 +25,37 @@ export class FileSystemService {
|
|
|
25
25
|
await fs.mkdir(docsDir, { recursive: true });
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// 新しいプロジェクト設定の読み込み
|
|
29
|
+
async loadProjectSettings(): Promise<ProjectSettings | null> {
|
|
30
|
+
const settingsPath = path.join(
|
|
31
|
+
this.rootPath,
|
|
32
|
+
this.configDocDir,
|
|
33
|
+
'project_settings.json'
|
|
34
|
+
);
|
|
35
|
+
try {
|
|
36
|
+
const content = await fs.readFile(settingsPath, 'utf-8');
|
|
37
|
+
return JSON.parse(content);
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 新しいプロジェクト設定の保存
|
|
44
|
+
async saveProjectSettings(settings: ProjectSettings): Promise<void> {
|
|
45
|
+
await this.ensureConfigDocDir();
|
|
46
|
+
const settingsPath = path.join(
|
|
47
|
+
this.rootPath,
|
|
48
|
+
this.configDocDir,
|
|
49
|
+
'project_settings.json'
|
|
50
|
+
);
|
|
51
|
+
await fs.writeFile(
|
|
52
|
+
settingsPath,
|
|
53
|
+
JSON.stringify(settings, null, 2),
|
|
54
|
+
'utf-8'
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 旧形式のconfig_files.jsonの読み込み(マイグレーション用)
|
|
28
59
|
async loadConfigFiles(): Promise<ProjectConfigFiles | null> {
|
|
29
60
|
const configFilesPath = path.join(
|
|
30
61
|
this.rootPath,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FileSystemService } from './fileSystem';
|
|
2
|
+
import { StorageService } from './storage';
|
|
2
3
|
import { ProjectConfigFiles, ConfigDocs } from '@/types';
|
|
3
4
|
|
|
4
5
|
interface ConfigWithDocs {
|
|
@@ -10,40 +11,53 @@ interface ConfigWithDocs {
|
|
|
10
11
|
|
|
11
12
|
export class HtmlGenerator {
|
|
12
13
|
private fsService: FileSystemService;
|
|
14
|
+
private storageService: StorageService;
|
|
13
15
|
|
|
14
16
|
constructor(rootPath: string) {
|
|
15
17
|
this.fsService = new FileSystemService(rootPath);
|
|
18
|
+
this.storageService = new StorageService(this.fsService);
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
async generateHtml(): Promise<string> {
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
22
|
+
// プロジェクト設定を読み込む
|
|
23
|
+
const settings = await this.fsService.loadProjectSettings();
|
|
24
|
+
if (!settings || !settings.configFiles || settings.configFiles.length === 0) {
|
|
22
25
|
return this.generateEmptyHtml();
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
// 各設定ファイルとそのドキュメントを読み込む
|
|
26
29
|
const configs: ConfigWithDocs[] = [];
|
|
27
|
-
for (const
|
|
30
|
+
for (const filePath of settings.configFiles) {
|
|
28
31
|
try {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
32
|
+
const fileName = filePath.split(/[/\\]/).pop() || 'config.json';
|
|
33
|
+
const docsFileName = this.storageService.getDocsFileName(filePath);
|
|
34
|
+
|
|
35
|
+
const configData = await this.fsService.loadConfigFile(filePath);
|
|
36
|
+
const docs = await this.fsService.loadConfigDocs(docsFileName);
|
|
31
37
|
|
|
32
38
|
configs.push({
|
|
33
|
-
filePath
|
|
34
|
-
fileName
|
|
39
|
+
filePath,
|
|
40
|
+
fileName,
|
|
35
41
|
configData,
|
|
36
42
|
docs: docs || {
|
|
37
|
-
configFilePath:
|
|
43
|
+
configFilePath: filePath,
|
|
38
44
|
lastModified: new Date().toISOString(),
|
|
39
45
|
properties: {}
|
|
40
46
|
}
|
|
41
47
|
});
|
|
42
48
|
} catch (error) {
|
|
43
|
-
console.error(`Failed to load config: ${
|
|
49
|
+
console.error(`Failed to load config: ${filePath}`, error);
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
// 互換性のため ProjectConfigFiles 形式に変換
|
|
54
|
+
const metadata: ProjectConfigFiles = {
|
|
55
|
+
projectName: settings.projectName,
|
|
56
|
+
createdAt: '',
|
|
57
|
+
lastModified: new Date().toISOString(),
|
|
58
|
+
configFiles: []
|
|
59
|
+
};
|
|
60
|
+
|
|
47
61
|
return this.generateFullHtml(metadata, configs);
|
|
48
62
|
}
|
|
49
63
|
|
|
@@ -13,23 +13,24 @@ export class MarkdownGenerator {
|
|
|
13
13
|
const fsService = new FileSystemService(this.rootPath);
|
|
14
14
|
const storageService = new StorageService(fsService);
|
|
15
15
|
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
if (!
|
|
16
|
+
// プロジェクト設定を読み込む
|
|
17
|
+
const settings = await fsService.loadProjectSettings();
|
|
18
|
+
if (!settings || settings.configFiles.length === 0) {
|
|
19
19
|
return '# 設定ファイルドキュメント\n\nドキュメント化された設定ファイルがありません。\n';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
let markdown = '# 設定ファイルドキュメント\n\n';
|
|
23
|
-
markdown += `プロジェクト: **${
|
|
24
|
-
markdown += `最終更新: ${new Date(
|
|
23
|
+
markdown += `プロジェクト: **${settings.projectName}**\n\n`;
|
|
24
|
+
markdown += `最終更新: ${new Date().toLocaleString('ja-JP')}\n\n`;
|
|
25
25
|
markdown += '---\n\n';
|
|
26
26
|
|
|
27
27
|
// 各設定ファイルのドキュメントを生成
|
|
28
|
-
for (const
|
|
29
|
-
const
|
|
28
|
+
for (const filePath of settings.configFiles) {
|
|
29
|
+
const fileName = filePath.split(/[/\\]/).pop() || 'config.json';
|
|
30
|
+
const docs = await storageService.loadAllDocs(filePath);
|
|
30
31
|
|
|
31
|
-
markdown += `## ${
|
|
32
|
-
markdown += `**ファイルパス:** \`${
|
|
32
|
+
markdown += `## ${fileName}\n\n`;
|
|
33
|
+
markdown += `**ファイルパス:** \`${filePath}\`\n\n`;
|
|
33
34
|
|
|
34
35
|
const propertyEntries = Object.entries(docs.properties);
|
|
35
36
|
if (propertyEntries.length === 0) {
|
|
@@ -13,24 +13,25 @@ export class MarkdownTableGenerator {
|
|
|
13
13
|
const fsService = new FileSystemService(this.rootPath);
|
|
14
14
|
const storageService = new StorageService(fsService);
|
|
15
15
|
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
if (!
|
|
16
|
+
// プロジェクト設定を読み込む
|
|
17
|
+
const settings = await fsService.loadProjectSettings();
|
|
18
|
+
if (!settings || settings.configFiles.length === 0) {
|
|
19
19
|
return '# 設定ファイルドキュメント\n\nドキュメント化された設定ファイルがありません。\n';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
let markdown = '# 設定ファイルドキュメント\n\n';
|
|
23
|
-
markdown += `プロジェクト: **${
|
|
24
|
-
markdown += `最終更新: ${new Date(
|
|
23
|
+
markdown += `プロジェクト: **${settings.projectName}**\n\n`;
|
|
24
|
+
markdown += `最終更新: ${new Date().toLocaleString('ja-JP')}\n\n`;
|
|
25
25
|
markdown += '---\n\n';
|
|
26
26
|
|
|
27
27
|
// 各設定ファイルのドキュメントを生成
|
|
28
|
-
for (const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
28
|
+
for (const filePath of settings.configFiles) {
|
|
29
|
+
const fileName = filePath.split(/[/\\]/).pop() || 'config.json';
|
|
30
|
+
const docs = await storageService.loadAllDocs(filePath);
|
|
31
|
+
const configData = await fsService.loadConfigFile(filePath);
|
|
31
32
|
|
|
32
|
-
markdown += `## ${
|
|
33
|
-
markdown += `**ファイルパス:** \`${
|
|
33
|
+
markdown += `## ${fileName}\n\n`;
|
|
34
|
+
markdown += `**ファイルパス:** \`${filePath}\`\n\n`;
|
|
34
35
|
|
|
35
36
|
const propertyEntries = Object.entries(docs.properties);
|
|
36
37
|
if (propertyEntries.length === 0) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FileSystemService } from './fileSystem';
|
|
2
2
|
import { ConfigDocs, PropertyDoc } from '@/types';
|
|
3
|
+
import path from 'path';
|
|
3
4
|
|
|
4
5
|
export class StorageService {
|
|
5
6
|
constructor(private fs: FileSystemService) {}
|
|
@@ -11,10 +12,13 @@ export class StorageService {
|
|
|
11
12
|
): Promise<void> {
|
|
12
13
|
const docsFileName = this.getDocsFileName(configFilePath);
|
|
13
14
|
|
|
15
|
+
// 絶対パスを相対パスに変換
|
|
16
|
+
const relativeConfigPath = this.toRelativePath(configFilePath);
|
|
17
|
+
|
|
14
18
|
let docs = await this.fs.loadConfigDocs(docsFileName);
|
|
15
19
|
if (!docs) {
|
|
16
20
|
docs = {
|
|
17
|
-
configFilePath,
|
|
21
|
+
configFilePath: relativeConfigPath,
|
|
18
22
|
lastModified: new Date().toISOString(),
|
|
19
23
|
properties: {}
|
|
20
24
|
};
|
|
@@ -22,6 +26,7 @@ export class StorageService {
|
|
|
22
26
|
|
|
23
27
|
docs.properties[propertyPath] = propertyDoc;
|
|
24
28
|
docs.lastModified = new Date().toISOString();
|
|
29
|
+
docs.configFilePath = relativeConfigPath; // 常に相対パスを保存
|
|
25
30
|
|
|
26
31
|
await this.fs.saveConfigDocs(docsFileName, docs);
|
|
27
32
|
}
|
|
@@ -30,28 +35,45 @@ export class StorageService {
|
|
|
30
35
|
const docsFileName = this.getDocsFileName(configFilePath);
|
|
31
36
|
const docs = await this.fs.loadConfigDocs(docsFileName);
|
|
32
37
|
|
|
38
|
+
// 絶対パスを相対パスに変換
|
|
39
|
+
const relativeConfigPath = this.toRelativePath(configFilePath);
|
|
40
|
+
|
|
33
41
|
return docs || {
|
|
34
|
-
configFilePath,
|
|
42
|
+
configFilePath: relativeConfigPath,
|
|
35
43
|
lastModified: new Date().toISOString(),
|
|
36
44
|
properties: {}
|
|
37
45
|
};
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
} else {
|
|
52
|
-
// 相対パスの場合:従来通り
|
|
53
|
-
const fileName = configFilePath.split(/[/\\]/).pop() || 'config.json';
|
|
48
|
+
// 公開メソッド: docsファイル名を取得
|
|
49
|
+
public getDocsFileName(configFilePath: string): string {
|
|
50
|
+
// 相対パスに変換してから処理
|
|
51
|
+
const relativePath = this.toRelativePath(configFilePath);
|
|
52
|
+
|
|
53
|
+
// パスの深さが1以下(ルート直下のファイル)の場合は、シンプルなファイル名
|
|
54
|
+
const pathParts = relativePath.split(/[/\\]/).filter(p => p && p !== '.');
|
|
55
|
+
|
|
56
|
+
if (pathParts.length <= 1) {
|
|
57
|
+
// ルート直下のファイル: components.json → components.docs.json
|
|
58
|
+
const fileName = pathParts[0] || 'config.json';
|
|
54
59
|
return fileName.replace('.json', '.docs.json');
|
|
60
|
+
} else {
|
|
61
|
+
// サブディレクトリのファイル: 相対パスを含めて一意にする
|
|
62
|
+
// 例: ../SimMoney/components.json → __SimMoney_components.docs.json
|
|
63
|
+
// 例: sample/appsettings.json → sample_appsettings.docs.json
|
|
64
|
+
const normalized = relativePath
|
|
65
|
+
.replace(/\.\./g, '__') // .. を __ に変換
|
|
66
|
+
.replace(/[/\\]/g, '_') // / と \ を _ に変換
|
|
67
|
+
.replace(/:/g, ''); // : を削除
|
|
68
|
+
return normalized.replace('.json', '.docs.json');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private toRelativePath(filePath: string): string {
|
|
73
|
+
// 絶対パスの場合は相対パスに変換
|
|
74
|
+
if (path.isAbsolute(filePath)) {
|
|
75
|
+
return path.relative(this.fs['rootPath'], filePath);
|
|
55
76
|
}
|
|
77
|
+
return filePath;
|
|
56
78
|
}
|
|
57
79
|
}
|
|
@@ -45,12 +45,16 @@ export interface FileSystemItem {
|
|
|
45
45
|
|
|
46
46
|
export type ExportFormat = 'html' | 'markdown' | 'markdown-table';
|
|
47
47
|
|
|
48
|
-
//
|
|
48
|
+
// プロジェクト設定(project_settings.json)- チーム共有
|
|
49
49
|
export interface ProjectSettings {
|
|
50
|
-
|
|
50
|
+
projectName: string;
|
|
51
|
+
configFiles: string[]; // 設定ファイルの相対パス配列
|
|
52
|
+
export?: {
|
|
53
|
+
fileName?: string; // 出力ファイル名(拡張子なし、デフォルト: config-doc)
|
|
54
|
+
};
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
// ユーザ個別設定(.
|
|
57
|
+
// ユーザ個別設定(.user_settings.json)
|
|
54
58
|
export interface UserSettings {
|
|
55
59
|
format: ExportFormat; // 出力形式
|
|
56
60
|
autoExport: boolean; // 保存時に自動エクスポート
|
|
@@ -58,4 +62,6 @@ export interface UserSettings {
|
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
// 統合された設定(レスポンス用)
|
|
61
|
-
export interface ExportSettings extends UserSettings
|
|
65
|
+
export interface ExportSettings extends UserSettings {
|
|
66
|
+
fileName?: string; // ProjectSettings.export.fileName から取得
|
|
67
|
+
}
|