@sarj/eslint-plugin 15.11.0 → 15.12.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/dist/index.js CHANGED
@@ -2009,6 +2009,67 @@ var no_duplicate_lifecycle_refresh_listeners_default = createRule({
2009
2009
  }
2010
2010
  });
2011
2011
 
2012
+ // src/rules/no-dangerously-allow-svg.ts
2013
+ import "@typescript-eslint/utils";
2014
+ var NEXT_CONFIG_RE = /(?:^|\/)next\.config\.[cm]?[jt]s$/;
2015
+ var noDangerouslyAllowSvgDocumentation = {
2016
+ summary: "Next.js image configuration enables unsanitized SVG rendering",
2017
+ rationale: "SVG files can contain scripts and other active content; enabling dangerouslyAllowSVG makes the image optimizer serve that content from the application origin.",
2018
+ remediation: "Keep dangerouslyAllowSVG disabled. If SVG delivery is unavoidable, use a separately reviewed asset path with restrictive Content-Disposition and Content-Security-Policy headers.",
2019
+ category: "security",
2020
+ limitations: [
2021
+ "Only a literal true assigned to dangerouslyAllowSVG in a next.config source file is reported; computed or imported configuration is intentionally not inferred."
2022
+ ],
2023
+ examples: [
2024
+ {
2025
+ id: "svg-disabled",
2026
+ title: "Keep active SVG delivery disabled",
2027
+ outcome: "no-match",
2028
+ files: [{ path: "next.config.mjs", source: "export default { images: { dangerouslyAllowSVG: false } };\n" }],
2029
+ focusPath: "next.config.mjs",
2030
+ expectedCount: 0,
2031
+ public: true
2032
+ },
2033
+ {
2034
+ id: "svg-enabled",
2035
+ title: "Do not enable active SVG delivery",
2036
+ outcome: "match",
2037
+ files: [{ path: "next.config.mjs", source: "export default { images: { dangerouslyAllowSVG: true } };\n" }],
2038
+ focusPath: "next.config.mjs",
2039
+ expectedCount: 1,
2040
+ public: true
2041
+ }
2042
+ ]
2043
+ };
2044
+ function propertyName(node) {
2045
+ if (!node.computed && node.key.type === "Identifier") return node.key.name;
2046
+ if (node.key.type === "Literal" && typeof node.key.value === "string") return node.key.value;
2047
+ return null;
2048
+ }
2049
+ var no_dangerously_allow_svg_default = createRule({
2050
+ name: "no-dangerously-allow-svg",
2051
+ documentation: noDangerouslyAllowSvgDocumentation,
2052
+ meta: {
2053
+ type: "problem",
2054
+ docs: { description: noDangerouslyAllowSvgDocumentation.summary },
2055
+ schema: [],
2056
+ messages: {
2057
+ noDangerouslyAllowSvg: "Do not enable dangerouslyAllowSVG. SVG can carry active content served from the application origin."
2058
+ }
2059
+ },
2060
+ defaultOptions: [],
2061
+ create(context) {
2062
+ if (!NEXT_CONFIG_RE.test(context.filename.replaceAll("\\", "/"))) return {};
2063
+ return {
2064
+ Property(node) {
2065
+ if (propertyName(node) === "dangerouslyAllowSVG" && node.value.type === "Literal" && node.value.value === true) {
2066
+ context.report({ node, messageId: "noDangerouslyAllowSvg" });
2067
+ }
2068
+ }
2069
+ };
2070
+ }
2071
+ });
2072
+
2012
2073
  // src/rules/no-dynamic-sql.ts
2013
2074
  import { AST_NODE_TYPES as AST_NODE_TYPES9 } from "@typescript-eslint/utils";
2014
2075
 
@@ -3004,7 +3065,7 @@ var no_hand_rolled_sleep_default = createRule({
3004
3065
  return {};
3005
3066
  }
3006
3067
  const checkClientModules = optionsArg?.checkClientModules ?? false;
3007
- function isClientModule() {
3068
+ function isClientModule2() {
3008
3069
  if (/\.[cm]?[jt]sx$/.test(filename)) {
3009
3070
  return true;
3010
3071
  }
@@ -3024,7 +3085,7 @@ var no_hand_rolled_sleep_default = createRule({
3024
3085
  if (checkClientModules) {
3025
3086
  return true;
3026
3087
  }
3027
- clientModule ??= isClientModule();
3088
+ clientModule ??= isClientModule2();
3028
3089
  return !clientModule;
3029
3090
  };
3030
3091
  return {
@@ -5175,6 +5236,67 @@ var no_positional_tuple_return_default = createRule({
5175
5236
  }
5176
5237
  });
5177
5238
 
5239
+ // src/rules/no-production-browser-source-maps.ts
5240
+ import "@typescript-eslint/utils";
5241
+ var NEXT_CONFIG_RE2 = /(?:^|\/)next\.config\.[cm]?[jt]s$/;
5242
+ var noProductionBrowserSourceMapsDocumentation = {
5243
+ summary: "Next.js production browser source maps expose application source",
5244
+ rationale: "Next.js production browser source maps publish original client source and implementation details to every browser that can load the deployment.",
5245
+ remediation: "Leave productionBrowserSourceMaps disabled and upload private source maps directly to the error-monitoring service during the build.",
5246
+ category: "security",
5247
+ limitations: [
5248
+ "Only a literal true assigned in a next.config source file is reported; computed or imported configuration is intentionally not inferred."
5249
+ ],
5250
+ examples: [
5251
+ {
5252
+ id: "private-source-maps",
5253
+ title: "Keep browser source maps private",
5254
+ outcome: "no-match",
5255
+ files: [{ path: "next.config.mjs", source: "export default { productionBrowserSourceMaps: false };\n" }],
5256
+ focusPath: "next.config.mjs",
5257
+ expectedCount: 0,
5258
+ public: true
5259
+ },
5260
+ {
5261
+ id: "public-source-maps",
5262
+ title: "Do not publish production browser source maps",
5263
+ outcome: "match",
5264
+ files: [{ path: "next.config.mjs", source: "export default { productionBrowserSourceMaps: true };\n" }],
5265
+ focusPath: "next.config.mjs",
5266
+ expectedCount: 1,
5267
+ public: true
5268
+ }
5269
+ ]
5270
+ };
5271
+ function propertyName2(node) {
5272
+ if (!node.computed && node.key.type === "Identifier") return node.key.name;
5273
+ if (node.key.type === "Literal" && typeof node.key.value === "string") return node.key.value;
5274
+ return null;
5275
+ }
5276
+ var no_production_browser_source_maps_default = createRule({
5277
+ name: "no-production-browser-source-maps",
5278
+ documentation: noProductionBrowserSourceMapsDocumentation,
5279
+ meta: {
5280
+ type: "problem",
5281
+ docs: { description: noProductionBrowserSourceMapsDocumentation.summary },
5282
+ schema: [],
5283
+ messages: {
5284
+ noProductionBrowserSourceMaps: "Do not publish production browser source maps. Upload private maps to your monitoring service instead."
5285
+ }
5286
+ },
5287
+ defaultOptions: [],
5288
+ create(context) {
5289
+ if (!NEXT_CONFIG_RE2.test(context.filename.replaceAll("\\", "/"))) return {};
5290
+ return {
5291
+ Property(node) {
5292
+ if (propertyName2(node) === "productionBrowserSourceMaps" && node.value.type === "Literal" && node.value.value === true) {
5293
+ context.report({ node, messageId: "noProductionBrowserSourceMaps" });
5294
+ }
5295
+ }
5296
+ };
5297
+ }
5298
+ });
5299
+
5178
5300
  // src/rules/no-raw-env.ts
5179
5301
  import "@typescript-eslint/utils";
5180
5302
  var noRawEnvDocumentation = {
@@ -6568,6 +6690,85 @@ var no_secret_in_log_default = createRule({
6568
6690
  }
6569
6691
  });
6570
6692
 
6693
+ // src/rules/no-server-env-in-client-component.ts
6694
+ import "@typescript-eslint/utils";
6695
+ var SERVER_ENV_MODULE_RE = /(?:^|\/)(?:server-env|server-settings)(?:\.[cm]?[jt]sx?)?$/;
6696
+ var noServerEnvInClientComponentDocumentation = {
6697
+ summary: "server-only environment settings imported by a client component",
6698
+ rationale: "Next.js client modules run in the browser, where server-only environment values are unavailable; importing a server settings module can produce undefined configuration or bundle a secret-bearing module into the client graph.",
6699
+ remediation: "Pass an explicitly public value from a Server Component, or import it from a separately validated client-settings module backed only by NEXT_PUBLIC_* values.",
6700
+ category: "correctness",
6701
+ limitations: [
6702
+ "Only static value imports in files with a top-level 'use client' directive and conventionally named server-env/server-settings modules are checked."
6703
+ ],
6704
+ examples: [
6705
+ {
6706
+ id: "public-client-settings",
6707
+ title: "Import a browser-safe settings boundary",
6708
+ outcome: "no-match",
6709
+ files: [
6710
+ {
6711
+ path: "status-card.tsx",
6712
+ source: "'use client';\nimport { CLIENT_SETTINGS } from '@/client-settings';\nexport const StatusCard = () => <p>{CLIENT_SETTINGS.apiOrigin}</p>;\n"
6713
+ }
6714
+ ],
6715
+ focusPath: "status-card.tsx",
6716
+ expectedCount: 0,
6717
+ public: true
6718
+ },
6719
+ {
6720
+ id: "server-settings-client-import",
6721
+ title: "Do not pull server settings into a client bundle",
6722
+ outcome: "match",
6723
+ files: [
6724
+ {
6725
+ path: "status-card.tsx",
6726
+ source: "'use client';\nimport { SERVER_SETTINGS } from '@/server-settings';\nexport const StatusCard = () => <p>{SERVER_SETTINGS.apiOrigin}</p>;\n"
6727
+ }
6728
+ ],
6729
+ focusPath: "status-card.tsx",
6730
+ expectedCount: 1,
6731
+ public: true
6732
+ }
6733
+ ]
6734
+ };
6735
+ function isClientModule(program) {
6736
+ return program.body.some(
6737
+ (statement) => statement.type === "ExpressionStatement" && statement.directive === "use client"
6738
+ );
6739
+ }
6740
+ function isTypeOnlyImport(node) {
6741
+ return node.importKind === "type" || node.specifiers.length > 0 && node.specifiers.every(
6742
+ (specifier) => specifier.type === "ImportSpecifier" && specifier.importKind === "type"
6743
+ );
6744
+ }
6745
+ var no_server_env_in_client_component_default = createRule({
6746
+ name: "no-server-env-in-client-component",
6747
+ documentation: noServerEnvInClientComponentDocumentation,
6748
+ meta: {
6749
+ type: "problem",
6750
+ docs: { description: noServerEnvInClientComponentDocumentation.summary },
6751
+ schema: [],
6752
+ messages: {
6753
+ noServerEnvInClientComponent: "A 'use client' module cannot import server-only settings. Pass public data from a Server Component or use a validated client-settings module."
6754
+ }
6755
+ },
6756
+ defaultOptions: [],
6757
+ create(context) {
6758
+ let clientModule = false;
6759
+ return {
6760
+ Program(node) {
6761
+ clientModule = isClientModule(node);
6762
+ },
6763
+ ImportDeclaration(node) {
6764
+ if (clientModule && !isTypeOnlyImport(node) && typeof node.source.value === "string" && SERVER_ENV_MODULE_RE.test(node.source.value)) {
6765
+ context.report({ node, messageId: "noServerEnvInClientComponent" });
6766
+ }
6767
+ }
6768
+ };
6769
+ }
6770
+ });
6771
+
6571
6772
  // src/rules/no-select-star.ts
6572
6773
  import "@typescript-eslint/utils";
6573
6774
  var noSelectStarDocumentation = {
@@ -11250,7 +11451,7 @@ var preferNonNullableCollectionDocumentation = {
11250
11451
  ]
11251
11452
  };
11252
11453
  var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
11253
- function propertyName(node) {
11454
+ function propertyName3(node) {
11254
11455
  const key = node.key;
11255
11456
  if (node.computed) return null;
11256
11457
  if (key.type === AST_NODE_TYPES48.Identifier) return key.name;
@@ -11263,7 +11464,7 @@ function isArrayType(node) {
11263
11464
  }
11264
11465
  function nullableProperty(node) {
11265
11466
  if (node.optional) return null;
11266
- const name = propertyName(node);
11467
+ const name = propertyName3(node);
11267
11468
  const annotation = node.typeAnnotation?.typeAnnotation;
11268
11469
  if (name === null || annotation?.type !== AST_NODE_TYPES48.TSUnionType) return null;
11269
11470
  const concrete = annotation.types.filter(
@@ -11473,7 +11674,7 @@ var prefer_non_nullable_collection_default = createRule({
11473
11674
  context.report({
11474
11675
  node,
11475
11676
  messageId: "preferNonNullableCollection",
11476
- data: { name: propertyName(node) ?? "collection" }
11677
+ data: { name: propertyName3(node) ?? "collection" }
11477
11678
  });
11478
11679
  }
11479
11680
  }
@@ -13653,11 +13854,11 @@ var prefer_zod_infer_default = createRule({
13653
13854
  continue;
13654
13855
  }
13655
13856
  const key = member.key;
13656
- const propertyName3 = key.type === AST_NODE_TYPES54.Identifier ? key.name : key.type === AST_NODE_TYPES54.Literal && typeof key.value === "string" ? key.value : null;
13657
- if (propertyName3 === null) {
13857
+ const propertyName5 = key.type === AST_NODE_TYPES54.Identifier ? key.name : key.type === AST_NODE_TYPES54.Literal && typeof key.value === "string" ? key.value : null;
13858
+ if (propertyName5 === null) {
13658
13859
  continue;
13659
13860
  }
13660
- const propertyTokens = nameTokens(propertyName3);
13861
+ const propertyTokens = nameTokens(propertyName5);
13661
13862
  if (propertyTokens.length < 2) {
13662
13863
  continue;
13663
13864
  }
@@ -13672,7 +13873,7 @@ var prefer_zod_infer_default = createRule({
13672
13873
  node: annotation,
13673
13874
  owner,
13674
13875
  ownerName,
13675
- propertyName: propertyName3,
13876
+ propertyName: propertyName5,
13676
13877
  propertyTokens
13677
13878
  });
13678
13879
  }
@@ -14787,7 +14988,7 @@ function isStaticValue(node) {
14787
14988
  }
14788
14989
  return false;
14789
14990
  }
14790
- function propertyName2(property) {
14991
+ function propertyName4(property) {
14791
14992
  if (property.computed) return null;
14792
14993
  if (property.key.type === AST_NODE_TYPES58.Identifier) return property.key.name;
14793
14994
  return typeof property.key.value === "string" ? property.key.value : null;
@@ -14824,7 +15025,7 @@ var require_static_next_matcher_default = createRule({
14824
15025
  continue;
14825
15026
  }
14826
15027
  for (const property of config.properties) {
14827
- if (property.type !== AST_NODE_TYPES58.Property || propertyName2(property) !== "matcher" || property.value.type === AST_NODE_TYPES58.AssignmentPattern) {
15028
+ if (property.type !== AST_NODE_TYPES58.Property || propertyName4(property) !== "matcher" || property.value.type === AST_NODE_TYPES58.AssignmentPattern) {
14828
15029
  continue;
14829
15030
  }
14830
15031
  if (!isStaticValue(property.value)) {
@@ -14837,10 +15038,146 @@ var require_static_next_matcher_default = createRule({
14837
15038
  }
14838
15039
  });
14839
15040
 
15041
+ // src/rules/require-use-form-default-values.ts
15042
+ import { ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
15043
+ var requireUseFormDefaultValuesDocumentation = {
15044
+ summary: "react-hook-form useForm call without defaultValues",
15045
+ rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
15046
+ remediation: "Pass an object with a defaultValues property to useForm; use empty strings, nulls, or schema-appropriate values deliberately for every controlled field.",
15047
+ category: "correctness",
15048
+ limitations: [
15049
+ "Only direct calls to a scope-resolved useForm value imported from react-hook-form are checked; wrapper hooks and computed option objects are intentionally not inferred."
15050
+ ],
15051
+ examples: [
15052
+ {
15053
+ id: "form-with-initial-values",
15054
+ title: "Give the form an explicit initial shape",
15055
+ outcome: "no-match",
15056
+ files: [{ path: "profile-form.tsx", source: "import { useForm } from 'react-hook-form';\nconst form = useForm({ defaultValues: { name: '' } });\n" }],
15057
+ focusPath: "profile-form.tsx",
15058
+ expectedCount: 0,
15059
+ public: true
15060
+ },
15061
+ {
15062
+ id: "form-without-initial-values",
15063
+ title: "Do not leave form initialization implicit",
15064
+ outcome: "match",
15065
+ files: [{ path: "profile-form.tsx", source: "import { useForm } from 'react-hook-form';\nconst form = useForm({ mode: 'onChange' });\n" }],
15066
+ focusPath: "profile-form.tsx",
15067
+ expectedCount: 1,
15068
+ public: true
15069
+ }
15070
+ ]
15071
+ };
15072
+ function hasDefaultValues(options) {
15073
+ return options?.type === "ObjectExpression" && options.properties.some(
15074
+ (property) => property.type === "Property" && !property.computed && (property.key.type === "Identifier" && property.key.name === "defaultValues" || property.key.type === "Literal" && property.key.value === "defaultValues")
15075
+ );
15076
+ }
15077
+ var require_use_form_default_values_default = createRule({
15078
+ name: "require-use-form-default-values",
15079
+ documentation: requireUseFormDefaultValuesDocumentation,
15080
+ meta: {
15081
+ type: "problem",
15082
+ docs: { description: requireUseFormDefaultValuesDocumentation.summary },
15083
+ schema: [],
15084
+ messages: {
15085
+ requireUseFormDefaultValues: "Pass explicit defaultValues to useForm so fields have a stable initial shape and reset behavior."
15086
+ }
15087
+ },
15088
+ defaultOptions: [],
15089
+ create(context) {
15090
+ const importedHooks = /* @__PURE__ */ new Set();
15091
+ return {
15092
+ ImportDeclaration(node) {
15093
+ if (node.source.value !== "react-hook-form") return;
15094
+ for (const specifier of node.specifiers) {
15095
+ if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
15096
+ const variable = ASTUtils19.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
15097
+ if (variable) importedHooks.add(variable);
15098
+ }
15099
+ },
15100
+ CallExpression(node) {
15101
+ if (node.callee.type !== "Identifier") return;
15102
+ const variable = ASTUtils19.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
15103
+ const options = node.arguments[0];
15104
+ if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
15105
+ context.report({ node, messageId: "requireUseFormDefaultValues" });
15106
+ }
15107
+ };
15108
+ }
15109
+ });
15110
+
15111
+ // src/rules/require-use-server-in-actions-file.ts
15112
+ import "@typescript-eslint/utils";
15113
+ var ACTION_MODULE_RE = /(?:^|\/)app\/.*\/(?:actions|[^/]+-actions)\.[cm]?[jt]s$/u;
15114
+ var requireUseServerInActionsFileDocumentation = {
15115
+ summary: "route action module missing the use server directive",
15116
+ rationale: "An exported async function is not callable as a Server Action merely because its file is named actions.ts. Without the module directive, a client import can fail or pull server-only implementation details across the client boundary.",
15117
+ remediation: "Put 'use server' at the start of the route action module.",
15118
+ category: "correctness",
15119
+ limitations: [
15120
+ "Only exported async functions in actions.ts or *-actions.ts below an app directory are checked; other naming schemes and inline Server Actions are intentionally outside the rule."
15121
+ ],
15122
+ examples: [
15123
+ {
15124
+ id: "server-action-module",
15125
+ title: "Mark the action module as server-only",
15126
+ outcome: "no-match",
15127
+ files: [{ path: "app/orders/actions.ts", source: "'use server';\nexport async function cancelOrder() {}\n" }],
15128
+ focusPath: "app/orders/actions.ts",
15129
+ expectedCount: 0,
15130
+ public: true
15131
+ },
15132
+ {
15133
+ id: "unmarked-action-module",
15134
+ title: "Do not rely on the filename to create a Server Action",
15135
+ outcome: "match",
15136
+ files: [{ path: "app/orders/actions.ts", source: "export async function cancelOrder() {}\n" }],
15137
+ focusPath: "app/orders/actions.ts",
15138
+ expectedCount: 1,
15139
+ public: true
15140
+ }
15141
+ ]
15142
+ };
15143
+ function isExportedAsyncFunction(node) {
15144
+ const declaration = node.declaration;
15145
+ if (declaration?.type === "FunctionDeclaration") return declaration.async;
15146
+ return declaration?.type === "VariableDeclaration" && declaration.declarations.some(
15147
+ (item) => item.init?.type === "ArrowFunctionExpression" || item.init?.type === "FunctionExpression" ? item.init.async : false
15148
+ );
15149
+ }
15150
+ var require_use_server_in_actions_file_default = createRule({
15151
+ name: "require-use-server-in-actions-file",
15152
+ documentation: requireUseServerInActionsFileDocumentation,
15153
+ meta: {
15154
+ type: "problem",
15155
+ docs: { description: requireUseServerInActionsFileDocumentation.summary },
15156
+ schema: [],
15157
+ messages: {
15158
+ requireUseServerInActionsFile: "This route action module exports an async function but is missing a leading 'use server' directive."
15159
+ }
15160
+ },
15161
+ defaultOptions: [],
15162
+ create(context) {
15163
+ return {
15164
+ Program(node) {
15165
+ const filename = context.filename.replaceAll("\\", "/");
15166
+ if (!ACTION_MODULE_RE.test(filename)) return;
15167
+ if (node.body.some((statement) => statement.type === "ExpressionStatement" && statement.directive === "use server")) return;
15168
+ const exportedAction = node.body.find(
15169
+ (statement) => statement.type === "ExportNamedDeclaration" && isExportedAsyncFunction(statement)
15170
+ );
15171
+ if (exportedAction) context.report({ node: exportedAction, messageId: "requireUseServerInActionsFile" });
15172
+ }
15173
+ };
15174
+ }
15175
+ });
15176
+
14840
15177
  // src/rules/require-zod-form-validation.ts
14841
15178
  import {
14842
15179
  AST_NODE_TYPES as AST_NODE_TYPES59,
14843
- ASTUtils as ASTUtils19
15180
+ ASTUtils as ASTUtils20
14844
15181
  } from "@typescript-eslint/utils";
14845
15182
  var requireZodFormValidationDocumentation = {
14846
15183
  summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
@@ -14908,7 +15245,7 @@ var require_zod_form_validation_default = createRule({
14908
15245
  return {};
14909
15246
  }
14910
15247
  const zodBindings = /* @__PURE__ */ new Set();
14911
- const resolvedBinding = (identifier) => ASTUtils19.findVariable(
15248
+ const resolvedBinding = (identifier) => ASTUtils20.findVariable(
14912
15249
  context.sourceCode.getScope(identifier),
14913
15250
  identifier.name
14914
15251
  );
@@ -15205,7 +15542,7 @@ var store_insert_requires_on_conflict_default = createRule({
15205
15542
  });
15206
15543
 
15207
15544
  // src/rules/stepdown.ts
15208
- import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
15545
+ import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as ASTUtils21 } from "@typescript-eslint/utils";
15209
15546
  var stepdownDocumentation = {
15210
15547
  summary: "Place a private helper below its sole direct same-scope caller.",
15211
15548
  rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
@@ -15405,7 +15742,7 @@ function methodName(node) {
15405
15742
  return !node.computed && node.key.type === AST_NODE_TYPES60.Identifier ? node.key.name : null;
15406
15743
  }
15407
15744
  function referencedMethod(context, node, classVariables) {
15408
- const objectVariable = node.object.type === AST_NODE_TYPES60.Identifier ? ASTUtils20.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
15745
+ const objectVariable = node.object.type === AST_NODE_TYPES60.Identifier ? ASTUtils21.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
15409
15746
  const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
15410
15747
  if (node.object.type !== AST_NODE_TYPES60.ThisExpression && !isClassReference) return null;
15411
15748
  if (node.property.type === AST_NODE_TYPES60.PrivateIdentifier) return `#${node.property.name}`;
@@ -15458,11 +15795,11 @@ function classScope(context, node, computedReferenceNames) {
15458
15795
  const pinned = /* @__PURE__ */ new Set();
15459
15796
  const classVariables = /* @__PURE__ */ new Set();
15460
15797
  if (node.id !== null) {
15461
- const internal = ASTUtils20.findVariable(context.sourceCode.getScope(node), node.id.name);
15798
+ const internal = ASTUtils21.findVariable(context.sourceCode.getScope(node), node.id.name);
15462
15799
  if (internal !== null) classVariables.add(internal);
15463
15800
  }
15464
15801
  if (node.type === AST_NODE_TYPES60.ClassExpression && node.parent.type === AST_NODE_TYPES60.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES60.Identifier) {
15465
- const outer = ASTUtils20.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
15802
+ const outer = ASTUtils21.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
15466
15803
  if (outer !== null) classVariables.add(outer);
15467
15804
  }
15468
15805
  for (const method of methods) {
@@ -15498,7 +15835,7 @@ function classScope(context, node, computedReferenceNames) {
15498
15835
  return;
15499
15836
  }
15500
15837
  if (binding.type !== AST_NODE_TYPES60.Identifier) return;
15501
- const variable = ASTUtils20.findVariable(context.sourceCode.getScope(binding), binding.name);
15838
+ const variable = ASTUtils21.findVariable(context.sourceCode.getScope(binding), binding.name);
15502
15839
  if (variable !== null) {
15503
15840
  methodClassVariables.add(variable);
15504
15841
  methodAliases.add(variable);
@@ -15528,7 +15865,7 @@ function classScope(context, node, computedReferenceNames) {
15528
15865
  return;
15529
15866
  }
15530
15867
  if (!privateNames.has(target)) return;
15531
- const objectVariable = current.object.type === AST_NODE_TYPES60.Identifier ? ASTUtils20.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
15868
+ const objectVariable = current.object.type === AST_NODE_TYPES60.Identifier ? ASTUtils21.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
15532
15869
  if (objectVariable !== null && methodAliases.has(objectVariable)) {
15533
15870
  pinned.add(target);
15534
15871
  return;
@@ -15976,7 +16313,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
15976
16313
  // src/rules/zod-naming-convention.ts
15977
16314
  import {
15978
16315
  AST_NODE_TYPES as AST_NODE_TYPES62,
15979
- ASTUtils as ASTUtils21
16316
+ ASTUtils as ASTUtils22
15980
16317
  } from "@typescript-eslint/utils";
15981
16318
  var zodNamingConventionDocumentation = {
15982
16319
  summary: "Enforce a consistent Zod schema naming convention \u2014 a `Z` prefix (`ZUser`) or a `Schema` suffix (`userSchema`); both are accepted by default.",
@@ -16069,7 +16406,7 @@ var zod_naming_convention_default = createRule({
16069
16406
  const acceptsSchemaWord = convention !== "prefix";
16070
16407
  const zodBindings = /* @__PURE__ */ new Set();
16071
16408
  function resolvedBinding(identifier) {
16072
- return ASTUtils21.findVariable(
16409
+ return ASTUtils22.findVariable(
16073
16410
  context.sourceCode.getScope(identifier),
16074
16411
  identifier.name
16075
16412
  );
@@ -16206,6 +16543,7 @@ var rules = {
16206
16543
  "no-comment-cruft": no_comment_cruft_default,
16207
16544
  "no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
16208
16545
  "no-duplicate-lifecycle-refresh-listeners": no_duplicate_lifecycle_refresh_listeners_default,
16546
+ "no-dangerously-allow-svg": no_dangerously_allow_svg_default,
16209
16547
  "no-dynamic-sql": no_dynamic_sql_default,
16210
16548
  "no-enum": no_enum_default,
16211
16549
  "no-fat-try-blocks": no_fat_try_blocks_default,
@@ -16221,6 +16559,7 @@ var rules = {
16221
16559
  "no-generic-single-export-module": no_generic_single_export_module_default,
16222
16560
  "no-offset-pagination": no_offset_pagination_default,
16223
16561
  "no-positional-tuple-return": no_positional_tuple_return_default,
16562
+ "no-production-browser-source-maps": no_production_browser_source_maps_default,
16224
16563
  "no-raw-env": no_raw_env_default,
16225
16564
  "no-raw-fetch-outside-clients": no_raw_fetch_outside_clients_default,
16226
16565
  "no-restricted-library-load": no_restricted_library_load_default,
@@ -16229,6 +16568,7 @@ var rules = {
16229
16568
  "no-restated-comment": no_restated_comment_default,
16230
16569
  "no-restated-jsdoc": no_restated_jsdoc_default,
16231
16570
  "no-secret-in-log": no_secret_in_log_default,
16571
+ "no-server-env-in-client-component": no_server_env_in_client_component_default,
16232
16572
  "no-select-star": no_select_star_default,
16233
16573
  "no-sentinel-return-on-catch": no_sentinel_return_on_catch_default,
16234
16574
  "no-silent-promise-catch": no_silent_promise_catch_default,
@@ -16244,6 +16584,8 @@ var rules = {
16244
16584
  "no-unnecessary-use-client": no_unnecessary_use_client_default,
16245
16585
  "no-unsafe-mock-casting": no_unsafe_mock_casting_default,
16246
16586
  "no-zod-native-enum": no_zod_native_enum_default,
16587
+ "require-use-form-default-values": require_use_form_default_values_default,
16588
+ "require-use-server-in-actions-file": require_use_server_in_actions_file_default,
16247
16589
  "test-loops-over-literal-cases": test_loops_over_literal_cases_default,
16248
16590
  "test-phase-label-comment": test_phase_label_comment_default,
16249
16591
  "prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
@@ -16274,7 +16616,7 @@ var rules = {
16274
16616
  };
16275
16617
  var meta = {
16276
16618
  name: "@sarj/eslint-plugin",
16277
- version: "15.11.0"
16619
+ version: "15.12.0"
16278
16620
  };
16279
16621
  var applicationOnlyRules = [
16280
16622
  "no-restricted-library-load",
@@ -16283,10 +16625,15 @@ var applicationOnlyRules = [
16283
16625
  ];
16284
16626
  var advisoryRules = [
16285
16627
  "no-bare-return-from-test-catch",
16628
+ "no-dangerously-allow-svg",
16286
16629
  "no-duplicate-lifecycle-refresh-listeners",
16630
+ "no-production-browser-source-maps",
16287
16631
  "no-router-refresh-polling",
16632
+ "no-server-env-in-client-component",
16288
16633
  "iac-source-coupled-test",
16289
16634
  "repeated-static-call-cases",
16635
+ "require-use-form-default-values",
16636
+ "require-use-server-in-actions-file",
16290
16637
  "source-coupled-test",
16291
16638
  "test-phase-label-comment"
16292
16639
  ];
@@ -16306,17 +16653,20 @@ var recommendedRules = {
16306
16653
  "@sarj/no-impossible-zod-literal-bounds": "error",
16307
16654
  "@sarj/no-log-only-catch": "error",
16308
16655
  "@sarj/no-bare-return-from-test-catch": "warn",
16656
+ "@sarj/no-dangerously-allow-svg": "warn",
16309
16657
  "@sarj/no-duplicate-lifecycle-refresh-listeners": "warn",
16310
16658
  "@sarj/no-long-comment": "error",
16311
16659
  "@sarj/no-vague-suppression-description": "error",
16312
16660
  "@sarj/no-generic-single-export-module": "error",
16313
16661
  "@sarj/no-offset-pagination": "error",
16314
16662
  "@sarj/no-positional-tuple-return": "error",
16663
+ "@sarj/no-production-browser-source-maps": "warn",
16315
16664
  "@sarj/no-repeated-string-literal": "error",
16316
16665
  "@sarj/no-router-refresh-polling": "warn",
16317
16666
  "@sarj/no-restated-comment": "error",
16318
16667
  "@sarj/no-restated-jsdoc": "error",
16319
16668
  "@sarj/no-secret-in-log": "error",
16669
+ "@sarj/no-server-env-in-client-component": "warn",
16320
16670
  "@sarj/no-select-star": "error",
16321
16671
  "@sarj/no-sentinel-return-on-catch": "error",
16322
16672
  "@sarj/no-silent-promise-catch": "error",
@@ -16350,6 +16700,8 @@ var recommendedRules = {
16350
16700
  "@sarj/require-fetch-timeout": "error",
16351
16701
  "@sarj/require-port-for-service": "error",
16352
16702
  "@sarj/require-static-next-matcher": "error",
16703
+ "@sarj/require-use-form-default-values": "warn",
16704
+ "@sarj/require-use-server-in-actions-file": "warn",
16353
16705
  "@sarj/require-zod-form-validation": "error",
16354
16706
  "@sarj/store-insert-requires-on-conflict": "error",
16355
16707
  "@sarj/stepdown": "error",
@@ -16374,12 +16726,14 @@ var strictRules = {
16374
16726
  "@sarj/no-impossible-zod-literal-bounds": "error",
16375
16727
  "@sarj/no-log-only-catch": "error",
16376
16728
  "@sarj/no-bare-return-from-test-catch": "warn",
16729
+ "@sarj/no-dangerously-allow-svg": "warn",
16377
16730
  "@sarj/no-duplicate-lifecycle-refresh-listeners": "warn",
16378
16731
  "@sarj/no-long-comment": "error",
16379
16732
  "@sarj/no-vague-suppression-description": "error",
16380
16733
  "@sarj/no-generic-single-export-module": "error",
16381
16734
  "@sarj/no-offset-pagination": "error",
16382
16735
  "@sarj/no-positional-tuple-return": "error",
16736
+ "@sarj/no-production-browser-source-maps": "warn",
16383
16737
  "@sarj/no-raw-env": "error",
16384
16738
  "@sarj/no-raw-fetch-outside-clients": "error",
16385
16739
  "@sarj/no-repeated-string-literal": "error",
@@ -16387,6 +16741,7 @@ var strictRules = {
16387
16741
  "@sarj/no-restated-comment": "error",
16388
16742
  "@sarj/no-restated-jsdoc": "error",
16389
16743
  "@sarj/no-secret-in-log": "error",
16744
+ "@sarj/no-server-env-in-client-component": "warn",
16390
16745
  "@sarj/no-select-star": "error",
16391
16746
  "@sarj/no-sentinel-return-on-catch": "error",
16392
16747
  "@sarj/no-silent-promise-catch": "error",
@@ -16421,6 +16776,8 @@ var strictRules = {
16421
16776
  "@sarj/require-fetch-timeout": "error",
16422
16777
  "@sarj/require-port-for-service": "error",
16423
16778
  "@sarj/require-static-next-matcher": "error",
16779
+ "@sarj/require-use-form-default-values": "warn",
16780
+ "@sarj/require-use-server-in-actions-file": "warn",
16424
16781
  "@sarj/require-zod-form-validation": "error",
16425
16782
  "@sarj/store-insert-requires-on-conflict": "error",
16426
16783
  "@sarj/stepdown": "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarj/eslint-plugin",
3
- "version": "15.11.0",
3
+ "version": "15.12.0",
4
4
  "packageManager": "npm@12.0.2",
5
5
  "description": "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
6
6
  "type": "module",