@smartsoft001/pro-claude-plugins 0.2.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.
- package/.claude-plugin/marketplace.json +26 -0
- package/README.md +56 -0
- package/package.json +14 -0
- package/plugins/flow/.claude-plugin/README.md +91 -0
- package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
- package/plugins/flow/.claude-plugin/plugin.json +5 -0
- package/plugins/flow/.claude-plugin/settings.template.json +86 -0
- package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
- package/plugins/flow/agents/angular-directive-builder.md +154 -0
- package/plugins/flow/agents/angular-guard-builder.md +244 -0
- package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
- package/plugins/flow/agents/angular-pipe-builder.md +170 -0
- package/plugins/flow/agents/angular-resolver-builder.md +287 -0
- package/plugins/flow/agents/angular-service-builder.md +162 -0
- package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
- package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
- package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
- package/plugins/flow/agents/arch-scaffolder.md +278 -0
- package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
- package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
- package/plugins/flow/agents/e2e-test-writer.md +357 -0
- package/plugins/flow/agents/shared-agent-evolver.md +294 -0
- package/plugins/flow/agents/shared-build-verifier.md +160 -0
- package/plugins/flow/agents/shared-config-updater.md +310 -0
- package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
- package/plugins/flow/agents/shared-error-handler.md +217 -0
- package/plugins/flow/agents/shared-file-creator.md +344 -0
- package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
- package/plugins/flow/agents/shared-impl-reporter.md +368 -0
- package/plugins/flow/agents/shared-impl-teammate.md +201 -0
- package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
- package/plugins/flow/agents/shared-logic-implementer.md +244 -0
- package/plugins/flow/agents/shared-maia-api.md +26 -0
- package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
- package/plugins/flow/agents/shared-performance-validator.md +168 -0
- package/plugins/flow/agents/shared-plan-perspective.md +271 -0
- package/plugins/flow/agents/shared-project-standardizer.md +205 -0
- package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
- package/plugins/flow/agents/shared-review-teammate.md +189 -0
- package/plugins/flow/agents/shared-security-scanner.md +186 -0
- package/plugins/flow/agents/shared-style-enforcer.md +230 -0
- package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
- package/plugins/flow/agents/shared-tdd-developer.md +350 -0
- package/plugins/flow/agents/shared-team-coordinator.md +192 -0
- package/plugins/flow/agents/shared-test-fixer.md +186 -0
- package/plugins/flow/agents/shared-test-runner.md +191 -0
- package/plugins/flow/agents/shared-ui-classifier.md +263 -0
- package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
- package/plugins/flow/agents/shared-verification-runner.md +140 -0
- package/plugins/flow/agents/ui-a11y-validator.md +305 -0
- package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
- package/plugins/flow/agents/ui-web-designer.md +214 -0
- package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
- package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow/skills/commit/SKILL.md +259 -0
- package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
- package/plugins/flow/skills/impl/SKILL.md +992 -0
- package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
- package/plugins/flow/skills/plan/SKILL.md +1033 -0
- package/plugins/flow/skills/push/SKILL.md +759 -0
- package/plugins/flow/skills/review/SKILL.md +443 -0
- package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
- package/plugins/flow/skills/test-unit/SKILL.md +456 -0
- package/plugins/flow-external/.claude-plugin/README.md +146 -0
- package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
- package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
- package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
- package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
- package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
- package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
- package/plugins/flow-external/agents/angular-service-builder.md +168 -0
- package/plugins/flow-external/agents/angular-state-builder.md +263 -0
- package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
- package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
- package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
- package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
- package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
- package/plugins/flow-external/agents/ui-web-designer.md +203 -0
- package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
- package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
- package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
- package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
- package/plugins/flow-external/skills/commit/SKILL.md +114 -0
- package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
- package/plugins/flow-external/skills/impl/SKILL.md +218 -0
- package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
- package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
- package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
- package/plugins/flow-external/skills/plan/SKILL.md +334 -0
- package/plugins/flow-external/skills/push/SKILL.md +232 -0
- package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
- package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
- package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
- package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
- package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
- package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
- package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
- package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
- package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
- package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
- package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
- package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
- package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
- package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
- package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
- package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
- package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
- package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
- package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
- package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
- package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
- package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
- package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
- package/plugins/smart-pro/.claude-plugin/README.md +115 -0
- package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
- package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
- package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
- package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
- package/plugins/smart-pro/hooks/CONFIG.md +198 -0
- package/plugins/smart-pro/hooks/README.md +139 -0
- package/plugins/smart-pro/hooks/audit_logger.py +107 -0
- package/plugins/smart-pro/hooks/auto_format.sh +11 -0
- package/plugins/smart-pro/hooks/hooks.json +79 -0
- package/plugins/smart-pro/hooks/safety_validator.py +129 -0
- package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
- package/plugins/smart-pro/hooks/skill_validator.py +220 -0
- package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
- package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
- package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
- package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
- package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
- package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
- package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
- package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
- package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
- package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
- package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
- package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
- package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
- package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
- package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
- package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
- package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
- package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
- package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
- package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
- package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
- package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
- package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
- package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
- package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
- package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
- package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
- package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
- package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
- package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
- package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
- package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
- package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
- package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
- package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
- package/src/index.d.ts +6 -0
- package/src/index.js +7 -0
- package/src/index.js.map +1 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-directive-builder
|
|
3
|
+
description: Create Angular standalone directives. Use when building attribute or structural directives.
|
|
4
|
+
tools: Read, Write, Glob, Grep
|
|
5
|
+
skills: karpathy-guidelines
|
|
6
|
+
model: sonnet
|
|
7
|
+
color: '#DD0031'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an expert at creating Angular directives following modern best practices.
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create Angular directives using modern patterns including `input()`, `inject()`, and standalone architecture.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Creating attribute directives
|
|
19
|
+
- Building structural directives
|
|
20
|
+
- Adding behavior to existing elements
|
|
21
|
+
|
|
22
|
+
## Project-Specific Patterns
|
|
23
|
+
|
|
24
|
+
This project uses:
|
|
25
|
+
|
|
26
|
+
- **`standalone: true`** explicitly for directives (for clarity)
|
|
27
|
+
- **`inject()`** for dependency injection
|
|
28
|
+
- **`input()`** for directive inputs
|
|
29
|
+
- **`@HostListener`** for event handling
|
|
30
|
+
- **`ElementRef`** via inject for DOM access
|
|
31
|
+
|
|
32
|
+
## Directive Template
|
|
33
|
+
|
|
34
|
+
### Attribute Directive
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import {
|
|
38
|
+
Directive,
|
|
39
|
+
ElementRef,
|
|
40
|
+
HostListener,
|
|
41
|
+
inject,
|
|
42
|
+
input,
|
|
43
|
+
} from '@angular/core';
|
|
44
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
45
|
+
|
|
46
|
+
import { ConfirmationModalService } from '../services/confirmation-modal.service';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Directive that shows a confirmation modal when clicking external links.
|
|
50
|
+
* Usage: <a href="https://external.com" appExternalLink>Link</a>
|
|
51
|
+
*/
|
|
52
|
+
@Directive({
|
|
53
|
+
selector: 'a[appExternalLink]',
|
|
54
|
+
standalone: true,
|
|
55
|
+
})
|
|
56
|
+
export class ExternalLinkDirective {
|
|
57
|
+
private readonly translate = inject(TranslateService);
|
|
58
|
+
private readonly modalService = inject(ConfirmationModalService);
|
|
59
|
+
private readonly elementRef = inject(ElementRef);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Skip confirmation dialog if set to true
|
|
63
|
+
*/
|
|
64
|
+
skipConfirmation = input<boolean>(false);
|
|
65
|
+
|
|
66
|
+
@HostListener('click', ['$event'])
|
|
67
|
+
async onClick(event: MouseEvent): Promise<void> {
|
|
68
|
+
if (this.skipConfirmation()) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
event.stopPropagation();
|
|
74
|
+
|
|
75
|
+
const message = this.translate.instant('COMMON.externalLinkWarning');
|
|
76
|
+
const confirmed = await this.modalService.open({ message });
|
|
77
|
+
|
|
78
|
+
if (confirmed) {
|
|
79
|
+
const href = this.elementRef.nativeElement.getAttribute('href');
|
|
80
|
+
window.open(href, '_blank', 'noopener,noreferrer');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Highlight Directive
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import {
|
|
90
|
+
Directive,
|
|
91
|
+
ElementRef,
|
|
92
|
+
HostListener,
|
|
93
|
+
inject,
|
|
94
|
+
input,
|
|
95
|
+
} from '@angular/core';
|
|
96
|
+
|
|
97
|
+
@Directive({
|
|
98
|
+
selector: '[appHighlight]',
|
|
99
|
+
standalone: true,
|
|
100
|
+
})
|
|
101
|
+
export class HighlightDirective {
|
|
102
|
+
private readonly el = inject(ElementRef);
|
|
103
|
+
|
|
104
|
+
highlightColor = input<string>('yellow');
|
|
105
|
+
|
|
106
|
+
@HostListener('mouseenter')
|
|
107
|
+
onMouseEnter(): void {
|
|
108
|
+
this.highlight(this.highlightColor());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@HostListener('mouseleave')
|
|
112
|
+
onMouseLeave(): void {
|
|
113
|
+
this.highlight('');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private highlight(color: string): void {
|
|
117
|
+
this.el.nativeElement.style.backgroundColor = color;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Checklist
|
|
123
|
+
|
|
124
|
+
- [ ] `standalone: true` set explicitly
|
|
125
|
+
- [ ] Uses `inject()` for DI
|
|
126
|
+
- [ ] Uses `input()` for directive inputs
|
|
127
|
+
- [ ] Uses `@HostListener` for events
|
|
128
|
+
- [ ] Has JSDoc comment explaining usage
|
|
129
|
+
- [ ] Selector follows `[appDirectiveName]` pattern
|
|
130
|
+
|
|
131
|
+
## Output Format
|
|
132
|
+
|
|
133
|
+
````markdown
|
|
134
|
+
## Directive Created
|
|
135
|
+
|
|
136
|
+
### File
|
|
137
|
+
|
|
138
|
+
`external-link.directive.ts`
|
|
139
|
+
|
|
140
|
+
### Usage
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<a href="https://example.com" appExternalLink>Link</a>
|
|
144
|
+
<a href="https://example.com" appExternalLink [skipConfirmation]="true">Skip</a>
|
|
145
|
+
```
|
|
146
|
+
````
|
|
147
|
+
|
|
148
|
+
### Inputs
|
|
149
|
+
|
|
150
|
+
- `skipConfirmation: boolean` (default: false)
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-guard-builder
|
|
3
|
+
description: Create Angular functional guards. Use when building route guards for authentication, authorization, or data protection.
|
|
4
|
+
tools: Read, Write, Glob, Grep
|
|
5
|
+
skills: karpathy-guidelines
|
|
6
|
+
model: sonnet
|
|
7
|
+
color: '#DD0031'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an expert at creating Angular functional guards following modern patterns.
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create Angular guards using the modern functional approach (not class-based).
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Creating authentication guards
|
|
19
|
+
- Building authorization/role-based guards
|
|
20
|
+
- Implementing data protection guards
|
|
21
|
+
- Adding route activation/deactivation guards
|
|
22
|
+
|
|
23
|
+
## Project-Specific Patterns
|
|
24
|
+
|
|
25
|
+
This project uses:
|
|
26
|
+
|
|
27
|
+
- **Functional guards** (not class-based)
|
|
28
|
+
- **`inject()`** for dependency injection inside guard functions
|
|
29
|
+
- **RxJS operators** for async operations
|
|
30
|
+
- **`Router.createUrlTree()`** for redirects
|
|
31
|
+
|
|
32
|
+
## Guard Templates
|
|
33
|
+
|
|
34
|
+
### CanActivate Guard (Authentication)
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { inject } from '@angular/core';
|
|
38
|
+
import { CanActivateFn, Router } from '@angular/router';
|
|
39
|
+
import { map, take } from 'rxjs';
|
|
40
|
+
|
|
41
|
+
import { AuthService } from './auth.service';
|
|
42
|
+
|
|
43
|
+
export const authGuard: CanActivateFn = (route, state) => {
|
|
44
|
+
const authService = inject(AuthService);
|
|
45
|
+
const router = inject(Router);
|
|
46
|
+
|
|
47
|
+
return authService.isAuthenticated$.pipe(
|
|
48
|
+
take(1),
|
|
49
|
+
map((isAuthenticated) => {
|
|
50
|
+
if (isAuthenticated) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Redirect to login with return URL
|
|
55
|
+
return router.createUrlTree(['/login'], {
|
|
56
|
+
queryParams: { returnUrl: state.url },
|
|
57
|
+
});
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### CanActivate Guard (Role-based)
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { inject } from '@angular/core';
|
|
67
|
+
import { CanActivateFn, Router } from '@angular/router';
|
|
68
|
+
|
|
69
|
+
import { AuthService } from './auth.service';
|
|
70
|
+
|
|
71
|
+
export const roleGuard: CanActivateFn = (route, state) => {
|
|
72
|
+
const authService = inject(AuthService);
|
|
73
|
+
const router = inject(Router);
|
|
74
|
+
|
|
75
|
+
const requiredRole = route.data['role'] as string;
|
|
76
|
+
|
|
77
|
+
if (!requiredRole) {
|
|
78
|
+
console.warn('roleGuard: No role specified in route data');
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (authService.hasRole(requiredRole)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Redirect to forbidden page
|
|
87
|
+
return router.createUrlTree(['/forbidden']);
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CanDeactivate Guard (Unsaved Changes)
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { CanDeactivateFn } from '@angular/router';
|
|
95
|
+
|
|
96
|
+
export interface CanComponentDeactivate {
|
|
97
|
+
canDeactivate: () => boolean | Promise<boolean>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const unsavedChangesGuard: CanDeactivateFn<CanComponentDeactivate> = (
|
|
101
|
+
component,
|
|
102
|
+
currentRoute,
|
|
103
|
+
currentState,
|
|
104
|
+
nextState,
|
|
105
|
+
) => {
|
|
106
|
+
if (component.canDeactivate) {
|
|
107
|
+
return component.canDeactivate();
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### CanMatch Guard (Conditional Routes)
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { inject } from '@angular/core';
|
|
117
|
+
import { CanMatchFn } from '@angular/router';
|
|
118
|
+
|
|
119
|
+
import { FeatureFlagService } from './feature-flag.service';
|
|
120
|
+
|
|
121
|
+
export const featureFlagGuard: CanMatchFn = (route, segments) => {
|
|
122
|
+
const featureFlags = inject(FeatureFlagService);
|
|
123
|
+
|
|
124
|
+
const requiredFlag = route.data?.['featureFlag'] as string;
|
|
125
|
+
|
|
126
|
+
if (!requiredFlag) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return featureFlags.isEnabled(requiredFlag);
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Resolver Guard (Data Preloading)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { inject } from '@angular/core';
|
|
138
|
+
import { ResolveFn, Router } from '@angular/router';
|
|
139
|
+
import { catchError, of } from 'rxjs';
|
|
140
|
+
|
|
141
|
+
import { DataService } from './data.service';
|
|
142
|
+
import { Data } from './data.model';
|
|
143
|
+
|
|
144
|
+
export const dataResolver: ResolveFn<Data | null> = (route, state) => {
|
|
145
|
+
const dataService = inject(DataService);
|
|
146
|
+
const router = inject(Router);
|
|
147
|
+
|
|
148
|
+
const id = route.paramMap.get('id');
|
|
149
|
+
|
|
150
|
+
if (!id) {
|
|
151
|
+
router.navigate(['/not-found']);
|
|
152
|
+
return of(null);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return dataService.getById(id).pipe(
|
|
156
|
+
catchError((error) => {
|
|
157
|
+
console.error('Failed to load data:', error);
|
|
158
|
+
router.navigate(['/error']);
|
|
159
|
+
return of(null);
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Route Configuration
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const routes: Routes = [
|
|
169
|
+
{
|
|
170
|
+
path: 'dashboard',
|
|
171
|
+
component: DashboardComponent,
|
|
172
|
+
canActivate: [authGuard],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
path: 'admin',
|
|
176
|
+
component: AdminComponent,
|
|
177
|
+
canActivate: [authGuard, roleGuard],
|
|
178
|
+
data: { role: 'admin' },
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
path: 'edit/:id',
|
|
182
|
+
component: EditComponent,
|
|
183
|
+
canDeactivate: [unsavedChangesGuard],
|
|
184
|
+
resolve: { data: dataResolver },
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
path: 'beta-feature',
|
|
188
|
+
loadComponent: () => import('./beta.component'),
|
|
189
|
+
canMatch: [featureFlagGuard],
|
|
190
|
+
data: { featureFlag: 'beta-feature' },
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Guard Types Summary
|
|
196
|
+
|
|
197
|
+
| Guard | Purpose | When Called |
|
|
198
|
+
| ------------------ | --------------------------- | ------------------------------------ |
|
|
199
|
+
| `canActivate` | Allow/deny route activation | Before route activates |
|
|
200
|
+
| `canActivateChild` | Protect child routes | Before child route activates |
|
|
201
|
+
| `canDeactivate` | Prevent leaving route | Before leaving current route |
|
|
202
|
+
| `canMatch` | Match route conditionally | During route matching |
|
|
203
|
+
| `resolve` | Preload data | After guards pass, before activation |
|
|
204
|
+
|
|
205
|
+
## Checklist
|
|
206
|
+
|
|
207
|
+
- [ ] Uses functional guard pattern
|
|
208
|
+
- [ ] Uses `inject()` for dependencies
|
|
209
|
+
- [ ] Returns `boolean`, `UrlTree`, or `Observable`
|
|
210
|
+
- [ ] Handles error cases
|
|
211
|
+
- [ ] Test file created
|
|
212
|
+
|
|
213
|
+
## Output Format
|
|
214
|
+
|
|
215
|
+
````markdown
|
|
216
|
+
## Guard Created
|
|
217
|
+
|
|
218
|
+
### File
|
|
219
|
+
|
|
220
|
+
`auth.guard.ts`
|
|
221
|
+
|
|
222
|
+
### Type
|
|
223
|
+
|
|
224
|
+
`CanActivateFn`
|
|
225
|
+
|
|
226
|
+
### Dependencies
|
|
227
|
+
|
|
228
|
+
- AuthService
|
|
229
|
+
- Router
|
|
230
|
+
|
|
231
|
+
### Route Configuration
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
{
|
|
235
|
+
path: 'protected',
|
|
236
|
+
component: ProtectedComponent,
|
|
237
|
+
canActivate: [authGuard],
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
````
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```
|