@angular-helpers/browser-web-apis 21.0.0 → 21.0.2
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
|
@@ -1,48 +1,49 @@
|
|
|
1
1
|
# @angular-helpers/browser-web-apis
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Angular services package for a structured and secure access layer over browser Web APIs.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Leer en espanol](./README.es.md)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **📱 Browser APIs**: Acceso unificado a APIs del navegador
|
|
9
|
-
- **⚡ Tree Shakable**: Solo incluye lo que usas
|
|
10
|
-
- **🛡️ Type Safe**: TypeScript completo
|
|
11
|
-
- **🔧 Modular**: Habilita solo lo que necesitas
|
|
12
|
-
- **📊 Reactive**: Signals y Observables
|
|
13
|
-
- **🔄 Lifecycle**: Gestión automática con destroyRef
|
|
7
|
+
## Features
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
- Integrated security with ReDoS prevention using Web Workers
|
|
10
|
+
- Unified browser API access through strongly typed services
|
|
11
|
+
- Tree-shakable architecture
|
|
12
|
+
- Modular provider setup to enable only what you need
|
|
13
|
+
- Reactive APIs with signals and observables
|
|
14
|
+
- Lifecycle-safe integration with `destroyRef`
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
- **CameraService** - Acceso a cámara con gestión de permisos
|
|
19
|
-
- **MediaDevicesService** - Enumeración y gestión de dispositivos multimedia
|
|
20
|
-
- **GeolocationService** - API de geolocalización
|
|
21
|
-
- **NotificationService** - Sistema de notificaciones
|
|
16
|
+
## Available Services
|
|
22
17
|
|
|
23
|
-
###
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- **ClipboardService** - Portapapeles del sistema
|
|
18
|
+
### Media and Device APIs
|
|
19
|
+
- `CameraService` - Camera access with permission handling
|
|
20
|
+
- `MediaDevicesService` - Media device listing and management
|
|
21
|
+
- `GeolocationService` - Geolocation API access
|
|
22
|
+
- `NotificationService` - Browser notifications API
|
|
29
23
|
|
|
30
|
-
###
|
|
31
|
-
-
|
|
32
|
-
-
|
|
24
|
+
### Web APIs
|
|
25
|
+
- `WebWorkerService` - Web Worker management
|
|
26
|
+
- `WebSocketService` - WebSocket connection handling
|
|
27
|
+
- `WebStorageService` - LocalStorage and SessionStorage helpers
|
|
28
|
+
- `WebShareService` - Native Web Share API support
|
|
29
|
+
- `ClipboardService` - System clipboard access
|
|
33
30
|
|
|
34
|
-
###
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- **MediaDeviceBaseService** - Clase base para dispositivos multimedia
|
|
31
|
+
### Security
|
|
32
|
+
- `RegexSecurityService` - ReDoS prevention with worker-based validation
|
|
33
|
+
- `PermissionsService` - Centralized browser permissions handling
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
### Utilities
|
|
36
|
+
- `CameraPermissionHelperService` - Camera permission helper utilities
|
|
37
|
+
- `BrowserApiBaseService` - Shared base class for browser API services
|
|
38
|
+
- `MediaDeviceBaseService` - Shared base class for media device services
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
40
41
|
|
|
41
42
|
```bash
|
|
42
43
|
npm install @angular-helpers/browser-web-apis
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
##
|
|
46
|
+
## Quick Setup
|
|
46
47
|
|
|
47
48
|
```typescript
|
|
48
49
|
import { provideBrowserWebApis } from '@angular-helpers/browser-web-apis';
|
|
@@ -52,15 +53,15 @@ bootstrapApplication(AppComponent, {
|
|
|
52
53
|
provideBrowserWebApis({
|
|
53
54
|
enableCamera: true,
|
|
54
55
|
enableGeolocation: true,
|
|
55
|
-
enableRegexSecurity: true
|
|
56
|
-
})
|
|
57
|
-
]
|
|
56
|
+
enableRegexSecurity: true,
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
58
59
|
});
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
##
|
|
62
|
+
## Usage by Service
|
|
62
63
|
|
|
63
|
-
###
|
|
64
|
+
### CameraService
|
|
64
65
|
|
|
65
66
|
```typescript
|
|
66
67
|
import { CameraService } from '@angular-helpers/browser-web-apis';
|
|
@@ -72,10 +73,10 @@ export class PhotoComponent {
|
|
|
72
73
|
try {
|
|
73
74
|
const stream = await this.cameraService.startCamera({
|
|
74
75
|
video: true,
|
|
75
|
-
audio: false
|
|
76
|
+
audio: false,
|
|
76
77
|
});
|
|
77
|
-
|
|
78
|
-
//
|
|
78
|
+
|
|
79
|
+
// Use stream for video/photo capture
|
|
79
80
|
} catch (error) {
|
|
80
81
|
console.error('Error accessing camera:', error);
|
|
81
82
|
}
|
|
@@ -87,7 +88,7 @@ export class PhotoComponent {
|
|
|
87
88
|
}
|
|
88
89
|
```
|
|
89
90
|
|
|
90
|
-
###
|
|
91
|
+
### RegexSecurityService (ReDoS Prevention)
|
|
91
92
|
|
|
92
93
|
```typescript
|
|
93
94
|
import { RegexSecurityService } from '@angular-helpers/browser-web-apis';
|
|
@@ -96,64 +97,25 @@ export class SecurityComponent {
|
|
|
96
97
|
constructor(private regexSecurity: RegexSecurityService) {}
|
|
97
98
|
|
|
98
99
|
async testPattern() {
|
|
99
|
-
const pattern = '(.+)+'; //
|
|
100
|
+
const pattern = '(.+)+'; // Potentially unsafe regex pattern
|
|
100
101
|
const text = 'some text to test';
|
|
101
|
-
|
|
102
|
+
|
|
102
103
|
try {
|
|
103
104
|
const result = await this.regexSecurity.testRegex(pattern, text, {
|
|
104
105
|
timeout: 5000,
|
|
105
|
-
safeMode: true
|
|
106
|
+
safeMode: true,
|
|
106
107
|
});
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
console.log('Match:', result.match);
|
|
109
110
|
console.log('Execution time:', result.executionTime);
|
|
110
111
|
} catch (error) {
|
|
111
112
|
console.error('Regex test failed:', error);
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
|
-
|
|
115
|
-
async analyzeSecurity() {
|
|
116
|
-
const analysis = await this.regexSecurity.analyzePatternSecurity('(.+)+');
|
|
117
|
-
|
|
118
|
-
console.log('Risk level:', analysis.risk);
|
|
119
|
-
console.log('Warnings:', analysis.warnings);
|
|
120
|
-
console.log('Recommendations:', analysis.recommendations);
|
|
121
|
-
}
|
|
122
115
|
}
|
|
123
116
|
```
|
|
124
117
|
|
|
125
|
-
###
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { RegexSecurityService, RegexSecurityBuilder } from '@angular-helpers/browser-web-apis';
|
|
129
|
-
|
|
130
|
-
export class RegexBuilderComponent {
|
|
131
|
-
constructor(private regexSecurity: RegexSecurityService) {}
|
|
132
|
-
|
|
133
|
-
async buildSafeRegex() {
|
|
134
|
-
const builder = RegexSecurityService.builder()
|
|
135
|
-
.startOfLine()
|
|
136
|
-
.characterSet('a-zA-Z0-9')
|
|
137
|
-
.quantifier('+')
|
|
138
|
-
.characterSet('@')
|
|
139
|
-
.characterSet('a-zA-Z0-9.-')
|
|
140
|
-
.quantifier('+')
|
|
141
|
-
.characterSet('.')
|
|
142
|
-
.characterSet('a-z')
|
|
143
|
-
.quantifier('{2,4}')
|
|
144
|
-
.endOfLine()
|
|
145
|
-
.timeout(3000)
|
|
146
|
-
.safeMode();
|
|
147
|
-
|
|
148
|
-
const emailPattern = builder.build().pattern;
|
|
149
|
-
const result = await builder.execute('test@example.com', this.regexSecurity);
|
|
150
|
-
|
|
151
|
-
console.log('Valid email:', result.match);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### 🌍 GeolocationService
|
|
118
|
+
### GeolocationService
|
|
157
119
|
|
|
158
120
|
```typescript
|
|
159
121
|
import { GeolocationService } from '@angular-helpers/browser-web-apis';
|
|
@@ -166,126 +128,34 @@ export class LocationComponent {
|
|
|
166
128
|
const position = await this.geolocation.getCurrentPosition({
|
|
167
129
|
enableHighAccuracy: true,
|
|
168
130
|
timeout: 10000,
|
|
169
|
-
maximumAge: 60000
|
|
131
|
+
maximumAge: 60000,
|
|
170
132
|
});
|
|
171
|
-
|
|
133
|
+
|
|
172
134
|
console.log('Position:', position.coords);
|
|
173
135
|
} catch (error) {
|
|
174
136
|
console.error('Error getting location:', error);
|
|
175
137
|
}
|
|
176
138
|
}
|
|
177
|
-
|
|
178
|
-
watchPosition() {
|
|
179
|
-
const watchId = this.geolocation.watchPosition(position => {
|
|
180
|
-
console.log('New position:', position.coords);
|
|
181
|
-
}, error => {
|
|
182
|
-
console.error('Watch error:', error);
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### 🔔 NotificationService
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
import { NotificationService } from '@angular-helpers/browser-web-apis';
|
|
192
|
-
|
|
193
|
-
export class NotificationComponent {
|
|
194
|
-
constructor(private notificationService: NotificationService) {}
|
|
195
|
-
|
|
196
|
-
async showNotification() {
|
|
197
|
-
try {
|
|
198
|
-
await this.notificationService.requestPermission();
|
|
199
|
-
|
|
200
|
-
this.notificationService.showNotification({
|
|
201
|
-
title: 'New Message',
|
|
202
|
-
body: 'You have a new message',
|
|
203
|
-
icon: '/assets/icon.png',
|
|
204
|
-
tag: 'message'
|
|
205
|
-
});
|
|
206
|
-
} catch (error) {
|
|
207
|
-
console.error('Notification error:', error);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
139
|
}
|
|
211
140
|
```
|
|
212
141
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
import { WebSocketService } from '@angular-helpers/browser-web-apis';
|
|
217
|
-
|
|
218
|
-
export class ChatComponent {
|
|
219
|
-
constructor(private webSocketService: WebSocketService) {}
|
|
220
|
-
|
|
221
|
-
connect() {
|
|
222
|
-
this.webSocketService.connect('ws://localhost:8080')
|
|
223
|
-
.subscribe({
|
|
224
|
-
next: (message) => console.log('Received:', message),
|
|
225
|
-
error: (error) => console.error('WebSocket error:', error),
|
|
226
|
-
complete: () => console.log('WebSocket disconnected')
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
sendMessage(message: string) {
|
|
231
|
-
this.webSocketService.send(message);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### 💾 WebStorageService
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
import { WebStorageService } from '@angular-helpers/browser-web-apis';
|
|
240
|
-
|
|
241
|
-
export class SettingsComponent {
|
|
242
|
-
constructor(private storageService: WebStorageService) {}
|
|
243
|
-
|
|
244
|
-
saveSettings() {
|
|
245
|
-
this.storageService.setItem('userSettings', {
|
|
246
|
-
theme: 'dark',
|
|
247
|
-
language: 'es',
|
|
248
|
-
notifications: true
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
- `showProgressNotification(title, current, total)` - Notificación con progreso
|
|
252
|
-
|
|
253
|
-
### ClipboardService
|
|
254
|
-
- `writeText(text)` - Escribir texto
|
|
255
|
-
- `readText()` - Leer texto
|
|
256
|
-
- `copyImage(blob)` - Copiar imagen
|
|
257
|
-
- `pasteImage()` - Pegar imagen
|
|
258
|
-
|
|
259
|
-
### MediaDevicesService
|
|
260
|
-
- `getUserMedia(constraints)` - Obtener media
|
|
261
|
-
- `getDisplayMedia(constraints?)` - Screen sharing
|
|
262
|
-
- `refreshDevices()` - Actualizar dispositivos
|
|
263
|
-
- `getDevicesByKind(kind)` - Dispositivos por tipo
|
|
264
|
-
|
|
265
|
-
### PermissionsService
|
|
266
|
-
- `query(descriptor)` - Consultar permiso
|
|
267
|
-
- `request(descriptor)` - Solicitar permiso
|
|
268
|
-
- `isGranted(permission)` - Verificar concedido
|
|
269
|
-
- `isDenied(permission)` - Verificar denegado
|
|
270
|
-
- `observePermission(permission)` - Observar cambios
|
|
271
|
-
|
|
272
|
-
## 🌐 Soporte de Navegadores
|
|
142
|
+
## Browser Support
|
|
273
143
|
|
|
274
|
-
|
|
144
|
+
The services automatically validate browser support and unsupported-path handling:
|
|
275
145
|
|
|
276
|
-
-
|
|
277
|
-
-
|
|
278
|
-
-
|
|
279
|
-
-
|
|
280
|
-
-
|
|
146
|
+
- Chrome: full support
|
|
147
|
+
- Firefox: full support
|
|
148
|
+
- Safari: partial support
|
|
149
|
+
- Edge: full support
|
|
150
|
+
- Mobile browsers: depends on platform and API
|
|
281
151
|
|
|
282
|
-
##
|
|
152
|
+
## Notes
|
|
283
153
|
|
|
284
|
-
-
|
|
285
|
-
-
|
|
286
|
-
-
|
|
287
|
-
-
|
|
154
|
+
- Secure context (HTTPS) is required for several APIs
|
|
155
|
+
- Some APIs require explicit user interaction
|
|
156
|
+
- Permission behavior varies by browser
|
|
157
|
+
- Always implement error handling and fallback logic
|
|
288
158
|
|
|
289
|
-
##
|
|
159
|
+
## License
|
|
290
160
|
|
|
291
161
|
MIT
|