@communecter/cocolight-api-client 1.0.189 → 1.0.191

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@communecter/cocolight-api-client",
3
- "version": "1.0.189",
3
+ "version": "1.0.191",
4
4
  "description": "Client Axios simplifié pour l'API cocolight",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,6 +22,27 @@ export interface AnswerChange {
22
22
  mutationType: "create" | "update" | "";
23
23
  changedFields: string[];
24
24
  }
25
+ /** Options de `Answer.generateProject()` — équivalent `costum.contextId`/`costum.contextType` legacy. */
26
+ export interface GenerateProjectOptions {
27
+ /** ID de l'entité parente (org/site porteur de l'appel). */
28
+ parentId: string;
29
+ /** Type de l'entité parente (ex: `"organizations"`). */
30
+ parentType: string;
31
+ }
32
+ /** Résultat de `Answer.generateProject()` — le backend renvoie la clé française `projet`. */
33
+ export interface GenerateProjectResult {
34
+ projectId: string;
35
+ roomId: string;
36
+ }
37
+ /**
38
+ * Résultat de `Answer.generateMilestoneFromDepense()`. `milestoneId` peut être
39
+ * une chaîne VIDE si la clé de dépense passée ne correspond à aucune entrée du
40
+ * tableau `depense[]` — le backend renvoie quand même `{success:1}` dans ce cas
41
+ * (cf. DepenseMilestoneOperationAction.php:39-43).
42
+ */
43
+ export interface GenerateMilestoneFromDepenseResult {
44
+ milestoneId: string;
45
+ }
25
46
  /** Un axe du radar multi-eval (= un input radioNew d'une step donnée). */
26
47
  export interface MultiEvalAxis {
27
48
  key: string;
@@ -365,6 +386,60 @@ export declare class Answer extends BaseEntity<AnswerItemNormalized> {
365
386
  * new Date(history[0].at * 1000); // date de la dernière modif (at en SECONDES)
366
387
  */
367
388
  getHistory(): Promise<AnswerChange[]>;
389
+ /**
390
+ * Promeut cette Answer en Project + Room (génération **irréversible** — une
391
+ * fois `project.id` posé, un second appel échoue avec "Already have a
392
+ * project"). Construit le projet à partir du mapping `proposition`/
393
+ * `description`/`depense` du form de config AAP.
394
+ *
395
+ * Constant : `GENERATE_PROJECT_FROM_ANSWER` (POST
396
+ * `/survey/form/generateproject/answerId/{answerId}/parentId/{parentId}/parentType/{parentType}`,
397
+ * auth bearer — le backend pose `Yii::app()->session['userId']` comme
398
+ * créateur et pour la notification `PROPOSAL_TO_PROJECT`).
399
+ *
400
+ * @param opts.parentId - ID de l'entité parente (org/site porteur de l'appel).
401
+ * @param opts.parentType - Type de l'entité parente (ex: `"organizations"`).
402
+ * @returns `{ projectId, roomId }` — le backend renvoie la clé française `projet`.
403
+ * @throws {ApiError} 400 si Answer sans id, ou `parentId`/`parentType` manquants.
404
+ * @throws {ApiAuthenticationError} si non connecté.
405
+ * @throws {ApiError} 409 si un projet est déjà associé à cette réponse.
406
+ * @throws {ApiError} 422 si le mapping du form ne fournit pas de nom de projet exploitable.
407
+ *
408
+ * @example
409
+ * const result = await answer.generateProject({ parentId: costum.contextId, parentType: costum.contextType });
410
+ */
411
+ generateProject(opts: GenerateProjectOptions): Promise<GenerateProjectResult>;
412
+ /**
413
+ * Sync answer→project pour UNE dépense de cette réponse (endpoint
414
+ * `GENERATE_MILESTONE_FROM_DEPENSE`,
415
+ * `POST /survey/form/depensemilestoneoperation`, auth bearer) : si la
416
+ * dépense `depenseKey` n'a pas encore de `milestone`, en crée un sur
417
+ * `project.oceco.milestones` ET pose `depense[depenseKey].milestone`,
418
+ * atomiquement côté serveur.
419
+ *
420
+ * L'endpoint serveur est idempotent (no-op si `!empty($dep["milestone"])`,
421
+ * `Answer::generateMilestonneFromDepense`), mais **cette méthode ne l'est
422
+ * pas** : un second appel sur la même dépense renvoie `{success:1,
423
+ * milestoneId:""}` côté serveur, que ce wrapper traite comme une erreur 502.
424
+ * L'appelant doit donc filtrer `if (depense.milestone) continue;` avant
425
+ * d'appeler (cf. `site-json` `associateExistingProject.ts`).
426
+ *
427
+ * Contrairement à `generateProject()`, exige que cette réponse ait DÉJÀ un
428
+ * projet associé (`answer.project.id` posé) — sinon `ApiError 400`
429
+ * (`"Don't have a project"`).
430
+ *
431
+ * @param depenseKey - Clé (index) de la dépense dans `answers.<step>.depense[]` —
432
+ * PAS un id Mongo. Une clé sans correspondance ne lève pas d'erreur côté
433
+ * serveur (`{success:1, milestoneId:""}`) — cette méthode le traite comme
434
+ * une erreur (502) plutôt que de renvoyer un id vide silencieusement.
435
+ * @throws {ApiError} 400 si Answer sans id, ou si aucun projet n'est associé.
436
+ * @throws {ApiAuthenticationError} si non connecté.
437
+ * @throws {ApiError} 502 si le serveur ne renvoie pas de `milestoneId` exploitable.
438
+ *
439
+ * @example
440
+ * const { milestoneId } = await answer.generateMilestoneFromDepense("0");
441
+ */
442
+ generateMilestoneFromDepense(depenseKey: string): Promise<GenerateMilestoneFromDepenseResult>;
368
443
  /**
369
444
  * Récupère les datasets agrégés des évaluations multiples (radar) de cette
370
445
  * Answer. Pour une réponse partagée contenant des inputs `radioNew` avec
@@ -1712,8 +1712,9 @@ export declare class BaseEntity<TServerData = any> {
1712
1712
  * Récupérer les événements d'une entitée : liste des événements de l'entité ou elle est "organizer" ou "attendee".
1713
1713
  * Constant : GET_EVENTS
1714
1714
  * `startDateUTC`/`endDateUTC` acceptent un `Date` ou une string ISO (un `Date` est coercé en ISO).
1715
- * `recurrency` est typé `false` (garde parité, comme `searchEventsCostum`) : omettre (récurrents inclus
1716
- * en mode calendrier) ou passer `false` (exclure) ; jamais `true` (le legacy `=== true` l'exclurait → divergence).
1715
+ * `recurrency` (booléen) : omettre ou `true` = récurrents inclus, `false` = exclus — fiable sur les deux
1716
+ * serveurs depuis le 2026-09-04 (parse booléen legacy + miroir Node). Mode LISTE (sans date) : mêmes
1717
+ * paramètres optionnels `from`/`to`/`order` que `searchEventsCostum` (voir sa doc).
1717
1718
  * @param data - Paramètres (partiels) de recherche/pagination.
1718
1719
  * @returns - Les données de réponse.
1719
1720
  */
@@ -2556,19 +2557,32 @@ export declare class BaseEntity<TServerData = any> {
2556
2557
  * **Deux modes** (endpoint `/co2/search/agenda`), selon que tu passes une date ou non :
2557
2558
  *
2558
2559
  * 1. **CALENDRIER** — déclenché par `startDateUTC` et/ou `endDateUTC` (l'agenda d'une période) :
2559
- * ramène **TOUT** ce qui matche la plage — ponctuels **+ récurrents** (`openingHours`, sauf `recurrency:false`) —
2560
- * trié par **occurrence** (`startDateSort`/`startDateSortFormat` calculés côté serveur), résultat = **tableau**.
2561
- * **Pas de pagination** serveur : une seule page (`next()`/`prev()` sans effet).
2562
- * 2. **LISTE** — déclenché par l'**absence** de date (flux paginé) :
2563
- * **ponctuels uniquement** (récurrents exclus), triés par `startDate` **décroissant** (plus récents d'abord),
2564
- * paginés via `indexMin`/`indexStep` (défaut 30) — `next()`/`prev()` fonctionnent. (Backend : objet keyé `_id`,
2565
- * hydraté en tableau d'`Event` côté lib.)
2560
+ * ramène **TOUT** ce qui matche la plage — ponctuels **+ récurrents** (`openingHours`, sauf `recurrency:false`),
2561
+ * chaque récurrent **déplié en une ligne par occurrence** — trié par **occurrence** (`startDateSort`/
2562
+ * `startDateSortFormat` calculés côté serveur), résultat = **tableau**. **Pas de pagination** serveur :
2563
+ * une seule page (`next()`/`prev()` sans effet). Pour une GRILLE (mois/semaine/jour).
2564
+ * 2. **LISTE** — déclenché par l'**absence** de date (flux paginé, `indexMin`/`indexStep`, `next()`/`prev()`) :
2565
+ * ponctuels **+ récurrents** (depuis le legacy 14c2caa1, **une ligne par récurrent** portant sa PROCHAINE
2566
+ * occurrence dans `startDateSort`/`startDateSortFormat`), résultat = **tableau**. Par défaut trié par
2567
+ * occurrence **décroissant** et **non borné** : la 1re page contient les events les plus LOINTAINS.
2568
+ * Trois paramètres **optionnels** (legacy 2026-09-04, miroir Node) rendent ce mode utilisable pour
2569
+ * « les prochains » :
2570
+ * - `from` (Date ou ISO) : borne basse « pas encore terminé à from » (ponctuel : `endDate ≥ from` sinon
2571
+ * `startDate ≥ from` ; récurrent : prochaine occurrence calculée DEPUIS `from`, un créneau en cours reste
2572
+ * servi). C'est aussi l'**ancre** de la pagination : `next()` rejoue la même valeur, la clé de tri des
2573
+ * récurrents ne bouge pas entre deux pages — passe donc un instant figé, pas `new Date()` à chaque appel.
2574
+ * - `to` (Date ou ISO) : borne haute stricte sur la clé d'occurrence.
2575
+ * - `order` : `"asc"` | `"desc"` (défaut `"desc"`).
2576
+ * Dès qu'un des trois est présent, chaque ligne porte **`endDateSortFormat`** (fin d'occurrence calculée
2577
+ * serveur, dans le fuseau de l'événement ; `null` sans fin connue) — ne PAS la recalculer côté client.
2578
+ * Sans eux, la réponse est strictement celle d'avant (aucune clé nouvelle).
2579
+ * « Les prochains » = `{ from: now, order: "asc" }` · « Les passés » = `{ to: now, order: "desc", recurrency: false }`.
2566
2580
  *
2567
2581
  * Le scope costum (`sourceKey`) s'applique dans les **deux** modes.
2568
2582
  *
2569
- * `recurrency` est typé `false` (garde parité) : **omettre** (mode calendrier → récurrents inclus) ou passer
2570
- * `false` (exclure) ; **jamais `true`** — le legacy fait un test strict `=== true` qui exclurait les récurrents
2571
- * (divergence), valeur donc interdite au type **et** à l'AJV.
2583
+ * `recurrency` (booléen) : omettre ou `true` = récurrents inclus, `false` = exclus (en LISTE, la requête des
2584
+ * récurrents est sautée). Fiable sur les deux serveurs depuis le 2026-09-04 (parse booléen legacy + miroir
2585
+ * Node) — l'ancienne garde `const:false` du contrat est levée.
2572
2586
  *
2573
2587
  * `startDateUTC`/`endDateUTC` acceptent un **`Date` ou une string ISO** : un `Date` est coercé en ISO
2574
2588
  * (`toISOString()`) avant l'envoi (le fil reste `type:string`). Évite le piège de l'ISO partielle
@@ -2579,9 +2593,14 @@ export declare class BaseEntity<TServerData = any> {
2579
2593
  * const page = await org.searchEventsCostum({ startDateUTC: debut, endDateUTC: new Date("2026-06-30T23:59:59Z") });
2580
2594
  * page.results.forEach((e) => console.log(e.serverData.name, e.serverData.startDateSort));
2581
2595
  *
2582
- // Mode LISTE — flux paginé (ponctuels, du plus récent)
2583
- * let p = await org.searchEventsCostum({ indexStep: 20 });
2596
+ // Mode LISTE — les prochains à partir de maintenant (en cours compris), une ligne par récurrent
2597
+ * const now = new Date(); // ancre figée, rejouée par next()
2598
+ * let p = await org.searchEventsCostum({ indexStep: 20, from: now, order: "asc" });
2599
+ * p.results.forEach((e) => console.log(e.serverData.startDateSortFormat, e.serverData.endDateSortFormat));
2584
2600
  * if (p.hasNext) p = await p.next();
2601
+ *
2602
+ // Mode LISTE — les passés, du plus récent, sans récurrent
2603
+ * const passes = await org.searchEventsCostum({ indexStep: 20, to: now, order: "desc", recurrency: false });
2585
2604
  */
2586
2605
  searchEventsCostum(data?: SearchEventsCostumInput, options?: {
2587
2606
  restoredState?: PaginatorState;
@@ -1,5 +1,5 @@
1
1
  import type ApiClient from "../ApiClient.js";
2
- import type { DocumentListData, PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, PasswordResetData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, RelaunchInvitationData, ContactSendData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GlobalAutocompleteAdminCostumData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetUserEligiblePlacesData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, CreateInvitationLinkData, ConnectByRefData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, SearchEventsCostumData, ShareEventsData, InviteMembersData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, NavigatorGettlData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, GetCoformByIdData, CoformUploadAnswerFileData, DeleteCoformAnswerFileData, CoformGetAnswerFilesData, GetCoformCatalogsData, SaveCoformAnswerData, GetCoformAnswerHistoryData, GetCoformMultievalDataData, GetCoformCommontableContributorsData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData, DeleteDocumentByIdData, DemoteAdminData, CostumFilterCoformData, CostumFilterCoformByPathData, GetCountriesData, SearchZonesData, CoformAnswersByFormsData, CostumToolsCatalogData, CostumToolUsersData, CostumCommunInfoData, CostumSaveToolEnrichmentData, CostumCommunListData, GenerateAnswerFromFormData, FundingEnvelopeData, CoremuOperationData, CostumProjectActionRequestNewData, CostumProjectActionRequestSetStatusData, CostumProjectActionRequestSetDateData, CostumProjectActionRequestSetContributorsData, CostumProjectActionRequestCancelData, CostumProjectActionRequestArchiveData, LinkDiscourseAccountData, UnlinkDiscourseAccountData, DiscourseProfileData, DiscourseCheckEmailData, DiscourseDismissLinkData, LinkMediawikiAccountData, UnlinkMediawikiAccountData, GetMediawikiContributionsData, AddClassifiedData, PersonActivateData, PersonValidateInvitationData, ValidateInvitationByMailData, ImportPreviewData, ExportElementsData, ImportElementsData, GeocodageData, ValidateGroupData, SetSourceData, TransferSourceCheckData, TransferSourceApplyData, TransferSourceRollbackData, TransferSourceHistoryData, ModerateData, NewsModerateData, CommentModerateData, UploadDocumentData, ZoneGetShapeData, ZoneGetZonirisData, CostumListValuesData, CostumResolvedData, DirectoryProposalData, DirectoryProposalCountData, DirectoryProposalNewCounterData } from "./EndpointApi.types.js";
2
+ import type { DocumentListData, PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, PasswordResetData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, RelaunchInvitationData, ContactSendData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GlobalAutocompleteAdminCostumData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetUserEligiblePlacesData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, CreateInvitationLinkData, ConnectByRefData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, SearchEventsCostumData, ShareEventsData, InviteMembersData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, NavigatorGettlData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, GetCoformByIdData, CoformUploadAnswerFileData, DeleteCoformAnswerFileData, CoformGetAnswerFilesData, GetCoformCatalogsData, SaveCoformAnswerData, GetCoformAnswerHistoryData, GetCoformMultievalDataData, GetCoformCommontableContributorsData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData, DeleteDocumentByIdData, DemoteAdminData, CostumFilterCoformData, CostumFilterCoformByPathData, GetCountriesData, SearchZonesData, CoformAnswersByFormsData, CostumToolsCatalogData, CostumToolUsersData, CostumCommunInfoData, CostumSaveToolEnrichmentData, CostumCommunListData, GenerateAnswerFromFormData, GenerateProjectFromAnswerData, GenerateMilestoneFromDepenseData, FundingEnvelopeData, CoremuOperationData, CostumProjectActionRequestNewData, CostumProjectActionRequestSetStatusData, CostumProjectActionRequestSetDateData, CostumProjectActionRequestSetContributorsData, CostumProjectActionRequestCancelData, CostumProjectActionRequestArchiveData, LinkDiscourseAccountData, UnlinkDiscourseAccountData, DiscourseProfileData, DiscourseCheckEmailData, DiscourseDismissLinkData, LinkMediawikiAccountData, UnlinkMediawikiAccountData, GetMediawikiContributionsData, AddClassifiedData, PersonActivateData, PersonValidateInvitationData, ValidateInvitationByMailData, ImportPreviewData, ExportElementsData, ImportElementsData, GeocodageData, ValidateGroupData, SetSourceData, TransferSourceCheckData, TransferSourceApplyData, TransferSourceRollbackData, TransferSourceHistoryData, ModerateData, NewsModerateData, CommentModerateData, UploadDocumentData, ZoneGetShapeData, ZoneGetZonirisData, CostumListValuesData, CostumResolvedData, DirectoryProposalData, DirectoryProposalCountData, DirectoryProposalNewCounterData } from "./EndpointApi.types.js";
3
3
  /**
4
4
  * Classe EndpointApi générée automatiquement depuis endpoints-copie.json
5
5
  */
@@ -260,7 +260,7 @@ export declare class EndpointApi {
260
260
  */
261
261
  relaunchInvitation(data: RelaunchInvitationData): Promise<any>;
262
262
  /**
263
- * Envoyer un message depuis un formulaire de contact public : Programme un mail 'contactForm' vers l'adresse d'administration du costum, depuis un formulaire de contact public — pendant du bloc CMS legacy 'contact' (modules/costum/views/tpls/blockCms/contact/*.php, qui postent tous sur cette route). Envoi ASYNCHRONE : le message est mis dans la file cron (Mail::schedule), pas expédié dans la requête. ⚠ Le DESTINATAIRE n'est PAS un paramètre : il est résolu SERVEUR depuis costum.admin.email (Mail.php:1891-1893, costum résolu par costumSlug — CacheHelper.php:73-76). Le contrat interdit donc tplMail/to/fromMail (additionalProperties:false) : la route legacy sous-jacente accepte un destinataire arbitraire sans aucune authentification (webhook Mailgun jamais implémenté, MailmanagementController.php:18-26) — ce contrat n'en expose QUE l'usage 'formulaire de contact'. ⚠ Si costum.admin.email est absent, le legacy retombe en cascade sur to puis replyTo, c'est-à-dire qu'il renvoie le message à SON PROPRE EXPÉDITEUR : vérifier que le costum porte bien cette adresse avant de brancher un formulaire. Le port Node, lui, REFUSE dans ce cas (et durcit : tpl en liste blanche, destinataire serveur, anti-abus par IP et par costum, longueurs bornées) — même esprit que RELAUNCH_INVITATION.
263
+ * Envoyer un message depuis un formulaire de contact public : Programme un mail 'contactForm' vers l'adresse d'administration du costum, depuis un formulaire de contact public — pendant du bloc CMS legacy 'contact' (modules/costum/views/tpls/blockCms/contact/*.php, qui postent tous sur cette route). Envoi ASYNCHRONE : le message est mis dans la file cron (Mail::schedule), pas expédié dans la requête. ⚠ Le ou les DESTINATAIRES ne sont PAS des paramètres : ils sont résolus SERVEUR, dans l'ordre de priorité du legacy — `costum.contactMail` d'abord, `costum.admin.email` seulement en repli (contactForm.php:606 ; costum résolu par costumSlug — CacheHelper.php:73-76). `contactMail` peut porter PLUSIEURS adresses, et chacune reçoit alors son propre mail, comme Mail::createAndSend qui éclate un tableau ou une chaîne à virgules (Mail.php:1901-1916) — cas réel : sportSanteBienetre en déclare deux quand son admin.email n'en porte qu'une. Le contrat interdit donc tplMail/to/fromMail (additionalProperties:false) : la route legacy sous-jacente accepte un destinataire arbitraire sans aucune authentification (webhook Mailgun jamais implémenté, MailmanagementController.php:18-26) — ce contrat n'en expose QUE l'usage 'formulaire de contact'. ⚠ Si ni contactMail ni admin.email ne sont configurés, le legacy retombe en cascade sur to puis replyTo, c'est-à-dire qu'il renvoie le message à SON PROPRE EXPÉDITEUR : vérifier que le costum porte bien une adresse avant de brancher un formulaire. Le port Node, lui, REFUSE dans ce cas (et durcit : tpl en liste blanche, destinataire serveur, anti-abus par IP et par costum, longueurs bornées) — même esprit que RELAUNCH_INVITATION.
264
264
  * Constant : CONTACT_SEND
265
265
  * @param data - Données envoyées à l'API
266
266
  * @returns Les données de réponse.
@@ -1333,6 +1333,26 @@ export declare class EndpointApi {
1333
1333
  * @throws {Error} - En cas d'erreur inattendue.
1334
1334
  */
1335
1335
  generateAnswerFromForm(data: GenerateAnswerFromFormData): Promise<any>;
1336
+ /**
1337
+ * Générer un projet à partir d'une réponse AAP : Promeut une réponse (Answer) AAP en Project + Room à partir du mapping du form de config (proposition/description/dépenses). Contrôleur : modules/survey/controllers/ocecoform/GenerateprojectAction.php:16-113 (mappé par FormController.php action 'generateproject'). Auth bearer obligatoire : Answer::GenerateProjectFromAnswer (Answer.php:625-767) pose Yii::app()->session['userId'] comme creator/idUserAuthor, et notifySwitchToProject (GenerateprojectAction.php:115-148) lit Yii::app()->session['userId'/'user'] pour la notification PROPOSAL_TO_PROJECT — ne fonctionne pas en session anonyme.
1338
+ * Constant : GENERATE_PROJECT_FROM_ANSWER
1339
+ * @param data - Données envoyées à l'API
1340
+ * @returns Les données de réponse.
1341
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1342
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1343
+ * @throws {Error} - En cas d'erreur inattendue.
1344
+ */
1345
+ generateProjectFromAnswer(data: GenerateProjectFromAnswerData): Promise<any>;
1346
+ /**
1347
+ * Générer un milestone projet à partir d'une dépense de réponse : Sync answer→project pour UNE dépense : si answers.aapStep1.depense[depid] n'a pas encore de milestone, en crée un sur project.oceco.milestones ET pose depense[depid].milestone, atomiquement côté serveur (idempotent — no-op si déjà lié). Contrôleur : modules/survey/controllers/ocecoform/DepenseMilestoneOperationAction.php:12-68 (mappé par FormController.php, action 'depensemilestoneoperation'), délègue à Answer::generateMilestonneFromDepense (Answer.php, cf. GenerateprojectAction qui l'appelle aussi en boucle après une génération de projet). Seule l'action 'generateMilestone' est modélisée ici — l'endpoint PHP supporte aussi 'closeMilestone' (réponse de forme différente, hors scope). auth bearer par prudence (mutation projet/financement) bien que ni l'action ni generateMilestonneFromDepense ne lisent Yii::app()->session (contrairement à GenerateprojectAction).
1348
+ * Constant : GENERATE_MILESTONE_FROM_DEPENSE
1349
+ * @param data - Données envoyées à l'API
1350
+ * @returns Les données de réponse.
1351
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1352
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
1353
+ * @throws {Error} - En cas d'erreur inattendue.
1354
+ */
1355
+ generateMilestoneFromDepense(data: GenerateMilestoneFromDepenseData): Promise<any>;
1336
1356
  /**
1337
1357
  * Trouver les informations sur les enveloppes d’un formulaire : Trouver les informations sur les enveloppes d’un formulaire
1338
1358
  * Constant : FUNDING_ENVELOPE
@@ -344,6 +344,14 @@ export interface UpdateBlockLocalityData {
344
344
  * Nom de l'EPCI. Peut être vide.
345
345
  */
346
346
  level5Name?: string;
347
+ /**
348
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
349
+ */
350
+ zoniris?: string;
351
+ /**
352
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
353
+ */
354
+ zonirisId?: string;
347
355
  postalCode?: string;
348
356
  streetAddress?: string;
349
357
  };
@@ -518,7 +526,7 @@ export interface RelaunchInvitationData {
518
526
  }
519
527
  export interface ContactSendData {
520
528
  /**
521
- * Slug du costum porteur — SEUL déterminant du destinataire (costum.admin.email).
529
+ * Slug du costum porteur — SEUL déterminant des destinataires (costum.contactMail, à défaut costum.admin.email).
522
530
  */
523
531
  costumSlug: string;
524
532
  /**
@@ -3034,6 +3042,14 @@ export interface AddOrganizationData {
3034
3042
  * Nom de l'EPCI. Peut être vide.
3035
3043
  */
3036
3044
  level5Name?: string;
3045
+ /**
3046
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
3047
+ */
3048
+ zoniris?: string;
3049
+ /**
3050
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
3051
+ */
3052
+ zonirisId?: string;
3037
3053
  postalCode?: string;
3038
3054
  streetAddress?: string;
3039
3055
  };
@@ -3335,6 +3351,14 @@ export interface AddProjectData {
3335
3351
  * Nom de l'EPCI. Peut être vide.
3336
3352
  */
3337
3353
  level5Name?: string;
3354
+ /**
3355
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
3356
+ */
3357
+ zoniris?: string;
3358
+ /**
3359
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
3360
+ */
3361
+ zonirisId?: string;
3338
3362
  postalCode?: string;
3339
3363
  streetAddress?: string;
3340
3364
  };
@@ -3475,6 +3499,14 @@ export interface AddPoiData {
3475
3499
  * Nom de l'EPCI. Peut être vide.
3476
3500
  */
3477
3501
  level5Name?: string;
3502
+ /**
3503
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
3504
+ */
3505
+ zoniris?: string;
3506
+ /**
3507
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
3508
+ */
3509
+ zonirisId?: string;
3478
3510
  postalCode?: string;
3479
3511
  streetAddress?: string;
3480
3512
  };
@@ -3785,6 +3817,14 @@ export interface AddEventData {
3785
3817
  * Nom de l'EPCI. Peut être vide.
3786
3818
  */
3787
3819
  level5Name?: string;
3820
+ /**
3821
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
3822
+ */
3823
+ zoniris?: string;
3824
+ /**
3825
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
3826
+ */
3827
+ zonirisId?: string;
3788
3828
  postalCode?: string;
3789
3829
  streetAddress?: string;
3790
3830
  };
@@ -4160,9 +4200,21 @@ export interface GetEventsData {
4160
4200
  countType?: unknown[];
4161
4201
  fediverse: boolean;
4162
4202
  /**
4163
- * GARDE PARITÉ legacy (identique à SEARCH_EVENTS_COSTUM) : seule valeur autorisée `false` (= exclure les récurrents) OU champ omis (= inclure, défaut). NE JAMAIS envoyer `true` — le legacy teste STRICTEMENT $recurrency === true (AgendaAction.php:65) qui échoue sur la string POST → exclut les récurrents, alors que notre backend les inclurait (divergence assumée). En interdisant `true`, omis→inclus et false→exclus se comportent pareil sur les 2 serveurs.
4203
+ * Inclure les événements récurrents (openingHours). Omis = inclure. `false` = exclure : en mode LISTE la requête des récurrents est sautée (comme avant 14c2caa1), en mode CALENDRIER les clauses openingHours.dayOfWeek ne sont pas posées. Depuis le 2026-09-04 le legacy parse la valeur en booléen (filter_var FILTER_VALIDATE_BOOLEAN) et le backend Node fait de même : `true`/`false` sont fiables sur les 2 serveurs (byte-parité prouvée). Historique : `=== true` strict (BUG-L-031, `true` excluait), puis truthy 14c2caa1 (la chaîne "false" INCLUAIT, BUG-L-259).
4204
+ */
4205
+ recurrency?: boolean;
4206
+ /**
4207
+ * Mode LISTE seulement (sans startDateUTC/endDateUTC). Borne basse « pas encore terminé à from » : ponctuels endDate ≥ from (sinon startDate ≥ from, un multi-jours en cours reste servi) ; récurrents : prochaine occurrence calculée DEPUIS from au lieu de maintenant (un créneau en cours reste « la prochaine »). Sert d'ANCRE de pagination : renvoyer la même valeur à chaque page (sinon la clé de tri des récurrents bouge entre deux pages). Dès que `from`, `to` ou `order` est présent, chaque ligne porte `endDateSortFormat`. Envoyer un ISO 8601 AVEC offset (toISOString) : une date nue est lue en Europe/Paris par le legacy et en UTC par le backend Node.
4208
+ */
4209
+ from?: string;
4210
+ /**
4211
+ * Mode LISTE seulement. Borne haute STRICTE sur la clé d'occurrence : ponctuels startDate < to ; récurrents prochaine occurrence < to. Même règle d'offset que `from`. « Les passés » = `to` = maintenant + `order` = desc + `recurrency` = false.
4164
4212
  */
4165
- recurrency?: false;
4213
+ to?: string;
4214
+ /**
4215
+ * Mode LISTE seulement — PAS de default déclaré : la lib injecte les defaults du contrat dans la requête, et la seule présence d'`order` déclenche le mode borné (endDateSortFormat). Défaut serveur : desc. Sens du tri sur la clé d'occurrence (startDateSort), départage _id dans le même sens ; la requête des ponctuels suit le même sens (top-K juste). « Les prochains à partir de maintenant » = `from` = maintenant + `order` = asc. Sans `from`/`to`/`order`, requête ET réponse sont strictement celles d'avant (DESC non borné, aucune clé nouvelle).
4216
+ */
4217
+ order?: "asc" | "desc";
4166
4218
  filters?: {
4167
4219
  $or: {};
4168
4220
  [k: string]: unknown;
@@ -4205,9 +4257,21 @@ export interface SearchEventsCostumData {
4205
4257
  countType?: unknown[];
4206
4258
  fediverse: boolean;
4207
4259
  /**
4208
- * GARDE PARITÉ legacy : seule valeur autorisée `false` (= exclure les récurrents) OU champ omis (= inclure, défaut). NE JAMAIS envoyer `true` — le legacy teste STRICTEMENT $recurrency === true (AgendaAction.php:65) qui échoue sur la string POST → exclut les récurrents, alors que notre backend les inclurait (divergence assumée). En interdisant `true`, omis→inclus et false→exclus se comportent pareil sur les 2 serveurs.
4260
+ * Inclure les événements récurrents (openingHours). Omis = inclure. `false` = exclure : en mode LISTE la requête des récurrents est sautée (comme avant 14c2caa1), en mode CALENDRIER les clauses openingHours.dayOfWeek ne sont pas posées. Depuis le 2026-09-04 le legacy parse la valeur en booléen (filter_var FILTER_VALIDATE_BOOLEAN) et le backend Node fait de même : `true`/`false` sont fiables sur les 2 serveurs (byte-parité prouvée). Historique : `=== true` strict (BUG-L-031, `true` excluait), puis truthy 14c2caa1 (la chaîne "false" INCLUAIT, BUG-L-259).
4261
+ */
4262
+ recurrency?: boolean;
4263
+ /**
4264
+ * Mode LISTE seulement (sans startDateUTC/endDateUTC). Borne basse « pas encore terminé à from » : ponctuels endDate ≥ from (sinon startDate ≥ from, un multi-jours en cours reste servi) ; récurrents : prochaine occurrence calculée DEPUIS from au lieu de maintenant (un créneau en cours reste « la prochaine »). Sert d'ANCRE de pagination : renvoyer la même valeur à chaque page (sinon la clé de tri des récurrents bouge entre deux pages). Dès que `from`, `to` ou `order` est présent, chaque ligne porte `endDateSortFormat`. Envoyer un ISO 8601 AVEC offset (toISOString) : une date nue est lue en Europe/Paris par le legacy et en UTC par le backend Node.
4265
+ */
4266
+ from?: string;
4267
+ /**
4268
+ * Mode LISTE seulement. Borne haute STRICTE sur la clé d'occurrence : ponctuels startDate < to ; récurrents prochaine occurrence < to. Même règle d'offset que `from`. « Les passés » = `to` = maintenant + `order` = desc + `recurrency` = false.
4269
+ */
4270
+ to?: string;
4271
+ /**
4272
+ * Mode LISTE seulement — PAS de default déclaré : la lib injecte les defaults du contrat dans la requête, et la seule présence d'`order` déclenche le mode borné (endDateSortFormat). Défaut serveur : desc. Sens du tri sur la clé d'occurrence (startDateSort), départage _id dans le même sens ; la requête des ponctuels suit le même sens (top-K juste). « Les prochains à partir de maintenant » = `from` = maintenant + `order` = asc. Sans `from`/`to`/`order`, requête ET réponse sont strictement celles d'avant (DESC non borné, aucune clé nouvelle).
4209
4273
  */
4210
- recurrency?: false;
4274
+ order?: "asc" | "desc";
4211
4275
  /**
4212
4276
  * Filtres Mongo additionnels (buildFilters).
4213
4277
  */
@@ -6164,6 +6228,39 @@ export interface GenerateAnswerFromFormData {
6164
6228
  };
6165
6229
  [k: string]: unknown;
6166
6230
  }
6231
+ export interface GenerateProjectFromAnswerData {
6232
+ pathParams?: {
6233
+ /**
6234
+ * ID de la réponse (collection answers) à promouvoir en projet. Vide → {success:0, content:'Empty answer id'} (GenerateprojectAction.php:17-21).
6235
+ */
6236
+ answerId: string;
6237
+ /**
6238
+ * ID de l'entité parente (costum.contextId legacy) sous laquelle le projet est rattaché (GenerateprojectAction.php:40-46).
6239
+ */
6240
+ parentId: string;
6241
+ /**
6242
+ * Type de l'entité parente (costum.contextType legacy, ex: 'organizations') (GenerateprojectAction.php:40-46).
6243
+ */
6244
+ parentType: string;
6245
+ [k: string]: unknown;
6246
+ };
6247
+ [k: string]: unknown;
6248
+ }
6249
+ export interface GenerateMilestoneFromDepenseData {
6250
+ /**
6251
+ * ID de la réponse (collection answers) portant la dépense. Vide → {success:0, content:'Empty answer id'} (DepenseMilestoneOperationAction.php:23-27). Sans project.id déjà posé sur l'answer → {success:0, content:"Don't have a project"} (:29-33) — cet endpoint est conçu pour être appelé APRÈS association/génération d'un projet, jamais avant.
6252
+ */
6253
+ answerId: string;
6254
+ /**
6255
+ * Clé (index) de la dépense dans answers.aapStep1.depense[] — PAS un id Mongo. Une clé qui ne matche aucune entrée du tableau ne déclenche pas d'erreur : la réponse reste {success:1} avec milestoneId vide (DepenseMilestoneOperationAction.php:39-43, $milestoneId non réaffecté dans ce cas).
6256
+ */
6257
+ depid: string;
6258
+ /**
6259
+ * Seule valeur modélisée par ce contrat (DepenseMilestoneOperationAction.php:36-50). Une valeur non reconnue, ou un answer sans aucune dépense, retombe sur le fallback {error:0} (:66, $args initial jamais modifié).
6260
+ */
6261
+ action: "generateMilestone";
6262
+ [k: string]: unknown;
6263
+ }
6167
6264
  export interface FundingEnvelopeData {
6168
6265
  /**
6169
6266
  * ID du contexte de l’entité
@@ -6244,7 +6341,7 @@ export interface CostumProjectActionRequestNewData {
6244
6341
  */
6245
6342
  milestone?: {
6246
6343
  /**
6247
- * ID du jalon associé
6344
+ * ID du jalon (project.oceco.milestones[].milestoneId) — chaîne LIBRE, aucun format garanti : ObjectId 24 hex (créé côté client via generateMilestoneId), uniqid() PHP 13 hex (Answer::generateMilestonneFromDepense, boucle de GenerateprojectAction sur les dépenses d'une réponse AAC promue en projet), ou identifiants legacy non-hex. Le backend ActionAction::run() case 'new' ne valide pas le format ; la seule vérif d'existence est Project.hasMilestone (appartenance à oceco.milestones[]).
6248
6345
  */
6249
6346
  milestoneId: string;
6250
6347
  /**
@@ -6568,6 +6665,14 @@ export interface AddClassifiedData {
6568
6665
  level4Name?: string;
6569
6666
  level5?: string;
6570
6667
  level5Name?: string;
6668
+ /**
6669
+ * NOM du decoupage infra-communal qui CONTIENT le point : bassin de vie, grand quartier, IRIS — tel que stocke dans `zoniris.name` (collection lue par `/co2/zone/getzoniris`). Ne se saisit pas : il est pose par calcul geometrique ($geoWithin du `geoPosition` dans le `geoShape` du contour, cf. `/co2/zone/associatezoniris`). C'est la valeur que filtrent les sites — `filters: {"address.zoniris": "Guillaume"}`, ou `$in` pour plusieurs bassins — et celle qu'emet une carte de contours cliquables. AUCUN rapport avec la chaine `levelN`, qui s'arrete a l'EPCI (level5) : `zoniris` descend SOUS la commune. Peut etre vide.
6670
+ */
6671
+ zoniris?: string;
6672
+ /**
6673
+ * `_id` (24 hex, en STRING) du document `zoniris` designe par `zoniris`. Meme role que `localityId` face a `addressLocality` : il survit au renommage d'un contour et permet a l'association de reconnaitre ses propres ecritures lors d'un rejeu. Peut etre vide.
6674
+ */
6675
+ zonirisId?: string;
6571
6676
  postalCode?: string;
6572
6677
  streetAddress?: string;
6573
6678
  };
@@ -0,0 +1,3 @@
1
+ import type { CostumExtensionModule } from "../types.js";
2
+ declare const mod: CostumExtensionModule;
3
+ export default mod;
@@ -1,4 +1,4 @@
1
- export type KnownCostumSlug = "CercleTravailleursSociauxLiberauxLaPlumeSociale" | "FabEn" | "LaReunionDesTiersLieux" | "LivingLabInnovationSocialeBraspanon" | "RoseLab" | "Santeentransition" | "alfph" | "ambitionTiersLieuxValDeLoire" | "assoKosasa" | "boclLe" | "bretagneTierslieux" | "caDuBassinDeThauTiersLieux" | "caDuBassinDeThauTiersLieux1" | "campagne" | "capTierslieux" | "catalyst" | "ccDesCaussesALaubracTiersLieux" | "chtitube" | "circuitCourt" | "cmcasHB" | "cmcasHauteBretagne" | "coFinancementTierslieux" | "coeurNumerique" | "communLundi" | "consortiumIledefranceTierslieux" | "copHautsdefrance" | "createchFablabDeLaMjcDeSaintjean" | "cressDeLaReunion1" | "cressReunion" | "cressReunionNetwork" | "ctenat" | "cyberReunion" | "daLocu" | "ecocentre" | "ekisphere" | "equipementsSportifs974" | "fabLimagne" | "fabdulys1" | "fablab3dplant" | "fablabChauxdefonds" | "federationDesCae" | "fianarantsoaAlimentation" | "formationGenerique" | "franceTierslieux" | "heraultTiersLieux" | "hinaura" | "hubmayotte" | "hubnouvellecaledonie" | "hubpolynesiefrancaise" | "hubreunion" | "hubterritoires" | "hubwallisetfutuna" | "hva" | "ibv2" | "institutBleu" | "journalInsoumisChambery" | "kpacite" | "laCompagnieDesTierslieux" | "laCooperativeTierslieux" | "laMaisonDesFaiseurs" | "laMinoterie1" | "laMyne" | "laReunionPourUnNumeriqueInclusif" | "laRosee" | "laSemaineDesTierslieux" | "laTresseTierslieu" | "labEnCommuns" | "labboite" | "lakou" | "lapossession" | "lattesTiersLieux" | "leFaugaTiersLieux" | "leTamponTiersLieux" | "lesCommunsDesTierslieux" | "lesImaginationsFertiles" | "lidairesTiersLieux" | "littoralHautsDeFrance" | "lotetgaronneTiersLieux" | "mayottePourUnNumeriqueInclusif" | "meir" | "montpellierMediterraneeMetropoleTiersLieux" | "montpellierTiersLieux" | "navigatorDesTierslieux" | "notragora" | "nouvellecaledoniePourUnNumeriqueInclusif" | "openAtlas" | "parent62" | "polynesieFrancaisePourUnNumeriqueInclusif" | "prdr" | "pyreneesatlantiquesTiersLieux" | "redlab" | "relief" | "reseauDesTierslieuxDeGuyane" | "reseauDesTierslieuxDeMayotte" | "reseauDesTierslieuxDuGrandEst" | "reseauNormandDesTierslieux" | "reseauRegionalDesTierslieuxGuadeloupe" | "reseauRegionalDesTierslieuxMartinique" | "reseauTierslieux" | "rfflabs" | "ries" | "sLieux" | "saintJosephTiersLieux" | "saintbenoitTiersLieux" | "saintbenoitTiersLieux1" | "saintbenoitTiersLieux2" | "saintpaulSport1" | "saintpaulTiersLieux" | "saintpierreTiersLieux" | "savoieTiersLieux" | "siteDuPactePourLaTransition" | "sportSanteBienetre" | "sudTierslieux" | "suppa" | "terramies" | "testeTplFormation" | "tiersLieuxGenerique" | "tierslieuxBfc" | "tierslieuxbelgique" | "tierslieuxorg" | "tierslieuxorg1" | "transiter" | "vhelioPeiTour2025" | "wallisetfutunaPourUnNumeriqueInclusif";
1
+ export type KnownCostumSlug = "CercleTravailleursSociauxLiberauxLaPlumeSociale" | "FabEn" | "LaReunionDesTiersLieux" | "LivingLabInnovationSocialeBraspanon" | "RoseLab" | "Santeentransition" | "alfph" | "ambitionTiersLieuxValDeLoire" | "assoKosasa" | "associationEkilibre" | "boclLe" | "bretagneTierslieux" | "caDuBassinDeThauTiersLieux" | "caDuBassinDeThauTiersLieux1" | "campagne" | "capTierslieux" | "catalyst" | "ccDesCaussesALaubracTiersLieux" | "chtitube" | "circuitCourt" | "cmcasHB" | "cmcasHauteBretagne" | "coFinancementTierslieux" | "coeurNumerique" | "communLundi" | "consortiumIledefranceTierslieux" | "copHautsdefrance" | "createchFablabDeLaMjcDeSaintjean" | "cressDeLaReunion1" | "cressReunion" | "cressReunionNetwork" | "ctenat" | "cyberReunion" | "daLocu" | "ecocentre" | "ekisphere" | "equipementsSportifs974" | "fabLimagne" | "fabdulys1" | "fablab3dplant" | "fablabChauxdefonds" | "federationDesCae" | "fianarantsoaAlimentation" | "formationGenerique" | "franceTierslieux" | "heraultTiersLieux" | "hinaura" | "hubmayotte" | "hubnouvellecaledonie" | "hubpolynesiefrancaise" | "hubreunion" | "hubterritoires" | "hubwallisetfutuna" | "hva" | "ibv2" | "institutBleu" | "journalInsoumisChambery" | "kpacite" | "laCompagnieDesTierslieux" | "laCooperativeTierslieux" | "laMaisonDesFaiseurs" | "laMinoterie1" | "laMyne" | "laReunionPourUnNumeriqueInclusif" | "laRosee" | "laSemaineDesTierslieux" | "laTresseTierslieu" | "labEnCommuns" | "labboite" | "lakou" | "lapossession" | "lattesTiersLieux" | "leFaugaTiersLieux" | "leTamponTiersLieux" | "lesCommunsDesTierslieux" | "lesImaginationsFertiles" | "lidairesTiersLieux" | "littoralHautsDeFrance" | "lotetgaronneTiersLieux" | "mayottePourUnNumeriqueInclusif" | "meir" | "montpellierMediterraneeMetropoleTiersLieux" | "montpellierTiersLieux" | "navigatorDesTierslieux" | "notragora" | "nouvellecaledoniePourUnNumeriqueInclusif" | "openAtlas" | "parent62" | "polynesieFrancaisePourUnNumeriqueInclusif" | "prdr" | "pyreneesatlantiquesTiersLieux" | "redlab" | "relief" | "reseauDesTierslieuxDeGuyane" | "reseauDesTierslieuxDeMayotte" | "reseauDesTierslieuxDuGrandEst" | "reseauNormandDesTierslieux" | "reseauRegionalDesTierslieuxGuadeloupe" | "reseauRegionalDesTierslieuxMartinique" | "reseauTierslieux" | "rfflabs" | "ries" | "sLieux" | "saintJosephTiersLieux" | "saintbenoitTiersLieux" | "saintbenoitTiersLieux1" | "saintbenoitTiersLieux2" | "saintpaulSport1" | "saintpaulTiersLieux" | "saintpierreTiersLieux" | "savoieTiersLieux" | "siteDuPactePourLaTransition" | "sportSanteBienetre" | "sudTierslieux" | "suppa" | "terramies" | "testeTplFormation" | "tiersLieuxGenerique" | "tierslieuxBfc" | "tierslieuxbelgique" | "tierslieuxorg" | "tierslieuxorg1" | "transiter" | "vhelioPeiTour2025" | "wallisetfutunaPourUnNumeriqueInclusif";
2
2
  export type Collection = "addPhoto" | "badges" | "classifieds" | "crowdfunding" | "events" | "organizations" | "person" | "poi" | "projects" | "proposal" | "ressources";
3
3
  export interface CostumExtensionField {
4
4
  name: string;
@@ -143,6 +143,57 @@ export interface CostumFieldMap {
143
143
  image?: string;
144
144
  };
145
145
  };
146
+ associationEkilibre: {
147
+ organizations: {
148
+ affiliate?: string | boolean;
149
+ affiliateTo?: string;
150
+ autreDescription?: string;
151
+ formLocality?: string;
152
+ image?: string;
153
+ infoGeneral?: Record<string, unknown>;
154
+ legalStatus?: string | string[];
155
+ link?: string;
156
+ linkedin?: string;
157
+ location?: string;
158
+ mobile?: string;
159
+ otherPersonInChargeTitle?: string;
160
+ otherRepresentativeTitle?: string;
161
+ personInChargeCivility?: string | string[];
162
+ personInChargeEmail?: string;
163
+ personInChargeFirstName?: string;
164
+ personInChargeName?: string;
165
+ personInChargeTelephone?: string | number;
166
+ personInChargeTitle?: "Président" | "Maire.sse" | "Chef.fe d'entreprise" | "Chef.fe d'établissement" | "Autre...";
167
+ representativeCivility?: string | string[];
168
+ representativeEmail?: string;
169
+ representativeFirstName?: string;
170
+ representativeName?: string;
171
+ representativeTelephone?: string | number;
172
+ representativeTitle?: "Président" | "Maire.sse" | "Chef.fe d'entreprise" | "Chef.fe d'établissement" | "Autre...";
173
+ responsableCivilePro?: Record<string, unknown>;
174
+ responsableSameAsRepresent?: string | boolean;
175
+ sextionInfo?: Record<string, unknown>;
176
+ sextionInfoRepresentant?: Record<string, unknown>;
177
+ sextionInfoResponsable?: Record<string, unknown>;
178
+ sigle?: string;
179
+ similarLink?: Record<string, unknown>;
180
+ siren?: string | number;
181
+ statusActor?: string | string[];
182
+ statusCommunale?: string | string[];
183
+ statusFile?: Record<string, unknown>;
184
+ statusPrimaire?: string | string[];
185
+ statusSecondaire?: string | string[];
186
+ youtube?: string;
187
+ };
188
+ poi: {
189
+ category?: string;
190
+ featured?: string | boolean;
191
+ link?: string;
192
+ publicationDate?: string;
193
+ publicationStatus?: string;
194
+ status?: string | string[];
195
+ };
196
+ };
146
197
  boclLe: {
147
198
  badges: {
148
199
  thematic?: string | string[];