eslint-plugin-firebase-ai-logic 1.0.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 (129) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +196 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/rules/no-deprecated-firebase-vertexai.d.ts +4 -0
  6. package/dist/rules/no-deprecated-firebase-vertexai.d.ts.map +1 -0
  7. package/dist/rules/no-deprecated-firebase-vertexai.js +68 -0
  8. package/dist/rules/no-deprecated-firebase-vertexai.js.map +1 -0
  9. package/dist/rules/no-deprecated-models.d.ts +4 -0
  10. package/dist/rules/no-deprecated-models.d.ts.map +1 -0
  11. package/dist/rules/no-deprecated-models.js +109 -0
  12. package/dist/rules/no-deprecated-models.js.map +1 -0
  13. package/dist/rules/no-google-genai-import.d.ts +4 -0
  14. package/dist/rules/no-google-genai-import.d.ts.map +1 -0
  15. package/dist/rules/no-google-genai-import.js +83 -0
  16. package/dist/rules/no-google-genai-import.js.map +1 -0
  17. package/dist/rules/no-schema-in-prompt.d.ts +4 -0
  18. package/dist/rules/no-schema-in-prompt.d.ts.map +1 -0
  19. package/dist/rules/no-schema-in-prompt.js +145 -0
  20. package/dist/rules/no-schema-in-prompt.js.map +1 -0
  21. package/dist/rules/no-sensitive-system-instruction.d.ts +4 -0
  22. package/dist/rules/no-sensitive-system-instruction.d.ts.map +1 -0
  23. package/dist/rules/no-sensitive-system-instruction.js +120 -0
  24. package/dist/rules/no-sensitive-system-instruction.js.map +1 -0
  25. package/dist/rules/no-streaming-with-schema.d.ts +4 -0
  26. package/dist/rules/no-streaming-with-schema.d.ts.map +1 -0
  27. package/dist/rules/no-streaming-with-schema.js +72 -0
  28. package/dist/rules/no-streaming-with-schema.js.map +1 -0
  29. package/dist/rules/no-thinking-simple-tasks.d.ts +4 -0
  30. package/dist/rules/no-thinking-simple-tasks.d.ts.map +1 -0
  31. package/dist/rules/no-thinking-simple-tasks.js +149 -0
  32. package/dist/rules/no-thinking-simple-tasks.js.map +1 -0
  33. package/dist/rules/no-unlimited-chat-history.d.ts +4 -0
  34. package/dist/rules/no-unlimited-chat-history.d.ts.map +1 -0
  35. package/dist/rules/no-unlimited-chat-history.js +122 -0
  36. package/dist/rules/no-unlimited-chat-history.js.map +1 -0
  37. package/dist/rules/no-unsupported-function-params.d.ts +4 -0
  38. package/dist/rules/no-unsupported-function-params.d.ts.map +1 -0
  39. package/dist/rules/no-unsupported-function-params.js +113 -0
  40. package/dist/rules/no-unsupported-function-params.js.map +1 -0
  41. package/dist/rules/no-unsupported-mime-type.d.ts +4 -0
  42. package/dist/rules/no-unsupported-mime-type.d.ts.map +1 -0
  43. package/dist/rules/no-unsupported-mime-type.js +162 -0
  44. package/dist/rules/no-unsupported-mime-type.js.map +1 -0
  45. package/dist/rules/no-unsupported-schema-features.d.ts +4 -0
  46. package/dist/rules/no-unsupported-schema-features.d.ts.map +1 -0
  47. package/dist/rules/no-unsupported-schema-features.js +107 -0
  48. package/dist/rules/no-unsupported-schema-features.js.map +1 -0
  49. package/dist/rules/no-verbose-prompts.d.ts +4 -0
  50. package/dist/rules/no-verbose-prompts.d.ts.map +1 -0
  51. package/dist/rules/no-verbose-prompts.js +119 -0
  52. package/dist/rules/no-verbose-prompts.js.map +1 -0
  53. package/dist/rules/no-vertex-ai-direct-import.d.ts +4 -0
  54. package/dist/rules/no-vertex-ai-direct-import.d.ts.map +1 -0
  55. package/dist/rules/no-vertex-ai-direct-import.js +48 -0
  56. package/dist/rules/no-vertex-ai-direct-import.js.map +1 -0
  57. package/dist/rules/no-vertexai-only-import.d.ts +4 -0
  58. package/dist/rules/no-vertexai-only-import.d.ts.map +1 -0
  59. package/dist/rules/no-vertexai-only-import.js +75 -0
  60. package/dist/rules/no-vertexai-only-import.js.map +1 -0
  61. package/dist/rules/prefer-batch-requests.d.ts +4 -0
  62. package/dist/rules/prefer-batch-requests.d.ts.map +1 -0
  63. package/dist/rules/prefer-batch-requests.js +168 -0
  64. package/dist/rules/prefer-batch-requests.js.map +1 -0
  65. package/dist/rules/prefer-cloud-storage-large-files.d.ts +4 -0
  66. package/dist/rules/prefer-cloud-storage-large-files.d.ts.map +1 -0
  67. package/dist/rules/prefer-cloud-storage-large-files.js +90 -0
  68. package/dist/rules/prefer-cloud-storage-large-files.js.map +1 -0
  69. package/dist/rules/prefer-concise-property-names.d.ts +4 -0
  70. package/dist/rules/prefer-concise-property-names.d.ts.map +1 -0
  71. package/dist/rules/prefer-concise-property-names.js +145 -0
  72. package/dist/rules/prefer-concise-property-names.js.map +1 -0
  73. package/dist/rules/prefer-count-tokens.d.ts +4 -0
  74. package/dist/rules/prefer-count-tokens.d.ts.map +1 -0
  75. package/dist/rules/prefer-count-tokens.js +106 -0
  76. package/dist/rules/prefer-count-tokens.js.map +1 -0
  77. package/dist/rules/prefer-optional-properties.d.ts +4 -0
  78. package/dist/rules/prefer-optional-properties.d.ts.map +1 -0
  79. package/dist/rules/prefer-optional-properties.js +93 -0
  80. package/dist/rules/prefer-optional-properties.js.map +1 -0
  81. package/dist/rules/prefer-streaming-long-responses.d.ts +4 -0
  82. package/dist/rules/prefer-streaming-long-responses.d.ts.map +1 -0
  83. package/dist/rules/prefer-streaming-long-responses.js +138 -0
  84. package/dist/rules/prefer-streaming-long-responses.js.map +1 -0
  85. package/dist/rules/require-ai-before-model.d.ts +4 -0
  86. package/dist/rules/require-ai-before-model.d.ts.map +1 -0
  87. package/dist/rules/require-ai-before-model.js +99 -0
  88. package/dist/rules/require-ai-before-model.js.map +1 -0
  89. package/dist/rules/require-app-check-production.d.ts +4 -0
  90. package/dist/rules/require-app-check-production.d.ts.map +1 -0
  91. package/dist/rules/require-app-check-production.js +59 -0
  92. package/dist/rules/require-app-check-production.js.map +1 -0
  93. package/dist/rules/require-backend.d.ts +4 -0
  94. package/dist/rules/require-backend.d.ts.map +1 -0
  95. package/dist/rules/require-backend.js +89 -0
  96. package/dist/rules/require-backend.js.map +1 -0
  97. package/dist/rules/require-error-handling.d.ts +4 -0
  98. package/dist/rules/require-error-handling.d.ts.map +1 -0
  99. package/dist/rules/require-error-handling.js +94 -0
  100. package/dist/rules/require-error-handling.js.map +1 -0
  101. package/dist/rules/require-function-description.d.ts +4 -0
  102. package/dist/rules/require-function-description.d.ts.map +1 -0
  103. package/dist/rules/require-function-description.js +134 -0
  104. package/dist/rules/require-function-description.js.map +1 -0
  105. package/dist/rules/require-function-response-handling.d.ts +4 -0
  106. package/dist/rules/require-function-response-handling.d.ts.map +1 -0
  107. package/dist/rules/require-function-response-handling.js +131 -0
  108. package/dist/rules/require-function-response-handling.js.map +1 -0
  109. package/dist/rules/require-json-validation.d.ts +4 -0
  110. package/dist/rules/require-json-validation.d.ts.map +1 -0
  111. package/dist/rules/require-json-validation.js +145 -0
  112. package/dist/rules/require-json-validation.js.map +1 -0
  113. package/dist/rules/require-thought-signature.d.ts +4 -0
  114. package/dist/rules/require-thought-signature.d.ts.map +1 -0
  115. package/dist/rules/require-thought-signature.js +132 -0
  116. package/dist/rules/require-thought-signature.js.map +1 -0
  117. package/dist/types.d.ts +18 -0
  118. package/dist/types.d.ts.map +1 -0
  119. package/dist/types.js +3 -0
  120. package/dist/types.js.map +1 -0
  121. package/dist/utils/ast-helpers.d.ts +81 -0
  122. package/dist/utils/ast-helpers.d.ts.map +1 -0
  123. package/dist/utils/ast-helpers.js +209 -0
  124. package/dist/utils/ast-helpers.js.map +1 -0
  125. package/dist/utils/constants.d.ts +64 -0
  126. package/dist/utils/constants.d.ts.map +1 -0
  127. package/dist/utils/constants.js +182 -0
  128. package/dist/utils/constants.js.map +1 -0
  129. package/package.json +50 -0
@@ -0,0 +1,4 @@
1
+ import type { ESLint } from 'eslint';
2
+ declare const plugin: ESLint.Plugin;
3
+ export = plugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AA+N7C,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAOpB,CAAC;AAEF,SAAS,MAAM,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ // Import rules
6
+ const no_google_genai_import_js_1 = __importDefault(require("./rules/no-google-genai-import.js"));
7
+ const no_vertex_ai_direct_import_js_1 = __importDefault(require("./rules/no-vertex-ai-direct-import.js"));
8
+ const no_deprecated_firebase_vertexai_js_1 = __importDefault(require("./rules/no-deprecated-firebase-vertexai.js"));
9
+ const no_vertexai_only_import_js_1 = __importDefault(require("./rules/no-vertexai-only-import.js"));
10
+ const no_deprecated_models_js_1 = __importDefault(require("./rules/no-deprecated-models.js"));
11
+ const require_backend_js_1 = __importDefault(require("./rules/require-backend.js"));
12
+ const require_ai_before_model_js_1 = __importDefault(require("./rules/require-ai-before-model.js"));
13
+ const no_schema_in_prompt_js_1 = __importDefault(require("./rules/no-schema-in-prompt.js"));
14
+ const no_streaming_with_schema_js_1 = __importDefault(require("./rules/no-streaming-with-schema.js"));
15
+ const no_unsupported_schema_features_js_1 = __importDefault(require("./rules/no-unsupported-schema-features.js"));
16
+ const prefer_optional_properties_js_1 = __importDefault(require("./rules/prefer-optional-properties.js"));
17
+ const require_function_description_js_1 = __importDefault(require("./rules/require-function-description.js"));
18
+ const no_unsupported_function_params_js_1 = __importDefault(require("./rules/no-unsupported-function-params.js"));
19
+ const require_function_response_handling_js_1 = __importDefault(require("./rules/require-function-response-handling.js"));
20
+ const require_error_handling_js_1 = __importDefault(require("./rules/require-error-handling.js"));
21
+ const require_json_validation_js_1 = __importDefault(require("./rules/require-json-validation.js"));
22
+ const prefer_count_tokens_js_1 = __importDefault(require("./rules/prefer-count-tokens.js"));
23
+ const no_unlimited_chat_history_js_1 = __importDefault(require("./rules/no-unlimited-chat-history.js"));
24
+ const prefer_batch_requests_js_1 = __importDefault(require("./rules/prefer-batch-requests.js"));
25
+ const no_verbose_prompts_js_1 = __importDefault(require("./rules/no-verbose-prompts.js"));
26
+ const no_sensitive_system_instruction_js_1 = __importDefault(require("./rules/no-sensitive-system-instruction.js"));
27
+ const require_app_check_production_js_1 = __importDefault(require("./rules/require-app-check-production.js"));
28
+ const no_unsupported_mime_type_js_1 = __importDefault(require("./rules/no-unsupported-mime-type.js"));
29
+ const prefer_cloud_storage_large_files_js_1 = __importDefault(require("./rules/prefer-cloud-storage-large-files.js"));
30
+ const prefer_streaming_long_responses_js_1 = __importDefault(require("./rules/prefer-streaming-long-responses.js"));
31
+ const no_thinking_simple_tasks_js_1 = __importDefault(require("./rules/no-thinking-simple-tasks.js"));
32
+ const prefer_concise_property_names_js_1 = __importDefault(require("./rules/prefer-concise-property-names.js"));
33
+ const require_thought_signature_js_1 = __importDefault(require("./rules/require-thought-signature.js"));
34
+ const rules = {
35
+ // Import rules (4)
36
+ 'no-google-genai-import': no_google_genai_import_js_1.default,
37
+ 'no-vertex-ai-direct-import': no_vertex_ai_direct_import_js_1.default,
38
+ 'no-deprecated-firebase-vertexai': no_deprecated_firebase_vertexai_js_1.default,
39
+ 'no-vertexai-only-import': no_vertexai_only_import_js_1.default,
40
+ // Model rules (1)
41
+ 'no-deprecated-models': no_deprecated_models_js_1.default,
42
+ // Initialization rules (2)
43
+ 'require-backend': require_backend_js_1.default,
44
+ 'require-ai-before-model': require_ai_before_model_js_1.default,
45
+ // Schema rules (4)
46
+ 'no-schema-in-prompt': no_schema_in_prompt_js_1.default,
47
+ 'no-streaming-with-schema': no_streaming_with_schema_js_1.default,
48
+ 'no-unsupported-schema-features': no_unsupported_schema_features_js_1.default,
49
+ 'prefer-optional-properties': prefer_optional_properties_js_1.default,
50
+ // Function calling rules (3)
51
+ 'require-function-description': require_function_description_js_1.default,
52
+ 'no-unsupported-function-params': no_unsupported_function_params_js_1.default,
53
+ 'require-function-response-handling': require_function_response_handling_js_1.default,
54
+ // Error handling rules (2)
55
+ 'require-error-handling': require_error_handling_js_1.default,
56
+ 'require-json-validation': require_json_validation_js_1.default,
57
+ // Performance & cost rules (4)
58
+ 'prefer-count-tokens': prefer_count_tokens_js_1.default,
59
+ 'no-unlimited-chat-history': no_unlimited_chat_history_js_1.default,
60
+ 'prefer-batch-requests': prefer_batch_requests_js_1.default,
61
+ 'no-verbose-prompts': no_verbose_prompts_js_1.default,
62
+ // Security rules (2)
63
+ 'no-sensitive-system-instruction': no_sensitive_system_instruction_js_1.default,
64
+ 'require-app-check-production': require_app_check_production_js_1.default,
65
+ // Multimodal/Vision rules (2)
66
+ 'no-unsupported-mime-type': no_unsupported_mime_type_js_1.default,
67
+ 'prefer-cloud-storage-large-files': prefer_cloud_storage_large_files_js_1.default,
68
+ // Best practices rules (3)
69
+ 'prefer-streaming-long-responses': prefer_streaming_long_responses_js_1.default,
70
+ 'no-thinking-simple-tasks': no_thinking_simple_tasks_js_1.default,
71
+ 'prefer-concise-property-names': prefer_concise_property_names_js_1.default,
72
+ // Gemini 3 specific rules (1)
73
+ 'require-thought-signature': require_thought_signature_js_1.default,
74
+ };
75
+ // Rule configurations
76
+ const recommendedRules = {
77
+ // Imports - all errors (breaking issues)
78
+ 'firebase-ai-logic/no-google-genai-import': 'error',
79
+ 'firebase-ai-logic/no-vertex-ai-direct-import': 'error',
80
+ 'firebase-ai-logic/no-deprecated-firebase-vertexai': 'error',
81
+ 'firebase-ai-logic/no-vertexai-only-import': 'error',
82
+ // Models - error (deprecated models)
83
+ 'firebase-ai-logic/no-deprecated-models': 'error',
84
+ // Initialization - errors (required for functionality)
85
+ 'firebase-ai-logic/require-backend': 'error',
86
+ 'firebase-ai-logic/require-ai-before-model': 'error',
87
+ // Schema - mix of errors and warnings
88
+ 'firebase-ai-logic/no-streaming-with-schema': 'error',
89
+ 'firebase-ai-logic/no-unsupported-schema-features': 'error',
90
+ 'firebase-ai-logic/no-schema-in-prompt': 'warn',
91
+ 'firebase-ai-logic/prefer-optional-properties': 'warn',
92
+ // Function calling - warnings
93
+ 'firebase-ai-logic/require-function-description': 'warn',
94
+ 'firebase-ai-logic/no-unsupported-function-params': 'error',
95
+ 'firebase-ai-logic/require-function-response-handling': 'warn',
96
+ // Error handling - warnings
97
+ 'firebase-ai-logic/require-error-handling': 'warn',
98
+ 'firebase-ai-logic/require-json-validation': 'warn',
99
+ // Performance - warnings
100
+ 'firebase-ai-logic/no-unlimited-chat-history': 'warn',
101
+ // Security - errors
102
+ 'firebase-ai-logic/no-sensitive-system-instruction': 'error',
103
+ 'firebase-ai-logic/require-app-check-production': 'warn',
104
+ // Multimodal - errors
105
+ 'firebase-ai-logic/no-unsupported-mime-type': 'error',
106
+ 'firebase-ai-logic/prefer-cloud-storage-large-files': 'warn',
107
+ // Gemini 3 specific - error (causes 400 errors if missing)
108
+ 'firebase-ai-logic/require-thought-signature': 'error',
109
+ };
110
+ const strictRules = {
111
+ ...recommendedRules,
112
+ // Upgrade warnings to errors
113
+ 'firebase-ai-logic/no-schema-in-prompt': 'error',
114
+ 'firebase-ai-logic/prefer-optional-properties': 'error',
115
+ 'firebase-ai-logic/require-function-description': 'error',
116
+ 'firebase-ai-logic/require-function-response-handling': 'error',
117
+ 'firebase-ai-logic/require-error-handling': 'error',
118
+ 'firebase-ai-logic/require-json-validation': 'error',
119
+ 'firebase-ai-logic/no-unlimited-chat-history': 'error',
120
+ 'firebase-ai-logic/require-app-check-production': 'error',
121
+ 'firebase-ai-logic/prefer-cloud-storage-large-files': 'error',
122
+ // Add optional rules
123
+ 'firebase-ai-logic/prefer-count-tokens': 'warn',
124
+ 'firebase-ai-logic/prefer-batch-requests': 'warn',
125
+ 'firebase-ai-logic/no-verbose-prompts': 'warn',
126
+ 'firebase-ai-logic/prefer-streaming-long-responses': 'warn',
127
+ 'firebase-ai-logic/no-thinking-simple-tasks': 'warn',
128
+ 'firebase-ai-logic/prefer-concise-property-names': 'warn',
129
+ };
130
+ const allRules = {
131
+ 'firebase-ai-logic/no-google-genai-import': 'error',
132
+ 'firebase-ai-logic/no-vertex-ai-direct-import': 'error',
133
+ 'firebase-ai-logic/no-deprecated-firebase-vertexai': 'error',
134
+ 'firebase-ai-logic/no-vertexai-only-import': 'error',
135
+ 'firebase-ai-logic/no-deprecated-models': 'error',
136
+ 'firebase-ai-logic/require-backend': 'error',
137
+ 'firebase-ai-logic/require-ai-before-model': 'error',
138
+ 'firebase-ai-logic/no-schema-in-prompt': 'error',
139
+ 'firebase-ai-logic/no-streaming-with-schema': 'error',
140
+ 'firebase-ai-logic/no-unsupported-schema-features': 'error',
141
+ 'firebase-ai-logic/prefer-optional-properties': 'error',
142
+ 'firebase-ai-logic/require-function-description': 'error',
143
+ 'firebase-ai-logic/no-unsupported-function-params': 'error',
144
+ 'firebase-ai-logic/require-function-response-handling': 'error',
145
+ 'firebase-ai-logic/require-error-handling': 'error',
146
+ 'firebase-ai-logic/require-json-validation': 'error',
147
+ 'firebase-ai-logic/prefer-count-tokens': 'error',
148
+ 'firebase-ai-logic/no-unlimited-chat-history': 'error',
149
+ 'firebase-ai-logic/prefer-batch-requests': 'error',
150
+ 'firebase-ai-logic/no-verbose-prompts': 'error',
151
+ 'firebase-ai-logic/no-sensitive-system-instruction': 'error',
152
+ 'firebase-ai-logic/require-app-check-production': 'error',
153
+ 'firebase-ai-logic/no-unsupported-mime-type': 'error',
154
+ 'firebase-ai-logic/prefer-cloud-storage-large-files': 'error',
155
+ 'firebase-ai-logic/prefer-streaming-long-responses': 'error',
156
+ 'firebase-ai-logic/no-thinking-simple-tasks': 'error',
157
+ 'firebase-ai-logic/prefer-concise-property-names': 'error',
158
+ 'firebase-ai-logic/require-thought-signature': 'error',
159
+ };
160
+ // Flat config format (ESLint 9+)
161
+ const configs = {
162
+ recommended: {
163
+ plugins: {
164
+ 'firebase-ai-logic': {
165
+ rules,
166
+ },
167
+ },
168
+ rules: recommendedRules,
169
+ },
170
+ strict: {
171
+ plugins: {
172
+ 'firebase-ai-logic': {
173
+ rules,
174
+ },
175
+ },
176
+ rules: strictRules,
177
+ },
178
+ all: {
179
+ plugins: {
180
+ 'firebase-ai-logic': {
181
+ rules,
182
+ },
183
+ },
184
+ rules: allRules,
185
+ },
186
+ };
187
+ const plugin = {
188
+ meta: {
189
+ name: 'eslint-plugin-firebase-ai-logic',
190
+ version: '1.0.0',
191
+ },
192
+ rules,
193
+ configs,
194
+ };
195
+ module.exports = plugin;
196
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
4
+ //# sourceMappingURL=no-deprecated-firebase-vertexai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated-firebase-vertexai.d.ts","sourceRoot":"","sources":["../../src/rules/no-deprecated-firebase-vertexai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAkFhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
+ const rule = {
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: "Disallow importing from 'firebase/vertexai-preview' - use 'firebase/ai' instead",
9
+ recommended: true,
10
+ url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#no-deprecated-firebase-vertexai',
11
+ },
12
+ fixable: 'code',
13
+ schema: [],
14
+ messages: {
15
+ deprecatedImport: "Import from 'firebase/vertexai-preview' is deprecated. Use 'firebase/ai' instead.",
16
+ migrationNote: "The 'firebase/vertexai-preview' package has been replaced by 'firebase/ai' which supports both GoogleAIBackend and VertexAIBackend.",
17
+ },
18
+ },
19
+ create(context) {
20
+ return {
21
+ ImportDeclaration(node) {
22
+ if ((0, ast_helpers_js_1.isStringLiteral)(node.source) &&
23
+ node.source.value === 'firebase/vertexai-preview') {
24
+ context.report({
25
+ node,
26
+ messageId: 'deprecatedImport',
27
+ fix(fixer) {
28
+ const specifiers = node.specifiers;
29
+ if (specifiers.length === 0) {
30
+ return fixer.replaceText(node, "import 'firebase/ai';");
31
+ }
32
+ // Map old imports to new ones
33
+ const importMapping = {
34
+ getVertexAI: 'getAI',
35
+ getGenerativeModel: 'getGenerativeModel',
36
+ };
37
+ const newImports = [];
38
+ for (const specifier of specifiers) {
39
+ if (specifier.type === 'ImportSpecifier' &&
40
+ specifier.imported.type === 'Identifier') {
41
+ const originalName = specifier.imported.name;
42
+ const newName = importMapping[originalName] ?? originalName;
43
+ if (!newImports.includes(newName)) {
44
+ newImports.push(newName);
45
+ }
46
+ }
47
+ }
48
+ return fixer.replaceText(node, `import { ${newImports.join(', ')} } from 'firebase/ai';`);
49
+ },
50
+ });
51
+ }
52
+ },
53
+ CallExpression(node) {
54
+ if (node.callee.type === 'Import' &&
55
+ node.arguments.length > 0 &&
56
+ (0, ast_helpers_js_1.isStringLiteral)(node.arguments[0]) &&
57
+ node.arguments[0].value === 'firebase/vertexai-preview') {
58
+ context.report({
59
+ node,
60
+ messageId: 'deprecatedImport',
61
+ });
62
+ }
63
+ },
64
+ };
65
+ },
66
+ };
67
+ exports.default = rule;
68
+ //# sourceMappingURL=no-deprecated-firebase-vertexai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated-firebase-vertexai.js","sourceRoot":"","sources":["../../src/rules/no-deprecated-firebase-vertexai.ts"],"names":[],"mappings":";;AACA,4DAA0D;AAE1D,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,iFAAiF;YACnF,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,6FAA6F;SACnG;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,gBAAgB,EACd,mFAAmF;YACrF,aAAa,EACX,qIAAqI;SACxI;KACF;IAED,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,iBAAiB,CAAC,IAAI;gBACpB,IACE,IAAA,gCAAe,EAAC,IAAI,CAAC,MAAM,CAAC;oBAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,2BAA2B,EACjD,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,kBAAkB;wBAC7B,GAAG,CAAC,KAAK;4BACP,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;4BAEnC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gCAC5B,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;4BAC1D,CAAC;4BAED,8BAA8B;4BAC9B,MAAM,aAAa,GAA2B;gCAC5C,WAAW,EAAE,OAAO;gCACpB,kBAAkB,EAAE,oBAAoB;6BACzC,CAAC;4BAEF,MAAM,UAAU,GAAa,EAAE,CAAC;4BAEhC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gCACnC,IACE,SAAS,CAAC,IAAI,KAAK,iBAAiB;oCACpC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EACxC,CAAC;oCACD,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;oCAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC;oCAE5D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wCAClC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oCAC3B,CAAC;gCACH,CAAC;4BACH,CAAC;4BAED,OAAO,KAAK,CAAC,WAAW,CACtB,IAAI,EACJ,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAC1D,CAAC;wBACJ,CAAC;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,cAAc,CAAC,IAAI;gBACjB,IACG,IAAI,CAAC,MAAsC,CAAC,IAAI,KAAK,QAAQ;oBAC9D,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;oBACzB,IAAA,gCAAe,EAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBACjC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAuB,CAAC,KAAK,KAAK,2BAA2B,EAC9E,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,kBAAkB;qBAC9B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
4
+ //# sourceMappingURL=no-deprecated-models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated-models.d.ts","sourceRoot":"","sources":["../../src/rules/no-deprecated-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAOnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAkIhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
+ const constants_js_1 = require("../utils/constants.js");
5
+ const rule = {
6
+ meta: {
7
+ type: 'problem',
8
+ docs: {
9
+ description: 'Disallow using deprecated Gemini models that have been retired and return 404 errors',
10
+ recommended: true,
11
+ url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#no-deprecated-models',
12
+ },
13
+ fixable: 'code',
14
+ schema: [],
15
+ messages: {
16
+ deprecatedModel: "Model '{{ model }}' is deprecated and will return 404 errors. Use '{{ recommended }}' instead.",
17
+ deprecatedModelList: 'Deprecated models include: gemini-1.0-*, gemini-1.5-*, gemini-2.0-*, gemini-2.5-*. Current valid models are: {{ validModels }}.',
18
+ gemini3Migration: "Gemini 3 is the current generation. Use 'gemini-3-flash-preview' for most tasks or 'gemini-3-pro-preview' for complex reasoning.",
19
+ },
20
+ },
21
+ create(context) {
22
+ function checkModelValue(node, modelValue) {
23
+ const lowerModel = modelValue.toLowerCase();
24
+ // Check if it's a deprecated model
25
+ const isDeprecated = constants_js_1.DEPRECATED_MODELS.some((deprecated) => lowerModel === deprecated.toLowerCase() ||
26
+ lowerModel.startsWith(deprecated.toLowerCase()));
27
+ if (isDeprecated) {
28
+ context.report({
29
+ node,
30
+ messageId: 'deprecatedModel',
31
+ data: {
32
+ model: modelValue,
33
+ recommended: constants_js_1.RECOMMENDED_MODEL,
34
+ },
35
+ fix(fixer) {
36
+ if ((0, ast_helpers_js_1.isStringLiteral)(node)) {
37
+ return fixer.replaceText(node, `'${constants_js_1.RECOMMENDED_MODEL}'`);
38
+ }
39
+ return null;
40
+ },
41
+ });
42
+ }
43
+ }
44
+ return {
45
+ // Check object literals with model property
46
+ Property(node) {
47
+ if (node.key.type === 'Identifier' &&
48
+ node.key.name === 'model' &&
49
+ node.value) {
50
+ const modelValue = (0, ast_helpers_js_1.getStringValue)(node.value);
51
+ if (modelValue) {
52
+ // Additional check: make sure this is likely a Gemini model config
53
+ const isGeminiModel = modelValue.toLowerCase().includes('gemini') ||
54
+ modelValue.toLowerCase().includes('models/');
55
+ if (isGeminiModel) {
56
+ checkModelValue(node.value, modelValue);
57
+ }
58
+ }
59
+ }
60
+ },
61
+ // Check string literals that look like model names
62
+ Literal(node) {
63
+ if (typeof node.value !== 'string')
64
+ return;
65
+ const value = node.value;
66
+ // Only check strings that look like Gemini model names
67
+ if (!value.toLowerCase().includes('gemini'))
68
+ return;
69
+ // Skip if this is an import source
70
+ if (node.parent?.type === 'ImportDeclaration' ||
71
+ node.parent?.type === 'ExportNamedDeclaration' ||
72
+ node.parent?.type === 'ExportAllDeclaration') {
73
+ return;
74
+ }
75
+ // Skip if it's already a model property (handled above in Property handler)
76
+ // This includes both direct model properties and those in getGenerativeModel calls
77
+ if (node.parent?.type === 'Property') {
78
+ const property = node.parent;
79
+ if (property.key.type === 'Identifier' &&
80
+ property.key.name === 'model') {
81
+ return;
82
+ }
83
+ }
84
+ // Check if this looks like a model name being used as a variable value
85
+ const isDeprecated = constants_js_1.DEPRECATED_MODELS.some((deprecated) => value.toLowerCase() === deprecated.toLowerCase() ||
86
+ value.toLowerCase() === `models/${deprecated.toLowerCase()}`);
87
+ if (isDeprecated) {
88
+ context.report({
89
+ node,
90
+ messageId: 'deprecatedModel',
91
+ data: {
92
+ model: value,
93
+ recommended: constants_js_1.RECOMMENDED_MODEL,
94
+ },
95
+ fix(fixer) {
96
+ // Handle models/ prefix
97
+ if (value.toLowerCase().startsWith('models/')) {
98
+ return fixer.replaceText(node, `'models/${constants_js_1.RECOMMENDED_MODEL}'`);
99
+ }
100
+ return fixer.replaceText(node, `'${constants_js_1.RECOMMENDED_MODEL}'`);
101
+ },
102
+ });
103
+ }
104
+ },
105
+ };
106
+ },
107
+ };
108
+ exports.default = rule;
109
+ //# sourceMappingURL=no-deprecated-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated-models.js","sourceRoot":"","sources":["../../src/rules/no-deprecated-models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
4
+ //# sourceMappingURL=no-google-genai-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-google-genai-import.d.ts","sourceRoot":"","sources":["../../src/rules/no-google-genai-import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAyGhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ast_helpers_js_1 = require("../utils/ast-helpers.js");
4
+ const rule = {
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: "Disallow importing from '@google/generative-ai' - use 'firebase/ai' instead",
9
+ recommended: true,
10
+ url: 'https://github.com/Just-mpm/eslint-plugin-firebase-ai-logic#no-google-genai-import',
11
+ },
12
+ fixable: 'code',
13
+ schema: [],
14
+ messages: {
15
+ wrongImport: "Do not import from '@google/generative-ai'. Use 'firebase/ai' instead for Firebase AI Logic integration.",
16
+ wrongImportDetail: "The '@google/generative-ai' package is for direct Gemini API usage without Firebase. For Firebase projects, use 'firebase/ai' which provides Firebase integration, App Check support, and proper authentication.",
17
+ },
18
+ },
19
+ create(context) {
20
+ return {
21
+ ImportDeclaration(node) {
22
+ if ((0, ast_helpers_js_1.isStringLiteral)(node.source) &&
23
+ node.source.value === '@google/generative-ai') {
24
+ context.report({
25
+ node,
26
+ messageId: 'wrongImport',
27
+ fix(fixer) {
28
+ // Get the imported specifiers
29
+ const specifiers = node.specifiers;
30
+ if (specifiers.length === 0) {
31
+ return fixer.replaceText(node, "import 'firebase/ai';");
32
+ }
33
+ // Map common imports from @google/generative-ai to firebase/ai equivalents
34
+ const importMapping = {
35
+ GoogleGenerativeAI: 'getAI',
36
+ GenerativeModel: 'getGenerativeModel',
37
+ HarmCategory: 'HarmCategory',
38
+ HarmBlockThreshold: 'HarmBlockThreshold',
39
+ // Most other imports have different names in firebase/ai
40
+ };
41
+ const newImports = [];
42
+ const needsGoogleAIBackend = specifiers.some((s) => s.type === 'ImportSpecifier' &&
43
+ s.imported.type === 'Identifier' &&
44
+ s.imported.name === 'GoogleGenerativeAI');
45
+ for (const specifier of specifiers) {
46
+ if (specifier.type === 'ImportSpecifier' &&
47
+ specifier.imported.type === 'Identifier') {
48
+ const originalName = specifier.imported.name;
49
+ const newName = importMapping[originalName];
50
+ if (newName && !newImports.includes(newName)) {
51
+ newImports.push(newName);
52
+ }
53
+ }
54
+ }
55
+ if (needsGoogleAIBackend && !newImports.includes('GoogleAIBackend')) {
56
+ newImports.push('GoogleAIBackend');
57
+ }
58
+ if (newImports.length > 0) {
59
+ return fixer.replaceText(node, `import { ${newImports.join(', ')} } from 'firebase/ai';`);
60
+ }
61
+ return null;
62
+ },
63
+ });
64
+ }
65
+ },
66
+ CallExpression(node) {
67
+ // Also catch dynamic imports - note: Import is not a valid callee type
68
+ // This code is kept for future extensibility but won't match current ESLint versions
69
+ if (node.callee.type === 'Import' &&
70
+ node.arguments.length > 0 &&
71
+ (0, ast_helpers_js_1.isStringLiteral)(node.arguments[0]) &&
72
+ node.arguments[0].value === '@google/generative-ai') {
73
+ context.report({
74
+ node,
75
+ messageId: 'wrongImport',
76
+ });
77
+ }
78
+ },
79
+ };
80
+ },
81
+ };
82
+ exports.default = rule;
83
+ //# sourceMappingURL=no-google-genai-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-google-genai-import.js","sourceRoot":"","sources":["../../src/rules/no-google-genai-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
4
+ //# sourceMappingURL=no-schema-in-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-schema-in-prompt.d.ts","sourceRoot":"","sources":["../../src/rules/no-schema-in-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAUnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA+KhB,CAAC;AAEF,eAAe,IAAI,CAAC"}