firebase-tools 10.1.5 → 10.2.2
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/api.js +1 -0
- package/lib/apiv2.js +3 -0
- package/lib/appdistribution/options-parser-util.js +1 -1
- package/lib/auth.js +62 -25
- package/lib/command.js +1 -1
- package/lib/commands/apps-android-sha-create.js +2 -2
- package/lib/commands/apps-sdkconfig.js +1 -1
- package/lib/commands/auth-import.js +1 -1
- package/lib/commands/database-rules-list.js +2 -2
- package/lib/commands/emulators-start.js +1 -1
- package/lib/commands/ext-configure.js +1 -0
- package/lib/commands/ext-dev-init.js +49 -49
- package/lib/commands/ext-export.js +12 -2
- package/lib/commands/ext-install.js +104 -103
- package/lib/commands/ext-uninstall.js +9 -8
- package/lib/commands/ext-update.js +10 -9
- package/lib/commands/functions-config-clone.js +1 -1
- package/lib/commands/functions-config-export.js +1 -1
- package/lib/commands/functions-secrets-access.js +17 -0
- package/lib/commands/functions-secrets-destroy.js +40 -0
- package/lib/commands/functions-secrets-get.js +21 -0
- package/lib/commands/functions-secrets-prune.js +50 -0
- package/lib/commands/functions-secrets-set.js +46 -0
- package/lib/commands/hosting-clone.js +3 -3
- package/lib/commands/index.js +7 -3
- package/lib/commands/login.js +1 -1
- package/lib/commands/remoteconfig-get.js +1 -1
- package/lib/deploy/extensions/deploymentSummary.js +3 -3
- package/lib/deploy/extensions/params.js +3 -0
- package/lib/deploy/extensions/planner.js +2 -1
- package/lib/deploy/extensions/tasks.js +1 -1
- package/lib/deploy/functions/backend.js +20 -5
- package/lib/deploy/functions/checkIam.js +1 -1
- package/lib/deploy/functions/containerCleaner.js +3 -3
- package/lib/deploy/functions/ensure.js +112 -0
- package/lib/deploy/functions/ensureCloudBuildEnabled.js +0 -49
- package/lib/deploy/functions/functionsDeployHelper.js +2 -2
- package/lib/deploy/functions/prepare.js +15 -20
- package/lib/deploy/functions/pricing.js +1 -1
- package/lib/deploy/functions/prompts.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +3 -3
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/release/planner.js +11 -8
- package/lib/deploy/functions/release/reporter.js +3 -0
- package/lib/deploy/functions/runtimes/discovery/index.js +6 -6
- package/lib/deploy/functions/runtimes/discovery/parsing.js +1 -1
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +17 -11
- package/lib/deploy/functions/runtimes/golang/index.js +2 -2
- package/lib/deploy/functions/runtimes/node/index.js +26 -0
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +40 -7
- package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
- package/lib/deploy/functions/validate.js +58 -3
- package/lib/deploy/hosting/client.js +9 -0
- package/lib/deploy/hosting/convertConfig.js +6 -0
- package/lib/deploy/hosting/deploy.js +2 -2
- package/lib/deploy/hosting/hashcache.js +21 -19
- package/lib/deploy/hosting/index.js +5 -5
- package/lib/deploy/hosting/prepare.js +25 -25
- package/lib/deploy/hosting/release.js +21 -24
- package/lib/deploy/hosting/uploader.js +5 -5
- package/lib/deploy/remoteconfig/functions.js +2 -2
- package/lib/emulator/auth/cloudFunctions.js +1 -1
- package/lib/emulator/auth/operations.js +1 -1
- package/lib/emulator/commandUtils.js +5 -1
- package/lib/emulator/constants.js +3 -0
- package/lib/emulator/controller.js +48 -18
- package/lib/emulator/download.js +18 -1
- package/lib/emulator/downloadableEmulators.js +30 -13
- package/lib/emulator/emulatorLogger.js +19 -1
- package/lib/emulator/extensions/validation.js +35 -0
- package/lib/emulator/extensionsEmulator.js +140 -0
- package/lib/emulator/functionsEmulator.js +175 -86
- package/lib/emulator/functionsEmulatorRuntime.js +108 -83
- package/lib/emulator/functionsEmulatorShared.js +51 -1
- package/lib/emulator/functionsEmulatorShell.js +1 -2
- package/lib/emulator/functionsEmulatorUtils.js +4 -4
- package/lib/emulator/functionsRuntimeWorker.js +3 -3
- package/lib/emulator/hub.js +4 -3
- package/lib/emulator/loggingEmulator.js +1 -1
- package/lib/emulator/pubsubEmulator.js +1 -1
- package/lib/emulator/registry.js +10 -2
- package/lib/emulator/storage/apis/firebase.js +31 -26
- package/lib/emulator/storage/apis/gcloud.js +7 -12
- package/lib/emulator/storage/files.js +36 -34
- package/lib/emulator/storage/index.js +2 -2
- package/lib/emulator/storage/metadata.js +2 -2
- package/lib/emulator/storage/rules/runtime.js +8 -7
- package/lib/emulator/types.js +3 -0
- package/lib/ensureApiEnabled.js +5 -1
- package/lib/error.js +1 -1
- package/lib/extensions/askUserForParam.js +2 -2
- package/lib/extensions/changelog.js +3 -1
- package/lib/extensions/checkProjectBilling.js +1 -1
- package/lib/extensions/diagnose.js +56 -0
- package/lib/extensions/displayExtensionInfo.js +1 -1
- package/lib/extensions/emulator/optionsHelper.js +24 -8
- package/lib/extensions/emulator/specHelper.js +10 -23
- package/lib/extensions/export.js +1 -51
- package/lib/extensions/extensionsApi.js +1 -1
- package/lib/extensions/extensionsHelper.js +23 -10
- package/lib/extensions/listExtensions.js +2 -0
- package/lib/extensions/manifest.js +48 -0
- package/lib/extensions/metricsUtils.js +4 -4
- package/lib/extensions/paramHelper.js +4 -4
- package/lib/extensions/refs.js +1 -1
- package/lib/extensions/secretsUtils.js +4 -4
- package/lib/functional.js +1 -1
- package/lib/functions/env.js +7 -8
- package/lib/functions/secrets.js +112 -0
- package/lib/gcp/cloudfunctions.js +24 -5
- package/lib/gcp/cloudfunctionsv2.js +18 -5
- package/lib/gcp/cloudtasks.js +1 -1
- package/lib/gcp/docker.js +2 -2
- package/lib/gcp/run.js +2 -2
- package/lib/gcp/secretManager.js +128 -46
- package/lib/gcp/storage.js +1 -0
- package/lib/hosting/api.js +1 -1
- package/lib/hosting/functionsProxy.js +15 -5
- package/lib/hosting/proxy.js +2 -2
- package/lib/init/features/account.js +1 -1
- package/lib/management/database.js +1 -1
- package/lib/previews.js +1 -1
- package/lib/responseToError.js +16 -7
- package/lib/serve/functions.js +2 -2
- package/lib/serve/hosting.js +1 -1
- package/lib/utils.js +7 -2
- package/npm-shrinkwrap.json +904 -412
- package/package.json +3 -3
- package/schema/firebase-config.json +32 -0
- package/templates/init/functions/javascript/package.lint.json +3 -3
- package/templates/init/functions/javascript/package.nolint.json +2 -2
- package/templates/init/functions/typescript/package.lint.json +7 -7
- package/templates/init/functions/typescript/package.nolint.json +3 -3
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.client = void 0;
|
|
4
|
+
const api_1 = require("../../api");
|
|
5
|
+
const apiv2_1 = require("../../apiv2");
|
|
6
|
+
exports.client = new apiv2_1.Client({
|
|
7
|
+
urlPrefix: api_1.hostingApiOrigin,
|
|
8
|
+
apiVersion: "v1beta1",
|
|
9
|
+
});
|
|
@@ -46,6 +46,12 @@ function convertConfig(config) {
|
|
|
46
46
|
}
|
|
47
47
|
else if ("function" in rewrite) {
|
|
48
48
|
vRewrite.function = rewrite.function;
|
|
49
|
+
if (rewrite.region) {
|
|
50
|
+
vRewrite.functionRegion = rewrite.region;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
vRewrite.functionRegion = "us-central1";
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
56
|
else if ("dynamicLinks" in rewrite) {
|
|
51
57
|
vRewrite.dynamicLinks = rewrite.dynamicLinks;
|
|
@@ -53,7 +53,7 @@ async function deploy(context, options) {
|
|
|
53
53
|
await uploader.start();
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
|
-
track("Hosting Deploy", "failure");
|
|
56
|
+
void track("Hosting Deploy", "failure");
|
|
57
57
|
throw err;
|
|
58
58
|
}
|
|
59
59
|
finally {
|
|
@@ -65,7 +65,7 @@ async function deploy(context, options) {
|
|
|
65
65
|
(0, utils_1.logLabeledSuccess)("hosting[" + deploy.site + "]", "file upload complete");
|
|
66
66
|
const dt = Date.now() - t0;
|
|
67
67
|
logger_1.logger.debug("[hosting] deploy completed after " + dt + "ms");
|
|
68
|
-
track("Hosting Deploy", "success", dt);
|
|
68
|
+
void track("Hosting Deploy", "success", dt);
|
|
69
69
|
return runDeploys(deploys, debugging);
|
|
70
70
|
}
|
|
71
71
|
const debugging = !!(options.debug || options.nonInteractive);
|
|
@@ -1,46 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dump = exports.load = void 0;
|
|
2
4
|
const fs = require("fs-extra");
|
|
3
5
|
const path = require("path");
|
|
4
|
-
const
|
|
6
|
+
const logger_1 = require("../../logger");
|
|
5
7
|
function cachePath(cwd, name) {
|
|
6
|
-
return path.resolve(cwd,
|
|
8
|
+
return path.resolve(cwd, `.firebase/hosting.${name}.cache`);
|
|
7
9
|
}
|
|
8
|
-
|
|
10
|
+
function load(cwd, name) {
|
|
9
11
|
try {
|
|
10
|
-
const out =
|
|
11
|
-
const lines = fs.readFileSync(cachePath(cwd, name),
|
|
12
|
-
|
|
13
|
-
});
|
|
14
|
-
lines.split("\n").forEach(function (line) {
|
|
12
|
+
const out = new Map();
|
|
13
|
+
const lines = fs.readFileSync(cachePath(cwd, name), "utf8");
|
|
14
|
+
for (const line of lines.split("\n")) {
|
|
15
15
|
const d = line.split(",");
|
|
16
16
|
if (d.length === 3) {
|
|
17
|
-
out
|
|
17
|
+
out.set(d[0], { mtime: parseInt(d[1]), hash: d[2] });
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
}
|
|
20
20
|
return out;
|
|
21
21
|
}
|
|
22
22
|
catch (e) {
|
|
23
23
|
if (e.code === "ENOENT") {
|
|
24
|
-
logger.debug(
|
|
24
|
+
logger_1.logger.debug(`[hosting] hash cache [${name}] not populated`);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
-
logger.debug(
|
|
27
|
+
logger_1.logger.debug(`[hosting] hash cache [${name}] load error: ${e.message}`);
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return new Map();
|
|
30
30
|
}
|
|
31
|
-
}
|
|
32
|
-
exports.
|
|
31
|
+
}
|
|
32
|
+
exports.load = load;
|
|
33
|
+
function dump(cwd, name, data) {
|
|
33
34
|
let st = "";
|
|
34
35
|
let count = 0;
|
|
35
36
|
for (const [path, d] of data) {
|
|
36
37
|
count++;
|
|
37
|
-
st += path
|
|
38
|
+
st += `${path},${d.mtime},${d.hash}\n`;
|
|
38
39
|
}
|
|
39
40
|
try {
|
|
40
41
|
fs.outputFileSync(cachePath(cwd, name), st, { encoding: "utf8" });
|
|
41
|
-
logger.debug(
|
|
42
|
+
logger_1.logger.debug(`[hosting] hash cache [${name}] stored for ${count} files`);
|
|
42
43
|
}
|
|
43
44
|
catch (e) {
|
|
44
|
-
logger.debug(
|
|
45
|
+
logger_1.logger.debug(`[hosting] unable to store hash cache [${name}]: ${e.stack}`);
|
|
45
46
|
}
|
|
46
|
-
}
|
|
47
|
+
}
|
|
48
|
+
exports.dump = dump;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.release = exports.deploy = exports.prepare = void 0;
|
|
4
|
-
|
|
5
|
-
exports
|
|
6
|
-
|
|
4
|
+
var prepare_1 = require("./prepare");
|
|
5
|
+
Object.defineProperty(exports, "prepare", { enumerable: true, get: function () { return prepare_1.prepare; } });
|
|
6
|
+
var deploy_1 = require("./deploy");
|
|
7
7
|
Object.defineProperty(exports, "deploy", { enumerable: true, get: function () { return deploy_1.deploy; } });
|
|
8
|
-
|
|
9
|
-
exports
|
|
8
|
+
var release_1 = require("./release");
|
|
9
|
+
Object.defineProperty(exports, "release", { enumerable: true, get: function () { return release_1.release; } });
|
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prepare = void 0;
|
|
4
|
+
const error_1 = require("../../error");
|
|
5
|
+
const client_1 = require("./client");
|
|
6
|
+
const projectUtils_1 = require("../../projectUtils");
|
|
7
|
+
const normalizedHostingConfigs_1 = require("../../hosting/normalizedHostingConfigs");
|
|
8
|
+
const validate_1 = require("./validate");
|
|
9
|
+
const convertConfig_1 = require("./convertConfig");
|
|
5
10
|
const deploymentTool = require("../../deploymentTool");
|
|
6
|
-
|
|
7
|
-
const { normalizedHostingConfigs } = require("../../hosting/normalizedHostingConfigs");
|
|
8
|
-
const { validateDeploy } = require("./validate");
|
|
9
|
-
module.exports = function (context, options) {
|
|
11
|
+
async function prepare(context, options) {
|
|
10
12
|
if (options.public) {
|
|
11
|
-
if (
|
|
12
|
-
throw new FirebaseError("Cannot specify --public option with multi-site configuration.");
|
|
13
|
+
if (Array.isArray(options.config.get("hosting"))) {
|
|
14
|
+
throw new error_1.FirebaseError("Cannot specify --public option with multi-site configuration.");
|
|
13
15
|
}
|
|
14
16
|
options.config.set("hosting.public", options.public);
|
|
15
17
|
}
|
|
16
|
-
const
|
|
18
|
+
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
19
|
+
const configs = (0, normalizedHostingConfigs_1.normalizedHostingConfigs)(options, { resolveTargets: true });
|
|
17
20
|
if (configs.length === 0) {
|
|
18
21
|
return Promise.resolve();
|
|
19
22
|
}
|
|
20
23
|
context.hosting = {
|
|
21
|
-
deploys: configs.map(
|
|
24
|
+
deploys: configs.map((cfg) => {
|
|
22
25
|
return { config: cfg, site: cfg.site };
|
|
23
26
|
}),
|
|
24
27
|
};
|
|
25
28
|
const versionCreates = [];
|
|
26
|
-
|
|
29
|
+
for (const deploy of context.hosting.deploys) {
|
|
27
30
|
const cfg = deploy.config;
|
|
28
|
-
validateDeploy(deploy, options);
|
|
31
|
+
(0, validate_1.validateDeploy)(deploy, options);
|
|
29
32
|
const data = {
|
|
30
|
-
config: convertConfig(cfg),
|
|
33
|
+
config: (0, convertConfig_1.convertConfig)(cfg),
|
|
31
34
|
labels: deploymentTool.labels(),
|
|
32
35
|
};
|
|
33
|
-
versionCreates.push(
|
|
34
|
-
.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
data,
|
|
38
|
-
})
|
|
39
|
-
.then(function (result) {
|
|
40
|
-
deploy.version = result.body.name;
|
|
36
|
+
versionCreates.push(client_1.client
|
|
37
|
+
.post(`/projects/${projectNumber}/sites/${deploy.site}/versions`, data)
|
|
38
|
+
.then((res) => {
|
|
39
|
+
deploy.version = res.body.name;
|
|
41
40
|
}));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
}
|
|
41
|
+
}
|
|
42
|
+
await Promise.all(versionCreates);
|
|
43
|
+
}
|
|
44
|
+
exports.prepare = prepare;
|
|
@@ -1,34 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.release = void 0;
|
|
4
|
+
const client_1 = require("./client");
|
|
5
|
+
const logger_1 = require("../../logger");
|
|
6
|
+
const projectUtils_1 = require("../../projectUtils");
|
|
3
7
|
const utils = require("../../utils");
|
|
4
|
-
|
|
5
|
-
module.exports = function (context, options) {
|
|
8
|
+
async function release(context, options) {
|
|
6
9
|
if (!context.hosting || !context.hosting.deploys) {
|
|
7
|
-
return
|
|
10
|
+
return;
|
|
8
11
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
});
|
|
17
|
-
logger.debug("[hosting] finalized version for " + deploy.site + ":", finalizeResult.body);
|
|
18
|
-
utils.logLabeledSuccess("hosting[" + deploy.site + "]", "version finalized");
|
|
19
|
-
utils.logLabeledBullet("hosting[" + deploy.site + "]", "releasing new version...");
|
|
12
|
+
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
13
|
+
logger_1.logger.debug(JSON.stringify(context.hosting.deploys, null, 2));
|
|
14
|
+
await Promise.all(context.hosting.deploys.map(async (deploy) => {
|
|
15
|
+
utils.logLabeledBullet(`hosting[${deploy.site}]`, "finalizing version...");
|
|
16
|
+
const finalizeResult = await client_1.client.patch(`/${deploy.version}`, { status: "FINALIZED" }, { queryParams: { updateMask: "status" } });
|
|
17
|
+
logger_1.logger.debug(`[hosting] finalized version for ${deploy.site}:${finalizeResult.body}`);
|
|
18
|
+
utils.logLabeledSuccess(`hosting[${deploy.site}]`, "version finalized");
|
|
19
|
+
utils.logLabeledBullet(`hosting[${deploy.site}]`, "releasing new version...");
|
|
20
20
|
const channelSegment = context.hostingChannel && context.hostingChannel !== "live"
|
|
21
21
|
? `/channels/${context.hostingChannel}`
|
|
22
22
|
: "";
|
|
23
23
|
if (channelSegment) {
|
|
24
|
-
logger.debug("[hosting] releasing to channel:", context.hostingChannel);
|
|
24
|
+
logger_1.logger.debug("[hosting] releasing to channel:", context.hostingChannel);
|
|
25
25
|
}
|
|
26
|
-
const releaseResult = await
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
data: { message: options.message || null },
|
|
30
|
-
});
|
|
31
|
-
logger.debug("[hosting] release:", releaseResult.body);
|
|
32
|
-
utils.logLabeledSuccess("hosting[" + deploy.site + "]", "release complete");
|
|
26
|
+
const releaseResult = await client_1.client.post(`/projects/${projectNumber}/sites/${deploy.site}${channelSegment}/releases`, { message: options.message || null }, { queryParams: { versionName: deploy.version } });
|
|
27
|
+
logger_1.logger.debug("[hosting] release:", releaseResult.body);
|
|
28
|
+
utils.logLabeledSuccess(`hosting[${deploy.site}]`, "release complete");
|
|
33
29
|
}));
|
|
34
|
-
}
|
|
30
|
+
}
|
|
31
|
+
exports.release = release;
|
|
@@ -11,7 +11,7 @@ const zlib = require("zlib");
|
|
|
11
11
|
const apiv2_1 = require("../../apiv2");
|
|
12
12
|
const queue_1 = require("../../throttler/queue");
|
|
13
13
|
const api_1 = require("../../api");
|
|
14
|
-
const
|
|
14
|
+
const hashcache_1 = require("./hashcache");
|
|
15
15
|
const logger_1 = require("../../logger");
|
|
16
16
|
const error_1 = require("../../error");
|
|
17
17
|
const MIN_UPLOAD_TIMEOUT = 30000;
|
|
@@ -54,7 +54,7 @@ class Uploader {
|
|
|
54
54
|
this.public = options.public || this.cwd;
|
|
55
55
|
this.files = options.files;
|
|
56
56
|
this.fileCount = this.files.length;
|
|
57
|
-
this.cache =
|
|
57
|
+
this.cache = (0, hashcache_1.load)(this.projectRoot, this.hashcacheName());
|
|
58
58
|
this.cacheNew = new Map();
|
|
59
59
|
this.sizeMap = {};
|
|
60
60
|
this.hashMap = {};
|
|
@@ -78,7 +78,7 @@ class Uploader {
|
|
|
78
78
|
.wait()
|
|
79
79
|
.then(this.queuePopulate.bind(this))
|
|
80
80
|
.then(() => {
|
|
81
|
-
|
|
81
|
+
(0, hashcache_1.dump)(this.projectRoot, this.hashcacheName(), this.cacheNew);
|
|
82
82
|
logger_1.logger.debug("[hosting][hash queue][FINAL]", this.hashQueue.stats());
|
|
83
83
|
this.populateQueue.close();
|
|
84
84
|
return this.populateQueue.wait();
|
|
@@ -91,7 +91,7 @@ class Uploader {
|
|
|
91
91
|
this.uploadQueue.wait().catch((err) => {
|
|
92
92
|
if (err.message.includes("content hash")) {
|
|
93
93
|
logger_1.logger.debug("[hosting][upload queue] upload failed with content hash error. Deleting hash cache");
|
|
94
|
-
|
|
94
|
+
(0, hashcache_1.dump)(this.projectRoot, this.hashcacheName(), new Map());
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
const fin = (err) => {
|
|
@@ -123,7 +123,7 @@ class Uploader {
|
|
|
123
123
|
const stats = fs.statSync(path.resolve(this.public, filePath));
|
|
124
124
|
const mtime = stats.mtime.getTime();
|
|
125
125
|
this.sizeMap[filePath] = stats.size;
|
|
126
|
-
const cached = this.cache
|
|
126
|
+
const cached = this.cache.get(filePath);
|
|
127
127
|
if (cached && cached.mtime === mtime) {
|
|
128
128
|
this.cacheNew.set(filePath, cached);
|
|
129
129
|
this.addHash(filePath, cached.hash);
|
|
@@ -20,10 +20,10 @@ async function getEtag(projectNumber, versionNumber) {
|
|
|
20
20
|
exports.getEtag = getEtag;
|
|
21
21
|
function validateInputRemoteConfigTemplate(template) {
|
|
22
22
|
const templateCopy = JSON.parse(JSON.stringify(template));
|
|
23
|
-
if (!templateCopy || templateCopy
|
|
23
|
+
if (!templateCopy || templateCopy === "null" || templateCopy === "undefined") {
|
|
24
24
|
throw new error_1.FirebaseError(`Invalid Remote Config template: ${JSON.stringify(templateCopy)}`);
|
|
25
25
|
}
|
|
26
|
-
if (typeof templateCopy.etag !== "string" || templateCopy.etag
|
|
26
|
+
if (typeof templateCopy.etag !== "string" || templateCopy.etag === "") {
|
|
27
27
|
throw new error_1.FirebaseError("ETag must be a non-empty string");
|
|
28
28
|
}
|
|
29
29
|
if (templateCopy.conditions && !Array.isArray(templateCopy.conditions)) {
|
|
@@ -35,7 +35,7 @@ class AuthCloudFunction {
|
|
|
35
35
|
catch (e) {
|
|
36
36
|
err = e;
|
|
37
37
|
}
|
|
38
|
-
if (err || (res === null || res === void 0 ? void 0 : res.status)
|
|
38
|
+
if (err || (res === null || res === void 0 ? void 0 : res.status) !== 200) {
|
|
39
39
|
this.logger.logLabeled("WARN", "functions", `Firebase Authentication function was not triggered due to emulation error. Please file a bug.`);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1378,7 +1378,7 @@ function mfaSignInFinalize(state, reqBody) {
|
|
|
1378
1378
|
(0, errors_1.assert)(sessionInfo, "MISSING_SESSION_INFO");
|
|
1379
1379
|
const phoneNumber = verifyPhoneNumber(state, sessionInfo, code);
|
|
1380
1380
|
let { user, signInProvider } = parsePendingCredential(state, reqBody.mfaPendingCredential);
|
|
1381
|
-
const enrollment = (_b = user.mfaInfo) === null || _b === void 0 ? void 0 : _b.find((enrollment) => enrollment.unobfuscatedPhoneInfo
|
|
1381
|
+
const enrollment = (_b = user.mfaInfo) === null || _b === void 0 ? void 0 : _b.find((enrollment) => enrollment.unobfuscatedPhoneInfo === phoneNumber);
|
|
1382
1382
|
(0, errors_1.assert)(enrollment && enrollment.mfaEnrollmentId, "MFA_ENROLLMENT_NOT_FOUND");
|
|
1383
1383
|
user = state.updateUserByLocalId(user.localId, { lastLoginAt: Date.now().toString() });
|
|
1384
1384
|
(0, errors_1.assert)(!user.disabled, "USER_DISABLED");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.emulatorExec = exports.shutdownWhenKilled = exports.setExportOnExitOptions = exports.parseInspectionPort = exports.beforeEmulatorCommand = exports.warnEmulatorNotSupported = exports.printNoticeIfEmulated = exports.DESC_TEST_PARAMS = exports.FLAG_TEST_PARAMS = exports.DESC_TEST_CONFIG = exports.FLAG_TEST_CONFIG = exports.DESC_UI = exports.FLAG_UI = exports.EXPORT_ON_EXIT_USAGE_ERROR = exports.DESC_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT_NAME = exports.DESC_IMPORT = exports.FLAG_IMPORT = exports.DESC_INSPECT_FUNCTIONS = exports.FLAG_INSPECT_FUNCTIONS = exports.DESC_ONLY = exports.FLAG_ONLY = void 0;
|
|
3
|
+
exports.emulatorExec = exports.shutdownWhenKilled = exports.setExportOnExitOptions = exports.parseInspectionPort = exports.beforeEmulatorCommand = exports.warnEmulatorNotSupported = exports.printNoticeIfEmulated = exports.DESC_TEST_PARAMS = exports.FLAG_TEST_PARAMS = exports.DESC_TEST_CONFIG = exports.FLAG_TEST_CONFIG = exports.DESC_UI = exports.FLAG_UI = exports.EXPORT_ON_EXIT_CWD_DANGER = exports.EXPORT_ON_EXIT_USAGE_ERROR = exports.DESC_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT_NAME = exports.DESC_IMPORT = exports.FLAG_IMPORT = exports.DESC_INSPECT_FUNCTIONS = exports.FLAG_INSPECT_FUNCTIONS = exports.DESC_ONLY = exports.FLAG_ONLY = void 0;
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const childProcess = require("child_process");
|
|
6
6
|
const controller = require("../emulator/controller");
|
|
@@ -36,6 +36,7 @@ exports.DESC_EXPORT_ON_EXIT = "automatically export emulator data (emulators:exp
|
|
|
36
36
|
`when no dir is provided the location of ${exports.FLAG_IMPORT} is used`;
|
|
37
37
|
exports.EXPORT_ON_EXIT_USAGE_ERROR = `"${exports.FLAG_EXPORT_ON_EXIT_NAME}" must be used with "${exports.FLAG_IMPORT}"` +
|
|
38
38
|
` or provide a dir directly to "${exports.FLAG_EXPORT_ON_EXIT}"`;
|
|
39
|
+
exports.EXPORT_ON_EXIT_CWD_DANGER = `"${exports.FLAG_EXPORT_ON_EXIT_NAME}" must not point to the current directory or parents. Please choose a new/dedicated directory for exports.`;
|
|
39
40
|
exports.FLAG_UI = "--ui";
|
|
40
41
|
exports.DESC_UI = "run the Emulator UI";
|
|
41
42
|
exports.FLAG_TEST_CONFIG = "--test-config <firebase.json file>";
|
|
@@ -131,6 +132,9 @@ function setExportOnExitOptions(options) {
|
|
|
131
132
|
if (options.exportOnExit === true || !options.exportOnExit) {
|
|
132
133
|
throw new error_1.FirebaseError(exports.EXPORT_ON_EXIT_USAGE_ERROR);
|
|
133
134
|
}
|
|
135
|
+
if (path.resolve(".").startsWith(path.resolve(options.exportOnExit))) {
|
|
136
|
+
throw new error_1.FirebaseError(exports.EXPORT_ON_EXIT_CWD_DANGER);
|
|
137
|
+
}
|
|
134
138
|
}
|
|
135
139
|
return;
|
|
136
140
|
}
|
|
@@ -8,6 +8,7 @@ const DEFAULT_PORTS = {
|
|
|
8
8
|
logging: 4500,
|
|
9
9
|
hosting: 5000,
|
|
10
10
|
functions: 5001,
|
|
11
|
+
extensions: 5001,
|
|
11
12
|
firestore: 8080,
|
|
12
13
|
pubsub: 8085,
|
|
13
14
|
database: 9000,
|
|
@@ -25,6 +26,7 @@ exports.FIND_AVAILBLE_PORT_BY_DEFAULT = {
|
|
|
25
26
|
pubsub: false,
|
|
26
27
|
auth: false,
|
|
27
28
|
storage: false,
|
|
29
|
+
extensions: false,
|
|
28
30
|
};
|
|
29
31
|
exports.EMULATOR_DESCRIPTION = {
|
|
30
32
|
ui: "Emulator UI",
|
|
@@ -37,6 +39,7 @@ exports.EMULATOR_DESCRIPTION = {
|
|
|
37
39
|
pubsub: "Pub/Sub Emulator",
|
|
38
40
|
auth: "Authentication Emulator",
|
|
39
41
|
storage: "Storage Emulator",
|
|
42
|
+
extensions: "Extensions Emulator",
|
|
40
43
|
};
|
|
41
44
|
const DEFAULT_HOST = "localhost";
|
|
42
45
|
class Constants {
|
|
@@ -35,8 +35,14 @@ const fsutils_1 = require("../fsutils");
|
|
|
35
35
|
const storage_1 = require("./storage");
|
|
36
36
|
const getDefaultDatabaseInstance_1 = require("../getDefaultDatabaseInstance");
|
|
37
37
|
const auth_2 = require("../auth");
|
|
38
|
+
const extensionsEmulator_1 = require("./extensionsEmulator");
|
|
39
|
+
const previews_1 = require("../previews");
|
|
40
|
+
const START_LOGGING_EMULATOR = utils.envOverride("START_LOGGING_EMULATOR", "false", (val) => val === "true");
|
|
38
41
|
async function getAndCheckAddress(emulator, options) {
|
|
39
42
|
var _a, _b, _c, _d;
|
|
43
|
+
if (emulator === types_1.Emulators.EXTENSIONS) {
|
|
44
|
+
emulator = types_1.Emulators.FUNCTIONS;
|
|
45
|
+
}
|
|
40
46
|
let host = ((_b = (_a = options.config.src.emulators) === null || _a === void 0 ? void 0 : _a[emulator]) === null || _b === void 0 ? void 0 : _b.host) || constants_1.Constants.getDefaultHost(emulator);
|
|
41
47
|
if (host === "localhost" && utils.isRunningInWSL()) {
|
|
42
48
|
host = "127.0.0.1";
|
|
@@ -56,7 +62,7 @@ async function getAndCheckAddress(emulator, options) {
|
|
|
56
62
|
if (!portOpen) {
|
|
57
63
|
if (findAvailablePort) {
|
|
58
64
|
const newPort = await portUtils.findAvailablePort(host, port);
|
|
59
|
-
if (newPort
|
|
65
|
+
if (newPort !== port) {
|
|
60
66
|
loggerForEmulator.logLabeled("WARN", emulator, `${constants_1.Constants.description(emulator)} unable to start on port ${port}, starting on ${newPort} instead.`);
|
|
61
67
|
port = newPort;
|
|
62
68
|
}
|
|
@@ -86,7 +92,7 @@ async function getAndCheckAddress(emulator, options) {
|
|
|
86
92
|
}
|
|
87
93
|
async function startEmulator(instance) {
|
|
88
94
|
const name = instance.getName();
|
|
89
|
-
track("Emulator Run", name);
|
|
95
|
+
void track("Emulator Run", name);
|
|
90
96
|
await registry_1.EmulatorRegistry.start(instance);
|
|
91
97
|
}
|
|
92
98
|
exports.startEmulator = startEmulator;
|
|
@@ -115,7 +121,11 @@ async function cleanShutdown() {
|
|
|
115
121
|
}
|
|
116
122
|
exports.cleanShutdown = cleanShutdown;
|
|
117
123
|
function filterEmulatorTargets(options) {
|
|
118
|
-
let targets = types_1.ALL_SERVICE_EMULATORS
|
|
124
|
+
let targets = [...types_1.ALL_SERVICE_EMULATORS];
|
|
125
|
+
if (previews_1.previews.extensionsemulator) {
|
|
126
|
+
targets.push(types_1.Emulators.EXTENSIONS);
|
|
127
|
+
}
|
|
128
|
+
targets = targets.filter((e) => {
|
|
119
129
|
return options.config.has(e) || options.config.has(`emulators.${e}`);
|
|
120
130
|
});
|
|
121
131
|
const onlyOptions = options.only;
|
|
@@ -222,7 +232,7 @@ async function startAll(options, showUI = true) {
|
|
|
222
232
|
if (shouldStart(options, types_1.Emulators.HUB)) {
|
|
223
233
|
const hubAddr = await getAndCheckAddress(types_1.Emulators.HUB, options);
|
|
224
234
|
const hub = new hub_1.EmulatorHub(Object.assign({ projectId }, hubAddr));
|
|
225
|
-
track("emulators:start", "hub");
|
|
235
|
+
void track("emulators:start", "hub");
|
|
226
236
|
await startEmulator(hub);
|
|
227
237
|
}
|
|
228
238
|
let exportMetadata = {
|
|
@@ -239,18 +249,43 @@ async function startAll(options, showUI = true) {
|
|
|
239
249
|
hubLogger.logLabeled("WARN", "emulators", `Could not find import/export metadata file, ${clc.bold("skipping data import!")}`);
|
|
240
250
|
}
|
|
241
251
|
}
|
|
252
|
+
const emulatableBackends = [];
|
|
253
|
+
const projectDir = (options.extDevDir || options.config.projectDir);
|
|
242
254
|
if (shouldStart(options, types_1.Emulators.FUNCTIONS)) {
|
|
255
|
+
utils.assertDefined(options.config.src.functions);
|
|
256
|
+
utils.assertDefined(options.config.src.functions.source, "Error: 'functions.source' is not defined");
|
|
257
|
+
utils.assertIsStringOrUndefined(options.extDevDir);
|
|
258
|
+
const functionsDir = path.join(projectDir, options.config.src.functions.source);
|
|
259
|
+
emulatableBackends.push({
|
|
260
|
+
functionsDir,
|
|
261
|
+
env: Object.assign({}, options.extDevEnv),
|
|
262
|
+
predefinedTriggers: options.extDevTriggers,
|
|
263
|
+
nodeMajorVersion: (0, functionsEmulatorUtils_1.parseRuntimeVersion)(options.extDevNodeVersion || options.config.get("functions.runtime")),
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
if (shouldStart(options, types_1.Emulators.EXTENSIONS) && previews_1.previews.extensionsemulator) {
|
|
267
|
+
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
268
|
+
const aliases = (0, projectUtils_1.getAliases)(options, projectId);
|
|
269
|
+
const extensionEmulator = new extensionsEmulator_1.ExtensionsEmulator({
|
|
270
|
+
projectId,
|
|
271
|
+
projectDir: options.config.projectDir,
|
|
272
|
+
projectNumber,
|
|
273
|
+
aliases,
|
|
274
|
+
extensions: options.config.get("extensions"),
|
|
275
|
+
});
|
|
276
|
+
const extensionsBackends = await extensionEmulator.getExtensionBackends();
|
|
277
|
+
emulatableBackends.push(...extensionsBackends);
|
|
278
|
+
void track("Emulator Run", types_1.Emulators.EXTENSIONS);
|
|
279
|
+
registry_1.EmulatorRegistry.registerExtensionsEmulator();
|
|
280
|
+
}
|
|
281
|
+
if (emulatableBackends.length) {
|
|
243
282
|
const functionsLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
244
283
|
const functionsAddr = await getAndCheckAddress(types_1.Emulators.FUNCTIONS, options);
|
|
245
284
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
246
|
-
utils.assertDefined(options.config.src.functions);
|
|
247
|
-
utils.assertDefined(options.config.src.functions.source, "Error: 'functions.source' is not defined");
|
|
248
|
-
utils.assertIsStringOrUndefined(options.extensionDir);
|
|
249
|
-
const functionsDir = path.join(options.extensionDir || options.config.projectDir, options.config.src.functions.source);
|
|
250
285
|
let inspectFunctions;
|
|
251
286
|
if (options.inspectFunctions) {
|
|
252
287
|
inspectFunctions = commandUtils.parseInspectionPort(options);
|
|
253
|
-
functionsLogger.logLabeled("WARN", "functions", `You are running the
|
|
288
|
+
functionsLogger.logLabeled("WARN", "functions", `You are running the Functions emulator in debug mode (port=${inspectFunctions}). This means that functions will execute in sequence rather than in parallel.`);
|
|
254
289
|
}
|
|
255
290
|
const emulatorsNotRunning = types_1.ALL_SERVICE_EMULATORS.filter((e) => {
|
|
256
291
|
return e !== types_1.Emulators.FUNCTIONS && !shouldStart(options, e);
|
|
@@ -259,16 +294,9 @@ async function startAll(options, showUI = true) {
|
|
|
259
294
|
functionsLogger.logLabeled("WARN", "functions", `The following emulators are not running, calls to these services from the Functions emulator will affect production: ${clc.bold(emulatorsNotRunning.join(", "))}`);
|
|
260
295
|
}
|
|
261
296
|
const account = (0, auth_2.getProjectDefaultAccount)(options.projectRoot);
|
|
262
|
-
const emulatableBackends = [
|
|
263
|
-
{
|
|
264
|
-
functionsDir,
|
|
265
|
-
env: Object.assign({}, options.extensionEnv),
|
|
266
|
-
predefinedTriggers: options.extensionTriggers,
|
|
267
|
-
nodeMajorVersion: (0, functionsEmulatorUtils_1.parseRuntimeVersion)(options.extensionNodeVersion || options.config.get("functions.runtime")),
|
|
268
|
-
},
|
|
269
|
-
];
|
|
270
297
|
const functionsEmulator = new functionsEmulator_1.FunctionsEmulator({
|
|
271
298
|
projectId,
|
|
299
|
+
projectDir,
|
|
272
300
|
emulatableBackends,
|
|
273
301
|
account,
|
|
274
302
|
host: functionsAddr.host,
|
|
@@ -423,13 +451,15 @@ async function startAll(options, showUI = true) {
|
|
|
423
451
|
if (showUI && !shouldStart(options, types_1.Emulators.UI)) {
|
|
424
452
|
hubLogger.logLabeled("WARN", "emulators", "The Emulator UI requires a project ID to start. Configure your default project with 'firebase use' or pass the --project flag.");
|
|
425
453
|
}
|
|
426
|
-
if (showUI && shouldStart(options, types_1.Emulators.UI)) {
|
|
454
|
+
if (showUI && (shouldStart(options, types_1.Emulators.UI) || START_LOGGING_EMULATOR)) {
|
|
427
455
|
const loggingAddr = await getAndCheckAddress(types_1.Emulators.LOGGING, options);
|
|
428
456
|
const loggingEmulator = new loggingEmulator_1.LoggingEmulator({
|
|
429
457
|
host: loggingAddr.host,
|
|
430
458
|
port: loggingAddr.port,
|
|
431
459
|
});
|
|
432
460
|
await startEmulator(loggingEmulator);
|
|
461
|
+
}
|
|
462
|
+
if (showUI && shouldStart(options, types_1.Emulators.UI)) {
|
|
433
463
|
const uiAddr = await getAndCheckAddress(types_1.Emulators.UI, options);
|
|
434
464
|
const ui = new ui_1.EmulatorUI(Object.assign({ projectId: projectId, auto_download: true }, uiAddr));
|
|
435
465
|
await startEmulator(ui);
|
package/lib/emulator/download.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.downloadEmulator = void 0;
|
|
3
|
+
exports.downloadExtensionVersion = exports.downloadEmulator = void 0;
|
|
4
4
|
const crypto = require("crypto");
|
|
5
5
|
const fs = require("fs-extra");
|
|
6
6
|
const path = require("path");
|
|
@@ -32,6 +32,23 @@ async function downloadEmulator(name) {
|
|
|
32
32
|
removeOldFiles(name, emulator);
|
|
33
33
|
}
|
|
34
34
|
exports.downloadEmulator = downloadEmulator;
|
|
35
|
+
async function downloadExtensionVersion(extensionVersionRef, sourceDownloadUri, targetDir) {
|
|
36
|
+
const emulatorLogger = emulatorLogger_1.EmulatorLogger.forExtension({ ref: extensionVersionRef });
|
|
37
|
+
emulatorLogger.logLabeled("BULLET", "extensions", `Starting download for ${extensionVersionRef} source code...`);
|
|
38
|
+
try {
|
|
39
|
+
fs.mkdirSync(targetDir);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
emulatorLogger.logLabeled("BULLET", "extensions", `cache directory for ${extensionVersionRef} already exists...`);
|
|
43
|
+
}
|
|
44
|
+
emulatorLogger.logLabeled("BULLET", "extensions", `downloading ${sourceDownloadUri}...`);
|
|
45
|
+
const sourceCodeZip = await downloadUtils.downloadToTmp(sourceDownloadUri);
|
|
46
|
+
await unzip(sourceCodeZip, targetDir);
|
|
47
|
+
fs.chmodSync(targetDir, 0o755);
|
|
48
|
+
emulatorLogger.logLabeled("BULLET", "extensions", `Downloaded to ${targetDir}...`);
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
50
|
+
}
|
|
51
|
+
exports.downloadExtensionVersion = downloadExtensionVersion;
|
|
35
52
|
function unzip(zipPath, unzipDir) {
|
|
36
53
|
return new Promise((resolve, reject) => {
|
|
37
54
|
fs.createReadStream(zipPath)
|
|
@@ -13,6 +13,7 @@ const path = require("path");
|
|
|
13
13
|
const os = require("os");
|
|
14
14
|
const registry_1 = require("./registry");
|
|
15
15
|
const download_1 = require("../emulator/download");
|
|
16
|
+
const previews_1 = require("../previews");
|
|
16
17
|
const EMULATOR_INSTANCE_KILL_TIMEOUT = 4000;
|
|
17
18
|
const CACHE_DIR = process.env.FIREBASE_EMULATORS_PATH || path.join(os.homedir(), ".cache", "firebase", "emulators");
|
|
18
19
|
exports.DownloadDetails = {
|
|
@@ -49,19 +50,35 @@ exports.DownloadDetails = {
|
|
|
49
50
|
namePrefix: "cloud-storage-rules-emulator",
|
|
50
51
|
},
|
|
51
52
|
},
|
|
52
|
-
ui:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
ui: previews_1.previews.emulatoruisnapshot
|
|
54
|
+
? {
|
|
55
|
+
version: "SNAPSHOT",
|
|
56
|
+
downloadPath: path.join(CACHE_DIR, "ui-vSNAPSHOT.zip"),
|
|
57
|
+
unzipDir: path.join(CACHE_DIR, "ui-vSNAPSHOT"),
|
|
58
|
+
binaryPath: path.join(CACHE_DIR, "ui-vSNAPSHOT", "server.bundle.js"),
|
|
59
|
+
opts: {
|
|
60
|
+
cacheDir: CACHE_DIR,
|
|
61
|
+
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-vSNAPSHOT.zip",
|
|
62
|
+
expectedSize: -1,
|
|
63
|
+
expectedChecksum: "",
|
|
64
|
+
skipCache: true,
|
|
65
|
+
skipChecksumAndSize: true,
|
|
66
|
+
namePrefix: "ui",
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
: {
|
|
70
|
+
version: "1.6.5",
|
|
71
|
+
downloadPath: path.join(CACHE_DIR, "ui-v1.6.5.zip"),
|
|
72
|
+
unzipDir: path.join(CACHE_DIR, "ui-v1.6.5"),
|
|
73
|
+
binaryPath: path.join(CACHE_DIR, "ui-v1.6.5", "server.bundle.js"),
|
|
74
|
+
opts: {
|
|
75
|
+
cacheDir: CACHE_DIR,
|
|
76
|
+
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-v1.6.5.zip",
|
|
77
|
+
expectedSize: 3816994,
|
|
78
|
+
expectedChecksum: "92dfff4b2ef8ab616e8a60cc93e0a00b",
|
|
79
|
+
namePrefix: "ui",
|
|
80
|
+
},
|
|
63
81
|
},
|
|
64
|
-
},
|
|
65
82
|
pubsub: {
|
|
66
83
|
downloadPath: path.join(CACHE_DIR, "pubsub-emulator-0.1.0.zip"),
|
|
67
84
|
version: "0.1.0",
|
|
@@ -131,8 +148,8 @@ const Commands = {
|
|
|
131
148
|
storage: {
|
|
132
149
|
binary: "java",
|
|
133
150
|
args: [
|
|
134
|
-
"-jar",
|
|
135
151
|
"-Duser.language=en",
|
|
152
|
+
"-jar",
|
|
136
153
|
getExecPath(types_1.Emulators.STORAGE),
|
|
137
154
|
"serve",
|
|
138
155
|
],
|