firebase-tools 10.2.2 → 10.4.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/commands/deploy.js +1 -1
- package/lib/commands/experimental-functions-shell.js +1 -1
- package/lib/commands/ext-configure.js +68 -7
- package/lib/commands/ext-export.js +10 -9
- package/lib/commands/ext-install.js +73 -9
- package/lib/commands/ext-uninstall.js +9 -0
- package/lib/commands/ext-update.js +58 -3
- package/lib/commands/functions-config-export.js +2 -2
- package/lib/commands/functions-shell.js +1 -1
- package/lib/commands/hosting-channel-create.js +2 -2
- package/lib/commands/hosting-channel-delete.js +2 -2
- package/lib/commands/hosting-channel-deploy.js +2 -2
- package/lib/commands/hosting-channel-list.js +2 -2
- package/lib/commands/hosting-channel-open.js +2 -2
- package/lib/commands/hosting-sites-delete.js +2 -2
- package/lib/commands/serve.js +1 -1
- package/lib/commands/target-apply.js +2 -2
- package/lib/commands/target-clear.js +2 -2
- package/lib/commands/target-remove.js +2 -2
- package/lib/commands/target.js +2 -2
- package/lib/config.js +9 -3
- package/lib/deploy/extensions/planner.js +15 -9
- package/lib/deploy/functions/backend.js +10 -1
- package/lib/deploy/functions/checkIam.js +4 -4
- package/lib/deploy/functions/prepare.js +2 -1
- package/lib/deploy/functions/release/fabricator.js +4 -4
- package/lib/deploy/functions/release/planner.js +34 -20
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +6 -1
- package/lib/deploy/functions/runtimes/node/index.js +27 -0
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +36 -13
- package/lib/deploy/functions/services/firebaseAlerts.js +30 -0
- package/lib/deploy/functions/services/index.js +9 -1
- package/lib/deploy/functions/services/storage.js +10 -4
- package/lib/deploy/functions/triggerRegionHelper.js +1 -1
- package/lib/emulator/auth/apiSpec.js +37 -0
- package/lib/emulator/commandUtils.js +2 -2
- package/lib/emulator/constants.js +1 -0
- package/lib/emulator/controller.js +9 -7
- package/lib/emulator/extensions/validation.js +37 -2
- package/lib/emulator/extensionsEmulator.js +47 -9
- package/lib/emulator/functionsEmulator.js +17 -12
- package/lib/emulator/functionsEmulatorShared.js +34 -11
- package/lib/emulator/storage/apis/firebase.js +316 -341
- package/lib/emulator/storage/apis/gcloud.js +238 -113
- package/lib/emulator/storage/crc.js +5 -1
- package/lib/emulator/storage/errors.js +9 -0
- package/lib/emulator/storage/files.js +161 -304
- package/lib/emulator/storage/index.js +25 -74
- package/lib/emulator/storage/metadata.js +63 -49
- package/lib/emulator/storage/multipart.js +62 -0
- package/lib/emulator/storage/persistence.js +78 -0
- package/lib/emulator/storage/rules/config.js +34 -0
- package/lib/emulator/storage/rules/manager.js +98 -0
- package/lib/emulator/storage/rules/runtime.js +4 -0
- package/lib/emulator/storage/rules/utils.js +48 -0
- package/lib/emulator/storage/server.js +2 -2
- package/lib/emulator/storage/upload.js +106 -0
- package/lib/extensions/askUserForParam.js +77 -28
- package/lib/extensions/emulator/optionsHelper.js +35 -3
- package/lib/extensions/extensionsHelper.js +19 -10
- package/lib/extensions/manifest.js +142 -14
- package/lib/extensions/paramHelper.js +32 -9
- package/lib/fsutils.js +14 -1
- package/lib/functions/env.js +4 -6
- package/lib/functions/events/v2.js +11 -0
- package/lib/gcp/cloudfunctions.js +20 -7
- package/lib/gcp/cloudfunctionsv2.js +30 -12
- package/lib/gcp/resourceManager.js +4 -4
- package/lib/requireConfig.js +11 -9
- package/lib/serve/functions.js +2 -1
- package/lib/utils.js +14 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/lib/deploy/extensions/params.js +0 -42
- package/lib/deploy/functions/eventTypes.js +0 -10
- package/lib/prepareUpload.js +0 -44
package/lib/commands/deploy.js
CHANGED
|
@@ -6,7 +6,7 @@ const { checkServiceAccountIam } = require("../deploy/functions/checkIam");
|
|
|
6
6
|
const checkValidTargetFilters = require("../checkValidTargetFilters");
|
|
7
7
|
const { Command } = require("../command");
|
|
8
8
|
const deploy = require("../deploy");
|
|
9
|
-
const requireConfig = require("../requireConfig");
|
|
9
|
+
const { requireConfig } = require("../requireConfig");
|
|
10
10
|
const { filterTargets } = require("../filterTargets");
|
|
11
11
|
const { requireHostingSite } = require("../requireHostingSite");
|
|
12
12
|
const VALID_TARGETS = [
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var { Command } = require("../command");
|
|
3
3
|
var { requirePermissions } = require("../requirePermissions");
|
|
4
4
|
var { actionFunction } = require("../functionsShellCommandAction");
|
|
5
|
-
var requireConfig = require("../requireConfig");
|
|
5
|
+
var { requireConfig } = require("../requireConfig");
|
|
6
6
|
module.exports = new Command("experimental:functions:shell")
|
|
7
7
|
.description("launch full Node shell with emulated functions. (Alias for `firebase functions:shell.)")
|
|
8
8
|
.option("-p, --port <port>", "the port on which to emulate functions (default: 5000)", 5000)
|
|
@@ -15,6 +15,10 @@ const paramHelper = require("../extensions/paramHelper");
|
|
|
15
15
|
const requirePermissions_1 = require("../requirePermissions");
|
|
16
16
|
const utils = require("../utils");
|
|
17
17
|
const logger_1 = require("../logger");
|
|
18
|
+
const refs = require("../extensions/refs");
|
|
19
|
+
const manifest = require("../extensions/manifest");
|
|
20
|
+
const functional_1 = require("../functional");
|
|
21
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
18
22
|
marked.setOptions({
|
|
19
23
|
renderer: new TerminalRenderer(),
|
|
20
24
|
});
|
|
@@ -22,6 +26,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
22
26
|
.description("configure an existing extension instance")
|
|
23
27
|
.withForce()
|
|
24
28
|
.option("--params <paramsFile>", "path of params file with .env format.")
|
|
29
|
+
.option("--local", "save to firebase.json rather than directly install to a Firebase project")
|
|
25
30
|
.before(requirePermissions_1.requirePermissions, [
|
|
26
31
|
"firebaseextensions.instances.update",
|
|
27
32
|
"firebaseextensions.instances.get",
|
|
@@ -29,9 +34,47 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
29
34
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
30
35
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
31
36
|
.action(async (instanceId, options) => {
|
|
37
|
+
var _a;
|
|
38
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
39
|
+
if (options.local) {
|
|
40
|
+
if (options.nonInteractive) {
|
|
41
|
+
throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead`);
|
|
42
|
+
}
|
|
43
|
+
const config = manifest.loadConfig(options);
|
|
44
|
+
const targetRef = manifest.getInstanceRef(instanceId, config);
|
|
45
|
+
const extensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(targetRef));
|
|
46
|
+
const oldParamValues = manifest.readInstanceParam({
|
|
47
|
+
instanceId,
|
|
48
|
+
projectDir: config.projectDir,
|
|
49
|
+
});
|
|
50
|
+
const [immutableParams, tbdParams] = (0, functional_1.partition)(extensionVersion.spec.params, (param) => { var _a; return (_a = param.immutable) !== null && _a !== void 0 ? _a : false; });
|
|
51
|
+
infoImmutableParams(immutableParams, oldParamValues);
|
|
52
|
+
paramHelper.setNewDefaults(tbdParams, oldParamValues);
|
|
53
|
+
const mutableParamsBindingOptions = await paramHelper.getParams({
|
|
54
|
+
projectId,
|
|
55
|
+
paramSpecs: tbdParams,
|
|
56
|
+
nonInteractive: false,
|
|
57
|
+
paramsEnvPath: ((_a = options.params) !== null && _a !== void 0 ? _a : ""),
|
|
58
|
+
instanceId,
|
|
59
|
+
reconfiguring: true,
|
|
60
|
+
});
|
|
61
|
+
const newParamOptions = Object.assign(Object.assign({}, (0, paramHelper_1.buildBindingOptionsWithBaseValue)(oldParamValues)), mutableParamsBindingOptions);
|
|
62
|
+
await manifest.writeToManifest([
|
|
63
|
+
{
|
|
64
|
+
instanceId,
|
|
65
|
+
ref: targetRef,
|
|
66
|
+
params: newParamOptions,
|
|
67
|
+
paramSpecs: extensionVersion.spec.params,
|
|
68
|
+
},
|
|
69
|
+
], config, {
|
|
70
|
+
nonInteractive: false,
|
|
71
|
+
force: true,
|
|
72
|
+
});
|
|
73
|
+
manifest.showPreviewWarning();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
32
76
|
const spinner = ora(`Configuring ${clc.bold(instanceId)}. This usually takes 3 to 5 minutes...`);
|
|
33
77
|
try {
|
|
34
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
35
78
|
let existingInstance;
|
|
36
79
|
try {
|
|
37
80
|
existingInstance = await extensionsApi.getInstance(projectId, instanceId);
|
|
@@ -45,10 +88,8 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
45
88
|
throw err;
|
|
46
89
|
}
|
|
47
90
|
const paramSpecWithNewDefaults = paramHelper.getParamsWithCurrentValuesAsDefaults(existingInstance);
|
|
48
|
-
const immutableParams = _.remove(paramSpecWithNewDefaults, (param) =>
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
const params = await paramHelper.getParams({
|
|
91
|
+
const immutableParams = _.remove(paramSpecWithNewDefaults, (param) => param.immutable);
|
|
92
|
+
const paramBindingOptions = await paramHelper.getParams({
|
|
52
93
|
projectId,
|
|
53
94
|
paramSpecs: paramSpecWithNewDefaults,
|
|
54
95
|
nonInteractive: options.nonInteractive,
|
|
@@ -56,13 +97,14 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
56
97
|
instanceId,
|
|
57
98
|
reconfiguring: true,
|
|
58
99
|
});
|
|
100
|
+
const paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
59
101
|
if (immutableParams.length) {
|
|
60
102
|
const plural = immutableParams.length > 1;
|
|
61
103
|
logger_1.logger.info(`The following param${plural ? "s are" : " is"} immutable:`);
|
|
62
104
|
for (const { param } of immutableParams) {
|
|
63
105
|
const value = _.get(existingInstance, `config.params.${param}`);
|
|
64
106
|
logger_1.logger.info(`param: ${param}, value: ${value}`);
|
|
65
|
-
|
|
107
|
+
paramBindings[param] = value;
|
|
66
108
|
}
|
|
67
109
|
logger_1.logger.info((plural
|
|
68
110
|
? "To set different values for these params"
|
|
@@ -70,10 +112,15 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
70
112
|
", uninstall the extension, then install a new instance of this extension.");
|
|
71
113
|
}
|
|
72
114
|
spinner.start();
|
|
73
|
-
const res = await extensionsApi.configureInstance({
|
|
115
|
+
const res = await extensionsApi.configureInstance({
|
|
116
|
+
projectId,
|
|
117
|
+
instanceId,
|
|
118
|
+
params: paramBindings,
|
|
119
|
+
});
|
|
74
120
|
spinner.stop();
|
|
75
121
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully configured ${clc.bold(instanceId)}.`);
|
|
76
122
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=config`)}`));
|
|
123
|
+
manifest.showDeprecationWarning();
|
|
77
124
|
return res;
|
|
78
125
|
}
|
|
79
126
|
catch (err) {
|
|
@@ -88,3 +135,17 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
88
135
|
throw err;
|
|
89
136
|
}
|
|
90
137
|
});
|
|
138
|
+
function infoImmutableParams(immutableParams, paramValues) {
|
|
139
|
+
if (!immutableParams.length) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const plural = immutableParams.length > 1;
|
|
143
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, marked(`The following param${plural ? "s are" : " is"} immutable and won't be changed:`));
|
|
144
|
+
for (const { param } of immutableParams) {
|
|
145
|
+
logger_1.logger.info(`param: ${param}, value: ${paramValues[param]}`);
|
|
146
|
+
}
|
|
147
|
+
logger_1.logger.info((plural
|
|
148
|
+
? "To set different values for these params"
|
|
149
|
+
: "To set a different value for this param") +
|
|
150
|
+
", uninstall the extension, then install a new instance of this extension.");
|
|
151
|
+
}
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
4
4
|
const command_1 = require("../command");
|
|
5
|
-
const config_1 = require("../config");
|
|
6
5
|
const planner = require("../deploy/extensions/planner");
|
|
7
|
-
const error_1 = require("../error");
|
|
8
6
|
const export_1 = require("../extensions/export");
|
|
9
7
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
10
|
-
const
|
|
8
|
+
const manifest = require("../extensions/manifest");
|
|
9
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
11
10
|
const functional_1 = require("../functional");
|
|
12
11
|
const getProjectNumber_1 = require("../getProjectNumber");
|
|
13
12
|
const logger_1 = require("../logger");
|
|
@@ -43,12 +42,14 @@ module.exports = new command_1.Command("ext:export")
|
|
|
43
42
|
logger_1.logger.info("Exiting. No changes made.");
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
const manifestSpecs = withRef.map((spec) => ({
|
|
46
|
+
instanceId: spec.instanceId,
|
|
47
|
+
ref: spec.ref,
|
|
48
|
+
params: (0, paramHelper_1.buildBindingOptionsWithBaseValue)(spec.params),
|
|
49
|
+
}));
|
|
50
|
+
const existingConfig = manifest.loadConfig(options);
|
|
51
|
+
await manifest.writeToManifest(manifestSpecs, existingConfig, {
|
|
51
52
|
nonInteractive: options.nonInteractive,
|
|
52
53
|
force: options.force,
|
|
53
|
-
});
|
|
54
|
+
}, true);
|
|
54
55
|
});
|
|
@@ -27,6 +27,8 @@ const utils = require("../utils");
|
|
|
27
27
|
const track_1 = require("../track");
|
|
28
28
|
const logger_1 = require("../logger");
|
|
29
29
|
const previews_1 = require("../previews");
|
|
30
|
+
const manifest = require("../extensions/manifest");
|
|
31
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
30
32
|
marked.setOptions({
|
|
31
33
|
renderer: new TerminalRenderer(),
|
|
32
34
|
});
|
|
@@ -38,13 +40,15 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
38
40
|
"or run with `-i` to see all available extensions.")
|
|
39
41
|
.withForce()
|
|
40
42
|
.option("--params <paramsFile>", "name of params variables file with .env format.")
|
|
43
|
+
.option("--local", "save to firebase.json rather than directly install to a Firebase project")
|
|
41
44
|
.before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.create"])
|
|
42
45
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
43
46
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
44
47
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
45
48
|
.action(async (extensionName, options) => {
|
|
49
|
+
var _a;
|
|
46
50
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
47
|
-
const paramsEnvPath = options.params;
|
|
51
|
+
const paramsEnvPath = ((_a = options.params) !== null && _a !== void 0 ? _a : "");
|
|
48
52
|
let learnMore = false;
|
|
49
53
|
if (!extensionName) {
|
|
50
54
|
if (options.interactive) {
|
|
@@ -59,12 +63,18 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
59
63
|
}
|
|
60
64
|
let source;
|
|
61
65
|
let extVersion;
|
|
66
|
+
if ((0, extensionsHelper_1.isUrlPath)(extensionName)) {
|
|
67
|
+
void (0, track_1.track)("Extension Install", "Install by url path", options.interactive ? 1 : 0);
|
|
68
|
+
}
|
|
62
69
|
if ((0, extensionsHelper_1.isLocalOrURLPath)(extensionName)) {
|
|
63
|
-
(0, track_1.track)("Extension Install", "Install by Source", options.interactive ? 1 : 0);
|
|
70
|
+
void (0, track_1.track)("Extension Install", "Install by Source", options.interactive ? 1 : 0);
|
|
71
|
+
if (options.local) {
|
|
72
|
+
throw new error_1.FirebaseError("Installing a local source locally is not supported yet, please use ext:dev:emulator commands");
|
|
73
|
+
}
|
|
64
74
|
source = await infoInstallBySource(projectId, extensionName);
|
|
65
75
|
}
|
|
66
76
|
else {
|
|
67
|
-
(0, track_1.track)("Extension Install", "Install by Extension Ref", options.interactive ? 1 : 0);
|
|
77
|
+
void (0, track_1.track)("Extension Install", "Install by Extension Ref", options.interactive ? 1 : 0);
|
|
68
78
|
extVersion = await infoInstallByReference(extensionName, options.interactive);
|
|
69
79
|
}
|
|
70
80
|
if (!(await (0, extensionsHelper_1.confirm)({
|
|
@@ -86,6 +96,27 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
86
96
|
`${spec.description}\n` +
|
|
87
97
|
`View details: https://firebase.google.com/products/extensions/${spec.name}\n`);
|
|
88
98
|
}
|
|
99
|
+
if (options.local) {
|
|
100
|
+
try {
|
|
101
|
+
return installToManifest({
|
|
102
|
+
paramsEnvPath,
|
|
103
|
+
projectId,
|
|
104
|
+
extensionName,
|
|
105
|
+
source,
|
|
106
|
+
extVersion,
|
|
107
|
+
nonInteractive: options.nonInteractive,
|
|
108
|
+
force: options.force,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (!(err instanceof error_1.FirebaseError)) {
|
|
113
|
+
throw new error_1.FirebaseError(`Error occurred saving the extension to manifest: ${err.message}`, {
|
|
114
|
+
original: err,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
89
120
|
try {
|
|
90
121
|
return installExtension({
|
|
91
122
|
paramsEnvPath,
|
|
@@ -126,7 +157,7 @@ async function infoInstallByReference(extensionName, interactive) {
|
|
|
126
157
|
const ref = refs.parse(extensionName);
|
|
127
158
|
const extension = await extensionsApi.getExtension(refs.toExtensionRef(ref));
|
|
128
159
|
if (!ref.version) {
|
|
129
|
-
(0, track_1.track)("Extension Install", "Install by Extension Version Ref", interactive ? 1 : 0);
|
|
160
|
+
void (0, track_1.track)("Extension Install", "Install by Extension Version Ref", interactive ? 1 : 0);
|
|
130
161
|
extensionName = `${extensionName}@latest`;
|
|
131
162
|
}
|
|
132
163
|
const extVersion = await extensionsApi.getExtensionVersion(extensionName);
|
|
@@ -134,6 +165,35 @@ async function infoInstallByReference(extensionName, interactive) {
|
|
|
134
165
|
await (0, warnings_1.displayWarningPrompts)(ref.publisherId, extension.registryLaunchStage, extVersion);
|
|
135
166
|
return extVersion;
|
|
136
167
|
}
|
|
168
|
+
async function installToManifest(options) {
|
|
169
|
+
const { projectId, extensionName, extVersion, paramsEnvPath, nonInteractive, force } = options;
|
|
170
|
+
const spec = extVersion === null || extVersion === void 0 ? void 0 : extVersion.spec;
|
|
171
|
+
if (!spec) {
|
|
172
|
+
throw new error_1.FirebaseError(`Could not find the extension.yaml for ${extensionName}. Please make sure this is a valid extension and try again.`);
|
|
173
|
+
}
|
|
174
|
+
const config = manifest.loadConfig(options);
|
|
175
|
+
let instanceId = spec.name;
|
|
176
|
+
while (manifest.instanceExists(instanceId, config)) {
|
|
177
|
+
instanceId = await (0, extensionsHelper_1.promptForValidInstanceId)(`${spec.name}-${(0, utils_1.getRandomString)(4)}`);
|
|
178
|
+
}
|
|
179
|
+
const paramBindingOptions = await paramHelper.getParams({
|
|
180
|
+
projectId,
|
|
181
|
+
paramSpecs: spec.params,
|
|
182
|
+
nonInteractive,
|
|
183
|
+
paramsEnvPath,
|
|
184
|
+
instanceId,
|
|
185
|
+
});
|
|
186
|
+
const ref = refs.parse(extVersion.ref);
|
|
187
|
+
await manifest.writeToManifest([
|
|
188
|
+
{
|
|
189
|
+
instanceId,
|
|
190
|
+
ref,
|
|
191
|
+
params: paramBindingOptions,
|
|
192
|
+
paramSpecs: spec.params,
|
|
193
|
+
},
|
|
194
|
+
], config, { nonInteractive, force: force !== null && force !== void 0 ? force : false });
|
|
195
|
+
manifest.showPreviewWarning();
|
|
196
|
+
}
|
|
137
197
|
async function installExtension(options) {
|
|
138
198
|
const { projectId, extensionName, source, extVersion, paramsEnvPath, nonInteractive, force } = options;
|
|
139
199
|
const spec = (source === null || source === void 0 ? void 0 : source.spec) || (extVersion === null || extVersion === void 0 ? void 0 : extVersion.spec);
|
|
@@ -201,17 +261,19 @@ async function installExtension(options) {
|
|
|
201
261
|
else {
|
|
202
262
|
choice = "installNew";
|
|
203
263
|
}
|
|
204
|
-
let
|
|
264
|
+
let paramBindingOptions;
|
|
265
|
+
let paramBindings;
|
|
205
266
|
switch (choice) {
|
|
206
267
|
case "installNew":
|
|
207
268
|
instanceId = await (0, extensionsHelper_1.promptForValidInstanceId)(`${instanceId}-${(0, utils_1.getRandomString)(4)}`);
|
|
208
|
-
|
|
269
|
+
paramBindingOptions = await paramHelper.getParams({
|
|
209
270
|
projectId,
|
|
210
271
|
paramSpecs: spec.params,
|
|
211
272
|
nonInteractive,
|
|
212
273
|
paramsEnvPath,
|
|
213
274
|
instanceId,
|
|
214
275
|
});
|
|
276
|
+
paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
215
277
|
spinner.text = "Installing your extension instance. This usually takes 3 to 5 minutes...";
|
|
216
278
|
spinner.start();
|
|
217
279
|
await extensionsApi.createInstance({
|
|
@@ -219,20 +281,21 @@ async function installExtension(options) {
|
|
|
219
281
|
instanceId,
|
|
220
282
|
extensionSource: source,
|
|
221
283
|
extensionVersionRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
|
|
222
|
-
params,
|
|
284
|
+
params: paramBindings,
|
|
223
285
|
});
|
|
224
286
|
spinner.stop();
|
|
225
287
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully installed your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
|
|
226
288
|
`Its Instance ID is ${clc.bold(instanceId)}.`);
|
|
227
289
|
break;
|
|
228
290
|
case "updateExisting":
|
|
229
|
-
|
|
291
|
+
paramBindingOptions = await paramHelper.getParams({
|
|
230
292
|
projectId,
|
|
231
293
|
paramSpecs: spec.params,
|
|
232
294
|
nonInteractive,
|
|
233
295
|
paramsEnvPath,
|
|
234
296
|
instanceId,
|
|
235
297
|
});
|
|
298
|
+
paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
236
299
|
spinner.text = "Updating your extension instance. This usually takes 3 to 5 minutes...";
|
|
237
300
|
spinner.start();
|
|
238
301
|
await (0, updateHelper_1.update)({
|
|
@@ -240,7 +303,7 @@ async function installExtension(options) {
|
|
|
240
303
|
instanceId,
|
|
241
304
|
source,
|
|
242
305
|
extRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
|
|
243
|
-
params,
|
|
306
|
+
params: paramBindings,
|
|
244
307
|
});
|
|
245
308
|
spinner.stop();
|
|
246
309
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully updated your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
|
|
@@ -253,6 +316,7 @@ async function installExtension(options) {
|
|
|
253
316
|
`which may include some required post-installation tasks: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=usage`)}`));
|
|
254
317
|
logger_1.logger.info(marked("You can run `firebase ext` to view available Firebase Extensions commands, " +
|
|
255
318
|
"including those to update, reconfigure, or delete your installed extension."));
|
|
319
|
+
manifest.showDeprecationWarning();
|
|
256
320
|
}
|
|
257
321
|
catch (err) {
|
|
258
322
|
if (spinner.isSpinning) {
|
|
@@ -16,17 +16,25 @@ const prompt_1 = require("../prompt");
|
|
|
16
16
|
const requirePermissions_1 = require("../requirePermissions");
|
|
17
17
|
const utils = require("../utils");
|
|
18
18
|
const logger_1 = require("../logger");
|
|
19
|
+
const manifest = require("../extensions/manifest");
|
|
19
20
|
marked.setOptions({
|
|
20
21
|
renderer: new TerminalRenderer(),
|
|
21
22
|
});
|
|
22
23
|
exports.default = new command_1.Command("ext:uninstall <extensionInstanceId>")
|
|
23
24
|
.description("uninstall an extension that is installed in your Firebase project by instance ID")
|
|
24
25
|
.withForce()
|
|
26
|
+
.option("--local", "remove from firebase.json rather than directly uninstall from a Firebase project")
|
|
25
27
|
.before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.delete"])
|
|
26
28
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
27
29
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
28
30
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
29
31
|
.action(async (instanceId, options) => {
|
|
32
|
+
if (options.local) {
|
|
33
|
+
const config = manifest.loadConfig(options);
|
|
34
|
+
manifest.removeFromManifest(instanceId, config);
|
|
35
|
+
manifest.showPreviewWarning();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
30
38
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
31
39
|
let instance;
|
|
32
40
|
try {
|
|
@@ -93,6 +101,7 @@ exports.default = new command_1.Command("ext:uninstall <extensionInstanceId>")
|
|
|
93
101
|
return utils.reject(`Error occurred uninstalling extension ${instanceId}`, { original: err });
|
|
94
102
|
}
|
|
95
103
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `uninstalled ${clc.bold(instanceId)}`);
|
|
104
|
+
manifest.showDeprecationWarning();
|
|
96
105
|
});
|
|
97
106
|
function consoleUninstallOnly(projectId, instanceId) {
|
|
98
107
|
const instanceURL = `https://console.firebase.google.com/project/${projectId}/extensions/instances/${instanceId}`;
|
|
@@ -22,6 +22,7 @@ const projectUtils_1 = require("../projectUtils");
|
|
|
22
22
|
const requirePermissions_1 = require("../requirePermissions");
|
|
23
23
|
const utils = require("../utils");
|
|
24
24
|
const previews_1 = require("../previews");
|
|
25
|
+
const manifest = require("../extensions/manifest");
|
|
25
26
|
marked.setOptions({
|
|
26
27
|
renderer: new TerminalRenderer(),
|
|
27
28
|
});
|
|
@@ -38,10 +39,62 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
38
39
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
39
40
|
.withForce()
|
|
40
41
|
.option("--params <paramsFile>", "name of params variables file with .env format.")
|
|
42
|
+
.option("--local", "save the update to firebase.json rather than directly update an existing Extension instance on a Firebase project")
|
|
41
43
|
.action(async (instanceId, updateSource, options) => {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
46
|
+
if (options.local) {
|
|
47
|
+
const config = manifest.loadConfig(options);
|
|
48
|
+
const oldRef = manifest.getInstanceRef(instanceId, config);
|
|
49
|
+
const oldExtensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(oldRef));
|
|
50
|
+
updateSource = (0, updateHelper_1.inferUpdateSource)(updateSource, refs.toExtensionRef(oldRef));
|
|
51
|
+
const newSourceOrigin = (0, extensionsHelper_1.getSourceOrigin)(updateSource);
|
|
52
|
+
if (![extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION, extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION_VERSION].includes(newSourceOrigin)) {
|
|
53
|
+
throw new error_1.FirebaseError(`Only updating to a published extension version is allowed`);
|
|
54
|
+
}
|
|
55
|
+
const newExtensionVersion = await extensionsApi.getExtensionVersion(updateSource);
|
|
56
|
+
if (oldExtensionVersion.ref === newExtensionVersion.ref) {
|
|
57
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `${clc.bold(instanceId)} is already up to date. Its version is ${clc.bold(newExtensionVersion.ref)}.`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `Updating ${clc.bold(instanceId)} from version ${clc.bold(oldExtensionVersion.ref)} to version ${clc.bold(newExtensionVersion.ref)}.`);
|
|
61
|
+
if (!(await (0, extensionsHelper_1.confirm)({
|
|
62
|
+
nonInteractive: options.nonInteractive,
|
|
63
|
+
force: options.force,
|
|
64
|
+
default: false,
|
|
65
|
+
}))) {
|
|
66
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "Update aborted.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const oldParamValues = manifest.readInstanceParam({
|
|
70
|
+
instanceId,
|
|
71
|
+
projectDir: config.projectDir,
|
|
72
|
+
});
|
|
73
|
+
const newParamBindingOptions = await paramHelper.getParamsForUpdate({
|
|
74
|
+
spec: oldExtensionVersion.spec,
|
|
75
|
+
newSpec: newExtensionVersion.spec,
|
|
76
|
+
currentParams: oldParamValues,
|
|
77
|
+
projectId,
|
|
78
|
+
paramsEnvPath: ((_a = options.params) !== null && _a !== void 0 ? _a : ""),
|
|
79
|
+
nonInteractive: options.nonInteractive,
|
|
80
|
+
instanceId,
|
|
81
|
+
});
|
|
82
|
+
await manifest.writeToManifest([
|
|
83
|
+
{
|
|
84
|
+
instanceId,
|
|
85
|
+
ref: refs.parse(newExtensionVersion.ref),
|
|
86
|
+
params: newParamBindingOptions,
|
|
87
|
+
paramSpecs: newExtensionVersion.spec.params,
|
|
88
|
+
},
|
|
89
|
+
], config, {
|
|
90
|
+
nonInteractive: options.nonInteractive,
|
|
91
|
+
force: true,
|
|
92
|
+
});
|
|
93
|
+
manifest.showPreviewWarning();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
42
96
|
const spinner = ora(`Updating ${clc.bold(instanceId)}. This usually takes 3 to 5 minutes...`);
|
|
43
97
|
try {
|
|
44
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
45
98
|
let existingInstance;
|
|
46
99
|
try {
|
|
47
100
|
existingInstance = await extensionsApi.getInstance(projectId, instanceId);
|
|
@@ -143,15 +196,16 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
143
196
|
}
|
|
144
197
|
}
|
|
145
198
|
const oldParamValues = Object.assign({}, existingParams);
|
|
146
|
-
const
|
|
199
|
+
const newParamBindings = await paramHelper.getParamsForUpdate({
|
|
147
200
|
spec: existingSpec,
|
|
148
201
|
newSpec,
|
|
149
202
|
currentParams: existingParams,
|
|
150
203
|
projectId,
|
|
151
|
-
paramsEnvPath: options.params,
|
|
204
|
+
paramsEnvPath: ((_b = options.params) !== null && _b !== void 0 ? _b : ""),
|
|
152
205
|
nonInteractive: options.nonInteractive,
|
|
153
206
|
instanceId,
|
|
154
207
|
});
|
|
208
|
+
const newParams = paramHelper.getBaseParamBindings(newParamBindings);
|
|
155
209
|
spinner.start();
|
|
156
210
|
const updateOptions = {
|
|
157
211
|
projectId,
|
|
@@ -170,6 +224,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
170
224
|
spinner.stop();
|
|
171
225
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully updated ${clc.bold(instanceId)}.`);
|
|
172
226
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your updated instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=usage`)}`));
|
|
227
|
+
manifest.showDeprecationWarning();
|
|
173
228
|
}
|
|
174
229
|
catch (err) {
|
|
175
230
|
if (spinner.isSpinning) {
|
|
@@ -12,7 +12,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
const functional_1 = require("../functional");
|
|
14
14
|
const configExport = require("../functions/runtimeConfigExport");
|
|
15
|
-
const
|
|
15
|
+
const requireConfig_1 = require("../requireConfig");
|
|
16
16
|
const REQUIRED_PERMISSIONS = [
|
|
17
17
|
"runtimeconfig.configs.list",
|
|
18
18
|
"runtimeconfig.configs.get",
|
|
@@ -76,7 +76,7 @@ exports.default = new command_1.Command("functions:config:export")
|
|
|
76
76
|
"runtimeconfig.variables.list",
|
|
77
77
|
"runtimeconfig.variables.get",
|
|
78
78
|
])
|
|
79
|
-
.before(requireConfig)
|
|
79
|
+
.before(requireConfig_1.requireConfig)
|
|
80
80
|
.before(requireInteractive_1.default)
|
|
81
81
|
.action(async (options) => {
|
|
82
82
|
let pInfos = configExport.getProjectInfos(options);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var { Command } = require("../command");
|
|
3
3
|
var { requirePermissions } = require("../requirePermissions");
|
|
4
4
|
var { actionFunction } = require("../functionsShellCommandAction");
|
|
5
|
-
var requireConfig = require("../requireConfig");
|
|
5
|
+
var { requireConfig } = require("../requireConfig");
|
|
6
6
|
var commandUtils = require("../emulator/commandUtils");
|
|
7
7
|
module.exports = new Command("functions:shell")
|
|
8
8
|
.description("launch full Node shell with emulated functions")
|
|
@@ -10,7 +10,7 @@ const prompt_1 = require("../prompt");
|
|
|
10
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
11
11
|
const projectUtils_1 = require("../projectUtils");
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
|
-
const
|
|
13
|
+
const requireConfig_1 = require("../requireConfig");
|
|
14
14
|
const { marked } = require("marked");
|
|
15
15
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
16
16
|
const LOG_TAG = "hosting:channel";
|
|
@@ -18,7 +18,7 @@ exports.default = new command_1.Command("hosting:channel:create [channelId]")
|
|
|
18
18
|
.description("create a Firebase Hosting channel")
|
|
19
19
|
.option("-e, --expires <duration>", "duration string (e.g. 12h or 30d) for channel expiration, max 30d")
|
|
20
20
|
.option("--site <siteId>", "site for which to create the channel")
|
|
21
|
-
.before(requireConfig)
|
|
21
|
+
.before(requireConfig_1.requireConfig)
|
|
22
22
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
23
23
|
.before(requireHostingSite_1.requireHostingSite)
|
|
24
24
|
.action(async (channelId, options) => {
|
|
@@ -9,13 +9,13 @@ const prompt_1 = require("../prompt");
|
|
|
9
9
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
10
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
11
11
|
const projectUtils_1 = require("../projectUtils");
|
|
12
|
-
const
|
|
12
|
+
const requireConfig_1 = require("../requireConfig");
|
|
13
13
|
const logger_1 = require("../logger");
|
|
14
14
|
exports.default = new command_1.Command("hosting:channel:delete <channelId>")
|
|
15
15
|
.description("delete a Firebase Hosting channel")
|
|
16
16
|
.withForce()
|
|
17
17
|
.option("--site <siteId>", "site in which the channel exists")
|
|
18
|
-
.before(requireConfig)
|
|
18
|
+
.before(requireConfig_1.requireConfig)
|
|
19
19
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
20
20
|
.before(requireHostingSite_1.requireHostingSite)
|
|
21
21
|
.action(async (channelId, options) => {
|
|
@@ -9,7 +9,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
9
9
|
const deploy = require("../deploy");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
|
-
const
|
|
12
|
+
const requireConfig_1 = require("../requireConfig");
|
|
13
13
|
const expireUtils_1 = require("../hosting/expireUtils");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
15
|
const { marked } = require("marked");
|
|
@@ -21,7 +21,7 @@ exports.default = new command_1.Command("hosting:channel:deploy [channelId]")
|
|
|
21
21
|
.option("--only <target1,target2...>", "only create previews for specified targets")
|
|
22
22
|
.option("--open", "open a browser to the channel after deploying")
|
|
23
23
|
.option("--no-authorized-domains", "do not sync channel domains with Firebase Auth")
|
|
24
|
-
.before(requireConfig)
|
|
24
|
+
.before(requireConfig_1.requireConfig)
|
|
25
25
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
26
26
|
.before(requireHostingSite_1.requireHostingSite)
|
|
27
27
|
.action(async (channelId, options) => {
|
|
@@ -7,14 +7,14 @@ const command_1 = require("../command");
|
|
|
7
7
|
const requirePermissions_1 = require("../requirePermissions");
|
|
8
8
|
const projectUtils_1 = require("../projectUtils");
|
|
9
9
|
const logger_1 = require("../logger");
|
|
10
|
-
const
|
|
10
|
+
const requireConfig_1 = require("../requireConfig");
|
|
11
11
|
const utils_1 = require("../utils");
|
|
12
12
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
13
13
|
const TABLE_HEAD = ["Channel ID", "Last Release Time", "URL", "Expire Time"];
|
|
14
14
|
exports.default = new command_1.Command("hosting:channel:list")
|
|
15
15
|
.description("list all Firebase Hosting channels for your project")
|
|
16
16
|
.option("--site <siteName>", "list channels for the specified site")
|
|
17
|
-
.before(requireConfig)
|
|
17
|
+
.before(requireConfig_1.requireConfig)
|
|
18
18
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
19
19
|
.before(requireHostingSite_1.requireHostingSite)
|
|
20
20
|
.action(async (options) => {
|
|
@@ -8,7 +8,7 @@ const error_1 = require("../error");
|
|
|
8
8
|
const api_1 = require("../hosting/api");
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
|
-
const
|
|
11
|
+
const requireConfig_1 = require("../requireConfig");
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
const prompt_1 = require("../prompt");
|
|
14
14
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
@@ -16,7 +16,7 @@ exports.default = new command_1.Command("hosting:channel:open [channelId]")
|
|
|
16
16
|
.description("opens the URL for a Firebase Hosting channel")
|
|
17
17
|
.help("if unable to open the URL in a browser, it will be displayed in the output")
|
|
18
18
|
.option("--site <siteId>", "the site to which the channel belongs")
|
|
19
|
-
.before(requireConfig)
|
|
19
|
+
.before(requireConfig_1.requireConfig)
|
|
20
20
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.get"])
|
|
21
21
|
.before(requireHostingSite_1.requireHostingSite)
|
|
22
22
|
.action(async (channelId, options) => {
|
|
@@ -8,13 +8,13 @@ const prompt_1 = require("../prompt");
|
|
|
8
8
|
const error_1 = require("../error");
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
|
-
const
|
|
11
|
+
const requireConfig_1 = require("../requireConfig");
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
13
|
const LOG_TAG = "hosting:sites";
|
|
14
14
|
exports.default = new command_1.Command("hosting:sites:delete <siteId>")
|
|
15
15
|
.description("delete a Firebase Hosting site")
|
|
16
16
|
.withForce()
|
|
17
|
-
.before(requireConfig)
|
|
17
|
+
.before(requireConfig_1.requireConfig)
|
|
18
18
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.delete"])
|
|
19
19
|
.action(async (siteId, options) => {
|
|
20
20
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
package/lib/commands/serve.js
CHANGED
|
@@ -5,7 +5,7 @@ var { Command } = require("../command");
|
|
|
5
5
|
const { logger } = require("../logger");
|
|
6
6
|
var utils = require("../utils");
|
|
7
7
|
var { requirePermissions } = require("../requirePermissions");
|
|
8
|
-
var requireConfig = require("../requireConfig");
|
|
8
|
+
var { requireConfig } = require("../requireConfig");
|
|
9
9
|
var { serve } = require("../serve/index");
|
|
10
10
|
var { filterTargets } = require("../filterTargets");
|
|
11
11
|
var { needProjectNumber } = require("../projectUtils");
|