firebase-tools 15.11.0 → 15.12.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/agentSkills.js +70 -0
- package/lib/api.js +3 -1
- package/lib/apphosting/backend.js +22 -3
- package/lib/bin/mcp.js +5 -1
- package/lib/commands/apphosting-backends-create.js +19 -2
- package/lib/commands/apphosting-backends-list.js +21 -5
- package/lib/commands/functions-delete.js +1 -0
- package/lib/commands/functions-export.js +40 -0
- package/lib/commands/index.js +3 -0
- package/lib/commands/init.js +1 -0
- package/lib/deploy/apphosting/deploy.js +11 -6
- package/lib/deploy/apphosting/prepare.js +21 -1
- package/lib/deploy/apphosting/release.js +2 -5
- package/lib/deploy/apphosting/util.js +45 -2
- package/lib/deploy/functions/prepare.js +4 -1
- package/lib/deploy/functions/release/fabricator.js +4 -3
- package/lib/deploy/functions/release/index.js +5 -0
- package/lib/deploy/functions/services/ailogic.js +68 -0
- package/lib/deploy/functions/services/index.js +4 -0
- package/lib/emulator/downloadableEmulatorInfo.json +24 -24
- package/lib/emulator/storage/rules/manager.js +10 -3
- package/lib/emulator/storage/rules/runtime.js +9 -7
- package/lib/experiments.js +22 -0
- package/lib/firebase_studio/migrate.js +30 -61
- package/lib/functions/iac/export.js +36 -0
- package/lib/functions/iac/terraform.js +146 -0
- package/lib/gcp/ailogic.js +108 -0
- package/lib/gcp/cloudfunctionsv2.js +24 -0
- package/lib/init/features/agentSkills.js +26 -0
- package/lib/init/features/dataconnect/sdk.js +26 -12
- package/lib/init/features/index.js +4 -1
- package/lib/init/index.js +6 -0
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/lib/utils.js +8 -0
- package/package.json +5 -3
- package/standalone/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expr = expr;
|
|
4
|
+
exports.copyField = copyField;
|
|
5
|
+
exports.renameField = renameField;
|
|
6
|
+
exports.serviceAccount = serviceAccount;
|
|
7
|
+
exports.serializeValue = serializeValue;
|
|
8
|
+
exports.blockToString = blockToString;
|
|
9
|
+
const utils = require("../../utils");
|
|
10
|
+
const error_1 = require("../../error");
|
|
11
|
+
function expr(string) {
|
|
12
|
+
return { "@type": "HCLExpression", value: string };
|
|
13
|
+
}
|
|
14
|
+
function copyField(attributes, source, field, transform = (v) => v) {
|
|
15
|
+
renameField(attributes, source, utils.toLowerSnakeCase(field), field, transform);
|
|
16
|
+
}
|
|
17
|
+
function renameField(attributes, source, attributeField, sourceField, transform = (v) => v) {
|
|
18
|
+
const val = source[sourceField];
|
|
19
|
+
if (val === undefined) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
attributes[attributeField] = val === null ? null : transform(val);
|
|
23
|
+
}
|
|
24
|
+
function serviceAccount(sa) {
|
|
25
|
+
if (sa.endsWith("@")) {
|
|
26
|
+
return `${sa}\${var.project}.iam.gserviceaccount.com`;
|
|
27
|
+
}
|
|
28
|
+
return sa;
|
|
29
|
+
}
|
|
30
|
+
function serializeValue(value, indentation = 0) {
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
value = value.replace(/{{ *params\.PROJECT_ID *}}/g, "${var.project}");
|
|
33
|
+
if (value.includes("{{ ")) {
|
|
34
|
+
throw new error_1.FirebaseError("Generalized parameterized fields are not supported in terraform yet");
|
|
35
|
+
}
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
}
|
|
38
|
+
else if (typeof value === "number" || typeof value === "boolean") {
|
|
39
|
+
return value.toString();
|
|
40
|
+
}
|
|
41
|
+
else if (value === null || value === undefined) {
|
|
42
|
+
return "null";
|
|
43
|
+
}
|
|
44
|
+
else if (Array.isArray(value)) {
|
|
45
|
+
if (value.some((e) => e !== null &&
|
|
46
|
+
typeof e === "object" &&
|
|
47
|
+
(Array.isArray(e) || e["@type"] !== "HCLExpression"))) {
|
|
48
|
+
return `[\n${value.map((v) => " ".repeat(indentation + 1) + serializeValue(v, indentation + 1)).join(",\n")}\n${" ".repeat(indentation)}]`;
|
|
49
|
+
}
|
|
50
|
+
return `[${value.map((v) => serializeValue(v)).join(", ")}]`;
|
|
51
|
+
}
|
|
52
|
+
else if (typeof value === "object") {
|
|
53
|
+
if (value["@type"] === "HCLExpression") {
|
|
54
|
+
return value.value;
|
|
55
|
+
}
|
|
56
|
+
const entries = Object.entries(value).map(([k, v]) => `${" ".repeat(indentation + 1)}${k} = ${serializeValue(v, indentation + 1)}`);
|
|
57
|
+
return `{\n${entries.join("\n")}\n${" ".repeat(indentation)}}`;
|
|
58
|
+
}
|
|
59
|
+
throw new error_1.FirebaseError(`Unsupported terraform value type ${typeof value}`, { exit: 1 });
|
|
60
|
+
}
|
|
61
|
+
const PREFIX_ARGUMENTS = new Set(["count", "for_each", "provider"]);
|
|
62
|
+
const SUFFIX_ARGUMENTS = new Set(["lifecycle", "depends_on"]);
|
|
63
|
+
const NON_BLOCK_PARAMETERS = {
|
|
64
|
+
google_cloudfunctions_function: new Set([
|
|
65
|
+
"name",
|
|
66
|
+
"runtime",
|
|
67
|
+
"description",
|
|
68
|
+
"available_memory_mb",
|
|
69
|
+
"timeout",
|
|
70
|
+
"entry_point",
|
|
71
|
+
"source_archive_bucket",
|
|
72
|
+
"source_archive_object",
|
|
73
|
+
"trigger_http",
|
|
74
|
+
"environment_variables",
|
|
75
|
+
"vpc_connector",
|
|
76
|
+
"service_account_email",
|
|
77
|
+
"max_instances",
|
|
78
|
+
"min_instances",
|
|
79
|
+
"project",
|
|
80
|
+
"region",
|
|
81
|
+
]),
|
|
82
|
+
google_cloudfunctions2_function: new Set(["name", "location", "description", "project"]),
|
|
83
|
+
google_cloud_scheduler_job: new Set([
|
|
84
|
+
"name",
|
|
85
|
+
"description",
|
|
86
|
+
"schedule",
|
|
87
|
+
"time_zone",
|
|
88
|
+
"paused",
|
|
89
|
+
"attempt_deadline",
|
|
90
|
+
"region",
|
|
91
|
+
"project",
|
|
92
|
+
]),
|
|
93
|
+
google_cloud_tasks_queue: new Set(["name", "location", "desired_state", "project"]),
|
|
94
|
+
google_eventarc_trigger: new Set(["name", "location", "project", "service_account"]),
|
|
95
|
+
google_pubsub_topic: new Set([
|
|
96
|
+
"name",
|
|
97
|
+
"project",
|
|
98
|
+
"labels",
|
|
99
|
+
"kms_key_name",
|
|
100
|
+
"message_retention_duration",
|
|
101
|
+
]),
|
|
102
|
+
google_pubsub_subscription: new Set([
|
|
103
|
+
"name",
|
|
104
|
+
"topic",
|
|
105
|
+
"project",
|
|
106
|
+
"labels",
|
|
107
|
+
"ack_deadline_seconds",
|
|
108
|
+
"message_retention_duration",
|
|
109
|
+
"retain_acked_messages",
|
|
110
|
+
"enable_message_ordering",
|
|
111
|
+
"filter",
|
|
112
|
+
]),
|
|
113
|
+
};
|
|
114
|
+
function serializeResourceAttributes(attributes, resourceType, indentation = 0) {
|
|
115
|
+
const nonBlockParams = NON_BLOCK_PARAMETERS[resourceType] || new Set();
|
|
116
|
+
const prefixGroup = [];
|
|
117
|
+
const nonBlockGroup = [];
|
|
118
|
+
const blockGroup = [];
|
|
119
|
+
const suffixGroup = [];
|
|
120
|
+
for (const [k, v] of Object.entries(attributes)) {
|
|
121
|
+
const serialized = `${" ".repeat(indentation + 1)}${k} = ${serializeValue(v, indentation + 1)}`;
|
|
122
|
+
if (PREFIX_ARGUMENTS.has(k)) {
|
|
123
|
+
prefixGroup.push(serialized);
|
|
124
|
+
}
|
|
125
|
+
else if (nonBlockParams.has(k)) {
|
|
126
|
+
nonBlockGroup.push(serialized);
|
|
127
|
+
}
|
|
128
|
+
else if (SUFFIX_ARGUMENTS.has(k)) {
|
|
129
|
+
suffixGroup.push(serialized);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
blockGroup.push(serialized);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const nonemptyGroups = [prefixGroup, nonBlockGroup, blockGroup, suffixGroup].filter((g) => g.length > 0);
|
|
136
|
+
const joinedGroups = nonemptyGroups.map((g) => g.join("\n")).join("\n\n");
|
|
137
|
+
return `{\n${joinedGroups}\n${" ".repeat(indentation)}}`;
|
|
138
|
+
}
|
|
139
|
+
function blockToString(block, indentation = 0) {
|
|
140
|
+
const labels = (block.labels || []).map((l) => `"${l}"`).join(" ");
|
|
141
|
+
if (block.type === "resource" && block.labels?.length) {
|
|
142
|
+
const resourceType = block.labels[0];
|
|
143
|
+
return `${" ".repeat(indentation)}${block.type} ${labels ? labels + " " : ""}${serializeResourceAttributes(block.attributes, resourceType, indentation)}`;
|
|
144
|
+
}
|
|
145
|
+
return `${" ".repeat(indentation)}${block.type} ${labels ? labels + " " : ""}${serializeValue(block.attributes, indentation)}`;
|
|
146
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.client = exports.AI_LOGIC_TRIGGERS_TO_EVENTS = exports.AI_LOGIC_EVENTS_TO_TRIGGER = exports.API_VERSION = void 0;
|
|
4
|
+
exports.createTrigger = createTrigger;
|
|
5
|
+
exports.getTrigger = getTrigger;
|
|
6
|
+
exports.updateTrigger = updateTrigger;
|
|
7
|
+
exports.deleteTrigger = deleteTrigger;
|
|
8
|
+
exports.listTriggers = listTriggers;
|
|
9
|
+
exports.upsertBlockingFunction = upsertBlockingFunction;
|
|
10
|
+
exports.deleteBlockingFunction = deleteBlockingFunction;
|
|
11
|
+
const apiv2_1 = require("../apiv2");
|
|
12
|
+
const api_1 = require("../api");
|
|
13
|
+
const ailogic_1 = require("../deploy/functions/services/ailogic");
|
|
14
|
+
exports.API_VERSION = "v1beta";
|
|
15
|
+
exports.AI_LOGIC_EVENTS_TO_TRIGGER = {
|
|
16
|
+
[ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT]: "before-generate-content",
|
|
17
|
+
[ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT]: "after-generate-content",
|
|
18
|
+
};
|
|
19
|
+
exports.AI_LOGIC_TRIGGERS_TO_EVENTS = {
|
|
20
|
+
"before-generate-content": ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT,
|
|
21
|
+
"after-generate-content": ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT,
|
|
22
|
+
};
|
|
23
|
+
exports.client = new apiv2_1.Client({
|
|
24
|
+
urlPrefix: (0, api_1.aiLogicProxyOrigin)(),
|
|
25
|
+
auth: true,
|
|
26
|
+
apiVersion: exports.API_VERSION,
|
|
27
|
+
});
|
|
28
|
+
async function createTrigger(projectId, location, triggerId, trigger, validateOnly = false) {
|
|
29
|
+
const parent = `projects/${projectId}/locations/${location}`;
|
|
30
|
+
const res = await exports.client.post(`${parent}/triggers`, trigger, {
|
|
31
|
+
queryParams: {
|
|
32
|
+
triggerId,
|
|
33
|
+
validateOnly: validateOnly ? "true" : "false",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return res.body;
|
|
37
|
+
}
|
|
38
|
+
async function getTrigger(projectId, location, triggerId) {
|
|
39
|
+
const name = `projects/${projectId}/locations/${location}/triggers/${triggerId}`;
|
|
40
|
+
const res = await exports.client.get(name);
|
|
41
|
+
return res.body;
|
|
42
|
+
}
|
|
43
|
+
async function updateTrigger(projectId, location, triggerId, trigger, updateMask, allowMissing = false, validateOnly = false) {
|
|
44
|
+
const name = `projects/${projectId}/locations/${location}/triggers/${triggerId}`;
|
|
45
|
+
const queryParams = {
|
|
46
|
+
allowMissing: allowMissing ? "true" : "false",
|
|
47
|
+
validateOnly: validateOnly ? "true" : "false",
|
|
48
|
+
};
|
|
49
|
+
if (updateMask && updateMask.length > 0) {
|
|
50
|
+
queryParams.updateMask = updateMask.join(",");
|
|
51
|
+
}
|
|
52
|
+
const res = await exports.client.patch(name, trigger, { queryParams });
|
|
53
|
+
return res.body;
|
|
54
|
+
}
|
|
55
|
+
async function deleteTrigger(projectId, location, triggerId, allowMissing = false, validateOnly = false, etag) {
|
|
56
|
+
const name = `projects/${projectId}/locations/${location}/triggers/${triggerId}`;
|
|
57
|
+
const queryParams = {
|
|
58
|
+
allowMissing: allowMissing ? "true" : "false",
|
|
59
|
+
validateOnly: validateOnly ? "true" : "false",
|
|
60
|
+
};
|
|
61
|
+
if (etag) {
|
|
62
|
+
queryParams.etag = etag;
|
|
63
|
+
}
|
|
64
|
+
await exports.client.delete(name, { queryParams });
|
|
65
|
+
}
|
|
66
|
+
async function listTriggers(projectId, location, filter) {
|
|
67
|
+
const parent = `projects/${projectId}/locations/${location}`;
|
|
68
|
+
let pageToken;
|
|
69
|
+
const triggers = [];
|
|
70
|
+
do {
|
|
71
|
+
const queryParams = pageToken ? { pageToken } : {};
|
|
72
|
+
if (filter) {
|
|
73
|
+
queryParams.filter = filter;
|
|
74
|
+
}
|
|
75
|
+
const res = await exports.client.get(`${parent}/triggers`, { queryParams });
|
|
76
|
+
if (res.body.triggers) {
|
|
77
|
+
triggers.push(...res.body.triggers);
|
|
78
|
+
}
|
|
79
|
+
pageToken = res.body.nextPageToken;
|
|
80
|
+
} while (pageToken);
|
|
81
|
+
return triggers;
|
|
82
|
+
}
|
|
83
|
+
async function upsertBlockingFunction(endpoint) {
|
|
84
|
+
const eventType = endpoint.blockingTrigger.eventType;
|
|
85
|
+
const triggerId = exports.AI_LOGIC_EVENTS_TO_TRIGGER[eventType];
|
|
86
|
+
const location = endpoint.blockingTrigger.options?.regionalWebhook ? endpoint.region : "global";
|
|
87
|
+
const triggerBody = {
|
|
88
|
+
cloudFunction: {
|
|
89
|
+
id: endpoint.id,
|
|
90
|
+
locationId: endpoint.region,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
try {
|
|
94
|
+
return await createTrigger(endpoint.project, location, triggerId, triggerBody);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (err && typeof err === "object" && "status" in err && err.status === 409) {
|
|
98
|
+
return await updateTrigger(endpoint.project, location, triggerId, triggerBody);
|
|
99
|
+
}
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function deleteBlockingFunction(endpoint) {
|
|
104
|
+
const eventType = endpoint.blockingTrigger.eventType;
|
|
105
|
+
const triggerId = exports.AI_LOGIC_EVENTS_TO_TRIGGER[eventType];
|
|
106
|
+
const location = endpoint.blockingTrigger.options?.regionalWebhook ? endpoint.region : "global";
|
|
107
|
+
await deleteTrigger(endpoint.project, location, triggerId, true);
|
|
108
|
+
}
|
|
@@ -21,6 +21,8 @@ const utils = require("../utils");
|
|
|
21
21
|
const projectConfig = require("../functions/projectConfig");
|
|
22
22
|
const constants_1 = require("../functions/constants");
|
|
23
23
|
const cloudfunctions_1 = require("./cloudfunctions");
|
|
24
|
+
const ailogic_1 = require("./ailogic");
|
|
25
|
+
const ailogic_2 = require("../deploy/functions/services/ailogic");
|
|
24
26
|
const k8s_1 = require("./k8s");
|
|
25
27
|
exports.API_VERSION = "v2";
|
|
26
28
|
const DEFAULT_MAX_INSTANCE_COUNT = 100;
|
|
@@ -263,6 +265,13 @@ function functionFromEndpoint(endpoint) {
|
|
|
263
265
|
else if (backend.isDataConnectGraphqlTriggered(endpoint)) {
|
|
264
266
|
gcfFunction.labels = { ...gcfFunction.labels, "deployment-fdcgraphql": "true" };
|
|
265
267
|
}
|
|
268
|
+
else if ((0, ailogic_2.isAILogicEvent)(endpoint)) {
|
|
269
|
+
gcfFunction.labels = {
|
|
270
|
+
...gcfFunction.labels,
|
|
271
|
+
"ailogic-event-type": ailogic_1.AI_LOGIC_EVENTS_TO_TRIGGER[endpoint.blockingTrigger.eventType],
|
|
272
|
+
"ailogic-locality": endpoint.blockingTrigger.options?.regionalWebhook ? "regional" : "global",
|
|
273
|
+
};
|
|
274
|
+
}
|
|
266
275
|
else if (backend.isBlockingTriggered(endpoint)) {
|
|
267
276
|
gcfFunction.labels = {
|
|
268
277
|
...gcfFunction.labels,
|
|
@@ -310,6 +319,21 @@ function endpointFromFunction(gcfFunction) {
|
|
|
310
319
|
dataConnectGraphqlTrigger: {},
|
|
311
320
|
};
|
|
312
321
|
}
|
|
322
|
+
else if (gcfFunction.labels?.["ailogic-event-type"]) {
|
|
323
|
+
const triggerType = gcfFunction.labels["ailogic-event-type"];
|
|
324
|
+
const eventType = ailogic_1.AI_LOGIC_TRIGGERS_TO_EVENTS[triggerType];
|
|
325
|
+
if (!eventType) {
|
|
326
|
+
throw new error_1.FirebaseError(`Unrecognized ailogic-event-type label: ${triggerType}`);
|
|
327
|
+
}
|
|
328
|
+
trigger = {
|
|
329
|
+
blockingTrigger: {
|
|
330
|
+
eventType,
|
|
331
|
+
options: {
|
|
332
|
+
regionalWebhook: gcfFunction.labels["ailogic-locality"] === "regional",
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
}
|
|
313
337
|
else if (gcfFunction.labels?.[constants_1.BLOCKING_LABEL]) {
|
|
314
338
|
trigger = {
|
|
315
339
|
blockingTrigger: {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.askQuestions = askQuestions;
|
|
4
|
+
exports.actuate = actuate;
|
|
5
|
+
const agentSkills_1 = require("../../agentSkills");
|
|
6
|
+
const logger_1 = require("../../logger");
|
|
7
|
+
const error_1 = require("../../error");
|
|
8
|
+
async function askQuestions(setup) {
|
|
9
|
+
try {
|
|
10
|
+
logger_1.logger.info("If you are using an AI coding agent, Firebase Agent Skills make it an expert at Firebase.");
|
|
11
|
+
const shouldInstall = await (0, agentSkills_1.promptForAgentSkills)();
|
|
12
|
+
setup.featureInfo = setup.featureInfo || {};
|
|
13
|
+
setup.featureInfo.agentSkills = { shouldInstall };
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
logger_1.logger.debug(`Could not prompt for agent skills: ${(0, error_1.getErrMsg)(err)}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function actuate(setup, config) {
|
|
20
|
+
const info = setup.featureInfo?.agentSkills;
|
|
21
|
+
if (!info || !info.shouldInstall) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const cwd = config.projectDir;
|
|
25
|
+
void (0, agentSkills_1.installAgentSkills)({ background: true, cwd });
|
|
26
|
+
}
|
|
@@ -12,6 +12,7 @@ const path = require("path");
|
|
|
12
12
|
const cwd = process.cwd();
|
|
13
13
|
const prompt_1 = require("../../../prompt");
|
|
14
14
|
const load_1 = require("../../../dataconnect/load");
|
|
15
|
+
const experiments = require("../../../experiments");
|
|
15
16
|
const error_1 = require("../../../error");
|
|
16
17
|
const lodash_1 = require("lodash");
|
|
17
18
|
const utils_1 = require("../../../utils");
|
|
@@ -275,19 +276,20 @@ function addSdkGenerateToConnectorYaml(connectorInfo, connectorYaml, app) {
|
|
|
275
276
|
}
|
|
276
277
|
case appUtils_1.Platform.WEB: {
|
|
277
278
|
const javascriptSdk = {
|
|
278
|
-
outputDir: path.relative(connectorDir, path.join(
|
|
279
|
-
package:
|
|
280
|
-
packageJsonDir: path.relative(connectorDir,
|
|
281
|
-
react: false,
|
|
282
|
-
angular: false,
|
|
279
|
+
outputDir: path.relative(connectorDir, path.join(app.directory, "src/dataconnect-generated")),
|
|
280
|
+
package: "@dataconnect/generated",
|
|
281
|
+
packageJsonDir: path.relative(connectorDir, app.directory),
|
|
282
|
+
react: app.frameworks?.includes(appUtils_1.Framework.REACT) ?? false,
|
|
283
|
+
angular: app.frameworks?.includes(appUtils_1.Framework.ANGULAR) ?? false,
|
|
283
284
|
};
|
|
284
|
-
|
|
285
|
-
javascriptSdk
|
|
285
|
+
if (experiments.isEnabled("fdcrealtime")) {
|
|
286
|
+
javascriptSdk.clientCache = {};
|
|
286
287
|
}
|
|
287
288
|
if (!(0, lodash_1.isArray)(generate?.javascriptSdk)) {
|
|
288
289
|
generate.javascriptSdk = generate.javascriptSdk ? [generate.javascriptSdk] : [];
|
|
289
290
|
}
|
|
290
|
-
|
|
291
|
+
const existing = generate.javascriptSdk.find((s) => s.outputDir === javascriptSdk.outputDir);
|
|
292
|
+
if (!existing) {
|
|
291
293
|
generate.javascriptSdk.push(javascriptSdk);
|
|
292
294
|
}
|
|
293
295
|
break;
|
|
@@ -297,23 +299,31 @@ function addSdkGenerateToConnectorYaml(connectorInfo, connectorYaml, app) {
|
|
|
297
299
|
outputDir: path.relative(connectorDir, path.join(appDir, `lib/dataconnect_generated`)),
|
|
298
300
|
package: "dataconnect_generated/generated.dart",
|
|
299
301
|
};
|
|
302
|
+
if (experiments.isEnabled("fdcrealtime")) {
|
|
303
|
+
dartSdk.clientCache = {};
|
|
304
|
+
}
|
|
300
305
|
if (!(0, lodash_1.isArray)(generate?.dartSdk)) {
|
|
301
306
|
generate.dartSdk = generate.dartSdk ? [generate.dartSdk] : [];
|
|
302
307
|
}
|
|
303
|
-
|
|
308
|
+
const existing = generate.dartSdk.find((s) => s.outputDir === dartSdk.outputDir);
|
|
309
|
+
if (!existing) {
|
|
304
310
|
generate.dartSdk.push(dartSdk);
|
|
305
311
|
}
|
|
306
312
|
break;
|
|
307
313
|
}
|
|
308
314
|
case appUtils_1.Platform.ANDROID: {
|
|
309
315
|
const kotlinSdk = {
|
|
310
|
-
outputDir: path.relative(connectorDir, path.join(
|
|
316
|
+
outputDir: path.relative(connectorDir, path.join(app.directory, "src/main/kotlin")),
|
|
311
317
|
package: `com.google.firebase.dataconnect.generated`,
|
|
312
318
|
};
|
|
319
|
+
if (experiments.isEnabled("fdcrealtime")) {
|
|
320
|
+
kotlinSdk.clientCache = {};
|
|
321
|
+
}
|
|
313
322
|
if (!(0, lodash_1.isArray)(generate?.kotlinSdk)) {
|
|
314
323
|
generate.kotlinSdk = generate.kotlinSdk ? [generate.kotlinSdk] : [];
|
|
315
324
|
}
|
|
316
|
-
|
|
325
|
+
const existing = generate.kotlinSdk.find((s) => s.outputDir === kotlinSdk.outputDir);
|
|
326
|
+
if (!existing) {
|
|
317
327
|
generate.kotlinSdk.push(kotlinSdk);
|
|
318
328
|
}
|
|
319
329
|
break;
|
|
@@ -323,10 +333,14 @@ function addSdkGenerateToConnectorYaml(connectorInfo, connectorYaml, app) {
|
|
|
323
333
|
outputDir: path.relative(connectorDir, path.join(app.directory, `../FirebaseDataConnectGenerated`)),
|
|
324
334
|
package: "DataConnectGenerated",
|
|
325
335
|
};
|
|
336
|
+
if (experiments.isEnabled("fdcrealtime")) {
|
|
337
|
+
swiftSdk.clientCache = {};
|
|
338
|
+
}
|
|
326
339
|
if (!(0, lodash_1.isArray)(generate?.swiftSdk)) {
|
|
327
340
|
generate.swiftSdk = generate.swiftSdk ? [generate.swiftSdk] : [];
|
|
328
341
|
}
|
|
329
|
-
|
|
342
|
+
const existing = generate.swiftSdk.find((s) => s.outputDir === swiftSdk.outputDir);
|
|
343
|
+
if (!existing) {
|
|
330
344
|
generate.swiftSdk.push(swiftSdk);
|
|
331
345
|
}
|
|
332
346
|
break;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.authActuate = exports.authAskQuestions = exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.functionsActuate = exports.functionsAskQuestions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
|
|
3
|
+
exports.agentSkillsActuate = exports.agentSkillsAskQuestions = exports.authActuate = exports.authAskQuestions = exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.functionsActuate = exports.functionsAskQuestions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
|
|
4
4
|
var account_1 = require("./account");
|
|
5
5
|
Object.defineProperty(exports, "account", { enumerable: true, get: function () { return account_1.doSetup; } });
|
|
6
6
|
var database_1 = require("./database");
|
|
@@ -52,3 +52,6 @@ Object.defineProperty(exports, "aiLogicActuate", { enumerable: true, get: functi
|
|
|
52
52
|
var auth_1 = require("./auth");
|
|
53
53
|
Object.defineProperty(exports, "authAskQuestions", { enumerable: true, get: function () { return auth_1.askQuestions; } });
|
|
54
54
|
Object.defineProperty(exports, "authActuate", { enumerable: true, get: function () { return auth_1.actuate; } });
|
|
55
|
+
var agentSkills_1 = require("./agentSkills");
|
|
56
|
+
Object.defineProperty(exports, "agentSkillsAskQuestions", { enumerable: true, get: function () { return agentSkills_1.askQuestions; } });
|
|
57
|
+
Object.defineProperty(exports, "agentSkillsActuate", { enumerable: true, get: function () { return agentSkills_1.actuate; } });
|
package/lib/init/index.js
CHANGED
|
@@ -74,6 +74,12 @@ const featuresList = [
|
|
|
74
74
|
askQuestions: features.authAskQuestions,
|
|
75
75
|
actuate: features.authActuate,
|
|
76
76
|
},
|
|
77
|
+
{
|
|
78
|
+
name: "agentSkills",
|
|
79
|
+
displayName: "Agent Skills",
|
|
80
|
+
askQuestions: features.agentSkillsAskQuestions,
|
|
81
|
+
actuate: features.agentSkillsActuate,
|
|
82
|
+
},
|
|
77
83
|
];
|
|
78
84
|
const featureMap = new Map(featuresList.map((feature) => [feature.name, feature]));
|
|
79
85
|
async function init(setup, config, options) {
|