@saasmakers/eslint 1.0.27 → 1.0.28

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.
@@ -10872,6 +10872,7 @@ const eslint_config = antfu__default(
10872
10872
  "saasmakers/ts-format-tests": "error",
10873
10873
  "saasmakers/vue-format-i18n": ["error", { locales: shared.localeCodes }],
10874
10874
  "saasmakers/vue-format-script": "error",
10875
+ "saasmakers/vue-format-style": "error",
10875
10876
  "saasmakers/vue-format-template": "error"
10876
10877
  }
10877
10878
  },
@@ -152,6 +152,7 @@ var eslint_config = antfu(
152
152
  "saasmakers/ts-format-tests": "error",
153
153
  "saasmakers/vue-format-i18n": ["error", { locales: localeCodes }],
154
154
  "saasmakers/vue-format-script": "error",
155
+ "saasmakers/vue-format-style": "error",
155
156
  "saasmakers/vue-format-template": "error"
156
157
  }
157
158
  },
@@ -152,6 +152,7 @@ var eslint_config = antfu(
152
152
  "saasmakers/ts-format-tests": "error",
153
153
  "saasmakers/vue-format-i18n": ["error", { locales: localeCodes }],
154
154
  "saasmakers/vue-format-script": "error",
155
+ "saasmakers/vue-format-style": "error",
155
156
  "saasmakers/vue-format-template": "error"
156
157
  }
157
158
  },
@@ -152,6 +152,7 @@ var eslint_config = antfu(
152
152
  "saasmakers/ts-format-tests": "error",
153
153
  "saasmakers/vue-format-i18n": ["error", { locales: localeCodes }],
154
154
  "saasmakers/vue-format-script": "error",
155
+ "saasmakers/vue-format-style": "error",
155
156
  "saasmakers/vue-format-template": "error"
156
157
  }
157
158
  },
@@ -10846,6 +10846,7 @@ const eslint_config = antfu(
10846
10846
  "saasmakers/ts-format-tests": "error",
10847
10847
  "saasmakers/vue-format-i18n": ["error", { locales: localeCodes }],
10848
10848
  "saasmakers/vue-format-script": "error",
10849
+ "saasmakers/vue-format-style": "error",
10849
10850
  "saasmakers/vue-format-template": "error"
10850
10851
  }
10851
10852
  },
package/dist/index.cjs CHANGED
@@ -253,7 +253,7 @@ function isThisReceiver(node) {
253
253
  function isVoidExpression(expression) {
254
254
  return expression.type === index$1.distExports.AST_NODE_TYPES.UnaryExpression && expression.operator === "void";
255
255
  }
256
- const rule$4 = {
256
+ const rule$5 = {
257
257
  defaultOptions: [{}],
258
258
  meta: {
259
259
  docs: { description: "Format TypeScript layout: single/multiline ternaries and union types, and blank lines between statements" },
@@ -563,7 +563,7 @@ function isTeardownStatement(statement) {
563
563
  }
564
564
  return false;
565
565
  }
566
- const rule$3 = {
566
+ const rule$4 = {
567
567
  defaultOptions: [],
568
568
  meta: {
569
569
  docs: { description: "Enforce sorted test functions and setup-before-assertions layout in test bodies" },
@@ -804,7 +804,7 @@ function checkUnusedStrings(context, parsed, source, content, contentOffset) {
804
804
  }
805
805
  }
806
806
  }
807
- const rule$2 = {
807
+ const rule$3 = {
808
808
  defaultOptions: [{ locales: defaultLocales }],
809
809
  meta: {
810
810
  docs: { description: "Format Vue i18n blocks: enforce valid/consistent locales, sorted keys, and no unused strings" },
@@ -872,7 +872,7 @@ const rule$2 = {
872
872
  };
873
873
 
874
874
  const untypedEmitsRegex = /const\s+emit\s*=\s*defineEmits\(\[([^\]]+)\]\)/g;
875
- const rule$1 = {
875
+ const rule$2 = {
876
876
  defaultOptions: [],
877
877
  meta: {
878
878
  docs: { description: "Format Vue component scripts: enforce multiline computed properties and typed emits" },
@@ -940,6 +940,42 @@ ${typedEvents}
940
940
  }
941
941
  };
942
942
 
943
+ const styleOpenTagRegex = /<style(?:\s[^>]*)?>/gi;
944
+ const rule$1 = {
945
+ defaultOptions: [],
946
+ meta: {
947
+ docs: { description: "Disallow <style> blocks in Vue SFCs. Styling must be done with Tailwind utility classes as much as possible." },
948
+ messages: { noStyleBlock: "Avoid <style> blocks in Vue components. Use Tailwind utility classes instead." },
949
+ schema: [],
950
+ type: "problem"
951
+ },
952
+ create(context) {
953
+ if (!context.filename.endsWith(".vue")) {
954
+ return {};
955
+ }
956
+ return {
957
+ Program() {
958
+ const sourceCode = context.sourceCode;
959
+ const source = sourceCode.getText();
960
+ styleOpenTagRegex.lastIndex = 0;
961
+ let styleMatch = styleOpenTagRegex.exec(source);
962
+ while (styleMatch !== null) {
963
+ const matchIndex = styleMatch.index;
964
+ const matchEnd = matchIndex + styleMatch[0].length;
965
+ context.report({
966
+ loc: {
967
+ end: sourceCode.getLocFromIndex(matchEnd),
968
+ start: sourceCode.getLocFromIndex(matchIndex)
969
+ },
970
+ messageId: "noStyleBlock"
971
+ });
972
+ styleMatch = styleOpenTagRegex.exec(source);
973
+ }
974
+ }
975
+ };
976
+ }
977
+ };
978
+
943
979
  const templateRegex = /<template>([\s\S]*)<\/template>/i;
944
980
  const templateTagLength = "<template>".length;
945
981
  const propsPrefixRegex = /\$?props\.(\w+)/g;
@@ -1217,10 +1253,11 @@ const rule = {
1217
1253
 
1218
1254
  const index = {
1219
1255
  rules: {
1220
- "ts-format-layout": rule$4,
1221
- "ts-format-tests": rule$3,
1222
- "vue-format-i18n": rule$2,
1223
- "vue-format-script": rule$1,
1256
+ "ts-format-layout": rule$5,
1257
+ "ts-format-tests": rule$4,
1258
+ "vue-format-i18n": rule$3,
1259
+ "vue-format-script": rule$2,
1260
+ "vue-format-style": rule$1,
1224
1261
  "vue-format-template": rule
1225
1262
  }
1226
1263
  };
package/dist/index.d.cts CHANGED
@@ -5203,6 +5203,7 @@ declare const _default: {
5203
5203
  locales?: string[];
5204
5204
  } | undefined)?], unknown, RuleListener>;
5205
5205
  'vue-format-script': RuleModule<"multilineComputed" | "untypedEmits", [], unknown, RuleListener>;
5206
+ 'vue-format-style': RuleModule<"noStyleBlock", [], unknown, RuleListener>;
5206
5207
  'vue-format-template': RuleModule<"dynamicClassMustBeObject" | "eventHandlerMustBeFunction" | "multilineClassObject" | "noPropsPrefix" | "prefixEventHandlerWithOn" | "removeTrueAttribute" | "singleLineClassObject" | "useT", [], unknown, RuleListener>;
5207
5208
  };
5208
5209
  };
package/dist/index.d.mts CHANGED
@@ -5203,6 +5203,7 @@ declare const _default: {
5203
5203
  locales?: string[];
5204
5204
  } | undefined)?], unknown, RuleListener>;
5205
5205
  'vue-format-script': RuleModule<"multilineComputed" | "untypedEmits", [], unknown, RuleListener>;
5206
+ 'vue-format-style': RuleModule<"noStyleBlock", [], unknown, RuleListener>;
5206
5207
  'vue-format-template': RuleModule<"dynamicClassMustBeObject" | "eventHandlerMustBeFunction" | "multilineClassObject" | "noPropsPrefix" | "prefixEventHandlerWithOn" | "removeTrueAttribute" | "singleLineClassObject" | "useT", [], unknown, RuleListener>;
5207
5208
  };
5208
5209
  };
package/dist/index.d.ts CHANGED
@@ -5203,6 +5203,7 @@ declare const _default: {
5203
5203
  locales?: string[];
5204
5204
  } | undefined)?], unknown, RuleListener>;
5205
5205
  'vue-format-script': RuleModule<"multilineComputed" | "untypedEmits", [], unknown, RuleListener>;
5206
+ 'vue-format-style': RuleModule<"noStyleBlock", [], unknown, RuleListener>;
5206
5207
  'vue-format-template': RuleModule<"dynamicClassMustBeObject" | "eventHandlerMustBeFunction" | "multilineClassObject" | "noPropsPrefix" | "prefixEventHandlerWithOn" | "removeTrueAttribute" | "singleLineClassObject" | "useT", [], unknown, RuleListener>;
5207
5208
  };
5208
5209
  };
package/dist/index.mjs CHANGED
@@ -251,7 +251,7 @@ function isThisReceiver(node) {
251
251
  function isVoidExpression(expression) {
252
252
  return expression.type === distExports.AST_NODE_TYPES.UnaryExpression && expression.operator === "void";
253
253
  }
254
- const rule$4 = {
254
+ const rule$5 = {
255
255
  defaultOptions: [{}],
256
256
  meta: {
257
257
  docs: { description: "Format TypeScript layout: single/multiline ternaries and union types, and blank lines between statements" },
@@ -561,7 +561,7 @@ function isTeardownStatement(statement) {
561
561
  }
562
562
  return false;
563
563
  }
564
- const rule$3 = {
564
+ const rule$4 = {
565
565
  defaultOptions: [],
566
566
  meta: {
567
567
  docs: { description: "Enforce sorted test functions and setup-before-assertions layout in test bodies" },
@@ -802,7 +802,7 @@ function checkUnusedStrings(context, parsed, source, content, contentOffset) {
802
802
  }
803
803
  }
804
804
  }
805
- const rule$2 = {
805
+ const rule$3 = {
806
806
  defaultOptions: [{ locales: defaultLocales }],
807
807
  meta: {
808
808
  docs: { description: "Format Vue i18n blocks: enforce valid/consistent locales, sorted keys, and no unused strings" },
@@ -870,7 +870,7 @@ const rule$2 = {
870
870
  };
871
871
 
872
872
  const untypedEmitsRegex = /const\s+emit\s*=\s*defineEmits\(\[([^\]]+)\]\)/g;
873
- const rule$1 = {
873
+ const rule$2 = {
874
874
  defaultOptions: [],
875
875
  meta: {
876
876
  docs: { description: "Format Vue component scripts: enforce multiline computed properties and typed emits" },
@@ -938,6 +938,42 @@ ${typedEvents}
938
938
  }
939
939
  };
940
940
 
941
+ const styleOpenTagRegex = /<style(?:\s[^>]*)?>/gi;
942
+ const rule$1 = {
943
+ defaultOptions: [],
944
+ meta: {
945
+ docs: { description: "Disallow <style> blocks in Vue SFCs. Styling must be done with Tailwind utility classes as much as possible." },
946
+ messages: { noStyleBlock: "Avoid <style> blocks in Vue components. Use Tailwind utility classes instead." },
947
+ schema: [],
948
+ type: "problem"
949
+ },
950
+ create(context) {
951
+ if (!context.filename.endsWith(".vue")) {
952
+ return {};
953
+ }
954
+ return {
955
+ Program() {
956
+ const sourceCode = context.sourceCode;
957
+ const source = sourceCode.getText();
958
+ styleOpenTagRegex.lastIndex = 0;
959
+ let styleMatch = styleOpenTagRegex.exec(source);
960
+ while (styleMatch !== null) {
961
+ const matchIndex = styleMatch.index;
962
+ const matchEnd = matchIndex + styleMatch[0].length;
963
+ context.report({
964
+ loc: {
965
+ end: sourceCode.getLocFromIndex(matchEnd),
966
+ start: sourceCode.getLocFromIndex(matchIndex)
967
+ },
968
+ messageId: "noStyleBlock"
969
+ });
970
+ styleMatch = styleOpenTagRegex.exec(source);
971
+ }
972
+ }
973
+ };
974
+ }
975
+ };
976
+
941
977
  const templateRegex = /<template>([\s\S]*)<\/template>/i;
942
978
  const templateTagLength = "<template>".length;
943
979
  const propsPrefixRegex = /\$?props\.(\w+)/g;
@@ -1215,10 +1251,11 @@ const rule = {
1215
1251
 
1216
1252
  const index = {
1217
1253
  rules: {
1218
- "ts-format-layout": rule$4,
1219
- "ts-format-tests": rule$3,
1220
- "vue-format-i18n": rule$2,
1221
- "vue-format-script": rule$1,
1254
+ "ts-format-layout": rule$5,
1255
+ "ts-format-tests": rule$4,
1256
+ "vue-format-i18n": rule$3,
1257
+ "vue-format-script": rule$2,
1258
+ "vue-format-style": rule$1,
1222
1259
  "vue-format-template": rule
1223
1260
  }
1224
1261
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasmakers/eslint",
3
- "version": "1.0.27",
3
+ "version": "1.0.28",
4
4
  "private": false,
5
5
  "description": "Shared ESLint config and rules for SaaS Makers projects",
6
6
  "license": "MIT",