@alicanyucelankara06/generic-service 1.0.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/README.md +202 -0
- package/dist/README.md +202 -0
- package/dist/fesm2022/acy-generic-service.mjs +336 -0
- package/dist/fesm2022/acy-generic-service.mjs.map +1 -0
- package/dist/types/acy-generic-service.d.ts +238 -0
- package/ng-package.json +7 -0
- package/package.json +27 -0
- package/src/lib/generic-service.config.ts +50 -0
- package/src/lib/generic.service.ts +392 -0
- package/src/lib/models.ts +49 -0
- package/src/public-api.ts +16 -0
- package/tsconfig.json +23 -0
- package/tsconfig.lib.json +9 -0
package/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# @acy/generic-service
|
|
2
|
+
|
|
3
|
+
Angular 21 için Generic CRUD Service paketi. Tüm entity servisleriniz için temel sınıf sağlar.
|
|
4
|
+
|
|
5
|
+
## Özellikler
|
|
6
|
+
|
|
7
|
+
- **CRUD Operasyonları** — `getAll`, `getById`, `create`, `update`, `patch`, `delete`
|
|
8
|
+
- **Pagination** — Sayfalı veri çekme, sayfa navigasyonu
|
|
9
|
+
- **Arama & Filtreleme** — Esnek query parametreleri
|
|
10
|
+
- **Toplu İşlemler** — `deleteMany`
|
|
11
|
+
- **Angular Signals** — Reactive state yönetimi (`items`, `loading`, `error` vb.)
|
|
12
|
+
- **Hata Yönetimi** — Standart API hata modeli
|
|
13
|
+
- **Konfigürasyon** — `InjectionToken` ile merkezi ayarlar
|
|
14
|
+
|
|
15
|
+
## Kurulum
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @acy/generic-service
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Konfigürasyon
|
|
22
|
+
|
|
23
|
+
`app.config.ts` içinde:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { ApplicationConfig, provideHttpClient } from '@angular/core';
|
|
27
|
+
import { provideGenericServiceConfig } from '@acy/generic-service';
|
|
28
|
+
|
|
29
|
+
export const appConfig: ApplicationConfig = {
|
|
30
|
+
providers: [
|
|
31
|
+
provideHttpClient(),
|
|
32
|
+
provideGenericServiceConfig({
|
|
33
|
+
baseUrl: 'https://api.example.com',
|
|
34
|
+
defaultPageSize: 20,
|
|
35
|
+
enableLogging: true,
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Kullanım
|
|
42
|
+
|
|
43
|
+
### 1. Entity Model Tanımla
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { BaseEntity } from '@acy/generic-service';
|
|
47
|
+
|
|
48
|
+
export interface User extends BaseEntity {
|
|
49
|
+
id: number;
|
|
50
|
+
name: string;
|
|
51
|
+
email: string;
|
|
52
|
+
role: 'admin' | 'user';
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Service Oluştur
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Injectable } from '@angular/core';
|
|
60
|
+
import { GenericService } from '@acy/generic-service';
|
|
61
|
+
import { User } from './user.model';
|
|
62
|
+
|
|
63
|
+
@Injectable({ providedIn: 'root' })
|
|
64
|
+
export class UserService extends GenericService<User> {
|
|
65
|
+
constructor() {
|
|
66
|
+
super('users'); // API endpoint: https://api.example.com/users
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Component İçinde Kullan
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { Component, inject, OnInit } from '@angular/core';
|
|
75
|
+
import { UserService } from './user.service';
|
|
76
|
+
|
|
77
|
+
@Component({
|
|
78
|
+
selector: 'app-user-list',
|
|
79
|
+
template: `
|
|
80
|
+
@if (userService.loading()) {
|
|
81
|
+
<p>Yükleniyor...</p>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@if (userService.error(); as error) {
|
|
85
|
+
<p class="error">{{ error.message }}</p>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@for (user of userService.items(); track user.id) {
|
|
89
|
+
<div (click)="userService.select(user)">
|
|
90
|
+
{{ user.name }} - {{ user.email }}
|
|
91
|
+
</div>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
<div class="pagination">
|
|
95
|
+
<button (click)="userService.previousPage()">Önceki</button>
|
|
96
|
+
<span>{{ userService.currentPage() }} / {{ userService.totalPages() }}</span>
|
|
97
|
+
<button (click)="userService.nextPage()">Sonraki</button>
|
|
98
|
+
</div>
|
|
99
|
+
`,
|
|
100
|
+
})
|
|
101
|
+
export class UserListComponent implements OnInit {
|
|
102
|
+
protected readonly userService = inject(UserService);
|
|
103
|
+
|
|
104
|
+
ngOnInit() {
|
|
105
|
+
this.userService.getPaged().subscribe();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4. CRUD İşlemleri
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Tümünü getir
|
|
114
|
+
this.userService.getAll().subscribe();
|
|
115
|
+
|
|
116
|
+
// Sayfalı getir
|
|
117
|
+
this.userService.getPaged({ page: 1, pageSize: 10, sort: 'name' }).subscribe();
|
|
118
|
+
|
|
119
|
+
// ID ile getir
|
|
120
|
+
this.userService.getById(1).subscribe();
|
|
121
|
+
|
|
122
|
+
// Yeni oluştur
|
|
123
|
+
this.userService.create({ name: 'Ali', email: 'ali@test.com', role: 'user' }).subscribe();
|
|
124
|
+
|
|
125
|
+
// Güncelle
|
|
126
|
+
this.userService.update(1, { name: 'Ali Can' }).subscribe();
|
|
127
|
+
|
|
128
|
+
// PATCH
|
|
129
|
+
this.userService.patch(1, { role: 'admin' }).subscribe();
|
|
130
|
+
|
|
131
|
+
// Sil
|
|
132
|
+
this.userService.delete(1).subscribe();
|
|
133
|
+
|
|
134
|
+
// Toplu sil
|
|
135
|
+
this.userService.deleteMany([1, 2, 3]).subscribe();
|
|
136
|
+
|
|
137
|
+
// Ara
|
|
138
|
+
this.userService.search('ali').subscribe();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 5. Override Örnekleri
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
@Injectable({ providedIn: 'root' })
|
|
145
|
+
export class ProductService extends GenericService<Product> {
|
|
146
|
+
constructor() {
|
|
147
|
+
super('products');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Özel endpoint
|
|
151
|
+
getByCategory(categoryId: number) {
|
|
152
|
+
return this.http.get<Product[]>(`${this.apiUrl}/category/${categoryId}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// buildHttpParams override
|
|
156
|
+
protected override buildHttpParams(params?: QueryParams): HttpParams {
|
|
157
|
+
let httpParams = super.buildHttpParams(params);
|
|
158
|
+
httpParams = httpParams.set('include', 'category,tags');
|
|
159
|
+
return httpParams;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Referansı
|
|
165
|
+
|
|
166
|
+
### GenericService<T>
|
|
167
|
+
|
|
168
|
+
| Method | Dönüş Tipi | Açıklama |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| `getAll(params?)` | `Observable<T[]>` | Tüm kayıtları getirir |
|
|
171
|
+
| `getPaged(params?)` | `Observable<PagedResponse<T>>` | Sayfalı getirir |
|
|
172
|
+
| `getById(id)` | `Observable<T>` | Tek kayıt |
|
|
173
|
+
| `create(item)` | `Observable<T>` | Yeni kayıt |
|
|
174
|
+
| `update(id, item)` | `Observable<T>` | Tam güncelleme |
|
|
175
|
+
| `patch(id, item)` | `Observable<T>` | Kısmi güncelleme |
|
|
176
|
+
| `delete(id)` | `Observable<void>` | Silme |
|
|
177
|
+
| `deleteMany(ids)` | `Observable<void>` | Toplu silme |
|
|
178
|
+
| `search(term, params?)` | `Observable<T[]>` | Arama |
|
|
179
|
+
|
|
180
|
+
### Signals (Readonly)
|
|
181
|
+
|
|
182
|
+
| Signal | Tip | Açıklama |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| `items` | `Signal<T[]>` | Mevcut liste |
|
|
185
|
+
| `selectedItem` | `Signal<T \| null>` | Seçili kayıt |
|
|
186
|
+
| `loading` | `Signal<boolean>` | Yükleniyor mu |
|
|
187
|
+
| `error` | `Signal<ApiError \| null>` | Son hata |
|
|
188
|
+
| `totalCount` | `Signal<number>` | Toplam kayıt |
|
|
189
|
+
| `currentPage` | `Signal<number>` | Mevcut sayfa |
|
|
190
|
+
| `pageSize` | `Signal<number>` | Sayfa boyutu |
|
|
191
|
+
| `totalPages` | `Signal<number>` | Toplam sayfa (computed) |
|
|
192
|
+
| `hasData` | `Signal<boolean>` | Veri var mı (computed) |
|
|
193
|
+
|
|
194
|
+
## Build
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm run build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Lisans
|
|
201
|
+
|
|
202
|
+
MIT
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# @acy/generic-service
|
|
2
|
+
|
|
3
|
+
Angular 21 için Generic CRUD Service paketi. Tüm entity servisleriniz için temel sınıf sağlar.
|
|
4
|
+
|
|
5
|
+
## Özellikler
|
|
6
|
+
|
|
7
|
+
- **CRUD Operasyonları** — `getAll`, `getById`, `create`, `update`, `patch`, `delete`
|
|
8
|
+
- **Pagination** — Sayfalı veri çekme, sayfa navigasyonu
|
|
9
|
+
- **Arama & Filtreleme** — Esnek query parametreleri
|
|
10
|
+
- **Toplu İşlemler** — `deleteMany`
|
|
11
|
+
- **Angular Signals** — Reactive state yönetimi (`items`, `loading`, `error` vb.)
|
|
12
|
+
- **Hata Yönetimi** — Standart API hata modeli
|
|
13
|
+
- **Konfigürasyon** — `InjectionToken` ile merkezi ayarlar
|
|
14
|
+
|
|
15
|
+
## Kurulum
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @acy/generic-service
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Konfigürasyon
|
|
22
|
+
|
|
23
|
+
`app.config.ts` içinde:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { ApplicationConfig, provideHttpClient } from '@angular/core';
|
|
27
|
+
import { provideGenericServiceConfig } from '@acy/generic-service';
|
|
28
|
+
|
|
29
|
+
export const appConfig: ApplicationConfig = {
|
|
30
|
+
providers: [
|
|
31
|
+
provideHttpClient(),
|
|
32
|
+
provideGenericServiceConfig({
|
|
33
|
+
baseUrl: 'https://api.example.com',
|
|
34
|
+
defaultPageSize: 20,
|
|
35
|
+
enableLogging: true,
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Kullanım
|
|
42
|
+
|
|
43
|
+
### 1. Entity Model Tanımla
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { BaseEntity } from '@acy/generic-service';
|
|
47
|
+
|
|
48
|
+
export interface User extends BaseEntity {
|
|
49
|
+
id: number;
|
|
50
|
+
name: string;
|
|
51
|
+
email: string;
|
|
52
|
+
role: 'admin' | 'user';
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Service Oluştur
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Injectable } from '@angular/core';
|
|
60
|
+
import { GenericService } from '@acy/generic-service';
|
|
61
|
+
import { User } from './user.model';
|
|
62
|
+
|
|
63
|
+
@Injectable({ providedIn: 'root' })
|
|
64
|
+
export class UserService extends GenericService<User> {
|
|
65
|
+
constructor() {
|
|
66
|
+
super('users'); // API endpoint: https://api.example.com/users
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Component İçinde Kullan
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { Component, inject, OnInit } from '@angular/core';
|
|
75
|
+
import { UserService } from './user.service';
|
|
76
|
+
|
|
77
|
+
@Component({
|
|
78
|
+
selector: 'app-user-list',
|
|
79
|
+
template: `
|
|
80
|
+
@if (userService.loading()) {
|
|
81
|
+
<p>Yükleniyor...</p>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@if (userService.error(); as error) {
|
|
85
|
+
<p class="error">{{ error.message }}</p>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@for (user of userService.items(); track user.id) {
|
|
89
|
+
<div (click)="userService.select(user)">
|
|
90
|
+
{{ user.name }} - {{ user.email }}
|
|
91
|
+
</div>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
<div class="pagination">
|
|
95
|
+
<button (click)="userService.previousPage()">Önceki</button>
|
|
96
|
+
<span>{{ userService.currentPage() }} / {{ userService.totalPages() }}</span>
|
|
97
|
+
<button (click)="userService.nextPage()">Sonraki</button>
|
|
98
|
+
</div>
|
|
99
|
+
`,
|
|
100
|
+
})
|
|
101
|
+
export class UserListComponent implements OnInit {
|
|
102
|
+
protected readonly userService = inject(UserService);
|
|
103
|
+
|
|
104
|
+
ngOnInit() {
|
|
105
|
+
this.userService.getPaged().subscribe();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4. CRUD İşlemleri
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Tümünü getir
|
|
114
|
+
this.userService.getAll().subscribe();
|
|
115
|
+
|
|
116
|
+
// Sayfalı getir
|
|
117
|
+
this.userService.getPaged({ page: 1, pageSize: 10, sort: 'name' }).subscribe();
|
|
118
|
+
|
|
119
|
+
// ID ile getir
|
|
120
|
+
this.userService.getById(1).subscribe();
|
|
121
|
+
|
|
122
|
+
// Yeni oluştur
|
|
123
|
+
this.userService.create({ name: 'Ali', email: 'ali@test.com', role: 'user' }).subscribe();
|
|
124
|
+
|
|
125
|
+
// Güncelle
|
|
126
|
+
this.userService.update(1, { name: 'Ali Can' }).subscribe();
|
|
127
|
+
|
|
128
|
+
// PATCH
|
|
129
|
+
this.userService.patch(1, { role: 'admin' }).subscribe();
|
|
130
|
+
|
|
131
|
+
// Sil
|
|
132
|
+
this.userService.delete(1).subscribe();
|
|
133
|
+
|
|
134
|
+
// Toplu sil
|
|
135
|
+
this.userService.deleteMany([1, 2, 3]).subscribe();
|
|
136
|
+
|
|
137
|
+
// Ara
|
|
138
|
+
this.userService.search('ali').subscribe();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 5. Override Örnekleri
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
@Injectable({ providedIn: 'root' })
|
|
145
|
+
export class ProductService extends GenericService<Product> {
|
|
146
|
+
constructor() {
|
|
147
|
+
super('products');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Özel endpoint
|
|
151
|
+
getByCategory(categoryId: number) {
|
|
152
|
+
return this.http.get<Product[]>(`${this.apiUrl}/category/${categoryId}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// buildHttpParams override
|
|
156
|
+
protected override buildHttpParams(params?: QueryParams): HttpParams {
|
|
157
|
+
let httpParams = super.buildHttpParams(params);
|
|
158
|
+
httpParams = httpParams.set('include', 'category,tags');
|
|
159
|
+
return httpParams;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Referansı
|
|
165
|
+
|
|
166
|
+
### GenericService<T>
|
|
167
|
+
|
|
168
|
+
| Method | Dönüş Tipi | Açıklama |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| `getAll(params?)` | `Observable<T[]>` | Tüm kayıtları getirir |
|
|
171
|
+
| `getPaged(params?)` | `Observable<PagedResponse<T>>` | Sayfalı getirir |
|
|
172
|
+
| `getById(id)` | `Observable<T>` | Tek kayıt |
|
|
173
|
+
| `create(item)` | `Observable<T>` | Yeni kayıt |
|
|
174
|
+
| `update(id, item)` | `Observable<T>` | Tam güncelleme |
|
|
175
|
+
| `patch(id, item)` | `Observable<T>` | Kısmi güncelleme |
|
|
176
|
+
| `delete(id)` | `Observable<void>` | Silme |
|
|
177
|
+
| `deleteMany(ids)` | `Observable<void>` | Toplu silme |
|
|
178
|
+
| `search(term, params?)` | `Observable<T[]>` | Arama |
|
|
179
|
+
|
|
180
|
+
### Signals (Readonly)
|
|
181
|
+
|
|
182
|
+
| Signal | Tip | Açıklama |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| `items` | `Signal<T[]>` | Mevcut liste |
|
|
185
|
+
| `selectedItem` | `Signal<T \| null>` | Seçili kayıt |
|
|
186
|
+
| `loading` | `Signal<boolean>` | Yükleniyor mu |
|
|
187
|
+
| `error` | `Signal<ApiError \| null>` | Son hata |
|
|
188
|
+
| `totalCount` | `Signal<number>` | Toplam kayıt |
|
|
189
|
+
| `currentPage` | `Signal<number>` | Mevcut sayfa |
|
|
190
|
+
| `pageSize` | `Signal<number>` | Sayfa boyutu |
|
|
191
|
+
| `totalPages` | `Signal<number>` | Toplam sayfa (computed) |
|
|
192
|
+
| `hasData` | `Signal<boolean>` | Veri var mı (computed) |
|
|
193
|
+
|
|
194
|
+
## Build
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm run build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Lisans
|
|
201
|
+
|
|
202
|
+
MIT
|