eslint-plugin-import-template 1.0.0

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 ADDED
@@ -0,0 +1,22 @@
1
+ # eslint-plugin-import-template
2
+
3
+ An eslint plugin that checks the existence of static resources in the template, for example, checks whether the static resource files introduced in the sfc module exist.
4
+
5
+ This plugin currently only supports static resource checking of the vue-sfc template.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install eslint-plugin-import-template --save-dev
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```js
16
+ module.exports = {
17
+ plugins: ['import-template'],
18
+ rules: {
19
+ 'import-template/vue-template-no-unresolved': 'error',
20
+ },
21
+ };
22
+ ```
@@ -0,0 +1,8 @@
1
+ import { Rule } from "eslint";
2
+
3
+ //#region src/index.d.ts
4
+ declare const plugin: {
5
+ rules: Record<string, Rule.RuleModule>;
6
+ };
7
+ //#endregion
8
+ export { plugin as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,117 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ //#region src/index.ts
5
+ function isUrlOrData(v) {
6
+ return /^(https?:|data:|\/\/)/.test(v);
7
+ }
8
+ const plugin = { rules: { "vue-template-no-unresolved": {
9
+ meta: {
10
+ type: "problem",
11
+ docs: {
12
+ description: "检查 Vue 模板中静态 `src`/`href` 引用的文件是否存在",
13
+ category: "Possible Errors"
14
+ },
15
+ schema: [{
16
+ type: "object",
17
+ properties: {
18
+ aliases: {
19
+ type: "object",
20
+ additionalProperties: { type: "string" }
21
+ },
22
+ extensions: {
23
+ type: "array",
24
+ items: { type: "string" }
25
+ }
26
+ },
27
+ additionalProperties: false
28
+ }]
29
+ },
30
+ create(context) {
31
+ const options = context.options && context.options[0] || {};
32
+ const aliases = options.aliases || { "@/": "./src/" };
33
+ const extensions = options.extensions || [
34
+ ".png",
35
+ ".webp",
36
+ ".jpg",
37
+ ".jpeg",
38
+ ".svg",
39
+ ".gif",
40
+ ".ico"
41
+ ];
42
+ function resolveWithAliases(raw, filename) {
43
+ if (isUrlOrData(raw)) return null;
44
+ for (const a of Object.keys(aliases)) if (raw.startsWith(a)) {
45
+ const target = aliases[a];
46
+ return path.resolve(process.cwd(), target, raw.slice(a.length));
47
+ }
48
+ if (raw.startsWith(".")) {
49
+ if (!filename || filename === "<input>") return null;
50
+ return path.resolve(path.dirname(filename), raw);
51
+ }
52
+ if (raw.startsWith("/")) return path.resolve(process.cwd(), `.${raw}`);
53
+ return null;
54
+ }
55
+ function checkRaw(raw, nodeForReport) {
56
+ if (!raw || typeof raw !== "string") return;
57
+ const resolved = resolveWithAliases(raw, context.getFilename());
58
+ if (!resolved) return;
59
+ if (path.extname(resolved)) {
60
+ if (!fs.existsSync(resolved)) context.report({
61
+ node: nodeForReport,
62
+ message: `Asset not found: ${raw}`
63
+ });
64
+ } else {
65
+ let found = false;
66
+ for (const e of extensions) if (fs.existsSync(resolved + e)) {
67
+ found = true;
68
+ break;
69
+ }
70
+ if (!found) context.report({
71
+ node: nodeForReport,
72
+ message: `Asset not found (tried ${extensions.join(", ")}): ${raw}`
73
+ });
74
+ }
75
+ }
76
+ function traverseTemplateBody(templateBody) {
77
+ if (!templateBody || !templateBody.children) return;
78
+ const stack = [...templateBody.children];
79
+ while (stack.length) {
80
+ const n = stack.shift();
81
+ if (!n) continue;
82
+ if (n.type === "VElement" && n.startTag && Array.isArray(n.startTag.attributes)) for (const attr of n.startTag.attributes) {
83
+ if (!attr) continue;
84
+ if (attr.type === "VAttribute") {
85
+ const name = attr.key && attr.key.name;
86
+ if (name === "src" || name === "href") {
87
+ if (attr.value && attr.value.type === "VLiteral") checkRaw(attr.value.value, attr);
88
+ }
89
+ }
90
+ }
91
+ if (n.children && n.children.length) stack.push(...n.children);
92
+ }
93
+ }
94
+ return {
95
+ VAttribute(node) {
96
+ const key = node.key && (node.key.name || node.key.argument && node.key.argument.name);
97
+ if (!key) return;
98
+ if (key !== "src" && key !== "href") return;
99
+ if (!node.value || node.value.type !== "VLiteral") return;
100
+ const raw = node.value.value;
101
+ checkRaw(raw, node);
102
+ },
103
+ "Program:exit"() {
104
+ try {
105
+ const ast = context.getSourceCode().ast;
106
+ if (ast && ast.templateBody) traverseTemplateBody(ast.templateBody);
107
+ } catch (err) {
108
+ console.error("local/check-vue-asset-exists error:", err && err.message);
109
+ }
110
+ }
111
+ };
112
+ }
113
+ } } };
114
+ var src_default = plugin;
115
+
116
+ //#endregion
117
+ export { src_default as default };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "eslint-plugin-import-template",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "description": "A starter for creating a TypeScript package.",
6
+ "author": "TRIS-H <2218975525@qq.com>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/TRIS-H/eslint-plugin-import-template#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/TRIS-H/eslint-plugin-import-template/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/TRIS-H/eslint-plugin-import-template"
15
+ },
16
+ "keywords": [
17
+ "eslint",
18
+ "eslintplugin",
19
+ "eslint-plugin",
20
+ "es6",
21
+ "jsnext",
22
+ "modules",
23
+ "assets",
24
+ "import",
25
+ "export"
26
+ ],
27
+ "exports": {
28
+ ".": "./dist/index.mjs",
29
+ "./package.json": "./package.json"
30
+ },
31
+ "main": "./dist/index.mjs",
32
+ "module": "./dist/index.mjs",
33
+ "types": "./dist/index.d.mts",
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsdown",
39
+ "dev": "tsdown --watch",
40
+ "test": "vitest",
41
+ "typecheck": "tsc --noEmit",
42
+ "prepublishOnly": "pnpm run build"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^25.0.3",
46
+ "bumpp": "^10.3.2",
47
+ "tsdown": "^0.18.1",
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.0.16"
50
+ },
51
+ "peerDependencies": {
52
+ "vue-eslint-parser": "^10.1.4"
53
+ }
54
+ }