oxlint-plugin-arch 0.12.5 → 0.12.6
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/CHANGELOG.md +16 -0
- package/README.md +2 -2
- package/dist/index.js +874 -87
- package/dist/preset/preset.js +79 -6
- package/dist/preset/preset.utils.d.ts +1 -0
- package/dist/rules/effect/effect-layer-file.d.ts +1 -0
- package/dist/rules/effect/effect-layers.d.ts +1 -0
- package/dist/rules/effect/effect-merge-pipe.d.ts +1 -0
- package/dist/rules/effect/effect-schema-first.d.ts +1 -0
- package/dist/rules/effect/effect-values-first.d.ts +1 -0
- package/dist/rules/types/types-duplicate.d.ts +1 -0
- package/dist/types/effect.types.d.ts +46 -0
- package/dist/types/preset.types.d.ts +9 -0
- package/dist/types/schemas.types.d.ts +2 -0
- package/dist/types/types.types.d.ts +4 -0
- package/dist/utils/effect.utils.d.ts +5 -0
- package/dist/vendor/dillon-anti-slop/index.js +3 -0
- package/package.json +11 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
1
4
|
// src/index.ts
|
|
2
5
|
import { eslintCompatPlugin } from "@oxlint/plugins";
|
|
3
6
|
|
|
@@ -3358,9 +3361,684 @@ var copyDashes = defineRule27({
|
|
|
3358
3361
|
}
|
|
3359
3362
|
});
|
|
3360
3363
|
|
|
3361
|
-
// src/rules/
|
|
3364
|
+
// src/rules/effect/effect-layer-file.ts
|
|
3362
3365
|
import { defineRule as defineRule28 } from "@oxlint/plugins";
|
|
3363
3366
|
|
|
3367
|
+
// src/utils/effect.utils.ts
|
|
3368
|
+
var effectBuilders = ["Effect.gen", "Effect.fn", "Effect.fnUntraced"];
|
|
3369
|
+
function effectIsBuilder(node, builders) {
|
|
3370
|
+
const value = node ? astUnwrap(node) : undefined;
|
|
3371
|
+
if (value?.type !== "CallExpression") {
|
|
3372
|
+
return false;
|
|
3373
|
+
}
|
|
3374
|
+
const callee = value.callee.type === "CallExpression" ? value.callee.callee : value.callee;
|
|
3375
|
+
return builders.has(astDottedName(callee) ?? "");
|
|
3376
|
+
}
|
|
3377
|
+
function effectGenerator(node, builders) {
|
|
3378
|
+
const value = node ? astUnwrap(node) : undefined;
|
|
3379
|
+
return effectIsBuilder(value, builders) ? value.arguments.find((argument) => argument.type === "FunctionExpression") : undefined;
|
|
3380
|
+
}
|
|
3381
|
+
function effectMatches(node, patterns) {
|
|
3382
|
+
if (!node || node.type === "Super") {
|
|
3383
|
+
return false;
|
|
3384
|
+
}
|
|
3385
|
+
const value = astUnwrap(node);
|
|
3386
|
+
const target = value.type === "CallExpression" ? value.callee : value;
|
|
3387
|
+
const name = astDottedName(target);
|
|
3388
|
+
if (name !== undefined && optionsPatternsTest(patterns, name)) {
|
|
3389
|
+
return true;
|
|
3390
|
+
}
|
|
3391
|
+
return value.type === "CallExpression" && target.type === "MemberExpression" && astMemberName(target) === "pipe" && effectMatches(target.object, patterns);
|
|
3392
|
+
}
|
|
3393
|
+
|
|
3394
|
+
// src/rules/effect/effect-layer-file.ts
|
|
3395
|
+
var effectLayerFileDefaultLayers = ["^Layer\\.", "^HttpRouter\\.add(?:All)?$", "(?:^|\\.)layer[^.]*$"];
|
|
3396
|
+
var effectLayerFileDefaultServices = ["(?:^|\\.)of$", "^Context\\."];
|
|
3397
|
+
var effectLayerFileDefaultConstructors = [
|
|
3398
|
+
"Layer.effect",
|
|
3399
|
+
"Layer.effectContext",
|
|
3400
|
+
"Layer.effectDiscard",
|
|
3401
|
+
"Layer.scoped",
|
|
3402
|
+
"Layer.scopedContext",
|
|
3403
|
+
"Layer.scopedDiscard",
|
|
3404
|
+
"Layer.sync",
|
|
3405
|
+
"Layer.unwrap"
|
|
3406
|
+
];
|
|
3407
|
+
var effectLayerFile = defineRule28({
|
|
3408
|
+
meta: {
|
|
3409
|
+
type: "problem",
|
|
3410
|
+
schema: [
|
|
3411
|
+
{
|
|
3412
|
+
type: "object",
|
|
3413
|
+
additionalProperties: false,
|
|
3414
|
+
properties: {
|
|
3415
|
+
layer: { type: "string" },
|
|
3416
|
+
make: { type: "string" },
|
|
3417
|
+
prefix: { type: "string" },
|
|
3418
|
+
builders: { type: "array", items: { type: "string" } },
|
|
3419
|
+
layers: optionsPatternSchema,
|
|
3420
|
+
services: optionsPatternSchema,
|
|
3421
|
+
constructors: { type: "array", items: { type: "string" } }
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
],
|
|
3425
|
+
messages: {
|
|
3426
|
+
missing: "A layer file exports `{{layer}}`.",
|
|
3427
|
+
notLayer: "`{{layer}}` is built with Layer: a Layer call, a Layer pipe, or a function returning one.",
|
|
3428
|
+
builderName: "The Effect that builds the service is named `{{make}}`, one per layer file.",
|
|
3429
|
+
moduleMethod: "Only `{{make}}` is an Effect at module level; move this into `{{make}}`, or into a utils file if two files use it.",
|
|
3430
|
+
moduleHelper: "A layer file holds only `{{make}}`, {{prefix}}<Role> layers and `{{layer}}`; move this into `{{make}}`, or into a utils file if two files use it.",
|
|
3431
|
+
localLayer: "A Layer other than `{{layer}}` is named {{prefix}}<Role> and is not exported.",
|
|
3432
|
+
makeReturn: "`{{make}}` returns the service through its tag (Tag.of({ … })), a Context, or a Layer.",
|
|
3433
|
+
inlineBuilder: "Build this layer from `{{make}}`, not an inline Effect: Layer.effect(Tag, {{make}}). One built layer per file."
|
|
3434
|
+
}
|
|
3435
|
+
},
|
|
3436
|
+
createOnce(context) {
|
|
3437
|
+
let layer = "layer";
|
|
3438
|
+
let make = "make";
|
|
3439
|
+
let prefix = "layer";
|
|
3440
|
+
let builders = new Set(effectBuilders);
|
|
3441
|
+
let layers = [];
|
|
3442
|
+
let services = [];
|
|
3443
|
+
let constructors = new Set(effectLayerFileDefaultConstructors);
|
|
3444
|
+
const returned = (node) => {
|
|
3445
|
+
const value = node ? astUnwrap(node) : node;
|
|
3446
|
+
if (!value || !astIsInlineFunction(value)) {
|
|
3447
|
+
return value;
|
|
3448
|
+
}
|
|
3449
|
+
return value.body?.type === "BlockStatement" ? returned(value.body.body.findLast((statement) => statement.type === "ReturnStatement")?.argument) : returned(value.body);
|
|
3450
|
+
};
|
|
3451
|
+
return {
|
|
3452
|
+
before() {
|
|
3453
|
+
const options = optionsFirst(context, {});
|
|
3454
|
+
layer = options.layer ?? "layer";
|
|
3455
|
+
make = options.make ?? "make";
|
|
3456
|
+
prefix = options.prefix ?? "layer";
|
|
3457
|
+
builders = new Set(options.builders ?? effectBuilders);
|
|
3458
|
+
constructors = new Set(options.constructors ?? effectLayerFileDefaultConstructors);
|
|
3459
|
+
layers = optionsPatterns(options.layers ?? effectLayerFileDefaultLayers);
|
|
3460
|
+
services = [...optionsPatterns(options.services ?? effectLayerFileDefaultServices), ...layers];
|
|
3461
|
+
},
|
|
3462
|
+
Program(program) {
|
|
3463
|
+
const data = { layer, make, prefix };
|
|
3464
|
+
const declarators = program.body.flatMap((statement) => {
|
|
3465
|
+
const declaration = astDeclaration(statement);
|
|
3466
|
+
const exported = statement.type === "ExportNamedDeclaration";
|
|
3467
|
+
return declaration?.type === "VariableDeclaration" ? declaration.declarations.map((node) => ({ exported, node, name: node.id.type === "Identifier" ? node.id.name : "" })) : [];
|
|
3468
|
+
});
|
|
3469
|
+
const exportedLayer = declarators.find(({ exported, name }) => exported && name === layer);
|
|
3470
|
+
if (!exportedLayer) {
|
|
3471
|
+
context.report({
|
|
3472
|
+
node: program,
|
|
3473
|
+
messageId: "missing",
|
|
3474
|
+
data
|
|
3475
|
+
});
|
|
3476
|
+
} else if (!effectMatches(returned(exportedLayer.node.init), layers)) {
|
|
3477
|
+
context.report({
|
|
3478
|
+
node: exportedLayer.node,
|
|
3479
|
+
messageId: "notLayer",
|
|
3480
|
+
data
|
|
3481
|
+
});
|
|
3482
|
+
}
|
|
3483
|
+
const wired = new Set;
|
|
3484
|
+
const wiring = declarators.filter((item) => item === exportedLayer || effectMatches(item.node.init, layers));
|
|
3485
|
+
astVisit(wiring.map(({ node }) => node.init), [], (call) => {
|
|
3486
|
+
if (call.type !== "CallExpression" || !optionsPatternsTest(layers, astDottedName(call.callee) ?? "")) {
|
|
3487
|
+
return;
|
|
3488
|
+
}
|
|
3489
|
+
for (const argument of call.arguments) {
|
|
3490
|
+
const target = argument.type === "CallExpression" ? argument.callee : argument;
|
|
3491
|
+
if (target.type === "Identifier") {
|
|
3492
|
+
wired.add(target.name);
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
});
|
|
3496
|
+
const locals = declarators.filter(({ exported }) => !exported);
|
|
3497
|
+
const effects = locals.filter(({ node }) => effectIsBuilder(node.init, builders));
|
|
3498
|
+
const builder = effects.find(({ name }) => name === make) ?? effects.find(({ name }) => wired.has(name));
|
|
3499
|
+
if (builder && builder.name !== make) {
|
|
3500
|
+
context.report({
|
|
3501
|
+
node: builder.node,
|
|
3502
|
+
messageId: "builderName",
|
|
3503
|
+
data
|
|
3504
|
+
});
|
|
3505
|
+
}
|
|
3506
|
+
for (const { node, name, exported } of declarators) {
|
|
3507
|
+
const isLayer = effectMatches(node.init, layers);
|
|
3508
|
+
const isEffect = effectIsBuilder(node.init, builders);
|
|
3509
|
+
if (!exported && isEffect && name !== builder?.name) {
|
|
3510
|
+
context.report({
|
|
3511
|
+
node,
|
|
3512
|
+
messageId: "moduleMethod",
|
|
3513
|
+
data
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3516
|
+
if (!exported && !isEffect && !isLayer && name !== make) {
|
|
3517
|
+
context.report({
|
|
3518
|
+
node,
|
|
3519
|
+
messageId: "moduleHelper",
|
|
3520
|
+
data
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3523
|
+
if (isLayer && name !== layer && (exported || !name.startsWith(prefix) || !/^[A-Z]\w*$/.test(name.slice(prefix.length)))) {
|
|
3524
|
+
context.report({
|
|
3525
|
+
node,
|
|
3526
|
+
messageId: "localLayer",
|
|
3527
|
+
data
|
|
3528
|
+
});
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
for (const statement of program.body) {
|
|
3532
|
+
if (statement.type === "FunctionDeclaration") {
|
|
3533
|
+
context.report({
|
|
3534
|
+
node: statement,
|
|
3535
|
+
messageId: "moduleHelper",
|
|
3536
|
+
data
|
|
3537
|
+
});
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
const generator = builder?.name === make ? effectGenerator(builder.node.init, builders) : undefined;
|
|
3541
|
+
for (const statement of generator?.body?.body ?? []) {
|
|
3542
|
+
if (statement.type === "ReturnStatement" && !effectMatches(statement.argument, services)) {
|
|
3543
|
+
context.report({
|
|
3544
|
+
node: statement,
|
|
3545
|
+
messageId: "makeReturn",
|
|
3546
|
+
data
|
|
3547
|
+
});
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
},
|
|
3551
|
+
CallExpression(node) {
|
|
3552
|
+
if (!constructors.has(astDottedName(node.callee) ?? "")) {
|
|
3553
|
+
return;
|
|
3554
|
+
}
|
|
3555
|
+
for (const argument of node.arguments) {
|
|
3556
|
+
if (argument.type !== "SpreadElement" && (astIsInlineFunction(astUnwrap(argument)) || effectIsBuilder(argument, builders))) {
|
|
3557
|
+
context.report({
|
|
3558
|
+
node: argument,
|
|
3559
|
+
messageId: "inlineBuilder",
|
|
3560
|
+
data: { layer, make, prefix }
|
|
3561
|
+
});
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3565
|
+
};
|
|
3566
|
+
}
|
|
3567
|
+
});
|
|
3568
|
+
|
|
3569
|
+
// src/rules/effect/effect-layers.ts
|
|
3570
|
+
import { defineRule as defineRule29 } from "@oxlint/plugins";
|
|
3571
|
+
var effectLayersDefaultMerge = ["Layer.mergeAll"];
|
|
3572
|
+
var effectLayersDefaultProvide = ["Effect.provide", "Layer.provide", "Layer.provideMerge"];
|
|
3573
|
+
var effectLayersDefaultMin = 2;
|
|
3574
|
+
var effectLayersGroupSchema = {
|
|
3575
|
+
type: "object",
|
|
3576
|
+
additionalProperties: false,
|
|
3577
|
+
properties: {
|
|
3578
|
+
callees: { type: "array", items: { type: "string" } },
|
|
3579
|
+
min: { type: "integer", minimum: 1 }
|
|
3580
|
+
}
|
|
3581
|
+
};
|
|
3582
|
+
var effectLayers = defineRule29({
|
|
3583
|
+
meta: {
|
|
3584
|
+
type: "layout",
|
|
3585
|
+
fixable: "whitespace",
|
|
3586
|
+
schema: [
|
|
3587
|
+
{
|
|
3588
|
+
type: "object",
|
|
3589
|
+
additionalProperties: false,
|
|
3590
|
+
properties: {
|
|
3591
|
+
merge: effectLayersGroupSchema,
|
|
3592
|
+
provide: effectLayersGroupSchema,
|
|
3593
|
+
indent: sourceIndentSchema
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
],
|
|
3597
|
+
messages: {
|
|
3598
|
+
merge: "Put every layer in this merge on its own line.",
|
|
3599
|
+
provide: "Put every layer in this array on its own line."
|
|
3600
|
+
}
|
|
3601
|
+
},
|
|
3602
|
+
createOnce(context) {
|
|
3603
|
+
let merge = new Set(effectLayersDefaultMerge);
|
|
3604
|
+
let provide = new Set(effectLayersDefaultProvide);
|
|
3605
|
+
let mergeMin = effectLayersDefaultMin;
|
|
3606
|
+
let provideMin = effectLayersDefaultMin;
|
|
3607
|
+
let indentUnit = sourceIndentUnit();
|
|
3608
|
+
const check = (node) => {
|
|
3609
|
+
const source = context.sourceCode;
|
|
3610
|
+
const call = node.type === "CallExpression";
|
|
3611
|
+
const items = call ? node.arguments : node.elements;
|
|
3612
|
+
const present = items.filter((item) => item !== null);
|
|
3613
|
+
const open = call ? source.getTokenAfter(node.typeArguments ?? node.callee) : source.getFirstToken(node);
|
|
3614
|
+
const close = source.getLastToken(node);
|
|
3615
|
+
if (open?.value !== (call ? "(" : "[") || close === null || present.length < (call ? mergeMin : provideMin)) {
|
|
3616
|
+
return;
|
|
3617
|
+
}
|
|
3618
|
+
const packed = [open, ...present].some((item, index) => item.loc.end.line === (present.at(index) ?? close).loc.start.line);
|
|
3619
|
+
if (!packed) {
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
const text = source.text;
|
|
3623
|
+
const newline = sourceNewline(text);
|
|
3624
|
+
const base = sourceLineIndent(text, open.range[0]);
|
|
3625
|
+
const gaps = sourceItemGaps(open.range[1], present, close.range[0]);
|
|
3626
|
+
context.report({
|
|
3627
|
+
node,
|
|
3628
|
+
messageId: call ? "merge" : "provide",
|
|
3629
|
+
fix: (fixer) => {
|
|
3630
|
+
if (present.length !== items.length) {
|
|
3631
|
+
return null;
|
|
3632
|
+
}
|
|
3633
|
+
return sourceRespace(fixer, text, gaps, (_, end) => `${newline}${base}${end ? "" : indentUnit}`);
|
|
3634
|
+
}
|
|
3635
|
+
});
|
|
3636
|
+
};
|
|
3637
|
+
return {
|
|
3638
|
+
before() {
|
|
3639
|
+
const options = optionsFirst(context, {});
|
|
3640
|
+
merge = new Set(options.merge?.callees ?? effectLayersDefaultMerge);
|
|
3641
|
+
provide = new Set(options.provide?.callees ?? effectLayersDefaultProvide);
|
|
3642
|
+
mergeMin = options.merge?.min ?? effectLayersDefaultMin;
|
|
3643
|
+
provideMin = options.provide?.min ?? effectLayersDefaultMin;
|
|
3644
|
+
indentUnit = sourceIndentUnit(options.indent);
|
|
3645
|
+
},
|
|
3646
|
+
CallExpression(node) {
|
|
3647
|
+
const name = astDottedName(node.callee);
|
|
3648
|
+
if (name !== undefined && merge.has(name)) {
|
|
3649
|
+
check(node);
|
|
3650
|
+
}
|
|
3651
|
+
if (name !== undefined && provide.has(name)) {
|
|
3652
|
+
for (const argument of node.arguments) {
|
|
3653
|
+
if (argument.type === "ArrayExpression") {
|
|
3654
|
+
check(argument);
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
};
|
|
3660
|
+
}
|
|
3661
|
+
});
|
|
3662
|
+
|
|
3663
|
+
// src/rules/effect/effect-merge-pipe.ts
|
|
3664
|
+
import { defineRule as defineRule30 } from "@oxlint/plugins";
|
|
3665
|
+
var effectMergePipeDefaultMerge = ["Layer.mergeAll"];
|
|
3666
|
+
var effectMergePipeDefaultPipe = ["pipe", "Function.pipe"];
|
|
3667
|
+
var effectMergePipeDefaultMethods = ["pipe"];
|
|
3668
|
+
var effectMergePipe = defineRule30({
|
|
3669
|
+
meta: {
|
|
3670
|
+
type: "layout",
|
|
3671
|
+
schema: [
|
|
3672
|
+
{
|
|
3673
|
+
type: "object",
|
|
3674
|
+
additionalProperties: false,
|
|
3675
|
+
properties: {
|
|
3676
|
+
merge: { type: "array", items: { type: "string" } },
|
|
3677
|
+
pipe: { type: "array", items: { type: "string" } },
|
|
3678
|
+
methods: { type: "array", items: { type: "string" } }
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
],
|
|
3682
|
+
messages: {
|
|
3683
|
+
piped: "A merge that spans lines is never piped. Name it first, then pipe the name."
|
|
3684
|
+
}
|
|
3685
|
+
},
|
|
3686
|
+
createOnce(context) {
|
|
3687
|
+
let merge = new Set(effectMergePipeDefaultMerge);
|
|
3688
|
+
let pipe = new Set(effectMergePipeDefaultPipe);
|
|
3689
|
+
let methods = new Set(effectMergePipeDefaultMethods);
|
|
3690
|
+
const isMultilineMerge = (node) => node?.type === "CallExpression" && merge.has(astDottedName(node.callee) ?? "") && !astIsOneLine(node);
|
|
3691
|
+
return {
|
|
3692
|
+
before() {
|
|
3693
|
+
const options = optionsFirst(context, {});
|
|
3694
|
+
merge = new Set(options.merge ?? effectMergePipeDefaultMerge);
|
|
3695
|
+
pipe = new Set(options.pipe ?? effectMergePipeDefaultPipe);
|
|
3696
|
+
methods = new Set(options.methods ?? effectMergePipeDefaultMethods);
|
|
3697
|
+
},
|
|
3698
|
+
CallExpression(node) {
|
|
3699
|
+
const callee = node.callee;
|
|
3700
|
+
const first = node.arguments.at(0);
|
|
3701
|
+
if (callee.type === "MemberExpression" && methods.has(astMemberName(callee) ?? "") && isMultilineMerge(callee.object)) {
|
|
3702
|
+
context.report({ node: callee.property, messageId: "piped" });
|
|
3703
|
+
}
|
|
3704
|
+
if (pipe.has(astDottedName(callee) ?? "") && first !== undefined && isMultilineMerge(first)) {
|
|
3705
|
+
context.report({ node: first, messageId: "piped" });
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3708
|
+
};
|
|
3709
|
+
}
|
|
3710
|
+
});
|
|
3711
|
+
|
|
3712
|
+
// src/rules/effect/effect-schema-first.ts
|
|
3713
|
+
import { defineRule as defineRule31 } from "@oxlint/plugins";
|
|
3714
|
+
var effectSchemaFirstDefaultRuntime = [
|
|
3715
|
+
"Effect",
|
|
3716
|
+
"Layer",
|
|
3717
|
+
"Stream",
|
|
3718
|
+
"Context",
|
|
3719
|
+
"Scope",
|
|
3720
|
+
"Kysely",
|
|
3721
|
+
"React",
|
|
3722
|
+
"Fiber",
|
|
3723
|
+
"Queue",
|
|
3724
|
+
"PubSub",
|
|
3725
|
+
"Ref",
|
|
3726
|
+
"Deferred",
|
|
3727
|
+
"ManagedRuntime",
|
|
3728
|
+
"Sink",
|
|
3729
|
+
"Channel",
|
|
3730
|
+
"Request",
|
|
3731
|
+
"Response",
|
|
3732
|
+
"Headers",
|
|
3733
|
+
"ReadableStream",
|
|
3734
|
+
"WritableStream",
|
|
3735
|
+
"Blob",
|
|
3736
|
+
"File",
|
|
3737
|
+
"AbortSignal",
|
|
3738
|
+
"WebSocket",
|
|
3739
|
+
"Socket",
|
|
3740
|
+
"Worker",
|
|
3741
|
+
"Uint8Array",
|
|
3742
|
+
"ArrayBuffer",
|
|
3743
|
+
"globalThis"
|
|
3744
|
+
];
|
|
3745
|
+
var effectSchemaFirstSections = {
|
|
3746
|
+
values: ["VariableDeclaration", "ClassDeclaration"],
|
|
3747
|
+
interfaces: ["TSInterfaceDeclaration"],
|
|
3748
|
+
modules: ["TSModuleDeclaration"],
|
|
3749
|
+
aliases: ["TSTypeAliasDeclaration"]
|
|
3750
|
+
};
|
|
3751
|
+
var effectSchemaFirstLabels = {
|
|
3752
|
+
values: "Schemas and values",
|
|
3753
|
+
interfaces: "interfaces",
|
|
3754
|
+
modules: "`declare module`",
|
|
3755
|
+
aliases: "type aliases"
|
|
3756
|
+
};
|
|
3757
|
+
var effectSchemaFirstDefaultOrder = ["values", ["interfaces", "modules"], "aliases"];
|
|
3758
|
+
var effectSchemaFirstSectionSchema = { type: "string", enum: ["values", "interfaces", "modules", "aliases"] };
|
|
3759
|
+
function effectSchemaFirstTypeName(node) {
|
|
3760
|
+
if (node.type === "TSQualifiedName") {
|
|
3761
|
+
const left = effectSchemaFirstTypeName(node.left);
|
|
3762
|
+
return left === undefined ? undefined : `${left}.${node.right.name}`;
|
|
3763
|
+
}
|
|
3764
|
+
return astDottedName(node);
|
|
3765
|
+
}
|
|
3766
|
+
function effectSchemaFirstReference(node) {
|
|
3767
|
+
if (node.type === "TSTypeReference") {
|
|
3768
|
+
return effectSchemaFirstTypeName(node.typeName);
|
|
3769
|
+
}
|
|
3770
|
+
if (node.type === "TSTypeQuery") {
|
|
3771
|
+
return effectSchemaFirstTypeName(node.exprName);
|
|
3772
|
+
}
|
|
3773
|
+
return node.type === "TSInterfaceHeritage" ? astDottedName(node.expression) : undefined;
|
|
3774
|
+
}
|
|
3775
|
+
var effectSchemaFirst = defineRule31({
|
|
3776
|
+
meta: {
|
|
3777
|
+
type: "suggestion",
|
|
3778
|
+
schema: [
|
|
3779
|
+
{
|
|
3780
|
+
type: "object",
|
|
3781
|
+
additionalProperties: false,
|
|
3782
|
+
properties: {
|
|
3783
|
+
member: { type: "string" },
|
|
3784
|
+
keep: optionsPatternSchema,
|
|
3785
|
+
runtime: { type: "array", items: { type: "string" } },
|
|
3786
|
+
rows: {
|
|
3787
|
+
type: "object",
|
|
3788
|
+
additionalProperties: false,
|
|
3789
|
+
properties: { types: { type: "array", items: { type: "string" } }, suffix: { type: "string" } }
|
|
3790
|
+
},
|
|
3791
|
+
order: {
|
|
3792
|
+
type: "array",
|
|
3793
|
+
items: { anyOf: [effectSchemaFirstSectionSchema, { type: "array", items: effectSchemaFirstSectionSchema, minItems: 1 }] }
|
|
3794
|
+
},
|
|
3795
|
+
derived: {
|
|
3796
|
+
type: "object",
|
|
3797
|
+
additionalProperties: false,
|
|
3798
|
+
properties: { first: { type: "boolean" }, sorted: { type: "boolean" } }
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
],
|
|
3803
|
+
messages: {
|
|
3804
|
+
order: "Order a types file as {{order}}.",
|
|
3805
|
+
schemaType: "Add `export type {{name}} = typeof {{name}}.{{member}}` to the final type block.",
|
|
3806
|
+
typeOrder: "Move {{name}}: the type block lists the `typeof` aliases first, in Schema order, then the other aliases.",
|
|
3807
|
+
dataInterface: "Every field of {{name}} fits a Schema: make it a Schema and derive its type.",
|
|
3808
|
+
rowItem: "{{name}} is built from a database row: make it a Schema; only a `…{{suffix}}` alias may read the row type."
|
|
3809
|
+
}
|
|
3810
|
+
},
|
|
3811
|
+
createOnce(context) {
|
|
3812
|
+
let member = "Type";
|
|
3813
|
+
let keep = [];
|
|
3814
|
+
let runtime = new Set(effectSchemaFirstDefaultRuntime);
|
|
3815
|
+
let rows;
|
|
3816
|
+
let suffix = "Record";
|
|
3817
|
+
let ranks = new Map;
|
|
3818
|
+
let orderText = "";
|
|
3819
|
+
let derivedFirst = true;
|
|
3820
|
+
let derivedSorted = true;
|
|
3821
|
+
const derives = (alias) => {
|
|
3822
|
+
const annotation = alias.typeAnnotation;
|
|
3823
|
+
const name = annotation.type === "TSTypeQuery" ? annotation.exprName : undefined;
|
|
3824
|
+
return name?.type === "TSQualifiedName" && name.left.type === "Identifier" && name.left.name === alias.id.name && name.right.name === member;
|
|
3825
|
+
};
|
|
3826
|
+
const refers = (node, names) => astSome(node, (child) => {
|
|
3827
|
+
if (child.type === "TSFunctionType" || child.type === "TSConstructorType" || child.type === "TSMethodSignature") {
|
|
3828
|
+
return true;
|
|
3829
|
+
}
|
|
3830
|
+
return (effectSchemaFirstReference(child)?.split(".") ?? []).some((name) => names.has(name));
|
|
3831
|
+
});
|
|
3832
|
+
const readsRow = (node) => astSome(node, (child) => Boolean(rows?.has(effectSchemaFirstReference(child) ?? "")));
|
|
3833
|
+
const checkOrder = (program) => {
|
|
3834
|
+
let highest = 0;
|
|
3835
|
+
for (const statement of program.body) {
|
|
3836
|
+
const rank = ranks.get(astDeclaration(statement)?.type ?? "") ?? 0;
|
|
3837
|
+
if (rank > 0 && rank < highest) {
|
|
3838
|
+
context.report({
|
|
3839
|
+
node: statement,
|
|
3840
|
+
messageId: "order",
|
|
3841
|
+
data: { order: orderText }
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
highest = Math.max(highest, rank);
|
|
3845
|
+
}
|
|
3846
|
+
};
|
|
3847
|
+
const keptNames = (program, aliases, interfaces) => {
|
|
3848
|
+
const kept = new Set(aliases.filter((alias) => refers(alias.typeAnnotation, runtime)).map((alias) => alias.id.name));
|
|
3849
|
+
for (const statement of program.body) {
|
|
3850
|
+
if (statement.type === "ImportDeclaration" && statement.source.value.startsWith(".")) {
|
|
3851
|
+
for (const specifier of statement.specifiers) {
|
|
3852
|
+
if (statement.importKind === "type" || specifier.type === "ImportSpecifier" && specifier.importKind === "type") {
|
|
3853
|
+
kept.add(specifier.local.name);
|
|
3854
|
+
}
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
const names = new Set([...runtime, ...kept]);
|
|
3859
|
+
let grew = true;
|
|
3860
|
+
while (grew) {
|
|
3861
|
+
grew = false;
|
|
3862
|
+
for (const node of interfaces) {
|
|
3863
|
+
const stays = node.body.body.length === 0 || Boolean(node.typeParameters) || optionsPatternsTest(keep, node.id.name) || refers(node, names);
|
|
3864
|
+
if (!kept.has(node.id.name) && stays) {
|
|
3865
|
+
names.add(node.id.name);
|
|
3866
|
+
kept.add(node.id.name);
|
|
3867
|
+
grew = true;
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
}
|
|
3871
|
+
return kept;
|
|
3872
|
+
};
|
|
3873
|
+
return {
|
|
3874
|
+
before() {
|
|
3875
|
+
const options = optionsFirst(context, {});
|
|
3876
|
+
member = options.member ?? "Type";
|
|
3877
|
+
keep = optionsPatterns(options.keep);
|
|
3878
|
+
runtime = new Set(options.runtime ?? effectSchemaFirstDefaultRuntime);
|
|
3879
|
+
rows = options.rows ? new Set(options.rows.types ?? ["Kysely.Selectable"]) : undefined;
|
|
3880
|
+
suffix = options.rows?.suffix ?? "Record";
|
|
3881
|
+
const order = (options.order ?? effectSchemaFirstDefaultOrder).map((group) => [group].flat());
|
|
3882
|
+
ranks = new Map(order.flatMap((group, index) => group.flatMap((section) => effectSchemaFirstSections[section].map((type) => [type, index + 1]))));
|
|
3883
|
+
orderText = order.map((group) => group.map((section) => effectSchemaFirstLabels[section]).join(" and ")).join(", then ");
|
|
3884
|
+
derivedFirst = options.derived?.first ?? true;
|
|
3885
|
+
derivedSorted = options.derived?.sorted ?? true;
|
|
3886
|
+
},
|
|
3887
|
+
Program(program) {
|
|
3888
|
+
checkOrder(program);
|
|
3889
|
+
const declarations = program.body.flatMap((statement) => astDeclaration(statement) ?? []);
|
|
3890
|
+
const aliases = declarations.filter((node) => node.type === "TSTypeAliasDeclaration");
|
|
3891
|
+
const interfaces = declarations.filter((node) => node.type === "TSInterfaceDeclaration");
|
|
3892
|
+
const schemas = declarations.flatMap((node) => node.type === "VariableDeclaration" ? node.declarations : []).map(({ id }) => id.type === "Identifier" ? id.name : "");
|
|
3893
|
+
const exported = program.body.flatMap((statement) => statement.type === "ExportNamedDeclaration" && statement.declaration ? [statement.declaration] : []);
|
|
3894
|
+
const typed = new Set(exported.flatMap((node) => node.type === "TSTypeAliasDeclaration" && derives(node) ? [node.id.name] : []));
|
|
3895
|
+
for (const node of exported.flatMap((declaration) => declaration.type === "VariableDeclaration" ? declaration.declarations : [])) {
|
|
3896
|
+
const isSchema = node.init?.type === "CallExpression" || node.init?.type === "MemberExpression";
|
|
3897
|
+
if (isSchema && node.id.type === "Identifier" && !typed.has(node.id.name)) {
|
|
3898
|
+
context.report({
|
|
3899
|
+
node,
|
|
3900
|
+
messageId: "schemaType",
|
|
3901
|
+
data: { name: node.id.name, member }
|
|
3902
|
+
});
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
let order = -1;
|
|
3906
|
+
let other = false;
|
|
3907
|
+
for (const alias of aliases) {
|
|
3908
|
+
if (!derives(alias)) {
|
|
3909
|
+
other = true;
|
|
3910
|
+
continue;
|
|
3911
|
+
}
|
|
3912
|
+
const index = schemas.indexOf(alias.id.name);
|
|
3913
|
+
if (derivedFirst && other || derivedSorted && index < order) {
|
|
3914
|
+
context.report({
|
|
3915
|
+
node: alias,
|
|
3916
|
+
messageId: "typeOrder",
|
|
3917
|
+
data: { name: alias.id.name }
|
|
3918
|
+
});
|
|
3919
|
+
}
|
|
3920
|
+
order = Math.max(order, index);
|
|
3921
|
+
}
|
|
3922
|
+
const kept = keptNames(program, aliases, interfaces);
|
|
3923
|
+
for (const node of interfaces) {
|
|
3924
|
+
if (!kept.has(node.id.name)) {
|
|
3925
|
+
context.report({
|
|
3926
|
+
node,
|
|
3927
|
+
messageId: "dataInterface",
|
|
3928
|
+
data: { name: node.id.name }
|
|
3929
|
+
});
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
for (const node of rows ? declarations : []) {
|
|
3933
|
+
const fromRow = node.type === "TSTypeAliasDeclaration" && !node.id.name.endsWith(suffix) && readsRow(node.typeAnnotation) || node.type === "TSInterfaceDeclaration" && node.extends.some(readsRow);
|
|
3934
|
+
if (fromRow) {
|
|
3935
|
+
context.report({
|
|
3936
|
+
node,
|
|
3937
|
+
messageId: "rowItem",
|
|
3938
|
+
data: { name: node.id.name, suffix }
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
};
|
|
3944
|
+
}
|
|
3945
|
+
});
|
|
3946
|
+
|
|
3947
|
+
// src/rules/effect/effect-values-first.ts
|
|
3948
|
+
import { defineRule as defineRule32 } from "@oxlint/plugins";
|
|
3949
|
+
var effectValuesFirstDefaultPinned = [
|
|
3950
|
+
"^Layer\\.",
|
|
3951
|
+
"^Context\\.",
|
|
3952
|
+
"^HttpRouter\\.add(?:All)?$",
|
|
3953
|
+
"(?:^|\\.)of$",
|
|
3954
|
+
"(?:^|\\.)layer[^.]*$",
|
|
3955
|
+
"^Schema\\.(?:asserts|decode\\w*|encode\\w*|is|isSchema|isSchemaError|resolveAnnotations)$"
|
|
3956
|
+
];
|
|
3957
|
+
var effectValuesFirst = defineRule32({
|
|
3958
|
+
meta: {
|
|
3959
|
+
type: "suggestion",
|
|
3960
|
+
schema: [
|
|
3961
|
+
{
|
|
3962
|
+
type: "object",
|
|
3963
|
+
additionalProperties: false,
|
|
3964
|
+
properties: {
|
|
3965
|
+
builders: { type: "array", items: { type: "string" } },
|
|
3966
|
+
pinned: optionsPatternSchema
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
],
|
|
3970
|
+
messages: {
|
|
3971
|
+
value: "`{{name}}` is a value declared after `{{after}}`: declare values first, then helpers and methods."
|
|
3972
|
+
}
|
|
3973
|
+
},
|
|
3974
|
+
createOnce(context) {
|
|
3975
|
+
let builders = new Set(effectBuilders);
|
|
3976
|
+
let pinned = [];
|
|
3977
|
+
const check = (statements) => {
|
|
3978
|
+
const tied = new Set;
|
|
3979
|
+
let first;
|
|
3980
|
+
let barrier = false;
|
|
3981
|
+
for (const statement of statements) {
|
|
3982
|
+
const declaration = astDeclaration(statement);
|
|
3983
|
+
if (declaration?.type === "FunctionDeclaration" && declaration.id) {
|
|
3984
|
+
tied.add(declaration.id.name);
|
|
3985
|
+
first ??= declaration.id.name;
|
|
3986
|
+
continue;
|
|
3987
|
+
}
|
|
3988
|
+
if (declaration?.type !== "VariableDeclaration") {
|
|
3989
|
+
barrier ||= statement.type === "ExpressionStatement" && first !== undefined;
|
|
3990
|
+
continue;
|
|
3991
|
+
}
|
|
3992
|
+
for (const declarator of declaration.declarations) {
|
|
3993
|
+
const init = declarator.init;
|
|
3994
|
+
const names = astBindings(declarator.id).map((binding) => binding.name);
|
|
3995
|
+
const helper = Boolean(init && (astIsInlineFunction(astUnwrap(init)) || effectIsBuilder(init, builders)));
|
|
3996
|
+
const kept = helper || effectMatches(init, pinned) || astSome(init, (node) => node.type === "Identifier" && tied.has(node.name));
|
|
3997
|
+
if (first !== undefined && !kept && !barrier) {
|
|
3998
|
+
context.report({
|
|
3999
|
+
node: declarator,
|
|
4000
|
+
messageId: "value",
|
|
4001
|
+
data: { name: names.join(", "), after: first }
|
|
4002
|
+
});
|
|
4003
|
+
}
|
|
4004
|
+
if (kept) {
|
|
4005
|
+
names.forEach((name) => tied.add(name));
|
|
4006
|
+
}
|
|
4007
|
+
barrier ||= kept && first !== undefined && astSome(init, (node) => node.type === "YieldExpression");
|
|
4008
|
+
first ??= helper ? names.join(", ") : undefined;
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
};
|
|
4012
|
+
const body = (init) => {
|
|
4013
|
+
const value = init ? astUnwrap(init) : null;
|
|
4014
|
+
const target = value && astIsInlineFunction(value) ? value : effectGenerator(value, builders);
|
|
4015
|
+
return target?.body?.type === "BlockStatement" ? target.body.body : [];
|
|
4016
|
+
};
|
|
4017
|
+
return {
|
|
4018
|
+
before() {
|
|
4019
|
+
const options = optionsFirst(context, {});
|
|
4020
|
+
builders = new Set(options.builders ?? effectBuilders);
|
|
4021
|
+
pinned = optionsPatterns(options.pinned ?? effectValuesFirstDefaultPinned);
|
|
4022
|
+
},
|
|
4023
|
+
Program(program) {
|
|
4024
|
+
check(program.body);
|
|
4025
|
+
for (const statement of program.body) {
|
|
4026
|
+
const declaration = astDeclaration(statement);
|
|
4027
|
+
if (declaration?.type === "FunctionDeclaration") {
|
|
4028
|
+
check(declaration.body?.body ?? []);
|
|
4029
|
+
}
|
|
4030
|
+
if (declaration?.type === "VariableDeclaration") {
|
|
4031
|
+
declaration.declarations.forEach((declarator) => check(body(declarator.init)));
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
};
|
|
4036
|
+
}
|
|
4037
|
+
});
|
|
4038
|
+
|
|
4039
|
+
// src/rules/files/files-components-only.ts
|
|
4040
|
+
import { defineRule as defineRule33 } from "@oxlint/plugins";
|
|
4041
|
+
|
|
3364
4042
|
// src/utils/react.utils.ts
|
|
3365
4043
|
function reactReturnsOutput(program, node) {
|
|
3366
4044
|
const expressions = astReturnExpressions(node);
|
|
@@ -3431,7 +4109,7 @@ function reactIsComponent(program, candidate) {
|
|
|
3431
4109
|
function componentName(basename2) {
|
|
3432
4110
|
return basename2.replace(/\.(tsx?|jsx?)$/, "").replaceAll(/(?:^[-.]*|[-.]+)(.?)/g, (_, char) => char.toUpperCase());
|
|
3433
4111
|
}
|
|
3434
|
-
var filesComponentsOnly =
|
|
4112
|
+
var filesComponentsOnly = defineRule33({
|
|
3435
4113
|
meta: {
|
|
3436
4114
|
type: "problem",
|
|
3437
4115
|
schema: [
|
|
@@ -3519,7 +4197,7 @@ var filesComponentsOnly = defineRule28({
|
|
|
3519
4197
|
});
|
|
3520
4198
|
|
|
3521
4199
|
// src/rules/files/files-constants-only.ts
|
|
3522
|
-
import { defineRule as
|
|
4200
|
+
import { defineRule as defineRule34 } from "@oxlint/plugins";
|
|
3523
4201
|
function unwrap(expression) {
|
|
3524
4202
|
if (expression.type === "ParenthesizedExpression" || expression.type === "TSAsExpression" || expression.type === "TSSatisfiesExpression" || expression.type === "TSTypeAssertion" || expression.type === "TSNonNullExpression" || expression.type === "TSInstantiationExpression") {
|
|
3525
4203
|
return unwrap(expression.expression);
|
|
@@ -3574,7 +4252,7 @@ function collectBindings(program) {
|
|
|
3574
4252
|
}
|
|
3575
4253
|
return bindings;
|
|
3576
4254
|
}
|
|
3577
|
-
var filesConstantsOnly =
|
|
4255
|
+
var filesConstantsOnly = defineRule34({
|
|
3578
4256
|
meta: {
|
|
3579
4257
|
type: "problem",
|
|
3580
4258
|
schema: [
|
|
@@ -3673,7 +4351,7 @@ var filesConstantsOnly = defineRule29({
|
|
|
3673
4351
|
});
|
|
3674
4352
|
|
|
3675
4353
|
// src/rules/files/files-domain-constants.ts
|
|
3676
|
-
import { defineRule as
|
|
4354
|
+
import { defineRule as defineRule35 } from "@oxlint/plugins";
|
|
3677
4355
|
import { basename as basename2, dirname as dirname2 } from "node:path";
|
|
3678
4356
|
function isData(expression) {
|
|
3679
4357
|
const value = astUnwrap(expression);
|
|
@@ -3691,7 +4369,7 @@ function isData(expression) {
|
|
|
3691
4369
|
}
|
|
3692
4370
|
return value.type === "NewExpression" && value.callee.type === "Identifier" && ["Map", "Set"].includes(value.callee.name) && value.arguments[0]?.type === "ArrayExpression" && value.arguments[0].elements.length > 0;
|
|
3693
4371
|
}
|
|
3694
|
-
var filesDomainConstants =
|
|
4372
|
+
var filesDomainConstants = defineRule35({
|
|
3695
4373
|
meta: {
|
|
3696
4374
|
type: "problem",
|
|
3697
4375
|
schema: [
|
|
@@ -3756,11 +4434,11 @@ var filesDomainConstants = defineRule30({
|
|
|
3756
4434
|
});
|
|
3757
4435
|
|
|
3758
4436
|
// src/rules/files/files-exports.ts
|
|
3759
|
-
import { defineRule as
|
|
4437
|
+
import { defineRule as defineRule36 } from "@oxlint/plugins";
|
|
3760
4438
|
function escapeRegExp(value) {
|
|
3761
4439
|
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3762
4440
|
}
|
|
3763
|
-
var filesExports =
|
|
4441
|
+
var filesExports = defineRule36({
|
|
3764
4442
|
meta: {
|
|
3765
4443
|
type: "problem",
|
|
3766
4444
|
schema: [
|
|
@@ -3841,12 +4519,12 @@ var filesExports = defineRule31({
|
|
|
3841
4519
|
});
|
|
3842
4520
|
|
|
3843
4521
|
// src/rules/files/files-externals.ts
|
|
3844
|
-
import { defineRule as
|
|
4522
|
+
import { defineRule as defineRule37 } from "@oxlint/plugins";
|
|
3845
4523
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
3846
4524
|
import { builtinModules as builtinModules2 } from "node:module";
|
|
3847
4525
|
import { dirname as dirname3, join as join2 } from "node:path";
|
|
3848
4526
|
var filesExternalsConfigs = "^(?:vite|next)\\.config\\.[cm]?[jt]s$";
|
|
3849
|
-
var filesExternals =
|
|
4527
|
+
var filesExternals = defineRule37({
|
|
3850
4528
|
meta: {
|
|
3851
4529
|
type: "problem",
|
|
3852
4530
|
schema: [
|
|
@@ -3939,7 +4617,7 @@ var filesExternals = defineRule32({
|
|
|
3939
4617
|
});
|
|
3940
4618
|
|
|
3941
4619
|
// src/rules/files/files-factory-keys.ts
|
|
3942
|
-
import { defineRule as
|
|
4620
|
+
import { defineRule as defineRule38 } from "@oxlint/plugins";
|
|
3943
4621
|
function returnedObject(expression) {
|
|
3944
4622
|
if (expression?.type === "TSAsExpression" || expression?.type === "TSSatisfiesExpression" || expression?.type === "TSTypeAssertion" || expression?.type === "TSNonNullExpression") {
|
|
3945
4623
|
return returnedObject(expression.expression);
|
|
@@ -3950,7 +4628,7 @@ function compileKeys(pattern, keys, requireKeys) {
|
|
|
3950
4628
|
const allowedList = keys.concat(requireKeys.filter((key) => !keys.includes(key)));
|
|
3951
4629
|
return { patterns: optionsPatternsWithEmpty(pattern), allowed: new Set(allowedList), allowedList, required: requireKeys };
|
|
3952
4630
|
}
|
|
3953
|
-
var filesFactoryKeys =
|
|
4631
|
+
var filesFactoryKeys = defineRule38({
|
|
3954
4632
|
meta: {
|
|
3955
4633
|
type: "problem",
|
|
3956
4634
|
schema: [
|
|
@@ -4068,8 +4746,8 @@ var filesFactoryKeys = defineRule33({
|
|
|
4068
4746
|
});
|
|
4069
4747
|
|
|
4070
4748
|
// src/rules/files/files-helpers.ts
|
|
4071
|
-
import { defineRule as
|
|
4072
|
-
var filesHelpers =
|
|
4749
|
+
import { defineRule as defineRule39 } from "@oxlint/plugins";
|
|
4750
|
+
var filesHelpers = defineRule39({
|
|
4073
4751
|
meta: {
|
|
4074
4752
|
type: "problem",
|
|
4075
4753
|
schema: [
|
|
@@ -4117,8 +4795,8 @@ var filesHelpers = defineRule34({
|
|
|
4117
4795
|
});
|
|
4118
4796
|
|
|
4119
4797
|
// src/rules/files/files-no-functions.ts
|
|
4120
|
-
import { defineRule as
|
|
4121
|
-
var filesNoFunctions =
|
|
4798
|
+
import { defineRule as defineRule40 } from "@oxlint/plugins";
|
|
4799
|
+
var filesNoFunctions = defineRule40({
|
|
4122
4800
|
meta: {
|
|
4123
4801
|
type: "problem",
|
|
4124
4802
|
schema: [
|
|
@@ -4172,8 +4850,8 @@ var filesNoFunctions = defineRule35({
|
|
|
4172
4850
|
});
|
|
4173
4851
|
|
|
4174
4852
|
// src/rules/files/files-restricted.ts
|
|
4175
|
-
import { defineRule as
|
|
4176
|
-
var filesRestricted =
|
|
4853
|
+
import { defineRule as defineRule41 } from "@oxlint/plugins";
|
|
4854
|
+
var filesRestricted = defineRule41({
|
|
4177
4855
|
meta: {
|
|
4178
4856
|
type: "problem",
|
|
4179
4857
|
schema: [
|
|
@@ -4205,7 +4883,7 @@ var filesRestricted = defineRule36({
|
|
|
4205
4883
|
});
|
|
4206
4884
|
|
|
4207
4885
|
// src/rules/files/files-route.ts
|
|
4208
|
-
import { defineRule as
|
|
4886
|
+
import { defineRule as defineRule42 } from "@oxlint/plugins";
|
|
4209
4887
|
function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
4210
4888
|
astVisit(item.node.body, [item.node], (node) => {
|
|
4211
4889
|
if (banIntrinsicJsx && node.type === "JSXOpeningElement" && node.name.type === "JSXIdentifier" && /^[a-z]/.test(node.name.name)) {
|
|
@@ -4225,7 +4903,7 @@ function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
|
4225
4903
|
}
|
|
4226
4904
|
});
|
|
4227
4905
|
}
|
|
4228
|
-
var filesRoute =
|
|
4906
|
+
var filesRoute = defineRule42({
|
|
4229
4907
|
meta: {
|
|
4230
4908
|
type: "problem",
|
|
4231
4909
|
schema: [
|
|
@@ -4295,7 +4973,7 @@ var filesRoute = defineRule37({
|
|
|
4295
4973
|
});
|
|
4296
4974
|
|
|
4297
4975
|
// src/rules/files/files-types-only.ts
|
|
4298
|
-
import { defineRule as
|
|
4976
|
+
import { defineRule as defineRule43 } from "@oxlint/plugins";
|
|
4299
4977
|
function runtimeImportLocalNames(statement) {
|
|
4300
4978
|
return statement.specifiers.flatMap((specifier) => specifier.type !== "ImportSpecifier" || specifier.importKind !== "type" ? [specifier.local.name] : []);
|
|
4301
4979
|
}
|
|
@@ -4464,7 +5142,7 @@ function runtimeKind(node) {
|
|
|
4464
5142
|
}
|
|
4465
5143
|
return node.type === "FunctionDeclaration" ? "function" : "variable";
|
|
4466
5144
|
}
|
|
4467
|
-
var filesTypesOnly =
|
|
5145
|
+
var filesTypesOnly = defineRule43({
|
|
4468
5146
|
meta: {
|
|
4469
5147
|
type: "problem",
|
|
4470
5148
|
schema: [
|
|
@@ -4572,8 +5250,8 @@ var filesTypesOnly = defineRule38({
|
|
|
4572
5250
|
});
|
|
4573
5251
|
|
|
4574
5252
|
// src/rules/layout/layout-arrow-body.ts
|
|
4575
|
-
import { defineRule as
|
|
4576
|
-
var layoutArrowBody =
|
|
5253
|
+
import { defineRule as defineRule44 } from "@oxlint/plugins";
|
|
5254
|
+
var layoutArrowBody = defineRule44({
|
|
4577
5255
|
meta: {
|
|
4578
5256
|
type: "layout",
|
|
4579
5257
|
fixable: "whitespace",
|
|
@@ -4625,12 +5303,12 @@ var layoutArrowBody = defineRule39({
|
|
|
4625
5303
|
});
|
|
4626
5304
|
|
|
4627
5305
|
// src/rules/layout/layout-call-arguments.ts
|
|
4628
|
-
import { defineRule as
|
|
5306
|
+
import { defineRule as defineRule45 } from "@oxlint/plugins";
|
|
4629
5307
|
function layoutCallArgumentsHuggable(node) {
|
|
4630
5308
|
return astIsInlineFunction(node) || node.type === "ObjectExpression" || node.type === "ArrayExpression" || astIsCall(node) && node.arguments.length === 1 && (node.callee.type !== "MemberExpression" || astIsOneLine(node.callee)) && node.arguments.every(layoutCallArgumentsHuggable);
|
|
4631
5309
|
}
|
|
4632
5310
|
var layoutCallArgumentsMax = { type: "integer", minimum: 1 };
|
|
4633
|
-
var layoutCallArguments =
|
|
5311
|
+
var layoutCallArguments = defineRule45({
|
|
4634
5312
|
meta: {
|
|
4635
5313
|
type: "layout",
|
|
4636
5314
|
fixable: "whitespace",
|
|
@@ -4812,12 +5490,12 @@ var layoutCallArguments = defineRule40({
|
|
|
4812
5490
|
});
|
|
4813
5491
|
|
|
4814
5492
|
// src/rules/layout/layout-call-array.ts
|
|
4815
|
-
import { defineRule as
|
|
5493
|
+
import { defineRule as defineRule46 } from "@oxlint/plugins";
|
|
4816
5494
|
var layoutCallArrayDefaultCallees = ["Promise.all", "Promise.allSettled"];
|
|
4817
5495
|
function layoutCallArrayRoot(node) {
|
|
4818
5496
|
return node.type === "MemberExpression" ? layoutCallArrayRoot(node.object) : node;
|
|
4819
5497
|
}
|
|
4820
|
-
var layoutCallArray =
|
|
5498
|
+
var layoutCallArray = defineRule46({
|
|
4821
5499
|
meta: {
|
|
4822
5500
|
type: "layout",
|
|
4823
5501
|
fixable: "whitespace",
|
|
@@ -4933,7 +5611,7 @@ var layoutCallArray = defineRule41({
|
|
|
4933
5611
|
});
|
|
4934
5612
|
|
|
4935
5613
|
// src/rules/layout/layout-call-depth.ts
|
|
4936
|
-
import { defineRule as
|
|
5614
|
+
import { defineRule as defineRule47 } from "@oxlint/plugins";
|
|
4937
5615
|
function layoutCallDepthOuter(node) {
|
|
4938
5616
|
const parent = node.parent;
|
|
4939
5617
|
if (!parent || parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type.endsWith("Statement")) {
|
|
@@ -4941,7 +5619,7 @@ function layoutCallDepthOuter(node) {
|
|
|
4941
5619
|
}
|
|
4942
5620
|
return astIsCall(parent) && parent.arguments.some((argument) => argument === node) ? parent : layoutCallDepthOuter(parent);
|
|
4943
5621
|
}
|
|
4944
|
-
var layoutCallDepth =
|
|
5622
|
+
var layoutCallDepth = defineRule47({
|
|
4945
5623
|
meta: {
|
|
4946
5624
|
type: "layout",
|
|
4947
5625
|
schema: [
|
|
@@ -4980,8 +5658,8 @@ var layoutCallDepth = defineRule42({
|
|
|
4980
5658
|
});
|
|
4981
5659
|
|
|
4982
5660
|
// src/rules/layout/layout-chain.ts
|
|
4983
|
-
import { defineRule as
|
|
4984
|
-
var layoutChain =
|
|
5661
|
+
import { defineRule as defineRule48 } from "@oxlint/plugins";
|
|
5662
|
+
var layoutChain = defineRule48({
|
|
4985
5663
|
meta: {
|
|
4986
5664
|
type: "layout",
|
|
4987
5665
|
fixable: "whitespace",
|
|
@@ -5100,8 +5778,8 @@ var layoutChain = defineRule43({
|
|
|
5100
5778
|
});
|
|
5101
5779
|
|
|
5102
5780
|
// src/rules/layout/layout-items.ts
|
|
5103
|
-
import { defineRule as
|
|
5104
|
-
var layoutItems =
|
|
5781
|
+
import { defineRule as defineRule49 } from "@oxlint/plugins";
|
|
5782
|
+
var layoutItems = defineRule49({
|
|
5105
5783
|
meta: {
|
|
5106
5784
|
type: "layout",
|
|
5107
5785
|
fixable: "whitespace",
|
|
@@ -5156,8 +5834,8 @@ var layoutItems = defineRule44({
|
|
|
5156
5834
|
});
|
|
5157
5835
|
|
|
5158
5836
|
// src/rules/layout/layout-jsx-attributes.ts
|
|
5159
|
-
import { defineRule as
|
|
5160
|
-
var layoutJsxAttributes =
|
|
5837
|
+
import { defineRule as defineRule50 } from "@oxlint/plugins";
|
|
5838
|
+
var layoutJsxAttributes = defineRule50({
|
|
5161
5839
|
meta: {
|
|
5162
5840
|
type: "layout",
|
|
5163
5841
|
fixable: "whitespace",
|
|
@@ -5245,8 +5923,8 @@ var layoutJsxAttributes = defineRule45({
|
|
|
5245
5923
|
});
|
|
5246
5924
|
|
|
5247
5925
|
// src/rules/layout/layout-key-value.ts
|
|
5248
|
-
import { defineRule as
|
|
5249
|
-
var layoutKeyValue =
|
|
5926
|
+
import { defineRule as defineRule51 } from "@oxlint/plugins";
|
|
5927
|
+
var layoutKeyValue = defineRule51({
|
|
5250
5928
|
meta: {
|
|
5251
5929
|
type: "layout",
|
|
5252
5930
|
fixable: "whitespace",
|
|
@@ -5282,7 +5960,7 @@ var layoutKeyValue = defineRule46({
|
|
|
5282
5960
|
});
|
|
5283
5961
|
|
|
5284
5962
|
// src/rules/layout/layout-object.ts
|
|
5285
|
-
import { defineRule as
|
|
5963
|
+
import { defineRule as defineRule52 } from "@oxlint/plugins";
|
|
5286
5964
|
function layoutObjectIsWhitespace(text) {
|
|
5287
5965
|
return /^[\t\n\r\f ]*$/.test(text);
|
|
5288
5966
|
}
|
|
@@ -5290,7 +5968,7 @@ function layoutObjectIsFlat(property) {
|
|
|
5290
5968
|
const value = property.type === "SpreadElement" ? property.argument : property.value;
|
|
5291
5969
|
return astIsOneLine(property) && (property.type === "SpreadElement" || !property.method && property.kind === "init") && value.type !== "ObjectExpression" && value.type !== "ArrayExpression" && !astIsInlineFunction(value);
|
|
5292
5970
|
}
|
|
5293
|
-
var layoutObject =
|
|
5971
|
+
var layoutObject = defineRule52({
|
|
5294
5972
|
meta: {
|
|
5295
5973
|
type: "layout",
|
|
5296
5974
|
fixable: "whitespace",
|
|
@@ -5407,7 +6085,7 @@ var layoutObject = defineRule47({
|
|
|
5407
6085
|
});
|
|
5408
6086
|
|
|
5409
6087
|
// src/rules/layout/layout-padding.ts
|
|
5410
|
-
import { defineRule as
|
|
6088
|
+
import { defineRule as defineRule53 } from "@oxlint/plugins";
|
|
5411
6089
|
var layoutPaddingControl = new Set([
|
|
5412
6090
|
"IfStatement",
|
|
5413
6091
|
"ForStatement",
|
|
@@ -5436,7 +6114,7 @@ function layoutPaddingKind(node) {
|
|
|
5436
6114
|
function layoutPaddingIsMultilineVariable(node, kind) {
|
|
5437
6115
|
return kind === "variable" && node.loc.start.line !== node.loc.end.line;
|
|
5438
6116
|
}
|
|
5439
|
-
var layoutPadding =
|
|
6117
|
+
var layoutPadding = defineRule53({
|
|
5440
6118
|
meta: {
|
|
5441
6119
|
type: "layout",
|
|
5442
6120
|
fixable: "whitespace",
|
|
@@ -5525,8 +6203,8 @@ var layoutPadding = defineRule48({
|
|
|
5525
6203
|
});
|
|
5526
6204
|
|
|
5527
6205
|
// src/rules/layout/layout-pipe.ts
|
|
5528
|
-
import { defineRule as
|
|
5529
|
-
var layoutPipe =
|
|
6206
|
+
import { defineRule as defineRule54 } from "@oxlint/plugins";
|
|
6207
|
+
var layoutPipe = defineRule54({
|
|
5530
6208
|
meta: {
|
|
5531
6209
|
type: "layout",
|
|
5532
6210
|
messages: {
|
|
@@ -5557,7 +6235,7 @@ var layoutPipe = defineRule49({
|
|
|
5557
6235
|
});
|
|
5558
6236
|
|
|
5559
6237
|
// src/rules/layout/layout-ternary.ts
|
|
5560
|
-
import { defineRule as
|
|
6238
|
+
import { defineRule as defineRule55 } from "@oxlint/plugins";
|
|
5561
6239
|
function layoutTernaryLines(node) {
|
|
5562
6240
|
return node.loc.end.line - node.loc.start.line + 1;
|
|
5563
6241
|
}
|
|
@@ -5565,7 +6243,7 @@ function layoutTernaryBreak(between, operator, newline) {
|
|
|
5565
6243
|
const at = between.indexOf(operator);
|
|
5566
6244
|
return `${between.slice(0, at).trimEnd()}${newline}${operator} ${between.slice(at + 1).trimStart()}`;
|
|
5567
6245
|
}
|
|
5568
|
-
var layoutTernary =
|
|
6246
|
+
var layoutTernary = defineRule55({
|
|
5569
6247
|
meta: {
|
|
5570
6248
|
type: "layout",
|
|
5571
6249
|
fixable: "whitespace",
|
|
@@ -5681,9 +6359,9 @@ var layoutTernary = defineRule50({
|
|
|
5681
6359
|
});
|
|
5682
6360
|
|
|
5683
6361
|
// src/rules/naming/naming-declarations.ts
|
|
5684
|
-
import { defineRule as
|
|
6362
|
+
import { defineRule as defineRule56 } from "@oxlint/plugins";
|
|
5685
6363
|
var namingDeclarationsKinds = ["function", "const", "let", "var", "class", "type", "interface", "enum"];
|
|
5686
|
-
var namingDeclarations =
|
|
6364
|
+
var namingDeclarations = defineRule56({
|
|
5687
6365
|
meta: {
|
|
5688
6366
|
type: "problem",
|
|
5689
6367
|
schema: [
|
|
@@ -5760,7 +6438,7 @@ var namingDeclarations = defineRule51({
|
|
|
5760
6438
|
});
|
|
5761
6439
|
|
|
5762
6440
|
// src/rules/naming/naming-exports.ts
|
|
5763
|
-
import { defineRule as
|
|
6441
|
+
import { defineRule as defineRule57 } from "@oxlint/plugins";
|
|
5764
6442
|
var namingExportsScopeProperties = {
|
|
5765
6443
|
scope: { type: "string", enum: ["exports", "functions", "declarations"] },
|
|
5766
6444
|
types: { type: "boolean" },
|
|
@@ -5786,7 +6464,7 @@ function matchTemplate(basename3, template, placeholder = "[a-z0-9-]+") {
|
|
|
5786
6464
|
}
|
|
5787
6465
|
return new RegExp(`^${pattern}$`).exec(basename3)?.groups ?? null;
|
|
5788
6466
|
}
|
|
5789
|
-
var namingExports =
|
|
6467
|
+
var namingExports = defineRule57({
|
|
5790
6468
|
meta: {
|
|
5791
6469
|
type: "problem",
|
|
5792
6470
|
schema: {
|
|
@@ -5923,10 +6601,10 @@ var namingExports = defineRule52({
|
|
|
5923
6601
|
});
|
|
5924
6602
|
|
|
5925
6603
|
// src/rules/naming/naming-file.ts
|
|
5926
|
-
import { defineRule as
|
|
6604
|
+
import { defineRule as defineRule58 } from "@oxlint/plugins";
|
|
5927
6605
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
5928
6606
|
import { dirname as dirname4 } from "node:path";
|
|
5929
|
-
var namingFile =
|
|
6607
|
+
var namingFile = defineRule58({
|
|
5930
6608
|
meta: {
|
|
5931
6609
|
type: "problem",
|
|
5932
6610
|
schema: {
|
|
@@ -5996,9 +6674,9 @@ var namingFile = defineRule53({
|
|
|
5996
6674
|
});
|
|
5997
6675
|
|
|
5998
6676
|
// src/rules/naming/naming-folder.ts
|
|
5999
|
-
import { defineRule as
|
|
6677
|
+
import { defineRule as defineRule59 } from "@oxlint/plugins";
|
|
6000
6678
|
import { posix as posix2 } from "node:path";
|
|
6001
|
-
var namingFolder =
|
|
6679
|
+
var namingFolder = defineRule59({
|
|
6002
6680
|
meta: {
|
|
6003
6681
|
type: "problem",
|
|
6004
6682
|
schema: [
|
|
@@ -6072,9 +6750,9 @@ var reactDynamicClasses = astSelectorRule(':matches(JSXAttribute[name.name="clas
|
|
|
6072
6750
|
var reactEmptyEffect = astSelectorRule(':matches(CallExpression[callee.name=/^use(Layout)?Effect$/], CallExpression[callee.object.name="React"][callee.property.name=/^use(Layout)?Effect$/]) > :matches(ArrowFunctionExpression, FunctionExpression) > BlockStatement[body.length=0]', "Remove the empty effect.");
|
|
6073
6751
|
|
|
6074
6752
|
// src/rules/react/react-memo.ts
|
|
6075
|
-
import { defineRule as
|
|
6753
|
+
import { defineRule as defineRule60 } from "@oxlint/plugins";
|
|
6076
6754
|
var reactMemoNames = ["memo", "useMemo", "useCallback"];
|
|
6077
|
-
var reactMemo =
|
|
6755
|
+
var reactMemo = defineRule60({
|
|
6078
6756
|
meta: {
|
|
6079
6757
|
type: "problem",
|
|
6080
6758
|
schema: [],
|
|
@@ -6109,7 +6787,7 @@ var reactMemo = defineRule55({
|
|
|
6109
6787
|
});
|
|
6110
6788
|
|
|
6111
6789
|
// src/rules/react/react-props.ts
|
|
6112
|
-
import { defineRule as
|
|
6790
|
+
import { defineRule as defineRule61 } from "@oxlint/plugins";
|
|
6113
6791
|
function reactPropsTarget(node) {
|
|
6114
6792
|
if (node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression") {
|
|
6115
6793
|
return { fn: node };
|
|
@@ -6136,7 +6814,7 @@ function reactIsPassThrough(type) {
|
|
|
6136
6814
|
const argument = type.typeArguments?.params.length === 1 ? type.typeArguments.params[0] : undefined;
|
|
6137
6815
|
return name.type === "Identifier" && name.name === "ComponentProps" && (argument?.type === "TSTypeQuery" || argument?.type === "TSLiteralType" && argument.literal.type === "Literal" && typeof argument.literal.value === "string");
|
|
6138
6816
|
}
|
|
6139
|
-
var reactProps =
|
|
6817
|
+
var reactProps = defineRule61({
|
|
6140
6818
|
meta: {
|
|
6141
6819
|
type: "problem",
|
|
6142
6820
|
schema: [
|
|
@@ -6235,7 +6913,7 @@ var reactProps = defineRule56({
|
|
|
6235
6913
|
});
|
|
6236
6914
|
|
|
6237
6915
|
// src/rules/schemas/schemas-inline.ts
|
|
6238
|
-
import { defineRule as
|
|
6916
|
+
import { defineRule as defineRule62 } from "@oxlint/plugins";
|
|
6239
6917
|
|
|
6240
6918
|
// src/utils/schemas.utils.ts
|
|
6241
6919
|
var schemasElementOptionsSchema = {
|
|
@@ -6271,7 +6949,7 @@ function schemasIsAllowedElement(node, allowScalars, namespaces, structuralMetho
|
|
|
6271
6949
|
}
|
|
6272
6950
|
|
|
6273
6951
|
// src/rules/schemas/schemas-inline.ts
|
|
6274
|
-
var schemasInline =
|
|
6952
|
+
var schemasInline = defineRule62({
|
|
6275
6953
|
meta: {
|
|
6276
6954
|
type: "problem",
|
|
6277
6955
|
schema: [schemasElementOptionsSchema],
|
|
@@ -6320,11 +6998,11 @@ var schemasInline = defineRule57({
|
|
|
6320
6998
|
});
|
|
6321
6999
|
|
|
6322
7000
|
// src/rules/schemas/schemas-local.ts
|
|
6323
|
-
import { defineRule as
|
|
7001
|
+
import { defineRule as defineRule63 } from "@oxlint/plugins";
|
|
6324
7002
|
var schemasLocalImportMessage = "Do not import runtime schema constructors from {{source}}; import a named schema instead.";
|
|
6325
7003
|
var schemasLocalConstructionMessage = "Do not construct schemas locally; import a named schema instead.";
|
|
6326
7004
|
var schemasLocalCalls = ["config", "prettifyError", "treeifyError", "flattenError", "formatError"];
|
|
6327
|
-
var schemasLocal =
|
|
7005
|
+
var schemasLocal = defineRule63({
|
|
6328
7006
|
meta: {
|
|
6329
7007
|
type: "problem",
|
|
6330
7008
|
schema: [
|
|
@@ -6337,6 +7015,8 @@ var schemasLocal = defineRule58({
|
|
|
6337
7015
|
calls: { type: "array", items: { type: "string" } },
|
|
6338
7016
|
allow: { type: "array", items: { type: "string" } },
|
|
6339
7017
|
patterns: { type: "array", items: { type: "string" } },
|
|
7018
|
+
imports: { type: "boolean" },
|
|
7019
|
+
values: { type: "boolean" },
|
|
6340
7020
|
message: { type: "string" },
|
|
6341
7021
|
importMessage: { type: "string" },
|
|
6342
7022
|
constructionMessage: { type: "string" }
|
|
@@ -6356,6 +7036,32 @@ var schemasLocal = defineRule58({
|
|
|
6356
7036
|
let pending = [];
|
|
6357
7037
|
let importMessage = schemasLocalImportMessage;
|
|
6358
7038
|
let constructionMessage = schemasLocalConstructionMessage;
|
|
7039
|
+
let imports = true;
|
|
7040
|
+
let values = false;
|
|
7041
|
+
let inline = new Set;
|
|
7042
|
+
function isInline(node) {
|
|
7043
|
+
if (inline.size === 0) {
|
|
7044
|
+
return false;
|
|
7045
|
+
}
|
|
7046
|
+
for (let parent = node.parent;parent; parent = parent.parent) {
|
|
7047
|
+
if (inline.has(parent)) {
|
|
7048
|
+
return true;
|
|
7049
|
+
}
|
|
7050
|
+
}
|
|
7051
|
+
return false;
|
|
7052
|
+
}
|
|
7053
|
+
function readsLocal(node) {
|
|
7054
|
+
const scope = context.sourceCode.getScope(node);
|
|
7055
|
+
return astSome(node, (child) => {
|
|
7056
|
+
if (child.type !== "Identifier") {
|
|
7057
|
+
return false;
|
|
7058
|
+
}
|
|
7059
|
+
const parent = child.parent;
|
|
7060
|
+
const named = parent.type === "MemberExpression" && parent.property === child && !parent.computed || parent.type === "Property" && parent.key === child && !parent.computed && !parent.shorthand;
|
|
7061
|
+
const type = named ? undefined : boundariesDeclaredVariable(scope, child.name)?.scope.type;
|
|
7062
|
+
return type !== undefined && type !== "module" && type !== "global";
|
|
7063
|
+
});
|
|
7064
|
+
}
|
|
6359
7065
|
function isAllowedCall(node, member) {
|
|
6360
7066
|
return member?.type === "MemberExpression" && member.object === node && !member.computed && member.property.type === "Identifier" && calls.has(member.property.name) && member.parent.type === "CallExpression" && member.parent.callee === member;
|
|
6361
7067
|
}
|
|
@@ -6363,6 +7069,9 @@ var schemasLocal = defineRule58({
|
|
|
6363
7069
|
return packages.has(source) || [...packages].some((name) => source.startsWith(`${name}/`));
|
|
6364
7070
|
}
|
|
6365
7071
|
function reportRuntimeImport(node, source) {
|
|
7072
|
+
if (!imports) {
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
6366
7075
|
context.report({
|
|
6367
7076
|
node,
|
|
6368
7077
|
messageId: "runtimeImport",
|
|
@@ -6387,6 +7096,9 @@ var schemasLocal = defineRule58({
|
|
|
6387
7096
|
pending = [];
|
|
6388
7097
|
importMessage = options.importMessage ?? options.message ?? schemasLocalImportMessage;
|
|
6389
7098
|
constructionMessage = options.constructionMessage ?? options.message ?? schemasLocalConstructionMessage;
|
|
7099
|
+
imports = options.imports ?? true;
|
|
7100
|
+
values = options.values ?? false;
|
|
7101
|
+
inline = new Set;
|
|
6390
7102
|
if ((options.allow ?? []).some((suffix) => filename.endsWith(suffix)) || (options.patterns ?? []).some((pattern) => new RegExp(pattern).test(filename))) {
|
|
6391
7103
|
return false;
|
|
6392
7104
|
}
|
|
@@ -6409,7 +7121,7 @@ var schemasLocal = defineRule58({
|
|
|
6409
7121
|
pending.push({ node, locals });
|
|
6410
7122
|
},
|
|
6411
7123
|
"Program:exit"() {
|
|
6412
|
-
const runtime = pending.filter(({ node, locals }) => context.sourceCode.getDeclaredVariables(node).filter((variable) => locals.includes(variable.name)).some((variable) => variable.references.length === 0 || variable.references.some((reference) => !isAllowedCall(reference.identifier, reference.identifier.parent))));
|
|
7124
|
+
const runtime = pending.filter(({ node, locals }) => context.sourceCode.getDeclaredVariables(node).filter((variable) => locals.includes(variable.name)).some((variable) => variable.references.length === 0 || variable.references.some((reference) => !isAllowedCall(reference.identifier, reference.identifier.parent) && !isInline(reference.identifier))));
|
|
6413
7125
|
for (const { node } of runtime) {
|
|
6414
7126
|
reportRuntimeImport(node, node.source.value);
|
|
6415
7127
|
}
|
|
@@ -6424,6 +7136,10 @@ var schemasLocal = defineRule58({
|
|
|
6424
7136
|
if (root.type !== "Identifier" || !constructors.has(root.name) || node.callee.type === "MemberExpression" && node.callee.object === root && isAllowedCall(root, root.parent)) {
|
|
6425
7137
|
return;
|
|
6426
7138
|
}
|
|
7139
|
+
if (values && (isInline(node) || readsLocal(node))) {
|
|
7140
|
+
inline.add(node);
|
|
7141
|
+
return;
|
|
7142
|
+
}
|
|
6427
7143
|
context.report({
|
|
6428
7144
|
node,
|
|
6429
7145
|
messageId: "construction",
|
|
@@ -6435,8 +7151,8 @@ var schemasLocal = defineRule58({
|
|
|
6435
7151
|
});
|
|
6436
7152
|
|
|
6437
7153
|
// src/rules/schemas/schemas-rederive.ts
|
|
6438
|
-
import { defineRule as
|
|
6439
|
-
var schemasRederive =
|
|
7154
|
+
import { defineRule as defineRule64 } from "@oxlint/plugins";
|
|
7155
|
+
var schemasRederive = defineRule64({
|
|
6440
7156
|
meta: {
|
|
6441
7157
|
type: "problem",
|
|
6442
7158
|
schema: [
|
|
@@ -6482,7 +7198,7 @@ var schemasRederive = defineRule59({
|
|
|
6482
7198
|
});
|
|
6483
7199
|
|
|
6484
7200
|
// src/rules/schemas/schemas-single-use.ts
|
|
6485
|
-
import { defineRule as
|
|
7201
|
+
import { defineRule as defineRule65 } from "@oxlint/plugins";
|
|
6486
7202
|
function isScalarSchema(node, namespaces, structuralMethods) {
|
|
6487
7203
|
if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression") {
|
|
6488
7204
|
return false;
|
|
@@ -6496,7 +7212,7 @@ function isScalarSchema(node, namespaces, structuralMethods) {
|
|
|
6496
7212
|
}
|
|
6497
7213
|
return node.callee.object.type === "CallExpression" && isScalarSchema(node.callee.object, namespaces, structuralMethods);
|
|
6498
7214
|
}
|
|
6499
|
-
var schemasSingleUse =
|
|
7215
|
+
var schemasSingleUse = defineRule65({
|
|
6500
7216
|
meta: {
|
|
6501
7217
|
type: "suggestion",
|
|
6502
7218
|
schema: [schemasElementOptionsSchema],
|
|
@@ -6572,7 +7288,7 @@ var schemasSingleUse = defineRule60({
|
|
|
6572
7288
|
});
|
|
6573
7289
|
|
|
6574
7290
|
// src/rules/tests/tests-assertions.ts
|
|
6575
|
-
import { defineRule as
|
|
7291
|
+
import { defineRule as defineRule66 } from "@oxlint/plugins";
|
|
6576
7292
|
var testsAssertionsModifiers = new Set(["for", "each", "concurrent", "sequential", "only", "skip"]);
|
|
6577
7293
|
var testsAssertionsFunctions = [
|
|
6578
7294
|
"expect",
|
|
@@ -6762,7 +7478,7 @@ function isAssertedTest(registration, sourceCode, state) {
|
|
|
6762
7478
|
}
|
|
6763
7479
|
return rows.length > 0 && rows.every((row) => hasAssertion(callback, row.bindings, new Set, state));
|
|
6764
7480
|
}
|
|
6765
|
-
var testsAssertions =
|
|
7481
|
+
var testsAssertions = defineRule66({
|
|
6766
7482
|
meta: {
|
|
6767
7483
|
type: "problem",
|
|
6768
7484
|
schema: [
|
|
@@ -6888,8 +7604,8 @@ var testsAssertions = defineRule61({
|
|
|
6888
7604
|
});
|
|
6889
7605
|
|
|
6890
7606
|
// src/rules/tests/tests-concurrent-db.ts
|
|
6891
|
-
import { defineRule as
|
|
6892
|
-
var testsConcurrentDb =
|
|
7607
|
+
import { defineRule as defineRule67 } from "@oxlint/plugins";
|
|
7608
|
+
var testsConcurrentDb = defineRule67({
|
|
6893
7609
|
meta: {
|
|
6894
7610
|
type: "problem",
|
|
6895
7611
|
schema: [
|
|
@@ -6945,7 +7661,7 @@ var testsConcurrentDb = defineRule62({
|
|
|
6945
7661
|
});
|
|
6946
7662
|
|
|
6947
7663
|
// src/rules/tests/tests-modifiers.ts
|
|
6948
|
-
import { defineRule as
|
|
7664
|
+
import { defineRule as defineRule68 } from "@oxlint/plugins";
|
|
6949
7665
|
var testsModifiersNames = ["test", "it", "describe", "suite"];
|
|
6950
7666
|
var testsModifiersPackages = new Set(["vitest", "bun:test", "@playwright/test", "@jest/globals"]);
|
|
6951
7667
|
var testsModifiersBanned = ["only", "skip", "todo"];
|
|
@@ -6964,7 +7680,7 @@ function modifierName(node) {
|
|
|
6964
7680
|
const property = astMemberName(node);
|
|
6965
7681
|
return object && property ? `${object}.${property}` : undefined;
|
|
6966
7682
|
}
|
|
6967
|
-
var testsModifiers =
|
|
7683
|
+
var testsModifiers = defineRule68({
|
|
6968
7684
|
meta: {
|
|
6969
7685
|
type: "problem",
|
|
6970
7686
|
schema: [
|
|
@@ -7018,9 +7734,9 @@ var testsModifiers = defineRule63({
|
|
|
7018
7734
|
});
|
|
7019
7735
|
|
|
7020
7736
|
// src/rules/tests/tests-titles.ts
|
|
7021
|
-
import { defineRule as
|
|
7737
|
+
import { defineRule as defineRule69 } from "@oxlint/plugins";
|
|
7022
7738
|
var testsTitlesModifiers = ["only", "skip", "concurrent", "sequential", "todo", "each", "for"];
|
|
7023
|
-
var testsTitles =
|
|
7739
|
+
var testsTitles = defineRule69({
|
|
7024
7740
|
meta: {
|
|
7025
7741
|
type: "suggestion",
|
|
7026
7742
|
schema: [
|
|
@@ -7098,11 +7814,11 @@ var testsTitles = defineRule64({
|
|
|
7098
7814
|
});
|
|
7099
7815
|
|
|
7100
7816
|
// src/rules/types/types-declarations.ts
|
|
7101
|
-
import { defineRule as
|
|
7817
|
+
import { defineRule as defineRule70 } from "@oxlint/plugins";
|
|
7102
7818
|
function isValuePattern(source) {
|
|
7103
7819
|
return /^\^?=/.test(source);
|
|
7104
7820
|
}
|
|
7105
|
-
var typesDeclarations =
|
|
7821
|
+
var typesDeclarations = defineRule70({
|
|
7106
7822
|
meta: {
|
|
7107
7823
|
type: "problem",
|
|
7108
7824
|
schema: [
|
|
@@ -7144,8 +7860,73 @@ var typesDeclarations = defineRule65({
|
|
|
7144
7860
|
}
|
|
7145
7861
|
});
|
|
7146
7862
|
|
|
7863
|
+
// src/rules/types/types-duplicate.ts
|
|
7864
|
+
import { defineRule as defineRule71 } from "@oxlint/plugins";
|
|
7865
|
+
var typesDuplicate = defineRule71({
|
|
7866
|
+
meta: {
|
|
7867
|
+
type: "suggestion",
|
|
7868
|
+
schema: [
|
|
7869
|
+
{
|
|
7870
|
+
type: "object",
|
|
7871
|
+
additionalProperties: false,
|
|
7872
|
+
properties: {
|
|
7873
|
+
structs: { type: "array", items: { type: "string" } },
|
|
7874
|
+
min: { type: "integer", minimum: 1 }
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
],
|
|
7878
|
+
messages: { duplicate: "{{name}} has the same members as {{first}}; use {{first}}, or derive one from the other." }
|
|
7879
|
+
},
|
|
7880
|
+
createOnce(context) {
|
|
7881
|
+
let structs = new Set(["Schema.Struct"]);
|
|
7882
|
+
let min = 2;
|
|
7883
|
+
let seen = new Map;
|
|
7884
|
+
const check = (node, name, kind, members) => {
|
|
7885
|
+
if (members.length < min) {
|
|
7886
|
+
return;
|
|
7887
|
+
}
|
|
7888
|
+
const signature = members.map((item) => context.sourceCode.getText(item).replaceAll(/\breadonly\s+/g, "").replaceAll(/\s+/g, "").replace(/[;,]$/, "")).sort().join(";");
|
|
7889
|
+
const key = `${kind}:${signature}`;
|
|
7890
|
+
const first = seen.get(key);
|
|
7891
|
+
if (first === undefined) {
|
|
7892
|
+
seen.set(key, name);
|
|
7893
|
+
return;
|
|
7894
|
+
}
|
|
7895
|
+
context.report({
|
|
7896
|
+
node,
|
|
7897
|
+
messageId: "duplicate",
|
|
7898
|
+
data: { name, first }
|
|
7899
|
+
});
|
|
7900
|
+
};
|
|
7901
|
+
return {
|
|
7902
|
+
before() {
|
|
7903
|
+
const options = optionsFirst(context, {});
|
|
7904
|
+
structs = new Set(options.structs ?? ["Schema.Struct"]);
|
|
7905
|
+
min = options.min ?? 2;
|
|
7906
|
+
seen = new Map;
|
|
7907
|
+
},
|
|
7908
|
+
TSInterfaceDeclaration(node) {
|
|
7909
|
+
const heritage = node.extends.map((item) => context.sourceCode.getText(item)).join(",");
|
|
7910
|
+
check(node, node.id.name, `type:${heritage}`, node.body.body);
|
|
7911
|
+
},
|
|
7912
|
+
TSTypeAliasDeclaration(node) {
|
|
7913
|
+
if (node.typeAnnotation.type === "TSTypeLiteral") {
|
|
7914
|
+
check(node, node.id.name, "type:", node.typeAnnotation.members);
|
|
7915
|
+
}
|
|
7916
|
+
},
|
|
7917
|
+
VariableDeclarator(node) {
|
|
7918
|
+
const init = node.init ? astUnwrap(node.init) : undefined;
|
|
7919
|
+
const fields = init?.type === "CallExpression" && structs.has(astDottedName(init.callee) ?? "") ? init.arguments[0] : undefined;
|
|
7920
|
+
if (fields?.type === "ObjectExpression" && node.id.type === "Identifier") {
|
|
7921
|
+
check(node, node.id.name, "struct", fields.properties);
|
|
7922
|
+
}
|
|
7923
|
+
}
|
|
7924
|
+
};
|
|
7925
|
+
}
|
|
7926
|
+
});
|
|
7927
|
+
|
|
7147
7928
|
// src/rules/types/types-imported-alias.ts
|
|
7148
|
-
import { defineRule as
|
|
7929
|
+
import { defineRule as defineRule72 } from "@oxlint/plugins";
|
|
7149
7930
|
function importedAliasTarget(declaration, imports) {
|
|
7150
7931
|
if (declaration?.type !== "TSTypeAliasDeclaration") {
|
|
7151
7932
|
return;
|
|
@@ -7157,7 +7938,7 @@ function importedAliasTarget(declaration, imports) {
|
|
|
7157
7938
|
const { name } = type.typeName;
|
|
7158
7939
|
return imports.has(name) && !declaration.typeParameters?.params.some((parameter) => parameter.name.name === name) ? name : undefined;
|
|
7159
7940
|
}
|
|
7160
|
-
var typesImportedAlias =
|
|
7941
|
+
var typesImportedAlias = defineRule72({
|
|
7161
7942
|
meta: {
|
|
7162
7943
|
type: "problem",
|
|
7163
7944
|
schema: [],
|
|
@@ -7219,7 +8000,7 @@ var typesImportedAlias = defineRule66({
|
|
|
7219
8000
|
});
|
|
7220
8001
|
|
|
7221
8002
|
// src/rules/types/types-inline.ts
|
|
7222
|
-
import { defineRule as
|
|
8003
|
+
import { defineRule as defineRule73 } from "@oxlint/plugins";
|
|
7223
8004
|
function parameterAnnotation(parameter) {
|
|
7224
8005
|
if (parameter.type === "TSParameterProperty") {
|
|
7225
8006
|
return parameterAnnotation(parameter.parameter);
|
|
@@ -7229,7 +8010,7 @@ function parameterAnnotation(parameter) {
|
|
|
7229
8010
|
}
|
|
7230
8011
|
return parameter.typeAnnotation;
|
|
7231
8012
|
}
|
|
7232
|
-
var typesInline =
|
|
8013
|
+
var typesInline = defineRule73({
|
|
7233
8014
|
meta: {
|
|
7234
8015
|
type: "problem",
|
|
7235
8016
|
schema: [
|
|
@@ -7305,8 +8086,8 @@ var typesInline = defineRule67({
|
|
|
7305
8086
|
var typesLocalAlias = astSelectorRule("TSTypeAliasDeclaration", "Local component/hook contracts use interfaces named for their owner. Derived or reusable aliases belong in domain types; do not substitute an empty interface.");
|
|
7306
8087
|
|
|
7307
8088
|
// src/rules/types/types-namespace-import.ts
|
|
7308
|
-
import { defineRule as
|
|
7309
|
-
var typesNamespaceImport =
|
|
8089
|
+
import { defineRule as defineRule74 } from "@oxlint/plugins";
|
|
8090
|
+
var typesNamespaceImport = defineRule74({
|
|
7310
8091
|
meta: {
|
|
7311
8092
|
type: "suggestion",
|
|
7312
8093
|
schema: [
|
|
@@ -7348,8 +8129,8 @@ var typesNamespaceImport = defineRule68({
|
|
|
7348
8129
|
});
|
|
7349
8130
|
|
|
7350
8131
|
// src/rules/types/types-service.ts
|
|
7351
|
-
import { defineRule as
|
|
7352
|
-
var typesService =
|
|
8132
|
+
import { defineRule as defineRule75 } from "@oxlint/plugins";
|
|
8133
|
+
var typesService = defineRule75({
|
|
7353
8134
|
meta: {
|
|
7354
8135
|
type: "problem",
|
|
7355
8136
|
schema: [
|
|
@@ -7399,12 +8180,12 @@ var typesService = defineRule69({
|
|
|
7399
8180
|
});
|
|
7400
8181
|
|
|
7401
8182
|
// src/rules/types/types-unknown.ts
|
|
7402
|
-
import { defineRule as
|
|
8183
|
+
import { defineRule as defineRule76 } from "@oxlint/plugins";
|
|
7403
8184
|
function isCatchName(node) {
|
|
7404
8185
|
const key = "key" in node && !(("computed" in node) && node.computed) ? node.key : undefined;
|
|
7405
8186
|
return key?.type === "Identifier" && key.name === "catch";
|
|
7406
8187
|
}
|
|
7407
|
-
var typesUnknown =
|
|
8188
|
+
var typesUnknown = defineRule76({
|
|
7408
8189
|
meta: { type: "problem", schema: [], messages: { forbidden: "Use an owned domain type rather than unknown." } },
|
|
7409
8190
|
createOnce(context) {
|
|
7410
8191
|
return {
|
|
@@ -7459,6 +8240,11 @@ var src_default = eslintCompatPlugin({
|
|
|
7459
8240
|
"comments-code": commentsCode,
|
|
7460
8241
|
"comments-directives": commentsDirectives,
|
|
7461
8242
|
"copy-dashes": copyDashes,
|
|
8243
|
+
"effect-layer-file": effectLayerFile,
|
|
8244
|
+
"effect-layers": effectLayers,
|
|
8245
|
+
"effect-merge-pipe": effectMergePipe,
|
|
8246
|
+
"effect-schema-first": effectSchemaFirst,
|
|
8247
|
+
"effect-values-first": effectValuesFirst,
|
|
7462
8248
|
"files-components-only": filesComponentsOnly,
|
|
7463
8249
|
"files-constants-only": filesConstantsOnly,
|
|
7464
8250
|
"files-domain-constants": filesDomainConstants,
|
|
@@ -7500,6 +8286,7 @@ var src_default = eslintCompatPlugin({
|
|
|
7500
8286
|
"tests-modifiers": testsModifiers,
|
|
7501
8287
|
"tests-titles": testsTitles,
|
|
7502
8288
|
"types-declarations": typesDeclarations,
|
|
8289
|
+
"types-duplicate": typesDuplicate,
|
|
7503
8290
|
"types-imported-alias": typesImportedAlias,
|
|
7504
8291
|
"types-inline": typesInline,
|
|
7505
8292
|
"types-local-alias": typesLocalAlias,
|