praxis-kit 3.1.0 → 4.0.0

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.
@@ -35,8 +35,8 @@ var require_deepMerge = __commonJS({
35
35
  return typeof obj === "object" && obj != null && !Array.isArray(obj);
36
36
  }
37
37
  function deepMerge(first = {}, second = {}) {
38
- const keys = /* @__PURE__ */ new Set([...Object.keys(first), ...Object.keys(second)]);
39
- return Object.fromEntries([...keys].map((key) => {
38
+ const keys2 = /* @__PURE__ */ new Set([...Object.keys(first), ...Object.keys(second)]);
39
+ return Object.fromEntries([...keys2].map((key) => {
40
40
  const firstHasKey = key in first;
41
41
  const secondHasKey = key in second;
42
42
  const firstValue = first[key];
@@ -237,19 +237,185 @@ var require_eslint_utils = __commonJS({
237
237
  }
238
238
  });
239
239
 
240
- // ../eslint-plugin/src/rules/no-dead-compound.ts
240
+ // ../../plugins/eslint/src/rules/no-dead-compound.ts
241
241
  var import_eslint_utils = __toESM(require_eslint_utils(), 1);
242
242
 
243
- // ../eslint-plugin/src/utils/ast.ts
244
- function getObjectProperty(obj, key) {
245
- return obj.properties.find((prop) => {
246
- if (prop.type !== "Property" || prop.kind !== "init" || prop.computed) {
243
+ // ../../lib/primitive/src/utils/is-object.ts
244
+ function isString(value) {
245
+ return typeof value === "string";
246
+ }
247
+
248
+ // ../../lib/primitive/src/utils/iterate.ts
249
+ function find(iterable, callback) {
250
+ for (const value of iterable) {
251
+ const result = callback(value);
252
+ if (result != null) {
253
+ return result;
254
+ }
255
+ }
256
+ return null;
257
+ }
258
+ function some(iterable, predicate) {
259
+ for (const value of iterable) {
260
+ if (predicate(value)) return true;
261
+ }
262
+ return false;
263
+ }
264
+ function every(iterable, predicate) {
265
+ let index = 0;
266
+ for (const value of iterable) {
267
+ if (!predicate(value, index++)) {
247
268
  return false;
248
269
  }
249
- const { key: propKey } = prop;
250
- return propKey.type === "Identifier" && propKey.name === key || propKey.type === "Literal" && propKey.value === key;
251
- });
270
+ }
271
+ return true;
272
+ }
273
+ function* filter(iterable, predicate) {
274
+ let index = 0;
275
+ for (const value of iterable) {
276
+ if (predicate(value, index++)) {
277
+ yield value;
278
+ }
279
+ }
280
+ }
281
+ function* map(iterable, callback) {
282
+ let index = 0;
283
+ for (const value of iterable) {
284
+ yield callback(value, index++);
285
+ }
286
+ }
287
+ function forEach(iterable, callback) {
288
+ let index = 0;
289
+ for (const value of iterable) {
290
+ callback(value, index++);
291
+ }
292
+ }
293
+ function reduce(iterable, initial, callback) {
294
+ let accumulator = initial;
295
+ let index = 0;
296
+ for (const value of iterable) {
297
+ accumulator = callback(accumulator, value, index++);
298
+ }
299
+ return accumulator;
300
+ }
301
+ function collect(iterable, callback) {
302
+ const result = {};
303
+ let index = 0;
304
+ for (const value of iterable) {
305
+ const entry = callback(value, index++);
306
+ if (entry === null) {
307
+ return null;
308
+ }
309
+ result[entry[0]] = entry[1];
310
+ }
311
+ return result;
312
+ }
313
+ function findLast(value, callback) {
314
+ for (let index = value.length - 1; index >= 0; index--) {
315
+ const result = callback(value[index], index);
316
+ if (result != null) {
317
+ return result;
318
+ }
319
+ }
320
+ return null;
321
+ }
322
+ function* items(collection) {
323
+ for (let i = 0; i < collection.length; i++) {
324
+ const item = collection.item(i);
325
+ if (item !== null) {
326
+ yield item;
327
+ }
328
+ }
329
+ }
330
+ function nodeList(list) {
331
+ return {
332
+ *[Symbol.iterator]() {
333
+ for (let i = 0; i < list.length; i++) {
334
+ const node = list.item(i);
335
+ if (node !== null) {
336
+ yield node;
337
+ }
338
+ }
339
+ }
340
+ };
341
+ }
342
+ function mapEntries(m) {
343
+ return m.entries();
344
+ }
345
+ function set(s) {
346
+ return s.values();
252
347
  }
348
+ function hasOwn(object, key) {
349
+ return Object.hasOwn(object, key);
350
+ }
351
+ function* entries(object) {
352
+ for (const key in object) {
353
+ if (!hasOwn(object, key)) continue;
354
+ yield [key, object[key]];
355
+ }
356
+ }
357
+ function* keys(object) {
358
+ for (const [key] of entries(object)) {
359
+ yield key;
360
+ }
361
+ }
362
+ function* values(object) {
363
+ for (const [, value] of entries(object)) {
364
+ yield value;
365
+ }
366
+ }
367
+ function mapValues(object, callback) {
368
+ const result = {};
369
+ for (const [key, value] of entries(object)) {
370
+ result[key] = callback(value, key);
371
+ }
372
+ return result;
373
+ }
374
+ function forEachEntry(object, callback) {
375
+ for (const [key, value] of entries(object)) {
376
+ callback(key, value);
377
+ }
378
+ }
379
+ function forEachKey(object, callback) {
380
+ for (const key of keys(object)) {
381
+ callback(key);
382
+ }
383
+ }
384
+ function forEachValue(object, callback) {
385
+ for (const value of values(object)) {
386
+ callback(value);
387
+ }
388
+ }
389
+ function forEachSet(s, callback) {
390
+ for (const value of s) {
391
+ callback(value);
392
+ }
393
+ }
394
+ var iterate = Object.freeze({
395
+ entries,
396
+ filter,
397
+ find,
398
+ findLast,
399
+ forEach,
400
+ forEachEntry,
401
+ forEachKey,
402
+ forEachSet,
403
+ forEachValue,
404
+ items,
405
+ keys,
406
+ map,
407
+ mapEntries,
408
+ mapValues,
409
+ nodeList,
410
+ reduce,
411
+ collect,
412
+ set,
413
+ some,
414
+ every,
415
+ values
416
+ });
417
+
418
+ // ../../plugins/eslint/src/utils/ast.ts
253
419
  function asObjectExpression(node) {
254
420
  return node?.type === "ObjectExpression" ? node : void 0;
255
421
  }
@@ -271,6 +437,30 @@ function asNumericLiteral(node) {
271
437
  }
272
438
  return void 0;
273
439
  }
440
+ function asStringLiteral(node) {
441
+ if (node?.type === "Literal" && typeof node.value === "string") return node.value;
442
+ return void 0;
443
+ }
444
+ function getPropertyKey(prop) {
445
+ const { key } = prop;
446
+ if (prop.computed) return void 0;
447
+ if (key.type === "Identifier") return key.name;
448
+ if (key.type === "Literal" && typeof key.value === "string") return key.value;
449
+ return void 0;
450
+ }
451
+ function getObjectProperty(obj, key) {
452
+ return obj.properties.find((prop) => {
453
+ if (prop.type !== "Property" || prop.kind !== "init" || prop.computed) {
454
+ return false;
455
+ }
456
+ const { key: propKey } = prop;
457
+ return propKey.type === "Identifier" && propKey.name === key || propKey.type === "Literal" && propKey.value === key;
458
+ });
459
+ }
460
+ function getFirstObjectArg(node) {
461
+ const [first] = node.arguments;
462
+ return first?.type === "ObjectExpression" ? first : void 0;
463
+ }
274
464
  function isFactoryCall(node, calleeNames) {
275
465
  const { callee } = node;
276
466
  if (callee.type === "Identifier") {
@@ -282,43 +472,59 @@ function isFactoryCall(node, calleeNames) {
282
472
  }
283
473
  return false;
284
474
  }
285
- function getFirstObjectArg(node) {
286
- const [first] = node.arguments;
287
- return first?.type === "ObjectExpression" ? first : void 0;
288
- }
289
- function asStringLiteral(node) {
290
- if (node?.type === "Literal" && typeof node.value === "string") return node.value;
291
- return void 0;
292
- }
293
- function getPropertyKey(prop) {
294
- const { key } = prop;
295
- if (prop.computed) return void 0;
296
- if (key.type === "Identifier") return key.name;
297
- if (key.type === "Literal" && typeof key.value === "string") return key.value;
298
- return void 0;
475
+ function extractVariantValues(node) {
476
+ const valuesObj = asObjectExpression(node);
477
+ if (!valuesObj) return void 0;
478
+ const values2 = /* @__PURE__ */ new Set();
479
+ iterate.forEach(valuesObj.properties, (prop) => {
480
+ if (prop.type !== "Property") return;
481
+ const key = getPropertyKey(prop);
482
+ if (key) values2.add(key);
483
+ });
484
+ return values2;
299
485
  }
300
486
  function extractVariantMap(variantsNode) {
301
487
  const variantsObj = asObjectExpression(variantsNode);
302
488
  if (!variantsObj) return void 0;
303
- const map = /* @__PURE__ */ new Map();
304
- for (const prop of variantsObj.properties) {
305
- if (prop.type !== "Property") continue;
489
+ const map2 = /* @__PURE__ */ new Map();
490
+ iterate.forEach(variantsObj.properties, (prop) => {
491
+ if (prop.type !== "Property") return;
306
492
  const key = getPropertyKey(prop);
307
- if (!key) continue;
308
- const valuesObj = asObjectExpression(prop.value);
309
- if (!valuesObj) continue;
310
- const values = /* @__PURE__ */ new Set();
311
- for (const vProp of valuesObj.properties) {
312
- if (vProp.type !== "Property") continue;
313
- const vKey = getPropertyKey(vProp);
314
- if (vKey !== void 0) values.add(vKey);
315
- }
316
- map.set(key, values);
317
- }
318
- return map;
493
+ if (!key) return;
494
+ const values2 = extractVariantValues(prop.value);
495
+ if (!values2) return;
496
+ map2.set(key, values2);
497
+ });
498
+ return map2;
319
499
  }
320
500
 
321
- // ../eslint-plugin/src/rules/no-dead-compound.ts
501
+ // ../../plugins/eslint/src/diagnostics.ts
502
+ var EslintDiagnosticTemplates = {
503
+ // HTML structural rules
504
+ redundantRole: 'role="{{ role }}" is redundant on <{{ tag }}>: the element already carries this implicit ARIA role. Remove the attribute.',
505
+ invalidChild: "<{{ child }}> is not a valid direct child of <{{ parent }}>. Allowed: {{ allowed }}.",
506
+ // Compound variant rules
507
+ deadCompoundKey: '"{{ key }}" is not a variant defined in styling.variants. This compound condition can never match.',
508
+ deadCompoundValue: '"{{ value }}" is not a valid value for variant "{{ key }}". Expected one of: {{ allowed }}. This compound condition can never match.',
509
+ deadCompoundNonLiteral: 'Compound value for "{{ key }}" is not a string literal and cannot be statically validated.',
510
+ // Enforcement rules
511
+ missingStrict: "enforcement.{{ field }} is defined but enforcement.diagnostics is not explicitly set. Pass a Diagnostics instance (e.g. warnDiagnostics, throwDiagnostics) so the enforcement behavior is clear at the call site.",
512
+ // Default value rules
513
+ invalidDefaultKey: '"{{ key }}" is not a variant defined in styling.variants. This default will have no effect.',
514
+ invalidDefaultValue: '"{{ value }}" is not a valid value for variant "{{ key }}". Expected one of: {{ allowed }}. This default will have no effect.',
515
+ invalidDefaultNonLiteral: 'Default value for "{{ key }}" is not a string literal and cannot be statically validated.',
516
+ // Cardinality rules
517
+ negativeMin: "cardinality.min must be >= 0 (got {{ value }}).",
518
+ negativeMax: "cardinality.max must be >= 0 (got {{ value }}).",
519
+ maxLessThanMin: "cardinality.max ({{ max }}) must be >= cardinality.min ({{ min }}). This rule can never be satisfied.",
520
+ zeroMax: "cardinality.max of 0 means no children of this type are allowed. Use 0 intentionally or remove the rule.",
521
+ // Children config rules
522
+ multipleFirst: 'Multiple enforcement.children rules require position: "first". Only one child can occupy the first position.',
523
+ multipleLast: 'Multiple enforcement.children rules require position: "last". Only one child can occupy the last position.',
524
+ minSumExceedsCapacity: 'A rule with position: "only" requires min >= 1, but {{ count }} other rule(s) also require min >= 1. These constraints cannot be satisfied simultaneously.'
525
+ };
526
+
527
+ // ../../plugins/eslint/src/rules/no-dead-compound.ts
322
528
  var createRule = (0, import_eslint_utils.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
323
529
  var noDeadCompound = createRule({
324
530
  name: "no-dead-compound",
@@ -328,9 +534,9 @@ var noDeadCompound = createRule({
328
534
  description: "Disallow compound variant conditions that reference unknown variant keys or values \u2014 compounds that can never fire."
329
535
  },
330
536
  messages: {
331
- unknownVariantKey: '"{{ key }}" is not a variant defined in styling.variants. This compound condition can never match.',
332
- unknownVariantValue: '"{{ value }}" is not a valid value for variant "{{ key }}". Expected one of: {{ allowed }}. This compound condition can never match.',
333
- nonLiteralValue: 'Compound value for "{{ key }}" is not a string literal and cannot be statically validated.'
537
+ unknownVariantKey: EslintDiagnosticTemplates.deadCompoundKey,
538
+ unknownVariantValue: EslintDiagnosticTemplates.deadCompoundValue,
539
+ nonLiteralValue: EslintDiagnosticTemplates.deadCompoundNonLiteral
334
540
  },
335
541
  schema: [
336
542
  {
@@ -364,43 +570,52 @@ var noDeadCompound = createRule({
364
570
  if (!compoundsProp) return;
365
571
  const compounds = asArrayExpression(compoundsProp.value);
366
572
  if (!compounds) return;
367
- for (const element of compounds.elements) {
368
- if (!element || element.type !== "ObjectExpression") continue;
369
- for (const prop of element.properties) {
370
- if (prop.type !== "Property") continue;
371
- const key = getPropertyKey(prop);
372
- if (!key || key === "class" || key === "className") continue;
573
+ iterate.forEach(compounds.elements, (element) => {
574
+ if (!element || element.type !== "ObjectExpression") return;
575
+ iterate.forEach(element.properties, (prop) => {
576
+ if (prop.type !== "Property") return;
577
+ const literalProp = prop;
578
+ const key = getPropertyKey(literalProp);
579
+ if (!key || key === "class" || key === "className") return;
373
580
  if (!variantMap.has(key)) {
374
581
  context.report({
375
582
  node: prop,
376
583
  messageId: "unknownVariantKey",
377
584
  data: { key }
378
585
  });
379
- continue;
586
+ return;
380
587
  }
381
- const value = asStringLiteral(prop.value);
588
+ const value = asStringLiteral(literalProp.value);
382
589
  if (value === void 0) {
383
590
  if (reportNonLiteral) {
384
591
  context.report({ node: prop, messageId: "nonLiteralValue", data: { key } });
385
592
  }
386
- continue;
593
+ return;
387
594
  }
388
595
  const allowed = variantMap.get(key);
389
596
  if (!allowed.has(value)) {
390
597
  context.report({
391
598
  node: prop,
392
599
  messageId: "unknownVariantValue",
393
- data: { key, value, allowed: [...allowed].map((v) => `"${v}"`).join(", ") }
600
+ data: {
601
+ key,
602
+ value,
603
+ allowed: iterate.reduce(
604
+ [...allowed],
605
+ "",
606
+ (acc, value2, index) => index === 0 ? `"${value2}"` : `${acc}, "${value2}"`
607
+ )
608
+ }
394
609
  });
395
610
  }
396
- }
397
- }
611
+ });
612
+ });
398
613
  }
399
614
  };
400
615
  }
401
616
  });
402
617
 
403
- // ../eslint-plugin/src/rules/no-enforcement-without-strict.ts
618
+ // ../../plugins/eslint/src/rules/no-enforcement-without-strict.ts
404
619
  var import_eslint_utils2 = __toESM(require_eslint_utils(), 1);
405
620
  var createRule2 = (0, import_eslint_utils2.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
406
621
  var noEnforcementWithoutStrict = createRule2({
@@ -411,7 +626,7 @@ var noEnforcementWithoutStrict = createRule2({
411
626
  description: "Require enforcement.strict when enforcement.children or enforcement.aria is defined."
412
627
  },
413
628
  messages: {
414
- missingStrict: "enforcement.{{ field }} is defined but enforcement.strict is not explicitly set. Adapter defaults vary \u2014 declare strict explicitly so the behavior is clear at the call site."
629
+ missingStrict: EslintDiagnosticTemplates.missingStrict
415
630
  },
416
631
  schema: [
417
632
  {
@@ -435,26 +650,38 @@ var noEnforcementWithoutStrict = createRule2({
435
650
  if (!enfProp) return;
436
651
  const enf = asObjectExpression(enfProp.value);
437
652
  if (!enf) return;
438
- const hasStrict = getObjectProperty(enf, "strict") !== void 0;
439
- for (const field of ["children", "aria"]) {
440
- const fieldProp = getObjectProperty(enf, field);
441
- if (!fieldProp) continue;
442
- if (field === "children") {
443
- const arr = asArrayExpression(fieldProp.value);
444
- if (!arr || arr.elements.length === 0) continue;
653
+ const hasDiagnostics = getObjectProperty(enf, "diagnostics") !== void 0;
654
+ if (hasDiagnostics) return;
655
+ const field = iterate.find(["children", "aria"], (field2) => {
656
+ const fieldProp = getObjectProperty(enf, field2);
657
+ if (!fieldProp) {
658
+ return null;
445
659
  }
446
- if (!hasStrict) {
447
- context.report({ node, messageId: "missingStrict", data: { field } });
448
- return;
660
+ if (field2 === "children") {
661
+ const arr = asArrayExpression(fieldProp.value);
662
+ if (!arr || arr.elements.length === 0) {
663
+ return null;
664
+ }
449
665
  }
666
+ return field2;
667
+ });
668
+ if (field) {
669
+ context.report({
670
+ node,
671
+ messageId: "missingStrict",
672
+ data: { field }
673
+ });
450
674
  }
451
675
  }
452
676
  };
453
677
  }
454
678
  });
455
679
 
456
- // ../eslint-plugin/src/rules/no-invalid-default.ts
680
+ // ../../plugins/eslint/src/rules/no-invalid-default.ts
457
681
  var import_eslint_utils3 = __toESM(require_eslint_utils(), 1);
682
+ function formatAllowedValues(values2) {
683
+ return Array.from(values2, (value) => `"${value}"`).join(", ");
684
+ }
458
685
  var createRule3 = (0, import_eslint_utils3.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
459
686
  var noInvalidDefault = createRule3({
460
687
  name: "no-invalid-default",
@@ -464,9 +691,9 @@ var noInvalidDefault = createRule3({
464
691
  description: "Disallow styling.defaults entries whose keys or values do not exist in styling.variants."
465
692
  },
466
693
  messages: {
467
- unknownDefaultKey: '"{{ key }}" is not a variant defined in styling.variants. This default will have no effect.',
468
- unknownDefaultValue: '"{{ value }}" is not a valid value for variant "{{ key }}". Expected one of: {{ allowed }}. This default will have no effect.',
469
- nonLiteralValue: 'Default value for "{{ key }}" is not a string literal and cannot be statically validated.'
694
+ unknownDefaultKey: EslintDiagnosticTemplates.invalidDefaultKey,
695
+ unknownDefaultValue: EslintDiagnosticTemplates.invalidDefaultValue,
696
+ nonLiteralValue: EslintDiagnosticTemplates.invalidDefaultNonLiteral
470
697
  },
471
698
  schema: [
472
699
  {
@@ -500,39 +727,39 @@ var noInvalidDefault = createRule3({
500
727
  if (!defaultsProp) return;
501
728
  const defaults = asObjectExpression(defaultsProp.value);
502
729
  if (!defaults) return;
503
- for (const prop of defaults.properties) {
504
- if (prop.type !== "Property") continue;
730
+ iterate.forEach(defaults.properties, (prop) => {
731
+ if (prop.type !== "Property") return;
505
732
  const key = getPropertyKey(prop);
506
- if (!key) continue;
733
+ if (!key) return;
507
734
  if (!variantMap.has(key)) {
508
735
  context.report({ node: prop, messageId: "unknownDefaultKey", data: { key } });
509
- continue;
736
+ return;
510
737
  }
511
738
  const value = asStringLiteral(prop.value);
512
739
  if (value === void 0) {
513
740
  if (reportNonLiteral) {
514
741
  context.report({ node: prop, messageId: "nonLiteralValue", data: { key } });
515
742
  }
516
- continue;
743
+ return;
517
744
  }
518
745
  const allowed = variantMap.get(key);
519
746
  if (!allowed.has(value)) {
520
747
  context.report({
521
748
  node: prop,
522
749
  messageId: "unknownDefaultValue",
523
- data: { key, value, allowed: [...allowed].map((v) => `"${v}"`).join(", ") }
750
+ data: { key, value, allowed: formatAllowedValues(allowed) }
524
751
  });
525
752
  }
526
- }
753
+ });
527
754
  }
528
755
  };
529
756
  }
530
757
  });
531
758
 
532
- // ../eslint-plugin/src/rules/no-invalid-html-nesting.ts
759
+ // ../../plugins/eslint/src/rules/no-invalid-html-nesting.ts
533
760
  var import_eslint_utils4 = __toESM(require_eslint_utils(), 1);
534
761
 
535
- // ../eslint-plugin/src/utils/html-nesting.ts
762
+ // ../../plugins/eslint/src/utils/html-nesting.ts
536
763
  var TAG_CATEGORIES = {
537
764
  // Phrasing + flow
538
765
  abbr: /* @__PURE__ */ new Set(["flow", "phrasing"]),
@@ -691,7 +918,7 @@ var HTML_CONTENT_MODELS = {
691
918
  summary: { kind: "category", allowed: /* @__PURE__ */ new Set(["phrasing", "heading"]) }
692
919
  };
693
920
 
694
- // ../eslint-plugin/src/rules/no-invalid-html-nesting.ts
921
+ // ../../plugins/eslint/src/rules/no-invalid-html-nesting.ts
695
922
  var createRule4 = (0, import_eslint_utils4.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
696
923
  var ALLOWED_TEXT = Object.fromEntries(
697
924
  Object.entries(HTML_CONTENT_MODELS).map(([tag, model]) => [
@@ -717,7 +944,7 @@ var noInvalidHtmlNesting = createRule4({
717
944
  description: "Disallow HTML children that violate the HTML5 content model for their parent element."
718
945
  },
719
946
  messages: {
720
- invalidChild: "<{{ child }}> is not a valid direct child of <{{ parent }}>. Allowed: {{ allowed }}."
947
+ invalidChild: EslintDiagnosticTemplates.invalidChild
721
948
  },
722
949
  schema: []
723
950
  },
@@ -729,11 +956,11 @@ var noInvalidHtmlNesting = createRule4({
729
956
  if (!parentTag) return;
730
957
  const model = HTML_CONTENT_MODELS[parentTag];
731
958
  if (!model) return;
732
- for (const child of node.children) {
733
- if (child.type !== "JSXElement") continue;
959
+ iterate.forEach(node.children, (child) => {
960
+ if (child.type !== "JSXElement") return;
734
961
  const childTag = getIntrinsicTag(child.openingElement.name);
735
- if (childTag === void 0) continue;
736
- if (isAllowed(childTag, model)) continue;
962
+ if (childTag === void 0) return;
963
+ if (isAllowed(childTag, model)) return;
737
964
  context.report({
738
965
  node: child,
739
966
  messageId: "invalidChild",
@@ -743,16 +970,16 @@ var noInvalidHtmlNesting = createRule4({
743
970
  allowed: ALLOWED_TEXT[parentTag] ?? ""
744
971
  }
745
972
  });
746
- }
973
+ });
747
974
  }
748
975
  };
749
976
  }
750
977
  });
751
978
 
752
- // ../eslint-plugin/src/rules/no-redundant-role.ts
979
+ // ../../plugins/eslint/src/rules/no-redundant-role.ts
753
980
  var import_eslint_utils5 = __toESM(require_eslint_utils(), 1);
754
981
 
755
- // ../eslint-plugin/src/utils/implicit-roles.ts
982
+ // ../../plugins/eslint/src/utils/implicit-roles.ts
756
983
  var IMPLICIT_ROLES = {
757
984
  article: "article",
758
985
  aside: "complementary",
@@ -795,28 +1022,31 @@ var IMPLICIT_ROLES = {
795
1022
  ul: "list"
796
1023
  };
797
1024
 
798
- // ../eslint-plugin/src/rules/no-redundant-role.ts
1025
+ // ../../plugins/eslint/src/rules/no-redundant-role.ts
799
1026
  var createRule5 = (0, import_eslint_utils5.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
1027
+ function isRedundantRole(explicit, implicit) {
1028
+ return explicit === implicit;
1029
+ }
800
1030
  function getJsxTagName(node) {
801
1031
  const name = node.name;
802
1032
  if (name.type === "JSXIdentifier") return name.name;
803
1033
  return void 0;
804
1034
  }
805
1035
  function getJsxStringAttribute(node, attrName) {
806
- for (const attr of node.attributes) {
807
- if (attr.type !== "JSXAttribute") continue;
808
- const key = attr.name;
809
- if (key.type !== "JSXIdentifier" || key.name !== attrName) continue;
810
- const val = attr.value;
811
- if (val === null) continue;
812
- if (val.type === "Literal" && typeof val.value === "string") {
1036
+ return iterate.find(node.attributes, (attr) => {
1037
+ if (attr.type !== "JSXAttribute") return null;
1038
+ const { name: key } = attr;
1039
+ if (key.type !== "JSXIdentifier" || key.name !== attrName) return null;
1040
+ const { value: val } = attr;
1041
+ if (val === null) return null;
1042
+ if (val.type === "Literal" && isString(val.value)) {
813
1043
  return { node: attr, value: val.value };
814
1044
  }
815
- if (val.type === "JSXExpressionContainer" && val.expression.type === "Literal" && typeof val.expression.value === "string") {
1045
+ if (val.type === "JSXExpressionContainer" && val.expression.type === "Literal" && isString(val.expression.value)) {
816
1046
  return { node: attr, value: val.expression.value };
817
1047
  }
818
- }
819
- return void 0;
1048
+ return null;
1049
+ }) ?? void 0;
820
1050
  }
821
1051
  var noRedundantRole = createRule5({
822
1052
  name: "no-redundant-role",
@@ -827,7 +1057,7 @@ var noRedundantRole = createRule5({
827
1057
  },
828
1058
  fixable: "code",
829
1059
  messages: {
830
- redundantRole: 'role="{{ role }}" is redundant on <{{ tag }}>: the element already carries this implicit ARIA role. Remove the attribute.'
1060
+ redundantRole: EslintDiagnosticTemplates.redundantRole
831
1061
  },
832
1062
  schema: []
833
1063
  },
@@ -841,11 +1071,11 @@ var noRedundantRole = createRule5({
841
1071
  if (!implicitRole) return;
842
1072
  const roleAttr = getJsxStringAttribute(node, "role");
843
1073
  if (!roleAttr) return;
844
- if (roleAttr.value === implicitRole) {
1074
+ if (isRedundantRole(roleAttr.value, implicitRole)) {
845
1075
  context.report({
846
1076
  node: roleAttr.node,
847
1077
  messageId: "redundantRole",
848
- data: { role: roleAttr.value, tag },
1078
+ data: { tag, role: roleAttr.value },
849
1079
  fix(fixer) {
850
1080
  return fixer.remove(roleAttr.node);
851
1081
  }
@@ -856,7 +1086,7 @@ var noRedundantRole = createRule5({
856
1086
  }
857
1087
  });
858
1088
 
859
- // ../eslint-plugin/src/rules/valid-cardinality.ts
1089
+ // ../../plugins/eslint/src/rules/valid-cardinality.ts
860
1090
  var import_eslint_utils6 = __toESM(require_eslint_utils(), 1);
861
1091
  var createRule6 = (0, import_eslint_utils6.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
862
1092
  var validCardinality = createRule6({
@@ -867,10 +1097,10 @@ var validCardinality = createRule6({
867
1097
  description: "Enforce valid min/max values in enforcement.children cardinality rules."
868
1098
  },
869
1099
  messages: {
870
- negativeMin: "cardinality.min must be >= 0 (got {{ value }}).",
871
- negativeMax: "cardinality.max must be >= 0 (got {{ value }}).",
872
- maxLessThanMin: "cardinality.max ({{ max }}) must be >= cardinality.min ({{ min }}). This rule can never be satisfied.",
873
- zeroMax: "cardinality.max of 0 means no children of this type are allowed. Use 0 intentionally or remove the rule."
1100
+ negativeMin: EslintDiagnosticTemplates.negativeMin,
1101
+ negativeMax: EslintDiagnosticTemplates.negativeMax,
1102
+ maxLessThanMin: EslintDiagnosticTemplates.maxLessThanMin,
1103
+ zeroMax: EslintDiagnosticTemplates.zeroMax
874
1104
  },
875
1105
  schema: [
876
1106
  {
@@ -885,6 +1115,30 @@ var validCardinality = createRule6({
885
1115
  defaultOptions: [{}],
886
1116
  create(context) {
887
1117
  const calleeNames = new Set(context.options[0]?.calleeNames ?? ["createContractComponent"]);
1118
+ function validateCardinality(cardProp) {
1119
+ const card = asObjectExpression(cardProp.value);
1120
+ if (!card) return;
1121
+ const minProp = getObjectProperty(card, "min");
1122
+ const maxProp = getObjectProperty(card, "max");
1123
+ const min = minProp ? asNumericLiteral(minProp.value) : void 0;
1124
+ const max = maxProp ? asNumericLiteral(maxProp.value) : void 0;
1125
+ if (minProp && min !== void 0 && min < 0) {
1126
+ context.report({ node: minProp, messageId: "negativeMin", data: { value: String(min) } });
1127
+ }
1128
+ if (maxProp && max !== void 0 && max < 0) {
1129
+ context.report({ node: maxProp, messageId: "negativeMax", data: { value: String(max) } });
1130
+ }
1131
+ if (maxProp && max === 0) {
1132
+ context.report({ node: maxProp, messageId: "zeroMax" });
1133
+ }
1134
+ if (min !== void 0 && max !== void 0 && min >= 0 && max > 0 && max < min) {
1135
+ context.report({
1136
+ node: cardProp,
1137
+ messageId: "maxLessThanMin",
1138
+ data: { min: String(min), max: String(max) }
1139
+ });
1140
+ }
1141
+ }
888
1142
  return {
889
1143
  CallExpression(node) {
890
1144
  if (!isFactoryCall(node, calleeNames)) return;
@@ -898,49 +1152,44 @@ var validCardinality = createRule6({
898
1152
  if (!childrenProp) return;
899
1153
  const arr = asArrayExpression(childrenProp.value);
900
1154
  if (!arr) return;
901
- for (const element of arr.elements) {
902
- if (!element || element.type !== "ObjectExpression") continue;
1155
+ iterate.forEach(arr.elements, (element) => {
1156
+ if (!element || element.type !== "ObjectExpression") return;
903
1157
  const cardProp = getObjectProperty(element, "cardinality");
904
- if (!cardProp) continue;
905
- const card = asObjectExpression(cardProp.value);
906
- if (!card) continue;
907
- const minProp = getObjectProperty(card, "min");
908
- const maxProp = getObjectProperty(card, "max");
909
- const min = minProp ? asNumericLiteral(minProp.value) : void 0;
910
- const max = maxProp ? asNumericLiteral(maxProp.value) : void 0;
911
- if (min !== void 0 && min < 0) {
912
- context.report({
913
- node: minProp,
914
- messageId: "negativeMin",
915
- data: { value: String(min) }
916
- });
917
- }
918
- if (max !== void 0 && max < 0) {
919
- context.report({
920
- node: maxProp,
921
- messageId: "negativeMax",
922
- data: { value: String(max) }
923
- });
924
- }
925
- if (max !== void 0 && max === 0) {
926
- context.report({ node: maxProp, messageId: "zeroMax" });
927
- }
928
- if (min !== void 0 && max !== void 0 && min >= 0 && max > 0 && max < min) {
929
- context.report({
930
- node: cardProp,
931
- messageId: "maxLessThanMin",
932
- data: { min: String(min), max: String(max) }
933
- });
934
- }
935
- }
1158
+ if (!cardProp) return;
1159
+ validateCardinality(cardProp);
1160
+ });
936
1161
  }
937
1162
  };
938
1163
  }
939
1164
  });
940
1165
 
941
- // ../eslint-plugin/src/rules/valid-children-config.ts
1166
+ // ../../plugins/eslint/src/rules/valid-children-config.ts
942
1167
  var import_eslint_utils7 = __toESM(require_eslint_utils(), 1);
943
1168
  var createRule7 = (0, import_eslint_utils7.RuleCreator)((name) => `https://praxis-kit.dev/eslint-rules/${name}`);
1169
+ function analyzeChildrenRules(elements) {
1170
+ const firstPositionProps = [];
1171
+ const lastPositionProps = [];
1172
+ let onlyWithMinProp = null;
1173
+ let requiredRuleCount = 0;
1174
+ iterate.forEach(elements, (element) => {
1175
+ if (!element || element.type !== "ObjectExpression") return;
1176
+ const positionProp = getObjectProperty(element, "position");
1177
+ const position = positionProp ? asStringLiteral(positionProp.value) : void 0;
1178
+ const cardProp = getObjectProperty(element, "cardinality");
1179
+ const card = cardProp ? asObjectExpression(cardProp.value) : void 0;
1180
+ const minProp = card ? getObjectProperty(card, "min") : void 0;
1181
+ const min = minProp ? asNumericLiteral(minProp.value) ?? 0 : 0;
1182
+ if (position === "first" && positionProp) firstPositionProps.push(positionProp);
1183
+ if (position === "last" && positionProp) lastPositionProps.push(positionProp);
1184
+ if (min >= 1) {
1185
+ requiredRuleCount++;
1186
+ if (position === "only" && positionProp && !onlyWithMinProp) {
1187
+ onlyWithMinProp = positionProp;
1188
+ }
1189
+ }
1190
+ });
1191
+ return { firstPositionProps, lastPositionProps, onlyWithMinProp, requiredRuleCount };
1192
+ }
944
1193
  var validChildrenConfig = createRule7({
945
1194
  name: "valid-children-config",
946
1195
  meta: {
@@ -949,9 +1198,9 @@ var validChildrenConfig = createRule7({
949
1198
  description: "Enforce cross-rule consistency of enforcement.children \u2014 detect positional conflicts and cardinality impossibilities."
950
1199
  },
951
1200
  messages: {
952
- multipleFirst: 'Multiple enforcement.children rules require position: "first". Only one child can occupy the first position.',
953
- multipleLast: 'Multiple enforcement.children rules require position: "last". Only one child can occupy the last position.',
954
- minSumExceedsCapacity: 'A rule with position: "only" requires min >= 1, but {{ count }} other rule(s) also require min >= 1. These constraints cannot be satisfied simultaneously.'
1201
+ multipleFirst: EslintDiagnosticTemplates.multipleFirst,
1202
+ multipleLast: EslintDiagnosticTemplates.multipleLast,
1203
+ minSumExceedsCapacity: EslintDiagnosticTemplates.minSumExceedsCapacity
955
1204
  },
956
1205
  schema: [
957
1206
  {
@@ -979,42 +1228,18 @@ var validChildrenConfig = createRule7({
979
1228
  if (!childrenProp) return;
980
1229
  const arr = asArrayExpression(childrenProp.value);
981
1230
  if (!arr) return;
982
- const firstPositionProps = [];
983
- const lastPositionProps = [];
984
- let onlyWithMinProp = null;
985
- let rulesWithMinCount = 0;
986
- for (const element of arr.elements) {
987
- if (!element || element.type !== "ObjectExpression") continue;
988
- const positionProp = getObjectProperty(element, "position");
989
- const position = positionProp ? asStringLiteral(positionProp.value) : void 0;
990
- const cardProp = getObjectProperty(element, "cardinality");
991
- const card = cardProp ? asObjectExpression(cardProp.value) : void 0;
992
- const minProp = card ? getObjectProperty(card, "min") : void 0;
993
- const min = minProp ? asNumericLiteral(minProp.value) ?? 0 : 0;
994
- if (position === "first" && positionProp) {
995
- firstPositionProps.push(positionProp);
996
- }
997
- if (position === "last" && positionProp) {
998
- lastPositionProps.push(positionProp);
999
- }
1000
- if (min >= 1) {
1001
- rulesWithMinCount++;
1002
- if (position === "only" && positionProp && !onlyWithMinProp) {
1003
- onlyWithMinProp = positionProp;
1004
- }
1005
- }
1006
- }
1007
- for (const prop of firstPositionProps.slice(1)) {
1231
+ const { firstPositionProps, lastPositionProps, onlyWithMinProp, requiredRuleCount } = analyzeChildrenRules(arr.elements);
1232
+ iterate.forEach(firstPositionProps.slice(1), (prop) => {
1008
1233
  context.report({ node: prop, messageId: "multipleFirst" });
1009
- }
1010
- for (const prop of lastPositionProps.slice(1)) {
1234
+ });
1235
+ iterate.forEach(lastPositionProps.slice(1), (prop) => {
1011
1236
  context.report({ node: prop, messageId: "multipleLast" });
1012
- }
1013
- if (onlyWithMinProp && rulesWithMinCount > 1) {
1237
+ });
1238
+ if (onlyWithMinProp && requiredRuleCount > 1) {
1014
1239
  context.report({
1015
1240
  node: onlyWithMinProp,
1016
1241
  messageId: "minSumExceedsCapacity",
1017
- data: { count: String(rulesWithMinCount - 1) }
1242
+ data: { count: String(requiredRuleCount - 1) }
1018
1243
  });
1019
1244
  }
1020
1245
  }
@@ -1022,7 +1247,7 @@ var validChildrenConfig = createRule7({
1022
1247
  }
1023
1248
  });
1024
1249
 
1025
- // ../eslint-plugin/src/index.ts
1250
+ // ../../plugins/eslint/src/index.ts
1026
1251
  var plugin = {
1027
1252
  meta: {
1028
1253
  name: "@praxis-kit/eslint-plugin",