eslint-plugin-firebase-ai-logic 1.2.0 → 1.3.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
@@ -239,7 +239,7 @@ const configs = {
239
239
  const plugin = {
240
240
  meta: {
241
241
  name: 'eslint-plugin-firebase-ai-logic',
242
- version: '1.2.0',
242
+ version: '1.3.0',
243
243
  },
244
244
  rules,
245
245
  configs,
@@ -1,4 +1,22 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * check-temperature-defaults
4
+ *
5
+ * This rule suggests using the default temperature (1.0) for Gemini models,
6
+ * but with important exceptions:
7
+ *
8
+ * EXCEPTIONS (low temperature is valid and recommended):
9
+ * 1. Structured output (responseMimeType: 'application/json')
10
+ * - Low temperature (0.1-0.3) prevents hallucinations in extraction tasks
11
+ * 2. Classification tasks
12
+ * - Deterministic outputs benefit from low temperature
13
+ * 3. Data extraction
14
+ * - Precise extraction needs low temperature
15
+ *
16
+ * The rule only warns when:
17
+ * - Temperature is NOT 1.0
18
+ * - AND responseMimeType is NOT 'application/json' (structured output)
19
+ */
2
20
  declare const rule: Rule.RuleModule;
3
21
  export default rule;
4
22
  //# sourceMappingURL=check-temperature-defaults.d.ts.map
@@ -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;AAOnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6DhB,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;AAQnC;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAgFhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,17 +1,35 @@
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
+ * check-temperature-defaults
6
+ *
7
+ * This rule suggests using the default temperature (1.0) for Gemini models,
8
+ * but with important exceptions:
9
+ *
10
+ * EXCEPTIONS (low temperature is valid and recommended):
11
+ * 1. Structured output (responseMimeType: 'application/json')
12
+ * - Low temperature (0.1-0.3) prevents hallucinations in extraction tasks
13
+ * 2. Classification tasks
14
+ * - Deterministic outputs benefit from low temperature
15
+ * 3. Data extraction
16
+ * - Precise extraction needs low temperature
17
+ *
18
+ * The rule only warns when:
19
+ * - Temperature is NOT 1.0
20
+ * - AND responseMimeType is NOT 'application/json' (structured output)
21
+ */
4
22
  const rule = {
5
23
  meta: {
6
- type: 'problem',
24
+ type: 'suggestion',
7
25
  docs: {
8
- description: 'Enforce default temperature (1.0) for Gemini 3 models to prevent unexpected behavior',
26
+ description: 'Suggest default temperature (1.0) for Gemini models, except for structured output tasks',
9
27
  recommended: true,
10
28
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#check-temperature-defaults',
11
29
  },
12
30
  schema: [],
13
31
  messages: {
14
- nonDefaultTemperature: 'Gemini 3 models are optimized for the default temperature (1.0). Changing this value may lead to unexpected behavior, looping, or degraded reasoning performance.',
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.',
15
33
  },
16
34
  },
17
35
  create(context) {
@@ -34,13 +52,30 @@ const rule = {
34
52
  : configArg;
35
53
  if (!(0, ast_helpers_js_1.isObjectExpression)(configToCheck))
36
54
  return;
55
+ // Check for responseMimeType - if it's 'application/json', low temperature is valid
56
+ const responseMimeTypeProp = (0, ast_helpers_js_1.findProperty)(configToCheck, 'responseMimeType');
57
+ if (responseMimeTypeProp) {
58
+ const mimeType = (0, ast_helpers_js_1.getStringValue)(responseMimeTypeProp.value);
59
+ if (mimeType === 'application/json') {
60
+ // Structured output - low temperature is appropriate, don't warn
61
+ return;
62
+ }
63
+ }
64
+ // Check for responseSchema - if present, it's structured output
65
+ const responseSchemaProp = (0, ast_helpers_js_1.findProperty)(configToCheck, 'responseSchema');
66
+ if (responseSchemaProp) {
67
+ // Has response schema - structured output, don't warn
68
+ return;
69
+ }
37
70
  // Check for temperature property
38
71
  const temperatureProp = (0, ast_helpers_js_1.findProperty)(configToCheck, 'temperature');
39
72
  if (temperatureProp) {
40
- // If value is literal and not 1.0, report
73
+ // If value is literal and not 1.0, suggest (not require) using default
41
74
  if (temperatureProp.value.type === 'Literal' &&
42
75
  typeof temperatureProp.value.value === 'number') {
43
- if (temperatureProp.value.value !== 1.0) {
76
+ const temp = temperatureProp.value.value;
77
+ // Only warn for non-default temperature when NOT doing structured output
78
+ if (temp !== 1.0) {
44
79
  context.report({
45
80
  node: temperatureProp,
46
81
  messageId: 'nonDefaultTemperature',
@@ -1 +1 @@
1
- {"version":3,"file":"check-temperature-defaults.js","sourceRoot":"","sources":["../../src/rules/check-temperature-defaults.ts"],"names":[],"mappings":";;AACA,4DAIiC;AAEjC,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,sFAAsF;YACxF,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,wFAAwF;SAC9F;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,qBAAqB,EACnB,mKAAmK;SACtK;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,iCAAiC;gBACjC,MAAM,eAAe,GAAG,IAAA,6BAAY,EAAC,aAAa,EAAE,aAAa,CAAC,CAAC;gBAEnE,IAAI,eAAe,EAAE,CAAC;oBACpB,0CAA0C;oBAC1C,IACE,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;wBACxC,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAC/C,CAAC;wBACD,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;4BACxC,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":";;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,4 +1,21 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * require-app-check-production
4
+ *
5
+ * This rule suggests using App Check to protect AI endpoints from abuse.
6
+ *
7
+ * IMPORTANT LIMITATIONS:
8
+ * - This rule only checks within the SAME FILE
9
+ * - Many projects use lazy loading where App Check is initialized in a separate file
10
+ * - Projects using hooks like useAppCheck() or ensureAppCheckReady() are valid
11
+ *
12
+ * The rule checks for:
13
+ * 1. Direct import of 'firebase/app-check'
14
+ * 2. Calls to initializeAppCheck()
15
+ * 3. Common patterns: useAppCheck, ensureAppCheckReady, AppCheckProvider
16
+ *
17
+ * If none are found in the same file as getAI(), it suggests (not requires) App Check.
18
+ */
2
19
  declare const rule: Rule.RuleModule;
3
20
  export default rule;
4
21
  //# sourceMappingURL=require-app-check-production.d.ts.map
@@ -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,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAmEhB,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;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAsGhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,6 +1,23 @@
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
+ * require-app-check-production
6
+ *
7
+ * This rule suggests using App Check to protect AI endpoints from abuse.
8
+ *
9
+ * IMPORTANT LIMITATIONS:
10
+ * - This rule only checks within the SAME FILE
11
+ * - Many projects use lazy loading where App Check is initialized in a separate file
12
+ * - Projects using hooks like useAppCheck() or ensureAppCheckReady() are valid
13
+ *
14
+ * The rule checks for:
15
+ * 1. Direct import of 'firebase/app-check'
16
+ * 2. Calls to initializeAppCheck()
17
+ * 3. Common patterns: useAppCheck, ensureAppCheckReady, AppCheckProvider
18
+ *
19
+ * If none are found in the same file as getAI(), it suggests (not requires) App Check.
20
+ */
4
21
  const rule = {
5
22
  meta: {
6
23
  type: 'suggestion',
@@ -11,31 +28,62 @@ const rule = {
11
28
  },
12
29
  schema: [],
13
30
  messages: {
14
- missingAppCheck: 'Consider using App Check with reCAPTCHA to protect your AI endpoints from abuse. Initialize with initializeAppCheck() before using AI features.',
15
- appCheckSuggestion: "import { initializeAppCheck, ReCaptchaV3Provider } from 'firebase/app-check'; initializeAppCheck(app, { provider: new ReCaptchaV3Provider('SITE_KEY') });",
31
+ 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
+ appCheckSuggestion: "import { initializeAppCheck, ReCaptchaEnterpriseProvider } from 'firebase/app-check'; initializeAppCheck(app, { provider: new ReCaptchaEnterpriseProvider('SITE_KEY') });",
16
33
  },
17
34
  },
18
35
  create(context) {
19
36
  let hasAppCheckImport = false;
20
37
  let hasAppCheckInit = false;
38
+ let hasAppCheckHelper = false;
21
39
  let hasAIInit = false;
22
40
  let aiInitNode = null;
41
+ // Common App Check helper patterns used in lazy loading
42
+ const appCheckHelperPatterns = [
43
+ 'useAppCheck',
44
+ 'ensureAppCheckReady',
45
+ 'AppCheckProvider',
46
+ 'getAppCheckInstance',
47
+ 'isAppCheckReady',
48
+ 'initializeAppCheckLazy',
49
+ ];
23
50
  return {
24
51
  // Track App Check imports
25
52
  ImportDeclaration(node) {
26
- if (node.source.value === 'firebase/app-check' &&
27
- node.specifiers.some((spec) => spec.type === 'ImportSpecifier' &&
28
- spec.imported.type === 'Identifier' &&
29
- spec.imported.name === 'initializeAppCheck')) {
53
+ const source = node.source.value;
54
+ // Direct firebase/app-check import
55
+ if (source === 'firebase/app-check') {
30
56
  hasAppCheckImport = true;
31
57
  }
58
+ // 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'))) {
63
+ hasAppCheckHelper = true;
64
+ }
65
+ // Check imported specifiers for App Check helpers
66
+ for (const spec of node.specifiers) {
67
+ if (spec.type === 'ImportSpecifier' && spec.imported.type === 'Identifier') {
68
+ if (appCheckHelperPatterns.includes(spec.imported.name)) {
69
+ hasAppCheckHelper = true;
70
+ }
71
+ }
72
+ }
32
73
  },
33
- // Track initializeAppCheck calls
74
+ // Track function calls
34
75
  CallExpression(node) {
35
76
  const calleeName = (0, ast_helpers_js_1.getCalleeName)(node);
77
+ if (!calleeName)
78
+ return;
79
+ // Direct initializeAppCheck call
36
80
  if (calleeName === 'initializeAppCheck') {
37
81
  hasAppCheckInit = true;
38
82
  }
83
+ // App Check helper calls
84
+ if (appCheckHelperPatterns.includes(calleeName)) {
85
+ hasAppCheckHelper = true;
86
+ }
39
87
  // Track getAI calls
40
88
  if (calleeName === 'getAI') {
41
89
  hasAIInit = true;
@@ -44,8 +92,9 @@ const rule = {
44
92
  },
45
93
  // Check at the end of the program
46
94
  'Program:exit'() {
47
- // Only warn if AI is being used but App Check is not configured
48
- if (hasAIInit && !hasAppCheckImport && !hasAppCheckInit && aiInitNode) {
95
+ // Only suggest if AI is being used but no App Check patterns found
96
+ const hasAnyAppCheckPattern = hasAppCheckImport || hasAppCheckInit || hasAppCheckHelper;
97
+ if (hasAIInit && !hasAnyAppCheckPattern && aiInitNode) {
49
98
  context.report({
50
99
  node: aiInitNode,
51
100
  messageId: 'missingAppCheck',
@@ -1 +1 @@
1
- {"version":3,"file":"require-app-check-production.js","sourceRoot":"","sources":["../../src/rules/require-app-check-production.ts"],"names":[],"mappings":";;AACA,4DAAwD;AAExD,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,iFAAiF;YACnF,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,0FAA0F;SAChG;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,eAAe,EACb,iJAAiJ;YACnJ,kBAAkB,EAChB,2JAA2J;SAC9J;KACF;IAED,MAAM,CAAC,OAAO;QACZ,IAAI,iBAAiB,GAAG,KAAK,CAAC;QAC9B,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,UAAU,GAAqB,IAAI,CAAC;QAExC,OAAO;YACL,0BAA0B;YAC1B,iBAAiB,CAAC,IAAI;gBACpB,IACE,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB;oBAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAClB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,iBAAiB;wBAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;wBACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,oBAAoB,CAC9C,EACD,CAAC;oBACD,iBAAiB,GAAG,IAAI,CAAC;gBAC3B,CAAC;YACH,CAAC;YAED,iCAAiC;YACjC,cAAc,CAAC,IAAI;gBACjB,MAAM,UAAU,GAAG,IAAA,8BAAa,EAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,UAAU,KAAK,oBAAoB,EAAE,CAAC;oBACxC,eAAe,GAAG,IAAI,CAAC;gBACzB,CAAC;gBAED,oBAAoB;gBACpB,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;oBAC3B,SAAS,GAAG,IAAI,CAAC;oBACjB,UAAU,GAAG,IAAiB,CAAC;gBACjC,CAAC;YACH,CAAC;YAED,kCAAkC;YAClC,cAAc;gBACZ,gEAAgE;gBAChE,IAAI,SAAS,IAAI,CAAC,iBAAiB,IAAI,CAAC,eAAe,IAAI,UAAU,EAAE,CAAC;oBACtE,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,UAAU;wBAChB,SAAS,EAAE,iBAAiB;qBAC7B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
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,4 +1,21 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * require-backend
4
+ *
5
+ * IMPORTANT: getAI(app) without a second argument is VALID.
6
+ * Firebase AI Logic uses GoogleAIBackend by default when no backend is specified.
7
+ *
8
+ * This rule only reports when:
9
+ * - A second argument (config object) exists BUT doesn't have 'backend' property
10
+ *
11
+ * Valid usage:
12
+ * - getAI(app) - Uses GoogleAIBackend by default ✅
13
+ * - getAI(app, { backend: new GoogleAIBackend() }) ✅
14
+ * - getAI(app, { backend: new VertexAIBackend() }) ✅
15
+ *
16
+ * Invalid usage:
17
+ * - getAI(app, { someOtherConfig: true }) - Has config but no backend ❌
18
+ */
2
19
  declare const rule: Rule.RuleModule;
3
20
  export default rule;
4
21
  //# sourceMappingURL=require-backend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"require-backend.d.ts","sourceRoot":"","sources":["../../src/rules/require-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAOnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA2GhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"require-backend.d.ts","sourceRoot":"","sources":["../../src/rules/require-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAOnC;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAyEhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,21 +1,37 @@
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
+ * require-backend
6
+ *
7
+ * IMPORTANT: getAI(app) without a second argument is VALID.
8
+ * Firebase AI Logic uses GoogleAIBackend by default when no backend is specified.
9
+ *
10
+ * This rule only reports when:
11
+ * - A second argument (config object) exists BUT doesn't have 'backend' property
12
+ *
13
+ * Valid usage:
14
+ * - getAI(app) - Uses GoogleAIBackend by default ✅
15
+ * - getAI(app, { backend: new GoogleAIBackend() }) ✅
16
+ * - getAI(app, { backend: new VertexAIBackend() }) ✅
17
+ *
18
+ * Invalid usage:
19
+ * - getAI(app, { someOtherConfig: true }) - Has config but no backend ❌
20
+ */
4
21
  const rule = {
5
22
  meta: {
6
- type: 'problem',
23
+ type: 'suggestion',
7
24
  docs: {
8
- description: "Require 'backend' option when calling getAI() - GoogleAIBackend or VertexAIBackend is mandatory",
25
+ description: "Suggest specifying 'backend' option when calling getAI() with a config object",
9
26
  recommended: true,
10
27
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#require-backend',
11
28
  },
12
29
  hasSuggestions: true,
13
30
  schema: [],
14
31
  messages: {
15
- missingBackend: "The 'backend' option is required when calling getAI(). Use { backend: new GoogleAIBackend() } or { backend: new VertexAIBackend() }.",
16
- missingBackendInConfig: "Missing 'backend' property in getAI() config. Firebase AI Logic requires explicitly specifying GoogleAIBackend or VertexAIBackend.",
17
- addGoogleAIBackend: "Add '{ backend: new GoogleAIBackend() }' as second argument",
18
- addVertexAIBackend: "Add '{ backend: new VertexAIBackend() }' as second argument",
32
+ missingBackendInConfig: "Config object provided to getAI() is missing 'backend' property. Consider adding { backend: new GoogleAIBackend() } or { backend: new VertexAIBackend() } for explicit backend selection.",
33
+ addGoogleAIBackend: "Add 'backend: new GoogleAIBackend()' to config",
34
+ addVertexAIBackend: "Add 'backend: new VertexAIBackend()' to config",
19
35
  },
20
36
  },
21
37
  create(context) {
@@ -25,43 +41,17 @@ const rule = {
25
41
  if (calleeName !== 'getAI')
26
42
  return;
27
43
  const args = node.arguments;
28
- // Case 1: No second argument at all
44
+ // getAI(app) without second argument is VALID - uses GoogleAIBackend by default
45
+ // Only check if there IS a second argument
29
46
  if (args.length < 2) {
30
- context.report({
31
- node,
32
- messageId: 'missingBackend',
33
- suggest: [
34
- {
35
- messageId: 'addGoogleAIBackend',
36
- fix(fixer) {
37
- const firstArg = args[0];
38
- if (!firstArg)
39
- return null;
40
- const sourceCode = context.sourceCode;
41
- const firstArgText = sourceCode.getText(firstArg);
42
- return fixer.replaceText(node, `getAI(${firstArgText}, { backend: new GoogleAIBackend() })`);
43
- },
44
- },
45
- {
46
- messageId: 'addVertexAIBackend',
47
- fix(fixer) {
48
- const firstArg = args[0];
49
- if (!firstArg)
50
- return null;
51
- const sourceCode = context.sourceCode;
52
- const firstArgText = sourceCode.getText(firstArg);
53
- return fixer.replaceText(node, `getAI(${firstArgText}, { backend: new VertexAIBackend() })`);
54
- },
55
- },
56
- ],
57
- });
58
- return;
47
+ return; // This is fine - default backend will be used
59
48
  }
60
- // Case 2: Second argument exists but might not have backend
49
+ // Case: Second argument exists but might not have backend
61
50
  const configArg = args[1];
62
51
  if ((0, ast_helpers_js_1.isObjectExpression)(configArg)) {
63
52
  const backendProp = (0, ast_helpers_js_1.findProperty)(configArg, 'backend');
64
- if (!backendProp) {
53
+ // Only report if config object exists but doesn't have backend
54
+ if (!backendProp && configArg.properties.length > 0) {
65
55
  context.report({
66
56
  node: configArg,
67
57
  messageId: 'missingBackendInConfig',
@@ -69,14 +59,17 @@ const rule = {
69
59
  {
70
60
  messageId: 'addGoogleAIBackend',
71
61
  fix(fixer) {
72
- // Insert backend property at the beginning of the object
73
- if (configArg.properties.length === 0) {
74
- return fixer.replaceText(configArg, '{ backend: new GoogleAIBackend() }');
75
- }
76
62
  const firstProp = configArg.properties[0];
77
63
  return fixer.insertTextBefore(firstProp, 'backend: new GoogleAIBackend(), ');
78
64
  },
79
65
  },
66
+ {
67
+ messageId: 'addVertexAIBackend',
68
+ fix(fixer) {
69
+ const firstProp = configArg.properties[0];
70
+ return fixer.insertTextBefore(firstProp, 'backend: new VertexAIBackend(), ');
71
+ },
72
+ },
80
73
  ],
81
74
  });
82
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"require-backend.js","sourceRoot":"","sources":["../../src/rules/require-backend.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"require-backend.js","sourceRoot":"","sources":["../../src/rules/require-backend.ts"],"names":[],"mappings":";;AACA,4DAIiC;AAEjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+EAA+E;YACjF,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,6EAA6E;SACnF;QACD,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,sBAAsB,EACpB,2LAA2L;YAC7L,kBAAkB,EAAE,gDAAgD;YACpE,kBAAkB,EAAE,gDAAgD;SACrE;KACF;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,MAAM,UAAU,GAAG,IAAA,8BAAa,EAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,UAAU,KAAK,OAAO;oBAAE,OAAO;gBAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAE5B,gFAAgF;gBAChF,2CAA2C;gBAC3C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,8CAA8C;gBACxD,CAAC;gBAED,0DAA0D;gBAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAE1B,IAAI,IAAA,mCAAkB,EAAC,SAAS,CAAC,EAAE,CAAC;oBAClC,MAAM,WAAW,GAAG,IAAA,6BAAY,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBAEvD,+DAA+D;oBAC/D,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACpD,OAAO,CAAC,MAAM,CAAC;4BACb,IAAI,EAAE,SAAS;4BACf,SAAS,EAAE,wBAAwB;4BACnC,OAAO,EAAE;gCACP;oCACE,SAAS,EAAE,oBAAoB;oCAC/B,GAAG,CAAC,KAAK;wCACP,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;wCAC1C,OAAO,KAAK,CAAC,gBAAgB,CAC3B,SAAS,EACT,kCAAkC,CACnC,CAAC;oCACJ,CAAC;iCACF;gCACD;oCACE,SAAS,EAAE,oBAAoB;oCAC/B,GAAG,CAAC,KAAK;wCACP,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;wCAC1C,OAAO,KAAK,CAAC,gBAAgB,CAC3B,SAAS,EACT,kCAAkC,CACnC,CAAC;oCACJ,CAAC;iCACF;6BACF;yBACF,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
@@ -1,4 +1,25 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * require-error-handling
4
+ *
5
+ * This rule suggests adding error handling for Firebase AI Logic API calls.
6
+ *
7
+ * RECOGNIZED ERROR HANDLING PATTERNS:
8
+ * 1. Direct try/catch blocks
9
+ * 2. .catch() chains
10
+ * 3. .then(onFulfilled, onRejected) with error handler
11
+ * 4. Wrapper functions with built-in error handling:
12
+ * - retryWithBackoff
13
+ * - withRetry
14
+ * - safeCall
15
+ * - handleApiCall
16
+ * - executeWithRetry
17
+ *
18
+ * The rule checks if the API call is:
19
+ * - Inside a try/catch block
20
+ * - Chained with .catch()
21
+ * - Wrapped in a known error-handling function
22
+ */
2
23
  declare const rule: Rule.RuleModule;
3
24
  export default rule;
4
25
  //# sourceMappingURL=require-error-handling.d.ts.map
@@ -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,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAiHhB,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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAgKhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,11 +1,32 @@
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
+ * require-error-handling
6
+ *
7
+ * This rule suggests adding error handling for Firebase AI Logic API calls.
8
+ *
9
+ * RECOGNIZED ERROR HANDLING PATTERNS:
10
+ * 1. Direct try/catch blocks
11
+ * 2. .catch() chains
12
+ * 3. .then(onFulfilled, onRejected) with error handler
13
+ * 4. Wrapper functions with built-in error handling:
14
+ * - retryWithBackoff
15
+ * - withRetry
16
+ * - safeCall
17
+ * - handleApiCall
18
+ * - executeWithRetry
19
+ *
20
+ * The rule checks if the API call is:
21
+ * - Inside a try/catch block
22
+ * - Chained with .catch()
23
+ * - Wrapped in a known error-handling function
24
+ */
4
25
  const rule = {
5
26
  meta: {
6
27
  type: 'suggestion',
7
28
  docs: {
8
- description: 'Require error handling for Firebase AI Logic API calls, especially for rate limit (429) errors',
29
+ description: 'Suggest error handling for Firebase AI Logic API calls, especially for rate limit (429) errors',
9
30
  recommended: true,
10
31
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#require-error-handling',
11
32
  },
@@ -26,6 +47,18 @@ const rule = {
26
47
  'countTokens',
27
48
  'embedContent',
28
49
  ];
50
+ // Common wrapper functions that provide error handling
51
+ const errorHandlingWrappers = [
52
+ 'retryWithBackoff',
53
+ 'withRetry',
54
+ 'safeCall',
55
+ 'handleApiCall',
56
+ 'executeWithRetry',
57
+ 'withErrorHandling',
58
+ 'tryCatch',
59
+ 'safeFetch',
60
+ 'retryOperation',
61
+ ];
29
62
  function isInsideTryCatch(node) {
30
63
  let current = node.parent;
31
64
  while (current) {
@@ -66,6 +99,32 @@ const rule = {
66
99
  }
67
100
  return false;
68
101
  }
102
+ function isInsideErrorHandlingWrapper(node) {
103
+ let current = node.parent;
104
+ while (current) {
105
+ // Check if we're inside a call to a known error handling wrapper
106
+ if (current.type === 'CallExpression') {
107
+ const wrapperName = (0, ast_helpers_js_1.getCalleeName)(current);
108
+ if (wrapperName && errorHandlingWrappers.includes(wrapperName)) {
109
+ return true;
110
+ }
111
+ }
112
+ // Check if we're inside an arrow function or function expression
113
+ // that is passed to a known error handling wrapper
114
+ if (current.type === 'ArrowFunctionExpression' ||
115
+ current.type === 'FunctionExpression') {
116
+ const parent = current.parent;
117
+ if (parent?.type === 'CallExpression') {
118
+ const wrapperName = (0, ast_helpers_js_1.getCalleeName)(parent);
119
+ if (wrapperName && errorHandlingWrappers.includes(wrapperName)) {
120
+ return true;
121
+ }
122
+ }
123
+ }
124
+ current = current.parent || null;
125
+ }
126
+ return false;
127
+ }
69
128
  return {
70
129
  CallExpression(node) {
71
130
  const calleeName = (0, ast_helpers_js_1.getCalleeName)(node);
@@ -74,9 +133,10 @@ const rule = {
74
133
  }
75
134
  // Check if this is an awaited call
76
135
  const isAwaited = node.parent?.type === 'AwaitExpression';
77
- // Check if inside try/catch or has .catch()
136
+ // Check if inside try/catch, has .catch(), or inside error handling wrapper
78
137
  const hasErrorHandling = isInsideTryCatch(node) ||
79
- isInsideAsyncErrorBoundary(node);
138
+ isInsideAsyncErrorBoundary(node) ||
139
+ isInsideErrorHandlingWrapper(node);
80
140
  if (!hasErrorHandling) {
81
141
  context.report({
82
142
  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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"}
@@ -1,4 +1,20 @@
1
1
  import type { Rule } from 'eslint';
2
+ /**
3
+ * validate-schema-structure
4
+ *
5
+ * IMPORTANT: The "required" property IS VALID in Firebase AI Logic!
6
+ *
7
+ * Firebase AI Logic Schema.object() accepts:
8
+ * - properties: Define the object properties
9
+ * - required: Array of required property names (VALID!)
10
+ * - optionalProperties: Array of optional property names (alternative approach)
11
+ *
12
+ * This rule should NOT report errors for using "required" in Schema.object()
13
+ * because it's a valid and common pattern for function calling parameters.
14
+ *
15
+ * The rule now only warns about using BOTH "required" AND "optionalProperties"
16
+ * in the same schema, which is redundant.
17
+ */
2
18
  declare const rule: Rule.RuleModule;
3
19
  export default rule;
4
20
  //# sourceMappingURL=validate-schema-structure.d.ts.map
@@ -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;AAMnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAyChB,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;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAqChB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,38 +1,51 @@
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
+ * validate-schema-structure
6
+ *
7
+ * IMPORTANT: The "required" property IS VALID in Firebase AI Logic!
8
+ *
9
+ * Firebase AI Logic Schema.object() accepts:
10
+ * - properties: Define the object properties
11
+ * - required: Array of required property names (VALID!)
12
+ * - optionalProperties: Array of optional property names (alternative approach)
13
+ *
14
+ * This rule should NOT report errors for using "required" in Schema.object()
15
+ * because it's a valid and common pattern for function calling parameters.
16
+ *
17
+ * The rule now only warns about using BOTH "required" AND "optionalProperties"
18
+ * in the same schema, which is redundant.
19
+ */
4
20
  const rule = {
5
21
  meta: {
6
- type: 'problem',
22
+ type: 'suggestion',
7
23
  docs: {
8
- description: 'Warn about using standard JSON Schema features like "required" that are handled differently in Firebase AI Logic',
24
+ description: 'Suggest best practices for Firebase AI Logic schema structure',
9
25
  recommended: true,
10
26
  url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#validate-schema-structure',
11
27
  },
12
28
  schema: [],
13
29
  messages: {
14
- redundantRequired: 'In Firebase AI Logic, all properties are required by default. Use "optionalProperties" array to mark fields as optional instead of using "required".',
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.',
15
31
  },
16
32
  },
17
33
  create(context) {
18
34
  return {
19
- Property(node) {
20
- // Check for "required" property in Schema definitions
21
- if (node.key.type === 'Identifier' && node.key.name === 'required') {
22
- // Check if we are likely inside a schema definition
23
- // Heuristic: Check if parent object also has "properties" or "type"
24
- // Or if we are inside Schema.object({...})
25
- const parent = node.parent;
26
- if ((0, ast_helpers_js_1.isObjectExpression)(parent)) {
27
- const hasProperties = (0, ast_helpers_js_1.findProperty)(parent, 'properties');
28
- const hasType = (0, ast_helpers_js_1.findProperty)(parent, 'type');
29
- if (hasProperties || hasType) {
30
- context.report({
31
- node: node.key,
32
- messageId: 'redundantRequired',
33
- });
34
- }
35
- }
35
+ // Check for objects that have BOTH required AND optionalProperties
36
+ ObjectExpression(node) {
37
+ const hasRequired = (0, ast_helpers_js_1.findProperty)(node, 'required');
38
+ const hasOptionalProperties = (0, ast_helpers_js_1.findProperty)(node, 'optionalProperties');
39
+ const hasProperties = (0, ast_helpers_js_1.findProperty)(node, 'properties');
40
+ // Only check if this looks like a schema definition
41
+ if (!hasProperties)
42
+ return;
43
+ // Only warn if BOTH are present (redundant)
44
+ if (hasRequired && hasOptionalProperties) {
45
+ context.report({
46
+ node: hasOptionalProperties.key,
47
+ messageId: 'redundantBothRequiredAndOptional',
48
+ });
36
49
  }
37
50
  },
38
51
  };
@@ -1 +1 @@
1
- {"version":3,"file":"validate-schema-structure.js","sourceRoot":"","sources":["../../src/rules/validate-schema-structure.ts"],"names":[],"mappings":";;AACA,4DAGiC;AAEjC,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,kHAAkH;YACpH,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,uFAAuF;SAC7F;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,iBAAiB,EACf,sJAAsJ;SACzJ;KACF;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,QAAQ,CAAC,IAAI;gBACV,sDAAsD;gBACtD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAClE,oDAAoD;oBACpD,oEAAoE;oBACpE,4CAA4C;oBAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC3B,IAAI,IAAA,mCAAkB,EAAC,MAAM,CAAC,EAAE,CAAC;wBAC9B,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,MAAM,EAAE,YAAY,CAAC,CAAC;wBACzD,MAAM,OAAO,GAAG,IAAA,6BAAY,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;wBAE7C,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;4BAC5B,OAAO,CAAC,MAAM,CAAC;gCACZ,IAAI,EAAE,IAAI,CAAC,GAAG;gCACd,SAAS,EAAE,mBAAmB;6BAChC,CAAC,CAAC;wBACN,CAAC;oBACJ,CAAC;gBACJ,CAAC;YACJ,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,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"}
@@ -21,11 +21,11 @@ export declare const WRONG_IMPORTS: {
21
21
  };
22
22
  };
23
23
  /** Models that have been retired and return 404 errors */
24
- export declare const DEPRECATED_MODELS: readonly ["gemini-pro", "gemini-1.0-pro", "gemini-1.0-pro-vision", "gemini-1.5-pro", "gemini-1.5-pro-latest", "gemini-1.5-pro-001", "gemini-1.5-pro-002", "gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-1.5-flash-001", "gemini-1.5-flash-002", "gemini-1.5-flash-8b", "gemini-2.0-flash", "gemini-2.0-flash-exp", "gemini-2.0-flash-lite", "gemini-2.5-pro", "gemini-2.5-pro-preview", "gemini-2.5-flash", "gemini-2.5-flash-preview", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview"];
24
+ export declare const DEPRECATED_MODELS: readonly ["gemini-pro", "gemini-1.0-pro", "gemini-1.0-pro-vision", "gemini-1.5-pro", "gemini-1.5-pro-latest", "gemini-1.5-pro-001", "gemini-1.5-pro-002", "gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-1.5-flash-001", "gemini-1.5-flash-002", "gemini-1.5-flash-8b", "gemini-2.0-flash", "gemini-2.0-flash-exp", "gemini-2.0-flash-lite"];
25
25
  /** Current recommended model for Firebase AI Logic */
26
26
  export declare const RECOMMENDED_MODEL = "gemini-3-flash-preview";
27
27
  /** All current valid models */
28
- export declare const VALID_MODELS: readonly ["gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-3-pro-image-preview"];
28
+ export declare const VALID_MODELS: readonly ["gemini-2.5-pro", "gemini-2.5-pro-preview", "gemini-2.5-flash", "gemini-2.5-flash-preview", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-3-pro-image-preview"];
29
29
  /** Schema features not supported by Firebase AI Logic */
30
30
  export declare const UNSUPPORTED_SCHEMA_FEATURES: readonly ["minLength", "maxLength", "pattern", "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "oneOf", "anyOf", "allOf", "not", "$ref", "if", "then", "else", "default", "const", "minItems", "uniqueItems", "minProperties", "maxProperties", "additionalProperties", "patternProperties"];
31
31
  /** Required fields for function declarations */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,+DAA+D;AAC/D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;CAqBhB,CAAC;AAMX,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,4eAsBpB,CAAC;AAEX,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,+BAA+B;AAC/B,eAAO,MAAM,YAAY,2FAIf,CAAC;AAMX,yDAAyD;AACzD,eAAO,MAAM,2BAA2B,4SAwB9B,CAAC;AAMX,gDAAgD;AAChD,eAAO,MAAM,wBAAwB,kCAAmC,CAAC;AAEzE,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,+FAS9B,CAAC;AAMX,sCAAsC;AACtC,eAAO,MAAM,0BAA0B,6FAO7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,0BAA0B,qIAU7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,0BAA0B,yGAQ7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,wBAAwB,wUAK3B,CAAC;AAMX,yCAAyC;AACzC,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX,iDAAiD;AACjD,eAAO,MAAM,uBAAuB,sHAK1B,CAAC;AAMX,uBAAuB;AACvB,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,+CAA+C;AAC/C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,+DAA+D;AAC/D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;CAqBhB,CAAC;AAMX,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,sVAqBpB,CAAC;AAEX,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,+BAA+B;AAC/B,eAAO,MAAM,YAAY,iPAYf,CAAC;AAMX,yDAAyD;AACzD,eAAO,MAAM,2BAA2B,4SAwB9B,CAAC;AAMX,gDAAgD;AAChD,eAAO,MAAM,wBAAwB,kCAAmC,CAAC;AAEzE,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,+FAS9B,CAAC;AAMX,sCAAsC;AACtC,eAAO,MAAM,0BAA0B,6FAO7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,0BAA0B,qIAU7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,0BAA0B,yGAQ7B,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,wBAAwB,wUAK3B,CAAC;AAMX,yCAAyC;AACzC,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX,iDAAiD;AACjD,eAAO,MAAM,uBAAuB,sHAK1B,CAAC;AAMX,uBAAuB;AACvB,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,+CAA+C;AAC/C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,eAAe,KAAK,CAAC"}
@@ -31,9 +31,11 @@ exports.WRONG_IMPORTS = {
31
31
  // ============================================================================
32
32
  /** Models that have been retired and return 404 errors */
33
33
  exports.DEPRECATED_MODELS = [
34
+ // Gemini 1.0 - Fully deprecated
34
35
  'gemini-pro',
35
36
  'gemini-1.0-pro',
36
37
  'gemini-1.0-pro-vision',
38
+ // Gemini 1.5 - Fully deprecated
37
39
  'gemini-1.5-pro',
38
40
  'gemini-1.5-pro-latest',
39
41
  'gemini-1.5-pro-001',
@@ -43,20 +45,25 @@ exports.DEPRECATED_MODELS = [
43
45
  'gemini-1.5-flash-001',
44
46
  'gemini-1.5-flash-002',
45
47
  'gemini-1.5-flash-8b',
48
+ // Gemini 2.0 - Fully deprecated
46
49
  'gemini-2.0-flash',
47
50
  'gemini-2.0-flash-exp',
48
51
  'gemini-2.0-flash-lite',
52
+ // Note: Gemini 2.5 models are NOT deprecated - they are current stable models
53
+ // gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite are valid
54
+ ];
55
+ /** Current recommended model for Firebase AI Logic */
56
+ exports.RECOMMENDED_MODEL = 'gemini-3-flash-preview';
57
+ /** All current valid models */
58
+ exports.VALID_MODELS = [
59
+ // Gemini 2.5 - Current stable models
49
60
  'gemini-2.5-pro',
50
61
  'gemini-2.5-pro-preview',
51
62
  'gemini-2.5-flash',
52
63
  'gemini-2.5-flash-preview',
53
64
  'gemini-2.5-flash-lite',
54
65
  'gemini-2.5-flash-lite-preview',
55
- ];
56
- /** Current recommended model for Firebase AI Logic */
57
- exports.RECOMMENDED_MODEL = 'gemini-3-flash-preview';
58
- /** All current valid models */
59
- exports.VALID_MODELS = [
66
+ // Gemini 3 - Preview models
60
67
  'gemini-3-pro-preview',
61
68
  'gemini-3-flash-preview',
62
69
  'gemini-3-pro-image-preview',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,+DAA+D;AAClD,QAAA,aAAa,GAAG;IAC3B,uBAAuB,EAAE;QACvB,OAAO,EACL,oGAAoG;QACtG,WAAW,EAAE,aAAa;KAC3B;IACD,wBAAwB,EAAE;QACxB,OAAO,EACL,uHAAuH;QACzH,WAAW,EAAE,aAAa;KAC3B;IACD,2BAA2B,EAAE;QAC3B,OAAO,EACL,mFAAmF;QACrF,WAAW,EAAE,aAAa;KAC3B;IACD,mBAAmB,EAAE;QACnB,OAAO,EACL,6GAA6G;QAC/G,WAAW,EAAE,aAAa;KAC3B;CACO,CAAC;AAEX,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,0DAA0D;AAC7C,QAAA,iBAAiB,GAAG;IAC/B,YAAY;IACZ,gBAAgB;IAChB,uBAAuB;IACvB,gBAAgB;IAChB,uBAAuB;IACvB,oBAAoB;IACpB,oBAAoB;IACpB,kBAAkB;IAClB,yBAAyB;IACzB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,kBAAkB;IAClB,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,wBAAwB;IACxB,kBAAkB;IAClB,0BAA0B;IAC1B,uBAAuB;IACvB,+BAA+B;CACvB,CAAC;AAEX,sDAAsD;AACzC,QAAA,iBAAiB,GAAG,wBAAwB,CAAC;AAE1D,+BAA+B;AAClB,QAAA,YAAY,GAAG;IAC1B,sBAAsB;IACtB,wBAAwB;IACxB,4BAA4B;CACpB,CAAC;AAEX,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,yDAAyD;AAC5C,QAAA,2BAA2B,GAAG;IACzC,WAAW;IACX,WAAW;IACX,SAAS;IACT,SAAS;IACT,SAAS;IACT,kBAAkB;IAClB,kBAAkB;IAClB,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,IAAI;IACJ,MAAM;IACN,MAAM;IACN,SAAS;IACT,OAAO;IACP,UAAU;IACV,aAAa;IACb,eAAe;IACf,eAAe;IACf,sBAAsB;IACtB,mBAAmB;CACX,CAAC;AAEX,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,gDAAgD;AACnC,QAAA,wBAAwB,GAAG,CAAC,MAAM,EAAE,aAAa,CAAU,CAAC;AAEzE,gEAAgE;AACnD,QAAA,2BAA2B,GAAG;IACzC,SAAS;IACT,UAAU;IACV,UAAU;IACV,SAAS;IACT,SAAS;IACT,OAAO;IACP,OAAO;IACP,OAAO;CACC,CAAC;AAEX,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,sCAAsC;AACzB,QAAA,0BAA0B,GAAG;IACxC,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,YAAY;CACJ,CAAC;AAEX,qCAAqC;AACxB,QAAA,0BAA0B,GAAG;IACxC,WAAW;IACX,YAAY;IACZ,WAAW;IACX,WAAW;IACX,aAAa;IACb,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;CACJ,CAAC;AAEX,qCAAqC;AACxB,QAAA,0BAA0B,GAAG;IACxC,WAAW;IACX,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,WAAW;IACX,YAAY;CACJ,CAAC;AAEX,qCAAqC;AACxB,QAAA,wBAAwB,GAAG;IACtC,GAAG,kCAA0B;IAC7B,GAAG,kCAA0B;IAC7B,GAAG,kCAA0B;IAC7B,iBAAiB;CACT,CAAC;AAEX,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,yCAAyC;AAC5B,QAAA,wBAAwB,GAAG;IACtC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,CAAU;IAC7B,KAAK,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAU;CAC5C,CAAC;AAEX,iDAAiD;AACpC,QAAA,uBAAuB,GAAG;IACrC,sBAAsB;IACtB,yBAAyB;IACzB,uBAAuB;IACvB,6BAA6B;CACrB,CAAC;AAEX,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,uBAAuB;AACV,QAAA,gBAAgB,GAAG;IAC9B,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,MAAM;CACf,CAAC;AAEX,qCAAqC;AACxB,QAAA,8BAA8B,GAAG,EAAE,CAAC;AAEjD,4CAA4C;AAC/B,QAAA,qBAAqB,GAAG,EAAE,CAAC;AAExC,+CAA+C;AAClC,QAAA,wBAAwB,GAAG,EAAE,CAAC;AAE3C,sCAAsC;AACzB,QAAA,eAAe,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.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.2.0",
3
+ "version": "1.3.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",