@esfaenza/dpe-builder 20.3.12 → 20.3.13
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/fesm2022/esfaenza-dpe-builder.mjs +3122 -667
- package/fesm2022/esfaenza-dpe-builder.mjs.map +1 -1
- package/index.d.ts +1302 -41
- package/package.json +1 -1
- package/styles/dpe-builder.css +379 -40
package/index.d.ts
CHANGED
|
@@ -217,9 +217,18 @@ interface AggregateNode extends DpeNode {
|
|
|
217
217
|
type TransformKind = 'Expression' | 'Slice' | 'ComputeRelative';
|
|
218
218
|
interface ExpressionField extends DpeExtensible {
|
|
219
219
|
alias: string;
|
|
220
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* Una **formula** nel linguaggio del compilatore registrato dall'ospite (ADR 0031): non e'
|
|
222
|
+
* SQL, e il frontend non ne conosce la grammatica. Forma `Value` sotto `Expression`, forma
|
|
223
|
+
* `WindowFunction` sotto `ComputeRelative`.
|
|
224
|
+
*/
|
|
221
225
|
expression: string;
|
|
222
|
-
/**
|
|
226
|
+
/**
|
|
227
|
+
* **Dichiarato dall'utente e autorevole** (ADR 0033): lo schema resta una funzione pura della
|
|
228
|
+
* definizione, quindi il tipo di una colonna calcolata e' questo e non quello inferito dal
|
|
229
|
+
* compilatore. Il compilatore lo **verifica** — `DPE_EXPR_TYPE_MISMATCH` /
|
|
230
|
+
* `DPE_EXPR_TYPE_WIDENED` / `DPE_EXPR_TYPE_UNVERIFIED` — ma non lo determina.
|
|
231
|
+
*/
|
|
223
232
|
declaredType: ColumnType;
|
|
224
233
|
}
|
|
225
234
|
interface TransformNode extends DpeNode {
|
|
@@ -316,6 +325,16 @@ interface CustomNode extends DpeNode {
|
|
|
316
325
|
type WritebackTargetKind = 'Database' | 'Json' | 'Csv';
|
|
317
326
|
type WritebackOperation = 'Insert' | 'Update' | 'Upsert' | 'Delete';
|
|
318
327
|
type WritebackFieldRole = 'Value' | 'PrimaryKey' | 'QualifierKey';
|
|
328
|
+
/**
|
|
329
|
+
* Granularita' del fallimento che l'host deve rispettare applicando un writeback (ADR 0040).
|
|
330
|
+
*
|
|
331
|
+
* `PerRecord`: l'host **puo'** applicare le righe indipendentemente e riportare i fallimenti per
|
|
332
|
+
* riga. `Atomic`: l'host **deve** applicare l'intero writeback in una transazione sola.
|
|
333
|
+
*
|
|
334
|
+
* Dichiarata e **non eseguita**: la libreria non apre transazioni e questo valore non cambia di
|
|
335
|
+
* una virgola l'SQL generato.
|
|
336
|
+
*/
|
|
337
|
+
type WritebackFailureHandling = 'Atomic' | 'PerRecord';
|
|
319
338
|
interface WritebackFieldMapping extends DpeExtensible {
|
|
320
339
|
/** Condiz.: alias a monte; assente quando `runtimeParameterName` e' presente. */
|
|
321
340
|
sourceFieldName?: string;
|
|
@@ -361,12 +380,34 @@ interface WritebackNode extends DpeNode {
|
|
|
361
380
|
operation?: WritebackOperation;
|
|
362
381
|
/** Obbligatorio (>=1) in un nodo valido. */
|
|
363
382
|
fields?: WritebackFieldMapping[];
|
|
364
|
-
/**
|
|
383
|
+
/**
|
|
384
|
+
* Predicato applicato al risultato: e' il **terzo sito di authoring di formule** (ADR 0031 §1),
|
|
385
|
+
* quello che si dimentica, e passa dal compilatore nella forma `Predicate`. Non e' SQL.
|
|
386
|
+
*/
|
|
365
387
|
filterCondition?: string;
|
|
366
388
|
/** Condiz.: richiesto per `operation === 'Upsert'`. */
|
|
367
389
|
externalIdFieldName?: string;
|
|
368
390
|
/** Default `false`. */
|
|
369
391
|
onlyChangedRows?: boolean;
|
|
392
|
+
/**
|
|
393
|
+
* `targetFieldName` della colonna con cui l'host raggruppa le righe per la rilavorazione
|
|
394
|
+
* (ADR 0040). Solo `target === 'Database'`. Dichiarato e non eseguito: la libreria non
|
|
395
|
+
* raggruppa niente, e senza questo campo l'unico lotto di lavoro possibile e' il writeback
|
|
396
|
+
* intero.
|
|
397
|
+
*/
|
|
398
|
+
processingGroupFieldName?: string;
|
|
399
|
+
/**
|
|
400
|
+
* Solo `target === 'Database'`, e **assente** vuol dire «non dichiarato», che non e' la stessa
|
|
401
|
+
* cosa di `PerRecord`: il valore efficace lo calcola il backend e arriva su
|
|
402
|
+
* `DpeWritebackStep.failureHandling`.
|
|
403
|
+
*
|
|
404
|
+
* L'opzionalita' non e' comodita': e' cio' che permette a un salva-dopo-carica di rispedire il
|
|
405
|
+
* documento **identico** (**I7**). Se l'editor scrivesse un default qui, una definizione che non
|
|
406
|
+
* dichiara niente tornerebbe al backend dichiarando `PerRecord`, e su un membro di gruppo
|
|
407
|
+
* atomico quella riga in piu' diventerebbe `DPE_MODEL_CONDITIONAL_FORBIDDEN` su un campo che
|
|
408
|
+
* nessuno ha toccato.
|
|
409
|
+
*/
|
|
410
|
+
failureHandling?: WritebackFailureHandling;
|
|
370
411
|
/** Solo `target === 'Json'`. */
|
|
371
412
|
jsonOptions?: JsonArtifactOptions;
|
|
372
413
|
/** Solo `target === 'Csv'`. */
|
|
@@ -415,7 +456,14 @@ type DpeAnyNode = DpeNodeCollectionMap[DpeNodeCollectionName];
|
|
|
415
456
|
/**
|
|
416
457
|
* L'elenco dei nomi di collezione in forma di valore, nell'ordine in cui i nodi si leggono
|
|
417
458
|
* (sorgenti -> trasformazioni -> sink). `keyof` non produce un array a runtime: questo
|
|
418
|
-
* elenco e' l'unico posto in cui vive l'ordine.
|
|
459
|
+
* elenco e' l'unico posto in cui vive l'ordine. Lo leggono il cammino del documento
|
|
460
|
+
* (`dpe-graph.ts`) e la palette, attraverso `DPE_NODE_CATEGORIES` che ne deriva.
|
|
461
|
+
*
|
|
462
|
+
* **Totale e senza ripetizioni, e a dirlo e' il compilatore.** Un array non si verifica contro
|
|
463
|
+
* un'unione: una collezione aggiunta a `DpeNodeCollectionMap` e dimenticata qui compilerebbe, e
|
|
464
|
+
* sparirebbe in silenzio dal cammino del documento (archi che non compaiono, rinomine
|
|
465
|
+
* incomplete) e dalla palette. Il controllo `COLLECTION_ORDER_IS_TOTAL` trasforma l'omissione, e
|
|
466
|
+
* la ripetizione, in un errore di build che nomina il membro.
|
|
419
467
|
*/
|
|
420
468
|
declare const DPE_NODE_COLLECTIONS: readonly DpeNodeCollectionName[];
|
|
421
469
|
|
|
@@ -474,6 +522,18 @@ interface Diagnostic {
|
|
|
474
522
|
* duplicazione del dominio: e' la sola distinzione che cambia **come si rende** un rilievo.
|
|
475
523
|
*/
|
|
476
524
|
declare const DPE_NODE_NOT_COMPILABLE = "DPE_NODE_NOT_COMPILABLE";
|
|
525
|
+
/**
|
|
526
|
+
* Il codice che il contratto (`contracts.md` §5 e §7) prescrive di mostrare **in testa** quando il
|
|
527
|
+
* catalogo delle formule non e' stato prodotto: nomina la sorgente il cui schema non si risolve,
|
|
528
|
+
* mentre le diagnostiche strutturali che lo accompagnano ne dicono la causa.
|
|
529
|
+
*
|
|
530
|
+
* Seconda e ultima costante di codice dichiarata dalla libreria, per lo stesso criterio della
|
|
531
|
+
* prima: non e' un elenco di dominio duplicato, e' l'unica cosa che cambia **come si rende** un
|
|
532
|
+
* sacco di rilievi. Senza di essa la riga che l'architetto ha aggiunto apposta — «una riga da
|
|
533
|
+
* mostrare in testa» — finirebbe in mezzo alle altre, che e' il rumore indistinguibile che il
|
|
534
|
+
* codice esiste per evitare.
|
|
535
|
+
*/
|
|
536
|
+
declare const DPE_CATALOG_UNAVAILABLE = "DPE_CATALOG_UNAVAILABLE";
|
|
477
537
|
/** Rappresentazione testuale del percorso, nella forma usata dai messaggi del backend. */
|
|
478
538
|
declare function diagnosticPathToString(path: DiagnosticPath | undefined): string;
|
|
479
539
|
|
|
@@ -498,6 +558,172 @@ declare function diagnosticPathToString(path: DiagnosticPath | undefined): strin
|
|
|
498
558
|
interface DpeEnvironment {
|
|
499
559
|
/** Il dialetto del database di destinazione. Dichiarato, mai scelto dall'utente dell'editor. */
|
|
500
560
|
readonly dialect: SqlDialectKind;
|
|
561
|
+
/**
|
|
562
|
+
* Nome del linguaggio in cui si scrivono le espressioni, dal compilatore di formule registrato
|
|
563
|
+
* dall'ospite (ADR 0031/0036).
|
|
564
|
+
*
|
|
565
|
+
* Serve **all'etichetta del campo**, e per questo sta qui e non nel catalogo: il catalogo puo'
|
|
566
|
+
* legittimamente non arrivare — il compilatore non descrive il proprio linguaggio
|
|
567
|
+
* (`ProvidesCatalog == false`), oppure il dialetto della definizione non e' fra quelli che
|
|
568
|
+
* copre e allora il catalogo e' nullo — mentre il nome del linguaggio si sa sempre. Un editor
|
|
569
|
+
* che leggesse il nome dal catalogo resterebbe muto proprio nei casi in cui l'utente ha piu'
|
|
570
|
+
* bisogno di sapere in che lingua sta scrivendo.
|
|
571
|
+
*
|
|
572
|
+
* Assente = l'editor non nomina nessun linguaggio. Non nomina il **dialetto** al suo posto: il
|
|
573
|
+
* dialetto non c'entra piu' con cio' che si scrive in quel campo (ADR 0031).
|
|
574
|
+
*/
|
|
575
|
+
readonly expressionLanguage?: string;
|
|
576
|
+
/**
|
|
577
|
+
* Il compilatore descrive il proprio linguaggio. Falso o assente: **non chiamare**
|
|
578
|
+
* `getFormulaCatalog`.
|
|
579
|
+
*
|
|
580
|
+
* Si interroga **prima** di chiamare, per la stessa ragione per cui la disponibilita' di un
|
|
581
|
+
* comando si sa prima del clic (`contracts.md` §7): una chiamata che si sa inutile costa al
|
|
582
|
+
* backend una passata completa di grafo e di metadati per restituire un catalogo vuoto.
|
|
583
|
+
*/
|
|
584
|
+
readonly providesFormulaCatalog?: boolean;
|
|
585
|
+
/**
|
|
586
|
+
* Le **forme** che il compilatore registrato sa produrre (`Capabilities.SupportedForms`, ADR
|
|
587
|
+
* 0031). Incrociata con `DpeNodeSchemaInfo.requiredForm` — che e' per **nodo** e arriva con la
|
|
588
|
+
* validazione — permette di **disabilitare** un campo formula che non potra' mai essere
|
|
589
|
+
* compilato.
|
|
590
|
+
*
|
|
591
|
+
* Le due meta' stanno in due posti perche' hanno due sorgenti e due vite: la forma richiesta
|
|
592
|
+
* viene dalla **definizione**, le forme supportate dal **compilatore registrato**, cioe'
|
|
593
|
+
* dall'installazione, come `expressionLanguage` e `providesFormulaCatalog` qui accanto.
|
|
594
|
+
* L'editor le incrocia e non deduce nessuna delle due.
|
|
595
|
+
*
|
|
596
|
+
* **Assente (o `null`) significa: non si disabilita niente.** Non e' un ripiego prudente, e' la
|
|
597
|
+
* politica: non sapere quali forme il compilatore copra non autorizza a indovinare, e un campo
|
|
598
|
+
* spento per ignoranza e' peggio di un campo acceso che il backend rifiutera' dicendo perche'.
|
|
599
|
+
* Un elenco **vuoto** e' un'altra cosa — e' una dichiarazione, e dice «nessuna forma».
|
|
600
|
+
*
|
|
601
|
+
* Opzionale **e** nullabile per la regola dei tipi di rispecchiamento: descrivono cio' che
|
|
602
|
+
* arriva **sul filo**, e l'ospite di riferimento ignora i nulli come politica globale, quindi la
|
|
603
|
+
* proprieta' puo' non comparire affatto.
|
|
604
|
+
*/
|
|
605
|
+
readonly supportedForms?: readonly DpeExpressionForm[] | null;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* La **forma** che i siti di espressione di un nodo pretendono (ADR 0031 §1).
|
|
609
|
+
*
|
|
610
|
+
* Attraversa il confine su `DpeNodeSchemaInfo.requiredForm` per una ragione sola: dedurla dal tipo
|
|
611
|
+
* di nodo — «una trasformazione `Expression` vuole un valore, il filtro di un writeback vuole un
|
|
612
|
+
* predicato» — sarebbe una **regola di dominio in TypeScript**, che e' vietata. La sa il backend, e
|
|
613
|
+
* la dice.
|
|
614
|
+
*
|
|
615
|
+
* Il tipo sta in questa sezione e non accanto agli schemi perche' e' la **stessa** enumerazione che
|
|
616
|
+
* `DpeEnvironment.supportedForms` dichiara: sono i due operandi dell'incrocio, e un'enumerazione
|
|
617
|
+
* dichiarata due volte diverge.
|
|
618
|
+
*/
|
|
619
|
+
type DpeExpressionForm = 'Value' | 'Predicate' | 'WindowFunction';
|
|
620
|
+
/**
|
|
621
|
+
* L'**involucro** di `getFormulaCatalog`, rispecchiamento di `DpeFormulaCatalogResult`
|
|
622
|
+
* (`contracts.md` §7, normativo). La rotta consegna questo, non il catalogo nudo.
|
|
623
|
+
*
|
|
624
|
+
* Il motivo e' misurato, non di principio: il service distingue **tre** esiti e il filo ne
|
|
625
|
+
* consegnava **due** — o un catalogo o un errore di trasporto — quindi *dialetto non coperto* e
|
|
626
|
+
* *backend rotto* arrivavano all'editor identici, e il degrado era silenzioso.
|
|
627
|
+
*
|
|
628
|
+
* **Il discriminante e' `diagnostics`, non `catalog`:** diagnostiche non vuote significa
|
|
629
|
+
* fallimento, e si mostrano; altrimenti un catalogo c'e', e la tavolozza si mostra se ha
|
|
630
|
+
* contenuto. In particolare un compilatore che non descrive il proprio linguaggio consegna il
|
|
631
|
+
* catalogo **presente e vuoto**, con `languageName` valorizzato e zero diagnostiche: chi ramasse
|
|
632
|
+
* su `catalog == null` non entrerebbe **mai** in quel caso.
|
|
633
|
+
*
|
|
634
|
+
* La derivazione dei tre esiti sta in `dpeFormulaCatalogOutcome`, una funzione pura, e non in un
|
|
635
|
+
* `if` dentro un componente.
|
|
636
|
+
*/
|
|
637
|
+
interface DpeFormulaCatalogResult {
|
|
638
|
+
/**
|
|
639
|
+
* Il catalogo. **Assente o `null` significa una cosa sola: non e' stato prodotto** — non
|
|
640
|
+
* «prodotto vuoto», che e' un esito diverso e si riconosce dagli elenchi vuoti.
|
|
641
|
+
*
|
|
642
|
+
* Opzionale **e** nullabile insieme, e non e' pignoleria: un tipo di rispecchiamento descrive
|
|
643
|
+
* cio' che arriva **sul filo**, non cio' che il record C# dichiara, e ospiti diversi
|
|
644
|
+
* serializzano diversamente. L'ospite di riferimento ignora i nulli come politica globale,
|
|
645
|
+
* quindi la proprieta' non compare affatto e arriva `undefined` mentre un tipo con il solo
|
|
646
|
+
* `| null` prometterebbe altro. `check:modelli` confronta i **nomi** dei campi e questa classe
|
|
647
|
+
* di divergenza non la vede.
|
|
648
|
+
*/
|
|
649
|
+
readonly catalog?: DpeFormulaCatalog | null;
|
|
650
|
+
/**
|
|
651
|
+
* Le diagnostiche del service. Mai nulla; **vuota** quando il compilatore semplicemente non
|
|
652
|
+
* descrive il proprio linguaggio, che non e' un errore.
|
|
653
|
+
*
|
|
654
|
+
* `DPE_CATALOG_UNAVAILABLE` e' la riga da mostrare **in testa**: nomina la sorgente il cui
|
|
655
|
+
* schema non si risolve, e le strutturali che la seguono ne dicono la causa. Non si filtrano
|
|
656
|
+
* per pertinenza — l'errore che spiega lo schema puo' stare a piu' salti di distanza — quindi
|
|
657
|
+
* diventano dettaglio espandibile invece di rumore indistinguibile.
|
|
658
|
+
*/
|
|
659
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
660
|
+
readonly hasErrors: boolean;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Rispecchiamento sul filo di `Jace.DPE.Expressions.DpeFormulaCatalog`: cosa il linguaggio di
|
|
664
|
+
* formule dell'ospite mette a disposizione **nel punto** in cui si sta scrivendo.
|
|
665
|
+
*
|
|
666
|
+
* **Non e' una regola di dominio e non ne diventa una** (`contracts.md` §7). L'editor lo usa per
|
|
667
|
+
* *mostrare* cosa esiste; non lo usa per validare cio' che l'utente scrive. La grammatica e' del
|
|
668
|
+
* compilatore, il frontend non la conosce, e nessuna validazione di formula viene scritta in
|
|
669
|
+
* TypeScript — per nessun motivo, nemmeno «solo per il caso banale»: una regola duplicata diverge,
|
|
670
|
+
* e quando diverge l'editor mente all'utente.
|
|
671
|
+
*
|
|
672
|
+
* Un catalogo **vuoto e' legittimo** (ADR 0036 §5) e non e' un errore: significa che il
|
|
673
|
+
* compilatore non descrive il proprio linguaggio, e l'editor mostra un campo di testo semplice.
|
|
674
|
+
*/
|
|
675
|
+
interface DpeFormulaCatalog {
|
|
676
|
+
/**
|
|
677
|
+
* Nome del linguaggio secondo il compilatore. **Non** e' la fonte dell'etichetta del campo:
|
|
678
|
+
* quella e' `DpeEnvironment.expressionLanguage`, che arriva anche quando il catalogo non arriva.
|
|
679
|
+
*/
|
|
680
|
+
readonly languageName: string;
|
|
681
|
+
readonly functions: readonly DpeFormulaFunction[];
|
|
682
|
+
readonly operators: readonly DpeFormulaOperator[];
|
|
683
|
+
readonly symbols: readonly DpeFormulaSymbol[];
|
|
684
|
+
}
|
|
685
|
+
interface DpeFormulaFunction {
|
|
686
|
+
/** Gruppo con cui l'elenco raggruppa la voce. */
|
|
687
|
+
readonly group: string;
|
|
688
|
+
readonly name: string;
|
|
689
|
+
readonly description?: string;
|
|
690
|
+
/**
|
|
691
|
+
* Assente quando il tipo di ritorno **dipende dagli argomenti** e un elenco statico non puo'
|
|
692
|
+
* dichiararlo (ADR 0036 §4). Assente significa «non si sa qui», non `String`.
|
|
693
|
+
*/
|
|
694
|
+
readonly returnType?: ColumnType;
|
|
695
|
+
readonly parameters: readonly DpeFormulaFunctionParameter[];
|
|
696
|
+
}
|
|
697
|
+
interface DpeFormulaFunctionParameter {
|
|
698
|
+
readonly name: string;
|
|
699
|
+
readonly description?: string;
|
|
700
|
+
readonly type?: ColumnType;
|
|
701
|
+
readonly isOptional?: boolean;
|
|
702
|
+
/**
|
|
703
|
+
* Il parametro appartiene a un gruppo che **si ripete** (funzione variadica). Un solo campo al
|
|
704
|
+
* posto della coppia gruppo/ordine del sistema di origine: il matching delle firme e' lavoro del
|
|
705
|
+
* compilatore, a un elenco per l'utente serve sapere che il gruppo si ripete.
|
|
706
|
+
*/
|
|
707
|
+
readonly isRepeating?: boolean;
|
|
708
|
+
}
|
|
709
|
+
interface DpeFormulaOperator {
|
|
710
|
+
readonly group: string;
|
|
711
|
+
readonly symbol: string;
|
|
712
|
+
readonly description?: string;
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Provenienza di un simbolo. Le tre sono strutturalmente diverse e l'elenco le raggruppa: una
|
|
716
|
+
* colonna a monte, un parametro di runtime della definizione e una costante del linguaggio non si
|
|
717
|
+
* correggono nello stesso modo quando il nome e' sbagliato.
|
|
718
|
+
*/
|
|
719
|
+
type DpeFormulaSymbolKind = 'Column' | 'Parameter' | 'Constant';
|
|
720
|
+
interface DpeFormulaSymbol {
|
|
721
|
+
readonly name: string;
|
|
722
|
+
readonly description?: string;
|
|
723
|
+
/** `null`/assente quando il compilatore non sa mapparlo sui sei tipi logici: una mancanza
|
|
724
|
+
* dichiarata e' meglio di una bugia. */
|
|
725
|
+
readonly type?: ColumnType;
|
|
726
|
+
readonly kind: DpeFormulaSymbolKind;
|
|
501
727
|
}
|
|
502
728
|
/**
|
|
503
729
|
* Riga di catalogo: identita' e fatti che l'ospite conosce **senza** caricare la definizione.
|
|
@@ -586,14 +812,66 @@ interface DpeColumnInfo {
|
|
|
586
812
|
*/
|
|
587
813
|
isNullable: boolean;
|
|
588
814
|
}
|
|
815
|
+
/**
|
|
816
|
+
* **Cio' che la libreria ha derivato su un nodo**: schema di uscita, compilabilita' e forma pretesa
|
|
817
|
+
* dai suoi siti di espressione. Arriva con **ogni** validazione, e da ADR 0041 con **una voce per
|
|
818
|
+
* ogni nodo della definizione, sempre** — anche per i nodi che il grafo non ha potuto ordinare.
|
|
819
|
+
*
|
|
820
|
+
* La presenza di una voce dice «questo nodo esiste, ed ecco cio' che la libreria ha potuto derivare
|
|
821
|
+
* su di esso»; **non** dice «il suo schema e' noto». Quello lo dice `hasSchema`, e solo quello.
|
|
822
|
+
*/
|
|
589
823
|
interface DpeNodeSchemaInfo {
|
|
590
824
|
nodeName: string;
|
|
591
|
-
|
|
825
|
+
/**
|
|
826
|
+
* Colonne di uscita. **Vuota non significa "nessuna colonna"** finche' non si e' letto
|
|
827
|
+
* `hasSchema`: e' vuota anche quando lo schema e' ignoto. Contarle senza guardare `hasSchema`
|
|
828
|
+
* afferma un fatto che il backend non ha affermato — ed e' il difetto misurato sul canvas prima
|
|
829
|
+
* dell'ADR 0041.
|
|
830
|
+
*
|
|
831
|
+
* **Obbligatoria**, come nel contratto (`contracts.md` §5): in C# e' `IReadOnlyList` mai nulla e
|
|
832
|
+
* arriva come `[]` quando e' vuota, quindi un ospite che omette la collezione vuota e' fuori
|
|
833
|
+
* contratto e non un caso da assecondare nel tipo. Dichiararla opzionale costringeva a un `?? []`
|
|
834
|
+
* a ogni lettura, e quel `?? []` e' **indistinguibile fra «vuota» e «non arrivata»** — cioe' la
|
|
835
|
+
* stessa ambiguita' che l'ADR 0041 ha tolto da `Columns`, riaperta un livello piu' in basso e in
|
|
836
|
+
* TypeScript. La regola generale (`contracts.md` §7): cio' che puo' mancare si dichiara opzionale
|
|
837
|
+
* **e** nullabile insieme, e una collezione non e' fra quelle cose.
|
|
838
|
+
*/
|
|
839
|
+
columns: DpeColumnInfo[];
|
|
840
|
+
/**
|
|
841
|
+
* Il discriminante fra «schema derivato» e «schema ignoto» (ADR 0041).
|
|
842
|
+
*
|
|
843
|
+
* - `true` = `columns` e' un **fatto**. Vuota vuol dire davvero zero colonne — stato
|
|
844
|
+
* raggiungibile, e gia' diagnosticato con `DPE_SCHEMA_EMPTY`.
|
|
845
|
+
* - `false` = schema **ignoto**: la derivazione non e' arrivata a una risposta (fallita qui o a
|
|
846
|
+
* monte, oppure nodo dentro un ciclo). `columns` e' vuota e **non significa niente**.
|
|
847
|
+
*
|
|
848
|
+
* **Assente = `false`.** Un ospite che serializza omettendo i falsi non manda affatto la
|
|
849
|
+
* proprieta', e qui l'omissione coincide con la risposta prudente: e' il motivo per cui il campo
|
|
850
|
+
* si chiama `hasSchema` e non `isSchemaUnknown`. Chi legge confronta quindi con `=== true`, mai
|
|
851
|
+
* per veridicita', e non lo deduce da `columns.length` — dedurlo sarebbe rimettere in TypeScript
|
|
852
|
+
* la regola che questo campo esiste per portare.
|
|
853
|
+
*/
|
|
854
|
+
hasSchema?: boolean;
|
|
592
855
|
/**
|
|
593
856
|
* `false` = nodo **valido ma non compilabile** (**I10**): e' un limite nostro, non un
|
|
594
857
|
* errore dell'utente, e va reso diverso da un nodo invalido.
|
|
595
858
|
*/
|
|
596
859
|
isCompilable: boolean;
|
|
860
|
+
/**
|
|
861
|
+
* La forma pretesa dai siti di espressione di questo nodo, oppure assente/`null` se il nodo non
|
|
862
|
+
* ne ha — che e' uno stato normale, non una mancanza.
|
|
863
|
+
*
|
|
864
|
+
* Sta qui e non sul risultato del catalogo perche' e' una cosa che la **libreria deriva** dal
|
|
865
|
+
* tipo del nodo (ADR 0031 §1), non una cosa che il **compilatore offre**: l'editor la riceve
|
|
866
|
+
* sempre, anche quando il catalogo non lo chiede affatto. Dedurla lato editor sarebbe una regola
|
|
867
|
+
* di dominio in TypeScript, che e' vietata; incrociarla con `DpeEnvironment.supportedForms`
|
|
868
|
+
* permette invece di **disabilitare** un campo che il compilatore registrato non compilera' mai.
|
|
869
|
+
*
|
|
870
|
+
* Opzionale **e** nullabile: un tipo di rispecchiamento descrive cio' che arriva **sul filo**, e
|
|
871
|
+
* l'ospite di riferimento omette i nulli come politica globale — quindi la proprieta' puo' non
|
|
872
|
+
* comparire affatto.
|
|
873
|
+
*/
|
|
874
|
+
requiredForm?: DpeExpressionForm | null;
|
|
597
875
|
}
|
|
598
876
|
interface DpeWritebackStep {
|
|
599
877
|
writebackName: string;
|
|
@@ -610,6 +888,23 @@ interface DpeWritebackStep {
|
|
|
610
888
|
externalIdFieldName?: string;
|
|
611
889
|
/** Presente se il writeback appartiene a un gruppo atomico. */
|
|
612
890
|
atomicGroupName?: string;
|
|
891
|
+
/**
|
|
892
|
+
* Il valore **efficace** per `target === 'Database'` (ADR 0040): membro di un gruppo atomico ->
|
|
893
|
+
* `Atomic`, altrimenti il valore dichiarato sul nodo, altrimenti `PerRecord`.
|
|
894
|
+
*
|
|
895
|
+
* **Assente per `Json`/`Csv`**, e segue la regola comune a tutti i campi dello `Step` che
|
|
896
|
+
* istruiscono chi scrive — `operation`, `tableName`, `externalIdFieldName`,
|
|
897
|
+
* `processingGroupFieldName`, `tenantColumnName`: sono assenti quando l'ospite non scrive.
|
|
898
|
+
* L'assenza dice una cosa precisa, «questo non lo scrivi tu», e dirla e' meglio di un
|
|
899
|
+
* `PerRecord` che su un artefatto sarebbe pure falso: un file si scrive per intero o per niente.
|
|
900
|
+
*
|
|
901
|
+
* Non e' il campo del nodo con un altro nome. `WritebackNode.failureHandling` e' cio' che
|
|
902
|
+
* l'autore ha scritto, questo e' cio' che l'host deve fare: ricavarlo qui incrociando
|
|
903
|
+
* `atomicGroupName` con il valore dichiarato e con il default vorrebbe dire reimplementare tre
|
|
904
|
+
* regole di dominio nell'editor, che e' esattamente cio' che l'editor non fa. Se il dato serve,
|
|
905
|
+
* arriva di qui.
|
|
906
|
+
*/
|
|
907
|
+
failureHandling?: WritebackFailureHandling;
|
|
613
908
|
/**
|
|
614
909
|
* Dichiarato, **non implementato dalla libreria**: il change tracking e' dell'host
|
|
615
910
|
* (ADR 0011) e non influenza l'SQL generato. Va mostrato come una dichiarazione che l'host
|
|
@@ -673,12 +968,66 @@ interface DpeCompiledWriteback {
|
|
|
673
968
|
/** Vedi {@link DpeFieldMappingInfo}: forma provvisoria. */
|
|
674
969
|
targetMapping?: DpeFieldMappingInfo[];
|
|
675
970
|
}
|
|
971
|
+
/**
|
|
972
|
+
* Il formato dell'artefatto prodotto. Due soli valori: `Database` non e' un artefatto e qui e'
|
|
973
|
+
* impossibile per costruzione — per questo il piano non riusa `WritebackTargetKind`.
|
|
974
|
+
*/
|
|
975
|
+
type ArtifactKind = 'Json' | 'Csv';
|
|
976
|
+
/**
|
|
977
|
+
* Una colonna dell'artefatto, con i **due nomi** che l'ADR 0015 tiene distinti: `resultName`
|
|
978
|
+
* lega la colonna del result set, `headerName` e' l'unico che viene scritto nel file.
|
|
979
|
+
* Mostrarli come uno solo nasconderebbe proprio la divergenza che quell'ADR ha chiuso.
|
|
980
|
+
*/
|
|
981
|
+
interface DpeArtifactColumn {
|
|
982
|
+
/** Alias SQL: serve a legare la colonna del result set. */
|
|
983
|
+
resultName: string;
|
|
984
|
+
/** Nome authored: e' quello che finisce nel file (ADR 0015). */
|
|
985
|
+
headerName: string;
|
|
986
|
+
type: LogicalType;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Il payload auto-sufficiente con cui l'ospite puo' **schedulare** la scrittura di un artefatto
|
|
990
|
+
* (ADR 0029): lo accoda, lo rilegge dopo un riavvio e lo riporta a `WriteArtifact`.
|
|
991
|
+
*
|
|
992
|
+
* L'editor non lo esegue e non lo materializza — `DpeBuilderApi` non acquista nessuna primitiva
|
|
993
|
+
* per questo — ma lo riceve dentro `DpeCompileResult.fileWritebacks`, e l'anteprima ne mostra
|
|
994
|
+
* l'SQL di lettura.
|
|
995
|
+
*
|
|
996
|
+
* `tenant` del record C# **non** e' qui, e non per dimenticanza: l'ambito tenant non attraversa
|
|
997
|
+
* il confine verso l'editor, per la stessa ragione per cui `getTable` reda la colonna di tenant
|
|
998
|
+
* (ADR 0027). Un backend che lo serializzi comunque non e' un errore: il client lo ignora.
|
|
999
|
+
*/
|
|
1000
|
+
interface DpeArtifactPlan {
|
|
1001
|
+
/**
|
|
1002
|
+
* Timbro del formato del payload. Il piano puo' tornare indietro **vecchio** da una coda, e un
|
|
1003
|
+
* valore ignoto viene rifiutato dal backend invece che tollerato.
|
|
1004
|
+
*/
|
|
1005
|
+
formatVersion: number;
|
|
1006
|
+
definitionName: string;
|
|
1007
|
+
/** E' anche il nome passato al sink dell'ospite: il piano non porta un `artifactName` distinto. */
|
|
1008
|
+
writebackName: string;
|
|
1009
|
+
sequence: number;
|
|
1010
|
+
kind: ArtifactKind;
|
|
1011
|
+
/** Lo legge l'ospite per scegliere la connessione, non la libreria. */
|
|
1012
|
+
dialect: SqlDialectKind;
|
|
1013
|
+
/** SQL di **lettura**: nessun artefatto e' stato prodotto. */
|
|
1014
|
+
statement: SqlStatement;
|
|
1015
|
+
columns?: DpeArtifactColumn[];
|
|
1016
|
+
/** Presenti solo per il `kind` corrispondente. */
|
|
1017
|
+
jsonOptions?: JsonArtifactOptions;
|
|
1018
|
+
csvOptions?: CsvArtifactOptions;
|
|
1019
|
+
}
|
|
676
1020
|
interface DpeCompileResult {
|
|
677
1021
|
hasErrors: boolean;
|
|
678
1022
|
diagnostics?: Diagnostic[];
|
|
679
1023
|
databaseWritebacks?: DpeCompiledWriteback[];
|
|
680
|
-
/**
|
|
681
|
-
|
|
1024
|
+
/**
|
|
1025
|
+
* ADR 0029: **piani di artefatto**, non writeback compilati. Portano gia' kind, opzioni e
|
|
1026
|
+
* intestazioni authored, cioe' tutto cio' che serve a scrivere il file; il `step` non c'e'
|
|
1027
|
+
* perche' per un file sarebbe fatto di soli campi nulli. L'SQL di lettura non e' ancora stato
|
|
1028
|
+
* eseguito.
|
|
1029
|
+
*/
|
|
1030
|
+
fileWritebacks?: DpeArtifactPlan[];
|
|
682
1031
|
writebackSequence?: DpeWritebackStep[];
|
|
683
1032
|
}
|
|
684
1033
|
|
|
@@ -699,14 +1048,14 @@ interface DpeCompileResult {
|
|
|
699
1048
|
* l'editor la considera disponibile e mostra il comando attivo.
|
|
700
1049
|
*
|
|
701
1050
|
* **Dichiarazione sottrattiva (ADR 0020).** Da quando la libreria spedisce un client HTTP che
|
|
702
|
-
* implementa tutte
|
|
1051
|
+
* implementa tutte le primitive, l'identita' da sola non basta: chi eredita quel client
|
|
703
1052
|
* non puo' dis-sovrascrivere un metodo. Disponibile diventa quindi «**sovrascritta** e **non
|
|
704
1053
|
* elencata** in `unsupportedPrimitives`». La seconda meta' e' solo sottrattiva — non rende
|
|
705
1054
|
* disponibile cio' che non e' implementato — e resta calcolata in questo file e in nessun altro.
|
|
706
1055
|
*/
|
|
707
1056
|
|
|
708
1057
|
/** Le primitive che un ambiente ospite puo' legittimamente non offrire. */
|
|
709
|
-
type DpeOptionalPrimitive = 'compilePreview' | 'load' | 'save' | 'getEnvironment' | 'listDefinitions' | 'createDefinition' | 'deleteDefinition';
|
|
1058
|
+
type DpeOptionalPrimitive = 'compilePreview' | 'load' | 'save' | 'getEnvironment' | 'getFormulaCatalog' | 'listDefinitions' | 'createDefinition' | 'deleteDefinition';
|
|
710
1059
|
declare function dpeIsPrimitiveAvailable(api: DpeBuilderApi, primitive: DpeOptionalPrimitive): boolean;
|
|
711
1060
|
/** L'insieme delle primitive disponibili: comodo per fotografarlo una volta alla costruzione. */
|
|
712
1061
|
interface DpeCapabilities {
|
|
@@ -714,6 +1063,15 @@ interface DpeCapabilities {
|
|
|
714
1063
|
readonly load: boolean;
|
|
715
1064
|
readonly save: boolean;
|
|
716
1065
|
readonly getEnvironment: boolean;
|
|
1066
|
+
/**
|
|
1067
|
+
* Il catalogo del linguaggio di formule (ADR 0036). **Condizione necessaria e non sufficiente**
|
|
1068
|
+
* per chiederlo: l'altra meta' e' `DpeEnvironment.providesFormulaCatalog`, che e' un fatto del
|
|
1069
|
+
* compilatore e non del trasporto. Le due stanno separate perche' sono due cose diverse — «il
|
|
1070
|
+
* backend non serve questa rotta» e «il compilatore non descrive il proprio linguaggio» — e
|
|
1071
|
+
* mescolarle renderebbe impossibile distinguere un ambiente incompleto da un compilatore
|
|
1072
|
+
* laconico.
|
|
1073
|
+
*/
|
|
1074
|
+
readonly getFormulaCatalog: boolean;
|
|
717
1075
|
readonly listDefinitions: boolean;
|
|
718
1076
|
readonly createDefinition: boolean;
|
|
719
1077
|
readonly deleteDefinition: boolean;
|
|
@@ -733,9 +1091,10 @@ interface DpeCommandAvailability {
|
|
|
733
1091
|
* (`contracts.md` §7, normativo): `createDefinition` per scrivere, e `getEnvironment` perche' il
|
|
734
1092
|
* dialetto della definizione nuova viene dall'ambiente (ADR 0017).
|
|
735
1093
|
*
|
|
736
|
-
* Perche' senza `getEnvironment` si disabilita invece di ripiegare su un dialetto qualsiasi:
|
|
737
|
-
*
|
|
738
|
-
*
|
|
1094
|
+
* Perche' senza `getEnvironment` si disabilita invece di ripiegare su un dialetto qualsiasi: il
|
|
1095
|
+
* dialetto decide con quali capacita' la definizione verra' compilata, e quali costrutti il
|
|
1096
|
+
* compilatore di formule copre (ADR 0031 §5: un dialetto fuori da `SupportedDialects` non compila
|
|
1097
|
+
* **nessuna** espressione), e chiederlo all'utente e' proprio la scelta che l'ADR 0017 ha tolto. Un
|
|
739
1098
|
* comando disabilitato che dice perche' e' meglio di entrambe; il rimedio per l'ospite e' una
|
|
740
1099
|
* riga, implementare `getEnvironment`.
|
|
741
1100
|
*
|
|
@@ -799,6 +1158,14 @@ declare abstract class DpeBuilderApi {
|
|
|
799
1158
|
*
|
|
800
1159
|
* Prende la definizione **in lavorazione**, non quella salvata: cio' che l'editor mostra
|
|
801
1160
|
* deve riferirsi a cio' che l'utente sta scrivendo. Va invocata con debounce.
|
|
1161
|
+
*
|
|
1162
|
+
* **`schemas` porta anche `requiredForm`**, la forma che i siti di espressione di quel nodo
|
|
1163
|
+
* pretendono. Sta li' e non sul risultato del catalogo delle formule perche' e' cio' che la
|
|
1164
|
+
* libreria **deriva** sul nodo, come le colonne e la compilabilita', mentre il catalogo e' cio'
|
|
1165
|
+
* che il compilatore **offre** e arriva solo quando il compilatore risponde: un ospite che
|
|
1166
|
+
* dichiara `providesFormulaCatalog` falso non fa chiamare quella rotta, e la forma non arrivava
|
|
1167
|
+
* mai. Chi implementa questo metodo la valorizza: senza, un campo formula non dice cosa vuole e
|
|
1168
|
+
* non si blocca quando il compilatore non sa produrre quella forma.
|
|
802
1169
|
*/
|
|
803
1170
|
abstract validate(definition: DpeDefinition): Observable<DpeValidateResult>;
|
|
804
1171
|
/**
|
|
@@ -830,7 +1197,7 @@ declare abstract class DpeBuilderApi {
|
|
|
830
1197
|
* definizione che gli viene passata dall'ospite.
|
|
831
1198
|
*
|
|
832
1199
|
* La deserializzazione (`IDpeService.Deserialize`) resta del backend: qui arriva un
|
|
833
|
-
* documento
|
|
1200
|
+
* documento gia' letto, con le sue eventuali diagnostiche gia' emesse.
|
|
834
1201
|
*/
|
|
835
1202
|
load(name: string): Observable<DpeDefinition>;
|
|
836
1203
|
/** Salvataggio. Opzionale: un editor in sola lettura e' un uso legittimo. */
|
|
@@ -843,13 +1210,46 @@ declare abstract class DpeBuilderApi {
|
|
|
843
1210
|
* Cosa l'editor fa con la risposta, e cosa non fa: mostra il dialetto in sola lettura e, se
|
|
844
1211
|
* differisce da quello della definizione (ADR 0009: e' li' che vive, ed e' da li' che il
|
|
845
1212
|
* backend lo legge), **lo segnala senza correggere**. Riscrivere `definition.dialect` sarebbe
|
|
846
|
-
* una migrazione silenziosa
|
|
1213
|
+
* una migrazione silenziosa delle capacita' con cui la definizione verra' compilata, per giunta eseguita
|
|
847
1214
|
* all'apertura e capace di marcare come «modificata» una definizione che nessuno ha toccato.
|
|
848
1215
|
*
|
|
849
1216
|
* Opzionale come le altre: dove manca, l'editor mostra il dialetto della definizione e non
|
|
850
1217
|
* dice nient'altro.
|
|
851
1218
|
*/
|
|
852
1219
|
getEnvironment(): Observable<DpeEnvironment>;
|
|
1220
|
+
/**
|
|
1221
|
+
* `IDpeService.GetFormulaCatalog` — cosa il linguaggio di formule mette a disposizione **nel
|
|
1222
|
+
* nodo indicato** (ADR 0031/0036). Opzionale: senza, l'editor mostra un campo di testo semplice,
|
|
1223
|
+
* che e' esattamente cio' che mostrava prima che il catalogo esistesse.
|
|
1224
|
+
*
|
|
1225
|
+
* **Prende la definizione e il nome del nodo, non uno schema.** Il catalogo dipende dallo schema
|
|
1226
|
+
* a monte — i simboli `Column` sono le colonne che quel nodo vede — e risolvere uno schema e' del
|
|
1227
|
+
* backend (**I4**): il frontend non sa farlo e non deve imparare. La definizione e' quella **in
|
|
1228
|
+
* lavorazione**, perche' quella aperta nell'editor puo' non essere ancora salvata.
|
|
1229
|
+
*
|
|
1230
|
+
* **Non e' una chiamata leggera** (`frontend.md` §5-quater, normativo): lato libreria costa una
|
|
1231
|
+
* passata completa di grafo e di propagazione, e interroga il provider di metadati per tutti i
|
|
1232
|
+
* datasource della definizione. Chi la consuma la chiede **una volta per nodo** e la conserva —
|
|
1233
|
+
* `DpeFormulaCatalogStore` lo fa — e non a ogni apertura di un campo, che e' il modo naturale di
|
|
1234
|
+
* scriverlo e quello sbagliato.
|
|
1235
|
+
*
|
|
1236
|
+
* Si interroga `DpeEnvironment.providesFormulaCatalog` **prima** di chiamare: un compilatore che
|
|
1237
|
+
* non descrive il proprio linguaggio risponde un catalogo vuoto, e farsi pagare quella passata di
|
|
1238
|
+
* grafo per riceverlo e' spreco puro (ADR 0036 §5).
|
|
1239
|
+
*
|
|
1240
|
+
* **Restituisce l'involucro, non il catalogo nudo** (`contracts.md` §7). Il service distingue
|
|
1241
|
+
* tre esiti e il filo ne consegnava due, quindi un dialetto non coperto e un backend rotto
|
|
1242
|
+
* arrivavano qui identici: la differenza fra «non lo so» e «non si puo'» si perdeva prima di
|
|
1243
|
+
* raggiungere lo schermo. Chi implementa questo metodo non trasforma un esito con diagnostiche
|
|
1244
|
+
* in un errore di trasporto: le diagnostiche **sono** la risposta.
|
|
1245
|
+
*
|
|
1246
|
+
* **`requiredForm` non e' piu' in questa risposta**: sta su `DpeNodeSchemaInfo.requiredForm`,
|
|
1247
|
+
* cioe' negli schemi di `validate`. La ragione e' proprio la riga qui sopra — questa risposta
|
|
1248
|
+
* arriva solo quando il compilatore parla, e la forma la libreria la sa senza chiedere niente a
|
|
1249
|
+
* nessuno. Chi implementa questo metodo non la rimette qui: due copie dello stesso fatto
|
|
1250
|
+
* divergono (ADR 0018).
|
|
1251
|
+
*/
|
|
1252
|
+
getFormulaCatalog(definition: DpeDefinition, nodeName: string): Observable<DpeFormulaCatalogResult>;
|
|
853
1253
|
/**
|
|
854
1254
|
* Elenco delle definizioni disponibili — **catalogo** (ADR 0019). Opzionale: dove manca, un
|
|
855
1255
|
* catalogo montato dall'ospite mostra il perche' invece di un elenco vuoto.
|
|
@@ -891,7 +1291,7 @@ declare abstract class DpeBuilderApi {
|
|
|
891
1291
|
*
|
|
892
1292
|
* L'editor si comporta in base alla **categoria**, mai leggendo il messaggio: chi implementa
|
|
893
1293
|
* {@link DpeBuilderApi} traduce l'errore di trasporto (status HTTP, payload, timeout) in un
|
|
894
|
-
* `DpeApiError`, e da
|
|
1294
|
+
* `DpeApiError`, e da li' in poi nella libreria non esiste piu' nessuna nozione di HTTP
|
|
895
1295
|
* (ADR 0007).
|
|
896
1296
|
*/
|
|
897
1297
|
/**
|
|
@@ -960,7 +1360,8 @@ declare const DPE_API_ERROR_FALLBACK_MESSAGE: Record<DpeApiErrorCategory, string
|
|
|
960
1360
|
* nessuna cache, nessun debounce, nessuna intestazione propria. Traduce trasporto ed errori e
|
|
961
1361
|
* nient'altro — la cache vive negli store, il debounce nel chiamante, i tentativi e
|
|
962
1362
|
* l'autenticazione negli interceptor dell'ospite. E non tocca `definition.dialect` in nessun
|
|
963
|
-
* metodo (ADR 0009 e 0017): sarebbe una migrazione silenziosa delle
|
|
1363
|
+
* metodo (ADR 0009 e 0017): sarebbe una migrazione silenziosa delle capacita' con cui il backend
|
|
1364
|
+
* compilera' la definizione.
|
|
964
1365
|
*/
|
|
965
1366
|
|
|
966
1367
|
/**
|
|
@@ -973,7 +1374,7 @@ interface DpeBuilderHttpConfig {
|
|
|
973
1374
|
/**
|
|
974
1375
|
* Primitive opzionali che questo ambiente **non serve** (`contracts.md` §7, dichiarazione
|
|
975
1376
|
* sottrattiva). E' l'unico modo che ha l'ospite di spegnere una primitiva che questo client
|
|
976
|
-
* implementa per forza: conoscendo tutti e
|
|
1377
|
+
* implementa per forza: conoscendo tutti e undici gli endpoint, li dichiarerebbe altrimenti tutti
|
|
977
1378
|
* disponibili, e un comando attivo su un endpoint non servito fallisce alla pressione.
|
|
978
1379
|
*/
|
|
979
1380
|
unsupported?: readonly DpeOptionalPrimitive[];
|
|
@@ -990,7 +1391,7 @@ declare class HttpDpeBuilderApi extends DpeBuilderApi {
|
|
|
990
1391
|
*/
|
|
991
1392
|
readonly unsupportedPrimitives: readonly DpeOptionalPrimitive[];
|
|
992
1393
|
/**
|
|
993
|
-
* Composizione dell'URL. Sovrascriverlo basta a spostare tutte e
|
|
1394
|
+
* Composizione dell'URL. Sovrascriverlo basta a spostare tutte e undici le rotte sotto un altro
|
|
994
1395
|
* prefisso senza toccare un metodo.
|
|
995
1396
|
*
|
|
996
1397
|
* `?? ''` e non un default: `baseUrl: ''` e' una configurazione **valida** e significa «rotte
|
|
@@ -1053,6 +1454,13 @@ declare class HttpDpeBuilderApi extends DpeBuilderApi {
|
|
|
1053
1454
|
protected httpPost<T>(path: string, body: unknown): Observable<T>;
|
|
1054
1455
|
protected httpPut<T>(path: string, body: unknown): Observable<T>;
|
|
1055
1456
|
protected httpDelete<T>(path: string): Observable<T>;
|
|
1457
|
+
/**
|
|
1458
|
+
* La rotta della validazione. Dal trasloco di `requiredForm` i suoi `schemas` portano **tre**
|
|
1459
|
+
* fatti per nodo e non due — colonne, compilabilita' e forma richiesta dai siti di espressione —
|
|
1460
|
+
* e un ospite che serva questa rotta a mano deve valorizzare anche il terzo: e' l'unica strada
|
|
1461
|
+
* per cui la forma arriva all'editor, e senza di essa un campo formula non dice cosa vuole ne'
|
|
1462
|
+
* si blocca quando il compilatore non sa produrla.
|
|
1463
|
+
*/
|
|
1056
1464
|
validate(definition: DpeDefinition): Observable<DpeValidateResult>;
|
|
1057
1465
|
getTables(): Observable<TableSummary[]>;
|
|
1058
1466
|
getTable(tableName: string): Observable<TableLookupResult>;
|
|
@@ -1113,6 +1521,36 @@ declare class HttpDpeBuilderApi extends DpeBuilderApi {
|
|
|
1113
1521
|
* senza correggere se differisce da quello della definizione.
|
|
1114
1522
|
*/
|
|
1115
1523
|
getEnvironment(): Observable<DpeEnvironment>;
|
|
1524
|
+
/**
|
|
1525
|
+
* L'**undicesima rotta** (ADR 0036): `POST {base}/formula-catalog/{nodeName}`, corpo il documento
|
|
1526
|
+
* nudo. Le altre dieci non cambiano.
|
|
1527
|
+
*
|
|
1528
|
+
* Perche' un `POST` e non un `GET`: il catalogo dipende dallo **schema a monte** del nodo, che il
|
|
1529
|
+
* backend sa risolvere solo avendo la definizione, e la definizione aperta nell'editor puo' non
|
|
1530
|
+
* essere ancora salvata. Un `GET` con il solo nome del nodo risponderebbe sul documento
|
|
1531
|
+
* archiviato, cioe' su un altro documento.
|
|
1532
|
+
*
|
|
1533
|
+
* Perche' il nome del nodo sta nel **percorso** e non nel corpo: un involucro
|
|
1534
|
+
* `{ definition, nodeName }` e' esattamente l'errore silenzioso del contratto — un backend che
|
|
1535
|
+
* deserializza una `DpeDefinition` da `{definition: …}` non riconosce nessuna proprieta',
|
|
1536
|
+
* risponde `200`, e l'editor riceve il catalogo di una definizione vuota. Meglio una rotta che
|
|
1537
|
+
* non puo' sbagliare che un secondo corpo con involucro.
|
|
1538
|
+
*
|
|
1539
|
+
* **La risposta e' `DpeFormulaCatalogResult`, non `DpeFormulaCatalog`** (`contracts.md` §7-bis).
|
|
1540
|
+
* E' l'unica correzione di questa rotta: consegnava il catalogo nudo, quindi i tre esiti del
|
|
1541
|
+
* service ne diventavano due e un dialetto non coperto si presentava come un guasto di rete. Il
|
|
1542
|
+
* client non interpreta niente di cio' che riceve — la tricotomia si legge in
|
|
1543
|
+
* `dpeFormulaCatalogOutcome`, dove e' pura e verificabile.
|
|
1544
|
+
*
|
|
1545
|
+
* **Rottura dichiarata del contratto di rotta:** la risposta non porta piu' `requiredForm`. La
|
|
1546
|
+
* forma richiesta dai siti di espressione di un nodo sta ora su `DpeNodeSchemaInfo.requiredForm`,
|
|
1547
|
+
* cioe' negli schemi di `POST {base}/validate`. Un ospite che la serializzi ancora qui non rompe
|
|
1548
|
+
* niente — il client passa il corpo intero e nessuno la legge — ma resta l'unica copia di un
|
|
1549
|
+
* fatto che l'editor prende da un'altra parte. Il motivo del trasloco e' che questa rotta
|
|
1550
|
+
* l'editor non la chiama affatto quando `DpeEnvironment.providesFormulaCatalog` e' falso: la
|
|
1551
|
+
* forma non arrivava mai, proprio dagli ospiti piu' laconici.
|
|
1552
|
+
*/
|
|
1553
|
+
getFormulaCatalog(definition: DpeDefinition, nodeName: string): Observable<DpeFormulaCatalogResult>;
|
|
1116
1554
|
/** Nessun parametro di interrogazione: il filtro del catalogo e' locale, di proposito. */
|
|
1117
1555
|
listDefinitions(): Observable<DpeDefinitionSummary[]>;
|
|
1118
1556
|
/**
|
|
@@ -1198,9 +1636,10 @@ declare class DpeCatalogStore {
|
|
|
1198
1636
|
* contratto, e non deve esistere — si comporrebbe di queste due comunque, e una primitiva
|
|
1199
1637
|
* dedicata dovrebbe ridecidere lato host cosa cambia.
|
|
1200
1638
|
*
|
|
1201
|
-
* Il dialetto e' quello della **definizione di partenza**, non quello dell'ambiente:
|
|
1202
|
-
*
|
|
1203
|
-
*
|
|
1639
|
+
* Il dialetto e' quello della **definizione di partenza**, non quello dell'ambiente: cambiarlo
|
|
1640
|
+
* duplicando sarebbe una migrazione silenziosa: il dialetto decide le capacita' con cui si
|
|
1641
|
+
* compila, e se il compilatore di formule non lo copre la copia non compila nessuna espressione
|
|
1642
|
+
* (ADR 0031 §5).
|
|
1204
1643
|
*/
|
|
1205
1644
|
duplicate(sourceName: string, name: string, label: string): Observable<DpeDefinitionSummary>;
|
|
1206
1645
|
/** Cancella per nome e ricarica l'elenco. La conferma e' della schermata, non dello store. */
|
|
@@ -1220,6 +1659,215 @@ declare class DpeCatalogStore {
|
|
|
1220
1659
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DpeCatalogStore>;
|
|
1221
1660
|
}
|
|
1222
1661
|
|
|
1662
|
+
/**
|
|
1663
|
+
* Le condizioni dei campi condizionali, **in un punto solo**.
|
|
1664
|
+
*
|
|
1665
|
+
* Un campo condizionale e' un campo del modello che ha significato solo quando un altro campo del
|
|
1666
|
+
* **suo stesso nodo** — il discriminante — vale una certa cosa: `jsonOptions` solo con
|
|
1667
|
+
* `target === 'Json'`, `expressionFields` solo con `kind` diverso da `Slice`, e cosi' via. Le
|
|
1668
|
+
* condizioni sono usate dall'ispettore in due direzioni opposte:
|
|
1669
|
+
*
|
|
1670
|
+
* 1. **resa** (`frontend.md` §5-ter, normativa): il controllo si rende quando la condizione vale
|
|
1671
|
+
* **oppure** quando il campo porta un valore. Un valore fuori condizione che nessun controllo
|
|
1672
|
+
* mostra non e' cancellabile dall'editor, e per **I7** sopravvive a ogni salvataggio;
|
|
1673
|
+
* 2. **ripulitura**: cambiare il discriminante e' un gesto deliberato con cui l'autore dichiara
|
|
1674
|
+
* inapplicabili i campi che il valore nuovo non governa, e quei campi escono dal documento.
|
|
1675
|
+
*
|
|
1676
|
+
* Fino a LS9 le stesse condizioni erano scritte **due volte in ogni ispettore**, una per direzione,
|
|
1677
|
+
* a pochi metodi di distanza. E' la duplicazione piu' facile da introdurre e la piu' difficile da
|
|
1678
|
+
* vedere, perche' i sintomi di una divergenza sono silenziosi e nessun test li coglie:
|
|
1679
|
+
*
|
|
1680
|
+
* - un campo **ripulito che resta mostrato** — la ripulitura lo toglie, la resa lo rimette, e
|
|
1681
|
+
* l'utente vede un controllo che non corrisponde a niente nel documento;
|
|
1682
|
+
* - §5-ter che **smette di coprire un campo** — la resa lo nasconde mentre il documento lo porta,
|
|
1683
|
+
* cioe' il difetto che quella regola esiste per chiudere, tornato in silenzio.
|
|
1684
|
+
*
|
|
1685
|
+
* Con la tabella qui sotto le due direzioni leggono **la stessa riga**: `dpeFieldVisibility()`
|
|
1686
|
+
* costruisce un segnale per ogni voce, `dpePruneInapplicable()` scorre le voci una per una.
|
|
1687
|
+
* Aggiungere un campo condizionale domani significa scrivere **una** riga; scriverla per la resa e
|
|
1688
|
+
* dimenticarla per la ripulitura non e' possibile, perche' e' la stessa riga.
|
|
1689
|
+
*
|
|
1690
|
+
* ## Cio' che questo file NON chiude, e va detto
|
|
1691
|
+
*
|
|
1692
|
+
* **La fonte autorevole di queste condizioni e' il backend**, e resta ricopiata a mano:
|
|
1693
|
+
* `dpe/dpe/Validation/ModelRules.cs` e `dpe/dpe/Validation/WritebackRules.cs`. Qui resta una
|
|
1694
|
+
* **regola di dominio in TypeScript**, cioe' una deroga dichiarata a un vincolo del progetto
|
|
1695
|
+
* (`frontend.md` §5-ter, «duplicazione dichiarata e temporanea»). `npm run check:modelli` **non**
|
|
1696
|
+
* la copre: confronta le forme dei tipi, non le condizioni.
|
|
1697
|
+
*
|
|
1698
|
+
* Quindi: chi tocca una condizione di la' deve toccarla anche di qua, e i due sintomi silenziosi
|
|
1699
|
+
* elencati sopra valgono identici per una divergenza dal backend — con l'aggravante che li' non
|
|
1700
|
+
* c'e' nemmeno il compilatore. La direzione che chiude la classe invece di sorvegliarla (la
|
|
1701
|
+
* tabella come **dato** pubblicato dal contratto, letta da `ModelRules`) e' la questione aperta 32.
|
|
1702
|
+
*
|
|
1703
|
+
* ## Cosa non sta in tabella, e perche'
|
|
1704
|
+
*
|
|
1705
|
+
* Solo i campi **del nodo**: la ripulitura toglie chiavi dal nodo, quindi una voce deve essere una
|
|
1706
|
+
* chiave del nodo. Una condizione che governa un campo **dentro una riga di una collezione** (il
|
|
1707
|
+
* tipo dichiarato di un campo di sorgente) non e' rappresentabile qui e resta scritta nel suo
|
|
1708
|
+
* ispettore, dove la meta' «porta un valore» e' un `some(...)` sulle righe.
|
|
1709
|
+
*/
|
|
1710
|
+
|
|
1711
|
+
/** La condizione di applicabilita' di un campo, valutata sul nodo intero. */
|
|
1712
|
+
type DpeFieldCondition<TNode> = (node: TNode) => boolean;
|
|
1713
|
+
/**
|
|
1714
|
+
* La tabella di un tipo di nodo: **chiave del nodo → condizione**.
|
|
1715
|
+
*
|
|
1716
|
+
* Le chiavi sono limitate a `keyof TNode` cosi' un campo rinominato nel modello non lascia qui una
|
|
1717
|
+
* riga orfana che nessuno consuma, e la ripulitura non puo' togliere una chiave inventata.
|
|
1718
|
+
*/
|
|
1719
|
+
type DpeConditionalFields<TNode> = {
|
|
1720
|
+
readonly [K in keyof TNode]?: DpeFieldCondition<TNode>;
|
|
1721
|
+
};
|
|
1722
|
+
/** Un segnale di visibilita' per ogni voce della tabella, con lo stesso nome del campo. */
|
|
1723
|
+
type DpeFieldVisibility<TConditions> = {
|
|
1724
|
+
readonly [K in keyof TConditions]: Signal<boolean>;
|
|
1725
|
+
};
|
|
1726
|
+
/**
|
|
1727
|
+
* «Il campo porta un valore», nel senso di `frontend.md` §5-ter.
|
|
1728
|
+
*
|
|
1729
|
+
* Nessuna delle equivalenze qui sotto e' un giudizio sul valore — dire che e' sbagliato tocca al
|
|
1730
|
+
* backend, e la regola di resa vale **diagnostica o no**:
|
|
1731
|
+
*
|
|
1732
|
+
* - **stringa vuota = assente**, perche' il backend confronta con `string.IsNullOrEmpty`: un
|
|
1733
|
+
* `processingGroupFieldName: ''` arrivato da fuori non deve far comparire un campo vuoto, che
|
|
1734
|
+
* sarebbe il rumore che la regola promette di non introdurre;
|
|
1735
|
+
* - **`false` = assente**, perche' i campi governati sono `bool` **non nullable** con default
|
|
1736
|
+
* `false` lato C# (`OnlyChangedRows`, `AllowsMultipleLookupValues`): dopo la deserializzazione
|
|
1737
|
+
* `false` e' indistinguibile dall'assenza;
|
|
1738
|
+
* - **collezione vuota = assente**: un `criteria: []` non dichiara niente, e il backend lo conta
|
|
1739
|
+
* con `Count(...) == 0`.
|
|
1740
|
+
*
|
|
1741
|
+
* Un oggetto invece **e' sempre** una dichiarazione, anche `{}`: per il backend un `jsonOptions`
|
|
1742
|
+
* non nullo fuori dal proprio target e' `DPE_MODEL_CONDITIONAL_FORBIDDEN` qualunque cosa contenga.
|
|
1743
|
+
*/
|
|
1744
|
+
declare function dpeDeclares(value: unknown): boolean;
|
|
1745
|
+
/**
|
|
1746
|
+
* I segnali di resa di §5-ter: **la condizione vale oppure il campo porta un valore**.
|
|
1747
|
+
*
|
|
1748
|
+
* Si costruiscono dalla tabella intera e non uno per uno, cosi' il segnale di un campo nuovo esiste
|
|
1749
|
+
* per il solo fatto che la sua riga esiste. Nel template il tipo fa il resto: `shows.jsonOptions()`
|
|
1750
|
+
* su una voce che non c'e' non compila, quindi non si puo' nascondere un campo per distrazione.
|
|
1751
|
+
*/
|
|
1752
|
+
declare function dpeFieldVisibility<TNode extends object, TConditions extends DpeConditionalFields<TNode>>(node: Signal<TNode>, conditions: TConditions): DpeFieldVisibility<TConditions>;
|
|
1753
|
+
/**
|
|
1754
|
+
* La modifica di un discriminante, **piu'** la rimozione dei campi che con il valore nuovo non si
|
|
1755
|
+
* applicano piu'.
|
|
1756
|
+
*
|
|
1757
|
+
* La condizione si valuta sul nodo **come sara' dopo il gesto** (`{ ...node, ...change }`), non su
|
|
1758
|
+
* quello di adesso: e' il solo modo di trattare un discriminante che ne cambia un altro nello
|
|
1759
|
+
* stesso gesto — su un writeback la destinazione decide l'operazione, e l'operazione decide il
|
|
1760
|
+
* campo di identificazione esterna.
|
|
1761
|
+
*
|
|
1762
|
+
* E si ripete **finche' non si stabilizza**, perche' una rimozione puo' invalidare la condizione
|
|
1763
|
+
* di un altro campo: portando una scrittura `Upsert` da `Database` a `Json`, il primo giro toglie
|
|
1764
|
+
* `operation` e solo il secondo si accorge che `externalIdFieldName` non e' piu' governato da
|
|
1765
|
+
* niente. Con un giro solo quel valore restava nel documento su un artefatto, dove il backend
|
|
1766
|
+
* **non lo diagnostica**: ignorato e invisibile, il caso peggiore. Trovato **eseguendo** la demo,
|
|
1767
|
+
* non leggendo il codice — la versione a un giro passava tutti i test che c'erano, e il test che
|
|
1768
|
+
* la coglie e' stato scritto dopo averla vista fallire a schermo.
|
|
1769
|
+
*
|
|
1770
|
+
* Il punto fisso esiste sempre: ogni giro puo' solo **aggiungere** rimozioni, i campi sono finiti
|
|
1771
|
+
* e un campo tolto non torna. Una condizione scritta al contrario (vera **perche'** l'altro campo
|
|
1772
|
+
* e' assente) renderebbe il risultato dipendente dall'ordine: in tabella non ce ne sono, e questo
|
|
1773
|
+
* e' il motivo per cui non ce ne devono essere.
|
|
1774
|
+
*
|
|
1775
|
+
* **Si toglie cio' che non si applica, non cio' che apparteneva al valore precedente**, e la
|
|
1776
|
+
* differenza non e' teorica: `Expression` → `ComputeRelative` non tocca `expressionFields`, perche'
|
|
1777
|
+
* quel campo e' governato da entrambi. Un «cambiando tipo si azzera» sarebbe piu' semplice da
|
|
1778
|
+
* scrivere e cancellerebbe espressioni SQL su un passaggio che non le rende inapplicabili.
|
|
1779
|
+
*
|
|
1780
|
+
* Togliere e' **rimuovere la chiave** (`undefined`), non scriverci `false` o `[]`: le due forme
|
|
1781
|
+
* sono equivalenti per il validatore e diverse per il documento, e il documento e' cio' che si
|
|
1782
|
+
* salva (**I7**).
|
|
1783
|
+
*
|
|
1784
|
+
* Si rimuove **solo cio' che c'e'**: un campo gia' assente non entra nel patch. Sul documento
|
|
1785
|
+
* salvato non cambia niente — una chiave a `undefined` sparisce serializzando — ma il patch
|
|
1786
|
+
* diventa il resoconto esatto del gesto, e «questo cambio non tocca niente» diventa una cosa
|
|
1787
|
+
* osservabile invece di una cosa da credere.
|
|
1788
|
+
*
|
|
1789
|
+
* Non e' distruttivo perche' il patch passa da `DpeDocumentStore.updateNode` → `commit`, che mette
|
|
1790
|
+
* l'istantanea precedente nella cronologia: «Annulla» rimette tutto. Verificato a schermo in
|
|
1791
|
+
* LS7-quater, non dedotto — era il solo fatto che avrebbe potuto togliere la ragione a questo
|
|
1792
|
+
* comportamento.
|
|
1793
|
+
*/
|
|
1794
|
+
declare function dpePruneInapplicable<TNode extends object, TConditions extends DpeConditionalFields<TNode>>(node: TNode, change: Partial<TNode>, conditions: TConditions): Partial<TNode>;
|
|
1795
|
+
/**
|
|
1796
|
+
* Sorgente: il tipo decide da dove si legge (`ModelRules.cs`, `ApplyDataSources`).
|
|
1797
|
+
*
|
|
1798
|
+
* Nessuno dei tre e' diagnosticato **fuori** condizione — il backend li richiede dove servono e
|
|
1799
|
+
* ignora il resto — e non cambia niente: §5-ter guarda il documento, non l'elenco dei codici.
|
|
1800
|
+
*/
|
|
1801
|
+
declare const DPE_DATA_SOURCE_CONDITIONS: {
|
|
1802
|
+
tableName: (node: DataSourceNode) => boolean;
|
|
1803
|
+
csvOptions: (node: DataSourceNode) => boolean;
|
|
1804
|
+
externalDatasetName: (node: DataSourceNode) => boolean;
|
|
1805
|
+
};
|
|
1806
|
+
/**
|
|
1807
|
+
* Filtro: `isDynamic` sceglie quale meta' del nodo vale (`ModelRules.cs`, `ApplyFilters`).
|
|
1808
|
+
*
|
|
1809
|
+
* Il parametro serve al filtro dinamico; criteri e condizione a quello statico.
|
|
1810
|
+
*/
|
|
1811
|
+
declare const DPE_FILTER_CONDITIONS: {
|
|
1812
|
+
criteria: (node: FilterNode) => boolean;
|
|
1813
|
+
condition: (node: FilterNode) => boolean;
|
|
1814
|
+
filterParameterName: (node: FilterNode) => boolean;
|
|
1815
|
+
};
|
|
1816
|
+
/**
|
|
1817
|
+
* Giunzione: la molteplicita' ammessa ha significato solo su una `Lookup`
|
|
1818
|
+
* (`JoinRules.cs`, `DialectRules.cs`).
|
|
1819
|
+
*/
|
|
1820
|
+
declare const DPE_JOIN_CONDITIONS: {
|
|
1821
|
+
allowsMultipleLookupValues: (node: JoinNode) => boolean;
|
|
1822
|
+
};
|
|
1823
|
+
/** Percorso gerarchico: le aggregazioni servono quando sono dichiarate richieste. */
|
|
1824
|
+
declare const DPE_HIERARCHY_PATH_CONDITIONS: {
|
|
1825
|
+
aggregateFields: (node: HierarchyPathNode) => boolean;
|
|
1826
|
+
};
|
|
1827
|
+
/**
|
|
1828
|
+
* Trasformazione: `kind` governa i quattro campi (`ModelRules.cs`, `ApplyTransforms`).
|
|
1829
|
+
*
|
|
1830
|
+
* `expressionFields` e' governato da **due** tipi, ed e' il motivo per cui la ripulitura non puo'
|
|
1831
|
+
* essere un azzeramento.
|
|
1832
|
+
*/
|
|
1833
|
+
declare const DPE_TRANSFORM_CONDITIONS: {
|
|
1834
|
+
expressionFields: (node: TransformNode) => boolean;
|
|
1835
|
+
droppedFields: (node: TransformNode) => boolean;
|
|
1836
|
+
partitionBy: (node: TransformNode) => boolean;
|
|
1837
|
+
orderBy: (node: TransformNode) => boolean;
|
|
1838
|
+
};
|
|
1839
|
+
/**
|
|
1840
|
+
* Scrittura: `target` governa sei campi, **`operation` ne governa un settimo**
|
|
1841
|
+
* (`ModelRules.cs`, `ApplyWritebacks`; `WritebackRules.cs`, `CheckArtifactOptions`,
|
|
1842
|
+
* `CheckProcessingGroupField`, `CheckFailureHandling`).
|
|
1843
|
+
*
|
|
1844
|
+
* `tableName` e `onlyChangedRows` sono in tabella pur **non** essendo diagnosticati fuori da
|
|
1845
|
+
* `Database`: nessuna regola li vieta, quindi il valore non e' «invalido», e' **ignorato e
|
|
1846
|
+
* invisibile** — che e' peggio, perche' niente lo segnala e un cambio di destinazione lo puo'
|
|
1847
|
+
* rendere attivo di colpo. Far dipendere questa tabella dall'elenco dei codici diagnostici
|
|
1848
|
+
* accoppierebbe l'ispettore a un'altra regola di dominio ancora.
|
|
1849
|
+
*
|
|
1850
|
+
* `externalIdFieldName` dipende da `operation`, **non** da `target`: e' la condizione che il
|
|
1851
|
+
* backend applica (`Operation == Upsert`, richiesto li' e vietato altrove) ed e' la sola scritta
|
|
1852
|
+
* qui. Fino a LS9 la ripulitura ne usava una seconda, piu' larga (`Target == Database`): era
|
|
1853
|
+
* proprio la divergenza interna che questo file esiste per rendere impossibile.
|
|
1854
|
+
*
|
|
1855
|
+
* `failureHandling` e' vietato dal backend anche dentro un gruppo atomico, e qui non si dice: la
|
|
1856
|
+
* condizione di resa piu' larga fa comparire il controllo — con il rilievo sotto — invece di
|
|
1857
|
+
* nascondere un valore che l'autore dovrebbe poter togliere. Restringerla farebbe sparire il
|
|
1858
|
+
* controllo proprio dove serve.
|
|
1859
|
+
*/
|
|
1860
|
+
declare const DPE_WRITEBACK_CONDITIONS: {
|
|
1861
|
+
tableName: (node: WritebackNode) => boolean;
|
|
1862
|
+
operation: (node: WritebackNode) => boolean;
|
|
1863
|
+
externalIdFieldName: (node: WritebackNode) => boolean;
|
|
1864
|
+
onlyChangedRows: (node: WritebackNode) => boolean;
|
|
1865
|
+
processingGroupFieldName: (node: WritebackNode) => boolean;
|
|
1866
|
+
failureHandling: (node: WritebackNode) => boolean;
|
|
1867
|
+
jsonOptions: (node: WritebackNode) => boolean;
|
|
1868
|
+
csvOptions: (node: WritebackNode) => boolean;
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1223
1871
|
/**
|
|
1224
1872
|
* Il grafo della definizione: **un solo posto** costruisce gli id di nodi, porte e archi, e
|
|
1225
1873
|
* **un solo elenco** descrive dove vivono i riferimenti fra nodi.
|
|
@@ -1228,7 +1876,7 @@ declare class DpeCatalogStore {
|
|
|
1228
1876
|
* derivazione degli archi dall'altro) fa sparire un arco **senza nessun errore**: e' il
|
|
1229
1877
|
* difetto piu' difficile da trovare in un editor a canvas. Allo stesso modo, un riferimento
|
|
1230
1878
|
* dimenticato nell'elenco degli slot fa restare incoerente il documento dopo una rinomina,
|
|
1231
|
-
* anche
|
|
1879
|
+
* anche li' in silenzio.
|
|
1232
1880
|
*
|
|
1233
1881
|
* Cosa **non** sta qui: nessuna regola di dominio. Questo file dice *dove* stanno i nomi dei
|
|
1234
1882
|
* nodi a monte, non se un riferimento e' valido, se il grafo ha cicli (**I2**), se un nodo e'
|
|
@@ -1285,7 +1933,16 @@ interface DpeSourceSlot<TNode> {
|
|
|
1285
1933
|
read(node: TNode): readonly (string | undefined)[];
|
|
1286
1934
|
write(node: TNode, names: readonly (string | undefined)[]): TNode;
|
|
1287
1935
|
}
|
|
1288
|
-
/**
|
|
1936
|
+
/**
|
|
1937
|
+
* Gli slot di ogni collezione. Aggiungere un nodo significa aggiungere una riga qui.
|
|
1938
|
+
*
|
|
1939
|
+
* **Che ci sia una riga per ogni collezione lo garantisce il compilatore**, non un test: il tipo
|
|
1940
|
+
* e' mappato sull'unione `DpeNodeCollectionName`, quindi una collezione aggiunta al modello e
|
|
1941
|
+
* dimenticata qui ferma la build («Property '...' is missing»), e `DPE_NODE_COLLECTIONS`, con cui
|
|
1942
|
+
* il documento si cammina, e' a sua volta controllato totale. Il test che lo verificava a runtime
|
|
1943
|
+
* non poteva fallire, e per questo e' stato tolto: aggiungeva la convinzione di una copertura, non
|
|
1944
|
+
* la copertura.
|
|
1945
|
+
*/
|
|
1289
1946
|
declare const DPE_SOURCE_SLOTS: {
|
|
1290
1947
|
readonly [K in DpeNodeCollectionName]: readonly DpeSourceSlot<DpeNodeCollectionMap[K]>[];
|
|
1291
1948
|
};
|
|
@@ -1368,7 +2025,7 @@ declare function dpeWriteSourceReference<K extends DpeNodeCollectionName>(collec
|
|
|
1368
2025
|
* avere.
|
|
1369
2026
|
*
|
|
1370
2027
|
* Cosa **non** fa, di proposito: non rinomina gli **alias di colonna** (sono un altro spazio
|
|
1371
|
-
* di nomi) e non decide se il nuovo nome sia lecito o
|
|
2028
|
+
* di nomi) e non decide se il nuovo nome sia lecito o gia' usato — l'unicita' e' **I1**, la
|
|
1372
2029
|
* verifica il backend.
|
|
1373
2030
|
*
|
|
1374
2031
|
* Il confronto e' **esatto**, non case-insensitive: `domain-model.md` dichiara il confronto
|
|
@@ -1402,6 +2059,19 @@ declare function dpeCountReferences(definition: DpeDefinition, nodeName: string)
|
|
|
1402
2059
|
declare function dpeDiagnosticNodeName(diagnostic: Diagnostic, definition?: DpeDefinition): string | undefined;
|
|
1403
2060
|
/** Il campo in causa, per evidenziarlo nell'ispettore. */
|
|
1404
2061
|
declare function dpeDiagnosticField(diagnostic: Diagnostic): string | undefined;
|
|
2062
|
+
/**
|
|
2063
|
+
* La diagnostica riguarda **quella riga** di una collezione dentro il nodo, e quel campo.
|
|
2064
|
+
*
|
|
2065
|
+
* Serve dove un nodo ha piu' righe con lo stesso nome di campo — il caso reale sono le colonne
|
|
2066
|
+
* calcolate di una trasformazione, che hanno tutte un `expression`. Filtrare per solo nome di
|
|
2067
|
+
* campo, come fa `issuesOn`, mostrerebbe l'errore della prima formula sotto la terza: il rilievo
|
|
2068
|
+
* arriva accanto a un testo che non lo ha prodotto, ed e' peggio di non mostrarlo.
|
|
2069
|
+
*
|
|
2070
|
+
* Il confronto e' sul segmento del percorso che nomina la collezione, ovunque stia: `contracts.md`
|
|
2071
|
+
* §1 pubblica il percorso in **due** forme (col nome del nodo dalla validazione, col solo indice
|
|
2072
|
+
* dalla deserializzazione), e in entrambe il segmento della riga porta l'indice.
|
|
2073
|
+
*/
|
|
2074
|
+
declare function dpeDiagnosticTargetsItem(diagnostic: Diagnostic, collection: string, index: number, field: string): boolean;
|
|
1405
2075
|
/**
|
|
1406
2076
|
* `true` per l'unico codice che significa "hai fatto bene, siamo noi" (**I10**, ADR 0005):
|
|
1407
2077
|
* `Forecast`, `CustomNode`, costrutto non supportato dal dialetto scelto. Non va mescolato
|
|
@@ -1695,6 +2365,326 @@ declare class DpeDocumentStore {
|
|
|
1695
2365
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DpeDocumentStore>;
|
|
1696
2366
|
}
|
|
1697
2367
|
|
|
2368
|
+
/**
|
|
2369
|
+
* La lettura dei **tre esiti** del catalogo delle formule — `contracts.md` §7, normativo.
|
|
2370
|
+
*
|
|
2371
|
+
* Sta in una funzione pura e non in un `if` dentro un componente per la ragione che ha reso questo
|
|
2372
|
+
* lotto necessario: la versione precedente del contratto consegnava il catalogo **nudo**, quindi i
|
|
2373
|
+
* tre esiti del service ne diventavano due, e *dialetto non coperto* e *backend rotto* arrivavano
|
|
2374
|
+
* a schermo identici. Un degrado silenzioso non si vede rileggendo un componente; si vede
|
|
2375
|
+
* scrivendo una tabella e provandola.
|
|
2376
|
+
*
|
|
2377
|
+
* **Il discriminante e' `diagnostics`, non `catalog`.** E' la riga che vale piu' di tutte le
|
|
2378
|
+
* altre, perche' la stesura precedente diceva il contrario: con `ProvidesCatalog == false` il
|
|
2379
|
+
* catalogo arriva **presente e vuoto**, con il nome del linguaggio e zero diagnostiche — quindi
|
|
2380
|
+
* un editor che ramasse su `catalog == null` non entrerebbe mai in quel caso, e mostrerebbe un
|
|
2381
|
+
* fallimento dove non c'e' niente da segnalare.
|
|
2382
|
+
*
|
|
2383
|
+
* `catalog` nullo o assente significa **una cosa sola: non e' stato prodotto**.
|
|
2384
|
+
*/
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* I quattro stati in cui il campo formula puo' trovarsi rispetto al catalogo — tre del contratto
|
|
2388
|
+
* piu' «non lo so ancora», che e' quello in cui il campo nasce.
|
|
2389
|
+
*
|
|
2390
|
+
* Unione discriminata e non un oggetto con quattro campi opzionali: cosi' «fallito **e** con
|
|
2391
|
+
* tavolozza» non e' rappresentabile, e chi rende non deve decidere quale dei due vince.
|
|
2392
|
+
*/
|
|
2393
|
+
type DpeFormulaCatalogOutcome =
|
|
2394
|
+
/** Nessuna risposta conservata: non e' stato chiesto, e' in volo, o la richiesta e' fallita. */
|
|
2395
|
+
{
|
|
2396
|
+
readonly kind: 'Unknown';
|
|
2397
|
+
}
|
|
2398
|
+
/** Catalogo consegnato **con contenuto**: si mostra la tavolozza. */
|
|
2399
|
+
| {
|
|
2400
|
+
readonly kind: 'Palette';
|
|
2401
|
+
readonly catalog: DpeFormulaCatalog;
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Catalogo consegnato **vuoto** e nessuna diagnostica: il compilatore non descrive il proprio
|
|
2405
|
+
* linguaggio, che non e' un errore. Niente tavolozza e **nessun rumore**; `languageName` c'e' ed
|
|
2406
|
+
* e' l'unica cosa da mostrare — e l'etichetta del campo la prende comunque dall'ambiente.
|
|
2407
|
+
*/
|
|
2408
|
+
| {
|
|
2409
|
+
readonly kind: 'Silent';
|
|
2410
|
+
readonly languageName?: string;
|
|
2411
|
+
}
|
|
2412
|
+
/**
|
|
2413
|
+
* Diagnostiche non vuote: il catalogo non e' stato prodotto e **il perche' si mostra**.
|
|
2414
|
+
*
|
|
2415
|
+
* `lead` e' la riga in testa, `details` tutto il resto **nell'ordine ricevuto**. La separazione
|
|
2416
|
+
* non e' estetica: il sacco strutturale riguarda l'intera definizione e puo' contenere voci che
|
|
2417
|
+
* con il nodo richiesto non c'entrano, filtrarle per pertinenza non e' affidabile (l'errore che
|
|
2418
|
+
* spiega lo schema puo' stare a piu' salti di distanza), quindi il rimedio dichiarato e' una
|
|
2419
|
+
* riga in testa e il resto come dettaglio.
|
|
2420
|
+
*/
|
|
2421
|
+
| {
|
|
2422
|
+
readonly kind: 'Failed';
|
|
2423
|
+
readonly lead: Diagnostic;
|
|
2424
|
+
readonly details: readonly Diagnostic[];
|
|
2425
|
+
readonly hasError: boolean;
|
|
2426
|
+
};
|
|
2427
|
+
/**
|
|
2428
|
+
* Legge l'involucro e dice in quale dei quattro stati ci si trova.
|
|
2429
|
+
*
|
|
2430
|
+
* L'ordine dei controlli e' il contratto messo in fila, e non e' intercambiabile:
|
|
2431
|
+
*
|
|
2432
|
+
* 1. nessun risultato -> `Unknown`;
|
|
2433
|
+
* 2. **diagnostiche non vuote** -> `Failed`, indipendentemente da `catalog`;
|
|
2434
|
+
* 3. catalogo con contenuto -> `Palette`;
|
|
2435
|
+
* 4. tutto il resto -> `Silent`, cioe' niente tavolozza e nessun rumore.
|
|
2436
|
+
*
|
|
2437
|
+
* Il quarto ramo assorbe anche il caso fuori contratto «nessun catalogo e nessuna diagnostica»:
|
|
2438
|
+
* a schermo e' indistinguibile dal terzo esito — niente da mostrare e niente da segnalare — e
|
|
2439
|
+
* inventare un quinto stato per rimproverare il backend darebbe all'utente un messaggio su cui non
|
|
2440
|
+
* puo' agire.
|
|
2441
|
+
*/
|
|
2442
|
+
declare function dpeFormulaCatalogOutcome(result: DpeFormulaCatalogResult | undefined): DpeFormulaCatalogOutcome;
|
|
2443
|
+
/**
|
|
2444
|
+
* L'etichetta con cui si nomina all'utente la forma pretesa dal campo.
|
|
2445
|
+
*
|
|
2446
|
+
* E' **traduzione**, non deduzione: la forma arriva dal backend, qui si sceglie solo come
|
|
2447
|
+
* chiamarla in italiano. Dedurla dal tipo di nodo sarebbe la regola di dominio che il contratto
|
|
2448
|
+
* vieta, e la differenza fra le due cose e' tutta in questa riga.
|
|
2449
|
+
*/
|
|
2450
|
+
declare function dpeExpressionFormLabel(form: DpeExpressionForm | null | undefined): string | undefined;
|
|
2451
|
+
/**
|
|
2452
|
+
* La stessa cosa detta all'utente: «serve un valore», «serve una funzione di finestra».
|
|
2453
|
+
*
|
|
2454
|
+
* Esiste separata dall'etichetta nuda per una ragione banale e reale: **l'articolo dipende dal
|
|
2455
|
+
* genere**, e comporre «serve un » + etichetta nel template produce «serve un funzione di
|
|
2456
|
+
* finestra». Il template non puo' sapere il genere di una parola, questa funzione si'.
|
|
2457
|
+
*/
|
|
2458
|
+
declare function dpeExpressionFormPrompt(form: DpeExpressionForm | null | undefined): string | undefined;
|
|
2459
|
+
/**
|
|
2460
|
+
* L'incrocio fra **la forma richiesta dal nodo** e **le forme che il compilatore sa compilare**.
|
|
2461
|
+
*
|
|
2462
|
+
* E' la meta' «disabilitare» della funzione che il contratto prescriveva: la meta' «mostrare» —
|
|
2463
|
+
* la pastiglia «serve una funzione di finestra» — era implementabile da LF6, perche' il primo
|
|
2464
|
+
* operando arriva con il catalogo; il secondo non stava sul filo, e senza di esso l'editor poteva
|
|
2465
|
+
* solo dire cosa serve, mai che non si potra' avere.
|
|
2466
|
+
*
|
|
2467
|
+
* Stessa forma di `DpeCommandAvailability` (`dpe-capabilities.ts`) e per la stessa ragione: un
|
|
2468
|
+
* campo spento che non dice perche' manda a cercare un guasto che non c'e'.
|
|
2469
|
+
*/
|
|
2470
|
+
interface DpeExpressionFormSupport {
|
|
2471
|
+
readonly isSupported: boolean;
|
|
2472
|
+
/** Presente **solo** quando la forma non e' supportata. E' il testo che il campo mostra. */
|
|
2473
|
+
readonly reason?: string;
|
|
2474
|
+
}
|
|
2475
|
+
/**
|
|
2476
|
+
* Decide se il campo formula si disabilita, e con quale motivo.
|
|
2477
|
+
*
|
|
2478
|
+
* Le tre regole, in quest'ordine e non intercambiabili:
|
|
2479
|
+
*
|
|
2480
|
+
* 1. **forma richiesta assente** -> supportato: il nodo non ospita formule, o la prima validazione
|
|
2481
|
+
* non e' ancora arrivata. Non c'e' niente da incrociare;
|
|
2482
|
+
* 2. **forme supportate non dichiarate** (`undefined` o `null`) -> supportato. E' la politica del
|
|
2483
|
+
* contratto: assente significa **non si disabilita niente**. Un ospite che non dichiara le
|
|
2484
|
+
* capacita' del proprio compilatore non autorizza l'editor a indovinarle, e un campo spento per
|
|
2485
|
+
* ignoranza toglie all'utente l'unica cosa che avrebbe: provare e leggere la risposta del
|
|
2486
|
+
* backend;
|
|
2487
|
+
* 3. **dichiarate e la forma non c'e'** -> non supportato. Un elenco **vuoto** entra qui, e ci
|
|
2488
|
+
* entra di proposito: vuoto non e' assente, e' un compilatore che dichiara di non compilare
|
|
2489
|
+
* nessuna forma.
|
|
2490
|
+
*
|
|
2491
|
+
* Nessuna di queste e' una regola di dominio: la forma la dice il backend, le capacita' pure.
|
|
2492
|
+
* Questa funzione fa solo l'intersezione e sceglie le parole italiane.
|
|
2493
|
+
*/
|
|
2494
|
+
declare function dpeExpressionFormSupport(requiredForm: DpeExpressionForm | null | undefined, supportedForms: readonly DpeExpressionForm[] | null | undefined): DpeExpressionFormSupport;
|
|
2495
|
+
/** Quante voci porta un catalogo. Zero e' l'esito «il compilatore non si descrive», non un guasto. */
|
|
2496
|
+
declare function dpeFormulaCatalogSize(catalog: DpeFormulaCatalog): number;
|
|
2497
|
+
|
|
2498
|
+
/**
|
|
2499
|
+
* Il catalogo del linguaggio di formule, **conservato per nodo** — `frontend.md` §5-quater,
|
|
2500
|
+
* normativo.
|
|
2501
|
+
*
|
|
2502
|
+
* `getFormulaCatalog` non e' una chiamata leggera: lato libreria costa una passata completa di
|
|
2503
|
+
* grafo e di propagazione, e interroga il provider di metadati per **tutti** i datasource della
|
|
2504
|
+
* definizione, non solo per il cono a monte del nodo. Chiederlo a ogni apertura di un campo formula
|
|
2505
|
+
* e' il modo naturale di scriverlo e quello sbagliato, e non lascia traccia: non fallisce, si
|
|
2506
|
+
* limita a far pagare al backend N volte una risposta che non e' cambiata.
|
|
2507
|
+
*
|
|
2508
|
+
* Quindi: **una volta per nodo**, conservato, e invalidato quando cambia cio' che puo' cambiarne il
|
|
2509
|
+
* contenuto.
|
|
2510
|
+
*
|
|
2511
|
+
* Cosa questo store **non** fa, e non e' una dimenticanza:
|
|
2512
|
+
*
|
|
2513
|
+
* - **non valida niente.** Il catalogo dice cosa esiste, non se cio' che l'utente ha scritto va
|
|
2514
|
+
* bene. La grammatica e' del compilatore dell'ospite, il frontend non la conosce e non puo'
|
|
2515
|
+
* conoscerla: nessuna validazione di formula viene scritta in TypeScript, per nessun motivo
|
|
2516
|
+
* (ADR 0031/0036, `contracts.md` §7);
|
|
2517
|
+
* - **non decide il nome del linguaggio.** Quello e' `DpeEnvironment.expressionLanguage`, e arriva
|
|
2518
|
+
* anche quando il catalogo non arriva — che e' il caso piu' importante dei due, perche' un
|
|
2519
|
+
* dialetto fuori da `SupportedDialects` rende il catalogo nullo (ADR 0031 §5) proprio mentre
|
|
2520
|
+
* l'utente ha ancora bisogno di sapere in che lingua sta scrivendo;
|
|
2521
|
+
* - **non chiama se non deve.** Servono due cose: la primitiva **sovrascritta e non dichiarata non
|
|
2522
|
+
* servita** (`dpe-capabilities.ts`) e il compilatore che dichiara di descrivere il proprio
|
|
2523
|
+
* linguaggio (`providesFormulaCatalog`). Un compilatore laconico risponde un catalogo vuoto, che
|
|
2524
|
+
* e' legittimo (ADR 0036 §5): farsi pagare una passata di grafo per riceverlo e' spreco puro.
|
|
2525
|
+
*
|
|
2526
|
+
* Provider del **componente radice** come gli altri store: due editor sulla stessa pagina hanno due
|
|
2527
|
+
* documenti, quindi due cache.
|
|
2528
|
+
*/
|
|
2529
|
+
|
|
2530
|
+
/**
|
|
2531
|
+
* L'impronta di cio' che puo' cambiare una risposta di `getFormulaCatalog`: **il nome del
|
|
2532
|
+
* documento** e **gli schemi che il backend ha propagato**.
|
|
2533
|
+
*
|
|
2534
|
+
* Le due parti corrispondono a cio' che la risposta contiene, e nessuna e' un indovinello: i
|
|
2535
|
+
* simboli `Column` *sono* le colonne che quel nodo vede, e quali siano lo decide la propagazione
|
|
2536
|
+
* dello schema, che e' del backend (**I4**). Qualunque altra impronta — «e' cambiata la topologia»,
|
|
2537
|
+
* «e' cambiato un alias di sorgente» — richiederebbe di sapere *quali* modifiche cambiano uno
|
|
2538
|
+
* schema, cioe' di riscrivere I4 in TypeScript.
|
|
2539
|
+
*
|
|
2540
|
+
* Conseguenza voluta, ed e' la ragione per cui questa funzione e' pura e verificabile: scrivere
|
|
2541
|
+
* nel testo di una formula **non** cambia l'impronta, quindi non invalida nulla. Rinominare un
|
|
2542
|
+
* alias a monte la cambia, e il catalogo si rilegge alla prossima apertura del nodo.
|
|
2543
|
+
*
|
|
2544
|
+
* Il nome del documento entra perche' prima della prima validazione gli schemi sono vuoti: senza
|
|
2545
|
+
* di esso due documenti diversi appena aperti avrebbero la stessa impronta, e il secondo
|
|
2546
|
+
* erediterebbe il catalogo del primo.
|
|
2547
|
+
*
|
|
2548
|
+
* **Qui c'era una terza parte, la forma dei nodi, e non c'e' piu'.** Era entrata quando la risposta
|
|
2549
|
+
* portava `requiredForm`, che dipende dal tipo del nodo mentre lo schema in uscita no: cambiare una
|
|
2550
|
+
* trasformazione da `Expression` a `ComputeRelative` lasciava l'impronta identica e la pastiglia
|
|
2551
|
+
* diceva la forma vecchia. Ora la forma arriva con la validazione e non con questa risposta, e
|
|
2552
|
+
* l'ingresso non esiste piu': misurato sui due lati, il contratto — il compilatore riceve
|
|
2553
|
+
* `DpeExpressionCatalogRequest`, cioe' **dialetto, colonne a monte e parametri**, e non il tipo del
|
|
2554
|
+
* nodo — e il browser, dove lo stesso nodo prima e dopo il cambio di tipo riceve un catalogo
|
|
2555
|
+
* identico (le stesse 32 voci). Toglierla non e' una semplificazione: e' non pagare una richiesta
|
|
2556
|
+
* per una risposta che non puo' essere cambiata.
|
|
2557
|
+
*
|
|
2558
|
+
* **Due ingressi restano scoperti, e sono scoperti da sempre:** il `dialect` e i `parameters` della
|
|
2559
|
+
* definizione, che pure entrano nella richiesta al compilatore. Oggi nessuno dei due si puo'
|
|
2560
|
+
* modificare a documento aperto — l'editor non li scrive, e caricarne un altro azzera gli schemi,
|
|
2561
|
+
* quindi l'impronta si muove lo stesso. Il giorno in cui compare un editor dei parametri, il posto
|
|
2562
|
+
* da cui ripartire e' questo.
|
|
2563
|
+
*/
|
|
2564
|
+
declare function dpeFormulaCatalogSignature(definitionName: string, schemas: readonly DpeNodeSchemaInfo[]): string;
|
|
2565
|
+
declare class DpeFormulaCatalogStore {
|
|
2566
|
+
private readonly api;
|
|
2567
|
+
private readonly document;
|
|
2568
|
+
/**
|
|
2569
|
+
* La dichiarazione dell'ambiente si chiede **una volta all'apertura**, e chi la chiede e'
|
|
2570
|
+
* `DpeValidationService`. Rileggerla da qui sarebbe un secondo `getEnvironment` per la stessa
|
|
2571
|
+
* risposta — e per giunta due risposte che possono arrivare in ordine diverso.
|
|
2572
|
+
*/
|
|
2573
|
+
private readonly validation;
|
|
2574
|
+
private readonly capabilities;
|
|
2575
|
+
private readonly _byNode;
|
|
2576
|
+
private readonly _pending;
|
|
2577
|
+
/**
|
|
2578
|
+
* Il nodo di cui si vuole il catalogo — **uno**, quello aperto.
|
|
2579
|
+
*
|
|
2580
|
+
* Esiste per un difetto trovato nel browser e non da nessun test: la disponibilita' dipende da
|
|
2581
|
+
* `getEnvironment`, che e' una chiamata di rete, e chi apre un nodo subito dopo aver aperto
|
|
2582
|
+
* l'editor chiede il catalogo **prima** che l'ambiente abbia risposto. La richiesta cadeva nel
|
|
2583
|
+
* vuoto e non veniva piu' ripetuta, perche' l'apertura del nodo era l'unico innesco: il campo
|
|
2584
|
+
* restava senza catalogo per sempre, senza errori, e riaprire lo stesso nodo non cambiava
|
|
2585
|
+
* niente. Tenere qui **l'intenzione** invece di agire subito la rende ripetibile quando la
|
|
2586
|
+
* condizione che mancava si verifica.
|
|
2587
|
+
*/
|
|
2588
|
+
private readonly _wanted;
|
|
2589
|
+
/**
|
|
2590
|
+
* Il catalogo si puo' chiedere: primitiva disponibile **e** compilatore che dichiara di
|
|
2591
|
+
* descrivere il proprio linguaggio. Le due meta' restano separate perche' sono due fatti
|
|
2592
|
+
* diversi — il trasporto e il compilatore — e un solo booleano non permetterebbe di capire
|
|
2593
|
+
* quale dei due manca.
|
|
2594
|
+
*/
|
|
2595
|
+
readonly isAvailable: Signal<boolean>;
|
|
2596
|
+
/**
|
|
2597
|
+
* L'impronta corrente: cambia quando cambia cio' che puo' cambiare una risposta, cioe' gli
|
|
2598
|
+
* **schemi** che il backend ha propagato — sono loro a decidere i simboli.
|
|
2599
|
+
*
|
|
2600
|
+
* Legge il documento, e va bene: il valore prodotto e' una stringa, e a parita' di stringa un
|
|
2601
|
+
* `computed` non notifica nessuno. Scrivere in una formula ricalcola l'impronta e non muove
|
|
2602
|
+
* niente — cioe' nessuna richiesta a ogni battitura, che resta la regola di `frontend.md`
|
|
2603
|
+
* §5-quater.
|
|
2604
|
+
*/
|
|
2605
|
+
readonly signature: Signal<string>;
|
|
2606
|
+
/**
|
|
2607
|
+
* La prima validazione e' tornata, cioe' **gli schemi si conoscono**.
|
|
2608
|
+
*
|
|
2609
|
+
* Prima di allora il catalogo non si chiede, e non e' prudenza: i simboli `Column` sono le colonne
|
|
2610
|
+
* che il nodo vede, e chiederli quando gli schemi non sono ancora arrivati significa ricevere una
|
|
2611
|
+
* risposta che l'istante dopo e' scaduta — cioe' **due** chiamate per la stessa apertura, dove
|
|
2612
|
+
* ogni chiamata costa al backend una passata completa di grafo e di metadati. Misurato: aprire un
|
|
2613
|
+
* nodo subito dopo l'editor faceva salire il contatore di due.
|
|
2614
|
+
*/
|
|
2615
|
+
private readonly hasValidated;
|
|
2616
|
+
/**
|
|
2617
|
+
* L'**involucro** noto per un nodo, se e' stato ottenuto con l'impronta corrente.
|
|
2618
|
+
*
|
|
2619
|
+
* Legge i signal, quindi si usa dentro un `computed` e resta reattivo — lo stesso schema di
|
|
2620
|
+
* `DpeMetadataStore.stateOf`.
|
|
2621
|
+
*
|
|
2622
|
+
* **Scade con l'impronta**: un catalogo ottenuto quando gli schemi erano altri non si restituisce
|
|
2623
|
+
* come se fosse attuale — dichiarerebbe disponibili simboli che non esistono piu'. Finche' il nodo
|
|
2624
|
+
* resta quello aperto, l'effect del costruttore ne chiede subito uno nuovo, quindi la scadenza si
|
|
2625
|
+
* vede al piu' come una sparizione momentanea del conteggio, non come un campo che resta muto.
|
|
2626
|
+
*
|
|
2627
|
+
* Scade anche l'esito d'errore, ed e' giusto: un `DPE_CATALOG_UNAVAILABLE` nasce da uno schema
|
|
2628
|
+
* che non si risolve, e cambiare gli schemi e' esattamente cio' che puo' averlo risolto.
|
|
2629
|
+
*/
|
|
2630
|
+
resultOf(nodeName: string): DpeFormulaCatalogResult | undefined;
|
|
2631
|
+
/**
|
|
2632
|
+
* Il catalogo consegnato, **quando e' stato prodotto**. Puo' legittimamente essere vuoto: chi
|
|
2633
|
+
* rende non deve confondere «vuoto» con «assente», e per questo la decisione di cosa mostrare
|
|
2634
|
+
* passa da `outcomeOf` e non da qui.
|
|
2635
|
+
*/
|
|
2636
|
+
catalogOf(nodeName: string): DpeFormulaCatalog | undefined;
|
|
2637
|
+
/**
|
|
2638
|
+
* Quale dei tre esiti del contratto si sta guardando — piu' «non lo so ancora».
|
|
2639
|
+
*
|
|
2640
|
+
* E' cio' che i componenti consumano: la tricotomia si legge **una volta**, in una funzione
|
|
2641
|
+
* pura, e non si riscrive in ogni ispettore con un `if` leggermente diverso.
|
|
2642
|
+
*/
|
|
2643
|
+
outcomeOf(nodeName: string): DpeFormulaCatalogOutcome;
|
|
2644
|
+
/** Una richiesta per questo nodo e' in volo: lo stato di attesa si mostra sempre. */
|
|
2645
|
+
isLoading(nodeName: string): boolean;
|
|
2646
|
+
constructor();
|
|
2647
|
+
/**
|
|
2648
|
+
* Chiede il catalogo per un nodo, **se serve**. Idempotente: chiamarla a ogni apertura della
|
|
2649
|
+
* finestra non produce chiamate, chiamarla in un ciclo nemmeno.
|
|
2650
|
+
*
|
|
2651
|
+
* Fa **due** cose, e servono entrambe:
|
|
2652
|
+
*
|
|
2653
|
+
* 1. prova subito, sotto `untracked`, cosi' l'esito e' immediato quando le condizioni ci sono
|
|
2654
|
+
* gia'. Affidarsi al solo `_wanted` non basterebbe: riaperto lo **stesso** nodo il signal non
|
|
2655
|
+
* cambia valore e l'effect non riparte;
|
|
2656
|
+
* 2. registra l'intenzione in `_wanted`, cosi' quando cambia una delle condizioni che mancavano
|
|
2657
|
+
* — la disponibilita' dell'ambiente, l'impronta degli schemi — la richiesta viene onorata
|
|
2658
|
+
* senza che l'utente debba riaprire il nodo.
|
|
2659
|
+
*
|
|
2660
|
+
* **Ogni lettura di signal e' in `untracked`**, e non e' prudenza: i chiamanti sono `effect` degli
|
|
2661
|
+
* ispettori, e un `this.document.definition()` letto qui diventerebbe una dipendenza di
|
|
2662
|
+
* quell'effect — cioe' una richiesta di catalogo **a ogni battitura**, che e' il difetto che
|
|
2663
|
+
* questo store esiste per evitare. Il sintomo non sarebbe un errore: sarebbe un backend che
|
|
2664
|
+
* macina grafi mentre qualcuno scrive.
|
|
2665
|
+
*/
|
|
2666
|
+
requestFor(nodeName: string): void;
|
|
2667
|
+
/**
|
|
2668
|
+
* La chiamata, **se serve davvero**: non c'e' gia' una richiesta in volo per quel nodo, e cio'
|
|
2669
|
+
* che e' in cache non e' stato ottenuto con l'impronta corrente.
|
|
2670
|
+
*
|
|
2671
|
+
* Tutte le letture stanno sotto `untracked` da parte dei chiamanti: sono signal, e legarli
|
|
2672
|
+
* all'effect vorrebbe dire rileggere il catalogo a ogni modifica del documento.
|
|
2673
|
+
*/
|
|
2674
|
+
private fetchIfNeeded;
|
|
2675
|
+
/**
|
|
2676
|
+
* Rilettura forzata, per chi vuole il catalogo aggiornato senza aspettare un cambio di impronta.
|
|
2677
|
+
* Non ha un consumatore nell'editor di oggi ed esiste perche' una cache senza modo di essere
|
|
2678
|
+
* invalidata a mano e' una cache che prima o poi si aggira con un ricaricamento della pagina.
|
|
2679
|
+
*/
|
|
2680
|
+
refresh(nodeName: string): void;
|
|
2681
|
+
private fetch;
|
|
2682
|
+
private put;
|
|
2683
|
+
private setPending;
|
|
2684
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DpeFormulaCatalogStore, never>;
|
|
2685
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DpeFormulaCatalogStore>;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
1698
2688
|
interface DpeLayoutNodeInput {
|
|
1699
2689
|
name: string;
|
|
1700
2690
|
width: number;
|
|
@@ -1749,7 +2739,7 @@ declare class DpeMetadataStore {
|
|
|
1749
2739
|
readonly isLoadingTables: _angular_core.Signal<boolean>;
|
|
1750
2740
|
/** Idempotente: la prima chiamata carica, le successive non fanno nulla. */
|
|
1751
2741
|
loadTables(): void;
|
|
1752
|
-
/** Stato noto di una tabella, se
|
|
2742
|
+
/** Stato noto di una tabella, se gia' richiesta. */
|
|
1753
2743
|
stateOf(tableName: string): DpeTableState | undefined;
|
|
1754
2744
|
/** Chiede la descrizione di una tabella una sola volta per nome. */
|
|
1755
2745
|
describe(tableName: string): void;
|
|
@@ -1793,6 +2783,12 @@ interface DpeNodeCategory {
|
|
|
1793
2783
|
*/
|
|
1794
2784
|
isNotCompilableInV1: boolean;
|
|
1795
2785
|
}
|
|
2786
|
+
/**
|
|
2787
|
+
* Le categorie nell'ordine di `DPE_NODE_COLLECTIONS`, che e' l'ordine della palette. **Derivate,
|
|
2788
|
+
* non riscritte**: l'ordine vive in un posto solo — il modello, dove un controllo di tipo lo tiene
|
|
2789
|
+
* totale e senza ripetizioni — e la collezione di ogni categoria e' la stessa variabile con cui se
|
|
2790
|
+
* ne legge la voce, quindi chiave e campo non hanno modo di divergere.
|
|
2791
|
+
*/
|
|
1796
2792
|
declare const DPE_NODE_CATEGORIES: readonly DpeNodeCategory[];
|
|
1797
2793
|
declare function dpeNodeCategory(collection: DpeNodeCollectionName): DpeNodeCategory;
|
|
1798
2794
|
/** Nomi dei dialetti per il selettore. La libreria conosce **solo** il nome (ADR 0009). */
|
|
@@ -1843,7 +2839,7 @@ declare function dpeNodeIconPaths(collection: DpeNodeCollectionName): readonly s
|
|
|
1843
2839
|
* Tutto il resto lo compila l'utente nell'ispettore, e cosa sia obbligatorio lo dice il
|
|
1844
2840
|
* backend.
|
|
1845
2841
|
*
|
|
1846
|
-
* Il nome candidato e' unico rispetto ai nomi
|
|
2842
|
+
* Il nome candidato e' unico rispetto ai nomi gia' presenti con confronto **esatto**
|
|
1847
2843
|
* (`contracts.md` §2: unicita' verificata `OrdinalIgnoreCase`, risoluzione `Ordinal`). Qui il
|
|
1848
2844
|
* confronto e' insensibile al caso di proposito: proporre `Filtro2` accanto a un `filtro2`
|
|
1849
2845
|
* esistente creerebbe un `DPE_MODEL_NAME_DUPLICATE` a nome dell'editor, non dell'utente.
|
|
@@ -1893,6 +2889,30 @@ declare class DpeValidationService {
|
|
|
1893
2889
|
* questo che i due si tengono separati: il confronto e' l'unica cosa che l'editor puo' dire.
|
|
1894
2890
|
*/
|
|
1895
2891
|
private readonly _environmentDialect;
|
|
2892
|
+
/**
|
|
2893
|
+
* Il nome del **linguaggio di formule** dichiarato dall'ambiente (ADR 0031/0036). Serve
|
|
2894
|
+
* all'etichetta del campo espressione, e arriva da qui e non dal catalogo per una ragione
|
|
2895
|
+
* precisa: il catalogo puo' essere assente o nullo — compilatore che non descrive il proprio
|
|
2896
|
+
* linguaggio, dialetto non coperto — mentre il nome del linguaggio si sa sempre. Letto dal
|
|
2897
|
+
* catalogo, l'editor resterebbe muto proprio nei casi in cui serve.
|
|
2898
|
+
*/
|
|
2899
|
+
private readonly _expressionLanguage;
|
|
2900
|
+
/** Il compilatore descrive il proprio linguaggio: se no, `getFormulaCatalog` non si chiama. */
|
|
2901
|
+
private readonly _providesFormulaCatalog;
|
|
2902
|
+
/**
|
|
2903
|
+
* Le forme che il compilatore registrato sa produrre (ADR 0031), dall'ambiente. E' il **secondo
|
|
2904
|
+
* operando** dell'incrocio che disabilita un campo formula incompilabile; il primo,
|
|
2905
|
+
* `requiredForm`, e' per nodo e arriva con la **validazione**, su `DpeNodeSchemaInfo`.
|
|
2906
|
+
*
|
|
2907
|
+
* I due arrivano da due chiamate diverse, ed e' la ragione per cui questo campo sta qui: le forme
|
|
2908
|
+
* supportate sono dell'**installazione** e si chiedono una volta all'apertura, la forma richiesta
|
|
2909
|
+
* e' del **nodo** e si aggiorna a ogni validazione.
|
|
2910
|
+
*
|
|
2911
|
+
* `undefined` non e' «nessuna forma», e' «non dichiarate», e non disabilita niente: la
|
|
2912
|
+
* distinzione e' tutta la politica del contratto e per questo non si normalizza qui in un
|
|
2913
|
+
* elenco vuoto, che direbbe l'opposto.
|
|
2914
|
+
*/
|
|
2915
|
+
private readonly _supportedForms;
|
|
1896
2916
|
readonly isValidating: _angular_core.Signal<boolean>;
|
|
1897
2917
|
readonly isCompiling: _angular_core.Signal<boolean>;
|
|
1898
2918
|
readonly error: _angular_core.Signal<DpeApiError | undefined>;
|
|
@@ -1902,6 +2922,9 @@ declare class DpeValidationService {
|
|
|
1902
2922
|
readonly justSaved: _angular_core.Signal<boolean>;
|
|
1903
2923
|
readonly saveError: _angular_core.Signal<DpeApiError | undefined>;
|
|
1904
2924
|
readonly environmentDialect: _angular_core.Signal<SqlDialectKind | undefined>;
|
|
2925
|
+
readonly expressionLanguage: _angular_core.Signal<string | undefined>;
|
|
2926
|
+
readonly providesFormulaCatalog: _angular_core.Signal<boolean>;
|
|
2927
|
+
readonly supportedForms: _angular_core.Signal<readonly DpeExpressionForm[] | undefined>;
|
|
1905
2928
|
/** Vero finche' non e' arrivata la prima risposta: la UI non deve dire "nessun problema". */
|
|
1906
2929
|
readonly hasResult: _angular_core.Signal<boolean>;
|
|
1907
2930
|
constructor();
|
|
@@ -1983,8 +3006,9 @@ declare class DpeBuilderComponent {
|
|
|
1983
3006
|
protected readonly dialect: Signal<SqlDialectKind>;
|
|
1984
3007
|
/**
|
|
1985
3008
|
* Disallineamento fra cio' che l'ambiente dichiara e cio' che la definizione porta. Si
|
|
1986
|
-
* **segnala** e non si corregge: correggere vorrebbe dire
|
|
1987
|
-
*
|
|
3009
|
+
* **segnala** e non si corregge: correggere vorrebbe dire cambiare le capacita' con cui la
|
|
3010
|
+
* definizione verra' compilata, che e' dell'host. Assente `getEnvironment`, non c'e' niente da
|
|
3011
|
+
* confrontare.
|
|
1988
3012
|
*/
|
|
1989
3013
|
protected readonly dialectMismatch: Signal<SqlDialectKind | undefined>;
|
|
1990
3014
|
/**
|
|
@@ -2138,7 +3162,18 @@ interface DpeCanvasNode {
|
|
|
2138
3162
|
* colore proprio. Sono due situazioni diverse e l'utente deve capire subito quale guarda.
|
|
2139
3163
|
*/
|
|
2140
3164
|
isNotCompilable: boolean;
|
|
2141
|
-
/**
|
|
3165
|
+
/**
|
|
3166
|
+
* Numero di colonne dello schema di uscita. `null` significa **nessuna pastiglia**, e ci sono
|
|
3167
|
+
* due modi di arrivarci:
|
|
3168
|
+
*
|
|
3169
|
+
* - il backend non ha dichiarato di aver derivato lo schema (`hasSchema`, ADR 0041): un «0 col.»
|
|
3170
|
+
* sarebbe un'affermazione che nessuno ha fatto;
|
|
3171
|
+
* - il nodo e' un **pozzo**: il conteggio risponde a «cosa esce di qui», e da un pozzo non esce
|
|
3172
|
+
* niente. Lo zero e' vero — e' la condizione normale di ogni writeback — ed e' la risposta a
|
|
3173
|
+
* una domanda che non si pone.
|
|
3174
|
+
*
|
|
3175
|
+
* Sui nodi **non** pozzo lo zero si mostra: li' significa `DPE_SCHEMA_EMPTY`, che e' un errore.
|
|
3176
|
+
*/
|
|
2142
3177
|
columnCount: number | null;
|
|
2143
3178
|
}
|
|
2144
3179
|
interface DpeCanvasEdge {
|
|
@@ -2227,7 +3262,7 @@ declare class DpeCanvasComponent {
|
|
|
2227
3262
|
sourceId: string;
|
|
2228
3263
|
targetId?: string;
|
|
2229
3264
|
}): void;
|
|
2230
|
-
/** Riassegnazione di un arco
|
|
3265
|
+
/** Riassegnazione di un arco gia' disegnato, da un capo o dall'altro. */
|
|
2231
3266
|
onReassignConnection(event: {
|
|
2232
3267
|
endpoint: string;
|
|
2233
3268
|
previousSourceId: string;
|
|
@@ -2260,9 +3295,13 @@ declare class DpeCanvasComponent {
|
|
|
2260
3295
|
nodeIds: string[];
|
|
2261
3296
|
}): void;
|
|
2262
3297
|
/**
|
|
2263
|
-
* Rilascio di una voce trascinata dalla palette. `externalItemRect` e'
|
|
3298
|
+
* Rilascio di una voce trascinata dalla palette. `externalItemRect` e' gia' nel sistema di
|
|
2264
3299
|
* coordinate del canvas: convertirlo a mano dal viewport sarebbe rifare la trasformazione
|
|
2265
3300
|
* di zoom e panoramica della libreria.
|
|
3301
|
+
*
|
|
3302
|
+
* `data` e' `unknown` per @foblex/flow, e qui il dato si **controlla** invece di convertirlo con
|
|
3303
|
+
* un `as`: un rilascio che non porta una collezione di nodi si ignora, come si ignorava un dato
|
|
3304
|
+
* vuoto. E' il confine che permette a `dpeNodeCategory` di lanciare fuori dall'unione.
|
|
2266
3305
|
*/
|
|
2267
3306
|
onCreateNode(event: {
|
|
2268
3307
|
data: unknown;
|
|
@@ -2464,7 +3503,33 @@ declare class DpeNodeFactsComponent {
|
|
|
2464
3503
|
*/
|
|
2465
3504
|
readonly isNotCompilable: _angular_core.Signal<boolean>;
|
|
2466
3505
|
readonly columns: _angular_core.Signal<_esfaenza_dpe_builder.DpeColumnInfo[]>;
|
|
2467
|
-
|
|
3506
|
+
/**
|
|
3507
|
+
* Se `columns` e' un **fatto** (ADR 0041). E' l'unica cosa che `hasSchema` dice: non dice che il
|
|
3508
|
+
* nodo sta bene, non dice che ha colonne, non dice che e' compilabile.
|
|
3509
|
+
*
|
|
3510
|
+
* `=== true` e non un confronto lasco: assente significa `false`, perche' un ospite che non
|
|
3511
|
+
* serializza i booleani falsi non manda affatto la proprieta' — e il verso prudente e' «non lo
|
|
3512
|
+
* so», non «zero colonne».
|
|
3513
|
+
*/
|
|
3514
|
+
readonly hasSchema: _angular_core.Signal<boolean>;
|
|
3515
|
+
/**
|
|
3516
|
+
* Il nodo e' un **pozzo**. Non si deduce da niente: si legge la collezione di appartenenza dal
|
|
3517
|
+
* documento e si chiede la categoria al catalogo dei nodi — la stessa che il view model del
|
|
3518
|
+
* canvas usa per decidere se disegnare la porta di uscita, e per la stessa domanda («da qui esce
|
|
3519
|
+
* qualcosa?»).
|
|
3520
|
+
*
|
|
3521
|
+
* Serve perche' uno schema di uscita **vuoto** significa due cose diverse su un pozzo e su un
|
|
3522
|
+
* nodo di mezzo, e la differenza non e' nei dati: e' nel tipo di nodo, che il backend ci ha gia'
|
|
3523
|
+
* detto qual e'.
|
|
3524
|
+
*/
|
|
3525
|
+
readonly isSink: _angular_core.Signal<boolean>;
|
|
3526
|
+
readonly diagnostics: _angular_core.Signal<Diagnostic[]>;
|
|
3527
|
+
/**
|
|
3528
|
+
* Il campo in causa, dalla stessa funzione che gli ispettori usano per agganciare il rilievo al
|
|
3529
|
+
* controllo (`contracts.md` §1). Vuoto quando la diagnostica riguarda il nodo intero, e allora
|
|
3530
|
+
* la riga non mostra niente: e' un fatto sul nodo, non su un campo.
|
|
3531
|
+
*/
|
|
3532
|
+
protected fieldOf(diagnostic: Diagnostic): string | undefined;
|
|
2468
3533
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DpeNodeFactsComponent, never>;
|
|
2469
3534
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DpeNodeFactsComponent, "dpe-node-facts", never, { "nodeName": { "alias": "nodeName"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2470
3535
|
}
|
|
@@ -2484,6 +3549,23 @@ declare abstract class DpeNodeInspectorBase<TNode extends DpeAnyNode = DpeAnyNod
|
|
|
2484
3549
|
readonly isNotCompilable: _angular_core.Signal<boolean>;
|
|
2485
3550
|
/** Colonne prodotte dal nodo, secondo il backend. Mai calcolate qui (**I4**). */
|
|
2486
3551
|
readonly outputColumns: _angular_core.Signal<readonly DpeColumnInfo[]>;
|
|
3552
|
+
/**
|
|
3553
|
+
* La forma pretesa dai siti di espressione del nodo, **dal backend** (ADR 0031 §1).
|
|
3554
|
+
*
|
|
3555
|
+
* Si legge dallo **schema** e non dal catalogo delle formule, ed e' il punto della faccenda: la
|
|
3556
|
+
* forma e' cio' che la libreria ha derivato su questo nodo — come le colonne e la compilabilita'
|
|
3557
|
+
* qui sopra — mentre il catalogo e' cio' che il compilatore offre, e **arriva solo quando il
|
|
3558
|
+
* compilatore risponde**. Finche' viaggiava col catalogo, un ospite che dichiara di non
|
|
3559
|
+
* descrivere il proprio linguaggio non faceva chiamare la rotta e la forma non arrivava mai.
|
|
3560
|
+
*
|
|
3561
|
+
* Assente significa «questo nodo non ospita formule», ed e' uno stato normale: nessuna forma si
|
|
3562
|
+
* indovina dal tipo di nodo, che sarebbe una regola di dominio in TypeScript.
|
|
3563
|
+
*
|
|
3564
|
+
* Sta sulla base e non sui due ispettori che la usano perche' e' un campo dello stesso record da
|
|
3565
|
+
* cui gia' si leggono `outputColumns` e `isNotCompilable`: leggerlo due volte in due componenti
|
|
3566
|
+
* significherebbe due letture da tenere allineate.
|
|
3567
|
+
*/
|
|
3568
|
+
readonly requiredForm: _angular_core.Signal<DpeExpressionForm | undefined>;
|
|
2487
3569
|
/**
|
|
2488
3570
|
* Colonne disponibili **in ingresso**: l'unione degli schemi dei nodi a monte, nell'ordine.
|
|
2489
3571
|
* Arrivano dal backend; se la validazione non e' ancora tornata l'elenco e' vuoto e i campi
|
|
@@ -2492,11 +3574,46 @@ declare abstract class DpeNodeInspectorBase<TNode extends DpeAnyNode = DpeAnyNod
|
|
|
2492
3574
|
readonly inputColumns: _angular_core.Signal<readonly DpeColumnInfo[]>;
|
|
2493
3575
|
/** I parametri dichiarati sulla radice: servono a filtri e mapping dei writeback. */
|
|
2494
3576
|
readonly parameters: _angular_core.Signal<_esfaenza_dpe_builder.DpeParameter[]>;
|
|
2495
|
-
/**
|
|
3577
|
+
/**
|
|
3578
|
+
* Le diagnostiche su un campo preciso, per mostrarle **accanto** al controllo.
|
|
3579
|
+
*
|
|
3580
|
+
* Il nome del campo si chiede a `dpeDiagnosticField` invece di leggere `path.field` qui:
|
|
3581
|
+
* `contracts.md` §1 nomina quella funzione come **il** punto in cui l'editor aggancia il rilievo
|
|
3582
|
+
* al controllo, e una funzione sola che sappia come una diagnostica nomina il proprio campo e'
|
|
3583
|
+
* la stessa ragione per cui esiste `DiagnosticArgumentKeys`. Il percorso e' gia' pubblicato in
|
|
3584
|
+
* tre forme diverse: il giorno in cui succede anche al campo, il posto da cambiare e' uno.
|
|
3585
|
+
*/
|
|
2496
3586
|
issuesOn(field: string): Diagnostic[];
|
|
2497
3587
|
hasIssueOn(field: string): boolean;
|
|
3588
|
+
/**
|
|
3589
|
+
* Le diagnostiche su **una riga** di una collezione del nodo (`expressionFields[2].expression`).
|
|
3590
|
+
*
|
|
3591
|
+
* Esiste accanto a `issuesOn` perche' quella filtra per solo nome di campo, e in una collezione
|
|
3592
|
+
* il nome si ripete su ogni riga: l'errore della prima formula finirebbe sotto la terza.
|
|
3593
|
+
*/
|
|
3594
|
+
issuesOnItem(collection: string, index: number, field: string): Diagnostic[];
|
|
3595
|
+
/**
|
|
3596
|
+
* «Il campo porta un valore», nel senso della regola di rendering di `frontend.md` §5-ter:
|
|
3597
|
+
* **un campo che porta un valore si rende anche fuori dalla propria condizione**.
|
|
3598
|
+
*
|
|
3599
|
+
* E' l'unica meta' della regola che serve anche **fuori** dalla tabella delle condizioni
|
|
3600
|
+
* (`core/dpe-conditional-fields.ts`): un campo dentro una riga di collezione non ha una voce
|
|
3601
|
+
* in tabella, perche' la ripulitura toglie chiavi del nodo, ma la sua resa segue la stessa
|
|
3602
|
+
* regola. Il predicato e' quello, non una seconda copia: qui si delega e basta.
|
|
3603
|
+
*/
|
|
3604
|
+
protected declares(value: unknown): boolean;
|
|
2498
3605
|
/** Applica una modifica al nodo. */
|
|
2499
3606
|
protected patch(patch: Partial<TNode>): void;
|
|
3607
|
+
/**
|
|
3608
|
+
* Cambia un **discriminante** e toglie in un colpo solo i campi che con il valore nuovo non si
|
|
3609
|
+
* applicano piu', secondo la tabella delle condizioni del nodo.
|
|
3610
|
+
*
|
|
3611
|
+
* E' la seconda strada che legge quelle condizioni — la prima e' la resa di §5-ter — e legge la
|
|
3612
|
+
* **stessa** tabella: una riga aggiunta domani entra qui senza che nessuno la ricopi, che e' il
|
|
3613
|
+
* punto di `core/dpe-conditional-fields.ts`. La ripulitura resta una modifica come le altre e
|
|
3614
|
+
* rientra nell'annullamento globale, perche' passa da `patch`.
|
|
3615
|
+
*/
|
|
3616
|
+
protected patchPruned<TConditions extends DpeConditionalFields<TNode>>(change: Partial<TNode>, conditions: TConditions): void;
|
|
2500
3617
|
/**
|
|
2501
3618
|
* Campo semplice: valore vuoto → chiave **rimossa**, non stringa vuota. Il backend
|
|
2502
3619
|
* distingue assente da vuoto (`DPE_MODEL_REQUIRED_MISSING` contro un valore non valido), e
|
|
@@ -2504,6 +3621,20 @@ declare abstract class DpeNodeInspectorBase<TNode extends DpeAnyNode = DpeAnyNod
|
|
|
2504
3621
|
* semantica invece di ripulire il campo.
|
|
2505
3622
|
*/
|
|
2506
3623
|
protected setField(field: keyof TNode & string, value: unknown): void;
|
|
3624
|
+
/**
|
|
3625
|
+
* Interruttore il cui **default e' `false`**: spento → chiave **rimossa**, non `false` scritto.
|
|
3626
|
+
*
|
|
3627
|
+
* Due conseguenze, e la seconda e' quella che serve a §5-ter. La prima e' **I7**: chi accende e
|
|
3628
|
+
* rispegne per curiosita' non deve lasciare nel documento una chiave che non c'era. La seconda
|
|
3629
|
+
* e' che cosi' una casella **sa dire «assente»**: il controllo che rende un campo fuori dalla
|
|
3630
|
+
* propria condizione deve poterlo riportare all'assenza, e una casella che scrivesse `false`
|
|
3631
|
+
* resterebbe accesa-o-spenta senza mai togliere niente — resa e inerte, che e' il difetto
|
|
3632
|
+
* travestito da soluzione.
|
|
3633
|
+
*
|
|
3634
|
+
* **Non** si usa dove l'assenza vale `true` (`includesSelfValue`): li' `false` e' una
|
|
3635
|
+
* dichiarazione vera e toglierla direbbe il contrario.
|
|
3636
|
+
*/
|
|
3637
|
+
protected setFlag(field: keyof TNode & string, value: boolean): void;
|
|
2507
3638
|
/** Numero da un campo di testo: vuoto o non numerico → assente, non `0`. */
|
|
2508
3639
|
protected toNumber(value: string): number | undefined;
|
|
2509
3640
|
/** Lettura tipizzata di un valore da un evento di input, senza `any` nei template. */
|
|
@@ -2569,10 +3700,17 @@ declare class DpeSchemaPanelComponent {
|
|
|
2569
3700
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DpeSchemaPanelComponent, "dpe-schema-panel", never, {}, {}, never, never, true, never>;
|
|
2570
3701
|
}
|
|
2571
3702
|
|
|
3703
|
+
/**
|
|
3704
|
+
* I tre soli fatti che un writeback compilato e un **piano di artefatto** (ADR 0029) hanno in
|
|
3705
|
+
* comune, e gli unici che questo pannello mostra. Tipizzare la sezione sul minimo condiviso
|
|
3706
|
+
* evita un'unione che il template dovrebbe poi discriminare per rendere le stesse tre cose: qui
|
|
3707
|
+
* cambia il tipo, non il comportamento.
|
|
3708
|
+
*/
|
|
3709
|
+
type DpeSqlPreviewItem = Pick<DpeCompiledWriteback & DpeArtifactPlan, 'writebackName' | 'sequence' | 'statement'>;
|
|
2572
3710
|
interface DpeSqlSection {
|
|
2573
3711
|
title: string;
|
|
2574
3712
|
hint: string;
|
|
2575
|
-
writebacks: readonly
|
|
3713
|
+
writebacks: readonly DpeSqlPreviewItem[];
|
|
2576
3714
|
}
|
|
2577
3715
|
declare class DpeSqlPreviewComponent {
|
|
2578
3716
|
private readonly store;
|
|
@@ -2590,20 +3728,140 @@ declare class DpeExpressionEditorComponent {
|
|
|
2590
3728
|
readonly label: _angular_core.InputSignal<string>;
|
|
2591
3729
|
readonly value: _angular_core.InputSignal<string | undefined>;
|
|
2592
3730
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
2593
|
-
readonly dialect: _angular_core.InputSignal<SqlDialectKind>;
|
|
2594
3731
|
/**
|
|
2595
|
-
*
|
|
2596
|
-
*
|
|
3732
|
+
* Il nome del linguaggio di formule dichiarato dall'ambiente. Assente: l'etichetta non nomina
|
|
3733
|
+
* niente. **Non** ripiega sul dialetto — sarebbe la bugia che questo lotto e' venuto a togliere.
|
|
3734
|
+
*/
|
|
3735
|
+
readonly language: _angular_core.InputSignal<string | undefined>;
|
|
3736
|
+
/**
|
|
3737
|
+
* I nomi delle colonne a monte, **come suggerimento**: sono cio' che il backend ha propagato
|
|
3738
|
+
* (**I4**), e l'editor non li calcola.
|
|
2597
3739
|
*/
|
|
2598
3740
|
readonly columns: _angular_core.InputSignal<readonly string[]>;
|
|
3741
|
+
/**
|
|
3742
|
+
* Le diagnostiche del backend **su questo campo**, gia' filtrate da chi conosce il percorso.
|
|
3743
|
+
* Si rendono e basta: il messaggio lo compone il backend, che e' l'unico posto in cui un
|
|
3744
|
+
* messaggio viene composto.
|
|
3745
|
+
*/
|
|
3746
|
+
readonly issues: _angular_core.InputSignal<readonly Diagnostic[]>;
|
|
3747
|
+
/**
|
|
3748
|
+
* **Quale dei tre esiti del catalogo** si sta guardando, gia' letto da `dpeFormulaCatalogOutcome`.
|
|
3749
|
+
*
|
|
3750
|
+
* Prende l'esito e non il catalogo perche' il catalogo da solo non basta piu' a distinguerli: un
|
|
3751
|
+
* compilatore che non descrive il proprio linguaggio consegna il catalogo **presente e vuoto**,
|
|
3752
|
+
* quindi «assente» e «vuoto» sono due situazioni diverse che un solo oggetto nullabile
|
|
3753
|
+
* appiattiva — ed e' l'appiattimento che faceva sembrare uguali un dialetto non coperto e un
|
|
3754
|
+
* backend rotto.
|
|
3755
|
+
*/
|
|
3756
|
+
readonly outcome: _angular_core.InputSignal<DpeFormulaCatalogOutcome>;
|
|
3757
|
+
/**
|
|
3758
|
+
* La forma pretesa dal campo, **dal backend**. Assente: il campo non la nomina. Non si deduce
|
|
3759
|
+
* dal tipo di nodo, che sarebbe una regola di dominio scritta dalla parte sbagliata del confine.
|
|
3760
|
+
*/
|
|
3761
|
+
readonly requiredForm: _angular_core.InputSignal<DpeExpressionForm | undefined>;
|
|
3762
|
+
/**
|
|
3763
|
+
* L'incrocio **gia' fatto** fra la forma richiesta da questo nodo e le forme che il compilatore
|
|
3764
|
+
* registrato sa produrre (`DpeEnvironment.supportedForms`), come per `outcome`: il componente
|
|
3765
|
+
* riceve l'esito, non i due operandi.
|
|
3766
|
+
*
|
|
3767
|
+
* Il difetto predefinito e' «supportato», ed e' la politica del contratto: **capacita' non
|
|
3768
|
+
* dichiarate non disabilitano niente**. Un ospite che monta questo componente senza passare
|
|
3769
|
+
* nulla ottiene un campo che si scrive, non uno spento per ignoranza.
|
|
3770
|
+
*/
|
|
3771
|
+
readonly formSupport: _angular_core.InputSignal<DpeExpressionFormSupport>;
|
|
3772
|
+
/**
|
|
3773
|
+
* **Una validazione e' in volo**, quindi la forma qui sopra puo' non essere ancora quella del
|
|
3774
|
+
* documento che l'utente ha davanti (ADR 0042). La pastiglia si segna «in aggiornamento» e
|
|
3775
|
+
* smette di asserire; il **blocco resta applicato**.
|
|
3776
|
+
*
|
|
3777
|
+
* E' di **documento** e **transitorio**, e per questo non e' una regola di dominio: arriva da
|
|
3778
|
+
* `DpeValidationService.isValidating`, che esisteva gia'. L'editor non sa — e non deve sapere —
|
|
3779
|
+
* che la forma dipende dal tipo del nodo: saperlo sarebbe riscrivere in TypeScript la regola che
|
|
3780
|
+
* `requiredForm` attraversa il confine per non avere.
|
|
3781
|
+
*
|
|
3782
|
+
* Non e' «il documento e' cambiato dall'ultima validazione», che e' il rimedio che l'ADR 0042
|
|
3783
|
+
* rifiuta: quello sarebbe vero **per tutta** la digitazione e spegnerebbe la pastiglia proprio
|
|
3784
|
+
* mentre si scrive nel campo che accompagna. `isValidating` diventa vero solo dopo la pausa di
|
|
3785
|
+
* digitazione, quindi mentre si scrive questa pastiglia resta ferma — e corretta, perche' la
|
|
3786
|
+
* forma non e' cambiata.
|
|
3787
|
+
*
|
|
3788
|
+
* Difetto predefinito `false`: un ospite che monta il componente senza passare nulla ottiene una
|
|
3789
|
+
* pastiglia asserita, che e' cio' che era prima.
|
|
3790
|
+
*/
|
|
3791
|
+
readonly isFormUpdating: _angular_core.InputSignal<boolean>;
|
|
3792
|
+
readonly isCatalogLoading: _angular_core.InputSignal<boolean>;
|
|
2599
3793
|
readonly controlId: _angular_core.InputSignal<string>;
|
|
2600
3794
|
readonly valueChange: _angular_core.OutputEmitterRef<string>;
|
|
2601
|
-
readonly
|
|
3795
|
+
readonly hasError: _angular_core.Signal<boolean>;
|
|
2602
3796
|
/** Elenco troncato: dieci nomi sono un aiuto, cinquanta sono un muro di testo. */
|
|
2603
3797
|
readonly columnHint: _angular_core.Signal<string>;
|
|
3798
|
+
/**
|
|
3799
|
+
* La forma pretesa, detta all'utente. Assente quando il nodo non ospita formule: il campo non
|
|
3800
|
+
* nomina nessuna forma di ripiego, che sarebbe la deduzione vietata travestita da default.
|
|
3801
|
+
*/
|
|
3802
|
+
readonly formPrompt: _angular_core.Signal<string | undefined>;
|
|
3803
|
+
/**
|
|
3804
|
+
* La classe della pastiglia. Binding a stringa e nessuna classe statica accanto, come per il
|
|
3805
|
+
* controllo bloccato: il binding governa l'intera lista.
|
|
3806
|
+
*
|
|
3807
|
+
* Il modificatore non cambia il testo, cambia il **tono**: la pastiglia perde la tinta d'accento
|
|
3808
|
+
* — che e' cio' che la faceva leggere come un fatto corrente — e prende il bordo tratteggiato
|
|
3809
|
+
* della cosa provvisoria.
|
|
3810
|
+
*/
|
|
3811
|
+
readonly formClass: _angular_core.Signal<"dpe-expr__form dpe-expr__form--updating" | "dpe-expr__form">;
|
|
3812
|
+
/**
|
|
3813
|
+
* Il titolo dice **cosa aspettarsi**, e nella finestra di aggiornamento dice anche che il blocco
|
|
3814
|
+
* non si tocca: e' la meta' che l'utente non puo' dedurre dal colore, e senza la quale un campo
|
|
3815
|
+
* che non accetta testo accanto a un'etichetta incerta sembra rotto.
|
|
3816
|
+
*/
|
|
3817
|
+
readonly formTitle: _angular_core.Signal<string>;
|
|
3818
|
+
/** `aria-busy` invece del solo colore: chi usa un lettore di schermo deve sentirlo. */
|
|
3819
|
+
readonly ariaBusy: _angular_core.Signal<"true" | null>;
|
|
3820
|
+
/** Il campo non si scrive: la forma richiesta qui non e' fra quelle che il compilatore produce. */
|
|
3821
|
+
readonly isBlocked: _angular_core.Signal<boolean>;
|
|
3822
|
+
/**
|
|
3823
|
+
* Il motivo, **presente solo quando il campo e' bloccato**. Un campo inerte e muto fa cercare
|
|
3824
|
+
* all'utente un errore nella propria formula, che e' l'unico posto in cui il problema non sta.
|
|
3825
|
+
*/
|
|
3826
|
+
readonly blockedReason: _angular_core.Signal<string | undefined>;
|
|
3827
|
+
/**
|
|
3828
|
+
* La classe del controllo bloccato. Binding a stringa e nessuna classe statica accanto, come per
|
|
3829
|
+
* i rilievi: il binding governa l'intera lista e una classe scritta anche nell'attributo statico
|
|
3830
|
+
* sembra ridondante finche' non sparisce.
|
|
3831
|
+
*/
|
|
3832
|
+
readonly inputClass: _angular_core.Signal<"" | "dpe-expr__input--blocked">;
|
|
3833
|
+
/** L'esito di fallimento, quando e' quello: il template rende solo se c'e'. */
|
|
3834
|
+
readonly failure: _angular_core.Signal<{
|
|
3835
|
+
readonly kind: "Failed";
|
|
3836
|
+
readonly lead: Diagnostic;
|
|
3837
|
+
readonly details: readonly Diagnostic[];
|
|
3838
|
+
readonly hasError: boolean;
|
|
3839
|
+
} | undefined>;
|
|
3840
|
+
/**
|
|
3841
|
+
* Il blocco del fallimento prende il bordo dell'errore quando fra le diagnostiche c'e' un
|
|
3842
|
+
* `Error`, quello dell'avviso altrimenti. Non e' decorazione: «il catalogo non c'e' perche' la
|
|
3843
|
+
* definizione e' rotta a monte» e «il catalogo non c'e' e basta» si correggono in modi diversi.
|
|
3844
|
+
*/
|
|
3845
|
+
readonly failureClass: _angular_core.Signal<"dpe-note dpe-note--danger" | "dpe-note dpe-note--warning">;
|
|
3846
|
+
/**
|
|
3847
|
+
* Cosa il linguaggio offre **qui**, in numeri. E' deliberatamente un conteggio: dice che il
|
|
3848
|
+
* catalogo e' arrivato e che dipende dal nodo (i simboli cambiano con lo schema a monte), senza
|
|
3849
|
+
* anticipare l'elenco navigabile, che e' un componente e va progettato guardandolo.
|
|
3850
|
+
*
|
|
3851
|
+
* Solo per l'esito `Palette`: un conteggio di zeri sotto un campo direbbe che qualcosa e'
|
|
3852
|
+
* andato storto, mentre il compilatore ha soltanto scelto di non descriversi.
|
|
3853
|
+
*/
|
|
3854
|
+
readonly catalogHint: _angular_core.Signal<string | undefined>;
|
|
3855
|
+
/**
|
|
3856
|
+
* `aria-describedby` porta **il suggerimento, i rilievi e il motivo per cui la tavolozza manca**:
|
|
3857
|
+
* un lettore di schermo deve sentire l'errore del compilatore leggendo il campo, non cercandolo
|
|
3858
|
+
* piu' in basso, e deve sapere che qui non c'e' aiuto disponibile prima di scrivere.
|
|
3859
|
+
*/
|
|
3860
|
+
readonly describedBy: _angular_core.Signal<string>;
|
|
3861
|
+
protected issueClass(issue: Diagnostic): string;
|
|
2604
3862
|
protected text(event: Event): string;
|
|
2605
3863
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DpeExpressionEditorComponent, never>;
|
|
2606
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DpeExpressionEditorComponent, "dpe-expression-editor", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "
|
|
3864
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DpeExpressionEditorComponent, "dpe-expression-editor", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "issues": { "alias": "issues"; "required": false; "isSignal": true; }; "outcome": { "alias": "outcome"; "required": false; "isSignal": true; }; "requiredForm": { "alias": "requiredForm"; "required": false; "isSignal": true; }; "formSupport": { "alias": "formSupport"; "required": false; "isSignal": true; }; "isFormUpdating": { "alias": "isFormUpdating"; "required": false; "isSignal": true; }; "isCatalogLoading": { "alias": "isCatalogLoading"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
2607
3865
|
}
|
|
2608
3866
|
|
|
2609
3867
|
declare class DpeColumnTypeEditorComponent {
|
|
@@ -2613,6 +3871,9 @@ declare class DpeColumnTypeEditorComponent {
|
|
|
2613
3871
|
protected readonly types: readonly LogicalType[];
|
|
2614
3872
|
readonly kind: _angular_core.Signal<LogicalType>;
|
|
2615
3873
|
readonly allowedValues: _angular_core.Signal<string>;
|
|
3874
|
+
readonly showsLength: _angular_core.Signal<boolean>;
|
|
3875
|
+
readonly showsPrecision: _angular_core.Signal<boolean>;
|
|
3876
|
+
readonly showsAllowedValues: _angular_core.Signal<boolean>;
|
|
2616
3877
|
protected onKind(kind: string): void;
|
|
2617
3878
|
protected onNumber(field: 'length' | 'precision' | 'scale', raw: string): void;
|
|
2618
3879
|
protected onAllowedValues(raw: string): void;
|
|
@@ -2636,5 +3897,5 @@ declare class DpeNodeIconComponent {
|
|
|
2636
3897
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DpeNodeIconComponent, "dpe-node-icon", never, { "collection": { "alias": "collection"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2637
3898
|
}
|
|
2638
3899
|
|
|
2639
|
-
export { DPE_API_ERROR_FALLBACK_MESSAGE, DPE_BUILDER_HTTP_CONFIG, DPE_DIALECT_LABELS, DPE_LAYOUT_KEY, DPE_NODE_CATEGORIES, DPE_NODE_COLLECTIONS, DPE_NODE_HEIGHT, DPE_NODE_ICON_PATHS, DPE_NODE_NOT_COMPILABLE, DPE_SOURCE_SLOTS, DpeApiError, DpeBuilderApi, DpeBuilderComponent, DpeCanvasComponent, DpeCatalogComponent, DpeCatalogStore, DpeColumnTypeEditorComponent, DpeDiagnosticsPanelComponent, DpeDocumentStore, DpeExpressionEditorComponent, DpeLayoutService, DpeMetadataStore, DpeNodeDialogComponent, DpeNodeFactsComponent, DpeNodeIconComponent, DpeNodeInspectorBase, DpeNodeInspectorComponent, DpeNodePaletteComponent, DpeSchemaPanelComponent, DpeSelectValueDirective, DpeSqlPreviewComponent, DpeValidationService, HttpDpeBuilderApi, diagnosticPathToString, dpeAllNodes, dpeBuildGraph, dpeCountReferences, dpeCreateCommandAvailability, dpeCreateNode, dpeDefinitionLevelDiagnostics, dpeDiagnosticField, dpeDiagnosticLocationLabel, dpeDiagnosticNodeName, dpeEdgeId, dpeEmptyDefinition, dpeFindNode, dpeGroupDiagnosticsByNode, dpeHasCompleteLayout, dpeInputPortId, dpeInputPorts, dpeIsDialectDiagnostic, dpeIsNotCompilable, dpeIsPrimitiveAvailable, dpeIsRectFullyVisible, dpeKnownNodeNames, dpeNodeCategory, dpeNodeIconFamily, dpeNodeIconFamilyClass, dpeNodeIconPaths, dpeNodeId, dpeNodeSourceReferences, dpeNodeSubtitle, dpeNodeWidth, dpeNodeWidthClass, dpeOutputPortId, dpeParseInputPortId, dpeParseNodeId, dpeParseOutputPortId, dpeProposeNodeName, dpeProposeWritebackSequence, dpeReadCapabilities, dpeReadNodePosition, dpeRenameNode, dpeWorstSeverity, dpeWriteNodePosition, dpeWriteSourceReference, provideDpeBuilderHttpApi };
|
|
2640
|
-
export type { AggregateField, AggregateFunction, AggregateNode, AppendNode, AtomicWritebackNode, AtomicWritebackRelationship, ColumnType, CsvArtifactOptions, CsvDelimiter, CsvSourceOptions, CustomNode, CustomNodeParameter, DataSourceField, DataSourceKind, DataSourceNode, DatePart, DeclaredField, DefinitionRunMode, DefinitionStatus, Diagnostic, DiagnosticPath, DiagnosticPathSegment, DiagnosticSeverity, DpeAnyNode, DpeApiErrorCategory, DpeBuilderHttpConfig, DpeCanvasEdge, DpeCanvasNode, DpeCanvasPort, DpeCapabilities, DpeColumnInfo, DpeCommandAvailability, DpeCompileResult, DpeCompiledWriteback, DpeDefinition, DpeDefinitionSummary, DpeEnvironment, DpeExtensible, DpeExtensionData, DpeFieldMappingInfo, DpeGraph, DpeGraphEdge, DpeGraphNode, DpeInputPort, DpeLayoutDirection, DpeLayoutEdgeInput, DpeLayoutNodeInput, DpeLayoutOptions, DpeLayoutPosition, DpeLocatedNode, DpeNode, DpeNodeCategory, DpeNodeCollectionMap, DpeNodeCollectionName, DpeNodeDiagnostics, DpeNodeIconFamily, DpeNodePaletteGroup, DpeNodePosition, DpeNodeSchemaInfo, DpeOptionalPrimitive, DpeParameter, DpeParameterValue, DpeRect, DpeSourceReference, DpeSourceSlot, DpeTableState, DpeValidateResult, DpeWritebackStep, ExpressionField, FieldDescriptor, FieldRelationship, FilterCriterion, FilterNode, FilterOperator, ForecastAccuracy, ForecastAggregationField, ForecastGroupField, ForecastModelType, ForecastNode, ForecastPeriodType, HierarchyPathNode, JoinKey, JoinKind, JoinNode, JoinResultField, JsonArtifactOptions, LogicalType, OrderByField, ParameterRole, SortDirection, SqlDialectKind, SqlParameterValue, SqlStatement, TableDescriptor, TableLookupOutcome, TableLookupResult, TableSummary, TransformKind, TransformNode, WritebackFieldMapping, WritebackFieldRole, WritebackNode, WritebackOperation, WritebackTargetKind };
|
|
3900
|
+
export { DPE_API_ERROR_FALLBACK_MESSAGE, DPE_BUILDER_HTTP_CONFIG, DPE_CATALOG_UNAVAILABLE, DPE_DATA_SOURCE_CONDITIONS, DPE_DIALECT_LABELS, DPE_FILTER_CONDITIONS, DPE_HIERARCHY_PATH_CONDITIONS, DPE_JOIN_CONDITIONS, DPE_LAYOUT_KEY, DPE_NODE_CATEGORIES, DPE_NODE_COLLECTIONS, DPE_NODE_HEIGHT, DPE_NODE_ICON_PATHS, DPE_NODE_NOT_COMPILABLE, DPE_SOURCE_SLOTS, DPE_TRANSFORM_CONDITIONS, DPE_WRITEBACK_CONDITIONS, DpeApiError, DpeBuilderApi, DpeBuilderComponent, DpeCanvasComponent, DpeCatalogComponent, DpeCatalogStore, DpeColumnTypeEditorComponent, DpeDiagnosticsPanelComponent, DpeDocumentStore, DpeExpressionEditorComponent, DpeFormulaCatalogStore, DpeLayoutService, DpeMetadataStore, DpeNodeDialogComponent, DpeNodeFactsComponent, DpeNodeIconComponent, DpeNodeInspectorBase, DpeNodeInspectorComponent, DpeNodePaletteComponent, DpeSchemaPanelComponent, DpeSelectValueDirective, DpeSqlPreviewComponent, DpeValidationService, HttpDpeBuilderApi, diagnosticPathToString, dpeAllNodes, dpeBuildGraph, dpeCountReferences, dpeCreateCommandAvailability, dpeCreateNode, dpeDeclares, dpeDefinitionLevelDiagnostics, dpeDiagnosticField, dpeDiagnosticLocationLabel, dpeDiagnosticNodeName, dpeDiagnosticTargetsItem, dpeEdgeId, dpeEmptyDefinition, dpeExpressionFormLabel, dpeExpressionFormPrompt, dpeExpressionFormSupport, dpeFieldVisibility, dpeFindNode, dpeFormulaCatalogOutcome, dpeFormulaCatalogSignature, dpeFormulaCatalogSize, dpeGroupDiagnosticsByNode, dpeHasCompleteLayout, dpeInputPortId, dpeInputPorts, dpeIsDialectDiagnostic, dpeIsNotCompilable, dpeIsPrimitiveAvailable, dpeIsRectFullyVisible, dpeKnownNodeNames, dpeNodeCategory, dpeNodeIconFamily, dpeNodeIconFamilyClass, dpeNodeIconPaths, dpeNodeId, dpeNodeSourceReferences, dpeNodeSubtitle, dpeNodeWidth, dpeNodeWidthClass, dpeOutputPortId, dpeParseInputPortId, dpeParseNodeId, dpeParseOutputPortId, dpeProposeNodeName, dpeProposeWritebackSequence, dpePruneInapplicable, dpeReadCapabilities, dpeReadNodePosition, dpeRenameNode, dpeWorstSeverity, dpeWriteNodePosition, dpeWriteSourceReference, provideDpeBuilderHttpApi };
|
|
3901
|
+
export type { AggregateField, AggregateFunction, AggregateNode, AppendNode, ArtifactKind, AtomicWritebackNode, AtomicWritebackRelationship, ColumnType, CsvArtifactOptions, CsvDelimiter, CsvSourceOptions, CustomNode, CustomNodeParameter, DataSourceField, DataSourceKind, DataSourceNode, DatePart, DeclaredField, DefinitionRunMode, DefinitionStatus, Diagnostic, DiagnosticPath, DiagnosticPathSegment, DiagnosticSeverity, DpeAnyNode, DpeApiErrorCategory, DpeArtifactColumn, DpeArtifactPlan, DpeBuilderHttpConfig, DpeCanvasEdge, DpeCanvasNode, DpeCanvasPort, DpeCapabilities, DpeColumnInfo, DpeCommandAvailability, DpeCompileResult, DpeCompiledWriteback, DpeConditionalFields, DpeDefinition, DpeDefinitionSummary, DpeEnvironment, DpeExpressionForm, DpeExpressionFormSupport, DpeExtensible, DpeExtensionData, DpeFieldCondition, DpeFieldMappingInfo, DpeFieldVisibility, DpeFormulaCatalog, DpeFormulaCatalogOutcome, DpeFormulaCatalogResult, DpeFormulaFunction, DpeFormulaFunctionParameter, DpeFormulaOperator, DpeFormulaSymbol, DpeFormulaSymbolKind, DpeGraph, DpeGraphEdge, DpeGraphNode, DpeInputPort, DpeLayoutDirection, DpeLayoutEdgeInput, DpeLayoutNodeInput, DpeLayoutOptions, DpeLayoutPosition, DpeLocatedNode, DpeNode, DpeNodeCategory, DpeNodeCollectionMap, DpeNodeCollectionName, DpeNodeDiagnostics, DpeNodeIconFamily, DpeNodePaletteGroup, DpeNodePosition, DpeNodeSchemaInfo, DpeOptionalPrimitive, DpeParameter, DpeParameterValue, DpeRect, DpeSourceReference, DpeSourceSlot, DpeTableState, DpeValidateResult, DpeWritebackStep, ExpressionField, FieldDescriptor, FieldRelationship, FilterCriterion, FilterNode, FilterOperator, ForecastAccuracy, ForecastAggregationField, ForecastGroupField, ForecastModelType, ForecastNode, ForecastPeriodType, HierarchyPathNode, JoinKey, JoinKind, JoinNode, JoinResultField, JsonArtifactOptions, LogicalType, OrderByField, ParameterRole, SortDirection, SqlDialectKind, SqlParameterValue, SqlStatement, TableDescriptor, TableLookupOutcome, TableLookupResult, TableSummary, TransformKind, TransformNode, WritebackFailureHandling, WritebackFieldMapping, WritebackFieldRole, WritebackNode, WritebackOperation, WritebackTargetKind };
|