@esfaenza/flow-builder 20.3.10 → 20.3.12

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/README.md CHANGED
@@ -133,7 +133,7 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
133
133
  | §6.4 Dizionari e cataloghi | |
134
134
  |---|---|
135
135
  | `getDictionaries(processType?)` | astratto — `processType` filtra le globali (§4.1) |
136
- | `getReferences(query)` / `getWritableReferences(query)` | astratti |
136
+ | `getReferences(definition)` / `getWritableReferences(definition)` | astratti — prendono il **documento nudo** e restituiscono **tutti** i riferimenti: nel body non c'e' nessun filtro di tipo, e la compatibilita' col campo la decide l'editor (§6.4, §13.17) |
137
137
  | `getConnectorTargets(definition, excluding?)` | astratto |
138
138
  | `getOutline(definition)` | astratto |
139
139
  | `listObjects()`, `listFields(object, usage?)` | astratti |
@@ -142,6 +142,7 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
142
142
  | `listForms` / `listFormParameters` | astratti |
143
143
  | `listEnumTypes`, `listEvents`, `listSubflowCandidates` | astratti |
144
144
  | `describeObject`, `listFieldValues` | opzionali |
145
+ | `listEnumValues(enumType)` | opzionale — i **valori** di un tipo di enumerazione, cioe' i nomi scrivibili in `enumValue` (§4.2, §4.6). `listEnumTypes` e' l'altra meta' e non basta: quella dice quali tipi esistono, questa quali valori ha un tipo. `enumType` e' esattamente l'`objectType` della risorsa, del parametro o del **membro** di una classe (§4.7.1): la risposta e' del tipo, non del punto di uso, e la cache e' per nome del tipo. Lista vuota = "non lo so" — il valore si scrive a mano, e un tipo sconosciuto risponde vuoto, non 404 |
145
146
  | `listStructures`, `describeStructure(className)` | opzionali — le classi e i loro membri per le risorse `Structure` (§4.7). `listStructures` e' l'**elenco delle classi** senza membri; `describeStructure` restituisce la **descrizione** di una classe (`className`, `label`, `members`), non un array nudo (§4.7.1). Senza, le classi non sono verificabili e il nome si scrive a mano: "non lo so", non "non esiste". I tre esiti sono distinti: `members` popolato = elenco autorevole, `members: []` = membri non dichiarati (si digita, nessuna accusa), rifiuto `StructureNotFound` = classe non registrata (si segnala la **classe**) |
146
147
 
147
148
  | §6.5 Esecuzione | |
@@ -203,6 +204,14 @@ qualsiasi.
203
204
  dalla mappa delle uscite invece di essere «ramo di errore» per tutti: su uno stage di
204
205
  orchestrazione quel ramo e' lo **step rifiutato**, non un guasto.
205
206
 
207
+ La stessa mappa distingue i rami di **recupero da errore** (`isFaultRecovery`: Record\*,
208
+ ActionCall, ScriptCall, Wait) dagli altri, perche' lasciarne uno vuoto non significa «il
209
+ percorso finisce qui» ma «se questo fallisce l'interview termina `Failed` e le modifiche
210
+ vengono annullate» (§3.5). L'editor delle uscite lo dice come promemoria — non col colore
211
+ d'avviso, perche' rinunciare al recupero e' la scelta piu' comune — e il backend lo segnala
212
+ con `FAULT_CONNECTOR_MISSING`, che e' un `Warning` e non blocca niente. Lo stage di
213
+ orchestrazione ne resta fuori: la §7 non lo comprende.
214
+
206
215
  Un tipo con un **discriminatore** compare come piu' voci, una per valore: il Collection
207
216
  Processor e' «Ordina» e «Filtra», non «ordina o filtra». Sono due gesti diversi — un `Sort`
208
217
  vuole `sortOptions`, un `Filter` vuole condizioni (§5.5) — e sceglierli dalla palette evita di
@@ -254,14 +263,20 @@ Restano fuori i percorsi radicati sul risultato **automatico** di un elemento
254
263
  (`Leggi_Contatti.Owner.Name`): la validazione non li verifica, e l'editor non accusa cio' che il
255
264
  backend non verifica.
256
265
 
257
- Il filtro di tipo di un campo (§6.4) guarda il tipo della **radice**, e quindi non basta: in un
266
+ Il filtro di tipo di un campo (§6.4) lo applica **l'editor**: la primitiva prende il documento nudo
267
+ e restituisce tutti i riferimenti, così la stessa risposta serve tutte le tendine di una schermata
268
+ (§13.17). La regola sta in `core/reference-filter.util.ts`, ed e' la stessa per le radici e per i
269
+ segmenti di un percorso. Il filtro guarda il tipo della **radice**, e quindi non basta: in un
258
270
  parametro `String` una variabile `Structure` non e' compatibile, ma `Richiesta.Ragione` sì. Per
259
- questo `<fb-reference-picker>`, dove un filtro c'e', chiede al backend **anche** l'elenco non
260
- filtrato, e ne ricava due cose: i contenitori compaiono come righe in cui si **entra** — cliccarle
261
- apre il percorso invece di scegliere un valore del tipo sbagliato — e le radici si riconoscono
262
- tutte, così un `Leggi_Ordine.Numero` già scritto in un campo `String` non viene accusato di non
263
- esistere. Le proposte le filtra il backend come prima; i segmenti di un percorso li filtra
264
- l'editor con la stessa regola, tenendo comunque quelli da cui si scende.
271
+ questo `<fb-reference-picker>` tiene l'elenco **completo** accanto a quello filtrato, e ne ricava
272
+ due cose: i contenitori compaiono come righe in cui si **entra** — cliccarle apre il percorso
273
+ invece di scegliere un valore del tipo sbagliato — e le radici si riconoscono tutte, così un
274
+ `Leggi_Ordine.Numero` già scritto in un campo `String` non viene accusato di non esistere. Nelle
275
+ proposte non entra comunque nessun valore del tipo sbagliato: i segmenti li filtra la stessa
276
+ regola, tenendo solo quelli da cui si scende. In un campo di **destinazione** le due liste sono due
277
+ richieste — `getWritableReferences` per le proposte, `getReferences` per le radici — perche' la
278
+ scrivibilita' e' del **percorso** e non della radice: un `$User.Anagrafica.Citta` scritto a mano e'
279
+ `TARGET_NOT_WRITABLE`, non un nome che non esiste.
265
280
 
266
281
  **Le globali si navigano come le risorse.** Un percorso dichiarato dall'host puo' portare un
267
282
  contenitore, e allora `objectType` dice di che tipo: `$User.Anagrafica.Citta` si propone e si
@@ -305,6 +320,25 @@ quindi l'editor dice di filtrare per le colonne della chiave invece di far cerca
305
320
  nell'elenco non c'e'. Restano `<select>` i dizionari chiusi — tipi di dato, operatori,
306
321
  enumerazioni — dove non c'e' niente da scrivere a mano.
307
322
 
323
+ **Valori di enum.** Un `Enum` ha due meta' e servono entrambe: l'`objectType` dice **quale tipo** —
324
+ e quello resta un `<select>`, perche' l'elenco dei tipi e' un dizionario chiuso — mentre i **valori**
325
+ di quel tipo arrivano da `listEnumValues(objectType)` e sono cio' che finisce in `enumValue` (§4.2,
326
+ §4.6). Senza la seconda chiamata all'utente resta una casella di testo su un insieme chiuso, che e'
327
+ il modo piu' facile di scrivere un valore che il runtime non riconoscera'. Li propone
328
+ `<fb-enum-value-picker>`, che il `<fb-value-editor>` monta al posto della casella di testo appena il
329
+ tipo della destinazione e' `Enum`: vale quindi in una condizione, in un filtro, nel valore iniziale
330
+ di una risorsa, in un parametro di action o di form, in un Assignment e in una `Map` di un Transform.
331
+ Cio' che si scrive e' il **nome**: `numericValue` viene mostrato accanto al valore — aiuta a
332
+ riconoscerlo in dati legacy — ma un numero in `enumValue` sarebbe un altro tipo (§13.18). Elenco
333
+ vuoto resta "non lo so" — primitiva non esposta, tipo senza valori dichiarati, `objectType` ancora
334
+ da scegliere — e allora il valore si digita; con l'elenco popolato un valore fuori elenco e' un
335
+ **avviso**, perche' nessun codice della §7 lo blocca ed e' l'editor ad accorgersene prima del runtime.
336
+
337
+ Perche' l'editor conosca il tipo della destinazione serve saperlo: in un Assignment arriva da
338
+ `getWritableReferences` (per corrispondenza esatta del nome: su `Cliente.Stato` resta ignoto), in una
339
+ condizione e in un filtro dal riferimento o dal campo a sinistra, in un Transform dal **membro** della
340
+ classe di destinazione. Dove il tipo non si sa, il campo resta generico invece di indovinare.
341
+
308
342
  Lo stesso controllo, nella variante `<fb-name-picker>`, vale per **ogni altro nome che il flow
309
343
  prende da fuori**: tipo di action e action, script, form, i nomi dei loro parametri di ingresso
310
344
  e di uscita, il flow di uno step in background e dei suoi evaluation flow, il flow invocato da
@@ -450,6 +484,8 @@ distribuire e nessuna dipendenza da un font di icone dell'applicazione ospite.
450
484
  | 14 | **`None` non e' un operatore, e' un "da completare"** | Condizione evidenziata come incompleta, con il conteggio in testa alla sezione e la frase «la bozza si salva, l'attivazione no»; il validatore della demo lo emette come **errore** |
451
485
  | 15 | **Un valore data senza `Z` significa ora locale** | `ValueEditorComponent` ha un selettore «Ora locale / UTC (Z)», dice che cambiare fuso riscrive l'orario e non lo converte, e toglie il suffisso solo per il controllo `datetime-local`, che con il fuso resterebbe vuoto |
452
486
  | 16 | **`Structure` e `Object` non sono intercambiabili** | `StructurePickerComponent` per la classe (fuori catalogo = **errore**, `STRUCTURE_TYPE_UNKNOWN`) e `StructureMemberPickerComponent` per i membri, filtrati su `isWritable` dove serve una destinazione. Il pannello risorse mostra la classe come obbligatoria con severita' di errore e **non** mostra il valore iniziale, perche' un `structureValue` non esiste; `ReferencePickerComponent` propone `Variabile.Membro` e verifica il percorso **fino in fondo** con `core/path-navigation.ts`, con `PATH_NOT_VERIFIABLE` dove la catena si interrompe; il Transform con target classe chiede un membro invece di un campo. `FlowDictionaryStore.isStructure` legge il flag dal dizionario, non dal nome del tipo. La risposta dei membri e' la **descrizione della classe** (`{className, label, members}`), e i suoi tre esiti restano distinti fino alla UI: `FlowCatalogStore.describeStructure` li traduce in `declared` / `undeclared` / `unknown-class` / `unknown-catalog`, e solo `declared` autorizza a dire che un membro non esiste (§4.7.1) |
487
+ | 17 | **Due body diversi per due famiglie di primitive** | `HttpFlowBuilderApi`: le primitive che **analizzano** il documento — `validate`, `parse`, `references`, `references/writable`, `connector-targets`, `outline` — lo mandano **nudo alla radice**; l'involucro `{definition, flowName, …}` resta alle sole primitive di scrittura della §6.2. Sbagliare involucro non da' nessun errore: il backend legge un flow vuoto e risponde `200`. Per lo stesso motivo `getReferences`/`getWritableReferences` prendono la `FlowDefinition` e non un oggetto query: non c'e' nessun campo di filtro nel body, e il filtro di tipo lo applica l'editor con `core/reference-filter.util.ts` |
488
+ | 18 | **Gli enum si scrivono come stringhe** | Il modello e' fatto di unioni di stringhe letterali (`FlowDataType`, `FlowVersionStatus`, …) e non di enum numerici: `JSON.stringify` non ha modo di produrre un ordinale. Conta perche' `"status": 3` non e' `Draft` ma `InvalidDraft` e `"dataType": 0` e' `String`, non "non specificato" — nessun errore lo segnalerebbe. Chi scrive un'altra implementazione di `FlowBuilderApi` non traduca i valori in numeri |
453
489
 
454
490
  Altre regole del contratto rispettate: liste vuote omesse invece di scritte come `[]` (§2),
455
491
  `filterLogic` mostrato **solo** dove il modello lo prevede (§4.4), `fullName` / `status` mai