firebase-tools 11.18.0 → 11.19.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/api.js +3 -2
- package/lib/commands/index.js +5 -0
- package/lib/commands/internaltesting-functions-discover.js +25 -0
- package/lib/deploy/extensions/prepare.js +6 -1
- package/lib/deploy/extensions/v2FunctionHelper.js +53 -0
- package/lib/deploy/functions/build.js +17 -2
- package/lib/deploy/functions/cel.js +90 -13
- package/lib/deploy/functions/params.js +141 -6
- package/lib/deploy/functions/prepare.js +40 -25
- package/lib/deploy/functions/release/fabricator.js +27 -1
- package/lib/deploy/functions/runtimes/discovery/parsing.js +7 -1
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +1 -1
- package/lib/deploy/functions/runtimes/node/index.js +2 -2
- package/lib/deploy/functions/runtimes/node/versioning.js +30 -14
- package/lib/emulator/commandUtils.js +2 -1
- package/lib/emulator/downloadableEmulators.js +3 -3
- package/lib/emulator/env.js +29 -27
- package/lib/emulator/functionsEmulator.js +15 -7
- package/lib/emulator/storage/rules/runtime.js +2 -2
- package/lib/emulator/workQueue.js +11 -6
- package/lib/experiments.js +6 -0
- package/lib/frameworks/index.js +7 -1
- package/lib/frameworks/next/constants.js +10 -0
- package/lib/frameworks/next/index.js +146 -146
- package/lib/frameworks/next/utils.js +65 -7
- package/lib/gcp/eventarc.js +42 -0
- package/npm-shrinkwrap.json +2 -93
- package/package.json +1 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveCpuAndConcurrency = exports.inferBlockingDetails = exports.updateEndpointTargetedStatus = exports.inferDetailsFromExisting = exports.prepare = exports.EVENTARC_SOURCE_ENV = void 0;
|
|
3
|
+
exports.loadCodebases = exports.resolveCpuAndConcurrency = exports.inferBlockingDetails = exports.updateEndpointTargetedStatus = exports.inferDetailsFromExisting = exports.prepare = exports.EVENTARC_SOURCE_ENV = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const backend = require("./backend");
|
|
6
6
|
const build = require("./build");
|
|
@@ -31,7 +31,7 @@ function hasUserConfig(config) {
|
|
|
31
31
|
return Object.keys(config).length > 1;
|
|
32
32
|
}
|
|
33
33
|
async function prepare(context, options, payload) {
|
|
34
|
-
var _a;
|
|
34
|
+
var _a, _b;
|
|
35
35
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
36
36
|
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
37
37
|
context.config = (0, projectConfig_1.normalizeAndValidate)(options.config.src.functions);
|
|
@@ -40,6 +40,9 @@ async function prepare(context, options, payload) {
|
|
|
40
40
|
if (codebases.length === 0) {
|
|
41
41
|
throw new error_1.FirebaseError("No function matches given --only filters. Aborting deployment.");
|
|
42
42
|
}
|
|
43
|
+
for (const codebase of codebases) {
|
|
44
|
+
(0, utils_1.logLabeledBullet)("functions", `preparing codebase ${clc.bold(codebase)} for deployment`);
|
|
45
|
+
}
|
|
43
46
|
const checkAPIsEnabled = await Promise.all([
|
|
44
47
|
ensureApiEnabled.ensure(projectId, "cloudfunctions.googleapis.com", "functions"),
|
|
45
48
|
ensureApiEnabled.check(projectId, "runtimeconfig.googleapis.com", "runtimeconfig", true),
|
|
@@ -52,45 +55,28 @@ async function prepare(context, options, payload) {
|
|
|
52
55
|
if (checkAPIsEnabled[1]) {
|
|
53
56
|
runtimeConfig = Object.assign(Object.assign({}, runtimeConfig), (await (0, prepareFunctionsUpload_1.getFunctionsConfig)(projectId)));
|
|
54
57
|
}
|
|
55
|
-
context.
|
|
58
|
+
const wantBuilds = await loadCodebases(context.config, options, firebaseConfig, runtimeConfig, context.filters);
|
|
56
59
|
const codebaseUsesEnvs = [];
|
|
57
60
|
const wantBackends = {};
|
|
58
|
-
for (const codebase of
|
|
59
|
-
(0, utils_1.logLabeledBullet)("functions", `preparing codebase ${clc.bold(codebase)} for deployment`);
|
|
61
|
+
for (const [codebase, wantBuild] of Object.entries(wantBuilds)) {
|
|
60
62
|
const config = (0, projectConfig_1.configForCodebase)(context.config, codebase);
|
|
61
|
-
const sourceDirName = config.source;
|
|
62
|
-
if (!sourceDirName) {
|
|
63
|
-
throw new error_1.FirebaseError(`No functions code detected at default location (./functions), and no functions source defined in firebase.json`);
|
|
64
|
-
}
|
|
65
|
-
const sourceDir = options.config.path(sourceDirName);
|
|
66
|
-
const delegateContext = {
|
|
67
|
-
projectId,
|
|
68
|
-
sourceDir,
|
|
69
|
-
projectDir: options.config.projectDir,
|
|
70
|
-
runtime: config.runtime || "",
|
|
71
|
-
};
|
|
72
|
-
const runtimeDelegate = await runtimes.getRuntimeDelegate(delegateContext);
|
|
73
|
-
logger_1.logger.debug(`Validating ${runtimeDelegate.name} source`);
|
|
74
|
-
await runtimeDelegate.validate();
|
|
75
|
-
logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
|
|
76
|
-
await runtimeDelegate.build();
|
|
77
63
|
const firebaseEnvs = functionsEnv.loadFirebaseEnvs(firebaseConfig, projectId);
|
|
78
64
|
const userEnvOpt = {
|
|
79
|
-
functionsSource:
|
|
65
|
+
functionsSource: options.config.path(config.source),
|
|
80
66
|
projectId: projectId,
|
|
81
67
|
projectAlias: options.projectAlias,
|
|
82
68
|
};
|
|
83
69
|
const userEnvs = functionsEnv.loadUserEnvs(userEnvOpt);
|
|
84
70
|
const envs = Object.assign(Object.assign({}, userEnvs), firebaseEnvs);
|
|
85
|
-
const wantBuild = await runtimeDelegate.discoverBuild(runtimeConfig, firebaseEnvs);
|
|
86
71
|
const { backend: wantBackend, envs: resolvedEnvs } = await build.resolveBackend(wantBuild, firebaseConfig, userEnvOpt, userEnvs, options.nonInteractive);
|
|
87
72
|
let hasEnvsFromParams = false;
|
|
88
73
|
wantBackend.environmentVariables = envs;
|
|
89
74
|
for (const envName of Object.keys(resolvedEnvs)) {
|
|
90
|
-
const
|
|
75
|
+
const isList = (_a = resolvedEnvs[envName]) === null || _a === void 0 ? void 0 : _a.legalList;
|
|
76
|
+
const envValue = (_b = resolvedEnvs[envName]) === null || _b === void 0 ? void 0 : _b.toSDK();
|
|
91
77
|
if (envValue &&
|
|
92
78
|
!resolvedEnvs[envName].internal &&
|
|
93
|
-
!Object.prototype.hasOwnProperty.call(wantBackend.environmentVariables, envName)) {
|
|
79
|
+
(!Object.prototype.hasOwnProperty.call(wantBackend.environmentVariables, envName) || isList)) {
|
|
94
80
|
wantBackend.environmentVariables[envName] = envValue;
|
|
95
81
|
hasEnvsFromParams = true;
|
|
96
82
|
}
|
|
@@ -127,6 +113,7 @@ async function prepare(context, options, payload) {
|
|
|
127
113
|
}
|
|
128
114
|
}
|
|
129
115
|
validate.endpointsAreUnique(wantBackends);
|
|
116
|
+
context.sources = {};
|
|
130
117
|
for (const [codebase, wantBackend] of Object.entries(wantBackends)) {
|
|
131
118
|
const config = (0, projectConfig_1.configForCodebase)(context.config, codebase);
|
|
132
119
|
const sourceDirName = config.source;
|
|
@@ -291,3 +278,31 @@ function resolveCpuAndConcurrency(want) {
|
|
|
291
278
|
}
|
|
292
279
|
}
|
|
293
280
|
exports.resolveCpuAndConcurrency = resolveCpuAndConcurrency;
|
|
281
|
+
async function loadCodebases(config, options, firebaseConfig, runtimeConfig, filters) {
|
|
282
|
+
const codebases = (0, functionsDeployHelper_1.targetCodebases)(config, filters);
|
|
283
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
284
|
+
const wantBuilds = {};
|
|
285
|
+
for (const codebase of codebases) {
|
|
286
|
+
const codebaseConfig = (0, projectConfig_1.configForCodebase)(config, codebase);
|
|
287
|
+
const sourceDirName = codebaseConfig.source;
|
|
288
|
+
if (!sourceDirName) {
|
|
289
|
+
throw new error_1.FirebaseError(`No functions code detected at default location (./functions), and no functions source defined in firebase.json`);
|
|
290
|
+
}
|
|
291
|
+
const sourceDir = options.config.path(sourceDirName);
|
|
292
|
+
const delegateContext = {
|
|
293
|
+
projectId,
|
|
294
|
+
sourceDir,
|
|
295
|
+
projectDir: options.config.projectDir,
|
|
296
|
+
runtime: codebaseConfig.runtime || "",
|
|
297
|
+
};
|
|
298
|
+
const runtimeDelegate = await runtimes.getRuntimeDelegate(delegateContext);
|
|
299
|
+
logger_1.logger.debug(`Validating ${runtimeDelegate.name} source`);
|
|
300
|
+
await runtimeDelegate.validate();
|
|
301
|
+
logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
|
|
302
|
+
await runtimeDelegate.build();
|
|
303
|
+
const firebaseEnvs = functionsEnv.loadFirebaseEnvs(firebaseConfig, projectId);
|
|
304
|
+
wantBuilds[codebase] = await runtimeDelegate.discoverBuild(runtimeConfig, firebaseEnvs);
|
|
305
|
+
}
|
|
306
|
+
return wantBuilds;
|
|
307
|
+
}
|
|
308
|
+
exports.loadCodebases = loadCodebases;
|
|
@@ -14,6 +14,7 @@ const cloudtasks = require("../../../gcp/cloudtasks");
|
|
|
14
14
|
const deploymentTool = require("../../../deploymentTool");
|
|
15
15
|
const gcf = require("../../../gcp/cloudfunctions");
|
|
16
16
|
const gcfV2 = require("../../../gcp/cloudfunctionsv2");
|
|
17
|
+
const eventarc = require("../../../gcp/eventarc");
|
|
17
18
|
const helper = require("../functionsDeployHelper");
|
|
18
19
|
const poller = require("../../../operation-poller");
|
|
19
20
|
const pubsub = require("../../../gcp/pubsub");
|
|
@@ -36,6 +37,12 @@ const gcfV2PollerOptions = {
|
|
|
36
37
|
masterTimeout: 25 * 60 * 1000,
|
|
37
38
|
maxBackoff: 10000,
|
|
38
39
|
};
|
|
40
|
+
const eventarcPollerOptions = {
|
|
41
|
+
apiOrigin: api_1.eventarcOrigin,
|
|
42
|
+
apiVersion: "v1",
|
|
43
|
+
masterTimeout: 25 * 60 * 1000,
|
|
44
|
+
maxBackoff: 10000,
|
|
45
|
+
};
|
|
39
46
|
const rethrowAs = (endpoint, op) => (err) => {
|
|
40
47
|
logger_1.logger.error(err.message);
|
|
41
48
|
throw new reporter.DeploymentError(endpoint, op, err);
|
|
@@ -212,7 +219,7 @@ class Fabricator {
|
|
|
212
219
|
}
|
|
213
220
|
}
|
|
214
221
|
async createV2Function(endpoint) {
|
|
215
|
-
var _a, _b;
|
|
222
|
+
var _a, _b, _c;
|
|
216
223
|
const storage = (_a = this.sources[endpoint.codebase]) === null || _a === void 0 ? void 0 : _a.storage;
|
|
217
224
|
if (!storage) {
|
|
218
225
|
logger_1.logger.debug("Precondition failed. Cannot create a GCFv2 function without storage");
|
|
@@ -237,6 +244,25 @@ class Fabricator {
|
|
|
237
244
|
})
|
|
238
245
|
.catch(rethrowAs(endpoint, "create topic"));
|
|
239
246
|
}
|
|
247
|
+
const channel = (_c = apiFunction.eventTrigger) === null || _c === void 0 ? void 0 : _c.channel;
|
|
248
|
+
if (channel) {
|
|
249
|
+
await this.executor
|
|
250
|
+
.run(async () => {
|
|
251
|
+
try {
|
|
252
|
+
const op = await eventarc.createChannel({ name: channel });
|
|
253
|
+
return await poller.pollOperation(Object.assign(Object.assign({}, eventarcPollerOptions), { pollerName: `create-${channel}-${endpoint.region}-${endpoint.id}`, operationResourceName: op.name }));
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
if (err.status === 409) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
throw new error_1.FirebaseError("Unexpected error creating Eventarc channel", {
|
|
260
|
+
original: err,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
.catch(rethrowAs(endpoint, "upsert eventarc channel"));
|
|
265
|
+
}
|
|
240
266
|
const resultFunction = await this.functionExecutor
|
|
241
267
|
.run(async () => {
|
|
242
268
|
const op = await gcfV2.createFunction(apiFunction);
|
|
@@ -8,7 +8,7 @@ function requireKeys(prefix, yaml, ...keys) {
|
|
|
8
8
|
}
|
|
9
9
|
for (const key of keys) {
|
|
10
10
|
if (!yaml[key]) {
|
|
11
|
-
throw new error_1.FirebaseError(`Expected key ${prefix + key}`);
|
|
11
|
+
throw new error_1.FirebaseError(`Expected key ${prefix + key.toString()}`);
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -47,6 +47,12 @@ function assertKeyTypes(prefix, yaml, schema) {
|
|
|
47
47
|
}
|
|
48
48
|
continue;
|
|
49
49
|
}
|
|
50
|
+
if (schemaType === "List") {
|
|
51
|
+
if (typeof value !== "string" && !Array.isArray(value)) {
|
|
52
|
+
throw new error_1.FirebaseError(`Expected ${fullKey} to be a field list (array or list expression); was ${typeof value}`);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
50
56
|
if (value === null) {
|
|
51
57
|
if (schemaType.endsWith("?")) {
|
|
52
58
|
continue;
|
|
@@ -48,7 +48,7 @@ function parseRequiredAPIs(manifest) {
|
|
|
48
48
|
function assertBuildEndpoint(ep, id) {
|
|
49
49
|
const prefix = `endpoints[${id}]`;
|
|
50
50
|
(0, parsing_1.assertKeyTypes)(prefix, ep, {
|
|
51
|
-
region: "
|
|
51
|
+
region: "List",
|
|
52
52
|
platform: (platform) => build.AllFunctionsPlatforms.includes(platform),
|
|
53
53
|
entryPoint: "string",
|
|
54
54
|
omit: "Field<boolean>?",
|
|
@@ -38,10 +38,10 @@ class Delegate {
|
|
|
38
38
|
this.sourceDir = sourceDir;
|
|
39
39
|
this.runtime = runtime;
|
|
40
40
|
this.name = "nodejs";
|
|
41
|
-
this._sdkVersion =
|
|
41
|
+
this._sdkVersion = undefined;
|
|
42
42
|
}
|
|
43
43
|
get sdkVersion() {
|
|
44
|
-
if (
|
|
44
|
+
if (this._sdkVersion === undefined) {
|
|
45
45
|
this._sdkVersion = versioning.getFunctionsSDKVersion(this.sourceDir) || "";
|
|
46
46
|
}
|
|
47
47
|
return this._sdkVersion;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkFunctionsSDKVersion = exports.getLatestSDKVersion = exports.getFunctionsSDKVersion = exports.FUNCTIONS_SDK_VERSION_TOO_OLD_WARNING = void 0;
|
|
4
|
-
const
|
|
3
|
+
exports.checkFunctionsSDKVersion = exports.getLatestSDKVersion = exports.getFunctionsSDKVersion = exports.findModuleVersion = exports.FUNCTIONS_SDK_VERSION_TOO_OLD_WARNING = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
5
6
|
const clc = require("colorette");
|
|
6
7
|
const semver = require("semver");
|
|
7
8
|
const spawn = require("cross-spawn");
|
|
@@ -15,26 +16,41 @@ exports.FUNCTIONS_SDK_VERSION_TOO_OLD_WARNING = clc.bold(clc.yellow("functions:
|
|
|
15
16
|
" version that is at least 2.0.0. Please run " +
|
|
16
17
|
clc.bold("npm i --save firebase-functions@latest") +
|
|
17
18
|
" in the functions folder.";
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
24
|
-
if (child.error) {
|
|
25
|
-
logger_1.logger.debug("getFunctionsSDKVersion encountered error:", child.error.stack);
|
|
19
|
+
function findModuleVersion(name, resolvedPath) {
|
|
20
|
+
let searchPath = path.dirname(resolvedPath);
|
|
21
|
+
while (true) {
|
|
22
|
+
if (searchPath === "/" || path.basename(searchPath) === "node_modules") {
|
|
23
|
+
logger_1.logger.debug(`Failed to find version of module ${name}: reached end of search path ${searchPath}`);
|
|
26
24
|
return;
|
|
27
25
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
26
|
+
const maybePackageJson = path.join(searchPath, "package.json");
|
|
27
|
+
if (fs.existsSync(maybePackageJson)) {
|
|
28
|
+
const pkg = require(maybePackageJson);
|
|
29
|
+
if (pkg.name === name) {
|
|
30
|
+
return pkg.version;
|
|
31
|
+
}
|
|
32
|
+
logger_1.logger.debug(`Failed to find version of module ${name}: instead found ${pkg.name} at ${searchPath}`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
searchPath = path.dirname(searchPath);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.findModuleVersion = findModuleVersion;
|
|
39
|
+
function getFunctionsSDKVersion(sourceDir) {
|
|
40
|
+
try {
|
|
41
|
+
return findModuleVersion("firebase-functions", require.resolve("firebase-functions", { paths: [sourceDir] }));
|
|
30
42
|
}
|
|
31
43
|
catch (e) {
|
|
44
|
+
if (e.code === "MODULE_NOT_FOUND") {
|
|
45
|
+
utils.logLabeledWarning("functions", "Couldn't find firebase-functions package in your source code. Have you run 'npm install'?");
|
|
46
|
+
}
|
|
32
47
|
logger_1.logger.debug("getFunctionsSDKVersion encountered error:", e);
|
|
33
48
|
return;
|
|
34
49
|
}
|
|
35
50
|
}
|
|
36
51
|
exports.getFunctionsSDKVersion = getFunctionsSDKVersion;
|
|
37
52
|
function getLatestSDKVersion() {
|
|
53
|
+
var _a;
|
|
38
54
|
const child = spawn.sync("npm", ["show", "firebase-functions", "--json=true"], {
|
|
39
55
|
encoding: "utf8",
|
|
40
56
|
});
|
|
@@ -43,10 +59,10 @@ function getLatestSDKVersion() {
|
|
|
43
59
|
return;
|
|
44
60
|
}
|
|
45
61
|
const output = JSON.parse(child.stdout);
|
|
46
|
-
if (
|
|
62
|
+
if (Object.keys(output).length === 0) {
|
|
47
63
|
return;
|
|
48
64
|
}
|
|
49
|
-
return
|
|
65
|
+
return (_a = output["dist-tags"]) === null || _a === void 0 ? void 0 : _a["latest"];
|
|
50
66
|
}
|
|
51
67
|
exports.getLatestSDKVersion = getLatestSDKVersion;
|
|
52
68
|
function checkFunctionsSDKVersion(currentVersion) {
|
|
@@ -219,7 +219,8 @@ exports.shutdownWhenKilled = shutdownWhenKilled;
|
|
|
219
219
|
async function runScript(script, extraEnv) {
|
|
220
220
|
utils.logBullet(`Running script: ${clc.bold(script)}`);
|
|
221
221
|
const env = Object.assign(Object.assign({}, process.env), extraEnv);
|
|
222
|
-
|
|
222
|
+
const emulatorInfos = registry_1.EmulatorRegistry.listRunningWithInfo();
|
|
223
|
+
(0, env_1.setEnvVarsForEmulators)(env, emulatorInfos);
|
|
223
224
|
const proc = childProcess.spawn(script, {
|
|
224
225
|
stdio: ["inherit", "inherit", "inherit"],
|
|
225
226
|
shell: true,
|
|
@@ -28,9 +28,9 @@ const EMULATOR_UPDATE_DETAILS = {
|
|
|
28
28
|
expectedChecksum: "4f41d24a3c0f3b55ea22804a424cc0ee",
|
|
29
29
|
},
|
|
30
30
|
storage: {
|
|
31
|
-
version: "1.1.
|
|
32
|
-
expectedSize:
|
|
33
|
-
expectedChecksum: "
|
|
31
|
+
version: "1.1.2",
|
|
32
|
+
expectedSize: 47028740,
|
|
33
|
+
expectedChecksum: "983b4415b1e72b109864f1b8e7ea7546",
|
|
34
34
|
},
|
|
35
35
|
ui: experiments.isEnabled("emulatoruisnapshot")
|
|
36
36
|
? { version: "SNAPSHOT", expectedSize: -1, expectedChecksum: "" }
|
package/lib/emulator/env.js
CHANGED
|
@@ -3,33 +3,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.setEnvVarsForEmulators = void 0;
|
|
4
4
|
const constants_1 = require("./constants");
|
|
5
5
|
const types_1 = require("./types");
|
|
6
|
-
const
|
|
7
|
-
function setEnvVarsForEmulators(env) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
6
|
+
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
7
|
+
function setEnvVarsForEmulators(env, emulators) {
|
|
8
|
+
for (const emu of emulators) {
|
|
9
|
+
const host = (0, functionsEmulatorShared_1.formatHost)(emu);
|
|
10
|
+
switch (emu.name) {
|
|
11
|
+
case types_1.Emulators.FIRESTORE:
|
|
12
|
+
env[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = host;
|
|
13
|
+
env[constants_1.Constants.FIRESTORE_EMULATOR_ENV_ALT] = host;
|
|
14
|
+
break;
|
|
15
|
+
case types_1.Emulators.DATABASE:
|
|
16
|
+
env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = host;
|
|
17
|
+
break;
|
|
18
|
+
case types_1.Emulators.STORAGE:
|
|
19
|
+
env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = host;
|
|
20
|
+
env[constants_1.Constants.CLOUD_STORAGE_EMULATOR_HOST] = `http://${host}`;
|
|
21
|
+
break;
|
|
22
|
+
case types_1.Emulators.AUTH:
|
|
23
|
+
env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = host;
|
|
24
|
+
break;
|
|
25
|
+
case types_1.Emulators.HUB:
|
|
26
|
+
env[constants_1.Constants.FIREBASE_EMULATOR_HUB] = host;
|
|
27
|
+
break;
|
|
28
|
+
case types_1.Emulators.PUBSUB:
|
|
29
|
+
env[constants_1.Constants.PUBSUB_EMULATOR_HOST] = host;
|
|
30
|
+
break;
|
|
31
|
+
case types_1.Emulators.EVENTARC:
|
|
32
|
+
env[constants_1.Constants.CLOUD_EVENTARC_EMULATOR_HOST] = `http://${host}`;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
exports.setEnvVarsForEmulators = setEnvVarsForEmulators;
|
|
@@ -107,9 +107,11 @@ class FunctionsEmulator {
|
|
|
107
107
|
const httpsFunctionRoutes = [httpsFunctionRoute, `${httpsFunctionRoute}/*`];
|
|
108
108
|
const listBackendsRoute = `/backends`;
|
|
109
109
|
const httpsHandler = (req, res) => {
|
|
110
|
-
|
|
110
|
+
const work = () => {
|
|
111
111
|
return this.handleHttpsTrigger(req, res);
|
|
112
|
-
}
|
|
112
|
+
};
|
|
113
|
+
work.type = `${req.path}-${new Date().toISOString()}`;
|
|
114
|
+
this.workQueue.submit(work);
|
|
113
115
|
};
|
|
114
116
|
const multicastHandler = (req, res) => {
|
|
115
117
|
var _a;
|
|
@@ -129,7 +131,7 @@ class FunctionsEmulator {
|
|
|
129
131
|
const triggers = this.multicastTriggers[triggerKey] || [];
|
|
130
132
|
const { host, port } = this.getInfo();
|
|
131
133
|
triggers.forEach((triggerId) => {
|
|
132
|
-
|
|
134
|
+
const work = () => {
|
|
133
135
|
return new Promise((resolve, reject) => {
|
|
134
136
|
const trigReq = http.request({
|
|
135
137
|
host: (0, utils_1.connectableHostname)(host),
|
|
@@ -143,7 +145,9 @@ class FunctionsEmulator {
|
|
|
143
145
|
trigReq.end();
|
|
144
146
|
resolve();
|
|
145
147
|
});
|
|
146
|
-
}
|
|
148
|
+
};
|
|
149
|
+
work.type = `${triggerId}-${new Date().toISOString()}`;
|
|
150
|
+
this.workQueue.submit(work);
|
|
147
151
|
});
|
|
148
152
|
res.json({ status: "multicast_acknowledged" });
|
|
149
153
|
};
|
|
@@ -262,7 +266,6 @@ class FunctionsEmulator {
|
|
|
262
266
|
await runtimeDelegate.validate();
|
|
263
267
|
logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
|
|
264
268
|
await runtimeDelegate.build();
|
|
265
|
-
logger_1.logger.debug(`Analyzing ${runtimeDelegate.name} backend spec`);
|
|
266
269
|
const firebaseConfig = this.getFirebaseConfig();
|
|
267
270
|
const environment = Object.assign(Object.assign(Object.assign(Object.assign({}, this.getSystemEnvs()), this.getEmulatorEnvs()), { FIREBASE_CONFIG: firebaseConfig }), emulatableBackend.env);
|
|
268
271
|
const userEnvOpt = {
|
|
@@ -270,8 +273,9 @@ class FunctionsEmulator {
|
|
|
270
273
|
projectId: this.args.projectId,
|
|
271
274
|
projectAlias: this.args.projectAlias,
|
|
272
275
|
};
|
|
276
|
+
const userEnvs = functionsEnv.loadUserEnvs(userEnvOpt);
|
|
273
277
|
const discoveredBuild = await runtimeDelegate.discoverBuild(runtimeConfig, environment);
|
|
274
|
-
const resolution = await (0, build_1.resolveBackend)(discoveredBuild, JSON.parse(firebaseConfig), userEnvOpt,
|
|
278
|
+
const resolution = await (0, build_1.resolveBackend)(discoveredBuild, JSON.parse(firebaseConfig), userEnvOpt, userEnvs);
|
|
275
279
|
const discoveredBackend = resolution.backend;
|
|
276
280
|
const endpoints = backend.allEndpoints(discoveredBackend);
|
|
277
281
|
(0, functionsEmulatorShared_1.prepareEndpoints)(endpoints);
|
|
@@ -717,7 +721,11 @@ class FunctionsEmulator {
|
|
|
717
721
|
skipTokenVerification: true,
|
|
718
722
|
enableCors: true,
|
|
719
723
|
});
|
|
720
|
-
|
|
724
|
+
let emulatorInfos = registry_1.EmulatorRegistry.listRunningWithInfo();
|
|
725
|
+
if (this.args.remoteEmulators) {
|
|
726
|
+
emulatorInfos = emulatorInfos.concat(Object.values(this.args.remoteEmulators));
|
|
727
|
+
}
|
|
728
|
+
(0, env_1.setEnvVarsForEmulators)(envs, emulatorInfos);
|
|
721
729
|
if (this.args.debugPort) {
|
|
722
730
|
envs["FUNCTION_DEBUG_MODE"] = "true";
|
|
723
731
|
}
|
|
@@ -283,7 +283,7 @@ function toExpressionValue(obj) {
|
|
|
283
283
|
}
|
|
284
284
|
if (obj == null) {
|
|
285
285
|
return {
|
|
286
|
-
null_value:
|
|
286
|
+
null_value: null,
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
289
|
if (typeof obj === "object") {
|
|
@@ -339,7 +339,7 @@ function createRequestExpressionValue(opts) {
|
|
|
339
339
|
},
|
|
340
340
|
time: toExpressionValue(new Date()),
|
|
341
341
|
resource: toExpressionValue(opts.file.after ? opts.file.after : null),
|
|
342
|
-
auth: opts.token ? createAuthExpressionValue(opts) : { null_value:
|
|
342
|
+
auth: opts.token ? createAuthExpressionValue(opts) : { null_value: null },
|
|
343
343
|
};
|
|
344
344
|
return {
|
|
345
345
|
map_value: {
|
|
@@ -11,7 +11,7 @@ class WorkQueue {
|
|
|
11
11
|
this.maxParallelWork = maxParallelWork;
|
|
12
12
|
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
13
13
|
this.queue = [];
|
|
14
|
-
this.
|
|
14
|
+
this.running = [];
|
|
15
15
|
this.notifyQueue = () => {
|
|
16
16
|
};
|
|
17
17
|
this.notifyWorkFinish = () => {
|
|
@@ -37,8 +37,8 @@ class WorkQueue {
|
|
|
37
37
|
this.notifyQueue = res;
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
if (this.
|
|
41
|
-
this.logger.logLabeled("DEBUG", "work-queue", `waiting for work to finish (running=${this.
|
|
40
|
+
if (this.running.length >= this.maxParallelWork) {
|
|
41
|
+
this.logger.logLabeled("DEBUG", "work-queue", `waiting for work to finish (running=${this.running})`);
|
|
42
42
|
await new Promise((res) => {
|
|
43
43
|
this.notifyWorkFinish = res;
|
|
44
44
|
});
|
|
@@ -74,8 +74,10 @@ class WorkQueue {
|
|
|
74
74
|
}
|
|
75
75
|
getState() {
|
|
76
76
|
return {
|
|
77
|
+
queuedWork: this.queue.map((work) => work.type),
|
|
77
78
|
queueLength: this.queue.length,
|
|
78
|
-
|
|
79
|
+
runningWork: this.running,
|
|
80
|
+
workRunningCount: this.running.length,
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
83
|
isWorking() {
|
|
@@ -85,7 +87,7 @@ class WorkQueue {
|
|
|
85
87
|
async runNext() {
|
|
86
88
|
const next = this.queue.shift();
|
|
87
89
|
if (next) {
|
|
88
|
-
this.
|
|
90
|
+
this.running.push(next.type || "anonymous");
|
|
89
91
|
this.logState();
|
|
90
92
|
try {
|
|
91
93
|
await next();
|
|
@@ -94,7 +96,10 @@ class WorkQueue {
|
|
|
94
96
|
this.logger.log("DEBUG", e);
|
|
95
97
|
}
|
|
96
98
|
finally {
|
|
97
|
-
this.
|
|
99
|
+
const index = this.running.indexOf(next.type || "anonymous");
|
|
100
|
+
if (index !== -1) {
|
|
101
|
+
this.running.splice(index, 1);
|
|
102
|
+
}
|
|
98
103
|
this.notifyWorkFinish();
|
|
99
104
|
this.logState();
|
|
100
105
|
}
|
package/lib/experiments.js
CHANGED
|
@@ -74,6 +74,12 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
74
74
|
crossservicerules: {
|
|
75
75
|
shortDescription: "Allow Firebase Rules to reference resources in other services",
|
|
76
76
|
},
|
|
77
|
+
internaltesting: {
|
|
78
|
+
shortDescription: "Exposes Firebase CLI commands intended for internal testing purposes.",
|
|
79
|
+
fullDescription: "Exposes Firebase CLI commands intended for internal testing purposes. " +
|
|
80
|
+
"These commands are not meant for public consumption and may break or disappear " +
|
|
81
|
+
"without a notice.",
|
|
82
|
+
},
|
|
77
83
|
});
|
|
78
84
|
function isValidExperiment(name) {
|
|
79
85
|
return Object.keys(exports.ALL_EXPERIMENTS).includes(name);
|
package/lib/frameworks/index.js
CHANGED
|
@@ -230,7 +230,10 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
230
230
|
const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, } = exports.WebFrameworks[framework];
|
|
231
231
|
console.log(`Detected a ${name} codebase. ${SupportLevelWarnings[support] || ""}\n`);
|
|
232
232
|
const isDevMode = context._name === "serve" || context._name === "emulators:start";
|
|
233
|
-
const
|
|
233
|
+
const hostingEmulatorInfo = emulators.find((e) => e.name === types_1.Emulators.HOSTING);
|
|
234
|
+
const devModeHandle = isDevMode &&
|
|
235
|
+
getDevModeHandle &&
|
|
236
|
+
(await getDevModeHandle(getProjectPath(), hostingEmulatorInfo));
|
|
234
237
|
let codegenFunctionsDirectory;
|
|
235
238
|
if (devModeHandle) {
|
|
236
239
|
config.public = (0, path_1.relative)(projectRoot, publicDirectory);
|
|
@@ -326,6 +329,9 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
326
329
|
${firebaseDefaults ? `__FIREBASE_DEFAULTS__=${JSON.stringify(firebaseDefaults)}\n` : ""}`);
|
|
327
330
|
await (0, promises_1.copyFile)(getProjectPath("package-lock.json"), (0, path_1.join)(functionsDist, "package-lock.json")).catch(() => {
|
|
328
331
|
});
|
|
332
|
+
if (await (0, fs_extra_1.pathExists)(getProjectPath(".npmrc"))) {
|
|
333
|
+
await (0, promises_1.copyFile)(getProjectPath(".npmrc"), (0, path_1.join)(functionsDist, ".npmrc"));
|
|
334
|
+
}
|
|
329
335
|
(0, child_process_1.execSync)(`${NPM_COMMAND} i --omit dev --no-audit`, {
|
|
330
336
|
cwd: functionsDist,
|
|
331
337
|
stdio: "inherit",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ROUTES_MANIFEST = exports.PRERENDER_MANIFEST = exports.PAGES_MANIFEST = exports.MIDDLEWARE_MANIFEST = exports.IMAGES_MANIFEST = exports.EXPORT_MARKER = exports.APP_PATH_ROUTES_MANIFEST = void 0;
|
|
4
|
+
exports.APP_PATH_ROUTES_MANIFEST = "app-path-routes-manifest.json";
|
|
5
|
+
exports.EXPORT_MARKER = "export-marker.json";
|
|
6
|
+
exports.IMAGES_MANIFEST = "images-manifest.json";
|
|
7
|
+
exports.MIDDLEWARE_MANIFEST = "middleware-manifest.json";
|
|
8
|
+
exports.PAGES_MANIFEST = "pages-manifest.json";
|
|
9
|
+
exports.PRERENDER_MANIFEST = "prerender-manifest.json";
|
|
10
|
+
exports.ROUTES_MANIFEST = "routes-manifest.json";
|