@cedarjs/eslint-plugin 9.0.0-canary.1784 → 9.0.0-canary.3124

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.
@@ -0,0 +1,3 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const cellTypeAnnotations: TSESLint.RuleModule<"needsTypeAnnotation" | "beforeQueryParamNeedsType", [], unknown, TSESLint.RuleListener>;
3
+ //# sourceMappingURL=cell-type-annotations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell-type-annotations.d.ts","sourceRoot":"","sources":["../src/cell-type-annotations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAA;AAwHlE,eAAO,MAAM,mBAAmB,8GAiZ9B,CAAA"}
@@ -0,0 +1,348 @@
1
+ import { basename } from "node:path";
2
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
3
+ const createRule = ESLintUtils.RuleCreator.withoutDocs;
4
+ const LIFECYCLE_EXPORTS = /* @__PURE__ */ new Set(["beforeQuery", "afterQuery", "isEmpty"]);
5
+ const RENDER_PROP_EXPORTS = /* @__PURE__ */ new Set(["Loading", "Failure", "Success"]);
6
+ function getParamPattern(param) {
7
+ return param.type === AST_NODE_TYPES.AssignmentPattern ? param.left : param;
8
+ }
9
+ function paramHasTypeAnnotation(param) {
10
+ const pattern = getParamPattern(param);
11
+ return "typeAnnotation" in pattern && !!pattern.typeAnnotation;
12
+ }
13
+ function getParamsClosingParen(sourceCode, fn) {
14
+ if (fn.params.length > 0) {
15
+ const lastParam = fn.params[fn.params.length - 1];
16
+ return sourceCode.getTokenAfter(lastParam, (token) => token.value === ")");
17
+ }
18
+ return sourceCode.getFirstToken(fn, (token) => token.value === ")");
19
+ }
20
+ function isUnparenthesizedArrowParam(fn, param, sourceCode) {
21
+ if (fn.type !== AST_NODE_TYPES.ArrowFunctionExpression) {
22
+ return false;
23
+ }
24
+ if (fn.params.length !== 1 || fn.params[0] !== param) {
25
+ return false;
26
+ }
27
+ return sourceCode.getTokenBefore(param)?.value !== "(";
28
+ }
29
+ function* insertWrappedAnnotations(fixer, param, paramTypeText, returnTypeText) {
30
+ yield fixer.insertTextBefore(param, "(");
31
+ const paramPart = paramTypeText ? `: ${paramTypeText}` : "";
32
+ const returnPart = returnTypeText ? `: ${returnTypeText}` : "";
33
+ yield fixer.insertTextAfter(param, `${paramPart})${returnPart}`);
34
+ }
35
+ function extractTypedDocumentNodeArgs(typeAnnotation, sourceCode) {
36
+ const type = typeAnnotation?.typeAnnotation;
37
+ if (type?.type !== AST_NODE_TYPES.TSTypeReference) {
38
+ return null;
39
+ }
40
+ if (type.typeName.type !== AST_NODE_TYPES.Identifier || type.typeName.name !== "TypedDocumentNode") {
41
+ return null;
42
+ }
43
+ const args = type.typeArguments?.params;
44
+ if (!args || args.length < 2) {
45
+ return null;
46
+ }
47
+ return {
48
+ data: sourceCode.getText(args[0]),
49
+ variables: sourceCode.getText(args[1])
50
+ };
51
+ }
52
+ function isImportSpecifier(specifier) {
53
+ return specifier.type === AST_NODE_TYPES.ImportSpecifier;
54
+ }
55
+ const cellTypeAnnotations = createRule({
56
+ meta: {
57
+ type: "suggestion",
58
+ docs: {
59
+ description: "Sets the types on a Cell file's lifecycle hooks and render props to the correct @cedarjs/web Cell types"
60
+ },
61
+ messages: {
62
+ needsTypeAnnotation: "The `{{name}}` {{kind}} needs a type annotation of `{{typeName}}` ({{location}}).",
63
+ beforeQueryParamNeedsType: "`beforeQuery`'s first parameter needs a type annotation. Cedar infers the Cell's external props from it, so leaving it untyped degrades type checking at every call site of this Cell."
64
+ },
65
+ fixable: "code",
66
+ schema: []
67
+ },
68
+ defaultOptions: [],
69
+ create(context) {
70
+ const sourceCode = context.sourceCode;
71
+ const filename = basename(context.filename);
72
+ const filenameIndicatesCell = filename.endsWith("Cell.tsx");
73
+ let hasQueryOrFragment = false;
74
+ let hasSuccessExport = false;
75
+ let derivedQueryTypes = null;
76
+ let webTypeImport = null;
77
+ const importedWebTypeNames = /* @__PURE__ */ new Set();
78
+ const checks = [];
79
+ const claimedImportNames = /* @__PURE__ */ new Set();
80
+ function needsImportEdit(importName) {
81
+ if (!importName) {
82
+ return false;
83
+ }
84
+ if (importedWebTypeNames.has(importName)) {
85
+ return false;
86
+ }
87
+ if (claimedImportNames.has(importName)) {
88
+ return false;
89
+ }
90
+ claimedImportNames.add(importName);
91
+ return true;
92
+ }
93
+ function* importEdit(fixer, importName) {
94
+ const specifiers = webTypeImport?.specifiers.filter(isImportSpecifier) ?? [];
95
+ const lastSpecifier = specifiers[specifiers.length - 1];
96
+ if (lastSpecifier) {
97
+ yield fixer.insertTextAfter(lastSpecifier, `, ${importName}`);
98
+ return;
99
+ }
100
+ yield fixer.insertTextBeforeRange(
101
+ [0, 0],
102
+ `import type { ${importName} } from '@cedarjs/web'
103
+ `
104
+ );
105
+ }
106
+ function checkBeforeQuery(fn, reportNode) {
107
+ const variablesType = derivedQueryTypes?.variables ?? "Record<string, unknown>";
108
+ if (!fn.returnType) {
109
+ const typeName = `CellBeforeQueryResult<${variablesType}>`;
110
+ const shouldImport = needsImportEdit("CellBeforeQueryResult");
111
+ context.report({
112
+ node: reportNode,
113
+ messageId: "needsTypeAnnotation",
114
+ data: {
115
+ name: "beforeQuery",
116
+ typeName,
117
+ kind: "function",
118
+ location: "return type"
119
+ },
120
+ *fix(fixer) {
121
+ const [firstParam2] = fn.params;
122
+ if (firstParam2 && isUnparenthesizedArrowParam(fn, firstParam2, sourceCode)) {
123
+ yield* insertWrappedAnnotations(fixer, firstParam2, null, typeName);
124
+ } else {
125
+ const closingParen = getParamsClosingParen(sourceCode, fn);
126
+ if (!closingParen) {
127
+ return;
128
+ }
129
+ yield fixer.insertTextAfter(closingParen, `: ${typeName}`);
130
+ }
131
+ if (shouldImport) {
132
+ yield* importEdit(fixer, "CellBeforeQueryResult");
133
+ }
134
+ }
135
+ });
136
+ }
137
+ const firstParam = fn.params[0];
138
+ if (firstParam && !paramHasTypeAnnotation(firstParam)) {
139
+ context.report({
140
+ node: reportNode,
141
+ messageId: "beforeQueryParamNeedsType"
142
+ });
143
+ }
144
+ }
145
+ function checkAfterQuery(fn, reportNode) {
146
+ const firstParam = fn.params[0];
147
+ const missingParam = !!firstParam && !paramHasTypeAnnotation(firstParam);
148
+ if (!missingParam) {
149
+ return;
150
+ }
151
+ const shouldImport = needsImportEdit("DataObject");
152
+ context.report({
153
+ node: reportNode,
154
+ messageId: "needsTypeAnnotation",
155
+ data: {
156
+ name: "afterQuery",
157
+ typeName: "DataObject",
158
+ kind: "function",
159
+ location: "parameter"
160
+ },
161
+ *fix(fixer) {
162
+ if (firstParam && isUnparenthesizedArrowParam(fn, firstParam, sourceCode)) {
163
+ yield* insertWrappedAnnotations(
164
+ fixer,
165
+ firstParam,
166
+ "DataObject",
167
+ null
168
+ );
169
+ } else if (firstParam) {
170
+ yield fixer.insertTextAfter(
171
+ getParamPattern(firstParam),
172
+ ": DataObject"
173
+ );
174
+ }
175
+ if (shouldImport) {
176
+ yield* importEdit(fixer, "DataObject");
177
+ }
178
+ }
179
+ });
180
+ }
181
+ function checkIsEmpty(fn, reportNode) {
182
+ const [responseParam, optionsParam] = fn.params;
183
+ const missingResponseType = !!responseParam && !paramHasTypeAnnotation(responseParam);
184
+ const missingOptionsType = !!optionsParam && !paramHasTypeAnnotation(optionsParam);
185
+ if (!missingResponseType && !missingOptionsType) {
186
+ return;
187
+ }
188
+ const shouldImport = needsImportEdit("DataObject");
189
+ context.report({
190
+ node: reportNode,
191
+ messageId: "needsTypeAnnotation",
192
+ data: {
193
+ name: "isEmpty",
194
+ typeName: "DataObject",
195
+ kind: "function",
196
+ location: "parameters"
197
+ },
198
+ *fix(fixer) {
199
+ if (responseParam && isUnparenthesizedArrowParam(fn, responseParam, sourceCode)) {
200
+ yield* insertWrappedAnnotations(
201
+ fixer,
202
+ responseParam,
203
+ missingResponseType ? "DataObject" : null,
204
+ null
205
+ );
206
+ } else {
207
+ if (missingResponseType && responseParam) {
208
+ yield fixer.insertTextAfter(
209
+ getParamPattern(responseParam),
210
+ ": DataObject"
211
+ );
212
+ }
213
+ if (missingOptionsType && optionsParam) {
214
+ yield fixer.insertTextAfter(
215
+ getParamPattern(optionsParam),
216
+ ": { isDataEmpty: (data: DataObject) => boolean }"
217
+ );
218
+ }
219
+ }
220
+ if (shouldImport) {
221
+ yield* importEdit(fixer, "DataObject");
222
+ }
223
+ }
224
+ });
225
+ }
226
+ function checkRenderProp(name, fn, reportNode) {
227
+ const [propsParam] = fn.params;
228
+ if (!propsParam || paramHasTypeAnnotation(propsParam)) {
229
+ return;
230
+ }
231
+ const variablesType = derivedQueryTypes?.variables;
232
+ let insertText;
233
+ if (name === "Success") {
234
+ insertText = derivedQueryTypes ? `CellSuccessProps<${derivedQueryTypes.data}, ${derivedQueryTypes.variables}>` : "CellSuccessProps";
235
+ } else if (name === "Failure") {
236
+ insertText = variablesType ? `CellFailureProps<${variablesType}>` : "CellFailureProps";
237
+ } else {
238
+ insertText = variablesType ? `CellLoadingProps<${variablesType}>` : "CellLoadingProps";
239
+ }
240
+ const importName = `Cell${name}Props`;
241
+ const shouldImport = needsImportEdit(importName);
242
+ context.report({
243
+ node: reportNode,
244
+ messageId: "needsTypeAnnotation",
245
+ data: {
246
+ name,
247
+ typeName: insertText,
248
+ kind: "component",
249
+ location: "parameter"
250
+ },
251
+ *fix(fixer) {
252
+ if (isUnparenthesizedArrowParam(fn, propsParam, sourceCode)) {
253
+ yield* insertWrappedAnnotations(fixer, propsParam, insertText, null);
254
+ } else {
255
+ yield fixer.insertTextAfter(
256
+ getParamPattern(propsParam),
257
+ `: ${insertText}`
258
+ );
259
+ }
260
+ if (shouldImport) {
261
+ yield* importEdit(fixer, importName);
262
+ }
263
+ }
264
+ });
265
+ }
266
+ function checkExport(name, fn, reportNode) {
267
+ if (name === "beforeQuery") {
268
+ checkBeforeQuery(fn, reportNode);
269
+ } else if (name === "afterQuery") {
270
+ checkAfterQuery(fn, reportNode);
271
+ } else if (name === "isEmpty") {
272
+ checkIsEmpty(fn, reportNode);
273
+ } else if (RENDER_PROP_EXPORTS.has(name)) {
274
+ checkRenderProp(name, fn, reportNode);
275
+ }
276
+ }
277
+ return {
278
+ ImportDeclaration(node) {
279
+ if (node.source.value !== "@cedarjs/web") {
280
+ return;
281
+ }
282
+ if (node.importKind === "type") {
283
+ webTypeImport = node;
284
+ }
285
+ node.specifiers.filter(isImportSpecifier).forEach((specifier) => {
286
+ if (node.importKind === "type" || specifier.importKind === "type") {
287
+ importedWebTypeNames.add(specifier.local.name);
288
+ }
289
+ });
290
+ },
291
+ ExportNamedDeclaration(node) {
292
+ if (node.declaration?.type === AST_NODE_TYPES.FunctionDeclaration) {
293
+ const fn = node.declaration;
294
+ const idNode = fn.id;
295
+ if (!idNode) {
296
+ return;
297
+ }
298
+ const name = idNode.name;
299
+ if (name === "Success") {
300
+ hasSuccessExport = true;
301
+ }
302
+ if (LIFECYCLE_EXPORTS.has(name) || RENDER_PROP_EXPORTS.has(name)) {
303
+ checks.push(() => checkExport(name, fn, idNode));
304
+ }
305
+ return;
306
+ }
307
+ if (node.declaration?.type !== AST_NODE_TYPES.VariableDeclaration) {
308
+ return;
309
+ }
310
+ node.declaration.declarations.forEach((vd) => {
311
+ if (vd.type !== AST_NODE_TYPES.VariableDeclarator || vd.id.type !== AST_NODE_TYPES.Identifier) {
312
+ return;
313
+ }
314
+ const name = vd.id.name;
315
+ if (name === "QUERY") {
316
+ derivedQueryTypes ||= extractTypedDocumentNodeArgs(
317
+ vd.id.typeAnnotation,
318
+ sourceCode
319
+ );
320
+ hasQueryOrFragment = true;
321
+ return;
322
+ }
323
+ if (name === "FRAGMENT") {
324
+ hasQueryOrFragment = true;
325
+ return;
326
+ }
327
+ if (name === "Success") {
328
+ hasSuccessExport = true;
329
+ }
330
+ if ((LIFECYCLE_EXPORTS.has(name) || RENDER_PROP_EXPORTS.has(name)) && (vd.init?.type === AST_NODE_TYPES.ArrowFunctionExpression || vd.init?.type === AST_NODE_TYPES.FunctionExpression)) {
331
+ const fn = vd.init;
332
+ checks.push(() => checkExport(name, fn, vd.id));
333
+ }
334
+ });
335
+ },
336
+ "Program:exit"() {
337
+ const isCellFile = filenameIndicatesCell && hasQueryOrFragment && hasSuccessExport;
338
+ if (!isCellFile) {
339
+ return;
340
+ }
341
+ checks.forEach((check) => check());
342
+ }
343
+ };
344
+ }
345
+ });
346
+ export {
347
+ cellTypeAnnotations
348
+ };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import type { ESLintUtils } from '@typescript-eslint/utils';
2
2
  export declare const meta: {
3
3
  name: string;
4
- version: any;
4
+ version: string;
5
5
  };
6
6
  export declare const rules: {
7
+ 'cell-type-annotations': ESLintUtils.RuleModule<"needsTypeAnnotation" | "beforeQueryParamNeedsType", [], unknown, ESLintUtils.RuleListener>;
7
8
  'process-env-computed': ESLintUtils.RuleModule<"unexpected", [], unknown, ESLintUtils.RuleListener>;
8
9
  'service-type-annotations': ESLintUtils.RuleModule<"needsType", [], unknown, ESLintUtils.RuleListener>;
9
10
  'unsupported-route-components': ESLintUtils.RuleModule<"unexpected", [], unknown, ESLintUtils.RuleListener>;
@@ -11,9 +12,10 @@ export declare const rules: {
11
12
  declare const plugin: {
12
13
  meta: {
13
14
  name: string;
14
- version: any;
15
+ version: string;
15
16
  };
16
17
  rules: {
18
+ 'cell-type-annotations': ESLintUtils.RuleModule<"needsTypeAnnotation" | "beforeQueryParamNeedsType", [], unknown, ESLintUtils.RuleListener>;
17
19
  'process-env-computed': ESLintUtils.RuleModule<"unexpected", [], unknown, ESLintUtils.RuleListener>;
18
20
  'service-type-annotations': ESLintUtils.RuleModule<"needsType", [], unknown, ESLintUtils.RuleListener>;
19
21
  'unsupported-route-components': ESLintUtils.RuleModule<"unexpected", [], unknown, ESLintUtils.RuleListener>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAM3D,eAAO,MAAM,IAAI;;;CAGhB,CAAA;AAED,eAAO,MAAM,KAAK;;;;CAIwC,CAAA;AAE1D,QAAA,MAAM,MAAM;;;;;;;;;;CAAkB,CAAA;AAE9B,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAS3D,eAAO,MAAM,IAAI;;;CAGhB,CAAA;AAED,eAAO,MAAM,KAAK;;;;;CAKwC,CAAA;AAE1D,QAAA,MAAM,MAAM;;;;;;;;;;;CAAkB,CAAA;AAE9B,eAAe,MAAM,CAAA"}
package/dist/index.js CHANGED
@@ -1,44 +1,22 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var src_exports = {};
20
- __export(src_exports, {
21
- default: () => src_default,
22
- meta: () => meta,
23
- rules: () => rules
24
- });
25
- module.exports = __toCommonJS(src_exports);
26
- var import_process_env_computed = require("./process-env-computed.js");
27
- var import_service_type_annotations = require("./service-type-annotations.js");
28
- var import_unsupported_route_components = require("./unsupported-route-components.js");
1
+ import pkgJson from "../package.json" with { type: "json" };
2
+ import { cellTypeAnnotations } from "./cell-type-annotations.js";
3
+ import { processEnvComputedRule } from "./process-env-computed.js";
4
+ import { serviceTypeAnnotations } from "./service-type-annotations.js";
5
+ import { unsupportedRouteComponents } from "./unsupported-route-components.js";
29
6
  const meta = {
30
7
  name: "@cedarjs/eslint-plugin",
31
- version: require("../package.json").version
8
+ version: pkgJson.version
32
9
  };
33
10
  const rules = {
34
- "process-env-computed": import_process_env_computed.processEnvComputedRule,
35
- "service-type-annotations": import_service_type_annotations.serviceTypeAnnotations,
36
- "unsupported-route-components": import_unsupported_route_components.unsupportedRouteComponents
11
+ "cell-type-annotations": cellTypeAnnotations,
12
+ "process-env-computed": processEnvComputedRule,
13
+ "service-type-annotations": serviceTypeAnnotations,
14
+ "unsupported-route-components": unsupportedRouteComponents
37
15
  };
38
16
  const plugin = { meta, rules };
39
- var src_default = plugin;
40
- // Annotate the CommonJS export names for ESM import in node:
41
- 0 && (module.exports = {
17
+ var index_default = plugin;
18
+ export {
19
+ index_default as default,
42
20
  meta,
43
21
  rules
44
- });
22
+ };
@@ -1,33 +1,10 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var process_env_computed_exports = {};
20
- __export(process_env_computed_exports, {
21
- processEnvComputedRule: () => processEnvComputedRule
22
- });
23
- module.exports = __toCommonJS(process_env_computed_exports);
24
- var import_utils = require("@typescript-eslint/utils");
25
- const createRule = import_utils.ESLintUtils.RuleCreator.withoutDocs;
1
+ import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
2
+ const createRule = ESLintUtils.RuleCreator.withoutDocs;
26
3
  function isProcessEnv(node) {
27
- return node.type === import_utils.AST_NODE_TYPES.MemberExpression && hasName(node.object, "process") && hasName(node.property, "env");
4
+ return node.type === AST_NODE_TYPES.MemberExpression && hasName(node.object, "process") && hasName(node.property, "env");
28
5
  }
29
6
  function hasName(node, name) {
30
- return node.type === import_utils.AST_NODE_TYPES.Identifier && node.name === name;
7
+ return node.type === AST_NODE_TYPES.Identifier && node.name === name;
31
8
  }
32
9
  function isTestFile(filename) {
33
10
  return filename.endsWith(".test.ts") || filename.endsWith(".test.js") || filename.endsWith(".test.tsx") || filename.endsWith(".test.jsx") || filename.endsWith(".test.mts") || filename.endsWith(".test.mjs") || filename.endsWith(".test.cjs") || filename.endsWith(".spec.ts") || filename.endsWith(".spec.js") || filename.endsWith(".spec.tsx") || filename.endsWith(".spec.jsx") || filename.endsWith(".spec.mts") || filename.endsWith(".spec.mjs") || filename.endsWith(".spec.cjs") || filename.includes("/__tests__/");
@@ -59,7 +36,6 @@ const processEnvComputedRule = createRule({
59
36
  };
60
37
  }
61
38
  });
62
- // Annotate the CommonJS export names for ESM import in node:
63
- 0 && (module.exports = {
39
+ export {
64
40
  processEnvComputedRule
65
- });
41
+ };
@@ -1,29 +1,6 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var service_type_annotations_exports = {};
20
- __export(service_type_annotations_exports, {
21
- serviceTypeAnnotations: () => serviceTypeAnnotations
22
- });
23
- module.exports = __toCommonJS(service_type_annotations_exports);
24
- var import_node_path = require("node:path");
25
- var import_utils = require("@typescript-eslint/utils");
26
- const createRule = import_utils.ESLintUtils.RuleCreator.withoutDocs;
1
+ import { basename } from "node:path";
2
+ import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
3
+ const createRule = ESLintUtils.RuleCreator.withoutDocs;
27
4
  const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
28
5
  const serviceTypeAnnotations = createRule({
29
6
  meta: {
@@ -39,7 +16,7 @@ const serviceTypeAnnotations = createRule({
39
16
  },
40
17
  defaultOptions: [],
41
18
  create(context) {
42
- const thisFilename = (0, import_node_path.basename)(context.filename);
19
+ const thisFilename = basename(context.filename);
43
20
  const sansTS = thisFilename.replace(".ts", "");
44
21
  const thisFileCorrespondingImport = `types/${sansTS}`;
45
22
  let importForThisFile = null;
@@ -51,18 +28,18 @@ const serviceTypeAnnotations = createRule({
51
28
  },
52
29
  // Then start looking at every exported fn/const
53
30
  ExportNamedDeclaration(node) {
54
- if (node.declaration?.type !== import_utils.AST_NODE_TYPES.VariableDeclaration) {
31
+ if (node.declaration?.type !== AST_NODE_TYPES.VariableDeclaration) {
55
32
  return;
56
33
  }
57
34
  node.declaration.declarations.forEach((vd) => {
58
- if (vd.type === import_utils.AST_NODE_TYPES.VariableDeclarator && vd.id.type === import_utils.AST_NODE_TYPES.Identifier) {
35
+ if (vd.type === AST_NODE_TYPES.VariableDeclarator && vd.id.type === AST_NODE_TYPES.Identifier) {
59
36
  if (vd.id.name.startsWith("_")) {
60
37
  return;
61
38
  }
62
39
  const isGlobalOrMutationResolver = /^[a-z]/.test(vd.id.name);
63
40
  const suffix = isGlobalOrMutationResolver ? "Resolver" : "TypeResolvers";
64
41
  const typeName = capitalizeFirstLetter(vd.id.name) + suffix;
65
- if (isGlobalOrMutationResolver && vd.init?.type !== import_utils.AST_NODE_TYPES.ArrowFunctionExpression) {
42
+ if (isGlobalOrMutationResolver && vd.init?.type !== AST_NODE_TYPES.ArrowFunctionExpression) {
66
43
  return;
67
44
  }
68
45
  const tsID = vd.id;
@@ -98,7 +75,7 @@ const serviceTypeAnnotations = createRule({
98
75
  if (!("typeName" in type)) {
99
76
  return;
100
77
  }
101
- const isCorrectType = type.typeName?.type === import_utils.AST_NODE_TYPES.Identifier && type.typeName?.name === typeName;
78
+ const isCorrectType = type.typeName?.type === AST_NODE_TYPES.Identifier && type.typeName?.name === typeName;
102
79
  if (isCorrectType) {
103
80
  return;
104
81
  }
@@ -134,7 +111,6 @@ const serviceTypeAnnotations = createRule({
134
111
  };
135
112
  }
136
113
  });
137
- // Annotate the CommonJS export names for ESM import in node:
138
- 0 && (module.exports = {
114
+ export {
139
115
  serviceTypeAnnotations
140
- });
116
+ };
@@ -1,35 +1,12 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var unsupported_route_components_exports = {};
20
- __export(unsupported_route_components_exports, {
21
- unsupportedRouteComponents: () => unsupportedRouteComponents
22
- });
23
- module.exports = __toCommonJS(unsupported_route_components_exports);
24
- var import_utils = require("@typescript-eslint/utils");
25
- const createRule = import_utils.ESLintUtils.RuleCreator.withoutDocs;
1
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
2
+ const createRule = ESLintUtils.RuleCreator.withoutDocs;
26
3
  function isAllowedElement(name) {
27
4
  const allowedElements = ["Router", "Route", "Set", "PrivateSet", "Private"];
28
5
  return allowedElements.includes(name);
29
6
  }
30
7
  function checkNodes(nodesToCheck, context) {
31
- if (nodesToCheck.type === import_utils.AST_NODE_TYPES.JSXElement) {
32
- const name = nodesToCheck.openingElement.name.type === import_utils.AST_NODE_TYPES.JSXIdentifier ? nodesToCheck.openingElement.name.name : null;
8
+ if (nodesToCheck.type === AST_NODE_TYPES.JSXElement) {
9
+ const name = nodesToCheck.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier ? nodesToCheck.openingElement.name.name : null;
33
10
  if (name && !isAllowedElement(name)) {
34
11
  context.report({
35
12
  node: nodesToCheck,
@@ -59,11 +36,11 @@ const unsupportedRouteComponents = createRule({
59
36
  VariableDeclaration(node) {
60
37
  if (isRoutesRenderBlock(node.declarations[0])) {
61
38
  const routesDeclaration = node.declarations[0].init;
62
- if (routesDeclaration?.type === import_utils.AST_NODE_TYPES.ArrowFunctionExpression) {
63
- if (routesDeclaration.body.type === import_utils.AST_NODE_TYPES.JSXElement) {
39
+ if (routesDeclaration?.type === AST_NODE_TYPES.ArrowFunctionExpression) {
40
+ if (routesDeclaration.body.type === AST_NODE_TYPES.JSXElement) {
64
41
  checkNodes(routesDeclaration.body, context);
65
- } else if (routesDeclaration.body.type === import_utils.AST_NODE_TYPES.BlockStatement) {
66
- if (routesDeclaration.body.body[0].type === import_utils.AST_NODE_TYPES.ReturnStatement && routesDeclaration.body.body[0].argument?.type === import_utils.AST_NODE_TYPES.JSXElement) {
42
+ } else if (routesDeclaration.body.type === AST_NODE_TYPES.BlockStatement) {
43
+ if (routesDeclaration.body.body[0].type === AST_NODE_TYPES.ReturnStatement && routesDeclaration.body.body[0].argument?.type === AST_NODE_TYPES.JSXElement) {
67
44
  const routesReturnStatement = routesDeclaration.body.body[0].argument;
68
45
  checkNodes(routesReturnStatement, context);
69
46
  }
@@ -75,9 +52,8 @@ const unsupportedRouteComponents = createRule({
75
52
  }
76
53
  });
77
54
  function isRoutesRenderBlock(node) {
78
- return node?.type === import_utils.AST_NODE_TYPES.VariableDeclarator && node?.id.type === import_utils.AST_NODE_TYPES.Identifier && node?.id.name === "Routes";
55
+ return node?.type === AST_NODE_TYPES.VariableDeclarator && node?.id.type === AST_NODE_TYPES.Identifier && node?.id.name === "Routes";
79
56
  }
80
- // Annotate the CommonJS export names for ESM import in node:
81
- 0 && (module.exports = {
57
+ export {
82
58
  unsupportedRouteComponents
83
- });
59
+ };
package/package.json CHANGED
@@ -1,42 +1,45 @@
1
1
  {
2
2
  "name": "@cedarjs/eslint-plugin",
3
- "version": "9.0.0-canary.1784+baa47810a",
3
+ "version": "9.0.0-canary.3124",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/cedarjs/cedar.git",
7
7
  "directory": "packages/eslint-plugin"
8
8
  },
9
9
  "license": "MIT",
10
+ "type": "module",
10
11
  "main": "./dist/index.js",
11
12
  "types": "./dist/index.d.ts",
12
13
  "files": [
13
14
  "dist"
14
15
  ],
15
16
  "scripts": {
16
- "build": "tsx ./build.mts && yarn build:types",
17
+ "build": "node ./build.mts",
17
18
  "build:pack": "yarn pack -o cedarjs-eslint-plugin.tgz",
18
- "build:types": "tsc --build --verbose",
19
+ "build:types": "tsc --build --verbose ./tsconfig.build.json",
19
20
  "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"",
20
21
  "prepublishOnly": "NODE_ENV=production yarn build",
21
22
  "test": "vitest run",
22
23
  "test:watch": "vitest watch"
23
24
  },
24
25
  "dependencies": {
25
- "@typescript-eslint/utils": "8.54.0",
26
+ "@typescript-eslint/utils": "8.69.0",
26
27
  "eslint": "8.57.1"
27
28
  },
28
29
  "devDependencies": {
29
- "@cedarjs/framework-tools": "9.0.0-canary.1784",
30
+ "@cedarjs/framework-tools": "9.0.0-canary.3124",
30
31
  "@types/eslint": "8.56.12",
31
- "@types/estree": "1.0.8",
32
- "@typescript-eslint/parser": "8.54.0",
33
- "@typescript-eslint/rule-tester": "8.54.0",
34
- "tsx": "4.21.0",
32
+ "@types/estree": "1.0.9",
33
+ "@typescript-eslint/parser": "8.69.0",
34
+ "@typescript-eslint/rule-tester": "8.69.0",
35
35
  "typescript": "5.9.3",
36
- "vitest": "3.2.4"
36
+ "vitest": "4.1.11"
37
+ },
38
+ "engines": {
39
+ "node": ">=24"
37
40
  },
38
41
  "publishConfig": {
39
42
  "access": "public"
40
43
  },
41
- "gitHead": "baa47810a7defb73de27fdf513b815d679509b5e"
44
+ "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1"
42
45
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Cedar
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.