@progalaxyelabs/ngx-stonescriptphp-client 1.0.4 → 1.1.1
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/package.json +11 -35
- package/dist/ngx-stonescriptphp-client/README.md +0 -186
- package/dist/ngx-stonescriptphp-client/fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs +0 -559
- package/dist/ngx-stonescriptphp-client/fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs.map +0 -1
- package/dist/ngx-stonescriptphp-client/index.d.ts +0 -184
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@progalaxyelabs/ngx-stonescriptphp-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Angular client library for StoneScriptPHP backend framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -23,60 +23,36 @@
|
|
|
23
23
|
"email": "team@stonescriptphp.org",
|
|
24
24
|
"url": "https://stonescriptphp.org"
|
|
25
25
|
},
|
|
26
|
-
"main": "dist/index.js",
|
|
27
|
-
"types": "dist/index.d.ts",
|
|
28
26
|
"files": [
|
|
29
|
-
"dist",
|
|
30
27
|
"README.md",
|
|
31
28
|
"HLD.md",
|
|
32
29
|
"LICENSE",
|
|
33
30
|
"docs"
|
|
34
31
|
],
|
|
35
32
|
"scripts": {
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"build": "ng build",
|
|
40
|
-
"watch": "ng build --watch --configuration development",
|
|
41
|
-
"test": "ng test",
|
|
33
|
+
"build": "ng-packagr -p ng-package.json",
|
|
34
|
+
"prepublishOnly": "npm run build",
|
|
35
|
+
"test": "echo \"No tests configured\"",
|
|
42
36
|
"publish:npm": "npm publish --access public"
|
|
43
37
|
},
|
|
44
38
|
"private": false,
|
|
45
39
|
"peerDependencies": {
|
|
46
40
|
"@angular/common": "^19.0.0 || ^20.0.0",
|
|
47
|
-
"@angular/core": "^19.0.0 || ^20.0.0"
|
|
48
|
-
"rxjs": "^7.8.0"
|
|
41
|
+
"@angular/core": "^19.0.0 || ^20.0.0"
|
|
49
42
|
},
|
|
50
43
|
"dependencies": {
|
|
51
|
-
"
|
|
52
|
-
"@angular/animations": "^20.0.0",
|
|
53
|
-
"@angular/common": "^20.0.0",
|
|
54
|
-
"@angular/compiler": "^20.0.0",
|
|
55
|
-
"@angular/core": "^20.0.0",
|
|
56
|
-
"@angular/forms": "^20.0.0",
|
|
57
|
-
"@angular/platform-browser": "^20.0.0",
|
|
58
|
-
"@angular/platform-browser-dynamic": "^20.0.0",
|
|
59
|
-
"@angular/router": "^20.0.0",
|
|
60
|
-
"rxjs": "~7.8.0",
|
|
61
|
-
"tslib": "^2.8.0",
|
|
62
|
-
"zone.js": "~0.15.0"
|
|
44
|
+
"tslib": "^2.8.0"
|
|
63
45
|
},
|
|
64
46
|
"devDependencies": {
|
|
65
|
-
"@angular
|
|
66
|
-
"@angular/
|
|
47
|
+
"@angular/common": "^20.0.0",
|
|
48
|
+
"@angular/compiler": "^20.0.0",
|
|
67
49
|
"@angular/compiler-cli": "^20.0.0",
|
|
68
|
-
"@
|
|
69
|
-
"@types/jasmine": "~5.1.0",
|
|
70
|
-
"jasmine-core": "~5.5.0",
|
|
71
|
-
"karma": "~6.4.0",
|
|
72
|
-
"karma-chrome-launcher": "~3.2.0",
|
|
73
|
-
"karma-coverage": "~2.2.0",
|
|
74
|
-
"karma-jasmine": "~5.1.0",
|
|
75
|
-
"karma-jasmine-html-reporter": "~2.1.0",
|
|
50
|
+
"@angular/core": "^20.0.0",
|
|
76
51
|
"ng-packagr": "^20.0.0",
|
|
77
52
|
"typescript": "~5.8.0"
|
|
78
53
|
},
|
|
79
54
|
"publishConfig": {
|
|
80
55
|
"access": "public"
|
|
81
|
-
}
|
|
56
|
+
},
|
|
57
|
+
"sideEffects": false
|
|
82
58
|
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
# ngx-stonescriptphp-client
|
|
2
|
-
|
|
3
|
-
> Official Angular client library for StoneScriptPHP backend framework
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@progalaxyelabs/ngx-stonescriptphp-client)
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
|
|
8
|
-
**Note:** While published as `@progalaxyelabs/ngx-stonescriptphp-client`, this is the official client for [StoneScriptPHP](https://stonescriptphp.org). Future versions will migrate to the `@stonescriptphp` namespace.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## What is this?
|
|
13
|
-
|
|
14
|
-
The Angular HTTP client library for **StoneScriptPHP** - a modern PHP backend framework that auto-generates TypeScript clients from your backend DTOs and contracts.
|
|
15
|
-
|
|
16
|
-
When you build APIs with StoneScriptPHP, you define:
|
|
17
|
-
- Request DTOs (TypeScript interfaces)
|
|
18
|
-
- Response DTOs (TypeScript interfaces)
|
|
19
|
-
- Route contracts (interfaces)
|
|
20
|
-
|
|
21
|
-
This library provides the HTTP client that consumes those contracts, giving you **100% type-safe** API calls with zero manual typing.
|
|
22
|
-
|
|
23
|
-
## Features
|
|
24
|
-
|
|
25
|
-
- ✅ **Type-safe HTTP calls** - Full TypeScript support from backend DTOs
|
|
26
|
-
- ✅ **Auto-generated clients** - StoneScriptPHP generates TypeScript from PHP
|
|
27
|
-
- ✅ **RxJS observables** - Native Angular integration
|
|
28
|
-
- ✅ **Error handling** - Consistent error responses
|
|
29
|
-
- ✅ **Interceptors ready** - Add auth, logging, retry logic
|
|
30
|
-
- ✅ **Angular 19+** - Modern Angular standalone components
|
|
31
|
-
|
|
32
|
-
## Installation
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm install @progalaxyelabs/ngx-stonescriptphp-client
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Quick Start
|
|
39
|
-
|
|
40
|
-
### 1. Generate TypeScript Client from Backend
|
|
41
|
-
|
|
42
|
-
In your StoneScriptPHP project:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
php stone generate typescript-client
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This generates TypeScript interfaces from your PHP DTOs.
|
|
49
|
-
|
|
50
|
-
### 2. Use in Angular
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
import { Component } from '@angular/core';
|
|
54
|
-
import { HttpClient } from '@angular/common/http';
|
|
55
|
-
import { Observable } from 'rxjs';
|
|
56
|
-
|
|
57
|
-
// Auto-generated from StoneScriptPHP backend
|
|
58
|
-
interface ProductRequest {
|
|
59
|
-
name: string;
|
|
60
|
-
price: number;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface ProductResponse {
|
|
64
|
-
productId: number;
|
|
65
|
-
status: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@Component({
|
|
69
|
-
selector: 'app-products',
|
|
70
|
-
standalone: true,
|
|
71
|
-
template: `<button (click)="createProduct()">Create Product</button>`
|
|
72
|
-
})
|
|
73
|
-
export class ProductsComponent {
|
|
74
|
-
constructor(private http: HttpClient) {}
|
|
75
|
-
|
|
76
|
-
createProduct(): void {
|
|
77
|
-
const request: ProductRequest = {
|
|
78
|
-
name: 'Widget',
|
|
79
|
-
price: 99.99
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
this.http.post<ProductResponse>('http://localhost:9100/products', request)
|
|
83
|
-
.subscribe(response => {
|
|
84
|
-
console.log('Product created:', response.productId);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## How it Works
|
|
91
|
-
|
|
92
|
-
StoneScriptPHP follows a **contract-first** approach:
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
PHP Backend (StoneScriptPHP) Angular Frontend
|
|
96
|
-
┌─────────────────────────┐ ┌──────────────────────┐
|
|
97
|
-
│ ProductRequest DTO │ ──────> │ ProductRequest.ts │
|
|
98
|
-
│ ProductResponse DTO │ ──────> │ ProductResponse.ts │
|
|
99
|
-
│ IProductRoute contract │ ──────> │ Type-safe HTTP calls │
|
|
100
|
-
└─────────────────────────┘ └──────────────────────┘
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
1. Define DTOs in PHP
|
|
104
|
-
2. Run `php stone generate typescript-client`
|
|
105
|
-
3. Import generated TypeScript interfaces in Angular
|
|
106
|
-
4. Make type-safe HTTP calls
|
|
107
|
-
|
|
108
|
-
## Advanced Usage
|
|
109
|
-
|
|
110
|
-
### With Interceptors
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
|
|
114
|
-
|
|
115
|
-
export class AuthInterceptor implements HttpInterceptor {
|
|
116
|
-
intercept(req: HttpRequest<any>, next: HttpHandler) {
|
|
117
|
-
const authReq = req.clone({
|
|
118
|
-
headers: req.headers.set('Authorization', 'Bearer ' + getToken())
|
|
119
|
-
});
|
|
120
|
-
return next.handle(authReq);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### With Error Handling
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
this.http.post<ProductResponse>('/products', request)
|
|
129
|
-
.pipe(
|
|
130
|
-
catchError(error => {
|
|
131
|
-
console.error('API Error:', error);
|
|
132
|
-
return throwError(() => error);
|
|
133
|
-
})
|
|
134
|
-
)
|
|
135
|
-
.subscribe(response => {
|
|
136
|
-
// Handle success
|
|
137
|
-
});
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## API Response Format
|
|
141
|
-
|
|
142
|
-
StoneScriptPHP responses follow this structure:
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
{
|
|
146
|
-
"status": "ok" | "error",
|
|
147
|
-
"message": "Success message",
|
|
148
|
-
"data": { /* Your DTO */ }
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Requirements
|
|
153
|
-
|
|
154
|
-
- Angular >= 19.0.0
|
|
155
|
-
- RxJS >= 7.8.0
|
|
156
|
-
- TypeScript >= 5.8.0
|
|
157
|
-
|
|
158
|
-
## Documentation
|
|
159
|
-
|
|
160
|
-
- **Framework Docs:** [stonescriptphp.org](https://stonescriptphp.org)
|
|
161
|
-
- **Getting Started:** [stonescriptphp.org/docs/getting-started](https://stonescriptphp.org/docs/getting-started)
|
|
162
|
-
- **TypeScript Client Guide:** [stonescriptphp.org/docs/typescript-client](https://stonescriptphp.org/docs/typescript-client)
|
|
163
|
-
|
|
164
|
-
## Example Projects
|
|
165
|
-
|
|
166
|
-
Check out the [StoneScriptPHP examples repository](https://github.com/progalaxyelabs/StoneScriptPHP/tree/main/examples) for full-stack example apps.
|
|
167
|
-
|
|
168
|
-
## Contributing
|
|
169
|
-
|
|
170
|
-
This is part of the StoneScriptPHP ecosystem. Contributions welcome!
|
|
171
|
-
|
|
172
|
-
- Report issues: [GitHub Issues](https://github.com/progalaxyelabs/ngx-stonescriptphp-client/issues)
|
|
173
|
-
- Framework repo: [StoneScriptPHP](https://github.com/progalaxyelabs/StoneScriptPHP)
|
|
174
|
-
|
|
175
|
-
## License
|
|
176
|
-
|
|
177
|
-
MIT
|
|
178
|
-
|
|
179
|
-
## Related Projects
|
|
180
|
-
|
|
181
|
-
- [StoneScriptPHP](https://github.com/progalaxyelabs/StoneScriptPHP) - The PHP backend framework
|
|
182
|
-
- [sunbird-garden](https://github.com/progalaxyelabs/sunbird-garden) - Reference implementation
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
**Made with ❤️ by the StoneScriptPHP team**
|
package/dist/ngx-stonescriptphp-client/fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs
DELETED
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, NgModule } from '@angular/core';
|
|
3
|
-
import { BehaviorSubject } from 'rxjs';
|
|
4
|
-
import { CommonModule } from '@angular/common';
|
|
5
|
-
|
|
6
|
-
class ApiResponse {
|
|
7
|
-
constructor(status, data = {}, message = '') {
|
|
8
|
-
this.status = status;
|
|
9
|
-
this.data = data;
|
|
10
|
-
this.message = message;
|
|
11
|
-
}
|
|
12
|
-
onOk(callback) {
|
|
13
|
-
if (this.status === 'ok') {
|
|
14
|
-
callback(this.data);
|
|
15
|
-
}
|
|
16
|
-
return this;
|
|
17
|
-
}
|
|
18
|
-
onNotOk(callback) {
|
|
19
|
-
if (this.status === 'not ok') {
|
|
20
|
-
callback(this.message, this.data);
|
|
21
|
-
}
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
onError(callback) {
|
|
25
|
-
if (this.status === 'error') {
|
|
26
|
-
callback();
|
|
27
|
-
}
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
|
-
isSuccess() {
|
|
31
|
-
return this.status === 'ok';
|
|
32
|
-
}
|
|
33
|
-
isError() {
|
|
34
|
-
return this.status === 'error' || this.status === 'not ok';
|
|
35
|
-
}
|
|
36
|
-
getData() {
|
|
37
|
-
return this.data || null;
|
|
38
|
-
}
|
|
39
|
-
getError() {
|
|
40
|
-
return this.message || 'Unknown error';
|
|
41
|
-
}
|
|
42
|
-
getStatus() {
|
|
43
|
-
return this.status;
|
|
44
|
-
}
|
|
45
|
-
getMessage() {
|
|
46
|
-
return this.message;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class TokenService {
|
|
51
|
-
constructor() {
|
|
52
|
-
this.accessToken = '';
|
|
53
|
-
this.refreshToken = '';
|
|
54
|
-
this.lsAccessTokenKey = 'progalaxyapi_access_token';
|
|
55
|
-
this.lsRefreshTokenKey = 'progalaxyapi_refresh_token';
|
|
56
|
-
}
|
|
57
|
-
setTokens(accessToken, refreshToken) {
|
|
58
|
-
this.accessToken = accessToken;
|
|
59
|
-
this.refreshToken = refreshToken;
|
|
60
|
-
localStorage.setItem(this.lsAccessTokenKey, accessToken);
|
|
61
|
-
localStorage.setItem(this.lsRefreshTokenKey, refreshToken);
|
|
62
|
-
}
|
|
63
|
-
setAccessToken(accessToken) {
|
|
64
|
-
this.accessToken = accessToken;
|
|
65
|
-
localStorage.setItem(this.lsAccessTokenKey, accessToken);
|
|
66
|
-
}
|
|
67
|
-
setRefreshToken(refreshToken) {
|
|
68
|
-
this.refreshToken = refreshToken;
|
|
69
|
-
localStorage.setItem(this.lsRefreshTokenKey, refreshToken);
|
|
70
|
-
}
|
|
71
|
-
getAccessToken() {
|
|
72
|
-
if (this.accessToken) {
|
|
73
|
-
return this.accessToken;
|
|
74
|
-
}
|
|
75
|
-
const storedAccessToken = localStorage.getItem(this.lsAccessTokenKey);
|
|
76
|
-
if (storedAccessToken) {
|
|
77
|
-
return storedAccessToken;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
return '';
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
getRefreshToken() {
|
|
84
|
-
if (this.refreshToken) {
|
|
85
|
-
return this.refreshToken;
|
|
86
|
-
}
|
|
87
|
-
const storedRefreshToken = localStorage.getItem(this.lsRefreshTokenKey);
|
|
88
|
-
if (storedRefreshToken) {
|
|
89
|
-
return storedRefreshToken;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
return '';
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
clear() {
|
|
96
|
-
this.accessToken = '';
|
|
97
|
-
this.refreshToken = '';
|
|
98
|
-
localStorage.removeItem(this.lsAccessTokenKey);
|
|
99
|
-
localStorage.removeItem(this.lsRefreshTokenKey);
|
|
100
|
-
}
|
|
101
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
102
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TokenService, providedIn: 'root' }); }
|
|
103
|
-
}
|
|
104
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TokenService, decorators: [{
|
|
105
|
-
type: Injectable,
|
|
106
|
-
args: [{
|
|
107
|
-
providedIn: 'root'
|
|
108
|
-
}]
|
|
109
|
-
}], ctorParameters: () => [] });
|
|
110
|
-
|
|
111
|
-
class SigninStatusService {
|
|
112
|
-
constructor() {
|
|
113
|
-
this.status = new BehaviorSubject(false);
|
|
114
|
-
}
|
|
115
|
-
signedOut() {
|
|
116
|
-
this.status.next(false);
|
|
117
|
-
}
|
|
118
|
-
signedIn() {
|
|
119
|
-
this.status.next(true);
|
|
120
|
-
}
|
|
121
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SigninStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
122
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SigninStatusService, providedIn: 'root' }); }
|
|
123
|
-
}
|
|
124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SigninStatusService, decorators: [{
|
|
125
|
-
type: Injectable,
|
|
126
|
-
args: [{
|
|
127
|
-
providedIn: 'root'
|
|
128
|
-
}]
|
|
129
|
-
}], ctorParameters: () => [] });
|
|
130
|
-
|
|
131
|
-
class MyEnvironmentModel {
|
|
132
|
-
constructor() {
|
|
133
|
-
this.production = true;
|
|
134
|
-
this.firebase = {
|
|
135
|
-
projectId: '',
|
|
136
|
-
appId: '',
|
|
137
|
-
databaseURL: '',
|
|
138
|
-
storageBucket: '',
|
|
139
|
-
locationId: '',
|
|
140
|
-
apiKey: '',
|
|
141
|
-
authDomain: '',
|
|
142
|
-
messagingSenderId: '',
|
|
143
|
-
measurementId: ''
|
|
144
|
-
};
|
|
145
|
-
this.apiServer = { host: '' };
|
|
146
|
-
this.chatServer = { host: '' };
|
|
147
|
-
/**
|
|
148
|
-
* Authentication configuration
|
|
149
|
-
* @default { mode: 'cookie', refreshEndpoint: '/auth/refresh', useCsrf: true }
|
|
150
|
-
*/
|
|
151
|
-
this.auth = {
|
|
152
|
-
mode: 'cookie',
|
|
153
|
-
refreshEndpoint: '/auth/refresh',
|
|
154
|
-
useCsrf: true,
|
|
155
|
-
refreshTokenCookieName: 'refresh_token',
|
|
156
|
-
csrfTokenCookieName: 'csrf_token',
|
|
157
|
-
csrfHeaderName: 'X-CSRF-Token'
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* CSRF Token Service
|
|
164
|
-
*
|
|
165
|
-
* Manages CSRF tokens for cookie-based authentication.
|
|
166
|
-
* Reads CSRF token from cookies and provides it for request headers.
|
|
167
|
-
*/
|
|
168
|
-
class CsrfService {
|
|
169
|
-
/**
|
|
170
|
-
* Get CSRF token from cookie
|
|
171
|
-
*/
|
|
172
|
-
getCsrfToken(cookieName = 'csrf_token') {
|
|
173
|
-
const cookies = document.cookie.split(';');
|
|
174
|
-
for (const cookie of cookies) {
|
|
175
|
-
const [name, value] = cookie.trim().split('=');
|
|
176
|
-
if (name === cookieName) {
|
|
177
|
-
return decodeURIComponent(value);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Check if CSRF token exists
|
|
184
|
-
*/
|
|
185
|
-
hasCsrfToken(cookieName = 'csrf_token') {
|
|
186
|
-
return this.getCsrfToken(cookieName) !== null;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Clear CSRF token (for logout)
|
|
190
|
-
* Note: Client-side deletion is limited for httpOnly cookies
|
|
191
|
-
*/
|
|
192
|
-
clearCsrfToken(cookieName = 'csrf_token') {
|
|
193
|
-
// Can only clear non-httpOnly cookies
|
|
194
|
-
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
|
195
|
-
}
|
|
196
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CsrfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
197
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CsrfService, providedIn: 'root' }); }
|
|
198
|
-
}
|
|
199
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CsrfService, decorators: [{
|
|
200
|
-
type: Injectable,
|
|
201
|
-
args: [{
|
|
202
|
-
providedIn: 'root'
|
|
203
|
-
}]
|
|
204
|
-
}] });
|
|
205
|
-
|
|
206
|
-
class ApiConnectionService {
|
|
207
|
-
constructor(tokens, signinStatus, environment, csrf) {
|
|
208
|
-
this.tokens = tokens;
|
|
209
|
-
this.signinStatus = signinStatus;
|
|
210
|
-
this.environment = environment;
|
|
211
|
-
this.csrf = csrf;
|
|
212
|
-
this.host = ''; // contains trailing slash
|
|
213
|
-
this.accessToken = '';
|
|
214
|
-
this.host = environment.apiServer.host;
|
|
215
|
-
// Set default auth config based on mode
|
|
216
|
-
this.authConfig = {
|
|
217
|
-
mode: environment.auth?.mode || 'cookie',
|
|
218
|
-
refreshEndpoint: environment.auth?.refreshEndpoint,
|
|
219
|
-
useCsrf: environment.auth?.useCsrf,
|
|
220
|
-
refreshTokenCookieName: environment.auth?.refreshTokenCookieName || 'refresh_token',
|
|
221
|
-
csrfTokenCookieName: environment.auth?.csrfTokenCookieName || 'csrf_token',
|
|
222
|
-
csrfHeaderName: environment.auth?.csrfHeaderName || 'X-CSRF-Token'
|
|
223
|
-
};
|
|
224
|
-
// Set default refresh endpoint based on mode if not specified
|
|
225
|
-
if (!this.authConfig.refreshEndpoint) {
|
|
226
|
-
this.authConfig.refreshEndpoint = this.authConfig.mode === 'cookie'
|
|
227
|
-
? '/auth/refresh'
|
|
228
|
-
: '/user/refresh_access';
|
|
229
|
-
}
|
|
230
|
-
// Set default CSRF setting based on mode if not specified
|
|
231
|
-
if (this.authConfig.useCsrf === undefined) {
|
|
232
|
-
this.authConfig.useCsrf = this.authConfig.mode === 'cookie';
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
async request(url, options, data) {
|
|
236
|
-
try {
|
|
237
|
-
if (data !== null) {
|
|
238
|
-
const body = JSON.stringify(data);
|
|
239
|
-
if (body) {
|
|
240
|
-
options.body = body;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
options.body = {};
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
const accessTokenIncluded = this.includeAccessToken(options);
|
|
247
|
-
let response = await fetch(url, options);
|
|
248
|
-
if ((response.status === 401) && accessTokenIncluded) {
|
|
249
|
-
response = await this.refreshAccessTokenAndRetry(url, options, response);
|
|
250
|
-
}
|
|
251
|
-
if (response.ok) {
|
|
252
|
-
const json = await (response.json());
|
|
253
|
-
return (new ApiResponse(json.status, json.data, json.message));
|
|
254
|
-
}
|
|
255
|
-
if (response.status === 401) {
|
|
256
|
-
this.signinStatus.signedOut();
|
|
257
|
-
}
|
|
258
|
-
return this.handleError(response);
|
|
259
|
-
}
|
|
260
|
-
catch (error) {
|
|
261
|
-
return this.handleError(error);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
handleError(error) {
|
|
265
|
-
console.error(`Backend returned code ${error.status}, ` +
|
|
266
|
-
`full error: `, error);
|
|
267
|
-
return new ApiResponse('error');
|
|
268
|
-
}
|
|
269
|
-
async get(endpoint, queryParamsObj) {
|
|
270
|
-
const url = this.host + endpoint.replace(/^\/+/, '') + this.buildQueryString(queryParamsObj);
|
|
271
|
-
const fetchOptions = {
|
|
272
|
-
mode: 'cors',
|
|
273
|
-
redirect: 'error'
|
|
274
|
-
};
|
|
275
|
-
return this.request(url, fetchOptions, null);
|
|
276
|
-
}
|
|
277
|
-
async post(pathWithQueryParams, data) {
|
|
278
|
-
const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
|
|
279
|
-
const fetchOptions = {
|
|
280
|
-
method: 'POST',
|
|
281
|
-
mode: 'cors',
|
|
282
|
-
redirect: 'error',
|
|
283
|
-
headers: {
|
|
284
|
-
'Content-Type': 'application/json'
|
|
285
|
-
},
|
|
286
|
-
body: JSON.stringify(data)
|
|
287
|
-
};
|
|
288
|
-
return this.request(url, fetchOptions, data);
|
|
289
|
-
}
|
|
290
|
-
async put(pathWithQueryParams, data) {
|
|
291
|
-
const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
|
|
292
|
-
const fetchOptions = {
|
|
293
|
-
method: 'PUT',
|
|
294
|
-
mode: 'cors',
|
|
295
|
-
redirect: 'error',
|
|
296
|
-
headers: {
|
|
297
|
-
'Content-Type': 'application/json'
|
|
298
|
-
},
|
|
299
|
-
body: JSON.stringify(data)
|
|
300
|
-
};
|
|
301
|
-
return this.request(url, fetchOptions, data);
|
|
302
|
-
}
|
|
303
|
-
async patch(pathWithQueryParams, data) {
|
|
304
|
-
const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
|
|
305
|
-
const fetchOptions = {
|
|
306
|
-
method: 'PATCH',
|
|
307
|
-
mode: 'cors',
|
|
308
|
-
redirect: 'error',
|
|
309
|
-
headers: {
|
|
310
|
-
'Content-Type': 'application/json'
|
|
311
|
-
},
|
|
312
|
-
body: JSON.stringify(data)
|
|
313
|
-
};
|
|
314
|
-
return this.request(url, fetchOptions, data);
|
|
315
|
-
}
|
|
316
|
-
async delete(endpoint, queryParamsObj) {
|
|
317
|
-
const url = this.host + endpoint.replace(/^\/+/, '') + this.buildQueryString(queryParamsObj);
|
|
318
|
-
const fetchOptions = {
|
|
319
|
-
method: 'DELETE',
|
|
320
|
-
mode: 'cors',
|
|
321
|
-
redirect: 'error'
|
|
322
|
-
};
|
|
323
|
-
return this.request(url, fetchOptions, null);
|
|
324
|
-
}
|
|
325
|
-
// async postFormWithFiles(pathWithQueryParams: string, formData: FormData): Promise<ApiResponse | null> {
|
|
326
|
-
// const url = this.host + pathWithQueryParams.replace(/^\/+/, '')
|
|
327
|
-
// try {
|
|
328
|
-
// const fetchOptions: RequestInit = {
|
|
329
|
-
// method: 'POST',
|
|
330
|
-
// mode: 'cors',
|
|
331
|
-
// redirect: 'error',
|
|
332
|
-
// body: formData
|
|
333
|
-
// }
|
|
334
|
-
// const accessTokenIncluded = this.includeAccessToken(fetchOptions)
|
|
335
|
-
// let response: Response = await fetch(url, fetchOptions)
|
|
336
|
-
// if ((response.status === 401) && accessTokenIncluded) {
|
|
337
|
-
// response = await this.refreshAccessTokenAndRetry(url, fetchOptions, response)
|
|
338
|
-
// }
|
|
339
|
-
// if (response.ok) {
|
|
340
|
-
// return ((await (response.json()) as ApiResponse))
|
|
341
|
-
// }
|
|
342
|
-
// return this.handleError(response)
|
|
343
|
-
// } catch (error) {
|
|
344
|
-
// return this.handleError(error)
|
|
345
|
-
// }
|
|
346
|
-
// }
|
|
347
|
-
includeAccessToken(options) {
|
|
348
|
-
this.accessToken = this.tokens.getAccessToken();
|
|
349
|
-
if (!this.accessToken) {
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
if (!options.headers) {
|
|
353
|
-
options.headers = {};
|
|
354
|
-
}
|
|
355
|
-
options.headers['Authorization'] = 'Bearer ' + this.accessToken;
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
async refreshAccessTokenAndRetry(url, fetchOptions, response) {
|
|
359
|
-
const refreshStatusOk = await this.refreshAccessToken();
|
|
360
|
-
if (!refreshStatusOk) {
|
|
361
|
-
return response;
|
|
362
|
-
}
|
|
363
|
-
fetchOptions.headers['Authorization'] = 'Bearer ' + this.accessToken;
|
|
364
|
-
response = await fetch(url, fetchOptions);
|
|
365
|
-
return response;
|
|
366
|
-
}
|
|
367
|
-
async refreshAccessToken() {
|
|
368
|
-
if (this.authConfig.mode === 'none') {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
if (this.authConfig.mode === 'cookie') {
|
|
372
|
-
return await this.refreshAccessTokenCookieMode();
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
return await this.refreshAccessTokenBodyMode();
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Refresh access token using cookie-based auth (StoneScriptPHP v2.1.x default)
|
|
380
|
-
*/
|
|
381
|
-
async refreshAccessTokenCookieMode() {
|
|
382
|
-
try {
|
|
383
|
-
const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint.replace(/^\/+/, '');
|
|
384
|
-
const headers = {
|
|
385
|
-
'Content-Type': 'application/json'
|
|
386
|
-
};
|
|
387
|
-
// Add CSRF token if enabled
|
|
388
|
-
if (this.authConfig.useCsrf) {
|
|
389
|
-
const csrfToken = this.csrf.getCsrfToken(this.authConfig.csrfTokenCookieName);
|
|
390
|
-
if (!csrfToken) {
|
|
391
|
-
console.error('CSRF token not found in cookie');
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
headers[this.authConfig.csrfHeaderName] = csrfToken;
|
|
395
|
-
}
|
|
396
|
-
let refreshTokenResponse = await fetch(refreshTokenUrl, {
|
|
397
|
-
method: 'POST',
|
|
398
|
-
mode: 'cors',
|
|
399
|
-
credentials: 'include', // Important: send cookies
|
|
400
|
-
redirect: 'error',
|
|
401
|
-
headers: headers
|
|
402
|
-
});
|
|
403
|
-
if (!refreshTokenResponse.ok) {
|
|
404
|
-
this.accessToken = '';
|
|
405
|
-
this.tokens.clear();
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
let refreshAccessData = await refreshTokenResponse.json();
|
|
409
|
-
if (!refreshAccessData || refreshAccessData.status !== 'ok') {
|
|
410
|
-
return false;
|
|
411
|
-
}
|
|
412
|
-
// Extract access token from response
|
|
413
|
-
const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token;
|
|
414
|
-
if (!newAccessToken) {
|
|
415
|
-
console.error('No access token in refresh response');
|
|
416
|
-
return false;
|
|
417
|
-
}
|
|
418
|
-
// Store new access token (refresh token is in httpOnly cookie)
|
|
419
|
-
this.tokens.setAccessToken(newAccessToken);
|
|
420
|
-
this.accessToken = newAccessToken;
|
|
421
|
-
return true;
|
|
422
|
-
}
|
|
423
|
-
catch (error) {
|
|
424
|
-
console.error('Token refresh failed (cookie mode):', error);
|
|
425
|
-
this.accessToken = '';
|
|
426
|
-
this.tokens.clear();
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Refresh access token using body-based auth (legacy mode)
|
|
432
|
-
*/
|
|
433
|
-
async refreshAccessTokenBodyMode() {
|
|
434
|
-
try {
|
|
435
|
-
const refreshToken = this.tokens.getRefreshToken();
|
|
436
|
-
if (!refreshToken) {
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint.replace(/^\/+/, '');
|
|
440
|
-
let refreshTokenResponse = await fetch(refreshTokenUrl, {
|
|
441
|
-
method: 'POST',
|
|
442
|
-
mode: 'cors',
|
|
443
|
-
redirect: 'error',
|
|
444
|
-
headers: {
|
|
445
|
-
'Content-Type': 'application/json'
|
|
446
|
-
},
|
|
447
|
-
body: JSON.stringify({
|
|
448
|
-
access_token: this.accessToken,
|
|
449
|
-
refresh_token: refreshToken
|
|
450
|
-
})
|
|
451
|
-
});
|
|
452
|
-
if (!refreshTokenResponse.ok) {
|
|
453
|
-
this.accessToken = '';
|
|
454
|
-
this.tokens.clear();
|
|
455
|
-
return false;
|
|
456
|
-
}
|
|
457
|
-
let refreshAccessData = await refreshTokenResponse.json();
|
|
458
|
-
if (!refreshAccessData) {
|
|
459
|
-
return false;
|
|
460
|
-
}
|
|
461
|
-
const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token;
|
|
462
|
-
if (!newAccessToken) {
|
|
463
|
-
console.error('No access token in refresh response');
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
this.tokens.setTokens(newAccessToken, refreshToken);
|
|
467
|
-
this.accessToken = newAccessToken;
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
|
-
catch (error) {
|
|
471
|
-
console.error('Token refresh failed (body mode):', error);
|
|
472
|
-
this.accessToken = '';
|
|
473
|
-
this.tokens.clear();
|
|
474
|
-
return false;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
buildQueryString(options) {
|
|
478
|
-
if (options === undefined) {
|
|
479
|
-
return '';
|
|
480
|
-
}
|
|
481
|
-
const array = [];
|
|
482
|
-
for (let key in options) {
|
|
483
|
-
if (options.hasOwnProperty(key) && (options[key] !== null) && (options[key] !== undefined)) {
|
|
484
|
-
array.push(encodeURIComponent(key) + "=" + encodeURIComponent(options[key]));
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
const str = array.join('&');
|
|
488
|
-
if (str !== '') {
|
|
489
|
-
return '?' + str;
|
|
490
|
-
}
|
|
491
|
-
return '';
|
|
492
|
-
}
|
|
493
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiConnectionService, deps: [{ token: TokenService }, { token: SigninStatusService }, { token: MyEnvironmentModel }, { token: CsrfService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
494
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiConnectionService, providedIn: 'root' }); }
|
|
495
|
-
}
|
|
496
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiConnectionService, decorators: [{
|
|
497
|
-
type: Injectable,
|
|
498
|
-
args: [{
|
|
499
|
-
providedIn: 'root'
|
|
500
|
-
}]
|
|
501
|
-
}], ctorParameters: () => [{ type: TokenService }, { type: SigninStatusService }, { type: MyEnvironmentModel }, { type: CsrfService }] });
|
|
502
|
-
|
|
503
|
-
class AuthService {
|
|
504
|
-
constructor() { }
|
|
505
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
506
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AuthService, providedIn: 'root' }); }
|
|
507
|
-
}
|
|
508
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AuthService, decorators: [{
|
|
509
|
-
type: Injectable,
|
|
510
|
-
args: [{
|
|
511
|
-
providedIn: 'root'
|
|
512
|
-
}]
|
|
513
|
-
}], ctorParameters: () => [] });
|
|
514
|
-
|
|
515
|
-
class DbService {
|
|
516
|
-
constructor() { }
|
|
517
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
518
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DbService, providedIn: 'root' }); }
|
|
519
|
-
}
|
|
520
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DbService, decorators: [{
|
|
521
|
-
type: Injectable,
|
|
522
|
-
args: [{
|
|
523
|
-
providedIn: 'root'
|
|
524
|
-
}]
|
|
525
|
-
}], ctorParameters: () => [] });
|
|
526
|
-
|
|
527
|
-
class NgxStoneScriptPhpClientModule {
|
|
528
|
-
static forRoot(environment) {
|
|
529
|
-
return {
|
|
530
|
-
ngModule: NgxStoneScriptPhpClientModule,
|
|
531
|
-
providers: [
|
|
532
|
-
{ provide: MyEnvironmentModel, useValue: environment }
|
|
533
|
-
]
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NgxStoneScriptPhpClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
537
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: NgxStoneScriptPhpClientModule, imports: [CommonModule] }); }
|
|
538
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NgxStoneScriptPhpClientModule, imports: [CommonModule] }); }
|
|
539
|
-
}
|
|
540
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NgxStoneScriptPhpClientModule, decorators: [{
|
|
541
|
-
type: NgModule,
|
|
542
|
-
args: [{
|
|
543
|
-
declarations: [],
|
|
544
|
-
imports: [
|
|
545
|
-
CommonModule
|
|
546
|
-
]
|
|
547
|
-
}]
|
|
548
|
-
}] });
|
|
549
|
-
|
|
550
|
-
/*
|
|
551
|
-
* Public API Surface of ngx-stonescriptphp-client
|
|
552
|
-
*/
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Generated bundle index. Do not edit.
|
|
556
|
-
*/
|
|
557
|
-
|
|
558
|
-
export { ApiConnectionService, ApiResponse, AuthService, CsrfService, DbService, MyEnvironmentModel, NgxStoneScriptPhpClientModule, SigninStatusService, TokenService };
|
|
559
|
-
//# sourceMappingURL=progalaxyelabs-ngx-stonescriptphp-client.mjs.map
|
package/dist/ngx-stonescriptphp-client/fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"progalaxyelabs-ngx-stonescriptphp-client.mjs","sources":["../../../projects/ngx-stonescriptphp-client/src/lib/api-response.model.ts","../../../projects/ngx-stonescriptphp-client/src/lib/token.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/signin-status.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/my-environment.model.ts","../../../projects/ngx-stonescriptphp-client/src/lib/csrf.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/api-connection.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/auth.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/db.service.ts","../../../projects/ngx-stonescriptphp-client/src/lib/ngx-stonescriptphp-client/ngx-stonescriptphp-client.module.ts","../../../projects/ngx-stonescriptphp-client/src/public-api.ts","../../../projects/ngx-stonescriptphp-client/src/progalaxyelabs-ngx-stonescriptphp-client.ts"],"sourcesContent":["export class ApiResponse<DataType> {\n private status: string\n private data: any\n private message: string\n\n constructor(status: string, data: any = {}, message: string = '') {\n this.status = status\n this.data = data\n this.message = message\n }\n\n onOk(callback: (data: DataType) => void): ApiResponse<DataType> {\n if (this.status === 'ok') {\n callback(this.data)\n }\n return this\n }\n\n onNotOk(callback: (message: string, data: DataType) => void): ApiResponse<DataType> {\n if (this.status === 'not ok') {\n callback(this.message, this.data)\n }\n return this\n }\n\n onError(callback: () => void): ApiResponse<DataType> {\n if (this.status === 'error') {\n callback()\n }\n return this\n }\n\n isSuccess(): boolean {\n return this.status === 'ok'\n }\n\n isError(): boolean {\n return this.status === 'error' || this.status === 'not ok'\n }\n\n getData(): DataType | null {\n return this.data || null\n }\n\n getError(): string {\n return this.message || 'Unknown error'\n }\n\n getStatus(): string {\n return this.status\n }\n\n getMessage(): string {\n return this.message\n }\n}","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class TokenService {\n private accessToken = ''\n private refreshToken = ''\n\n private lsAccessTokenKey = 'progalaxyapi_access_token'\n private lsRefreshTokenKey = 'progalaxyapi_refresh_token'\n\n constructor() { }\n\n setTokens(accessToken: string, refreshToken: string) {\n this.accessToken = accessToken\n this.refreshToken = refreshToken\n localStorage.setItem(this.lsAccessTokenKey, accessToken)\n localStorage.setItem(this.lsRefreshTokenKey, refreshToken)\n }\n\n setAccessToken(accessToken: string) {\n this.accessToken = accessToken\n localStorage.setItem(this.lsAccessTokenKey, accessToken)\n }\n\n setRefreshToken(refreshToken: string) {\n this.refreshToken = refreshToken\n localStorage.setItem(this.lsRefreshTokenKey, refreshToken)\n }\n\n getAccessToken() {\n if (this.accessToken) {\n return this.accessToken\n }\n\n const storedAccessToken = localStorage.getItem(this.lsAccessTokenKey)\n if (storedAccessToken) {\n return storedAccessToken\n } else {\n return ''\n }\n }\n\n getRefreshToken() {\n if (this.refreshToken) {\n return this.refreshToken\n }\n\n const storedRefreshToken = localStorage.getItem(this.lsRefreshTokenKey)\n if (storedRefreshToken) {\n return storedRefreshToken\n } else {\n return ''\n }\n }\n\n clear() {\n this.accessToken = ''\n this.refreshToken = ''\n localStorage.removeItem(this.lsAccessTokenKey)\n localStorage.removeItem(this.lsRefreshTokenKey)\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class SigninStatusService {\n public status: BehaviorSubject<boolean>\n\n constructor() {\n this.status = new BehaviorSubject<boolean>(false)\n }\n\n signedOut(): void {\n this.status.next(false)\n }\n\n signedIn(): void {\n this.status.next(true)\n }\n}\n","export type AuthMode = 'cookie' | 'body' | 'none';\n\nexport interface AuthConfig {\n /**\n * Authentication mode:\n * - 'cookie': Use httpOnly cookies + CSRF tokens (recommended, matches StoneScriptPHP v2.1.x)\n * - 'body': Send tokens in request body (legacy mode)\n * - 'none': No automatic token refresh\n */\n mode: AuthMode;\n\n /**\n * Token refresh endpoint path\n * @default '/auth/refresh' for cookie mode, '/user/refresh_access' for body mode\n */\n refreshEndpoint?: string;\n\n /**\n * Enable CSRF token support (required for cookie mode)\n * @default true for cookie mode, false for body mode\n */\n useCsrf?: boolean;\n\n /**\n * Cookie name for refresh token\n * @default 'refresh_token'\n */\n refreshTokenCookieName?: string;\n\n /**\n * Cookie name for CSRF token\n * @default 'csrf_token'\n */\n csrfTokenCookieName?: string;\n\n /**\n * CSRF header name\n * @default 'X-CSRF-Token'\n */\n csrfHeaderName?: string;\n}\n\nexport class MyEnvironmentModel {\n production: boolean = true\n firebase: {\n projectId: string\n appId: string\n databaseURL: string\n storageBucket: string\n locationId: string\n apiKey: string\n authDomain: string\n messagingSenderId: string\n measurementId: string\n } = {\n projectId: '',\n appId: '',\n databaseURL: '',\n storageBucket: '',\n locationId: '',\n apiKey: '',\n authDomain: '',\n messagingSenderId: '',\n measurementId: ''\n }\n apiServer: {\n host: string\n } = { host: '' }\n chatServer: {\n host: string\n } = { host: '' }\n\n /**\n * Authentication configuration\n * @default { mode: 'cookie', refreshEndpoint: '/auth/refresh', useCsrf: true }\n */\n auth?: AuthConfig = {\n mode: 'cookie',\n refreshEndpoint: '/auth/refresh',\n useCsrf: true,\n refreshTokenCookieName: 'refresh_token',\n csrfTokenCookieName: 'csrf_token',\n csrfHeaderName: 'X-CSRF-Token'\n };\n}","import { Injectable } from '@angular/core';\n\n/**\n * CSRF Token Service\n *\n * Manages CSRF tokens for cookie-based authentication.\n * Reads CSRF token from cookies and provides it for request headers.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class CsrfService {\n\n /**\n * Get CSRF token from cookie\n */\n getCsrfToken(cookieName: string = 'csrf_token'): string | null {\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split('=');\n if (name === cookieName) {\n return decodeURIComponent(value);\n }\n }\n return null;\n }\n\n /**\n * Check if CSRF token exists\n */\n hasCsrfToken(cookieName: string = 'csrf_token'): boolean {\n return this.getCsrfToken(cookieName) !== null;\n }\n\n /**\n * Clear CSRF token (for logout)\n * Note: Client-side deletion is limited for httpOnly cookies\n */\n clearCsrfToken(cookieName: string = 'csrf_token'): void {\n // Can only clear non-httpOnly cookies\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { TokenService } from './token.service';\nimport { SigninStatusService } from './signin-status.service';\nimport { ApiResponse } from './api-response.model';\nimport { MyEnvironmentModel, AuthConfig } from './my-environment.model';\nimport { CsrfService } from './csrf.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ApiConnectionService {\n\n private host = '' // contains trailing slash\n\n private accessToken = ''\n\n private authConfig: AuthConfig\n\n constructor(\n private tokens: TokenService,\n private signinStatus: SigninStatusService,\n private environment: MyEnvironmentModel,\n private csrf: CsrfService\n ) {\n this.host = environment.apiServer.host\n\n // Set default auth config based on mode\n this.authConfig = {\n mode: environment.auth?.mode || 'cookie',\n refreshEndpoint: environment.auth?.refreshEndpoint,\n useCsrf: environment.auth?.useCsrf,\n refreshTokenCookieName: environment.auth?.refreshTokenCookieName || 'refresh_token',\n csrfTokenCookieName: environment.auth?.csrfTokenCookieName || 'csrf_token',\n csrfHeaderName: environment.auth?.csrfHeaderName || 'X-CSRF-Token'\n }\n\n // Set default refresh endpoint based on mode if not specified\n if (!this.authConfig.refreshEndpoint) {\n this.authConfig.refreshEndpoint = this.authConfig.mode === 'cookie'\n ? '/auth/refresh'\n : '/user/refresh_access'\n }\n\n // Set default CSRF setting based on mode if not specified\n if (this.authConfig.useCsrf === undefined) {\n this.authConfig.useCsrf = this.authConfig.mode === 'cookie'\n }\n }\n\n\n private async request<DataType>(url: string, options: any, data: any | null): Promise<ApiResponse<DataType>> {\n try {\n \n if(data !== null) {\n const body = JSON.stringify(data)\n if(body) {\n options.body = body\n } else {\n options.body = {}\n }\n }\n\n const accessTokenIncluded = this.includeAccessToken(options)\n\n let response: Response = await fetch(url, options)\n\n if ((response.status === 401) && accessTokenIncluded) {\n response = await this.refreshAccessTokenAndRetry(url, options, response)\n }\n\n if (response.ok) {\n const json = await (response.json())\n return (new ApiResponse<DataType>(json.status, json.data, json.message))\n }\n\n if (response.status === 401) {\n this.signinStatus.signedOut()\n }\n\n return this.handleError<DataType>(response)\n } catch (error) {\n return this.handleError<DataType>(error)\n }\n }\n\n private handleError<DataType>(error: any): ApiResponse<DataType> {\n console.error(\n `Backend returned code ${error.status}, ` +\n `full error: `, error);\n return new ApiResponse<DataType>('error')\n }\n\n async get<DataType>(endpoint: string, queryParamsObj?: any ): Promise<ApiResponse<DataType>> {\n const url = this.host + endpoint.replace(/^\\/+/, '') + this.buildQueryString(queryParamsObj)\n const fetchOptions: RequestInit = {\n mode: 'cors',\n redirect: 'error'\n }\n return this.request(url, fetchOptions, null)\n }\n\n async post<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>> {\n const url = this.host + pathWithQueryParams.replace(/^\\/+/, '')\n const fetchOptions: RequestInit = {\n method: 'POST',\n mode: 'cors',\n redirect: 'error',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(data)\n }\n return this.request(url, fetchOptions, data)\n }\n\n async put<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>> {\n const url = this.host + pathWithQueryParams.replace(/^\\/+/, '')\n const fetchOptions: RequestInit = {\n method: 'PUT',\n mode: 'cors',\n redirect: 'error',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(data)\n }\n return this.request(url, fetchOptions, data)\n }\n\n async patch<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>> {\n const url = this.host + pathWithQueryParams.replace(/^\\/+/, '')\n const fetchOptions: RequestInit = {\n method: 'PATCH',\n mode: 'cors',\n redirect: 'error',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(data)\n }\n return this.request(url, fetchOptions, data)\n }\n\n async delete<DataType>(endpoint: string, queryParamsObj?: any): Promise<ApiResponse<DataType>> {\n const url = this.host + endpoint.replace(/^\\/+/, '') + this.buildQueryString(queryParamsObj)\n const fetchOptions: RequestInit = {\n method: 'DELETE',\n mode: 'cors',\n redirect: 'error'\n }\n return this.request(url, fetchOptions, null)\n }\n\n // async postFormWithFiles(pathWithQueryParams: string, formData: FormData): Promise<ApiResponse | null> {\n // const url = this.host + pathWithQueryParams.replace(/^\\/+/, '')\n // try {\n // const fetchOptions: RequestInit = {\n // method: 'POST',\n // mode: 'cors',\n // redirect: 'error',\n // body: formData\n // }\n\n // const accessTokenIncluded = this.includeAccessToken(fetchOptions)\n\n // let response: Response = await fetch(url, fetchOptions)\n\n // if ((response.status === 401) && accessTokenIncluded) {\n // response = await this.refreshAccessTokenAndRetry(url, fetchOptions, response)\n // }\n\n // if (response.ok) {\n // return ((await (response.json()) as ApiResponse))\n // }\n\n // return this.handleError(response)\n // } catch (error) {\n // return this.handleError(error)\n // }\n // }\n\n private includeAccessToken(options: any): boolean {\n this.accessToken = this.tokens.getAccessToken()\n if (!this.accessToken) {\n return false\n }\n\n if (!options.headers) {\n options.headers = {}\n }\n options.headers['Authorization'] = 'Bearer ' + this.accessToken\n return true\n }\n\n private async refreshAccessTokenAndRetry(url: string, fetchOptions: any, response: Response): Promise<Response> {\n\n const refreshStatusOk = await this.refreshAccessToken()\n if (!refreshStatusOk) {\n return response\n }\n\n fetchOptions.headers['Authorization'] = 'Bearer ' + this.accessToken\n response = await fetch(url, fetchOptions)\n return response\n }\n\n async refreshAccessToken(): Promise<boolean> {\n if (this.authConfig.mode === 'none') {\n return false\n }\n\n if (this.authConfig.mode === 'cookie') {\n return await this.refreshAccessTokenCookieMode()\n } else {\n return await this.refreshAccessTokenBodyMode()\n }\n }\n\n /**\n * Refresh access token using cookie-based auth (StoneScriptPHP v2.1.x default)\n */\n private async refreshAccessTokenCookieMode(): Promise<boolean> {\n try {\n const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint!.replace(/^\\/+/, '')\n const headers: any = {\n 'Content-Type': 'application/json'\n }\n\n // Add CSRF token if enabled\n if (this.authConfig.useCsrf) {\n const csrfToken = this.csrf.getCsrfToken(this.authConfig.csrfTokenCookieName!)\n if (!csrfToken) {\n console.error('CSRF token not found in cookie')\n return false\n }\n headers[this.authConfig.csrfHeaderName!] = csrfToken\n }\n\n let refreshTokenResponse = await fetch(refreshTokenUrl, {\n method: 'POST',\n mode: 'cors',\n credentials: 'include', // Important: send cookies\n redirect: 'error',\n headers: headers\n })\n\n if (!refreshTokenResponse.ok) {\n this.accessToken = ''\n this.tokens.clear()\n return false\n }\n\n let refreshAccessData = await refreshTokenResponse.json()\n if (!refreshAccessData || refreshAccessData.status !== 'ok') {\n return false\n }\n\n // Extract access token from response\n const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token\n if (!newAccessToken) {\n console.error('No access token in refresh response')\n return false\n }\n\n // Store new access token (refresh token is in httpOnly cookie)\n this.tokens.setAccessToken(newAccessToken)\n this.accessToken = newAccessToken\n\n return true\n } catch (error) {\n console.error('Token refresh failed (cookie mode):', error)\n this.accessToken = ''\n this.tokens.clear()\n return false\n }\n }\n\n /**\n * Refresh access token using body-based auth (legacy mode)\n */\n private async refreshAccessTokenBodyMode(): Promise<boolean> {\n try {\n const refreshToken = this.tokens.getRefreshToken()\n if (!refreshToken) {\n return false\n }\n\n const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint!.replace(/^\\/+/, '')\n let refreshTokenResponse = await fetch(refreshTokenUrl, {\n method: 'POST',\n mode: 'cors',\n redirect: 'error',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n access_token: this.accessToken,\n refresh_token: refreshToken\n })\n })\n\n if (!refreshTokenResponse.ok) {\n this.accessToken = ''\n this.tokens.clear()\n return false\n }\n\n let refreshAccessData = await refreshTokenResponse.json()\n if (!refreshAccessData) {\n return false\n }\n\n const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token\n if (!newAccessToken) {\n console.error('No access token in refresh response')\n return false\n }\n\n this.tokens.setTokens(newAccessToken, refreshToken)\n this.accessToken = newAccessToken\n\n return true\n } catch (error) {\n console.error('Token refresh failed (body mode):', error)\n this.accessToken = ''\n this.tokens.clear()\n return false\n }\n }\n\n buildQueryString(options?: any): string {\n if (options === undefined) {\n return ''\n }\n\n const array = []\n for (let key in options) {\n if (options.hasOwnProperty(key) && (options[key] !== null) && (options[key] !== undefined)) {\n array.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(options[key]))\n }\n }\n const str = array.join('&')\n if (str !== '') {\n return '?' + str\n }\n\n return ''\n }\n}\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthService {\n\n constructor() { }\n}\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DbService {\n\n constructor() { }\n}\n","import { ModuleWithProviders, NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MyEnvironmentModel } from '../my-environment.model';\n\n\n\n@NgModule({\n declarations: [],\n imports: [\n CommonModule\n ]\n})\nexport class NgxStoneScriptPhpClientModule {\n public static forRoot(environment: MyEnvironmentModel): ModuleWithProviders<NgxStoneScriptPhpClientModule> {\n return {\n ngModule: NgxStoneScriptPhpClientModule,\n providers: [\n { provide: MyEnvironmentModel, useValue: environment }\n ]\n }\n }\n}\n","/*\n * Public API Surface of ngx-stonescriptphp-client\n */\n\nexport * from './lib/api-connection.service';\nexport * from './lib/auth.service';\nexport * from './lib/db.service';\nexport * from './lib/signin-status.service';\nexport * from './lib/token.service';\nexport * from './lib/csrf.service';\nexport * from './lib/api-response.model';\nexport * from './lib/my-environment.model';\nexport * from './lib/ngx-stonescriptphp-client/ngx-stonescriptphp-client.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.TokenService","i2.SigninStatusService","i3.MyEnvironmentModel","i4.CsrfService"],"mappings":"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"}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { ModuleWithProviders } from '@angular/core';
|
|
3
|
-
import { BehaviorSubject } from 'rxjs';
|
|
4
|
-
import * as i1 from '@angular/common';
|
|
5
|
-
|
|
6
|
-
declare class TokenService {
|
|
7
|
-
private accessToken;
|
|
8
|
-
private refreshToken;
|
|
9
|
-
private lsAccessTokenKey;
|
|
10
|
-
private lsRefreshTokenKey;
|
|
11
|
-
constructor();
|
|
12
|
-
setTokens(accessToken: string, refreshToken: string): void;
|
|
13
|
-
setAccessToken(accessToken: string): void;
|
|
14
|
-
setRefreshToken(refreshToken: string): void;
|
|
15
|
-
getAccessToken(): string;
|
|
16
|
-
getRefreshToken(): string;
|
|
17
|
-
clear(): void;
|
|
18
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<TokenService, never>;
|
|
19
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<TokenService>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare class SigninStatusService {
|
|
23
|
-
status: BehaviorSubject<boolean>;
|
|
24
|
-
constructor();
|
|
25
|
-
signedOut(): void;
|
|
26
|
-
signedIn(): void;
|
|
27
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<SigninStatusService, never>;
|
|
28
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<SigninStatusService>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare class ApiResponse<DataType> {
|
|
32
|
-
private status;
|
|
33
|
-
private data;
|
|
34
|
-
private message;
|
|
35
|
-
constructor(status: string, data?: any, message?: string);
|
|
36
|
-
onOk(callback: (data: DataType) => void): ApiResponse<DataType>;
|
|
37
|
-
onNotOk(callback: (message: string, data: DataType) => void): ApiResponse<DataType>;
|
|
38
|
-
onError(callback: () => void): ApiResponse<DataType>;
|
|
39
|
-
isSuccess(): boolean;
|
|
40
|
-
isError(): boolean;
|
|
41
|
-
getData(): DataType | null;
|
|
42
|
-
getError(): string;
|
|
43
|
-
getStatus(): string;
|
|
44
|
-
getMessage(): string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
type AuthMode = 'cookie' | 'body' | 'none';
|
|
48
|
-
interface AuthConfig {
|
|
49
|
-
/**
|
|
50
|
-
* Authentication mode:
|
|
51
|
-
* - 'cookie': Use httpOnly cookies + CSRF tokens (recommended, matches StoneScriptPHP v2.1.x)
|
|
52
|
-
* - 'body': Send tokens in request body (legacy mode)
|
|
53
|
-
* - 'none': No automatic token refresh
|
|
54
|
-
*/
|
|
55
|
-
mode: AuthMode;
|
|
56
|
-
/**
|
|
57
|
-
* Token refresh endpoint path
|
|
58
|
-
* @default '/auth/refresh' for cookie mode, '/user/refresh_access' for body mode
|
|
59
|
-
*/
|
|
60
|
-
refreshEndpoint?: string;
|
|
61
|
-
/**
|
|
62
|
-
* Enable CSRF token support (required for cookie mode)
|
|
63
|
-
* @default true for cookie mode, false for body mode
|
|
64
|
-
*/
|
|
65
|
-
useCsrf?: boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Cookie name for refresh token
|
|
68
|
-
* @default 'refresh_token'
|
|
69
|
-
*/
|
|
70
|
-
refreshTokenCookieName?: string;
|
|
71
|
-
/**
|
|
72
|
-
* Cookie name for CSRF token
|
|
73
|
-
* @default 'csrf_token'
|
|
74
|
-
*/
|
|
75
|
-
csrfTokenCookieName?: string;
|
|
76
|
-
/**
|
|
77
|
-
* CSRF header name
|
|
78
|
-
* @default 'X-CSRF-Token'
|
|
79
|
-
*/
|
|
80
|
-
csrfHeaderName?: string;
|
|
81
|
-
}
|
|
82
|
-
declare class MyEnvironmentModel {
|
|
83
|
-
production: boolean;
|
|
84
|
-
firebase: {
|
|
85
|
-
projectId: string;
|
|
86
|
-
appId: string;
|
|
87
|
-
databaseURL: string;
|
|
88
|
-
storageBucket: string;
|
|
89
|
-
locationId: string;
|
|
90
|
-
apiKey: string;
|
|
91
|
-
authDomain: string;
|
|
92
|
-
messagingSenderId: string;
|
|
93
|
-
measurementId: string;
|
|
94
|
-
};
|
|
95
|
-
apiServer: {
|
|
96
|
-
host: string;
|
|
97
|
-
};
|
|
98
|
-
chatServer: {
|
|
99
|
-
host: string;
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
* Authentication configuration
|
|
103
|
-
* @default { mode: 'cookie', refreshEndpoint: '/auth/refresh', useCsrf: true }
|
|
104
|
-
*/
|
|
105
|
-
auth?: AuthConfig;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* CSRF Token Service
|
|
110
|
-
*
|
|
111
|
-
* Manages CSRF tokens for cookie-based authentication.
|
|
112
|
-
* Reads CSRF token from cookies and provides it for request headers.
|
|
113
|
-
*/
|
|
114
|
-
declare class CsrfService {
|
|
115
|
-
/**
|
|
116
|
-
* Get CSRF token from cookie
|
|
117
|
-
*/
|
|
118
|
-
getCsrfToken(cookieName?: string): string | null;
|
|
119
|
-
/**
|
|
120
|
-
* Check if CSRF token exists
|
|
121
|
-
*/
|
|
122
|
-
hasCsrfToken(cookieName?: string): boolean;
|
|
123
|
-
/**
|
|
124
|
-
* Clear CSRF token (for logout)
|
|
125
|
-
* Note: Client-side deletion is limited for httpOnly cookies
|
|
126
|
-
*/
|
|
127
|
-
clearCsrfToken(cookieName?: string): void;
|
|
128
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<CsrfService, never>;
|
|
129
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<CsrfService>;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
declare class ApiConnectionService {
|
|
133
|
-
private tokens;
|
|
134
|
-
private signinStatus;
|
|
135
|
-
private environment;
|
|
136
|
-
private csrf;
|
|
137
|
-
private host;
|
|
138
|
-
private accessToken;
|
|
139
|
-
private authConfig;
|
|
140
|
-
constructor(tokens: TokenService, signinStatus: SigninStatusService, environment: MyEnvironmentModel, csrf: CsrfService);
|
|
141
|
-
private request;
|
|
142
|
-
private handleError;
|
|
143
|
-
get<DataType>(endpoint: string, queryParamsObj?: any): Promise<ApiResponse<DataType>>;
|
|
144
|
-
post<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>>;
|
|
145
|
-
put<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>>;
|
|
146
|
-
patch<DataType>(pathWithQueryParams: string, data: any): Promise<ApiResponse<DataType>>;
|
|
147
|
-
delete<DataType>(endpoint: string, queryParamsObj?: any): Promise<ApiResponse<DataType>>;
|
|
148
|
-
private includeAccessToken;
|
|
149
|
-
private refreshAccessTokenAndRetry;
|
|
150
|
-
refreshAccessToken(): Promise<boolean>;
|
|
151
|
-
/**
|
|
152
|
-
* Refresh access token using cookie-based auth (StoneScriptPHP v2.1.x default)
|
|
153
|
-
*/
|
|
154
|
-
private refreshAccessTokenCookieMode;
|
|
155
|
-
/**
|
|
156
|
-
* Refresh access token using body-based auth (legacy mode)
|
|
157
|
-
*/
|
|
158
|
-
private refreshAccessTokenBodyMode;
|
|
159
|
-
buildQueryString(options?: any): string;
|
|
160
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<ApiConnectionService, never>;
|
|
161
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<ApiConnectionService>;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
declare class AuthService {
|
|
165
|
-
constructor();
|
|
166
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, never>;
|
|
167
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
declare class DbService {
|
|
171
|
-
constructor();
|
|
172
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<DbService, never>;
|
|
173
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<DbService>;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
declare class NgxStoneScriptPhpClientModule {
|
|
177
|
-
static forRoot(environment: MyEnvironmentModel): ModuleWithProviders<NgxStoneScriptPhpClientModule>;
|
|
178
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<NgxStoneScriptPhpClientModule, never>;
|
|
179
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<NgxStoneScriptPhpClientModule, never, [typeof i1.CommonModule], never>;
|
|
180
|
-
static ɵinj: i0.ɵɵInjectorDeclaration<NgxStoneScriptPhpClientModule>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export { ApiConnectionService, ApiResponse, AuthService, CsrfService, DbService, MyEnvironmentModel, NgxStoneScriptPhpClientModule, SigninStatusService, TokenService };
|
|
184
|
-
export type { AuthConfig, AuthMode };
|