firebase-tools 11.26.0 → 11.28.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 (37) hide show
  1. package/lib/commands/ext-install.js +6 -1
  2. package/lib/commands/ext-update.js +6 -1
  3. package/lib/commands/firestore-databases-create.js +45 -0
  4. package/lib/commands/firestore-databases-delete.js +39 -0
  5. package/lib/commands/firestore-databases-get.js +25 -0
  6. package/lib/commands/firestore-databases-list.js +24 -0
  7. package/lib/commands/firestore-databases-update.js +42 -0
  8. package/lib/commands/firestore-indexes-list.js +2 -2
  9. package/lib/commands/firestore-locations.js +24 -0
  10. package/lib/commands/index.js +7 -0
  11. package/lib/commands/init.js +5 -0
  12. package/lib/commands/open.js +10 -0
  13. package/lib/deploy/firestore/deploy.js +2 -2
  14. package/lib/deploy/functions/backend.js +1 -5
  15. package/lib/deploy/functions/build.js +8 -11
  16. package/lib/deploy/functions/release/fabricator.js +16 -6
  17. package/lib/experiments.js +1 -6
  18. package/lib/extensions/extensionsHelper.js +5 -37
  19. package/lib/extensions/manifest.js +23 -1
  20. package/lib/firestore/{indexes-sort.js → api-sort.js} +10 -2
  21. package/lib/firestore/{indexes-api.js → api-types.js} +16 -1
  22. package/lib/firestore/{indexes.js → api.js} +122 -16
  23. package/lib/frameworks/astro/index.js +76 -0
  24. package/lib/frameworks/astro/utils.js +22 -0
  25. package/lib/frameworks/nuxt/index.js +34 -14
  26. package/lib/frameworks/nuxt/utils.js +11 -1
  27. package/lib/frameworks/nuxt2/index.js +3 -9
  28. package/lib/gcp/cloudfunctions.js +3 -0
  29. package/lib/gcp/cloudfunctionsv2.js +39 -26
  30. package/lib/init/features/extensions/index.js +16 -0
  31. package/lib/init/features/firestore/indexes.js +2 -2
  32. package/lib/init/features/index.js +3 -1
  33. package/lib/init/index.js +1 -0
  34. package/lib/prompt.js +19 -1
  35. package/npm-shrinkwrap.json +14 -14
  36. package/package.json +1 -1
  37. /package/lib/firestore/{indexes-spec.js → api-spec.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StateTtl = exports.State = exports.ArrayConfig = exports.Order = exports.QueryScope = exports.Mode = void 0;
3
+ exports.DatabaseDeleteProtectionState = exports.DatabaseDeleteProtectionStateOption = exports.DatabaseType = exports.StateTtl = exports.State = exports.ArrayConfig = exports.Order = exports.QueryScope = exports.Mode = void 0;
4
4
  var Mode;
5
5
  (function (Mode) {
6
6
  Mode["ASCENDING"] = "ASCENDING";
@@ -33,3 +33,18 @@ var StateTtl;
33
33
  StateTtl["ACTIVE"] = "ACTIVE";
34
34
  StateTtl["NEEDS_REPAIR"] = "NEEDS_REPAIR";
35
35
  })(StateTtl = exports.StateTtl || (exports.StateTtl = {}));
36
+ var DatabaseType;
37
+ (function (DatabaseType) {
38
+ DatabaseType["DATASTORE_MODE"] = "DATASTORE_MODE";
39
+ DatabaseType["FIRESTORE_NATIVE"] = "FIRESTORE_NATIVE";
40
+ })(DatabaseType = exports.DatabaseType || (exports.DatabaseType = {}));
41
+ var DatabaseDeleteProtectionStateOption;
42
+ (function (DatabaseDeleteProtectionStateOption) {
43
+ DatabaseDeleteProtectionStateOption["ENABLED"] = "ENABLED";
44
+ DatabaseDeleteProtectionStateOption["DISABLED"] = "DISABLED";
45
+ })(DatabaseDeleteProtectionStateOption = exports.DatabaseDeleteProtectionStateOption || (exports.DatabaseDeleteProtectionStateOption = {}));
46
+ var DatabaseDeleteProtectionState;
47
+ (function (DatabaseDeleteProtectionState) {
48
+ DatabaseDeleteProtectionState["ENABLED"] = "DELETE_PROTECTION_ENABLED";
49
+ DatabaseDeleteProtectionState["DISABLED"] = "DELETE_PROTECTION_DISABLED";
50
+ })(DatabaseDeleteProtectionState = exports.DatabaseDeleteProtectionState || (exports.DatabaseDeleteProtectionState = {}));
@@ -1,17 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FirestoreIndexes = void 0;
3
+ exports.FirestoreApi = void 0;
4
4
  const clc = require("colorette");
5
5
  const logger_1 = require("../logger");
6
6
  const utils = require("../utils");
7
7
  const validator = require("./validator");
8
- const API = require("./indexes-api");
9
- const sort = require("./indexes-sort");
8
+ const types = require("./api-types");
9
+ const sort = require("./api-sort");
10
10
  const util = require("./util");
11
11
  const prompt_1 = require("../prompt");
12
12
  const api_1 = require("../api");
13
+ const error_1 = require("../error");
13
14
  const apiv2_1 = require("../apiv2");
14
- class FirestoreIndexes {
15
+ class FirestoreApi {
15
16
  constructor() {
16
17
  this.apiClient = new apiv2_1.Client({ urlPrefix: api_1.firestoreOrigin, apiVersion: "v1" });
17
18
  }
@@ -193,6 +194,44 @@ class FirestoreIndexes {
193
194
  logger_1.logger.info(this.prettyIndexString(index));
194
195
  });
195
196
  }
197
+ prettyPrintDatabases(databases) {
198
+ if (databases.length === 0) {
199
+ logger_1.logger.info("No databases found.");
200
+ return;
201
+ }
202
+ const sortedDatabases = databases.sort(sort.compareApiDatabase);
203
+ const Table = require("cli-table");
204
+ const table = new Table({
205
+ head: ["Database Name"],
206
+ colWidths: [Math.max(...sortedDatabases.map((database) => database.name.length + 5), 20)],
207
+ });
208
+ table.push(...sortedDatabases.map((database) => [this.prettyDatabaseString(database)]));
209
+ logger_1.logger.info(table.toString());
210
+ }
211
+ prettyPrintDatabase(database) {
212
+ const Table = require("cli-table");
213
+ const table = new Table({
214
+ head: ["Field", "Value"],
215
+ colWidths: [25, Math.max(50, 5 + database.name.length)],
216
+ });
217
+ table.push(["Name", clc.yellow(database.name)], ["Create Time", clc.yellow(database.createTime)], ["Last Update Time", clc.yellow(database.updateTime)], ["Type", clc.yellow(database.type)], ["Location", clc.yellow(database.locationId)], ["Delete Protection State", clc.yellow(database.deleteProtectionState)]);
218
+ logger_1.logger.info(table.toString());
219
+ }
220
+ prettyPrintLocations(locations) {
221
+ if (locations.length === 0) {
222
+ logger_1.logger.info("No Locations Available");
223
+ return;
224
+ }
225
+ const Table = require("cli-table");
226
+ const table = new Table({
227
+ head: ["Display Name", "LocationId"],
228
+ colWidths: [20, 30],
229
+ });
230
+ table.push(...locations
231
+ .sort(sort.compareLocation)
232
+ .map((location) => [location.displayName, location.locationId]));
233
+ logger_1.logger.info(table.toString());
234
+ }
196
235
  printFieldOverrides(fields) {
197
236
  if (fields.length === 0) {
198
237
  logger_1.logger.info("None");
@@ -217,16 +256,16 @@ class FirestoreIndexes {
217
256
  validateIndex(index) {
218
257
  validator.assertHas(index, "collectionGroup");
219
258
  validator.assertHas(index, "queryScope");
220
- validator.assertEnum(index, "queryScope", Object.keys(API.QueryScope));
259
+ validator.assertEnum(index, "queryScope", Object.keys(types.QueryScope));
221
260
  validator.assertHas(index, "fields");
222
261
  index.fields.forEach((field) => {
223
262
  validator.assertHas(field, "fieldPath");
224
263
  validator.assertHasOneOf(field, ["order", "arrayConfig"]);
225
264
  if (field.order) {
226
- validator.assertEnum(field, "order", Object.keys(API.Order));
265
+ validator.assertEnum(field, "order", Object.keys(types.Order));
227
266
  }
228
267
  if (field.arrayConfig) {
229
- validator.assertEnum(field, "arrayConfig", Object.keys(API.ArrayConfig));
268
+ validator.assertEnum(field, "arrayConfig", Object.keys(types.ArrayConfig));
230
269
  }
231
270
  });
232
271
  }
@@ -240,13 +279,13 @@ class FirestoreIndexes {
240
279
  field.indexes.forEach((index) => {
241
280
  validator.assertHasOneOf(index, ["arrayConfig", "order"]);
242
281
  if (index.arrayConfig) {
243
- validator.assertEnum(index, "arrayConfig", Object.keys(API.ArrayConfig));
282
+ validator.assertEnum(index, "arrayConfig", Object.keys(types.ArrayConfig));
244
283
  }
245
284
  if (index.order) {
246
- validator.assertEnum(index, "order", Object.keys(API.Order));
285
+ validator.assertEnum(index, "order", Object.keys(types.Order));
247
286
  }
248
287
  if (index.queryScope) {
249
- validator.assertEnum(index, "queryScope", Object.keys(API.QueryScope));
288
+ validator.assertEnum(index, "queryScope", Object.keys(types.QueryScope));
250
289
  }
251
290
  });
252
291
  }
@@ -376,7 +415,7 @@ class FirestoreIndexes {
376
415
  result.indexes = spec.indexes.map((index) => {
377
416
  const i = {
378
417
  collectionGroup: index.collectionGroup || index.collectionId,
379
- queryScope: index.queryScope || API.QueryScope.COLLECTION,
418
+ queryScope: index.queryScope || types.QueryScope.COLLECTION,
380
419
  fields: [],
381
420
  };
382
421
  if (index.fields) {
@@ -390,8 +429,8 @@ class FirestoreIndexes {
390
429
  else if (field.arrayConfig) {
391
430
  f.arrayConfig = field.arrayConfig;
392
431
  }
393
- else if (field.mode === API.Mode.ARRAY_CONTAINS) {
394
- f.arrayConfig = API.ArrayConfig.CONTAINS;
432
+ else if (field.mode === types.Mode.ARRAY_CONTAINS) {
433
+ f.arrayConfig = types.ArrayConfig.CONTAINS;
395
434
  }
396
435
  else {
397
436
  f.order = field.mode;
@@ -403,14 +442,78 @@ class FirestoreIndexes {
403
442
  });
404
443
  return result;
405
444
  }
445
+ async listDatabases(project) {
446
+ const url = `/projects/${project}/databases`;
447
+ const res = await this.apiClient.get(url);
448
+ const databases = res.body.databases;
449
+ if (!databases) {
450
+ return [];
451
+ }
452
+ return databases;
453
+ }
454
+ async locations(project) {
455
+ const url = `/projects/${project}/locations`;
456
+ const res = await this.apiClient.get(url);
457
+ const locations = res.body.locations;
458
+ if (!locations) {
459
+ return [];
460
+ }
461
+ return locations;
462
+ }
463
+ async getDatabase(project, databaseId) {
464
+ const url = `/projects/${project}/databases/${databaseId}`;
465
+ const res = await this.apiClient.get(url);
466
+ const database = res.body;
467
+ if (!database) {
468
+ throw new error_1.FirebaseError("Not found");
469
+ }
470
+ return database;
471
+ }
472
+ async createDatabase(project, databaseId, locationId, type, deleteProtectionState) {
473
+ const url = `/projects/${project}/databases`;
474
+ const payload = {
475
+ type,
476
+ locationId,
477
+ deleteProtectionState,
478
+ };
479
+ const options = { queryParams: { databaseId: databaseId } };
480
+ const res = await this.apiClient.post(url, payload, options);
481
+ const database = res.body.response;
482
+ if (!database) {
483
+ throw new error_1.FirebaseError("Not found");
484
+ }
485
+ return database;
486
+ }
487
+ async updateDatabase(project, databaseId, type, deleteProtectionState) {
488
+ const url = `/projects/${project}/databases/${databaseId}`;
489
+ const payload = {
490
+ type,
491
+ deleteProtectionState,
492
+ };
493
+ const res = await this.apiClient.patch(url, payload);
494
+ const database = res.body.response;
495
+ if (!database) {
496
+ throw new error_1.FirebaseError("Not found");
497
+ }
498
+ return database;
499
+ }
500
+ async deleteDatabase(project, databaseId) {
501
+ const url = `/projects/${project}/databases/${databaseId}`;
502
+ const res = await this.apiClient.delete(url);
503
+ const database = res.body.response;
504
+ if (!database) {
505
+ throw new error_1.FirebaseError("Not found");
506
+ }
507
+ return database;
508
+ }
406
509
  prettyIndexString(index, includeState = true) {
407
510
  let result = "";
408
511
  if (index.state && includeState) {
409
512
  const stateMsg = `[${index.state}] `;
410
- if (index.state === API.State.READY) {
513
+ if (index.state === types.State.READY) {
411
514
  result += clc.green(stateMsg);
412
515
  }
413
- else if (index.state === API.State.CREATING) {
516
+ else if (index.state === types.State.CREATING) {
414
517
  result += clc.yellow(stateMsg);
415
518
  }
416
519
  else {
@@ -429,6 +532,9 @@ class FirestoreIndexes {
429
532
  });
430
533
  return result;
431
534
  }
535
+ prettyDatabaseString(database) {
536
+ return clc.yellow(database.name);
537
+ }
432
538
  prettyFieldString(field) {
433
539
  let result = "";
434
540
  const parsedName = util.parseFieldName(field.name);
@@ -456,4 +562,4 @@ class FirestoreIndexes {
456
562
  return result;
457
563
  }
458
564
  }
459
- exports.FirestoreIndexes = FirestoreIndexes;
565
+ exports.FirestoreApi = FirestoreApi;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.type = exports.support = exports.name = void 0;
4
+ const cross_spawn_1 = require("cross-spawn");
5
+ const fs_extra_1 = require("fs-extra");
6
+ const path_1 = require("path");
7
+ const __1 = require("..");
8
+ const error_1 = require("../../error");
9
+ const utils_1 = require("../utils");
10
+ const utils_2 = require("./utils");
11
+ exports.name = "Astro";
12
+ exports.support = "experimental";
13
+ exports.type = 2;
14
+ function getAstroVersion(cwd) {
15
+ var _a;
16
+ return (_a = (0, __1.findDependency)("astro", { cwd, depth: 0, omitDev: false })) === null || _a === void 0 ? void 0 : _a.version;
17
+ }
18
+ async function discover(dir) {
19
+ if (!(0, fs_extra_1.existsSync)((0, path_1.join)(dir, "package.json")))
20
+ return;
21
+ if (!getAstroVersion(dir))
22
+ return;
23
+ const { output, publicDir: publicDirectory } = await (0, utils_2.getConfig)(dir);
24
+ return {
25
+ mayWantBackend: output === "server",
26
+ publicDirectory,
27
+ };
28
+ }
29
+ exports.discover = discover;
30
+ const DEFAULT_BUILD_SCRIPT = ["astro build"];
31
+ async function build(cwd) {
32
+ const cli = (0, __1.getNodeModuleBin)("astro", cwd);
33
+ await (0, utils_1.warnIfCustomBuildScript)(cwd, exports.name, DEFAULT_BUILD_SCRIPT);
34
+ const { output, adapter } = await (0, utils_2.getConfig)(cwd);
35
+ if (output === "server" && (adapter === null || adapter === void 0 ? void 0 : adapter.name) !== "@astrojs/node") {
36
+ throw new error_1.FirebaseError("Deploying an Astro application with SSR on Firebase Hosting requires the @astrojs/node adapter.");
37
+ }
38
+ const build = (0, cross_spawn_1.sync)(cli, ["build"], { cwd, stdio: "inherit" });
39
+ if (build.status)
40
+ throw new error_1.FirebaseError("Unable to build your Astro app");
41
+ return { wantsBackend: output === "server" };
42
+ }
43
+ exports.build = build;
44
+ async function ɵcodegenPublicDirectory(root, dest) {
45
+ const { outDir, output } = await (0, utils_2.getConfig)(root);
46
+ const assetPath = (0, path_1.join)(root, outDir, output === "server" ? "client" : "");
47
+ await (0, fs_extra_1.copy)(assetPath, dest);
48
+ }
49
+ exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
50
+ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
51
+ const { outDir } = await (0, utils_2.getConfig)(sourceDir);
52
+ const packageJson = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, "package.json"));
53
+ await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, outDir, "server"), (0, path_1.join)(destDir));
54
+ return {
55
+ packageJson,
56
+ bootstrapScript: (0, utils_2.getBootstrapScript)(),
57
+ };
58
+ }
59
+ exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
60
+ async function getDevModeHandle(cwd) {
61
+ const host = new Promise((resolve) => {
62
+ const cli = (0, __1.getNodeModuleBin)("astro", cwd);
63
+ const serve = (0, cross_spawn_1.spawn)(cli, ["dev"], { cwd });
64
+ serve.stdout.on("data", (data) => {
65
+ process.stdout.write(data);
66
+ const match = data.toString().match(/(http:\/\/.+:\d+)/);
67
+ if (match)
68
+ resolve(match[1]);
69
+ });
70
+ serve.stderr.on("data", (data) => {
71
+ process.stderr.write(data);
72
+ });
73
+ });
74
+ return (0, utils_1.simpleProxy)(await host);
75
+ }
76
+ exports.getDevModeHandle = getDevModeHandle;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getConfig = exports.getBootstrapScript = void 0;
4
+ const path_1 = require("path");
5
+ const { dynamicImport } = require(true && "../../dynamicImport");
6
+ function getBootstrapScript() {
7
+ return `const entry = import('./entry.mjs');\nexport const handle = async (req, res) => (await entry).handler(req, res)`;
8
+ }
9
+ exports.getBootstrapScript = getBootstrapScript;
10
+ async function getConfig(cwd) {
11
+ const astroDirectory = (0, path_1.dirname)(require.resolve("astro/package.json", { paths: [cwd] }));
12
+ const { openConfig } = await dynamicImport((0, path_1.join)(astroDirectory, "dist", "core", "config", "config.js"));
13
+ const logging = undefined;
14
+ const { astroConfig: config } = await openConfig({ cmd: "build", cwd, logging });
15
+ return {
16
+ outDir: (0, path_1.relative)(cwd, config.outDir.pathname),
17
+ publicDir: (0, path_1.relative)(cwd, config.publicDir.pathname),
18
+ output: config.output,
19
+ adapter: config.adapter,
20
+ };
21
+ }
22
+ exports.getConfig = getConfig;
@@ -1,32 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.type = exports.support = exports.name = void 0;
3
+ exports.getConfig = exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.type = exports.support = exports.name = void 0;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const promises_1 = require("fs/promises");
6
6
  const path_1 = require("path");
7
7
  const semver_1 = require("semver");
8
+ const cross_spawn_1 = require("cross-spawn");
8
9
  const __1 = require("..");
9
10
  const utils_1 = require("../utils");
11
+ const utils_2 = require("./utils");
10
12
  exports.name = "Nuxt";
11
13
  exports.support = "experimental";
12
14
  exports.type = 4;
13
- const utils_2 = require("./utils");
14
- const DEFAULT_BUILD_SCRIPT = ["nuxt build"];
15
+ const utils_3 = require("./utils");
16
+ const DEFAULT_BUILD_SCRIPT = ["nuxt build", "nuxi build"];
15
17
  async function discover(dir) {
16
18
  if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
17
19
  return;
18
- const nuxtDependency = (0, __1.findDependency)("nuxt", {
19
- cwd: dir,
20
- depth: 0,
21
- omitDev: false,
22
- });
23
- const version = nuxtDependency === null || nuxtDependency === void 0 ? void 0 : nuxtDependency.version;
24
- const anyConfigFileExists = await (0, utils_2.nuxtConfigFilesExist)(dir);
25
- if (!anyConfigFileExists && !nuxtDependency)
20
+ const anyConfigFileExists = await (0, utils_3.nuxtConfigFilesExist)(dir);
21
+ const nuxtVersion = (0, utils_2.getNuxtVersion)(dir);
22
+ if (!anyConfigFileExists && !nuxtVersion)
23
+ return;
24
+ if (nuxtVersion && (0, semver_1.lt)(nuxtVersion, "3.0.0-0"))
26
25
  return;
27
- if (version && (0, semver_1.gte)(version, "3.0.0-0"))
28
- return { mayWantBackend: true };
29
- return;
26
+ const { dir: { public: publicDirectory }, } = await getConfig(dir);
27
+ return { publicDirectory, mayWantBackend: true };
30
28
  }
31
29
  exports.discover = discover;
32
30
  async function build(root) {
@@ -60,3 +58,25 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
60
58
  return { packageJson: Object.assign(Object.assign({}, packageJson), outputPackageJson), frameworksEntry: "nuxt3" };
61
59
  }
62
60
  exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
61
+ async function getDevModeHandle(cwd) {
62
+ const host = new Promise((resolve) => {
63
+ const cli = (0, __1.getNodeModuleBin)("nuxt", cwd);
64
+ const serve = (0, cross_spawn_1.spawn)(cli, ["dev"], { cwd: cwd });
65
+ serve.stdout.on("data", (data) => {
66
+ process.stdout.write(data);
67
+ const match = data.toString().match(/(http:\/\/.+:\d+)/);
68
+ if (match)
69
+ resolve(match[1]);
70
+ });
71
+ serve.stderr.on("data", (data) => {
72
+ process.stderr.write(data);
73
+ });
74
+ });
75
+ return (0, utils_1.simpleProxy)(await host);
76
+ }
77
+ exports.getDevModeHandle = getDevModeHandle;
78
+ async function getConfig(dir) {
79
+ const { loadNuxtConfig } = await (0, __1.relativeRequire)(dir, "@nuxt/kit");
80
+ return await loadNuxtConfig(dir);
81
+ }
82
+ exports.getConfig = getConfig;
@@ -1,8 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nuxtConfigFilesExist = void 0;
3
+ exports.nuxtConfigFilesExist = exports.getNuxtVersion = void 0;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const path_1 = require("path");
6
+ const __1 = require("..");
7
+ function getNuxtVersion(cwd) {
8
+ var _a;
9
+ return (_a = (0, __1.findDependency)("nuxt", {
10
+ cwd,
11
+ depth: 0,
12
+ omitDev: false,
13
+ })) === null || _a === void 0 ? void 0 : _a.version;
14
+ }
15
+ exports.getNuxtVersion = getNuxtVersion;
6
16
  async function nuxtConfigFilesExist(dir) {
7
17
  const configFilesExist = await Promise.all([
8
18
  (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "nuxt.config.js")),
@@ -13,18 +13,12 @@ exports.type = 2;
13
13
  async function discover(dir) {
14
14
  if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
15
15
  return;
16
- const nuxtDependency = (0, __1.findDependency)("nuxt", {
17
- cwd: dir,
18
- depth: 0,
19
- omitDev: false,
20
- });
21
- const version = nuxtDependency === null || nuxtDependency === void 0 ? void 0 : nuxtDependency.version;
16
+ const nuxtVersion = (0, utils_1.getNuxtVersion)(dir);
22
17
  const anyConfigFileExists = await (0, utils_1.nuxtConfigFilesExist)(dir);
23
- if (!anyConfigFileExists && !nuxtDependency)
18
+ if (!anyConfigFileExists && !nuxtVersion)
24
19
  return;
25
- if (version && (0, semver_1.lt)(version, "3.0.0-0"))
20
+ if (nuxtVersion && (0, semver_1.lt)(nuxtVersion, "3.0.0-0"))
26
21
  return { mayWantBackend: true };
27
- return;
28
22
  }
29
23
  exports.discover = discover;
30
24
  async function getNuxtApp(cwd) {
@@ -44,6 +44,7 @@ exports.generateUploadUrl = generateUploadUrl;
44
44
  async function createFunction(cloudFunction) {
45
45
  const apiPath = cloudFunction.name.substring(0, cloudFunction.name.lastIndexOf("/"));
46
46
  const endpoint = `/${apiPath}`;
47
+ cloudFunction.buildEnvironmentVariables = Object.assign(Object.assign({}, cloudFunction.buildEnvironmentVariables), { GOOGLE_NODE_RUN_SCRIPTS: "" });
47
48
  try {
48
49
  const res = await client.post(endpoint, cloudFunction);
49
50
  return {
@@ -131,6 +132,8 @@ exports.setInvokerUpdate = setInvokerUpdate;
131
132
  async function updateFunction(cloudFunction) {
132
133
  const endpoint = `/${cloudFunction.name}`;
133
134
  const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "environmentVariables", "secretEnvironmentVariables");
135
+ cloudFunction.buildEnvironmentVariables = Object.assign(Object.assign({}, cloudFunction.buildEnvironmentVariables), { GOOGLE_NODE_RUN_SCRIPTS: "" });
136
+ fieldMasks.push("buildEnvironmentVariables");
134
137
  try {
135
138
  const res = await client.patch(endpoint, cloudFunction, {
136
139
  queryParams: {
@@ -80,6 +80,7 @@ exports.generateUploadUrl = generateUploadUrl;
80
80
  async function createFunction(cloudFunction) {
81
81
  const components = cloudFunction.name.split("/");
82
82
  const functionId = components.splice(-1, 1)[0];
83
+ cloudFunction.buildConfig.environmentVariables = Object.assign(Object.assign({}, cloudFunction.buildConfig.environmentVariables), { GOOGLE_NODE_RUN_SCRIPTS: "" });
83
84
  try {
84
85
  const res = await client.post(components.join("/"), cloudFunction, { queryParams: { functionId } });
85
86
  return res.body;
@@ -133,6 +134,8 @@ async function listFunctionsInternal(projectId, region) {
133
134
  }
134
135
  async function updateFunction(cloudFunction) {
135
136
  const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "serviceConfig.environmentVariables", "serviceConfig.secretEnvironmentVariables");
137
+ cloudFunction.buildConfig.environmentVariables = Object.assign(Object.assign({}, cloudFunction.buildConfig.environmentVariables), { GOOGLE_NODE_RUN_SCRIPTS: "" });
138
+ fieldMasks.push("buildConfig.buildEnvironmentVariables");
136
139
  try {
137
140
  const queryParams = {
138
141
  updateMask: fieldMasks.join(","),
@@ -322,39 +325,49 @@ function endpointFromFunction(gcfFunction) {
322
325
  }
323
326
  const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
324
327
  project,
325
- region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
326
- proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "ingressSettings", "environmentVariables", "secretEnvironmentVariables", "timeoutSeconds");
327
- proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccount", "serviceAccountEmail");
328
- proto.convertIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", (prod) => {
329
- if (prod === null) {
330
- logger_1.logger.debug("Prod should always return a valid memory amount");
331
- return prod;
328
+ region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime });
329
+ if (gcfFunction.serviceConfig) {
330
+ proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "ingressSettings", "environmentVariables", "secretEnvironmentVariables", "timeoutSeconds", "uri");
331
+ proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccount", "serviceAccountEmail");
332
+ proto.convertIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", (prod) => {
333
+ if (prod === null) {
334
+ logger_1.logger.debug("Prod should always return a valid memory amount");
335
+ return prod;
336
+ }
337
+ const mem = mebibytes(prod);
338
+ if (!backend.isValidMemoryOption(mem)) {
339
+ logger_1.logger.warn("Converting a function to an endpoint with an invalid memory option", mem);
340
+ }
341
+ return mem;
342
+ });
343
+ proto.convertIfPresent(endpoint, gcfFunction.serviceConfig, "cpu", "availableCpu", (cpu) => {
344
+ let cpuVal = Number(cpu);
345
+ if (Number.isNaN(cpuVal)) {
346
+ cpuVal = null;
347
+ }
348
+ return cpuVal;
349
+ });
350
+ proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
351
+ proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
352
+ proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "concurrency", "maxInstanceRequestConcurrency");
353
+ proto.copyIfPresent(endpoint, gcfFunction, "labels");
354
+ if (gcfFunction.serviceConfig.vpcConnector) {
355
+ endpoint.vpc = { connector: gcfFunction.serviceConfig.vpcConnector };
356
+ proto.renameIfPresent(endpoint.vpc, gcfFunction.serviceConfig, "egressSettings", "vpcConnectorEgressSettings");
332
357
  }
333
- const mem = mebibytes(prod);
334
- if (!backend.isValidMemoryOption(mem)) {
335
- logger_1.logger.warn("Converting a function to an endpoint with an invalid memory option", mem);
358
+ const serviceName = gcfFunction.serviceConfig.service;
359
+ if (!serviceName) {
360
+ logger_1.logger.debug("Got a v2 function without a service name." +
361
+ "Maybe we've migrated to using the v2 API everywhere and missed this code");
362
+ }
363
+ else {
364
+ endpoint.runServiceId = utils.last(serviceName.split("/"));
336
365
  }
337
- return mem;
338
- });
339
- proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
340
- proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
341
- proto.copyIfPresent(endpoint, gcfFunction, "labels");
342
- if (gcfFunction.serviceConfig.vpcConnector) {
343
- endpoint.vpc = { connector: gcfFunction.serviceConfig.vpcConnector };
344
- proto.renameIfPresent(endpoint.vpc, gcfFunction.serviceConfig, "egressSettings", "vpcConnectorEgressSettings");
345
366
  }
346
367
  endpoint.codebase = ((_e = gcfFunction.labels) === null || _e === void 0 ? void 0 : _e[constants_1.CODEBASE_LABEL]) || projectConfig.DEFAULT_CODEBASE;
347
368
  if ((_f = gcfFunction.labels) === null || _f === void 0 ? void 0 : _f[constants_1.HASH_LABEL]) {
348
369
  endpoint.hash = gcfFunction.labels[constants_1.HASH_LABEL];
349
370
  }
350
- const serviceName = gcfFunction.serviceConfig.service;
351
- if (!serviceName) {
352
- logger_1.logger.debug("Got a v2 function without a service name." +
353
- "Maybe we've migrated to using the v2 API everywhere and missed this code");
354
- }
355
- else {
356
- endpoint.runServiceId = utils.last(serviceName.split("/"));
357
- }
358
371
  return endpoint;
359
372
  }
360
373
  exports.endpointFromFunction = endpointFromFunction;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.doSetup = void 0;
4
+ const requirePermissions_1 = require("../../../requirePermissions");
5
+ const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
6
+ const manifest = require("../../../extensions/manifest");
7
+ async function doSetup(setup, config, options) {
8
+ var _a, _b;
9
+ const projectId = (_b = (_a = setup === null || setup === void 0 ? void 0 : setup.rcfile) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.default;
10
+ if (projectId) {
11
+ await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: projectId }));
12
+ await Promise.all([(0, ensureApiEnabled_1.ensure)(projectId, "firebaseextensions.googleapis.com", "unused", true)]);
13
+ }
14
+ return manifest.writeEmptyManifest(config, options);
15
+ }
16
+ exports.doSetup = doSetup;
@@ -4,11 +4,11 @@ exports.initIndexes = void 0;
4
4
  const clc = require("colorette");
5
5
  const fs = require("fs");
6
6
  const error_1 = require("../../../error");
7
- const iv2 = require("../../../firestore/indexes");
7
+ const api = require("../../../firestore/api");
8
8
  const fsutils = require("../../../fsutils");
9
9
  const prompt_1 = require("../../../prompt");
10
10
  const logger_1 = require("../../../logger");
11
- const indexes = new iv2.FirestoreIndexes();
11
+ const indexes = new api.FirestoreApi();
12
12
  const INDEXES_TEMPLATE = fs.readFileSync(__dirname + "/../../../../templates/init/firestore/firestore.indexes.json", "utf8");
13
13
  function initIndexes(setup, config) {
14
14
  logger_1.logger.info();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hostingGithub = exports.remoteconfig = exports.project = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = exports.account = void 0;
3
+ exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = exports.account = void 0;
4
4
  var account_1 = require("./account");
5
5
  Object.defineProperty(exports, "account", { enumerable: true, get: function () { return account_1.doSetup; } });
6
6
  var database_1 = require("./database");
@@ -15,6 +15,8 @@ var storage_1 = require("./storage");
15
15
  Object.defineProperty(exports, "storage", { enumerable: true, get: function () { return storage_1.doSetup; } });
16
16
  var emulators_1 = require("./emulators");
17
17
  Object.defineProperty(exports, "emulators", { enumerable: true, get: function () { return emulators_1.doSetup; } });
18
+ var extensions_1 = require("./extensions");
19
+ Object.defineProperty(exports, "extensions", { enumerable: true, get: function () { return extensions_1.doSetup; } });
18
20
  var project_1 = require("./project");
19
21
  Object.defineProperty(exports, "project", { enumerable: true, get: function () { return project_1.doSetup; } });
20
22
  var remoteconfig_1 = require("./remoteconfig");
package/lib/init/index.js CHANGED
@@ -14,6 +14,7 @@ const featureFns = new Map([
14
14
  ["hosting", features.hosting],
15
15
  ["storage", features.storage],
16
16
  ["emulators", features.emulators],
17
+ ["extensions", features.extensions],
17
18
  ["project", features.project],
18
19
  ["remoteconfig", features.remoteconfig],
19
20
  ["hosting:github", features.hostingGithub],