firebase-tools 15.18.0 → 15.19.1

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.
@@ -44,46 +44,46 @@
44
44
  }
45
45
  },
46
46
  "pubsub": {
47
- "version": "0.8.31",
48
- "expectedSize": 52942385,
49
- "expectedChecksum": "04a85aa9873222e9b7a430c6c49cfd9e",
50
- "expectedChecksumSHA256": "b474e7d3200f5a8b5f7f467ee3b087c94b939e7d41527e935296a7bcabdbea9a",
51
- "remoteUrl": "https://storage.googleapis.com/firebase-preview-drop/emulator/pubsub-emulator-0.8.31.zip",
52
- "downloadPathRelativeToCacheDir": "pubsub-emulator-0.8.31.zip",
53
- "binaryPathRelativeToCacheDir": "pubsub-emulator-0.8.31/pubsub-emulator/bin/cloud-pubsub-emulator"
47
+ "version": "0.8.32",
48
+ "expectedSize": 52942305,
49
+ "expectedChecksum": "b47a3698985bff5f6aedec04fad9354e",
50
+ "expectedChecksumSHA256": "476d6492718210837f13e64b5b9f54335469381827bad25eda62e36572e47a82",
51
+ "remoteUrl": "https://storage.googleapis.com/firebase-preview-drop/emulator/pubsub-emulator-0.8.32.zip",
52
+ "downloadPathRelativeToCacheDir": "pubsub-emulator-0.8.32.zip",
53
+ "binaryPathRelativeToCacheDir": "pubsub-emulator-0.8.32/pubsub-emulator/bin/cloud-pubsub-emulator"
54
54
  },
55
55
  "dataconnect": {
56
56
  "darwin": {
57
- "version": "3.4.8",
58
- "expectedSize": 32398304,
59
- "expectedChecksum": "fee47f6867b5aa939ab667fb801b9807",
60
- "expectedChecksumSHA256": "0586ffa3614f9231932ee50fb424ee4385100188aac40de91289c705d36ceb67",
61
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.4.8",
62
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.8"
57
+ "version": "3.4.10",
58
+ "expectedSize": 32439760,
59
+ "expectedChecksum": "c3609b01993c1f66d340eda59fa31467",
60
+ "expectedChecksumSHA256": "257419922a81b4856b1ce7c1ac0684b4690a380072fe132d1960070f7d00941a",
61
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.4.10",
62
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.10"
63
63
  },
64
64
  "darwin_arm64": {
65
- "version": "3.4.8",
66
- "expectedSize": 30537682,
67
- "expectedChecksum": "f4ccfe080736fb0a35d60841cf439eab",
68
- "expectedChecksumSHA256": "d3efdafa7c82f843b1cca7ae2b2404235fa9c918b892806ce4a9910e6907318f",
69
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.4.8",
70
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.8"
65
+ "version": "3.4.10",
66
+ "expectedSize": 30571186,
67
+ "expectedChecksum": "fd17de6fb356a5e0c1c67ae7f4adfa08",
68
+ "expectedChecksumSHA256": "9c6da9eea98ee85b16b6e0c5075d1c757aaa252526470fbe63cfb915e3585361",
69
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.4.10",
70
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.10"
71
71
  },
72
72
  "win32": {
73
- "version": "3.4.8",
74
- "expectedSize": 32438272,
75
- "expectedChecksum": "5850b1887b23c351d83b32142bac6858",
76
- "expectedChecksumSHA256": "d9c2ed151a5d0a9c0530f442f92b3434fe98469e5e6fee230628ba81e9a1540d",
77
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.4.8",
78
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.8.exe"
73
+ "version": "3.4.10",
74
+ "expectedSize": 32479744,
75
+ "expectedChecksum": "3ed78e5d74da96e89f385a64fa6151fc",
76
+ "expectedChecksumSHA256": "bc4bb887b5adbba5b916fa41a091f544aac70f35d5209c483fac90f89abb2c93",
77
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.4.10",
78
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.10.exe"
79
79
  },
80
80
  "linux": {
81
- "version": "3.4.8",
82
- "expectedSize": 31555768,
83
- "expectedChecksum": "c6b43a325a0e3559d7bc325591dda14f",
84
- "expectedChecksumSHA256": "f1809b93e985e497da8ed0a23c049b28f9ff4482b021c9f86af6b8c1a6949fef",
85
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.4.8",
86
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.8"
81
+ "version": "3.4.10",
82
+ "expectedSize": 31592632,
83
+ "expectedChecksum": "a003103017717ddc4ea9967d5820ea51",
84
+ "expectedChecksumSHA256": "50b22fdaf7bf1c30b5f331ef07a7f19c51309ca9c9897be426e86254e02b514c",
85
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.4.10",
86
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.10"
87
87
  }
88
88
  }
89
89
  }
@@ -127,9 +127,9 @@ exports.ALL_EXPERIMENTS = experiments({
127
127
  public: false,
128
128
  },
129
129
  abiu: {
130
- shortDescription: "Enable App Hosting ABIU and runtime selection",
131
- default: false,
132
- public: false,
130
+ shortDescription: "Enable Automatic Base Image Updates (ABIU) and runtime selection for App Hosting",
131
+ default: true,
132
+ public: true,
133
133
  },
134
134
  dataconnect: {
135
135
  shortDescription: "Deprecated. Previosuly, enabled SQL Connect related features.",
@@ -182,6 +182,11 @@ exports.ALL_EXPERIMENTS = experiments({
182
182
  default: true,
183
183
  public: false,
184
184
  },
185
+ crashlyticsWeb: {
186
+ shortDescription: "Enable the ability to upload source maps for web apps to Crashlytics.",
187
+ default: false,
188
+ public: true,
189
+ },
185
190
  });
186
191
  function isValidExperiment(name) {
187
192
  return Object.keys(exports.ALL_EXPERIMENTS).includes(name);
@@ -242,6 +242,14 @@ async function injectAntigravityContext(rootPath, projectId, appName, nonInterac
242
242
  global: installLocation === "global",
243
243
  background: false,
244
244
  agentName: "gemini-cli",
245
+ skillPackage: "firebase/agent-skills",
246
+ });
247
+ await (0, agentSkills_1.installAgentSkills)({
248
+ cwd: rootPath,
249
+ global: installLocation === "global",
250
+ background: false,
251
+ agentName: "gemini-cli",
252
+ skillPackage: "genkit-ai/skills",
245
253
  });
246
254
  const systemInstructionsTemplate = await (0, templates_1.readTemplate)("firebase-studio-export/system_instructions_template.md");
247
255
  const systemInstructions = systemInstructionsTemplate.replace("${appName}", appName);
@@ -58,38 +58,62 @@ async function execute(sqlStatements, opts) {
58
58
  : cloud_sql_connector_1.IpAddressTypes.PRIVATE,
59
59
  authType: authType,
60
60
  };
61
- const pool = new pg.Pool({
62
- ...(await connector.getOptions(connectionOpts)),
63
- password: opts.password,
64
- user: opts.username,
65
- database: opts.databaseId,
66
- });
67
- const cleanUpFn = async () => {
68
- conn.release();
69
- await pool.end();
70
- connector.close();
71
- };
72
- const conn = await pool.connect();
61
+ let pool;
62
+ let conn;
73
63
  const results = [];
74
- logFn(`Logged in as ${opts.username}`);
75
- if (opts.transaction) {
76
- sqlStatements.unshift("BEGIN;");
77
- sqlStatements.push("COMMIT;");
64
+ try {
65
+ pool = new pg.Pool({
66
+ ...(await connector.getOptions(connectionOpts)),
67
+ password: opts.password,
68
+ user: opts.username,
69
+ database: opts.databaseId,
70
+ });
71
+ pool.on("error", (err) => {
72
+ logger_1.logger.debug("[cloudsql] pool error (ignored during teardown):", err);
73
+ });
74
+ conn = await pool.connect();
75
+ logFn(`Logged in as ${opts.username}`);
76
+ if (opts.transaction) {
77
+ sqlStatements.unshift("BEGIN;");
78
+ sqlStatements.push("COMMIT;");
79
+ }
80
+ for (const s of sqlStatements) {
81
+ logFn(`> ${s}`);
82
+ try {
83
+ results.push(await conn.query(s));
84
+ }
85
+ catch (err) {
86
+ logFn(`Rolling back transaction due to error ${err}}`);
87
+ await conn.query("ROLLBACK;");
88
+ throw new error_1.FirebaseError(`Error executing SQL statement: ${s}: ${err}`);
89
+ }
90
+ }
91
+ logFn(``);
78
92
  }
79
- for (const s of sqlStatements) {
80
- logFn(`> ${s}`);
93
+ finally {
94
+ if (conn) {
95
+ try {
96
+ conn.release();
97
+ }
98
+ catch (err) {
99
+ logger_1.logger.debug("[cloudsql] error releasing connection during cleanup:", err);
100
+ }
101
+ }
102
+ if (pool) {
103
+ try {
104
+ await pool.end();
105
+ }
106
+ catch (err) {
107
+ logger_1.logger.debug("[cloudsql] error ending pool during cleanup:", err);
108
+ }
109
+ }
81
110
  try {
82
- results.push(await conn.query(s));
111
+ connector.close();
83
112
  }
84
113
  catch (err) {
85
- logFn(`Rolling back transaction due to error ${err}}`);
86
- await conn.query("ROLLBACK;");
87
- await cleanUpFn();
88
- throw new error_1.FirebaseError(`Error executing ${err}`);
114
+ logger_1.logger.debug("[cloudsql] error closing connector during cleanup:", err);
89
115
  }
90
116
  }
91
- await cleanUpFn();
92
- logFn(``);
93
117
  return results;
94
118
  }
95
119
  async function executeSqlCmdsAsIamUser(options, instanceId, databaseId, cmds, silent = false, transaction = false) {
@@ -7,41 +7,186 @@ exports.extractCodeBlock = extractCodeBlock;
7
7
  const apiv2_1 = require("../apiv2");
8
8
  const api_1 = require("../api");
9
9
  const error_1 = require("../error");
10
- const apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.cloudAiCompanionOrigin)(), auth: true });
11
- const SCHEMA_GENERATOR_EXPERIENCE = "/appeco/firebase/fdc-schema-generator";
12
- const OPERATION_GENERATION_EXPERIENCE = "/appeco/firebase/fdc-query-generator";
13
- const FIREBASE_CHAT_REQUEST_CONTEXT_TYPE_NAME = "type.googleapis.com/google.cloud.cloudaicompanion.v1main.FirebaseChatRequestContext";
10
+ const logger_1 = require("../logger");
11
+ const apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.dataconnectOrigin)(), auth: true });
14
12
  exports.PROMPT_GENERATE_CONNECTOR = "Create 4 operations for an app using the instance schema with proper authentication.";
15
13
  exports.PROMPT_GENERATE_SEED_DATA = "Create a mutation to populate the database with some seed data.";
16
- async function generateSchema(prompt, project, chatHistory = []) {
17
- const res = await apiClient.post(`/v1beta/projects/${project}/locations/global/instances/default:completeTask`, {
18
- input: { messages: [...chatHistory, { content: prompt, author: "USER" }] },
19
- experienceContext: {
20
- experience: SCHEMA_GENERATOR_EXPERIENCE,
21
- },
14
+ function logCurl(method, path, body) {
15
+ const url = `${(0, api_1.dataconnectOrigin)()}${path}`;
16
+ const headers = [
17
+ '-H "Content-Type: application/json"',
18
+ '-H "Authorization: Bearer $(gcloud auth print-access-token)"',
19
+ ].join(" ");
20
+ const curl = `curl -X ${method} "${url}" ${headers} -d '${JSON.stringify(body)}'`;
21
+ logger_1.logger.debug(`[Agent Service] Reusable cURL command:\\n${curl}`);
22
+ }
23
+ async function generateSchema(prompt, project, location, onStatus) {
24
+ const path = `/v1/projects/${project}/locations/${location}/services/-:generateSchema`;
25
+ const body = {
26
+ name: `projects/${project}/locations/${location}/services/-`,
27
+ prompt,
28
+ };
29
+ logCurl("POST", path, body);
30
+ const res = await apiClient.request({
31
+ method: "POST",
32
+ path,
33
+ body,
34
+ responseType: "stream",
35
+ resolveOnHTTPError: true,
36
+ });
37
+ if (res.status >= 400) {
38
+ const errorText = await readStream(res.body);
39
+ throw new error_1.FirebaseError(`Failed to generate schema. Status: ${res.status}, Message: ${errorText}`);
40
+ }
41
+ return consumeStream(res.body, onStatus);
42
+ }
43
+ async function generateOperation(prompt, service, project, schemas, onStatus) {
44
+ let location = "us-central1";
45
+ let serviceId = service;
46
+ if (service.startsWith("projects/")) {
47
+ const parts = service.split("/");
48
+ project = parts[1];
49
+ location = parts[3];
50
+ serviceId = parts[5];
51
+ }
52
+ if (schemas && schemas.length > 0) {
53
+ serviceId = "-";
54
+ }
55
+ const path = `/v1/projects/${project}/locations/${location}/services/${serviceId}:generateQuery`;
56
+ const body = {
57
+ name: `projects/${project}/locations/${location}/services/${serviceId}`,
58
+ prompt,
59
+ schemas,
60
+ };
61
+ logCurl("POST", path, body);
62
+ const res = await apiClient.request({
63
+ method: "POST",
64
+ path,
65
+ body,
66
+ responseType: "stream",
67
+ resolveOnHTTPError: true,
22
68
  });
23
- return extractCodeBlock(res.body.output.messages[0].content);
69
+ if (res.status >= 400) {
70
+ const errorText = await readStream(res.body);
71
+ throw new error_1.FirebaseError(`Failed to generate operation. Status: ${res.status}, Message: ${errorText}`);
72
+ }
73
+ return consumeStream(res.body, onStatus);
24
74
  }
25
- async function generateOperation(prompt, service, project, chatHistory = []) {
26
- const res = await apiClient.post(`/v1beta/projects/${project}/locations/global/instances/default:completeTask`, {
27
- input: { messages: [...chatHistory, { content: prompt, author: "USER" }] },
28
- experienceContext: {
29
- experience: OPERATION_GENERATION_EXPERIENCE,
30
- },
31
- clientContext: {
32
- additionalContext: {
33
- "@type": FIREBASE_CHAT_REQUEST_CONTEXT_TYPE_NAME,
34
- fdcInfo: { fdcServiceName: service, requiresQuery: true },
35
- },
36
- },
75
+ async function readStream(stream) {
76
+ return new Promise((resolve, reject) => {
77
+ let data = "";
78
+ stream.on("data", (chunk) => {
79
+ data += chunk.toString();
80
+ });
81
+ stream.on("end", () => {
82
+ resolve(data);
83
+ });
84
+ stream.on("error", (err) => {
85
+ reject(err);
86
+ });
87
+ });
88
+ }
89
+ async function consumeStream(stream, onStatus) {
90
+ return new Promise((resolve, reject) => {
91
+ let buffer = "";
92
+ let fullText = "";
93
+ stream.on("data", (chunk) => {
94
+ const text = chunk.toString();
95
+ fullText += text;
96
+ buffer += text;
97
+ let newlineIndex;
98
+ while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
99
+ const line = buffer.substring(0, newlineIndex).trim();
100
+ buffer = buffer.substring(newlineIndex + 1);
101
+ if (line) {
102
+ try {
103
+ const obj = JSON.parse(line);
104
+ if (obj.status && onStatus) {
105
+ onStatus(obj.status);
106
+ }
107
+ }
108
+ catch (err) {
109
+ }
110
+ }
111
+ }
112
+ });
113
+ stream.on("end", () => {
114
+ try {
115
+ const response = JSON.parse(fullText);
116
+ if (Array.isArray(response)) {
117
+ let code = "";
118
+ for (const item of response) {
119
+ if (item.status && onStatus) {
120
+ onStatus(item.status);
121
+ }
122
+ if (item.part?.textChunk?.text) {
123
+ code += item.part.textChunk.text;
124
+ }
125
+ if (item.part?.codeChunk?.code) {
126
+ code += item.part.codeChunk.code;
127
+ }
128
+ }
129
+ if (code) {
130
+ resolve(extractCodeBlock(code));
131
+ }
132
+ else {
133
+ resolve(fullText);
134
+ }
135
+ }
136
+ else {
137
+ const resObj = response;
138
+ if (resObj.part?.codeChunk?.code) {
139
+ resolve(extractCodeBlock(resObj.part.codeChunk.code));
140
+ }
141
+ else if (resObj.part?.textChunk?.text) {
142
+ resolve(extractCodeBlock(resObj.part.textChunk.text));
143
+ }
144
+ else {
145
+ resolve(fullText);
146
+ }
147
+ }
148
+ }
149
+ catch (e) {
150
+ const lines = fullText.trim().split("\n");
151
+ let code = "";
152
+ for (const line of lines) {
153
+ try {
154
+ const obj = JSON.parse(line);
155
+ if (obj.part?.codeChunk?.code) {
156
+ code += obj.part.codeChunk.code;
157
+ }
158
+ else if (obj.part?.textChunk?.text) {
159
+ code += obj.part.textChunk.text;
160
+ }
161
+ if (obj.status && onStatus) {
162
+ onStatus(obj.status);
163
+ }
164
+ }
165
+ catch (err) {
166
+ logger_1.logger.error("Failed to parse FSQL Generate response: ", err);
167
+ }
168
+ }
169
+ if (code) {
170
+ resolve(extractCodeBlock(code));
171
+ }
172
+ else {
173
+ resolve(fullText);
174
+ }
175
+ }
176
+ });
177
+ stream.on("error", (err) => {
178
+ reject(err);
179
+ });
37
180
  });
38
- return extractCodeBlock(res.body.output.messages[0].content);
39
181
  }
40
182
  function extractCodeBlock(text) {
41
183
  const regex = /```(?:[a-z]+\n)?([\s\S]*?)```/m;
42
- const match = text.match(regex);
184
+ const match = regex.exec(text);
43
185
  if (match && match[1]) {
44
186
  return match[1].trim();
45
187
  }
46
- throw new error_1.FirebaseError(`No code block found in the generated response: ${text}`);
188
+ if (!text.includes("{")) {
189
+ logger_1.logger.warn("[Agent Service] Response seems to be plain text, no GraphQL code block found.");
190
+ }
191
+ return text.trim();
47
192
  }
@@ -79,7 +79,6 @@ async function askQuestions(setup, config, options) {
79
79
  });
80
80
  if (wantToGenerate) {
81
81
  configstore_1.configstore.set("gemini", true);
82
- await (0, ensureApis_1.ensureGIFApiTos)(setup.projectId);
83
82
  info.appDescription = await (0, prompt_1.input)({
84
83
  message: `Describe your app idea:`,
85
84
  validate: async (s) => {
@@ -168,25 +167,59 @@ async function actuateWithInfo(setup, config, info, options) {
168
167
  return await writeFiles(config, info, templateServiceInfo, options);
169
168
  }
170
169
  const serviceAlreadyExists = !(await (0, client_1.createService)(projectId, info.locationId, info.serviceId));
171
- const schemaGql = await (0, utils_1.promiseWithSpinner)(() => (0, fdcExperience_1.generateSchema)(info.appDescription, projectId), "Generating the SQL Connect Schema...");
170
+ const schemaGql = await (0, utils_1.promiseWithSpinner)(() => (0, fdcExperience_1.generateSchema)(info.appDescription, projectId, info.locationId), "Generating the SQL Connect Schema...");
172
171
  const schemaFiles = [{ path: "schema.gql", content: schemaGql }];
173
172
  if (serviceAlreadyExists) {
174
173
  (0, utils_1.logLabeledError)("dataconnect", `SQL Connect Service ${serviceName} already exists. Skip saving them...`);
175
174
  info.flow += "_save_gemini_service_already_exists";
176
175
  return await writeFiles(config, info, { schemaGql: schemaFiles, connectors: [] }, options);
177
176
  }
177
+ const schemas = [
178
+ {
179
+ name: `${serviceName}/schemas/${types_1.MAIN_SCHEMA_ID}`,
180
+ datasources: [],
181
+ source: {
182
+ files: schemaFiles,
183
+ },
184
+ },
185
+ ];
186
+ let operationGql = "";
187
+ let seedDataGql = "";
188
+ let genOperationsSuccess = false;
189
+ let genOperationsError = null;
178
190
  await (0, utils_1.promiseWithSpinner)(async () => {
179
- const [saveSchemaGql, waitForCloudSQLProvision] = schemasDeploySequence(projectId, info, schemaFiles, info.shouldProvisionCSQL);
180
- await (0, client_1.upsertSchema)(saveSchemaGql);
181
- if (waitForCloudSQLProvision) {
182
- void (0, client_1.upsertSchema)(waitForCloudSQLProvision);
191
+ const deployPromise = (async () => {
192
+ const [saveSchemaGql, waitForCloudSQLProvision] = schemasDeploySequence(projectId, info, schemaFiles, info.shouldProvisionCSQL);
193
+ await (0, client_1.upsertSchema)(saveSchemaGql);
194
+ if (waitForCloudSQLProvision) {
195
+ void (0, client_1.upsertSchema)(waitForCloudSQLProvision);
196
+ }
197
+ })();
198
+ const opPromise = (async () => {
199
+ try {
200
+ const [op, seed] = await Promise.all([
201
+ (0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_CONNECTOR, serviceName, projectId, schemas),
202
+ (0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_SEED_DATA, serviceName, projectId, schemas),
203
+ ]);
204
+ return { op, seed, success: true };
205
+ }
206
+ catch (err) {
207
+ (0, utils_1.logLabeledError)("dataconnect", `Deployment failed: ${err instanceof Error ? err.message : String(err)}`);
208
+ return { success: false, error: err };
209
+ }
210
+ })();
211
+ const [, opResult] = await Promise.all([deployPromise, opPromise]);
212
+ if (opResult.success && opResult.op && opResult.seed) {
213
+ operationGql = opResult.op;
214
+ seedDataGql = opResult.seed;
215
+ genOperationsSuccess = true;
183
216
  }
184
- }, "Saving the SQL Connect Schema...");
185
- try {
186
- const [operationGql, seedDataGql] = await (0, utils_1.promiseWithSpinner)(() => Promise.all([
187
- (0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_CONNECTOR, serviceName, projectId),
188
- (0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_SEED_DATA, serviceName, projectId),
189
- ]), "Generating the SQL Connect Operations...");
217
+ else {
218
+ (0, utils_1.logLabeledError)("dataconnect", `Operation Generation failed...`);
219
+ genOperationsError = opResult.error;
220
+ }
221
+ }, "Saving the SQL Connect Schema and generating operations...");
222
+ if (genOperationsSuccess) {
190
223
  const connectors = [
191
224
  {
192
225
  id: "example",
@@ -202,11 +235,12 @@ async function actuateWithInfo(setup, config, info, options) {
202
235
  info.flow += "_save_gemini";
203
236
  await writeFiles(config, info, { schemaGql: schemaFiles, connectors: connectors, seedDataGql: seedDataGql }, options);
204
237
  }
205
- catch (err) {
206
- (0, utils_1.logLabeledError)("dataconnect", `Operation Generation failed...`);
238
+ else {
207
239
  info.flow += "_save_gemini_operation_error";
208
240
  await writeFiles(config, info, { schemaGql: schemaFiles, connectors: [] }, options);
209
- throw err;
241
+ }
242
+ if (genOperationsError) {
243
+ throw genOperationsError;
210
244
  }
211
245
  }
212
246
  function schemasDeploySequence(projectId, info, schemaFiles, linkToCloudSql) {