tool-snippets 0.0.12 → 0.0.13
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 +59 -40
- package/package.json +1 -1
- package/vscode/tool-frontend.code-snippets +123 -40
- package/webstorm/_tool-frontend.xml +53 -13
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ npm run SNIPPETS:vscode
|
|
|
36
36
|
|
|
37
37
|
## Использование
|
|
38
38
|
|
|
39
|
-
В редакторе начните вводить префикс сниппета (например `tool-
|
|
39
|
+
В редакторе начните вводить префикс сниппета (например `tool-global-debugger`, `tool-global-forEach`, `tool-watch-subscribe`) — IntelliSense предложит подстановку.
|
|
40
40
|
|
|
41
41
|
## Структура пакета
|
|
42
42
|
|
|
@@ -73,51 +73,70 @@ npm publish
|
|
|
73
73
|
|
|
74
74
|
### Группы
|
|
75
75
|
|
|
76
|
-
**1. `tool-
|
|
76
|
+
**1. `tool-type-*` — объявления типов (`type`, `interface`)**
|
|
77
|
+
- `tool-type-pickPartialOmit`, `tool-type-keyof`, `tool-type-nullable`, `tool-type-partial`, `tool-type-never`, `tool-type-readonly`
|
|
78
|
+
|
|
79
|
+
**2. `tool-ng-*` — Angular (DI, ViewChild, get/set)**
|
|
80
|
+
- `tool-ng-injector`, `tool-ng-viewChild`, `tool-ng-viewChildEl`, `tool-ng-getset`, `tool-ng-getset-input`
|
|
81
|
+
|
|
82
|
+
**3. `tool-hook-*` — хуки жизненного цикла Angular**
|
|
77
83
|
- `tool-hook-onChanges`, `tool-hook-onInit`, `tool-hook-afterViewInit`, `tool-hook-onDestroy`
|
|
78
84
|
|
|
79
|
-
**
|
|
80
|
-
- `tool-
|
|
85
|
+
**4. `tool-watch-*` — подписки и наблюдение (Observable, Proxy)**
|
|
86
|
+
- `tool-watch-subscribe`, `tool-watch-proxy`
|
|
81
87
|
|
|
82
|
-
**
|
|
83
|
-
- `tool-
|
|
88
|
+
**5. `tool-const-*` — константы и типизированные объекты (`as const`, `Record`, `satisfies`)**
|
|
89
|
+
- `tool-const-asConst`, `tool-const-record`, `tool-const-recordSatisfies`
|
|
90
|
+
|
|
91
|
+
**6. `tool-comm-*` — общие конструкции (try/catch, await-try)**
|
|
92
|
+
- `tool-comm-try`, `tool-comm-try-await`
|
|
93
|
+
|
|
94
|
+
**7. `tool-width-*` — ширина страницы (`--tool-page-width`)**
|
|
95
|
+
- `tool-width-wrapper`, `tool-width-css`, `tool-width-state`
|
|
96
|
+
|
|
97
|
+
**8. `tool-theme-*` — темизация (`ThemeModule`)**
|
|
98
|
+
- `tool-theme-send`, `tool-theme-directive`, `tool-theme-module`
|
|
84
99
|
|
|
85
|
-
**
|
|
86
|
-
- `tool-
|
|
100
|
+
**9. `tool-global-*` — общее (массивы, ветвления, глобальные объекты, глобальные ошибки)**
|
|
101
|
+
- `tool-global-forEach`, `tool-global-switch`, `tool-global-switch-never`, `tool-global-window`, `tool-global-errors`, `tool-global-debugger`
|
|
87
102
|
|
|
88
|
-
**5. `tool-global-*` — общее (массивы, ветвления, глобальные объекты, глобальные ошибки)**
|
|
89
|
-
- `tool-global-forEach`, `tool-global-switch`, `tool-global-switch-never`, `tool-global-window`, `tool-global-errors`
|
|
90
103
|
|
|
91
104
|
## Примеры сниппетов
|
|
92
105
|
|
|
93
|
-
| Префикс
|
|
94
|
-
|
|
95
|
-
| `tool-hook-onChanges`
|
|
96
|
-
| `tool-hook-onInit`
|
|
97
|
-
| `tool-hook-afterViewInit`
|
|
98
|
-
| `tool-hook-onDestroy`
|
|
99
|
-
| `tool-ng-
|
|
100
|
-
| `tool-ng-
|
|
101
|
-
| `tool-ng-
|
|
102
|
-
| `tool-ng-
|
|
103
|
-
| `tool-ng-getset`
|
|
104
|
-
| `tool-
|
|
105
|
-
| `tool-type-
|
|
106
|
-
| `tool-type-
|
|
107
|
-
| `tool-type-
|
|
108
|
-
| `tool-type-
|
|
109
|
-
| `tool-type-
|
|
110
|
-
| `tool-
|
|
111
|
-
| `tool-
|
|
112
|
-
| `tool-
|
|
113
|
-
| `tool-
|
|
114
|
-
| `tool-
|
|
115
|
-
| `tool-
|
|
116
|
-
| `tool-
|
|
117
|
-
| `tool-global-forEach`
|
|
118
|
-
| `tool-global-switch`
|
|
119
|
-
| `tool-global-switch-never`
|
|
120
|
-
| `tool-global-window`
|
|
121
|
-
| `tool-global-errors`
|
|
122
|
-
| `tool-global-debugger`
|
|
106
|
+
| Префикс | Описание |
|
|
107
|
+
|------------------------------|---|
|
|
108
|
+
| `tool-hook-onChanges` | хук `ngOnChanges` |
|
|
109
|
+
| `tool-hook-onInit` | хук `ngOnInit` |
|
|
110
|
+
| `tool-hook-afterViewInit` | хук `ngAfterViewInit` |
|
|
111
|
+
| `tool-hook-onDestroy` | хук `ngOnDestroy` |
|
|
112
|
+
| `tool-ng-injector` | сервис через `Injector` |
|
|
113
|
+
| `tool-ng-viewChild` | `@ViewChild` (компонент) |
|
|
114
|
+
| `tool-ng-viewChildEl` | `@ViewChild` (ElementRef) |
|
|
115
|
+
| `tool-ng-getset` | getter/setter |
|
|
116
|
+
| `tool-ng-getset-input` | getter/setter с `@Input()` |
|
|
117
|
+
| `tool-type-pickPartialOmit` | `Pick & Partial<Omit>` |
|
|
118
|
+
| `tool-type-keyof` | `keyof` |
|
|
119
|
+
| `tool-type-nullable` | `TNullable<T>` |
|
|
120
|
+
| `tool-type-partial` | `Partial<T>` |
|
|
121
|
+
| `tool-type-never` | `switch` + `never` (exhaustive check) |
|
|
122
|
+
| `tool-type-readonly` | interface с `readonly` |
|
|
123
|
+
| `tool-const-asConst` | объект `as const` |
|
|
124
|
+
| `tool-const-record` | `Record<K, V>` + `as const` |
|
|
125
|
+
| `tool-const-recordSatisfies` | `as const satisfies Record` |
|
|
126
|
+
| `tool-comm-try` | блок `try-catch-finally` |
|
|
127
|
+
| `tool-comm-try-await` | tryCatch для promise |
|
|
128
|
+
| `tool-watch-subscribe` | подписка на Observable с `takeUntil` |
|
|
129
|
+
| `tool-watch-proxy` | Proxy-логирование изменений |
|
|
130
|
+
| `tool-global-forEach` | forEach по массиву |
|
|
131
|
+
| `tool-global-switch` | `switch` блок |
|
|
132
|
+
| `tool-global-switch-never` | `switch` + `never` |
|
|
133
|
+
| `tool-global-window` | declare global window |
|
|
134
|
+
| `tool-global-errors` | global error listeners |
|
|
135
|
+
| `tool-global-debugger` | `debugger;` |
|
|
136
|
+
| `tool-width-wrapper` | привязка `wrapperRef` для `--tool-page-width` |
|
|
137
|
+
| `tool-width-css` | CSS-правило с `var(--tool-page-width)` |
|
|
138
|
+
| `tool-width-state` | подписка на `ToolScreenService.state$` |
|
|
139
|
+
| `tool-theme-send` | `ThemeLighthouse.send$()` + подписка |
|
|
140
|
+
| `tool-theme-directive` | HTML с `[themeClass]` |
|
|
141
|
+
| `tool-theme-module` | импорт `ThemeModule` |
|
|
123
142
|
```
|
package/package.json
CHANGED
|
@@ -59,34 +59,6 @@
|
|
|
59
59
|
"description": "хук, вызывается перед уничтожением компонента - при уничтожении",
|
|
60
60
|
"scope": "javascript,typescript"
|
|
61
61
|
},
|
|
62
|
-
"tool-ng-subscribe": {
|
|
63
|
-
"prefix": "tool-ng-subscribe",
|
|
64
|
-
"body": [
|
|
65
|
-
"// --------------------------------------",
|
|
66
|
-
"import { OnDestroy } from '@angular/core';",
|
|
67
|
-
"import { Subject } from 'rxjs/Subject';",
|
|
68
|
-
"import { takeUntil } from 'rxjs/operators';",
|
|
69
|
-
"// --------------------------------------",
|
|
70
|
-
"private _destroyedSubscribe$: Subject<void> = new Subject<void>();",
|
|
71
|
-
"// --------------------------------------",
|
|
72
|
-
" $1",
|
|
73
|
-
" .pipe(takeUntil(this._destroyedSubscribe$))",
|
|
74
|
-
" .subscribe({",
|
|
75
|
-
" next: (result) => { console.log('result', result); },",
|
|
76
|
-
" error: (err) => { console.error('Ошибка:', err); // здесь можно показать уведомление или выполнить fallback-логику },",
|
|
77
|
-
" complete: () => { console.log('Поток завершён'); }",
|
|
78
|
-
" });",
|
|
79
|
-
"// --------------------------------------",
|
|
80
|
-
"public ngOnDestroy(): void {",
|
|
81
|
-
" this._destroyedSubscribe$.next();",
|
|
82
|
-
" this._destroyedSubscribe$.complete();",
|
|
83
|
-
"}",
|
|
84
|
-
"// --------------------------------------",
|
|
85
|
-
"$0"
|
|
86
|
-
],
|
|
87
|
-
"description": "подписка на Observable и автоматическая отписка при уничтожении компонента (ngOnDestroy).",
|
|
88
|
-
"scope": "javascript,typescript"
|
|
89
|
-
},
|
|
90
62
|
"tool-ng-injector": {
|
|
91
63
|
"prefix": "tool-ng-injector",
|
|
92
64
|
"body": [
|
|
@@ -243,14 +215,14 @@
|
|
|
243
215
|
"description": "Interface with readonly properties",
|
|
244
216
|
"scope": "javascript,typescript"
|
|
245
217
|
},
|
|
246
|
-
"tool-
|
|
247
|
-
"prefix": "tool-
|
|
218
|
+
"tool-const-asConst": {
|
|
219
|
+
"prefix": "tool-const-asConst",
|
|
248
220
|
"body": ["const obj = { $1: $2 } as const; // readonly", "$0"],
|
|
249
221
|
"description": "объект константа",
|
|
250
222
|
"scope": "javascript,typescript"
|
|
251
223
|
},
|
|
252
|
-
"tool-
|
|
253
|
-
"prefix": "tool-
|
|
224
|
+
"tool-const-record": {
|
|
225
|
+
"prefix": "tool-const-record",
|
|
254
226
|
"body": [
|
|
255
227
|
"// type UserId = 'id1' | 'id2' | 'id3';",
|
|
256
228
|
"// const users: Record<UserId, string> = { id1: 'Alice', id2: 'Bob', id3: 'Charlie' // id4: 'David' // ❌ ошибка: ключ не из UserId } as const;;",
|
|
@@ -260,8 +232,8 @@
|
|
|
260
232
|
"description": "типизация объектов через Record",
|
|
261
233
|
"scope": "javascript,typescript"
|
|
262
234
|
},
|
|
263
|
-
"tool-
|
|
264
|
-
"prefix": "tool-
|
|
235
|
+
"tool-const-recordSatisfies": {
|
|
236
|
+
"prefix": "tool-const-recordSatisfies",
|
|
265
237
|
"body": [
|
|
266
238
|
"// type UserId = 'id1' | 'id2' | 'id3';",
|
|
267
239
|
"// const users = { id1: 'Alice', id2: 'Bob', id3: 'Charlie' // id4: 'David' // ❌ ошибка: ключ не из UserId } as const satisfies Record<UserId, string>;",
|
|
@@ -271,8 +243,8 @@
|
|
|
271
243
|
"description": "константный объект с as const и satisfies Record",
|
|
272
244
|
"scope": "javascript,typescript"
|
|
273
245
|
},
|
|
274
|
-
"tool-
|
|
275
|
-
"prefix": "tool-
|
|
246
|
+
"tool-comm-try": {
|
|
247
|
+
"prefix": "tool-comm-try",
|
|
276
248
|
"body": [
|
|
277
249
|
"try {",
|
|
278
250
|
" $0",
|
|
@@ -285,8 +257,8 @@
|
|
|
285
257
|
"description": "обертка кода в блок try-catch-finally",
|
|
286
258
|
"scope": "javascript,typescript"
|
|
287
259
|
},
|
|
288
|
-
"tool-
|
|
289
|
-
"prefix": "tool-
|
|
260
|
+
"tool-comm-try-await": {
|
|
261
|
+
"prefix": "tool-comm-try-await",
|
|
290
262
|
"body": [
|
|
291
263
|
"private readonly awaitTryCatch = inject(AwaitTryCatchService);",
|
|
292
264
|
"await this.awaitTryCatch.send($1, $2)", "$0"
|
|
@@ -294,8 +266,8 @@
|
|
|
294
266
|
"description": "tryCatch для promise",
|
|
295
267
|
"scope": "javascript,typescript"
|
|
296
268
|
},
|
|
297
|
-
"tool-
|
|
298
|
-
"prefix": "tool-
|
|
269
|
+
"tool-watch-proxy": {
|
|
270
|
+
"prefix": "tool-watch-proxy",
|
|
299
271
|
"body": [
|
|
300
272
|
"public createProxyLog(target, onChange) {",
|
|
301
273
|
" // Обработка null и примитивов",
|
|
@@ -354,6 +326,34 @@
|
|
|
354
326
|
"description": "Функция создания Proxy Логирование",
|
|
355
327
|
"scope": "javascript,typescript"
|
|
356
328
|
},
|
|
329
|
+
"tool-watch-subscribe": {
|
|
330
|
+
"prefix": "tool-watch-subscribe",
|
|
331
|
+
"body": [
|
|
332
|
+
"// --------------------------------------",
|
|
333
|
+
"import { OnDestroy } from '@angular/core';",
|
|
334
|
+
"import { Subject } from 'rxjs/Subject';",
|
|
335
|
+
"import { takeUntil } from 'rxjs/operators';",
|
|
336
|
+
"// --------------------------------------",
|
|
337
|
+
"private _destroyedSubscribe$: Subject<void> = new Subject<void>();",
|
|
338
|
+
"// --------------------------------------",
|
|
339
|
+
" $1",
|
|
340
|
+
" .pipe(takeUntil(this._destroyedSubscribe$))",
|
|
341
|
+
" .subscribe({",
|
|
342
|
+
" next: (result) => { console.log('result', result); },",
|
|
343
|
+
" error: (err) => { console.error('Ошибка:', err); // здесь можно показать уведомление или выполнить fallback-логику },",
|
|
344
|
+
" complete: () => { console.log('Поток завершён'); }",
|
|
345
|
+
" });",
|
|
346
|
+
"// --------------------------------------",
|
|
347
|
+
"public ngOnDestroy(): void {",
|
|
348
|
+
" this._destroyedSubscribe$.next();",
|
|
349
|
+
" this._destroyedSubscribe$.complete();",
|
|
350
|
+
"}",
|
|
351
|
+
"// --------------------------------------",
|
|
352
|
+
"$0"
|
|
353
|
+
],
|
|
354
|
+
"description": "подписка на Observable и автоматическая отписка при уничтожении компонента (ngOnDestroy).",
|
|
355
|
+
"scope": "javascript,typescript"
|
|
356
|
+
},
|
|
357
357
|
"tool-global-forEach": {
|
|
358
358
|
"prefix": "tool-global-forEach",
|
|
359
359
|
"body": [
|
|
@@ -434,5 +434,88 @@
|
|
|
434
434
|
"body": ["debugger;"],
|
|
435
435
|
"description": "debugger",
|
|
436
436
|
"scope": "javascript,typescript"
|
|
437
|
+
},
|
|
438
|
+
"tool-width-wrapper": {
|
|
439
|
+
"prefix": "tool-width-wrapper",
|
|
440
|
+
"body": [
|
|
441
|
+
"// в компоненте инструмента: привязать корневой элемент",
|
|
442
|
+
"private readonly screen = inject(ToolScreenService);",
|
|
443
|
+
"private readonly host = inject(ElementRef<HTMLElement>);",
|
|
444
|
+
"",
|
|
445
|
+
"public ngAfterViewInit(): void {",
|
|
446
|
+
" this.screen.setWrapperRef(this.host);",
|
|
447
|
+
"}",
|
|
448
|
+
"$0"
|
|
449
|
+
],
|
|
450
|
+
"description": "ToolScreenService: привязать wrapperRef для --tool-page-width",
|
|
451
|
+
"scope": "javascript,typescript"
|
|
452
|
+
},
|
|
453
|
+
"tool-width-css": {
|
|
454
|
+
"prefix": "tool-width-css",
|
|
455
|
+
"body": [
|
|
456
|
+
".$1 {",
|
|
457
|
+
" width: var(--tool-page-width, 100%);",
|
|
458
|
+
"}",
|
|
459
|
+
"$0"
|
|
460
|
+
],
|
|
461
|
+
"description": "CSS: использовать --tool-page-width",
|
|
462
|
+
"scope": "css,scss"
|
|
463
|
+
},
|
|
464
|
+
"tool-width-state": {
|
|
465
|
+
"prefix": "tool-width-state",
|
|
466
|
+
"body": [
|
|
467
|
+
"public readonly screen = inject(ToolScreenService);",
|
|
468
|
+
"",
|
|
469
|
+
"public ngOnInit(): void {",
|
|
470
|
+
" this.screen.state$",
|
|
471
|
+
" .pipe(takeUntil(this._destroyed$))",
|
|
472
|
+
" .subscribe((info) => {",
|
|
473
|
+
" // info.screen.type / orientation / options",
|
|
474
|
+
" console.log(info.screen.type, info.screen.orientation);",
|
|
475
|
+
" });",
|
|
476
|
+
"}",
|
|
477
|
+
"$0"
|
|
478
|
+
],
|
|
479
|
+
"description": "ToolScreenService: подписка на state$ (для --tool-page-width)",
|
|
480
|
+
"scope": "javascript,typescript"
|
|
481
|
+
},
|
|
482
|
+
"tool-theme-send": {
|
|
483
|
+
"prefix": "tool-theme-send",
|
|
484
|
+
"body": [
|
|
485
|
+
"// отправка текущей темы",
|
|
486
|
+
"this.themeLighthouse.send$({ name: '$1' }, '$2');",
|
|
487
|
+
"// подписка на смену темы",
|
|
488
|
+
"this.themeLighthouse.lighthouse$",
|
|
489
|
+
" .pipe(takeUntil(this._destroyed$))",
|
|
490
|
+
" .subscribe((theme) => { console.log('theme', theme); });",
|
|
491
|
+
"$0"
|
|
492
|
+
],
|
|
493
|
+
"description": "ThemeLighthouse: отправить тему и подписаться на изменения",
|
|
494
|
+
"scope": "javascript,typescript"
|
|
495
|
+
},
|
|
496
|
+
"tool-theme-directive": {
|
|
497
|
+
"prefix": "tool-theme-directive",
|
|
498
|
+
"body": [
|
|
499
|
+
"<!-- в шаблоне: суффикс _theme к каждому базовому классу -->",
|
|
500
|
+
"<div [themeClass]=\"['$1']\"></div>",
|
|
501
|
+
"<!-- при теме dark → $1_dark -->",
|
|
502
|
+
"$0"
|
|
503
|
+
],
|
|
504
|
+
"description": "ThemeClassDirective: темизированные классы",
|
|
505
|
+
"scope": "html"
|
|
506
|
+
},
|
|
507
|
+
"tool-theme-module": {
|
|
508
|
+
"prefix": "tool-theme-module",
|
|
509
|
+
"body": [
|
|
510
|
+
"import { ThemeModule } from 'tool-screen-ang15';",
|
|
511
|
+
"",
|
|
512
|
+
"@NgModule({",
|
|
513
|
+
" imports: [ThemeModule],",
|
|
514
|
+
"})",
|
|
515
|
+
"export class $1 {}",
|
|
516
|
+
"$0"
|
|
517
|
+
],
|
|
518
|
+
"description": "Подключение ThemeModule",
|
|
519
|
+
"scope": "javascript,typescript"
|
|
437
520
|
}
|
|
438
521
|
}
|
|
@@ -26,13 +26,6 @@
|
|
|
26
26
|
<option name="TypeScript" value="true" />
|
|
27
27
|
</context>
|
|
28
28
|
</template>
|
|
29
|
-
<template name="tool-ng-subscribe" value="// -------------------------------------- import { OnDestroy } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { takeUntil } from 'rxjs/operators'; // -------------------------------------- private _destroyedSubscribe$: Subject<void> = new Subject<void>(); // -------------------------------------- $TEXT$ .pipe(takeUntil(this._destroyedSubscribe$)) .subscribe({ next: (result) => { console.log('result', result); }, error: (err) => { console.error('Ошибка:', err); // здесь можно показать уведомление или выполнить fallback-логику }, complete: () => { console.log('Поток завершён'); } }); // -------------------------------------- public ngOnDestroy(): void { this._destroyedSubscribe$.next(); this._destroyedSubscribe$.complete(); } // --------------------------------------" description="подписка на Observable и автоматическая отписка при уничтожении компонента (ngOnDestroy)." toReformat="false" toShortenFQNames="true">
|
|
30
|
-
<variable name="TEXT" expression="" defaultValue="" alwaysStopAt="true" />
|
|
31
|
-
<context>
|
|
32
|
-
<option name="JAVA_SCRIPT" value="true" />
|
|
33
|
-
<option name="TypeScript" value="true" />
|
|
34
|
-
</context>
|
|
35
|
-
</template>
|
|
36
29
|
<template name="tool-ng-injector" value="// в "рабочем компоненте" - public constructor(protected injector: Injector) { super(injector); } import { Injector, Type } from '@angular/core'; protected $INSTANS$: $SERVICE$; protected constructor( protected injector: Injector, ) { this.$INSTANS$ = injector.get<$SERVICE$>($SERVICE$ as Type<$SERVICE$>); }" description="Подключение сервиса в базовом компоненте через injector" toReformat="false" toShortenFQNames="true">
|
|
37
30
|
<variable name="INSTANS" expression="" defaultValue="" alwaysStopAt="true" />
|
|
38
31
|
<variable name="SERVICE" expression="" defaultValue="" alwaysStopAt="true" />
|
|
@@ -115,7 +108,7 @@
|
|
|
115
108
|
<option name="TypeScript" value="true" />
|
|
116
109
|
</context>
|
|
117
110
|
</template>
|
|
118
|
-
<template name="tool-
|
|
111
|
+
<template name="tool-const-asConst" value="const obj = { $PROP$: $VAL$} as const; // readonly" description="объект константа" toReformat="false" toShortenFQNames="true">
|
|
119
112
|
<variable name="PROP" expression="" defaultValue="" alwaysStopAt="true" />
|
|
120
113
|
<variable name="VAL" expression="" defaultValue="" alwaysStopAt="true" />
|
|
121
114
|
<context>
|
|
@@ -123,7 +116,7 @@
|
|
|
123
116
|
<option name="TypeScript" value="true" />
|
|
124
117
|
</context>
|
|
125
118
|
</template>
|
|
126
|
-
<template name="tool-
|
|
119
|
+
<template name="tool-const-record" value="// type UserId = 'id1' | 'id2' | 'id3'; // const users: Record<UserId, string> = { id1: 'Alice', id2: 'Bob', id3: 'Charlie' // id4: 'David' // ❌ ошибка: ключ не из UserId } as const;; const obj: Record<$PROP$, $VAL$> = {$END$} as const; // readonly" description="типизация объектов через Record" toReformat="false" toShortenFQNames="true">
|
|
127
120
|
<variable name="PROP" expression="" defaultValue="" alwaysStopAt="true" />
|
|
128
121
|
<variable name="VAL" expression="" defaultValue="" alwaysStopAt="true" />
|
|
129
122
|
<context>
|
|
@@ -131,7 +124,7 @@
|
|
|
131
124
|
<option name="TypeScript" value="true" />
|
|
132
125
|
</context>
|
|
133
126
|
</template>
|
|
134
|
-
<template name="tool-
|
|
127
|
+
<template name="tool-const-recordSatisfies" value="// type UserId = 'id1' | 'id2' | 'id3'; // const users = { id1: 'Alice', id2: 'Bob', id3: 'Charlie' // id4: 'David' // ❌ ошибка: ключ не из UserId } as const satisfies Record<UserId, string>; const obj = {$END$} as const satisfies Record<$KEY_TYPE$, $VALUE_TYPE$>;" description="константный объект с as const и satisfies Record" toReformat="false" toShortenFQNames="true">
|
|
135
128
|
<variable name="KEY_TYPE" expression="" defaultValue="" alwaysStopAt="true" />
|
|
136
129
|
<variable name="VALUE_TYPE" expression="" defaultValue="" alwaysStopAt="true" />
|
|
137
130
|
<context>
|
|
@@ -139,13 +132,13 @@
|
|
|
139
132
|
<option name="TypeScript" value="true" />
|
|
140
133
|
</context>
|
|
141
134
|
</template>
|
|
142
|
-
<template name="tool-
|
|
135
|
+
<template name="tool-comm-try" value="try { $END$ } catch (error) { console.error(error); } finally { // код, который выполнится всегда }" description="обертка кода в блок try-catch-finally" toReformat="false" toShortenFQNames="true">
|
|
143
136
|
<context>
|
|
144
137
|
<option name="JAVA_SCRIPT" value="true" />
|
|
145
138
|
<option name="TypeScript" value="true" />
|
|
146
139
|
</context>
|
|
147
140
|
</template>
|
|
148
|
-
<template name="tool-
|
|
141
|
+
<template name="tool-comm-try-await" value="private readonly awaitTryCatch = inject(AwaitTryCatchService); await this.awaitTryCatch.send($PROMISE$, $FROM$)" description="tryCatch для promise" toReformat="false" toShortenFQNames="true">
|
|
149
142
|
<variable name="PROMISE" expression="" defaultValue="" alwaysStopAt="true" />
|
|
150
143
|
<variable name="FROM" expression="" defaultValue="" alwaysStopAt="true" />
|
|
151
144
|
<context>
|
|
@@ -153,7 +146,14 @@
|
|
|
153
146
|
<option name="TypeScript" value="true" />
|
|
154
147
|
</context>
|
|
155
148
|
</template>
|
|
156
|
-
<template name="tool-
|
|
149
|
+
<template name="tool-watch-proxy" value="public createProxyLog(target, onChange) { // Обработка null и примитивов if (target === null || typeof target !== 'object') { return target; } return new Proxy(target, { set(obj, prop, value) { const oldValue = obj[prop]; // Рекурсивно обрабатываем новые объекты const newValue = this.createProxyLog(value, onChange); obj[prop] = newValue; // Проверяем реальное изменение (учитываем NaN) if (oldValue !== value && !(Number.isNaN(oldValue) && Number.isNaN(value))) { onChange(prop, newValue, oldValue); } return true; }, get(obj, prop) { const value = obj[prop]; // Рекурсивно создаем прокси для вложенных объектов if (value !== null && typeof value === 'object') { return this.createProxyLog(value, onChange); } return value; }, deleteProperty(obj, prop) { const oldValue = obj[prop]; const deleted = delete obj[prop]; if (deleted) { onChange(prop, undefined, oldValue); } return deleted; } }); } // Использование: //let state = this.createProxyLog( //{ user: { name: 'Alice', age: 30 } settings: { theme: 'dark', notifications: true } }, //(prop, value, oldValue) => { console.log(`Property "${prop}" changed: ${oldValue} → ${value}`); }); // // delete state.user.email; // Property "email" changed: alice@example.com → undefined" description="Функция создания Proxy Логирование" toReformat="false" toShortenFQNames="true">
|
|
150
|
+
<context>
|
|
151
|
+
<option name="JAVA_SCRIPT" value="true" />
|
|
152
|
+
<option name="TypeScript" value="true" />
|
|
153
|
+
</context>
|
|
154
|
+
</template>
|
|
155
|
+
<template name="tool-watch-subscribe" value="// -------------------------------------- import { OnDestroy } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { takeUntil } from 'rxjs/operators'; // -------------------------------------- private _destroyedSubscribe$: Subject<void> = new Subject<void>(); // -------------------------------------- $TEXT$ .pipe(takeUntil(this._destroyedSubscribe$)) .subscribe({ next: (result) => { console.log('result', result); }, error: (err) => { console.error('Ошибка:', err); // здесь можно показать уведомление или выполнить fallback-логику }, complete: () => { console.log('Поток завершён'); } }); // -------------------------------------- public ngOnDestroy(): void { this._destroyedSubscribe$.next(); this._destroyedSubscribe$.complete(); } // --------------------------------------" description="подписка на Observable и автоматическая отписка при уничтожении компонента (ngOnDestroy)." toReformat="false" toShortenFQNames="true">
|
|
156
|
+
<variable name="TEXT" expression="" defaultValue="" alwaysStopAt="true" />
|
|
157
157
|
<context>
|
|
158
158
|
<option name="JAVA_SCRIPT" value="true" />
|
|
159
159
|
<option name="TypeScript" value="true" />
|
|
@@ -208,4 +208,44 @@
|
|
|
208
208
|
<option name="TypeScript" value="true" />
|
|
209
209
|
</context>
|
|
210
210
|
</template>
|
|
211
|
+
<template name="tool-width-wrapper" value="// в компоненте инструмента: привязать корневой элемент private readonly screen = inject(ToolScreenService); private readonly host = inject(ElementRef<HTMLElement>); public ngAfterViewInit(): void { this.screen.setWrapperRef(this.host); }$END$" description="ToolScreenService: привязать wrapperRef для --tool-page-width" toReformat="false" toShortenFQNames="true">
|
|
212
|
+
<context>
|
|
213
|
+
<option name="JAVA_SCRIPT" value="true" />
|
|
214
|
+
<option name="TypeScript" value="true" />
|
|
215
|
+
</context>
|
|
216
|
+
</template>
|
|
217
|
+
<template name="tool-width-css" value=".$WRAPPER$ { width: var(--tool-page-width, 100%); }$END$" description="CSS: использовать --tool-page-width" toReformat="false" toShortenFQNames="true">
|
|
218
|
+
<variable name="WRAPPER" expression="" defaultValue=""tool-wrapper"" alwaysStopAt="true" />
|
|
219
|
+
<context>
|
|
220
|
+
<option name="CSS" value="true" />
|
|
221
|
+
<option name="SCSS" value="true" />
|
|
222
|
+
</context>
|
|
223
|
+
</template>
|
|
224
|
+
<template name="tool-width-state" value="public readonly screen = inject(ToolScreenService); public ngOnInit(): void { this.screen.state$ .pipe(takeUntil(this._destroyed$)) .subscribe((info) => { // info.screen.type / orientation / options console.log(info.screen.type, info.screen.orientation); }); }$END$" description="ToolScreenService: подписка на state$ (для --tool-page-width)" toReformat="false" toShortenFQNames="true">
|
|
225
|
+
<context>
|
|
226
|
+
<option name="JAVA_SCRIPT" value="true" />
|
|
227
|
+
<option name="TypeScript" value="true" />
|
|
228
|
+
</context>
|
|
229
|
+
</template>
|
|
230
|
+
<template name="tool-theme-send" value="// отправка текущей темы this.themeLighthouse.send$({ name: '$THEME$' }, '$FROM$'); // подписка на смену темы this.themeLighthouse.lighthouse$ .pipe(takeUntil(this._destroyed$)) .subscribe((theme) => { console.log('theme', theme); });$END$" description="ThemeLighthouse: отправить тему и подписаться на изменения" toReformat="false" toShortenFQNames="true">
|
|
231
|
+
<variable name="THEME" expression="" defaultValue=""dark"" alwaysStopAt="true" />
|
|
232
|
+
<variable name="FROM" expression="" defaultValue=""AppComponent"" alwaysStopAt="true" />
|
|
233
|
+
<context>
|
|
234
|
+
<option name="JAVA_SCRIPT" value="true" />
|
|
235
|
+
<option name="TypeScript" value="true" />
|
|
236
|
+
</context>
|
|
237
|
+
</template>
|
|
238
|
+
<template name="tool-theme-directive" value="<!-- в шаблоне: суффикс _theme к каждому базовому классу --> <div [themeClass]="['$BASE$']"></div> <!-- при теме dark → $BASE$_dark -->$END$" description="ThemeClassDirective: темизированные классы" toReformat="false" toShortenFQNames="true">
|
|
239
|
+
<variable name="BASE" expression="" defaultValue=""license-widget"" alwaysStopAt="true" />
|
|
240
|
+
<context>
|
|
241
|
+
<option name="HTML" value="true" />
|
|
242
|
+
</context>
|
|
243
|
+
</template>
|
|
244
|
+
<template name="tool-theme-module" value="import { ThemeModule } from 'tool-screen-ang15'; @NgModule({ imports: [ThemeModule], }) export class $MODULE$ {} $END$" description="Подключение ThemeModule" toReformat="false" toShortenFQNames="true">
|
|
245
|
+
<variable name="MODULE" expression="" defaultValue="AppModule" alwaysStopAt="true" />
|
|
246
|
+
<context>
|
|
247
|
+
<option name="JAVA_SCRIPT" value="true" />
|
|
248
|
+
<option name="TypeScript" value="true" />
|
|
249
|
+
</context>
|
|
250
|
+
</template>
|
|
211
251
|
</templateSet>
|