firebase-tools 10.9.2 → 11.0.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/README.md +15 -9
- package/lib/commands/apps-sdkconfig.js +6 -2
- package/lib/commands/ext-configure.js +51 -120
- package/lib/commands/ext-dev-emulators-exec.js +11 -6
- package/lib/commands/ext-dev-emulators-start.js +10 -26
- package/lib/commands/ext-install.js +8 -197
- package/lib/commands/ext-uninstall.js +4 -93
- package/lib/commands/ext-update.js +62 -225
- package/lib/emulator/commandUtils.js +1 -1
- package/lib/emulator/controller.js +2 -2
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/extensionsEmulator.js +7 -3
- package/lib/emulator/functionsEmulator.js +1 -2
- package/lib/emulator/portUtils.js +2 -0
- package/lib/emulator/storage/crc.js +3 -0
- package/lib/emulator/storage/rules/runtime.js +1 -1
- package/lib/extensions/extensionsHelper.js +4 -5
- package/lib/extensions/manifest.js +5 -11
- package/lib/firebaseConfigValidate.js +1 -1
- package/npm-shrinkwrap.json +621 -404
- package/package.json +14 -17
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const _ = require("lodash");
|
|
4
|
-
const clc = require("cli-color");
|
|
5
|
-
const ora = require("ora");
|
|
6
3
|
const { marked } = require("marked");
|
|
7
4
|
const TerminalRenderer = require("marked-terminal");
|
|
8
5
|
const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
9
6
|
const command_1 = require("../command");
|
|
10
|
-
const error_1 = require("../error");
|
|
11
|
-
const projectUtils_1 = require("../projectUtils");
|
|
12
|
-
const extensionsApi = require("../extensions/extensionsApi");
|
|
13
|
-
const secretsUtils = require("../extensions/secretsUtils");
|
|
14
7
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
15
|
-
const prompt_1 = require("../prompt");
|
|
16
8
|
const requirePermissions_1 = require("../requirePermissions");
|
|
17
|
-
const utils = require("../utils");
|
|
18
|
-
const logger_1 = require("../logger");
|
|
19
9
|
const manifest = require("../extensions/manifest");
|
|
20
10
|
marked.setOptions({
|
|
21
11
|
renderer: new TerminalRenderer(),
|
|
@@ -23,91 +13,12 @@ marked.setOptions({
|
|
|
23
13
|
exports.default = new command_1.Command("ext:uninstall <extensionInstanceId>")
|
|
24
14
|
.description("uninstall an extension that is installed in your Firebase project by instance ID")
|
|
25
15
|
.withForce()
|
|
26
|
-
.option("--local", "remove from firebase.json rather than directly uninstall from a Firebase project")
|
|
27
16
|
.before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.delete"])
|
|
28
17
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
29
18
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
30
19
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
31
|
-
.action(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
manifest.showPreviewWarning();
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
39
|
-
let instance;
|
|
40
|
-
try {
|
|
41
|
-
instance = await extensionsApi.getInstance(projectId, instanceId);
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
if (err.status === 404) {
|
|
45
|
-
return utils.reject(`No extension instance ${instanceId} in project ${projectId}.`, {
|
|
46
|
-
exit: 1,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
throw err;
|
|
50
|
-
}
|
|
51
|
-
if (_.get(instance, "config.source.spec.name") === "pubsub-stream-bigquery") {
|
|
52
|
-
return consoleUninstallOnly(projectId, instanceId);
|
|
53
|
-
}
|
|
54
|
-
if (!options.force) {
|
|
55
|
-
const serviceAccountMessage = `Uninstalling deletes the service account used by this extension instance:\n${clc.bold(instance.serviceAccountEmail)}\n\n`;
|
|
56
|
-
const managedSecrets = await secretsUtils.getManagedSecrets(instance);
|
|
57
|
-
const resourcesMessage = _.get(instance, "config.source.spec.resources", []).length
|
|
58
|
-
? "Uninstalling deletes all extension resources created for this extension instance:\n" +
|
|
59
|
-
instance.config.source.spec.resources
|
|
60
|
-
.map((resource) => clc.bold(`- ${extensionsHelper_1.resourceTypeToNiceName[resource.type] || resource.type}: ${resource.name} \n`))
|
|
61
|
-
.join("") +
|
|
62
|
-
managedSecrets
|
|
63
|
-
.map(secretsUtils.prettySecretName)
|
|
64
|
-
.map((s) => clc.bold(`- Secret: ${s}\n`))
|
|
65
|
-
.join("") +
|
|
66
|
-
"\n"
|
|
67
|
-
: "";
|
|
68
|
-
const artifactsMessage = `The following ${clc.bold("will not")} be deleted:\n` +
|
|
69
|
-
"Any artifacts (for example, stored images) created by this extension instance.\n" +
|
|
70
|
-
"Any other project resources with which this extension instance interacted.\n";
|
|
71
|
-
const extensionDeletionMessage = `Here's what will happen when you uninstall ${clc.bold(instanceId)} from project ${clc.bold(projectId)}. Be aware that this cannot be undone.\n\n` +
|
|
72
|
-
`${serviceAccountMessage}` +
|
|
73
|
-
`${resourcesMessage}` +
|
|
74
|
-
`${artifactsMessage}`;
|
|
75
|
-
logger_1.logger.info(extensionDeletionMessage);
|
|
76
|
-
const confirmedExtensionDeletion = await (0, prompt_1.promptOnce)({
|
|
77
|
-
type: "confirm",
|
|
78
|
-
default: true,
|
|
79
|
-
message: "Are you sure that you wish to uninstall this extension?",
|
|
80
|
-
});
|
|
81
|
-
if (!confirmedExtensionDeletion) {
|
|
82
|
-
return utils.reject("Command aborted.", { exit: 1 });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const spinner = ora(` ${clc.green.bold(extensionsHelper_1.logPrefix)}: uninstalling ${clc.bold(instanceId)}. This usually takes 1 to 2 minutes...`);
|
|
86
|
-
spinner.start();
|
|
87
|
-
try {
|
|
88
|
-
spinner.info();
|
|
89
|
-
spinner.text = ` ${clc.green.bold(extensionsHelper_1.logPrefix)}: deleting your extension instance's resources.`;
|
|
90
|
-
spinner.start();
|
|
91
|
-
await extensionsApi.deleteInstance(projectId, instanceId);
|
|
92
|
-
spinner.succeed(` ${clc.green.bold(extensionsHelper_1.logPrefix)}: deleted your extension instance's resources.`);
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
if (spinner.isSpinning) {
|
|
96
|
-
spinner.fail();
|
|
97
|
-
}
|
|
98
|
-
if (err instanceof error_1.FirebaseError) {
|
|
99
|
-
throw err;
|
|
100
|
-
}
|
|
101
|
-
return utils.reject(`Error occurred uninstalling extension ${instanceId}`, { original: err });
|
|
102
|
-
}
|
|
103
|
-
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `uninstalled ${clc.bold(instanceId)}`);
|
|
104
|
-
manifest.showDeprecationWarning();
|
|
20
|
+
.action((instanceId, options) => {
|
|
21
|
+
const config = manifest.loadConfig(options);
|
|
22
|
+
manifest.removeFromManifest(instanceId, config);
|
|
23
|
+
manifest.showPostDeprecationNotice();
|
|
105
24
|
});
|
|
106
|
-
function consoleUninstallOnly(projectId, instanceId) {
|
|
107
|
-
const instanceURL = `https://console.firebase.google.com/project/${projectId}/extensions/instances/${instanceId}`;
|
|
108
|
-
const consoleUninstall = "This extension has additional uninstall checks that are not currently supported by the CLI, and can only be uninstalled through the Firebase Console. " +
|
|
109
|
-
`Please visit **[${instanceURL}](${instanceURL})** to uninstall this extension.`;
|
|
110
|
-
logger_1.logger.info("\n");
|
|
111
|
-
utils.logLabeledWarning(extensionsHelper_1.logPrefix, marked(consoleUninstall));
|
|
112
|
-
return Promise.resolve();
|
|
113
|
-
}
|
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const clc = require("cli-color");
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const { marked } = require("marked");
|
|
6
|
-
const ora = require("ora");
|
|
7
5
|
const TerminalRenderer = require("marked-terminal");
|
|
8
6
|
const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
9
7
|
const command_1 = require("../command");
|
|
10
8
|
const error_1 = require("../error");
|
|
11
|
-
const billingMigrationHelper_1 = require("../extensions/billingMigrationHelper");
|
|
12
|
-
const checkProjectBilling_1 = require("../extensions/checkProjectBilling");
|
|
13
|
-
const cloudbilling_1 = require("../gcp/cloudbilling");
|
|
14
9
|
const extensionsApi = require("../extensions/extensionsApi");
|
|
15
|
-
const secretsUtils = require("../extensions/secretsUtils");
|
|
16
|
-
const provisioningHelper = require("../extensions/provisioningHelper");
|
|
17
10
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
18
11
|
const paramHelper = require("../extensions/paramHelper");
|
|
19
12
|
const updateHelper_1 = require("../extensions/updateHelper");
|
|
@@ -39,227 +32,71 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
39
32
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
40
33
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
41
34
|
.withForce()
|
|
42
|
-
.option("--params <paramsFile>", "name of params variables file with .env format.")
|
|
43
|
-
.option("--local", "save the update to firebase.json rather than directly update an existing Extension instance on a Firebase project")
|
|
44
35
|
.action(async (instanceId, updateSource, options) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`If you've edited the extension param spec, you can edit an extension instance's params ` +
|
|
54
|
-
`interactively by running "firebase ext:configure --local {instance-id}"`);
|
|
55
|
-
}
|
|
56
|
-
const oldRef = manifest.getInstanceRef(instanceId, config);
|
|
57
|
-
const oldExtensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(oldRef));
|
|
58
|
-
updateSource = (0, updateHelper_1.inferUpdateSource)(updateSource, refs.toExtensionRef(oldRef));
|
|
59
|
-
const newSourceOrigin = (0, extensionsHelper_1.getSourceOrigin)(updateSource);
|
|
60
|
-
if (![extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION, extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION_VERSION].includes(newSourceOrigin)) {
|
|
61
|
-
throw new error_1.FirebaseError(`Only updating to a published extension version is allowed`);
|
|
62
|
-
}
|
|
63
|
-
const newExtensionVersion = await extensionsApi.getExtensionVersion(updateSource);
|
|
64
|
-
if (oldExtensionVersion.ref === newExtensionVersion.ref) {
|
|
65
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `${clc.bold(instanceId)} is already up to date. Its version is ${clc.bold(newExtensionVersion.ref)}.`);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `Updating ${clc.bold(instanceId)} from version ${clc.bold(oldExtensionVersion.ref)} to version ${clc.bold(newExtensionVersion.ref)}.`);
|
|
69
|
-
if (!(await (0, extensionsHelper_1.confirm)({
|
|
70
|
-
nonInteractive: options.nonInteractive,
|
|
71
|
-
force: options.force,
|
|
72
|
-
default: false,
|
|
73
|
-
}))) {
|
|
74
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "Update aborted.");
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const oldParamValues = manifest.readInstanceParam({
|
|
78
|
-
instanceId,
|
|
79
|
-
projectDir: config.projectDir,
|
|
80
|
-
});
|
|
81
|
-
const newParamBindingOptions = await paramHelper.getParamsForUpdate({
|
|
82
|
-
spec: oldExtensionVersion.spec,
|
|
83
|
-
newSpec: newExtensionVersion.spec,
|
|
84
|
-
currentParams: oldParamValues,
|
|
85
|
-
projectId,
|
|
86
|
-
paramsEnvPath: ((_a = options.params) !== null && _a !== void 0 ? _a : ""),
|
|
87
|
-
nonInteractive: options.nonInteractive,
|
|
88
|
-
instanceId,
|
|
89
|
-
});
|
|
90
|
-
const eventsConfig = newExtensionVersion.spec.events
|
|
91
|
-
? await askUserForEventsConfig.askForEventsConfig(newExtensionVersion.spec.events, "${param:PROJECT_ID}", instanceId)
|
|
92
|
-
: undefined;
|
|
93
|
-
if (eventsConfig) {
|
|
94
|
-
newParamBindingOptions.EVENTARC_CHANNEL = { baseValue: eventsConfig.channel };
|
|
95
|
-
newParamBindingOptions.ALLOWED_EVENT_TYPES = {
|
|
96
|
-
baseValue: eventsConfig.allowedEventTypes.join(","),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
await manifest.writeToManifest([
|
|
100
|
-
{
|
|
101
|
-
instanceId,
|
|
102
|
-
ref: refs.parse(newExtensionVersion.ref),
|
|
103
|
-
params: newParamBindingOptions,
|
|
104
|
-
extensionSpec: newExtensionVersion.spec,
|
|
105
|
-
extensionVersion: newExtensionVersion,
|
|
106
|
-
},
|
|
107
|
-
], config, {
|
|
108
|
-
nonInteractive: options.nonInteractive,
|
|
109
|
-
force: true,
|
|
110
|
-
});
|
|
111
|
-
manifest.showPreviewWarning();
|
|
112
|
-
return;
|
|
36
|
+
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
37
|
+
const config = manifest.loadConfig(options);
|
|
38
|
+
const oldRefOrPath = manifest.getInstanceTarget(instanceId, config);
|
|
39
|
+
if ((0, extensionsHelper_1.isLocalPath)(oldRefOrPath)) {
|
|
40
|
+
throw new error_1.FirebaseError(`Updating an extension with local source is not neccessary. ` +
|
|
41
|
+
`Rerun "firebase deploy" or restart the emulator after making changes to your local extension source. ` +
|
|
42
|
+
`If you've edited the extension param spec, you can edit an extension instance's params ` +
|
|
43
|
+
`interactively by running "firebase ext:configure --local {instance-id}"`);
|
|
113
44
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
throw new error_1.FirebaseError(`Instance '${clc.bold(instanceId)}' cannot be updated anymore because the underlying extension was unpublished from Firebase's registry of extensions. Going forward, you will only be able to re-configure or uninstall this instance.`);
|
|
121
|
-
}
|
|
122
|
-
const existingParams = existingInstance.config.params;
|
|
123
|
-
const existingSource = existingInstance.config.source.name;
|
|
124
|
-
if (existingInstance.config.extensionRef) {
|
|
125
|
-
updateSource = (0, updateHelper_1.inferUpdateSource)(updateSource, existingInstance.config.extensionRef);
|
|
126
|
-
}
|
|
127
|
-
let newSourceName;
|
|
128
|
-
const existingSourceOrigin = await (0, updateHelper_1.getExistingSourceOrigin)(projectId, instanceId, existingSpec.name, existingSource);
|
|
129
|
-
const newSourceOrigin = (0, extensionsHelper_1.getSourceOrigin)(updateSource);
|
|
130
|
-
const validUpdate = isValidUpdate(existingSourceOrigin, newSourceOrigin);
|
|
131
|
-
if (!validUpdate) {
|
|
132
|
-
throw new error_1.FirebaseError(`Cannot update from a(n) ${existingSourceOrigin} to a(n) ${newSourceOrigin}. Please provide a new source that is a(n) ${existingSourceOrigin} and try again.`);
|
|
133
|
-
}
|
|
134
|
-
switch (newSourceOrigin) {
|
|
135
|
-
case extensionsHelper_1.SourceOrigin.LOCAL:
|
|
136
|
-
if (previews_1.previews.extdev) {
|
|
137
|
-
newSourceName = await (0, updateHelper_1.updateFromLocalSource)(projectId, instanceId, updateSource, existingSpec);
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
case extensionsHelper_1.SourceOrigin.URL:
|
|
141
|
-
if (previews_1.previews.extdev) {
|
|
142
|
-
newSourceName = await (0, updateHelper_1.updateFromUrlSource)(projectId, instanceId, updateSource, existingSpec);
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
case extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION_VERSION:
|
|
146
|
-
newSourceName = await (0, updateHelper_1.updateToVersionFromPublisherSource)(projectId, instanceId, updateSource, existingSpec);
|
|
147
|
-
break;
|
|
148
|
-
case extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION:
|
|
149
|
-
newSourceName = await (0, updateHelper_1.updateFromPublisherSource)(projectId, instanceId, updateSource, existingSpec);
|
|
150
|
-
break;
|
|
151
|
-
default:
|
|
152
|
-
throw new error_1.FirebaseError(`Unknown source '${clc.bold(updateSource)}.'`);
|
|
153
|
-
}
|
|
154
|
-
if (!(await (0, extensionsHelper_1.confirm)({
|
|
155
|
-
nonInteractive: options.nonInteractive,
|
|
156
|
-
force: options.force,
|
|
157
|
-
default: true,
|
|
158
|
-
}))) {
|
|
159
|
-
throw new error_1.FirebaseError(`Update cancelled.`);
|
|
160
|
-
}
|
|
161
|
-
const newSource = await extensionsApi.getSource(newSourceName);
|
|
162
|
-
const newSpec = newSource.spec;
|
|
163
|
-
if (![extensionsHelper_1.SourceOrigin.LOCAL, extensionsHelper_1.SourceOrigin.URL].includes(newSourceOrigin) &&
|
|
164
|
-
existingSpec.version === newSpec.version) {
|
|
165
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `${clc.bold(instanceId)} is already up to date. Its version is ${clc.bold(existingSpec.version)}.`);
|
|
166
|
-
const retry = await (0, extensionsHelper_1.confirm)({
|
|
167
|
-
nonInteractive: options.nonInteractive,
|
|
168
|
-
force: options.force,
|
|
169
|
-
default: false,
|
|
170
|
-
});
|
|
171
|
-
if (!retry) {
|
|
172
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "Update aborted.");
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
await (0, updateHelper_1.displayChanges)({
|
|
177
|
-
spec: existingSpec,
|
|
178
|
-
newSpec: newSpec,
|
|
179
|
-
nonInteractive: options.nonInteractive,
|
|
180
|
-
force: options.force,
|
|
181
|
-
});
|
|
182
|
-
await provisioningHelper.checkProductsProvisioned(projectId, newSpec);
|
|
183
|
-
const usesSecrets = secretsUtils.usesSecrets(newSpec);
|
|
184
|
-
if (newSpec.billingRequired || usesSecrets) {
|
|
185
|
-
const enabled = await (0, cloudbilling_1.checkBillingEnabled)(projectId);
|
|
186
|
-
(0, billingMigrationHelper_1.displayNode10UpdateBillingNotice)(existingSpec, newSpec);
|
|
187
|
-
if (!(await (0, extensionsHelper_1.confirm)({
|
|
188
|
-
nonInteractive: options.nonInteractive,
|
|
189
|
-
force: options.force,
|
|
190
|
-
default: true,
|
|
191
|
-
}))) {
|
|
192
|
-
throw new error_1.FirebaseError("Update cancelled.");
|
|
193
|
-
}
|
|
194
|
-
if (!enabled) {
|
|
195
|
-
if (!options.nonInteractive) {
|
|
196
|
-
await (0, checkProjectBilling_1.enableBilling)(projectId);
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
throw new error_1.FirebaseError("The extension requires your project to be upgraded to the Blaze plan. " +
|
|
200
|
-
"To run this command in non-interactive mode, first upgrade your project: " +
|
|
201
|
-
marked(`https://console.cloud.google.com/billing/linkedaccount?project=${projectId}`));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (usesSecrets) {
|
|
205
|
-
await secretsUtils.ensureSecretManagerApiEnabled(options);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
const oldParamValues = Object.assign({}, existingParams);
|
|
209
|
-
const newParamBindings = await paramHelper.getParamsForUpdate({
|
|
210
|
-
spec: existingSpec,
|
|
211
|
-
newSpec,
|
|
212
|
-
currentParams: existingParams,
|
|
213
|
-
projectId,
|
|
214
|
-
paramsEnvPath: ((_b = options.params) !== null && _b !== void 0 ? _b : ""),
|
|
215
|
-
nonInteractive: options.nonInteractive,
|
|
216
|
-
instanceId,
|
|
217
|
-
});
|
|
218
|
-
const eventsConfig = newSpec.events
|
|
219
|
-
? await askUserForEventsConfig.askForEventsConfig(newSpec.events, projectId, instanceId)
|
|
220
|
-
: undefined;
|
|
221
|
-
const newParams = paramHelper.getBaseParamBindings(newParamBindings);
|
|
222
|
-
spinner.start();
|
|
223
|
-
const updateOptions = {
|
|
224
|
-
projectId,
|
|
225
|
-
instanceId,
|
|
226
|
-
canEmitEvents: eventsConfig ? true : false,
|
|
227
|
-
eventarcChannel: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.channel,
|
|
228
|
-
allowedEventTypes: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.allowedEventTypes,
|
|
229
|
-
};
|
|
230
|
-
if (newSourceName.includes("publisher")) {
|
|
231
|
-
updateOptions.extRef = refs.toExtensionVersionRef(refs.parse(newSourceName));
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
updateOptions.source = newSource;
|
|
235
|
-
}
|
|
236
|
-
if (!_.isEqual(newParams, oldParamValues)) {
|
|
237
|
-
updateOptions.params = newParams;
|
|
238
|
-
}
|
|
239
|
-
await (0, updateHelper_1.update)(updateOptions);
|
|
240
|
-
spinner.stop();
|
|
241
|
-
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully updated ${clc.bold(instanceId)}.`);
|
|
242
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your updated instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=usage`)}`));
|
|
243
|
-
manifest.showDeprecationWarning();
|
|
45
|
+
const oldRef = manifest.getInstanceRef(instanceId, config);
|
|
46
|
+
const oldExtensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(oldRef));
|
|
47
|
+
updateSource = (0, updateHelper_1.inferUpdateSource)(updateSource, refs.toExtensionRef(oldRef));
|
|
48
|
+
const newSourceOrigin = (0, extensionsHelper_1.getSourceOrigin)(updateSource);
|
|
49
|
+
if (![extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION, extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION_VERSION].includes(newSourceOrigin)) {
|
|
50
|
+
throw new error_1.FirebaseError(`Only updating to a published extension version is allowed`);
|
|
244
51
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (!(err instanceof error_1.FirebaseError)) {
|
|
250
|
-
throw new error_1.FirebaseError(`Error occurred while updating the instance: ${err.message}`, {
|
|
251
|
-
original: err,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
throw err;
|
|
52
|
+
const newExtensionVersion = await extensionsApi.getExtensionVersion(updateSource);
|
|
53
|
+
if (oldExtensionVersion.ref === newExtensionVersion.ref) {
|
|
54
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `${clc.bold(instanceId)} is already up to date. Its version is ${clc.bold(newExtensionVersion.ref)}.`);
|
|
55
|
+
return;
|
|
255
56
|
}
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
57
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `Updating ${clc.bold(instanceId)} from version ${clc.bold(oldExtensionVersion.ref)} to version ${clc.bold(newExtensionVersion.ref)}.`);
|
|
58
|
+
if (!(await (0, extensionsHelper_1.confirm)({
|
|
59
|
+
nonInteractive: options.nonInteractive,
|
|
60
|
+
force: options.force,
|
|
61
|
+
default: false,
|
|
62
|
+
}))) {
|
|
63
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "Update aborted.");
|
|
64
|
+
return;
|
|
260
65
|
}
|
|
261
|
-
|
|
262
|
-
|
|
66
|
+
const oldParamValues = manifest.readInstanceParam({
|
|
67
|
+
instanceId,
|
|
68
|
+
projectDir: config.projectDir,
|
|
69
|
+
});
|
|
70
|
+
const newParamBindingOptions = await paramHelper.getParamsForUpdate({
|
|
71
|
+
spec: oldExtensionVersion.spec,
|
|
72
|
+
newSpec: newExtensionVersion.spec,
|
|
73
|
+
currentParams: oldParamValues,
|
|
74
|
+
projectId,
|
|
75
|
+
paramsEnvPath: "",
|
|
76
|
+
nonInteractive: options.nonInteractive,
|
|
77
|
+
instanceId,
|
|
78
|
+
});
|
|
79
|
+
const eventsConfig = newExtensionVersion.spec.events
|
|
80
|
+
? await askUserForEventsConfig.askForEventsConfig(newExtensionVersion.spec.events, "${param:PROJECT_ID}", instanceId)
|
|
81
|
+
: undefined;
|
|
82
|
+
if (eventsConfig) {
|
|
83
|
+
newParamBindingOptions.EVENTARC_CHANNEL = { baseValue: eventsConfig.channel };
|
|
84
|
+
newParamBindingOptions.ALLOWED_EVENT_TYPES = {
|
|
85
|
+
baseValue: eventsConfig.allowedEventTypes.join(","),
|
|
86
|
+
};
|
|
263
87
|
}
|
|
264
|
-
|
|
265
|
-
|
|
88
|
+
await manifest.writeToManifest([
|
|
89
|
+
{
|
|
90
|
+
instanceId,
|
|
91
|
+
ref: refs.parse(newExtensionVersion.ref),
|
|
92
|
+
params: newParamBindingOptions,
|
|
93
|
+
extensionSpec: newExtensionVersion.spec,
|
|
94
|
+
extensionVersion: newExtensionVersion,
|
|
95
|
+
},
|
|
96
|
+
], config, {
|
|
97
|
+
nonInteractive: options.nonInteractive,
|
|
98
|
+
force: true,
|
|
99
|
+
});
|
|
100
|
+
manifest.showPostDeprecationNotice();
|
|
101
|
+
return;
|
|
102
|
+
});
|
|
@@ -371,5 +371,5 @@ async function checkJavaSupported() {
|
|
|
371
371
|
});
|
|
372
372
|
}
|
|
373
373
|
exports.checkJavaSupported = checkJavaSupported;
|
|
374
|
-
exports.JAVA_DEPRECATION_WARNING = "
|
|
374
|
+
exports.JAVA_DEPRECATION_WARNING = "firebase-tools no longer supports Java version before 11. " +
|
|
375
375
|
"Please upgrade to Java version 11 or above to continue using the emulators.";
|
|
@@ -219,8 +219,8 @@ async function startAll(options, showUI = true) {
|
|
|
219
219
|
const deprecationNotices = [];
|
|
220
220
|
if (targets.some(downloadableEmulators_1.requiresJava)) {
|
|
221
221
|
if (!(await commandUtils.checkJavaSupported())) {
|
|
222
|
-
utils.
|
|
223
|
-
|
|
222
|
+
utils.logLabeledError("emulators", commandUtils_1.JAVA_DEPRECATION_WARNING, "warn");
|
|
223
|
+
throw new error_1.FirebaseError(commandUtils_1.JAVA_DEPRECATION_WARNING);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
const hubLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.HUB);
|
|
@@ -18,13 +18,13 @@ const EMULATOR_INSTANCE_KILL_TIMEOUT = 4000;
|
|
|
18
18
|
const CACHE_DIR = process.env.FIREBASE_EMULATORS_PATH || path.join(os.homedir(), ".cache", "firebase", "emulators");
|
|
19
19
|
exports.DownloadDetails = {
|
|
20
20
|
database: {
|
|
21
|
-
downloadPath: path.join(CACHE_DIR, "firebase-database-emulator-v4.
|
|
22
|
-
version: "4.
|
|
21
|
+
downloadPath: path.join(CACHE_DIR, "firebase-database-emulator-v4.8.0.jar"),
|
|
22
|
+
version: "4.8.0",
|
|
23
23
|
opts: {
|
|
24
24
|
cacheDir: CACHE_DIR,
|
|
25
|
-
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v4.
|
|
26
|
-
expectedSize:
|
|
27
|
-
expectedChecksum: "
|
|
25
|
+
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v4.8.0.jar",
|
|
26
|
+
expectedSize: 33676395,
|
|
27
|
+
expectedChecksum: "e5ae0085d9c88ed14b0bd9c25fe62916",
|
|
28
28
|
namePrefix: "firebase-database-emulator",
|
|
29
29
|
},
|
|
30
30
|
},
|
|
@@ -164,7 +164,7 @@ const Commands = {
|
|
|
164
164
|
},
|
|
165
165
|
ui: {
|
|
166
166
|
binary: "node",
|
|
167
|
-
args: [getExecPath(types_1.Emulators.UI)],
|
|
167
|
+
args: ["--dns-result-order=ipv4first", getExecPath(types_1.Emulators.UI)],
|
|
168
168
|
optionalArgs: [],
|
|
169
169
|
joinArgs: false,
|
|
170
170
|
},
|
|
@@ -6,7 +6,7 @@ const os = require("os");
|
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const clc = require("cli-color");
|
|
8
8
|
const Table = require("cli-table");
|
|
9
|
-
const
|
|
9
|
+
const spawn = require("cross-spawn");
|
|
10
10
|
const planner = require("../deploy/extensions/planner");
|
|
11
11
|
const error_1 = require("../error");
|
|
12
12
|
const refs_1 = require("../extensions/refs");
|
|
@@ -110,16 +110,20 @@ class ExtensionsEmulator {
|
|
|
110
110
|
return true;
|
|
111
111
|
}
|
|
112
112
|
installAndBuildSourceCode(sourceCodePath) {
|
|
113
|
-
|
|
113
|
+
this.logger.logLabeled("DEBUG", "Extensions", `Running "npm install" for ${sourceCodePath}`);
|
|
114
|
+
const npmInstall = spawn.sync("npm", ["--prefix", `/${sourceCodePath}/functions/`, "install"], {
|
|
114
115
|
encoding: "utf8",
|
|
115
116
|
});
|
|
116
117
|
if (npmInstall.error) {
|
|
117
118
|
throw npmInstall.error;
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
+
this.logger.logLabeled("DEBUG", "Extensions", `Finished "npm install" for ${sourceCodePath}`);
|
|
121
|
+
this.logger.logLabeled("DEBUG", "Extensions", `Running "npm run gcp-build" for ${sourceCodePath}`);
|
|
122
|
+
const npmRunGCPBuild = spawn.sync("npm", ["--prefix", `/${sourceCodePath}/functions/`, "run", "gcp-build"], { encoding: "utf8" });
|
|
120
123
|
if (npmRunGCPBuild.error) {
|
|
121
124
|
throw npmRunGCPBuild.error;
|
|
122
125
|
}
|
|
126
|
+
this.logger.logLabeled("DEBUG", "Extensions", `Finished "npm run gcp-build" for ${sourceCodePath}`);
|
|
123
127
|
}
|
|
124
128
|
async getExtensionBackends() {
|
|
125
129
|
await this.readManifest();
|
|
@@ -18,7 +18,6 @@ const constants_1 = require("./constants");
|
|
|
18
18
|
const types_1 = require("./types");
|
|
19
19
|
const chokidar = require("chokidar");
|
|
20
20
|
const spawn = require("cross-spawn");
|
|
21
|
-
const child_process_1 = require("child_process");
|
|
22
21
|
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
23
22
|
const registry_1 = require("./registry");
|
|
24
23
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
@@ -605,7 +604,7 @@ class FunctionsEmulator {
|
|
|
605
604
|
let localMajorVersion = "0";
|
|
606
605
|
const localNodePath = path.join(backend.functionsDir, "node_modules/.bin/node");
|
|
607
606
|
try {
|
|
608
|
-
const localNodeOutput =
|
|
607
|
+
const localNodeOutput = spawn.sync(localNodePath, ["--version"]).stdout.toString();
|
|
609
608
|
localMajorVersion = localNodeOutput.slice(1).split(".")[0];
|
|
610
609
|
}
|
|
611
610
|
catch (err) {
|
|
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.waitForPortClosed = exports.checkPortOpen = exports.findAvailablePort = exports.suggestUnrestricted = exports.isRestricted = void 0;
|
|
4
4
|
const pf = require("portfinder");
|
|
5
5
|
const tcpport = require("tcp-port-used");
|
|
6
|
+
const dns = require("dns");
|
|
6
7
|
const error_1 = require("../error");
|
|
7
8
|
const logger_1 = require("../logger");
|
|
9
|
+
dns.setDefaultResultOrder("ipv4first");
|
|
8
10
|
const RESTRICTED_PORTS = [
|
|
9
11
|
1,
|
|
10
12
|
7,
|
|
@@ -25,6 +25,9 @@ function crc32c(bytes) {
|
|
|
25
25
|
}
|
|
26
26
|
exports.crc32c = crc32c;
|
|
27
27
|
function crc32cToString(crc32cValue) {
|
|
28
|
+
if (typeof crc32cValue === "string") {
|
|
29
|
+
crc32cValue = Number(crc32cValue);
|
|
30
|
+
}
|
|
28
31
|
return "----" + Buffer.from([crc32cValue]).toString("base64");
|
|
29
32
|
}
|
|
30
33
|
exports.crc32cToString = crc32cToString;
|
|
@@ -115,7 +115,7 @@ class StorageRulesRuntime {
|
|
|
115
115
|
}
|
|
116
116
|
});
|
|
117
117
|
(_b = this._childprocess.stdout) === null || _b === void 0 ? void 0 : _b.on("data", (buf) => {
|
|
118
|
-
const serializedRuntimeActionResponse = buf.toString("
|
|
118
|
+
const serializedRuntimeActionResponse = buf.toString("utf-8").trim();
|
|
119
119
|
if (serializedRuntimeActionResponse !== "") {
|
|
120
120
|
let rap;
|
|
121
121
|
try {
|
|
@@ -31,6 +31,7 @@ const utils_2 = require("../utils");
|
|
|
31
31
|
const changelog_1 = require("./changelog");
|
|
32
32
|
const getProjectNumber_1 = require("../getProjectNumber");
|
|
33
33
|
const constants_1 = require("../emulator/constants");
|
|
34
|
+
const planner_1 = require("../deploy/extensions/planner");
|
|
34
35
|
var SpecParamType;
|
|
35
36
|
(function (SpecParamType) {
|
|
36
37
|
SpecParamType["SELECT"] = "select";
|
|
@@ -529,15 +530,13 @@ async function diagnoseAndFixProject(options) {
|
|
|
529
530
|
}
|
|
530
531
|
}
|
|
531
532
|
exports.diagnoseAndFixProject = diagnoseAndFixProject;
|
|
532
|
-
function canonicalizeRefInput(extensionName) {
|
|
533
|
+
async function canonicalizeRefInput(extensionName) {
|
|
533
534
|
if (extensionName.split("/").length < 2) {
|
|
534
535
|
const [extensionID, version] = extensionName.split("@");
|
|
535
536
|
extensionName = `firebase/${extensionID}@${version || "latest"}`;
|
|
536
537
|
}
|
|
537
538
|
const ref = refs.parse(extensionName);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}
|
|
541
|
-
return extensionName;
|
|
539
|
+
ref.version = await (0, planner_1.resolveVersion)(ref);
|
|
540
|
+
return refs.toExtensionVersionRef(ref);
|
|
542
541
|
}
|
|
543
542
|
exports.canonicalizeRefInput = canonicalizeRefInput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.showPostDeprecationNotice = exports.readInstanceParam = exports.getInstanceRef = exports.getInstanceTarget = exports.instanceExists = exports.loadConfig = exports.removeFromManifest = exports.writeLocalSecrets = exports.writeToManifest = exports.ENV_DIRECTORY = void 0;
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const refs = require("./refs");
|
|
@@ -181,16 +181,10 @@ function readParamsFile(projectDir, fileName) {
|
|
|
181
181
|
const params = (0, paramHelper_1.readEnvFile)(paramPath);
|
|
182
182
|
return params;
|
|
183
183
|
}
|
|
184
|
-
function
|
|
185
|
-
utils.
|
|
184
|
+
function showPostDeprecationNotice() {
|
|
185
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "The behavior of ext:install, ext:update, ext:configure, and ext:uninstall has changed in firebase-tools@11.0.0. " +
|
|
186
186
|
"Instead of deploying extensions directly, " +
|
|
187
187
|
"changes to extension instances will be written to firebase.json and ./extensions/*.env. " +
|
|
188
|
-
`Then ${clc.bold("firebase deploy (--only extensions)")} will deploy the changes to your Firebase project.
|
|
189
|
-
`To access this behavior now, pass the ${clc.bold("--local")} flag.`);
|
|
188
|
+
`Then ${clc.bold("firebase deploy (--only extensions)")} will deploy the changes to your Firebase project. See https://firebase.google.com/docs/extensions/manifest for more details.`);
|
|
190
189
|
}
|
|
191
|
-
exports.
|
|
192
|
-
function showPreviewWarning() {
|
|
193
|
-
utils.logLabeledWarning(extensionsHelper_1.logPrefix, `See these changes in your Firebase Emulator by running "firebase emulators:start". ` +
|
|
194
|
-
`Run ${clc.bold("firebase deploy (--only extensions)")} to deploy the changes to your Firebase project. `);
|
|
195
|
-
}
|
|
196
|
-
exports.showPreviewWarning = showPreviewWarning;
|
|
190
|
+
exports.showPostDeprecationNotice = showPostDeprecationNotice;
|
|
@@ -8,7 +8,7 @@ const ajv = new Ajv();
|
|
|
8
8
|
let _VALIDATOR = undefined;
|
|
9
9
|
function getValidator() {
|
|
10
10
|
if (!_VALIDATOR) {
|
|
11
|
-
const schemaStr = fs.readFileSync(path.resolve(__dirname, "../schema/firebase-config.json"), "
|
|
11
|
+
const schemaStr = fs.readFileSync(path.resolve(__dirname, "../schema/firebase-config.json"), "utf-8");
|
|
12
12
|
const schema = JSON.parse(schemaStr);
|
|
13
13
|
_VALIDATOR = ajv.compile(schema);
|
|
14
14
|
}
|