@yasainet/eslint 0.0.51 → 0.0.52

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/README.md CHANGED
@@ -35,7 +35,7 @@ Each entry point enforces a feature-based architecture with the following conven
35
35
  ├── shared/ # Cross-feature shared modules
36
36
  ├── ...
37
37
  {libRoot}/ # *.lib.ts — library wrappers (e.g., supabase.lib.ts)
38
- {utilsRoot}/ # *.util.ts — top-level utilities
38
+ {utilsRoot}/ # *.util.ts — top-level utilities (e.g., font.util.ts)
39
39
  ```
40
40
 
41
41
  ## Setup
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yasainet/eslint",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "ESLint",
5
5
  "type": "module",
6
6
  "exports": {
@@ -2,6 +2,7 @@ import { featureNameRule } from "./feature-name.mjs";
2
2
  import { importPathStyleRule } from "./import-path-style.mjs";
3
3
  import { namespaceImportNameRule } from "./namespace-import-name.mjs";
4
4
  import { noAnyReturnRule } from "./no-any-return.mjs";
5
+ import { queriesExportRule } from "./queries-export.mjs";
5
6
  import { schemaNamingRule } from "./schema-naming.mjs";
6
7
 
7
8
  /** Single plugin object to avoid ESLint "Cannot redefine plugin" errors. */
@@ -11,6 +12,7 @@ export const localPlugin = {
11
12
  "import-path-style": importPathStyleRule,
12
13
  "namespace-import-name": namespaceImportNameRule,
13
14
  "no-any-return": noAnyReturnRule,
15
+ "queries-export": queriesExportRule,
14
16
  "schema-naming": schemaNamingRule,
15
17
  },
16
18
  };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Enforce verb allow list for `queries/*.query.ts` exports.
3
+ *
4
+ * The queries layer is the TS-idiomatic translation of Rails 5 actions
5
+ * (index/show -> get, create, update, destroy -> delete). Auth ceremonies
6
+ * (signUp / signIn / signOut) are admitted as industry-standard exceptions.
7
+ */
8
+
9
+ const QUERIES_ALLOW = /^(get|create|update|delete|signUp|signIn|signOut)([A-Z]|$)/;
10
+
11
+ function isFunctionLike(initNode) {
12
+ if (!initNode) return false;
13
+ const t = initNode.type;
14
+ if (t === "ArrowFunctionExpression" || t === "FunctionExpression") return true;
15
+ if (t === "CallExpression") {
16
+ return initNode.arguments.some(
17
+ (arg) =>
18
+ arg.type === "ArrowFunctionExpression" ||
19
+ arg.type === "FunctionExpression",
20
+ );
21
+ }
22
+ return false;
23
+ }
24
+
25
+ function reportIfInvalid(context, idNode) {
26
+ if (!QUERIES_ALLOW.test(idNode.name)) {
27
+ context.report({
28
+ node: idNode,
29
+ messageId: "invalidName",
30
+ data: { name: idNode.name },
31
+ });
32
+ }
33
+ }
34
+
35
+ export const queriesExportRule = {
36
+ meta: {
37
+ type: "problem",
38
+ messages: {
39
+ invalidName:
40
+ "queries export '{{ name }}' must start with one of: get, create, update, delete, signUp, signIn, signOut. (Rails 5 actions translated to TS idiom)",
41
+ },
42
+ schema: [],
43
+ },
44
+ create(context) {
45
+ return {
46
+ ExportNamedDeclaration(node) {
47
+ if (!node.declaration) return;
48
+ const decl = node.declaration;
49
+
50
+ if (decl.type === "FunctionDeclaration" && decl.id) {
51
+ reportIfInvalid(context, decl.id);
52
+ return;
53
+ }
54
+
55
+ if (decl.type === "VariableDeclaration") {
56
+ for (const variator of decl.declarations) {
57
+ if (variator.id.type !== "Identifier") continue;
58
+ if (!isFunctionLike(variator.init)) continue;
59
+ reportIfInvalid(context, variator.id);
60
+ }
61
+ }
62
+ },
63
+ };
64
+ },
65
+ };
@@ -102,6 +102,14 @@ export function createNamingConfigs(featureRoot, prefixLibMapping) {
102
102
  ],
103
103
  },
104
104
  },
105
+ {
106
+ name: "naming/queries-export",
107
+ files: featuresGlob(featureRoot, "**/queries/*.query.ts"),
108
+ plugins: { local: localPlugin },
109
+ rules: {
110
+ "local/queries-export": "error",
111
+ },
112
+ },
105
113
  );
106
114
 
107
115
  configs.push(