eslint-plugin-qwik 1.3.1 → 1.3.3
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.js +10 -2
- package/package.json +5 -5
package/index.js
CHANGED
|
@@ -152,7 +152,15 @@ export const ColorList = component$(() => {
|
|
|
152
152
|
);
|
|
153
153
|
});`.trim();var al=require("@typescript-eslint/utils");var{getStaticValue:uv}=al.ASTUtils,lv=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i,sl={meta:{type:"problem",docs:{recommended:"error",description:"Disallow javascript: URLs.",url:"https://qwik.builder.io/docs/advanced/eslint/#jsx-no-script-url"},schema:[],messages:{noJSURL:"For security, don't use javascript: URLs. Use event handlers instead if you can."}},create(r){return{JSXAttribute(e){if(e.name.type==="JSXIdentifier"&&e.value){let t=uv(e.value.type==="JSXExpressionContainer"?e.value.expression:e.value,r.getScope());t&&typeof t.value=="string"&&lv.test(t.value)&&r.report({node:e.value,messageId:"noJSURL"})}}}}},yx=`
|
|
154
154
|
<button onClick$={() => alert('open the door please')>ring</button>`.trim(),mx=`
|
|
155
|
-
<button onClick$="javascript:alert('open the door please')">ring</button>`.trim();var ul={loader$:!0,routeLoader$:!0,routeAction$:!0,routeHandler$:!0},pv={...ul,action$:!0,globalAction$:!0},ll={meta:{type:"problem",docs:{description:"Detect declaration location of loader$.",recommended:!0,url:"https://qwik.builder.io/docs/advanced/eslint/#loader-location"},schema:[{type:"object",properties:{routesDir:{type:"string",default:"src/routes"}},additionalProperties:!1}],messages:{invalidLoaderLocation
|
|
155
|
+
<button onClick$="javascript:alert('open the door please')">ring</button>`.trim();var ul={loader$:!0,routeLoader$:!0,routeAction$:!0,routeHandler$:!0},pv={...ul,action$:!0,globalAction$:!0},ll={meta:{type:"problem",docs:{description:"Detect declaration location of loader$.",recommended:!0,url:"https://qwik.builder.io/docs/advanced/eslint/#loader-location"},schema:[{type:"object",properties:{routesDir:{type:"string",default:"src/routes"}},additionalProperties:!1}],messages:{invalidLoaderLocation:`'{{fnName}}() are typically declared in route boundary files such as layout.tsx, index.tsx and plugin.tsx inside the {{routesDir}} directory
|
|
156
|
+
(docs: https://qwik.builder.io/docs/route-loader/).
|
|
157
|
+
|
|
158
|
+
This {{fnName}}() is declared outside of the route boundaries. This may be useful when you want to create reusable logic or a library. In such a case, it is essential that this function is re-exported from within the router boundary otherwise it will not run.
|
|
159
|
+
(docs: https://qwik.builder.io/docs/cookbook/re-exporting-loaders/).
|
|
160
|
+
|
|
161
|
+
If you understand this, you can disable this warning with:
|
|
162
|
+
// eslint-disable-next-line qwik/loader-location
|
|
163
|
+
`,missingExport:"The return of `{{fnName}}()` needs to be exported in the same module, like this\n```\nexport const {{id}} = {{fnName}}(() => { ... });\n```",wrongName:"The named export of `{{fnName}}()` needs to follow the `use*` naming convention. It must start with `use`, like this:\n```\nexport const {{fixed}} = {{fnName}}(() => { ... });\n```\nInstead it was named:\n```\nexport const {{id}} = ...\n```",recommendedValue:"For `{{fnName}}()` it is recommended to inline the arrow function. Instead of:\n```\nexport const {{id}} = {{fnName}}({{arg}});\n```\nDo this:\n```\nexport const {{id}} = {{fnName}}(() => { ...logic here... });\n```\nThis will help the optimizer make sure that no server code is leaked to the client build."}},create(r){var c,y;let e=((y=(c=r.options)==null?void 0:c[0])==null?void 0:y.routesDir)??"src/routes",t=cv(r.getFilename()),n=/\/layout(|!|-.+)\.tsx?$/.test(t),o=/\/index(|!|@.+)\.tsx?$/.test(t),i=/\/plugin(|@.+)\.tsx?$/.test(t),u=new RegExp(`/${e}/`).test(t)&&(o||n||i);return{CallExpression(m){if(m.callee.type!=="Identifier")return;let f=m.callee.name;if(!pv[f])return;if(!u&&ul[f]){r.report({node:m.callee,messageId:"invalidLoaderLocation",data:{routesDir:e,fnName:f,path:t}});return}let p=m.parent;if(p.type!=="VariableDeclarator"){r.report({node:m.callee,messageId:"missingExport",data:{fnName:f,id:"useStuff"}});return}if(p.id.type!=="Identifier"){r.report({node:m.callee,messageId:"missingExport",data:{fnName:f,id:"useStuff"}});return}if(!/^use/.test(p.id.name)){let g="use"+p.id.name[0].toUpperCase()+p.id.name.slice(1);r.report({node:p.id,messageId:"wrongName",data:{fnName:f,id:p.id.name,fixed:g}});return}if(!fv(p)){r.report({node:p.id,messageId:"missingExport",data:{fnName:f,id:p.id.name}});return}if(m.arguments.length>0&&m.arguments[0].type==="Identifier"){r.report({node:m.arguments[0],messageId:"recommendedValue",data:{fnName:f,id:p.id.name,arg:m.arguments[0].name}});return}}}}};function cv(r){let e=/^\\\\\?\\/.test(r),t=/[^\u0000-\u0080]+/.test(r);return e||t||(r=r.replace(/\\/g,"/"),r.endsWith("/")&&(r=r.slice(0,r.length-1))),r}var bx=`
|
|
156
164
|
import { routeLoader$ } from '@builder.io/qwik-city';
|
|
157
165
|
|
|
158
166
|
export const useProductDetails = routeLoader$(async (requestEvent) => {
|
|
@@ -278,7 +286,7 @@ Did you mean to wrap it in \`$()\`?
|
|
|
278
286
|
|
|
279
287
|
{{solution}}
|
|
280
288
|
Check out https://qwik.builder.io/docs/advanced/dollar/ for more details.`,mutableIdentifier:`Mutating let "{{varName}}" within the ({{dollarName}}) closure is not allowed, instead create an object/store/signal and mutate one of its properties.
|
|
281
|
-
Check out https://qwik.builder.io/docs/advanced/dollar/ for more details.`}},create(r){var m;let t={allowAny:((m=r.options[0])==null?void 0:m.allowAny)??!0},n=r.sourceCode.scopeManager,o=Sn.ESLintUtils.getParserServices(r),i=o.esTreeNodeToTSNodeMap,a=o.program.getTypeChecker(),u=new Map,c=[];function y(f){f.references.forEach(p=>{var d,x;let g=p.resolved,l=(d=p.resolved)==null?void 0:d.scope;if(g&&l){let h=(x=g.defs.at(0))==null?void 0:x.type;if(h==="Type"||h==="ImportBinding")return;let S=p.from,O;for(;S&&(O=u.get(S),!O);)S=S.upper;if(S&&O){let j=l.type;if(j==="global"||j==="module")return;let V=p.identifier,ke=i.get(V),R=l;for(;R&&!u.has(R);)R=R.upper;if(R!==S){V.parent&&V.parent.type==="AssignmentExpression"&&V.parent.left===V&&r.report({messageId:"mutableIdentifier",node:p.identifier,data:{varName:p.identifier.name,dollarName:O}});let ce=gv(r,a,ke,p.identifier,t);ce&&r.report({messageId:"referencesOutside",node:p.identifier,data:{varName:p.identifier.name,dollarName:O,reason:vv(ce)}})}}}}),f.childScopes.forEach(y)}return{CallExpression(f){if(f.callee.type==="Identifier"&&f.callee.name.endsWith("$")){let p=f.arguments.at(0);if(p&&p.type==="ArrowFunctionExpression"){let g=n.acquire(p);g&&u.set(g,f.callee.name)}}},JSXAttribute(f){let p=f.name,g=p.type==="JSXIdentifier"?p.name:p.name.name;if(g.endsWith("$")){let l=f.value;if(l&&l.type==="JSXExpressionContainer"){let d=n.acquire(l.expression);if(d)u.set(d,g);else if(l.expression.type==="Identifier"){let x=i.get(l.expression),h=a.getTypeAtLocation(x);if(!hl(h))if(h.isUnionOrIntersection())h.types.every(S=>S.symbol?S.symbol.name==="PropFnInterface":!!(S.flags&(N.default.TypeFlags.Undefined|N.default.TypeFlags.Null)))||r.report({messageId:"invalidJsxDollar",node:l.expression,data:{varName:l.expression.name,solution:`Fix the type of ${l.expression.name} to be
|
|
289
|
+
Check out https://qwik.builder.io/docs/advanced/dollar/ for more details.`}},create(r){var m;let t={allowAny:((m=r.options[0])==null?void 0:m.allowAny)??!0},n=r.sourceCode.scopeManager,o=Sn.ESLintUtils.getParserServices(r),i=o.esTreeNodeToTSNodeMap,a=o.program.getTypeChecker(),u=new Map,c=[];function y(f){f.references.forEach(p=>{var d,x;let g=p.resolved,l=(d=p.resolved)==null?void 0:d.scope;if(g&&l){let h=(x=g.defs.at(0))==null?void 0:x.type;if(h==="Type"||h==="ImportBinding")return;let S=p.from,O;for(;S&&(O=u.get(S),!O);)S=S.upper;if(S&&O){let j=l.type;if(j==="global"||j==="module")return;let V=p.identifier,ke=i.get(V),R=l;for(;R&&!u.has(R);)R=R.upper;if(R!==S){V.parent&&V.parent.type==="AssignmentExpression"&&V.parent.left===V&&r.report({messageId:"mutableIdentifier",node:p.identifier,data:{varName:p.identifier.name,dollarName:O}});let ce=gv(r,a,ke,p.identifier,t);ce&&r.report({messageId:"referencesOutside",node:p.identifier,data:{varName:p.identifier.name,dollarName:O,reason:vv(ce)}})}}}}),f.childScopes.forEach(y)}return{CallExpression(f){if(f.callee.type==="Identifier"&&f.callee.name.endsWith("$")){let p=f.arguments.at(0);if(p&&p.type==="ArrowFunctionExpression"){let g=n.acquire(p);g&&u.set(g,f.callee.name)}}},JSXAttribute(f){let p=f.name,g=p.type==="JSXIdentifier"?p.name:p.name.name;if(g.endsWith("$")){let l=f.value;if(l&&l.type==="JSXExpressionContainer"){let d=n.acquire(l.expression);if(d)u.set(d,g);else if(l.expression.type==="Identifier"){let x=i.get(l.expression),h=a.getTypeAtLocation(x);if(!hl(h))if(h.isUnionOrIntersection())h.types.every(S=>S.symbol?S.symbol.name==="PropFnInterface":!!(S.flags&(N.default.TypeFlags.Undefined|N.default.TypeFlags.Null)))||r.report({messageId:"invalidJsxDollar",node:l.expression,data:{varName:l.expression.name,solution:`Fix the type of ${l.expression.name} to be QRL`}});else{if(h.symbol.name==="PropFnInterface")return;r.report({messageId:"invalidJsxDollar",node:l.expression,data:{varName:l.expression.name,solution:`const ${l.expression.name} = $(
|
|
282
290
|
${bl(h.symbol,r.sourceCode.text)}
|
|
283
291
|
);
|
|
284
292
|
`}})}}}}},Program(f){let p=i.get(f),g=a.getSymbolAtLocation(p);g&&(c=a.getExportsOfModule(g))},"Program:exit"(){y(n.globalScope)}}}});function gv(r,e,t,n,o){let i=e.getTypeAtLocation(t);return hv(r,e,i,t,n,o,new Set)}function vv(r){let e="";return r.location?e+=`"${r.location}" `:e+="it ",e+=`${r.reason}`,e}function hv(r,e,t,n,o,i,a){let u=_e(r,e,t,n,i,0,a);if(u){let c=u.location;return c&&(u.location=`${o.name}.${c}`),u}return u}function _e(r,e,t,n,o,i,a){if(a.has(t)||(a.add(t),t.getProperty("__no_serialize__")||t.getProperty("__qwik_serializable__")))return;if(t.flags&N.default.TypeFlags.Unknown)return{type:t,typeStr:e.typeToString(t),reason:"is unknown, which could be serializable or not, please make the type for specific"};let c=t.flags&N.default.TypeFlags.Any;if(!o.allowAny&&c)return{type:t,typeStr:e.typeToString(t),reason:"is any, which is not serializable"};if(t.flags&N.default.TypeFlags.ESSymbolLike)return{type:t,typeStr:e.typeToString(t),reason:"is Symbol, which is not serializable"};if(t.flags&N.default.TypeFlags.Enum)return{type:t,typeStr:e.typeToString(t),reason:"is an enum, use an string or a number instead"};if(hl(t))return;if(t.getCallSignatures().length>0){let g=t.symbol.name;if(g==="PropFnInterface"||g==="RefFnInterface"||g==="bivarianceHack"||g==="FunctionComponent")return;let l="is a function, which is not serializable";if(i===0&&N.default.isIdentifier(n)){let d=`const ${n.text} = $(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-qwik",
|
|
3
3
|
"description": "An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.3",
|
|
5
5
|
"author": "Builder Team",
|
|
6
6
|
"bugs": "https://github.com/BuilderIO/qwik/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@builder.io/qwik": "workspace:*",
|
|
12
|
-
"@types/eslint": "^8.44.
|
|
12
|
+
"@types/eslint": "^8.44.8",
|
|
13
13
|
"@types/estree": "^1.0.2",
|
|
14
|
-
"@typescript-eslint/rule-tester": "^6.
|
|
15
|
-
"@typescript-eslint/utils": "^6.
|
|
14
|
+
"@typescript-eslint/rule-tester": "^6.13.2",
|
|
15
|
+
"@typescript-eslint/utils": "^6.13.2",
|
|
16
16
|
"redent": "^4.0.0"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"main": "index.js",
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"eslint": "^8.
|
|
30
|
+
"eslint": "^8.55.0"
|
|
31
31
|
},
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|