firebase-tools 13.11.3 → 13.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/auth.js +14 -15
- package/lib/commands/dataconnect-sdk-generate.js +4 -3
- package/lib/commands/ext-dev-init.js +25 -26
- package/lib/commands/index.js +9 -11
- package/lib/commands/init.js +13 -11
- package/lib/config.js +6 -1
- package/lib/crashlytics/buildToolsJarHelper.js +1 -1
- package/lib/dataconnect/client.js +1 -1
- package/lib/dataconnect/fileUtils.js +8 -6
- package/lib/dataconnect/load.js +4 -3
- package/lib/deploy/dataconnect/prepare.js +1 -1
- package/lib/emulator/controller.js +0 -4
- package/lib/emulator/dataconnectEmulator.js +111 -13
- package/lib/emulator/downloadableEmulators.js +0 -1
- package/lib/emulator/hub.js +1 -1
- package/lib/emulator/portUtils.js +9 -0
- package/lib/emulator/storage/rules/config.js +4 -2
- package/lib/experiments.js +2 -2
- package/lib/hosting/implicitInit.js +2 -2
- package/lib/init/features/dataconnect/index.js +12 -11
- package/lib/init/features/dataconnect/sdk.js +120 -0
- package/lib/init/features/firestore/indexes.js +2 -2
- package/lib/init/features/firestore/rules.js +2 -2
- package/lib/init/features/functions/javascript.js +6 -8
- package/lib/init/features/functions/python.js +4 -6
- package/lib/init/features/functions/typescript.js +8 -10
- package/lib/init/features/hosting/index.js +3 -3
- package/lib/init/features/index.js +3 -1
- package/lib/init/features/storage.js +2 -2
- package/lib/init/index.js +1 -0
- package/lib/listFiles.js +1 -0
- package/lib/management/apps.js +2 -2
- package/lib/templates.js +23 -0
- package/lib/utils.js +2 -2
- package/package.json +1 -1
- package/schema/connector-yaml.json +36 -4
- package/schema/dataconnect-yaml.json +4 -0
- package/schema/firebase-config.json +0 -8
- package/templates/_gitignore +3 -0
- package/templates/init/dataconnect/connector.yaml +11 -0
- package/templates/init/dataconnect/dataconnect.yaml +1 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataConnectEmulatorClient = exports.DataConnectEmulator = void 0;
|
|
3
|
+
exports.checkIfDataConnectEmulatorRunningOnAddress = exports.DataConnectEmulatorClient = exports.DataConnectEmulator = exports.dataConnectEmulatorEvents = void 0;
|
|
4
4
|
const childProcess = require("child_process");
|
|
5
5
|
const clc = require("colorette");
|
|
6
6
|
const api_1 = require("../api");
|
|
@@ -11,10 +11,17 @@ const error_1 = require("../error");
|
|
|
11
11
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
12
12
|
const types_2 = require("../dataconnect/types");
|
|
13
13
|
const portUtils_1 = require("./portUtils");
|
|
14
|
+
const apiv2_1 = require("../apiv2");
|
|
14
15
|
const registry_1 = require("./registry");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
const load_1 = require("../dataconnect/load");
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
const events_1 = require("events");
|
|
20
|
+
exports.dataConnectEmulatorEvents = new events_1.EventEmitter();
|
|
15
21
|
class DataConnectEmulator {
|
|
16
22
|
constructor(args) {
|
|
17
23
|
this.args = args;
|
|
24
|
+
this.usingExistingEmulator = false;
|
|
18
25
|
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.DATACONNECT);
|
|
19
26
|
this.emulatorClient = new DataConnectEmulatorClient();
|
|
20
27
|
}
|
|
@@ -33,17 +40,38 @@ class DataConnectEmulator {
|
|
|
33
40
|
catch (err) {
|
|
34
41
|
this.logger.log("DEBUG", `'fdc build' failed with error: ${err.message}`);
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
43
|
+
const alreadyRunning = await this.discoverRunningInstance();
|
|
44
|
+
if (alreadyRunning) {
|
|
45
|
+
this.logger.logLabeled("INFO", "Data Connect", "Detected an instance of the emulator already running with your service, reusing it. This emulator will not be shut down at the end of this command.");
|
|
46
|
+
this.usingExistingEmulator = true;
|
|
47
|
+
this.watchUnmanagedInstance();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
await (0, downloadableEmulators_1.start)(types_1.Emulators.DATACONNECT, {
|
|
51
|
+
auto_download: this.args.auto_download,
|
|
52
|
+
listen: (0, portUtils_1.listenSpecsToString)(this.args.listen),
|
|
53
|
+
config_dir: this.args.configDir,
|
|
54
|
+
});
|
|
55
|
+
this.usingExistingEmulator = false;
|
|
56
|
+
}
|
|
57
|
+
if (!(0, utils_1.isVSCodeExtension)()) {
|
|
58
|
+
await this.connectToPostgres();
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
42
61
|
}
|
|
43
|
-
connect() {
|
|
62
|
+
async connect() {
|
|
63
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
64
|
+
if (!emuInfo) {
|
|
65
|
+
this.logger.logLabeled("ERROR", "Data Connect", "Could not connect to Data Connect emulator. Check dataconnect-debug.log for more details.");
|
|
66
|
+
return Promise.reject();
|
|
67
|
+
}
|
|
44
68
|
return Promise.resolve();
|
|
45
69
|
}
|
|
46
|
-
stop() {
|
|
70
|
+
async stop() {
|
|
71
|
+
if (this.usingExistingEmulator) {
|
|
72
|
+
this.logger.logLabeled("INFO", "Data Connect", "Skipping cleanup of Data Connect emulator, as it was not started by this process.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
47
75
|
return (0, downloadableEmulators_1.stop)(types_1.Emulators.DATACONNECT);
|
|
48
76
|
}
|
|
49
77
|
getInfo() {
|
|
@@ -65,16 +93,19 @@ class DataConnectEmulator {
|
|
|
65
93
|
"--logtostderr",
|
|
66
94
|
"-v=2",
|
|
67
95
|
"generate",
|
|
68
|
-
`--service_location=${args.locationId}`,
|
|
69
96
|
`--config_dir=${args.configDir}`,
|
|
70
97
|
`--connector_id=${args.connectorId}`,
|
|
71
98
|
];
|
|
72
99
|
const res = childProcess.spawnSync(commandInfo.binary, cmd, { encoding: "utf-8" });
|
|
100
|
+
logger_1.logger.info(res.stderr);
|
|
73
101
|
if (res.error) {
|
|
74
102
|
throw new error_1.FirebaseError(`Error starting up Data Connect generate: ${res.error.message}`, {
|
|
75
103
|
original: res.error,
|
|
76
104
|
});
|
|
77
105
|
}
|
|
106
|
+
if (res.status !== 0) {
|
|
107
|
+
throw new error_1.FirebaseError(`Unable to generate your Data Connect SDKs (exit code ${res.status}): ${res.stderr}`);
|
|
108
|
+
}
|
|
78
109
|
return res.stdout;
|
|
79
110
|
}
|
|
80
111
|
static async build(args) {
|
|
@@ -107,6 +138,35 @@ class DataConnectEmulator {
|
|
|
107
138
|
}
|
|
108
139
|
return (_b = (_a = this.args.rc.getDataconnect()) === null || _a === void 0 ? void 0 : _a.postgres) === null || _b === void 0 ? void 0 : _b.localConnectionString;
|
|
109
140
|
}
|
|
141
|
+
async discoverRunningInstance() {
|
|
142
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
143
|
+
if (!emuInfo) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
const serviceInfo = await (0, load_1.load)(this.args.projectId, this.args.configDir);
|
|
147
|
+
const sameService = emuInfo.services.find((s) => serviceInfo.dataConnectYaml.serviceId === s.serviceId);
|
|
148
|
+
if (!sameService) {
|
|
149
|
+
throw new error_1.FirebaseError(`There is a Data Connect emulator already running on ${this.args.listen[0].address}:${this.args.listen[0].port}, but it is emulating a different service. Please stop that instance of the Data Connect emulator, or specify a different port in 'firebase.json'`);
|
|
150
|
+
}
|
|
151
|
+
if (sameService.connectionString &&
|
|
152
|
+
sameService.connectionString !== this.getLocalConectionString()) {
|
|
153
|
+
throw new error_1.FirebaseError(`There is a Data Connect emulator already running, but it is using a different Postgres connection string. Please stop that instance of the Data Connect emulator, or specify a different port in 'firebase.json'`);
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
watchUnmanagedInstance() {
|
|
158
|
+
return setInterval(async () => {
|
|
159
|
+
if (!this.usingExistingEmulator) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
163
|
+
if (!emuInfo) {
|
|
164
|
+
this.logger.logLabeled("INFO", "Data Connect", "The already running emulator seems to have shut down. Starting a new instance of the Data Connect emulator...");
|
|
165
|
+
await this.start();
|
|
166
|
+
exports.dataConnectEmulatorEvents.emit("restart");
|
|
167
|
+
}
|
|
168
|
+
}, 5000);
|
|
169
|
+
}
|
|
110
170
|
async connectToPostgres(localConnectionString, database, serviceId) {
|
|
111
171
|
const connectionString = localConnectionString !== null && localConnectionString !== void 0 ? localConnectionString : this.getLocalConectionString();
|
|
112
172
|
if (!connectionString) {
|
|
@@ -114,8 +174,22 @@ class DataConnectEmulator {
|
|
|
114
174
|
Run ${clc.bold("firebase setup:emulators:dataconnect")} to set up a Postgres connection.`;
|
|
115
175
|
throw new error_1.FirebaseError(msg);
|
|
116
176
|
}
|
|
117
|
-
|
|
118
|
-
|
|
177
|
+
const MAX_RETRIES = 3;
|
|
178
|
+
for (let i = 1; i <= MAX_RETRIES; i++) {
|
|
179
|
+
try {
|
|
180
|
+
this.logger.logLabeled("DEBUG", "Data Connect", `Connecting to ${connectionString}}`);
|
|
181
|
+
await this.emulatorClient.configureEmulator({ connectionString, database, serviceId });
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (i === MAX_RETRIES) {
|
|
186
|
+
throw err;
|
|
187
|
+
}
|
|
188
|
+
this.logger.logLabeled("DEBUG", "Data Connect", `Retrying connectToPostgress call (${i} of ${MAX_RETRIES} attempts): ${err}`);
|
|
189
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
119
193
|
}
|
|
120
194
|
}
|
|
121
195
|
exports.DataConnectEmulator = DataConnectEmulator;
|
|
@@ -124,6 +198,7 @@ class DataConnectEmulatorClient {
|
|
|
124
198
|
this.client = undefined;
|
|
125
199
|
}
|
|
126
200
|
async configureEmulator(body) {
|
|
201
|
+
var _a, _b;
|
|
127
202
|
if (!this.client) {
|
|
128
203
|
this.client = registry_1.EmulatorRegistry.client(types_1.Emulators.DATACONNECT);
|
|
129
204
|
}
|
|
@@ -133,10 +208,33 @@ class DataConnectEmulatorClient {
|
|
|
133
208
|
}
|
|
134
209
|
catch (err) {
|
|
135
210
|
if (err.status === 500) {
|
|
136
|
-
throw new error_1.FirebaseError(`Data Connect emulator: ${err.context.body.message}`);
|
|
211
|
+
throw new error_1.FirebaseError(`Data Connect emulator: ${(_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.message}`);
|
|
137
212
|
}
|
|
138
213
|
throw err;
|
|
139
214
|
}
|
|
140
215
|
}
|
|
216
|
+
async getInfo() {
|
|
217
|
+
if (!this.client) {
|
|
218
|
+
this.client = registry_1.EmulatorRegistry.client(types_1.Emulators.DATACONNECT);
|
|
219
|
+
}
|
|
220
|
+
return getInfo(this.client);
|
|
221
|
+
}
|
|
141
222
|
}
|
|
142
223
|
exports.DataConnectEmulatorClient = DataConnectEmulatorClient;
|
|
224
|
+
async function checkIfDataConnectEmulatorRunningOnAddress(l) {
|
|
225
|
+
const client = new apiv2_1.Client({
|
|
226
|
+
urlPrefix: `http:/${l.family === "IPv6" ? `[${l.address}]` : l.address}:${l.port}`,
|
|
227
|
+
auth: false,
|
|
228
|
+
});
|
|
229
|
+
return getInfo(client);
|
|
230
|
+
}
|
|
231
|
+
exports.checkIfDataConnectEmulatorRunningOnAddress = checkIfDataConnectEmulatorRunningOnAddress;
|
|
232
|
+
async function getInfo(client) {
|
|
233
|
+
try {
|
|
234
|
+
const res = await client.get("emulator/info");
|
|
235
|
+
return res.body;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
}
|
package/lib/emulator/hub.js
CHANGED
|
@@ -149,7 +149,7 @@ class EmulatorHub extends ExpressBasedEmulator_1.ExpressBasedEmulator {
|
|
|
149
149
|
const locatorPath = EmulatorHub.getLocatorFilePath(this.args.projectId);
|
|
150
150
|
return new Promise((resolve, reject) => {
|
|
151
151
|
fs.unlink(locatorPath, (e) => {
|
|
152
|
-
if (e) {
|
|
152
|
+
if (e && e.code !== "ENOENT") {
|
|
153
153
|
reject(e);
|
|
154
154
|
}
|
|
155
155
|
else {
|
|
@@ -11,6 +11,7 @@ const types_1 = require("./types");
|
|
|
11
11
|
const constants_1 = require("./constants");
|
|
12
12
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
13
13
|
const node_child_process_1 = require("node:child_process");
|
|
14
|
+
const dataconnectEmulator_1 = require("./dataconnectEmulator");
|
|
14
15
|
const RESTRICTED_PORTS = new Set([
|
|
15
16
|
1,
|
|
16
17
|
7,
|
|
@@ -219,6 +220,14 @@ async function resolveHostAndAssignPorts(listenConfig) {
|
|
|
219
220
|
available.push(listen);
|
|
220
221
|
}
|
|
221
222
|
else {
|
|
223
|
+
if (/^dataconnect/i.exec(name)) {
|
|
224
|
+
const alreadyRunning = await (0, dataconnectEmulator_1.checkIfDataConnectEmulatorRunningOnAddress)(listen);
|
|
225
|
+
if (alreadyRunning) {
|
|
226
|
+
emuLogger.logLabeled("DEBUG", "dataconnect", `Detected already running emulator on ${listen.address}:${listen.port}. Will attempt to reuse it.`);
|
|
227
|
+
}
|
|
228
|
+
available.push(listen);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
222
231
|
if (!portFixed) {
|
|
223
232
|
if (i > 0) {
|
|
224
233
|
emuLogger.logLabeled("DEBUG", name, `Port ${p} taken on secondary address ${addr.address}, will keep searching to find a better port.`);
|
|
@@ -6,6 +6,7 @@ const fsutils_1 = require("../../../fsutils");
|
|
|
6
6
|
const constants_1 = require("../../constants");
|
|
7
7
|
const types_1 = require("../../types");
|
|
8
8
|
const emulatorLogger_1 = require("../../emulatorLogger");
|
|
9
|
+
const templates_1 = require("../../../templates");
|
|
9
10
|
function getSourceFile(rules, options) {
|
|
10
11
|
const path = options.config.path(rules);
|
|
11
12
|
return { name: path, content: (0, fsutils_1.readFile)(path) };
|
|
@@ -48,6 +49,7 @@ function getStorageRulesConfig(projectId, options) {
|
|
|
48
49
|
}
|
|
49
50
|
exports.getStorageRulesConfig = getStorageRulesConfig;
|
|
50
51
|
function defaultStorageRules() {
|
|
51
|
-
const
|
|
52
|
-
|
|
52
|
+
const defaultRulesPath = "emulators/default_storage.rules";
|
|
53
|
+
const name = (0, templates_1.absoluteTemplateFilePath)(defaultRulesPath);
|
|
54
|
+
return { name, content: (0, fsutils_1.readFile)(name) };
|
|
53
55
|
}
|
package/lib/experiments.js
CHANGED
|
@@ -92,8 +92,8 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
92
92
|
public: false,
|
|
93
93
|
},
|
|
94
94
|
dataconnect: {
|
|
95
|
-
shortDescription: "
|
|
96
|
-
fullDescription: "
|
|
95
|
+
shortDescription: "Deprecated. Previosuly, enabled Data Connect related features.",
|
|
96
|
+
fullDescription: "Deprecated. Previously, enabled Data Connect related features.",
|
|
97
97
|
public: false,
|
|
98
98
|
},
|
|
99
99
|
genkit: {
|
|
@@ -3,13 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.implicitInit = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const clc = require("colorette");
|
|
6
|
-
const fs = require("fs");
|
|
7
6
|
const fetchWebSetup_1 = require("../fetchWebSetup");
|
|
8
7
|
const utils = require("../utils");
|
|
9
8
|
const logger_1 = require("../logger");
|
|
10
9
|
const registry_1 = require("../emulator/registry");
|
|
11
10
|
const types_1 = require("../emulator/types");
|
|
12
|
-
const
|
|
11
|
+
const templates_1 = require("../templates");
|
|
12
|
+
const INIT_TEMPLATE = (0, templates_1.readTemplateSync)("hosting/init.js");
|
|
13
13
|
async function implicitInit(options) {
|
|
14
14
|
let config;
|
|
15
15
|
try {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.doSetup = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
|
+
const clc = require("colorette");
|
|
5
6
|
const prompt_1 = require("../../../prompt");
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
7
|
const provisionCloudSql_1 = require("../../../dataconnect/provisionCloudSql");
|
|
8
8
|
const freeTrial_1 = require("../../../dataconnect/freeTrial");
|
|
9
9
|
const cloudsql = require("../../../gcp/cloudsql/cloudsqladmin");
|
|
@@ -12,12 +12,13 @@ const client_1 = require("../../../dataconnect/client");
|
|
|
12
12
|
const emulators_1 = require("../emulators");
|
|
13
13
|
const names_1 = require("../../../dataconnect/names");
|
|
14
14
|
const logger_1 = require("../../../logger");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
15
|
+
const templates_1 = require("../../../templates");
|
|
16
|
+
const utils_1 = require("../../../utils");
|
|
17
|
+
const DATACONNECT_YAML_TEMPLATE = (0, templates_1.readTemplateSync)("init/dataconnect/dataconnect.yaml");
|
|
18
|
+
const CONNECTOR_YAML_TEMPLATE = (0, templates_1.readTemplateSync)("init/dataconnect/connector.yaml");
|
|
19
|
+
const SCHEMA_TEMPLATE = (0, templates_1.readTemplateSync)("init/dataconnect/schema.gql");
|
|
20
|
+
const QUERIES_TEMPLATE = (0, templates_1.readTemplateSync)("init/dataconnect/queries.gql");
|
|
21
|
+
const MUTATIONS_TEMPLATE = (0, templates_1.readTemplateSync)("init/dataconnect/mutations.gql");
|
|
21
22
|
async function doSetup(setup, config) {
|
|
22
23
|
var _a, _b, _c;
|
|
23
24
|
let info = {
|
|
@@ -47,10 +48,7 @@ async function doSetup(setup, config) {
|
|
|
47
48
|
const dir = config.get("dataconnect.source") || "dataconnect";
|
|
48
49
|
const subbedDataconnectYaml = subValues(DATACONNECT_YAML_TEMPLATE, info);
|
|
49
50
|
const subbedConnectorYaml = subValues(CONNECTOR_YAML_TEMPLATE, info);
|
|
50
|
-
|
|
51
|
-
config.set("dataconnect.source", dir);
|
|
52
|
-
config.set("dataconnect.location", info.locationId);
|
|
53
|
-
}
|
|
51
|
+
config.set("dataconnect", { source: dir });
|
|
54
52
|
await config.askWriteProjectFile((0, path_1.join)(dir, "dataconnect.yaml"), subbedDataconnectYaml);
|
|
55
53
|
await config.askWriteProjectFile((0, path_1.join)(dir, "schema", "schema.gql"), SCHEMA_TEMPLATE);
|
|
56
54
|
await config.askWriteProjectFile((0, path_1.join)(dir, info.connectorId, "connector.yaml"), subbedConnectorYaml);
|
|
@@ -71,6 +69,8 @@ async function doSetup(setup, config) {
|
|
|
71
69
|
waitForCreation: false,
|
|
72
70
|
});
|
|
73
71
|
}
|
|
72
|
+
logger_1.logger.info("");
|
|
73
|
+
(0, utils_1.logSuccess)(`If you'd like to generate an SDK for your new connector, run ${clc.bold("firebase init dataconnect:sdk")}`);
|
|
74
74
|
}
|
|
75
75
|
exports.doSetup = doSetup;
|
|
76
76
|
function subValues(template, replacementValues) {
|
|
@@ -79,6 +79,7 @@ function subValues(template, replacementValues) {
|
|
|
79
79
|
cloudSqlDatabase: "__cloudSqlDatabase__",
|
|
80
80
|
cloudSqlInstanceId: "__cloudSqlInstanceId__",
|
|
81
81
|
connectorId: "__connectorId__",
|
|
82
|
+
locationId: "__location__",
|
|
82
83
|
};
|
|
83
84
|
let replaced = template;
|
|
84
85
|
for (const [k, v] of Object.entries(replacementValues)) {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.doSetup = void 0;
|
|
4
|
+
const yaml = require("yaml");
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const prompt_1 = require("../../../prompt");
|
|
7
|
+
const clc = require("colorette");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
const fileUtils_1 = require("../../../dataconnect/fileUtils");
|
|
10
|
+
const load_1 = require("../../../dataconnect/load");
|
|
11
|
+
const logger_1 = require("../../../logger");
|
|
12
|
+
const dataconnectEmulator_1 = require("../../../emulator/dataconnectEmulator");
|
|
13
|
+
const IOS = "ios";
|
|
14
|
+
const WEB = "web";
|
|
15
|
+
const ANDROID = "android";
|
|
16
|
+
async function doSetup(setup, config) {
|
|
17
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
18
|
+
const serviceCfgs = (0, fileUtils_1.readFirebaseJson)(config);
|
|
19
|
+
const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(setup.projectId || "", path.join(process.cwd(), c.source))));
|
|
20
|
+
const connectorChoices = serviceInfos
|
|
21
|
+
.map((si) => {
|
|
22
|
+
return si.connectorInfo.map((ci) => {
|
|
23
|
+
return {
|
|
24
|
+
name: `${si.dataConnectYaml.serviceId}/${ci.connectorYaml.connectorId}`,
|
|
25
|
+
value: ci,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
})
|
|
29
|
+
.flat();
|
|
30
|
+
if (!connectorChoices.length) {
|
|
31
|
+
logger_1.logger.info(`Your config has no connectors to set up SDKs for. Run ${clc.bold("firebase init dataconnect")} to set up a service and conenctors.`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const connectorInfo = await (0, prompt_1.promptOnce)({
|
|
35
|
+
message: "Which connector do you want set up a generated SDK for?",
|
|
36
|
+
type: "list",
|
|
37
|
+
choices: connectorChoices,
|
|
38
|
+
});
|
|
39
|
+
const platforms = await (0, prompt_1.promptOnce)({
|
|
40
|
+
message: "Which platforms do you want to set up a generated SDK for?",
|
|
41
|
+
type: "checkbox",
|
|
42
|
+
choices: [
|
|
43
|
+
{ name: "iOS (Swift)", value: IOS },
|
|
44
|
+
{ name: "Web (JavaScript)", value: WEB },
|
|
45
|
+
{ name: "Androd (Kotlin)", value: ANDROID },
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
const newConnectorYaml = JSON.parse(JSON.stringify(connectorInfo.connectorYaml));
|
|
49
|
+
if (!newConnectorYaml.generate) {
|
|
50
|
+
newConnectorYaml.generate = {};
|
|
51
|
+
}
|
|
52
|
+
if (platforms.includes(IOS)) {
|
|
53
|
+
const defaultOutputDir = (_a = newConnectorYaml.generate.swiftSdk) === null || _a === void 0 ? void 0 : _a.outputDir;
|
|
54
|
+
const outputDir = await (0, prompt_1.promptOnce)({
|
|
55
|
+
message: `What directory do you want to write your Swift SDK code to? (If not absolute, path will be relative to '${connectorInfo.directory}')`,
|
|
56
|
+
type: "input",
|
|
57
|
+
default: defaultOutputDir,
|
|
58
|
+
});
|
|
59
|
+
const swiftSdk = { outputDir };
|
|
60
|
+
newConnectorYaml.generate.swiftSdk = swiftSdk;
|
|
61
|
+
}
|
|
62
|
+
if (platforms.includes(WEB)) {
|
|
63
|
+
const outputDir = await (0, prompt_1.promptOnce)({
|
|
64
|
+
message: `What directory do you want to write your JavaScript SDK code to? (If not absolute, path will be relative to '${connectorInfo.directory}')`,
|
|
65
|
+
type: "input",
|
|
66
|
+
default: (_b = newConnectorYaml.generate.javascriptSdk) === null || _b === void 0 ? void 0 : _b.outputDir,
|
|
67
|
+
});
|
|
68
|
+
const pkg = await (0, prompt_1.promptOnce)({
|
|
69
|
+
message: "What package name do you want to use for your JavaScript SDK?",
|
|
70
|
+
type: "input",
|
|
71
|
+
default: (_d = (_c = newConnectorYaml.generate.javascriptSdk) === null || _c === void 0 ? void 0 : _c.package) !== null && _d !== void 0 ? _d : `@firebasegen/${connectorInfo.connectorYaml.connectorId}`,
|
|
72
|
+
});
|
|
73
|
+
const packageJSONDir = await (0, prompt_1.promptOnce)({
|
|
74
|
+
message: "Which directory contains the package.json that you would like to add the JavaScript SDK dependency to? (Leave blank to skip)",
|
|
75
|
+
type: "input",
|
|
76
|
+
default: (_e = newConnectorYaml.generate.javascriptSdk) === null || _e === void 0 ? void 0 : _e.packageJSONDir,
|
|
77
|
+
});
|
|
78
|
+
const javascriptSdk = {
|
|
79
|
+
outputDir,
|
|
80
|
+
package: pkg,
|
|
81
|
+
};
|
|
82
|
+
if (packageJSONDir) {
|
|
83
|
+
javascriptSdk.packageJSONDir = packageJSONDir;
|
|
84
|
+
}
|
|
85
|
+
newConnectorYaml.generate.javascriptSdk = javascriptSdk;
|
|
86
|
+
}
|
|
87
|
+
if (platforms.includes(ANDROID)) {
|
|
88
|
+
const outputDir = await (0, prompt_1.promptOnce)({
|
|
89
|
+
message: `What directory do you want to write your Kotlin SDK code to? (If not absolute, path will be relative to '${connectorInfo.directory}')`,
|
|
90
|
+
type: "input",
|
|
91
|
+
default: (_f = newConnectorYaml.generate.kotlinSdk) === null || _f === void 0 ? void 0 : _f.outputDir,
|
|
92
|
+
});
|
|
93
|
+
const pkg = await (0, prompt_1.promptOnce)({
|
|
94
|
+
message: "What package name do you want to use for your Kotlin SDK?",
|
|
95
|
+
type: "input",
|
|
96
|
+
default: (_h = (_g = newConnectorYaml.generate.kotlinSdk) === null || _g === void 0 ? void 0 : _g.package) !== null && _h !== void 0 ? _h : `com.google.firebase.dataconnect.connectors.${connectorInfo.connectorYaml.connectorId}`,
|
|
97
|
+
});
|
|
98
|
+
const kotlinSdk = {
|
|
99
|
+
outputDir,
|
|
100
|
+
package: pkg,
|
|
101
|
+
};
|
|
102
|
+
newConnectorYaml.generate.kotlinSdk = kotlinSdk;
|
|
103
|
+
}
|
|
104
|
+
const connectorYamlContents = yaml.stringify(newConnectorYaml);
|
|
105
|
+
const connectorYamlPath = `${connectorInfo.directory}/connector.yaml`;
|
|
106
|
+
fs.writeFileSync(connectorYamlPath, connectorYamlContents, "utf8");
|
|
107
|
+
logger_1.logger.info(`Wrote new config to ${connectorYamlPath}`);
|
|
108
|
+
if (setup.projectId &&
|
|
109
|
+
(await (0, prompt_1.confirm)({
|
|
110
|
+
message: "Would you like to generate SDK code now?",
|
|
111
|
+
default: true,
|
|
112
|
+
}))) {
|
|
113
|
+
await dataconnectEmulator_1.DataConnectEmulator.generate({
|
|
114
|
+
configDir: connectorInfo.directory,
|
|
115
|
+
connectorId: connectorInfo.connectorYaml.connectorId,
|
|
116
|
+
});
|
|
117
|
+
logger_1.logger.info(`Generated SDK code for ${connectorInfo.connectorYaml.connectorId}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.doSetup = doSetup;
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initIndexes = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const fs = require("fs");
|
|
6
5
|
const error_1 = require("../../../error");
|
|
7
6
|
const api = require("../../../firestore/api");
|
|
8
7
|
const fsutils = require("../../../fsutils");
|
|
9
8
|
const prompt_1 = require("../../../prompt");
|
|
10
9
|
const logger_1 = require("../../../logger");
|
|
10
|
+
const templates_1 = require("../../../templates");
|
|
11
11
|
const indexes = new api.FirestoreApi();
|
|
12
|
-
const INDEXES_TEMPLATE =
|
|
12
|
+
const INDEXES_TEMPLATE = (0, templates_1.readTemplateSync)("init/firestore/firestore.indexes.json");
|
|
13
13
|
function initIndexes(setup, config) {
|
|
14
14
|
logger_1.logger.info();
|
|
15
15
|
logger_1.logger.info("Firestore indexes allow you to perform complex queries while");
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initRules = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const fs = require("fs");
|
|
6
5
|
const gcp = require("../../../gcp");
|
|
7
6
|
const fsutils = require("../../../fsutils");
|
|
8
7
|
const prompt_1 = require("../../../prompt");
|
|
9
8
|
const logger_1 = require("../../../logger");
|
|
10
9
|
const utils = require("../../../utils");
|
|
10
|
+
const templates_1 = require("../../../templates");
|
|
11
11
|
const DEFAULT_RULES_FILE = "firestore.rules";
|
|
12
|
-
const RULES_TEMPLATE =
|
|
12
|
+
const RULES_TEMPLATE = (0, templates_1.readTemplateSync)("init/firestore/firestore.rules");
|
|
13
13
|
function initRules(setup, config) {
|
|
14
14
|
logger_1.logger.info();
|
|
15
15
|
logger_1.logger.info("Firestore Security Rules allow you to define how and when to allow");
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setup = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const path = require("path");
|
|
6
4
|
const npm_dependencies_1 = require("./npm-dependencies");
|
|
7
5
|
const prompt_1 = require("../../../prompt");
|
|
8
6
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
9
|
-
const
|
|
10
|
-
const INDEX_TEMPLATE =
|
|
11
|
-
const PACKAGE_LINTING_TEMPLATE =
|
|
12
|
-
const PACKAGE_NO_LINTING_TEMPLATE =
|
|
13
|
-
const ESLINT_TEMPLATE =
|
|
14
|
-
const GITIGNORE_TEMPLATE =
|
|
7
|
+
const templates_1 = require("../../../templates");
|
|
8
|
+
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index.js");
|
|
9
|
+
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.lint.json");
|
|
10
|
+
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.nolint.json");
|
|
11
|
+
const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_eslintrc");
|
|
12
|
+
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_gitignore");
|
|
15
13
|
function setup(setup, config) {
|
|
16
14
|
return (0, prompt_1.prompt)(setup.functions, [
|
|
17
15
|
{
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setup = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
4
|
const spawn = require("cross-spawn");
|
|
6
|
-
const path = require("path");
|
|
7
5
|
const python_1 = require("../../../deploy/functions/runtimes/python");
|
|
8
6
|
const python_2 = require("../../../functions/python");
|
|
9
7
|
const prompt_1 = require("../../../prompt");
|
|
10
8
|
const supported_1 = require("../../../deploy/functions/runtimes/supported");
|
|
11
|
-
const
|
|
12
|
-
const MAIN_TEMPLATE =
|
|
13
|
-
const REQUIREMENTS_TEMPLATE =
|
|
14
|
-
const GITIGNORE_TEMPLATE =
|
|
9
|
+
const templates_1 = require("../../../templates");
|
|
10
|
+
const MAIN_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/python/main.py");
|
|
11
|
+
const REQUIREMENTS_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/python/requirements.txt");
|
|
12
|
+
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/python/_gitignore");
|
|
15
13
|
async function setup(setup, config) {
|
|
16
14
|
await config.askWriteProjectFile(`${setup.functions.source}/requirements.txt`, REQUIREMENTS_TEMPLATE);
|
|
17
15
|
await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setup = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const path = require("path");
|
|
6
4
|
const npm_dependencies_1 = require("./npm-dependencies");
|
|
7
5
|
const prompt_1 = require("../../../prompt");
|
|
8
6
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
9
|
-
const
|
|
10
|
-
const PACKAGE_LINTING_TEMPLATE =
|
|
11
|
-
const PACKAGE_NO_LINTING_TEMPLATE =
|
|
12
|
-
const ESLINT_TEMPLATE =
|
|
13
|
-
const TSCONFIG_TEMPLATE =
|
|
14
|
-
const TSCONFIG_DEV_TEMPLATE =
|
|
15
|
-
const INDEX_TEMPLATE =
|
|
16
|
-
const GITIGNORE_TEMPLATE =
|
|
7
|
+
const templates_1 = require("../../../templates");
|
|
8
|
+
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.lint.json");
|
|
9
|
+
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.nolint.json");
|
|
10
|
+
const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
|
|
11
|
+
const TSCONFIG_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.json");
|
|
12
|
+
const TSCONFIG_DEV_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.dev.json");
|
|
13
|
+
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/index.ts");
|
|
14
|
+
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_gitignore");
|
|
17
15
|
function setup(setup, config) {
|
|
18
16
|
return (0, prompt_1.prompt)(setup.functions, [
|
|
19
17
|
{
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.doSetup = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const fs = require("fs");
|
|
6
5
|
const rimraf_1 = require("rimraf");
|
|
7
6
|
const path_1 = require("path");
|
|
8
7
|
const apiv2_1 = require("../../../apiv2");
|
|
@@ -15,8 +14,9 @@ const experiments = require("../../../experiments");
|
|
|
15
14
|
const getDefaultHostingSite_1 = require("../../../getDefaultHostingSite");
|
|
16
15
|
const utils_1 = require("../../../utils");
|
|
17
16
|
const interactive_1 = require("../../../hosting/interactive");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
const templates_1 = require("../../../templates");
|
|
18
|
+
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/hosting/index.html");
|
|
19
|
+
const MISSING_TEMPLATE = (0, templates_1.readTemplateSync)("init/hosting/404.html");
|
|
20
20
|
const DEFAULT_IGNORES = ["firebase.json", "**/.*", "**/node_modules/**"];
|
|
21
21
|
async function doSetup(setup, config, options) {
|
|
22
22
|
var _a;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.genkit = exports.apphosting = exports.dataconnect = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = exports.account = void 0;
|
|
3
|
+
exports.genkit = exports.apphosting = exports.dataconnectSdk = exports.dataconnect = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = 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");
|
|
@@ -25,6 +25,8 @@ var github_1 = require("./hosting/github");
|
|
|
25
25
|
Object.defineProperty(exports, "hostingGithub", { enumerable: true, get: function () { return github_1.initGitHub; } });
|
|
26
26
|
var dataconnect_1 = require("./dataconnect");
|
|
27
27
|
Object.defineProperty(exports, "dataconnect", { enumerable: true, get: function () { return dataconnect_1.doSetup; } });
|
|
28
|
+
var sdk_1 = require("./dataconnect/sdk");
|
|
29
|
+
Object.defineProperty(exports, "dataconnectSdk", { enumerable: true, get: function () { return sdk_1.doSetup; } });
|
|
28
30
|
var apphosting_1 = require("../../apphosting");
|
|
29
31
|
Object.defineProperty(exports, "apphosting", { enumerable: true, get: function () { return apphosting_1.doSetup; } });
|
|
30
32
|
var genkit_1 = require("./genkit");
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.doSetup = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const fs = require("fs");
|
|
6
5
|
const logger_1 = require("../../logger");
|
|
7
6
|
const prompt_1 = require("../../prompt");
|
|
8
7
|
const ensureCloudResourceLocation_1 = require("../../ensureCloudResourceLocation");
|
|
9
|
-
const
|
|
8
|
+
const templates_1 = require("../../templates");
|
|
9
|
+
const RULES_TEMPLATE = (0, templates_1.readTemplateSync)("init/storage/storage.rules");
|
|
10
10
|
async function doSetup(setup, config) {
|
|
11
11
|
setup.config.storage = {};
|
|
12
12
|
(0, ensureCloudResourceLocation_1.ensureLocationSet)(setup.projectLocation, "Cloud Storage");
|