@dayinxisheng/novel-tools 0.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +80 -0
  3. package/dist/commands/check.d.ts +6 -0
  4. package/dist/commands/check.d.ts.map +1 -0
  5. package/dist/commands/check.js +105 -0
  6. package/dist/commands/check.js.map +1 -0
  7. package/dist/commands/index.d.ts +4 -0
  8. package/dist/commands/index.d.ts.map +1 -0
  9. package/dist/commands/index.js +31 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/commands/init.d.ts +6 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +52 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/query.d.ts +6 -0
  16. package/dist/commands/query.d.ts.map +1 -0
  17. package/dist/commands/query.js +169 -0
  18. package/dist/commands/query.js.map +1 -0
  19. package/dist/commands/shared.d.ts +51 -0
  20. package/dist/commands/shared.d.ts.map +1 -0
  21. package/dist/commands/shared.js +110 -0
  22. package/dist/commands/shared.js.map +1 -0
  23. package/dist/commands/snapshot.d.ts +6 -0
  24. package/dist/commands/snapshot.d.ts.map +1 -0
  25. package/dist/commands/snapshot.js +140 -0
  26. package/dist/commands/snapshot.js.map +1 -0
  27. package/dist/core/constants.d.ts +38 -0
  28. package/dist/core/constants.d.ts.map +1 -0
  29. package/dist/core/constants.js +88 -0
  30. package/dist/core/constants.js.map +1 -0
  31. package/dist/core/file.d.ts +55 -0
  32. package/dist/core/file.d.ts.map +1 -0
  33. package/dist/core/file.js +136 -0
  34. package/dist/core/file.js.map +1 -0
  35. package/dist/core/index.d.ts +5 -0
  36. package/dist/core/index.d.ts.map +1 -0
  37. package/dist/core/index.js +8 -0
  38. package/dist/core/index.js.map +1 -0
  39. package/dist/core/types.d.ts +145 -0
  40. package/dist/core/types.d.ts.map +1 -0
  41. package/dist/core/types.js +2 -0
  42. package/dist/core/types.js.map +1 -0
  43. package/dist/core/yaml.d.ts +43 -0
  44. package/dist/core/yaml.d.ts.map +1 -0
  45. package/dist/core/yaml.js +90 -0
  46. package/dist/core/yaml.js.map +1 -0
  47. package/dist/services/event.service.d.ts +35 -0
  48. package/dist/services/event.service.d.ts.map +1 -0
  49. package/dist/services/event.service.js +177 -0
  50. package/dist/services/event.service.js.map +1 -0
  51. package/dist/services/index.d.ts +6 -0
  52. package/dist/services/index.d.ts.map +1 -0
  53. package/dist/services/index.js +7 -0
  54. package/dist/services/index.js.map +1 -0
  55. package/dist/services/init.service.d.ts +51 -0
  56. package/dist/services/init.service.d.ts.map +1 -0
  57. package/dist/services/init.service.js +250 -0
  58. package/dist/services/init.service.js.map +1 -0
  59. package/dist/services/query.service.d.ts +43 -0
  60. package/dist/services/query.service.d.ts.map +1 -0
  61. package/dist/services/query.service.js +129 -0
  62. package/dist/services/query.service.js.map +1 -0
  63. package/dist/services/snapshot.service.d.ts +42 -0
  64. package/dist/services/snapshot.service.d.ts.map +1 -0
  65. package/dist/services/snapshot.service.js +234 -0
  66. package/dist/services/snapshot.service.js.map +1 -0
  67. package/dist/services/validate.service.d.ts +43 -0
  68. package/dist/services/validate.service.d.ts.map +1 -0
  69. package/dist/services/validate.service.js +278 -0
  70. package/dist/services/validate.service.js.map +1 -0
  71. package/dist/utils/index.d.ts +3 -0
  72. package/dist/utils/index.d.ts.map +1 -0
  73. package/dist/utils/index.js +4 -0
  74. package/dist/utils/index.js.map +1 -0
  75. package/dist/utils/output.d.ts +30 -0
  76. package/dist/utils/output.d.ts.map +1 -0
  77. package/dist/utils/output.js +112 -0
  78. package/dist/utils/output.js.map +1 -0
  79. package/dist/utils/validation.d.ts +59 -0
  80. package/dist/utils/validation.d.ts.map +1 -0
  81. package/dist/utils/validation.js +120 -0
  82. package/dist/utils/validation.js.map +1 -0
  83. package/package.json +62 -0
@@ -0,0 +1,112 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * 输出格式化工具
4
+ */
5
+ export class OutputFormatter {
6
+ /**
7
+ * 格式化表格
8
+ */
9
+ static formatTable(headers, rows) {
10
+ const columnWidths = headers.map((header, i) => {
11
+ const maxWidth = Math.max(header.length, ...rows.map(row => (row[i] || '').length));
12
+ return maxWidth + 2;
13
+ });
14
+ let output = '';
15
+ // 表头
16
+ output += chalk.bold(headers.map((header, i) => header.padEnd(columnWidths[i])).join(''));
17
+ output += '\n';
18
+ // 分隔线
19
+ output += chalk.gray(columnWidths.map(width => '─'.repeat(width - 1) + ' ').join(''));
20
+ output += '\n';
21
+ // 数据行
22
+ for (const row of rows) {
23
+ output += row
24
+ .map((cell, i) => (cell || '').padEnd(columnWidths[i]))
25
+ .join('');
26
+ output += '\n';
27
+ }
28
+ return output;
29
+ }
30
+ /**
31
+ * 格式化 YAML 输出
32
+ */
33
+ static formatYaml(obj, indent = 0) {
34
+ let output = '';
35
+ const prefix = ' '.repeat(indent);
36
+ for (const [key, value] of Object.entries(obj)) {
37
+ if (value === null || value === undefined) {
38
+ output += `${prefix}${key}:\n`;
39
+ }
40
+ else if (Array.isArray(value)) {
41
+ if (value.length === 0) {
42
+ output += `${prefix}${key}: []\n`;
43
+ }
44
+ else {
45
+ output += `${prefix}${key}:\n`;
46
+ for (const item of value) {
47
+ if (typeof item === 'object') {
48
+ output += `${prefix} - ${JSON.stringify(item)}\n`;
49
+ }
50
+ else {
51
+ output += `${prefix} - ${item}\n`;
52
+ }
53
+ }
54
+ }
55
+ }
56
+ else if (typeof value === 'object') {
57
+ output += `${prefix}${key}:\n`;
58
+ output += this.formatYaml(value, indent + 1);
59
+ }
60
+ else {
61
+ output += `${prefix}${key}: ${value}\n`;
62
+ }
63
+ }
64
+ return output;
65
+ }
66
+ /**
67
+ * 格式化时间
68
+ */
69
+ static formatDate(dateStr) {
70
+ const date = new Date(dateStr);
71
+ return date.toLocaleString('zh-CN', {
72
+ year: 'numeric',
73
+ month: '2-digit',
74
+ day: '2-digit',
75
+ hour: '2-digit',
76
+ minute: '2-digit'
77
+ });
78
+ }
79
+ /**
80
+ * 格式化文件大小
81
+ */
82
+ static formatFileSize(bytes) {
83
+ const units = ['B', 'KB', 'MB', 'GB'];
84
+ let size = bytes;
85
+ let unitIndex = 0;
86
+ while (size >= 1024 && unitIndex < units.length - 1) {
87
+ size /= 1024;
88
+ unitIndex++;
89
+ }
90
+ return `${size.toFixed(1)} ${units[unitIndex]}`;
91
+ }
92
+ /**
93
+ * 格式化字数
94
+ */
95
+ static formatWordCount(words) {
96
+ if (words >= 10000) {
97
+ return `${(words / 10000).toFixed(1)} 万字`;
98
+ }
99
+ return `${words.toLocaleString()} 字`;
100
+ }
101
+ /**
102
+ * 格式化进度条
103
+ */
104
+ static formatProgressBar(current, total, width = 30) {
105
+ const percentage = Math.min(100, Math.max(0, (current / total) * 100));
106
+ const filled = Math.round((percentage / 100) * width);
107
+ const empty = width - filled;
108
+ const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
109
+ return `${bar} ${percentage.toFixed(1)}%`;
110
+ }
111
+ }
112
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { NovelType } from '../core/types.js';
2
+ /**
3
+ * 验证工具类
4
+ */
5
+ export declare class ValidationUtils {
6
+ /**
7
+ * 验证小说类型
8
+ */
9
+ static validateNovelType(type: string): type is NovelType;
10
+ /**
11
+ * 验证章节号
12
+ */
13
+ static validateChapterNumber(num: string | number): boolean;
14
+ /**
15
+ * 验证卷号
16
+ */
17
+ static validateVolumeNumber(num: string | number): boolean;
18
+ /**
19
+ * 验证字数
20
+ */
21
+ static validateWordCount(num: string | number): boolean;
22
+ /**
23
+ * 验证项目名称
24
+ */
25
+ static validateProjectName(name: string): boolean;
26
+ /**
27
+ * 验证文件路径
28
+ */
29
+ static validateFilePath(path: string): boolean;
30
+ /**
31
+ * 验证 YAML 文件名
32
+ */
33
+ static validateYamlFilename(filename: string): boolean;
34
+ /**
35
+ * 验证事件类型
36
+ */
37
+ static isValidEventType(type: string): boolean;
38
+ /**
39
+ * 规范化人物姓名
40
+ */
41
+ static normalizeCharacterName(name: string): string;
42
+ /**
43
+ * 规范化弧名称
44
+ */
45
+ static normalizeArcName(name: string): string;
46
+ /**
47
+ * 验证章节范围
48
+ */
49
+ static validateChapterRange(start: number, end: number): boolean;
50
+ /**
51
+ * 解析卷标识符
52
+ */
53
+ static parseVolumeIdentifier(input: string): number | null;
54
+ /**
55
+ * 解析章节标识符
56
+ */
57
+ static parseChapterIdentifier(input: string): number | null;
58
+ }
59
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,SAAS;IAKzD;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAK3D;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAK1D;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAKvD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMjD;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAM9C;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAItD;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkB9C;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAInD;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI7C;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAIhE;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAW1D;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAU5D"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * 验证工具类
3
+ */
4
+ export class ValidationUtils {
5
+ /**
6
+ * 验证小说类型
7
+ */
8
+ static validateNovelType(type) {
9
+ const validTypes = ['webnovel', 'literary', 'fanfiction'];
10
+ return validTypes.includes(type);
11
+ }
12
+ /**
13
+ * 验证章节号
14
+ */
15
+ static validateChapterNumber(num) {
16
+ const chapter = typeof num === 'string' ? parseInt(num, 10) : num;
17
+ return Number.isInteger(chapter) && chapter > 0;
18
+ }
19
+ /**
20
+ * 验证卷号
21
+ */
22
+ static validateVolumeNumber(num) {
23
+ const volume = typeof num === 'string' ? parseInt(num, 10) : num;
24
+ return Number.isInteger(volume) && volume > 0;
25
+ }
26
+ /**
27
+ * 验证字数
28
+ */
29
+ static validateWordCount(num) {
30
+ const words = typeof num === 'string' ? parseInt(num, 10) : num;
31
+ return Number.isInteger(words) && words > 0;
32
+ }
33
+ /**
34
+ * 验证项目名称
35
+ */
36
+ static validateProjectName(name) {
37
+ // 项目名称不能为空,不能包含特殊字符
38
+ const validPattern = /^[a-zA-Z0-9\u4e00-\u9fa5_-]+$/;
39
+ return validPattern.test(name) && name.length > 0 && name.length <= 50;
40
+ }
41
+ /**
42
+ * 验证文件路径
43
+ */
44
+ static validateFilePath(path) {
45
+ // 基本路径验证
46
+ const invalidPattern = /[<>:"|?*]/;
47
+ return !invalidPattern.test(path);
48
+ }
49
+ /**
50
+ * 验证 YAML 文件名
51
+ */
52
+ static validateYamlFilename(filename) {
53
+ return filename.endsWith('.yaml') || filename.endsWith('.yml');
54
+ }
55
+ /**
56
+ * 验证事件类型
57
+ */
58
+ static isValidEventType(type) {
59
+ const validTypes = [
60
+ '位置变化',
61
+ '等级变化',
62
+ '势力变化',
63
+ '状态变化',
64
+ '关系变化',
65
+ '获得物品',
66
+ '出场',
67
+ '伏笔埋设',
68
+ '伏笔呼应',
69
+ '战斗',
70
+ '重要决定',
71
+ '死亡'
72
+ ];
73
+ return validTypes.includes(type);
74
+ }
75
+ /**
76
+ * 规范化人物姓名
77
+ */
78
+ static normalizeCharacterName(name) {
79
+ return name.trim().replace(/\s+/g, ' ');
80
+ }
81
+ /**
82
+ * 规范化弧名称
83
+ */
84
+ static normalizeArcName(name) {
85
+ return name.trim().replace(/\s+/g, ' ');
86
+ }
87
+ /**
88
+ * 验证章节范围
89
+ */
90
+ static validateChapterRange(start, end) {
91
+ return start > 0 && end >= start;
92
+ }
93
+ /**
94
+ * 解析卷标识符
95
+ */
96
+ static parseVolumeIdentifier(input) {
97
+ const match = input.match(/(?:vol|第)?(\d+)(?:卷)?/i);
98
+ if (match) {
99
+ const volume = parseInt(match[1], 10);
100
+ if (volume > 0) {
101
+ return volume;
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ /**
107
+ * 解析章节标识符
108
+ */
109
+ static parseChapterIdentifier(input) {
110
+ const match = input.match(/(?:chapter|第)?(\d+)(?:章)?/i);
111
+ if (match) {
112
+ const chapter = parseInt(match[1], 10);
113
+ if (chapter > 0) {
114
+ return chapter;
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ }
120
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@dayinxisheng/novel-tools",
3
+ "version": "0.1.0",
4
+ "description": "小说创作辅助工具集 - TypeScript 实现",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "novel-tools": "dist/commands/index.js"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ },
15
+ "./core": "./dist/core/index.js",
16
+ "./services": "./dist/services/index.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "test": "jest",
22
+ "test:watch": "jest --watch",
23
+ "test:coverage": "jest --coverage",
24
+ "lint": "eslint src --ext .ts",
25
+ "prepare": "npm run build",
26
+ "prepublishOnly": "npm run test && npm run build"
27
+ },
28
+ "keywords": [
29
+ "novel",
30
+ "writing",
31
+ "fiction",
32
+ "cli",
33
+ "authoring"
34
+ ],
35
+ "author": "dayinxisheng",
36
+ "license": "MIT",
37
+ "dependencies": {
38
+ "chalk": "^5.3.0",
39
+ "commander": "^12.1.0",
40
+ "glob": "^11.0.0",
41
+ "js-yaml": "^4.1.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/jest": "^29.5.12",
45
+ "@types/js-yaml": "^4.0.9",
46
+ "@types/node": "^20.11.24",
47
+ "@typescript-eslint/eslint-plugin": "^7.1.1",
48
+ "@typescript-eslint/parser": "^7.1.1",
49
+ "eslint": "^8.57.0",
50
+ "jest": "^29.7.0",
51
+ "ts-jest": "^29.1.2",
52
+ "typescript": "^5.3.3"
53
+ },
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ },
57
+ "files": [
58
+ "dist",
59
+ "README.md",
60
+ "CHANGELOG.md"
61
+ ]
62
+ }