History

[codex] Fix paid organization creation limit (#829)

* Fix paid organization creation limit * Clarify stack PR URL reporting * Clarify clickable stack PR links

Rhys Sullivan committed 5 months ago

Commit 766c7901 parent 62b8b7d14 files · +385 −14Browse files

Showing the changes to scripts (2 of 14 files). Show all

Unified · Split

2 files
  1. scripts/oxlint-plugin-executor.js +2 −0
  2. scripts/oxlint-plugin-executor/rules/prefer-effect-predicate.js +89 −0
scripts/oxlint-plugin-executor.js+2−0
@@ -27,6 +27,7 @@ import noUnknownErrorMessage from "./oxlint-plugin-executor/rules/no-unknown-err · 26 unmodified lines
2727 import noUnknownShapeProbing from "./oxlint-plugin-executor/rules/no-unknown-shape-probing.js";
2828 import noUnsupportedEffectApi from "./oxlint-plugin-executor/rules/no-unsupported-effect-api.js";
2929 import noVitestImport from "./oxlint-plugin-executor/rules/no-vitest-import.js";
30+import preferEffectPredicate from "./oxlint-plugin-executor/rules/prefer-effect-predicate.js";
3031 import preferSchemaInferredTypes from "./oxlint-plugin-executor/rules/prefer-schema-inferred-types.js";
3132 import preferYieldTaggedError from "./oxlint-plugin-executor/rules/prefer-yield-tagged-error.js";
3233 import preferValueInferredExtensionTypes from "./oxlint-plugin-executor/rules/prefer-value-inferred-extension-types.js";
@@ -67,6 +68,7 @@ export default { · 34 unmodified lines
6768 "no-unknown-error-message": noUnknownErrorMessage,
6869 "no-unknown-shape-probing": noUnknownShapeProbing,
6970 "no-unsupported-effect-api": noUnsupportedEffectApi,
71+ "prefer-effect-predicate": preferEffectPredicate,
7072 "prefer-schema-inferred-types": preferSchemaInferredTypes,
7173 "prefer-value-inferred-extension-types": preferValueInferredExtensionTypes,
7274 "prefer-yield-tagged-error": preferYieldTaggedError,
scripts/oxlint-plugin-executor/rules/prefer-effect-predicate.js+89−0
@@ -0,0 +1,89 @@
1+import { getPropertyName, isIdentifier, unwrapExpression } from "../utils.js";
2+
3+const message =
4+ "Use Predicate.isNotNull/isNotUndefined/isNotNullish from effect instead of hand-rolled nullish predicates.";
5+
6+const nullishOperators = new Set(["!==", "!=", "===", "=="]);
7+
8+const isNullLiteral = (node) => node?.type === "Literal" && node.value === null;
9+const isUndefinedIdentifier = (node) => isIdentifier(node, "undefined");
10+const isNullishLiteral = (node) => isNullLiteral(node) || isUndefinedIdentifier(node);
11+
12+const isNullishComparison = (node, identifierName) => {
13+ const expression = unwrapExpression(node);
14+ if (expression?.type !== "BinaryExpression" || !nullishOperators.has(expression.operator)) {
15+ return false;
16+ }
17+
18+ const left = unwrapExpression(expression.left);
19+ const right = unwrapExpression(expression.right);
20+ return (
21+ (isIdentifier(left, identifierName) && isNullishLiteral(right)) ||
22+ (isIdentifier(right, identifierName) && isNullishLiteral(left))
23+ );
24+};
25+
26+const getSingleIdentifierParamName = (params) => {
27+ if (params.length !== 1) return undefined;
28+ const param = unwrapExpression(params[0]);
29+ return param?.type === "Identifier" ? param.name : undefined;
30+};
31+
32+const isNullishPredicateFunction = (node) => {
33+ const name = getSingleIdentifierParamName(node.params ?? []);
34+ return name !== undefined && isNullishComparison(node.body, name);
35+};
36+
37+const isFilterCall = (node) => {
38+ const callee = unwrapExpression(node.callee);
39+ return callee?.type === "MemberExpression" && getPropertyName(callee.property) === "filter";
40+};
41+
42+const importsEffect = (node) => {
43+ const source = node.source;
44+ return source?.type === "Literal" && source.value === "effect";
45+};
46+
47+export default {
48+ meta: {
49+ type: "problem",
50+ docs: {
51+ description: message,
52+ },
53+ },
54+ create(context) {
55+ let hasEffectImport = false;
56+
57+ return {
58+ ImportDeclaration(node) {
59+ if (importsEffect(node)) {
60+ hasEffectImport = true;
61+ }
62+ },
63+ VariableDeclarator(node) {
64+ if (!hasEffectImport) return;
65+ const init = unwrapExpression(node.init);
66+ if (init?.type === "ArrowFunctionExpression" && isNullishPredicateFunction(init)) {
67+ context.report({ node: init, message });
68+ }
69+ },
70+ FunctionDeclaration(node) {
71+ if (!hasEffectImport) return;
72+ if (isNullishPredicateFunction(node)) {
73+ context.report({ node, message });
74+ }
75+ },
76+ CallExpression(node) {
77+ if (!hasEffectImport || !isFilterCall(node)) return;
78+ const predicate = unwrapExpression(node.arguments[0]);
79+ if (
80+ (predicate?.type === "ArrowFunctionExpression" ||
81+ predicate?.type === "FunctionExpression") &&
82+ isNullishPredicateFunction(predicate)
83+ ) {
84+ context.report({ node: predicate, message });
85+ }
86+ },
87+ };
88+ },
89+};