@communecter/cocolight-api-client 1.0.150 → 1.0.152
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.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
- package/package.json +3 -2
- package/src/api/BaseEntity.ts +106 -5
- package/src/api/EndpointApi.ts +16 -1
- package/src/api/EndpointApi.types.ts +293 -202
- package/src/api/User.ts +13 -4
- package/src/api/UserApi.ts +16 -5
- package/src/costum/runtime.ts +65 -12
- package/src/endpoints.module.ts +370 -210
- package/types/api/BaseEntity.d.ts +56 -2
- package/types/api/EndpointApi.d.ts +10 -1
- package/types/api/EndpointApi.types.d.ts +91 -44
- package/types/api/User.d.ts +9 -2
- package/types/api/UserApi.d.ts +7 -1
- package/types/costum/runtime.d.ts +14 -5
- package/types/endpoints.module.d.ts +1634 -1086
package/src/costum/runtime.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { COSTUM_RUNTIME } from "./runtime-map.js";
|
|
|
19
19
|
|
|
20
20
|
import type { CostumExtensionModule, CostumExtensionField, KnownCostumSlug, Collection } from "./types.js";
|
|
21
21
|
import type { BaseEntity } from "../api/BaseEntity.js";
|
|
22
|
+
import type { GetElementsKeyResponse } from "../types/api-responses.js";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Contexte costum résolu, attaché à une instance d'entité via `config.costumCtx`.
|
|
@@ -99,13 +100,13 @@ type ScopeCollection = "poi" | "organizations" | "projects" | "events";
|
|
|
99
100
|
* et n'altère jamais l'état partagé — chaque entité reçoit son propre `_costumCtx`.
|
|
100
101
|
*/
|
|
101
102
|
export class CostumScope {
|
|
102
|
-
readonly slug: KnownCostumSlug;
|
|
103
|
+
readonly slug: KnownCostumSlug | (string & {});
|
|
103
104
|
private readonly user: BaseEntity;
|
|
104
105
|
private readonly module: CostumExtensionModule;
|
|
105
106
|
private readonly costumId: string;
|
|
106
107
|
private readonly costumType: string;
|
|
107
108
|
|
|
108
|
-
constructor(user: BaseEntity, slug: KnownCostumSlug, module: CostumExtensionModule, costumId: string, costumType: string) {
|
|
109
|
+
constructor(user: BaseEntity, slug: KnownCostumSlug | (string & {}), module: CostumExtensionModule, costumId: string, costumType: string) {
|
|
109
110
|
this.user = user;
|
|
110
111
|
this.slug = slug;
|
|
111
112
|
this.module = module;
|
|
@@ -191,8 +192,23 @@ export class CostumScope {
|
|
|
191
192
|
export function resolveCostumCtxFromSource(sourceKey: string | undefined | null, collection: Collection): CostumRuntimeContext | null {
|
|
192
193
|
if (!sourceKey) return null;
|
|
193
194
|
const entry = COSTUM_RUNTIME[sourceKey]?.[collection];
|
|
194
|
-
if (!entry) return null;
|
|
195
195
|
const meta = COSTUM_META[sourceKey as KnownCostumSlug];
|
|
196
|
+
if (!entry) {
|
|
197
|
+
// Pas d'overlay de champs pour (sourceKey, collection). Si le costum est CONNU (meta présent), on
|
|
198
|
+
// reconnaît quand même le scope (source.key = identité) via un ctx NU (fields:[]) — l'élément est
|
|
199
|
+
// rattaché au costum sans champ spécifique. Costum hors registry → null (résolution live = inc1b).
|
|
200
|
+
if (!meta) return null;
|
|
201
|
+
return {
|
|
202
|
+
slug: sourceKey,
|
|
203
|
+
costumId: meta.costumId,
|
|
204
|
+
costumType: meta.costumType,
|
|
205
|
+
collection,
|
|
206
|
+
schema: { type: "object", additionalProperties: true, properties: {} },
|
|
207
|
+
fields: [],
|
|
208
|
+
presets: {},
|
|
209
|
+
hidden: [],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
196
212
|
const props = (entry.schema as { properties?: Record<string, unknown> }).properties ?? {};
|
|
197
213
|
return {
|
|
198
214
|
slug: sourceKey,
|
|
@@ -206,16 +222,53 @@ export function resolveCostumCtxFromSource(sourceKey: string | undefined | null,
|
|
|
206
222
|
};
|
|
207
223
|
}
|
|
208
224
|
|
|
225
|
+
/** Module costum « nu » (scope d'IDENTITÉ sans overlay de champs) : `collections` vide → `create()` no-op. */
|
|
226
|
+
function fieldlessModule(slug: string): CostumExtensionModule {
|
|
227
|
+
return { slug, collections: {} };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Ouvre un scope costum FIELDLESS depuis une entité DÉJÀ CHARGÉE (zéro fetch) : `costumSlug` = slug de
|
|
232
|
+
* l'entité (= `source.key` posé par le backend), `costumId/costumType` = l'entité porteuse. Pendant runtime
|
|
233
|
+
* exact de `_withCostumContext` (BaseEntity), pour la voie « entité tenue » (un site nu sans form). Le
|
|
234
|
+
* backend re-gate `found` sur l'existence d'un costum sur l'entité → un site sans costum n'estampille rien.
|
|
235
|
+
*/
|
|
236
|
+
export function costumScopeFromEntity(user: BaseEntity, entity: BaseEntity): CostumScope {
|
|
237
|
+
const sd = entity.serverData as { slug?: string | null; id?: string | null } | undefined;
|
|
238
|
+
const slug = sd?.slug;
|
|
239
|
+
const id = sd?.id;
|
|
240
|
+
if (typeof slug !== "string" || slug.trim() === "") {
|
|
241
|
+
throw new ApiError("me.costum(entity) : l'entité n'a pas de slug (charge-la d'abord).", 400);
|
|
242
|
+
}
|
|
243
|
+
if (typeof id !== "string" || !id) {
|
|
244
|
+
throw new ApiError("me.costum(entity) : l'entité n'a pas d'id.", 400);
|
|
245
|
+
}
|
|
246
|
+
return new CostumScope(user, slug, fieldlessModule(slug), id, entity.getEntityType());
|
|
247
|
+
}
|
|
248
|
+
|
|
209
249
|
/**
|
|
210
|
-
* Résout un `CostumScope` pour un user connecté.
|
|
211
|
-
*
|
|
250
|
+
* Résout un `CostumScope` par SLUG pour un user connecté.
|
|
251
|
+
* - slug à champs (meta + loader) → charge le module généré (code-split via dynamic import).
|
|
252
|
+
* - slug CONNU sans loader (fieldless) → scope d'identité nu (`collections:{}`).
|
|
253
|
+
* - slug HORS registry → résolution LIVE via `slug/getinfo` (contextId/contextType) → scope nu (tier 3b).
|
|
212
254
|
*/
|
|
213
|
-
export async function resolveCostumScope(user: BaseEntity, slug: KnownCostumSlug): Promise<CostumScope> {
|
|
214
|
-
const meta = COSTUM_META[slug];
|
|
215
|
-
const loader = COSTUM_SCHEMAS[slug];
|
|
216
|
-
if (
|
|
217
|
-
|
|
255
|
+
export async function resolveCostumScope(user: BaseEntity, slug: KnownCostumSlug | (string & {})): Promise<CostumScope> {
|
|
256
|
+
const meta = COSTUM_META[slug as KnownCostumSlug];
|
|
257
|
+
const loader = COSTUM_SCHEMAS[slug as KnownCostumSlug];
|
|
258
|
+
if (meta && loader) {
|
|
259
|
+
const { default: module } = await loader();
|
|
260
|
+
return new CostumScope(user, slug, module, meta.costumId, meta.costumType);
|
|
261
|
+
}
|
|
262
|
+
if (meta) {
|
|
263
|
+
// Connu mais sans overlay de champs : scope d'identité pur (estampille source.key, aucun champ costum).
|
|
264
|
+
return new CostumScope(user, slug, fieldlessModule(slug), meta.costumId, meta.costumType);
|
|
265
|
+
}
|
|
266
|
+
// Tier 3b — slug HORS registry : résolution LIVE slug → {contextId, contextType} via la route `slug/getinfo`
|
|
267
|
+
// (GET_ELEMENTS_KEY, « none »). Couvre les sites fieldless/cold/futurs sans rien bundler. costumSlug = le slug
|
|
268
|
+
// demandé (slug ENTITÉ) ; le backend re-gate `found` sur l'existence d'un costum sur l'entité résolue.
|
|
269
|
+
const info = await user.endpointApi.getElementsKey({ pathParams: { slug } }) as GetElementsKeyResponse;
|
|
270
|
+
if (info?.contextId && info?.contextType) {
|
|
271
|
+
return new CostumScope(user, slug, fieldlessModule(slug), String(info.contextId), String(info.contextType));
|
|
218
272
|
}
|
|
219
|
-
|
|
220
|
-
return new CostumScope(user, slug, module, meta.costumId, meta.costumType);
|
|
273
|
+
throw new ApiError(`Costum inconnu : "${slug}" — slug introuvable (résolution live slug/getinfo).`, 404);
|
|
221
274
|
}
|