@egen-civitas/esm-extensions 2.0.0 → 2.2.0
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/CHANGELOG.md +23 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/public.d.ts +2 -1
- package/dist/public.d.ts.map +1 -1
- package/dist/public.js +2 -1
- package/dist/tool-window-registration.d.ts +24 -0
- package/dist/tool-window-registration.d.ts.map +1 -0
- package/dist/tool-window-registration.js +30 -0
- package/dist/tool-window.d.ts +59 -0
- package/dist/tool-window.d.ts.map +1 -1
- package/dist/tool-window.js +77 -9
- package/package.json +15 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @egen-civitas/esm-extensions
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fa07dbd: Compartiments verticaux dans les zones gauche et droite. Chaque zone devient une pile de compartiments dont les hauteurs (en % de la zone) totalisent toujours 100 : aucun débordement, contenu défilant en interne, redimensionnement libre entre voisins (les autres s'ajustent selon leurs minimum et maximum). La zone actuelle devient le compartiment par défaut (dimensions fixées par le shell) et porte désormais le fond sombre à la place de la zone. Une app choisit, dans la `meta` de son option de rail, d'afficher dans le compartiment par défaut ou dans un compartiment propre via `meta.compartment` (`{ height, minHeight, maxHeight }` en %, valeurs par défaut `DEFAULT_COMPARTMENT_HEIGHTS`). Nouveaux exports : `getToolWindowCompartment`, `DEFAULT_COMPARTMENT_HEIGHTS`, `ToolWindowCompartment`, `closeToolWindow(anchor, id?)` pour fermer un seul compartiment.
|
|
8
|
+
|
|
9
|
+
## 2.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 8a39e13: Rails et zones ouverts aux apps distantes/fédérées : `ToolWindowMeta.iconUrl` (icône personnalisée sûre, rendue en masque monochrome), `getToolWindowMetaProblems` + avertissement précis à l'enregistrement quand une `meta` de rail est invalide (plus d'entrée ignorée en silence), `registerToolWindow` (déclaration par le code, sans `routes.json`), `openToolWindow` (ouverture sans bascule). Guide : `packages/framework/esm-extensions/TOOL-WINDOWS.md`.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [159db44]
|
|
18
|
+
- @egen-civitas/esm-api@2.0.0
|
|
19
|
+
- @egen-civitas/esm-config@2.0.0
|
|
20
|
+
- @egen-civitas/esm-utils@2.0.0
|
|
21
|
+
- @egen-civitas/esm-globals@2.0.0
|
|
22
|
+
- @egen-civitas/esm-translations@1.0.3
|
|
23
|
+
- @egen-civitas/esm-state@1.0.3
|
|
24
|
+
- @egen-civitas/esm-feature-flags@1.0.2
|
|
25
|
+
|
|
3
26
|
## 2.0.0
|
|
4
27
|
|
|
5
28
|
### Major Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './extensions.js';
|
|
|
2
2
|
export * from './helpers.js';
|
|
3
3
|
export * from './nav-entry.js';
|
|
4
4
|
export * from './tool-window.js';
|
|
5
|
+
export * from './tool-window-registration.js';
|
|
5
6
|
export * from './nav-behavior.js';
|
|
6
7
|
export * from './modals.js';
|
|
7
8
|
export * from './workspaces.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./extensions.js";
|
|
|
2
2
|
export * from "./helpers.js";
|
|
3
3
|
export * from "./nav-entry.js";
|
|
4
4
|
export * from "./tool-window.js";
|
|
5
|
+
export * from "./tool-window-registration.js";
|
|
5
6
|
export * from "./nav-behavior.js";
|
|
6
7
|
export * from "./modals.js";
|
|
7
8
|
export * from "./workspaces.js";
|
package/dist/public.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { type ExtensionMeta, type ExtensionRegistration, type ExtensionStore, ty
|
|
|
4
4
|
export { type WorkspaceRegistration } from './workspaces.js';
|
|
5
5
|
export { type ExtensionData, type ComponentConfig } from './types.js';
|
|
6
6
|
export { TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, type NavEntryMeta, isNavEntryMeta, isNavEntryInWorkspace, } from './nav-entry.js';
|
|
7
|
-
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, type ToolWindowAnchor, type ToolWindowMeta, isToolWindowMeta, } from './tool-window.js';
|
|
7
|
+
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, type ToolWindowAnchor, type ToolWindowMeta, isToolWindowMeta, isToolWindowSlot, isSafeToolWindowIconUrl, getToolWindowMetaProblems, getToolWindowCompartment, DEFAULT_COMPARTMENT_HEIGHTS, type ToolWindowCompartment, type ResolvedToolWindowCompartment, } from './tool-window.js';
|
|
8
|
+
export { registerToolWindow, type ToolWindowRegistration } from './tool-window-registration.js';
|
|
8
9
|
export { type NavBehavior, type NavBehaviorTarget, type NavSelectContext, registerNavBehavior, getNavBehavior, } from './nav-behavior.js';
|
|
9
10
|
//# sourceMappingURL=public.d.ts.map
|
package/dist/public.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/public.js
CHANGED
|
@@ -2,5 +2,6 @@ export { getExtensionNameFromId, registerExtension, attach, detach, detachAll, g
|
|
|
2
2
|
export { renderExtension } from "./render.js";
|
|
3
3
|
export { getExtensionStore } from "./store.js";
|
|
4
4
|
export { TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, isNavEntryMeta, isNavEntryInWorkspace } from "./nav-entry.js";
|
|
5
|
-
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, isToolWindowMeta } from "./tool-window.js";
|
|
5
|
+
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, isToolWindowMeta, isToolWindowSlot, isSafeToolWindowIconUrl, getToolWindowMetaProblems, getToolWindowCompartment, DEFAULT_COMPARTMENT_HEIGHTS } from "./tool-window.js";
|
|
6
|
+
export { registerToolWindow } from "./tool-window-registration.js";
|
|
6
7
|
export { registerNavBehavior, getNavBehavior } from "./nav-behavior.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ExtensionRegistration } from './store.js';
|
|
2
|
+
import { type ToolWindowAnchor, type ToolWindowMeta } from './tool-window.js';
|
|
3
|
+
export interface ToolWindowRegistration {
|
|
4
|
+
/** Nom du module (de l'app) qui porte la fenêtre : celui de l'importmap / de la fédération. */
|
|
5
|
+
moduleName: string;
|
|
6
|
+
/** Identifiant unique de la fenêtre d'outils (nom de l'extension). */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Zone dans laquelle le contenu s'ouvre ; détermine le rail (voir `ToolWindowMeta.rail` pour le bas). */
|
|
9
|
+
anchor: ToolWindowAnchor;
|
|
10
|
+
/** Bouton du rail + titre de la zone. */
|
|
11
|
+
meta: ToolWindowMeta;
|
|
12
|
+
/** Chargement du contenu (cycles de vie single-spa), appelé quand la zone s'ouvre. */
|
|
13
|
+
load: ExtensionRegistration['load'];
|
|
14
|
+
privileges?: ExtensionRegistration['privileges'];
|
|
15
|
+
featureFlag?: string;
|
|
16
|
+
displayExpression?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Déclare une fenêtre d'outils par le code, sans `routes.json` : pour une app fédérée ou open source
|
|
20
|
+
* qui s'intègre au shell depuis son point d'entrée. Équivalent exact d'une extension `routes.json` posée
|
|
21
|
+
* sur le slot de rail de la zone. Retourne `false` (et avertit) si la `meta` est invalide.
|
|
22
|
+
*/
|
|
23
|
+
export declare function registerToolWindow(registration: ToolWindowRegistration): boolean;
|
|
24
|
+
//# sourceMappingURL=tool-window-registration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-window-registration.d.ts","sourceRoot":"","sources":["../src/tool-window-registration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IACrC,+FAA+F;IAC/F,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,0GAA0G;IAC1G,MAAM,EAAE,gBAAgB,CAAC;IACzB,yCAAyC;IACzC,IAAI,EAAE,cAAc,CAAC;IACrB,sFAAsF;IACtF,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,sBAAsB,GAAG,OAAO,CA6BhF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** @module @category Extension */ import { attach, registerExtension } from "./extensions.js";
|
|
2
|
+
import { getToolWindowMetaProblems, TOOL_WINDOW_SLOTS } from "./tool-window.js";
|
|
3
|
+
/**
|
|
4
|
+
* Déclare une fenêtre d'outils par le code, sans `routes.json` : pour une app fédérée ou open source
|
|
5
|
+
* qui s'intègre au shell depuis son point d'entrée. Équivalent exact d'une extension `routes.json` posée
|
|
6
|
+
* sur le slot de rail de la zone. Retourne `false` (et avertit) si la `meta` est invalide.
|
|
7
|
+
*/ export function registerToolWindow(registration) {
|
|
8
|
+
const { moduleName, name, anchor, meta, load, privileges, featureFlag, displayExpression } = registration;
|
|
9
|
+
const problems = getToolWindowMetaProblems(meta);
|
|
10
|
+
if (problems.length > 0 || !TOOL_WINDOW_SLOTS[anchor]) {
|
|
11
|
+
console.warn(`[workbench] La fenêtre d'outils « ${name} » de ${moduleName} n'est pas enregistrée : ${problems.join(' ; ') || `zone inconnue « ${String(anchor)} »`}.`);
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (anchor === 'bottom' && meta.compartment && meta.compartment !== 'default') {
|
|
15
|
+
console.warn(`[workbench] La fenêtre d'outils « ${name} » de ${moduleName} : \`compartment\` est ignoré dans la zone basse (zones gauche et droite uniquement).`);
|
|
16
|
+
}
|
|
17
|
+
registerExtension({
|
|
18
|
+
name,
|
|
19
|
+
moduleName,
|
|
20
|
+
load,
|
|
21
|
+
meta,
|
|
22
|
+
privileges,
|
|
23
|
+
featureFlag,
|
|
24
|
+
displayExpression,
|
|
25
|
+
online: true,
|
|
26
|
+
offline: false
|
|
27
|
+
});
|
|
28
|
+
attach(TOOL_WINDOW_SLOTS[anchor], name);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
package/dist/tool-window.d.ts
CHANGED
|
@@ -27,6 +27,28 @@ export declare const SHELL_RAIL_RIGHT_SLOT = "shell-rail-right-slot";
|
|
|
27
27
|
export type ToolWindowAnchor = 'left' | 'bottom' | 'right';
|
|
28
28
|
/** Slot de rail associé à chaque zone. */
|
|
29
29
|
export declare const TOOL_WINDOW_SLOTS: Readonly<Record<ToolWindowAnchor, string>>;
|
|
30
|
+
/**
|
|
31
|
+
* Compartiment propre : bloc vertical redimensionnable d'une zone latérale (gauche ou droite).
|
|
32
|
+
*
|
|
33
|
+
* Une zone latérale est une pile verticale de compartiments dont les hauteurs, exprimées en
|
|
34
|
+
* **pourcentage de la hauteur de la zone**, totalisent toujours 100 : jamais de débordement. Chaque
|
|
35
|
+
* compartiment défile en interne quand son contenu est trop haut, et peut être redimensionné librement
|
|
36
|
+
* (dans ses bornes) face à ses voisins.
|
|
37
|
+
*
|
|
38
|
+
* Toutes les valeurs sont optionnelles : celles qui manquent prennent `DEFAULT_COMPARTMENT_HEIGHTS`.
|
|
39
|
+
*/
|
|
40
|
+
export interface ToolWindowCompartment {
|
|
41
|
+
/** Hauteur de base à l'ouverture, en % de la zone (défaut 40). */
|
|
42
|
+
height?: number;
|
|
43
|
+
/** Hauteur minimale, en % de la zone (défaut 15). */
|
|
44
|
+
minHeight?: number;
|
|
45
|
+
/** Hauteur maximale, en % de la zone (défaut 100). */
|
|
46
|
+
maxHeight?: number;
|
|
47
|
+
}
|
|
48
|
+
/** Hauteurs (en % de la zone) d'un compartiment propre dont l'app n'a pas précisé les valeurs. */
|
|
49
|
+
export declare const DEFAULT_COMPARTMENT_HEIGHTS: Readonly<Required<ToolWindowCompartment>>;
|
|
50
|
+
/** Hauteurs résolues d'un compartiment propre : `minHeight <= height <= maxHeight`, tout dans ]0, 100]. */
|
|
51
|
+
export type ResolvedToolWindowCompartment = Required<ToolWindowCompartment>;
|
|
30
52
|
/** Métadonnées d'une fenêtre d'outils (bouton de rail + titre de zone). */
|
|
31
53
|
export interface ToolWindowMeta {
|
|
32
54
|
/** Titre par défaut : info-bulle du bouton et en-tête de la zone. */
|
|
@@ -35,6 +57,13 @@ export interface ToolWindowMeta {
|
|
|
35
57
|
titleKey?: string;
|
|
36
58
|
/** Nom d'icône lucide (ex. `Users`), résolu par le shell dans une liste blanche. */
|
|
37
59
|
icon?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Icône personnalisée (apps distantes/fédérées qui ne trouvent pas leur bonheur dans la liste
|
|
62
|
+
* blanche) : URL `https://…`, chemin absolu `/…` ou `data:image/svg+xml|png|webp…`. Affichée comme un
|
|
63
|
+
* masque monochrome (elle prend la couleur du rail) : fournir une icône d'une seule teinte. Prioritaire
|
|
64
|
+
* sur `icon`. Jamais injectée comme HTML : aucun script ne peut s'exécuter.
|
|
65
|
+
*/
|
|
66
|
+
iconUrl?: string;
|
|
38
67
|
/** Ordre d'affichage dans le rail (croissant) ; défaut : ordre du slot. */
|
|
39
68
|
order?: number;
|
|
40
69
|
/**
|
|
@@ -49,7 +78,37 @@ export interface ToolWindowMeta {
|
|
|
49
78
|
* qui occupe toute la largeur entre les rails.
|
|
50
79
|
*/
|
|
51
80
|
rail?: 'left' | 'right';
|
|
81
|
+
/**
|
|
82
|
+
* Zones gauche et droite uniquement : où s'affiche le contenu.
|
|
83
|
+
*
|
|
84
|
+
* - `'default'` (ou absent) : dans le **compartiment par défaut** de la zone, partagé avec les autres
|
|
85
|
+
* fenêtres d'outils du rail (une seule y est affichée à la fois). Ses dimensions sont fixées par le
|
|
86
|
+
* shell et ne sont pas modifiables par les apps.
|
|
87
|
+
* - un objet `ToolWindowCompartment` : dans un **compartiment propre**, empilé verticalement sous/sur les
|
|
88
|
+
* autres, ouvert indépendamment du compartiment par défaut. L'app y définit la hauteur de base, le
|
|
89
|
+
* minimum et le maximum (en % de la zone) ; les valeurs omises prennent `DEFAULT_COMPARTMENT_HEIGHTS`.
|
|
90
|
+
*
|
|
91
|
+
* Sans effet sur la zone basse.
|
|
92
|
+
*/
|
|
93
|
+
compartment?: 'default' | ToolWindowCompartment;
|
|
52
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Résout `meta.compartment` : `null` pour le compartiment par défaut, sinon les hauteurs d'un compartiment
|
|
97
|
+
* propre, complétées par `DEFAULT_COMPARTMENT_HEIGHTS` puis rendues cohérentes (`min <= base <= max`).
|
|
98
|
+
*/
|
|
99
|
+
export declare function getToolWindowCompartment(meta: {
|
|
100
|
+
compartment?: unknown;
|
|
101
|
+
}): ResolvedToolWindowCompartment | null;
|
|
102
|
+
/** Vrai si `url` est une URL d'icône autorisée (`ToolWindowMeta.iconUrl`). */
|
|
103
|
+
export declare function isSafeToolWindowIconUrl(url: unknown): url is string;
|
|
104
|
+
/**
|
|
105
|
+
* Liste précise des problèmes d'une `meta` de fenêtre d'outils (vide = valide). Sert aux messages
|
|
106
|
+
* d'avertissement à l'enregistrement : une entrée invalide n'apparaît pas dans les rails, et le dire
|
|
107
|
+
* clairement évite de chercher pourquoi à l'intégration d'une app distante.
|
|
108
|
+
*/
|
|
109
|
+
export declare function getToolWindowMetaProblems(meta: unknown): string[];
|
|
53
110
|
/** Valide une `meta` d'extension : vrai si c'est une `ToolWindowMeta` exploitable. */
|
|
54
111
|
export declare function isToolWindowMeta(meta: unknown): meta is ToolWindowMeta;
|
|
112
|
+
/** Vrai si `slot` est l'un des slots de rail du shell. */
|
|
113
|
+
export declare function isToolWindowSlot(slot: string): boolean;
|
|
55
114
|
//# sourceMappingURL=tool-window.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-window.d.ts","sourceRoot":"","sources":["../src/tool-window.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3D,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAIxE,CAAC;AAEF,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-window.d.ts","sourceRoot":"","sources":["../src/tool-window.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3D,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAIxE,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kGAAkG;AAClG,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAIjF,CAAC;AAEF,2GAA2G;AAC3G,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;AAE5E,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,qBAAqB,CAAC;CACjD;AAID;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,6BAA6B,GAAG,IAAI,CAW9G;AAED,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAmCjE;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAEtE;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
package/dist/tool-window.js
CHANGED
|
@@ -26,14 +26,82 @@ export const SHELL_RAIL_RIGHT_SLOT = 'shell-rail-right-slot';
|
|
|
26
26
|
bottom: SHELL_RAIL_BOTTOM_SLOT,
|
|
27
27
|
right: SHELL_RAIL_RIGHT_SLOT
|
|
28
28
|
};
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/** Hauteurs (en % de la zone) d'un compartiment propre dont l'app n'a pas précisé les valeurs. */ export const DEFAULT_COMPARTMENT_HEIGHTS = {
|
|
30
|
+
height: 40,
|
|
31
|
+
minHeight: 15,
|
|
32
|
+
maxHeight: 100
|
|
33
|
+
};
|
|
34
|
+
const COMPARTMENT_KEYS = [
|
|
35
|
+
'height',
|
|
36
|
+
'minHeight',
|
|
37
|
+
'maxHeight'
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Résout `meta.compartment` : `null` pour le compartiment par défaut, sinon les hauteurs d'un compartiment
|
|
41
|
+
* propre, complétées par `DEFAULT_COMPARTMENT_HEIGHTS` puis rendues cohérentes (`min <= base <= max`).
|
|
42
|
+
*/ export function getToolWindowCompartment(meta) {
|
|
43
|
+
const raw = meta.compartment;
|
|
44
|
+
if (!raw || raw === 'default' || typeof raw !== 'object') return null;
|
|
45
|
+
const value = (key)=>{
|
|
46
|
+
const n = raw[key];
|
|
47
|
+
return typeof n === 'number' && Number.isFinite(n) && n > 0 && n <= 100 ? n : DEFAULT_COMPARTMENT_HEIGHTS[key];
|
|
48
|
+
};
|
|
49
|
+
const minHeight = value('minHeight');
|
|
50
|
+
const maxHeight = Math.max(minHeight, value('maxHeight'));
|
|
51
|
+
const height = Math.min(maxHeight, Math.max(minHeight, value('height')));
|
|
52
|
+
return {
|
|
53
|
+
height,
|
|
54
|
+
minHeight,
|
|
55
|
+
maxHeight
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Vrai si `url` est une URL d'icône autorisée (`ToolWindowMeta.iconUrl`). */ export function isSafeToolWindowIconUrl(url) {
|
|
59
|
+
if (typeof url !== 'string' || url.length === 0) return false;
|
|
60
|
+
return /^(https:\/\/|\/(?!\/)|data:image\/(svg\+xml|png|webp|gif|jpeg)[;,])/i.test(url);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Liste précise des problèmes d'une `meta` de fenêtre d'outils (vide = valide). Sert aux messages
|
|
64
|
+
* d'avertissement à l'enregistrement : une entrée invalide n'apparaît pas dans les rails, et le dire
|
|
65
|
+
* clairement évite de chercher pourquoi à l'intégration d'une app distante.
|
|
66
|
+
*/ export function getToolWindowMetaProblems(meta) {
|
|
67
|
+
if (!meta || typeof meta !== 'object') return [
|
|
68
|
+
'`meta` est absente : ajouter au moins { "title": "…" }'
|
|
69
|
+
];
|
|
31
70
|
const m = meta;
|
|
32
|
-
|
|
33
|
-
if (m.
|
|
34
|
-
if (m.
|
|
35
|
-
if (m.
|
|
36
|
-
if (m.
|
|
37
|
-
if (m.
|
|
38
|
-
|
|
71
|
+
const problems = [];
|
|
72
|
+
if (typeof m.title !== 'string' || m.title.length === 0) problems.push('`title` doit être une chaîne non vide');
|
|
73
|
+
if (m.titleKey !== undefined && typeof m.titleKey !== 'string') problems.push('`titleKey` doit être une chaîne');
|
|
74
|
+
if (m.icon !== undefined && typeof m.icon !== 'string') problems.push('`icon` doit être une chaîne');
|
|
75
|
+
if (m.iconUrl !== undefined && !isSafeToolWindowIconUrl(m.iconUrl)) problems.push('`iconUrl` doit commencer par https://, / ou data:image/(svg+xml|png|webp|gif|jpeg)');
|
|
76
|
+
if (m.order !== undefined && (typeof m.order !== 'number' || !Number.isFinite(m.order))) problems.push('`order` doit être un nombre fini');
|
|
77
|
+
if (m.global !== undefined && typeof m.global !== 'boolean') problems.push('`global` doit être un booléen');
|
|
78
|
+
if (m.rail !== undefined && m.rail !== 'left' && m.rail !== 'right') problems.push('`rail` vaut "left" ou "right"');
|
|
79
|
+
if (m.compartment !== undefined && m.compartment !== 'default') {
|
|
80
|
+
const c = m.compartment;
|
|
81
|
+
if (!c || typeof c !== 'object' || Array.isArray(c)) {
|
|
82
|
+
problems.push('`compartment` vaut \"default\" ou un objet { height, minHeight, maxHeight }');
|
|
83
|
+
} else {
|
|
84
|
+
for (const key of COMPARTMENT_KEYS){
|
|
85
|
+
const n = c[key];
|
|
86
|
+
if (n !== undefined && (typeof n !== 'number' || !Number.isFinite(n) || n <= 0 || n > 100)) problems.push(`\`compartment.${key}\` doit être un nombre dans ]0, 100] (pourcentage de la zone)`);
|
|
87
|
+
}
|
|
88
|
+
const resolved = getToolWindowCompartment({
|
|
89
|
+
compartment: c
|
|
90
|
+
});
|
|
91
|
+
if (resolved && problems.length === 0) {
|
|
92
|
+
const { minHeight, maxHeight } = {
|
|
93
|
+
minHeight: c.minHeight ?? DEFAULT_COMPARTMENT_HEIGHTS.minHeight,
|
|
94
|
+
maxHeight: c.maxHeight ?? DEFAULT_COMPARTMENT_HEIGHTS.maxHeight
|
|
95
|
+
};
|
|
96
|
+
if (minHeight > maxHeight) problems.push('`compartment.minHeight` ne peut pas dépasser `compartment.maxHeight`');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return problems;
|
|
101
|
+
}
|
|
102
|
+
/** Valide une `meta` d'extension : vrai si c'est une `ToolWindowMeta` exploitable. */ export function isToolWindowMeta(meta) {
|
|
103
|
+
return getToolWindowMetaProblems(meta).length === 0;
|
|
104
|
+
}
|
|
105
|
+
/** Vrai si `slot` est l'un des slots de rail du shell. */ export function isToolWindowSlot(slot) {
|
|
106
|
+
return Object.values(TOOL_WINDOW_SLOTS).includes(slot);
|
|
39
107
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@egen-civitas/esm-extensions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Coordinates extensions and extension points in the Egen Frontend",
|
|
6
6
|
"type": "module",
|
|
@@ -63,26 +63,26 @@
|
|
|
63
63
|
"lodash-es": "^4.17.21"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@egen-civitas/esm-api": "^
|
|
67
|
-
"@egen-civitas/esm-config": "^
|
|
66
|
+
"@egen-civitas/esm-api": "^2.0.0",
|
|
67
|
+
"@egen-civitas/esm-config": "^2.0.0",
|
|
68
68
|
"@egen-civitas/esm-expression-evaluator": "^1.0.0",
|
|
69
|
-
"@egen-civitas/esm-feature-flags": "^1.0.
|
|
70
|
-
"@egen-civitas/esm-globals": "^
|
|
71
|
-
"@egen-civitas/esm-state": "^1.0.
|
|
72
|
-
"@egen-civitas/esm-translations": "^1.0.
|
|
73
|
-
"@egen-civitas/esm-utils": "^
|
|
69
|
+
"@egen-civitas/esm-feature-flags": "^1.0.2",
|
|
70
|
+
"@egen-civitas/esm-globals": "^2.0.0",
|
|
71
|
+
"@egen-civitas/esm-state": "^1.0.3",
|
|
72
|
+
"@egen-civitas/esm-translations": "^1.0.3",
|
|
73
|
+
"@egen-civitas/esm-utils": "^2.0.0",
|
|
74
74
|
"react": "18.x",
|
|
75
75
|
"single-spa": "6.x"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@egen-civitas/esm-api": "^
|
|
79
|
-
"@egen-civitas/esm-config": "^
|
|
78
|
+
"@egen-civitas/esm-api": "^2.0.0",
|
|
79
|
+
"@egen-civitas/esm-config": "^2.0.0",
|
|
80
80
|
"@egen-civitas/esm-expression-evaluator": "^1.0.0",
|
|
81
|
-
"@egen-civitas/esm-feature-flags": "^1.0.
|
|
82
|
-
"@egen-civitas/esm-globals": "^
|
|
83
|
-
"@egen-civitas/esm-state": "^1.0.
|
|
84
|
-
"@egen-civitas/esm-translations": "^1.0.
|
|
85
|
-
"@egen-civitas/esm-utils": "^
|
|
81
|
+
"@egen-civitas/esm-feature-flags": "^1.0.2",
|
|
82
|
+
"@egen-civitas/esm-globals": "^2.0.0",
|
|
83
|
+
"@egen-civitas/esm-state": "^1.0.3",
|
|
84
|
+
"@egen-civitas/esm-translations": "^1.0.3",
|
|
85
|
+
"@egen-civitas/esm-utils": "^2.0.0",
|
|
86
86
|
"@swc/cli": "0.8.1",
|
|
87
87
|
"@swc/core": "1.15.21",
|
|
88
88
|
"@vitest/coverage-v8": "^4.1.2",
|