firebase-tools 11.1.0 → 11.2.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/accountExporter.js +11 -4
- package/lib/accountImporter.js +5 -6
- package/lib/appdistribution/client.js +7 -9
- package/lib/auth.js +3 -5
- package/lib/checkValidTargetFilters.js +28 -18
- package/lib/commands/database-profile.js +2 -3
- package/lib/commands/database-push.js +2 -3
- package/lib/commands/database-remove.js +1 -2
- package/lib/commands/database-set.js +1 -2
- package/lib/commands/deploy.js +5 -6
- package/lib/commands/ext-dev-emulators-exec.js +1 -1
- package/lib/commands/ext-dev-emulators-start.js +1 -1
- package/lib/commands/ext-dev-list.js +6 -7
- package/lib/commands/ext-info.js +12 -13
- package/lib/commands/ext.js +2 -3
- package/lib/commands/functions-delete.js +1 -7
- package/lib/commands/open.js +5 -6
- package/lib/commands/serve.js +3 -5
- package/lib/commands/use.js +2 -3
- package/lib/config.js +4 -3
- package/lib/deploy/database/prepare.js +2 -3
- package/lib/deploy/extensions/secrets.js +3 -3
- package/lib/deploy/functions/build.js +3 -2
- package/lib/deploy/functions/ensure.js +1 -11
- package/lib/deploy/functions/prepare.js +3 -13
- package/lib/deploy/functions/prepareFunctionsUpload.js +2 -3
- package/lib/deploy/functions/release/fabricator.js +0 -1
- package/lib/deploy/functions/release/index.js +1 -5
- package/lib/deploy/functions/runtimes/discovery/index.js +18 -3
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +3 -2
- package/lib/deploy/functions/runtimes/golang/index.js +2 -22
- package/lib/deploy/functions/runtimes/node/index.js +3 -7
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +1 -1
- package/lib/deploy/lifecycleHooks.js +7 -10
- package/lib/deploy/storage/prepare.js +1 -1
- package/lib/emulator/auth/index.js +1 -1
- package/lib/emulator/auth/operations.js +336 -64
- package/lib/emulator/auth/server.js +2 -2
- package/lib/emulator/auth/state.js +32 -7
- package/lib/emulator/commandUtils.js +1 -1
- package/lib/emulator/constants.js +1 -1
- package/lib/emulator/controller.js +6 -5
- package/lib/emulator/databaseEmulator.js +2 -2
- package/lib/emulator/download.js +1 -1
- package/lib/emulator/events/types.js +2 -3
- package/lib/emulator/firestoreEmulator.js +2 -2
- package/lib/emulator/functionsEmulator.js +27 -37
- package/lib/emulator/functionsEmulatorRuntime.js +7 -7
- package/lib/emulator/hostingEmulator.js +1 -1
- package/lib/emulator/hub.js +1 -1
- package/lib/emulator/loggingEmulator.js +1 -1
- package/lib/emulator/pubsubEmulator.js +1 -1
- package/lib/emulator/storage/crc.js +4 -4
- package/lib/emulator/storage/index.js +1 -1
- package/lib/emulator/types.js +1 -1
- package/lib/extensions/askUserForConsent.js +1 -2
- package/lib/extensions/askUserForParam.js +15 -18
- package/lib/extensions/emulator/optionsHelper.js +4 -4
- package/lib/extensions/extensionsApi.js +1 -22
- package/lib/extensions/extensionsHelper.js +6 -6
- package/lib/extensions/listExtensions.js +9 -10
- package/lib/extensions/manifest.js +2 -2
- package/lib/extensions/resolveSource.js +11 -7
- package/lib/extensions/secretsUtils.js +3 -3
- package/lib/extensions/types.js +24 -0
- package/lib/extensions/updateHelper.js +1 -1
- package/lib/extensions/utils.js +1 -2
- package/lib/extensions/warnings.js +3 -3
- package/lib/firestore/encodeFirestoreValue.js +11 -8
- package/lib/fsAsync.js +3 -3
- package/lib/functionsConfig.js +17 -14
- package/lib/functionsConfigClone.js +10 -12
- package/lib/gcp/cloudfunctions.js +2 -15
- package/lib/gcp/rules.js +1 -1
- package/lib/gcp/runtimeconfig.js +2 -2
- package/lib/hosting/proxy.js +1 -1
- package/lib/init/features/hosting/github.js +1 -1
- package/lib/init/features/hosting/index.js +2 -2
- package/lib/localFunction.js +4 -4
- package/lib/previews.js +1 -1
- package/lib/profileReport.js +10 -10
- package/lib/prompt.js +1 -2
- package/lib/rc.js +1 -1
- package/lib/rulesDeploy.js +2 -2
- package/lib/serve/index.js +4 -5
- package/lib/utils.js +30 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +10 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getExtension = exports.deleteExtension = exports.unpublishExtension = exports.publishExtensionVersion = exports.undeprecateExtensionVersion = exports.deprecateExtensionVersion = exports.registerPublisherProfile = exports.getPublisherProfile = exports.listExtensionVersions = exports.listExtensions = exports.getExtensionVersion = exports.getSource = exports.createSource = exports.updateInstanceFromRegistry = exports.updateInstance = exports.configureInstance = exports.listInstances = exports.getInstance = exports.deleteInstance = exports.createInstance =
|
|
3
|
+
exports.getExtension = exports.deleteExtension = exports.unpublishExtension = exports.publishExtensionVersion = exports.undeprecateExtensionVersion = exports.deprecateExtensionVersion = exports.registerPublisherProfile = exports.getPublisherProfile = exports.listExtensionVersions = exports.listExtensions = exports.getExtensionVersion = exports.getSource = exports.createSource = exports.updateInstanceFromRegistry = exports.updateInstance = exports.configureInstance = exports.listInstances = exports.getInstance = exports.deleteInstance = exports.createInstance = void 0;
|
|
4
4
|
const yaml = require("js-yaml");
|
|
5
5
|
const clc = require("cli-color");
|
|
6
6
|
const { marked } = require("marked");
|
|
@@ -13,27 +13,6 @@ const refs = require("./refs");
|
|
|
13
13
|
const VERSION = "v1beta";
|
|
14
14
|
const PAGE_SIZE_MAX = 100;
|
|
15
15
|
const apiClient = new apiv2_1.Client({ urlPrefix: api_1.extensionsOrigin, apiVersion: VERSION });
|
|
16
|
-
var RegistryLaunchStage;
|
|
17
|
-
(function (RegistryLaunchStage) {
|
|
18
|
-
RegistryLaunchStage["EXPERIMENTAL"] = "EXPERIMENTAL";
|
|
19
|
-
RegistryLaunchStage["BETA"] = "BETA";
|
|
20
|
-
RegistryLaunchStage["GA"] = "GA";
|
|
21
|
-
RegistryLaunchStage["DEPRECATED"] = "DEPRECATED";
|
|
22
|
-
RegistryLaunchStage["REGISTRY_LAUNCH_STAGE_UNSPECIFIED"] = "REGISTRY_LAUNCH_STAGE_UNSPECIFIED";
|
|
23
|
-
})(RegistryLaunchStage = exports.RegistryLaunchStage || (exports.RegistryLaunchStage = {}));
|
|
24
|
-
var Visibility;
|
|
25
|
-
(function (Visibility) {
|
|
26
|
-
Visibility["UNLISTED"] = "unlisted";
|
|
27
|
-
Visibility["PUBLIC"] = "public";
|
|
28
|
-
})(Visibility = exports.Visibility || (exports.Visibility = {}));
|
|
29
|
-
exports.FUNCTIONS_RESOURCE_TYPE = "firebaseextensions.v1beta.function";
|
|
30
|
-
var ParamType;
|
|
31
|
-
(function (ParamType) {
|
|
32
|
-
ParamType["STRING"] = "STRING";
|
|
33
|
-
ParamType["SELECT"] = "SELECT";
|
|
34
|
-
ParamType["MULTISELECT"] = "MULTISELECT";
|
|
35
|
-
ParamType["SECRET"] = "SECRET";
|
|
36
|
-
})(ParamType = exports.ParamType || (exports.ParamType = {}));
|
|
37
16
|
async function createInstanceHelper(projectId, instanceId, config, validateOnly = false) {
|
|
38
17
|
const createRes = await apiClient.post(`/projects/${projectId}/instances/`, {
|
|
39
18
|
name: `projects/${projectId}/instances/${instanceId}`,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.canonicalizeRefInput = exports.diagnoseAndFixProject = exports.confirm = exports.getSourceOrigin = exports.isLocalOrURLPath = exports.isLocalPath = exports.isUrlPath = exports.instanceIdExists = exports.promptForRepeatInstance = exports.promptForOfficialExtension = exports.displayReleaseNotes = exports.getPublisherProjectFromName = exports.createSourceFromLocation = exports.publishExtensionVersionFromLocalSource = exports.ensureExtensionsApiEnabled = exports.promptForValidInstanceId = exports.validateSpec = exports.validateCommandLineParams = exports.populateDefaultParams = exports.substituteParams = exports.getFirebaseProjectParams = exports.getDBInstanceFromURL = exports.resourceTypeToNiceName = exports.AUTOPOULATED_PARAM_PLACEHOLDERS = exports.EXTENSIONS_BUCKET_NAME = exports.URL_REGEX = exports.logPrefix = exports.SourceOrigin = exports.SpecParamType = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const clc = require("cli-color");
|
|
6
5
|
const ora = require("ora");
|
|
7
6
|
const semver = require("semver");
|
|
@@ -116,9 +115,10 @@ function substituteParams(original, params) {
|
|
|
116
115
|
const substituteRegexMatches = (unsubstituted, regex) => {
|
|
117
116
|
return unsubstituted.replace(regex, paramVal);
|
|
118
117
|
};
|
|
119
|
-
return
|
|
118
|
+
return regexes.reduce(substituteRegexMatches, str);
|
|
120
119
|
};
|
|
121
|
-
|
|
120
|
+
const s = Object.entries(params).reduce((str, [key, val]) => applySubstitution(str, val, key), startingString);
|
|
121
|
+
return JSON.parse(s);
|
|
122
122
|
}
|
|
123
123
|
exports.substituteParams = substituteParams;
|
|
124
124
|
function populateDefaultParams(paramVars, paramSpecs) {
|
|
@@ -207,8 +207,8 @@ function validateSpec(spec) {
|
|
|
207
207
|
if (!param.label) {
|
|
208
208
|
errors.push(`Param${param.param ? ` ${param.param}` : ""} is missing required field: label`);
|
|
209
209
|
}
|
|
210
|
-
if (param.type && !
|
|
211
|
-
errors.push(`Invalid type ${param.type} for param${param.param ? ` ${param.param}` : ""}. Valid types are ${
|
|
210
|
+
if (param.type && !Object.values(SpecParamType).includes(param.type)) {
|
|
211
|
+
errors.push(`Invalid type ${param.type} for param${param.param ? ` ${param.param}` : ""}. Valid types are ${Object.values(SpecParamType).join(", ")}`);
|
|
212
212
|
}
|
|
213
213
|
if (!param.type || param.type === SpecParamType.STRING) {
|
|
214
214
|
if (param.options) {
|
|
@@ -422,7 +422,7 @@ async function promptForOfficialExtension(message) {
|
|
|
422
422
|
type: "list",
|
|
423
423
|
message,
|
|
424
424
|
choices: (0, utils_1.convertOfficialExtensionsToList)(officialExts),
|
|
425
|
-
pageSize:
|
|
425
|
+
pageSize: Object.keys(officialExts).length,
|
|
426
426
|
});
|
|
427
427
|
}
|
|
428
428
|
exports.promptForOfficialExtension = promptForOfficialExtension;
|
|
@@ -1,40 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.listExtensions = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const clc = require("cli-color");
|
|
6
5
|
const Table = require("cli-table");
|
|
7
6
|
const extensionsApi_1 = require("./extensionsApi");
|
|
7
|
+
const logger_1 = require("../logger");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
8
9
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
9
|
-
const utils = require("../utils");
|
|
10
10
|
const extensionsUtils = require("./utils");
|
|
11
|
-
const logger_1 = require("../logger");
|
|
12
11
|
async function listExtensions(projectId) {
|
|
13
12
|
const instances = await (0, extensionsApi_1.listInstances)(projectId);
|
|
14
13
|
if (instances.length < 1) {
|
|
15
|
-
|
|
14
|
+
(0, utils_1.logLabeledBullet)(extensionsHelper_1.logPrefix, `there are no extensions installed on project ${clc.bold(projectId)}.`);
|
|
16
15
|
return [];
|
|
17
16
|
}
|
|
18
17
|
const table = new Table({
|
|
19
18
|
head: ["Extension", "Publisher", "Instance ID", "State", "Version", "Your last update"],
|
|
20
19
|
style: { head: ["yellow"] },
|
|
21
20
|
});
|
|
22
|
-
const sorted =
|
|
21
|
+
const sorted = instances.sort((a, b) => new Date(b.createTime).valueOf() - new Date(a.createTime).valueOf());
|
|
23
22
|
const formatted = [];
|
|
24
23
|
sorted.forEach((instance) => {
|
|
25
24
|
var _a, _b, _c, _d;
|
|
26
|
-
let extension =
|
|
25
|
+
let extension = instance.config.extensionRef || "";
|
|
27
26
|
let publisher;
|
|
28
27
|
if (extension === "") {
|
|
29
|
-
extension =
|
|
28
|
+
extension = instance.config.source.spec.name || "";
|
|
30
29
|
publisher = "N/A";
|
|
31
30
|
}
|
|
32
31
|
else {
|
|
33
32
|
publisher = extension.split("/")[0];
|
|
34
33
|
}
|
|
35
|
-
const instanceId = (_a =
|
|
34
|
+
const instanceId = (_a = (0, utils_1.last)(instance.name.split("/"))) !== null && _a !== void 0 ? _a : "";
|
|
36
35
|
const state = instance.state +
|
|
37
|
-
(
|
|
36
|
+
((instance.config.source.state || "ACTIVE") === "DELETED" ? " (UNPUBLISHED)" : "");
|
|
38
37
|
const version = (_d = (_c = (_b = instance === null || instance === void 0 ? void 0 : instance.config) === null || _b === void 0 ? void 0 : _b.source) === null || _c === void 0 ? void 0 : _c.spec) === null || _d === void 0 ? void 0 : _d.version;
|
|
39
38
|
const updateTime = extensionsUtils.formatTimestamp(instance.updateTime);
|
|
40
39
|
table.push([extension, publisher, instanceId, state, version, updateTime]);
|
|
@@ -47,7 +46,7 @@ async function listExtensions(projectId) {
|
|
|
47
46
|
updateTime,
|
|
48
47
|
});
|
|
49
48
|
});
|
|
50
|
-
|
|
49
|
+
(0, utils_1.logLabeledBullet)(extensionsHelper_1.logPrefix, `list of extensions installed in ${clc.bold(projectId)}:`);
|
|
51
50
|
logger_1.logger.info(table.toString());
|
|
52
51
|
return formatted;
|
|
53
52
|
}
|
|
@@ -12,7 +12,7 @@ const paramHelper_1 = require("./paramHelper");
|
|
|
12
12
|
const error_1 = require("../error");
|
|
13
13
|
const utils = require("../utils");
|
|
14
14
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
15
|
-
const
|
|
15
|
+
const types_1 = require("./types");
|
|
16
16
|
exports.ENV_DIRECTORY = "extensions";
|
|
17
17
|
async function writeToManifest(specs, config, options, allowOverwrite = false) {
|
|
18
18
|
if (config.has("extensions") &&
|
|
@@ -48,7 +48,7 @@ async function writeLocalSecrets(specs, config, force) {
|
|
|
48
48
|
continue;
|
|
49
49
|
}
|
|
50
50
|
const writeBuffer = {};
|
|
51
|
-
const locallyOverridenSecretParams = extensionSpec.params.filter((p) => { var _a; return p.type ===
|
|
51
|
+
const locallyOverridenSecretParams = extensionSpec.params.filter((p) => { var _a; return p.type === types_1.ParamType.SECRET && ((_a = spec.params[p.param]) === null || _a === void 0 ? void 0 : _a.local); });
|
|
52
52
|
for (const paramSpec of locallyOverridenSecretParams) {
|
|
53
53
|
const key = paramSpec.param;
|
|
54
54
|
const localValue = spec.params[key].local;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getTrustedPublishers = exports.getExtensionRegistry = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const logger_1 = require("../logger");
|
|
6
5
|
const apiv2_1 = require("../apiv2");
|
|
7
6
|
const api_1 = require("../api");
|
|
8
7
|
const EXTENSIONS_REGISTRY_ENDPOINT = "/extensions.json";
|
|
9
|
-
async function getExtensionRegistry(onlyFeatured) {
|
|
8
|
+
async function getExtensionRegistry(onlyFeatured = false) {
|
|
9
|
+
var _a;
|
|
10
10
|
const client = new apiv2_1.Client({ urlPrefix: api_1.firebaseExtensionsRegistryOrigin });
|
|
11
11
|
const res = await client.get(EXTENSIONS_REGISTRY_ENDPOINT);
|
|
12
|
-
const extensions =
|
|
12
|
+
const extensions = res.body.mods || {};
|
|
13
13
|
if (onlyFeatured) {
|
|
14
|
-
const featuredList =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const featuredList = new Set(((_a = res.body.featured) === null || _a === void 0 ? void 0 : _a.discover) || []);
|
|
15
|
+
const filteredExtensions = {};
|
|
16
|
+
for (const [name, extension] of Object.entries(extensions)) {
|
|
17
|
+
if (featuredList.has(name)) {
|
|
18
|
+
filteredExtensions[name] = extension;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return filteredExtensions;
|
|
18
22
|
}
|
|
19
23
|
return extensions;
|
|
20
24
|
}
|
|
@@ -5,7 +5,7 @@ const getProjectNumber_1 = require("../getProjectNumber");
|
|
|
5
5
|
const utils = require("../utils");
|
|
6
6
|
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
7
7
|
const projectUtils_1 = require("../projectUtils");
|
|
8
|
-
const
|
|
8
|
+
const types_1 = require("./types");
|
|
9
9
|
const secretManagerApi = require("../gcp/secretManager");
|
|
10
10
|
const logger_1 = require("../logger");
|
|
11
11
|
exports.SECRET_LABEL = "firebase-extensions-managed";
|
|
@@ -15,7 +15,7 @@ async function ensureSecretManagerApiEnabled(options) {
|
|
|
15
15
|
}
|
|
16
16
|
exports.ensureSecretManagerApiEnabled = ensureSecretManagerApiEnabled;
|
|
17
17
|
function usesSecrets(spec) {
|
|
18
|
-
return spec.params && !!spec.params.find((p) => p.type ===
|
|
18
|
+
return spec.params && !!spec.params.find((p) => p.type === types_1.ParamType.SECRET);
|
|
19
19
|
}
|
|
20
20
|
exports.usesSecrets = usesSecrets;
|
|
21
21
|
async function grantFirexServiceAgentSecretAdminRole(secret) {
|
|
@@ -38,7 +38,7 @@ async function getManagedSecrets(instance) {
|
|
|
38
38
|
exports.getManagedSecrets = getManagedSecrets;
|
|
39
39
|
function getActiveSecrets(spec, params) {
|
|
40
40
|
return spec.params
|
|
41
|
-
.map((p) => (p.type ===
|
|
41
|
+
.map((p) => (p.type === types_1.ParamType.SECRET ? params[p.param] : ""))
|
|
42
42
|
.filter((pv) => !!pv);
|
|
43
43
|
}
|
|
44
44
|
exports.getActiveSecrets = getActiveSecrets;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParamType = exports.FUNCTIONS_RESOURCE_TYPE = exports.Visibility = exports.RegistryLaunchStage = void 0;
|
|
4
|
+
var RegistryLaunchStage;
|
|
5
|
+
(function (RegistryLaunchStage) {
|
|
6
|
+
RegistryLaunchStage["EXPERIMENTAL"] = "EXPERIMENTAL";
|
|
7
|
+
RegistryLaunchStage["BETA"] = "BETA";
|
|
8
|
+
RegistryLaunchStage["GA"] = "GA";
|
|
9
|
+
RegistryLaunchStage["DEPRECATED"] = "DEPRECATED";
|
|
10
|
+
RegistryLaunchStage["REGISTRY_LAUNCH_STAGE_UNSPECIFIED"] = "REGISTRY_LAUNCH_STAGE_UNSPECIFIED";
|
|
11
|
+
})(RegistryLaunchStage = exports.RegistryLaunchStage || (exports.RegistryLaunchStage = {}));
|
|
12
|
+
var Visibility;
|
|
13
|
+
(function (Visibility) {
|
|
14
|
+
Visibility["UNLISTED"] = "unlisted";
|
|
15
|
+
Visibility["PUBLIC"] = "public";
|
|
16
|
+
})(Visibility = exports.Visibility || (exports.Visibility = {}));
|
|
17
|
+
exports.FUNCTIONS_RESOURCE_TYPE = "firebaseextensions.v1beta.function";
|
|
18
|
+
var ParamType;
|
|
19
|
+
(function (ParamType) {
|
|
20
|
+
ParamType["STRING"] = "STRING";
|
|
21
|
+
ParamType["SELECT"] = "SELECT";
|
|
22
|
+
ParamType["MULTISELECT"] = "MULTISELECT";
|
|
23
|
+
ParamType["SECRET"] = "SECRET";
|
|
24
|
+
})(ParamType = exports.ParamType || (exports.ParamType = {}));
|
|
@@ -17,7 +17,7 @@ function invalidSourceErrMsgTemplate(instanceId, source) {
|
|
|
17
17
|
- Run \`${clc.bold("firebase ext:update " + instanceId)}\` to update from the published source.\n
|
|
18
18
|
- Check your directory path or URL, then run \`${clc.bold("firebase ext:update " + instanceId + " <otherSource>")}\` to update from a local directory or URL source.`;
|
|
19
19
|
}
|
|
20
|
-
async function getExistingSourceOrigin(projectId, instanceId
|
|
20
|
+
async function getExistingSourceOrigin(projectId, instanceId) {
|
|
21
21
|
const instance = await extensionsApi.getInstance(projectId, instanceId);
|
|
22
22
|
return instance && instance.config.extensionRef
|
|
23
23
|
? extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION
|
package/lib/extensions/utils.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.formatTimestamp = exports.getRandomString = exports.convertOfficialExtensionsToList = exports.convertExtensionOptionToLabeledList = exports.onceWithJoin = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const prompt_1 = require("../prompt");
|
|
6
5
|
async function onceWithJoin(question) {
|
|
7
6
|
const response = await (0, prompt_1.promptOnce)(question);
|
|
@@ -22,7 +21,7 @@ function convertExtensionOptionToLabeledList(options) {
|
|
|
22
21
|
}
|
|
23
22
|
exports.convertExtensionOptionToLabeledList = convertExtensionOptionToLabeledList;
|
|
24
23
|
function convertOfficialExtensionsToList(officialExts) {
|
|
25
|
-
const l =
|
|
24
|
+
const l = Object.entries(officialExts).map(([key, entry]) => {
|
|
26
25
|
return {
|
|
27
26
|
checked: false,
|
|
28
27
|
value: `${entry.publisher}/${key}`,
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.paramsFlagDeprecationWarning = exports.displayWarningsForDeploy = exports.displayWarningPrompts = void 0;
|
|
4
4
|
const { marked } = require("marked");
|
|
5
5
|
const clc = require("cli-color");
|
|
6
|
-
const
|
|
6
|
+
const types_1 = require("./types");
|
|
7
7
|
const displayExtensionInfo_1 = require("./displayExtensionInfo");
|
|
8
8
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
9
9
|
const resolveSource_1 = require("./resolveSource");
|
|
@@ -31,7 +31,7 @@ async function displayWarningPrompts(publisherId, launchStage, extensionVersion)
|
|
|
31
31
|
githubLink: extensionVersion.spec.sourceUrl,
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
-
else if (launchStage ===
|
|
34
|
+
else if (launchStage === types_1.RegistryLaunchStage.EXPERIMENTAL) {
|
|
35
35
|
displayExperimentalWarning();
|
|
36
36
|
}
|
|
37
37
|
else {
|
|
@@ -55,7 +55,7 @@ async function displayWarningsForDeploy(instancesToCreate) {
|
|
|
55
55
|
await (0, planner_1.getExtension)(i);
|
|
56
56
|
}
|
|
57
57
|
const [eapExtensions, nonEapExtensions] = (0, functional_1.partition)(publishedExtensionInstances, (i) => { var _a, _b; return !trustedPublishers.includes((_b = (_a = i.ref) === null || _a === void 0 ? void 0 : _a.publisherId) !== null && _b !== void 0 ? _b : ""); });
|
|
58
|
-
const experimental = nonEapExtensions.filter((i) => i.extension.registryLaunchStage ===
|
|
58
|
+
const experimental = nonEapExtensions.filter((i) => i.extension.registryLaunchStage === types_1.RegistryLaunchStage.EXPERIMENTAL);
|
|
59
59
|
if (experimental.length) {
|
|
60
60
|
const humanReadableList = experimental.map((i) => `\t${(0, deploymentSummary_1.humanReadable)(i)}`).join("\n");
|
|
61
61
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`The following are instances of ${clc.bold("experimental")} extensions.They may not be production-ready. Their functionality may change in backward-incompatible ways before their official release, or they may be discontinued.\n${humanReadableList}\n`, { gfm: false }));
|
|
@@ -9,22 +9,22 @@ function isPlainObject(input) {
|
|
|
9
9
|
_.isEqual(Object.getPrototypeOf(input), Object.prototype));
|
|
10
10
|
}
|
|
11
11
|
function encodeHelper(val) {
|
|
12
|
-
if (
|
|
12
|
+
if (typeof val === "string") {
|
|
13
13
|
return { stringValue: val };
|
|
14
14
|
}
|
|
15
|
-
if (
|
|
15
|
+
if (val === !!val) {
|
|
16
16
|
return { booleanValue: val };
|
|
17
17
|
}
|
|
18
|
-
if (
|
|
18
|
+
if (Number.isInteger(val)) {
|
|
19
19
|
return { integerValue: val };
|
|
20
20
|
}
|
|
21
|
-
if (
|
|
21
|
+
if (typeof val === "number") {
|
|
22
22
|
return { doubleValue: val };
|
|
23
23
|
}
|
|
24
|
-
if (
|
|
24
|
+
if (val instanceof Date && !Number.isNaN(val)) {
|
|
25
25
|
return { timestampValue: val.toISOString() };
|
|
26
26
|
}
|
|
27
|
-
if (
|
|
27
|
+
if (Array.isArray(val)) {
|
|
28
28
|
const encodedElements = [];
|
|
29
29
|
for (const v of val) {
|
|
30
30
|
const enc = encodeHelper(v);
|
|
@@ -36,7 +36,7 @@ function encodeHelper(val) {
|
|
|
36
36
|
arrayValue: { values: encodedElements },
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
if (
|
|
39
|
+
if (val === null) {
|
|
40
40
|
return { nullValue: "NULL_VALUE" };
|
|
41
41
|
}
|
|
42
42
|
if (val instanceof Buffer || val instanceof Uint8Array) {
|
|
@@ -51,6 +51,9 @@ function encodeHelper(val) {
|
|
|
51
51
|
"The emulator does not yet support Firestore document reference values or geo points.");
|
|
52
52
|
}
|
|
53
53
|
function encodeFirestoreValue(data) {
|
|
54
|
-
return
|
|
54
|
+
return Object.entries(data).reduce((acc, [key, val]) => {
|
|
55
|
+
acc[key] = encodeHelper(val);
|
|
56
|
+
return acc;
|
|
57
|
+
}, {});
|
|
55
58
|
}
|
|
56
59
|
exports.encodeFirestoreValue = encodeFirestoreValue;
|
package/lib/fsAsync.js
CHANGED
|
@@ -8,7 +8,7 @@ const minimatch = require("minimatch");
|
|
|
8
8
|
async function readdirRecursiveHelper(options) {
|
|
9
9
|
const dirContents = (0, fs_extra_1.readdirSync)(options.path);
|
|
10
10
|
const fullPaths = dirContents.map((n) => (0, path_1.join)(options.path, n));
|
|
11
|
-
const filteredPaths =
|
|
11
|
+
const filteredPaths = fullPaths.filter((p) => !options.filter(p));
|
|
12
12
|
const filePromises = [];
|
|
13
13
|
for (const p of filteredPaths) {
|
|
14
14
|
const fstat = (0, fs_extra_1.statSync)(p);
|
|
@@ -22,12 +22,12 @@ async function readdirRecursiveHelper(options) {
|
|
|
22
22
|
}
|
|
23
23
|
const files = await Promise.all(filePromises);
|
|
24
24
|
let flatFiles = _.flattenDeep(files);
|
|
25
|
-
flatFiles =
|
|
25
|
+
flatFiles = flatFiles.filter((f) => f !== null);
|
|
26
26
|
return flatFiles;
|
|
27
27
|
}
|
|
28
28
|
async function readdirRecursive(options) {
|
|
29
29
|
const mmopts = { matchBase: true, dot: true };
|
|
30
|
-
const rules =
|
|
30
|
+
const rules = (options.ignore || []).map((glob) => {
|
|
31
31
|
return (p) => minimatch(p, glob, mmopts);
|
|
32
32
|
});
|
|
33
33
|
const filter = (t) => {
|
package/lib/functionsConfig.js
CHANGED
|
@@ -27,7 +27,7 @@ function setVariable(projectId, configId, varPath, val) {
|
|
|
27
27
|
return runtimeconfig.variables.set(projectId, configId, varPath, val);
|
|
28
28
|
}
|
|
29
29
|
function isReservedNamespace(id) {
|
|
30
|
-
return
|
|
30
|
+
return exports.RESERVED_NAMESPACES.some((reserved) => {
|
|
31
31
|
return id.config.toLowerCase().startsWith(reserved);
|
|
32
32
|
});
|
|
33
33
|
}
|
|
@@ -44,7 +44,7 @@ function varNameToIds(varName) {
|
|
|
44
44
|
}
|
|
45
45
|
exports.varNameToIds = varNameToIds;
|
|
46
46
|
function idsToVarName(projectId, configId, varId) {
|
|
47
|
-
return
|
|
47
|
+
return ["projects", projectId, "configs", configId, "variables", varId].join("/");
|
|
48
48
|
}
|
|
49
49
|
exports.idsToVarName = idsToVarName;
|
|
50
50
|
function getAppEngineLocation(config) {
|
|
@@ -63,7 +63,7 @@ async function getFirebaseConfig(options) {
|
|
|
63
63
|
exports.getFirebaseConfig = getFirebaseConfig;
|
|
64
64
|
async function setVariablesRecursive(projectId, configId, varPath, val) {
|
|
65
65
|
let parsed = val;
|
|
66
|
-
if (
|
|
66
|
+
if (typeof val === "string") {
|
|
67
67
|
try {
|
|
68
68
|
parsed = JSON.parse(val);
|
|
69
69
|
}
|
|
@@ -71,8 +71,8 @@ async function setVariablesRecursive(projectId, configId, varPath, val) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
if (_.isPlainObject(parsed)) {
|
|
74
|
-
return Promise.all(
|
|
75
|
-
const newVarPath = varPath ?
|
|
74
|
+
return Promise.all(Object.entries(parsed).map(([key, item]) => {
|
|
75
|
+
const newVarPath = varPath ? [varPath, key].join("/") : key;
|
|
76
76
|
return setVariablesRecursive(projectId, configId, newVarPath, item);
|
|
77
77
|
}));
|
|
78
78
|
}
|
|
@@ -87,7 +87,7 @@ async function materializeConfig(configName, output) {
|
|
|
87
87
|
_.set(output, key, variable.text);
|
|
88
88
|
};
|
|
89
89
|
const traverseVariables = async function (variables) {
|
|
90
|
-
return Promise.all(
|
|
90
|
+
return Promise.all(variables.map((variable) => {
|
|
91
91
|
return materializeVariable(variable.name);
|
|
92
92
|
}));
|
|
93
93
|
};
|
|
@@ -99,7 +99,10 @@ exports.materializeConfig = materializeConfig;
|
|
|
99
99
|
async function materializeAll(projectId) {
|
|
100
100
|
const output = {};
|
|
101
101
|
const configs = await runtimeconfig.configs.list(projectId);
|
|
102
|
-
|
|
102
|
+
if (!Array.isArray(configs) || !configs.length) {
|
|
103
|
+
return output;
|
|
104
|
+
}
|
|
105
|
+
await Promise.all(configs.map((config) => {
|
|
103
106
|
if (config.name.match(new RegExp("configs/firebase"))) {
|
|
104
107
|
return;
|
|
105
108
|
}
|
|
@@ -110,7 +113,7 @@ async function materializeAll(projectId) {
|
|
|
110
113
|
exports.materializeAll = materializeAll;
|
|
111
114
|
function parseSetArgs(args) {
|
|
112
115
|
const parsed = [];
|
|
113
|
-
|
|
116
|
+
for (const arg of args) {
|
|
114
117
|
const parts = arg.split("=");
|
|
115
118
|
const key = parts[0];
|
|
116
119
|
if (parts.length < 2) {
|
|
@@ -129,17 +132,17 @@ function parseSetArgs(args) {
|
|
|
129
132
|
varId: id.variable,
|
|
130
133
|
val: val,
|
|
131
134
|
});
|
|
132
|
-
}
|
|
135
|
+
}
|
|
133
136
|
return parsed;
|
|
134
137
|
}
|
|
135
138
|
exports.parseSetArgs = parseSetArgs;
|
|
136
139
|
function parseUnsetArgs(args) {
|
|
137
140
|
const parsed = [];
|
|
138
141
|
let splitArgs = [];
|
|
139
|
-
|
|
140
|
-
splitArgs =
|
|
141
|
-
}
|
|
142
|
-
|
|
142
|
+
for (const arg of args) {
|
|
143
|
+
splitArgs = Array.from(new Set([...splitArgs, ...arg.split(",")]));
|
|
144
|
+
}
|
|
145
|
+
for (const key of splitArgs) {
|
|
143
146
|
const id = keyToIds(key);
|
|
144
147
|
if (isReservedNamespace(id)) {
|
|
145
148
|
throw new error_1.FirebaseError("Cannot unset reserved namespace " + clc.bold(id.config));
|
|
@@ -148,7 +151,7 @@ function parseUnsetArgs(args) {
|
|
|
148
151
|
configId: id.config,
|
|
149
152
|
varId: id.variable,
|
|
150
153
|
});
|
|
151
|
-
}
|
|
154
|
+
}
|
|
152
155
|
return parsed;
|
|
153
156
|
}
|
|
154
157
|
exports.parseUnsetArgs = parseUnsetArgs;
|
|
@@ -10,14 +10,12 @@ function matchPrefix(short, long) {
|
|
|
10
10
|
if (short.length > long.length) {
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
|
-
return
|
|
14
|
-
return accum && x === long[i];
|
|
15
|
-
}, true);
|
|
13
|
+
return short.reduce((accum, x, i) => accum && x === long[i], true);
|
|
16
14
|
}
|
|
17
15
|
function applyExcept(json, except) {
|
|
18
|
-
|
|
16
|
+
for (const key of except) {
|
|
19
17
|
_.unset(json, key);
|
|
20
|
-
}
|
|
18
|
+
}
|
|
21
19
|
}
|
|
22
20
|
function cloneVariable(varName, toProject) {
|
|
23
21
|
return runtimeconfig.variables.get(varName).then((variable) => {
|
|
@@ -27,42 +25,42 @@ function cloneVariable(varName, toProject) {
|
|
|
27
25
|
}
|
|
28
26
|
function cloneConfig(configName, toProject) {
|
|
29
27
|
return runtimeconfig.variables.list(configName).then((variables) => {
|
|
30
|
-
return Promise.all(
|
|
28
|
+
return Promise.all(variables.map((variable) => {
|
|
31
29
|
return cloneVariable(variable.name, toProject);
|
|
32
30
|
}));
|
|
33
31
|
});
|
|
34
32
|
}
|
|
35
33
|
async function cloneConfigOrVariable(key, fromProject, toProject) {
|
|
36
34
|
const parts = key.split(".");
|
|
37
|
-
if (
|
|
35
|
+
if (functionsConfig.RESERVED_NAMESPACES.includes(parts[0])) {
|
|
38
36
|
throw new error_1.FirebaseError("Cannot clone reserved namespace " + clc.bold(parts[0]));
|
|
39
37
|
}
|
|
40
|
-
const configName =
|
|
38
|
+
const configName = ["projects", fromProject, "configs", parts[0]].join("/");
|
|
41
39
|
if (parts.length === 1) {
|
|
42
40
|
return cloneConfig(configName, toProject);
|
|
43
41
|
}
|
|
44
42
|
return runtimeconfig.variables.list(configName).then((variables) => {
|
|
45
43
|
const promises = [];
|
|
46
|
-
|
|
44
|
+
for (const variable of variables) {
|
|
47
45
|
const varId = functionsConfig.varNameToIds(variable.name).variable;
|
|
48
46
|
const variablePrefixFilter = parts.slice(1);
|
|
49
47
|
if (matchPrefix(variablePrefixFilter, varId.split("/"))) {
|
|
50
48
|
promises.push(cloneVariable(variable.name, toProject));
|
|
51
49
|
}
|
|
52
|
-
}
|
|
50
|
+
}
|
|
53
51
|
return Promise.all(promises);
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
54
|
async function functionsConfigClone(fromProject, toProject, only, except = []) {
|
|
57
55
|
if (only) {
|
|
58
|
-
return Promise.all(
|
|
56
|
+
return Promise.all(only.map((key) => {
|
|
59
57
|
return cloneConfigOrVariable(key, fromProject, toProject);
|
|
60
58
|
}));
|
|
61
59
|
}
|
|
62
60
|
return functionsConfig.materializeAll(fromProject).then((toClone) => {
|
|
63
61
|
_.unset(toClone, "firebase");
|
|
64
62
|
applyExcept(toClone, except);
|
|
65
|
-
return Promise.all(
|
|
63
|
+
return Promise.all(Object.entries(toClone).map(([configId, val]) => {
|
|
66
64
|
return functionsConfig.setVariablesRecursive(toProject, configId, "", val);
|
|
67
65
|
}));
|
|
68
66
|
});
|
|
@@ -4,7 +4,6 @@ exports.functionFromEndpoint = exports.endpointFromFunction = exports.listAllFun
|
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const error_1 = require("../error");
|
|
6
6
|
const logger_1 = require("../logger");
|
|
7
|
-
const previews_1 = require("../previews");
|
|
8
7
|
const backend = require("../deploy/functions/backend");
|
|
9
8
|
const utils = require("../utils");
|
|
10
9
|
const proto = require("./proto");
|
|
@@ -24,10 +23,6 @@ const BLOCKING_EVENT_TO_LABEL_KEY = {
|
|
|
24
23
|
"providers/cloud.auth/eventTypes/user.beforeCreate": "before-create",
|
|
25
24
|
"providers/cloud.auth/eventTypes/user.beforeSignIn": "before-sign-in",
|
|
26
25
|
};
|
|
27
|
-
function validateFunction(func) {
|
|
28
|
-
proto.assertOneOf("Cloud Function", func, "sourceCode", "sourceArchiveUrl", "sourceRepository", "sourceUploadUrl");
|
|
29
|
-
proto.assertOneOf("Cloud Function", func, "trigger", "httpsTrigger", "eventTrigger");
|
|
30
|
-
}
|
|
31
26
|
function functionsOpLogReject(funcName, type, err) {
|
|
32
27
|
var _a, _b;
|
|
33
28
|
if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 429) {
|
|
@@ -58,11 +53,7 @@ async function createFunction(cloudFunction) {
|
|
|
58
53
|
const apiPath = cloudFunction.name.substring(0, cloudFunction.name.lastIndexOf("/"));
|
|
59
54
|
const endpoint = `/${apiPath}`;
|
|
60
55
|
try {
|
|
61
|
-
const
|
|
62
|
-
if (previews_1.previews.artifactregistry) {
|
|
63
|
-
headers["X-Firebase-Artifact-Registry"] = "optin";
|
|
64
|
-
}
|
|
65
|
-
const res = await client.post(endpoint, cloudFunction, { headers });
|
|
56
|
+
const res = await client.post(endpoint, cloudFunction);
|
|
66
57
|
return {
|
|
67
58
|
name: res.body.name,
|
|
68
59
|
type: "create",
|
|
@@ -147,12 +138,7 @@ async function updateFunction(cloudFunction) {
|
|
|
147
138
|
const endpoint = `/${cloudFunction.name}`;
|
|
148
139
|
const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "environmentVariables", "secretEnvironmentVariables");
|
|
149
140
|
try {
|
|
150
|
-
const headers = {};
|
|
151
|
-
if (previews_1.previews.artifactregistry) {
|
|
152
|
-
headers["X-Firebase-Artifact-Registry"] = "optin";
|
|
153
|
-
}
|
|
154
141
|
const res = await client.patch(endpoint, cloudFunction, {
|
|
155
|
-
headers,
|
|
156
142
|
queryParams: {
|
|
157
143
|
updateMask: fieldMasks.join(","),
|
|
158
144
|
},
|
|
@@ -293,6 +279,7 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
|
293
279
|
sourceUploadUrl: sourceUploadUrl,
|
|
294
280
|
entryPoint: endpoint.entryPoint,
|
|
295
281
|
runtime: endpoint.runtime,
|
|
282
|
+
dockerRegistry: "ARTIFACT_REGISTRY",
|
|
296
283
|
};
|
|
297
284
|
proto.copyIfPresent(gcfFunction, endpoint, "labels");
|
|
298
285
|
if (backend.isEventTriggered(endpoint)) {
|
package/lib/gcp/rules.js
CHANGED
|
@@ -20,7 +20,7 @@ function _handleErrorResponse(response) {
|
|
|
20
20
|
async function getLatestRulesetName(projectId, service) {
|
|
21
21
|
const releases = await listAllReleases(projectId);
|
|
22
22
|
const prefix = `projects/${projectId}/releases/${service}`;
|
|
23
|
-
const release =
|
|
23
|
+
const release = releases.find((r) => r.name.startsWith(prefix));
|
|
24
24
|
if (!release) {
|
|
25
25
|
return null;
|
|
26
26
|
}
|
package/lib/gcp/runtimeconfig.js
CHANGED
|
@@ -15,7 +15,7 @@ function listConfigs(projectId) {
|
|
|
15
15
|
.then((resp) => resp.body.configs);
|
|
16
16
|
}
|
|
17
17
|
function createConfig(projectId, configId) {
|
|
18
|
-
const path =
|
|
18
|
+
const path = ["projects", projectId, "configs"].join("/");
|
|
19
19
|
return apiClient
|
|
20
20
|
.post(`/projects/${projectId}/configs`, {
|
|
21
21
|
name: path + "/" + configId,
|
|
@@ -88,7 +88,7 @@ function updateVariable(projectId, configId, varId, value) {
|
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
function setVariable(projectId, configId, varId, value) {
|
|
91
|
-
const path =
|
|
91
|
+
const path = ["projects", projectId, "configs", configId, "variables", varId].join("/");
|
|
92
92
|
return getVariable(path)
|
|
93
93
|
.then(() => {
|
|
94
94
|
return updateVariable(projectId, configId, varId, value);
|
package/lib/hosting/proxy.js
CHANGED
|
@@ -133,7 +133,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
|
|
|
133
133
|
}
|
|
134
134
|
exports.proxyRequestHandler = proxyRequestHandler;
|
|
135
135
|
function errorRequestHandler(error) {
|
|
136
|
-
return (req, res
|
|
136
|
+
return (req, res) => {
|
|
137
137
|
res.statusCode = 500;
|
|
138
138
|
const out = `A problem occurred while trying to handle a proxied rewrite: ${error}`;
|
|
139
139
|
logger_1.logger.error(out);
|
|
@@ -27,7 +27,7 @@ const YML_MERGE_FILENAME = "firebase-hosting-merge.yml";
|
|
|
27
27
|
const CHECKOUT_GITHUB_ACTION_NAME = "actions/checkout@v2";
|
|
28
28
|
const HOSTING_GITHUB_ACTION_NAME = "FirebaseExtended/action-hosting-deploy@v0";
|
|
29
29
|
const githubApiClient = new apiv2_1.Client({ urlPrefix: api_1.githubApiOrigin, auth: false });
|
|
30
|
-
async function initGitHub(setup
|
|
30
|
+
async function initGitHub(setup) {
|
|
31
31
|
if (!setup.projectId) {
|
|
32
32
|
return (0, utils_1.reject)("Could not determine Project ID, can't set up GitHub workflow.", { exit: 1 });
|
|
33
33
|
}
|