@metigan/angular 1.0.2 โ 1.0.3
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/.gitattributes +31 -0
- package/README.md +313 -64
- package/package.json +1 -1
- package/dist/LICENSE +0 -22
- package/dist/README.md +0 -584
- package/dist/esm2022/metigan-angular.mjs +0 -5
- package/dist/esm2022/public-api.mjs +0 -21
- package/dist/esm2022/src/lib/audiences.service.mjs +0 -157
- package/dist/esm2022/src/lib/config.mjs +0 -30
- package/dist/esm2022/src/lib/contacts.service.mjs +0 -267
- package/dist/esm2022/src/lib/email.service.mjs +0 -267
- package/dist/esm2022/src/lib/errors.mjs +0 -40
- package/dist/esm2022/src/lib/forms.service.mjs +0 -180
- package/dist/esm2022/src/lib/http-client.service.mjs +0 -111
- package/dist/esm2022/src/lib/metigan.module.mjs +0 -67
- package/dist/esm2022/src/lib/metigan.service.mjs +0 -72
- package/dist/esm2022/src/lib/templates.service.mjs +0 -85
- package/dist/esm2022/src/lib/types.mjs +0 -6
- package/dist/fesm2022/metigan-angular.mjs +0 -1241
- package/dist/fesm2022/metigan-angular.mjs.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/public-api.d.ts +0 -15
- package/dist/src/lib/audiences.service.d.ts +0 -62
- package/dist/src/lib/config.d.ts +0 -28
- package/dist/src/lib/contacts.service.d.ts +0 -80
- package/dist/src/lib/email.service.d.ts +0 -44
- package/dist/src/lib/errors.d.ts +0 -24
- package/dist/src/lib/forms.service.d.ts +0 -67
- package/dist/src/lib/http-client.service.d.ts +0 -46
- package/dist/src/lib/metigan.module.d.ts +0 -27
- package/dist/src/lib/metigan.service.d.ts +0 -27
- package/dist/src/lib/templates.service.d.ts +0 -36
- package/dist/src/lib/types.d.ts +0 -329
package/.gitattributes
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
|
2
|
+
* text=auto
|
|
3
|
+
|
|
4
|
+
# Source files - ensure LF line endings
|
|
5
|
+
*.ts text eol=lf
|
|
6
|
+
*.js text eol=lf
|
|
7
|
+
*.json text eol=lf
|
|
8
|
+
*.md text eol=lf
|
|
9
|
+
*.yml text eol=lf
|
|
10
|
+
*.yaml text eol=lf
|
|
11
|
+
|
|
12
|
+
# Compiled JavaScript files - ensure LF line endings
|
|
13
|
+
*.mjs text eol=lf
|
|
14
|
+
*.d.ts text eol=lf
|
|
15
|
+
|
|
16
|
+
# Config files - ensure LF line endings
|
|
17
|
+
.npmignore text eol=lf
|
|
18
|
+
*.npmignore text eol=lf
|
|
19
|
+
yarn.lock text eol=lf
|
|
20
|
+
package-lock.json text eol=lf
|
|
21
|
+
|
|
22
|
+
# Binary files
|
|
23
|
+
*.png binary
|
|
24
|
+
*.jpg binary
|
|
25
|
+
*.jpeg binary
|
|
26
|
+
*.gif binary
|
|
27
|
+
*.ico binary
|
|
28
|
+
*.woff binary
|
|
29
|
+
*.woff2 binary
|
|
30
|
+
*.ttf binary
|
|
31
|
+
*.eot binary
|
package/README.md
CHANGED
|
@@ -1,46 +1,94 @@
|
|
|
1
1
|
# Metigan Angular SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@metigan/angular)
|
|
4
|
+
[](https://www.npmjs.com/package/@metigan/angular)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Official Angular SDK for the Metigan API. Send emails, manage contacts, audiences, templates, and forms with ease in your Angular applications.
|
|
8
|
+
|
|
9
|
+
## โจ Features
|
|
10
|
+
|
|
11
|
+
- ๐ง **Send Emails** - Send HTML emails with attachments, CC, BCC, and templates
|
|
12
|
+
- ๐ฅ **Manage Contacts** - Create, update, list, and manage contact subscriptions
|
|
13
|
+
- ๐ฏ **Audiences** - Organize contacts into audiences and track statistics
|
|
14
|
+
- ๐ **Forms** - Submit and manage form data
|
|
15
|
+
- ๐จ **Templates** - Use email templates with dynamic variables
|
|
16
|
+
- ๐ **RxJS Observables** - All methods return Observables for reactive programming
|
|
17
|
+
- โก **TypeScript** - Full TypeScript support with type definitions
|
|
18
|
+
- ๐ก๏ธ **Error Handling** - Comprehensive error handling with typed exceptions
|
|
19
|
+
- ๐ **Angular 15+** - Supports Angular 15, 16, 17, 18, 19, 20, and 21
|
|
20
|
+
- ๐ฆ **Standalone Support** - Works with both NgModules and Standalone Components
|
|
21
|
+
|
|
22
|
+
## ๐ Requirements
|
|
23
|
+
|
|
24
|
+
- **Angular**: 15.0.0 or higher (15, 16, 17, 18, 19, 20, 21)
|
|
25
|
+
- **RxJS**: 7.0.0 or higher
|
|
26
|
+
- **TypeScript**: 4.9.0 or higher
|
|
4
27
|
|
|
5
28
|
## ๐ฆ Installation
|
|
6
29
|
|
|
30
|
+
Install via npm:
|
|
31
|
+
|
|
7
32
|
```bash
|
|
8
33
|
npm install @metigan/angular
|
|
9
|
-
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or via yarn:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
10
39
|
yarn add @metigan/angular
|
|
11
40
|
```
|
|
12
41
|
|
|
42
|
+
## ๐ Getting Your API Key
|
|
43
|
+
|
|
44
|
+
Get your API key from the [Metigan Dashboard](https://app.metigan.com/api-keys).
|
|
45
|
+
|
|
46
|
+
1. Sign in to your Metigan account
|
|
47
|
+
2. Navigate to **Settings** โ **API Keys**
|
|
48
|
+
3. Create a new API key or use an existing one
|
|
49
|
+
4. Copy the API key and use it in your application
|
|
50
|
+
|
|
51
|
+
> โ ๏ธ **Security Note**: Never expose your API key in client-side code. For client-side usage, consider using environment-specific keys or implementing a proxy server.
|
|
52
|
+
|
|
13
53
|
## ๐ Quick Start
|
|
14
54
|
|
|
15
|
-
###
|
|
55
|
+
### Using NgModules (Angular 15+)
|
|
56
|
+
|
|
57
|
+
#### 1. Import the Module
|
|
16
58
|
|
|
17
59
|
In your `app.module.ts`:
|
|
18
60
|
|
|
19
61
|
```typescript
|
|
20
62
|
import { NgModule } from '@angular/core';
|
|
63
|
+
import { BrowserModule } from '@angular/platform-browser';
|
|
21
64
|
import { MetiganModule } from '@metigan/angular';
|
|
22
65
|
|
|
66
|
+
import { AppComponent } from './app.component';
|
|
67
|
+
|
|
23
68
|
@NgModule({
|
|
69
|
+
declarations: [AppComponent],
|
|
24
70
|
imports: [
|
|
71
|
+
BrowserModule,
|
|
25
72
|
MetiganModule.forRoot({
|
|
26
73
|
apiKey: 'your-api-key'
|
|
27
74
|
})
|
|
28
|
-
]
|
|
75
|
+
],
|
|
76
|
+
bootstrap: [AppComponent]
|
|
29
77
|
})
|
|
30
78
|
export class AppModule { }
|
|
31
79
|
```
|
|
32
80
|
|
|
33
|
-
|
|
81
|
+
#### 2. Use in Components
|
|
34
82
|
|
|
35
83
|
```typescript
|
|
36
|
-
import { Component
|
|
84
|
+
import { Component } from '@angular/core';
|
|
37
85
|
import { MetiganService } from '@metigan/angular';
|
|
38
86
|
|
|
39
87
|
@Component({
|
|
40
88
|
selector: 'app-my-component',
|
|
41
89
|
template: '<button (click)="sendEmail()">Send Email</button>'
|
|
42
90
|
})
|
|
43
|
-
export class MyComponent
|
|
91
|
+
export class MyComponent {
|
|
44
92
|
constructor(private metigan: MetiganService) {}
|
|
45
93
|
|
|
46
94
|
sendEmail() {
|
|
@@ -62,19 +110,22 @@ export class MyComponent implements OnInit {
|
|
|
62
110
|
}
|
|
63
111
|
```
|
|
64
112
|
|
|
65
|
-
###
|
|
113
|
+
### Using Standalone Components (Angular 17+)
|
|
114
|
+
|
|
115
|
+
For Standalone Components, use manual initialization:
|
|
66
116
|
|
|
67
|
-
|
|
117
|
+
For Standalone Components, you can initialize manually:
|
|
68
118
|
|
|
69
119
|
```typescript
|
|
70
120
|
import { Component, OnInit } from '@angular/core';
|
|
71
121
|
import { MetiganService } from '@metigan/angular';
|
|
72
122
|
|
|
73
123
|
@Component({
|
|
74
|
-
selector: 'app-
|
|
75
|
-
|
|
124
|
+
selector: 'app-root',
|
|
125
|
+
standalone: true,
|
|
126
|
+
template: '<button (click)="sendEmail()">Send Email</button>'
|
|
76
127
|
})
|
|
77
|
-
export class
|
|
128
|
+
export class AppComponent implements OnInit {
|
|
78
129
|
constructor(private metigan: MetiganService) {}
|
|
79
130
|
|
|
80
131
|
ngOnInit() {
|
|
@@ -85,6 +136,18 @@ export class MyComponent implements OnInit {
|
|
|
85
136
|
retryCount: 3
|
|
86
137
|
});
|
|
87
138
|
}
|
|
139
|
+
|
|
140
|
+
sendEmail() {
|
|
141
|
+
this.metigan.email.sendEmail({
|
|
142
|
+
from: 'sender@example.com',
|
|
143
|
+
recipients: ['recipient@example.com'],
|
|
144
|
+
subject: 'Hello!',
|
|
145
|
+
content: '<h1>Welcome</h1><p>Thank you for signing up.</p>'
|
|
146
|
+
}).subscribe({
|
|
147
|
+
next: (response) => console.log('Sent:', response),
|
|
148
|
+
error: (error) => console.error('Error:', error)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
88
151
|
}
|
|
89
152
|
```
|
|
90
153
|
|
|
@@ -146,7 +209,11 @@ this.metigan.email.sendEmail({
|
|
|
146
209
|
from: 'sender@example.com',
|
|
147
210
|
recipients: ['recipient@example.com'],
|
|
148
211
|
subject: 'Welcome Email',
|
|
149
|
-
templateId: 'template-123'
|
|
212
|
+
templateId: 'template-123',
|
|
213
|
+
variables: {
|
|
214
|
+
name: 'John Doe',
|
|
215
|
+
company: 'Acme Inc'
|
|
216
|
+
}
|
|
150
217
|
}).subscribe({
|
|
151
218
|
next: (response) => console.log('Sent'),
|
|
152
219
|
error: (error) => console.error('Error:', error)
|
|
@@ -419,7 +486,7 @@ this.metigan.audiences.merge(
|
|
|
419
486
|
});
|
|
420
487
|
```
|
|
421
488
|
|
|
422
|
-
##
|
|
489
|
+
## ๐จ Templates Module
|
|
423
490
|
|
|
424
491
|
### List Templates
|
|
425
492
|
|
|
@@ -448,15 +515,14 @@ this.metigan.templates.get('template-123').subscribe({
|
|
|
448
515
|
|
|
449
516
|
## โ๏ธ Configuration
|
|
450
517
|
|
|
451
|
-
### Module Configuration
|
|
518
|
+
### Module Configuration (NgModules)
|
|
452
519
|
|
|
453
520
|
```typescript
|
|
454
521
|
MetiganModule.forRoot({
|
|
455
522
|
apiKey: 'your-api-key',
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
retryDelay: 2000, // Optional: Delay between retries in ms
|
|
523
|
+
timeout: 60000, // Optional: Request timeout in ms (default: 30000)
|
|
524
|
+
retryCount: 5, // Optional: Number of retries (default: 3)
|
|
525
|
+
retryDelay: 2000, // Optional: Delay between retries in ms (default: 2000)
|
|
460
526
|
apiUrl: 'https://api.metigan.com' // Optional: Custom API URL
|
|
461
527
|
})
|
|
462
528
|
```
|
|
@@ -473,53 +539,30 @@ this.metigan.initialize({
|
|
|
473
539
|
});
|
|
474
540
|
```
|
|
475
541
|
|
|
476
|
-
|
|
542
|
+
### Environment Configuration
|
|
477
543
|
|
|
478
|
-
|
|
544
|
+
For better security, use environment variables:
|
|
479
545
|
|
|
546
|
+
**environment.ts**:
|
|
480
547
|
```typescript
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
// Success
|
|
486
|
-
},
|
|
487
|
-
error: (error) => {
|
|
488
|
-
if (error instanceof ValidationError) {
|
|
489
|
-
console.error('Invalid data:', error.message);
|
|
490
|
-
} else if (error instanceof ApiError) {
|
|
491
|
-
console.error(`API error (${error.statusCode}):`, error.message);
|
|
492
|
-
} else if (error instanceof MetiganError) {
|
|
493
|
-
console.error('Metigan error:', error.message);
|
|
494
|
-
} else {
|
|
495
|
-
console.error('Unknown error:', error);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
});
|
|
548
|
+
export const environment = {
|
|
549
|
+
production: false,
|
|
550
|
+
metiganApiKey: 'your-api-key'
|
|
551
|
+
};
|
|
499
552
|
```
|
|
500
553
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
If you only need a specific service:
|
|
504
|
-
|
|
554
|
+
**app.module.ts**:
|
|
505
555
|
```typescript
|
|
506
|
-
import {
|
|
556
|
+
import { environment } from './environments/environment';
|
|
507
557
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
subject: 'Test',
|
|
517
|
-
content: '<p>Hello</p>'
|
|
518
|
-
}).subscribe({
|
|
519
|
-
next: (response) => console.log('Sent'),
|
|
520
|
-
error: (error) => console.error('Error:', error)
|
|
521
|
-
});
|
|
522
|
-
}
|
|
558
|
+
@NgModule({
|
|
559
|
+
imports: [
|
|
560
|
+
MetiganModule.forRoot({
|
|
561
|
+
apiKey: environment.metiganApiKey
|
|
562
|
+
})
|
|
563
|
+
]
|
|
564
|
+
})
|
|
565
|
+
export class AppModule { }
|
|
523
566
|
```
|
|
524
567
|
|
|
525
568
|
## ๐ RxJS Observables
|
|
@@ -554,7 +597,12 @@ export class MyComponent implements OnDestroy {
|
|
|
554
597
|
private subscription = new Subscription();
|
|
555
598
|
|
|
556
599
|
sendEmail() {
|
|
557
|
-
const sub = this.metigan.email.sendEmail(
|
|
600
|
+
const sub = this.metigan.email.sendEmail({
|
|
601
|
+
from: 'sender@example.com',
|
|
602
|
+
recipients: ['recipient@example.com'],
|
|
603
|
+
subject: 'Test',
|
|
604
|
+
content: '<p>Hello</p>'
|
|
605
|
+
}).subscribe({
|
|
558
606
|
next: (response) => console.log('Sent'),
|
|
559
607
|
error: (error) => console.error('Error:', error)
|
|
560
608
|
});
|
|
@@ -568,6 +616,203 @@ export class MyComponent implements OnDestroy {
|
|
|
568
616
|
}
|
|
569
617
|
```
|
|
570
618
|
|
|
619
|
+
### Using takeUntil Pattern
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
import { Component, OnDestroy } from '@angular/core';
|
|
623
|
+
import { Subject } from 'rxjs';
|
|
624
|
+
import { takeUntil } from 'rxjs/operators';
|
|
625
|
+
|
|
626
|
+
export class MyComponent implements OnDestroy {
|
|
627
|
+
private destroy$ = new Subject<void>();
|
|
628
|
+
|
|
629
|
+
loadTemplates() {
|
|
630
|
+
this.metigan.templates.list()
|
|
631
|
+
.pipe(takeUntil(this.destroy$))
|
|
632
|
+
.subscribe({
|
|
633
|
+
next: (response) => console.log('Templates:', response),
|
|
634
|
+
error: (error) => console.error('Error:', error)
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
ngOnDestroy() {
|
|
639
|
+
this.destroy$.next();
|
|
640
|
+
this.destroy$.complete();
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## ๐ก๏ธ Error Handling
|
|
646
|
+
|
|
647
|
+
All services return RxJS Observables, so use standard error handling:
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
import { MetiganError, ValidationError, ApiError } from '@metigan/angular';
|
|
651
|
+
|
|
652
|
+
this.metigan.email.sendEmail(options).subscribe({
|
|
653
|
+
next: (response) => {
|
|
654
|
+
// Success
|
|
655
|
+
console.log('Email sent successfully');
|
|
656
|
+
},
|
|
657
|
+
error: (error) => {
|
|
658
|
+
if (error instanceof ValidationError) {
|
|
659
|
+
console.error('Invalid data:', error.message);
|
|
660
|
+
// Handle validation errors
|
|
661
|
+
} else if (error instanceof ApiError) {
|
|
662
|
+
console.error(`API error (${error.statusCode}):`, error.message);
|
|
663
|
+
// Handle API errors (4xx, 5xx)
|
|
664
|
+
if (error.statusCode === 401) {
|
|
665
|
+
// Unauthorized - check API key
|
|
666
|
+
} else if (error.statusCode === 429) {
|
|
667
|
+
// Rate limited - retry after delay
|
|
668
|
+
}
|
|
669
|
+
} else if (error instanceof MetiganError) {
|
|
670
|
+
console.error('Metigan error:', error.message);
|
|
671
|
+
// Handle general Metigan errors
|
|
672
|
+
} else {
|
|
673
|
+
console.error('Unknown error:', error);
|
|
674
|
+
// Handle unexpected errors
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
## ๐ Using Individual Services
|
|
681
|
+
|
|
682
|
+
If you only need a specific service, you can inject it directly:
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
import { MetiganEmailService } from '@metigan/angular';
|
|
686
|
+
|
|
687
|
+
@Component({
|
|
688
|
+
selector: 'app-email',
|
|
689
|
+
template: ''
|
|
690
|
+
})
|
|
691
|
+
export class EmailComponent {
|
|
692
|
+
constructor(private emailService: MetiganEmailService) {}
|
|
693
|
+
|
|
694
|
+
ngOnInit() {
|
|
695
|
+
// Initialize the service
|
|
696
|
+
this.emailService.initialize('your-api-key');
|
|
697
|
+
|
|
698
|
+
// Use the service
|
|
699
|
+
this.emailService.sendEmail({
|
|
700
|
+
from: 'sender@example.com',
|
|
701
|
+
recipients: ['recipient@example.com'],
|
|
702
|
+
subject: 'Test',
|
|
703
|
+
content: '<p>Hello</p>'
|
|
704
|
+
}).subscribe({
|
|
705
|
+
next: (response) => console.log('Sent'),
|
|
706
|
+
error: (error) => console.error('Error:', error)
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
Available services:
|
|
713
|
+
- `MetiganEmailService`
|
|
714
|
+
- `MetiganFormsService`
|
|
715
|
+
- `MetiganContactsService`
|
|
716
|
+
- `MetiganAudiencesService`
|
|
717
|
+
- `MetiganTemplatesService`
|
|
718
|
+
|
|
719
|
+
## ๐งช Testing
|
|
720
|
+
|
|
721
|
+
When testing components that use Metigan services, you can mock the services:
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
import { TestBed } from '@angular/core/testing';
|
|
725
|
+
import { of, throwError } from 'rxjs';
|
|
726
|
+
import { MetiganService } from '@metigan/angular';
|
|
727
|
+
|
|
728
|
+
describe('MyComponent', () => {
|
|
729
|
+
let mockMetiganService: jasmine.SpyObj<MetiganService>;
|
|
730
|
+
|
|
731
|
+
beforeEach(() => {
|
|
732
|
+
mockMetiganService = jasmine.createSpyObj('MetiganService', ['email']);
|
|
733
|
+
mockMetiganService.email = jasmine.createSpyObj('email', ['sendEmail']);
|
|
734
|
+
|
|
735
|
+
TestBed.configureTestingModule({
|
|
736
|
+
providers: [
|
|
737
|
+
{ provide: MetiganService, useValue: mockMetiganService }
|
|
738
|
+
]
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it('should send email', () => {
|
|
743
|
+
mockMetiganService.email.sendEmail.and.returnValue(
|
|
744
|
+
of({ success: true, message: 'Email sent' })
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
// Test your component
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
## ๐ Troubleshooting
|
|
753
|
+
|
|
754
|
+
### "API key is required" Error
|
|
755
|
+
|
|
756
|
+
Make sure you've initialized the service with an API key:
|
|
757
|
+
|
|
758
|
+
```typescript
|
|
759
|
+
// For NgModules
|
|
760
|
+
MetiganModule.forRoot({ apiKey: 'your-api-key' })
|
|
761
|
+
|
|
762
|
+
// For manual initialization
|
|
763
|
+
this.metigan.initialize({ apiKey: 'your-api-key' })
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Observable Not Subscribing
|
|
767
|
+
|
|
768
|
+
Make sure you're subscribing to the Observable:
|
|
769
|
+
|
|
770
|
+
```typescript
|
|
771
|
+
// โ Wrong - nothing happens
|
|
772
|
+
this.metigan.email.sendEmail(options);
|
|
773
|
+
|
|
774
|
+
// โ
Correct - subscribes to the Observable
|
|
775
|
+
this.metigan.email.sendEmail(options).subscribe({
|
|
776
|
+
next: (response) => console.log('Sent'),
|
|
777
|
+
error: (error) => console.error('Error:', error)
|
|
778
|
+
});
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
### Memory Leaks
|
|
782
|
+
|
|
783
|
+
Always unsubscribe from Observables to prevent memory leaks:
|
|
784
|
+
|
|
785
|
+
```typescript
|
|
786
|
+
// Using async pipe (recommended)
|
|
787
|
+
templates$ = this.metigan.templates.list();
|
|
788
|
+
|
|
789
|
+
// Using takeUntil pattern
|
|
790
|
+
private destroy$ = new Subject<void>();
|
|
791
|
+
this.metigan.templates.list()
|
|
792
|
+
.pipe(takeUntil(this.destroy$))
|
|
793
|
+
.subscribe(...);
|
|
794
|
+
|
|
795
|
+
// Using Subscription
|
|
796
|
+
private subscription = new Subscription();
|
|
797
|
+
this.subscription.add(
|
|
798
|
+
this.metigan.email.sendEmail(...).subscribe(...)
|
|
799
|
+
);
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### TypeScript Errors
|
|
803
|
+
|
|
804
|
+
Make sure you have TypeScript 4.9.0 or higher and Angular 15+ installed:
|
|
805
|
+
|
|
806
|
+
```bash
|
|
807
|
+
npm install typescript@^4.9.0 --save-dev
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
## ๐ Additional Resources
|
|
811
|
+
|
|
812
|
+
- [Angular Documentation](https://angular.io/docs)
|
|
813
|
+
- [RxJS Documentation](https://rxjs.dev/)
|
|
814
|
+
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
|
|
815
|
+
|
|
571
816
|
## ๐ License
|
|
572
817
|
|
|
573
818
|
MIT ยฉ Metigan
|
|
@@ -577,8 +822,12 @@ MIT ยฉ Metigan
|
|
|
577
822
|
- [Documentation](https://docs.metigan.com)
|
|
578
823
|
- [Dashboard](https://app.metigan.com)
|
|
579
824
|
- [API Reference](https://docs.metigan.com/api)
|
|
580
|
-
- [GitHub](https://github.com/metigan/angular)
|
|
825
|
+
- [GitHub Repository](https://github.com/metigan/angular)
|
|
826
|
+
- [Issue Tracker](https://github.com/metigan/angular/issues)
|
|
827
|
+
|
|
828
|
+
## ๐ฌ Support
|
|
581
829
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
830
|
+
For support, please:
|
|
831
|
+
- Check the [Documentation](https://docs.metigan.com)
|
|
832
|
+
- Open an issue on [GitHub](https://github.com/metigan/angular/issues)
|
|
833
|
+
- Contact support at support@metigan.com
|
package/package.json
CHANGED
package/dist/LICENSE
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Metigan
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
22
|
-
|