@akanjs/lint 0.0.39 → 0.0.40
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/index.d.ts +12 -0
- package/index.js +34 -351
- package/package.json +2 -4
package/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as _typescript_eslint_utils_dist_ts_eslint from '@typescript-eslint/utils/dist/ts-eslint';
|
|
2
|
+
|
|
3
|
+
declare const _default: {
|
|
4
|
+
rules: {
|
|
5
|
+
noImportExternalLibrary: _typescript_eslint_utils_dist_ts_eslint.RuleModule<"noImportExternalLibrary", [], unknown, _typescript_eslint_utils_dist_ts_eslint.RuleListener>;
|
|
6
|
+
noImportClientFunctions: _typescript_eslint_utils_dist_ts_eslint.RuleModule<"noImportClientFunctions", [], unknown, _typescript_eslint_utils_dist_ts_eslint.RuleListener>;
|
|
7
|
+
nonScalarPropsRestricted: _typescript_eslint_utils_dist_ts_eslint.RuleModule<"nonScalarPropsRestricted", [], unknown, _typescript_eslint_utils_dist_ts_eslint.RuleListener>;
|
|
8
|
+
useClientByFile: _typescript_eslint_utils_dist_ts_eslint.RuleModule<"noUseClient" | "forceUseClient", [], unknown, _typescript_eslint_utils_dist_ts_eslint.RuleListener>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { _default as default };
|
package/index.js
CHANGED
|
@@ -1,351 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// pkgs/@akanjs/lint/util/fileIsServerFile.ts
|
|
36
|
-
var serverFileNameSet = /* @__PURE__ */ new Set();
|
|
37
|
-
var clientFileNameSet = /* @__PURE__ */ new Set(["st.ts", "store.ts"]);
|
|
38
|
-
var serverFileSuffixSet = /* @__PURE__ */ new Set(["page.tsx", "layout.tsx", "Unit.tsx", "View.tsx"]);
|
|
39
|
-
var clientFileSuffixSet = /* @__PURE__ */ new Set(["Zone.tsx", "Util.tsx", "Template.tsx"]);
|
|
40
|
-
var fileIsServerFile = (absFilePath, sourceCode) => {
|
|
41
|
-
if (absFilePath.includes("eslint-rules"))
|
|
42
|
-
return true;
|
|
43
|
-
const filePaths = absFilePath.split("/");
|
|
44
|
-
const filename = filePaths.at(-1) ?? "";
|
|
45
|
-
const fileLastName = absFilePath.split(".").slice(-2).join(".");
|
|
46
|
-
if (filename === "page.tsx") {
|
|
47
|
-
if (filePaths.includes("admin"))
|
|
48
|
-
return false;
|
|
49
|
-
else
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
if (filename === "layout.tsx") {
|
|
53
|
-
if (filePaths.at(-2) === "app")
|
|
54
|
-
return false;
|
|
55
|
-
else
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
if (serverFileNameSet.has(filename))
|
|
59
|
-
return true;
|
|
60
|
-
if (clientFileNameSet.has(filename))
|
|
61
|
-
return false;
|
|
62
|
-
if (serverFileSuffixSet.has(fileLastName))
|
|
63
|
-
return true;
|
|
64
|
-
if (clientFileSuffixSet.has(fileLastName))
|
|
65
|
-
return false;
|
|
66
|
-
if (new RegExp(/useEffect|useState|useContext|st\.do\.|st\.use\./g).test(sourceCode))
|
|
67
|
-
return false;
|
|
68
|
-
return null;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// pkgs/@akanjs/lint/util/fileHasUseClient.ts
|
|
72
|
-
var fileHasUseClient = (context) => {
|
|
73
|
-
const firstLineIdx = context.sourceCode.lines.findIndex((line) => line.trim() !== "");
|
|
74
|
-
return { hasUseClient: context.sourceCode.lines[firstLineIdx].includes('"use client"'), firstLineIdx };
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// pkgs/@akanjs/lint/util/fileHasContent.ts
|
|
78
|
-
var fileHasContent = (context, node) => {
|
|
79
|
-
const firstToken = context.sourceCode.getFirstToken(node);
|
|
80
|
-
return !!firstToken;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// pkgs/@akanjs/lint/util/fileHasClientFunction.ts
|
|
84
|
-
var reactClientFunctionSet = /* @__PURE__ */ new Set([
|
|
85
|
-
"useState",
|
|
86
|
-
"useEffect",
|
|
87
|
-
"useContext",
|
|
88
|
-
"useReducer",
|
|
89
|
-
"useCallback",
|
|
90
|
-
"useMemo",
|
|
91
|
-
"useRef",
|
|
92
|
-
"useImperativeHandle",
|
|
93
|
-
"useLayoutEffect",
|
|
94
|
-
"useDebugValue"
|
|
95
|
-
]);
|
|
96
|
-
var frameworkClientFunctionSet = /* @__PURE__ */ new Set(["st"]);
|
|
97
|
-
var fileHasClientFunction = (node) => {
|
|
98
|
-
if (node.source.value === "react")
|
|
99
|
-
return node.specifiers.some((specifier) => reactClientFunctionSet.has(specifier.local.name));
|
|
100
|
-
else if (node.specifiers.some((specifier) => frameworkClientFunctionSet.has(specifier.local.name)))
|
|
101
|
-
return true;
|
|
102
|
-
else
|
|
103
|
-
return false;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// pkgs/@akanjs/lint/util/getFilename.ts
|
|
107
|
-
var getFilename = (absFilePath) => {
|
|
108
|
-
const filePaths = absFilePath.split("/");
|
|
109
|
-
return filePaths.at(-1) ?? "";
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// pkgs/@akanjs/lint/util/fileIsPureImportFile.ts
|
|
113
|
-
var fileSuffixSet = /* @__PURE__ */ new Set([
|
|
114
|
-
"page.tsx",
|
|
115
|
-
"layout.tsx",
|
|
116
|
-
"index.ts",
|
|
117
|
-
"cnst_.ts",
|
|
118
|
-
"cnst.ts",
|
|
119
|
-
"db.ts",
|
|
120
|
-
"dict.ts",
|
|
121
|
-
"fetch.ts",
|
|
122
|
-
"option.ts",
|
|
123
|
-
"sig.ts",
|
|
124
|
-
"srv.ts",
|
|
125
|
-
"st.ts",
|
|
126
|
-
"usePage.ts",
|
|
127
|
-
"_server.ts",
|
|
128
|
-
"constant.ts",
|
|
129
|
-
"dictionary.ts",
|
|
130
|
-
"document.ts",
|
|
131
|
-
"service.ts",
|
|
132
|
-
"signal.ts",
|
|
133
|
-
"spec.ts",
|
|
134
|
-
"test.ts",
|
|
135
|
-
"store.ts",
|
|
136
|
-
"Template.tsx",
|
|
137
|
-
"Unit.tsx",
|
|
138
|
-
"Util.tsx",
|
|
139
|
-
"View.tsx",
|
|
140
|
-
"Zone.tsx",
|
|
141
|
-
"index.tsx"
|
|
142
|
-
]);
|
|
143
|
-
var fileIsPureImportFile = (filename) => {
|
|
144
|
-
const suffixFilename = filename.split("/").at(-1)?.split(".").slice(-2).join(".") ?? "";
|
|
145
|
-
if (fileSuffixSet.has(suffixFilename))
|
|
146
|
-
return true;
|
|
147
|
-
else
|
|
148
|
-
return false;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// pkgs/@akanjs/lint/util/isInternalImport.ts
|
|
152
|
-
var fs = __toESM(__require("fs"));
|
|
153
|
-
var projectRoot = process.cwd();
|
|
154
|
-
var libNames = [...fs.readdirSync(`${projectRoot}/libs`), ...fs.readdirSync(`${projectRoot}/pkgs`)];
|
|
155
|
-
var internalImportSet = /* @__PURE__ */ new Set([
|
|
156
|
-
...libNames.map((libName) => `@${libName}`),
|
|
157
|
-
"react-icons",
|
|
158
|
-
"react",
|
|
159
|
-
"next",
|
|
160
|
-
"@radix-ui",
|
|
161
|
-
"@playwright",
|
|
162
|
-
"@akanjs",
|
|
163
|
-
".",
|
|
164
|
-
".."
|
|
165
|
-
]);
|
|
166
|
-
var isInternalImport = (importPaths, appName) => {
|
|
167
|
-
if (internalImportSet.has(importPaths[0]))
|
|
168
|
-
return true;
|
|
169
|
-
else if (importPaths[0] === appName)
|
|
170
|
-
return true;
|
|
171
|
-
else
|
|
172
|
-
return false;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// pkgs/@akanjs/lint/util/getAppName.ts
|
|
176
|
-
var getAppName = (filePaths) => {
|
|
177
|
-
const appsIdx = filePaths.findIndex((part) => part === "apps");
|
|
178
|
-
const appName = appsIdx === -1 ? null : filePaths[appsIdx + 1];
|
|
179
|
-
return appName;
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// pkgs/@akanjs/lint/rules/noImportClientFunctions.ts
|
|
183
|
-
var noImportClientFunctions = import_utils.ESLintUtils.RuleCreator(() => __filename)({
|
|
184
|
-
name: "noImportClientFunctions",
|
|
185
|
-
meta: {
|
|
186
|
-
type: "problem",
|
|
187
|
-
docs: {
|
|
188
|
-
description: "Enforce that client functions are not imported."
|
|
189
|
-
},
|
|
190
|
-
messages: {
|
|
191
|
-
noImportClientFunctions: "Error: Client functions should not be imported."
|
|
192
|
-
},
|
|
193
|
-
// fixable: "code",
|
|
194
|
-
schema: []
|
|
195
|
-
},
|
|
196
|
-
defaultOptions: [],
|
|
197
|
-
create(context) {
|
|
198
|
-
const isServerFile = fileIsServerFile(context.filename, context.sourceCode.text);
|
|
199
|
-
if (!isServerFile)
|
|
200
|
-
return {};
|
|
201
|
-
return {
|
|
202
|
-
ImportDeclaration(node) {
|
|
203
|
-
const hasClientFunction = fileHasClientFunction(node);
|
|
204
|
-
if (hasClientFunction)
|
|
205
|
-
context.report({
|
|
206
|
-
node,
|
|
207
|
-
messageId: "noImportClientFunctions"
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// pkgs/@akanjs/lint/rules/noImportExternalLibrary.ts
|
|
215
|
-
var import_utils2 = __require("@typescript-eslint/utils");
|
|
216
|
-
var noImportExternalLibrary = import_utils2.ESLintUtils.RuleCreator(() => __filename)({
|
|
217
|
-
name: "noImportExternalLibrary",
|
|
218
|
-
meta: {
|
|
219
|
-
type: "problem",
|
|
220
|
-
docs: {
|
|
221
|
-
description: "Enforce that external libraries are not imported."
|
|
222
|
-
},
|
|
223
|
-
messages: {
|
|
224
|
-
noImportExternalLibrary: "Error: External libraries should not be imported."
|
|
225
|
-
},
|
|
226
|
-
// fixable: "code",
|
|
227
|
-
schema: []
|
|
228
|
-
},
|
|
229
|
-
defaultOptions: [],
|
|
230
|
-
create(context) {
|
|
231
|
-
const isPureImportFile = fileIsPureImportFile(context.filename);
|
|
232
|
-
if (!isPureImportFile)
|
|
233
|
-
return {};
|
|
234
|
-
const filePaths = context.filename.split("/");
|
|
235
|
-
const appName = getAppName(filePaths);
|
|
236
|
-
const appPath = appName ? `@${appName}` : null;
|
|
237
|
-
return {
|
|
238
|
-
ImportDeclaration(node) {
|
|
239
|
-
const importPaths = node.source.value.split("/");
|
|
240
|
-
if (!isInternalImport(importPaths, appPath))
|
|
241
|
-
context.report({
|
|
242
|
-
node,
|
|
243
|
-
messageId: "noImportExternalLibrary"
|
|
244
|
-
// fix(fixer) {
|
|
245
|
-
// return fixer.remove(node);
|
|
246
|
-
// },
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// pkgs/@akanjs/lint/rules/nonScalarPropsRestricted.ts
|
|
254
|
-
var import_utils3 = __require("@typescript-eslint/utils");
|
|
255
|
-
var allowedPropKeySet = /* @__PURE__ */ new Set(["loader", "render", "of"]);
|
|
256
|
-
var nonScalarPropsRestricted = import_utils3.ESLintUtils.RuleCreator(() => __filename)({
|
|
257
|
-
name: "nonScalarPropsRestricted",
|
|
258
|
-
meta: {
|
|
259
|
-
type: "problem",
|
|
260
|
-
docs: {
|
|
261
|
-
description: "Enforce that non-scalar props are not used."
|
|
262
|
-
},
|
|
263
|
-
messages: {
|
|
264
|
-
nonScalarPropsRestricted: "Error: Non-scalar props should not be used."
|
|
265
|
-
},
|
|
266
|
-
// fixable: "code",
|
|
267
|
-
schema: []
|
|
268
|
-
},
|
|
269
|
-
defaultOptions: [],
|
|
270
|
-
create(context) {
|
|
271
|
-
const filename = getFilename(context.filename);
|
|
272
|
-
const isServerFile = fileIsServerFile(context.filename, context.sourceCode.text);
|
|
273
|
-
if (!isServerFile || !["page.tsx", "layout.tsx"].includes(filename))
|
|
274
|
-
return {};
|
|
275
|
-
return {
|
|
276
|
-
JSXAttribute(node) {
|
|
277
|
-
if (node.value?.expression) {
|
|
278
|
-
const { expression, parent } = node.value;
|
|
279
|
-
if (expression.type === "ArrowFunctionExpression" || expression.type === "FunctionExpression") {
|
|
280
|
-
if (!allowedPropKeySet.has(parent.name.name))
|
|
281
|
-
context.report({
|
|
282
|
-
node,
|
|
283
|
-
messageId: "nonScalarPropsRestricted"
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
// pkgs/@akanjs/lint/rules/useClientByFile.ts
|
|
293
|
-
var import_utils4 = __require("@typescript-eslint/utils");
|
|
294
|
-
var useClientByFile = import_utils4.ESLintUtils.RuleCreator(() => __filename)({
|
|
295
|
-
name: "useClientByFile",
|
|
296
|
-
meta: {
|
|
297
|
-
type: "problem",
|
|
298
|
-
docs: {
|
|
299
|
-
description: "Enforce that `use client` is not used in `server` files."
|
|
300
|
-
},
|
|
301
|
-
messages: {
|
|
302
|
-
noUseClient: 'Error: "use client" should not be used at the top of a `server` file.',
|
|
303
|
-
forceUseClient: 'Error: "use client" should be used at the top of a `client` file.'
|
|
304
|
-
},
|
|
305
|
-
// fixable: "code",
|
|
306
|
-
schema: []
|
|
307
|
-
},
|
|
308
|
-
defaultOptions: [],
|
|
309
|
-
create(context) {
|
|
310
|
-
const isServerFile = fileIsServerFile(context.filename, context.sourceCode.text);
|
|
311
|
-
if (isServerFile === null)
|
|
312
|
-
return {};
|
|
313
|
-
if (isServerFile)
|
|
314
|
-
return {
|
|
315
|
-
Program(node) {
|
|
316
|
-
if (!fileHasContent(context, node))
|
|
317
|
-
return;
|
|
318
|
-
const { hasUseClient, firstLineIdx } = fileHasUseClient(context);
|
|
319
|
-
if (hasUseClient)
|
|
320
|
-
context.report({
|
|
321
|
-
node: node.body[firstLineIdx],
|
|
322
|
-
messageId: "noUseClient"
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
else
|
|
327
|
-
return {
|
|
328
|
-
Program(node) {
|
|
329
|
-
if (!fileHasContent(context, node))
|
|
330
|
-
return;
|
|
331
|
-
const { hasUseClient, firstLineIdx } = fileHasUseClient(context);
|
|
332
|
-
if (!hasUseClient)
|
|
333
|
-
context.report({
|
|
334
|
-
node: node.body[firstLineIdx],
|
|
335
|
-
messageId: "forceUseClient"
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
// pkgs/@akanjs/lint/index.ts
|
|
343
|
-
var lint_default = {
|
|
344
|
-
rules: {
|
|
345
|
-
noImportExternalLibrary,
|
|
346
|
-
noImportClientFunctions,
|
|
347
|
-
nonScalarPropsRestricted,
|
|
348
|
-
useClientByFile
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
})();
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var index_exports = {};
|
|
19
|
+
__export(index_exports, {
|
|
20
|
+
default: () => index_default
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(index_exports);
|
|
23
|
+
var import_noImportClientFunctions = require("./rules/noImportClientFunctions");
|
|
24
|
+
var import_noImportExternalLibrary = require("./rules/noImportExternalLibrary");
|
|
25
|
+
var import_nonScalarPropsRestricted = require("./rules/nonScalarPropsRestricted");
|
|
26
|
+
var import_useClientByFile = require("./rules/useClientByFile");
|
|
27
|
+
var index_default = {
|
|
28
|
+
rules: {
|
|
29
|
+
noImportExternalLibrary: import_noImportExternalLibrary.noImportExternalLibrary,
|
|
30
|
+
noImportClientFunctions: import_noImportClientFunctions.noImportClientFunctions,
|
|
31
|
+
nonScalarPropsRestricted: import_nonScalarPropsRestricted.nonScalarPropsRestricted,
|
|
32
|
+
useClientByFile: import_useClientByFile.useClientByFile
|
|
33
|
+
}
|
|
34
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/lint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.40",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -14,7 +14,5 @@
|
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": ">=22"
|
|
16
16
|
},
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"@typescript-eslint/utils": "^8.29.1"
|
|
19
|
-
}
|
|
17
|
+
"dependencies": {}
|
|
20
18
|
}
|