@singularlogic/coreplatts 0.0.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.
@@ -0,0 +1,177 @@
1
+ import { AxiosInstance } from 'axios';
2
+
3
+ interface Updated {
4
+ by?: string;
5
+ at?: Date;
6
+ }
7
+ interface Meta {
8
+ creator?: string;
9
+ description?: string;
10
+ title?: string;
11
+ date_creation?: Date | null;
12
+ write?: string[];
13
+ read?: string[];
14
+ tags?: string[];
15
+ update?: Updated;
16
+ }
17
+ interface FileModel {
18
+ _id?: string;
19
+ meta: Meta;
20
+ folder: string;
21
+ ancestors?: string[];
22
+ original_title: string;
23
+ file_type: string;
24
+ size: number;
25
+ total?: number;
26
+ }
27
+ interface FolderModel {
28
+ _id: string;
29
+ meta: Meta;
30
+ parent: string;
31
+ ancestors: string[];
32
+ files: string[];
33
+ folders: string[];
34
+ level: number;
35
+ size: number;
36
+ }
37
+ interface FolderList {
38
+ files: FileModel[];
39
+ folder: FolderModel[];
40
+ }
41
+
42
+ declare class File$1 implements FileModel {
43
+ protected _httpClient: AxiosInstance;
44
+ _id?: string;
45
+ meta: Meta;
46
+ folder: string;
47
+ ancestors?: string[];
48
+ original_title: string;
49
+ file_type: string;
50
+ size: number;
51
+ total?: number;
52
+ _managementURL: string;
53
+ private _fileConsumer;
54
+ constructor(struct: FileModel, _httpClient: AxiosInstance);
55
+ getFilename(): string;
56
+ download(concurrencyLimit?: number, token?: string): Promise<Uint8Array>;
57
+ }
58
+
59
+ declare class Folder implements FolderModel {
60
+ protected _httpClient: AxiosInstance;
61
+ _id: string;
62
+ meta: Meta;
63
+ parent: string;
64
+ ancestors: string[];
65
+ files: string[];
66
+ folders: string[];
67
+ level: number;
68
+ size: number;
69
+ _managementURL: string;
70
+ private _fileConsumer;
71
+ constructor(struct: FolderModel, _httpClient: AxiosInstance);
72
+ getName(): string | undefined;
73
+ listItems(token?: string): Promise<FolderList>;
74
+ getFileByID(id: string, token?: string): Promise<File$1>;
75
+ getFileByName(name: string, token?: string): Promise<File$1>;
76
+ uploadFile(file: File, meta: Meta, chunkSize?: number, concurrentLimit?: number, timeout?: number, token?: string, onProgress?: (uploaded: number, total: number) => void): Promise<File$1>;
77
+ }
78
+
79
+ interface OidcToken {
80
+ access_token: string;
81
+ expires_in: number;
82
+ refresh_expires_in: number;
83
+ refresh_token: string;
84
+ token_type: string;
85
+ scope: string;
86
+ }
87
+ interface UserAttributes {
88
+ viewer_in_user_attr?: string[];
89
+ editor_in_user_attr?: string[];
90
+ }
91
+ interface UserAccess {
92
+ manageGroupMembership: boolean;
93
+ view: boolean;
94
+ mapRoles: boolean;
95
+ impersonate: boolean;
96
+ manage: boolean;
97
+ }
98
+ interface User$1 {
99
+ id: string;
100
+ username: string;
101
+ firstName: string;
102
+ lastName: string;
103
+ email: string;
104
+ emailVerified: boolean;
105
+ attributes: UserAttributes;
106
+ createdTimestamp: number;
107
+ enabled: boolean;
108
+ totp: boolean;
109
+ disableableCredentialTypes: string[];
110
+ requiredActions: string[];
111
+ notBefore: number;
112
+ access: UserAccess;
113
+ }
114
+
115
+ interface Group$1 {
116
+ id?: string;
117
+ name: string;
118
+ path: string;
119
+ subGroups?: string[];
120
+ attributes?: {
121
+ [key: string]: any[];
122
+ };
123
+ }
124
+ declare enum Role {
125
+ ADMIN,
126
+ MEMBER
127
+ }
128
+ interface UserRoles {
129
+ [email: string]: Role;
130
+ }
131
+
132
+ interface Bucket {
133
+ _id?: string;
134
+ name: string;
135
+ creation_date?: Date;
136
+ }
137
+
138
+ interface IClient$1 {
139
+ login(email: string, password: string): Promise<OidcToken>;
140
+ myUser(token?: string): Promise<User$1>;
141
+ allOrganizations(token?: string): Promise<Group$1[]>;
142
+ myOrganizations(token?: string): Promise<Group$1[]>;
143
+ organizationByID(id: string, token?: string): Promise<Group$1>;
144
+ organizationByName(name: string, token?: string): Promise<Group$1>;
145
+ createOrganization(name: string, token?: string): Promise<Bucket>;
146
+ addToOrganization(organization: string, users: UserRoles, token?: string): void;
147
+ getFolderByName(name: string, token?: string): Promise<Folder>;
148
+ getFolderByID(id: string, token?: string): Promise<Folder>;
149
+ removeOrganizationByID(organization: string, token?: string): Promise<Bucket>;
150
+ register(email: string, password: string, password_confirm: string, firstName: string, lastName: string): void;
151
+ }
152
+ declare class Client implements IClient$1 {
153
+ private _userConsumer;
154
+ private _groupConsumer;
155
+ private _bucketConsumer;
156
+ private _folderConsumer;
157
+ constructor(_managementURL: string, _accountURL: string);
158
+ private _setSession;
159
+ login(email: string, password: string): Promise<OidcToken>;
160
+ myUser(token: string): Promise<User$1>;
161
+ allOrganizations(token: string): Promise<Group$1[]>;
162
+ myOrganizations(token: string): Promise<Group$1[]>;
163
+ organizationByID(id: string, token: string): Promise<Group$1>;
164
+ organizationByName(name: string, token: string): Promise<Group$1>;
165
+ createOrganization(name: string, token: string): Promise<Bucket>;
166
+ removeOrganizationByID(organization: string, token: string): Promise<Bucket>;
167
+ addToOrganization(organization: string, users: UserRoles, token: string): void;
168
+ register(email: string, password: string, password_confirm: string, firstName: string, lastName: string): Promise<any>;
169
+ getFolderByName(name: string, token: string): Promise<Folder>;
170
+ getFolderByID(id: string, token: string): Promise<Folder>;
171
+ }
172
+
173
+ type User = User$1;
174
+ type Group = Group$1;
175
+ type IClient = IClient$1;
176
+
177
+ export { Client, type Group, type IClient, type User };
package/dist/index.js ADDED
@@ -0,0 +1,879 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
26
+ var __copyProps = (to, from, except, desc) => {
27
+ if (from && typeof from === "object" || typeof from === "function") {
28
+ for (let key of __getOwnPropNames(from))
29
+ if (!__hasOwnProp.call(to, key) && key !== except)
30
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ }
32
+ return to;
33
+ };
34
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
35
+ // If the importer is in node compatibility mode or this is not an ESM
36
+ // file that has been converted to a CommonJS file using a Babel-
37
+ // compatible transform (i.e. "__esModule" has not been set), then set
38
+ // "default" to the CommonJS "module.exports" for node compatibility.
39
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
40
+ mod
41
+ ));
42
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
43
+ var __async = (__this, __arguments, generator) => {
44
+ return new Promise((resolve, reject) => {
45
+ var fulfilled = (value) => {
46
+ try {
47
+ step(generator.next(value));
48
+ } catch (e) {
49
+ reject(e);
50
+ }
51
+ };
52
+ var rejected = (value) => {
53
+ try {
54
+ step(generator.throw(value));
55
+ } catch (e) {
56
+ reject(e);
57
+ }
58
+ };
59
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
60
+ step((generator = generator.apply(__this, __arguments)).next());
61
+ });
62
+ };
63
+
64
+ // src/index.ts
65
+ var index_exports = {};
66
+ __export(index_exports, {
67
+ Client: () => Client
68
+ });
69
+ module.exports = __toCommonJS(index_exports);
70
+
71
+ // src/client.ts
72
+ var import_axios = __toESM(require("axios"));
73
+
74
+ // src/apis/base.consumer.ts
75
+ var BaseConsumer = class {
76
+ constructor(_httpClient, _requestPath) {
77
+ this._httpClient = _httpClient;
78
+ this._requestPath = _requestPath;
79
+ this._httpClient = _httpClient;
80
+ this._basePath = this._httpClient.defaults["baseURL"];
81
+ this.path = this._basePath + "/" + _requestPath;
82
+ }
83
+ getOne(additional_path = "", params = null, token) {
84
+ let config = {};
85
+ if (params === null) {
86
+ config = {
87
+ headers: {
88
+ "Content-Type": "application/json",
89
+ "Authorization": "Bearer " + token
90
+ }
91
+ };
92
+ } else {
93
+ config = {
94
+ params,
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ "Authorization": "Bearer " + token
98
+ }
99
+ };
100
+ }
101
+ return this._httpClient.get(this.path + additional_path, config).then((resp) => {
102
+ return resp.data;
103
+ }).catch((error) => {
104
+ console.error(`\u274C Can't retrieve requsted entity:`, error);
105
+ return null;
106
+ });
107
+ }
108
+ getMany(additional_path = "", params = null, token) {
109
+ let config = {};
110
+ if (params === null) {
111
+ config = {
112
+ headers: {
113
+ "Content-Type": "application/json",
114
+ "Authorization": "Bearer " + token
115
+ }
116
+ };
117
+ } else {
118
+ config = {
119
+ params,
120
+ headers: {
121
+ "Content-Type": "application/json",
122
+ "Authorization": "Bearer " + token
123
+ }
124
+ };
125
+ }
126
+ return this._httpClient.get(this.path + additional_path, config).then((resp) => {
127
+ return resp.data;
128
+ }).catch((error) => {
129
+ console.error(`\u274C Can't retrieve requsted entities:`, error);
130
+ return null;
131
+ });
132
+ }
133
+ post(additional_path = "", payload, extraHeaders, token) {
134
+ const config = {
135
+ headers: __spreadValues({
136
+ "Content-Type": "application/json",
137
+ "Authorization": `Bearer ${token}`
138
+ }, extraHeaders)
139
+ };
140
+ return this._httpClient.post(this.path + additional_path, payload, config).then((resp) => resp.data).catch((error) => {
141
+ console.error(`\u274C Error in posting:`, error);
142
+ return null;
143
+ });
144
+ }
145
+ delete(id, token) {
146
+ let config = {
147
+ headers: {
148
+ "Content-Type": "application/json",
149
+ "Authorization": "Bearer " + token
150
+ }
151
+ };
152
+ return this._httpClient.delete(this.path + id, config).then((resp) => resp.data).catch((error) => {
153
+ console.error(`\u274C Error deleting ${id}:`, error);
154
+ return null;
155
+ });
156
+ }
157
+ };
158
+
159
+ // src/apis/account/user.consumer.ts
160
+ var _namespace = "user/";
161
+ var UserConsumer = class extends BaseConsumer {
162
+ // private _accountBase:string;
163
+ constructor(_httpClient) {
164
+ super(_httpClient, _namespace);
165
+ this._client = _httpClient;
166
+ }
167
+ login(email, password) {
168
+ let config = {
169
+ headers: {
170
+ "Content-Type": "application/x-www-form-urlencoded"
171
+ }
172
+ };
173
+ let data = {
174
+ "username": email,
175
+ "password": password
176
+ };
177
+ return this._client.post(this.path, data, config).then((resp) => {
178
+ return resp.data;
179
+ });
180
+ }
181
+ getUser(token) {
182
+ return this.getOne("", null, token);
183
+ }
184
+ register(email, password, firstName, lastName) {
185
+ let config = {
186
+ headers: {
187
+ "Content-Type": "application/x-www-form-urlencoded"
188
+ }
189
+ };
190
+ let data = {
191
+ "email": email,
192
+ "password": password,
193
+ "last_name": lastName,
194
+ "first_name": firstName
195
+ };
196
+ return this._client.post(this.path + "/register/", data, config).then((resp) => {
197
+ return resp.data;
198
+ }).catch((err) => {
199
+ console.log(err);
200
+ });
201
+ }
202
+ };
203
+
204
+ // src/apis/account/group.consumer.ts
205
+ var _namespace2 = "group/";
206
+ var GroupConsumer = class extends BaseConsumer {
207
+ constructor(_httpClient) {
208
+ super(_httpClient, _namespace2);
209
+ this._client = _httpClient;
210
+ }
211
+ getAllGroups(token) {
212
+ return this.getMany("all", null, token);
213
+ }
214
+ getUserGroups(token) {
215
+ return this.getMany("", null, token);
216
+ }
217
+ getGroupByID(id, token) {
218
+ return this.getOne("id/" + id, null, token);
219
+ }
220
+ getGroupByName(name, token) {
221
+ return this.getOne("name/" + name, null, token);
222
+ }
223
+ postGroup(name, token) {
224
+ const postGroup = {
225
+ name,
226
+ path: "/",
227
+ subGroups: [],
228
+ attributes: {},
229
+ id: void 0
230
+ };
231
+ return this.post("", postGroup, void 0, token);
232
+ }
233
+ addUsers(group_name, input, token) {
234
+ let payload = {
235
+ users: Object.entries(input).map(([email, role]) => ({
236
+ [email]: { admin: role === "admin" /* ADMIN */ }
237
+ }))
238
+ };
239
+ let config = {
240
+ headers: {
241
+ "Content-Type": "application/json",
242
+ "Authorization": "Bearer " + token
243
+ }
244
+ };
245
+ this._client.post(this.path + "name/" + group_name, payload, config);
246
+ }
247
+ deleteGroup(id, token) {
248
+ return this.delete("id/" + id, token);
249
+ }
250
+ };
251
+
252
+ // src/apis/management/bucket.consumer.ts
253
+ var _namespace3 = "bucket";
254
+ var BucketConsumer = class extends BaseConsumer {
255
+ constructor(_httpClient) {
256
+ super(_httpClient, _namespace3);
257
+ }
258
+ postBucket(id, name, token) {
259
+ const postBucket = {
260
+ name,
261
+ _id: id,
262
+ creation_date: void 0
263
+ };
264
+ return this.post("", postBucket, void 0, token);
265
+ }
266
+ deleteBucket(id, token) {
267
+ return this.delete("/" + id, token);
268
+ }
269
+ };
270
+
271
+ // src/utils/utils.ts
272
+ function withValidToken(fn, accountsAPI) {
273
+ return function(...args) {
274
+ return __async(this, null, function* () {
275
+ const isStorageAvailable = typeof localStorage !== "undefined";
276
+ const now = Math.floor(Date.now() / 1e3);
277
+ if (!isStorageAvailable) {
278
+ console.warn("\u26A0\uFE0F localStorage not available. You must pass token manually.");
279
+ return Promise.resolve(fn.apply(this, args));
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");
285
+ if (!token || now >= exp) {
286
+ if (!refreshToken || now >= refreshExp) {
287
+ console.warn("\u26A0\uFE0F Session expired. Please log in again.");
288
+ return Promise.resolve(fn.apply(this, args));
289
+ }
290
+ try {
291
+ const response = yield fetch(`${accountsAPI}/user/refresh`, {
292
+ method: "POST",
293
+ headers: { "Content-Type": "application/json" },
294
+ body: JSON.stringify({ refresh_token: refreshToken })
295
+ });
296
+ if (!response.ok) throw new Error("Token refresh failed");
297
+ const session = yield response.json();
298
+ const newExp = now + session.expires_in;
299
+ const newRefreshExp = now + session.refresh_expires_in;
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));
304
+ token = session.access_token;
305
+ } catch (e) {
306
+ console.error("\u{1F510} Token refresh failed:", e);
307
+ throw new Error("Could not refresh session.");
308
+ }
309
+ }
310
+ const result = fn.apply(this, [...args, token]);
311
+ return result instanceof Promise ? result : Promise.resolve(result);
312
+ });
313
+ };
314
+ }
315
+ function runConcurrent(items, fn, limit) {
316
+ return __async(this, null, function* () {
317
+ const queue = [...items];
318
+ const running = [];
319
+ const runNext = () => __async(this, null, function* () {
320
+ const item = queue.shift();
321
+ if (!item) return;
322
+ const p = fn(item).finally(() => {
323
+ running.splice(running.indexOf(p), 1);
324
+ });
325
+ running.push(p);
326
+ if (running.length >= limit) {
327
+ yield Promise.race(running);
328
+ }
329
+ return runNext();
330
+ });
331
+ const initialTasks = Array.from(
332
+ { length: Math.min(limit, items.length) },
333
+ runNext
334
+ // Start up to `limit` runners in parallel
335
+ );
336
+ yield Promise.all(initialTasks);
337
+ yield Promise.all(running);
338
+ });
339
+ }
340
+ function runConcurrentWithResults(items, fn, limit) {
341
+ return __async(this, null, function* () {
342
+ const results = new Array(items.length);
343
+ const queue = items.map((item, index) => ({ item, index }));
344
+ const running = [];
345
+ const runNext = () => __async(this, null, function* () {
346
+ const next = queue.shift();
347
+ if (!next) return;
348
+ const { item, index } = next;
349
+ const p = fn(item, index).then((res) => {
350
+ results[index] = res;
351
+ }).finally(() => {
352
+ running.splice(running.indexOf(p), 1);
353
+ });
354
+ running.push(p);
355
+ if (running.length >= limit) {
356
+ yield Promise.race(running);
357
+ }
358
+ return runNext();
359
+ });
360
+ const initial = Array.from({ length: Math.min(limit, items.length) }, runNext);
361
+ yield Promise.all(initial);
362
+ yield Promise.all(running);
363
+ return results;
364
+ });
365
+ }
366
+ function splitFileIntoChunks(file, chunkSize) {
367
+ const chunks = [];
368
+ for (let i = 0; i < Math.ceil(file.size / chunkSize); i++) {
369
+ const start = i * chunkSize;
370
+ const end = Math.min(file.size, start + chunkSize);
371
+ chunks.push(file.slice(start, end));
372
+ }
373
+ return chunks;
374
+ }
375
+ function createChunkUploader(chunks, timeoutSeconds) {
376
+ let uploadedChunks = 0;
377
+ const totalChunks = chunks.length;
378
+ return (part) => __async(this, null, function* () {
379
+ var _a, _b;
380
+ const chunkIndex = part.number - 1;
381
+ const blob = chunks[chunkIndex];
382
+ const controller = new AbortController();
383
+ const timeoutId = setTimeout(() => controller.abort(), timeoutSeconds * 1e3);
384
+ try {
385
+ const response = yield fetch(part.presigned_url, {
386
+ method: "PUT",
387
+ body: blob,
388
+ signal: controller.signal,
389
+ headers: {
390
+ "Content-Type": "application/octet-stream"
391
+ }
392
+ });
393
+ if (response.ok) {
394
+ const etag = (_b = (_a = response.headers.get("ETag")) == null ? void 0 : _a.replace(/"/g, "")) != null ? _b : "";
395
+ part.etag = etag;
396
+ part.uploaded = true;
397
+ uploadedChunks++;
398
+ } else {
399
+ part.uploaded = false;
400
+ const errorText = yield response.text();
401
+ console.error(`\u274C Failed to upload part ${part.number}: ${errorText}`);
402
+ }
403
+ } catch (err) {
404
+ part.uploaded = false;
405
+ console.error(`\u274C Error uploading part ${part.number}: ${err}`);
406
+ } finally {
407
+ clearTimeout(timeoutId);
408
+ }
409
+ });
410
+ }
411
+ function downloadPart(url) {
412
+ return __async(this, null, function* () {
413
+ const response = yield fetch(url);
414
+ if (!response.ok) {
415
+ throw new Error(`Failed to download chunk: ${response.status}`);
416
+ }
417
+ const buffer = yield response.arrayBuffer();
418
+ return new Uint8Array(buffer);
419
+ });
420
+ }
421
+
422
+ // src/apis/management/file.factory.ts
423
+ var File = class {
424
+ constructor(struct, _httpClient) {
425
+ this._httpClient = _httpClient;
426
+ this._id = struct._id;
427
+ this.meta = struct.meta;
428
+ this.folder = struct.folder;
429
+ this.ancestors = struct.ancestors;
430
+ this.original_title = struct.original_title;
431
+ this.file_type = struct.file_type;
432
+ this.size = struct.size;
433
+ this.total = struct.total;
434
+ this._httpClient = _httpClient;
435
+ if (this._httpClient.defaults["baseURL"] === void 0) {
436
+ console.error(`\u274C Can't retrieve requsted entity: Folder model can't find the management URL`);
437
+ throw new Error(`\u274C Can't retrieve requsted entity: Folder model can't find the management URL`);
438
+ }
439
+ this._managementURL = this._httpClient.defaults["baseURL"];
440
+ this._fileConsumer = new FileConsumer(this._httpClient);
441
+ this.download = withValidToken(
442
+ this.download.bind(this),
443
+ this._managementURL
444
+ );
445
+ }
446
+ getFilename() {
447
+ var _a;
448
+ const title = this.meta.title || "untitled";
449
+ const extension = ((_a = this.file_type) == null ? void 0 : _a.replace(/^\./, "")) || "";
450
+ if (extension && title.toLowerCase().endsWith(`.${extension.toLowerCase()}`)) {
451
+ return title;
452
+ }
453
+ console.log(title, extension);
454
+ return extension ? `${title}.${extension}` : title;
455
+ }
456
+ download(concurrencyLimit = 5, token) {
457
+ return __async(this, null, function* () {
458
+ if (this._id === void 0) {
459
+ throw new Error("No File ID found");
460
+ }
461
+ if (token === void 0) {
462
+ throw new Error("No token provided");
463
+ }
464
+ const wrapper = yield this._fileConsumer.initDownload(this._id, token);
465
+ const parts = wrapper.parts;
466
+ const results = yield runConcurrentWithResults(
467
+ parts,
468
+ (part) => downloadPart(part.presigned_url),
469
+ concurrencyLimit
470
+ );
471
+ const totalLength = results.reduce((acc, chunk) => acc + chunk.length, 0);
472
+ const merged = new Uint8Array(totalLength);
473
+ let offset = 0;
474
+ for (const chunk of results) {
475
+ merged.set(chunk, offset);
476
+ offset += chunk.length;
477
+ }
478
+ return merged;
479
+ });
480
+ }
481
+ // public list_items(token: string){
482
+ // const params = new URLSearchParams({ id: this._id });
483
+ // let config = {
484
+ // params,
485
+ // headers: {
486
+ // 'Content-Type':'application/json',
487
+ // 'Authorization': 'Bearer ' + token
488
+ // }
489
+ // }
490
+ // return this._httpClient.get(this._managementURL + '/' + _namespace + '/list', config ).then(resp=>{
491
+ // return resp.data
492
+ // }).catch(error => {
493
+ // console.error(`❌ Can't retrieve requsted entity:`, error);
494
+ // return null; // Return null in case of failure
495
+ // });
496
+ // }
497
+ };
498
+
499
+ // src/apis/management/file.consumer.ts
500
+ var _namespace4 = "file";
501
+ var FileConsumer = class extends BaseConsumer {
502
+ constructor(_httpClient) {
503
+ super(_httpClient, _namespace4);
504
+ }
505
+ getFileByID(id, token) {
506
+ return this.getOne(`/info/${id}`, null, token).then(
507
+ (resp) => {
508
+ return new File(resp, this._httpClient);
509
+ }
510
+ );
511
+ }
512
+ initUpload(file, fileSize, chunckSize, token) {
513
+ const config = {
514
+ headers: {
515
+ "Content-Type": "application/json",
516
+ "Authorization": `Bearer ${token}`,
517
+ "Chunk-Size": String(chunckSize),
518
+ "File-Size": String(fileSize)
519
+ }
520
+ };
521
+ return this._httpClient.post(this.path + "/upload/initialize", file, config).then((resp) => resp.data).catch((error) => {
522
+ console.error(`\u274C Error in posting:`, error);
523
+ return null;
524
+ });
525
+ }
526
+ closeUplaod(wrapper, token) {
527
+ return this.post("/upload/complete", wrapper, void 0, token);
528
+ }
529
+ initDownload(fileId, token) {
530
+ const config = {
531
+ headers: {
532
+ "Authorization": `Bearer ${token}`,
533
+ "Content-Type": "application/json"
534
+ },
535
+ timeout: 0
536
+ // disables timeout
537
+ };
538
+ return this._httpClient.get(this.path + `/download/initialize/${fileId}`, config).then((resp) => {
539
+ if (resp.data && resp.data.internal_status) {
540
+ console.error(`\u274C Error in response:`, resp.data.internal_status);
541
+ throw new Error("Download initialization failed: " + resp.data.internal_status);
542
+ }
543
+ return resp.data;
544
+ }).catch((error) => {
545
+ console.error(`\u274C Error in request:`, error);
546
+ throw new Error("Download initialization failed: " + error.message);
547
+ });
548
+ }
549
+ download(concurrent_limit = 5) {
550
+ return __async(this, null, function* () {
551
+ return new Blob();
552
+ });
553
+ }
554
+ store(_0) {
555
+ return __async(this, arguments, function* (path, concurrent_limit = 5, chunk_size = 5 * 1024 * 1024) {
556
+ });
557
+ }
558
+ rename(new_name) {
559
+ return __async(this, null, function* () {
560
+ });
561
+ }
562
+ changeType(new_type) {
563
+ return __async(this, null, function* () {
564
+ });
565
+ }
566
+ updateDescription(new_description) {
567
+ return __async(this, null, function* () {
568
+ });
569
+ }
570
+ // async copyTo(destination_name?: string, destination_id?: string, new_name?: string): Promise<IFile | null> {
571
+ // // implement later
572
+ // return null;
573
+ // }
574
+ moveTo(destination_name, destination_id, new_name) {
575
+ return __async(this, null, function* () {
576
+ });
577
+ }
578
+ // async delete(): Promise<boolean> {
579
+ // // implement later
580
+ // return false;
581
+ // }
582
+ checkRequestStatus() {
583
+ return __async(this, null, function* () {
584
+ return null;
585
+ });
586
+ }
587
+ };
588
+
589
+ // src/apis/management/folder.factory.ts
590
+ var _namespace5 = "folder";
591
+ var Folder = class {
592
+ constructor(struct, _httpClient) {
593
+ this._httpClient = _httpClient;
594
+ this._id = struct._id;
595
+ this.meta = struct.meta;
596
+ this.parent = struct.parent;
597
+ this.ancestors = struct.ancestors;
598
+ this.files = struct.files;
599
+ this.folders = struct.folders;
600
+ this.level = struct.level;
601
+ this.size = struct.size;
602
+ this._httpClient = _httpClient;
603
+ if (this._httpClient.defaults["baseURL"] === void 0) {
604
+ console.error(`\u274C Can't retrieve requsted entity: Folder model can't find the management URL`);
605
+ throw new Error(`\u274C Can't retrieve requsted entity: Folder model can't find the management URL`);
606
+ }
607
+ this._managementURL = this._httpClient.defaults["baseURL"];
608
+ this._fileConsumer = new FileConsumer(this._httpClient);
609
+ this.listItems = withValidToken(this.listItems.bind(this), this._managementURL);
610
+ this.getFileByID = withValidToken(this.getFileByID.bind(this), this._managementURL);
611
+ this.getFileByName = withValidToken(this.getFileByName.bind(this), this._managementURL);
612
+ this.uploadFile = withValidToken(
613
+ this.uploadFile.bind(this),
614
+ this._managementURL
615
+ );
616
+ }
617
+ getName() {
618
+ return this.meta.title;
619
+ }
620
+ listItems(token) {
621
+ const params = new URLSearchParams({ id: this._id });
622
+ let config = {
623
+ params,
624
+ headers: {
625
+ "Content-Type": "application/json",
626
+ "Authorization": "Bearer " + token
627
+ }
628
+ };
629
+ return this._httpClient.get(this._managementURL + "/" + _namespace5 + "/list", config).then((resp) => {
630
+ return resp.data;
631
+ }).catch((error) => {
632
+ console.error(`\u274C Can't retrieve requsted entity:`, error);
633
+ throw new Error(`\u274C Can't retrieve requsted entity: error`);
634
+ });
635
+ }
636
+ getFileByID(id, token) {
637
+ if (token === void 0) {
638
+ console.error(`\u274C Can't retrieve token`);
639
+ throw new Error(`\u274C Can't retrieve token`);
640
+ }
641
+ return this._fileConsumer.getFileByID(id, token);
642
+ }
643
+ getFileByName(name, token) {
644
+ if (token === void 0) {
645
+ console.error(`\u274C Can't retrieve token`);
646
+ throw new Error(`\u274C Can't retrieve token`);
647
+ }
648
+ return this.listItems(token).then(
649
+ (resp) => {
650
+ let fileInfo = resp.files.find((file) => file.meta.title === name);
651
+ if (fileInfo !== void 0) {
652
+ return new File(fileInfo, this._httpClient);
653
+ }
654
+ console.error(`\u274C File "${name}" does not exist in folder`);
655
+ throw new Error(`File "${name}" not found`);
656
+ }
657
+ );
658
+ }
659
+ uploadFile(_0, _1) {
660
+ return __async(this, arguments, function* (file, meta, chunkSize = 5 * 1024 * 1024, concurrentLimit = 10, timeout = 3600, token, onProgress) {
661
+ if (!this._id) throw new Error("Folder ID is missing in the current folder context");
662
+ if (!token) throw new Error("Token required for upload");
663
+ const fileSize = file.size;
664
+ const originalTitle = file.name.substring(0, file.name.lastIndexOf(".")) || file.name;
665
+ const fileType = file.name.includes(".") ? file.name.substring(file.name.lastIndexOf(".")) : "";
666
+ const totalChunks = Math.ceil(fileSize / chunkSize);
667
+ const fileModel = {
668
+ folder: this._id,
669
+ original_title: originalTitle,
670
+ file_type: fileType,
671
+ size: fileSize,
672
+ total: totalChunks,
673
+ meta
674
+ };
675
+ const wrapper = yield this._fileConsumer.initUpload(fileModel, fileSize, chunkSize, token);
676
+ const chunks = splitFileIntoChunks(file, chunkSize);
677
+ const uploadFn = createChunkUploader(chunks, timeout);
678
+ yield runConcurrent(wrapper.parts, uploadFn, concurrentLimit);
679
+ const allUploaded = wrapper.parts.every((p) => p.uploaded);
680
+ if (!allUploaded) {
681
+ throw new Error("Not all parts were uploaded successfully. Cannot complete upload.");
682
+ }
683
+ const finalModel = yield this._fileConsumer.closeUplaod(wrapper, token);
684
+ return new File(finalModel, this._httpClient);
685
+ });
686
+ }
687
+ // public uploadFile(
688
+ // file: File,
689
+ // meta: Meta,
690
+ // chunkSize: number = 5 * 1024 * 1024,
691
+ // concurrentLimit: number = 10,
692
+ // timeout: number = 3600,
693
+ // token?: string
694
+ // ): Promise<FileModel> {
695
+ // if (!token) {
696
+ // throw new Error("Not token available");
697
+ // }
698
+ // const fileSize = file.size;
699
+ // const originalTitle = file.name.substring(0, file.name.lastIndexOf(".")) || file.name;
700
+ // const fileType = file.name.includes(".")
701
+ // ? file.name.substring(file.name.lastIndexOf("."))
702
+ // : "";
703
+ // const totalChunks = Math.ceil(fileSize / chunkSize);
704
+ // const fileModel: FileModel = {
705
+ // folder: this._id,
706
+ // original_title: originalTitle,
707
+ // file_type: fileType,
708
+ // size: fileSize,
709
+ // total: totalChunks,
710
+ // meta: meta,
711
+ // };
712
+ // return this._fileConsumer.initUpload(
713
+ // fileModel,
714
+ // fileSize,
715
+ // chunkSize,
716
+ // token
717
+ // ).then(
718
+ // (wrapper: MultipartWrapper) => {
719
+ // const chunks = splitFileIntoChunks(file, chunkSize);
720
+ // const uploadFn = createChunkUploader(chunks, timeout);
721
+ // // ⬇ Upload all parts in parallel with concurrency limit and part mutation
722
+ // runConcurrent(wrapper.parts, uploadFn, concurrentLimit).then(() =>
723
+ // {
724
+ // const allUploaded = wrapper.parts.every(p => p.uploaded);
725
+ // if (!allUploaded) {
726
+ // throw new Error("Not all parts were uploaded successfully. Cannot complete upload.");
727
+ // }
728
+ // this._fileConsumer.closeMultipart(this._managementURL, wrapper, token).then(
729
+ // (fileModel: FileModel) => {
730
+ // return new FileWrapper(fileModel, this._httpClient)
731
+ // }
732
+ // )
733
+ // }
734
+ // )
735
+ // }
736
+ // );
737
+ // }
738
+ };
739
+
740
+ // src/apis/management/folder.consumer.ts
741
+ var _namespace6 = "folder";
742
+ var FolderConsumer = class extends BaseConsumer {
743
+ constructor(_httpClient) {
744
+ super(_httpClient, _namespace6);
745
+ }
746
+ getFolderByID(id, token) {
747
+ const params = id ? new URLSearchParams({ id }) : void 0;
748
+ return this.getOne("", params, token).then(
749
+ (resp) => {
750
+ return new Folder(resp, this._httpClient);
751
+ }
752
+ );
753
+ }
754
+ getFolderByName(name, token) {
755
+ const params = name ? new URLSearchParams({ path: name }) : void 0;
756
+ return this.getOne("", params, token).then(
757
+ (resp) => {
758
+ return new Folder(resp, this._httpClient);
759
+ }
760
+ );
761
+ }
762
+ };
763
+
764
+ // src/client.ts
765
+ var Client = class {
766
+ constructor(_managementURL, _accountURL) {
767
+ const configManagement = {
768
+ baseURL: _managementURL
769
+ };
770
+ const configAccount = {
771
+ baseURL: _accountURL
772
+ };
773
+ const axiosManagement = import_axios.default.create(configManagement);
774
+ const axiosAccount = import_axios.default.create(configAccount);
775
+ this._userConsumer = new UserConsumer(axiosAccount);
776
+ this._groupConsumer = new GroupConsumer(axiosAccount);
777
+ this._bucketConsumer = new BucketConsumer(axiosManagement);
778
+ this._folderConsumer = new FolderConsumer(axiosManagement);
779
+ this.addToOrganization = withValidToken(this.addToOrganization.bind(this), _accountURL);
780
+ this.myUser = withValidToken(this.myUser.bind(this), _accountURL);
781
+ this.removeOrganizationByID = withValidToken(this.removeOrganizationByID.bind(this), _accountURL);
782
+ this.organizationByName = withValidToken(this.organizationByName.bind(this), _accountURL);
783
+ this.allOrganizations = withValidToken(this.allOrganizations.bind(this), _accountURL);
784
+ this.myOrganizations = withValidToken(this.myOrganizations.bind(this), _accountURL);
785
+ this.organizationByID = withValidToken(this.organizationByID.bind(this), _accountURL);
786
+ this.createOrganization = withValidToken(this.createOrganization.bind(this), _accountURL);
787
+ this.getFolderByName = withValidToken(this.getFolderByName.bind(this), _accountURL);
788
+ this.getFolderByID = withValidToken(this.getFolderByID.bind(this), _accountURL);
789
+ }
790
+ // public setSession(session: OidcToken): void {
791
+ // const storage = typeof window !== "undefined" ? sessionStorage : global.sessionStorage;
792
+ // if (storage) {
793
+ // storage.setItem('token', session.access_token);
794
+ // storage.setItem('refresh_token', session.refresh_token);
795
+ // storage.setItem('exp', String(session.expires_in));
796
+ // storage.setItem('refresh_exp', String(session.refresh_expires_in));
797
+ // } else {
798
+ // console.warn("Session storage is not available.");
799
+ // }
800
+ // }
801
+ // public getSessionVariable(key: string): string | null {
802
+ // const storage = typeof window !== "undefined" ? sessionStorage : global.sessionStorage;
803
+ // return storage ? storage.getItem(key) : null;
804
+ // }
805
+ _setSession(session) {
806
+ const now = Math.floor(Date.now() / 1e3);
807
+ if (typeof localStorage !== "undefined") {
808
+ localStorage.setItem("token", session.access_token);
809
+ localStorage.setItem("refresh_token", session.refresh_token);
810
+ localStorage.setItem("exp", String(now + session.expires_in));
811
+ localStorage.setItem("refresh_exp", String(now + session.refresh_expires_in));
812
+ } else {
813
+ console.warn("\u26A0\uFE0F Local Storage not available. You will need to pass tokens manually.");
814
+ }
815
+ }
816
+ login(email, password) {
817
+ return this._userConsumer.login(email, password).then(
818
+ (resp) => {
819
+ this._setSession(resp);
820
+ return resp;
821
+ }
822
+ );
823
+ }
824
+ myUser(token) {
825
+ return this._userConsumer.getUser(token);
826
+ }
827
+ allOrganizations(token) {
828
+ return this._groupConsumer.getAllGroups(token);
829
+ }
830
+ myOrganizations(token) {
831
+ return this._groupConsumer.getUserGroups(token);
832
+ }
833
+ organizationByID(id, token) {
834
+ return this._groupConsumer.getGroupByID(id, token);
835
+ }
836
+ organizationByName(name, token) {
837
+ return this._groupConsumer.getGroupByName(name, token);
838
+ }
839
+ createOrganization(name, token) {
840
+ return this._groupConsumer.postGroup(name, token).then(
841
+ (group) => {
842
+ return this._bucketConsumer.postBucket(group.id, name, token);
843
+ }
844
+ );
845
+ }
846
+ removeOrganizationByID(organization, token) {
847
+ return this._groupConsumer.deleteGroup(organization, token).then(
848
+ () => {
849
+ return this._bucketConsumer.deleteBucket(organization, token).then(
850
+ (bucket) => {
851
+ if (!bucket) {
852
+ throw new Error(`Bucket with ID ${organization} could not be deleted.`);
853
+ }
854
+ return bucket;
855
+ }
856
+ );
857
+ }
858
+ );
859
+ }
860
+ addToOrganization(organization, users, token) {
861
+ return this._groupConsumer.addUsers(organization, users, token);
862
+ }
863
+ register(email, password, password_confirm, firstName, lastName) {
864
+ if (password != password_confirm) {
865
+ throw new Error("Passwords do not match");
866
+ }
867
+ return this._userConsumer.register(email, password, firstName, lastName);
868
+ }
869
+ getFolderByName(name, token) {
870
+ return this._folderConsumer.getFolderByName(name, token);
871
+ }
872
+ getFolderByID(id, token) {
873
+ return this._folderConsumer.getFolderByID(id, token);
874
+ }
875
+ };
876
+ // Annotate the CommonJS export names for ESM import in node:
877
+ 0 && (module.exports = {
878
+ Client
879
+ });
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@singularlogic/coreplatts",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "scripts": {
10
+ "build": "tsup src/index.ts --dts --format cjs --out-dir dist",
11
+ "test": "mocha --require ts-node/register tests/*.test.ts",
12
+ "types": "tsc --emitDeclarationOnly",
13
+ "release": "npm run types && npm run build"
14
+ },
15
+ "keywords": [],
16
+ "author": "",
17
+ "license": "ISC",
18
+ "type": "commonjs",
19
+ "description": "",
20
+ "dependencies": {
21
+ "axios": "^1.8.3"
22
+ },
23
+ "devDependencies": {
24
+ "@types/mocha": "^10.0.10",
25
+ "@types/node": "^22.13.10",
26
+ "eslint": "^9.25.0",
27
+ "mocha": "^11.1.0",
28
+ "prettier": "^3.5.3",
29
+ "ts-node": "^10.9.2",
30
+ "tsup": "^8.4.0",
31
+ "typescript": "^5.8.3"
32
+ }
33
+ }