firebase-tools 11.16.0 → 11.17.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.
@@ -122,12 +122,13 @@ async function want(args) {
122
122
  exports.want = want;
123
123
  async function resolveVersion(ref) {
124
124
  const extensionRef = refs.toExtensionRef(ref);
125
- const versions = await extensionsApi.listExtensionVersions(extensionRef);
125
+ const versions = await extensionsApi.listExtensionVersions(extensionRef, undefined, true);
126
126
  if (versions.length === 0) {
127
127
  throw new error_1.FirebaseError(`No versions found for ${extensionRef}`);
128
128
  }
129
129
  if (!ref.version || ref.version === "latest") {
130
130
  return versions
131
+ .filter((ev) => ev.spec.version !== undefined)
131
132
  .map((ev) => ev.spec.version)
132
133
  .sort(semver.compare)
133
134
  .pop();
@@ -160,6 +160,9 @@ function toBackend(build, paramValues) {
160
160
  const bkEndpoints = [];
161
161
  for (const endpointId of Object.keys(build.endpoints)) {
162
162
  const bdEndpoint = build.endpoints[endpointId];
163
+ if (r.resolveBoolean(bdEndpoint.omit || false)) {
164
+ continue;
165
+ }
163
166
  let regions = bdEndpoint.region;
164
167
  if (typeof regions === "undefined") {
165
168
  regions = [api.functionsDefaultRegion];
@@ -80,7 +80,7 @@ async function deploy(context, options, payload) {
80
80
  await (0, checkIam_1.checkHttpIam)(context, options, payload);
81
81
  const uploads = [];
82
82
  for (const [codebase, { wantBackend, haveBackend }] of Object.entries(payload.functions)) {
83
- if (shouldUploadBeSkipped(wantBackend, haveBackend)) {
83
+ if (shouldUploadBeSkipped(context, wantBackend, haveBackend)) {
84
84
  continue;
85
85
  }
86
86
  uploads.push(uploadCodebase(context, codebase, wantBackend));
@@ -88,7 +88,10 @@ async function deploy(context, options, payload) {
88
88
  await Promise.all(uploads);
89
89
  }
90
90
  exports.deploy = deploy;
91
- function shouldUploadBeSkipped(wantBackend, haveBackend) {
91
+ function shouldUploadBeSkipped(context, wantBackend, haveBackend) {
92
+ if (context.filters && context.filters.length > 0) {
93
+ return false;
94
+ }
92
95
  const wantEndpoints = backend.allEndpoints(wantBackend);
93
96
  const haveEndpoints = backend.allEndpoints(haveBackend);
94
97
  if (wantEndpoints.length !== haveEndpoints.length) {
@@ -167,9 +167,9 @@ class Fabricator {
167
167
  if (apiFunction.httpsTrigger) {
168
168
  apiFunction.httpsTrigger.securityLevel = "SECURE_ALWAYS";
169
169
  }
170
- apiFunction.sourceToken = await scraper.tokenPromise();
171
170
  const resultFunction = await this.functionExecutor
172
171
  .run(async () => {
172
+ apiFunction.sourceToken = await scraper.getToken();
173
173
  const op = await gcf.createFunction(apiFunction);
174
174
  return poller.pollOperation(Object.assign(Object.assign({}, gcfV1PollerOptions), { pollerName: `create-${endpoint.codebase}-${endpoint.region}-${endpoint.id}`, operationResourceName: op.name, onPoll: scraper.poller }));
175
175
  })
@@ -301,9 +301,9 @@ class Fabricator {
301
301
  throw new Error("Precondition failed");
302
302
  }
303
303
  const apiFunction = gcf.functionFromEndpoint(endpoint, sourceUrl);
304
- apiFunction.sourceToken = await scraper.tokenPromise();
305
304
  const resultFunction = await this.functionExecutor
306
305
  .run(async () => {
306
+ apiFunction.sourceToken = await scraper.getToken();
307
307
  const op = await gcf.updateFunction(apiFunction);
308
308
  return await poller.pollOperation(Object.assign(Object.assign({}, gcfV1PollerOptions), { pollerName: `update-${endpoint.codebase}-${endpoint.region}-${endpoint.id}`, operationResourceName: op.name, onPoll: scraper.poller }));
309
309
  })
@@ -1,18 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SourceTokenScraper = void 0;
4
+ const error_1 = require("../../../error");
5
+ const functional_1 = require("../../../functional");
4
6
  const logger_1 = require("../../../logger");
5
7
  class SourceTokenScraper {
6
- constructor() {
7
- this.firstCall = true;
8
+ constructor(validDurationMs = 1500000) {
9
+ this.tokenValidDurationMs = validDurationMs;
8
10
  this.promise = new Promise((resolve) => (this.resolve = resolve));
11
+ this.fetchState = "NONE";
9
12
  }
10
- tokenPromise() {
11
- if (this.firstCall) {
12
- this.firstCall = false;
13
- return Promise.resolve(undefined);
13
+ async getToken() {
14
+ if (this.fetchState === "NONE") {
15
+ this.fetchState = "FETCHING";
16
+ return undefined;
14
17
  }
15
- return this.promise;
18
+ else if (this.fetchState === "FETCHING") {
19
+ return this.promise;
20
+ }
21
+ else if (this.fetchState === "VALID") {
22
+ if (this.isTokenExpired()) {
23
+ this.fetchState = "FETCHING";
24
+ this.promise = new Promise((resolve) => (this.resolve = resolve));
25
+ return undefined;
26
+ }
27
+ return this.promise;
28
+ }
29
+ else {
30
+ (0, functional_1.assertExhaustive)(this.fetchState);
31
+ }
32
+ }
33
+ isTokenExpired() {
34
+ if (this.expiry === undefined) {
35
+ throw new error_1.FirebaseError("Your deployment is checking the expiration of a source token that has not yet been polled. " +
36
+ "Hitting this case should never happen and should be considered a bug. " +
37
+ "Please file an issue at https://github.com/firebase/firebase-tools/issues " +
38
+ "and try deploying your functions again.");
39
+ }
40
+ return Date.now() >= this.expiry;
16
41
  }
17
42
  get poller() {
18
43
  return (op) => {
@@ -21,6 +46,8 @@ class SourceTokenScraper {
21
46
  const [, , , region] = ((_c = (_b = op.metadata) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.split("/")) || [];
22
47
  logger_1.logger.debug(`Got source token ${(_d = op.metadata) === null || _d === void 0 ? void 0 : _d.sourceToken} for region ${region}`);
23
48
  this.resolve((_e = op.metadata) === null || _e === void 0 ? void 0 : _e.sourceToken);
49
+ this.fetchState = "VALID";
50
+ this.expiry = Date.now() + this.tokenValidDurationMs;
24
51
  }
25
52
  };
26
53
  }
@@ -51,6 +51,7 @@ function assertBuildEndpoint(ep, id) {
51
51
  region: "array",
52
52
  platform: (platform) => build.AllFunctionsPlatforms.includes(platform),
53
53
  entryPoint: "string",
54
+ omit: "Field<boolean>?",
54
55
  availableMemoryMb: (mem) => mem === null || isCEL(mem) || build.isValidMemoryOption(mem),
55
56
  maxInstances: "Field<number>?",
56
57
  minInstances: "Field<number>?",
@@ -259,7 +260,7 @@ function parseEndpointForBuild(id, ep, project, defaultRegion, runtime) {
259
260
  if ("serviceAccountEmail" in ep) {
260
261
  parsed.serviceAccount = ep.serviceAccountEmail;
261
262
  }
262
- (0, proto_1.copyIfPresent)(parsed, ep, "availableMemoryMb", "cpu", "maxInstances", "minInstances", "concurrency", "timeoutSeconds", "vpc", "labels", "ingressSettings", "environmentVariables", "serviceAccount");
263
+ (0, proto_1.copyIfPresent)(parsed, ep, "omit", "availableMemoryMb", "cpu", "maxInstances", "minInstances", "concurrency", "timeoutSeconds", "vpc", "labels", "ingressSettings", "environmentVariables", "serviceAccount");
263
264
  (0, proto_1.convertIfPresent)(parsed, ep, "secretEnvironmentVariables", (senvs) => {
264
265
  if (!senvs) {
265
266
  return null;
@@ -40,12 +40,13 @@ function runCommand(command, childOptions) {
40
40
  });
41
41
  }
42
42
  function getChildEnvironment(target, overallOptions, config) {
43
+ var _a;
43
44
  const projectId = needProjectId(overallOptions);
44
45
  const projectDir = overallOptions.projectRoot;
45
46
  let resourceDir;
46
47
  switch (target) {
47
48
  case "hosting":
48
- resourceDir = overallOptions.config.path(config.public);
49
+ resourceDir = overallOptions.config.path((_a = config.public) !== null && _a !== void 0 ? _a : config.source);
49
50
  break;
50
51
  case "functions":
51
52
  resourceDir = overallOptions.config.path(config.source);