firebase-tools 15.14.0 → 15.15.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/lib/api.js +2 -6
- package/lib/command.js +23 -29
- package/lib/commands/dataconnect-compile.js +6 -6
- package/lib/commands/dataconnect-execute.js +1 -1
- package/lib/commands/dataconnect-sdk-generate.js +3 -3
- package/lib/commands/dataconnect-services-list.js +1 -1
- package/lib/commands/dataconnect-sql-diff.js +3 -3
- package/lib/commands/dataconnect-sql-grant.js +2 -2
- package/lib/commands/dataconnect-sql-migrate.js +4 -4
- package/lib/commands/dataconnect-sql-setup.js +2 -2
- package/lib/commands/dataconnect-sql-shell.js +4 -4
- package/lib/commands/ext-dev-usage.js +0 -2
- package/lib/commands/init.js +3 -3
- package/lib/commands/open.js +1 -1
- package/lib/commands/setup-emulators-dataconnect.js +1 -1
- package/lib/dataconnect/freeTrial.js +2 -2
- package/lib/dataconnect/load.js +2 -2
- package/lib/dataconnect/provisionCloudSql.js +3 -3
- package/lib/dataconnect/schemaMigration.js +11 -11
- package/lib/dataconnect/webhook.js +1 -1
- package/lib/deploy/functions/backend.js +1 -1
- package/lib/deploy/functions/build.js +3 -3
- package/lib/deploy/functions/deploy.js +5 -2
- package/lib/deploy/functions/prepare.js +53 -0
- package/lib/deploy/functions/release/fabricator.js +59 -46
- package/lib/deploy/functions/release/planner.js +1 -1
- package/lib/deploy/functions/runtimes/dart/index.js +3 -1
- package/lib/deploy/functions/runtimes/dart/triggerSupport.js +123 -0
- package/lib/deploy/functions/runtimes/index.js +1 -4
- package/lib/deploy/functions/services/ailogic.js +12 -1
- package/lib/deploy/functions/services/dataconnect.js +1 -1
- package/lib/emulator/constants.js +1 -1
- package/lib/emulator/controller.js +2 -2
- package/lib/emulator/dataconnectEmulator.js +14 -14
- package/lib/emulator/dataconnectToolkitController.js +2 -2
- package/lib/emulator/downloadableEmulatorInfo.json +31 -31
- package/lib/emulator/extensionsEmulator.js +1 -2
- package/lib/emulator/functionsEmulator.js +15 -0
- package/lib/emulator/hub.js +3 -3
- package/lib/emulator/hubExport.js +2 -2
- package/lib/emulator/initEmulators.js +1 -1
- package/lib/experiments.js +10 -5
- package/lib/gcp/ailogic.js +6 -3
- package/lib/gcp/runv2.js +9 -2
- package/lib/init/features/dataconnect/index.js +7 -7
- package/lib/init/features/dataconnect/resolver.js +2 -2
- package/lib/init/features/dataconnect/sdk.js +8 -8
- package/lib/init/features/functions/index.js +1 -1
- package/lib/mcp/index.js +0 -1
- package/lib/mcp/prompts/dataconnect/schema.js +6 -6
- package/lib/mcp/resources/guides/init_data_connect.js +2 -2
- package/lib/mcp/resources/guides/init_firestore.js +1 -1
- package/lib/mcp/tools/core/init.js +9 -9
- package/lib/mcp/tools/dataconnect/compile.js +5 -5
- package/lib/mcp/tools/dataconnect/execute.js +6 -6
- package/lib/mcp/tools/dataconnect/list_services.js +7 -7
- package/lib/mcp/util/dataconnect/content.js +19 -19
- package/lib/tsconfig.compile.tsbuildinfo +1 -1
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +16 -4
- package/templates/init/functions/dart/pubspec.yaml +6 -7
- package/templates/init/functions/dart/server.dart +3 -1
- package/lib/shortenUrl.js +0 -28
|
@@ -227,7 +227,7 @@ class HubExport {
|
|
|
227
227
|
});
|
|
228
228
|
const instance = registry_1.EmulatorRegistry.get(types_1.Emulators.DATACONNECT);
|
|
229
229
|
if (!instance) {
|
|
230
|
-
throw new error_1.FirebaseError("Unable to export
|
|
230
|
+
throw new error_1.FirebaseError("Unable to export SQL Connect emulator data: the SQL Connect emulator is not running.");
|
|
231
231
|
}
|
|
232
232
|
const dataconnectExportPath = path.join(this.tmpDir, metadata.dataconnect.path);
|
|
233
233
|
if (fs.existsSync(dataconnectExportPath)) {
|
|
@@ -251,7 +251,7 @@ function fetchToFile(options, path) {
|
|
|
251
251
|
}
|
|
252
252
|
function shouldExport(e) {
|
|
253
253
|
if (e === types_1.Emulators.DATACONNECT && (0, api_1.dataConnectLocalConnString)()) {
|
|
254
|
-
logger_1.logger.info("Skipping export for
|
|
254
|
+
logger_1.logger.info("Skipping export for SQL Connect because FIREBASE_DATACONNECT_POSTGRESQL_STRING is set.");
|
|
255
255
|
return false;
|
|
256
256
|
}
|
|
257
257
|
return types_1.IMPORT_EXPORT_EMULATORS.includes(e) && registry_1.EmulatorRegistry.isRunning(e);
|
|
@@ -60,7 +60,7 @@ exports.AdditionalInitFns = {
|
|
|
60
60
|
const additionalConfig = {};
|
|
61
61
|
const defaultDataConnectDir = config.get("dataconnect.source", "dataconnect");
|
|
62
62
|
const defaultDataDir = config.get("emulators.dataconnect.dataDir", `${defaultDataConnectDir}/.dataconnect/pgliteData`);
|
|
63
|
-
if (await (0, prompt_1.confirm)("Do you want to persist Postgres data from the
|
|
63
|
+
if (await (0, prompt_1.confirm)("Do you want to persist Postgres data from the SQL Connect emulator between runs? " +
|
|
64
64
|
`Data will be saved to ${defaultDataDir}. ` +
|
|
65
65
|
`You can change this directory by editing 'firebase.json#emulators.dataconnect.dataDir'.`)) {
|
|
66
66
|
additionalConfig["dataDir"] = defaultDataDir;
|
package/lib/experiments.js
CHANGED
|
@@ -74,6 +74,11 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
74
74
|
public: false,
|
|
75
75
|
default: false,
|
|
76
76
|
},
|
|
77
|
+
dartfunctions: {
|
|
78
|
+
shortDescription: "Enable Dart Functions.",
|
|
79
|
+
public: false,
|
|
80
|
+
default: false,
|
|
81
|
+
},
|
|
77
82
|
emulatoruisnapshot: {
|
|
78
83
|
shortDescription: "Load pre-release versions of the emulator UI",
|
|
79
84
|
},
|
|
@@ -127,8 +132,8 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
127
132
|
public: false,
|
|
128
133
|
},
|
|
129
134
|
dataconnect: {
|
|
130
|
-
shortDescription: "Deprecated. Previosuly, enabled
|
|
131
|
-
fullDescription: "Deprecated. Previously, enabled
|
|
135
|
+
shortDescription: "Deprecated. Previosuly, enabled SQL Connect related features.",
|
|
136
|
+
fullDescription: "Deprecated. Previously, enabled SQL Connect related features.",
|
|
132
137
|
public: false,
|
|
133
138
|
},
|
|
134
139
|
genkit: {
|
|
@@ -154,7 +159,7 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
154
159
|
public: true,
|
|
155
160
|
},
|
|
156
161
|
fdcift: {
|
|
157
|
-
shortDescription: "Enable instrumentless trial for
|
|
162
|
+
shortDescription: "Enable instrumentless trial for SQL Connect",
|
|
158
163
|
default: true,
|
|
159
164
|
public: false,
|
|
160
165
|
},
|
|
@@ -163,12 +168,12 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
163
168
|
public: true,
|
|
164
169
|
},
|
|
165
170
|
fdcwebhooks: {
|
|
166
|
-
shortDescription: "Enable Firebase
|
|
171
|
+
shortDescription: "Enable Firebase SQL Connect webhooks feature.",
|
|
167
172
|
default: true,
|
|
168
173
|
public: false,
|
|
169
174
|
},
|
|
170
175
|
fdcrealtime: {
|
|
171
|
-
shortDescription: "Enable Firebase
|
|
176
|
+
shortDescription: "Enable Firebase SQL Connect realtime feature.",
|
|
172
177
|
default: true,
|
|
173
178
|
public: false,
|
|
174
179
|
},
|
package/lib/gcp/ailogic.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.upsertBlockingFunction = upsertBlockingFunction;
|
|
|
10
10
|
exports.deleteBlockingFunction = deleteBlockingFunction;
|
|
11
11
|
const apiv2_1 = require("../apiv2");
|
|
12
12
|
const api_1 = require("../api");
|
|
13
|
+
const error_1 = require("../error");
|
|
13
14
|
exports.API_VERSION = "v1beta";
|
|
14
15
|
exports.AI_LOGIC_BEFORE_GENERATE_CONTENT = "google.firebase.ailogic.v1.beforeGenerate";
|
|
15
16
|
exports.AI_LOGIC_AFTER_GENERATE_CONTENT = "google.firebase.ailogic.v1.afterGenerate";
|
|
@@ -53,7 +54,7 @@ async function updateTrigger(projectId, location, triggerId, trigger, updateMask
|
|
|
53
54
|
const res = await exports.client.patch(name, trigger, { queryParams });
|
|
54
55
|
return res.body;
|
|
55
56
|
}
|
|
56
|
-
async function deleteTrigger(projectId, location, triggerId, allowMissing =
|
|
57
|
+
async function deleteTrigger(projectId, location, triggerId, allowMissing = true, validateOnly = false, etag) {
|
|
57
58
|
const name = `projects/${projectId}/locations/${location}/triggers/${triggerId}`;
|
|
58
59
|
const queryParams = {
|
|
59
60
|
allowMissing: allowMissing ? "true" : "false",
|
|
@@ -95,8 +96,10 @@ async function upsertBlockingFunction(endpoint) {
|
|
|
95
96
|
return await createTrigger(endpoint.project, location, triggerId, triggerBody);
|
|
96
97
|
}
|
|
97
98
|
catch (err) {
|
|
98
|
-
if (
|
|
99
|
-
return await updateTrigger(endpoint.project, location, triggerId, triggerBody
|
|
99
|
+
if ((0, error_1.getErrStatus)(err) === 409) {
|
|
100
|
+
return await updateTrigger(endpoint.project, location, triggerId, triggerBody, [
|
|
101
|
+
"cloudFunction",
|
|
102
|
+
]);
|
|
100
103
|
}
|
|
101
104
|
throw err;
|
|
102
105
|
}
|
package/lib/gcp/runv2.js
CHANGED
|
@@ -99,6 +99,7 @@ async function listServices(projectId) {
|
|
|
99
99
|
if (res.body.services) {
|
|
100
100
|
for (const service of res.body.services) {
|
|
101
101
|
if (service.labels?.[exports.CLIENT_NAME_LABEL] === "cloud-functions" ||
|
|
102
|
+
service.labels?.[exports.CLIENT_NAME_LABEL] === "cloudfunctions" ||
|
|
102
103
|
service.labels?.[exports.CLIENT_NAME_LABEL] === "firebase-functions") {
|
|
103
104
|
allServices.push(service);
|
|
104
105
|
}
|
|
@@ -134,10 +135,13 @@ function endpointFromService(service) {
|
|
|
134
135
|
}
|
|
135
136
|
const cpu = Number(service.template.containers[0].resources.limits.cpu);
|
|
136
137
|
const endpoint = {
|
|
137
|
-
platform: service.labels?.[exports.CLIENT_NAME_LABEL] === "cloud-functions"
|
|
138
|
+
platform: service.labels?.[exports.CLIENT_NAME_LABEL] === "cloud-functions" ||
|
|
139
|
+
service.labels?.[exports.CLIENT_NAME_LABEL] === "cloudfunctions"
|
|
140
|
+
? "gcfv2"
|
|
141
|
+
: "run",
|
|
138
142
|
id,
|
|
139
143
|
project,
|
|
140
|
-
labels: service.labels
|
|
144
|
+
labels: { ...service.labels, "deployment-tool": "cli-firebase" },
|
|
141
145
|
region: location,
|
|
142
146
|
runtime: service.labels?.[exports.RUNTIME_LABEL] || (0, supported_1.latest)("nodejs"),
|
|
143
147
|
availableMemoryMb: memory,
|
|
@@ -206,6 +210,9 @@ function serviceFromEndpoint(endpoint, image) {
|
|
|
206
210
|
}),
|
|
207
211
|
};
|
|
208
212
|
const template = {
|
|
213
|
+
annotations: {
|
|
214
|
+
"run.googleapis.com/client-name": "cli-firebase",
|
|
215
|
+
},
|
|
209
216
|
containers: [
|
|
210
217
|
{
|
|
211
218
|
name: "worker",
|
|
@@ -102,7 +102,7 @@ async function actuate(setup, config, options) {
|
|
|
102
102
|
config.set("emulators.dataconnect.dataDir", dataDir);
|
|
103
103
|
const info = setup.featureInfo?.dataconnect;
|
|
104
104
|
if (!info) {
|
|
105
|
-
throw new Error("
|
|
105
|
+
throw new Error("SQL Connect feature RequiredInfo is not provided");
|
|
106
106
|
}
|
|
107
107
|
info.serviceId = info.serviceId || defaultServiceId();
|
|
108
108
|
info.cloudSqlInstanceId = info.cloudSqlInstanceId || `${info.serviceId.toLowerCase()}-fdc`;
|
|
@@ -130,11 +130,11 @@ async function actuate(setup, config, options) {
|
|
|
130
130
|
}, Date.now() - startTime);
|
|
131
131
|
}
|
|
132
132
|
if (info.appDescription) {
|
|
133
|
-
setup.instructions.push(`You can visualize the
|
|
133
|
+
setup.instructions.push(`You can visualize the SQL Connect Schema in Firebase Console:
|
|
134
134
|
|
|
135
135
|
https://console.firebase.google.com/project/${setup.projectId}/dataconnect/locations/${info.locationId}/services/${info.serviceId}/schema`);
|
|
136
136
|
}
|
|
137
|
-
setup.instructions.push(`Install the
|
|
137
|
+
setup.instructions.push(`Install the SQL Connect VS Code Extensions. You can explore SQL Connect Query on local pgLite and Cloud SQL Postgres Instance.`);
|
|
138
138
|
}
|
|
139
139
|
async function actuateWithInfo(setup, config, info, options) {
|
|
140
140
|
const projectId = setup.projectId;
|
|
@@ -166,10 +166,10 @@ async function actuateWithInfo(setup, config, info, options) {
|
|
|
166
166
|
return await writeFiles(config, info, templateServiceInfo, options);
|
|
167
167
|
}
|
|
168
168
|
const serviceAlreadyExists = !(await (0, client_1.createService)(projectId, info.locationId, info.serviceId));
|
|
169
|
-
const schemaGql = await (0, utils_1.promiseWithSpinner)(() => (0, fdcExperience_1.generateSchema)(info.appDescription, projectId), "Generating the
|
|
169
|
+
const schemaGql = await (0, utils_1.promiseWithSpinner)(() => (0, fdcExperience_1.generateSchema)(info.appDescription, projectId), "Generating the SQL Connect Schema...");
|
|
170
170
|
const schemaFiles = [{ path: "schema.gql", content: schemaGql }];
|
|
171
171
|
if (serviceAlreadyExists) {
|
|
172
|
-
(0, utils_1.logLabeledError)("dataconnect", `
|
|
172
|
+
(0, utils_1.logLabeledError)("dataconnect", `SQL Connect Service ${serviceName} already exists. Skip saving them...`);
|
|
173
173
|
info.flow += "_save_gemini_service_already_exists";
|
|
174
174
|
return await writeFiles(config, info, { schemaGql: schemaFiles, connectors: [] }, options);
|
|
175
175
|
}
|
|
@@ -179,12 +179,12 @@ async function actuateWithInfo(setup, config, info, options) {
|
|
|
179
179
|
if (waitForCloudSQLProvision) {
|
|
180
180
|
void (0, client_1.upsertSchema)(waitForCloudSQLProvision);
|
|
181
181
|
}
|
|
182
|
-
}, "Saving the
|
|
182
|
+
}, "Saving the SQL Connect Schema...");
|
|
183
183
|
try {
|
|
184
184
|
const [operationGql, seedDataGql] = await (0, utils_1.promiseWithSpinner)(() => Promise.all([
|
|
185
185
|
(0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_CONNECTOR, serviceName, projectId),
|
|
186
186
|
(0, fdcExperience_1.generateOperation)(fdcExperience_1.PROMPT_GENERATE_SEED_DATA, serviceName, projectId),
|
|
187
|
-
]), "Generating the
|
|
187
|
+
]), "Generating the SQL Connect Operations...");
|
|
188
188
|
const connectors = [
|
|
189
189
|
{
|
|
190
190
|
id: "example",
|
|
@@ -25,7 +25,7 @@ async function askQuestions(setup, config, options) {
|
|
|
25
25
|
};
|
|
26
26
|
const serviceInfos = await (0, load_1.loadAll)(setup.projectId || "", config);
|
|
27
27
|
if (!serviceInfos.length) {
|
|
28
|
-
throw new Error(`No Firebase
|
|
28
|
+
throw new Error(`No Firebase SQL Connect workspace found. Run ${clc.bold("firebase init dataconnect")} to set up a service and main schema.`);
|
|
29
29
|
}
|
|
30
30
|
else if (serviceInfos.length === 1) {
|
|
31
31
|
resolverInfo.serviceInfo = serviceInfos[0];
|
|
@@ -69,7 +69,7 @@ async function actuate(setup, config) {
|
|
|
69
69
|
}
|
|
70
70
|
const resolverInfo = setup.featureInfo?.dataconnectResolver;
|
|
71
71
|
if (!resolverInfo) {
|
|
72
|
-
throw new Error("
|
|
72
|
+
throw new Error("SQL Connect resolver feature ResolverRequiredInfo not provided");
|
|
73
73
|
}
|
|
74
74
|
const startTime = Date.now();
|
|
75
75
|
try {
|
|
@@ -109,7 +109,7 @@ async function chooseApp() {
|
|
|
109
109
|
};
|
|
110
110
|
});
|
|
111
111
|
const pickedApps = await (0, prompt_1.checkbox)({
|
|
112
|
-
message: "Which apps do you want to set up
|
|
112
|
+
message: "Which apps do you want to set up SQL Connect SDKs in?",
|
|
113
113
|
choices,
|
|
114
114
|
validate: (choices) => {
|
|
115
115
|
if (choices.length === 0) {
|
|
@@ -128,7 +128,7 @@ async function chooseApp() {
|
|
|
128
128
|
async function actuate(setup, config) {
|
|
129
129
|
const sdkInfo = setup.featureInfo?.dataconnectSdk;
|
|
130
130
|
if (!sdkInfo) {
|
|
131
|
-
throw new Error("
|
|
131
|
+
throw new Error("SQL Connect SDK feature RequiredInfo is not provided");
|
|
132
132
|
}
|
|
133
133
|
const startTime = Date.now();
|
|
134
134
|
try {
|
|
@@ -183,7 +183,7 @@ async function actuateWithInfo(setup, config, info) {
|
|
|
183
183
|
if (!info.apps.length) {
|
|
184
184
|
info.apps = await (0, appUtils_1.detectApps)(cwd);
|
|
185
185
|
if (!info.apps.length) {
|
|
186
|
-
(0, utils_1.logLabeledBullet)("dataconnect", "No apps to setup
|
|
186
|
+
(0, utils_1.logLabeledBullet)("dataconnect", "No apps to setup SQL Connect Generated SDKs");
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
189
|
}
|
|
@@ -209,17 +209,17 @@ async function actuateWithInfo(setup, config, info) {
|
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
catch (e) {
|
|
212
|
-
(0, utils_1.logLabeledError)("dataconnect", `Failed to generate
|
|
212
|
+
(0, utils_1.logLabeledError)("dataconnect", `Failed to generate SQL Connect SDKs\n${e?.message}`);
|
|
213
213
|
}
|
|
214
214
|
(0, utils_1.logLabeledSuccess)("dataconnect", `Installed generated SDKs for ${clc.bold(apps.map((a) => (0, appUtils_1.appDescription)(a)).join(", "))}`);
|
|
215
215
|
if (apps.some((a) => a.platform === appUtils_1.Platform.IOS)) {
|
|
216
216
|
(0, utils_1.logBullet)(clc.bold("Please follow the instructions here to add your generated sdk to your XCode project:\n\thttps://firebase.google.com/docs/data-connect/ios-sdk#set-client"));
|
|
217
217
|
}
|
|
218
218
|
if (apps.some((a) => a.frameworks?.includes(appUtils_1.Framework.REACT))) {
|
|
219
|
-
(0, utils_1.logBullet)("Visit https://firebase.google.com/docs/data-connect/web-sdk#react for more information on how to set up React Generated SDKs for Firebase
|
|
219
|
+
(0, utils_1.logBullet)("Visit https://firebase.google.com/docs/data-connect/web-sdk#react for more information on how to set up React Generated SDKs for Firebase SQL Connect");
|
|
220
220
|
}
|
|
221
221
|
if (apps.some((a) => a.frameworks?.includes(appUtils_1.Framework.ANGULAR))) {
|
|
222
|
-
(0, utils_1.logBullet)("Run `ng add @angular/fire` to install angular sdk dependencies.\nVisit https://github.com/invertase/tanstack-query-firebase/tree/main/packages/angular for more information on how to set up Angular Generated SDKs for Firebase
|
|
222
|
+
(0, utils_1.logBullet)("Run `ng add @angular/fire` to install angular sdk dependencies.\nVisit https://github.com/invertase/tanstack-query-firebase/tree/main/packages/angular for more information on how to set up Angular Generated SDKs for Firebase SQL Connect");
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
async function chooseExistingConnector(setup, config) {
|
|
@@ -235,7 +235,7 @@ async function chooseExistingConnector(setup, config) {
|
|
|
235
235
|
})
|
|
236
236
|
.flat();
|
|
237
237
|
if (!choices.length) {
|
|
238
|
-
throw new error_1.FirebaseError(`No Firebase
|
|
238
|
+
throw new error_1.FirebaseError(`No Firebase SQL Connect workspace found. Run ${clc.bold("firebase init dataconnect")} to set up a service and connector.`);
|
|
239
239
|
}
|
|
240
240
|
if (choices.length === 1) {
|
|
241
241
|
return choices[0].value;
|
|
@@ -346,7 +346,7 @@ function addSdkGenerateToConnectorYaml(connectorInfo, connectorYaml, app) {
|
|
|
346
346
|
break;
|
|
347
347
|
}
|
|
348
348
|
default:
|
|
349
|
-
throw new error_1.FirebaseError(`Unsupported platform ${app.platform} for
|
|
349
|
+
throw new error_1.FirebaseError(`Unsupported platform ${app.platform} for SQL Connect SDK generation. Supported platforms are: ${Object.values(appUtils_1.Platform).join(", ")}\n${JSON.stringify(app)}`);
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
function dedupeAppsByPlatformAndDirectory(apps) {
|
package/lib/mcp/index.js
CHANGED
|
@@ -133,7 +133,6 @@ class FirebaseMcpServer {
|
|
|
133
133
|
if (this.detectedFeatures?.length)
|
|
134
134
|
return this.detectedFeatures;
|
|
135
135
|
this.logger.debug("detecting active features of Firebase MCP server...");
|
|
136
|
-
await this.detectProjectRoot();
|
|
137
136
|
const projectId = (await this.getProjectId()) || "";
|
|
138
137
|
const accountEmail = await this.getAuthenticatedUser();
|
|
139
138
|
const isBillingEnabled = projectId ? await this.safeCheckBillingEnabled(projectId) : false;
|
|
@@ -8,10 +8,10 @@ const content_1 = require("../../util/dataconnect/content");
|
|
|
8
8
|
const compile_1 = require("../../util/dataconnect/compile");
|
|
9
9
|
function renderServices(fdcServices) {
|
|
10
10
|
if (!fdcServices.length)
|
|
11
|
-
return "
|
|
12
|
-
return `\n\n##
|
|
11
|
+
return "SQL Connect Status: <UNCONFIGURED>";
|
|
12
|
+
return `\n\n## SQL Connect Schema
|
|
13
13
|
|
|
14
|
-
The following is the up-to-date content of existing schema files (their paths are relative to the
|
|
14
|
+
The following is the up-to-date content of existing schema files (their paths are relative to the SQL Connect source directory).
|
|
15
15
|
|
|
16
16
|
${(0, types_1.mainSchema)(fdcServices[0].schemas)
|
|
17
17
|
.source.files?.map((f) => `\`\`\`graphql ${f.path}\n${f.content}\n\`\`\``)
|
|
@@ -22,7 +22,7 @@ function renderErrors(errors) {
|
|
|
22
22
|
}
|
|
23
23
|
exports.schema = (0, prompt_1.prompt)("core", {
|
|
24
24
|
name: "schema",
|
|
25
|
-
description: "Generate or update your Firebase
|
|
25
|
+
description: "Generate or update your Firebase SQL Connect schema.",
|
|
26
26
|
arguments: [
|
|
27
27
|
{
|
|
28
28
|
name: "prompt",
|
|
@@ -31,7 +31,7 @@ exports.schema = (0, prompt_1.prompt)("core", {
|
|
|
31
31
|
},
|
|
32
32
|
],
|
|
33
33
|
annotations: {
|
|
34
|
-
title: "Generate
|
|
34
|
+
title: "Generate SQL Connect Schema",
|
|
35
35
|
},
|
|
36
36
|
}, async ({ prompt }, { config, projectId, accountEmail }) => {
|
|
37
37
|
const fdcServices = await (0, load_1.loadAll)(projectId, config);
|
|
@@ -58,7 +58,7 @@ ${prompt}
|
|
|
58
58
|
|
|
59
59
|
==== TASK INSTRUCTIONS ====
|
|
60
60
|
|
|
61
|
-
1. If
|
|
61
|
+
1. If SQL Connect is marked as \`<UNCONFIGURED>\`, first run the \`firebase_init\` tool with \`{dataconnect: {}}\` arguments to initialize it.
|
|
62
62
|
2. If there is not an existing schema to work with (or the existing schema is the commented-out default schema about a movie app), follow the user's prompt to generate a robust schema meeting the specified requirements.
|
|
63
63
|
3. If there is already a schema, perform edits to the existing schema file(s) based on the user's instructions. If schema build errors are present and seem relevant to your changes, attempt to fix them.
|
|
64
64
|
4. After you have performed edits on the schema, run the \`dataconnect_compile\` tool to build the schema and see if there are any errors. Fix errors that are related to the user's prompt or your changes.
|
|
@@ -5,8 +5,8 @@ const resource_1 = require("../../resource");
|
|
|
5
5
|
exports.init_data_connect = (0, resource_1.resource)({
|
|
6
6
|
uri: "firebase://guides/init/data_connect",
|
|
7
7
|
name: "data_connect_init_guide",
|
|
8
|
-
title: "Firebase
|
|
9
|
-
description: "guides the coding agent through configuring
|
|
8
|
+
title: "Firebase SQL Connect Init Guide",
|
|
9
|
+
description: "guides the coding agent through configuring SQL Connect for PostgreSQL access in the current project",
|
|
10
10
|
}, async (uri) => {
|
|
11
11
|
return {
|
|
12
12
|
contents: [
|
|
@@ -19,7 +19,7 @@ exports.init_firestore = (0, resource_1.resource)({
|
|
|
19
19
|
**Database Setup:**
|
|
20
20
|
- Configure Firestore as the application's primary database.
|
|
21
21
|
- Implement client-side CRUD using the Firebase SDK.
|
|
22
|
-
- Present the app's Firestore data model to the user. Do not confuse Firestore's document model (NoSQL) with Firebase
|
|
22
|
+
- Present the app's Firestore data model to the user. Do not confuse Firestore's document model (NoSQL) with Firebase SQL Connect's schema.
|
|
23
23
|
- Write the default \`firestore.rules\` file (see below) explain what they do, and obtain the user's confirmation before deploying.
|
|
24
24
|
- Run \`firebase deploy --only firestore\` to create the database automatically Do not ask the user to create it in the console.
|
|
25
25
|
- Use production environment directly (avoid emulator for initial setup)
|
|
@@ -13,7 +13,7 @@ const projects_1 = require("../../../management/projects");
|
|
|
13
13
|
const dataconnect_1 = require("../../../init/features/dataconnect");
|
|
14
14
|
exports.init = (0, tool_1.tool)("core", {
|
|
15
15
|
name: "init",
|
|
16
|
-
description: "Use this to initialize selected Firebase services in the workspace (Cloud Firestore database, Firebase
|
|
16
|
+
description: "Use this to initialize selected Firebase services in the workspace (Cloud Firestore database, Firebase SQL Connect, Firebase Realtime Database, Firebase AI Logic). All services are optional; specify only the products you want to set up. " +
|
|
17
17
|
"You can initialize new features into an existing project directory, but re-initializing an existing feature may overwrite configuration. " +
|
|
18
18
|
"To deploy the initialized features, run the `firebase deploy` command after `firebase_init` tool.",
|
|
19
19
|
inputSchema: zod_1.z.object({
|
|
@@ -62,32 +62,32 @@ exports.init = (0, tool_1.tool)("core", {
|
|
|
62
62
|
service_id: zod_1.z
|
|
63
63
|
.string()
|
|
64
64
|
.optional()
|
|
65
|
-
.describe("The Firebase
|
|
65
|
+
.describe("The Firebase SQL Connect service ID to initialize. Default to match the current folder name."),
|
|
66
66
|
location_id: zod_1.z
|
|
67
67
|
.string()
|
|
68
68
|
.optional()
|
|
69
69
|
.default(dataconnect_1.FDC_DEFAULT_REGION)
|
|
70
|
-
.describe("The GCP region ID to set up the Firebase
|
|
70
|
+
.describe("The GCP region ID to set up the Firebase SQL Connect service."),
|
|
71
71
|
cloudsql_instance_id: zod_1.z
|
|
72
72
|
.string()
|
|
73
73
|
.optional()
|
|
74
|
-
.describe("The GCP Cloud SQL instance ID to use in the Firebase
|
|
74
|
+
.describe("The GCP Cloud SQL instance ID to use in the Firebase SQL Connect service. By default, use <serviceId>-fdc. " +
|
|
75
75
|
"\nSet `provision_cloudsql` to true to start Cloud SQL provisioning."),
|
|
76
76
|
cloudsql_database: zod_1.z
|
|
77
77
|
.string()
|
|
78
78
|
.optional()
|
|
79
79
|
.default("fdcdb")
|
|
80
|
-
.describe("The Postgres database ID to use in the Firebase
|
|
80
|
+
.describe("The Postgres database ID to use in the Firebase SQL Connect service."),
|
|
81
81
|
provision_cloudsql: zod_1.z
|
|
82
82
|
.boolean()
|
|
83
83
|
.optional()
|
|
84
84
|
.default(false)
|
|
85
85
|
.describe("If true, provision the Cloud SQL instance if `cloudsql_instance_id` does not exist already. " +
|
|
86
|
-
`\nThe first Cloud SQL instance in the project will use the
|
|
86
|
+
`\nThe first Cloud SQL instance in the project will use the SQL Connect no-cost trial. See its terms of service: ${(0, freeTrial_1.freeTrialTermsLink)()}.`),
|
|
87
87
|
})
|
|
88
88
|
.optional()
|
|
89
|
-
.describe("Provide this object to initialize Firebase
|
|
90
|
-
"It installs
|
|
89
|
+
.describe("Provide this object to initialize Firebase SQL Connect with Cloud SQL Postgres in this project directory.\n" +
|
|
90
|
+
"It installs SQL Connect Generated SDKs in all detected apps in the folder."),
|
|
91
91
|
storage: zod_1.z
|
|
92
92
|
.object({
|
|
93
93
|
rules_filename: zod_1.z
|
|
@@ -245,7 +245,7 @@ exports.init = (0, tool_1.tool)("core", {
|
|
|
245
245
|
config.writeProjectFile("firebase.json", setup.config);
|
|
246
246
|
config.writeProjectFile(".firebaserc", setup.rcfile);
|
|
247
247
|
if (featureInfo.dataconnectSdk && !featureInfo.dataconnectSdk.apps.length) {
|
|
248
|
-
setup.instructions.push(`No app is found in the current folder. We recommend you create an app (web, ios, android) first, then re-run the 'firebase_init' MCP tool with the same input without app_description to add
|
|
248
|
+
setup.instructions.push(`No app is found in the current folder. We recommend you create an app (web, ios, android) first, then re-run the 'firebase_init' MCP tool with the same input without app_description to add SQL Connect SDKs to your apps.
|
|
249
249
|
Consider popular commands like 'npx create-react-app my-app', 'npx create-next-app my-app', 'flutter create my-app', etc`);
|
|
250
250
|
}
|
|
251
251
|
return (0, util_1.toContent)(`Successfully setup those features: ${featuresList.join(", ")}
|
|
@@ -7,7 +7,7 @@ const compile_1 = require("../../util/dataconnect/compile");
|
|
|
7
7
|
const load_1 = require("../../../dataconnect/load");
|
|
8
8
|
exports.compile = (0, tool_1.tool)("dataconnect", {
|
|
9
9
|
name: "build",
|
|
10
|
-
description: "Use this to compile Firebase
|
|
10
|
+
description: "Use this to compile Firebase SQL Connect schema, operations, and/or connectors and check for build errors.",
|
|
11
11
|
inputSchema: zod_1.z.object({
|
|
12
12
|
error_filter: zod_1.z
|
|
13
13
|
.enum(["all", "schema", "operations"])
|
|
@@ -16,14 +16,14 @@ exports.compile = (0, tool_1.tool)("dataconnect", {
|
|
|
16
16
|
service_id: zod_1.z
|
|
17
17
|
.string()
|
|
18
18
|
.optional()
|
|
19
|
-
.describe(`Service ID of the
|
|
19
|
+
.describe(`Service ID of the SQL Connect service to compile. Used to disambiguate when there are multiple SQL Connect services in firebase.json.`),
|
|
20
20
|
location_id: zod_1.z
|
|
21
21
|
.string()
|
|
22
22
|
.optional()
|
|
23
|
-
.describe(`
|
|
23
|
+
.describe(`SQL Connect Service location ID to disambiguate among multiple SQL Connect services.`),
|
|
24
24
|
}),
|
|
25
25
|
annotations: {
|
|
26
|
-
title: "Compile
|
|
26
|
+
title: "Compile SQL Connect",
|
|
27
27
|
readOnlyHint: true,
|
|
28
28
|
},
|
|
29
29
|
_meta: {
|
|
@@ -40,7 +40,7 @@ exports.compile = (0, tool_1.tool)("dataconnect", {
|
|
|
40
40
|
content: [
|
|
41
41
|
{
|
|
42
42
|
type: "text",
|
|
43
|
-
text: `The following errors were encountered while compiling
|
|
43
|
+
text: `The following errors were encountered while compiling SQL Connect:\n\n${errors.join("\n")}`,
|
|
44
44
|
},
|
|
45
45
|
],
|
|
46
46
|
isError: true,
|
|
@@ -9,20 +9,20 @@ const converter_1 = require("../../util/dataconnect/converter");
|
|
|
9
9
|
const emulator_1 = require("../../util/dataconnect/emulator");
|
|
10
10
|
exports.execute = (0, tool_1.tool)("dataconnect", {
|
|
11
11
|
name: "execute",
|
|
12
|
-
description: "Use this to execute a GraphQL operation against a
|
|
12
|
+
description: "Use this to execute a GraphQL operation against a SQL Connect service or its emulator.",
|
|
13
13
|
inputSchema: zod_1.z.object({
|
|
14
|
-
query: zod_1.z.string().describe(`A Firebase
|
|
14
|
+
query: zod_1.z.string().describe(`A Firebase SQL Connect GraphQL query or mutation to execute.
|
|
15
15
|
You can use the \`dataconnect_generate_operation\` tool to generate a query.
|
|
16
|
-
Example
|
|
16
|
+
Example SQL Connect schema and example queries can be found in files ending in \`.graphql\` or \`.gql\`.
|
|
17
17
|
`),
|
|
18
18
|
service_id: zod_1.z
|
|
19
19
|
.string()
|
|
20
20
|
.optional()
|
|
21
|
-
.describe(`Service ID of the
|
|
21
|
+
.describe(`Service ID of the SQL Connect service to compile. Used to disambiguate when there are multiple SQL Connect services in firebase.json.`),
|
|
22
22
|
location_id: zod_1.z
|
|
23
23
|
.string()
|
|
24
24
|
.optional()
|
|
25
|
-
.describe(`
|
|
25
|
+
.describe(`SQL Connect Service location ID to disambiguate among multiple SQL Connect services.`),
|
|
26
26
|
variables_json: zod_1.z
|
|
27
27
|
.string()
|
|
28
28
|
.optional()
|
|
@@ -39,7 +39,7 @@ Example Data Connect schema and example queries can be found in files ending in
|
|
|
39
39
|
.describe("If true, target the DataConnect emulator. Run `firebase emulators:start` to start it"),
|
|
40
40
|
}),
|
|
41
41
|
annotations: {
|
|
42
|
-
title: "Execute Firebase
|
|
42
|
+
title: "Execute Firebase SQL Connect Query",
|
|
43
43
|
},
|
|
44
44
|
_meta: {
|
|
45
45
|
requiresProject: true,
|
|
@@ -12,10 +12,10 @@ const js_yaml_1 = require("js-yaml");
|
|
|
12
12
|
const logger_1 = require("../../../logger");
|
|
13
13
|
exports.list_services = (0, tool_1.tool)("dataconnect", {
|
|
14
14
|
name: "list_services",
|
|
15
|
-
description: "Use this to list existing local and backend Firebase
|
|
15
|
+
description: "Use this to list existing local and backend Firebase SQL Connect services",
|
|
16
16
|
inputSchema: zod_1.z.object({}),
|
|
17
17
|
annotations: {
|
|
18
|
-
title: "List existing Firebase
|
|
18
|
+
title: "List existing Firebase SQL Connect services",
|
|
19
19
|
readOnlyHint: true,
|
|
20
20
|
},
|
|
21
21
|
_meta: {
|
|
@@ -84,7 +84,7 @@ exports.list_services = (0, tool_1.tool)("dataconnect", {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
if (localServices.length) {
|
|
87
|
-
output.push(`# Local
|
|
87
|
+
output.push(`# Local SQL Connect Sources`);
|
|
88
88
|
for (const s of localServices) {
|
|
89
89
|
const local = s.local;
|
|
90
90
|
output.push((0, js_yaml_1.dump)(local.dataConnectYaml));
|
|
@@ -97,7 +97,7 @@ exports.list_services = (0, tool_1.tool)("dataconnect", {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
if (remoteOnlyServices.length) {
|
|
100
|
-
output.push(`#
|
|
100
|
+
output.push(`# SQL Connect Services in project ${projectId}`);
|
|
101
101
|
for (const s of remoteOnlyServices) {
|
|
102
102
|
if (s.deployed) {
|
|
103
103
|
includeDeployedServiceInfo(s.deployed);
|
|
@@ -106,10 +106,10 @@ exports.list_services = (0, tool_1.tool)("dataconnect", {
|
|
|
106
106
|
}
|
|
107
107
|
output.push(`\n# What's next?`);
|
|
108
108
|
if (!localServices.length) {
|
|
109
|
-
output.push(`- There is no local
|
|
109
|
+
output.push(`- There is no local SQL Connect service in the local workspace. Consider use the \`firebase_init\` MCP tool to setup one.`);
|
|
110
110
|
}
|
|
111
|
-
output.push(`- You can use the \`dataconnect_compile\` tool to compile all local
|
|
112
|
-
output.push(`- You run \`firebase deploy\` in command line to deploy the
|
|
111
|
+
output.push(`- You can use the \`dataconnect_compile\` tool to compile all local SQL Connect schemas and query sources.`);
|
|
112
|
+
output.push(`- You run \`firebase deploy\` in command line to deploy the SQL Connect schemas, connector and perform SQL migrations.`);
|
|
113
113
|
return (0, util_1.toContent)(output.join("\n"));
|
|
114
114
|
});
|
|
115
115
|
function clearCCFEFields(r) {
|