firebase-tools 11.10.0 → 11.10.1-canary.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.
@@ -102,10 +102,21 @@ process.on("exit", (code) => {
102
102
  else {
103
103
  configstore_1.configstore.delete("lastError");
104
104
  }
105
- const updateMessage = `Update available ${clc.gray("{currentVersion}")} → ${clc.green("{latestVersion}")}\n` +
106
- `To update to the latest version using npm, run\n${clc.cyan("npm install -g firebase-tools")}\n` +
107
- `For other CLI management options, visit the ${(0, marked_1.marked)("[CLI documentation](https://firebase.google.com/docs/cli#update-cli)")}`;
108
- updateNotifier.notify({ defer: false, isGlobal: true, message: updateMessage });
105
+ try {
106
+ const updateMessage = `Update available ${clc.gray("{currentVersion}")} ${clc.green("{latestVersion}")}\n` +
107
+ `To update to the latest version using npm, run\n${clc.cyan("npm install -g firebase-tools")}\n` +
108
+ `For other CLI management options, visit the ${(0, marked_1.marked)("[CLI documentation](https://firebase.google.com/docs/cli#update-cli)")}`;
109
+ updateNotifier.notify({ defer: false, isGlobal: true, message: updateMessage });
110
+ }
111
+ catch (err) {
112
+ logger_1.logger.debug("Error when notifying about new CLI updates:");
113
+ if (err instanceof Error) {
114
+ logger_1.logger.debug(err);
115
+ }
116
+ else {
117
+ logger_1.logger.debug(`${err}`);
118
+ }
119
+ }
109
120
  });
110
121
  process.on("uncaughtException", (err) => {
111
122
  (0, errorOut_1.errorOut)(err);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serviceIsResolved = exports.Fabricator = void 0;
3
+ exports.Fabricator = void 0;
4
4
  const clc = require("colorette");
5
5
  const error_1 = require("../../../error");
6
6
  const sourceTokenScraper_1 = require("./sourceTokenScraper");
@@ -23,7 +23,6 @@ const scheduler = require("../../../gcp/cloudscheduler");
23
23
  const utils = require("../../../utils");
24
24
  const services = require("../services");
25
25
  const v1_1 = require("../../../functions/events/v1");
26
- const throttler_1 = require("../../../throttler/throttler");
27
26
  const checkIam_1 = require("../checkIam");
28
27
  const gcfV1PollerOptions = {
29
28
  apiOrigin: api_1.functionsOrigin,
@@ -401,7 +400,7 @@ class Fabricator {
401
400
  async setRunTraits(serviceName, endpoint) {
402
401
  await this.functionExecutor
403
402
  .run(async () => {
404
- let service = await run.getService(serviceName);
403
+ const service = await run.getService(serviceName);
405
404
  let changed = false;
406
405
  if (service.spec.template.spec.containerConcurrency !== endpoint.concurrency) {
407
406
  service.spec.template.spec.containerConcurrency = endpoint.concurrency;
@@ -415,15 +414,7 @@ class Fabricator {
415
414
  logger_1.logger.debug("Skipping setRunTraits on", serviceName, " because it already matches");
416
415
  return;
417
416
  }
418
- delete service.status;
419
- delete service.spec.template.metadata.name;
420
- service = await run.replaceService(serviceName, service);
421
- let retry = 0;
422
- while (!exports.serviceIsResolved(service)) {
423
- await (0, throttler_1.backoff)(retry, 2, 30);
424
- retry = retry + 1;
425
- service = await run.getService(serviceName);
426
- }
417
+ await run.updateService(serviceName, service);
427
418
  })
428
419
  .catch(rethrowAs(endpoint, "set concurrency"));
429
420
  }
@@ -547,26 +538,3 @@ class Fabricator {
547
538
  }
548
539
  }
549
540
  exports.Fabricator = Fabricator;
550
- function serviceIsResolved(service) {
551
- var _a, _b, _c, _d, _e;
552
- if (((_a = service.status) === null || _a === void 0 ? void 0 : _a.observedGeneration) !== service.metadata.generation) {
553
- logger_1.logger.debug(`Service ${service.metadata.name} is not resolved because` +
554
- `observed generation ${(_b = service.status) === null || _b === void 0 ? void 0 : _b.observedGeneration} does not ` +
555
- `match spec generation ${service.metadata.generation}`);
556
- return false;
557
- }
558
- const readyCondition = (_d = (_c = service.status) === null || _c === void 0 ? void 0 : _c.conditions) === null || _d === void 0 ? void 0 : _d.find((condition) => {
559
- return condition.type === "Ready";
560
- });
561
- if ((readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status) === "Unknown") {
562
- logger_1.logger.debug(`Waiting for service ${service.metadata.name} to be ready. ` +
563
- `Status is ${JSON.stringify((_e = service.status) === null || _e === void 0 ? void 0 : _e.conditions)}`);
564
- return false;
565
- }
566
- else if ((readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status) === "True") {
567
- return true;
568
- }
569
- logger_1.logger.debug(`Service ${service.metadata.name} has unexpected ready status ${JSON.stringify(readyCondition)}. It may have failed rollout.`);
570
- throw new error_1.FirebaseError(`Unexpected Status ${readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status} for service ${service.metadata.name}`);
571
- }
572
- exports.serviceIsResolved = serviceIsResolved;
@@ -201,7 +201,7 @@ function createFirebaseEndpoints(emulator) {
201
201
  }
202
202
  return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(metadata));
203
203
  }
204
- if (uploadType === "resumable") {
204
+ if (uploadType === "resumable" || req.header("x-goog-upload-command")) {
205
205
  const uploadCommand = req.header("x-goog-upload-command");
206
206
  if (!uploadCommand) {
207
207
  res.sendStatus(400);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configForCodebase = exports.normalizeAndValidate = exports.validate = exports.normalize = exports.DEFAULT_CODEBASE = void 0;
3
+ exports.configForCodebase = exports.normalizeAndValidate = exports.validate = exports.assertUnique = exports.validateCodebase = exports.normalize = exports.DEFAULT_CODEBASE = void 0;
4
4
  const error_1 = require("../error");
5
5
  exports.DEFAULT_CODEBASE = "default";
6
6
  function normalize(config) {
@@ -16,6 +16,13 @@ function normalize(config) {
16
16
  return [config];
17
17
  }
18
18
  exports.normalize = normalize;
19
+ function validateCodebase(codebase) {
20
+ if (codebase.length === 0 || codebase.length > 63 || !/^[a-z0-9_-]+$/.test(codebase)) {
21
+ throw new error_1.FirebaseError("Invalid codebase name. Codebase must be less than 64 characters and " +
22
+ "can contain only lowercase letters, numeric characters, underscores, and dashes.");
23
+ }
24
+ }
25
+ exports.validateCodebase = validateCodebase;
19
26
  function validateSingle(config) {
20
27
  if (!config.source) {
21
28
  throw new error_1.FirebaseError("functions.source must be specified");
@@ -23,14 +30,14 @@ function validateSingle(config) {
23
30
  if (!config.codebase) {
24
31
  config.codebase = exports.DEFAULT_CODEBASE;
25
32
  }
26
- if (config.codebase.length > 63 || !/^[a-z0-9_-]+$/.test(config.codebase)) {
27
- throw new error_1.FirebaseError("Invalid codebase name. Codebase must be less than 63 characters and " +
28
- "can contain only lowercase letters, numeric characters, underscores, and dashes.");
29
- }
33
+ validateCodebase(config.codebase);
30
34
  return Object.assign(Object.assign({}, config), { source: config.source, codebase: config.codebase });
31
35
  }
32
- function assertUnique(config, property) {
36
+ function assertUnique(config, property, propval) {
33
37
  const values = new Set();
38
+ if (propval) {
39
+ values.add(propval);
40
+ }
34
41
  for (const single of config) {
35
42
  const value = single[property];
36
43
  if (values.has(value)) {
@@ -39,6 +46,7 @@ function assertUnique(config, property) {
39
46
  values.add(value);
40
47
  }
41
48
  }
49
+ exports.assertUnique = assertUnique;
42
50
  function validate(config) {
43
51
  const validated = config.map((cfg) => validateSingle(cfg));
44
52
  assertUnique(validated, "source");
package/lib/gcp/run.js CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setInvokerUpdate = exports.setInvokerCreate = exports.getIamPolicy = exports.setIamPolicy = exports.replaceService = exports.getService = exports.LOCATION_LABEL = void 0;
3
+ exports.setInvokerUpdate = exports.setInvokerCreate = exports.getIamPolicy = exports.setIamPolicy = exports.replaceService = exports.serviceIsResolved = exports.updateService = exports.getService = exports.LOCATION_LABEL = void 0;
4
4
  const apiv2_1 = require("../apiv2");
5
5
  const error_1 = require("../error");
6
6
  const api_1 = require("../api");
7
7
  const proto = require("./proto");
8
+ const throttler_1 = require("../throttler/throttler");
9
+ const logger_1 = require("../logger");
8
10
  const API_VERSION = "v1";
9
11
  const client = new apiv2_1.Client({
10
12
  urlPrefix: api_1.runOrigin,
@@ -24,13 +26,49 @@ async function getService(name) {
24
26
  }
25
27
  }
26
28
  exports.getService = getService;
29
+ async function updateService(name, service) {
30
+ delete service.status;
31
+ delete service.spec.template.metadata.name;
32
+ service = await exports.replaceService(name, service);
33
+ let retry = 0;
34
+ while (!exports.serviceIsResolved(service)) {
35
+ await (0, throttler_1.backoff)(retry, 2, 30);
36
+ retry = retry + 1;
37
+ service = await exports.getService(name);
38
+ }
39
+ return service;
40
+ }
41
+ exports.updateService = updateService;
42
+ function serviceIsResolved(service) {
43
+ var _a, _b, _c, _d, _e;
44
+ if (((_a = service.status) === null || _a === void 0 ? void 0 : _a.observedGeneration) !== service.metadata.generation) {
45
+ logger_1.logger.debug(`Service ${service.metadata.name} is not resolved because` +
46
+ `observed generation ${(_b = service.status) === null || _b === void 0 ? void 0 : _b.observedGeneration} does not ` +
47
+ `match spec generation ${service.metadata.generation}`);
48
+ return false;
49
+ }
50
+ const readyCondition = (_d = (_c = service.status) === null || _c === void 0 ? void 0 : _c.conditions) === null || _d === void 0 ? void 0 : _d.find((condition) => {
51
+ return condition.type === "Ready";
52
+ });
53
+ if ((readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status) === "Unknown") {
54
+ logger_1.logger.debug(`Waiting for service ${service.metadata.name} to be ready. ` +
55
+ `Status is ${JSON.stringify((_e = service.status) === null || _e === void 0 ? void 0 : _e.conditions)}`);
56
+ return false;
57
+ }
58
+ else if ((readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status) === "True") {
59
+ return true;
60
+ }
61
+ logger_1.logger.debug(`Service ${service.metadata.name} has unexpected ready status ${JSON.stringify(readyCondition)}. It may have failed rollout.`);
62
+ throw new error_1.FirebaseError(`Unexpected Status ${readyCondition === null || readyCondition === void 0 ? void 0 : readyCondition.status} for service ${service.metadata.name}`);
63
+ }
64
+ exports.serviceIsResolved = serviceIsResolved;
27
65
  async function replaceService(name, service) {
28
66
  try {
29
67
  const response = await client.put(name, service);
30
68
  return response.body;
31
69
  }
32
70
  catch (err) {
33
- throw new error_1.FirebaseError(`Failed to update Run service ${name}`, {
71
+ throw new error_1.FirebaseError(`Failed to replace Run service ${name}`, {
34
72
  original: err,
35
73
  });
36
74
  }
@@ -2,19 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.doSetup = void 0;
4
4
  const clc = require("colorette");
5
- const _ = require("lodash");
6
5
  const logger_1 = require("../../../logger");
7
6
  const prompt_1 = require("../../../prompt");
8
7
  const requirePermissions_1 = require("../../../requirePermissions");
9
8
  const previews_1 = require("../../../previews");
10
9
  const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
10
+ const projectConfig_1 = require("../../../functions/projectConfig");
11
+ const error_1 = require("../../../error");
12
+ const MAX_ATTEMPTS = 5;
11
13
  async function doSetup(setup, config, options) {
12
14
  var _a, _b;
13
- logger_1.logger.info();
14
- logger_1.logger.info("A " + clc.bold("functions") + " directory will be created in your project with sample code");
15
- logger_1.logger.info("pre-configured. Functions can be deployed with " + clc.bold("firebase deploy") + ".");
16
- logger_1.logger.info();
17
- setup.functions = {};
18
15
  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;
19
16
  if (projectId) {
20
17
  await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: projectId }));
@@ -23,6 +20,116 @@ async function doSetup(setup, config, options) {
23
20
  (0, ensureApiEnabled_1.ensure)(projectId, "runtimeconfig.googleapis.com", "unused", true),
24
21
  ]);
25
22
  }
23
+ setup.functions = {};
24
+ if (!config.src.functions) {
25
+ setup.config.functions = [];
26
+ return initNewCodebase(setup, config);
27
+ }
28
+ const codebases = setup.config.functions.map((cfg) => clc.bold(cfg.codebase));
29
+ logger_1.logger.info(`\nDetected existing codebase(s): ${codebases.join(", ")}\n`);
30
+ setup.config.functions = (0, projectConfig_1.normalizeAndValidate)(setup.config.functions);
31
+ const choices = [
32
+ {
33
+ name: "Initialize",
34
+ value: "new",
35
+ },
36
+ {
37
+ name: "Overwrite",
38
+ value: "overwrite",
39
+ },
40
+ ];
41
+ const initOpt = await (0, prompt_1.promptOnce)({
42
+ type: "list",
43
+ message: "Would you like to initialize a new codebase, or overwrite an existing one?",
44
+ default: "new",
45
+ choices,
46
+ });
47
+ return initOpt === "new" ? initNewCodebase(setup, config) : overwriteCodebase(setup, config);
48
+ }
49
+ exports.doSetup = doSetup;
50
+ async function initNewCodebase(setup, config) {
51
+ logger_1.logger.info("Let's create a new codebase for your functions.");
52
+ logger_1.logger.info("A directory corresponding to the codebase will be created in your project");
53
+ logger_1.logger.info("with sample code pre-configured.\n");
54
+ logger_1.logger.info("See https://firebase.google.com/docs/functions/organize-functions for");
55
+ logger_1.logger.info("more information on organizing your functions using codebases.\n");
56
+ logger_1.logger.info(`Functions can be deployed with ${clc.bold("firebase deploy")}.\n`);
57
+ let source;
58
+ let codebase;
59
+ if (setup.config.functions.length === 0) {
60
+ source = "functions";
61
+ codebase = "default";
62
+ }
63
+ else {
64
+ let attempts = 0;
65
+ while (true) {
66
+ if (attempts++ >= MAX_ATTEMPTS) {
67
+ throw new error_1.FirebaseError("Exceeded max number of attempts to input valid codebase name. Please restart.");
68
+ }
69
+ codebase = await (0, prompt_1.promptOnce)({
70
+ type: "input",
71
+ message: "What should be the name of this codebase?",
72
+ });
73
+ try {
74
+ (0, projectConfig_1.validateCodebase)(codebase);
75
+ (0, projectConfig_1.assertUnique)(setup.config.functions, "codebase", codebase);
76
+ break;
77
+ }
78
+ catch (err) {
79
+ logger_1.logger.error(err);
80
+ }
81
+ }
82
+ attempts = 0;
83
+ while (true) {
84
+ if (attempts >= MAX_ATTEMPTS) {
85
+ throw new error_1.FirebaseError("Exceeded max number of attempts to input valid source. Please restart.");
86
+ }
87
+ attempts++;
88
+ source = await (0, prompt_1.promptOnce)({
89
+ type: "input",
90
+ message: `In what sub-directory would you like to initialize your functions for codebase ${clc.bold(codebase)}?`,
91
+ default: codebase,
92
+ });
93
+ try {
94
+ (0, projectConfig_1.assertUnique)(setup.config.functions, "source", source);
95
+ break;
96
+ }
97
+ catch (err) {
98
+ logger_1.logger.error(err);
99
+ }
100
+ }
101
+ }
102
+ setup.config.functions.push({
103
+ source,
104
+ codebase,
105
+ });
106
+ setup.functions.source = source;
107
+ setup.functions.codebase = codebase;
108
+ return languageSetup(setup, config);
109
+ }
110
+ async function overwriteCodebase(setup, config) {
111
+ let codebase;
112
+ if (setup.config.functions.length > 1) {
113
+ const choices = setup.config.functions.map((cfg) => ({
114
+ name: cfg["codebase"],
115
+ value: cfg["codebase"],
116
+ }));
117
+ codebase = await (0, prompt_1.promptOnce)({
118
+ type: "list",
119
+ message: "Which codebase would you like to overwrite?",
120
+ choices,
121
+ });
122
+ }
123
+ else {
124
+ codebase = setup.config.functions[0].codebase;
125
+ }
126
+ const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, codebase);
127
+ setup.functions.source = cbconfig.source;
128
+ setup.functions.codebase = cbconfig.codebase;
129
+ logger_1.logger.info(`\nOverwriting ${clc.bold(`codebase ${codebase}...\n`)}`);
130
+ return languageSetup(setup, config);
131
+ }
132
+ async function languageSetup(setup, config) {
26
133
  const choices = [
27
134
  {
28
135
  name: "JavaScript",
@@ -45,12 +152,14 @@ async function doSetup(setup, config, options) {
45
152
  default: "javascript",
46
153
  choices,
47
154
  });
48
- _.set(setup, "config.functions.ignore", [
49
- "node_modules",
50
- ".git",
51
- "firebase-debug.log",
52
- "firebase-debug.*.log",
53
- ]);
155
+ const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
156
+ switch (language) {
157
+ case "javascript":
158
+ cbconfig.ignore = ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log"];
159
+ break;
160
+ case "typescript":
161
+ cbconfig.ignore = ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log"];
162
+ break;
163
+ }
54
164
  return require("./" + language).setup(setup, config);
55
165
  }
56
- exports.doSetup = doSetup;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setup = void 0;
4
- const _ = require("lodash");
5
4
  const fs = require("fs");
6
5
  const path = require("path");
7
6
  const npm_dependencies_1 = require("./npm-dependencies");
8
7
  const prompt_1 = require("../../../prompt");
8
+ const projectConfig_1 = require("../../../functions/projectConfig");
9
9
  const TEMPLATE_ROOT = path.resolve(__dirname, "../../../../templates/init/functions/javascript/");
10
10
  const INDEX_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "index.js"), "utf8");
11
11
  const PACKAGE_LINTING_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "package.lint.json"), "utf8");
@@ -23,20 +23,21 @@ function setup(setup, config) {
23
23
  ])
24
24
  .then(() => {
25
25
  if (setup.functions.lint) {
26
- _.set(setup, "config.functions.predeploy", ['npm --prefix "$RESOURCE_DIR" run lint']);
26
+ const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
27
+ cbconfig.predeploy = ['npm --prefix "$RESOURCE_DIR" run lint'];
27
28
  return config
28
- .askWriteProjectFile("functions/package.json", PACKAGE_LINTING_TEMPLATE)
29
+ .askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE)
29
30
  .then(() => {
30
- config.askWriteProjectFile("functions/.eslintrc.js", ESLINT_TEMPLATE);
31
+ config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
31
32
  });
32
33
  }
33
- return config.askWriteProjectFile("functions/package.json", PACKAGE_NO_LINTING_TEMPLATE);
34
+ return config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE);
34
35
  })
35
36
  .then(() => {
36
- return config.askWriteProjectFile("functions/index.js", INDEX_TEMPLATE);
37
+ return config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
37
38
  })
38
39
  .then(() => {
39
- return config.askWriteProjectFile("functions/.gitignore", GITIGNORE_TEMPLATE);
40
+ return config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
40
41
  })
41
42
  .then(() => {
42
43
  return (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
@@ -16,7 +16,7 @@ function askInstallDependencies(setup, config) {
16
16
  if (setup.npm) {
17
17
  return new Promise((resolve) => {
18
18
  const installer = spawn("npm", ["install"], {
19
- cwd: config.projectDir + "/functions",
19
+ cwd: config.projectDir + `/${setup.source}`,
20
20
  stdio: "inherit",
21
21
  });
22
22
  installer.on("error", (err) => {
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setup = void 0;
4
- const _ = require("lodash");
5
4
  const fs = require("fs");
6
5
  const path = require("path");
7
6
  const npm_dependencies_1 = require("./npm-dependencies");
8
7
  const prompt_1 = require("../../../prompt");
8
+ const projectConfig_1 = require("../../../functions/projectConfig");
9
9
  const TEMPLATE_ROOT = path.resolve(__dirname, "../../../../templates/init/functions/typescript/");
10
10
  const PACKAGE_LINTING_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "package.lint.json"), "utf8");
11
11
  const PACKAGE_NO_LINTING_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "package.nolint.json"), "utf8");
@@ -24,33 +24,35 @@ function setup(setup, config) {
24
24
  },
25
25
  ])
26
26
  .then(() => {
27
+ const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
28
+ cbconfig.predeploy = [];
27
29
  if (setup.functions.lint) {
28
- _.set(setup, "config.functions.predeploy", [
29
- 'npm --prefix "$RESOURCE_DIR" run lint',
30
- 'npm --prefix "$RESOURCE_DIR" run build',
31
- ]);
30
+ cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run lint');
31
+ cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
32
32
  return config
33
- .askWriteProjectFile("functions/package.json", PACKAGE_LINTING_TEMPLATE)
33
+ .askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE)
34
34
  .then(() => {
35
- return config.askWriteProjectFile("functions/.eslintrc.js", ESLINT_TEMPLATE);
35
+ return config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
36
36
  });
37
37
  }
38
- _.set(setup, "config.functions.predeploy", 'npm --prefix "$RESOURCE_DIR" run build');
39
- return config.askWriteProjectFile("functions/package.json", PACKAGE_NO_LINTING_TEMPLATE);
38
+ else {
39
+ cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
40
+ }
41
+ return config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE);
40
42
  })
41
43
  .then(() => {
42
- return config.askWriteProjectFile("functions/tsconfig.json", TSCONFIG_TEMPLATE);
44
+ return config.askWriteProjectFile(`${setup.functions.source}/tsconfig.json`, TSCONFIG_TEMPLATE);
43
45
  })
44
46
  .then(() => {
45
47
  if (setup.functions.lint) {
46
- return config.askWriteProjectFile("functions/tsconfig.dev.json", TSCONFIG_DEV_TEMPLATE);
48
+ return config.askWriteProjectFile(`${setup.functions.source}/tsconfig.dev.json`, TSCONFIG_DEV_TEMPLATE);
47
49
  }
48
50
  })
49
51
  .then(() => {
50
- return config.askWriteProjectFile("functions/src/index.ts", INDEX_TEMPLATE);
52
+ return config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
51
53
  })
52
54
  .then(() => {
53
- return config.askWriteProjectFile("functions/.gitignore", GITIGNORE_TEMPLATE);
55
+ return config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
54
56
  })
55
57
  .then(() => {
56
58
  return (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "11.10.0",
3
+ "version": "11.10.1-canary.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "firebase-tools",
9
- "version": "11.10.0",
9
+ "version": "11.10.1-canary.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@google-cloud/pubsub": "^3.0.1",
package/package.json CHANGED
@@ -1,42 +1,11 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "11.10.0",
3
+ "version": "11.10.1-canary.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
7
7
  "firebase": "./lib/bin/firebase.js"
8
8
  },
9
- "scripts": {
10
- "build": "tsc",
11
- "build:watch": "tsc --watch",
12
- "clean": "rimraf lib dev",
13
- "format": "npm run format:ts && npm run format:other",
14
- "format:other": "npm run lint:other -- --write",
15
- "format:ts": "npm run lint:ts -- --fix --quiet",
16
- "generate:auth-api": "ts-node scripts/gen-auth-api-spec.ts",
17
- "generate:json-schema": "typescript-json-schema --strictNullChecks --required --noExtraProps src/firebaseConfig.ts FirebaseConfig > schema/firebase-config.json",
18
- "lint": "npm run lint:ts && npm run lint:other",
19
- "lint:changed-files": "ts-node ./scripts/lint-changed-files.ts",
20
- "lint:other": "prettier --check '**/*.{md,yaml,yml}'",
21
- "lint:quiet": "npm run lint:ts -- --quiet && npm run lint:other",
22
- "lint:ts": "eslint --config .eslintrc.js --ext .ts,.js .",
23
- "mocha": "nyc mocha 'src/test/**/*.{ts,js}'",
24
- "prepare": "npm run clean && npm run build -- --build tsconfig.publish.json",
25
- "test": "npm run lint:quiet && npm run test:compile && npm run mocha",
26
- "test:client-integration": "bash ./scripts/client-integration-tests/run.sh",
27
- "test:compile": "tsc --project tsconfig.compile.json",
28
- "test:emulator": "bash ./scripts/emulator-tests/run.sh",
29
- "test:extensions-deploy": "bash ./scripts/extensions-deploy-tests/run.sh",
30
- "test:extensions-emulator": "bash ./scripts/extensions-emulator-tests/run.sh",
31
- "test:functions-deploy": "bash ./scripts/functions-deploy-tests/run.sh",
32
- "test:hosting": "bash ./scripts/hosting-tests/run.sh",
33
- "test:hosting-rewrites": "bash ./scripts/hosting-tests/rewrites-tests/run.sh",
34
- "test:import-export": "bash ./scripts/emulator-import-export-tests/run.sh",
35
- "test:triggers-end-to-end": "bash ./scripts/triggers-end-to-end-tests/run.sh",
36
- "test:triggers-end-to-end:inspect": "bash ./scripts/triggers-end-to-end-tests/run.sh inspect",
37
- "test:storage-deploy": "bash ./scripts/storage-deploy-tests/run.sh",
38
- "test:storage-emulator-integration": "bash ./scripts/storage-emulator-integration/run.sh"
39
- },
40
9
  "files": [
41
10
  "lib",
42
11
  "schema",
@@ -151,82 +120,5 @@
151
120
  "winston": "^3.0.0",
152
121
  "winston-transport": "^4.4.0",
153
122
  "ws": "^7.2.3"
154
- },
155
- "devDependencies": {
156
- "@google/events": "^5.1.1",
157
- "@manifoldco/swagger-to-ts": "^2.0.0",
158
- "@types/archiver": "^5.1.0",
159
- "@types/async-lock": "^1.1.5",
160
- "@types/body-parser": "^1.17.0",
161
- "@types/chai": "^4.3.0",
162
- "@types/chai-as-promised": "^7.1.4",
163
- "@types/cjson": "^0.5.0",
164
- "@types/cli-table": "^0.3.0",
165
- "@types/configstore": "^4.0.0",
166
- "@types/cors": "^2.8.10",
167
- "@types/cross-spawn": "^6.0.1",
168
- "@types/express": "^4.17.0",
169
- "@types/express-serve-static-core": "^4.17.8",
170
- "@types/fs-extra": "^9.0.13",
171
- "@types/glob": "^7.1.1",
172
- "@types/inquirer": "^8.1.3",
173
- "@types/js-yaml": "^3.12.2",
174
- "@types/jsonwebtoken": "^8.3.8",
175
- "@types/libsodium-wrappers": "^0.7.9",
176
- "@types/lodash": "^4.14.149",
177
- "@types/marked": "^4.0.3",
178
- "@types/marked-terminal": "^3.1.3",
179
- "@types/mocha": "^9.0.0",
180
- "@types/multer": "^1.4.3",
181
- "@types/node": "^14.18.18",
182
- "@types/node-fetch": "^2.5.12",
183
- "@types/progress": "^2.0.3",
184
- "@types/puppeteer": "^5.4.2",
185
- "@types/request": "^2.48.1",
186
- "@types/retry": "^0.12.1",
187
- "@types/rimraf": "^2.0.3",
188
- "@types/semver": "^6.0.0",
189
- "@types/sinon": "^9.0.10",
190
- "@types/sinon-chai": "^3.2.2",
191
- "@types/stream-json": "^1.7.2",
192
- "@types/supertest": "^2.0.12",
193
- "@types/tar": "^6.1.1",
194
- "@types/tcp-port-used": "^1.0.1",
195
- "@types/tmp": "^0.2.3",
196
- "@types/triple-beam": "^1.3.0",
197
- "@types/universal-analytics": "^0.4.5",
198
- "@types/unzipper": "^0.10.0",
199
- "@types/update-notifier": "^5.1.0",
200
- "@types/uuid": "^8.3.1",
201
- "@types/ws": "^7.2.3",
202
- "@typescript-eslint/eslint-plugin": "^5.9.0",
203
- "@typescript-eslint/parser": "^5.9.0",
204
- "chai": "^4.3.4",
205
- "chai-as-promised": "^7.1.1",
206
- "eslint": "^8.6.0",
207
- "eslint-config-google": "^0.14.0",
208
- "eslint-config-prettier": "^8.3.0",
209
- "eslint-plugin-jsdoc": "^39.2.9",
210
- "eslint-plugin-prettier": "^4.0.0",
211
- "firebase": "^7.24.0",
212
- "firebase-admin": "^9.4.2",
213
- "firebase-functions": "^3.23.0",
214
- "google-discovery-to-swagger": "^2.1.0",
215
- "mocha": "^9.1.3",
216
- "nock": "^13.0.5",
217
- "node-mocks-http": "^1.11.0",
218
- "nyc": "^15.1.0",
219
- "openapi-merge": "^1.0.23",
220
- "prettier": "^2.5.1",
221
- "proxy": "^1.0.2",
222
- "puppeteer": "^9.0.0",
223
- "sinon": "^9.2.3",
224
- "sinon-chai": "^3.6.0",
225
- "source-map-support": "^0.5.9",
226
- "supertest": "^6.2.3",
227
- "swagger2openapi": "^6.0.3",
228
- "ts-node": "^10.4.0",
229
- "typescript": "^4.5.4",
230
- "typescript-json-schema": "^0.50.1"
231
123
  }
232
124
  }
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseChangelog = exports.getLocalChangelog = exports.breakingChangesInUpdate = exports.displayReleaseNotes = exports.getReleaseNotesForUpdate = void 0;
4
- const clc = require("colorette");
5
- const { marked } = require("marked");
6
- const path = require("path");
7
- const semver = require("semver");
8
- const TerminalRenderer = require("marked-terminal");
9
- const Table = require("cli-table");
10
- const extensionsApi_1 = require("./extensionsApi");
11
- const localHelper_1 = require("./localHelper");
12
- const logger_1 = require("../logger");
13
- const refs = require("./refs");
14
- const utils_1 = require("../utils");
15
- marked.setOptions({
16
- renderer: new TerminalRenderer(),
17
- });
18
- const EXTENSIONS_CHANGELOG = "CHANGELOG.md";
19
- const VERSION_LINE_REGEX = /##.*(\d+\.\d+\.\d+(?:-((\d+|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(\d+|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?).*/;
20
- async function getReleaseNotesForUpdate(args) {
21
- const releaseNotes = {};
22
- const filter = `id<="${args.toVersion}" AND id>"${args.fromVersion}"`;
23
- const extensionVersions = await (0, extensionsApi_1.listExtensionVersions)(args.extensionRef, filter);
24
- extensionVersions.sort((ev1, ev2) => {
25
- return -semver.compare(ev1.spec.version, ev2.spec.version);
26
- });
27
- for (const extensionVersion of extensionVersions) {
28
- if (extensionVersion.releaseNotes) {
29
- const version = refs.parse(extensionVersion.ref).version;
30
- releaseNotes[version] = extensionVersion.releaseNotes;
31
- }
32
- }
33
- return releaseNotes;
34
- }
35
- exports.getReleaseNotesForUpdate = getReleaseNotesForUpdate;
36
- function displayReleaseNotes(releaseNotes, fromVersion) {
37
- const versions = [fromVersion].concat(Object.keys(releaseNotes));
38
- const breakingVersions = breakingChangesInUpdate(versions);
39
- const table = new Table({ head: ["Version", "What's New"], style: { head: ["yellow", "bold"] } });
40
- for (const [version, note] of Object.entries(releaseNotes)) {
41
- if (breakingVersions.includes(version)) {
42
- table.push([clc.yellow(clc.bold(version)), marked(note)]);
43
- }
44
- else {
45
- table.push([version, marked(note)]);
46
- }
47
- }
48
- logger_1.logger.info(clc.bold("What's new with this update:"));
49
- if (breakingVersions.length) {
50
- (0, utils_1.logLabeledWarning)("warning", "This is a major version update, which means it may contain breaking changes." +
51
- " Read the release notes carefully before continuing with this update.");
52
- }
53
- logger_1.logger.info(table.toString());
54
- }
55
- exports.displayReleaseNotes = displayReleaseNotes;
56
- function breakingChangesInUpdate(versionsInUpdate) {
57
- const breakingVersions = [];
58
- const semvers = versionsInUpdate.map((v) => semver.parse(v)).sort(semver.compare);
59
- for (let i = 1; i < semvers.length; i++) {
60
- const hasMajorBump = semvers[i - 1].major < semvers[i].major;
61
- const hasMinorBumpInPreview = semvers[i - 1].major === 0 &&
62
- semvers[i].major === 0 &&
63
- semvers[i - 1].minor < semvers[i].minor;
64
- if (hasMajorBump || hasMinorBumpInPreview) {
65
- breakingVersions.push(semvers[i].raw);
66
- }
67
- }
68
- return breakingVersions;
69
- }
70
- exports.breakingChangesInUpdate = breakingChangesInUpdate;
71
- function getLocalChangelog(directory) {
72
- const rawChangelog = (0, localHelper_1.readFile)(path.resolve(directory, EXTENSIONS_CHANGELOG));
73
- return parseChangelog(rawChangelog);
74
- }
75
- exports.getLocalChangelog = getLocalChangelog;
76
- function parseChangelog(rawChangelog) {
77
- const changelog = {};
78
- let currentVersion = "";
79
- for (const line of rawChangelog.split("\n")) {
80
- const matches = line.match(VERSION_LINE_REGEX);
81
- if (matches) {
82
- currentVersion = matches[1];
83
- }
84
- else if (currentVersion) {
85
- if (!changelog[currentVersion]) {
86
- changelog[currentVersion] = line;
87
- }
88
- else {
89
- changelog[currentVersion] += `\n${line}`;
90
- }
91
- }
92
- }
93
- return changelog;
94
- }
95
- exports.parseChangelog = parseChangelog;
@@ -1 +0,0 @@
1
- - Added support for publishing pre-release Extension versions. (#4804)