@dxtmisha/scripts 0.7.2 → 0.7.7

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 (104) hide show
  1. package/bin/design-wiki-storm.ts +9 -0
  2. package/package.json +5 -3
  3. package/src/classes/Ai/AiAbstract.ts +14 -1
  4. package/src/classes/Ai/AiGoogleLite.ts +2 -1
  5. package/src/classes/Build/__tests__/buildFunctional.test.ts +43 -0
  6. package/src/classes/Build/buildFunctional.ts +15 -0
  7. package/src/classes/Component/ComponentCreator.ts +1 -0
  8. package/src/classes/Component/ComponentItem.ts +15 -0
  9. package/src/classes/Component/ComponentWiki.ts +8 -0
  10. package/src/classes/Component/ComponentWikiFile.ts +2 -0
  11. package/src/classes/Component/__tests__/ComponentCreator.test.ts +71 -0
  12. package/src/classes/Component/__tests__/ComponentItem.test.ts +71 -0
  13. package/src/classes/Design/DesignCommand.ts +15 -14
  14. package/src/classes/Design/DesignComponent.ts +235 -28
  15. package/src/classes/Design/DesignConstructor.ts +9 -5
  16. package/src/classes/Design/DesignConstructors.ts +8 -4
  17. package/src/classes/Design/DesignFlags.ts +16 -0
  18. package/src/classes/Design/DesignReplace.ts +10 -6
  19. package/src/classes/Design/DesignStructure.ts +8 -6
  20. package/src/classes/Design/DesignStructureClasses.ts +8 -4
  21. package/src/classes/Design/DesignStructureItemAbstract.ts +11 -2
  22. package/src/classes/Design/DesignStructureRead.ts +8 -4
  23. package/src/classes/Design/DesignStructureStyles.ts +8 -4
  24. package/src/classes/Design/DesignTypes.ts +53 -28
  25. package/src/classes/Design/DesignTypescript.ts +11 -2
  26. package/src/classes/Design/DesignUi.ts +42 -11
  27. package/src/classes/Design/DesignWiki.ts +4 -6
  28. package/src/classes/Design/DesignWikiStorm.ts +94 -0
  29. package/src/classes/Design/DesignWikiStormItem.ts +246 -0
  30. package/src/classes/Git/GitRead.ts +1 -0
  31. package/src/classes/Git/__tests__/GitRead.test.ts +70 -0
  32. package/src/classes/Library/LibraryAiWiki.ts +2 -1
  33. package/src/classes/Library/LibraryFlags.ts +9 -7
  34. package/src/classes/Library/LibraryItems.ts +9 -9
  35. package/src/classes/Library/LibraryList.ts +10 -5
  36. package/src/classes/Library/LibraryMedia.ts +21 -6
  37. package/src/classes/Library/LibraryPlugin.ts +8 -5
  38. package/src/classes/Library/LibraryTypes.ts +34 -10
  39. package/src/classes/Package/PackageInit.ts +12 -4
  40. package/src/classes/Package/PackageItem.ts +13 -4
  41. package/src/classes/Properties/Properties.ts +14 -3
  42. package/src/classes/Properties/PropertiesCache.ts +19 -20
  43. package/src/classes/Properties/PropertiesConfig.ts +39 -28
  44. package/src/classes/Properties/PropertiesConvector.ts +10 -6
  45. package/src/classes/Properties/PropertiesFile.ts +22 -28
  46. package/src/classes/Properties/PropertiesImport.ts +10 -7
  47. package/src/classes/Properties/PropertiesItems.ts +19 -12
  48. package/src/classes/Properties/PropertiesKeys.ts +15 -9
  49. package/src/classes/Properties/PropertiesMain.ts +13 -7
  50. package/src/classes/Properties/PropertiesPalette.ts +12 -6
  51. package/src/classes/Properties/PropertiesPath.ts +17 -11
  52. package/src/classes/Properties/PropertiesScss.ts +10 -8
  53. package/src/classes/Properties/PropertiesSeparator.ts +9 -11
  54. package/src/classes/Properties/PropertiesSettings.ts +8 -6
  55. package/src/classes/Properties/PropertiesStandard.ts +5 -6
  56. package/src/classes/Properties/PropertiesTool.ts +16 -9
  57. package/src/classes/Properties/PropertiesTypes.ts +12 -12
  58. package/src/classes/Properties/PropertiesValues.ts +14 -14
  59. package/src/classes/Properties/PropertiesWrap.ts +5 -6
  60. package/src/classes/Properties/convector/convectorColor.ts +5 -3
  61. package/src/classes/Properties/to/PropertiesToAbstract.ts +18 -4
  62. package/src/composables/__tests__/useAi.test.ts +75 -0
  63. package/src/config.ts +2 -0
  64. package/src/functions/__tests__/getComponentPaths.test.ts +19 -0
  65. package/src/functions/__tests__/getConfigAi.test.ts +26 -0
  66. package/src/functions/__tests__/getConstructorProperties.test.ts +51 -0
  67. package/src/functions/__tests__/getDirname.test.ts +31 -0
  68. package/src/functions/__tests__/getNameDirByPaths.test.ts +40 -0
  69. package/src/functions/__tests__/getPackageJson.test.ts +34 -0
  70. package/src/functions/__tests__/hasNativeDirname.test.ts +18 -0
  71. package/src/functions/__tests__/toPathStandardSep.test.ts +31 -0
  72. package/src/functions/getConfigAi.ts +3 -2
  73. package/src/functions/toPathStandardSep.ts +1 -1
  74. package/src/library-ai.ts +0 -1
  75. package/src/library.ts +6 -0
  76. package/src/media/properties/css.ts +3 -1
  77. package/src/media/templates/component/props.ts +1 -1
  78. package/src/media/templates/component/wiki.ts +6 -12
  79. package/src/media/templates/component/wikiData.ts +28 -0
  80. package/src/media/templates/packages/figma/README.md +1 -0
  81. package/src/media/templates/packages/figma/ai.sample.config.ts +2 -0
  82. package/src/media/templates/packages/figma/design.config.json +3 -0
  83. package/src/media/templates/packages/figma/index.html +12 -0
  84. package/src/media/templates/packages/figma/manifest.json +25 -0
  85. package/src/media/templates/packages/figma/package.json +37 -0
  86. package/src/media/templates/packages/figma/src/App.vue +9 -0
  87. package/src/media/templates/packages/figma/src/classes/_.gitignore.txt +1 -0
  88. package/src/media/templates/packages/figma/src/code.ts +16 -0
  89. package/src/media/templates/packages/figma/src/components/_.gitignore.txt +1 -0
  90. package/src/media/templates/packages/figma/src/composables/_.gitignore.txt +1 -0
  91. package/src/media/templates/packages/figma/src/config.ts +0 -0
  92. package/src/media/templates/packages/figma/src/functions/_.gitignore.txt +1 -0
  93. package/src/media/templates/packages/figma/src/library.ts +0 -0
  94. package/src/media/templates/packages/figma/src/main.ts +4 -0
  95. package/src/media/templates/packages/figma/src/media/_.gitignore.txt +1 -0
  96. package/src/media/templates/packages/figma/src/storybook/_.gitignore.txt +1 -0
  97. package/src/media/templates/packages/figma/src/types/_.gitignore.txt +1 -0
  98. package/src/media/templates/packages/figma/src/vite-env.d.ts +1 -0
  99. package/src/media/templates/packages/figma/tsconfig.app.json +12 -0
  100. package/src/media/templates/packages/figma/tsconfig.json +7 -0
  101. package/src/media/templates/packages/figma/tsconfig.node.json +8 -0
  102. package/src/media/templates/packages/figma/vite.config.ts +7 -0
  103. package/src/types/configTypes.ts +3 -0
  104. package/src/types/webTypes.ts +105 -0
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env vite-node
2
+
3
+ import { DesignWikiStorm } from '../src/classes/Design/DesignWikiStorm'
4
+
5
+ // const name: string | undefined = process.argv?.[2] ?? undefined
6
+
7
+ new DesignWikiStorm()
8
+ .make()
9
+ .then()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dxtmisha/scripts",
3
3
  "private": false,
4
- "version": "0.7.2",
4
+ "version": "0.7.7",
5
5
  "type": "module",
6
6
  "description": "Development scripts and CLI tools for DXT UI projects - automated component generation, library building and project management tools",
7
7
  "keywords": [
@@ -28,7 +28,8 @@
28
28
  "url": "https://github.com/dxtmisha/dxt-ui/issues"
29
29
  },
30
30
  "scripts": {
31
- "library": "dxt-library"
31
+ "library": "dxt-library",
32
+ "publish-to-npm": "npm publish --access public"
32
33
  },
33
34
  "files": [
34
35
  "bin/",
@@ -49,7 +50,8 @@
49
50
  "dxt-library": "bin/design-library.ts",
50
51
  "dxt-package": "bin/design-package.ts",
51
52
  "dxt-types": "bin/design-types.ts",
52
- "dxt-ui": "bin/design-ui.ts"
53
+ "dxt-ui": "bin/design-ui.ts",
54
+ "dxt-wiki-storm": "bin/design-wiki-storm.ts"
53
55
  },
54
56
  "exports": {
55
57
  ".": "./src/library.ts",
@@ -39,10 +39,12 @@ export abstract class AiAbstract<AI = any> {
39
39
  * Конструктор инициализирует ресурсы конкретной реализации.
40
40
  * @param key - API key / API ключ
41
41
  * @param model - initial model id / начальный идентификатор модели
42
+ * @param config - configuration object / объект конфигурации
42
43
  */
43
44
  constructor(
44
45
  protected key: string,
45
- protected model: string
46
+ protected model: string,
47
+ protected config: Record<string, any> = {}
46
48
  ) {
47
49
  }
48
50
 
@@ -150,6 +152,17 @@ export abstract class AiAbstract<AI = any> {
150
152
  return this
151
153
  }
152
154
 
155
+ /**
156
+ * Sets / switches configuration object.
157
+ *
158
+ * Устанавливает / переключает объект конфигурации.
159
+ * @param config - configuration object / объект конфигурации
160
+ */
161
+ setConfig(config: Record<string, any>): this {
162
+ this.config = config
163
+ return this
164
+ }
165
+
153
166
  /**
154
167
  * Generates AI response using active model and composed contents.
155
168
  *
@@ -69,7 +69,8 @@ export class AiGoogleLite extends AiAbstract<GoogleGenAI> {
69
69
  { text: contents }
70
70
  ]
71
71
  }
72
- ]
72
+ ],
73
+ config: this.config
73
74
  })
74
75
 
75
76
  return response?.text ?? ''
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { BuildFunctional } from '../buildFunctional'
3
+ import { PropertiesFile } from '../../Properties/PropertiesFile'
4
+ import { UI_DIRS_LIBRARY } from '../../../config'
5
+
6
+ vi.mock('@dxtmisha/functional', () => ({
7
+ func1: vi.fn(),
8
+ func2: vi.fn()
9
+ }))
10
+
11
+ vi.mock('../../Properties/PropertiesFile', () => ({
12
+ PropertiesFile: {
13
+ writeByPath: vi.fn()
14
+ }
15
+ }))
16
+
17
+ describe('BuildFunctional', () => {
18
+ it('getList should return keys of the functional package', () => {
19
+ const build = new BuildFunctional()
20
+ const list = build.getList()
21
+ expect(list).toContain('func1')
22
+ expect(list).toContain('func2')
23
+ expect(list).toHaveLength(2)
24
+ })
25
+
26
+ it('make should call PropertiesFile.writeByPath with correct arguments', () => {
27
+ const build = new BuildFunctional()
28
+ build.make()
29
+
30
+ expect(PropertiesFile.writeByPath).toHaveBeenCalledWith(
31
+ [...UI_DIRS_LIBRARY, 'functional.ts'],
32
+ expect.stringContaining('export { func1 } from \'@dxtmisha/functional\'')
33
+ )
34
+ expect(PropertiesFile.writeByPath).toHaveBeenCalledWith(
35
+ [...UI_DIRS_LIBRARY, 'functional.ts'],
36
+ expect.stringContaining('export { func2 } from \'@dxtmisha/functional\'')
37
+ )
38
+ expect(PropertiesFile.writeByPath).toHaveBeenCalledWith(
39
+ [...UI_DIRS_LIBRARY, 'functional.ts'],
40
+ expect.stringContaining('export type * from \'@dxtmisha/functional\'')
41
+ )
42
+ })
43
+ })
@@ -4,10 +4,20 @@ import { PropertiesFile } from '../Properties/PropertiesFile'
4
4
 
5
5
  import { UI_DIRS_LIBRARY } from '../../config'
6
6
 
7
+ /**
8
+ * A class for building the functional library exports.
9
+ *
10
+ * Класс для сборки экспортов функциональной библиотеки.
11
+ */
7
12
  export class BuildFunctional {
8
13
  constructor() {
9
14
  }
10
15
 
16
+ /**
17
+ * Generates the functional.ts file by re-exporting all members from @dxtmisha/functional.
18
+ *
19
+ * Генерирует файл functional.ts, повторно экспортируя все элементы из @dxtmisha/functional.
20
+ */
11
21
  make(): void {
12
22
  console.log('Build functional...')
13
23
 
@@ -33,6 +43,11 @@ export class BuildFunctional {
33
43
  console.log('...end')
34
44
  }
35
45
 
46
+ /**
47
+ * Returns a list of all exported members from the @dxtmisha/functional package.
48
+ *
49
+ * Возвращает список всех экспортируемых элементов из пакета @dxtmisha/functional.
50
+ */
36
51
  getList(): string[] {
37
52
  return Object.keys(functional)
38
53
  }
@@ -34,6 +34,7 @@ export class ComponentCreator {
34
34
  * Collects only empty component directories.
35
35
  *
36
36
  * Собирает только пустые директории компонентов.
37
+ * @protected
37
38
  */
38
39
  protected getDirs(): string[] {
39
40
  return PropertiesFile.readDirOnlyRecursive(UI_DIRS_COMPONENTS)
@@ -56,6 +56,7 @@ export class ComponentItem {
56
56
  * Gets component name from directory path.
57
57
  *
58
58
  * Получает имя компонента из пути директории.
59
+ * @protected
59
60
  */
60
61
  protected getName(): string {
61
62
  const parts = PropertiesFile.splitForDir(this.path)
@@ -66,6 +67,7 @@ export class ComponentItem {
66
67
  * Reads project name from package.json.
67
68
  *
68
69
  * Читает имя проекта из package.json.
70
+ * @protected
69
71
  */
70
72
  protected getProjectName(): string {
71
73
  return this.readPackage()?.name ?? 'Project'
@@ -75,6 +77,8 @@ export class ComponentItem {
75
77
  * Builds destination file path for output.
76
78
  *
77
79
  * Строит путь назначения для выходного файла.
80
+ * @param path filename/ имя файла
81
+ * @protected
78
82
  */
79
83
  protected getFilePath(path: string): string[] {
80
84
  return [
@@ -87,6 +91,8 @@ export class ComponentItem {
87
91
  * Builds template file path for reading.
88
92
  *
89
93
  * Строит путь к файлу шаблона для чтения.
94
+ * @param path filename/ имя файла
95
+ * @protected
90
96
  */
91
97
  protected getSamplePath(path: string): string[] {
92
98
  return [...DIR_SAMPLE, path]
@@ -96,6 +102,7 @@ export class ComponentItem {
96
102
  * Lists all template files recursively.
97
103
  *
98
104
  * Получает список всех файлов шаблонов рекурсивно.
105
+ * @protected
99
106
  */
100
107
  protected getFilesSample(): string[] {
101
108
  return PropertiesFile.readDirRecursive(DIR_SAMPLE)
@@ -105,6 +112,8 @@ export class ComponentItem {
105
112
  * Reads template file content as string.
106
113
  *
107
114
  * Читает содержимое файла шаблона как строку.
115
+ * @param path filename/ имя файла
116
+ * @protected
108
117
  */
109
118
  protected readFile(path: string): string {
110
119
  return String(PropertiesFile.readFile(this.getSamplePath(path)))
@@ -114,6 +123,7 @@ export class ComponentItem {
114
123
  * Reads package.json data or returns empty object.
115
124
  *
116
125
  * Читает данные package.json или возвращает пустой объект.
126
+ * @protected
117
127
  */
118
128
  protected readPackage(): Record<string, any> {
119
129
  return PropertiesFile.readFile(UI_FILE_PACKAGE) ?? {}
@@ -123,6 +133,9 @@ export class ComponentItem {
123
133
  * Writes generated file to destination.
124
134
  *
125
135
  * Записывает сгенерированный файл в место назначения.
136
+ * @param path filename/ имя файла
137
+ * @param content file content/ содержимое файла
138
+ * @protected
126
139
  */
127
140
  protected writeFile(path: string, content: string): void {
128
141
  const paths = this.getFilePath(path)
@@ -135,6 +148,8 @@ export class ComponentItem {
135
148
  * Replaces template placeholders with actual values.
136
149
  *
137
150
  * Заменяет плейсхолдеры шаблона реальными значениями.
151
+ * @param contentOrPath content or path/ содержимое или путь
152
+ * @protected
138
153
  */
139
154
  protected replacement(contentOrPath: string): string {
140
155
  return contentOrPath
@@ -125,6 +125,7 @@ export class ComponentWiki {
125
125
  * Returns root path segments for the component.
126
126
  *
127
127
  * Возвращает сегменты корневого пути компонента.
128
+ * @protected
128
129
  */
129
130
  protected getRootComponent(): string[] {
130
131
  return [
@@ -137,6 +138,7 @@ export class ComponentWiki {
137
138
  * Returns wiki directory path segments.
138
139
  *
139
140
  * Возвращает сегменты пути wiki директории.
141
+ * @protected
140
142
  */
141
143
  protected getPathWiki(): string[] {
142
144
  return [
@@ -149,6 +151,7 @@ export class ComponentWiki {
149
151
  * Returns temporary directory path segments.
150
152
  *
151
153
  * Возвращает сегменты пути временной директории.
154
+ * @protected
152
155
  */
153
156
  protected getPathTemporary(): string[] {
154
157
  return [
@@ -161,6 +164,7 @@ export class ComponentWiki {
161
164
  * Derives component folder name.
162
165
  *
163
166
  * Получает имя директории компонента.
167
+ * @protected
164
168
  */
165
169
  protected getName(): string {
166
170
  return String(getNameDirByPaths(this.getRootComponent()))
@@ -170,6 +174,7 @@ export class ComponentWiki {
170
174
  * Reads the demo file content.
171
175
  *
172
176
  * Читает содержимое демо-файла.
177
+ * @protected
173
178
  */
174
179
  protected readDemo(): string {
175
180
  return new ComponentWikiFile(FILE_DEMO_SAMPLE).read()
@@ -179,6 +184,7 @@ export class ComponentWiki {
179
184
  * Reads the prompt template.
180
185
  *
181
186
  * Читает шаблон промпта.
187
+ * @protected
182
188
  */
183
189
  protected readPrompt(): string {
184
190
  return new ComponentWikiFile(FILE_PROMPT_SAMPLE)
@@ -190,6 +196,7 @@ export class ComponentWiki {
190
196
  * Prepares context for AI.
191
197
  *
192
198
  * Подготавливает контекст для ИИ.
199
+ * @protected
193
200
  */
194
201
  protected makeAi(): void {
195
202
  if (this.ai) {
@@ -206,6 +213,7 @@ export class ComponentWiki {
206
213
  * Invokes AI generation and splits result into types / stories / mdx.
207
214
  *
208
215
  * Вызывает генерацию через ИИ и делит результат на types / stories / mdx.
216
+ * @protected
209
217
  */
210
218
  protected async aiGenerate(): Promise<void> {
211
219
  if (this.ai) {
@@ -98,6 +98,7 @@ export class ComponentWikiFile {
98
98
  *
99
99
  * Извлекает дату из строки содержимого.
100
100
  * @param content content string / строка содержимого
101
+ * @protected
101
102
  */
102
103
  protected extractDateFromContent(content: string): Datetime {
103
104
  const match = content.match(DATE_UPDATED_MATCH)
@@ -118,6 +119,7 @@ export class ComponentWikiFile {
118
119
  *
119
120
  * Добавляет текущую дату в содержимое, если isDate равно true.
120
121
  * @param content content string / строка содержимого
122
+ * @protected
121
123
  */
122
124
  protected addDate(content: string): string {
123
125
  if (this.isDate) {
@@ -0,0 +1,71 @@
1
+ import { describe, expect, it, vi, beforeEach } from 'vitest'
2
+ import { ComponentCreator } from '../ComponentCreator'
3
+ import { PropertiesFile } from '../../Properties/PropertiesFile'
4
+ import { ComponentItem } from '../ComponentItem'
5
+ import { getComponentPaths } from '../../../functions/getComponentPaths'
6
+ import { UI_DIRS_COMPONENTS } from '../../../config'
7
+
8
+ vi.mock('../../Properties/PropertiesFile', () => ({
9
+ PropertiesFile: {
10
+ readDirOnlyRecursive: vi.fn(),
11
+ readDir: vi.fn()
12
+ }
13
+ }))
14
+
15
+ vi.mock('../ComponentItem', () => ({
16
+ ComponentItem: vi.fn().mockImplementation(function () {
17
+ return {
18
+ make: vi.fn()
19
+ }
20
+ })
21
+ }))
22
+
23
+ vi.mock('../../../functions/getComponentPaths', () => ({
24
+ getComponentPaths: vi.fn(path => [path, 'full'])
25
+ }))
26
+
27
+ describe('ComponentCreator', () => {
28
+ let creator: ComponentCreator
29
+
30
+ beforeEach(() => {
31
+ vi.clearAllMocks()
32
+ creator = new ComponentCreator()
33
+ })
34
+
35
+ it('make should call ComponentItem.make for each empty directory', () => {
36
+ vi.mocked(PropertiesFile.readDirOnlyRecursive).mockReturnValue(['dir1', 'dir2', 'dir3'])
37
+ vi.mocked(PropertiesFile.readDir).mockImplementation((path) => {
38
+ if (Array.isArray(path) && path[0] === 'dir2') return ['file.ts']
39
+ return []
40
+ })
41
+
42
+ creator.make()
43
+
44
+ expect(ComponentItem).toHaveBeenCalledWith('dir1')
45
+ expect(ComponentItem).not.toHaveBeenCalledWith('dir2')
46
+ expect(ComponentItem).toHaveBeenCalledWith('dir3')
47
+
48
+ const mockInstance1 = vi.mocked(ComponentItem).mock.results[0]?.value
49
+ const mockInstance2 = vi.mocked(ComponentItem).mock.results[1]?.value
50
+
51
+ expect(mockInstance1?.make).toHaveBeenCalled()
52
+ expect(mockInstance2?.make).toHaveBeenCalled()
53
+ })
54
+
55
+ it('getDirs should return only empty directories', () => {
56
+ vi.mocked(PropertiesFile.readDirOnlyRecursive).mockReturnValue(['empty', 'not-empty'])
57
+ vi.mocked(PropertiesFile.readDir).mockImplementation((path) => {
58
+ if (Array.isArray(path) && path[0] === 'not-empty') return ['index.ts']
59
+ return []
60
+ })
61
+
62
+ // Access protected method for testing
63
+ const dirs = (creator as any).getDirs()
64
+
65
+ expect(dirs).toContain('empty')
66
+ expect(dirs).not.toContain('not-empty')
67
+ expect(dirs).toHaveLength(1)
68
+ expect(PropertiesFile.readDirOnlyRecursive).toHaveBeenCalledWith(UI_DIRS_COMPONENTS)
69
+ expect(getComponentPaths).toHaveBeenCalledWith('empty')
70
+ })
71
+ })
@@ -0,0 +1,71 @@
1
+ import { describe, expect, it, vi, beforeEach } from 'vitest'
2
+ import { ComponentItem } from '../ComponentItem'
3
+ import { PropertiesFile } from '../../Properties/PropertiesFile'
4
+ import { toKebabCase } from '@dxtmisha/functional-basic'
5
+
6
+ vi.mock('../../Properties/PropertiesFile', () => ({
7
+ PropertiesFile: {
8
+ splitForDir: vi.fn(path => path.split('/')),
9
+ readFile: vi.fn(),
10
+ writeByPath: vi.fn(),
11
+ chmod: vi.fn(),
12
+ readDirRecursive: vi.fn()
13
+ }
14
+ }))
15
+
16
+ vi.mock('../../../functions/getComponentPaths', () => ({
17
+ getComponentPaths: vi.fn(path => [path, 'full'])
18
+ }))
19
+
20
+ describe('ComponentItem', () => {
21
+ let item: ComponentItem
22
+ const mockPath = 'src/components/TestComponent'
23
+
24
+ beforeEach(() => {
25
+ vi.clearAllMocks()
26
+ item = new ComponentItem(mockPath)
27
+ })
28
+
29
+ it('getName should return the last part of the path', () => {
30
+ const name = (item as any).getName()
31
+ expect(name).toBe('TestComponent')
32
+ expect(PropertiesFile.splitForDir).toHaveBeenCalledWith(mockPath)
33
+ })
34
+
35
+ it('getProjectName should return package name or "Project"', () => {
36
+ vi.mocked(PropertiesFile.readFile).mockReturnValue({ name: 'test-project' })
37
+ const projectName = (item as any).getProjectName()
38
+ expect(projectName).toBe('test-project')
39
+
40
+ vi.mocked(PropertiesFile.readFile).mockReturnValue(undefined)
41
+ expect((item as any).getProjectName()).toBe('Project')
42
+ })
43
+
44
+ it('replacement should replace placeholders correctly', () => {
45
+ vi.mocked(PropertiesFile.readFile).mockReturnValue({ name: 'test-project' })
46
+ const content = 'Name: ComponentDoc, kebab: component-doc, project: [project], path: [path]'
47
+ const result = (item as any).replacement(content)
48
+
49
+ expect(result).toContain('Name: TestComponent')
50
+ expect(result).toContain(`kebab: ${toKebabCase('TestComponent')}`)
51
+ expect(result).toContain('project: test-project')
52
+ expect(result).toContain(`path: ${mockPath}`)
53
+ })
54
+
55
+ it('make should read templates and write files with replacements', () => {
56
+ vi.mocked(PropertiesFile.readDirRecursive).mockReturnValue(['Template.ts'])
57
+ vi.mocked(PropertiesFile.readFile).mockImplementation((path) => {
58
+ if (Array.isArray(path) && path.includes('package.json')) return { name: 'test-project' }
59
+ return 'export class ComponentDoc {}'
60
+ })
61
+
62
+ item.make()
63
+
64
+ expect(PropertiesFile.readDirRecursive).toHaveBeenCalled()
65
+ expect(PropertiesFile.writeByPath).toHaveBeenCalledWith(
66
+ expect.arrayContaining([mockPath, 'Template.ts']),
67
+ 'export class TestComponent {}'
68
+ )
69
+ expect(PropertiesFile.chmod).toHaveBeenCalled()
70
+ })
71
+ })
@@ -11,7 +11,7 @@ import { PropertiesFile } from '../Properties/PropertiesFile'
11
11
  import { DesignStructure } from './DesignStructure'
12
12
  import { DesignReplace } from './DesignReplace'
13
13
 
14
- import { UI_FILE_PACKAGE, UI_KEY_CONSTRUCTOR } from '../../config'
14
+ import { UI_FILE_PACKAGE } from '../../config'
15
15
 
16
16
  const dirnamePath = hasNativeDirname()
17
17
  ? __dirname
@@ -20,9 +20,11 @@ const dirnamePath = hasNativeDirname()
20
20
  const DIR_SAMPLE = [dirnamePath, '..', '..', 'media', 'templates']
21
21
 
22
22
  /**
23
- * Base abstract class for generating script files.
23
+ * Base abstract class for generating script files and design system components.
24
+ * Provides unified logic for template reading, data transformation, and file writing.
24
25
  *
25
- * Базовый абстрактный класс для генерации файлов скриптов.
26
+ * Базовый абстрактный класс для генерации файлов скриптов и компонентов дизайн-системы.
27
+ * Обеспечивает единую логику чтения шаблонов, трансформации данных и записи файлов.
26
28
  */
27
29
  export abstract class DesignCommand {
28
30
  protected abstract DIR_SAMPLE: string
@@ -31,11 +33,12 @@ export abstract class DesignCommand {
31
33
  protected structure?: DesignStructure
32
34
 
33
35
  /**
34
- * Constructor
35
- * @param command component name/ названия компонента
36
- * @param options additional parameters/ дополнительные параметры
36
+ * Constructor for DesignCommand.
37
+ *
38
+ * Конструктор для DesignCommand.
39
+ * @param command component name or command identifier / название компонента или идентификатор команды
40
+ * @param options additional key-value parameters / дополнительные параметры ключ-значение
37
41
  */
38
-
39
42
  protected constructor(
40
43
  protected readonly command: string,
41
44
  protected readonly options: Record<string, string> = {}
@@ -43,9 +46,11 @@ export abstract class DesignCommand {
43
46
  }
44
47
 
45
48
  /**
46
- * Entry point for the command.
49
+ * Main entry point for executing the command.
50
+ * Validates input and triggers the primary initialization logic.
47
51
  *
48
- * Точка входа для команды.
52
+ * Основная точка входа для выполнения команды.
53
+ * Проверяет входные данные и запускает основную логику инициализации.
49
54
  */
50
55
  make(): void {
51
56
  if (this.command) {
@@ -112,11 +117,7 @@ export abstract class DesignCommand {
112
117
  */
113
118
  protected getStructure(): DesignStructure {
114
119
  if (!this.structure) {
115
- const [design, component] = this.getCommand().split('.', 2)
116
- this.structure = new DesignStructure(
117
- design ?? UI_KEY_CONSTRUCTOR,
118
- component ?? 'component'
119
- )
120
+ this.structure = new DesignStructure(this.getCommand())
120
121
  }
121
122
 
122
123
  return this.structure