eslint-plugin-nextjs 0.1.2 → 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 +13 -13
- package/dist/index.d.ts +3 -6
- package/dist/index.js +398 -260
- package/dist/index.js.map +1 -1
- package/package.json +15 -10
- package/dist/index.cjs +0 -1485
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -11
- package/dist/rules/google-font-display.cjs +0 -119
- package/dist/rules/google-font-display.cjs.map +0 -1
- package/dist/rules/google-font-display.d.cts +0 -8
- package/dist/rules/google-font-display.d.ts +0 -8
- package/dist/rules/google-font-display.js +0 -92
- package/dist/rules/google-font-display.js.map +0 -1
- package/dist/rules/google-font-preconnect.cjs +0 -109
- package/dist/rules/google-font-preconnect.cjs.map +0 -1
- package/dist/rules/google-font-preconnect.d.cts +0 -5
- package/dist/rules/google-font-preconnect.d.ts +0 -5
- package/dist/rules/google-font-preconnect.js +0 -82
- package/dist/rules/google-font-preconnect.js.map +0 -1
- package/dist/rules/inline-script-id.cjs +0 -94
- package/dist/rules/inline-script-id.cjs.map +0 -1
- package/dist/rules/inline-script-id.d.cts +0 -5
- package/dist/rules/inline-script-id.d.ts +0 -5
- package/dist/rules/inline-script-id.js +0 -67
- package/dist/rules/inline-script-id.js.map +0 -1
- package/dist/rules/next-script-for-ga.cjs +0 -129
- package/dist/rules/next-script-for-ga.cjs.map +0 -1
- package/dist/rules/next-script-for-ga.d.cts +0 -5
- package/dist/rules/next-script-for-ga.d.ts +0 -5
- package/dist/rules/next-script-for-ga.js +0 -102
- package/dist/rules/next-script-for-ga.js.map +0 -1
- package/dist/rules/no-assign-module-variable.cjs +0 -64
- package/dist/rules/no-assign-module-variable.cjs.map +0 -1
- package/dist/rules/no-assign-module-variable.d.cts +0 -5
- package/dist/rules/no-assign-module-variable.d.ts +0 -5
- package/dist/rules/no-assign-module-variable.js +0 -37
- package/dist/rules/no-assign-module-variable.js.map +0 -1
- package/dist/rules/no-async-client-component.cjs +0 -99
- package/dist/rules/no-async-client-component.cjs.map +0 -1
- package/dist/rules/no-async-client-component.d.cts +0 -5
- package/dist/rules/no-async-client-component.d.ts +0 -5
- package/dist/rules/no-async-client-component.js +0 -72
- package/dist/rules/no-async-client-component.js.map +0 -1
- package/dist/rules/no-before-interactive-script-outside-document.cjs +0 -94
- package/dist/rules/no-before-interactive-script-outside-document.cjs.map +0 -1
- package/dist/rules/no-before-interactive-script-outside-document.d.cts +0 -5
- package/dist/rules/no-before-interactive-script-outside-document.d.ts +0 -5
- package/dist/rules/no-before-interactive-script-outside-document.js +0 -59
- package/dist/rules/no-before-interactive-script-outside-document.js.map +0 -1
- package/dist/rules/no-css-tags.cjs +0 -70
- package/dist/rules/no-css-tags.cjs.map +0 -1
- package/dist/rules/no-css-tags.d.cts +0 -5
- package/dist/rules/no-css-tags.d.ts +0 -5
- package/dist/rules/no-css-tags.js +0 -43
- package/dist/rules/no-css-tags.js.map +0 -1
- package/dist/rules/no-document-import-in-page.cjs +0 -74
- package/dist/rules/no-document-import-in-page.cjs.map +0 -1
- package/dist/rules/no-document-import-in-page.d.cts +0 -5
- package/dist/rules/no-document-import-in-page.d.ts +0 -5
- package/dist/rules/no-document-import-in-page.js +0 -39
- package/dist/rules/no-document-import-in-page.js.map +0 -1
- package/dist/rules/no-duplicate-head.cjs +0 -87
- package/dist/rules/no-duplicate-head.cjs.map +0 -1
- package/dist/rules/no-duplicate-head.d.cts +0 -5
- package/dist/rules/no-duplicate-head.d.ts +0 -5
- package/dist/rules/no-duplicate-head.js +0 -60
- package/dist/rules/no-duplicate-head.js.map +0 -1
- package/dist/rules/no-head-element.cjs +0 -76
- package/dist/rules/no-head-element.cjs.map +0 -1
- package/dist/rules/no-head-element.d.cts +0 -5
- package/dist/rules/no-head-element.d.ts +0 -5
- package/dist/rules/no-head-element.js +0 -41
- package/dist/rules/no-head-element.js.map +0 -1
- package/dist/rules/no-head-import-in-document.cjs +0 -76
- package/dist/rules/no-head-import-in-document.cjs.map +0 -1
- package/dist/rules/no-head-import-in-document.d.cts +0 -5
- package/dist/rules/no-head-import-in-document.d.ts +0 -5
- package/dist/rules/no-head-import-in-document.js +0 -41
- package/dist/rules/no-head-import-in-document.js.map +0 -1
- package/dist/rules/no-html-link-for-pages.cjs +0 -302
- package/dist/rules/no-html-link-for-pages.cjs.map +0 -1
- package/dist/rules/no-html-link-for-pages.d.cts +0 -5
- package/dist/rules/no-html-link-for-pages.d.ts +0 -5
- package/dist/rules/no-html-link-for-pages.js +0 -267
- package/dist/rules/no-html-link-for-pages.js.map +0 -1
- package/dist/rules/no-img-element.cjs +0 -83
- package/dist/rules/no-img-element.cjs.map +0 -1
- package/dist/rules/no-img-element.d.cts +0 -5
- package/dist/rules/no-img-element.d.ts +0 -5
- package/dist/rules/no-img-element.js +0 -48
- package/dist/rules/no-img-element.js.map +0 -1
- package/dist/rules/no-page-custom-font.cjs +0 -184
- package/dist/rules/no-page-custom-font.cjs.map +0 -1
- package/dist/rules/no-page-custom-font.d.cts +0 -5
- package/dist/rules/no-page-custom-font.d.ts +0 -5
- package/dist/rules/no-page-custom-font.js +0 -159
- package/dist/rules/no-page-custom-font.js.map +0 -1
- package/dist/rules/no-script-component-in-head.cjs +0 -74
- package/dist/rules/no-script-component-in-head.cjs.map +0 -1
- package/dist/rules/no-script-component-in-head.d.cts +0 -5
- package/dist/rules/no-script-component-in-head.d.ts +0 -5
- package/dist/rules/no-script-component-in-head.js +0 -47
- package/dist/rules/no-script-component-in-head.js.map +0 -1
- package/dist/rules/no-styled-jsx-in-document.cjs +0 -78
- package/dist/rules/no-styled-jsx-in-document.cjs.map +0 -1
- package/dist/rules/no-styled-jsx-in-document.d.cts +0 -5
- package/dist/rules/no-styled-jsx-in-document.d.ts +0 -5
- package/dist/rules/no-styled-jsx-in-document.js +0 -43
- package/dist/rules/no-styled-jsx-in-document.js.map +0 -1
- package/dist/rules/no-sync-scripts.cjs +0 -64
- package/dist/rules/no-sync-scripts.cjs.map +0 -1
- package/dist/rules/no-sync-scripts.d.cts +0 -5
- package/dist/rules/no-sync-scripts.d.ts +0 -5
- package/dist/rules/no-sync-scripts.js +0 -37
- package/dist/rules/no-sync-scripts.js.map +0 -1
- package/dist/rules/no-title-in-document-head.cjs +0 -78
- package/dist/rules/no-title-in-document-head.cjs.map +0 -1
- package/dist/rules/no-title-in-document-head.d.cts +0 -5
- package/dist/rules/no-title-in-document-head.d.ts +0 -5
- package/dist/rules/no-title-in-document-head.js +0 -51
- package/dist/rules/no-title-in-document-head.js.map +0 -1
- package/dist/rules/no-typos.cjs +0 -133
- package/dist/rules/no-typos.cjs.map +0 -1
- package/dist/rules/no-typos.d.cts +0 -5
- package/dist/rules/no-typos.d.ts +0 -5
- package/dist/rules/no-typos.js +0 -98
- package/dist/rules/no-typos.js.map +0 -1
- package/dist/rules/no-unwanted-polyfillio.cjs +0 -164
- package/dist/rules/no-unwanted-polyfillio.cjs.map +0 -1
- package/dist/rules/no-unwanted-polyfillio.d.cts +0 -5
- package/dist/rules/no-unwanted-polyfillio.d.ts +0 -5
- package/dist/rules/no-unwanted-polyfillio.js +0 -137
- package/dist/rules/no-unwanted-polyfillio.js.map +0 -1
- package/dist/utils/define-rule.cjs +0 -31
- package/dist/utils/define-rule.cjs.map +0 -1
- package/dist/utils/define-rule.d.cts +0 -5
- package/dist/utils/define-rule.d.ts +0 -5
- package/dist/utils/define-rule.js +0 -6
- package/dist/utils/define-rule.js.map +0 -1
- package/dist/utils/get-root-dirs.cjs +0 -60
- package/dist/utils/get-root-dirs.cjs.map +0 -1
- package/dist/utils/get-root-dirs.d.cts +0 -8
- package/dist/utils/get-root-dirs.d.ts +0 -8
- package/dist/utils/get-root-dirs.js +0 -25
- package/dist/utils/get-root-dirs.js.map +0 -1
- package/dist/utils/node-attributes.cjs +0 -67
- package/dist/utils/node-attributes.cjs.map +0 -1
- package/dist/utils/node-attributes.d.cts +0 -15
- package/dist/utils/node-attributes.d.ts +0 -15
- package/dist/utils/node-attributes.js +0 -46
- package/dist/utils/node-attributes.js.map +0 -1
- package/dist/utils/url.cjs +0 -167
- package/dist/utils/url.cjs.map +0 -1
- package/dist/utils/url.d.cts +0 -35
- package/dist/utils/url.d.ts +0 -35
- package/dist/utils/url.js +0 -128
- package/dist/utils/url.js.map +0 -1
@@ -1,82 +0,0 @@
|
|
1
|
-
// src/utils/define-rule.ts
|
2
|
-
var defineRule = (rule) => rule;
|
3
|
-
|
4
|
-
// src/utils/node-attributes.ts
|
5
|
-
var NodeAttributes = class {
|
6
|
-
attributes;
|
7
|
-
constructor(ASTnode) {
|
8
|
-
this.attributes = {};
|
9
|
-
ASTnode.attributes.forEach((attribute) => {
|
10
|
-
if (!attribute.type || attribute.type !== "JSXAttribute") {
|
11
|
-
return;
|
12
|
-
}
|
13
|
-
if (attribute.value) {
|
14
|
-
const value = typeof attribute.value.value === "string" ? attribute.value.value : typeof attribute.value.expression?.value !== "undefined" ? attribute.value.expression.value : attribute.value.expression?.properties;
|
15
|
-
this.attributes[attribute.name.name] = {
|
16
|
-
hasValue: true,
|
17
|
-
value
|
18
|
-
};
|
19
|
-
} else {
|
20
|
-
this.attributes[attribute.name.name] = {
|
21
|
-
hasValue: false
|
22
|
-
};
|
23
|
-
}
|
24
|
-
});
|
25
|
-
}
|
26
|
-
has(attrName) {
|
27
|
-
return Boolean(this.attributes[attrName]);
|
28
|
-
}
|
29
|
-
hasAny() {
|
30
|
-
return Boolean(Object.keys(this.attributes).length);
|
31
|
-
}
|
32
|
-
hasValue(attrName) {
|
33
|
-
return Boolean(this.attributes[attrName]?.hasValue);
|
34
|
-
}
|
35
|
-
value(attrName) {
|
36
|
-
const attr = this.attributes[attrName];
|
37
|
-
if (!attr) {
|
38
|
-
return true;
|
39
|
-
}
|
40
|
-
if ("hasValue" in attr && attr.hasValue) {
|
41
|
-
return attr.value;
|
42
|
-
}
|
43
|
-
return void 0;
|
44
|
-
}
|
45
|
-
};
|
46
|
-
|
47
|
-
// src/rules/google-font-preconnect.ts
|
48
|
-
var url = "https://nextjs.org/docs/messages/google-font-preconnect";
|
49
|
-
var googleFontPreconnect = defineRule({
|
50
|
-
create: (context) => ({
|
51
|
-
JSXOpeningElement: (node) => {
|
52
|
-
if (node.name.name !== "link") {
|
53
|
-
return;
|
54
|
-
}
|
55
|
-
const attributes = new NodeAttributes(node);
|
56
|
-
if (!attributes.has("href") || !attributes.hasValue("href")) {
|
57
|
-
return;
|
58
|
-
}
|
59
|
-
const hrefValue = attributes.value("href");
|
60
|
-
const preconnectMissing = !attributes.has("rel") || !attributes.hasValue("rel") || attributes.value("rel") !== "preconnect";
|
61
|
-
if (typeof hrefValue === "string" && hrefValue.startsWith("https://fonts.gstatic.com") && preconnectMissing) {
|
62
|
-
context.report({
|
63
|
-
message: `\`rel="preconnect"\` is missing from Google Font. See: ${url}`,
|
64
|
-
node
|
65
|
-
});
|
66
|
-
}
|
67
|
-
}
|
68
|
-
}),
|
69
|
-
meta: {
|
70
|
-
docs: {
|
71
|
-
description: "Ensure `preconnect` is used with Google Fonts.",
|
72
|
-
recommended: true,
|
73
|
-
url
|
74
|
-
},
|
75
|
-
schema: [],
|
76
|
-
type: "problem"
|
77
|
-
}
|
78
|
-
});
|
79
|
-
export {
|
80
|
-
googleFontPreconnect
|
81
|
-
};
|
82
|
-
//# sourceMappingURL=google-font-preconnect.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/utils/define-rule.ts","../../src/utils/node-attributes.ts","../../src/rules/google-font-preconnect.ts"],"sourcesContent":["import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n","// Return attributes and values of a node in a convenient way:\n/* example: \n <ExampleElement attr1=\"15\" attr2>\n { attr1: {\n hasValue: true,\n value: 15\n },\n attr2: {\n hasValue: false\n }\nInclusion of hasValue is in case an eslint rule cares about boolean values\nexplicitly assigned to attribute vs the attribute being used as a flag\n*/\nexport default class NodeAttributes {\n attributes: Record<\n string,\n | {\n hasValue: true;\n value: any;\n }\n | {\n hasValue?: false;\n }\n >;\n\n constructor(ASTnode: any) {\n this.attributes = {};\n ASTnode.attributes.forEach((attribute: any) => {\n if (!attribute.type || attribute.type !== \"JSXAttribute\") {\n return;\n }\n\n if (attribute.value) {\n // hasValue\n const value =\n typeof attribute.value.value === \"string\" ? attribute.value.value\n : typeof attribute.value.expression?.value !== \"undefined\" ?\n attribute.value.expression.value\n : attribute.value.expression?.properties;\n\n this.attributes[attribute.name.name] = {\n hasValue: true,\n value,\n };\n } else {\n this.attributes[attribute.name.name] = {\n hasValue: false,\n };\n }\n });\n }\n\n has(attrName: string): boolean {\n return Boolean(this.attributes[attrName]);\n }\n\n hasAny(): boolean {\n return Boolean(Object.keys(this.attributes).length);\n }\n\n hasValue(attrName: string): boolean {\n return Boolean(this.attributes[attrName]?.hasValue);\n }\n\n value(attrName: string): any {\n const attr = this.attributes[attrName];\n\n if (!attr) {\n return true;\n }\n\n if (\"hasValue\" in attr && attr.hasValue) {\n return attr.value;\n }\n\n return undefined;\n }\n}\n","import { defineRule } from \"../utils/define-rule.js\";\nimport NodeAttributes from \"../utils/node-attributes.js\";\n\nconst url = \"https://nextjs.org/docs/messages/google-font-preconnect\";\n\nexport const googleFontPreconnect = defineRule({\n create: (context: any) => ({\n JSXOpeningElement: (node: any) => {\n if (node.name.name !== \"link\") {\n return;\n }\n\n const attributes = new NodeAttributes(node);\n if (!attributes.has(\"href\") || !attributes.hasValue(\"href\")) {\n return;\n }\n\n const hrefValue = attributes.value(\"href\");\n const preconnectMissing =\n !attributes.has(\"rel\") ||\n !attributes.hasValue(\"rel\") ||\n attributes.value(\"rel\") !== \"preconnect\";\n\n if (\n typeof hrefValue === \"string\" &&\n hrefValue.startsWith(\"https://fonts.gstatic.com\") &&\n preconnectMissing\n ) {\n context.report({\n message: `\\`rel=\"preconnect\"\\` is missing from Google Font. See: ${url}`,\n node,\n });\n }\n },\n }),\n meta: {\n docs: {\n description: \"Ensure `preconnect` is used with Google Fonts.\",\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n"],"mappings":";AAEO,IAAM,aAAa,CAAC,SAA2C;;;ACWtE,IAAqB,iBAArB,MAAoC;AAAA,EAClC;AAAA,EAWA,YAAY,SAAc;AACxB,SAAK,aAAa,CAAC;AACnB,YAAQ,WAAW,QAAQ,CAAC,cAAmB;AAC7C,UAAI,CAAC,UAAU,QAAQ,UAAU,SAAS,gBAAgB;AACxD;AAAA,MACF;AAEA,UAAI,UAAU,OAAO;AAEnB,cAAM,QACJ,OAAO,UAAU,MAAM,UAAU,WAAW,UAAU,MAAM,QAC1D,OAAO,UAAU,MAAM,YAAY,UAAU,cAC7C,UAAU,MAAM,WAAW,QAC3B,UAAU,MAAM,YAAY;AAEhC,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAA2B;AAC7B,WAAO,QAAQ,KAAK,WAAW,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,SAAkB;AAChB,WAAO,QAAQ,OAAO,KAAK,KAAK,UAAU,EAAE,MAAM;AAAA,EACpD;AAAA,EAEA,SAAS,UAA2B;AAClC,WAAO,QAAQ,KAAK,WAAW,QAAQ,GAAG,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAM,UAAuB;AAC3B,UAAM,OAAO,KAAK,WAAW,QAAQ;AAErC,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,QAAQ,KAAK,UAAU;AACvC,aAAO,KAAK;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AACF;;;AC1EA,IAAM,MAAM;AAEL,IAAM,uBAAuB,WAAW;AAAA,EAC7C,QAAQ,CAAC,aAAkB;AAAA,IACzB,mBAAmB,CAAC,SAAc;AAChC,UAAI,KAAK,KAAK,SAAS,QAAQ;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,IAAI,eAAe,IAAI;AAC1C,UAAI,CAAC,WAAW,IAAI,MAAM,KAAK,CAAC,WAAW,SAAS,MAAM,GAAG;AAC3D;AAAA,MACF;AAEA,YAAM,YAAY,WAAW,MAAM,MAAM;AACzC,YAAM,oBACJ,CAAC,WAAW,IAAI,KAAK,KACrB,CAAC,WAAW,SAAS,KAAK,KAC1B,WAAW,MAAM,KAAK,MAAM;AAE9B,UACE,OAAO,cAAc,YACrB,UAAU,WAAW,2BAA2B,KAChD,mBACA;AACA,gBAAQ,OAAO;AAAA,UACb,SAAS,0DAA0D,GAAG;AAAA,UACtE;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,aAAa;AAAA,MACb,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|
@@ -1,94 +0,0 @@
|
|
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
|
-
|
20
|
-
// src/rules/inline-script-id.ts
|
21
|
-
var inline_script_id_exports = {};
|
22
|
-
__export(inline_script_id_exports, {
|
23
|
-
inlineScriptId: () => inlineScriptId
|
24
|
-
});
|
25
|
-
module.exports = __toCommonJS(inline_script_id_exports);
|
26
|
-
|
27
|
-
// src/utils/define-rule.ts
|
28
|
-
var defineRule = (rule) => rule;
|
29
|
-
|
30
|
-
// src/rules/inline-script-id.ts
|
31
|
-
var url = "https://nextjs.org/docs/messages/inline-script-id";
|
32
|
-
var inlineScriptId = defineRule({
|
33
|
-
create: (context) => {
|
34
|
-
let nextScriptImportName = null;
|
35
|
-
return {
|
36
|
-
ImportDeclaration: (node) => {
|
37
|
-
if (node.source.value === "next/script") {
|
38
|
-
nextScriptImportName = node.specifiers[0].local.name;
|
39
|
-
}
|
40
|
-
},
|
41
|
-
JSXElement: (node) => {
|
42
|
-
if (nextScriptImportName === null) {
|
43
|
-
return;
|
44
|
-
}
|
45
|
-
if (node.openingElement?.name && node.openingElement.name.name !== nextScriptImportName) {
|
46
|
-
return;
|
47
|
-
}
|
48
|
-
const attributeNames = /* @__PURE__ */ new Set();
|
49
|
-
let hasNonCheckableSpreadAttribute = false;
|
50
|
-
node.openingElement.attributes.forEach((attribute) => {
|
51
|
-
if (hasNonCheckableSpreadAttribute) {
|
52
|
-
return;
|
53
|
-
}
|
54
|
-
if (attribute.type === "JSXAttribute") {
|
55
|
-
attributeNames.add(attribute.name.name);
|
56
|
-
} else if (attribute.type === "JSXSpreadAttribute") {
|
57
|
-
if (attribute.argument?.properties) {
|
58
|
-
attribute.argument.properties.forEach((property) => {
|
59
|
-
attributeNames.add(property.key.name);
|
60
|
-
});
|
61
|
-
} else {
|
62
|
-
hasNonCheckableSpreadAttribute = true;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
});
|
66
|
-
if (hasNonCheckableSpreadAttribute) {
|
67
|
-
return;
|
68
|
-
}
|
69
|
-
if (node.children.length > 0 || attributeNames.has("dangerouslySetInnerHTML")) {
|
70
|
-
if (!attributeNames.has("id")) {
|
71
|
-
context.report({
|
72
|
-
message: `\`next/script\` components with inline content must specify an \`id\` attribute. See: ${url}`,
|
73
|
-
node
|
74
|
-
});
|
75
|
-
}
|
76
|
-
}
|
77
|
-
}
|
78
|
-
};
|
79
|
-
},
|
80
|
-
meta: {
|
81
|
-
docs: {
|
82
|
-
description: "Enforce `id` attribute on `next/script` components with inline content.",
|
83
|
-
recommended: true,
|
84
|
-
url
|
85
|
-
},
|
86
|
-
schema: [],
|
87
|
-
type: "problem"
|
88
|
-
}
|
89
|
-
});
|
90
|
-
// Annotate the CommonJS export names for ESM import in node:
|
91
|
-
0 && (module.exports = {
|
92
|
-
inlineScriptId
|
93
|
-
});
|
94
|
-
//# sourceMappingURL=inline-script-id.cjs.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/rules/inline-script-id.ts","../../src/utils/define-rule.ts"],"sourcesContent":["import { defineRule } from \"../utils/define-rule.js\";\n\nconst url = \"https://nextjs.org/docs/messages/inline-script-id\";\n\nexport const inlineScriptId = defineRule({\n create: (context) => {\n let nextScriptImportName: null | string = null;\n\n return {\n ImportDeclaration: (node: any) => {\n if (node.source.value === \"next/script\") {\n nextScriptImportName = node.specifiers[0].local.name;\n }\n },\n JSXElement: (node: any) => {\n if (nextScriptImportName === null) {\n return;\n }\n\n if (\n node.openingElement?.name &&\n node.openingElement.name.name !== nextScriptImportName\n ) {\n return;\n }\n\n const attributeNames = new Set();\n\n let hasNonCheckableSpreadAttribute = false;\n node.openingElement.attributes.forEach((attribute: any) => {\n // Early return if we already have a non-checkable spread attribute, for better performance\n if (hasNonCheckableSpreadAttribute) {\n return;\n }\n\n if (attribute.type === \"JSXAttribute\") {\n attributeNames.add(attribute.name.name);\n } else if (attribute.type === \"JSXSpreadAttribute\") {\n if (attribute.argument?.properties) {\n attribute.argument.properties.forEach((property: any) => {\n attributeNames.add(property.key.name);\n });\n } else {\n // JSXSpreadAttribute without properties is not checkable\n hasNonCheckableSpreadAttribute = true;\n }\n }\n });\n\n // https://github.com/vercel/next.js/issues/34030\n // If there is a non-checkable spread attribute, we simply ignore them\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasNonCheckableSpreadAttribute) {\n return;\n }\n\n if (\n node.children.length > 0 ||\n attributeNames.has(\"dangerouslySetInnerHTML\")\n ) {\n if (!attributeNames.has(\"id\")) {\n context.report({\n message: `\\`next/script\\` components with inline content must specify an \\`id\\` attribute. See: ${url}`,\n node,\n });\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n \"Enforce `id` attribute on `next/script` components with inline content.\",\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n","import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,aAAa,CAAC,SAA2C;;;ADAtE,IAAM,MAAM;AAEL,IAAM,iBAAiB,WAAW;AAAA,EACvC,QAAQ,CAAC,YAAY;AACnB,QAAI,uBAAsC;AAE1C,WAAO;AAAA,MACL,mBAAmB,CAAC,SAAc;AAChC,YAAI,KAAK,OAAO,UAAU,eAAe;AACvC,iCAAuB,KAAK,WAAW,CAAC,EAAE,MAAM;AAAA,QAClD;AAAA,MACF;AAAA,MACA,YAAY,CAAC,SAAc;AACzB,YAAI,yBAAyB,MAAM;AACjC;AAAA,QACF;AAEA,YACE,KAAK,gBAAgB,QACrB,KAAK,eAAe,KAAK,SAAS,sBAClC;AACA;AAAA,QACF;AAEA,cAAM,iBAAiB,oBAAI,IAAI;AAE/B,YAAI,iCAAiC;AACrC,aAAK,eAAe,WAAW,QAAQ,CAAC,cAAmB;AAEzD,cAAI,gCAAgC;AAClC;AAAA,UACF;AAEA,cAAI,UAAU,SAAS,gBAAgB;AACrC,2BAAe,IAAI,UAAU,KAAK,IAAI;AAAA,UACxC,WAAW,UAAU,SAAS,sBAAsB;AAClD,gBAAI,UAAU,UAAU,YAAY;AAClC,wBAAU,SAAS,WAAW,QAAQ,CAAC,aAAkB;AACvD,+BAAe,IAAI,SAAS,IAAI,IAAI;AAAA,cACtC,CAAC;AAAA,YACH,OAAO;AAEL,+CAAiC;AAAA,YACnC;AAAA,UACF;AAAA,QACF,CAAC;AAKD,YAAI,gCAAgC;AAClC;AAAA,QACF;AAEA,YACE,KAAK,SAAS,SAAS,KACvB,eAAe,IAAI,yBAAyB,GAC5C;AACA,cAAI,CAAC,eAAe,IAAI,IAAI,GAAG;AAC7B,oBAAQ,OAAO;AAAA,cACb,SAAS,yFAAyF,GAAG;AAAA,cACrG;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,aACE;AAAA,MACF,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|
@@ -1,67 +0,0 @@
|
|
1
|
-
// src/utils/define-rule.ts
|
2
|
-
var defineRule = (rule) => rule;
|
3
|
-
|
4
|
-
// src/rules/inline-script-id.ts
|
5
|
-
var url = "https://nextjs.org/docs/messages/inline-script-id";
|
6
|
-
var inlineScriptId = defineRule({
|
7
|
-
create: (context) => {
|
8
|
-
let nextScriptImportName = null;
|
9
|
-
return {
|
10
|
-
ImportDeclaration: (node) => {
|
11
|
-
if (node.source.value === "next/script") {
|
12
|
-
nextScriptImportName = node.specifiers[0].local.name;
|
13
|
-
}
|
14
|
-
},
|
15
|
-
JSXElement: (node) => {
|
16
|
-
if (nextScriptImportName === null) {
|
17
|
-
return;
|
18
|
-
}
|
19
|
-
if (node.openingElement?.name && node.openingElement.name.name !== nextScriptImportName) {
|
20
|
-
return;
|
21
|
-
}
|
22
|
-
const attributeNames = /* @__PURE__ */ new Set();
|
23
|
-
let hasNonCheckableSpreadAttribute = false;
|
24
|
-
node.openingElement.attributes.forEach((attribute) => {
|
25
|
-
if (hasNonCheckableSpreadAttribute) {
|
26
|
-
return;
|
27
|
-
}
|
28
|
-
if (attribute.type === "JSXAttribute") {
|
29
|
-
attributeNames.add(attribute.name.name);
|
30
|
-
} else if (attribute.type === "JSXSpreadAttribute") {
|
31
|
-
if (attribute.argument?.properties) {
|
32
|
-
attribute.argument.properties.forEach((property) => {
|
33
|
-
attributeNames.add(property.key.name);
|
34
|
-
});
|
35
|
-
} else {
|
36
|
-
hasNonCheckableSpreadAttribute = true;
|
37
|
-
}
|
38
|
-
}
|
39
|
-
});
|
40
|
-
if (hasNonCheckableSpreadAttribute) {
|
41
|
-
return;
|
42
|
-
}
|
43
|
-
if (node.children.length > 0 || attributeNames.has("dangerouslySetInnerHTML")) {
|
44
|
-
if (!attributeNames.has("id")) {
|
45
|
-
context.report({
|
46
|
-
message: `\`next/script\` components with inline content must specify an \`id\` attribute. See: ${url}`,
|
47
|
-
node
|
48
|
-
});
|
49
|
-
}
|
50
|
-
}
|
51
|
-
}
|
52
|
-
};
|
53
|
-
},
|
54
|
-
meta: {
|
55
|
-
docs: {
|
56
|
-
description: "Enforce `id` attribute on `next/script` components with inline content.",
|
57
|
-
recommended: true,
|
58
|
-
url
|
59
|
-
},
|
60
|
-
schema: [],
|
61
|
-
type: "problem"
|
62
|
-
}
|
63
|
-
});
|
64
|
-
export {
|
65
|
-
inlineScriptId
|
66
|
-
};
|
67
|
-
//# sourceMappingURL=inline-script-id.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/utils/define-rule.ts","../../src/rules/inline-script-id.ts"],"sourcesContent":["import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n","import { defineRule } from \"../utils/define-rule.js\";\n\nconst url = \"https://nextjs.org/docs/messages/inline-script-id\";\n\nexport const inlineScriptId = defineRule({\n create: (context) => {\n let nextScriptImportName: null | string = null;\n\n return {\n ImportDeclaration: (node: any) => {\n if (node.source.value === \"next/script\") {\n nextScriptImportName = node.specifiers[0].local.name;\n }\n },\n JSXElement: (node: any) => {\n if (nextScriptImportName === null) {\n return;\n }\n\n if (\n node.openingElement?.name &&\n node.openingElement.name.name !== nextScriptImportName\n ) {\n return;\n }\n\n const attributeNames = new Set();\n\n let hasNonCheckableSpreadAttribute = false;\n node.openingElement.attributes.forEach((attribute: any) => {\n // Early return if we already have a non-checkable spread attribute, for better performance\n if (hasNonCheckableSpreadAttribute) {\n return;\n }\n\n if (attribute.type === \"JSXAttribute\") {\n attributeNames.add(attribute.name.name);\n } else if (attribute.type === \"JSXSpreadAttribute\") {\n if (attribute.argument?.properties) {\n attribute.argument.properties.forEach((property: any) => {\n attributeNames.add(property.key.name);\n });\n } else {\n // JSXSpreadAttribute without properties is not checkable\n hasNonCheckableSpreadAttribute = true;\n }\n }\n });\n\n // https://github.com/vercel/next.js/issues/34030\n // If there is a non-checkable spread attribute, we simply ignore them\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasNonCheckableSpreadAttribute) {\n return;\n }\n\n if (\n node.children.length > 0 ||\n attributeNames.has(\"dangerouslySetInnerHTML\")\n ) {\n if (!attributeNames.has(\"id\")) {\n context.report({\n message: `\\`next/script\\` components with inline content must specify an \\`id\\` attribute. See: ${url}`,\n node,\n });\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n \"Enforce `id` attribute on `next/script` components with inline content.\",\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n"],"mappings":";AAEO,IAAM,aAAa,CAAC,SAA2C;;;ACAtE,IAAM,MAAM;AAEL,IAAM,iBAAiB,WAAW;AAAA,EACvC,QAAQ,CAAC,YAAY;AACnB,QAAI,uBAAsC;AAE1C,WAAO;AAAA,MACL,mBAAmB,CAAC,SAAc;AAChC,YAAI,KAAK,OAAO,UAAU,eAAe;AACvC,iCAAuB,KAAK,WAAW,CAAC,EAAE,MAAM;AAAA,QAClD;AAAA,MACF;AAAA,MACA,YAAY,CAAC,SAAc;AACzB,YAAI,yBAAyB,MAAM;AACjC;AAAA,QACF;AAEA,YACE,KAAK,gBAAgB,QACrB,KAAK,eAAe,KAAK,SAAS,sBAClC;AACA;AAAA,QACF;AAEA,cAAM,iBAAiB,oBAAI,IAAI;AAE/B,YAAI,iCAAiC;AACrC,aAAK,eAAe,WAAW,QAAQ,CAAC,cAAmB;AAEzD,cAAI,gCAAgC;AAClC;AAAA,UACF;AAEA,cAAI,UAAU,SAAS,gBAAgB;AACrC,2BAAe,IAAI,UAAU,KAAK,IAAI;AAAA,UACxC,WAAW,UAAU,SAAS,sBAAsB;AAClD,gBAAI,UAAU,UAAU,YAAY;AAClC,wBAAU,SAAS,WAAW,QAAQ,CAAC,aAAkB;AACvD,+BAAe,IAAI,SAAS,IAAI,IAAI;AAAA,cACtC,CAAC;AAAA,YACH,OAAO;AAEL,+CAAiC;AAAA,YACnC;AAAA,UACF;AAAA,QACF,CAAC;AAKD,YAAI,gCAAgC;AAClC;AAAA,QACF;AAEA,YACE,KAAK,SAAS,SAAS,KACvB,eAAe,IAAI,yBAAyB,GAC5C;AACA,cAAI,CAAC,eAAe,IAAI,IAAI,GAAG;AAC7B,oBAAQ,OAAO;AAAA,cACb,SAAS,yFAAyF,GAAG;AAAA,cACrG;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,aACE;AAAA,MACF,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|
@@ -1,129 +0,0 @@
|
|
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
|
-
|
20
|
-
// src/rules/next-script-for-ga.ts
|
21
|
-
var next_script_for_ga_exports = {};
|
22
|
-
__export(next_script_for_ga_exports, {
|
23
|
-
nextScriptForGa: () => nextScriptForGa
|
24
|
-
});
|
25
|
-
module.exports = __toCommonJS(next_script_for_ga_exports);
|
26
|
-
|
27
|
-
// src/utils/define-rule.ts
|
28
|
-
var defineRule = (rule) => rule;
|
29
|
-
|
30
|
-
// src/utils/node-attributes.ts
|
31
|
-
var NodeAttributes = class {
|
32
|
-
attributes;
|
33
|
-
constructor(ASTnode) {
|
34
|
-
this.attributes = {};
|
35
|
-
ASTnode.attributes.forEach((attribute) => {
|
36
|
-
if (!attribute.type || attribute.type !== "JSXAttribute") {
|
37
|
-
return;
|
38
|
-
}
|
39
|
-
if (attribute.value) {
|
40
|
-
const value = typeof attribute.value.value === "string" ? attribute.value.value : typeof attribute.value.expression?.value !== "undefined" ? attribute.value.expression.value : attribute.value.expression?.properties;
|
41
|
-
this.attributes[attribute.name.name] = {
|
42
|
-
hasValue: true,
|
43
|
-
value
|
44
|
-
};
|
45
|
-
} else {
|
46
|
-
this.attributes[attribute.name.name] = {
|
47
|
-
hasValue: false
|
48
|
-
};
|
49
|
-
}
|
50
|
-
});
|
51
|
-
}
|
52
|
-
has(attrName) {
|
53
|
-
return Boolean(this.attributes[attrName]);
|
54
|
-
}
|
55
|
-
hasAny() {
|
56
|
-
return Boolean(Object.keys(this.attributes).length);
|
57
|
-
}
|
58
|
-
hasValue(attrName) {
|
59
|
-
return Boolean(this.attributes[attrName]?.hasValue);
|
60
|
-
}
|
61
|
-
value(attrName) {
|
62
|
-
const attr = this.attributes[attrName];
|
63
|
-
if (!attr) {
|
64
|
-
return true;
|
65
|
-
}
|
66
|
-
if ("hasValue" in attr && attr.hasValue) {
|
67
|
-
return attr.value;
|
68
|
-
}
|
69
|
-
return void 0;
|
70
|
-
}
|
71
|
-
};
|
72
|
-
|
73
|
-
// src/rules/next-script-for-ga.ts
|
74
|
-
var SUPPORTED_SRCS = [
|
75
|
-
"www.google-analytics.com/analytics.js",
|
76
|
-
"www.googletagmanager.com/gtag/js"
|
77
|
-
];
|
78
|
-
var SUPPORTED_HTML_CONTENT_URLS = [
|
79
|
-
"www.google-analytics.com/analytics.js",
|
80
|
-
"www.googletagmanager.com/gtm.js"
|
81
|
-
];
|
82
|
-
var description = "Prefer `next/script` component when using the inline script for Google Analytics.";
|
83
|
-
var url = "https://nextjs.org/docs/messages/next-script-for-ga";
|
84
|
-
var ERROR_MSG = `${description} See: ${url}`;
|
85
|
-
var containsStr = (str, strList) => {
|
86
|
-
return strList.some((s) => str.includes(s));
|
87
|
-
};
|
88
|
-
var nextScriptForGa = defineRule({
|
89
|
-
create: (context) => ({
|
90
|
-
JSXOpeningElement: (node) => {
|
91
|
-
if (node.name.name !== "script") {
|
92
|
-
return;
|
93
|
-
}
|
94
|
-
if (node.attributes.length === 0) {
|
95
|
-
return;
|
96
|
-
}
|
97
|
-
const attributes = new NodeAttributes(node);
|
98
|
-
if (typeof attributes.value("src") === "string" && containsStr(attributes.value("src"), SUPPORTED_SRCS)) {
|
99
|
-
return context.report({
|
100
|
-
message: ERROR_MSG,
|
101
|
-
node
|
102
|
-
});
|
103
|
-
}
|
104
|
-
if (attributes.value("dangerouslySetInnerHTML") && attributes.value("dangerouslySetInnerHTML").length > 0) {
|
105
|
-
const htmlContent = attributes.value("dangerouslySetInnerHTML")[0].value.quasis?.[0].value.raw;
|
106
|
-
if (htmlContent && containsStr(htmlContent, SUPPORTED_HTML_CONTENT_URLS)) {
|
107
|
-
context.report({
|
108
|
-
message: ERROR_MSG,
|
109
|
-
node
|
110
|
-
});
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
114
|
-
}),
|
115
|
-
meta: {
|
116
|
-
docs: {
|
117
|
-
description,
|
118
|
-
recommended: true,
|
119
|
-
url
|
120
|
-
},
|
121
|
-
schema: [],
|
122
|
-
type: "problem"
|
123
|
-
}
|
124
|
-
});
|
125
|
-
// Annotate the CommonJS export names for ESM import in node:
|
126
|
-
0 && (module.exports = {
|
127
|
-
nextScriptForGa
|
128
|
-
});
|
129
|
-
//# sourceMappingURL=next-script-for-ga.cjs.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/rules/next-script-for-ga.ts","../../src/utils/define-rule.ts","../../src/utils/node-attributes.ts"],"sourcesContent":["import { defineRule } from \"../utils/define-rule.js\";\nimport NodeAttributes from \"../utils/node-attributes.js\";\n\nconst SUPPORTED_SRCS = [\n \"www.google-analytics.com/analytics.js\",\n \"www.googletagmanager.com/gtag/js\",\n];\nconst SUPPORTED_HTML_CONTENT_URLS = [\n \"www.google-analytics.com/analytics.js\",\n \"www.googletagmanager.com/gtm.js\",\n];\nconst description =\n \"Prefer `next/script` component when using the inline script for Google Analytics.\";\nconst url = \"https://nextjs.org/docs/messages/next-script-for-ga\";\nconst ERROR_MSG = `${description} See: ${url}`;\n\n// Check if one of the items in the list is a substring of the passed string\nconst containsStr = (str: string, strList: string[]) => {\n return strList.some((s) => str.includes(s));\n};\n\nexport const nextScriptForGa = defineRule({\n create: (context: any) => ({\n JSXOpeningElement: (node: any) => {\n if (node.name.name !== \"script\") {\n return;\n }\n if (node.attributes.length === 0) {\n return;\n }\n const attributes = new NodeAttributes(node);\n\n // Check if the Alternative async tag is being used to add GA.\n // https://developers.google.com/analytics/devguides/collection/analyticsjs#alternative_async_tag\n // https://developers.google.com/analytics/devguides/collection/gtagjs\n if (\n typeof attributes.value(\"src\") === \"string\" &&\n containsStr(attributes.value(\"src\"), SUPPORTED_SRCS)\n ) {\n return context.report({\n message: ERROR_MSG,\n node,\n });\n }\n\n // Check if inline script is being used to add GA.\n // https://developers.google.com/analytics/devguides/collection/analyticsjs#the_google_analytics_tag\n // https://developers.google.com/tag-manager/quickstart\n if (\n attributes.value(\"dangerouslySetInnerHTML\") &&\n attributes.value(\"dangerouslySetInnerHTML\").length > 0\n ) {\n const htmlContent = attributes.value(\"dangerouslySetInnerHTML\")[0].value\n .quasis?.[0].value.raw;\n if (\n htmlContent &&\n containsStr(htmlContent, SUPPORTED_HTML_CONTENT_URLS)\n ) {\n context.report({\n message: ERROR_MSG,\n node,\n });\n }\n }\n },\n }),\n meta: {\n docs: {\n description,\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n","import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n","// Return attributes and values of a node in a convenient way:\n/* example: \n <ExampleElement attr1=\"15\" attr2>\n { attr1: {\n hasValue: true,\n value: 15\n },\n attr2: {\n hasValue: false\n }\nInclusion of hasValue is in case an eslint rule cares about boolean values\nexplicitly assigned to attribute vs the attribute being used as a flag\n*/\nexport default class NodeAttributes {\n attributes: Record<\n string,\n | {\n hasValue: true;\n value: any;\n }\n | {\n hasValue?: false;\n }\n >;\n\n constructor(ASTnode: any) {\n this.attributes = {};\n ASTnode.attributes.forEach((attribute: any) => {\n if (!attribute.type || attribute.type !== \"JSXAttribute\") {\n return;\n }\n\n if (attribute.value) {\n // hasValue\n const value =\n typeof attribute.value.value === \"string\" ? attribute.value.value\n : typeof attribute.value.expression?.value !== \"undefined\" ?\n attribute.value.expression.value\n : attribute.value.expression?.properties;\n\n this.attributes[attribute.name.name] = {\n hasValue: true,\n value,\n };\n } else {\n this.attributes[attribute.name.name] = {\n hasValue: false,\n };\n }\n });\n }\n\n has(attrName: string): boolean {\n return Boolean(this.attributes[attrName]);\n }\n\n hasAny(): boolean {\n return Boolean(Object.keys(this.attributes).length);\n }\n\n hasValue(attrName: string): boolean {\n return Boolean(this.attributes[attrName]?.hasValue);\n }\n\n value(attrName: string): any {\n const attr = this.attributes[attrName];\n\n if (!attr) {\n return true;\n }\n\n if (\"hasValue\" in attr && attr.hasValue) {\n return attr.value;\n }\n\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,aAAa,CAAC,SAA2C;;;ACWtE,IAAqB,iBAArB,MAAoC;AAAA,EAClC;AAAA,EAWA,YAAY,SAAc;AACxB,SAAK,aAAa,CAAC;AACnB,YAAQ,WAAW,QAAQ,CAAC,cAAmB;AAC7C,UAAI,CAAC,UAAU,QAAQ,UAAU,SAAS,gBAAgB;AACxD;AAAA,MACF;AAEA,UAAI,UAAU,OAAO;AAEnB,cAAM,QACJ,OAAO,UAAU,MAAM,UAAU,WAAW,UAAU,MAAM,QAC1D,OAAO,UAAU,MAAM,YAAY,UAAU,cAC7C,UAAU,MAAM,WAAW,QAC3B,UAAU,MAAM,YAAY;AAEhC,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAA2B;AAC7B,WAAO,QAAQ,KAAK,WAAW,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,SAAkB;AAChB,WAAO,QAAQ,OAAO,KAAK,KAAK,UAAU,EAAE,MAAM;AAAA,EACpD;AAAA,EAEA,SAAS,UAA2B;AAClC,WAAO,QAAQ,KAAK,WAAW,QAAQ,GAAG,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAM,UAAuB;AAC3B,UAAM,OAAO,KAAK,WAAW,QAAQ;AAErC,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,QAAQ,KAAK,UAAU;AACvC,aAAO,KAAK;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AACF;;;AF1EA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AACF;AACA,IAAM,8BAA8B;AAAA,EAClC;AAAA,EACA;AACF;AACA,IAAM,cACJ;AACF,IAAM,MAAM;AACZ,IAAM,YAAY,GAAG,WAAW,SAAS,GAAG;AAG5C,IAAM,cAAc,CAAC,KAAa,YAAsB;AACtD,SAAO,QAAQ,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;AAC5C;AAEO,IAAM,kBAAkB,WAAW;AAAA,EACxC,QAAQ,CAAC,aAAkB;AAAA,IACzB,mBAAmB,CAAC,SAAc;AAChC,UAAI,KAAK,KAAK,SAAS,UAAU;AAC/B;AAAA,MACF;AACA,UAAI,KAAK,WAAW,WAAW,GAAG;AAChC;AAAA,MACF;AACA,YAAM,aAAa,IAAI,eAAe,IAAI;AAK1C,UACE,OAAO,WAAW,MAAM,KAAK,MAAM,YACnC,YAAY,WAAW,MAAM,KAAK,GAAG,cAAc,GACnD;AACA,eAAO,QAAQ,OAAO;AAAA,UACpB,SAAS;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH;AAKA,UACE,WAAW,MAAM,yBAAyB,KAC1C,WAAW,MAAM,yBAAyB,EAAE,SAAS,GACrD;AACA,cAAM,cAAc,WAAW,MAAM,yBAAyB,EAAE,CAAC,EAAE,MAChE,SAAS,CAAC,EAAE,MAAM;AACrB,YACE,eACA,YAAY,aAAa,2BAA2B,GACpD;AACA,kBAAQ,OAAO;AAAA,YACb,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ;AAAA,MACA,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|
@@ -1,102 +0,0 @@
|
|
1
|
-
// src/utils/define-rule.ts
|
2
|
-
var defineRule = (rule) => rule;
|
3
|
-
|
4
|
-
// src/utils/node-attributes.ts
|
5
|
-
var NodeAttributes = class {
|
6
|
-
attributes;
|
7
|
-
constructor(ASTnode) {
|
8
|
-
this.attributes = {};
|
9
|
-
ASTnode.attributes.forEach((attribute) => {
|
10
|
-
if (!attribute.type || attribute.type !== "JSXAttribute") {
|
11
|
-
return;
|
12
|
-
}
|
13
|
-
if (attribute.value) {
|
14
|
-
const value = typeof attribute.value.value === "string" ? attribute.value.value : typeof attribute.value.expression?.value !== "undefined" ? attribute.value.expression.value : attribute.value.expression?.properties;
|
15
|
-
this.attributes[attribute.name.name] = {
|
16
|
-
hasValue: true,
|
17
|
-
value
|
18
|
-
};
|
19
|
-
} else {
|
20
|
-
this.attributes[attribute.name.name] = {
|
21
|
-
hasValue: false
|
22
|
-
};
|
23
|
-
}
|
24
|
-
});
|
25
|
-
}
|
26
|
-
has(attrName) {
|
27
|
-
return Boolean(this.attributes[attrName]);
|
28
|
-
}
|
29
|
-
hasAny() {
|
30
|
-
return Boolean(Object.keys(this.attributes).length);
|
31
|
-
}
|
32
|
-
hasValue(attrName) {
|
33
|
-
return Boolean(this.attributes[attrName]?.hasValue);
|
34
|
-
}
|
35
|
-
value(attrName) {
|
36
|
-
const attr = this.attributes[attrName];
|
37
|
-
if (!attr) {
|
38
|
-
return true;
|
39
|
-
}
|
40
|
-
if ("hasValue" in attr && attr.hasValue) {
|
41
|
-
return attr.value;
|
42
|
-
}
|
43
|
-
return void 0;
|
44
|
-
}
|
45
|
-
};
|
46
|
-
|
47
|
-
// src/rules/next-script-for-ga.ts
|
48
|
-
var SUPPORTED_SRCS = [
|
49
|
-
"www.google-analytics.com/analytics.js",
|
50
|
-
"www.googletagmanager.com/gtag/js"
|
51
|
-
];
|
52
|
-
var SUPPORTED_HTML_CONTENT_URLS = [
|
53
|
-
"www.google-analytics.com/analytics.js",
|
54
|
-
"www.googletagmanager.com/gtm.js"
|
55
|
-
];
|
56
|
-
var description = "Prefer `next/script` component when using the inline script for Google Analytics.";
|
57
|
-
var url = "https://nextjs.org/docs/messages/next-script-for-ga";
|
58
|
-
var ERROR_MSG = `${description} See: ${url}`;
|
59
|
-
var containsStr = (str, strList) => {
|
60
|
-
return strList.some((s) => str.includes(s));
|
61
|
-
};
|
62
|
-
var nextScriptForGa = defineRule({
|
63
|
-
create: (context) => ({
|
64
|
-
JSXOpeningElement: (node) => {
|
65
|
-
if (node.name.name !== "script") {
|
66
|
-
return;
|
67
|
-
}
|
68
|
-
if (node.attributes.length === 0) {
|
69
|
-
return;
|
70
|
-
}
|
71
|
-
const attributes = new NodeAttributes(node);
|
72
|
-
if (typeof attributes.value("src") === "string" && containsStr(attributes.value("src"), SUPPORTED_SRCS)) {
|
73
|
-
return context.report({
|
74
|
-
message: ERROR_MSG,
|
75
|
-
node
|
76
|
-
});
|
77
|
-
}
|
78
|
-
if (attributes.value("dangerouslySetInnerHTML") && attributes.value("dangerouslySetInnerHTML").length > 0) {
|
79
|
-
const htmlContent = attributes.value("dangerouslySetInnerHTML")[0].value.quasis?.[0].value.raw;
|
80
|
-
if (htmlContent && containsStr(htmlContent, SUPPORTED_HTML_CONTENT_URLS)) {
|
81
|
-
context.report({
|
82
|
-
message: ERROR_MSG,
|
83
|
-
node
|
84
|
-
});
|
85
|
-
}
|
86
|
-
}
|
87
|
-
}
|
88
|
-
}),
|
89
|
-
meta: {
|
90
|
-
docs: {
|
91
|
-
description,
|
92
|
-
recommended: true,
|
93
|
-
url
|
94
|
-
},
|
95
|
-
schema: [],
|
96
|
-
type: "problem"
|
97
|
-
}
|
98
|
-
});
|
99
|
-
export {
|
100
|
-
nextScriptForGa
|
101
|
-
};
|
102
|
-
//# sourceMappingURL=next-script-for-ga.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/utils/define-rule.ts","../../src/utils/node-attributes.ts","../../src/rules/next-script-for-ga.ts"],"sourcesContent":["import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n","// Return attributes and values of a node in a convenient way:\n/* example: \n <ExampleElement attr1=\"15\" attr2>\n { attr1: {\n hasValue: true,\n value: 15\n },\n attr2: {\n hasValue: false\n }\nInclusion of hasValue is in case an eslint rule cares about boolean values\nexplicitly assigned to attribute vs the attribute being used as a flag\n*/\nexport default class NodeAttributes {\n attributes: Record<\n string,\n | {\n hasValue: true;\n value: any;\n }\n | {\n hasValue?: false;\n }\n >;\n\n constructor(ASTnode: any) {\n this.attributes = {};\n ASTnode.attributes.forEach((attribute: any) => {\n if (!attribute.type || attribute.type !== \"JSXAttribute\") {\n return;\n }\n\n if (attribute.value) {\n // hasValue\n const value =\n typeof attribute.value.value === \"string\" ? attribute.value.value\n : typeof attribute.value.expression?.value !== \"undefined\" ?\n attribute.value.expression.value\n : attribute.value.expression?.properties;\n\n this.attributes[attribute.name.name] = {\n hasValue: true,\n value,\n };\n } else {\n this.attributes[attribute.name.name] = {\n hasValue: false,\n };\n }\n });\n }\n\n has(attrName: string): boolean {\n return Boolean(this.attributes[attrName]);\n }\n\n hasAny(): boolean {\n return Boolean(Object.keys(this.attributes).length);\n }\n\n hasValue(attrName: string): boolean {\n return Boolean(this.attributes[attrName]?.hasValue);\n }\n\n value(attrName: string): any {\n const attr = this.attributes[attrName];\n\n if (!attr) {\n return true;\n }\n\n if (\"hasValue\" in attr && attr.hasValue) {\n return attr.value;\n }\n\n return undefined;\n }\n}\n","import { defineRule } from \"../utils/define-rule.js\";\nimport NodeAttributes from \"../utils/node-attributes.js\";\n\nconst SUPPORTED_SRCS = [\n \"www.google-analytics.com/analytics.js\",\n \"www.googletagmanager.com/gtag/js\",\n];\nconst SUPPORTED_HTML_CONTENT_URLS = [\n \"www.google-analytics.com/analytics.js\",\n \"www.googletagmanager.com/gtm.js\",\n];\nconst description =\n \"Prefer `next/script` component when using the inline script for Google Analytics.\";\nconst url = \"https://nextjs.org/docs/messages/next-script-for-ga\";\nconst ERROR_MSG = `${description} See: ${url}`;\n\n// Check if one of the items in the list is a substring of the passed string\nconst containsStr = (str: string, strList: string[]) => {\n return strList.some((s) => str.includes(s));\n};\n\nexport const nextScriptForGa = defineRule({\n create: (context: any) => ({\n JSXOpeningElement: (node: any) => {\n if (node.name.name !== \"script\") {\n return;\n }\n if (node.attributes.length === 0) {\n return;\n }\n const attributes = new NodeAttributes(node);\n\n // Check if the Alternative async tag is being used to add GA.\n // https://developers.google.com/analytics/devguides/collection/analyticsjs#alternative_async_tag\n // https://developers.google.com/analytics/devguides/collection/gtagjs\n if (\n typeof attributes.value(\"src\") === \"string\" &&\n containsStr(attributes.value(\"src\"), SUPPORTED_SRCS)\n ) {\n return context.report({\n message: ERROR_MSG,\n node,\n });\n }\n\n // Check if inline script is being used to add GA.\n // https://developers.google.com/analytics/devguides/collection/analyticsjs#the_google_analytics_tag\n // https://developers.google.com/tag-manager/quickstart\n if (\n attributes.value(\"dangerouslySetInnerHTML\") &&\n attributes.value(\"dangerouslySetInnerHTML\").length > 0\n ) {\n const htmlContent = attributes.value(\"dangerouslySetInnerHTML\")[0].value\n .quasis?.[0].value.raw;\n if (\n htmlContent &&\n containsStr(htmlContent, SUPPORTED_HTML_CONTENT_URLS)\n ) {\n context.report({\n message: ERROR_MSG,\n node,\n });\n }\n }\n },\n }),\n meta: {\n docs: {\n description,\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n"],"mappings":";AAEO,IAAM,aAAa,CAAC,SAA2C;;;ACWtE,IAAqB,iBAArB,MAAoC;AAAA,EAClC;AAAA,EAWA,YAAY,SAAc;AACxB,SAAK,aAAa,CAAC;AACnB,YAAQ,WAAW,QAAQ,CAAC,cAAmB;AAC7C,UAAI,CAAC,UAAU,QAAQ,UAAU,SAAS,gBAAgB;AACxD;AAAA,MACF;AAEA,UAAI,UAAU,OAAO;AAEnB,cAAM,QACJ,OAAO,UAAU,MAAM,UAAU,WAAW,UAAU,MAAM,QAC1D,OAAO,UAAU,MAAM,YAAY,UAAU,cAC7C,UAAU,MAAM,WAAW,QAC3B,UAAU,MAAM,YAAY;AAEhC,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,WAAW,UAAU,KAAK,IAAI,IAAI;AAAA,UACrC,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAA2B;AAC7B,WAAO,QAAQ,KAAK,WAAW,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,SAAkB;AAChB,WAAO,QAAQ,OAAO,KAAK,KAAK,UAAU,EAAE,MAAM;AAAA,EACpD;AAAA,EAEA,SAAS,UAA2B;AAClC,WAAO,QAAQ,KAAK,WAAW,QAAQ,GAAG,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAM,UAAuB;AAC3B,UAAM,OAAO,KAAK,WAAW,QAAQ;AAErC,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,QAAQ,KAAK,UAAU;AACvC,aAAO,KAAK;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AACF;;;AC1EA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AACF;AACA,IAAM,8BAA8B;AAAA,EAClC;AAAA,EACA;AACF;AACA,IAAM,cACJ;AACF,IAAM,MAAM;AACZ,IAAM,YAAY,GAAG,WAAW,SAAS,GAAG;AAG5C,IAAM,cAAc,CAAC,KAAa,YAAsB;AACtD,SAAO,QAAQ,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;AAC5C;AAEO,IAAM,kBAAkB,WAAW;AAAA,EACxC,QAAQ,CAAC,aAAkB;AAAA,IACzB,mBAAmB,CAAC,SAAc;AAChC,UAAI,KAAK,KAAK,SAAS,UAAU;AAC/B;AAAA,MACF;AACA,UAAI,KAAK,WAAW,WAAW,GAAG;AAChC;AAAA,MACF;AACA,YAAM,aAAa,IAAI,eAAe,IAAI;AAK1C,UACE,OAAO,WAAW,MAAM,KAAK,MAAM,YACnC,YAAY,WAAW,MAAM,KAAK,GAAG,cAAc,GACnD;AACA,eAAO,QAAQ,OAAO;AAAA,UACpB,SAAS;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH;AAKA,UACE,WAAW,MAAM,yBAAyB,KAC1C,WAAW,MAAM,yBAAyB,EAAE,SAAS,GACrD;AACA,cAAM,cAAc,WAAW,MAAM,yBAAyB,EAAE,CAAC,EAAE,MAChE,SAAS,CAAC,EAAE,MAAM;AACrB,YACE,eACA,YAAY,aAAa,2BAA2B,GACpD;AACA,kBAAQ,OAAO;AAAA,YACb,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ;AAAA,MACA,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|
@@ -1,64 +0,0 @@
|
|
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
|
-
|
20
|
-
// src/rules/no-assign-module-variable.ts
|
21
|
-
var no_assign_module_variable_exports = {};
|
22
|
-
__export(no_assign_module_variable_exports, {
|
23
|
-
noAssignModuleVariable: () => noAssignModuleVariable
|
24
|
-
});
|
25
|
-
module.exports = __toCommonJS(no_assign_module_variable_exports);
|
26
|
-
|
27
|
-
// src/utils/define-rule.ts
|
28
|
-
var defineRule = (rule) => rule;
|
29
|
-
|
30
|
-
// src/rules/no-assign-module-variable.ts
|
31
|
-
var url = "https://nextjs.org/docs/messages/no-assign-module-variable";
|
32
|
-
var noAssignModuleVariable = defineRule({
|
33
|
-
create: (context) => ({
|
34
|
-
VariableDeclaration: (node) => {
|
35
|
-
const moduleVariableFound = node.declarations.some((declaration) => {
|
36
|
-
if ("name" in declaration.id) {
|
37
|
-
return declaration.id.name === "module";
|
38
|
-
}
|
39
|
-
return false;
|
40
|
-
});
|
41
|
-
if (!moduleVariableFound) {
|
42
|
-
return;
|
43
|
-
}
|
44
|
-
context.report({
|
45
|
-
message: `Do not assign to the variable \`module\`. See: ${url}`,
|
46
|
-
node
|
47
|
-
});
|
48
|
-
}
|
49
|
-
}),
|
50
|
-
meta: {
|
51
|
-
docs: {
|
52
|
-
description: "Prevent assignment to the `module` variable.",
|
53
|
-
recommended: true,
|
54
|
-
url
|
55
|
-
},
|
56
|
-
schema: [],
|
57
|
-
type: "problem"
|
58
|
-
}
|
59
|
-
});
|
60
|
-
// Annotate the CommonJS export names for ESM import in node:
|
61
|
-
0 && (module.exports = {
|
62
|
-
noAssignModuleVariable
|
63
|
-
});
|
64
|
-
//# sourceMappingURL=no-assign-module-variable.cjs.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../src/rules/no-assign-module-variable.ts","../../src/utils/define-rule.ts"],"sourcesContent":["import { defineRule } from \"../utils/define-rule.js\";\nconst url = \"https://nextjs.org/docs/messages/no-assign-module-variable\";\n\nexport const noAssignModuleVariable = defineRule({\n create: (context: any) => ({\n VariableDeclaration: (node: any) => {\n // Checks node.declarations array for variable with id.name of `module`\n const moduleVariableFound = node.declarations.some((declaration: any) => {\n if (\"name\" in declaration.id) {\n return declaration.id.name === \"module\";\n }\n return false;\n });\n\n // Return early if no `module` variable is found\n if (!moduleVariableFound) {\n return;\n }\n\n context.report({\n message: `Do not assign to the variable \\`module\\`. See: ${url}`,\n node,\n });\n },\n }),\n\n meta: {\n docs: {\n description: \"Prevent assignment to the `module` variable.\",\n recommended: true,\n url,\n },\n schema: [],\n type: \"problem\",\n },\n});\n","import type { Rule } from \"eslint\";\n\nexport const defineRule = (rule: Rule.RuleModule): Rule.RuleModule => rule;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,aAAa,CAAC,SAA2C;;;ADDtE,IAAM,MAAM;AAEL,IAAM,yBAAyB,WAAW;AAAA,EAC/C,QAAQ,CAAC,aAAkB;AAAA,IACzB,qBAAqB,CAAC,SAAc;AAElC,YAAM,sBAAsB,KAAK,aAAa,KAAK,CAAC,gBAAqB;AACvE,YAAI,UAAU,YAAY,IAAI;AAC5B,iBAAO,YAAY,GAAG,SAAS;AAAA,QACjC;AACA,eAAO;AAAA,MACT,CAAC;AAGD,UAAI,CAAC,qBAAqB;AACxB;AAAA,MACF;AAEA,cAAQ,OAAO;AAAA,QACb,SAAS,kDAAkD,GAAG;AAAA,QAC9D;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,aAAa;AAAA,MACb,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF,CAAC;","names":[]}
|