@communecter/cocolight-api-client 1.0.195 → 1.0.197
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/api/Answer.d.ts +89 -0
- package/types/api/BaseEntity.d.ts +70 -0
- package/types/api/EndpointApi.d.ts +42 -3
- package/types/api/EndpointApi.types.d.ts +158 -6
- package/types/api/Event.d.ts +1 -1
- package/types/api/Organization.d.ts +2 -2
- package/types/api/Poi.d.ts +1 -1
- package/types/api/Project.d.ts +2 -2
- package/types/api/User.d.ts +39 -3
- package/types/api/serverDataType/Ampli.d.ts +121 -0
- package/types/costum/liveDigest.d.ts +29 -0
- package/types/costum/runtime.d.ts +63 -7
- package/types/costum/widenSchema.d.ts +22 -0
- package/types/endpoints.module.d.ts +5355 -2166
- package/types/index.d.ts +5 -2
- package/types/utils/ampliSlug.d.ts +31 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types de l'**ampli** — l'espace de propositions d'un costum.
|
|
3
|
+
*
|
|
4
|
+
* Source de vérité : les actions legacy du module costum
|
|
5
|
+
* `controllers/actions/ampli/{CreateAmpliAction,RemoveAmpliAction}.php`, routées par
|
|
6
|
+
* `CostumizeController` sur `/costum/costumize/{createampli,removeampli}`.
|
|
7
|
+
*
|
|
8
|
+
* Un ampli n'est **pas une entité** : c'est une entrée de la carte `costum.ampli`, portée par
|
|
9
|
+
* l'élément hôte du costum (organisation, projet, citoyen ou événement) et indexée par son
|
|
10
|
+
* **slug**. D'où le placement des deux méthodes sur `BaseEntity` plutôt qu'une classe dédiée :
|
|
11
|
+
* elles s'appliquent à l'hôte, exactement comme `saveToolEnrichment`.
|
|
12
|
+
*/
|
|
13
|
+
/** Collections pouvant porter un costum, donc un ampli (`parentType` des deux actions). */
|
|
14
|
+
export declare const AMPLI_PARENT_TYPES: readonly ["organizations", "projects", "citoyens", "events"];
|
|
15
|
+
export type AmpliParentType = (typeof AMPLI_PARENT_TYPES)[number];
|
|
16
|
+
/**
|
|
17
|
+
* Chemins des questions du formulaire de dépôt, forme `<idSousFormulaire>.<idQuestion>`
|
|
18
|
+
* (**sans** le préfixe `answers.`). Chaîne vide quand la question n'existe pas — `finder` l'est
|
|
19
|
+
* toujours pour un formulaire généré par le serveur.
|
|
20
|
+
*/
|
|
21
|
+
export interface AmpliPaths {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
address: string;
|
|
25
|
+
tags: string;
|
|
26
|
+
image: string;
|
|
27
|
+
finder: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Une entrée de `costum.ampli`, telle que relue via `element/about` — quelle que soit son époque.
|
|
31
|
+
*
|
|
32
|
+
* Deux formes coexistent en base :
|
|
33
|
+
* - les entrées écrites par `CreateAmpliAction` AVANT modules/costum@3ef97ef28 n'ont que
|
|
34
|
+
* `{ name, description, tags, pages, home }`, et leur clé vient de `strtolower` + espace → tiret
|
|
35
|
+
* (« Idées d'été » → `idées-d'été`) ;
|
|
36
|
+
* - les entrées écrites depuis portent en plus `slug`, `coform` et `path` ({@link CreatedAmpliEntry}).
|
|
37
|
+
*
|
|
38
|
+
* La CLÉ de la carte `costum.ampli` reste la seule référence fiable d'un ampli existant.
|
|
39
|
+
*/
|
|
40
|
+
export interface AmpliEntry {
|
|
41
|
+
name: string;
|
|
42
|
+
/** Markdown, `""` si non fourni. */
|
|
43
|
+
description: string;
|
|
44
|
+
/** `null` sur une entrée ancienne créée avec des tags en tableau (`explode` d'un tableau). */
|
|
45
|
+
tags: string[] | null;
|
|
46
|
+
/** Pages Co de l'ampli (`#<page>`). Toujours vide pour une création depuis site-json. */
|
|
47
|
+
pages: string[];
|
|
48
|
+
/** Ancre de la page d'accueil Co. Toujours vide pour une création depuis site-json. */
|
|
49
|
+
home: string;
|
|
50
|
+
/** Clé de l'entrée dans `costum.ampli` — absente des entrées anciennes. */
|
|
51
|
+
slug?: string;
|
|
52
|
+
/** ObjectId du `Form` de dépôt — absent des entrées anciennes. */
|
|
53
|
+
coform?: string;
|
|
54
|
+
/** Chemins des questions du formulaire de dépôt — absents des entrées anciennes. */
|
|
55
|
+
path?: AmpliPaths;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* L'entrée que {@link BaseEntity#createAmpli} vient d'écrire : la forme actuelle, complète.
|
|
59
|
+
*/
|
|
60
|
+
export interface CreatedAmpliEntry extends AmpliEntry {
|
|
61
|
+
slug: string;
|
|
62
|
+
tags: string[];
|
|
63
|
+
coform: string;
|
|
64
|
+
path: AmpliPaths;
|
|
65
|
+
}
|
|
66
|
+
/** Champs communs aux deux modes de {@link BaseEntity#createAmpli}. */
|
|
67
|
+
interface CreateAmpliInputCommon {
|
|
68
|
+
/**
|
|
69
|
+
* Nom affiché. Le serveur en dérive la **clé** de l'entrée (`ampliSlug`) : « Idées d'été » donne
|
|
70
|
+
* `idees-d-ete`. Un nom qui ne produit aucun slug exploitable est refusé.
|
|
71
|
+
*/
|
|
72
|
+
name: string;
|
|
73
|
+
/** Markdown, stocké tel quel. */
|
|
74
|
+
description?: string;
|
|
75
|
+
/** Vides et doublons sont retirés côté serveur. */
|
|
76
|
+
tags?: string[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Mode A (défaut) — le **serveur crée le formulaire** : un `Form` et son sous-formulaire à cinq
|
|
80
|
+
* questions (titre, description, adresse, mots-clés, image), dont les chemins reviennent dans
|
|
81
|
+
* {@link CreatedAmpliEntry.path}. C'est le mode du parcours de création depuis site-json.
|
|
82
|
+
*/
|
|
83
|
+
export type CreateAmpliInputGeneratedForm = CreateAmpliInputCommon;
|
|
84
|
+
/**
|
|
85
|
+
* Mode B — **rattachement à un formulaire existant** : `coform` désigne le `Form`, `namePath` et
|
|
86
|
+
* `addressPath` sont exigés par le serveur, les autres chemins sont facultatifs.
|
|
87
|
+
*/
|
|
88
|
+
export interface CreateAmpliInputExistingForm extends CreateAmpliInputCommon {
|
|
89
|
+
/** ObjectId du `Form` à rattacher. Sa présence bascule l'appel en mode B. */
|
|
90
|
+
coform: string;
|
|
91
|
+
namePath: string;
|
|
92
|
+
addressPath: string;
|
|
93
|
+
descriptionPath?: string;
|
|
94
|
+
tagsPath?: string;
|
|
95
|
+
imagePath?: string;
|
|
96
|
+
finderPath?: string;
|
|
97
|
+
}
|
|
98
|
+
/** Entrée de {@link BaseEntity#createAmpli} — le mode se lit à la présence de `coform`. */
|
|
99
|
+
export type CreateAmpliInput = CreateAmpliInputGeneratedForm | CreateAmpliInputExistingForm;
|
|
100
|
+
/**
|
|
101
|
+
* Retour de {@link BaseEntity#createAmpli}.
|
|
102
|
+
*
|
|
103
|
+
* `data`, `app` et `blockCms` ne servent qu'à l'interface Co (boutons de menu, carte des pages,
|
|
104
|
+
* blocs CMS) et arrivent **vides** pour un appel site-json. Ils restent au contrat pour garder une
|
|
105
|
+
* seule forme de réponse ; un appelant site-json les ignore.
|
|
106
|
+
*/
|
|
107
|
+
export interface CreateAmpliResult {
|
|
108
|
+
result: true;
|
|
109
|
+
/** Clé de l'entrée : permet de naviguer vers `/ampli/<slug>` sans attendre un rechargement. */
|
|
110
|
+
slug: string;
|
|
111
|
+
ampli: CreatedAmpliEntry;
|
|
112
|
+
data: unknown[];
|
|
113
|
+
app: unknown[];
|
|
114
|
+
blockCms: unknown[];
|
|
115
|
+
}
|
|
116
|
+
/** Retour de {@link BaseEntity#removeAmpli} — `msg` vaut `"Ampli removed"`. */
|
|
117
|
+
export interface RemoveAmpliResult {
|
|
118
|
+
result: true;
|
|
119
|
+
msg: string;
|
|
120
|
+
}
|
|
121
|
+
export {};
|
|
@@ -63,6 +63,28 @@ interface FieldDef {
|
|
|
63
63
|
/** Valeur FORCÉE par le costum — cf. collectValuePresets. */
|
|
64
64
|
value?: unknown;
|
|
65
65
|
}
|
|
66
|
+
/** Clé de base d'une collection telle que la déclare un `typeObj` — cf. `findCostumBaseNode`. */
|
|
67
|
+
export interface CostumBaseNode {
|
|
68
|
+
/** Clé `typeObj` retenue (ex. `organizations`, `event`). */
|
|
69
|
+
typeKey: string;
|
|
70
|
+
/** Le nœud déclare-t-il des champs (`beforeBuild.properties`) ? Sinon : variante de base VIDE. */
|
|
71
|
+
hasForm: boolean;
|
|
72
|
+
add: boolean;
|
|
73
|
+
createLabel: string | null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Trouve la CLÉ DE BASE d'une collection dans le `typeObj` d'un costum — le formulaire que le site
|
|
77
|
+
* applique quand on « ajoute une organisation » sans rien préciser, même quand ce nœud ne déclare AUCUN
|
|
78
|
+
* champ (ex. federationDesCae : `organizations: {add:true}` à côté du sous-type `organizationsTls`).
|
|
79
|
+
*
|
|
80
|
+
* Une base est une clé de `BASE_TYPEKEYS[collection]` dont le nœud est un objet SANS `sameAs`, ou avec un
|
|
81
|
+
* `sameAs` RÉFLEXIF (`event: {sameAs:"event"}` — parent62, institutBleu, navigator) : ce `sameAs` ne
|
|
82
|
+
* rattache le nœud à rien d'autre que lui-même. Deux clés sœurs (`organization` ET `organizations`) : on
|
|
83
|
+
* préfère celle qui porte un formulaire, sinon la première dans l'ordre du `typeObj` — en pratique
|
|
84
|
+
* `costum/co/resolved` n'en livre qu'une (le dernier déclaré gagne à la fusion moteur ⊕ overlay).
|
|
85
|
+
* Null si le costum ne déclare pas de clé de base pour cette collection.
|
|
86
|
+
*/
|
|
87
|
+
export declare function findCostumBaseNode(data: CostumJsonData, collection: string): CostumBaseNode | null;
|
|
66
88
|
/**
|
|
67
89
|
* Digère `getcostumjson` → `CostumRuntimeContext` pour UNE collection (null si le costum ne couvre pas
|
|
68
90
|
* cette collection). `meta` = identité de l'élément porteur (costumId/costumType, résolue par slug/getinfo).
|
|
@@ -86,6 +108,12 @@ export declare function listCostumFormNodes(data: CostumJsonData): Array<{
|
|
|
86
108
|
createLabel: string | null;
|
|
87
109
|
discriminator?: string;
|
|
88
110
|
}>;
|
|
111
|
+
/**
|
|
112
|
+
* `opts.typeKey` : ne digère que cette clé `typeObj` (énumération par sous-type).
|
|
113
|
+
* `opts.allowFormless` (avec `typeKey`) : digère AUSSI ce nœud s'il ne déclare aucun champ — sert à la
|
|
114
|
+
* variante de BASE vide (cf. `findCostumBaseNode`) : schéma vide, `fields` vide, mais `presetValue` et
|
|
115
|
+
* `hide` PROPRES du nœud conservés. Sans cette option, un nœud sans formulaire est ignoré (inchangé).
|
|
116
|
+
*/
|
|
89
117
|
export declare function digestCostumJson(data: CostumJsonData, collection: Collection, meta: {
|
|
90
118
|
costumId: string;
|
|
91
119
|
costumType: string;
|
|
@@ -93,5 +121,6 @@ export declare function digestCostumJson(data: CostumJsonData, collection: Colle
|
|
|
93
121
|
baseFieldNames?: string[];
|
|
94
122
|
}, opts?: {
|
|
95
123
|
typeKey?: string;
|
|
124
|
+
allowFormless?: boolean;
|
|
96
125
|
}): DigestedCostum | null;
|
|
97
126
|
export {};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { CostumExtensionModule, CostumExtensionField, KnownCostumSlug, Collection } from "./types.js";
|
|
2
2
|
import type { BaseEntity } from "../api/BaseEntity.js";
|
|
3
|
+
import type { Event } from "../api/Event.js";
|
|
4
|
+
import type { Organization } from "../api/Organization.js";
|
|
5
|
+
import type { Poi } from "../api/Poi.js";
|
|
6
|
+
import type { Project } from "../api/Project.js";
|
|
3
7
|
/** Active/désactive FORCE-LIVE (cf. `COSTUM_FORCE_LIVE`). */
|
|
4
8
|
export declare function setCostumForceLive(actif: boolean): void;
|
|
5
9
|
/** État courant de FORCE-LIVE. */
|
|
@@ -83,6 +87,33 @@ export interface CostumFormDescriptor {
|
|
|
83
87
|
/** Valeur de `type` estampillée au save qui distingue le sous-type (= presetValue.type, sinon typeKey). */
|
|
84
88
|
discriminator?: string;
|
|
85
89
|
}
|
|
90
|
+
/** Collections couvertes par les fabriques du scope (poi/organization/project/event). Identité entityType↔collection. */
|
|
91
|
+
type ScopeCollection = "poi" | "organizations" | "projects" | "events";
|
|
92
|
+
/** Entité rendue par chaque fabrique — même correspondance que `EntityTypeMap` (BaseEntity), qui n'est pas
|
|
93
|
+
* exporté : `create` étant public, son type de retour doit être nommable dans les `.d.ts`. */
|
|
94
|
+
type ScopeEntityMap = {
|
|
95
|
+
poi: Poi;
|
|
96
|
+
organizations: Organization;
|
|
97
|
+
projects: Project;
|
|
98
|
+
events: Event;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Options de création sous un costum (`CostumScope.create` et ses raccourcis). Jamais envoyées au serveur.
|
|
102
|
+
*/
|
|
103
|
+
export interface CostumCreateOptions {
|
|
104
|
+
/**
|
|
105
|
+
* Sous-type CIBLÉ : clé `typeObj` du costum (ex. `"organizationsTls"` pour le formulaire « Créer votre
|
|
106
|
+
* CAE »). Ses presets et champs s'appliquent, quel que soit `data.type`. Sans lui, un sous-type ne
|
|
107
|
+
* s'applique que si `data.type` est son discriminant ; sinon c'est la clé de base de la collection.
|
|
108
|
+
* Inconnu du costum → repli silencieux sur cette règle (trace `debug`).
|
|
109
|
+
*/
|
|
110
|
+
subType?: string;
|
|
111
|
+
}
|
|
112
|
+
/** Options de `CostumScope.contextFor` : celles de la création, plus le mode de sélection. */
|
|
113
|
+
export interface CostumContextOptions extends CostumCreateOptions {
|
|
114
|
+
/** Sélectionner comme une CRÉATION (défaut = clé de base) plutôt que comme une lecture (défaut historique). */
|
|
115
|
+
create?: boolean;
|
|
116
|
+
}
|
|
86
117
|
/**
|
|
87
118
|
* Scope costum : fabrique des entités liées à un costum. Réutilise le `user` (parent, deps, auth)
|
|
88
119
|
* et n'altère jamais l'état partagé — chaque entité reçoit son propre `_costumCtx`.
|
|
@@ -98,14 +129,38 @@ export declare class CostumScope {
|
|
|
98
129
|
* Construit le `CostumRuntimeContext` pour une collection (null si non couverte). `type` (optionnel) = le
|
|
99
130
|
* sous-type voulu (= `presetValue.type` de la variante) : sélectionne l'overlay de CE sous-type, sinon la
|
|
100
131
|
* racine=union. Indispensable au CREATE d'un sous-type précis (bon `type`/presets/champs — cf. P0 write-safety).
|
|
132
|
+
*
|
|
133
|
+
* `opts` (optionnel) : `subType` cible un sous-type par sa clé `typeObj` (prime sur `type`) ; `create`
|
|
134
|
+
* sélectionne comme une création (défaut = clé de base du costum). Sans `opts` : sélection de LECTURE,
|
|
135
|
+
* inchangée (revive/édition).
|
|
136
|
+
*/
|
|
137
|
+
contextFor(collection: Collection, type?: string | null, opts?: CostumContextOptions): CostumRuntimeContext | null;
|
|
138
|
+
/**
|
|
139
|
+
* Crée une entité de `collection` sous ce costum (presets appliqués, surchargeables par `data`).
|
|
140
|
+
*
|
|
141
|
+
* Formulaire costum appliqué (presets + champs) — dans l'ordre :
|
|
142
|
+
* 1. `opts.subType` : le sous-type CIBLÉ par sa clé `typeObj` (ex. `"organizationsTls"`) ;
|
|
143
|
+
* 2. `data.type` : le sous-type dont c'est le discriminant (ex. `poi({ type: "article" })`) ;
|
|
144
|
+
* 3. sinon la CLÉ DE BASE de la collection si le costum en déclare une (ex. `organizations`), MÊME SANS
|
|
145
|
+
* champ : un sous-type n'est jamais appliqué par défaut ; sans clé de base, comportement historique.
|
|
146
|
+
* Un `subType` inconnu retombe sur 2→3 (trace `debug`, aucune exception). `opts` n'est JAMAIS envoyé au
|
|
147
|
+
* serveur. La whitelist d'écriture reste l'union racine ∪ variante (byte-safe).
|
|
148
|
+
*
|
|
149
|
+
* const cae = await tl.organization({ name }, { subType: "organizationsTls" }); // formulaire « CAE »
|
|
150
|
+
* const org = await tl.organization({ name }); // formulaire de base
|
|
151
|
+
*/
|
|
152
|
+
create<T extends ScopeCollection>(collection: T, data?: Record<string, unknown>, opts?: CostumCreateOptions): Promise<ScopeEntityMap[T]>;
|
|
153
|
+
/**
|
|
154
|
+
* Trace (`debug`) un `subType` que ce scope ne sait pas cibler pour `collection` : collection non couverte,
|
|
155
|
+
* ou variantes dont aucune ne porte cette clé `typeObj`. Une collection à formulaire UNIQUE n'a pas de
|
|
156
|
+
* variantes à comparer : rien n'est tracé (la racine EST ce formulaire). Le repli lui-même est fait par
|
|
157
|
+
* `pickCostumOverlay` ; ceci ne fait que le rendre visible.
|
|
101
158
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
project(data?: Record<string, unknown>): Promise<import("../index.js").Project>;
|
|
108
|
-
event(data?: Record<string, unknown>): Promise<import("../index.js").Event>;
|
|
159
|
+
private traceUnknownSubType;
|
|
160
|
+
poi(data?: Record<string, unknown>, opts?: CostumCreateOptions): Promise<Poi>;
|
|
161
|
+
organization(data?: Record<string, unknown>, opts?: CostumCreateOptions): Promise<Organization>;
|
|
162
|
+
project(data?: Record<string, unknown>, opts?: CostumCreateOptions): Promise<Project>;
|
|
163
|
+
event(data?: Record<string, unknown>, opts?: CostumCreateOptions): Promise<Event>;
|
|
109
164
|
/**
|
|
110
165
|
* Poste une news sous CE costum, sur le mur de `target` : `source.key` = costum du scope (le SITE,
|
|
111
166
|
* comme poi/org — cf. `News::prepData`), `parent` = `target`. News n'est PAS une collection « élément »
|
|
@@ -159,3 +214,4 @@ export declare function resolveCostumScope(user: BaseEntity, slug: KnownCostumSl
|
|
|
159
214
|
* No-op si le costum ne résout pas / ne couvre pas la collection (l'entité reste en scope d'identité).
|
|
160
215
|
*/
|
|
161
216
|
export declare function loadCostumContext(user: BaseEntity, slug: string, collection: Collection): Promise<CostumRuntimeContext | null>;
|
|
217
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UN COSTUM PEUT ÉLARGIR UN CHAMP NATIF, JAMAIS LE RESTREINDRE.
|
|
3
|
+
*
|
|
4
|
+
* Un costum legacy redéclare des champs que le contrat connaît déjà (`type`, `tags`, `openingHours`,
|
|
5
|
+
* `telephone`…). Son schéma ne vient pas du stockage mais du WIDGET déclaré (digest live, `inferType`)
|
|
6
|
+
* ou d'un préremplissage (`presetProps`, typé chaîne). Il sert à ÉLARGIR un champ contraint — les
|
|
7
|
+
* types d'événement d'institutBleu sont tous hors de l'énumération native, et la production en vit.
|
|
8
|
+
* Mais posé À LA PLACE du schéma natif, il refusait aussi la forme native. Mesuré le 2026-10-01 sur les
|
|
9
|
+
* 21 costums résolus des sites de site-json : 111 champs natifs redéclarés, dont 8 RESTREINTS — horaires
|
|
10
|
+
* en liste refusés (CAE, navigator, relief : création impossible dès qu'on les saisit), téléphone en
|
|
11
|
+
* objet legacy refusé, mots-clés préremplis refusés en liste — pour 27 élargissements légitimes.
|
|
12
|
+
*
|
|
13
|
+
* Règle : pour un champ défini des deux côtés, la requête accepte le natif OU le costum (`anyOf`).
|
|
14
|
+
* Elle est monotone — tout ce qui passait passe encore — et une valeur que les deux refusent reste
|
|
15
|
+
* refusée. Appliquée aux DEUX points de fusion : la création (`ApiClient.callEndpoint`, enveloppe
|
|
16
|
+
* costum) et la modification (`BaseEntity._saveCostumViaElementSave`), qui faisaient l'inverse l'une
|
|
17
|
+
* de l'autre (le costum primait à la création, le natif à la modification).
|
|
18
|
+
*/
|
|
19
|
+
/** Schéma d'un champ défini par le contrat (`natif`) ET par le costum : natif OU costum. */
|
|
20
|
+
export declare function widenSchema(natif: unknown, costum: unknown): unknown;
|
|
21
|
+
/** `widenSchema` clé par clé : chaque propriété du costum élargit celle du natif, les autres restent. */
|
|
22
|
+
export declare function widenProperties(natives: Record<string, unknown>, costum: Record<string, unknown>): Record<string, unknown>;
|