firebase-tools 10.4.2 → 10.7.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/bin/firebase.js +1 -1
- package/lib/command.js +4 -4
- package/lib/commands/deploy.js +1 -1
- package/lib/commands/emulators-start.js +13 -3
- package/lib/commands/ext-configure.js +15 -5
- package/lib/commands/ext-dev-emulators-start.js +5 -1
- package/lib/commands/ext-export.js +6 -5
- package/lib/commands/ext-install.js +28 -44
- package/lib/commands/ext-update.js +9 -1
- package/lib/commands/functions-delete.js +2 -5
- package/lib/commands/functions-secrets-destroy.js +23 -3
- package/lib/commands/functions-secrets-prune.js +15 -12
- package/lib/commands/functions-secrets-set.js +51 -4
- package/lib/commands/hosting-channel-deploy.js +2 -2
- package/lib/deploy/database/deploy.js +4 -0
- package/lib/deploy/database/index.js +1 -0
- package/lib/deploy/extensions/deploy.js +4 -4
- package/lib/deploy/extensions/deploymentSummary.js +8 -5
- package/lib/deploy/extensions/planner.js +36 -9
- package/lib/deploy/extensions/prepare.js +1 -1
- package/lib/deploy/extensions/secrets.js +2 -2
- package/lib/deploy/extensions/tasks.js +60 -21
- package/lib/deploy/functions/backend.js +17 -6
- package/lib/deploy/functions/build.js +162 -0
- package/lib/deploy/functions/checkIam.js +6 -5
- package/lib/deploy/functions/deploy.js +14 -15
- package/lib/deploy/functions/ensure.js +4 -4
- package/lib/deploy/functions/functionsDeployHelper.js +54 -23
- package/lib/deploy/functions/prepare.js +92 -39
- package/lib/deploy/functions/prepareFunctionsUpload.js +16 -21
- package/lib/deploy/functions/pricing.js +6 -3
- package/lib/deploy/functions/prompts.js +1 -7
- package/lib/deploy/functions/release/fabricator.js +44 -5
- package/lib/deploy/functions/release/index.js +31 -6
- package/lib/deploy/functions/release/planner.js +10 -8
- package/lib/deploy/functions/release/reporter.js +14 -11
- package/lib/deploy/functions/runtimes/discovery/parsing.js +12 -6
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +61 -13
- package/lib/deploy/functions/runtimes/node/index.js +1 -1
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +3 -3
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +29 -24
- package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
- package/lib/deploy/functions/services/auth.js +95 -0
- package/lib/deploy/functions/services/index.js +41 -21
- package/lib/deploy/functions/services/storage.js +1 -6
- package/lib/deploy/functions/validate.js +8 -5
- package/lib/deploy/hosting/args.js +2 -0
- package/lib/deploy/hosting/convertConfig.js +37 -8
- package/lib/deploy/hosting/deploy.js +3 -3
- package/lib/deploy/hosting/prepare.js +2 -2
- package/lib/deploy/hosting/release.js +6 -2
- package/lib/deploy/index.js +82 -93
- package/lib/deploy/remoteconfig/deploy.js +4 -0
- package/lib/deploy/remoteconfig/index.js +3 -1
- package/lib/emulator/auth/operations.js +26 -20
- package/lib/emulator/auth/state.js +79 -43
- package/lib/emulator/auth/utils.js +3 -25
- package/lib/emulator/commandUtils.js +72 -2
- package/lib/emulator/controller.js +14 -5
- package/lib/emulator/downloadableEmulators.js +47 -24
- package/lib/emulator/extensions/postinstall.js +41 -0
- package/lib/emulator/extensions/validation.js +2 -2
- package/lib/emulator/extensionsEmulator.js +85 -21
- package/lib/emulator/functionsEmulator.js +79 -7
- package/lib/emulator/functionsEmulatorShared.js +36 -21
- package/lib/emulator/registry.js +34 -12
- package/lib/emulator/shared/request.js +19 -0
- package/lib/emulator/storage/apis/firebase.js +32 -35
- package/lib/emulator/storage/apis/gcloud.js +84 -66
- package/lib/emulator/storage/files.js +56 -52
- package/lib/emulator/storage/index.js +23 -3
- package/lib/emulator/storage/metadata.js +18 -8
- package/lib/emulator/storage/rules/manager.js +7 -17
- package/lib/emulator/storage/rules/utils.js +11 -3
- package/lib/emulator/storage/server.js +38 -12
- package/lib/ensureApiEnabled.js +8 -4
- package/lib/extensions/askUserForParam.js +14 -11
- package/lib/extensions/changelog.js +1 -1
- package/lib/extensions/emulator/optionsHelper.js +9 -10
- package/lib/extensions/emulator/specHelper.js +7 -1
- package/lib/extensions/emulator/triggerHelper.js +11 -14
- package/lib/extensions/extensionsApi.js +2 -1
- package/lib/extensions/extensionsHelper.js +30 -24
- package/lib/extensions/manifest.js +28 -8
- package/lib/extensions/paramHelper.js +19 -13
- package/lib/extensions/provisioningHelper.js +2 -2
- package/lib/extensions/warnings.js +3 -3
- package/lib/functions/env.js +10 -2
- package/lib/functions/events/index.js +7 -0
- package/lib/functions/events/v1.js +6 -0
- package/lib/functions/projectConfig.js +24 -3
- package/lib/functions/runtimeConfigExport.js +10 -6
- package/lib/functions/secrets.js +99 -6
- package/lib/gcp/cloudfunctions.js +37 -18
- package/lib/gcp/cloudfunctionsv2.js +41 -25
- package/lib/gcp/cloudtasks.js +5 -3
- package/lib/gcp/identityPlatform.js +44 -0
- package/lib/gcp/secretManager.js +2 -2
- package/lib/metaprogramming.js +2 -0
- package/lib/previews.js +1 -1
- package/lib/serve/hosting.js +25 -12
- package/lib/serve/index.js +6 -0
- package/lib/track.js +15 -21
- package/lib/utils.js +30 -1
- package/npm-shrinkwrap.json +44 -2
- package/package.json +4 -1
- package/schema/firebase-config.json +6 -0
- package/lib/emulator/storage/list.js +0 -18
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertConfig = void 0;
|
|
4
4
|
const error_1 = require("../../error");
|
|
5
|
+
const backend_1 = require("../functions/backend");
|
|
5
6
|
function has(obj, k) {
|
|
6
7
|
return obj[k] !== undefined;
|
|
7
8
|
}
|
|
@@ -28,7 +29,7 @@ function extractPattern(type, spec) {
|
|
|
28
29
|
}
|
|
29
30
|
throw new error_1.FirebaseError(`Cannot specify a ${type} with no pattern (either a glob or regex required).`);
|
|
30
31
|
}
|
|
31
|
-
function convertConfig(config) {
|
|
32
|
+
async function convertConfig(context, payload, config, finalize) {
|
|
32
33
|
if (Array.isArray(config)) {
|
|
33
34
|
throw new error_1.FirebaseError(`convertConfig should be given a single configuration, not an array.`, {
|
|
34
35
|
exit: 2,
|
|
@@ -38,29 +39,57 @@ function convertConfig(config) {
|
|
|
38
39
|
if (!config) {
|
|
39
40
|
return out;
|
|
40
41
|
}
|
|
42
|
+
const endpointBeingDeployed = (serviceId, region = "us-central1") => {
|
|
43
|
+
var _a, _b, _c;
|
|
44
|
+
const endpoint = (_c = (_b = (_a = payload.functions) === null || _a === void 0 ? void 0 : _a.wantBackend) === null || _b === void 0 ? void 0 : _b.endpoints[region]) === null || _c === void 0 ? void 0 : _c[serviceId];
|
|
45
|
+
if (endpoint && (0, backend_1.isHttpsTriggered)(endpoint) && endpoint.platform === "gcfv2")
|
|
46
|
+
return endpoint;
|
|
47
|
+
return undefined;
|
|
48
|
+
};
|
|
49
|
+
const matchingEndpoint = async (serviceId, region = "us-central1") => {
|
|
50
|
+
const pendingEndpoint = endpointBeingDeployed(serviceId, region);
|
|
51
|
+
if (pendingEndpoint)
|
|
52
|
+
return pendingEndpoint;
|
|
53
|
+
const backend = await (0, backend_1.existingBackend)(context);
|
|
54
|
+
return (0, backend_1.allEndpoints)(backend).find((it) => (0, backend_1.isHttpsTriggered)(it) &&
|
|
55
|
+
it.platform === "gcfv2" &&
|
|
56
|
+
it.id === serviceId &&
|
|
57
|
+
it.region === region);
|
|
58
|
+
};
|
|
41
59
|
if (Array.isArray(config.rewrites)) {
|
|
42
|
-
out.rewrites =
|
|
60
|
+
out.rewrites = [];
|
|
61
|
+
for (const rewrite of config.rewrites) {
|
|
43
62
|
const vRewrite = extractPattern("rewrite", rewrite);
|
|
44
63
|
if ("destination" in rewrite) {
|
|
45
64
|
vRewrite.path = rewrite.destination;
|
|
46
65
|
}
|
|
47
66
|
else if ("function" in rewrite) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
if (!finalize && endpointBeingDeployed(rewrite.function, rewrite.region))
|
|
68
|
+
continue;
|
|
69
|
+
const endpoint = await matchingEndpoint(rewrite.function, rewrite.region);
|
|
70
|
+
if (endpoint) {
|
|
71
|
+
vRewrite.run = { serviceId: endpoint.id, region: endpoint.region };
|
|
51
72
|
}
|
|
52
73
|
else {
|
|
53
|
-
vRewrite.
|
|
74
|
+
vRewrite.function = rewrite.function;
|
|
75
|
+
if (rewrite.region) {
|
|
76
|
+
vRewrite.functionRegion = rewrite.region;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
vRewrite.functionRegion = "us-central1";
|
|
80
|
+
}
|
|
54
81
|
}
|
|
55
82
|
}
|
|
56
83
|
else if ("dynamicLinks" in rewrite) {
|
|
57
84
|
vRewrite.dynamicLinks = rewrite.dynamicLinks;
|
|
58
85
|
}
|
|
59
86
|
else if ("run" in rewrite) {
|
|
87
|
+
if (!finalize && endpointBeingDeployed(rewrite.run.serviceId, rewrite.run.region))
|
|
88
|
+
continue;
|
|
60
89
|
vRewrite.run = Object.assign({ region: "us-central1" }, rewrite.run);
|
|
61
90
|
}
|
|
62
|
-
|
|
63
|
-
}
|
|
91
|
+
out.rewrites.push(vRewrite);
|
|
92
|
+
}
|
|
64
93
|
}
|
|
65
94
|
if (Array.isArray(config.redirects)) {
|
|
66
95
|
out.redirects = config.redirects.map((redirect) => {
|
|
@@ -5,7 +5,7 @@ const uploader_1 = require("./uploader");
|
|
|
5
5
|
const detectProjectRoot_1 = require("../../detectProjectRoot");
|
|
6
6
|
const listFiles_1 = require("../../listFiles");
|
|
7
7
|
const logger_1 = require("../../logger");
|
|
8
|
-
const
|
|
8
|
+
const track_1 = require("../../track");
|
|
9
9
|
const utils_1 = require("../../utils");
|
|
10
10
|
const clc = require("cli-color");
|
|
11
11
|
const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
@@ -63,7 +63,7 @@ async function deploy(context, options) {
|
|
|
63
63
|
await uploader.start();
|
|
64
64
|
}
|
|
65
65
|
catch (err) {
|
|
66
|
-
void track("Hosting Deploy", "failure");
|
|
66
|
+
void (0, track_1.track)("Hosting Deploy", "failure");
|
|
67
67
|
throw err;
|
|
68
68
|
}
|
|
69
69
|
finally {
|
|
@@ -75,7 +75,7 @@ async function deploy(context, options) {
|
|
|
75
75
|
(0, utils_1.logLabeledSuccess)("hosting[" + deploy.site + "]", "file upload complete");
|
|
76
76
|
const dt = Date.now() - t0;
|
|
77
77
|
logger_1.logger.debug("[hosting] deploy completed after " + dt + "ms");
|
|
78
|
-
void track("Hosting Deploy", "success", dt);
|
|
78
|
+
void (0, track_1.track)("Hosting Deploy", "success", dt);
|
|
79
79
|
return runDeploys(deploys, debugging);
|
|
80
80
|
}
|
|
81
81
|
const debugging = !!(options.debug || options.nonInteractive);
|
|
@@ -8,7 +8,7 @@ const normalizedHostingConfigs_1 = require("../../hosting/normalizedHostingConfi
|
|
|
8
8
|
const validate_1 = require("./validate");
|
|
9
9
|
const convertConfig_1 = require("./convertConfig");
|
|
10
10
|
const deploymentTool = require("../../deploymentTool");
|
|
11
|
-
async function prepare(context, options) {
|
|
11
|
+
async function prepare(context, options, payload) {
|
|
12
12
|
if (options.public) {
|
|
13
13
|
if (Array.isArray(options.config.get("hosting"))) {
|
|
14
14
|
throw new error_1.FirebaseError("Cannot specify --public option with multi-site configuration.");
|
|
@@ -30,7 +30,7 @@ async function prepare(context, options) {
|
|
|
30
30
|
const cfg = deploy.config;
|
|
31
31
|
(0, validate_1.validateDeploy)(deploy, options);
|
|
32
32
|
const data = {
|
|
33
|
-
config: (0, convertConfig_1.convertConfig)(cfg),
|
|
33
|
+
config: await (0, convertConfig_1.convertConfig)(context, payload, cfg, false),
|
|
34
34
|
labels: deploymentTool.labels(),
|
|
35
35
|
};
|
|
36
36
|
versionCreates.push(client_1.client
|
|
@@ -5,7 +5,8 @@ const client_1 = require("./client");
|
|
|
5
5
|
const logger_1 = require("../../logger");
|
|
6
6
|
const projectUtils_1 = require("../../projectUtils");
|
|
7
7
|
const utils = require("../../utils");
|
|
8
|
-
|
|
8
|
+
const convertConfig_1 = require("./convertConfig");
|
|
9
|
+
async function release(context, options, payload) {
|
|
9
10
|
if (!context.hosting || !context.hosting.deploys) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
@@ -13,7 +14,10 @@ async function release(context, options) {
|
|
|
13
14
|
logger_1.logger.debug(JSON.stringify(context.hosting.deploys, null, 2));
|
|
14
15
|
await Promise.all(context.hosting.deploys.map(async (deploy) => {
|
|
15
16
|
utils.logLabeledBullet(`hosting[${deploy.site}]`, "finalizing version...");
|
|
16
|
-
const
|
|
17
|
+
const config = await (0, convertConfig_1.convertConfig)(context, payload, deploy.config, true);
|
|
18
|
+
const data = { status: "FINALIZED", config };
|
|
19
|
+
const queryParams = { updateMask: "status,config" };
|
|
20
|
+
const finalizeResult = await client_1.client.patch(`/${deploy.version}`, data, { queryParams });
|
|
17
21
|
logger_1.logger.debug(`[hosting] finalized version for ${deploy.site}:${finalizeResult.body}`);
|
|
18
22
|
utils.logLabeledSuccess(`hosting[${deploy.site}]`, "version finalized");
|
|
19
23
|
utils.logLabeledBullet(`hosting[${deploy.site}]`, "releasing new version...");
|
package/lib/deploy/index.js
CHANGED
|
@@ -1,103 +1,92 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deploy = void 0;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
const api_1 = require("../api");
|
|
6
|
+
const cli_color_1 = require("cli-color");
|
|
7
|
+
const lodash_1 = require("lodash");
|
|
8
|
+
const projectUtils_1 = require("../projectUtils");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
const error_1 = require("../error");
|
|
11
|
+
const track_1 = require("../track");
|
|
12
|
+
const lifecycleHooks = require("./lifecycleHooks");
|
|
13
|
+
const previews_1 = require("../previews");
|
|
14
|
+
const HostingTarget = require("./hosting");
|
|
15
|
+
const DatabaseTarget = require("./database");
|
|
16
|
+
const FirestoreTarget = require("./firestore");
|
|
17
|
+
const FunctionsTarget = require("./functions");
|
|
18
|
+
const StorageTarget = require("./storage");
|
|
19
|
+
const RemoteConfigTarget = require("./remoteconfig");
|
|
20
|
+
const ExtensionsTarget = require("./extensions");
|
|
21
|
+
const TARGETS = {
|
|
22
|
+
hosting: HostingTarget,
|
|
23
|
+
database: DatabaseTarget,
|
|
24
|
+
firestore: FirestoreTarget,
|
|
25
|
+
functions: FunctionsTarget,
|
|
26
|
+
storage: StorageTarget,
|
|
27
|
+
remoteconfig: RemoteConfigTarget,
|
|
28
|
+
extensions: ExtensionsTarget,
|
|
19
29
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var _chain = function (fns, context, options, payload) {
|
|
24
|
-
var latest = (fns.shift() || _noop)(context, options, payload);
|
|
25
|
-
if (fns.length) {
|
|
26
|
-
return latest.then(function () {
|
|
27
|
-
return _chain(fns, context, options, payload);
|
|
28
|
-
});
|
|
30
|
+
const chain = async function (fns, context, options, payload) {
|
|
31
|
+
for (const latest of fns) {
|
|
32
|
+
await latest(context, options, payload);
|
|
29
33
|
}
|
|
30
|
-
return latest;
|
|
31
34
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
const deploy = async function (targetNames, options, customContext = {}) {
|
|
36
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
37
|
+
const payload = {};
|
|
38
|
+
const context = Object.assign({ projectId }, customContext);
|
|
39
|
+
const predeploys = [];
|
|
40
|
+
const prepares = [];
|
|
41
|
+
const deploys = [];
|
|
42
|
+
const releases = [];
|
|
43
|
+
const postdeploys = [];
|
|
44
|
+
const startTime = Date.now();
|
|
45
|
+
if (previews_1.previews.frameworkawareness && targetNames.includes("hosting")) {
|
|
46
|
+
const config = options.config.get("hosting");
|
|
47
|
+
if (Array.isArray(config) ? config.some((it) => it.source) : config.source) {
|
|
48
|
+
await require("firebase-frameworks").prepare(targetNames, context, options);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const targetName of targetNames) {
|
|
52
|
+
const target = TARGETS[targetName];
|
|
45
53
|
if (!target) {
|
|
46
|
-
return Promise.reject(new FirebaseError(
|
|
54
|
+
return Promise.reject(new error_1.FirebaseError((0, cli_color_1.bold)(targetName) + " is not a valid deploy target", { exit: 1 }));
|
|
47
55
|
}
|
|
48
56
|
predeploys.push(lifecycleHooks(targetName, "predeploy"));
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (target.deploy) {
|
|
53
|
-
deploys.push(target.deploy);
|
|
54
|
-
}
|
|
55
|
-
if (target.release) {
|
|
56
|
-
releases.push(target.release);
|
|
57
|
-
}
|
|
57
|
+
prepares.push(target.prepare);
|
|
58
|
+
deploys.push(target.deploy);
|
|
59
|
+
releases.push(target.release);
|
|
58
60
|
postdeploys.push(lifecycleHooks(targetName, "postdeploy"));
|
|
59
61
|
}
|
|
60
|
-
logger.info();
|
|
61
|
-
logger.info(
|
|
62
|
-
logger.info();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
utils.logSuccess(clc.underline.bold("Deploy complete!"));
|
|
90
|
-
logger.info();
|
|
91
|
-
var deployedHosting = _.includes(targetNames, "hosting");
|
|
92
|
-
logger.info(clc.bold("Project Console:"), utils.consoleUrl(options.project, "/overview"));
|
|
93
|
-
if (deployedHosting) {
|
|
94
|
-
_.each(context.hosting.deploys, function (deploy) {
|
|
95
|
-
logger.info(clc.bold("Hosting URL:"), utils.addSubdomain(api.hostingOrigin, deploy.site));
|
|
96
|
-
});
|
|
97
|
-
const versionNames = context.hosting.deploys.map((deploy) => deploy.version);
|
|
98
|
-
return { hosting: versionNames.length === 1 ? versionNames[0] : versionNames };
|
|
99
|
-
}
|
|
100
|
-
});
|
|
62
|
+
logger_1.logger.info();
|
|
63
|
+
logger_1.logger.info((0, cli_color_1.bold)((0, cli_color_1.white)("===") + " Deploying to '" + projectId + "'..."));
|
|
64
|
+
logger_1.logger.info();
|
|
65
|
+
(0, utils_1.logBullet)("deploying " + (0, cli_color_1.bold)(targetNames.join(", ")));
|
|
66
|
+
await chain(predeploys, context, options, payload);
|
|
67
|
+
await chain(prepares, context, options, payload);
|
|
68
|
+
await chain(deploys, context, options, payload);
|
|
69
|
+
await chain(releases, context, options, payload);
|
|
70
|
+
await chain(postdeploys, context, options, payload);
|
|
71
|
+
if ((0, lodash_1.has)(options, "config.notes.databaseRules")) {
|
|
72
|
+
await (0, track_1.track)("Rules Deploy", options.config.notes.databaseRules);
|
|
73
|
+
}
|
|
74
|
+
const duration = Date.now() - startTime;
|
|
75
|
+
await (0, track_1.track)("Product Deploy", [...targetNames].sort().join(","), duration);
|
|
76
|
+
logger_1.logger.info();
|
|
77
|
+
(0, utils_1.logSuccess)(cli_color_1.bold.underline("Deploy complete!"));
|
|
78
|
+
logger_1.logger.info();
|
|
79
|
+
const deployedHosting = (0, lodash_1.includes)(targetNames, "hosting");
|
|
80
|
+
logger_1.logger.info((0, cli_color_1.bold)("Project Console:"), (0, utils_1.consoleUrl)(options.project, "/overview"));
|
|
81
|
+
if (deployedHosting) {
|
|
82
|
+
(0, lodash_1.each)(context.hosting.deploys, (deploy) => {
|
|
83
|
+
logger_1.logger.info((0, cli_color_1.bold)("Hosting URL:"), (0, utils_1.addSubdomain)(api_1.hostingOrigin, deploy.site));
|
|
84
|
+
});
|
|
85
|
+
const versionNames = context.hosting.deploys.map((deploy) => deploy.version);
|
|
86
|
+
return { hosting: versionNames.length === 1 ? versionNames[0] : versionNames };
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return { hosting: undefined };
|
|
90
|
+
}
|
|
101
91
|
};
|
|
102
|
-
deploy
|
|
103
|
-
module.exports = deploy;
|
|
92
|
+
exports.deploy = deploy;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.release = exports.prepare = void 0;
|
|
3
|
+
exports.deploy = exports.release = exports.prepare = void 0;
|
|
4
4
|
const prepare_1 = require("./prepare");
|
|
5
5
|
exports.prepare = prepare_1.default;
|
|
6
6
|
const release_1 = require("./release");
|
|
7
7
|
exports.release = release_1.default;
|
|
8
|
+
const deploy_1 = require("./deploy");
|
|
9
|
+
exports.deploy = deploy_1.default;
|
|
@@ -39,6 +39,8 @@ exports.authOperations = {
|
|
|
39
39
|
projects: {
|
|
40
40
|
createSessionCookie,
|
|
41
41
|
queryAccounts,
|
|
42
|
+
getConfig,
|
|
43
|
+
updateConfig,
|
|
42
44
|
accounts: {
|
|
43
45
|
_: signUp,
|
|
44
46
|
delete: deleteAccount,
|
|
@@ -1236,28 +1238,17 @@ function getEmulatorProjectConfig(state) {
|
|
|
1236
1238
|
usageMode: state.usageMode,
|
|
1237
1239
|
};
|
|
1238
1240
|
}
|
|
1239
|
-
function updateEmulatorProjectConfig(state, reqBody) {
|
|
1241
|
+
function updateEmulatorProjectConfig(state, reqBody, ctx) {
|
|
1240
1242
|
var _a;
|
|
1241
|
-
const
|
|
1242
|
-
if (allowDuplicateEmails != null) {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
if (usageMode != null) {
|
|
1248
|
-
(0, errors_1.assert)(state instanceof state_1.AgentProjectState, "((Only top level projects can set usageMode.))");
|
|
1249
|
-
switch (usageMode) {
|
|
1250
|
-
case "PASSTHROUGH":
|
|
1251
|
-
(0, errors_1.assert)(state.getUserCount() === 0, "Users are present, unable to set passthrough mode");
|
|
1252
|
-
state.usageMode = state_1.UsageMode.PASSTHROUGH;
|
|
1253
|
-
break;
|
|
1254
|
-
case "DEFAULT":
|
|
1255
|
-
state.usageMode = state_1.UsageMode.DEFAULT;
|
|
1256
|
-
break;
|
|
1257
|
-
default:
|
|
1258
|
-
throw new errors_1.BadRequestError("Invalid usage mode provided");
|
|
1259
|
-
}
|
|
1243
|
+
const updateMask = [];
|
|
1244
|
+
if (((_a = reqBody.signIn) === null || _a === void 0 ? void 0 : _a.allowDuplicateEmails) != null) {
|
|
1245
|
+
updateMask.push("signIn.allowDuplicateEmails");
|
|
1246
|
+
}
|
|
1247
|
+
if (reqBody.usageMode) {
|
|
1248
|
+
updateMask.push("usageMode");
|
|
1260
1249
|
}
|
|
1250
|
+
ctx.params.query.updateMask = updateMask.join();
|
|
1251
|
+
updateConfig(state, reqBody, ctx);
|
|
1261
1252
|
return getEmulatorProjectConfig(state);
|
|
1262
1253
|
}
|
|
1263
1254
|
function listOobCodesInProject(state) {
|
|
@@ -1390,6 +1381,21 @@ function mfaSignInFinalize(state, reqBody) {
|
|
|
1390
1381
|
refreshToken,
|
|
1391
1382
|
};
|
|
1392
1383
|
}
|
|
1384
|
+
function getConfig(state, reqBody, ctx) {
|
|
1385
|
+
(0, errors_1.assert)(state instanceof state_1.AgentProjectState, "((Can only get top-level configurations on agent projects.))");
|
|
1386
|
+
return state.config;
|
|
1387
|
+
}
|
|
1388
|
+
function updateConfig(state, reqBody, ctx) {
|
|
1389
|
+
var _a;
|
|
1390
|
+
(0, errors_1.assert)(state instanceof state_1.AgentProjectState, "((Can only update top-level configurations on agent projects.))");
|
|
1391
|
+
for (const event in (_a = reqBody.blockingFunctions) === null || _a === void 0 ? void 0 : _a.triggers) {
|
|
1392
|
+
if (Object.prototype.hasOwnProperty.call(reqBody.blockingFunctions.triggers, event)) {
|
|
1393
|
+
(0, errors_1.assert)(Object.values(state_1.BlockingFunctionEvents).includes(event), "INVALID_BLOCKING_FUNCTION: ((Event type is invalid.))");
|
|
1394
|
+
(0, errors_1.assert)((0, utils_1.parseAbsoluteUri)(reqBody.blockingFunctions.triggers[event].functionUri), "INVALID_BLOCKING_FUNCTION: ((Expected an absolute URI with valid scheme and host.))");
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
return state.updateConfig(reqBody, ctx.params.query.updateMask);
|
|
1398
|
+
}
|
|
1393
1399
|
function coercePrimitiveToString(value) {
|
|
1394
1400
|
switch (typeof value) {
|
|
1395
1401
|
case "string":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UsageMode = exports.TenantProjectState = exports.AgentProjectState = exports.ProjectState = exports.SIGNIN_METHOD_EMAIL_LINK = exports.PROVIDER_GAME_CENTER = exports.PROVIDER_CUSTOM = exports.PROVIDER_ANONYMOUS = exports.PROVIDER_PHONE = exports.PROVIDER_PASSWORD = void 0;
|
|
3
|
+
exports.BlockingFunctionEvents = exports.UsageMode = exports.TenantProjectState = exports.AgentProjectState = exports.ProjectState = exports.SIGNIN_METHOD_EMAIL_LINK = exports.PROVIDER_GAME_CENTER = exports.PROVIDER_CUSTOM = exports.PROVIDER_ANONYMOUS = exports.PROVIDER_PHONE = exports.PROVIDER_PASSWORD = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const cloudFunctions_1 = require("./cloudFunctions");
|
|
6
6
|
const errors_1 = require("./errors");
|
|
@@ -422,25 +422,28 @@ exports.ProjectState = ProjectState;
|
|
|
422
422
|
class AgentProjectState extends ProjectState {
|
|
423
423
|
constructor(projectId) {
|
|
424
424
|
super(projectId);
|
|
425
|
-
this._oneAccountPerEmail = true;
|
|
426
|
-
this._usageMode = UsageMode.DEFAULT;
|
|
427
425
|
this.tenantProjectForTenantId = new Map();
|
|
428
426
|
this._authCloudFunction = new cloudFunctions_1.AuthCloudFunction(this.projectId);
|
|
427
|
+
this._config = {
|
|
428
|
+
signIn: { allowDuplicateEmails: false },
|
|
429
|
+
usageMode: UsageMode.DEFAULT,
|
|
430
|
+
blockingFunctions: {},
|
|
431
|
+
};
|
|
429
432
|
}
|
|
430
433
|
get authCloudFunction() {
|
|
431
434
|
return this._authCloudFunction;
|
|
432
435
|
}
|
|
433
436
|
get oneAccountPerEmail() {
|
|
434
|
-
return this.
|
|
437
|
+
return !this._config.signIn.allowDuplicateEmails;
|
|
435
438
|
}
|
|
436
439
|
set oneAccountPerEmail(oneAccountPerEmail) {
|
|
437
|
-
this.
|
|
440
|
+
this._config.signIn.allowDuplicateEmails = !oneAccountPerEmail;
|
|
438
441
|
}
|
|
439
442
|
get usageMode() {
|
|
440
|
-
return this.
|
|
443
|
+
return this._config.usageMode;
|
|
441
444
|
}
|
|
442
445
|
set usageMode(usageMode) {
|
|
443
|
-
this.
|
|
446
|
+
this._config.usageMode = usageMode;
|
|
444
447
|
}
|
|
445
448
|
get allowPasswordSignup() {
|
|
446
449
|
return true;
|
|
@@ -457,6 +460,31 @@ class AgentProjectState extends ProjectState {
|
|
|
457
460
|
get enableEmailLinkSignin() {
|
|
458
461
|
return true;
|
|
459
462
|
}
|
|
463
|
+
get config() {
|
|
464
|
+
return this._config;
|
|
465
|
+
}
|
|
466
|
+
get blockingFunctionsConfig() {
|
|
467
|
+
return this._config.blockingFunctions;
|
|
468
|
+
}
|
|
469
|
+
set blockingFunctionsConfig(blockingFunctions) {
|
|
470
|
+
this._config.blockingFunctions = blockingFunctions;
|
|
471
|
+
}
|
|
472
|
+
updateConfig(update, updateMask) {
|
|
473
|
+
var _a, _b, _c, _d;
|
|
474
|
+
if (update.usageMode) {
|
|
475
|
+
(0, errors_1.assert)(update.usageMode !== UsageMode.USAGE_MODE_UNSPECIFIED, "INVALID_USAGE_MODE: ((Invalid usage mode provided.))");
|
|
476
|
+
if (update.usageMode === UsageMode.PASSTHROUGH) {
|
|
477
|
+
(0, errors_1.assert)(this.getUserCount() === 0, "USERS_STILL_EXIST: ((Users are present, unable to set passthrough mode.))");
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (!updateMask) {
|
|
481
|
+
this.oneAccountPerEmail = (_b = !((_a = update.signIn) === null || _a === void 0 ? void 0 : _a.allowDuplicateEmails)) !== null && _b !== void 0 ? _b : true;
|
|
482
|
+
this.blockingFunctionsConfig = (_c = update.blockingFunctions) !== null && _c !== void 0 ? _c : {};
|
|
483
|
+
this.usageMode = (_d = update.usageMode) !== null && _d !== void 0 ? _d : UsageMode.DEFAULT;
|
|
484
|
+
return this.config;
|
|
485
|
+
}
|
|
486
|
+
return applyMask(updateMask, this.config, update);
|
|
487
|
+
}
|
|
460
488
|
getTenantProject(tenantId) {
|
|
461
489
|
if (!this.tenantProjectForTenantId.has(tenantId)) {
|
|
462
490
|
this.createTenantWithTenantId(tenantId, {
|
|
@@ -574,40 +602,21 @@ class TenantProjectState extends ProjectState {
|
|
|
574
602
|
};
|
|
575
603
|
return this.tenantConfig;
|
|
576
604
|
}
|
|
577
|
-
|
|
578
|
-
for (const path of paths) {
|
|
579
|
-
const fields = path.split(".");
|
|
580
|
-
let updateField = update;
|
|
581
|
-
let existingField = this._tenantConfig;
|
|
582
|
-
let field;
|
|
583
|
-
for (let i = 0; i < fields.length - 1; i++) {
|
|
584
|
-
field = fields[i];
|
|
585
|
-
if (updateField[field] == null) {
|
|
586
|
-
console.warn(`Unable to find field '${field}' in update '${updateField}`);
|
|
587
|
-
break;
|
|
588
|
-
}
|
|
589
|
-
if (Array.isArray(updateField[field]) ||
|
|
590
|
-
Object(updateField[field]) !== updateField[field]) {
|
|
591
|
-
console.warn(`Field '${field}' is singular and cannot have sub-fields`);
|
|
592
|
-
break;
|
|
593
|
-
}
|
|
594
|
-
if (!existingField[field]) {
|
|
595
|
-
existingField[field] = {};
|
|
596
|
-
}
|
|
597
|
-
updateField = updateField[field];
|
|
598
|
-
existingField = existingField[field];
|
|
599
|
-
}
|
|
600
|
-
field = fields[fields.length - 1];
|
|
601
|
-
if (updateField[field] == null) {
|
|
602
|
-
console.warn(`Unable to find field '${field}' in update '${JSON.stringify(updateField)}`);
|
|
603
|
-
continue;
|
|
604
|
-
}
|
|
605
|
-
existingField[field] = updateField[field];
|
|
606
|
-
}
|
|
607
|
-
return this.tenantConfig;
|
|
605
|
+
return applyMask(updateMask, this.tenantConfig, update);
|
|
608
606
|
}
|
|
609
607
|
}
|
|
610
608
|
exports.TenantProjectState = TenantProjectState;
|
|
609
|
+
var UsageMode;
|
|
610
|
+
(function (UsageMode) {
|
|
611
|
+
UsageMode["USAGE_MODE_UNSPECIFIED"] = "USAGE_MODE_UNSPECIFIED";
|
|
612
|
+
UsageMode["DEFAULT"] = "DEFAULT";
|
|
613
|
+
UsageMode["PASSTHROUGH"] = "PASSTHROUGH";
|
|
614
|
+
})(UsageMode = exports.UsageMode || (exports.UsageMode = {}));
|
|
615
|
+
var BlockingFunctionEvents;
|
|
616
|
+
(function (BlockingFunctionEvents) {
|
|
617
|
+
BlockingFunctionEvents["BEFORE_CREATE"] = "beforeCreate";
|
|
618
|
+
BlockingFunctionEvents["BEFORE_SIGN_IN"] = "beforeSignIn";
|
|
619
|
+
})(BlockingFunctionEvents = exports.BlockingFunctionEvents || (exports.BlockingFunctionEvents = {}));
|
|
611
620
|
function getProviderEmailsForUser(user) {
|
|
612
621
|
var _a;
|
|
613
622
|
const emails = new Set();
|
|
@@ -618,8 +627,35 @@ function getProviderEmailsForUser(user) {
|
|
|
618
627
|
});
|
|
619
628
|
return emails;
|
|
620
629
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
630
|
+
function applyMask(updateMask, dest, update) {
|
|
631
|
+
const paths = updateMask.split(",");
|
|
632
|
+
for (const path of paths) {
|
|
633
|
+
const fields = path.split(".");
|
|
634
|
+
let updateField = update;
|
|
635
|
+
let existingField = dest;
|
|
636
|
+
let field;
|
|
637
|
+
for (let i = 0; i < fields.length - 1; i++) {
|
|
638
|
+
field = fields[i];
|
|
639
|
+
if (updateField[field] == null) {
|
|
640
|
+
console.warn(`Unable to find field '${field}' in update '${updateField}`);
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
if (Array.isArray(updateField[field]) || Object(updateField[field]) !== updateField[field]) {
|
|
644
|
+
console.warn(`Field '${field}' is singular and cannot have sub-fields`);
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
if (!existingField[field]) {
|
|
648
|
+
existingField[field] = {};
|
|
649
|
+
}
|
|
650
|
+
updateField = updateField[field];
|
|
651
|
+
existingField = existingField[field];
|
|
652
|
+
}
|
|
653
|
+
field = fields[fields.length - 1];
|
|
654
|
+
if (updateField[field] == null) {
|
|
655
|
+
console.warn(`Unable to find field '${field}' in update '${JSON.stringify(updateField)}`);
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
existingField[field] = updateField[field];
|
|
659
|
+
}
|
|
660
|
+
return dest;
|
|
661
|
+
}
|
|
@@ -64,34 +64,12 @@ function logError(err) {
|
|
|
64
64
|
}
|
|
65
65
|
exports.logError = logError;
|
|
66
66
|
function authEmulatorUrl(req) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (info) {
|
|
70
|
-
if (info.host === "0.0.0.0") {
|
|
71
|
-
url.hostname = "127.0.0.1";
|
|
72
|
-
}
|
|
73
|
-
else if (info.host === "::") {
|
|
74
|
-
url.hostname = "[::1]";
|
|
75
|
-
}
|
|
76
|
-
else if (info.host.includes(":")) {
|
|
77
|
-
url.hostname = `[${info.host}]`;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
url.hostname = info.host;
|
|
81
|
-
}
|
|
82
|
-
url.port = info.port.toString();
|
|
67
|
+
if (registry_1.EmulatorRegistry.getInfo(types_1.Emulators.AUTH)) {
|
|
68
|
+
return registry_1.EmulatorRegistry.url(types_1.Emulators.AUTH);
|
|
83
69
|
}
|
|
84
70
|
else {
|
|
85
|
-
|
|
86
|
-
url.protocol = req.protocol;
|
|
87
|
-
if (host) {
|
|
88
|
-
url.host = host;
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
console.warn("Cannot determine host and port of auth emulator server.");
|
|
92
|
-
}
|
|
71
|
+
return registry_1.EmulatorRegistry.url(types_1.Emulators.AUTH, req);
|
|
93
72
|
}
|
|
94
|
-
return url;
|
|
95
73
|
}
|
|
96
74
|
exports.authEmulatorUrl = authEmulatorUrl;
|
|
97
75
|
function mirrorFieldTo(dest, field, source) {
|