@grexx/grexxlinter 0.2.1318 → 0.2.1372
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/cli.js +18 -10
- package/lsp.js +8 -5
- package/package.json +1 -1
- package/schemas/widget.schema.json +274 -0
package/cli.js
CHANGED
|
@@ -14547,8 +14547,7 @@ function buildCoverageIndex(doc) {
|
|
|
14547
14547
|
return {
|
|
14548
14548
|
clauseCovered(casetype, field, modality, when) {
|
|
14549
14549
|
if (!casetype || !field) return null;
|
|
14550
|
-
|
|
14551
|
-
return v === void 0 ? null : v;
|
|
14550
|
+
return map.get(key(casetype, field, modality, when)) ?? null;
|
|
14552
14551
|
},
|
|
14553
14552
|
uncoveredCount: (casetype) => uncovered.get(casetype) ?? 0
|
|
14554
14553
|
};
|
|
@@ -15039,7 +15038,8 @@ function lintDocument(ctx, input) {
|
|
|
15039
15038
|
if (!emittedReqAny.has(key2)) {
|
|
15040
15039
|
emittedReqAny.add(key2);
|
|
15041
15040
|
const state = describeState(schema, g.err, input.value, ctx.registry.resolveRef);
|
|
15042
|
-
|
|
15041
|
+
const stateSuffix = state ? ` ${state}` : "";
|
|
15042
|
+
push("required-field", g.instancePath, null, `missing at least one of: ${g.fields.join(", ")}${stateSuffix}`);
|
|
15043
15043
|
}
|
|
15044
15044
|
continue;
|
|
15045
15045
|
}
|
|
@@ -15063,11 +15063,14 @@ function lintDocument(ctx, input) {
|
|
|
15063
15063
|
}
|
|
15064
15064
|
if (e.keyword === "type") {
|
|
15065
15065
|
const actual = valueAtPointer(input.value, e.instancePath);
|
|
15066
|
-
|
|
15066
|
+
let recv = typeof actual;
|
|
15067
|
+
if (actual === null) recv = "null";
|
|
15068
|
+
else if (Array.isArray(actual)) recv = "array";
|
|
15067
15069
|
let val = JSON.stringify(actual) ?? "";
|
|
15068
15070
|
if (val.length > 60) val = `${val.slice(0, 57)}\u2026"`;
|
|
15069
15071
|
const expected = String(e.params.type);
|
|
15070
|
-
|
|
15072
|
+
const withValue = actual === void 0 ? "" : ` with value ${val}`;
|
|
15073
|
+
push("invalid-type", path, field, `expected ${expected} but received ${recv}${withValue}`);
|
|
15071
15074
|
continue;
|
|
15072
15075
|
}
|
|
15073
15076
|
const rule = ruleForKeyword(e.keyword);
|
|
@@ -15124,7 +15127,7 @@ function toJSOrError(doc) {
|
|
|
15124
15127
|
// src/cli.ts
|
|
15125
15128
|
var PARALLEL_THRESHOLD = 200;
|
|
15126
15129
|
var MAX_WORKERS = 8;
|
|
15127
|
-
var VERSION = true ? "0.2.
|
|
15130
|
+
var VERSION = true ? "0.2.1372" : "0.0.0-dev";
|
|
15128
15131
|
function isNewer(latest, current) {
|
|
15129
15132
|
const a = latest.split(".").map(Number);
|
|
15130
15133
|
const b = current.split(".").map(Number);
|
|
@@ -15195,6 +15198,7 @@ function discover(paths, exclude) {
|
|
|
15195
15198
|
for (const p of paths) walk(p);
|
|
15196
15199
|
return files;
|
|
15197
15200
|
}
|
|
15201
|
+
var KEY_SEP = String.fromCodePoint(0);
|
|
15198
15202
|
var COLORS = { error: "\x1B[31m", warning: "\x1B[33m", info: "\x1B[36m" };
|
|
15199
15203
|
var RESET = "\x1B[0m";
|
|
15200
15204
|
var useColor = process.stdout.isTTY;
|
|
@@ -15205,7 +15209,8 @@ function printText(results, settings, quiet, errorsOnly) {
|
|
|
15205
15209
|
const msgs = errorsOnly ? r.messages.filter((m) => m.severity === "error") : r.messages;
|
|
15206
15210
|
if (quiet && msgs.length === 0) continue;
|
|
15207
15211
|
const rel = r.file ? relative(process.cwd(), r.file) : "<input>";
|
|
15208
|
-
const
|
|
15212
|
+
const casetypeTag = r.casetype ? ` (${r.casetype})` : "";
|
|
15213
|
+
const head = `${rel}${casetypeTag}`;
|
|
15209
15214
|
if (msgs.length === 0) {
|
|
15210
15215
|
if (!quiet) console.log(`${paint("ok", COLORS.info)} ${head}`);
|
|
15211
15216
|
continue;
|
|
@@ -15218,9 +15223,12 @@ function printText(results, settings, quiet, errorsOnly) {
|
|
|
15218
15223
|
}
|
|
15219
15224
|
const s = summarize(results.filter((r) => !r.skipped));
|
|
15220
15225
|
const skipped = results.filter((r) => r.skipped).length;
|
|
15226
|
+
const skippedNote = skipped ? `, ${skipped} skipped` : "";
|
|
15227
|
+
const errorsText = paint(`${s.errors} error(s)`, COLORS.error);
|
|
15228
|
+
const warningsText = paint(`${s.warnings} warning(s)`, COLORS.warning);
|
|
15221
15229
|
console.log(
|
|
15222
15230
|
`
|
|
15223
|
-
${s.files} file(s)${
|
|
15231
|
+
${s.files} file(s)${skippedNote} \u2014 ${errorsText}, ${warningsText}, ${s.infos} info(s) [fail-on: ${settings.failOn}]`
|
|
15224
15232
|
);
|
|
15225
15233
|
}
|
|
15226
15234
|
function printReport(results, kind, errorsOnly) {
|
|
@@ -15243,7 +15251,7 @@ function printReport(results, kind, errorsOnly) {
|
|
|
15243
15251
|
}
|
|
15244
15252
|
const by = /* @__PURE__ */ new Map();
|
|
15245
15253
|
for (const m of msgs) {
|
|
15246
|
-
const key2 =
|
|
15254
|
+
const key2 = [m.casetype ?? "?", m.rule, m.severity, m.message].join(KEY_SEP);
|
|
15247
15255
|
const e = by.get(key2) ?? { count: 0, casetype: m.casetype ?? "?", severity: m.severity, message: m.message };
|
|
15248
15256
|
e.count++;
|
|
15249
15257
|
by.set(key2, e);
|
|
@@ -15363,5 +15371,5 @@ async function main() {
|
|
|
15363
15371
|
}
|
|
15364
15372
|
process.exit(summarize(results.filter((r) => !r.skipped)).exitCode);
|
|
15365
15373
|
}
|
|
15366
|
-
if (isMainThread)
|
|
15374
|
+
if (isMainThread) await main();
|
|
15367
15375
|
else runWorker();
|
package/lsp.js
CHANGED
|
@@ -23616,8 +23616,7 @@ function buildCoverageIndex(doc) {
|
|
|
23616
23616
|
return {
|
|
23617
23617
|
clauseCovered(casetype, field, modality, when) {
|
|
23618
23618
|
if (!casetype || !field) return null;
|
|
23619
|
-
|
|
23620
|
-
return v === void 0 ? null : v;
|
|
23619
|
+
return map.get(key(casetype, field, modality, when)) ?? null;
|
|
23621
23620
|
},
|
|
23622
23621
|
uncoveredCount: (casetype) => uncovered.get(casetype) ?? 0
|
|
23623
23622
|
};
|
|
@@ -23997,7 +23996,8 @@ function lintDocument(ctx2, input) {
|
|
|
23997
23996
|
if (!emittedReqAny.has(key2)) {
|
|
23998
23997
|
emittedReqAny.add(key2);
|
|
23999
23998
|
const state = describeState(schema, g.err, input.value, ctx2.registry.resolveRef);
|
|
24000
|
-
|
|
23999
|
+
const stateSuffix = state ? ` ${state}` : "";
|
|
24000
|
+
push("required-field", g.instancePath, null, `missing at least one of: ${g.fields.join(", ")}${stateSuffix}`);
|
|
24001
24001
|
}
|
|
24002
24002
|
continue;
|
|
24003
24003
|
}
|
|
@@ -24021,11 +24021,14 @@ function lintDocument(ctx2, input) {
|
|
|
24021
24021
|
}
|
|
24022
24022
|
if (e.keyword === "type") {
|
|
24023
24023
|
const actual = valueAtPointer(input.value, e.instancePath);
|
|
24024
|
-
|
|
24024
|
+
let recv = typeof actual;
|
|
24025
|
+
if (actual === null) recv = "null";
|
|
24026
|
+
else if (Array.isArray(actual)) recv = "array";
|
|
24025
24027
|
let val = JSON.stringify(actual) ?? "";
|
|
24026
24028
|
if (val.length > 60) val = `${val.slice(0, 57)}\u2026"`;
|
|
24027
24029
|
const expected = String(e.params.type);
|
|
24028
|
-
|
|
24030
|
+
const withValue = actual === void 0 ? "" : ` with value ${val}`;
|
|
24031
|
+
push("invalid-type", path, field, `expected ${expected} but received ${recv}${withValue}`);
|
|
24029
24032
|
continue;
|
|
24030
24033
|
}
|
|
24031
24034
|
const rule = ruleForKeyword(e.keyword);
|
package/package.json
CHANGED
|
@@ -250,6 +250,280 @@
|
|
|
250
250
|
"title": "widget",
|
|
251
251
|
"type": "object",
|
|
252
252
|
"allOf": [
|
|
253
|
+
{
|
|
254
|
+
"$comment": "Shape of the legacy options blob for grids — the only structure it has, since widget.options is declared `additionalProperties: true`. Closed at every level: an unknown key is an additional-field finding. The key set and the types are the union observed over 1275 grid widgets (def-yamls-142 plus three real projects); where the stored spelling and the studio's mapper disagree, both are declared, because both are live.",
|
|
255
|
+
"if": {
|
|
256
|
+
"properties": {
|
|
257
|
+
"widgetType": {
|
|
258
|
+
"enum": [
|
|
259
|
+
"grid",
|
|
260
|
+
"grid-v2"
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"required": [
|
|
265
|
+
"widgetType"
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
"then": {
|
|
269
|
+
"properties": {
|
|
270
|
+
"options": {
|
|
271
|
+
"type": "object",
|
|
272
|
+
"additionalProperties": false,
|
|
273
|
+
"properties": {
|
|
274
|
+
"type": {
|
|
275
|
+
"type": "string"
|
|
276
|
+
},
|
|
277
|
+
"usesCases": {
|
|
278
|
+
"type": "boolean"
|
|
279
|
+
},
|
|
280
|
+
"dataset": {
|
|
281
|
+
"type": "string"
|
|
282
|
+
},
|
|
283
|
+
"extraclasses": {
|
|
284
|
+
"$comment": "Extra CSS classes on the widget wrapper. No editor writes it; it rides through from the legacy designer.",
|
|
285
|
+
"type": "string"
|
|
286
|
+
},
|
|
287
|
+
"grid": {
|
|
288
|
+
"type": "object",
|
|
289
|
+
"additionalProperties": false,
|
|
290
|
+
"properties": {
|
|
291
|
+
"showHeader": {
|
|
292
|
+
"type": "boolean"
|
|
293
|
+
},
|
|
294
|
+
"title": {
|
|
295
|
+
"type": "string"
|
|
296
|
+
},
|
|
297
|
+
"showToolbar": {
|
|
298
|
+
"type": "boolean"
|
|
299
|
+
},
|
|
300
|
+
"showSimpleSearch": {
|
|
301
|
+
"type": "boolean"
|
|
302
|
+
},
|
|
303
|
+
"showAdvancedSearch": {
|
|
304
|
+
"type": "boolean"
|
|
305
|
+
},
|
|
306
|
+
"showLinenumbers": {
|
|
307
|
+
"type": "boolean"
|
|
308
|
+
},
|
|
309
|
+
"showColumnHeaders": {
|
|
310
|
+
"type": "boolean"
|
|
311
|
+
},
|
|
312
|
+
"showColumnSelector": {
|
|
313
|
+
"type": "boolean"
|
|
314
|
+
},
|
|
315
|
+
"showFooter": {
|
|
316
|
+
"type": "boolean"
|
|
317
|
+
},
|
|
318
|
+
"noFullCount": {
|
|
319
|
+
"type": "boolean"
|
|
320
|
+
},
|
|
321
|
+
"selectColumn": {
|
|
322
|
+
"type": "boolean"
|
|
323
|
+
},
|
|
324
|
+
"autoHeight": {
|
|
325
|
+
"type": "boolean"
|
|
326
|
+
},
|
|
327
|
+
"saveSearch": {
|
|
328
|
+
"type": "string"
|
|
329
|
+
},
|
|
330
|
+
"orderColumn": {
|
|
331
|
+
"type": "string"
|
|
332
|
+
},
|
|
333
|
+
"height": {
|
|
334
|
+
"$comment": "Every stored value is a string (\"640\"); the studio's mapper writes a number on edit.",
|
|
335
|
+
"type": [
|
|
336
|
+
"string",
|
|
337
|
+
"number"
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
"pagination": {
|
|
341
|
+
"type": "object",
|
|
342
|
+
"additionalProperties": false,
|
|
343
|
+
"properties": {
|
|
344
|
+
"rowsPerPage": {
|
|
345
|
+
"type": [
|
|
346
|
+
"number",
|
|
347
|
+
"string"
|
|
348
|
+
]
|
|
349
|
+
},
|
|
350
|
+
"inifiteScroll": {
|
|
351
|
+
"$comment": "Misspelled in the atalanta runtime that reads it — this is the wire format.",
|
|
352
|
+
"type": "boolean"
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
"gridAggregationRowType": {
|
|
357
|
+
"$comment": "Mirror of the first-class gridAggregationRowType; stored as an empty array on all but one of 475 occurrences, so both spellings are allowed.",
|
|
358
|
+
"type": [
|
|
359
|
+
"string",
|
|
360
|
+
"array"
|
|
361
|
+
]
|
|
362
|
+
},
|
|
363
|
+
"gridAggregationRowPosition": {
|
|
364
|
+
"$comment": "Mirror of the first-class gridAggregationRowPosition; stored as an empty array, as above.",
|
|
365
|
+
"type": [
|
|
366
|
+
"string",
|
|
367
|
+
"array"
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
"row": {
|
|
373
|
+
"type": "object",
|
|
374
|
+
"additionalProperties": false,
|
|
375
|
+
"properties": {
|
|
376
|
+
"clickHandler": {
|
|
377
|
+
"type": "string"
|
|
378
|
+
},
|
|
379
|
+
"clickHandlerColumnCase": {
|
|
380
|
+
"type": "string"
|
|
381
|
+
},
|
|
382
|
+
"rowHeight": {
|
|
383
|
+
"type": [
|
|
384
|
+
"string",
|
|
385
|
+
"number"
|
|
386
|
+
]
|
|
387
|
+
},
|
|
388
|
+
"viewToOpen": {
|
|
389
|
+
"$comment": "Only read when clickHandler is viewHandler; the studio drops both keys when it is not.",
|
|
390
|
+
"type": "string"
|
|
391
|
+
},
|
|
392
|
+
"customViewModalClasses": {
|
|
393
|
+
"type": "string"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"subgrid": {
|
|
398
|
+
"type": "object",
|
|
399
|
+
"additionalProperties": false,
|
|
400
|
+
"properties": {
|
|
401
|
+
"enabled": {
|
|
402
|
+
"type": "boolean"
|
|
403
|
+
},
|
|
404
|
+
"height": {
|
|
405
|
+
"type": [
|
|
406
|
+
"string",
|
|
407
|
+
"number"
|
|
408
|
+
]
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
"columns": {
|
|
413
|
+
"$comment": "Keyed by the dataset column's atalanta case id. On a case-converted grid the entry degrades to a caseId pointer at the gridColumn; on a grid that was never converted it keeps the full inline column settings instead, and those 2798 legacy entries are what the types below are read off. `size` stays untyped: it is a nested map whose own key set has no second source to check against.",
|
|
414
|
+
"type": "object",
|
|
415
|
+
"additionalProperties": {
|
|
416
|
+
"type": "object",
|
|
417
|
+
"additionalProperties": false,
|
|
418
|
+
"properties": {
|
|
419
|
+
"caseId": {
|
|
420
|
+
"type": "string"
|
|
421
|
+
},
|
|
422
|
+
"name": {
|
|
423
|
+
"type": "string"
|
|
424
|
+
},
|
|
425
|
+
"column": {
|
|
426
|
+
"type": "string"
|
|
427
|
+
},
|
|
428
|
+
"title": {
|
|
429
|
+
"type": "string"
|
|
430
|
+
},
|
|
431
|
+
"hidden": {
|
|
432
|
+
"type": "boolean"
|
|
433
|
+
},
|
|
434
|
+
"hideable": {
|
|
435
|
+
"type": "boolean"
|
|
436
|
+
},
|
|
437
|
+
"searchable": {
|
|
438
|
+
"type": "boolean"
|
|
439
|
+
},
|
|
440
|
+
"sortable": {
|
|
441
|
+
"type": "boolean"
|
|
442
|
+
},
|
|
443
|
+
"resizable": {
|
|
444
|
+
"type": "boolean"
|
|
445
|
+
},
|
|
446
|
+
"wordwrap": {
|
|
447
|
+
"type": "boolean"
|
|
448
|
+
},
|
|
449
|
+
"valueAsRowClass": {
|
|
450
|
+
"type": "boolean"
|
|
451
|
+
},
|
|
452
|
+
"render": {
|
|
453
|
+
"type": "string"
|
|
454
|
+
},
|
|
455
|
+
"order": {
|
|
456
|
+
"type": [
|
|
457
|
+
"integer",
|
|
458
|
+
"string"
|
|
459
|
+
]
|
|
460
|
+
},
|
|
461
|
+
"clickHandler": {
|
|
462
|
+
"type": "string"
|
|
463
|
+
},
|
|
464
|
+
"clickHandlerColumnCase": {
|
|
465
|
+
"type": "string"
|
|
466
|
+
},
|
|
467
|
+
"aggregationOperation": {
|
|
468
|
+
"$comment": "Written here by the studio's mapper, but absent from every stored legacy entry — no observed value to type it from, so the key is accepted untyped."
|
|
469
|
+
},
|
|
470
|
+
"size": {
|
|
471
|
+
"type": "object"
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
"activities": {
|
|
477
|
+
"$comment": "Keyed by slot — addActivityId / editActivity / finishActivity / multiNN. Unlike columns these keep their full legacy field set alongside the caseId pointer, so every key here is observed and typed.",
|
|
478
|
+
"type": "object",
|
|
479
|
+
"additionalProperties": {
|
|
480
|
+
"type": "object",
|
|
481
|
+
"additionalProperties": false,
|
|
482
|
+
"properties": {
|
|
483
|
+
"caseId": {
|
|
484
|
+
"type": "string"
|
|
485
|
+
},
|
|
486
|
+
"activity": {
|
|
487
|
+
"type": "string"
|
|
488
|
+
},
|
|
489
|
+
"enabled": {
|
|
490
|
+
"type": "boolean"
|
|
491
|
+
},
|
|
492
|
+
"title": {
|
|
493
|
+
"type": "string"
|
|
494
|
+
},
|
|
495
|
+
"useActivityTitle": {
|
|
496
|
+
"type": "boolean"
|
|
497
|
+
},
|
|
498
|
+
"icon": {
|
|
499
|
+
"type": "string"
|
|
500
|
+
},
|
|
501
|
+
"type": {
|
|
502
|
+
"type": "string"
|
|
503
|
+
},
|
|
504
|
+
"checkRights": {
|
|
505
|
+
"type": "string"
|
|
506
|
+
},
|
|
507
|
+
"whenDoneRefreshType": {
|
|
508
|
+
"type": "string"
|
|
509
|
+
},
|
|
510
|
+
"breaker": {
|
|
511
|
+
"type": "boolean"
|
|
512
|
+
},
|
|
513
|
+
"order": {
|
|
514
|
+
"type": [
|
|
515
|
+
"integer",
|
|
516
|
+
"string"
|
|
517
|
+
]
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
},
|
|
253
527
|
{
|
|
254
528
|
"if": {
|
|
255
529
|
"properties": {
|