@dxtmisha/scripts 0.9.0 → 0.10.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 (42) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/package.json +2 -1
  3. package/src/classes/Ai/AiClaudeAgent.ts +16 -0
  4. package/src/classes/Ai/AiClaudeAgentLite.ts +86 -0
  5. package/src/classes/Ai/AiClaudeCliLite.ts +29 -65
  6. package/src/classes/Ai/AiClaudeLite.ts +19 -7
  7. package/src/classes/Ai/AiGoogleCliLite.ts +27 -64
  8. package/src/classes/Ai/AiOpenAi.ts +26 -0
  9. package/src/classes/Ai/AiOpenAiLite.ts +107 -0
  10. package/src/classes/Ai/AiZAi.ts +17 -0
  11. package/src/classes/Ai/AiZAiLite.ts +26 -0
  12. package/src/classes/Ai/ApiTmp.ts +43 -0
  13. package/src/classes/Build/BuildPackages.ts +33 -7
  14. package/src/classes/Design/DesignComponent.ts +1 -1
  15. package/src/classes/Library/LibraryAiPromptItem.ts +36 -2
  16. package/src/composables/useAi.ts +15 -0
  17. package/src/config.ts +2 -0
  18. package/src/demo/ai.ts +10 -0
  19. package/src/library-ai.ts +4 -4
  20. package/src/library.ts +67 -54
  21. package/src/media/templates/componentDoc/materials/README.md +8 -0
  22. package/src/media/templates/componentDoc/materials/prompt.txt +28 -0
  23. package/src/media/templates/componentDoc/wiki/prompt.txt +21 -0
  24. package/src/media/templates/componentDoc/wiki/run.ts +2 -1
  25. package/src/media/templates/prompts/aiCodeGlobalPrompt.en.txt +19 -0
  26. package/src/media/templates/prompts/aiCodeGlobalPrompt.ru.txt +21 -0
  27. package/src/media/templates/prompts/componentPrompt.en.txt +71 -16
  28. package/src/media/templates/prompts/componentPrompt.ru.txt +71 -16
  29. package/src/types/configTypes.ts +9 -2
  30. package/src/classes/Component/__tests__/ComponentCreator.test.ts +0 -71
  31. package/src/classes/Component/__tests__/ComponentItem.test.ts +0 -71
  32. package/src/classes/Git/__tests__/GitRead.test.ts +0 -70
  33. package/src/composables/__tests__/useAi.test.ts +0 -75
  34. package/src/functions/__tests__/getComponentPaths.test.ts +0 -19
  35. package/src/functions/__tests__/getConfigAi.test.ts +0 -26
  36. package/src/functions/__tests__/getConstructorProperties.test.ts +0 -51
  37. package/src/functions/__tests__/getDirname.test.ts +0 -31
  38. package/src/functions/__tests__/getNameDirByPaths.test.ts +0 -40
  39. package/src/functions/__tests__/getPackageJson.test.ts +0 -34
  40. package/src/functions/__tests__/hasNativeDirname.test.ts +0 -18
  41. package/src/functions/__tests__/toPathStandardSep.test.ts +0 -31
  42. package/src/media/templates/componentDoc/figma/run-figma.ts +0 -26
@@ -52,27 +52,79 @@
52
52
  7. **Events (События)**:
53
53
  - Заголовок `## Events`
54
54
  - Для каждого события:
55
- - `### имяСобытия`
56
- - Описание, когда срабатывает.
55
+ - Заголовок `### \`имяСобытия\`` (имя события обязательно должно быть обернуто в обратные кавычки).
56
+ - Краткое текстовое описание того, когда событие срабатывает.
57
57
  - **Параметры:**
58
- - Список: `- `имя: тип` — описание`.
59
- - Пример кода (если событие сложное).
60
-
61
- 8. **Expose (Методы компонента)**:
58
+ - Заголовок: `**Параметры:**`
59
+ - Список: `- \`имяПараметра: типПараметра\` — описание параметра.`
60
+ - **Структура сложных типов (если применимо):**
61
+ - Заголовок: `**Структура TypeName:**` (или `**Структура TypeName:** такая же, как для события \`другоеСобытие\``, если они идентичны).
62
+ - Список: `- \`имяПоля: типПоля\` — описание поля.`
63
+ - **Пример кода (если событие сложное):**
64
+ - Примеры кода ОБЯЗАТЕЛЬНО должны быть обернуты в компонент Storybook `<Source />` вместо стандартного markdown-форматирования (три обратные кавычки). Не забудь добавить `import { Source } from '@storybook/addon-docs/blocks';` в самый верх MDX файла, если его там еще нет:
65
+ ```md
66
+ <Source
67
+ code={`
68
+ <script setup>
69
+ // пример кода здесь
70
+ </script>
71
+ `}
72
+ language="html"
73
+ />
74
+ ```
75
+
76
+ 8. **Expose (Публичные методы и свойства компонента)**:
62
77
  - Заголовок `## Expose`
63
- - Для каждого публичного метода (доступного через ref):
64
- - `### имяМетода()`
65
- - Описание действия.
66
- - **Возвращает:** `Тип` (или `void`).
78
+ - Внутри раздела выводи список публичных методов, реактивных ссылок (Refs) и вычисляемых свойств (Computed), доступных через ref компонента, в чистом маркированном формате сигнатур:
79
+ - Для методов: `- `имяМетода(имяПараметра: типПараметра): возвращаемыйТип` — Описание.`
80
+ - Для реактивных переменных/свойств: `- `имяСвойства: ТипСвойства` — Описание.`
81
+ - Стандартные типы возвращаемых значений: `boolean`, `void`, `Ref<any>`, `ComputedRef<any>` и т.д.
67
82
 
68
83
  9. **Slots (Слоты)**:
69
84
  - Заголовок `## Slots`
70
- - Для каждого слота:
71
- - `### имяСлота`
72
- - Описание назначения.
73
- - **Параметры (Scoped Props):**
74
- - Список: `- `имя: тип` — описание`.
75
- - Пример кода использования слота.
85
+ - Внутри раздела выводи список слотов в чистом маркированном формате сигнатур:
86
+ - Для слотов без параметров: `- `имяСлота: Тип` — Описание.`
87
+ - Для слотов с параметрами: `- `имяСлота(имяПараметра: типПараметра): Тип` — Описание.`
88
+ - Стандартный тип возвращаемого значения обычно `VNode` или `any`.
89
+
90
+ ### Вспомогательные стили Storybook (storybookStyle.scss):
91
+ При написании сценариев Storybook (`*.stories.ts`) и примеров кода в MDX-документации ОБЯЗАТЕЛЬНО используй предопределенные вспомогательные классы для демонстрации. Эти стили импортируются глобально и имеют префикс `.wiki-storybook-`. Избегай написания кастомных инлайн-стилей или новых CSS-классов для лейаута, позиционирования, заглушек или контейнеров. Используй следующие готовые классы:
92
+
93
+ - **Контейнеры и сетки**:
94
+ - `.wiki-storybook-container` — включает контейнерные запросы (`container-type: inline-size`).
95
+ - `.wiki-storybook-group` — CSS Grid сетка на 12 колонок (`grid-template-columns: repeat(12, 1fr)`) с отступом `8px`. Отлично подходит для демонстрации нескольких вариантов компонента.
96
+ - `.wiki-storybook-flex` — базовая flex-обертка (`display: flex; flex-wrap: wrap`) с отступом `8px`.
97
+ - `.wiki-storybook-flex-align-center` — flex-обертка с центрированием элементов по вертикали (`align-items: center`).
98
+ - `.wiki-storybook-flex-center` — полное центрирование элементов (горизонтальное и вертикальное) с отступом `8px`.
99
+ - `.wiki-storybook-flex-column` — вертикальный flex-контейнер (`display: flex; flex-direction: column`) с отступом `16px`.
100
+ - `.wiki-storybook-decreased` — уменьшает максимальную ширину блока до `72%`.
101
+ - `.wiki-storybook-decreasedX2` — адаптивно уменьшает ширину блока (`64%` на экранах `md`, `48%` на экранах `lg`).
102
+
103
+ - **Демонстрационные карточки (`.wiki-storybook-item`)**:
104
+ Используются для отображения компонентов внутри единого визуального блока (по умолчанию aspect-ratio `1/1`, рамка, скругление углов, скрытый overflow):
105
+ - `.wiki-storybook-item__label` — небольшая плавающая метка в левом верхнем углу (`font-size: 12px`, полупрозрачный размытый фон) для подписи вариаций. Класс `.wiki-storybook-item__label--static` делает метку статичной без абсолютного позиционирования.
106
+ - `&--padding` — добавляет стандартные внутренние отступы `16px`.
107
+ - `&--rectangle` — устанавливает соотношение сторон `16:9` и растягивает блок на все 12 колонок в сетке.
108
+ - `&--widescreen` — соотношение сторон `32:9`, растягивает блок на все 12 колонок в сетке.
109
+ - `&--compact` — соотношение сторон `64:9`, растягивает блок на все 12 колонок в сетке.
110
+ - `&--auto` — автоматическое соотношение сторон, растягивает блок на все 12 колонок в сетке.
111
+ - `&--squared--xs`, `&--squared--sm`, `&--squared--md`, `&--squared--lg`, `&--squared--max` — адаптивное управление шириной квадратных блоков. Например, `--squared--sm` занимает 6 колонок на мобильных, 4 колонки на планшетах (от 640px) и 2 колонки на десктопах (от 1024px).
112
+ - `&--center` — выравнивает содержимое по центру с помощью flex.
113
+ - `&--widthAuto` — устанавливает ширину `auto`.
114
+ - `&--overflowVisible` — сбрасывает `overflow: hidden` на `overflow: visible` (необходимо для выпадающих меню, модалок).
115
+ - `&--rtl` — включает режим отображения справа налево (Right-to-Left).
116
+
117
+ - **Тестовые компоненты и заглушки**:
118
+ - `.wiki-storybook-card` — тестовая карточка (ширина `320px`, скругления, рамка) для симуляции реального интерфейса:
119
+ - `.wiki-storybook-card__image` — обложка высотой 128px.
120
+ - `.wiki-storybook-card__content` — вертикальный flex-контейнер с отступами `16px` и расстоянием `16px`.
121
+ - `.wiki-storybook-card__label` — заголовок с размером шрифта `20px`.
122
+ - `.wiki-storybook-card__information` — серый текст описания (`14px`).
123
+ - `.wiki-storybook-card__actions` — горизонтальный контейнер для кнопок (`8px`).
124
+ - `.wiki-storybook-button` — кнопка-заглушка для обработки кликов. Модификаторы для статусных цветов: `&--success` (зеленый), `&--error` (красный), `&--warning` (желтый), `&--info` (синий).
125
+ - `.wiki-storybook-dummy` — визуальный блок-заглушка (`32px` высотой, полупрозрачный серый).
126
+ - Цвета: `&--color--blue`, `&--color--red`, `&--color--green`.
127
+ - Размеры (высота): `&--size--sm` (`64px`), `&--size--md` (`128px`), `&--size--lg` (`256px`).
76
128
 
77
129
  ### Инструкции:
78
130
  1. Изучи предоставленный код компонента (включая props, emits, slots, expose).
@@ -82,6 +134,9 @@
82
134
  3.2. Старайся сохранять оригинальные описания без изменений.
83
135
  4. Используй правильную терминологию (Props, Events, Slots, Expose).
84
136
  4.1. Все заголовки должны быть на языке [wikiLanguage].
137
+ 4.2. В сценариях Storybook и примерах MDX-кода вы ОБЯЗАНЫ использовать предопределенные классы-помощники разметки из `storybookStyle.scss` (описанные выше) вместо инлайн-стилей или кастомных блоков CSS.
138
+ 4.3. Ни при каких обстоятельствах не изменяй оригинальный код компонента, если об этом явно не попросили.
139
+ 4.4. Строго следуй всем правилам и инструкциям данного промпта. Никаких галлюцинаций: категорически запрещено придумывать, домысливать или добавлять несуществующие свойства (props), методы (expose), события (events), слоты (slots) или внешние зависимости.
85
140
  5. Не добавляй лишних введений или заключений, только MDX.
86
141
  6. Верни только полный MDX-код документации без какого-либо дополнительного текста, комментариев или форматирования markdown (```).
87
142
  7. Результат должен быть исключительно в виде текста (ответа), не прикрепляй никаких файлов.
@@ -1,5 +1,12 @@
1
1
  /** AI type for content generation / Тип ИИ для генерации контента */
2
- export type AiType = 'gemini' | 'gemini-cli'
2
+ export type AiType
3
+ = | 'claude'
4
+ | 'claude-cli'
5
+ | 'claude-agent'
6
+ | 'gemini'
7
+ | 'gemini-cli'
8
+ | 'openai'
9
+ | 'zai'
3
10
 
4
11
  /** Configuration structure for the design system UI project / Структура конфигурации для проекта дизайн-системы UI */
5
12
  export type DesignUiConfig = {
@@ -40,7 +47,7 @@ export type DesignUiConfig = {
40
47
  packagePrefix?: string
41
48
 
42
49
  /** AI type for generating content / Тип ИИ для генерации контента */
43
- aiType?: 'gemini'
50
+ aiType?: AiType
44
51
 
45
52
  /** AI model for generating content / Модель ИИ для генерации контента */
46
53
  aiModel?: string
@@ -1,71 +0,0 @@
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
- })
@@ -1,71 +0,0 @@
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
- })
@@ -1,70 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { GitRead } from '../GitRead'
3
- import { execSync } from 'node:child_process'
4
- import { PropertiesFile } from '../../Properties/PropertiesFile'
5
-
6
- vi.mock('node:child_process', () => ({
7
- execSync: vi.fn()
8
- }))
9
-
10
- vi.mock('../../Properties/PropertiesFile', () => ({
11
- PropertiesFile: {
12
- getTime: vi.fn()
13
- }
14
- }))
15
-
16
- describe('GitRead', () => {
17
- beforeEach(() => {
18
- vi.clearAllMocks()
19
- })
20
-
21
- it('getDirPrefix should return the result of git rev-parse', () => {
22
- vi.mocked(execSync).mockReturnValue('packages/scripts/' as any)
23
- const result = GitRead.getDirPrefix()
24
- expect(execSync).toHaveBeenCalledWith('git rev-parse --show-prefix', expect.anything())
25
- expect(result).toBe('packages/scripts/')
26
- })
27
-
28
- it('getFilesPath should return list of HEAD files', () => {
29
- vi.mocked(execSync).mockReturnValue('file1.ts\nfile2.ts\n' as any)
30
- const result = GitRead.getFilesPath()
31
- expect(result).toEqual(['file1.ts', 'file2.ts'])
32
- })
33
-
34
- it('getList should return files with metadata', () => {
35
- vi.mocked(execSync).mockImplementation((cmd: string) => {
36
- if (cmd.startsWith('git rev-parse')) return 'prefix/' as any
37
- if (cmd.startsWith('git ls-tree')) return 'file.ts\n' as any
38
- if (cmd.startsWith('git log')) return '2023-10-27 12:00:00 +0300' as any
39
- return '' as any
40
- })
41
-
42
- const result = GitRead.getList()
43
- expect(result[0]).toMatchObject({
44
- path: 'file.ts',
45
- pathFull: 'prefix/file.ts',
46
- date: expect.stringContaining('2023-10-27')
47
- })
48
- })
49
-
50
- it('getListPorcelain should parse git status and metadata', () => {
51
- vi.mocked(execSync).mockImplementation((cmd: string) => {
52
- if (cmd.startsWith('git rev-parse')) return 'prefix/' as any
53
- if (cmd.startsWith('git status')) return 'M file.ts\nA new.ts\n' as any
54
- return '' as any
55
- })
56
- vi.mocked(PropertiesFile.getTime).mockReturnValue('2023-10-27 12:00:00' as any)
57
-
58
- const result = GitRead.getListPorcelain()
59
- expect(result).toHaveLength(2)
60
- expect(result[0]).toMatchObject({
61
- path: 'file.ts',
62
- status: 'M'
63
- })
64
- })
65
-
66
- it('splitPath should correctly split string', () => {
67
- expect(GitRead.splitPath('a/b/c')).toEqual(['a', 'b', 'c'])
68
- expect(GitRead.splitPath('/a/b/')).toEqual(['a', 'b'])
69
- })
70
- })
@@ -1,75 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { useAi } from '../useAi'
3
- import { PropertiesConfig } from '../../classes/Properties/PropertiesConfig'
4
- import { AiGoogle } from '../../classes/Ai/AiGoogle'
5
- import { AiGoogleCli } from '../../classes/Ai/AiGoogleCli'
6
-
7
- vi.mock('../../classes/Properties/PropertiesConfig', () => ({
8
- PropertiesConfig: {
9
- getAiType: vi.fn()
10
- }
11
- }))
12
-
13
- vi.mock('../../classes/Ai/AiGoogle', () => {
14
- return {
15
- AiGoogle: vi.fn().mockImplementation(function () {
16
- return { name: 'AiGoogleInstance' }
17
- })
18
- }
19
- })
20
-
21
- vi.mock('../../classes/Ai/AiGoogleCli', () => {
22
- return {
23
- AiGoogleCli: vi.fn().mockImplementation(function () {
24
- return { name: 'AiGoogleCliInstance' }
25
- })
26
- }
27
- })
28
-
29
- describe('useAi', () => {
30
- beforeEach(() => {
31
- vi.clearAllMocks()
32
- })
33
-
34
- it('should return an instance of AiGoogle when the type is gemini', () => {
35
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('gemini')
36
- const mockInstance = { name: 'AiGoogleInstance' }
37
- vi.mocked(AiGoogle).mockImplementation(function () {
38
- return mockInstance as any
39
- })
40
-
41
- const result = useAi()
42
-
43
- expect(result).toEqual(mockInstance)
44
- expect(AiGoogle).toHaveBeenCalled()
45
- })
46
-
47
- it('should return an instance of AiGoogleCli when the type is gemini-cli', () => {
48
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('gemini-cli')
49
- const mockInstance = { name: 'AiGoogleCliInstance' }
50
- vi.mocked(AiGoogleCli).mockImplementation(function () {
51
- return mockInstance as any
52
- })
53
-
54
- const result = useAi()
55
-
56
- expect(result).toEqual(mockInstance)
57
- expect(AiGoogleCli).toHaveBeenCalled()
58
- })
59
-
60
- it('should return undefined for an unknown type', () => {
61
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue('unknown' as any)
62
-
63
- const result = useAi()
64
-
65
- expect(result).toBeUndefined()
66
- })
67
-
68
- it('should return undefined if no type is configured', () => {
69
- vi.mocked(PropertiesConfig.getAiType).mockReturnValue(undefined as any)
70
-
71
- const result = useAi()
72
-
73
- expect(result).toBeUndefined()
74
- })
75
- })
@@ -1,19 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { getComponentPaths } from '../getComponentPaths'
3
- import { UI_DIRS_COMPONENTS } from '../../config'
4
-
5
- describe('getComponentPaths', () => {
6
- it('should return an array containing UI_DIRS_COMPONENTS and the given path', () => {
7
- const path = 'test-component'
8
- const result = getComponentPaths(path)
9
-
10
- expect(result).toEqual([...UI_DIRS_COMPONENTS, path])
11
- })
12
-
13
- it('it should work with nested paths', () => {
14
- const path = 'nested/test-component'
15
- const result = getComponentPaths(path)
16
-
17
- expect(result).toEqual([...UI_DIRS_COMPONENTS, path])
18
- })
19
- })
@@ -1,26 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import { getConfigAi } from '../getConfigAi'
3
- import { PropertiesConfig } from '../../classes/Properties/PropertiesConfig'
4
-
5
- vi.mock('../../classes/Properties/PropertiesConfig', () => ({
6
- PropertiesConfig: {
7
- getAiKey: vi.fn(),
8
- getAiModel: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getConfigAi', () => {
13
- it('should return AI key and model from PropertiesConfig', () => {
14
- const mockKey = 'test-key'
15
- const mockModel = 'test-model'
16
-
17
- vi.mocked(PropertiesConfig.getAiKey).mockReturnValue(mockKey)
18
- vi.mocked(PropertiesConfig.getAiModel).mockReturnValue(mockModel)
19
-
20
- const result = getConfigAi()
21
-
22
- expect(result).toEqual([mockKey, mockModel])
23
- expect(PropertiesConfig.getAiKey).toHaveBeenCalled()
24
- expect(PropertiesConfig.getAiModel).toHaveBeenCalled()
25
- })
26
- })
@@ -1,51 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getConstructorProperties } from '../getConstructorProperties'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
- import { hasNativeDirname } from '../hasNativeDirname'
5
-
6
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
7
- PropertiesFile: {
8
- readFile: vi.fn()
9
- }
10
- }))
11
-
12
- vi.mock('../hasNativeDirname', () => ({
13
- hasNativeDirname: vi.fn()
14
- }))
15
-
16
- describe('getConstructorProperties', () => {
17
- beforeEach(() => {
18
- vi.clearAllMocks()
19
- })
20
-
21
- it('should return properties for given constructor names', () => {
22
- const mockItem = { some: 'property' }
23
- vi.mocked(hasNativeDirname).mockReturnValue(true)
24
- vi.mocked(PropertiesFile.readFile).mockReturnValue(mockItem)
25
-
26
- const result = getConstructorProperties(['Button', 'Input'])
27
-
28
- expect(result).toEqual({
29
- Button: mockItem,
30
- Input: mockItem
31
- })
32
- expect(PropertiesFile.readFile).toHaveBeenCalledTimes(2)
33
- })
34
-
35
- it('should return an empty object if no constructors found or error occurs', () => {
36
- vi.mocked(hasNativeDirname).mockReturnValue(true)
37
- vi.mocked(PropertiesFile.readFile).mockReturnValue(undefined)
38
-
39
- const result = getConstructorProperties(['NonExistent'])
40
-
41
- expect(result).toEqual({})
42
- })
43
-
44
- it('should handles non-native dirname environment', () => {
45
- vi.mocked(hasNativeDirname).mockReturnValue(false)
46
- vi.mocked(PropertiesFile.readFile).mockReturnValue({ status: 'ok' })
47
-
48
- const result = getConstructorProperties(['Button'])
49
- expect(result).toEqual({ Button: { status: 'ok' } })
50
- })
51
- })
@@ -1,31 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getDirname } from '../getDirname'
3
- import { hasNativeDirname } from '../hasNativeDirname'
4
-
5
- vi.mock('../hasNativeDirname', () => ({
6
- hasNativeDirname: vi.fn()
7
- }))
8
-
9
- // We can't easily mock import.meta.url or __dirname globally in a way that affects the module internally without ESM tricks,
10
- // but we can at least test that it calls the right path based on hasNativeDirname
11
- describe('getDirname', () => {
12
- beforeEach(() => {
13
- vi.clearAllMocks()
14
- })
15
-
16
- it('should return __dirname when hasNativeDirname is true', () => {
17
- vi.mocked(hasNativeDirname).mockReturnValue(true)
18
-
19
- // In a vitest environment with native support, __dirname should be defined
20
- // We expect it to not throw and return a string
21
- const result = getDirname()
22
- expect(typeof result).toBe('string')
23
- })
24
-
25
- it('should return a path via fileURLToPath when hasNativeDirname is false', () => {
26
- vi.mocked(hasNativeDirname).mockReturnValue(false)
27
-
28
- const result = getDirname()
29
- expect(typeof result).toBe('string')
30
- })
31
- })
@@ -1,40 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getNameDirByPaths } from '../getNameDirByPaths'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
-
5
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
6
- PropertiesFile: {
7
- splitForDir: vi.fn(),
8
- joinPath: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getNameDirByPaths', () => {
13
- beforeEach(() => {
14
- vi.clearAllMocks()
15
- })
16
-
17
- it('should return the last directory name from provided paths', () => {
18
- const mockPaths = ['src', 'components', 'button']
19
- const mockJoinedPath = 'src/components/button'
20
- const mockSplitDirs = ['src', 'components', 'button']
21
-
22
- vi.mocked(PropertiesFile.joinPath).mockReturnValue(mockJoinedPath)
23
- vi.mocked(PropertiesFile.splitForDir).mockReturnValue(mockSplitDirs)
24
-
25
- const result = getNameDirByPaths(mockPaths)
26
-
27
- expect(result).toBe('button')
28
- expect(PropertiesFile.joinPath).toHaveBeenCalledWith(mockPaths)
29
- expect(PropertiesFile.splitForDir).toHaveBeenCalledWith(mockJoinedPath)
30
- })
31
-
32
- it('should work with a single path segment', () => {
33
- const mockPaths = ['root']
34
- vi.mocked(PropertiesFile.joinPath).mockReturnValue('root')
35
- vi.mocked(PropertiesFile.splitForDir).mockReturnValue(['root'])
36
-
37
- const result = getNameDirByPaths(mockPaths)
38
- expect(result).toBe('root')
39
- })
40
- })
@@ -1,34 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { getPackageJson } from '../getPackageJson'
3
- import { PropertiesFile } from '../../classes/Properties/PropertiesFile'
4
- import { UI_FILE_PACKAGE } from '../../config'
5
-
6
- vi.mock('../../classes/Properties/PropertiesFile', () => ({
7
- PropertiesFile: {
8
- readFile: vi.fn()
9
- }
10
- }))
11
-
12
- describe('getPackageJson', () => {
13
- beforeEach(() => {
14
- vi.clearAllMocks()
15
- })
16
-
17
- it('should return package.json content via PropertiesFile.readFile', () => {
18
- const mockContent = { name: 'test-package', version: '1.0.0' }
19
- vi.mocked(PropertiesFile.readFile).mockReturnValue(mockContent)
20
-
21
- const result = getPackageJson()
22
-
23
- expect(result).toEqual(mockContent)
24
- expect(PropertiesFile.readFile).toHaveBeenCalledWith(UI_FILE_PACKAGE)
25
- })
26
-
27
- it('should return undefined if file reading fails', () => {
28
- vi.mocked(PropertiesFile.readFile).mockReturnValue(undefined)
29
-
30
- const result = getPackageJson()
31
-
32
- expect(result).toBeUndefined()
33
- })
34
- })
@@ -1,18 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { hasNativeDirname } from '../hasNativeDirname'
3
-
4
- describe('hasNativeDirname', () => {
5
- it('should return a boolean', () => {
6
- const result = hasNativeDirname()
7
- expect(typeof result).toBe('boolean')
8
- })
9
-
10
- it('it should return true if __dirname is defined', () => {
11
- // In vitest/node environment, __dirname is usually defined
12
- // We can't easily "un-define" it for a negative test without complex environment manipulation,
13
- // but we can verify it returns true if it's there
14
- if (typeof __dirname !== 'undefined') {
15
- expect(hasNativeDirname()).toBe(true)
16
- }
17
- })
18
- })