firebase-tools 11.29.0 → 11.30.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.
Files changed (52) hide show
  1. package/lib/commands/database-import.js +2 -2
  2. package/lib/commands/hosting-channel-deploy.js +3 -0
  3. package/lib/database/import.js +113 -18
  4. package/lib/deploy/extensions/secrets.js +2 -2
  5. package/lib/deploy/functions/ensure.js +7 -1
  6. package/lib/deploy/functions/release/fabricator.js +2 -0
  7. package/lib/deploy/functions/runtimes/discovery/index.js +1 -1
  8. package/lib/deploy/functions/runtimes/index.js +11 -3
  9. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +3 -3
  10. package/lib/deploy/functions/runtimes/python/index.js +41 -13
  11. package/lib/deploy/hosting/convertConfig.js +8 -4
  12. package/lib/deploy/hosting/prepare.js +115 -2
  13. package/lib/deploy/index.js +24 -8
  14. package/lib/emulator/adminSdkConfig.js +8 -0
  15. package/lib/emulator/controller.js +7 -9
  16. package/lib/emulator/download.js +3 -12
  17. package/lib/emulator/downloadableEmulators.js +5 -5
  18. package/lib/emulator/functionsEmulator.js +57 -7
  19. package/lib/emulator/functionsEmulatorRuntime.js +4 -1
  20. package/lib/emulator/functionsEmulatorShared.js +1 -0
  21. package/lib/emulator/functionsRuntimeWorker.js +12 -4
  22. package/lib/experiments.js +20 -7
  23. package/lib/extensions/extensionsHelper.js +2 -2
  24. package/lib/frameworks/angular/index.js +13 -13
  25. package/lib/frameworks/astro/index.js +3 -4
  26. package/lib/frameworks/constants.js +42 -0
  27. package/lib/frameworks/express/index.js +3 -2
  28. package/lib/frameworks/flutter/index.js +39 -0
  29. package/lib/frameworks/flutter/utils.js +11 -0
  30. package/lib/frameworks/index.js +58 -131
  31. package/lib/frameworks/interfaces.js +2 -0
  32. package/lib/frameworks/next/constants.js +2 -1
  33. package/lib/frameworks/next/index.js +124 -87
  34. package/lib/frameworks/next/utils.js +71 -6
  35. package/lib/frameworks/nuxt/index.js +4 -5
  36. package/lib/frameworks/nuxt/utils.js +2 -2
  37. package/lib/frameworks/nuxt2/index.js +5 -5
  38. package/lib/frameworks/utils.js +101 -1
  39. package/lib/frameworks/vite/index.js +5 -6
  40. package/lib/functions/ensureTargeted.js +4 -4
  41. package/lib/functions/python.js +12 -5
  42. package/lib/gcp/resourceManager.js +1 -0
  43. package/lib/hosting/config.js +4 -8
  44. package/lib/init/features/functions/index.js +4 -7
  45. package/lib/init/features/hosting/github.js +7 -2
  46. package/lib/init/features/hosting/index.js +3 -2
  47. package/lib/serve/index.js +2 -1
  48. package/lib/unzip.js +126 -0
  49. package/npm-shrinkwrap.json +6 -287
  50. package/package.json +1 -2
  51. package/schema/firebase-config.json +1 -1
  52. package/templates/init/functions/python/requirements.txt +1 -1
@@ -1,15 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prepareFrameworks = exports.findDependency = exports.getNodeModuleBin = exports.discover = exports.relativeRequire = exports.WebFrameworks = exports.ALLOWED_SSR_REGIONS = exports.DEFAULT_REGION = exports.NODE_VERSION = exports.FIREBASE_ADMIN_VERSION = exports.FIREBASE_FUNCTIONS_VERSION = exports.FIREBASE_FRAMEWORKS_VERSION = void 0;
3
+ exports.prepareFrameworks = exports.discover = exports.WebFrameworks = void 0;
4
4
  const path_1 = require("path");
5
5
  const process_1 = require("process");
6
6
  const child_process_1 = require("child_process");
7
7
  const cross_spawn_1 = require("cross-spawn");
8
- const fs_1 = require("fs");
9
- const url_1 = require("url");
10
8
  const promises_1 = require("fs/promises");
11
9
  const fs_extra_1 = require("fs-extra");
12
- const clc = require("colorette");
13
10
  const process = require("node:process");
14
11
  const semver = require("semver");
15
12
  const glob = require("glob");
@@ -26,67 +23,21 @@ const constants_1 = require("../emulator/constants");
26
23
  const error_1 = require("../error");
27
24
  const requireHostingSite_1 = require("../requireHostingSite");
28
25
  const experiments = require("../experiments");
29
- const ensureTargeted_1 = require("../functions/ensureTargeted");
30
26
  const implicitInit_1 = require("../hosting/implicitInit");
31
- const fsutils_1 = require("../fsutils");
32
- const { dynamicImport } = require(true && "../dynamicImport");
33
- const SupportLevelWarnings = {
34
- ["experimental"]: clc.yellow(`This is an experimental integration, proceed with caution.`),
35
- ["community-supported"]: clc.yellow(`This is a community-supported integration, support is best effort.`),
36
- };
37
- exports.FIREBASE_FRAMEWORKS_VERSION = "^0.7.0";
38
- exports.FIREBASE_FUNCTIONS_VERSION = "^3.23.0";
39
- exports.FIREBASE_ADMIN_VERSION = "^11.0.1";
40
- exports.NODE_VERSION = parseInt(process.versions.node, 10).toString();
41
- exports.DEFAULT_REGION = "us-central1";
42
- exports.ALLOWED_SSR_REGIONS = [
43
- { name: "us-central1 (Iowa)", value: "us-central1" },
44
- { name: "us-west1 (Oregon)", value: "us-west1" },
45
- { name: "us-east1 (South Carolina)", value: "us-east1" },
46
- { name: "europe-west1 (Belgium)", value: "europe-west1" },
47
- { name: "asia-east1 (Taiwan)", value: "asia-east1" },
48
- ];
49
- const DEFAULT_FIND_DEP_OPTIONS = {
50
- cwd: process.cwd(),
51
- omitDev: true,
52
- };
53
- exports.WebFrameworks = Object.fromEntries((0, fs_1.readdirSync)(__dirname)
54
- .filter((path) => (0, fs_1.statSync)((0, path_1.join)(__dirname, path)).isDirectory())
55
- .map((path) => {
56
- try {
57
- return [path, require((0, path_1.join)(__dirname, path))];
58
- }
59
- catch (e) {
60
- return [];
61
- }
62
- })
63
- .filter(([, obj]) => obj && obj.name && obj.discover && obj.build && obj.type !== undefined && obj.support));
64
- function relativeRequire(dir, mod) {
65
- try {
66
- const path = require.resolve(mod, { paths: [dir] });
67
- if ((0, path_1.extname)(path) === ".mjs") {
68
- return dynamicImport((0, url_1.pathToFileURL)(path).toString());
69
- }
70
- else {
71
- return require(path);
72
- }
73
- }
74
- catch (e) {
75
- const path = (0, path_1.relative)(process.cwd(), dir);
76
- console.error(`Could not load dependency ${mod} in ${path.startsWith("..") ? path : `./${path}`}, have you run \`npm install\`?`);
77
- throw e;
78
- }
79
- }
80
- exports.relativeRequire = relativeRequire;
27
+ const utils_1 = require("./utils");
28
+ const constants_2 = require("./constants");
29
+ Object.defineProperty(exports, "WebFrameworks", { enumerable: true, get: function () { return constants_2.WebFrameworks; } });
30
+ const utils_2 = require("../utils");
31
+ const ensureTargeted_1 = require("../functions/ensureTargeted");
81
32
  async function discover(dir, warn = true) {
82
33
  const allFrameworkTypes = [
83
- ...new Set(Object.values(exports.WebFrameworks).map(({ type }) => type)),
34
+ ...new Set(Object.values(constants_2.WebFrameworks).map(({ type }) => type)),
84
35
  ].sort();
85
36
  for (const discoveryType of allFrameworkTypes) {
86
37
  const frameworksDiscovered = [];
87
- for (const framework in exports.WebFrameworks) {
88
- if (exports.WebFrameworks[framework]) {
89
- const { discover, type } = exports.WebFrameworks[framework];
38
+ for (const framework in constants_2.WebFrameworks) {
39
+ if (constants_2.WebFrameworks[framework]) {
40
+ const { discover, type } = constants_2.WebFrameworks[framework];
90
41
  if (type !== discoveryType)
91
42
  continue;
92
43
  const result = await discover(dir);
@@ -107,54 +58,9 @@ async function discover(dir, warn = true) {
107
58
  return;
108
59
  }
109
60
  exports.discover = discover;
110
- function scanDependencyTree(searchingFor, dependencies = {}) {
111
- for (const [name, dependency] of Object.entries(dependencies)) {
112
- if (name === searchingFor)
113
- return dependency;
114
- const result = scanDependencyTree(searchingFor, dependency.dependencies);
115
- if (result)
116
- return result;
117
- }
118
- return;
119
- }
120
- function getNodeModuleBin(name, cwd) {
121
- var _a;
122
- const cantFindExecutable = new error_1.FirebaseError(`Could not find the ${name} executable.`);
123
- const npmRoot = (_a = (0, cross_spawn_1.sync)("npm", ["root"], { cwd }).stdout) === null || _a === void 0 ? void 0 : _a.toString().trim();
124
- if (!npmRoot) {
125
- throw cantFindExecutable;
126
- }
127
- const path = (0, path_1.join)(npmRoot, ".bin", name);
128
- if (!(0, fsutils_1.fileExistsSync)(path)) {
129
- throw cantFindExecutable;
130
- }
131
- return path;
132
- }
133
- exports.getNodeModuleBin = getNodeModuleBin;
134
- function findDependency(name, options = {}) {
135
- var _a;
136
- const { cwd: dir, depth, omitDev } = Object.assign(Object.assign({}, DEFAULT_FIND_DEP_OPTIONS), options);
137
- const cwd = (_a = (0, cross_spawn_1.sync)("npm", ["root"], { cwd: dir }).stdout) === null || _a === void 0 ? void 0 : _a.toString().trim();
138
- if (!cwd)
139
- return;
140
- const env = Object.assign({}, process.env);
141
- delete env.NODE_ENV;
142
- const result = (0, cross_spawn_1.sync)("npm", [
143
- "list",
144
- name,
145
- "--json",
146
- ...(omitDev ? ["--omit", "dev"] : []),
147
- ...(depth === undefined ? [] : ["--depth", depth.toString(10)]),
148
- ], { cwd, env });
149
- if (!result.stdout)
150
- return;
151
- const json = JSON.parse(result.stdout.toString());
152
- return scanDependencyTree(name, json.dependencies);
153
- }
154
- exports.findDependency = findDependency;
155
61
  async function prepareFrameworks(targetNames, context, options, emulators = []) {
156
62
  var _a, _b, _c;
157
- var _d, _e, _f, _g;
63
+ var _d, _e, _f, _g, _h;
158
64
  const nodeVersion = process.version;
159
65
  if (!semver.satisfies(nodeVersion, ">=16.0.0")) {
160
66
  throw new error_1.FirebaseError(`The frameworks awareness feature requires Node.JS >= 16 and npm >= 8 in order to work correctly, due to some of the downstream dependencies. Please upgrade your version of Node.JS, reinstall firebase-tools, and give it another go.`);
@@ -166,7 +72,7 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
166
72
  try {
167
73
  await (0, requireHostingSite_1.requireHostingSite)(options);
168
74
  }
169
- catch (_h) {
75
+ catch (_j) {
170
76
  options.site = project;
171
77
  }
172
78
  }
@@ -175,7 +81,7 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
175
81
  if (configs.length === 0) {
176
82
  return;
177
83
  }
178
- const allowedRegionsValues = exports.ALLOWED_SSR_REGIONS.map((r) => r.value);
84
+ const allowedRegionsValues = constants_2.ALLOWED_SSR_REGIONS.map((r) => r.value);
179
85
  for (const config of configs) {
180
86
  const { source, site, public: publicDir, frameworksBackend } = config;
181
87
  if (!source) {
@@ -191,15 +97,15 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
191
97
  if (publicDir) {
192
98
  throw new Error(`hosting.public and hosting.source cannot both be set in firebase.json`);
193
99
  }
194
- const ssrRegion = (_b = frameworksBackend === null || frameworksBackend === void 0 ? void 0 : frameworksBackend.region) !== null && _b !== void 0 ? _b : exports.DEFAULT_REGION;
100
+ const ssrRegion = (_b = frameworksBackend === null || frameworksBackend === void 0 ? void 0 : frameworksBackend.region) !== null && _b !== void 0 ? _b : constants_2.DEFAULT_REGION;
195
101
  if (!allowedRegionsValues.includes(ssrRegion)) {
196
- const validRegions = allowedRegionsValues.join(", ");
102
+ const validRegions = (0, utils_1.conjoinOptions)(allowedRegionsValues);
197
103
  throw new error_1.FirebaseError(`Hosting config for site ${site} places server-side content in region ${ssrRegion} which is not known. Valid regions are ${validRegions}`);
198
104
  }
199
105
  const getProjectPath = (...args) => (0, path_1.join)(projectRoot, source, ...args);
200
106
  const functionId = `ssr${site.toLowerCase().replace(/-/g, "")}`;
201
- const usesFirebaseAdminSdk = !!findDependency("firebase-admin", { cwd: getProjectPath() });
202
- const usesFirebaseJsSdk = !!findDependency("@firebase/app", { cwd: getProjectPath() });
107
+ const usesFirebaseAdminSdk = !!(0, utils_1.findDependency)("firebase-admin", { cwd: getProjectPath() });
108
+ const usesFirebaseJsSdk = !!(0, utils_1.findDependency)("@firebase/app", { cwd: getProjectPath() });
203
109
  if (usesFirebaseAdminSdk) {
204
110
  process.env.GOOGLE_CLOUD_PROJECT = project;
205
111
  if (account && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
@@ -264,11 +170,12 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
264
170
  process.env.__FIREBASE_DEFAULTS__ = JSON.stringify(firebaseDefaults);
265
171
  }
266
172
  const results = await discover(getProjectPath());
267
- if (!results)
268
- throw new error_1.FirebaseError("Unable to detect the web framework in use, check firebase-debug.log for more info.");
173
+ if (!results) {
174
+ throw new error_1.FirebaseError((0, utils_1.frameworksCallToAction)("Unable to detect the web framework in use, check firebase-debug.log for more info."));
175
+ }
269
176
  const { framework, mayWantBackend, publicDirectory } = results;
270
- const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, } = exports.WebFrameworks[framework];
271
- console.log(`Detected a ${name} codebase. ${SupportLevelWarnings[support] || ""}\n`);
177
+ const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, docsUrl, } = constants_2.WebFrameworks[framework];
178
+ console.log(`\n${(0, utils_1.frameworksCallToAction)(constants_2.SupportLevelWarnings[support](name), docsUrl, " ")}\n`);
272
179
  const isDevMode = context._name === "serve" || context._name === "emulators:start";
273
180
  const hostingEmulatorInfo = emulators.find((e) => e.name === types_1.Emulators.HOSTING);
274
181
  const devModeHandle = isDevMode &&
@@ -302,16 +209,17 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
302
209
  firebaseDefaults._authTokenSyncURL = "/__session";
303
210
  process.env.__FIREBASE_DEFAULTS__ = JSON.stringify(firebaseDefaults);
304
211
  }
305
- const rewrite = {
212
+ if (context.hostingChannel) {
213
+ experiments.assertEnabled("pintags", "deploy an app that requires a backend to a preview channel");
214
+ }
215
+ config.rewrites.push({
306
216
  source: "**",
307
217
  function: {
308
218
  functionId,
219
+ region: ssrRegion,
220
+ pinTag: experiments.isEnabled("pintags"),
309
221
  },
310
- };
311
- if (experiments.isEnabled("pintags")) {
312
- rewrite.function.pinTag = true;
313
- }
314
- config.rewrites.push(rewrite);
222
+ });
315
223
  const codebase = `firebase-frameworks-${site}`;
316
224
  const existingFunctionsConfig = options.config.get("functions")
317
225
  ? [].concat(options.config.get("functions"))
@@ -323,11 +231,16 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
323
231
  codebase,
324
232
  },
325
233
  ]);
326
- if (!targetNames.includes("functions")) {
327
- targetNames.unshift("functions");
328
- }
329
- if (options.only) {
330
- options.only = (0, ensureTargeted_1.ensureTargeted)(options.only, codebase);
234
+ if (!experiments.isEnabled("pintags") ||
235
+ context._name === "serve" ||
236
+ context._name === "emulators:start" ||
237
+ context._name === "emulators:exec") {
238
+ if (!targetNames.includes("functions")) {
239
+ targetNames.unshift("functions");
240
+ }
241
+ if (options.only) {
242
+ options.only = (0, ensureTargeted_1.ensureTargeted)(options.only, codebase);
243
+ }
331
244
  }
332
245
  if (await (0, fs_extra_1.pathExists)(functionsDist)) {
333
246
  const functionsDistStat = await (0, fs_extra_1.stat)(functionsDist);
@@ -348,13 +261,27 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
348
261
  const { packageJson, bootstrapScript, frameworksEntry = framework, } = await codegenFunctionsDirectory(getProjectPath(), functionsDist);
349
262
  process.env.__FIREBASE_FRAMEWORKS_ENTRY__ = frameworksEntry;
350
263
  packageJson.main = "server.js";
351
- delete packageJson.devDependencies;
352
264
  packageJson.dependencies || (packageJson.dependencies = {});
353
- (_d = packageJson.dependencies)["firebase-frameworks"] || (_d["firebase-frameworks"] = exports.FIREBASE_FRAMEWORKS_VERSION);
354
- (_e = packageJson.dependencies)["firebase-functions"] || (_e["firebase-functions"] = exports.FIREBASE_FUNCTIONS_VERSION);
355
- (_f = packageJson.dependencies)["firebase-admin"] || (_f["firebase-admin"] = exports.FIREBASE_ADMIN_VERSION);
265
+ (_d = packageJson.dependencies)["firebase-frameworks"] || (_d["firebase-frameworks"] = constants_2.FIREBASE_FRAMEWORKS_VERSION);
266
+ (_e = packageJson.dependencies)["firebase-functions"] || (_e["firebase-functions"] = constants_2.FIREBASE_FUNCTIONS_VERSION);
267
+ (_f = packageJson.dependencies)["firebase-admin"] || (_f["firebase-admin"] = constants_2.FIREBASE_ADMIN_VERSION);
356
268
  packageJson.engines || (packageJson.engines = {});
357
- (_g = packageJson.engines).node || (_g.node = exports.NODE_VERSION);
269
+ const validEngines = constants_2.VALID_ENGINES.node.filter((it) => it <= constants_2.NODE_VERSION);
270
+ const engine = validEngines[validEngines.length - 1] || constants_2.VALID_ENGINES.node[0];
271
+ if (engine !== constants_2.NODE_VERSION) {
272
+ (0, utils_2.logWarning)(`This integration expects Node version ${(0, utils_1.conjoinOptions)(constants_2.VALID_ENGINES.node, "or")}. You're running version ${constants_2.NODE_VERSION}, problems may be encountered.`);
273
+ }
274
+ (_g = packageJson.engines).node || (_g.node = engine.toString());
275
+ delete packageJson.scripts;
276
+ delete packageJson.devDependencies;
277
+ const bundledDependencies = packageJson.bundledDependencies || {};
278
+ if (Object.keys(bundledDependencies).length) {
279
+ (0, utils_2.logWarning)("Bundled dependencies aren't supported in Cloud Functions, converting to dependencies.");
280
+ for (const [dep, version] of Object.entries(bundledDependencies)) {
281
+ (_h = packageJson.dependencies)[dep] || (_h[dep] = version);
282
+ }
283
+ delete packageJson.bundledDependencies;
284
+ }
358
285
  for (const [name, version] of Object.entries(packageJson.dependencies)) {
359
286
  if (version.startsWith("file:")) {
360
287
  const path = version.replace(/^file:/, "");
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
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;
3
+ exports.APP_PATHS_MANIFEST = 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
4
  exports.APP_PATH_ROUTES_MANIFEST = "app-path-routes-manifest.json";
5
5
  exports.EXPORT_MARKER = "export-marker.json";
6
6
  exports.IMAGES_MANIFEST = "images-manifest.json";
@@ -8,3 +8,4 @@ exports.MIDDLEWARE_MANIFEST = "middleware-manifest.json";
8
8
  exports.PAGES_MANIFEST = "pages-manifest.json";
9
9
  exports.PRERENDER_MANIFEST = "prerender-manifest.json";
10
10
  exports.ROUTES_MANIFEST = "routes-manifest.json";
11
+ exports.APP_PATHS_MANIFEST = "app-paths-manifest.json";