@deslop/coding-standards 0.1.1249 → 0.1.1252
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/dist/lint.js +439 -28
- package/package.json +1 -1
package/dist/lint.js
CHANGED
|
@@ -2307,6 +2307,19 @@ const succeed = (success) => new SuccessImpl(success);
|
|
|
2307
2307
|
const fromOption$1 = /*#__PURE__*/ dual(2, (self, onNone) => isNone$1(self) ? fail(onNone()) : succeed(self.value));
|
|
2308
2308
|
// ../../node_modules/.pnpm/effect@4.1.2/node_modules/effect/dist/Order.js
|
|
2309
2309
|
/**
|
|
2310
|
+
* Defines comparison functions for ordered values.
|
|
2311
|
+
*
|
|
2312
|
+
* An `Order<A>` compares two `A` values and returns whether the first is less
|
|
2313
|
+
* than, equal to, or greater than the second. Orders are used for sorting,
|
|
2314
|
+
* choosing minimum or maximum values, checking ranges, and building ordered data
|
|
2315
|
+
* structures. This module includes built-in orders, constructors for custom
|
|
2316
|
+
* orders, tools for reversing and combining comparisons, tuple and struct
|
|
2317
|
+
* helpers, comparison predicates, clamping, and reducer support.
|
|
2318
|
+
*
|
|
2319
|
+
* @stability stable
|
|
2320
|
+
* @since 2.0.0
|
|
2321
|
+
*/
|
|
2322
|
+
/**
|
|
2310
2323
|
* Creates a new `Order` instance from a comparison function.
|
|
2311
2324
|
*
|
|
2312
2325
|
* **When to use**
|
|
@@ -2374,6 +2387,76 @@ function make$4(compare) {
|
|
|
2374
2387
|
* @since 4.0.0
|
|
2375
2388
|
*/
|
|
2376
2389
|
const String$2 = /*#__PURE__*/ make$4((self, that) => self < that ? -1 : 1);
|
|
2390
|
+
/**
|
|
2391
|
+
* Order instance for numbers that compares them numerically.
|
|
2392
|
+
*
|
|
2393
|
+
* **When to use**
|
|
2394
|
+
*
|
|
2395
|
+
* Use when you need numeric ordering for numbers.
|
|
2396
|
+
*
|
|
2397
|
+
* **Details**
|
|
2398
|
+
*
|
|
2399
|
+
* `0` is considered equal to `-0`. All `NaN` values are considered equal to
|
|
2400
|
+
* each other, and any `NaN` is considered less than any non-`NaN` number. All
|
|
2401
|
+
* other values use standard numeric comparison.
|
|
2402
|
+
*
|
|
2403
|
+
* **Example** (Ordering numbers)
|
|
2404
|
+
*
|
|
2405
|
+
* ```ts import.meta.vitest
|
|
2406
|
+
* import { Order } from "effect"
|
|
2407
|
+
*
|
|
2408
|
+
* Order.Number(1, 1) // => 0
|
|
2409
|
+
* Order.Number(1, 2) // => -1
|
|
2410
|
+
* Order.Number(2, 1) // => 1
|
|
2411
|
+
*
|
|
2412
|
+
* Order.Number(0, -0) // => 0
|
|
2413
|
+
* Order.Number(NaN, 1) // => -1
|
|
2414
|
+
* ```
|
|
2415
|
+
*
|
|
2416
|
+
* @see {@link mapInput} to compare objects by a number property
|
|
2417
|
+
* @see {@link BigInt} for bigint comparisons
|
|
2418
|
+
* @stability stable
|
|
2419
|
+
* @category instances
|
|
2420
|
+
* @since 4.0.0
|
|
2421
|
+
*/
|
|
2422
|
+
const Number$2 = /*#__PURE__*/ make$4((self, that) => {
|
|
2423
|
+
if (globalThis.Number.isNaN(self) && globalThis.Number.isNaN(that)) return 0;
|
|
2424
|
+
if (globalThis.Number.isNaN(self)) return -1;
|
|
2425
|
+
if (globalThis.Number.isNaN(that)) return 1;
|
|
2426
|
+
return self < that ? -1 : 1;
|
|
2427
|
+
});
|
|
2428
|
+
/**
|
|
2429
|
+
* Returns the maximum of two values according to the given order. If they are equal, returns the first argument.
|
|
2430
|
+
*
|
|
2431
|
+
* **When to use**
|
|
2432
|
+
*
|
|
2433
|
+
* Use when you need to select the larger of two values according to an
|
|
2434
|
+
* `Order`.
|
|
2435
|
+
*
|
|
2436
|
+
* **Details**
|
|
2437
|
+
*
|
|
2438
|
+
* Returns the value that compares as greater than or equal to the other value.
|
|
2439
|
+
* If values are equal, the first argument is returned.
|
|
2440
|
+
*
|
|
2441
|
+
* **Example** (Selecting the maximum value)
|
|
2442
|
+
*
|
|
2443
|
+
* ```ts import.meta.vitest
|
|
2444
|
+
* import { Order } from "effect"
|
|
2445
|
+
*
|
|
2446
|
+
* const maxNumber = Order.max(Order.Number)
|
|
2447
|
+
*
|
|
2448
|
+
* maxNumber(1, 2) // => 2
|
|
2449
|
+
* maxNumber(2, 1) // => 2
|
|
2450
|
+
* maxNumber(1, 1) // => 1
|
|
2451
|
+
* ```
|
|
2452
|
+
*
|
|
2453
|
+
* @see {@link min} for the minimum of two values
|
|
2454
|
+
* @see {@link clamp} to clamp a value between min and max
|
|
2455
|
+
* @stability stable
|
|
2456
|
+
* @category comparisons
|
|
2457
|
+
* @since 2.0.0
|
|
2458
|
+
*/
|
|
2459
|
+
const max$1 = (O) => dual(2, (self, that) => self === that || O(self, that) > -1 ? self : that);
|
|
2377
2460
|
// ../../node_modules/.pnpm/effect@4.1.2/node_modules/effect/dist/Option.js
|
|
2378
2461
|
/**
|
|
2379
2462
|
* Creates an `Option` representing the absence of a value.
|
|
@@ -4565,6 +4648,33 @@ const filter = /*#__PURE__*/ dual(2, (self, predicate) => {
|
|
|
4565
4648
|
return out;
|
|
4566
4649
|
});
|
|
4567
4650
|
/**
|
|
4651
|
+
* Folds an iterable from left to right into a single value.
|
|
4652
|
+
*
|
|
4653
|
+
* **When to use**
|
|
4654
|
+
*
|
|
4655
|
+
* Use to combine all elements into one accumulated value from left to right.
|
|
4656
|
+
*
|
|
4657
|
+
* **Details**
|
|
4658
|
+
*
|
|
4659
|
+
* The function receives `(accumulator, element, index)`.
|
|
4660
|
+
*
|
|
4661
|
+
* **Example** (Summing an array)
|
|
4662
|
+
*
|
|
4663
|
+
* ```ts import.meta.vitest
|
|
4664
|
+
* import { Array } from "effect"
|
|
4665
|
+
*
|
|
4666
|
+
* Array.reduce([1, 2, 3], 0, (acc, n) => acc + n) // => 6
|
|
4667
|
+
* ```
|
|
4668
|
+
*
|
|
4669
|
+
* @see {@link reduceRight} — fold from right to left
|
|
4670
|
+
* @see {@link scan} — fold keeping intermediate values
|
|
4671
|
+
*
|
|
4672
|
+
* @stability stable
|
|
4673
|
+
* @category folding
|
|
4674
|
+
* @since 2.0.0
|
|
4675
|
+
*/
|
|
4676
|
+
const reduce = /*#__PURE__*/ dual(3, (self, b, f) => fromIterable(self).reduce((b, a, i) => f(b, a, i), b));
|
|
4677
|
+
/**
|
|
4568
4678
|
* Checks whether all elements satisfy the predicate. Supports refinements for
|
|
4569
4679
|
* type narrowing.
|
|
4570
4680
|
*
|
|
@@ -4832,6 +4942,28 @@ const TaggedError = TaggedError$1;
|
|
|
4832
4942
|
*/
|
|
4833
4943
|
const Number$1 = globalThis.Number;
|
|
4834
4944
|
/**
|
|
4945
|
+
* Returns the maximum between two `number`s.
|
|
4946
|
+
*
|
|
4947
|
+
* **When to use**
|
|
4948
|
+
*
|
|
4949
|
+
* Use to select the larger of two numbers.
|
|
4950
|
+
*
|
|
4951
|
+
* **Example** (Finding the maximum)
|
|
4952
|
+
*
|
|
4953
|
+
* ```ts import.meta.vitest
|
|
4954
|
+
* import { Number } from "effect"
|
|
4955
|
+
*
|
|
4956
|
+
* Number.max(2, 3) // => 3
|
|
4957
|
+
* ```
|
|
4958
|
+
*
|
|
4959
|
+
* @see {@link min} for selecting the smaller value
|
|
4960
|
+
*
|
|
4961
|
+
* @stability stable
|
|
4962
|
+
* @category math
|
|
4963
|
+
* @since 2.0.0
|
|
4964
|
+
*/
|
|
4965
|
+
const max = /*#__PURE__*/ max$1(Number$2);
|
|
4966
|
+
/**
|
|
4835
4967
|
* Parses a `number` from a `string` safely using the `Number()` function.
|
|
4836
4968
|
* The following special string values are supported: "NaN", "Infinity", "-Infinity".
|
|
4837
4969
|
*
|
|
@@ -4904,6 +5036,28 @@ const Order = String$2;
|
|
|
4904
5036
|
*/
|
|
4905
5037
|
const toUpperCase = (self) => self.toUpperCase();
|
|
4906
5038
|
/**
|
|
5039
|
+
* Replaces matches in a string using `String.prototype.replace`.
|
|
5040
|
+
*
|
|
5041
|
+
* **Details**
|
|
5042
|
+
*
|
|
5043
|
+
* String search values and non-global regular expressions replace the first
|
|
5044
|
+
* match; global regular expressions replace every match.
|
|
5045
|
+
*
|
|
5046
|
+
* **Example** (Replacing a substring)
|
|
5047
|
+
*
|
|
5048
|
+
* ```ts import.meta.vitest
|
|
5049
|
+
* import { pipe, String } from "effect"
|
|
5050
|
+
*
|
|
5051
|
+
* pipe("abc", String.replace("b", "d")) // => "adc"
|
|
5052
|
+
* pipe("hello world", String.replace("world", "Effect")) // => "hello Effect"
|
|
5053
|
+
* ```
|
|
5054
|
+
*
|
|
5055
|
+
* @stability stable
|
|
5056
|
+
* @category transforming
|
|
5057
|
+
* @since 2.0.0
|
|
5058
|
+
*/
|
|
5059
|
+
const replace = (searchValue, replaceValue) => (self) => self.replace(searchValue, replaceValue);
|
|
5060
|
+
/**
|
|
4907
5061
|
* Removes whitespace from both ends of a string.
|
|
4908
5062
|
*
|
|
4909
5063
|
* **Example** (Trimming whitespace)
|
|
@@ -7691,7 +7845,7 @@ const noFloatingDerivedType = defineRule({
|
|
|
7691
7845
|
});
|
|
7692
7846
|
// src/rules/no-gradient.ts
|
|
7693
7847
|
const GRADIENT = /(?:^|[\s:])bg-(?:linear|radial|conic|gradient)(?:-|$|\s)|gradient\(/u;
|
|
7694
|
-
function report$
|
|
7848
|
+
function report$6(context, node) {
|
|
7695
7849
|
context.report({
|
|
7696
7850
|
message: "Use a flat theme token such as bg-card or bg-muted; gradients are never part of the design.",
|
|
7697
7851
|
node
|
|
@@ -7700,10 +7854,10 @@ function report$5(context, node) {
|
|
|
7700
7854
|
const noGradient = defineRule({
|
|
7701
7855
|
create: (context) => ({
|
|
7702
7856
|
Literal: (node) => {
|
|
7703
|
-
if (isString(node.value) && GRADIENT.test(node.value)) report$
|
|
7857
|
+
if (isString(node.value) && GRADIENT.test(node.value)) report$6(context, node);
|
|
7704
7858
|
},
|
|
7705
7859
|
TemplateElement: (node) => {
|
|
7706
|
-
if (GRADIENT.test(node.value.raw)) report$
|
|
7860
|
+
if (GRADIENT.test(node.value.raw)) report$6(context, node);
|
|
7707
7861
|
}
|
|
7708
7862
|
}),
|
|
7709
7863
|
meta: { type: "problem" }
|
|
@@ -7791,7 +7945,7 @@ function replaceableGuard(node) {
|
|
|
7791
7945
|
"typeof === undefined": "isUndefined"
|
|
7792
7946
|
}, key)));
|
|
7793
7947
|
}
|
|
7794
|
-
function report$
|
|
7948
|
+
function report$5(input) {
|
|
7795
7949
|
map$1(replaceableGuard(input.node), (guard) => input.context.report({
|
|
7796
7950
|
message: `Use Predicate.${guard} instead of this hand-written type guard.`,
|
|
7797
7951
|
node: input.node
|
|
@@ -7800,19 +7954,19 @@ function report$4(input) {
|
|
|
7800
7954
|
const noHandWrittenGuard = defineRule({
|
|
7801
7955
|
create: (context) => ({
|
|
7802
7956
|
ArrowFunctionExpression: (node) => {
|
|
7803
|
-
report$
|
|
7957
|
+
report$5({
|
|
7804
7958
|
context,
|
|
7805
7959
|
node
|
|
7806
7960
|
});
|
|
7807
7961
|
},
|
|
7808
7962
|
FunctionDeclaration: (node) => {
|
|
7809
|
-
report$
|
|
7963
|
+
report$5({
|
|
7810
7964
|
context,
|
|
7811
7965
|
node
|
|
7812
7966
|
});
|
|
7813
7967
|
},
|
|
7814
7968
|
FunctionExpression: (node) => {
|
|
7815
|
-
report$
|
|
7969
|
+
report$5({
|
|
7816
7970
|
context,
|
|
7817
7971
|
node
|
|
7818
7972
|
});
|
|
@@ -7863,14 +8017,14 @@ const PRIMITIVES = {
|
|
|
7863
8017
|
textarea: "Textarea"
|
|
7864
8018
|
};
|
|
7865
8019
|
const CONTROL_STYLE = /(?:^|:)(?:hover|focus|focus-visible|active):|(?:^|:)(?:rounded|shadow|ring)(?:-|$)|(?:^|:)p[blrtxy]?-(?!0$)|(?:^|:)bg-(?!transparent$)|(?:^|:)border(?:-[blrtxy])?$|(?:^|:)border-(?!0$|[blrtxy]-0$)/u;
|
|
7866
|
-
function classStrings(node) {
|
|
8020
|
+
function classStrings$1(node) {
|
|
7867
8021
|
if (node.type === "Literal") return filter([node.value], isString);
|
|
7868
8022
|
if (node.type === "TemplateLiteral") return map(node.quasis, (quasi) => quasi.value.raw);
|
|
7869
|
-
if (node.type === "JSXExpressionContainer") return classStrings(node.expression);
|
|
7870
|
-
if (node.type === "CallExpression") return flatMap(node.arguments, classStrings);
|
|
7871
|
-
if (node.type === "ConditionalExpression") return flatMap([node.consequent, node.alternate], classStrings);
|
|
7872
|
-
if (node.type === "LogicalExpression") return classStrings(node.right);
|
|
7873
|
-
if (node.type === "ArrayExpression") return flatMap(filter(node.elements, isNotNull), classStrings);
|
|
8023
|
+
if (node.type === "JSXExpressionContainer") return classStrings$1(node.expression);
|
|
8024
|
+
if (node.type === "CallExpression") return flatMap(node.arguments, classStrings$1);
|
|
8025
|
+
if (node.type === "ConditionalExpression") return flatMap([node.consequent, node.alternate], classStrings$1);
|
|
8026
|
+
if (node.type === "LogicalExpression") return classStrings$1(node.right);
|
|
8027
|
+
if (node.type === "ArrayExpression") return flatMap(filter(node.elements, isNotNull), classStrings$1);
|
|
7874
8028
|
return empty$2();
|
|
7875
8029
|
}
|
|
7876
8030
|
const noNativeControl = defineRule({
|
|
@@ -7880,7 +8034,7 @@ const noNativeControl = defineRule({
|
|
|
7880
8034
|
map$1(get$3(PRIMITIVES, name), (primitive) => {
|
|
7881
8035
|
const styled = pipe(node.attributes, findFirst((attribute) => attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier" && attribute.name.name === "className"), map$1((attribute) => {
|
|
7882
8036
|
if (attribute.type !== "JSXAttribute" || attribute.value === null) return empty$2();
|
|
7883
|
-
return classStrings(attribute.value);
|
|
8037
|
+
return classStrings$1(attribute.value);
|
|
7884
8038
|
}), exists((values) => some(values, (value) => some(split(value, /\s+/u), matches(CONTROL_STYLE)))));
|
|
7885
8039
|
if (name !== "select" && !styled) return;
|
|
7886
8040
|
context.report({
|
|
@@ -8304,6 +8458,139 @@ const noPollingTest = defineRule({
|
|
|
8304
8458
|
},
|
|
8305
8459
|
meta: { type: "problem" }
|
|
8306
8460
|
});
|
|
8461
|
+
// src/rules/no-primitive-restyle.ts
|
|
8462
|
+
const UI_MODULES = ["@deslop/components-web/ui/", "#components/ui/"];
|
|
8463
|
+
const PLACEMENT_PREFIXES = [
|
|
8464
|
+
"m-",
|
|
8465
|
+
"mx-",
|
|
8466
|
+
"my-",
|
|
8467
|
+
"mt-",
|
|
8468
|
+
"mr-",
|
|
8469
|
+
"mb-",
|
|
8470
|
+
"ml-",
|
|
8471
|
+
"ms-",
|
|
8472
|
+
"me-",
|
|
8473
|
+
"w-",
|
|
8474
|
+
"h-",
|
|
8475
|
+
"size-",
|
|
8476
|
+
"min-w-",
|
|
8477
|
+
"min-h-",
|
|
8478
|
+
"max-w-",
|
|
8479
|
+
"max-h-",
|
|
8480
|
+
"basis-",
|
|
8481
|
+
"order-",
|
|
8482
|
+
"col-span-",
|
|
8483
|
+
"col-start-",
|
|
8484
|
+
"col-end-",
|
|
8485
|
+
"row-span-",
|
|
8486
|
+
"row-start-",
|
|
8487
|
+
"row-end-",
|
|
8488
|
+
"self-",
|
|
8489
|
+
"justify-self-",
|
|
8490
|
+
"place-self-",
|
|
8491
|
+
"inset-",
|
|
8492
|
+
"inset-x-",
|
|
8493
|
+
"inset-y-",
|
|
8494
|
+
"top-",
|
|
8495
|
+
"right-",
|
|
8496
|
+
"bottom-",
|
|
8497
|
+
"left-",
|
|
8498
|
+
"start-",
|
|
8499
|
+
"end-",
|
|
8500
|
+
"z-",
|
|
8501
|
+
"translate-",
|
|
8502
|
+
"pointer-events-"
|
|
8503
|
+
];
|
|
8504
|
+
const PLACEMENT_EXACT = [
|
|
8505
|
+
"flex-1",
|
|
8506
|
+
"flex-auto",
|
|
8507
|
+
"flex-none",
|
|
8508
|
+
"grow",
|
|
8509
|
+
"grow-0",
|
|
8510
|
+
"shrink",
|
|
8511
|
+
"shrink-0",
|
|
8512
|
+
"relative",
|
|
8513
|
+
"absolute",
|
|
8514
|
+
"fixed",
|
|
8515
|
+
"sticky",
|
|
8516
|
+
"hidden",
|
|
8517
|
+
"block",
|
|
8518
|
+
"flex",
|
|
8519
|
+
"inline-flex",
|
|
8520
|
+
"grid",
|
|
8521
|
+
"sr-only"
|
|
8522
|
+
];
|
|
8523
|
+
const RESTYLE = "A shadcn component keeps its shipped look: className only places it (margin, size, position, flex or grid placement). Pick a variant or change the composition instead of restyling.";
|
|
8524
|
+
function uiImport(program) {
|
|
8525
|
+
return flatMap(program.body, (statement) => {
|
|
8526
|
+
if (statement.type !== "ImportDeclaration") return empty$2();
|
|
8527
|
+
if (!some(UI_MODULES, (prefix) => startsWith(prefix)(statement.source.value))) return empty$2();
|
|
8528
|
+
return map(statement.specifiers, (specifier) => specifier.local.name);
|
|
8529
|
+
});
|
|
8530
|
+
}
|
|
8531
|
+
function classStrings(node) {
|
|
8532
|
+
if (node.type === "Literal") return filter([node.value], isString);
|
|
8533
|
+
if (node.type === "TemplateLiteral") return map(node.quasis, (quasi) => quasi.value.raw);
|
|
8534
|
+
if (node.type === "JSXExpressionContainer") return classStrings(node.expression);
|
|
8535
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "cn") return flatMap(node.arguments, (argument) => classStrings(argument));
|
|
8536
|
+
return empty$2();
|
|
8537
|
+
}
|
|
8538
|
+
function utility(token) {
|
|
8539
|
+
const scanned = reduce(split("")(token), {
|
|
8540
|
+
depth: 0,
|
|
8541
|
+
end: 0,
|
|
8542
|
+
index: 0
|
|
8543
|
+
}, (state, character) => {
|
|
8544
|
+
const index = state.index + 1;
|
|
8545
|
+
if (character === "[") return {
|
|
8546
|
+
depth: state.depth + 1,
|
|
8547
|
+
end: state.end,
|
|
8548
|
+
index
|
|
8549
|
+
};
|
|
8550
|
+
if (character === "]") return {
|
|
8551
|
+
depth: max(0, state.depth - 1),
|
|
8552
|
+
end: state.end,
|
|
8553
|
+
index
|
|
8554
|
+
};
|
|
8555
|
+
if (character === ":" && state.depth === 0) return {
|
|
8556
|
+
depth: state.depth,
|
|
8557
|
+
end: index,
|
|
8558
|
+
index
|
|
8559
|
+
};
|
|
8560
|
+
return {
|
|
8561
|
+
depth: state.depth,
|
|
8562
|
+
end: state.end,
|
|
8563
|
+
index
|
|
8564
|
+
};
|
|
8565
|
+
});
|
|
8566
|
+
return pipe(token, slice(scanned.end), replaceAll(/^!|!$/gu, ""), replace(/^-/u, ""));
|
|
8567
|
+
}
|
|
8568
|
+
function places(token) {
|
|
8569
|
+
const name = utility(token);
|
|
8570
|
+
return contains(PLACEMENT_EXACT, name) || some(PLACEMENT_PREFIXES, (prefix) => startsWith(prefix)(name));
|
|
8571
|
+
}
|
|
8572
|
+
function restyled(attribute) {
|
|
8573
|
+
if (attribute.value === null) return false;
|
|
8574
|
+
return pipe(classStrings(attribute.value), flatMap((value) => split(value, /\s+/u)), filter(isNonEmpty), some((token) => !places(token)));
|
|
8575
|
+
}
|
|
8576
|
+
const noPrimitiveRestyle = defineRule({
|
|
8577
|
+
create: (context) => {
|
|
8578
|
+
const file = { primitives: empty$2() };
|
|
8579
|
+
return {
|
|
8580
|
+
JSXOpeningElement: (node) => {
|
|
8581
|
+
if (node.name.type !== "JSXIdentifier" || !contains(file.primitives, node.name.name)) return;
|
|
8582
|
+
pipe(findFirst(node.attributes, (attribute) => attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier" && attribute.name.name === "className"), filter$1((attribute) => attribute.type === "JSXAttribute" && restyled(attribute)), map$1((attribute) => context.report({
|
|
8583
|
+
message: RESTYLE,
|
|
8584
|
+
node: attribute
|
|
8585
|
+
})));
|
|
8586
|
+
},
|
|
8587
|
+
Program: (node) => {
|
|
8588
|
+
file.primitives = uiImport(node);
|
|
8589
|
+
}
|
|
8590
|
+
};
|
|
8591
|
+
},
|
|
8592
|
+
meta: { type: "problem" }
|
|
8593
|
+
});
|
|
8307
8594
|
// src/rules/no-property-alias.ts
|
|
8308
8595
|
const FUNCTIONS = [
|
|
8309
8596
|
"ArrowFunctionExpression",
|
|
@@ -8400,7 +8687,7 @@ function replacement(input) {
|
|
|
8400
8687
|
if (input.read.parent?.type === "Property" && input.read.parent.shorthand) return `${input.name}: ${input.text}`;
|
|
8401
8688
|
return input.text;
|
|
8402
8689
|
}
|
|
8403
|
-
function report$
|
|
8690
|
+
function report$4(input) {
|
|
8404
8691
|
const reads = pipe(input.variable.references, filter((reference) => reference.isRead()), map((reference) => reference.identifier));
|
|
8405
8692
|
const text = input.context.sourceCode.getText(input.init);
|
|
8406
8693
|
const aliasRequired = needsAlias({
|
|
@@ -8479,7 +8766,7 @@ const noPropertyAlias = defineRule({
|
|
|
8479
8766
|
scope: context.sourceCode.getScope(candidate.node)
|
|
8480
8767
|
}), match$2({
|
|
8481
8768
|
onNone: constVoid,
|
|
8482
|
-
onSome: (variable) => report$
|
|
8769
|
+
onSome: (variable) => report$4({
|
|
8483
8770
|
...candidate,
|
|
8484
8771
|
context,
|
|
8485
8772
|
variable,
|
|
@@ -8675,7 +8962,7 @@ const shipped = [
|
|
|
8675
8962
|
schema: "Natural"
|
|
8676
8963
|
}
|
|
8677
8964
|
];
|
|
8678
|
-
function schemaMember$
|
|
8965
|
+
function schemaMember$2(input) {
|
|
8679
8966
|
if (input.node.type !== "MemberExpression" || !importedMember({
|
|
8680
8967
|
context: input.context,
|
|
8681
8968
|
importedName: "Schema",
|
|
@@ -8685,11 +8972,11 @@ function schemaMember$1(input) {
|
|
|
8685
8972
|
}
|
|
8686
8973
|
function shippedSchema(input) {
|
|
8687
8974
|
if (input.filter.type !== "CallExpression") return none();
|
|
8688
|
-
const base = schemaMember$
|
|
8975
|
+
const base = schemaMember$2({
|
|
8689
8976
|
context: input.context,
|
|
8690
8977
|
node: input.base
|
|
8691
8978
|
});
|
|
8692
|
-
const check = schemaMember$
|
|
8979
|
+
const check = schemaMember$2({
|
|
8693
8980
|
context: input.context,
|
|
8694
8981
|
node: input.filter.callee
|
|
8695
8982
|
});
|
|
@@ -8712,7 +8999,7 @@ function reinventedSchema(input) {
|
|
|
8712
8999
|
if (input.node.callee.type !== "MemberExpression" || !contains$1(memberName(input.node.callee), "check")) return none();
|
|
8713
9000
|
const callee = input.node.callee;
|
|
8714
9001
|
const [filter] = input.node.arguments;
|
|
8715
|
-
if (isSome(schemaMember$
|
|
9002
|
+
if (isSome(schemaMember$2({
|
|
8716
9003
|
context: input.context,
|
|
8717
9004
|
node: callee
|
|
8718
9005
|
}))) {
|
|
@@ -9275,7 +9562,7 @@ function executes(context, node) {
|
|
|
9275
9562
|
function receiver(read) {
|
|
9276
9563
|
return read.parent?.type === "MemberExpression" && read.parent.object === read && read.parent.parent.type === "CallExpression" && read.parent.parent.callee === read.parent;
|
|
9277
9564
|
}
|
|
9278
|
-
function report$
|
|
9565
|
+
function report$3(input) {
|
|
9279
9566
|
const declaration = input.node.parent;
|
|
9280
9567
|
const init = input.node.init;
|
|
9281
9568
|
if (declaration.type !== "VariableDeclaration" || declaration.parent.type !== "BlockStatement" || input.node.id.type !== "Identifier" || init === null) return;
|
|
@@ -9332,7 +9619,7 @@ const noSingleUseValue = defineRule({
|
|
|
9332
9619
|
NewExpression: effect,
|
|
9333
9620
|
"Program:exit": () => {
|
|
9334
9621
|
const nodes = toArray(effects);
|
|
9335
|
-
for (const node of toArray(candidates)) report$
|
|
9622
|
+
for (const node of toArray(candidates)) report$3({
|
|
9336
9623
|
context,
|
|
9337
9624
|
effects: nodes,
|
|
9338
9625
|
node
|
|
@@ -9639,7 +9926,7 @@ const noTestTimeout = defineRule({
|
|
|
9639
9926
|
meta: { type: "problem" }
|
|
9640
9927
|
});
|
|
9641
9928
|
// src/rules/no-type-from-value.ts
|
|
9642
|
-
function schemaMember(name) {
|
|
9929
|
+
function schemaMember$1(name) {
|
|
9643
9930
|
return name.type === "TSQualifiedName" && contains([
|
|
9644
9931
|
"Encoded",
|
|
9645
9932
|
"Type",
|
|
@@ -9652,7 +9939,7 @@ function schemaMember(name) {
|
|
|
9652
9939
|
function valueQuery(node) {
|
|
9653
9940
|
if (node.type === "TSParenthesizedType") return valueQuery(node.typeAnnotation);
|
|
9654
9941
|
if (node.type === "TSIndexedAccessType") return valueQuery(node.objectType);
|
|
9655
|
-
return node.type === "TSTypeQuery" && (node.exprName.type === "Identifier" || node.exprName.type === "TSQualifiedName" && !schemaMember(node.exprName));
|
|
9942
|
+
return node.type === "TSTypeQuery" && (node.exprName.type === "Identifier" || node.exprName.type === "TSQualifiedName" && !schemaMember$1(node.exprName));
|
|
9656
9943
|
}
|
|
9657
9944
|
function nestedObject(node) {
|
|
9658
9945
|
return node.parent?.type === "TSIndexedAccessType" && node.parent.objectType === node;
|
|
@@ -10001,7 +10288,7 @@ function fix(input) {
|
|
|
10001
10288
|
return some$1([input.fixer.replaceTextRange([open.range[0], close.range[1]], "(cause)"), insertion]);
|
|
10002
10289
|
}), () => []);
|
|
10003
10290
|
}
|
|
10004
|
-
function report$
|
|
10291
|
+
function report$2(context, node) {
|
|
10005
10292
|
context.report({
|
|
10006
10293
|
fix: (fixer) => fix({
|
|
10007
10294
|
context,
|
|
@@ -10014,7 +10301,7 @@ function report$1(context, node) {
|
|
|
10014
10301
|
}
|
|
10015
10302
|
function reportOption(context, key, bare, options) {
|
|
10016
10303
|
if (options?.type !== "ObjectExpression") return;
|
|
10017
|
-
for (const property of options.properties) if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === key && dropsCause(context, property.value, bare)) report$
|
|
10304
|
+
for (const property of options.properties) if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === key && dropsCause(context, property.value, bare)) report$2(context, property.value);
|
|
10018
10305
|
}
|
|
10019
10306
|
const preserveErrorCause = defineRule({
|
|
10020
10307
|
create: (context) => ({ CallExpression: (node) => {
|
|
@@ -10024,7 +10311,7 @@ const preserveErrorCause = defineRule({
|
|
|
10024
10311
|
});
|
|
10025
10312
|
if (contains$1(name, "mapError")) {
|
|
10026
10313
|
const bare = detailedFailure(context, node);
|
|
10027
|
-
forEach(filter(node.arguments, (argument) => dropsCause(context, argument, bare)), (callback) => report$
|
|
10314
|
+
forEach(filter(node.arguments, (argument) => dropsCause(context, argument, bare)), (callback) => report$2(context, callback));
|
|
10028
10315
|
return;
|
|
10029
10316
|
}
|
|
10030
10317
|
if (contains$1(name, "mapBoth")) {
|
|
@@ -10275,6 +10562,125 @@ const schemaTypePair = defineRule({
|
|
|
10275
10562
|
type: "problem"
|
|
10276
10563
|
}
|
|
10277
10564
|
});
|
|
10565
|
+
// src/rules/service-schema-file.ts
|
|
10566
|
+
const SERVICE_PATH = /[/\\]src[/\\]services[/\\][^/\\]+[/\\]/u;
|
|
10567
|
+
const SCHEMA_FILE = /[/\\]schema\.ts$/u;
|
|
10568
|
+
const SCHEMA_CLASSES = [
|
|
10569
|
+
"Class",
|
|
10570
|
+
"TaggedClass",
|
|
10571
|
+
"TaggedError",
|
|
10572
|
+
"TaggedRequest"
|
|
10573
|
+
];
|
|
10574
|
+
const DERIVED = matches(/^(?:is|to)[A-Z]/u);
|
|
10575
|
+
const FILTER = matches(/^makeFilter(?:Group)?$/u);
|
|
10576
|
+
function schemaMember(input) {
|
|
10577
|
+
if (input.node.type === "CallExpression" && input.node.callee.type !== "Super") return schemaMember({
|
|
10578
|
+
context: input.context,
|
|
10579
|
+
node: input.node.callee
|
|
10580
|
+
});
|
|
10581
|
+
if (input.node.type === "ChainExpression") return schemaMember({
|
|
10582
|
+
context: input.context,
|
|
10583
|
+
node: input.node.expression
|
|
10584
|
+
});
|
|
10585
|
+
if (input.node.type === "TSInstantiationExpression") return schemaMember({
|
|
10586
|
+
context: input.context,
|
|
10587
|
+
node: input.node.expression
|
|
10588
|
+
});
|
|
10589
|
+
if (input.node.type === "TSSatisfiesExpression") return schemaMember({
|
|
10590
|
+
context: input.context,
|
|
10591
|
+
node: input.node.expression
|
|
10592
|
+
});
|
|
10593
|
+
if (input.node.type === "MemberExpression") {
|
|
10594
|
+
if (input.node.object.type === "Identifier") return some$1(input.node);
|
|
10595
|
+
if (input.node.object.type !== "Super") return schemaMember({
|
|
10596
|
+
context: input.context,
|
|
10597
|
+
node: input.node.object
|
|
10598
|
+
});
|
|
10599
|
+
}
|
|
10600
|
+
return none();
|
|
10601
|
+
}
|
|
10602
|
+
function constructorMember(input) {
|
|
10603
|
+
return importedMember({
|
|
10604
|
+
context: input.context,
|
|
10605
|
+
importedName: "Schema",
|
|
10606
|
+
node: input.node
|
|
10607
|
+
}) && pipe(memberName(input.node), exists((name) => !isSchemaOperationName(name) && !DERIVED(name) && !FILTER(name)));
|
|
10608
|
+
}
|
|
10609
|
+
function definesSchema(input) {
|
|
10610
|
+
if (input.node.type === "CallExpression" && input.node.callee.type === "Identifier" && isImportBinding({
|
|
10611
|
+
context: input.context,
|
|
10612
|
+
importedName: "pipe",
|
|
10613
|
+
node: input.node.callee,
|
|
10614
|
+
source: "effect"
|
|
10615
|
+
})) {
|
|
10616
|
+
const [first] = input.node.arguments;
|
|
10617
|
+
return first !== void 0 && first.type !== "SpreadElement" && definesSchema({
|
|
10618
|
+
...input,
|
|
10619
|
+
node: first
|
|
10620
|
+
});
|
|
10621
|
+
}
|
|
10622
|
+
return pipe(schemaMember(input), exists((member) => constructorMember({
|
|
10623
|
+
context: input.context,
|
|
10624
|
+
node: member
|
|
10625
|
+
})));
|
|
10626
|
+
}
|
|
10627
|
+
function schemaClass(input) {
|
|
10628
|
+
if (input.node.type === "CallExpression" && input.node.callee.type !== "Super") return schemaClass({
|
|
10629
|
+
context: input.context,
|
|
10630
|
+
node: input.node.callee
|
|
10631
|
+
});
|
|
10632
|
+
if (input.node.type === "TSInstantiationExpression") return schemaClass({
|
|
10633
|
+
context: input.context,
|
|
10634
|
+
node: input.node.expression
|
|
10635
|
+
});
|
|
10636
|
+
if (input.node.type === "MemberExpression" && input.node.object.type === "Identifier" && importedMember({
|
|
10637
|
+
context: input.context,
|
|
10638
|
+
importedName: "Schema",
|
|
10639
|
+
node: input.node
|
|
10640
|
+
})) return pipe(memberName(input.node), exists((name) => contains(SCHEMA_CLASSES, name)));
|
|
10641
|
+
return false;
|
|
10642
|
+
}
|
|
10643
|
+
function extendsSchema(input) {
|
|
10644
|
+
return input.node.superClass !== null && schemaClass({
|
|
10645
|
+
context: input.context,
|
|
10646
|
+
node: input.node.superClass
|
|
10647
|
+
});
|
|
10648
|
+
}
|
|
10649
|
+
function report$1(context, node) {
|
|
10650
|
+
context.report({
|
|
10651
|
+
message: "Move this schema into the service's schema.ts and import it.",
|
|
10652
|
+
node
|
|
10653
|
+
});
|
|
10654
|
+
}
|
|
10655
|
+
function exported(statement) {
|
|
10656
|
+
if (statement.type === "ExportDefaultDeclaration") return statement.declaration;
|
|
10657
|
+
return statementDeclaration(statement);
|
|
10658
|
+
}
|
|
10659
|
+
function definitions(context, declaration) {
|
|
10660
|
+
if (declaration?.type === "VariableDeclaration" && declaration.kind === "const") return flatMap(declaration.declarations, (variable) => {
|
|
10661
|
+
if (variable.init === null) return empty$2();
|
|
10662
|
+
if (variable.init.type === "ClassExpression") return filter([variable.init], (node) => extendsSchema({
|
|
10663
|
+
context,
|
|
10664
|
+
node
|
|
10665
|
+
}));
|
|
10666
|
+
return filter([variable.init], (node) => definesSchema({
|
|
10667
|
+
context,
|
|
10668
|
+
node
|
|
10669
|
+
}));
|
|
10670
|
+
});
|
|
10671
|
+
if (declaration?.type === "ClassDeclaration" || declaration?.type === "ClassExpression") return filter([declaration], (node) => extendsSchema({
|
|
10672
|
+
context,
|
|
10673
|
+
node
|
|
10674
|
+
}));
|
|
10675
|
+
return empty$2();
|
|
10676
|
+
}
|
|
10677
|
+
const serviceSchemaFile = defineRule({
|
|
10678
|
+
create: (context) => ({ Program: (program) => {
|
|
10679
|
+
if (!SERVICE_PATH.test(context.filename) || SCHEMA_FILE.test(context.filename) || isTestFile(context)) return;
|
|
10680
|
+
for (const node of flatMap(program.body, (statement) => definitions(context, exported(statement)))) report$1(context, node);
|
|
10681
|
+
} }),
|
|
10682
|
+
meta: { type: "problem" }
|
|
10683
|
+
});
|
|
10278
10684
|
// src/rules/swiftui-theme-values.ts
|
|
10279
10685
|
const PAINTS = [
|
|
10280
10686
|
"background",
|
|
@@ -10409,6 +10815,7 @@ const RULES = {
|
|
|
10409
10815
|
"no-option-value-access": noOptionValueAccess,
|
|
10410
10816
|
"no-pipe-method": noPipeMethod,
|
|
10411
10817
|
"no-polling-test": noPollingTest,
|
|
10818
|
+
"no-primitive-restyle": noPrimitiveRestyle,
|
|
10412
10819
|
"no-property-alias": noPropertyAlias,
|
|
10413
10820
|
"no-redundant-state-type": noRedundantStateType,
|
|
10414
10821
|
"no-redundant-use-ref-null-type": noRedundantUseRefNullType,
|
|
@@ -10435,6 +10842,7 @@ const RULES = {
|
|
|
10435
10842
|
"preserve-error-cause": preserveErrorCause,
|
|
10436
10843
|
"require-unicode-regexp": requireUnicodeRegexp,
|
|
10437
10844
|
"schema-type-pair": schemaTypePair,
|
|
10845
|
+
"service-schema-file": serviceSchemaFile,
|
|
10438
10846
|
"swiftui-theme-values": swiftuiThemeValues
|
|
10439
10847
|
};
|
|
10440
10848
|
const lint = {
|
|
@@ -11315,7 +11723,10 @@ const lint = {
|
|
|
11315
11723
|
"typescript/no-confusing-void-expression": ["error", { ignoreVoidReturningFunctions: true }],
|
|
11316
11724
|
"typescript/no-deprecated": "error",
|
|
11317
11725
|
"typescript/no-duplicate-type-constituents": "error",
|
|
11318
|
-
"typescript/no-floating-promises": "error",
|
|
11726
|
+
"typescript/no-floating-promises": ["error", { allowForKnownSafeCalls: [{
|
|
11727
|
+
from: "file",
|
|
11728
|
+
name: "navigate"
|
|
11729
|
+
}] }],
|
|
11319
11730
|
"typescript/no-for-in-array": "error",
|
|
11320
11731
|
"typescript/no-generated-empty-object-type": "error",
|
|
11321
11732
|
"typescript/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }],
|