@communecter/cocolight-api-client 1.0.199 → 1.0.201
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/cocolight-api-client.browser.js +1 -1
- package/dist/cocolight-api-client.cjs +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 +1 -1
- package/types/ApiClient.d.ts +15 -3
- package/types/costum/runtime.d.ts +25 -1
- package/types/index.d.ts +1 -1
- package/types/utils/logger.d.ts +29 -0
- package/types/utils/validators.d.ts +27 -0
package/package.json
CHANGED
package/types/ApiClient.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
+
import { type ApiClientLogger } from "./utils/logger.js";
|
|
3
|
+
export type { ApiClientLogger } from "./utils/logger.js";
|
|
2
4
|
import { type TokenStorageStrategy } from "./utils/TokenStorage.js";
|
|
3
5
|
/**
|
|
4
6
|
* Résultat retourné quand une requête est **mise en file** (offline ou breaker).
|
|
@@ -19,7 +21,17 @@ export interface ApiClientOptions {
|
|
|
19
21
|
refreshUrl?: string;
|
|
20
22
|
endpoints?: any[];
|
|
21
23
|
timeout?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Niveau `debug` (sinon `info`) du logger de CE client, sans effet sur les autres. Avec un `logger`
|
|
26
|
+
* fourni : appliqué s'il sait faire des enfants (pino → enfant au niveau `debug`), ignoré sinon.
|
|
27
|
+
*/
|
|
22
28
|
debug?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Logger à utiliser à la place de celui de la lib (pino ou tout objet à `debug/info/warn/error`) :
|
|
31
|
+
* un serveur peut passer le sien, ou un logger muet. Par défaut, un enfant du logger pino partagé
|
|
32
|
+
* du processus (un seul transport par processus, cf. utils/logger.ts).
|
|
33
|
+
*/
|
|
34
|
+
logger?: ApiClientLogger | null;
|
|
23
35
|
maxRetries?: number;
|
|
24
36
|
circuitBreakerThreshold?: number;
|
|
25
37
|
circuitBreakerResetTime?: number;
|
|
@@ -108,7 +120,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
108
120
|
private _offlineClientManager;
|
|
109
121
|
private _ajv;
|
|
110
122
|
private _ajvNoDefaults;
|
|
111
|
-
_logger:
|
|
123
|
+
_logger: ApiClientLogger;
|
|
112
124
|
private _client;
|
|
113
125
|
private readonly _breakerThreshold;
|
|
114
126
|
private readonly _breakerResetTime;
|
|
@@ -121,7 +133,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
121
133
|
private _mode;
|
|
122
134
|
/** Contexte costum du SITE appelant, injecté sur les endpoints qui le déclarent (cf. setSiteCostum). */
|
|
123
135
|
private _siteCostum;
|
|
124
|
-
constructor({ baseURL, accessToken, refreshToken, refreshUrl, endpoints, timeout, debug, maxRetries, circuitBreakerThreshold, circuitBreakerResetTime, fromJSONValue, mode, tokenStorageStrategy, costumForceLive, siteCostum }: ApiClientOptions);
|
|
136
|
+
constructor({ baseURL, accessToken, refreshToken, refreshUrl, endpoints, timeout, debug, logger, maxRetries, circuitBreakerThreshold, circuitBreakerResetTime, fromJSONValue, mode, tokenStorageStrategy, costumForceLive, siteCostum }: ApiClientOptions);
|
|
125
137
|
/**
|
|
126
138
|
* Déclare l'identité costum du SITE APPELANT — l'entité au nom de laquelle ce front agit.
|
|
127
139
|
*
|
|
@@ -217,6 +229,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
217
229
|
private _resetCircuitBreakerSuccess;
|
|
218
230
|
static stripNullsInPlace(obj: any): any;
|
|
219
231
|
private _resolveSpecialValuesInPlace;
|
|
232
|
+
/** Nettoyage « anonyme » d'un schéma (alias `@xxx`), mémoïsé par schéma source — cf. utils/validators.ts. */
|
|
220
233
|
private _cleanSchemaLeftoverAlias;
|
|
221
234
|
/**
|
|
222
235
|
* Safely calls an asynchronous function and handles any errors that occur.
|
|
@@ -458,7 +471,6 @@ export default class ApiClient extends EventEmitter {
|
|
|
458
471
|
* @returns La donnée normalisée.
|
|
459
472
|
*/
|
|
460
473
|
private _normalizeRecursively;
|
|
461
|
-
private _startBeforeEndValidate;
|
|
462
474
|
/**
|
|
463
475
|
* Récupère le schéma de requête pour un endpoint donné.
|
|
464
476
|
* @param constant - Le nom de l'endpoint.
|
|
@@ -4,6 +4,20 @@ import type { Event } from "../api/Event.js";
|
|
|
4
4
|
import type { Organization } from "../api/Organization.js";
|
|
5
5
|
import type { Poi } from "../api/Poi.js";
|
|
6
6
|
import type { Project } from "../api/Project.js";
|
|
7
|
+
/**
|
|
8
|
+
* Forme d'un slug de costum, celle qu'exige la requête de `COSTUM_RESOLVED` (`costum/co/resolved`).
|
|
9
|
+
* Recopiée du contrat : `tests/unit/costum-prefetch-slug.test.ts` la compare au `pattern` du module d'endpoints.
|
|
10
|
+
*/
|
|
11
|
+
export declare const COSTUM_SLUG_RE: RegExp;
|
|
12
|
+
/**
|
|
13
|
+
* Slug de costum d'un document CHARGÉ : `source.key`, repli sur `source.keys[0]` — la préséance des trois
|
|
14
|
+
* lecteurs d'avant (`get()`, finalizer de `searchCostum`, `_setData`) — retenu SEULEMENT s'il a la forme
|
|
15
|
+
* d'un slug. Ces lecteurs typaient la donnée `{ key?: string; keys?: string[] }`, ce qu'elle n'est pas
|
|
16
|
+
* toujours (cf. `prefetchCostums`) : `_setData` passait un tableau à `resolveCostumCtxFromSource`, où
|
|
17
|
+
* `COSTUM_RUNTIME[sourceKey]` le convertissait en chaîne (`["x"]` → `"x"`). Une clé invalide ne se rabat
|
|
18
|
+
* PAS sur `keys[0]` : seule une clé absente le fait, comme avant.
|
|
19
|
+
*/
|
|
20
|
+
export declare function sourceKeyOf(doc: unknown): string | undefined;
|
|
7
21
|
/** Active/désactive FORCE-LIVE (cf. `COSTUM_FORCE_LIVE`). */
|
|
8
22
|
export declare function setCostumForceLive(actif: boolean): void;
|
|
9
23
|
/** État courant de FORCE-LIVE. */
|
|
@@ -25,8 +39,18 @@ export declare function describeCostumForms(user: BaseEntity, slug: string): Pro
|
|
|
25
39
|
* Pré-charge EN BATCH les costums (par slug) manquants/périmés du cache live, AVANT un revive synchrone
|
|
26
40
|
* (finalizer de `searchCostum`, `get()`, `entitySlug`). Dédup + TTL : un slug déjà frais est ignoré.
|
|
27
41
|
* Chaque fetch qui échoue est avalé (offline → le revive retombera sur le bundle). Concurrence bornée.
|
|
42
|
+
*
|
|
43
|
+
* Seules les clés à la forme d'un slug de costum partent. La base porte des `source.key` qui n'en sont pas
|
|
44
|
+
* (mesuré le 2026-10-15) : des TABLEAUX sur 820 éléments — `["crowdfunder"]` d'un import de 2016 sur un
|
|
45
|
+
* membre d'Open Atlas, mais aussi 5 organisations créées en 2024-2025 avec `insertOrign: "costum"` — et des
|
|
46
|
+
* chaînes hors format (`"MCZD33 Import2"`, `"<id>@organizations"`). La validation de `COSTUM_RESOLVED`
|
|
47
|
+
* refusait ces clés avant tout envoi : les écarter ne perd aucune résolution, et `safeCall` ne journalise
|
|
48
|
+
* plus une ERREUR à chaque recherche qui liste l'élément.
|
|
49
|
+
* Certaines nomment pourtant un vrai site (`["reunion10"]`, `["occitanie1"]`), et le legacy les y compte :
|
|
50
|
+
* MongoDB fait correspondre `{"source.key": "reunion10"}` à un tableau qui contient la valeur. La lib ne
|
|
51
|
+
* leur résolvait déjà aucun costum ; les rattacher relève de la normalisation des données, pas de ce filtre.
|
|
28
52
|
*/
|
|
29
|
-
export declare function prefetchCostums(user: BaseEntity, sourceKeys:
|
|
53
|
+
export declare function prefetchCostums(user: BaseEntity, sourceKeys: readonly unknown[]): Promise<void>;
|
|
30
54
|
/**
|
|
31
55
|
* Contexte costum résolu, attaché à une instance d'entité via `config.costumCtx`.
|
|
32
56
|
* Porté tel quel par `BaseEntity._costumCtx` et consommé par les 3 couches de filtrage.
|
package/types/index.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export type { default as Api } from "./Api.js";
|
|
|
44
44
|
export type { default as ApiClient } from "./ApiClient.js";
|
|
45
45
|
export type { default as EndpointApi } from "./api/EndpointApi.js";
|
|
46
46
|
export type { UserApi } from "./api/UserApi.js";
|
|
47
|
-
export type { ApiClientOptions, CallEndpointData, CallEndpointResult, CallEndpointResponse, ApiClientOfflineEnqueueResult } from "./ApiClient.js";
|
|
47
|
+
export type { ApiClientOptions, ApiClientLogger, CallEndpointData, CallEndpointResult, CallEndpointResponse, ApiClientOfflineEnqueueResult } from "./ApiClient.js";
|
|
48
48
|
export type { TokenStorageStrategy } from "./utils/TokenStorage.js";
|
|
49
49
|
export type { MultiServerTokenStorageStrategy } from "./utils/MultiServerTokenStorageStrategy.js";
|
|
50
50
|
export type { default as OfflineClientManager } from "./utils/OfflineClientManager.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Ce que l'ApiClient attend d'un logger : les quatre niveaux, rien d'autre (duck-typing, pino ou non). */
|
|
2
|
+
export interface ApiClientLogger {
|
|
3
|
+
debug: (...args: unknown[]) => void;
|
|
4
|
+
info: (...args: unknown[]) => void;
|
|
5
|
+
warn: (...args: unknown[]) => void;
|
|
6
|
+
error: (...args: unknown[]) => void;
|
|
7
|
+
}
|
|
8
|
+
type RootLogger = ApiClientLogger & {
|
|
9
|
+
child: (bindings: object, options?: {
|
|
10
|
+
level?: string;
|
|
11
|
+
}) => ApiClientLogger;
|
|
12
|
+
};
|
|
13
|
+
/** Le logger racine du processus, créé au premier appel. */
|
|
14
|
+
export declare function getRootLogger(): RootLogger;
|
|
15
|
+
/**
|
|
16
|
+
* Le logger d'UN client. Sans `logger` fourni : un enfant du logger racine au niveau demandé (un enfant
|
|
17
|
+
* pino ne crée ni thread ni flux : vingt clients coûtent zéro thread). Avec un `logger` fourni : lui-même,
|
|
18
|
+
* sauf si `debug` est demandé ET qu'il sait faire des enfants (pino) — on lui demande alors un enfant au
|
|
19
|
+
* niveau `debug`, pour que l'option tienne sa promesse même avec le logger d'un serveur réglé sur `info`.
|
|
20
|
+
* Un logger sans `child` (console, objet maison) est rendu tel quel : `debug` est alors sans effet.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createClientLogger(debug: boolean, logger?: ApiClientLogger | null): ApiClientLogger;
|
|
23
|
+
/**
|
|
24
|
+
* Pour les tests : oublie la racine (la prochaine demande en recrée une), après avoir vidé et fermé son
|
|
25
|
+
* flux — en dev/test la racine porte un transport `pino-pretty` (worker + listener `exit`) qu'on ne
|
|
26
|
+
* veut pas orpheliner à chaque reset.
|
|
27
|
+
*/
|
|
28
|
+
export declare function _resetRootLoggerForTests(): Promise<void>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ValidateFunction } from "ajv";
|
|
2
|
+
export type AjvVariant = "defaults" | "noDefaults";
|
|
3
|
+
/** Fonction de validation AJV. */
|
|
4
|
+
export type Validator = ValidateFunction;
|
|
5
|
+
/** L'instance AJV partagée d'une variante, construite au premier appel. */
|
|
6
|
+
export declare function getAjv(variant: AjvVariant): any;
|
|
7
|
+
/**
|
|
8
|
+
* Le validateur compilé d'un schéma.
|
|
9
|
+
* - sans `dynamic` : le schéma est un objet STABLE (contrat, ou nettoyage mémoïsé) → cache par identité,
|
|
10
|
+
* illimité mais faible (WeakMap).
|
|
11
|
+
* - `dynamic: true` : le schéma vient d'être construit (enveloppe costum) → cache borné, indexé par `key`
|
|
12
|
+
* (cf. `dynamicKey`) ou, à défaut, par le JSON du schéma entier.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getValidator(schema: object, variant?: AjvVariant, opts?: {
|
|
15
|
+
dynamic?: boolean;
|
|
16
|
+
key?: string;
|
|
17
|
+
}): Validator;
|
|
18
|
+
/**
|
|
19
|
+
* Clé du cache borné pour un schéma recomposé à partir d'un schéma de base STABLE (identité) et d'un
|
|
20
|
+
* complément VARIABLE (sérialisé) : on ne sérialise que le complément — l'enveloppe costum, quelques
|
|
21
|
+
* champs — jamais le schéma du contrat entier (plusieurs dizaines de Ko avec ses `$defs`).
|
|
22
|
+
*/
|
|
23
|
+
export declare function dynamicKey(base: object, extra: unknown): string;
|
|
24
|
+
/** Version nettoyée d'un schéma du contrat, la MÊME d'un appel à l'autre pour le même schéma source. */
|
|
25
|
+
export declare function cleanSchemaLeftoverAlias<T>(schema: T): T;
|
|
26
|
+
/** Pour les tests : taille du cache borné d'une variante. */
|
|
27
|
+
export declare function _dynamicCacheSizeForTests(variant: AjvVariant): number;
|