@communecter/cocolight-api-client 1.0.54 → 1.0.56
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/dist/401.cocolight-api-client.browser.js +1 -0
- package/dist/401.cocolight-api-client.cjs +1 -0
- package/dist/401.cocolight-api-client.mjs.js +1 -0
- package/dist/588.cocolight-api-client.browser.js +1 -0
- package/dist/588.cocolight-api-client.cjs +1 -0
- package/dist/588.cocolight-api-client.mjs.js +1 -0
- package/dist/593.cocolight-api-client.browser.js +1 -0
- package/dist/593.cocolight-api-client.cjs +1 -0
- package/dist/593.cocolight-api-client.mjs.js +1 -0
- package/dist/839.cocolight-api-client.browser.js +1 -0
- package/dist/839.cocolight-api-client.cjs +1 -0
- package/dist/839.cocolight-api-client.mjs.js +1 -0
- package/dist/cocolight-api-client.browser.js +3 -3
- package/dist/cocolight-api-client.cjs +1 -1
- package/dist/cocolight-api-client.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
- package/package.json +29 -17
- package/src/{Api.js → Api.ts} +85 -95
- package/src/{ApiClient.js → ApiClient.ts} +436 -247
- package/src/EJSONType.ts +103 -0
- package/src/api/{Badge.js → Badge.ts} +56 -45
- package/src/api/BaseEntity.ts +3890 -0
- package/src/api/Comment.ts +200 -0
- package/src/api/{EndpointApi.js → EndpointApi.ts} +363 -297
- package/src/api/EndpointApi.types.ts +4609 -0
- package/src/api/EntityRegistry.ts +203 -0
- package/src/api/Event.ts +332 -0
- package/src/api/News.ts +331 -0
- package/src/api/{Organization.js → Organization.ts} +155 -119
- package/src/api/{Poi.js → Poi.ts} +68 -60
- package/src/api/{Project.js → Project.ts} +150 -127
- package/src/api/{User.js → User.ts} +321 -256
- package/src/api/UserApi.ts +148 -0
- package/src/api/serverDataType/Comment.ts +88 -0
- package/src/api/serverDataType/Event.ts +80 -0
- package/src/api/serverDataType/News.ts +138 -0
- package/src/api/serverDataType/Organization.ts +80 -0
- package/src/api/serverDataType/Project.ts +71 -0
- package/src/api/serverDataType/User.ts +103 -0
- package/src/api/serverDataType/common.ts +80 -0
- package/src/endpoints.module.ts +2621 -0
- package/src/error.ts +86 -0
- package/src/index.ts +86 -0
- package/src/mixin/UserMixin.ts +4 -0
- package/src/types/api-responses.ts +217 -0
- package/src/types/entities.ts +22 -0
- package/src/types/error-guards.ts +230 -0
- package/src/types/index.ts +39 -0
- package/src/types/payloads.ts +21 -0
- package/src/types/transforms.ts +110 -0
- package/src/utils/{FileOfflineStorageStrategy.node.js → FileOfflineStorageStrategy.node.ts} +15 -12
- package/src/utils/{FileStorageStrategy.node.js → FileStorageStrategy.node.ts} +16 -39
- package/src/utils/MultiServerFileStorageStrategy.node.ts +67 -0
- package/src/utils/MultiServerTokenStorageStrategy.ts +139 -0
- package/src/utils/{OfflineClientManager.js → OfflineClientManager.ts} +82 -86
- package/src/utils/OfflineQueueStorageStrategy.ts +47 -0
- package/src/utils/TokenStorage.ts +77 -0
- package/src/utils/compat.ts +12 -0
- package/src/utils/createDefaultMultiServerTokenStorageStrategy.ts +35 -0
- package/src/utils/{createDefaultOfflineStrategy.js → createDefaultOfflineStrategy.ts} +8 -3
- package/src/utils/createDefaultTokenStorageStrategy.ts +33 -0
- package/src/utils/{reactive.js → reactive.ts} +49 -40
- package/src/utils/stream-utils.node.ts +12 -0
- package/types/Api.d.ts +38 -82
- package/types/Api.d.ts.map +1 -0
- package/types/ApiClient.d.ts +244 -184
- package/types/ApiClient.d.ts.map +1 -0
- package/types/EJSONType.d.ts +48 -22
- package/types/EJSONType.d.ts.map +1 -0
- package/types/api/Badge.d.ts +20 -20
- package/types/api/Badge.d.ts.map +1 -0
- package/types/api/BaseEntity.d.ts +751 -446
- package/types/api/BaseEntity.d.ts.map +1 -0
- package/types/api/Comment.d.ts +36 -0
- package/types/api/EndpointApi.d.ts +347 -295
- package/types/api/EndpointApi.d.ts.map +1 -0
- package/types/api/EndpointApi.types.d.ts +3914 -4133
- package/types/api/EntityRegistry.d.ts +18 -16
- package/types/api/EntityRegistry.d.ts.map +1 -0
- package/types/api/Event.d.ts +119 -35
- package/types/api/Event.d.ts.map +1 -0
- package/types/api/News.d.ts +52 -20
- package/types/api/News.d.ts.map +1 -0
- package/types/api/Organization.d.ts +165 -49
- package/types/api/Organization.d.ts.map +1 -0
- package/types/api/Poi.d.ts +51 -22
- package/types/api/Poi.d.ts.map +1 -0
- package/types/api/Project.d.ts +151 -52
- package/types/api/Project.d.ts.map +1 -0
- package/types/api/User.d.ts +222 -93
- package/types/api/User.d.ts.map +1 -0
- package/types/api/UserApi.d.ts +60 -9
- package/types/api/UserApi.d.ts.map +1 -0
- package/types/api/serverDataType/Comment.d.ts +83 -0
- package/types/api/serverDataType/Event.d.ts +67 -0
- package/types/api/serverDataType/News.d.ts +130 -0
- package/types/api/serverDataType/Organization.d.ts +65 -0
- package/types/api/serverDataType/Organization.d.ts.map +1 -0
- package/types/api/serverDataType/Project.d.ts +58 -0
- package/types/api/serverDataType/Project.d.ts.map +1 -0
- package/types/api/serverDataType/User.d.ts +86 -0
- package/types/api/serverDataType/User.d.ts.map +1 -0
- package/types/api/serverDataType/common.d.ts +71 -0
- package/types/api/serverDataType/common.d.ts.map +1 -0
- package/types/endpoints.module.d.ts +6922 -1215
- package/types/endpoints.module.d.ts.map +1 -0
- package/types/error.d.ts +25 -51
- package/types/error.d.ts.map +1 -0
- package/types/index.d.ts +55 -48
- package/types/index.d.ts.map +1 -0
- package/types/mixin/UserMixin.d.ts +1 -1
- package/types/mixin/UserMixin.d.ts.map +1 -0
- package/types/types/api-responses.d.ts +190 -0
- package/types/types/api-responses.d.ts.map +1 -0
- package/types/types/entities.d.ts +17 -0
- package/types/types/entities.d.ts.map +1 -0
- package/types/types/error-guards.d.ts +99 -0
- package/types/types/error-guards.d.ts.map +1 -0
- package/types/types/index.d.ts +7 -0
- package/types/types/payloads.d.ts +17 -0
- package/types/types/payloads.d.ts.map +1 -0
- package/types/types/transforms.d.ts +79 -0
- package/types/types/transforms.d.ts.map +1 -0
- package/types/utils/FileOfflineStorageStrategy.node.d.ts +10 -9
- package/types/utils/FileOfflineStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/FileStorageStrategy.node.d.ts +9 -20
- package/types/utils/FileStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/MultiServerFileStorageStrategy.node.d.ts +13 -18
- package/types/utils/MultiServerFileStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/MultiServerTokenStorageStrategy.d.ts +30 -51
- package/types/utils/MultiServerTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/OfflineClientManager.d.ts +52 -88
- package/types/utils/OfflineClientManager.d.ts.map +1 -0
- package/types/utils/OfflineQueueStorageStrategy.d.ts +12 -9
- package/types/utils/OfflineQueueStorageStrategy.d.ts.map +1 -0
- package/types/utils/TokenStorage.d.ts +20 -70
- package/types/utils/TokenStorage.d.ts.map +1 -0
- package/types/utils/compat.d.ts +4 -0
- package/types/utils/compat.d.ts.map +1 -0
- package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts +2 -11
- package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/createDefaultOfflineStrategy.d.ts +2 -3
- package/types/utils/createDefaultOfflineStrategy.d.ts.map +1 -0
- package/types/utils/createDefaultTokenStorageStrategy.d.ts +2 -12
- package/types/utils/createDefaultTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/reactive.d.ts +10 -16
- package/types/utils/reactive.d.ts.map +1 -0
- package/types/utils/stream-utils.node.d.ts +3 -2
- package/types/utils/stream-utils.node.d.ts.map +1 -0
- package/dist/123.cocolight-api-client.browser.js +0 -1
- package/dist/123.cocolight-api-client.cjs +0 -1
- package/dist/22.cocolight-api-client.mjs.js +0 -1
- package/dist/339.cocolight-api-client.mjs.js +0 -1
- package/dist/394.cocolight-api-client.browser.js +0 -1
- package/dist/394.cocolight-api-client.cjs +0 -1
- package/dist/405.cocolight-api-client.browser.js +0 -1
- package/dist/405.cocolight-api-client.cjs +0 -1
- package/dist/774.cocolight-api-client.mjs.js +0 -1
- package/dist/790.cocolight-api-client.mjs.js +0 -1
- package/dist/931.cocolight-api-client.browser.js +0 -1
- package/dist/931.cocolight-api-client.cjs +0 -1
- package/src/EJSONType.js +0 -53
- package/src/api/BaseEntity.js +0 -2828
- package/src/api/EntityRegistry.js +0 -152
- package/src/api/Event.js +0 -226
- package/src/api/News.js +0 -244
- package/src/api/UserApi.js +0 -81
- package/src/endpoints.module.js +0 -5
- package/src/error.js +0 -121
- package/src/index.js +0 -97
- package/src/mixin/UserMixin.js +0 -8
- package/src/utils/MultiServerFileStorageStrategy.node.js +0 -87
- package/src/utils/MultiServerTokenStorageStrategy.js +0 -188
- package/src/utils/OfflineQueueStorageStrategy.js +0 -51
- package/src/utils/TokenStorage.js +0 -153
- package/src/utils/createDefaultMultiServerTokenStorageStrategy.js +0 -51
- package/src/utils/createDefaultTokenStorageStrategy.js +0 -49
- package/src/utils/stream-utils.node.js +0 -10
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// types/transforms.ts - Types spécialisés pour les transformations par entité
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
3
|
+
|
|
4
|
+
import type { TransformFunction, EntityRefsMap } from "./entities.js";
|
|
5
|
+
import type { SocialNetworkPayload } from "./payloads.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Types pour les données d'entrée des transforms
|
|
9
|
+
*/
|
|
10
|
+
export interface ParentData {
|
|
11
|
+
[key: string]: {
|
|
12
|
+
type?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface OrganizerData {
|
|
18
|
+
[key: string]: {
|
|
19
|
+
type?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Alias pour SocialNetworkPayload depuis payloads.ts (évite la duplication)
|
|
25
|
+
export type SocialNetworkData = SocialNetworkPayload;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Types pour les transforms spécifiques aux événements
|
|
29
|
+
*/
|
|
30
|
+
export interface EventTransforms {
|
|
31
|
+
parent: TransformFunction<ParentData | null, EntityRefsMap>;
|
|
32
|
+
organizer: TransformFunction<OrganizerData | null, EntityRefsMap>;
|
|
33
|
+
[key: string]: TransformFunction<any, any> | undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Types pour les transforms spécifiques aux utilisateurs/organisations/projets (réseaux sociaux)
|
|
38
|
+
*/
|
|
39
|
+
export interface SocialTransforms {
|
|
40
|
+
github: TransformFunction<any, string | undefined>;
|
|
41
|
+
gitlab: TransformFunction<any, string | undefined>;
|
|
42
|
+
facebook: TransformFunction<any, string | undefined>;
|
|
43
|
+
twitter: TransformFunction<any, string | undefined>;
|
|
44
|
+
instagram: TransformFunction<any, string | undefined>;
|
|
45
|
+
linkedIn?: TransformFunction<any, string | undefined>;
|
|
46
|
+
youtube?: TransformFunction<any, string | undefined>;
|
|
47
|
+
website?: TransformFunction<any, string | undefined>;
|
|
48
|
+
diaspora?: TransformFunction<any, string | undefined>;
|
|
49
|
+
mastodon?: TransformFunction<any, string | undefined>;
|
|
50
|
+
telegram?: TransformFunction<any, string | undefined>;
|
|
51
|
+
signal?: TransformFunction<any, string | undefined>;
|
|
52
|
+
[key: string]: TransformFunction<any, any> | undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Types pour les transforms des utilisateurs
|
|
57
|
+
*/
|
|
58
|
+
export interface UserTransforms extends SocialTransforms {
|
|
59
|
+
// Ajouter d'autres transforms spécifiques aux utilisateurs si nécessaire
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Types pour les transforms des organisations
|
|
64
|
+
*/
|
|
65
|
+
export interface OrganizationTransforms extends SocialTransforms {
|
|
66
|
+
// Ajouter d'autres transforms spécifiques aux organisations si nécessaire
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Types pour les transforms des projets
|
|
71
|
+
*/
|
|
72
|
+
export interface ProjectTransforms extends SocialTransforms {
|
|
73
|
+
parent: TransformFunction<ParentData | null, EntityRefsMap>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Union de tous les types de transforms
|
|
78
|
+
*/
|
|
79
|
+
export type EntityTransforms = EventTransforms | UserTransforms | OrganizationTransforms | ProjectTransforms;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fonction helper pour créer des transforms d'entité avec type safety
|
|
83
|
+
*/
|
|
84
|
+
export function createEntityRef(type: string, name?: string) {
|
|
85
|
+
return { type, name };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Fonction helper pour transformer les données parent/organizer
|
|
90
|
+
*/
|
|
91
|
+
export function transformEntityRefs(val: ParentData | OrganizerData | null): EntityRefsMap {
|
|
92
|
+
if (!val || typeof val !== "object") return {};
|
|
93
|
+
|
|
94
|
+
return Object.fromEntries(
|
|
95
|
+
Object.entries(val).map(([key, obj]) => [
|
|
96
|
+
key,
|
|
97
|
+
createEntityRef(
|
|
98
|
+
obj?.type ?? "",
|
|
99
|
+
obj?.name ?? undefined
|
|
100
|
+
)
|
|
101
|
+
])
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Fonction helper pour extraire les données de réseaux sociaux
|
|
107
|
+
*/
|
|
108
|
+
export function createSocialTransform(field: keyof SocialNetworkData): TransformFunction<any, string | undefined> {
|
|
109
|
+
return (val: any, full?: any) => full?.socialNetwork?.[field];
|
|
110
|
+
}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import path from "path";
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
5
4
|
|
|
6
5
|
import { OfflineQueueStorageStrategy } from "./OfflineQueueStorageStrategy.js";
|
|
7
6
|
|
|
8
|
-
export class FileOfflineStorage extends OfflineQueueStorageStrategy {
|
|
9
|
-
|
|
7
|
+
export class FileOfflineStorage<T = any> extends OfflineQueueStorageStrategy<T> {
|
|
8
|
+
public readonly dir: string;
|
|
9
|
+
public readonly filePath: string;
|
|
10
|
+
|
|
11
|
+
constructor(filename: string = "offline-queue.json", dir: string = path.join(os.homedir(), ".config", "cocolight")) {
|
|
10
12
|
super();
|
|
11
13
|
this.dir = dir;
|
|
12
14
|
this.filePath = path.join(dir, filename);
|
|
13
15
|
this._ensureDirectoryExists();
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
_ensureDirectoryExists() {
|
|
18
|
+
private _ensureDirectoryExists(): void {
|
|
17
19
|
if (!fs.existsSync(this.dir)) {
|
|
18
20
|
fs.mkdirSync(this.dir, { recursive: true });
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
private _readFile(): T[] {
|
|
22
25
|
if (!fs.existsSync(this.filePath)) return [];
|
|
23
26
|
try {
|
|
24
|
-
const json = JSON.parse(fs.readFileSync(this.filePath, "utf8"));
|
|
27
|
+
const json: T[] = JSON.parse(fs.readFileSync(this.filePath, "utf8"));
|
|
25
28
|
return json;
|
|
26
29
|
} catch (e) {
|
|
27
30
|
console.error("Erreur lecture offline queue :", e);
|
|
@@ -29,7 +32,7 @@ export class FileOfflineStorage extends OfflineQueueStorageStrategy {
|
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
_writeFile(queue) {
|
|
35
|
+
private _writeFile(queue: T[]): void {
|
|
33
36
|
try {
|
|
34
37
|
fs.writeFileSync(this.filePath, JSON.stringify(queue, null, 2), "utf8");
|
|
35
38
|
} catch (e) {
|
|
@@ -37,11 +40,11 @@ export class FileOfflineStorage extends OfflineQueueStorageStrategy {
|
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
async loadQueue() {
|
|
43
|
+
async loadQueue(): Promise<T[]> {
|
|
41
44
|
return this._readFile();
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
async saveQueue(queue) {
|
|
47
|
+
async saveQueue(queue: T[]): Promise<void> {
|
|
45
48
|
this._writeFile(queue);
|
|
46
49
|
}
|
|
47
50
|
}
|
|
@@ -1,36 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import * as path from "path";
|
|
4
5
|
|
|
5
6
|
import { TokenStorageStrategy } from "./TokenStorage.js";
|
|
6
7
|
|
|
7
|
-
/**
|
|
8
|
-
* Stratégie de stockage des tokens basée sur un fichier (Node uniquement).
|
|
9
|
-
* @implements {TokenStorageStrategy}
|
|
10
|
-
*/
|
|
11
8
|
export class FileStorageStrategy extends TokenStorageStrategy {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
constructor(filename = "tokens.json", dir = path.join(os.homedir(), ".config", "cocolight")) {
|
|
9
|
+
public readonly dir: string;
|
|
10
|
+
public readonly filePath: string;
|
|
11
|
+
|
|
12
|
+
constructor(filename: string = "tokens.json", dir: string = path.join(os.homedir(), ".config", "cocolight")) {
|
|
17
13
|
super();
|
|
18
|
-
/** @type {string} */
|
|
19
14
|
this.dir = dir;
|
|
20
|
-
/** @type {string} */
|
|
21
15
|
this.filePath = path.join(dir, filename);
|
|
22
16
|
this._ensureDirectoryExists();
|
|
23
17
|
}
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
_ensureDirectoryExists() {
|
|
19
|
+
private _ensureDirectoryExists(): void {
|
|
27
20
|
if (!fs.existsSync(this.dir)) {
|
|
28
21
|
fs.mkdirSync(this.dir, { recursive: true });
|
|
29
22
|
}
|
|
30
23
|
}
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
_readFile() {
|
|
25
|
+
private _readFile(): any {
|
|
34
26
|
if (!fs.existsSync(this.filePath)) return {};
|
|
35
27
|
try {
|
|
36
28
|
return JSON.parse(fs.readFileSync(this.filePath, "utf8"));
|
|
@@ -41,46 +33,31 @@ export class FileStorageStrategy extends TokenStorageStrategy {
|
|
|
41
33
|
}
|
|
42
34
|
}
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
* @private
|
|
46
|
-
* @param {Record<string, any>} data
|
|
47
|
-
*/
|
|
48
|
-
_writeFile(data) {
|
|
36
|
+
private _writeFile(data: Record<string, any>): void {
|
|
49
37
|
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2), "utf8");
|
|
50
38
|
}
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
getAccessToken() {
|
|
40
|
+
getAccessToken(): string | null {
|
|
54
41
|
return this._readFile().accessToken || null;
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
|
|
58
|
-
* @param {string|null} token
|
|
59
|
-
* @returns {void}
|
|
60
|
-
*/
|
|
61
|
-
setAccessToken(token) {
|
|
44
|
+
setAccessToken(token: string | null): void {
|
|
62
45
|
const data = this._readFile();
|
|
63
46
|
data.accessToken = token;
|
|
64
47
|
this._writeFile(data);
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
|
|
68
|
-
getRefreshToken() {
|
|
50
|
+
getRefreshToken(): string | null {
|
|
69
51
|
return this._readFile().refreshToken || null;
|
|
70
52
|
}
|
|
71
53
|
|
|
72
|
-
|
|
73
|
-
* @param {string|null} token
|
|
74
|
-
* @returns {void}
|
|
75
|
-
*/
|
|
76
|
-
setRefreshToken(token) {
|
|
54
|
+
setRefreshToken(token: string | null): void {
|
|
77
55
|
const data = this._readFile();
|
|
78
56
|
data.refreshToken = token;
|
|
79
57
|
this._writeFile(data);
|
|
80
58
|
}
|
|
81
59
|
|
|
82
|
-
|
|
83
|
-
clear() {
|
|
60
|
+
clear(): void {
|
|
84
61
|
this._writeFile({});
|
|
85
62
|
}
|
|
86
63
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
|
|
5
|
+
import { MultiServerTokenStorageStrategy } from "./MultiServerTokenStorageStrategy.js";
|
|
6
|
+
|
|
7
|
+
export class MultiServerFileStorageStrategy extends MultiServerTokenStorageStrategy {
|
|
8
|
+
public readonly filePath: string;
|
|
9
|
+
|
|
10
|
+
constructor(filename: string = "tokens.json", dir: string = path.join(os.homedir(), ".config", "cocolight")) {
|
|
11
|
+
super();
|
|
12
|
+
this.filePath = path.join(dir, filename);
|
|
13
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private _readFile(): any {
|
|
17
|
+
if (!fs.existsSync(this.filePath)) return {};
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(fs.readFileSync(this.filePath, "utf8"));
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private _writeFile(data: Record<string, { accessToken?: string | null; refreshToken?: string | null }>): void {
|
|
26
|
+
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2), "utf8");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getAccessToken(): string | null {
|
|
30
|
+
const base = this._requireBaseURL();
|
|
31
|
+
return this._readFile()[base]?.accessToken ?? null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setAccessToken(token: string | null): void {
|
|
35
|
+
const base = this._requireBaseURL();
|
|
36
|
+
const all = this._readFile();
|
|
37
|
+
all[base] = { ...(all[base] || {}), accessToken: token };
|
|
38
|
+
this._writeFile(all);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getRefreshToken(): string | null {
|
|
42
|
+
const base = this._requireBaseURL();
|
|
43
|
+
return this._readFile()[base]?.refreshToken ?? null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setRefreshToken(token: string | null): void {
|
|
47
|
+
const base = this._requireBaseURL();
|
|
48
|
+
const all = this._readFile();
|
|
49
|
+
all[base] = { ...(all[base] || {}), refreshToken: token };
|
|
50
|
+
this._writeFile(all);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
clear(): void {
|
|
54
|
+
const base = this._requireBaseURL();
|
|
55
|
+
const all = this._readFile();
|
|
56
|
+
delete all[base];
|
|
57
|
+
this._writeFile(all);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getServers(): string[] {
|
|
61
|
+
return Object.keys(this._readFile());
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exportAll(): Record<string, { accessToken?: string | null; refreshToken?: string | null }> {
|
|
65
|
+
return this._readFile();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { TokenStorageStrategy } from "./TokenStorage.js";
|
|
2
|
+
|
|
3
|
+
export abstract class MultiServerTokenStorageStrategy extends TokenStorageStrategy {
|
|
4
|
+
protected _currentBaseURL: string | null = null;
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
use(baseURL: string): void {
|
|
11
|
+
if (!baseURL) throw new Error("baseURL est requis");
|
|
12
|
+
this._currentBaseURL = baseURL.replace(/\/+$/, "");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected _ensureContext(): void {
|
|
16
|
+
if (!this._currentBaseURL) throw new Error("baseURL non défini. Appelez use(baseURL)");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected _requireBaseURL(): string {
|
|
20
|
+
this._ensureContext();
|
|
21
|
+
return this._currentBaseURL!;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
abstract getServers(): string[];
|
|
25
|
+
abstract exportAll(): Record<string, { accessToken?: string | null; refreshToken?: string | null }>;
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class MultiServerMemoryStorageStrategy extends MultiServerTokenStorageStrategy {
|
|
30
|
+
private _storage = new Map<string, { accessToken?: string | null; refreshToken?: string | null }>();
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getAccessToken(): string | null {
|
|
37
|
+
const base = this._requireBaseURL();
|
|
38
|
+
return this._storage.get(base)?.accessToken ?? null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setAccessToken(token: string | null): void {
|
|
42
|
+
const base = this._requireBaseURL();
|
|
43
|
+
const current = this._storage.get(base) || {};
|
|
44
|
+
this._storage.set(base, { ...current, accessToken: token });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getRefreshToken(): string | null {
|
|
48
|
+
const base = this._requireBaseURL();
|
|
49
|
+
return this._storage.get(base)?.refreshToken ?? null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setRefreshToken(token: string | null): void {
|
|
53
|
+
const base = this._requireBaseURL();
|
|
54
|
+
const current = this._storage.get(base) || {};
|
|
55
|
+
this._storage.set(base, { ...current, refreshToken: token });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
clear(): void {
|
|
59
|
+
const base = this._requireBaseURL();
|
|
60
|
+
this._storage.delete(base);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getServers(): string[] {
|
|
64
|
+
return Array.from(this._storage.keys());
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
exportAll(): Record<string, { accessToken?: string | null; refreshToken?: string | null }> {
|
|
68
|
+
return Object.fromEntries(this._storage.entries());
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class MultiServerLocalStorageStrategy extends MultiServerTokenStorageStrategy {
|
|
73
|
+
public readonly prefix: string;
|
|
74
|
+
|
|
75
|
+
constructor(prefix: string = "cocolight") {
|
|
76
|
+
super();
|
|
77
|
+
this.prefix = prefix;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private _key(baseURL: string): string {
|
|
81
|
+
return `${this.prefix}_tokens_${baseURL}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private _getData(): any {
|
|
85
|
+
this._ensureContext();
|
|
86
|
+
if (typeof localStorage === "undefined") return {};
|
|
87
|
+
const raw = localStorage.getItem(this._key(this._currentBaseURL!));
|
|
88
|
+
return raw ? JSON.parse(raw) : {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private _setData(data: any): void {
|
|
92
|
+
if (typeof localStorage === "undefined") return;
|
|
93
|
+
localStorage.setItem(this._key(this._currentBaseURL!), JSON.stringify(data));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getAccessToken(): string | null {
|
|
97
|
+
return this._getData().accessToken ?? null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setAccessToken(token: string | null): void {
|
|
101
|
+
const data = this._getData();
|
|
102
|
+
data.accessToken = token;
|
|
103
|
+
this._setData(data);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
getRefreshToken(): string | null {
|
|
107
|
+
return this._getData().refreshToken ?? null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
setRefreshToken(token: string | null): void {
|
|
111
|
+
const data = this._getData();
|
|
112
|
+
data.refreshToken = token;
|
|
113
|
+
this._setData(data);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
clear(): void {
|
|
117
|
+
if (typeof localStorage === "undefined") return;
|
|
118
|
+
localStorage.removeItem(this._key(this._currentBaseURL!));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getServers(): string[] {
|
|
122
|
+
if (typeof localStorage === "undefined") return [];
|
|
123
|
+
const keys = Object.keys(localStorage);
|
|
124
|
+
return keys
|
|
125
|
+
.filter(k => k.startsWith(`${this.prefix}_tokens_`))
|
|
126
|
+
.map(k => k.replace(`${this.prefix}_tokens_`, ""));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
exportAll(): Record<string, { accessToken?: string | null; refreshToken?: string | null }> {
|
|
130
|
+
const result: Record<string, { accessToken?: string | null; refreshToken?: string | null }> = {};
|
|
131
|
+
|
|
132
|
+
for (const baseURL of this.getServers()) {
|
|
133
|
+
const key = this._key(baseURL);
|
|
134
|
+
const raw = typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
|
|
135
|
+
if (raw) result[baseURL] = JSON.parse(raw);
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
}
|