@dxtmisha/scripts 0.6.3 → 0.7.6
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/ai-doc.ts +1 -3
- package/bin/build-functional.ts +5 -0
- package/bin/design-flags.ts +5 -0
- package/bin/design-wiki-storm.ts +9 -0
- package/package.json +14 -8
- package/src/classes/Ai/AiAbstract.ts +14 -1
- package/src/classes/Ai/AiGoogleLite.ts +2 -1
- package/src/classes/Build/__tests__/buildFunctional.test.ts +43 -0
- package/src/classes/Build/buildFunctional.ts +54 -0
- package/src/classes/Component/ComponentCreator.ts +1 -0
- package/src/classes/Component/ComponentItem.ts +15 -0
- package/src/classes/Component/ComponentWiki.ts +8 -0
- package/src/classes/Component/ComponentWikiFile.ts +2 -0
- package/src/classes/Component/__tests__/ComponentCreator.test.ts +71 -0
- package/src/classes/Component/__tests__/ComponentItem.test.ts +71 -0
- package/src/classes/Design/DesignCommand.ts +65 -10
- package/src/classes/Design/DesignComponent.ts +303 -39
- package/src/classes/Design/DesignConstructor.ts +49 -20
- package/src/classes/Design/DesignConstructors.ts +61 -2
- package/src/classes/Design/DesignFlags.ts +215 -0
- package/src/classes/Design/DesignReplace.ts +11 -7
- package/src/classes/Design/DesignStructure.ts +8 -6
- package/src/classes/Design/DesignStructureClasses.ts +8 -4
- package/src/classes/Design/DesignStructureItemAbstract.ts +11 -2
- package/src/classes/Design/DesignStructureRead.ts +8 -4
- package/src/classes/Design/DesignStructureStyles.ts +8 -4
- package/src/classes/Design/DesignTypes.ts +53 -28
- package/src/classes/Design/DesignTypescript.ts +11 -2
- package/src/classes/Design/DesignUi.ts +74 -4
- package/src/classes/Design/DesignWiki.ts +4 -6
- package/src/classes/Design/DesignWikiStorm.ts +94 -0
- package/src/classes/Design/DesignWikiStormItem.ts +246 -0
- package/src/classes/Git/GitRead.ts +1 -0
- package/src/classes/Git/__tests__/GitRead.test.ts +70 -0
- package/src/classes/Library/LibraryAiWiki.ts +127 -0
- package/src/classes/Library/LibraryAiWikiItem.ts +79 -0
- package/src/classes/Library/LibraryExport.ts +0 -2
- package/src/classes/Library/LibraryFlags.ts +9 -7
- package/src/classes/Library/LibraryItems.ts +22 -13
- package/src/classes/Library/LibraryList.ts +189 -0
- package/src/classes/Library/LibraryMedia.ts +22 -8
- package/src/classes/Library/LibraryPlugin.ts +73 -0
- package/src/classes/Library/LibraryTypes.ts +130 -0
- package/src/classes/Package/PackageInit.ts +12 -4
- package/src/classes/Package/PackageItem.ts +16 -5
- package/src/classes/Properties/Properties.ts +14 -3
- package/src/classes/Properties/PropertiesCache.ts +19 -20
- package/src/classes/Properties/PropertiesConfig.ts +46 -26
- package/src/classes/Properties/PropertiesConvector.ts +10 -6
- package/src/classes/Properties/PropertiesFile.ts +27 -31
- package/src/classes/Properties/PropertiesImport.ts +10 -7
- package/src/classes/Properties/PropertiesItems.ts +19 -12
- package/src/classes/Properties/PropertiesKeys.ts +15 -9
- package/src/classes/Properties/PropertiesMain.ts +13 -7
- package/src/classes/Properties/PropertiesPalette.ts +12 -6
- package/src/classes/Properties/PropertiesPath.ts +17 -11
- package/src/classes/Properties/PropertiesScss.ts +10 -8
- package/src/classes/Properties/PropertiesSeparator.ts +9 -11
- package/src/classes/Properties/PropertiesSettings.ts +8 -6
- package/src/classes/Properties/PropertiesStandard.ts +5 -6
- package/src/classes/Properties/PropertiesTool.ts +16 -9
- package/src/classes/Properties/PropertiesTypes.ts +12 -12
- package/src/classes/Properties/PropertiesValues.ts +14 -14
- package/src/classes/Properties/PropertiesWrap.ts +5 -6
- package/src/classes/Properties/convector/convectorColor.ts +5 -3
- package/src/classes/Properties/to/PropertiesToAbstract.ts +18 -4
- package/src/classes/Styles/Styles.ts +1 -0
- package/src/composables/__tests__/useAi.test.ts +75 -0
- package/src/config.ts +9 -0
- package/src/functions/__tests__/getComponentPaths.test.ts +19 -0
- package/src/functions/__tests__/getConfigAi.test.ts +26 -0
- package/src/functions/__tests__/getConstructorProperties.test.ts +51 -0
- package/src/functions/__tests__/getDirname.test.ts +31 -0
- package/src/functions/__tests__/getNameDirByPaths.test.ts +40 -0
- package/src/functions/__tests__/getPackageJson.test.ts +34 -0
- package/src/functions/__tests__/hasNativeDirname.test.ts +18 -0
- package/src/functions/__tests__/toPathStandardSep.test.ts +31 -0
- package/src/functions/getConfigAi.ts +3 -2
- package/src/functions/toPathStandardSep.ts +1 -1
- package/src/library-ai.ts +0 -1
- package/src/library.ts +10 -0
- package/src/media/properties/css.ts +3 -1
- package/src/media/templates/component/{DesignComponentWikiAi.vue → DesignComponentAiWiki.vue} +2 -2
- package/src/media/templates/component/props.ts +2 -3
- package/src/media/templates/component/styleToken.scss +1 -1
- package/src/media/templates/component/wiki.ts +6 -12
- package/src/media/templates/component/wikiData.ts +28 -0
- package/src/media/templates/constructors/props.ts +3 -4
- package/src/media/templates/packages/figma/README.md +1 -0
- package/src/media/templates/packages/figma/ai.sample.config.ts +2 -0
- package/src/media/templates/packages/figma/design.config.json +3 -0
- package/src/media/templates/packages/figma/index.html +12 -0
- package/src/media/templates/packages/figma/manifest.json +25 -0
- package/src/media/templates/packages/figma/package.json +37 -0
- package/src/media/templates/packages/figma/src/App.vue +9 -0
- package/src/media/templates/packages/figma/src/classes/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/code.ts +16 -0
- package/src/media/templates/packages/figma/src/components/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/composables/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/functions/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/library.ts +0 -0
- package/src/media/templates/packages/figma/src/main.ts +4 -0
- package/src/media/templates/packages/figma/src/media/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/storybook/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/types/_.gitignore.txt +1 -0
- package/src/media/templates/packages/figma/src/vite-env.d.ts +1 -0
- package/src/media/templates/packages/figma/tsconfig.app.json +12 -0
- package/src/media/templates/packages/figma/tsconfig.json +7 -0
- package/src/media/templates/packages/figma/tsconfig.node.json +8 -0
- package/src/media/templates/packages/figma/vite.config.ts +7 -0
- package/src/media/templates/packages/library/src/main.ts +1 -1
- package/src/media/templates/packages/project/design.config.json +3 -0
- package/src/media/templates/packages/project/index.html +1 -2
- package/src/media/templates/packages/project/public/_.gitignore.txt +0 -0
- package/src/media/templates/packages/project/src/main.ts +2 -1
- package/src/media/templates/packages/project/src/vite-env.d.ts +1 -0
- package/src/types/configTypes.ts +6 -0
- package/src/types/designTypes.ts +12 -0
- package/src/types/libraryTypes.ts +1 -1
- package/src/types/webTypes.ts +105 -0
- /package/src/media/templates/packages/{library/public/_.gitignore.txt → figma/src/config.ts} +0 -0
package/bin/ai-doc.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxtmisha/scripts",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.6
|
|
4
|
+
"version": "0.7.6",
|
|
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,11 +28,12 @@
|
|
|
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": "npm publish --access public"
|
|
32
33
|
},
|
|
33
34
|
"files": [
|
|
34
|
-
"src/",
|
|
35
35
|
"bin/",
|
|
36
|
+
"src/",
|
|
36
37
|
"README.md",
|
|
37
38
|
"package.json",
|
|
38
39
|
"LICENSE"
|
|
@@ -41,30 +42,35 @@
|
|
|
41
42
|
"module": "./src/library.ts",
|
|
42
43
|
"bin": {
|
|
43
44
|
"dxt-ai-doc": "bin/ai-doc.ts",
|
|
45
|
+
"dxt-build-functional": "bin/build-functional.ts",
|
|
44
46
|
"dxt-component": "bin/design-component.ts",
|
|
45
47
|
"dxt-component-wiki": "bin/design-component-wiki.ts",
|
|
46
48
|
"dxt-constructor": "bin/design-constructor.ts",
|
|
49
|
+
"dxt-flags": "bin/design-flags.ts",
|
|
47
50
|
"dxt-library": "bin/design-library.ts",
|
|
48
51
|
"dxt-package": "bin/design-package.ts",
|
|
49
52
|
"dxt-types": "bin/design-types.ts",
|
|
50
|
-
"dxt-ui": "bin/design-ui.ts"
|
|
53
|
+
"dxt-ui": "bin/design-ui.ts",
|
|
54
|
+
"dxt-wiki-storm": "bin/design-wiki-storm.ts"
|
|
51
55
|
},
|
|
52
56
|
"exports": {
|
|
53
57
|
".": "./src/library.ts",
|
|
54
58
|
"./ai": "./src/library-ai.ts",
|
|
59
|
+
"./plugin": "./src/library-plugin.ts",
|
|
55
60
|
"./config": "./src/config.ts",
|
|
56
61
|
"./properties.json": "./src/media/properties.json"
|
|
57
62
|
},
|
|
58
63
|
"engines": {
|
|
59
|
-
"node": ">=
|
|
64
|
+
"node": ">=20.0.0"
|
|
60
65
|
},
|
|
61
66
|
"peerDependencies": {
|
|
62
67
|
"@dxtmisha/configuration": "*",
|
|
68
|
+
"@dxtmisha/media": "*",
|
|
63
69
|
"@dxtmisha/functional": "*",
|
|
64
|
-
"@dxtmisha/
|
|
70
|
+
"@dxtmisha/functional-basic": "*",
|
|
65
71
|
"@dxtmisha/wiki": "*",
|
|
66
|
-
"typescript": "
|
|
67
|
-
"vue": "
|
|
72
|
+
"typescript": "^5.0.0",
|
|
73
|
+
"vue": "^3.0.0"
|
|
68
74
|
},
|
|
69
75
|
"dependencies": {}
|
|
70
76
|
}
|
|
@@ -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
|
*
|
|
@@ -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
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as functional from '@dxtmisha/functional'
|
|
2
|
+
|
|
3
|
+
import { PropertiesFile } from '../Properties/PropertiesFile'
|
|
4
|
+
|
|
5
|
+
import { UI_DIRS_LIBRARY } from '../../config'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A class for building the functional library exports.
|
|
9
|
+
*
|
|
10
|
+
* Класс для сборки экспортов функциональной библиотеки.
|
|
11
|
+
*/
|
|
12
|
+
export class BuildFunctional {
|
|
13
|
+
constructor() {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generates the functional.ts file by re-exporting all members from @dxtmisha/functional.
|
|
18
|
+
*
|
|
19
|
+
* Генерирует файл functional.ts, повторно экспортируя все элементы из @dxtmisha/functional.
|
|
20
|
+
*/
|
|
21
|
+
make(): void {
|
|
22
|
+
console.log('Build functional...')
|
|
23
|
+
|
|
24
|
+
const list = this.getList()
|
|
25
|
+
const code: string[] = [
|
|
26
|
+
'export type * from \'@dxtmisha/functional\'',
|
|
27
|
+
''
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
list.sort()
|
|
31
|
+
list.forEach((item) => {
|
|
32
|
+
console.log(`-- ${item}`)
|
|
33
|
+
|
|
34
|
+
code.push(`export { ${item} } from '@dxtmisha/functional'`)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
code.push('')
|
|
38
|
+
PropertiesFile.writeByPath(
|
|
39
|
+
[...UI_DIRS_LIBRARY, 'functional.ts'],
|
|
40
|
+
code.join('\n')
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
console.log('...end')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns a list of all exported members from the @dxtmisha/functional package.
|
|
48
|
+
*
|
|
49
|
+
* Возвращает список всех экспортируемых элементов из пакета @dxtmisha/functional.
|
|
50
|
+
*/
|
|
51
|
+
getList(): string[] {
|
|
52
|
+
return Object.keys(functional)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -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
|
+
})
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import { dirname } from 'node:path'
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
5
|
-
import { toArray } from '@dxtmisha/functional-basic'
|
|
5
|
+
import { toArray, toCamelCase, toCamelCaseFirst, toKebabCase } from '@dxtmisha/functional-basic'
|
|
6
6
|
import { hasNativeDirname } from '../../functions/hasNativeDirname'
|
|
7
|
+
import { getPackageJson } from '../../functions/getPackageJson'
|
|
7
8
|
|
|
8
9
|
import { PropertiesConfig } from '../Properties/PropertiesConfig'
|
|
9
10
|
import { PropertiesFile } from '../Properties/PropertiesFile'
|
|
10
11
|
import { DesignStructure } from './DesignStructure'
|
|
11
12
|
import { DesignReplace } from './DesignReplace'
|
|
12
13
|
|
|
13
|
-
import { UI_KEY_CONSTRUCTOR } from '../../config'
|
|
14
|
+
import { UI_FILE_PACKAGE, UI_KEY_CONSTRUCTOR } from '../../config'
|
|
14
15
|
|
|
15
16
|
const dirnamePath = hasNativeDirname()
|
|
16
17
|
? __dirname
|
|
@@ -19,9 +20,11 @@ const dirnamePath = hasNativeDirname()
|
|
|
19
20
|
const DIR_SAMPLE = [dirnamePath, '..', '..', 'media', 'templates']
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
|
-
* 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.
|
|
23
25
|
*
|
|
24
|
-
* Базовый абстрактный класс для генерации файлов
|
|
26
|
+
* Базовый абстрактный класс для генерации файлов скриптов и компонентов дизайн-системы.
|
|
27
|
+
* Обеспечивает единую логику чтения шаблонов, трансформации данных и записи файлов.
|
|
25
28
|
*/
|
|
26
29
|
export abstract class DesignCommand {
|
|
27
30
|
protected abstract DIR_SAMPLE: string
|
|
@@ -30,11 +33,12 @@ export abstract class DesignCommand {
|
|
|
30
33
|
protected structure?: DesignStructure
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
|
-
* Constructor
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
+
* Constructor for DesignCommand.
|
|
37
|
+
*
|
|
38
|
+
* Конструктор для DesignCommand.
|
|
39
|
+
* @param command component name or command identifier / название компонента или идентификатор команды
|
|
40
|
+
* @param options additional key-value parameters / дополнительные параметры ключ-значение
|
|
36
41
|
*/
|
|
37
|
-
|
|
38
42
|
protected constructor(
|
|
39
43
|
protected readonly command: string,
|
|
40
44
|
protected readonly options: Record<string, string> = {}
|
|
@@ -42,9 +46,11 @@ export abstract class DesignCommand {
|
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
/**
|
|
45
|
-
*
|
|
49
|
+
* Main entry point for executing the command.
|
|
50
|
+
* Validates input and triggers the primary initialization logic.
|
|
46
51
|
*
|
|
47
|
-
*
|
|
52
|
+
* Основная точка входа для выполнения команды.
|
|
53
|
+
* Проверяет входные данные и запускает основную логику инициализации.
|
|
48
54
|
*/
|
|
49
55
|
make(): void {
|
|
50
56
|
if (this.command) {
|
|
@@ -84,6 +90,26 @@ export abstract class DesignCommand {
|
|
|
84
90
|
return this.command
|
|
85
91
|
}
|
|
86
92
|
|
|
93
|
+
protected getName(): string {
|
|
94
|
+
return toCamelCaseFirst(this.getCommand())
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected getNameMin(): string {
|
|
98
|
+
return toCamelCase(this.getCommand())
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected getCode(): string {
|
|
102
|
+
return toKebabCase(this.getCommand())
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected getFullName(): string {
|
|
106
|
+
return toCamelCaseFirst(`${PropertiesConfig.getDesignName()}-${this.getCommand()}`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
protected getProjectName(): string {
|
|
110
|
+
return toCamelCaseFirst(PropertiesConfig.getProjectName())
|
|
111
|
+
}
|
|
112
|
+
|
|
87
113
|
/**
|
|
88
114
|
* Returns a structure object.
|
|
89
115
|
*
|
|
@@ -180,6 +206,35 @@ export abstract class DesignCommand {
|
|
|
180
206
|
)
|
|
181
207
|
}
|
|
182
208
|
|
|
209
|
+
protected updatePackage(
|
|
210
|
+
namePath: string,
|
|
211
|
+
value: any
|
|
212
|
+
): this {
|
|
213
|
+
const packageFile = getPackageJson()
|
|
214
|
+
let focus: Record<string, any> | any | undefined = packageFile
|
|
215
|
+
|
|
216
|
+
if (packageFile && focus) {
|
|
217
|
+
const names = namePath.split('|')
|
|
218
|
+
const key = names.pop()
|
|
219
|
+
|
|
220
|
+
for (const name of names) {
|
|
221
|
+
if (!(name in focus)) {
|
|
222
|
+
focus[name] = {}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
focus = focus[name]
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (key) {
|
|
229
|
+
focus[key] = value
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
PropertiesFile.writeByPath(UI_FILE_PACKAGE, packageFile)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return this
|
|
236
|
+
}
|
|
237
|
+
|
|
183
238
|
/**
|
|
184
239
|
* Outputting data to the console.
|
|
185
240
|
*
|