uilint-eslint 0.2.101 → 0.2.103

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/dist/index.d.ts CHANGED
@@ -805,6 +805,16 @@ declare const rules: {
805
805
  } | undefined)?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
806
806
  name: string;
807
807
  };
808
+ "no-unsafe-type-casts": _typescript_eslint_utils_ts_eslint.RuleModule<"noAsAny" | "noAsUnknown" | "noDoubleCast" | "noLegacyAsAny" | "noLegacyAsUnknown", [{
809
+ reportAsAny?: boolean;
810
+ reportAsUnknown?: boolean;
811
+ reportDoubleCast?: boolean;
812
+ allowInTestFiles?: boolean;
813
+ allowInCatchBlocks?: boolean;
814
+ allowedTypes?: string[];
815
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
816
+ name: string;
817
+ };
808
818
  };
809
819
  /**
810
820
  * Plugin metadata
@@ -948,6 +958,16 @@ declare const plugin: {
948
958
  } | undefined)?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
949
959
  name: string;
950
960
  };
961
+ "no-unsafe-type-casts": _typescript_eslint_utils_ts_eslint.RuleModule<"noAsAny" | "noAsUnknown" | "noDoubleCast" | "noLegacyAsAny" | "noLegacyAsUnknown", [{
962
+ reportAsAny?: boolean;
963
+ reportAsUnknown?: boolean;
964
+ reportDoubleCast?: boolean;
965
+ allowInTestFiles?: boolean;
966
+ allowInCatchBlocks?: boolean;
967
+ allowedTypes?: string[];
968
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
969
+ name: string;
970
+ };
951
971
  };
952
972
  };
953
973
  /**
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ import { ESLintUtils } from "@typescript-eslint/utils";
3
3
  var createRule = ESLintUtils.RuleCreator(
4
4
  (name) => `https://github.com/peter-suggate/uilint/blob/main/packages/uilint-eslint/docs/rules/${name}.md`
5
5
  );
6
- function defineRuleMeta(meta17) {
7
- return meta17;
6
+ function defineRuleMeta(meta18) {
7
+ return meta18;
8
8
  }
9
9
 
10
10
  // src/rules/consistent-dark-mode.ts
@@ -4197,8 +4197,8 @@ function loadIndex(projectRoot, indexPath) {
4197
4197
  log(`Loaded metadata.json: ${Object.keys(entries).length} entries`);
4198
4198
  const metadataStore = /* @__PURE__ */ new Map();
4199
4199
  const fileToChunks = /* @__PURE__ */ new Map();
4200
- for (const [id, meta17] of Object.entries(entries)) {
4201
- const m = meta17;
4200
+ for (const [id, meta18] of Object.entries(entries)) {
4201
+ const m = meta18;
4202
4202
  metadataStore.set(id, {
4203
4203
  filePath: m.filePath,
4204
4204
  startLine: m.startLine,
@@ -4302,9 +4302,9 @@ function findSimilarChunks(index, chunkId, threshold) {
4302
4302
  const sortedAll = allScores.sort((a, b) => b.score - a.score).slice(0, 10);
4303
4303
  log(` Top 10 similarity scores (threshold=${threshold}):`);
4304
4304
  for (const { id, score } of sortedAll) {
4305
- const meta17 = index.metadataStore.get(id);
4305
+ const meta18 = index.metadataStore.get(id);
4306
4306
  const meetsThreshold = score >= threshold ? "\u2713" : "\u2717";
4307
- log(` ${meetsThreshold} ${(score * 100).toFixed(1)}% - ${id} (${meta17?.name || "anonymous"} in ${meta17?.filePath})`);
4307
+ log(` ${meetsThreshold} ${(score * 100).toFixed(1)}% - ${id} (${meta18?.name || "anonymous"} in ${meta18?.filePath})`);
4308
4308
  }
4309
4309
  log(` Found ${results.length} chunks above threshold`);
4310
4310
  return results.sort((a, b) => b.score - a.score);
@@ -4395,20 +4395,20 @@ var no_semantic_duplicates_default = createRule({
4395
4395
  log(` Chunk ${chunkId} already reported, skipping`);
4396
4396
  continue;
4397
4397
  }
4398
- const meta17 = index.metadataStore.get(chunkId);
4399
- if (!meta17) {
4398
+ const meta18 = index.metadataStore.get(chunkId);
4399
+ if (!meta18) {
4400
4400
  log(` No metadata for chunk ${chunkId}`);
4401
4401
  continue;
4402
4402
  }
4403
- log(` Checking chunk ${chunkId}: lines ${meta17.startLine}-${meta17.endLine} (node at line ${nodeLine})`);
4404
- if (nodeLine >= meta17.startLine && nodeLine <= meta17.endLine) {
4403
+ log(` Checking chunk ${chunkId}: lines ${meta18.startLine}-${meta18.endLine} (node at line ${nodeLine})`);
4404
+ if (nodeLine >= meta18.startLine && nodeLine <= meta18.endLine) {
4405
4405
  log(` Node is within chunk range, searching for similar chunks...`);
4406
4406
  const similar = findSimilarChunks(index, chunkId, threshold);
4407
4407
  if (similar.length > 0) {
4408
4408
  const best = similar[0];
4409
4409
  const bestMeta = index.metadataStore.get(best.id);
4410
4410
  if (bestMeta) {
4411
- const chunkLines = meta17.endLine - meta17.startLine + 1;
4411
+ const chunkLines = meta18.endLine - meta18.startLine + 1;
4412
4412
  if (chunkLines < minLines) {
4413
4413
  log(` Skipping: chunk has ${chunkLines} lines, below minLines=${minLines}`);
4414
4414
  continue;
@@ -4418,8 +4418,8 @@ var no_semantic_duplicates_default = createRule({
4418
4418
  const similarity = Math.round(best.score * 100);
4419
4419
  const sourceCode = extractCodeFromFile(
4420
4420
  filename,
4421
- meta17.startLine,
4422
- meta17.endLine
4421
+ meta18.startLine,
4422
+ meta18.endLine
4423
4423
  );
4424
4424
  const targetAbsolutePath = join6(projectRoot, bestMeta.filePath);
4425
4425
  const targetCode = extractCodeFromFile(
@@ -4427,17 +4427,17 @@ var no_semantic_duplicates_default = createRule({
4427
4427
  bestMeta.startLine,
4428
4428
  bestMeta.endLine
4429
4429
  );
4430
- log(` REPORTING: ${meta17.kind} '${name || meta17.name}' is ${similarity}% similar to '${bestMeta.name}' at ${relPath}:${bestMeta.startLine}`);
4430
+ log(` REPORTING: ${meta18.kind} '${name || meta18.name}' is ${similarity}% similar to '${bestMeta.name}' at ${relPath}:${bestMeta.startLine}`);
4431
4431
  context.report({
4432
4432
  node,
4433
4433
  loc: {
4434
- start: { line: meta17.startLine, column: meta17.startColumn },
4435
- end: { line: meta17.endLine, column: meta17.endColumn }
4434
+ start: { line: meta18.startLine, column: meta18.startColumn },
4435
+ end: { line: meta18.endLine, column: meta18.endColumn }
4436
4436
  },
4437
4437
  messageId: "semanticDuplicate",
4438
4438
  data: {
4439
- kind: meta17.kind,
4440
- name: name || meta17.name || "(anonymous)",
4439
+ kind: meta18.kind,
4440
+ name: name || meta18.name || "(anonymous)",
4441
4441
  similarity: String(similarity),
4442
4442
  otherName: bestMeta.name || "(anonymous)",
4443
4443
  otherLocation: `${relPath}:${bestMeta.startLine}`,
@@ -4446,10 +4446,10 @@ var no_semantic_duplicates_default = createRule({
4446
4446
  targetCode: targetCode || "",
4447
4447
  sourceLocation: JSON.stringify({
4448
4448
  filePath: relativeFilename,
4449
- startLine: meta17.startLine,
4450
- endLine: meta17.endLine,
4451
- startColumn: meta17.startColumn,
4452
- endColumn: meta17.endColumn
4449
+ startLine: meta18.startLine,
4450
+ endLine: meta18.endLine,
4451
+ startColumn: meta18.startColumn,
4452
+ endColumn: meta18.endColumn
4453
4453
  }),
4454
4454
  targetLocation: JSON.stringify({
4455
4455
  filePath: bestMeta.filePath,
@@ -4459,7 +4459,7 @@ var no_semantic_duplicates_default = createRule({
4459
4459
  startColumn: bestMeta.startColumn,
4460
4460
  endColumn: bestMeta.endColumn
4461
4461
  }),
4462
- sourceName: name || meta17.name || "(anonymous)",
4462
+ sourceName: name || meta18.name || "(anonymous)",
4463
4463
  targetName: bestMeta.name || "(anonymous)",
4464
4464
  similarityScore: String(best.score)
4465
4465
  }
@@ -4469,7 +4469,7 @@ var no_semantic_duplicates_default = createRule({
4469
4469
  log(` No similar chunks found above threshold`);
4470
4470
  }
4471
4471
  } else {
4472
- log(` Node line ${nodeLine} not in chunk range ${meta17.startLine}-${meta17.endLine}`);
4472
+ log(` Node line ${nodeLine} not in chunk range ${meta18.startLine}-${meta18.endLine}`);
4473
4473
  }
4474
4474
  }
4475
4475
  }
@@ -6830,6 +6830,379 @@ var prefer_tailwind_default = createRule({
6830
6830
  }
6831
6831
  });
6832
6832
 
6833
+ // src/rules/no-unsafe-type-casts.ts
6834
+ var meta16 = defineRuleMeta({
6835
+ id: "no-unsafe-type-casts",
6836
+ version: "1.0.0",
6837
+ name: "No Unsafe Type Casts",
6838
+ description: "Disallow unsafe type casting patterns that bypass TypeScript's type system",
6839
+ defaultSeverity: "error",
6840
+ category: "static",
6841
+ icon: "\u{1F6E1}\uFE0F",
6842
+ hint: "Prevents type system circumvention via casts",
6843
+ defaultEnabled: true,
6844
+ defaultOptions: [
6845
+ {
6846
+ reportAsAny: true,
6847
+ reportAsUnknown: false,
6848
+ reportDoubleCast: true,
6849
+ allowInTestFiles: true,
6850
+ allowInCatchBlocks: true,
6851
+ allowedTypes: []
6852
+ }
6853
+ ],
6854
+ optionSchema: {
6855
+ fields: [
6856
+ {
6857
+ key: "reportAsAny",
6858
+ label: "Report 'as any' casts",
6859
+ type: "boolean",
6860
+ defaultValue: true,
6861
+ description: "Flag expressions like `value as any`"
6862
+ },
6863
+ {
6864
+ key: "reportAsUnknown",
6865
+ label: "Report 'as unknown' casts",
6866
+ type: "boolean",
6867
+ defaultValue: false,
6868
+ description: "Flag expressions like `value as unknown`"
6869
+ },
6870
+ {
6871
+ key: "reportDoubleCast",
6872
+ label: "Report double-cast patterns",
6873
+ type: "boolean",
6874
+ defaultValue: true,
6875
+ description: "Flag expressions like `value as unknown as Type`"
6876
+ },
6877
+ {
6878
+ key: "allowInTestFiles",
6879
+ label: "Allow in test files",
6880
+ type: "boolean",
6881
+ defaultValue: true,
6882
+ description: "Skip reporting in *.test.ts, *.spec.ts, and __tests__/* files"
6883
+ },
6884
+ {
6885
+ key: "allowInCatchBlocks",
6886
+ label: "Allow in catch blocks",
6887
+ type: "boolean",
6888
+ defaultValue: true,
6889
+ description: "Allow type casts inside catch blocks for error handling"
6890
+ },
6891
+ {
6892
+ key: "allowedTypes",
6893
+ label: "Allowed target types",
6894
+ type: "text",
6895
+ defaultValue: "",
6896
+ placeholder: "HTMLElement, Error, Event",
6897
+ description: "Comma-separated list of type names that are allowed as cast targets"
6898
+ }
6899
+ ]
6900
+ },
6901
+ docs: `
6902
+ ## What it does
6903
+
6904
+ Detects and prevents unsafe type casting patterns in TypeScript that bypass
6905
+ the type system. These patterns can introduce runtime errors by lying to the
6906
+ compiler about types.
6907
+
6908
+ ### Detected Patterns
6909
+
6910
+ | Pattern | Risk | Description |
6911
+ |---------|------|-------------|
6912
+ | \`x as any\` | High | Completely disables type checking |
6913
+ | \`x as unknown as T\` | High | Forces incompatible type conversion |
6914
+ | \`x as unknown\` | Medium | Casts to unknown without narrowing |
6915
+ | \`<any>x\` | High | Legacy syntax equivalent to \`as any\` |
6916
+
6917
+ ## Why it's useful
6918
+
6919
+ - **Type Safety**: Catches type system circumvention that leads to runtime errors
6920
+ - **Code Quality**: Encourages proper type guards and runtime validation
6921
+ - **Maintainability**: Makes type assumptions explicit and verifiable
6922
+ - **Refactoring**: Prevents hidden type mismatches that break during refactors
6923
+
6924
+ ## Examples
6925
+
6926
+ ### \u274C Incorrect
6927
+
6928
+ \`\`\`typescript
6929
+ // Casting to any - bypasses all type checking
6930
+ const data = response.data as any;
6931
+ data.nonExistentMethod(); // No error, but crashes at runtime
6932
+
6933
+ // Double-cast pattern - forces incompatible types
6934
+ const user = jsonData as unknown as User;
6935
+ console.log(user.email); // Might be undefined!
6936
+
6937
+ // Legacy angle-bracket syntax
6938
+ const element = <any>document.getElementById("app");
6939
+ \`\`\`
6940
+
6941
+ ### \u2705 Correct
6942
+
6943
+ \`\`\`typescript
6944
+ // Use runtime validation (Zod, io-ts, etc.)
6945
+ const user = UserSchema.parse(jsonData);
6946
+ console.log(user.email); // Type-safe!
6947
+
6948
+ // Use type guards
6949
+ function isUser(data: unknown): data is User {
6950
+ return typeof data === "object" && data !== null && "email" in data;
6951
+ }
6952
+
6953
+ if (isUser(jsonData)) {
6954
+ console.log(jsonData.email); // Narrowed to User
6955
+ }
6956
+
6957
+ // Proper DOM type assertions (allowed by default)
6958
+ const input = document.getElementById("email") as HTMLInputElement;
6959
+
6960
+ // Safe cast with validation
6961
+ const error = err instanceof Error ? err : new Error(String(err));
6962
+ \`\`\`
6963
+
6964
+ ## Configuration
6965
+
6966
+ \`\`\`js
6967
+ // eslint.config.js
6968
+ "uilint/no-unsafe-type-casts": ["error", {
6969
+ reportAsAny: true, // Flag 'as any' casts
6970
+ reportAsUnknown: false, // Don't flag 'as unknown' alone
6971
+ reportDoubleCast: true, // Flag 'as unknown as T' patterns
6972
+ allowInTestFiles: true, // Allow in test files
6973
+ allowInCatchBlocks: true, // Allow error handling casts
6974
+ allowedTypes: [ // Types that are safe to cast to
6975
+ "HTMLElement",
6976
+ "HTMLInputElement",
6977
+ "HTMLButtonElement",
6978
+ "Error",
6979
+ "Event"
6980
+ ]
6981
+ }]
6982
+ \`\`\`
6983
+
6984
+ ## Allowed Type Exceptions
6985
+
6986
+ You can configure specific types that are allowed as cast targets. This is useful for:
6987
+
6988
+ - **DOM elements**: \`HTMLElement\`, \`HTMLInputElement\`, etc.
6989
+ - **Error handling**: \`Error\`, \`TypeError\`, etc.
6990
+ - **Event handling**: \`Event\`, \`MouseEvent\`, \`KeyboardEvent\`, etc.
6991
+ - **Third-party types**: Types from libraries that require casting
6992
+
6993
+ ## When to Disable
6994
+
6995
+ Consider disabling this rule when:
6996
+
6997
+ - Working with legacy code that requires extensive type casting
6998
+ - Integrating with untyped JavaScript libraries
6999
+ - Writing type-level tests or type utilities
7000
+
7001
+ Use inline comments for specific exceptions:
7002
+
7003
+ \`\`\`typescript
7004
+ // eslint-disable-next-line uilint/no-unsafe-type-casts
7005
+ const data = legacyApiResponse as any;
7006
+ \`\`\`
7007
+ `
7008
+ });
7009
+ function isTestFile2(filename) {
7010
+ return filename.includes(".test.") || filename.includes(".spec.") || filename.includes("__tests__") || filename.includes("__mocks__");
7011
+ }
7012
+ function isInsideCatchBlock(node) {
7013
+ let current = node.parent;
7014
+ while (current) {
7015
+ if (current.type === "CatchClause") {
7016
+ return true;
7017
+ }
7018
+ current = current.parent;
7019
+ }
7020
+ return false;
7021
+ }
7022
+ function getTypeName(typeAnnotation) {
7023
+ switch (typeAnnotation.type) {
7024
+ case "TSTypeReference":
7025
+ if (typeAnnotation.typeName.type === "Identifier") {
7026
+ return typeAnnotation.typeName.name;
7027
+ }
7028
+ if (typeAnnotation.typeName.type === "TSQualifiedName") {
7029
+ return `${getQualifiedName(typeAnnotation.typeName)}`;
7030
+ }
7031
+ return null;
7032
+ case "TSAnyKeyword":
7033
+ return "any";
7034
+ case "TSUnknownKeyword":
7035
+ return "unknown";
7036
+ default:
7037
+ return null;
7038
+ }
7039
+ }
7040
+ function getQualifiedName(node) {
7041
+ const left = node.left.type === "Identifier" ? node.left.name : getQualifiedName(node.left);
7042
+ return `${left}.${node.right.name}`;
7043
+ }
7044
+ function isAllowedType(typeAnnotation, allowedTypes) {
7045
+ const typeName = getTypeName(typeAnnotation);
7046
+ if (!typeName) return false;
7047
+ return allowedTypes.includes(typeName);
7048
+ }
7049
+ function isDoubleCastPattern(node) {
7050
+ if (node.expression.type !== "TSAsExpression") {
7051
+ return false;
7052
+ }
7053
+ const innerCast = node.expression;
7054
+ const innerType = innerCast.typeAnnotation;
7055
+ return innerType.type === "TSUnknownKeyword" || innerType.type === "TSAnyKeyword";
7056
+ }
7057
+ function isLegacyDoubleCastPattern(node) {
7058
+ if (node.expression.type !== "TSTypeAssertion") {
7059
+ return false;
7060
+ }
7061
+ const innerCast = node.expression;
7062
+ const innerType = innerCast.typeAnnotation;
7063
+ return innerType.type === "TSUnknownKeyword" || innerType.type === "TSAnyKeyword";
7064
+ }
7065
+ var no_unsafe_type_casts_default = createRule({
7066
+ name: "no-unsafe-type-casts",
7067
+ meta: {
7068
+ type: "problem",
7069
+ docs: {
7070
+ description: "Disallow unsafe type casting patterns that bypass TypeScript's type system"
7071
+ },
7072
+ messages: {
7073
+ noAsAny: "Avoid using 'as any'. This completely bypasses type checking. Use proper typing, type guards, or runtime validation instead.",
7074
+ noAsUnknown: "Casting to 'unknown' without subsequent type narrowing bypasses type safety. Use type guards or validation.",
7075
+ noDoubleCast: "Double-cast pattern ('as unknown as {{targetType}}') bypasses type checking. Use runtime validation or type guards instead.",
7076
+ noLegacyAsAny: "Avoid using '<any>' type assertion. This completely bypasses type checking. Use proper typing or type guards instead.",
7077
+ noLegacyAsUnknown: "Casting to '<unknown>' without subsequent type narrowing bypasses type safety. Use type guards or validation."
7078
+ },
7079
+ schema: [
7080
+ {
7081
+ type: "object",
7082
+ properties: {
7083
+ reportAsAny: {
7084
+ type: "boolean",
7085
+ description: "Report 'as any' casts"
7086
+ },
7087
+ reportAsUnknown: {
7088
+ type: "boolean",
7089
+ description: "Report 'as unknown' casts"
7090
+ },
7091
+ reportDoubleCast: {
7092
+ type: "boolean",
7093
+ description: "Report double-cast patterns like 'as unknown as T'"
7094
+ },
7095
+ allowInTestFiles: {
7096
+ type: "boolean",
7097
+ description: "Allow casts in test files"
7098
+ },
7099
+ allowInCatchBlocks: {
7100
+ type: "boolean",
7101
+ description: "Allow casts in catch blocks for error handling"
7102
+ },
7103
+ allowedTypes: {
7104
+ type: "array",
7105
+ items: { type: "string" },
7106
+ description: "Type names that are allowed as cast targets"
7107
+ }
7108
+ },
7109
+ additionalProperties: false
7110
+ }
7111
+ ]
7112
+ },
7113
+ defaultOptions: [
7114
+ {
7115
+ reportAsAny: true,
7116
+ reportAsUnknown: false,
7117
+ reportDoubleCast: true,
7118
+ allowInTestFiles: true,
7119
+ allowInCatchBlocks: true,
7120
+ allowedTypes: []
7121
+ }
7122
+ ],
7123
+ create(context) {
7124
+ const options = context.options[0] || {};
7125
+ const reportAsAny = options.reportAsAny ?? true;
7126
+ const reportAsUnknown = options.reportAsUnknown ?? false;
7127
+ const reportDoubleCast = options.reportDoubleCast ?? true;
7128
+ const allowInTestFiles = options.allowInTestFiles ?? true;
7129
+ const allowInCatchBlocks = options.allowInCatchBlocks ?? true;
7130
+ const allowedTypes = options.allowedTypes ?? [];
7131
+ const filename = context.filename || context.getFilename();
7132
+ if (allowInTestFiles && isTestFile2(filename)) {
7133
+ return {};
7134
+ }
7135
+ function checkAsExpression(node) {
7136
+ const targetType = node.typeAnnotation;
7137
+ if (allowInCatchBlocks && isInsideCatchBlock(node)) {
7138
+ return;
7139
+ }
7140
+ if (reportDoubleCast && isDoubleCastPattern(node)) {
7141
+ const targetTypeName = getTypeName(targetType) || "Type";
7142
+ context.report({
7143
+ node,
7144
+ messageId: "noDoubleCast",
7145
+ data: { targetType: targetTypeName }
7146
+ });
7147
+ return;
7148
+ }
7149
+ if (isAllowedType(targetType, allowedTypes)) {
7150
+ return;
7151
+ }
7152
+ if (reportAsAny && targetType.type === "TSAnyKeyword") {
7153
+ context.report({
7154
+ node,
7155
+ messageId: "noAsAny"
7156
+ });
7157
+ return;
7158
+ }
7159
+ if (reportAsUnknown && targetType.type === "TSUnknownKeyword") {
7160
+ context.report({
7161
+ node,
7162
+ messageId: "noAsUnknown"
7163
+ });
7164
+ return;
7165
+ }
7166
+ }
7167
+ function checkTypeAssertion(node) {
7168
+ const targetType = node.typeAnnotation;
7169
+ if (allowInCatchBlocks && isInsideCatchBlock(node)) {
7170
+ return;
7171
+ }
7172
+ if (reportDoubleCast && isLegacyDoubleCastPattern(node)) {
7173
+ const targetTypeName = getTypeName(targetType) || "Type";
7174
+ context.report({
7175
+ node,
7176
+ messageId: "noDoubleCast",
7177
+ data: { targetType: targetTypeName }
7178
+ });
7179
+ return;
7180
+ }
7181
+ if (isAllowedType(targetType, allowedTypes)) {
7182
+ return;
7183
+ }
7184
+ if (reportAsAny && targetType.type === "TSAnyKeyword") {
7185
+ context.report({
7186
+ node,
7187
+ messageId: "noLegacyAsAny"
7188
+ });
7189
+ return;
7190
+ }
7191
+ if (reportAsUnknown && targetType.type === "TSUnknownKeyword") {
7192
+ context.report({
7193
+ node,
7194
+ messageId: "noLegacyAsUnknown"
7195
+ });
7196
+ return;
7197
+ }
7198
+ }
7199
+ return {
7200
+ TSAsExpression: checkAsExpression,
7201
+ TSTypeAssertion: checkTypeAssertion
7202
+ };
7203
+ }
7204
+ });
7205
+
6833
7206
  // src/category-registry.ts
6834
7207
  var categoryRegistry = [
6835
7208
  {
@@ -6873,7 +7246,9 @@ var ruleRegistry = [
6873
7246
  // Test coverage enforcement
6874
7247
  meta14,
6875
7248
  // Style preferences
6876
- meta15
7249
+ meta15,
7250
+ // Type safety
7251
+ meta16
6877
7252
  ];
6878
7253
  function getRuleMetadata(id) {
6879
7254
  return ruleRegistry.find((rule) => rule.id === id);
@@ -6906,15 +7281,16 @@ var rules = {
6906
7281
  "require-input-validation": require_input_validation_default,
6907
7282
  "no-semantic-duplicates": no_semantic_duplicates_default,
6908
7283
  "require-test-coverage": require_test_coverage_default,
6909
- "prefer-tailwind": prefer_tailwind_default
7284
+ "prefer-tailwind": prefer_tailwind_default,
7285
+ "no-unsafe-type-casts": no_unsafe_type_casts_default
6910
7286
  };
6911
7287
  var version = "0.1.0";
6912
- var meta16 = {
7288
+ var meta17 = {
6913
7289
  name: "uilint",
6914
7290
  version
6915
7291
  };
6916
7292
  var plugin = {
6917
- meta: meta16,
7293
+ meta: meta17,
6918
7294
  rules
6919
7295
  };
6920
7296
  var jsxLanguageOptions = {
@@ -7049,6 +7425,16 @@ var recommendedConfig = {
7049
7425
  "preferSemanticColors": true,
7050
7426
  "allowedHardCodedColors": []
7051
7427
  }
7428
+ ]],
7429
+ "uilint/no-unsafe-type-casts": ["error", ...[
7430
+ {
7431
+ "reportAsAny": true,
7432
+ "reportAsUnknown": false,
7433
+ "reportDoubleCast": true,
7434
+ "allowInTestFiles": true,
7435
+ "allowInCatchBlocks": true,
7436
+ "allowedTypes": []
7437
+ }
7052
7438
  ]]
7053
7439
  }
7054
7440
  };
@@ -7196,6 +7582,16 @@ var strictConfig = {
7196
7582
  "preferSemanticColors": true,
7197
7583
  "allowedHardCodedColors": []
7198
7584
  }
7585
+ ]],
7586
+ "uilint/no-unsafe-type-casts": ["error", ...[
7587
+ {
7588
+ "reportAsAny": true,
7589
+ "reportAsUnknown": false,
7590
+ "reportDoubleCast": true,
7591
+ "allowInTestFiles": true,
7592
+ "allowInCatchBlocks": true,
7593
+ "allowedTypes": []
7594
+ }
7199
7595
  ]]
7200
7596
  }
7201
7597
  };
@@ -7204,7 +7600,7 @@ var configs = {
7204
7600
  strict: strictConfig
7205
7601
  };
7206
7602
  var uilintEslint = {
7207
- meta: meta16,
7603
+ meta: meta17,
7208
7604
  plugin,
7209
7605
  rules,
7210
7606
  configs
@@ -7242,7 +7638,7 @@ export {
7242
7638
  isEventHandlerAttribute,
7243
7639
  loadCache,
7244
7640
  loadStyleguide,
7245
- meta16 as meta,
7641
+ meta17 as meta,
7246
7642
  plugin,
7247
7643
  ruleRegistry,
7248
7644
  rules,