@esfaenza/dpe-builder 20.3.14 → 20.3.15
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.
|
@@ -1146,10 +1146,24 @@ function dpeIsNodeCollectionName(value) {
|
|
|
1146
1146
|
* `node`; l'indice del primo segmento risolto nella collezione corrispondente della
|
|
1147
1147
|
* definizione — che e' il caso della deserializzazione, dove i nomi non sono ancora noti.
|
|
1148
1148
|
* Senza la terza, un `filters[0].sourceName` resterebbe una riga non cliccabile.
|
|
1149
|
+
*
|
|
1150
|
+
* La prima e la terza strada valgono solo se la radice del percorso e' una collezione di nodi
|
|
1151
|
+
* (`contracts.md` §1, normativo; questione aperta 39).
|
|
1149
1152
|
*/
|
|
1150
1153
|
function dpeDiagnosticNodeName(diagnostic, definition) {
|
|
1151
1154
|
const first = diagnostic.path?.segments?.[0];
|
|
1152
|
-
|
|
1155
|
+
/*
|
|
1156
|
+
* Il backend emette primi segmenti con un nome che non sono nodi: `parameters/<nome>` dalla
|
|
1157
|
+
* validazione, `restrictions/<writeback>` e `artifactPlan/<writeback>` dalle utility. Senza il
|
|
1158
|
+
* controllo il nome del parametro tornava come nodo — riga cliccabile verso un nodo che non
|
|
1159
|
+
* esiste, e diagnostica sparita da quelle della definizione. `artifactPlan` portava al
|
|
1160
|
+
* writeback solo per coincidenza di nome, contro l'intento dell'emettitore: smette apposta.
|
|
1161
|
+
* Il confronto e' esatto con i nomi del modello, senza varianti, perche' il contratto impone
|
|
1162
|
+
* alle collezioni di nodi la sola grafia del modello in ogni forma del percorso: se un livello
|
|
1163
|
+
* ne scrivesse un'altra, la navigazione di quel tipo di nodo si spegnerebbe in silenzio, e il
|
|
1164
|
+
* rimedio e' nel backend, non in un elenco di grafie qui.
|
|
1165
|
+
*/
|
|
1166
|
+
if (first?.name && dpeIsNodeCollectionName(first.collection)) {
|
|
1153
1167
|
return first.name;
|
|
1154
1168
|
}
|
|
1155
1169
|
const fromArguments = diagnostic.arguments?.['node'];
|
|
@@ -1248,19 +1262,69 @@ function dpeGroupDiagnosticsByNode(diagnostics, definition) {
|
|
|
1248
1262
|
function dpeDefinitionLevelDiagnostics(diagnostics, definition) {
|
|
1249
1263
|
return diagnostics.filter((diagnostic) => dpeDiagnosticNodeName(diagnostic, definition) === undefined);
|
|
1250
1264
|
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Le parole con cui si legge il primo segmento quando la sua radice non e' una collezione di nodi.
|
|
1267
|
+
* Le tre radici sono quelle che `contracts.md` §1 dichiara non-nodo; per `restrictions` e
|
|
1268
|
+
* `artifactPlan` il nome e' **del writeback**, non della cosa, e la preposizione lo dice — per
|
|
1269
|
+
* questo la preposizione sta solo davanti al nome, e non davanti all'indice.
|
|
1270
|
+
*
|
|
1271
|
+
* E' un elenco scritto qui, ma non e' l'opzione C della questione 39 rientrata dalla finestra:
|
|
1272
|
+
* governa solo il testo, non la navigazione, e una radice che non vi compare non sparisce — si
|
|
1273
|
+
* legge grezza, come i segmenti successivi. Il difetto che l'elenco puo' avere e' una parola
|
|
1274
|
+
* italiana mancante, non un elemento nascosto o un nodo inventato.
|
|
1275
|
+
*
|
|
1276
|
+
* `Map` e non oggetto letterale: la chiave arriva dal backend, e su un oggetto una radice che si
|
|
1277
|
+
* chiamasse `constructor` o `toString` troverebbe una funzione del prototipo.
|
|
1278
|
+
*/
|
|
1279
|
+
const NON_NODE_ROOT_WORDS = new Map([
|
|
1280
|
+
['parameters', { noun: 'parametro' }],
|
|
1281
|
+
['restrictions', { noun: 'restrizione', preposition: 'su' }],
|
|
1282
|
+
['artifactPlan', { noun: 'piano dell’artefatto', preposition: 'di' }],
|
|
1283
|
+
]);
|
|
1284
|
+
function dpeSegmentLabel(segment) {
|
|
1285
|
+
const index = segment.index === undefined ? '' : `[${segment.index}]`;
|
|
1286
|
+
return `${segment.collection ?? ''}${segment.name ? `/${segment.name}` : index}`;
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* La radice non-nodo descritta: col nome se c'e', altrimenti con l'indice se c'e', altrimenti con
|
|
1290
|
+
* la sola parola. Nessuna delle tre strade restituisce vuoto per una radice conosciuta, ed e' il
|
|
1291
|
+
* punto: il nome vuoto e l'indice senza nome sono proprio le forme che si scartavano.
|
|
1292
|
+
*/
|
|
1293
|
+
function dpeNonNodeRootLabel(segment) {
|
|
1294
|
+
const words = NON_NODE_ROOT_WORDS.get(segment.collection ?? '');
|
|
1295
|
+
if (words === undefined) {
|
|
1296
|
+
return dpeSegmentLabel(segment);
|
|
1297
|
+
}
|
|
1298
|
+
if (segment.name) {
|
|
1299
|
+
return [words.noun, words.preposition, segment.name].filter(Boolean).join(' ');
|
|
1300
|
+
}
|
|
1301
|
+
return segment.index === undefined ? words.noun : `${words.noun} [${segment.index}]`;
|
|
1302
|
+
}
|
|
1251
1303
|
/** Testo leggibile del percorso, per la riga del pannello. */
|
|
1252
1304
|
function dpeDiagnosticLocationLabel(diagnostic, definition) {
|
|
1253
1305
|
const node = dpeDiagnosticNodeName(diagnostic, definition);
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1306
|
+
const [first, ...rest] = diagnostic.path?.segments ?? [];
|
|
1307
|
+
/*
|
|
1308
|
+
* Il primo segmento si scartava sempre, perche' si presumeva che fosse il nodo e il nodo e' gia'
|
|
1309
|
+
* in testa. Da quando `parameters`, `restrictions` e `artifactPlan` non indicano un nodo,
|
|
1310
|
+
* scartarlo cancellava **quale** parametro o writeback: il messaggio di
|
|
1311
|
+
* `DPE_MODEL_CONDITIONAL_REQUIRED` non lo nomina, e due parametri senza `valueType` davano due
|
|
1312
|
+
* righe identiche, `definizione › valueType`. Lo stesso controllo di `dpeDiagnosticNodeName`
|
|
1313
|
+
* decide qui, cosi' il primo segmento e' o il nodo in testa o la radice descritta, mai tutt'e due
|
|
1314
|
+
* e mai nessuno.
|
|
1315
|
+
*
|
|
1316
|
+
* Il controllo e' sulla sola radice, non sulla presenza del nome: la deserializzazione non
|
|
1317
|
+
* conosce i nomi (`parameters[0].valueType`), la validazione non ne ha uno per un parametro che
|
|
1318
|
+
* non lo porta, e `ArtifactPlanValidator` nomina il piano con `""` quando manca proprio il
|
|
1319
|
+
* `writebackName` di cui si lamenta — tre forme in cui scartare il segmento attribuiva il difetto
|
|
1320
|
+
* alla definizione. La riga resta non navigabile: lo decide `dpeDiagnosticNodeName`, non questa
|
|
1321
|
+
* etichetta.
|
|
1322
|
+
*/
|
|
1323
|
+
const root = first && !dpeIsNodeCollectionName(first.collection) ? dpeNonNodeRootLabel(first) : '';
|
|
1324
|
+
const head = root.length === 0 ? [node ?? 'definizione'] : [node, root];
|
|
1325
|
+
const tail = rest.map(dpeSegmentLabel).filter((part) => part.length > 0);
|
|
1262
1326
|
const field = diagnostic.path?.field;
|
|
1263
|
-
return [
|
|
1327
|
+
return [...head, ...tail, field].filter(Boolean).join(' › ');
|
|
1264
1328
|
}
|
|
1265
1329
|
/** I nomi dei nodi presenti nella definizione: serve a chi naviga dal pannello al canvas. */
|
|
1266
1330
|
function dpeKnownNodeNames(definition) {
|