@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.
Files changed (179) hide show
  1. package/dist/401.cocolight-api-client.browser.js +1 -0
  2. package/dist/401.cocolight-api-client.cjs +1 -0
  3. package/dist/401.cocolight-api-client.mjs.js +1 -0
  4. package/dist/588.cocolight-api-client.browser.js +1 -0
  5. package/dist/588.cocolight-api-client.cjs +1 -0
  6. package/dist/588.cocolight-api-client.mjs.js +1 -0
  7. package/dist/593.cocolight-api-client.browser.js +1 -0
  8. package/dist/593.cocolight-api-client.cjs +1 -0
  9. package/dist/593.cocolight-api-client.mjs.js +1 -0
  10. package/dist/839.cocolight-api-client.browser.js +1 -0
  11. package/dist/839.cocolight-api-client.cjs +1 -0
  12. package/dist/839.cocolight-api-client.mjs.js +1 -0
  13. package/dist/cocolight-api-client.browser.js +3 -3
  14. package/dist/cocolight-api-client.cjs +1 -1
  15. package/dist/cocolight-api-client.mjs.js +1 -1
  16. package/dist/cocolight-api-client.vite.mjs.js +1 -1
  17. package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
  18. package/package.json +29 -17
  19. package/src/{Api.js → Api.ts} +85 -95
  20. package/src/{ApiClient.js → ApiClient.ts} +436 -247
  21. package/src/EJSONType.ts +103 -0
  22. package/src/api/{Badge.js → Badge.ts} +56 -45
  23. package/src/api/BaseEntity.ts +3890 -0
  24. package/src/api/Comment.ts +200 -0
  25. package/src/api/{EndpointApi.js → EndpointApi.ts} +363 -297
  26. package/src/api/EndpointApi.types.ts +4609 -0
  27. package/src/api/EntityRegistry.ts +203 -0
  28. package/src/api/Event.ts +332 -0
  29. package/src/api/News.ts +331 -0
  30. package/src/api/{Organization.js → Organization.ts} +155 -119
  31. package/src/api/{Poi.js → Poi.ts} +68 -60
  32. package/src/api/{Project.js → Project.ts} +150 -127
  33. package/src/api/{User.js → User.ts} +321 -256
  34. package/src/api/UserApi.ts +148 -0
  35. package/src/api/serverDataType/Comment.ts +88 -0
  36. package/src/api/serverDataType/Event.ts +80 -0
  37. package/src/api/serverDataType/News.ts +138 -0
  38. package/src/api/serverDataType/Organization.ts +80 -0
  39. package/src/api/serverDataType/Project.ts +71 -0
  40. package/src/api/serverDataType/User.ts +103 -0
  41. package/src/api/serverDataType/common.ts +80 -0
  42. package/src/endpoints.module.ts +2621 -0
  43. package/src/error.ts +86 -0
  44. package/src/index.ts +86 -0
  45. package/src/mixin/UserMixin.ts +4 -0
  46. package/src/types/api-responses.ts +217 -0
  47. package/src/types/entities.ts +22 -0
  48. package/src/types/error-guards.ts +230 -0
  49. package/src/types/index.ts +39 -0
  50. package/src/types/payloads.ts +21 -0
  51. package/src/types/transforms.ts +110 -0
  52. package/src/utils/{FileOfflineStorageStrategy.node.js → FileOfflineStorageStrategy.node.ts} +15 -12
  53. package/src/utils/{FileStorageStrategy.node.js → FileStorageStrategy.node.ts} +16 -39
  54. package/src/utils/MultiServerFileStorageStrategy.node.ts +67 -0
  55. package/src/utils/MultiServerTokenStorageStrategy.ts +139 -0
  56. package/src/utils/{OfflineClientManager.js → OfflineClientManager.ts} +82 -86
  57. package/src/utils/OfflineQueueStorageStrategy.ts +47 -0
  58. package/src/utils/TokenStorage.ts +77 -0
  59. package/src/utils/compat.ts +12 -0
  60. package/src/utils/createDefaultMultiServerTokenStorageStrategy.ts +35 -0
  61. package/src/utils/{createDefaultOfflineStrategy.js → createDefaultOfflineStrategy.ts} +8 -3
  62. package/src/utils/createDefaultTokenStorageStrategy.ts +33 -0
  63. package/src/utils/{reactive.js → reactive.ts} +49 -40
  64. package/src/utils/stream-utils.node.ts +12 -0
  65. package/types/Api.d.ts +38 -82
  66. package/types/Api.d.ts.map +1 -0
  67. package/types/ApiClient.d.ts +244 -184
  68. package/types/ApiClient.d.ts.map +1 -0
  69. package/types/EJSONType.d.ts +48 -22
  70. package/types/EJSONType.d.ts.map +1 -0
  71. package/types/api/Badge.d.ts +20 -20
  72. package/types/api/Badge.d.ts.map +1 -0
  73. package/types/api/BaseEntity.d.ts +751 -446
  74. package/types/api/BaseEntity.d.ts.map +1 -0
  75. package/types/api/Comment.d.ts +36 -0
  76. package/types/api/EndpointApi.d.ts +347 -295
  77. package/types/api/EndpointApi.d.ts.map +1 -0
  78. package/types/api/EndpointApi.types.d.ts +3914 -4133
  79. package/types/api/EntityRegistry.d.ts +18 -16
  80. package/types/api/EntityRegistry.d.ts.map +1 -0
  81. package/types/api/Event.d.ts +119 -35
  82. package/types/api/Event.d.ts.map +1 -0
  83. package/types/api/News.d.ts +52 -20
  84. package/types/api/News.d.ts.map +1 -0
  85. package/types/api/Organization.d.ts +165 -49
  86. package/types/api/Organization.d.ts.map +1 -0
  87. package/types/api/Poi.d.ts +51 -22
  88. package/types/api/Poi.d.ts.map +1 -0
  89. package/types/api/Project.d.ts +151 -52
  90. package/types/api/Project.d.ts.map +1 -0
  91. package/types/api/User.d.ts +222 -93
  92. package/types/api/User.d.ts.map +1 -0
  93. package/types/api/UserApi.d.ts +60 -9
  94. package/types/api/UserApi.d.ts.map +1 -0
  95. package/types/api/serverDataType/Comment.d.ts +83 -0
  96. package/types/api/serverDataType/Event.d.ts +67 -0
  97. package/types/api/serverDataType/News.d.ts +130 -0
  98. package/types/api/serverDataType/Organization.d.ts +65 -0
  99. package/types/api/serverDataType/Organization.d.ts.map +1 -0
  100. package/types/api/serverDataType/Project.d.ts +58 -0
  101. package/types/api/serverDataType/Project.d.ts.map +1 -0
  102. package/types/api/serverDataType/User.d.ts +86 -0
  103. package/types/api/serverDataType/User.d.ts.map +1 -0
  104. package/types/api/serverDataType/common.d.ts +71 -0
  105. package/types/api/serverDataType/common.d.ts.map +1 -0
  106. package/types/endpoints.module.d.ts +6922 -1215
  107. package/types/endpoints.module.d.ts.map +1 -0
  108. package/types/error.d.ts +25 -51
  109. package/types/error.d.ts.map +1 -0
  110. package/types/index.d.ts +55 -48
  111. package/types/index.d.ts.map +1 -0
  112. package/types/mixin/UserMixin.d.ts +1 -1
  113. package/types/mixin/UserMixin.d.ts.map +1 -0
  114. package/types/types/api-responses.d.ts +190 -0
  115. package/types/types/api-responses.d.ts.map +1 -0
  116. package/types/types/entities.d.ts +17 -0
  117. package/types/types/entities.d.ts.map +1 -0
  118. package/types/types/error-guards.d.ts +99 -0
  119. package/types/types/error-guards.d.ts.map +1 -0
  120. package/types/types/index.d.ts +7 -0
  121. package/types/types/payloads.d.ts +17 -0
  122. package/types/types/payloads.d.ts.map +1 -0
  123. package/types/types/transforms.d.ts +79 -0
  124. package/types/types/transforms.d.ts.map +1 -0
  125. package/types/utils/FileOfflineStorageStrategy.node.d.ts +10 -9
  126. package/types/utils/FileOfflineStorageStrategy.node.d.ts.map +1 -0
  127. package/types/utils/FileStorageStrategy.node.d.ts +9 -20
  128. package/types/utils/FileStorageStrategy.node.d.ts.map +1 -0
  129. package/types/utils/MultiServerFileStorageStrategy.node.d.ts +13 -18
  130. package/types/utils/MultiServerFileStorageStrategy.node.d.ts.map +1 -0
  131. package/types/utils/MultiServerTokenStorageStrategy.d.ts +30 -51
  132. package/types/utils/MultiServerTokenStorageStrategy.d.ts.map +1 -0
  133. package/types/utils/OfflineClientManager.d.ts +52 -88
  134. package/types/utils/OfflineClientManager.d.ts.map +1 -0
  135. package/types/utils/OfflineQueueStorageStrategy.d.ts +12 -9
  136. package/types/utils/OfflineQueueStorageStrategy.d.ts.map +1 -0
  137. package/types/utils/TokenStorage.d.ts +20 -70
  138. package/types/utils/TokenStorage.d.ts.map +1 -0
  139. package/types/utils/compat.d.ts +4 -0
  140. package/types/utils/compat.d.ts.map +1 -0
  141. package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts +2 -11
  142. package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts.map +1 -0
  143. package/types/utils/createDefaultOfflineStrategy.d.ts +2 -3
  144. package/types/utils/createDefaultOfflineStrategy.d.ts.map +1 -0
  145. package/types/utils/createDefaultTokenStorageStrategy.d.ts +2 -12
  146. package/types/utils/createDefaultTokenStorageStrategy.d.ts.map +1 -0
  147. package/types/utils/reactive.d.ts +10 -16
  148. package/types/utils/reactive.d.ts.map +1 -0
  149. package/types/utils/stream-utils.node.d.ts +3 -2
  150. package/types/utils/stream-utils.node.d.ts.map +1 -0
  151. package/dist/123.cocolight-api-client.browser.js +0 -1
  152. package/dist/123.cocolight-api-client.cjs +0 -1
  153. package/dist/22.cocolight-api-client.mjs.js +0 -1
  154. package/dist/339.cocolight-api-client.mjs.js +0 -1
  155. package/dist/394.cocolight-api-client.browser.js +0 -1
  156. package/dist/394.cocolight-api-client.cjs +0 -1
  157. package/dist/405.cocolight-api-client.browser.js +0 -1
  158. package/dist/405.cocolight-api-client.cjs +0 -1
  159. package/dist/774.cocolight-api-client.mjs.js +0 -1
  160. package/dist/790.cocolight-api-client.mjs.js +0 -1
  161. package/dist/931.cocolight-api-client.browser.js +0 -1
  162. package/dist/931.cocolight-api-client.cjs +0 -1
  163. package/src/EJSONType.js +0 -53
  164. package/src/api/BaseEntity.js +0 -2828
  165. package/src/api/EntityRegistry.js +0 -152
  166. package/src/api/Event.js +0 -226
  167. package/src/api/News.js +0 -244
  168. package/src/api/UserApi.js +0 -81
  169. package/src/endpoints.module.js +0 -5
  170. package/src/error.js +0 -121
  171. package/src/index.js +0 -97
  172. package/src/mixin/UserMixin.js +0 -8
  173. package/src/utils/MultiServerFileStorageStrategy.node.js +0 -87
  174. package/src/utils/MultiServerTokenStorageStrategy.js +0 -188
  175. package/src/utils/OfflineQueueStorageStrategy.js +0 -51
  176. package/src/utils/TokenStorage.js +0 -153
  177. package/src/utils/createDefaultMultiServerTokenStorageStrategy.js +0 -51
  178. package/src/utils/createDefaultTokenStorageStrategy.js +0 -49
  179. 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
- // src/utils/FileOfflineStorage.node.js
2
- import fs from "fs";
3
- import os from "os";
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
- constructor(filename = "offline-queue.json", dir = path.join(os.homedir(), ".config", "cocolight")) {
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
- _readFile() {
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
- import fs from "fs";
2
- import os from "os";
3
- import path from "path";
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
- * @param {string} [filename="tokens.json"]
14
- * @param {string} [dir=path.join(os.homedir(), ".config", "cocolight")]
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
- /** @private */
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
- /** @private */
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
- /** @returns {string|null} */
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
- /** @returns {string|null} */
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
- /** @returns {void} */
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
+ }