@esfaenza/dpe-builder 20.3.3 → 20.3.6

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/index.d.ts CHANGED
@@ -657,6 +657,17 @@ interface DpeFieldMappingInfo {
657
657
  interface DpeCompiledWriteback {
658
658
  writebackName: string;
659
659
  sequence: number;
660
+ /**
661
+ * L'intento di scrittura di questo writeback: operazione, tabella, chiave di corrispondenza,
662
+ * gruppo atomico, target. **Mai assente** (`contracts.md` §5), ed e' la **stessa istanza** che
663
+ * compare in `DpeCompileResult.writebackSequence` (ADR 0018).
664
+ *
665
+ * Sta qui e non duplicato campo per campo su questo tipo: senza di esso il client non ha modo di
666
+ * sapere *cosa* fa uno statement — mostrerebbe l'SQL di un `Upsert` e di una `Delete` allo stesso
667
+ * modo — e l'unica alternativa sarebbe incrociare `writebackSequence` per nome, cioe' ricostruire
668
+ * a mano un collegamento che il backend manda gia' fatto.
669
+ */
670
+ step: DpeWritebackStep;
660
671
  statement: SqlStatement;
661
672
  resultColumns?: DpeColumnInfo[];
662
673
  /** Vedi {@link DpeFieldMappingInfo}: forma provvisoria. */
@@ -989,6 +1000,20 @@ declare class HttpDpeBuilderApi extends DpeBuilderApi {
989
1000
  protected url(path: string): string;
990
1001
  /** Codifica di un segmento variabile. Un nome di definizione puo' contenere `/`, spazi, `&`. */
991
1002
  protected segment(value: string): string;
1003
+ /**
1004
+ * La chiave che finisce in un segmento di rotta, **verificata prima di partire**.
1005
+ *
1006
+ * Perche' esiste: `encodeURIComponent(undefined)` vale `'undefined'`, e senza questo controllo un
1007
+ * nome mancante non produceva nessun errore — produceva `PUT /definitions/undefined`, cioe' una
1008
+ * richiesta sensata per il trasporto e priva di senso per il dominio. La sbaglia il backend
1009
+ * (`404`, o peggio: sovrascrive una definizione che si chiama davvero cosi'), e chi guarda la rete
1010
+ * vede una chiave inventata dal client senza sapere da dove arrivi.
1011
+ *
1012
+ * Rifiuta **senza emettere la richiesta**: una chiave assente non si ritenta e non riguarda il
1013
+ * backend. La categoria e' `Backend` e non `MissingService` — il comando c'e' e non va disabilitato
1014
+ * — ne' `Transport`, che significherebbe «ritenta».
1015
+ */
1016
+ protected requireKey(value: string | null | undefined, primitive: string, what: string): string;
992
1017
  /**
993
1018
  * Cio' che avvolge **ogni** chiamata, e l'unico posto in cui si decide se una chiamata parte.
994
1019
  *
@@ -1034,6 +1059,31 @@ declare class HttpDpeBuilderApi extends DpeBuilderApi {
1034
1059
  /** L'**unica** rotta con involucro: il corpo porta anche i valori dei parametri (§7-bis). */
1035
1060
  compilePreview(definition: DpeDefinition, parameterValues?: DpeParameterValue[]): Observable<DpeCompileResult>;
1036
1061
  load(name: string): Observable<DpeDefinition>;
1062
+ /**
1063
+ * La risposta di `load` **e' una definizione**, e qui si verifica invece di sperarlo.
1064
+ *
1065
+ * Costa quattro righe e trasforma il difetto peggiore di questo contratto in un errore immediato
1066
+ * che nomina la causa. Senza, una risposta della forma sbagliata non produce nessun errore:
1067
+ * produce un editor con il canvas vuoto e un `name` `undefined`, che si manifesta molto piu' tardi
1068
+ * come un salvataggio verso una chiave inventata. I tre modi in cui succede davvero:
1069
+ *
1070
+ * - il backend restituisce **l'involucro della lettura** (`{ definition, diagnostics, hasErrors }`)
1071
+ * invece del documento: e' l'esito di `IDpeService.Deserialize`, ed e' un errore facile da fare
1072
+ * scrivendo `Ok(read)` al posto di `Ok(documento)`;
1073
+ * - la risposta e' in **PascalCase**: `Name` non e' `name`, e in TypeScript non e' un errore;
1074
+ * - la rotta risponde un **sommario** (`DpeDefinitionSummary`) invece della definizione: si
1075
+ * somigliano, e il sommario ha `name` ma non `formatVersion` ne' i nodi.
1076
+ *
1077
+ * Si controllano le due proprieta' **obbligatorie** del documento e nient'altro: una definizione
1078
+ * puo' legittimamente non avere nessun nodo, e verificare di piu' vorrebbe dire validare, che e'
1079
+ * del backend.
1080
+ */
1081
+ protected requireDefinition(payload: unknown): DpeDefinition;
1082
+ /**
1083
+ * Il nome viene dal **documento** e non da un parametro: e' la chiave, e la rotta e'
1084
+ * `PUT /definitions/{definition.name}`. Se manca, la chiamata si rifiuta qui — un salvataggio
1085
+ * senza chiave non e' un salvataggio, e una definizione nuova si crea con `createDefinition`.
1086
+ */
1037
1087
  save(definition: DpeDefinition): Observable<void>;
1038
1088
  /**
1039
1089
  * La dichiarazione dell'ambiente (ADR 0017). Questo client la implementa perche' conosce
@@ -1514,8 +1564,16 @@ declare class DpeDocumentStore {
1514
1564
  select(nodeName: string | undefined): void;
1515
1565
  /** Selezione multipla (riquadro, `Ctrl+A`): la lista che arriva dal gesto, senza duplicati. */
1516
1566
  selectMany(nodeNames: readonly string[]): void;
1517
- /** Proprieta' della radice: etichetta, descrizione, dialetto, parametri. */
1518
- patchDefinition(patch: Partial<DpeDefinition>): void;
1567
+ /**
1568
+ * Proprieta' della radice: etichetta, descrizione, dialetto, parametri.
1569
+ *
1570
+ * **`name` e `formatVersion` non sono nell'insieme**, e il tipo lo impedisce invece di dirlo in un
1571
+ * commento. `name` e' la chiave del catalogo: rinominare e' creare-e-cancellare (ADR 0019), non
1572
+ * una modifica del documento — e `Partial<DpeDefinition>` permetteva `{ name: undefined }`, che
1573
+ * lasciava nel documento una chiave senza valore. Da li' il salvataggio partiva verso
1574
+ * `PUT /definitions/undefined`. `formatVersion` e' del formato, non dell'autore.
1575
+ */
1576
+ patchDefinition(patch: Partial<Omit<DpeDefinition, 'name' | 'formatVersion'>>): void;
1519
1577
  addNode<K extends DpeNodeCollectionName>(collection: K, node: DpeNodeCollectionMap[K]): void;
1520
1578
  updateNode<K extends DpeNodeCollectionName>(collection: K, nodeName: string, patch: Partial<DpeNodeCollectionMap[K]>): void;
1521
1579
  /**
@@ -1878,6 +1936,31 @@ declare class DpeBuilderComponent {
1878
1936
  * (ADR 0006), che e' dell'host. Assente `getEnvironment`, non c'e' niente da confrontare.
1879
1937
  */
1880
1938
  protected readonly dialectMismatch: Signal<SqlDialectKind | undefined>;
1939
+ /**
1940
+ * Il documento porta una chiave utilizzabile. Il nome **e'** la chiave del catalogo, e la rotta di
1941
+ * aggiornamento e' `PUT /definitions/{name}`: senza nome non c'e' niente da aggiornare, e una
1942
+ * definizione nuova si crea dal catalogo (ADR 0019), non da qui.
1943
+ *
1944
+ * Sta qui e non solo nel client per la ragione che questo progetto applica alle primitive
1945
+ * assenti: un comando disabilitato che dice il motivo e' meglio di un comando attivo che fallisce
1946
+ * alla pressione. Il client rifiuta comunque — e' lui che compone l'URL, e un ospite che chiami
1947
+ * `save()` per vie proprie deve trovare la stessa risposta.
1948
+ */
1949
+ protected readonly hasKey: Signal<boolean>;
1950
+ /**
1951
+ * Il documento ricevuto **non e' una definizione**, detto subito e a schermo.
1952
+ *
1953
+ * L'unico ingresso e' l'input `definition`, e finora l'editor accettava qualunque oggetto: con un
1954
+ * documento della forma sbagliata mostrava un canvas vuoto — che sembra una definizione senza
1955
+ * nodi, cioe' uno stato legittimo — e il difetto ricompariva molto piu' tardi come un salvataggio
1956
+ * verso una chiave che il client doveva inventare. Le tre forme che arrivano davvero al posto del
1957
+ * documento sono l'involucro di lettura (`{ definition, diagnostics }`), il **sommario** del
1958
+ * catalogo (ha `name` ma non `formatVersion` ne' i nodi) e una risposta in PascalCase.
1959
+ *
1960
+ * Si controllano le due proprieta' obbligatorie e nient'altro: una definizione senza nodi e'
1961
+ * legittima, e verificare di piu' sarebbe validare — che e' del backend (I6).
1962
+ */
1963
+ protected readonly documentProblem: Signal<string | undefined>;
1881
1964
  protected readonly canSave: Signal<boolean>;
1882
1965
  protected readonly nodeCount: Signal<number>;
1883
1966
  constructor();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esfaenza/dpe-builder",
3
- "version": "20.3.3",
3
+ "version": "20.3.6",
4
4
  "peerDependencies": {
5
5
  "@angular/cdk": "^20.2.14",
6
6
  "@angular/common": "^20.3.25",