firebase-tools 13.11.4 → 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/init.js +9 -5
- package/lib/config.js +6 -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 -1
- package/lib/emulator/dataconnectEmulator.js +6 -3
- package/lib/emulator/downloadableEmulators.js +0 -1
- package/lib/emulator/storage/rules/config.js +4 -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
package/lib/auth.js
CHANGED
|
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addAdditionalAccount = exports.logout = exports.getAccessToken = exports.findAccountByEmail = exports.loginGithub = exports.loginGoogle = exports.setGlobalDefaultAccount = exports.setProjectAccount = exports.loginAdditionalAccount = exports.selectAccount = exports.setRefreshToken = exports.setActiveAccount = exports.getAllAccounts = exports.getAdditionalAccounts = exports.getProjectDefaultAccount = exports.getGlobalDefaultAccount = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const FormData = require("form-data");
|
|
6
|
-
const fs = require("fs");
|
|
7
6
|
const http = require("http");
|
|
8
7
|
const jwt = require("jsonwebtoken");
|
|
9
8
|
const opn = require("open");
|
|
10
|
-
const path = require("path");
|
|
11
9
|
const portfinder = require("portfinder");
|
|
12
10
|
const url = require("url");
|
|
13
|
-
const util = require("util");
|
|
14
11
|
const apiv2 = require("./apiv2");
|
|
15
12
|
const configstore_1 = require("./configstore");
|
|
16
13
|
const error_1 = require("./error");
|
|
@@ -23,6 +20,7 @@ const uuid_1 = require("uuid");
|
|
|
23
20
|
const crypto_1 = require("crypto");
|
|
24
21
|
const track_1 = require("./track");
|
|
25
22
|
const api_1 = require("./api");
|
|
23
|
+
const templates_1 = require("./templates");
|
|
26
24
|
portfinder.setBasePort(9005);
|
|
27
25
|
function getGlobalDefaultAccount() {
|
|
28
26
|
const user = configstore_1.configstore.get("user");
|
|
@@ -261,13 +259,12 @@ async function getGithubTokensFromAuthorizationCode(code, callbackUrl) {
|
|
|
261
259
|
});
|
|
262
260
|
return res.body.access_token;
|
|
263
261
|
}
|
|
264
|
-
|
|
265
|
-
const response = await util.promisify(fs.readFile)(path.join(__dirname, filename));
|
|
262
|
+
function respondHtml(req, res, statusCode, html) {
|
|
266
263
|
res.writeHead(statusCode, {
|
|
267
|
-
"Content-Length":
|
|
264
|
+
"Content-Length": html.length,
|
|
268
265
|
"Content-Type": "text/html",
|
|
269
266
|
});
|
|
270
|
-
res.end(
|
|
267
|
+
res.end(html);
|
|
271
268
|
req.socket.destroy();
|
|
272
269
|
}
|
|
273
270
|
function urlsafeBase64(base64string) {
|
|
@@ -319,8 +316,8 @@ async function loginRemotely() {
|
|
|
319
316
|
async function loginWithLocalhostGoogle(port, userHint) {
|
|
320
317
|
const callbackUrl = getCallbackUrl(port);
|
|
321
318
|
const authUrl = getLoginUrl(callbackUrl, userHint);
|
|
322
|
-
const
|
|
323
|
-
const tokens = await loginWithLocalhost(port, callbackUrl, authUrl,
|
|
319
|
+
const successHtml = await (0, templates_1.readTemplate)("loginSuccess.html");
|
|
320
|
+
const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getTokensFromAuthorizationCode);
|
|
324
321
|
void (0, track_1.trackGA4)("login", { method: "google_localhost" });
|
|
325
322
|
return {
|
|
326
323
|
user: jwt.decode(tokens.id_token, { json: true }),
|
|
@@ -331,30 +328,32 @@ async function loginWithLocalhostGoogle(port, userHint) {
|
|
|
331
328
|
async function loginWithLocalhostGitHub(port) {
|
|
332
329
|
const callbackUrl = getCallbackUrl(port);
|
|
333
330
|
const authUrl = getGithubLoginUrl(callbackUrl);
|
|
334
|
-
const
|
|
335
|
-
const tokens = await loginWithLocalhost(port, callbackUrl, authUrl,
|
|
331
|
+
const successHtml = await (0, templates_1.readTemplate)("loginSuccessGithub.html");
|
|
332
|
+
const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getGithubTokensFromAuthorizationCode);
|
|
336
333
|
void (0, track_1.trackGA4)("login", { method: "github_localhost" });
|
|
337
334
|
return tokens;
|
|
338
335
|
}
|
|
339
|
-
async function loginWithLocalhost(port, callbackUrl, authUrl,
|
|
336
|
+
async function loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getTokens) {
|
|
340
337
|
return new Promise((resolve, reject) => {
|
|
341
338
|
const server = http.createServer(async (req, res) => {
|
|
342
339
|
const query = url.parse(`${req.url}`, true).query || {};
|
|
343
340
|
const queryState = query.state;
|
|
344
341
|
const queryCode = query.code;
|
|
345
342
|
if (queryState !== _nonce || typeof queryCode !== "string") {
|
|
346
|
-
await
|
|
343
|
+
const html = await (0, templates_1.readTemplate)("loginFailure.html");
|
|
344
|
+
respondHtml(req, res, 400, html);
|
|
347
345
|
reject(new error_1.FirebaseError("Unexpected error while logging in"));
|
|
348
346
|
server.close();
|
|
349
347
|
return;
|
|
350
348
|
}
|
|
351
349
|
try {
|
|
352
350
|
const tokens = await getTokens(queryCode, callbackUrl);
|
|
353
|
-
|
|
351
|
+
respondHtml(req, res, 200, successHtml);
|
|
354
352
|
resolve(tokens);
|
|
355
353
|
}
|
|
356
354
|
catch (err) {
|
|
357
|
-
await
|
|
355
|
+
const html = await (0, templates_1.readTemplate)("loginFailure.html");
|
|
356
|
+
respondHtml(req, res, 400, html);
|
|
358
357
|
reject(err);
|
|
359
358
|
}
|
|
360
359
|
server.close();
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
|
+
const clc = require("colorette");
|
|
5
6
|
const command_1 = require("../command");
|
|
6
7
|
const dataconnectEmulator_1 = require("../emulator/dataconnectEmulator");
|
|
7
8
|
const projectUtils_1 = require("../projectUtils");
|
|
@@ -19,7 +20,7 @@ exports.command = new command_1.Command("dataconnect:sdk:generate")
|
|
|
19
20
|
const cwd = options.cwd || process.cwd();
|
|
20
21
|
configDir = path.resolve(path.join(cwd), configDir);
|
|
21
22
|
}
|
|
22
|
-
const serviceInfo = await (0, load_1.load)(projectId,
|
|
23
|
+
const serviceInfo = await (0, load_1.load)(projectId, configDir);
|
|
23
24
|
const hasGeneratables = serviceInfo.connectorInfo.some((c) => {
|
|
24
25
|
var _a, _b, _c;
|
|
25
26
|
return (((_a = c.connectorYaml.generate) === null || _a === void 0 ? void 0 : _a.javascriptSdk) ||
|
|
@@ -28,13 +29,13 @@ exports.command = new command_1.Command("dataconnect:sdk:generate")
|
|
|
28
29
|
});
|
|
29
30
|
if (!hasGeneratables) {
|
|
30
31
|
logger_1.logger.warn("No generated SDKs have been declared in connector.yaml files.");
|
|
31
|
-
logger_1.logger.warn("
|
|
32
|
+
logger_1.logger.warn(`Run ${clc.bold("firebase init dataconnect:sdk")} to configure a generated SDK.`);
|
|
33
|
+
logger_1.logger.warn(`See https://firebase.google.com/docs/data-connect/gp/web-sdk for more details of how to configure generated SDKs.`);
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
for (const conn of serviceInfo.connectorInfo) {
|
|
35
37
|
const output = await dataconnectEmulator_1.DataConnectEmulator.generate({
|
|
36
38
|
configDir,
|
|
37
|
-
locationId: service.location,
|
|
38
39
|
connectorId: conn.connectorYaml.connectorId,
|
|
39
40
|
});
|
|
40
41
|
logger_1.logger.info(output);
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const path = require("path");
|
|
6
4
|
const marked_1 = require("marked");
|
|
7
5
|
const TerminalRenderer = require("marked-terminal");
|
|
8
6
|
const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
@@ -12,19 +10,18 @@ const error_1 = require("../error");
|
|
|
12
10
|
const prompt_1 = require("../prompt");
|
|
13
11
|
const logger_1 = require("../logger");
|
|
14
12
|
const npmDependencies = require("../init/features/functions/npm-dependencies");
|
|
13
|
+
const templates_1 = require("../templates");
|
|
15
14
|
marked_1.marked.setOptions({
|
|
16
15
|
renderer: new TerminalRenderer(),
|
|
17
16
|
});
|
|
18
|
-
const TEMPLATE_ROOT = path.resolve(__dirname, "../../templates/extensions/");
|
|
19
|
-
const FUNCTIONS_ROOT = path.resolve(__dirname, "../../templates/init/functions/");
|
|
20
17
|
function readCommonTemplates() {
|
|
21
18
|
return {
|
|
22
|
-
integrationTestFirebaseJsonTemplate:
|
|
23
|
-
integrationTestEnvTemplate:
|
|
24
|
-
extSpecTemplate:
|
|
25
|
-
preinstallTemplate:
|
|
26
|
-
postinstallTemplate:
|
|
27
|
-
changelogTemplate:
|
|
19
|
+
integrationTestFirebaseJsonTemplate: (0, templates_1.readTemplateSync)("extensions/integration-test.json"),
|
|
20
|
+
integrationTestEnvTemplate: (0, templates_1.readTemplateSync)("extensions/integration-test.env"),
|
|
21
|
+
extSpecTemplate: (0, templates_1.readTemplateSync)("extensions/extension.yaml"),
|
|
22
|
+
preinstallTemplate: (0, templates_1.readTemplateSync)("extensions/PREINSTALL.md"),
|
|
23
|
+
postinstallTemplate: (0, templates_1.readTemplateSync)("extensions/POSTINSTALL.md"),
|
|
24
|
+
changelogTemplate: (0, templates_1.readTemplateSync)("extensions/CL-template.md"),
|
|
28
25
|
};
|
|
29
26
|
}
|
|
30
27
|
exports.command = new command_1.Command("ext:dev:init")
|
|
@@ -34,6 +31,7 @@ exports.command = new command_1.Command("ext:dev:init")
|
|
|
34
31
|
const cwd = options.cwd || process.cwd();
|
|
35
32
|
const config = new config_1.Config({}, { projectDir: cwd, cwd: cwd });
|
|
36
33
|
try {
|
|
34
|
+
let welcome;
|
|
37
35
|
const lang = await (0, prompt_1.promptOnce)({
|
|
38
36
|
type: "list",
|
|
39
37
|
name: "language",
|
|
@@ -53,10 +51,12 @@ exports.command = new command_1.Command("ext:dev:init")
|
|
|
53
51
|
switch (lang) {
|
|
54
52
|
case "javascript": {
|
|
55
53
|
await javascriptSelected(config);
|
|
54
|
+
welcome = (0, templates_1.readTemplateSync)("extensions/javascript/WELCOME.md");
|
|
56
55
|
break;
|
|
57
56
|
}
|
|
58
57
|
case "typescript": {
|
|
59
58
|
await typescriptSelected(config);
|
|
59
|
+
welcome = (0, templates_1.readTemplateSync)("extensions/typescript/WELCOME.md");
|
|
60
60
|
break;
|
|
61
61
|
}
|
|
62
62
|
default: {
|
|
@@ -64,7 +64,6 @@ exports.command = new command_1.Command("ext:dev:init")
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
await npmDependencies.askInstallDependencies({ source: "functions" }, config);
|
|
67
|
-
const welcome = fs.readFileSync(path.join(TEMPLATE_ROOT, lang, "WELCOME.md"), "utf8");
|
|
68
67
|
return logger_1.logger.info("\n" + (0, marked_1.marked)(welcome));
|
|
69
68
|
}
|
|
70
69
|
catch (err) {
|
|
@@ -77,15 +76,15 @@ exports.command = new command_1.Command("ext:dev:init")
|
|
|
77
76
|
}
|
|
78
77
|
});
|
|
79
78
|
async function typescriptSelected(config) {
|
|
80
|
-
const packageLintingTemplate =
|
|
81
|
-
const packageNoLintingTemplate =
|
|
82
|
-
const tsconfigTemplate =
|
|
83
|
-
const tsconfigDevTemplate =
|
|
84
|
-
const indexTemplate =
|
|
85
|
-
const integrationTestTemplate =
|
|
86
|
-
const gitignoreTemplate =
|
|
87
|
-
const mocharcTemplate =
|
|
88
|
-
const eslintTemplate =
|
|
79
|
+
const packageLintingTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/package.lint.json");
|
|
80
|
+
const packageNoLintingTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/package.nolint.json");
|
|
81
|
+
const tsconfigTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/tsconfig.json");
|
|
82
|
+
const tsconfigDevTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/tsconfig.dev.json");
|
|
83
|
+
const indexTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/index.ts");
|
|
84
|
+
const integrationTestTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/integration-test.ts");
|
|
85
|
+
const gitignoreTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/_gitignore");
|
|
86
|
+
const mocharcTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/_mocharc");
|
|
87
|
+
const eslintTemplate = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
|
|
89
88
|
const lint = await (0, prompt_1.promptOnce)({
|
|
90
89
|
name: "lint",
|
|
91
90
|
type: "confirm",
|
|
@@ -116,12 +115,12 @@ async function typescriptSelected(config) {
|
|
|
116
115
|
await config.askWriteProjectFile("functions/.gitignore", gitignoreTemplate);
|
|
117
116
|
}
|
|
118
117
|
async function javascriptSelected(config) {
|
|
119
|
-
const indexTemplate =
|
|
120
|
-
const integrationTestTemplate =
|
|
121
|
-
const packageLintingTemplate =
|
|
122
|
-
const packageNoLintingTemplate =
|
|
123
|
-
const gitignoreTemplate =
|
|
124
|
-
const eslintTemplate =
|
|
118
|
+
const indexTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/index.js");
|
|
119
|
+
const integrationTestTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/integration-test.js");
|
|
120
|
+
const packageLintingTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/package.lint.json");
|
|
121
|
+
const packageNoLintingTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/package.nolint.json");
|
|
122
|
+
const gitignoreTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/_gitignore");
|
|
123
|
+
const eslintTemplate = (0, templates_1.readTemplateSync)("init/functions/javascript/_eslintrc");
|
|
125
124
|
const lint = await (0, prompt_1.promptOnce)({
|
|
126
125
|
name: "lint",
|
|
127
126
|
type: "confirm",
|
package/lib/commands/init.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initAction = exports.command = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const fs = require("fs");
|
|
6
5
|
const os = require("os");
|
|
7
6
|
const path = require("path");
|
|
8
7
|
const command_1 = require("../command");
|
|
@@ -15,10 +14,10 @@ const requireAuth_1 = require("../requireAuth");
|
|
|
15
14
|
const fsutils = require("../fsutils");
|
|
16
15
|
const utils = require("../utils");
|
|
17
16
|
const experiments_1 = require("../experiments");
|
|
17
|
+
const templates_1 = require("../templates");
|
|
18
18
|
const homeDir = os.homedir();
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const GITIGNORE_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "_gitignore"), "utf8");
|
|
19
|
+
const BANNER_TEXT = (0, templates_1.readTemplateSync)("banner.txt");
|
|
20
|
+
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("_gitignore");
|
|
22
21
|
function isOutside(from, to) {
|
|
23
22
|
return !!/^\.\./.exec(path.relative(from, to));
|
|
24
23
|
}
|
|
@@ -78,7 +77,12 @@ if ((0, experiments_1.isEnabled)("genkit")) {
|
|
|
78
77
|
}
|
|
79
78
|
choices.push({
|
|
80
79
|
value: "dataconnect",
|
|
81
|
-
name: "Data Connect: Set up a Firebase Data Connect service
|
|
80
|
+
name: "Data Connect: Set up a Firebase Data Connect service",
|
|
81
|
+
checked: false,
|
|
82
|
+
});
|
|
83
|
+
choices.push({
|
|
84
|
+
value: "dataconnect:sdk",
|
|
85
|
+
name: "Data Connect: Set up a generated SDK for your Firebase Data Connect service",
|
|
82
86
|
checked: false,
|
|
83
87
|
});
|
|
84
88
|
const featureNames = choices.map((choice) => choice.value);
|
package/lib/config.js
CHANGED
|
@@ -18,7 +18,7 @@ const loadCJSON_1 = require("./loadCJSON");
|
|
|
18
18
|
const parseBoltRules = require("./parseBoltRules");
|
|
19
19
|
class Config {
|
|
20
20
|
constructor(src, options = {}) {
|
|
21
|
-
var _a;
|
|
21
|
+
var _a, _b;
|
|
22
22
|
this.data = {};
|
|
23
23
|
this.defaults = {};
|
|
24
24
|
this.notes = {};
|
|
@@ -54,6 +54,11 @@ class Config {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
+
if (((_b = this._src.dataconnect) === null || _b === void 0 ? void 0 : _b.location) ||
|
|
58
|
+
(Array.isArray(this._src.dataconnect) && this._src.dataconnect.some((c) => c === null || c === void 0 ? void 0 : c.location))) {
|
|
59
|
+
utils.logLabeledWarning("dataconnect", "'location' has been moved from 'firebase.json' to 'dataconnect.yaml'. " +
|
|
60
|
+
"Please remove 'dataconnect.location' from 'firebase.json' and add it as top level field to 'dataconnect.yaml' instead ");
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
materialize(target) {
|
|
59
64
|
const val = _.get(this._src, target);
|
|
@@ -11,12 +11,11 @@ function readFirebaseJson(config) {
|
|
|
11
11
|
return [];
|
|
12
12
|
}
|
|
13
13
|
const validator = (cfg) => {
|
|
14
|
-
if (!cfg["source"]
|
|
15
|
-
throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source`
|
|
14
|
+
if (!cfg["source"]) {
|
|
15
|
+
throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source`");
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
18
18
|
source: cfg["source"],
|
|
19
|
-
location: cfg["location"],
|
|
20
19
|
};
|
|
21
20
|
};
|
|
22
21
|
const configs = config.get("dataconnect");
|
|
@@ -27,7 +26,7 @@ function readFirebaseJson(config) {
|
|
|
27
26
|
return configs.map(validator);
|
|
28
27
|
}
|
|
29
28
|
else {
|
|
30
|
-
throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string
|
|
29
|
+
throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string }");
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
exports.readFirebaseJson = readFirebaseJson;
|
|
@@ -38,6 +37,9 @@ async function readDataConnectYaml(sourceDirectory) {
|
|
|
38
37
|
}
|
|
39
38
|
exports.readDataConnectYaml = readDataConnectYaml;
|
|
40
39
|
function validateDataConnectYaml(unvalidated) {
|
|
40
|
+
if (!unvalidated["location"]) {
|
|
41
|
+
throw new error_1.FirebaseError("Missing required field 'location' in dataconnect.yaml");
|
|
42
|
+
}
|
|
41
43
|
return unvalidated;
|
|
42
44
|
}
|
|
43
45
|
async function readConnectorYaml(sourceDirectory) {
|
|
@@ -74,13 +76,13 @@ async function pickService(projectId, config, serviceId) {
|
|
|
74
76
|
throw new error_1.FirebaseError("No Data Connect services found in firebase.json.");
|
|
75
77
|
}
|
|
76
78
|
else if (serviceCfgs.length === 1) {
|
|
77
|
-
serviceInfo = await (0, load_1.load)(projectId, serviceCfgs[0].
|
|
79
|
+
serviceInfo = await (0, load_1.load)(projectId, serviceCfgs[0].source);
|
|
78
80
|
}
|
|
79
81
|
else {
|
|
80
82
|
if (!serviceId) {
|
|
81
83
|
throw new error_1.FirebaseError("Multiple Data Connect services found in firebase.json. Please specify a service ID to use.");
|
|
82
84
|
}
|
|
83
|
-
const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, c.
|
|
85
|
+
const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, c.source)));
|
|
84
86
|
const maybe = infos.find((i) => i.dataConnectYaml.serviceId === serviceId);
|
|
85
87
|
if (!maybe) {
|
|
86
88
|
throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json.`);
|
package/lib/dataconnect/load.js
CHANGED
|
@@ -4,9 +4,9 @@ exports.load = void 0;
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const fileUtils = require("./fileUtils");
|
|
6
6
|
const types_1 = require("./types");
|
|
7
|
-
async function load(projectId,
|
|
7
|
+
async function load(projectId, sourceDirectory) {
|
|
8
8
|
const dataConnectYaml = await fileUtils.readDataConnectYaml(sourceDirectory);
|
|
9
|
-
const serviceName = `projects/${projectId}/locations/${
|
|
9
|
+
const serviceName = `projects/${projectId}/locations/${dataConnectYaml.location}/services/${dataConnectYaml.serviceId}`;
|
|
10
10
|
const schemaDir = path.join(sourceDirectory, dataConnectYaml.schema.source);
|
|
11
11
|
const schemaGQLs = await fileUtils.readGQLFiles(schemaDir);
|
|
12
12
|
const connectorInfo = await Promise.all(dataConnectYaml.connectorDirs.map(async (dir) => {
|
|
@@ -14,6 +14,7 @@ async function load(projectId, locationId, sourceDirectory) {
|
|
|
14
14
|
const connectorYaml = await fileUtils.readConnectorYaml(connectorDir);
|
|
15
15
|
const connectorGqls = await fileUtils.readGQLFiles(connectorDir);
|
|
16
16
|
return {
|
|
17
|
+
directory: connectorDir,
|
|
17
18
|
connectorYaml,
|
|
18
19
|
connector: {
|
|
19
20
|
name: `${serviceName}/connectors/${connectorYaml.connectorId}`,
|
|
@@ -28,7 +29,7 @@ async function load(projectId, locationId, sourceDirectory) {
|
|
|
28
29
|
sourceDirectory,
|
|
29
30
|
schema: {
|
|
30
31
|
name: `${serviceName}/schemas/${types_1.SCHEMA_ID}`,
|
|
31
|
-
primaryDatasource: (0, types_1.toDatasource)(projectId,
|
|
32
|
+
primaryDatasource: (0, types_1.toDatasource)(projectId, dataConnectYaml.location, dataConnectYaml.schema.datasource),
|
|
32
33
|
source: {
|
|
33
34
|
files: schemaGQLs,
|
|
34
35
|
},
|
|
@@ -18,7 +18,7 @@ async function default_1(context, options) {
|
|
|
18
18
|
const serviceCfgs = (0, fileUtils_1.readFirebaseJson)(options.config);
|
|
19
19
|
utils.logLabeledBullet("dataconnect", `Preparing to deploy`);
|
|
20
20
|
const filters = (0, filters_1.getResourceFilters)(options);
|
|
21
|
-
const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId,
|
|
21
|
+
const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, path.join(options.cwd || process.cwd(), c.source))));
|
|
22
22
|
for (const si of serviceInfos) {
|
|
23
23
|
si.deploymentMetadata = await (0, build_1.build)(options, si.sourceDirectory);
|
|
24
24
|
}
|
|
@@ -13,6 +13,7 @@ const types_2 = require("../dataconnect/types");
|
|
|
13
13
|
const portUtils_1 = require("./portUtils");
|
|
14
14
|
const apiv2_1 = require("../apiv2");
|
|
15
15
|
const registry_1 = require("./registry");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
16
17
|
const load_1 = require("../dataconnect/load");
|
|
17
18
|
const utils_1 = require("../utils");
|
|
18
19
|
const events_1 = require("events");
|
|
@@ -50,7 +51,6 @@ class DataConnectEmulator {
|
|
|
50
51
|
auto_download: this.args.auto_download,
|
|
51
52
|
listen: (0, portUtils_1.listenSpecsToString)(this.args.listen),
|
|
52
53
|
config_dir: this.args.configDir,
|
|
53
|
-
service_location: this.args.locationId,
|
|
54
54
|
});
|
|
55
55
|
this.usingExistingEmulator = false;
|
|
56
56
|
}
|
|
@@ -93,16 +93,19 @@ class DataConnectEmulator {
|
|
|
93
93
|
"--logtostderr",
|
|
94
94
|
"-v=2",
|
|
95
95
|
"generate",
|
|
96
|
-
`--service_location=${args.locationId}`,
|
|
97
96
|
`--config_dir=${args.configDir}`,
|
|
98
97
|
`--connector_id=${args.connectorId}`,
|
|
99
98
|
];
|
|
100
99
|
const res = childProcess.spawnSync(commandInfo.binary, cmd, { encoding: "utf-8" });
|
|
100
|
+
logger_1.logger.info(res.stderr);
|
|
101
101
|
if (res.error) {
|
|
102
102
|
throw new error_1.FirebaseError(`Error starting up Data Connect generate: ${res.error.message}`, {
|
|
103
103
|
original: res.error,
|
|
104
104
|
});
|
|
105
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
|
+
}
|
|
106
109
|
return res.stdout;
|
|
107
110
|
}
|
|
108
111
|
static async build(args) {
|
|
@@ -140,7 +143,7 @@ class DataConnectEmulator {
|
|
|
140
143
|
if (!emuInfo) {
|
|
141
144
|
return false;
|
|
142
145
|
}
|
|
143
|
-
const serviceInfo = await (0, load_1.load)(this.args.projectId, this.args.
|
|
146
|
+
const serviceInfo = await (0, load_1.load)(this.args.projectId, this.args.configDir);
|
|
144
147
|
const sameService = emuInfo.services.find((s) => serviceInfo.dataConnectYaml.serviceId === s.serviceId);
|
|
145
148
|
if (!sameService) {
|
|
146
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'`);
|
|
@@ -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
|
}
|
|
@@ -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");
|
package/lib/init/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const featureFns = new Map([
|
|
|
11
11
|
["database", features.database],
|
|
12
12
|
["firestore", features.firestore],
|
|
13
13
|
["dataconnect", features.dataconnect],
|
|
14
|
+
["dataconnect:sdk", features.dataconnectSdk],
|
|
14
15
|
["functions", features.functions],
|
|
15
16
|
["hosting", features.hosting],
|
|
16
17
|
["storage", features.storage],
|
package/lib/listFiles.js
CHANGED
package/lib/management/apps.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deleteAppAndroidSha = exports.createAppAndroidSha = exports.listAppAndroidSha = exports.getAppConfig = exports.getAppConfigFile = exports.listFirebaseApps = exports.createWebApp = exports.createAndroidApp = exports.createIosApp = exports.getAppPlatform = exports.ShaCertificateType = exports.AppPlatform = exports.APP_LIST_PAGE_SIZE = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
4
|
const apiv2_1 = require("../apiv2");
|
|
6
5
|
const api_1 = require("../api");
|
|
7
6
|
const error_1 = require("../error");
|
|
8
7
|
const logger_1 = require("../logger");
|
|
9
8
|
const operation_poller_1 = require("../operation-poller");
|
|
9
|
+
const templates_1 = require("../templates");
|
|
10
10
|
const TIMEOUT_MILLIS = 30000;
|
|
11
11
|
exports.APP_LIST_PAGE_SIZE = 100;
|
|
12
12
|
const CREATE_APP_API_REQUEST_TIMEOUT_MILLIS = 15000;
|
|
@@ -182,7 +182,7 @@ function getAppConfigResourceString(appId, platform) {
|
|
|
182
182
|
}
|
|
183
183
|
function parseConfigFromResponse(responseBody, platform) {
|
|
184
184
|
if (platform === AppPlatform.WEB) {
|
|
185
|
-
const JS_TEMPLATE =
|
|
185
|
+
const JS_TEMPLATE = (0, templates_1.readTemplateSync)("setup/web.js");
|
|
186
186
|
return {
|
|
187
187
|
fileName: WEB_CONFIG_FILE_NAME,
|
|
188
188
|
fileContents: JS_TEMPLATE.replace("{/*--CONFIG--*/}", JSON.stringify(responseBody, null, 2)),
|
package/lib/templates.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readTemplate = exports.readTemplateSync = exports.absoluteTemplateFilePath = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
const TEMPLATE_ENCODING = "utf8";
|
|
9
|
+
function absoluteTemplateFilePath(relPath) {
|
|
10
|
+
if ((0, utils_1.isVSCodeExtension)()) {
|
|
11
|
+
return (0, path_1.resolve)(__dirname, "templates", relPath);
|
|
12
|
+
}
|
|
13
|
+
return (0, path_1.resolve)(__dirname, "../templates", relPath);
|
|
14
|
+
}
|
|
15
|
+
exports.absoluteTemplateFilePath = absoluteTemplateFilePath;
|
|
16
|
+
function readTemplateSync(relPath) {
|
|
17
|
+
return (0, fs_1.readFileSync)(absoluteTemplateFilePath(relPath), TEMPLATE_ENCODING);
|
|
18
|
+
}
|
|
19
|
+
exports.readTemplateSync = readTemplateSync;
|
|
20
|
+
function readTemplate(relPath) {
|
|
21
|
+
return (0, promises_1.readFile)(absoluteTemplateFilePath(relPath), TEMPLATE_ENCODING);
|
|
22
|
+
}
|
|
23
|
+
exports.readTemplate = readTemplate;
|
package/lib/utils.js
CHANGED
|
@@ -23,6 +23,7 @@ const configstore_1 = require("./configstore");
|
|
|
23
23
|
const error_1 = require("./error");
|
|
24
24
|
const logger_1 = require("./logger");
|
|
25
25
|
const prompt_1 = require("./prompt");
|
|
26
|
+
const templates_1 = require("./templates");
|
|
26
27
|
exports.IS_WINDOWS = process.platform === "win32";
|
|
27
28
|
const SUCCESS_CHAR = exports.IS_WINDOWS ? "+" : "✔";
|
|
28
29
|
const WARNING_CHAR = exports.IS_WINDOWS ? "!" : "⚠";
|
|
@@ -504,8 +505,7 @@ async function openInBrowser(url) {
|
|
|
504
505
|
}
|
|
505
506
|
exports.openInBrowser = openInBrowser;
|
|
506
507
|
async function openInBrowserPopup(url, buttonText) {
|
|
507
|
-
const popupPage =
|
|
508
|
-
.readFileSync(path.join(__dirname, "../templates/popup.html"), { encoding: "utf-8" })
|
|
508
|
+
const popupPage = (0, templates_1.readTemplateSync)("popup.html")
|
|
509
509
|
.replace("${url}", url)
|
|
510
510
|
.replace("${buttonText}", buttonText);
|
|
511
511
|
const port = await (0, portfinder_1.getPortPromise)();
|
package/package.json
CHANGED
|
@@ -2,7 +2,39 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"additionalProperties": false,
|
|
4
4
|
"definitions": {
|
|
5
|
-
"
|
|
5
|
+
"javascriptSdk": {
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"outputDir": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Path to the directory where generated files should be written to."
|
|
12
|
+
},
|
|
13
|
+
"package": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The package name to use for the generated code."
|
|
16
|
+
},
|
|
17
|
+
"packageJSONDir": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "The directory containining the package.json to install the generated package in."
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"kotlinSdk": {
|
|
24
|
+
"additionalProperties": true,
|
|
25
|
+
"type": "object",
|
|
26
|
+
"properties": {
|
|
27
|
+
"outputDir": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Path to the directory where generated files should be written to."
|
|
30
|
+
},
|
|
31
|
+
"package": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "The package name to use for the generated code."
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"swiftSdk": {
|
|
6
38
|
"additionalProperties": true,
|
|
7
39
|
"type": "object",
|
|
8
40
|
"properties": {
|
|
@@ -30,21 +62,21 @@
|
|
|
30
62
|
"javascriptSdk": {
|
|
31
63
|
"type": "array",
|
|
32
64
|
"items": {
|
|
33
|
-
"$ref": "#/definitions/
|
|
65
|
+
"$ref": "#/definitions/javascriptSdk"
|
|
34
66
|
},
|
|
35
67
|
"description": "Configuration for a generated Javascript SDK"
|
|
36
68
|
},
|
|
37
69
|
"kotlinSdk": {
|
|
38
70
|
"type": "array",
|
|
39
71
|
"items": {
|
|
40
|
-
"$ref": "#/definitions/
|
|
72
|
+
"$ref": "#/definitions/kotlinSdk"
|
|
41
73
|
},
|
|
42
74
|
"description": "Configuration for a generated Kotlin SDK"
|
|
43
75
|
},
|
|
44
76
|
"swiftSdk": {
|
|
45
77
|
"type": "array",
|
|
46
78
|
"items": {
|
|
47
|
-
"$ref": "#/definitions/
|
|
79
|
+
"$ref": "#/definitions/swiftSdk"
|
|
48
80
|
},
|
|
49
81
|
"description": "Configuration for a generated Swift SDK"
|
|
50
82
|
}
|
|
@@ -58,6 +58,10 @@
|
|
|
58
58
|
"type": "string",
|
|
59
59
|
"description": "The ID of the Firebase Data Connect service."
|
|
60
60
|
},
|
|
61
|
+
"location": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "The region of the Firebase Data Connect service."
|
|
64
|
+
},
|
|
61
65
|
"connectorDirs": {
|
|
62
66
|
"type": "array",
|
|
63
67
|
"items": {
|
|
@@ -276,9 +276,6 @@
|
|
|
276
276
|
{
|
|
277
277
|
"additionalProperties": false,
|
|
278
278
|
"properties": {
|
|
279
|
-
"location": {
|
|
280
|
-
"type": "string"
|
|
281
|
-
},
|
|
282
279
|
"postdeploy": {
|
|
283
280
|
"anyOf": [
|
|
284
281
|
{
|
|
@@ -310,7 +307,6 @@
|
|
|
310
307
|
}
|
|
311
308
|
},
|
|
312
309
|
"required": [
|
|
313
|
-
"location",
|
|
314
310
|
"source"
|
|
315
311
|
],
|
|
316
312
|
"type": "object"
|
|
@@ -319,9 +315,6 @@
|
|
|
319
315
|
"items": {
|
|
320
316
|
"additionalProperties": false,
|
|
321
317
|
"properties": {
|
|
322
|
-
"location": {
|
|
323
|
-
"type": "string"
|
|
324
|
-
},
|
|
325
318
|
"postdeploy": {
|
|
326
319
|
"anyOf": [
|
|
327
320
|
{
|
|
@@ -353,7 +346,6 @@
|
|
|
353
346
|
}
|
|
354
347
|
},
|
|
355
348
|
"required": [
|
|
356
|
-
"location",
|
|
357
349
|
"source"
|
|
358
350
|
],
|
|
359
351
|
"type": "object"
|
package/templates/_gitignore
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
connectorId: "__connectorId__"
|
|
2
2
|
authMode: "PUBLIC"
|
|
3
|
+
## ## Here's an example of how to add generated SDKs.
|
|
4
|
+
## ## You'll need to replace the outputDirs with ones pointing to where you want the generated code in your app.
|
|
5
|
+
# generate:
|
|
6
|
+
# javascriptSdk:
|
|
7
|
+
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
8
|
+
# package: "@firebasegen/my-connector"
|
|
9
|
+
# packageJSONDir: < Optional. Path to your Javascript app's package.json>
|
|
10
|
+
# swiftSdk:
|
|
11
|
+
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
12
|
+
# kotlinSdk:
|
|
13
|
+
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|