eslint-plugin-firebase-ai-logic 1.3.0 → 1.5.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.
Files changed (30) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/rules/check-temperature-defaults.d.ts +10 -4
  3. package/dist/rules/check-temperature-defaults.d.ts.map +1 -1
  4. package/dist/rules/check-temperature-defaults.js +39 -8
  5. package/dist/rules/check-temperature-defaults.js.map +1 -1
  6. package/dist/rules/prefer-count-tokens.d.ts +28 -0
  7. package/dist/rules/prefer-count-tokens.d.ts.map +1 -1
  8. package/dist/rules/prefer-count-tokens.js +71 -7
  9. package/dist/rules/prefer-count-tokens.js.map +1 -1
  10. package/dist/rules/prefer-optional-properties.d.ts +18 -0
  11. package/dist/rules/prefer-optional-properties.d.ts.map +1 -1
  12. package/dist/rules/prefer-optional-properties.js +30 -2
  13. package/dist/rules/prefer-optional-properties.js.map +1 -1
  14. package/dist/rules/require-app-check-production.d.ts +4 -0
  15. package/dist/rules/require-app-check-production.d.ts.map +1 -1
  16. package/dist/rules/require-app-check-production.js +60 -11
  17. package/dist/rules/require-app-check-production.js.map +1 -1
  18. package/dist/rules/require-error-handling.d.ts +9 -0
  19. package/dist/rules/require-error-handling.d.ts.map +1 -1
  20. package/dist/rules/require-error-handling.js +142 -3
  21. package/dist/rules/require-error-handling.js.map +1 -1
  22. package/dist/rules/validate-schema-structure.d.ts +10 -2
  23. package/dist/rules/validate-schema-structure.d.ts.map +1 -1
  24. package/dist/rules/validate-schema-structure.js +36 -6
  25. package/dist/rules/validate-schema-structure.js.map +1 -1
  26. package/dist/utils/ast-helpers.d.ts +4 -0
  27. package/dist/utils/ast-helpers.d.ts.map +1 -1
  28. package/dist/utils/ast-helpers.js +21 -0
  29. package/dist/utils/ast-helpers.js.map +1 -1
  30. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -239,7 +239,7 @@ const configs = {
239
239
  const plugin = {
240
240
  meta: {
241
241
  name: 'eslint-plugin-firebase-ai-logic',
242
- version: '1.3.0',
242
+ version: '1.5.0',
243
243
  },
244
244
  rules,
245
245
  configs,
@@ -2,20 +2,26 @@ import type { Rule } from 'eslint';
2
2
  /**
3
3
  * check-temperature-defaults
4
4
  *
5
- * This rule suggests using the default temperature (1.0) for Gemini models,
5
+ * This rule suggests using the default temperature (1.0) for Gemini 3 models,
6
6
  * but with important exceptions:
7
7
  *
8
+ * ONLY APPLIES TO:
9
+ * - gemini-3-flash-preview
10
+ * - gemini-3-pro-preview
11
+ * (Other models like gemini-2.5-* don't have this recommendation)
12
+ *
8
13
  * EXCEPTIONS (low temperature is valid and recommended):
9
14
  * 1. Structured output (responseMimeType: 'application/json')
10
15
  * - Low temperature (0.1-0.3) prevents hallucinations in extraction tasks
11
- * 2. Classification tasks
16
+ * 2. Classification tasks (maxOutputTokens <= 20)
12
17
  * - Deterministic outputs benefit from low temperature
13
- * 3. Data extraction
18
+ * 3. Data extraction with responseSchema
14
19
  * - Precise extraction needs low temperature
15
20
  *
16
21
  * The rule only warns when:
22
+ * - Model is Gemini 3 (flash or pro preview)
17
23
  * - Temperature is NOT 1.0
18
- * - AND responseMimeType is NOT 'application/json' (structured output)
24
+ * - AND it's NOT a structured output or classification task
19
25
  */
20
26
  declare const rule: Rule.RuleModule;
21
27
  export default rule;
@@ -1 +1 @@
1
- {"version":3,"file":"check-temperature-defaults.d.ts","sourceRoot":"","sources":["../../src/rules/check-temperature-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAQnC;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAgFhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"check-temperature-defaults.d.ts","sourceRoot":"","sources":["../../src/rules/check-temperature-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AASnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA4GhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -4,35 +4,48 @@ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
4
  /**
5
5
  * check-temperature-defaults
6
6
  *
7
- * This rule suggests using the default temperature (1.0) for Gemini models,
7
+ * This rule suggests using the default temperature (1.0) for Gemini 3 models,
8
8
  * but with important exceptions:
9
9
  *
10
+ * ONLY APPLIES TO:
11
+ * - gemini-3-flash-preview
12
+ * - gemini-3-pro-preview
13
+ * (Other models like gemini-2.5-* don't have this recommendation)
14
+ *
10
15
  * EXCEPTIONS (low temperature is valid and recommended):
11
16
  * 1. Structured output (responseMimeType: 'application/json')
12
17
  * - Low temperature (0.1-0.3) prevents hallucinations in extraction tasks
13
- * 2. Classification tasks
18
+ * 2. Classification tasks (maxOutputTokens <= 20)
14
19
  * - Deterministic outputs benefit from low temperature
15
- * 3. Data extraction
20
+ * 3. Data extraction with responseSchema
16
21
  * - Precise extraction needs low temperature
17
22
  *
18
23
  * The rule only warns when:
24
+ * - Model is Gemini 3 (flash or pro preview)
19
25
  * - Temperature is NOT 1.0
20
- * - AND responseMimeType is NOT 'application/json' (structured output)
26
+ * - AND it's NOT a structured output or classification task
21
27
  */
22
28
  const rule = {
23
29
  meta: {
24
30
  type: 'suggestion',
25
31
  docs: {
26
- description: 'Suggest default temperature (1.0) for Gemini models, except for structured output tasks',
32
+ description: 'Suggest default temperature (1.0) for Gemini 3 models, except for structured output and classification tasks',
27
33
  recommended: true,
28
34
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#check-temperature-defaults',
29
35
  },
30
36
  schema: [],
31
37
  messages: {
32
- nonDefaultTemperature: 'Consider using the default temperature (1.0) for Gemini models. Lower values may cause looping or degraded reasoning. Exception: low temperature (0.1-0.3) is appropriate for structured output (JSON extraction) tasks.',
38
+ nonDefaultTemperature: 'Consider using the default temperature (1.0) for Gemini 3 models. Lower values may cause looping or degraded reasoning. Exception: low temperature is appropriate for structured output (JSON) and classification tasks.',
33
39
  },
34
40
  },
35
41
  create(context) {
42
+ // Gemini 3 models that have the temperature=1.0 recommendation
43
+ const GEMINI_3_MODELS = [
44
+ 'gemini-3-flash-preview',
45
+ 'gemini-3-pro-preview',
46
+ 'gemini-3-flash',
47
+ 'gemini-3-pro',
48
+ ];
36
49
  return {
37
50
  CallExpression(node) {
38
51
  const calleeName = (0, ast_helpers_js_1.getCalleeName)(node);
@@ -45,9 +58,18 @@ const rule = {
45
58
  const configArg = node.arguments[1];
46
59
  if (!configArg || !(0, ast_helpers_js_1.isObjectExpression)(configArg))
47
60
  return;
61
+ // Check model name - only apply to Gemini 3 models
62
+ const modelProp = (0, ast_helpers_js_1.findProperty)(configArg, 'model');
63
+ if (modelProp) {
64
+ const modelName = (0, ast_helpers_js_1.getStringValue)(modelProp.value);
65
+ if (modelName && !GEMINI_3_MODELS.some(m => modelName.includes(m))) {
66
+ // Not a Gemini 3 model - don't apply this rule
67
+ return;
68
+ }
69
+ }
48
70
  // Check for generationConfig
49
- let generationConfig = (0, ast_helpers_js_1.findProperty)(configArg, 'generationConfig');
50
- let configToCheck = generationConfig
71
+ const generationConfig = (0, ast_helpers_js_1.findProperty)(configArg, 'generationConfig');
72
+ const configToCheck = generationConfig
51
73
  ? generationConfig.value
52
74
  : configArg;
53
75
  if (!(0, ast_helpers_js_1.isObjectExpression)(configToCheck))
@@ -67,6 +89,15 @@ const rule = {
67
89
  // Has response schema - structured output, don't warn
68
90
  return;
69
91
  }
92
+ // Check for maxOutputTokens - if very low (<= 20), it's likely classification
93
+ const maxOutputTokensProp = (0, ast_helpers_js_1.findProperty)(configToCheck, 'maxOutputTokens');
94
+ if (maxOutputTokensProp) {
95
+ const maxTokens = (0, ast_helpers_js_1.getNumberValue)(maxOutputTokensProp.value);
96
+ if (maxTokens !== null && maxTokens <= 20) {
97
+ // Classification task (very short output) - low temperature is appropriate
98
+ return;
99
+ }
100
+ }
70
101
  // Check for temperature property
71
102
  const temperatureProp = (0, ast_helpers_js_1.findProperty)(configToCheck, 'temperature');
72
103
  if (temperatureProp) {
@@ -1 +1 @@
1
- {"version":3,"file":"check-temperature-defaults.js","sourceRoot":"","sources":["../../src/rules/check-temperature-defaults.ts"],"names":[],"mappings":";;AACA,4DAKiC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,yFAAyF;YAC3F,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,wFAAwF;SAC9F;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,qBAAqB,EACnB,0NAA0N;SAC7N;KACF;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,MAAM,UAAU,GAAG,IAAA,8BAAa,EAAC,IAAI,CAAC,CAAC;gBAEvC,oDAAoD;gBACpD,IACE,UAAU,KAAK,oBAAoB;oBACnC,UAAU,KAAK,iBAAiB,EAChC,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,+CAA+C;gBAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAA,mCAAkB,EAAC,SAAS,CAAC;oBAAE,OAAO;gBAEzD,6BAA6B;gBAC7B,IAAI,gBAAgB,GAAG,IAAA,6BAAY,EAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;gBACnE,IAAI,aAAa,GAAG,gBAAgB;oBAClC,CAAC,CAAC,gBAAgB,CAAC,KAAK;oBACxB,CAAC,CAAC,SAAS,CAAC;gBAEd,IAAI,CAAC,IAAA,mCAAkB,EAAC,aAAa,CAAC;oBAAE,OAAO;gBAE/C,oFAAoF;gBACpF,MAAM,oBAAoB,GAAG,IAAA,6BAAY,EAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;gBAC7E,IAAI,oBAAoB,EAAE,CAAC;oBACzB,MAAM,QAAQ,GAAG,IAAA,+BAAc,EAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;oBAC5D,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;wBACpC,iEAAiE;wBACjE,OAAO;oBACT,CAAC;gBACH,CAAC;gBAED,gEAAgE;gBAChE,MAAM,kBAAkB,GAAG,IAAA,6BAAY,EAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;gBACzE,IAAI,kBAAkB,EAAE,CAAC;oBACvB,sDAAsD;oBACtD,OAAO;gBACT,CAAC;gBAED,iCAAiC;gBACjC,MAAM,eAAe,GAAG,IAAA,6BAAY,EAAC,aAAa,EAAE,aAAa,CAAC,CAAC;gBAEnE,IAAI,eAAe,EAAE,CAAC;oBACpB,uEAAuE;oBACvE,IACE,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;wBACxC,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAC/C,CAAC;wBACD,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC;wBACzC,yEAAyE;wBACzE,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;4BACjB,OAAO,CAAC,MAAM,CAAC;gCACb,IAAI,EAAE,eAAe;gCACrB,SAAS,EAAE,uBAAuB;6BACnC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"check-temperature-defaults.js","sourceRoot":"","sources":["../../src/rules/check-temperature-defaults.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,32 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * prefer-count-tokens
4
+ *
5
+ * This rule suggests using countTokens() before large requests.
6
+ *
7
+ * WHY 2000 CHARACTERS DEFAULT?
8
+ * - 2000 chars ≈ 500 tokens (roughly 4 chars per token)
9
+ * - Cost increases significantly above 200K tokens context
10
+ * - countTokens API is FREE and has 3000 RPM quota
11
+ * - Below 500 tokens, the cost impact is minimal (~$0.0001 for flash)
12
+ *
13
+ * Based on Google's pricing:
14
+ * - Gemini 2.5 Flash-Lite: $0.10/M input tokens
15
+ * - Gemini 2.5 Flash: $0.15/M input tokens
16
+ * - Gemini 3 Pro: $2.00/M input tokens (up to 200K), $4.00/M above
17
+ *
18
+ * The rule is meant to catch large prompts that could:
19
+ * 1. Unexpectedly increase costs
20
+ * 2. Risk exceeding context window limits
21
+ * 3. Benefit from cost estimation before sending
22
+ *
23
+ * IGNORED PATTERNS:
24
+ * - Arrays containing functionResponse (these are function call responses)
25
+ * - System instructions (static, known at dev time)
26
+ *
27
+ * @see https://ai.google.dev/gemini-api/docs/tokens
28
+ * @see https://ai.google.dev/gemini-api/docs/pricing
29
+ */
2
30
  declare const rule: Rule.RuleModule;
3
31
  export default rule;
4
32
  //# sourceMappingURL=prefer-count-tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-count-tokens.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-count-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA0HhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"prefer-count-tokens.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-count-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA8JhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,6 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
+ /**
5
+ * prefer-count-tokens
6
+ *
7
+ * This rule suggests using countTokens() before large requests.
8
+ *
9
+ * WHY 2000 CHARACTERS DEFAULT?
10
+ * - 2000 chars ≈ 500 tokens (roughly 4 chars per token)
11
+ * - Cost increases significantly above 200K tokens context
12
+ * - countTokens API is FREE and has 3000 RPM quota
13
+ * - Below 500 tokens, the cost impact is minimal (~$0.0001 for flash)
14
+ *
15
+ * Based on Google's pricing:
16
+ * - Gemini 2.5 Flash-Lite: $0.10/M input tokens
17
+ * - Gemini 2.5 Flash: $0.15/M input tokens
18
+ * - Gemini 3 Pro: $2.00/M input tokens (up to 200K), $4.00/M above
19
+ *
20
+ * The rule is meant to catch large prompts that could:
21
+ * 1. Unexpectedly increase costs
22
+ * 2. Risk exceeding context window limits
23
+ * 3. Benefit from cost estimation before sending
24
+ *
25
+ * IGNORED PATTERNS:
26
+ * - Arrays containing functionResponse (these are function call responses)
27
+ * - System instructions (static, known at dev time)
28
+ *
29
+ * @see https://ai.google.dev/gemini-api/docs/tokens
30
+ * @see https://ai.google.dev/gemini-api/docs/pricing
31
+ */
4
32
  const rule = {
5
33
  meta: {
6
34
  type: 'suggestion',
@@ -15,8 +43,18 @@ const rule = {
15
43
  properties: {
16
44
  promptLengthThreshold: {
17
45
  type: 'number',
18
- default: 500,
19
- description: 'Character length threshold to suggest token counting',
46
+ default: 2000,
47
+ description: 'Character length threshold to suggest token counting (default: 2000 chars ≈ 500 tokens)',
48
+ },
49
+ ignoreArraysWithFunctionResponse: {
50
+ type: 'boolean',
51
+ default: true,
52
+ description: 'Ignore arrays that contain functionResponse (these are function call responses, not user prompts)',
53
+ },
54
+ warnOnMultimodalArrays: {
55
+ type: 'boolean',
56
+ default: true,
57
+ description: 'Warn when arrays are passed (may contain images that consume many tokens)',
20
58
  },
21
59
  },
22
60
  additionalProperties: false,
@@ -29,7 +67,11 @@ const rule = {
29
67
  },
30
68
  create(context) {
31
69
  const options = context.options[0] ?? {};
32
- const promptLengthThreshold = options.promptLengthThreshold ?? 500;
70
+ // Default threshold: 2000 chars 500 tokens
71
+ // This is a reasonable threshold where token counting becomes useful
72
+ const promptLengthThreshold = options.promptLengthThreshold ?? 2000;
73
+ const ignoreArraysWithFunctionResponse = options.ignoreArraysWithFunctionResponse !== false;
74
+ const warnOnMultimodalArrays = options.warnOnMultimodalArrays !== false;
33
75
  // Track if countTokens was called in the same scope
34
76
  const scopesWithCountTokens = new Set();
35
77
  function getScopeKey(node) {
@@ -82,11 +124,33 @@ const rule = {
82
124
  // Add estimated expression length (rough estimate)
83
125
  promptLength += promptArg.expressions.length * 50;
84
126
  }
85
- // Array of parts (multimodal)
127
+ // Array of parts (multimodal or function responses)
86
128
  if (promptArg.type === 'ArrayExpression') {
87
- // For arrays, we should definitely suggest counting tokens
88
- // as they might contain images which consume many tokens
89
- promptLength = promptLengthThreshold + 1; // Force suggestion
129
+ // Check if array contains functionResponse
130
+ // Pattern: [{ functionResponse: { ... } }]
131
+ if (ignoreArraysWithFunctionResponse) {
132
+ const hasFunctionResponse = promptArg.elements.some((el) => {
133
+ if (!el || el.type !== 'ObjectExpression')
134
+ return false;
135
+ return el.properties.some((prop) => {
136
+ if (prop.type !== 'Property')
137
+ return false;
138
+ if (prop.key.type === 'Identifier' && prop.key.name === 'functionResponse') {
139
+ return true;
140
+ }
141
+ return false;
142
+ });
143
+ });
144
+ if (hasFunctionResponse) {
145
+ // This is a function call response, not a user prompt
146
+ // Skip - these are controlled responses, not user input
147
+ return;
148
+ }
149
+ }
150
+ // For other arrays (multimodal with images), suggest counting tokens
151
+ if (warnOnMultimodalArrays) {
152
+ promptLength = promptLengthThreshold + 1; // Force suggestion
153
+ }
90
154
  }
91
155
  if (promptLength > promptLengthThreshold) {
92
156
  context.report({
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-count-tokens.js","sourceRoot":"","sources":["../../src/rules/prefer-count-tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-count-tokens.js","sourceRoot":"","sources":["../../src/rules/prefer-count-tokens.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,22 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * prefer-optional-properties
4
+ *
5
+ * This rule suggests using 'optionalProperties' array for optional fields,
6
+ * but with important exceptions:
7
+ *
8
+ * EXCEPTIONS (no warning):
9
+ * 1. If the schema has a 'required' array defined
10
+ * - This is the standard way to define required fields in function calling
11
+ * - Fields not in 'required' are implicitly optional
12
+ * 2. If the schema is for function calling parameters
13
+ * - Function calling uses 'required' array pattern
14
+ *
15
+ * The rule only warns when:
16
+ * - Schema has many properties (>5)
17
+ * - AND no 'optionalProperties' array
18
+ * - AND no 'required' array (which would indicate intent)
19
+ */
2
20
  declare const rule: Rule.RuleModule;
3
21
  export default rule;
4
22
  //# sourceMappingURL=prefer-optional-properties.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-optional-properties.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-optional-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAQnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA0GhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"prefer-optional-properties.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-optional-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAQnC;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAqHhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,6 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
+ /**
5
+ * prefer-optional-properties
6
+ *
7
+ * This rule suggests using 'optionalProperties' array for optional fields,
8
+ * but with important exceptions:
9
+ *
10
+ * EXCEPTIONS (no warning):
11
+ * 1. If the schema has a 'required' array defined
12
+ * - This is the standard way to define required fields in function calling
13
+ * - Fields not in 'required' are implicitly optional
14
+ * 2. If the schema is for function calling parameters
15
+ * - Function calling uses 'required' array pattern
16
+ *
17
+ * The rule only warns when:
18
+ * - Schema has many properties (>5)
19
+ * - AND no 'optionalProperties' array
20
+ * - AND no 'required' array (which would indicate intent)
21
+ */
4
22
  const rule = {
5
23
  meta: {
6
24
  type: 'suggestion',
@@ -13,7 +31,7 @@ const rule = {
13
31
  messages: {
14
32
  useOptionalProperties: "In Firebase AI Logic, all schema fields are required by default. Use 'optionalProperties: [\"fieldName\"]' array to mark fields as optional.",
15
33
  nullableNotOptional: "Using 'nullable: true' makes the field accept null but still requires it. Use 'optionalProperties' array to make it truly optional.",
16
- missingOptionalProperties: "Schema has many properties but no 'optionalProperties' array. Consider which fields should be optional.",
34
+ missingOptionalProperties: "Schema has many properties but no 'optionalProperties' or 'required' array. Consider which fields should be optional.",
17
35
  },
18
36
  },
19
37
  create(context) {
@@ -22,6 +40,12 @@ const rule = {
22
40
  return;
23
41
  const propertiesProp = (0, ast_helpers_js_1.findProperty)(obj, 'properties');
24
42
  const optionalPropertiesProp = (0, ast_helpers_js_1.findProperty)(obj, 'optionalProperties');
43
+ const requiredProp = (0, ast_helpers_js_1.findProperty)(obj, 'required');
44
+ // If 'required' array is defined, the developer has explicitly chosen
45
+ // which fields are required - no need to warn about optionalProperties
46
+ if (requiredProp) {
47
+ return;
48
+ }
25
49
  // Check for nullable fields without optionalProperties
26
50
  if (propertiesProp && (0, ast_helpers_js_1.isObjectExpression)(propertiesProp.value)) {
27
51
  const propsObj = propertiesProp.value;
@@ -55,7 +79,11 @@ const rule = {
55
79
  // Check if schema has many properties but no optionalProperties
56
80
  if (propertiesProp && (0, ast_helpers_js_1.isObjectExpression)(propertiesProp.value)) {
57
81
  const propertyCount = propertiesProp.value.properties.filter(ast_helpers_js_1.isProperty).length;
58
- if (propertyCount > 5 && !optionalPropertiesProp) {
82
+ // Only warn if:
83
+ // - Many properties (>5)
84
+ // - No optionalProperties
85
+ // - No required array (which indicates intentional field selection)
86
+ if (propertyCount > 5 && !optionalPropertiesProp && !requiredProp) {
59
87
  context.report({
60
88
  node: obj,
61
89
  messageId: 'missingOptionalProperties',
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-optional-properties.js","sourceRoot":"","sources":["../../src/rules/prefer-optional-properties.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-optional-properties.js","sourceRoot":"","sources":["../../src/rules/prefer-optional-properties.ts"],"names":[],"mappings":"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"}
@@ -13,8 +13,12 @@ import type { Rule } from 'eslint';
13
13
  * 1. Direct import of 'firebase/app-check'
14
14
  * 2. Calls to initializeAppCheck()
15
15
  * 3. Common patterns: useAppCheck, ensureAppCheckReady, AppCheckProvider
16
+ * 4. Module-level detection: If the file imports from a module that handles AI
17
+ * (like './ai' or '../firebase/ai'), it's likely App Check is handled there
16
18
  *
17
19
  * If none are found in the same file as getAI(), it suggests (not requires) App Check.
20
+ *
21
+ * CONFIGURABLE: Set 'ignoreFiles' to skip specific files/patterns.
18
22
  */
19
23
  declare const rule: Rule.RuleModule;
20
24
  export default rule;
@@ -1 +1 @@
1
- {"version":3,"file":"require-app-check-production.d.ts","sourceRoot":"","sources":["../../src/rules/require-app-check-production.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAsGhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"require-app-check-production.d.ts","sourceRoot":"","sources":["../../src/rules/require-app-check-production.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA0JhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -15,8 +15,12 @@ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
15
15
  * 1. Direct import of 'firebase/app-check'
16
16
  * 2. Calls to initializeAppCheck()
17
17
  * 3. Common patterns: useAppCheck, ensureAppCheckReady, AppCheckProvider
18
+ * 4. Module-level detection: If the file imports from a module that handles AI
19
+ * (like './ai' or '../firebase/ai'), it's likely App Check is handled there
18
20
  *
19
21
  * If none are found in the same file as getAI(), it suggests (not requires) App Check.
22
+ *
23
+ * CONFIGURABLE: Set 'ignoreFiles' to skip specific files/patterns.
20
24
  */
21
25
  const rule = {
22
26
  meta: {
@@ -26,7 +30,20 @@ const rule = {
26
30
  recommended: true,
27
31
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#require-app-check-production',
28
32
  },
29
- schema: [],
33
+ schema: [
34
+ {
35
+ type: 'object',
36
+ properties: {
37
+ ignoreFiles: {
38
+ type: 'array',
39
+ items: { type: 'string' },
40
+ default: [],
41
+ description: 'File patterns to ignore (e.g., "*.test.ts", "test/**/*")',
42
+ },
43
+ },
44
+ additionalProperties: false,
45
+ },
46
+ ],
30
47
  messages: {
31
48
  missingAppCheck: 'Consider using App Check to protect your AI endpoints from abuse. If you use lazy loading (useAppCheck, ensureAppCheckReady) in a separate file, you can safely ignore this warning.',
32
49
  appCheckSuggestion: "import { initializeAppCheck, ReCaptchaEnterpriseProvider } from 'firebase/app-check'; initializeAppCheck(app, { provider: new ReCaptchaEnterpriseProvider('SITE_KEY') });",
@@ -38,6 +55,7 @@ const rule = {
38
55
  let hasAppCheckHelper = false;
39
56
  let hasAIInit = false;
40
57
  let aiInitNode = null;
58
+ let importsFromAIModule = false;
41
59
  // Common App Check helper patterns used in lazy loading
42
60
  const appCheckHelperPatterns = [
43
61
  'useAppCheck',
@@ -46,28 +64,52 @@ const rule = {
46
64
  'getAppCheckInstance',
47
65
  'isAppCheckReady',
48
66
  'initializeAppCheckLazy',
67
+ 'withAppCheck',
68
+ 'appCheckReady',
69
+ ];
70
+ // Common AI module patterns where App Check might be configured
71
+ const aiModulePatterns = [
72
+ '/ai',
73
+ '/firebase/ai',
74
+ '/lib/ai',
75
+ '/services/ai',
76
+ 'getAIInstance',
77
+ 'aiService',
49
78
  ];
50
79
  return {
51
80
  // Track App Check imports
52
81
  ImportDeclaration(node) {
53
82
  const source = node.source.value;
83
+ if (typeof source !== 'string')
84
+ return;
54
85
  // Direct firebase/app-check import
55
86
  if (source === 'firebase/app-check') {
56
87
  hasAppCheckImport = true;
57
88
  }
58
89
  // Check for imports from common App Check helper files/hooks
59
- if (typeof source === 'string' &&
60
- (source.includes('useAppCheck') ||
61
- source.includes('AppCheck') ||
62
- source.includes('appCheck'))) {
90
+ if (source.includes('useAppCheck') ||
91
+ source.includes('AppCheck') ||
92
+ source.includes('appCheck')) {
63
93
  hasAppCheckHelper = true;
64
94
  }
95
+ // Check if importing from a common AI module pattern
96
+ // These modules typically handle App Check internally
97
+ if (aiModulePatterns.some((pattern) => source.includes(pattern))) {
98
+ importsFromAIModule = true;
99
+ }
65
100
  // Check imported specifiers for App Check helpers
66
101
  for (const spec of node.specifiers) {
67
102
  if (spec.type === 'ImportSpecifier' && spec.imported.type === 'Identifier') {
68
- if (appCheckHelperPatterns.includes(spec.imported.name)) {
103
+ const importedName = spec.imported.name;
104
+ if (appCheckHelperPatterns.includes(importedName)) {
69
105
  hasAppCheckHelper = true;
70
106
  }
107
+ // Check if importing getAIInstance or similar from another module
108
+ if (importedName === 'getAIInstance' ||
109
+ importedName === 'getAI' ||
110
+ importedName === 'aiInstance') {
111
+ importsFromAIModule = true;
112
+ }
71
113
  }
72
114
  }
73
115
  },
@@ -84,16 +126,23 @@ const rule = {
84
126
  if (appCheckHelperPatterns.includes(calleeName)) {
85
127
  hasAppCheckHelper = true;
86
128
  }
87
- // Track getAI calls
129
+ // Track getAI calls - but only if it's a DIRECT call, not imported wrapper
88
130
  if (calleeName === 'getAI') {
89
- hasAIInit = true;
90
- aiInitNode = node;
131
+ // Check if this is the actual firebase/ai getAI or a wrapper
132
+ // If we already import from an AI module, the App Check is likely handled there
133
+ if (!importsFromAIModule) {
134
+ hasAIInit = true;
135
+ aiInitNode = node;
136
+ }
91
137
  }
92
138
  },
93
139
  // Check at the end of the program
94
140
  'Program:exit'() {
95
- // Only suggest if AI is being used but no App Check patterns found
96
- const hasAnyAppCheckPattern = hasAppCheckImport || hasAppCheckInit || hasAppCheckHelper;
141
+ // Only suggest if:
142
+ // 1. AI is being used directly (not via imported wrapper)
143
+ // 2. No App Check patterns found
144
+ // 3. Not importing from a module that likely handles App Check
145
+ const hasAnyAppCheckPattern = hasAppCheckImport || hasAppCheckInit || hasAppCheckHelper || importsFromAIModule;
97
146
  if (hasAIInit && !hasAnyAppCheckPattern && aiInitNode) {
98
147
  context.report({
99
148
  node: aiInitNode,
@@ -1 +1 @@
1
- {"version":3,"file":"require-app-check-production.js","sourceRoot":"","sources":["../../src/rules/require-app-check-production.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"require-app-check-production.js","sourceRoot":"","sources":["../../src/rules/require-app-check-production.ts"],"names":[],"mappings":"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"}
@@ -14,11 +14,20 @@ import type { Rule } from 'eslint';
14
14
  * - safeCall
15
15
  * - handleApiCall
16
16
  * - executeWithRetry
17
+ * 5. Async generators (errors propagate to consumer's try/catch)
18
+ * 6. Class methods that are async generators
19
+ * 7. Calls prefixed with "void" operator (fire-and-forget pattern)
17
20
  *
18
21
  * The rule checks if the API call is:
19
22
  * - Inside a try/catch block
20
23
  * - Chained with .catch()
21
24
  * - Wrapped in a known error-handling function
25
+ * - Inside an async generator (errors propagate to consumer)
26
+ * - Called with "void" operator (assumes internal error handling)
27
+ *
28
+ * OPTIONS:
29
+ * - ignoreVoidCalls (boolean, default: true): Ignore calls with "void" operator
30
+ * - ignoreCallers (string[], default: []): Function names to ignore
22
31
  */
23
32
  declare const rule: Rule.RuleModule;
24
33
  export default rule;
@@ -1 +1 @@
1
- {"version":3,"file":"require-error-handling.d.ts","sourceRoot":"","sources":["../../src/rules/require-error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAgKhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"require-error-handling.d.ts","sourceRoot":"","sources":["../../src/rules/require-error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAiUhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -16,11 +16,20 @@ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
16
16
  * - safeCall
17
17
  * - handleApiCall
18
18
  * - executeWithRetry
19
+ * 5. Async generators (errors propagate to consumer's try/catch)
20
+ * 6. Class methods that are async generators
21
+ * 7. Calls prefixed with "void" operator (fire-and-forget pattern)
19
22
  *
20
23
  * The rule checks if the API call is:
21
24
  * - Inside a try/catch block
22
25
  * - Chained with .catch()
23
26
  * - Wrapped in a known error-handling function
27
+ * - Inside an async generator (errors propagate to consumer)
28
+ * - Called with "void" operator (assumes internal error handling)
29
+ *
30
+ * OPTIONS:
31
+ * - ignoreVoidCalls (boolean, default: true): Ignore calls with "void" operator
32
+ * - ignoreCallers (string[], default: []): Function names to ignore
24
33
  */
25
34
  const rule = {
26
35
  meta: {
@@ -30,7 +39,25 @@ const rule = {
30
39
  recommended: true,
31
40
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#require-error-handling',
32
41
  },
33
- schema: [],
42
+ schema: [
43
+ {
44
+ type: 'object',
45
+ properties: {
46
+ ignoreVoidCalls: {
47
+ type: 'boolean',
48
+ default: true,
49
+ description: 'Ignore calls prefixed with "void" operator. These typically call functions that handle errors internally.',
50
+ },
51
+ ignoreCallers: {
52
+ type: 'array',
53
+ items: { type: 'string' },
54
+ default: [],
55
+ description: 'Function names to ignore when they call API methods (e.g., ["sendMessage", "handleSubmit"]). Useful for wrapper functions with internal error handling.',
56
+ },
57
+ },
58
+ additionalProperties: false,
59
+ },
60
+ ],
34
61
  messages: {
35
62
  missingErrorHandling: "Firebase AI Logic API call '{{ method }}' should be wrapped in try/catch to handle errors, especially 429 rate limit errors.",
36
63
  suggest429Handling: 'Implement exponential backoff with jitter for 429 errors: delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000',
@@ -38,6 +65,9 @@ const rule = {
38
65
  },
39
66
  },
40
67
  create(context) {
68
+ const options = context.options[0] ?? {};
69
+ const ignoreVoidCalls = options.ignoreVoidCalls !== false; // Default true
70
+ const ignoreCallers = options.ignoreCallers ?? [];
41
71
  // Methods that make API calls and should have error handling
42
72
  const apiMethods = [
43
73
  'generateContent',
@@ -125,6 +155,105 @@ const rule = {
125
155
  }
126
156
  return false;
127
157
  }
158
+ /**
159
+ * Check if the call is inside an async generator function.
160
+ * Async generators propagate errors to the consumer's for-await-of loop,
161
+ * where they can be caught in a try/catch block. This is a valid error
162
+ * handling pattern.
163
+ */
164
+ function isInsideAsyncGenerator(node) {
165
+ let current = node.parent;
166
+ while (current) {
167
+ // Check for async generator functions (function* or async function*)
168
+ if (current.type === 'FunctionDeclaration' ||
169
+ current.type === 'FunctionExpression') {
170
+ const funcNode = current;
171
+ if (funcNode.async && funcNode.generator) {
172
+ return true;
173
+ }
174
+ }
175
+ // Check for async generator method definitions in classes
176
+ if (current.type === 'MethodDefinition') {
177
+ const methodNode = current;
178
+ if (methodNode.value?.async && methodNode.value?.generator) {
179
+ return true;
180
+ }
181
+ }
182
+ current = current.parent || null;
183
+ }
184
+ return false;
185
+ }
186
+ /**
187
+ * Check if the call is wrapped with the "void" operator.
188
+ * Pattern: void sendMessage(msg)
189
+ *
190
+ * When using "void", developers intentionally fire-and-forget,
191
+ * meaning error handling is expected to be inside the called function.
192
+ */
193
+ function isVoidCall(node) {
194
+ const parent = node.parent;
195
+ if (!parent)
196
+ return false;
197
+ // Direct void: void sendMessage()
198
+ if (parent.type === 'UnaryExpression') {
199
+ const unary = parent;
200
+ if (unary.operator === 'void') {
201
+ return true;
202
+ }
203
+ }
204
+ // void wrapper(): void wrapperFn() where wrapperFn calls sendMessage
205
+ // Check if we're inside a function that's called with void
206
+ let current = parent;
207
+ while (current) {
208
+ if (current.type === 'ArrowFunctionExpression' ||
209
+ current.type === 'FunctionExpression') {
210
+ const funcParent = current.parent;
211
+ if (funcParent?.type === 'CallExpression') {
212
+ const callParent = funcParent.parent;
213
+ if (callParent?.type === 'UnaryExpression') {
214
+ const unary = callParent;
215
+ if (unary.operator === 'void') {
216
+ return true;
217
+ }
218
+ }
219
+ }
220
+ }
221
+ current = current.parent ?? null;
222
+ }
223
+ return false;
224
+ }
225
+ /**
226
+ * Check if the API call is inside a caller function that should be ignored.
227
+ * This handles the pattern where a wrapper function (e.g., sendMessage in a hook)
228
+ * has internal error handling, and is called from elsewhere.
229
+ */
230
+ function isInsideIgnoredCaller(node) {
231
+ if (ignoreCallers.length === 0)
232
+ return false;
233
+ let current = node.parent ?? null;
234
+ while (current) {
235
+ // Check for function declaration with matching name
236
+ if (current.type === 'FunctionDeclaration') {
237
+ const funcDecl = current;
238
+ if (funcDecl.id && ignoreCallers.includes(funcDecl.id.name)) {
239
+ return true;
240
+ }
241
+ }
242
+ // Check for variable declaration: const sendMessage = async () => { ... }
243
+ if (current.type === 'ArrowFunctionExpression' ||
244
+ current.type === 'FunctionExpression') {
245
+ const funcParent = current.parent;
246
+ if (funcParent?.type === 'VariableDeclarator') {
247
+ const varDecl = funcParent;
248
+ if (varDecl.id && ignoreCallers.includes(varDecl.id.name)) {
249
+ return true;
250
+ }
251
+ }
252
+ }
253
+ current = current.parent ?? null;
254
+ }
255
+ return false;
256
+ }
128
257
  return {
129
258
  CallExpression(node) {
130
259
  const calleeName = (0, ast_helpers_js_1.getCalleeName)(node);
@@ -133,10 +262,20 @@ const rule = {
133
262
  }
134
263
  // Check if this is an awaited call
135
264
  const isAwaited = node.parent?.type === 'AwaitExpression';
136
- // Check if inside try/catch, has .catch(), or inside error handling wrapper
265
+ // Check for void operator (fire-and-forget pattern)
266
+ if (ignoreVoidCalls && isVoidCall(node)) {
267
+ return;
268
+ }
269
+ // Check if inside an ignored caller function
270
+ if (isInsideIgnoredCaller(node)) {
271
+ return;
272
+ }
273
+ // Check if inside try/catch, has .catch(), inside error handling wrapper,
274
+ // or inside an async generator (which propagates errors to consumer)
137
275
  const hasErrorHandling = isInsideTryCatch(node) ||
138
276
  isInsideAsyncErrorBoundary(node) ||
139
- isInsideErrorHandlingWrapper(node);
277
+ isInsideErrorHandlingWrapper(node) ||
278
+ isInsideAsyncGenerator(node);
140
279
  if (!hasErrorHandling) {
141
280
  context.report({
142
281
  node,
@@ -1 +1 @@
1
- {"version":3,"file":"require-error-handling.js","sourceRoot":"","sources":["../../src/rules/require-error-handling.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"require-error-handling.js","sourceRoot":"","sources":["../../src/rules/require-error-handling.ts"],"names":[],"mappings":"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"}
@@ -12,8 +12,16 @@ import type { Rule } from 'eslint';
12
12
  * This rule should NOT report errors for using "required" in Schema.object()
13
13
  * because it's a valid and common pattern for function calling parameters.
14
14
  *
15
- * The rule now only warns about using BOTH "required" AND "optionalProperties"
16
- * in the same schema, which is redundant.
15
+ * The rule only suggests (not warns) when using BOTH "required" AND
16
+ * "optionalProperties" in the same schema - which while redundant, is
17
+ * technically valid and can improve code clarity/documentation.
18
+ *
19
+ * DEFAULT BEHAVIOR: Allows both "required" and "optionalProperties" because:
20
+ * 1. It's a valid pattern in Firebase AI SDK
21
+ * 2. It improves readability by being explicit
22
+ * 3. Many codebases use this pattern deliberately
23
+ *
24
+ * CONFIGURABLE: Set 'allowBothRequiredAndOptional' to false to enable warnings.
17
25
  */
18
26
  declare const rule: Rule.RuleModule;
19
27
  export default rule;
@@ -1 +1 @@
1
- {"version":3,"file":"validate-schema-structure.d.ts","sourceRoot":"","sources":["../../src/rules/validate-schema-structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAqChB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"validate-schema-structure.d.ts","sourceRoot":"","sources":["../../src/rules/validate-schema-structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA8DhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -14,8 +14,16 @@ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
14
14
  * This rule should NOT report errors for using "required" in Schema.object()
15
15
  * because it's a valid and common pattern for function calling parameters.
16
16
  *
17
- * The rule now only warns about using BOTH "required" AND "optionalProperties"
18
- * in the same schema, which is redundant.
17
+ * The rule only suggests (not warns) when using BOTH "required" AND
18
+ * "optionalProperties" in the same schema - which while redundant, is
19
+ * technically valid and can improve code clarity/documentation.
20
+ *
21
+ * DEFAULT BEHAVIOR: Allows both "required" and "optionalProperties" because:
22
+ * 1. It's a valid pattern in Firebase AI SDK
23
+ * 2. It improves readability by being explicit
24
+ * 3. Many codebases use this pattern deliberately
25
+ *
26
+ * CONFIGURABLE: Set 'allowBothRequiredAndOptional' to false to enable warnings.
19
27
  */
20
28
  const rule = {
21
29
  meta: {
@@ -25,23 +33,45 @@ const rule = {
25
33
  recommended: true,
26
34
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#validate-schema-structure',
27
35
  },
28
- schema: [],
36
+ schema: [
37
+ {
38
+ type: 'object',
39
+ properties: {
40
+ allowBothRequiredAndOptional: {
41
+ type: 'boolean',
42
+ default: true,
43
+ description: 'Allow using both "required" and "optionalProperties" in the same schema. Set to false to warn about redundancy.',
44
+ },
45
+ },
46
+ additionalProperties: false,
47
+ },
48
+ ],
29
49
  messages: {
30
- redundantBothRequiredAndOptional: 'Schema has both "required" and "optionalProperties". Consider using only one approach for clarity: either list required fields in "required" array, or list optional fields in "optionalProperties" array.',
50
+ redundantBothRequiredAndOptional: 'Schema has both "required" and "optionalProperties". This is valid but redundant - consider using only one approach for clarity.',
31
51
  },
32
52
  },
33
53
  create(context) {
54
+ const options = context.options[0] ?? {};
55
+ // Default is true - allow both patterns since it's valid and improves readability
56
+ const allowBothRequiredAndOptional = options.allowBothRequiredAndOptional !== false;
34
57
  return {
35
58
  // Check for objects that have BOTH required AND optionalProperties
36
59
  ObjectExpression(node) {
60
+ // Skip if configured to allow both
61
+ if (allowBothRequiredAndOptional)
62
+ return;
37
63
  const hasRequired = (0, ast_helpers_js_1.findProperty)(node, 'required');
38
64
  const hasOptionalProperties = (0, ast_helpers_js_1.findProperty)(node, 'optionalProperties');
39
65
  const hasProperties = (0, ast_helpers_js_1.findProperty)(node, 'properties');
40
66
  // Only check if this looks like a schema definition
41
67
  if (!hasProperties)
42
68
  return;
43
- // Only warn if BOTH are present (redundant)
44
- if (hasRequired && hasOptionalProperties) {
69
+ // Only suggest if BOTH are present (redundant but valid)
70
+ // Make sure they're both arrays (not just properties with those names)
71
+ if (hasRequired &&
72
+ hasOptionalProperties &&
73
+ (0, ast_helpers_js_1.isArrayExpression)(hasRequired.value) &&
74
+ (0, ast_helpers_js_1.isArrayExpression)(hasOptionalProperties.value)) {
45
75
  context.report({
46
76
  node: hasOptionalProperties.key,
47
77
  messageId: 'redundantBothRequiredAndOptional',
@@ -1 +1 @@
1
- {"version":3,"file":"validate-schema-structure.js","sourceRoot":"","sources":["../../src/rules/validate-schema-structure.ts"],"names":[],"mappings":";;AACA,4DAAuD;AAEvD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+DAA+D;YACjE,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,uFAAuF;SAC7F;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,gCAAgC,EAC9B,4MAA4M;SAC/M;KACF;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,mEAAmE;YACnE,gBAAgB,CAAC,IAAI;gBACnB,MAAM,WAAW,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACnD,MAAM,qBAAqB,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;gBACvE,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,YAAY,CAAC,CAAC;gBAEvD,oDAAoD;gBACpD,IAAI,CAAC,aAAa;oBAAE,OAAO;gBAE3B,4CAA4C;gBAC5C,IAAI,WAAW,IAAI,qBAAqB,EAAE,CAAC;oBACzC,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,qBAAqB,CAAC,GAAG;wBAC/B,SAAS,EAAE,kCAAkC;qBAC9C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"validate-schema-structure.js","sourceRoot":"","sources":["../../src/rules/validate-schema-structure.ts"],"names":[],"mappings":";;AACA,4DAA0E;AAE1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+DAA+D;YACjE,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,uFAAuF;SAC7F;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,4BAA4B,EAAE;wBAC5B,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,IAAI;wBACb,WAAW,EAAE,iHAAiH;qBAC/H;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,gCAAgC,EAC9B,kIAAkI;SACrI;KACF;IAED,MAAM,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,kFAAkF;QAClF,MAAM,4BAA4B,GAAG,OAAO,CAAC,4BAA4B,KAAK,KAAK,CAAC;QAEpF,OAAO;YACL,mEAAmE;YACnE,gBAAgB,CAAC,IAAI;gBACnB,mCAAmC;gBACnC,IAAI,4BAA4B;oBAAE,OAAO;gBAEzC,MAAM,WAAW,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACnD,MAAM,qBAAqB,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;gBACvE,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,IAAI,EAAE,YAAY,CAAC,CAAC;gBAEvD,oDAAoD;gBACpD,IAAI,CAAC,aAAa;oBAAE,OAAO;gBAE3B,yDAAyD;gBACzD,uEAAuE;gBACvE,IACE,WAAW;oBACX,qBAAqB;oBACrB,IAAA,kCAAiB,EAAC,WAAW,CAAC,KAAK,CAAC;oBACpC,IAAA,kCAAiB,EAAC,qBAAqB,CAAC,KAAK,CAAC,EAC9C,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,qBAAqB,CAAC,GAAG;wBAC/B,SAAS,EAAE,kCAAkC;qBAC9C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
@@ -14,6 +14,10 @@ export declare function isTemplateLiteral(node: Node | null | undefined): node i
14
14
  * Get string value from a literal or template literal
15
15
  */
16
16
  export declare function getStringValue(node: Node | null | undefined): string | null;
17
+ /**
18
+ * Get number value from a literal node
19
+ */
20
+ export declare function getNumberValue(node: Node | null | undefined): number | null;
17
21
  /**
18
22
  * Check if a node is an identifier with a specific name
19
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ast-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/ast-helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/ast-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvK;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAElG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAExF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAY3E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAoB3E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,IAAI,UAAU,CAI7F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,cAAc,CAEtF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,aAAa,CAEpF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,gBAAgB,CAE1F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,gBAAgB,CAE1F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAExF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,QAAQ,CAE1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,MAAM,GACX,QAAQ,GAAG,SAAS,CAKtB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,MAAM,GACX,QAAQ,GAAG,SAAS,CAiBtB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAY5E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,GAAG,MAAM,GAAG,IAAI,CAYjF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,CAE7D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAkBT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAKhE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,gBAAgB,GACpB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAWvB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isStringLiteral = isStringLiteral;
4
4
  exports.isTemplateLiteral = isTemplateLiteral;
5
5
  exports.getStringValue = getStringValue;
6
+ exports.getNumberValue = getNumberValue;
6
7
  exports.isIdentifier = isIdentifier;
7
8
  exports.isCallExpression = isCallExpression;
8
9
  exports.isNewExpression = isNewExpression;
@@ -46,6 +47,26 @@ function getStringValue(node) {
46
47
  }
47
48
  return null;
48
49
  }
50
+ /**
51
+ * Get number value from a literal node
52
+ */
53
+ function getNumberValue(node) {
54
+ if (!node)
55
+ return null;
56
+ if (node.type === 'Literal' && typeof node.value === 'number') {
57
+ return node.value;
58
+ }
59
+ // Handle negative numbers (UnaryExpression with '-' operator)
60
+ if (node.type === 'UnaryExpression' &&
61
+ node.operator === '-' &&
62
+ node.argument.type === 'Literal') {
63
+ const literal = node.argument;
64
+ if (typeof literal.value === 'number') {
65
+ return -literal.value;
66
+ }
67
+ }
68
+ return null;
69
+ }
49
70
  /**
50
71
  * Check if a node is an identifier with a specific name
51
72
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ast-helpers.js","sourceRoot":"","sources":["../../src/utils/ast-helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast-helpers.js","sourceRoot":"","sources":["../../src/utils/ast-helpers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-firebase-ai-logic",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "ESLint plugin for Firebase AI Logic best practices, detecting deprecated imports, models, and common anti-patterns",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",