@violetflux/eslint-plugin-kerros 0.3.2 → 0.3.3
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/index.cjs +48 -8
- package/dist/index.mjs +48 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -736,7 +736,10 @@ const noBroadStoreAccess = createRule({
|
|
|
736
736
|
docs: { description: "Prevent broad enumeration and serialization of complete Store snapshots." },
|
|
737
737
|
schema: [{
|
|
738
738
|
type: "object",
|
|
739
|
-
properties: {
|
|
739
|
+
properties: {
|
|
740
|
+
includeObjectFields: { type: "boolean" },
|
|
741
|
+
includeStoreModels: { type: "boolean" }
|
|
742
|
+
},
|
|
740
743
|
additionalProperties: false
|
|
741
744
|
}],
|
|
742
745
|
messages: {
|
|
@@ -744,10 +747,31 @@ const noBroadStoreAccess = createRule({
|
|
|
744
747
|
broadObjectField: "Do not enumerate, serialize, or spread an object field from a selector-free Store snapshot."
|
|
745
748
|
}
|
|
746
749
|
},
|
|
747
|
-
defaultOptions: [{
|
|
750
|
+
defaultOptions: [{
|
|
751
|
+
includeObjectFields: false,
|
|
752
|
+
includeStoreModels: false
|
|
753
|
+
}],
|
|
748
754
|
create(context, [options]) {
|
|
749
|
-
const { getIdentifierSymbol, getType, isStoreHookCall } = createKerrosTypeTools(context);
|
|
755
|
+
const { getFactoryKind, getIdentifierSymbol, getType, isStoreHookCall } = createKerrosTypeTools(context);
|
|
750
756
|
const origins = createReferenceOriginTracker(context.sourceCode.ast);
|
|
757
|
+
const storeModels = /* @__PURE__ */ new Set();
|
|
758
|
+
const pendingReports = [];
|
|
759
|
+
/** Test whether an expression belongs to a function registered as a createStore model. */
|
|
760
|
+
const isInsideStoreModel = (expression) => {
|
|
761
|
+
let node = expression.parent;
|
|
762
|
+
while (node) {
|
|
763
|
+
if (node.type === "FunctionDeclaration" && node.id) {
|
|
764
|
+
const symbol = getIdentifierSymbol(node.id);
|
|
765
|
+
return symbol ? storeModels.has(symbol) : false;
|
|
766
|
+
}
|
|
767
|
+
if ((node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") && node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier") {
|
|
768
|
+
const symbol = getIdentifierSymbol(node.parent.id);
|
|
769
|
+
return symbol ? storeModels.has(symbol) : false;
|
|
770
|
+
}
|
|
771
|
+
node = node.parent;
|
|
772
|
+
}
|
|
773
|
+
return false;
|
|
774
|
+
};
|
|
751
775
|
/** Classify whether an expression is a complete Store snapshot or one object field from it. */
|
|
752
776
|
const readStoreOrigin = (input, seen = /* @__PURE__ */ new Set()) => {
|
|
753
777
|
const node = unwrapExpression(input);
|
|
@@ -777,12 +801,12 @@ const noBroadStoreAccess = createRule({
|
|
|
777
801
|
/** Report one operation that subscribes to every enumerable field. */
|
|
778
802
|
const reportBroadAccess = (expression) => {
|
|
779
803
|
const origin = readStoreOrigin(expression);
|
|
780
|
-
if (origin === "snapshot")
|
|
781
|
-
|
|
804
|
+
if (origin === "snapshot") pendingReports.push({
|
|
805
|
+
expression,
|
|
782
806
|
messageId: "broadAccess"
|
|
783
807
|
});
|
|
784
|
-
else if (origin === "objectField" && options.includeObjectFields)
|
|
785
|
-
|
|
808
|
+
else if (origin === "objectField" && options.includeObjectFields) pendingReports.push({
|
|
809
|
+
expression,
|
|
786
810
|
messageId: "broadObjectField"
|
|
787
811
|
});
|
|
788
812
|
};
|
|
@@ -812,6 +836,13 @@ const noBroadStoreAccess = createRule({
|
|
|
812
836
|
};
|
|
813
837
|
return {
|
|
814
838
|
CallExpression(node) {
|
|
839
|
+
if (getFactoryKind(node) === "createStore") {
|
|
840
|
+
const model = node.arguments[0];
|
|
841
|
+
if (model?.type === "Identifier") {
|
|
842
|
+
const symbol = getIdentifierSymbol(model);
|
|
843
|
+
if (symbol) storeModels.add(symbol);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
815
846
|
const argument = getBroadArgument(node);
|
|
816
847
|
if (argument) reportBroadAccess(argument);
|
|
817
848
|
},
|
|
@@ -838,6 +869,15 @@ const noBroadStoreAccess = createRule({
|
|
|
838
869
|
expression: node.right,
|
|
839
870
|
objectField: false
|
|
840
871
|
}, node);
|
|
872
|
+
},
|
|
873
|
+
"Program:exit"() {
|
|
874
|
+
for (const { expression, messageId } of pendingReports) {
|
|
875
|
+
if (!options.includeStoreModels && isInsideStoreModel(expression)) continue;
|
|
876
|
+
context.report({
|
|
877
|
+
node: expression,
|
|
878
|
+
messageId
|
|
879
|
+
});
|
|
880
|
+
}
|
|
841
881
|
}
|
|
842
882
|
};
|
|
843
883
|
}
|
|
@@ -2501,7 +2541,7 @@ const rules = {
|
|
|
2501
2541
|
const plugin = {
|
|
2502
2542
|
meta: {
|
|
2503
2543
|
name: "@violetflux/eslint-plugin-kerros",
|
|
2504
|
-
version: "0.3.
|
|
2544
|
+
version: "0.3.3"
|
|
2505
2545
|
},
|
|
2506
2546
|
rules
|
|
2507
2547
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -708,7 +708,10 @@ const noBroadStoreAccess = createRule({
|
|
|
708
708
|
docs: { description: "Prevent broad enumeration and serialization of complete Store snapshots." },
|
|
709
709
|
schema: [{
|
|
710
710
|
type: "object",
|
|
711
|
-
properties: {
|
|
711
|
+
properties: {
|
|
712
|
+
includeObjectFields: { type: "boolean" },
|
|
713
|
+
includeStoreModels: { type: "boolean" }
|
|
714
|
+
},
|
|
712
715
|
additionalProperties: false
|
|
713
716
|
}],
|
|
714
717
|
messages: {
|
|
@@ -716,10 +719,31 @@ const noBroadStoreAccess = createRule({
|
|
|
716
719
|
broadObjectField: "Do not enumerate, serialize, or spread an object field from a selector-free Store snapshot."
|
|
717
720
|
}
|
|
718
721
|
},
|
|
719
|
-
defaultOptions: [{
|
|
722
|
+
defaultOptions: [{
|
|
723
|
+
includeObjectFields: false,
|
|
724
|
+
includeStoreModels: false
|
|
725
|
+
}],
|
|
720
726
|
create(context, [options]) {
|
|
721
|
-
const { getIdentifierSymbol, getType, isStoreHookCall } = createKerrosTypeTools(context);
|
|
727
|
+
const { getFactoryKind, getIdentifierSymbol, getType, isStoreHookCall } = createKerrosTypeTools(context);
|
|
722
728
|
const origins = createReferenceOriginTracker(context.sourceCode.ast);
|
|
729
|
+
const storeModels = /* @__PURE__ */ new Set();
|
|
730
|
+
const pendingReports = [];
|
|
731
|
+
/** Test whether an expression belongs to a function registered as a createStore model. */
|
|
732
|
+
const isInsideStoreModel = (expression) => {
|
|
733
|
+
let node = expression.parent;
|
|
734
|
+
while (node) {
|
|
735
|
+
if (node.type === "FunctionDeclaration" && node.id) {
|
|
736
|
+
const symbol = getIdentifierSymbol(node.id);
|
|
737
|
+
return symbol ? storeModels.has(symbol) : false;
|
|
738
|
+
}
|
|
739
|
+
if ((node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") && node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier") {
|
|
740
|
+
const symbol = getIdentifierSymbol(node.parent.id);
|
|
741
|
+
return symbol ? storeModels.has(symbol) : false;
|
|
742
|
+
}
|
|
743
|
+
node = node.parent;
|
|
744
|
+
}
|
|
745
|
+
return false;
|
|
746
|
+
};
|
|
723
747
|
/** Classify whether an expression is a complete Store snapshot or one object field from it. */
|
|
724
748
|
const readStoreOrigin = (input, seen = /* @__PURE__ */ new Set()) => {
|
|
725
749
|
const node = unwrapExpression(input);
|
|
@@ -749,12 +773,12 @@ const noBroadStoreAccess = createRule({
|
|
|
749
773
|
/** Report one operation that subscribes to every enumerable field. */
|
|
750
774
|
const reportBroadAccess = (expression) => {
|
|
751
775
|
const origin = readStoreOrigin(expression);
|
|
752
|
-
if (origin === "snapshot")
|
|
753
|
-
|
|
776
|
+
if (origin === "snapshot") pendingReports.push({
|
|
777
|
+
expression,
|
|
754
778
|
messageId: "broadAccess"
|
|
755
779
|
});
|
|
756
|
-
else if (origin === "objectField" && options.includeObjectFields)
|
|
757
|
-
|
|
780
|
+
else if (origin === "objectField" && options.includeObjectFields) pendingReports.push({
|
|
781
|
+
expression,
|
|
758
782
|
messageId: "broadObjectField"
|
|
759
783
|
});
|
|
760
784
|
};
|
|
@@ -784,6 +808,13 @@ const noBroadStoreAccess = createRule({
|
|
|
784
808
|
};
|
|
785
809
|
return {
|
|
786
810
|
CallExpression(node) {
|
|
811
|
+
if (getFactoryKind(node) === "createStore") {
|
|
812
|
+
const model = node.arguments[0];
|
|
813
|
+
if (model?.type === "Identifier") {
|
|
814
|
+
const symbol = getIdentifierSymbol(model);
|
|
815
|
+
if (symbol) storeModels.add(symbol);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
787
818
|
const argument = getBroadArgument(node);
|
|
788
819
|
if (argument) reportBroadAccess(argument);
|
|
789
820
|
},
|
|
@@ -810,6 +841,15 @@ const noBroadStoreAccess = createRule({
|
|
|
810
841
|
expression: node.right,
|
|
811
842
|
objectField: false
|
|
812
843
|
}, node);
|
|
844
|
+
},
|
|
845
|
+
"Program:exit"() {
|
|
846
|
+
for (const { expression, messageId } of pendingReports) {
|
|
847
|
+
if (!options.includeStoreModels && isInsideStoreModel(expression)) continue;
|
|
848
|
+
context.report({
|
|
849
|
+
node: expression,
|
|
850
|
+
messageId
|
|
851
|
+
});
|
|
852
|
+
}
|
|
813
853
|
}
|
|
814
854
|
};
|
|
815
855
|
}
|
|
@@ -2473,7 +2513,7 @@ const rules = {
|
|
|
2473
2513
|
const plugin = {
|
|
2474
2514
|
meta: {
|
|
2475
2515
|
name: "@violetflux/eslint-plugin-kerros",
|
|
2476
|
-
version: "0.3.
|
|
2516
|
+
version: "0.3.3"
|
|
2477
2517
|
},
|
|
2478
2518
|
rules
|
|
2479
2519
|
};
|