itube-specs 0.0.861 → 0.0.863
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/README.md
CHANGED
|
@@ -61,11 +61,15 @@ npm run lint # ESLint (гейтит на ноль варнингов)
|
|
|
61
61
|
npm run lint:fix # ESLint --fix
|
|
62
62
|
npm run lint:css # Stylelint по **/*.{scss,vue}
|
|
63
63
|
npm run lint:css:fix # Stylelint --fix
|
|
64
|
+
npm run check:themes # сверяет наборы имён токенов во всех темах
|
|
65
|
+
npm run check:styles # компилирует стили каждого SFC каждой темой (~1.5s)
|
|
64
66
|
npm run test # vitest однократно
|
|
65
67
|
npm run patch # npm version patch — бамп версии перед публикацией
|
|
66
68
|
```
|
|
67
69
|
|
|
68
70
|
Pre-commit (husky + lint-staged): на закоммиченных файлах прогоняются `eslint --fix` и `stylelint --fix`.
|
|
71
|
+
Если в коммите есть `assets/scss/themes/**`, гоняется `check:themes`; если любой `.vue` или `assets/scss/**` —
|
|
72
|
+
`check:styles`. Оба есть и в CI, в шаге Lint.
|
|
69
73
|
⚠️ **Шаблоны `.vue` не типизируются вообще.** Обычный `tsc` их не читает, а `vue-tsc` не подключён (накопился
|
|
70
74
|
бэклог ошибок в шаблонах, подключение — отдельная задача). Значит чистый `tsc` ничего не говорит про выражения
|
|
71
75
|
в шаблоне: арифметика над строковым union, неверный тип пропа, переименованное поле пройдут молча.
|
|
@@ -126,8 +130,15 @@ assets/scss/themes/dark/_theme.scss
|
|
|
126
130
|
`loadPaths`). Это точка пер-сайтовой темизации.
|
|
127
131
|
|
|
128
132
|
**Все токены обязаны быть во всех темах.** Отсутствующий токен — жёсткая ошибка Sass в момент, когда
|
|
129
|
-
тема выбрана, то есть падает вся сборка сайта, а не «поехал цвет».
|
|
130
|
-
|
|
133
|
+
тема выбрана, то есть падает вся сборка сайта, а не «поехал цвет». Это гейтит `npm run check:themes`
|
|
134
|
+
(pre-commit при правке тем + CI). Сверяются только верхнеуровневые `$name:`, поэтому начинка
|
|
135
|
+
`$surfaces` / `$button-variant-overrides` игнорируется — она по замыслу разная.
|
|
136
|
+
|
|
137
|
+
Паритет доказывает лишь то, что темы согласованы **между собой**. Токен, использованный в компоненте, но не
|
|
138
|
+
заведённый **ни в одной** теме, эту проверку пройдёт и всё равно уронит сборку — для этого есть
|
|
139
|
+
`npm run check:styles`: он достаёт каждый `<style lang="scss">`, приписывает тот же `@use`-префикс, что
|
|
140
|
+
подставляет приложение, и компилирует по разу на тему. То же, что делает Vite, — значит ловит и неизвестные
|
|
141
|
+
миксины, и неверные аргументы `@include`, и показывает, в какой теме падает.
|
|
131
142
|
|
|
132
143
|
Контекстные различия (контрол внутри попапа, вариант кнопки, зависящий от темы) решают миксины
|
|
133
144
|
`surface()` и `button-variant()` из `mixins/`: место объявляет себя, а значения даёт тема через карты
|
|
@@ -178,9 +189,9 @@ ad-конфиг), теперь читается из `runtimeConfig.public` (з
|
|
|
178
189
|
- **Компоненты** — `pathPrefix: true`: имя = папка + файл (`ui/icon.vue` → `<UiIcon>`), BEM-класс = kebab
|
|
179
190
|
тега. Корень папки — `index.vue` (или `main.vue`, если иначе имя было бы односложным).
|
|
180
191
|
- **`as const`** вместо `enum` — доменные наборы в `runtime/constants/`, тип через
|
|
181
|
-
`typeof X[keyof typeof X]
|
|
182
|
-
|
|
183
|
-
оборачивать. Подробнее — в [CLAUDE.md](./CLAUDE.md).
|
|
192
|
+
`typeof X[keyof typeof X]`, значения строковые. Enum остаётся в бандле, в опубликованном пакете
|
|
193
|
+
`import type` на нём ломается в рантайме, а там, где значение приходит из API/URL/куки, сырую строку
|
|
194
|
+
в него не положить. Фреймворковые union'ы не оборачивать. Подробнее — в [CLAUDE.md](./CLAUDE.md).
|
|
184
195
|
- **Стили** — co-location в `<style lang="scss">` без `scoped`, flat-BEM, только дизайн-токены.
|
|
185
196
|
`vars` и `mixins` **авто-инжектятся** через `additionalData` приложения, поэтому в блоке компонента
|
|
186
197
|
`@use` писать не надо. Сам `sass` в слое не установлен — SCSS компилируется внутри приложения, но
|
|
@@ -64,16 +64,18 @@ $surface-roles: (
|
|
|
64
64
|
|
|
65
65
|
$overrides: map.get($surfaces, $name);
|
|
66
66
|
|
|
67
|
-
@
|
|
68
|
-
|
|
67
|
+
@if $overrides {
|
|
68
|
+
@each $role, $value in $overrides {
|
|
69
|
+
$props: map.get($surface-roles, $role);
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
@if not $props {
|
|
72
|
+
@error 'surface(#{$name}): неизвестная роль `#{$role}`. Допустимые: #{map.keys($surface-roles)}';
|
|
73
|
+
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
@if $value {
|
|
76
|
+
@each $prop in $props {
|
|
77
|
+
#{$prop}: #{$value};
|
|
78
|
+
}
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -142,8 +142,7 @@
|
|
|
142
142
|
|
|
143
143
|
<script setup lang="ts">
|
|
144
144
|
import type { IVideoCard, IPlaylistCard, IProfileData } from '../../types';
|
|
145
|
-
import
|
|
146
|
-
import { AuthSteps, PlaylistStep } from '../../runtime';
|
|
145
|
+
import { AuthSteps, PlaylistStep, PlaylistType } from '../../runtime';
|
|
147
146
|
import { AuthorizationApiService } from '../../services/api/authorization.service';
|
|
148
147
|
|
|
149
148
|
const props = defineProps<{
|
|
@@ -167,7 +166,7 @@ const sharePlaylistCard = computed<IPlaylistCard>(() => ({
|
|
|
167
166
|
videosCount: props.items.length,
|
|
168
167
|
thumbUrls: props.items.slice(0, 4).map(item => item.thumbUrls || { webp: {} }),
|
|
169
168
|
created: 0,
|
|
170
|
-
playlistType:
|
|
169
|
+
playlistType: PlaylistType.Public,
|
|
171
170
|
}));
|
|
172
171
|
|
|
173
172
|
const { isAuthorized } = useUser(AuthorizationApiService);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itube-specs",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.863",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
"lint:fix": "eslint . --fix",
|
|
12
12
|
"lint:css": "stylelint \"**/*.{scss,vue}\" --max-warnings=0 --allow-empty-input",
|
|
13
13
|
"lint:css:fix": "stylelint \"**/*.{scss,vue}\" --fix --allow-empty-input",
|
|
14
|
+
"check:themes": "node scripts/check-themes.mjs",
|
|
15
|
+
"check:styles": "node scripts/check-styles.mjs",
|
|
14
16
|
"test": "NODE_OPTIONS='--no-warnings' vitest",
|
|
15
17
|
"prepare": "husky"
|
|
16
18
|
},
|
|
@@ -69,26 +71,27 @@
|
|
|
69
71
|
],
|
|
70
72
|
"devDependencies": {
|
|
71
73
|
"@intlify/eslint-plugin-vue-i18n": "^4.5.1",
|
|
72
|
-
"@nuxt/eslint": "
|
|
74
|
+
"@nuxt/eslint": "^1.16.0",
|
|
73
75
|
"@nuxt/icon": "1.15.0",
|
|
74
76
|
"@nuxt/test-utils": "^3.23.0",
|
|
75
77
|
"@nuxtjs/i18n": "9.5.6",
|
|
76
78
|
"@types/node": "^20.19.19",
|
|
77
|
-
"@vue/test-utils": "^2.4.
|
|
78
|
-
"eslint": "^9.
|
|
79
|
+
"@vue/test-utils": "^2.4.11",
|
|
80
|
+
"eslint": "^9.39.5",
|
|
79
81
|
"happy-dom": "^18.0.1",
|
|
80
82
|
"husky": "^9.1.7",
|
|
81
83
|
"lint-staged": "^17.0.7",
|
|
82
84
|
"nuxt": "^3.21.8",
|
|
83
85
|
"postcss-html": "^1.8.1",
|
|
86
|
+
"sass": "^1.102.0",
|
|
84
87
|
"stylelint": "^17.13.0",
|
|
85
88
|
"stylelint-config-standard-scss": "^17.0.0",
|
|
86
89
|
"typescript": "^5.9.3",
|
|
87
|
-
"vitest": "^3.2.
|
|
90
|
+
"vitest": "^3.2.7",
|
|
88
91
|
"vue": "3.5.17"
|
|
89
92
|
},
|
|
90
93
|
"dependencies": {
|
|
91
|
-
"@sentry/nuxt": "^10.
|
|
94
|
+
"@sentry/nuxt": "^10.69.0",
|
|
92
95
|
"@vueform/slider": "2.1.10",
|
|
93
96
|
"@vueuse/core": "12.8.2"
|
|
94
97
|
}
|
|
@@ -17,7 +17,7 @@ export class ServerApiHelper {
|
|
|
17
17
|
});
|
|
18
18
|
return response.data;
|
|
19
19
|
} catch (error: any) {
|
|
20
|
-
throw new Error(`Cannot fetch ${url}: ${error?.data ?? error?.message ?? error}
|
|
20
|
+
throw new Error(`Cannot fetch ${url}: ${error?.data ?? error?.message ?? error}`, { cause: error });
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|