@singularlogic/coreplatts 0.0.4 โ 0.0.5
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 +166 -0
- package/dist/index.js +12 -26
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @singularlogic/coreplatts
|
|
2
|
+
|
|
3
|
+
A TypeScript client library to access the **BUILDSPACE** identity and storage APIs.
|
|
4
|
+
Built to work with [Keycloak](https://www.keycloak.org/) and [MinIO](https://min.io/), this library wraps REST endpoints and handles authentication, token refresh, organization and folder management.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## ๐ฆ Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @singularlogic/coreplatts
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ๐ Getting Started
|
|
17
|
+
|
|
18
|
+
### Create a client
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { Client } from '@singularlogic/coreplatts';
|
|
22
|
+
|
|
23
|
+
const managementURL = 'https://api-buildspace.euinno.eu';
|
|
24
|
+
const accountURL = 'https://account-buildspace.euinno.eu';
|
|
25
|
+
|
|
26
|
+
const client = new Client(managementURL, accountURL);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ๐ Authentication
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const token = await client.login('user@example.com', 'password');
|
|
35
|
+
console.log('Access token:', token.access_token);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Tokens are stored in `localStorage` or `sessionStorage` and automatically refreshed when expired.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ๐ค User Management
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const me = await client.myUser(); // auto-includes access token
|
|
46
|
+
console.log(me.username);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Register new users:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
await client.register(
|
|
53
|
+
'new@user.com',
|
|
54
|
+
'password123',
|
|
55
|
+
'password123',
|
|
56
|
+
'First',
|
|
57
|
+
'Last'
|
|
58
|
+
);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## ๐งโ๐คโ๐ง Organizations (Groups)
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const orgs = await client.allOrganizations();
|
|
67
|
+
const myOrgs = await client.myOrganizations();
|
|
68
|
+
|
|
69
|
+
const org = await client.organizationByName('MyOrg');
|
|
70
|
+
|
|
71
|
+
await client.createOrganization('MyNewOrg');
|
|
72
|
+
|
|
73
|
+
await client.addToOrganization('MyNewOrg', {
|
|
74
|
+
'user1@example.com': 'MEMBER',
|
|
75
|
+
'admin@example.com': 'ADMIN'
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## ๐ Folder & File Management
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const folder = await client.getFolderByName('project-data');
|
|
85
|
+
console.log(folder.files);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
You can also upload and download files using `Folder` and `File` methods.
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const file = await folder.getFileByName('report.pdf');
|
|
94
|
+
await file.download();
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## ๐ Automatic Token Handling
|
|
100
|
+
|
|
101
|
+
All token-sensitive methods use a utility that:
|
|
102
|
+
- Checks if the access token is expired
|
|
103
|
+
- Refreshes it using `refresh_token` if needed
|
|
104
|
+
- Uses `localStorage` or `sessionStorage` automatically
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## ๐งช Example in Angular Service
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { Injectable } from '@angular/core';
|
|
112
|
+
import { Client } from '@singularlogic/coreplatts';
|
|
113
|
+
import { environment } from '../environments/environment';
|
|
114
|
+
|
|
115
|
+
@Injectable({ providedIn: 'root' })
|
|
116
|
+
export class AuthService {
|
|
117
|
+
client = new Client(environment.managementURL, environment.accountURL);
|
|
118
|
+
|
|
119
|
+
getCurrentUser() {
|
|
120
|
+
return this.client.myUser();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## ๐งฑ Core Classes
|
|
128
|
+
|
|
129
|
+
### `Client`
|
|
130
|
+
|
|
131
|
+
- Handles auth, session, and proxies to:
|
|
132
|
+
- `UserConsumer`
|
|
133
|
+
- `GroupConsumer`
|
|
134
|
+
- `BucketConsumer`
|
|
135
|
+
- `FolderConsumer`
|
|
136
|
+
|
|
137
|
+
### `Folder`
|
|
138
|
+
|
|
139
|
+
- Can fetch files
|
|
140
|
+
- Can upload files with chunking and concurrency control
|
|
141
|
+
|
|
142
|
+
### `File`
|
|
143
|
+
|
|
144
|
+
- Can be downloaded by ID or name
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## ๐ API Summary
|
|
149
|
+
|
|
150
|
+
| Method | Description |
|
|
151
|
+
|--------|-------------|
|
|
152
|
+
| `login(email, password)` | Authenticate user |
|
|
153
|
+
| `myUser()` | Get current user info |
|
|
154
|
+
| `register(...)` | Create new user |
|
|
155
|
+
| `allOrganizations()` | List all groups |
|
|
156
|
+
| `createOrganization(name)` | Create group + bucket |
|
|
157
|
+
| `addToOrganization(name, users)` | Assign roles |
|
|
158
|
+
| `getFolderByName(name)` | Retrieve folder |
|
|
159
|
+
| `getFolderByID(id)` | Retrieve folder by ID |
|
|
160
|
+
| `removeOrganizationByID(id)` | Delete group and bucket |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## ๐ License
|
|
165
|
+
|
|
166
|
+
MIT ยฉ [SingularLogic S.A.](https://www.singularlogic.eu)
|
package/dist/index.js
CHANGED
|
@@ -272,30 +272,16 @@ var BucketConsumer = class extends BaseConsumer {
|
|
|
272
272
|
function withValidToken(fn, accountsAPI) {
|
|
273
273
|
return function(...args) {
|
|
274
274
|
return __async(this, null, function* () {
|
|
275
|
-
|
|
276
|
-
const isBrowser = typeof window !== "undefined";
|
|
277
|
-
const storage = isBrowser ? (_a = window.sessionStorage) != null ? _a : window.localStorage : void 0;
|
|
278
|
-
if (!storage) {
|
|
279
|
-
console.warn("\u26A0\uFE0F sessionStorage or localStorage not available. You must pass token manually.");
|
|
280
|
-
return Promise.resolve(fn.apply(this, args));
|
|
281
|
-
}
|
|
275
|
+
const isStorageAvailable = typeof localStorage !== "undefined";
|
|
282
276
|
const now = Math.floor(Date.now() / 1e3);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
let refreshExp = Number(storage.getItem("refresh_exp") || "0");
|
|
287
|
-
if ((!exp || !refreshExp) && storage.getItem("id_token_claims_obj")) {
|
|
288
|
-
try {
|
|
289
|
-
const claims = JSON.parse(storage.getItem("id_token_claims_obj"));
|
|
290
|
-
if (claims.exp) exp = claims.exp;
|
|
291
|
-
if (claims.iat && claims.exp) {
|
|
292
|
-
const estimatedDuration = claims.exp - claims.iat;
|
|
293
|
-
refreshExp = claims.iat + 3 * estimatedDuration;
|
|
294
|
-
}
|
|
295
|
-
} catch (err) {
|
|
296
|
-
console.warn("\u26A0\uFE0F Could not parse id_token_claims_obj:", err);
|
|
297
|
-
}
|
|
277
|
+
if (!isStorageAvailable) {
|
|
278
|
+
console.warn("\u26A0\uFE0F localStorage not available. You must pass token manually.");
|
|
279
|
+
return Promise.resolve(fn.apply(this, args));
|
|
298
280
|
}
|
|
281
|
+
let token = localStorage.getItem("token");
|
|
282
|
+
const refreshToken = localStorage.getItem("refresh_token");
|
|
283
|
+
const exp = Number(localStorage.getItem("exp") || "0");
|
|
284
|
+
const refreshExp = Number(localStorage.getItem("refresh_exp") || "0");
|
|
299
285
|
if (!token || now >= exp) {
|
|
300
286
|
if (!refreshToken || now >= refreshExp) {
|
|
301
287
|
console.warn("\u26A0\uFE0F Session expired. Please log in again.");
|
|
@@ -311,10 +297,10 @@ function withValidToken(fn, accountsAPI) {
|
|
|
311
297
|
const session = yield response.json();
|
|
312
298
|
const newExp = now + session.expires_in;
|
|
313
299
|
const newRefreshExp = now + session.refresh_expires_in;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
300
|
+
localStorage.setItem("token", session.access_token);
|
|
301
|
+
localStorage.setItem("refresh_token", session.refresh_token);
|
|
302
|
+
localStorage.setItem("exp", String(newExp));
|
|
303
|
+
localStorage.setItem("refresh_exp", String(newRefreshExp));
|
|
318
304
|
token = session.access_token;
|
|
319
305
|
} catch (e) {
|
|
320
306
|
console.error("\u{1F510} Token refresh failed:", e);
|